tInitial revision - vaccinewars - be a doctor and try to vaccinate the world | |
git clone git://src.adamsgaard.dk/vaccinewars | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 1776472dd917614b290c38dfa6a6df04cd9dd70f | |
parent e55c937a193d3df67ac391ac0e055c4eb9e091cb | |
Author: Ben Webb <[email protected]> | |
Date: Sun, 10 Sep 2000 15:10:58 +0000 | |
Initial revision | |
Diffstat: | |
A AUTHORS | 33 +++++++++++++++++++++++++++++… | |
A COPYING | 340 +++++++++++++++++++++++++++++… | |
A ChangeLog | 361 +++++++++++++++++++++++++++++… | |
A INSTALL | 226 +++++++++++++++++++++++++++++… | |
A LICENCE | 340 +++++++++++++++++++++++++++++… | |
A Makefile.am | 9 +++++++++ | |
A Makefile.in | 385 +++++++++++++++++++++++++++++… | |
A NEWS | 73 +++++++++++++++++++++++++++++… | |
A README | 103 +++++++++++++++++++++++++++++… | |
A TODO | 25 +++++++++++++++++++++++++ | |
A acconfig.h | 22 ++++++++++++++++++++++ | |
A aclocal.m4 | 706 +++++++++++++++++++++++++++++… | |
A config.h.in | 185 ++++++++++++++++++++++++++++++ | |
A configure | 4754 +++++++++++++++++++++++++++++… | |
A configure.in | 176 +++++++++++++++++++++++++++++… | |
A cygwin.am | 2 ++ | |
A doc/Makefile.am | 10 ++++++++++ | |
A doc/Makefile.in | 205 ++++++++++++++++++++++++++++++ | |
A doc/aiplayer.html | 55 +++++++++++++++++++++++++++++… | |
A doc/clientplay.html | 233 +++++++++++++++++++++++++++++… | |
A doc/commandline.html | 123 +++++++++++++++++++++++++++++… | |
A doc/configfile.html | 460 +++++++++++++++++++++++++++++… | |
A doc/credits.html | 51 +++++++++++++++++++++++++++++… | |
A doc/developer.html | 37 +++++++++++++++++++++++++++++… | |
A doc/example-cfg | 42 +++++++++++++++++++++++++++++… | |
A doc/i18n.html | 101 +++++++++++++++++++++++++++++… | |
A doc/index.html | 54 +++++++++++++++++++++++++++++… | |
A doc/installation.html | 119 +++++++++++++++++++++++++++++… | |
A doc/metaserver.html | 118 +++++++++++++++++++++++++++++… | |
A doc/server.html | 90 +++++++++++++++++++++++++++++… | |
A doc/servercommands.html | 57 +++++++++++++++++++++++++++++… | |
A doc/windows.html | 44 +++++++++++++++++++++++++++++… | |
A install-sh | 251 +++++++++++++++++++++++++++++… | |
A missing | 190 ++++++++++++++++++++++++++++++ | |
A mkinstalldirs | 40 +++++++++++++++++++++++++++++… | |
A po/POTFILES.in | 10 ++++++++++ | |
A po/cat-id-tbl.c | 727 ++++++++++++++++++++++++++++++ | |
A po/de.gmo | 0 | |
A po/de.po | 2692 +++++++++++++++++++++++++++++… | |
A po/dopewars.pot | 2676 ++++++++++++++++++++++++++++++ | |
A po/stamp-cat-id | 1 + | |
A src/AIPlayer.c | 457 +++++++++++++++++++++++++++++… | |
A src/AIPlayer.h | 43 ++++++++++++++++++++++++++++++ | |
A src/Makefile.am | 21 +++++++++++++++++++++ | |
A src/Makefile.in | 353 +++++++++++++++++++++++++++++… | |
A src/curses_client.c | 1689 ++++++++++++++++++++++++++++++ | |
A src/curses_client.h | 31 +++++++++++++++++++++++++++++… | |
A src/dopeid.h | 81 ++++++++++++++++++++++++++++++ | |
A src/dopeos.c | 349 +++++++++++++++++++++++++++++… | |
A src/dopeos.h | 196 +++++++++++++++++++++++++++++… | |
A src/dopewars.c | 1496 +++++++++++++++++++++++++++++… | |
A src/dopewars.h | 388 ++++++++++++++++++++++++++++++ | |
A src/dopewars.rc | 237 +++++++++++++++++++++++++++++… | |
A src/gtk_client.c | 2547 +++++++++++++++++++++++++++++… | |
A src/gtk_client.h | 31 +++++++++++++++++++++++++++++… | |
A src/message.c | 747 ++++++++++++++++++++++++++++++ | |
A src/message.h | 143 +++++++++++++++++++++++++++++… | |
A src/serverside.c | 2209 +++++++++++++++++++++++++++++… | |
A src/serverside.h | 78 +++++++++++++++++++++++++++++… | |
A src/win32_client.c | 1823 ++++++++++++++++++++++++++++++ | |
A src/win32_client.h | 36 +++++++++++++++++++++++++++++… | |
A stamp-h.in | 1 + | |
62 files changed, 29082 insertions(+), 0 deletions(-) | |
--- | |
diff --git a/AUTHORS b/AUTHORS | |
t@@ -0,0 +1,33 @@ | |
+dopewars is derived from the MS-DOS game of the same name (author unknown). | |
+ | |
+This is turn was based upon the MS-DOS game "Drug Wars", by John E. Dell. | |
+ | |
+dopewars is written by and is copyright of Ben Webb ([email protected]… | |
+ | |
+Pivotal to the development of dopewars were and are the following:- | |
+ | |
+Dan Wolf for uncountable numbers of useful suggestions for the structure of the | |
+multiplayer game, drawing upon a disturbing knowledge of the drugs world. He | |
+also undertook scary amounts of research (i.e. playing the game) to assist with | |
+the re-engineering of the MS-DOS version, and plays the game to an unhealthy | |
+extent (as is witnessed by his high scores on many dopewars servers). | |
+ | |
+Phil Davis, Caroline Moore, Katherine Holt and Andrea Elliot-Smith for extensi… | |
+play testing of early versions of dopewars, despite the large amounts of "real" | |
+work which they were supposed to be doing, and despite the many dodgy bugs, as | |
+well as for providing suggestions, even if they were often rude. You know who | |
+you are. | |
+ | |
+Owen Walsh and Pete Winn for yet more play testing, and for consequently doing | |
+very little research in vastly more important fields... | |
+ | |
+James Matthews for providing absolutely no useful suggestions, but providing | |
+vital assistance with the Officer Bob code. | |
+ | |
+Mike Meyer for providing several modifications to version 1.4.3, as well as | |
+spotting many of his own and my bugs... | |
+ | |
+Matt Higgins for a couple of patches to version 1.4.4. | |
+ | |
+Tony Brown for assistance with using dopewars via. enforced web proxies. | |
+ | |
diff --git a/COPYING b/COPYING | |
t@@ -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. | |
diff --git a/ChangeLog b/ChangeLog | |
t@@ -0,0 +1,361 @@ | |
+1.4.9 | |
+ - Internationalization (i18n) support | |
+ - Networking revamped - now uses nonblocking sockets to improve server | |
+ responsiveness and to remove deadlocks (previously, any client could | |
+ halt server by sending an unterminated message) | |
+ - Longer T>alk and P>age messages allowed in curses client | |
+ - Minor bug fixes to configure options | |
+ - Client-side code moved out of clientside.c and dopewars.c; | |
+ client-specific code now placed in <xxx>_client.c, while generic code is | |
+ in message.c | |
+ - GTK+ client added | |
+ - Native "pointy-clicky" Win32 graphical client added | |
+ - GLib dependency introduced; string and list handling is taken care of | |
+ now by GLib routines | |
+ - Configuration files now handled by GLib's GScanner; "string lists" | |
+ (of the format { "string1", "string2", "string3" } ) are now supported | |
+ for configuration of subway sayings, "stopped to" and overheard songs | |
+ - Timeouts bug fixed | |
+ - MaxClients bug fixed | |
+ | |
+1.4.8 09-07-2000 | |
+ - Several fixes to Win32 networking code | |
+ - IdleTimeout and ConnectTimeout variables added, to allow the server to | |
+ break connections that have been idle for too long, or take too long | |
+ to (dis)connect, respectively | |
+ - Servers now use UDP packets to communicate with metaserver, for | |
+ a faster response to changing game conditions; the client, and older | |
+ versions of the server, still use the "old" CGI script interface; | |
+ MetaServer.Port variable split into .HttpPort and .UdpPort | |
+ - MetaServer.Password can now be used with a blank MetaServer.LocalName | |
+ (with the new metaserver interface only) in order to identify servers | |
+ whose IPs are dynamic (but are otherwise the "same" server); this passwo… | |
+ must, again, be acquired from the metaserver maintainer | |
+ - Metaserver now records current & maximum numbers of players, high | |
+ scores, and last update time and uptime, for each server | |
+ - Servers now re-register with metaserver when players join or leave, | |
+ on receipt of a SIGUSR1 signal, and periodically | |
+ - Metaserver list in client now lists uptime, and current/maximum | |
+ numbers of players | |
+ - Pid file maintained while in server mode (-r command line switch) | |
+ - Names of the gun shop, pub, bank and loan shark can now be customised | |
+ (GunShopName, RoughPubName, BankName and LoanSharkName) | |
+ - When a player tries to run from a fight, running to the current location | |
+ now takes them back to the fighting screen | |
+ | |
+1.4.7 14-01-2000 | |
+ - Minor fixes to Win32 code | |
+ - dopewars now uses autoconf to (hopefully) build properly on odd sytems | |
+ such as HP-UX, and also to build "out of the box" under Cygwin (win32) | |
+ - long long datatype used for all prices on platforms that support it | |
+ - fixes to strtoprice and pricetostr code; replacement of code which | |
+ uses printf("%ld") for prices with pricetostr calls (with thanks to | |
+ Coolio) | |
+ - "Leave" option added to Bank | |
+ - Messages window is now only displayed for network games | |
+ - Binary can be compiled without TCP/IP networking support (e.g. for use | |
+ on standalone systems) by configuring with --disable-networking | |
+ - Minor modification to config. file handling to allow variables to be set | |
+ to null strings (use "Variable=") | |
+ - Option to allow the "local" server name to be specified when registering | |
+ with the metaserver - MetaServer.LocalName variable. Useful when the | |
+ metaserver refuses to resolve your IP address to your "preferred" domain | |
+ name or when connecting via. an enforced web proxy. Email the metaserver | |
+ maintainer, for an authentication password (MetaServer.Password) linked … | |
+ your chosen domain name, to use this option successfully. | |
+ | |
+1.4.6 12-11-1999 | |
+ - Bug fix for message window and "sew you up" prompt | |
+ - Bug fix for server hanging in LoseBitch function | |
+ - If player opts to play again, server selection method used last time | |
+ is used again | |
+ - Terminal resizing now handled properly | |
+ - Port to Win32 (Windows 95,98,NT) console mode | |
+ | |
+1.4.5 21-10-1999 | |
+ - Limited support now for terminals at sizes other than 80x24; but response | |
+ to a resize during the program run doesn't work properly yet... | |
+ - Minor improvements to AI players | |
+ - Corrected website address displayed by client on connecting to a | |
+ server of a different version | |
+ - If player opts to play again, defaults to the name they used last time | |
+ - Server now disconnects clients when their game ends (rather than | |
+ waiting for them to politely disconnect) - this gets around the problem | |
+ of particularly unresponsive clients getting killed and then sitting | |
+ around in an "undead" state, able to be repeatedly killed by other | |
+ players | |
+ - Armed players cannot now "stand and take it" (why would you want to | |
+ anyway?) in multiplayer fights | |
+ - Client now offers to obtain the list of available servers from the | |
+ metaserver, to select one to connect to | |
+ - "Special" values (MetaServer), (Prompt) and (Single) (including the | |
+ brackets) now accepted for the "Server" variable, which instruct the | |
+ client to list the servers, prompt the user for a server, or play | |
+ in single-player mode, rather than connecting immediately to a server | |
+ - "MetaServer.Port" variable added to facilitate connection to the | |
+ metaserver via. a proxy server (with thanks to Tony Brown) | |
+ - Signal handling cleaned up | |
+ - Buffer overflow problem with ExtractWord() fixed (hopefully) (with thanks | |
+ to Lamagra) | |
+ - Command line option -S for running a "private" server (do not contact | |
+ the metaserver) | |
+ - Prices for spies and tipoffs can be customised; this information is not | |
+ communicated properly between 1.4.5 and earlier versions, of course. | |
+ In such a case, the game will still work properly, although the client | |
+ may report erroneous spy and tipoff prices | |
+ - Fixed dodgy "pricetostr" function | |
+ - Bug fix for "Drop" command in single-player mode | |
+ - Command line option -g for specifying a supplementary configuration file | |
+ - FightTimeout variable fixed - it now actually does something... | |
+ - GunShop, LoanShark, RoughPub and Bank variables corrected so that they | |
+ take actual location numbers now - not (location-1). WARNING: this | |
+ breaks old configuration files! | |
+ - Full HTML documentation now provided | |
+ - Prices of bitches for hire can now be configured - Bitch.MinPrice and | |
+ Bitch.MaxPrice | |
+ - Removed description of non-existent "die" command in server | |
+ - Minor fixes in antique mode | |
+ - Fix of NumDrug and NumGun processing (now allows more than the default | |
+ number of drugs and guns) (with thanks to Matt Higgins) | |
+ - "ConfigVerbose" option added to display extra feedback during config | |
+ file processing (with thanks to Matt Higgins) | |
+ | |
+1.4.4 16-09-1999 | |
+ - Full compatibility with 1.4.3 servers and clients maintained | |
+ (although a warning is displayed to upgrade as soon as possible) | |
+ - dopewars client now properly redraws the screen when Ctrl-L is pressed | |
+ - Server output is now line-buffered by default for more sensible output | |
+ of log files | |
+ - L>ist bug in single player mode fixed | |
+ - Number of game turns can now be configured with the "NumTurns" | |
+ variable, or the game can be left to go on forever if it's set to zero | |
+ - The shortcuts "k" and "m" are now supported in any input of numbers | |
+ (e.g. money to put in the bank). So, for instance, typing 1.5m would | |
+ be short for typing 1500000 (m=million, k=thousand) | |
+ - Server now automatically contacts the dopewars metaserver (actually | |
+ a CGI script), at bellatrix.pcl.ox.ac.uk, whenever it is brought up or | |
+ down, to keep the list of servers on the dopewars webpage up to date. | |
+ Aspects of the server's communication with the metaserver can be | |
+ configured with the MetaServer.xxx variables | |
+ - Names of the two police officers which chase you (originally | |
+ Hardass and Bob) can now be configured with the variables | |
+ "Names.Officer" and "Names.ReserveOfficer" respectively | |
+ (provided by: Mike Meyer) | |
+ - Several uses of the string constant "bitches" rather than | |
+ the variable "Names.Bitches" have been spotted, and corrected | |
+ (provided by: Mike Meyer) | |
+ - "Sanitized" variable - if nonzero, removes drug references | |
+ (random events, the cops, etc.) - obviously drug names need to also | |
+ be changed in the config. file to complement this. Turns dopewars into | |
+ a simple trading game | |
+ (provided by: Mike Meyer) | |
+ - Minor formatting cleanups to accommodate longer drug names on the | |
+ screen neatly | |
+ (provided by: Mike Meyer) | |
+ | |
+1.4.3 23-06-1999 | |
+ - Bug with random offer of weed/paraquat fixed | |
+ - L>ist command now offers list of logged-on players or high scores | |
+ - "Out of time" message to explain why the game stops suddenly after | |
+ 31 days | |
+ - Bank is now a little more user-friendly | |
+ - Messages announcing players leaving or joining the game now appear in | |
+ the central "messages" window, rather than the main, bottom window | |
+ - Clients should now behave properly after the server crashes (or they | |
+ are pushed off the server) - i.e. they should revert to a single-player | |
+ mode game | |
+ - price_t type used for all prices | |
+ - Server interactive interface is now greatly improved, complete with | |
+ help screen | |
+ - SO_REUSEADDR set so that server can be restarted immediately if it crash… | |
+ - Facility to drop unwanted drugs, with the accompanying chance that you | |
+ are caught by Officer Hardass and shot at | |
+ - Fighting interface greatly improved:- | |
+ - All player-player fighting now occurs in a specialised window. Players | |
+ can switch between the standard "deal drugs" window and the fighting | |
+ window with the D and F keys | |
+ - Number of keystrokes required to shoot and acknowledge all the | |
+ relevant messages now greatly reduced | |
+ - Some indication is now given of the other player's status (number of | |
+ bitches and guns) | |
+ - Server now imposes timeouts on fights, so if an opponent does not | |
+ return fire within a set time, a repeat attack is allowed | |
+ - A bounty is paid out for killing an enemy bitch, and any guns/drugs | |
+ they're carrying are passed on to the victor (if he/she is able to | |
+ carry them) | |
+ - A dead player's cash is appropriated by the victor of a fight | |
+ - Handling of configuration files now greatly improved; the same options | |
+ that are set here can also be set within the server as long as no | |
+ players are connected. A large number of dopewars settings can be | |
+ changed and customised from here. Customised settings will be used | |
+ in single-player mode, and if dopewars is used as a server the settings | |
+ will be propagated to any clients (of version 1.4.3 or higher) that | |
+ connect. Not everything can be customised, but any remaining changes | |
+ should be server-side only (and thus require no alteration to the | |
+ clients). Options include:- | |
+ - MaxClients option to limit the maximum number of players connected | |
+ to the server | |
+ - FightTimeout option to alter the length of the fight timeout | |
+ - StartCash and StartDebt to change the default starting cash and debt | |
+ of every player | |
+ - Probabilities and toughness of Officer Hardass and his deputies can | |
+ be "tweaked" | |
+ - Numbers and names of locations, drugs and guns can be altered | |
+ - The words used to denote "bitches", "guns" and "drugs" can be | |
+ customised | |
+ - Drugs can now be sorted by name or by price, in forwards or reverse | |
+ order, with the DrugSortMethod option (can take values 1-4) | |
+ | |
+1.4.2 16-05-1999 | |
+ - AI player improvements | |
+ - Message structure changed to use less bandwidth and neater code | |
+ - Now easier to break out of buy/sell drug prompts etc. (by pressing an | |
+ 'invalid' key or ENTER) | |
+ - Cleanup of player list | |
+ - Cleanup after a player leaves the server; i.e. remove any references to | |
+ their spies or tipoffs with other players | |
+ - Added highlight of most recent score (for systems without working | |
+ A_STANDOUT attribute) | |
+ - Fixed bug which caused all street-bought (i.e. not at Dan's gun shop) | |
+ guns to be Saturday Night Specials | |
+ - Prevented badly-behaved clients from continuing to jet to new locations | |
+ after their death | |
+ - Added code to remove whitespace from name=value data read from | |
+ configuration file, and defaulted from $HOME/.dopewars to /etc/dopewars | |
+ - Added "helpful" messages when guns cannot be bought or sold in gun shop | |
+ - Minor cleanups of player-player fighting messages | |
+ | |
+1.4.1b 28-04-1999 | |
+ - segfault bug in server fixed | |
+ | |
+1.4.1a 28-04-1999 | |
+ - Interim release before 1.4.2; a few bug fixes in antique mode | |
+ | |
+1.4.1 27-04-1999 | |
+ - Fix of bug where paying off your debt would actually _increase_ it! | |
+ Dunno how that one slipped through... I blame my beta testers... ;) | |
+ | |
+1.4.0 27-04-1999 | |
+ - Fixed bug with server; server now detects if standard input has | |
+ been closed properly (previously if its input was redirected from | |
+ /dev/null it would keep trying to read from it, using 100% CPU. Oops.) | |
+ - First release under GPL | |
+ | |
+1.3.8 26-04-1999 | |
+ - Message structure changed; separator changed from : to ^ and extra | |
+ field added to identify messages to AI players | |
+ - Shorthand routines added for "printmessage" and "question" messages; | |
+ SendPrintMessage and SendQuestion repectively | |
+ - Display of status of fight with Officer Hardass cleaned up | |
+ - All servers are now interactive; to run in background simply attach | |
+ standard input and output to /dev/null | |
+ - AI Player can now connect to server and perform simple actions | |
+ - Bank and Loan Shark display cleaned up | |
+ - Drug busts etc. now displayed all at once rather than singly | |
+ - High scores now maintained by server | |
+ - print_price replaced with FormatPrice | |
+ - LOGF macro now used for all server log messages | |
+ - Read in location of score files, server, port from ~/.dopewars | |
+ - Fixed bugs in player-player fighting code | |
+ | |
+1.3.7 28-03-1999 | |
+ - Proper support for tipoffs and spies | |
+ - Discovered spies cannot now be shot if you don't have a gun... | |
+ - Option added for computer players (non-functional however) | |
+ | |
+1.3.6 14-03-1999 | |
+ - BreakoffCombat routine added to terminate fights cleanly when one | |
+ player runs away from a fight (under 1.3.5 defending player would | |
+ just hang when this was done...) | |
+ | |
+1.3.5 27-02-1999 | |
+ - Basic support for meeting other players; E_MEETOTHER event added | |
+ - Simple player-player fights allowed with the use of E_WAITFIGHT, | |
+ E_DEFEND and E_ATTACK events | |
+ - Two players with same name bug fixed | |
+ - "question" message extended; server now passes a list of allowed | |
+ responses in the first "word" of message data | |
+ | |
+1.3.4 25-02-1999 | |
+ - Client and virtual server now maintain completely separate lists of | |
+ players | |
+ - GunShop now works properly; user can actually see what's going on! | |
+ | |
+1.3.3 23-02-1999 | |
+ - Complete implementation of fighting with Officer Hardass | |
+ - E_DOCTOR event added to handle question "do you want a doctor to | |
+ sew you up?" after killing Hardass | |
+ - Clients now handle list and endlist messages properly to display | |
+ lists of current players on starting a game | |
+ - Minor bugfix to ensure game actually ends after the 31st | |
+ - Client now wipes price list on each jet to stop old prices | |
+ flashing up between messages from the server | |
+ | |
+1.3.2 22-02-1999 | |
+ - "subwayflash" message added | |
+ - OfferObject/RandomOffer split into separate event from OfficerHardass | |
+ - "smoke paraquat" also given separate event (E_WEED) and implemented | |
+ - Bank/LoanShark bugfixes | |
+ - Bugfix for drug price generation code | |
+ - Partial implementation of fighting with Officer Hardass | |
+ | |
+1.3.1 21-02-1999 | |
+ - Drugs can now be bought and sold | |
+ - RandomOffer and OfferObject routines added to handle server-based | |
+ random events ("a friend gives you..." etc.) and object offers ("do | |
+ you want to buy a..." etc.) although "smoke paraquat?" doesn't | |
+ work properly | |
+ - GunShop / LoanShark / Bank / Pub all handled by the server now | |
+ - Some networking bugfixes | |
+ | |
+1.3.0 20-02-1999 | |
+ - Development series (moving decision-making from client to server to | |
+ improve multi-player games and cut down on cheating, in preparation | |
+ for an OpenSource release) | |
+ - Simple implementation of a "virtual server" to handle the server-side | |
+ stuff within a single-player game | |
+ - Splitting up of Dopewars into dopewars.c (init. code and utils) | |
+ message.c (message-handling code) | |
+ serverside.c (server-side code) | |
+ clientside.c (client-side code) | |
+ - Drug prices now generated by server, not client - so synchronisation | |
+ of turns (and drug prices) should be easy to implement in the future | |
+ - Minimal functionality - networking backbone only... | |
+ | |
+1.2.0 13-02-1999 | |
+ - Stable release; some bugs in fighting code cleaned up | |
+ | |
+1.1.26 13-02-1999 | |
+ - "PolicePresence" member is now read - when a fight is started, there | |
+ is a finite chance (varies from location to location) that the | |
+ perpetrator will get attacked by the police | |
+ - MinDrug and MaxDrug members added to Location struct - some locations | |
+ may have a smaller range of drugs on offer than others | |
+ | |
+1.1.25 11-02-1999 | |
+ - Added an "Inventory" struct to keep track of players' belongings | |
+ and anything dropped during a fight; winner of a fight now gets | |
+ whatever the other player dropped (guns and/or drugs) | |
+ | |
+1.1.24 9-02-1999 | |
+ - Put in code to "finish" fights properly when one player escapes | |
+ - Attacking player is now told whether they hit the other player or | |
+ not when in a fight | |
+ | |
+1.1.23 3-02-1999 | |
+ - "Jet" command replaced with "Run" when in a fight | |
+ - "PolicePresence" member added to Location struct | |
+ - GunShop bug fixed (guns were taking up no space) | |
+ | |
+1.1.22 30-01-1999 | |
+ - Implemented very simple "shoot at another dealers" code; players, on | |
+ arriving at a location where another dealer already is, can choose | |
+ to attack (if they have any guns). The attacked player can then | |
+ choose to return fire or run for it... | |
+ | |
+1.1.21 29-01-1999 | |
+ - Added support for the "spy on another dealer" bitch errand | |
+ | |
+1.1.20 29-01-1999 | |
+ - Added support for the "tip off another dealer to the cops" bitch | |
+ errand | |
diff --git a/INSTALL b/INSTALL | |
t@@ -0,0 +1,226 @@ | |
+dopewars installation should require no more than the following:- | |
+ | |
+ ./configure | |
+ make | |
+ make install | |
+ | |
+The configure script checks to see if your system is a "normal" Unix or the | |
+Unix-under-Win32 "Cygwin" environment. On a Cygwin system, the default is to | |
+build a native Win32 binary with the Cygwin tools; this will then run without | |
+requiring the presence and performance penalty of the CYGWIN.DLL library. This | |
+test can be overridden (if, for example, you wanted to build the Unix version | |
+under Cygwin) with the --enable-nativewin32 option to configure e.g. | |
+ | |
+to build the Win32 binary under Cygwin | |
+ ./configure | |
+ (Cygwin should be automatically detected) | |
+or | |
+ ./configure --enable-nativewin32 | |
+ | |
+to build the Unix version under Cygwin | |
+ ./configure --disable-nativewin32 | |
+ | |
+For a smaller binary, you may wish to build a "stripped" binary by specifying | |
+the -s option in LDFLAGS. In a Bourne-compatible shell, this can be achieved | |
+with a command similar to the following:- | |
+ LDFLAGS="-s" ./configure | |
+ | |
+The dopewars high score file is written as /usr/local/share/dopewars.sco by | |
+default. It can be placed into an alternative location by specifying the | |
+--datadir flag to configure. The dopewars binary can also be moved from | |
+/usr/local/bin/dopewars with the --bindir flag. For example:- | |
+ | |
+ ./configure --bindir=/usr/bin --datadir=/var/games/dopewars | |
+will configure the system to write the dopewars binary as /usr/bin/dopewars | |
+and the high score as /var/games/dopewars/dopewars.sco | |
+ | |
+By default, the configure script will check your system for the availability | |
+of networking functions (specifically, the socket and select function calls). | |
+If these are found, the default behaviour is to compile dopewars with support | |
+for running as a server, and/or to connect to existing servers over a TCP/IP | |
+network. (Without networking, dopewars will only be useable in single-player | |
+mode.) This test can be overridden by specifying the --enable-networking or | |
+--disable-networking options to the configure script. | |
+ | |
+Basic Installation | |
+================== | |
+ | |
+ These are generic installation instructions. | |
+ | |
+ The `configure' shell script attempts to guess correct values for | |
+various system-dependent variables used during compilation. It uses | |
+those values to create a `Makefile' in each directory of the package. | |
+It may also create one or more `.h' files containing system-dependent | |
+definitions. Finally, it creates a shell script `config.status' that | |
+you can run in the future to recreate the current configuration, a file | |
+`config.cache' that saves the results of its tests to speed up | |
+reconfiguring, and a file `config.log' containing compiler output | |
+(useful mainly for debugging `configure'). | |
+ | |
+ If you need to do unusual things to compile the package, please try | |
+to figure out how `configure' could check whether to do them, and mail | |
+diffs or instructions to the address given in the `README' so they can | |
+be considered for the next release. If at some point `config.cache' | |
+contains results you don't want to keep, you may remove or edit it. | |
+ | |
+ The file `configure.in' is used to create `configure' by a program | |
+called `autoconf'. You only need `configure.in' if you want to change | |
+it or regenerate `configure' using a newer version of `autoconf'. | |
+ | |
+The simplest way to compile this package is: | |
+ | |
+ 1. `cd' to the directory containing the package's source code and type | |
+ `./configure' to configure the package for your system. If you're | |
+ using `csh' on an old version of System V, you might need to type | |
+ `sh ./configure' instead to prevent `csh' from trying to execute | |
+ `configure' itself. | |
+ | |
+ Running `configure' takes awhile. While running, it prints some | |
+ messages telling which features it is checking for. | |
+ | |
+ 2. Type `make' to compile the package. | |
+ | |
+ 3. Optionally, type `make check' to run any self-tests that come with | |
+ the package. | |
+ | |
+ 4. Type `make install' to install the programs and any data files and | |
+ documentation. | |
+ | |
+ 5. You can remove the program binaries and object files from the | |
+ source code directory by typing `make clean'. To also remove the | |
+ files that `configure' created (so you can compile the package for | |
+ a different kind of computer), type `make distclean'. There is | |
+ also a `make maintainer-clean' target, but that is intended mainly | |
+ for the package's developers. If you use it, you may have to get | |
+ all sorts of other programs in order to regenerate files that came | |
+ with the distribution. | |
+ | |
+Compilers and Options | |
+===================== | |
+ | |
+ Some systems require unusual options for compilation or linking that | |
+the `configure' script does not know about. You can give `configure' | |
+initial values for variables by setting them in the environment. Using | |
+a Bourne-compatible shell, you can do that on the command line like | |
+this: | |
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure | |
+ | |
+Or on systems that have the `env' program, you can do it like this: | |
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure | |
+ | |
+Compiling For Multiple Architectures | |
+==================================== | |
+ | |
+ You can compile the package for more than one kind of computer at the | |
+same time, by placing the object files for each architecture in their | |
+own directory. To do this, you must use a version of `make' that | |
+supports the `VPATH' variable, such as GNU `make'. `cd' to the | |
+directory where you want the object files and executables to go and run | |
+the `configure' script. `configure' automatically checks for the | |
+source code in the directory that `configure' is in and in `..'. | |
+ | |
+ If you have to use a `make' that does not supports the `VPATH' | |
+variable, you have to compile the package for one architecture at a time | |
+in the source code directory. After you have installed the package for | |
+one architecture, use `make distclean' before reconfiguring for another | |
+architecture. | |
+ | |
+Installation Names | |
+================== | |
+ | |
+ By default, `make install' will install the package's files in | |
+`/usr/local/bin', `/usr/local/man', etc. You can specify an | |
+installation prefix other than `/usr/local' by giving `configure' the | |
+option `--prefix=PATH'. | |
+ | |
+ You can specify separate installation prefixes for | |
+architecture-specific files and architecture-independent files. If you | |
+give `configure' the option `--exec-prefix=PATH', the package will use | |
+PATH as the prefix for installing programs and libraries. | |
+Documentation and other data files will still use the regular prefix. | |
+ | |
+ In addition, if you use an unusual directory layout you can give | |
+options like `--bindir=PATH' to specify different values for particular | |
+kinds of files. Run `configure --help' for a list of the directories | |
+you can set and what kinds of files go in them. | |
+ | |
+ If the package supports it, you can cause programs to be installed | |
+with an extra prefix or suffix on their names by giving `configure' the | |
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. | |
+ | |
+Optional Features | |
+================= | |
+ | |
+ Some packages pay attention to `--enable-FEATURE' options to | |
+`configure', where FEATURE indicates an optional part of the package. | |
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE | |
+is something like `gnu-as' or `x' (for the X Window System). The | |
+`README' should mention any `--enable-' and `--with-' options that the | |
+package recognizes. | |
+ | |
+ For packages that use the X Window System, `configure' can usually | |
+find the X include and library files automatically, but if it doesn't, | |
+you can use the `configure' options `--x-includes=DIR' and | |
+`--x-libraries=DIR' to specify their locations. | |
+ | |
+Specifying the System Type | |
+========================== | |
+ | |
+ There may be some features `configure' can not figure out | |
+automatically, but needs to determine by the type of host the package | |
+will run on. Usually `configure' can figure that out, but if it prints | |
+a message saying it can not guess the host type, give it the | |
+`--host=TYPE' option. TYPE can either be a short name for the system | |
+type, such as `sun4', or a canonical name with three fields: | |
+ CPU-COMPANY-SYSTEM | |
+ | |
+See the file `config.sub' for the possible values of each field. If | |
+`config.sub' isn't included in this package, then this package doesn't | |
+need to know the host type. | |
+ | |
+ If you are building compiler tools for cross-compiling, you can also | |
+use the `--target=TYPE' option to select the type of system they will | |
+produce code for and the `--build=TYPE' option to select the type of | |
+system on which you are compiling the package. | |
+ | |
+Sharing Defaults | |
+================ | |
+ | |
+ If you want to set default values for `configure' scripts to share, | |
+you can create a site shell script called `config.site' that gives | |
+default values for variables like `CC', `cache_file', and `prefix'. | |
+`configure' looks for `PREFIX/share/config.site' if it exists, then | |
+`PREFIX/etc/config.site' if it exists. Or, you can set the | |
+`CONFIG_SITE' environment variable to the location of the site script. | |
+A warning: not all `configure' scripts look for a site script. | |
+ | |
+Operation Controls | |
+================== | |
+ | |
+ `configure' recognizes the following options to control how it | |
+operates. | |
+ | |
+`--cache-file=FILE' | |
+ Use and save the results of the tests in FILE instead of | |
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for | |
+ debugging `configure'. | |
+ | |
+`--help' | |
+ Print a summary of the options to `configure', and exit. | |
+ | |
+`--quiet' | |
+`--silent' | |
+`-q' | |
+ Do not print messages saying which checks are being made. To | |
+ suppress all normal output, redirect it to `/dev/null' (any error | |
+ messages will still be shown). | |
+ | |
+`--srcdir=DIR' | |
+ Look for the package's source code in directory DIR. Usually | |
+ `configure' can determine that directory automatically. | |
+ | |
+`--version' | |
+ Print the version of Autoconf used to generate the `configure' | |
+ script, and exit. | |
+ | |
+`configure' also accepts some other, not widely useful, options. | |
diff --git a/LICENCE b/LICENCE | |
t@@ -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. | |
diff --git a/Makefile.am b/Makefile.am | |
t@@ -0,0 +1,9 @@ | |
+SUBDIRS = src doc po intl | |
+ | |
+DISTFILES = ABOUT-NLS | |
+ | |
+install-data-local: | |
+ touch ${datadir}/dopewars.sco | |
+ chown root.games ${datadir}/dopewars.sco | |
+ chmod 0660 ${datadir}/dopewars.sco | |
+ | |
diff --git a/Makefile.in b/Makefile.in | |
t@@ -0,0 +1,385 @@ | |
+# Makefile.in generated automatically by automake 1.4 from Makefile.am | |
+ | |
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. | |
+# This Makefile.in is free software; the Free Software Foundation | |
+# gives unlimited permission to copy and/or distribute it, | |
+# with or without modifications, as long as this notice is preserved. | |
+ | |
+# This program is distributed in the hope that it will be useful, | |
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without | |
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
+# PARTICULAR PURPOSE. | |
+ | |
+ | |
+SHELL = @SHELL@ | |
+ | |
+srcdir = @srcdir@ | |
+top_srcdir = @top_srcdir@ | |
+VPATH = @srcdir@ | |
+prefix = @prefix@ | |
+exec_prefix = @exec_prefix@ | |
+ | |
+bindir = @bindir@ | |
+sbindir = @sbindir@ | |
+libexecdir = @libexecdir@ | |
+datadir = @datadir@ | |
+sysconfdir = @sysconfdir@ | |
+sharedstatedir = @sharedstatedir@ | |
+localstatedir = @localstatedir@ | |
+libdir = @libdir@ | |
+infodir = @infodir@ | |
+mandir = @mandir@ | |
+includedir = @includedir@ | |
+oldincludedir = /usr/include | |
+ | |
+DESTDIR = | |
+ | |
+pkgdatadir = $(datadir)/@PACKAGE@ | |
+pkglibdir = $(libdir)/@PACKAGE@ | |
+pkgincludedir = $(includedir)/@PACKAGE@ | |
+ | |
+top_builddir = . | |
+ | |
+ACLOCAL = @ACLOCAL@ | |
+AUTOCONF = @AUTOCONF@ | |
+AUTOMAKE = @AUTOMAKE@ | |
+AUTOHEADER = @AUTOHEADER@ | |
+ | |
+INSTALL = @INSTALL@ | |
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) | |
+INSTALL_DATA = @INSTALL_DATA@ | |
+INSTALL_SCRIPT = @INSTALL_SCRIPT@ | |
+transform = @program_transform_name@ | |
+ | |
+NORMAL_INSTALL = : | |
+PRE_INSTALL = : | |
+POST_INSTALL = : | |
+NORMAL_UNINSTALL = : | |
+PRE_UNINSTALL = : | |
+POST_UNINSTALL = : | |
+CATALOGS = @CATALOGS@ | |
+CATOBJEXT = @CATOBJEXT@ | |
+CC = @CC@ | |
+DATADIRNAME = @DATADIRNAME@ | |
+GENCAT = @GENCAT@ | |
+GMOFILES = @GMOFILES@ | |
+GMSGFMT = @GMSGFMT@ | |
+GTK_CFLAGS = @GTK_CFLAGS@ | |
+GTK_CONFIG = @GTK_CONFIG@ | |
+GTK_LIBS = @GTK_LIBS@ | |
+GT_NO = @GT_NO@ | |
+GT_YES = @GT_YES@ | |
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ | |
+INSTOBJEXT = @INSTOBJEXT@ | |
+INTLDEPS = @INTLDEPS@ | |
+INTLLIBS = @INTLLIBS@ | |
+INTLOBJS = @INTLOBJS@ | |
+MAKEINFO = @MAKEINFO@ | |
+MKINSTALLDIRS = @MKINSTALLDIRS@ | |
+MSGFMT = @MSGFMT@ | |
+PACKAGE = @PACKAGE@ | |
+POFILES = @POFILES@ | |
+POSUB = @POSUB@ | |
+RANLIB = @RANLIB@ | |
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ | |
+USE_NLS = @USE_NLS@ | |
+VERSION = @VERSION@ | |
+WIN_RC = @WIN_RC@ | |
+WIN_RES = @WIN_RES@ | |
+l = @l@ | |
+localedir = @localedir@ | |
+ | |
+SUBDIRS = src doc po intl | |
+ | |
+DISTFILES = ABOUT-NLS | |
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 | |
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs | |
+CONFIG_HEADER = config.h | |
+CONFIG_CLEAN_FILES = | |
+DIST_COMMON = README ./stamp-h.in ABOUT-NLS AUTHORS COPYING ChangeLog \ | |
+INSTALL Makefile.am Makefile.in NEWS TODO acconfig.h aclocal.m4 \ | |
+config.h.in configure configure.in install-sh missing mkinstalldirs | |
+ | |
+ | |
+TAR = gtar | |
+GZIP_ENV = --best | |
+all: all-redirect | |
+.SUFFIXES: | |
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) | |
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile | |
+ | |
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) | |
+ cd $(top_builddir) \ | |
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status | |
+ | |
+$(ACLOCAL_M4): configure.in | |
+ cd $(srcdir) && $(ACLOCAL) | |
+ | |
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) | |
+ $(SHELL) ./config.status --recheck | |
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDEN… | |
+ cd $(srcdir) && $(AUTOCONF) | |
+ | |
+config.h: stamp-h | |
+ @if test ! -f $@; then \ | |
+ rm -f stamp-h; \ | |
+ $(MAKE) stamp-h; \ | |
+ else :; fi | |
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status | |
+ cd $(top_builddir) \ | |
+ && CONFIG_FILES= CONFIG_HEADERS=config.h \ | |
+ $(SHELL) ./config.status | |
+ @echo timestamp > stamp-h 2> /dev/null | |
+$(srcdir)/config.h.in: $(srcdir)/stamp-h.in | |
+ @if test ! -f $@; then \ | |
+ rm -f $(srcdir)/stamp-h.in; \ | |
+ $(MAKE) $(srcdir)/stamp-h.in; \ | |
+ else :; fi | |
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h | |
+ cd $(top_srcdir) && $(AUTOHEADER) | |
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null | |
+ | |
+mostlyclean-hdr: | |
+ | |
+clean-hdr: | |
+ | |
+distclean-hdr: | |
+ -rm -f config.h | |
+ | |
+maintainer-clean-hdr: | |
+ | |
+# This directory's subdirectories are mostly independent; you can cd | |
+# into them and run `make' without going through this Makefile. | |
+# To change the values of `make' variables: instead of editing Makefiles, | |
+# (1) if the variable is set in `config.status', edit `config.status' | |
+# (which will cause the Makefiles to be regenerated when you run `make'); | |
+# (2) otherwise, pass the desired values on the `make' command line. | |
+ | |
+@SET_MAKE@ | |
+ | |
+all-recursive install-data-recursive install-exec-recursive \ | |
+installdirs-recursive install-recursive uninstall-recursive \ | |
+check-recursive installcheck-recursive info-recursive dvi-recursive: | |
+ @set fnord $(MAKEFLAGS); amf=$$2; \ | |
+ dot_seen=no; \ | |
+ target=`echo $@ | sed s/-recursive//`; \ | |
+ list='$(SUBDIRS)'; for subdir in $$list; do \ | |
+ echo "Making $$target in $$subdir"; \ | |
+ if test "$$subdir" = "."; then \ | |
+ dot_seen=yes; \ | |
+ local_target="$$target-am"; \ | |
+ else \ | |
+ local_target="$$target"; \ | |
+ fi; \ | |
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ | |
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ | |
+ done; \ | |
+ if test "$$dot_seen" = "no"; then \ | |
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ | |
+ fi; test -z "$$fail" | |
+ | |
+mostlyclean-recursive clean-recursive distclean-recursive \ | |
+maintainer-clean-recursive: | |
+ @set fnord $(MAKEFLAGS); amf=$$2; \ | |
+ dot_seen=no; \ | |
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ | |
+ rev="$$subdir $$rev"; \ | |
+ test "$$subdir" = "." && dot_seen=yes; \ | |
+ done; \ | |
+ test "$$dot_seen" = "no" && rev=". $$rev"; \ | |
+ target=`echo $@ | sed s/-recursive//`; \ | |
+ for subdir in $$rev; do \ | |
+ echo "Making $$target in $$subdir"; \ | |
+ if test "$$subdir" = "."; then \ | |
+ local_target="$$target-am"; \ | |
+ else \ | |
+ local_target="$$target"; \ | |
+ fi; \ | |
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ | |
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ | |
+ done && test -z "$$fail" | |
+tags-recursive: | |
+ list='$(SUBDIRS)'; for subdir in $$list; do \ | |
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags)… | |
+ done | |
+ | |
+tags: TAGS | |
+ | |
+ID: $(HEADERS) $(SOURCES) $(LISP) | |
+ list='$(SOURCES) $(HEADERS)'; \ | |
+ unique=`for i in $$list; do echo $$i; done | \ | |
+ awk ' { files[$$0] = 1; } \ | |
+ END { for (i in files) print i; }'`; \ | |
+ here=`pwd` && cd $(srcdir) \ | |
+ && mkid -f$$here/ID $$unique $(LISP) | |
+ | |
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(… | |
+ tags=; \ | |
+ here=`pwd`; \ | |
+ list='$(SUBDIRS)'; for subdir in $$list; do \ | |
+ if test "$$subdir" = .; then :; else \ | |
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ | |
+ fi; \ | |
+ done; \ | |
+ list='$(SOURCES) $(HEADERS)'; \ | |
+ unique=`for i in $$list; do echo $$i; done | \ | |
+ awk ' { files[$$0] = 1; } \ | |
+ END { for (i in files) print i; }'`; \ | |
+ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \ | |
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique … | |
+ | |
+mostlyclean-tags: | |
+ | |
+clean-tags: | |
+ | |
+distclean-tags: | |
+ -rm -f TAGS ID | |
+ | |
+maintainer-clean-tags: | |
+ | |
+distdir = $(PACKAGE)-$(VERSION) | |
+top_distdir = $(distdir) | |
+ | |
+# This target untars the dist file and tries a VPATH configuration. Then | |
+# it guarantees that the distribution is self-contained by making another | |
+# tarfile. | |
+distcheck: dist | |
+ -rm -rf $(distdir) | |
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz | |
+ mkdir $(distdir)/=build | |
+ mkdir $(distdir)/=inst | |
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \ | |
+ cd $(distdir)/=build \ | |
+ && ../configure --with-included-gettext --srcdir=.. --prefix=$$dc_in… | |
+ && $(MAKE) $(AM_MAKEFLAGS) \ | |
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \ | |
+ && $(MAKE) $(AM_MAKEFLAGS) check \ | |
+ && $(MAKE) $(AM_MAKEFLAGS) install \ | |
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ | |
+ && $(MAKE) $(AM_MAKEFLAGS) dist | |
+ -rm -rf $(distdir) | |
+ @banner="$(distdir).tar.gz is ready for distribution"; \ | |
+ dashes=`echo "$$banner" | sed s/./=/g`; \ | |
+ echo "$$dashes"; \ | |
+ echo "$$banner"; \ | |
+ echo "$$dashes" | |
+dist: distdir | |
+ -chmod -R a+r $(distdir) | |
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) | |
+ -rm -rf $(distdir) | |
+dist-all: distdir | |
+ -chmod -R a+r $(distdir) | |
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) | |
+ -rm -rf $(distdir) | |
+distdir: $(DISTFILES) | |
+ -rm -rf $(distdir) | |
+ mkdir $(distdir) | |
+ -chmod 777 $(distdir) | |
+ here=`cd $(top_builddir) && pwd`; \ | |
+ top_distdir=`cd $(distdir) && pwd`; \ | |
+ distdir=`cd $(distdir) && pwd`; \ | |
+ cd $(top_srcdir) \ | |
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top… | |
+ @for file in $(DISTFILES); do \ | |
+ d=$(srcdir); \ | |
+ if test -d $$d/$$file; then \ | |
+ cp -pr $$d/$$file $(distdir)/$$file; \ | |
+ else \ | |
+ test -f $(distdir)/$$file \ | |
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ | |
+ || cp -p $$d/$$file $(distdir)/$$file || :; \ | |
+ fi; \ | |
+ done | |
+ for subdir in $(SUBDIRS); do \ | |
+ if test "$$subdir" = .; then :; else \ | |
+ test -d $(distdir)/$$subdir \ | |
+ || mkdir $(distdir)/$$subdir \ | |
+ || exit 1; \ | |
+ chmod 777 $(distdir)/$$subdir; \ | |
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) … | |
+ || exit 1; \ | |
+ fi; \ | |
+ done | |
+info-am: | |
+info: info-recursive | |
+dvi-am: | |
+dvi: dvi-recursive | |
+check-am: all-am | |
+check: check-recursive | |
+installcheck-am: | |
+installcheck: installcheck-recursive | |
+all-recursive-am: config.h | |
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive | |
+ | |
+install-exec-am: | |
+install-exec: install-exec-recursive | |
+ | |
+install-data-am: install-data-local | |
+install-data: install-data-recursive | |
+ | |
+install-am: all-am | |
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | |
+install: install-recursive | |
+uninstall-am: | |
+uninstall: uninstall-recursive | |
+all-am: Makefile config.h | |
+all-redirect: all-recursive-am | |
+install-strip: | |
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install | |
+installdirs: installdirs-recursive | |
+installdirs-am: | |
+ | |
+ | |
+mostlyclean-generic: | |
+ | |
+clean-generic: | |
+ | |
+distclean-generic: | |
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) | |
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]* | |
+ | |
+maintainer-clean-generic: | |
+mostlyclean-am: mostlyclean-hdr mostlyclean-tags mostlyclean-generic | |
+ | |
+mostlyclean: mostlyclean-recursive | |
+ | |
+clean-am: clean-hdr clean-tags clean-generic mostlyclean-am | |
+ | |
+clean: clean-recursive | |
+ | |
+distclean-am: distclean-hdr distclean-tags distclean-generic clean-am | |
+ | |
+distclean: distclean-recursive | |
+ -rm -f config.status | |
+ | |
+maintainer-clean-am: maintainer-clean-hdr maintainer-clean-tags \ | |
+ maintainer-clean-generic distclean-am | |
+ @echo "This command is intended for maintainers to use;" | |
+ @echo "it deletes files that may require special tools to rebuild." | |
+ | |
+maintainer-clean: maintainer-clean-recursive | |
+ -rm -f config.status | |
+ | |
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \ | |
+install-data-recursive uninstall-data-recursive install-exec-recursive \ | |
+uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ | |
+all-recursive check-recursive installcheck-recursive info-recursive \ | |
+dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ | |
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ | |
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ | |
+dvi-am dvi check check-am installcheck-am installcheck all-recursive-am \ | |
+install-exec-am install-exec install-data-local install-data-am \ | |
+install-data install-am install uninstall-am uninstall all-redirect \ | |
+all-am all installdirs-am installdirs mostlyclean-generic \ | |
+distclean-generic clean-generic maintainer-clean-generic clean \ | |
+mostlyclean distclean maintainer-clean | |
+ | |
+ | |
+install-data-local: | |
+ touch ${datadir}/dopewars.sco | |
+ chown root.games ${datadir}/dopewars.sco | |
+ chmod 0660 ${datadir}/dopewars.sco | |
+ | |
+# Tell versions [3.59,3.63) of GNU make to not export all variables. | |
+# Otherwise a system limit (for SysV at least) may be exceeded. | |
+.NOEXPORT: | |
diff --git a/NEWS b/NEWS | |
t@@ -0,0 +1,73 @@ | |
+2nd July 2000 | |
+ A mirror in the US is now available for dopewars downloads. Follow the US | |
+links (as opposed to the UK links) on the download page to download from this | |
+site. | |
+ | |
+14th January 2000 | |
+ dopewars 1.4.7 released. This now uses autoconf to build on a variety | |
+of "odd" Unices, and also "out of the box" under Cygwin (Win32). Servers for | |
+which the IP is incorrectly resolved by the metaserver can now set a | |
+preferred hostname with the "MetaServer.LocalName" variable. | |
+ | |
+31st Decemeber 1999 | |
+ The Polish version of dopewars has moved to http://dresswars.mtl.pl/ | |
+ | |
+12th November 1999 | |
+ dopewars 1.4.6 released. This fixes a few minor bugs with 1.4.5, and is n… | |
+also available on the popular Windows platform. A Win32 binary can be download… | |
+from the download page, | |
+http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/download.html. | |
+ | |
+8th November 1999 | |
+ A translation of the dopewars pages and dopewars client software into | |
+Polish is now available at http://naboo.mtl.pl/~dopewars/. | |
+ | |
+21st October 1999 | |
+ dopewars 1.4.5 released. Client players can now be instructed to connect … | |
+the metaserver, to present a "nice" list of available servers for the user to | |
+select from; more configuration options; metaserver almost works with web | |
+proxies now. | |
+ | |
+11th October 1999 | |
+ Snapshots of the latest in-development version of dopewars are now made | |
+available on a semi-regular basis at the main download page. HTML documentation | |
+is also now available. | |
+ | |
+16th September 1999 | |
+ dopewars 1.4.4 released. This handles connection to the new metaserver | |
+automatically, so that the list of dopewars servers can be easily kept up to | |
+date. Other minor changes fix small bugs from earlier versions. | |
+ | |
+15th September 1999 | |
+ Servers can now be registered by completing the form at | |
+http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/serverform.html. The upcoming | |
+version 1.4.4 of dopewars will be able to handle the connection to the web and | |
+the completion of registration details automatically. | |
+ | |
+23rd June 1999 | |
+ dopewars 1.4.3 released. This adds many new features (while hopefully not | |
+adding any new bugs) such as much better fight handling, and the ability to | |
+customise dopewars servers and clients. | |
+ | |
+16th May 1999 | |
+ dopewars 1.4.2 released. This version fixes numerous minor bugs and makes | |
+many small improvements - most noticeable is the support for AI players in | |
+multiplayer games (dopewars -c). | |
+ | |
+28th April 1999 | |
+ Interim release of dopewars 1.4.1b, which fixes a segfault problem with t… | |
+server. | |
+ | |
+28th April 1999 | |
+ Interim release of dopewars 1.4.1a, which corrects a few minor bugs in | |
+"antique" mode. | |
+ | |
+27th April 1999 | |
+ dopewars 1.4.1 released. This fixes a bug with the loan shark, which was | |
+discovered by several people quick off the mark; dunno how that slipped past my | |
+team of beta testers here at Oxford - they're obviously too busy doing "real" | |
+work! | |
+ | |
+27th April 1999 | |
+ First GPL release of dopewars (1.4.0) | |
+ | |
diff --git a/README b/README | |
t@@ -0,0 +1,103 @@ | |
+This is dopewars 1.4.8, a game simulating the life of a drug dealer in | |
+New York. The aim of the game is to make lots and lots of money... | |
+unfortunately, you start the game with a hefty debt, accumulating interest, | |
+and the cops take a rather dim view of drug dealing... | |
+ | |
+These are brief instructions; see the HTML documentation for full information. | |
+ | |
+dopewars 1.4.8 servers should handle clients as old as version 1.4.3 with | |
+hardly any visible problems (the reverse is also true). However, it is | |
+recommended that both clients and servers are upgraded to 1.4.8! | |
+ | |
+INSTALLATION | |
+ | |
+Either... | |
+ | |
+1. Get the relevant RPM from http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ | |
+ | |
+Or... | |
+ | |
+2. Get the tarball dopewars-1.4.8.tar.gz from the same URL | |
+ Extract it via. tar -xvzf dopewars-1.4.8.tar.gz | |
+ Follow the instructions in the INSTALL file in the newly-created | |
+ dopewars-1.4.8 directory | |
+ | |
+Once you're done, you can safely delete the RPM, tarball and dopewars | |
+directory. The dopewars binary is all you need! | |
+ | |
+dopewars stores its high score files by default in /usr/share/dopewars.sco | |
+This will be created by make install or by RPM installation. A different high | |
+score file can be selected with the -f switch. | |
+ | |
+WIN32 INSTALLATION | |
+ | |
+dopewars now compiles as a console application under Win32 (Windows 95,98,NT). | |
+Almost all functionality of the standard Unix binary is retained; for example, | |
+all of the same command line switches are supported, and configuration files | |
+are still looked for in $HOME/.dopewars (so set the environment variable HOME | |
+to something sensible if it is not set and you want to use this feature). | |
+ | |
+The easiest way to install the Win32 version is to download the precompiled | |
+binary. The supplied configure script, however, should build the binary | |
+correctly under Cygwin (see the INSTALL file for details). | |
+ | |
+USAGE | |
+ | |
+dopewars has built-in client-server support for multi-player games. For a | |
+full list of options configurable on the command line, run dopewars with | |
+the -h switch. | |
+ | |
+dopewars -a | |
+This is "antique" dopewars; it tries to keep to the original dopewars, based | |
+on the "Drug Wars" game by John E. Dell, as closely as possible. | |
+ | |
+dopewars | |
+By default, dopewars supports multi-player games. On starting a game, the | |
+program will attempt to connect to a dopewars server so that players can send | |
+messages back and forth, and shoot each other if they really want to... | |
+ | |
+dopewars -s | |
+Starts a dopewars server. By default this is an interactive server; if you | |
+want to put it in the background, then run it as | |
+"dopewars -s < /dev/null > /dev/null &" or similar. | |
+ | |
+dopewars -c | |
+Create and run a computer dopewars player. This will attempt to connect | |
+to a dopewars server, and if this succeeds, it will then participate in | |
+multi-player dopewars games. At the moment, it does next to nothing, however! | |
+ | |
+CONFIGURATION | |
+ | |
+Most of the dopewars defaults (for example, the location of the high score fil… | |
+the port and server to connect to, the names of the drugs and guns, etc.) can … | |
+configured by adding suitable entries to the dopewars configuration file. The | |
+global file /etc/dopewars is read first, and can then be overridden by the loc… | |
+settings in ~/.dopewars. All of the settings here can also be set on the comma… | |
+line of an interactive dopewars server when no players are logged on. See the | |
+file "example-cfg" for an example configuration file, and for a brief | |
+explanation of each option, type "help" in an interactive server. | |
+ | |
+PLAYING | |
+ | |
+dopewars is supposed to be fairly self-explanatory. You should be able to | |
+pick the basics up fairly quickly, but still be discovering subtleties for | |
+_ages_ ;) If you're _really_ stuck, send me an email. I might even answer it! | |
+ | |
+Clue: buy drugs when they're cheap, sell them when they're expensive. The Bronx | |
+and Ghetto are "special" locations. Anything more would spoil the fun. ;) | |
+ | |
+BUGS | |
+ | |
+Well, there are bound to be lots. Let me know if you find any, and I'll see | |
+if I can fix 'em... of course, a working patch would be even nicer! ;) | |
+ | |
+LICENCE | |
+ | |
+dopewars is released under the GNU General Public License; see the text file | |
+LICENCE for further information. | |
+ | |
+SUPPORT | |
+ | |
+dopewars is written and maintained by Ben Webb <[email protected]> | |
+Enquiries about dopewars may be sent to this address (keep them sensible | |
+please ;) Bug fixes and reports, improvements and patches are also welcomed. | |
diff --git a/TODO b/TODO | |
t@@ -0,0 +1,25 @@ | |
+- Fix GTK+ modal dialog behaviour (scrolling of messages, mouse grabbing) | |
+- Revamp player-player fighting | |
+- Display purchase price of drugs? | |
+- Increase cops' toughness - they should kill a bitch in 50-70% of encounters | |
+ (and damage should be cumulative) | |
+- Increase difficulty of escaping from another player - impose penalty on | |
+ running (lose drugs, free shot, destination revealed) | |
+- Alliances/cartels - several players share cash | |
+- Fix spying in server (currently you can spy on other players _before_ they | |
+ accept your bitch!) | |
+- Graphical mode server? (would avoid select() problems under Win32) | |
+- Revamp protocol - e.g. remove From/To names from messages - without breaking | |
+ backwards compatibility (tricky!) | |
+- Problems reported with display of large prices and health - must fix | |
+- Introduce minimum/maximum players options - AI players automatically | |
+ spawned/killed to "fill the gaps" when humans leave/enter | |
+- "Deal" option when meeting players? | |
+- Bribe/steal bitches when meeting players (difficulty inv. prop. to number of | |
+ bitches?) | |
+- Fix bug with players leaving the game during fights (first, must find it) | |
+- Metaserver keeps list of game types of each server | |
+Cannot reproduce... can you? (- Investigate deadlock during fighting if both | |
+ players move to "deal") | |
+Cannot reproduce... can you? (- Investigate prompt for bitch on every turn | |
+ after a spy is dispatched) | |
diff --git a/acconfig.h b/acconfig.h | |
t@@ -0,0 +1,22 @@ | |
+ | |
+/* Define if building under the Cygwin environment */ | |
+#undef CYGWIN | |
+ | |
+/* Define if dopewars should use TCP/IP networking to connect to servers */ | |
+#undef NETWORKING | |
+ | |
+/* Use the GTK+ client? */ | |
+#undef GTK_CLIENT | |
+ | |
+/* Use the (n)curses client? */ | |
+#undef CURSES_CLIENT | |
+ | |
+/* Use the Win32 client? */ | |
+#undef WIN32_CLIENT | |
+ | |
+#undef ENABLE_NLS | |
+#undef HAVE_CATGETS | |
+#undef HAVE_GETTEXT | |
+#undef HAVE_LC_MESSAGES | |
+#undef HAVE_STPCPY | |
+ | |
diff --git a/aclocal.m4 b/aclocal.m4 | |
t@@ -0,0 +1,706 @@ | |
+dnl aclocal.m4 generated automatically by aclocal 1.4 | |
+ | |
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. | |
+dnl This file is free software; the Free Software Foundation | |
+dnl gives unlimited permission to copy and/or distribute it, | |
+dnl with or without modifications, as long as this notice is preserved. | |
+ | |
+dnl This program is distributed in the hope that it will be useful, | |
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without | |
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
+dnl PARTICULAR PURPOSE. | |
+ | |
+# Do all the work for Automake. This macro actually does too much -- | |
+# some checks are only needed if your package does certain things. | |
+# But this isn't really a big deal. | |
+ | |
+# serial 1 | |
+ | |
+dnl Usage: | |
+dnl AM_INIT_AUTOMAKE(package,version, [no-define]) | |
+ | |
+AC_DEFUN(AM_INIT_AUTOMAKE, | |
+[AC_REQUIRE([AC_PROG_INSTALL]) | |
+PACKAGE=[$1] | |
+AC_SUBST(PACKAGE) | |
+VERSION=[$2] | |
+AC_SUBST(VERSION) | |
+dnl test to see if srcdir already configured | |
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then | |
+ AC_MSG_ERROR([source directory already configured; run "make distclean" ther… | |
+fi | |
+ifelse([$3],, | |
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) | |
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) | |
+AC_REQUIRE([AM_SANITY_CHECK]) | |
+AC_REQUIRE([AC_ARG_PROGRAM]) | |
+dnl FIXME This is truly gross. | |
+missing_dir=`cd $ac_aux_dir && pwd` | |
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) | |
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) | |
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) | |
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) | |
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) | |
+AC_REQUIRE([AC_PROG_MAKE_SET])]) | |
+ | |
+# | |
+# Check to make sure that the build environment is sane. | |
+# | |
+ | |
+AC_DEFUN(AM_SANITY_CHECK, | |
+[AC_MSG_CHECKING([whether build environment is sane]) | |
+# Just in case | |
+sleep 1 | |
+echo timestamp > conftestfile | |
+# Do `set' in a subshell so we don't clobber the current shell's | |
+# arguments. Must try -L first in case configure is actually a | |
+# symlink; some systems play weird games with the mod time of symlinks | |
+# (eg FreeBSD returns the mod time of the symlink's containing | |
+# directory). | |
+if ( | |
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` | |
+ if test "[$]*" = "X"; then | |
+ # -L didn't work. | |
+ set X `ls -t $srcdir/configure conftestfile` | |
+ fi | |
+ if test "[$]*" != "X $srcdir/configure conftestfile" \ | |
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then | |
+ | |
+ # If neither matched, then we have a broken ls. This can happen | |
+ # if, for instance, CONFIG_SHELL is bash and it inherits a | |
+ # broken ls alias from the environment. This has actually | |
+ # happened. Such a system could not be considered "sane". | |
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken | |
+alias in your environment]) | |
+ fi | |
+ | |
+ test "[$]2" = conftestfile | |
+ ) | |
+then | |
+ # Ok. | |
+ : | |
+else | |
+ AC_MSG_ERROR([newly created file is older than distributed files! | |
+Check your system clock]) | |
+fi | |
+rm -f conftest* | |
+AC_MSG_RESULT(yes)]) | |
+ | |
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) | |
+dnl The program must properly implement --version. | |
+AC_DEFUN(AM_MISSING_PROG, | |
+[AC_MSG_CHECKING(for working $2) | |
+# Run test in a subshell; some versions of sh will print an error if | |
+# an executable is not found, even if stderr is redirected. | |
+# Redirect stdin to placate older versions of autoconf. Sigh. | |
+if ($2 --version) < /dev/null > /dev/null 2>&1; then | |
+ $1=$2 | |
+ AC_MSG_RESULT(found) | |
+else | |
+ $1="$3/missing $2" | |
+ AC_MSG_RESULT(missing) | |
+fi | |
+AC_SUBST($1)]) | |
+ | |
+# Like AC_CONFIG_HEADER, but automatically create stamp file. | |
+ | |
+AC_DEFUN(AM_CONFIG_HEADER, | |
+[AC_PREREQ([2.12]) | |
+AC_CONFIG_HEADER([$1]) | |
+dnl When config.status generates a header, we must update the stamp-h file. | |
+dnl This file resides in the same directory as the config header | |
+dnl that is generated. We must strip everything past the first ":", | |
+dnl and everything past the last "/". | |
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl | |
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>, | |
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]… | |
+<<am_indx=1 | |
+for am_file in <<$1>>; do | |
+ case " <<$>>CONFIG_HEADERS " in | |
+ *" <<$>>am_file "*<<)>> | |
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`sta… | |
+ ;; | |
+ esac | |
+ am_indx=`expr "<<$>>am_indx" + 1` | |
+done<<>>dnl>>) | |
+changequote([,]))]) | |
+ | |
+# Macro to add for using GNU gettext. | |
+# Ulrich Drepper <[email protected]>, 1995. | |
+# | |
+# This file can be copied and used freely without restrictions. It can | |
+# be used in projects which are not available under the GNU Public License | |
+# but which still want to provide support for the GNU gettext functionality. | |
+# Please note that the actual code is *not* freely available. | |
+ | |
+# serial 5 | |
+ | |
+AC_DEFUN(AM_WITH_NLS, | |
+ [AC_MSG_CHECKING([whether NLS is requested]) | |
+ dnl Default is enabled NLS | |
+ AC_ARG_ENABLE(nls, | |
+ [ --disable-nls do not use Native Language Support], | |
+ USE_NLS=$enableval, USE_NLS=yes) | |
+ AC_MSG_RESULT($USE_NLS) | |
+ AC_SUBST(USE_NLS) | |
+ | |
+ USE_INCLUDED_LIBINTL=no | |
+ | |
+ dnl If we use NLS figure out what method | |
+ if test "$USE_NLS" = "yes"; then | |
+ AC_DEFINE(ENABLE_NLS) | |
+ AC_MSG_CHECKING([whether included gettext is requested]) | |
+ AC_ARG_WITH(included-gettext, | |
+ [ --with-included-gettext use the GNU gettext library included here], | |
+ nls_cv_force_use_gnu_gettext=$withval, | |
+ nls_cv_force_use_gnu_gettext=no) | |
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext) | |
+ | |
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" | |
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then | |
+ dnl User does not insist on using GNU NLS library. Figure out what | |
+ dnl to use. If gettext or catgets are available (in this order) we | |
+ dnl use this. Else we have to fall back to GNU NLS library. | |
+ dnl catgets is only used if permitted by option --with-catgets. | |
+ nls_cv_header_intl= | |
+ nls_cv_header_libgt= | |
+ CATOBJEXT=NONE | |
+ | |
+ AC_CHECK_HEADER(libintl.h, | |
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc, | |
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")], | |
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)]) | |
+ | |
+ if test "$gt_cv_func_gettext_libc" != "yes"; then | |
+ AC_CHECK_LIB(intl, bindtextdomain, | |
+ [AC_CACHE_CHECK([for gettext in libintl], | |
+ gt_cv_func_gettext_libintl, | |
+ [AC_CHECK_LIB(intl, gettext, | |
+ gt_cv_func_gettext_libintl=yes, | |
+ gt_cv_func_gettext_libintl=no)], | |
+ gt_cv_func_gettext_libintl=no)]) | |
+ fi | |
+ | |
+ if test "$gt_cv_func_gettext_libc" = "yes" \ | |
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then | |
+ AC_DEFINE(HAVE_GETTEXT) | |
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, | |
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl | |
+ if test "$MSGFMT" != "no"; then | |
+ AC_CHECK_FUNCS(dcgettext) | |
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) | |
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, | |
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) | |
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; | |
+ return _nl_msg_cat_cntr], | |
+ [CATOBJEXT=.gmo | |
+ DATADIRNAME=share], | |
+ [CATOBJEXT=.mo | |
+ DATADIRNAME=lib]) | |
+ INSTOBJEXT=.mo | |
+ fi | |
+ fi | |
+ ]) | |
+ | |
+ if test "$CATOBJEXT" = "NONE"; then | |
+ AC_MSG_CHECKING([whether catgets can be used]) | |
+ AC_ARG_WITH(catgets, | |
+ [ --with-catgets use catgets functions if available], | |
+ nls_cv_use_catgets=$withval, nls_cv_use_catgets=no) | |
+ AC_MSG_RESULT($nls_cv_use_catgets) | |
+ | |
+ if test "$nls_cv_use_catgets" = "yes"; then | |
+ dnl No gettext in C library. Try catgets next. | |
+ AC_CHECK_LIB(i, main) | |
+ AC_CHECK_FUNC(catgets, | |
+ [AC_DEFINE(HAVE_CATGETS) | |
+ INTLOBJS="\$(CATOBJS)" | |
+ AC_PATH_PROG(GENCAT, gencat, no)dnl | |
+ if test "$GENCAT" != "no"; then | |
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, no) | |
+ if test "$GMSGFMT" = "no"; then | |
+ AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt, | |
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no) | |
+ fi | |
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, | |
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) | |
+ USE_INCLUDED_LIBINTL=yes | |
+ CATOBJEXT=.cat | |
+ INSTOBJEXT=.cat | |
+ DATADIRNAME=lib | |
+ INTLDEPS='$(top_builddir)/intl/libintl.a' | |
+ INTLLIBS=$INTLDEPS | |
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'` | |
+ nls_cv_header_intl=intl/libintl.h | |
+ nls_cv_header_libgt=intl/libgettext.h | |
+ fi]) | |
+ fi | |
+ fi | |
+ | |
+ if test "$CATOBJEXT" = "NONE"; then | |
+ dnl Neither gettext nor catgets in included in the C library. | |
+ dnl Fall back on GNU gettext library. | |
+ nls_cv_use_gnu_gettext=yes | |
+ fi | |
+ fi | |
+ | |
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then | |
+ dnl Mark actions used to generate GNU NLS library. | |
+ INTLOBJS="\$(GETTOBJS)" | |
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, | |
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt) | |
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) | |
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, | |
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) | |
+ AC_SUBST(MSGFMT) | |
+ USE_INCLUDED_LIBINTL=yes | |
+ CATOBJEXT=.gmo | |
+ INSTOBJEXT=.mo | |
+ DATADIRNAME=share | |
+ INTLDEPS='$(top_builddir)/intl/libintl.a' | |
+ INTLLIBS=$INTLDEPS | |
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'` | |
+ nls_cv_header_intl=intl/libintl.h | |
+ nls_cv_header_libgt=intl/libgettext.h | |
+ fi | |
+ | |
+ dnl Test whether we really found GNU xgettext. | |
+ if test "$XGETTEXT" != ":"; then | |
+ dnl If it is no GNU xgettext we define it as : so that the | |
+ dnl Makefiles still can work. | |
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then | |
+ : ; | |
+ else | |
+ AC_MSG_RESULT( | |
+ [found xgettext program is not GNU xgettext; ignore it]) | |
+ XGETTEXT=":" | |
+ fi | |
+ fi | |
+ | |
+ # We need to process the po/ directory. | |
+ POSUB=po | |
+ else | |
+ DATADIRNAME=share | |
+ nls_cv_header_intl=intl/libintl.h | |
+ nls_cv_header_libgt=intl/libgettext.h | |
+ fi | |
+ AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl) | |
+ AC_OUTPUT_COMMANDS( | |
+ [case "$CONFIG_FILES" in *po/Makefile.in*) | |
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile | |
+ esac]) | |
+ | |
+ | |
+ # If this is used in GNU gettext we have to set USE_NLS to `yes' | |
+ # because some of the sources are only built for this goal. | |
+ if test "$PACKAGE" = gettext; then | |
+ USE_NLS=yes | |
+ USE_INCLUDED_LIBINTL=yes | |
+ fi | |
+ | |
+ dnl These rules are solely for the distribution goal. While doing this | |
+ dnl we only have to keep exactly one list of the available catalogs | |
+ dnl in configure.in. | |
+ for lang in $ALL_LINGUAS; do | |
+ GMOFILES="$GMOFILES $lang.gmo" | |
+ POFILES="$POFILES $lang.po" | |
+ done | |
+ | |
+ dnl Make all variables we use known to autoconf. | |
+ AC_SUBST(USE_INCLUDED_LIBINTL) | |
+ AC_SUBST(CATALOGS) | |
+ AC_SUBST(CATOBJEXT) | |
+ AC_SUBST(DATADIRNAME) | |
+ AC_SUBST(GMOFILES) | |
+ AC_SUBST(INSTOBJEXT) | |
+ AC_SUBST(INTLDEPS) | |
+ AC_SUBST(INTLLIBS) | |
+ AC_SUBST(INTLOBJS) | |
+ AC_SUBST(POFILES) | |
+ AC_SUBST(POSUB) | |
+ ]) | |
+ | |
+AC_DEFUN(AM_GNU_GETTEXT, | |
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl | |
+ AC_REQUIRE([AC_PROG_CC])dnl | |
+ AC_REQUIRE([AC_PROG_RANLIB])dnl | |
+ AC_REQUIRE([AC_ISC_POSIX])dnl | |
+ AC_REQUIRE([AC_HEADER_STDC])dnl | |
+ AC_REQUIRE([AC_C_CONST])dnl | |
+ AC_REQUIRE([AC_C_INLINE])dnl | |
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl | |
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl | |
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl | |
+ AC_REQUIRE([AC_FUNC_MMAP])dnl | |
+ | |
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \ | |
+unistd.h sys/param.h]) | |
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \ | |
+strdup __argz_count __argz_stringify __argz_next]) | |
+ | |
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then | |
+ AC_CHECK_FUNCS(stpcpy) | |
+ fi | |
+ if test "${ac_cv_func_stpcpy}" = "yes"; then | |
+ AC_DEFINE(HAVE_STPCPY) | |
+ fi | |
+ | |
+ AM_LC_MESSAGES | |
+ AM_WITH_NLS | |
+ | |
+ if test "x$CATOBJEXT" != "x"; then | |
+ if test "x$ALL_LINGUAS" = "x"; then | |
+ LINGUAS= | |
+ else | |
+ AC_MSG_CHECKING(for catalogs to be installed) | |
+ NEW_LINGUAS= | |
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do | |
+ case "$ALL_LINGUAS" in | |
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; | |
+ esac | |
+ done | |
+ LINGUAS=$NEW_LINGUAS | |
+ AC_MSG_RESULT($LINGUAS) | |
+ fi | |
+ | |
+ dnl Construct list of names of catalog files to be constructed. | |
+ if test -n "$LINGUAS"; then | |
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done | |
+ fi | |
+ fi | |
+ | |
+ dnl The reference to <locale.h> in the installed <libintl.h> file | |
+ dnl must be resolved because we cannot expect the users of this | |
+ dnl to define HAVE_LOCALE_H. | |
+ if test $ac_cv_header_locale_h = yes; then | |
+ INCLUDE_LOCALE_H="#include <locale.h>" | |
+ else | |
+ INCLUDE_LOCALE_H="\ | |
+/* The system does not provide the header <locale.h>. Take care yourself. */" | |
+ fi | |
+ AC_SUBST(INCLUDE_LOCALE_H) | |
+ | |
+ dnl Determine which catalog format we have (if any is needed) | |
+ dnl For now we know about two different formats: | |
+ dnl Linux libc-5 and the normal X/Open format | |
+ test -d intl || mkdir intl | |
+ if test "$CATOBJEXT" = ".cat"; then | |
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen) | |
+ | |
+ dnl Transform the SED scripts while copying because some dumb SEDs | |
+ dnl cannot handle comments. | |
+ sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed | |
+ fi | |
+ dnl po2tbl.sed is always needed. | |
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ | |
+ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed | |
+ | |
+ dnl In the intl/Makefile.in we have a special dependency which makes | |
+ dnl only sense for gettext. We comment this out for non-gettext | |
+ dnl packages. | |
+ if test "$PACKAGE" = "gettext"; then | |
+ GT_NO="#NO#" | |
+ GT_YES= | |
+ else | |
+ GT_NO= | |
+ GT_YES="#YES#" | |
+ fi | |
+ AC_SUBST(GT_NO) | |
+ AC_SUBST(GT_YES) | |
+ | |
+ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly | |
+ dnl find the mkinstalldirs script in another subdir but ($top_srcdir). | |
+ dnl Try to locate is. | |
+ MKINSTALLDIRS= | |
+ if test -n "$ac_aux_dir"; then | |
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" | |
+ fi | |
+ if test -z "$MKINSTALLDIRS"; then | |
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" | |
+ fi | |
+ AC_SUBST(MKINSTALLDIRS) | |
+ | |
+ dnl *** For now the libtool support in intl/Makefile is not for real. | |
+ l= | |
+ AC_SUBST(l) | |
+ | |
+ dnl Generate list of files to be processed by xgettext which will | |
+ dnl be included in po/Makefile. | |
+ test -d po || mkdir po | |
+ if test "x$srcdir" != "x."; then | |
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then | |
+ posrcprefix="$srcdir/" | |
+ else | |
+ posrcprefix="../$srcdir/" | |
+ fi | |
+ else | |
+ posrcprefix="../" | |
+ fi | |
+ rm -f po/POTFILES | |
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(… | |
+ < $srcdir/po/POTFILES.in > po/POTFILES | |
+ ]) | |
+ | |
+# Search path for a program which passes the given test. | |
+# Ulrich Drepper <[email protected]>, 1996. | |
+# | |
+# This file can be copied and used freely without restrictions. It can | |
+# be used in projects which are not available under the GNU Public License | |
+# but which still want to provide support for the GNU gettext functionality. | |
+# Please note that the actual code is *not* freely available. | |
+ | |
+# serial 1 | |
+ | |
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, | |
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) | |
+AC_DEFUN(AM_PATH_PROG_WITH_TEST, | |
+[# Extract the first word of "$2", so it can be a program name with args. | |
+set dummy $2; ac_word=[$]2 | |
+AC_MSG_CHECKING([for $ac_word]) | |
+AC_CACHE_VAL(ac_cv_path_$1, | |
+[case "[$]$1" in | |
+ /*) | |
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path. | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" | |
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ if [$3]; then | |
+ ac_cv_path_$1="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+dnl If no 4th arg is given, leave the cache variable unset, | |
+dnl so AC_PATH_PROGS will keep looking. | |
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" | |
+])dnl | |
+ ;; | |
+esac])dnl | |
+$1="$ac_cv_path_$1" | |
+if test -n "[$]$1"; then | |
+ AC_MSG_RESULT([$]$1) | |
+else | |
+ AC_MSG_RESULT(no) | |
+fi | |
+AC_SUBST($1)dnl | |
+]) | |
+ | |
+# Check whether LC_MESSAGES is available in <locale.h>. | |
+# Ulrich Drepper <[email protected]>, 1995. | |
+# | |
+# This file can be copied and used freely without restrictions. It can | |
+# be used in projects which are not available under the GNU Public License | |
+# but which still want to provide support for the GNU gettext functionality. | |
+# Please note that the actual code is *not* freely available. | |
+ | |
+# serial 1 | |
+ | |
+AC_DEFUN(AM_LC_MESSAGES, | |
+ [if test $ac_cv_header_locale_h = yes; then | |
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, | |
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES], | |
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) | |
+ if test $am_cv_val_LC_MESSAGES = yes; then | |
+ AC_DEFINE(HAVE_LC_MESSAGES) | |
+ fi | |
+ fi]) | |
+ | |
+# Configure paths for GTK+ | |
+# Owen Taylor 97-11-3 | |
+ | |
+dnl AM_PATH_GTK([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, M… | |
+dnl Test for GTK, and define GTK_CFLAGS and GTK_LIBS | |
+dnl | |
+AC_DEFUN(AM_PATH_GTK, | |
+[dnl | |
+dnl Get the cflags and libraries from the gtk-config script | |
+dnl | |
+AC_ARG_WITH(gtk-prefix,[ --with-gtk-prefix=PFX Prefix where GTK is installe… | |
+ gtk_config_prefix="$withval", gtk_config_prefix="") | |
+AC_ARG_WITH(gtk-exec-prefix,[ --with-gtk-exec-prefix=PFX Exec prefix where GT… | |
+ gtk_config_exec_prefix="$withval", gtk_config_exec_prefix="") | |
+AC_ARG_ENABLE(gtktest, [ --disable-gtktest Do not try to compile and ru… | |
+ , enable_gtktest=yes) | |
+ | |
+ for module in . $4 | |
+ do | |
+ case "$module" in | |
+ gthread) | |
+ gtk_config_args="$gtk_config_args gthread" | |
+ ;; | |
+ esac | |
+ done | |
+ | |
+ if test x$gtk_config_exec_prefix != x ; then | |
+ gtk_config_args="$gtk_config_args --exec-prefix=$gtk_config_exec_prefix" | |
+ if test x${GTK_CONFIG+set} != xset ; then | |
+ GTK_CONFIG=$gtk_config_exec_prefix/bin/gtk-config | |
+ fi | |
+ fi | |
+ if test x$gtk_config_prefix != x ; then | |
+ gtk_config_args="$gtk_config_args --prefix=$gtk_config_prefix" | |
+ if test x${GTK_CONFIG+set} != xset ; then | |
+ GTK_CONFIG=$gtk_config_prefix/bin/gtk-config | |
+ fi | |
+ fi | |
+ | |
+ AC_PATH_PROG(GTK_CONFIG, gtk-config, no) | |
+ min_gtk_version=ifelse([$1], ,0.99.7,$1) | |
+ AC_MSG_CHECKING(for GTK - version >= $min_gtk_version) | |
+ no_gtk="" | |
+ if test "$GTK_CONFIG" = "no" ; then | |
+ no_gtk=yes | |
+ else | |
+ GTK_CFLAGS=`$GTK_CONFIG $gtk_config_args --cflags` | |
+ GTK_LIBS=`$GTK_CONFIG $gtk_config_args --libs` | |
+ gtk_config_major_version=`$GTK_CONFIG $gtk_config_args --version | \ | |
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` | |
+ gtk_config_minor_version=`$GTK_CONFIG $gtk_config_args --version | \ | |
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` | |
+ gtk_config_micro_version=`$GTK_CONFIG $gtk_config_args --version | \ | |
+ sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` | |
+ if test "x$enable_gtktest" = "xyes" ; then | |
+ ac_save_CFLAGS="$CFLAGS" | |
+ ac_save_LIBS="$LIBS" | |
+ CFLAGS="$CFLAGS $GTK_CFLAGS" | |
+ LIBS="$GTK_LIBS $LIBS" | |
+dnl | |
+dnl Now check if the installed GTK is sufficiently new. (Also sanity | |
+dnl checks the results of gtk-config to some extent | |
+dnl | |
+ rm -f conf.gtktest | |
+ AC_TRY_RUN([ | |
+#include <gtk/gtk.h> | |
+#include <stdio.h> | |
+#include <stdlib.h> | |
+ | |
+int | |
+main () | |
+{ | |
+ int major, minor, micro; | |
+ char *tmp_version; | |
+ | |
+ system ("touch conf.gtktest"); | |
+ | |
+ /* HP/UX 9 (%@#!) writes to sscanf strings */ | |
+ tmp_version = g_strdup("$min_gtk_version"); | |
+ if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { | |
+ printf("%s, bad version string\n", "$min_gtk_version"); | |
+ exit(1); | |
+ } | |
+ | |
+ if ((gtk_major_version != $gtk_config_major_version) || | |
+ (gtk_minor_version != $gtk_config_minor_version) || | |
+ (gtk_micro_version != $gtk_config_micro_version)) | |
+ { | |
+ printf("\n*** 'gtk-config --version' returned %d.%d.%d, but GTK+ (%d.%d.… | |
+ $gtk_config_major_version, $gtk_config_minor_version, $gtk_config… | |
+ gtk_major_version, gtk_minor_version, gtk_micro_version); | |
+ printf ("*** was found! If gtk-config was correct, then it is best\n"); | |
+ printf ("*** to remove the old version of GTK+. You may also be able to … | |
+ printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by… | |
+ printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\… | |
+ printf("*** required on your system.\n"); | |
+ printf("*** If gtk-config was wrong, set the environment variable GTK_CO… | |
+ printf("*** to point to the correct copy of gtk-config, and remove the f… | |
+ printf("*** before re-running configure\n"); | |
+ } | |
+#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK… | |
+ else if ((gtk_major_version != GTK_MAJOR_VERSION) || | |
+ (gtk_minor_version != GTK_MINOR_VERSION) || | |
+ (gtk_micro_version != GTK_MICRO_VERSION)) | |
+ { | |
+ printf("*** GTK+ header files (version %d.%d.%d) do not match\n", | |
+ GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); | |
+ printf("*** library (version %d.%d.%d)\n", | |
+ gtk_major_version, gtk_minor_version, gtk_micro_version); | |
+ } | |
+#endif /* defined (GTK_MAJOR_VERSION) ... */ | |
+ else | |
+ { | |
+ if ((gtk_major_version > major) || | |
+ ((gtk_major_version == major) && (gtk_minor_version > minor)) || | |
+ ((gtk_major_version == major) && (gtk_minor_version == minor) && (gtk_… | |
+ { | |
+ return 0; | |
+ } | |
+ else | |
+ { | |
+ printf("\n*** An old version of GTK+ (%d.%d.%d) was found.\n", | |
+ gtk_major_version, gtk_minor_version, gtk_micro_version); | |
+ printf("*** You need a version of GTK+ newer than %d.%d.%d. The latest… | |
+ major, minor, micro); | |
+ printf("*** GTK+ is always available from ftp://ftp.gtk.org.\n"); | |
+ printf("***\n"); | |
+ printf("*** If you have already installed a sufficiently new version, … | |
+ printf("*** probably means that the wrong copy of the gtk-config shell… | |
+ printf("*** being found. The easiest way to fix this is to remove the … | |
+ printf("*** of GTK+, but you can also set the GTK_CONFIG environment t… | |
+ printf("*** correct copy of gtk-config. (In this case, you will have t… | |
+ printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /… | |
+ printf("*** so that the correct libraries are found at run-time))\n"); | |
+ } | |
+ } | |
+ return 1; | |
+} | |
+],, no_gtk=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) | |
+ CFLAGS="$ac_save_CFLAGS" | |
+ LIBS="$ac_save_LIBS" | |
+ fi | |
+ fi | |
+ if test "x$no_gtk" = x ; then | |
+ AC_MSG_RESULT(yes) | |
+ ifelse([$2], , :, [$2]) | |
+ else | |
+ AC_MSG_RESULT(no) | |
+ if test "$GTK_CONFIG" = "no" ; then | |
+ echo "*** The gtk-config script installed by GTK could not be found" | |
+ echo "*** If GTK was installed in PREFIX, make sure PREFIX/bin is in" | |
+ echo "*** your path, or set the GTK_CONFIG environment variable to the" | |
+ echo "*** full path to gtk-config." | |
+ else | |
+ if test -f conf.gtktest ; then | |
+ : | |
+ else | |
+ echo "*** Could not run GTK test program, checking why..." | |
+ CFLAGS="$CFLAGS $GTK_CFLAGS" | |
+ LIBS="$LIBS $GTK_LIBS" | |
+ AC_TRY_LINK([ | |
+#include <gtk/gtk.h> | |
+#include <stdio.h> | |
+], [ return ((gtk_major_version) || (gtk_minor_version) || (gtk_micro_ver… | |
+ [ echo "*** The test program compiled, but did not run. This usually m… | |
+ echo "*** that the run-time linker is not finding GTK or finding the… | |
+ echo "*** version of GTK. If it is not finding GTK, you'll need to s… | |
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.c… | |
+ echo "*** to the installed location Also, make sure you have run ld… | |
+ echo "*** is required on your system" | |
+ echo "***" | |
+ echo "*** If you have an old version installed, it is best to remove… | |
+ echo "*** you may also be able to get things to work by modifying LD… | |
+ echo "***" | |
+ echo "*** If you have a RedHat 5.0 system, you should remove the GTK… | |
+ echo "*** came with the system with the command" | |
+ echo "***" | |
+ echo "*** rpm --erase --nodeps gtk gtk-devel" ], | |
+ [ echo "*** The test program failed to compile or link. See the file c… | |
+ echo "*** exact error that occured. This usually means GTK was incor… | |
+ echo "*** or that you have moved GTK since it was installed. In the … | |
+ echo "*** may want to edit the gtk-config script: $GTK_CONFIG" ]) | |
+ CFLAGS="$ac_save_CFLAGS" | |
+ LIBS="$ac_save_LIBS" | |
+ fi | |
+ fi | |
+ GTK_CFLAGS="" | |
+ GTK_LIBS="" | |
+ ifelse([$3], , :, [$3]) | |
+ fi | |
+ AC_SUBST(GTK_CFLAGS) | |
+ AC_SUBST(GTK_LIBS) | |
+ rm -f conf.gtktest | |
+]) | |
+ | |
diff --git a/config.h.in b/config.h.in | |
t@@ -0,0 +1,185 @@ | |
+/* config.h.in. Generated automatically from configure.in by autoheader. */ | |
+ | |
+/* Define if using alloca.c. */ | |
+#undef C_ALLOCA | |
+ | |
+/* Define to empty if the keyword does not work. */ | |
+#undef const | |
+ | |
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. | |
+ This function is required for alloca.c support on those systems. */ | |
+#undef CRAY_STACKSEG_END | |
+ | |
+/* Define if you have alloca, as a function or macro. */ | |
+#undef HAVE_ALLOCA | |
+ | |
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */ | |
+#undef HAVE_ALLOCA_H | |
+ | |
+/* Define if you have a working `mmap' system call. */ | |
+#undef HAVE_MMAP | |
+ | |
+/* Define if you have the strftime function. */ | |
+#undef HAVE_STRFTIME | |
+ | |
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */ | |
+#undef HAVE_SYS_WAIT_H | |
+ | |
+/* Define as __inline if that's what the C compiler calls it. */ | |
+#undef inline | |
+ | |
+/* Define to `long' if <sys/types.h> doesn't define. */ | |
+#undef off_t | |
+ | |
+/* Define if you need to in order for stat and other things to work. */ | |
+#undef _POSIX_SOURCE | |
+ | |
+/* Define if the setvbuf function takes the buffering type as its second | |
+ argument and the buffer pointer as the third, as on System V | |
+ before release 3. */ | |
+#undef SETVBUF_REVERSED | |
+ | |
+/* Define to `unsigned' if <sys/types.h> doesn't define. */ | |
+#undef size_t | |
+ | |
+/* If using the C implementation of alloca, define if you know the | |
+ direction of stack growth for your system; otherwise it will be | |
+ automatically deduced at run-time. | |
+ STACK_DIRECTION > 0 => grows toward higher addresses | |
+ STACK_DIRECTION < 0 => grows toward lower addresses | |
+ STACK_DIRECTION = 0 => direction of growth unknown | |
+ */ | |
+#undef STACK_DIRECTION | |
+ | |
+/* Define if you have the ANSI C header files. */ | |
+#undef STDC_HEADERS | |
+ | |
+/* Define if you can safely include both <sys/time.h> and <time.h>. */ | |
+#undef TIME_WITH_SYS_TIME | |
+ | |
+/* Define if your <sys/time.h> declares struct tm. */ | |
+#undef TM_IN_SYS_TIME | |
+ | |
+/* Define if building under the Cygwin environment */ | |
+#undef CYGWIN | |
+ | |
+/* Define if dopewars should use TCP/IP networking to connect to servers */ | |
+#undef NETWORKING | |
+ | |
+/* Use the GTK+ client? */ | |
+#undef GTK_CLIENT | |
+ | |
+/* Use the (n)curses client? */ | |
+#undef CURSES_CLIENT | |
+ | |
+/* Use the Win32 client? */ | |
+#undef WIN32_CLIENT | |
+ | |
+#undef ENABLE_NLS | |
+#undef HAVE_CATGETS | |
+#undef HAVE_GETTEXT | |
+#undef HAVE_LC_MESSAGES | |
+#undef HAVE_STPCPY | |
+ | |
+/* The number of bytes in a long long. */ | |
+#undef SIZEOF_LONG_LONG | |
+ | |
+/* Define if you have the __argz_count function. */ | |
+#undef HAVE___ARGZ_COUNT | |
+ | |
+/* Define if you have the __argz_next function. */ | |
+#undef HAVE___ARGZ_NEXT | |
+ | |
+/* Define if you have the __argz_stringify function. */ | |
+#undef HAVE___ARGZ_STRINGIFY | |
+ | |
+/* Define if you have the dcgettext function. */ | |
+#undef HAVE_DCGETTEXT | |
+ | |
+/* Define if you have the getcwd function. */ | |
+#undef HAVE_GETCWD | |
+ | |
+/* Define if you have the getpagesize function. */ | |
+#undef HAVE_GETPAGESIZE | |
+ | |
+/* Define if you have the munmap function. */ | |
+#undef HAVE_MUNMAP | |
+ | |
+/* Define if you have the putenv function. */ | |
+#undef HAVE_PUTENV | |
+ | |
+/* Define if you have the select function. */ | |
+#undef HAVE_SELECT | |
+ | |
+/* Define if you have the setenv function. */ | |
+#undef HAVE_SETENV | |
+ | |
+/* Define if you have the setlocale function. */ | |
+#undef HAVE_SETLOCALE | |
+ | |
+/* Define if you have the socket function. */ | |
+#undef HAVE_SOCKET | |
+ | |
+/* Define if you have the stpcpy function. */ | |
+#undef HAVE_STPCPY | |
+ | |
+/* Define if you have the strcasecmp function. */ | |
+#undef HAVE_STRCASECMP | |
+ | |
+/* Define if you have the strchr function. */ | |
+#undef HAVE_STRCHR | |
+ | |
+/* Define if you have the strdup function. */ | |
+#undef HAVE_STRDUP | |
+ | |
+/* Define if you have the strstr function. */ | |
+#undef HAVE_STRSTR | |
+ | |
+/* Define if you have the <argz.h> header file. */ | |
+#undef HAVE_ARGZ_H | |
+ | |
+/* Define if you have the <fcntl.h> header file. */ | |
+#undef HAVE_FCNTL_H | |
+ | |
+/* Define if you have the <limits.h> header file. */ | |
+#undef HAVE_LIMITS_H | |
+ | |
+/* Define if you have the <locale.h> header file. */ | |
+#undef HAVE_LOCALE_H | |
+ | |
+/* Define if you have the <malloc.h> header file. */ | |
+#undef HAVE_MALLOC_H | |
+ | |
+/* Define if you have the <nl_types.h> header file. */ | |
+#undef HAVE_NL_TYPES_H | |
+ | |
+/* Define if you have the <string.h> header file. */ | |
+#undef HAVE_STRING_H | |
+ | |
+/* Define if you have the <sys/param.h> header file. */ | |
+#undef HAVE_SYS_PARAM_H | |
+ | |
+/* Define if you have the <sys/time.h> header file. */ | |
+#undef HAVE_SYS_TIME_H | |
+ | |
+/* Define if you have the <unistd.h> header file. */ | |
+#undef HAVE_UNISTD_H | |
+ | |
+/* Define if you have the cur_colr library (-lcur_colr). */ | |
+#undef HAVE_LIBCUR_COLR | |
+ | |
+/* Define if you have the curses library (-lcurses). */ | |
+#undef HAVE_LIBCURSES | |
+ | |
+/* Define if you have the i library (-li). */ | |
+#undef HAVE_LIBI | |
+ | |
+/* Define if you have the ncurses library (-lncurses). */ | |
+#undef HAVE_LIBNCURSES | |
+ | |
+/* Name of package */ | |
+#undef PACKAGE | |
+ | |
+/* Version number of package */ | |
+#undef VERSION | |
+ | |
diff --git a/configure b/configure | |
t@@ -0,0 +1,4754 @@ | |
+#! /bin/sh | |
+ | |
+# Guess values for system-dependent variables and create Makefiles. | |
+# Generated automatically using autoconf version 2.13 | |
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. | |
+# | |
+# This configure script is free software; the Free Software Foundation | |
+# gives unlimited permission to copy, distribute and modify it. | |
+ | |
+# Defaults: | |
+ac_help= | |
+ac_default_prefix=/usr/local | |
+# Any additions from configure.in: | |
+ac_help="$ac_help | |
+ --disable-nls do not use Native Language Support" | |
+ac_help="$ac_help | |
+ --with-included-gettext use the GNU gettext library included here" | |
+ac_help="$ac_help | |
+ --with-catgets use catgets functions if available" | |
+ac_help="$ac_help | |
+ --enable-gtk-client include GTK+ client on Unix systems" | |
+ac_help="$ac_help | |
+ --enable-curses-client include curses client" | |
+ac_help="$ac_help | |
+ --enable-win32-client include graphical Win32 client on Windows systems" | |
+ac_help="$ac_help | |
+ --enable-nativewin32 build a native Win32 binary under Cygwin" | |
+ac_help="$ac_help | |
+ --with-gtk-prefix=PFX Prefix where GTK is installed (optional)" | |
+ac_help="$ac_help | |
+ --with-gtk-exec-prefix=PFX Exec prefix where GTK is installed (optional)" | |
+ac_help="$ac_help | |
+ --disable-gtktest Do not try to compile and run a test GTK program" | |
+ac_help="$ac_help | |
+ --enable-networking dopewars will use TCP/IP to connect to servers" | |
+ | |
+# Initialize some variables set by options. | |
+# The variables have the same names as the options, with | |
+# dashes changed to underlines. | |
+build=NONE | |
+cache_file=./config.cache | |
+exec_prefix=NONE | |
+host=NONE | |
+no_create= | |
+nonopt=NONE | |
+no_recursion= | |
+prefix=NONE | |
+program_prefix=NONE | |
+program_suffix=NONE | |
+program_transform_name=s,x,x, | |
+silent= | |
+site= | |
+srcdir= | |
+target=NONE | |
+verbose= | |
+x_includes=NONE | |
+x_libraries=NONE | |
+bindir='${exec_prefix}/bin' | |
+sbindir='${exec_prefix}/sbin' | |
+libexecdir='${exec_prefix}/libexec' | |
+datadir='${prefix}/share' | |
+sysconfdir='${prefix}/etc' | |
+sharedstatedir='${prefix}/com' | |
+localstatedir='${prefix}/var' | |
+libdir='${exec_prefix}/lib' | |
+includedir='${prefix}/include' | |
+oldincludedir='/usr/include' | |
+infodir='${prefix}/info' | |
+mandir='${prefix}/man' | |
+ | |
+# Initialize some other variables. | |
+subdirs= | |
+MFLAGS= MAKEFLAGS= | |
+SHELL=${CONFIG_SHELL-/bin/sh} | |
+# Maximum number of lines to put in a shell here document. | |
+ac_max_here_lines=12 | |
+ | |
+ac_prev= | |
+for ac_option | |
+do | |
+ | |
+ # If the previous option needs an argument, assign it. | |
+ if test -n "$ac_prev"; then | |
+ eval "$ac_prev=\$ac_option" | |
+ ac_prev= | |
+ continue | |
+ fi | |
+ | |
+ case "$ac_option" in | |
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; | |
+ *) ac_optarg= ;; | |
+ esac | |
+ | |
+ # Accept the important Cygnus configure options, so we can diagnose typos. | |
+ | |
+ case "$ac_option" in | |
+ | |
+ -bindir | --bindir | --bindi | --bind | --bin | --bi) | |
+ ac_prev=bindir ;; | |
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) | |
+ bindir="$ac_optarg" ;; | |
+ | |
+ -build | --build | --buil | --bui | --bu) | |
+ ac_prev=build ;; | |
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*) | |
+ build="$ac_optarg" ;; | |
+ | |
+ -cache-file | --cache-file | --cache-fil | --cache-fi \ | |
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) | |
+ ac_prev=cache_file ;; | |
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | |
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) | |
+ cache_file="$ac_optarg" ;; | |
+ | |
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da) | |
+ ac_prev=datadir ;; | |
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ | |
+ | --da=*) | |
+ datadir="$ac_optarg" ;; | |
+ | |
+ -disable-* | --disable-*) | |
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` | |
+ # Reject names that are not valid shell variable names. | |
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then | |
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit … | |
+ fi | |
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'` | |
+ eval "enable_${ac_feature}=no" ;; | |
+ | |
+ -enable-* | --enable-*) | |
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` | |
+ # Reject names that are not valid shell variable names. | |
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then | |
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit … | |
+ fi | |
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'` | |
+ case "$ac_option" in | |
+ *=*) ;; | |
+ *) ac_optarg=yes ;; | |
+ esac | |
+ eval "enable_${ac_feature}='$ac_optarg'" ;; | |
+ | |
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | |
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | |
+ | --exec | --exe | --ex) | |
+ ac_prev=exec_prefix ;; | |
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | |
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | |
+ | --exec=* | --exe=* | --ex=*) | |
+ exec_prefix="$ac_optarg" ;; | |
+ | |
+ -gas | --gas | --ga | --g) | |
+ # Obsolete; use --with-gas. | |
+ with_gas=yes ;; | |
+ | |
+ -help | --help | --hel | --he) | |
+ # Omit some internal or obsolete options to make the list less imposing. | |
+ # This message is too long to be a string in the A/UX 3.1 sh. | |
+ cat << EOF | |
+Usage: configure [options] [host] | |
+Options: [defaults in brackets after descriptions] | |
+Configuration: | |
+ --cache-file=FILE cache test results in FILE | |
+ --help print this message | |
+ --no-create do not create output files | |
+ --quiet, --silent do not print \`checking...' messages | |
+ --version print the version of autoconf that created configure | |
+Directory and file names: | |
+ --prefix=PREFIX install architecture-independent files in PREFIX | |
+ [$ac_default_prefix] | |
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX | |
+ [same as prefix] | |
+ --bindir=DIR user executables in DIR [EPREFIX/bin] | |
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] | |
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec] | |
+ --datadir=DIR read-only architecture-independent data in DIR | |
+ [PREFIX/share] | |
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] | |
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR | |
+ [PREFIX/com] | |
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] | |
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib] | |
+ --includedir=DIR C header files in DIR [PREFIX/include] | |
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] | |
+ --infodir=DIR info documentation in DIR [PREFIX/info] | |
+ --mandir=DIR man documentation in DIR [PREFIX/man] | |
+ --srcdir=DIR find the sources in DIR [configure dir or ..] | |
+ --program-prefix=PREFIX prepend PREFIX to installed program names | |
+ --program-suffix=SUFFIX append SUFFIX to installed program names | |
+ --program-transform-name=PROGRAM | |
+ run sed PROGRAM on installed program names | |
+EOF | |
+ cat << EOF | |
+Host type: | |
+ --build=BUILD configure for building on BUILD [BUILD=HOST] | |
+ --host=HOST configure for HOST [guessed] | |
+ --target=TARGET configure for TARGET [TARGET=HOST] | |
+Features and packages: | |
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) | |
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes] | |
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] | |
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) | |
+ --x-includes=DIR X include files are in DIR | |
+ --x-libraries=DIR X library files are in DIR | |
+EOF | |
+ if test -n "$ac_help"; then | |
+ echo "--enable and --with options recognized:$ac_help" | |
+ fi | |
+ exit 0 ;; | |
+ | |
+ -host | --host | --hos | --ho) | |
+ ac_prev=host ;; | |
+ -host=* | --host=* | --hos=* | --ho=*) | |
+ host="$ac_optarg" ;; | |
+ | |
+ -includedir | --includedir | --includedi | --included | --include \ | |
+ | --includ | --inclu | --incl | --inc) | |
+ ac_prev=includedir ;; | |
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | |
+ | --includ=* | --inclu=* | --incl=* | --inc=*) | |
+ includedir="$ac_optarg" ;; | |
+ | |
+ -infodir | --infodir | --infodi | --infod | --info | --inf) | |
+ ac_prev=infodir ;; | |
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) | |
+ infodir="$ac_optarg" ;; | |
+ | |
+ -libdir | --libdir | --libdi | --libd) | |
+ ac_prev=libdir ;; | |
+ -libdir=* | --libdir=* | --libdi=* | --libd=*) | |
+ libdir="$ac_optarg" ;; | |
+ | |
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | |
+ | --libexe | --libex | --libe) | |
+ ac_prev=libexecdir ;; | |
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | |
+ | --libexe=* | --libex=* | --libe=*) | |
+ libexecdir="$ac_optarg" ;; | |
+ | |
+ -localstatedir | --localstatedir | --localstatedi | --localstated \ | |
+ | --localstate | --localstat | --localsta | --localst \ | |
+ | --locals | --local | --loca | --loc | --lo) | |
+ ac_prev=localstatedir ;; | |
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | |
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \ | |
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) | |
+ localstatedir="$ac_optarg" ;; | |
+ | |
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m) | |
+ ac_prev=mandir ;; | |
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) | |
+ mandir="$ac_optarg" ;; | |
+ | |
+ -nfp | --nfp | --nf) | |
+ # Obsolete; use --without-fp. | |
+ with_fp=no ;; | |
+ | |
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | |
+ | --no-cr | --no-c) | |
+ no_create=yes ;; | |
+ | |
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | |
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) | |
+ no_recursion=yes ;; | |
+ | |
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | |
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | |
+ | --oldin | --oldi | --old | --ol | --o) | |
+ ac_prev=oldincludedir ;; | |
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | |
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | |
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) | |
+ oldincludedir="$ac_optarg" ;; | |
+ | |
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) | |
+ ac_prev=prefix ;; | |
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) | |
+ prefix="$ac_optarg" ;; | |
+ | |
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \ | |
+ | --program-pre | --program-pr | --program-p) | |
+ ac_prev=program_prefix ;; | |
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \ | |
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) | |
+ program_prefix="$ac_optarg" ;; | |
+ | |
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \ | |
+ | --program-suf | --program-su | --program-s) | |
+ ac_prev=program_suffix ;; | |
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \ | |
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) | |
+ program_suffix="$ac_optarg" ;; | |
+ | |
+ -program-transform-name | --program-transform-name \ | |
+ | --program-transform-nam | --program-transform-na \ | |
+ | --program-transform-n | --program-transform- \ | |
+ | --program-transform | --program-transfor \ | |
+ | --program-transfo | --program-transf \ | |
+ | --program-trans | --program-tran \ | |
+ | --progr-tra | --program-tr | --program-t) | |
+ ac_prev=program_transform_name ;; | |
+ -program-transform-name=* | --program-transform-name=* \ | |
+ | --program-transform-nam=* | --program-transform-na=* \ | |
+ | --program-transform-n=* | --program-transform-=* \ | |
+ | --program-transform=* | --program-transfor=* \ | |
+ | --program-transfo=* | --program-transf=* \ | |
+ | --program-trans=* | --program-tran=* \ | |
+ | --progr-tra=* | --program-tr=* | --program-t=*) | |
+ program_transform_name="$ac_optarg" ;; | |
+ | |
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | |
+ | -silent | --silent | --silen | --sile | --sil) | |
+ silent=yes ;; | |
+ | |
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) | |
+ ac_prev=sbindir ;; | |
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | |
+ | --sbi=* | --sb=*) | |
+ sbindir="$ac_optarg" ;; | |
+ | |
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \ | |
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | |
+ | --sharedst | --shareds | --shared | --share | --shar \ | |
+ | --sha | --sh) | |
+ ac_prev=sharedstatedir ;; | |
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | |
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | |
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | |
+ | --sha=* | --sh=*) | |
+ sharedstatedir="$ac_optarg" ;; | |
+ | |
+ -site | --site | --sit) | |
+ ac_prev=site ;; | |
+ -site=* | --site=* | --sit=*) | |
+ site="$ac_optarg" ;; | |
+ | |
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) | |
+ ac_prev=srcdir ;; | |
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) | |
+ srcdir="$ac_optarg" ;; | |
+ | |
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | |
+ | --syscon | --sysco | --sysc | --sys | --sy) | |
+ ac_prev=sysconfdir ;; | |
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | |
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) | |
+ sysconfdir="$ac_optarg" ;; | |
+ | |
+ -target | --target | --targe | --targ | --tar | --ta | --t) | |
+ ac_prev=target ;; | |
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) | |
+ target="$ac_optarg" ;; | |
+ | |
+ -v | -verbose | --verbose | --verbos | --verbo | --verb) | |
+ verbose=yes ;; | |
+ | |
+ -version | --version | --versio | --versi | --vers) | |
+ echo "configure generated by autoconf version 2.13" | |
+ exit 0 ;; | |
+ | |
+ -with-* | --with-*) | |
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` | |
+ # Reject names that are not valid shell variable names. | |
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then | |
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit … | |
+ fi | |
+ ac_package=`echo $ac_package| sed 's/-/_/g'` | |
+ case "$ac_option" in | |
+ *=*) ;; | |
+ *) ac_optarg=yes ;; | |
+ esac | |
+ eval "with_${ac_package}='$ac_optarg'" ;; | |
+ | |
+ -without-* | --without-*) | |
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'` | |
+ # Reject names that are not valid shell variable names. | |
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then | |
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit … | |
+ fi | |
+ ac_package=`echo $ac_package| sed 's/-/_/g'` | |
+ eval "with_${ac_package}=no" ;; | |
+ | |
+ --x) | |
+ # Obsolete; use --with-x. | |
+ with_x=yes ;; | |
+ | |
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | |
+ | --x-incl | --x-inc | --x-in | --x-i) | |
+ ac_prev=x_includes ;; | |
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | |
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) | |
+ x_includes="$ac_optarg" ;; | |
+ | |
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \ | |
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) | |
+ ac_prev=x_libraries ;; | |
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | |
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) | |
+ x_libraries="$ac_optarg" ;; | |
+ | |
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show… | |
+ ;; | |
+ | |
+ *) | |
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then | |
+ echo "configure: warning: $ac_option: invalid host type" 1>&2 | |
+ fi | |
+ if test "x$nonopt" != xNONE; then | |
+ { echo "configure: error: can only configure for one host and one target… | |
+ fi | |
+ nonopt="$ac_option" | |
+ ;; | |
+ | |
+ esac | |
+done | |
+ | |
+if test -n "$ac_prev"; then | |
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/… | |
+fi | |
+ | |
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1… | |
+ | |
+# File descriptor usage: | |
+# 0 standard input | |
+# 1 file creation | |
+# 2 errors and warnings | |
+# 3 some systems may open it to /dev/tty | |
+# 4 used on the Kubota Titan | |
+# 6 checking for... messages and results | |
+# 5 compiler messages saved in config.log | |
+if test "$silent" = yes; then | |
+ exec 6>/dev/null | |
+else | |
+ exec 6>&1 | |
+fi | |
+exec 5>./config.log | |
+ | |
+echo "\ | |
+This file contains any messages produced by compilers while | |
+running configure, to aid debugging if configure makes a mistake. | |
+" 1>&5 | |
+ | |
+# Strip out --no-create and --no-recursion so they do not pile up. | |
+# Also quote any args containing shell metacharacters. | |
+ac_configure_args= | |
+for ac_arg | |
+do | |
+ case "$ac_arg" in | |
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | |
+ | --no-cr | --no-c) ;; | |
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | |
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; | |
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) | |
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;; | |
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;; | |
+ esac | |
+done | |
+ | |
+# NLS nuisances. | |
+# Only set these to C if already set. These must not be set unconditionally | |
+# because not all systems understand e.g. LANG=C (notably SCO). | |
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! | |
+# Non-C LC_CTYPE values break the ctype check. | |
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi | |
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi | |
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi | |
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi | |
+ | |
+# confdefs.h avoids OS command line length limits that DEFS can exceed. | |
+rm -rf conftest* confdefs.h | |
+# AIX cpp loses on an empty file, so make sure it contains at least a newline. | |
+echo > confdefs.h | |
+ | |
+# A filename unique to this package, relative to the directory that | |
+# configure is in, which we can look for to find out if srcdir is correct. | |
+ac_unique_file=src/dopewars.c | |
+ | |
+# Find the source files, if location was not specified. | |
+if test -z "$srcdir"; then | |
+ ac_srcdir_defaulted=yes | |
+ # Try the directory containing this script, then its parent. | |
+ ac_prog=$0 | |
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` | |
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. | |
+ srcdir=$ac_confdir | |
+ if test ! -r $srcdir/$ac_unique_file; then | |
+ srcdir=.. | |
+ fi | |
+else | |
+ ac_srcdir_defaulted=no | |
+fi | |
+if test ! -r $srcdir/$ac_unique_file; then | |
+ if test "$ac_srcdir_defaulted" = yes; then | |
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2;… | |
+ else | |
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } | |
+ fi | |
+fi | |
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` | |
+ | |
+# Prefer explicitly selected file to automatically selected ones. | |
+if test -z "$CONFIG_SITE"; then | |
+ if test "x$prefix" != xNONE; then | |
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" | |
+ else | |
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/c… | |
+ fi | |
+fi | |
+for ac_site_file in $CONFIG_SITE; do | |
+ if test -r "$ac_site_file"; then | |
+ echo "loading site script $ac_site_file" | |
+ . "$ac_site_file" | |
+ fi | |
+done | |
+ | |
+if test -r "$cache_file"; then | |
+ echo "loading cache $cache_file" | |
+ . $cache_file | |
+else | |
+ echo "creating cache $cache_file" | |
+ > $cache_file | |
+fi | |
+ | |
+ac_ext=c | |
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. | |
+ac_cpp='$CPP $CPPFLAGS' | |
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' | |
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.… | |
+cross_compiling=$ac_cv_prog_cc_cross | |
+ | |
+ac_exeext= | |
+ac_objext=o | |
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then | |
+ # Stardent Vistra SVR4 grep lacks -e, says [email protected]. | |
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then | |
+ ac_n= ac_c=' | |
+' ac_t=' ' | |
+ else | |
+ ac_n=-n ac_c= ac_t= | |
+ fi | |
+else | |
+ ac_n= ac_c='\c' ac_t= | |
+fi | |
+ | |
+ | |
+ | |
+ac_aux_dir= | |
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do | |
+ if test -f $ac_dir/install-sh; then | |
+ ac_aux_dir=$ac_dir | |
+ ac_install_sh="$ac_aux_dir/install-sh -c" | |
+ break | |
+ elif test -f $ac_dir/install.sh; then | |
+ ac_aux_dir=$ac_dir | |
+ ac_install_sh="$ac_aux_dir/install.sh -c" | |
+ break | |
+ fi | |
+done | |
+if test -z "$ac_aux_dir"; then | |
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $… | |
+fi | |
+ac_config_guess=$ac_aux_dir/config.guess | |
+ac_config_sub=$ac_aux_dir/config.sub | |
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. | |
+ | |
+# Find a good install program. We prefer a C program (faster), | |
+# so one script is as good as another. But avoid the broken or | |
+# incompatible versions: | |
+# SysV /etc/install, /usr/sbin/install | |
+# SunOS /usr/etc/install | |
+# IRIX /sbin/install | |
+# AIX /bin/install | |
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag | |
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args | |
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" | |
+# ./install, which can be erroneously created by make from ./install.sh. | |
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 | |
+echo "configure:579: checking for a BSD compatible install" >&5 | |
+if test -z "$INSTALL"; then | |
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" | |
+ for ac_dir in $PATH; do | |
+ # Account for people who put trailing slashes in PATH elements. | |
+ case "$ac_dir/" in | |
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*… | |
+ *) | |
+ # OSF1 and SCO ODT 3.0 have their own names for install. | |
+ # Don't use installbsd from OSF since it installs stuff as root | |
+ # by default. | |
+ for ac_prog in ginstall scoinst install; do | |
+ if test -f $ac_dir/$ac_prog; then | |
+ if test $ac_prog = install && | |
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then | |
+ # AIX install. It has an incompatible calling convention. | |
+ : | |
+ else | |
+ ac_cv_path_install="$ac_dir/$ac_prog -c" | |
+ break 2 | |
+ fi | |
+ fi | |
+ done | |
+ ;; | |
+ esac | |
+ done | |
+ IFS="$ac_save_IFS" | |
+ | |
+fi | |
+ if test "${ac_cv_path_install+set}" = set; then | |
+ INSTALL="$ac_cv_path_install" | |
+ else | |
+ # As a last resort, use the slow shell script. We don't cache a | |
+ # path for INSTALL within a source directory, because that will | |
+ # break other packages using the cache if that directory is | |
+ # removed, or if the path is relative. | |
+ INSTALL="$ac_install_sh" | |
+ fi | |
+fi | |
+echo "$ac_t""$INSTALL" 1>&6 | |
+ | |
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}. | |
+# It thinks the first close brace ends the variable substitution. | |
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' | |
+ | |
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' | |
+ | |
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' | |
+ | |
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 | |
+echo "configure:632: checking whether build environment is sane" >&5 | |
+# Just in case | |
+sleep 1 | |
+echo timestamp > conftestfile | |
+# Do `set' in a subshell so we don't clobber the current shell's | |
+# arguments. Must try -L first in case configure is actually a | |
+# symlink; some systems play weird games with the mod time of symlinks | |
+# (eg FreeBSD returns the mod time of the symlink's containing | |
+# directory). | |
+if ( | |
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` | |
+ if test "$*" = "X"; then | |
+ # -L didn't work. | |
+ set X `ls -t $srcdir/configure conftestfile` | |
+ fi | |
+ if test "$*" != "X $srcdir/configure conftestfile" \ | |
+ && test "$*" != "X conftestfile $srcdir/configure"; then | |
+ | |
+ # If neither matched, then we have a broken ls. This can happen | |
+ # if, for instance, CONFIG_SHELL is bash and it inherits a | |
+ # broken ls alias from the environment. This has actually | |
+ # happened. Such a system could not be considered "sane". | |
+ { echo "configure: error: ls -t appears to fail. Make sure there is not… | |
+alias in your environment" 1>&2; exit 1; } | |
+ fi | |
+ | |
+ test "$2" = conftestfile | |
+ ) | |
+then | |
+ # Ok. | |
+ : | |
+else | |
+ { echo "configure: error: newly created file is older than distributed file… | |
+Check your system clock" 1>&2; exit 1; } | |
+fi | |
+rm -f conftest* | |
+echo "$ac_t""yes" 1>&6 | |
+if test "$program_transform_name" = s,x,x,; then | |
+ program_transform_name= | |
+else | |
+ # Double any \ or $. echo might interpret backslashes. | |
+ cat <<\EOF_SED > conftestsed | |
+s,\\,\\\\,g; s,\$,$$,g | |
+EOF_SED | |
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`" | |
+ rm -f conftestsed | |
+fi | |
+test "$program_prefix" != NONE && | |
+ program_transform_name="s,^,${program_prefix},; $program_transform_name" | |
+# Use a double $ so make ignores it. | |
+test "$program_suffix" != NONE && | |
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" | |
+ | |
+# sed with no file args requires a program. | |
+test "$program_transform_name" = "" && program_transform_name="s,x,x," | |
+ | |
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 | |
+echo "configure:689: checking whether ${MAKE-make} sets \${MAKE}" >&5 | |
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` | |
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; t… | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftestmake <<\EOF | |
+all: | |
+ @echo 'ac_maketemp="${MAKE}"' | |
+EOF | |
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us. | |
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` | |
+if test -n "$ac_maketemp"; then | |
+ eval ac_cv_prog_make_${ac_make}_set=yes | |
+else | |
+ eval ac_cv_prog_make_${ac_make}_set=no | |
+fi | |
+rm -f conftestmake | |
+fi | |
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ SET_MAKE= | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+ SET_MAKE="MAKE=${MAKE-make}" | |
+fi | |
+ | |
+ | |
+PACKAGE=dopewars | |
+ | |
+VERSION=1.4.8-devel | |
+ | |
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then | |
+ { echo "configure: error: source directory already configured; run "make dis… | |
+fi | |
+cat >> confdefs.h <<EOF | |
+#define PACKAGE "$PACKAGE" | |
+EOF | |
+ | |
+cat >> confdefs.h <<EOF | |
+#define VERSION "$VERSION" | |
+EOF | |
+ | |
+ | |
+ | |
+missing_dir=`cd $ac_aux_dir && pwd` | |
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6 | |
+echo "configure:735: checking for working aclocal" >&5 | |
+# Run test in a subshell; some versions of sh will print an error if | |
+# an executable is not found, even if stderr is redirected. | |
+# Redirect stdin to placate older versions of autoconf. Sigh. | |
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then | |
+ ACLOCAL=aclocal | |
+ echo "$ac_t""found" 1>&6 | |
+else | |
+ ACLOCAL="$missing_dir/missing aclocal" | |
+ echo "$ac_t""missing" 1>&6 | |
+fi | |
+ | |
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 | |
+echo "configure:748: checking for working autoconf" >&5 | |
+# Run test in a subshell; some versions of sh will print an error if | |
+# an executable is not found, even if stderr is redirected. | |
+# Redirect stdin to placate older versions of autoconf. Sigh. | |
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then | |
+ AUTOCONF=autoconf | |
+ echo "$ac_t""found" 1>&6 | |
+else | |
+ AUTOCONF="$missing_dir/missing autoconf" | |
+ echo "$ac_t""missing" 1>&6 | |
+fi | |
+ | |
+echo $ac_n "checking for working automake""... $ac_c" 1>&6 | |
+echo "configure:761: checking for working automake" >&5 | |
+# Run test in a subshell; some versions of sh will print an error if | |
+# an executable is not found, even if stderr is redirected. | |
+# Redirect stdin to placate older versions of autoconf. Sigh. | |
+if (automake --version) < /dev/null > /dev/null 2>&1; then | |
+ AUTOMAKE=automake | |
+ echo "$ac_t""found" 1>&6 | |
+else | |
+ AUTOMAKE="$missing_dir/missing automake" | |
+ echo "$ac_t""missing" 1>&6 | |
+fi | |
+ | |
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 | |
+echo "configure:774: checking for working autoheader" >&5 | |
+# Run test in a subshell; some versions of sh will print an error if | |
+# an executable is not found, even if stderr is redirected. | |
+# Redirect stdin to placate older versions of autoconf. Sigh. | |
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then | |
+ AUTOHEADER=autoheader | |
+ echo "$ac_t""found" 1>&6 | |
+else | |
+ AUTOHEADER="$missing_dir/missing autoheader" | |
+ echo "$ac_t""missing" 1>&6 | |
+fi | |
+ | |
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 | |
+echo "configure:787: checking for working makeinfo" >&5 | |
+# Run test in a subshell; some versions of sh will print an error if | |
+# an executable is not found, even if stderr is redirected. | |
+# Redirect stdin to placate older versions of autoconf. Sigh. | |
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then | |
+ MAKEINFO=makeinfo | |
+ echo "$ac_t""found" 1>&6 | |
+else | |
+ MAKEINFO="$missing_dir/missing makeinfo" | |
+ echo "$ac_t""missing" 1>&6 | |
+fi | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+# Extract the first word of "gcc", so it can be a program name with args. | |
+set dummy gcc; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:808: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ if test -n "$CC"; then | |
+ ac_cv_prog_CC="$CC" # Let the user override the test. | |
+else | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" | |
+ ac_dummy="$PATH" | |
+ for ac_dir in $ac_dummy; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ ac_cv_prog_CC="gcc" | |
+ break | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+fi | |
+fi | |
+CC="$ac_cv_prog_CC" | |
+if test -n "$CC"; then | |
+ echo "$ac_t""$CC" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+if test -z "$CC"; then | |
+ # Extract the first word of "cc", so it can be a program name with args. | |
+set dummy cc; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:838: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ if test -n "$CC"; then | |
+ ac_cv_prog_CC="$CC" # Let the user override the test. | |
+else | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" | |
+ ac_prog_rejected=no | |
+ ac_dummy="$PATH" | |
+ for ac_dir in $ac_dummy; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then | |
+ ac_prog_rejected=yes | |
+ continue | |
+ fi | |
+ ac_cv_prog_CC="cc" | |
+ break | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+if test $ac_prog_rejected = yes; then | |
+ # We found a bogon in the path, so make sure we never use it. | |
+ set dummy $ac_cv_prog_CC | |
+ shift | |
+ if test $# -gt 0; then | |
+ # We chose a different compiler from the bogus one. | |
+ # However, it has the same basename, so the bogon will be chosen | |
+ # first if we set CC to just the basename; use the full file name. | |
+ shift | |
+ set dummy "$ac_dir/$ac_word" "$@" | |
+ shift | |
+ ac_cv_prog_CC="$@" | |
+ fi | |
+fi | |
+fi | |
+fi | |
+CC="$ac_cv_prog_CC" | |
+if test -n "$CC"; then | |
+ echo "$ac_t""$CC" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ if test -z "$CC"; then | |
+ case "`uname -s`" in | |
+ *win32* | *WIN32*) | |
+ # Extract the first word of "cl", so it can be a program name with args. | |
+set dummy cl; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:889: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ if test -n "$CC"; then | |
+ ac_cv_prog_CC="$CC" # Let the user override the test. | |
+else | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" | |
+ ac_dummy="$PATH" | |
+ for ac_dir in $ac_dummy; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ ac_cv_prog_CC="cl" | |
+ break | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+fi | |
+fi | |
+CC="$ac_cv_prog_CC" | |
+if test -n "$CC"; then | |
+ echo "$ac_t""$CC" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ ;; | |
+ esac | |
+ fi | |
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH"… | |
+fi | |
+ | |
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... … | |
+echo "configure:921: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) wo… | |
+ | |
+ac_ext=c | |
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. | |
+ac_cpp='$CPP $CPPFLAGS' | |
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' | |
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.… | |
+cross_compiling=$ac_cv_prog_cc_cross | |
+ | |
+cat > conftest.$ac_ext << EOF | |
+ | |
+#line 932 "configure" | |
+#include "confdefs.h" | |
+ | |
+main(){return(0);} | |
+EOF | |
+if { (eval echo configure:937: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && … | |
+ ac_cv_prog_cc_works=yes | |
+ # If we can't run a trivial program, we are probably using a cross compiler. | |
+ if (./conftest; exit) 2>/dev/null; then | |
+ ac_cv_prog_cc_cross=no | |
+ else | |
+ ac_cv_prog_cc_cross=yes | |
+ fi | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ ac_cv_prog_cc_works=no | |
+fi | |
+rm -fr conftest* | |
+ac_ext=c | |
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. | |
+ac_cpp='$CPP $CPPFLAGS' | |
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' | |
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.… | |
+cross_compiling=$ac_cv_prog_cc_cross | |
+ | |
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 | |
+if test $ac_cv_prog_cc_works = no; then | |
+ { echo "configure: error: installation or configuration problem: C compiler … | |
+fi | |
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-… | |
+echo "configure:963: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is… | |
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 | |
+cross_compiling=$ac_cv_prog_cc_cross | |
+ | |
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 | |
+echo "configure:968: checking whether we are using GNU C" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.c <<EOF | |
+#ifdef __GNUC__ | |
+ yes; | |
+#endif | |
+EOF | |
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:977: \"$ac_try\")… | |
+ ac_cv_prog_gcc=yes | |
+else | |
+ ac_cv_prog_gcc=no | |
+fi | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6 | |
+ | |
+if test $ac_cv_prog_gcc = yes; then | |
+ GCC=yes | |
+else | |
+ GCC= | |
+fi | |
+ | |
+ac_test_CFLAGS="${CFLAGS+set}" | |
+ac_save_CFLAGS="$CFLAGS" | |
+CFLAGS= | |
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 | |
+echo "configure:996: checking whether ${CC-cc} accepts -g" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ echo 'void f(){}' > conftest.c | |
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then | |
+ ac_cv_prog_cc_g=yes | |
+else | |
+ ac_cv_prog_cc_g=no | |
+fi | |
+rm -f conftest* | |
+ | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 | |
+if test "$ac_test_CFLAGS" = set; then | |
+ CFLAGS="$ac_save_CFLAGS" | |
+elif test $ac_cv_prog_cc_g = yes; then | |
+ if test "$GCC" = yes; then | |
+ CFLAGS="-g -O2" | |
+ else | |
+ CFLAGS="-g" | |
+ fi | |
+else | |
+ if test "$GCC" = yes; then | |
+ CFLAGS="-O2" | |
+ else | |
+ CFLAGS= | |
+ fi | |
+fi | |
+ | |
+# Find a good install program. We prefer a C program (faster), | |
+# so one script is as good as another. But avoid the broken or | |
+# incompatible versions: | |
+# SysV /etc/install, /usr/sbin/install | |
+# SunOS /usr/etc/install | |
+# IRIX /sbin/install | |
+# AIX /bin/install | |
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag | |
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args | |
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" | |
+# ./install, which can be erroneously created by make from ./install.sh. | |
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 | |
+echo "configure:1039: checking for a BSD compatible install" >&5 | |
+if test -z "$INSTALL"; then | |
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" | |
+ for ac_dir in $PATH; do | |
+ # Account for people who put trailing slashes in PATH elements. | |
+ case "$ac_dir/" in | |
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*… | |
+ *) | |
+ # OSF1 and SCO ODT 3.0 have their own names for install. | |
+ # Don't use installbsd from OSF since it installs stuff as root | |
+ # by default. | |
+ for ac_prog in ginstall scoinst install; do | |
+ if test -f $ac_dir/$ac_prog; then | |
+ if test $ac_prog = install && | |
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then | |
+ # AIX install. It has an incompatible calling convention. | |
+ : | |
+ else | |
+ ac_cv_path_install="$ac_dir/$ac_prog -c" | |
+ break 2 | |
+ fi | |
+ fi | |
+ done | |
+ ;; | |
+ esac | |
+ done | |
+ IFS="$ac_save_IFS" | |
+ | |
+fi | |
+ if test "${ac_cv_path_install+set}" = set; then | |
+ INSTALL="$ac_cv_path_install" | |
+ else | |
+ # As a last resort, use the slow shell script. We don't cache a | |
+ # path for INSTALL within a source directory, because that will | |
+ # break other packages using the cache if that directory is | |
+ # removed, or if the path is relative. | |
+ INSTALL="$ac_install_sh" | |
+ fi | |
+fi | |
+echo "$ac_t""$INSTALL" 1>&6 | |
+ | |
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}. | |
+# It thinks the first close brace ends the variable substitution. | |
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' | |
+ | |
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' | |
+ | |
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' | |
+ | |
+ | |
+ALL_LINGUAS="de" | |
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 | |
+echo "configure:1094: checking how to run the C preprocessor" >&5 | |
+# On Suns, sometimes $CPP names a directory. | |
+if test -n "$CPP" && test -d "$CPP"; then | |
+ CPP= | |
+fi | |
+if test -z "$CPP"; then | |
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ # This must be in double quotes, not single quotes, because CPP may get | |
+ # substituted into the Makefile and "${CC-cc}" will confuse make. | |
+ CPP="${CC-cc} -E" | |
+ # On the NeXT, cc -E runs the code through the compiler's parser, | |
+ # not just through cpp. | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1109 "configure" | |
+#include "confdefs.h" | |
+#include <assert.h> | |
+Syntax Error | |
+EOF | |
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
+{ (eval echo configure:1115: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
+if test -z "$ac_err"; then | |
+ : | |
+else | |
+ echo "$ac_err" >&5 | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ CPP="${CC-cc} -E -traditional-cpp" | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1126 "configure" | |
+#include "confdefs.h" | |
+#include <assert.h> | |
+Syntax Error | |
+EOF | |
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
+{ (eval echo configure:1132: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
+if test -z "$ac_err"; then | |
+ : | |
+else | |
+ echo "$ac_err" >&5 | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ CPP="${CC-cc} -nologo -E" | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1143 "configure" | |
+#include "confdefs.h" | |
+#include <assert.h> | |
+Syntax Error | |
+EOF | |
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
+{ (eval echo configure:1149: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
+if test -z "$ac_err"; then | |
+ : | |
+else | |
+ echo "$ac_err" >&5 | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ CPP=/lib/cpp | |
+fi | |
+rm -f conftest* | |
+fi | |
+rm -f conftest* | |
+fi | |
+rm -f conftest* | |
+ ac_cv_prog_CPP="$CPP" | |
+fi | |
+ CPP="$ac_cv_prog_CPP" | |
+else | |
+ ac_cv_prog_CPP="$CPP" | |
+fi | |
+echo "$ac_t""$CPP" 1>&6 | |
+ | |
+# Extract the first word of "ranlib", so it can be a program name with args. | |
+set dummy ranlib; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:1176: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ if test -n "$RANLIB"; then | |
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. | |
+else | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" | |
+ ac_dummy="$PATH" | |
+ for ac_dir in $ac_dummy; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ ac_cv_prog_RANLIB="ranlib" | |
+ break | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" | |
+fi | |
+fi | |
+RANLIB="$ac_cv_prog_RANLIB" | |
+if test -n "$RANLIB"; then | |
+ echo "$ac_t""$RANLIB" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6 | |
+echo "configure:1204: checking for POSIXized ISC" >&5 | |
+if test -d /etc/conf/kconfig.d && | |
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 | |
+then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ISC=yes # If later tests want to check for ISC. | |
+ cat >> confdefs.h <<\EOF | |
+#define _POSIX_SOURCE 1 | |
+EOF | |
+ | |
+ if test "$GCC" = yes; then | |
+ CC="$CC -posix" | |
+ else | |
+ CC="$CC -Xp" | |
+ fi | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+ ISC= | |
+fi | |
+ | |
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 | |
+echo "configure:1225: checking for ANSI C header files" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1230 "configure" | |
+#include "confdefs.h" | |
+#include <stdlib.h> | |
+#include <stdarg.h> | |
+#include <string.h> | |
+#include <float.h> | |
+EOF | |
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
+{ (eval echo configure:1238: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
+if test -z "$ac_err"; then | |
+ rm -rf conftest* | |
+ ac_cv_header_stdc=yes | |
+else | |
+ echo "$ac_err" >&5 | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ ac_cv_header_stdc=no | |
+fi | |
+rm -f conftest* | |
+ | |
+if test $ac_cv_header_stdc = yes; then | |
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI. | |
+cat > conftest.$ac_ext <<EOF | |
+#line 1255 "configure" | |
+#include "confdefs.h" | |
+#include <string.h> | |
+EOF | |
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | | |
+ egrep "memchr" >/dev/null 2>&1; then | |
+ : | |
+else | |
+ rm -rf conftest* | |
+ ac_cv_header_stdc=no | |
+fi | |
+rm -f conftest* | |
+ | |
+fi | |
+ | |
+if test $ac_cv_header_stdc = yes; then | |
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. | |
+cat > conftest.$ac_ext <<EOF | |
+#line 1273 "configure" | |
+#include "confdefs.h" | |
+#include <stdlib.h> | |
+EOF | |
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | | |
+ egrep "free" >/dev/null 2>&1; then | |
+ : | |
+else | |
+ rm -rf conftest* | |
+ ac_cv_header_stdc=no | |
+fi | |
+rm -f conftest* | |
+ | |
+fi | |
+ | |
+if test $ac_cv_header_stdc = yes; then | |
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. | |
+if test "$cross_compiling" = yes; then | |
+ : | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1294 "configure" | |
+#include "confdefs.h" | |
+#include <ctype.h> | |
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') | |
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) | |
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) | |
+int main () { int i; for (i = 0; i < 256; i++) | |
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); | |
+exit (0); } | |
+ | |
+EOF | |
+if { (eval echo configure:1305: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+then | |
+ : | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -fr conftest* | |
+ ac_cv_header_stdc=no | |
+fi | |
+rm -fr conftest* | |
+fi | |
+ | |
+fi | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_header_stdc" 1>&6 | |
+if test $ac_cv_header_stdc = yes; then | |
+ cat >> confdefs.h <<\EOF | |
+#define STDC_HEADERS 1 | |
+EOF | |
+ | |
+fi | |
+ | |
+echo $ac_n "checking for working const""... $ac_c" 1>&6 | |
+echo "configure:1329: checking for working const" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1334 "configure" | |
+#include "confdefs.h" | |
+ | |
+int main() { | |
+ | |
+/* Ultrix mips cc rejects this. */ | |
+typedef int charset[2]; const charset x; | |
+/* SunOS 4.1.1 cc rejects this. */ | |
+char const *const *ccp; | |
+char **p; | |
+/* NEC SVR4.0.2 mips cc rejects this. */ | |
+struct point {int x, y;}; | |
+static struct point const zero = {0,0}; | |
+/* AIX XL C 1.02.0.0 rejects this. | |
+ It does not let you subtract one const X* pointer from another in an arm | |
+ of an if-expression whose if-part is not a constant expression */ | |
+const char *g = "string"; | |
+ccp = &g + (g ? g-g : 0); | |
+/* HPUX 7.0 cc rejects these. */ | |
+++ccp; | |
+p = (char**) ccp; | |
+ccp = (char const *const *) p; | |
+{ /* SCO 3.2v4 cc rejects this. */ | |
+ char *t; | |
+ char const *s = 0 ? (char *) 0 : (char const *) 0; | |
+ | |
+ *t++ = 0; | |
+} | |
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ | |
+ int x[] = {25, 17}; | |
+ const int *foo = &x[0]; | |
+ ++foo; | |
+} | |
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ | |
+ typedef const int *iptr; | |
+ iptr p = 0; | |
+ ++p; | |
+} | |
+{ /* AIX XL C 1.02.0.0 rejects this saying | |
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ | |
+ struct s { int j; const int *ap[3]; }; | |
+ struct s *b; b->j = 5; | |
+} | |
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ | |
+ const int foo = 10; | |
+} | |
+ | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:1383: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+ rm -rf conftest* | |
+ ac_cv_c_const=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ ac_cv_c_const=no | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_c_const" 1>&6 | |
+if test $ac_cv_c_const = no; then | |
+ cat >> confdefs.h <<\EOF | |
+#define const | |
+EOF | |
+ | |
+fi | |
+ | |
+echo $ac_n "checking for inline""... $ac_c" 1>&6 | |
+echo "configure:1404: checking for inline" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ ac_cv_c_inline=no | |
+for ac_kw in inline __inline__ __inline; do | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1411 "configure" | |
+#include "confdefs.h" | |
+ | |
+int main() { | |
+} $ac_kw foo() { | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:1418: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+ rm -rf conftest* | |
+ ac_cv_c_inline=$ac_kw; break | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+fi | |
+rm -f conftest* | |
+done | |
+ | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_c_inline" 1>&6 | |
+case "$ac_cv_c_inline" in | |
+ inline | yes) ;; | |
+ no) cat >> confdefs.h <<\EOF | |
+#define inline | |
+EOF | |
+ ;; | |
+ *) cat >> confdefs.h <<EOF | |
+#define inline $ac_cv_c_inline | |
+EOF | |
+ ;; | |
+esac | |
+ | |
+echo $ac_n "checking for off_t""... $ac_c" 1>&6 | |
+echo "configure:1444: checking for off_t" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1449 "configure" | |
+#include "confdefs.h" | |
+#include <sys/types.h> | |
+#if STDC_HEADERS | |
+#include <stdlib.h> | |
+#include <stddef.h> | |
+#endif | |
+EOF | |
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | | |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then | |
+ rm -rf conftest* | |
+ ac_cv_type_off_t=yes | |
+else | |
+ rm -rf conftest* | |
+ ac_cv_type_off_t=no | |
+fi | |
+rm -f conftest* | |
+ | |
+fi | |
+echo "$ac_t""$ac_cv_type_off_t" 1>&6 | |
+if test $ac_cv_type_off_t = no; then | |
+ cat >> confdefs.h <<\EOF | |
+#define off_t long | |
+EOF | |
+ | |
+fi | |
+ | |
+echo $ac_n "checking for size_t""... $ac_c" 1>&6 | |
+echo "configure:1477: checking for size_t" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1482 "configure" | |
+#include "confdefs.h" | |
+#include <sys/types.h> | |
+#if STDC_HEADERS | |
+#include <stdlib.h> | |
+#include <stddef.h> | |
+#endif | |
+EOF | |
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | | |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then | |
+ rm -rf conftest* | |
+ ac_cv_type_size_t=yes | |
+else | |
+ rm -rf conftest* | |
+ ac_cv_type_size_t=no | |
+fi | |
+rm -f conftest* | |
+ | |
+fi | |
+echo "$ac_t""$ac_cv_type_size_t" 1>&6 | |
+if test $ac_cv_type_size_t = no; then | |
+ cat >> confdefs.h <<\EOF | |
+#define size_t unsigned | |
+EOF | |
+ | |
+fi | |
+ | |
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works | |
+# for constant arguments. Useless! | |
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 | |
+echo "configure:1512: checking for working alloca.h" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1517 "configure" | |
+#include "confdefs.h" | |
+#include <alloca.h> | |
+int main() { | |
+char *p = alloca(2 * sizeof(int)); | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:1524: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ ac_cv_header_alloca_h=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ ac_cv_header_alloca_h=no | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&6 | |
+if test $ac_cv_header_alloca_h = yes; then | |
+ cat >> confdefs.h <<\EOF | |
+#define HAVE_ALLOCA_H 1 | |
+EOF | |
+ | |
+fi | |
+ | |
+echo $ac_n "checking for alloca""... $ac_c" 1>&6 | |
+echo "configure:1545: checking for alloca" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1550 "configure" | |
+#include "confdefs.h" | |
+ | |
+#ifdef __GNUC__ | |
+# define alloca __builtin_alloca | |
+#else | |
+# ifdef _MSC_VER | |
+# include <malloc.h> | |
+# define alloca _alloca | |
+# else | |
+# if HAVE_ALLOCA_H | |
+# include <alloca.h> | |
+# else | |
+# ifdef _AIX | |
+ #pragma alloca | |
+# else | |
+# ifndef alloca /* predefined by HP cc +Olibcalls */ | |
+char *alloca (); | |
+# endif | |
+# endif | |
+# endif | |
+# endif | |
+#endif | |
+ | |
+int main() { | |
+char *p = (char *) alloca(1); | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:1578: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ ac_cv_func_alloca_works=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ ac_cv_func_alloca_works=no | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_func_alloca_works" 1>&6 | |
+if test $ac_cv_func_alloca_works = yes; then | |
+ cat >> confdefs.h <<\EOF | |
+#define HAVE_ALLOCA 1 | |
+EOF | |
+ | |
+fi | |
+ | |
+if test $ac_cv_func_alloca_works = no; then | |
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions | |
+ # that cause trouble. Some versions do not even contain alloca or | |
+ # contain a buggy version. If you still want to use their alloca, | |
+ # use ar to extract alloca.o from them instead of compiling alloca.c. | |
+ ALLOCA=alloca.${ac_objext} | |
+ cat >> confdefs.h <<\EOF | |
+#define C_ALLOCA 1 | |
+EOF | |
+ | |
+ | |
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 | |
+echo "configure:1610: checking whether alloca needs Cray hooks" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1615 "configure" | |
+#include "confdefs.h" | |
+#if defined(CRAY) && ! defined(CRAY2) | |
+webecray | |
+#else | |
+wenotbecray | |
+#endif | |
+ | |
+EOF | |
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | | |
+ egrep "webecray" >/dev/null 2>&1; then | |
+ rm -rf conftest* | |
+ ac_cv_os_cray=yes | |
+else | |
+ rm -rf conftest* | |
+ ac_cv_os_cray=no | |
+fi | |
+rm -f conftest* | |
+ | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_os_cray" 1>&6 | |
+if test $ac_cv_os_cray = yes; then | |
+for ac_func in _getb67 GETB67 getb67; do | |
+ echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
+echo "configure:1640: checking for $ac_func" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1645 "configure" | |
+#include "confdefs.h" | |
+/* System header to define __stub macros and hopefully few prototypes, | |
+ which can conflict with char $ac_func(); below. */ | |
+#include <assert.h> | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char $ac_func(); | |
+ | |
+int main() { | |
+ | |
+/* The GNU C library defines this for functions which it implements | |
+ to always fail with ENOSYS. Some functions are actually named | |
+ something starting with __ and the normal name is an alias. */ | |
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) | |
+choke me | |
+#else | |
+$ac_func(); | |
+#endif | |
+ | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:1668: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ cat >> confdefs.h <<EOF | |
+#define CRAY_STACKSEG_END $ac_func | |
+EOF | |
+ | |
+ break | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+done | |
+fi | |
+ | |
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 | |
+echo "configure:1695: checking stack direction for C alloca" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ if test "$cross_compiling" = yes; then | |
+ ac_cv_c_stack_direction=0 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1703 "configure" | |
+#include "confdefs.h" | |
+find_stack_direction () | |
+{ | |
+ static char *addr = 0; | |
+ auto char dummy; | |
+ if (addr == 0) | |
+ { | |
+ addr = &dummy; | |
+ return find_stack_direction (); | |
+ } | |
+ else | |
+ return (&dummy > addr) ? 1 : -1; | |
+} | |
+main () | |
+{ | |
+ exit (find_stack_direction() < 0); | |
+} | |
+EOF | |
+if { (eval echo configure:1722: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+then | |
+ ac_cv_c_stack_direction=1 | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -fr conftest* | |
+ ac_cv_c_stack_direction=-1 | |
+fi | |
+rm -fr conftest* | |
+fi | |
+ | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&6 | |
+cat >> confdefs.h <<EOF | |
+#define STACK_DIRECTION $ac_cv_c_stack_direction | |
+EOF | |
+ | |
+fi | |
+ | |
+for ac_hdr in unistd.h | |
+do | |
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` | |
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 | |
+echo "configure:1747: checking for $ac_hdr" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1752 "configure" | |
+#include "confdefs.h" | |
+#include <$ac_hdr> | |
+EOF | |
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
+{ (eval echo configure:1757: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
+if test -z "$ac_err"; then | |
+ rm -rf conftest* | |
+ eval "ac_cv_header_$ac_safe=yes" | |
+else | |
+ echo "$ac_err" >&5 | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_header_$ac_safe=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEF… | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_hdr 1 | |
+EOF | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+done | |
+ | |
+for ac_func in getpagesize | |
+do | |
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
+echo "configure:1786: checking for $ac_func" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1791 "configure" | |
+#include "confdefs.h" | |
+/* System header to define __stub macros and hopefully few prototypes, | |
+ which can conflict with char $ac_func(); below. */ | |
+#include <assert.h> | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char $ac_func(); | |
+ | |
+int main() { | |
+ | |
+/* The GNU C library defines this for functions which it implements | |
+ to always fail with ENOSYS. Some functions are actually named | |
+ something starting with __ and the normal name is an alias. */ | |
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) | |
+choke me | |
+#else | |
+$ac_func(); | |
+#endif | |
+ | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:1814: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGH… | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_func 1 | |
+EOF | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+done | |
+ | |
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6 | |
+echo "configure:1839: checking for working mmap" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ if test "$cross_compiling" = yes; then | |
+ ac_cv_func_mmap_fixed_mapped=no | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 1847 "configure" | |
+#include "confdefs.h" | |
+ | |
+/* Thanks to Mike Haertel and Jim Avera for this test. | |
+ Here is a matrix of mmap possibilities: | |
+ mmap private not fixed | |
+ mmap private fixed at somewhere currently unmapped | |
+ mmap private fixed at somewhere already mapped | |
+ mmap shared not fixed | |
+ mmap shared fixed at somewhere currently unmapped | |
+ mmap shared fixed at somewhere already mapped | |
+ For private mappings, we should verify that changes cannot be read() | |
+ back from the file, nor mmap's back from the file at a different | |
+ address. (There have been systems where private was not correctly | |
+ implemented like the infamous i386 svr4.0, and systems where the | |
+ VM page cache was not coherent with the filesystem buffer cache | |
+ like early versions of FreeBSD and possibly contemporary NetBSD.) | |
+ For shared mappings, we should conversely verify that changes get | |
+ propogated back to all the places they're supposed to be. | |
+ | |
+ Grep wants private fixed already mapped. | |
+ The main things grep needs to know about mmap are: | |
+ * does it exist and is it safe to write into the mmap'd area | |
+ * how to use it (BSD variants) */ | |
+#include <sys/types.h> | |
+#include <fcntl.h> | |
+#include <sys/mman.h> | |
+ | |
+/* This mess was copied from the GNU getpagesize.h. */ | |
+#ifndef HAVE_GETPAGESIZE | |
+# ifdef HAVE_UNISTD_H | |
+# include <unistd.h> | |
+# endif | |
+ | |
+/* Assume that all systems that can run configure have sys/param.h. */ | |
+# ifndef HAVE_SYS_PARAM_H | |
+# define HAVE_SYS_PARAM_H 1 | |
+# endif | |
+ | |
+# ifdef _SC_PAGESIZE | |
+# define getpagesize() sysconf(_SC_PAGESIZE) | |
+# else /* no _SC_PAGESIZE */ | |
+# ifdef HAVE_SYS_PARAM_H | |
+# include <sys/param.h> | |
+# ifdef EXEC_PAGESIZE | |
+# define getpagesize() EXEC_PAGESIZE | |
+# else /* no EXEC_PAGESIZE */ | |
+# ifdef NBPG | |
+# define getpagesize() NBPG * CLSIZE | |
+# ifndef CLSIZE | |
+# define CLSIZE 1 | |
+# endif /* no CLSIZE */ | |
+# else /* no NBPG */ | |
+# ifdef NBPC | |
+# define getpagesize() NBPC | |
+# else /* no NBPC */ | |
+# ifdef PAGESIZE | |
+# define getpagesize() PAGESIZE | |
+# endif /* PAGESIZE */ | |
+# endif /* no NBPC */ | |
+# endif /* no NBPG */ | |
+# endif /* no EXEC_PAGESIZE */ | |
+# else /* no HAVE_SYS_PARAM_H */ | |
+# define getpagesize() 8192 /* punt totally */ | |
+# endif /* no HAVE_SYS_PARAM_H */ | |
+# endif /* no _SC_PAGESIZE */ | |
+ | |
+#endif /* no HAVE_GETPAGESIZE */ | |
+ | |
+#ifdef __cplusplus | |
+extern "C" { void *malloc(unsigned); } | |
+#else | |
+char *malloc(); | |
+#endif | |
+ | |
+int | |
+main() | |
+{ | |
+ char *data, *data2, *data3; | |
+ int i, pagesize; | |
+ int fd; | |
+ | |
+ pagesize = getpagesize(); | |
+ | |
+ /* | |
+ * First, make a file with some known garbage in it. | |
+ */ | |
+ data = malloc(pagesize); | |
+ if (!data) | |
+ exit(1); | |
+ for (i = 0; i < pagesize; ++i) | |
+ *(data + i) = rand(); | |
+ umask(0); | |
+ fd = creat("conftestmmap", 0600); | |
+ if (fd < 0) | |
+ exit(1); | |
+ if (write(fd, data, pagesize) != pagesize) | |
+ exit(1); | |
+ close(fd); | |
+ | |
+ /* | |
+ * Next, try to mmap the file at a fixed address which | |
+ * already has something else allocated at it. If we can, | |
+ * also make sure that we see the same garbage. | |
+ */ | |
+ fd = open("conftestmmap", O_RDWR); | |
+ if (fd < 0) | |
+ exit(1); | |
+ data2 = malloc(2 * pagesize); | |
+ if (!data2) | |
+ exit(1); | |
+ data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1); | |
+ if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE, | |
+ MAP_PRIVATE | MAP_FIXED, fd, 0L)) | |
+ exit(1); | |
+ for (i = 0; i < pagesize; ++i) | |
+ if (*(data + i) != *(data2 + i)) | |
+ exit(1); | |
+ | |
+ /* | |
+ * Finally, make sure that changes to the mapped area | |
+ * do not percolate back to the file as seen by read(). | |
+ * (This is a bug on some variants of i386 svr4.0.) | |
+ */ | |
+ for (i = 0; i < pagesize; ++i) | |
+ *(data2 + i) = *(data2 + i) + 1; | |
+ data3 = malloc(pagesize); | |
+ if (!data3) | |
+ exit(1); | |
+ if (read(fd, data3, pagesize) != pagesize) | |
+ exit(1); | |
+ for (i = 0; i < pagesize; ++i) | |
+ if (*(data + i) != *(data3 + i)) | |
+ exit(1); | |
+ close(fd); | |
+ unlink("conftestmmap"); | |
+ exit(0); | |
+} | |
+ | |
+EOF | |
+if { (eval echo configure:1987: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+then | |
+ ac_cv_func_mmap_fixed_mapped=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -fr conftest* | |
+ ac_cv_func_mmap_fixed_mapped=no | |
+fi | |
+rm -fr conftest* | |
+fi | |
+ | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6 | |
+if test $ac_cv_func_mmap_fixed_mapped = yes; then | |
+ cat >> confdefs.h <<\EOF | |
+#define HAVE_MMAP 1 | |
+EOF | |
+ | |
+fi | |
+ | |
+ | |
+ for ac_hdr in argz.h limits.h locale.h nl_types.h malloc.h string.h \ | |
+unistd.h sys/param.h | |
+do | |
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` | |
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 | |
+echo "configure:2015: checking for $ac_hdr" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 2020 "configure" | |
+#include "confdefs.h" | |
+#include <$ac_hdr> | |
+EOF | |
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
+{ (eval echo configure:2025: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
+if test -z "$ac_err"; then | |
+ rm -rf conftest* | |
+ eval "ac_cv_header_$ac_safe=yes" | |
+else | |
+ echo "$ac_err" >&5 | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_header_$ac_safe=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEF… | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_hdr 1 | |
+EOF | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+done | |
+ | |
+ for ac_func in getcwd munmap putenv setenv setlocale strchr strcasecmp \ | |
+strdup __argz_count __argz_stringify __argz_next | |
+do | |
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
+echo "configure:2055: checking for $ac_func" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 2060 "configure" | |
+#include "confdefs.h" | |
+/* System header to define __stub macros and hopefully few prototypes, | |
+ which can conflict with char $ac_func(); below. */ | |
+#include <assert.h> | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char $ac_func(); | |
+ | |
+int main() { | |
+ | |
+/* The GNU C library defines this for functions which it implements | |
+ to always fail with ENOSYS. Some functions are actually named | |
+ something starting with __ and the normal name is an alias. */ | |
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) | |
+choke me | |
+#else | |
+$ac_func(); | |
+#endif | |
+ | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:2083: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGH… | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_func 1 | |
+EOF | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+done | |
+ | |
+ | |
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then | |
+ for ac_func in stpcpy | |
+do | |
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
+echo "configure:2112: checking for $ac_func" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 2117 "configure" | |
+#include "confdefs.h" | |
+/* System header to define __stub macros and hopefully few prototypes, | |
+ which can conflict with char $ac_func(); below. */ | |
+#include <assert.h> | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char $ac_func(); | |
+ | |
+int main() { | |
+ | |
+/* The GNU C library defines this for functions which it implements | |
+ to always fail with ENOSYS. Some functions are actually named | |
+ something starting with __ and the normal name is an alias. */ | |
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) | |
+choke me | |
+#else | |
+$ac_func(); | |
+#endif | |
+ | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:2140: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGH… | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_func 1 | |
+EOF | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+done | |
+ | |
+ fi | |
+ if test "${ac_cv_func_stpcpy}" = "yes"; then | |
+ cat >> confdefs.h <<\EOF | |
+#define HAVE_STPCPY 1 | |
+EOF | |
+ | |
+ fi | |
+ | |
+ if test $ac_cv_header_locale_h = yes; then | |
+ echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6 | |
+echo "configure:2174: checking for LC_MESSAGES" >&5 | |
+if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 2179 "configure" | |
+#include "confdefs.h" | |
+#include <locale.h> | |
+int main() { | |
+return LC_MESSAGES | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:2186: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ am_cv_val_LC_MESSAGES=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ am_cv_val_LC_MESSAGES=no | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+echo "$ac_t""$am_cv_val_LC_MESSAGES" 1>&6 | |
+ if test $am_cv_val_LC_MESSAGES = yes; then | |
+ cat >> confdefs.h <<\EOF | |
+#define HAVE_LC_MESSAGES 1 | |
+EOF | |
+ | |
+ fi | |
+ fi | |
+ echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6 | |
+echo "configure:2207: checking whether NLS is requested" >&5 | |
+ # Check whether --enable-nls or --disable-nls was given. | |
+if test "${enable_nls+set}" = set; then | |
+ enableval="$enable_nls" | |
+ USE_NLS=$enableval | |
+else | |
+ USE_NLS=yes | |
+fi | |
+ | |
+ echo "$ac_t""$USE_NLS" 1>&6 | |
+ | |
+ | |
+ USE_INCLUDED_LIBINTL=no | |
+ | |
+ if test "$USE_NLS" = "yes"; then | |
+ cat >> confdefs.h <<\EOF | |
+#define ENABLE_NLS 1 | |
+EOF | |
+ | |
+ echo $ac_n "checking whether included gettext is requested""... $ac_c" 1… | |
+echo "configure:2227: checking whether included gettext is requested" >&5 | |
+ # Check whether --with-included-gettext or --without-included-gettext wa… | |
+if test "${with_included_gettext+set}" = set; then | |
+ withval="$with_included_gettext" | |
+ nls_cv_force_use_gnu_gettext=$withval | |
+else | |
+ nls_cv_force_use_gnu_gettext=no | |
+fi | |
+ | |
+ echo "$ac_t""$nls_cv_force_use_gnu_gettext" 1>&6 | |
+ | |
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext" | |
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then | |
+ nls_cv_header_intl= | |
+ nls_cv_header_libgt= | |
+ CATOBJEXT=NONE | |
+ | |
+ ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'` | |
+echo $ac_n "checking for libintl.h""... $ac_c" 1>&6 | |
+echo "configure:2246: checking for libintl.h" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 2251 "configure" | |
+#include "confdefs.h" | |
+#include <libintl.h> | |
+EOF | |
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
+{ (eval echo configure:2256: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
+if test -z "$ac_err"; then | |
+ rm -rf conftest* | |
+ eval "ac_cv_header_$ac_safe=yes" | |
+else | |
+ echo "$ac_err" >&5 | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_header_$ac_safe=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6 | |
+echo "configure:2273: checking for gettext in libc" >&5 | |
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 2278 "configure" | |
+#include "confdefs.h" | |
+#include <libintl.h> | |
+int main() { | |
+return (int) gettext ("") | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:2285: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ gt_cv_func_gettext_libc=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ gt_cv_func_gettext_libc=no | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6 | |
+ | |
+ if test "$gt_cv_func_gettext_libc" != "yes"; then | |
+ echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 | |
+echo "configure:2301: checking for bindtextdomain in -lintl" >&5 | |
+ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` | |
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ ac_save_LIBS="$LIBS" | |
+LIBS="-lintl $LIBS" | |
+cat > conftest.$ac_ext <<EOF | |
+#line 2309 "configure" | |
+#include "confdefs.h" | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char bindtextdomain(); | |
+ | |
+int main() { | |
+bindtextdomain() | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:2320: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=no" | |
+fi | |
+rm -f conftest* | |
+LIBS="$ac_save_LIBS" | |
+ | |
+fi | |
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6 | |
+echo "configure:2336: checking for gettext in libintl" >&5 | |
+if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6 | |
+echo "configure:2341: checking for gettext in -lintl" >&5 | |
+ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'` | |
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ ac_save_LIBS="$LIBS" | |
+LIBS="-lintl $LIBS" | |
+cat > conftest.$ac_ext <<EOF | |
+#line 2349 "configure" | |
+#include "confdefs.h" | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char gettext(); | |
+ | |
+int main() { | |
+gettext() | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:2360: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=no" | |
+fi | |
+rm -f conftest* | |
+LIBS="$ac_save_LIBS" | |
+ | |
+fi | |
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ gt_cv_func_gettext_libintl=yes | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+gt_cv_func_gettext_libintl=no | |
+fi | |
+ | |
+fi | |
+ | |
+echo "$ac_t""$gt_cv_func_gettext_libintl" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ fi | |
+ | |
+ if test "$gt_cv_func_gettext_libc" = "yes" \ | |
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then | |
+ cat >> confdefs.h <<\EOF | |
+#define HAVE_GETTEXT 1 | |
+EOF | |
+ | |
+ # Extract the first word of "msgfmt", so it can be a program nam… | |
+set dummy msgfmt; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:2399: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$MSGFMT" in | |
+ /*) | |
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" | |
+ for ac_dir in $PATH; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then | |
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no" | |
+ ;; | |
+esac | |
+fi | |
+MSGFMT="$ac_cv_path_MSGFMT" | |
+if test -n "$MSGFMT"; then | |
+ echo "$ac_t""$MSGFMT" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ if test "$MSGFMT" != "no"; then | |
+ for ac_func in dcgettext | |
+do | |
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
+echo "configure:2433: checking for $ac_func" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 2438 "configure" | |
+#include "confdefs.h" | |
+/* System header to define __stub macros and hopefully few prototypes, | |
+ which can conflict with char $ac_func(); below. */ | |
+#include <assert.h> | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char $ac_func(); | |
+ | |
+int main() { | |
+ | |
+/* The GNU C library defines this for functions which it implements | |
+ to always fail with ENOSYS. Some functions are actually named | |
+ something starting with __ and the normal name is an alias. */ | |
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) | |
+choke me | |
+#else | |
+$ac_func(); | |
+#endif | |
+ | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:2461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGH… | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_func 1 | |
+EOF | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+done | |
+ | |
+ # Extract the first word of "gmsgfmt", so it can be a program … | |
+set dummy gmsgfmt; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:2488: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$GMSGFMT" in | |
+ /*) | |
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. | |
+ ;; | |
+ ?:/*) | |
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos pa… | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" | |
+ ac_dummy="$PATH" | |
+ for ac_dir in $ac_dummy; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" | |
+ ;; | |
+esac | |
+fi | |
+GMSGFMT="$ac_cv_path_GMSGFMT" | |
+if test -n "$GMSGFMT"; then | |
+ echo "$ac_t""$GMSGFMT" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ # Extract the first word of "xgettext", so it can be a program… | |
+set dummy xgettext; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:2524: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$XGETTEXT" in | |
+ /*) | |
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" | |
+ for ac_dir in $PATH; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then | |
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" | |
+ ;; | |
+esac | |
+fi | |
+XGETTEXT="$ac_cv_path_XGETTEXT" | |
+if test -n "$XGETTEXT"; then | |
+ echo "$ac_t""$XGETTEXT" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 2556 "configure" | |
+#include "confdefs.h" | |
+ | |
+int main() { | |
+extern int _nl_msg_cat_cntr; | |
+ return _nl_msg_cat_cntr | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:2564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ CATOBJEXT=.gmo | |
+ DATADIRNAME=share | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ CATOBJEXT=.mo | |
+ DATADIRNAME=lib | |
+fi | |
+rm -f conftest* | |
+ INSTOBJEXT=.mo | |
+ fi | |
+ fi | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ | |
+ if test "$CATOBJEXT" = "NONE"; then | |
+ echo $ac_n "checking whether catgets can be used""... $ac_c" 1>&6 | |
+echo "configure:2587: checking whether catgets can be used" >&5 | |
+ # Check whether --with-catgets or --without-catgets was given. | |
+if test "${with_catgets+set}" = set; then | |
+ withval="$with_catgets" | |
+ nls_cv_use_catgets=$withval | |
+else | |
+ nls_cv_use_catgets=no | |
+fi | |
+ | |
+ echo "$ac_t""$nls_cv_use_catgets" 1>&6 | |
+ | |
+ if test "$nls_cv_use_catgets" = "yes"; then | |
+ echo $ac_n "checking for main in -li""... $ac_c" 1>&6 | |
+echo "configure:2600: checking for main in -li" >&5 | |
+ac_lib_var=`echo i'_'main | sed 'y%./+-%__p_%'` | |
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ ac_save_LIBS="$LIBS" | |
+LIBS="-li $LIBS" | |
+cat > conftest.$ac_ext <<EOF | |
+#line 2608 "configure" | |
+#include "confdefs.h" | |
+ | |
+int main() { | |
+main() | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:2615: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=no" | |
+fi | |
+rm -f conftest* | |
+LIBS="$ac_save_LIBS" | |
+ | |
+fi | |
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_lib=HAVE_LIB`echo i | sed -e 's/[^a-zA-Z0-9_]/_/g' \ | |
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_lib 1 | |
+EOF | |
+ | |
+ LIBS="-li $LIBS" | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ echo $ac_n "checking for catgets""... $ac_c" 1>&6 | |
+echo "configure:2643: checking for catgets" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_catgets'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 2648 "configure" | |
+#include "confdefs.h" | |
+/* System header to define __stub macros and hopefully few prototypes, | |
+ which can conflict with char catgets(); below. */ | |
+#include <assert.h> | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char catgets(); | |
+ | |
+int main() { | |
+ | |
+/* The GNU C library defines this for functions which it implements | |
+ to always fail with ENOSYS. Some functions are actually named | |
+ something starting with __ and the normal name is an alias. */ | |
+#if defined (__stub_catgets) || defined (__stub___catgets) | |
+choke me | |
+#else | |
+catgets(); | |
+#endif | |
+ | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:2671: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_catgets=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_catgets=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+if eval "test \"`echo '$ac_cv_func_'catgets`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ cat >> confdefs.h <<\EOF | |
+#define HAVE_CATGETS 1 | |
+EOF | |
+ | |
+ INTLOBJS="\$(CATOBJS)" | |
+ # Extract the first word of "gencat", so it can be a program na… | |
+set dummy gencat; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:2693: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$GENCAT" in | |
+ /*) | |
+ ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a path. | |
+ ;; | |
+ ?:/*) | |
+ ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a dos path. | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" | |
+ ac_dummy="$PATH" | |
+ for ac_dir in $ac_dummy; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ ac_cv_path_GENCAT="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_GENCAT" && ac_cv_path_GENCAT="no" | |
+ ;; | |
+esac | |
+fi | |
+GENCAT="$ac_cv_path_GENCAT" | |
+if test -n "$GENCAT"; then | |
+ echo "$ac_t""$GENCAT" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ if test "$GENCAT" != "no"; then | |
+ # Extract the first word of "gmsgfmt", so it can be a program… | |
+set dummy gmsgfmt; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:2729: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$GMSGFMT" in | |
+ /*) | |
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. | |
+ ;; | |
+ ?:/*) | |
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos pa… | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" | |
+ ac_dummy="$PATH" | |
+ for ac_dir in $ac_dummy; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no" | |
+ ;; | |
+esac | |
+fi | |
+GMSGFMT="$ac_cv_path_GMSGFMT" | |
+if test -n "$GMSGFMT"; then | |
+ echo "$ac_t""$GMSGFMT" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ if test "$GMSGFMT" = "no"; then | |
+ # Extract the first word of "msgfmt", so it can be a progra… | |
+set dummy msgfmt; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:2766: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$GMSGFMT" in | |
+ /*) | |
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" | |
+ for ac_dir in $PATH; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then | |
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="no" | |
+ ;; | |
+esac | |
+fi | |
+GMSGFMT="$ac_cv_path_GMSGFMT" | |
+if test -n "$GMSGFMT"; then | |
+ echo "$ac_t""$GMSGFMT" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ fi | |
+ # Extract the first word of "xgettext", so it can be a progra… | |
+set dummy xgettext; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:2801: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$XGETTEXT" in | |
+ /*) | |
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" | |
+ for ac_dir in $PATH; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then | |
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" | |
+ ;; | |
+esac | |
+fi | |
+XGETTEXT="$ac_cv_path_XGETTEXT" | |
+if test -n "$XGETTEXT"; then | |
+ echo "$ac_t""$XGETTEXT" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ USE_INCLUDED_LIBINTL=yes | |
+ CATOBJEXT=.cat | |
+ INSTOBJEXT=.cat | |
+ DATADIRNAME=lib | |
+ INTLDEPS='$(top_builddir)/intl/libintl.a' | |
+ INTLLIBS=$INTLDEPS | |
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'` | |
+ nls_cv_header_intl=intl/libintl.h | |
+ nls_cv_header_libgt=intl/libgettext.h | |
+ fi | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ fi | |
+ fi | |
+ | |
+ if test "$CATOBJEXT" = "NONE"; then | |
+ nls_cv_use_gnu_gettext=yes | |
+ fi | |
+ fi | |
+ | |
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then | |
+ INTLOBJS="\$(GETTOBJS)" | |
+ # Extract the first word of "msgfmt", so it can be a program name with… | |
+set dummy msgfmt; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:2859: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$MSGFMT" in | |
+ /*) | |
+ ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path. | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" | |
+ for ac_dir in $PATH; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then | |
+ ac_cv_path_MSGFMT="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="msgfmt" | |
+ ;; | |
+esac | |
+fi | |
+MSGFMT="$ac_cv_path_MSGFMT" | |
+if test -n "$MSGFMT"; then | |
+ echo "$ac_t""$MSGFMT" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ # Extract the first word of "gmsgfmt", so it can be a program name wit… | |
+set dummy gmsgfmt; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:2893: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$GMSGFMT" in | |
+ /*) | |
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path. | |
+ ;; | |
+ ?:/*) | |
+ ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos pa… | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" | |
+ ac_dummy="$PATH" | |
+ for ac_dir in $ac_dummy; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ ac_cv_path_GMSGFMT="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT" | |
+ ;; | |
+esac | |
+fi | |
+GMSGFMT="$ac_cv_path_GMSGFMT" | |
+if test -n "$GMSGFMT"; then | |
+ echo "$ac_t""$GMSGFMT" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ # Extract the first word of "xgettext", so it can be a program name wi… | |
+set dummy xgettext; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:2929: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$XGETTEXT" in | |
+ /*) | |
+ ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path. | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" | |
+ for ac_dir in $PATH; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then | |
+ ac_cv_path_XGETTEXT="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":" | |
+ ;; | |
+esac | |
+fi | |
+XGETTEXT="$ac_cv_path_XGETTEXT" | |
+if test -n "$XGETTEXT"; then | |
+ echo "$ac_t""$XGETTEXT" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ | |
+ USE_INCLUDED_LIBINTL=yes | |
+ CATOBJEXT=.gmo | |
+ INSTOBJEXT=.mo | |
+ DATADIRNAME=share | |
+ INTLDEPS='$(top_builddir)/intl/libintl.a' | |
+ INTLLIBS=$INTLDEPS | |
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'` | |
+ nls_cv_header_intl=intl/libintl.h | |
+ nls_cv_header_libgt=intl/libgettext.h | |
+ fi | |
+ | |
+ if test "$XGETTEXT" != ":"; then | |
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then | |
+ : ; | |
+ else | |
+ echo "$ac_t""found xgettext program is not GNU xgettext; ignore it" … | |
+ XGETTEXT=":" | |
+ fi | |
+ fi | |
+ | |
+ # We need to process the po/ directory. | |
+ POSUB=po | |
+ else | |
+ DATADIRNAME=share | |
+ nls_cv_header_intl=intl/libintl.h | |
+ nls_cv_header_libgt=intl/libgettext.h | |
+ fi | |
+ | |
+ | |
+ | |
+ | |
+ # If this is used in GNU gettext we have to set USE_NLS to `yes' | |
+ # because some of the sources are only built for this goal. | |
+ if test "$PACKAGE" = gettext; then | |
+ USE_NLS=yes | |
+ USE_INCLUDED_LIBINTL=yes | |
+ fi | |
+ | |
+ for lang in $ALL_LINGUAS; do | |
+ GMOFILES="$GMOFILES $lang.gmo" | |
+ POFILES="$POFILES $lang.po" | |
+ done | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ | |
+ if test "x$CATOBJEXT" != "x"; then | |
+ if test "x$ALL_LINGUAS" = "x"; then | |
+ LINGUAS= | |
+ else | |
+ echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6 | |
+echo "configure:3022: checking for catalogs to be installed" >&5 | |
+ NEW_LINGUAS= | |
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do | |
+ case "$ALL_LINGUAS" in | |
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; | |
+ esac | |
+ done | |
+ LINGUAS=$NEW_LINGUAS | |
+ echo "$ac_t""$LINGUAS" 1>&6 | |
+ fi | |
+ | |
+ if test -n "$LINGUAS"; then | |
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done | |
+ fi | |
+ fi | |
+ | |
+ if test $ac_cv_header_locale_h = yes; then | |
+ INCLUDE_LOCALE_H="#include <locale.h>" | |
+ else | |
+ INCLUDE_LOCALE_H="\ | |
+/* The system does not provide the header <locale.h>. Take care yourself. */" | |
+ fi | |
+ | |
+ | |
+ test -d intl || mkdir intl | |
+ if test "$CATOBJEXT" = ".cat"; then | |
+ ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'` | |
+echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6 | |
+echo "configure:3050: checking for linux/version.h" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3055 "configure" | |
+#include "confdefs.h" | |
+#include <linux/version.h> | |
+EOF | |
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
+{ (eval echo configure:3060: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
+if test -z "$ac_err"; then | |
+ rm -rf conftest* | |
+ eval "ac_cv_header_$ac_safe=yes" | |
+else | |
+ echo "$ac_err" >&5 | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_header_$ac_safe=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ msgformat=linux | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+msgformat=xopen | |
+fi | |
+ | |
+ | |
+ sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed | |
+ fi | |
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \ | |
+ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed | |
+ | |
+ if test "$PACKAGE" = "gettext"; then | |
+ GT_NO="#NO#" | |
+ GT_YES= | |
+ else | |
+ GT_NO= | |
+ GT_YES="#YES#" | |
+ fi | |
+ | |
+ | |
+ | |
+ MKINSTALLDIRS= | |
+ if test -n "$ac_aux_dir"; then | |
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" | |
+ fi | |
+ if test -z "$MKINSTALLDIRS"; then | |
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" | |
+ fi | |
+ | |
+ | |
+ l= | |
+ | |
+ | |
+ test -d po || mkdir po | |
+ if test "x$srcdir" != "x."; then | |
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then | |
+ posrcprefix="$srcdir/" | |
+ else | |
+ posrcprefix="../$srcdir/" | |
+ fi | |
+ else | |
+ posrcprefix="../" | |
+ fi | |
+ rm -f po/POTFILES | |
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(… | |
+ < $srcdir/po/POTFILES.in > po/POTFILES | |
+ | |
+if test "$gt_cv_func_gettext_libintl" = "yes"; then | |
+ LIBS="-lintl $LIBS" | |
+fi | |
+ | |
+localedir=${datadir}/locale | |
+ | |
+ | |
+# Check whether --enable-gtk-client or --disable-gtk-client was given. | |
+if test "${enable_gtk_client+set}" = set; then | |
+ enableval="$enable_gtk_client" | |
+ GTK_CLIENT="$enableval" | |
+else | |
+ GTK_CLIENT="yes" | |
+fi | |
+ | |
+ | |
+# Check whether --enable-curses-client or --disable-curses-client was given. | |
+if test "${enable_curses_client+set}" = set; then | |
+ enableval="$enable_curses_client" | |
+ CURSES_CLIENT="$enableval" | |
+else | |
+ CURSES_CLIENT="yes" | |
+fi | |
+ | |
+ | |
+# Check whether --enable-win32-client or --disable-win32-client was given. | |
+if test "${enable_win32_client+set}" = set; then | |
+ enableval="$enable_win32_client" | |
+ WIN32_CLIENT="$enableval" | |
+else | |
+ WIN32_CLIENT="yes" | |
+fi | |
+ | |
+ | |
+WIN_RC="" | |
+WIN_RES="" | |
+WIN_MAKE_RES="/dev/null" | |
+ | |
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 | |
+echo "configure:3163: checking for Cygwin environment" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3168 "configure" | |
+#include "confdefs.h" | |
+ | |
+int main() { | |
+ | |
+#ifndef __CYGWIN__ | |
+#define __CYGWIN__ __CYGWIN32__ | |
+#endif | |
+return __CYGWIN__; | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:3179: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+ rm -rf conftest* | |
+ ac_cv_cygwin=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ ac_cv_cygwin=no | |
+fi | |
+rm -f conftest* | |
+rm -f conftest* | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_cygwin" 1>&6 | |
+CYGWIN= | |
+test "$ac_cv_cygwin" = yes && CYGWIN=yes | |
+# Check whether --enable-nativewin32 or --disable-nativewin32 was given. | |
+if test "${enable_nativewin32+set}" = set; then | |
+ enableval="$enable_nativewin32" | |
+ CYGWIN="$enableval" | |
+fi | |
+ | |
+ | |
+if test "$CYGWIN" = "yes" ; then | |
+ echo "$ac_t"""Configuring for native Win32 binary under Cygwin"" 1>&6 | |
+ cat >> confdefs.h <<\EOF | |
+#define CYGWIN 1 | |
+EOF | |
+ | |
+ CFLAGS="$CFLAGS -mwindows -fnative-struct -mno-cygwin" | |
+ LIBS="$LIBS -lwsock32 -lcomctl32" | |
+ if test "$WIN32_CLIENT" = "yes" ; then | |
+ WIN_RC="dopewars.rc" | |
+ WIN_RES="dopewars.res" | |
+ WIN_MAKE_RES="$srcdir/cygwin.am" | |
+ cat >> confdefs.h <<\EOF | |
+#define WIN32_CLIENT 1 | |
+EOF | |
+ | |
+ fi | |
+ GTK_CLIENT="no" | |
+ | |
+ LDFLAGS="$LDFLAGS -lglib-1.3" | |
+else | |
+ echo "$ac_t"""Configuring for Unix binary"" 1>&6 | |
+ if test "$CURSES_CLIENT" = "yes" ; then | |
+ echo $ac_n "checking for initscr in -lncurses""... $ac_c" 1>&6 | |
+echo "configure:3226: checking for initscr in -lncurses" >&5 | |
+ac_lib_var=`echo ncurses'_'initscr | sed 'y%./+-%__p_%'` | |
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ ac_save_LIBS="$LIBS" | |
+LIBS="-lncurses $LIBS" | |
+cat > conftest.$ac_ext <<EOF | |
+#line 3234 "configure" | |
+#include "confdefs.h" | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char initscr(); | |
+ | |
+int main() { | |
+initscr() | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:3245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=no" | |
+fi | |
+rm -f conftest* | |
+LIBS="$ac_save_LIBS" | |
+ | |
+fi | |
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_lib=HAVE_LIB`echo ncurses | sed -e 's/[^a-zA-Z0-9_]/_/g' \ | |
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_lib 1 | |
+EOF | |
+ | |
+ LIBS="-lncurses $LIBS" | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ if test "$ac_cv_lib_ncurses_initscr" = "no" ; then | |
+ echo $ac_n "checking for initscr in -lcurses""... $ac_c" 1>&6 | |
+echo "configure:3274: checking for initscr in -lcurses" >&5 | |
+ac_lib_var=`echo curses'_'initscr | sed 'y%./+-%__p_%'` | |
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ ac_save_LIBS="$LIBS" | |
+LIBS="-lcurses $LIBS" | |
+cat > conftest.$ac_ext <<EOF | |
+#line 3282 "configure" | |
+#include "confdefs.h" | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char initscr(); | |
+ | |
+int main() { | |
+initscr() | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:3293: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=no" | |
+fi | |
+rm -f conftest* | |
+LIBS="$ac_save_LIBS" | |
+ | |
+fi | |
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_lib=HAVE_LIB`echo curses | sed -e 's/[^a-zA-Z0-9_]/_/g' \ | |
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_lib 1 | |
+EOF | |
+ | |
+ LIBS="-lcurses $LIBS" | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ if test "$ac_cv_lib_curses_initscr" = "no" ; then | |
+ echo $ac_n "checking for initscr in -lcur_colr""... $ac_c" 1>&6 | |
+echo "configure:3322: checking for initscr in -lcur_colr" >&5 | |
+ac_lib_var=`echo cur_colr'_'initscr | sed 'y%./+-%__p_%'` | |
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ ac_save_LIBS="$LIBS" | |
+LIBS="-lcur_colr $LIBS" | |
+cat > conftest.$ac_ext <<EOF | |
+#line 3330 "configure" | |
+#include "confdefs.h" | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char initscr(); | |
+ | |
+int main() { | |
+initscr() | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:3341: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=no" | |
+fi | |
+rm -f conftest* | |
+LIBS="$ac_save_LIBS" | |
+ | |
+fi | |
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_lib=HAVE_LIB`echo cur_colr | sed -e 's/[^a-zA-Z0-9_]/_/g' \ | |
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_lib 1 | |
+EOF | |
+ | |
+ LIBS="-lcur_colr $LIBS" | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ if test "$ac_cv_lib_cur_colr_initscr" = "no" ; then | |
+ echo "configure: warning: Cannot find any curses-type library" … | |
+ CURSES_CLIENT="no" | |
+ fi | |
+ fi | |
+ fi | |
+ fi | |
+ | |
+ if test "$GTK_CLIENT" = "yes" ; then | |
+ # Check whether --with-gtk-prefix or --without-gtk-prefix was give… | |
+if test "${with_gtk_prefix+set}" = set; then | |
+ withval="$with_gtk_prefix" | |
+ gtk_config_prefix="$withval" | |
+else | |
+ gtk_config_prefix="" | |
+fi | |
+ | |
+# Check whether --with-gtk-exec-prefix or --without-gtk-exec-prefix was given. | |
+if test "${with_gtk_exec_prefix+set}" = set; then | |
+ withval="$with_gtk_exec_prefix" | |
+ gtk_config_exec_prefix="$withval" | |
+else | |
+ gtk_config_exec_prefix="" | |
+fi | |
+ | |
+# Check whether --enable-gtktest or --disable-gtktest was given. | |
+if test "${enable_gtktest+set}" = set; then | |
+ enableval="$enable_gtktest" | |
+ : | |
+else | |
+ enable_gtktest=yes | |
+fi | |
+ | |
+ | |
+ for module in . | |
+ do | |
+ case "$module" in | |
+ gthread) | |
+ gtk_config_args="$gtk_config_args gthread" | |
+ ;; | |
+ esac | |
+ done | |
+ | |
+ if test x$gtk_config_exec_prefix != x ; then | |
+ gtk_config_args="$gtk_config_args --exec-prefix=$gtk_config_exec_prefix" | |
+ if test x${GTK_CONFIG+set} != xset ; then | |
+ GTK_CONFIG=$gtk_config_exec_prefix/bin/gtk-config | |
+ fi | |
+ fi | |
+ if test x$gtk_config_prefix != x ; then | |
+ gtk_config_args="$gtk_config_args --prefix=$gtk_config_prefix" | |
+ if test x${GTK_CONFIG+set} != xset ; then | |
+ GTK_CONFIG=$gtk_config_prefix/bin/gtk-config | |
+ fi | |
+ fi | |
+ | |
+ # Extract the first word of "gtk-config", so it can be a program name with a… | |
+set dummy gtk-config; ac_word=$2 | |
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 | |
+echo "configure:3427: checking for $ac_word" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_path_GTK_CONFIG'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ case "$GTK_CONFIG" in | |
+ /*) | |
+ ac_cv_path_GTK_CONFIG="$GTK_CONFIG" # Let the user override the test with a … | |
+ ;; | |
+ ?:/*) | |
+ ac_cv_path_GTK_CONFIG="$GTK_CONFIG" # Let the user override the test with a … | |
+ ;; | |
+ *) | |
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" | |
+ ac_dummy="$PATH" | |
+ for ac_dir in $ac_dummy; do | |
+ test -z "$ac_dir" && ac_dir=. | |
+ if test -f $ac_dir/$ac_word; then | |
+ ac_cv_path_GTK_CONFIG="$ac_dir/$ac_word" | |
+ break | |
+ fi | |
+ done | |
+ IFS="$ac_save_ifs" | |
+ test -z "$ac_cv_path_GTK_CONFIG" && ac_cv_path_GTK_CONFIG="no" | |
+ ;; | |
+esac | |
+fi | |
+GTK_CONFIG="$ac_cv_path_GTK_CONFIG" | |
+if test -n "$GTK_CONFIG"; then | |
+ echo "$ac_t""$GTK_CONFIG" 1>&6 | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+ min_gtk_version=1.2.0 | |
+ echo $ac_n "checking for GTK - version >= $min_gtk_version""... $ac_c" 1>&6 | |
+echo "configure:3462: checking for GTK - version >= $min_gtk_version" >&5 | |
+ no_gtk="" | |
+ if test "$GTK_CONFIG" = "no" ; then | |
+ no_gtk=yes | |
+ else | |
+ GTK_CFLAGS=`$GTK_CONFIG $gtk_config_args --cflags` | |
+ GTK_LIBS=`$GTK_CONFIG $gtk_config_args --libs` | |
+ gtk_config_major_version=`$GTK_CONFIG $gtk_config_args --version | \ | |
+ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` | |
+ gtk_config_minor_version=`$GTK_CONFIG $gtk_config_args --version | \ | |
+ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` | |
+ gtk_config_micro_version=`$GTK_CONFIG $gtk_config_args --version | \ | |
+ sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` | |
+ if test "x$enable_gtktest" = "xyes" ; then | |
+ ac_save_CFLAGS="$CFLAGS" | |
+ ac_save_LIBS="$LIBS" | |
+ CFLAGS="$CFLAGS $GTK_CFLAGS" | |
+ LIBS="$GTK_LIBS $LIBS" | |
+ rm -f conf.gtktest | |
+ if test "$cross_compiling" = yes; then | |
+ echo $ac_n "cross compiling; assumed OK... $ac_c" | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3485 "configure" | |
+#include "confdefs.h" | |
+ | |
+#include <gtk/gtk.h> | |
+#include <stdio.h> | |
+#include <stdlib.h> | |
+ | |
+int | |
+main () | |
+{ | |
+ int major, minor, micro; | |
+ char *tmp_version; | |
+ | |
+ system ("touch conf.gtktest"); | |
+ | |
+ /* HP/UX 9 (%@#!) writes to sscanf strings */ | |
+ tmp_version = g_strdup("$min_gtk_version"); | |
+ if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { | |
+ printf("%s, bad version string\n", "$min_gtk_version"); | |
+ exit(1); | |
+ } | |
+ | |
+ if ((gtk_major_version != $gtk_config_major_version) || | |
+ (gtk_minor_version != $gtk_config_minor_version) || | |
+ (gtk_micro_version != $gtk_config_micro_version)) | |
+ { | |
+ printf("\n*** 'gtk-config --version' returned %d.%d.%d, but GTK+ (%d.%d.… | |
+ $gtk_config_major_version, $gtk_config_minor_version, $gtk_config… | |
+ gtk_major_version, gtk_minor_version, gtk_micro_version); | |
+ printf ("*** was found! If gtk-config was correct, then it is best\n"); | |
+ printf ("*** to remove the old version of GTK+. You may also be able to … | |
+ printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by… | |
+ printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\… | |
+ printf("*** required on your system.\n"); | |
+ printf("*** If gtk-config was wrong, set the environment variable GTK_CO… | |
+ printf("*** to point to the correct copy of gtk-config, and remove the f… | |
+ printf("*** before re-running configure\n"); | |
+ } | |
+#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK… | |
+ else if ((gtk_major_version != GTK_MAJOR_VERSION) || | |
+ (gtk_minor_version != GTK_MINOR_VERSION) || | |
+ (gtk_micro_version != GTK_MICRO_VERSION)) | |
+ { | |
+ printf("*** GTK+ header files (version %d.%d.%d) do not match\n", | |
+ GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); | |
+ printf("*** library (version %d.%d.%d)\n", | |
+ gtk_major_version, gtk_minor_version, gtk_micro_version); | |
+ } | |
+#endif /* defined (GTK_MAJOR_VERSION) ... */ | |
+ else | |
+ { | |
+ if ((gtk_major_version > major) || | |
+ ((gtk_major_version == major) && (gtk_minor_version > minor)) || | |
+ ((gtk_major_version == major) && (gtk_minor_version == minor) && (gtk_… | |
+ { | |
+ return 0; | |
+ } | |
+ else | |
+ { | |
+ printf("\n*** An old version of GTK+ (%d.%d.%d) was found.\n", | |
+ gtk_major_version, gtk_minor_version, gtk_micro_version); | |
+ printf("*** You need a version of GTK+ newer than %d.%d.%d. The latest… | |
+ major, minor, micro); | |
+ printf("*** GTK+ is always available from ftp://ftp.gtk.org.\n"); | |
+ printf("***\n"); | |
+ printf("*** If you have already installed a sufficiently new version, … | |
+ printf("*** probably means that the wrong copy of the gtk-config shell… | |
+ printf("*** being found. The easiest way to fix this is to remove the … | |
+ printf("*** of GTK+, but you can also set the GTK_CONFIG environment t… | |
+ printf("*** correct copy of gtk-config. (In this case, you will have t… | |
+ printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /… | |
+ printf("*** so that the correct libraries are found at run-time))\n"); | |
+ } | |
+ } | |
+ return 1; | |
+} | |
+ | |
+EOF | |
+if { (eval echo configure:3563: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+then | |
+ : | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -fr conftest* | |
+ no_gtk=yes | |
+fi | |
+rm -fr conftest* | |
+fi | |
+ | |
+ CFLAGS="$ac_save_CFLAGS" | |
+ LIBS="$ac_save_LIBS" | |
+ fi | |
+ fi | |
+ if test "x$no_gtk" = x ; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ gtk_found="yes" | |
+ else | |
+ echo "$ac_t""no" 1>&6 | |
+ if test "$GTK_CONFIG" = "no" ; then | |
+ echo "*** The gtk-config script installed by GTK could not be found" | |
+ echo "*** If GTK was installed in PREFIX, make sure PREFIX/bin is in" | |
+ echo "*** your path, or set the GTK_CONFIG environment variable to the" | |
+ echo "*** full path to gtk-config." | |
+ else | |
+ if test -f conf.gtktest ; then | |
+ : | |
+ else | |
+ echo "*** Could not run GTK test program, checking why..." | |
+ CFLAGS="$CFLAGS $GTK_CFLAGS" | |
+ LIBS="$LIBS $GTK_LIBS" | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3597 "configure" | |
+#include "confdefs.h" | |
+ | |
+#include <gtk/gtk.h> | |
+#include <stdio.h> | |
+ | |
+int main() { | |
+ return ((gtk_major_version) || (gtk_minor_version) || (gtk_micro_version)); | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:3607: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ echo "*** The test program compiled, but did not run. This usually means" | |
+ echo "*** that the run-time linker is not finding GTK or finding the… | |
+ echo "*** version of GTK. If it is not finding GTK, you'll need to s… | |
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.c… | |
+ echo "*** to the installed location Also, make sure you have run ld… | |
+ echo "*** is required on your system" | |
+ echo "***" | |
+ echo "*** If you have an old version installed, it is best to remove… | |
+ echo "*** you may also be able to get things to work by modifying LD… | |
+ echo "***" | |
+ echo "*** If you have a RedHat 5.0 system, you should remove the GTK… | |
+ echo "*** came with the system with the command" | |
+ echo "***" | |
+ echo "*** rpm --erase --nodeps gtk gtk-devel" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ echo "*** The test program failed to compile or link. See the file config.l… | |
+ echo "*** exact error that occured. This usually means GTK was incor… | |
+ echo "*** or that you have moved GTK since it was installed. In the … | |
+ echo "*** may want to edit the gtk-config script: $GTK_CONFIG" | |
+fi | |
+rm -f conftest* | |
+ CFLAGS="$ac_save_CFLAGS" | |
+ LIBS="$ac_save_LIBS" | |
+ fi | |
+ fi | |
+ GTK_CFLAGS="" | |
+ GTK_LIBS="" | |
+ gtk_found="no" | |
+ fi | |
+ | |
+ | |
+ rm -f conf.gtktest | |
+ | |
+ if test "$gtk_found" = "no" ; then | |
+ echo "configure: warning: Cannot find GTK+" 1>&2 | |
+ GTK_CLIENT="no" | |
+ fi | |
+ fi | |
+ | |
+ WIN32_CLIENT="no" | |
+ | |
+ if test "$GTK_CLIENT" = "yes" ; then | |
+ cat >> confdefs.h <<\EOF | |
+#define GTK_CLIENT 1 | |
+EOF | |
+ | |
+ fi | |
+ | |
+ CFLAGS="$CFLAGS `glib-config --cflags`" | |
+ LDFLAGS="$LDFLAGS `glib-config --libs`" | |
+fi | |
+ | |
+if test "$CURSES_CLIENT" = "yes" ; then | |
+ cat >> confdefs.h <<\EOF | |
+#define CURSES_CLIENT 1 | |
+EOF | |
+ | |
+fi | |
+ | |
+if test "$CURSES_CLIENT" = "no" -a "$GTK_CLIENT" = "no" -a "$WIN32_CLIENT" = "… | |
+ echo "configure: warning: No clients will be compiled - binary will be serv… | |
+fi | |
+ | |
+ | |
+ | |
+ | |
+ | |
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 | |
+echo "configure:3680: checking for ANSI C header files" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3685 "configure" | |
+#include "confdefs.h" | |
+#include <stdlib.h> | |
+#include <stdarg.h> | |
+#include <string.h> | |
+#include <float.h> | |
+EOF | |
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
+{ (eval echo configure:3693: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
+if test -z "$ac_err"; then | |
+ rm -rf conftest* | |
+ ac_cv_header_stdc=yes | |
+else | |
+ echo "$ac_err" >&5 | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ ac_cv_header_stdc=no | |
+fi | |
+rm -f conftest* | |
+ | |
+if test $ac_cv_header_stdc = yes; then | |
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI. | |
+cat > conftest.$ac_ext <<EOF | |
+#line 3710 "configure" | |
+#include "confdefs.h" | |
+#include <string.h> | |
+EOF | |
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | | |
+ egrep "memchr" >/dev/null 2>&1; then | |
+ : | |
+else | |
+ rm -rf conftest* | |
+ ac_cv_header_stdc=no | |
+fi | |
+rm -f conftest* | |
+ | |
+fi | |
+ | |
+if test $ac_cv_header_stdc = yes; then | |
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. | |
+cat > conftest.$ac_ext <<EOF | |
+#line 3728 "configure" | |
+#include "confdefs.h" | |
+#include <stdlib.h> | |
+EOF | |
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | | |
+ egrep "free" >/dev/null 2>&1; then | |
+ : | |
+else | |
+ rm -rf conftest* | |
+ ac_cv_header_stdc=no | |
+fi | |
+rm -f conftest* | |
+ | |
+fi | |
+ | |
+if test $ac_cv_header_stdc = yes; then | |
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. | |
+if test "$cross_compiling" = yes; then | |
+ : | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3749 "configure" | |
+#include "confdefs.h" | |
+#include <ctype.h> | |
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') | |
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) | |
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) | |
+int main () { int i; for (i = 0; i < 256; i++) | |
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); | |
+exit (0); } | |
+ | |
+EOF | |
+if { (eval echo configure:3760: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+then | |
+ : | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -fr conftest* | |
+ ac_cv_header_stdc=no | |
+fi | |
+rm -fr conftest* | |
+fi | |
+ | |
+fi | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_header_stdc" 1>&6 | |
+if test $ac_cv_header_stdc = yes; then | |
+ cat >> confdefs.h <<\EOF | |
+#define STDC_HEADERS 1 | |
+EOF | |
+ | |
+fi | |
+ | |
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6 | |
+echo "configure:3784: checking for sys/wait.h that is POSIX.1 compatible" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3789 "configure" | |
+#include "confdefs.h" | |
+#include <sys/types.h> | |
+#include <sys/wait.h> | |
+#ifndef WEXITSTATUS | |
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) | |
+#endif | |
+#ifndef WIFEXITED | |
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) | |
+#endif | |
+int main() { | |
+int s; | |
+wait (&s); | |
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:3805: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+ rm -rf conftest* | |
+ ac_cv_header_sys_wait_h=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ ac_cv_header_sys_wait_h=no | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6 | |
+if test $ac_cv_header_sys_wait_h = yes; then | |
+ cat >> confdefs.h <<\EOF | |
+#define HAVE_SYS_WAIT_H 1 | |
+EOF | |
+ | |
+fi | |
+ | |
+for ac_hdr in fcntl.h sys/time.h unistd.h | |
+do | |
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` | |
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 | |
+echo "configure:3829: checking for $ac_hdr" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3834 "configure" | |
+#include "confdefs.h" | |
+#include <$ac_hdr> | |
+EOF | |
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" | |
+{ (eval echo configure:3839: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } | |
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` | |
+if test -z "$ac_err"; then | |
+ rm -rf conftest* | |
+ eval "ac_cv_header_$ac_safe=yes" | |
+else | |
+ echo "$ac_err" >&5 | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_header_$ac_safe=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEF… | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_hdr 1 | |
+EOF | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+done | |
+ | |
+ | |
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $… | |
+echo "configure:3867: checking whether time.h and sys/time.h may both be inclu… | |
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3872 "configure" | |
+#include "confdefs.h" | |
+#include <sys/types.h> | |
+#include <sys/time.h> | |
+#include <time.h> | |
+int main() { | |
+struct tm *tp; | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:3881: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+ rm -rf conftest* | |
+ ac_cv_header_time=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ ac_cv_header_time=no | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_header_time" 1>&6 | |
+if test $ac_cv_header_time = yes; then | |
+ cat >> confdefs.h <<\EOF | |
+#define TIME_WITH_SYS_TIME 1 | |
+EOF | |
+ | |
+fi | |
+ | |
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" … | |
+echo "configure:3902: checking whether struct tm is in sys/time.h or time.h" >… | |
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3907 "configure" | |
+#include "confdefs.h" | |
+#include <sys/types.h> | |
+#include <time.h> | |
+int main() { | |
+struct tm *tp; tp->tm_sec; | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:3915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5… | |
+ rm -rf conftest* | |
+ ac_cv_struct_tm=time.h | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ ac_cv_struct_tm=sys/time.h | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_struct_tm" 1>&6 | |
+if test $ac_cv_struct_tm = sys/time.h; then | |
+ cat >> confdefs.h <<\EOF | |
+#define TM_IN_SYS_TIME 1 | |
+EOF | |
+ | |
+fi | |
+ | |
+ | |
+echo $ac_n "checking size of long long""... $ac_c" 1>&6 | |
+echo "configure:3937: checking size of long long" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ if test "$cross_compiling" = yes; then | |
+ { echo "configure: error: can not run test program while cross compiling" … | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3945 "configure" | |
+#include "confdefs.h" | |
+#include <stdio.h> | |
+main() | |
+{ | |
+ FILE *f=fopen("conftestval", "w"); | |
+ if (!f) exit(1); | |
+ fprintf(f, "%d\n", sizeof(long long)); | |
+ exit(0); | |
+} | |
+EOF | |
+if { (eval echo configure:3956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+then | |
+ ac_cv_sizeof_long_long=`cat conftestval` | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -fr conftest* | |
+ ac_cv_sizeof_long_long=0 | |
+fi | |
+rm -fr conftest* | |
+fi | |
+ | |
+fi | |
+echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6 | |
+cat >> confdefs.h <<EOF | |
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long | |
+EOF | |
+ | |
+ | |
+ | |
+echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 | |
+echo "configure:3977: checking for 8-bit clean memcmp" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ if test "$cross_compiling" = yes; then | |
+ ac_cv_func_memcmp_clean=no | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 3985 "configure" | |
+#include "confdefs.h" | |
+ | |
+main() | |
+{ | |
+ char c0 = 0x40, c1 = 0x80, c2 = 0x81; | |
+ exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1); | |
+} | |
+ | |
+EOF | |
+if { (eval echo configure:3995: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+then | |
+ ac_cv_func_memcmp_clean=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -fr conftest* | |
+ ac_cv_func_memcmp_clean=no | |
+fi | |
+rm -fr conftest* | |
+fi | |
+ | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6 | |
+test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" | |
+ | |
+echo $ac_n "checking whether setvbuf arguments are reversed""... $ac_c" 1>&6 | |
+echo "configure:4013: checking whether setvbuf arguments are reversed" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_setvbuf_reversed'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ if test "$cross_compiling" = yes; then | |
+ { echo "configure: error: can not run test program while cross compiling" … | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 4021 "configure" | |
+#include "confdefs.h" | |
+#include <stdio.h> | |
+/* If setvbuf has the reversed format, exit 0. */ | |
+main () { | |
+ /* This call has the arguments reversed. | |
+ A reversed system may check and see that the address of main | |
+ is not _IOLBF, _IONBF, or _IOFBF, and return nonzero. */ | |
+ if (setvbuf(stdout, _IOLBF, (char *) main, BUFSIZ) != 0) | |
+ exit(1); | |
+ putc('\r', stdout); | |
+ exit(0); /* Non-reversed systems segv here. */ | |
+} | |
+EOF | |
+if { (eval echo configure:4035: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+then | |
+ ac_cv_func_setvbuf_reversed=yes | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -fr conftest* | |
+ ac_cv_func_setvbuf_reversed=no | |
+fi | |
+rm -fr conftest* | |
+fi | |
+ | |
+rm -f core core.* *.core | |
+fi | |
+ | |
+echo "$ac_t""$ac_cv_func_setvbuf_reversed" 1>&6 | |
+if test $ac_cv_func_setvbuf_reversed = yes; then | |
+ cat >> confdefs.h <<\EOF | |
+#define SETVBUF_REVERSED 1 | |
+EOF | |
+ | |
+fi | |
+ | |
+echo $ac_n "checking for strftime""... $ac_c" 1>&6 | |
+echo "configure:4059: checking for strftime" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_strftime'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 4064 "configure" | |
+#include "confdefs.h" | |
+/* System header to define __stub macros and hopefully few prototypes, | |
+ which can conflict with char strftime(); below. */ | |
+#include <assert.h> | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char strftime(); | |
+ | |
+int main() { | |
+ | |
+/* The GNU C library defines this for functions which it implements | |
+ to always fail with ENOSYS. Some functions are actually named | |
+ something starting with __ and the normal name is an alias. */ | |
+#if defined (__stub_strftime) || defined (__stub___strftime) | |
+choke me | |
+#else | |
+strftime(); | |
+#endif | |
+ | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:4087: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_strftime=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_strftime=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+if eval "test \"`echo '$ac_cv_func_'strftime`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ cat >> confdefs.h <<\EOF | |
+#define HAVE_STRFTIME 1 | |
+EOF | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+# strftime is in -lintl on SCO UNIX. | |
+echo $ac_n "checking for strftime in -lintl""... $ac_c" 1>&6 | |
+echo "configure:4109: checking for strftime in -lintl" >&5 | |
+ac_lib_var=`echo intl'_'strftime | sed 'y%./+-%__p_%'` | |
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ ac_save_LIBS="$LIBS" | |
+LIBS="-lintl $LIBS" | |
+cat > conftest.$ac_ext <<EOF | |
+#line 4117 "configure" | |
+#include "confdefs.h" | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char strftime(); | |
+ | |
+int main() { | |
+strftime() | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:4128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_lib_$ac_lib_var=no" | |
+fi | |
+rm -f conftest* | |
+LIBS="$ac_save_LIBS" | |
+ | |
+fi | |
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ cat >> confdefs.h <<\EOF | |
+#define HAVE_STRFTIME 1 | |
+EOF | |
+ | |
+LIBS="-lintl $LIBS" | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+ | |
+fi | |
+ | |
+for ac_func in strdup strstr | |
+do | |
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
+echo "configure:4157: checking for $ac_func" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 4162 "configure" | |
+#include "confdefs.h" | |
+/* System header to define __stub macros and hopefully few prototypes, | |
+ which can conflict with char $ac_func(); below. */ | |
+#include <assert.h> | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char $ac_func(); | |
+ | |
+int main() { | |
+ | |
+/* The GNU C library defines this for functions which it implements | |
+ to always fail with ENOSYS. Some functions are actually named | |
+ something starting with __ and the normal name is an alias. */ | |
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) | |
+choke me | |
+#else | |
+$ac_func(); | |
+#endif | |
+ | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:4185: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGH… | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_func 1 | |
+EOF | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+done | |
+ | |
+ | |
+network="no" | |
+if test "$CYGWIN" = "yes" ; then | |
+ network="yes" | |
+else | |
+ for ac_func in socket select | |
+do | |
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 | |
+echo "configure:4217: checking for $ac_func" >&5 | |
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then | |
+ echo $ac_n "(cached) $ac_c" 1>&6 | |
+else | |
+ cat > conftest.$ac_ext <<EOF | |
+#line 4222 "configure" | |
+#include "confdefs.h" | |
+/* System header to define __stub macros and hopefully few prototypes, | |
+ which can conflict with char $ac_func(); below. */ | |
+#include <assert.h> | |
+/* Override any gcc2 internal prototype to avoid an error. */ | |
+/* We use char because int might match the return type of a gcc2 | |
+ builtin and then its argument prototype would still apply. */ | |
+char $ac_func(); | |
+ | |
+int main() { | |
+ | |
+/* The GNU C library defines this for functions which it implements | |
+ to always fail with ENOSYS. Some functions are actually named | |
+ something starting with __ and the normal name is an alias. */ | |
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func) | |
+choke me | |
+#else | |
+$ac_func(); | |
+#endif | |
+ | |
+; return 0; } | |
+EOF | |
+if { (eval echo configure:4245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } &&… | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=yes" | |
+else | |
+ echo "configure: failed program was:" >&5 | |
+ cat conftest.$ac_ext >&5 | |
+ rm -rf conftest* | |
+ eval "ac_cv_func_$ac_func=no" | |
+fi | |
+rm -f conftest* | |
+fi | |
+ | |
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then | |
+ echo "$ac_t""yes" 1>&6 | |
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGH… | |
+ cat >> confdefs.h <<EOF | |
+#define $ac_tr_func 1 | |
+EOF | |
+ | |
+else | |
+ echo "$ac_t""no" 1>&6 | |
+fi | |
+done | |
+ | |
+ if test "$ac_cv_func_select" = "yes" ; then | |
+ if test "$ac_cv_func_socket" = "yes" ; then | |
+ network="yes" | |
+ fi | |
+ fi | |
+fi | |
+ | |
+# Check whether --enable-networking or --disable-networking was given. | |
+if test "${enable_networking+set}" = set; then | |
+ enableval="$enable_networking" | |
+ network="$enableval" | |
+fi | |
+ | |
+ | |
+if test "$network" = "yes" ; then | |
+ cat >> confdefs.h <<\EOF | |
+#define NETWORKING 1 | |
+EOF | |
+ | |
+ echo "$ac_t""dopewars will use TCP/IP networking to connect to servers" 1>&6 | |
+else | |
+ echo "$ac_t""Networking disabled; only single-player mode will be available… | |
+fi | |
+ | |
+if test -n "$GCC"; then | |
+ CFLAGS="$CFLAGS -Wall" | |
+fi | |
+ | |
+CFLAGS="$CFLAGS -DDATADIR=\\\"${datadir}\\\"" | |
+ | |
+trap '' 1 2 15 | |
+cat > confcache <<\EOF | |
+# This file is a shell script that caches the results of configure | |
+# tests run on this system so they can be shared between configure | |
+# scripts and configure runs. It is not useful on other systems. | |
+# If it contains results you don't want to keep, you may remove or edit it. | |
+# | |
+# By default, configure uses ./config.cache as the cache file, | |
+# creating it if it does not exist already. You can give configure | |
+# the --cache-file=FILE option to use a different cache file; that is | |
+# what configure does when it calls configure scripts in | |
+# subdirectories, so they share the cache. | |
+# Giving --cache-file=/dev/null disables caching, for debugging configure. | |
+# config.status only pays attention to the cache file if you give it the | |
+# --recheck option to rerun configure. | |
+# | |
+EOF | |
+# The following way of writing the cache mishandles newlines in values, | |
+# but we know of no workaround that is simple, portable, and efficient. | |
+# So, don't put newlines in cache variables' values. | |
+# Ultrix sh set writes to stderr and can't be redirected directly, | |
+# and sets the high bit in the cache file unless we assign to the vars. | |
+(set) 2>&1 | | |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in | |
+ *ac_space=\ *) | |
+ # `set' does not quote correctly, so add quotes (double-quote substitution | |
+ # turns \\\\ into \\, and sed turns \\ into \). | |
+ sed -n \ | |
+ -e "s/'/'\\\\''/g" \ | |
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" | |
+ ;; | |
+ *) | |
+ # `set' quotes correctly as required by POSIX, so do not add quotes. | |
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' | |
+ ;; | |
+ esac >> confcache | |
+if cmp -s $cache_file confcache; then | |
+ : | |
+else | |
+ if test -w $cache_file; then | |
+ echo "updating cache $cache_file" | |
+ cat confcache > $cache_file | |
+ else | |
+ echo "not updating unwritable cache $cache_file" | |
+ fi | |
+fi | |
+rm -f confcache | |
+ | |
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1… | |
+ | |
+test "x$prefix" = xNONE && prefix=$ac_default_prefix | |
+# Let make expand exec_prefix. | |
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' | |
+ | |
+# Any assignment to VPATH causes Sun make to only execute | |
+# the first set of double-colon rules, so remove it if not needed. | |
+# If there is a colon in the path, we need to keep it. | |
+if test "x$srcdir" = x.; then | |
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' | |
+fi | |
+ | |
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 | |
+ | |
+DEFS=-DHAVE_CONFIG_H | |
+ | |
+# Without the "./", some shells look in PATH for config.status. | |
+: ${CONFIG_STATUS=./config.status} | |
+ | |
+echo creating $CONFIG_STATUS | |
+rm -f $CONFIG_STATUS | |
+cat > $CONFIG_STATUS <<EOF | |
+#! /bin/sh | |
+# Generated automatically by configure. | |
+# Run this file to recreate the current configuration. | |
+# This directory was configured as follows, | |
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`: | |
+# | |
+# $0 $ac_configure_args | |
+# | |
+# Compiler output produced by configure, useful for debugging | |
+# configure, is in ./config.log if it exists. | |
+ | |
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" | |
+for ac_option | |
+do | |
+ case "\$ac_option" in | |
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) | |
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create -… | |
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recur… | |
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v) | |
+ echo "$CONFIG_STATUS generated by autoconf version 2.13" | |
+ exit 0 ;; | |
+ -help | --help | --hel | --he | --h) | |
+ echo "\$ac_cs_usage"; exit 0 ;; | |
+ *) echo "\$ac_cs_usage"; exit 1 ;; | |
+ esac | |
+done | |
+ | |
+ac_given_srcdir=$srcdir | |
+ac_given_INSTALL="$INSTALL" | |
+ | |
+trap 'rm -fr `echo " | |
+Makefile | |
+src/Makefile | |
+doc/Makefile | |
+intl/Makefile | |
+po/Makefile.in config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 | |
+EOF | |
+cat >> $CONFIG_STATUS <<EOF | |
+ | |
+# Protect against being on the right side of a sed subst in config.status. | |
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; | |
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF | |
+$ac_vpsub | |
+$extrasub | |
+s%@SHELL@%$SHELL%g | |
+s%@CFLAGS@%$CFLAGS%g | |
+s%@CPPFLAGS@%$CPPFLAGS%g | |
+s%@CXXFLAGS@%$CXXFLAGS%g | |
+s%@FFLAGS@%$FFLAGS%g | |
+s%@DEFS@%$DEFS%g | |
+s%@LDFLAGS@%$LDFLAGS%g | |
+s%@LIBS@%$LIBS%g | |
+s%@exec_prefix@%$exec_prefix%g | |
+s%@prefix@%$prefix%g | |
+s%@program_transform_name@%$program_transform_name%g | |
+s%@bindir@%$bindir%g | |
+s%@sbindir@%$sbindir%g | |
+s%@libexecdir@%$libexecdir%g | |
+s%@datadir@%$datadir%g | |
+s%@sysconfdir@%$sysconfdir%g | |
+s%@sharedstatedir@%$sharedstatedir%g | |
+s%@localstatedir@%$localstatedir%g | |
+s%@libdir@%$libdir%g | |
+s%@includedir@%$includedir%g | |
+s%@oldincludedir@%$oldincludedir%g | |
+s%@infodir@%$infodir%g | |
+s%@mandir@%$mandir%g | |
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g | |
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g | |
+s%@INSTALL_DATA@%$INSTALL_DATA%g | |
+s%@PACKAGE@%$PACKAGE%g | |
+s%@VERSION@%$VERSION%g | |
+s%@ACLOCAL@%$ACLOCAL%g | |
+s%@AUTOCONF@%$AUTOCONF%g | |
+s%@AUTOMAKE@%$AUTOMAKE%g | |
+s%@AUTOHEADER@%$AUTOHEADER%g | |
+s%@MAKEINFO@%$MAKEINFO%g | |
+s%@SET_MAKE@%$SET_MAKE%g | |
+s%@CC@%$CC%g | |
+s%@RANLIB@%$RANLIB%g | |
+s%@CPP@%$CPP%g | |
+s%@ALLOCA@%$ALLOCA%g | |
+s%@USE_NLS@%$USE_NLS%g | |
+s%@MSGFMT@%$MSGFMT%g | |
+s%@GMSGFMT@%$GMSGFMT%g | |
+s%@XGETTEXT@%$XGETTEXT%g | |
+s%@GENCAT@%$GENCAT%g | |
+s%@USE_INCLUDED_LIBINTL@%$USE_INCLUDED_LIBINTL%g | |
+s%@CATALOGS@%$CATALOGS%g | |
+s%@CATOBJEXT@%$CATOBJEXT%g | |
+s%@DATADIRNAME@%$DATADIRNAME%g | |
+s%@GMOFILES@%$GMOFILES%g | |
+s%@INSTOBJEXT@%$INSTOBJEXT%g | |
+s%@INTLDEPS@%$INTLDEPS%g | |
+s%@INTLLIBS@%$INTLLIBS%g | |
+s%@INTLOBJS@%$INTLOBJS%g | |
+s%@POFILES@%$POFILES%g | |
+s%@POSUB@%$POSUB%g | |
+s%@INCLUDE_LOCALE_H@%$INCLUDE_LOCALE_H%g | |
+s%@GT_NO@%$GT_NO%g | |
+s%@GT_YES@%$GT_YES%g | |
+s%@MKINSTALLDIRS@%$MKINSTALLDIRS%g | |
+s%@l@%$l%g | |
+s%@localedir@%$localedir%g | |
+s%@GTK_CONFIG@%$GTK_CONFIG%g | |
+s%@GTK_CFLAGS@%$GTK_CFLAGS%g | |
+s%@GTK_LIBS@%$GTK_LIBS%g | |
+s%@WIN_RC@%$WIN_RC%g | |
+s%@WIN_RES@%$WIN_RES%g | |
+/@WIN_MAKE_RES@/r $WIN_MAKE_RES | |
+s%@WIN_MAKE_RES@%%g | |
+s%@LIBOBJS@%$LIBOBJS%g | |
+ | |
+CEOF | |
+EOF | |
+ | |
+cat >> $CONFIG_STATUS <<\EOF | |
+ | |
+# Split the substitutions into bite-sized pieces for seds with | |
+# small command number limits, like on Digital OSF/1 and HP-UX. | |
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. | |
+ac_file=1 # Number of current file. | |
+ac_beg=1 # First line for current file. | |
+ac_end=$ac_max_sed_cmds # Line after last line for current file. | |
+ac_more_lines=: | |
+ac_sed_cmds="" | |
+while $ac_more_lines; do | |
+ if test $ac_beg -gt 1; then | |
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file | |
+ else | |
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file | |
+ fi | |
+ if test ! -s conftest.s$ac_file; then | |
+ ac_more_lines=false | |
+ rm -f conftest.s$ac_file | |
+ else | |
+ if test -z "$ac_sed_cmds"; then | |
+ ac_sed_cmds="sed -f conftest.s$ac_file" | |
+ else | |
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" | |
+ fi | |
+ ac_file=`expr $ac_file + 1` | |
+ ac_beg=$ac_end | |
+ ac_end=`expr $ac_end + $ac_max_sed_cmds` | |
+ fi | |
+done | |
+if test -z "$ac_sed_cmds"; then | |
+ ac_sed_cmds=cat | |
+fi | |
+EOF | |
+ | |
+cat >> $CONFIG_STATUS <<EOF | |
+ | |
+CONFIG_FILES=\${CONFIG_FILES-"Makefile | |
+src/Makefile | |
+doc/Makefile | |
+intl/Makefile | |
+po/Makefile.in"} | |
+EOF | |
+cat >> $CONFIG_STATUS <<\EOF | |
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then | |
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". | |
+ case "$ac_file" in | |
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` | |
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; | |
+ *) ac_file_in="${ac_file}.in" ;; | |
+ esac | |
+ | |
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. | |
+ | |
+ # Remove last slash and all that follows it. Not all systems have dirname. | |
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` | |
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then | |
+ # The file is in a subdirectory. | |
+ test ! -d "$ac_dir" && mkdir "$ac_dir" | |
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" | |
+ # A "../" for each directory in $ac_dir_suffix. | |
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` | |
+ else | |
+ ac_dir_suffix= ac_dots= | |
+ fi | |
+ | |
+ case "$ac_given_srcdir" in | |
+ .) srcdir=. | |
+ if test -z "$ac_dots"; then top_srcdir=. | |
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; | |
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; | |
+ *) # Relative path. | |
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" | |
+ top_srcdir="$ac_dots$ac_given_srcdir" ;; | |
+ esac | |
+ | |
+ case "$ac_given_INSTALL" in | |
+ [/$]*) INSTALL="$ac_given_INSTALL" ;; | |
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;; | |
+ esac | |
+ | |
+ echo creating "$ac_file" | |
+ rm -f "$ac_file" | |
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%… | |
+ case "$ac_file" in | |
+ *Makefile*) ac_comsub="1i\\ | |
+# $configure_input" ;; | |
+ *) ac_comsub= ;; | |
+ esac | |
+ | |
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $a… | |
+ sed -e "$ac_comsub | |
+s%@configure_input@%$configure_input%g | |
+s%@srcdir@%$srcdir%g | |
+s%@top_srcdir@%$top_srcdir%g | |
+s%@INSTALL@%$INSTALL%g | |
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file | |
+fi; done | |
+rm -f conftest.s* | |
+ | |
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where | |
+# NAME is the cpp macro being defined and VALUE is the value it is being given. | |
+# | |
+# ac_d sets the value in "#define NAME VALUE" lines. | |
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)' | |
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2' | |
+ac_dC='\3' | |
+ac_dD='%g' | |
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". | |
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' | |
+ac_uB='\([ ]\)%\1#\2define\3' | |
+ac_uC=' ' | |
+ac_uD='\4%g' | |
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". | |
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' | |
+ac_eB='$%\1#\2define\3' | |
+ac_eC=' ' | |
+ac_eD='%g' | |
+ | |
+if test "${CONFIG_HEADERS+set}" != set; then | |
+EOF | |
+cat >> $CONFIG_STATUS <<EOF | |
+ CONFIG_HEADERS="config.h" | |
+EOF | |
+cat >> $CONFIG_STATUS <<\EOF | |
+fi | |
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then | |
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". | |
+ case "$ac_file" in | |
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` | |
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; | |
+ *) ac_file_in="${ac_file}.in" ;; | |
+ esac | |
+ | |
+ echo creating $ac_file | |
+ | |
+ rm -f conftest.frag conftest.in conftest.out | |
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $a… | |
+ cat $ac_file_inputs > conftest.in | |
+ | |
+EOF | |
+ | |
+# Transform confdefs.h into a sed script conftest.vals that substitutes | |
+# the proper values into config.h.in to produce config.h. And first: | |
+# Protect against being on the right side of a sed subst in config.status. | |
+# Protect against being in an unquoted here document in config.status. | |
+rm -f conftest.vals | |
+cat > conftest.hdr <<\EOF | |
+s/[\\&%]/\\&/g | |
+s%[\\$`]%\\&%g | |
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${a… | |
+s%ac_d%ac_u%gp | |
+s%ac_u%ac_e%gp | |
+EOF | |
+sed -n -f conftest.hdr confdefs.h > conftest.vals | |
+rm -f conftest.hdr | |
+ | |
+# This sed command replaces #undef with comments. This is necessary, for | |
+# example, in the case of _POSIX_SOURCE, which is predefined and required | |
+# on some systems where configure will not decide to define it. | |
+cat >> conftest.vals <<\EOF | |
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*… | |
+EOF | |
+ | |
+# Break up conftest.vals because some shells have a limit on | |
+# the size of here documents, and old seds have small limits too. | |
+ | |
+rm -f conftest.tail | |
+while : | |
+do | |
+ ac_lines=`grep -c . conftest.vals` | |
+ # grep -c gives empty output for an empty file on some AIX systems. | |
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi | |
+ # Write a limited-size here document to conftest.frag. | |
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS | |
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS | |
+ echo 'CEOF | |
+ sed -f conftest.frag conftest.in > conftest.out | |
+ rm -f conftest.in | |
+ mv conftest.out conftest.in | |
+' >> $CONFIG_STATUS | |
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail | |
+ rm -f conftest.vals | |
+ mv conftest.tail conftest.vals | |
+done | |
+rm -f conftest.vals | |
+ | |
+cat >> $CONFIG_STATUS <<\EOF | |
+ rm -f conftest.frag conftest.h | |
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h | |
+ cat conftest.in >> conftest.h | |
+ rm -f conftest.in | |
+ if cmp -s $ac_file conftest.h 2>/dev/null; then | |
+ echo "$ac_file is unchanged" | |
+ rm -f conftest.h | |
+ else | |
+ # Remove last slash and all that follows it. Not all systems have dirname. | |
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` | |
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then | |
+ # The file is in a subdirectory. | |
+ test ! -d "$ac_dir" && mkdir "$ac_dir" | |
+ fi | |
+ rm -f $ac_file | |
+ mv conftest.h $ac_file | |
+ fi | |
+fi; done | |
+ | |
+EOF | |
+ | |
+cat >> $CONFIG_STATUS <<EOF | |
+ac_sources="$nls_cv_header_libgt" | |
+ac_dests="$nls_cv_header_intl" | |
+EOF | |
+ | |
+cat >> $CONFIG_STATUS <<\EOF | |
+srcdir=$ac_given_srcdir | |
+while test -n "$ac_sources"; do | |
+ set $ac_dests; ac_dest=$1; shift; ac_dests=$* | |
+ set $ac_sources; ac_source=$1; shift; ac_sources=$* | |
+ | |
+ echo "linking $srcdir/$ac_source to $ac_dest" | |
+ | |
+ if test ! -r $srcdir/$ac_source; then | |
+ { echo "configure: error: $srcdir/$ac_source: File not found" 1>&2; exit 1… | |
+ fi | |
+ rm -f $ac_dest | |
+ | |
+ # Make relative symlinks. | |
+ # Remove last slash and all that follows it. Not all systems have dirname. | |
+ ac_dest_dir=`echo $ac_dest|sed 's%/[^/][^/]*$%%'` | |
+ if test "$ac_dest_dir" != "$ac_dest" && test "$ac_dest_dir" != .; then | |
+ # The dest file is in a subdirectory. | |
+ test ! -d "$ac_dest_dir" && mkdir "$ac_dest_dir" | |
+ ac_dest_dir_suffix="/`echo $ac_dest_dir|sed 's%^\./%%'`" | |
+ # A "../" for each directory in $ac_dest_dir_suffix. | |
+ ac_dots=`echo $ac_dest_dir_suffix|sed 's%/[^/]*%../%g'` | |
+ else | |
+ ac_dest_dir_suffix= ac_dots= | |
+ fi | |
+ | |
+ case "$srcdir" in | |
+ [/$]*) ac_rel_source="$srcdir/$ac_source" ;; | |
+ *) ac_rel_source="$ac_dots$srcdir/$ac_source" ;; | |
+ esac | |
+ | |
+ # Make a symlink if possible; otherwise try a hard link. | |
+ if ln -s $ac_rel_source $ac_dest 2>/dev/null || | |
+ ln $srcdir/$ac_source $ac_dest; then : | |
+ else | |
+ { echo "configure: error: can not link $ac_dest to $srcdir/$ac_source" 1>&… | |
+ fi | |
+done | |
+EOF | |
+cat >> $CONFIG_STATUS <<EOF | |
+ | |
+ | |
+ | |
+EOF | |
+cat >> $CONFIG_STATUS <<\EOF | |
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h | |
+case "$CONFIG_FILES" in *po/Makefile.in*) | |
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile | |
+ esac | |
+sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile | |
+exit 0 | |
+EOF | |
+chmod +x $CONFIG_STATUS | |
+rm -fr confdefs* $ac_clean_files | |
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 | |
+ | |
diff --git a/configure.in b/configure.in | |
t@@ -0,0 +1,176 @@ | |
+dnl Process this file with autoconf to produce a configure script. | |
+AC_INIT(src/dopewars.c) | |
+ | |
+dnl Initialise automake | |
+AM_INIT_AUTOMAKE(dopewars,1.4.8-devel) | |
+ | |
+dnl Write configuration defines into config.h | |
+AM_CONFIG_HEADER(config.h) | |
+ | |
+dnl Checks for programs. | |
+AC_PROG_CC | |
+AC_PROG_INSTALL | |
+ | |
+dnl Do i18n stuff | |
+ALL_LINGUAS="de" | |
+AM_GNU_GETTEXT | |
+if test "$gt_cv_func_gettext_libintl" = "yes"; then | |
+ LIBS="-lintl $LIBS" | |
+fi | |
+ | |
+localedir=${datadir}/locale | |
+AC_SUBST(localedir) | |
+dnl AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl) | |
+ | |
+dnl Process client options | |
+AC_ARG_ENABLE(gtk-client, | |
+[ --enable-gtk-client include GTK+ client on Unix systems], | |
+[ GTK_CLIENT="$enableval" ],[ GTK_CLIENT="yes" ]) | |
+ | |
+AC_ARG_ENABLE(curses-client, | |
+[ --enable-curses-client include curses client], | |
+[ CURSES_CLIENT="$enableval" ],[ CURSES_CLIENT="yes" ]) | |
+ | |
+AC_ARG_ENABLE(win32-client, | |
+[ --enable-win32-client include graphical Win32 client on Windows systems], | |
+[ WIN32_CLIENT="$enableval" ],[ WIN32_CLIENT="yes" ]) | |
+ | |
+WIN_RC="" | |
+WIN_RES="" | |
+WIN_MAKE_RES="/dev/null" | |
+ | |
+dnl Test for Cygwin environment | |
+AC_CYGWIN | |
+dnl Let the user override this with the --enable-nativewin32 option | |
+AC_ARG_ENABLE(nativewin32, | |
+[ --enable-nativewin32 build a native Win32 binary under Cygwin], | |
+[ CYGWIN="$enableval" ]) | |
+ | |
+if test "$CYGWIN" = "yes" ; then | |
+ AC_MSG_RESULT("Configuring for native Win32 binary under Cygwin") | |
+ AC_DEFINE(CYGWIN) | |
+ CFLAGS="$CFLAGS -mwindows -fnative-struct -mno-cygwin" | |
+ LIBS="$LIBS -lwsock32 -lcomctl32" | |
+ if test "$WIN32_CLIENT" = "yes" ; then | |
+ WIN_RC="dopewars.rc" | |
+ WIN_RES="dopewars.res" | |
+ WIN_MAKE_RES="$srcdir/cygwin.am" | |
+ AC_DEFINE(WIN32_CLIENT) | |
+ fi | |
+ GTK_CLIENT="no" | |
+ | |
+ dnl Glib stuff | |
+ LDFLAGS="$LDFLAGS -lglib-1.3" | |
+else | |
+ AC_MSG_RESULT("Configuring for Unix binary") | |
+ dnl On true Unix systems, test for valid curses-like libraries | |
+ if test "$CURSES_CLIENT" = "yes" ; then | |
+ AC_CHECK_LIB(ncurses,initscr) | |
+ if test "$ac_cv_lib_ncurses_initscr" = "no" ; then | |
+ AC_CHECK_LIB(curses,initscr) | |
+ if test "$ac_cv_lib_curses_initscr" = "no" ; then | |
+ AC_CHECK_LIB(cur_colr,initscr) | |
+ if test "$ac_cv_lib_cur_colr_initscr" = "no" ; then | |
+ AC_MSG_WARN(Cannot find any curses-type library) | |
+ CURSES_CLIENT="no" | |
+ fi | |
+ fi | |
+ fi | |
+ fi | |
+ | |
+ if test "$GTK_CLIENT" = "yes" ; then | |
+ dnl Tests for GTK | |
+ AM_PATH_GTK(1.2.0,gtk_found="yes",gtk_found="no") | |
+ if test "$gtk_found" = "no" ; then | |
+ AC_MSG_WARN(Cannot find GTK+) | |
+ GTK_CLIENT="no" | |
+ fi | |
+ fi | |
+ | |
+ WIN32_CLIENT="no" | |
+ | |
+ if test "$GTK_CLIENT" = "yes" ; then | |
+ AC_DEFINE(GTK_CLIENT) | |
+ fi | |
+ | |
+ dnl Glib stuff | |
+ CFLAGS="$CFLAGS `glib-config --cflags`" | |
+ LDFLAGS="$LDFLAGS `glib-config --libs`" | |
+fi | |
+ | |
+if test "$CURSES_CLIENT" = "yes" ; then | |
+ AC_DEFINE(CURSES_CLIENT) | |
+fi | |
+ | |
+if test "$CURSES_CLIENT" = "no" -a "$GTK_CLIENT" = "no" -a "$WIN32_CLIENT" = "… | |
+ AC_MSG_WARN(No clients will be compiled - binary will be server/AI only!) | |
+fi | |
+ | |
+AC_SUBST(WIN_RC) | |
+AC_SUBST(WIN_RES) | |
+AC_SUBST_FILE(WIN_MAKE_RES) | |
+ | |
+dnl Checks for header files. | |
+AC_HEADER_STDC | |
+AC_HEADER_SYS_WAIT | |
+AC_CHECK_HEADERS(fcntl.h sys/time.h unistd.h) | |
+ | |
+dnl Checks for typedefs, structures, and compiler characteristics. | |
+AC_HEADER_TIME | |
+AC_STRUCT_TM | |
+ | |
+dnl Can we use a long long datatype for price_t ? | |
+AC_CHECK_SIZEOF(long long) | |
+ | |
+dnl Checks for library functions. | |
+AC_FUNC_MEMCMP | |
+AC_FUNC_SETVBUF_REVERSED | |
+AC_FUNC_STRFTIME | |
+AC_CHECK_FUNCS(strdup strstr) | |
+ | |
+dnl Enable networking by default under Win32, but on Unix systems | |
+dnl make it dependent on the availability of select and socket | |
+network="no" | |
+if test "$CYGWIN" = "yes" ; then | |
+ network="yes" | |
+else | |
+ dnl Check for socket and select even if networking gets manually | |
+ dnl disabled below, since select is used if available for | |
+ dnl millisecond sleeping | |
+ AC_CHECK_FUNCS(socket select) | |
+ if test "$ac_cv_func_select" = "yes" ; then | |
+ if test "$ac_cv_func_socket" = "yes" ; then | |
+ network="yes" | |
+ fi | |
+ fi | |
+fi | |
+ | |
+dnl Let the user override this with the --enable-networking option | |
+AC_ARG_ENABLE(networking, | |
+[ --enable-networking dopewars will use TCP/IP to connect to servers], | |
+[ network="$enableval" ]) | |
+ | |
+dnl Inform the user of the status of networking | |
+if test "$network" = "yes" ; then | |
+ AC_DEFINE(NETWORKING) | |
+ AC_MSG_RESULT(dopewars will use TCP/IP networking to connect to servers) | |
+else | |
+ AC_MSG_RESULT(Networking disabled; only single-player mode will be availabl… | |
+fi | |
+ | |
+dnl Enable full warnings if using gcc | |
+if test -n "$GCC"; then | |
+ CFLAGS="$CFLAGS -Wall" | |
+fi | |
+ | |
+dnl Pass the data directory to the compiler so the program knows | |
+dnl where the high score file is | |
+CFLAGS="$CFLAGS -DDATADIR=\\\"${datadir}\\\"" | |
+ | |
+AC_OUTPUT([ | |
+Makefile | |
+src/Makefile | |
+doc/Makefile | |
+intl/Makefile | |
+po/Makefile.in], | |
+[sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile]) | |
diff --git a/cygwin.am b/cygwin.am | |
t@@ -0,0 +1,2 @@ | |
+dopewars.res : dopewars.rc | |
+ (echo "#include <windows.h>"; tr -d '\r' < dopewars.rc) | windres -O c… | |
diff --git a/doc/Makefile.am b/doc/Makefile.am | |
t@@ -0,0 +1,10 @@ | |
+DOCPATH=/usr/doc/${PACKAGE}-${VERSION}/ | |
+DOCS= aiplayer.html configfile.html index.html server.html \ | |
+ clientplay.html credits.html installation.html \ | |
+ servercommands.html commandline.html developer.html \ | |
+ metaserver.html windows.html | |
+ | |
+install-data-local: | |
+ ${INSTALL} -d -o root -g root -m 0755 $(DOCPATH) | |
+ ${INSTALL} -o root -g root -m 0644 $(DOCS) $(DOCPATH) | |
+ | |
diff --git a/doc/Makefile.in b/doc/Makefile.in | |
t@@ -0,0 +1,205 @@ | |
+# Makefile.in generated automatically by automake 1.4 from Makefile.am | |
+ | |
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. | |
+# This Makefile.in is free software; the Free Software Foundation | |
+# gives unlimited permission to copy and/or distribute it, | |
+# with or without modifications, as long as this notice is preserved. | |
+ | |
+# This program is distributed in the hope that it will be useful, | |
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without | |
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
+# PARTICULAR PURPOSE. | |
+ | |
+ | |
+SHELL = @SHELL@ | |
+ | |
+srcdir = @srcdir@ | |
+top_srcdir = @top_srcdir@ | |
+VPATH = @srcdir@ | |
+prefix = @prefix@ | |
+exec_prefix = @exec_prefix@ | |
+ | |
+bindir = @bindir@ | |
+sbindir = @sbindir@ | |
+libexecdir = @libexecdir@ | |
+datadir = @datadir@ | |
+sysconfdir = @sysconfdir@ | |
+sharedstatedir = @sharedstatedir@ | |
+localstatedir = @localstatedir@ | |
+libdir = @libdir@ | |
+infodir = @infodir@ | |
+mandir = @mandir@ | |
+includedir = @includedir@ | |
+oldincludedir = /usr/include | |
+ | |
+DESTDIR = | |
+ | |
+pkgdatadir = $(datadir)/@PACKAGE@ | |
+pkglibdir = $(libdir)/@PACKAGE@ | |
+pkgincludedir = $(includedir)/@PACKAGE@ | |
+ | |
+top_builddir = .. | |
+ | |
+ACLOCAL = @ACLOCAL@ | |
+AUTOCONF = @AUTOCONF@ | |
+AUTOMAKE = @AUTOMAKE@ | |
+AUTOHEADER = @AUTOHEADER@ | |
+ | |
+INSTALL = @INSTALL@ | |
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) | |
+INSTALL_DATA = @INSTALL_DATA@ | |
+INSTALL_SCRIPT = @INSTALL_SCRIPT@ | |
+transform = @program_transform_name@ | |
+ | |
+NORMAL_INSTALL = : | |
+PRE_INSTALL = : | |
+POST_INSTALL = : | |
+NORMAL_UNINSTALL = : | |
+PRE_UNINSTALL = : | |
+POST_UNINSTALL = : | |
+CATALOGS = @CATALOGS@ | |
+CATOBJEXT = @CATOBJEXT@ | |
+CC = @CC@ | |
+DATADIRNAME = @DATADIRNAME@ | |
+GENCAT = @GENCAT@ | |
+GMOFILES = @GMOFILES@ | |
+GMSGFMT = @GMSGFMT@ | |
+GTK_CFLAGS = @GTK_CFLAGS@ | |
+GTK_CONFIG = @GTK_CONFIG@ | |
+GTK_LIBS = @GTK_LIBS@ | |
+GT_NO = @GT_NO@ | |
+GT_YES = @GT_YES@ | |
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ | |
+INSTOBJEXT = @INSTOBJEXT@ | |
+INTLDEPS = @INTLDEPS@ | |
+INTLLIBS = @INTLLIBS@ | |
+INTLOBJS = @INTLOBJS@ | |
+MAKEINFO = @MAKEINFO@ | |
+MKINSTALLDIRS = @MKINSTALLDIRS@ | |
+MSGFMT = @MSGFMT@ | |
+PACKAGE = @PACKAGE@ | |
+POFILES = @POFILES@ | |
+POSUB = @POSUB@ | |
+RANLIB = @RANLIB@ | |
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ | |
+USE_NLS = @USE_NLS@ | |
+VERSION = @VERSION@ | |
+WIN_RC = @WIN_RC@ | |
+WIN_RES = @WIN_RES@ | |
+l = @l@ | |
+localedir = @localedir@ | |
+ | |
+DOCPATH = /usr/doc/${PACKAGE}-${VERSION}/ | |
+DOCS = aiplayer.html configfile.html index.html server.html clientplay.h… | |
+ | |
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs | |
+CONFIG_HEADER = ../config.h | |
+CONFIG_CLEAN_FILES = | |
+DIST_COMMON = Makefile.am Makefile.in | |
+ | |
+ | |
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) | |
+ | |
+TAR = gtar | |
+GZIP_ENV = --best | |
+all: all-redirect | |
+.SUFFIXES: | |
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) | |
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile | |
+ | |
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) | |
+ cd $(top_builddir) \ | |
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status | |
+ | |
+tags: TAGS | |
+TAGS: | |
+ | |
+ | |
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) | |
+ | |
+subdir = doc | |
+ | |
+distdir: $(DISTFILES) | |
+ here=`cd $(top_builddir) && pwd`; \ | |
+ top_distdir=`cd $(top_distdir) && pwd`; \ | |
+ distdir=`cd $(distdir) && pwd`; \ | |
+ cd $(top_srcdir) \ | |
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top… | |
+ @for file in $(DISTFILES); do \ | |
+ d=$(srcdir); \ | |
+ if test -d $$d/$$file; then \ | |
+ cp -pr $$d/$$file $(distdir)/$$file; \ | |
+ else \ | |
+ test -f $(distdir)/$$file \ | |
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ | |
+ || cp -p $$d/$$file $(distdir)/$$file || :; \ | |
+ fi; \ | |
+ done | |
+info-am: | |
+info: info-am | |
+dvi-am: | |
+dvi: dvi-am | |
+check-am: all-am | |
+check: check-am | |
+installcheck-am: | |
+installcheck: installcheck-am | |
+install-exec-am: | |
+install-exec: install-exec-am | |
+ | |
+install-data-am: install-data-local | |
+install-data: install-data-am | |
+ | |
+install-am: all-am | |
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | |
+install: install-am | |
+uninstall-am: | |
+uninstall: uninstall-am | |
+all-am: Makefile | |
+all-redirect: all-am | |
+install-strip: | |
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install | |
+installdirs: | |
+ | |
+ | |
+mostlyclean-generic: | |
+ | |
+clean-generic: | |
+ | |
+distclean-generic: | |
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) | |
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]* | |
+ | |
+maintainer-clean-generic: | |
+mostlyclean-am: mostlyclean-generic | |
+ | |
+mostlyclean: mostlyclean-am | |
+ | |
+clean-am: clean-generic mostlyclean-am | |
+ | |
+clean: clean-am | |
+ | |
+distclean-am: distclean-generic clean-am | |
+ | |
+distclean: distclean-am | |
+ | |
+maintainer-clean-am: maintainer-clean-generic distclean-am | |
+ @echo "This command is intended for maintainers to use;" | |
+ @echo "it deletes files that may require special tools to rebuild." | |
+ | |
+maintainer-clean: maintainer-clean-am | |
+ | |
+.PHONY: tags distdir info-am info dvi-am dvi check check-am \ | |
+installcheck-am installcheck install-exec-am install-exec \ | |
+install-data-local install-data-am install-data install-am install \ | |
+uninstall-am uninstall all-redirect all-am all installdirs \ | |
+mostlyclean-generic distclean-generic clean-generic \ | |
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean | |
+ | |
+ | |
+install-data-local: | |
+ ${INSTALL} -d -o root -g root -m 0755 $(DOCPATH) | |
+ ${INSTALL} -o root -g root -m 0644 $(DOCS) $(DOCPATH) | |
+ | |
+# Tell versions [3.59,3.63) of GNU make to not export all variables. | |
+# Otherwise a system limit (for SysV at least) may be exceeded. | |
+.NOEXPORT: | |
diff --git a/doc/aiplayer.html b/doc/aiplayer.html | |
t@@ -0,0 +1,55 @@ | |
+<html> | |
+<head> | |
+<title>Adding computer-controlled players</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>Adding computer-controlled players</h1> | |
+ | |
+Multiplayer games of dopewars can be made a little more interesting by | |
+introducing computer-controlled, or AI, players. These players will join | |
+a dopewars server, and to all intents and purposes will behave like normal | |
+human players - they will deal in drugs in an attempt to make a fortune, | |
+they will encounter the cops, you can spy on them, and they will shoot at | |
+you if you give them the chance!<p> | |
+ | |
+To start a computer-controlled player, all you need is the standard dopewars | |
+binary. Run it as<br> | |
+<b>dopewars -c</b><br> | |
+and it will attempt to connect to the server and port specified in the | |
+<a href="configfile.html">configuration files</a> (or the local host, if none | |
+is specified). Alternatively, you can specify server and port with suitable | |
+<a href="commandline.html">command line options</a>. Since an AI player | |
+takes its game settings from the server it connects to, no other options in | |
+the configuration files will take effect, with the exception of the | |
+<a href="configfile.html#AITurnPause">AITurnPause</a> option, which sets the | |
+pause in seconds between turns.<p> | |
+ | |
+Once started and connected to the server, the AI player will choose a | |
+suitable name for itself and start playing. It will continue to play until | |
+its game finishes - i.e. it is killed or runs out of time - at which point | |
+the program will finish and drop you back to the command prompt. The program | |
+will display information to let you know what the AI player is doing within | |
+the game as it goes. Note that the program will pause for five seconds (or | |
+whatever you have set AITurnPause to be) before jetting to a new location - | |
+this is to simulate the time it takes a human player to choose which drugs | |
+to buy and to press all the requisite keys; it also gives other players a | |
+fighting chance of spotting the computer sitting still in any one location | |
+for a few seconds!<p> | |
+ | |
+If a computer player is attacked by the cops or another player, it will | |
+defend itself if it can, and attempt to run if necessary. During normal | |
+play it will also attempt to "blend in" with the other players by hurling | |
+rather pathetic insults at them... you are free to edit the code of the | |
+AI player to give these insults a little more "punch", or | |
+<a href="mailto:[email protected]">email</a> them to me (preferably | |
+without actually directing the insults themselves at me!) and I'll add them | |
+to the next dopewars release. | |
+ | |
+<hr> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>30-9-99</b> | |
+</body> | |
+</html> | |
diff --git a/doc/clientplay.html b/doc/clientplay.html | |
t@@ -0,0 +1,233 @@ | |
+<html> | |
+<head> | |
+<title>Playing the game: the dopewars client</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>Playing the game: the dopewars client</h1> | |
+ | |
+The dopewars client is the part of dopewars which most users will | |
+encounter most frequently. If the dopewars binary is run without the | |
+<b>-s</b> (server) or <b>-c</b> (computer player) options (see | |
+<a href="commandline.html">command line options</a>) it defaults to running | |
+in client mode. The dopewars client handles the interaction between a | |
+human player and the dopewars server (but if a dopewars server is not | |
+available, a "virtual" server will be run by the client to enable a | |
+single-player game to be played).<p> | |
+ | |
+A brief description of using the client and playing dopewars is given here. | |
+Bear in mind that both the client and the server you are connecting to can | |
+be configured by means of the dopewars <a href="configfile.html"> | |
+configuration files</a>, and so the game may differ radically from what is | |
+described here. It is suggested that you familiarise yourself with the game | |
+using the default settings before getting too adventurous!<p> | |
+ | |
+<ul> | |
+<li><a href="#startup">Starting the dopewars client</a> | |
+<li><a href="#screen">The main game screen</a> | |
+<li><a href="#server">Connecting to a dopewars server (or not)</a> | |
+<li><a href="#dealing">Dealing drugs and moving around</a> | |
+<li><a href="#finance">Your finances: loans and banks</a> | |
+<li><a href="#cops">Law enforcement and why it's a bad thing</a> | |
+<li><a href="#multiplayer">Multiplayer: interacting with other players</a> | |
+</ul> | |
+ | |
+<a name="startup"><h2>Starting the dopewars client</h2></a> | |
+<ul> | |
+<li>From the command prompt, run the dopewars client with the command<br> | |
+<b>dopewars</b><br> | |
+or to run an <a href="commandline.html#antique">"antique"</a> mode game,<br> | |
+<b>dopewars -a</b> | |
+ | |
+<li>An introduction screen will appear, giving a brief description of the | |
+game and version and licensing information. Press any key to clear this. | |
+</ul> | |
+ | |
+<a name="screen"><h2>The main game screen</h2></a> | |
+ | |
+The game screen is your interface with the dopewars world. At the top of the | |
+screen, from left to right, is displayed the game date, the game location | |
+(you start in the Bronx), the number of bitches working for you, and the | |
+space you have available for drugs. Note that each drug uses up one "space", | |
+but some guns may take up more. | |
+Your "bitches" are your subordinates - each bitch increases your "space" | |
+by 10 (you yourself start with a space of 20) and can carry one gun (you can | |
+carry two). Your bitches also take damage for you when in firefights, so it | |
+is advantageous to acquire extra bitches during the game.<p> | |
+ | |
+Below the top line of the screen are three large windows. The one in | |
+the top left lists your statistics - your finances, the health of yourself | |
+or your bitches, and the number of guns you are carrying. Notice that you | |
+start the game with a debt - this will increase, turn by turn, until you | |
+pay it off to the Loan Shark. The top right window lists the drugs that you | |
+are currently carrying (you start off with none). Below this is a window in | |
+which messages from other players (if any) will appear.<p> | |
+ | |
+Please note that if you are playing in <a href="commandline.html#antique"> | |
+"antique"</a> mode, you do not have "bitches" but instead have a large | |
+trenchcoat which can carry 100 drugs. Antique mode also disables the | |
+messages window.<p> | |
+ | |
+<a name="server"><h2>Connecting to a dopewars server (or not)</h2></a> | |
+ | |
+On starting a game of dopewars, the first thing you must do is give | |
+yourself a name. This identifies you to the server and to other players. If | |
+you are running in <a href="commandline.html#singleplayer">single-player</a> | |
+or <a href="commandline.html#antique">antique</a> mode, the client will | |
+then start an internal "virtual" server and immediately start the game.<p> | |
+ | |
+In other cases, the client will attempt to connect to a dopewars server | |
+specified in the <a href="configfile.html#Server">configuration file</a> or | |
+on the <a href="commandline.html#server">command line</a> (if none is | |
+specified, it defaults to the local host). If this connection is successful, | |
+the game will then start. Otherwise, you will be given the option to manually | |
+choose a different server, obtain the server list from the metaserver and | |
+choose one, play a single-player game, or quit, by pressing the | |
+C, L, P, or Q keys respectively. If you don't want the client to attempt to | |
+connect to a server, this can be set - full details are given in the section | |
+on <a href="configfile.html#Server">configuration files</a>.<p> | |
+ | |
+<a name="dealing"><h2>Dealing drugs and moving around</h2></a> | |
+ | |
+The New York of dopewars is divided into 8 (6 in "antique" mode) locations. | |
+At each of these locations, a variety of drugs, with fluctuating prices, are | |
+on sale. Not all of the drugs are necessarily on sale at each location all | |
+of the time, and the normally gentle fluctuations may be affected by such | |
+events as other dealers flooding the market with drugs, or the cops making | |
+a big drugs bust (which will drive the price up). On arriving at a new | |
+location, you will be told if any of these "special" events have occurred.<p> | |
+ | |
+The main way to make money in dopewars is to buy and sell drugs, buying | |
+cheaply at one location, and then moving ("jetting") to a new location (a | |
+process which uses up one "day" or turn), and then selling for a profit at | |
+this new location. When you have arrived at a location, you will be told which | |
+drugs are being dealt in. You may buy one of these drugs by pressing the "B" | |
+key, then pressing the letter for the drug you wish to buy, and then entering | |
+the number of this drug you require. Bear in mind that you may not be able | |
+to afford or carry these drugs! Selling drugs is similar, on pressing the "S" | |
+key. When you are done and wish to "jet" to a new location, press the "J" key | |
+and then choose the location number.<p> | |
+ | |
+If you are at a location where you cannot sell your drugs, you can drop them | |
+to free up space in your inventory (with the "D" key). Of course, this does | |
+not get you any money, and there is a chance that the cops may catch you in | |
+the act and attack you (see below).<p> | |
+ | |
+<a name="finance"><h2>Your finances: loans and banks</h2></a> | |
+ | |
+Buying and selling drugs may make money, but unfortunately you start the game | |
+with a debt to the loan shark of $5,000. Every turn this accumulates | |
+interest, and counts against your total amount of money at the end of the | |
+game (which is used as your high score, so it's quite possible to end with | |
+a negative score). To pay off the loan, you must visit the loan shark by | |
+jetting to the Bronx. You will be asked if you wish to visit the loan shark - | |
+respond by pressing the "Y" key - and then asked how much money you want to | |
+give him. Respond by entering the amount of money, without the $ sign or | |
+commas, and ended with "k" or "m" as shorthand for "thousand" or "million" | |
+if you like (i.e. entering "2.5k" is the same as "2000", which is $2,000).<p> | |
+ | |
+You can also deposit or withdraw money from the bank, which is also located | |
+in the Bronx. This is done in a similar way to paying the loan shark. Putting | |
+your money in the bank lets you accumulate interest on it, and prevents it | |
+from being stolen if you are mugged (which does occasionally happen). Money | |
+in the bank also contributes to your high score at the end of the game.<p> | |
+ | |
+<a name="cops"><h2>Law enforcement and why it's a bad thing</h2></a> | |
+ | |
+When you jet to a new location, one or more "random events" may occur. | |
+Usually this is just something such as a drug bust which affects drug prices, | |
+but there are a number of other beneficial, useless, or just plain annoying | |
+random events. Perhaps the most annoying of these is an encounter with the | |
+cops, in the form of Officer Hardass or Bob and their deputies.<p> | |
+ | |
+When you meet Officer Hardass, you must decide what to do. If you don't have | |
+any guns, you must answer Y (yes) or N (no) to the question "Do you run?" | |
+If you are lucky, you'll get away - otherwise, the cops may shoot you. The | |
+more deputies are accompanying Hardass, the worse the damage is likely to be. | |
+If you take enough damage for your health to drop to zero, you will lose a | |
+bitch (and, possibly, some drugs and a gun, if the bitch was carrying them). | |
+If you have no bitches, you will die, and the game will end! The more | |
+successful your drug dealing is (i.e. the more money you have made) the | |
+more aggressive the cops will be.<p> | |
+ | |
+If, on the other hand, you have acquired one or more guns, you can either run | |
+("R" key) or fight ("F"). Guns may be offered to you at bargain prices | |
+randomly, or you can visit the gun shop in the Ghetto and buy or sell them. | |
+To beat the cops by fighting them, you must kill all the deputies, one by one, | |
+and then finally Officer Hardass. Bear in mind that the more guns you have, the | |
+more damage you will do to the cops! If you kill Officer Hardass, you can take | |
+whatever money you find on his corpse, and if you are lucky a doctor will | |
+offer to "sew you up" (i.e. restore your health to 100) for a price.<p> | |
+ | |
+If, after killing Officer Hardass, you are unlucky enough to meet the cops | |
+again later on, they will be lead by his replacement, Officer Bob, who is | |
+unfortunately immortal. You can kill him and ransack his corpse as before, | |
+but that doesn't stop him from returning later on...<p> | |
+ | |
+If you lose bitches, or simply want to acquire more, you can visit the pub | |
+in the Ghetto to hire them, or they may offer their services to you at | |
+bargain rates randomly.<p> | |
+ | |
+<a name="multiplayer"><h2>Multiplayer: interacting with other players</h2></a> | |
+ | |
+If you log on to a dopewars server, there is the possibility of meeting other | |
+players, either human or computer-controlled. When joining a game which | |
+already contains other players, they will be listed to you. Other players | |
+which join or leave the game once you are playing will announce their | |
+presence to you automatically via. the "Messages" window.<p> | |
+ | |
+When in multiplayer mode, you can send a message to all current players by | |
+pressing the "T" key from the main drug prices screen, and then typing in | |
+your message. To send a private message, use the "P" key and select the | |
+player instead. These messages will appear in the Messages window also.<p> | |
+ | |
+Another new command in multiplayer mode is the list command ("L" key). This | |
+will either list the other players in the game, or the list of high scores | |
+maintained by the server which you're connected to.<p> | |
+ | |
+The "G" key activates the "give errand" command. With this you can sack one | |
+of your bitches (with the "G" key again), pay one to tip off the cops to one | |
+of the other players, or pay one to leave your employment and to join another | |
+player and spy on them for you. In any case, if you lose a bitch you may | |
+also lose any drugs or guns which they were carrying (remember that each | |
+bitch can carry one gun, and increases your inventory - your available space - | |
+by 10).<p> | |
+ | |
+A tip-off means that Officer Hardass or Bob will attack your chosen | |
+enemy when they jet to their next location (and then you will get to hear | |
+the result of the encounter). A spy, on the other hand, will present himself t… | |
+a bargain bitch (in the same way as normal "bargain bitches" appear). If your | |
+enemy accepts the bitch, you will then be able to see everything about the | |
+enemy whenever you like, by pressing the "C" key from the main drug prices | |
+screen. Unfortunately, there is a chance that your spy may be discovered by | |
+your opponent later on...<p> | |
+ | |
+If, in the course of normal play, you are carrying one or more guns, and you | |
+jet to the a location where another player already is, you will be informed of | |
+their presence. You can either ignore them completely (with the "E" key) | |
+in which case they will never know you were there, or you can attack them | |
+with the "A" key. When you attack another player, or another player attacks | |
+you, the main screen which normally lists drug prices at the current location | |
+is replaced by the fighting screen. You can switch back from this screen to | |
+the drug price screen with the "D" key, but note that the "Jet" command is now | |
+missing from the drug price screen - you must instead use the "F" key to | |
+return to the fight, and conclude it before continuing on your way.<p> | |
+ | |
+When in a fight with another player, you can choose not to fire back with the | |
+"S" key, you can shoot back with the "F" key, or you can run from the fight | |
+with the "R" key. Be aware that if you fail to shoot back at your enemy | |
+within five seconds, they can fire at you again (otherwise, shots alternate | |
+between you and your enemy). If you kill an enemy bitch, you | |
+are awarded a bounty from the cops for killing such a dangerous criminal; if | |
+you kill an enemy player (after you've killed all of their bitches) you | |
+receive their total assets - their cash and bank balance minus any debt. In | |
+either case you can loot the body and pick up any guns or drugs which the | |
+bitch or player was carrying.<p> | |
+ | |
+<hr> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>11-10-99</b> | |
+</body> | |
+</html> | |
diff --git a/doc/commandline.html b/doc/commandline.html | |
t@@ -0,0 +1,123 @@ | |
+<html> | |
+<head> | |
+<title>dopewars command line options</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>dopewars command line options</h1> | |
+ | |
+Once you have <a href="installation.html">installed</a> dopewars, you should | |
+be able to run the binary just by typing<br> | |
+<b>dopewars</b><br> | |
+(unless you have installed the binary in a directory which is not in your | |
+path, in which case precede it with the path). Run without any options, | |
+the dopewars binary runs as a dopewars client.<p> | |
+ | |
+Command line options can be used to configure common aspects of dopewars. | |
+More exhaustive configuration is possible by editing the dopewars | |
+<a href="configfile.html">configuration files</a>; note, however, that | |
+command line options can be used to override some of these settings (also see | |
+the <b>-g</b> option below).<p> | |
+ | |
+For a brief description of | |
+the command line options, specify the option <b>-h</b> with the command<br> | |
+<b>dopewars -h</b><br> | |
+A list of the other command line options is presented below. | |
+<dl> | |
+<dt><b>-b</b> | |
+<dd>"Black and white". This tells the dopewars client (if that is what | |
+you're running) not to use coloured text (by default, colour is used if the | |
+terminal and curses support it). | |
+ | |
+<a name="singleplayer"><dt><b>-n</b></a> | |
+<dd>If running the client, run in single-player mode. Don't try to connect | |
+to any available dopewars servers. | |
+ | |
+<a name="antique"><dt><b>-a</b></a> | |
+<dd>Puts the client into "antique" mode; dopewars is derived from the | |
+earlier game for MS-DOS of the same name, which in turn was based on | |
+"Drug Wars" by John E. Dell. "Antique" mode aims to follow the behaviour | |
+of the MS-DOS dopewars closely, and consequently this entails single-player | |
+mode also. | |
+ | |
+<a name="hiscore"><dt><b>-f <i>file</i></b></a> | |
+<dd>Specifies the path and name of the file used to store the dopewars | |
+high scores in; this can alternatively be specified in the configuration file | |
+with the <a href="configfile.html#HiScoreFile">HiScoreFile=<i>file</i></a> | |
+option. | |
+ | |
+<a name="server"><dt><b>-o <i>addr</i></b></a> | |
+<dd>Gives the name of the machine running a dopewars server, in human | |
+readable (e.g. "nowhere.com") or dotted quad (e.g. 127.0.0.1) form. When the | |
+client is started, if not in single-player mode, it automatically attempts to | |
+connect to this server for a multiplayer game. This can also be specified with | |
+the <a href="configfile.html#Server">Server=<i>addr</i></a> configuration file | |
+option. | |
+ | |
+<a name="port"><dt><b>-p <i>port</i></b></a> | |
+<dd>Specifies the numeric port number which the server uses. This is usually | |
+7902, but some servers may use other port numbers to avoid conflicts with | |
+other services running on the machine. If you are running the dopewars client, | |
+it will search for a server on this port; if you are running the server, it | |
+will bind to this port and wait for connections from clients (the clients | |
+must also be instructed to use this port, of course). This is equivalent to | |
+setting the port number with the <a href="configfile.html#Port">Port=<i>port</… | |
+configuration file option. | |
+ | |
+<dt><b>-s</b> | |
+<dd>Runs the <a href="server.html">dopewars server</a>. This mediates | |
+multiplayer games of dopewars, and keeps track of high scores. Any player | |
+wishing to join the game hosted | |
+by this server must connect to your machine using the dopewars client and the | |
+port number which you have chosen, and can then interact with other players | |
+who have done the same thing. By default, a dopewars server will report its | |
+status to the <a href="metaserver.html">metaserver</a>, unless it is set | |
+otherwise in the <a href="configfile.html#MetaServerActive">configuration | |
+file</a>. | |
+ | |
+<a name="privateserver"><dt><b>-S</b></a> | |
+<dd>Also runs a dopewars server, but in this case <b>does not</b> report its | |
+status to the metaserver. This does not stop clients from connecting to your | |
+server, of course (unless it is behind a firewall, or the | |
+<a href="configfile.html#MaxClients">maximum number of clients</a> is exceeded… | |
+but it makes it harder to find. The connection to the | |
+<a href="metaserver.html">metaserver</a> can also be disabled by adding | |
+<a href="configfile.html#MetaServerActive">MetaServer.Active=0</a> to the | |
+configuration files. | |
+ | |
+<dt><b>-g <i>file</i></b> | |
+<dd>Instructs dopewars to read setup information from the | |
+<a href="configfile.html">configuration file</a> named by <b><i>file</i></b>. | |
+This file is read immediately - i.e. at the point at which the -g option is | |
+encountered - and so these settings will override any set in the default | |
+configuration files or by previous command line options. Command line options | |
+occurring <b>after</b> the -g option, or for that matter further -g options, | |
+that change these same settings, will then override them. | |
+ | |
+<dt><b>-r <i>file</i></b> | |
+<dd>Maintains a pid file with the specified name while the server is running. | |
+The file is a one-line text file, containing the process ID of the dopewars | |
+server process, and is deleted when the server quits. | |
+ | |
+<a name="computer"><dt><b>-c</b></a> | |
+<dd>Runs a computerised player. This will connect to the specifed dopewars | |
+server and join in the multiplayer game going on there. When the player | |
+finishes the game (or is eliminated by the other players or the server) the | |
+program finishes. | |
+ | |
+<dt><b>-h</b> | |
+<dd>Displays a brief description of the available command line options, and | |
+contact details. | |
+ | |
+<dt><b>-v</b> | |
+<dd>Displays the current dopewars version number, and then exits. | |
+ | |
+</dl> | |
+ | |
+<hr> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>06-05-2000</b> | |
+</body> | |
+</html> | |
diff --git a/doc/configfile.html b/doc/configfile.html | |
t@@ -0,0 +1,460 @@ | |
+<html> | |
+<head> | |
+<title>dopewars configuration files</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>dopewars configuration files</h1> | |
+ | |
+A dopewars <a href="server.html">server</a>, or a <a href="clientplay.html"> | |
+client</a> (in single-player mode) can be heavily configured by the means | |
+of dopewars configuration files. Clients used to connect to multiplayer | |
+servers can also be configured by the same means, but almost all of these | |
+settings will be overridden on connecting to the server (although the server | |
+location settings <i>Port</i> and <i>Server</i> are still useful).<p> | |
+ | |
+The order of making dopewars settings is as follows:- | |
+<ol> | |
+<li>The global configuration file (if present) <b>/etc/dopewars</b> | |
+<li>The user-specific file (if present) <b>~/.dopewars</b> | |
+<li>Options specified on the <a href="commandline.html">command line</a> | |
+</ol> | |
+ | |
+Settings in a configuration file can set numbers, strings or "string lists". | |
+A numerical value is set with a command such as <b>Port=7902</b> (which sets | |
+the TCP port for mulitplayer connections to 7902).<p> | |
+ | |
+String (text) values are set with commands such as <b>BankName="the bank"</b> | |
+(which sets the name of the bank). Notice that string values <b>must</b> be | |
+enclosed in quotes. Strings in double quotes understand escapes such as "\n"; | |
+strings in single quotes do not treat backslash characters specially.<p> | |
+ | |
+A string list is used for setting an array of strings; for example | |
+<b>SubwaySaying = { "Saying 1", "Saying 2", "Saying 3" }</b> sets up three | |
+"subway sayings". A string list consists of a list of strings, separated by | |
+commas and wrapped with braces - { and } characters. Single strings in a | |
+string list can be replaced individually - for example | |
+<b>SubwaySaying[3]="Third Saying"</b> replaces the third string (which was | |
+previously "Saying 3"). The <i>number</i> of strings in the list | |
+<i>"List"</i> can be set with the variable <i>NumList</i> - for example, | |
+<b>NumSubwaySaying=4</b> dimensions the <b>SubwaySaying</b> list to contain | |
+four strings.<p> | |
+ | |
+Whitespace and line breaks are ignored in the configuration files; comments | |
+can be used, and extend from a '#' character to the end of the current line, | |
+or are enclosed by C-style /* and */ symbols. See the | |
+<a href="example-cfg">example configuration file</a> for a demonstration. | |
+Valid configuration file settings are listed below. The examples given | |
+generally reproduce the default behaviour; obviously you are free to replace | |
+the parts in italics to customise your own server and client.<p> | |
+ | |
+<ul> | |
+<li><a href="#fileloc">General configuration: file and server locations</a> | |
+<li><a href="#metaserver">Metaserver configuration</a> | |
+<li><a href="#places">Basic configuration: places in the game</a> | |
+<li><a href="#drugs">Basic configuration: drug prices</a> | |
+<li><a href="#guns">Basic configuration: guns</a> | |
+<li><a href="#advanced">Advanced configuration</a> | |
+</ul> | |
+ | |
+<a name="fileloc"><h2>General configuration: file and server locations</h2></a> | |
+ | |
+<dl> | |
+<a name="Port"><dt><b>Port=<i>7902</i></b></a> | |
+<dd>Tells the dopewars client to look for a server on port <i>7902</i>, and | |
+tells the dopewars server to bind to port <i>7902</i> and wait for connections. | |
+This can be overridden with the -p <a href="commandline.html#port"> | |
+command line option</a>. | |
+ | |
+<a name="Server"><dt><b>Server=<i>"localhost"</i></b></a> | |
+<dd>Tells the dopewars client to look for a server at the address | |
+<i>localhost</i>. Dotted quad (e.g. 127.0.0.1) addresses may also be used here. | |
+If this variable is set to one of the three "special" names | |
+<b>(MetaServer)</b>, <b>(Prompt)</b>, or <b>(Single)</b> (including the | |
+brackets) then the client will not connect to a server but instead | |
+list the servers available at the metaserver, prompt the user to enter a | |
+server name and port, or play in single player mode, respectively. | |
+This option can be overridden with the -o <a href="commandline.html#server"> | |
+command line option</a> (but be sure to protect the brackets from the shell | |
+if you use one of the "special" names). | |
+ | |
+<a name="HiScoreFile"><dt><b>HiScoreFile=<i>"/var/lib/dopewars.sco"</i></b></a> | |
+<dd>Tells the dopewars server (or the client, if running in single-player | |
+mode, not connected to a server) to use the file <i>/var/lib/dopewars.sco</i> | |
+to store high scores. This can be overridden with the -f | |
+<a href="commandline.html#hiscore">command line option</a>. | |
+ | |
+<dt><b>Pager=<i>"more"</i></b> | |
+<dd>Sets the pager used to display multi-page output in an interactive server | |
+to <i>more</i>. ("less" is a popular alternative) | |
+ | |
+<dt><b>ConfigVerbose=<i>0</i></b> | |
+<dd>Prints extra feedback information when processing the config. file if set | |
+to 1; this only takes affect, of course, after the ConfigVerbose variable is | |
+set, and then remains in force until it is reset again. | |
+</dl> | |
+ | |
+<a name="metaserver"><h2>Metaserver configuration</h2></a> | |
+<dl> | |
+<a name="MetaServerActive"><dt><b>MetaServer.Active=<i>1</i></b></a> | |
+<dd>Tells the dopewars server to report its status to the | |
+<a href="metaserver.html">metaserver</a>. If <i>1</i> | |
+is replaced by <i>0</i> (zero) the server will not report to the metaserver. | |
+This setting, if set to 1, can be overridden by the -S | |
+<a href="commandline.html#privateserver">command line option</a>. | |
+ | |
+<dt><b>MetaServer.Name=<i>"bellatrix.pcl.ox.ac.uk"</i></b> | |
+<dd>Tells dopewars that the metaserver is located at | |
+<i>bellatrix.pcl.ox.ac.uk</i>. See the <a href="metaserver.html">metaserver</a> | |
+page for information about connecting to the dopewars metaserver via. a | |
+proxy web server. | |
+ | |
+<dt><b>MetaServer.HttpPort=<i>80</i></b> | |
+<dd>Instructs the dopewars client that the metaserver can be found on TCP port | |
+<i>80</i>. This is the standard HTTP port for Web access, but you may need to | |
+change this if you are connecting via. a proxy web server. | |
+ | |
+<dt><b>MetaServer.UdpPort=<i>7802</i></b> | |
+<dd>Instructs the dopewars server that the metaserver can be found on UDP port | |
+<i>7802</i>. The server utilises UDP as oppposed to the TCP connection used | |
+by the client due to its much lower overhead. | |
+ | |
+<dt><b>MetaServer.Path=<i>"/~ben/cgi-bin/server.pl"</i></b> | |
+<dd>Tells dopewars that the CGI script on the metaserver, for server | |
+registration (server mode) or listing the available servers (client mode) is | |
+<i>/~ben/cgi-bin/server.pl</i>. | |
+ | |
+<a name="MetaServerComment"><dt><b>MetaServer.Comment=<i>"dopewars | |
+server"</i></b></a> | |
+<dd>Sets the comment for your server, which appears on the list of servers | |
+maintained by the metaserver, to <i>dopewars server</i>. | |
+ | |
+<dt><b>MetaServer.LocalName=<i>"dope-serv.com"</i></b></a> | |
+<dd>Tells the metaserver that the preferred hostname of your dopewars server | |
+machine is <i>dope-serv.com</i>. By default, the metaserver tries to ascertain | |
+your domain name from the connection, and this can fail if you connect via. | |
+a proxy server, or if DNS does not properly translate your IP address to your | |
+domain name. You must also set MetaServer.Password to the password given to | |
+you by the <a href="mailto:[email protected]">metaserver | |
+maintainer</a> for this to work. A blank LocalName can also be used with a | |
+suitable password to identify "your" server, even if its IP changes. | |
+See the <a href="metaserver.html">metaserver page</a> for more details. | |
+ | |
+<dt><b>MetaServer.Password=<i>"auth"</i></b></a> | |
+<dd>Uses the password <i>auth</i> to authenticate your dopewars server's | |
+hostname (see MetaServer.LocalName above) with the metaserver. | |
+</dl> | |
+ | |
+<a name="places"><h2>Basic configuration: places in the game</h2></a> | |
+ | |
+<dl> | |
+<dt><b>NumLocation=<i>8</i></b> | |
+<dd>Sets the number of locations in the game to <i>8</i>. Note that if too | |
+many locations are specified, the client may not be able to display them | |
+all! | |
+ | |
+<dt><b>Location[<i>4</i>].Name=<i>"Manhattan"</i></b> | |
+<dd>Sets the name of the <i>4th</i> location in the game to <i>Manhattan</i>. | |
+The index within the square brackets can range from 1 to whatever | |
+NumLocation is set to above, or an error will be reported. | |
+ | |
+<dt><b>Location[<i>4</i>].PolicePresence=<i>90</i></b> | |
+<dd>Sets the police presence in the <i>4th</i> location to <i>90%</i>. In | |
+theory this affects how likely it is for the police to catch players at | |
+each location; in practice, it has no effect (code not written yet - sorry!). | |
+ | |
+<dt><b>Location[<i>4</i>].MinDrug=<i>4</i></b> | |
+<dd>Sets the minimum possible number of different drugs that will be on sale | |
+to players in location number <i>4</i> to <i>4</i>. | |
+ | |
+<dt><b>Location[<i>4</i>].MaxDrug=<i>10</i></b> | |
+<dd>Sets the maximum possible number of different drugs that will be on sale | |
+to players in location number <i>4</i> to <i>10</i>. | |
+ | |
+<dt><b>LoanShark=<i>1</i></b> | |
+<dd>Makes the loan shark pop up when players visit location number <i>1</i>. | |
+To stop the loan shark from appearing at all (making it rather difficult to | |
+pay off debts) set this number to something which is not a valid location, | |
+such as 0 (zero). | |
+ | |
+<dt><b>Bank=<i>1</i></b> | |
+<dd>Makes the bank appear when a player visits location <i>1</i> (the Bronx). | |
+ | |
+<dt><b>GunShop=<i>2</i></b> | |
+<dd>Players can visit the gun shop in location number <i>2</i> (the | |
+Ghetto). | |
+ | |
+<dt><b>RoughPub=<i>2</i></b> | |
+<dd>Players can visit the rough pub to hire bitches in location number | |
+<i>2</i>. | |
+ | |
+<dt><b>LoanSharkName=<i>"the Loan Shark"</i></b> | |
+<dd>The loan shark is known by the name <i>"the Loan Shark"</i> during the gam… | |
+ | |
+<dt><b>BankName=<i>"the bank"</i></b> | |
+<dd>The bank is known by the name <i>"the bank"</i> during the game. | |
+ | |
+<dt><b>GunShopName=<i>"Dan's House of Guns"</i></b> | |
+<dd>The gun shop is known by the name <i>"Dan's House of Guns"</i> during | |
+the game. | |
+ | |
+<dt><b>RoughPubName=<i>"the pub"</i></b> | |
+<dd>The pub is known by the name <i>"the pub"</i> during the game. | |
+</dl> | |
+ | |
+<a name="drugs"><h2>Basic configuration: drug prices</h2></a> | |
+<dl> | |
+<dt><b>NumDrug=<i>12</i></b> | |
+<dd>Sets there to be <i>12</i> different types of drug in the game. | |
+ | |
+<dt><b>Drug[<i>6</i>].Name=<i>"MDA"</i></b> | |
+<dd>Sets the name of the <i>6th</i> drug to be <i>MDA</i>. | |
+ | |
+<dt><b>Drug[<i>6</i>].MinPrice=<i>1500</i></b> | |
+<dd>Sets the usual minimum price of the <i>6th</i> drug (in the absence of | |
+"special events" such as drug busts) to be <i>$1,500</i>. | |
+ | |
+<dt><b>Drug[<i>6</i>].MaxPrice=<i>4400</i></b> | |
+<dd>Sets the usual maximum price of drug number <i>6</i> to be <i>$4,400</i>. | |
+ | |
+<dt><b>Drug[<i>1</i>].Cheap=<i>1</i></b> | |
+<dd>Tells dopewars that drug <i>1</i> (by default, Acid) can occasionally | |
+be especially cheap (if this is set to 0, zero, this does not happen). | |
+ | |
+<dt><b>Drug[<i>1</i>].CheapStr=<i>"The market is flooded with cheap | |
+home-made acid!"</i></b> | |
+<dd>Sets the message to display to alert players that drug number <i>1</i> | |
+is especially cheap. | |
+ | |
+<dt><b>Drugs.CheapDivide=<i>4</i></b> | |
+<dd>Tells dopewars that whenever a drug is "specially" cheap, divide the | |
+normal price distribution (between Drug[x].MinPrice and Drug[x].MaxPrice) by | |
+<i>4</i>. | |
+ | |
+<dt><b>Drug[<i>4</i>].Expensive=<i>1</i></b> | |
+<dd>Tells dopewars that drug <i>4</i> (normally Heroin) can occasionally be | |
+particuarly expensive (0, zero, cancels this). | |
+ | |
+<dt><b>Drugs.ExpensiveStr1=<i>"Cops made a big %s bust! Prices are | |
+outrageous!"</i></b> | |
+<dd>Sets the string that is displayed when <b>any</b> drug is particularly | |
+expensive. This is a standard C-style format string - i.e. the %s is | |
+replaced by the name of the drug which is expensive. This string is | |
+displayed 50% of the time for expensive drugs. | |
+ | |
+<dt><b>Drugs.ExpensiveStr2=<i>"Addicts are buying %s at ridiculous | |
+prices!"</i></b> | |
+<dd>Sets the string which is used for expensive drugs the other 50% of the | |
+time. | |
+ | |
+<dt><b>Drugs.ExpensiveMultiply=<i>4</i></b> | |
+<dd>Tells dopewars that whenever a drug is "specially" expensive, multiply the | |
+normal price distribution (between Drug[x].MinPrice and Drug[x].MaxPrice) by | |
+<i>4</i>. | |
+</dl> | |
+ | |
+<a name="guns"><h2>Basic configuration: guns</h2></a> | |
+<dl> | |
+<dt><b>NumGun=<i>4</i></b> | |
+<dd>Configures the game to have <i>4</i> guns available to players at the | |
+gun shop. | |
+ | |
+<dt><b>Gun[<i>3</i>].Name=<i>"Ruger"</i></b> | |
+<dd>Sets the name of the <i>3rd</i> gun to <i>Ruger</i>. | |
+ | |
+<dt><b>Gun[<i>3</i>].Price=<i>2900</i></b> | |
+<dd>Sets the price in the gun shop of the <i>3rd</i> gun to <i>$2,900</i>. | |
+Guns offered "on the street" (i.e. by random events) will be priced at 10% | |
+of the value set here. | |
+ | |
+<dt><b>Gun[<i>3</i>].Space=<i>4</i></b> | |
+<dd>Tells dopewars that gun number <i>3</i> uses <i>4</i> spaces in the | |
+inventory - i.e. carrying one of these guns uses the same spaces as 4 drugs. | |
+ | |
+<dt><b>Gun[<i>3</i>].Damage=<i>4</i></b> | |
+<dd>Defines gun number <i>3</i> to do up to <i>4</i> points of damage - i.e. | |
+a successful hit with one of these guns decreases the target's health by | |
+up to 4 points. | |
+</dl> | |
+ | |
+<a name="advanced"><h2>Advanced configuration</h2></a> | |
+<dl> | |
+<dt><b>NumTurns=<i>31</i></b> | |
+<dd>Defines the game to end after <i>31</i> "days" or turns. If this is set | |
+to 0 (zero) the game never ends for a player, unless they quit or are killed. | |
+ | |
+<dt><b>Sanitized=<i>0</i></b> | |
+<dd>If set to 1, this "sanitizes" the game by removing all drug references | |
+from the random events. To completely remove drug references, of course, you | |
+must also alter the drug names above. | |
+ | |
+<dt><b>DrugSortMethod=<i>1</i></b> | |
+<dd>Tells the dopewars client how to sort the names of available drugs at | |
+each location for display. The default, <i>1</i>, sorts them in alphabetical | |
+order by their names. The choices are as follows:- | |
+<ul> | |
+<li><b>1</b>. Sort in forward alphabetical order by name | |
+<li><b>2</b>. Sort in reverse alphabetical order by name | |
+<li><b>3</b>. Sort in order of current price, cheapest first | |
+<li><b>4</b>. Sort in order of current price, most expensive first | |
+</ul> | |
+ | |
+<dt><b>FightTimeout=<i>5</i></b> | |
+<dd>If a player in a firefight with another player fails to fire back | |
+within <i>5</i> seconds, lets his/her enemy have another shot. If this | |
+is set to 0 (zero) timeouts are disabled, and players may take as long | |
+as they like to fire back. | |
+ | |
+<dt><b>IdleTimeout=<i>14400</i></b> | |
+<dd>If a connected player in a game does nothing to interact with the | |
+server for <i>14400</i> seconds, he/she will be automatically disconnected. | |
+ | |
+<dt><b>ConnectTimeout=<i>300</i></b> | |
+<dd>If a player takes more than <i>300</i> seconds to complete the process | |
+of connecting or disconnecting to the server, the server will sever the | |
+connection. | |
+ | |
+<a name="MaxClients"><dt><b>MaxClients=<i>20</i></b></a> | |
+<dd>Prevents more than <i>20</i> clients from connecting to the server at | |
+any one time. | |
+ | |
+<a name="AITurnPause"><dt><b>AITurnPause=<i>5</i></b></a> | |
+<dd>Makes computer-controlled client players run from this machine (not | |
+necessarily AI players that connect to a server run on this machine) wait | |
+<i>5</i> seconds between moving from location to location - i.e. a turn | |
+takes at least 5 seconds. | |
+ | |
+<dt><b>StartCash=<i>2000</i></b> | |
+<dd>Each player will start the game with <i>$2,000</i> in cash. | |
+ | |
+<dt><b>StartDebt=<i>5000</i></b> | |
+<dd>Each player will start the game with a debt to the loan shark of | |
+<i>$5,000</i>. | |
+ | |
+<dt><b>Cops.EscapeProb=<i>70</i></b> | |
+<dd>Gives each player a <i>70%</i> chance of escaping successfully from | |
+Officer Hardass or Bob on his own, if the player chooses to run | |
+ | |
+<dt><b>Cops.DeputyEscape=<i>2</i></b> | |
+<dd>Decreases the probability of escaping from the cops by <i>2%</i> per | |
+deputy accompanying a police officer. | |
+ | |
+<dt><b>Cops.HitProb=<i>65</i></b> | |
+<dd>Sets the probability of a lone policer officer hitting you in a firefight | |
+to <i>65%</i>. | |
+ | |
+<dt><b>Cops.DeputyHit=<i>2</i></b> | |
+<dd>Increases the probability of the cops hitting you by <i>2%</i> per deputy | |
+accompanying a police officer. | |
+ | |
+<dt><b>Cops.Damage=<i>5</i></b> | |
+<dd>Sets the maximum damage done to a player in a firefight with the cops | |
+to <i>5</i> per cop. | |
+ | |
+<dt><b>Cops.Toughness=<i>2</i></b> | |
+<dd>Sets the difficulty of killing a cop to <i>2</i>. This works <b>against</b> | |
+the decreased difficulty provided by each extra gun a player has. | |
+ | |
+<dt><b>Cops.DropProb=<i>30</i></b> | |
+<dd>Sets the probability that the cops will discover a player dropping drugs, | |
+and subsequently attack them, to <i>30%</i>. | |
+ | |
+<dt><b>Names.Bitch=<i>"bitch"</i></b> | |
+<dd>Sets the word used to describe a single "bitch" in the game. Bitch, gun | |
+and drug names are automatically capitalised where necessary by the dopewars | |
+code. | |
+ | |
+<dt><b>Names.Bitches=<i>"bitches"</i></b> | |
+<dd>Sets the word used to describe two or more "bitches". | |
+ | |
+<dt><b>Names.Gun=<i>"gun"</i></b> | |
+<dd>Sets the word used to describe a single "gun" (for example, it could be | |
+replaced by "knife"). | |
+ | |
+<dt><b>Names.Guns=<i>"guns"</i></b> | |
+<dd>Sets the word used to describe two or more "guns". | |
+ | |
+<dt><b>Names.Drug=<i>"drug"</i></b> | |
+<dd>Sets the word used to describe a single "drug" (for example, it could be | |
+replaced by "candy bar" or something similarly innocuous). | |
+ | |
+<dt><b>Names.Drugs=<i>"drugs"</i></b> | |
+<dd>Sets the word used to describe two or more "drugs". | |
+ | |
+<dt><b>Names.Month=<i>"12-"</i></b> | |
+<dd>Sets the text which is displayed on the client's screen to the immediate | |
+left of the current turn (by default, a "turn" is a day, and so this part | |
+is the month, in displaying the date in MM-DD-YYYY format) | |
+ | |
+<dt><b>Names.Year=<i>"-1984"</i></b> | |
+<dd>Sets the text displayed to the immediate right of the current turn (by | |
+default, the year). | |
+ | |
+<dt><b>Names.Officer=<i>"Hardass"</i></b> | |
+<dd>Sets the name of the first police officer to attack each player to | |
+<i>Hardass</i>. | |
+ | |
+<dt><b>Names.ReserveOfficer=<i>"Bob"</i></b> | |
+<dd>Sets the name of the police officer which attacks the players if they | |
+kill the first one to <i>Bob</i>. | |
+ | |
+<dt><b>Prices.Spy=<i>20000</i></b> | |
+<dd>Sets the price to pay a bitch to spy on another player to be | |
+<i>$20,000</i>. | |
+ | |
+<dt><b>Prices.Tipoff=<i>10000</i></b> | |
+<dd>Sets the price to pay a bitch to tip off the cops to another player to be | |
+<i>$10,000</i>. | |
+ | |
+<dt><b>Bitch.MinPrice=<i>50000</i></b> | |
+<dd>Sets the minimum price for a bitch at the Rough Pub to be <i>$50,000</i>. | |
+Note that prices for bitches "on the street" (i.e. those that are offered | |
+by random events) are produced by dividing the normal bitch price | |
+distribution by 10. | |
+ | |
+<dt><b>Bitch.MaxPrice=<i>150000</i></b> | |
+<dd>Sets the maximum price for a bitch to <i>$150,000</i>. | |
+ | |
+<dt><b>SubwaySaying= <i>{ "First saying", "Second saying", | |
+"Third saying" }</i></b> | |
+<dd>Sets the list of things which the lady you sometimes meet on the subway | |
+says to you; one of <i>"First saying"</i>, <i>"Second saying"</i> and | |
+<i>"Third saying"</i> will be displayed each time. Any previous sayings will | |
+be erased. Note that individual sayings can be overwritten by appending an | |
+array suffix to the variable name - for example, to replace | |
+<i>"Third saying"</i> with <i>"3rd saying"</i> the following command would | |
+suffice:-<br> | |
+<b>SubwaySaying[3]="3rd saying"</b> | |
+ | |
+<dt><b>NumSubwaySaying=<i>5</i></b> | |
+<dd>Sets there to be <i>5</i> distinct things that the lady on the subway | |
+says to you. If this number is greater than the old number of sayings, the | |
+newly added sayings will be blank; if it is smaller, the sayings that are now | |
+beyond the end of the list will be deleted. | |
+ | |
+<dt><b>Playing= <i>{ "Song 1", "Song 2", "Song 3" }</i></b> | |
+<dd>Sets the list of things which you can sometimes hear playing while | |
+jetting; one of <i>"Song 1"</i>, <i>"Song 2"</i> or <i>"Song 3"</i> will be | |
+displayed. See the help for <b>SubwaySaying</b> for more details. | |
+ | |
+<dt><b>NumPlaying=<i>4</i></b> | |
+<dd>Sets there to be <i>4</i> distinct things which you can sometimes hear | |
+playing. | |
+ | |
+<dt><b>StoppedTo= <i>{ "have a beer", "smoke a joint", "smoke a cigar", | |
+"smoke a Djarum", "smoke a cigarette" }</i></b> | |
+<dd>Sets the list of things which you sometimes stop to do while jetting; | |
+see <b>SubwaySaying</b> for more details. | |
+ | |
+<dt><b>NumStoppedTo=<i>5</i></b> | |
+<dd>Sets there to be <i>5</i> distinct things which you can stop to do. | |
+ | |
+</dl> | |
+ | |
+<hr> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>09-09-2000</b> | |
+</body> | |
+</html> | |
diff --git a/doc/credits.html b/doc/credits.html | |
t@@ -0,0 +1,51 @@ | |
+<html> | |
+<head> | |
+<title>Credits and acknowledgements</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>Credits and acknowledgements</h1> | |
+ | |
+dopewars is derived from the MS-DOS game of the same name (author unknown).<p> | |
+ | |
+This is turn was based upon the MS-DOS game "Drug Wars", by John E. Dell.<p> | |
+ | |
+dopewars is written by and is copyright of | |
+<a href="mailto:[email protected]">Ben Webb</a>.<p> | |
+ | |
+Pivotal to the development of dopewars were and are the following:-<p> | |
+ | |
+<b>Dan Wolf</b> for uncountable numbers of useful suggestions for the structure | |
+of the multiplayer game, drawing upon a disturbing knowledge of the drugs | |
+world. He also undertook scary amounts of research (i.e. playing the game) to | |
+assist with the re-engineering of the MS-DOS version, and plays the game to | |
+an unhealthy extent (as is witnessed by his high scores on many dopewars | |
+servers).<p> | |
+ | |
+<b>Phil Davis, Caroline Moore, Katherine Holt</b> and <b>Andrea | |
+Elliot-Smith</b> for extensive play testing of early versions of dopewars, | |
+despite the large amounts of "real" work which they were supposed to be | |
+doing, and despite the many dodgy bugs, as well as for providing | |
+suggestions, even if they were often rude. You know who you are.<p> | |
+ | |
+<b>Owen Walsh</b> and <b>Pete Winn</b> for yet more play testing, and for | |
+consequently doing very little research in vastly more important fields...<p> | |
+ | |
+<b>James Matthews</b> for providing absolutely no useful suggestions, but | |
+providing vital assistance with the Officer Bob code.<p> | |
+ | |
+<b>Mike Meyer</b> for providing several modifications to version 1.4.3, | |
+as well as spotting many of his own and my bugs...<p> | |
+ | |
+<b>Matt Higgins</b> for a couple of patches to version 1.4.4.<p> | |
+ | |
+<b>Tony Brown</b> for assistance with using dopewars via. enforced web | |
+proxies.<p> | |
+ | |
+<hr> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>11-10-99</b> | |
+</body> | |
+</html> | |
diff --git a/doc/developer.html b/doc/developer.html | |
t@@ -0,0 +1,37 @@ | |
+<html> | |
+<head> | |
+<title>Notes for developers</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>Notes for developers</h1> | |
+ | |
+You are free to make whatever changes to the code you wish, as long as you | |
+abide by the terms set out in the <a href="LICENCE">GNU General | |
+Public License</a>. Obviously, I only have a limited amount of time to devote | |
+to dopewars development, and so encourage discussion of the dopewars code, | |
+documentation and concept, and particularly welcome suggested improvements.<p> | |
+ | |
+You are free to distribute modified versions of the code, | |
+again subject to the licence, but I also welcome patches to the code at my | |
+email address, | |
+<a href="mailto:[email protected]">[email protected]</a>. | |
+If I choose to include these patches in a new dopewars version, you will of | |
+course be credited in the changelog (unless, of course, you don't want to | |
+be).<p> | |
+ | |
+For information on the internal workings of the dopewars game code, and | |
+the client-server interface, the best documentation for the budding | |
+developer is the source code itself. I have endeavoured to add sufficient | |
+documentation to the source where necessary; any discussion here of the | |
+internal workings, however, may be incomplete, out of date, and possibly | |
+misleading. Feel free to email me at the address above with questions on this; | |
+I might possibly even know the answers!<p> | |
+ | |
+<hr> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>30-9-99</b> | |
+</body> | |
+</html> | |
diff --git a/doc/example-cfg b/doc/example-cfg | |
t@@ -0,0 +1,42 @@ | |
+# Anything after a '#' symbol on the same line is treated as a comment | |
+# and is ignored | |
+ | |
+/* Multi-line comments are also possible, if this C-style syntax is used to | |
+ denote their starting and finishing points | |
+ N.B. Whitespace (tabs, space characters) is ignored, as are line breaks | |
+ (except for the purpose of terminating '#'-style comments) */ | |
+ | |
+# An example of setting a numerical value | |
+MaxClients= 6 | |
+ | |
+/* An example of setting a string (text) value */ | |
+HiScoreFile= "/var/lib/games/dopewars.sco" | |
+ | |
+# An example of setting a string list value | |
+StoppedTo = { "drink a beer", "visit a friend", | |
+ "smoke a cigar" } | |
+ | |
+StartCash=2000000 # Start each player with $2million | |
+StartDebt=0 | |
+Port=7904 | |
+Pager="less" | |
+NumLocation=6 | |
+Location[1].Name="Oxford" | |
+Location[2].Name="London" | |
+Location[3].Name="Birmingham" | |
+Location[4].Name="Manchester" | |
+Location[5].Name="Edinburgh" | |
+Location[6].Name="Milton Keynes" | |
+ | |
+Drug[1].Name="Smarties" | |
+Drug[1].Cheap=0 | |
+Drug[1].Expensive=1 | |
+Drug[1].MinPrice=5000 | |
+Drug[1].MaxPrice=50000 | |
+ | |
+Gun[2].Name="Uzi 9mm" | |
+Gun[2].Price=500000 | |
+Gun[2].Space=20 | |
+Gun[2].Damage=50 | |
+ | |
+DrugSortMethod=3 | |
diff --git a/doc/i18n.html b/doc/i18n.html | |
t@@ -0,0 +1,101 @@ | |
+<html> | |
+<head> | |
+<title>Internationalization</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>Internationalization</h1> | |
+ | |
+dopewars uses the <a href="http://www.gnu.org/manual/gettext/">GNU gettext</a> | |
+utilities for internationalization (i18n) support. This allows the software | |
+to be translated into the local language at runtime - run dopewars in the UK | |
+and it'll talk to you in English, but run it in Germany and it'll talk to you | |
+in German. This relies on translators to translate the program's output into | |
+each language beforehand, of course, and so native language speakers to carry | |
+out this task are always needed! | |
+ | |
+<h2>Running dopewars with i18n support</h2> | |
+i18n is only included in versions of dopewars later than 1.4.8. By default, | |
+"Native Language Support" is compiled in; binary installations should be | |
+already set up for i18n. When compiling dopewars from source code, the | |
+<tt>configure</tt> script should detect whether your system can support | |
+GNU gettext. If it can, but the gettext utilities themselves are not present, | |
+an included copy in the <tt>intl/</tt> subdirectory is used. To disable i18n, | |
+pass the <tt>--disable-nls</tt> option to the <tt>configure</tt> script.<p> | |
+ | |
+When you run your installed copy of dopewars, it should detect your "locale" | |
+automatically and talk to you in your native language. If this does not happen, | |
+the following are some possible explanations:- | |
+<ul> | |
+<li>dopewars cannot find the locale-specific language file - by default, stored | |
+under /usr/local/share/locale/ | |
+<li>Your language is not yet supported - why not add it yourself? | |
+<li>Your system does not have locale support | |
+<li>You haven't set an environment variable to specify your locale (usually | |
+this is done automatically). For example, if you're using the <tt>bash</tt> | |
+shell and want a German translation, the command "<tt>export LANG=de</tt>" | |
+should fix the problem. | |
+</ul> | |
+ | |
+<h2>Adding a new translation</h2> | |
+Translation files are kept in the subdirectory <tt>po/</tt> of the dopewars | |
+source code distribution. They are named by | |
+<a href="http://userpage.chemie.fu-berlin.de/diverse/doc/ISO_639.html"> | |
+2-letter language codes</a> followed by the <tt>.po</tt> extension - for | |
+example, the German translation is stored in the file <tt>po/de.po</tt>. | |
+They are simple text files, consisting of lists of the original English string | |
+(labelled by "msgid") followed by the translated string (labelled by | |
+"msgstr").<p> | |
+ | |
+Adding a new translation is simply a matter of copying the reference file | |
+<tt>dopewars.pot</tt> to your language-specific <tt>.po</tt> file in the <tt>p… | |
+in the "msgstr" entries. Once this is done, edit the <tt>configure.in</tt> | |
+file in the top dopewars directory to add your language code to the | |
+<tt>ALL_LINGUAS</tt> variable. Then run <tt>autoconf</tt> to rebuild the | |
+<tt>configure</tt> script, before making and installing dopewars as usual. The | |
+new translation should now be available. Once this is complete, please | |
+<a href="mailto:[email protected]">send</a> the translation to be | |
+included in the next dopewars version.<p> | |
+ | |
+Please note that some strings are <b>format strings</b> containing the % | |
+character. These are used in the program code for substituting numbers and | |
+other pieces of text into the string - these substitutions are are performed | |
+using variables which are specified in the <b>same order</b> as the % | |
+characters in the format string. For example, the following format string | |
+substitutes in a string (%s) and an integer number (%d):-<br> | |
+<tt>"String '%s' has %d characters"</tt><br> | |
+The string and number are specified in order in the code. This is problematic | |
+if your translation changes the order - for example, a valid German translation | |
+of the string would be<br> | |
+<tt>"%d Zeichen lang ist die Zeichenkette '%s'"</tt><br> | |
+Now the number and string are specified in the wrong order, and this will | |
+probably crash the program on running! To fix this, use the special notation<b… | |
+<tt>"%2$d Zeichen lang ist die Zeichenkette '%1$s'"</tt><br> | |
+(i.e. replace <b>%x</b> with <b>%n$x</b> where <b>n</b> is the index that the | |
+format specifier "should" have, starting from 1.)<p> | |
+ | |
+<h2>Updating a translation for a new dopewars version</h2> | |
+New versions of dopewars will often change what is printed to the user, and | |
+so may may require changes to the translation. To update an existing | |
+translation, "<tt>make</tt>" the new version of dopewars. This will create | |
+a <tt>dopewars.pot</tt> file listing the strings that need translating. Change | |
+into the <tt>po/</tt> subdirectory, and create a new translation file from | |
+your "old" translation file (we'll assume it's called <tt>de.po</tt>) and | |
+<tt>dopewars.pot</tt> with the <tt>msgmerge</tt> command:-<br> | |
+<tt>msgmerge -o newfile de.po dopewars.pot</tt><br> | |
+Examine this new file <tt>newfile</tt> for translations that need updating | |
+(a search for "fuzzy" should find most of them) and then overwrite your old | |
+translation with the new one:<br> | |
+<tt>mv newfile de.po</tt><br> | |
+Rebuild and reinstall dopewars, and the new translations should become | |
+available. Again, it is deeply appreciated if such updated files are | |
+contributed to the main dopewars distribution!<p> | |
+ | |
+<hr><br> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>09-09-2000</b> | |
+ | |
+</body> | |
+</html> | |
diff --git a/doc/index.html b/doc/index.html | |
t@@ -0,0 +1,54 @@ | |
+<html> | |
+<head> | |
+<title>dopewars 1.4.8: Main Index</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>dopewars 1.4.8: Main Index</h1> | |
+ | |
+<table> | |
+ | |
+<tr> | |
+<td> | |
+<a href="installation.html">Obtaining and installing dopewars</a><br> | |
+<a href="commandline.html">dopewars command line options</a><br> | |
+<a href="clientplay.html">Playing the game: the dopewars client</a><br> | |
+<a href="server.html">Setting up and running a dopewars server</a><br> | |
+<a href="aiplayer.html">Adding computer-controlled players</a><br> | |
+<a href="configfile.html">dopewars configuration files</a><br> | |
+<a href="metaserver.html">The dopewars metaserver</a><br> | |
+<a href="i18n.html">Internationalization (i18n)</a><br> | |
+<a href="windows.html">dopewars and Microsoft Windows</a><br> | |
+<a href="developer.html">Notes for developers</a><br> | |
+<a href="credits.html">Credits and acknowledgements</a><br> | |
+</td> | |
+ | |
+<td> | |
+dopewars is a game simulating the life of a drug dealer in 1984 New York, | |
+based upon the MS-DOS game of the same name, in turn derived from "Drug | |
+Wars" by John E. Dell. The aim of the game is to make lots and lots of | |
+money, but unfortunately you start the game with a hefty debt to the loan | |
+shark (who charges equally hefty interest) and the cops take a rather dim | |
+view of drug dealing...<p> | |
+ | |
+dopewars expands upon the MS-DOS version by introducing multiplayer | |
+functions. With the aid of dopewars servers, several players (computer or | |
+human) can roam New York (or some other city, chosen by the operator of the | |
+server) and attempt to shoot other players and steal their lucrative drugs.<p> | |
+ | |
+dopewars is written on the RedHat Linux platform, and should run on most | |
+varieties of Unix, as well as under Microsoft Windows. The source code is | |
+freely available under the <a href="LICENCE">GNU General Public License</a>.<p> | |
+ | |
+For more information on the current state of dopewars, check out the | |
+<a href="http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/">webpage</a>.<p> | |
+</td> | |
+ | |
+</tr> | |
+</table> | |
+ | |
+<p> | |
+<hr> | |
+Last update: <b>09-09-2000</b> | |
+</body> | |
+</html> | |
diff --git a/doc/installation.html b/doc/installation.html | |
t@@ -0,0 +1,119 @@ | |
+<html> | |
+<head> | |
+<title>Obtaining and installing dopewars</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>Obtaining and installing dopewars</h1> | |
+ | |
+The dopewars source code and precompiled binaries for Intel and Alpha | |
+systems (in RPM format) are available from the main dopewars web page, | |
+at <a href="http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/"> | |
+http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/</a>. Just follow the link from | |
+there to the download section. "rpm" is the RedHat Package Manager, a program | |
+for simplifying installation and upgrade of programs, and is part of the | |
+RedHat Linux distribution. If you are using a different distribution, it | |
+may be still be included, however. If you do not want to use "rpm", or the | |
+installation fails, then you can obtain the source code tarball and recompile | |
+the code from scratch.<p> | |
+ | |
+<b>Prerequisites:</b> dopewars relies on the screen library curses (or the | |
+equivalent, such as ncurses or cur_colr) but otherwise aims to be usable | |
+without modification on a wide variety of Unix variants. The | |
+<a href="#tarball">tarball</a> can also be compiled using the freely | |
+available <a href="http://sourceware.cygnus.com/cygwin/">Cygwin</a> suite for | |
+Win32 systems, to yield a Windows binary. dopewars is developed and tested on | |
+RedHat Linux systems.<p> | |
+ | |
+<ul> | |
+<li><a href="#rpmbinary">RPM binary installation</a> | |
+<li><a href="#rpmsource">RPM source installation</a> | |
+<li><a href="#tarball">Tarball installation</a> | |
+</ul> | |
+ | |
+<a name="rpmbinary"><h2>RPM binary installation</h2></a> | |
+The binary RPMs are built for Compaq (formerly DEC) Alpha systems running | |
+RedHat Linux 6.2, and Intel (also Intel compatibles, such as AMD, Cyrix, etc.) | |
+systems running RedHat Linux 6.2. On other systems, these binary RPMs may | |
+refuse to install, or may run but then crash with mysterious segmentation | |
+faults due to library conflicts. | |
+ | |
+<ol> | |
+<li>Download the | |
+<a href="http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/dopewars-1.4.8-1.alpha.rp… | |
+Alpha</a> or | |
+<a href="http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/dopewars-1.4.8-1.i386.rpm… | |
+i386 (Intel)</a> RPM with your web browser. (If your browser is incorrectly set | |
+up, it may try and display the file, in which case tell it explicitly to save | |
+the file - Shift+Mouse button 1 in Netscape.) | |
+<li>Become root on your Unix box (if you cannot become root, then you will | |
+probably not be able to use RPM installation, depending on how "rpm" is set | |
+up). | |
+<li>Change to the directory containing the dopewars rpm, and install it with | |
+the command <br> | |
+<b>rpm -i dopewars-1.4.8-1.<i>xxx</i>.rpm</b><br> | |
+(where <b><i>xxx</i></b> is i386 or alpha). If you have a previous version | |
+of dopewars installed, upgrade it instead with<br> | |
+<b>rpm -U dopewars-1.4.8-1.<i>xxx</i>.rpm</b> | |
+</ol> | |
+ | |
+<a name="rpmsource"><h2>RPM source installation</h2></a> | |
+This route is open to you if your system has "rpm", but the binary RPMs do | |
+not work on your system, or your machine is not an Intel or Alpha (a PowerMac, | |
+for example). It involves obtaining the RPM of the source code, and then | |
+building the binaries from it on your system. | |
+ | |
+<ol> | |
+<li>Download the <a href="http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/dopewars… | |
+<li>Become root and change to the directory containing the new rpm. | |
+<li>Build a binary rpm with the command<br> | |
+<b>rpm --rebuild dopewars-1.4.8-1.src.rpm</b> | |
+<li>Change to the directory which the binary rpm has been written to (check | |
+the output of the above - usually /usr/src/redhat/RPMS/<i>xxx</i>, where | |
+<i>xxx</i> is your machine type - for example, "i386" on Intel machines, | |
+"alpha" on Alphas) | |
+<li>Install the binary rpm with the command<br> | |
+<b>rpm -i dopewars-1.4.8-1.<i>xxx</i>.rpm</b><br> | |
+or upgrade an existing version with<br> | |
+<b>rpm -U dopewars-1.4.8-1.<i>xxx</i>.rpm</b><br> | |
+</ol> | |
+ | |
+<a name="tarball"><h2>Tarball installation</h2></a> | |
+If you don't have, or don't want to use, RPM, you can obtain the source code in | |
+gzipped, tarred ("tarball") format and recompile and install it yourself. This | |
+is also usually a necessity if you cannot become root (the superuser) on your | |
+Unix box. | |
+ | |
+<ol> | |
+<li>Download the <a href="http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/dopewars… | |
+<li>Change to the directory containing the tarball and extract the contents | |
+with the command <br> | |
+<b>tar -xvzf dopewars-1.4.8.tar.gz</b><br> | |
+(or similar). | |
+<li>Change into the dopewars-1.4.8 directory, and read all the important | |
+documentation in there ;) | |
+<li>Build the binary with the commands<br> | |
+<b>./configure</b><br> | |
+<b>make</b> | |
+<li>Become root and install the dopewars files with<br> | |
+<b>make install</b><br> | |
+The configure script will test your system and set up dopewars so that it | |
+should compile cleanly. If you are running the Cygwin tools under Microsoft | |
+Windows, the script should detect this and allow you to build a native | |
+Windows binary; this will then run on any Win32 system, even one without Cygwin | |
+installed. The configure script supports a number of configurable options; for | |
+more details, read the INSTALL file in the dopewars-1.4.8 directory.<p> | |
+ | |
+If you cannot become root, run the configure script specifying directories for | |
+which you have write access for both the dopewars binary and high score file | |
+with a command such as<br> | |
+<b>./configure --bindir=/home/user/dopewars --datadir=/home/user/dopewars</b> | |
+</ol> | |
+ | |
+<hr> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>09-07-2000</b> | |
+</body> | |
+</html> | |
diff --git a/doc/metaserver.html b/doc/metaserver.html | |
t@@ -0,0 +1,118 @@ | |
+<html> | |
+<head> | |
+<title>The dopewars metaserver</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>The dopewars metaserver</h1> | |
+ | |
+Every dopewars <a href="server.html">server</a> is different, due to their | |
+differing locations and configurations. Thus some centralised system for | |
+listing the currently available servers and displaying some sort of comment | |
+about the games running on them is necessary, to enable client players to | |
+pick the game that most suits them. This is the function of the dopewars | |
+<b>metaserver</b>.<p> | |
+ | |
+<ul> | |
+<li><a href="#location">Metaserver location</a> | |
+<li><a href="#client">Using the metaserver from the client</a> | |
+<li><a href="#server">Using the metaserver from the server</a> | |
+<ul> | |
+<li><a href="#wrongip">But it's displaying the wrong IP address!</a> | |
+<li><a href="#dynamicip">But my server has a dynamic IP...</a> | |
+</ul> | |
+</ul> | |
+ | |
+<a name="location"><h2>Metaserver location</h2></a> | |
+The metaserver has a CGI (web) interface for humans and dopewars clients to | |
+read from, and a UDP interface for servers to report to. It lives at the | |
+same place as the <a href="http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/"> | |
+main dopewars page</a>; the CGI interface listens on TCP port 80, and the | |
+UDP interface on port 7802. These are the default settings which all | |
+dopewars servers and clients use for metaserver communication.<p> | |
+ | |
+<a name="client"><h2>Using the metaserver from the client</h2></a> | |
+Players who want to use the metaserver to list the currently available | |
+servers should go to | |
+<a href="http://bellatrix.pcl.ox.ac.uk/~ben/cgi-bin/serverlist.pl">this | |
+link</a>, or just follow the "Servers" link from the main dopewars web page. | |
+It cannot be guaranteed that all the listed servers are functional - they | |
+may, for example, have been registered in error, or a server may have crashed | |
+since being added to the list - but the list is checked daily for service, | |
+and so there is at least a good chance that the servers listed there will | |
+be working.<p> | |
+ | |
+The metaserver, being a collection of CGI scripts, should work happily on | |
+most machines which have web access. A problem occurs, however, if your | |
+connection to the Web is via. an enforced proxy server (i.e. traffic on | |
+port 80 from your machine is blocked by firewall). dopewars can be | |
+configured to connect via. a proxy server without too much difficulty; if | |
+your proxy server is at <i>proxy.com</i> on port <i>8080</i> then you should | |
+add the following lines to your dopewars <a href="configfile.html"> | |
+configuration file</a>:-<br> | |
+<b>MetaServer.Name=proxy.com<br> | |
+MetaServer.Port=8080<br> | |
+MetaServer.Path=http://bellatrix.pcl.ox.ac.uk/~ben/cgi-bin/server.pl</b><p> | |
+ | |
+<a name="server"><h2>Using the metaserver from the server</h2></a> | |
+People running servers who <b>do not</b> want their details listed by the | |
+metaserver should disable the metaserver comunication of the server with | |
+the <a href="configfile.html#MetaServerActive">MetaServer.Active=0</a> | |
+configuration file setting, or the <b>-S</b> | |
+<a href="commandline.html#privateserver">command line option</a>. Servers | |
+which <b>do</b> register their details can have their accompanying comment | |
+set with the <a href="configfile.html#MetaServerComment"> | |
+MetaServer.Comment</a> configuration file setting.<p> | |
+ | |
+Each dopewars server notifies the metaserver of its current status, and | |
+sends this data on startup and shutdown, and when players leave or join the | |
+game. See the <a href="server.html">server page</a> for more details.<p> | |
+ | |
+<a name="wrongip"><h3>But it's displaying the wrong IP address!</h3></a> | |
+Once connected to the metaserver, you may find that it incorrectly | |
+displays the domain name of your server machine. This is usually because the | |
+metaserver cannot resolve your IP address to a domain name.<p> | |
+ | |
+In this case, you will need to override the hostname that the metaserver | |
+guesses for your machine with one you choose yourself. This is done by | |
+specifying the hostname with the MetaServer.LocalName variable in your dopewars | |
+<a href="configfile.html">configuration file</a>. In order to prevent abuse | |
+of this facility, you must obtain a password from the metaserver maintainer to | |
+authenticate your chosen hostname. | |
+<a href="mailto:[email protected]">Email</a> the maintainer, giving | |
+the exact hostname you want to use (be aware that this is case-sensitive) and | |
+you will be given a password. Specify this password with the MetaServer.Passwo… | |
+variable in the dopewars configuration file.<p> | |
+ | |
+For example, if you wish your server to be known as <b>dope-serv.com</b> and | |
+you have emailed the maintainer, receiving the password <b>Dope-Auth</b>, then | |
+add the following to the dopewars configuration file:-<br> | |
+<b>MetaServer.LocalName=dope-serv.com<br> | |
+MetaServer.Password=Dope-Auth</b><p> | |
+ | |
+Restart your dopewars server, or send it a SIGUSR1 signal, for the change to | |
+take effect. Bear in mind that if you make up a non-existent or invalid domain | |
+name, the metaserver will accept it, but the server will be removed from the | |
+metaserver's list when it is checked daily for service.<p> | |
+ | |
+<a name="dynamicip"><h3>But my server has a dynamic IP...</h3></a> | |
+Finally, your server's IP may be resolved happily, but you may have a connecti… | |
+to the internet which assigns you a dynamic IP. Consider what happens if your | |
+connection is broken before the dopewars server exits; the metaserver will | |
+list the IP of the "old" server, and you will now have no way of removing that | |
+entry when your connection comes back up, as your IP will be different. In | |
+this case, you can <a href="mailto:[email protected]">email</a> the | |
+metaserver maintainer, and specify a blank MetaServer.LocalName variable. | |
+You will again receive a MetaServer.Password variable (see | |
+<a href="#wrongip">above</a>), which the metaserver | |
+will use to identify "your" server; now, when your internet connection is | |
+restored, the server registration with the "new" IP will automatically replace | |
+the "old" one. | |
+ | |
+<hr> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>09-07-2000</b> | |
+</body> | |
+</html> | |
diff --git a/doc/server.html b/doc/server.html | |
t@@ -0,0 +1,90 @@ | |
+<html> | |
+<head> | |
+<title>Setting up and running a dopewars server</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>Setting up and running a dopewars server</h1> | |
+ | |
+Multiplayer games of dopewars require a running dopewars server; this mediates | |
+the interactions between each player (each player runs a | |
+<a href="clientplay.html">client</a> which connects to this server). The server | |
+runs the game, generating drug prices and the like, and instructs the clients | |
+accordingly. The server can be run on any machine that can be reached over | |
+the network by clients (so you don't have to run it on the same machine that | |
+you run your client on, for example, unless your firewall blocks the dopewars | |
+port).<p> | |
+ | |
+Single player games do not require a server (although you can still connect | |
+to one if you like) as a "virtual server" is run by the dopewars client.<p> | |
+ | |
+The dopewars server can be heavily customised by means of the | |
+<a href="configfile.html">configuration files</a>. For example, you can | |
+change the names of all the game locations so that the game is set in your | |
+home city rather than New York. Any players that then connect to your | |
+customised server will play this customised game.<p> | |
+ | |
+<ul> | |
+<li><a href="#interactive">Running an interactive server</a> | |
+<li><a href="#noninteractive">Non-interactive servers</a> | |
+<li><a href="#metaserver">Private and public: the dopewars metaserver</a> | |
+</ul> | |
+ | |
+<a name="interactive"><h2>Running an interactive server</h2></a> | |
+ | |
+All the code for the dopewars server is included in the same binary as the | |
+standard client. To run the binary in server mode, specify the <b>-s</b> or | |
+<b>-S</b> <a href="commandline.html">command line option</a>. By default, | |
+this runs the server in "interactive" mode; that is to say that the server | |
+functions as normal, but in addition responds to typed commands from you. | |
+Click <a href="servercommands.html">here</a> for a list of the valid commands | |
+in interactive mode.<p> | |
+ | |
+<a name="noninteractive"><h2>Non-interactive servers</h2></a> | |
+ | |
+Usually, however, you will not need to use server commands (most can be | |
+specified in the <a href="configfile.html">configuration files</a> anyway) | |
+and so will want a non-interactive server. This will sit in the background | |
+and quietly deal with dopewars games without disturbing you, the user. To | |
+"persuade" the server to be non-interactive, you must redirect standard | |
+input and output, and use your shell's job control to put it in the background, | |
+with a command similar to the following:-<br> | |
+<b>dopewars -s < /dev/null >> /var/log/dopewars.log &</b><br> | |
+(this writes server output to the logfile <i>/var/log/dopewars.log</i>. | |
+Alternatively you can redirect this output to <i>/dev/null</i>.)<p> | |
+ | |
+<a name="metaserver"><h2>Private and public: the dopewars metaserver</h2></a> | |
+ | |
+By default, a server reports its status to the dopewars | |
+<a href="metaserver.html">metaserver</a>. It does this on startup and | |
+shutdown, and whenever players join or leave the game. In addition, you | |
+can force a report (under Unix systems) by sending the dopewars server | |
+process a SIGUSR1 signal. The server will "remind" the metaserver that it | |
+exists by ensuring that a report is sent at least once every 20 minutes or so, | |
+regardless. A "status report" comprises contact details for the server, | |
+a count of the number of active players, and current high scores.<p> | |
+ | |
+The metaserver also has a web interface, which is used by dopewars clients to | |
+obtain the list of servers, and can also be viewed with a web browser | |
+<a href="http://bellatrix.pcl.ox.ac.uk/~ben/cgi-bin/serverlist.pl">here</a>.<p> | |
+ | |
+Whether your server connects to the metaserver can be configured with the | |
+<a href="configfile.html#MetaServerActive">MetaServer.Active</a> configuration | |
+file setting, or the <b>-s</b> and <b>-S</b> <a href="commandline.html"> | |
+command line options</a>.<p> | |
+ | |
+N.B. Your machine may have trouble connecting with | |
+the metaserver in some circumstances, most notably if you are using an | |
+enforced proxy server or your DNS does not correctly resolve your IP address | |
+to your domain name. In such cases, you may be unable to connect to the | |
+metaserver, or it may register your server with an incorrect name. For | |
+information on getting round these difficulties, see the | |
+<a href="metaserver.html">metaserver</a> page. | |
+ | |
+<hr> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>09-07-2000</b> | |
+</body> | |
+</html> | |
diff --git a/doc/servercommands.html b/doc/servercommands.html | |
t@@ -0,0 +1,57 @@ | |
+<html> | |
+<head> | |
+<title>Interactive server commands</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>Interactive server commands</h1> | |
+ | |
+Available commands are listed below. Please note also that any valid | |
+line from a <a href="configfile.html">configuration file</a> can | |
+be entered at the interactive server's prompt. Note, however, that game | |
+options cannot be changed while players are connected. In addition, the | |
+current value of any option from the configuration files can be displayed | |
+by typing the name of the variable by itself. For example, entering | |
+<i>MetaServer.Comment</i> at the prompt will display the comment that the | |
+server sends to the <a href="metaserver.html">metaserver</a>. | |
+ | |
+<dl> | |
+<dt><b>help</b> | |
+<dd>Displays a help screen, listing valid server commands and the variables | |
+which can be set in <a href="configfile.html">configuration files</a>. | |
+ | |
+<dt><b>list</b> | |
+<dd>Lists the given names of all the players currently logged on to the | |
+server. | |
+ | |
+<dt><b>push <i>Bert</i></b> | |
+<dd>Politely asks the player with the given name <i>Bert</i> to leave the | |
+server - i.e. sends a message to the client, which should then finish off | |
+and break the connection at the far end. | |
+ | |
+<dt><b>kill <i>Bert</i></b> | |
+<dd>Abruptly breaks the connection to the player with given name <i>Bert</i>. | |
+This is necessary if, for example, the client refuses to acknowledge a | |
+"push" message. | |
+ | |
+<dt><b>msg:<i>Hi all!</i></b> | |
+<dd>Broadcasts the message <i>Hi all!</i> to all players currently connected | |
+to this server. | |
+ | |
+<dt><b>quit</b> | |
+<dd>Politely quit, by asking all clients to leave, and then terminating once | |
+they have done so. An "impolite" quit, which is necessary if the clients fail | |
+to respond to this message, is performed on receipt of a SIGINT or SIGTERM | |
+signal (i.e. pressing Ctrl-C or killing the process with the "kill" command). | |
+</dl> | |
+ | |
+<hr> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+<ul> | |
+<li><a href="server.html">Setting up and running a dopewars server</a> | |
+</ul> | |
+</ul> | |
+Last update: <b>28-9-99</b> | |
+</body> | |
+</html> | |
diff --git a/doc/windows.html b/doc/windows.html | |
t@@ -0,0 +1,44 @@ | |
+<html> | |
+<head> | |
+<title>dopewars and Microsoft Windows</title> | |
+</head> | |
+ | |
+<body> | |
+<h1>dopewars and Microsoft Windows</h1> | |
+ | |
+dopewars now runs natively on Win32 systems (95, 98, NT). It runs as a console | |
+application, so if you want a pretty pointy-clicky dopewars client, you'll have | |
+to write your own - but feel free to | |
+<a href="mailto:[email protected]">email me</a> if you want to tackle | |
+such a project!<p> | |
+ | |
+Binaries can be obtained from the main | |
+<a href="http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/download.html">download | |
+site</a>, or dopewars will compile with the free | |
+<a href="http://sourceware.cygnus.com/cygwin/">Cygwin</a> tools under Win32. | |
+The installation procedure is the same as <a href="installation.html">that for | |
+Unix systems</a> - download the tarball, extract the files, change into the | |
+created directory, run the <b>configure</b> script, and then <b>make</b>. This | |
+builds a native Win32 binary, which does not need the Cygwin libraries to | |
+run.<p> | |
+ | |
+In virtually all respects, the Unix and Win32 versions of dopewars should be | |
+identical. Both will accept the same command line parameters and configuration | |
+options. Be aware that unless you change the directories with configure before | |
+you build, however, the Win32 port will attempt to locate the high score file | |
+in its standard Unix location, which will almost certainly fail to be found on… | |
+Windows machine. The dopewars configuration file will still be read from | |
+$HOME/.dopewars or /etc/dopewars, so one can still be used under Windows by | |
+creating a file "C:\etc\dopewars" (or similar - but take care that Windows | |
+doesn't helpfully add a ".txt" extension to it for you; create it from a DOS | |
+prompt to be sure) or by setting the environment variable HOME to a sensible | |
+directory and placing a configuration file ".dopewars" within that directory.<… | |
+ | |
+<hr><br> | |
+<ul> | |
+<li><a href="index.html">Main index</a> | |
+</ul> | |
+Last update: <b>09-07-2000</b> | |
+ | |
+</body> | |
+</html> | |
diff --git a/install-sh b/install-sh | |
t@@ -0,0 +1,251 @@ | |
+#!/bin/sh | |
+# | |
+# install - install a program, script, or datafile | |
+# This comes from X11R5 (mit/util/scripts/install.sh). | |
+# | |
+# Copyright 1991 by the Massachusetts Institute of Technology | |
+# | |
+# Permission to use, copy, modify, distribute, and sell this software and its | |
+# documentation for any purpose is hereby granted without fee, provided that | |
+# the above copyright notice appear in all copies and that both that | |
+# copyright notice and this permission notice appear in supporting | |
+# documentation, and that the name of M.I.T. not be used in advertising or | |
+# publicity pertaining to distribution of the software without specific, | |
+# written prior permission. M.I.T. makes no representations about the | |
+# suitability of this software for any purpose. It is provided "as is" | |
+# without express or implied warranty. | |
+# | |
+# Calling this script install-sh is preferred over install.sh, to prevent | |
+# `make' implicit rules from creating a file called install from it | |
+# when there is no Makefile. | |
+# | |
+# This script is compatible with the BSD install script, but was written | |
+# from scratch. It can only install one file at a time, a restriction | |
+# shared with many OS's install programs. | |
+ | |
+ | |
+# set DOITPROG to echo to test this script | |
+ | |
+# Don't use :- since 4.3BSD and earlier shells don't like it. | |
+doit="${DOITPROG-}" | |
+ | |
+ | |
+# put in absolute paths if you don't have them in your path; or use env. vars. | |
+ | |
+mvprog="${MVPROG-mv}" | |
+cpprog="${CPPROG-cp}" | |
+chmodprog="${CHMODPROG-chmod}" | |
+chownprog="${CHOWNPROG-chown}" | |
+chgrpprog="${CHGRPPROG-chgrp}" | |
+stripprog="${STRIPPROG-strip}" | |
+rmprog="${RMPROG-rm}" | |
+mkdirprog="${MKDIRPROG-mkdir}" | |
+ | |
+transformbasename="" | |
+transform_arg="" | |
+instcmd="$mvprog" | |
+chmodcmd="$chmodprog 0755" | |
+chowncmd="" | |
+chgrpcmd="" | |
+stripcmd="" | |
+rmcmd="$rmprog -f" | |
+mvcmd="$mvprog" | |
+src="" | |
+dst="" | |
+dir_arg="" | |
+ | |
+while [ x"$1" != x ]; do | |
+ case $1 in | |
+ -c) instcmd="$cpprog" | |
+ shift | |
+ continue;; | |
+ | |
+ -d) dir_arg=true | |
+ shift | |
+ continue;; | |
+ | |
+ -m) chmodcmd="$chmodprog $2" | |
+ shift | |
+ shift | |
+ continue;; | |
+ | |
+ -o) chowncmd="$chownprog $2" | |
+ shift | |
+ shift | |
+ continue;; | |
+ | |
+ -g) chgrpcmd="$chgrpprog $2" | |
+ shift | |
+ shift | |
+ continue;; | |
+ | |
+ -s) stripcmd="$stripprog" | |
+ shift | |
+ continue;; | |
+ | |
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'` | |
+ shift | |
+ continue;; | |
+ | |
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'` | |
+ shift | |
+ continue;; | |
+ | |
+ *) if [ x"$src" = x ] | |
+ then | |
+ src=$1 | |
+ else | |
+ # this colon is to work around a 386BSD /bin/sh bug | |
+ : | |
+ dst=$1 | |
+ fi | |
+ shift | |
+ continue;; | |
+ esac | |
+done | |
+ | |
+if [ x"$src" = x ] | |
+then | |
+ echo "install: no input file specified" | |
+ exit 1 | |
+else | |
+ true | |
+fi | |
+ | |
+if [ x"$dir_arg" != x ]; then | |
+ dst=$src | |
+ src="" | |
+ | |
+ if [ -d $dst ]; then | |
+ instcmd=: | |
+ chmodcmd="" | |
+ else | |
+ instcmd=mkdir | |
+ fi | |
+else | |
+ | |
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command | |
+# might cause directories to be created, which would be especially bad | |
+# if $src (and thus $dsttmp) contains '*'. | |
+ | |
+ if [ -f $src -o -d $src ] | |
+ then | |
+ true | |
+ else | |
+ echo "install: $src does not exist" | |
+ exit 1 | |
+ fi | |
+ | |
+ if [ x"$dst" = x ] | |
+ then | |
+ echo "install: no destination specified" | |
+ exit 1 | |
+ else | |
+ true | |
+ fi | |
+ | |
+# If destination is a directory, append the input filename; if your system | |
+# does not like double slashes in filenames, you may need to add some logic | |
+ | |
+ if [ -d $dst ] | |
+ then | |
+ dst="$dst"/`basename $src` | |
+ else | |
+ true | |
+ fi | |
+fi | |
+ | |
+## this sed command emulates the dirname command | |
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` | |
+ | |
+# Make sure that the destination directory exists. | |
+# this part is taken from Noah Friedman's mkinstalldirs script | |
+ | |
+# Skip lots of stat calls in the usual case. | |
+if [ ! -d "$dstdir" ]; then | |
+defaultIFS=' | |
+' | |
+IFS="${IFS-${defaultIFS}}" | |
+ | |
+oIFS="${IFS}" | |
+# Some sh's can't handle IFS=/ for some reason. | |
+IFS='%' | |
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` | |
+IFS="${oIFS}" | |
+ | |
+pathcomp='' | |
+ | |
+while [ $# -ne 0 ] ; do | |
+ pathcomp="${pathcomp}${1}" | |
+ shift | |
+ | |
+ if [ ! -d "${pathcomp}" ] ; | |
+ then | |
+ $mkdirprog "${pathcomp}" | |
+ else | |
+ true | |
+ fi | |
+ | |
+ pathcomp="${pathcomp}/" | |
+done | |
+fi | |
+ | |
+if [ x"$dir_arg" != x ] | |
+then | |
+ $doit $instcmd $dst && | |
+ | |
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && | |
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && | |
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && | |
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi | |
+else | |
+ | |
+# If we're going to rename the final executable, determine the name now. | |
+ | |
+ if [ x"$transformarg" = x ] | |
+ then | |
+ dstfile=`basename $dst` | |
+ else | |
+ dstfile=`basename $dst $transformbasename | | |
+ sed $transformarg`$transformbasename | |
+ fi | |
+ | |
+# don't allow the sed command to completely eliminate the filename | |
+ | |
+ if [ x"$dstfile" = x ] | |
+ then | |
+ dstfile=`basename $dst` | |
+ else | |
+ true | |
+ fi | |
+ | |
+# Make a temp file name in the proper directory. | |
+ | |
+ dsttmp=$dstdir/#inst.$$# | |
+ | |
+# Move or copy the file name to the temp name | |
+ | |
+ $doit $instcmd $src $dsttmp && | |
+ | |
+ trap "rm -f ${dsttmp}" 0 && | |
+ | |
+# and set any options; do chmod last to preserve setuid bits | |
+ | |
+# If any of these fail, we abort the whole thing. If we want to | |
+# ignore errors from any of these, just make sure not to ignore | |
+# errors from the above "$doit $instcmd $src $dsttmp" command. | |
+ | |
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && | |
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && | |
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && | |
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && | |
+ | |
+# Now rename the file to the real destination. | |
+ | |
+ $doit $rmcmd -f $dstdir/$dstfile && | |
+ $doit $mvcmd $dsttmp $dstdir/$dstfile | |
+ | |
+fi && | |
+ | |
+ | |
+exit 0 | |
diff --git a/missing b/missing | |
t@@ -0,0 +1,190 @@ | |
+#! /bin/sh | |
+# Common stub for a few missing GNU programs while installing. | |
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc. | |
+# Franc,ois Pinard <[email protected]>, 1996. | |
+ | |
+# 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, 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. | |
+ | |
+if test $# -eq 0; then | |
+ echo 1>&2 "Try \`$0 --help' for more information" | |
+ exit 1 | |
+fi | |
+ | |
+case "$1" in | |
+ | |
+ -h|--h|--he|--hel|--help) | |
+ echo "\ | |
+$0 [OPTION]... PROGRAM [ARGUMENT]... | |
+ | |
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an | |
+error status if there is no known handling for PROGRAM. | |
+ | |
+Options: | |
+ -h, --help display this help and exit | |
+ -v, --version output version information and exit | |
+ | |
+Supported PROGRAM values: | |
+ aclocal touch file \`aclocal.m4' | |
+ autoconf touch file \`configure' | |
+ autoheader touch file \`config.h.in' | |
+ automake touch all \`Makefile.in' files | |
+ bison create \`y.tab.[ch]', if possible, from existing .[ch] | |
+ flex create \`lex.yy.c', if possible, from existing .c | |
+ lex create \`lex.yy.c', if possible, from existing .c | |
+ makeinfo touch the output file | |
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]" | |
+ ;; | |
+ | |
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version) | |
+ echo "missing - GNU libit 0.0" | |
+ ;; | |
+ | |
+ -*) | |
+ echo 1>&2 "$0: Unknown \`$1' option" | |
+ echo 1>&2 "Try \`$0 --help' for more information" | |
+ exit 1 | |
+ ;; | |
+ | |
+ aclocal) | |
+ echo 1>&2 "\ | |
+WARNING: \`$1' is missing on your system. You should only need it if | |
+ you modified \`acinclude.m4' or \`configure.in'. You might want | |
+ to install the \`Automake' and \`Perl' packages. Grab them from | |
+ any GNU archive site." | |
+ touch aclocal.m4 | |
+ ;; | |
+ | |
+ autoconf) | |
+ echo 1>&2 "\ | |
+WARNING: \`$1' is missing on your system. You should only need it if | |
+ you modified \`configure.in'. You might want to install the | |
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU | |
+ archive site." | |
+ touch configure | |
+ ;; | |
+ | |
+ autoheader) | |
+ echo 1>&2 "\ | |
+WARNING: \`$1' is missing on your system. You should only need it if | |
+ you modified \`acconfig.h' or \`configure.in'. You might want | |
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them | |
+ from any GNU archive site." | |
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` | |
+ test -z "$files" && files="config.h" | |
+ touch_files= | |
+ for f in $files; do | |
+ case "$f" in | |
+ *:*) touch_files="$touch_files "`echo "$f" | | |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;; | |
+ *) touch_files="$touch_files $f.in";; | |
+ esac | |
+ done | |
+ touch $touch_files | |
+ ;; | |
+ | |
+ automake) | |
+ echo 1>&2 "\ | |
+WARNING: \`$1' is missing on your system. You should only need it if | |
+ you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. | |
+ You might want to install the \`Automake' and \`Perl' packages. | |
+ Grab them from any GNU archive site." | |
+ find . -type f -name Makefile.am -print | | |
+ sed 's/\.am$/.in/' | | |
+ while read f; do touch "$f"; done | |
+ ;; | |
+ | |
+ bison|yacc) | |
+ echo 1>&2 "\ | |
+WARNING: \`$1' is missing on your system. You should only need it if | |
+ you modified a \`.y' file. You may need the \`Bison' package | |
+ in order for those modifications to take effect. You can get | |
+ \`Bison' from any GNU archive site." | |
+ rm -f y.tab.c y.tab.h | |
+ if [ $# -ne 1 ]; then | |
+ eval LASTARG="\${$#}" | |
+ case "$LASTARG" in | |
+ *.y) | |
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` | |
+ if [ -f "$SRCFILE" ]; then | |
+ cp "$SRCFILE" y.tab.c | |
+ fi | |
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` | |
+ if [ -f "$SRCFILE" ]; then | |
+ cp "$SRCFILE" y.tab.h | |
+ fi | |
+ ;; | |
+ esac | |
+ fi | |
+ if [ ! -f y.tab.h ]; then | |
+ echo >y.tab.h | |
+ fi | |
+ if [ ! -f y.tab.c ]; then | |
+ echo 'main() { return 0; }' >y.tab.c | |
+ fi | |
+ ;; | |
+ | |
+ lex|flex) | |
+ echo 1>&2 "\ | |
+WARNING: \`$1' is missing on your system. You should only need it if | |
+ you modified a \`.l' file. You may need the \`Flex' package | |
+ in order for those modifications to take effect. You can get | |
+ \`Flex' from any GNU archive site." | |
+ rm -f lex.yy.c | |
+ if [ $# -ne 1 ]; then | |
+ eval LASTARG="\${$#}" | |
+ case "$LASTARG" in | |
+ *.l) | |
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` | |
+ if [ -f "$SRCFILE" ]; then | |
+ cp "$SRCFILE" lex.yy.c | |
+ fi | |
+ ;; | |
+ esac | |
+ fi | |
+ if [ ! -f lex.yy.c ]; then | |
+ echo 'main() { return 0; }' >lex.yy.c | |
+ fi | |
+ ;; | |
+ | |
+ makeinfo) | |
+ echo 1>&2 "\ | |
+WARNING: \`$1' is missing on your system. You should only need it if | |
+ you modified a \`.texi' or \`.texinfo' file, or any other file | |
+ indirectly affecting the aspect of the manual. The spurious | |
+ call might also be the consequence of using a buggy \`make' (AIX, | |
+ DU, IRIX). You might want to install the \`Texinfo' package or | |
+ the \`GNU make' package. Grab either from any GNU archive site." | |
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` | |
+ if test -z "$file"; then | |
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` | |
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` | |
+ fi | |
+ touch $file | |
+ ;; | |
+ | |
+ *) | |
+ echo 1>&2 "\ | |
+WARNING: \`$1' is needed, and you do not seem to have it handy on your | |
+ system. You might have modified some files without having the | |
+ proper tools for further handling them. Check the \`README' file, | |
+ it often tells you about the needed prerequirements for installing | |
+ this package. You may also peek at any GNU archive site, in case | |
+ some other package would contain this missing \`$1' program." | |
+ exit 1 | |
+ ;; | |
+esac | |
+ | |
+exit 0 | |
diff --git a/mkinstalldirs b/mkinstalldirs | |
t@@ -0,0 +1,40 @@ | |
+#! /bin/sh | |
+# mkinstalldirs --- make directory hierarchy | |
+# Author: Noah Friedman <[email protected]> | |
+# Created: 1993-05-16 | |
+# Public domain | |
+ | |
+# $Id$ | |
+ | |
+errstatus=0 | |
+ | |
+for file | |
+do | |
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` | |
+ shift | |
+ | |
+ pathcomp= | |
+ for d | |
+ do | |
+ pathcomp="$pathcomp$d" | |
+ case "$pathcomp" in | |
+ -* ) pathcomp=./$pathcomp ;; | |
+ esac | |
+ | |
+ if test ! -d "$pathcomp"; then | |
+ echo "mkdir $pathcomp" | |
+ | |
+ mkdir "$pathcomp" || lasterr=$? | |
+ | |
+ if test ! -d "$pathcomp"; then | |
+ errstatus=$lasterr | |
+ fi | |
+ fi | |
+ | |
+ pathcomp="$pathcomp/" | |
+ done | |
+done | |
+ | |
+exit $errstatus | |
+ | |
+# mkinstalldirs ends here | |
diff --git a/po/POTFILES.in b/po/POTFILES.in | |
t@@ -0,0 +1,10 @@ | |
+# List of source files containing translatable strings | |
+ | |
+src/dopewars.c | |
+src/dopeos.c | |
+src/curses_client.c | |
+src/gtk_client.c | |
+src/win32_client.c | |
+src/serverside.c | |
+src/message.c | |
+src/AIPlayer.c | |
diff --git a/po/cat-id-tbl.c b/po/cat-id-tbl.c | |
t@@ -0,0 +1,727 @@ | |
+/* Automatically generated by po2tbl.sed from dopewars.pot. */ | |
+ | |
+#if HAVE_CONFIG_H | |
+# include <config.h> | |
+#endif | |
+ | |
+#include "libgettext.h" | |
+ | |
+const struct _msg_ent _msg_tbl[] = { | |
+ {"", 1}, | |
+ {"bitch", 2}, | |
+ {"bitches", 3}, | |
+ {"gun", 4}, | |
+ {"guns", 5}, | |
+ {"drug", 6}, | |
+ {"drugs", 7}, | |
+ {"12-", 8}, | |
+ {"-1984", 9}, | |
+ {"Hardass", 10}, | |
+ {"Bob", 11}, | |
+ {"the Loan Shark", 12}, | |
+ {"the Bank", 13}, | |
+ {"Dan's House of Guns", 14}, | |
+ {"the pub", 15}, | |
+ {"Network port to connect to", 16}, | |
+ {"Name of the high score file", 17}, | |
+ {"Name of the server to connect to", 18}, | |
+ {"Non-zero if server should report to a metaserver", 19}, | |
+ {"Port for metaserver communication (client)", 20}, | |
+ {"Port for metaserver communication (server)", 21}, | |
+ {"Metaserver name to report server details to", 22}, | |
+ {"Path of the CGI script on the metaserver (client)", 23}, | |
+ {"Preferred hostname of your server machine", 24}, | |
+ {"Authentication for LocalName with the metaserver", 25}, | |
+ {"Server description, reported to the metaserver", 26}, | |
+ {"Program used to display multi-page output", 27}, | |
+ {"No. of game turns (if 0, game never ends)", 28}, | |
+ {"Random events are sanitized", 29}, | |
+ {"Be verbose in processing config file", 30}, | |
+ {"Number of locations in the game", 31}, | |
+ {"Number of guns in the game", 32}, | |
+ {"Number of drugs in the game", 33}, | |
+ {"Location of the Loan Shark", 34}, | |
+ {"Location of the bank", 35}, | |
+ {"Location of the gun shop", 36}, | |
+ {"Location of the pub", 37}, | |
+ {"Name of the loan shark", 38}, | |
+ {"Name of the bank", 39}, | |
+ {"Name of the gun shop", 40}, | |
+ {"Name of the pub", 41}, | |
+ {"Sort key for listing available drugs", 42}, | |
+ {"No. of seconds in which to return fire", 43}, | |
+ {"Players are disconnected after this many seconds", 44}, | |
+ {"Time in seconds for connections to be made or broken", 45}, | |
+ {"Maximum number of TCP/IP connections", 46}, | |
+ {"Seconds between turns of AI players", 47}, | |
+ {"Amount of cash that each player starts with", 48}, | |
+ {"Amount of debt that each player starts with", 49}, | |
+ {"Name of each location", 50}, | |
+ {"Police presence at each location (%)", 51}, | |
+ {"Minimum number of drugs at each location", 52}, | |
+ {"Maximum number of drugs at each location", 53}, | |
+ {"Name of each drug", 54}, | |
+ {"Minimum normal price of each drug", 55}, | |
+ {"Maximum normal price of each drug", 56}, | |
+ {"Non-zero if this drug can be specially cheap", 57}, | |
+ {"Non-zero if this drug can be specially expensive", 58}, | |
+ {"Message displayed when this drug is specially cheap", 59}, | |
+ {"Format string used for expensive drugs 50% of time", 60}, | |
+ {"Divider for drug price when it's specially cheap", 61}, | |
+ {"Multiplier for specially expensive drug prices", 62}, | |
+ {"Name of each gun", 63}, | |
+ {"Price of each gun", 64}, | |
+ {"Space taken by each gun", 65}, | |
+ {"Damage done by each gun", 66}, | |
+ {"% probability of escaping from Officer Hardass", 67}, | |
+ {"Modifier to EscapeProb for each extra deputy", 68}, | |
+ {"% probability that Officer Hardass hits you", 69}, | |
+ {"Modifier to HitProb for each extra deputy", 70}, | |
+ {"Maximum damage done to you by each cop", 71}, | |
+ {"Toughness of (difficulty of hitting) each cop", 72}, | |
+ {"% probability that the cops catch you dropping drugs", 73}, | |
+ {"Word used to denote a single \"bitch\"", 74}, | |
+ {"Word used to denote two or more \"bitches\"", 75}, | |
+ {"Word used to denote a single gun or equivalent", 76}, | |
+ {"Word used to denote two or more guns", 77}, | |
+ {"Word used to denote a single drug or equivalent", 78}, | |
+ {"Word used to denote two or more drugs", 79}, | |
+ {"Text prefixed to the turn number (i.e. the month)", 80}, | |
+ {"Text appended to the turn number (i.e. the year)", 81}, | |
+ {"Name of the police officer", 82}, | |
+ {"Name of the reserve police officer", 83}, | |
+ {"Cost for a bitch to spy on the enemy", 84}, | |
+ {"Cost for a bitch to tipoff the cops to an enemy", 85}, | |
+ {"Minimum price to hire a bitch", 86}, | |
+ {"Maximum price to hire a bitch", 87}, | |
+ {"List of things which you overhear on the subway", 88}, | |
+ {"Number of subway sayings", 89}, | |
+ {"List of songs which you can hear playing", 90}, | |
+ {"Number of playing songs", 91}, | |
+ {"List of things which you can stop to do", 92}, | |
+ {"Number of things which you can stop to do", 93}, | |
+ {"escaped", 94}, | |
+ {"defected", 95}, | |
+ {"was shot", 96}, | |
+ {"`Are you Experienced` by Jimi Hendrix", 97}, | |
+ {"`Cheeba Cheeba` by Tone Loc", 98}, | |
+ {"`Comin` in to Los Angeles` by Arlo Guthrie", 99}, | |
+ {"`Commercial` by Spanky and Our Gang", 100}, | |
+ {"`Late in the Evening` by Paul Simon", 101}, | |
+ {"`Light Up` by Styx", 102}, | |
+ {"`Mexico` by Jefferson Airplane", 103}, | |
+ {"`One toke over the line` by Brewer & Shipley", 104}, | |
+ {"`The Smokeout` by Shel Silverstein", 105}, | |
+ {"`White Rabbit` by Jefferson Airplane", 106}, | |
+ {"`Itchycoo Park` by Small Faces", 107}, | |
+ {"`White Punks on Dope` by the Tubes", 108}, | |
+ {"`Legend of a Mind` by the Moody Blues", 109}, | |
+ {"`Eight Miles High` by the Byrds", 110}, | |
+ {"`Acapulco Gold` by Riders of the Purple Sage", 111}, | |
+ {"`Kicks` by Paul Revere & the Raiders", 112}, | |
+ {"the Nixon tapes", 113}, | |
+ {"`Legalize It` by Mojo Nixon & Skid Roper", 114}, | |
+ {"have a beer", 115}, | |
+ {"smoke a joint", 116}, | |
+ {"smoke a cigar", 117}, | |
+ {"smoke a Djarum", 118}, | |
+ {"smoke a cigarette", 119}, | |
+ {"Baretta", 120}, | |
+ {".38 Special", 121}, | |
+ {"Ruger", 122}, | |
+ {"Saturday Night Special", 123}, | |
+ {"Bronx", 124}, | |
+ {"Ghetto", 125}, | |
+ {"Central Park", 126}, | |
+ {"Manhattan", 127}, | |
+ {"Coney Island", 128}, | |
+ {"Brooklyn", 129}, | |
+ {"Queens", 130}, | |
+ {"Staten Island", 131}, | |
+ {"Acid", 132}, | |
+ {"The market is flooded with cheap home-made acid!", 133}, | |
+ {"Cocaine", 134}, | |
+ {"Hashish", 135}, | |
+ {"The Marrakesh Express has arrived!", 136}, | |
+ {"Heroin", 137}, | |
+ {"Ludes", 138}, | |
+ {"Rival drug dealers raided a pharmacy and are selling cheap ludes!", 139}, | |
+ {"MDA", 140}, | |
+ {"Opium", 141}, | |
+ {"PCP", 142}, | |
+ {"Peyote", 143}, | |
+ {"Shrooms", 144}, | |
+ {"Speed", 145}, | |
+ {"Weed", 146}, | |
+ {"\ | |
+Columbian freighter dusted the Coast Guard! Weed prices have bottomed out!", 1… | |
+ {"Cops made a big %s bust! Prices are outrageous!", 148}, | |
+ {"Addicts are buying %s at ridiculous prices!", 149}, | |
+ {"Wouldn't it be funny if everyone suddenly quacked at once?", 150}, | |
+ {"The Pope was once Jewish, you know", 151}, | |
+ {"I'll bet you have some really interesting dreams", 152}, | |
+ {"So I think I'm going to Amsterdam this year", 153}, | |
+ {"Son, you need a yellow haircut", 154}, | |
+ {"I think it's wonderful what they're doing with incense these days", 155}, | |
+ {"I wasn't always a woman, you know", 156}, | |
+ {"Does your mother know you're a dope dealer?", 157}, | |
+ {"Are you high on something?", 158}, | |
+ {"Oh, you must be from California", 159}, | |
+ {"I used to be a hippie, myself", 160}, | |
+ {"There's nothing like having lots of money", 161}, | |
+ {"You look like an aardvark!", 162}, | |
+ {"I don't believe in Ronald Reagan", 163}, | |
+ {"Courage! Bush is a noodle!", 164}, | |
+ {"Haven't I seen you on TV?", 165}, | |
+ {"I think hemorrhoid commercials are really neat!", 166}, | |
+ {"We're winning the war for drugs!", 167}, | |
+ {"A day without dope is like night", 168}, | |
+ {"We only use 20% of our brains, so why not burn out the other 80%", 169}, | |
+ {"I'm soliciting contributions for Zombies for Christ", 170}, | |
+ {"I'd like to sell you an edible poodle", 171}, | |
+ {"Winners don't do drugs... unless they do", 172}, | |
+ {"Kill a cop for Christ!", 173}, | |
+ {"I am the walrus!", 174}, | |
+ {"Jesus loves you more than you will know", 175}, | |
+ {"I feel an unaccountable urge to dye my hair blue", 176}, | |
+ {"Wasn't Jane Fonda wonderful in Barbarella", 177}, | |
+ {"Just say No... well, maybe... ok, what the hell!", 178}, | |
+ {"Would you like a jelly baby?", 179}, | |
+ {"Drugs can be your friend!", 180}, | |
+ {"Unable to process configuration file line", 181}, | |
+ {"\ | |
+Configuration can only be changed interactively when no\n\ | |
+players are logged on. Wait for all players to log off, or remove\n\ | |
+them with the push or kill commands, and try again.", 182}, | |
+ {"Index into %s array should be between 1 and %d", 183}, | |
+ {"%s is %d\n", 184}, | |
+ {"%s is %s\n", 185}, | |
+ {"%s is \"%s\"\n", 186}, | |
+ {"%s[%d] is %s\n", 187}, | |
+ {"%s is { ", 188}, | |
+ {"Resized structure list to %d elements\n", 189}, | |
+ {"\ | |
+Usage: dopewars [OPTION]...\n\ | |
+Drug dealing game based on \"Drug Wars\" by John E. Dell\n\ | |
+ -b \"black and white\" - i.e. do not use pretty colours\n\ | |
+ (by default colours are used where the terminal supports \ | |
+them)\n\ | |
+ -n be boring and don't connect to any available dopewars servers\n\ | |
+ (i.e. single player mode)\n\ | |
+ -a \"antique\" dopewars - keep as closely to the original version \ | |
+as\n\ | |
+ possible (this also disables any networking)\n\ | |
+ -f file specify a file to use as the high score table\n\ | |
+ (by default %s/dopewars.sco is used)\n\ | |
+ -o addr specify a hostname where the server for multiplayer dopewars\n\ | |
+ can be found (in human-readable - e.g. nowhere.com - format)\n\ | |
+ -s run in server mode (note: for a \"non-interactive\" server, \ | |
+simply\n\ | |
+ run as dopewars -s < /dev/null >> logfile & )\n\ | |
+ -S run a \"private\" server (i.e. do not notify the metaserver)\n\ | |
+ -p specify the network port to use (default: 7902)\n\ | |
+ -g file specify the pathname of a dopewars configuration file. This file\n\ | |
+ is read immediately when the -g option is encountered\n\ | |
+ -r file maintain pid file \"file\" while running the server\n\ | |
+ -c create and run a computer player\n\ | |
+ -w force the use of a graphical (windowed) client (GTK+ or Win32)\n\ | |
+ -t force the use of a text-mode client (curses)\n\ | |
+ (by default, a windowed client is used when possible)\n\ | |
+ -h display this help information\n\ | |
+ -v output version information and exit\n\ | |
+\n\ | |
+dopewars is Copyright (C) Ben Webb 1998-2000, and released under the GNU \ | |
+GPL\n\ | |
+Report bugs to the author at [email protected]\n", 190}, | |
+ {"D O P E W A R S", 191}, | |
+ {"\ | |
+Based on John E. Dell's old Drug Wars game, dopewars is a simulation of an", 1… | |
+ {"imaginary drug market. dopewars is an All-American game which features", … | |
+ {"buying, selling, and trying to get past the cops!", 194}, | |
+ {"\ | |
+The first thing you need to do is pay off your debt to the Loan Shark. After",… | |
+ {"\ | |
+that, your goal is to make as much money as possible (and stay alive)! You", 1… | |
+ {"have one month of game time to make your fortune.", 197}, | |
+ {"Copyright (C) 1998-2000 Ben Webb [email protected]", 198}, | |
+ {"Version %s", 199}, | |
+ {"dopewars is released under the GNU General Public Licence", 200}, | |
+ {"Drug Dealing and Research Dan Wolf", 201}, | |
+ {"Play Testing Phil Davis Owen Walsh", 202}, | |
+ {"Extensive Play Testing Katherine Holt Caroline Moore", 203}, | |
+ {"Constructive Criticism Andrea Elliot-Smith Pete Winn", 204}, | |
+ {"Unconstructive Criticism James Matthews", 205}, | |
+ {"For information on the command line options, type dopewars -h at your", 20… | |
+ {"\ | |
+Unix prompt. This will display a help screen, listing the available options.",… | |
+ {"Please enter the hostname and port of a dopewars server:-", 208}, | |
+ {"Hostname: ", 209}, | |
+ {"Port: ", 210}, | |
+ {"No servers listed on metaserver", 211}, | |
+ {"Please wait... attempting to contact metaserver...", 212}, | |
+ {"Connection to metaserver established. Obtaining server list...", 213}, | |
+ {"Server : %s", 214}, | |
+ {"Port : %d", 215}, | |
+ {"Version : %s", 216}, | |
+ {"Players: -unknown- (maximum %d)", 217}, | |
+ {"Players: %d (maximum %d)", 218}, | |
+ {"Up since : %s", 219}, | |
+ {"Comment: %s", 220}, | |
+ {"N>ext server; P>revious server; S>elect this server... ", 221}, | |
+ {"NPS", 222}, | |
+ {"Please wait... attempting to contact dopewars server...", 223}, | |
+ {"Error: %s", 224}, | |
+ {"Could not start multiplayer dopewars", 225}, | |
+ {"Will you... C>onnect to a different host and/or port", 226}, | |
+ {" L>ist the servers on the metaserver, and select one", 227}, | |
+ {" Q>uit (where you can start a server by typing ", 228}, | |
+ {" dopewars -s < /dev/null & )", 229}, | |
+ {" or P>lay single-player ? ", 230}, | |
+ {"CLQP", 231}, | |
+ {"Where to, dude ? ", 232}, | |
+ {"You can't get any cash for the following carried %s :", 233}, | |
+ {"What do you want to drop? ", 234}, | |
+ {"How many do you drop? ", 235}, | |
+ {"What do you wish to buy? ", 236}, | |
+ {"What do you wish to sell? ", 237}, | |
+ {"You can afford %d, and can carry %d. ", 238}, | |
+ {"How many do you buy? ", 239}, | |
+ {"You have %d. ", 240}, | |
+ {"How many do you sell? ", 241}, | |
+ {"Choose an errand to give one of your %s...", 242}, | |
+ {" S>py on another dealer (cost: %s)", 243}, | |
+ {" T>ip off the cops to another dealer (cost: %s)", 244}, | |
+ {" G>et stuffed", 245}, | |
+ {"or C>ontact your spies and receive reports", 246}, | |
+ {"or N>o errand ? ", 247}, | |
+ {"STGCN", 248}, | |
+ {"Whom do you want to spy on? ", 249}, | |
+ {"Whom do you want to tip the cops off to? ", 250}, | |
+ {" Are you sure? ", 251}, | |
+ {"YN", 252}, | |
+ {"Are you sure you want to quit? ", 253}, | |
+ {"New name: ", 254}, | |
+ {"You have been pushed from the server. Reverting to single player mode.", 2… | |
+ {"The server has terminated. Reverting to single player mode.", 256}, | |
+ {"%s joins the game!", 257}, | |
+ {"%s has left the game.", 258}, | |
+ {"%s will now be known as %s.", 259}, | |
+ {"S U B W A Y", 260}, | |
+ {"\ | |
+Unfortunately, somebody else is already using \"your\" name. Please change \ | |
+it.", 261}, | |
+ {"H I G H S C O R E S", 262}, | |
+ {"Will you B>uy, S>ell, or L>eave? ", 263}, | |
+ {"BSL", 264}, | |
+ {"You don't have any %s to sell!", 265}, | |
+ {"You'll need more %s to carry any more %s!", 266}, | |
+ {"You don't have enough space to carry that %s!", 267}, | |
+ {"You don't have enough cash to buy that %s!", 268}, | |
+ {"You don't have any to sell!", 269}, | |
+ {"How much money do you pay back? ", 270}, | |
+ {"You don't have that much money!", 271}, | |
+ {"Do you want to D>eposit money, W>ithdraw money, or L>eave ? ", 272}, | |
+ {"DWL", 273}, | |
+ {"How much money? ", 274}, | |
+ {"There isn't that much money in the bank...", 275}, | |
+ {"Press any key...", 276}, | |
+ {"Messages", 277}, | |
+ {"Stats", 278}, | |
+ {"Cash %17s", 279}, | |
+ {"Health %3d", 280}, | |
+ {"Bank %17s", 281}, | |
+ {"Debt %17s", 282}, | |
+ {"Space %6d", 283}, | |
+ {"%s %3d Space %6d", 284}, | |
+ {"Trenchcoat", 285}, | |
+ {"Spy reports for %s", 286}, | |
+ {"%s...", 287}, | |
+ {"No other players are currently logged on!", 288}, | |
+ {"Players currently logged on:-", 289}, | |
+ {"Hey dude, what's your name? ", 290}, | |
+ {"Hey dude, the prices of %s here are:", 291}, | |
+ {"Will you B>uy", 292}, | |
+ {", S>ell", 293}, | |
+ {", D>rop", 294}, | |
+ {", T>alk, P>age, L>ist", 295}, | |
+ {", G>ive", 296}, | |
+ {", F>ight", 297}, | |
+ {", J>et", 298}, | |
+ {", or Q>uit? ", 299}, | |
+ {"Do you ", 300}, | |
+ {"F>ight, ", 301}, | |
+ {"S>tand, ", 302}, | |
+ {"R>un, ", 303}, | |
+ {"D>eal ", 304}, | |
+ {"Connection to server lost! Reverting to single player mode", 305}, | |
+ {"BSDTPLGFJQ", 306}, | |
+ {"DRFSQ", 307}, | |
+ {"List what? P>layers or S>cores? ", 308}, | |
+ {"PS", 309}, | |
+ {"Whom do you want to page (talk privately to) ? ", 310}, | |
+ {"Talk: ", 311}, | |
+ {"Play again? ", 312}, | |
+ {"\ | |
+No curses client available - rebuild the binary passing the\n\ | |
+--enable-curses-client option to configure, or use a windowed\n\ | |
+client (if available) instead!\n", 313}, | |
+ {"/_Game", 314}, | |
+ {"/Game/_New", 315}, | |
+ {"/Game/_Quit", 316}, | |
+ {"/_Talk", 317}, | |
+ {"/Talk/To _All", 318}, | |
+ {"/Talk/To _Player", 319}, | |
+ {"/_List", 320}, | |
+ {"/List/_Players", 321}, | |
+ {"/List/_Scores", 322}, | |
+ {"/List/_Inventory", 323}, | |
+ {"/_Errands", 324}, | |
+ {"/Errands/_Spy", 325}, | |
+ {"/Errands/_Tipoff", 326}, | |
+ {"/Errands/Sack _Bitch", 327}, | |
+ {"/Errands/_Get spy reports", 328}, | |
+ {"/_Help", 329}, | |
+ {"/Help/_About", 330}, | |
+ {"Warning", 331}, | |
+ {"Message", 332}, | |
+ {"Quit Game", 333}, | |
+ {"Abandon current game?", 334}, | |
+ {"Start new game", 335}, | |
+ {"Inventory", 336}, | |
+ {"Close", 337}, | |
+ {"Connection to server lost - switching to single player mode", 338}, | |
+ {"You have been pushed from the server.", 339}, | |
+ {"The server has terminated.", 340}, | |
+ {"Jetting to %s", 341}, | |
+ {"<main>/Errands/Spy", 342}, | |
+ {"_Spy\t(%s)", 343}, | |
+ {"_Tipoff\t(%s)", 344}, | |
+ {"<main>/Errands/Tipoff", 345}, | |
+ {"High Scores", 346}, | |
+ {"OK", 347}, | |
+ {"Fight", 348}, | |
+ {"_Deal %s", 349}, | |
+ {"_Fight", 350}, | |
+ {"_Stand", 351}, | |
+ {"_Run", 352}, | |
+ {"Jet to location", 353}, | |
+ {"at %s", 354}, | |
+ {"You are currently carrying %d %s", 355}, | |
+ {"Available space: %d", 356}, | |
+ {"You can afford %d", 357}, | |
+ {"Buy", 358}, | |
+ {"Sell", 359}, | |
+ {"Drop", 360}, | |
+ {"%s how many?", 361}, | |
+ {"Cancel", 362}, | |
+ {"You don't have any %s!", 363}, | |
+ {"_Yes", 364}, | |
+ {"_No", 365}, | |
+ {"_Attack", 366}, | |
+ {"_Evade", 367}, | |
+ {"Question", 368}, | |
+ {"<main>/Talk", 369}, | |
+ {"<main>/List", 370}, | |
+ {"<main>/Errands", 371}, | |
+ {"Space", 372}, | |
+ {"Cash", 373}, | |
+ {"Debt", 374}, | |
+ {"Bank", 375}, | |
+ {"Health", 376}, | |
+ {"_Jet!", 377}, | |
+ {"dopewars", 378}, | |
+ {"Drug Dealing and Research", 379}, | |
+ {"Play Testing", 380}, | |
+ {"Extensive Play Testing", 381}, | |
+ {"Constructive Criticism", 382}, | |
+ {"Unconstructive Criticism", 383}, | |
+ {"About dopewars", 384}, | |
+ {"\ | |
+Based on John E. Dell's old Drug Wars game, dopewars is a simulation of an\n\ | |
+imaginary drug market. dopewars is an All-American game which features\n\ | |
+buying, selling, and trying to get past the cops!\n\ | |
+\n\ | |
+The first thing you need to do is pay off your debt to the Loan Shark. \ | |
+After\n\ | |
+that, your goal is to make as much money as possible (and stay alive)! You\n\ | |
+have one month of game time to make your fortune.\n", 385}, | |
+ {"\ | |
+Version %s Copyright (C) 1998-2000 Ben Webb [email protected]\n\ | |
+dopewars is released under the GNU General Public Licence\n", 386}, | |
+ {"\ | |
+\n\ | |
+For information on the command line options, type dopewars -h at your\n\ | |
+Unix prompt. This will display a help screen, listing the availableoptions.", … | |
+ {"Status: Attempting to contact server...", 388}, | |
+ {"Status: Could not connect (%s)", 389}, | |
+ {"%d of %d", 390}, | |
+ {"Server", 391}, | |
+ {"Port", 392}, | |
+ {"Version", 393}, | |
+ {"Players", 394}, | |
+ {"Comment", 395}, | |
+ {"New Game", 396}, | |
+ {"Hey dude, what's your _name?", 397}, | |
+ {"Host name", 398}, | |
+ {"_Connect", 399}, | |
+ {"Single player", 400}, | |
+ {"_Antique mode", 401}, | |
+ {"_Start single-player game", 402}, | |
+ {"Metaserver", 403}, | |
+ {"_Update", 404}, | |
+ {"Status: Waiting for user input", 405}, | |
+ {"Cash: %s", 406}, | |
+ {"Debt: %s", 407}, | |
+ {"Bank: %s", 408}, | |
+ {"Pay back:", 409}, | |
+ {"Deposit", 410}, | |
+ {"Withdraw", 411}, | |
+ {"Pay all", 412}, | |
+ {"Player List", 413}, | |
+ {"Talk to player(s)", 414}, | |
+ {"Talk to all players", 415}, | |
+ {"Message:-", 416}, | |
+ {"Send", 417}, | |
+ {"Spy On Player", 418}, | |
+ {"\ | |
+Please choose the player to spy on. Your %s will\n\ | |
+then offer his services to the player, and if successful,\n\ | |
+you will be able to view the player's stats with the\n\ | |
+\"Get spy reports\" menu. Remember that the %s will leave\n\ | |
+you, so any %s or %s that he's carrying may be lost!", 419}, | |
+ {"Tip Off The Cops", 420}, | |
+ {"\ | |
+Please choose the player to tip off the cops to. Your %s will\n\ | |
+help the cops to attack that player, and then report back to you\n\ | |
+on the encounter. Remember that the %s will leave you temporarily,\n\ | |
+so any %s or %s that he's carrying may be lost!", 421}, | |
+ {"Sack %s", 422}, | |
+ {"\ | |
+Are you sure? (Any %s or %s carried\n\ | |
+by this %s may be lost!)", 423}, | |
+ {"Name", 424}, | |
+ {"Price", 425}, | |
+ {"Number", 426}, | |
+ {"_Buy ->", 427}, | |
+ {"<- _Sell", 428}, | |
+ {"_Drop <-", 429}, | |
+ {"%s here", 430}, | |
+ {"%s carried", 431}, | |
+ {"Change Name", 432}, | |
+ {"\ | |
+Unfortunately, somebody else is already using \"your\" name. Please change \ | |
+it:-", 433}, | |
+ {"Done", 434}, | |
+ {"Spy reports", 435}, | |
+ {"\ | |
+No GTK+ client available - rebuild the binary passing the\n\ | |
+--enable-gtk-client option to configure, or use the curses\n\ | |
+client (if available) instead!\n", 436}, | |
+ {"\ | |
+dopewars server version %s commands and settings\n\ | |
+\n\ | |
+help Displays this help screen\n\ | |
+list Lists all players logged on\n\ | |
+push <player> Politely asks the named player to leave\n\ | |
+kill <player> Abruptly breaks the connection with the named \ | |
+player\n\ | |
+msg:<mesg> Send message to all players\n\ | |
+quit Gracefully quit, after notifying all players\n\ | |
+<variable>=<value> Sets the named variable to the given value\n\ | |
+<variable> Displays the value of the named variable\n\ | |
+<list>[x].<var>=<value> Sets the named variable in the given list,\n\ | |
+ index x, to the given value\n\ | |
+<list>[x].<var> Displays the value of the named list variable\n\ | |
+\n\ | |
+Valid variables are listed below:-\n\ | |
+\n", 437}, | |
+ {"cannot send data to metaserver\n", 438}, | |
+ {"Sending data to metaserver at %s\n", 439}, | |
+ {"Notifying metaserver at %s\n", 440}, | |
+ {"cannot locate metaserver\n", 441}, | |
+ {"cannot create socket for metaserver communication\n", 442}, | |
+ {"cannot read high score file\n", 443}, | |
+ {"\ | |
+Message is lying about its origin\n\ | |
+%s: %c: %s: %s\n\ | |
+Should be from %s", 444}, | |
+ {"MaxClients (%d) exceeded - dropping connection", 445}, | |
+ {"\ | |
+Sorry, but this server has a limit of %d %s, which has been reached.^Please \ | |
+try connecting again later.", 446}, | |
+ {"player", 447}, | |
+ {"players", 448}, | |
+ {"%s will now be known as %s", 449}, | |
+ {"Your dealing time is up...", 450}, | |
+ {"%s: DENIED jet to %s", 451}, | |
+ {"%s now spying on %s", 452}, | |
+ {"%s spy on %s: DENIED", 453}, | |
+ {"%s tipped off the cops to %s", 454}, | |
+ {"%s tipoff about %s: DENIED", 455}, | |
+ {"--More--", 456}, | |
+ {"Pager exited abnormally - using stdout instead...", 457}, | |
+ {"Maintaining pid file %s", 458}, | |
+ {"Cannot create pid file %s", 459}, | |
+ {"\ | |
+Cannot open high score file %s.\n\ | |
+Either ensure you have permissions to access this file and directory, or\n\ | |
+specify an alternate high score file with the -f command line option.", 460}, | |
+ {"\ | |
+dopewars server version %s ready and waiting for connections\n\ | |
+on port %d. For assistance with server commands, enter the command \"help\"\n"… | |
+ {"Cannot install SIGUSR1 interrupt handler!", 462}, | |
+ {"Cannot install SIGINT interrupt handler!", 463}, | |
+ {"Cannot install SIGTERM interrupt handler!", 464}, | |
+ {"Cannot install SIGHUP interrupt handler!", 465}, | |
+ {"Cannot install pipe handler!", 466}, | |
+ {"Users currently logged on:-\n", 467}, | |
+ {"No users currently logged on!", 468}, | |
+ {"Pushing %s", 469}, | |
+ {"No such user!", 470}, | |
+ {"%s killed", 471}, | |
+ {"Unknown command - try \"help\" for help...", 472}, | |
+ {"got connection from %s", 473}, | |
+ {"%s leaves the server!", 474}, | |
+ {"Standard input closed.", 475}, | |
+ {"Unable to read high score file %s", 476}, | |
+ {"Congratulations! You made the high scores!", 477}, | |
+ {"You didn't even make the high score table...", 478}, | |
+ {"Unable to write high score file %s", 479}, | |
+ {"(R.I.P.)", 480}, | |
+ {"%s: Tipoff from %s", 481}, | |
+ {"One of your %s was spying for %s.^The spy %s!", 482}, | |
+ {"Your spy working with %s has been discovered!^The spy %s!", 483}, | |
+ {" The lady next to you on the subway said,^ \"%s\"%s", 484}, | |
+ {"^ (at least, you -think- that's what she said)", 485}, | |
+ {" You hear someone playing %s", 486}, | |
+ {"YN^Would you like to visit %s?", 487}, | |
+ {"YN^^Would you like to hire %s %s for %s?", 488}, | |
+ {"an", 489}, | |
+ {"a", 490}, | |
+ {"AE^%s is already here!^Do you Attack, or Evade?", 491}, | |
+ {"YN^Officer %s is chasing you!", 492}, | |
+ {"YN^Officer %s and %d of his deputies are chasing you!", 493}, | |
+ {"^Do you run?", 494}, | |
+ {"^Do you Run, or Fight?", 495}, | |
+ {"%s: tipoff by %s finished OK.", 496}, | |
+ {"Following your tipoff, the cops ambushed %s, who was shot dead", 497}, | |
+ {"Following your tipoff, the cops ambushed %s, who escaped with %d %s. ", 49… | |
+ {"^You stand there like an idiot.", 499}, | |
+ {"^You lose him in the alleys.", 500}, | |
+ {"^You lose them in the alleys.", 501}, | |
+ {"^You can't shake him, man!", 502}, | |
+ {"^You can't shake them, man!", 503}, | |
+ {"^You killed Officer %s! You find %s on his corpse!", 504}, | |
+ {"YN^^^^Do you pay a doctor %s to sew your %s up?", 505}, | |
+ {"YN^^^^Do you pay a doctor %s to sew you up?", 506}, | |
+ {"^You got one, man!", 507}, | |
+ {"^You missed!", 508}, | |
+ {"^He's firing on you, man! ", 509}, | |
+ {"^They're firing on you, man! ", 510}, | |
+ {"You've been hit! ", 511}, | |
+ {"He wasted you, man! What a drag!", 512}, | |
+ {"They wasted you, man! What a drag!", 513}, | |
+ {"You lost one of your %s!", 514}, | |
+ {"He missed!", 515}, | |
+ {"They missed!", 516}, | |
+ {"You were mugged in the subway!", 517}, | |
+ {"You meet a friend! He gives you %d %s.", 518}, | |
+ {"You meet a friend! You give him %d %s.", 519}, | |
+ {"Sanitized away a RandomOffer", 520}, | |
+ {"\ | |
+Police dogs chase you for %d blocks! You dropped some %s! That's a drag, man!"… | |
+ {"You find %d %s on a dead dude in the subway!", 522}, | |
+ {"Your mama made brownies with some of your %s! They were great!", 523}, | |
+ {"\ | |
+YN^There is some weed that smells like paraquat here!^It looks good! Will \ | |
+you smoke it? ", 524}, | |
+ {"You stopped to %s.", 525}, | |
+ {"Would you like to buy a bigger trenchcoat for %s?", 526}, | |
+ {"YN^Hey dude! I'll help carry your %s for a mere %s. Yes or no?", 527}, | |
+ {"YN^Would you like to buy a %s for %s?", 528}, | |
+ {"%s: offer was on behalf of %s", 529}, | |
+ {"%s has accepted your %s!^Use the G key to contact your spy.", 530}, | |
+ {"\ | |
+You hallucinated for three days on the wildest trip you ever imagined!^Then \ | |
+you died because your brain disintegrated!", 531}, | |
+ {"Too late - %s has just left!", 532}, | |
+ {"%s has rejected your %s!", 533}, | |
+ {"%s has got away!", 534}, | |
+ {"%s has run off!", 535}, | |
+ {"Coward! You successfully escaped from the fight.", 536}, | |
+ {"pitifully armed", 537}, | |
+ {"lightly armed", 538}, | |
+ {"moderately well armed", 539}, | |
+ {"heavily armed", 540}, | |
+ {"armed to the teeth", 541}, | |
+ {" fires and ", 542}, | |
+ {" stands and takes it.", 543}, | |
+ {"%s arrives, with %d %s, %s,^%s", 544}, | |
+ {"%s arrives, %s,^%s", 545}, | |
+ {"%s fires and ", 546}, | |
+ {"%s stands and takes it.", 547}, | |
+ {"misses you!", 548}, | |
+ {"You failed to hit %s.", 549}, | |
+ {"You stand and take it.", 550}, | |
+ {"hits you, man!", 551}, | |
+ {" You've been wasted! What a drag!", 552}, | |
+ {"You hit and killed %s", 553}, | |
+ {", and loot the body!", 554}, | |
+ {"^You lost a %s, man!", 555}, | |
+ {"You are paid a bounty of %s in reward for killing^one of %s's %s", 556}, | |
+ {"You killed one of %s's %s (%d left)", 557}, | |
+ {"You fire, and hit %s!", 558}, | |
+ {"YN^Officer %%s spots you dropping %s, and chases you!", 559}, | |
+ {"\ | |
+YN^Officer %%s and %%d of his deputies spot you dropping %s, and chase you!", … | |
+ {"Player removed due to idle timeout", 561}, | |
+ {"Player removed due to connect timeout", 562}, | |
+ {"%s fails to return fire...", 563}, | |
+ {"\ | |
+This server is version %s, while your client is version %s.\n\ | |
+Be warned that different versions may not be fully compatible!\n\ | |
+Refer to the website at http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/\n\ | |
+for the latest version.", 564}, | |
+ {"Could not find host", 565}, | |
+ {"Could not create network socket", 566}, | |
+ {"Connection refused or no server present", 567}, | |
+ {"Cannot locate metaserver", 568}, | |
+ {"Cannot create socket", 569}, | |
+ {"Metaserver not running HTTP or connection denied", 570}, | |
+ {"AI Player started; attempting to contact server at %s:%d...", 571}, | |
+ {"\ | |
+Could not connect to dopewars server\n\ | |
+(%s)\n\ | |
+AI Player terminating abnormally.", 572}, | |
+ {"Connection established\n", 573}, | |
+ {"Connection to server lost!\n", 574}, | |
+ {"AI Player terminated OK.\n", 575}, | |
+ {"Using name %s\n", 576}, | |
+ {"Players in this game:-\n", 577}, | |
+ {"%s joins the game.\n", 578}, | |
+ {"%s has left the game.\n", 579}, | |
+ {"Jetting to %s with %s cash and %s debt", 580}, | |
+ {"AI Player killed. Terminating normally.\n", 581}, | |
+ {"Game time is up. Leaving game.\n", 582}, | |
+ {"AI Player pushed from the server.\n", 583}, | |
+ {"The server has terminated.\n", 584}, | |
+ {"Selling %d %s at %s\n", 585}, | |
+ {"Buying %d %s at %s\n", 586}, | |
+ {"Buying a %s for %s at the gun shop\n", 587}, | |
+ {"Debt of %s paid off to loan shark\n", 588}, | |
+ {"Loan shark located at %s\n", 589}, | |
+ {"Gun shop located at %s\n", 590}, | |
+ {"Pub located at %s\n", 591}, | |
+ {"Bank located at %s\n", 592}, | |
+ {"Call yourselves drug dealers?", 593}, | |
+ {"A trained monkey could do better...", 594}, | |
+ {"Think you're hard enough to deal with the likes of me?", 595}, | |
+ {"Zzzzz... are you dealing in candy or what?", 596}, | |
+ {"Reckon I'll just have to shoot you for your own good.", 597}, | |
+ {"\ | |
+This binary has been compiled without networking support, and thus cannot \ | |
+act as an AI player.\n\ | |
+Recompile passing --enable-networking to the configure script.", 598}, | |
+}; | |
+ | |
+int _msg_tbl_length = 598; | |
diff --git a/po/de.gmo b/po/de.gmo | |
Binary files differ. | |
diff --git a/po/de.po b/po/de.po | |
t@@ -0,0 +1,2692 @@ | |
+# SOME DESCRIPTIVE TITLE. | |
+# Copyright (C) YEAR Free Software Foundation, Inc. | |
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
+# | |
+#, fuzzy | |
+msgid "" | |
+msgstr "" | |
+"Project-Id-Version: PACKAGE VERSION\n" | |
+"POT-Creation-Date: 2000-09-09 17:49+0100\n" | |
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | |
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |
+"Language-Team: LANGUAGE <[email protected]>\n" | |
+"MIME-Version: 1.0\n" | |
+"Content-Type: text/plain; charset=CHARSET\n" | |
+"Content-Transfer-Encoding: ENCODING\n" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "bitch" | |
+msgstr "Hure" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "bitches" | |
+msgstr "Huren" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "gun" | |
+msgstr "Waffel" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "guns" | |
+msgstr "Waffeln" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "drug" | |
+msgstr "Droge" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "drugs" | |
+msgstr "Drogen" | |
+ | |
+#: src/dopewars.c:109 | |
+msgid "12-" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:109 | |
+msgid "-1984" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:110 | |
+msgid "Hardass" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:110 | |
+msgid "Bob" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:110 | |
+msgid "the Loan Shark" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:110 | |
+msgid "the Bank" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:111 | |
+msgid "Dan's House of Guns" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:111 | |
+msgid "the pub" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:127 | |
+msgid "Network port to connect to" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:130 | |
+msgid "Name of the high score file" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:131 | |
+msgid "Name of the server to connect to" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:134 | |
+msgid "Non-zero if server should report to a metaserver" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:137 | |
+msgid "Port for metaserver communication (client)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:140 | |
+msgid "Port for metaserver communication (server)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:143 | |
+msgid "Metaserver name to report server details to" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:146 | |
+msgid "Path of the CGI script on the metaserver (client)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:149 | |
+msgid "Preferred hostname of your server machine" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:151 | |
+msgid "Authentication for LocalName with the metaserver" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:154 | |
+msgid "Server description, reported to the metaserver" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:157 | |
+msgid "Program used to display multi-page output" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:159 | |
+msgid "No. of game turns (if 0, game never ends)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:161 | |
+msgid "Random events are sanitized" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:164 | |
+msgid "Be verbose in processing config file" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:166 | |
+msgid "Number of locations in the game" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:169 | |
+msgid "Number of guns in the game" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:171 | |
+msgid "Number of drugs in the game" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:173 | |
+msgid "Location of the Loan Shark" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:175 | |
+msgid "Location of the bank" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:177 | |
+msgid "Location of the gun shop" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:179 | |
+msgid "Location of the pub" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:182 | |
+msgid "Name of the loan shark" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:184 | |
+msgid "Name of the bank" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:186 | |
+msgid "Name of the gun shop" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:188 | |
+msgid "Name of the pub" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:190 | |
+msgid "Sort key for listing available drugs" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:193 | |
+msgid "No. of seconds in which to return fire" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:196 | |
+msgid "Players are disconnected after this many seconds" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:199 | |
+msgid "Time in seconds for connections to be made or broken" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:202 | |
+msgid "Maximum number of TCP/IP connections" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:205 | |
+msgid "Seconds between turns of AI players" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:208 | |
+msgid "Amount of cash that each player starts with" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:211 | |
+msgid "Amount of debt that each player starts with" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:213 | |
+msgid "Name of each location" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:217 | |
+msgid "Police presence at each location (%)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:221 | |
+msgid "Minimum number of drugs at each location" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:225 | |
+msgid "Maximum number of drugs at each location" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:229 | |
+msgid "Name of each drug" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:233 | |
+msgid "Minimum normal price of each drug" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:237 | |
+msgid "Maximum normal price of each drug" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:241 | |
+msgid "Non-zero if this drug can be specially cheap" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:245 | |
+msgid "Non-zero if this drug can be specially expensive" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:249 | |
+msgid "Message displayed when this drug is specially cheap" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:253 src/dopewars.c:256 | |
+#, c-format | |
+msgid "Format string used for expensive drugs 50% of time" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:259 | |
+msgid "Divider for drug price when it's specially cheap" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:262 | |
+msgid "Multiplier for specially expensive drug prices" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:265 | |
+msgid "Name of each gun" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:269 | |
+msgid "Price of each gun" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:273 | |
+msgid "Space taken by each gun" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:277 | |
+msgid "Damage done by each gun" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:281 | |
+#, c-format | |
+msgid "% probability of escaping from Officer Hardass" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:284 | |
+msgid "Modifier to EscapeProb for each extra deputy" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:287 | |
+#, c-format | |
+msgid "% probability that Officer Hardass hits you" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:290 | |
+msgid "Modifier to HitProb for each extra deputy" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:293 | |
+msgid "Maximum damage done to you by each cop" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:296 | |
+msgid "Toughness of (difficulty of hitting) each cop" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:299 | |
+#, c-format | |
+msgid "% probability that the cops catch you dropping drugs" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:302 | |
+msgid "Word used to denote a single \"bitch\"" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:304 | |
+msgid "Word used to denote two or more \"bitches\"" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:307 | |
+msgid "Word used to denote a single gun or equivalent" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:310 | |
+msgid "Word used to denote two or more guns" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:312 | |
+msgid "Word used to denote a single drug or equivalent" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:315 | |
+msgid "Word used to denote two or more drugs" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:317 | |
+msgid "Text prefixed to the turn number (i.e. the month)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:320 | |
+msgid "Text appended to the turn number (i.e. the year)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:323 | |
+msgid "Name of the police officer" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:325 | |
+msgid "Name of the reserve police officer" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:327 | |
+msgid "Cost for a bitch to spy on the enemy" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:330 | |
+msgid "Cost for a bitch to tipoff the cops to an enemy" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:333 | |
+msgid "Minimum price to hire a bitch" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:336 | |
+msgid "Maximum price to hire a bitch" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:339 | |
+msgid "List of things which you overhear on the subway" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:342 | |
+msgid "Number of subway sayings" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:345 | |
+msgid "List of songs which you can hear playing" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:348 | |
+msgid "Number of playing songs" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:351 | |
+msgid "List of things which you can stop to do" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:354 | |
+msgid "Number of things which you can stop to do" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:359 | |
+msgid "escaped" | |
+msgstr "entkommen" | |
+ | |
+#: src/dopewars.c:359 | |
+msgid "defected" | |
+msgstr "defected" | |
+ | |
+#: src/dopewars.c:359 | |
+msgid "was shot" | |
+msgstr "wurde getroffen" | |
+ | |
+#: src/dopewars.c:363 | |
+msgid "`Are you Experienced` by Jimi Hendrix" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:364 | |
+msgid "`Cheeba Cheeba` by Tone Loc" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:365 | |
+msgid "`Comin` in to Los Angeles` by Arlo Guthrie" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:366 | |
+msgid "`Commercial` by Spanky and Our Gang" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:367 | |
+msgid "`Late in the Evening` by Paul Simon" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:368 | |
+msgid "`Light Up` by Styx" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:369 | |
+msgid "`Mexico` by Jefferson Airplane" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:370 | |
+msgid "`One toke over the line` by Brewer & Shipley" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:371 | |
+msgid "`The Smokeout` by Shel Silverstein" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:372 | |
+msgid "`White Rabbit` by Jefferson Airplane" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:373 | |
+msgid "`Itchycoo Park` by Small Faces" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:374 | |
+msgid "`White Punks on Dope` by the Tubes" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:375 | |
+msgid "`Legend of a Mind` by the Moody Blues" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:376 | |
+msgid "`Eight Miles High` by the Byrds" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:377 | |
+msgid "`Acapulco Gold` by Riders of the Purple Sage" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:378 | |
+msgid "`Kicks` by Paul Revere & the Raiders" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:379 | |
+msgid "the Nixon tapes" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:380 | |
+msgid "`Legalize It` by Mojo Nixon & Skid Roper" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:385 | |
+msgid "have a beer" | |
+msgstr "Du trinkst ein Bier" | |
+ | |
+#: src/dopewars.c:386 | |
+msgid "smoke a joint" | |
+msgstr "Du rauchst einen Joint" | |
+ | |
+#: src/dopewars.c:387 | |
+msgid "smoke a cigar" | |
+msgstr "Du rauchst eine Zigarre" | |
+ | |
+#: src/dopewars.c:388 | |
+msgid "smoke a Djarum" | |
+msgstr "Du rauchst eine Bong" | |
+ | |
+#: src/dopewars.c:389 | |
+msgid "smoke a cigarette" | |
+msgstr "Du rauchst eine Zigarette" | |
+ | |
+#: src/dopewars.c:393 | |
+msgid "Baretta" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:394 | |
+msgid ".38 Special" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:395 | |
+msgid "Ruger" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:396 | |
+msgid "Saturday Night Special" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:400 | |
+msgid "Bronx" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:401 | |
+msgid "Ghetto" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:402 | |
+msgid "Central Park" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:403 | |
+msgid "Manhattan" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:404 | |
+msgid "Coney Island" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:405 | |
+msgid "Brooklyn" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:406 | |
+msgid "Queens" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:407 | |
+msgid "Staten Island" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:411 | |
+msgid "Acid" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:412 | |
+msgid "The market is flooded with cheap home-made acid!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:413 | |
+msgid "Cocaine" | |
+msgstr "Kokain" | |
+ | |
+#: src/dopewars.c:414 | |
+msgid "Hashish" | |
+msgstr "Hasch" | |
+ | |
+#: src/dopewars.c:414 | |
+msgid "The Marrakesh Express has arrived!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:415 | |
+msgid "Heroin" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:416 | |
+msgid "Ludes" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:417 | |
+msgid "Rival drug dealers raided a pharmacy and are selling cheap ludes!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:418 | |
+msgid "MDA" | |
+msgstr "MDMA" | |
+ | |
+#: src/dopewars.c:419 | |
+msgid "Opium" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:420 | |
+msgid "PCP" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:421 | |
+msgid "Peyote" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:422 | |
+msgid "Shrooms" | |
+msgstr "Pilze" | |
+ | |
+#: src/dopewars.c:423 | |
+msgid "Speed" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:424 | |
+msgid "Weed" | |
+msgstr "Grass" | |
+ | |
+#: src/dopewars.c:424 | |
+msgid "" | |
+"Columbian freighter dusted the Coast Guard! Weed prices have bottomed out!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:430 | |
+#, c-format | |
+msgid "Cops made a big %s bust! Prices are outrageous!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:431 | |
+#, c-format | |
+msgid "Addicts are buying %s at ridiculous prices!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:436 | |
+msgid "Wouldn't it be funny if everyone suddenly quacked at once?" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:437 | |
+msgid "The Pope was once Jewish, you know" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:438 | |
+msgid "I'll bet you have some really interesting dreams" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:439 | |
+msgid "So I think I'm going to Amsterdam this year" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:440 | |
+msgid "Son, you need a yellow haircut" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:441 | |
+msgid "I think it's wonderful what they're doing with incense these days" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:442 | |
+msgid "I wasn't always a woman, you know" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:443 | |
+msgid "Does your mother know you're a dope dealer?" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:444 | |
+msgid "Are you high on something?" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:445 | |
+msgid "Oh, you must be from California" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:446 | |
+msgid "I used to be a hippie, myself" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:447 | |
+msgid "There's nothing like having lots of money" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:448 | |
+msgid "You look like an aardvark!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:449 | |
+msgid "I don't believe in Ronald Reagan" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:450 | |
+msgid "Courage! Bush is a noodle!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:451 | |
+msgid "Haven't I seen you on TV?" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:452 | |
+msgid "I think hemorrhoid commercials are really neat!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:453 | |
+msgid "We're winning the war for drugs!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:454 | |
+msgid "A day without dope is like night" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:455 | |
+#, c-format | |
+msgid "We only use 20% of our brains, so why not burn out the other 80%" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:456 | |
+msgid "I'm soliciting contributions for Zombies for Christ" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:457 | |
+msgid "I'd like to sell you an edible poodle" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:458 | |
+msgid "Winners don't do drugs... unless they do" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:459 | |
+msgid "Kill a cop for Christ!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:460 | |
+msgid "I am the walrus!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:461 | |
+msgid "Jesus loves you more than you will know" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:462 | |
+msgid "I feel an unaccountable urge to dye my hair blue" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:463 | |
+msgid "Wasn't Jane Fonda wonderful in Barbarella" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:464 | |
+msgid "Just say No... well, maybe... ok, what the hell!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:465 | |
+msgid "Would you like a jelly baby?" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:466 | |
+msgid "Drugs can be your friend!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1073 | |
+msgid "Unable to process configuration file line" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1188 | |
+#, c-format | |
+msgid "Index into %s array should be between 1 and %d" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1207 | |
+#, c-format | |
+msgid "%s is %d\n" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1212 | |
+#, c-format | |
+msgid "%s is %s\n" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1215 | |
+#, c-format | |
+msgid "%s is \"%s\"\n" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1219 | |
+#, c-format | |
+msgid "%s[%d] is %s\n" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1222 | |
+#, c-format | |
+msgid "%s is { " | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1253 | |
+#, c-format | |
+msgid "Resized structure list to %d elements\n" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1396 | |
+#, c-format | |
+msgid "" | |
+"Usage: dopewars [OPTION]...\n" | |
+"Drug dealing game based on \"Drug Wars\" by John E. Dell\n" | |
+" -b \"black and white\" - i.e. do not use pretty colours\n" | |
+" (by default colours are used where the terminal supports " | |
+"them)\n" | |
+" -n be boring and don't connect to any available dopewars servers\n" | |
+" (i.e. single player mode)\n" | |
+" -a \"antique\" dopewars - keep as closely to the original version " | |
+"as\n" | |
+" possible (this also disables any networking)\n" | |
+" -f file specify a file to use as the high score table\n" | |
+" (by default %s/dopewars.sco is used)\n" | |
+" -o addr specify a hostname where the server for multiplayer dopewars\n" | |
+" can be found (in human-readable - e.g. nowhere.com - format)\n" | |
+" -s run in server mode (note: for a \"non-interactive\" server, " | |
+"simply\n" | |
+" run as dopewars -s < /dev/null >> logfile & )\n" | |
+" -S run a \"private\" server (i.e. do not notify the metaserver)\n" | |
+" -p specify the network port to use (default: 7902)\n" | |
+" -g file specify the pathname of a dopewars configuration file. This file\n" | |
+" is read immediately when the -g option is encountered\n" | |
+" -r file maintain pid file \"file\" while running the server\n" | |
+" -c create and run a computer player\n" | |
+" -w force the use of a graphical (windowed) client (GTK+ or Win32)\n" | |
+" -t force the use of a text-mode client (curses)\n" | |
+" (by default, a windowed client is used when possible)\n" | |
+" -h display this help information\n" | |
+" -v output version information and exit\n" | |
+"\n" | |
+"dopewars is Copyright (C) Ben Webb 1998-2000, and released under the GNU " | |
+"GPL\n" | |
+"Report bugs to the author at [email protected]\n" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:134 | |
+msgid "D O P E W A R S" | |
+msgstr "D R O G E N K R I E G" | |
+ | |
+#: src/curses_client.c:139 | |
+msgid "" | |
+"Based on John E. Dell's old Drug Wars game, dopewars is a simulation of an" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:141 | |
+msgid "imaginary drug market. dopewars is an All-American game which features" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:143 | |
+msgid "buying, selling, and trying to get past the cops!" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:145 | |
+msgid "" | |
+"The first thing you need to do is pay off your debt to the Loan Shark. After" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:147 | |
+msgid "" | |
+"that, your goal is to make as much money as possible (and stay alive)! You" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:149 | |
+msgid "have one month of game time to make your fortune." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:151 | |
+msgid "Copyright (C) 1998-2000 Ben Webb [email protected]" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:153 | |
+#, c-format | |
+msgid "Version %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:156 | |
+msgid "dopewars is released under the GNU General Public Licence" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:159 | |
+msgid "Drug Dealing and Research Dan Wolf" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:160 | |
+msgid "Play Testing Phil Davis Owen Walsh" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:162 | |
+msgid "Extensive Play Testing Katherine Holt Caroline Moore" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:164 | |
+msgid "Constructive Criticism Andrea Elliot-Smith Pete Winn" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:166 | |
+msgid "Unconstructive Criticism James Matthews" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:168 | |
+msgid "For information on the command line options, type dopewars -h at your" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:170 | |
+msgid "" | |
+"Unix prompt. This will display a help screen, listing the available options." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:186 | |
+msgid "Please enter the hostname and port of a dopewars server:-" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:187 | |
+msgid "Hostname: " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:190 | |
+msgid "Port: " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:206 | |
+msgid "No servers listed on metaserver" | |
+msgstr "Es sind keine Server auf dem Metaserver eingetragen" | |
+ | |
+#: src/curses_client.c:210 | |
+msgid "Please wait... attempting to contact metaserver..." | |
+msgstr "Bitte warten... Erstelle Verbindung zu Metaserver..." | |
+ | |
+#: src/curses_client.c:218 | |
+msgid "Connection to metaserver established. Obtaining server list..." | |
+msgstr "Verbindung zu Metaserver aufgebaut. Hole Serverliste..." | |
+ | |
+#: src/curses_client.c:231 | |
+#, c-format | |
+msgid "Server : %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:233 | |
+#, c-format | |
+msgid "Port : %d" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:235 | |
+#, c-format | |
+msgid "Version : %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:238 | |
+#, c-format | |
+msgid "Players: -unknown- (maximum %d)" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:241 | |
+#, c-format | |
+msgid "Players: %d (maximum %d)" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:245 | |
+#, c-format | |
+msgid "Up since : %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:247 | |
+#, c-format | |
+msgid "Comment: %s" | |
+msgstr "Kommentar:%s" | |
+ | |
+#: src/curses_client.c:251 | |
+msgid "N>ext server; P>revious server; S>elect this server... " | |
+msgstr "N>aechster ; V>orheriger ; W>aehle diesen Server... " | |
+ | |
+#: src/curses_client.c:252 | |
+msgid "NPS" | |
+msgstr "NVW" | |
+ | |
+#: src/curses_client.c:298 | |
+msgid "Please wait... attempting to contact dopewars server..." | |
+msgstr "Bitten warten... Baue Verbindung zu Server auf..." | |
+ | |
+#: src/curses_client.c:305 | |
+#, c-format | |
+msgid "Error: %s" | |
+msgstr "Fehler: %s" | |
+ | |
+#: src/curses_client.c:308 | |
+msgid "Could not start multiplayer dopewars" | |
+msgstr "Kann den Multiplayer-Modus nicht starten" | |
+ | |
+#: src/curses_client.c:315 | |
+msgid "Will you... C>onnect to a different host and/or port" | |
+msgstr " " | |
+ | |
+#: src/curses_client.c:317 | |
+msgid " L>ist the servers on the metaserver, and select one" | |
+msgstr " Oeffne V>erbindug zu einem Server " | |
+ | |
+#: src/curses_client.c:320 | |
+msgid " Q>uit (where you can start a server by typing " | |
+msgstr " Oeffne L>iste von Metaserver" | |
+ | |
+#: src/curses_client.c:323 | |
+msgid " dopewars -s < /dev/null & )" | |
+msgstr " Moechtest Du ein S>olospiel starten ? " | |
+ | |
+#: src/curses_client.c:324 | |
+msgid " or P>lay single-player ? " | |
+msgstr " oder moechtest Du A>bhauen " | |
+ | |
+#: src/curses_client.c:326 | |
+msgid "CLQP" | |
+msgstr "VLAS" | |
+ | |
+#: src/curses_client.c:363 src/gtk_client.c:757 | |
+msgid "Where to, dude ? " | |
+msgstr "Wohin, kleiner ? " | |
+ | |
+#: src/curses_client.c:393 | |
+#, c-format | |
+msgid "You can't get any cash for the following carried %s :" | |
+msgstr "Bekommst Du kein Geld fuer dein Zeug? %s :" | |
+ | |
+#: src/curses_client.c:406 | |
+msgid "What do you want to drop? " | |
+msgstr "Was willst Du wegwerfen? " | |
+ | |
+#: src/curses_client.c:417 | |
+msgid "How many do you drop? " | |
+msgstr "Und wieviel davon? " | |
+ | |
+#: src/curses_client.c:446 src/curses_client.c:816 | |
+msgid "What do you wish to buy? " | |
+msgstr "Was moechtest Du kaufen? " | |
+ | |
+#: src/curses_client.c:448 src/curses_client.c:818 | |
+msgid "What do you wish to sell? " | |
+msgstr "Was moechtest Du verkaufen? " | |
+ | |
+#: src/curses_client.c:465 | |
+#, c-format | |
+msgid "You can afford %d, and can carry %d. " | |
+msgstr "Du kannst %d kaufen, und %d tragen. " | |
+ | |
+#: src/curses_client.c:468 | |
+msgid "How many do you buy? " | |
+msgstr "Wieviel moechtest Du kaufen? " | |
+ | |
+#: src/curses_client.c:476 | |
+#, c-format | |
+msgid "You have %d. " | |
+msgstr "Du hast %d. " | |
+ | |
+#: src/curses_client.c:478 | |
+msgid "How many do you sell? " | |
+msgstr "Wieviel magst Du verticken? " | |
+ | |
+#: src/curses_client.c:501 | |
+#, c-format | |
+msgid "Choose an errand to give one of your %s..." | |
+msgstr "Waehle einen Auftrag fuer deine %s..." | |
+ | |
+#: src/curses_client.c:507 | |
+#, c-format | |
+msgid " S>py on another dealer (cost: %s)" | |
+msgstr " S>chicke Spion zu einem anderem Dealer (cost: %s)" | |
+ | |
+#: src/curses_client.c:511 | |
+#, c-format | |
+msgid " T>ip off the cops to another dealer (cost: %s)" | |
+msgstr " V>erpfeife ein anderen Dealer an die Cops (cost: %s)" | |
+ | |
+#: src/curses_client.c:514 | |
+msgid " G>et stuffed" | |
+msgstr " G>et stuffed" | |
+ | |
+#: src/curses_client.c:517 | |
+msgid "or C>ontact your spies and receive reports" | |
+msgstr "oder K>ontaktiere Spion" | |
+ | |
+#: src/curses_client.c:519 | |
+msgid "or N>o errand ? " | |
+msgstr "oder N>ichts ? " | |
+ | |
+#: src/curses_client.c:522 | |
+msgid "STGCN" | |
+msgstr "SVGKN" | |
+ | |
+#: src/curses_client.c:525 | |
+msgid "Whom do you want to spy on? " | |
+msgstr "Ueber wen moechtest Du mehr erfahren? " | |
+ | |
+#: src/curses_client.c:530 | |
+msgid "Whom do you want to tip the cops off to? " | |
+msgstr "Wen moechtest Du los werden? " | |
+ | |
+#: src/curses_client.c:535 | |
+msgid " Are you sure? " | |
+msgstr " Bist Du sicher? [J/N] " | |
+ | |
+#: src/curses_client.c:536 src/curses_client.c:554 src/curses_client.c:1673 | |
+msgid "YN" | |
+msgstr "JN" | |
+ | |
+#: src/curses_client.c:552 | |
+msgid "Are you sure you want to quit? " | |
+msgstr "Willst Du wirklich schon gehen? [J/N]" | |
+ | |
+#: src/curses_client.c:560 | |
+msgid "New name: " | |
+msgstr "Neuer Name: " | |
+ | |
+#: src/curses_client.c:610 | |
+msgid "You have been pushed from the server. Reverting to single player mode." | |
+msgstr "Du wurdest vom Server geworfen. Kehre in Einzelspieler-Modus zurueck." | |
+ | |
+#: src/curses_client.c:620 | |
+msgid "The server has terminated. Reverting to single player mode." | |
+msgstr "" | |
+"Verbindung zu Server unterbrochen! Kehre zurueck in Einzelspieler-Modus" | |
+ | |
+#: src/curses_client.c:635 src/gtk_client.c:328 src/serverside.c:255 | |
+#, c-format | |
+msgid "%s joins the game!" | |
+msgstr "%s betritt das Spiel!" | |
+ | |
+#: src/curses_client.c:640 src/gtk_client.c:334 | |
+#, c-format | |
+msgid "%s has left the game." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:645 | |
+#, c-format | |
+msgid "%s will now be known as %s." | |
+msgstr "%s ist nun bekannt als %s." | |
+ | |
+#: src/curses_client.c:669 | |
+msgid "S U B W A Y" | |
+msgstr "U - B A H N" | |
+ | |
+#: src/curses_client.c:712 | |
+msgid "" | |
+"Unfortunately, somebody else is already using \"your\" name. Please change " | |
+"it." | |
+msgstr " Naja, jemand anders benutzt \"Deinen\" Namen." | |
+ | |
+#: src/curses_client.c:734 | |
+msgid "H I G H S C O R E S" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:790 | |
+msgid "Will you B>uy, S>ell, or L>eave? " | |
+msgstr "Willst Du K>aufen, V>erkaufen, oder A>bhauen? " | |
+ | |
+#: src/curses_client.c:795 | |
+msgid "BSL" | |
+msgstr "KVA" | |
+ | |
+#: src/curses_client.c:800 | |
+#, c-format | |
+msgid "You don't have any %s to sell!" | |
+msgstr "Du hast keine %s zum verkaufen!" | |
+ | |
+#: src/curses_client.c:807 src/gtk_client.c:1029 | |
+#, c-format | |
+msgid "You'll need more %s to carry any more %s!" | |
+msgstr "Du brauchst mehr %s Platz um noch was zu tragen %s!" | |
+ | |
+#: src/curses_client.c:829 src/gtk_client.c:1033 | |
+#, c-format | |
+msgid "You don't have enough space to carry that %s!" | |
+msgstr "Du hast nicht genug Platz um %s zu tragen!" | |
+ | |
+#: src/curses_client.c:837 src/gtk_client.c:1037 | |
+#, c-format | |
+msgid "You don't have enough cash to buy that %s!" | |
+msgstr "Du hast nicht genug Kohle fuer %s!" | |
+ | |
+#: src/curses_client.c:850 src/gtk_client.c:1041 | |
+msgid "You don't have any to sell!" | |
+msgstr "Du hast nix zum verkaufen!" | |
+ | |
+#: src/curses_client.c:874 | |
+msgid "How much money do you pay back? " | |
+msgstr "Wieviel Geld moechtest Du dem Kredithai geben? " | |
+ | |
+#: src/curses_client.c:880 src/curses_client.c:910 src/gtk_client.c:1839 | |
+msgid "You don't have that much money!" | |
+msgstr "Soviel Kohle hast Du nicht!" | |
+ | |
+#: src/curses_client.c:900 | |
+msgid "Do you want to D>eposit money, W>ithdraw money, or L>eave ? " | |
+msgstr "Moechtest Du E>inzahlen, A>bheben, oder die Bank V>erlassen? " | |
+ | |
+#: src/curses_client.c:903 | |
+msgid "DWL" | |
+msgstr "EAV" | |
+ | |
+#: src/curses_client.c:905 | |
+msgid "How much money? " | |
+msgstr "Wieviel Kohle? " | |
+ | |
+#: src/curses_client.c:913 src/gtk_client.c:1832 | |
+msgid "There isn't that much money in the bank..." | |
+msgstr "Ein Baenker spricht: \"Soviel Geld haben Sie nicht.\"" | |
+ | |
+#: src/curses_client.c:992 | |
+msgid "Press any key..." | |
+msgstr "Drueck mal ne Taste..." | |
+ | |
+#: src/curses_client.c:1123 | |
+msgid "Messages" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1130 src/gtk_client.c:1322 | |
+msgid "Stats" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1133 | |
+#, c-format | |
+msgid "Cash %17s" | |
+msgstr "Bargeld %17s" | |
+ | |
+#: src/curses_client.c:1140 | |
+#, c-format | |
+msgid "Health %3d" | |
+msgstr "Gesundheit %3d" | |
+ | |
+#: src/curses_client.c:1142 | |
+#, c-format | |
+msgid "Bank %17s" | |
+msgstr "Konto %17s" | |
+ | |
+#: src/curses_client.c:1146 | |
+#, c-format | |
+msgid "Debt %17s" | |
+msgstr "Schulden %17s" | |
+ | |
+#: src/curses_client.c:1150 | |
+#, c-format | |
+msgid "Space %6d" | |
+msgstr "Platz %6d" | |
+ | |
+#: src/curses_client.c:1152 | |
+#, c-format | |
+msgid "%s %3d Space %6d" | |
+msgstr "%s %3d Platz %6d" | |
+ | |
+#: src/curses_client.c:1163 | |
+msgid "Trenchcoat" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1203 | |
+#, c-format | |
+msgid "Spy reports for %s" | |
+msgstr "Spion berichtet %s" | |
+ | |
+#: src/curses_client.c:1207 src/curses_client.c:1212 | |
+#, c-format | |
+msgid "%s..." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1233 | |
+msgid "No other players are currently logged on!" | |
+msgstr "Tja, Du bist alleine auf der Welt!" | |
+ | |
+#: src/curses_client.c:1238 | |
+msgid "Players currently logged on:-" | |
+msgstr "Eingeloggte Mitspieler:-" | |
+ | |
+#: src/curses_client.c:1386 | |
+msgid "Hey dude, what's your name? " | |
+msgstr "Hey kleiner, wie heisst Du? " | |
+ | |
+#: src/curses_client.c:1419 | |
+#, c-format | |
+msgid "Hey dude, the prices of %s here are:" | |
+msgstr "Hey kleiner, die %s preise von hier:" | |
+ | |
+#: src/curses_client.c:1431 | |
+msgid "Will you B>uy" | |
+msgstr "K>aufen" | |
+ | |
+#: src/curses_client.c:1432 | |
+msgid ", S>ell" | |
+msgstr ", V>erkaufen" | |
+ | |
+#: src/curses_client.c:1433 | |
+msgid ", D>rop" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1434 | |
+msgid ", T>alk, P>age, L>ist" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1437 | |
+msgid ", G>ive" | |
+msgstr ", G>eben" | |
+ | |
+#: src/curses_client.c:1440 | |
+msgid ", F>ight" | |
+msgstr ", F>ighten" | |
+ | |
+#: src/curses_client.c:1444 | |
+msgid ", J>et" | |
+msgstr ", R>eisen" | |
+ | |
+#: src/curses_client.c:1446 src/curses_client.c:1461 | |
+msgid ", or Q>uit? " | |
+msgstr ", oder E>nde? " | |
+ | |
+#: src/curses_client.c:1454 | |
+msgid "Do you " | |
+msgstr "Willst Du " | |
+ | |
+#: src/curses_client.c:1456 | |
+msgid "F>ight, " | |
+msgstr "F>ighten, " | |
+ | |
+#: src/curses_client.c:1457 | |
+msgid "S>tand, " | |
+msgstr "S>tehen bleiben, " | |
+ | |
+#: src/curses_client.c:1459 | |
+msgid "R>un, " | |
+msgstr "R>ennen, " | |
+ | |
+#: src/curses_client.c:1460 | |
+msgid "D>eal " | |
+msgstr "D>ealen " | |
+ | |
+#: src/curses_client.c:1503 | |
+msgid "Connection to server lost! Reverting to single player mode" | |
+msgstr "" | |
+"Verbindung zu Server unterbrochen! Kehre zurueck in Einzelspieler-Modus" | |
+ | |
+#: src/curses_client.c:1532 | |
+msgid "BSDTPLGFJQ" | |
+msgstr "KVDTPLGFRE" | |
+ | |
+#: src/curses_client.c:1534 | |
+msgid "DRFSQ" | |
+msgstr "DRFSE" | |
+ | |
+#: src/curses_client.c:1562 | |
+msgid "List what? P>layers or S>cores? " | |
+msgstr "Zeige was? S>pieler oder P>unkte? " | |
+ | |
+#: src/curses_client.c:1563 | |
+msgid "PS" | |
+msgstr "SP" | |
+ | |
+#: src/curses_client.c:1572 | |
+msgid "Whom do you want to page (talk privately to) ? " | |
+msgstr "Wem moechtest Du volltexten ? " | |
+ | |
+#: src/curses_client.c:1587 | |
+msgid "Talk: " | |
+msgstr "Sag: " | |
+ | |
+#: src/curses_client.c:1672 | |
+msgid "Play again? " | |
+msgstr "Moechtest Du nochmal spielen? [J/N]+-> " | |
+ | |
+#: src/curses_client.c:1684 | |
+msgid "" | |
+"No curses client available - rebuild the binary passing the\n" | |
+"--enable-curses-client option to configure, or use a windowed\n" | |
+"client (if available) instead!\n" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:141 | |
+msgid "/_Game" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:142 | |
+msgid "/Game/_New" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:143 | |
+msgid "/Game/_Quit" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:144 | |
+msgid "/_Talk" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:145 | |
+msgid "/Talk/To _All" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:146 | |
+msgid "/Talk/To _Player" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:147 | |
+msgid "/_List" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:148 | |
+msgid "/List/_Players" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:149 | |
+msgid "/List/_Scores" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:150 | |
+msgid "/List/_Inventory" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:151 | |
+msgid "/_Errands" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:152 | |
+msgid "/Errands/_Spy" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:153 | |
+msgid "/Errands/_Tipoff" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:154 | |
+msgid "/Errands/Sack _Bitch" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:155 | |
+msgid "/Errands/_Get spy reports" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:156 | |
+msgid "/_Help" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:157 | |
+msgid "/Help/_About" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:162 | |
+msgid "Warning" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:162 | |
+msgid "Message" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:172 | |
+msgid "Quit Game" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:172 src/gtk_client.c:181 | |
+msgid "Abandon current game?" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:180 | |
+msgid "Start new game" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:202 | |
+msgid "Inventory" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:230 src/gtk_client.c:2075 src/gtk_client.c:2443 | |
+msgid "Close" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:260 | |
+msgid "Connection to server lost - switching to single player mode" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:302 | |
+msgid "You have been pushed from the server." | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:307 | |
+msgid "The server has terminated." | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:347 | |
+#, c-format | |
+msgid "Jetting to %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:352 | |
+msgid "<main>/Errands/Spy" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:354 | |
+#, c-format | |
+msgid "_Spy\t(%s)" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:358 | |
+#, c-format | |
+msgid "_Tipoff\t(%s)" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:360 | |
+msgid "<main>/Errands/Tipoff" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:393 | |
+msgid "High Scores" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:427 src/gtk_client.c:980 src/gtk_client.c:1435 | |
+#: src/gtk_client.c:1748 src/gtk_client.c:1913 src/gtk_client.c:2192 | |
+#: src/gtk_client.c:2350 | |
+msgid "OK" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:506 | |
+msgid "Fight" | |
+msgstr "Fighten" | |
+ | |
+#: src/gtk_client.c:533 | |
+#, c-format | |
+msgid "_Deal %s" | |
+msgstr "_Dealen %s" | |
+ | |
+#: src/gtk_client.c:537 src/gtk_client.c:1073 src/gtk_client.c:1267 | |
+msgid "_Fight" | |
+msgstr "_Fighten" | |
+ | |
+#: src/gtk_client.c:540 | |
+msgid "_Stand" | |
+msgstr "_Stehen bleiben" | |
+ | |
+#: src/gtk_client.c:543 src/gtk_client.c:1072 | |
+msgid "_Run" | |
+msgstr "_Rennen" | |
+ | |
+#: src/gtk_client.c:607 | |
+#, c-format | |
+msgid "Space: %d" | |
+msgstr "Platz: %d" | |
+ | |
+#: src/gtk_client.c:748 | |
+msgid "Jet to location" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:813 | |
+#, c-format | |
+msgid "at %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:818 | |
+#, c-format | |
+msgid "You are currently carrying %d %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:823 | |
+#, c-format | |
+msgid "Available space: %d" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:828 | |
+#, c-format | |
+msgid "You can afford %d" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:878 src/gtk_client.c:1009 | |
+msgid "Buy" | |
+msgstr "Kaufen" | |
+ | |
+#: src/gtk_client.c:879 src/gtk_client.c:1010 | |
+msgid "Sell" | |
+msgstr "Verkaufen" | |
+ | |
+#: src/gtk_client.c:880 src/gtk_client.c:1011 | |
+msgid "Drop" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:968 | |
+#, c-format | |
+msgid "%s how many?" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:986 src/gtk_client.c:1748 src/gtk_client.c:1924 | |
+#: src/gtk_client.c:2200 | |
+msgid "Cancel" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1025 | |
+#, c-format | |
+msgid "You don't have any %s!" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1072 src/gtk_client.c:1749 | |
+msgid "_Yes" | |
+msgstr "_Ja" | |
+ | |
+#: src/gtk_client.c:1072 src/gtk_client.c:1749 | |
+msgid "_No" | |
+msgstr "_Nein" | |
+ | |
+#: src/gtk_client.c:1073 | |
+msgid "_Attack" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1073 | |
+msgid "_Evade" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1091 | |
+msgid "Question" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1199 | |
+msgid "<main>/Talk" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1201 | |
+msgid "<main>/List" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1203 | |
+msgid "<main>/Errands" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1222 | |
+msgid "Cash" | |
+msgstr "Bargeld" | |
+ | |
+#: src/gtk_client.c:1227 | |
+msgid "Debt" | |
+msgstr "Schulden" | |
+ | |
+#: src/gtk_client.c:1232 | |
+msgid "Bank" | |
+msgstr "Konto" | |
+ | |
+#: src/gtk_client.c:1247 | |
+msgid "Health" | |
+msgstr "Gesundheit" | |
+ | |
+#: src/gtk_client.c:1267 | |
+msgid "_Jet!" | |
+msgstr "_Reisen!" | |
+ | |
+#: src/gtk_client.c:1298 | |
+msgid "dopewars" | |
+msgstr "drogenkrieg" | |
+ | |
+#: src/gtk_client.c:1382 | |
+msgid "Drug Dealing and Research" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1383 | |
+msgid "Play Testing" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1384 | |
+msgid "Extensive Play Testing" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1386 | |
+msgid "Constructive Criticism" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1388 | |
+msgid "Unconstructive Criticism" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1392 | |
+msgid "About dopewars" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1401 | |
+msgid "" | |
+"Based on John E. Dell's old Drug Wars game, dopewars is a simulation of an\n" | |
+"imaginary drug market. dopewars is an All-American game which features\n" | |
+"buying, selling, and trying to get past the cops!\n" | |
+"\n" | |
+"The first thing you need to do is pay off your debt to the Loan Shark. " | |
+"After\n" | |
+"that, your goal is to make as much money as possible (and stay alive)! You\n" | |
+"have one month of game time to make your fortune.\n" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1409 | |
+#, c-format | |
+msgid "" | |
+"Version %s Copyright (C) 1998-2000 Ben Webb [email protected]\n" | |
+"dopewars is released under the GNU General Public Licence\n" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1427 | |
+msgid "" | |
+"\n" | |
+"For information on the command line options, type dopewars -h at your\n" | |
+"Unix prompt. This will display a help screen, listing the availableoptions." | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1465 src/gtk_client.c:1550 | |
+msgid "Status: Attempting to contact server..." | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1471 src/gtk_client.c:1556 | |
+#, c-format | |
+msgid "Status: Could not connect (%s)" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1505 | |
+#, c-format | |
+msgid "%d of %d" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1572 src/gtk_client.c:1609 src/gtk_client.c:1650 | |
+msgid "Server" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1573 src/gtk_client.c:1624 | |
+msgid "Port" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1574 | |
+msgid "Version" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1575 | |
+msgid "Players" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1576 | |
+msgid "Comment" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1585 | |
+msgid "New Game" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1594 | |
+msgid "Hey dude, what's your _name?" | |
+msgstr "Hey kleiner, wie heisst Du? " | |
+ | |
+#: src/gtk_client.c:1616 | |
+msgid "Host name" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1639 src/gtk_client.c:1702 | |
+msgid "_Connect" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1652 src/gtk_client.c:1673 | |
+msgid "Single player" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1658 | |
+msgid "_Antique mode" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1665 | |
+msgid "_Start single-player game" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1675 src/gtk_client.c:1713 | |
+msgid "Metaserver" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1692 | |
+msgid "_Update" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1717 | |
+msgid "Status: Waiting for user input" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1870 | |
+#, c-format | |
+msgid "Cash: %s" | |
+msgstr "Bargeld: %s" | |
+ | |
+#: src/gtk_client.c:1877 | |
+#, c-format | |
+msgid "Debt: %s" | |
+msgstr "Schulden: %s" | |
+ | |
+#: src/gtk_client.c:1880 | |
+#, c-format | |
+msgid "Bank: %s" | |
+msgstr "Konto: %s" | |
+ | |
+#: src/gtk_client.c:1888 | |
+msgid "Pay back:" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1891 | |
+msgid "Deposit" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1895 | |
+msgid "Withdraw" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1919 | |
+msgid "Pay all" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1941 | |
+msgid "Player List" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2030 | |
+msgid "Talk to player(s)" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2052 | |
+msgid "Talk to all players" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2056 | |
+msgid "Message:-" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2069 | |
+msgid "Send" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2162 | |
+msgid "Spy On Player" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2164 | |
+#, c-format | |
+msgid "" | |
+"Please choose the player to spy on. Your %s will\n" | |
+"then offer his services to the player, and if successful,\n" | |
+"you will be able to view the player's stats with the\n" | |
+"\"Get spy reports\" menu. Remember that the %s will leave\n" | |
+"you, so any %s or %s that he's carrying may be lost!" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2172 | |
+msgid "Tip Off The Cops" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2174 | |
+#, c-format | |
+msgid "" | |
+"Please choose the player to tip off the cops to. Your %s will\n" | |
+"help the cops to attack that player, and then report back to you\n" | |
+"on the encounter. Remember that the %s will leave you temporarily,\n" | |
+"so any %s or %s that he's carrying may be lost!" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2214 | |
+#, c-format | |
+msgid "Sack %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2215 | |
+#, c-format | |
+msgid "" | |
+"Are you sure? (Any %s or %s carried\n" | |
+"by this %s may be lost!)" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2236 | |
+msgid "Name" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2237 | |
+msgid "Price" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2238 | |
+msgid "Number" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2240 | |
+msgid "_Buy ->" | |
+msgstr "_Kaufen ->" | |
+ | |
+#: src/gtk_client.c:2241 | |
+msgid "<- _Sell" | |
+msgstr "<- _Verkaufen" | |
+ | |
+#: src/gtk_client.c:2242 | |
+msgid "_Drop <-" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2247 | |
+#, c-format | |
+msgid "%s here" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2250 | |
+#, c-format | |
+msgid "%s carried" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2326 | |
+msgid "Change Name" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2336 | |
+msgid "" | |
+"Unfortunately, somebody else is already using \"your\" name. Please change " | |
+"it:-" | |
+msgstr "Naja, jemand anders benutzt \"Deinen\" Namen." | |
+ | |
+#: src/gtk_client.c:2395 | |
+msgid "Done" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2429 | |
+msgid "Spy reports" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2499 | |
+msgid "" | |
+"No GTK+ client available - rebuild the binary passing the\n" | |
+"--enable-gtk-client option to configure, or use the curses\n" | |
+"client (if available) instead!\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:68 | |
+#, c-format | |
+msgid "" | |
+"dopewars server version %s commands and settings\n" | |
+"\n" | |
+"help Displays this help screen\n" | |
+"list Lists all players logged on\n" | |
+"push <player> Politely asks the named player to leave\n" | |
+"kill <player> Abruptly breaks the connection with the named " | |
+"player\n" | |
+"msg:<mesg> Send message to all players\n" | |
+"quit Gracefully quit, after notifying all players\n" | |
+"<variable>=<value> Sets the named variable to the given value\n" | |
+"<variable> Displays the value of the named variable\n" | |
+"<list>[x].<var>=<value> Sets the named variable in the given list,\n" | |
+" index x, to the given value\n" | |
+"<list>[x].<var> Displays the value of the named list variable\n" | |
+"\n" | |
+"Valid variables are listed below:-\n" | |
+"\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:100 | |
+msgid "cannot send data to metaserver\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:122 | |
+#, c-format | |
+msgid "Sending data to metaserver at %s\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:124 | |
+#, c-format | |
+msgid "Notifying metaserver at %s\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:127 | |
+msgid "cannot locate metaserver\n" | |
+msgstr "Fehler: Kann Metaserver nicht lokalisieren.\n" | |
+ | |
+#: src/serverside.c:132 | |
+msgid "cannot create socket for metaserver communication\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:166 | |
+msgid "cannot read high score file\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:204 | |
+#, c-format | |
+msgid "" | |
+"Message is lying about its origin\n" | |
+"%s: %c: %s: %s\n" | |
+"Should be from %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:263 | |
+#, c-format | |
+msgid "MaxClients (%d) exceeded - dropping connection" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:265 | |
+#, c-format | |
+msgid "" | |
+"Sorry, but this server has a limit of %d %s, which has been reached.^Please " | |
+"try connecting again later." | |
+msgstr "" | |
+"Sorry, aber hier duerfen max. %d %s spielen.^Bitte versuchs spaeter nochmal." | |
+ | |
+#: src/serverside.c:267 | |
+msgid "player" | |
+msgstr "Spieler" | |
+ | |
+#: src/serverside.c:267 | |
+msgid "players" | |
+msgstr "Spielers" | |
+ | |
+#: src/serverside.c:276 | |
+#, c-format | |
+msgid "%s will now be known as %s" | |
+msgstr "%s ist nun bekannt als %s" | |
+ | |
+#: src/serverside.c:291 | |
+msgid "Your dealing time is up..." | |
+msgstr "Deine Zeit als Dealer ist vorbei..." | |
+ | |
+#: src/serverside.c:302 | |
+#, c-format | |
+msgid "%s: DENIED jet to %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:359 | |
+#, c-format | |
+msgid "%s now spying on %s" | |
+msgstr "%s spioniert nun bei %s" | |
+ | |
+#: src/serverside.c:367 | |
+#, c-format | |
+msgid "%s spy on %s: DENIED" | |
+msgstr "%s spion bei %s: VERWEIGERT" | |
+ | |
+#: src/serverside.c:373 | |
+#, c-format | |
+msgid "%s tipped off the cops to %s" | |
+msgstr "%s hat %s bei den Cops verraten" | |
+ | |
+#: src/serverside.c:381 | |
+#, c-format | |
+msgid "%s tipoff about %s: DENIED" | |
+msgstr "%s verpfeifft %s: VERWEIGERT" | |
+ | |
+#: src/serverside.c:489 | |
+msgid "--More--" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:500 | |
+msgid "Pager exited abnormally - using stdout instead..." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:515 | |
+#, c-format | |
+msgid "Maintaining pid file %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:519 | |
+#, c-format | |
+msgid "Cannot create pid file %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:568 | |
+#, c-format | |
+msgid "" | |
+"Cannot open high score file %s.\n" | |
+"Either ensure you have permissions to access this file and directory, or\n" | |
+"specify an alternate high score file with the -f command line option." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:605 | |
+#, c-format | |
+msgid "" | |
+"dopewars server version %s ready and waiting for connections\n" | |
+"on port %d. For assistance with server commands, enter the command \"help\"\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:622 | |
+msgid "Cannot install SIGUSR1 interrupt handler!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:628 | |
+msgid "Cannot install SIGINT interrupt handler!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:631 | |
+msgid "Cannot install SIGTERM interrupt handler!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:634 | |
+msgid "Cannot install SIGHUP interrupt handler!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:639 | |
+msgid "Cannot install pipe handler!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:662 | |
+msgid "Users currently logged on:-\n" | |
+msgstr "Eingelogte Spieler:-\n" | |
+ | |
+#: src/serverside.c:667 | |
+msgid "No users currently logged on!" | |
+msgstr "Du bist ganz allein, machs Dir selbst!" | |
+ | |
+#: src/serverside.c:671 | |
+#, c-format | |
+msgid "Pushing %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:673 src/serverside.c:681 | |
+msgid "No such user!" | |
+msgstr "Kein solcher Benutzer!" | |
+ | |
+#: src/serverside.c:677 | |
+#, c-format | |
+msgid "%s killed" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:683 | |
+msgid "Unknown command - try \"help\" for help..." | |
+msgstr "Unbekanntes Kommando - versuch mal \"help\" fuer hilfe..." | |
+ | |
+#: src/serverside.c:700 | |
+#, c-format | |
+msgid "got connection from %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:716 | |
+#, c-format | |
+msgid "%s leaves the server!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:781 | |
+msgid "Standard input closed." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:915 | |
+#, c-format | |
+msgid "Unable to read high score file %s" | |
+msgstr "Fehler: Kann die Bestenliste %s nicht lesen" | |
+ | |
+#: src/serverside.c:935 | |
+msgid "Congratulations! You made the high scores!" | |
+msgstr "Fantastisch! Du hasts geschafft!" | |
+ | |
+#: src/serverside.c:948 | |
+msgid "You didn't even make the high score table..." | |
+msgstr "Tja, besser spielen dann gibs auch ein Eintrag" | |
+ | |
+#: src/serverside.c:962 | |
+#, c-format | |
+msgid "Unable to write high score file %s" | |
+msgstr "*ARGH* Kann Bestenliste %s nicht schreiben" | |
+ | |
+#: src/serverside.c:981 | |
+msgid "(R.I.P.)" | |
+msgstr "(K.I.A.)" | |
+ | |
+#: src/serverside.c:1016 | |
+#, c-format | |
+msgid "%s: Tipoff from %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1033 | |
+#, c-format | |
+msgid "One of your %s was spying for %s.^The spy %s!" | |
+msgstr "Einer deiner %s hat fuer %s gearbeitet.^Der Verraeter %s!" | |
+ | |
+#: src/serverside.c:1041 | |
+#, c-format | |
+msgid "Your spy working with %s has been discovered!^The spy %s!" | |
+msgstr "Dein Spion bei %s wurde gerettet!^Der Spion %s!" | |
+ | |
+#: src/serverside.c:1064 | |
+#, c-format | |
+msgid " The lady next to you on the subway said,^ \"%s\"%s" | |
+msgstr " Die Frau neben Dir in der U-Bahn spricht,^\"%s\"%s" | |
+ | |
+#: src/serverside.c:1067 | |
+msgid "^ (at least, you -think- that's what she said)" | |
+msgstr "^ (Du denkst Sie haette das gesagt)" | |
+ | |
+#: src/serverside.c:1069 | |
+#, c-format | |
+msgid " You hear someone playing %s" | |
+msgstr " Du hoerst jemanden %s spielen" | |
+ | |
+#: src/serverside.c:1078 src/serverside.c:1087 src/serverside.c:1096 | |
+#: src/serverside.c:1105 | |
+#, c-format | |
+msgid "YN^Would you like to visit %s?" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1116 | |
+#, c-format | |
+msgid "YN^^Would you like to hire %s %s for %s?" | |
+msgstr "YN^^Willst Du ein %s %s fuer %s anheuern?" | |
+ | |
+#: src/serverside.c:1117 | |
+msgid "an" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1117 | |
+msgid "a" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1129 | |
+#, c-format | |
+msgid "AE^%s is already here!^Do you Attack, or Evade?" | |
+msgstr "" | |
+ | |
+#. Send client "Play" a message announcing the attack of the cops | |
+#. The format string used for this purpose can be altered by | |
+#. passing non-NULL "LoneMessage" (for unaccompanied Officer | |
+#. Hardass) and/or "DeputyMessage" (for him with x deputies) | |
+#: src/serverside.c:1198 | |
+#, c-format | |
+msgid "YN^Officer %s is chasing you!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1200 | |
+#, c-format | |
+msgid "YN^Officer %s and %d of his deputies are chasing you!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1221 | |
+msgid "^Do you run?" | |
+msgstr "^Willst Du rennen?" | |
+ | |
+#: src/serverside.c:1224 | |
+msgid "^Do you Run, or Fight?" | |
+msgstr "^Willst Du Rennen, oder Fighten?" | |
+ | |
+#: src/serverside.c:1239 | |
+#, c-format | |
+msgid "%s: tipoff by %s finished OK." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1245 | |
+#, c-format | |
+msgid "Following your tipoff, the cops ambushed %s, who was shot dead" | |
+msgstr "" | |
+"Nach deinem Tip haben die Cops %s gefunden, er wurde leider erschossen." | |
+ | |
+#: src/serverside.c:1249 | |
+#, c-format | |
+msgid "Following your tipoff, the cops ambushed %s, who escaped with %d %s. " | |
+msgstr "" | |
+"Nach deinem Tip haben die Cops %s gefunden, Leider, konnte %d entkommen mit " | |
+"%s." | |
+ | |
+#: src/serverside.c:1286 | |
+msgid "^You stand there like an idiot." | |
+msgstr "^Du stehst rum wie ein IDIOT." | |
+ | |
+#: src/serverside.c:1290 | |
+msgid "^You lose him in the alleys." | |
+msgstr "^Du konntest ihnen entkommen." | |
+ | |
+#: src/serverside.c:1292 | |
+msgid "^You lose them in the alleys." | |
+msgstr "^Du konntest ihnen entkommen." | |
+ | |
+#: src/serverside.c:1300 | |
+msgid "^You can't shake him, man!" | |
+msgstr "^Du kannst ihn nicht taeuschen!" | |
+ | |
+#: src/serverside.c:1302 | |
+msgid "^You can't shake them, man!" | |
+msgstr "^Du kannst sie nicht verarschen!" | |
+ | |
+#: src/serverside.c:1313 | |
+#, c-format | |
+msgid "^You killed Officer %s! You find %s on his corpse!" | |
+msgstr "^Du hast %s erschossen! Du findest %s in seinen Sachen!" | |
+ | |
+#: src/serverside.c:1327 | |
+#, c-format | |
+msgid "YN^^^^Do you pay a doctor %s to sew your %s up?" | |
+msgstr "YN^^^^Willst du den Dok %s bezahlen um %s zu heilen?" | |
+ | |
+#: src/serverside.c:1331 | |
+#, c-format | |
+msgid "YN^^^^Do you pay a doctor %s to sew you up?" | |
+msgstr "YN^^^^Willst du den Dok %s bezahlen um zu heilen?" | |
+ | |
+#: src/serverside.c:1342 | |
+msgid "^You got one, man!" | |
+msgstr "^Jo, du hast einen erwischt!" | |
+ | |
+#: src/serverside.c:1345 | |
+msgid "^You missed!" | |
+msgstr "^Daneben, du Dumpfbacke!" | |
+ | |
+#: src/serverside.c:1349 | |
+msgid "^He's firing on you, man! " | |
+msgstr "^Die schiessen auf dich, Alter! " | |
+ | |
+#: src/serverside.c:1351 | |
+msgid "^They're firing on you, man! " | |
+msgstr "^Die schiessen auf dich, Alter! " | |
+ | |
+#: src/serverside.c:1354 | |
+msgid "You've been hit! " | |
+msgstr "Du wurdest getroffen! " | |
+ | |
+#: src/serverside.c:1361 | |
+msgid "He wasted you, man! What a drag!" | |
+msgstr " Du wurdest weggeputzt! Was fuer eine Schande!" | |
+ | |
+#: src/serverside.c:1363 | |
+msgid "They wasted you, man! What a drag!" | |
+msgstr " Du wurdest weggeputzt! Was fuer eine Schande!" | |
+ | |
+#: src/serverside.c:1371 | |
+#, c-format | |
+msgid "You lost one of your %s!" | |
+msgstr "Du hast eine deiner %s verloren!" | |
+ | |
+#: src/serverside.c:1380 | |
+msgid "He missed!" | |
+msgstr "Die haben dich verfehlt!" | |
+ | |
+#: src/serverside.c:1382 | |
+msgid "They missed!" | |
+msgstr "Die haben dich verfehlt!" | |
+ | |
+#: src/serverside.c:1402 | |
+msgid "You were mugged in the subway!" | |
+msgstr "Du wurdest in der U-Bahn ausgeraubt!" | |
+ | |
+#: src/serverside.c:1413 | |
+#, c-format | |
+msgid "You meet a friend! He gives you %d %s." | |
+msgstr "Du triffst einen Freund! Er gibt dir %d %s." | |
+ | |
+#: src/serverside.c:1418 | |
+#, c-format | |
+msgid "You meet a friend! You give him %d %s." | |
+msgstr "Du triffst einen Freund! Du gibst ihm %d %s." | |
+ | |
+#: src/serverside.c:1425 | |
+msgid "Sanitized away a RandomOffer" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1430 | |
+#, c-format | |
+msgid "" | |
+"Police dogs chase you for %d blocks! You dropped some %s! That's a drag, man!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1444 | |
+#, c-format | |
+msgid "You find %d %s on a dead dude in the subway!" | |
+msgstr "Du findest %d %s bei einem toten Penner in der U-Bahn!" | |
+ | |
+#: src/serverside.c:1456 | |
+#, c-format | |
+msgid "Your mama made brownies with some of your %s! They were great!" | |
+msgstr "Deine Ma hat brownies gemacht aus deinem %s! Die waren super!" | |
+ | |
+#: src/serverside.c:1464 | |
+msgid "" | |
+"YN^There is some weed that smells like paraquat here!^It looks good! Will " | |
+"you smoke it? " | |
+msgstr "YN^Irgendwas riecht hier gut!^Sieht gut aus! Willst Du es rauchen?" | |
+ | |
+#: src/serverside.c:1471 | |
+#, c-format | |
+msgid "You stopped to %s." | |
+msgstr "Du hoerst auf zu" | |
+ | |
+#: src/serverside.c:1492 | |
+#, c-format | |
+msgid "Would you like to buy a bigger trenchcoat for %s?" | |
+msgstr "Moechtest Du ein groesseren Trenchcoat fuer %s kaufen?" | |
+ | |
+#: src/serverside.c:1497 | |
+#, c-format | |
+msgid "YN^Hey dude! I'll help carry your %s for a mere %s. Yes or no?" | |
+msgstr "YN^Hey Dude! Ich trage %s fuer %s." | |
+ | |
+#: src/serverside.c:1509 | |
+#, c-format | |
+msgid "YN^Would you like to buy a %s for %s?" | |
+msgstr "YN^Willst Du eine %s fuer %s kaufen?" | |
+ | |
+#: src/serverside.c:1610 src/serverside.c:1721 | |
+#, c-format | |
+msgid "%s: offer was on behalf of %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1613 | |
+#, c-format | |
+msgid "%s has accepted your %s!^Use the G key to contact your spy." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1659 | |
+msgid "" | |
+"You hallucinated for three days on the wildest trip you ever imagined!^Then " | |
+"you died because your brain disintegrated!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1698 | |
+#, c-format | |
+msgid "Too late - %s has just left!" | |
+msgstr "Zu Spaet - %s hat sich verpisst!" | |
+ | |
+#: src/serverside.c:1724 | |
+#, c-format | |
+msgid "%s has rejected your %s!" | |
+msgstr "%s hat deine %s abgelehnt!" | |
+ | |
+#: src/serverside.c:1759 | |
+#, c-format | |
+msgid "%s has got away!" | |
+msgstr "%s ist abgehauen!" | |
+ | |
+#: src/serverside.c:1800 | |
+#, c-format | |
+msgid "%s has run off!" | |
+msgstr "%s ist abgehauen!" | |
+ | |
+#: src/serverside.c:1812 | |
+msgid "Coward! You successfully escaped from the fight." | |
+msgstr "Feigling! Du bist mal wieder erfolgreich entkommen." | |
+ | |
+#: src/serverside.c:1868 | |
+msgid "pitifully armed" | |
+msgstr "ist kaum bewaffnet" | |
+ | |
+#: src/serverside.c:1869 | |
+msgid "lightly armed" | |
+msgstr "ist leicht bewaffnet" | |
+ | |
+#: src/serverside.c:1870 | |
+msgid "moderately well armed" | |
+msgstr "ist gut bewaffnet" | |
+ | |
+#: src/serverside.c:1871 | |
+msgid "heavily armed" | |
+msgstr "ist schwer bewaffnet" | |
+ | |
+#: src/serverside.c:1872 | |
+msgid "armed to the teeth" | |
+msgstr "ist bis zu den Zaehnen bewaffnet" | |
+ | |
+#: src/serverside.c:1873 | |
+msgid " fires and " | |
+msgstr " feuert und " | |
+ | |
+#: src/serverside.c:1874 | |
+msgid " stands and takes it." | |
+msgstr " steht rum und kriegts voll ab." | |
+ | |
+#: src/serverside.c:1877 | |
+#, c-format | |
+msgid "%s arrives, with %d %s, %s,^%s" | |
+msgstr "%s trifft ein mit %d %s, %s,^%s" | |
+ | |
+#: src/serverside.c:1881 | |
+#, c-format | |
+msgid "%s arrives, %s,^%s" | |
+msgstr "%s trifft, %s,^%s" | |
+ | |
+#: src/serverside.c:1886 | |
+#, c-format | |
+msgid "%s fires and " | |
+msgstr "%s feuert und " | |
+ | |
+#: src/serverside.c:1888 | |
+#, c-format | |
+msgid "%s stands and takes it." | |
+msgstr "%s steht rum und kriegts voll ab." | |
+ | |
+#: src/serverside.c:1900 | |
+msgid "misses you!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1901 | |
+#, c-format | |
+msgid "You failed to hit %s." | |
+msgstr "Du Idiot hast an %s vorbei geschossen." | |
+ | |
+#: src/serverside.c:1904 | |
+msgid "You stand and take it." | |
+msgstr "Du stehst rum und kassierst Treffer." | |
+ | |
+#: src/serverside.c:1908 | |
+msgid "hits you, man!" | |
+msgstr "trifft Dich!" | |
+ | |
+#: src/serverside.c:1911 | |
+msgid " You've been wasted! What a drag!" | |
+msgstr " Du wurdest weggeputzt! Was fuer eine Schande!" | |
+ | |
+#: src/serverside.c:1912 | |
+#, c-format | |
+msgid "You hit and killed %s" | |
+msgstr "Du triffst und %s stirbt" | |
+ | |
+#: src/serverside.c:1927 src/serverside.c:1960 | |
+msgid ", and loot the body!" | |
+msgstr ", und oeffnest den Koerper!" | |
+ | |
+#: src/serverside.c:1936 | |
+#, c-format | |
+msgid "^You lost a %s, man!" | |
+msgstr "^Du hast eine %s verloren, Kleiner!" | |
+ | |
+#: src/serverside.c:1941 | |
+#, c-format | |
+msgid "You are paid a bounty of %s in reward for killing^one of %s's %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1949 | |
+#, c-format | |
+msgid "You killed one of %s's %s (%d left)" | |
+msgstr "Du hast eine %s von %s getoetet (%d hat er noch)" | |
+ | |
+#: src/serverside.c:1967 | |
+#, c-format | |
+msgid "You fire, and hit %s!" | |
+msgstr "Du schiesst, und triffst %s!" | |
+ | |
+#: src/serverside.c:2006 | |
+msgid "YN^Officer %%s spots you dropping %s, and chases you!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:2008 | |
+msgid "" | |
+"YN^Officer %%s and %%d of his deputies spot you dropping %s, and chase you!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:2163 | |
+msgid "Player removed due to idle timeout" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:2173 | |
+msgid "Player removed due to connect timeout" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:2179 src/serverside.c:2185 | |
+#, c-format | |
+msgid "%s fails to return fire..." | |
+msgstr "%s vergisst sich zu wehren..." | |
+ | |
+#: src/message.c:370 | |
+#, c-format | |
+msgid "" | |
+"This server is version %s, while your client is version %s.\n" | |
+"Be warned that different versions may not be fully compatible!\n" | |
+"Refer to the website at http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/\n" | |
+"for the latest version." | |
+msgstr "" | |
+"Dieser Server hat Version %s, dein Klient hat Version %s.^Sei gewarnt, beide " | |
+"Versionen sind nicht zu einander kompatibel!^Schau mal auf " | |
+"http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ nach^dort findest Du die neuste " | |
+"Version." | |
+ | |
+#: src/message.c:505 | |
+msgid "Could not find host" | |
+msgstr "" | |
+ | |
+#: src/message.c:506 | |
+msgid "Could not create network socket" | |
+msgstr "" | |
+ | |
+#: src/message.c:507 | |
+msgid "Connection refused or no server present" | |
+msgstr "" | |
+ | |
+#: src/message.c:663 | |
+msgid "Cannot locate metaserver" | |
+msgstr "" | |
+ | |
+#: src/message.c:664 | |
+msgid "Cannot create socket" | |
+msgstr "" | |
+ | |
+#: src/message.c:666 | |
+msgid "Metaserver not running HTTP or connection denied" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:58 | |
+#, c-format | |
+msgid "AI Player started; attempting to contact server at %s:%d..." | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:61 | |
+#, c-format | |
+msgid "" | |
+"Could not connect to dopewars server\n" | |
+"(%s)\n" | |
+"AI Player terminating abnormally." | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:65 | |
+msgid "Connection established\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:85 | |
+msgid "Connection to server lost!\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:98 | |
+msgid "AI Player terminated OK.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:111 | |
+#, c-format | |
+msgid "Using name %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:130 | |
+msgid "Players in this game:-\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:160 | |
+#, c-format | |
+msgid "%s joins the game.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:163 | |
+#, c-format | |
+msgid "%s has left the game.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:171 | |
+#, c-format | |
+msgid "Jetting to %s with %s cash and %s debt" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:191 | |
+msgid "AI Player killed. Terminating normally.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:212 | |
+msgid "Game time is up. Leaving game.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:216 | |
+msgid "AI Player pushed from the server.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:220 | |
+msgid "The server has terminated.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:276 | |
+#, c-format | |
+msgid "Selling %d %s at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:292 | |
+#, c-format | |
+msgid "Buying %d %s at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:321 | |
+#, c-format | |
+msgid "Buying a %s for %s at the gun shop\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:361 | |
+#, c-format | |
+msgid "Debt of %s paid off to loan shark\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:386 | |
+#, c-format | |
+msgid "Loan shark located at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:394 | |
+#, c-format | |
+msgid "Gun shop located at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:402 | |
+#, c-format | |
+msgid "Pub located at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:415 | |
+#, c-format | |
+msgid "Bank located at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:439 | |
+msgid "Call yourselves drug dealers?" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:440 | |
+msgid "A trained monkey could do better..." | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:441 | |
+msgid "Think you're hard enough to deal with the likes of me?" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:442 | |
+msgid "Zzzzz... are you dealing in candy or what?" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:443 | |
+msgid "Reckon I'll just have to shoot you for your own good." | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:452 | |
+msgid "" | |
+"This binary has been compiled without networking support, and thus cannot " | |
+"act as an AI player.\n" | |
+"Recompile passing --enable-networking to the configure script." | |
+msgstr "" | |
+ | |
+#~ msgid "him" | |
+#~ msgstr "ihnen" | |
+ | |
+#~ msgid "them" | |
+#~ msgstr "ihnen" | |
+ | |
+#~ msgid "He's" | |
+#~ msgstr "Die" | |
+ | |
+#~ msgid "They're" | |
+#~ msgstr "Die" | |
diff --git a/po/dopewars.pot b/po/dopewars.pot | |
t@@ -0,0 +1,2676 @@ | |
+# SOME DESCRIPTIVE TITLE. | |
+# Copyright (C) YEAR Free Software Foundation, Inc. | |
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
+# | |
+#, fuzzy | |
+msgid "" | |
+msgstr "" | |
+"Project-Id-Version: PACKAGE VERSION\n" | |
+"POT-Creation-Date: 2000-09-10 04:08+0100\n" | |
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | |
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |
+"Language-Team: LANGUAGE <[email protected]>\n" | |
+"MIME-Version: 1.0\n" | |
+"Content-Type: text/plain; charset=CHARSET\n" | |
+"Content-Transfer-Encoding: ENCODING\n" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "bitch" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "bitches" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "gun" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "guns" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "drug" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:108 | |
+msgid "drugs" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:109 | |
+msgid "12-" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:109 | |
+msgid "-1984" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:110 | |
+msgid "Hardass" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:110 | |
+msgid "Bob" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:110 | |
+msgid "the Loan Shark" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:110 | |
+msgid "the Bank" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:111 | |
+msgid "Dan's House of Guns" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:111 | |
+msgid "the pub" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:127 | |
+msgid "Network port to connect to" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:130 | |
+msgid "Name of the high score file" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:131 | |
+msgid "Name of the server to connect to" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:134 | |
+msgid "Non-zero if server should report to a metaserver" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:137 | |
+msgid "Port for metaserver communication (client)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:140 | |
+msgid "Port for metaserver communication (server)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:143 | |
+msgid "Metaserver name to report server details to" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:146 | |
+msgid "Path of the CGI script on the metaserver (client)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:149 | |
+msgid "Preferred hostname of your server machine" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:151 | |
+msgid "Authentication for LocalName with the metaserver" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:154 | |
+msgid "Server description, reported to the metaserver" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:157 | |
+msgid "Program used to display multi-page output" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:159 | |
+msgid "No. of game turns (if 0, game never ends)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:161 | |
+msgid "Random events are sanitized" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:164 | |
+msgid "Be verbose in processing config file" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:166 | |
+msgid "Number of locations in the game" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:169 | |
+msgid "Number of guns in the game" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:171 | |
+msgid "Number of drugs in the game" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:173 | |
+msgid "Location of the Loan Shark" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:175 | |
+msgid "Location of the bank" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:177 | |
+msgid "Location of the gun shop" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:179 | |
+msgid "Location of the pub" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:182 | |
+msgid "Name of the loan shark" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:184 | |
+msgid "Name of the bank" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:186 | |
+msgid "Name of the gun shop" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:188 | |
+msgid "Name of the pub" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:190 | |
+msgid "Sort key for listing available drugs" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:193 | |
+msgid "No. of seconds in which to return fire" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:196 | |
+msgid "Players are disconnected after this many seconds" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:199 | |
+msgid "Time in seconds for connections to be made or broken" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:202 | |
+msgid "Maximum number of TCP/IP connections" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:205 | |
+msgid "Seconds between turns of AI players" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:208 | |
+msgid "Amount of cash that each player starts with" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:211 | |
+msgid "Amount of debt that each player starts with" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:213 | |
+msgid "Name of each location" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:217 | |
+msgid "Police presence at each location (%)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:221 | |
+msgid "Minimum number of drugs at each location" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:225 | |
+msgid "Maximum number of drugs at each location" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:229 | |
+msgid "Name of each drug" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:233 | |
+msgid "Minimum normal price of each drug" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:237 | |
+msgid "Maximum normal price of each drug" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:241 | |
+msgid "Non-zero if this drug can be specially cheap" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:245 | |
+msgid "Non-zero if this drug can be specially expensive" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:249 | |
+msgid "Message displayed when this drug is specially cheap" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:253 src/dopewars.c:256 | |
+#, c-format | |
+msgid "Format string used for expensive drugs 50% of time" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:259 | |
+msgid "Divider for drug price when it's specially cheap" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:262 | |
+msgid "Multiplier for specially expensive drug prices" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:265 | |
+msgid "Name of each gun" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:269 | |
+msgid "Price of each gun" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:273 | |
+msgid "Space taken by each gun" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:277 | |
+msgid "Damage done by each gun" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:281 | |
+#, c-format | |
+msgid "% probability of escaping from Officer Hardass" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:284 | |
+msgid "Modifier to EscapeProb for each extra deputy" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:287 | |
+#, c-format | |
+msgid "% probability that Officer Hardass hits you" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:290 | |
+msgid "Modifier to HitProb for each extra deputy" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:293 | |
+msgid "Maximum damage done to you by each cop" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:296 | |
+msgid "Toughness of (difficulty of hitting) each cop" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:299 | |
+#, c-format | |
+msgid "% probability that the cops catch you dropping drugs" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:302 | |
+msgid "Word used to denote a single \"bitch\"" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:304 | |
+msgid "Word used to denote two or more \"bitches\"" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:307 | |
+msgid "Word used to denote a single gun or equivalent" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:310 | |
+msgid "Word used to denote two or more guns" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:312 | |
+msgid "Word used to denote a single drug or equivalent" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:315 | |
+msgid "Word used to denote two or more drugs" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:317 | |
+msgid "Text prefixed to the turn number (i.e. the month)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:320 | |
+msgid "Text appended to the turn number (i.e. the year)" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:323 | |
+msgid "Name of the police officer" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:325 | |
+msgid "Name of the reserve police officer" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:327 | |
+msgid "Cost for a bitch to spy on the enemy" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:330 | |
+msgid "Cost for a bitch to tipoff the cops to an enemy" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:333 | |
+msgid "Minimum price to hire a bitch" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:336 | |
+msgid "Maximum price to hire a bitch" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:339 | |
+msgid "List of things which you overhear on the subway" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:342 | |
+msgid "Number of subway sayings" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:345 | |
+msgid "List of songs which you can hear playing" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:348 | |
+msgid "Number of playing songs" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:351 | |
+msgid "List of things which you can stop to do" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:354 | |
+msgid "Number of things which you can stop to do" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:359 | |
+msgid "escaped" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:359 | |
+msgid "defected" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:359 | |
+msgid "was shot" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:363 | |
+msgid "`Are you Experienced` by Jimi Hendrix" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:364 | |
+msgid "`Cheeba Cheeba` by Tone Loc" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:365 | |
+msgid "`Comin` in to Los Angeles` by Arlo Guthrie" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:366 | |
+msgid "`Commercial` by Spanky and Our Gang" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:367 | |
+msgid "`Late in the Evening` by Paul Simon" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:368 | |
+msgid "`Light Up` by Styx" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:369 | |
+msgid "`Mexico` by Jefferson Airplane" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:370 | |
+msgid "`One toke over the line` by Brewer & Shipley" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:371 | |
+msgid "`The Smokeout` by Shel Silverstein" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:372 | |
+msgid "`White Rabbit` by Jefferson Airplane" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:373 | |
+msgid "`Itchycoo Park` by Small Faces" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:374 | |
+msgid "`White Punks on Dope` by the Tubes" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:375 | |
+msgid "`Legend of a Mind` by the Moody Blues" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:376 | |
+msgid "`Eight Miles High` by the Byrds" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:377 | |
+msgid "`Acapulco Gold` by Riders of the Purple Sage" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:378 | |
+msgid "`Kicks` by Paul Revere & the Raiders" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:379 | |
+msgid "the Nixon tapes" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:380 | |
+msgid "`Legalize It` by Mojo Nixon & Skid Roper" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:385 | |
+msgid "have a beer" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:386 | |
+msgid "smoke a joint" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:387 | |
+msgid "smoke a cigar" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:388 | |
+msgid "smoke a Djarum" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:389 | |
+msgid "smoke a cigarette" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:393 | |
+msgid "Baretta" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:394 | |
+msgid ".38 Special" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:395 | |
+msgid "Ruger" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:396 | |
+msgid "Saturday Night Special" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:400 | |
+msgid "Bronx" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:401 | |
+msgid "Ghetto" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:402 | |
+msgid "Central Park" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:403 | |
+msgid "Manhattan" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:404 | |
+msgid "Coney Island" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:405 | |
+msgid "Brooklyn" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:406 | |
+msgid "Queens" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:407 | |
+msgid "Staten Island" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:411 | |
+msgid "Acid" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:412 | |
+msgid "The market is flooded with cheap home-made acid!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:413 | |
+msgid "Cocaine" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:414 | |
+msgid "Hashish" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:414 | |
+msgid "The Marrakesh Express has arrived!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:415 | |
+msgid "Heroin" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:416 | |
+msgid "Ludes" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:417 | |
+msgid "Rival drug dealers raided a pharmacy and are selling cheap ludes!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:418 | |
+msgid "MDA" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:419 | |
+msgid "Opium" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:420 | |
+msgid "PCP" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:421 | |
+msgid "Peyote" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:422 | |
+msgid "Shrooms" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:423 | |
+msgid "Speed" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:424 | |
+msgid "Weed" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:424 | |
+msgid "" | |
+"Columbian freighter dusted the Coast Guard! Weed prices have bottomed out!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:430 | |
+#, c-format | |
+msgid "Cops made a big %s bust! Prices are outrageous!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:431 | |
+#, c-format | |
+msgid "Addicts are buying %s at ridiculous prices!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:436 | |
+msgid "Wouldn't it be funny if everyone suddenly quacked at once?" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:437 | |
+msgid "The Pope was once Jewish, you know" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:438 | |
+msgid "I'll bet you have some really interesting dreams" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:439 | |
+msgid "So I think I'm going to Amsterdam this year" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:440 | |
+msgid "Son, you need a yellow haircut" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:441 | |
+msgid "I think it's wonderful what they're doing with incense these days" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:442 | |
+msgid "I wasn't always a woman, you know" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:443 | |
+msgid "Does your mother know you're a dope dealer?" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:444 | |
+msgid "Are you high on something?" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:445 | |
+msgid "Oh, you must be from California" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:446 | |
+msgid "I used to be a hippie, myself" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:447 | |
+msgid "There's nothing like having lots of money" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:448 | |
+msgid "You look like an aardvark!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:449 | |
+msgid "I don't believe in Ronald Reagan" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:450 | |
+msgid "Courage! Bush is a noodle!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:451 | |
+msgid "Haven't I seen you on TV?" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:452 | |
+msgid "I think hemorrhoid commercials are really neat!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:453 | |
+msgid "We're winning the war for drugs!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:454 | |
+msgid "A day without dope is like night" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:455 | |
+#, c-format | |
+msgid "We only use 20% of our brains, so why not burn out the other 80%" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:456 | |
+msgid "I'm soliciting contributions for Zombies for Christ" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:457 | |
+msgid "I'd like to sell you an edible poodle" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:458 | |
+msgid "Winners don't do drugs... unless they do" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:459 | |
+msgid "Kill a cop for Christ!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:460 | |
+msgid "I am the walrus!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:461 | |
+msgid "Jesus loves you more than you will know" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:462 | |
+msgid "I feel an unaccountable urge to dye my hair blue" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:463 | |
+msgid "Wasn't Jane Fonda wonderful in Barbarella" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:464 | |
+msgid "Just say No... well, maybe... ok, what the hell!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:465 | |
+msgid "Would you like a jelly baby?" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:466 | |
+msgid "Drugs can be your friend!" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1073 | |
+msgid "Unable to process configuration file line" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1134 | |
+msgid "" | |
+"Configuration can only be changed interactively when no\n" | |
+"players are logged on. Wait for all players to log off, or remove\n" | |
+"them with the push or kill commands, and try again." | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1195 | |
+#, c-format | |
+msgid "Index into %s array should be between 1 and %d" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1214 | |
+#, c-format | |
+msgid "%s is %d\n" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1219 | |
+#, c-format | |
+msgid "%s is %s\n" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1222 | |
+#, c-format | |
+msgid "%s is \"%s\"\n" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1226 | |
+#, c-format | |
+msgid "%s[%d] is %s\n" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1229 | |
+#, c-format | |
+msgid "%s is { " | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1260 | |
+#, c-format | |
+msgid "Resized structure list to %d elements\n" | |
+msgstr "" | |
+ | |
+#: src/dopewars.c:1403 | |
+#, c-format | |
+msgid "" | |
+"Usage: dopewars [OPTION]...\n" | |
+"Drug dealing game based on \"Drug Wars\" by John E. Dell\n" | |
+" -b \"black and white\" - i.e. do not use pretty colours\n" | |
+" (by default colours are used where the terminal supports " | |
+"them)\n" | |
+" -n be boring and don't connect to any available dopewars servers\n" | |
+" (i.e. single player mode)\n" | |
+" -a \"antique\" dopewars - keep as closely to the original version " | |
+"as\n" | |
+" possible (this also disables any networking)\n" | |
+" -f file specify a file to use as the high score table\n" | |
+" (by default %s/dopewars.sco is used)\n" | |
+" -o addr specify a hostname where the server for multiplayer dopewars\n" | |
+" can be found (in human-readable - e.g. nowhere.com - format)\n" | |
+" -s run in server mode (note: for a \"non-interactive\" server, " | |
+"simply\n" | |
+" run as dopewars -s < /dev/null >> logfile & )\n" | |
+" -S run a \"private\" server (i.e. do not notify the metaserver)\n" | |
+" -p specify the network port to use (default: 7902)\n" | |
+" -g file specify the pathname of a dopewars configuration file. This file\n" | |
+" is read immediately when the -g option is encountered\n" | |
+" -r file maintain pid file \"file\" while running the server\n" | |
+" -c create and run a computer player\n" | |
+" -w force the use of a graphical (windowed) client (GTK+ or Win32)\n" | |
+" -t force the use of a text-mode client (curses)\n" | |
+" (by default, a windowed client is used when possible)\n" | |
+" -h display this help information\n" | |
+" -v output version information and exit\n" | |
+"\n" | |
+"dopewars is Copyright (C) Ben Webb 1998-2000, and released under the GNU " | |
+"GPL\n" | |
+"Report bugs to the author at [email protected]\n" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:134 | |
+msgid "D O P E W A R S" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:139 | |
+msgid "" | |
+"Based on John E. Dell's old Drug Wars game, dopewars is a simulation of an" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:141 | |
+msgid "imaginary drug market. dopewars is an All-American game which features" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:143 | |
+msgid "buying, selling, and trying to get past the cops!" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:145 | |
+msgid "" | |
+"The first thing you need to do is pay off your debt to the Loan Shark. After" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:147 | |
+msgid "" | |
+"that, your goal is to make as much money as possible (and stay alive)! You" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:149 | |
+msgid "have one month of game time to make your fortune." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:151 | |
+msgid "Copyright (C) 1998-2000 Ben Webb [email protected]" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:153 | |
+#, c-format | |
+msgid "Version %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:156 | |
+msgid "dopewars is released under the GNU General Public Licence" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:159 | |
+msgid "Drug Dealing and Research Dan Wolf" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:160 | |
+msgid "Play Testing Phil Davis Owen Walsh" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:162 | |
+msgid "Extensive Play Testing Katherine Holt Caroline Moore" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:164 | |
+msgid "Constructive Criticism Andrea Elliot-Smith Pete Winn" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:166 | |
+msgid "Unconstructive Criticism James Matthews" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:168 | |
+msgid "For information on the command line options, type dopewars -h at your" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:170 | |
+msgid "" | |
+"Unix prompt. This will display a help screen, listing the available options." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:186 | |
+msgid "Please enter the hostname and port of a dopewars server:-" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:187 | |
+msgid "Hostname: " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:190 | |
+msgid "Port: " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:206 | |
+msgid "No servers listed on metaserver" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:210 | |
+msgid "Please wait... attempting to contact metaserver..." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:218 | |
+msgid "Connection to metaserver established. Obtaining server list..." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:231 | |
+#, c-format | |
+msgid "Server : %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:233 | |
+#, c-format | |
+msgid "Port : %d" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:235 | |
+#, c-format | |
+msgid "Version : %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:238 | |
+#, c-format | |
+msgid "Players: -unknown- (maximum %d)" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:241 | |
+#, c-format | |
+msgid "Players: %d (maximum %d)" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:245 | |
+#, c-format | |
+msgid "Up since : %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:247 | |
+#, c-format | |
+msgid "Comment: %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:251 | |
+msgid "N>ext server; P>revious server; S>elect this server... " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:252 | |
+msgid "NPS" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:298 | |
+msgid "Please wait... attempting to contact dopewars server..." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:305 | |
+#, c-format | |
+msgid "Error: %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:308 | |
+msgid "Could not start multiplayer dopewars" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:315 | |
+msgid "Will you... C>onnect to a different host and/or port" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:317 | |
+msgid " L>ist the servers on the metaserver, and select one" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:320 | |
+msgid " Q>uit (where you can start a server by typing " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:323 | |
+msgid " dopewars -s < /dev/null & )" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:324 | |
+msgid " or P>lay single-player ? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:326 | |
+msgid "CLQP" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:363 src/gtk_client.c:795 | |
+msgid "Where to, dude ? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:393 | |
+#, c-format | |
+msgid "You can't get any cash for the following carried %s :" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:406 | |
+msgid "What do you want to drop? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:417 | |
+msgid "How many do you drop? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:446 src/curses_client.c:816 | |
+msgid "What do you wish to buy? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:448 src/curses_client.c:818 | |
+msgid "What do you wish to sell? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:465 | |
+#, c-format | |
+msgid "You can afford %d, and can carry %d. " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:468 | |
+msgid "How many do you buy? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:476 | |
+#, c-format | |
+msgid "You have %d. " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:478 | |
+msgid "How many do you sell? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:501 | |
+#, c-format | |
+msgid "Choose an errand to give one of your %s..." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:507 | |
+#, c-format | |
+msgid " S>py on another dealer (cost: %s)" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:511 | |
+#, c-format | |
+msgid " T>ip off the cops to another dealer (cost: %s)" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:514 | |
+msgid " G>et stuffed" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:517 | |
+msgid "or C>ontact your spies and receive reports" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:519 | |
+msgid "or N>o errand ? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:522 | |
+msgid "STGCN" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:525 | |
+msgid "Whom do you want to spy on? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:530 | |
+msgid "Whom do you want to tip the cops off to? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:535 | |
+msgid " Are you sure? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:536 src/curses_client.c:554 src/curses_client.c:1673 | |
+msgid "YN" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:552 | |
+msgid "Are you sure you want to quit? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:560 | |
+msgid "New name: " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:610 | |
+msgid "You have been pushed from the server. Reverting to single player mode." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:620 | |
+msgid "The server has terminated. Reverting to single player mode." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:635 src/gtk_client.c:328 src/serverside.c:258 | |
+#, c-format | |
+msgid "%s joins the game!" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:640 src/gtk_client.c:334 | |
+#, c-format | |
+msgid "%s has left the game." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:645 | |
+#, c-format | |
+msgid "%s will now be known as %s." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:669 | |
+msgid "S U B W A Y" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:712 | |
+msgid "" | |
+"Unfortunately, somebody else is already using \"your\" name. Please change " | |
+"it." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:734 | |
+msgid "H I G H S C O R E S" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:790 | |
+msgid "Will you B>uy, S>ell, or L>eave? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:795 | |
+msgid "BSL" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:800 | |
+#, c-format | |
+msgid "You don't have any %s to sell!" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:807 src/gtk_client.c:1067 | |
+#, c-format | |
+msgid "You'll need more %s to carry any more %s!" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:829 src/gtk_client.c:1071 | |
+#, c-format | |
+msgid "You don't have enough space to carry that %s!" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:837 src/gtk_client.c:1075 | |
+#, c-format | |
+msgid "You don't have enough cash to buy that %s!" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:850 src/gtk_client.c:1079 | |
+msgid "You don't have any to sell!" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:874 | |
+msgid "How much money do you pay back? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:880 src/curses_client.c:910 src/gtk_client.c:1879 | |
+msgid "You don't have that much money!" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:900 | |
+msgid "Do you want to D>eposit money, W>ithdraw money, or L>eave ? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:903 | |
+msgid "DWL" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:905 | |
+msgid "How much money? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:913 src/gtk_client.c:1872 | |
+msgid "There isn't that much money in the bank..." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:992 | |
+msgid "Press any key..." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1123 | |
+msgid "Messages" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1130 src/gtk_client.c:1362 | |
+msgid "Stats" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1133 | |
+#, c-format | |
+msgid "Cash %17s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1140 | |
+#, c-format | |
+msgid "Health %3d" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1142 | |
+#, c-format | |
+msgid "Bank %17s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1146 | |
+#, c-format | |
+msgid "Debt %17s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1150 | |
+#, c-format | |
+msgid "Space %6d" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1152 | |
+#, c-format | |
+msgid "%s %3d Space %6d" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1163 | |
+msgid "Trenchcoat" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1203 | |
+#, c-format | |
+msgid "Spy reports for %s" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1207 src/curses_client.c:1212 | |
+#, c-format | |
+msgid "%s..." | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1233 | |
+msgid "No other players are currently logged on!" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1238 | |
+msgid "Players currently logged on:-" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1386 | |
+msgid "Hey dude, what's your name? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1419 | |
+#, c-format | |
+msgid "Hey dude, the prices of %s here are:" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1431 | |
+msgid "Will you B>uy" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1432 | |
+msgid ", S>ell" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1433 | |
+msgid ", D>rop" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1434 | |
+msgid ", T>alk, P>age, L>ist" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1437 | |
+msgid ", G>ive" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1440 | |
+msgid ", F>ight" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1444 | |
+msgid ", J>et" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1446 src/curses_client.c:1461 | |
+msgid ", or Q>uit? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1454 | |
+msgid "Do you " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1456 | |
+msgid "F>ight, " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1457 | |
+msgid "S>tand, " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1459 | |
+msgid "R>un, " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1460 | |
+msgid "D>eal " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1503 | |
+msgid "Connection to server lost! Reverting to single player mode" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1532 | |
+msgid "BSDTPLGFJQ" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1534 | |
+msgid "DRFSQ" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1562 | |
+msgid "List what? P>layers or S>cores? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1563 | |
+msgid "PS" | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1572 | |
+msgid "Whom do you want to page (talk privately to) ? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1587 | |
+msgid "Talk: " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1672 | |
+msgid "Play again? " | |
+msgstr "" | |
+ | |
+#: src/curses_client.c:1684 | |
+msgid "" | |
+"No curses client available - rebuild the binary passing the\n" | |
+"--enable-curses-client option to configure, or use a windowed\n" | |
+"client (if available) instead!\n" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:141 | |
+msgid "/_Game" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:142 | |
+msgid "/Game/_New" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:143 | |
+msgid "/Game/_Quit" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:144 | |
+msgid "/_Talk" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:145 | |
+msgid "/Talk/To _All" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:146 | |
+msgid "/Talk/To _Player" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:147 | |
+msgid "/_List" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:148 | |
+msgid "/List/_Players" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:149 | |
+msgid "/List/_Scores" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:150 | |
+msgid "/List/_Inventory" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:151 | |
+msgid "/_Errands" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:152 | |
+msgid "/Errands/_Spy" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:153 | |
+msgid "/Errands/_Tipoff" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:154 | |
+msgid "/Errands/Sack _Bitch" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:155 | |
+msgid "/Errands/_Get spy reports" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:156 | |
+msgid "/_Help" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:157 | |
+msgid "/Help/_About" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:162 | |
+msgid "Warning" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:162 | |
+msgid "Message" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:172 | |
+msgid "Quit Game" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:172 src/gtk_client.c:181 | |
+msgid "Abandon current game?" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:180 | |
+msgid "Start new game" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:202 | |
+msgid "Inventory" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:230 src/gtk_client.c:2115 src/gtk_client.c:2483 | |
+msgid "Close" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:260 | |
+msgid "Connection to server lost - switching to single player mode" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:302 | |
+msgid "You have been pushed from the server." | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:307 | |
+msgid "The server has terminated." | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:347 | |
+#, c-format | |
+msgid "Jetting to %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:352 | |
+msgid "<main>/Errands/Spy" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:354 | |
+#, c-format | |
+msgid "_Spy\t(%s)" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:358 | |
+#, c-format | |
+msgid "_Tipoff\t(%s)" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:360 | |
+msgid "<main>/Errands/Tipoff" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:393 | |
+msgid "High Scores" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:427 src/gtk_client.c:1018 src/gtk_client.c:1475 | |
+#: src/gtk_client.c:1788 src/gtk_client.c:1953 src/gtk_client.c:2232 | |
+#: src/gtk_client.c:2390 | |
+msgid "OK" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:506 | |
+msgid "Fight" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:533 | |
+#, c-format | |
+msgid "_Deal %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:537 src/gtk_client.c:1111 src/gtk_client.c:1307 | |
+msgid "_Fight" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:540 | |
+msgid "_Stand" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:543 src/gtk_client.c:1110 | |
+msgid "_Run" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:786 | |
+msgid "Jet to location" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:851 | |
+#, c-format | |
+msgid "at %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:856 | |
+#, c-format | |
+msgid "You are currently carrying %d %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:861 | |
+#, c-format | |
+msgid "Available space: %d" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:866 | |
+#, c-format | |
+msgid "You can afford %d" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:916 src/gtk_client.c:1047 | |
+msgid "Buy" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:917 src/gtk_client.c:1048 | |
+msgid "Sell" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:918 src/gtk_client.c:1049 | |
+msgid "Drop" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1006 | |
+#, c-format | |
+msgid "%s how many?" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1024 src/gtk_client.c:1788 src/gtk_client.c:1964 | |
+#: src/gtk_client.c:2240 | |
+msgid "Cancel" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1063 | |
+#, c-format | |
+msgid "You don't have any %s!" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1110 src/gtk_client.c:1789 | |
+msgid "_Yes" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1110 src/gtk_client.c:1789 | |
+msgid "_No" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1111 | |
+msgid "_Attack" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1111 | |
+msgid "_Evade" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1129 | |
+msgid "Question" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1237 | |
+msgid "<main>/Talk" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1239 | |
+msgid "<main>/List" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1241 | |
+msgid "<main>/Errands" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1257 | |
+msgid "Space" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1262 | |
+msgid "Cash" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1267 | |
+msgid "Debt" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1272 | |
+msgid "Bank" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1287 | |
+msgid "Health" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1307 | |
+msgid "_Jet!" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1338 | |
+msgid "dopewars" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1422 | |
+msgid "Drug Dealing and Research" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1423 | |
+msgid "Play Testing" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1424 | |
+msgid "Extensive Play Testing" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1426 | |
+msgid "Constructive Criticism" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1428 | |
+msgid "Unconstructive Criticism" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1432 | |
+msgid "About dopewars" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1441 | |
+msgid "" | |
+"Based on John E. Dell's old Drug Wars game, dopewars is a simulation of an\n" | |
+"imaginary drug market. dopewars is an All-American game which features\n" | |
+"buying, selling, and trying to get past the cops!\n" | |
+"\n" | |
+"The first thing you need to do is pay off your debt to the Loan Shark. " | |
+"After\n" | |
+"that, your goal is to make as much money as possible (and stay alive)! You\n" | |
+"have one month of game time to make your fortune.\n" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1449 | |
+#, c-format | |
+msgid "" | |
+"Version %s Copyright (C) 1998-2000 Ben Webb [email protected]\n" | |
+"dopewars is released under the GNU General Public Licence\n" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1467 | |
+msgid "" | |
+"\n" | |
+"For information on the command line options, type dopewars -h at your\n" | |
+"Unix prompt. This will display a help screen, listing the availableoptions." | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1505 src/gtk_client.c:1590 | |
+msgid "Status: Attempting to contact server..." | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1511 src/gtk_client.c:1596 | |
+#, c-format | |
+msgid "Status: Could not connect (%s)" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1545 | |
+#, c-format | |
+msgid "%d of %d" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1612 src/gtk_client.c:1649 src/gtk_client.c:1690 | |
+msgid "Server" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1613 src/gtk_client.c:1664 | |
+msgid "Port" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1614 | |
+msgid "Version" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1615 | |
+msgid "Players" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1616 | |
+msgid "Comment" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1625 | |
+msgid "New Game" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1634 | |
+msgid "Hey dude, what's your _name?" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1656 | |
+msgid "Host name" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1679 src/gtk_client.c:1742 | |
+msgid "_Connect" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1692 src/gtk_client.c:1713 | |
+msgid "Single player" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1698 | |
+msgid "_Antique mode" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1705 | |
+msgid "_Start single-player game" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1715 src/gtk_client.c:1753 | |
+msgid "Metaserver" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1732 | |
+msgid "_Update" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1757 | |
+msgid "Status: Waiting for user input" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1910 | |
+#, c-format | |
+msgid "Cash: %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1917 | |
+#, c-format | |
+msgid "Debt: %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1920 | |
+#, c-format | |
+msgid "Bank: %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1928 | |
+msgid "Pay back:" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1931 | |
+msgid "Deposit" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1935 | |
+msgid "Withdraw" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1959 | |
+msgid "Pay all" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:1981 | |
+msgid "Player List" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2070 | |
+msgid "Talk to player(s)" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2092 | |
+msgid "Talk to all players" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2096 | |
+msgid "Message:-" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2109 | |
+msgid "Send" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2202 | |
+msgid "Spy On Player" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2204 | |
+#, c-format | |
+msgid "" | |
+"Please choose the player to spy on. Your %s will\n" | |
+"then offer his services to the player, and if successful,\n" | |
+"you will be able to view the player's stats with the\n" | |
+"\"Get spy reports\" menu. Remember that the %s will leave\n" | |
+"you, so any %s or %s that he's carrying may be lost!" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2212 | |
+msgid "Tip Off The Cops" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2214 | |
+#, c-format | |
+msgid "" | |
+"Please choose the player to tip off the cops to. Your %s will\n" | |
+"help the cops to attack that player, and then report back to you\n" | |
+"on the encounter. Remember that the %s will leave you temporarily,\n" | |
+"so any %s or %s that he's carrying may be lost!" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2254 | |
+#, c-format | |
+msgid "Sack %s" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2255 | |
+#, c-format | |
+msgid "" | |
+"Are you sure? (Any %s or %s carried\n" | |
+"by this %s may be lost!)" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2276 | |
+msgid "Name" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2277 | |
+msgid "Price" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2278 | |
+msgid "Number" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2280 | |
+msgid "_Buy ->" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2281 | |
+msgid "<- _Sell" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2282 | |
+msgid "_Drop <-" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2287 | |
+#, c-format | |
+msgid "%s here" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2290 | |
+#, c-format | |
+msgid "%s carried" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2366 | |
+msgid "Change Name" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2376 | |
+msgid "" | |
+"Unfortunately, somebody else is already using \"your\" name. Please change " | |
+"it:-" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2435 | |
+msgid "Done" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2469 | |
+msgid "Spy reports" | |
+msgstr "" | |
+ | |
+#: src/gtk_client.c:2540 | |
+msgid "" | |
+"No GTK+ client available - rebuild the binary passing the\n" | |
+"--enable-gtk-client option to configure, or use the curses\n" | |
+"client (if available) instead!\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:71 | |
+#, c-format | |
+msgid "" | |
+"dopewars server version %s commands and settings\n" | |
+"\n" | |
+"help Displays this help screen\n" | |
+"list Lists all players logged on\n" | |
+"push <player> Politely asks the named player to leave\n" | |
+"kill <player> Abruptly breaks the connection with the named " | |
+"player\n" | |
+"msg:<mesg> Send message to all players\n" | |
+"quit Gracefully quit, after notifying all players\n" | |
+"<variable>=<value> Sets the named variable to the given value\n" | |
+"<variable> Displays the value of the named variable\n" | |
+"<list>[x].<var>=<value> Sets the named variable in the given list,\n" | |
+" index x, to the given value\n" | |
+"<list>[x].<var> Displays the value of the named list variable\n" | |
+"\n" | |
+"Valid variables are listed below:-\n" | |
+"\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:103 | |
+msgid "cannot send data to metaserver\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:125 | |
+#, c-format | |
+msgid "Sending data to metaserver at %s\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:127 | |
+#, c-format | |
+msgid "Notifying metaserver at %s\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:130 | |
+msgid "cannot locate metaserver\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:135 | |
+msgid "cannot create socket for metaserver communication\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:169 | |
+msgid "cannot read high score file\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:207 | |
+#, c-format | |
+msgid "" | |
+"Message is lying about its origin\n" | |
+"%s: %c: %s: %s\n" | |
+"Should be from %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:266 | |
+#, c-format | |
+msgid "MaxClients (%d) exceeded - dropping connection" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:268 | |
+#, c-format | |
+msgid "" | |
+"Sorry, but this server has a limit of %d %s, which has been reached.^Please " | |
+"try connecting again later." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:270 | |
+msgid "player" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:270 | |
+msgid "players" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:279 | |
+#, c-format | |
+msgid "%s will now be known as %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:294 | |
+msgid "Your dealing time is up..." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:305 | |
+#, c-format | |
+msgid "%s: DENIED jet to %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:362 | |
+#, c-format | |
+msgid "%s now spying on %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:370 | |
+#, c-format | |
+msgid "%s spy on %s: DENIED" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:376 | |
+#, c-format | |
+msgid "%s tipped off the cops to %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:384 | |
+#, c-format | |
+msgid "%s tipoff about %s: DENIED" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:492 | |
+msgid "--More--" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:503 | |
+msgid "Pager exited abnormally - using stdout instead..." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:518 | |
+#, c-format | |
+msgid "Maintaining pid file %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:522 | |
+#, c-format | |
+msgid "Cannot create pid file %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:571 | |
+#, c-format | |
+msgid "" | |
+"Cannot open high score file %s.\n" | |
+"Either ensure you have permissions to access this file and directory, or\n" | |
+"specify an alternate high score file with the -f command line option." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:608 | |
+#, c-format | |
+msgid "" | |
+"dopewars server version %s ready and waiting for connections\n" | |
+"on port %d. For assistance with server commands, enter the command \"help\"\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:625 | |
+msgid "Cannot install SIGUSR1 interrupt handler!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:631 | |
+msgid "Cannot install SIGINT interrupt handler!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:634 | |
+msgid "Cannot install SIGTERM interrupt handler!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:637 | |
+msgid "Cannot install SIGHUP interrupt handler!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:642 | |
+msgid "Cannot install pipe handler!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:665 | |
+msgid "Users currently logged on:-\n" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:670 | |
+msgid "No users currently logged on!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:674 | |
+#, c-format | |
+msgid "Pushing %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:676 src/serverside.c:684 | |
+msgid "No such user!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:680 | |
+#, c-format | |
+msgid "%s killed" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:686 | |
+msgid "Unknown command - try \"help\" for help..." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:703 | |
+#, c-format | |
+msgid "got connection from %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:719 | |
+#, c-format | |
+msgid "%s leaves the server!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:787 | |
+msgid "Standard input closed." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:930 | |
+#, c-format | |
+msgid "Unable to read high score file %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:950 | |
+msgid "Congratulations! You made the high scores!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:963 | |
+msgid "You didn't even make the high score table..." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:977 | |
+#, c-format | |
+msgid "Unable to write high score file %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:996 | |
+msgid "(R.I.P.)" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1031 | |
+#, c-format | |
+msgid "%s: Tipoff from %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1048 | |
+#, c-format | |
+msgid "One of your %s was spying for %s.^The spy %s!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1056 | |
+#, c-format | |
+msgid "Your spy working with %s has been discovered!^The spy %s!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1079 | |
+#, c-format | |
+msgid " The lady next to you on the subway said,^ \"%s\"%s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1082 | |
+msgid "^ (at least, you -think- that's what she said)" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1084 | |
+#, c-format | |
+msgid " You hear someone playing %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1093 src/serverside.c:1102 src/serverside.c:1111 | |
+#: src/serverside.c:1120 | |
+#, c-format | |
+msgid "YN^Would you like to visit %s?" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1131 | |
+#, c-format | |
+msgid "YN^^Would you like to hire %s %s for %s?" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1132 | |
+msgid "an" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1132 | |
+msgid "a" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1144 | |
+#, c-format | |
+msgid "AE^%s is already here!^Do you Attack, or Evade?" | |
+msgstr "" | |
+ | |
+#. Send client "Play" a message announcing the attack of the cops | |
+#. The format string used for this purpose can be altered by | |
+#. passing non-NULL "LoneMessage" (for unaccompanied Officer | |
+#. Hardass) and/or "DeputyMessage" (for him with x deputies) | |
+#: src/serverside.c:1213 | |
+#, c-format | |
+msgid "YN^Officer %s is chasing you!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1215 | |
+#, c-format | |
+msgid "YN^Officer %s and %d of his deputies are chasing you!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1236 | |
+msgid "^Do you run?" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1239 | |
+msgid "^Do you Run, or Fight?" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1254 | |
+#, c-format | |
+msgid "%s: tipoff by %s finished OK." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1260 | |
+#, c-format | |
+msgid "Following your tipoff, the cops ambushed %s, who was shot dead" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1264 | |
+#, c-format | |
+msgid "Following your tipoff, the cops ambushed %s, who escaped with %d %s. " | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1301 | |
+msgid "^You stand there like an idiot." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1305 | |
+msgid "^You lose him in the alleys." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1307 | |
+msgid "^You lose them in the alleys." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1315 | |
+msgid "^You can't shake him, man!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1317 | |
+msgid "^You can't shake them, man!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1328 | |
+#, c-format | |
+msgid "^You killed Officer %s! You find %s on his corpse!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1342 | |
+#, c-format | |
+msgid "YN^^^^Do you pay a doctor %s to sew your %s up?" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1346 | |
+#, c-format | |
+msgid "YN^^^^Do you pay a doctor %s to sew you up?" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1357 | |
+msgid "^You got one, man!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1360 | |
+msgid "^You missed!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1364 | |
+msgid "^He's firing on you, man! " | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1366 | |
+msgid "^They're firing on you, man! " | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1369 | |
+msgid "You've been hit! " | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1376 | |
+msgid "He wasted you, man! What a drag!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1378 | |
+msgid "They wasted you, man! What a drag!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1386 | |
+#, c-format | |
+msgid "You lost one of your %s!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1395 | |
+msgid "He missed!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1397 | |
+msgid "They missed!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1417 | |
+msgid "You were mugged in the subway!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1428 | |
+#, c-format | |
+msgid "You meet a friend! He gives you %d %s." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1433 | |
+#, c-format | |
+msgid "You meet a friend! You give him %d %s." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1440 | |
+msgid "Sanitized away a RandomOffer" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1445 | |
+#, c-format | |
+msgid "" | |
+"Police dogs chase you for %d blocks! You dropped some %s! That's a drag, man!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1459 | |
+#, c-format | |
+msgid "You find %d %s on a dead dude in the subway!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1471 | |
+#, c-format | |
+msgid "Your mama made brownies with some of your %s! They were great!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1479 | |
+msgid "" | |
+"YN^There is some weed that smells like paraquat here!^It looks good! Will " | |
+"you smoke it? " | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1486 | |
+#, c-format | |
+msgid "You stopped to %s." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1507 | |
+#, c-format | |
+msgid "Would you like to buy a bigger trenchcoat for %s?" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1512 | |
+#, c-format | |
+msgid "YN^Hey dude! I'll help carry your %s for a mere %s. Yes or no?" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1524 | |
+#, c-format | |
+msgid "YN^Would you like to buy a %s for %s?" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1625 src/serverside.c:1736 | |
+#, c-format | |
+msgid "%s: offer was on behalf of %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1628 | |
+#, c-format | |
+msgid "%s has accepted your %s!^Use the G key to contact your spy." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1674 | |
+msgid "" | |
+"You hallucinated for three days on the wildest trip you ever imagined!^Then " | |
+"you died because your brain disintegrated!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1713 | |
+#, c-format | |
+msgid "Too late - %s has just left!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1739 | |
+#, c-format | |
+msgid "%s has rejected your %s!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1774 | |
+#, c-format | |
+msgid "%s has got away!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1815 | |
+#, c-format | |
+msgid "%s has run off!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1827 | |
+msgid "Coward! You successfully escaped from the fight." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1883 | |
+msgid "pitifully armed" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1884 | |
+msgid "lightly armed" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1885 | |
+msgid "moderately well armed" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1886 | |
+msgid "heavily armed" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1887 | |
+msgid "armed to the teeth" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1888 | |
+msgid " fires and " | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1889 | |
+msgid " stands and takes it." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1892 | |
+#, c-format | |
+msgid "%s arrives, with %d %s, %s,^%s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1896 | |
+#, c-format | |
+msgid "%s arrives, %s,^%s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1901 | |
+#, c-format | |
+msgid "%s fires and " | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1903 | |
+#, c-format | |
+msgid "%s stands and takes it." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1915 | |
+msgid "misses you!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1916 | |
+#, c-format | |
+msgid "You failed to hit %s." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1919 | |
+msgid "You stand and take it." | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1923 | |
+msgid "hits you, man!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1926 | |
+msgid " You've been wasted! What a drag!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1927 | |
+#, c-format | |
+msgid "You hit and killed %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1942 src/serverside.c:1975 | |
+msgid ", and loot the body!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1951 | |
+#, c-format | |
+msgid "^You lost a %s, man!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1956 | |
+#, c-format | |
+msgid "You are paid a bounty of %s in reward for killing^one of %s's %s" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1964 | |
+#, c-format | |
+msgid "You killed one of %s's %s (%d left)" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:1982 | |
+#, c-format | |
+msgid "You fire, and hit %s!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:2021 | |
+msgid "YN^Officer %%s spots you dropping %s, and chases you!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:2023 | |
+msgid "" | |
+"YN^Officer %%s and %%d of his deputies spot you dropping %s, and chase you!" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:2178 | |
+msgid "Player removed due to idle timeout" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:2188 | |
+msgid "Player removed due to connect timeout" | |
+msgstr "" | |
+ | |
+#: src/serverside.c:2194 src/serverside.c:2200 | |
+#, c-format | |
+msgid "%s fails to return fire..." | |
+msgstr "" | |
+ | |
+#: src/message.c:384 | |
+#, c-format | |
+msgid "" | |
+"This server is version %s, while your client is version %s.\n" | |
+"Be warned that different versions may not be fully compatible!\n" | |
+"Refer to the website at http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/\n" | |
+"for the latest version." | |
+msgstr "" | |
+ | |
+#: src/message.c:519 | |
+msgid "Could not find host" | |
+msgstr "" | |
+ | |
+#: src/message.c:520 | |
+msgid "Could not create network socket" | |
+msgstr "" | |
+ | |
+#: src/message.c:521 | |
+msgid "Connection refused or no server present" | |
+msgstr "" | |
+ | |
+#: src/message.c:677 | |
+msgid "Cannot locate metaserver" | |
+msgstr "" | |
+ | |
+#: src/message.c:678 | |
+msgid "Cannot create socket" | |
+msgstr "" | |
+ | |
+#: src/message.c:680 | |
+msgid "Metaserver not running HTTP or connection denied" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:58 | |
+#, c-format | |
+msgid "AI Player started; attempting to contact server at %s:%d..." | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:61 | |
+#, c-format | |
+msgid "" | |
+"Could not connect to dopewars server\n" | |
+"(%s)\n" | |
+"AI Player terminating abnormally." | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:65 | |
+msgid "Connection established\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:85 | |
+msgid "Connection to server lost!\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:98 | |
+msgid "AI Player terminated OK.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:111 | |
+#, c-format | |
+msgid "Using name %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:130 | |
+msgid "Players in this game:-\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:160 | |
+#, c-format | |
+msgid "%s joins the game.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:163 | |
+#, c-format | |
+msgid "%s has left the game.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:171 | |
+#, c-format | |
+msgid "Jetting to %s with %s cash and %s debt" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:191 | |
+msgid "AI Player killed. Terminating normally.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:212 | |
+msgid "Game time is up. Leaving game.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:216 | |
+msgid "AI Player pushed from the server.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:220 | |
+msgid "The server has terminated.\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:276 | |
+#, c-format | |
+msgid "Selling %d %s at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:292 | |
+#, c-format | |
+msgid "Buying %d %s at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:321 | |
+#, c-format | |
+msgid "Buying a %s for %s at the gun shop\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:361 | |
+#, c-format | |
+msgid "Debt of %s paid off to loan shark\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:386 | |
+#, c-format | |
+msgid "Loan shark located at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:394 | |
+#, c-format | |
+msgid "Gun shop located at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:402 | |
+#, c-format | |
+msgid "Pub located at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:415 | |
+#, c-format | |
+msgid "Bank located at %s\n" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:439 | |
+msgid "Call yourselves drug dealers?" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:440 | |
+msgid "A trained monkey could do better..." | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:441 | |
+msgid "Think you're hard enough to deal with the likes of me?" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:442 | |
+msgid "Zzzzz... are you dealing in candy or what?" | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:443 | |
+msgid "Reckon I'll just have to shoot you for your own good." | |
+msgstr "" | |
+ | |
+#: src/AIPlayer.c:452 | |
+msgid "" | |
+"This binary has been compiled without networking support, and thus cannot " | |
+"act as an AI player.\n" | |
+"Recompile passing --enable-networking to the configure script." | |
+msgstr "" | |
diff --git a/po/stamp-cat-id b/po/stamp-cat-id | |
t@@ -0,0 +1 @@ | |
+timestamp | |
diff --git a/src/AIPlayer.c b/src/AIPlayer.c | |
t@@ -0,0 +1,457 @@ | |
+/* AIPlayer.c Code for dopewars computer players */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+ | |
+#include <stdio.h> | |
+#include <string.h> | |
+#include <unistd.h> | |
+#include <stdlib.h> | |
+#include <sys/types.h> | |
+#include <errno.h> | |
+#include <glib.h> | |
+#include "dopeos.h" | |
+#include "dopewars.h" | |
+#include "message.h" | |
+#include "AIPlayer.h" | |
+ | |
+#if NETWORKING | |
+#define NUMNAMES 8 | |
+#define MINSAFECASH 300 | |
+#define MINSAFEHEALTH 40 | |
+ | |
+/* Reserve some space for picking up new guns */ | |
+#define SPACERESERVE 10 | |
+ | |
+/* Locations of the loan shark, bank, gun shop and pub */ | |
+/* Note: these are not the same as the global variables */ | |
+/* LoanSharkLoc, BankLoc, GunShopLoc and RoughPubLoc, */ | |
+/* which are set locally. The remote server could */ | |
+/* have different locations set, and the AI must work */ | |
+/* out where these locations are for itself. */ | |
+int RealLoanShark,RealBank,RealGunShop,RealPub; | |
+ | |
+void AIPlayerLoop() { | |
+/* Main loop for AI players. Connects to server, plays game, */ | |
+/* and then disconnects. */ | |
+ gchar *pt; | |
+ Player *AIPlay; | |
+ fd_set readfs,writefs; | |
+ AIPlay=g_new(Player,1); | |
+ FirstClient=AddPlayer(0,AIPlay,FirstClient); | |
+ g_message(_("AI Player started; attempting to contact server at %s:%d..."), | |
+ ServerName,Port); | |
+ pt=SetupNetwork(); | |
+ if (pt) g_error(_("Could not connect to dopewars server\n(%s)\n" | |
+ "AI Player terminating abnormally."),_(pt)); | |
+ AIPlay->fd=ClientSock; | |
+ AISetName(AIPlay); | |
+ g_message(_("Connection established\n")); | |
+ | |
+ /* Forget where the "special" locations are */ | |
+ RealLoanShark=RealBank=RealGunShop=RealPub=-1; | |
+ | |
+ while (1) { | |
+ FD_ZERO(&readfs); | |
+ FD_ZERO(&writefs); | |
+ FD_SET(ClientSock,&readfs); | |
+ if (AIPlay->WriteBuf.DataPresent) FD_SET(ClientSock,&writefs); | |
+ if (bselect(ClientSock+1,&readfs,NULL,NULL,NULL)==-1) { | |
+ if (errno==EINTR) continue; | |
+ printf("Error in select\n"); exit(1); | |
+ } | |
+ if (FD_ISSET(ClientSock,&writefs)) { | |
+ WriteConnectionBufferToWire(AIPlay); | |
+ } | |
+ if (FD_ISSET(ClientSock,&readfs)) { | |
+ pt=bgets(ClientSock); | |
+ if (!pt) { | |
+ g_print(_("Connection to server lost!\n")); | |
+ ShutdownNetwork(); | |
+ break; | |
+ } else { | |
+ if (HandleAIMessage(pt,AIPlay)) { | |
+ g_free(pt); | |
+ ShutdownNetwork(); | |
+ break; | |
+ } | |
+ g_free(pt); | |
+ } | |
+ } | |
+ } | |
+ g_print(_("AI Player terminated OK.\n")); | |
+} | |
+ | |
+void AISetName(Player *AIPlay) { | |
+/* Chooses a random name for the AI player, and informs the server */ | |
+ char *AINames[NUMNAMES] = { | |
+ "Chip", "Dopey", "Al", "Dan", "Bob", "Fred", "Bert", "Jim" | |
+ }; | |
+ gchar *text; | |
+ text=g_strdup_printf("AI) %s",AINames[brandom(0,NUMNAMES)]); | |
+ SetPlayerName(AIPlay,text); | |
+ g_free(text); | |
+ SendClientMessage(NULL,C_NONE,C_NAME,NULL,GetPlayerName(AIPlay),AIPlay); | |
+ g_print(_("Using name %s\n"),GetPlayerName(AIPlay)); | |
+} | |
+ | |
+int HandleAIMessage(char *Message,Player *AIPlay) { | |
+/* Performs appropriate processing on an incoming network message */ | |
+/* "Message" for AI player "AIPlay". Returns 1 if the game should */ | |
+/* be ended as a result, 0 otherwise. */ | |
+ char *Data,Code,AICode,WasFighting; | |
+ Player *From,*To,*tmp; | |
+ GSList *list; | |
+ gchar *prstr,*prstr2; | |
+ struct timeval tv; | |
+ gboolean Handled; | |
+ if (ProcessMessage(Message,&From,&AICode,&Code,&To,&Data,FirstClient)==-1) { | |
+ g_warning("Bad network message. Oops."); return 0; | |
+ } | |
+ Handled=HandleGenericClientMessage(From,AICode,Code,To,Data,NULL); | |
+ switch(Code) { | |
+ case C_ENDLIST: | |
+ g_print(_("Players in this game:-\n")); | |
+ for (list=FirstClient;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ g_print(" %s\n",GetPlayerName(tmp)); | |
+ } | |
+ break; | |
+ case C_NEWNAME: | |
+ AISetName(AIPlay); | |
+ break; | |
+ case C_FIGHTPRINT: | |
+ PrintAIMessage(Data); | |
+ if (From!=&Noone) { | |
+ AIPlay->Flags |= FIGHTING+CANSHOOT; | |
+ } | |
+ if (TotalGunsCarried(AIPlay)>0 && AIPlay->Health>MINSAFEHEALTH) { | |
+ SendClientMessage(AIPlay,C_NONE,C_FIGHTACT,NULL,"F",AIPlay); | |
+ } else { | |
+ AIJet(AIPlay); | |
+ } | |
+ break; | |
+ case C_PRINTMESSAGE: | |
+ PrintAIMessage(Data); | |
+ break; | |
+ case C_MSG: | |
+ g_print("%s: %s\n",GetPlayerName(From),Data); | |
+ break; | |
+ case C_MSGTO: | |
+ g_print("%s->%s: %s\n",GetPlayerName(From),GetPlayerName(To),Data); | |
+ break; | |
+ case C_JOIN: | |
+ g_print(_("%s joins the game.\n"),Data); break; | |
+ case C_LEAVE: | |
+ if (From!=&Noone) { | |
+ g_print(_("%s has left the game.\n"),Data); | |
+ } | |
+ break; | |
+ case C_SUBWAYFLASH: | |
+ /* Use bselect rather than sleep, as this is portable to Win32 */ | |
+ tv.tv_sec=AITurnPause; | |
+ tv.tv_usec=0; | |
+ bselect(0,NULL,NULL,NULL,&tv); | |
+ g_print(_("Jetting to %s with %s cash and %s debt"), | |
+ Location[(int)AIPlay->IsAt].Name, | |
+ (prstr=FormatPrice(AIPlay->Cash)), | |
+ (prstr2=FormatPrice(AIPlay->Debt))); | |
+ g_free(prstr); g_free(prstr2); | |
+ if (brandom(0,100)<10) AISendRandomMessage(AIPlay); | |
+ break; | |
+ case C_UPDATE: | |
+ WasFighting=FALSE; | |
+ if (From==&Noone) { | |
+ if (AIPlay->Flags & FIGHTING) WasFighting=TRUE; | |
+ ReceivePlayerData(Data,To); | |
+ } else { | |
+ ReceivePlayerData(Data,From); /* spy reports */ | |
+ } | |
+ if (!(AIPlay->Flags & FIGHTING) && WasFighting) { | |
+ AIDealDrugs(AIPlay); | |
+ AIJet(AIPlay); | |
+ } | |
+ if (AIPlay->Health==0) { | |
+ g_print(_("AI Player killed. Terminating normally.\n")); | |
+ g_free(Data); | |
+ return 1; | |
+ } | |
+ break; | |
+ case C_DRUGHERE: | |
+ AIDealDrugs(AIPlay); | |
+ AIJet(AIPlay); | |
+ break; | |
+ case C_GUNSHOP: | |
+ AIGunShop(AIPlay); | |
+ break; | |
+ case C_LOANSHARK: | |
+ AIPayLoan(AIPlay); | |
+ break; | |
+ case C_QUESTION: | |
+ AIHandleQuestion(Data,AICode,AIPlay,From); | |
+ break; | |
+ case C_HISCORE: case C_STARTHISCORE: | |
+ break; | |
+ case C_ENDHISCORE: | |
+ g_print(_("Game time is up. Leaving game.\n")); | |
+ g_free(Data); | |
+ return 1; | |
+ case C_PUSH: | |
+ g_print(_("AI Player pushed from the server.\n")); | |
+ g_free(Data); | |
+ return 1; | |
+ case C_QUIT: | |
+ g_print(_("The server has terminated.\n")); | |
+ g_free(Data); | |
+ return 1; | |
+ default: | |
+ if (!Handled) g_message("%s^%c^%s%s\n",GetPlayerName(From),Code, | |
+ GetPlayerName(To),Data); | |
+ break; | |
+ } | |
+ g_free(Data); | |
+ return 0; | |
+} | |
+ | |
+void PrintAIMessage(char *Text) { | |
+/* Prints a message received via a printmessage or question */ | |
+/* network message, stored in "Text" */ | |
+ int i; | |
+ char SomeText=0; | |
+ for (i=0;i<strlen(Text);i++) { | |
+ if (Text[i]=='^') { | |
+ if (SomeText) putchar('\n'); | |
+ } else { | |
+ putchar(Text[i]); | |
+ SomeText=1; | |
+ } | |
+ } | |
+ putchar('\n'); | |
+} | |
+ | |
+void AIDealDrugs(Player *AIPlay) { | |
+/* Buy and sell drugs for AI player "AIPlay" */ | |
+ price_t *Profit,MaxProfit; | |
+ gchar *prstr,*text; | |
+ int i,LastHighest,Highest,Num,MinProfit; | |
+ Profit = g_new(price_t,NumDrug); | |
+ for (i=0;i<NumDrug;i++) { | |
+ Profit[i]=AIPlay->Drugs[i].Price-(Drug[i].MaxPrice+Drug[i].MinPrice)/2; | |
+ } | |
+ MinProfit=0; | |
+ for (i=0;i<NumDrug;i++) if (Profit[i]<MinProfit) MinProfit=Profit[i]; | |
+ MinProfit--; | |
+ for (i=0;i<NumDrug;i++) if (Profit[i]<0) Profit[i]=MinProfit-Profit[i]; | |
+ LastHighest=-1; | |
+ while (1) { | |
+ MaxProfit=MinProfit; | |
+ Highest=-1; | |
+ for (i=0;i<NumDrug;i++) { | |
+ if (Profit[i]>MaxProfit && i!=LastHighest && | |
+ (LastHighest==-1 || Profit[LastHighest]>Profit[i])) { | |
+ Highest=i; | |
+ MaxProfit=Profit[i]; | |
+ } | |
+ } | |
+ LastHighest=Highest; | |
+ if (Highest==-1) break; | |
+ Num=AIPlay->Drugs[Highest].Carried; | |
+ if (MaxProfit>0 && Num>0) { | |
+ g_print(_("Selling %d %s at %s\n"),Num,Drug[Highest].Name, | |
+ (prstr=FormatPrice(AIPlay->Drugs[Highest].Price))); | |
+ g_free(prstr); | |
+ AIPlay->CoatSize+=Num; | |
+ AIPlay->Cash+=Num*AIPlay->Drugs[Highest].Price; | |
+ text=g_strdup_printf("drug^%d^%d",Highest,-Num); | |
+ SendClientMessage(AIPlay,C_NONE,C_BUYOBJECT,NULL,text,AIPlay); | |
+ g_free(text); | |
+ } | |
+ if (AIPlay->Drugs[Highest].Price != 0 && | |
+ AIPlay->CoatSize>SPACERESERVE) { | |
+ Num=AIPlay->Cash/AIPlay->Drugs[Highest].Price; | |
+ if (Num>AIPlay->CoatSize-SPACERESERVE) { | |
+ Num=AIPlay->CoatSize-SPACERESERVE; | |
+ } | |
+ if (MaxProfit<0 && Num>0) { | |
+ g_print(_("Buying %d %s at %s\n"),Num,Drug[Highest].Name, | |
+ (prstr=FormatPrice(AIPlay->Drugs[Highest].Price))); | |
+ g_free(prstr); | |
+ text=g_strdup_printf("drug^%d^%d",Highest,Num); | |
+ AIPlay->CoatSize-=Num; | |
+ AIPlay->Cash-=Num*AIPlay->Drugs[Highest].Price; | |
+ SendClientMessage(AIPlay,C_NONE,C_BUYOBJECT,NULL,text,AIPlay); | |
+ g_free(text); | |
+ } | |
+ } | |
+ } | |
+ g_free(Profit); | |
+} | |
+ | |
+void AIGunShop(Player *AIPlay) { | |
+/* Handles a visit to the gun shop by AI player "AIPlay" */ | |
+ int i; | |
+ int Bought; | |
+ gchar *text,*prstr; | |
+ do { | |
+ Bought=0; | |
+ for (i=0;i<NumGun;i++) { | |
+ if (TotalGunsCarried(AIPlay)<AIPlay->Bitches.Carried+2 && | |
+ Gun[i].Space<=AIPlay->CoatSize && | |
+ Gun[i].Price<=AIPlay->Cash-MINSAFECASH) { | |
+ AIPlay->Cash-=Gun[i].Price; | |
+ AIPlay->CoatSize-=Gun[i].Space; | |
+ AIPlay->Guns[i].Carried++; | |
+ Bought++; | |
+ g_print(_("Buying a %s for %s at the gun shop\n"),Gun[i].Name, | |
+ (prstr=FormatPrice(Gun[i].Price))); | |
+ g_free(prstr); | |
+ text=g_strdup_printf("gun^%d^1",i); | |
+ SendClientMessage(AIPlay,C_NONE,C_BUYOBJECT,NULL,text,AIPlay); | |
+ g_free(text); | |
+ } | |
+ } | |
+ } while (Bought); | |
+ SendClientMessage(AIPlay,C_NONE,C_DONE,NULL,NULL,AIPlay); | |
+} | |
+ | |
+void AIJet(Player *AIPlay) { | |
+/* Decides on a new game location for AI player "AIPlay" and jets there */ | |
+ int NewLocation; | |
+ char text[40]; | |
+ if (!AIPlay) return; | |
+ NewLocation=AIPlay->IsAt; | |
+ if (RealLoanShark>=0 && AIPlay->Cash > (price_t)((float)AIPlay->Debt*1.2)) { | |
+ NewLocation=RealLoanShark; | |
+ } else if (RealPub>=0 && brandom(0,100)<30 && AIPlay->Cash>MINSAFECASH*10) { | |
+ NewLocation=RealPub; | |
+ } else if (RealGunShop>=0 && brandom(0,100)<70 && | |
+ TotalGunsCarried(AIPlay)<AIPlay->Bitches.Carried+2 && | |
+ AIPlay->Cash>MINSAFECASH*5) { | |
+ NewLocation=RealGunShop; | |
+ } | |
+ while (NewLocation==AIPlay->IsAt) NewLocation=brandom(0,NumLocation); | |
+ sprintf(text,"%d",NewLocation); | |
+ SendClientMessage(AIPlay,C_NONE,C_REQUESTJET,NULL,text,AIPlay); | |
+} | |
+ | |
+void AIPayLoan(Player *AIPlay) { | |
+/* Pays off the loan of AI player "AIPlay" if this doesn't leave */ | |
+/* the player with insufficient funds for further dealing */ | |
+ gchar *prstr; | |
+ if (AIPlay->Cash-AIPlay->Debt >= MINSAFECASH) { | |
+ prstr=pricetostr(AIPlay->Debt); | |
+ SendClientMessage(AIPlay,C_NONE,C_PAYLOAN,NULL,prstr,AIPlay); | |
+ g_free(prstr); | |
+ g_print(_("Debt of %s paid off to loan shark\n"), | |
+ (prstr=FormatPrice(AIPlay->Debt))); | |
+ g_free(prstr); | |
+ } | |
+ SendClientMessage(AIPlay,C_NONE,C_DONE,NULL,NULL,AIPlay); | |
+} | |
+ | |
+void AISendAnswer(Player *From,Player *To,char *answer) { | |
+/* Sends the answer "answer" from AI player "From" to the server, */ | |
+/* claiming to be for player "To". Also prints the answer on the screen. */ | |
+ SendClientMessage(From,C_NONE,C_ANSWER,To,answer,From); puts(answer); | |
+} | |
+ | |
+void AIHandleQuestion(char *Data,char AICode,Player *AIPlay,Player *From) { | |
+/* Works out a sensible response to the question coded in "Data" and with */ | |
+/* computer-readable code "AICode", claiming to be from "From" and for AI */ | |
+/* player "AIPlay", and sends it */ | |
+ char *Prompt,*allowed; | |
+ if (From==&Noone) From=NULL; | |
+ Prompt=Data; | |
+ allowed=GetNextWord(&Prompt,""); | |
+ PrintAIMessage(Prompt); | |
+ switch (AICode) { | |
+ case C_ASKLOAN: | |
+ if (RealLoanShark==-1) { | |
+ g_print(_("Loan shark located at %s\n"), | |
+ Location[(int)AIPlay->IsAt].Name); | |
+ } | |
+ RealLoanShark=AIPlay->IsAt; | |
+ AISendAnswer(AIPlay,From,"Y"); | |
+ break; | |
+ case C_ASKGUNSHOP: | |
+ if (RealGunShop==-1) { | |
+ g_print(_("Gun shop located at %s\n"), | |
+ Location[(int)AIPlay->IsAt].Name); | |
+ } | |
+ RealGunShop=AIPlay->IsAt; | |
+ AISendAnswer(AIPlay,From,"Y"); | |
+ break; | |
+ case C_ASKPUB: | |
+ if (RealPub==-1) { | |
+ g_print(_("Pub located at %s\n"),Location[(int)AIPlay->IsAt].Name); | |
+ } | |
+ RealPub=AIPlay->IsAt; | |
+ AISendAnswer(AIPlay,From,"Y"); | |
+ break; | |
+ case C_ASKBITCH: case C_ASKRUN: case C_ASKGUN: | |
+ AISendAnswer(AIPlay,From,"Y"); | |
+ break; | |
+ case C_ASKRUNFIGHT: | |
+ AISendAnswer(AIPlay,From,AIPlay->Health<MINSAFEHEALTH ? "R" : "F"); | |
+ break; | |
+ case C_ASKBANK: | |
+ if (RealBank==-1) { | |
+ g_print(_("Bank located at %s\n"),Location[(int)AIPlay->IsAt].Name… | |
+ } | |
+ RealBank=AIPlay->IsAt; | |
+ AISendAnswer(AIPlay,From,"N"); | |
+ break; | |
+ case C_MEETPLAYER: | |
+ if (TotalGunsCarried(AIPlay)>0) AISendAnswer(AIPlay,From,"A"); | |
+ else { | |
+ AISendAnswer(AIPlay,From,"E"); | |
+ AIJet(AIPlay); | |
+ } | |
+ break; | |
+ case C_ASKSEW: | |
+ AISendAnswer(AIPlay,From,AIPlay->Health<MINSAFEHEALTH ? "Y" : "N"); | |
+ break; | |
+ default: | |
+ AISendAnswer(AIPlay,From,"N"); | |
+ break; | |
+ } | |
+} | |
+ | |
+void AISendRandomMessage(Player *AIPlay) { | |
+/* Sends a random message to all other dopewars players */ | |
+ char *RandomInsult[5]= { | |
+ N_("Call yourselves drug dealers?"), | |
+ N_("A trained monkey could do better..."), | |
+ N_("Think you\'re hard enough to deal with the likes of me?"), | |
+ N_("Zzzzz... are you dealing in candy or what?"), | |
+ N_("Reckon I'll just have to shoot you for your own good.") | |
+ }; | |
+ SendClientMessage(AIPlay,C_NONE,C_MSG,NULL, | |
+ _(RandomInsult[brandom(0,5)]),AIPlay); | |
+} | |
+ | |
+#else /* NETWORKING */ | |
+ | |
+void AIPlayerLoop() { | |
+ g_print(_("This binary has been compiled without networking support, and " | |
+ "thus cannot act as an AI player.\nRecompile passing " | |
+ "--enable-networking to the configure script.")); | |
+} | |
+ | |
+#endif /* NETWORKING */ | |
diff --git a/src/AIPlayer.h b/src/AIPlayer.h | |
t@@ -0,0 +1,43 @@ | |
+/* AIPlayer.h Header file for dopewars computer player code */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+ | |
+#ifndef __AIPLAYER_H__ | |
+#define __AIPLAYER_H__ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+void AIPlayerLoop(); | |
+ | |
+#if NETWORKING | |
+int HandleAIMessage(char *Message,Player *AIPlay); | |
+void PrintAIMessage(char *Text); | |
+void AIDealDrugs(Player *AIPlay); | |
+void AIJet(Player *AIPlay); | |
+void AIHandleQuestion(char *Data,char AICode,Player *AIPlay,Player *From); | |
+void AIGunShop(Player *AIPlay); | |
+void AIPayLoan(Player *AIPlay); | |
+void AISendRandomMessage(Player *AIPlay); | |
+void AISetName(Player *AIPlay); | |
+#endif /* NETWORKING */ | |
+ | |
+#endif | |
diff --git a/src/Makefile.am b/src/Makefile.am | |
t@@ -0,0 +1,21 @@ | |
+bin_PROGRAMS = dopewars | |
+dopewars_SOURCES = AIPlayer.c serverside.c dopewars.c message.c \ | |
+ curses_client.c gtk_client.c win32_client.c \ | |
+ dopeos.c @WIN_RC@ | |
+dopewars_DEPENDENCIES = @WIN_RES@ | |
+SUFFIXES = .rc .res | |
+INCLUDES = @GTK_CFLAGS@ -I.. -I. | |
+LDADD = @GTK_LIBS@ @WIN_RES@ | |
+DEFS = @DEFS@ -DLOCALEDIR=\"${localedir}\" | |
+ | |
+DOCPATH=/usr/doc/${PACKAGE}-${VERSION}/ | |
+DOCS= aiplayer.html configfile.html index.html server.html clientplay.html \ | |
+ credits.html installation.html servercommands.html commandline.html \ | |
+ developer.html metaserver.html windows.html README | |
+ | |
+@WIN_MAKE_RES@ | |
+ | |
+install-exec-hook: | |
+ chown root.games ${bindir}/dopewars | |
+ chmod 2755 ${bindir}/dopewars | |
+ | |
diff --git a/src/Makefile.in b/src/Makefile.in | |
t@@ -0,0 +1,353 @@ | |
+# Makefile.in generated automatically by automake 1.4 from Makefile.am | |
+ | |
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. | |
+# This Makefile.in is free software; the Free Software Foundation | |
+# gives unlimited permission to copy and/or distribute it, | |
+# with or without modifications, as long as this notice is preserved. | |
+ | |
+# This program is distributed in the hope that it will be useful, | |
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without | |
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
+# PARTICULAR PURPOSE. | |
+ | |
+ | |
+SHELL = @SHELL@ | |
+ | |
+srcdir = @srcdir@ | |
+top_srcdir = @top_srcdir@ | |
+VPATH = @srcdir@ | |
+prefix = @prefix@ | |
+exec_prefix = @exec_prefix@ | |
+ | |
+bindir = @bindir@ | |
+sbindir = @sbindir@ | |
+libexecdir = @libexecdir@ | |
+datadir = @datadir@ | |
+sysconfdir = @sysconfdir@ | |
+sharedstatedir = @sharedstatedir@ | |
+localstatedir = @localstatedir@ | |
+libdir = @libdir@ | |
+infodir = @infodir@ | |
+mandir = @mandir@ | |
+includedir = @includedir@ | |
+oldincludedir = /usr/include | |
+ | |
+DESTDIR = | |
+ | |
+pkgdatadir = $(datadir)/@PACKAGE@ | |
+pkglibdir = $(libdir)/@PACKAGE@ | |
+pkgincludedir = $(includedir)/@PACKAGE@ | |
+ | |
+top_builddir = .. | |
+ | |
+ACLOCAL = @ACLOCAL@ | |
+AUTOCONF = @AUTOCONF@ | |
+AUTOMAKE = @AUTOMAKE@ | |
+AUTOHEADER = @AUTOHEADER@ | |
+ | |
+INSTALL = @INSTALL@ | |
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) | |
+INSTALL_DATA = @INSTALL_DATA@ | |
+INSTALL_SCRIPT = @INSTALL_SCRIPT@ | |
+transform = @program_transform_name@ | |
+ | |
+NORMAL_INSTALL = : | |
+PRE_INSTALL = : | |
+POST_INSTALL = : | |
+NORMAL_UNINSTALL = : | |
+PRE_UNINSTALL = : | |
+POST_UNINSTALL = : | |
+CATALOGS = @CATALOGS@ | |
+CATOBJEXT = @CATOBJEXT@ | |
+CC = @CC@ | |
+DATADIRNAME = @DATADIRNAME@ | |
+GENCAT = @GENCAT@ | |
+GMOFILES = @GMOFILES@ | |
+GMSGFMT = @GMSGFMT@ | |
+GTK_CFLAGS = @GTK_CFLAGS@ | |
+GTK_CONFIG = @GTK_CONFIG@ | |
+GTK_LIBS = @GTK_LIBS@ | |
+GT_NO = @GT_NO@ | |
+GT_YES = @GT_YES@ | |
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@ | |
+INSTOBJEXT = @INSTOBJEXT@ | |
+INTLDEPS = @INTLDEPS@ | |
+INTLLIBS = @INTLLIBS@ | |
+INTLOBJS = @INTLOBJS@ | |
+MAKEINFO = @MAKEINFO@ | |
+MKINSTALLDIRS = @MKINSTALLDIRS@ | |
+MSGFMT = @MSGFMT@ | |
+PACKAGE = @PACKAGE@ | |
+POFILES = @POFILES@ | |
+POSUB = @POSUB@ | |
+RANLIB = @RANLIB@ | |
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@ | |
+USE_NLS = @USE_NLS@ | |
+VERSION = @VERSION@ | |
+WIN_RC = @WIN_RC@ | |
+WIN_RES = @WIN_RES@ | |
+l = @l@ | |
+localedir = @localedir@ | |
+ | |
+bin_PROGRAMS = dopewars | |
+dopewars_SOURCES = AIPlayer.c serverside.c dopewars.c message.c … | |
+ | |
+dopewars_DEPENDENCIES = @WIN_RES@ | |
+SUFFIXES = .rc .res | |
+INCLUDES = @GTK_CFLAGS@ -I.. -I. | |
+LDADD = @GTK_LIBS@ @WIN_RES@ | |
+DEFS = @DEFS@ -DLOCALEDIR=\"${localedir}\" | |
+ | |
+DOCPATH = /usr/doc/${PACKAGE}-${VERSION}/ | |
+DOCS = aiplayer.html configfile.html index.html server.html clientplay.html … | |
+ | |
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs | |
+CONFIG_HEADER = ../config.h | |
+CONFIG_CLEAN_FILES = | |
+PROGRAMS = $(bin_PROGRAMS) | |
+ | |
+CPPFLAGS = @CPPFLAGS@ | |
+LDFLAGS = @LDFLAGS@ | |
+LIBS = @LIBS@ | |
+dopewars_OBJECTS = AIPlayer.o serverside.o dopewars.o message.o \ | |
+curses_client.o gtk_client.o win32_client.o dopeos.o | |
+dopewars_LDADD = $(LDADD) | |
+dopewars_LDFLAGS = | |
+CFLAGS = @CFLAGS@ | |
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(… | |
+CCLD = $(CC) | |
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ | |
+DIST_COMMON = Makefile.am Makefile.in | |
+ | |
+ | |
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) | |
+ | |
+TAR = gtar | |
+GZIP_ENV = --best | |
+DEP_FILES = .deps/AIPlayer.P .deps/curses_client.P .deps/dopeos.P \ | |
+.deps/dopewars.P .deps/gtk_client.P .deps/message.P .deps/serverside.P \ | |
+.deps/win32_client.P | |
+SOURCES = $(dopewars_SOURCES) | |
+OBJECTS = $(dopewars_OBJECTS) | |
+ | |
+all: all-redirect | |
+.SUFFIXES: | |
+.SUFFIXES: .S .c .o .rc .res .s | |
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) | |
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile | |
+ | |
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES) | |
+ cd $(top_builddir) \ | |
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status | |
+ | |
+ | |
+mostlyclean-binPROGRAMS: | |
+ | |
+clean-binPROGRAMS: | |
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) | |
+ | |
+distclean-binPROGRAMS: | |
+ | |
+maintainer-clean-binPROGRAMS: | |
+ | |
+install-binPROGRAMS: $(bin_PROGRAMS) | |
+ @$(NORMAL_INSTALL) | |
+ $(mkinstalldirs) $(DESTDIR)$(bindir) | |
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \ | |
+ if test -f $$p; then \ | |
+ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed '… | |
+ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXE… | |
+ else :; fi; \ | |
+ done | |
+ | |
+uninstall-binPROGRAMS: | |
+ @$(NORMAL_UNINSTALL) | |
+ list='$(bin_PROGRAMS)'; for p in $$list; do \ | |
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(tra… | |
+ done | |
+ | |
+.s.o: | |
+ $(COMPILE) -c $< | |
+ | |
+.S.o: | |
+ $(COMPILE) -c $< | |
+ | |
+mostlyclean-compile: | |
+ -rm -f *.o core *.core | |
+ | |
+clean-compile: | |
+ | |
+distclean-compile: | |
+ -rm -f *.tab.c | |
+ | |
+maintainer-clean-compile: | |
+ | |
+dopewars: $(dopewars_OBJECTS) $(dopewars_DEPENDENCIES) | |
+ @rm -f dopewars | |
+ $(LINK) $(dopewars_LDFLAGS) $(dopewars_OBJECTS) $(dopewars_LDADD) $(LI… | |
+ | |
+tags: TAGS | |
+ | |
+ID: $(HEADERS) $(SOURCES) $(LISP) | |
+ list='$(SOURCES) $(HEADERS)'; \ | |
+ unique=`for i in $$list; do echo $$i; done | \ | |
+ awk ' { files[$$0] = 1; } \ | |
+ END { for (i in files) print i; }'`; \ | |
+ here=`pwd` && cd $(srcdir) \ | |
+ && mkid -f$$here/ID $$unique $(LISP) | |
+ | |
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) | |
+ tags=; \ | |
+ here=`pwd`; \ | |
+ list='$(SOURCES) $(HEADERS)'; \ | |
+ unique=`for i in $$list; do echo $$i; done | \ | |
+ awk ' { files[$$0] = 1; } \ | |
+ END { for (i in files) print i; }'`; \ | |
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ | |
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o … | |
+ | |
+mostlyclean-tags: | |
+ | |
+clean-tags: | |
+ | |
+distclean-tags: | |
+ -rm -f TAGS ID | |
+ | |
+maintainer-clean-tags: | |
+ | |
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) | |
+ | |
+subdir = src | |
+ | |
+distdir: $(DISTFILES) | |
+ here=`cd $(top_builddir) && pwd`; \ | |
+ top_distdir=`cd $(top_distdir) && pwd`; \ | |
+ distdir=`cd $(distdir) && pwd`; \ | |
+ cd $(top_srcdir) \ | |
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top… | |
+ @for file in $(DISTFILES); do \ | |
+ d=$(srcdir); \ | |
+ if test -d $$d/$$file; then \ | |
+ cp -pr $$d/$$file $(distdir)/$$file; \ | |
+ else \ | |
+ test -f $(distdir)/$$file \ | |
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ | |
+ || cp -p $$d/$$file $(distdir)/$$file || :; \ | |
+ fi; \ | |
+ done | |
+ | |
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :) | |
+ | |
+-include $(DEP_FILES) | |
+ | |
+mostlyclean-depend: | |
+ | |
+clean-depend: | |
+ | |
+distclean-depend: | |
+ -rm -rf .deps | |
+ | |
+maintainer-clean-depend: | |
+ | |
+%.o: %.c | |
+ @echo '$(COMPILE) -c $<'; \ | |
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $< | |
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \ | |
+ tr ' ' '\012' < .deps/$(*F).pp \ | |
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ | |
+ >> .deps/$(*F).P; \ | |
+ rm .deps/$(*F).pp | |
+ | |
+%.lo: %.c | |
+ @echo '$(LTCOMPILE) -c $<'; \ | |
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $< | |
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ | |
+ < .deps/$(*F).pp > .deps/$(*F).P; \ | |
+ tr ' ' '\012' < .deps/$(*F).pp \ | |
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ | |
+ >> .deps/$(*F).P; \ | |
+ rm -f .deps/$(*F).pp | |
+info-am: | |
+info: info-am | |
+dvi-am: | |
+dvi: dvi-am | |
+check-am: all-am | |
+check: check-am | |
+installcheck-am: | |
+installcheck: installcheck-am | |
+install-exec-am: install-binPROGRAMS | |
+ @$(NORMAL_INSTALL) | |
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook | |
+install-exec: install-exec-am | |
+ | |
+install-data-am: | |
+install-data: install-data-am | |
+ | |
+install-am: all-am | |
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am | |
+install: install-am | |
+uninstall-am: uninstall-binPROGRAMS | |
+uninstall: uninstall-am | |
+all-am: Makefile $(PROGRAMS) | |
+all-redirect: all-am | |
+install-strip: | |
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install | |
+installdirs: | |
+ $(mkinstalldirs) $(DESTDIR)$(bindir) | |
+ | |
+ | |
+mostlyclean-generic: | |
+ | |
+clean-generic: | |
+ | |
+distclean-generic: | |
+ -rm -f Makefile $(CONFIG_CLEAN_FILES) | |
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]* | |
+ | |
+maintainer-clean-generic: | |
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ | |
+ mostlyclean-tags mostlyclean-depend mostlyclean-generic | |
+ | |
+mostlyclean: mostlyclean-am | |
+ | |
+clean-am: clean-binPROGRAMS clean-compile clean-tags clean-depend \ | |
+ clean-generic mostlyclean-am | |
+ | |
+clean: clean-am | |
+ | |
+distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \ | |
+ distclean-depend distclean-generic clean-am | |
+ | |
+distclean: distclean-am | |
+ | |
+maintainer-clean-am: maintainer-clean-binPROGRAMS \ | |
+ maintainer-clean-compile maintainer-clean-tags \ | |
+ maintainer-clean-depend maintainer-clean-generic \ | |
+ distclean-am | |
+ @echo "This command is intended for maintainers to use;" | |
+ @echo "it deletes files that may require special tools to rebuild." | |
+ | |
+maintainer-clean: maintainer-clean-am | |
+ | |
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ | |
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ | |
+mostlyclean-compile distclean-compile clean-compile \ | |
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \ | |
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \ | |
+distclean-depend clean-depend maintainer-clean-depend info-am info \ | |
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ | |
+install-exec install-data-am install-data install-am install \ | |
+uninstall-am uninstall all-redirect all-am all installdirs \ | |
+mostlyclean-generic distclean-generic clean-generic \ | |
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean | |
+ | |
+ | |
+@WIN_MAKE_RES@ | |
+ | |
+install-exec-hook: | |
+ chown root.games ${bindir}/dopewars | |
+ chmod 2755 ${bindir}/dopewars | |
+ | |
+# Tell versions [3.59,3.63) of GNU make to not export all variables. | |
+# Otherwise a system limit (for SysV at least) may be exceeded. | |
+.NOEXPORT: | |
diff --git a/src/curses_client.c b/src/curses_client.c | |
t@@ -0,0 +1,1689 @@ | |
+/* curses_client.c dopewars client using the (n)curses console library */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#ifdef CURSES_CLIENT | |
+ | |
+#include <string.h> | |
+#include <stdlib.h> | |
+#include <sys/types.h> | |
+#include <unistd.h> | |
+#include <ctype.h> | |
+#include <signal.h> | |
+#include <errno.h> | |
+#include <glib.h> | |
+#include "dopeos.h" | |
+#include "curses_client.h" | |
+#include "serverside.h" | |
+#include "dopewars.h" | |
+#include "message.h" | |
+ | |
+static void PrepareHighScoreScreen(); | |
+static void PrintHighScore(char *Data); | |
+ | |
+static int ResizedFlag; | |
+static SCREEN *cur_screen; | |
+static char ConnectMethod=CM_SERVER; | |
+ | |
+/* Function definitions; make them static so as not to clash with functions | |
+ of the same name in different clients */ | |
+static void display_intro(); | |
+static void ResizeHandle(int sig); | |
+static void CheckForResize(Player *Play); | |
+static int GetKey(char *allowed,char *orig_allowed,gboolean AllowOther, | |
+ gboolean PrintAllowed); | |
+static void clear_bottom(), clear_screen(); | |
+static void clear_line(int line), clear_exceptfor(int skip); | |
+static void nice_wait(); | |
+static void DisplayFightMessage(char *text); | |
+static void DisplaySpyReports(char *Data,Player *From,Player *To); | |
+static void display_message(char *buf); | |
+static void print_location(char *text); | |
+static void print_status(Player *Play,char DispDrug); | |
+static char *nice_input(char *prompt,int sy,int sx,char digitsonly, | |
+ char *displaystr); | |
+static Player *ListPlayers(Player *Play,char Select,char *Prompt); | |
+static void HandleClientMessage(char *buf,Player *ReallyTo); | |
+static void PrintMessage(char *text); | |
+static void GunShop(Player *Play); | |
+static void LoanShark(Player *Play); | |
+static void Bank(Player *Play); | |
+ | |
+static char DisplayMode,QuitRequest; | |
+ | |
+static void start_curses() { | |
+/* Initialises the curses library for accessing the screen */ | |
+ cur_screen=newterm(NULL,stdout,stdin); | |
+ if (WantColour) { | |
+ start_color(); | |
+ init_pair(1,COLOR_MAGENTA,COLOR_WHITE); | |
+ init_pair(2,COLOR_BLACK,COLOR_WHITE); | |
+ init_pair(3,COLOR_BLACK,COLOR_WHITE); | |
+ init_pair(4,COLOR_BLUE,COLOR_WHITE); | |
+ init_pair(5,COLOR_WHITE,COLOR_BLUE); | |
+ init_pair(6,COLOR_RED,COLOR_WHITE); | |
+ } | |
+ cbreak(); | |
+ noecho(); | |
+ nodelay(stdscr,FALSE); | |
+ keypad(stdscr,TRUE); | |
+ curs_set(0); | |
+} | |
+ | |
+static void end_curses() { | |
+/* Shuts down the curses screen library */ | |
+ keypad(stdscr,FALSE); | |
+ curs_set(1); | |
+ erase(); | |
+ refresh(); | |
+ endwin(); | |
+} | |
+ | |
+void ResizeHandle(int sig) { | |
+/* Handles a SIGWINCH signal, which is sent to indicate that the */ | |
+/* size of the curses screen has changed. */ | |
+ ResizedFlag=1; | |
+} | |
+ | |
+void CheckForResize(Player *Play) { | |
+/* Checks to see if the curses window needs to be resized - i.e. if a */ | |
+/* SIGWINCH signal has been received */ | |
+ sigset_t sigset; | |
+ sigemptyset(&sigset); | |
+ sigaddset(&sigset,SIGWINCH); | |
+ sigprocmask(SIG_BLOCK,&sigset,NULL); | |
+ if (ResizedFlag) { | |
+ ResizedFlag=0; | |
+ end_curses(); start_curses(); | |
+ Width=COLS; Depth=LINES; | |
+ attrset(TextAttr); clear_screen(); | |
+ display_message(""); | |
+ DisplayFightMessage(NULL); | |
+ print_status(Play,1); | |
+ } | |
+ sigprocmask(SIG_UNBLOCK,&sigset,NULL); | |
+} | |
+ | |
+void display_intro() { | |
+/* Displays a dopewars introduction screen */ | |
+ GString *text; | |
+ attrset(TextAttr); | |
+ clear_screen(); | |
+ attrset(TitleAttr); | |
+ | |
+ text=g_string_new(_("D O P E W A R S")); | |
+ mvaddstr(1,(Width-text->len)/2,text->str); | |
+ | |
+ attrset(TextAttr); | |
+ | |
+ mvaddstr(3,1,_("Based on John E. Dell's old Drug Wars game, dopewars " | |
+ "is a simulation of an")); | |
+ mvaddstr(4,1,_("imaginary drug market. dopewars is an All-American " | |
+ "game which features")); | |
+ mvaddstr(5,1,_("buying, selling, and trying to get past the cops!")); | |
+ | |
+ mvaddstr(7,1,_("The first thing you need to do is pay off your " | |
+ "debt to the Loan Shark. After")); | |
+ mvaddstr(8,1,_("that, your goal is to make as much money as " | |
+ "possible (and stay alive)! You")); | |
+ mvaddstr(9,1,_("have one month of game time to make your fortune.")); | |
+ | |
+ mvaddstr(11,18,_("Copyright (C) 1998-2000 Ben Webb " | |
+ "[email protected]")); | |
+ g_string_sprintf(text,_("Version %s"),VERSION); | |
+ mvaddstr(11,2,text->str); | |
+ g_string_assign(text, | |
+ _("dopewars is released under the GNU General Public Licence")); | |
+ mvaddstr(12,(Width-text->len)/2,text->str); | |
+ | |
+ mvaddstr(14,7,_("Drug Dealing and Research Dan Wolf")); | |
+ mvaddstr(15,7,_("Play Testing Phil Davis " | |
+ "Owen Walsh")); | |
+ mvaddstr(16,7,_("Extensive Play Testing Katherine Holt " | |
+ "Caroline Moore")); | |
+ mvaddstr(17,7,_("Constructive Criticism Andrea Elliot-Smith " | |
+ "Pete Winn")); | |
+ mvaddstr(18,7,_("Unconstructive Criticism James Matthews")); | |
+ | |
+ mvaddstr(20,3,_("For information on the command line options, type " | |
+ "dopewars -h at your")); | |
+ mvaddstr(21,1,_("Unix prompt. This will display a help screen, listing " | |
+ "the available options.")); | |
+ | |
+ g_string_free(text,TRUE); | |
+ nice_wait(); | |
+ attrset(TextAttr); clear_screen(); refresh(); | |
+} | |
+ | |
+#ifdef NETWORKING | |
+static void SelectServerManually() { | |
+/* Prompts the user to enter a server name and port to connect to */ | |
+ gchar *text,*PortText; | |
+ if (ServerName[0]=='(') AssignName(&ServerName,"localhost"); | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ mvaddstr(17,1, | |
+ _("Please enter the hostname and port of a dopewars server:-")); | |
+ text=nice_input(_("Hostname: "),18,1,0,ServerName); | |
+ AssignName(&ServerName,text); g_free(text); | |
+ PortText=g_strdup_printf("%d",Port); | |
+ text=nice_input(_("Port: "),19,1,1,PortText); | |
+ Port=atoi(text); | |
+ g_free(text); g_free(PortText); | |
+} | |
+ | |
+static char *SelectServerFromMetaServer() { | |
+/* Contacts the dopewars metaserver, and obtains a list of valid */ | |
+/* server/port pairs, one of which the user should select. */ | |
+/* Returns a pointer to a static string containing an error */ | |
+/* message if the connection failed, otherwise NULL. */ | |
+ char *MetaError; | |
+ int HttpSock,c; | |
+ GSList *ListPt; | |
+ ServerData *ThisServer; | |
+ GString *text; | |
+ gint index; | |
+ static char NoServers[] = N_("No servers listed on metaserver"); | |
+ | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ mvaddstr(17,1,_("Please wait... attempting to contact metaserver...")); | |
+ refresh(); | |
+ | |
+ MetaError=OpenMetaServerConnection(&HttpSock); | |
+ if (MetaError) return MetaError; | |
+ | |
+ clear_line(17); | |
+ mvaddstr(17,1, | |
+ _("Connection to metaserver established. Obtaining server list...")); | |
+ refresh(); | |
+ | |
+ ReadMetaServerData(HttpSock); | |
+ CloseMetaServerConnection(HttpSock); | |
+ | |
+ text=g_string_new(""); | |
+ | |
+ ListPt=ServerList; | |
+ while (ListPt) { | |
+ ThisServer=(ServerData *)(ListPt->data); | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ g_string_sprintf(text,_("Server : %s"),ThisServer->Name); | |
+ mvaddstr(17,1,text->str); | |
+ g_string_sprintf(text,_("Port : %d"),ThisServer->Port); | |
+ mvaddstr(18,1,text->str); | |
+ g_string_sprintf(text,_("Version : %s"),ThisServer->Version); | |
+ mvaddstr(18,40,text->str); | |
+ if (ThisServer->CurPlayers==-1) { | |
+ g_string_sprintf(text,_("Players: -unknown- (maximum %d)"), | |
+ ThisServer->MaxPlayers); | |
+ } else { | |
+ g_string_sprintf(text,_("Players: %d (maximum %d)"), | |
+ ThisServer->CurPlayers,ThisServer->MaxPlayers); | |
+ } | |
+ mvaddstr(19,1,text->str); | |
+ g_string_sprintf(text,_("Up since : %s"),ThisServer->UpSince); | |
+ mvaddstr(19,40,text->str); | |
+ g_string_sprintf(text,_("Comment: %s"),ThisServer->Comment); | |
+ mvaddstr(20,1,text->str); | |
+ attrset(PromptAttr); | |
+ mvaddstr(23,1, | |
+ _("N>ext server; P>revious server; S>elect this server... ")); | |
+ c=GetKey(_("NPS"),"NPS",FALSE,FALSE); | |
+ switch(c) { | |
+ case 'S': AssignName(&ServerName,ThisServer->Name); | |
+ Port=ThisServer->Port; | |
+ ThisServer=NULL; | |
+ break; | |
+ case 'N': ListPt=g_slist_next(ListPt); | |
+ if (!ListPt) ListPt=ServerList; | |
+ break; | |
+ case 'P': index=g_slist_position(ServerList,ListPt)-1; | |
+ if (index>=0) ListPt=g_slist_nth(ServerList,(guint)index); | |
+ else ListPt=g_slist_last(ListPt); | |
+ break; | |
+ } | |
+ } | |
+ if (!ServerList) return NoServers; | |
+ clear_line(17); | |
+ refresh(); | |
+ g_string_free(text,TRUE); | |
+ return NULL; | |
+} | |
+ | |
+static char ConnectToServer(Player *Play) { | |
+/* Connects to a dopewars server. Prompts the user to select a server */ | |
+/* if necessary. Returns TRUE, unless the user elected to quit the */ | |
+/* program rather than choose a valid server. */ | |
+ char *pt=NULL,*MetaError=NULL; | |
+ gchar *text; | |
+ int c; | |
+ if (strcasecmp(ServerName,"(MetaServer)")==0 || ConnectMethod==CM_META) { | |
+ ConnectMethod=CM_META; | |
+ MetaError=SelectServerFromMetaServer(); | |
+ } else if (strcasecmp(ServerName,"(Prompt)")==0 || | |
+ ConnectMethod==CM_PROMPT) { | |
+ ConnectMethod=CM_PROMPT; | |
+ SelectServerManually(); | |
+ } else if (strcasecmp(ServerName,"(Single)")==0 || | |
+ ConnectMethod==CM_SINGLE) { | |
+ ConnectMethod=CM_SINGLE; | |
+ return TRUE; | |
+ } | |
+ while (1) { | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ if (!MetaError) { | |
+ mvaddstr(17,1, | |
+ _("Please wait... attempting to contact dopewars server...")… | |
+ refresh(); | |
+ pt=SetupNetwork(); | |
+ } | |
+ if (pt || MetaError) { | |
+ clear_line(17); | |
+ if (MetaError) { | |
+ text=g_strdup_printf(_("Error: %s"),_(MetaError)); | |
+ mvaddstr(17,1,text); g_free(text); | |
+ } else { | |
+ mvaddstr(16,1,_("Could not start multiplayer dopewars")); | |
+ text=g_strdup_printf(" (%s)",_(pt)); | |
+ mvaddstr(17,1,text); g_free(text); | |
+ } | |
+ pt=MetaError=NULL; | |
+ attrset(PromptAttr); | |
+ mvaddstr(18,1, | |
+ _("Will you... C>onnect to a different host and/or port")); | |
+ mvaddstr(19,1, | |
+ _(" L>ist the servers on the metaserver, and " | |
+ "select one")); | |
+ mvaddstr(20,1, | |
+ _(" Q>uit (where you can start a server by " | |
+ "typing ")); | |
+ mvaddstr(21,1, | |
+ _(" dopewars -s < /dev/null & )")); | |
+ mvaddstr(22,1,_(" or P>lay single-player ? ")); | |
+ attrset(TextAttr); | |
+ c=GetKey(_("CLQP"),"CLQP",FALSE,FALSE); | |
+ switch(c) { | |
+ case 'Q': return FALSE; | |
+ case 'P': ConnectMethod=CM_SINGLE; | |
+ return TRUE; | |
+ case 'L': ConnectMethod=CM_META; | |
+ MetaError=SelectServerFromMetaServer(); | |
+ break; | |
+ case 'C': ConnectMethod=CM_PROMPT; | |
+ SelectServerManually(); | |
+ break; | |
+ } | |
+ } else break; | |
+ } | |
+ return TRUE; | |
+} | |
+#endif /* NETWORKING */ | |
+ | |
+static int jet(Player *Play,char AllowReturn) { | |
+/* Displays the list of locations and prompts the user to select one. */ | |
+/* If "AllowReturn" is TRUE, then if the current location is selected */ | |
+/* simply drop back to the main game loop, otherwise send a request */ | |
+/* to the server to move to the new location. If FALSE, the user MUST */ | |
+/* choose a new location to move to. The active client player is */ | |
+/* passed in "Play" */ | |
+/* N.B. May set the global variable DisplayMode */ | |
+/* Returns: 1 if the user chose to jet to a new location, */ | |
+/* 0 if the action was cancelled instead. */ | |
+ int i,c; | |
+ char text[80]; | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ for (i=0;i<NumLocation;i++) { | |
+ sprintf(text,"%d. %s",i+1,Location[i].Name); | |
+ mvaddstr(17+i/3,(i%3)*20+12,text); | |
+ } | |
+ attrset(PromptAttr); | |
+ mvaddstr(22,22,_("Where to, dude ? ")); | |
+ attrset(TextAttr); | |
+ curs_set(1); | |
+ while (1) { | |
+ c=bgetch(); | |
+ if (c>='1' && c<'1'+NumLocation) { | |
+ addstr(Location[c-'1'].Name); | |
+ if (Play->IsAt != c-'1') { | |
+ curs_set(0); | |
+ sprintf(text,"%d",c-'1'); | |
+ DisplayMode=DM_NONE; | |
+ SendClientMessage(Play,C_NONE,C_REQUESTJET,NULL,text,Play); | |
+ return 1; | |
+ } | |
+ } | |
+ if (AllowReturn) break; | |
+ } | |
+ curs_set(0); | |
+ return 0; | |
+} | |
+ | |
+static void DropDrugs(Player *Play) { | |
+/* Prompts the user "Play" to drop some of the currently carried drugs */ | |
+ int i,c,NumDrugs; | |
+ GString *text; | |
+ gchar *buf; | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ text=g_string_new(""); | |
+ g_string_sprintf(text, | |
+ _("You can\'t get any cash for the following carried %s :"… | |
+ Names.Drugs); | |
+ mvaddstr(16,1,text->str); | |
+ NumDrugs=0; | |
+ for (i=0;i<NumDrug;i++) { | |
+ if (Play->Drugs[i].Carried>0 && Play->Drugs[i].Price==0) { | |
+ g_string_sprintf(text,"%c. %-10s %-8d",NumDrugs+'A',Drug[i].Name, | |
+ Play->Drugs[i].Carried); | |
+ mvaddstr(17+NumDrugs/3,(NumDrugs%3)*25+4,text->str); | |
+ NumDrugs++; | |
+ } | |
+ } | |
+ attrset(PromptAttr); | |
+ mvaddstr(22,20,_("What do you want to drop? ")); | |
+ curs_set(1); | |
+ attrset(TextAttr); | |
+ c=bgetch(); | |
+ c=toupper(c); | |
+ if (c>='A' && c<'A'+NumDrugs) { | |
+ for (i=0;i<NumDrug;i++) if (Play->Drugs[i].Carried>0 && | |
+ Play->Drugs[i].Price==0) { | |
+ c--; | |
+ if (c<'A') { | |
+ addstr(Drug[i].Name); | |
+ buf=nice_input(_("How many do you drop? "),23,8,1,NULL); | |
+ c=atoi(buf); g_free(buf); | |
+ if (c>0) { | |
+ g_string_sprintf(text,"drug^%d^%d",i,-c); | |
+ SendClientMessage(Play,C_NONE,C_BUYOBJECT,NULL,text->str,Play); | |
+ } | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+static void DealDrugs(Player *Play,char Buy) { | |
+/* Prompts the user (i.e. the owner of client "Play") to buy drugs if */ | |
+/* "Buy" is TRUE, or to sell drugs otherwise. A list of available drugs */ | |
+/* is displayed, and on receiving the selection, the user is prompted */ | |
+/* for the number of drugs desired. Finally a message is sent to the */ | |
+/* server to buy or sell the required quantity. */ | |
+ int i,c,NumDrugsHere; | |
+ gchar *text,*input; | |
+ int DrugNum,CanCarry,CanAfford; | |
+ | |
+ NumDrugsHere=0; | |
+ for (c=0;c<NumDrug;c++) if (Play->Drugs[c].Price>0) NumDrugsHere++; | |
+ | |
+ clear_line(22); | |
+ attrset(PromptAttr); | |
+ if (Buy) { | |
+ mvaddstr(22,20,_("What do you wish to buy? ")); | |
+ } else { | |
+ mvaddstr(22,20,_("What do you wish to sell? ")); | |
+ } | |
+ curs_set(1); | |
+ attrset(TextAttr); | |
+ c=bgetch(); | |
+ c=toupper(c); | |
+ if (c>='A' && c<'A'+NumDrugsHere) { | |
+ DrugNum=-1; | |
+ for (i=0;i<NumDrug;i++) { | |
+ DrugNum=GetNextDrugIndex(DrugNum,Play); | |
+ if (--c<'A') break; | |
+ } | |
+ addstr(Drug[DrugNum].Name); | |
+ CanCarry=Play->CoatSize; | |
+ CanAfford=Play->Cash/Play->Drugs[DrugNum].Price; | |
+ | |
+ if (Buy) { | |
+ text=g_strdup_printf(_("You can afford %d, and can carry %d. "), | |
+ CanAfford,CanCarry); | |
+ mvaddstr(23,2,text); | |
+ input=nice_input(_("How many do you buy? "),23,2+strlen(text),1,NULL); | |
+ c=atoi(input); g_free(input); g_free(text); | |
+ if (c>=0) { | |
+ text=g_strdup_printf("drug^%d^%d",DrugNum,c); | |
+ SendClientMessage(Play,C_NONE,C_BUYOBJECT,NULL,text,Play); | |
+ g_free(text); | |
+ } | |
+ } else { | |
+ text=g_strdup_printf(_("You have %d. "),Play->Drugs[DrugNum].Carried); | |
+ mvaddstr(23,2,text); | |
+ input=nice_input(_("How many do you sell? "),23,2+strlen(text),1,NULL… | |
+ c=atoi(input); g_free(input); g_free(text); | |
+ if (c>=0) { | |
+ text=g_strdup_printf("drug^%d^%d",DrugNum,-c); | |
+ SendClientMessage(Play,C_NONE,C_BUYOBJECT,NULL,text,Play); | |
+ g_free(text); | |
+ } | |
+ } | |
+ } | |
+ curs_set(0); | |
+} | |
+ | |
+static void GiveErrand(Player *Play) { | |
+/* Prompts the user (player "Play") to give an errand to one of his/her */ | |
+/* bitches. The decision is relayed to the server for implementation. */ | |
+ int c,y; | |
+ gchar *prstr; | |
+ GString *text; | |
+ Player *To; | |
+ text=g_string_new(""); | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ y=17; | |
+ g_string_sprintf(text,_("Choose an errand to give one of your %s..."), | |
+ Names.Bitches); | |
+ mvaddstr(y++,1,text->str); | |
+ attrset(PromptAttr); | |
+ if (Play->Bitches.Carried>0) { | |
+ g_string_sprintf(text, | |
+ _(" S>py on another dealer (cost: %s)"), | |
+ prstr=FormatPrice(Prices.Spy)); | |
+ mvaddstr(y++,2,text->str); g_free(prstr); | |
+ g_string_sprintf(text, | |
+ _(" T>ip off the cops to another dealer (cost: %s)"), | |
+ prstr=FormatPrice(Prices.Tipoff)); | |
+ mvaddstr(y++,2,text->str); g_free(prstr); | |
+ mvaddstr(y++,2,_(" G>et stuffed")); | |
+ } | |
+ if (Play->Flags&SPYINGON) { | |
+ mvaddstr(y++,2,_("or C>ontact your spies and receive reports")); | |
+ } | |
+ mvaddstr(y++,2,_("or N>o errand ? ")); | |
+ curs_set(1); | |
+ attrset(TextAttr); | |
+ c=GetKey(_("STGCN"),"STGCN",TRUE,FALSE); | |
+ if (Play->Bitches.Carried>0 || c=='C') switch (c) { | |
+ case 'S': | |
+ To=ListPlayers(Play,TRUE,_("Whom do you want to spy on? ")); | |
+ if (To) SendClientMessage(Play,C_NONE,C_SPYON,To,NULL,Play); | |
+ break; | |
+ case 'T': | |
+ To=ListPlayers(Play,TRUE, | |
+ _("Whom do you want to tip the cops off to? ")); | |
+ if (To) SendClientMessage(Play,C_NONE,C_TIPOFF,To,NULL,Play); | |
+ break; | |
+ case 'G': | |
+ attrset(PromptAttr); | |
+ addstr(_(" Are you sure? ")); | |
+ c=GetKey(_("YN"),"YN",FALSE,TRUE); | |
+ if (c=='Y') SendClientMessage(Play,C_NONE,C_SACKBITCH,NULL,NULL,Play); | |
+ break; | |
+ case 'C': | |
+ if (Play->Flags & SPYINGON) { | |
+ SendClientMessage(Play,C_NONE,C_CONTACTSPY,NULL,NULL,Play); | |
+ } | |
+ break; | |
+ } | |
+} | |
+ | |
+static int want_to_quit() { | |
+/* Asks the user if he/she _really_ wants to quit dopewars */ | |
+ attrset(TextAttr); | |
+ clear_line(22); | |
+ attrset(PromptAttr); | |
+ mvaddstr(22,1,_("Are you sure you want to quit? ")); | |
+ attrset(TextAttr); | |
+ return (GetKey(_("YN"),"YN",FALSE,TRUE)!='N'); | |
+} | |
+ | |
+static void change_name(Player *Play,char nullname) { | |
+/* Prompts the user to change his or her name, and notifies the server */ | |
+ gchar *NewName; | |
+ NewName=nice_input(_("New name: "),23,0,0,NULL); | |
+ if (NewName[0]) { | |
+ SendClientMessage(nullname ? NULL : Play,C_NONE,C_NAME,NULL,NewName,Play… | |
+ SetPlayerName(Play,NewName); | |
+ } | |
+ g_free(NewName); | |
+} | |
+ | |
+void HandleClientMessage(char *Message,Player *ReallyTo) { | |
+/* Given a message "Message" coming in on a socket which identifies it as */ | |
+/* "really" for player "ReallyTo", performs processing and reacts properly; */ | |
+/* if a message indicates the end of the game, the global variable */ | |
+/* QuitRequest is set. The global variable DisplayMode may also be changed */ | |
+/* by this routine as a result of network traffic. */ | |
+ char *pt,*Data,Code,*wrd; | |
+ char AICode; | |
+ Player *From,*To,*tmp; | |
+ GSList *list; | |
+ gchar *text; | |
+ int i; | |
+ gboolean Handled; | |
+ if (ProcessMessage(Message,&From,&AICode,&Code,&To,&Data,FirstClient)==-1) { | |
+ return; | |
+ } | |
+ | |
+ Handled=HandleGenericClientMessage(From,AICode,Code,To,Data,&DisplayMode); | |
+ switch(Code) { | |
+ case C_ENDLIST: | |
+ if (FirstClient && g_slist_next(FirstClient)) { | |
+ ListPlayers(To,FALSE,NULL); | |
+ } | |
+ break; | |
+ case C_STARTHISCORE: | |
+ PrepareHighScoreScreen(); break; | |
+ case C_HISCORE: | |
+ PrintHighScore(Data); break; | |
+ case C_ENDHISCORE: | |
+ if (strcmp(Data,"end")==0) { | |
+ QuitRequest=TRUE; | |
+ } else { | |
+ nice_wait(); | |
+ clear_screen(); | |
+ display_message(""); | |
+ print_status(To,1); | |
+ refresh(); | |
+ } | |
+ break; | |
+ case C_PUSH: | |
+ attrset(TextAttr); | |
+ clear_line(22); | |
+ mvaddstr(22,0,_("You have been pushed from the server. " | |
+ "Reverting to single player mode.")); | |
+ nice_wait(); | |
+ SwitchToSinglePlayer(To); | |
+ print_status(To,TRUE); | |
+ break; | |
+ case C_QUIT: | |
+ attrset(TextAttr); | |
+ clear_line(22); | |
+ mvaddstr(22,0, | |
+ _("The server has terminated. Reverting to single player mode.")); | |
+ nice_wait(); | |
+ SwitchToSinglePlayer(To); | |
+ print_status(To,TRUE); | |
+ break; | |
+ case C_MSG: | |
+ text=g_strdup_printf("%s: %s",GetPlayerName(From),Data); | |
+ display_message(text); g_free(text); | |
+ break; | |
+ case C_MSGTO: | |
+ text=g_strdup_printf("%s->%s: %s",GetPlayerName(From), | |
+ GetPlayerName(To),Data); | |
+ display_message(text); g_free(text); | |
+ break; | |
+ case C_JOIN: | |
+ text=g_strdup_printf(_("%s joins the game!"),Data); | |
+ display_message(text); g_free(text); | |
+ break; | |
+ case C_LEAVE: | |
+ if (From!=&Noone) { | |
+ text=g_strdup_printf(_("%s has left the game."),Data); | |
+ display_message(text); g_free(text); | |
+ } | |
+ break; | |
+ case C_RENAME: | |
+ text=g_strdup_printf(_("%s will now be known as %s."), | |
+ GetPlayerName(From),Data); | |
+ SetPlayerName(From,Data); | |
+ mvaddstr(22,0,text); g_free(text); nice_wait(); | |
+ break; | |
+ case C_PRINTMESSAGE: | |
+ PrintMessage(Data); | |
+ nice_wait(); | |
+ break; | |
+ case C_FIGHTPRINT: | |
+ pt=Data; | |
+ wrd=GetNextWord(&pt,NULL); | |
+ while (wrd) { | |
+ DisplayFightMessage(wrd); | |
+ wrd=GetNextWord(&pt,NULL); | |
+ } | |
+ break; | |
+ case C_SUBWAYFLASH: | |
+ DisplayFightMessage(NULL); | |
+ for (list=FirstClient;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ tmp->Flags &= ~FIGHTING; | |
+ } | |
+ for (i=0;i<4;i++) { | |
+ print_location(_("S U B W A Y")); | |
+ refresh(); | |
+ MicroSleep(100000); | |
+ print_location(""); | |
+ refresh(); | |
+ MicroSleep(100000); | |
+ } | |
+ print_location(Location[(int)To->IsAt].Name); | |
+ break; | |
+ case C_QUESTION: | |
+ pt=Data; | |
+ wrd=GetNextWord(&pt,""); | |
+ PrintMessage(pt); | |
+ addch(' '); | |
+ i=GetKey(wrd,wrd,FALSE,TRUE); | |
+ wrd=g_strdup_printf("%c",i); | |
+ SendClientMessage(To,C_NONE,C_ANSWER, | |
+ From==&Noone ? NULL : From,wrd,To); | |
+ g_free(wrd); | |
+ break; | |
+ case C_LOANSHARK: | |
+ LoanShark(To); | |
+ SendClientMessage(To,C_NONE,C_DONE,NULL,NULL,To); | |
+ break; | |
+ case C_BANK: | |
+ Bank(To); | |
+ SendClientMessage(To,C_NONE,C_DONE,NULL,NULL,To); | |
+ break; | |
+ case C_GUNSHOP: | |
+ GunShop(To); | |
+ SendClientMessage(To,C_NONE,C_DONE,NULL,NULL,To); | |
+ break; | |
+ case C_UPDATE: | |
+ if (From==&Noone) { | |
+ ReceivePlayerData(Data,To); | |
+ print_status(To,1); refresh(); | |
+ } else { | |
+ DisplaySpyReports(Data,From,To); | |
+ } | |
+ break; | |
+ case C_NEWNAME: | |
+ clear_line(22); clear_line(23); | |
+ attrset(TextAttr); | |
+ mvaddstr(22,0,_("Unfortunately, somebody else is already " | |
+ "using \"your\" name. Please change it.")); | |
+ change_name(ReallyTo,1); | |
+ break; | |
+ default: | |
+ if (!Handled) { | |
+ text=g_strdup_printf("%s^%c^%s^%s",GetPlayerName(From),Code, | |
+ GetPlayerName(To),Data); | |
+ mvaddstr(22,0,text); g_free(text); nice_wait(); | |
+ } | |
+ break; | |
+ } | |
+ g_free(Data); | |
+} | |
+ | |
+void PrepareHighScoreScreen() { | |
+/* Responds to a "starthiscore" message by clearing the screen and */ | |
+/* displaying the title for the high scores screen */ | |
+ char *text; | |
+ attrset(TextAttr); | |
+ clear_screen(); | |
+ attrset(TitleAttr); | |
+ text=_("H I G H S C O R E S"); | |
+ mvaddstr(0,(Width-strlen(text))/2,text); | |
+ attrset(TextAttr); | |
+} | |
+ | |
+void PrintHighScore(char *Data) { | |
+/* Prints a high score coded in "Data"; first word is the index of the */ | |
+/* score (i.e. y screen coordinate), second word is the text, the first */ | |
+/* letter of which identifies whether it's to be printed bold or not. */ | |
+ char *cp; | |
+ int index; | |
+ cp=Data; | |
+ index=GetNextInt(&cp,0); | |
+ if (!cp || strlen(cp)<2) return; | |
+ move(index+2,0); | |
+ attrset(TextAttr); | |
+ if (cp[0]=='B') standout(); | |
+ addstr(&cp[1]); | |
+ if (cp[0]=='B') standend(); | |
+} | |
+ | |
+void PrintMessage(char *text) { | |
+/* Prints a message "text" received via. a "printmessage" message in the */ | |
+/* bottom part of the screen. */ | |
+ int i,line; | |
+ attrset(TextAttr); | |
+ clear_line(16); | |
+ for (i=0;i<strlen(text);i++) { | |
+ if (text[i]!='^') { | |
+ clear_exceptfor(i+1); | |
+ break; | |
+ } | |
+ } | |
+ line=17; move(line,1); | |
+ for (i=0;i<strlen(text);i++) { | |
+ if (text[i]=='^') { | |
+ line++; move(line,1); | |
+ } else addch(text[i]); | |
+ } | |
+} | |
+ | |
+void GunShop(Player *Play) { | |
+/* Allows player "Play" to buy and sell guns interactively. Passes the */ | |
+/* decisions on to the server for sanity checking and implementation. */ | |
+ int i,c,c2; | |
+ gchar *text,*prstr; | |
+ print_status(Play,0); | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ for (i=0;i<NumGun;i++) { | |
+ text=g_strdup_printf("%c. %-22s %12s",'A'+i,Gun[i].Name, | |
+ prstr=FormatPrice(Gun[i].Price)); | |
+ mvaddstr(17+i/2,(i%2)*40+1,text); | |
+ g_free(prstr); g_free(text); | |
+ } | |
+ while (1) { | |
+ text=_("Will you B>uy, S>ell, or L>eave? "); | |
+ attrset(PromptAttr); | |
+ clear_line(22); | |
+ mvaddstr(22,40-strlen(text)/2,text); | |
+ attrset(TextAttr); | |
+ c=GetKey(_("BSL"),"BSL",FALSE,FALSE); | |
+ if (c=='L') break; | |
+ if (c=='S' || c=='B') { | |
+ clear_line(22); | |
+ if (c=='S' && TotalGunsCarried(Play)==0) { | |
+ text=g_strdup_printf(_("You don't have any %s to sell!"), | |
+ Names.Guns); | |
+ mvaddstr(22,(Width-strlen(text))/2,text); g_free(text); | |
+ nice_wait(); | |
+ clear_line(23); | |
+ continue; | |
+ } else if (c=='B' && TotalGunsCarried(Play)>=Play->Bitches.Carried+2)… | |
+ text=g_strdup_printf(_("You'll need more %s to carry any more %s!"… | |
+ Names.Bitches,Names.Guns); | |
+ mvaddstr(22,(Width-strlen(text))/2,text); g_free(text); | |
+ nice_wait(); | |
+ clear_line(23); | |
+ continue; | |
+ } | |
+ attrset(PromptAttr); | |
+ if (c=='B') { | |
+ mvaddstr(22,20,_("What do you wish to buy? ")); | |
+ } else { | |
+ mvaddstr(22,20,_("What do you wish to sell? ")); | |
+ } | |
+ curs_set(1); | |
+ attrset(TextAttr); | |
+ c2=bgetch(); c2=toupper(c2); | |
+ if (c2>='A' && c2<'A'+NumGun) { | |
+ c2-='A'; | |
+ addstr(Gun[c2].Name); | |
+ if (c=='B') { | |
+ if (Gun[c2].Space > Play->CoatSize) { | |
+ clear_line(22); | |
+ text=g_strdup_printf(_("You don't have enough space to " | |
+ "carry that %s!"),Names.Gun); | |
+ mvaddstr(22,(Width-strlen(text))/2,text); g_free(text); | |
+ nice_wait(); | |
+ clear_line(23); | |
+ continue; | |
+ } else if (Gun[c2].Price > Play->Cash) { | |
+ clear_line(22); | |
+ text=g_strdup_printf(_("You don't have enough cash to buy " | |
+ "that %s!"),Names.Gun); | |
+ mvaddstr(22,(Width-strlen(text))/2,text); g_free(text); | |
+ nice_wait(); | |
+ clear_line(23); | |
+ continue; | |
+ } | |
+ Play->Cash -= Gun[c2].Price; | |
+ Play->CoatSize -= Gun[c2].Space; | |
+ Play->Guns[c2].Carried++; | |
+ } else if (c=='S') { | |
+ if (Play->Guns[c2].Carried == 0) { | |
+ clear_line(22); | |
+ mvaddstr(22,10,_("You don't have any to sell!")); | |
+ nice_wait(); clear_line(23); continue; | |
+ } | |
+ Play->Cash += Gun[c2].Price; | |
+ Play->CoatSize += Gun[c2].Space; | |
+ Play->Guns[c2].Carried--; | |
+ } | |
+ text=g_strdup_printf("gun^%d^%d",c2,c=='B' ? 1 : -1); | |
+ SendClientMessage(Play,C_NONE,C_BUYOBJECT,NULL,text,Play); | |
+ g_free(text); | |
+ print_status(Play,0); | |
+ } | |
+ } | |
+ } | |
+ print_status(Play,1); | |
+} | |
+ | |
+void LoanShark(Player *Play) { | |
+/* Allows player "Play" to pay off loans interactively. */ | |
+ gchar *text,*prstr; | |
+ price_t money; | |
+ while (1) { | |
+ clear_bottom(); | |
+ attrset(PromptAttr); | |
+ text=nice_input(_("How much money do you pay back? "),19,1,1,NULL); | |
+ attrset(TextAttr); | |
+ money=strtoprice(text); g_free(text); | |
+ if (money<0) money=0; | |
+ if (money>Play->Debt) money=Play->Debt; | |
+ if (money>Play->Cash) { | |
+ mvaddstr(20,1,_("You don't have that much money!")); | |
+ nice_wait(); | |
+ } else { | |
+ SendClientMessage(Play,C_NONE,C_PAYLOAN,NULL, | |
+ (prstr=pricetostr(money)),Play); | |
+ g_free(prstr); | |
+ break; | |
+ } | |
+ } | |
+} | |
+ | |
+void Bank(Player *Play) { | |
+/* Allows player "Play" to pay in or withdraw money from the bank */ | |
+/* interactively. */ | |
+ gchar *text,*prstr; | |
+ price_t money; | |
+ int c; | |
+ while (1) { | |
+ clear_bottom(); | |
+ attrset(PromptAttr); | |
+ mvaddstr(18,1,_("Do you want to D>eposit money, W>ithdraw money, " | |
+ "or L>eave ? ")); | |
+ attrset(TextAttr); | |
+ c=GetKey(_("DWL"),"DWL",FALSE,FALSE); | |
+ if (c=='L') return; | |
+ text=nice_input(_("How much money? "),19,1,1,NULL); | |
+ money=strtoprice(text); g_free(text); | |
+ if (money<0) money=0; | |
+ if (c=='W') money=-money; | |
+ if (money>Play->Cash) { | |
+ mvaddstr(20,1,_("You don't have that much money!")); | |
+ nice_wait(); | |
+ } else if (-money > Play->Bank) { | |
+ mvaddstr(20,1,_("There isn't that much money in the bank...")); | |
+ nice_wait(); | |
+ } else if (money==0) { | |
+ break; | |
+ } else { | |
+ SendClientMessage(Play,C_NONE,C_DEPOSIT,NULL, | |
+ (prstr=pricetostr(money)),Play); | |
+ g_free(prstr); | |
+ break; | |
+ } | |
+ } | |
+} | |
+ | |
+int GetKey(char *allowed,char *orig_allowed,gboolean AllowOther, | |
+ gboolean PrintAllowed) { | |
+/* Waits for keyboard input; will only accept a key listed in the */ | |
+/* "allowed" string. This string may have been translated; thus */ | |
+/* the "orig_allowed" string contains the untranslated keys. */ | |
+/* Returns the untranslated key corresponding to the key pressed */ | |
+/* (e.g. if allowed[2] is pressed, orig_allowed[2] is returned) */ | |
+/* Case insensitive. If "AllowOther" is TRUE, keys other than the */ | |
+/* given selection are allowed, and cause a zero return value. */ | |
+ int i,c; | |
+ curs_set(1); | |
+ c=0; | |
+ if (!allowed || strlen(allowed)==0) return 0; | |
+ if (PrintAllowed) { | |
+ addch('[' | TextAttr); | |
+ for (i=0;i<strlen(allowed);i++) { | |
+ if (i>0) addch('/' | TextAttr); | |
+ addch(allowed[i] | TextAttr); | |
+ } | |
+ addch(']' | TextAttr); | |
+ addch(' ' | TextAttr); | |
+ } | |
+ while (1) { | |
+ c=bgetch(); c=toupper(c); | |
+ for (i=0;i<strlen(allowed);i++) if (allowed[i]==c) { | |
+ addch(c | TextAttr); | |
+ curs_set(0); return orig_allowed[i]; | |
+ } | |
+ if (AllowOther) break; | |
+ } | |
+ curs_set(0); | |
+ return 0; | |
+} | |
+ | |
+void clear_line(int line) { | |
+/* Clears one whole line on the curses screen */ | |
+ int i; | |
+ move(line,0); | |
+ for (i=0;i<Width;i++) addch(' '); | |
+} | |
+ | |
+void clear_exceptfor(int skip) { | |
+/* Clears the bottom of the screen (i.e. from line 16 to line 23) */ | |
+/* except for the top "skip" lines */ | |
+ int i; | |
+ for (i=16+skip;i<=23;i++) clear_line(i); | |
+} | |
+ | |
+ | |
+void clear_bottom() { | |
+/* Clears screen lines 16 to 23 */ | |
+ int i; | |
+ for (i=16;i<=23;i++) clear_line(i); | |
+} | |
+ | |
+void clear_screen() { | |
+/* Clears the entire screen; 24 lines of 80 characters each */ | |
+ int i; | |
+ for (i=0;i<Depth;i++) clear_line(i); | |
+} | |
+ | |
+void nice_wait() { | |
+/* Displays a prompt on the bottom screen line and waits for the user */ | |
+/* to press a key */ | |
+ gchar *text; | |
+ attrset(PromptAttr); | |
+ text=_("Press any key..."); | |
+ mvaddstr(23,(Width-strlen(text))/2,text); | |
+ bgetch(); | |
+ attrset(TextAttr); | |
+} | |
+ | |
+void DisplayFightMessage(char *text) { | |
+/* Handles the display of messages pertaining to player-player fights */ | |
+/* in the lower part of screen (fighting sub-screen). Adds the new line */ | |
+/* of text in "text" and scrolls up previous messages if necessary */ | |
+/* If "text" is NULL, initialises the area */ | |
+/* If "text" is a blank string, redisplays the message area */ | |
+/* Messages are displayed from lines 16 to 20; line 22 is used for */ | |
+/* the prompt for the user */ | |
+ static char Messages[5][79]; | |
+ static int x,y; | |
+ char *textpt; | |
+ int i; | |
+ if (text==NULL) { | |
+ x=0; y=15; | |
+ for (i=0;i<5;i++) Messages[i][0]='\0'; | |
+ return; | |
+ } | |
+ textpt=text; | |
+ if (!textpt[0]) { | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ for (i=16;i<=20;i++) { | |
+ mvaddstr(i,1,Messages[i-16]); | |
+ } | |
+ } else while(textpt[0]) { | |
+ if (y==20) for (i=0;i<4;i++) { | |
+ strcpy(Messages[i],Messages[i+1]); | |
+ } | |
+ if (y<20) y++; | |
+ strncpy(Messages[y-16],textpt,78); Messages[y-16][78]='\0'; | |
+ if (strlen(textpt)<=78) break; | |
+ textpt+=78; | |
+ } | |
+} | |
+ | |
+void display_message(char *buf) { | |
+/* Displays a network message "buf" in the message area (lines */ | |
+/* 10 to 14) scrolling previous messages up */ | |
+/* If "buf" is NULL, clears the message area */ | |
+/* If "buf" is a blank string, redisplays the message area */ | |
+ int x,y; | |
+ int wid; | |
+ static char Messages[5][200]; | |
+ char *bufpt; | |
+ wid = Width-4 < 200 ? Width-4 : 200; | |
+ if (!buf) { | |
+ for (y=0;y<5;y++) { | |
+ memset(Messages[y],' ',200); | |
+ if (Network) { | |
+ mvaddch(y+10,0,' ' | TextAttr); | |
+ addch(ACS_VLINE | StatsAttr); | |
+ for (x=0;x<wid;x++) { | |
+ addch(' ' | StatsAttr); | |
+ } | |
+ addch(ACS_VLINE | StatsAttr); | |
+ } | |
+ } | |
+ return; | |
+ } | |
+ if (!Network) return; | |
+ bufpt=buf; | |
+ while (bufpt[0]!=0) { | |
+ memmove(Messages[0],Messages[1],200*4); | |
+ memset(Messages[4],' ',200); | |
+ memcpy(Messages[4],bufpt,strlen(bufpt)>wid ? wid : strlen(bufpt)); | |
+ if (strlen(bufpt)<=wid) break; | |
+ bufpt+=wid; | |
+ } | |
+ for (y=0;y<5;y++) for (x=0;x<wid;x++) { | |
+ mvaddch(y+10,x+2,Messages[y][x] | StatsAttr); | |
+ } | |
+ refresh(); | |
+} | |
+ | |
+void print_location(char *text) { | |
+/* Displays the string "text" at the top of the screen. Usually used for */ | |
+/* displaying the current location or the "Subway" flash. */ | |
+ int i; | |
+ if (!text) return; | |
+ attrset(LocationAttr); | |
+ move(0,Width/2-9); | |
+ for (i=0;i<18;i++) addch(' '); | |
+ mvaddstr(0,(Width-strlen(text))/2,text); | |
+ attrset(TextAttr); | |
+} | |
+ | |
+void print_status(Player *Play,char DispDrug) { | |
+/* Displays the status of player "Play" - i.e. the current turn, the */ | |
+/* location, bitches, available space, cash, guns, health and bank */ | |
+/* details. If "DispDrugs" is TRUE, displays the carried drugs on the */ | |
+/* right hand side of the screen; if FALSE, displays the carried guns. */ | |
+ int i,c; | |
+ gchar *prstr,*caps; | |
+ GString *text; | |
+ | |
+ text=g_string_new(NULL); | |
+ attrset(TitleAttr); | |
+ g_string_sprintf(text,"%s%02d%s",Names.Month,Play->Turn,Names.Year); | |
+ mvaddstr(0,3,text->str); | |
+ | |
+ attrset(StatsAttr); | |
+ for (i=2;i<=14;i++) { | |
+ mvaddch(i,1,ACS_VLINE); | |
+ mvaddch(i,Width-2,ACS_VLINE); | |
+ } | |
+ mvaddch(1,1,ACS_ULCORNER); | |
+ for (i=0;i<Width-4;i++) addch(ACS_HLINE); | |
+ addch(ACS_URCORNER); | |
+ | |
+ mvaddch(1,Width/2,ACS_TTEE); | |
+ for (i=2;i<=(Network ? 8 : 13);i++) { | |
+ move(i,2); | |
+ for (c=2;c<Width/2;c++) addch(' '); | |
+ addch(ACS_VLINE); | |
+ for (c=Width/2+1;c<Width-2;c++) addch(' '); | |
+ } | |
+ if (!Network) { | |
+ mvaddch(14,1,ACS_LLCORNER); | |
+ for (i=0;i<Width-4;i++) addch(ACS_HLINE); | |
+ addch(ACS_LRCORNER); | |
+ mvaddch(14,Width/2,ACS_BTEE); | |
+ } else { | |
+ mvaddch(9,1,ACS_LTEE); | |
+ for (i=0;i<Width-4;i++) addch(ACS_HLINE); | |
+ addch(ACS_RTEE); | |
+ mvaddstr(9,15,_("Messages")); | |
+ mvaddch(9,Width/2,ACS_BTEE); | |
+ mvaddch(15,1,ACS_LLCORNER); | |
+ for (i=0;i<Width-4;i++) addch(ACS_HLINE); | |
+ addch(ACS_LRCORNER); | |
+ } | |
+ | |
+ mvaddstr(1,Width/4-2,_("Stats")); | |
+ | |
+ attrset(StatsAttr); | |
+ g_string_sprintf(text,_("Cash %17s"),prstr=FormatPrice(Play->Cash)); | |
+ g_free(prstr); | |
+ mvaddstr(3,9,text->str); | |
+ g_string_sprintf(text,"%-19s%3d",caps=InitialCaps(Names.Guns), | |
+ TotalGunsCarried(Play)); | |
+ g_free(caps); | |
+ mvaddstr(Network ? 4 : 5,9,text->str); | |
+ g_string_sprintf(text,_("Health %3d"),Play->Health); | |
+ mvaddstr(Network ? 5 : 7,9,text->str); | |
+ g_string_sprintf(text,_("Bank %17s"),prstr=FormatPrice(Play->Bank)); | |
+ g_free(prstr); | |
+ mvaddstr(Network ? 6 : 9,9,text->str); | |
+ if (Play->Debt>0) attrset(DebtAttr); | |
+ g_string_sprintf(text,_("Debt %17s"),prstr=FormatPrice(Play->Debt)); | |
+ g_free(prstr); | |
+ mvaddstr(Network ? 7 : 11,9,text->str); | |
+ attrset(TitleAttr); | |
+ if (WantAntique) g_string_sprintf(text,_("Space %6d"),Play->CoatSize); | |
+ else { | |
+ g_string_sprintf(text,_("%s %3d Space %6d"), | |
+ caps=InitialCaps(Names.Bitches), | |
+ Play->Bitches.Carried,Play->CoatSize); | |
+ g_free(caps); | |
+ } | |
+ mvaddstr(0,Width-2-strlen(text->str),text->str); | |
+ print_location(Location[(int)Play->IsAt].Name); | |
+ attrset(StatsAttr); | |
+ | |
+ c=0; | |
+ if (DispDrug) { | |
+ if (WantAntique) mvaddstr(1,Width*3/4-5,_("Trenchcoat")); | |
+ else { | |
+ caps=InitialCaps(Names.Drugs); | |
+ mvaddstr(1,Width*3/4-strlen(caps)/2,caps); | |
+ g_free(caps); | |
+ } | |
+ for (i=0;i<NumDrug;i++) { | |
+ if (Play->Drugs[i].Carried>0) { | |
+ g_string_sprintf(text,"%-7s %3d",Drug[i].Name, | |
+ Play->Drugs[i].Carried); | |
+ mvaddstr(3+c/2,Width/2+3+(c%2)*17,text->str); | |
+ c++; | |
+ } | |
+ } | |
+ } else { | |
+ caps=InitialCaps(Names.Guns); | |
+ mvaddstr(1,Width*3/4-strlen(caps)/2,caps); | |
+ g_free(caps); | |
+ for (i=0;i<NumGun;i++) { | |
+ if (Play->Guns[i].Carried>0) { | |
+ g_string_sprintf(text,"%-22s %3d",Gun[i].Name, | |
+ Play->Guns[i].Carried); | |
+ mvaddstr(3+c,Width/2+3,text->str); | |
+ c++; | |
+ } | |
+ } | |
+ } | |
+ attrset(TextAttr); | |
+ if (!Network) clear_line(15); | |
+ refresh(); | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+void DisplaySpyReports(char *Data,Player *From,Player *To) { | |
+/* Parses details about player "From" from string "Data" and then */ | |
+/* displays the lot, drugs and guns. */ | |
+ gchar *caps,*text; | |
+ ReceivePlayerData(Data,From); | |
+ | |
+ clear_bottom(); | |
+ text=g_strdup_printf(_("Spy reports for %s"),GetPlayerName(From)); | |
+ mvaddstr(17,1,text); g_free(text); | |
+ | |
+ caps=InitialCaps(Names.Drugs); | |
+ text=g_strdup_printf(_("%s..."),caps); | |
+ mvaddstr(19,20,text); g_free(text); g_free(caps); | |
+ print_status(From,1); nice_wait(); | |
+ clear_line(19); | |
+ caps=InitialCaps(Names.Guns); | |
+ text=g_strdup_printf(_("%s..."),caps); | |
+ mvaddstr(19,20,text); g_free(text); g_free(caps); | |
+ print_status(From,0); nice_wait(); | |
+ | |
+ print_status(To,1); refresh(); | |
+} | |
+ | |
+Player *ListPlayers(Player *Play,char Select,char *Prompt) { | |
+/* Displays the "Prompt" if non-NULL, and then lists all clients */ | |
+/* currently playing dopewars, other than the current player "Play". */ | |
+/* If "Select" is TRUE, gives each player a letter and asks the user */ | |
+/* to select one, which is returned by the function. */ | |
+ Player *tmp=NULL; | |
+ GSList *list; | |
+ int i,c; | |
+ gchar *text; | |
+ | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ if (!FirstClient || (!g_slist_next(FirstClient) && | |
+ FirstClient->data == Play)) { | |
+ text=_("No other players are currently logged on!"); | |
+ mvaddstr(18,(Width-strlen(text))/2,text); | |
+ nice_wait(); | |
+ return 0; | |
+ } | |
+ mvaddstr(16,1,_("Players currently logged on:-")); | |
+ | |
+ i=0; | |
+ for (list=FirstClient;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ if (strcmp(GetPlayerName(tmp),GetPlayerName(Play))==0) continue; | |
+ if (Select) text=g_strdup_printf("%c. %s",'A'+i,GetPlayerName(tmp)); | |
+ else text=g_strdup(GetPlayerName(tmp)); | |
+ mvaddstr(17+i/2,(i%2)*40+1,text); | |
+ g_free(text); | |
+ i++; | |
+ } | |
+ | |
+ if (Prompt) { | |
+ attrset(PromptAttr); mvaddstr(22,10,Prompt); attrset(TextAttr); | |
+ } | |
+ if (Select) { | |
+ curs_set(1); | |
+ attrset(TextAttr); | |
+ c=0; | |
+ while (c<'A' || c>='A'+i) { c=bgetch(); c=toupper(c); } | |
+ if (Prompt) addch(c); | |
+ list=FirstClient; | |
+ while (c>='A') { | |
+ if (list!=FirstClient) list=g_slist_next(list); | |
+ tmp=(Player *)list->data; | |
+ while (strcmp(GetPlayerName(tmp),GetPlayerName(Play))==0) { | |
+ list=g_slist_next(list); | |
+ tmp=(Player *)list->data; | |
+ } | |
+ c--; | |
+ } | |
+ return tmp; | |
+ } else { | |
+ nice_wait(); | |
+ } | |
+ return NULL; | |
+} | |
+ | |
+char *nice_input(char *prompt,int sy,int sx,char digitsonly,char *displaystr) { | |
+/* Displays the given "prompt" (if non-NULL) at coordinates sx,sy and */ | |
+/* allows the user to input a string, which is returned. This is a */ | |
+/* dynamically allocated string, and so must be freed by the calling */ | |
+/* routine. If "digitsonly" is TRUE, the user will be permitted only to */ | |
+/* input numbers, although the suffixes m and k are allowed (the */ | |
+/* strtoprice routine understands this notation for a 1000000 or 1000 */ | |
+/* multiplier) as well as a decimal point (. or ,) */ | |
+/* If "displaystr" is non-NULL, it is taken as a default response. */ | |
+ int i,c,x; | |
+ gboolean DecimalPoint,Suffix; | |
+ GString *text; | |
+ gchar *ReturnString; | |
+ DecimalPoint=Suffix=FALSE; | |
+ x=sx; | |
+ move(sy,x); | |
+ if (prompt) { | |
+ attrset(PromptAttr); | |
+ addstr(prompt); | |
+ x+=strlen(prompt); | |
+ } | |
+ attrset(TextAttr); | |
+ if (displaystr) { | |
+ addstr(displaystr); | |
+ i=strlen(displaystr); | |
+ text=g_string_new(displaystr); | |
+ } else { | |
+ i=0; | |
+ text=g_string_new(""); | |
+ } | |
+ curs_set(1); | |
+ while(1) { | |
+ move(sy+(x+i)/Width,(x+i)%Width); | |
+ c=bgetch(); | |
+ if (c==KEY_ENTER || c=='\n') { | |
+ break; | |
+ } else if ((c==8 || c==KEY_BACKSPACE || c==127) && i>0) { | |
+ move(sy+(x+i-1)/Width,(x+i-1)%Width); | |
+ addch(' '); | |
+ i--; | |
+ if (DecimalPoint && text->str[i]=='.') DecimalPoint=FALSE; | |
+ if (Suffix) Suffix=FALSE; | |
+ g_string_truncate(text,i); | |
+ } else if (!Suffix) { | |
+ if ((digitsonly && c>='0' && c<='9') || | |
+ (!digitsonly && c>=32 && c!='^' && c<127)) { | |
+ g_string_append_c(text,c); | |
+ i++; | |
+ addch(c); | |
+ } else if (digitsonly && (c=='.' || c==',') && !DecimalPoint) { | |
+ g_string_append_c(text,'.'); | |
+ addch(c); | |
+ DecimalPoint=TRUE; | |
+ } else if (digitsonly && (c=='M' || c=='m' || c=='k' || c=='K') | |
+ && !Suffix) { | |
+ g_string_append_c(text,c); | |
+ i++; | |
+ addch(c); | |
+ Suffix=TRUE; | |
+ } | |
+ } | |
+ } | |
+ curs_set(0); | |
+ move(sy,x); | |
+ ReturnString=text->str; | |
+ g_string_free(text,FALSE); /* Leave the buffer to return */ | |
+ return ReturnString; | |
+} | |
+ | |
+static void Curses_DoGame(Player *Play) { | |
+/* Loop which handles the user playing an interactive game (i.e. "Play" */ | |
+/* is a client connected to a server, either locally or remotely) */ | |
+/* dopewars is essentially server-driven, so this loop simply has to */ | |
+/* make the screen look pretty, respond to user keypresses, and react */ | |
+/* to messages from the server. */ | |
+ gchar *buf,*OldName,*TalkMsg,*pt,*prstr; | |
+ GString *text; | |
+ int i,c; | |
+ char IsCarrying; | |
+#if NETWORKING || HAVE_SELECT | |
+ fd_set readfs,writefs; | |
+#endif | |
+ int NumDrugsHere; | |
+ int MaxSock; | |
+ char HaveWorthless; | |
+ Player *tmp; | |
+ struct sigaction sact; | |
+ | |
+ DisplayMode=DM_NONE; | |
+ QuitRequest=FALSE; | |
+ | |
+ ResizedFlag=0; | |
+ sact.sa_handler=ResizeHandle; | |
+ sact.sa_flags=0; | |
+ sigemptyset(&sact.sa_mask); | |
+ if (sigaction(SIGWINCH,&sact,NULL)==-1) { | |
+ g_warning("Cannot install SIGWINCH handler!\n"); | |
+ } | |
+ OldName=g_strdup(GetPlayerName(Play)); | |
+ attrset(TextAttr); clear_screen(); | |
+ display_message(NULL); | |
+ DisplayFightMessage(NULL); | |
+ print_status(Play,1); | |
+ | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ buf=NULL; | |
+ do { | |
+ g_free(buf); | |
+ buf=nice_input(_("Hey dude, what's your name? "),17,1,0,OldName); | |
+ } while (buf[0]==0); | |
+#if NETWORKING | |
+ if (WantNetwork) { | |
+ if (!ConnectToServer(Play)) { end_curses(); exit(1); } | |
+ Play->fd=ClientSock; | |
+ } | |
+#endif /* NETWORKING */ | |
+ print_status(Play,TRUE); | |
+ display_message(""); | |
+ | |
+ SetPlayerName(Play,buf); | |
+ SendClientMessage(NULL,C_NONE,C_NAME,NULL,buf,Play); | |
+ g_free(buf); g_free(OldName); | |
+ | |
+ text=g_string_new(""); | |
+ | |
+ while (1) { | |
+ if (Play->Health==0) DisplayMode=DM_NONE; | |
+ HaveWorthless=0; | |
+ IsCarrying=0; | |
+ for (i=0;i<NumDrug;i++) { | |
+ if (Play->Drugs[i].Carried>0) { | |
+ IsCarrying=1; | |
+ if (Play->Drugs[i].Price==0) HaveWorthless=1; | |
+ } | |
+ } | |
+ switch(DisplayMode) { | |
+ case DM_STREET: | |
+ attrset(TextAttr); | |
+ NumDrugsHere=0; | |
+ for (i=0;i<NumDrug;i++) if (Play->Drugs[i].Price>0) NumDrugsHere++; | |
+ clear_bottom(); | |
+ g_string_sprintf(text,_("Hey dude, the prices of %s here are:"), | |
+ Names.Drugs); | |
+ mvaddstr(16,1,text->str); | |
+ i=-1; | |
+ for (c=0;c<NumDrugsHere;c++) { | |
+ if ((i=GetNextDrugIndex(i,Play))==-1) break; | |
+ g_string_sprintf(text,"%c. %-10s %8s",'A'+c,Drug[i].Name, | |
+ prstr=FormatPrice(Play->Drugs[i].Price)); | |
+ g_free(prstr); | |
+ mvaddstr(17+c/3,(c%3)*25+4,text->str); | |
+ } | |
+ attrset(PromptAttr); | |
+ g_string_assign(text,_("Will you B>uy")); | |
+ if (IsCarrying) g_string_append(text,_(", S>ell")); | |
+ if (HaveWorthless && !WantAntique) g_string_append(text,_(", D>rop… | |
+ if (Network) g_string_append(text,_(", T>alk, P>age, L>ist")); | |
+ if (!WantAntique && (Play->Bitches.Carried>0 || | |
+ Play->Flags&SPYINGON)) { | |
+ g_string_append(text,_(", G>ive")); | |
+ } | |
+ if (Play->Flags & FIGHTING) { | |
+ g_string_append(text,_(", F>ight")); | |
+/* } else if (Play->Flags&TRADING) { | |
+ g_string_append(text,", T>rade");*/ | |
+ } else { | |
+ g_string_append(text,_(", J>et")); | |
+ } | |
+ g_string_append(text,_(", or Q>uit? ")); | |
+ mvaddstr(22,40-strlen(text->str)/2,text->str); | |
+ attrset(TextAttr); | |
+ curs_set(1); | |
+ break; | |
+ case DM_FIGHT: | |
+ DisplayFightMessage(""); | |
+ attrset(PromptAttr); | |
+ g_string_assign(text,_("Do you ")); | |
+ if (Play->Flags&CANSHOOT) { | |
+ if (TotalGunsCarried(Play)>0) g_string_append(text,_("F>ight, "… | |
+ else g_string_append(text,_("S>tand, ")); | |
+ } | |
+ if (Play->Flags&FIGHTING) g_string_append(text,_("R>un, ")); | |
+ g_string_append(text,_("D>eal ")); g_string_append(text,Names.Drug… | |
+ g_string_append(text,_(", or Q>uit? ")); | |
+ mvaddstr(22,40-strlen(text->str)/2,text->str); | |
+ attrset(TextAttr); | |
+ curs_set(1); | |
+ break; | |
+ case DM_DEAL: | |
+ attrset(TextAttr); | |
+ clear_bottom(); | |
+ mvaddstr(16,1,"Your trade:-"); | |
+ mvaddstr(19,1,"His trade:-"); | |
+ g_string_assign(text,"Do you A>dd, R>emove, O>K, D>eal "); | |
+ g_string_append(text,Names.Drugs); | |
+ g_string_append(text,", or Q>uit? "); | |
+ attrset(PromptAttr); | |
+ mvaddstr(22,40-strlen(text->str)/2,text->str); | |
+ attrset(TextAttr); | |
+ curs_set(1); | |
+ break; | |
+ } | |
+ refresh(); | |
+ | |
+ if (QuitRequest) return; | |
+#if NETWORKING | |
+ FD_ZERO(&readfs); | |
+ FD_ZERO(&writefs); | |
+ FD_SET(0,&readfs); MaxSock=1; | |
+ if (Client) { | |
+ FD_SET(Play->fd,&readfs); | |
+ if (Play->WriteBuf.DataPresent) FD_SET(Play->fd,&writefs); | |
+ MaxSock=ClientSock+2; | |
+ } | |
+ if (bselect(MaxSock,&readfs,&writefs,NULL,NULL)==-1) { | |
+ if (errno==EINTR) { | |
+ CheckForResize(Play); | |
+ continue; | |
+ } | |
+ perror("bselect"); exit(1); | |
+ } | |
+ if (Client && FD_ISSET(Play->fd,&readfs)) { | |
+ if (!ReadConnectionBufferFromWire(Play)) { | |
+ attrset(TextAttr); | |
+ clear_line(22); | |
+ mvaddstr(22,0,_("Connection to server lost! " | |
+ "Reverting to single player mode")); | |
+ nice_wait(); | |
+ SwitchToSinglePlayer(Play); | |
+ print_status(Play,TRUE); | |
+ } else { | |
+ while ((pt=ReadFromConnectionBuffer(Play))!=NULL) { | |
+ HandleClientMessage(pt,Play); | |
+ g_free(pt); | |
+ } | |
+ if (QuitRequest) return; | |
+ } | |
+ } | |
+ if (Client && FD_ISSET(Play->fd,&writefs)) { | |
+ WriteConnectionBufferToWire(Play); | |
+ } | |
+ if (FD_ISSET(0,&readfs)) { | |
+#elif HAVE_SELECT | |
+ FD_ZERO(&readfs); | |
+ FD_SET(0,&readfs); MaxSock=1; | |
+ if (bselect(MaxSock,&readfs,NULL,NULL,NULL)==-1) { | |
+ if (errno==EINTR) { | |
+ CheckForResize(Play); | |
+ continue; | |
+ } | |
+ perror("bselect"); exit(1); | |
+ } | |
+#endif /* NETWORKING */ | |
+ if (DisplayMode==DM_STREET) { | |
+ c=GetKey(_("BSDTPLGFJQ"),"BSDTPLGFJQ",TRUE,FALSE); | |
+ } else if (DisplayMode==DM_FIGHT) { | |
+ c=GetKey(_("DRFSQ"),"DRFSQ",TRUE,FALSE); | |
+ } else c=0; | |
+#if ! (NETWORKING || HAVE_SELECT) | |
+ CheckForResize(Play); | |
+#endif | |
+ if (DisplayMode==DM_STREET) { | |
+ if (c=='J' && !(Play->Flags&FIGHTING)) { | |
+ jet(Play,TRUE); | |
+ } else if (c=='F' && Play->Flags&FIGHTING) { | |
+ DisplayMode=DM_FIGHT; | |
+ } else if (c=='T' && Play->Flags&TRADING) { | |
+ DisplayMode=DM_DEAL; | |
+ } else if (c=='B') { | |
+ DealDrugs(Play,TRUE); | |
+ } else if (c=='S' && IsCarrying) { | |
+ DealDrugs(Play,FALSE); | |
+ } else if (c=='D' && HaveWorthless && !WantAntique) { | |
+ DropDrugs(Play); | |
+ } else if (c=='G' && !WantAntique && Play->Bitches.Carried>0) { | |
+ GiveErrand(Play); | |
+ } else if (c=='Q') { | |
+ if (want_to_quit()==1) { | |
+ DisplayMode=DM_NONE; | |
+ clear_bottom(); | |
+ SendClientMessage(Play,C_NONE,C_WANTQUIT,NULL,NULL,Play); | |
+ } | |
+ } else if (c=='L' && Network) { | |
+ attrset(PromptAttr); | |
+ mvaddstr(23,20,_("List what? P>layers or S>cores? ")); | |
+ i=GetKey(_("PS"),"PS",TRUE,FALSE); | |
+ if (i=='P') { | |
+ ListPlayers(Play,FALSE,NULL); | |
+ } else if (i=='S') { | |
+ DisplayMode=DM_NONE; | |
+ SendClientMessage(Play,C_NONE,C_REQUESTSCORE,NULL,NULL,Play); | |
+ } | |
+ } else if (c=='P' && Network) { | |
+ tmp=ListPlayers(Play,TRUE, | |
+ _("Whom do you want to page (talk privately to) ? ")); | |
+ if (tmp) { | |
+ attrset(TextAttr); clear_line(22); | |
+ TalkMsg=nice_input("Talk: ",22,0,0,NULL); | |
+ if (TalkMsg[0]) { | |
+ SendClientMessage(Play,C_NONE,C_MSGTO,tmp,TalkMsg,Play); | |
+ buf=g_strdup_printf("%s->%s: %s",GetPlayerName(Play), | |
+ GetPlayerName(tmp),TalkMsg); | |
+ display_message(buf); | |
+ g_free(buf); | |
+ } | |
+ g_free(TalkMsg); | |
+ } | |
+ } else if (c=='T' && Client) { | |
+ attrset(TextAttr); clear_line(22); | |
+ TalkMsg=nice_input(_("Talk: "),22,0,0,NULL); | |
+ if (TalkMsg[0]) { | |
+ SendClientMessage(Play,C_NONE,C_MSG,NULL,TalkMsg,Play); | |
+ buf=g_strdup_printf("%s: %s",GetPlayerName(Play),TalkMsg); | |
+ display_message(buf); | |
+ g_free(buf); | |
+ } | |
+ g_free(TalkMsg); | |
+ } | |
+ } else if (DisplayMode==DM_FIGHT) { | |
+ switch(c) { | |
+ case 'D': | |
+ DisplayMode=DM_STREET; | |
+ break; | |
+ case 'R': | |
+ jet(Play,TRUE); | |
+ break; | |
+ case 'F': | |
+ if (TotalGunsCarried(Play)>0 && Play->Flags&CANSHOOT) { | |
+ buf=g_strdup_printf("%c",c); | |
+ Play->Flags &= ~CANSHOOT; | |
+ SendClientMessage(Play,C_NONE,C_FIGHTACT,NULL,buf,Play); | |
+ g_free(buf); | |
+ } | |
+ break; | |
+ case 'S': | |
+ if (TotalGunsCarried(Play)==0 && Play->Flags&CANSHOOT) { | |
+ buf=g_strdup_printf("%c",c); | |
+ Play->Flags &= ~CANSHOOT; | |
+ SendClientMessage(Play,C_NONE,C_FIGHTACT,NULL,buf,Play); | |
+ g_free(buf); | |
+ } | |
+ break; | |
+ case 'Q': | |
+ if (want_to_quit()==1) { | |
+ DisplayMode=DM_NONE; clear_bottom(); | |
+ SendClientMessage(Play,C_NONE,C_WANTQUIT,NULL,NULL,Play); | |
+ } | |
+ break; | |
+ } | |
+ } else if (DisplayMode==DM_DEAL) { | |
+ switch(c) { | |
+ case 'D': | |
+ DisplayMode=DM_STREET; | |
+ break; | |
+ case 'Q': | |
+ if (want_to_quit()==1) { | |
+ DisplayMode=DM_NONE; clear_bottom(); | |
+ SendClientMessage(Play,C_NONE,C_WANTQUIT,NULL,NULL,Play); | |
+ } | |
+ break; | |
+ } | |
+ } | |
+#if NETWORKING | |
+ } | |
+#endif | |
+ curs_set(0); | |
+ } | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+void CursesLoop() { | |
+ char c; | |
+ gchar *Name=NULL; | |
+ Player *Play; | |
+ | |
+ start_curses(); | |
+ Width=COLS; Depth=LINES; | |
+ | |
+/* Set up message handlers */ | |
+ ClientMessageHandlerPt = HandleClientMessage; | |
+ SocketWriteTestPt = NULL; | |
+ | |
+ display_intro(); | |
+ | |
+ c='Y'; | |
+ while(c=='Y') { | |
+ Play=g_new(Player,1); | |
+ FirstClient=AddPlayer(0,Play,FirstClient); | |
+ SetPlayerName(Play,Name); | |
+ Curses_DoGame(Play); | |
+ g_free(Name); Name=g_strdup(GetPlayerName(Play)); | |
+ ShutdownNetwork(); | |
+ CleanUpServer(); | |
+ attrset(TextAttr); | |
+ mvaddstr(23,20,_("Play again? ")); | |
+ c=GetKey(_("YN"),"YN",TRUE,TRUE); | |
+ } | |
+ g_free(Name); | |
+ end_curses(); | |
+} | |
+ | |
+#else | |
+ | |
+#include <glib.h> | |
+ | |
+void CursesLoop() { | |
+ g_print(_("No curses client available - rebuild the binary passing the\n" | |
+ "--enable-curses-client option to configure, or use a windowed\n" | |
+ "client (if available) instead!\n")); | |
+} | |
+ | |
+#endif /* CURSES_CLIENT */ | |
diff --git a/src/curses_client.h b/src/curses_client.h | |
t@@ -0,0 +1,31 @@ | |
+/* curses_client.h dopewars client using the (n)curses console library */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+ | |
+#ifndef __CURSES_CLIENT_H__ | |
+#define __CURSES_CLIENT_H__ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+void CursesLoop(); | |
+ | |
+#endif | |
diff --git a/src/dopeid.h b/src/dopeid.h | |
t@@ -0,0 +1,81 @@ | |
+#define SpyReportsDia 1017 | |
+#define EB_NEWNAME 102 | |
+#define NewNameDia 1016 | |
+#define SB_MONEY 120 | |
+#define DebtDialog 1015 | |
+#define ST_MONEY 103 | |
+#define ST_BANK 106 | |
+#define RB_WITHDRAW 102 | |
+#define RB_DEPOSIT 107 | |
+#define ST_CURRENCY 104 | |
+#define EB_MONEY 105 | |
+#define BankDialog 1014 | |
+#define ST_ERRAND 102 | |
+#define LB_ERRANDPLAY 103 | |
+#define ErrandDialog 1013 | |
+#define BT_DEALDRUGS 102 | |
+#define BT_FIGHT 103 | |
+#define BT_RUN 104 | |
+#define FightDialog 1012 | |
+#define EB_FIGHTSTATUS 101 | |
+#define LB_SERVERLIST 113 | |
+#define BT_UPDATE 114 | |
+#define ID_SPY 501 | |
+#define ID_TIPOFF 502 | |
+#define ID_SACKBITCH 503 | |
+#define ID_GETSPY 504 | |
+#define LB_HISCORES 101 | |
+#define HiScoreDia 1011 | |
+#define ST_HOSTNAME 109 | |
+#define ST_PORT 110 | |
+#define CB_ANTIQUE 111 | |
+#define BT_STARTSINGLE 112 | |
+#define InventoryDia 1010 | |
+#define ST_INVENDRUGS 101 | |
+#define LB_INVENDRUGS 103 | |
+#define ST_INVENGUNS 102 | |
+#define LB_INVENGUNS 104 | |
+#define ID_TALKTOALL 201 | |
+#define ID_TALKTOPLAYERS 202 | |
+#define ID_LISTPLAYERS 301 | |
+#define ID_LISTSCORES 302 | |
+#define ID_LISTINVENTORY 303 | |
+#define PlayerListDia 1009 | |
+#define LB_PLAYERLIST 101 | |
+#define TalkDialog 1008 | |
+#define LB_TALKPLAYERS 101 | |
+#define CB_TALKALL 103 | |
+#define EB_TALKMESSAGE 102 | |
+#define BT_TALKSEND 104 | |
+#define ID_CANCEL 110 | |
+#define SB_DEALNUM 109 | |
+#define ED_DEALNUM 105 | |
+#define ST_DEALCARRY 107 | |
+#define ST_DEALNUM 108 | |
+#define ST_DEALTYPE 106 | |
+#define ST_DEALPRICE 103 | |
+#define ST_DEALLIMIT 104 | |
+#define CB_DEALDRUG 102 | |
+#define DealDialog 1005 | |
+#define LB_GUNSHERE 103 | |
+#define LB_GUNSCARRIED 104 | |
+#define BT_BUYGUN 105 | |
+#define BT_SELLGUN 106 | |
+#define ST_GUNSHERE 107 | |
+#define ST_GUNSCARRIED 108 | |
+#define GunShopDia 1006 | |
+#define ST_TEXT 101 | |
+#define QuestionDia 1007 | |
+#define JetDialog 1004 | |
+#define ED_NAME 108 | |
+#define ID_NEWGAME 101 | |
+#define ED_HOSTNAME 105 | |
+#define ED_PORT 106 | |
+#define BT_CONNECT 107 | |
+#define NewGameDialog 1003 | |
+#define ID_OK 101 | |
+#define ID_ABOUT 401 | |
+#define AboutDialog 1002 | |
+#define ID_EXIT 102 | |
+#define MainMenu 1000 | |
+#define MainDialog 1001 | |
diff --git a/src/dopeos.c b/src/dopeos.c | |
t@@ -0,0 +1,349 @@ | |
+/* dopeos.c dopewars - operating-system-specific functions */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#include "dopeos.h" | |
+#include "dopewars.h" | |
+ | |
+#ifdef CYGWIN /* Code for native Win32 build under Cygwin */ | |
+ | |
+#include <conio.h> | |
+ | |
+CHAR_INFO RealScreen[25][80],VirtualScreen[25][80]; | |
+HANDLE hOut,hIn; | |
+ | |
+void refresh() { | |
+ int y; | |
+ COORD size,offset; | |
+ SMALL_RECT screenpos; | |
+ for (y=0;y<Depth;y++) { | |
+ if (memcmp(&RealScreen[y][0],&VirtualScreen[y][0], | |
+ sizeof(CHAR_INFO)*Width)!=0) { | |
+ memcpy(&RealScreen[y][0],&VirtualScreen[y][0], | |
+ Width*sizeof(CHAR_INFO)); | |
+ size.X=Width; size.Y=1; | |
+ offset.X=offset.Y=0; | |
+ screenpos.Left=0; screenpos.Top=y; | |
+ screenpos.Right=Width-1; screenpos.Bottom=y; | |
+ WriteConsoleOutput(hOut,&VirtualScreen[y][0],size, | |
+ offset,&screenpos); | |
+ } | |
+ } | |
+} | |
+ | |
+HANDLE WINAPI GetConHandle(TCHAR *pszName) { | |
+ SECURITY_ATTRIBUTES sa; | |
+ sa.nLength = sizeof(sa); | |
+ sa.lpSecurityDescriptor = NULL; | |
+ sa.bInheritHandle = TRUE; | |
+ return CreateFile(pszName,GENERIC_READ|GENERIC_WRITE, | |
+ FILE_SHARE_READ|FILE_SHARE_WRITE, | |
+ &sa,OPEN_EXISTING,(DWORD)0,(HANDLE)0); | |
+} | |
+ | |
+WORD CurAttr=0,TextAttr=2<<8,PromptAttr=1<<8,TitleAttr=4<<8; | |
+WORD LocationAttr=3<<8,StatsAttr=5<<8,DebtAttr=6<<8; | |
+int Width,Depth,CurX,CurY; | |
+char *optarg; | |
+WORD Attr[10]; | |
+HWND hwndMain; | |
+ | |
+SCREEN *newterm(void *a,void *b,void *c) { | |
+ COORD coord; | |
+ int i; | |
+ coord.X=80; coord.Y=25; | |
+ Width=80; Depth=25; CurAttr=TextAttr; CurX=0; CurY=0; | |
+ for (i=0;i<10;i++) | |
+ Attr[i]=FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN; | |
+ hOut=GetStdHandle(STD_OUTPUT_HANDLE); | |
+ hIn=GetStdHandle(STD_INPUT_HANDLE); | |
+ SetConsoleMode(hIn,0); | |
+/* SetConsoleScreenBufferSize(hOut,coord);*/ | |
+/* clear_screen();*/ | |
+ return NULL; | |
+} | |
+ | |
+void start_color() {} | |
+void init_pair(int index,WORD fg,WORD bg) { | |
+ if (index>=0 && index<10) { | |
+ Attr[index]=0; | |
+ switch(fg) { | |
+ case COLOR_MAGENTA: Attr[index]|=(FOREGROUND_RED+FOREGROUND_BLUE); | |
+ break; | |
+ case COLOR_BLUE: Attr[index]|=FOREGROUND_BLUE; | |
+ break; | |
+ case COLOR_RED: Attr[index]|=FOREGROUND_RED; | |
+ break; | |
+ case COLOR_WHITE: Attr[index]|=(FOREGROUND_RED+FOREGROUND_BLUE+ | |
+ FOREGROUND_GREEN); | |
+ break; | |
+ } | |
+ switch(bg) { | |
+ case COLOR_MAGENTA: Attr[index]|=(BACKGROUND_RED+BACKGROUND_BLUE); | |
+ break; | |
+ case COLOR_BLUE: Attr[index]|=BACKGROUND_BLUE; | |
+ break; | |
+ case COLOR_RED: Attr[index]|=BACKGROUND_RED; | |
+ break; | |
+ case COLOR_WHITE: Attr[index]|=(BACKGROUND_RED+BACKGROUND_BLUE+ | |
+ BACKGROUND_GREEN); | |
+ break; | |
+ } | |
+ } | |
+} | |
+ | |
+void cbreak() {} | |
+void noecho() {} | |
+void nodelay(void *a,char b) {} | |
+ | |
+void keypad(void *a,char b) {} | |
+void curs_set(BOOL visible) { | |
+ CONSOLE_CURSOR_INFO ConCurInfo; | |
+ move(CurY,CurX); | |
+ ConCurInfo.dwSize=10; | |
+ ConCurInfo.bVisible=visible; | |
+ SetConsoleCursorInfo(hOut,&ConCurInfo); | |
+} | |
+ | |
+void endwin() { | |
+ CurAttr=0; | |
+/* clear_screen(); */ | |
+ refresh(); | |
+ curs_set(1); | |
+/* CloseHandle(hIn); | |
+ CloseHandle(hOut);*/ | |
+} | |
+ | |
+void move(int y,int x) { | |
+ COORD coord; | |
+ CurX=x; CurY=y; | |
+ coord.X=x; coord.Y=y; | |
+ SetConsoleCursorPosition(hOut,coord); | |
+} | |
+ | |
+void attrset(WORD newAttr) { | |
+ CurAttr=newAttr; | |
+} | |
+ | |
+void addstr(char *str) { | |
+ int i; | |
+ for (i=0;i<strlen(str);i++) addch(str[i]); | |
+ move(CurY,CurX); | |
+} | |
+ | |
+void addch(int ch) { | |
+ int attr; | |
+ VirtualScreen[CurY][CurX].Char.AsciiChar=ch%256; | |
+ attr=ch>>8; | |
+ if (attr>0) VirtualScreen[CurY][CurX].Attributes=Attr[attr]; | |
+ else VirtualScreen[CurY][CurX].Attributes=Attr[CurAttr>>8]; | |
+ if (++CurX>=Width) { | |
+ CurX=0; | |
+ if (++CurY>=Depth) CurY=0; | |
+ } | |
+} | |
+ | |
+void mvaddstr(int y,int x,char *str) { | |
+ move(y,x); addstr(str); | |
+} | |
+ | |
+void mvaddch(int y,int x,int ch) { | |
+ move(y,x); addch(ch); | |
+} | |
+ | |
+int bgetch() { | |
+/* Waits for the user to press a key */ | |
+ DWORD NumRead; | |
+ char Buffer[10]; | |
+ refresh(); | |
+ ReadConsole(hIn,Buffer,1,&NumRead,NULL); | |
+ return (int)(Buffer[0]); | |
+} | |
+ | |
+char *index(char *str,char ch) { | |
+ int i; | |
+ for (i=0;i<strlen(str);i++) { if (str[i]==ch) return str+i; } | |
+ return NULL; | |
+} | |
+ | |
+int apos=0; | |
+int getopt(int argc,char *argv[],char *str) { | |
+ int i,c; | |
+ char *pt; | |
+ if (apos>=argc) return EOF; | |
+ if (argv[apos] && argv[apos][0]=='-') { | |
+ for (i=1;i<strlen(argv[apos]);i++) { | |
+ c=argv[apos][i]; | |
+ pt=index(str,c); | |
+ if (pt) { | |
+ if (*(pt+1)==':' && apos<argc-1) { | |
+ optarg=argv[apos+1]; argv[apos+1]=NULL; | |
+ } | |
+ argv[apos][i]='-'; | |
+ return c; | |
+ } | |
+ } | |
+ } | |
+ apos++; | |
+ return 0; | |
+} | |
+ | |
+void sigemptyset(int *mask) {} | |
+void sigaddset(int *mask,int sig) {} | |
+int sigaction(int sig,struct sigaction *sact,char *pt) { return 0; } | |
+void sigprocmask(int flag,int *mask,char *pt) {} | |
+void gettimeofday(void *pt,void *pt2) {} | |
+void standout() {} | |
+void standend() {} | |
+ | |
+gboolean IsKeyPressed() { | |
+ INPUT_RECORD ConsoleIn; | |
+ DWORD NumConsoleIn; | |
+ while (PeekConsoleInput(hIn,&ConsoleIn,1,&NumConsoleIn)) { | |
+ if (NumConsoleIn==1) { | |
+ if (ConsoleIn.EventType==KEY_EVENT && | |
+ ConsoleIn.Event.KeyEvent.bKeyDown) { | |
+ return TRUE; | |
+ } else { | |
+ ReadConsoleInput(hIn,&ConsoleIn,1,&NumConsoleIn); | |
+ } | |
+ } else break; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+int bselect(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfds, | |
+ struct timeval *tm) { | |
+ int retval; | |
+ struct timeval tv,*tp; | |
+ fd_set localread,localexcept; | |
+ char CheckKbHit=0,KeyRead; | |
+ if (nfds==0 && tm) { Sleep(tm->tv_sec*1000+tm->tv_usec/1000); return 0; } | |
+ if (FD_ISSET(0,readfds)) { | |
+ if (nfds==1) return 1; | |
+ tp=&tv; | |
+ CheckKbHit=1; | |
+ FD_CLR(0,readfds); | |
+ } else tp=tm; | |
+ KeyRead=0; | |
+ while (1) { | |
+ tv.tv_sec=0; | |
+ tv.tv_usec=250000; | |
+ | |
+ if (readfds) memcpy(&localread,readfds,sizeof(fd_set)); | |
+ if (exceptfds) memcpy(&localexcept,exceptfds,sizeof(fd_set)); | |
+ if (CheckKbHit && IsKeyPressed()) tv.tv_usec=0; | |
+ retval=select(nfds,readfds,writefds,exceptfds,tp); | |
+ if (retval==SOCKET_ERROR) return retval; | |
+ if (CheckKbHit && IsKeyPressed()) { | |
+ retval++; FD_SET(0,readfds); | |
+ } | |
+ if (retval>0 || !CheckKbHit) break; | |
+ if (CheckKbHit && tm) { | |
+ if (tm->tv_usec >= 250000) tm->tv_usec-=250000; | |
+ else if (tm->tv_sec) { | |
+ tm->tv_usec+=750000; | |
+ tm->tv_sec--; | |
+ } else break; | |
+ } | |
+ if (readfds) memcpy(readfds,&localread,sizeof(fd_set)); | |
+ if (exceptfds) memcpy(exceptfds,&localexcept,sizeof(fd_set)); | |
+ } | |
+ return retval; | |
+} | |
+ | |
+#if NETWORKING | |
+void fcntl(SOCKET s,int fsetfl,long cmd) { | |
+ unsigned long param=1; | |
+ ioctlsocket(s,cmd,¶m); | |
+} | |
+ | |
+void StartNetworking() { | |
+ WSADATA wsaData; | |
+ if (WSAStartup(MAKEWORD(1,0),&wsaData)!=0) { | |
+ printf("Cannot initialise WinSock!\n"); | |
+ exit(1); | |
+ } | |
+} | |
+ | |
+void StopNetworking() { WSACleanup(); } | |
+ | |
+void SetReuse(SOCKET sock) { | |
+ BOOL tmp; | |
+ tmp=TRUE; | |
+ if (setsockopt(sock,SOL_SOCKET, | |
+ SO_REUSEADDR,(char *)(&tmp),sizeof(tmp))==-1) { | |
+ perror("setsockopt"); exit(1); | |
+} | |
+} | |
+#endif /* NETWORKING */ | |
+ | |
+#else /* Code for Unix build */ | |
+ | |
+#ifdef HAVE_UNISTD_H | |
+#include <unistd.h> | |
+#endif | |
+ | |
+int Width,Depth; | |
+ | |
+#ifdef CURSES_CLIENT | |
+int bgetch() { | |
+/* Calls the curses getch() function; if the key pressed is Ctrl-L */ | |
+/* then automatically clears and redraws the screen, otherwise */ | |
+/* passes the key back to the calling routine */ | |
+ int c; | |
+ c=getch(); | |
+ while (c=='\f') { | |
+ wrefresh(curscr); | |
+ c=getch(); | |
+ } | |
+ return c; | |
+} | |
+#endif | |
+ | |
+#if NETWORKING | |
+void StartNetworking() {} | |
+void StopNetworking() {} | |
+void SetReuse(int sock) { | |
+ int i; | |
+ i=1; | |
+ if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR, | |
+ &i,sizeof(i))==-1) { | |
+ perror("setsockopt"); exit(1); | |
+ } | |
+} | |
+#endif /* NETWORKING */ | |
+ | |
+#endif /* CYGWIN */ | |
+ | |
+void MicroSleep(int microsec) { | |
+/* On systems with select, sleep for "microsec" microseconds */ | |
+#if HAVE_SELECT | |
+ struct timeval tv; | |
+ tv.tv_sec=0; | |
+ tv.tv_usec=100000; | |
+ bselect(0,NULL,NULL,NULL,&tv); | |
+#endif | |
+} | |
+ | |
diff --git a/src/dopeos.h b/src/dopeos.h | |
t@@ -0,0 +1,196 @@ | |
+/* dopeos.h dopewars - operating system-specific function */ | |
+/* definitions */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+#ifndef __DOPEOS_H__ | |
+#define __DOPEOS_H__ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#ifdef CYGWIN /* Definitions for native Win32 build */ | |
+#include <windows.h> | |
+#include <string.h> | |
+ | |
+#if NETWORKING | |
+#include <winsock.h> | |
+#endif | |
+ | |
+#include <stdio.h> | |
+ | |
+void refresh(); | |
+HANDLE WINAPI GetConHandle (TCHAR * pszName); | |
+extern WORD TextAttr,PromptAttr,TitleAttr,LocationAttr,StatsAttr,DebtAttr; | |
+extern int Width,Depth; | |
+ | |
+#define COLOR_MAGENTA 1 | |
+#define COLOR_BLACK 2 | |
+#define COLOR_WHITE 3 | |
+#define COLOR_BLUE 4 | |
+#define COLOR_RED 5 | |
+ | |
+#define SIGWINCH 0 | |
+#define SIGPIPE 0 | |
+#define SIG_BLOCK 0 | |
+#define SIG_UNBLOCK 0 | |
+ | |
+struct sigaction { | |
+ void *sa_handler; | |
+ int sa_flags; | |
+ int sa_mask; | |
+}; | |
+ | |
+void sigemptyset(int *mask); | |
+void sigaddset(int *mask,int sig); | |
+int sigaction(int sig,struct sigaction *sact,char *pt); | |
+void sigprocmask(int flag,int *mask,char *pt); | |
+ | |
+#define COLS Width | |
+#define LINES Depth | |
+ | |
+#define ACS_VLINE 179 | |
+#define ACS_ULCORNER 218 | |
+#define ACS_HLINE 196 | |
+#define ACS_URCORNER 191 | |
+#define ACS_TTEE 194 | |
+#define ACS_LLCORNER 192 | |
+#define ACS_LRCORNER 217 | |
+#define ACS_BTEE 193 | |
+#define ACS_LTEE 195 | |
+#define ACS_RTEE 180 | |
+ | |
+typedef int SCREEN; | |
+#define stdscr 0 | |
+#define curscr 0 | |
+#define KEY_ENTER 13 | |
+#define KEY_BACKSPACE 8 | |
+#define A_BOLD 0 | |
+ | |
+SCREEN *newterm(void *,void *,void *); | |
+void start_color(); | |
+void init_pair(int index,WORD fg,WORD bg); | |
+void cbreak(); | |
+void noecho(); | |
+void nodelay(void *,char); | |
+void keypad(void *,char); | |
+void curs_set(BOOL visible); | |
+void endwin(); | |
+void move(int y,int x); | |
+void attrset(WORD newAttr); | |
+void addstr(char *str); | |
+void addch(int ch); | |
+void mvaddstr(int x,int y,char *str); | |
+void mvaddch(int x,int y,int ch); | |
+int bgetch(); | |
+#define erase() clear_screen() | |
+char *index(char *str,char ch); | |
+int getopt(int argc,char *argv[],char *str); | |
+extern char *optarg; | |
+#define F_SETFL 0 | |
+#define O_NONBLOCK FIONBIO | |
+ | |
+typedef int ssize_t; | |
+void gettimeofday(void *pt,void *pt2); | |
+void standout(); | |
+void standend(); | |
+void endwin(); | |
+int bselect(int nfds,fd_set *readfds,fd_set *writefds,fd_set *exceptfs, | |
+ struct timeval *tm); | |
+ | |
+#if NETWORKING | |
+void fcntl(SOCKET s,int fsetfl,long cmd); | |
+#define CloseSocket(sock) closesocket(sock) | |
+void StartNetworking(); | |
+void StopNetworking(); | |
+void SetReuse(SOCKET sock); | |
+#endif | |
+ | |
+#else /* Definitions for Unix build */ | |
+ | |
+#include <sys/types.h> | |
+ | |
+#ifdef NETWORKING | |
+#include <sys/socket.h> | |
+#include <netinet/in.h> | |
+#include <arpa/inet.h> | |
+#include <netdb.h> | |
+#include <unistd.h> | |
+#endif /* NETWORKING */ | |
+ | |
+/* Only include sys/wait.h on those systems which support it */ | |
+#if HAVE_SYS_WAIT_H | |
+#include <sys/wait.h> | |
+#endif | |
+ | |
+/* Now make definitions if they haven't been done properly */ | |
+#ifndef WEXITSTATUS | |
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) | |
+#endif | |
+ | |
+#ifndef WIFEXITED | |
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) | |
+#endif | |
+ | |
+/* Include a suitable curses-type library */ | |
+#if HAVE_LIBNCURSES | |
+#include <ncurses.h> | |
+#elif HAVE_LIBCURSES | |
+#include <curses.h> | |
+#elif HAVE_LIBCUR_COLR | |
+#include <curses_colr/curses.h> | |
+#endif | |
+ | |
+extern int Width,Depth; | |
+ | |
+#define PromptAttr (COLOR_PAIR(1)) | |
+#define TextAttr (COLOR_PAIR(2)) | |
+#define LocationAttr (COLOR_PAIR(3)|A_BOLD) | |
+#define TitleAttr (COLOR_PAIR(4)) | |
+#define StatsAttr (COLOR_PAIR(5)) | |
+#define DebtAttr (COLOR_PAIR(6)) | |
+ | |
+int bgetch(); | |
+#define bselect select | |
+ | |
+#if NETWORKING | |
+#define CloseSocket(sock) close(sock) | |
+void StartNetworking(); | |
+void StopNetworking(); | |
+void SetReuse(int sock); | |
+#endif /* NETWORKING */ | |
+ | |
+#endif /* CYGWIN */ | |
+ | |
+void MicroSleep(int microsec); | |
+ | |
+#ifndef SOCKET_ERROR | |
+#define SOCKET_ERROR -1 | |
+#endif | |
+ | |
+#ifndef WEXITSTATUS | |
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) | |
+#endif | |
+ | |
+#ifndef WIFEXITED | |
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) | |
+#endif | |
+ | |
+#endif /* __DOPEOS_H__ */ | |
diff --git a/src/dopewars.c b/src/dopewars.c | |
t@@ -0,0 +1,1496 @@ | |
+/* dopewars.c dopewars - general purpose routines and initialisation */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#include "dopewars.h" | |
+ | |
+#include <stdio.h> | |
+#include <stdlib.h> | |
+#include <ctype.h> | |
+#ifdef HAVE_UNISTD_H | |
+#include <unistd.h> | |
+#endif | |
+#include <string.h> | |
+#include <errno.h> | |
+#include <signal.h> | |
+#include <curses_client.h> | |
+#include <gtk_client.h> | |
+#include <win32_client.h> | |
+#include <glib.h> | |
+#include "dopeos.h" | |
+#include "message.h" | |
+#include "serverside.h" | |
+#include "AIPlayer.h" | |
+ | |
+int ClientSock,ListenSock; | |
+char Network,Client,Server,NotifyMetaServer,AIPlayer; | |
+/* dopewars acting as standalone TCP server: | |
+ Network=Server=TRUE Client=FALSE | |
+ dopewars acting as client, connecting to standalone server: | |
+ Network=Client=TRUE Server=FALSE | |
+ dopewars in single-player or antique mode: | |
+ Network=Server=Client=FALSE | |
+*/ | |
+int Port=7902,Sanitized=0,ConfigVerbose=0; | |
+char *HiScoreFile=NULL,*ServerName=NULL,*Pager=NULL; | |
+char WantHelp,WantVersion,WantAntique,WantColour,WantNetwork; | |
+char WantedClient; | |
+int NumLocation=0,NumGun=0,NumDrug=0,NumSubway=0,NumPlaying=0,NumStoppedTo=0; | |
+Player Noone; | |
+int LoanSharkLoc=DEFLOANSHARK,BankLoc=DEFBANK,GunShopLoc=DEFGUNSHOP, | |
+ RoughPubLoc=DEFROUGHPUB; | |
+int DrugSortMethod=DS_ATOZ; | |
+int FightTimeout=5,IdleTimeout=14400,ConnectTimeout=300; | |
+int MaxClients=20,AITurnPause=5; | |
+price_t StartCash=2000,StartDebt=5500; | |
+GSList *ServerList=NULL; | |
+ | |
+GScannerConfig ScannerConfig = { | |
+ " \t\n", /* Ignore these characters */ | |
+ G_CSET_a_2_z "_" G_CSET_A_2_Z, /* Valid characters for starting | |
+ an identifier */ | |
+ G_CSET_a_2_z "._-0123456789" G_CSET_A_2_Z, /* Valid characters for | |
+ continuing an identifier */ | |
+ "#\n", /* Single line comments start with # and end with \n */ | |
+ FALSE, /* Are symbols case sensitive? */ | |
+ TRUE, /* Ignore C-style comments? */ | |
+ TRUE, /* Ignore single-line comments? */ | |
+ TRUE, /* Treat C-style comments as single tokens - do not break into | |
+ words? */ | |
+ TRUE, /* Read identifiers as tokens? */ | |
+ TRUE, /* Read single-character identifiers as 1-character strings? */ | |
+ TRUE, /* Allow the parsing of NULL as the G_TOKEN_IDENTIFIER_NULL ? */ | |
+ FALSE, /* Allow symbols (defined by g_scanner_scope_add_symbol) ? */ | |
+ TRUE, /* Allow binary numbers in 0b1110 format ? */ | |
+ TRUE, /* Allow octal numbers in C-style e.g. 034 ? */ | |
+ FALSE, /* Allow floats? */ | |
+ TRUE, /* Allow hex numbers in C-style e.g. 0xFF ? */ | |
+ TRUE, /* Allow hex numbers in $FF format ? */ | |
+ TRUE, /* Allow '' strings (no escaping) ? */ | |
+ TRUE, /* Allow "" strings (\ escapes parsed) ? */ | |
+ TRUE, /* Convert octal, binary and hex to int? */ | |
+ FALSE, /* Convert ints to floats? */ | |
+ FALSE, /* Treat all identifiers as strings? */ | |
+ TRUE, /* Leave single characters (e.g. {,=) unchanged, instead of | |
+ returning G_TOKEN_CHAR ? */ | |
+ FALSE, /* Replace read symbols with the token given by their value, instead | |
+ of G_TOKEN_SYMBOL ? */ | |
+ FALSE /* scope_0_fallback... */ | |
+}; | |
+ | |
+struct LOCATION StaticLocation,*Location=NULL; | |
+struct DRUG StaticDrug,*Drug=NULL; | |
+struct GUN StaticGun,*Gun=NULL; | |
+struct COPS Cops = { 70,2,65,2,5,2,30 }; | |
+struct NAMES Names = { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, | |
+ NULL,NULL,NULL,NULL }; | |
+struct NAMES DefaultNames = { | |
+ N_("bitch"),N_("bitches"),N_("gun"),N_("guns"),N_("drug"),N_("drugs"), | |
+ N_("12-"),N_("-1984"), | |
+ N_("Hardass"),N_("Bob"),N_("the Loan Shark"),N_("the Bank"), | |
+ N_("Dan\'s House of Guns"),N_("the pub") | |
+}; | |
+struct PRICES Prices = { | |
+ 20000,10000 | |
+}; | |
+struct BITCH Bitch = { | |
+ 50000,150000 | |
+}; | |
+struct METASERVER MetaServer = { 0,0,0,NULL,NULL,NULL,NULL,NULL }; | |
+struct METASERVER DefaultMetaServer = { | |
+ 1,80,7802,"bellatrix.pcl.ox.ac.uk","/~ben/cgi-bin/server.pl","","", | |
+ "dopewars server" | |
+}; | |
+int NumTurns=31; | |
+ | |
+struct GLOBALS Globals[NUMGLOB] = { | |
+ { &Port,NULL,NULL,NULL,"Port",N_("Network port to connect to"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&HiScoreFile,NULL,"HiScoreFile", | |
+ N_("Name of the high score file"),NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&ServerName,NULL,"Server",N_("Name of the server to connect to"… | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &MetaServer.Active,NULL,NULL,NULL,"MetaServer.Active", | |
+ N_("Non-zero if server should report to a metaserver"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &MetaServer.HttpPort,NULL,NULL,NULL,"MetaServer.HttpPort", | |
+ N_("Port for metaserver communication (client)"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &MetaServer.UdpPort,NULL,NULL,NULL,"MetaServer.UdpPort", | |
+ N_("Port for metaserver communication (server)"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&MetaServer.Name,NULL,"MetaServer.Name", | |
+ N_("Metaserver name to report server details to"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&MetaServer.Path,NULL,"MetaServer.Path", | |
+ N_("Path of the CGI script on the metaserver (client)"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&MetaServer.LocalName,NULL,"MetaServer.LocalName", | |
+ N_("Preferred hostname of your server machine"),NULL,NULL,0,"",NULL,NULL … | |
+ { NULL,NULL,&MetaServer.Password,NULL,"MetaServer.Password", | |
+ N_("Authentication for LocalName with the metaserver"),NULL,NULL,0,"",NUL… | |
+ NULL }, | |
+ { NULL,NULL,&MetaServer.Comment,NULL,"MetaServer.Comment", | |
+ N_("Server description, reported to the metaserver"),NULL,NULL,0,"",NULL, | |
+ NULL }, | |
+ { NULL,NULL,&Pager,NULL,"Pager", | |
+ N_("Program used to display multi-page output"),NULL,NULL,0,"",NULL,NULL … | |
+ { &NumTurns,NULL,NULL,NULL,"NumTurns", | |
+ N_("No. of game turns (if 0, game never ends)"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &Sanitized,NULL,NULL,NULL,"Sanitized",N_("Random events are sanitized"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &ConfigVerbose,NULL,NULL,NULL,"ConfigVerbose", | |
+ N_("Be verbose in processing config file"),NULL,NULL,0,"",NULL,NULL }, | |
+ { &NumLocation,NULL,NULL,NULL,"NumLocation", | |
+ N_("Number of locations in the game"), | |
+ (void **)(&Location),NULL,sizeof(struct LOCATION),"",NULL, | |
+ ResizeLocations }, | |
+ { &NumGun,NULL,NULL,NULL,"NumGun",N_("Number of guns in the game"), | |
+ (void **)(&Gun),NULL,sizeof(struct GUN),"",NULL,ResizeGuns }, | |
+ { &NumDrug,NULL,NULL,NULL,"NumDrug",N_("Number of drugs in the game"), | |
+ (void **)(&Drug),NULL,sizeof(struct DRUG),"",NULL,ResizeDrugs }, | |
+ { &LoanSharkLoc,NULL,NULL,NULL,"LoanShark",N_("Location of the Loan Shark"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &BankLoc,NULL,NULL,NULL,"Bank",N_("Location of the bank"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &GunShopLoc,NULL,NULL,NULL,"GunShop",N_("Location of the gun shop"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &RoughPubLoc,NULL,NULL,NULL,"RoughPub",N_("Location of the pub"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Names.LoanSharkName,NULL,"LoanSharkName", | |
+ N_("Name of the loan shark"),NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Names.BankName,NULL,"BankName", | |
+ N_("Name of the bank"),NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Names.GunShopName,NULL,"GunShopName", | |
+ N_("Name of the gun shop"),NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Names.RoughPubName,NULL,"RoughPubName", | |
+ N_("Name of the pub"),NULL,NULL,0,"",NULL,NULL }, | |
+ { &DrugSortMethod,NULL,NULL,NULL,"DrugSortMethod", | |
+ N_("Sort key for listing available drugs"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &FightTimeout,NULL,NULL,NULL,"FightTimeout", | |
+ N_("No. of seconds in which to return fire"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &IdleTimeout,NULL,NULL,NULL,"IdleTimeout", | |
+ N_("Players are disconnected after this many seconds"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &ConnectTimeout,NULL,NULL,NULL,"ConnectTimeout", | |
+ N_("Time in seconds for connections to be made or broken"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &MaxClients,NULL,NULL,NULL,"MaxClients", | |
+ N_("Maximum number of TCP/IP connections"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &AITurnPause,NULL,NULL,NULL,"AITurnPause", | |
+ N_("Seconds between turns of AI players"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,&StartCash,NULL,NULL,"StartCash", | |
+ N_("Amount of cash that each player starts with"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,&StartDebt,NULL,NULL,"StartDebt", | |
+ N_("Amount of debt that each player starts with"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&StaticLocation.Name,NULL,"Name",N_("Name of each location"), | |
+ (void **)(&Location),&StaticLocation, | |
+ sizeof(struct LOCATION),"Location",&NumLocation,NULL }, | |
+ { &(StaticLocation.PolicePresence),NULL,NULL,NULL,"PolicePresence", | |
+ N_("Police presence at each location (%)"), | |
+ (void **)(&Location),&StaticLocation, | |
+ sizeof(struct LOCATION),"Location",&NumLocation,NULL }, | |
+ { &(StaticLocation.MinDrug),NULL,NULL,NULL,"MinDrug", | |
+ N_("Minimum number of drugs at each location"), | |
+ (void **)(&Location),&StaticLocation, | |
+ sizeof(struct LOCATION),"Location",&NumLocation,NULL }, | |
+ { &(StaticLocation.MaxDrug),NULL,NULL,NULL,"MaxDrug", | |
+ N_("Maximum number of drugs at each location"), | |
+ (void **)(&Location),&StaticLocation, | |
+ sizeof(struct LOCATION),"Location",&NumLocation,NULL }, | |
+ { NULL,NULL,&StaticDrug.Name,NULL,"Name", | |
+ N_("Name of each drug"), | |
+ (void **)(&Drug),&StaticDrug, | |
+ sizeof(struct DRUG),"Drug",&NumDrug,NULL }, | |
+ { NULL,&(StaticDrug.MinPrice),NULL,NULL,"MinPrice", | |
+ N_("Minimum normal price of each drug"), | |
+ (void **)(&Drug),&StaticDrug, | |
+ sizeof(struct DRUG),"Drug",&NumDrug,NULL }, | |
+ { NULL,&(StaticDrug.MaxPrice),NULL,NULL,"MaxPrice", | |
+ N_("Maximum normal price of each drug"), | |
+ (void **)(&Drug),&StaticDrug, | |
+ sizeof(struct DRUG),"Drug",&NumDrug,NULL }, | |
+ { &(StaticDrug.Cheap),NULL,NULL,NULL,"Cheap", | |
+ N_("Non-zero if this drug can be specially cheap"), | |
+ (void **)(&Drug),&StaticDrug, | |
+ sizeof(struct DRUG),"Drug",&NumDrug,NULL }, | |
+ { &(StaticDrug.Expensive),NULL,NULL,NULL,"Expensive", | |
+ N_("Non-zero if this drug can be specially expensive"), | |
+ (void **)(&Drug),&StaticDrug, | |
+ sizeof(struct DRUG),"Drug",&NumDrug,NULL }, | |
+ { NULL,NULL,&StaticDrug.CheapStr,NULL,"CheapStr", | |
+ N_("Message displayed when this drug is specially cheap"), | |
+ (void **)(&Drug),&StaticDrug, | |
+ sizeof(struct DRUG),"Drug",&NumDrug,NULL }, | |
+ { NULL,NULL,&Drugs.ExpensiveStr1,NULL,"Drugs.ExpensiveStr1", | |
+ N_("Format string used for expensive drugs 50% of time"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Drugs.ExpensiveStr2,NULL,"Drugs.ExpensiveStr2", | |
+ N_("Format string used for expensive drugs 50% of time"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &(Drugs.CheapDivide),NULL,NULL,NULL,"Drugs.CheapDivide", | |
+ N_("Divider for drug price when it's specially cheap"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &(Drugs.ExpensiveMultiply),NULL,NULL,NULL,"Drugs.ExpensiveMultiply", | |
+ N_("Multiplier for specially expensive drug prices"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&StaticGun.Name,NULL,"Name", | |
+ N_("Name of each gun"), | |
+ (void **)(&Gun),&StaticGun, | |
+ sizeof(struct GUN),"Gun",&NumGun,NULL }, | |
+ { NULL,&(StaticGun.Price),NULL,NULL,"Price", | |
+ N_("Price of each gun"), | |
+ (void **)(&Gun),&StaticGun, | |
+ sizeof(struct GUN),"Gun",&NumGun,NULL }, | |
+ { &(StaticGun.Space),NULL,NULL,NULL,"Space", | |
+ N_("Space taken by each gun"), | |
+ (void **)(&Gun),&StaticGun, | |
+ sizeof(struct GUN),"Gun",&NumGun,NULL }, | |
+ { &(StaticGun.Damage),NULL,NULL,NULL,"Damage", | |
+ N_("Damage done by each gun"), | |
+ (void **)(&Gun),&StaticGun, | |
+ sizeof(struct GUN),"Gun",&NumGun,NULL }, | |
+ { &(Cops.EscapeProb),NULL,NULL,NULL,"Cops.EscapeProb", | |
+ N_("% probability of escaping from Officer Hardass"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &(Cops.DeputyEscape),NULL,NULL,NULL,"Cops.DeputyEscape", | |
+ N_("Modifier to EscapeProb for each extra deputy"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &(Cops.HitProb),NULL,NULL,NULL,"Cops.HitProb", | |
+ N_("% probability that Officer Hardass hits you"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &(Cops.DeputyHit),NULL,NULL,NULL,"Cops.DeputyHit", | |
+ N_("Modifier to HitProb for each extra deputy"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &(Cops.Damage),NULL,NULL,NULL,"Cops.Damage", | |
+ N_("Maximum damage done to you by each cop"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &(Cops.Toughness),NULL,NULL,NULL,"Cops.Toughness", | |
+ N_("Toughness of (difficulty of hitting) each cop"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { &(Cops.DropProb),NULL,NULL,NULL,"Cops.DropProb", | |
+ N_("% probability that the cops catch you dropping drugs"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Names.Bitch,NULL,"Names.Bitch", | |
+ N_("Word used to denote a single \"bitch\""),NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Names.Bitches,NULL,"Names.Bitches", | |
+ N_("Word used to denote two or more \"bitches\""), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Names.Gun,NULL,"Names.Gun", | |
+ N_("Word used to denote a single gun or equivalent"),NULL,NULL,0,"",NULL, | |
+ NULL }, | |
+ { NULL,NULL,&Names.Guns,NULL,"Names.Guns", | |
+ N_("Word used to denote two or more guns"),NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Names.Drug,NULL,"Names.Drug", | |
+ N_("Word used to denote a single drug or equivalent"),NULL,NULL,0,"",NULL, | |
+ NULL }, | |
+ { NULL,NULL,&Names.Drugs,NULL,"Names.Drugs", | |
+ N_("Word used to denote two or more drugs"),NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Names.Month,NULL,"Names.Month", | |
+ N_("Text prefixed to the turn number (i.e. the month)"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,&Names.Year,NULL,"Names.Year", | |
+ N_("Text appended to the turn number (i.e. the year)"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL, &Names.Officer,NULL,"Names.Officer", | |
+ N_("Name of the police officer"),NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL, &Names.ReserveOfficer,NULL,"Names.ReserveOfficer", | |
+ N_("Name of the reserve police officer"),NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,&Prices.Spy,NULL,NULL,"Prices.Spy", | |
+ N_("Cost for a bitch to spy on the enemy"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,&Prices.Tipoff,NULL,NULL,"Prices.Tipoff", | |
+ N_("Cost for a bitch to tipoff the cops to an enemy"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,&Bitch.MinPrice,NULL,NULL,"Bitch.MinPrice", | |
+ N_("Minimum price to hire a bitch"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,&Bitch.MaxPrice,NULL,NULL,"Bitch.MaxPrice", | |
+ N_("Maximum price to hire a bitch"), | |
+ NULL,NULL,0,"",NULL,NULL }, | |
+ { NULL,NULL,NULL,&SubwaySaying,"SubwaySaying", | |
+ N_("List of things which you overhear on the subway"), | |
+ NULL,NULL,0,"",&NumSubway,ResizeSubway }, | |
+ { &NumSubway,NULL,NULL,NULL,"NumSubwaySaying", | |
+ N_("Number of subway sayings"), | |
+ NULL,NULL,0,"",NULL,ResizeSubway }, | |
+ { NULL,NULL,NULL,&Playing,"Playing", | |
+ N_("List of songs which you can hear playing"), | |
+ NULL,NULL,0,"",&NumPlaying,ResizePlaying }, | |
+ { &NumPlaying,NULL,NULL,NULL,"NumPlaying", | |
+ N_("Number of playing songs"), | |
+ NULL,NULL,0,"",NULL,ResizePlaying }, | |
+ { NULL,NULL,NULL,&StoppedTo,"StoppedTo", | |
+ N_("List of things which you can stop to do"), | |
+ NULL,NULL,0,"",&NumStoppedTo,ResizeStoppedTo }, | |
+ { &NumStoppedTo,NULL,NULL,NULL,"NumStoppedTo", | |
+ N_("Number of things which you can stop to do"), | |
+ NULL,NULL,0,"",NULL,ResizeStoppedTo } | |
+}; | |
+ | |
+char *Discover[NUMDISCOVER] = { | |
+ N_("escaped"), N_("defected"), N_("was shot") }; | |
+ | |
+char **Playing=NULL; | |
+char *DefaultPlaying[NUMPLAYING] = { | |
+ N_("`Are you Experienced` by Jimi Hendrix"), | |
+ N_("`Cheeba Cheeba` by Tone Loc"), | |
+ N_("`Comin` in to Los Angeles` by Arlo Guthrie"), | |
+ N_("`Commercial` by Spanky and Our Gang"), | |
+ N_("`Late in the Evening` by Paul Simon"), | |
+ N_("`Light Up` by Styx"), | |
+ N_("`Mexico` by Jefferson Airplane"), | |
+ N_("`One toke over the line` by Brewer & Shipley"), | |
+ N_("`The Smokeout` by Shel Silverstein"), | |
+ N_("`White Rabbit` by Jefferson Airplane"), | |
+ N_("`Itchycoo Park` by Small Faces"), | |
+ N_("`White Punks on Dope` by the Tubes"), | |
+ N_("`Legend of a Mind` by the Moody Blues"), | |
+ N_("`Eight Miles High` by the Byrds"), | |
+ N_("`Acapulco Gold` by Riders of the Purple Sage"), | |
+ N_("`Kicks` by Paul Revere & the Raiders"), | |
+ N_("the Nixon tapes"), | |
+ N_("`Legalize It` by Mojo Nixon & Skid Roper") | |
+}; | |
+ | |
+char **StoppedTo=NULL; | |
+char *DefaultStoppedTo[NUMSTOPPEDTO] = { | |
+ N_("have a beer"), | |
+ N_("smoke a joint"), | |
+ N_("smoke a cigar"), | |
+ N_("smoke a Djarum"), | |
+ N_("smoke a cigarette") | |
+}; | |
+ | |
+struct GUN DefaultGun[NUMGUN] = { | |
+ { N_("Baretta"),3000,4,5 }, | |
+ { N_(".38 Special"),3500,4,9 }, | |
+ { N_("Ruger"),2900,4,4 }, | |
+ { N_("Saturday Night Special"),3100,4,7 } | |
+}; | |
+ | |
+struct LOCATION DefaultLocation[NUMLOCATION] = { | |
+ { N_("Bronx"),10,NUMDRUG/2+1,NUMDRUG }, | |
+ { N_("Ghetto"),5,NUMDRUG/2+2,NUMDRUG }, | |
+ { N_("Central Park"),15,NUMDRUG/2,NUMDRUG }, | |
+ { N_("Manhattan"),90,NUMDRUG/2-2,NUMDRUG-2 }, | |
+ { N_("Coney Island"),20,NUMDRUG/2,NUMDRUG }, | |
+ { N_("Brooklyn"),70,NUMDRUG/2-2,NUMDRUG-1 }, | |
+ { N_("Queens"),50,NUMDRUG/2,NUMDRUG }, | |
+ { N_("Staten Island"),20,NUMDRUG/2,NUMDRUG } | |
+}; | |
+ | |
+struct DRUG DefaultDrug[NUMDRUG] = { | |
+ { N_("Acid"),1000,4400,1,0, | |
+ N_("The market is flooded with cheap home-made acid!") }, | |
+ { N_("Cocaine"),15000,29000,0,1,"" }, | |
+ { N_("Hashish"),480,1280,1,0,N_("The Marrakesh Express has arrived!") }, | |
+ { N_("Heroin"),5500,13000,0,1,"" }, | |
+ { N_("Ludes"),11,60,1,0, | |
+ N_("Rival drug dealers raided a pharmacy and are selling cheap ludes!") }, | |
+ { N_("MDA"),1500,4400,0,0,"" }, | |
+ { N_("Opium"),540,1250,0,1,"" }, | |
+ { N_("PCP"),1000,2500,0,0,"" }, | |
+ { N_("Peyote"),220,700,0,0,"" }, | |
+ { N_("Shrooms"),630,1300,0,0,"" }, | |
+ { N_("Speed"),90,250,0,1,"" }, | |
+ { N_("Weed"),315,890,1,0,N_("Columbian freighter dusted the Coast Guard! \ | |
+Weed prices have bottomed out!") } | |
+}; | |
+ | |
+struct DRUGS Drugs = { NULL,NULL,0,0 }; | |
+struct DRUGS DefaultDrugs = { | |
+ N_("Cops made a big %s bust! Prices are outrageous!"), | |
+ N_("Addicts are buying %s at ridiculous prices!"), | |
+ 4,4 }; | |
+ | |
+char **SubwaySaying=NULL; | |
+char *DefaultSubwaySaying[NUMSUBWAY] = { | |
+ N_("Wouldn\'t it be funny if everyone suddenly quacked at once?"), | |
+ N_("The Pope was once Jewish, you know"), | |
+ N_("I\'ll bet you have some really interesting dreams"), | |
+ N_("So I think I\'m going to Amsterdam this year"), | |
+ N_("Son, you need a yellow haircut"), | |
+ N_("I think it\'s wonderful what they\'re doing with incense these days"), | |
+ N_("I wasn\'t always a woman, you know"), | |
+ N_("Does your mother know you\'re a dope dealer?"), | |
+ N_("Are you high on something?"), | |
+ N_("Oh, you must be from California"), | |
+ N_("I used to be a hippie, myself"), | |
+ N_("There\'s nothing like having lots of money"), | |
+ N_("You look like an aardvark!"), | |
+ N_("I don\'t believe in Ronald Reagan"), | |
+ N_("Courage! Bush is a noodle!"), | |
+ N_("Haven\'t I seen you on TV?"), | |
+ N_("I think hemorrhoid commercials are really neat!"), | |
+ N_("We\'re winning the war for drugs!"), | |
+ N_("A day without dope is like night"), | |
+ N_("We only use 20% of our brains, so why not burn out the other 80%"), | |
+ N_("I\'m soliciting contributions for Zombies for Christ"), | |
+ N_("I\'d like to sell you an edible poodle"), | |
+ N_("Winners don\'t do drugs... unless they do"), | |
+ N_("Kill a cop for Christ!"), | |
+ N_("I am the walrus!"), | |
+ N_("Jesus loves you more than you will know"), | |
+ N_("I feel an unaccountable urge to dye my hair blue"), | |
+ N_("Wasn\'t Jane Fonda wonderful in Barbarella"), | |
+ N_("Just say No... well, maybe... ok, what the hell!"), | |
+ N_("Would you like a jelly baby?"), | |
+ N_("Drugs can be your friend!") | |
+}; | |
+ | |
+int brandom(int bot,int top) { | |
+/* Returns a random integer not less than bot and less than top */ | |
+ return (int)((float)(top-bot)*rand()/(RAND_MAX+1.0))+bot; | |
+} | |
+ | |
+int CountPlayers(GSList *First) { | |
+/* Returns the total numbers of players in the list starting at "First"; */ | |
+/* players still in the process of connecting or leaving are ignored. */ | |
+ GSList *list; | |
+ Player *Play; | |
+ int count=0; | |
+ for (list=First;list;list=g_slist_next(list)) { | |
+ Play=(Player *)list->data; | |
+ if (strlen(GetPlayerName(Play))>0) count++; | |
+ } | |
+ return count; | |
+} | |
+ | |
+GSList *AddPlayer(int fd,Player *NewPlayer,GSList *First) { | |
+/* Adds the new Player structure "NewPlayer" to the linked list */ | |
+/* pointed to by "First", and initialises all fields. Returns the new */ | |
+/* start of the list. If this function is called by the server, then */ | |
+/* it should pass the file descriptor of the socket used to */ | |
+/* communicate with the client player. */ | |
+ NewPlayer->fd=-1; | |
+ NewPlayer->Name=NULL; | |
+ SetPlayerName(NewPlayer,NULL); | |
+ NewPlayer->IsAt=0; | |
+ NewPlayer->Attacked=NULL; | |
+ NewPlayer->EventNum=E_NONE; | |
+ NewPlayer->FightTimeout=NewPlayer->ConnectTimeout=NewPlayer->IdleTimeout=0; | |
+ NewPlayer->Guns=(Inventory *)g_malloc0(NumGun*sizeof(Inventory)); | |
+ NewPlayer->Drugs=(Inventory *)g_malloc0(NumDrug*sizeof(Inventory)); | |
+ InitList(&(NewPlayer->SpyList)); | |
+ InitList(&(NewPlayer->TipList)); | |
+ NewPlayer->Turn=1; | |
+ NewPlayer->Cash=StartCash; | |
+ NewPlayer->Debt=StartDebt; | |
+ NewPlayer->Bank=0; | |
+ NewPlayer->Health=100; | |
+ NewPlayer->CoatSize=100; | |
+ NewPlayer->Bitches.Carried=8; | |
+ NewPlayer->Flags=0; | |
+ NewPlayer->ReadBuf.Data=NewPlayer->WriteBuf.Data=NULL; | |
+ NewPlayer->ReadBuf.Length=NewPlayer->WriteBuf.Length=0; | |
+ NewPlayer->ReadBuf.DataPresent=NewPlayer->WriteBuf.DataPresent=0; | |
+ if (Server) NewPlayer->fd=fd; | |
+ return g_slist_append(First,(gpointer)NewPlayer); | |
+} | |
+ | |
+void UpdatePlayer(Player *Play) { | |
+/* Redimensions the Gun and Drug lists for "Play" */ | |
+ Play->Guns=(Inventory *)g_realloc(Play->Guns,NumGun*sizeof(Inventory)); | |
+ Play->Drugs=(Inventory *)g_realloc(Play->Drugs,NumDrug*sizeof(Inventory)); | |
+} | |
+ | |
+GSList *RemovePlayer(Player *Play,GSList *First) { | |
+/* Removes the Player structure pointed to by "Play" from the linked */ | |
+/* list starting at "First". The client socket is freed if called */ | |
+/* from the server. The new start of the list is returned. */ | |
+ g_assert(Play); | |
+ g_assert(First); | |
+ | |
+ First=g_slist_remove(First,(gpointer)Play); | |
+ if (Server && Play->fd>=0) { | |
+ CloseSocket(Play->fd); | |
+ } | |
+ ClearList(&(Play->SpyList)); | |
+ ClearList(&(Play->TipList)); | |
+ g_free(Play->ReadBuf.Data); | |
+ g_free(Play->WriteBuf.Data); | |
+ g_free(Play->Name); | |
+ g_free(Play); | |
+ return First; | |
+} | |
+ | |
+void CopyPlayer(Player *Dest,Player *Src) { | |
+/* Copies player "Src" to player "Dest" */ | |
+ if (!Dest || !Src) return; | |
+ Dest->Turn=Src->Turn; | |
+ Dest->Cash=Src->Cash; | |
+ Dest->Debt=Src->Debt; | |
+ Dest->Bank=Src->Bank; | |
+ Dest->Health=Src->Health; | |
+ ClearInventory(Dest->Guns,Dest->Drugs); | |
+ AddInventory(Dest->Guns,Src->Guns,NumGun); | |
+ AddInventory(Dest->Drugs,Src->Drugs,NumDrug); | |
+ Dest->CoatSize=Src->CoatSize; | |
+ Dest->IsAt=Src->IsAt; | |
+ g_free(Dest->Name); | |
+ Dest->Name=g_strdup(Src->Name); | |
+ Dest->Bitches.Carried=Src->Bitches.Carried; | |
+ Dest->Flags=Src->Flags; | |
+} | |
+ | |
+char *GetPlayerName(Player *Play) { | |
+ if (Play->Name) return Play->Name; | |
+ else return ""; | |
+} | |
+ | |
+void SetPlayerName(Player *Play,char *Name) { | |
+ if (Play->Name) g_free(Play->Name); | |
+ if (!Name) Play->Name=g_strdup(""); | |
+ else Play->Name = g_strdup(Name); | |
+} | |
+ | |
+Player *GetPlayerByName(char *Name,GSList *First) { | |
+/* Searches the linked list starting at "First" for a Player structure */ | |
+/* with the name "Name". Returns a pointer to this structure, or NULL */ | |
+/* if no match can be found. */ | |
+ GSList *list; | |
+ Player *Play; | |
+ if (Name==NULL || Name[0]==0) return &Noone; | |
+ for (list=First;list;list=g_slist_next(list)) { | |
+ Play=(Player *)list->data; | |
+ if (strcmp(GetPlayerName(Play),Name)==0) return Play; | |
+ } | |
+ return NULL; | |
+} | |
+ | |
+price_t strtoprice(char *buf) { | |
+/* Forms a price based on the string representation in "buf" */ | |
+ int i,buflen,FracNum; | |
+ char digit,minus,suffix; | |
+ gboolean InFrac; | |
+ price_t val=0; | |
+ minus=0; | |
+ InFrac=FALSE; | |
+ if (!buf) return 0; | |
+ buflen=strlen(buf); | |
+ suffix=buf[buflen-1]; | |
+ suffix=toupper(suffix); | |
+ if (suffix=='M') FracNum=6; | |
+ else if (suffix=='K') FracNum=3; | |
+ else FracNum=0; | |
+ for (i=0;i<strlen(buf);i++) { | |
+ digit=buf[i]; | |
+ if (digit=='.' || digit==',') { | |
+ InFrac=TRUE; | |
+ } else if (digit>='0' && digit<='9') { | |
+ if (InFrac && FracNum<=0) break; | |
+ else if (InFrac) FracNum--; | |
+ val*=10; | |
+ val+=(digit-'0'); | |
+ } else if (digit=='-') minus=1; | |
+ } | |
+ for (i=0;i<FracNum;i++) val*=10; | |
+ if (minus) val=-val; | |
+ return val; | |
+} | |
+ | |
+gchar *pricetostr(price_t price) { | |
+/* Prints "price" directly into a dynamically-allocated string buffer */ | |
+/* and returns a pointer to this buffer. It is the responsbility of */ | |
+/* the user to g_free this buffer when it is finished with. */ | |
+ GString *PriceStr; | |
+ gchar *NewBuffer; | |
+ price_t absprice; | |
+ | |
+ if (price<0) absprice=-price; else absprice=price; | |
+ PriceStr=g_string_new(NULL); | |
+ while (absprice!=0) { | |
+ g_string_prepend_c(PriceStr,'0'+(absprice%10)); | |
+ absprice /= 10; | |
+ if (absprice==0) { | |
+ if (price<0) g_string_prepend_c(PriceStr,'-'); | |
+ } | |
+ } | |
+ NewBuffer=PriceStr->str; | |
+ /* Free the string structure, but not the actual char array */ | |
+ g_string_free(PriceStr,FALSE); | |
+ return NewBuffer; | |
+} | |
+ | |
+gchar *FormatPrice(price_t price) { | |
+/* Takes the number in "price" and prints it into a dynamically-allocated */ | |
+/* string, adding commas to split up thousands, and adding a currency */ | |
+/* symbol to the start. Returns a pointer to the string, which must be */ | |
+/* g_free'd by the user when it is finished with. */ | |
+ GString *PriceStr; | |
+ gchar *NewBuffer; | |
+ char thou[10]; | |
+ gboolean First=TRUE; | |
+ price_t absprice; | |
+ PriceStr=g_string_new(NULL); | |
+ if (price<0) absprice=-price; else absprice=price; | |
+ while (First || absprice>0) { | |
+ if (absprice>=1000) sprintf(thou,"%03d",(int)(absprice%1000l)); | |
+ else sprintf(thou,"%d",(int)(price%1000l)); | |
+ price/=1000l; | |
+ absprice/=1000l; | |
+ if (!First) g_string_prepend_c(PriceStr,','); | |
+ g_string_prepend(PriceStr,thou); | |
+ First=FALSE; | |
+ } | |
+ g_string_prepend_c(PriceStr,'$'); | |
+ NewBuffer=PriceStr->str; | |
+ /* Free the string structure only, not the char data */ | |
+ g_string_free(PriceStr,FALSE); | |
+ return NewBuffer; | |
+} | |
+ | |
+int TotalGunsCarried(Player *Play) { | |
+/* Returns the total number of guns being carried by "Play" */ | |
+ int i,c; | |
+ c=0; | |
+ for (i=0;i<NumGun;i++) c+=Play->Guns[i].Carried; | |
+ return c; | |
+} | |
+ | |
+gchar *InitialCaps(gchar *string) { | |
+/* Capitalises the first character of "string" and writes the resultant */ | |
+/* string into a dynamically-allocated copy; the user must g_free this */ | |
+/* string (a pointer to which is returned) when it is no longer needed. */ | |
+ gchar *buf; | |
+ if (!string) return NULL; | |
+ buf=g_strdup(string); | |
+ if (strlen(buf)>=1) buf[0]=toupper(buf[0]); | |
+ return buf; | |
+} | |
+ | |
+char StartsWithVowel(char *string) { | |
+/* Returns TRUE if "string" starts with a vowel */ | |
+ int c; | |
+ if (!string || strlen(string)<1) return FALSE; | |
+ c=toupper(string[0]); | |
+ return (c=='A' || c=='E' || c=='I' || c=='O' || c=='U'); | |
+} | |
+ | |
+int read_string(FILE *fp,char **buf) { | |
+/* Reads a NULL-terminated string into the buffer "buf" from file "fp". */ | |
+/* buf is sized to hold the string; this is a dynamic string and must be */ | |
+/* freed by the calling routine. Returns 0 on success, EOF on failure. */ | |
+ int c; | |
+ GString *text; | |
+ text=g_string_new(""); | |
+ c=0; | |
+ while (1) { | |
+ c=fgetc(fp); | |
+ if (c==EOF || c==0) break; | |
+ else { g_string_append_c(text,(char)c); } | |
+ } | |
+ *buf=text->str; | |
+ /* Free the GString, but not the actual data text->str */ | |
+ g_string_free(text,FALSE); | |
+ if (c==EOF) return EOF; else return 0; | |
+} | |
+ | |
+void ClearInventory(Inventory *Guns,Inventory *Drugs) { | |
+/* This function simply clears the given inventories "Guns" */ | |
+/* and "Drugs" if they are non-NULL */ | |
+ int i; | |
+ if (Guns) for (i=0;i<NumGun;i++) Guns[i].Carried=0; | |
+ if (Drugs) for (i=0;i<NumDrug;i++) Drugs[i].Carried=0; | |
+} | |
+ | |
+char IsInventoryClear(Inventory *Guns,Inventory *Drugs) { | |
+/* Returns TRUE only if "Guns" and "Drugs" contain no objects */ | |
+ int i; | |
+ if (Guns) for (i=0;i<NumGun;i++) if (Guns[i].Carried > 0) return FALSE; | |
+ if (Drugs) for (i=0;i<NumDrug;i++) if (Drugs[i].Carried > 0) return FALSE; | |
+ return TRUE; | |
+} | |
+ | |
+void AddInventory(Inventory *Cumul,Inventory *Add,int Length) { | |
+/* Adds inventory "Add" into the contents of inventory "Cumul" */ | |
+/* Each inventory is of length "Length" */ | |
+ int i; | |
+ for (i=0;i<Length;i++) Cumul[i].Carried+=Add[i].Carried; | |
+} | |
+ | |
+void ChangeSpaceForInventory(Inventory *Guns,Inventory *Drugs, | |
+ Player *Play) { | |
+/* Given the lists of "Guns" and "Drugs" (which the given player "Play" */ | |
+/* must have sufficient room to carry) updates the player's space to */ | |
+/* reflect carrying them. */ | |
+ int i; | |
+ if (Guns) for (i=0;i<NumGun;i++) { | |
+ Play->CoatSize-=Guns[i].Carried*Gun[i].Space; | |
+ } | |
+ if (Drugs) for (i=0;i<NumDrug;i++) { | |
+ Play->CoatSize-=Drugs[i].Carried; | |
+ } | |
+} | |
+ | |
+void TruncateInventoryFor(Inventory *Guns,Inventory *Drugs, | |
+ Player *Play) { | |
+/* Discards items from "Guns" and/or "Drugs" (if non-NULL) if necessary */ | |
+/* such that player "Play" is able to carry them all. The cheapest */ | |
+/* objects are discarded. */ | |
+ int i,Total,CheapIndex; | |
+ int CheapestGun; | |
+ Total=0; | |
+ if (Guns) for (i=0;i<NumGun;i++) Total+=Guns[i].Carried; | |
+ Total+=TotalGunsCarried(Play); | |
+ while (Guns && Total > Play->Bitches.Carried+2) { | |
+ CheapIndex=-1; | |
+ for (i=0;i<NumGun;i++) if (Guns[i].Carried && (CheapIndex==-1 || | |
+ Gun[i].Price <= Gun[CheapIndex].Price)) { | |
+ CheapIndex=i; | |
+ } | |
+ i=Total-Play->Bitches.Carried-2; | |
+ if (Guns[CheapIndex].Carried > i) { | |
+ Guns[CheapIndex].Carried-=i; Total-=i; | |
+ } else { | |
+ Total-=Guns[CheapIndex].Carried; Guns[CheapIndex].Carried=0; | |
+ } | |
+ } | |
+ | |
+ Total=Play->CoatSize; | |
+ if (Guns) for (i=0;i<NumGun;i++) Total-=Guns[i].Carried*Gun[i].Space; | |
+ if (Drugs) for (i=0;i<NumDrug;i++) Total-=Drugs[i].Carried; | |
+ while (Total < 0) { | |
+ CheapestGun=-1; | |
+ CheapIndex=-1; | |
+ if (Guns) for (i=0;i<NumGun;i++) if (Guns[i].Carried && (CheapIndex==-1 … | |
+ Gun[i].Price <= Gun[CheapIndex].Price)) { | |
+ CheapIndex=i; CheapestGun=Gun[i].Price/Gun[i].Space; | |
+ } | |
+ if (Drugs) for (i=0;i<NumDrug;i++) if (Drugs[i].Carried && | |
+ (CheapIndex==-1 || | |
+ (CheapestGun==-1 && Drug[i].MinPrice<=Drug[CheapIndex].MinPrice) || | |
+ (CheapestGun>=0 && Drug[i].MinPrice<=CheapestGun))) { | |
+ CheapIndex=i; CheapestGun=-1; | |
+ } | |
+ if (Guns && CheapestGun>=0) { | |
+ Guns[CheapIndex].Carried--; | |
+ Total+=Gun[CheapIndex].Space; | |
+ } else { | |
+ if (Drugs && Drugs[CheapIndex].Carried >= -Total) { | |
+ Drugs[CheapIndex].Carried += Total; Total=0; | |
+ } else { | |
+ Total+=Drugs[CheapIndex].Carried; Drugs[CheapIndex].Carried=0; | |
+ } | |
+ } | |
+ } | |
+} | |
+ | |
+int IsCarryingRandom(Player *Play,int amount) { | |
+/* Returns an index into the drugs array of a random drug that "Play" is */ | |
+/* carrying at least "amount" of. If no suitable drug is found after 5 */ | |
+/* attempts, returns -1. */ | |
+ int i,ind; | |
+ for (i=0;i<5;i++) { | |
+ ind=brandom(0,NumDrug); | |
+ if (Play->Drugs[ind].Carried >= amount) { | |
+ return ind; | |
+ } | |
+ } | |
+ return -1; | |
+} | |
+ | |
+int GetNextDrugIndex(int OldIndex,Player *Play) { | |
+/* Returns an index into the "Drugs" array maintained by player "Play" */ | |
+/* of the next available drug after "OldIndex", following the current */ | |
+/* sort method (defined globally as "DrugSortMethod") */ | |
+ int i,MaxIndex; | |
+ MaxIndex=-1; | |
+ for (i=0;i<NumDrug;i++) { | |
+ if (Play->Drugs[i].Price!=0 && i!=OldIndex && i!=MaxIndex && | |
+ (MaxIndex==-1 || | |
+ (DrugSortMethod==DS_ATOZ && | |
+ strcasecmp(Drug[MaxIndex].Name,Drug[i].Name)>0) || | |
+ (DrugSortMethod==DS_ZTOA && | |
+ strcasecmp(Drug[MaxIndex].Name,Drug[i].Name)<0) || | |
+ (DrugSortMethod==DS_CHEAPFIRST && | |
+ Play->Drugs[MaxIndex].Price > Play->Drugs[i].Price) || | |
+ (DrugSortMethod==DS_CHEAPLAST && | |
+ Play->Drugs[MaxIndex].Price < Play->Drugs[i].Price)) && | |
+ (OldIndex==-1 || | |
+ (DrugSortMethod==DS_ATOZ && | |
+ strcasecmp(Drug[OldIndex].Name,Drug[i].Name)<=0) || | |
+ (DrugSortMethod==DS_ZTOA && | |
+ strcasecmp(Drug[OldIndex].Name,Drug[i].Name)>=0) || | |
+ (DrugSortMethod==DS_CHEAPFIRST && | |
+ Play->Drugs[OldIndex].Price <= Play->Drugs[i].Price) || | |
+ (DrugSortMethod==DS_CHEAPLAST && | |
+ Play->Drugs[OldIndex].Price >= Play->Drugs[i].Price))) { | |
+ MaxIndex=i; | |
+ } | |
+ } | |
+ return MaxIndex; | |
+} | |
+ | |
+void InitList(DopeList *List) { | |
+/* A DopeList is akin to a Vector class; it is a list of DopeEntry */ | |
+/* structures, which can be dynamically extended or compressed. This */ | |
+/* function initialises the newly-created list pointed to by "List" */ | |
+/* (A DopeEntry contains a Player pointer and a counter, and is used */ | |
+/* by the server to keep track of tipoffs and spies.) */ | |
+ List->Data=NULL; | |
+ List->Number=0; | |
+} | |
+ | |
+void ClearList(DopeList *List) { | |
+/* Clears the list pointed to by "List" */ | |
+ free(List->Data); | |
+ InitList(List); | |
+} | |
+ | |
+void AddListEntry(DopeList *List,DopeEntry *NewEntry) { | |
+/* Adds a new DopeEntry (pointed to by "NewEntry") to the list "List". */ | |
+/* A copy of NewEntry is placed into the list, so the original */ | |
+/* structure pointed to by NewEntry can be reused. */ | |
+ if (!NewEntry || !List) return; | |
+ List->Number++; | |
+ List->Data = (DopeEntry *)g_realloc(List->Data,List->Number* | |
+ sizeof(DopeEntry)); | |
+ g_memmove(&(List->Data[List->Number-1]),NewEntry,sizeof(DopeEntry)); | |
+} | |
+ | |
+void RemoveListEntry(DopeList *List,int Index) { | |
+/* Removes the DopeEntry at index "Index" from list "List" */ | |
+ if (!List || Index<0 || Index>=List->Number) return; | |
+ | |
+ g_memmove(&(List->Data[Index]),&(List->Data[Index+1]), | |
+ (List->Number-1-Index)*sizeof(DopeEntry)); | |
+ List->Number--; | |
+ List->Data = (DopeEntry *)g_realloc(List->Data,List->Number* | |
+ sizeof(DopeEntry)); | |
+ if (List->Number==0) List->Data=NULL; | |
+} | |
+ | |
+int GetListEntry(DopeList *List,Player *Play) { | |
+/* Returns the index of the DopeEntry matching "Play" in list "List" */ | |
+/* or -1 if this is not found. */ | |
+ int i; | |
+ for (i=List->Number-1;i>=0;i--) { | |
+ if (List->Data[i].Play==Play) return i; | |
+ } | |
+ return -1; | |
+} | |
+ | |
+void RemoveListPlayer(DopeList *List,Player *Play) { | |
+/* Removes (if it exists) the DopeEntry in list "List" matching "Play" */ | |
+ RemoveListEntry(List,GetListEntry(List,Play)); | |
+} | |
+ | |
+void RemoveAllEntries(DopeList *List,Player *Play) { | |
+/* Similar to RemoveListPlayer, except that if the list contains "Play" */ | |
+/* more than once, all the matching entries are removed, not just the first */ | |
+ int i=0; | |
+ while (1) { | |
+ i=GetListEntry(List,Play); | |
+ if (i==-1) break; | |
+ RemoveListEntry(List,i); | |
+ } | |
+} | |
+ | |
+void ResizeLocations(int NewNum) { | |
+ int i; | |
+ if (NewNum<NumLocation) for (i=NewNum;i<NumLocation;i++) { | |
+ g_free(Location[i].Name); | |
+ } | |
+ Location=g_realloc(Location,sizeof(struct LOCATION)*NewNum); | |
+ if (NewNum>NumLocation) { | |
+ memset(&Location[NumLocation],0, | |
+ (NewNum-NumLocation)*sizeof(struct LOCATION)); | |
+ for (i=NumLocation;i<NewNum;i++) { | |
+ Location[i].Name=g_strdup(""); | |
+ } | |
+ } | |
+ NumLocation=NewNum; | |
+} | |
+ | |
+void ResizeGuns(int NewNum) { | |
+ int i; | |
+ if (NewNum<NumGun) for (i=NewNum;i<NumGun;i++) { | |
+ g_free(Gun[i].Name); | |
+ } | |
+ Gun=g_realloc(Gun,sizeof(struct GUN)*NewNum); | |
+ if (NewNum>NumGun) { | |
+ memset(&Gun[NumGun],0,(NewNum-NumGun)*sizeof(struct GUN)); | |
+ for (i=NumGun;i<NewNum;i++) { | |
+ Gun[i].Name=g_strdup(""); | |
+ } | |
+ } | |
+ NumGun=NewNum; | |
+} | |
+ | |
+void ResizeDrugs(int NewNum) { | |
+ int i; | |
+ if (NewNum<NumDrug) for (i=NewNum;i<NumDrug;i++) { | |
+ g_free(Drug[i].Name); g_free(Drug[i].CheapStr); | |
+ } | |
+ Drug=g_realloc(Drug,sizeof(struct DRUG)*NewNum); | |
+ if (NewNum>NumDrug) { | |
+ memset(&Drug[NumDrug],0, | |
+ (NewNum-NumDrug)*sizeof(struct DRUG)); | |
+ for (i=NumDrug;i<NewNum;i++) { | |
+ Drug[i].Name=g_strdup(""); Drug[i].CheapStr=g_strdup(""); | |
+ } | |
+ } | |
+ NumDrug=NewNum; | |
+} | |
+ | |
+void ResizeSubway(int NewNum) { | |
+ int i; | |
+ if (NewNum<NumSubway) for (i=NewNum;i<NumSubway;i++) { | |
+ g_free(SubwaySaying[i]); | |
+ } | |
+ SubwaySaying=g_realloc(SubwaySaying,sizeof(char *)*NewNum); | |
+ if (NewNum>NumSubway) for (i=NumSubway;i<NewNum;i++) { | |
+ SubwaySaying[i]=g_strdup(""); | |
+ } | |
+ NumSubway=NewNum; | |
+} | |
+ | |
+void ResizePlaying(int NewNum) { | |
+ int i; | |
+ if (NewNum<NumPlaying) for (i=NewNum;i<NumPlaying;i++) { | |
+ g_free(Playing[i]); | |
+ } | |
+ Playing=g_realloc(Playing,sizeof(char *)*NewNum); | |
+ if (NewNum>NumPlaying) for (i=NumPlaying;i<NewNum;i++) { | |
+ Playing[i]=g_strdup(""); | |
+ } | |
+ NumPlaying=NewNum; | |
+} | |
+ | |
+void ResizeStoppedTo(int NewNum) { | |
+ int i; | |
+ if (NewNum<NumStoppedTo) for (i=NewNum;i<NumStoppedTo;i++) { | |
+ g_free(StoppedTo[i]); | |
+ } | |
+ StoppedTo=g_realloc(StoppedTo,sizeof(char *)*NewNum); | |
+ if (NewNum>NumStoppedTo) for (i=NumStoppedTo;i<NewNum;i++) { | |
+ StoppedTo[i]=g_strdup(""); | |
+ } | |
+ NumStoppedTo=NewNum; | |
+} | |
+ | |
+void AssignName(gchar **dest,gchar *src) { | |
+ g_free(*dest); | |
+ *dest=g_strdup(src); | |
+} | |
+ | |
+void CopyNames(struct NAMES *dest,struct NAMES *src) { | |
+ AssignName(&dest->Bitch,_(src->Bitch)); | |
+ AssignName(&dest->Bitches,_(src->Bitches)); | |
+ AssignName(&dest->Gun,_(src->Gun)); | |
+ AssignName(&dest->Guns,_(src->Guns)); | |
+ AssignName(&dest->Drug,_(src->Drug)); | |
+ AssignName(&dest->Drugs,_(src->Drugs)); | |
+ AssignName(&dest->Month,_(src->Month)); | |
+ AssignName(&dest->Year,_(src->Year)); | |
+ AssignName(&dest->Officer,_(src->Officer)); | |
+ AssignName(&dest->ReserveOfficer,_(src->ReserveOfficer)); | |
+ AssignName(&dest->LoanSharkName,_(src->LoanSharkName)); | |
+ AssignName(&dest->BankName,_(src->BankName)); | |
+ AssignName(&dest->GunShopName,_(src->GunShopName)); | |
+ AssignName(&dest->RoughPubName,_(src->RoughPubName)); | |
+} | |
+ | |
+void CopyMetaServer(struct METASERVER *dest,struct METASERVER *src) { | |
+ dest->Active=src->Active; | |
+ dest->HttpPort=src->HttpPort; | |
+ dest->UdpPort=src->UdpPort; | |
+ AssignName(&dest->Name,src->Name); | |
+ AssignName(&dest->Path,src->Path); | |
+ AssignName(&dest->LocalName,src->LocalName); | |
+ AssignName(&dest->Password,src->Password); | |
+ AssignName(&dest->Comment,src->Comment); | |
+} | |
+ | |
+void CopyLocation(struct LOCATION *dest,struct LOCATION *src) { | |
+ AssignName(&dest->Name,_(src->Name)); | |
+ dest->PolicePresence=src->PolicePresence; | |
+ dest->MinDrug=src->MinDrug; dest->MaxDrug=src->MaxDrug; | |
+} | |
+ | |
+void CopyGun(struct GUN *dest,struct GUN *src) { | |
+ AssignName(&dest->Name,_(src->Name)); | |
+ dest->Price=src->Price; | |
+ dest->Space=src->Space; | |
+ dest->Damage=src->Damage; | |
+} | |
+ | |
+void CopyDrug(struct DRUG *dest,struct DRUG *src) { | |
+ AssignName(&dest->Name,_(src->Name)); | |
+ dest->MinPrice=src->MinPrice; | |
+ dest->MaxPrice=src->MaxPrice; | |
+ dest->Cheap=src->Cheap; | |
+ dest->Expensive=src->Expensive; | |
+ AssignName(&dest->CheapStr,_(src->CheapStr)); | |
+} | |
+ | |
+void CopyDrugs(struct DRUGS *dest,struct DRUGS *src) { | |
+ AssignName(&dest->ExpensiveStr1,_(src->ExpensiveStr1)); | |
+ AssignName(&dest->ExpensiveStr2,_(src->ExpensiveStr2)); | |
+ dest->CheapDivide=src->CheapDivide; | |
+ dest->ExpensiveMultiply=src->ExpensiveMultiply; | |
+} | |
+ | |
+void ReadConfigFile(char *FileName) { | |
+ FILE *fp; | |
+ GScanner *scanner; | |
+ fp=fopen(FileName,"r"); | |
+ if (fp) { | |
+ scanner=g_scanner_new(&ScannerConfig); | |
+ scanner->input_name=FileName; | |
+ g_scanner_input_file(scanner,fileno(fp)); | |
+ while (!g_scanner_eof(scanner)) if (!ParseNextConfig(scanner)) { | |
+ g_scanner_error(scanner, | |
+ _("Unable to process configuration file line")); | |
+ } | |
+ g_scanner_destroy(scanner); | |
+ fclose(fp); | |
+ } | |
+} | |
+ | |
+gboolean ParseNextConfig(GScanner *scanner) { | |
+ GTokenType token; | |
+ gchar *ID1,*ID2; | |
+ gulong index=0; | |
+ int GlobalIndex; | |
+ gboolean IndexGiven=FALSE; | |
+ | |
+ ID1=ID2=NULL; | |
+ token=g_scanner_get_next_token(scanner); | |
+ if (token==G_TOKEN_EOF) return TRUE; | |
+ if (token!=G_TOKEN_IDENTIFIER) { | |
+ g_scanner_unexp_token(scanner,G_TOKEN_IDENTIFIER,NULL,NULL, | |
+ NULL,NULL,FALSE); | |
+ return FALSE; | |
+ } | |
+ ID1=g_strdup(scanner->value.v_identifier); | |
+ token=g_scanner_get_next_token(scanner); | |
+ if (token==G_TOKEN_LEFT_BRACE) { | |
+ token=g_scanner_get_next_token(scanner); | |
+ if (token!=G_TOKEN_INT) { | |
+ g_scanner_unexp_token(scanner,G_TOKEN_INT,NULL,NULL, | |
+ NULL,NULL,FALSE); | |
+ return FALSE; | |
+ } | |
+ index=scanner->value.v_int; | |
+ IndexGiven=TRUE; | |
+ token=g_scanner_get_next_token(scanner); | |
+ if (token!=G_TOKEN_RIGHT_BRACE) { | |
+ g_scanner_unexp_token(scanner,G_TOKEN_RIGHT_BRACE,NULL,NULL, | |
+ NULL,NULL,FALSE); | |
+ return FALSE; | |
+ } | |
+ token=g_scanner_get_next_token(scanner); | |
+ if (token=='.') { | |
+ token=g_scanner_get_next_token(scanner); | |
+ if (token!=G_TOKEN_IDENTIFIER) { | |
+ g_scanner_unexp_token(scanner,G_TOKEN_IDENTIFIER,NULL,NULL, | |
+ NULL,NULL,FALSE); | |
+ return FALSE; | |
+ } | |
+ ID2=g_strdup(scanner->value.v_identifier); | |
+ token=g_scanner_get_next_token(scanner); | |
+ } | |
+ } | |
+ GlobalIndex=GetGlobalIndex(ID1,ID2); | |
+ g_free(ID1); g_free(ID2); | |
+ if (GlobalIndex==-1) return FALSE; | |
+ if (token==G_TOKEN_EOF) { | |
+ PrintConfigValue(GlobalIndex,index,IndexGiven,scanner); | |
+ return TRUE; | |
+ } else if (token==G_TOKEN_EQUAL_SIGN) { | |
+ token=g_scanner_get_next_token(scanner); | |
+ if (CountPlayers(FirstServer)>0) { | |
+ g_warning( | |
+_("Configuration can only be changed interactively when no\n" | |
+"players are logged on. Wait for all players to log off, or remove\n" | |
+"them with the push or kill commands, and try again.")); | |
+ } else { | |
+ SetConfigValue(GlobalIndex,index,IndexGiven,scanner); | |
+ } | |
+ return TRUE; | |
+ } else { | |
+ return FALSE; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+int GetGlobalIndex(gchar *ID1,gchar *ID2) { | |
+ int i; | |
+ if (!ID1) return -1; | |
+ for (i=0;i<NUMGLOB;i++) { | |
+ if (strcasecmp(ID1,Globals[i].Name)==0 && !Globals[i].NameStruct[0]) { | |
+/* Just a bog-standard ID1=value */ | |
+ return i; | |
+ } | |
+ if (strcasecmp(ID1,Globals[i].NameStruct)==0 && ID2 && | |
+ strcasecmp(ID2,Globals[i].Name)==0 && | |
+ Globals[i].StructStaticPt && Globals[i].StructListPt) { | |
+/* ID1[index].ID2=value */ | |
+ return i; | |
+ } | |
+ } | |
+ return -1; | |
+} | |
+ | |
+void *GetGlobalPointer(int GlobalIndex,int StructIndex) { | |
+ void *ValPt=NULL; | |
+ | |
+ if (Globals[GlobalIndex].IntVal) { | |
+ ValPt=(void *)Globals[GlobalIndex].IntVal; | |
+ } else if (Globals[GlobalIndex].PriceVal) { | |
+ ValPt=(void *)Globals[GlobalIndex].PriceVal; | |
+ } else if (Globals[GlobalIndex].StringVal) { | |
+ ValPt=(void *)Globals[GlobalIndex].StringVal; | |
+ } | |
+ if (!ValPt) return NULL; | |
+ | |
+ if (Globals[GlobalIndex].StructStaticPt && | |
+ Globals[GlobalIndex].StructListPt) { | |
+ return ValPt-Globals[GlobalIndex].StructStaticPt + | |
+ *(Globals[GlobalIndex].StructListPt) + | |
+ (StructIndex-1)*Globals[GlobalIndex].LenStruct; | |
+ } else { | |
+ return ValPt; | |
+ } | |
+} | |
+ | |
+gboolean CheckMaxIndex(GScanner *scanner,int GlobalIndex,int StructIndex, | |
+ gboolean IndexGiven) { | |
+ if (!Globals[GlobalIndex].MaxIndex || | |
+ (Globals[GlobalIndex].StringList && !IndexGiven) || | |
+ (IndexGiven && StructIndex>=1 && | |
+ StructIndex <= *(Globals[GlobalIndex].MaxIndex))) { | |
+ return TRUE; | |
+ } | |
+ g_scanner_error(scanner,_("Index into %s array should be between 1 and %d"), | |
+ (Globals[GlobalIndex].NameStruct && | |
+ Globals[GlobalIndex].NameStruct[0]) ? | |
+ Globals[GlobalIndex].NameStruct : | |
+ Globals[GlobalIndex].Name, | |
+ *(Globals[GlobalIndex].MaxIndex)); | |
+ return FALSE; | |
+} | |
+ | |
+void PrintConfigValue(int GlobalIndex,int StructIndex,gboolean IndexGiven, | |
+ GScanner *scanner) { | |
+ gchar *prstr,*GlobalName; | |
+ int i; | |
+ if (!CheckMaxIndex(scanner,GlobalIndex,StructIndex,IndexGiven)) return; | |
+ if (Globals[GlobalIndex].NameStruct[0]) { | |
+ GlobalName=g_strdup_printf("%s[%d].%s",Globals[GlobalIndex].NameStruct, | |
+ StructIndex,Globals[GlobalIndex].Name); | |
+ } else GlobalName=Globals[GlobalIndex].Name; | |
+ if (Globals[GlobalIndex].IntVal) { | |
+ g_print(_("%s is %d\n"),GlobalName, | |
+ *((int *)GetGlobalPointer(GlobalIndex,StructIndex))); | |
+ } else if (Globals[GlobalIndex].PriceVal) { | |
+ prstr=FormatPrice(*((price_t *)GetGlobalPointer(GlobalIndex, | |
+ StructIndex))); | |
+ g_print(_("%s is %s\n"),GlobalName,prstr); | |
+ g_free(prstr); | |
+ } else if (Globals[GlobalIndex].StringVal) { | |
+ g_print(_("%s is \"%s\"\n"),GlobalName, | |
+ *((gchar **)GetGlobalPointer(GlobalIndex,StructIndex))); | |
+ } else if (Globals[GlobalIndex].StringList) { | |
+ if (IndexGiven) { | |
+ g_print(_("%s[%d] is %s\n"),GlobalName,StructIndex, | |
+ (*(Globals[GlobalIndex].StringList))[StructIndex-1]); | |
+ } else { | |
+ g_print(_("%s is { "),GlobalName); | |
+ if (Globals[GlobalIndex].MaxIndex) { | |
+ for (i=0;i<*(Globals[GlobalIndex].MaxIndex);i++) { | |
+ if (i>0) g_print(", "); | |
+ g_print("\"%s\"",(*(Globals[GlobalIndex].StringList))[i]); | |
+ } | |
+ } | |
+ g_print(" }\n"); | |
+ } | |
+ } | |
+ if (Globals[GlobalIndex].NameStruct[0]) g_free(GlobalName); | |
+} | |
+ | |
+void SetConfigValue(int GlobalIndex,int StructIndex,gboolean IndexGiven, | |
+ GScanner *scanner) { | |
+ gchar *GlobalName,*tmpstr; | |
+ GTokenType token; | |
+ int IntVal,NewNum; | |
+ Player *tmp; | |
+ GSList *list,*StartList; | |
+ token=scanner->token; | |
+ if (!CheckMaxIndex(scanner,GlobalIndex,StructIndex,IndexGiven)) return; | |
+ if (Globals[GlobalIndex].NameStruct[0]) { | |
+ GlobalName=g_strdup_printf("%s[%d].%s",Globals[GlobalIndex].NameStruct, | |
+ StructIndex,Globals[GlobalIndex].Name); | |
+ } else GlobalName=Globals[GlobalIndex].Name; | |
+ if (Globals[GlobalIndex].IntVal) { | |
+ if (token==G_TOKEN_INT) { | |
+ IntVal=(int)scanner->value.v_int; | |
+ if (Globals[GlobalIndex].ResizeFunc) { | |
+ (*(Globals[GlobalIndex].ResizeFunc))(IntVal); | |
+ g_print(_("Resized structure list to %d elements\n"),IntVal); | |
+ for (list=FirstClient;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ UpdatePlayer(tmp); | |
+ } | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ UpdatePlayer(tmp); | |
+ } | |
+ } | |
+ *((int *)GetGlobalPointer(GlobalIndex,StructIndex))=IntVal; | |
+ } else { | |
+ g_scanner_unexp_token(scanner,G_TOKEN_INT,NULL,NULL, | |
+ NULL,NULL,FALSE); return; | |
+ } | |
+ } else if (Globals[GlobalIndex].PriceVal) { | |
+ if (token==G_TOKEN_INT) { | |
+ *((price_t *)GetGlobalPointer(GlobalIndex,StructIndex))= | |
+ (price_t)scanner->value.v_int; | |
+ } else { | |
+ g_scanner_unexp_token(scanner,G_TOKEN_INT,NULL,NULL, | |
+ NULL,NULL,FALSE); return; | |
+ } | |
+ } else if (Globals[GlobalIndex].StringVal) { | |
+ if (token==G_TOKEN_STRING) { | |
+ AssignName((gchar **)GetGlobalPointer(GlobalIndex,StructIndex), | |
+ scanner->value.v_string); | |
+ } else { | |
+ g_scanner_unexp_token(scanner,G_TOKEN_STRING,NULL,NULL, | |
+ NULL,NULL,FALSE); return; | |
+ } | |
+ } else if (Globals[GlobalIndex].StringList) { | |
+ if (IndexGiven) { | |
+ if (token==G_TOKEN_STRING) { | |
+ AssignName(&(*(Globals[GlobalIndex].StringList))[StructIndex-1], | |
+ scanner->value.v_string); | |
+ } else { | |
+ g_scanner_unexp_token(scanner,G_TOKEN_STRING,NULL,NULL, | |
+ NULL,NULL,FALSE); return; | |
+ } | |
+ } else { | |
+ StartList=NULL; | |
+ if (token!=G_TOKEN_LEFT_CURLY) { | |
+ g_scanner_unexp_token(scanner,G_TOKEN_LEFT_CURLY,NULL,NULL, | |
+ NULL,NULL,FALSE); return; | |
+ } | |
+ NewNum=0; | |
+ while(1) { | |
+ token=g_scanner_get_next_token(scanner); | |
+ tmpstr=NULL; | |
+ if (token==G_TOKEN_STRING) { | |
+ tmpstr=g_strdup(scanner->value.v_string); | |
+ } else if (token==G_TOKEN_RIGHT_CURLY) { | |
+ break; | |
+ } else if (token==G_TOKEN_COMMA) { | |
+ } else { | |
+ g_scanner_unexp_token(scanner,G_TOKEN_STRING,NULL,NULL, | |
+ NULL,NULL,FALSE); return; | |
+ } | |
+ if (tmpstr) { | |
+ NewNum++; StartList=g_slist_append(StartList,tmpstr); | |
+ } | |
+ } | |
+ (*Globals[GlobalIndex].ResizeFunc)(NewNum); | |
+ NewNum=0; | |
+ for (list=StartList;list;NewNum++,list=g_slist_next(list)) { | |
+ AssignName(&(*(Globals[GlobalIndex].StringList))[NewNum], | |
+ (char *)list->data); | |
+ g_free(list->data); | |
+ } | |
+ g_slist_free(StartList); | |
+ } | |
+ } | |
+ if (Globals[GlobalIndex].NameStruct[0]) g_free(GlobalName); | |
+} | |
+ | |
+void SetupParameters() { | |
+/* Sets up data - such as the location of the high score file - to */ | |
+/* hard-coded internal values, and then processes the global and */ | |
+/* user-specific configuration files */ | |
+ char *ConfigFile,*pt; | |
+ int i; | |
+ | |
+/* Initialise variables */ | |
+ srand(time(NULL)); | |
+ PidFile=NULL; | |
+ Location=NULL; | |
+ Gun=NULL; | |
+ Drug=NULL; | |
+ SubwaySaying=Playing=StoppedTo=NULL; | |
+ NumLocation=NumGun=NumDrug=0; | |
+ FirstClient=FirstServer=NULL; | |
+ Noone.Name=g_strdup("Noone"); | |
+ WantColour=WantNetwork=1; | |
+ WantHelp=WantVersion=WantAntique=0; | |
+ WantedClient=CLIENT_AUTO; | |
+ Server=AIPlayer=Client=Network=FALSE; | |
+ | |
+/* Set hard-coded default values */ | |
+ g_free(HiScoreFile); g_free(ServerName); g_free(Pager); | |
+ HiScoreFile=g_strdup_printf("%s/dopewars.sco",DATADIR); | |
+ ServerName=g_strdup("localhost"); | |
+ Pager=g_strdup("more"); | |
+ | |
+ CopyNames(&Names,&DefaultNames); | |
+ CopyMetaServer(&MetaServer,&DefaultMetaServer); | |
+ CopyDrugs(&Drugs,&DefaultDrugs); | |
+ | |
+ ResizeLocations(NUMLOCATION); | |
+ for (i=0;i<NumLocation;i++) CopyLocation(&Location[i],&DefaultLocation[i]); | |
+ ResizeGuns(NUMGUN); | |
+ for (i=0;i<NumGun;i++) CopyGun(&Gun[i],&DefaultGun[i]); | |
+ ResizeDrugs(NUMDRUG); | |
+ for (i=0;i<NumDrug;i++) CopyDrug(&Drug[i],&DefaultDrug[i]); | |
+ ResizeSubway(NUMSUBWAY); | |
+ for (i=0;i<NumSubway;i++) { | |
+ AssignName(&SubwaySaying[i],_(DefaultSubwaySaying[i])); | |
+ } | |
+ ResizePlaying(NUMPLAYING); | |
+ for (i=0;i<NumPlaying;i++) { | |
+ AssignName(&Playing[i],_(DefaultPlaying[i])); | |
+ } | |
+ ResizeStoppedTo(NUMSTOPPEDTO); | |
+ for (i=0;i<NumStoppedTo;i++) { | |
+ AssignName(&StoppedTo[i],_(DefaultStoppedTo[i])); | |
+ } | |
+ | |
+/* Now read in the global configuration file */ | |
+ ReadConfigFile("/etc/dopewars"); | |
+ | |
+/* Finally, try to read in the .dopewars file in the user's home directory */ | |
+ pt=getenv("HOME"); | |
+ if (!pt) return; | |
+ ConfigFile=g_strdup_printf("%s/.dopewars",pt); | |
+ ReadConfigFile(ConfigFile); | |
+ g_free(ConfigFile); | |
+} | |
+ | |
+void HandleHelpTexts() { | |
+ g_print("dopewars version %s\n",VERSION); | |
+ if (!WantHelp) return; | |
+ | |
+ g_print( | |
+_("Usage: dopewars [OPTION]...\n\ | |
+Drug dealing game based on \"Drug Wars\" by John E. Dell\n\ | |
+ -b \"black and white\" - i.e. do not use pretty colours\n\ | |
+ (by default colours are used where the terminal supports them)\n\ | |
+ -n be boring and don't connect to any available dopewars servers\n\ | |
+ (i.e. single player mode)\n\ | |
+ -a \"antique\" dopewars - keep as closely to the original version as\n\ | |
+ possible (this also disables any networking)\n\ | |
+ -f file specify a file to use as the high score table\n\ | |
+ (by default %s/dopewars.sco is used)\n\ | |
+ -o addr specify a hostname where the server for multiplayer dopewars\n\ | |
+ can be found (in human-readable - e.g. nowhere.com - format)\n\ | |
+ -s run in server mode (note: for a \"non-interactive\" server, simply\… | |
+ run as dopewars -s < /dev/null >> logfile & )\n\ | |
+ -S run a \"private\" server (i.e. do not notify the metaserver)\n\ | |
+ -p specify the network port to use (default: 7902)\n\ | |
+ -g file specify the pathname of a dopewars configuration file. This file\n\ | |
+ is read immediately when the -g option is encountered\n\ | |
+ -r file maintain pid file \"file\" while running the server\n\ | |
+ -c create and run a computer player\n\ | |
+ -w force the use of a graphical (windowed) client (GTK+ or Win32)\n\ | |
+ -t force the use of a text-mode client (curses)\n\ | |
+ (by default, a windowed client is used when possible)\n\ | |
+ -h display this help information\n\ | |
+ -v output version information and exit\n\n\ | |
+dopewars is Copyright (C) Ben Webb 1998-2000, and released under the GNU GPL\n\ | |
+Report bugs to the author at [email protected]\n"),DATADIR); | |
+} | |
+ | |
+void HandleCmdLine(int argc,char *argv[]) { | |
+ int c; | |
+ while (1) { | |
+ c=getopt(argc,argv,"anbchvf:o:sSp:g:r:wt"); | |
+ if (c==EOF) break; | |
+ switch(c) { | |
+ case 'n': WantNetwork=0; break; | |
+ case 'b': WantColour=0; break; | |
+ case 'c': AIPlayer=1; break; | |
+ case 'a': WantAntique=1; WantNetwork=0; break; | |
+ case 'v': WantVersion=1; break; | |
+ case 'h': | |
+ case '?': WantHelp=1; break; | |
+ case 'f': AssignName(&HiScoreFile,optarg); break; | |
+ case 'o': AssignName(&ServerName,optarg); break; | |
+ case 's': Server=TRUE; NotifyMetaServer=TRUE; break; | |
+ case 'S': Server=TRUE; NotifyMetaServer=FALSE; break; | |
+ case 'p': Port=atoi(optarg); break; | |
+ case 'g': ReadConfigFile(optarg); break; | |
+ case 'r': AssignName(&PidFile,optarg); break; | |
+ case 'w': WantedClient=CLIENT_WINDOW; break; | |
+ case 't': WantedClient=CLIENT_CURSES; break; | |
+ } | |
+ } | |
+} | |
+ | |
+#ifdef CYGWIN | |
+ | |
+int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, | |
+ LPSTR lpszCmdParam,int nCmdShow) { | |
+ return Win32Loop(hInstance,hPrevInstance,lpszCmdParam,nCmdShow); | |
+} | |
+ | |
+#else /* !CYGWIN */ | |
+ | |
+int main(int argc,char *argv[]) { | |
+#ifdef ENABLE_NLS | |
+ setlocale(LC_ALL,""); | |
+ bindtextdomain(PACKAGE,LOCALEDIR); | |
+ textdomain(PACKAGE); | |
+#endif | |
+ SetupParameters(); | |
+ HandleCmdLine(argc,argv); | |
+ if (WantVersion || WantHelp) { | |
+ HandleHelpTexts(); | |
+ } else { | |
+ StartNetworking(); | |
+ if (Server) { | |
+ ServerLoop(); | |
+ } else switch(WantedClient) { | |
+ case CLIENT_AUTO: | |
+ if (!GtkLoop(&argc,&argv,TRUE)) CursesLoop(); | |
+ break; | |
+ case CLIENT_WINDOW: | |
+ GtkLoop(&argc,&argv,FALSE); break; | |
+ case CLIENT_CURSES: | |
+ CursesLoop(); break; | |
+ } | |
+ StopNetworking(); | |
+ } | |
+ g_free(PidFile); | |
+ return 0; | |
+} | |
+ | |
+#endif /* CYGWIN */ | |
diff --git a/src/dopewars.h b/src/dopewars.h | |
t@@ -0,0 +1,388 @@ | |
+/* dopewars.h Common structures and stuff for Dopewars */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+ | |
+#ifndef __DOPEWARS_H__ | |
+#define __DOPEWARS_H__ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#include <stdio.h> | |
+ | |
+/* Be careful not to include both sys/time.h and time.h on those systems */ | |
+/* which don't like it */ | |
+#if TIME_WITH_SYS_TIME | |
+#include <sys/time.h> | |
+#include <time.h> | |
+#else | |
+#if HAVE_SYS_TIME_H | |
+#include <sys/time.h> | |
+#else | |
+#include <time.h> | |
+#endif | |
+#endif | |
+ | |
+#include <glib.h> | |
+#include "dopeos.h" | |
+ | |
+/* Internationalization stuff */ | |
+ | |
+#ifdef ENABLE_NLS | |
+#include <locale.h> | |
+#include <libintl.h> | |
+#define _(String) gettext (String) | |
+#ifdef gettext_noop | |
+#define N_(String) gettext_noop (String) | |
+#else | |
+#define N_(String) (String) | |
+#endif | |
+#else | |
+#define gettext(String) (String) | |
+#define dgettext(Domain,Message) (Message) | |
+#define dcgettext(Domain,Message,Type) (Message) | |
+#define _(String) (String) | |
+#define N_(String) (String) | |
+#endif | |
+ | |
+/* Make price_t be a long long if the type is supported by the compiler */ | |
+#if SIZEOF_LONG_LONG == 0 | |
+typedef long price_t; | |
+#else | |
+typedef long long price_t; | |
+#endif | |
+ | |
+#define NMLEN 20 | |
+ | |
+struct COPS { | |
+ int EscapeProb,DeputyEscape,HitProb,DeputyHit,Damage, | |
+ Toughness,DropProb; | |
+}; | |
+ | |
+struct NAMES { | |
+ gchar *Bitch,*Bitches,*Gun,*Guns,*Drug,*Drugs,*Month,*Year, | |
+ *Officer,*ReserveOfficer,*LoanSharkName,*BankName, | |
+ *GunShopName,*RoughPubName; | |
+}; | |
+ | |
+struct METASERVER { | |
+ int Active; | |
+ int HttpPort,UdpPort; | |
+ gchar *Name,*Path,*LocalName,*Password,*Comment; | |
+}; | |
+ | |
+struct PRICES { | |
+ price_t Spy,Tipoff; | |
+}; | |
+ | |
+struct BITCH { | |
+ price_t MinPrice,MaxPrice; | |
+}; | |
+ | |
+#define CLIENT_AUTO 0 | |
+#define CLIENT_WINDOW 1 | |
+#define CLIENT_CURSES 2 | |
+ | |
+extern int ClientSock,ListenSock; | |
+extern char Network,Client,Server,NotifyMetaServer,AIPlayer; | |
+extern int Port,Sanitized; | |
+extern int NumLocation,NumGun,NumDrug,NumSubway,NumPlaying,NumStoppedTo; | |
+extern gchar *HiScoreFile,*ServerName,*Pager; | |
+extern char WantHelp,WantVersion,WantAntique,WantColour,WantNetwork; | |
+extern char WantedClient; | |
+extern int LoanSharkLoc,BankLoc,GunShopLoc,RoughPubLoc; | |
+extern int DrugSortMethod,FightTimeout,IdleTimeout,ConnectTimeout; | |
+extern int MaxClients,AITurnPause; | |
+extern struct PRICES Prices; | |
+extern struct BITCH Bitch; | |
+extern price_t StartCash,StartDebt; | |
+extern struct COPS Cops; | |
+extern struct NAMES Names; | |
+extern struct METASERVER MetaServer; | |
+extern int NumTurns; | |
+ | |
+#define DM_NONE 0 | |
+#define DM_STREET 1 | |
+#define DM_FIGHT 2 | |
+#define DM_DEAL 3 | |
+ | |
+#define DS_ATOZ 1 | |
+#define DS_ZTOA 2 | |
+#define DS_CHEAPFIRST 3 | |
+#define DS_CHEAPLAST 4 | |
+#define DS_MAX 5 | |
+ | |
+#define NAMELEN 37 | |
+#define BUFLEN 600 | |
+#define NUMSUBWAY 31 | |
+#define NUMHISCORE 18 | |
+#define NUMSTOPPEDTO 5 | |
+#define NUMPLAYING 18 | |
+#define NUMDISCOVER 3 | |
+ | |
+#define NUMDRUG 12 | |
+#define NUMGUN 4 | |
+#define NUMLOCATION 8 | |
+ | |
+#define ESCAPE 0 | |
+#define DEFECT 1 | |
+#define SHOT 2 | |
+ | |
+#define MINTRENCHPRICE 200 | |
+#define MAXTRENCHPRICE 300 | |
+ | |
+#define ACID 0 | |
+#define COCAINE 1 | |
+#define HASHISH 2 | |
+#define HEROIN 3 | |
+#define LUDES 4 | |
+#define MDA 5 | |
+#define OPIUM 6 | |
+#define PCP 7 | |
+#define PEYOTE 8 | |
+#define SHROOMS 9 | |
+#define SPEED 10 | |
+#define WEED 11 | |
+ | |
+#define DEFLOANSHARK 1 | |
+#define DEFBANK 1 | |
+#define DEFGUNSHOP 2 | |
+#define DEFROUGHPUB 2 | |
+ | |
+#define METAVERSION 2 | |
+ | |
+#define FIRSTTURN 1 | |
+#define DEADHARDASS 2 | |
+#define TIPPEDOFF 4 | |
+#define SPIEDON 8 | |
+#define SPYINGON 16 | |
+#define FIGHTING 32 | |
+#define CANSHOOT 64 | |
+#define TRADING 128 | |
+ | |
+#define LISTONLY 0 | |
+#define PAGETO 1 | |
+#define SELECTTIP 2 | |
+#define SELECTSPY 3 | |
+ | |
+#define F_STAND 0 | |
+#define F_FIGHT 1 | |
+#define F_RUN 2 | |
+ | |
+#define E_NONE 0 | |
+#define E_SUBWAY 1 | |
+#define E_OFFOBJECT 2 | |
+#define E_WEED 3 | |
+#define E_SAYING 4 | |
+#define E_LOANSHARK 5 | |
+#define E_BANK 6 | |
+#define E_GUNSHOP 7 | |
+#define E_ROUGHPUB 8 | |
+#define E_HIREBITCH 9 | |
+#define E_ARRIVE 10 | |
+#define E_MAX 11 | |
+ | |
+#define E_FINISH 100 | |
+ | |
+#define E_OUTOFSYNC 120 | |
+#define E_ATTACK 121 | |
+#define E_WAITATTACK 122 | |
+#define E_FREEFORALL 123 | |
+#define E_DEFEND 124 | |
+#define E_COPS 125 | |
+#define E_DOCTOR 126 | |
+#define E_MAXOOS 127 | |
+ | |
+struct GUN { | |
+ gchar *Name; | |
+ price_t Price; | |
+ int Space; | |
+ int Damage; | |
+}; | |
+extern struct GUN DefaultGun[NUMGUN],*Gun; | |
+ | |
+struct HISCORE { | |
+ gchar *Time; | |
+ price_t Money; | |
+ char Dead; | |
+ gchar *Name; | |
+}; | |
+ | |
+struct LOCATION { | |
+ gchar *Name; | |
+ int PolicePresence; | |
+ int MinDrug,MaxDrug; | |
+}; | |
+extern struct LOCATION DefaultLocation[NUMLOCATION],*Location; | |
+ | |
+struct DRUG { | |
+ gchar *Name; | |
+ price_t MinPrice,MaxPrice; | |
+ int Cheap,Expensive; | |
+ gchar *CheapStr; | |
+}; | |
+extern struct DRUG DefaultDrug[NUMDRUG],*Drug; | |
+ | |
+struct DRUGS { | |
+ gchar *ExpensiveStr1,*ExpensiveStr2; | |
+ int CheapDivide,ExpensiveMultiply; | |
+}; | |
+extern struct DRUGS Drugs; | |
+ | |
+struct INVENTORY { | |
+ price_t Price; | |
+ int Carried; | |
+}; | |
+typedef struct INVENTORY Inventory; | |
+ | |
+struct PLAYER_T; | |
+typedef struct PLAYER_T Player; | |
+ | |
+struct TDopeEntry { | |
+ Player *Play; | |
+ int Turns; | |
+}; | |
+typedef struct TDopeEntry DopeEntry; | |
+ | |
+struct TDopeList { | |
+ DopeEntry *Data; | |
+ int Number; | |
+}; | |
+typedef struct TDopeList DopeList; | |
+ | |
+typedef struct tagConnBuf { | |
+ gchar *Data; /* bytes waiting to be read/written */ | |
+ int Length; /* allocated length of the "Data" buffer */ | |
+ int DataPresent; /* number of bytes currently in "Data" */ | |
+} ConnBuf; | |
+ | |
+struct PLAYER_T { | |
+ int Turn; | |
+ price_t Cash,Debt,Bank; | |
+ int Health; | |
+ int CoatSize; | |
+ char IsAt; | |
+ char Flags; | |
+ gchar *Name; | |
+ Inventory *Guns,*Drugs,Bitches; | |
+ int fd; | |
+ int EventNum,ResyncNum; | |
+ int Cops; | |
+ time_t FightTimeout,IdleTimeout,ConnectTimeout; | |
+ price_t DocPrice; | |
+ DopeList SpyList,TipList; | |
+ Player *OnBehalfOf,*Attacked; | |
+ ConnBuf ReadBuf,WriteBuf; | |
+}; | |
+ | |
+#define CM_SERVER 0 | |
+#define CM_PROMPT 1 | |
+#define CM_META 2 | |
+#define CM_SINGLE 3 | |
+typedef struct tag_serverdata { | |
+ char *Name; | |
+ int Port; | |
+ int MaxPlayers,CurPlayers; | |
+ char *Comment,*Version,*Update,*UpSince; | |
+} ServerData; | |
+ | |
+#define NUMGLOB 79 | |
+struct GLOBALS { | |
+ int *IntVal; | |
+ price_t *PriceVal; | |
+ gchar **StringVal; | |
+ gchar ***StringList; | |
+ char *Name,*Help; | |
+ | |
+ void **StructListPt,*StructStaticPt; | |
+ int LenStruct; | |
+ char *NameStruct; | |
+ int *MaxIndex; | |
+ void (*ResizeFunc)(int NewNum); | |
+}; | |
+ | |
+extern struct GLOBALS Globals[NUMGLOB]; | |
+extern Player Noone; | |
+extern char *Discover[NUMDISCOVER]; | |
+extern char **Playing; | |
+extern char **SubwaySaying; | |
+extern char **StoppedTo; | |
+extern GSList *ServerList; | |
+extern GScannerConfig ScannerConfig; | |
+ | |
+GSList *RemovePlayer(Player *Play,GSList *First); | |
+Player *GetPlayerByName(gchar *Name,GSList *First); | |
+int CountPlayers(GSList *First); | |
+GSList *AddPlayer(int fd,Player *NewPlayer,GSList *First); | |
+void UpdatePlayer(Player *Play); | |
+void CopyPlayer(Player *Dest,Player *Src); | |
+void ClearInventory(Inventory *Guns,Inventory *Drugs); | |
+int IsCarryingRandom(Player *Play,int amount); | |
+void ChangeSpaceForInventory(Inventory *Guns,Inventory *Drugs, | |
+ Player *Play); | |
+void InitList(DopeList *List); | |
+void AddListEntry(DopeList *List,DopeEntry *NewEntry); | |
+void RemoveListEntry(DopeList *List,int Entry); | |
+int GetListEntry(DopeList *List,Player *Play); | |
+void RemoveListPlayer(DopeList *List,Player *Play); | |
+void RemoveAllEntries(DopeList *List,Player *Play); | |
+void ClearList(DopeList *List); | |
+int TotalGunsCarried(Player *Play); | |
+int read_string(FILE *fp,char **buf); | |
+int brandom(int bot,int top); | |
+void AddInventory(Inventory *Cumul,Inventory *Add,int Length); | |
+void TruncateInventoryFor(Inventory *Guns,Inventory *Drugs, | |
+ Player *Play); | |
+void PrintInventory(Inventory *Guns,Inventory *Drugs); | |
+price_t strtoprice(char *buf); | |
+gchar *pricetostr(price_t price); | |
+gchar *FormatPrice(price_t price); | |
+char IsInventoryClear(Inventory *Guns,Inventory *Drugs); | |
+void ResizeLocations(int NewNum); | |
+void ResizeGuns(int NewNum); | |
+void ResizeDrugs(int NewNum); | |
+void ResizeSubway(int NewNum); | |
+void ResizePlaying(int NewNum); | |
+void ResizeStoppedTo(int NewNum); | |
+void AssignName(gchar **dest,gchar *src); | |
+void CopyNames(struct NAMES *dest,struct NAMES *src); | |
+void CopyMetaServer(struct METASERVER *dest,struct METASERVER *src); | |
+void CopyLocation(struct LOCATION *dest,struct LOCATION *src); | |
+void CopyGun(struct GUN *dest,struct GUN *src); | |
+void CopyDrug(struct DRUG *dest,struct DRUG *src); | |
+void CopyDrugs(struct DRUGS *dest,struct DRUGS *src); | |
+int GetNextDrugIndex(int OldIndex,Player *Play); | |
+gchar *InitialCaps(gchar *string); | |
+char StartsWithVowel(char *string); | |
+char *GetPlayerName(Player *Play); | |
+void SetPlayerName(Player *Play,char *Name); | |
+void HandleCmdLine(int argc,char *argv[]); | |
+void SetupParameters(); | |
+void HandleHelpTexts(); | |
+void ReadConfigFile(char *FileName); | |
+gboolean ParseNextConfig(GScanner *scanner); | |
+int GetGlobalIndex(gchar *ID1,gchar *ID2); | |
+void *GetGlobalPointer(int GlobalIndex,int StructIndex); | |
+void PrintConfigValue(int GlobalIndex,int StructIndex,gboolean IndexGiven, | |
+ GScanner *scanner); | |
+void SetConfigValue(int GlobalIndex,int StructIndex,gboolean IndexGiven, | |
+ GScanner *scanner); | |
+#endif | |
diff --git a/src/dopewars.rc b/src/dopewars.rc | |
t@@ -0,0 +1,237 @@ | |
+#include "dopeid.h" | |
+MainDialog DIALOG 28, 17, 227, 184 STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | … | |
+BEGIN | |
+ CONTROL "Stats", 101, "button", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 5… | |
+ CONTROL "", 102, "EDIT", ES_LEFT | ES_AUTOVSCROLL | ES_READONLY | WS_C… | |
+ CONTROL "", 103, "LISTBOX", LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BO… | |
+ CONTROL "", 104, "LISTBOX", LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BO… | |
+ PUSHBUTTON "&Buy ->", 105, 98, 118, 30, 14, WS_CHILD | WS_VISIBLE | WS… | |
+ PUSHBUTTON "<- &Sell", 106, 98, 134, 30, 14, WS_CHILD | WS_VISIBLE | W… | |
+ PUSHBUTTON "&Drop <-", 107, 98, 151, 30, 14, WS_CHILD | WS_VISIBLE | W… | |
+ PUSHBUTTON "&Jet!", 108, 98, 168, 30, 14, WS_CHILD | WS_VISIBLE | WS_T… | |
+ LTEXT "Drugs Here", -1, 6, 116, 37, 8, WS_CHILD | WS_VISIBLE | WS_GROUP | |
+ LTEXT "Drugs Carried", -1, 135, 116, 47, 8, WS_CHILD | WS_VISIBLE | WS… | |
+END | |
+ | |
+MainMenu MENU | |
+BEGIN | |
+ POPUP "&Game" | |
+ BEGIN | |
+ MENUITEM "&New...", ID_NEWGAME | |
+ MENUITEM SEPARATOR | |
+ MENUITEM "E&xit\tAlt+F4", ID_EXIT | |
+ END | |
+ | |
+ POPUP "&Talk", GRAYED | |
+ BEGIN | |
+ MENUITEM "To &all...", ID_TALKTOALL | |
+ MENUITEM "To &players...", ID_TALKTOPLAYERS | |
+ END | |
+ | |
+ POPUP "&List", GRAYED | |
+ BEGIN | |
+ MENUITEM "&Players...", ID_LISTPLAYERS | |
+ MENUITEM "&Scores...", ID_LISTSCORES | |
+ MENUITEM "&Inventory...", ID_LISTINVENTORY | |
+ END | |
+ | |
+ POPUP "&Errands", GRAYED | |
+ BEGIN | |
+ MENUITEM "&Spy...", ID_SPY | |
+ MENUITEM "&Tipoff...", ID_TIPOFF | |
+ MENUITEM "Sack &Bitch...", ID_SACKBITCH | |
+ MENUITEM "&Get spy reports...", ID_GETSPY | |
+ END | |
+ | |
+ POPUP "&Help", HELP | |
+ BEGIN | |
+ MENUITEM "&About...", ID_ABOUT | |
+ END | |
+ | |
+END | |
+ | |
+AboutDialog DIALOG 28, 31, 255, 183 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "About dopewars" | |
+BEGIN | |
+ CTEXT "Based on John E. Dell's old Drug Wars game, dopewars is a simul… | |
+ CTEXT "The first thing you need to do is pay off your debt to the Loan… | |
+ CTEXT "Copyright (C) 1998-2000 Ben Webb [email protected]… | |
+ CTEXT "dopewars is released under the GNU General Public Licence", -1,… | |
+ LTEXT "Drug Dealing and Research", -1, 19, 99, 92, 8, WS_CHILD | WS_VI… | |
+ LTEXT "Play Testing", -1, 19, 111, 42, 8, WS_CHILD | WS_VISIBLE | WS_G… | |
+ LTEXT "Extensive Play Testing", -1, 19, 123, 77, 8, WS_CHILD | WS_VISI… | |
+ LTEXT "Constructive Criticism", -1, 19, 135, 74, 8, WS_CHILD | WS_VISI… | |
+ LTEXT "Unconstructive criticism", -1, 19, 147, 80, 8, WS_CHILD | WS_VI… | |
+ LTEXT "Dan Wolf", -1, 116, 99, 34, 8, WS_CHILD | WS_VISIBLE | WS_GROUP | |
+ LTEXT "Phil Davis", -1, 116, 111, 36, 8, WS_CHILD | WS_VISIBLE | WS_GR… | |
+ LTEXT "Owen Walsh", -1, 183, 111, 45, 8, WS_CHILD | WS_VISIBLE | WS_GR… | |
+ LTEXT "Katherine Holt", -1, 116, 123, 49, 8, WS_CHILD | WS_VISIBLE | W… | |
+ LTEXT "Caroline Moore", -1, 183, 123, 53, 8, WS_CHILD | WS_VISIBLE | W… | |
+ LTEXT "Andrea Elliot-Smith", -1, 116, 135, 64, 8, WS_CHILD | WS_VISIBL… | |
+ LTEXT "Pete Winn", -1, 183, 135, 37, 8, WS_CHILD | WS_VISIBLE | WS_GRO… | |
+ LTEXT "James Matthews", -1, 116, 147, 57, 8, WS_CHILD | WS_VISIBLE | W… | |
+ DEFPUSHBUTTON "OK", ID_OK, 108, 163, 38, 17, WS_CHILD | WS_VISIBLE | W… | |
+END | |
+ | |
+NewGameDialog DIALOG 67, 37, 169, 122 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "New Game" | |
+BEGIN | |
+ LTEXT "Hey dude, what's your name?", -1, 7, 7, 98, 8, WS_CHILD | WS_VI… | |
+ EDITTEXT ED_NAME, 107, 5, 57, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS… | |
+ CONTROL "&Hostname", ST_HOSTNAME, "STATIC", SS_LEFT | WS_CHILD | NOT W… | |
+ CONTROL "&Port", ST_PORT, "STATIC", SS_LEFT | WS_CHILD | NOT WS_VISIBL… | |
+ CONTROL "", ED_HOSTNAME, "EDIT", ES_LEFT | WS_CHILD | NOT WS_VISIBLE |… | |
+ CONTROL "", ED_PORT, "EDIT", ES_LEFT | WS_CHILD | NOT WS_VISIBLE | WS_… | |
+ CONTROL "&Connect", BT_CONNECT, "BUTTON", BS_PUSHBUTTON | WS_CHILD | N… | |
+ CONTROL "&Antique mode", CB_ANTIQUE, "BUTTON", BS_AUTOCHECKBOX | WS_CH… | |
+ CONTROL "&Start single-player game", BT_STARTSINGLE, "BUTTON", BS_PUSH… | |
+ CONTROL "", LB_SERVERLIST, "LISTBOX", LBS_NOTIFY | LBS_HASSTRINGS | LB… | |
+ CONTROL "&Update", BT_UPDATE, "BUTTON", BS_PUSHBUTTON | WS_CHILD | NOT… | |
+END | |
+ | |
+JetDialog DIALOG 18, 18, 142, 92 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "Jet" | |
+BEGIN | |
+ LTEXT "Jet to location:-", -1, 5, 6, 51, 8, WS_CHILD | WS_VISIBLE | WS… | |
+END | |
+ | |
+DealDialog DIALOG 18, 18, 157, 88 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "Deal Drugs" | |
+BEGIN | |
+ LTEXT "Buy", ST_DEALTYPE, 3, 9, 18, 8, WS_CHILD | WS_VISIBLE | WS_GROUP | |
+ CONTROL "", CB_DEALDRUG, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_… | |
+ LTEXT "at $1000", ST_DEALPRICE, 99, 9, 54, 8, WS_CHILD | WS_VISIBLE | … | |
+ CTEXT "You can afford 100, and can carry 100", ST_DEALLIMIT, 3, 38, 15… | |
+ RTEXT "Buy how many?", ST_DEALNUM, 30, 51, 56, 8, SS_RIGHT | WS_CHILD … | |
+ EDITTEXT ED_DEALNUM, 91, 49, 33, 12, ES_LEFT | WS_CHILD | WS_VISIBLE |… | |
+ DEFPUSHBUTTON "OK", ID_OK, 41, 69, 28, 14, WS_CHILD | WS_VISIBLE | WS_… | |
+ CTEXT "You are currently carrying 100", ST_DEALCARRY, 3, 27, 151, 8, W… | |
+ PUSHBUTTON "Cancel", ID_CANCEL, 87, 69, 28, 14, WS_CHILD | WS_VISIBLE … | |
+END | |
+ | |
+GunShopDia DIALOG 25, 22, 227, 88 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "Gun Shop" | |
+BEGIN | |
+ LTEXT "Guns here", ST_GUNSHERE, 7, 8, 71, 8, WS_CHILD | WS_VISIBLE | W… | |
+ LTEXT "Guns carried", ST_GUNSCARRIED, 133, 8, 71, 8, WS_CHILD | WS_VIS… | |
+ CONTROL "", LB_GUNSHERE, "LISTBOX", LBS_NOTIFY | LBS_HASSTRINGS | LBS_… | |
+ CONTROL "", LB_GUNSCARRIED, "LISTBOX", LBS_NOTIFY | LBS_HASSTRINGS | L… | |
+ PUSHBUTTON "&Buy ->", BT_BUYGUN, 98, 19, 30, 14, WS_CHILD | WS_VISIBLE… | |
+ PUSHBUTTON "<- &Sell", BT_SELLGUN, 98, 38, 30, 14, WS_CHILD | WS_VISIB… | |
+ DEFPUSHBUTTON "OK", ID_OK, 98, 66, 30, 14, WS_CHILD | WS_VISIBLE | WS_… | |
+END | |
+ | |
+ | |
+QuestionDia DIALOG 18, 18, 142, 92 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | |
+CAPTION "Question" | |
+BEGIN | |
+ CTEXT "Text", ST_TEXT, 6, 12, 128, 40, WS_CHILD | WS_VISIBLE | WS_GROUP | |
+END | |
+ | |
+PlayerListDia DIALOG 18, 18, 142, 94 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "Player List" | |
+BEGIN | |
+ LTEXT "Players currently logged on:-", -1, 7, 6, 97, 8, WS_CHILD | WS_… | |
+ CONTROL "", LB_PLAYERLIST, "LISTBOX", LBS_NOTIFY | LBS_HASSTRINGS | WS… | |
+ PUSHBUTTON "&Close", ID_CANCEL, 57, 74, 28, 14, WS_CHILD | WS_VISIBLE … | |
+END | |
+ | |
+TalkDialog DIALOG 24, 18, 147, 120 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "Talk" | |
+BEGIN | |
+ CONTROL "", LB_TALKPLAYERS, "LISTBOX", LBS_NOTIFY | LBS_MULTIPLESEL | … | |
+ LTEXT "Talk to", -1, 8, 3, 24, 8, WS_CHILD | WS_VISIBLE | WS_GROUP | |
+ EDITTEXT EB_TALKMESSAGE, 8, 81, 130, 12, ES_LEFT | WS_CHILD | WS_VISIB… | |
+ CONTROL "All players", CB_TALKALL, "BUTTON", BS_AUTOCHECKBOX | WS_CHIL… | |
+ LTEXT "Message", -1, 8, 71, 34, 8, WS_CHILD | WS_VISIBLE | WS_GROUP | |
+ DEFPUSHBUTTON "&Send", BT_TALKSEND, 31, 100, 27, 14, WS_CHILD | WS_VIS… | |
+ PUSHBUTTON "&Close", ID_CANCEL, 89, 100, 27, 14, WS_CHILD | WS_VISIBLE… | |
+END | |
+ | |
+InventoryDia DIALOG 18, 18, 210, 88 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "Inventory" | |
+BEGIN | |
+ LTEXT "Drugs", ST_INVENDRUGS, 7, 5, 47, 8, WS_CHILD | WS_VISIBLE | WS_… | |
+ LTEXT "Guns", ST_INVENGUNS, 111, 5, 51, 8, WS_CHILD | WS_VISIBLE | WS_… | |
+ LISTBOX LB_INVENDRUGS, 7, 15, 93, 48, LBS_NOTIFY | WS_CHILD | WS_VISIB… | |
+ LISTBOX LB_INVENGUNS, 111, 15, 93, 48, LBS_NOTIFY | WS_CHILD | WS_VISI… | |
+ PUSHBUTTON "&Close", ID_CANCEL, 91, 69, 28, 14, WS_CHILD | WS_VISIBLE … | |
+END | |
+ | |
+HiScoreDia DIALOG 18, 18, 157, 151 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "High Scores" | |
+BEGIN | |
+ CONTROL "", LB_HISCORES, "LISTBOX", LBS_NOTIFY | LBS_HASSTRINGS | LBS_… | |
+ PUSHBUTTON "&Close", ID_CANCEL, 64, 132, 28, 14, WS_CHILD | WS_VISIBLE… | |
+END | |
+ | |
+FightDialog DIALOG 18, 18, 185, 99 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "Fight" | |
+BEGIN | |
+ CONTROL "", EB_FIGHTSTATUS, "EDIT", ES_LEFT | ES_MULTILINE | ES_READON… | |
+ PUSHBUTTON "&Deal Drugs", BT_DEALDRUGS, 6, 77, 46, 16, WS_CHILD | WS_V… | |
+ PUSHBUTTON "&Fight", BT_FIGHT, 69, 77, 46, 16, WS_CHILD | WS_VISIBLE |… | |
+ PUSHBUTTON "&Run", BT_RUN, 132, 77, 46, 16, WS_CHILD | WS_VISIBLE | WS… | |
+END | |
+ | |
+ | |
+ErrandDialog DIALOG 18, 18, 190, 132 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "Tip Off" | |
+BEGIN | |
+ CTEXT "Please choose the player to tip off the cops to. Your bitch wil… | |
+ LISTBOX LB_ERRANDPLAY, 19, 65, 152, 39, LBS_NOTIFY | WS_CHILD | WS_VIS… | |
+ DEFPUSHBUTTON "OK", ID_OK, 27, 110, 32, 17, WS_CHILD | WS_VISIBLE | WS… | |
+ PUSHBUTTON "&Cancel", ID_CANCEL, 130, 110, 32, 17, WS_CHILD | WS_VISIB… | |
+END | |
+ | |
+BankDialog DIALOG 99, 78, 117, 93 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "Bank" | |
+BEGIN | |
+ CONTROL "&Withdraw", RB_WITHDRAW, "BUTTON", BS_AUTORADIOBUTTON | WS_CH… | |
+ CONTROL "&Deposit", RB_DEPOSIT, "BUTTON", BS_AUTORADIOBUTTON | WS_CHIL… | |
+ LTEXT "$", ST_CURRENCY, 56, 40, 7, 8, WS_CHILD | WS_VISIBLE | WS_GROUP | |
+ EDITTEXT EB_MONEY, 64, 38, 45, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | W… | |
+ DEFPUSHBUTTON "OK", ID_OK, 13, 68, 32, 16, WS_CHILD | WS_VISIBLE | WS_… | |
+ PUSHBUTTON "&Cancel", ID_CANCEL, 67, 68, 32, 16, WS_CHILD | WS_VISIBLE… | |
+ CTEXT "Cash: $0", ST_MONEY, 7, 5, 102, 8, WS_CHILD | WS_VISIBLE | WS_G… | |
+ CTEXT "Bank: $0", ST_BANK, 7, 16, 102, 8, WS_CHILD | WS_VISIBLE | WS_G… | |
+END | |
+DebtDialog DIALOG 88, 60, 117, 76 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | |
+CAPTION "Debt" | |
+BEGIN | |
+ LTEXT "$", ST_CURRENCY, 53, 33, 7, 8, WS_CHILD | WS_VISIBLE | WS_GROUP | |
+ EDITTEXT EB_MONEY, 61, 31, 45, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | W… | |
+ DEFPUSHBUTTON "OK", ID_OK, 15, 53, 32, 16, WS_CHILD | WS_VISIBLE | WS_… | |
+ PUSHBUTTON "&Cancel", ID_CANCEL, 69, 53, 32, 16, WS_CHILD | WS_VISIBLE… | |
+ LTEXT "Pay back:", 102, 10, 33, 38, 8, WS_CHILD | WS_VISIBLE | WS_GROUP | |
+ CTEXT "Cash: $0", ST_MONEY, 7, 4, 102, 8, WS_CHILD | WS_VISIBLE | WS_G… | |
+ CTEXT "Debt: $0", ST_BANK, 7, 15, 102, 8, WS_CHILD | WS_VISIBLE | WS_G… | |
+END | |
+NewNameDia DIALOG 18, 18, 148, 64 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | |
+CAPTION "New Name" | |
+BEGIN | |
+ LTEXT "Unfortunately somebody is already using ""your"" name. Please c… | |
+ EDITTEXT EB_NEWNAME, 8, 28, 131, 12, ES_LEFT | WS_CHILD | WS_VISIBLE |… | |
+ DEFPUSHBUTTON "OK", ID_OK, 62, 46, 24, 14, WS_CHILD | WS_VISIBLE | WS_… | |
+END | |
+SpyReportsDia DIALOG 18, 18, 142, 92 | |
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | |
+CAPTION "Spy Reports" | |
+BEGIN | |
+ PUSHBUTTON "&Close", ID_CANCEL, 56, 71, 30, 15, WS_CHILD | WS_VISIBLE … | |
+END | |
diff --git a/src/gtk_client.c b/src/gtk_client.c | |
t@@ -0,0 +1,2547 @@ | |
+/* gtk_client.c dopewars client using the GTK+ toolkit */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#ifdef GTK_CLIENT | |
+ | |
+#include <stdlib.h> | |
+#include <string.h> | |
+#include <gtk/gtk.h> | |
+#include <gdk/gdkkeysyms.h> | |
+ | |
+#include "dopeos.h" | |
+#include "dopewars.h" | |
+#include "gtk_client.h" | |
+#include "message.h" | |
+#include "serverside.h" | |
+ | |
+#define BT_BUY (GINT_TO_POINTER(1)) | |
+#define BT_SELL (GINT_TO_POINTER(2)) | |
+#define BT_DROP (GINT_TO_POINTER(3)) | |
+ | |
+#define MB_OK 1 | |
+#define MB_CANCEL 2 | |
+#define MB_YES 4 | |
+#define MB_NO 8 | |
+#define MB_MAX 4 | |
+ | |
+#define ET_SPY 0 | |
+#define ET_TIPOFF 1 | |
+ | |
+struct InventoryWidgets { | |
+ GtkWidget *HereList,*CarriedList; | |
+ GtkWidget *HereFrame,*CarriedFrame; | |
+ GtkWidget *BuyButton,*SellButton,*DropButton; | |
+ GtkWidget *vbbox; | |
+}; | |
+ | |
+struct StatusWidgets { | |
+ GtkWidget *Location,*Date,*SpaceName,*SpaceValue,*CashName,*CashValue, | |
+ *DebtName,*DebtValue,*BankName,*BankValue, | |
+ *GunsName,*GunsValue,*BitchesName,*BitchesValue, | |
+ *HealthName,*HealthValue; | |
+}; | |
+ | |
+struct ClientDataStruct { | |
+ GtkWidget *window,*messages; | |
+ gchar *PlayerName; | |
+ Player *Play; | |
+ GtkItemFactory *Menu; | |
+ struct StatusWidgets Status; | |
+ struct InventoryWidgets Drug,Gun,InvenDrug,InvenGun; | |
+ GtkWidget *JetButton,*vbox,*PlayerList,*TalkList; | |
+ guint JetAccel; | |
+ gint GdkInputTag; | |
+}; | |
+ | |
+static struct ClientDataStruct ClientData; | |
+static gboolean InGame=FALSE,MetaServerRead=FALSE; | |
+static GtkWidget *FightDialog=NULL,*SpyReportsDialog; | |
+static gboolean IsShowingPlayerList=FALSE,IsShowingTalkList=FALSE, | |
+ IsShowingInventory=FALSE,IsShowingGunShop=FALSE; | |
+ | |
+static void display_intro(GtkWidget *widget,gpointer data); | |
+static void DestroyGtk(GtkWidget *widget,gpointer data); | |
+static void QuitGame(GtkWidget *widget,gpointer data); | |
+static void NewGame(GtkWidget *widget,gpointer data); | |
+static void ListScores(GtkWidget *widget,gpointer data); | |
+static void ListInventory(GtkWidget *widget,gpointer data); | |
+static void NewGameDialog(); | |
+static void StartGame(); | |
+static void EndGame(); | |
+static void UpdateMenus(); | |
+static void GetClientMessage(gpointer data,gint socket, | |
+ GdkInputCondition condition); | |
+static void SetSocketWriteTest(Player *Play,gboolean WriteTest); | |
+static void HandleClientMessage(char *buf,Player *ReallyTo); | |
+static void PrepareHighScoreDialog(); | |
+static void AddScoreToDialog(char *Data); | |
+static void CompleteHighScoreDialog(); | |
+static void PrintMessage(char *Data); | |
+static void DisplayFightMessage(char *Data); | |
+static GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status); | |
+static void DisplayStats(Player *Play,struct StatusWidgets *Status); | |
+static void UpdateStatus(Player *Play,gboolean DisplayDrugs); | |
+static void SetJetButtonTitle(GtkAccelGroup *accel_group); | |
+static void UpdateInventory(struct InventoryWidgets *Inven, | |
+ Inventory *Objects,int NumObjects, | |
+ gboolean AreDrugs); | |
+static void JetButtonPressed(GtkWidget *widget,gpointer data); | |
+static void Jet(); | |
+static void DealDrugs(GtkWidget *widget,gpointer data); | |
+static void DealGuns(GtkWidget *widget,gpointer data); | |
+static void QuestionDialog(char *Data,Player *From); | |
+static gint MessageBox(GtkWidget *parent,const gchar *Title, | |
+ const gchar *Text,gint Options); | |
+static void TransferDialog(gboolean Debt); | |
+static void ListPlayers(GtkWidget *widget,gpointer data); | |
+static void TalkToAll(GtkWidget *widget,gpointer data); | |
+static void TalkToPlayers(GtkWidget *widget,gpointer data); | |
+static void TalkDialog(gboolean TalkToAll); | |
+static GtkWidget *CreatePlayerList(); | |
+static void UpdatePlayerList(GtkWidget *clist,gboolean IncludeSelf); | |
+static void TipOff(GtkWidget *widget,gpointer data); | |
+static void SpyOnPlayer(GtkWidget *widget,gpointer data); | |
+static void ErrandDialog(gint ErrandType); | |
+static void SackBitch(GtkWidget *widget,gpointer data); | |
+static void DestroyShowing(GtkWidget *widget,gpointer data); | |
+static gint DisallowDelete(GtkWidget *widget,GdkEvent *event,gpointer data); | |
+static void GunShopDialog(); | |
+static void NewNameDialog(); | |
+static void UpdatePlayerLists(); | |
+static void CreateInventory(GtkWidget *hbox,gchar *Objects, | |
+ GtkAccelGroup *accel_group, | |
+ gboolean CreateButtons,gboolean CreateHere, | |
+ struct InventoryWidgets *widgets, | |
+ GtkSignalFunc CallBack); | |
+static void GetSpyReports(GtkWidget *widget,gpointer data); | |
+static void DisplaySpyReports(Player *Play); | |
+ | |
+static GtkItemFactoryEntry menu_items[] = { | |
+ { N_("/_Game"),NULL,NULL,0,"<Branch>" }, | |
+ { N_("/Game/_New"),"<control>N",NewGame,0,NULL }, | |
+ { N_("/Game/_Quit"),"<control>Q",QuitGame,0,NULL }, | |
+ { N_("/_Talk"),NULL,NULL,0,"<Branch>" }, | |
+ { N_("/Talk/To _All"),NULL,TalkToAll,0,NULL }, | |
+ { N_("/Talk/To _Player"),NULL,TalkToPlayers,0,NULL }, | |
+ { N_("/_List"),NULL,NULL,0,"<Branch>" }, | |
+ { N_("/List/_Players"),NULL,ListPlayers,0,NULL }, | |
+ { N_("/List/_Scores"),NULL,ListScores,0,NULL }, | |
+ { N_("/List/_Inventory"),NULL,ListInventory,0,NULL }, | |
+ { N_("/_Errands"),NULL,NULL,0,"<Branch>" }, | |
+ { N_("/Errands/_Spy"),NULL,SpyOnPlayer,0,NULL }, | |
+ { N_("/Errands/_Tipoff"),NULL,TipOff,0,NULL }, | |
+ { N_("/Errands/Sack _Bitch"),NULL,SackBitch,0,NULL }, | |
+ { N_("/Errands/_Get spy reports"),NULL,GetSpyReports,0,NULL }, | |
+ { N_("/_Help"),NULL,NULL,0,"<LastBranch>" }, | |
+ { N_("/Help/_About"),"F1",display_intro,0,NULL } | |
+}; | |
+ | |
+static void LogMessage(const gchar *log_domain,GLogLevelFlags log_level, | |
+ const gchar *message,gpointer user_data) { | |
+ MessageBox(NULL,log_level&G_LOG_LEVEL_WARNING ? _("Warning") : _("Message"), | |
+ message,MB_OK); | |
+} | |
+ | |
+void DestroyGtk(GtkWidget *widget,gpointer data) { | |
+ gtk_main_quit(); | |
+} | |
+ | |
+void QuitGame(GtkWidget *widget,gpointer data) { | |
+ if (!InGame || | |
+ MessageBox(ClientData.window,_("Quit Game"),_("Abandon current game?"), | |
+ MB_YES|MB_NO)==MB_YES) { | |
+ gtk_main_quit(); | |
+ } | |
+} | |
+ | |
+void NewGame(GtkWidget *widget,gpointer data) { | |
+ if (InGame) { | |
+ if (MessageBox(ClientData.window,_("Start new game"), | |
+ _("Abandon current game?"),MB_YES|MB_NO)==MB_YES) EndGame(); | |
+ else return; | |
+ } | |
+ NewGameDialog(); | |
+} | |
+ | |
+void ListScores(GtkWidget *widget,gpointer data) { | |
+ SendClientMessage(ClientData.Play,C_NONE,C_REQUESTSCORE,NULL,NULL, | |
+ ClientData.Play); | |
+} | |
+ | |
+void ListInventory(GtkWidget *widget,gpointer data) { | |
+ GtkWidget *window,*button,*hsep,*vbox,*hbox; | |
+ GtkAccelGroup *accel_group; | |
+ gchar *caps; | |
+ | |
+ if (IsShowingInventory) return; | |
+ window=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_default_size(GTK_WINDOW(window),550,120); | |
+ accel_group=gtk_accel_group_new(); | |
+ gtk_window_add_accel_group(GTK_WINDOW(window),accel_group); | |
+ gtk_window_set_title(GTK_WINDOW(window),_("Inventory")); | |
+ | |
+ IsShowingInventory=TRUE; | |
+ gtk_window_set_modal(GTK_WINDOW(window),FALSE); | |
+ gtk_object_set_data(GTK_OBJECT(window),"IsShowing", | |
+ (gpointer)&IsShowingInventory); | |
+ gtk_signal_connect(GTK_OBJECT(window),"destroy", | |
+ GTK_SIGNAL_FUNC(DestroyShowing),NULL); | |
+ | |
+ gtk_window_set_transient_for(GTK_WINDOW(window), | |
+ GTK_WINDOW(ClientData.window)); | |
+ gtk_container_set_border_width(GTK_CONTAINER(window),7); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ | |
+ hbox=gtk_hbox_new(FALSE,7); | |
+ caps=InitialCaps(Names.Drugs); | |
+ CreateInventory(hbox,caps,accel_group,FALSE,FALSE, | |
+ &ClientData.InvenDrug,NULL); g_free(caps); | |
+ caps=InitialCaps(Names.Guns); | |
+ CreateInventory(hbox,caps,accel_group,FALSE,FALSE, | |
+ &ClientData.InvenGun,NULL); g_free(caps); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ button=gtk_button_new_with_label(_("Close")); | |
+ gtk_signal_connect_object(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)window); | |
+ gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(window),vbox); | |
+ | |
+ UpdateInventory(&ClientData.InvenDrug,ClientData.Play->Drugs,NumDrug,TRUE); | |
+ UpdateInventory(&ClientData.InvenGun,ClientData.Play->Guns,NumGun,FALSE); | |
+ | |
+ gtk_widget_show_all(window); | |
+} | |
+ | |
+void GetClientMessage(gpointer data,gint socket, | |
+ GdkInputCondition condition) { | |
+ gchar *pt; | |
+ if (condition&GDK_INPUT_WRITE) { | |
+ WriteConnectionBufferToWire(ClientData.Play); | |
+ if (ClientData.Play->WriteBuf.DataPresent==0) { | |
+ SetSocketWriteTest(ClientData.Play,FALSE); | |
+ } | |
+ } | |
+ if (condition&GDK_INPUT_READ) { | |
+ if (ReadConnectionBufferFromWire(ClientData.Play)) { | |
+ while ((pt=ReadFromConnectionBuffer(ClientData.Play))!=NULL) { | |
+ HandleClientMessage(pt,NULL); g_free(pt); | |
+ } | |
+ } else { | |
+ if (Network) gdk_input_remove(ClientData.GdkInputTag); | |
+ g_warning(_("Connection to server lost - switching to " | |
+ "single player mode")); | |
+ SwitchToSinglePlayer(ClientData.Play); | |
+ } | |
+ } | |
+} | |
+ | |
+void SetSocketWriteTest(Player *Play,gboolean WriteTest) { | |
+ if (Network) { | |
+ if (ClientData.GdkInputTag) gdk_input_remove(ClientData.GdkInputTag); | |
+ ClientData.GdkInputTag=gdk_input_add(Play->fd, | |
+ GDK_INPUT_READ|(WriteTest ? GDK_INPUT_WRITE : 0), | |
+ GetClientMessage,NULL); | |
+ } | |
+} | |
+ | |
+void HandleClientMessage(char *pt,Player *ReallyTo) { | |
+ char *Data,Code,AICode,DisplayMode; | |
+ Player *From,*To,*Play; | |
+ gchar *text,*prstr; | |
+ gboolean Handled; | |
+ GtkWidget *MenuItem; | |
+ GSList *list; | |
+ if (ProcessMessage(pt,&From,&AICode,&Code,&To,&Data,FirstClient)==-1) { | |
+ return; | |
+ } | |
+ Handled=HandleGenericClientMessage(From,AICode,Code,To,Data,&DisplayMode); | |
+ switch(Code) { | |
+ case C_STARTHISCORE: | |
+ PrepareHighScoreDialog(); break; | |
+ case C_HISCORE: | |
+ AddScoreToDialog(Data); break; | |
+ case C_ENDHISCORE: | |
+ CompleteHighScoreDialog(); | |
+ if (strcmp(Data,"end")==0) EndGame(); | |
+ break; | |
+ case C_PRINTMESSAGE: | |
+ PrintMessage(Data); break; | |
+ case C_FIGHTPRINT: | |
+ DisplayFightMessage(Data); break; | |
+ case C_PUSH: | |
+ if (Network) gdk_input_remove(ClientData.GdkInputTag); | |
+ g_warning(_("You have been pushed from the server.")); | |
+ SwitchToSinglePlayer(To); | |
+ break; | |
+ case C_QUIT: | |
+ if (Network) gdk_input_remove(ClientData.GdkInputTag); | |
+ g_warning(_("The server has terminated.")); | |
+ SwitchToSinglePlayer(To); | |
+ break; | |
+ case C_NEWNAME: | |
+ NewNameDialog(); break; | |
+ case C_BANK: | |
+ TransferDialog(FALSE); break; | |
+ case C_LOANSHARK: | |
+ TransferDialog(TRUE); break; | |
+ case C_GUNSHOP: | |
+ GunShopDialog(); break; | |
+ case C_MSG: | |
+ text=g_strdup_printf("%s: %s",GetPlayerName(From),Data); | |
+ PrintMessage(text); g_free(text); | |
+ break; | |
+ case C_MSGTO: | |
+ text=g_strdup_printf("%s->%s: %s",GetPlayerName(From), | |
+ GetPlayerName(To),Data); | |
+ PrintMessage(text); g_free(text); | |
+ break; | |
+ case C_JOIN: | |
+ text=g_strdup_printf(_("%s joins the game!"),Data); | |
+ PrintMessage(text); g_free(text); | |
+ UpdatePlayerLists(); | |
+ break; | |
+ case C_LEAVE: | |
+ if (From!=&Noone) { | |
+ text=g_strdup_printf(_("%s has left the game."),Data); | |
+ PrintMessage(text); g_free(text); | |
+ UpdatePlayerLists(); | |
+ } | |
+ break; | |
+ case C_QUESTION: | |
+ QuestionDialog(Data,From==&Noone ? NULL : From); break; | |
+ case C_SUBWAYFLASH: | |
+ DisplayFightMessage(NULL); | |
+ for (list=FirstClient;list;list=g_slist_next(list)) { | |
+ Play=(Player *)list->data; | |
+ Play->Flags &= ~FIGHTING; | |
+ } | |
+ text=g_strdup_printf(_("Jetting to %s"),Location[(int)To->IsAt].Name); | |
+ PrintMessage(text); g_free(text); | |
+ break; | |
+ case C_ENDLIST: | |
+ MenuItem=gtk_item_factory_get_widget(ClientData.Menu, | |
+ _("<main>/Errands/Spy")); | |
+ prstr=FormatPrice(Prices.Spy); | |
+ text=g_strdup_printf(_("_Spy\t(%s)"),prstr); | |
+ gtk_label_parse_uline(GTK_LABEL(GTK_BIN(MenuItem)->child),text); | |
+ g_free(text); g_free(prstr); | |
+ prstr=FormatPrice(Prices.Tipoff); | |
+ text=g_strdup_printf(_("_Tipoff\t(%s)"),prstr); | |
+ MenuItem=gtk_item_factory_get_widget(ClientData.Menu, | |
+ _("<main>/Errands/Tipoff")); | |
+ gtk_label_parse_uline(GTK_LABEL(GTK_BIN(MenuItem)->child),text); | |
+ g_free(text); g_free(prstr); | |
+ break; | |
+ case C_UPDATE: | |
+ if (From==&Noone) { | |
+ ReceivePlayerData(Data,To); | |
+ UpdateStatus(To,TRUE); | |
+ } else { | |
+ ReceivePlayerData(Data,From); | |
+ DisplaySpyReports(From); | |
+ } | |
+ break; | |
+ case C_DRUGHERE: | |
+ UpdateInventory(&ClientData.Drug,To->Drugs,NumDrug,TRUE); | |
+ gtk_clist_sort(GTK_CLIST(ClientData.Drug.HereList)); | |
+ if (IsShowingInventory) { | |
+ UpdateInventory(&ClientData.InvenDrug,To->Drugs,NumDrug,TRUE); | |
+ } | |
+ break; | |
+ } | |
+ g_free(Data); | |
+} | |
+ | |
+struct HiScoreDiaStruct { | |
+ GtkWidget *dialog,*table,*vbox; | |
+}; | |
+static struct HiScoreDiaStruct HiScoreDialog; | |
+ | |
+void PrepareHighScoreDialog() { | |
+ GtkWidget *dialog,*vbox,*hsep,*table; | |
+ | |
+ HiScoreDialog.dialog=dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_title(GTK_WINDOW(dialog),_("High Scores")); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog),7); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ HiScoreDialog.vbox=vbox=gtk_vbox_new(FALSE,7); | |
+ HiScoreDialog.table=table=gtk_table_new(NUMHISCORE,1,FALSE); | |
+ gtk_table_set_row_spacings(GTK_TABLE(table),5); | |
+ gtk_table_set_col_spacings(GTK_TABLE(table),5); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),table,TRUE,TRUE,0); | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+void AddScoreToDialog(char *Data) { | |
+ GtkWidget *label; | |
+ char *cp; | |
+ int index; | |
+ cp=Data; | |
+ index=GetNextInt(&cp,0); | |
+ if (!cp || strlen(cp)<2) return; | |
+ label=gtk_label_new(&cp[1]); | |
+ gtk_table_attach_defaults(GTK_TABLE(HiScoreDialog.table),label, | |
+ 0,1,index,index+1); | |
+ gtk_widget_show(label); | |
+} | |
+ | |
+void CompleteHighScoreDialog() { | |
+ GtkWidget *OKButton,*dialog; | |
+ dialog=HiScoreDialog.dialog; | |
+ OKButton=gtk_button_new_with_label(_("OK")); | |
+ gtk_signal_connect_object(GTK_OBJECT(OKButton),"clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)dialog); | |
+ gtk_box_pack_start(GTK_BOX(HiScoreDialog.vbox),OKButton,TRUE,TRUE,0); | |
+ | |
+ GTK_WIDGET_SET_FLAGS(OKButton,GTK_CAN_DEFAULT); | |
+ gtk_widget_grab_default(OKButton); | |
+ gtk_widget_show(OKButton); | |
+} | |
+ | |
+void PrintMessage(char *text) { | |
+ gint EditPos; | |
+ char *cr="\n"; | |
+ GtkEditable *messages; | |
+ | |
+ messages=GTK_EDITABLE(ClientData.messages); | |
+ | |
+ g_strdelimit(text,"^",'\n'); | |
+ EditPos=gtk_text_get_length(GTK_TEXT(ClientData.messages)); | |
+ while (*text=='\n') text++; | |
+ gtk_editable_insert_text(messages,text,strlen(text),&EditPos); | |
+ if (text[strlen(text)-1]!='\n') { | |
+ gtk_editable_insert_text(messages,cr,1,&EditPos); | |
+ } | |
+} | |
+ | |
+static void FightCallback(GtkWidget *widget,gpointer data) { | |
+ gint Answer; | |
+ Player *Play; | |
+ gchar *text; | |
+ Answer=GPOINTER_TO_INT(data); | |
+ Play=ClientData.Play; | |
+ switch(Answer) { | |
+ case 'D': | |
+ gtk_widget_hide(FightDialog); break; | |
+ case 'R': | |
+ gtk_widget_hide(FightDialog); | |
+ Jet(); break; | |
+ case 'F': case 'S': | |
+ if (Play->Flags&CANSHOOT && | |
+ ((Answer=='F' && TotalGunsCarried(Play)>0) || | |
+ (Answer=='S' && TotalGunsCarried(Play)==0))) { | |
+ Play->Flags &= ~CANSHOOT; | |
+ text=g_strdup_printf("%c",Answer); | |
+ SendClientMessage(Play,C_NONE,C_FIGHTACT,NULL,text,Play); | |
+ g_free(text); | |
+ } | |
+ break; | |
+ } | |
+} | |
+ | |
+static GtkWidget *AddFightButton(gchar *Text,GtkAccelGroup *accel_group, | |
+ GtkBox *box,gint Answer) { | |
+ GtkWidget *button; | |
+ guint AccelKey; | |
+ button=gtk_button_new_with_label(""); | |
+ AccelKey=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child),Text); | |
+ gtk_widget_add_accelerator(button,"clicked",accel_group,AccelKey,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(FightCallback), | |
+ GINT_TO_POINTER(Answer)); | |
+ gtk_box_pack_start(box,button,TRUE,TRUE,0); | |
+ return button; | |
+} | |
+ | |
+static void CreateFightDialog() { | |
+ GtkWidget *dialog,*vbox,*button,*hbox,*hbbox,*hsep,*text,*vscroll; | |
+ GtkAdjustment *adj; | |
+ GtkAccelGroup *accel_group; | |
+ gchar *buf; | |
+ | |
+ FightDialog=dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_signal_connect(GTK_OBJECT(dialog),"delete_event", | |
+ GTK_SIGNAL_FUNC(DisallowDelete),NULL); | |
+ gtk_window_set_default_size(GTK_WINDOW(dialog),240,130); | |
+ accel_group=gtk_accel_group_new(); | |
+ gtk_window_add_accel_group(GTK_WINDOW(dialog),accel_group); | |
+ gtk_window_set_title(GTK_WINDOW(dialog),_("Fight")); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog),7); | |
+ | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ | |
+ hbox=gtk_hbox_new(FALSE,0); | |
+ adj=(GtkAdjustment *)gtk_adjustment_new(0.0,0.0,100.0,1.0,10.0,10.0); | |
+ text=gtk_text_new(NULL,adj); | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"text",text); | |
+ gtk_text_set_editable(GTK_TEXT(text),FALSE); | |
+ gtk_text_set_word_wrap(GTK_TEXT(text),TRUE); | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"text",text); | |
+ gtk_box_pack_start(GTK_BOX(hbox),text,TRUE,TRUE,0); | |
+ vscroll=gtk_vscrollbar_new(adj); | |
+ gtk_box_pack_start(GTK_BOX(hbox),vscroll,FALSE,FALSE,0); | |
+ gtk_widget_show_all(hbox); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ gtk_widget_show(hsep); | |
+ | |
+ hbbox=gtk_hbutton_box_new(); | |
+ buf=g_strdup_printf(_("_Deal %s"),Names.Drugs); | |
+ button=AddFightButton(buf,accel_group,GTK_BOX(hbbox),'D'); | |
+ gtk_widget_show(button); | |
+ | |
+ button=AddFightButton(_("_Fight"),accel_group,GTK_BOX(hbbox),'F'); | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"fight",button); | |
+ | |
+ button=AddFightButton(_("_Stand"),accel_group,GTK_BOX(hbbox),'S'); | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"stand",button); | |
+ | |
+ button=AddFightButton(_("_Run"),accel_group,GTK_BOX(hbbox),'R'); | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"run",button); | |
+ | |
+ gtk_widget_show(hsep); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbbox,FALSE,FALSE,0); | |
+ gtk_widget_show(hbbox); | |
+ gtk_widget_show(vbox); | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ gtk_widget_show(dialog); | |
+} | |
+ | |
+void DisplayFightMessage(char *Data) { | |
+ Player *Play; | |
+ gint EditPos; | |
+ GtkWidget *Fight,*Stand,*Run,*Text; | |
+ char cr[] = "\n"; | |
+ | |
+ if (!Data) { | |
+ if (FightDialog) { | |
+ gtk_widget_destroy(FightDialog); FightDialog=NULL; | |
+ } | |
+ return; | |
+ } | |
+ if (FightDialog) { | |
+ if (!GTK_WIDGET_VISIBLE(FightDialog)) gtk_widget_show(FightDialog); | |
+ } else { | |
+ CreateFightDialog(); | |
+ } | |
+ if (!FightDialog) return; | |
+ | |
+ Fight=GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog),"fight")); | |
+ Stand=GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog),"stand")); | |
+ Run=GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog),"run")); | |
+ Text=GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(FightDialog),"text")); | |
+ | |
+ Play=ClientData.Play; | |
+ | |
+ g_strdelimit(Data,"^",'\n'); | |
+ if (strlen(Data)>0) { | |
+ EditPos=gtk_text_get_length(GTK_TEXT(Text)); | |
+ gtk_editable_insert_text(GTK_EDITABLE(Text),Data,strlen(Data),&EditPos); | |
+ gtk_editable_insert_text(GTK_EDITABLE(Text),cr,strlen(cr),&EditPos); | |
+ } | |
+ | |
+ if (Play->Flags&CANSHOOT && TotalGunsCarried(Play)>0) | |
+ gtk_widget_show(Fight); else gtk_widget_hide(Fight); | |
+ if (Play->Flags&CANSHOOT && TotalGunsCarried(Play)==0) | |
+ gtk_widget_show(Stand); else gtk_widget_hide(Stand); | |
+ if (Play->Flags&FIGHTING) | |
+ gtk_widget_show(Run); else gtk_widget_hide(Run); | |
+} | |
+ | |
+void DisplayStats(Player *Play,struct StatusWidgets *Status) { | |
+ gchar *prstr,*caps; | |
+ GString *text; | |
+ | |
+ text=g_string_new(NULL); | |
+ | |
+ gtk_label_set_text(GTK_LABEL(Status->Location), | |
+ Location[(int)Play->IsAt].Name); | |
+ | |
+ g_string_sprintf(text,"%s%02d%s",Names.Month,Play->Turn,Names.Year); | |
+ gtk_label_set_text(GTK_LABEL(Status->Date),text->str); | |
+ | |
+ g_string_sprintf(text,"%d",Play->CoatSize); | |
+ gtk_label_set_text(GTK_LABEL(Status->SpaceValue),text->str); | |
+ | |
+ prstr=FormatPrice(Play->Cash); | |
+ gtk_label_set_text(GTK_LABEL(Status->CashValue),prstr); | |
+ g_free(prstr); | |
+ | |
+ prstr=FormatPrice(Play->Bank); | |
+ gtk_label_set_text(GTK_LABEL(Status->BankValue),prstr); | |
+ g_free(prstr); | |
+ | |
+ prstr=FormatPrice(Play->Debt); | |
+ gtk_label_set_text(GTK_LABEL(Status->DebtValue),prstr); | |
+ g_free(prstr); | |
+ | |
+ caps=InitialCaps(Names.Guns); | |
+ gtk_label_set_text(GTK_LABEL(Status->GunsName),caps); | |
+ g_free(caps); | |
+ g_string_sprintf(text,"%d",TotalGunsCarried(Play)); | |
+ gtk_label_set_text(GTK_LABEL(Status->GunsValue),text->str); | |
+ | |
+ if (!WantAntique) { | |
+ caps=InitialCaps(Names.Bitches); | |
+ gtk_label_set_text(GTK_LABEL(Status->BitchesName),caps); | |
+ g_free(caps); | |
+ g_string_sprintf(text,"%d",Play->Bitches.Carried); | |
+ gtk_label_set_text(GTK_LABEL(Status->BitchesValue),text->str); | |
+ } else { | |
+ gtk_label_set_text(GTK_LABEL(Status->BitchesName),NULL); | |
+ gtk_label_set_text(GTK_LABEL(Status->BitchesValue),NULL); | |
+ } | |
+ | |
+ g_string_sprintf(text,"%d",Play->Health); | |
+ gtk_label_set_text(GTK_LABEL(Status->HealthValue),text->str); | |
+ | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+void UpdateStatus(Player *Play,gboolean DisplayDrugs) { | |
+ GtkAccelGroup *accel_group; | |
+ DisplayStats(Play,&ClientData.Status); | |
+ UpdateInventory(&ClientData.Drug,ClientData.Play->Drugs,NumDrug,TRUE); | |
+ gtk_clist_sort(GTK_CLIST(ClientData.Drug.HereList)); | |
+ accel_group=(GtkAccelGroup *) | |
+ gtk_object_get_data(GTK_OBJECT(ClientData.window),"accel_group"); | |
+ SetJetButtonTitle(accel_group); | |
+ if (IsShowingGunShop) { | |
+ UpdateInventory(&ClientData.Gun,ClientData.Play->Guns,NumGun,FALSE); | |
+ } | |
+ if (IsShowingInventory) { | |
+ UpdateInventory(&ClientData.InvenDrug,ClientData.Play->Drugs, | |
+ NumDrug,TRUE); | |
+ UpdateInventory(&ClientData.InvenGun,ClientData.Play->Guns, | |
+ NumGun,FALSE); | |
+ } | |
+} | |
+ | |
+void UpdateInventory(struct InventoryWidgets *Inven, | |
+ Inventory *Objects,int NumObjects,gboolean AreDrugs) { | |
+ GtkWidget *herelist,*carrylist; | |
+ Player *Play; | |
+ gint i,row,selectrow[2]; | |
+ gpointer rowdata; | |
+ price_t price; | |
+ gchar *titles[2]; | |
+ gboolean CanBuy=FALSE,CanSell=FALSE,CanDrop=FALSE; | |
+ GList *glist[2],*selection; | |
+ GtkCList *clist[2]; | |
+ int numlist; | |
+ | |
+ Play=ClientData.Play; | |
+ herelist=Inven->HereList; | |
+ carrylist=Inven->CarriedList; | |
+ | |
+ if (herelist) numlist=2; else numlist=1; | |
+ | |
+/* Make lists of the current selections */ | |
+ clist[0]=GTK_CLIST(carrylist); | |
+ if (herelist) clist[1]=GTK_CLIST(herelist); else clist[1]=NULL; | |
+ | |
+ for (i=0;i<numlist;i++) { | |
+ glist[i]=NULL; | |
+ selectrow[i]=-1; | |
+ for (selection=clist[i]->selection;selection; | |
+ selection=g_list_next(selection)) { | |
+ row=GPOINTER_TO_INT(selection->data); | |
+ rowdata=gtk_clist_get_row_data(clist[i],row); | |
+ glist[i]=g_list_append(glist[i],rowdata); | |
+ } | |
+ } | |
+ | |
+ gtk_clist_freeze(GTK_CLIST(carrylist)); | |
+ gtk_clist_clear(GTK_CLIST(carrylist)); | |
+ | |
+ if (herelist) { | |
+ gtk_clist_freeze(GTK_CLIST(herelist)); | |
+ gtk_clist_clear(GTK_CLIST(herelist)); | |
+ } | |
+ | |
+ for (i=0;i<NumObjects;i++) { | |
+ if (AreDrugs) { | |
+ titles[0] = Drug[i].Name; price=Objects[i].Price; | |
+ } else { | |
+ titles[0]=Gun[i].Name; price=Gun[i].Price; | |
+ } | |
+ | |
+ if (herelist && price > 0) { | |
+ CanBuy=TRUE; | |
+ titles[1] = FormatPrice(price); | |
+ row=gtk_clist_append(GTK_CLIST(herelist),titles); g_free(titles[1]); | |
+ gtk_clist_set_row_data(GTK_CLIST(herelist),row,GINT_TO_POINTER(i)); | |
+ if (g_list_find(glist[1],GINT_TO_POINTER(i))) { | |
+ selectrow[1]=row; | |
+ gtk_clist_select_row(GTK_CLIST(herelist),row,0); | |
+ } | |
+ } | |
+ | |
+ if (Objects[i].Carried > 0) { | |
+ if (price>0) CanSell=TRUE; else CanDrop=TRUE; | |
+ titles[1] = g_strdup_printf("%d",Objects[i].Carried); | |
+ row=gtk_clist_append(GTK_CLIST(carrylist),titles); g_free(titles[1]); | |
+ gtk_clist_set_row_data(GTK_CLIST(carrylist),row,GINT_TO_POINTER(i)); | |
+ if (g_list_find(glist[0],GINT_TO_POINTER(i))) { | |
+ selectrow[0]=row; | |
+ gtk_clist_select_row(GTK_CLIST(carrylist),row,0); | |
+ } | |
+ } | |
+ } | |
+ | |
+ for (i=0;i<numlist;i++) { | |
+ if (selectrow[i]!=-1 && gtk_clist_row_is_visible(clist[i], | |
+ selectrow[i])!=GTK_VISIBILITY_FULL) { | |
+ gtk_clist_moveto(clist[i],selectrow[i],0,0.0,0.0); | |
+ } | |
+ g_list_free(glist[i]); | |
+ } | |
+ | |
+ gtk_clist_thaw(GTK_CLIST(carrylist)); | |
+ if (herelist) gtk_clist_thaw(GTK_CLIST(herelist)); | |
+ | |
+ if (Inven->vbbox) { | |
+ gtk_widget_set_sensitive(Inven->BuyButton,CanBuy); | |
+ gtk_widget_set_sensitive(Inven->SellButton,CanSell); | |
+ gtk_widget_set_sensitive(Inven->DropButton,CanDrop); | |
+ } | |
+} | |
+ | |
+static void JetCallback(GtkWidget *widget,gpointer data) { | |
+ int NewLocation; | |
+ gchar *text; | |
+ GtkWidget *JetDialog; | |
+ | |
+ JetDialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),"dialog")); | |
+ NewLocation = GPOINTER_TO_INT(data); | |
+ text=g_strdup_printf("%d",NewLocation); | |
+ SendClientMessage(ClientData.Play,C_NONE,C_REQUESTJET,NULL, | |
+ text,ClientData.Play); | |
+ g_free(text); | |
+ gtk_widget_destroy(JetDialog); | |
+} | |
+ | |
+void JetButtonPressed(GtkWidget *widget,gpointer data) { | |
+ if (ClientData.Play->Flags & FIGHTING) { | |
+ DisplayFightMessage(""); | |
+ } else { | |
+ Jet(); | |
+ } | |
+} | |
+ | |
+void Jet() { | |
+ GtkWidget *dialog,*table,*button,*label,*vbox; | |
+ GtkAccelGroup *accel_group; | |
+ gint boxsize,i,row,col; | |
+ gchar *name,AccelChar; | |
+ guint AccelKey; | |
+ | |
+ accel_group=gtk_accel_group_new(); | |
+ | |
+ dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_title(GTK_WINDOW(dialog),_("Jet to location")); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog),7); | |
+ gtk_window_add_accel_group(GTK_WINDOW(dialog),accel_group); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ | |
+ label=gtk_label_new(_("Where to, dude ? ")); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ | |
+ /* Generate a square box of buttons for all locations */ | |
+ boxsize=1; | |
+ while (boxsize*boxsize < NumLocation) boxsize++; | |
+ | |
+ table=gtk_table_new(boxsize,boxsize,TRUE); | |
+ | |
+ for (i=0;i<NumLocation;i++) { | |
+ if (i<9) AccelChar='1'+i; | |
+ else if (i<35) AccelChar='A'+i-9; | |
+ else AccelChar='\0'; | |
+ | |
+ row=i/boxsize; col=i%boxsize; | |
+ if (AccelChar=='\0') { | |
+ button=gtk_button_new_with_label(Location[i].Name); | |
+ } else { | |
+ button=gtk_button_new_with_label(""); | |
+ name=g_strdup_printf("_%c. %s",AccelChar,Location[i].Name); | |
+ AccelKey=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child),name… | |
+ gtk_widget_add_accelerator(button,"clicked",accel_group,AccelKey,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
+ g_free(name); | |
+ } | |
+ gtk_widget_set_sensitive(button,i != ClientData.Play->IsAt); | |
+ gtk_object_set_data(GTK_OBJECT(button),"dialog",dialog); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(JetCallback),GINT_TO_POINTER(i)); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),button,col,col+1,row,row+1); | |
+ } | |
+ gtk_box_pack_start(GTK_BOX(vbox),table,TRUE,TRUE,0); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+struct DealDiaStruct { | |
+ GtkWidget *dialog,*cost,*carrying,*space,*afford,*amount; | |
+ gint DrugInd; | |
+ gpointer Type; | |
+}; | |
+static struct DealDiaStruct DealDialog; | |
+ | |
+static void UpdateDealDialog() { | |
+ GString *text; | |
+ gchar *prstr; | |
+ GtkAdjustment *spin_adj; | |
+ gint DrugInd,CanDrop,CanCarry,CanAfford,MaxDrug; | |
+ Player *Play; | |
+ | |
+ text=g_string_new(NULL); | |
+ DrugInd=DealDialog.DrugInd; | |
+ Play=ClientData.Play; | |
+ | |
+ prstr=FormatPrice(Play->Drugs[DrugInd].Price); | |
+ g_string_sprintf(text,_("at %s"),prstr); | |
+ g_free(prstr); | |
+ gtk_label_set_text(GTK_LABEL(DealDialog.cost),text->str); | |
+ | |
+ CanDrop=Play->Drugs[DrugInd].Carried; | |
+ g_string_sprintf(text,_("You are currently carrying %d %s"), | |
+ CanDrop,Drug[DrugInd].Name); | |
+ gtk_label_set_text(GTK_LABEL(DealDialog.carrying),text->str); | |
+ | |
+ CanCarry=Play->CoatSize; | |
+ g_string_sprintf(text,_("Available space: %d"),CanCarry); | |
+ gtk_label_set_text(GTK_LABEL(DealDialog.space),text->str); | |
+ | |
+ if (DealDialog.Type==BT_BUY) { | |
+ CanAfford=Play->Cash/Play->Drugs[DrugInd].Price; | |
+ g_string_sprintf(text,_("You can afford %d"),CanAfford); | |
+ gtk_label_set_text(GTK_LABEL(DealDialog.afford),text->str); | |
+ MaxDrug=MIN(CanCarry,CanAfford); | |
+ } else MaxDrug=CanDrop; | |
+ | |
+ spin_adj=(GtkAdjustment *)gtk_adjustment_new(MaxDrug,1.0,MaxDrug, | |
+ 1.0,10.0,10.0); | |
+ gtk_spin_button_set_adjustment(GTK_SPIN_BUTTON(DealDialog.amount),spin_adj); | |
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(DealDialog.amount),MaxDrug); | |
+ | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+static void DealSelectCallback(GtkWidget *widget,gpointer data) { | |
+ DealDialog.DrugInd=GPOINTER_TO_INT(data); | |
+ UpdateDealDialog(); | |
+} | |
+ | |
+static void DealOKCallback(GtkWidget *widget,gpointer data) { | |
+ GtkWidget *spinner; | |
+ gint amount; | |
+ gchar *text; | |
+ | |
+ spinner=DealDialog.amount; | |
+ | |
+ amount=gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner)); | |
+ | |
+ text=g_strdup_printf("drug^%d^%d",DealDialog.DrugInd, | |
+ data==BT_BUY ? amount : -amount); | |
+ SendClientMessage(ClientData.Play,C_NONE,C_BUYOBJECT,NULL, | |
+ text,ClientData.Play); | |
+ g_free(text); | |
+ | |
+ gtk_widget_destroy(DealDialog.dialog); | |
+} | |
+ | |
+void DealDrugs(GtkWidget *widget,gpointer data) { | |
+ GtkWidget *dialog,*label,*hbox,*hbbox,*button,*spinner,*menu, | |
+ *optionmenu,*menuitem,*vbox,*hsep; | |
+ GtkAdjustment *spin_adj; | |
+ GtkAccelGroup *accel_group; | |
+ GtkWidget *clist; | |
+ gchar *Action; | |
+ GString *text; | |
+ GList *selection; | |
+ gint row; | |
+ Player *Play; | |
+ gint DrugInd,i,SelIndex,FirstInd; | |
+ gboolean DrugIndOK; | |
+ | |
+ if (data==BT_BUY) Action=_("Buy"); | |
+ else if (data==BT_SELL) Action=_("Sell"); | |
+ else if (data==BT_DROP) Action=_("Drop"); | |
+ else { | |
+ g_warning("Bad DealDrug type"); return; | |
+ } | |
+ | |
+ DealDialog.Type=data; | |
+ Play=ClientData.Play; | |
+ | |
+ if (data==BT_BUY) clist=ClientData.Drug.HereList; | |
+ else clist=ClientData.Drug.CarriedList; | |
+ selection=GTK_CLIST(clist)->selection; | |
+ if (selection) { | |
+ row=GPOINTER_TO_INT(selection->data); | |
+ DrugInd=GPOINTER_TO_INT(gtk_clist_get_row_data(GTK_CLIST(clist),row)); | |
+ } else DrugInd=-1; | |
+ | |
+ DrugIndOK=FALSE; | |
+ FirstInd=-1; | |
+ for (i=0;i<NumDrug;i++) { | |
+ if ((data==BT_DROP && Play->Drugs[i].Carried>0 && | |
+ Play->Drugs[i].Price==0) || | |
+ (data==BT_SELL && Play->Drugs[i].Carried>0 && | |
+ Play->Drugs[i].Price!=0) || | |
+ (data==BT_BUY && Play->Drugs[i].Price!=0)) { | |
+ if (FirstInd==-1) FirstInd=i; | |
+ if (DrugInd==i) DrugIndOK=TRUE; | |
+ } | |
+ } | |
+ if (!DrugIndOK) { | |
+ if (FirstInd==-1) return; | |
+ else DrugInd=FirstInd; | |
+ } | |
+ | |
+ text=g_string_new(NULL); | |
+ accel_group=gtk_accel_group_new(); | |
+ dialog=DealDialog.dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_title(GTK_WINDOW(dialog),Action); | |
+ gtk_window_add_accel_group(GTK_WINDOW(dialog),accel_group); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog),7); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ | |
+ hbox=gtk_hbox_new(FALSE,7); | |
+ | |
+ label=gtk_label_new(Action); | |
+ gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0); | |
+ | |
+ optionmenu=gtk_option_menu_new(); | |
+ menu=gtk_menu_new(); | |
+ SelIndex=-1; | |
+ for (i=0;i<NumDrug;i++) { | |
+ if ((data==BT_DROP && Play->Drugs[i].Carried>0 && | |
+ Play->Drugs[i].Price==0) || | |
+ (data==BT_SELL && Play->Drugs[i].Carried>0 && | |
+ Play->Drugs[i].Price!=0) || | |
+ (data==BT_BUY && Play->Drugs[i].Price!=0)) { | |
+ menuitem=gtk_menu_item_new_with_label(Drug[i].Name); | |
+ gtk_signal_connect(GTK_OBJECT(menuitem),"activate", | |
+ GTK_SIGNAL_FUNC(DealSelectCallback), | |
+ GINT_TO_POINTER(i)); | |
+ gtk_menu_append(GTK_MENU(menu),menuitem); | |
+ if (DrugInd>=i) SelIndex++; | |
+ } | |
+ } | |
+ gtk_menu_set_active(GTK_MENU(menu),SelIndex); | |
+ gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu),menu); | |
+ gtk_box_pack_start(GTK_BOX(hbox),optionmenu,TRUE,TRUE,0); | |
+ | |
+ DealDialog.DrugInd=DrugInd; | |
+ | |
+ label=DealDialog.cost=gtk_label_new(NULL); | |
+ gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0); | |
+ | |
+ label=DealDialog.carrying=gtk_label_new(NULL); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ | |
+ label=DealDialog.space=gtk_label_new(NULL); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ | |
+ if (data==BT_BUY) { | |
+ label=DealDialog.afford=gtk_label_new(NULL); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ } | |
+ hbox=gtk_hbox_new(FALSE,7); | |
+ g_string_sprintf(text,_("%s how many?"),Action); | |
+ label=gtk_label_new(text->str); | |
+ gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0); | |
+ spin_adj=(GtkAdjustment *)gtk_adjustment_new(1.0,1.0,2.0,1.0,10.0,10.0); | |
+ spinner=DealDialog.amount=gtk_spin_button_new(spin_adj,1.0,0); | |
+ gtk_box_pack_start(GTK_BOX(hbox),spinner,FALSE,FALSE,0); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ hbbox=gtk_hbutton_box_new(); | |
+ button=gtk_button_new_with_label(_("OK")); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(DealOKCallback),data); | |
+ GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT); | |
+ gtk_widget_grab_default(button); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ button=gtk_button_new_with_label(_("Cancel")); | |
+ gtk_signal_connect_object(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)dialog); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbbox,FALSE,FALSE,0); | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ | |
+ g_string_free(text,TRUE); | |
+ UpdateDealDialog(); | |
+ | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+void DealGuns(GtkWidget *widget,gpointer data) { | |
+ GtkWidget *clist,*dialog; | |
+ GList *selection; | |
+ gint row,GunInd; | |
+ gchar *Action,*Title; | |
+ GString *text; | |
+ | |
+ dialog=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); | |
+ if (data==BT_BUY) Action=_("Buy"); | |
+ else if (data==BT_SELL) Action=_("Sell"); | |
+ else Action=_("Drop"); | |
+ | |
+ if (data==BT_BUY) clist=ClientData.Gun.HereList; | |
+ else clist=ClientData.Gun.CarriedList; | |
+ selection=GTK_CLIST(clist)->selection; | |
+ if (selection) { | |
+ row=GPOINTER_TO_INT(selection->data); | |
+ GunInd=GPOINTER_TO_INT(gtk_clist_get_row_data(GTK_CLIST(clist),row)); | |
+ } else return; | |
+ | |
+ Title=g_strdup_printf("%s %s",Action,Names.Guns); | |
+ text=g_string_new(""); | |
+ | |
+ if (data!=BT_BUY && TotalGunsCarried(ClientData.Play)==0) { | |
+ g_string_sprintf(text,_("You don't have any %s!"),Names.Guns); | |
+ MessageBox(dialog,Title,text->str,MB_OK); | |
+ } else if (data==BT_BUY && TotalGunsCarried(ClientData.Play) >= | |
+ ClientData.Play->Bitches.Carried+2) { | |
+ g_string_sprintf(text,_("You'll need more %s to carry any more %s!"), | |
+ Names.Bitches,Names.Guns); | |
+ MessageBox(dialog,Title,text->str,MB_OK); | |
+ } else if (data==BT_BUY && Gun[GunInd].Space > ClientData.Play->CoatSize) { | |
+ g_string_sprintf(text,_("You don't have enough space to carry that %s!"), | |
+ Names.Gun); | |
+ MessageBox(dialog,Title,text->str,MB_OK); | |
+ } else if (data==BT_BUY && Gun[GunInd].Price > ClientData.Play->Cash) { | |
+ g_string_sprintf(text,_("You don't have enough cash to buy that %s!"), | |
+ Names.Gun); | |
+ MessageBox(dialog,Title,text->str,MB_OK); | |
+ } else if (data==BT_SELL && ClientData.Play->Guns[GunInd].Carried == 0) { | |
+ MessageBox(dialog,Title,_("You don't have any to sell!"),MB_OK); | |
+ } else { | |
+ g_string_sprintf(text,"gun^%d^%d",GunInd,data==BT_BUY ? 1 : -1); | |
+ SendClientMessage(ClientData.Play,C_NONE,C_BUYOBJECT,NULL,text->str, | |
+ ClientData.Play); | |
+ } | |
+ g_free(Title); | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+static void QuestionCallback(GtkWidget *widget,gpointer data) { | |
+ gint Answer; | |
+ gchar text[5]; | |
+ GtkWidget *dialog; | |
+ Player *To; | |
+ | |
+ dialog = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),"dialog")); | |
+ To = (Player *)gtk_object_get_data(GTK_OBJECT(dialog),"From"); | |
+ Answer = GPOINTER_TO_INT(data); | |
+ | |
+ text[0]=(gchar)Answer; text[1]='\0'; | |
+ SendClientMessage(ClientData.Play,C_NONE,C_ANSWER,To,text,ClientData.Play); | |
+ | |
+ gtk_widget_destroy(dialog); | |
+} | |
+ | |
+void QuestionDialog(char *Data,Player *From) { | |
+ GtkWidget *dialog,*label,*vbox,*hsep,*hbbox,*button; | |
+ GtkAccelGroup *accel_group; | |
+ guint AccelKey; | |
+ gchar *Responses,**split,*LabelText; | |
+ gchar *Words[] = { N_("_Yes"), N_("_No"), N_("_Run"), | |
+ N_("_Fight"), N_("_Attack"), N_("_Evade") }; | |
+ gint numWords = sizeof(Words) / sizeof(Words[0]); | |
+ gint i,Answer; | |
+ | |
+ split=g_strsplit(Data,"^",1); | |
+ if (!split[0] || !split[1]) { | |
+ g_warning("Bad QUESTION message %s",Data); return; | |
+ } | |
+ | |
+ g_strdelimit(split[1],"^",'\n'); | |
+ | |
+ Responses=split[0]; LabelText=split[1]; | |
+ | |
+ dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ accel_group=gtk_accel_group_new(); | |
+ gtk_signal_connect(GTK_OBJECT(dialog),"delete_event", | |
+ GTK_SIGNAL_FUNC(DisallowDelete),NULL); | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"From",(gpointer)From); | |
+ gtk_window_set_title(GTK_WINDOW(dialog),_("Question")); | |
+ gtk_window_add_accel_group(GTK_WINDOW(dialog),accel_group); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog),7); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ while (*LabelText=='\n') LabelText++; | |
+ label=gtk_label_new(LabelText); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ hbbox=gtk_hbutton_box_new(); | |
+ | |
+ for (i=0;i<numWords;i++) { | |
+ Answer=(gint)Words[i][0]; | |
+ if (Answer=='_' && strlen(Words[i])>=2) Answer=(gint)Words[i][1]; | |
+ if (strchr(Responses,Answer)) { | |
+ button=gtk_button_new_with_label(""); | |
+ AccelKey=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child), | |
+ _(Words[i])); | |
+ gtk_widget_add_accelerator(button,"clicked",accel_group,AccelKey,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
+ gtk_object_set_data(GTK_OBJECT(button),"dialog",(gpointer)dialog); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(QuestionCallback), | |
+ GINT_TO_POINTER(Answer)); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ } | |
+ } | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbbox,TRUE,TRUE,0); | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ gtk_widget_show_all(dialog); | |
+ | |
+ g_strfreev(split); | |
+} | |
+ | |
+void StartGame() { | |
+ Player *Play; | |
+ Play=ClientData.Play=g_new(Player,1); | |
+ FirstClient=AddPlayer(0,Play,FirstClient); | |
+ Play->fd=ClientSock; | |
+ SetPlayerName(Play,ClientData.PlayerName); | |
+ SendClientMessage(NULL,C_NONE,C_NAME,NULL,ClientData.PlayerName,Play); | |
+ InGame=TRUE; | |
+ UpdateMenus(); | |
+ if (Network) { | |
+ SetSocketWriteTest(Play,TRUE); | |
+ } | |
+ gtk_widget_show_all(ClientData.vbox); | |
+ UpdatePlayerLists(); | |
+} | |
+ | |
+void EndGame() { | |
+ DisplayFightMessage(NULL); | |
+ gtk_widget_hide_all(ClientData.vbox); | |
+ gtk_editable_delete_text(GTK_EDITABLE(ClientData.messages),0,-1); | |
+ g_free(ClientData.PlayerName); | |
+ ClientData.PlayerName=g_strdup(GetPlayerName(ClientData.Play)); | |
+ if (Network) gdk_input_remove(ClientData.GdkInputTag); | |
+ ShutdownNetwork(); | |
+ UpdatePlayerLists(); | |
+ CleanUpServer(); | |
+ InGame=FALSE; | |
+ UpdateMenus(); | |
+} | |
+ | |
+static void ChangeDrugSort(GtkCList *clist,gint column,gpointer user_data) { | |
+ if (column==0) { | |
+ DrugSortMethod=(DrugSortMethod==DS_ATOZ ? DS_ZTOA : DS_ATOZ); | |
+ } else { | |
+ DrugSortMethod=(DrugSortMethod==DS_CHEAPFIRST ? DS_CHEAPLAST : | |
+ DS_CHEAPFIRST); | |
+ } | |
+ gtk_clist_sort(clist); | |
+} | |
+ | |
+static gint DrugSortFunc(GtkCList *clist,gconstpointer ptr1, | |
+ gconstpointer ptr2) { | |
+ int index1,index2; | |
+ price_t pricediff; | |
+ | |
+ index1=GPOINTER_TO_INT(((GtkCListRow *)ptr1)->data); | |
+ index2=GPOINTER_TO_INT(((GtkCListRow *)ptr2)->data); | |
+ if (index1<0 || index1>=NumDrug || index2<0 || index2>=NumDrug) return 0; | |
+ | |
+ switch(DrugSortMethod) { | |
+ case DS_ATOZ: | |
+ return strcasecmp(Drug[index1].Name,Drug[index2].Name); | |
+ case DS_ZTOA: | |
+ return strcasecmp(Drug[index2].Name,Drug[index1].Name); | |
+ case DS_CHEAPFIRST: | |
+ pricediff=ClientData.Play->Drugs[index1].Price- | |
+ ClientData.Play->Drugs[index2].Price; | |
+ return pricediff==0 ? 0 : pricediff<0 ? -1 : 1; | |
+ case DS_CHEAPLAST: | |
+ pricediff=ClientData.Play->Drugs[index2].Price- | |
+ ClientData.Play->Drugs[index1].Price; | |
+ return pricediff==0 ? 0 : pricediff<0 ? -1 : 1; | |
+ } | |
+ return 0; | |
+} | |
+ | |
+void UpdateMenus() { | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget(ClientData.Menu, | |
+ _("<main>/Talk")),InGame); | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget(ClientData.Menu, | |
+ _("<main>/List")),InGame); | |
+ gtk_widget_set_sensitive(gtk_item_factory_get_widget(ClientData.Menu, | |
+ _("<main>/Errands")),InGame… | |
+} | |
+ | |
+GtkWidget *CreateStatusWidgets(struct StatusWidgets *Status) { | |
+ GtkWidget *table,*label; | |
+ | |
+ table = gtk_table_new(3,6,FALSE); | |
+ gtk_table_set_row_spacings(GTK_TABLE(table),3); | |
+ gtk_table_set_col_spacings(GTK_TABLE(table),3); | |
+ | |
+ label=Status->Location = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,0,2,0,1); | |
+ | |
+ label=Status->Date = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,2,4,0,1); | |
+ | |
+ label=Status->SpaceName = gtk_label_new(_("Space")); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,4,5,0,1); | |
+ label=Status->SpaceValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,5,6,0,1); | |
+ | |
+ label=Status->CashName = gtk_label_new(_("Cash")); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,1,2); | |
+ label=Status->CashValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,1,2,1,2); | |
+ | |
+ label=Status->DebtName = gtk_label_new(_("Debt")); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,2,3,1,2); | |
+ label=Status->DebtValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,3,4,1,2); | |
+ | |
+ label=Status->BankName = gtk_label_new(_("Bank")); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,4,5,1,2); | |
+ label=Status->BankValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,5,6,1,2); | |
+ | |
+ label=Status->GunsName = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,2,3); | |
+ label=Status->GunsValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,1,2,2,3); | |
+ | |
+ label=Status->BitchesName = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,2,3,2,3); | |
+ label=Status->BitchesValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,3,4,2,3); | |
+ | |
+ label=Status->HealthName = gtk_label_new(_("Health")); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,4,5,2,3); | |
+ label=Status->HealthValue = gtk_label_new(NULL); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,5,6,2,3); | |
+ return table; | |
+} | |
+ | |
+void SetJetButtonTitle(GtkAccelGroup *accel_group) { | |
+ GtkWidget *button; | |
+ guint accel_key; | |
+ | |
+ button=ClientData.JetButton; | |
+ accel_key=ClientData.JetAccel; | |
+ | |
+ if (accel_key) { | |
+ gtk_widget_remove_accelerator(button,accel_group,accel_key,0); | |
+ } | |
+ | |
+ accel_key=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child), | |
+ (ClientData.Play && ClientData.Play->Flags & FIGHTING) ? | |
+ _("_Fight") : _("_Jet!")); | |
+ gtk_widget_add_accelerator(button,"clicked",accel_group,accel_key,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
+ ClientData.JetAccel=accel_key; | |
+} | |
+ | |
+char GtkLoop(int *argc,char **argv[],char ReturnOnFail) { | |
+ GtkWidget *window,*vbox,*vbox2,*hbox,*frame,*table,*menubar,*text, | |
+ *vpaned,*button,*vscroll,*clist; | |
+ GtkAccelGroup *accel_group; | |
+ GtkItemFactory *item_factory; | |
+ GtkAdjustment *adj; | |
+ gchar *buf; | |
+ int i; | |
+ gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]); | |
+ | |
+ if (ReturnOnFail && !gtk_init_check(argc,argv)) return FALSE; | |
+ else if (!ReturnOnFail) gtk_init(argc,argv); | |
+ | |
+/* Set up message handlers */ | |
+ ClientMessageHandlerPt = HandleClientMessage; | |
+ ClientData.GdkInputTag=0; | |
+ SocketWriteTestPt = SetSocketWriteTest; | |
+ | |
+/* Have the GLib log messages pop up in a nice dialog box */ | |
+ g_log_set_handler(NULL,G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING, | |
+ LogMessage,NULL); | |
+ | |
+ ClientData.PlayerName=NULL; | |
+ ClientData.Play=NULL; | |
+ window=ClientData.window=gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
+ gtk_window_set_title(GTK_WINDOW(window),_("dopewars")); | |
+ gtk_window_set_default_size(GTK_WINDOW(window),450,390); | |
+ gtk_signal_connect(GTK_OBJECT(window),"destroy", | |
+ GTK_SIGNAL_FUNC(DestroyGtk),NULL); | |
+ | |
+ accel_group = gtk_accel_group_new(); | |
+ gtk_object_set_data(GTK_OBJECT(window),"accel_group",accel_group); | |
+ item_factory = ClientData.Menu = gtk_item_factory_new(GTK_TYPE_MENU_BAR, | |
+ "<main>",accel_group); | |
+ /* Translate the paths of the menu items, in place */ | |
+ for (i=0;i<nmenu_items;i++) { | |
+ menu_items[i].path=_(menu_items[i].path); | |
+ } | |
+ | |
+ gtk_item_factory_create_items(item_factory,nmenu_items,menu_items,NULL); | |
+ gtk_window_add_accel_group(GTK_WINDOW(window),accel_group); | |
+ menubar = gtk_item_factory_get_widget(item_factory,"<main>"); | |
+ | |
+ vbox2=gtk_vbox_new(FALSE,0); | |
+ gtk_box_pack_start(GTK_BOX(vbox2),menubar,FALSE,FALSE,0); | |
+ gtk_widget_show_all(menubar); | |
+ UpdateMenus(); | |
+ | |
+ vbox=ClientData.vbox=gtk_vbox_new(FALSE,5); | |
+ frame=gtk_frame_new(_("Stats")); | |
+ | |
+ table = CreateStatusWidgets(&ClientData.Status); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(frame),table); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),frame,FALSE,FALSE,0); | |
+ | |
+ vpaned=gtk_vpaned_new(); | |
+ | |
+ hbox=gtk_hbox_new(FALSE,0); | |
+ adj=(GtkAdjustment *)gtk_adjustment_new(0.0,0.0,100.0,1.0,10.0,10.0); | |
+ text=ClientData.messages=gtk_text_new(NULL,adj); | |
+ gtk_widget_set_usize(text,100,80); | |
+ gtk_text_set_point(GTK_TEXT(text),0); | |
+ gtk_text_set_editable(GTK_TEXT(text),FALSE); | |
+ gtk_text_set_word_wrap(GTK_TEXT(text),TRUE); | |
+ gtk_box_pack_start(GTK_BOX(hbox),text,TRUE,TRUE,0); | |
+ vscroll=gtk_vscrollbar_new(adj); | |
+ gtk_box_pack_start(GTK_BOX(hbox),vscroll,FALSE,FALSE,0); | |
+ gtk_paned_pack1(GTK_PANED(vpaned),hbox,TRUE,TRUE); | |
+ | |
+ hbox=gtk_hbox_new(FALSE,7); | |
+ buf=InitialCaps(Names.Drugs); | |
+ CreateInventory(hbox,buf,accel_group,TRUE,TRUE,&ClientData.Drug, | |
+ DealDrugs); g_free(buf); | |
+ clist=ClientData.Drug.HereList; | |
+ gtk_clist_column_titles_active(GTK_CLIST(clist)); | |
+ gtk_clist_set_compare_func(GTK_CLIST(clist),DrugSortFunc); | |
+ gtk_signal_connect(GTK_OBJECT(clist),"click-column", | |
+ GTK_SIGNAL_FUNC(ChangeDrugSort),NULL); | |
+ | |
+ button=ClientData.JetButton=gtk_button_new_with_label(""); | |
+ ClientData.JetAccel=0; | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(JetButtonPressed),NULL); | |
+ gtk_box_pack_start(GTK_BOX(ClientData.Drug.vbbox),button,TRUE,TRUE,0); | |
+ SetJetButtonTitle(accel_group); | |
+ | |
+ gtk_paned_pack2(GTK_PANED(vpaned),hbox,TRUE,TRUE); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),vpaned,TRUE,TRUE,0); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox2),vbox,TRUE,TRUE,0); | |
+ gtk_container_add(GTK_CONTAINER(window),vbox2); | |
+ | |
+/* Just show the window, not the vbox - we'll do that when the game starts */ | |
+ gtk_widget_show(vbox2); | |
+ gtk_widget_show(window); | |
+ | |
+ gtk_main(); | |
+ return TRUE; | |
+} | |
+ | |
+void display_intro(GtkWidget *widget,gpointer data) { | |
+ GtkWidget *dialog,*label,*table,*OKButton,*vbox,*hsep; | |
+ gchar *VersionStr; | |
+ const int rows=5,cols=3; | |
+ int i,j; | |
+ gchar *table_data[5][3] = { | |
+ { N_("Drug Dealing and Research"), "Dan Wolf", NULL }, | |
+ { N_("Play Testing"), "Phil Davis", "Owen Walsh" }, | |
+ { N_("Extensive Play Testing"), "Katherine Holt", | |
+ "Caroline Moore" }, | |
+ { N_("Constructive Criticism"), "Andrea Elliot-Smith", | |
+ "Pete Winn" }, | |
+ { N_("Unconstructive Criticism"), "James Matthews", NULL } | |
+ }; | |
+ | |
+ dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_title(GTK_WINDOW(dialog),_("About dopewars")); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ gtk_container_border_width(GTK_CONTAINER(dialog),10); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,5); | |
+ | |
+ label=gtk_label_new( | |
+_("Based on John E. Dell's old Drug Wars game, dopewars is a simulation of an\… | |
+"imaginary drug market. dopewars is an All-American game which features\n" | |
+"buying, selling, and trying to get past the cops!\n\n" | |
+"The first thing you need to do is pay off your debt to the Loan Shark. After\… | |
+"that, your goal is to make as much money as possible (and stay alive)! You\n" | |
+"have one month of game time to make your fortune.\n")); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ | |
+ VersionStr=g_strdup_printf(_("Version %s " | |
+"Copyright (C) 1998-2000 Ben Webb [email protected]\n" | |
+"dopewars is released under the GNU General Public Licence\n"),VERSION); | |
+ label=gtk_label_new(VersionStr); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ g_free(VersionStr); | |
+ | |
+ table = gtk_table_new(rows,cols,FALSE); | |
+ gtk_table_set_row_spacings(GTK_TABLE(table),3); | |
+ gtk_table_set_col_spacings(GTK_TABLE(table),3); | |
+ for (i=0;i<rows;i++) for (j=0;j<cols;j++) if (table_data[i][j]) { | |
+ if (j==0) label=gtk_label_new(_(table_data[i][j])); | |
+ else label=gtk_label_new(table_data[i][j]); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,j,j+1,i,i+1); | |
+ } | |
+ gtk_box_pack_start(GTK_BOX(vbox),table,FALSE,FALSE,0); | |
+ | |
+ label=gtk_label_new( | |
+_("\nFor information on the command line options, type dopewars -h at your\n" | |
+"Unix prompt. This will display a help screen, listing the available" | |
+"options.")); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ OKButton=gtk_button_new_with_label(_("OK")); | |
+ gtk_signal_connect_object(GTK_OBJECT(OKButton),"clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)dialog); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),OKButton,FALSE,FALSE,0); | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ | |
+ GTK_WIDGET_SET_FLAGS(OKButton,GTK_CAN_DEFAULT); | |
+ gtk_widget_grab_default(OKButton); | |
+ | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+struct StartGameStruct { | |
+ GtkWidget *dialog,*name,*hostname,*port,*antique,*status,*metaserv; | |
+}; | |
+ | |
+static void ConnectToServer(GtkWidget *widget,struct StartGameStruct *widgets)… | |
+ gchar *text,*NetworkError; | |
+ g_free(ServerName); | |
+ ServerName=gtk_editable_get_chars(GTK_EDITABLE(widgets->hostname),0,-1); | |
+ text=gtk_editable_get_chars(GTK_EDITABLE(widgets->port),0,-1); | |
+ Port=atoi(text); | |
+ g_free(text); | |
+ g_free(ClientData.PlayerName); | |
+ ClientData.PlayerName=gtk_editable_get_chars(GTK_EDITABLE(widgets->name), | |
+ 0,-1); | |
+ if (!ClientData.PlayerName || !ClientData.PlayerName[0]) return; | |
+ gtk_label_set_text(GTK_LABEL(widgets->status), | |
+ _("Status: Attempting to contact server...")); | |
+ NetworkError=SetupNetwork(); | |
+ if (!NetworkError) { | |
+ gtk_widget_destroy(widgets->dialog); | |
+ StartGame(); | |
+ } else { | |
+ text=g_strdup_printf(_("Status: Could not connect (%s)"),NetworkError); | |
+ gtk_label_set_text(GTK_LABEL(widgets->status),text); | |
+ g_free(text); | |
+ } | |
+} | |
+ | |
+static void StartSinglePlayer(GtkWidget *widget, | |
+ struct StartGameStruct *widgets) { | |
+ WantAntique= | |
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widgets->antique)); | |
+ g_free(ClientData.PlayerName); | |
+ ClientData.PlayerName=gtk_editable_get_chars(GTK_EDITABLE(widgets->name), | |
+ 0,-1); | |
+ StartGame(); | |
+ gtk_widget_destroy(widgets->dialog); | |
+} | |
+ | |
+static void FillMetaServerList(struct StartGameStruct *widgets) { | |
+ GtkWidget *metaserv; | |
+ ServerData *ThisServer; | |
+ gchar *titles[5]; | |
+ GSList *ListPt; | |
+ gint row; | |
+ | |
+ metaserv=widgets->metaserv; | |
+ gtk_clist_freeze(GTK_CLIST(metaserv)); | |
+ gtk_clist_clear(GTK_CLIST(metaserv)); | |
+ | |
+ | |
+ for (ListPt=ServerList;ListPt;ListPt=g_slist_next(ListPt)) { | |
+ ThisServer=(ServerData *)(ListPt->data); | |
+ titles[0]=ThisServer->Name; | |
+ titles[1]=g_strdup_printf("%d",ThisServer->Port); | |
+ titles[2]=ThisServer->Version; | |
+ titles[3]=g_strdup_printf(_("%d of %d"),ThisServer->CurPlayers, | |
+ ThisServer->MaxPlayers); | |
+ titles[4]=ThisServer->Comment; | |
+ row=gtk_clist_append(GTK_CLIST(metaserv),titles); | |
+ gtk_clist_set_row_data(GTK_CLIST(metaserv),row,(gpointer)ThisServer); | |
+ g_free(titles[1]); g_free(titles[3]); | |
+ } | |
+ gtk_clist_thaw(GTK_CLIST(metaserv)); | |
+} | |
+ | |
+static void UpdateMetaServerList(GtkWidget *widget, | |
+ struct StartGameStruct *widgets) { | |
+ char *MetaError; | |
+ int HttpSock; | |
+ MetaError=OpenMetaServerConnection(&HttpSock); | |
+ | |
+ if (MetaError) { | |
+ return; | |
+ } | |
+ ReadMetaServerData(HttpSock); | |
+ CloseMetaServerConnection(HttpSock); | |
+ MetaServerRead=TRUE; | |
+ FillMetaServerList(widgets); | |
+} | |
+ | |
+static void MetaServerConnect(GtkWidget *widget, | |
+ struct StartGameStruct *widgets) { | |
+ GList *selection; | |
+ gint row; | |
+ GtkWidget *clist; | |
+ ServerData *ThisServer; | |
+ gchar *text,*NetworkError; | |
+ | |
+ clist=widgets->metaserv; | |
+ selection=GTK_CLIST(clist)->selection; | |
+ if (selection) { | |
+ row=GPOINTER_TO_INT(selection->data); | |
+ ThisServer=(ServerData *)gtk_clist_get_row_data(GTK_CLIST(clist),row); | |
+ AssignName(&ServerName,ThisServer->Name); | |
+ Port=ThisServer->Port; | |
+ g_free(ClientData.PlayerName); | |
+ ClientData.PlayerName=gtk_editable_get_chars(GTK_EDITABLE(widgets->name), | |
+ 0,-1); | |
+ if (!ClientData.PlayerName || !ClientData.PlayerName[0]) return; | |
+ gtk_label_set_text(GTK_LABEL(widgets->status), | |
+ _("Status: Attempting to contact server...")); | |
+ NetworkError=SetupNetwork(); | |
+ if (!NetworkError) { | |
+ gtk_widget_destroy(widgets->dialog); | |
+ StartGame(); | |
+ } else { | |
+ text=g_strdup_printf(_("Status: Could not connect (%s)"),NetworkError… | |
+ gtk_label_set_text(GTK_LABEL(widgets->status),text); | |
+ g_free(text); | |
+ } | |
+ } | |
+} | |
+ | |
+void NewGameDialog() { | |
+ GtkWidget *vbox,*vbox2,*hbox,*label,*entry,*notebook,*frame,*button; | |
+ GtkWidget *table,*clist,*scrollwin,*dialog,*hbbox; | |
+ GtkAccelGroup *accel_group; | |
+ guint AccelKey; | |
+ gchar *text; | |
+ gchar *server_titles[5]; | |
+ static struct StartGameStruct widgets; | |
+ | |
+ server_titles[0]=_("Server"); | |
+ server_titles[1]=_("Port"); | |
+ server_titles[2]=_("Version"); | |
+ server_titles[3]=_("Players"); | |
+ server_titles[4]=_("Comment"); | |
+ | |
+ widgets.dialog=dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ accel_group=gtk_accel_group_new(); | |
+ | |
+ gtk_window_set_title(GTK_WINDOW(widgets.dialog),_("New Game")); | |
+ gtk_container_set_border_width(GTK_CONTAINER(widgets.dialog),7); | |
+ gtk_window_add_accel_group(GTK_WINDOW(widgets.dialog),accel_group); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ hbox=gtk_hbox_new(FALSE,7); | |
+ | |
+ label=gtk_label_new(""); | |
+ AccelKey=gtk_label_parse_uline(GTK_LABEL(label), | |
+ _("Hey dude, what's your _name?")); | |
+ gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0); | |
+ | |
+ entry=widgets.name=gtk_entry_new(); | |
+ gtk_widget_add_accelerator(entry,"grab-focus",accel_group,AccelKey,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
+ if (ClientData.PlayerName) { | |
+ gtk_entry_set_text(GTK_ENTRY(entry),ClientData.PlayerName); | |
+ } | |
+ gtk_box_pack_start(GTK_BOX(hbox),entry,TRUE,TRUE,0); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbox,FALSE,FALSE,0); | |
+ | |
+ notebook=gtk_notebook_new(); | |
+ | |
+ frame=gtk_frame_new(_("Server")); | |
+ gtk_container_set_border_width(GTK_CONTAINER(frame),4); | |
+ vbox2=gtk_vbox_new(FALSE,7); | |
+ gtk_container_set_border_width(GTK_CONTAINER(vbox2),4); | |
+ table=gtk_table_new(2,2,FALSE); | |
+ gtk_table_set_row_spacings(GTK_TABLE(table),4); | |
+ gtk_table_set_col_spacings(GTK_TABLE(table),4); | |
+ label=gtk_label_new(_("Host name")); | |
+ gtk_table_attach(GTK_TABLE(table),label,0,1,0,1, | |
+ GTK_SHRINK,GTK_SHRINK,0,0); | |
+ entry=widgets.hostname=gtk_entry_new(); | |
+ gtk_entry_set_text(GTK_ENTRY(entry),ServerName); | |
+ gtk_table_attach(GTK_TABLE(table),entry,1,2,0,1, | |
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, | |
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL,0,0); | |
+ label=gtk_label_new(_("Port")); | |
+ gtk_table_attach(GTK_TABLE(table),label,0,1,1,2, | |
+ GTK_SHRINK,GTK_SHRINK,0,0); | |
+ entry=widgets.port=gtk_entry_new(); | |
+ text=g_strdup_printf("%d",Port); | |
+ gtk_entry_set_text(GTK_ENTRY(entry),text); | |
+ g_free(text); | |
+ gtk_table_attach(GTK_TABLE(table),entry,1,2,1,2, | |
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL, | |
+ GTK_EXPAND|GTK_SHRINK|GTK_FILL,0,0); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox2),table,FALSE,FALSE,0); | |
+ | |
+ button=gtk_button_new_with_label(""); | |
+ AccelKey=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child), | |
+ _("_Connect")); | |
+ gtk_widget_add_accelerator(button,"clicked",accel_group,AccelKey,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(ConnectToServer), | |
+ (gpointer)&widgets); | |
+ gtk_box_pack_start(GTK_BOX(vbox2),button,FALSE,FALSE,0); | |
+ gtk_container_add(GTK_CONTAINER(frame),vbox2); | |
+ GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT); | |
+ gtk_widget_grab_default(button); | |
+ | |
+ label=gtk_label_new(_("Server")); | |
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),frame,label); | |
+ frame=gtk_frame_new(_("Single player")); | |
+ gtk_container_set_border_width(GTK_CONTAINER(frame),4); | |
+ vbox2=gtk_vbox_new(FALSE,7); | |
+ gtk_container_set_border_width(GTK_CONTAINER(vbox2),4); | |
+ widgets.antique=gtk_check_button_new_with_label(""); | |
+ AccelKey=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(widgets.antique)->child), | |
+ _("_Antique mode")); | |
+ gtk_widget_add_accelerator(widgets.antique,"clicked",accel_group,AccelKey,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widgets.antique),WantAntique… | |
+ gtk_box_pack_start(GTK_BOX(vbox2),widgets.antique,FALSE,FALSE,0); | |
+ button=gtk_button_new_with_label(""); | |
+ AccelKey=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child), | |
+ _("_Start single-player game")); | |
+ gtk_widget_add_accelerator(button,"clicked",accel_group,AccelKey,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(StartSinglePlayer), | |
+ (gpointer)&widgets); | |
+ gtk_box_pack_start(GTK_BOX(vbox2),button,FALSE,FALSE,0); | |
+ gtk_container_add(GTK_CONTAINER(frame),vbox2); | |
+ label=gtk_label_new(_("Single player")); | |
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),frame,label); | |
+ frame=gtk_frame_new(_("Metaserver")); | |
+ gtk_container_set_border_width(GTK_CONTAINER(frame),4); | |
+ | |
+ vbox2=gtk_vbox_new(FALSE,7); | |
+ gtk_container_set_border_width(GTK_CONTAINER(vbox2),4); | |
+ scrollwin=gtk_scrolled_window_new(NULL,NULL); | |
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), | |
+ GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC); | |
+ clist=widgets.metaserv=gtk_clist_new_with_titles(5,server_titles); | |
+ gtk_clist_column_titles_passive(GTK_CLIST(clist)); | |
+ gtk_clist_set_selection_mode(GTK_CLIST(clist),GTK_SELECTION_SINGLE); | |
+ gtk_container_add(GTK_CONTAINER(scrollwin),clist); | |
+ gtk_box_pack_start(GTK_BOX(vbox2),scrollwin,TRUE,TRUE,0); | |
+ | |
+ hbbox=gtk_hbutton_box_new(); | |
+ button=gtk_button_new_with_label(""); | |
+ AccelKey=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child), | |
+ _("_Update")); | |
+ gtk_widget_add_accelerator(button,"clicked",accel_group,AccelKey,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(UpdateMetaServerList), | |
+ (gpointer)&widgets); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ | |
+ button=gtk_button_new_with_label(""); | |
+ AccelKey=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child), | |
+ _("_Connect")); | |
+ gtk_widget_add_accelerator(button,"clicked",accel_group,AccelKey,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(MetaServerConnect), | |
+ (gpointer)&widgets); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox2),hbbox,FALSE,FALSE,0); | |
+ gtk_container_add(GTK_CONTAINER(frame),vbox2); | |
+ | |
+ label=gtk_label_new(_("Metaserver")); | |
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),frame,label); | |
+ gtk_box_pack_start(GTK_BOX(vbox),notebook,TRUE,TRUE,0); | |
+ | |
+ label=widgets.status=gtk_label_new(_("Status: Waiting for user input")); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(widgets.dialog),vbox); | |
+ | |
+ gtk_widget_grab_focus(widgets.name); | |
+ FillMetaServerList(&widgets); | |
+ | |
+ gtk_widget_show_all(widgets.dialog); | |
+} | |
+ | |
+static void DestroyMessageBox(GtkWidget *widget,gpointer data) { | |
+ gtk_main_quit(); | |
+} | |
+ | |
+static void MessageBoxCallback(GtkWidget *widget,gpointer data) { | |
+ gint *retval; | |
+ GtkWidget *dialog; | |
+ dialog=gtk_widget_get_ancestor(widget,GTK_TYPE_WINDOW); | |
+ retval=(gint *)gtk_object_get_data(GTK_OBJECT(widget),"retval"); | |
+ if (retval) *retval=GPOINTER_TO_INT(data); | |
+ gtk_widget_destroy(dialog); | |
+} | |
+ | |
+gint MessageBox(GtkWidget *parent,const gchar *Title, | |
+ const gchar *Text,gint Options) { | |
+ GtkWidget *dialog,*button,*label,*vbox,*hbbox,*hsep; | |
+ GtkAccelGroup *accel_group; | |
+ gint i; | |
+ static gint retval; | |
+ guint AccelKey; | |
+ gchar *ButtonData[MB_MAX] = { N_("OK"), N_("Cancel"), | |
+ N_("_Yes"), N_("_No") }; | |
+ | |
+ dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ accel_group=gtk_accel_group_new(); | |
+ gtk_window_add_accel_group(GTK_WINDOW(dialog),accel_group); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog),7); | |
+ if (parent) gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(parent)); | |
+ gtk_signal_connect(GTK_OBJECT(dialog),"destroy", | |
+ GTK_SIGNAL_FUNC(DestroyMessageBox),NULL); | |
+ if (Title) gtk_window_set_title(GTK_WINDOW(dialog),Title); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ | |
+ if (Text) { | |
+ label=gtk_label_new(Text); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ } | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ retval=MB_CANCEL; | |
+ | |
+ hbbox=gtk_hbutton_box_new(); | |
+ for (i=0;i<MB_MAX;i++) { | |
+ if (Options & (1<<i)) { | |
+ button=gtk_button_new_with_label(""); | |
+ AccelKey=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button)->child), | |
+ _(ButtonData[i])); | |
+ if (AccelKey) gtk_widget_add_accelerator(button,"clicked", | |
+ accel_group,AccelKey,0, | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE… | |
+ gtk_object_set_data(GTK_OBJECT(button),"retval",&retval); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(MessageBoxCallback), | |
+ GINT_TO_POINTER(1<<i)); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ } | |
+ } | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbbox,TRUE,TRUE,0); | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ gtk_widget_show_all(dialog); | |
+ gtk_main(); | |
+ return retval; | |
+} | |
+ | |
+static void SendDoneMessage(GtkWidget *widget,gpointer data) { | |
+ SendClientMessage(ClientData.Play,C_NONE,C_DONE,NULL,NULL,ClientData.Play); | |
+} | |
+ | |
+static void TransferPayAll(GtkWidget *widget,GtkWidget *dialog) { | |
+ gchar *text; | |
+ text=pricetostr(ClientData.Play->Debt); | |
+ SendClientMessage(ClientData.Play,C_NONE,C_PAYLOAN,NULL, | |
+ text,ClientData.Play); | |
+ g_free(text); | |
+ gtk_widget_destroy(dialog); | |
+} | |
+ | |
+static void TransferOK(GtkWidget *widget,GtkWidget *dialog) { | |
+ gpointer Debt; | |
+ GtkWidget *deposit,*entry; | |
+ gchar *text; | |
+ price_t money; | |
+ | |
+ Debt=gtk_object_get_data(GTK_OBJECT(dialog),"debt"); | |
+ entry=GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog),"entry")); | |
+ text=gtk_editable_get_chars(GTK_EDITABLE(entry),0,-1); | |
+ money=strtoprice(text); | |
+ g_free(text); | |
+ | |
+ if (money<0) money=0; | |
+ if (Debt) { | |
+ if (money>ClientData.Play->Debt) money=ClientData.Play->Debt; | |
+ } else { | |
+ deposit=GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog),"deposit")); | |
+ if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(deposit))) { | |
+ money=-money; | |
+ } | |
+ if (-money>ClientData.Play->Bank) { | |
+ MessageBox(dialog,"Bank", | |
+ _("There isn't that much money in the bank..."), | |
+ MB_OK); | |
+ return; | |
+ } | |
+ } | |
+ if (money>ClientData.Play->Cash) { | |
+ MessageBox(dialog,Debt ? "Pay loan" : "Bank", | |
+ _("You don't have that much money!"),MB_OK); | |
+ return; | |
+ } | |
+ text=pricetostr(money); | |
+ SendClientMessage(ClientData.Play,C_NONE, | |
+ Debt ? C_PAYLOAN : C_DEPOSIT,NULL,text,ClientData.Play); | |
+ g_free(text); | |
+ gtk_widget_destroy(dialog); | |
+} | |
+ | |
+void TransferDialog(gboolean Debt) { | |
+ GtkWidget *dialog,*button,*label,*radio,*table,*vbox,*hbbox,*hsep,*entry; | |
+ gchar *text,*prstr; | |
+ GSList *group; | |
+ | |
+ dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_signal_connect(GTK_OBJECT(dialog),"destroy", | |
+ GTK_SIGNAL_FUNC(SendDoneMessage),NULL); | |
+ gtk_window_set_title(GTK_WINDOW(dialog),Debt ? Names.LoanSharkName : | |
+ Names.BankName); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog),7); | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ table=gtk_table_new(4,3,FALSE); | |
+ gtk_table_set_row_spacings(GTK_TABLE(table),4); | |
+ gtk_table_set_col_spacings(GTK_TABLE(table),4); | |
+ | |
+ prstr=FormatPrice(ClientData.Play->Cash); | |
+ text=g_strdup_printf(_("Cash: %s"),prstr); | |
+ label=gtk_label_new(text); | |
+ g_free(text); g_free(prstr); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,0,3,0,1); | |
+ | |
+ if (Debt) { | |
+ prstr=FormatPrice(ClientData.Play->Debt); | |
+ text=g_strdup_printf(_("Debt: %s"),prstr); | |
+ } else { | |
+ prstr=FormatPrice(ClientData.Play->Bank); | |
+ text=g_strdup_printf(_("Bank: %s"),prstr); | |
+ } | |
+ label=gtk_label_new(text); | |
+ g_free(text); g_free(prstr); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,0,3,1,2); | |
+ | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"debt",(gpointer)Debt); | |
+ if (Debt) { | |
+ label=gtk_label_new(_("Pay back:")); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,0,1,2,4); | |
+ } else { | |
+ radio=gtk_radio_button_new_with_label(NULL,_("Deposit")); | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"deposit",radio); | |
+ group=gtk_radio_button_group(GTK_RADIO_BUTTON(radio)); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),radio,0,1,2,3); | |
+ radio=gtk_radio_button_new_with_label(group,_("Withdraw")); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),radio,0,1,3,4); | |
+ } | |
+ label=gtk_label_new("$"); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),label,1,2,2,4); | |
+ entry=gtk_entry_new(); | |
+ gtk_entry_set_text(GTK_ENTRY(entry),"0"); | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"entry",entry); | |
+ gtk_signal_connect(GTK_OBJECT(entry),"activate", | |
+ GTK_SIGNAL_FUNC(TransferOK),dialog); | |
+ gtk_table_attach_defaults(GTK_TABLE(table),entry,2,3,2,4); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),table,TRUE,TRUE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ hbbox=gtk_hbutton_box_new(); | |
+ button=gtk_button_new_with_label(_("OK")); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(TransferOK),dialog); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ | |
+ if (Debt && ClientData.Play->Cash>=ClientData.Play->Debt) { | |
+ button=gtk_button_new_with_label(_("Pay all")); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(TransferPayAll),dialog); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ } | |
+ button=gtk_button_new_with_label(_("Cancel")); | |
+ gtk_signal_connect_object(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)dialog); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbbox,FALSE,FALSE,0); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+void ListPlayers(GtkWidget *widget,gpointer data) { | |
+ GtkWidget *dialog,*clist,*button,*vbox,*hsep; | |
+ | |
+ if (IsShowingPlayerList) return; | |
+ dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_title(GTK_WINDOW(dialog),_("Player List")); | |
+ gtk_window_set_default_size(GTK_WINDOW(dialog),200,180); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog),7); | |
+ | |
+ IsShowingPlayerList=TRUE; | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),FALSE); | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"IsShowing", | |
+ (gpointer)&IsShowingPlayerList); | |
+ gtk_signal_connect(GTK_OBJECT(dialog),"destroy", | |
+ GTK_SIGNAL_FUNC(DestroyShowing),NULL); | |
+ | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ | |
+ clist=ClientData.PlayerList=CreatePlayerList(); | |
+ UpdatePlayerList(clist,FALSE); | |
+ gtk_box_pack_start(GTK_BOX(vbox),clist,TRUE,TRUE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ button=gtk_button_new_with_label("OK"); | |
+ gtk_signal_connect_object(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)dialog); | |
+ gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0); | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+struct TalkStruct { | |
+ GtkWidget *dialog,*clist,*entry,*checkbutton; | |
+}; | |
+ | |
+static void TalkSend(GtkWidget *widget,struct TalkStruct *TalkData) { | |
+ gboolean AllPlayers; | |
+ gchar *text; | |
+ GString *msg; | |
+ GList *selection; | |
+ gint row; | |
+ Player *Play; | |
+ | |
+ AllPlayers= | |
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(TalkData->checkbutton)); | |
+ text=gtk_editable_get_chars(GTK_EDITABLE(TalkData->entry),0,-1); | |
+ gtk_editable_delete_text(GTK_EDITABLE(TalkData->entry),0,-1); | |
+ if (!text) return; | |
+ | |
+ msg=g_string_new(""); | |
+ | |
+ if (AllPlayers) { | |
+ SendClientMessage(ClientData.Play,C_NONE,C_MSG,NULL,text,ClientData.Play… | |
+ g_string_sprintf(msg,"%s: %s",GetPlayerName(ClientData.Play),text); | |
+ PrintMessage(msg->str); | |
+ } else { | |
+ for(selection=GTK_CLIST(TalkData->clist)->selection;selection; | |
+ selection=g_list_next(selection)) { | |
+ row=GPOINTER_TO_INT(selection->data); | |
+ Play=(Player *)gtk_clist_get_row_data(GTK_CLIST(TalkData->clist),row); | |
+ if (Play) { | |
+ SendClientMessage(ClientData.Play,C_NONE,C_MSGTO,Play, | |
+ text,ClientData.Play); | |
+ g_string_sprintf(msg,"%s->%s: %s",GetPlayerName(ClientData.Play), | |
+ GetPlayerName(Play),text); | |
+ PrintMessage(msg->str); | |
+ } | |
+ } | |
+ } | |
+ g_free(text); | |
+ g_string_free(msg,TRUE); | |
+} | |
+ | |
+void TalkToAll(GtkWidget *widget,gpointer data) { | |
+ TalkDialog(TRUE); | |
+} | |
+ | |
+void TalkToPlayers(GtkWidget *widget,gpointer data) { | |
+ TalkDialog(FALSE); | |
+} | |
+ | |
+void TalkDialog(gboolean TalkToAll) { | |
+ GtkWidget *dialog,*clist,*button,*entry,*label,*vbox,*hsep, | |
+ *checkbutton,*hbbox; | |
+ static struct TalkStruct TalkData; | |
+ | |
+ if (IsShowingTalkList) return; | |
+ dialog=TalkData.dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_title(GTK_WINDOW(dialog),_("Talk to player(s)")); | |
+ gtk_window_set_default_size(GTK_WINDOW(dialog),200,190); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog),7); | |
+ | |
+ IsShowingTalkList=TRUE; | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),FALSE); | |
+ gtk_object_set_data(GTK_OBJECT(dialog),"IsShowing", | |
+ (gpointer)&IsShowingTalkList); | |
+ gtk_signal_connect(GTK_OBJECT(dialog),"destroy", | |
+ GTK_SIGNAL_FUNC(DestroyShowing),NULL); | |
+ | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ | |
+ clist=TalkData.clist=ClientData.TalkList=CreatePlayerList(); | |
+ UpdatePlayerList(clist,FALSE); | |
+ gtk_clist_set_selection_mode(GTK_CLIST(clist),GTK_SELECTION_MULTIPLE); | |
+ gtk_box_pack_start(GTK_BOX(vbox),clist,TRUE,TRUE,0); | |
+ | |
+ checkbutton=TalkData.checkbutton= | |
+ gtk_check_button_new_with_label(_("Talk to all players")); | |
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbutton),TalkToAll); | |
+ gtk_box_pack_start(GTK_BOX(vbox),checkbutton,FALSE,FALSE,0); | |
+ | |
+ label=gtk_label_new(_("Message:-")); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ | |
+ entry=TalkData.entry=gtk_entry_new(); | |
+ gtk_signal_connect(GTK_OBJECT(entry),"activate", | |
+ GTK_SIGNAL_FUNC(TalkSend), | |
+ (gpointer)&TalkData); | |
+ gtk_box_pack_start(GTK_BOX(vbox),entry,FALSE,FALSE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ hbbox=gtk_hbutton_box_new(); | |
+ button=gtk_button_new_with_label(_("Send")); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(TalkSend), | |
+ (gpointer)&TalkData); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ | |
+ button=gtk_button_new_with_label(_("Close")); | |
+ gtk_signal_connect_object(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)dialog); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbbox,FALSE,FALSE,0); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+GtkWidget *CreatePlayerList() { | |
+ GtkWidget *clist; | |
+ gchar *text[1]; | |
+ | |
+ text[0]="Name"; | |
+ clist=gtk_clist_new_with_titles(1,text); | |
+ gtk_clist_column_titles_passive(GTK_CLIST(clist)); | |
+ gtk_clist_set_column_auto_resize(GTK_CLIST(clist),0,TRUE); | |
+ return clist; | |
+} | |
+ | |
+void UpdatePlayerList(GtkWidget *clist,gboolean IncludeSelf) { | |
+ GSList *list; | |
+ gchar *text[1]; | |
+ gint row; | |
+ Player *Play; | |
+ gtk_clist_freeze(GTK_CLIST(clist)); | |
+ gtk_clist_clear(GTK_CLIST(clist)); | |
+ for (list=FirstClient;list;list=g_slist_next(list)) { | |
+ Play=(Player *)list->data; | |
+ if (IncludeSelf || Play!=ClientData.Play) { | |
+ text[0]=GetPlayerName(Play); | |
+ row=gtk_clist_append(GTK_CLIST(clist),text); | |
+ gtk_clist_set_row_data(GTK_CLIST(clist),row,Play); | |
+ } | |
+ } | |
+ gtk_clist_thaw(GTK_CLIST(clist)); | |
+} | |
+ | |
+static void ErrandOK(GtkWidget *widget,GtkWidget *clist) { | |
+ GList *selection; | |
+ Player *Play; | |
+ gint row; | |
+ GtkWidget *dialog; | |
+ gint ErrandType; | |
+ dialog=GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(widget),"dialog")); | |
+ ErrandType=GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(widget), | |
+ "errandtype")); | |
+ selection=GTK_CLIST(clist)->selection; | |
+ if (selection) { | |
+ row=GPOINTER_TO_INT(selection->data); | |
+ Play=(Player *)gtk_clist_get_row_data(GTK_CLIST(clist),row); | |
+ if (ErrandType==ET_SPY) { | |
+ SendClientMessage(ClientData.Play,C_NONE,C_SPYON,Play, | |
+ NULL,ClientData.Play); | |
+ } else { | |
+ SendClientMessage(ClientData.Play,C_NONE,C_TIPOFF,Play, | |
+ NULL,ClientData.Play); | |
+ } | |
+ gtk_widget_destroy(dialog); | |
+ } | |
+} | |
+ | |
+void SpyOnPlayer(GtkWidget *widget,gpointer data) { | |
+ ErrandDialog(ET_SPY); | |
+} | |
+ | |
+void TipOff(GtkWidget *widget,gpointer data) { | |
+ ErrandDialog(ET_TIPOFF); | |
+} | |
+ | |
+void ErrandDialog(gint ErrandType) { | |
+ GtkWidget *dialog,*clist,*button,*vbox,*hbbox,*hsep,*label; | |
+ gchar *text; | |
+ | |
+ dialog=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_container_set_border_width(GTK_CONTAINER(dialog),7); | |
+ | |
+ gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(dialog), | |
+ GTK_WINDOW(ClientData.window)); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ | |
+ if (ErrandType==ET_SPY) { | |
+ gtk_window_set_title(GTK_WINDOW(dialog),_("Spy On Player")); | |
+ text=g_strdup_printf( | |
+_("Please choose the player to spy on. Your %s will\n" | |
+"then offer his services to the player, and if successful,\n" | |
+"you will be able to view the player's stats with the\n" | |
+"\"Get spy reports\" menu. Remember that the %s will leave\n" | |
+"you, so any %s or %s that he's carrying may be lost!"), | |
+Names.Bitch,Names.Bitch,Names.Guns,Names.Drugs); | |
+ label=gtk_label_new(text); g_free(text); | |
+ } else { | |
+ gtk_window_set_title(GTK_WINDOW(dialog),_("Tip Off The Cops")); | |
+ text=g_strdup_printf( | |
+_("Please choose the player to tip off the cops to. Your %s will\n" | |
+"help the cops to attack that player, and then report back to you\n" | |
+"on the encounter. Remember that the %s will leave you temporarily,\n" | |
+"so any %s or %s that he's carrying may be lost!"), | |
+Names.Bitch,Names.Bitch,Names.Guns,Names.Drugs); | |
+ label=gtk_label_new(text); g_free(text); | |
+ } | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ | |
+ clist=ClientData.PlayerList=CreatePlayerList(); | |
+ UpdatePlayerList(clist,FALSE); | |
+ gtk_box_pack_start(GTK_BOX(vbox),clist,TRUE,TRUE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ hbbox=gtk_hbutton_box_new(); | |
+ button=gtk_button_new_with_label(_("OK")); | |
+ gtk_object_set_data(GTK_OBJECT(button),"dialog",dialog); | |
+ gtk_object_set_data(GTK_OBJECT(button),"errandtype", | |
+ GINT_TO_POINTER(ErrandType)); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(ErrandOK), | |
+ (gpointer)clist); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ button=gtk_button_new_with_label(_("Cancel")); | |
+ gtk_signal_connect_object(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)dialog); | |
+ gtk_box_pack_start(GTK_BOX(hbbox),button,TRUE,TRUE,0); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbbox,FALSE,FALSE,0); | |
+ gtk_container_add(GTK_CONTAINER(dialog),vbox); | |
+ gtk_widget_show_all(dialog); | |
+} | |
+ | |
+void SackBitch(GtkWidget *widget,gpointer data) { | |
+ char *caps,*title,*text; | |
+ caps=InitialCaps(Names.Bitch); | |
+ title=g_strdup_printf(_("Sack %s"),caps); | |
+ text=g_strdup_printf(_("Are you sure? (Any %s or %s carried\n" | |
+ "by this %s may be lost!)"),Names.Guns, | |
+ Names.Drugs,Names.Bitch); | |
+ if (MessageBox(ClientData.window,title,text,MB_YES|MB_NO)==MB_YES) { | |
+ SendClientMessage(ClientData.Play,C_NONE,C_SACKBITCH,NULL,NULL, | |
+ ClientData.Play); | |
+ } | |
+ g_free(caps); g_free(text); g_free(title); | |
+} | |
+ | |
+void CreateInventory(GtkWidget *hbox,gchar *Objects,GtkAccelGroup *accel_group, | |
+ gboolean CreateButtons,gboolean CreateHere, | |
+ struct InventoryWidgets *widgets,GtkSignalFunc CallBack) { | |
+ GtkWidget *scrollwin,*clist,*vbbox,*frame[2],*button[3]; | |
+ gint i,mini; | |
+ guint accel_key; | |
+ GString *text; | |
+ gchar *titles[2][2]; | |
+ gchar *button_text[3]; | |
+ gpointer button_type[3] = { BT_BUY, BT_SELL, BT_DROP }; | |
+ | |
+ titles[0][0]=titles[1][0]=_("Name"); | |
+ titles[0][1]=_("Price"); | |
+ titles[1][1]=_("Number"); | |
+ | |
+ button_text[0]=_("_Buy ->"); | |
+ button_text[1]=_("<- _Sell"); | |
+ button_text[2]=_("_Drop <-"); | |
+ | |
+ text=g_string_new(""); | |
+ | |
+ if (CreateHere) { | |
+ g_string_sprintf(text,_("%s here"),Objects); | |
+ widgets->HereFrame=frame[0]=gtk_frame_new(text->str); | |
+ } | |
+ g_string_sprintf(text,_("%s carried"),Objects); | |
+ widgets->CarriedFrame=frame[1]=gtk_frame_new(text->str); | |
+ | |
+ widgets->HereList=widgets->CarriedList=NULL; | |
+ if (CreateHere) mini=0; else mini=1; | |
+ for (i=mini;i<2;i++) { | |
+ gtk_container_set_border_width(GTK_CONTAINER(frame[i]),5); | |
+ | |
+ scrollwin=gtk_scrolled_window_new(NULL,NULL); | |
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), | |
+ GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC… | |
+ clist=gtk_clist_new_with_titles(2,titles[i]); | |
+ gtk_clist_set_column_auto_resize(GTK_CLIST(clist),0,TRUE); | |
+ gtk_clist_set_column_auto_resize(GTK_CLIST(clist),1,TRUE); | |
+ gtk_clist_column_titles_passive(GTK_CLIST(clist)); | |
+ gtk_clist_set_selection_mode(GTK_CLIST(clist),GTK_SELECTION_SINGLE); | |
+ gtk_clist_set_auto_sort(GTK_CLIST(clist),FALSE); | |
+ gtk_container_add(GTK_CONTAINER(scrollwin),clist); | |
+ gtk_container_add(GTK_CONTAINER(frame[i]),scrollwin); | |
+ if (i==0) widgets->HereList=clist; else widgets->CarriedList=clist; | |
+ } | |
+ if (CreateHere) gtk_box_pack_start(GTK_BOX(hbox),frame[0],TRUE,TRUE,0); | |
+ | |
+ if (CreateButtons) { | |
+ widgets->vbbox=vbbox=gtk_vbutton_box_new(); | |
+ | |
+ for (i=0;i<3;i++) { | |
+ button[i]=gtk_button_new_with_label(""); | |
+ accel_key=gtk_label_parse_uline(GTK_LABEL(GTK_BIN(button[i])->child), | |
+ button_text[i]); | |
+ gtk_widget_add_accelerator(button[i],"clicked",accel_group,accel_key,… | |
+ GTK_ACCEL_VISIBLE | GTK_ACCEL_SIGNAL_VISIBLE… | |
+ if (CallBack) gtk_signal_connect(GTK_OBJECT(button[i]),"clicked", | |
+ GTK_SIGNAL_FUNC(CallBack), | |
+ button_type[i]); | |
+ gtk_box_pack_start(GTK_BOX(vbbox),button[i],TRUE,TRUE,0); | |
+ } | |
+ widgets->BuyButton=button[0]; | |
+ widgets->SellButton=button[1]; | |
+ widgets->DropButton=button[2]; | |
+ gtk_box_pack_start(GTK_BOX(hbox),vbbox,FALSE,FALSE,0); | |
+ } else widgets->vbbox=NULL; | |
+ | |
+ gtk_box_pack_start(GTK_BOX(hbox),frame[1],TRUE,TRUE,0); | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+void DestroyShowing(GtkWidget *widget,gpointer data) { | |
+ gboolean *IsShowing; | |
+ | |
+ IsShowing=(gboolean *)gtk_object_get_data(GTK_OBJECT(widget),"IsShowing"); | |
+ if (IsShowing) *IsShowing=FALSE; | |
+} | |
+ | |
+gint DisallowDelete(GtkWidget *widget,GdkEvent *event,gpointer data) { | |
+ return(TRUE); | |
+} | |
+ | |
+static void NewNameOK(GtkWidget *widget,GtkWidget *window) { | |
+ GtkWidget *entry; | |
+ gchar *text; | |
+ | |
+ entry=GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(window),"entry")); | |
+ text=gtk_editable_get_chars(GTK_EDITABLE(entry),0,-1); | |
+ if (text[0]) { | |
+ SetPlayerName(ClientData.Play,text); | |
+ SendClientMessage(NULL,C_NONE,C_NAME,NULL,text,ClientData.Play); | |
+ gtk_widget_destroy(window); | |
+ } | |
+ g_free(text); | |
+} | |
+ | |
+void NewNameDialog() { | |
+ GtkWidget *window,*button,*hsep,*vbox,*label,*entry; | |
+ | |
+ window=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_title(GTK_WINDOW(window),_("Change Name")); | |
+ gtk_window_set_modal(GTK_WINDOW(window),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(window), | |
+ GTK_WINDOW(ClientData.window)); | |
+ gtk_container_set_border_width(GTK_CONTAINER(window),7); | |
+ gtk_signal_connect(GTK_OBJECT(window),"delete_event", | |
+ GTK_SIGNAL_FUNC(DisallowDelete),NULL); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ | |
+ label=gtk_label_new(_("Unfortunately, somebody else is already " | |
+ "using \"your\" name. Please change it:-")); | |
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0); | |
+ | |
+ entry=gtk_entry_new(); | |
+ gtk_object_set_data(GTK_OBJECT(window),"entry",entry); | |
+ gtk_signal_connect(GTK_OBJECT(entry),"activate", | |
+ GTK_SIGNAL_FUNC(NewNameOK),window); | |
+ gtk_entry_set_text(GTK_ENTRY(entry),GetPlayerName(ClientData.Play)); | |
+ gtk_box_pack_start(GTK_BOX(vbox),entry,FALSE,FALSE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ button=gtk_button_new_with_label(_("OK")); | |
+ gtk_signal_connect(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(NewNameOK),window); | |
+ gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0); | |
+ GTK_WIDGET_SET_FLAGS(button,GTK_CAN_DEFAULT); | |
+ gtk_widget_grab_default(button); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(window),vbox); | |
+ gtk_widget_show_all(window); | |
+} | |
+ | |
+void GunShopDialog() { | |
+ GtkWidget *window,*button,*hsep,*vbox,*hbox; | |
+ GtkAccelGroup *accel_group; | |
+ gchar *text; | |
+ | |
+ window=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ gtk_window_set_default_size(GTK_WINDOW(window),600,190); | |
+ gtk_signal_connect(GTK_OBJECT(window),"destroy", | |
+ GTK_SIGNAL_FUNC(SendDoneMessage),NULL); | |
+ accel_group=gtk_accel_group_new(); | |
+ gtk_window_add_accel_group(GTK_WINDOW(window),accel_group); | |
+ gtk_window_set_title(GTK_WINDOW(window),Names.GunShopName); | |
+ gtk_window_set_modal(GTK_WINDOW(window),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(window), | |
+ GTK_WINDOW(ClientData.window)); | |
+ gtk_container_set_border_width(GTK_CONTAINER(window),7); | |
+ IsShowingGunShop=TRUE; | |
+ gtk_object_set_data(GTK_OBJECT(window),"IsShowing", | |
+ (gpointer)&IsShowingGunShop); | |
+ gtk_signal_connect(GTK_OBJECT(window),"destroy", | |
+ GTK_SIGNAL_FUNC(DestroyShowing),NULL); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,7); | |
+ | |
+ hbox=gtk_hbox_new(FALSE,7); | |
+ text=InitialCaps(Names.Guns); | |
+ CreateInventory(hbox,text,accel_group,TRUE,TRUE,&ClientData.Gun, | |
+ DealGuns); g_free(text); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0); | |
+ | |
+ hsep=gtk_hseparator_new(); | |
+ gtk_box_pack_start(GTK_BOX(vbox),hsep,FALSE,FALSE,0); | |
+ | |
+ button=gtk_button_new_with_label(_("Done")); | |
+ gtk_signal_connect_object(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)window); | |
+ gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(window),vbox); | |
+ | |
+ UpdateInventory(&ClientData.Gun,ClientData.Play->Guns,NumGun,FALSE); | |
+ gtk_widget_show_all(window); | |
+} | |
+ | |
+void UpdatePlayerLists() { | |
+ if (IsShowingPlayerList) UpdatePlayerList(ClientData.PlayerList,FALSE); | |
+ if (IsShowingTalkList) UpdatePlayerList(ClientData.TalkList,FALSE); | |
+} | |
+ | |
+void GetSpyReports(GtkWidget *Widget,gpointer data) { | |
+ SendClientMessage(ClientData.Play,C_NONE,C_CONTACTSPY,NULL,NULL, | |
+ ClientData.Play); | |
+} | |
+ | |
+static void DestroySpyReports(GtkWidget *widget,gpointer data) { | |
+ SpyReportsDialog=NULL; | |
+} | |
+ | |
+static void CreateSpyReports() { | |
+ GtkWidget *window,*button,*vbox,*notebook; | |
+ GtkAccelGroup *accel_group; | |
+ | |
+ SpyReportsDialog=window=gtk_window_new(GTK_WINDOW_DIALOG); | |
+ accel_group=gtk_accel_group_new(); | |
+ gtk_object_set_data(GTK_OBJECT(window),"accel_group",accel_group); | |
+ gtk_window_add_accel_group(GTK_WINDOW(window),accel_group); | |
+ gtk_window_set_title(GTK_WINDOW(window),_("Spy reports")); | |
+ gtk_window_set_modal(GTK_WINDOW(window),TRUE); | |
+ gtk_window_set_transient_for(GTK_WINDOW(window), | |
+ GTK_WINDOW(ClientData.window)); | |
+ gtk_container_set_border_width(GTK_CONTAINER(window),7); | |
+ gtk_signal_connect(GTK_OBJECT(window),"destroy", | |
+ GTK_SIGNAL_FUNC(DestroySpyReports),NULL); | |
+ | |
+ vbox=gtk_vbox_new(FALSE,5); | |
+ notebook=gtk_notebook_new(); | |
+ gtk_object_set_data(GTK_OBJECT(window),"notebook",notebook); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),notebook,TRUE,TRUE,0); | |
+ | |
+ button=gtk_button_new_with_label(_("Close")); | |
+ gtk_signal_connect_object(GTK_OBJECT(button),"clicked", | |
+ GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
+ (gpointer)window); | |
+ gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,0); | |
+ | |
+ gtk_container_add(GTK_CONTAINER(window),vbox); | |
+ | |
+ gtk_widget_show_all(window); | |
+} | |
+ | |
+void DisplaySpyReports(Player *Play) { | |
+ GtkWidget *dialog,*notebook,*vbox,*hbox,*frame,*label,*table; | |
+ GtkAccelGroup *accel_group; | |
+ gchar *caps; | |
+ struct StatusWidgets Status; | |
+ struct InventoryWidgets SpyDrugs,SpyGuns; | |
+ | |
+ if (!SpyReportsDialog) CreateSpyReports(); | |
+ dialog=SpyReportsDialog; | |
+ notebook=GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(dialog),"notebook")); | |
+ accel_group=(GtkAccelGroup *)(gtk_object_get_data(GTK_OBJECT(dialog), | |
+ "accel_group")); | |
+ vbox=gtk_vbox_new(FALSE,5); | |
+ frame=gtk_frame_new("Stats"); | |
+ gtk_container_set_border_width(GTK_CONTAINER(frame),4); | |
+ table=CreateStatusWidgets(&Status); | |
+ gtk_container_add(GTK_CONTAINER(frame),table); | |
+ gtk_box_pack_start(GTK_BOX(vbox),frame,FALSE,FALSE,0); | |
+ | |
+ hbox=gtk_hbox_new(FALSE,5); | |
+ caps=InitialCaps(Names.Drugs); | |
+ CreateInventory(hbox,caps,accel_group,FALSE,FALSE,&SpyDrugs,NULL); | |
+ g_free(caps); | |
+ caps=InitialCaps(Names.Guns); | |
+ CreateInventory(hbox,caps,accel_group,FALSE,FALSE,&SpyGuns,NULL); | |
+ g_free(caps); | |
+ | |
+ gtk_box_pack_start(GTK_BOX(vbox),hbox,TRUE,TRUE,0); | |
+ label=gtk_label_new(GetPlayerName(Play)); | |
+ | |
+ DisplayStats(Play,&Status); | |
+ UpdateInventory(&SpyDrugs,Play->Drugs,NumDrug,TRUE); | |
+ UpdateInventory(&SpyGuns,Play->Guns,NumGun,FALSE); | |
+ | |
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),vbox,label); | |
+ | |
+ gtk_widget_show_all(notebook); | |
+} | |
+ | |
+#else | |
+ | |
+#include <glib.h> | |
+#include "dopewars.h" | |
+ | |
+char GtkLoop(int *argc,char **argv[],char ReturnOnFail) { | |
+ if (!ReturnOnFail) { | |
+ g_print(_("No GTK+ client available - rebuild the binary passing the\n" | |
+ "--enable-gtk-client option to configure, or use the curses\n" | |
+ "client (if available) instead!\n")); | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+#endif /* GTK_CLIENT */ | |
diff --git a/src/gtk_client.h b/src/gtk_client.h | |
t@@ -0,0 +1,31 @@ | |
+/* gtk_client.h dopewars client using the GTK+ toolkit */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+ | |
+#ifndef __GTK_CLIENT_H__ | |
+#define __GTK_CLIENT_H__ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+char GtkLoop(int *argc,char **argv[],char ReturnOnFail); | |
+ | |
+#endif | |
diff --git a/src/message.c b/src/message.c | |
t@@ -0,0 +1,747 @@ | |
+/* message.c Message-handling routines for dopewars */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#ifdef HAVE_UNISTD_H | |
+#include <unistd.h> | |
+#endif | |
+#ifdef HAVE_FCNTL_H | |
+#include <fcntl.h> | |
+#endif | |
+ | |
+#include <string.h> | |
+#include <stdlib.h> | |
+#include <glib.h> | |
+#include <errno.h> | |
+#include "dopeos.h" | |
+#include "dopewars.h" | |
+#include "serverside.h" | |
+#include "message.h" | |
+ | |
+/* Maximum sizes (in bytes) of read and write buffers - connections should | |
+ be dropped if either buffer is filled */ | |
+#define MAXREADBUF (32768) | |
+#define MAXWRITEBUF (65536) | |
+ | |
+/* dopewars is built around a client-server model. Each client handles the | |
+ user interface, but all the important calculation and processing is | |
+ handled by the server. All communication is conducted via. TCP by means | |
+ of plain text newline-delimited messages. | |
+ | |
+ Message structure:- | |
+ From^To^ACData | |
+ | |
+ From,To: Player names identifying the sender and intended recipient of | |
+ the message. Either field may be blank, although the server will | |
+ usually reject incoming messages if they are not properly | |
+ identified with a correct "From" field. | |
+ A: One-letter code; used by AI players to identify the message subtype | |
+ (check AIPlayer.h) | |
+ C: One-letter code to identify the message type (check message.h) | |
+ Data: Message-dependent information | |
+ | |
+ For example, a common message is the "printmessage" message (message code | |
+ C is C_PRINTMESSAGE), which simply instructs the client to display "Data". | |
+ Any ^ characters within Data are replaced by newlines on output. So in orde… | |
+ for the server to instruct player "Fred" to display "Hello world" it would | |
+ send the message:- | |
+ ^Fred^AAHello world | |
+ Note that the server has left the From field blank, and has specified the | |
+ AI code 'A' - defined in AIPlayer.h as C_NONE (i.e. an "unimportant" | |
+ message) as well as the main code 'A', defined as C_PRINTMESSAGE in | |
+ message.h | |
+ | |
+ When the network is down, a server is simulated locally. Client to server | |
+ messages are simply passed directly to the server message handling routine | |
+ in serverside.c, while server to client messages are queued in MessageList | |
+ and read by the do_game loop within dopewars.c */ | |
+ | |
+GSList *FirstClient; | |
+ | |
+void (*ClientMessageHandlerPt) (char *,Player *) = NULL; | |
+void (*SocketWriteTestPt) (Player *,gboolean) = NULL; | |
+ | |
+void SendClientMessage(Player *From,char AICode,char Code, | |
+ Player *To,char *Data,Player *BufOwn) { | |
+/* Send a message from client player "From" with computer code "AICode", */ | |
+/* human-readable code "Code" and data "Data". The message is sent to the */ | |
+/* server, identifying itself as for "To". From, To, or Data may be NULL. */ | |
+ GString *text; | |
+ Player *ServerFrom; | |
+ g_assert(BufOwn!=NULL); | |
+ text=g_string_new(NULL); | |
+ g_string_sprintf(text,"%s^%s^%c%c%s",From ? GetPlayerName(From) : "", | |
+ To ? GetPlayerName(To) : "",AICode,Code, | |
+ Data ? Data : ""); | |
+ | |
+#if NETWORKING | |
+ if (!Network) { | |
+#endif | |
+ if (From) ServerFrom=GetPlayerByName(GetPlayerName(From),FirstServer); | |
+ else ServerFrom=NULL; | |
+ HandleServerMessage(text->str,ServerFrom); | |
+#if NETWORKING | |
+ } else { | |
+ WriteToConnectionBuffer(BufOwn,text->str); | |
+ if (SocketWriteTestPt) (*SocketWriteTestPt)(BufOwn,TRUE); | |
+ } | |
+#endif /* NETWORKING */ | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+void SendPrintMessage(Player *From,char AICode, | |
+ Player *To,char *Data) { | |
+/* Shorthand for the server sending a "printmessage"; instructs the */ | |
+/* client "To" to display "Data" */ | |
+ SendServerMessage(From,AICode,C_PRINTMESSAGE,To,Data); | |
+} | |
+ | |
+void SendQuestion(Player *From,char AICode, | |
+ Player *To,char *Data) { | |
+/* Shorthand for the server sending a "question"; instructs the client */ | |
+/* "To" to display the second word of Data and accept any letter within */ | |
+/* the first word of Data as suitable reply */ | |
+ SendServerMessage(From,AICode,C_QUESTION,To,Data); | |
+} | |
+ | |
+void SendServerMessage(Player *From,char AICode,char Code, | |
+ Player *To,char *Data) { | |
+/* Sends a message from the server to client player "To" with computer */ | |
+/* code "AICode", human-readable code "Code" and data "Data". The message */ | |
+/* will claim to be from or on behalf of player "From" */ | |
+ gchar *text; | |
+ if (!Network) { | |
+ text=g_strdup_printf("%s^%s^%c%c%s",From ? GetPlayerName(From) : "", | |
+ To ? GetPlayerName(To) : "",AICode,Code, | |
+ Data ? Data : ""); | |
+ if (ClientMessageHandlerPt) { | |
+ (*ClientMessageHandlerPt)(text,(Player *)(FirstClient->data)); | |
+ } | |
+ g_free(text); | |
+ } else SendClientMessage(From,AICode,Code,To,Data,To); | |
+} | |
+ | |
+#if NETWORKING | |
+gchar *ReadFromConnectionBuffer(Player *Play) { | |
+ ConnBuf *conn; | |
+ int MessageLen; | |
+ char *SepPt; | |
+ gchar *NewMessage; | |
+ conn=&Play->ReadBuf; | |
+ if (!conn->Data || !conn->DataPresent) return NULL; | |
+ SepPt=memchr(conn->Data,'\n',conn->DataPresent); | |
+ if (!SepPt) return NULL; | |
+ *SepPt='\0'; | |
+ MessageLen=SepPt-conn->Data+1; | |
+ NewMessage=g_new(gchar,MessageLen); | |
+ memcpy(NewMessage,conn->Data,MessageLen); | |
+ if (MessageLen<conn->DataPresent) { | |
+ memmove(&conn->Data[0],&conn->Data[MessageLen], | |
+ conn->DataPresent-MessageLen); | |
+ } | |
+ conn->DataPresent-=MessageLen; | |
+ return NewMessage; | |
+} | |
+ | |
+gboolean ReadConnectionBufferFromWire(Player *Play) { | |
+ ConnBuf *conn; | |
+ int CurrentPosition,BytesRead; | |
+ conn=&Play->ReadBuf; | |
+ CurrentPosition=conn->DataPresent; | |
+ while(1) { | |
+ if (CurrentPosition>=conn->Length) { | |
+ if (conn->Length==MAXREADBUF) { | |
+ return FALSE; /* drop connection */ | |
+ } | |
+ if (conn->Length==0) conn->Length=256; else conn->Length*=2; | |
+ if (conn->Length>MAXREADBUF) conn->Length=MAXREADBUF; | |
+ conn->Data=g_realloc(conn->Data,conn->Length); | |
+ } | |
+ BytesRead=recv(Play->fd,&conn->Data[CurrentPosition], | |
+ conn->Length-CurrentPosition,0); | |
+ if (BytesRead==SOCKET_ERROR) { | |
+ break; | |
+ } else if (BytesRead==0) { | |
+ return FALSE; | |
+ } else { | |
+ CurrentPosition+=BytesRead; | |
+ } | |
+ } | |
+ conn->DataPresent=CurrentPosition; | |
+ return TRUE; | |
+} | |
+ | |
+void WriteToConnectionBuffer(Player *Play,gchar *data) { | |
+ int AddLength,NewLength; | |
+ ConnBuf *conn; | |
+ conn=&Play->WriteBuf; | |
+ AddLength=strlen(data)+1; | |
+ NewLength=conn->DataPresent+AddLength; | |
+ if (NewLength > conn->Length) { | |
+ conn->Length*=2; | |
+ conn->Length=MAX(conn->Length,NewLength); | |
+ if (conn->Length > MAXWRITEBUF) conn->Length=MAXWRITEBUF; | |
+ if (NewLength > conn->Length) return; | |
+ conn->Data=g_realloc(conn->Data,conn->Length); | |
+ } | |
+ memcpy(&conn->Data[conn->DataPresent],data,AddLength); | |
+ conn->DataPresent=NewLength; | |
+ conn->Data[NewLength-1]='\n'; | |
+} | |
+ | |
+gboolean WriteConnectionBufferToWire(Player *Play) { | |
+ ConnBuf *conn; | |
+ int CurrentPosition,BytesSent; | |
+ conn=&Play->WriteBuf; | |
+ if (!conn->Data || !conn->DataPresent) return TRUE; | |
+ if (conn->Length==MAXWRITEBUF) return FALSE; | |
+ CurrentPosition=0; | |
+ while (CurrentPosition<conn->DataPresent) { | |
+ BytesSent=send(Play->fd,&conn->Data[CurrentPosition], | |
+ conn->DataPresent-CurrentPosition,0); | |
+ if (BytesSent==SOCKET_ERROR) { | |
+ if (errno==EPIPE) return FALSE; | |
+ break; | |
+ } else { | |
+ CurrentPosition+=BytesSent; | |
+ } | |
+ } | |
+ if (CurrentPosition>0 && CurrentPosition<conn->DataPresent) { | |
+ memmove(&conn->Data[0],&conn->Data[CurrentPosition], | |
+ conn->DataPresent-CurrentPosition); | |
+ } | |
+ conn->DataPresent-=CurrentPosition; | |
+ return TRUE; | |
+} | |
+ | |
+gchar *bgets(int fd) { | |
+/* Drop-in substitute for fgets; reads a newline-terminated string from */ | |
+/* file descriptor fd, into a dynamically-allocated buffer. Returns a */ | |
+/* pointer to the buffer, or NULL if an error occurred. It is the user's */ | |
+/* responsibility to g_free the pointer when it is no longer needed. */ | |
+/* Used for non-blocking read from TCP sockets. */ | |
+/* N.B. The terminating newline is _not_ returned in the string. */ | |
+ ssize_t len; | |
+ unsigned TotalLen=0; | |
+ GString *text; | |
+ gchar *buffer; | |
+ char tmp[10]; | |
+ text=g_string_new(NULL); | |
+ for (;;) { | |
+ len=recv(fd,tmp,1,0); | |
+ if (len==SOCKET_ERROR) { g_string_free(text,TRUE); return NULL; } | |
+ if (len==0) { g_string_free(text,TRUE); return NULL; } | |
+ if (tmp[0]=='\n') { | |
+ buffer=text->str; | |
+ g_string_free(text,FALSE); /* Just free the g_string, not the data */ | |
+ return buffer; | |
+ } else { | |
+ g_string_append_c(text,tmp[0]); | |
+ TotalLen++; | |
+ /* Test to make sure dodgy clients don't eat all of our nice memory */ | |
+ if (TotalLen > 64000) { | |
+ g_warning("Abnormally large packet"); | |
+ g_string_free(text,TRUE); return NULL; | |
+ } | |
+ } | |
+ } | |
+} | |
+#endif /* NETWORKING */ | |
+ | |
+void chomp(char *str) { | |
+/* Removes a terminating newline from "str", if one is present. */ | |
+ int len=strlen(str); | |
+ if (str[len-1]=='\n') str[len-1]=0; | |
+} | |
+ | |
+void BroadcastToClients(char AICode,char Code,char *Data, | |
+ Player *From,Player *Except) { | |
+/* Sends the message made up of AICode,Code and Data to all players except */ | |
+/* "Except" (if non-NULL). It will be sent by the server, and on behalf of */ | |
+/* player "From" */ | |
+ Player *tmp; | |
+ GSList *list; | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ if (tmp!=Except) SendServerMessage(From,AICode,Code,tmp,Data); | |
+ } | |
+} | |
+ | |
+void SendInventory(Player *From,char AICode,char Code, | |
+ Player *To,Inventory *Guns,Inventory *Drugs) { | |
+/* Encodes an Inventory structure into a string, and sends it as the data */ | |
+/* with a server message constructed from the other arguments. */ | |
+ int i; | |
+ GString *text; | |
+ text=g_string_new(NULL); | |
+ for (i=0;i<NumGun;i++) { | |
+ g_string_sprintfa(text,"%d:",Guns ? Guns[i].Carried : 0); | |
+ } | |
+ for (i=0;i<NumDrug;i++) { | |
+ g_string_sprintfa(text,"%d:",Drugs ? Drugs[i].Carried : 0); | |
+ } | |
+ SendServerMessage(From,AICode,Code,To,text->str); | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+void ReceiveInventory(char *Data,Inventory *Guns,Inventory *Drugs) { | |
+/* Decodes a string representation (in "Data") to its original Inventory */ | |
+/* contents, and stores it in "Guns" and "Drugs" if non-NULL */ | |
+ int i,val; | |
+ char *pt; | |
+ pt=Data; | |
+ for (i=0;i<NumGun;i++) { | |
+ val=GetNextInt(&pt,0); | |
+ if (Guns) Guns[i].Carried=val; | |
+ } | |
+ for (i=0;i<NumDrug;i++) { | |
+ val=GetNextInt(&pt,0); | |
+ if (Drugs) Drugs[i].Carried=val; | |
+ } | |
+} | |
+ | |
+void SendPlayerData(Player *To) { | |
+/* Sends all pertinent data about player "To" from the server to player "To" */ | |
+ SendSpyReport(NULL,To); | |
+} | |
+ | |
+void SendSpyReport(Player *To,Player *SpiedOn) { | |
+/* Sends pertinent data about player "SpiedOn" from the server to player "To" … | |
+ gchar *cashstr,*debtstr,*bankstr; | |
+ GString *text; | |
+ int i; | |
+ text=g_string_new(NULL); | |
+ g_string_sprintf(text,"%s^%s^%s^%d^%d^%d^%d^%d^", | |
+ (cashstr=pricetostr(SpiedOn->Cash)), | |
+ (debtstr=pricetostr(SpiedOn->Debt)), | |
+ (bankstr=pricetostr(SpiedOn->Bank)), | |
+ SpiedOn->Health,SpiedOn->CoatSize, | |
+ SpiedOn->IsAt,SpiedOn->Turn,SpiedOn->Flags); | |
+ g_free(cashstr); g_free(debtstr); g_free(bankstr); | |
+ for (i=0;i<NumGun;i++) { | |
+ g_string_sprintfa(text,"%d^",SpiedOn->Guns[i].Carried); | |
+ } | |
+ for (i=0;i<NumDrug;i++) { | |
+ g_string_sprintfa(text,"%d^",SpiedOn->Drugs[i].Carried); | |
+ } | |
+ g_string_sprintfa(text,"%d",SpiedOn->Bitches.Carried); | |
+ if (To) SendServerMessage(SpiedOn,C_NONE,C_UPDATE,To,text->str); | |
+ else SendServerMessage(NULL,C_NONE,C_UPDATE,SpiedOn,text->str); | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+void SendInitialData(Player *To) { | |
+ gchar *text; | |
+ if (!Network) return; | |
+ text=g_strdup_printf("%s^%d^%d^%d^%s^%s^%s^%s^%s^%s^%s^%s^", | |
+ VERSION,NumLocation,NumGun,NumDrug, | |
+ Names.Bitch,Names.Bitches,Names.Gun,Names.Guns, | |
+ Names.Drug,Names.Drugs,Names.Month,Names.Year); | |
+ SendServerMessage(NULL,C_NONE,C_INIT,To,text); | |
+ g_free(text); | |
+} | |
+ | |
+void ReceiveInitialData(char *Data) { | |
+ char *pt,*ServerVersion; | |
+ GSList *list; | |
+ pt=Data; | |
+ ServerVersion=GetNextWord(&pt,"(unknown)"); | |
+ ResizeLocations(GetNextInt(&pt,NumLocation)); | |
+ ResizeGuns(GetNextInt(&pt,NumGun)); | |
+ ResizeDrugs(GetNextInt(&pt,NumDrug)); | |
+ for (list=FirstClient;list;list=g_slist_next(list)) { | |
+ UpdatePlayer((Player*)list->data); | |
+ } | |
+ AssignName(&Names.Bitch,GetNextWord(&pt,"")); | |
+ AssignName(&Names.Bitches,GetNextWord(&pt,"")); | |
+ AssignName(&Names.Gun,GetNextWord(&pt,"")); | |
+ AssignName(&Names.Guns,GetNextWord(&pt,"")); | |
+ AssignName(&Names.Drug,GetNextWord(&pt,"")); | |
+ AssignName(&Names.Drugs,GetNextWord(&pt,"")); | |
+ AssignName(&Names.Month,GetNextWord(&pt,"")); | |
+ AssignName(&Names.Year,GetNextWord(&pt,"")); | |
+ if (strcmp(VERSION,ServerVersion)!=0) { | |
+ g_message(_("This server is version %s, while your client is " | |
+"version %s.\nBe warned that different versions may not be fully compatible!\n" | |
+"Refer to the website at http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/\n" | |
+"for the latest version."),ServerVersion,VERSION); | |
+ } | |
+} | |
+ | |
+void SendMiscData(Player *To) { | |
+ gchar *text,*prstr[2]; | |
+ int i; | |
+ if (!Network) return; | |
+ text=g_strdup_printf("0^%c%s^%s^",DT_PRICES, | |
+ (prstr[0]=pricetostr(Prices.Spy)), | |
+ (prstr[1]=pricetostr(Prices.Tipoff))); | |
+ SendServerMessage(NULL,C_NONE,C_DATA,To,text); | |
+ g_free(prstr[0]); g_free(prstr[1]); g_free(text); | |
+ for (i=0;i<NumGun;i++) { | |
+ text=g_strdup_printf("%d^%c%s^%s^%d^%d^",i,DT_GUN,Gun[i].Name, | |
+ (prstr[0]=pricetostr(Gun[i].Price)), | |
+ Gun[i].Space,Gun[i].Damage); | |
+ SendServerMessage(NULL,C_NONE,C_DATA,To,text); | |
+ g_free(prstr[0]); g_free(text); | |
+ } | |
+ for (i=0;i<NumDrug;i++) { | |
+ text=g_strdup_printf("%d^%c%s^%s^%s^",i,DT_DRUG,Drug[i].Name, | |
+ (prstr[0]=pricetostr(Drug[i].MinPrice)), | |
+ (prstr[1]=pricetostr(Drug[i].MaxPrice))); | |
+ SendServerMessage(NULL,C_NONE,C_DATA,To,text); | |
+ g_free(prstr[0]); g_free(prstr[1]); g_free(text); | |
+ } | |
+ for (i=0;i<NumLocation;i++) { | |
+ text=g_strdup_printf("%d^%c%s^",i,DT_LOCATION,Location[i].Name); | |
+ SendServerMessage(NULL,C_NONE,C_DATA,To,text); | |
+ g_free(text); | |
+ } | |
+} | |
+ | |
+void ReceiveMiscData(char *Data) { | |
+/* Decodes information about locations, drugs, prices, etc. in "Data" */ | |
+ char *pt,*Name,Type; | |
+ int i; | |
+ pt=Data; | |
+ i=GetNextInt(&pt,0); | |
+ Name=GetNextWord(&pt,""); | |
+ Type=Name[0]; | |
+ if (strlen(Name)>1) switch(Type) { | |
+ case DT_LOCATION: | |
+ if (i>=0 && i<NumLocation) { | |
+ AssignName(&Location[i].Name,&Name[1]); | |
+ Location[i].PolicePresence=10; | |
+ Location[i].MinDrug=NumDrug/2+1; | |
+ Location[i].MaxDrug=NumDrug; | |
+ } | |
+ break; | |
+ case DT_GUN: | |
+ if (i>=0 && i<NumGun) { | |
+ AssignName(&Gun[i].Name,&Name[1]); | |
+ Gun[i].Price=GetNextPrice(&pt,0); | |
+ Gun[i].Space=GetNextInt(&pt,0); | |
+ Gun[i].Damage=GetNextInt(&pt,0); | |
+ } | |
+ break; | |
+ case DT_DRUG: | |
+ if (i>=0 && i<NumDrug) { | |
+ AssignName(&Drug[i].Name,&Name[1]); | |
+ Drug[i].MinPrice=GetNextPrice(&pt,0); | |
+ Drug[i].MaxPrice=GetNextPrice(&pt,0); | |
+ } | |
+ break; | |
+ case DT_PRICES: | |
+ Prices.Spy=strtoprice(&Name[1]); | |
+ Prices.Tipoff=GetNextPrice(&pt,0); | |
+ break; | |
+ } | |
+} | |
+ | |
+void ReceivePlayerData(char *text,Player *From) { | |
+/* Decode player data from the string "text" into player "From" */ | |
+ char *cp; | |
+ int i; | |
+ cp=text; | |
+ From->Cash=GetNextPrice(&cp,0); | |
+ From->Debt=GetNextPrice(&cp,0); | |
+ From->Bank=GetNextPrice(&cp,0); | |
+ From->Health=GetNextInt(&cp,100); | |
+ From->CoatSize=GetNextInt(&cp,0); | |
+ From->IsAt=GetNextInt(&cp,0); | |
+ From->Turn=GetNextInt(&cp,0); | |
+ From->Flags=GetNextInt(&cp,0); | |
+ for (i=0;i<NumGun;i++) { | |
+ From->Guns[i].Carried=GetNextInt(&cp,0); | |
+ } | |
+ for (i=0;i<NumDrug;i++) { | |
+ From->Drugs[i].Carried=GetNextInt(&cp,0); | |
+ } | |
+ From->Bitches.Carried=GetNextInt(&cp,0); | |
+} | |
+ | |
+gchar *GetNextWord(gchar **Data,gchar *Default) { | |
+ gchar *Word; | |
+ if (*Data==NULL || **Data=='\0') return Default; | |
+ Word=*Data; | |
+ while (**Data!='\0' && **Data!='^') (*Data)++; | |
+ if (**Data=='\0') { | |
+ *Data=NULL; | |
+ } else { | |
+ **Data='\0'; (*Data)++; | |
+ } | |
+ return Word; | |
+} | |
+ | |
+void AssignNextWord(gchar **Data,gchar **Dest) { | |
+ if (!Dest) return; | |
+ g_free(*Dest); | |
+ *Dest=g_strdup(GetNextWord(Data,"")); | |
+} | |
+ | |
+int GetNextInt(gchar **Data,int Default) { | |
+ gchar *Word=GetNextWord(Data,NULL); | |
+ if (Word) return atoi(Word); else return Default; | |
+} | |
+ | |
+price_t GetNextPrice(gchar **Data,price_t Default) { | |
+ gchar *Word=GetNextWord(Data,NULL); | |
+ if (Word) return strtoprice(Word); else return Default; | |
+} | |
+ | |
+#if NETWORKING | |
+char *SetupNetwork() { | |
+/* Sets up the connection from the client to the server. If the connection */ | |
+/* is successful, Network and Client are set to TRUE, and ClientSock is a */ | |
+/* file descriptor for the newly-opened socket. NULL is returned. If the */ | |
+/* connection fails, a pointer to an error message is returned. */ | |
+ struct sockaddr_in ClientAddr; | |
+ struct hostent *he; | |
+ static char NoHost[]= N_("Could not find host"); | |
+ static char NoSocket[]= N_("Could not create network socket"); | |
+ static char NoConnect[]= N_("Connection refused or no server present"); | |
+ | |
+ Network=Client=Server=FALSE; | |
+ | |
+ if ((he=gethostbyname(ServerName))==NULL) { | |
+ return NoHost; | |
+ } | |
+ ClientSock=socket(AF_INET,SOCK_STREAM,0); | |
+ if (ClientSock==SOCKET_ERROR) { | |
+ return NoSocket; | |
+ } | |
+ | |
+ ClientAddr.sin_family=AF_INET; | |
+ ClientAddr.sin_port=htons(Port); | |
+ ClientAddr.sin_addr=*((struct in_addr *)he->h_addr); | |
+ memset(ClientAddr.sin_zero,0,sizeof(ClientAddr.sin_zero)); | |
+ | |
+ if (connect(ClientSock,(struct sockaddr *)&ClientAddr, | |
+ sizeof(struct sockaddr))==-1) { | |
+ CloseSocket(ClientSock); | |
+ return NoConnect; | |
+ } else { | |
+ fcntl(ClientSock,F_SETFL,O_NONBLOCK); | |
+ } | |
+ Client=TRUE; Network=TRUE; | |
+ return NULL; | |
+} | |
+#endif /* NETWORKING */ | |
+ | |
+void SwitchToSinglePlayer(Player *Play) { | |
+/* Called when the client is pushed off the server, or the server */ | |
+/* terminates. Using the client information, starts a local server */ | |
+/* to reproduce the current game situation as best as possible so */ | |
+/* that the game can be continued in single player mode */ | |
+ Player *NewPlayer; | |
+ if (!Network || !Client || !FirstClient) return; | |
+ if (Play!=FirstClient->data) { | |
+ g_error("Oops! FirstClient should be player!"); | |
+ } | |
+ while (g_slist_next(FirstClient)) { | |
+ FirstClient=RemovePlayer((Player *)g_slist_next(FirstClient)->data, | |
+ FirstClient); | |
+ } | |
+ CloseSocket(ClientSock); | |
+ CleanUpServer(); | |
+ Network=Server=Client=FALSE; | |
+ NewPlayer=g_new(Player,1); | |
+ FirstServer=AddPlayer(0,NewPlayer,FirstServer); | |
+ CopyPlayer(NewPlayer,Play); | |
+ NewPlayer->Flags=0; | |
+ NewPlayer->EventNum=E_ARRIVE; | |
+ SendEvent(NewPlayer); | |
+} | |
+ | |
+void ShutdownNetwork() { | |
+/* Closes down the client side of the network connection. Clears the list */ | |
+/* of client players, and closes the network socket. */ | |
+ while (FirstClient) { | |
+ FirstClient=RemovePlayer((Player *)FirstClient->data,FirstClient); | |
+ } | |
+#if NETWORKING | |
+ if (Client) { | |
+ CloseSocket(ClientSock); | |
+ } | |
+#endif /* NETWORKING */ | |
+ Client=Network=Server=FALSE; | |
+} | |
+ | |
+int ProcessMessage(char *Msg,Player **From,char *AICode,char *Code, | |
+ Player **To,char **Data,GSList *First) { | |
+/* Given a "raw" message in "Msg" and a pointer to the start of the linked */ | |
+/* list of known players in "First", sets the other arguments to the message */ | |
+/* fields. Data is a dynamically-allocated buffer, which must be g_free'd by */ | |
+/* the caller. Returns 0 on success, -1 on failure. */ | |
+ gchar **split; | |
+ Player *tmp; | |
+ | |
+ *Data=NULL; | |
+ split=g_strsplit(Msg,"^",2); | |
+ if (split[0]) { | |
+ tmp=GetPlayerByName(split[0],First); | |
+ if (tmp && split[1]) { | |
+ *From=tmp; | |
+ tmp=GetPlayerByName(split[1],First); | |
+ if (tmp && split[2]) { | |
+ *To=tmp; | |
+ *AICode=split[2][0]; | |
+ *Code=split[2][1]; | |
+ *Data=g_strdup(split[2]+2); | |
+ g_strfreev(split); | |
+ return 0; | |
+ } | |
+ } | |
+ } | |
+ g_strfreev(split); | |
+ return -1; | |
+} | |
+ | |
+void ReceiveDrugsHere(char *text,Player *To) { | |
+/* Decodes the message data "text" into a list of drug prices for */ | |
+/* player "To" */ | |
+ char *cp; | |
+ int i; | |
+ | |
+ To->EventNum=E_ARRIVE; | |
+ cp=text; | |
+ for (i=0;i<NumDrug;i++) { | |
+ To->Drugs[i].Price=GetNextPrice(&cp,0); | |
+ } | |
+} | |
+ | |
+gboolean HandleGenericClientMessage(Player *From,char AICode,char Code, | |
+ Player *To,char *Data,char *DisplayMode) { | |
+/* Handles messages that both human clients and AI players deal with in the */ | |
+/* same way. */ | |
+ Player *tmp; | |
+ switch(Code) { | |
+ case C_LIST: case C_JOIN: | |
+ tmp=g_new(Player,1); | |
+ FirstClient=AddPlayer(0,tmp,FirstClient); | |
+ SetPlayerName(tmp,Data); | |
+ break; | |
+ case C_DATA: | |
+ ReceiveMiscData(Data); break; | |
+ case C_INIT: | |
+ ReceiveInitialData(Data); break; | |
+ case C_LEAVE: | |
+ if (From!=&Noone) FirstClient=RemovePlayer(From,FirstClient); | |
+ break; | |
+ case C_TRADE: | |
+ if (DisplayMode) *DisplayMode=DM_DEAL; | |
+ break; | |
+ case C_DRUGHERE: | |
+ ReceiveDrugsHere(Data,To); | |
+ if (DisplayMode) *DisplayMode=DM_STREET; | |
+ break; | |
+ case C_FIGHTPRINT: | |
+ if (From!=&Noone) { | |
+ From->Flags |= FIGHTING; | |
+ To->Flags |= CANSHOOT; | |
+ } | |
+ if (DisplayMode) *DisplayMode=DM_FIGHT; | |
+ break; | |
+ case C_CHANGEDISP: | |
+ if (DisplayMode) { | |
+ if (Data[0]=='N' && *DisplayMode==DM_STREET) *DisplayMode=DM_NONE; | |
+ if (Data[0]=='Y' && *DisplayMode==DM_NONE) *DisplayMode=DM_STREET; | |
+ } | |
+ break; | |
+ default: | |
+ return FALSE; break; | |
+ } | |
+ return TRUE; | |
+} | |
+ | |
+char *OpenMetaServerConnection(int *HttpSock) { | |
+ static char NoHost[] = N_("Cannot locate metaserver"); | |
+ static char NoSocket[] = N_("Cannot create socket"); | |
+ static char NoService[] = | |
+ N_("Metaserver not running HTTP or connection denied"); | |
+ struct sockaddr_in HttpAddr; | |
+ struct hostent *he; | |
+ | |
+ if ((he=gethostbyname(MetaServer.Name))==NULL) return NoHost; | |
+ if ((*HttpSock=socket(AF_INET,SOCK_STREAM,0))==-1) return NoSocket; | |
+ HttpAddr.sin_family=AF_INET; | |
+ HttpAddr.sin_port=htons(MetaServer.HttpPort); | |
+ HttpAddr.sin_addr=*((struct in_addr *)he->h_addr); | |
+ memset(HttpAddr.sin_zero,0,sizeof(HttpAddr.sin_zero)); | |
+ if (connect(*HttpSock,(struct sockaddr *)&HttpAddr, | |
+ sizeof(struct sockaddr))==SOCKET_ERROR) { | |
+ CloseSocket(*HttpSock); | |
+ return NoService; | |
+ } | |
+ return NULL; | |
+} | |
+ | |
+void CloseMetaServerConnection(int HttpSock) { | |
+ CloseSocket(HttpSock); | |
+} | |
+ | |
+void ClearServerList() { | |
+ ServerData *ThisServer; | |
+ while (ServerList) { | |
+ ThisServer=(ServerData *)(ServerList->data); | |
+ g_free(ThisServer->Name); g_free(ThisServer->Comment); | |
+ g_free(ThisServer->Version); g_free(ThisServer->Update); | |
+ g_free(ThisServer->UpSince); g_free(ThisServer); | |
+ ServerList=g_slist_remove(ServerList,ThisServer); | |
+ } | |
+} | |
+ | |
+void ReadMetaServerData(int HttpSock) { | |
+ gchar *buf; | |
+ ServerData *NewServer; | |
+ gboolean HeaderDone; | |
+ | |
+ ClearServerList(); | |
+ buf=g_strdup_printf("GET %s?output=text&getlist=%d HTTP/1.0\n\n", | |
+ MetaServer.Path,METAVERSION); | |
+ send(HttpSock,buf,strlen(buf),0); | |
+ g_free(buf); | |
+ HeaderDone=FALSE; | |
+ | |
+ while ((buf=bgets(HttpSock))) { | |
+ if (HeaderDone) { | |
+ NewServer=g_new0(ServerData,1); | |
+ NewServer->Name=buf; | |
+ buf=bgets(HttpSock); | |
+ NewServer->Port=atoi(buf); g_free(buf); | |
+ NewServer->Version=bgets(HttpSock); | |
+ buf=bgets(HttpSock); | |
+ if (buf[0]) NewServer->CurPlayers=atoi(buf); | |
+ else NewServer->CurPlayers=-1; | |
+ g_free(buf); | |
+ buf=bgets(HttpSock); | |
+ NewServer->MaxPlayers=atoi(buf); g_free(buf); | |
+ NewServer->Update=bgets(HttpSock); | |
+ NewServer->Comment=bgets(HttpSock); | |
+ NewServer->UpSince=bgets(HttpSock); | |
+ ServerList=g_slist_append(ServerList,NewServer); | |
+ } else { | |
+ if (strncmp(buf,"MetaServer:",11)==0) HeaderDone=TRUE; | |
+ g_free(buf); | |
+ } | |
+ } | |
+} | |
diff --git a/src/message.h b/src/message.h | |
t@@ -0,0 +1,143 @@ | |
+/* message.h Header file for Dopewars message-handling routines */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+ | |
+#ifndef __MESSAGE_H__ | |
+#define __MESSAGE_H__ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#include <glib.h> | |
+#include "dopewars.h" | |
+ | |
+#define C_PRINTMESSAGE 'A' | |
+#define C_LIST 'B' | |
+#define C_ENDLIST 'C' | |
+#define C_NEWNAME 'D' | |
+#define C_MSG 'E' | |
+#define C_MSGTO 'F' | |
+#define C_JOIN 'G' | |
+#define C_LEAVE 'H' | |
+#define C_SUBWAYFLASH 'I' | |
+#define C_UPDATE 'J' | |
+#define C_DRUGHERE 'K' | |
+#define C_GUNSHOP 'L' | |
+#define C_LOANSHARK 'M' | |
+#define C_BANK 'N' | |
+#define C_QUESTION 'O' | |
+#define C_HISCORE 'Q' | |
+#define C_STARTHISCORE 'R' | |
+#define C_ENDHISCORE 'S' | |
+#define C_BUYOBJECT 'T' | |
+#define C_DONE 'U' | |
+#define C_REQUESTJET 'V' | |
+#define C_PAYLOAN 'W' | |
+#define C_ANSWER 'X' | |
+#define C_DEPOSIT 'Y' | |
+#define C_PUSH 'Z' | |
+#define C_QUIT 'a' | |
+#define C_RENAME 'b' | |
+#define C_NAME 'c' | |
+#define C_SACKBITCH 'd' | |
+#define C_TIPOFF 'e' | |
+#define C_SPYON 'f' | |
+#define C_WANTQUIT 'g' | |
+#define C_CONTACTSPY 'h' | |
+#define C_KILL 'i' | |
+#define C_REQUESTSCORE 'j' | |
+#define C_INIT 'k' | |
+#define C_DATA 'l' | |
+#define C_FIGHTPRINT 'm' | |
+#define C_FIGHTACT 'n' | |
+#define C_TRADE 'o' | |
+#define C_CHANGEDISP 'p' | |
+#define C_NETMESSAGE 'q' | |
+ | |
+#define C_NONE 'A' | |
+#define C_ASKLOAN 'B' | |
+#define C_COPS 'C' | |
+#define C_ASKBITCH 'D' | |
+#define C_ASKGUN 'E' | |
+#define C_ASKGUNSHOP 'F' | |
+#define C_ASKPUB 'G' | |
+#define C_ASKBANK 'H' | |
+#define C_ASKRUN 'I' | |
+#define C_ASKRUNFIGHT 'J' | |
+#define C_ASKSEW 'K' | |
+#define C_MEETPLAYER 'L' | |
+ | |
+#define DT_LOCATION 'A' | |
+#define DT_DRUG 'B' | |
+#define DT_GUN 'C' | |
+#define DT_PRICES 'D' | |
+ | |
+void SendClientMessage(Player *From,char AICode,char Code, | |
+ Player *To,char *Data,Player *BufOwn); | |
+void SendServerMessage(Player *From,char AICode,char Code, | |
+ Player *To,char *Data); | |
+void SendPrintMessage(Player *From,char AICode,Player *To,char *Data); | |
+void SendQuestion(Player *From,char AICode,Player *To,char *Data); | |
+ | |
+#if NETWORKING | |
+gchar *ReadFromConnectionBuffer(Player *Play); | |
+gboolean ReadConnectionBufferFromWire(Player *Play); | |
+void WriteToConnectionBuffer(Player *Play,gchar *data); | |
+gboolean WriteConnectionBufferToWire(Player *Play); | |
+gchar *bgets(int fd); | |
+#endif /* NETWORKING */ | |
+ | |
+extern GSList *FirstClient; | |
+ | |
+extern void (*ClientMessageHandlerPt) (char *,Player *); | |
+extern void (*SocketWriteTestPt) (Player *,gboolean); | |
+ | |
+void chomp(char *str); | |
+void BroadcastToClients(char AICode,char Code,char *Data,Player *From, | |
+ Player *Except); | |
+void SendInventory(Player *From,char AICode,char Code,Player *To, | |
+ Inventory *Guns,Inventory *Drugs); | |
+void ReceiveInventory(char *Data,Inventory *Guns,Inventory *Drugs); | |
+void SendPlayerData(Player *To); | |
+void SendSpyReport(Player *To,Player *SpiedOn); | |
+void ReceivePlayerData(char *text,Player *From); | |
+void SendInitialData(Player *To); | |
+void ReceiveInitialData(char *data); | |
+void SendMiscData(Player *To); | |
+void ReceiveMiscData(char *Data); | |
+gchar *GetNextWord(gchar **Data,gchar *Default); | |
+void AssignNextWord(gchar **Data,gchar **Dest); | |
+int GetNextInt(gchar **Data,int Default); | |
+price_t GetNextPrice(gchar **Data,price_t Default); | |
+char *SetupNetwork(); | |
+void ShutdownNetwork(); | |
+void SwitchToSinglePlayer(Player *Play); | |
+int ProcessMessage(char *Msg,Player **From,char *AICode,char *Code, | |
+ Player **To,char **Data,GSList *First); | |
+void ReceiveDrugsHere(char *text,Player *To); | |
+gboolean HandleGenericClientMessage(Player *From,char AICode,char Code, | |
+ Player *To,char *Data,char *DisplayMode); | |
+char *OpenMetaServerConnection(int *HttpSock); | |
+void CloseMetaServerConnection(int HttpSock); | |
+void ClearServerList(); | |
+void ReadMetaServerData(int HttpSock); | |
+ | |
+#endif | |
diff --git a/src/serverside.c b/src/serverside.c | |
t@@ -0,0 +1,2209 @@ | |
+/* serverside.c Handles the server side of dopewars */ | |
+/* copyright (c) 1998-2000 ben webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#include <stdio.h> | |
+#include <string.h> | |
+#include <sys/types.h> | |
+#include <sys/stat.h> | |
+#ifdef HAVE_UNISTD_H | |
+#include <unistd.h> | |
+#endif | |
+#include <signal.h> | |
+#include <errno.h> | |
+#include <stdlib.h> | |
+#include <glib.h> | |
+#include "dopeos.h" | |
+#include "serverside.h" | |
+#include "dopewars.h" | |
+#include "message.h" | |
+ | |
+#ifdef HAVE_FCNTL_H | |
+#include <fcntl.h> | |
+#endif | |
+ | |
+#ifndef SD_SEND | |
+#define SD_SEND 1 | |
+#endif | |
+#ifndef SD_RECV | |
+#define SD_RECV 0 | |
+#endif | |
+ | |
+/* Maximum time, in seconds, between reports from this server to the */ | |
+/* metaserver. Setting this to be too small will most likely annoy the */ | |
+/* metaserver maintainer, and result in your host being blocked... ;) */ | |
+#define METATIME (1200) | |
+ | |
+int TerminateRequest,ReregisterRequest; | |
+ | |
+int MetaTimeout; | |
+char WantQuit=FALSE; | |
+ | |
+GSList *FirstServer=NULL; | |
+ | |
+static GScanner *Scanner; | |
+ | |
+/* Pointer to the filename of a pid file (if non-NULL) */ | |
+char *PidFile; | |
+ | |
+static char HelpText[] = { | |
+ N_("dopewars server version %s commands and settings\n\n" | |
+ "help Displays this help screen\n" | |
+ "list Lists all players logged on\n" | |
+ "push <player> Politely asks the named player to leave\n" | |
+ "kill <player> Abruptly breaks the connection with the " | |
+ "named player\n" | |
+ "msg:<mesg> Send message to all players\n" | |
+ "quit Gracefully quit, after notifying all players\n" | |
+ "<variable>=<value> Sets the named variable to the given value\n" | |
+ "<variable> Displays the value of the named variable\n" | |
+ "<list>[x].<var>=<value> Sets the named variable in the given list,\n" | |
+ " index x, to the given value\n" | |
+ "<list>[x].<var> Displays the value of the named list variable\… | |
+ "\nValid variables are listed below:-\n\n") | |
+}; | |
+ | |
+int SendSingleHighScore(Player *Play,struct HISCORE *Score, | |
+ int index,char Bold); | |
+ | |
+int SendToMetaServer(char Up,int MetaSock,char *data, | |
+ struct sockaddr_in *MetaAddr) { | |
+/* Sends server details, and any additional data, to the metaserver */ | |
+ GString *text; | |
+ int numbytes; | |
+ text=g_string_new(""); | |
+ g_string_sprintf(text,"R:%d\n%d\n%s\n%s", | |
+ METAVERSION,Port,MetaServer.LocalName,MetaServer.Password); | |
+ if (data) { g_string_append(text,"\n"); g_string_append(text,data); } | |
+ numbytes=sendto(MetaSock,text->str,strlen(text->str),0, | |
+ (struct sockaddr *)MetaAddr,sizeof(struct sockaddr)); | |
+ g_string_free(text,TRUE); | |
+ if (numbytes==-1) { | |
+ g_warning(_("cannot send data to metaserver\n")); | |
+ return 0; | |
+ } | |
+ return 1; | |
+} | |
+ | |
+void RegisterWithMetaServer(char Up,char SendData) { | |
+/* Sends server details to the metaserver, if specified. If "Up" is */ | |
+/* TRUE, informs the metaserver that the server is now accepting */ | |
+/* connections - otherwise tells the metaserver that this server is */ | |
+/* about to go down. If "SendData" is TRUE, then also sends game */ | |
+/* data (e.g. scores) to the metaserver. If networking is disabled, */ | |
+/* does nothing. */ | |
+#if NETWORKING | |
+ struct HISCORE MultiScore[NUMHISCORE],AntiqueScore[NUMHISCORE]; | |
+ struct sockaddr_in MetaAddr; | |
+ struct hostent *he; | |
+ int MetaSock; | |
+ gchar *text,*prstr; | |
+ int i; | |
+ if (!MetaServer.Active || !NotifyMetaServer) return; | |
+ if (SendData) { | |
+ g_message(_("Sending data to metaserver at %s\n"),MetaServer.Name); | |
+ } else { | |
+ g_message(_("Notifying metaserver at %s\n"),MetaServer.Name); | |
+ } | |
+ if ((he=gethostbyname(MetaServer.Name))==NULL) { | |
+ g_warning(_("cannot locate metaserver\n")); | |
+ return; | |
+ } | |
+ MetaSock=socket(AF_INET,SOCK_DGRAM,0); | |
+ if (MetaSock==-1) { | |
+ g_warning(_("cannot create socket for metaserver communication\n")); | |
+ return; | |
+ } | |
+ memset(&MetaAddr,0,sizeof(struct sockaddr_in)); | |
+ MetaAddr.sin_family=AF_INET; | |
+ MetaAddr.sin_port=htons(MetaServer.UdpPort); | |
+ MetaAddr.sin_addr=*((struct in_addr *)he->h_addr); | |
+ | |
+ text=g_strdup_printf("report\n%d\n%s\n%d\n%d\n%s", | |
+ Up ? 1 : 0,VERSION,CountPlayers(FirstServer), | |
+ MaxClients,MetaServer.Comment); | |
+ if (!SendToMetaServer(Up,MetaSock,text,&MetaAddr)) { | |
+ g_free(text); | |
+ return; | |
+ } | |
+ g_free(text); | |
+ | |
+ if (SendData) { | |
+ if (HighScoreRead(MultiScore,AntiqueScore)) { | |
+ for (i=0;i<NUMHISCORE;i++) { | |
+ text=g_strdup_printf("multi\n%d\n%s^%s^%s^%c", | |
+ i,prstr=FormatPrice(MultiScore[i].Money),MultiScore[i].Tim… | |
+ MultiScore[i].Name,MultiScore[i].Dead ? '1':'0'); | |
+ g_free(prstr); | |
+ if (!SendToMetaServer(Up,MetaSock,text,&MetaAddr)) { | |
+ g_free(text); | |
+ return; | |
+ } | |
+ g_free(text); | |
+ } | |
+ for (i=0;i<NUMHISCORE;i++) { | |
+ g_free(MultiScore[i].Name); g_free(MultiScore[i].Time); | |
+ g_free(AntiqueScore[i].Name); g_free(AntiqueScore[i].Time); | |
+ } | |
+ } else { g_warning(_("cannot read high score file\n")); } | |
+ } | |
+ CloseSocket(MetaSock); | |
+ MetaTimeout=time(NULL)+METATIME; | |
+#endif /* NETWORKING */ | |
+} | |
+ | |
+void HandleServerPlayer(Player *Play) { | |
+ gchar *buf; | |
+ gboolean MessageRead=FALSE; | |
+ while ((buf=ReadFromConnectionBuffer(Play))!=NULL) { | |
+ MessageRead=TRUE; | |
+ HandleServerMessage(buf,Play); | |
+ g_free(buf); | |
+ } | |
+/* Reset the idle timeout (if necessary) */ | |
+ if (MessageRead && IdleTimeout) { | |
+ Play->IdleTimeout=time(NULL)+(time_t)IdleTimeout; | |
+ } | |
+} | |
+ | |
+void HandleServerMessage(gchar *buf,Player *ReallyFrom) { | |
+/* Given a message "buf" which identifies itself as being from player */ | |
+/* "ReallyFrom" by the incoming socket, performs processing and sends */ | |
+/* suitable replies. */ | |
+ Player *From,*To,*tmp,*pt; | |
+ GSList *list; | |
+ char Code,*Data,AICode; | |
+ DopeEntry NewEntry; | |
+ int i; | |
+ price_t money; | |
+ | |
+ if (ProcessMessage(buf,&From,&AICode,&Code,&To,&Data,FirstServer)==-1) { | |
+ g_warning("Bad message"); | |
+ return; | |
+ } | |
+ if (From!=ReallyFrom && (From!=&Noone || | |
+ (Code!=C_NAME && Code!=C_NETMESSAGE))) { | |
+ g_warning(_("Message is lying about its origin\n%s: %c: %s: %s\n" | |
+ "Should be from %s"),From ? GetPlayerName(From) : "",Code, | |
+ To ? GetPlayerName(To) : "",Data, | |
+ ReallyFrom ? GetPlayerName(ReallyFrom) : "NULL"); | |
+ g_free(Data); | |
+ return; | |
+ } | |
+ switch(Code) { | |
+ case C_MSGTO: | |
+ if (Network) { | |
+ g_message("%s->%s: %s",GetPlayerName(From),GetPlayerName(To),Data); | |
+ } | |
+ SendServerMessage(From,AICode,Code,To,Data); | |
+ break; | |
+ case C_NETMESSAGE: | |
+ g_message("Net:%s\n",Data); | |
+/* shutdown(ReallyFrom->fd,SD_RECV);*/ | |
+/* Make sure they do actually disconnect, eventually! */ | |
+ if (ConnectTimeout) { | |
+ ReallyFrom->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; | |
+ } | |
+ break; | |
+ case C_NAME: | |
+ pt=GetPlayerByName(Data,FirstServer); | |
+ if (pt && pt!=From) { | |
+ if (ConnectTimeout) { | |
+ ReallyFrom->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; | |
+ } | |
+ SendServerMessage(NULL,C_NONE,C_NEWNAME,ReallyFrom,NULL); | |
+ } else if (((ReallyFrom && strlen(GetPlayerName(ReallyFrom))==0 && | |
+ Network) || (!Network && From==&Noone)) && Data[0]) { | |
+ if (CountPlayers(FirstServer)<MaxClients || !Network) { | |
+ SendInitialData(ReallyFrom); | |
+ SendMiscData(ReallyFrom); | |
+ if (!Network) { | |
+ From=g_new(Player,1); | |
+ FirstServer=AddPlayer(0,From,FirstServer); | |
+ } else From=ReallyFrom; | |
+ SetPlayerName(From,Data); | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ pt=(Player *)list->data; | |
+ if (pt!=From) { | |
+ SendServerMessage(NULL,C_NONE,C_LIST,From, | |
+ GetPlayerName(pt)); | |
+ } | |
+ } | |
+ SendServerMessage(NULL,C_NONE,C_ENDLIST,From,NULL); | |
+ RegisterWithMetaServer(TRUE,FALSE); | |
+ From->ConnectTimeout=0; | |
+ | |
+ if (Network) { | |
+ g_message(_("%s joins the game!"),GetPlayerName(From)); | |
+ } | |
+ BroadcastToClients(C_NONE,C_JOIN,GetPlayerName(From),NULL,From); | |
+ From->EventNum=E_ARRIVE; | |
+ SendPlayerData(From); | |
+ SendEvent(From); | |
+ } else { | |
+ From=ReallyFrom; | |
+ g_message(_("MaxClients (%d) exceeded - dropping connection"), | |
+ MaxClients); | |
+ sprintf(buf,_("Sorry, but this server has a limit of %d " | |
+"%s, which has been reached.^Please try connecting again later."), | |
+ MaxClients,MaxClients==1 ? _("player") : _("players")); | |
+ SendServerMessage(NULL,C_NONE,C_PRINTMESSAGE,From,buf); | |
+/* shutdown(From->fd,SD_RECV);*/ | |
+/* Make sure they do actually disconnect, eventually! */ | |
+ if (ConnectTimeout) { | |
+ From->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; | |
+ } | |
+ } | |
+ } else { | |
+ g_message(_("%s will now be known as %s"),GetPlayerName(From),Data… | |
+ BroadcastToClients(C_NONE,C_RENAME,Data,From,From); | |
+ SetPlayerName(From,Data); | |
+ } | |
+ break; | |
+ case C_WANTQUIT: | |
+ if (From->EventNum!=E_FINISH) FinishGame(From,NULL); | |
+ break; | |
+ case C_REQUESTJET: | |
+ i=atoi(Data); | |
+ if (From->EventNum==E_ATTACK || From->EventNum==E_DEFEND || | |
+ From->EventNum==E_WAITATTACK || From->EventNum==E_FREEFORALL) { | |
+ BreakoffCombat(From,FALSE); | |
+ } | |
+ if (NumTurns>0 && From->Turn>=NumTurns && From->EventNum!=E_FINISH) { | |
+ FinishGame(From,_("Your dealing time is up...")); | |
+ } else if (i!=From->IsAt && (NumTurns==0 || From->Turn<NumTurns) && | |
+ From->EventNum==E_NONE && From->Health>0) { | |
+ From->IsAt=(char)i; | |
+ From->Turn++; | |
+ From->Debt=(price_t)((float)From->Debt*1.1); | |
+ From->Bank=(price_t)((float)From->Bank*1.05); | |
+ SendPlayerData(From); | |
+ From->EventNum=E_SUBWAY; | |
+ SendEvent(From); | |
+ } else { | |
+ g_warning(_("%s: DENIED jet to %s"),GetPlayerName(From), | |
+ Location[i].Name); | |
+ } | |
+ break; | |
+ case C_REQUESTSCORE: | |
+ SendHighScores(From,FALSE,NULL); | |
+ break; | |
+ case C_CONTACTSPY: | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ if (tmp!=From && GetListEntry(&(tmp->SpyList),From)>=0) { | |
+ SendSpyReport(From,tmp); | |
+ } | |
+ } | |
+ break; | |
+ case C_DEPOSIT: | |
+ money=strtoprice(Data); | |
+ if (From->Bank+money >=0 && From->Cash-money >=0) { | |
+ From->Bank+=money; From->Cash-=money; | |
+ SendPlayerData(From); | |
+ } | |
+ break; | |
+ case C_PAYLOAN: | |
+ money=strtoprice(Data); | |
+ if (From->Debt-money >=0 && From->Cash-money >=0) { | |
+ From->Debt-=money; From->Cash-=money; | |
+ SendPlayerData(From); | |
+ } | |
+ break; | |
+ case C_BUYOBJECT: | |
+ BuyObject(From,Data); | |
+ break; | |
+ case C_FIGHTACT: | |
+ if (From->EventNum==E_ATTACK || From->EventNum==E_FREEFORALL) { | |
+ AttackPlayer(From,From->Attacked, | |
+ TotalGunsCarried(From)>0 ? AT_SHOOT : 0); | |
+ } else if (From->EventNum==E_DEFEND) { | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ if ((tmp->EventNum==E_FREEFORALL || tmp->EventNum==E_WAITATTACK… | |
+ && tmp->Attacked==From) { | |
+ AttackPlayer(From,tmp, | |
+ TotalGunsCarried(From)>0 ? AT_SHOOT : 0); | |
+ } | |
+ } | |
+ } | |
+ break; | |
+ case C_ANSWER: | |
+ HandleAnswer(From,To,Data); | |
+ break; | |
+ case C_DONE: | |
+ if (From->EventNum!=E_NONE && From->EventNum<E_OUTOFSYNC) { | |
+ From->EventNum++; SendEvent(From); | |
+ } | |
+ break; | |
+ case C_SPYON: | |
+ if (From->Cash >= Prices.Spy) { | |
+ g_message(_("%s now spying on %s"),GetPlayerName(From), | |
+ GetPlayerName(To)); | |
+ From->Cash -= Prices.Spy; | |
+ LoseBitch(From,NULL,NULL); | |
+ NewEntry.Play=From; NewEntry.Turns=-1; | |
+ AddListEntry(&(To->SpyList),&NewEntry); | |
+ SendPlayerData(From); | |
+ } else { | |
+ g_warning(_("%s spy on %s: DENIED"),GetPlayerName(From), | |
+ GetPlayerName(To)); | |
+ } | |
+ break; | |
+ case C_TIPOFF: | |
+ if (From->Cash >= Prices.Tipoff) { | |
+ g_message(_("%s tipped off the cops to %s"),GetPlayerName(From), | |
+ GetPlayerName(To)); | |
+ From->Cash -= Prices.Tipoff; | |
+ LoseBitch(From,NULL,NULL); | |
+ NewEntry.Play=From; NewEntry.Turns=0; | |
+ AddListEntry(&(To->TipList),&NewEntry); | |
+ SendPlayerData(From); | |
+ } else { | |
+ g_warning(_("%s tipoff about %s: DENIED"),GetPlayerName(From), | |
+ GetPlayerName(To)); | |
+ } | |
+ break; | |
+ case C_SACKBITCH: | |
+ LoseBitch(From,NULL,NULL); | |
+ SendPlayerData(From); | |
+ break; | |
+ case C_MSG: | |
+ if (Network) g_message("%s: %s",GetPlayerName(From),Data); | |
+ BroadcastToClients(C_NONE,C_MSG,Data,From,From); | |
+ break; | |
+ default: | |
+ g_warning("%s:%c:%s:%s",GetPlayerName(From),Code, | |
+ GetPlayerName(To),Data); | |
+ break; | |
+ } | |
+ g_free(Data); | |
+} | |
+ | |
+void ClientLeftServer(Player *Play) { | |
+/* Notifies all clients that player "Play" has left the game and */ | |
+/* cleans up after them if necessary. */ | |
+ Player *tmp; | |
+ GSList *list; | |
+ if (Play->EventNum==E_ATTACK || Play->EventNum==E_DEFEND || | |
+ Play->EventNum==E_WAITATTACK || Play->EventNum==E_FREEFORALL) { | |
+ BreakoffCombat(Play,TRUE); | |
+ } | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ if (tmp!=Play) { | |
+ RemoveAllEntries(&(tmp->TipList),Play); | |
+ RemoveAllEntries(&(tmp->SpyList),Play); | |
+ } | |
+ } | |
+ BroadcastToClients(C_NONE,C_LEAVE,GetPlayerName(Play),Play,Play); | |
+} | |
+ | |
+void CleanUpServer() { | |
+/* Closes down the server and frees up associated handles and memory */ | |
+ if (Server) RegisterWithMetaServer(FALSE,FALSE); | |
+ while (FirstServer) { | |
+ FirstServer=RemovePlayer((Player *)FirstServer->data,FirstServer); | |
+ } | |
+#if NETWORKING | |
+ if (Server) CloseSocket(ListenSock); | |
+#endif | |
+} | |
+ | |
+void ReregisterHandle(int sig) { | |
+/* Responds to a SIGUSR1 signal, and requests the main event loop to */ | |
+/* reregister the server with the dopewars metaserver. */ | |
+ ReregisterRequest=1; | |
+} | |
+ | |
+void BreakHandle(int sig) { | |
+/* Traps an attempt by the user to send dopewars a SIGTERM or SIGINT */ | |
+/* (e.g. pressing Ctrl-C) and signals for a "nice" shutdown. Restores */ | |
+/* the default signal action (to terminate without cleanup) so that */ | |
+/* the user can still close the program easily if this cleanup code */ | |
+/* then causes problems or long delays. */ | |
+ struct sigaction sact; | |
+ TerminateRequest=1; | |
+ sact.sa_handler=SIG_DFL; | |
+ sact.sa_flags=0; | |
+ sigaction(SIGTERM,&sact,NULL); | |
+ sigaction(SIGINT,&sact,NULL); | |
+} | |
+ | |
+void PrintHelpTo(FILE *fp) { | |
+/* Prints the server help screen to the given file pointer */ | |
+ int i; | |
+ GString *VarName; | |
+ VarName=g_string_new(""); | |
+ fprintf(fp,_(HelpText),VERSION); | |
+ for (i=0;i<NUMGLOB;i++) { | |
+ if (Globals[i].NameStruct[0]) { | |
+ g_string_sprintf(VarName,"%s%s.%s",Globals[i].NameStruct, | |
+ Globals[i].StructListPt ? "[x]" : "",Globals[i].Name… | |
+ } else { | |
+ g_string_assign(VarName,Globals[i].Name); | |
+ } | |
+ fprintf(fp,"%-26s %s\n",VarName->str,_(Globals[i].Help)); | |
+ } | |
+ fprintf(fp,"\n\n"); | |
+ g_string_free(VarName,TRUE); | |
+} | |
+ | |
+void ServerHelp() { | |
+/* Displays a simple help screen listing the server commands and options */ | |
+ int i; | |
+#ifdef CYGWIN | |
+ int Lines; | |
+ GString *VarName; | |
+ VarName=g_string_new(""); | |
+ g_print(_(HelpText),VERSION); | |
+ Lines=16; | |
+ for (i=0;i<NUMGLOB;i++) { | |
+ if (Globals[i].NameStruct[0]) { | |
+ g_string_sprintf(VarName,"%s%s.%s",Globals[i].NameStruct, | |
+ Globals[i].StructListPt ? "[x]" : "",Globals[i].Name… | |
+ } else { | |
+ g_string_assign(VarName,Globals[i].Name); | |
+ } | |
+ g_print("%-26s %s\n",VarName->str,_(Globals[i].Help)); | |
+ Lines++; | |
+ if (Lines%24==0) { | |
+ g_print(_("--More--")); bgetch(); g_print("\n"); | |
+ } | |
+ } | |
+ g_string_free(VarName,TRUE); | |
+#else | |
+ FILE *fp; | |
+ fp=popen(Pager,"w"); | |
+ if (fp) { | |
+ PrintHelpTo(fp); | |
+ i=pclose(fp); | |
+ if (i==-1 || (WIFEXITED(i) && WEXITSTATUS(i)==127)) { | |
+ g_warning(_("Pager exited abnormally - using stdout instead...")); | |
+ PrintHelpTo(stdout); | |
+ } | |
+ } | |
+#endif | |
+} | |
+ | |
+#if NETWORKING | |
+void CreatePidFile() { | |
+/* Creates a pid file (if "PidFile" is non-NULL) and writes the process */ | |
+/* ID into it */ | |
+ FILE *fp; | |
+ if (!PidFile) return; | |
+ fp=fopen(PidFile,"w"); | |
+ if (fp) { | |
+ g_message(_("Maintaining pid file %s"),PidFile); | |
+ fprintf(fp,"%ld\n",(long)getpid()); | |
+ fclose(fp); | |
+ chmod(PidFile,S_IREAD|S_IWRITE); | |
+ } else g_warning(_("Cannot create pid file %s"),PidFile); | |
+} | |
+ | |
+void RemovePidFile() { | |
+/* Removes the previously-created pid file "PidFile" */ | |
+ if (PidFile) unlink(PidFile); | |
+} | |
+ | |
+gboolean ReadServerKey(GString *LineBuf,gboolean *EndOfLine) { | |
+ int ch; | |
+ *EndOfLine=FALSE; | |
+#ifdef CYGWIN | |
+ ch=bgetch(); | |
+ if (ch=='\0') { | |
+ return FALSE; | |
+ } else if (ch=='\r') { | |
+ g_print("\n"); | |
+ *EndOfLine=TRUE; | |
+ return TRUE; | |
+ } else if (ch==8) { | |
+ if (strlen(LineBuf->str)>0) { | |
+ g_print("\010 \010"); | |
+ g_string_truncate(LineBuf,strlen(LineBuf->str)-1); | |
+ } | |
+ return TRUE; | |
+ } | |
+ g_string_append_c(LineBuf,(gchar)ch); | |
+ g_print("%c",ch); | |
+ return TRUE; | |
+#else | |
+ while (1) { | |
+ ch=getchar(); | |
+ if (ch==EOF) return FALSE; | |
+ else if (ch=='\n') { | |
+ *EndOfLine=TRUE; | |
+ break; | |
+ } | |
+ g_string_append_c(LineBuf,(gchar)ch); | |
+ } | |
+ return TRUE; | |
+#endif | |
+} | |
+ | |
+void StartServer() { | |
+ struct sockaddr_in ServerAddr; | |
+ struct sigaction sact; | |
+ Scanner=g_scanner_new(&ScannerConfig); | |
+ Scanner->input_name="(stdin)"; | |
+ if (!CheckHighScoreFile()) { | |
+ g_error(_("Cannot open high score file %s.\n" | |
+ "Either ensure you have permissions to access this file and " | |
+ "directory, or\nspecify an alternate high score file with " | |
+ "the -f command line option."),HiScoreFile); | |
+ } | |
+ CreatePidFile(); | |
+ | |
+/* Make the output line-buffered, so that the log file (if used) is */ | |
+/* updated regularly */ | |
+ fflush(stdout); | |
+ | |
+#ifdef SETVBUF_REVERSED /* 2nd and 3rd arguments are reversed on some systems … | |
+ setvbuf(stdout,_IOLBF,(char *)NULL,0); | |
+#else | |
+ setvbuf(stdout,(char *)NULL,_IOLBF,0); | |
+#endif | |
+ | |
+ Network=TRUE; | |
+ FirstServer=NULL; | |
+ SocketWriteTestPt=NULL; | |
+ ClientMessageHandlerPt=NULL; | |
+ ListenSock=socket(AF_INET,SOCK_STREAM,0); | |
+ if (ListenSock==SOCKET_ERROR) { | |
+ perror("create socket"); exit(1); | |
+ } | |
+ SetReuse(ListenSock); | |
+ fcntl(ListenSock,F_SETFL,O_NONBLOCK); | |
+ | |
+ ServerAddr.sin_family=AF_INET; | |
+ ServerAddr.sin_port=htons(Port); | |
+ ServerAddr.sin_addr.s_addr=INADDR_ANY; | |
+ memset(ServerAddr.sin_zero,0,sizeof(ServerAddr.sin_zero)); | |
+ if (bind(ListenSock,(struct sockaddr *)&ServerAddr, | |
+ sizeof(struct sockaddr)) == SOCKET_ERROR) { | |
+ perror("bind socket"); exit(1); | |
+ } | |
+ | |
+ g_print(_("dopewars server version %s ready and waiting for connections\n" | |
+ "on port %d. For assistance with server commands, enter the " | |
+ "command \"help\"\n"),VERSION,Port); | |
+ | |
+ if (listen(ListenSock,10)==SOCKET_ERROR) { | |
+ perror("listen socket"); exit(1); | |
+ } | |
+ | |
+ MetaTimeout=0; | |
+ | |
+ TerminateRequest=ReregisterRequest=0; | |
+ | |
+#if !CYGWIN | |
+ sact.sa_handler=ReregisterHandle; | |
+ sact.sa_flags=0; | |
+ sigemptyset(&sact.sa_mask); | |
+ if (sigaction(SIGUSR1,&sact,NULL)==-1) { | |
+ g_warning(_("Cannot install SIGUSR1 interrupt handler!")); | |
+ } | |
+ sact.sa_handler=BreakHandle; | |
+ sact.sa_flags=0; | |
+ sigemptyset(&sact.sa_mask); | |
+ if (sigaction(SIGINT,&sact,NULL)==-1) { | |
+ g_warning(_("Cannot install SIGINT interrupt handler!")); | |
+ } | |
+ if (sigaction(SIGTERM,&sact,NULL)==-1) { | |
+ g_warning(_("Cannot install SIGTERM interrupt handler!")); | |
+ } | |
+ if (sigaction(SIGHUP,&sact,NULL)==-1) { | |
+ g_warning(_("Cannot install SIGHUP interrupt handler!")); | |
+ } | |
+ sact.sa_handler=SIG_IGN; | |
+ sact.sa_flags=0; | |
+ if (sigaction(SIGPIPE,&sact,NULL)==-1) { | |
+ g_warning(_("Cannot install pipe handler!")); | |
+ } | |
+#endif | |
+ | |
+ RegisterWithMetaServer(TRUE,TRUE); | |
+} | |
+ | |
+gboolean HandleServerCommand(char *string) { | |
+ GSList *list; | |
+ Player *tmp; | |
+ g_scanner_input_text(Scanner,string,strlen(string)); | |
+ if (!ParseNextConfig(Scanner)) { | |
+ if (strcasecmp(string,"help")==0 || strcasecmp(string,"h")==0 || | |
+ strcmp(string,"?")==0) { | |
+ ServerHelp(); | |
+ } else if (strcasecmp(string,"quit")==0) { | |
+ if (!FirstServer) return TRUE; | |
+ WantQuit=TRUE; | |
+ BroadcastToClients(C_NONE,C_QUIT,NULL,NULL,NULL); | |
+ } else if (strncasecmp(string,"msg:",4)==0) { | |
+ BroadcastToClients(C_NONE,C_MSG,string+4,NULL,NULL); | |
+ } else if (strcasecmp(string,"list")==0) { | |
+ if (FirstServer) { | |
+ g_print(_("Users currently logged on:-\n")); | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ g_print("%s\n",GetPlayerName(tmp)); | |
+ } | |
+ } else g_message(_("No users currently logged on!")); | |
+ } else if (strncasecmp(string,"push ",5)==0) { | |
+ tmp=GetPlayerByName(string+5,FirstServer); | |
+ if (tmp) { | |
+ g_message(_("Pushing %s"),GetPlayerName(tmp)); | |
+ SendServerMessage(NULL,C_NONE,C_PUSH,tmp,NULL); | |
+ } else g_warning(_("No such user!")); | |
+ } else if (strncasecmp(string,"kill ",5)==0) { | |
+ tmp=GetPlayerByName(string+5,FirstServer); | |
+ if (tmp) { | |
+ g_message(_("%s killed"),GetPlayerName(tmp)); | |
+ BroadcastToClients(C_NONE,C_KILL,GetPlayerName(tmp),tmp, | |
+ (Player *)FirstServer->data); | |
+ FirstServer=RemovePlayer(tmp,FirstServer); | |
+ } else g_warning(_("No such user!")); | |
+ } else { | |
+ g_warning(_("Unknown command - try \"help\" for help...")); | |
+ } | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+void HandleNewConnection() { | |
+ int cadsize; | |
+ int ClientSock; | |
+ struct sockaddr_in ClientAddr; | |
+ Player *tmp; | |
+ cadsize=sizeof(struct sockaddr); | |
+ if ((ClientSock=accept(ListenSock,(struct sockaddr *)&ClientAddr, | |
+ &cadsize))==-1) { | |
+ perror("accept socket"); bgetch(); exit(1); | |
+ } | |
+ fcntl(ClientSock,F_SETFL,O_NONBLOCK); | |
+ g_message(_("got connection from %s"),inet_ntoa(ClientAddr.sin_addr)); | |
+ tmp=g_new(Player,1); | |
+ FirstServer=AddPlayer(ClientSock,tmp,FirstServer); | |
+ if (ConnectTimeout) { | |
+ tmp->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; | |
+ } | |
+} | |
+ | |
+void StopServer() { | |
+ g_scanner_destroy(Scanner); | |
+ CleanUpServer(); | |
+ RemovePidFile(); | |
+} | |
+ | |
+gboolean RemovePlayerFromServer(Player *Play,gboolean WantQuit) { | |
+ if (!WantQuit && strlen(GetPlayerName(Play))>0) { | |
+ g_message(_("%s leaves the server!"),GetPlayerName(Play)); | |
+ ClientLeftServer(Play); | |
+/* Blank the name, so that CountPlayers ignores this player */ | |
+ SetPlayerName(Play,NULL); | |
+/* Report the new high scores (if any) and the new number of players | |
+ to the metaserver */ | |
+ RegisterWithMetaServer(TRUE,TRUE); | |
+ } | |
+ FirstServer=RemovePlayer(Play,FirstServer); | |
+ return (!FirstServer && WantQuit); | |
+} | |
+ | |
+void ServerLoop() { | |
+/* Initialises server, processes network and interactive messages, and */ | |
+/* finally cleans up the server on exit. */ | |
+ Player *tmp; | |
+ GSList *list,*nextlist; | |
+ fd_set readfs,writefs,errorfs; | |
+ int topsock; | |
+ char WantQuit=FALSE; | |
+ char InputClosed=FALSE; | |
+ struct timeval timeout; | |
+ int MinTimeout; | |
+ GString *LineBuf; | |
+ gboolean EndOfLine; | |
+ | |
+ StartServer(); | |
+ | |
+ LineBuf=g_string_new(""); | |
+ while (1) { | |
+ FD_ZERO(&readfs); | |
+ FD_ZERO(&writefs); | |
+ FD_ZERO(&errorfs); | |
+ if (!InputClosed) FD_SET(0,&readfs); | |
+ FD_SET(ListenSock,&readfs); | |
+ FD_SET(ListenSock,&errorfs); | |
+ topsock=ListenSock+1; | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ tmp=(Player *)list->data; | |
+ if (tmp->fd>0) { | |
+ FD_SET(tmp->fd,&readfs); | |
+ if (tmp->WriteBuf.DataPresent) FD_SET(tmp->fd,&writefs); | |
+ FD_SET(tmp->fd,&errorfs); | |
+ if (tmp->fd>=topsock) topsock=tmp->fd+1; | |
+ } | |
+ } | |
+ MinTimeout=GetMinimumTimeout(FirstServer); | |
+ if (MinTimeout!=-1) { | |
+ timeout.tv_sec=MinTimeout; | |
+ timeout.tv_usec=0; | |
+ } | |
+ if (bselect(topsock,&readfs,&writefs,&errorfs, | |
+ MinTimeout==-1 ? NULL : &timeout)==-1) { | |
+ if (errno==EINTR) { | |
+ if (ReregisterRequest) { | |
+ ReregisterRequest=0; | |
+ RegisterWithMetaServer(TRUE,TRUE); | |
+ continue; | |
+ } else if (TerminateRequest) break; else continue; | |
+ } | |
+ perror("select"); bgetch(); break; | |
+ } | |
+ FirstServer=HandleTimeouts(FirstServer); | |
+ if (FD_ISSET(0,&readfs)) { | |
+ if (ReadServerKey(LineBuf,&EndOfLine)==FALSE) { | |
+ if (isatty(0)) { | |
+ break; | |
+ } else { | |
+ g_message(_("Standard input closed.")); | |
+ InputClosed=TRUE; | |
+ } | |
+ } else if (EndOfLine) { | |
+ if (HandleServerCommand(LineBuf->str)) break; | |
+ g_string_truncate(LineBuf,0); | |
+ } | |
+ } | |
+ if (FD_ISSET(ListenSock,&readfs)) { | |
+ HandleNewConnection(); | |
+ } | |
+ list=FirstServer; | |
+ while (list) { | |
+ nextlist=g_slist_next(list); | |
+ tmp=(Player *)list->data; | |
+ if (tmp && FD_ISSET(tmp->fd,&errorfs)) { | |
+ g_warning("socket error from client: %d",tmp->fd); | |
+ CleanUpServer(); bgetch(); break; | |
+ } | |
+ if (tmp && FD_ISSET(tmp->fd,&writefs)) { | |
+/* Try and empty the player's write buffer */ | |
+ if (!WriteConnectionBufferToWire(tmp)) { | |
+/* The socket has been shut down, or the buffer was filled - remove player */ | |
+ if (RemovePlayerFromServer(tmp,WantQuit)) break; | |
+ tmp=NULL; | |
+ } | |
+ } | |
+ if (tmp && FD_ISSET(tmp->fd,&readfs)) { | |
+/* Read any waiting data into the player's read buffer */ | |
+ if (!ReadConnectionBufferFromWire(tmp)) { | |
+/* remove player! */ | |
+ if (RemovePlayerFromServer(tmp,WantQuit)) break; | |
+ tmp=NULL; | |
+ } else { | |
+/* If any complete messages were read, process them */ | |
+ HandleServerPlayer(tmp); | |
+ } | |
+ } | |
+ list=nextlist; | |
+ } | |
+ } | |
+ StopServer(); | |
+ g_string_free(LineBuf,TRUE); | |
+} | |
+#endif /* NETWORKING */ | |
+ | |
+void FinishGame(Player *Play,char *Message) { | |
+/* Tells player "Play" that the game is over; display "Message" */ | |
+ ClientLeftServer(Play); | |
+ Play->EventNum=E_FINISH; | |
+ SendHighScores(Play,TRUE,Message); | |
+/* shutdown(Play->fd,SD_RECV);*/ | |
+/* Make sure they do actually disconnect, eventually! */ | |
+ if (ConnectTimeout) { | |
+ Play->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; | |
+ } | |
+} | |
+ | |
+void HighScoreTypeRead(struct HISCORE *HiScore,FILE *fp) { | |
+/* Reads a batch of NUMHISCORE high scores into "HiScore" from "fp" */ | |
+ int i; | |
+ char *buf; | |
+ for (i=0;i<NUMHISCORE;i++) { | |
+ if (read_string(fp,&HiScore[i].Name)==EOF) break; | |
+ read_string(fp,&HiScore[i].Time); | |
+ read_string(fp,&buf); | |
+ HiScore[i].Money=strtoprice(buf); g_free(buf); | |
+ HiScore[i].Dead=fgetc(fp); | |
+ } | |
+} | |
+ | |
+void HighScoreTypeWrite(struct HISCORE *HiScore,FILE *fp) { | |
+/* Writes out a batch of NUMHISCORE high scores from "HiScore" to "fp" */ | |
+ int i; | |
+ gchar *text; | |
+ for (i=0;i<NUMHISCORE;i++) { | |
+ if (HiScore[i].Name) { | |
+ fwrite(HiScore[i].Name,strlen(HiScore[i].Name)+1,1,fp); | |
+ } else fputc(0,fp); | |
+ if (HiScore[i].Time) { | |
+ fwrite(HiScore[i].Time,strlen(HiScore[i].Time)+1,1,fp); | |
+ } else fputc(0,fp); | |
+ text=pricetostr(HiScore[i].Money); | |
+ fwrite(text,strlen(text)+1,1,fp); | |
+ g_free(text); | |
+ fputc(HiScore[i].Dead,fp); | |
+ } | |
+} | |
+ | |
+gboolean CheckHighScoreFile() { | |
+/* Tests to see whether the high score file is is read-and-writable */ | |
+ FILE *fp; | |
+ fp=fopen(HiScoreFile,"a+"); | |
+ if (fp) { | |
+ fclose(fp); | |
+ return TRUE; | |
+ } else { | |
+ return FALSE; | |
+ } | |
+} | |
+ | |
+int HighScoreRead(struct HISCORE *MultiScore,struct HISCORE *AntiqueScore) { | |
+/* Reads all the high scores into MultiScore and */ | |
+/* AntiqueScore (antique mode scores). Returns 1 on success, 0 on failure. */ | |
+ FILE *fp; | |
+ memset(MultiScore,0,sizeof(struct HISCORE)*NUMHISCORE); | |
+ memset(AntiqueScore,0,sizeof(struct HISCORE)*NUMHISCORE); | |
+ fp=fopen(HiScoreFile,"r"); | |
+ if (fp) { | |
+ HighScoreTypeRead(AntiqueScore,fp); | |
+ HighScoreTypeRead(MultiScore,fp); | |
+ fclose(fp); | |
+ } else return 0; | |
+ return 1; | |
+} | |
+ | |
+int HighScoreWrite(struct HISCORE *MultiScore,struct HISCORE *AntiqueScore) { | |
+/* Writes out all the high scores from MultiScore and AntiqueScore; returns */ | |
+/* 1 on success, 0 on failure. */ | |
+ FILE *fp; | |
+ fp=fopen(HiScoreFile,"w"); | |
+ if (fp) { | |
+ HighScoreTypeWrite(AntiqueScore,fp); | |
+ HighScoreTypeWrite(MultiScore,fp); | |
+ fclose(fp); | |
+ } else return 0; | |
+ return 1; | |
+} | |
+ | |
+void SendHighScores(Player *Play,char EndGame,char *Message) { | |
+/* Adds "Play" to the high score list if necessary, and then sends the */ | |
+/* scores over the network to "Play" */ | |
+/* If "EndGame" is TRUE, add the current score if it's high enough and */ | |
+/* display an explanatory message. "Message" is tacked onto the start */ | |
+/* if it's non-NULL. The client is then informed that the game's over. */ | |
+ struct HISCORE MultiScore[NUMHISCORE],AntiqueScore[NUMHISCORE],Score; | |
+ struct HISCORE *HiScore; | |
+ struct tm *timep; | |
+ time_t tim; | |
+ GString *text; | |
+ int i,j,InList=-1; | |
+ text=g_string_new(""); | |
+ if (!HighScoreRead(MultiScore,AntiqueScore)) { | |
+ g_warning(_("Unable to read high score file %s"),HiScoreFile); | |
+ } | |
+ if (Message) { | |
+ g_string_assign(text,Message); | |
+ if (strlen(text->str)>0) g_string_append_c(text,'^'); | |
+ } | |
+ if (WantAntique) HiScore=AntiqueScore; else HiScore=MultiScore; | |
+ if (EndGame) { | |
+ Score.Money=Play->Cash+Play->Bank-Play->Debt; | |
+ Score.Name=g_strdup(GetPlayerName(Play)); | |
+ if (Play->Health==0) Score.Dead=1; else Score.Dead=0; | |
+ tim=time(NULL); | |
+ timep=gmtime(&tim); | |
+ Score.Time=g_new(char,80); /* Yuck! */ | |
+ strftime(Score.Time,80,"%d-%m-%Y",timep); | |
+ for (i=0;i<NUMHISCORE;i++) { | |
+ if (InList==-1 && (Score.Money > HiScore[i].Money || | |
+ !HiScore[i].Time || HiScore[i].Time[0]==0)) { | |
+ InList=i; | |
+ g_string_append(text, | |
+ _("Congratulations! You made the high scores!")); | |
+ SendPrintMessage(NULL,C_NONE,Play,text->str); | |
+ g_free(HiScore[NUMHISCORE-1].Name); | |
+ g_free(HiScore[NUMHISCORE-1].Time); | |
+ for (j=NUMHISCORE-1;j>i;j--) { | |
+ memcpy(&HiScore[j],&HiScore[j-1],sizeof(struct HISCORE)); | |
+ } | |
+ memcpy(&HiScore[i],&Score,sizeof(struct HISCORE)); | |
+ break; | |
+ } | |
+ } | |
+ if (InList==-1) { | |
+ g_string_append(text, | |
+ _("You didn't even make the high score table...")); | |
+ SendPrintMessage(NULL,C_NONE,Play,text->str); | |
+ } | |
+ } | |
+ SendServerMessage(NULL,C_NONE,C_STARTHISCORE,Play,NULL); | |
+ | |
+ j=0; | |
+ for (i=0;i<NUMHISCORE;i++) { | |
+ if (SendSingleHighScore(Play,&HiScore[i],j,InList==i)) j++; | |
+ } | |
+ if (InList==-1 && EndGame) SendSingleHighScore(Play,&Score,j,1); | |
+ SendServerMessage(NULL,C_NONE,C_ENDHISCORE,Play,EndGame ? "end" : NULL); | |
+ if (!EndGame) SendDrugsHere(Play,FALSE); | |
+ if (EndGame && !HighScoreWrite(MultiScore,AntiqueScore)) { | |
+ g_warning(_("Unable to write high score file %s"),HiScoreFile); | |
+ } | |
+ for (i=0;i<NUMHISCORE;i++) { | |
+ g_free(MultiScore[i].Name); g_free(MultiScore[i].Time); | |
+ g_free(AntiqueScore[i].Name); g_free(AntiqueScore[i].Time); | |
+ } | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+int SendSingleHighScore(Player *Play,struct HISCORE *Score, | |
+ int index,char Bold) { | |
+/* Sends a single high score in "Score" with position "index" to player */ | |
+/* "Play". If Bold is TRUE, instructs the client to display the score in */ | |
+/* bold text. */ | |
+ gchar *Data,*prstr; | |
+ if (!Score->Time || Score->Time[0]==0) return 0; | |
+ Data=g_strdup_printf("%d^%c%c%18s %-14s %-34s %8s%c",index, | |
+ Bold ? 'B' : 'N',Bold ? '>' : ' ', | |
+ prstr=FormatPrice(Score->Money), | |
+ Score->Time,Score->Name,Score->Dead ? _("(R.I.P.)") :"… | |
+ Bold ? '<' : ' '); | |
+ SendServerMessage(NULL,C_NONE,C_HISCORE,Play,Data); | |
+ g_free(prstr); g_free(Data); | |
+ return 1; | |
+} | |
+ | |
+void SendEvent(Player *To) { | |
+/* In order for the server to keep track of the state of each client, each … | |
+/* client's state is identified by its EventNum data member. So, for example, … | |
+/* there is a state for fighting the cops, a state for going to the bank, and … | |
+/* so on. This function instructs client player "To" to carry out the actions … | |
+/* expected of it in its current state. It is the client's responsibility to … | |
+/* ensure that it carries out the correct actions to advance itself to the … | |
+/* "next" state; if it fails in this duty it will hang! … | |
+ price_t Money; | |
+ int i,j; | |
+ gchar *text; | |
+ Player *Play; | |
+ GSList *list; | |
+ gchar *prstr; | |
+ if (!To) return; | |
+ if (To->EventNum==E_MAX) To->EventNum=E_NONE; | |
+ if (To->EventNum==E_NONE || To->EventNum>=E_OUTOFSYNC) return; | |
+ Money=To->Cash+To->Bank-To->Debt; | |
+ | |
+ ClearPrices(To); | |
+ | |
+ while (To->EventNum<E_MAX) { | |
+ switch (To->EventNum) { | |
+ case E_SUBWAY: | |
+ SendServerMessage(NULL,C_NONE,C_SUBWAYFLASH,To,NULL); | |
+ break; | |
+ case E_OFFOBJECT: | |
+ for (i=0;i<To->TipList.Number;i++) { | |
+ g_message(_("%s: Tipoff from %s"),GetPlayerName(To), | |
+ GetPlayerName(To->TipList.Data[i].Play)); | |
+ To->OnBehalfOf=To->TipList.Data[i].Play; | |
+ SendCopOffer(To,FORCECOPS); | |
+ return; | |
+ } | |
+ for (i=0;i<To->SpyList.Number;i++) { | |
+ if (To->SpyList.Data[i].Turns<0) { | |
+ To->OnBehalfOf=To->SpyList.Data[i].Play; | |
+ SendCopOffer(To,FORCEBITCH); | |
+ return; | |
+ } | |
+ To->SpyList.Data[i].Turns++; | |
+ if (To->SpyList.Data[i].Turns>3 && | |
+ brandom(0,100)<10+To->SpyList.Data[i].Turns) { | |
+ if (TotalGunsCarried(To) > 0) j=brandom(0,NUMDISCOVER); | |
+ else j=brandom(0,NUMDISCOVER-1); | |
+ text=g_strdup_printf(_("One of your %s was spying for %s." | |
+ "^The spy %s!"),Names.Bitches, | |
+ GetPlayerName(To->SpyList.Data[i].Play… | |
+ _(Discover[j])); | |
+ if (j!=DEFECT) LoseBitch(To,NULL,NULL); | |
+ SendPlayerData(To); | |
+ SendPrintMessage(NULL,C_NONE,To,text); | |
+ g_free(text); | |
+ text=g_strdup_printf(_("Your spy working with %s has " | |
+ "been discovered!^The spy %s!"), | |
+ GetPlayerName(To),_(Discover[j])); | |
+ if (j==ESCAPE) GainBitch(To->SpyList.Data[i].Play); | |
+ To->SpyList.Data[i].Play->Flags &= ~SPYINGON; | |
+ SendPlayerData(To->SpyList.Data[i].Play); | |
+ SendPrintMessage(NULL,C_NONE, | |
+ To->SpyList.Data[i].Play,text); | |
+ g_free(text); | |
+ RemoveListEntry(&(To->SpyList),i); | |
+ i--; | |
+ } | |
+ } | |
+ if (Money>3000000) i=130; | |
+ else if (Money>1000000) i=115; | |
+ else i=100; | |
+ if (brandom(0,i)>75) { | |
+ if (SendCopOffer(To,NOFORCE)) return; | |
+ } | |
+ break; | |
+ case E_SAYING: | |
+ if (!Sanitized && (brandom(0,100) < 15)) { | |
+ if (brandom(0,100)<50) { | |
+ text=g_strdup_printf(_(" The lady next to you on the subway " | |
+ "said,^ \"%s\"%s"), | |
+ SubwaySaying[brandom(0,NumSubway)],brandom(0,100)<30 ? | |
+ _("^ (at least, you -think- that's what she said)") : ""… | |
+ } else { | |
+ text=g_strdup_printf(_(" You hear someone playing %s"), | |
+ Playing[brandom(0,NumPlaying)]); | |
+ } | |
+ SendPrintMessage(NULL,C_NONE,To,text); | |
+ g_free(text); | |
+ } | |
+ break; | |
+ case E_LOANSHARK: | |
+ if (To->IsAt+1==LoanSharkLoc && To->Debt>0) { | |
+ text=g_strdup_printf(_("YN^Would you like to visit %s?"), | |
+ Names.LoanSharkName); | |
+ SendQuestion(NULL,C_ASKLOAN,To,text); | |
+ g_free(text); | |
+ return; | |
+ } | |
+ break; | |
+ case E_BANK: | |
+ if (To->IsAt+1==BankLoc) { | |
+ text=g_strdup_printf(_("YN^Would you like to visit %s?"), | |
+ Names.BankName); | |
+ SendQuestion(NULL,C_ASKBANK,To,text); | |
+ g_free(text); | |
+ return; | |
+ } | |
+ break; | |
+ case E_GUNSHOP: | |
+ if (To->IsAt+1==GunShopLoc && !Sanitized && !WantAntique) { | |
+ text=g_strdup_printf(_("YN^Would you like to visit %s?"), | |
+ Names.GunShopName); | |
+ SendQuestion(NULL,C_ASKGUNSHOP,To,text); | |
+ g_free(text); | |
+ return; | |
+ } | |
+ break; | |
+ case E_ROUGHPUB: | |
+ if (To->IsAt+1==RoughPubLoc && !WantAntique) { | |
+ text=g_strdup_printf(_("YN^Would you like to visit %s?"), | |
+ Names.RoughPubName); | |
+ SendQuestion(NULL,C_ASKPUB,To,text); | |
+ g_free(text); | |
+ return; | |
+ } | |
+ break; | |
+ case E_HIREBITCH: | |
+ if (To->IsAt+1==RoughPubLoc && !WantAntique) { | |
+ To->Bitches.Price=brandom(Bitch.MinPrice,Bitch.MaxPrice); | |
+ text=g_strdup_printf( | |
+ _("YN^^Would you like to hire %s %s for %s?"), | |
+ StartsWithVowel(Names.Bitch) ? _("an") : _("a"), | |
+ Names.Bitch,prstr=FormatPrice(To->Bitches.Price)); | |
+ SendQuestion(NULL,C_ASKBITCH,To,text); | |
+ g_free(text); g_free(prstr); | |
+ return; | |
+ } | |
+ break; | |
+ case E_ARRIVE: | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ Play=(Player *)list->data; | |
+ if (Play!=To && Play->IsAt==To->IsAt && | |
+ Play->EventNum==E_NONE && TotalGunsCarried(To)>0) { | |
+ text=g_strdup_printf(_("AE^%s is already here!^" | |
+ "Do you Attack, or Evade?"), | |
+ GetPlayerName(Play)); | |
+ To->Attacked=Play; | |
+ SendDrugsHere(To,TRUE); | |
+ SendQuestion(NULL,C_MEETPLAYER,To,text); | |
+ g_free(text); | |
+ return; | |
+ } | |
+ } | |
+ SendDrugsHere(To,TRUE); | |
+ break; | |
+ } | |
+ To->EventNum++; | |
+ } | |
+ if (To->EventNum >= E_MAX) To->EventNum=E_NONE; | |
+} | |
+ | |
+int SendCopOffer(Player *To,char Force) { | |
+/* In response to client player "To" being in state E_OFFOBJECT, */ | |
+/* randomly engages the client in combat with the cops or offers */ | |
+/* other random events. Returns 0 if the client should then be */ | |
+/* advanced to the next state, 1 otherwise (i.e. if there are */ | |
+/* questions pending which the client must answer first) */ | |
+/* If Force==FORCECOPS, engage in combat with the cops for certain */ | |
+/* If Force==FORCEBITCH, offer the client a bitch for certain */ | |
+ int i; | |
+ i=brandom(0,100); | |
+ if (Force==FORCECOPS) i=100; | |
+ else if (Force==FORCEBITCH) i=0; | |
+ else To->OnBehalfOf=NULL; | |
+ if (i<33) { | |
+ return(OfferObject(To,Force==FORCEBITCH)); | |
+ } else if (i<50) { return(RandomOffer(To)); | |
+ } else if (Sanitized) { return 0; | |
+ } else { | |
+ StartOfficerHardass(To,To->EventNum+1,NULL,NULL); | |
+ } | |
+ return 1; | |
+} | |
+ | |
+void StartOfficerHardass(Player *Play,int ResyncNum, | |
+ char *LoneMessage,char *DeputyMessage) { | |
+/* Starts combat between player "Play" and the cops. "ResyncNum" is */ | |
+/* the event number to be returned to after combat is complete. */ | |
+/* "LoneMessage" and "DeputyMessage" are the format strings passed */ | |
+/* to OfficerHardass if they are non-NULL. */ | |
+ price_t Money; | |
+ if (!Play) return; | |
+ Money=Play->Cash+Play->Bank-Play->Debt; | |
+ if (Money>3000000) Play->Cops=brandom(11,27); | |
+ else if (Money>1000000) Play->Cops=brandom(7,14); | |
+ else if (Money>500000) Play->Cops=brandom(6,12); | |
+ else if (Money>100000) Play->Cops=brandom(2,8); | |
+ else Play->Cops=brandom(1,5); | |
+ | |
+ Play->ResyncNum=ResyncNum; | |
+ Play->EventNum=E_COPS; | |
+ if (Play->ResyncNum==E_MAX || Play->ResyncNum==E_NONE) { | |
+ SendServerMessage(NULL,C_NONE,C_CHANGEDISP,Play,"N"); | |
+ } | |
+ OfficerHardass(Play,LoneMessage,DeputyMessage); | |
+} | |
+ | |
+void OfficerHardass(Player *Play,char *LoneMessage,char *DeputyMessage) { | |
+/* Send client "Play" a message announcing the attack of the cops */ | |
+/* The format string used for this purpose can be altered by */ | |
+/* passing non-NULL "LoneMessage" (for unaccompanied Officer */ | |
+/* Hardass) and/or "DeputyMessage" (for him with x deputies) */ | |
+ char LoneDefault[] = { N_("YN^Officer %s is chasing you!") }; | |
+ char DeputyDefault[] = { | |
+ N_("YN^Officer %s and %d of his deputies are chasing you!") | |
+ }; | |
+ char *OfficerName; | |
+ GString *text; | |
+ | |
+ if (!Play || Play->EventNum!=E_COPS) return; | |
+ if (Play->Cops==0) { | |
+ Play->EventNum=Play->ResyncNum; SendEvent(Play); return; | |
+ } | |
+ text=g_string_new(NULL); | |
+ OfficerName=(Play->Flags&DEADHARDASS ? Names.ReserveOfficer : | |
+ Names.Officer); | |
+ if (Play->Cops==1) { | |
+ g_string_sprintf(text,LoneMessage ? LoneMessage : _(LoneDefault), | |
+ OfficerName); | |
+ } else { | |
+ g_string_sprintf(text,DeputyMessage ? DeputyMessage : _(DeputyDefault), | |
+ OfficerName, Play->Cops - 1); | |
+ } | |
+ SendPlayerData(Play); | |
+ if (TotalGunsCarried(Play)==0) { | |
+ g_string_append(text,_("^Do you run?")); | |
+ SendQuestion(NULL,C_ASKRUN,Play,text->str); | |
+ } else { | |
+ g_string_append(text,_("^Do you Run, or Fight?")); | |
+ if (strlen(text->str)>=2) { | |
+ text->str[0]='R'; text->str[1]='F'; | |
+ } | |
+ SendQuestion(NULL,C_ASKRUNFIGHT,Play,text->str); | |
+ } | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+void FinishFightWithHardass(Player *Play,char *Message) { | |
+/* Clean up after a fight between "Play" and the cops. If the cops were */ | |
+/* tipped off by another player, inform them of the results. */ | |
+/* If the player died, pass "Message" to the FinishGame subroutine. */ | |
+ GString *text; | |
+ if (g_slist_find(FirstServer,(gpointer)Play->OnBehalfOf)) { | |
+ g_message(_("%s: tipoff by %s finished OK."),GetPlayerName(Play), | |
+ GetPlayerName(Play->OnBehalfOf)); | |
+ RemoveListPlayer(&(Play->TipList),Play->OnBehalfOf); | |
+ text=g_string_new(NULL); | |
+ if (Play->Health==0) { | |
+ g_string_sprintf(text, | |
+ _("Following your tipoff, the cops ambushed %s, who was shot dead"), | |
+ GetPlayerName(Play)); | |
+ } else { | |
+ g_string_sprintf(text, | |
+ _("Following your tipoff, the cops ambushed %s, who escaped " | |
+ "with %d %s. "),GetPlayerName(Play), | |
+ Play->Bitches.Carried,Names.Bitches); | |
+ } | |
+ GainBitch(Play->OnBehalfOf); | |
+ SendPlayerData(Play->OnBehalfOf); | |
+ SendPrintMessage(NULL,C_NONE,Play->OnBehalfOf,text->str); | |
+ g_string_free(text,TRUE); | |
+ } | |
+ Play->OnBehalfOf=NULL; | |
+ if (Play->Health==0) FinishGame(Play,Message); | |
+ else { | |
+ Play->EventNum=Play->ResyncNum; | |
+ if (Play->ResyncNum==E_MAX || Play->ResyncNum==E_NONE) { | |
+ SendServerMessage(NULL,C_NONE,C_CHANGEDISP,Play,"Y"); | |
+ } | |
+ SendEvent(Play); | |
+ } | |
+} | |
+ | |
+void FireAtHardass(Player *Play,char FireType) { | |
+/* Have player "Play" attack the cops. */ | |
+/* FireType is F_STAND: Player has no gun and didn't run */ | |
+/* F_RUN: Player chose to run */ | |
+/* F_FIGHT: Player chose to fire back */ | |
+ int Damage,i,j; | |
+ char *OfficerName; | |
+ gchar *prstr; | |
+ GString *text; | |
+ | |
+ if (!Play || Play->EventNum!=E_COPS) return; | |
+ if (Play->Cops==0) { FinishFightWithHardass(Play,NULL); return; } | |
+ | |
+ text=g_string_new("^"); | |
+ OfficerName=(Play->Flags&DEADHARDASS ? Names.ReserveOfficer : | |
+ Names.Officer); | |
+ if (FireType==F_STAND) { | |
+ g_string_append(text,_("^You stand there like an idiot.")); | |
+ } else if (FireType==F_RUN) { | |
+ if (brandom(0,100) < Cops.EscapeProb-(Play->Cops-1)*Cops.DeputyEscape) { | |
+ if (Play->Cops==1) { | |
+ g_string_append(text,_("^You lose him in the alleys.")); | |
+ } else { | |
+ g_string_append(text,_("^You lose them in the alleys.")); | |
+ } | |
+ SendPrintMessage(NULL,C_NONE,Play,text->str); | |
+ FinishFightWithHardass(Play,NULL); | |
+ g_string_free(text,TRUE); | |
+ return; | |
+ } else { | |
+ if (Play->Cops==1) { | |
+ g_string_append(text,_("^You can\'t shake him, man!")); | |
+ } else { | |
+ g_string_append(text,_("^You can\'t shake them, man!")); | |
+ } | |
+ } | |
+ } else if (FireType==F_FIGHT) { | |
+ Damage=100-brandom(0,Play->Cops)*Cops.Toughness; | |
+ for (i=0;i<NumGun;i++) for (j=0;j<Play->Guns[i].Carried;j++) { | |
+ Damage+=brandom(0,Gun[i].Damage); | |
+ } | |
+ if (Damage>=100) { | |
+ if (Play->Cops==1) { | |
+ i=brandom(1500,3000); | |
+ g_string_sprintfa(text,_("^You killed Officer %s! " | |
+ "You find %s on his corpse!"), | |
+ OfficerName,prstr=FormatPrice(i)); | |
+ g_free(prstr); | |
+ Play->Cash += i; | |
+ Play->Flags |= DEADHARDASS; | |
+ SendPlayerData(Play); | |
+ SendPrintMessage(NULL,C_NONE,Play,text->str); | |
+ Play->DocPrice=brandom(1000,2000-5*Play->Health); | |
+ if (brandom(0,100)<75 && Play->DocPrice<=Play->Cash && | |
+ Play->Health<100) { | |
+ Play->EventNum=E_DOCTOR; | |
+ if (Play->Bitches.Carried && !WantAntique) { | |
+ g_string_sprintf(text, | |
+ _("YN^^^^Do you pay a doctor %s to sew your %s up?"), | |
+ prstr=FormatPrice(Play->DocPrice),Names.Bitches); | |
+ } else { | |
+ g_string_sprintf(text, | |
+ _("YN^^^^Do you pay a doctor %s to sew you up?"), | |
+ prstr=FormatPrice(Play->DocPrice)); | |
+ } | |
+ g_free(prstr); | |
+ SendQuestion(NULL,C_ASKSEW,Play,text->str); | |
+ } else { | |
+ FinishFightWithHardass(Play,NULL); | |
+ } | |
+ g_string_free(text,TRUE); | |
+ return; | |
+ } else { | |
+ g_string_append(text,_("^You got one, man!")); | |
+ Play->Cops--; | |
+ } | |
+ } else g_string_append(text,_("^You missed!")); | |
+ } | |
+ | |
+ if (Play->Cops==1) { | |
+ g_string_append(text,_("^He's firing on you, man! ")); | |
+ } else { | |
+ g_string_append(text,_("^They're firing on you, man! ")); | |
+ } | |
+ if (brandom(0,100) < Cops.HitProb+(Play->Cops-1)*Cops.DeputyHit) { | |
+ g_string_append(text,_("You've been hit! ")); | |
+ Damage=0; | |
+ for (i=0;i<Play->Cops;i++) Damage+=brandom(0,Cops.Damage); | |
+ if (Damage==0) Damage=1; | |
+ if (Damage>Play->Health) { | |
+ if (Play->Bitches.Carried==0 || WantAntique) { | |
+ if (Play->Cops==1) { | |
+ g_string_append(text,_("He wasted you, man! What a drag!")); | |
+ } else { | |
+ g_string_append(text,_("They wasted you, man! What a drag!")); | |
+ } | |
+ Play->Health=0; | |
+ SendPlayerData(Play); | |
+ FinishFightWithHardass(Play,text->str); | |
+ g_string_free(text,TRUE); | |
+ return; | |
+ } else { | |
+ g_string_sprintfa(text,_("You lost one of your %s!"),Names.Bitches… | |
+ LoseBitch(Play,NULL,NULL); | |
+ Play->Health=100; | |
+ } | |
+ } else { | |
+ Play->Health-=Damage; | |
+ } | |
+ } else { | |
+ if (Play->Cops==1) { | |
+ g_string_append(text,_("He missed!")); | |
+ } else { | |
+ g_string_append(text,_("They missed!")); | |
+ } | |
+ } | |
+ SendPlayerData(Play); | |
+ SendPrintMessage(NULL,C_NONE,Play,text->str); | |
+ g_string_free(text,TRUE); | |
+ OfficerHardass(Play,NULL,NULL); | |
+} | |
+ | |
+int RandomOffer(Player *To) { | |
+/* Inform player "To" of random offers or happenings. Returns 0 if */ | |
+/* the client can immediately be advanced to the next state, or 1 */ | |
+/* there are first questions to be answered. */ | |
+ int r,amount,ind; | |
+ GString *text; | |
+ r=brandom(0,100); | |
+ | |
+ text=g_string_new(NULL); | |
+ | |
+ if (!Sanitized && (r < 10)) { | |
+ g_string_assign(text,_("You were mugged in the subway!")); | |
+ To->Cash=To->Cash*(price_t)brandom(80,95)/100l; | |
+ } else if (r<30) { | |
+ amount=brandom(3,7); | |
+ ind=IsCarryingRandom(To,amount); | |
+ if (ind==-1 && amount>To->CoatSize) { | |
+ g_string_free(text,TRUE); return 0; | |
+ } | |
+ if (ind==-1) { | |
+ ind=brandom(0,NumDrug); | |
+ g_string_sprintf(text, | |
+ _("You meet a friend! He gives you %d %s."),amount,Drug[ind].Name); | |
+ To->Drugs[ind].Carried+=amount; | |
+ To->CoatSize-=amount; | |
+ } else { | |
+ g_string_sprintf(text, | |
+ _("You meet a friend! You give him %d %s."),amount,Drug[ind].Name… | |
+ To->Drugs[ind].Carried-=amount; | |
+ To->CoatSize+=amount; | |
+ } | |
+ SendPlayerData(To); | |
+ SendPrintMessage(NULL,C_NONE,To,text->str); | |
+ } else if (Sanitized) { | |
+ g_message(_("Sanitized away a RandomOffer")); | |
+ } else if (r<50) { | |
+ amount=brandom(3,7); | |
+ ind=IsCarryingRandom(To,amount); | |
+ if (ind!=-1) { | |
+ g_string_sprintf(text,_("Police dogs chase you for %d blocks! " | |
+ "You dropped some %s! That's a drag, man!"), | |
+ brandom(3,7),Names.Drugs); | |
+ To->Drugs[ind].Carried-=amount; | |
+ To->CoatSize+=amount; | |
+ SendPlayerData(To); | |
+ SendPrintMessage(NULL,C_NONE,To,text->str); | |
+ } else { | |
+ ind=brandom(0,NumDrug); | |
+ amount=brandom(3,7); | |
+ if (amount>To->CoatSize) { | |
+ g_string_free(text,TRUE); return 0; | |
+ } | |
+ g_string_sprintf(text, | |
+ _("You find %d %s on a dead dude in the subway!"), | |
+ amount,Drug[ind].Name); | |
+ To->Drugs[ind].Carried+=amount; | |
+ To->CoatSize-=amount; | |
+ SendPlayerData(To); | |
+ SendPrintMessage(NULL,C_NONE,To,text->str); | |
+ } | |
+ } else if (r<60 && To->Drugs[WEED].Carried+To->Drugs[HASHISH].Carried>0) { | |
+ ind = (To->Drugs[WEED].Carried>To->Drugs[HASHISH].Carried) ? | |
+ WEED : HASHISH; | |
+ amount=brandom(2,6); | |
+ if (amount>To->Drugs[ind].Carried) amount=To->Drugs[ind].Carried; | |
+ g_string_sprintf(text,_("Your mama made brownies with some of your %s! " | |
+ "They were great!"),Drug[ind].Name); | |
+ To->Drugs[ind].Carried-=amount; | |
+ To->CoatSize+=amount; | |
+ SendPlayerData(To); | |
+ SendPrintMessage(NULL,C_NONE,To,text->str); | |
+ } else if (r<65) { | |
+ g_string_assign(text, | |
+ _("YN^There is some weed that smells like paraquat here!" | |
+ "^It looks good! Will you smoke it? ")); | |
+ To->EventNum=E_WEED; | |
+ SendQuestion(NULL,C_NONE,To,text->str); | |
+ g_string_free(text,TRUE); | |
+ return 1; | |
+ } else { | |
+ g_string_sprintf(text,_("You stopped to %s."), | |
+ StoppedTo[brandom(0,NumStoppedTo)]); | |
+ amount=brandom(1,10); | |
+ if (To->Cash>=amount) To->Cash-=amount; | |
+ SendPlayerData(To); | |
+ SendPrintMessage(NULL,C_NONE,To,text->str); | |
+ } | |
+ g_string_free(text,TRUE); | |
+ return 0; | |
+} | |
+ | |
+int OfferObject(Player *To,char ForceBitch) { | |
+/* Offers player "To" bitches/trenchcoats or guns. If ForceBitch is */ | |
+/* TRUE, then a bitch is definitely offered. Returns 0 if the client */ | |
+/* can advance immediately to the next state, 1 otherwise. */ | |
+ int ObjNum; | |
+ gchar *prstr,*text=NULL; | |
+ | |
+ if (brandom(0,100)<50 || ForceBitch) { | |
+ if (WantAntique) { | |
+ To->Bitches.Price=brandom(MINTRENCHPRICE,MAXTRENCHPRICE); | |
+ text=g_strdup_printf(_("Would you like to buy a bigger trenchcoat " | |
+ "for %s?"),prstr=FormatPrice(To->Bitches.Price)); | |
+ g_free(prstr); | |
+ } else { | |
+ To->Bitches.Price=brandom(Bitch.MinPrice,Bitch.MaxPrice)/10l; | |
+ text=g_strdup_printf(_("YN^Hey dude! I'll help carry your %s for a " | |
+ "mere %s. Yes or no?"),Names.Drugs, | |
+ prstr=FormatPrice(To->Bitches.Price)); | |
+ g_free(prstr); | |
+ } | |
+ SendQuestion(NULL,C_ASKBITCH,To,text); | |
+ g_free(text); | |
+ return 1; | |
+ } else if (!Sanitized && (TotalGunsCarried(To) < To->Bitches.Carried+2)) { | |
+ ObjNum=brandom(0,NumGun); | |
+ To->Guns[ObjNum].Price=Gun[ObjNum].Price/10; | |
+ if (Gun[ObjNum].Space>To->CoatSize) return 0; | |
+ text=g_strdup_printf(_("YN^Would you like to buy a %s for %s?"), | |
+ Gun[ObjNum].Name, | |
+ prstr=FormatPrice(To->Guns[ObjNum].Price)); | |
+ g_free(prstr); | |
+ SendQuestion(NULL,C_ASKGUN,To,text); | |
+ g_free(text); | |
+ return 1; | |
+ } | |
+ return 0; | |
+} | |
+ | |
+void SendDrugsHere(Player *To,char DisplayBusts) { | |
+/* Sends details of drug prices to player "To". If "DisplayBusts" */ | |
+/* is TRUE, also regenerates drug prices and sends details of */ | |
+/* special events such as drug busts */ | |
+ int i; | |
+ gchar *Deal,*prstr; | |
+ GString *text; | |
+ gboolean First; | |
+ | |
+ Deal=g_malloc0(NumDrug); | |
+ if (DisplayBusts) GenerateDrugsHere(To,Deal); | |
+ | |
+ text=g_string_new(NULL); | |
+ First=TRUE; | |
+ if (DisplayBusts) for (i=0;i<NumDrug;i++) if (Deal[i]) { | |
+ if (!First) g_string_append_c(text,'^'); | |
+ if (Drug[i].Expensive) { | |
+ g_string_sprintfa(text,Deal[i]==1 ? Drugs.ExpensiveStr1 : | |
+ Drugs.ExpensiveStr2, | |
+ Drug[i].Name); | |
+ } else if (Drug[i].Cheap) { | |
+ g_string_append(text,Drug[i].CheapStr); | |
+ } | |
+ First=FALSE; | |
+ } | |
+ if (!First) SendPrintMessage(NULL,C_NONE,To,text->str); | |
+ g_string_truncate(text,0); | |
+ for (i=0;i<NumDrug;i++) { | |
+ g_string_sprintfa(text,"%s^",(prstr=pricetostr(To->Drugs[i].Price))); | |
+ g_free(prstr); | |
+ } | |
+ SendServerMessage(NULL,C_NONE,C_DRUGHERE,To,text->str); | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+void GenerateDrugsHere(Player *To,gchar *Deal) { | |
+/* Generates drug prices and drug busts etc. for player "To" */ | |
+/* "Deal" is an array of chars of size NumDrug */ | |
+ int NumEvents,NumDrugs,NumRandom,i; | |
+ for (i=0;i<NumDrug;i++) { | |
+ To->Drugs[i].Price=0; | |
+ Deal[i]=0; | |
+ } | |
+ NumEvents=0; | |
+ if (brandom(0,100)<70) NumEvents=1; | |
+ if (brandom(0,100)<40 && NumEvents==1) NumEvents=2; | |
+ if (brandom(0,100)<5 && NumEvents==2) NumEvents=3; | |
+ NumDrugs=0; | |
+ while (NumEvents>0) { | |
+ i=brandom(0,NumDrug); | |
+ if (Deal[i]!=0) continue; | |
+ if (Drug[i].Expensive && (!Drug[i].Cheap || brandom(0,100)<50)) { | |
+ Deal[i]=brandom(1,3); | |
+ To->Drugs[i].Price=brandom(Drug[i].MinPrice,Drug[i].MaxPrice) | |
+ *Drugs.ExpensiveMultiply; | |
+ NumDrugs++; | |
+ NumEvents--; | |
+ } else if (Drug[i].Cheap) { | |
+ Deal[i]=1; | |
+ To->Drugs[i].Price=brandom(Drug[i].MinPrice,Drug[i].MaxPrice) | |
+ /Drugs.CheapDivide; | |
+ NumDrugs++; | |
+ NumEvents--; | |
+ } | |
+ } | |
+ NumRandom=brandom(Location[(int)To->IsAt].MinDrug, | |
+ Location[(int)To->IsAt].MaxDrug); | |
+ if (NumRandom > NumDrug) NumRandom=NumDrug; | |
+ | |
+ NumDrugs=NumRandom-NumDrugs; | |
+ while (NumDrugs>0) { | |
+ i=brandom(0,NumDrug); | |
+ if (To->Drugs[i].Price==0) { | |
+ To->Drugs[i].Price=brandom(Drug[i].MinPrice,Drug[i].MaxPrice); | |
+ NumDrugs--; | |
+ } | |
+ } | |
+} | |
+ | |
+void HandleAnswer(Player *From,Player *To,char *answer) { | |
+/* Handles the incoming message in "answer" from player "From" and */ | |
+/* intended for player "To". */ | |
+ int i; | |
+ gchar *text; | |
+ if (!From || From->EventNum==E_NONE) return; | |
+ if (answer[0]=='Y' && From->EventNum==E_OFFOBJECT && From->Bitches.Price | |
+ && From->Bitches.Price>From->Cash) answer[0]='N'; | |
+ if (answer[0]=='Y') switch (From->EventNum) { | |
+ case E_OFFOBJECT: | |
+ if (g_slist_find(FirstServer,(gpointer)From->OnBehalfOf)) { | |
+ g_message(_("%s: offer was on behalf of %s"),GetPlayerName(From), | |
+ GetPlayerName(From->OnBehalfOf)); | |
+ if (From->Bitches.Price) { | |
+ text=g_strdup_printf(_("%s has accepted your %s!" | |
+ "^Use the G key to contact your spy."), | |
+ GetPlayerName(From),Names.Bitch); | |
+ From->OnBehalfOf->Flags |= SPYINGON; | |
+ SendPlayerData(From->OnBehalfOf); | |
+ SendPrintMessage(NULL,C_NONE,From->OnBehalfOf,text); | |
+ g_free(text); | |
+ i=GetListEntry(&(From->SpyList),From->OnBehalfOf); | |
+ if (i>=0) From->SpyList.Data[i].Turns=0; | |
+ } | |
+ } | |
+ if (From->Bitches.Price) { | |
+ text=g_strdup_printf("bitch^0^1"); | |
+ BuyObject(From,text); | |
+ g_free(text); | |
+ } else { | |
+ for (i=0;i<NumGun;i++) if (From->Guns[i].Price) { | |
+ text=g_strdup_printf("gun^%d^1",i); | |
+ BuyObject(From,text); | |
+ g_free(text); | |
+ break; | |
+ } | |
+ } | |
+ From->OnBehalfOf=NULL; | |
+ From->EventNum++; SendEvent(From); | |
+ break; | |
+ case E_LOANSHARK: | |
+ SendServerMessage(NULL,C_NONE,C_LOANSHARK,From,NULL); | |
+ break; | |
+ case E_BANK: | |
+ SendServerMessage(NULL,C_NONE,C_BANK,From,NULL); | |
+ break; | |
+ case E_GUNSHOP: | |
+ for (i=0;i<NumGun;i++) From->Guns[i].Price=Gun[i].Price; | |
+ SendServerMessage(NULL,C_NONE,C_GUNSHOP,From,NULL); | |
+ break; | |
+ case E_HIREBITCH: | |
+ text=g_strdup_printf("bitch^0^1"); | |
+ BuyObject(From,text); | |
+ g_free(text); | |
+ From->EventNum++; SendEvent(From); | |
+ break; | |
+ case E_ROUGHPUB: | |
+ From->EventNum++; SendEvent(From); | |
+ break; | |
+ case E_WEED: | |
+ FinishGame(From,_("You hallucinated for three days on the wildest " | |
+"trip you ever imagined!^Then you died because your brain disintegrated!")); | |
+ break; | |
+ case E_COPS: | |
+ FireAtHardass(From,F_RUN); | |
+ break; | |
+ case E_DOCTOR: | |
+ if (From->Cash >= From->DocPrice) { | |
+ From->Cash -= From->DocPrice; | |
+ From->Health=100; | |
+ SendPlayerData(From); | |
+ } | |
+ FinishFightWithHardass(From,NULL); | |
+ break; | |
+ } else if (From->EventNum==E_COPS && | |
+ (answer[0]=='F' || answer[0]=='R')) { | |
+ FireAtHardass(From,answer[0]=='F' ? F_FIGHT : F_RUN); | |
+ } else if (From->EventNum==E_ARRIVE) { | |
+ if ((answer[0]=='A' || answer[0]=='T') && | |
+ g_slist_find(FirstServer,(gpointer)From->Attacked)) { | |
+ if (From->Attacked->IsAt==From->IsAt) { | |
+ if (answer[0]=='A') { | |
+ if (From->Attacked->EventNum<E_MAX) { | |
+ From->Attacked->ResyncNum=From->Attacked->EventNum; | |
+ } | |
+ From->Attacked->Flags |= FIGHTING; | |
+ SendPlayerData(From->Attacked); | |
+ From->Flags |= FIGHTING; | |
+ SendPlayerData(From); | |
+ From->Attacked->EventNum=E_DEFEND; | |
+ From->ResyncNum=E_ARRIVE+1; | |
+ From->EventNum=E_ATTACK; | |
+ AttackPlayer(From,From->Attacked,AT_FIRST | AT_SHOOT); | |
+/* } else if (answer[0]=='T') { | |
+ From->Flags |= TRADING; | |
+ SendPlayerData(From); | |
+ SendServerMessage(NULL,C_NONE,C_TRADE,From,NULL);*/ | |
+ } | |
+ } else { | |
+ text=g_strdup_printf(_("Too late - %s has just left!"), | |
+ GetPlayerName(From->Attacked)); | |
+ SendPrintMessage(NULL,C_NONE,From,text); | |
+ g_free(text); | |
+ From->EventNum++; SendEvent(From); | |
+ } | |
+ } else { | |
+ From->EventNum++; SendEvent(From); | |
+ } | |
+ } else switch(From->EventNum) { | |
+ case E_ROUGHPUB: | |
+ From->EventNum++; | |
+ From->EventNum++; SendEvent(From); | |
+ break; | |
+ case E_COPS: | |
+ FireAtHardass(From,F_STAND); | |
+ break; | |
+ case E_DOCTOR: | |
+ FinishFightWithHardass(From,NULL); | |
+ break; | |
+ case E_HIREBITCH: case E_GUNSHOP: case E_BANK: case E_LOANSHARK: | |
+ case E_OFFOBJECT: case E_WEED: | |
+ if (g_slist_find(FirstServer,(gpointer)From->OnBehalfOf)) { | |
+ g_message(_("%s: offer was on behalf of %s"),GetPlayerName(From), | |
+ GetPlayerName(From->OnBehalfOf)); | |
+ if (From->Bitches.Price && From->EventNum==E_OFFOBJECT) { | |
+ text=g_strdup_printf(_("%s has rejected your %s!"), | |
+ GetPlayerName(From),Names.Bitch); | |
+ GainBitch(From->OnBehalfOf); | |
+ SendPlayerData(From->OnBehalfOf); | |
+ SendPrintMessage(NULL,C_NONE,From->OnBehalfOf,text); | |
+ g_free(text); | |
+ RemoveListPlayer(&(From->SpyList),From->OnBehalfOf); | |
+ } | |
+ } | |
+ From->EventNum++; SendEvent(From); | |
+ break; | |
+ } | |
+} | |
+ | |
+void BreakoffCombat(Player *Attack,char LeftGame) { | |
+/* Withdraws from player-player combat that player "Attack" is */ | |
+/* currently involved in. "LeftGame" is TRUE if "Attack" has just */ | |
+/* left the game, in which case no more messages are sent to this */ | |
+/* player (just the other side of the fight is cleaned up) */ | |
+ Player *Defend,*Play,*Victor; | |
+ GSList *list; | |
+ gchar *text; | |
+ char FightDone; | |
+ if (!g_slist_find(FirstServer,(gpointer)Attack)) { | |
+ g_warning("Players involved in a fight are not valid!"); | |
+ return; | |
+ } | |
+ if (Attack->EventNum!=E_DEFEND && Attack->EventNum!=E_ATTACK && | |
+ Attack->EventNum!=E_FREEFORALL && Attack->EventNum!=E_WAITATTACK) { | |
+ g_warning("Players in fight are not attack/defending!"); | |
+ return; | |
+ } | |
+ Victor=NULL; | |
+ | |
+ if (Attack->EventNum==E_DEFEND) { | |
+ text=g_strdup_printf(_("%s has got away!"),GetPlayerName(Attack)); | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ Play=(Player *)list->data; | |
+ if (Play->Attacked==Attack && (Play->EventNum==E_ATTACK || | |
+ Play->EventNum==E_WAITATTACK || Play->EventNum==E_FREEFORALL)) { | |
+ ClearFightTimeout(Play); | |
+ Play->Attacked=NULL; | |
+ Play->Flags &= ~FIGHTING; | |
+ SendPlayerData(Play); | |
+ if (Attack->Health!=0) { | |
+ SendServerMessage(NULL,C_NONE,C_FIGHTPRINT,Play,text); | |
+ } | |
+ Victor=Play; | |
+ Play->EventNum=Play->ResyncNum; SendEvent(Play); | |
+ } | |
+ } | |
+ g_free(text); | |
+ } else { | |
+ ClearFightTimeout(Attack); | |
+ Victor=Attack; | |
+ Defend=Attack->Attacked; | |
+ if (!g_slist_find(FirstServer,(gpointer)Defend)) { | |
+ g_warning("Players involved in a fight are not valid!"); | |
+ return; | |
+ } | |
+ if (Defend->EventNum!=E_DEFEND) { | |
+ g_warning("Players in fight are not attack/defending!"); | |
+ return; | |
+ } | |
+ | |
+ Attack->Attacked=NULL; | |
+ FightDone=TRUE; | |
+ for (list=FirstServer;list;list=g_slist_next(list)) { | |
+ Play=(Player *)list->data; | |
+ if (Play->Attacked==Defend && (Play->EventNum==E_ATTACK || | |
+ Play->EventNum==E_WAITATTACK || Play->EventNum==E_FREEFORALL)) { | |
+ FightDone=FALSE; | |
+ break; | |
+ } | |
+ } | |
+ if (Attack->Health>0) { | |
+ text=g_strdup_printf(_("%s has run off!"),GetPlayerName(Attack)); | |
+ SendServerMessage(NULL,C_NONE,C_FIGHTPRINT,Defend,text); | |
+ g_free(text); | |
+ } | |
+ if (FightDone) { | |
+ Defend->Flags &= ~FIGHTING; | |
+ SendPlayerData(Defend); | |
+ Defend->EventNum=Defend->ResyncNum; SendEvent(Defend); | |
+ } | |
+ } | |
+ if (!LeftGame) { | |
+ if (Attack->Health>0) SendPrintMessage(NULL,C_NONE,Attack, | |
+ _("Coward! You successfully escaped from the fight.")); | |
+ Attack->Flags &= ~FIGHTING; SendPlayerData(Attack); | |
+ Attack->EventNum=Attack->ResyncNum; SendEvent(Attack); | |
+ } | |
+} | |
+ | |
+void AttackPlayer(Player *Attack,Player *Defend,char AttackType) { | |
+/* Processes a player-player attack from player "Attack" to player "Defend" */ | |
+/* AttackType is the type of attack, and may contain the following flags:- */ | |
+/* AT_FIRST: Set if this is the first attack */ | |
+/* AT_SHOOT: Set if this is an 'active' attack - i.e. player "Attack" is */ | |
+/* actually shooting, not just "not running" */ | |
+ int i,j; | |
+ Inventory *Guns,*Drugs; | |
+ price_t Bounty; | |
+ int Damage,MaxDamage; | |
+ GString *DefendText,*AttackText; | |
+ gchar *prstr,*ActionText,*ArmamentText; | |
+ | |
+ if (!g_slist_find(FirstServer,(gpointer)Attack) || | |
+ !g_slist_find(FirstServer,(gpointer)Defend)) { | |
+ g_warning("Players involved in a fight are not valid!"); | |
+ return; | |
+ } | |
+ if (Attack->EventNum!=E_DEFEND && Attack->EventNum!=E_ATTACK && | |
+ Attack->EventNum!=E_FREEFORALL) { | |
+ g_warning("%s is in wrong state (%d) to attack!", | |
+ GetPlayerName(Attack),Attack->EventNum); | |
+ return; | |
+ } | |
+ if ((Attack->EventNum==E_ATTACK || Attack->EventNum==E_FREEFORALL) && | |
+ Defend->EventNum!=E_DEFEND) { | |
+ g_warning("%s is trying to attack %s, who is in wrong state (%d)!", | |
+ GetPlayerName(Attack),GetPlayerName(Defend),Defend->EventNum); | |
+ return; | |
+ } | |
+ if (Attack->EventNum==E_DEFEND && Defend->EventNum!=E_WAITATTACK && | |
+ Defend->EventNum!=E_FREEFORALL) { | |
+ g_warning("%s is trying to defend against %s, who is in wrong \ | |
+state (%d)!",GetPlayerName(Attack),GetPlayerName(Defend),Defend->EventNum); | |
+ return; | |
+ } | |
+ MaxDamage=0; | |
+ Damage=0; | |
+ AttackText=g_string_new(NULL); | |
+ DefendText=g_string_new(NULL); | |
+ for (i=0;i<NumGun;i++) { | |
+ if (Gun[i].Damage>MaxDamage) MaxDamage=Gun[i].Damage; | |
+ Damage+=Gun[i].Damage*Attack->Guns[i].Carried; | |
+ } | |
+ MaxDamage *= (Attack->Bitches.Carried+2); | |
+ MaxDamage = Damage*100/MaxDamage; | |
+ | |
+ Guns=(Inventory *)g_malloc0(sizeof(Inventory)*NumGun); | |
+ Drugs=(Inventory *)g_malloc0(sizeof(Inventory)*NumDrug); | |
+ ClearInventory(Guns,Drugs); | |
+ ArmamentText= MaxDamage<10 ? _("pitifully armed") : | |
+ MaxDamage<25 ? _("lightly armed") : | |
+ MaxDamage<60 ? _("moderately well armed") : | |
+ MaxDamage<80 ? _("heavily armed") : | |
+ _("armed to the teeth"); | |
+ ActionText=AttackType&AT_SHOOT ? _(" fires and ") : | |
+ _(" stands and takes it."); | |
+ if (AttackType&AT_FIRST) { | |
+ if (Attack->Bitches.Carried>0) { | |
+ g_string_sprintf(DefendText,_("%s arrives, with %d %s, %s,^%s"), | |
+ GetPlayerName(Attack),Attack->Bitches.Carried, | |
+ Names.Bitches,ArmamentText,ActionText); | |
+ } else { | |
+ g_string_sprintf(DefendText,_("%s arrives, %s,^%s"), | |
+ GetPlayerName(Attack),ArmamentText,ActionText); | |
+ } | |
+ } else { | |
+ if (AttackType&AT_SHOOT) { | |
+ g_string_sprintf(DefendText,_("%s fires and "),GetPlayerName(Attack)); | |
+ } else { | |
+ g_string_sprintf(DefendText,_("%s stands and takes it."), | |
+ GetPlayerName(Attack)); | |
+ } | |
+ } | |
+ Damage=0; | |
+ if (AttackType&AT_SHOOT) { | |
+ for (i=0;i<NumGun;i++) for (j=0;j<Attack->Guns[i].Carried;j++) { | |
+ Damage+=brandom(0,Gun[i].Damage); | |
+ } | |
+ } | |
+ if (Damage==0) { | |
+ if (AttackType & AT_SHOOT) { | |
+ g_string_append(DefendText,_("misses you!")); | |
+ g_string_sprintf(AttackText,_("You failed to hit %s."), | |
+ GetPlayerName(Defend)); | |
+ } else { | |
+ g_string_assign(AttackText,_("You stand and take it.")); | |
+ } | |
+ SendServerMessage(NULL,C_NONE,C_FIGHTPRINT,Attack,AttackText->str); | |
+ } else { | |
+ g_string_append(DefendText,_("hits you, man!")); | |
+ if (Damage>=Defend->Health) { | |
+ if (Defend->Bitches.Carried==0) { | |
+ g_string_append(DefendText,_(" You've been wasted! What a drag!")); | |
+ g_string_sprintf(AttackText,_("You hit and killed %s"), | |
+ GetPlayerName(Defend)); | |
+ Defend->Health=0; | |
+ Bounty=Defend->Cash+Defend->Bank-Defend->Debt; | |
+ if (Bounty>0) Attack->Cash+=Bounty; | |
+ SendPlayerData(Defend); | |
+ SendServerMessage(NULL,C_NONE,C_FIGHTPRINT,Defend,DefendText->str); | |
+ AddInventory(Guns,Defend->Guns,NumGun); | |
+ AddInventory(Drugs,Defend->Drugs,NumDrug); | |
+ TruncateInventoryFor(Guns,Drugs,Attack); | |
+ if (!IsInventoryClear(Guns,Drugs)) { | |
+ AddInventory(Attack->Guns,Guns,NumGun); | |
+ AddInventory(Attack->Drugs,Drugs,NumDrug); | |
+ ChangeSpaceForInventory(Guns,Drugs,Attack); | |
+ SendPlayerData(Attack); | |
+ g_string_append(AttackText,_(", and loot the body!")); | |
+ } else g_string_append_c(AttackText,'!'); | |
+ SendServerMessage(NULL,C_NONE,C_FIGHTPRINT,Attack,AttackText->str); | |
+ g_free(Guns); g_free(Drugs); | |
+ g_string_free(AttackText,TRUE); | |
+ FinishGame(Defend,DefendText->str); | |
+ g_string_free(DefendText,TRUE); | |
+ return; | |
+ } else { | |
+ g_string_sprintfa(DefendText,_("^You lost a %s, man!"), | |
+ Names.Bitch); | |
+ Bounty=(Defend->Cash+Defend->Bank-Defend->Debt)* | |
+ Defend->Bitches.Carried/1000L; | |
+ if (Bounty>0) { | |
+ g_string_sprintf(AttackText,_("You are paid a bounty of %s in " | |
+ "reward for killing^one of %s's %s"), | |
+ prstr=FormatPrice(Bounty), | |
+ GetPlayerName(Defend),Names.Bitches); | |
+ g_free(prstr); | |
+ Attack->Cash+=Bounty; | |
+ SendPlayerData(Attack); | |
+ } else { | |
+ g_string_sprintf(AttackText,_("You killed one of %s's %s " | |
+ "(%d left)"),GetPlayerName(Defend), | |
+ Names.Bitches,Defend->Bitches.Carried-1); | |
+ } | |
+ LoseBitch(Defend,Guns,Drugs); | |
+ TruncateInventoryFor(Guns,Drugs,Attack); | |
+ if (!IsInventoryClear(Guns,Drugs)) { | |
+ AddInventory(Attack->Guns,Guns,NumGun); | |
+ AddInventory(Attack->Drugs,Drugs,NumDrug); | |
+ ChangeSpaceForInventory(Guns,Drugs,Attack); | |
+ SendPlayerData(Attack); | |
+ g_string_append(AttackText,_(", and loot the body!")); | |
+ } else g_string_append_c(AttackText,'!'); | |
+ SendServerMessage(NULL,C_NONE,C_FIGHTPRINT,Attack,AttackText->str); | |
+ Defend->Health=100; | |
+ } | |
+ } else { | |
+ Defend->Health-=Damage; | |
+ g_string_sprintf(AttackText,_("You fire, and hit %s!"), | |
+ GetPlayerName(Defend)); | |
+ SendServerMessage(NULL,C_NONE,C_FIGHTPRINT,Attack,AttackText->str); | |
+ } | |
+ } | |
+ if (Attack->EventNum==E_ATTACK || Attack->EventNum==E_FREEFORALL) { | |
+ Attack->EventNum=E_WAITATTACK; SetFightTimeout(Attack); | |
+ } else if (Attack->EventNum==E_DEFEND) { | |
+ Defend->EventNum=E_ATTACK; SetFightTimeout(Defend); | |
+ } | |
+ SendPlayerData(Defend); | |
+ SendServerMessage(Attack,C_NONE,C_FIGHTPRINT,Defend,DefendText->str); | |
+ g_string_free(AttackText,TRUE); | |
+ g_string_free(DefendText,TRUE); | |
+ g_free(Guns); g_free(Drugs); | |
+} | |
+ | |
+void BuyObject(Player *From,char *data) { | |
+/* Processes a request stored in "data" from player "From" to buy an */ | |
+/* object (bitch, gun, or drug) */ | |
+/* Objects can be sold if the amount given in "data" is negative, and */ | |
+/* given away if their current price is zero. */ | |
+ char *cp,*type; | |
+ gchar *lone,*deputy; | |
+ int index,i,amount; | |
+ cp=data; | |
+ type=GetNextWord(&cp,""); | |
+ index=GetNextInt(&cp,0); | |
+ amount=GetNextInt(&cp,0); | |
+ if (strcmp(type,"drug")==0) { | |
+ if (index>=0 && index<NumDrug && From->Drugs[index].Carried+amount >= 0 | |
+ && From->CoatSize-amount >= 0 && (From->Drugs[index].Price!=0 || | |
+ amount<0) && From->Cash >= amount*From->Drugs[index].Price) { | |
+ From->Drugs[index].Carried+=amount; | |
+ From->CoatSize-=amount; | |
+ From->Cash-=amount*From->Drugs[index].Price; | |
+ SendPlayerData(From); | |
+ | |
+ if (!Sanitized && (From->Drugs[index].Price==0 && brandom(0,100)<Cops… | |
+ lone=g_strdup_printf(_("YN^Officer %%s spots you dropping %s, and " | |
+ "chases you!"),Names.Drugs); | |
+ deputy=g_strdup_printf(_("YN^Officer %%s and %%d of his deputies " | |
+ "spot you dropping %s, and chase you!"), | |
+ Names.Drugs); | |
+ StartOfficerHardass(From,From->EventNum,lone,deputy); | |
+ g_free(lone); g_free(deputy); | |
+ } | |
+ } | |
+ } else if (strcmp(type,"gun")==0) { | |
+ if (index>=0 && index<NumGun && TotalGunsCarried(From)+amount >= 0 | |
+ && TotalGunsCarried(From)+amount <= From->Bitches.Carried+2 | |
+ && From->Guns[index].Price!=0 | |
+ && From->CoatSize-amount*Gun[index].Space >= 0 | |
+ && From->Cash >= amount*From->Guns[index].Price) { | |
+ From->Guns[index].Carried+=amount; | |
+ From->CoatSize-=amount*Gun[index].Space; | |
+ From->Cash-=amount*From->Guns[index].Price; | |
+ SendPlayerData(From); | |
+ } | |
+ } else if (strcmp(type,"bitch")==0) { | |
+ if (From->Bitches.Carried+amount >= 0 | |
+ && From->Bitches.Price!=0 | |
+ && amount*From->Bitches.Price <= From->Cash) { | |
+ for (i=0;i<amount;i++) GainBitch(From); | |
+ if (amount>0) From->Cash-=amount*From->Bitches.Price; | |
+ SendPlayerData(From); | |
+ } | |
+ } | |
+} | |
+ | |
+void ClearPrices(Player *Play) { | |
+/* Clears the bitch and gun prices stored for player "Play" */ | |
+ int i; | |
+ Play->Bitches.Price=0; | |
+ for (i=0;i<NumGun;i++) Play->Guns[i].Price=0; | |
+} | |
+ | |
+void GainBitch(Player *Play) { | |
+/* Gives player "Play" a new bitch (or larger trenchcoat) */ | |
+ Play->CoatSize+=10; | |
+ Play->Bitches.Carried++; | |
+} | |
+ | |
+int LoseBitch(Player *Play,Inventory *Guns,Inventory *Drugs) { | |
+/* Loses one bitch belonging to player "Play". If drugs or guns are */ | |
+/* lost with the bitch, 1 is returned (0 otherwise) and the lost */ | |
+/* items are added to "Guns" and "Drugs" if non-NULL */ | |
+ int losedrug=0,i,num,drugslost; | |
+ int *GunIndex,tmp; | |
+ GunIndex=g_new(int,NumGun); | |
+ ClearInventory(Guns,Drugs); | |
+ Play->CoatSize-=10; | |
+ if (TotalGunsCarried(Play)>0) { | |
+ if (brandom(0,100)<TotalGunsCarried(Play)*100/(Play->Bitches.Carried+2))… | |
+ for (i=0;i<NumGun;i++) GunIndex[i]=i; | |
+ for (i=0;i<NumGun*5;i++) { | |
+ num=brandom(0,NumGun-1); | |
+ tmp=GunIndex[num+1]; | |
+ GunIndex[num+1]=GunIndex[num]; | |
+ GunIndex[num]=tmp; | |
+ } | |
+ for (i=0;i<NumGun;i++) { | |
+ if (Play->Guns[GunIndex[i]].Carried > 0) { | |
+ Play->Guns[GunIndex[i]].Carried--; losedrug=1; | |
+ Play->CoatSize+=Gun[GunIndex[i]].Space; | |
+ if (Guns) Guns[GunIndex[i]].Carried++; | |
+ break; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ for (i=0;i<NumDrug;i++) if (Play->Drugs[i].Carried>0) { | |
+ num=(int)((float)Play->Drugs[i].Carried/(Play->Bitches.Carried+2.0)+0.5); | |
+ if (num>0) { | |
+ Play->Drugs[i].Carried-=num; | |
+ if (Drugs) Drugs[i].Carried+=num; | |
+ Play->CoatSize+=num; | |
+ losedrug=1; | |
+ } | |
+ } | |
+ while (Play->CoatSize<0) { | |
+ drugslost=0; | |
+ for (i=0;i<NumDrug;i++) { | |
+ if (Play->Drugs[i].Carried>0) { | |
+ losedrug=1; drugslost=1; | |
+ Play->Drugs[i].Carried--; | |
+ Play->CoatSize++; | |
+ if (Play->CoatSize>=0) break; | |
+ } | |
+ } | |
+ if (!drugslost) for (i=0;i<NumGun;i++) { | |
+ if (Play->Guns[i].Carried>0) { | |
+ losedrug=1; | |
+ Play->Guns[i].Carried--; | |
+ Play->CoatSize+=Gun[i].Space; | |
+ if (Play->CoatSize>=0) break; | |
+ } | |
+ } | |
+ } | |
+ Play->Bitches.Carried--; | |
+ g_free(GunIndex); | |
+ return losedrug; | |
+} | |
+ | |
+void SetFightTimeout(Player *Play) { | |
+ if (FightTimeout) Play->FightTimeout=time(NULL)+(time_t)FightTimeout; | |
+ else Play->FightTimeout=0; | |
+} | |
+ | |
+void ClearFightTimeout(Player *Play) { | |
+ Play->FightTimeout=0; | |
+} | |
+ | |
+int AddTimeout(time_t timeout,time_t timenow,int *mintime) { | |
+ if (timeout==0) return 0; | |
+ else if (timeout<=timenow) return 1; | |
+ else { | |
+ if (*mintime<0 || timeout-timenow < *mintime) *mintime=timeout-timenow; | |
+ return 0; | |
+ } | |
+} | |
+ | |
+int GetMinimumTimeout(GSList *First) { | |
+ Player *Play; | |
+ GSList *list; | |
+ int mintime=-1; | |
+ time_t timenow; | |
+ | |
+ timenow=time(NULL); | |
+ if (AddTimeout(MetaTimeout,timenow,&mintime)) return 0; | |
+ for (list=First;list;list=g_slist_next(list)) { | |
+ Play=(Player *)list->data; | |
+ if (AddTimeout(Play->FightTimeout,timenow,&mintime) || | |
+ AddTimeout(Play->IdleTimeout,timenow,&mintime) || | |
+ AddTimeout(Play->ConnectTimeout,timenow,&mintime)) return 0; | |
+ } | |
+ return mintime; | |
+} | |
+ | |
+GSList *HandleTimeouts(GSList *First) { | |
+ GSList *list,*nextlist; | |
+ Player *Play; | |
+ gchar *text; | |
+ time_t timenow; | |
+ | |
+ timenow=time(NULL); | |
+ if (MetaTimeout!=0 && MetaTimeout<=timenow) { | |
+ MetaTimeout=0; | |
+ RegisterWithMetaServer(TRUE,FALSE); | |
+ } | |
+ list=First; | |
+ while (list) { | |
+ nextlist=g_slist_next(list); | |
+ Play=(Player *)list->data; | |
+ if (Play->IdleTimeout!=0 && Play->IdleTimeout<=timenow) { | |
+ Play->IdleTimeout=0; | |
+ g_message(_("Player removed due to idle timeout")); | |
+ SendPrintMessage(NULL,C_NONE,Play,"Disconnected due to idle timeout"); | |
+ ClientLeftServer(Play); | |
+/* shutdown(Play->fd,SD_RECV);*/ | |
+/* Make sure they do actually disconnect, eventually! */ | |
+ if (ConnectTimeout) { | |
+ Play->ConnectTimeout=time(NULL)+(time_t)ConnectTimeout; | |
+ } | |
+ } else if (Play->ConnectTimeout!=0 && Play->ConnectTimeout<=timenow) { | |
+ Play->ConnectTimeout=0; | |
+ g_message(_("Player removed due to connect timeout")); | |
+ First=RemovePlayer(Play,First); | |
+ } else if (Play->FightTimeout!=0 && Play->FightTimeout<=timenow) { | |
+ ClearFightTimeout(Play); | |
+ if (Play->EventNum==E_WAITATTACK) { | |
+ Play->EventNum=E_FREEFORALL; | |
+ text=g_strdup_printf(_("%s fails to return fire..."), | |
+ GetPlayerName(Play->Attacked)); | |
+ SendServerMessage(Play->Attacked,C_NONE,C_FIGHTPRINT,Play,text); | |
+ g_free(text); | |
+ } else if (Play->EventNum==E_ATTACK) { | |
+ Play->EventNum=E_FREEFORALL; | |
+ text=g_strdup_printf(_("%s fails to return fire..."), | |
+ GetPlayerName(Play)); | |
+ SendServerMessage(Play,C_NONE,C_FIGHTPRINT,Play->Attacked,text); | |
+ g_free(text); | |
+ } | |
+ } | |
+ list=nextlist; | |
+ } | |
+ return First; | |
+} | |
diff --git a/src/serverside.h b/src/serverside.h | |
t@@ -0,0 +1,78 @@ | |
+/* serverside.h Server-side parts of Dopewars */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+ | |
+#ifndef __SERVERSIDE_H__ | |
+#define __SERVERSIDE_H__ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#include "dopewars.h" | |
+ | |
+#define NOFORCE 0 | |
+#define FORCECOPS 1 | |
+#define FORCEBITCH 2 | |
+ | |
+#define AT_FIRST 1 | |
+#define AT_SHOOT 2 | |
+ | |
+extern GSList *FirstServer; | |
+extern char *PidFile; | |
+ | |
+void CleanUpServer(); | |
+void BreakHandle(); | |
+void ClientLeftServer(Player *Play); | |
+void StartServer(); | |
+void StopServer(); | |
+gboolean HandleServerCommand(char *string); | |
+void HandleNewConnection(); | |
+void ServerLoop(); | |
+void HandleServerPlayer(Player *Play); | |
+void HandleServerMessage(gchar *buf,Player *ReallyFrom); | |
+void FinishGame(Player *Play,char *Message); | |
+void SendHighScores(Player *Play,char AddCurrent,char *Message); | |
+void SendEvent(Player *To); | |
+int SendCopOffer(Player *To,char Force); | |
+int OfferObject(Player *To,char ForceBitch); | |
+void SendDrugsHere(Player *To,char DisplayBusts); | |
+void GenerateDrugsHere(Player *To,char *Deal); | |
+void BuyObject(Player *From,char *data); | |
+int RandomOffer(Player *To); | |
+void HandleAnswer(Player *From,Player *To,char *answer); | |
+void ClearPrices(Player *Play); | |
+void StartOfficerHardass(Player *Play,int ResyncNum, | |
+ char *LoneMessage,char *DeputyMessage); | |
+void OfficerHardass(Player *Play,char *LoneMessage,char *DeputyMessage); | |
+void FireAtHardass(Player *Play,char FireType); | |
+void FinishFightWithHardass(Player *Play,char *Message); | |
+int LoseBitch(Player *Play,Inventory *Guns,Inventory *Drugs); | |
+void GainBitch(Player *Play); | |
+void AttackPlayer(Player *Attack,Player *Defend,char AttackType); | |
+void BreakoffCombat(Player *Attack,char LeftGame); | |
+void SetFightTimeout(Player *Play); | |
+void ClearFightTimeout(Player *Play); | |
+int GetMinimumTimeout(GSList *First); | |
+GSList *HandleTimeouts(GSList *First); | |
+gboolean CheckHighScoreFile(); | |
+int HighScoreRead(struct HISCORE *MultiScore,struct HISCORE *AntiqueScore); | |
+ | |
+#endif | |
diff --git a/src/win32_client.c b/src/win32_client.c | |
t@@ -0,0 +1,1823 @@ | |
+/* win32_client.c dopewars client using the Win32 user interface */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+#ifdef CYGWIN | |
+ | |
+#include <windows.h> | |
+#include <commctrl.h> | |
+#include <glib.h> | |
+#include <stdlib.h> | |
+#include "dopeid.h" | |
+ | |
+#include "dopeos.h" | |
+#include "dopewars.h" | |
+#include "curses_client.h" | |
+#include "win32_client.h" | |
+#include "message.h" | |
+#include "serverside.h" | |
+ | |
+#ifdef WIN32_CLIENT | |
+ | |
+#define WM_SOCKETDATA (WM_USER+100) | |
+#define WM_ADDSPYREPORT (WM_USER+101) | |
+ | |
+#define BT_BUY ((LPARAM)1) | |
+#define BT_SELL ((LPARAM)2) | |
+#define BT_DROP ((LPARAM)3) | |
+ | |
+HINSTANCE hInst; | |
+ | |
+BOOL InGame=FALSE,MetaServerRead=FALSE; | |
+ | |
+struct STATS { | |
+ HWND SellButton,BuyButton,DropButton,JetButton,StatGroup, | |
+ HereList,CarriedList,MessageEdit,Location,Date,Space,Cash,Debt,Bank, | |
+ Guns,Bitches,Health; | |
+}; | |
+ | |
+struct CLIENTDATA { | |
+ HWND Window; | |
+ struct STATS Stats; | |
+ gchar *PlayerName; | |
+ Player *Play; | |
+}; | |
+ | |
+ | |
+static HWND PlayerListWnd=NULL,TalkWnd=NULL,InventoryWnd=NULL,ScoresWnd=NULL, | |
+ FightWnd=NULL,GunShopWnd=NULL,SpyReportsWnd=NULL; | |
+ | |
+static struct CLIENTDATA ClientData; | |
+ | |
+static void PrintMessage(char *Data); | |
+static void UpdateInventory(HWND HereList,HWND CarriedList, | |
+ HWND BuyButton,HWND SellButton,HWND DropButton, | |
+ Inventory *Objects, | |
+ int NumObjects,gboolean AreDrugs); | |
+static void UpdatePlayerLists(); | |
+static void UpdatePlayerList(HWND listwin,gboolean IncludeSelf); | |
+static void EndGame(); | |
+static void DisplayFightMessage(char *Data); | |
+static BOOL CALLBACK ScoresWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam); | |
+static void AddScoreToDialog(char *Data); | |
+static BOOL CALLBACK GunShopWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam); | |
+static BOOL CALLBACK QuestionWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam); | |
+static BOOL CALLBACK TransferWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam); | |
+static BOOL CALLBACK NewNameWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam); | |
+static void UpdateControls(); | |
+static void SetSocketWriteTest(Player *Play,gboolean WriteTest); | |
+static void DisplaySpyReports(Player *Play); | |
+static void CreateStats(HWND hwnd,struct STATS *Stats, | |
+ gboolean CreateEdit,gboolean CreateButtons); | |
+static void SizeStats(HWND hwnd,struct STATS *Stats,RECT *rect); | |
+static void ShowStats(struct STATS *Stats,int State); | |
+ | |
+static void LogMessage(const gchar *log_domain,GLogLevelFlags log_level, | |
+ const gchar *message,gpointer user_data) { | |
+ MessageBox(ClientData.Window,message, | |
+ log_level&G_LOG_LEVEL_WARNING ? "Warning" : "Message",MB_OK); | |
+} | |
+ | |
+static void DisplayStats(Player *Play,struct STATS *Stats) { | |
+ gchar *prstr,*caps; | |
+ GString *text; | |
+ | |
+ text=g_string_new(""); | |
+ SetWindowText(Stats->Location,Location[(int)Play->IsAt].Name); | |
+ | |
+ g_string_sprintf(text,"%s%02d%s",Names.Month,Play->Turn,Names.Year); | |
+ SetWindowText(Stats->Date,text->str); | |
+ | |
+ g_string_sprintf(text,"Space available: %d",Play->CoatSize); | |
+ SetWindowText(Stats->Space,text->str); | |
+ | |
+ prstr=FormatPrice(Play->Cash); | |
+ g_string_sprintf(text,"Cash: %s",prstr); | |
+ SetWindowText(Stats->Cash,text->str); | |
+ g_free(prstr); | |
+ | |
+ prstr=FormatPrice(Play->Debt); | |
+ g_string_sprintf(text,"Debt: %s",prstr); | |
+ SetWindowText(Stats->Debt,text->str); | |
+ g_free(prstr); | |
+ | |
+ prstr=FormatPrice(Play->Bank); | |
+ g_string_sprintf(text,"Bank: %s",prstr); | |
+ SetWindowText(Stats->Bank,text->str); | |
+ g_free(prstr); | |
+ | |
+ caps=InitialCaps(Names.Guns); | |
+ g_string_sprintf(text,"%s: %d",caps,TotalGunsCarried(Play)); | |
+ SetWindowText(Stats->Guns,text->str); | |
+ g_free(caps); | |
+ | |
+ if (!WantAntique) { | |
+ caps=InitialCaps(Names.Bitches); | |
+ g_string_sprintf(text,"%s: %d",caps,Play->Bitches.Carried); | |
+ SetWindowText(Stats->Bitches,text->str); | |
+ g_free(caps); | |
+ } else SetWindowText(Stats->Bitches,""); | |
+ | |
+ g_string_sprintf(text,"Health: %d",Play->Health); | |
+ SetWindowText(Stats->Health,text->str); | |
+ | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+static void UpdateStatus(Player *Play,gboolean DisplayDrugs) { | |
+ DisplayStats(Play,&ClientData.Stats); | |
+ | |
+ UpdateInventory(ClientData.Stats.HereList,ClientData.Stats.CarriedList, | |
+ ClientData.Stats.BuyButton,ClientData.Stats.SellButton, | |
+ ClientData.Stats.DropButton,Play->Drugs,NumDrug,TRUE); | |
+ if (GunShopWnd) { | |
+ UpdateInventory(GetDlgItem(GunShopWnd,LB_GUNSHERE), | |
+ GetDlgItem(GunShopWnd,LB_GUNSCARRIED), | |
+ GetDlgItem(GunShopWnd,BT_BUYGUN), | |
+ GetDlgItem(GunShopWnd,BT_SELLGUN), | |
+ NULL,ClientData.Play->Guns,NumGun,FALSE); | |
+ } | |
+ if (InventoryWnd) { | |
+ UpdateInventory(NULL,GetDlgItem(InventoryWnd,LB_INVENDRUGS), | |
+ NULL,NULL,NULL,ClientData.Play->Drugs,NumDrug,TRUE); | |
+ UpdateInventory(NULL,GetDlgItem(InventoryWnd,LB_INVENGUNS), | |
+ NULL,NULL,NULL,ClientData.Play->Guns,NumGun,FALSE); | |
+ } | |
+} | |
+ | |
+void UpdateInventory(HWND HereList,HWND CarriedList, | |
+ HWND BuyButton,HWND SellButton,HWND DropButton, | |
+ Inventory *Objects,int NumObjects,gboolean AreDrugs) { | |
+ Player *Play; | |
+ gint i; | |
+ price_t price; | |
+ gchar *name,*prstr,*text; | |
+ LRESULT addresult; | |
+ gboolean CanBuy=FALSE,CanSell=FALSE,CanDrop=FALSE; | |
+ | |
+ Play=ClientData.Play; | |
+ | |
+ SendMessage(HereList,LB_RESETCONTENT,0,0); | |
+ SendMessage(CarriedList,LB_RESETCONTENT,0,0); | |
+ for (i=0;i<NumObjects;i++) { | |
+ if (AreDrugs) { | |
+ name=Drug[i].Name; price=Objects[i].Price; | |
+ } else { | |
+ name=Gun[i].Name; price=Gun[i].Price; | |
+ } | |
+ if (HereList && price>0) { | |
+ CanBuy=TRUE; | |
+ prstr=FormatPrice(price); | |
+ text=g_strdup_printf("%s\t%s",name,prstr); | |
+ addresult=SendMessage(HereList,LB_ADDSTRING,0,(LPARAM)text); | |
+ if (addresult>=0 && addresult<NumObjects) { | |
+ SendMessage(HereList,LB_SETITEMDATA,(WPARAM)addresult,(LPARAM)i); | |
+ } | |
+ g_free(text); g_free(prstr); | |
+ } | |
+ if (Objects[i].Carried>0) { | |
+ if (price>0) CanSell=TRUE; else CanDrop=TRUE; | |
+ text=g_strdup_printf("%s\t%d",name,Objects[i].Carried); | |
+ addresult=SendMessage(CarriedList,LB_ADDSTRING,0,(LPARAM)text); | |
+ if (addresult>=0 && addresult<NumObjects) { | |
+ SendMessage(CarriedList,LB_SETITEMDATA,(WPARAM)addresult,(LPARAM)i… | |
+ } | |
+ g_free(text); | |
+ } | |
+ } | |
+ if (BuyButton) EnableWindow(BuyButton,CanBuy); | |
+ if (SellButton) EnableWindow(SellButton,CanSell); | |
+ if (DropButton) EnableWindow(DropButton,CanDrop); | |
+} | |
+ | |
+static void SetErrandMenus(HWND hwnd) { | |
+ gchar *text,*prstr; | |
+ HMENU menu; | |
+ menu=GetMenu(hwnd); | |
+ if (!menu) return; | |
+ | |
+ prstr=FormatPrice(Prices.Spy); | |
+ text=g_strdup_printf("&Spy\t(%s)",prstr); | |
+ ModifyMenu(menu,ID_SPY,MF_BYCOMMAND | MF_STRING,ID_SPY,text); | |
+ g_free(text); g_free(prstr); | |
+ | |
+ prstr=FormatPrice(Prices.Tipoff); | |
+ text=g_strdup_printf("&Tipoff\t(%s)",prstr); | |
+ ModifyMenu(menu,ID_TIPOFF,MF_BYCOMMAND | MF_STRING,ID_TIPOFF,text); | |
+ g_free(text); g_free(prstr); | |
+ | |
+ DrawMenuBar(hwnd); | |
+} | |
+ | |
+static void HandleClientMessage(char *pt,Player *ReallyTo) { | |
+ char *Data,Code,AICode,DisplayMode; | |
+ Player *From,*To,*Play; | |
+ gboolean Handled; | |
+ gchar *text; | |
+ LRESULT Answer; | |
+ GSList *list; | |
+ if (ProcessMessage(pt,&From,&AICode,&Code,&To,&Data,FirstClient)==-1) { | |
+ return; | |
+ } | |
+ Handled=HandleGenericClientMessage(From,AICode,Code,To,Data,&DisplayMode); | |
+ switch(Code) { | |
+ case C_STARTHISCORE: | |
+ if (ScoresWnd) { | |
+ SetWindowPos(ScoresWnd,HWND_TOP,0,0,0,0, | |
+ SWP_NOMOVE|SWP_NOSIZE); | |
+ } else { | |
+ ScoresWnd=CreateDialog(hInst,MAKEINTRESOURCE(HiScoreDia), | |
+ ClientData.Window,ScoresWndProc); | |
+ ShowWindow(ScoresWnd,SW_SHOWNORMAL); | |
+ } | |
+ SendDlgItemMessage(ScoresWnd,LB_HISCORES,LB_RESETCONTENT,0,0); | |
+ break; | |
+ case C_HISCORE: | |
+ AddScoreToDialog(Data); break; | |
+ case C_ENDHISCORE: | |
+ if (strcmp(Data,"end")==0) EndGame(); | |
+ break; | |
+ case C_PRINTMESSAGE: | |
+ PrintMessage(Data); break; | |
+ case C_FIGHTPRINT: | |
+ DisplayFightMessage(Data); break; | |
+ case C_PUSH: | |
+ g_warning("You have been pushed from the server."); | |
+ SwitchToSinglePlayer(To); | |
+ break; | |
+ case C_QUIT: | |
+ g_warning("The server has terminated."); | |
+ SwitchToSinglePlayer(To); | |
+ break; | |
+ case C_NEWNAME: | |
+ DialogBox(hInst,MAKEINTRESOURCE(NewNameDia), | |
+ ClientData.Window,NewNameWndProc); | |
+ break; | |
+ case C_BANK: | |
+ DialogBoxParam(hInst,MAKEINTRESOURCE(BankDialog), | |
+ ClientData.Window,TransferWndProc,(LPARAM)C_BANK); | |
+ break; | |
+ case C_LOANSHARK: | |
+ DialogBoxParam(hInst,MAKEINTRESOURCE(DebtDialog), | |
+ ClientData.Window,TransferWndProc,(LPARAM)C_LOANSHARK); | |
+ break; | |
+ case C_GUNSHOP: | |
+ EnableWindow(ClientData.Window,FALSE); | |
+ GunShopWnd=CreateDialog(hInst,MAKEINTRESOURCE(GunShopDia), | |
+ ClientData.Window,GunShopWndProc); | |
+ EnableWindow(GunShopWnd,TRUE); | |
+ ShowWindow(GunShopWnd,SW_SHOW); | |
+ break; | |
+ case C_MSG: | |
+ text=g_strdup_printf("%s: %s",GetPlayerName(From),Data); | |
+ PrintMessage(text); g_free(text); | |
+ break; | |
+ case C_MSGTO: | |
+ text=g_strdup_printf("%s->%s: %s",GetPlayerName(From), | |
+ GetPlayerName(To),Data); | |
+ PrintMessage(text); g_free(text); | |
+ break; | |
+ case C_JOIN: | |
+ text=g_strdup_printf("%s joins the game!",Data); | |
+ PrintMessage(text); g_free(text); | |
+ UpdatePlayerLists(); | |
+ break; | |
+ case C_LEAVE: | |
+ if (From!=&Noone) { | |
+ text=g_strdup_printf("%s has left the game.",Data); | |
+ PrintMessage(text); g_free(text); | |
+ UpdatePlayerLists(); | |
+ } | |
+ break; | |
+ case C_QUESTION: | |
+ Answer=DialogBoxParam(hInst,MAKEINTRESOURCE(QuestionDia), | |
+ ClientData.Window,QuestionWndProc,(LPARAM)Data); | |
+ if (Answer!=0) { | |
+ text=g_strdup_printf("%c",(char)Answer); | |
+ SendClientMessage(To,C_NONE,C_ANSWER, | |
+ From==&Noone ? NULL : From,text,To); | |
+ g_free(text); | |
+ } | |
+ break; | |
+ case C_SUBWAYFLASH: | |
+ DisplayFightMessage(NULL); | |
+ for (list=FirstClient;list;list=g_slist_next(list)) { | |
+ Play=(Player *)list->data; | |
+ Play->Flags &= ~FIGHTING; | |
+ } | |
+ text=g_strdup_printf("Jetting to %s",Location[(int)To->IsAt].Name); | |
+ PrintMessage(text); g_free(text); | |
+ break; | |
+ case C_ENDLIST: | |
+ SetErrandMenus(ClientData.Window); | |
+ break; | |
+ case C_UPDATE: | |
+ if (From==&Noone) { | |
+ ReceivePlayerData(Data,To); | |
+ UpdateStatus(To,TRUE); | |
+ } else { | |
+ ReceivePlayerData(Data,From); | |
+ DisplaySpyReports(From); | |
+ } | |
+ break; | |
+ case C_DRUGHERE: | |
+ UpdateInventory(ClientData.Stats.HereList,ClientData.Stats.CarriedLis… | |
+ ClientData.Stats.BuyButton,ClientData.Stats.SellButto… | |
+ ClientData.Stats.DropButton,To->Drugs,NumDrug,TRUE); | |
+ if (InventoryWnd) { | |
+ UpdateInventory(NULL,GetDlgItem(InventoryWnd,LB_INVENDRUGS), | |
+ NULL,NULL,NULL,To->Drugs,NumDrug,TRUE); | |
+ } | |
+ break; | |
+ } | |
+} | |
+ | |
+static void StartGame() { | |
+ Player *Play; | |
+ Play=ClientData.Play=g_new(Player,1); | |
+ FirstClient=AddPlayer(0,Play,FirstClient); | |
+ Play->fd=ClientSock; | |
+ SetPlayerName(Play,ClientData.PlayerName); | |
+ SendClientMessage(NULL,C_NONE,C_NAME,NULL,ClientData.PlayerName,Play); | |
+ InGame=TRUE; | |
+ UpdateControls(); | |
+ if (Network) { | |
+ SetSocketWriteTest(ClientData.Play,TRUE); | |
+ } | |
+ SetWindowText(ClientData.Stats.MessageEdit,""); | |
+ UpdatePlayerLists(); | |
+} | |
+ | |
+void EndGame() { | |
+ DisplayFightMessage(NULL); | |
+ g_free(ClientData.PlayerName); | |
+ ClientData.PlayerName=g_strdup(GetPlayerName(ClientData.Play)); | |
+ if (Network) { | |
+ WSAAsyncSelect(ClientSock,ClientData.Window,0,0); | |
+ } | |
+ ShutdownNetwork(); | |
+ UpdatePlayerLists(); | |
+ CleanUpServer(); | |
+ InGame=FALSE; | |
+ UpdateControls(); | |
+} | |
+ | |
+void PrintMessage(char *text) { | |
+ int buflen; | |
+ gchar *buffer,**split,*joined; | |
+ if (!text) return; | |
+ | |
+ while (*text=='^') text++; | |
+ split=g_strsplit(text,"^",0); | |
+ joined=g_strjoinv("\r\n",split); | |
+ g_strfreev(split); | |
+ | |
+ if (joined[strlen(joined)-1]!='\n') { | |
+ buffer=g_strdup_printf("%s\r\n",joined); | |
+ } else buffer=joined; | |
+ | |
+ buflen=GetWindowTextLength(ClientData.Stats.MessageEdit); | |
+ SendMessage(ClientData.Stats.MessageEdit,EM_SETSEL,(WPARAM)buflen, | |
+ (WPARAM)buflen); | |
+ SendMessage(ClientData.Stats.MessageEdit,EM_REPLACESEL,FALSE,(LPARAM)buffer… | |
+ g_free(buffer); | |
+} | |
+ | |
+void UpdateControls() { | |
+ HMENU Menu; | |
+ UINT State; | |
+ | |
+ Menu=GetMenu(ClientData.Window); | |
+ State = MF_BYPOSITION | (InGame ? MF_ENABLED : MF_GRAYED); | |
+ | |
+ EnableMenuItem(Menu,1,State); | |
+ EnableMenuItem(Menu,2,State); | |
+ EnableMenuItem(Menu,3,State); | |
+ DrawMenuBar(ClientData.Window); | |
+ | |
+ EnableWindow(ClientData.Stats.JetButton,InGame); | |
+ if (!InGame) { | |
+ EnableWindow(ClientData.Stats.BuyButton,FALSE); | |
+ EnableWindow(ClientData.Stats.DropButton,FALSE); | |
+ EnableWindow(ClientData.Stats.SellButton,FALSE); | |
+ } | |
+} | |
+ | |
+void SetSocketWriteTest(Player *Play,gboolean WriteTest) { | |
+ if (Network) { | |
+ WSAAsyncSelect(Play->fd,ClientData.Window,WM_SOCKETDATA, | |
+ FD_READ|(WriteTest ? FD_WRITE : 0)); | |
+ } | |
+} | |
+ | |
+static void UpdateDealDialog(HWND hwnd,LONG DealType,int DrugInd) { | |
+ GString *text; | |
+ gchar *prstr; | |
+ Player *Play; | |
+ int CanDrop,CanCarry,CanAfford,MaxDrug; | |
+ | |
+ Play=ClientData.Play; | |
+ text=g_string_new(""); | |
+ | |
+ CanDrop=Play->Drugs[DrugInd].Carried; | |
+ CanCarry=Play->CoatSize; | |
+ prstr=FormatPrice(Play->Drugs[DrugInd].Price); | |
+ g_string_sprintf(text,"at %s",prstr); | |
+ g_free(prstr); | |
+ SetDlgItemText(hwnd,ST_DEALPRICE,text->str); | |
+ | |
+ g_string_sprintf(text,"You are currently carrying %d %s", | |
+ CanDrop,Drug[DrugInd].Name); | |
+ SetDlgItemText(hwnd,ST_DEALCARRY,text->str); | |
+ if (DealType==BT_BUY) { | |
+ CanAfford=Play->Cash/Play->Drugs[DrugInd].Price; | |
+ g_string_sprintf(text,"You can afford %d, and can carry %d", | |
+ CanAfford,CanCarry); | |
+ SetDlgItemText(hwnd,ST_DEALLIMIT,text->str); | |
+ MaxDrug=MIN(CanCarry,CanAfford); | |
+ } else { | |
+ MaxDrug=CanDrop; | |
+ SetDlgItemText(hwnd,ST_DEALLIMIT,""); | |
+ } | |
+ | |
+ SendDlgItemMessage(hwnd,SB_DEALNUM,UDM_SETRANGE, | |
+ 0,(LPARAM)MAKELONG(MaxDrug,0)); | |
+ SendDlgItemMessage(hwnd,SB_DEALNUM,UDM_SETPOS,0,(LPARAM)MaxDrug); | |
+/* g_string_sprintf(text,"%d",MaxDrug); | |
+ SetDlgItemText(hwnd,ED_DEALNUM,text->str);*/ | |
+ | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+void UpdatePlayerLists() { | |
+ if (TalkWnd) { | |
+ UpdatePlayerList(GetDlgItem(TalkWnd,LB_TALKPLAYERS),FALSE); | |
+ } | |
+ if (PlayerListWnd) { | |
+ UpdatePlayerList(GetDlgItem(PlayerListWnd,LB_PLAYERLIST),FALSE); | |
+ } | |
+} | |
+ | |
+void UpdatePlayerList(HWND listwin,gboolean IncludeSelf) { | |
+ GSList *list; | |
+ LRESULT row; | |
+ Player *Play; | |
+ SendMessage(listwin,LB_RESETCONTENT,0,0); | |
+ for (list=FirstClient;list;list=g_slist_next(list)) { | |
+ Play=(Player *)list->data; | |
+ if (IncludeSelf || Play!=ClientData.Play) { | |
+ row=SendMessage(listwin,LB_ADDSTRING,0,(LPARAM)GetPlayerName(Play)); | |
+ if (row!=LB_ERR && row!=LB_ERRSPACE) { | |
+ SendMessage(listwin,LB_SETITEMDATA,(WPARAM)row,(LPARAM)Play); | |
+ } | |
+ } | |
+ } | |
+} | |
+ | |
+BOOL CALLBACK TalkWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ int textlength,listlength,i; | |
+ LRESULT LBResult; | |
+ gchar *text; | |
+ GString *message; | |
+ HWND MessageWnd,ListWnd; | |
+ Player *Play; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ CheckDlgButton(hwnd,CB_TALKALL,lParam ? BST_CHECKED : BST_UNCHECKED); | |
+ UpdatePlayerList(GetDlgItem(hwnd,LB_TALKPLAYERS),FALSE); | |
+ return TRUE; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_CANCEL) { | |
+ DestroyWindow(hwnd); return TRUE; | |
+ } else if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==BT_TALKSEND)… | |
+ MessageWnd=GetDlgItem(hwnd,EB_TALKMESSAGE); | |
+ ListWnd=GetDlgItem(hwnd,LB_TALKPLAYERS); | |
+ textlength=GetWindowTextLength(MessageWnd); | |
+ if (textlength>0) { | |
+ textlength++; | |
+ text=g_new(gchar,textlength); | |
+ GetWindowText(MessageWnd,text,textlength); | |
+ SetWindowText(MessageWnd,""); | |
+ message=g_string_new(""); | |
+ if (IsDlgButtonChecked(hwnd,CB_TALKALL)==BST_CHECKED) { | |
+ SendClientMessage(ClientData.Play,C_NONE,C_MSG,NULL,text, | |
+ ClientData.Play); | |
+ g_string_sprintf(message,"%s: %s", | |
+ GetPlayerName(ClientData.Play),text); | |
+ PrintMessage(message->str); | |
+ } else { | |
+ LBResult=SendMessage(ListWnd,LB_GETCOUNT,0,0); | |
+ if (LBResult!=LB_ERR) { | |
+ listlength=(int)LBResult; | |
+ for (i=0;i<listlength;i++) { | |
+ LBResult=SendMessage(ListWnd,LB_GETSEL,(WPARAM)i,0); | |
+ if (LBResult!=LB_ERR && LBResult>0) { | |
+ LBResult=SendMessage(ListWnd,LB_GETITEMDATA, | |
+ (WPARAM)i,0); | |
+ if (LBResult!=LB_ERR && LBResult) { | |
+ Play=(Player *)LBResult; | |
+ SendClientMessage(ClientData.Play,C_NONE,C_MSGTO, | |
+ Play,text,ClientData.Play); | |
+ g_string_sprintf(message,"%s->%s: %s", | |
+ GetPlayerName(ClientData.Play), | |
+ GetPlayerName(Play),text); | |
+ PrintMessage(message->str); | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ g_free(text); | |
+ g_string_free(message,TRUE); | |
+ return TRUE; | |
+ } | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ DestroyWindow(hwnd); | |
+ return TRUE; | |
+ case WM_DESTROY: | |
+ TalkWnd=NULL; | |
+ break; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+BOOL CALLBACK ScoresWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ return TRUE; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_CANCEL) { | |
+ DestroyWindow(hwnd); return TRUE; | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ DestroyWindow(hwnd); | |
+ return TRUE; | |
+ case WM_DESTROY: | |
+ ScoresWnd=NULL; | |
+ break; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+void AddScoreToDialog(char *Data) { | |
+ char *cp; | |
+ int index; | |
+ if (!ScoresWnd) return; | |
+ cp=Data; | |
+ index=GetNextInt(&cp,0); | |
+ if (!cp || strlen(cp)<1) return; | |
+ SendDlgItemMessage(ScoresWnd,LB_HISCORES,LB_INSERTSTRING,index, | |
+ (LPARAM)&cp[1]); | |
+} | |
+ | |
+BOOL CALLBACK GunShopWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ LRESULT LBRes,row; | |
+ HWND ListWnd; | |
+ int GunInd; | |
+ gchar *Title; | |
+ GString *text; | |
+ int Tabs=45; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ SendMessage(GetDlgItem(hwnd,LB_GUNSHERE),LB_SETTABSTOPS, | |
+ (WPARAM)1,(LPARAM)&Tabs); | |
+ SendMessage(GetDlgItem(hwnd,LB_GUNSCARRIED),LB_SETTABSTOPS, | |
+ (WPARAM)1,(LPARAM)&Tabs); | |
+ UpdateInventory(GetDlgItem(hwnd,LB_GUNSHERE), | |
+ GetDlgItem(hwnd,LB_GUNSCARRIED), | |
+ GetDlgItem(hwnd,BT_BUYGUN), | |
+ GetDlgItem(hwnd,BT_SELLGUN), | |
+ NULL,ClientData.Play->Guns,NumGun,FALSE); | |
+ return TRUE; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED) switch(LOWORD(wParam)) { | |
+ case ID_OK: | |
+ DestroyWindow(hwnd); return TRUE; | |
+ case BT_BUYGUN: | |
+ case BT_SELLGUN: | |
+ if (LOWORD(wParam)==BT_BUYGUN) { | |
+ ListWnd=GetDlgItem(hwnd,LB_GUNSHERE); | |
+ } else { | |
+ ListWnd=GetDlgItem(hwnd,LB_GUNSCARRIED); | |
+ } | |
+ row=SendMessage(ListWnd,LB_GETCURSEL,0,0); | |
+ GunInd=-1; | |
+ if (row!=LB_ERR) { | |
+ LBRes=SendMessage(ListWnd,LB_GETITEMDATA,row,0); | |
+ if (LBRes!=LB_ERR) GunInd=(int)LBRes; | |
+ } | |
+ if (GunInd==-1) break; | |
+ Title=g_strdup_printf("%s %s", | |
+ LOWORD(wParam)==BT_BUYGUN ? "Buy" : "Sell", | |
+ Names.Guns); | |
+ text=g_string_new(""); | |
+ if (LOWORD(wParam)==BT_SELLGUN && | |
+ TotalGunsCarried(ClientData.Play)==0) { | |
+ g_string_sprintf(text,"You don't have any %s!",Names.Guns); | |
+ MessageBox(hwnd,text->str,Title,MB_OK); | |
+ } else if (LOWORD(wParam)==BT_BUYGUN && | |
+ Gun[GunInd].Space > ClientData.Play->CoatSize) { | |
+ g_string_sprintf(text, | |
+ "You don't have enough space to carry that %s!", | |
+ Names.Gun); | |
+ MessageBox(hwnd,text->str,Title,MB_OK); | |
+ } else if (LOWORD(wParam)==BT_BUYGUN && | |
+ Gun[GunInd].Price > ClientData.Play->Cash) { | |
+ g_string_sprintf(text, | |
+ "You don't have enough cash to buy that %s!", | |
+ Names.Gun); | |
+ MessageBox(hwnd,text->str,Title,MB_OK); | |
+ } else if (LOWORD(wParam)==BT_SELLGUN && | |
+ ClientData.Play->Guns[GunInd].Carried==0) { | |
+ MessageBox(hwnd,"You don't have any to sell!",Title,MB_OK); | |
+ } else { | |
+ g_string_sprintf(text,"gun^%d^%d",GunInd, | |
+ LOWORD(wParam)==BT_BUYGUN ? 1 : -1); | |
+ SendClientMessage(ClientData.Play,C_NONE,C_BUYOBJECT, | |
+ NULL,text->str,ClientData.Play); | |
+ } | |
+ g_free(Title); | |
+ g_string_free(text,TRUE); | |
+ break; | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ DestroyWindow(hwnd); | |
+ return TRUE; | |
+ case WM_DESTROY: | |
+ GunShopWnd=NULL; | |
+ EnableWindow(ClientData.Window,TRUE); | |
+ SendClientMessage(ClientData.Play,C_NONE,C_DONE,NULL,NULL, | |
+ ClientData.Play); | |
+ return TRUE; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+static BOOL CALLBACK InventoryWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ int Tabs=45; | |
+ HWND List; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ List=GetDlgItem(hwnd,LB_INVENDRUGS); | |
+ SendMessage(List,LB_SETTABSTOPS,(WPARAM)1,(LPARAM)&Tabs); | |
+ UpdateInventory(NULL,List,NULL,NULL,NULL, | |
+ ClientData.Play->Drugs,NumDrug,TRUE); | |
+ List=GetDlgItem(hwnd,LB_INVENGUNS); | |
+ SendMessage(List,LB_SETTABSTOPS,(WPARAM)1,(LPARAM)&Tabs); | |
+ UpdateInventory(NULL,List,NULL,NULL,NULL, | |
+ ClientData.Play->Guns,NumGun,FALSE); | |
+ return TRUE; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_CANCEL) { | |
+ DestroyWindow(hwnd); return TRUE; | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ DestroyWindow(hwnd); | |
+ return TRUE; | |
+ case WM_DESTROY: | |
+ InventoryWnd=NULL; | |
+ break; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+BOOL CALLBACK PlayerListWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ UpdatePlayerList(GetDlgItem(hwnd,LB_PLAYERLIST),FALSE); | |
+ return TRUE; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_CANCEL) { | |
+ DestroyWindow(hwnd); return TRUE; | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ DestroyWindow(hwnd); | |
+ return TRUE; | |
+ case WM_DESTROY: | |
+ PlayerListWnd=NULL; | |
+ break; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+BOOL CALLBACK NewNameWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ int buflen; | |
+ gchar *text; | |
+ HWND EditWnd; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ SetDlgItemText(hwnd,EB_NEWNAME,GetPlayerName(ClientData.Play)); | |
+ return TRUE; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_OK) { | |
+ EditWnd=GetDlgItem(hwnd,EB_NEWNAME); | |
+ buflen=GetWindowTextLength(EditWnd); | |
+ text=g_new(char,buflen+1); | |
+ GetWindowText(EditWnd,text,buflen+1); | |
+ SetPlayerName(ClientData.Play,text); | |
+ SendClientMessage(NULL,C_NONE,C_NAME,NULL,text,ClientData.Play); | |
+ g_free(text); | |
+ DestroyWindow(hwnd); | |
+ return TRUE; | |
+ } | |
+ break; | |
+ case WM_DESTROY: | |
+ EndDialog(hwnd,0); return TRUE; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+BOOL CALLBACK TransferWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ static char Type; | |
+ HWND MoneyWnd; | |
+ int buflen; | |
+ price_t money; | |
+ gchar *text,*prstr; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ Type=(char)lParam; | |
+ prstr=FormatPrice(ClientData.Play->Cash); | |
+ text=g_strdup_printf("Cash: %s",prstr); | |
+ SetDlgItemText(hwnd,ST_MONEY,text); | |
+ g_free(text); g_free(prstr); | |
+ if (Type==C_BANK) { | |
+ CheckDlgButton(hwnd,RB_WITHDRAW,BST_CHECKED); | |
+ prstr=FormatPrice(ClientData.Play->Bank); | |
+ text=g_strdup_printf("Bank: %s",prstr); | |
+ } else { | |
+ prstr=FormatPrice(ClientData.Play->Debt); | |
+ text=g_strdup_printf("Debt: %s",prstr); | |
+ } | |
+ SetDlgItemText(hwnd,ST_BANK,text); | |
+ g_free(text); g_free(prstr); | |
+ return TRUE; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED) switch(LOWORD(wParam)) { | |
+ case ID_CANCEL: | |
+ SendMessage(hwnd,WM_CLOSE,0,0); | |
+ return TRUE; | |
+ case ID_OK: | |
+ MoneyWnd=GetDlgItem(hwnd,EB_MONEY); | |
+ buflen=GetWindowTextLength(MoneyWnd); | |
+ prstr=g_new(char,buflen+1); | |
+ GetWindowText(MoneyWnd,prstr,buflen+1); | |
+ money=strtoprice(prstr); g_free(prstr); | |
+ if (money<0) money=0; | |
+ if (Type==C_LOANSHARK) { | |
+ if (money>ClientData.Play->Debt) money=ClientData.Play->Debt; | |
+ } else { | |
+ if (IsDlgButtonChecked(hwnd,RB_WITHDRAW)==BST_CHECKED) { | |
+ money=-money; | |
+ } | |
+ if (-money>ClientData.Play->Bank) { | |
+ MessageBox(hwnd, | |
+ "There isn't that much money in the bank...", | |
+ "Bank",MB_OK); | |
+ return TRUE; | |
+ } | |
+ } | |
+ if (money>ClientData.Play->Cash) { | |
+ MessageBox(hwnd,"You don't have that much money!", | |
+ Type==C_LOANSHARK ? "Pay loan" : "Bank",MB_OK); | |
+ return TRUE; | |
+ } | |
+ text=pricetostr(money); | |
+ SendClientMessage(ClientData.Play,C_NONE, | |
+ Type==C_LOANSHARK ? C_PAYLOAN : C_DEPOSIT, | |
+ NULL,text,ClientData.Play); | |
+ g_free(text); | |
+ SendMessage(hwnd,WM_CLOSE,0,0); | |
+ return TRUE; | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ EndDialog(hwnd,0); | |
+ SendClientMessage(ClientData.Play,C_NONE,C_DONE,NULL,NULL, | |
+ ClientData.Play); | |
+ return TRUE; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+BOOL CALLBACK QuestionWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ char *Data; | |
+ HWND button; | |
+ gchar *Words[] = { "&Yes", "&No", "&Run", "&Fight", "&Attack", "&Evade" }; | |
+ gint NumWords = sizeof(Words) / sizeof(Words[0]); | |
+ gint i,x,xspacing,y,Width,Height,NumButtons; | |
+ RECT rect; | |
+ gchar **split,*Responses,*LabelText; | |
+ gint Answer; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ Data=(char *)lParam; | |
+ split=g_strsplit(Data,"^",1); | |
+ if (!split[0] || !split[1]) { | |
+ g_warning("Bad QUESTION message %s",Data); return TRUE; | |
+ } | |
+ g_strdelimit(split[1],"^",'\n'); | |
+ Responses=split[0]; LabelText=split[1]; | |
+ while (*LabelText=='\n') LabelText++; | |
+ SetDlgItemText(hwnd,ST_TEXT,LabelText); | |
+ GetClientRect(hwnd,&rect); | |
+ NumButtons=0; | |
+ for (i=0;i<NumWords;i++) { | |
+ Answer=Words[i][0]; | |
+ if (Answer=='&' && strlen(Words[i])>=2) Answer=Words[i][1]; | |
+ if (strchr(Responses,Answer)) NumButtons++; | |
+ } | |
+ y=rect.bottom-38; | |
+ Width=60; Height=28; | |
+ xspacing=(rect.right-20)/(NumButtons+1); | |
+ NumButtons=0; | |
+ for (i=0;i<NumWords;i++) { | |
+ Answer=Words[i][0]; | |
+ if (Answer=='&' && strlen(Words[i])>=2) Answer=Words[i][1]; | |
+ if (strchr(Responses,Answer)) { | |
+ NumButtons++; | |
+ x=10+xspacing*NumButtons-Width/2; | |
+ button=CreateWindow("BUTTON",Words[i], | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|BS_PUSHBUTTO… | |
+ x,y,Width,Height,hwnd, | |
+ (HMENU)Answer,hInst,NULL); | |
+ } | |
+ } | |
+ g_strfreev(split); | |
+ break; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED) { | |
+ EndDialog(hwnd,LOWORD(wParam)); | |
+ return TRUE; | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ EndDialog(hwnd,0); return TRUE; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+static BOOL CALLBACK DealWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ static LONG DealType=0; | |
+ static char *DealString=""; | |
+ gchar *text; | |
+ char Num[40]; | |
+ Player *Play; | |
+ HWND ListWnd,UpDownWnd; | |
+ LRESULT Selection,Index,Data; | |
+ static int DrugInd; | |
+ int i,FirstInd,amount; | |
+ gboolean DrugIndOK; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ UpDownWnd=CreateUpDownControl(WS_CHILD|WS_BORDER|WS_VISIBLE| | |
+ UDS_ALIGNRIGHT|UDS_ARROWKEYS| | |
+ UDS_SETBUDDYINT|UDS_NOTHOUSANDS, | |
+ 0,0,1,1,hwnd,SB_DEALNUM,hInst, | |
+ GetDlgItem(hwnd,ED_DEALNUM), | |
+ 0,100,100); | |
+ SendMessage(UpDownWnd,UDM_SETBASE,10,0); | |
+ Play=ClientData.Play; | |
+ DealType=lParam; | |
+ switch(DealType) { | |
+ case BT_BUY: DealString="Buy"; break; | |
+ case BT_SELL: DealString="Sell"; break; | |
+ case BT_DROP: DealString="Drop"; break; | |
+ } | |
+ SetDlgItemText(hwnd,ST_DEALTYPE,DealString); | |
+ text=g_strdup_printf("%s how many?",DealString); | |
+ SetDlgItemText(hwnd,ST_DEALNUM,text); g_free(text); | |
+ if (DealType==BT_BUY) ListWnd=ClientData.Stats.HereList; | |
+ else ListWnd=ClientData.Stats.CarriedList; | |
+ DrugInd=-1; | |
+ Selection=SendMessage(ListWnd,LB_GETCURSEL,0,0); | |
+ if (Selection!=LB_ERR) { | |
+ Data=SendMessage(ListWnd,LB_GETITEMDATA,Selection,0); | |
+ if (Data!=LB_ERR) DrugInd=(int)Data; | |
+ } | |
+ | |
+ DrugIndOK=FALSE; | |
+ FirstInd=-1; | |
+ for (i=0;i<NumDrug;i++) { | |
+ if ((DealType==BT_DROP && Play->Drugs[i].Carried>0 && | |
+ Play->Drugs[i].Price==0) || | |
+ (DealType==BT_SELL && Play->Drugs[i].Carried>0 && | |
+ Play->Drugs[i].Price!=0) || | |
+ (DealType==BT_BUY && Play->Drugs[i].Price!=0)) { | |
+ if (FirstInd==-1) FirstInd=i; | |
+ if (DrugInd==i) DrugIndOK=TRUE; | |
+ } | |
+ } | |
+ if (!DrugIndOK) { | |
+ if (FirstInd==-1) { EndDialog(hwnd,0); return TRUE; } | |
+ else DrugInd=FirstInd; | |
+ } | |
+ for (i=0;i<NumDrug;i++) { | |
+ if ((DealType==BT_DROP && Play->Drugs[i].Carried>0 && | |
+ Play->Drugs[i].Price==0) || | |
+ (DealType==BT_SELL && Play->Drugs[i].Carried>0 && | |
+ Play->Drugs[i].Price!=0) || | |
+ (DealType==BT_BUY && Play->Drugs[i].Price!=0)) { | |
+ Index=SendDlgItemMessage(hwnd,CB_DEALDRUG,CB_ADDSTRING, | |
+ 0,(LPARAM)Drug[i].Name); | |
+ if (Index!=CB_ERR) { | |
+ SendDlgItemMessage(hwnd,CB_DEALDRUG,CB_SETITEMDATA,Index,i); | |
+ if (i==DrugInd) { | |
+ SendDlgItemMessage(hwnd,CB_DEALDRUG,CB_SETCURSEL,Index,0); | |
+ } | |
+ } | |
+ } | |
+ } | |
+ UpdateDealDialog(hwnd,DealType,DrugInd); | |
+ break; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==CBN_SELCHANGE && LOWORD(wParam)==CB_DEALDRUG) { | |
+ Index=SendDlgItemMessage(hwnd,CB_DEALDRUG,CB_GETCURSEL,0,0); | |
+ if (Index!=CB_ERR) { | |
+ Data=SendDlgItemMessage(hwnd,CB_DEALDRUG,CB_GETITEMDATA,Index,0… | |
+ if (Data!=CB_ERR) { | |
+ DrugInd=(int)Data; | |
+ UpdateDealDialog(hwnd,DealType,DrugInd); | |
+ } | |
+ } | |
+ } else if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_OK) { | |
+ Num[0]=0; | |
+ GetDlgItemText(hwnd,ED_DEALNUM,Num,39); | |
+ amount=atoi(Num); | |
+ text=g_strdup_printf("drug^%d^%d",DrugInd, | |
+ DealType==BT_BUY ? amount : -amount); | |
+ SendClientMessage(ClientData.Play,C_NONE,C_BUYOBJECT,NULL,text, | |
+ ClientData.Play); | |
+ g_free(text); | |
+ EndDialog(hwnd,0); return TRUE; | |
+ } else if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_CANCEL) { | |
+ EndDialog(hwnd,0); return TRUE; | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ EndDialog(hwnd,0); return TRUE; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+static BOOL CALLBACK JetWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ gint boxsize,i,row,col,ButtonWidth,NewLocation; | |
+ HWND button; | |
+ gchar *name,AccelChar; | |
+ SIZE TextSize; | |
+ HDC hDC; | |
+ gchar *text; | |
+ ButtonWidth=40; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ boxsize=1; | |
+ while (boxsize*boxsize < NumLocation) boxsize++; | |
+ for (i=0;i<NumLocation;i++) { | |
+ if (i<9) AccelChar='1'+i; | |
+ else if (i<35) AccelChar='A'+i-9; | |
+ else AccelChar='\0'; | |
+ row=i/boxsize; col=i%boxsize; | |
+ if (AccelChar=='\0') name=Location[i].Name; | |
+ else { | |
+ name=g_strdup_printf("&%c. %s",AccelChar,Location[i].Name); | |
+ } | |
+ button=CreateWindow("BUTTON",name, | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|BS_PUSHBUTTON, | |
+ 0,0,1,1,hwnd,(HMENU)i,hInst,NULL); | |
+ hDC=GetDC(button); | |
+ if (GetTextExtentPoint32(hDC,name,strlen(name),&TextSize) && | |
+ TextSize.cx+15 > ButtonWidth) { | |
+ ButtonWidth=TextSize.cx+15; | |
+ } | |
+ ReleaseDC(button,hDC); | |
+ if (i==ClientData.Play->IsAt) EnableWindow(button,FALSE); | |
+ if (AccelChar!='\0') g_free(name); | |
+ } | |
+ for (i=0;i<NumLocation;i++) { | |
+ row=i/boxsize; col=i%boxsize; | |
+ MoveWindow(GetDlgItem(hwnd,i), | |
+ 7+col*(ButtonWidth+5),38+row*33,ButtonWidth,28,FALSE); | |
+ } | |
+ SetWindowPos(hwnd,HWND_TOP,0,0, | |
+ 14+boxsize*(ButtonWidth+5),65+boxsize*33, | |
+ SWP_NOMOVE|SWP_NOOWNERZORDER); | |
+ break; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED) { | |
+ EndDialog(hwnd,0); | |
+ NewLocation=(gint)(LOWORD(wParam)); | |
+ text=g_strdup_printf("%d",NewLocation); | |
+ SendClientMessage(ClientData.Play,C_NONE,C_REQUESTJET,NULL,text, | |
+ ClientData.Play); | |
+ g_free(text); | |
+ return TRUE; | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ EndDialog(hwnd,0); return TRUE; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+#define MaxInd 3 | |
+#define NumIDs 5 | |
+ | |
+static void ShowPage(HWND hwnd,int TabIndex,int ShowType) { | |
+ static int IDs[MaxInd][NumIDs]={ | |
+ { ST_HOSTNAME,ST_PORT,ED_HOSTNAME,ED_PORT,BT_CONNECT }, | |
+ { CB_ANTIQUE,BT_STARTSINGLE,0,0,0 }, | |
+ { LB_SERVERLIST,BT_UPDATE,0,0,0 } | |
+ }; | |
+ int i; | |
+ if (!hwnd || TabIndex<0 || TabIndex>=MaxInd) return; | |
+ | |
+ for (i=0;i<NumIDs;i++) if (IDs[TabIndex][i]!=0) { | |
+ ShowWindow(GetDlgItem(hwnd,IDs[TabIndex][i]),ShowType); | |
+ } | |
+} | |
+ | |
+static gboolean GetEnteredName(HWND hwnd) { | |
+ int buflen; | |
+ g_free(ClientData.PlayerName); | |
+ buflen=GetWindowTextLength(GetDlgItem(hwnd,ED_NAME)); | |
+ ClientData.PlayerName=g_new(char,buflen+1); | |
+ GetDlgItemText(hwnd,ED_NAME,ClientData.PlayerName,buflen+1); | |
+ return (ClientData.PlayerName && ClientData.PlayerName[0]); | |
+} | |
+ | |
+static void FillMetaServerList(HWND hwnd) { | |
+ ServerData *ThisServer; | |
+ GSList *ListPt; | |
+ GString *text; | |
+ | |
+ text=g_string_new(""); | |
+ SendMessage(hwnd,LB_RESETCONTENT,0,0); | |
+ for (ListPt=ServerList;ListPt;ListPt=g_slist_next(ListPt)) { | |
+ ThisServer=(ServerData *)(ListPt->data); | |
+ g_string_sprintf(text,"%s\t%d",ThisServer->Name,ThisServer->Port); | |
+ SendMessage(hwnd,LB_ADDSTRING,0,(LPARAM)text->str); | |
+ } | |
+ g_string_free(text,TRUE); | |
+} | |
+ | |
+static void UpdateMetaServerList(HWND hwnd) { | |
+ char *MetaError; | |
+ int HttpSock; | |
+ MetaError=OpenMetaServerConnection(&HttpSock); | |
+ | |
+ if (MetaError) { | |
+ return; | |
+ } | |
+ ReadMetaServerData(HttpSock); | |
+ CloseMetaServerConnection(HttpSock); | |
+ MetaServerRead=TRUE; | |
+ FillMetaServerList(hwnd); | |
+} | |
+ | |
+static BOOL CALLBACK ErrandWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ LRESULT LBResult; | |
+ HWND ListWnd; | |
+ Player *Play; | |
+ static LONG ErrandType=0; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ ErrandType=lParam; | |
+ UpdatePlayerList(GetDlgItem(hwnd,LB_ERRANDPLAY),FALSE); | |
+ break; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_CANCEL) { | |
+ EndDialog(hwnd,1); return TRUE; | |
+ } else if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_OK) { | |
+ ListWnd=GetDlgItem(hwnd,LB_ERRANDPLAY); | |
+ LBResult=SendMessage(ListWnd,LB_GETCURSEL,0,0); | |
+ if (LBResult!=LB_ERR) { | |
+ LBResult=SendMessage(ListWnd,LB_GETITEMDATA,LBResult,0); | |
+ if (LBResult!=LB_ERR) { | |
+ Play=(Player *)LBResult; | |
+ SendClientMessage(ClientData.Play,C_NONE, | |
+ ErrandType==ID_SPY ? C_SPYON : C_TIPOFF, | |
+ Play,NULL,ClientData.Play); | |
+ EndDialog(hwnd,0); return TRUE; | |
+ } | |
+ } | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ EndDialog(hwnd,0); return TRUE; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+static BOOL CALLBACK NewGameWndProc(HWND hwnd,UINT msg,UINT wParam, | |
+ LONG lParam) { | |
+ gchar *NetworkError; | |
+ int buflen; | |
+ static HWND tabwnd=NULL; | |
+ TC_ITEM tie; | |
+ RECT rect; | |
+ NMHDR *nmhdr; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ if (ClientData.PlayerName) { | |
+ SetDlgItemText(hwnd,ED_NAME,ClientData.PlayerName); | |
+ } | |
+ SetDlgItemText(hwnd,ED_HOSTNAME,ServerName); | |
+ SetDlgItemInt(hwnd,ED_PORT,Port,FALSE); | |
+ CheckDlgButton(hwnd,CB_ANTIQUE, | |
+ WantAntique ? BST_CHECKED : BST_UNCHECKED); | |
+ GetClientRect(hwnd,&rect); | |
+ tabwnd=CreateWindow(WC_TABCONTROL,"", | |
+ WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE, | |
+ 10,40,rect.right-20,rect.bottom-50,hwnd, | |
+ NULL,hInst,NULL); | |
+ tie.mask = TCIF_TEXT | TCIF_IMAGE; | |
+ tie.iImage = -1; | |
+ tie.pszText = "Server"; | |
+ TabCtrl_InsertItem(tabwnd,0,&tie); | |
+ tie.pszText = "Single player"; | |
+ TabCtrl_InsertItem(tabwnd,1,&tie); | |
+ tie.pszText = "Metaserver"; | |
+ TabCtrl_InsertItem(tabwnd,2,&tie); | |
+ ShowPage(hwnd,TabCtrl_GetCurSel(tabwnd),SW_SHOW); | |
+ FillMetaServerList(GetDlgItem(hwnd,LB_SERVERLIST)); | |
+ return TRUE; | |
+ case WM_NOTIFY: | |
+ nmhdr = (NMHDR *)lParam; | |
+ if (nmhdr && nmhdr->code==TCN_SELCHANGE) { | |
+ ShowPage(hwnd,TabCtrl_GetCurSel(tabwnd),SW_SHOW); | |
+ } else if (nmhdr && nmhdr->code==TCN_SELCHANGING) { | |
+ ShowPage(hwnd,TabCtrl_GetCurSel(tabwnd),SW_HIDE); | |
+ } | |
+ break; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==BT_CONNECT) { | |
+ if (!GetEnteredName(hwnd)) return TRUE; | |
+ buflen=GetWindowTextLength(GetDlgItem(hwnd,ED_HOSTNAME)); | |
+ GetDlgItemText(hwnd,ED_HOSTNAME,ServerName,buflen+1); | |
+ Port=GetDlgItemInt(hwnd,ED_PORT,NULL,FALSE); | |
+ NetworkError=SetupNetwork(); | |
+ if (!NetworkError) { | |
+ EndDialog(hwnd,1); | |
+ StartGame(); | |
+ } | |
+ return TRUE; | |
+ } else if (HIWORD(wParam)==BN_CLICKED && | |
+ LOWORD(wParam)==BT_STARTSINGLE) { | |
+ if (IsDlgButtonChecked(hwnd,CB_ANTIQUE)==BST_CHECKED) | |
+ WantAntique=TRUE; else WantAntique=FALSE; | |
+ if (!GetEnteredName(hwnd)) return TRUE; | |
+ EndDialog(hwnd,1); | |
+ StartGame(); | |
+ return TRUE; | |
+ } else if (HIWORD(wParam)==BN_CLICKED && | |
+ LOWORD(wParam)==BT_UPDATE) { | |
+ UpdateMetaServerList(GetDlgItem(hwnd,LB_SERVERLIST)); | |
+ return TRUE; | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ EndDialog(hwnd,0); return TRUE; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+BOOL CALLBACK AboutWndProc(HWND hwnd,UINT msg,UINT wParam,LONG lParam) { | |
+ switch(msg) { | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_OK) { | |
+ EndDialog(hwnd,1); return TRUE; | |
+ } | |
+ break; | |
+ case WM_CLOSE: | |
+ EndDialog(hwnd,0); return TRUE; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+void CreateStats(HWND hwnd,struct STATS *Stats, | |
+ gboolean CreateEdit,gboolean CreateButtons) { | |
+ int Tabs=45; | |
+ if (!Stats) return; | |
+ memset(Stats,0,sizeof(struct STATS)); | |
+ if (CreateButtons) { | |
+ Stats->SellButton=CreateWindow("BUTTON","<- &Sell", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|BS_PUSHBUTTON, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->BuyButton=CreateWindow("BUTTON","&Buy ->", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|BS_PUSHBUTTON, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->DropButton=CreateWindow("BUTTON","&Drop <-", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|BS_PUSHBUTTON, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->JetButton=CreateWindow("BUTTON","&Jet!", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|BS_PUSHBUTTON, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ } | |
+ Stats->StatGroup=CreateWindow("BUTTON","Stats", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|BS_GROUPBOX, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->HereList=CreateWindow("LISTBOX","Here", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_VSCROLL| | |
+ WS_BORDER|LBS_HASSTRINGS|LBS_USETABSTOPS, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ SendMessage(Stats->HereList,LB_SETTABSTOPS, | |
+ (WPARAM)1,(LPARAM)&Tabs); | |
+ Stats->CarriedList=CreateWindow("LISTBOX","Carried", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_VSCROLL| | |
+ WS_BORDER|LBS_HASSTRINGS|LBS_USETABSTOPS, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ SendMessage(Stats->CarriedList,LB_SETTABSTOPS, | |
+ (WPARAM)1,(LPARAM)&Tabs); | |
+ if (CreateEdit) { | |
+ Stats->MessageEdit=CreateWindow("EDIT","", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|WS_VSCROLL| | |
+ WS_BORDER|ES_LEFT|ES_AUTOVSCROLL| | |
+ ES_MULTILINE|ES_READONLY, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ } | |
+ Stats->Location=CreateWindow("STATIC","", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|SS_CENTER, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->Date=CreateWindow("STATIC","", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|SS_CENTER, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->Space=CreateWindow("STATIC","", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|SS_CENTER, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->Cash=CreateWindow("STATIC","", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|SS_CENTER, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->Debt=CreateWindow("STATIC","", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|SS_CENTER, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->Bank=CreateWindow("STATIC","", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|SS_CENTER, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->Guns=CreateWindow("STATIC","", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|SS_CENTER, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->Bitches=CreateWindow("STATIC","", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|SS_CENTER, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+ Stats->Health=CreateWindow("STATIC","", | |
+ WS_CHILD|WS_TABSTOP|WS_VISIBLE|SS_CENTER, | |
+ 0,0,1,1,hwnd,NULL,hInst,NULL); | |
+} | |
+ | |
+void SizeStats(HWND hwnd,struct STATS *Stats,RECT *rect) { | |
+ LONG EditDepth,ListDepth,editspace,TextHeight; | |
+ HDC hDC; | |
+ int width,depth,ButtonX,ButtonY,ButtonWid; | |
+ TEXTMETRIC TextMetric; | |
+ if (!Stats || !rect) return; | |
+ | |
+ width=rect->right-rect->left; | |
+ depth=rect->bottom-rect->top; | |
+ | |
+ if (Stats->MessageEdit) EditDepth=(depth-126)/2; else EditDepth=0; | |
+ ListDepth=(depth-126)-EditDepth; | |
+ editspace=(width-25)/3; | |
+ hDC=GetDC(Stats->Location); | |
+ GetTextMetrics(hDC,&TextMetric); | |
+ ReleaseDC(Stats->Location,hDC); | |
+ TextHeight=TextMetric.tmHeight; | |
+ | |
+ MoveWindow(Stats->StatGroup,rect->left+10,rect->top+10, | |
+ width-20,86,TRUE); | |
+ MoveWindow(Stats->Location,rect->left+15,rect->top+25, | |
+ editspace-5,TextHeight,TRUE); | |
+ MoveWindow(Stats->Date,rect->left+15+editspace,rect->top+25, | |
+ editspace-5,TextHeight,TRUE); | |
+ MoveWindow(Stats->Space,rect->left+15+2*editspace,rect->top+25, | |
+ editspace-5,TextHeight,TRUE); | |
+ MoveWindow(Stats->Cash,rect->left+15,rect->top+25+TextHeight+4, | |
+ editspace-5,TextHeight,TRUE); | |
+ MoveWindow(Stats->Debt,rect->left+15+editspace,rect->top+25+TextHeight+4, | |
+ editspace-5,TextHeight,TRUE); | |
+ MoveWindow(Stats->Bank,rect->left+15+2*editspace,rect->top+25+TextHeight+4, | |
+ editspace-5,TextHeight,TRUE); | |
+ MoveWindow(Stats->Guns,rect->left+15,rect->top+25+TextHeight*2+8, | |
+ editspace-5,TextHeight,TRUE); | |
+ MoveWindow(Stats->Bitches,rect->left+15+editspace, | |
+ rect->top+25+TextHeight*2+8,editspace-5,TextHeight,TRUE); | |
+ MoveWindow(Stats->Health,rect->left+15+2*editspace, | |
+ rect->top+25+TextHeight*2+8,editspace-5,TextHeight,TRUE); | |
+ if (Stats->MessageEdit) { | |
+ MoveWindow(Stats->MessageEdit,rect->left+10,rect->top+106, | |
+ width-20,EditDepth,TRUE); | |
+ } | |
+ if (Stats->SellButton) { | |
+ ButtonWid=60; | |
+ ButtonX=rect->left+width/2-30; | |
+ ButtonY=rect->top+116+EditDepth; | |
+ MoveWindow(Stats->SellButton,ButtonX,ButtonY,60,28,TRUE); | |
+ MoveWindow(Stats->BuyButton,ButtonX,ButtonY+35,60,28,TRUE); | |
+ MoveWindow(Stats->DropButton,ButtonX,ButtonY+70,60,28,TRUE); | |
+ MoveWindow(Stats->JetButton,ButtonX,ButtonY+105,60,28,TRUE); | |
+ } else ButtonWid=0; | |
+ MoveWindow(Stats->HereList,rect->left+10,rect->top+116+EditDepth, | |
+ (width-ButtonWid)/2-15,ListDepth,TRUE); | |
+ MoveWindow(Stats->CarriedList, | |
+ rect->left+(width+ButtonWid)/2+5,rect->top+116+EditDepth, | |
+ (width-ButtonWid)/2-15,ListDepth,TRUE); | |
+} | |
+ | |
+void ShowStats(struct STATS *Stats,int State) { | |
+ ShowWindow(Stats->StatGroup,State); | |
+ ShowWindow(Stats->Location,State); | |
+ ShowWindow(Stats->Date,State); | |
+ ShowWindow(Stats->Space,State); | |
+ ShowWindow(Stats->Space,State); | |
+ ShowWindow(Stats->Cash,State); | |
+ ShowWindow(Stats->Debt,State); | |
+ ShowWindow(Stats->Bank,State); | |
+ ShowWindow(Stats->Guns,State); | |
+ ShowWindow(Stats->Bitches,State); | |
+ ShowWindow(Stats->Health,State); | |
+ if (Stats->MessageEdit) ShowWindow(Stats->MessageEdit,State); | |
+ if (Stats->SellButton) { | |
+ ShowWindow(Stats->SellButton,State); | |
+ ShowWindow(Stats->BuyButton,State); | |
+ ShowWindow(Stats->DropButton,State); | |
+ ShowWindow(Stats->JetButton,State); | |
+ } | |
+ ShowWindow(Stats->HereList,State); | |
+ ShowWindow(Stats->CarriedList,State); | |
+} | |
+ | |
+LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,UINT wParam,LONG lParam) { | |
+ RECT rect; | |
+ char *pt; | |
+ switch(msg) { | |
+ case WM_CREATE: | |
+ CreateStats(hwnd,&ClientData.Stats,TRUE,TRUE); | |
+ ClientData.PlayerName=NULL; | |
+ ClientData.Play=NULL; | |
+ ClientMessageHandlerPt = HandleClientMessage; | |
+ SocketWriteTestPt = SetSocketWriteTest; | |
+ g_log_set_handler(NULL,G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_WARNING, | |
+ LogMessage,NULL); | |
+ UpdateControls(); | |
+ break; | |
+ case WM_SIZE: | |
+ GetClientRect(hwnd,&rect); | |
+ SizeStats(hwnd,&ClientData.Stats,&rect); | |
+ break; | |
+ case WM_CLOSE: | |
+ if (!InGame || MessageBox(hwnd,"Abandon current game?", | |
+ "Quit Game",MB_YESNO)==IDYES) { | |
+ DestroyWindow(hwnd); | |
+ } | |
+ break; | |
+ case WM_DESTROY: | |
+ PostQuitMessage(0); | |
+ break; | |
+ case WM_SOCKETDATA: | |
+ if (WSAGETSELECTEVENT(lParam)==FD_WRITE) { | |
+ WriteConnectionBufferToWire(ClientData.Play); | |
+ if (ClientData.Play->WriteBuf.DataPresent==0) { | |
+ SetSocketWriteTest(ClientData.Play,FALSE); | |
+ } | |
+ } else { | |
+ if (ReadConnectionBufferFromWire(ClientData.Play)) { | |
+ while ((pt=ReadFromConnectionBuffer(ClientData.Play))!=NULL) { | |
+ HandleClientMessage(pt,NULL); g_free(pt); | |
+ } | |
+ } else { | |
+ if (Network) WSAAsyncSelect(ClientSock,ClientData.Window,0,0); | |
+ g_warning("Connection to server lost - switching " | |
+ "to single player mode"); | |
+ SwitchToSinglePlayer(ClientData.Play); | |
+ } | |
+ } | |
+ break; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED && | |
+ (HWND)lParam==ClientData.Stats.JetButton) { | |
+ if (ClientData.Play->Flags & FIGHTING) { | |
+ DisplayFightMessage(""); | |
+ } else { | |
+ DialogBox(hInst,MAKEINTRESOURCE(JetDialog),hwnd,JetWndProc); | |
+ } | |
+ } else if (HIWORD(wParam)==BN_CLICKED && | |
+ (HWND)lParam==ClientData.Stats.BuyButton) { | |
+ DialogBoxParam(hInst,MAKEINTRESOURCE(DealDialog), | |
+ hwnd,DealWndProc,BT_BUY); | |
+ } else if (HIWORD(wParam)==BN_CLICKED && | |
+ (HWND)lParam==ClientData.Stats.SellButton) { | |
+ DialogBoxParam(hInst,MAKEINTRESOURCE(DealDialog), | |
+ hwnd,DealWndProc,BT_SELL); | |
+ } else if (HIWORD(wParam)==BN_CLICKED && | |
+ (HWND)lParam==ClientData.Stats.DropButton) { | |
+ DialogBoxParam(hInst,MAKEINTRESOURCE(DealDialog), | |
+ hwnd,DealWndProc,BT_DROP); | |
+ } else if (HIWORD(wParam)==0) switch(LOWORD(wParam)) { | |
+ case ID_EXIT: | |
+ SendMessage(hwnd,WM_CLOSE,0,0); | |
+ break; | |
+ case ID_NEWGAME: | |
+ if (InGame && MessageBox(hwnd,"Abandon current game?", | |
+ "Start new game",MB_YESNO)==IDYES) { | |
+ EndGame(); | |
+ } | |
+ if (!InGame) DialogBox(hInst,MAKEINTRESOURCE(NewGameDialog), | |
+ hwnd,NewGameWndProc); | |
+ break; | |
+ case ID_TALKTOALL: | |
+ case ID_TALKTOPLAYERS: | |
+ if (TalkWnd) { | |
+ SetWindowPos(TalkWnd,HWND_TOP,0,0,0,0, | |
+ SWP_NOMOVE|SWP_NOSIZE); | |
+ } else { | |
+ TalkWnd=CreateDialogParam(hInst, | |
+ MAKEINTRESOURCE(TalkDialog),hwnd, | |
+ TalkWndProc, | |
+ LOWORD(wParam)==ID_TALKTOALL ? TRUE : FALSE); | |
+ ShowWindow(TalkWnd,SW_SHOWNORMAL); | |
+ } | |
+ break; | |
+ case ID_SPY: | |
+ DialogBoxParam(hInst,MAKEINTRESOURCE(ErrandDialog),hwnd, | |
+ ErrandWndProc,(LPARAM)ID_SPY); | |
+ break; | |
+ case ID_TIPOFF: | |
+ DialogBoxParam(hInst,MAKEINTRESOURCE(ErrandDialog),hwnd, | |
+ ErrandWndProc,(LPARAM)ID_TIPOFF); | |
+ break; | |
+ case ID_SACKBITCH: | |
+ if (MessageBox(hwnd,"Are you sure? (Any drugs or guns carried\n" | |
+ "by this bitch may be lost!)", | |
+ "Sack Bitch",MB_YESNO)==IDYES) { | |
+ SendClientMessage(ClientData.Play,C_NONE,C_SACKBITCH, | |
+ NULL,NULL,ClientData.Play); | |
+ } | |
+ break; | |
+ case ID_GETSPY: | |
+ if (SpyReportsWnd) DestroyWindow(SpyReportsWnd); | |
+ SpyReportsWnd=NULL; | |
+ SendClientMessage(ClientData.Play,C_NONE,C_CONTACTSPY, | |
+ NULL,NULL,ClientData.Play); | |
+ break; | |
+ case ID_LISTPLAYERS: | |
+ if (PlayerListWnd) { | |
+ SetWindowPos(PlayerListWnd,HWND_TOP,0,0,0,0, | |
+ SWP_NOMOVE|SWP_NOSIZE); | |
+ } else { | |
+ PlayerListWnd=CreateDialog(hInst, | |
+ MAKEINTRESOURCE(PlayerListDia),hwnd, | |
+ PlayerListWndProc); | |
+ ShowWindow(PlayerListWnd,SW_SHOWNORMAL); | |
+ } | |
+ break; | |
+ case ID_LISTINVENTORY: | |
+ if (InventoryWnd) { | |
+ SetWindowPos(InventoryWnd,HWND_TOP,0,0,0,0, | |
+ SWP_NOMOVE|SWP_NOSIZE); | |
+ } else { | |
+ InventoryWnd=CreateDialog(hInst, | |
+ MAKEINTRESOURCE(InventoryDia),hwnd, | |
+ InventoryWndProc); | |
+ ShowWindow(InventoryWnd,SW_SHOWNORMAL); | |
+ } | |
+ break; | |
+ case ID_LISTSCORES: | |
+ SendClientMessage(ClientData.Play,C_NONE,C_REQUESTSCORE, | |
+ NULL,NULL,ClientData.Play); | |
+ break; | |
+ case ID_ABOUT: | |
+ DialogBox(hInst,MAKEINTRESOURCE(AboutDialog),hwnd,AboutWndProc); | |
+ break; | |
+ } | |
+ default: | |
+ return DefWindowProc(hwnd,msg,wParam,lParam); | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+static BOOL CALLBACK FightWndProc(HWND hwnd,UINT msg,WPARAM wParam, | |
+ LPARAM lParam) { | |
+ char text[10]; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ return TRUE; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED) switch(LOWORD(wParam)) { | |
+ case BT_DEALDRUGS: | |
+ EnableWindow(ClientData.Window,TRUE); | |
+ EnableWindow(hwnd,FALSE); | |
+ ShowWindow(hwnd,SW_HIDE); | |
+ return TRUE; | |
+ case BT_FIGHT: | |
+ ClientData.Play->Flags &= ~CANSHOOT; | |
+ if (TotalGunsCarried(ClientData.Play)==0) { | |
+ text[0]='S'; | |
+ } else { | |
+ text[0]='F'; | |
+ } | |
+ text[1]='\0'; | |
+ SendClientMessage(ClientData.Play,C_NONE,C_FIGHTACT,NULL,text, | |
+ ClientData.Play); | |
+ return TRUE; | |
+ case BT_RUN: | |
+ EnableWindow(ClientData.Window,TRUE); | |
+ EnableWindow(hwnd,FALSE); | |
+ ShowWindow(hwnd,SW_HIDE); | |
+ DialogBox(hInst,MAKEINTRESOURCE(JetDialog), | |
+ ClientData.Window,JetWndProc); | |
+ return TRUE; | |
+ } | |
+ break; | |
+ case WM_DESTROY: | |
+ EnableWindow(ClientData.Window,TRUE); | |
+ FightWnd=NULL; | |
+ break; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+void DisplayFightMessage(char *Data) { | |
+ int buflen; | |
+ gchar *buffer,**split,*joined; | |
+ HWND EditWnd,Fight,Run; | |
+ if (!Data) { | |
+ if (FightWnd) DestroyWindow(FightWnd); | |
+ FightWnd=NULL; | |
+ return; | |
+ } | |
+ EnableWindow(ClientData.Window,FALSE); | |
+ if (!FightWnd) { | |
+ FightWnd=CreateDialog(hInst,MAKEINTRESOURCE(FightDialog), | |
+ ClientData.Window,FightWndProc); | |
+ } | |
+ ShowWindow(FightWnd,SW_SHOW); | |
+ EnableWindow(FightWnd,TRUE); | |
+ | |
+ while (*Data=='^') Data++; | |
+ split=g_strsplit(Data,"^",0); | |
+ joined=g_strjoinv("\r\n",split); | |
+ g_strfreev(split); | |
+ | |
+ if (joined[strlen(joined)-1]!='\n') { | |
+ buffer=g_strdup_printf("%s\r\n",joined); | |
+ } else buffer=joined; | |
+ | |
+ EditWnd=GetDlgItem(FightWnd,EB_FIGHTSTATUS); | |
+ | |
+ buflen=GetWindowTextLength(EditWnd); | |
+ SendMessage(EditWnd,EM_SETSEL,(WPARAM)buflen,(WPARAM)buflen); | |
+ SendMessage(EditWnd,EM_REPLACESEL,FALSE,(LPARAM)buffer); | |
+ g_free(buffer); | |
+ | |
+ Fight=GetDlgItem(FightWnd,BT_FIGHT); | |
+ Run=GetDlgItem(FightWnd,BT_RUN); | |
+ if (TotalGunsCarried(ClientData.Play)==0) { | |
+ SetWindowText(Fight,"&Stand"); | |
+ } else { | |
+ SetWindowText(Fight,"&Fight"); | |
+ } | |
+ ShowWindow(Fight,ClientData.Play->Flags&CANSHOOT ? SW_SHOW : SW_HIDE); | |
+ ShowWindow(Run,ClientData.Play->Flags&FIGHTING ? SW_SHOW : SW_HIDE); | |
+} | |
+ | |
+static BOOL CALLBACK SpyReportsWndProc(HWND hwnd,UINT msg,WPARAM wParam, | |
+ LPARAM lParam) { | |
+ Player *Play; | |
+ TC_ITEM tie; | |
+ RECT rect,StatRect; | |
+ static HWND tab=NULL; | |
+ static int TabPos=0; | |
+ static GSList *TabList=NULL; | |
+ GSList *list; | |
+ struct STATS *Stats; | |
+ static struct STATS *SelStats=NULL; | |
+ NMHDR *nmhdr; | |
+ switch(msg) { | |
+ case WM_INITDIALOG: | |
+ tab=CreateWindow(WC_TABCONTROL,"", | |
+ WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, | |
+ 10,10,100,100,hwnd,NULL,hInst,NULL); | |
+ TabPos=0; | |
+ TabList=NULL; | |
+ SelStats=NULL; | |
+ SetWindowPos(hwnd,HWND_TOP,0,0,500,320,SWP_NOZORDER|SWP_NOMOVE); | |
+ return TRUE; | |
+ case WM_COMMAND: | |
+ if (HIWORD(wParam)==BN_CLICKED && LOWORD(wParam)==ID_CANCEL) { | |
+ DestroyWindow(hwnd); return TRUE; | |
+ } | |
+ break; | |
+ case WM_SIZE: | |
+ GetClientRect(hwnd,&rect); | |
+ MoveWindow(GetDlgItem(hwnd,ID_CANCEL),(rect.right-60)/2,rect.bottom-3… | |
+ 60,30,TRUE); | |
+ SetRect(&StatRect,5,5,rect.right-10,rect.bottom-45); | |
+ MoveWindow(tab,StatRect.left,StatRect.top,StatRect.right, | |
+ StatRect.bottom,TRUE); | |
+ TabCtrl_AdjustRect(tab,FALSE,&StatRect); | |
+ OffsetRect(&StatRect,5,5); | |
+ for (list=TabList;list;list=g_slist_next(list)) { | |
+ Stats=(struct STATS *)list->data; | |
+ SizeStats(hwnd,Stats,&StatRect); | |
+ } | |
+ break; | |
+ case WM_NOTIFY: | |
+ nmhdr = (NMHDR *)lParam; | |
+ list=g_slist_nth(TabList,TabCtrl_GetCurSel(tab)); | |
+ if (nmhdr && list && nmhdr->code==TCN_SELCHANGE) { | |
+ if (SelStats) ShowStats(SelStats,SW_HIDE); | |
+ SelStats=(struct STATS *)list->data; | |
+ ShowStats(SelStats,SW_SHOW); | |
+ } | |
+ break; | |
+ case WM_ADDSPYREPORT: | |
+ Play=(Player *)lParam; | |
+ if (Play && tab) { | |
+ tie.mask = TCIF_TEXT | TCIF_IMAGE; | |
+ tie.iImage = -1; | |
+ tie.pszText = GetPlayerName(Play); | |
+ Stats=g_new(struct STATS,1); | |
+ TabList=g_slist_append(TabList,(gpointer)Stats); | |
+ CreateStats(hwnd,Stats,FALSE,FALSE); | |
+ DisplayStats(Play,Stats); | |
+ UpdateInventory(NULL,Stats->HereList,NULL,NULL,NULL, | |
+ Play->Drugs,NumDrug,TRUE); | |
+ UpdateInventory(NULL,Stats->CarriedList,NULL,NULL,NULL, | |
+ Play->Guns,NumGun,FALSE); | |
+ TabCtrl_InsertItem(tab,TabPos,&tie); | |
+ GetClientRect(hwnd,&rect); | |
+ SetRect(&StatRect,5,5,rect.right-10,rect.bottom-45); | |
+ TabCtrl_AdjustRect(tab,FALSE,&StatRect); | |
+ OffsetRect(&StatRect,5,5); | |
+ if (TabPos!=TabCtrl_GetCurSel(tab)) { | |
+ ShowStats(Stats,SW_HIDE); | |
+ } else { | |
+ if (SelStats) ShowStats(SelStats,SW_HIDE); | |
+ SelStats=Stats; ShowStats(SelStats,SW_SHOW); | |
+ } | |
+ SizeStats(hwnd,Stats,&StatRect); | |
+ TabPos++; | |
+ } | |
+ return TRUE; | |
+ case WM_CLOSE: | |
+ DestroyWindow(hwnd); return TRUE; | |
+ case WM_DESTROY: | |
+ while (TabList) { | |
+ Stats=(struct STATS *)TabList->data; | |
+ TabList=g_slist_remove(TabList,(gpointer)Stats); | |
+ g_free(Stats); | |
+ } | |
+ SpyReportsWnd=NULL; | |
+ break; | |
+ } | |
+ return FALSE; | |
+} | |
+ | |
+void DisplaySpyReports(Player *Play) { | |
+ if (!SpyReportsWnd) { | |
+ SpyReportsWnd=CreateDialog(hInst,MAKEINTRESOURCE(SpyReportsDia), | |
+ ClientData.Window,SpyReportsWndProc); | |
+ } | |
+ ShowWindow(SpyReportsWnd,SW_SHOWNORMAL); | |
+ SendMessage(SpyReportsWnd,WM_ADDSPYREPORT,0,(LPARAM)Play); | |
+} | |
+ | |
+#endif /* WIN32_CLIENT */ | |
+ | |
+static void ServerLogMessage(const gchar *log_domain,GLogLevelFlags log_level, | |
+ const gchar *message,gpointer user_data) { | |
+ DWORD NumChar; | |
+ gchar *text; | |
+ text=g_strdup_printf("%s\n",message); | |
+ WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),text,strlen(text),&NumChar,NUL… | |
+ g_free(text); | |
+} | |
+ | |
+static void Win32PrintFunc(const gchar *string) { | |
+ DWORD NumChar; | |
+ WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),string,strlen(string), | |
+ &NumChar,NULL); | |
+} | |
+ | |
+int APIENTRY Win32Loop(HINSTANCE hInstance,HINSTANCE hPrevInstance, | |
+ LPSTR lpszCmdParam,int nCmdShow) { | |
+ static char szAppName[] = "dopewars"; | |
+ HWND hwnd; | |
+ MSG msg; | |
+ gchar **split; | |
+ WNDCLASS wc; | |
+ int argc; | |
+ SetupParameters(); | |
+ split=g_strsplit(lpszCmdParam," ",0); | |
+ argc=0; | |
+ while (split[argc]) argc++; | |
+ g_set_print_handler(Win32PrintFunc); | |
+ HandleCmdLine(argc,split); | |
+ g_strfreev(split); | |
+ if (WantVersion || WantHelp) { | |
+ AllocConsole(); | |
+ HandleHelpTexts(); | |
+ newterm(NULL,NULL,NULL); | |
+ bgetch(); | |
+ } else { | |
+ StartNetworking(); | |
+ if (Server) { | |
+ AllocConsole(); | |
+ SetConsoleTitle("dopewars server"); | |
+ g_log_set_handler(NULL,G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_WARNING, | |
+ ServerLogMessage,NULL); | |
+ newterm(NULL,NULL,NULL); | |
+ ServerLoop(); | |
+ } else if (WantedClient==CLIENT_CURSES) { | |
+ AllocConsole(); | |
+ SetConsoleTitle("dopewars"); | |
+ CursesLoop(); | |
+ } else { | |
+#ifdef WIN32_CLIENT | |
+ hInst=hInstance; | |
+ if (!hPrevInstance) { | |
+ wc.style = CS_HREDRAW|CS_VREDRAW; | |
+ wc.lpfnWndProc = MainWndProc; | |
+ wc.cbClsExtra = 0; | |
+ wc.cbWndExtra = 0; | |
+ wc.hInstance = hInstance; | |
+ wc.hIcon = LoadIcon(NULL,IDI_APPLICATION); | |
+ wc.hCursor = LoadCursor(NULL,IDC_ARROW); | |
+ wc.hbrBackground = GetStockObject(LTGRAY_BRUSH); | |
+ wc.lpszMenuName = MAKEINTRESOURCE(MainMenu); | |
+ wc.lpszClassName = szAppName; | |
+ RegisterClass(&wc); | |
+ } | |
+ InitCommonControls(); | |
+ hwnd=ClientData.Window=CreateWindow(szAppName,"dopewars", | |
+ WS_OVERLAPPEDWINDOW|CS_HREDRAW|CS_VREDRAW|WS_SIZEBOX, | |
+ CW_USEDEFAULT,0,460,460,NULL,NULL,hInstance,NULL); | |
+ ShowWindow(hwnd,nCmdShow); | |
+ UpdateWindow(hwnd); | |
+ while(GetMessage(&msg,NULL,0,0)) { | |
+ if ((!PlayerListWnd || !IsDialogMessage(PlayerListWnd,&msg)) && | |
+ (!TalkWnd || !IsDialogMessage(TalkWnd,&msg)) && | |
+ (!InventoryWnd || !IsDialogMessage(InventoryWnd,&msg)) && | |
+ (!FightWnd || !IsDialogMessage(FightWnd,&msg)) && | |
+ (!GunShopWnd || !IsDialogMessage(GunShopWnd,&msg)) && | |
+ (!SpyReportsWnd || !IsDialogMessage(SpyReportsWnd,&msg)) && | |
+ (!ScoresWnd || !IsDialogMessage(ScoresWnd,&msg))) { | |
+ TranslateMessage(&msg); | |
+ DispatchMessage(&msg); | |
+ } | |
+ } | |
+ StopNetworking(); | |
+ return msg.wParam; | |
+ } | |
+#else | |
+ g_print("No windowed client available - rebuild the binary passing the\n" | |
+ "--enable-win32-client option to configure, or use the curses\n" | |
+ "client (if available) instead!\n"); | |
+#endif | |
+ StopNetworking(); | |
+ } | |
+ if (PidFile) g_free(PidFile); | |
+ return 0; | |
+} | |
+ | |
+#endif /* CYGWIN */ | |
diff --git a/src/win32_client.h b/src/win32_client.h | |
t@@ -0,0 +1,36 @@ | |
+/* win32_client.h dopewars client using native Win32 user interface */ | |
+/* Copyright (C) 1998-2000 Ben Webb */ | |
+/* Email: [email protected] */ | |
+/* WWW: http://bellatrix.pcl.ox.ac.uk/~ben/dopewars/ */ | |
+ | |
+/* 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. */ | |
+ | |
+ | |
+#ifndef __WIN32_CLIENT_H__ | |
+#define __WIN32_CLIENT_H__ | |
+ | |
+#ifdef CYGWIN | |
+#include <windows.h> | |
+ | |
+#ifdef HAVE_CONFIG_H | |
+#include <config.h> | |
+#endif | |
+ | |
+int APIENTRY Win32Loop(HINSTANCE hInstance,HINSTANCE hPrevInstance, | |
+ LPSTR lpCmdLine,int nCmdShow); | |
+ | |
+#endif | |
+#endif | |
diff --git a/stamp-h.in b/stamp-h.in | |
t@@ -0,0 +1 @@ | |
+timestamp |