tInitial revision - vaccinewars - be a doctor and try to vaccinate the world
(HTM) git clone git://src.adamsgaard.dk/vaccinewars
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 1776472dd917614b290c38dfa6a6df04cd9dd70f
(DIR) parent e55c937a193d3df67ac391ac0e055c4eb9e091cb
(HTM) Author: Ben Webb <ben@salilab.org>
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(-)
---
(DIR) 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 (ben@bellatrix.pcl.ox.ac.uk)
+
+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 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.
+
+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.
+
(DIR) 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.
(DIR) 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 password
+ 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 to
+ 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 crashes
+ - 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
(DIR) 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.
(DIR) 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.
(DIR) 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
+
(DIR) 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_DEPENDENCIES)
+ 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) $(LISP)
+ 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 $(LISP) -o $$here/TAGS)
+
+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_install_base \
+ && $(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_srcdir) --output-dir=$$top_distdir --gnu Makefile
+ @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) distdir=../$(distdir)/$$subdir 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:
(DIR) 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 now
+also available on the popular Windows platform. A Win32 binary can be downloaded
+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 to
+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 the
+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)
+
(DIR) 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 file,
+the port and server to connect to, the names of the drugs and guns, etc.) can be
+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 local
+settings in ~/.dopewars. All of the settings here can also be set on the command
+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 <ben@bellatrix.pcl.ox.ac.uk>
+Enquiries about dopewars may be sent to this address (keep them sensible
+please ;) Bug fixes and reports, improvements and patches are also welcomed.
(DIR) 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)
(DIR) 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
+
(DIR) 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" there first])
+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>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<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%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 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/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 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 <drepper@cygnus.com>, 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 [, MODULES]]]])
+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 installed (optional)],
+ gtk_config_prefix="$withval", gtk_config_prefix="")
+AC_ARG_WITH(gtk-exec-prefix,[ --with-gtk-exec-prefix=PFX Exec prefix where GTK is installed (optional)],
+ gtk_config_exec_prefix="$withval", gtk_config_exec_prefix="")
+AC_ARG_ENABLE(gtktest, [ --disable-gtktest Do not try to compile and run a test GTK program],
+ , 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.%d)\n",
+ $gtk_config_major_version, $gtk_config_minor_version, $gtk_config_micro_version,
+ 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 fix the error\n");
+ printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
+ printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
+ printf("*** required on your system.\n");
+ printf("*** If gtk-config was wrong, set the environment variable GTK_CONFIG\n");
+ printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n");
+ printf("*** before re-running configure\n");
+ }
+#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK_MICRO_VERSION)
+ 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_micro_version >= micro)))
+ {
+ 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 version of\n",
+ 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, this error\n");
+ printf("*** probably means that the wrong copy of the gtk-config shell script is\n");
+ printf("*** being found. The easiest way to fix this is to remove the old version\n");
+ printf("*** of GTK+, but you can also set the GTK_CONFIG environment to point to the\n");
+ printf("*** correct copy of gtk-config. (In this case, you will have to\n");
+ printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+ 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_version)); ],
+ [ 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 wrong"
+ echo "*** version of GTK. If it is not finding GTK, you'll need to set your"
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+ echo "*** to the installed location Also, make sure you have run ldconfig if that"
+ echo "*** is required on your system"
+ echo "***"
+ echo "*** If you have an old version installed, it is best to remove it, although"
+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
+ echo "***"
+ echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that"
+ 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 config.log for the"
+ echo "*** exact error that occured. This usually means GTK was incorrectly installed"
+ echo "*** or that you have moved GTK since it was installed. In the latter case, you"
+ 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
+])
+
(DIR) 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
+
(DIR) 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 1; }
+ 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 1; }
+ 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 1; }
+ 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 1; }
+ 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 usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ 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 at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# 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; exit 1; }
+ 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/config.site"
+ 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.$ac_ext $LIBS 1>&5'
+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 ghazi@caip.rutgers.edu.
+ 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 $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+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 a broken
+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 files!
+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"; then
+ 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 distclean" there first" 1>&2; exit 1; }
+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" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:921: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+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.$ac_ext $LIBS 1>&5'
+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; } && test -s conftest${ac_exeext}; then
+ 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.$ac_ext $LIBS 1>&5'
+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 cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:963: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+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\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ 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; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+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; }; then
+ 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; }; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+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./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ 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; } && test -s conftest${ac_exeext}; then
+ 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' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ 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; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+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./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ 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; } && test -s conftest${ac_exeext}; then
+ 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' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ 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; } && test -s conftest${ac_exeext}; then
+ 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' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ 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; } && test -s conftest${ac_exeext}; then
+ 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>&6
+echo "configure:2227: checking whether included gettext is requested" >&5
+ # Check whether --with-included-gettext or --without-included-gettext was given.
+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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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 name with args.
+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; } && test -s conftest${ac_exeext}; then
+ 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' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ 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 name with args.
+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 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_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 with args.
+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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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 name with args.
+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 name with args.
+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 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_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 program name with args.
+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 program name with args.
+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 args.
+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 with args.
+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 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_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 with args.
+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" 1>&6
+ 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/\(.*\) \\\\/\1/" \
+ < $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; }; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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" 1>&2
+ CURSES_CLIENT="no"
+ fi
+ fi
+ fi
+ fi
+
+ if test "$GTK_CLIENT" = "yes" ; then
+ # Check whether --with-gtk-prefix or --without-gtk-prefix was given.
+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 args.
+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 path.
+ ;;
+ ?:/*)
+ ac_cv_path_GTK_CONFIG="$GTK_CONFIG" # 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_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.%d)\n",
+ $gtk_config_major_version, $gtk_config_minor_version, $gtk_config_micro_version,
+ 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 fix the error\n");
+ printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n");
+ printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n");
+ printf("*** required on your system.\n");
+ printf("*** If gtk-config was wrong, set the environment variable GTK_CONFIG\n");
+ printf("*** to point to the correct copy of gtk-config, and remove the file config.cache\n");
+ printf("*** before re-running configure\n");
+ }
+#if defined (GTK_MAJOR_VERSION) && defined (GTK_MINOR_VERSION) && defined (GTK_MICRO_VERSION)
+ 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_micro_version >= micro)))
+ {
+ 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 version of\n",
+ 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, this error\n");
+ printf("*** probably means that the wrong copy of the gtk-config shell script is\n");
+ printf("*** being found. The easiest way to fix this is to remove the old version\n");
+ printf("*** of GTK+, but you can also set the GTK_CONFIG environment to point to the\n");
+ printf("*** correct copy of gtk-config. (In this case, you will have to\n");
+ printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n");
+ 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; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+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; } && test -s conftest${ac_exeext}; then
+ 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 wrong"
+ echo "*** version of GTK. If it is not finding GTK, you'll need to set your"
+ echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
+ echo "*** to the installed location Also, make sure you have run ldconfig if that"
+ echo "*** is required on your system"
+ echo "***"
+ echo "*** If you have an old version installed, it is best to remove it, although"
+ echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"
+ echo "***"
+ echo "*** If you have a RedHat 5.0 system, you should remove the GTK package that"
+ 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.log for the"
+ echo "*** exact error that occured. This usually means GTK was incorrectly installed"
+ echo "*** or that you have moved GTK since it was installed. In the latter case, you"
+ 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" = "no" ; then
+ echo "configure: warning: No clients will be compiled - binary will be server/AI only!" 1>&2
+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; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+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; }; then
+ 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./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ 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""... $ac_c" 1>&6
+echo "configure:3867: checking whether time.h and sys/time.h may both be included" >&5
+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; }; then
+ 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" 1>&6
+echo "configure:3902: checking whether struct tm is in sys/time.h or time.h" >&5
+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; }; then
+ 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" 1>&2; exit 1; }
+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; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+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; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+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" 1>&2; exit 1; }
+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; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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; } && test -s conftest${ac_exeext}; then
+ 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' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ 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; } && test -s conftest${ac_exeext}; then
+ 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' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ 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" 1>&6
+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 2 15
+
+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 --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -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%.*/%%'` by configure."
+ 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%:% $ac_given_srcdir/%g"`
+ 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%:% $ac_given_srcdir/%g"`
+ 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${ac_dD}%gp
+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>&2; exit 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
+
(DIR) 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" = "no" ; then
+ 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 available)
+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])
(DIR) 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 coff -o dopewars.res
(DIR) 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)
+
(DIR) 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.html credits.html installation.html servercommands.html commandline.html developer.html metaserver.html windows.html
+
+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_srcdir) --output-dir=$$top_distdir --gnu doc/Makefile
+ @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:
(DIR) 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:ben@bellatrix.pcl.ox.ac.uk">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>
(DIR) 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 to the enemy as
+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>
(DIR) 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</i></a>
+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>
(DIR) 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:ben@bellatrix.pcl.ox.ac.uk">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 game.
+
+<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>
(DIR) 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:ben@bellatrix.pcl.ox.ac.uk">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>
(DIR) 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:ben@bellatrix.pcl.ox.ac.uk">ben@bellatrix.pcl.ox.ac.uk</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>
(DIR) 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
(DIR) 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>po/</tt> directory, and filling
+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:ben@bellatrix.pcl.ox.ac.uk">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<br>
+<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>
(DIR) 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>
(DIR) 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.rpm">
+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-1.4.8-1.src.rpm">source code RPM</a>.
+<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-1.4.8.tar.gz">source code tarball</a>.
+<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>
(DIR) 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:ben@bellatrix.pcl.ox.ac.uk">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.Password
+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 connection
+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:ben@bellatrix.pcl.ox.ac.uk">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>
(DIR) 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>
(DIR) 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>
(DIR) 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:ben@bellatrix.pcl.ox.ac.uk">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 a
+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.<p>
+
+<hr><br>
+<ul>
+<li><a href="index.html">Main index</a>
+</ul>
+Last update: <b>09-07-2000</b>
+
+</body>
+</html>
(DIR) 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
(DIR) 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 <pinard@iro.umontreal.ca>, 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
(DIR) diff --git a/mkinstalldirs b/mkinstalldirs
t@@ -0,0 +1,40 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# 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
(DIR) 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
(DIR) 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!", 147},
+ {"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 ben@bellatrix.pcl.ox.ac.uk\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", 192},
+ {"imaginary drug market. dopewars is an All-American game which features", 193},
+ {"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", 195},
+ {"\
+that, your goal is to make as much money as possible (and stay alive)! You", 196},
+ {"have one month of game time to make your fortune.", 197},
+ {"Copyright (C) 1998-2000 Ben Webb ben@bellatrix.pcl.ox.ac.uk", 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", 206},
+ {"\
+Unix prompt. This will display a help screen, listing the available options.", 207},
+ {"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.", 255},
+ {"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 ben@bellatrix.pcl.ox.ac.uk\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.", 387},
+ {"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", 461},
+ {"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. ", 498},
+ {"^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!", 521},
+ {"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!", 560},
+ {"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;
(DIR) diff --git a/po/de.gmo b/po/de.gmo
Binary files differ.
(DIR) 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 <LL@li.org>\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 ben@bellatrix.pcl.ox.ac.uk\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 ben@bellatrix.pcl.ox.ac.uk"
+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 ben@bellatrix.pcl.ox.ac.uk\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"
(DIR) 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 <LL@li.org>\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 ben@bellatrix.pcl.ox.ac.uk\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 ben@bellatrix.pcl.ox.ac.uk"
+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 ben@bellatrix.pcl.ox.ac.uk\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 ""
(DIR) diff --git a/po/stamp-cat-id b/po/stamp-cat-id
t@@ -0,0 +1 @@
+timestamp
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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 */
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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
(DIR) 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
+
(DIR) 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 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
+
+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) $(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 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ 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 '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ 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) $(LIBS)
+
+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 $$here/TAGS)
+
+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_srcdir) --output-dir=$$top_distdir --gnu src/Makefile
+ @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:
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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 "
+ "ben@bellatrix.pcl.ox.ac.uk"));
+ 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.Drugs);
+ 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 */
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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
(DIR) 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
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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
+}
+
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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__ */
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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,"",NULL,
+ 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\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 ben@bellatrix.pcl.ox.ac.uk\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 */
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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
(DIR) 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 | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX CAPTION "dopewars" MENU MainMenu
+BEGIN
+ CONTROL "Stats", 101, "button", BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 5, 5, 217, 48
+ CONTROL "", 102, "EDIT", ES_LEFT | ES_AUTOVSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 6, 58, 216, 56
+ CONTROL "", 103, "LISTBOX", LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 6, 126, 87, 54
+ CONTROL "", 104, "LISTBOX", LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 135, 126, 87, 54
+ PUSHBUTTON "&Buy ->", 105, 98, 118, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "<- &Sell", 106, 98, 134, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Drop <-", 107, 98, 151, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Jet!", 108, 98, 168, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ 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_GROUP
+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 simulation of an imaginary drug market. dopewars is an All-American game which features buying, selling, and trying to get past the cops!", -1, 9, 7, 237, 26, WS_CHILD | WS_VISIBLE | WS_GROUP
+ CTEXT "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 have one month of game time to make your fortune.", -1, 9, 38, 237, 25, WS_CHILD | WS_VISIBLE | WS_GROUP
+ CTEXT "Copyright (C) 1998-2000 Ben Webb ben@bellatrix.pcl.ox.ac.uk", -1, 9, 68, 237, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ CTEXT "dopewars is released under the GNU General Public Licence", -1, 9, 82, 237, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "Drug Dealing and Research", -1, 19, 99, 92, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "Play Testing", -1, 19, 111, 42, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "Extensive Play Testing", -1, 19, 123, 77, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "Constructive Criticism", -1, 19, 135, 74, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "Unconstructive criticism", -1, 19, 147, 80, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ 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_GROUP
+ LTEXT "Owen Walsh", -1, 183, 111, 45, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "Katherine Holt", -1, 116, 123, 49, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "Caroline Moore", -1, 183, 123, 53, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "Andrea Elliot-Smith", -1, 116, 135, 64, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "Pete Winn", -1, 183, 135, 37, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LTEXT "James Matthews", -1, 116, 147, 57, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ DEFPUSHBUTTON "OK", ID_OK, 108, 163, 38, 17, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+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_VISIBLE | WS_GROUP
+ EDITTEXT ED_NAME, 107, 5, 57, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP
+ CONTROL "&Hostname", ST_HOSTNAME, "STATIC", SS_LEFT | WS_CHILD | NOT WS_VISIBLE | WS_GROUP, 13, 48, 35, 8
+ CONTROL "&Port", ST_PORT, "STATIC", SS_LEFT | WS_CHILD | NOT WS_VISIBLE | WS_GROUP, 13, 73, 16, 8
+ CONTROL "", ED_HOSTNAME, "EDIT", ES_LEFT | WS_CHILD | NOT WS_VISIBLE | WS_BORDER | WS_TABSTOP, 52, 46, 103, 12
+ CONTROL "", ED_PORT, "EDIT", ES_LEFT | WS_CHILD | NOT WS_VISIBLE | WS_BORDER | WS_TABSTOP, 52, 71, 103, 12
+ CONTROL "&Connect", BT_CONNECT, "BUTTON", BS_PUSHBUTTON | WS_CHILD | NOT WS_VISIBLE | WS_TABSTOP, 44, 93, 80, 14
+ CONTROL "&Antique mode", CB_ANTIQUE, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | NOT WS_VISIBLE | WS_TABSTOP, 56, 50, 58, 12
+ CONTROL "&Start single-player game", BT_STARTSINGLE, "BUTTON", BS_PUSHBUTTON | WS_CHILD | NOT WS_VISIBLE | WS_TABSTOP, 38, 83, 92, 14
+ CONTROL "", LB_SERVERLIST, "LISTBOX", LBS_NOTIFY | LBS_HASSTRINGS | LBS_USETABSTOPS | WS_CHILD | NOT WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 11, 39, 147, 56
+ CONTROL "&Update", BT_UPDATE, "BUTTON", BS_PUSHBUTTON | WS_CHILD | NOT WS_VISIBLE | WS_TABSTOP, 60, 99, 49, 14
+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_GROUP
+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_VISIBLE | WS_VSCROLL | WS_TABSTOP, 23, 7, 72, 62
+ LTEXT "at $1000", ST_DEALPRICE, 99, 9, 54, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ CTEXT "You can afford 100, and can carry 100", ST_DEALLIMIT, 3, 38, 151, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ RTEXT "Buy how many?", ST_DEALNUM, 30, 51, 56, 8, SS_RIGHT | WS_CHILD | WS_VISIBLE | WS_GROUP
+ EDITTEXT ED_DEALNUM, 91, 49, 33, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP
+ DEFPUSHBUTTON "OK", ID_OK, 41, 69, 28, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ CTEXT "You are currently carrying 100", ST_DEALCARRY, 3, 27, 151, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ PUSHBUTTON "Cancel", ID_CANCEL, 87, 69, 28, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+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 | WS_GROUP
+ LTEXT "Guns carried", ST_GUNSCARRIED, 133, 8, 71, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ CONTROL "", LB_GUNSHERE, "LISTBOX", LBS_NOTIFY | LBS_HASSTRINGS | LBS_USETABSTOPS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 7, 19, 86, 42
+ CONTROL "", LB_GUNSCARRIED, "LISTBOX", LBS_NOTIFY | LBS_HASSTRINGS | LBS_USETABSTOPS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 133, 19, 86, 42
+ PUSHBUTTON "&Buy ->", BT_BUYGUN, 98, 19, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "<- &Sell", BT_SELLGUN, 98, 38, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ DEFPUSHBUTTON "OK", ID_OK, 98, 66, 30, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+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_VISIBLE | WS_GROUP
+ CONTROL "", LB_PLAYERLIST, "LISTBOX", LBS_NOTIFY | LBS_HASSTRINGS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 7, 18, 127, 49
+ PUSHBUTTON "&Close", ID_CANCEL, 57, 74, 28, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+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 | LBS_HASSTRINGS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 8, 13, 130, 43
+ 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_VISIBLE | WS_BORDER | WS_TABSTOP
+ CONTROL "All players", CB_TALKALL, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 8, 57, 45, 12
+ LTEXT "Message", -1, 8, 71, 34, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ DEFPUSHBUTTON "&Send", BT_TALKSEND, 31, 100, 27, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Close", ID_CANCEL, 89, 100, 27, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+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_GROUP
+ LTEXT "Guns", ST_INVENGUNS, 111, 5, 51, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LISTBOX LB_INVENDRUGS, 7, 15, 93, 48, LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BORDER | LBS_HASSTRINGS | LBS_USETABSTOPS | WS_VSCROLL
+ LISTBOX LB_INVENGUNS, 111, 15, 93, 48, LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BORDER | LBS_HASSTRINGS | LBS_USETABSTOPS | WS_VSCROLL
+ PUSHBUTTON "&Close", ID_CANCEL, 91, 69, 28, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+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_USETABSTOPS | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 7, 6, 142, 119
+ PUSHBUTTON "&Close", ID_CANCEL, 64, 132, 28, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+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_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL, 6, 4, 172, 68
+ PUSHBUTTON "&Deal Drugs", BT_DEALDRUGS, 6, 77, 46, 16, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Fight", BT_FIGHT, 69, 77, 46, 16, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Run", BT_RUN, 132, 77, 46, 16, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+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 will help the cops to attack that player, and then report back to you on the encounter. Remember that the bitch will leave you temporarily, so any guns or drugs that he's carrying may be lost!", ST_ERRAND, 5, 7, 179, 53, WS_CHILD | WS_VISIBLE | WS_GROUP
+ LISTBOX LB_ERRANDPLAY, 19, 65, 152, 39, LBS_NOTIFY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL
+ DEFPUSHBUTTON "OK", ID_OK, 27, 110, 32, 17, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Cancel", ID_CANCEL, 130, 110, 32, 17, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+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_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 7, 29, 45, 12
+ CONTROL "&Deposit", RB_DEPOSIT, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 47, 45, 12
+ 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 | WS_BORDER | WS_TABSTOP
+ DEFPUSHBUTTON "OK", ID_OK, 13, 68, 32, 16, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Cancel", ID_CANCEL, 67, 68, 32, 16, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ CTEXT "Cash: $0", ST_MONEY, 7, 5, 102, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+ CTEXT "Bank: $0", ST_BANK, 7, 16, 102, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+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 | WS_BORDER | WS_TABSTOP
+ DEFPUSHBUTTON "OK", ID_OK, 15, 53, 32, 16, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ PUSHBUTTON "&Cancel", ID_CANCEL, 69, 53, 32, 16, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+ 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_GROUP
+ CTEXT "Debt: $0", ST_BANK, 7, 15, 102, 8, WS_CHILD | WS_VISIBLE | WS_GROUP
+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 change it:-", -1, 5, 6, 137, 17, WS_CHILD | WS_VISIBLE | WS_GROUP
+ EDITTEXT EB_NEWNAME, 8, 28, 131, 12, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP
+ DEFPUSHBUTTON "OK", ID_OK, 62, 46, 24, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+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 | WS_TABSTOP
+END
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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\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"));
+ gtk_box_pack_start(GTK_BOX(vbox),label,FALSE,FALSE,0);
+
+ VersionStr=g_strdup_printf(_("Version %s "
+"Copyright (C) 1998-2000 Ben Webb ben@bellatrix.pcl.ox.ac.uk\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,0,
+ 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 */
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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 order
+ 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);
+ }
+ }
+}
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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\n"
+ "\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].Time,
+ 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.DropProb)) {
+ 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;
+}
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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.CarriedList,
+ ClientData.Stats.BuyButton,ClientData.Stats.SellButton,
+ 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_PUSHBUTTON,
+ 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-35,
+ 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,NULL);
+ 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 */
(DIR) 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: ben@bellatrix.pcl.ox.ac.uk */
+/* 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
(DIR) diff --git a/stamp-h.in b/stamp-h.in
t@@ -0,0 +1 @@
+timestamp