[Pioneers-commits] r2 - in trunk: . client client/ai client/common client/gtk client/gtk/data client/gtk/data/themes client/gtk/data/themes/FreeCIV-like client/gtk/data/themes/Iceland client/gtk/data/themes/Tiny client/gtk/data/themes/Wesnoth-like client/help client/help/C client/help/C/images common common/gtk debian docs editor editor/gtk macros meta-server po server server/gtk
kemm at garage.maemo.org
kemm at garage.maemo.org
Mon Dec 24 22:30:33 EET 2007
Author: kemm
Date: 2007-12-24 22:30:29 +0200 (Mon, 24 Dec 2007)
New Revision: 2
Added:
trunk/AUTHORS
trunk/COPYING
trunk/ChangeLog
trunk/Makefile.am
trunk/NEWS
trunk/README
trunk/README.Cygwin
trunk/README.MinGW
trunk/TODO
trunk/autogen.sh
trunk/client/
trunk/client/Makefile.am
trunk/client/ai/
trunk/client/ai/Makefile.am
trunk/client/ai/ai.c
trunk/client/ai/ai.h
trunk/client/ai/computer_names
trunk/client/ai/greedy.c
trunk/client/ai/lobbybot.c
trunk/client/callback.h
trunk/client/common/
trunk/client/common/Makefile.am
trunk/client/common/build.c
trunk/client/common/callback.c
trunk/client/common/client.c
trunk/client/common/client.h
trunk/client/common/develop.c
trunk/client/common/i18n.c
trunk/client/common/main.c
trunk/client/common/player.c
trunk/client/common/resource.c
trunk/client/common/robber.c
trunk/client/common/setup.c
trunk/client/common/stock.c
trunk/client/common/turn.c
trunk/client/gtk/
trunk/client/gtk/Makefile.am
trunk/client/gtk/admin-gtk.c
trunk/client/gtk/callbacks.c
trunk/client/gtk/chat.c
trunk/client/gtk/connect.c
trunk/client/gtk/data/
trunk/client/gtk/data/Makefile.am
trunk/client/gtk/data/brick.png
trunk/client/gtk/data/bridge.png
trunk/client/gtk/data/city.png
trunk/client/gtk/data/city_wall.png
trunk/client/gtk/data/develop.png
trunk/client/gtk/data/dice.png
trunk/client/gtk/data/finish.png
trunk/client/gtk/data/grain.png
trunk/client/gtk/data/lumber.png
trunk/client/gtk/data/ore.png
trunk/client/gtk/data/pioneers.desktop
trunk/client/gtk/data/pioneers.rc
trunk/client/gtk/data/pioneers.svg
trunk/client/gtk/data/road.png
trunk/client/gtk/data/settlement.png
trunk/client/gtk/data/ship.png
trunk/client/gtk/data/ship_move.png
trunk/client/gtk/data/splash.svg
trunk/client/gtk/data/style-ai.png
trunk/client/gtk/data/style-human-1.png
trunk/client/gtk/data/style-human-2.png
trunk/client/gtk/data/style-human-3.png
trunk/client/gtk/data/style-human-4.png
trunk/client/gtk/data/style-human-5.png
trunk/client/gtk/data/style-human-6.png
trunk/client/gtk/data/style-human-7.png
trunk/client/gtk/data/style-human.png
trunk/client/gtk/data/themes/
trunk/client/gtk/data/themes/FreeCIV-like/
trunk/client/gtk/data/themes/FreeCIV-like/Makefile.am
trunk/client/gtk/data/themes/FreeCIV-like/board.png
trunk/client/gtk/data/themes/FreeCIV-like/desert.png
trunk/client/gtk/data/themes/FreeCIV-like/field.png
trunk/client/gtk/data/themes/FreeCIV-like/forest.png
trunk/client/gtk/data/themes/FreeCIV-like/hill.png
trunk/client/gtk/data/themes/FreeCIV-like/mountain.png
trunk/client/gtk/data/themes/FreeCIV-like/pasture.png
trunk/client/gtk/data/themes/FreeCIV-like/sea.png
trunk/client/gtk/data/themes/FreeCIV-like/theme.cfg
trunk/client/gtk/data/themes/Iceland/
trunk/client/gtk/data/themes/Iceland/Makefile.am
trunk/client/gtk/data/themes/Iceland/desert.png
trunk/client/gtk/data/themes/Iceland/field_grain.png
trunk/client/gtk/data/themes/Iceland/forest_lumber.png
trunk/client/gtk/data/themes/Iceland/gold.png
trunk/client/gtk/data/themes/Iceland/hill_brick.png
trunk/client/gtk/data/themes/Iceland/mountain_ore.png
trunk/client/gtk/data/themes/Iceland/pasture_wool.png
trunk/client/gtk/data/themes/Iceland/theme.cfg
trunk/client/gtk/data/themes/Makefile.am
trunk/client/gtk/data/themes/Tiny/
trunk/client/gtk/data/themes/Tiny/Makefile.am
trunk/client/gtk/data/themes/Tiny/board.png
trunk/client/gtk/data/themes/Tiny/brick-lorindol.png
trunk/client/gtk/data/themes/Tiny/brick-port.png
trunk/client/gtk/data/themes/Tiny/desert-lorindol.png
trunk/client/gtk/data/themes/Tiny/gold-lorindol.png
trunk/client/gtk/data/themes/Tiny/grain-lorindol.png
trunk/client/gtk/data/themes/Tiny/grain-port.png
trunk/client/gtk/data/themes/Tiny/lumber-lorindol.png
trunk/client/gtk/data/themes/Tiny/lumber-port.png
trunk/client/gtk/data/themes/Tiny/ore-lorindol.png
trunk/client/gtk/data/themes/Tiny/ore-port.png
trunk/client/gtk/data/themes/Tiny/sea-lorindol.png
trunk/client/gtk/data/themes/Tiny/theme.cfg
trunk/client/gtk/data/themes/Tiny/wool-lorindol.png
trunk/client/gtk/data/themes/Tiny/wool-port.png
trunk/client/gtk/data/themes/Wesnoth-like/
trunk/client/gtk/data/themes/Wesnoth-like/Makefile.am
trunk/client/gtk/data/themes/Wesnoth-like/board.png
trunk/client/gtk/data/themes/Wesnoth-like/desert.png
trunk/client/gtk/data/themes/Wesnoth-like/field.png
trunk/client/gtk/data/themes/Wesnoth-like/forest.png
trunk/client/gtk/data/themes/Wesnoth-like/gold.png
trunk/client/gtk/data/themes/Wesnoth-like/hill.png
trunk/client/gtk/data/themes/Wesnoth-like/mountain.png
trunk/client/gtk/data/themes/Wesnoth-like/pasture.png
trunk/client/gtk/data/themes/Wesnoth-like/sea.png
trunk/client/gtk/data/themes/Wesnoth-like/theme.cfg
trunk/client/gtk/data/themes/board.png
trunk/client/gtk/data/themes/desert.png
trunk/client/gtk/data/themes/field.png
trunk/client/gtk/data/themes/forest.png
trunk/client/gtk/data/themes/gold.png
trunk/client/gtk/data/themes/hill.png
trunk/client/gtk/data/themes/mountain.png
trunk/client/gtk/data/themes/pasture.png
trunk/client/gtk/data/themes/plain.png
trunk/client/gtk/data/themes/sea.png
trunk/client/gtk/data/trade.png
trunk/client/gtk/data/wool.png
trunk/client/gtk/develop.c
trunk/client/gtk/discard.c
trunk/client/gtk/frontend.c
trunk/client/gtk/frontend.h
trunk/client/gtk/gameover.c
trunk/client/gtk/gold.c
trunk/client/gtk/gui.c
trunk/client/gtk/gui.h
trunk/client/gtk/histogram.c
trunk/client/gtk/histogram.h
trunk/client/gtk/identity.c
trunk/client/gtk/interface.c
trunk/client/gtk/legend.c
trunk/client/gtk/monopoly.c
trunk/client/gtk/name.c
trunk/client/gtk/offline.c
trunk/client/gtk/player.c
trunk/client/gtk/plenty.c
trunk/client/gtk/quote-view.c
trunk/client/gtk/quote-view.h
trunk/client/gtk/quote.c
trunk/client/gtk/resource-table.c
trunk/client/gtk/resource-table.h
trunk/client/gtk/resource.c
trunk/client/gtk/settingscreen.c
trunk/client/gtk/state.c
trunk/client/gtk/trade.c
trunk/client/help/
trunk/client/help/C/
trunk/client/help/C/Makefile.am
trunk/client/help/C/Makefile.in
trunk/client/help/C/images/
trunk/client/help/C/images/actions.png
trunk/client/help/C/images/brick.png
trunk/client/help/C/images/chat.png
trunk/client/help/C/images/client.png
trunk/client/help/C/images/connect-dialog.png
trunk/client/help/C/images/desert.png
trunk/client/help/C/images/develop-cards.png
trunk/client/help/C/images/discard-dialog.png
trunk/client/help/C/images/discards.png
trunk/client/help/C/images/field.png
trunk/client/help/C/images/forest.png
trunk/client/help/C/images/gameover-dialog.png
trunk/client/help/C/images/gold.png
trunk/client/help/C/images/grain.png
trunk/client/help/C/images/hill.png
trunk/client/help/C/images/identity.png
trunk/client/help/C/images/join-private-dialog.png
trunk/client/help/C/images/legend-dialog.png
trunk/client/help/C/images/lumber.png
trunk/client/help/C/images/map.png
trunk/client/help/C/images/messages.png
trunk/client/help/C/images/monopoly-dialog.png
trunk/client/help/C/images/mountain.png
trunk/client/help/C/images/ore.png
trunk/client/help/C/images/pasture.png
trunk/client/help/C/images/place-robber.png
trunk/client/help/C/images/player-summary.png
trunk/client/help/C/images/plenty-dialog.png
trunk/client/help/C/images/quote.png
trunk/client/help/C/images/resources.png
trunk/client/help/C/images/sea.png
trunk/client/help/C/images/server-create.png
trunk/client/help/C/images/servers-dialog.png
trunk/client/help/C/images/status.png
trunk/client/help/C/images/steal-from.png
trunk/client/help/C/images/trade.png
trunk/client/help/C/images/wool.png
trunk/client/help/C/legal.xml
trunk/client/help/C/pioneers-C.omf
trunk/client/help/C/pioneers.xml
trunk/client/help/Makefile.am
trunk/common/
trunk/common/Makefile.am
trunk/common/buildrec.c
trunk/common/buildrec.h
trunk/common/cards.c
trunk/common/cards.h
trunk/common/common_glib.c
trunk/common/common_glib.h
trunk/common/cost.c
trunk/common/cost.h
trunk/common/driver.c
trunk/common/driver.h
trunk/common/game.c
trunk/common/game.h
trunk/common/gtk/
trunk/common/gtk/Makefile.am
trunk/common/gtk/aboutbox.c
trunk/common/gtk/aboutbox.h
trunk/common/gtk/colors.c
trunk/common/gtk/colors.h
trunk/common/gtk/common_gtk.c
trunk/common/gtk/common_gtk.h
trunk/common/gtk/config-gnome.c
trunk/common/gtk/config-gnome.h
trunk/common/gtk/game-rules.c
trunk/common/gtk/game-rules.h
trunk/common/gtk/game-settings.c
trunk/common/gtk/game-settings.h
trunk/common/gtk/gtkbugs.c
trunk/common/gtk/gtkbugs.h
trunk/common/gtk/guimap.c
trunk/common/gtk/guimap.h
trunk/common/gtk/player-icon.c
trunk/common/gtk/player-icon.h
trunk/common/gtk/polygon.c
trunk/common/gtk/polygon.h
trunk/common/gtk/select-game.c
trunk/common/gtk/select-game.h
trunk/common/gtk/theme.c
trunk/common/gtk/theme.h
trunk/common/log.c
trunk/common/log.h
trunk/common/map.c
trunk/common/map.h
trunk/common/map_query.c
trunk/common/network.c
trunk/common/network.h
trunk/common/quoteinfo.c
trunk/common/quoteinfo.h
trunk/common/state.c
trunk/common/state.h
trunk/configure.ac
trunk/debian/
trunk/debian/changelog
trunk/debian/compat
trunk/debian/conffiles.ex
trunk/debian/control
trunk/debian/copyright
trunk/debian/cron.d.ex
trunk/debian/dirs
trunk/debian/docs
trunk/debian/emacsen-install.ex
trunk/debian/emacsen-remove.ex
trunk/debian/emacsen-startup.ex
trunk/debian/init.d.ex
trunk/debian/maemo-pioneers-default.ex
trunk/debian/maemo-pioneers-doc.docs
trunk/debian/maemo-pioneers-doc.install
trunk/debian/maemo-pioneers.doc-base.EX
trunk/debian/manpage.1.ex
trunk/debian/manpage.sgml.ex
trunk/debian/manpage.xml.ex
trunk/debian/menu.ex
trunk/debian/postinst.ex
trunk/debian/postrm.ex
trunk/debian/preinst.ex
trunk/debian/prerm.ex
trunk/debian/rules
trunk/debian/watch.ex
trunk/docs/
trunk/docs/Makefile.am
trunk/docs/pioneers-meta-server.6
trunk/docs/pioneers-server-console.6
trunk/docs/pioneers-server-gtk.6
trunk/docs/pioneers.6
trunk/docs/pioneersai.6
trunk/editor/
trunk/editor/Makefile.am
trunk/editor/gtk/
trunk/editor/gtk/Makefile.am
trunk/editor/gtk/editor.c
trunk/editor/gtk/game-buildings.c
trunk/editor/gtk/game-buildings.h
trunk/editor/gtk/game-devcards.c
trunk/editor/gtk/game-devcards.h
trunk/editor/gtk/game-resources.c
trunk/editor/gtk/game-resources.h
trunk/editor/gtk/pioneers-editor.desktop
trunk/editor/gtk/pioneers-editor.rc
trunk/editor/gtk/pioneers-editor.svg
trunk/macros/
trunk/macros/Makefile.am
trunk/macros/gnome-autogen.sh
trunk/macros/type_socklen_t.m4
trunk/meta-server/
trunk/meta-server/Makefile.am
trunk/meta-server/main.c
trunk/omf.make
trunk/pioneers.nsi.in
trunk/pioneers.spec.in
trunk/po/
trunk/po/ChangeLog
trunk/po/Makefile.in.in
trunk/po/POTFILES.in
trunk/po/af.po
trunk/po/de.po
trunk/po/es.po
trunk/po/fr.po
trunk/po/hu.po
trunk/po/it.po
trunk/po/ja.po
trunk/po/nl.po
trunk/po/pioneers.pot
trunk/po/sv.po
trunk/server/
trunk/server/5-6-player.game
trunk/server/Another_swimming_pool_in_the_wall.game
trunk/server/Cube.game
trunk/server/Evil_square.game
trunk/server/GuerreDe100ans.game
trunk/server/Makefile.am
trunk/server/Mini_another_swimming_pool_in_the_wall.game
trunk/server/admin.c
trunk/server/admin.h
trunk/server/archipel_gold.game
trunk/server/buildutil.c
trunk/server/canyon.game
trunk/server/coeur.game
trunk/server/conquest+ports.game
trunk/server/conquest.game
trunk/server/crane_island.game
trunk/server/default.game
trunk/server/develop.c
trunk/server/discard.c
trunk/server/four-islands.game
trunk/server/glib-driver.c
trunk/server/glib-driver.h
trunk/server/gold.c
trunk/server/gtk/
trunk/server/gtk/Makefile.am
trunk/server/gtk/main.c
trunk/server/gtk/pioneers-server.desktop
trunk/server/gtk/pioneers-server.rc
trunk/server/gtk/pioneers-server.svg
trunk/server/henjes.game
trunk/server/iles.game
trunk/server/lobby.game
trunk/server/lorindol.game
trunk/server/main.c
trunk/server/meta.c
trunk/server/player.c
trunk/server/pond.game
trunk/server/pregame.c
trunk/server/resource.c
trunk/server/robber.c
trunk/server/seafarers-gold.game
trunk/server/seafarers.game
trunk/server/server.c
trunk/server/server.h
trunk/server/small.game
trunk/server/square.game
trunk/server/star.game
trunk/server/trade.c
trunk/server/turn.c
trunk/server/x.game
trunk/xmldocs.make
Log:
Initial import
Somewhat playable, but needs huge interface redesign and so on...
Anyway, you already can start your own server (with or w/o AI bots) or
connect to internet servers and play.
Added: trunk/AUTHORS
===================================================================
--- trunk/AUTHORS (rev 0)
+++ trunk/AUTHORS 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,14 @@
+Dave Cole <dave at dccs.com.au>
+Andy Heroff <aheroff at mediaone.net>
+Roman Hodek <roman at hodek.net>
+Dan Egnor <egnor at ofb.net>
+Steve Langasek <vorlon at dodds.net>
+Bibek Sahu <scorpio at dodds.net>
+Roderick Schertler <roderick at argon.org>
+Jeff Breidenbach <jab at debian.org>
+David Fallon <davef at tetsubo.com>
+Matt Waggoner <matt at waggoner.com>
+Geoff Hanson <gwhizz at usa.net>
+Bas Wijnen <shevek at fmf.nl>
+Roland Clobus <rclobus at bigfoot.com>
+Brian Wellington <bwelling at xbill.org>
Added: trunk/COPYING
===================================================================
--- trunk/COPYING (rev 0)
+++ trunk/COPYING 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 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.
Added: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog (rev 0)
+++ trunk/ChangeLog 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,4613 @@
+
+2007-10-07 Roland Clobus <rclobus at bigfoot.com>
+ * Released version 0.11.3
+
+2007-10-07 Roland Clobus <rclobus at bigfoot.com>
+ * common/state.c: Purge cache when disconnecting.
+ * server/player.c: Cached players must receive broadcasts.
+ * common/network.c: Log when a connection has a time out.
+
+2007-10-03 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, server/server.c: Use sigaction instead signal.
+
+2007-09-16 Roland Clobus <rclobus at bigfoot.com>
+ * common/network.h, common/state.c, common/network.c: The server could
+ crash when a SIGPIPE was received.
+
+2007-08-11 Roland Clobus <rclobus at bigfoot.com>
+ * common/network.c: Added net_would_block and net_write_error to help
+ porting the server to MS Windows (based on a patch by Keishi Suenaga).
+ * server/player.c: When a player is still connecting, don't reuse the
+ player number.
+
+2007-08-08 Roland Clobus <rclobus at bigfoot.com>
+ * getVersions.sh: Updated for SF
+
+2007-08-05 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Work version is 0.11.3
+ * docs/README.release: updated svn branch command.
+
+2007-08-05 Roland Clobus <rclobus at bigfoot.com>
+ * Released version 0.11.2
+
+2007-08-05 Roland Clobus <rclobus at bigfoot.com>
+ * server/robber.c: Do not use sm_send in the server, but player_send.
+ * common/network.c: Added \n after a log message.
+ * pioneers.spec.in: Corrected download location, changed packager name.
+ * docs/README.release: Updated release script
+ * README, NEWS, client/ai/lobbybot.c: Prepare for release 0.11.2
+
+2007-08-05 Bas Wijnen <shevek at fmf.nl>
+ * client/common/client.c: Fixed OK button in discard dialog
+
+2007-08-04 Roland Clobus <rclobus at bigfoot.com>
+ * common/map_query.c: Added checks against NULL pointers, based on
+ the patch by ffaadd (#1767378), which could crash the server.
+
+2007-08-01 Roland Clobus <rclobus at bigfoot.com>
+ * client/help/C/pioneers.xml, client/help/C/images/quote.png,
+ client/help/C/images/trade.png, client/help/C/images/server-create.png,
+ client/help/C/images/plenty-dialog.png, client/help/C/images/sea.png,
+ client/help/C/images/monopoly-dialog.png, client/help/C/images/map.png,
+ client/help/C/images/pasture.png, client/help/C/images/field.png,
+ client/help/C/images/desert.png,
+ client/help/C/images/player-summary.png, client/help/C/images/hill.png,
+ client/help/C/images/identity.png, client/help/C/images/brick.png,
+ client/help/C/images/grain.png, client/help/C/images/actions.png,
+ client/help/C/images/forest.png,
+ client/help/C/images/gameover-dialog.png,
+ client/help/C/images/join-private-dialog.png,
+ client/help/C/images/discard-dialog.png,
+ client/help/C/images/resources.png, client/help/C/images/client.png,
+ client/help/C/images/wool.png, client/help/C/images/gold.png,
+ client/help/C/images/ore.png, client/help/C/images/connect-dialog.png,
+ client/help/C/images/servers-dialog.png,
+ client/help/C/images/lumber.png, client/help/C/images/mountain.png,
+ client/help/C/images/legend-dialog.png: Updated the manual
+ * docs/README.release: Added a note about the manual
+
+2007-07-29 Roland Clobus <rclobus at bigfoot.com>
+ * pioneers.nsi.in: Added city_wall.png
+
+2007-07-22 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Work version is 0.11.2
+ * NEWS: Fixed a typo
+ * client/common/client.c, client/common/gui.c: Fixed for gcc-2.95
+ * client/gtk/name.c: make reindent
+
+2007-07-22 Roland Clobus <rclobus at bigfoot.com>
+ * Released version 0.11.1
+
+2007-07-22 Roland Clobus <rclobus at bigfoot.com>
+ * pioneers.spec.in: Updated. It works for openSUSE 10.2.
+ * server/gtk/main.c: Cosmetic changes.
+ * server/server.c, server/server.h, server/admin.c, server/admin.h:
+ Added 'send-message', 'help', 'info' to the admin commands.
+ The addition of 'send-message' is based on a patch by David Hall
+ <hacking at gringer.dis.org.nz>
+ * common/gtk/theme.c: The default theme is now 'Tiny'.
+ * common/gtk/guimap.c: Use the full size for the map. The font size in
+ the server was effectively always 1pt.
+ * pioneers.nsi.in: Added Afrikaans and Japanese.
+ * pioneers.nsi.in: Added style-*.png
+ * client/ai/computer_names: Corrected spelling of 'Gödel'
+ * README, NEWS: Updated for 0.11.1
+ * client/gtk/data/splash.svg: Updated to 0.11
+ * client/ai/lobbybot.c: Updated to 0.11
+
+2007-07-21 Roland Clobus <rclobus at bigfoot.com>
+ * server/server.h: Added robber undo in 0.11 change list.
+
+2007-07-21 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/player-icon.c, common/gtk/player-icon.h,
+ common/gtk/Makefile.am, server/player.c, server/server.h,
+ server/pregame.c, client/callback.h, client/gtk/callbacks.c,
+ client/gtk/name.c, client/gtk/frontend.h, client/gtk/data/Makefile.am,
+ client/gtk/player.c, client/gtk/quote-view.c, client/gtk/chat.c,
+ client/gtk/offline.c, client/gtk/connect.c, client/common/client.c,
+ client/common/client.h, client/common/callback.c,
+ client/common/player.c, client/ai/ai.c: Added a customizable player
+ icon. Based on a patch by Giancarlo Capella <giancarlo at comm.cc>.
+
+2007-07-21 Bas Wijnen <shevek at fmf.nl>
+ * common/map.c, server/player.c, server/robber.c, server/server.h,
+ client/callback.h, client/gtk/interface.c, client/gtk/callbacks.c,
+ client/gtk/frontend.h, client/common/client.c, client/common/client.h,
+ client/common/robber.c, client/common/callback.c, client/ai/greedy.c:
+ Show the robber in the new place when choosing who to steal from.
+
+2007-07-21 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, pioneers.nsi.in: Add minimum required Gtk+ version
+ from configure.ac in the installer builder script.
+
+2007-07-21 Bas Wijnen <shevek at fmf.nl>
+ * ChangeLog, docs/README.game, common/gtk/gtkbugs.c, common/state.c,
+ configure.ac, po/ChangeLog, client/gtk/quote.c,
+ client/help/C/custom.xsl: Clean up whitespace.
+
+2007-07-20 Roland Clobus<rclobus at bigfoot.com>
+ * common/state.c, common/state.h, configure.ac, server/gold.c,
+ server/resource.c, server/turn.c, server/player.c, server/develop.c,
+ server/trade.c, server/discard.c, server/robber.c, server/server.h,
+ server/pregame.c, server/buildutil.c, client/common/client.c:
+ Updating the protocol to 0.11. All messages sent by the server are
+ versioned. Based on a patch by Bas Wijnen <shevek at fmf.nl>.
+
+2007-07-19 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/guimap.c: gmap->area was unref'd too often.
+ * client/callback.h, client/gtk/player.c: Cleanup of
+ player->user_data.
+ * server/gtk/main.c: Allow themes.
+
+2007-06-05 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/gtkbugs.c: action_set_sensitive is still (Gtk+-2.10) not
+ fixed, so the version check is disabled.
+ * client/gtk/connect.c: Removed a debug message.
+
+2007-05-13 Roland Clobus <rclobus at bigfoot.com>
+ * editor/gtk/game-parameters.h, editor/gtk/editor.c,
+ editor/gtk/Makefile.am, editor/gtk/game-parameters.c,
+ common/map-query.c, common/gtk/common_gtk.h,
+ common/gtk/game-settings.c, common/gtk/game-settings.h,
+ common/gtk/Makefile.am, common/gtk/commmon_gtk.c, common/game.c,
+ common/map.c, common/game.h, common/map.h, server/gtk/main.c,
+ client/gtk/connect.c: Added victory point check. Game rules are split
+ from game settings.
+ * editor/gtk/game-settings.c -> common/gtk/game-rules.c,
+ editor/gtk/game-settings.h -> common/gtk/game-rules.h: Renamed
+ * pioneers.spec.in: Sorted the language list, added af and ja.
+
+2007-05-13 Brian Wellington <bwelling at xbill.org>
+ * editor/gtk/game-buildings.c, common/map_query.c,
+ common/gtk/guimap.c, common/gtk/guimap.h, common/cost.c,
+ common/game.c, common/cost.h, common/state.c, common/map.h,
+ common/buildrec.h, server/turn.c, server/discard.c, server/server.h,
+ server/pregame.c, server/buildutil.c, client/callback.h,
+ client/gtk/interface.c, client/gtk/frontend.c, client/gtk/frontend.h,
+ client/gtk/data/Makefile.am, client/gtk/data/city_wall.png,
+ client/gtk/player.c, client/gtk/legend.c, client/gtk/settingscreen.c,
+ client/gtk/gui.c, client/gtk/identity.c, client/common/client.c,
+ client/common/client.h, client/common/stock.c,
+ client/common/callback.c, client/common/player.c: Added support for
+ city walls (using 'extension' in the protocol)
+
+2005-05-13 Roland Clobus <rclobus at bigfoot.com>
+ * server/player.c, server/server.h: Use 'extension' for broadcasts.
+
+2007-05-08 Roland Clobus <rclobus at bigfoot.com>
+ * editor/gtk/editor.c, common/gtk/guimap.c, common/gtk/select-game.c,
+ common/gtk/guimap.h, common/gtk/select-game.h, server/gtk/main.c,
+ client/gtk/gui.c: Map preview in the server.
+
+2007-04-29 Brian Wellington <bwelling at xbill.org>
+ * common/gtk/polygon.c, common/gtk/polygon.h, common/gtk/guimap.c:
+ Add the poly_draw_with_border() function to draw bordered polygons.
+
+2007-04-29 Brian Wellington <bwelling at xbill.org>
+ * client/gtk/gui.c: Add support for NULL pointer for shortcuts.
+
+2007-04-29 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/guimap.c: Simplified code to handle better updates.
+
+2007-04-29 Brian Wellington <bwelling at xbill.org>
+ * client/gtk/gui.c: Add a workaround for gtk bug #434261 that
+ causes strings like (Fn) in toolbar labels to be mishandled.
+
+2007-04-29 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/gui.c: Upgraded the code to 2.6, and allow for
+ toolbuttons without shortcut keys.
+ * common/network.c: Don't log the keepalive messages.
+
+2007-04-28 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/guimap.c, common/gtk/guimap.h, client/gtk/interface.c,
+ client/gtk/frontend.c: Single click actions are set enabled with the
+ same mechanism as the GtkActions.
+
+2007-04-17 Roland Clobus <rclobus at bigfoot.com>
+ * common/state.c, server/pregame.c: Disconnect during mode_pregame
+ could crash the server.
+
+2007-04-15 Bernd Ernesti <veega at users.sourceforge.net>
+ * editor/gtk/editor.c, meta-server/main.c, server/gtk/main.c,
+ server/main.c: #include <locale.h> where needed.
+
+2007-04-09 Roland Clobus <rclobus at bigfoot.com>
+ * pioneers.nsi.in: Added a better check for the Gtk+ runtime, and
+ allow the installer to continue, even when no runtime is found.
+
+2007-04-08 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Reorder the language codes (now alphabetical)
+
+2007-03-04 Roland CLobus <rclobus at bigfoot.com>
+ * common/gtk/guimap.c, common/gtk/guimap.h, client/gtk/identify.c: Fix
+ for #1589423. Sets a minimum size, to avoid drawing a polygon with
+ only (0,0) as coordinates.
+
+2007-02-18 Roland Clobus <rclobus at bigfoot.com>
+ * server/player.c: Fix for #1473765. Don't recycle player objects when
+ a (re)connect is in progress.
+ * common/game.c, common/game.h, common/state.h, common/cards.c,
+ server/develop.c, client/callback.h, client/gtk/settingscreen.c,
+ client/common/client.c, client/common/develop.c: Renamed
+ STAT_UNIVERSITY enum.
+ * client/gtk/develop.c: Cluster development cards of the same type.
+
+2006-11-18 Roland Clobus <rclobus at bigfoot.com>
+ * client/ai/computer_names: Fixed a typo (present since 2000 :-)
+
+2006-10-14 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/gui.c: Move the chat panel to the right or the bottom of
+ the screen. Based on a patch by Rich Harkins <rich at worldsinfinite.com>
+ which required a restart.
+ * ChangeLog: Enabled a BOM, so the comment about utf-8 is no longer
+ required.
+ * configure.ac, server/gtk/main.c, server/server.c, server/server.h,
+ server/main.c: Replaced alarm with g_timeout_add.
+ * common/network.c: Added wrapper functions for reporting error
+ messages.
+
+2006-10-01 Rich Harkins <rich at worldsinfinite.com>
+ * Makefile.am, server/gtk/main.c: Launch the client from the server.
+
+2006-09-16 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Subversion repository is at 0.10.3.
+ * server/gtk/Makefile.am, server/gtk/pioneers-server.rc: Add Windows
+ icon for the server.
+
+2006-09-16 Roland Clobus <rclobus at bigfoot.com>
+ * Released version 0.10.2
+
+2006-09-16 Roland Clobus <rclobus at bigfoot.com>
+ * editor/gtk/editor.c, server/gtk/main.c, server/main.c,
+ client/gtk/offline.c, client/ai/ai.c: Added --version.
+ * common/network.h, common/network.c, meta-server/main.c,
+ server/player.c, server/server.c, server/server.h, server/admin.c: Use
+ net_closesocket to close a socket (Windows port closes sockets
+ differently).
+ * common/gtk/gtkbugs.c: Cannot press a button twice without moving the
+ cursor out and in again. The workaround depends on the runtime version
+ of Gtk+, not the version at compile time. (Refinement of the patch
+ 2006-09-03)
+ * server/meta.c: Log when unknown messages are sent from the meta
+ server.
+ * Makefile.am: Add 48x48 icons (for Windows XP, Thumbnail view).
+
+2006-09-12 Stefan Walter <sw at gegenunendlich.de>
+ * common/Makefile.am: Creation of version.h compatible with FreeBSD.
+
+2006-09-12 Roland Clobus <rclobus at bigfoot.com>
+ * server/meta.c, meta-server/main.c: Meta server disconnects
+ unresponsive servers. Server shows a message when the meta server
+ disconnects.
+ * client/gtk/interface.c: Don't change GUI state when a second quote
+ is issued.
+ * common/game.c: Return NULL pointer when game not found.
+
+2006-09-10 Bas Wijnen <wijnen at debian.org>
+ * common/game.c: Treat errors in files as end-of-file, and an
+ incomplete line at the end as a complete line.
+
+2006-09-10 LT-P <LT-P at LT-P.net>
+ * server/iles.game, server/GuerreDe100ans.game: Added
+ island-discovery-bonus.
+
+2006-09-10 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, meta-server/main.c: Added glib commandline parsing,
+ --debug, --syslog-debug, --version. Fixed a bug for the current number
+ of players. Added the servername to the syslog output.
+ * client/gtk/data/Makefile.am: Added splash.svg to the tarball.
+ * common/state.c, server/player.c, server/trade.c, server/server.h,
+ server/pregame.c: Reconnect during trade.
+
+2006-09-07 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/data/Makefile.am: Add rule for splash.png
+
+2006-09-03 Thomas Schürger <thomas at schuerger.com>
+ * common/gtk/gtkbugs.c: Enabled workaround for toolbuttons that could
+ not be pressed twice.
+
+2006-09-03 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/data/Makefile.am, editor/gtk/Makefile.am: Remove the *.res
+ files from the tarball (partly revert 2006-09-01)
+ * Changed ChangeLog to utf8.
+
+2006-09-02 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/data/splash.png: Removed, replaced by splash.svg
+ * configure.ac, Makefile.am, client/gtk/Makefile.am,
+ client/gtk/data/Makefile.am: Fix themedir for Windows.
+ * pioneers.nsi.in, client/gtk/data/tick.png, client/gtk/data/cross.png:
+ Images are no longer in use.
+ * configure.ac: Nicer feedback from configure script when Gtk not
+ present.
+
+2006-09-01 Roland Clobus <rclobus at bigfoot.com>
+ * editor/gtk/Makefile.am, client/gtk/data/Makefile.am, Makefile.am:
+ Add the resource files for Microsoft Windows to the tarball.
+
+2006-08-31 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/data/splash.svg: Version 0.10 is shown now.
+ * docs/README.release: What to do extra when the protocol changes.
+ * README.Cygwin: Found more Cygwin packages.
+
+2006-08-26 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Subversion repository is at 0.10.2.
+ * docs/README.release: Added the command for tagging the repository.
+
+2006-08-26 Roland Clobus <rclobus at bigfoot.com>
+ * Released version 0.10.1
+
+2006-08-26 Roland Clobus <rclobus at bigfoot.com>
+ * client/ai/lobbybot.c: Make it build with gcc-2.95 again.
+ * server/gtk/main.c, server/meta.c: Changed reported hostname to
+ overridden hostname. If it is left empty, the metaserver will do a
+ hostname lookup.
+ * common/network.h: Include time.h too.
+ * client/help/C/pioneers.xml: Rename AI -> computer player.
+ * client/common/client.c, server/develop.c: Year of Plenty
+ communicates with "plenty %R" instead of "receives %R".
+ * client/gtk/interface.c: Disable single click cursor until all
+ players have discarded or chosen gold.
+ * common/network.c, common/network.h: Cleanup the timer when the
+ session is closed.
+ * client/help/C/pioneers.xml: Updated the FAQ.
+ * server/conquest.game, server/conquest+ports.game: Added nosetup for
+ the smaller islands.
+
+2006-08-26 Bas Wijnen <shevek at fmf.nl>
+ * common/network.h, common/state.c, common/state.h, common/network.c,
+ server/player.c, server/admin.c: Send keepalive packets when
+ connection is idle, and disconnect when no reply is received.
+ * client/gtk/player.c: Don't beep for players which are seen during
+ connecting.
+ * client/gtk/trade.c, client/gtk/quote-view.c,
+ client/gtk/quote-view.h: Show maritime trades only when they match the
+ supply, or no supply is specified.
+
+2006-08-21 Bas Wijnen <shevek at fmf.nl>
+ * common/gtk/config-gnome.c: Added include file.
+ * server/gold.c, client/callback.h, client/common/client.c,
+ client/ai/greedy.c: Notify players when resources are not distributed
+ due to empty bank.
+
+2006-08-17 Roland Clobus <rclobus at bigfoot.com>
+ * server/player.c: Use ERR as prefix when too many connections are
+ made.
+ * server/gtk/main.c, server/server.c, server/server.h, server/main.c,
+ server/admin.c: No global GameParams object. Added --file to
+ server-console.
+ * docs/README.game, common/buildrec.h, common/map_query.c,
+ common/game.c, common/game.h, common/map.h, common/buildrec.c,
+ server/turn.c, server/conquest.game, server/conquest+ports.game,
+ server/player.c, server/server.h, server/pregame.c,
+ server/four-islands.game, server/buildutil.c, client/callback.h,
+ client/gtk/callbacks.c, client/gtk/frontend.h, client/gtk/player.c,
+ client/gtk/settingscreen.c, client/common/client.c,
+ client/common/build.c, client/common/client.h, client/common/player.c:
+ Added island-discovery-bonus keyword.
+
+2006-08-17 Bas Wijnen <shevek at fmf.nl>
+ * AUTHORS, editor/gtk/editor.c: Show full authorlist in editor's
+ help->about, and add Brian to the full list.
+
+2006-08-15 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/connect.c: Don't connect to a new game at the meta server
+ as a viewer.
+ * common/network.h, common/log.c, common/network.c, README.subversion,
+ configure.ac, server/gtk/main.c, server/main.c,
+ client/gtk/callbacks.c, client/gtk/state.c, client/gtk/offline.c,
+ client/gtk/gui.h, client/ai/ai.c: Added --debug for debug messages,
+ instead of --enable-logging in configure.
+ * Makefile.am: Added dependency for icons.
+ * editor/gtk/Makefile.am, client/gtk/data/Makefile.am: Cleanup
+ the *-icon.o files. (Enables 'make distcheck' on Cygwin)
+ * common/gtk/aboutbox.c: Added homepage, and cleanup.
+ * README.subversion, configure.ac: Added --without-help.
+ * configure.ac, server/admin.c, client/gtk/player.c,
+ common/gtk/config-gnome.c: Cleanup configure.ac.
+ * Makefile.am: Remove trailing slash.
+
+2006-08-14 Bas Wijnen <shevek at fmf.nl>
+ * client/gtk/data/Makefile.am, editor/gtk/Makefile.am: Remove
+ incorrect direct dependency on *.rc files by executables.
+
+2006-08-14 Roland Clobus <rclobus at bigfoot.com>
+ * editor/gtk/Makefile.am, README.subversion, configure.ac,
+ Makefile.am, client/gtk/data/Makefile.am, client/gtk/Makefile.am:
+ Reduce the need for netpbm.
+ * client/gtk/connect.c: Translate the data from the meta server.
+ * server/lobby.game: Tournament-time is not a keyword anymore.
+ * client/gtk/interface.c: No build cursor during trade.
+ * server/gtk/main.c, server/server.c, server/server.h, server/main.c,
+ server/admin.c: Fix regression of random seating order dd 2006-08-10
+
+2006-08-14 Bas Wijnen <shevek at fmf.nl>
+ * client/callback.h, client/gtk/offline.h, client/common/client.c,
+ client/common/main.c, client/ai/ai.h, client/ai/greedy.c,
+ client/ai/ai/c: Make AI quit nicely instead of calling exit. Also
+ quit nicely if setup is impossible instead of crashing.
+
+2006-08-11 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/client.c: Marked a string for translation.
+ * client/gtk/interface.c: More robust gui_state changes.
+
+2006-08-10 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/client.c: Don't say 'A is now A' in the client.
+ * server/serer.c: Fix for a scope bug made 2006-08-05.
+ * server/player.c, client/common/client.c: i18n for NOTE messages,
+ close connection when a bad version is encountered, clearer message
+ when entering a tournament game.
+ * configure.ac: Protocol is now 0.10
+ * common/game.c, common/game.h: Don't broadcast tournament-time.
+ * docs/README.game: Information about *.game files
+ * editor/gtk/editor.c, common/game.c, common/map.c, common/game.h,
+ common/map.h, server/x.game, server/star.game, server/canyon.game,
+ server/pond.game, server/seafarers.game, server/lorindol.game,
+ server/seafarers-gold.game: Deserts need chit sequence numbers, chit
+ length must be correct.
+ * server/gtk/main.c, server/server.c, server/server.h: Replace global
+ 'random_order'.
+
+2006-08-05 Roland Clobus <rclobus at bigfoot.com>
+ * server/gtk/main.c, server/meta.c, server/server.c, server/server.h,
+ server/main.c, server/admin.c: Replaced a variable of global scope
+ with a variable of file scope to make -r implied when -m is specified.
+ * common/gtk/guimap.c: Use gmap->area when it exists.
+ * editor/gtk/editor.c, client/ai/lobbybot.c: Added translator comments.
+
+2006-08-05 Bas Wijnen <shevek at fmf.nl>
+ * client/gtk/connect.c: Avoid use of comma-operator.
+ * client/ai/greedy.c: Fix possible infinite loop after playing
+ monopoly card.
+ * docs/README.states, docs/client_states.fig: Updated to new
+ situation (the changes below, and changes which had been made before).
+ * common/state.c, common/state.h, client/common/client.c,
+ client/common/callback.c: Improved state handling.
+
+2006-08-04 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/interface.c: Enable roll dice for the second game of the
+ same instance of the client.
+ * client/common/client.c: Don't show waiting for your turn for
+ viewers.
+ * client/ai/greedy.c: AI can trade lumber again.
+ * server/turn.c: Unregister from the metaserver at game over.
+ * server/coeur.game: Don't shuffle gold tiles.
+ * client/gtk/gui.c: Settings used wrong variable.
+ * README.subversion: Information about building from the subversion
+ repository.
+ * editor/gtk/editor.c, common/gtk/guimap.c, common/gtk/guimap.h,
+ client/gtk/callbacks.c, client/gtk/gui.c, client/gtk/gui.h: Show
+ nosetup nodes in the editor and in the client (for players only).
+ * client/common/resource.c: Fix regression of 2006-07-27.
+ * docs/README.release, client/callback.h, client/gtk/interface.c,
+ client/gtk/callbacks.c, client/gtk/frontend.h, client/gtk/chat.c,
+ client/common/client.c, client/common/client.h,
+ client/common/Makefile.am, client/common/player.c,
+ client/common/chat.c, client/ai/ai.h, client/ai/greedy.c,
+ client/ai/Makefile.am, client/ai/ai.c, client/ai/lobbybot.c: Added
+ robot for the lobby.
+ * client/gtk/interface.c, client/gtk/frontend.h, client/gtk/discard.c,
+ client/gtk/state.c, client/gtk/offline.c, client/gtk/gui.c: Leave a
+ game without quitting the client.
+
+2006-08-01 Bas Wijnen <shevek at fmf.nl>
+ * configure.ac: Mention install root in notification.
+ * configure.ac, Makefile.am: Let configure.ac not touch AM_*
+ variables.
+
+2006-07-29 Roland Clobus <rclobus at bigfoot.com>
+ * editor/gtk/editor.c: Added keyboard shortcuts to the editor
+ * client/common/client.c: Allow a player to initiate trade when he has
+ no resources
+
+2006-07-27 Bas Wijnen <shevek at fmf.nl>
+ * editor/gtk/editor.c, common/gtk/theme.c, common/gtk/select-game.c,
+ common/game.c, common/map.c, common/game.h, common/state.c,
+ common/log.c, common/map.h, common/state.h, common/network.c,
+ meta-server/main.c, server/player.c, server/pregame.c,
+ client/gtk/callbacks.c, client/gtk/player.c,
+ client/gtk/settingscreen.c, client/gtk/state.c, client/gtk/gui.c,
+ client/gtk/connect.c, client/common/develop.c, client/common/robber.c,
+ client/common/client.c, client/common/client.h,
+ client/common/resource.c, client/common/player.c, client/ai/ai.c: Use
+ dynamic instead of static memory to allow arbitrary large strings in
+ most situations. Still use static strings for network traffic, to
+ avoid denial of service opportunities.
+ * server/gtk/main.c: Show all authors.
+
+2006-07-27 Bas Wijnen <shevek at fmf.nl>
+ * macros/Makefile.am, editor/gtk/Makefile.am,
+ editor/gtk/pioneers-editor.rc, editor/Makefile.am, docs/Makefile.am,
+ common/gtk/aboutbox.c, common/gtk/Makefile.am, common/Makefile.am,
+ meta-server/Makefile.am, configure.ac, server/gtk/Makefile.am,
+ server/pregame.c, server/Makefile.am, Makefile.am, autogen.sh,
+ client/gtk/pioneers.rc, client/gtk/data/themes/Tiny/Makefile.am,
+ client/gtk/data/themes/Iceland/Makefile.am,
+ client/gtk/data/themes/FreeCIV-like/Makefile.am,
+ client/gtk/data/themes/Wesnoth-like/Makefile.am,
+ client/gtk/data/themes/Makefile.am, client/gtk/data/Makefile.am,
+ client/gtk/offline.c, client/gtk/Makefile.am,
+ client/common/Makefile.am, client/help/Makefile.am,
+ client/ai/Makefile.am, client/Makefile.am: Move to a single-Makefile
+ system.
+ * server/pregame.c: Remove unused static variable.
+
+2006-07-25 Roland Clobus <rclobus at bigfoot.com>
+ * server/lobby.game: New, non-empty map
+ * server/main.c: create a listening admin socket only when requested
+ from the command line
+ * client/gtk/player.c, client/gtk/gui.c, client/gtk/gui.h: Announce
+ new players and viewers when they enter
+
+2006-07-05 Roland Clobus <rclobus at bigfoot.com>
+ * editor/gtk/editor.c, common/gtk/theme.c, common/gtk/config-gnome.c,
+ common/game.c, common/state.c, common/network.c, server/gtk/main.c,
+ client/gtk/offline.c, client/gtk/gui.c, client/common/client.c,
+ client/common/player.c: Removed translation tags in g_error and
+ g_warning
+ * docs/README.release: Update steps for a release
+ * server/lobby.game: Added an empty map, for the lobby
+ * editor/gtk/editor.c, common/gtk/config-gnome.c, configure.ac,
+ server/gtk/main.c, client/gtk/offline.c, client/gtk/gui.c,
+ client/ai/ai.c: Removed Glib 2.6 #ifdef code
+
+2006-06-23 Roland Clobus <rclobus at bigfoot.com>
+ * getVersions.sh: View the versions in the various distributions
+
+2006-06-06 Roland Clobus <rclobus at bigfoot.com>
+ * Released version 0.9.64
+ * Subversion commit date: 2006-06-19
+
+2006-06-06 Roland Clobus <rclobus at bigfoot.com>
+ * server/main.c: Allow games with more than 3 victory points, when
+ started from the commandline
+ * server/trade.c: Restored to 0.9.52 version
+ * Subversion commit date: 2006-06-19
+
+2006-05-30 Roland Clobus <rclobus at bigfoot.com>
+ * Released version 0.9.63
+
+2006-05-30 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, client/gtk/quote.c, client/gtk/offline.c,
+ client/common/client.h, client/common/callback.c: Minimum requirement
+ is Glib 2.6 and Gtk+ 2.6. Remove use of Gtk+ 2.8 icon. Fixed compiler
+ warnings
+
+2006-05-28 Roland Clobus <rclobus at bigfoot.com>
+ * Released version 0.9.62
+
+2006-05-28 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/interface.c, client/gtk/frontend.h, client/gtk/player.c,
+ client/gtk/quote.c, client/gtk/trade.c, client/gtk/quote-view.c,
+ client/gtk/quote-view.h: Rewrite of quote.c
+ * server/trade.c: Throw away the quotes before ending the trade
+
+2006-05-28 Bas Wijnen <shevek at fmf.nl>
+ * client/callback.h, client/gtk/name.c, client/gtk/frontend.h,
+ client/gtk/offline.c, client/gtk/connect.c, client/common/client.c,
+ client/common/client.h, client/common/callback.c,
+ client/common/player.c, client/ai/ai.c: Separate requested name and
+ viewerness from actual values during the game, add commandline-option
+ to select meta-server in gtk client.
+
+2006-05-27 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/gui.c: Moved legend, game settings and dice histgram from
+ help to game menu.
+ * client/gtk/offline.c, client/gtk/gui.c: Fixed the help. When an
+ error occurs, show it in the chat log.
+
+2006-05-26 Bas Wijnen <shevek at fmf.nl>
+ * common/network.c: Write logged escaped bytes as bytes, now words.
+ * common/gtk/theme.c: Allow scaling scalable themes to 0.
+
+2006-05-26 Roland CLobus <rclobus at bigfoot.com>
+ * editor/gtk/editor.c, server/gtk/main.c, server/main.c,
+ client/gtk/offline.c, client/ai/ai.c: Quit when unknown commandline
+ options are passed
+ * client/help/C/pioneers.xml: Describe all chat commands
+
+2006-05-25 Bas Wijnen <shevek at fmf.nl>
+ * common/state.c, common/state.h, server/player.c: Make server handle
+ broken pipe correctly.
+
+2006-05-25 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/common_gtk.c, common/log.c, common/log.h,
+ client/common/chat.c:
+ Better layout for the log to the console
+
+2006-05-24 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Nicer feedback when something is not built
+
+2006-05-23 Roland Clobus <rclobus at bigfoot.com>
+ * editor/gtk/editor.c, server/gtk/main.c, server/main.c,
+ client/gtk/offline.c: Updates comments for translators
+ * client/common/client.c: Removed g_warning() text from translations
+
+2006-05-21 Giancarlo Capella <giancarlo at comm.cc>
+ * client/gtk/frontend.h, client/gtk/resource.c,
+ client/gtk/data/grain.png, client/gtk/data/wool.png,
+ client/gtk/data/ore.png, client/gtk/data/Makefile.am,
+ client/gtk/data/lumber.png, client/gtk/data/brick.png,
+ client/gtk/legend.c, client/gtk/gui.c, client/gtk/gui.h: Visual display
+ of the resources in the resources panel and the legend
+
+2006-05-20 Roland Clobus <rclobus at bigfoot.com>
+ * common/quoteinfo.c, common/game.c, common/quoteinfo.h,
+ client/callback.h, client/gtk/interface.c, client/gtk/plenty.c,
+ client/gtk/frontend.h, client/gtk/gold.c, client/gtk/quote.c,
+ client/gtk/legend.c, client/gtk/trade.c, client/gtk/discard.c,
+ client/gtk/chat.c, client/common/client.c, client/common/client.h,
+ client/common/resource.c, client/common/callback.c,
+ client/common/player.c: Added const for resources
+ * client/gtk/Makefile.am: Added quote-view.c and quote-view.h
+ * client/gtk/trade.c, client/gtk/quote-view.c, client/gtk/quote-view.h:
+ Moved code from trade.c to quote-view.c and replaced frames
+ * client/gtk/player.c, client/gtk/discard.c: More descriptive asserts
+ * client/gtk/resource-table.c, client/gtk/resource-table.h:
+ New functions added for trade and quote
+ * meta-server/main.c, client/gtk/gui.c: Signed->unsigned cleanup
+
+2006-05-17 Bas Wijnen <shevek at fmf.nl>
+ * client/ai/greedy.c: Fix for AI segfault.
+ * client/gtk/interface.c: Allow reuse of client after winning by
+ playing a soldier.
+
+2006-05-14 Bas Wijnen <shevek at fmf.nl>
+ * server/pregame.c, client/common/client.c: Fix reconnect procedure,
+ add RSETUP state command.
+
+2006-05-13 Roland Clobus <rclobus at bigfoot.com>
+ * client/help/C/custom.xsl, client/help/C/pioneers.xml,
+ client/help/C/Makefile.am: Manual updates. Manual conversion to html
+ and htmlhelp added.
+
+2006-05-09 Bas Wijnen <shevek at fmf.nl>
+ * docs/pioneers-meta-server.6: Updated.
+
+2006-05-02 Bas Wijnen <shevek at fmf.nl>
+ * client/gtk/interface.c, client/gtk/plenty.c, client/gtk/frontend.h:
+ Disable Ok button in Year of Plenty dialog when too few resources are
+ selected.
+ * server/pregame.c, client/callback.h, client/gtk/name.c,
+ client/gtk/frontend.h, client/gtk/offline.c, client/gtk/connect.c,
+ client/gtk/identity.c, client/common/client.c, client/common/client.h,
+ client/common/callback.c, client/ai/ai.c: Allow players to connect as
+ viewer.
+
+2006-04-30 Roland Clobus <rclobus at bigfoot.com>
+ * editor/gtk/editor.c, server/gtk/main.c, server/main.c, po/POTFILES.in,
+ client/gtk/offline.c, client/ai/ai.c: Use GOptionContext for command
+ line parsing
+ * editor/gtk/editor.c: Make the last loaded/saved game persistent
+
+2006-04-25 Roland Clobus <rclobus at bigfoot.com>
+ * README.Cygwin: Updated for Subversion
+ * client/gtk/gui.c: Message window as editable
+
+2006-04-23 Roland Clobus <rclobus at bigfoot.com>
+ * docs/README.release: Added a small guide for the steps needed to
+ make a release
+
+2006-04-21 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/common_gtk.h, common/gtk/common_gtk.c,
+ client/gtk/callbacks.c, client/gtk/frontend.h, client/gtk/player.c,
+ client/gtk/trade.c, client/gtk/chat.c: Easier /beep
+ * client/gtk/player.c: Make disconnected icon symmetrical.
+
+2006-04-18 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/guimap.c, common/gtk/common_gtk.c, common/cost.c,
+ common/game.c, common/map.c, server/gtk/main.c, server/meta.c,
+ server/server.c, client/gtk/interface.c, client/gtk/resource-table.c,
+ client/gtk/frontend.c, client/gtk/name.c, client/gtk/gold.c,
+ client/gtk/resource.c, client/gtk/player.c, client/gtk/develop.c,
+ client/gtk/legend.c, client/gtk/discard.c, client/gtk/offline.c,
+ client/gtk/gui.c, client/gtk/identity.c, client/gtk/histogram.c,
+ client/common/develop.c, client/common/build.c, client/common/setup.c,
+ client/common/client.c, client/common/stock.c, client/common/resource.c,
+ client/common/turn.c, client/common/player.c, client/common/callback.c:
+ Remove old-style function definition warnings.
+
+2006-04-14 Roland CLobus <rclobus at bigfoot.com>
+ * common/network.c: Add the time to the logged network traffic.
+
+2006-04-09 Roland Clobus <rclobus at bigfoot.com>
+ * Released version 0.9.61
+
+2006-04-09 Bas Wijnen <shevek at fmf.nl>
+ * client/callback.h, client/gtk/plenty.c, client/gtk/monopoly.c,
+ client/common/client.c: If somehow the dialog was closed, show it again
+
+2006-04-09 Roland Clobus <rclobus at bigfoot.com>
+ * client/help/C/pioneers.xml, client/help/C/images/discards.png,
+ client/help/C/images/place-robber.png, client/help/C/images/quote.png,
+ client/help/C/images/trade.png, client/help/C/images/messages.png,
+ client/help/C/images/plenty-dialog.png,
+ client/help/C/images/monopoly-dialog.png,
+ client/help/C/images/steal-from.png, client/help/C/images/map.png,
+ client/help/C/images/chat.png,
+ client/help/C/images/player-summary.png,
+ client/help/C/images/identity.png, client/help/C/images/actions.png,
+ client/help/C/images/gameover-dialog.png,
+ client/help/C/images/join-private-dialog.png,
+ client/help/C/images/discard-dialog.png,
+ client/help/C/images/resources.png, client/help/C/images/client.png,
+ client/help/C/images/status.png,
+ client/help/C/images/servers-dialog.png,
+ client/help/C/images/connect-dialog.png,
+ client/help/C/images/develop-cards.png
+ client/help/C/images/legend-dialog.png: Updated screenshots for 0.9.61
+ * docs/pioneers.6, docs/pioneers-server-console.6,
+ docs/pioneers-server-gtk.6: Updated the man pages
+ * common/gtk/config-gnome.c: Fixed the regression of 0.9.23
+ * server/admin.c: Fixed the assert when a connection is made to the
+ admin interface
+
+2006-04-08 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/gui.c: Disable the unused menu item 'Leave Game'
+
+2006-04-06 Bas Wijnen <shevek at fmf.nl>
+ * common/game.c: Remove compiler warnings.
+
+2006-04-03 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/guimap.c, common/gtk/guimap.h, client/gtk/interface.c,
+ client/gtk/gui.c, client/gtk/gui.h: Implemented 'single click build'
+ for the movement of ships. (Click anywhere to cancel)
+ * client/gtk/gui.c: Always show the map after a (re)connect.
+ * Makefile.am: let 'make restorepo' work with Subversion.
+ * configure.ac, Makefile.am, macros/Makefile.am: add the macros
+ subdirectory in the tarball (without the .svn directory)
+ * client/common/player.c: Remove compiler warnings
+
+2006-04-02 0.9.61 Bas Wijnen <shevek at fmf.nl>
+ * server/gtk/main.c: Split interface for running and non-running
+ state.
+ * client/common/develop.c: Disallow road building if there's no place
+ to build it.
+ * client/ai/greedy.c: Do a proper check for roadbuilding.
+
+2006-03-30 0.9.57 Roland Clobus <rclobus at bigfoot.com>
+ * client/help/C/pioneers.xml: Updated documentation. Corrected spelling
+ to en_us.
+ * client/callback.h, client/common/chat.c, client/common/client.h,
+ client/common/player.c: Fixed a crash in the client when a /beep is
+ sent when not all players are present yet.
+ * server/meta.c, server/server.c, server/server.h: Unregister from the
+ meta-server when the server stops.
+ * client/gtk/gui.c: Activate the map page when trade tabs have been
+ shown. Also hide the legend tab page after a connect (when turned off
+ in the preferences).
+
+2006-03-30 Samual Wright <sam at lykoszine.co.uk>
+ * client/help/C/pioneers.xml: Fixed a typo
+
+2006-03-30 Repository converted from cvs to svn
+
+2006-03-14 0.9.56 Roland Clobus <rclobus at bigfoot.com>
+ * server/pregame.c: Show disconnected players when reconnecting
+
+2006-02-09 0.9.55 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, meta-server/README.protocol: New version for the meta
+ server
+ * meta-server/main.c: Partly reverse the patch for 0.9.54, disable the
+ 'create' command globally, instead of per connection.
+
+2006-02-08 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/data/.cvsignore, editor/gtk/.cvsignore: Ignore icons
+
+2006-02-07 0.9.54 Roland Clobus <rclobus at bigfoot.com>
+ * pioneers.nsi.in: Added Swedish translation to installer.
+ * client/gtk/connect.c, client/gtk/gui.c, editor/gtk/editor.c,
+ server/server.c, server/gtk/main.c: Initialize GError * to NULL
+ * meta-server/main.c: Fixes crashes in the metaserver that did allow
+ the creation of new servers even when the metaserver does not support
+ it.
+ * common/gtk/guimap.c (calc_edge_poly): Apply gravity to ships and
+ bridges.
+
+2006-02-04 0.9.53 Roland Clobus <rclobus at bigfoot.com>
+ * server/main.c, server/player.c, server/server.c, server/server.h,
+ server/turn.c, server/gtk/main.c: Fixed memory leaks, at game over the
+ GTK server will enable its interface when all players have left.
+ * server/trade.c: Fixed a memory leak (based on a patch by Bas Wijnen
+ <shevek at fmf.nl>)
+ * common/gtk/guimap.c (guimap_cursor_move): Implemented single click
+ build for ship/bridge situations
+ * README.Cygwin, configure.ac, client/gtk/data/Makefile.am,
+ editor/gtk/Makefile.am: The icons for Microsoft Windows executables
+ are generated using netpbm.
+ * client/gtk/data/pioneers.ico, editor/gtk/pioneers-editor.ico:
+ Removed, they are now generated from the corresponding SVG files.
+
+2006-02-02 0.9.52 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/callbacks.c (frontend_new_bank): Removed compiler warning.
+ * autogen.sh: Require automake1.7 as minimum version.
+
+2006-01-27 0.9.51 Stefan Walter <sw at gegenunendlich.de>
+ * client/gtk/settingscreen.c: Patch for gcc-2.95
+
+2006-01-26 0.9.50 Brian Wellington <bwelling at xbill.org>
+ * pioneers.spec.in: Added Swedish translation
+
+2006-01-25 0.9.49 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/frontend.c, common/gtk/gtkbugs.c, common/gtk/gtkbugs.h:
+ For Gtk+-2.6, don't disconnect the shortcut keys when the action is set
+ to insensitive.
+ * pioneers.nsi.in: Added Wesnoth-like theme
+ * NEWS, README.Cygwin: Updated for the release
+
+2006-01-22 0.9.48 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Scrollkeeper only built when present, and when libgnome
+ is present. Protect script variables with ""
+ * configure.ac: Added AC_CONFIG_AUX_DIR
+ * pioneers.nsi.in: Check the presence of the Gtk+ runtime before
+ installing.
+
+2006-01-17 0.9.47 Bas Wijnen <shevek at fmf.nl>
+ * (Almost) all files: Change FSF postal address, change my e-mail
+ address, fixed copyright statements.
+ * server/server.h, server/player.c (player_by_name): Make
+ player_by_name a static function.
+
+2006-01-15 0.9.46 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/chat.c, client/gtk/chat.c, client/gtk/connect.c,
+ client/gtk/name.c, common/game.h, server/player.c, server/server.h:
+ Limit the maximum length for the chat and player name.
+
+2006-01-13 0.9.45 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Added Swedish translation, fixed locale dir
+ * debian/control, debian/pioneers-client.install,
+ debian/pioneers-client.menu, debian/pioneers-server-gtk.install,
+ debian/pioneers-server-gtk.menu, debian/rules: Updated Debian files
+ * debian/copyright: Updated download URL
+
+2006-01-03 0.9.44 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, client/gtk/data/Makefile.am, editor/gtk/Makefile.am,
+ server/gtk/Makefile.am: The svg renderer is called with width and
+ height.
+ * client/gtk/Makefile.am: Reverted Fink patch of 0.9.40
+ * editor/gtk/Makefile.am: Patch for Fink
+
+2006-01-02 0.9.43 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Build online help only when both libgnome and
+ scrollkeeper are present.
+ * macros/gnome-autogen.sh: Added bootstrap script from gnome-common
+ 2.12.0-1
+ * macros/ChangeLog, macros/Makefile.am, macros/aclocal-include.m4,
+ macros/autogen.sh, macros/compiler-flags.m4, macros/curses.m4,
+ macros/gnome-bonobo-check.m4, macros/gnome-common.m4,
+ macroos/gnome-cxx-check.m4, macros/gnome-fileutils.m4,
+ macros/gnome-gettext.m4, macros/gnome-ghttp-check.m4,
+ macros/gnome-gnorba-check.m4, macros/gnome-guile-checks.m4,
+ macros/gnome-libgtop-check.m4, macros/gnome-objc-checks.m4,
+ macros/gnome-orbit-check.m4, macros/gnome-print-check.m4,
+ macros/gnome-pthread-check.m4, macros/gnome-support.m4,
+ macros/gnome-undelfs.m4, macros/gnome-vfs.m4,
+ macros/gnome-x-checks.m4, macros/gnome-xml-check.m4, macros/gnome.m4,
+ macros/linger.m4, macros/macros.dep, macros/need-declaration.m4,
+ macros/.cvsignore:
+ Remove the old GNOME1 macros.
+ * autogen.sh: Use the gnome-autogen.sh from the macros directory if
+ gnome-common not installed.
+ * client/gtk/data/gnome-pioneers.png: Removed, is replaced by
+ pioneers.png
+
+2006-01-01 0.9.42 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/callbacks.c, client/gtk/frontend.h, client/gtk/gui.c,
+ client/gtk/gui.h, client/gtk/histogram.c, client/gtk/histogram.h,
+ client/gtk/legend.c, client/gtk/offline.c, client/gtk/settingscreen.c,
+ client/gtk/trade.c, common/gtk/theme.c, common/gtk/theme.h: Update all
+ images when the theme changes. Update the rules in the legend when a
+ new game is started.
+
+2005-12-30 Brian Wellington <bwelling at xbill.org>
+ * Add theme based on Battle of Wesnoth artwork (patch from Phil Ezolt).
+
+2005-12-30 0.9.41 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/config-gnome.c (config_get_string, config_get_int):
+ Set the default_used flag in all code paths.
+
+2005-12-29 Stephen Jacob <sj at sjacob.org>
+ * pioneers.spec.in: Added the new icons and desktop files
+
+2005-12-25 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/guic, common/network.c, common/state.c, common/state.h,
+ common/gtk/config-gnome.c, editor/gtk/editor.c, server/player.c,
+ server/pregame.c, server/gtk/main.c: make reindent
+
+2005-12-21 0.9.40 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, pioneers.nsi.in: Windows installer script.
+ (nsis.sf.net)
+ * client/gtk/Makefile.am, meta-server/Makefile.am: Added extra include
+ for driver.o (needed for Fink port, based on the patch by Tristan
+ Thiede)
+ * configure.ac, client/gtk/data/Makefile.am, editor/gtk/Makefile.am,
+ server/gtk/Makefile.am: Configurable SVG renderer.
+ * .cvsignore: Ignore pioneers.nsi.
+ * client/gt/data/pioneers.ico: Updated to match the icons of 0.9.38.
+ * editor/gtk/Makefile.am, editor/gtk/pioneers-editor.ico,
+ editor/gtk/pioneers-editor.rc: Windows icon for the editor.
+ * NEWS: Updated for the release
+
+2005-12-18 0.9.39 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/callback.c, client/gtk/interface.c: Fixed a crash when
+ a robber could be placed in a game with more than six players.
+ * common/network.h, common/state.c, common/state.h, server/player.c,
+ server/pregame.c, server/server.h: Allow many connections to the
+ server at once.
+
+2005-12-11 0.9.38 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/Makefile.am, client/gtk/gui.c,
+ client/gtk/data/Makefile.am, client/gtk/data/pioneers.desktop,
+ editor/gtk/Makefile.am, editor/gtk/editor.c,
+ editor/gtk/pioneers-editor.desktop, server/gtk/Makefile.am,
+ server/gtk/main.c, server/gtk/pioneer-server.desktop: Use the new
+ icons (automatically rendered from the svg files from 0.9.37)
+ * client/gtk/data/.cvsignore, editor/gtk/.cvsignore,
+ server/gtk/.cvsignore: Ignore the generated .png files
+
+2005-12-05 0.9.37 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/data/pioneers.svg, editor/gtk/pioneers-editor.svg,
+ server/gtk/pioneers-server.svg: Added icon files.
+
+2005-11-23 0.9.36 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: No console window for graphical applications in MinGW
+ port.
+
+2005-11-15 0.9.35 Roland Clobus <rclobus at bigfoot.com> [Windows native port]
+ * rules.make: Removed, functionality moved to configure.ac
+ * client/gtk/pioneers.rc, client/gtk/data/pioneers.ico: Windows icon.
+ * Makefile.am, configure.ac, client/Makefile.am,
+ client/ai/Makefile.am, client/common/Makefile.am,
+ client/gtk/Makfile.am, client/gtk/data/Makefile.am,
+ client/gtk/data/themes/Makefile.am,
+ client/gtk/data/themes/FreeCIV-like/Makefile.am,
+ client/gtk/data/themes/Iceland/Makefile.am,
+ client/gtk/data/themes/Tiny/Makefile.am, client/help/Makefile.am,
+ client/help/C/Makefile.am, common/Makefile.am, common/gtk/Makefile.am,
+ docs/Makefile.am, editor/Makefile.am, editor/gtk/Makefile.am,
+ meta-server/Makefile.am, server/Makefile.am, server/gtk/Makefile.am:
+ Stop using rules.make, all is managed from configure.ac
+ * client/gtk/gui.c: Don't use gtk_icon_source_set_filename anymore, it
+ does not allow relative paths, as needed for Windows and klik.
+ * configure.ac: Use pio-develop at lists.sourceforge.net as contact email
+ address.
+
+2005-11-14 Brian Wellington <bwelling at xbill.org>
+ * editor/gtk/editor.c: After a 'save as', remember the filename.
+
+2005-11-09 Brian Wellington <bwelling at xbill.org>
+ * editor/gtk/editor.c: File|New resets/redraws the map. Use the 'Save
+ as' icon. Don't show the robber in the editor.
+
+2005-10-23 0.9.34 Bas Wijnen <shevek at fmf.nl>
+ * client/common/callback.c: Removed some debug text.
+
+2005-10-23 Roland Clobus <rclobus at bigfoot.com>
+ * Makefile.am, configure.ac: Whether the client, server, meta-server
+ or editor are built is controlled from the configure script.
+ * Makefile.am, README.MinGW: Added README.Cygwin and README.MinGW to
+ the distributed tarball.
+ * configure.ac, client/common/i18n.c, common/network.c,
+ common/network.h: The code can be configured and built from the MinGW
+ environment. Use send and recv instead of write and read.
+
+2005-10-02 0.9.33 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Enable debug, enable deprecation-check and enable
+ logging were always active.
+
+2005-10-02 0.9.32 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, client/gtk/offline.c, common/gtk/config-gnome.c,
+ common/gtk/config-gnome.h, editor/gtk/editor.c, server/gtk/main.c:
+ Added optional support for GLib-2.6 (g_key_file). For environments that
+ cannot build the help, libgnome is no longer a build requirement.
+ * client/callback.h, client/ai/greedy.c, client/common/setup.c,
+ client/gtk/interface.c, common/map.h, common/map_query.c,
+ common/gtk/guimap.h, server/robber.c: Replaced all casts to
+ CheckFunc by functions with the correct prototype. This allows player
+ of the PPC to play Pioneers again. Cleanup of unused arguments in the
+ used functions.
+ * configure.ac, common/network.c, meta-server/main.c: Replace the last
+ uses of strerror by g_strerror.
+
+2005-10-02 Bas Wijnen <shevek at fmf.nl>
+ * client/ai/greedy.c: Do not trade if the wanted resource is not in
+ the bank. (Fixes Debian bug #328880)
+
+2005-09-25 0.9.31 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, rules.make, client/ai/Makefile.am,
+ client/common/Makefile.am, client/gtk/Makefile.am, common/Makefile.am,
+ common/gtk/Makefile.am, editor/gtk/Makefile.am,
+ meta-server/Makefile.am, server/Makefile.am, server/gtk/Makefile.am:
+ Moved $(debug_includes) from rules.make to configure.ac. There are now
+ four new commandline options to ./configure. All four are per default
+ enabled when --enable-maintainer-mode is given. The four are:
+ --enable-warnings, --enable-debug, --enable-logging,
+ --enable-deprecation-checks. This patch is based on a patch by Bas
+ Wijnen.
+
+2005-09-17 0.9.30 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/quote.c, common/gtk/config-gnome.c: Removed the
+ definition of *_DISABLED_DEPRECATED to make the source build again
+
+2005-09-17 Roland Clobus <rclobus at bigfoot.com>
+ * README.Cygwin: Added gettext-devel as required package
+
+2005-09-16 0.9.29 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/gui.c: Add #ifdef HAVE_HELP around static declaration
+ * configure.ac, client/ai/Makefile.am, client/common/Makefile.am,
+ common/Makefile.am, meta-server/Makefile.am, server/Makefile.am: Use
+ GLib includes in Makefile.am where needed
+
+2005-09-14 0.9.28 Bas Wijnen <shevek at fmf.nl>
+
+ * client/gtk/frontend.c: Apply workaround for Gtk bug to action
+ buttons.
+
+2005-09-14 0.9.27 Bas Wijnen <shevek at fmf.nl>
+
+ * editor/gtk/editor.c: Warn instead of crash when clearing nonexistant
+ hex. Set minimum map size to 1, not 2. Set sensitivity of correct
+ buttons when resize limits are hit. Let ports disappear correctly.
+ * client/gtk/gold.c, client/gtk/discard.c: Reindented.
+
+2005-09-13 0.9.26 Roland Clobus <rclobus at bigfoot.com>, based on the patch by
+ Ferenc Bánhidi <banhidi at inf.elte.hu>
+ * configure.ac, client/gtk/gui.c, editor/gtk/editor.c: Disable online
+ help if it cannot be built
+ * client/ai/ai.c (ai_start_game), client/common/i18n.c (change_nls),
+ client/gtk/connect.c (meta_create_notify): Use glib functions
+ * client/common/main.c (run_main), common/network.c, common/network.h,
+ meta-server/main.c (main), server/main.c (main) serverk/gtk/main.c
+ (main): Use new functions net_init and net_cleanup, as preparation for
+ the Windows native port
+
+2005-09-13 Bas Wijnen <shevek at fmf.rug.nl>
+ * client/callback.h, client/ai/greedy.c, client/common/client.c,
+ client/gtk/frontend.h, client/gtk/interface.c, client/gtk/plenty.c,
+ client/gtk/resource-table.c, client/gtk/resource-table.h: Made
+ function prototype with const bank
+ * client/gtk/discard.c, client/gtk/gold.c: If somehow the dialog was
+ closed, show it again
+
+2005-09-13 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/gtkbugs.c, common/gtk/gtkbugs.h, common/gtk/Makefile.am,
+ client/gtk/discard.c, client/gtk/gold.c, client/gtk/player.c: Moved
+ fix for bug in Gtk-2.6 to gtkbugs.c
+
+2005-09-09 0.9.25 Ferenc Bánhidi <banhidi at inf.elte.hu>
+ * configure.ac, client/common/i18n.c, po/hu.po: Added Hungarian
+ translation
+
+2005-09-09 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/client.c (mode_build_response): Remove debug code
+
+2005-09-01 0.9.24 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/connect.c (meta_dlg_cb), client/gtk/frontend.c
+ (gui_free), common/network.c (net_connect, net_free): Fixed memory
+ leaks
+
+2005-08-17 0.9.23 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/frontend.c (set_sensitive): Disable the hotkeys when the
+ GtkAction is disabled
+
+2005-08-14 0.9.22 Roland Clobus <rclobus at bigfoot.com.
+ * editor/gtk/editor.c: Use GPOINTER_TO_INT instead of (gint) cast
+ * client/gtk/interface.c: Fixed build cursor is shown for wrong player
+ * client/common/client.c (setup_msg): Removed extra comma in setup
+ message
+ * client/gtk/settingscreen.c: Replaced the GtkFrame with GNOME style
+ labels and indentation
+ * client/common/resource.c (resource_format_type): Added support for
+ showing numbers
+ * client/gtk/legend.c: Replaced the GtkFrame with GNOME style labels
+ and indentation, and use cost_* functions
+ * client/callback.h, client/common/client.c, client/gtk/gui.c,
+ client/gtk/interface.c: Enable the left pane for messages: road
+ building, place the robber, move a ship
+
+2005-08-14 Bas Wijnen <shevek at fmf.nl>
+ * client/gtk/connect.c: Fixed buffer overrun
+ * client/gtk/gui.c: Fix for crash at startup with toolbar hidden
+
+2005-08-05 0.9.21 Stefan Walter <sw at gegenunendlich.de>
+ * meta-server/main.c: Added missing #includes for FreeBSD
+
+2005-08-01 0.9.20 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/player.c (player_build_summary): Add missing line in
+ summary for Gtk+-2.6
+ * common/gtk/aboutbox.c (aboutbox_display): Add close button to about
+ dialog
+
+2005-07-14 0.9.19 Roland Clobus <rclobus at bigfoot.com>
+ * README.cygwin: Added instructions for building from CVS.
+ * autogen.sh: Added automake-1.9
+ * configure.ac, client/gtk/Makefile.am, client/gtk/frontend.c,
+ client/gtk/frontend.h, client/gtk/gui.c, client/gtk/offline.c,
+ common/gtk/Makefile.am, editor/gtk/Makefile.am,
+ server/gtk/Makefile.am: use libgnome+gtk instead of libgnomeui
+ * Makefile.am: Renamed indent make target to reindent
+
+2005-07-09 0.9.18 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/guimap.c: Single click build: when a ship and road can be
+ built, a ship is chosen when the cursor is at sea, a road is chosen
+ when the cursor is over land.
+
+2005-07-07 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/gnocatan.c renamed to main.c
+ * meta-server/gnocatan-meta-server.c renamed to main.c
+ * server/server.c renamed to main.c
+ * server/gnocatan-server.c renamed to admin.c, contains only admin
+ code
+ * server/gnocatan-server.h renamed to admin.h, contains only admin
+ code
+ * server/gtk/gnocatan-server-gtk.c renamed to main.c
+ * server/server.c, server/server.h: moved server code from admin.c and
+ admin.h to these files
+ * client/common/Makefile.am, meta-server/Makefile.am, po/POTFILES.in,
+ server/Makefile.am, server/gtk/Makefile.am: use the renamed files
+ * pioneers.spec.in: Updated home page
+
+2005-07-03 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/guimap.c, editor/gtk/editor.c: Use the Q_() macro for the
+ short translatable strings
+
+2005-07-02 Roland Clobus <rclobus at bigfoot.com>
+ * client/help/C/pioneers.xml: Updated link to homepage
+ * client/common/client.c: fixed the hello string (protocol change)
+
+2005-06-29 Roland Clobus <rclobus at bigfoot.com>
+ * client/help/C/pioneers-C.omf, client/help/C/pioneers.xml:
+ updated help pages
+ * docs/pioneers-meta-server.6, docs/pioneers-server-console.6,
+ docs/pioneers-server-gtk.6, docs/pioneers.6, docs/pioneersai.6:
+ updated man pages
+ * client/gtk/offline: use Pioneers settings
+ * docs/README.states: fix use of "Gnocatan"
+ * client/gtk/gameover.c: Last translatable string with Gnocatan.
+ * README, README.Cygwin, client/ai/ai.c, common/network.c,
+ common/network.h, editor/gtk/editor.c, meta-server/README.protocol,
+ meta-server/gnocatan-meta-server.c, server/archipel_gold.game,
+ server/crane_island.game, server/gnocatan-server.c, server/pregame.c,
+ server/gtk/gnocatan-server-gtk.c: Use "Pioneers" in the README
+ files, renamed 'get_gnocatan_dir' to 'get_pioneers_dir', updated
+ protocol for the hello message, use settings for Pioneers.
+
+ * server/buildutil.c, server/develop.c, server/discard.c,
+ server/glib-driver.c, server/glib-driver.h, server/gnocatan-server.h,
+ server/gold.c, server/player.c, server/pregame.c, server/resource.c,
+ server/robber.c, server/server.h, server/trade.c, server/turn.c,
+ common/buildrec.c, common/buildrec.h, common/cards.c, common/cards.h,
+ common/common_glib.c, common/common_glib.h, common/cost.c,
+ common/cost.h, common/driver.c, common/driver.h, common/game.c,
+ common/game.h, common/log.c, common/log.h, common/map.c,
+ common/map.h, common/map_query.c, common/quoteinfo.c,
+ common/quoteinfo.h, common/state.c,
+ common/state.h, common/gtk/colors.c, common/gtk/colors.h,
+ common/gtk/common_gtk.c, common/gtk/common_gtk.h,
+ common/gtk/config-gnome.c, common/gtk/config-gnome.h,
+ common/gtk/game-settings.c, common/gtk/game-settings.h,
+ common/gtk/guimap.c, common/gtk/guimap.h, common/gtk/polygon.c,
+ common/gtk/polygon.h, common/gtk/select-game.c,
+ common/gtk/select-game.h, common/gtk/theme.c, common/gtk/theme.h,
+ client/gtk/admin-gtk.c, client/gtk/callbacks.c, client/gtk/chat.c,
+ client/gtk/develop.c, client/gtk/discard.c, client/gtk/frontend.c,
+ client/gtk/frontend.h, client/gtk/gameover.c, client/gtk/gold.c,
+ client/gtk/gui.h, client/gtk/histogram.c, client/gtk/histogram.h,
+ client/gtk/identity.c, client/gtk/interface.c, client/gtk/legend.c,
+ client/gtk/monopoly.c, client/gtk/name.c, client/gtk/player.c,
+ client/gtk/plenty.c, client/gtk/quote.c, client/gtk/resource-table.c,
+ client/gtk/resource-table.h, client/gtk/resource.c,
+ client/gtk/settingscreen.c, client/gtk/state.c, client/gtk/trade.c,
+ client/callback.h, client/ai/ai.h, client/ai/greedy.c,
+ client/common/build.c, client/common/callback.c,
+ client/common/chat.c, client/common/client.c, client/common/client.h,
+ client/common/develop.c, client/common/gnocatan.c,
+ client/common/i18n.c, client/common/player.c,
+ client/common/resource.c, client/common/robber.c,
+ client/common/setup.c, client/common/stock.c, client/common/turn.c:
+ fix uses of the name "Gnocatan" in the header comments
+
+2005-06-28 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/develop.c, client/gtk/player.c,
+ client/gtk/settingscreen.c, editor/gtk/game-devcards.c: change the
+ development card to 'Pioneer University'
+
+2005-06-26 Steve Langasek <vorlon at debian.org>
+ * client/gtk/connect.c, server/gtk/gnocatan-server-gtk.c:
+ Auto-migrate metaserver values from 'gnocatan.debian.net'
+ to 'pioneers.debian.net' (done in a pretty ugly, hard-coded
+ fashion, but this should be just a temporary hack)
+
+2005-06-26 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/data/splash.svg, client/gtk/data/splash.png: Set name to
+ Pioneers
+ * client/gtk/gui.c: Use the correct splash image
+
+2005-06-25 Steve Langasek <vorlon at debian.org>
+ * autogen.sh: tested with automake-1.8, so allow the package to
+ be built using that version
+ * macros/autogen.sh: fix broken references to configure.in
+ (should now be configure.ac).
+ * Makefile.am: drop the dist hook for debian/, it doesn't belong
+ in the tarball
+ * configure.ac, rules.make, client/Makefile.am,
+ client/ai/Makefile.am, client/common/Makefile.am,
+ client/gtk/Makefile.am, client/gtk/connect.c,
+ client/gtk/gui.c, client/gtk/data/Makefile.am,
+ client/gtk/data/themes/Makefile.am,
+ client/gtk/data/themes/FreeCIV-like/Makefile.am,
+ client/gtk/data/themes/Iceland/Makefile.am,
+ client/gtk/data/themes/Tiny/Makefile.am,
+ client/help/Makfile.am, client/help/C/Makefile.am,
+ common/Makefile.am, common/gtk/Makefile.am, editor/Makefile.am,
+ meta-server/gnocatan-meta-server.c, server/Makefile.am,
+ server/gnocatan-server-console.c, server/gnocatan-server.c,
+ server/gtk/Makefile.am, server/gtk/gnocatan-server-gtk.c: fix
+ uses of the name "Gnocatan" in the source
+ * configure.ac: change the PACKAGE name to "pioneers"
+ * configure.ac, client/help/C/gnocatan.xml,
+ meta-server/meta-report: change the default metaserver to
+ pioneers.debian.net
+ * client/ai/Makefile.am, client/common/Makefile.am,
+ client/gtk/Makefile.am, common/Makefile.am,
+ common/gtk/Makefile.am, editor/gtk/Makefile.am,
+ meta-server/Makefile.am, server/Makefile.am,
+ server/gtk/Makefile.am: change the names of the binaries being
+ built
+ * docs/Makefile.am, docs/pioneers.6, docs/pioneers-server-gtk.6,
+ docs/pioneers-server-console.6, docs/pioneersai.6,
+ docs/pioneers-meta-server.6: rename the manpages to match
+ * rules.make, server/gnocatan-server-console.c: fix up all
+ embedded paths to binaries to use the new names
+ * client/gtk/connect.c, client/gtk/gui.c, common/gtk/aboutbox.c,
+ editor/gtk/editor.c, meta-server/gnocatan-meta-server.c,
+ server/gtk/gnocatan-server-gtk.c: fix names embedded in the GUI
+ * client/gtk/data/gnocatan.desktop,
+ server/gtk/gnocatan-server.desktop: fix both the display names
+ and the paths to the binaries
+ * Makefile.am, configure.ac, pioneers.spec.in: fix up the RPM
+ packaging to match
+ * client/gtk/data/pioneers.desktop, client/help/C/pioneers-C.omf,
+ client/gtk/data/gnome-pioneers.png, client/help/C/pioneers.xml,
+ server/gtk/pioneers-server.desktop, server/gtk/Makefile.am,
+ client/gtk/data/Makefile.am, client/help/C/Makefile.am,
+ client/gtk/gui.c, server/gtk/gnocatan-server-gtk.c: fix the
+ names of installed data files
+ * rules.make, editor/gtk/Makefile.am, common/gtk/aboutbox.c,
+ client/ai/Makefile.am, client/gtk/Makefile.am,
+ client/gtk/data/Makefile.am, client/gtk/data/themes/Makefile.am,
+ client/gtk/data/themes/FreeCIV-like/Makefile.am,
+ client/gtk/data/themes/Iceland/Makefile.am,
+ client/gtk/data/themes/Tiny/Makefile.am, server/Makefile.am,
+ server/gtk/Makefile.am, common/gtk/Makefile.am: fix remaining
+ paths where data files are installed
+ * configure.ac, rules.make, client/ai/ai.c,
+ client/gtk/connect.c, client/gtk/gui.c, client/gtk/offline.c,
+ common/network.c, common/network.h,
+ meta-server/gnocatan-meta-server.c, meta-server/meta-report,
+ server/gnocatan-server-console.c, server/gnocatan-server.c,
+ server/meta.c, server/server.c, server/gtk/gnocatan-server-gtk.c:
+ fix up all variables in the source, including environmental
+ variables; support using old env variable names as fallbacks.
+
+2005-06-05 Brian Wellington <bwelling at xbill.org>
+ * common/game.c, common/game.h, common/map.c, common/map.h,
+ editor/gtk/editor.c: Remove the chits field in the GameParams
+ structure.
+
+2005-06-05 0.9.17 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Require GLib minimum version 2.4
+ * common/log.h: Use glib/gi18n.h
+
+2005-05-26 0.9.16 Roland Clobus <rclobus at bigfoot.com>
+ * common/game.c, common/game.h: Constness for params_copy.
+ * common/map.c (layout_chits), server/server.c (game_free),
+ server/gtk/gnocatan-server-gtk.c (build_game_settings): Fixed memory
+ leaks.
+ * common/gtk/guimap.c: Implemented the todo in the single click
+ building. The cursor will switch between node and edge, whichever is
+ closest.
+
+2005-05-25 Brian Wellington <bwelling at xbill.org>
+ * client/common/client.c, server/pregame.c: Send the number
+ of development cards that have been bought to connecting clients,
+ so that the client's state is correct after a reconnect.
+
+2005-05-22 Roland Clobus <rclobus at bigfoot.com>
+ * apply 'make indent' again
+
+2005-05-19 0.9.15 Roland Clobus <rclobus at bigfoot.com>
+ * nearly all: replaced numElems and UNUSED macros by the GLib macros
+ G_N_ELEMENTS and G_GNUC_UNUSED
+
+2005-05-17 0.9.14 Roland Clobus <rclobus at bigfoot.com>
+ * client/ai/greedy.c (resource_desire): Fixed a typo from 0.9.13
+
+2005-05-16 0.9.13 Roland Clobus <rclobus at bigfoot.com>
+ * client/ai/greedy.c (resource_desire): Don't consider resources that
+ have no value (fixes monopoly deadlock)
+
+2005-05-15 Brian Wellington <bwelling at xbill.org>
+ * client/ai/greedy.c: Rework the AI's maritime trading code to
+ reduce the number of pointless trades and increase the effectiveness
+ of trades.
+
+2005-05-15 0.9.12 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/common_gtk.c: Removed GTK compatibility code. It is not
+ needed since 2.4 is required.
+ * common/gtk/guimap.c: Moved comments back that were moved by a make
+ indent, such that the translators see them again.
+
+2005-05-01 0.9.11 Roland Clobus <rclobus at bigfoot.com>
+ * server/gtk/gnocatan-server-gtk.c (main): Enabled translations in the
+ menu.
+ * editor/gtk/editor.c: Use GINT_TO_POINTER and GPOINTER_TO_INT
+ * editor/gtk/editor.c, editor/gtk/game-buildings.c,
+ editor/gtk/game-devcards.c: Enabled some translations.
+ * client/gtk/settingsscreen.c: Fixed a string
+
+2005-04-24 Brian Wellington <bwelling at xbill.org>
+ * common/map.[ch]: Add map_add_hex().
+ * client/gtk/gui.c, common/gtk/guimap.[ch]: Move map widget and
+ event handling code to guimap.c
+
+2005-04-24 Brian Wellington <bwelling at xbill.org>
+ * common/gtk/guimap.[ch]: Add guimap_find_hex().
+
+2005-04-20 Brian Wellington <bwelling at xbill.org>
+ * client/ai/greedy.c: Fix a problem with the AI's monopoly card
+ support.
+ * client/gtk/guimap.[ch], client/gtk/Makefile.am,
+ common/gtk/guimap.[ch], common/gtk/Makefile.am: Move map display
+ code to common/gtk.
+
+2005-04-21 0.9.10 Roland Clobus <rclobus at bigfoot.com>
+ * client/callback.h, client/common/resource.c, common/buildrec.h,
+ common/cost.c, common/cost.h, server/resource.c, server/server.h: Add
+ const for function prototypes.
+ * client/ai/greedy.c: Use cost_* functions
+
+2005-04-20 Brian Wellington <bwelling at xbill.org>
+ * client/gtk/frontend.h, client/gtk/gui.c, client/gtk/guimap.c,
+ client/gtk/guimap.h, client/gtk/player.c, common/gtk/Makefile.am,
+ common/gtk/colors.c, common/gtk/colors.h: Move non-client-specific
+ code to common/gtk.
+
+2005-04-20 0.9.9 Roland Clobus <rclobus at bigfoot.com>
+ * rules.make, server/gnocatan-server-console.c: Add
+ G_DISABLE_DEPRECATED, and replace the old functions.
+ * server/gtk/gnocatan-server-gtk.c: Replace libgnomeui calls with
+ libgnome and Gtk+ calls.
+ * client/common/callback.c, client/gtk/gui.c, client/gtk/interface.c:
+ No direct build of a city in the client. First a settlement has to be
+ built.
+ * common/network.c, meta-server/gnocatan-meta-server.c: Added code
+ that will allow the tarball to be built under Cygwin. The client uses
+ IPv4 functions, the server will not create listening sockets, and the
+ metaserver will not create new games.
+
+2005-04-19 Brian Wellington <bwelling at xbill.org>
+ * configure.ac, Makefile.am, editor: Add gnocatan-editor.
+
+2005-04-18 Brian Wellington <bwelling at xbill.org>
+ * client/gtk/plenty.c: Remove duplicated and deprecated code
+ by using the resource table widget.
+ * server/gnocatan-server-console.c, server/player.c,
+ server/server.c, server/server.h, server/gtk/gnocatan-server-gtk.c:
+ Add the ability to disable AI chatting from gnocatan-server-gtk.
+ * client/gtk/polygon.[ch], client/gtk/theme.[ch],
+ client/gtk/Makefile.am, common/gtk/polygon.[ch],
+ common/gtk/theme.[ch], common/gtk/Makefile.am: Move theme and polygon
+ code from client/gtk to common/gtk.
+ * client/ai/greedy.c: The AI can now play monopoly cards.
+
+2005-04-17 Stephen Jacob <sj at sjacob.org>
+ * client/callback.h, client/ai/greedy.c, client/common/callback.c,
+ client/common/player.c, client/gtk/player.c: The AI now holds VP
+ dev cards until it has enough points to win.
+
+2005-04-14 Brian Wellington <bwelling at xbill.org>
+ * common/game.c, server/pregame.c: Make params_write_file() create a
+ valid game file.
+
+2004-04-14 0.9.8 Roland Clobus <rclobus at bigfoot.com>
+ * server/server.c (accept_connection): Used wrong file descriptor, bug
+ was introduced in 0.9.6
+ * common/game.c (params_copy), common/map.c (disconnect_hex),
+ server/square.game: Fixed the core dump which resulted in the
+ imcomplete file. Added some descriptions of the errors.
+ * client/ai/greedy.c (greedy_turn): Fix for bug introduced in 0.9.6.
+ * client/ai/greedy.c (trade_desired, greedy_consider_quote): Let the
+ AI accept free offers during trade.
+ * common/map.c (layout_chits): Use at most one robber per map.
+ * common/map.c (map_copy): Use robber and pirate hex from the copied
+ map, not the original map.
+ * configure.ac: Do not use Gtk+ for console-only applications.
+
+2005-04-09 0.9.7 Daniel <dgun at umpire.com>
+ * server/gnocatan-server.c: When duplicate game titles exist, a number
+ is added to the title.
+
+2005-04-09 Yusei <yusei at ragondux.com>
+ * crane_island.game: Added a new map
+
+2005-04-09 LT-P <LT-P at LT-P.net>
+ * iles.game, coeur.game: Added new maps
+ * Evil_square.game: Updated the map
+
+2005-04-09 Blyx <blyx at apshram.net>
+ * archipel_gold.game: Added a new map
+
+2005-04-06 Stephen Jacob <sj at sjacob.org>
+ * common/gtk/common-gtk.c: Change the text color of player 3's
+ messages, since light gray on white is really hard to read.
+
+2005-04-06 0.9.6 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, common/network.c, common/network.h,
+ meta-server/gnocatan-meta-server.c, server/gnocatan-server-console.c,
+ server/gnocatan-server.c, server/gnocatan-server.h, server/meta.c,
+ server/server.c, server/server.h, server/gtk/gnocatan-server-gtk.c:
+ Removed global variables for serverhostname and port. Moved duplicate
+ code of server and meta-server to common/network.c. All ports are now
+ strings (service names), there are no conversions to integers left.
+ Upgraded meta-server protocol to 1.2.
+ * rules.make, client/gtk/connect.c, client/gtk/plenty.c,
+ client/gtk/quote.c: Added GTK_DISABLE_DEPRECATED for developer-only
+ builds. Marked the files that still use deprecated calls.
+
+2005-04-03 Brian Wellington <bwelling at xbill.org>
+ * configure.ac, common/Makefile.am, common/map.[ch],
+ common/mt_rand.[ch], server/server.c: Remove the old random
+ number generator.
+
+2005-04-03 0.9.5 Roland Clobus <rclobus at bigfoot.com>
+ * client/ai/greedy.c: AI can use gold (and prefer it) during setup.
+ The nosetup nodes are honoured. Year of Plenty will only be played
+ when the bank has at least 2 resources left.
+
+2005-04-02 Brian Wellington <bwelling at xbill.org>
+ * client/gtk/gui.c, client/gtk/guimap.c, client/gtk/legend.c,
+ client/gtk/offline.c, client/gtk/theme.c, client/gtk/theme.h: Cleanups
+ to the theme code.
+ * client/gtk/connect.c, meta-server/gnocatan-meta-server.c,
+ server/server.c: Use g_spawn_async instead of open-coded fork()/exec().
+
+2005-04-02 0.9.4 Roland Clobus <rclobus at bigfoot.com>
+ * client/ai/greedy.c: When receiving gold, the AI must choose
+ something, even when it has enough resources.
+
+2005-03-31 Brian Wellington <bwelling at xbill.org>
+ * client/ai/ai.c: The AI should not stay in a game if it is full.
+
+2005-03-28 Brian Wellington <bwelling at xbill.org>
+ * client/gtk/connect.c, client/gtk/gui.c, client/gtk/theme.c,
+ client/gtk/theme.h, common/gtk/select-game.c,
+ common/gtk/select-game.h: Replace deprecated GtkOptionMenus
+ with GtkComboBoxes.
+
+2005-03-28 0.9.3 Roland Clobus <rclobus at bigfoot.com>
+ * Makefile.am: Added target 'restorepo', to make it easier to remove
+ the changes to the *.po files when make distcheck has been used, but
+ no new translations have been added.
+ * client/gtk/data/splash.svg, client/gtk/data/splash.png: Updated
+ splash screen image to version 0.9
+ * configure.ac: Require Gtk+-2.4. Added checks, which 'autoscan' did
+ recommend.
+
+2005-03-26 0.9.2 Roland Clobus <rclobus at bigfoot.com>
+ * client/callback.h, client/ai/greedy.c, client/common/client.c,
+ client/common/client.h, client/common/player.c,
+ client/common/resource.c, client/gtk/callbacks.c,
+ client/gtk/connect.c, client/gtk/gui.c, client/gtk/gui.h,
+ client/gtk/legend.c, client/gtk/settingscreen.c, client/gtk/trade.c,
+ common/log.c, common/log.h, common/gtk/common_gtk.c: Made several
+ gchar* arguments const gchar* argument.
+
+2005-03-24 Brian Wellington <bwelling at xbill.org>
+ * client/gtk/connect.c: Remove static buffers.
+
+2005-03-23 Brian Wellington <bwelling at xbill.org>
+ * client/ai/greedy.c: Add gold support to the AI.
+ * server/player.c: The patch to enable random seating ordered
+ caused gtk assertions when connecting to a full game.
+ * Makefile.am, configure.ac, client/ai/Makefile.am, ai/: Remove
+ the old AI; enable the new AI.
+
+2005-03-23 0.9.1 Roland Clobus <rclobus at bigfoot.com>
+ * New version numbering: only 3 digits. The first two match the
+ protocol version, and the third is the build number.
+ * client/gtk/frontend.h, client/gtk/offline.c, client/gtk/theme.h:
+ Moved declaration of init_themes to theme.h
+ * server/player.c: Version check to only two digits. Added message
+ when version does not match.
+ * client/common/client.c, common/game.c, common/game.h, common/map.c,
+ common/map.h, server/pregame.c: Small protocol change, to avoid
+ sending unused data. Added option to send secrets of the map.
+ * client/ai/ai.c: Code cleanup to random_name. Randomizer needs to be
+ initialized only once.
+ * po/POTFILES.in: Added client/ai/ai.c
+ * client/gtk/connect.c: Made metaserver redirects insensitive to
+ buffer overflows.
+
+2005-03-23 Bas Wijnen <shevek at fmf.nl>
+ * client/common/client.c, server/gold.c, server/pregame.c: Fixed race
+ condition for client after rolling dice.
+
+2005-03-22 Brian Wellington <bwelling at xbill.org>
+ * meta-server/gnocatan-meta-server.c: Removed compiler warnings when
+ compiling with -pedantic.
+
+2005-03-20 0.8.1.59 Roland Clobus <rclobus at bigfoot.com>
+ * common/game.c: The automatic indent did break the sending of
+ gameinfo.
+
+2005-03-20 0.8.1.58 Roland Clobus <rclobus at bigfoot.com>
+ * ALL: Applied 'make indent'
+
+2005-03-20 0.8.1.57 Roland Clobus <rclobus at bigfoot.com>
+ * server/gnocatan-server.c: Made random seating order the default.
+ * server/gtk/gnocatan-server-gtk.c: Made random order setting
+ persistent.
+ * Makefile.am: Added 'make indent' target.
+
+2005-03-16 Brian Wellington <bwelling at xbill.org>
+ * common/game.c, common/game.h, server/meta.c, server/player.c,
+ server/server.c, server/server.h: Move the register-server,
+ server-port, and random-order fields from the GameParams object to
+ the Game object.
+ * client/gtk/resource-table.c (resource_table_new): Removed the use of
+ a fixed-size buffer.
+
+2005-03-14 0.8.1.56 Brian Wellington <bwelling at xbill.org>
+ * common/gtk/aboutbox.c, common/gtk/aboutbox.h, common/gtk/Makefile.am,
+ client/gtk/gui.c, server/gtk/gnocatan-server-gtk.c: Add common code for
+ displaying about boxes; make the client and server use it.
+ * common/game.c, common/game.h, server/gnocatan-server.c: Add
+ params_load_file()/params_write_file() helper functions.
+ * common/game.h, server/gnocatan-server.c, server/gnocatan-server.h,
+ server/player.c, server/pregame.c, server/server.c, server/server.h,
+ server/gtk/gnocatan-server-gtk.c: Add the ability to randomize
+ seating order.
+ * client/gtk/guimap.c, client/gtk/guimap.h, client/gtk/gui.c,
+ client/gtk/gui.h, client/gtk/callbacks.c: When starting a new game,
+ clear the highlighted chits, pointed out by Arjan Schrijver.
+
+ Gnocatan is joined by a new developer: Brian Wellington
+
+2005-03-12 0.8.1.55 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac, added gnocatan.spec.in, removed gnocatan.spec: The
+ spec is automatically generated and uses the current version.
+ * ai/ai.c, client/ai/ai.c, client/gtk/connect.c, common/network.c,
+ common/network.h, meta-server/Makefile.am,
+ meta-server/gnocatan-meta-server.c, server/gnocatan-server-console.c,
+ server/gnocatan-server.c, server/gnocatan-server.h, server/meta.c,
+ server/server.c, server/server.h, server/gtk/gnocatan-server-gtk.c:
+ More consistent use of the environment variables GNOCATAN_DIR,
+ GNOCATAN_META_SERVER, GNOCATAN_SERVER_CONSOLE and
+ GNOCATAN_SERVER_NAME. Moved common code to common/network.c.
+ * docs/gnocatan-meta-server.6, docs/gnocatan-server-console.6,
+ docs/gnocatan-server-gtk.6, docs/gnocatan.6, docs/gnocatanai.6: Added
+ ENVIRONMENT section and FILES section. Added documentation of some new
+ commandline options.
+ * meta-server/gnocatan-meta-server.c (client_create_new_server): Use
+ -m and -n commandline options instead of the environment variable. The
+ server-console started from the meta-server will use the same hostname
+ as the meta-server.
+ * server/gnocatan-server-console.c (main): Correctly initialise
+ hostname.
+
+2005-03-12 Arjan Schrijver <arjan at anymore.nl>
+ * meta-server/gnocatan-meta-server.c: Added commandline options to
+ limit the portrange of the metaserver, and to set the hostname.
+
+2005-03-02 0.8.1.54 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/interface.c: Reversal of the patch in 0.8.1.48, because
+ it would set the client to the state turn when performing a maritime
+ trade. Added a reset of the have_turn flag when game over is reached.
+
+2005-03-02 Brian Wellington <bwelling at users.sourceforge.net>
+ * client/gtk/interface.c: Disable the reject button when the trade was
+ already rejected.
+
+2005-02-05 0.8.1.53 Roland Clobus <rclobus at bigfoot.com>
+ * server/gnocatan-server.c, meta-server/gnocatan-meta-server.c: Forgot
+ the NULL termination of g_build_filename, pointed out by Brian
+ Wellington.
+
+2005-02-05 Brian Wellington <bwelling at users.sourceforge.net>
+ * gnocatan.spec: Updated to version 0.8.1
+
+2005-02-03 0.8.1.52 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/gui.c, server/gtk/gnocatan-server-gtk.c: Fix for crash in
+ about dialog. Also reintroduces the version number.
+ * client/gtk/gui.c, client/gtk/guimap.c, client/gtk/guimap.h,
+ client/gtk/theme.c, client/gtk/theme.h,
+ server/gtk/gnocatan-server-gtk.c: Theme.c rewrite, using
+ g_build_filename instead of gnome_program_locate_file.
+ * client/gtk/trade.c: Fixed a memory leak.
+ * common/game.c, common/game.h, common/map.c,
+ server/gnocatan-server.c, server/gnocatan-server.h: Server will not
+ crash on invalid/unreadable games.
+ * configure.ac, rules.make,
+ client/gtk/connect.c, client/help/C/gnocatan.xml,
+ client/help/C/images/connect-dialog.png,
+ client/help/C/images/server-create.png,
+ client/help/C/images/server-create.png,
+ client/help/C/images/servers-dialog.png,
+ meta-server/gnocatan-meta-server.c: Meta server protocol updated to
+ 1.1. New keyword: capability. When 'create games' is sent, the
+ metaserver is capable of locally creating new game. Updated the
+ documentation to reflect the change.
+ * server/gtk/gnocatan-server-gtk.c(game_activate): Disabled the 'Add
+ Computer Player' button when gnocatanai is not installed.
+
+2005-01-25 0.8.1.51 Roland Clobus <rclobus at bigfoot.com>
+ * common/gtk/common_gtk.c: Added stub for gtk_alignment_set_padding,
+ allowing to code to build with Gtk+-2.0 and 2.2 again.
+ * client/gtk/gold.c(gold_choose_player_must): Replaced the last Gtk+
+ deprecated funcion call in this file.
+
+2005-01-25 Stefan Walter <sw at gegenunendlich.de>
+ * common/network.c, meta-server/gnocatan-meta-server.c,
+ server/server.c: Restored the include files needed for FreeBSD that
+ disappeared in 0.8.1.48
+
+2005-01-23 0.8.1.50 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/client.c: Removed unused variables from
+ recovery_info_t, does not show turn 0 anymore.
+ * common/map.c: Added default case
+ * common/state.c, common/state.h, server/gold.c, server/pregame.c,
+ server/server.h: Fixed reconnect during distribution of gold.
+ * client/common/client.c, client/common/client.h,
+ client/common/develop.c: Removed unused function road_building_begin.
+ * client/gtk/gold.c, client/gtk/resource-table.c,
+ client/gtk/resource-table.h: Replaced gtk_clist.
+ * server/player.c, server/pregame.c, server/server.h: Server crashed
+ when the player who is in the setup phase reconnected with another
+ name.
+
+2005-01-15 Roland Clobus <rclobus at bigfoot.com>
+ * INSTALL, .cvsignore: Removed INSTALL from CVS. It is generated
+ * README: Added information from the old INSTALL
+
+2005-01-15 0.8.1.49 Daniel <dgun at umpire.com>
+ * common/map.c, common/map.h: Patch #1100340: Added the option to mark
+ a tile such that it will never be shuffled, by adding a + (plus) after
+ the number in the .game file. All gold tiles will now be shuffled,
+ unless they are marked.
+ * server/henjes.game, server/seafarers-gold.game: Patch #1101870:
+ Marked all gold tiles such that they will not be shuffled, when random
+ map is turned on.
+
+2005-01-09 0.8.1.48 Roland Clobus <rcobus at bigfoot.com>
+ * common/buildrec.c, common/map.h, common/map_query.c: Bug #1094484:
+ Disallow the building of a road during setup phase when the settlement
+ cannot be built.
+ * common/network.c, meta-server/gnocatan-meta-server.c: Minimal system
+ include files.
+ * server/buildutil.c, server/develop.c, server/discard.c,
+ server/gold.c, server/meta.c, server/player.c, server/pregame.c,
+ server/resource.c, server/robber.c, server/server.c, server/trade.c,
+ server/turn.c: Minimal list of include files.
+ * client/gtk/interface.c: Bug #1027642, Bug #942472: Player did not
+ get a turn after the setup phase in a second game with the same
+ client.
+ * client/gtk/gui.c: Minor spelling change, to make text in about boxes
+ of client and server the same.
+
+2004-12-25 0.8.1.47 Etan Reisner <deryni at eden.rutgers.edu>
+ * server/gtk/gnocatan-server-gtk.c, client/gtk/gui.c: Replaced GNOME
+ about dialog with Gtk code.
+
+2004-12-25 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/discard.c, client/gtk/resource.c, client/common/client.c:
+ Removed usused variable
+ * server/player.c: Removed unused code.
+ * common/state.c, common/state.h: Added stack dump code.
+ * server/player.c: Added stack names when restoring the disconnect
+ player.
+
+2004-12-21 0.8.1.46 Roland Clobus <rclobus at bigfoot.com>
+ * configure.ac: Renamed configure.in to the more modern configure.ac
+ * autogen.sh: Changed configure.in to configure.ac
+
+2004-12-19 Etan Reisner <deryni at eden.rutgers.edu>
+ * ai/client.c, common/gtk/select-game.c,
+ meta-server/gnocatan-meta-server.c, server/gtk/gnocatan-server-gtk.c:
+ Using g_strdup instead of strdup
+ * client/common/callback.c, server/gnocatan-server-console.c: Removing
+ unused/duplicate #include lines
+
+004-12-03 0.8.1.45 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/resource-table.c, client/gtk/resource-table.h,
+ client/gtk/Makefile.am: Added a simple way to add a selection for
+ resources in the client.
+ * client/gtk/frontend.c: Reenabled the workaround for a Gtk+ bug.
+ * client/common/player.c: A leaving player is a normal message, not an
+ error message.
+ * client/common/client.c, client/gtk/interface.c, server/discard.c,
+ server/pregame.c, server/server.h: Fixed reconnect in state DISCARD
+ and YOUAREROBBER.
+ * client/gtk/discard.c: Using the new resource-table widget, and
+ removed deprecated gtk_clist.
+ * client/gtk/frontend.h, client/gtk/player.c: Made player_create_icon
+ accessible to other source files.
+ * client/gtk/gui.c(gui_set_game_params): Initially the map pixmap was
+ too small. (Debian bug #284063)
+
+2004-11-28 0.8.1.44 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/gui.h: Fix for the macro that would have bad side effects
+ when used in if statements
+ * client/common/client.c, server/pregame.c: Enable sending the bank by
+ the server
+ * client/gtk/gui.c(gui_highlight_chits),
+ client/gtk/guimap.c(guimap_highlight_chits): Enable highlighted chits
+ when reconnected.
+ * client/gtk/monopoly.c(monopoly_create_dlg): Only show one dialog
+ when reconnecting.
+ * client/common/client.c, client/gtk/guimap.c: Fix for crash when
+ reconnecting during RoadBuilding card that was played before a dice
+ roll.
+ * client/common/develop.c(develop_bought_turn): Development cards can
+ be played when reconnected.
+ * client/common/client.c, server/pregame.c: Dialog did not show when
+ reconnecting when a Year of Plenty card has been played.
+
+2004-11-21 0.8.1.43 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/offline.c(frontend_offline): Game|Connect incorrectly
+ available when client is started with a commandline with server and
+ port
+ * client/gtk/guimap.c(guimap_cursor_move): Crash when leaving the map
+ with a cursor active
+ * client/gtk/chat.c, client/gtk/develop.c, client/gtk/discard.c,
+ client/gtk/gold.c, client/gtk/gui.c, client/gtk/player.c,
+ client/gtk/resource.c: Main screen consistent again, now without
+ frames
+ * client/common/callback.c, client/gtk/connect.c,
+ client/gtk/develop.c, client/gtk/discard.c, client/gtk/frontend.c,
+ client/gtk/frontend.h, client/gtk/gameover.c, client/gtk/gold.c,
+ client/gtk/gui.c, client/gtk/gui.h, client/gtk/guimap.c,
+ client/gtk/guimap.h, client/gtk/histogram.c, client/gtk/identity.c,
+ client/gtk/legend.c, client/gtk/monopoly.c, client/gtk/offline.c,
+ client/gtk/player.c, client/gtk/plenty.c, client/gtk/quote.c,
+ client/gtk/resource.c, client/gtk/settingscreen.c, client/gtk/state.c,
+ client/gtk/trade.c: Preparations for 'Leave Game', added some
+ constness, chat disabled when offline, frontend_gui_register_* can
+ handle more than one widget, removed toolbar hack (not needed anymore)
+ * client/gtk/guimap.c: Removed compiler warnings when compiling with
+ --pedantic
+ * ai/client.c, ai/client.h: Removed dead code
+ * client/common/client.c, common/common_glib.c, common/driver.h,
+ common/state.c, common/state.h, common/gtk/common_gtk.c: Removed
+ reference to widget from StateMachine. The code was moved to the gtk
+ directory in 0.8.0
+
+2004-11-12 Roland Clobus <rclobus at bigfoot.com>
+ * Actually updated the build number to 0.8.1.42
+
+2004-11-05 0.8.1.42 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/resource.c: Translation was not active
+ * client/callback.h, client/ai/greedy.c, client/common/client.c,
+ client/common/develop.c, client/gtk/frontend.h, common/cards.c,
+ common/cards.h: More const in prototypes
+ * client/gtk/develop.c: Rewrite without deprecated GTK calls
+ * client/common/callbacks.c: Reset development cards when a new game
+ starts
+
+2004-10-27 0.8.1.41 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/client.c: Added dummy callsbacks to remove compiler
+ warnings
+ * common/common_glib.c, common/common_glib.h, common/driver.h,
+ common/network.c, server/gnocatan-server.c, server/server.c: Using the
+ new typedef InputFunc
+ * rules.make: When compiling with --enable-debug,
+ GNOME_DISABLE_DEPRECATED can be used
+ * ai/ai.c, ai/client.c, ai/computer.c, ai/player.c, ai/resource.c,
+ ai/trade.c: gnome.h previously included string.h, now we must do it
+ ourselves
+ * client/gtk/gui.c: Rewrite of Preference dialog. It uses
+ instant-apply. Toolbar settings removed, because GNOME already saves
+ it
+ * client/common/chat.c, common/log.c, common/log.h,
+ common/gtk/common_gtk.c: Chat color separate from use of color of
+ messages
+ * client/gtk/identity.c: Removed compiler warnings
+
+2004-10-24 0.8.1.40 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/gui.c, client/gtk/gui.h, client/gtk/trade.c: Removed the
+ second global variable map. (The other is client/common/client.[ch])
+ * client/gtk/guimap.c, client/gtk/guimap.h, client/gtk/histogram.c:
+ Reenabled the dots that indicate the probability (when enough space in
+ the hex/chit is available)
+ * client/common/callback.c(can_move_ship),
+ common/buildrec.c(can_setup_settlement): Removed the compiler warnings
+ about losing const-ness, introduced in 0.8.1.39 (It is still cheating:
+ a temporary non-const pointer is used to temporarily modify the map)
+ * common/common_glib.c, common/common_glib.h, common/driver.h: Removed
+ compiler warning: ISO C forbids passing arg 2 of pointer to function
+ between function pointer and `void *'
+
+2004-10-17 0.8.1.39 Roland Clobus <rclobus at bigfoot.com>
+ * common/map.h, common/map_query.c: Fixed longest road detection
+ * client/gtk/monopoly.c: No longer uses deprecated calls. Removed
+ frame
+ * client/callback.h, client/common/build.c, client/common/client.h,
+ client/common/resource.c, client/common/setup.c,
+ client/gtk/frontend.h, client/gtk/gui.c, client/gtk/guimap.c,
+ client/gtk/guimap.h, client/gtk/interface.c, common/buildrec.c,
+ common/buildrec.h, common/map.h, common/map_query.c: Many pointers are
+ now const
+ * client/common/robber.c: Removed unused code
+ * client/gtk/frontend.c, client/gtk/gameover.c, client/gtk/resource.c:
+ Replaced deprecated calls
+ * client/gtk/gui.c, client/gtk/guimap.c, client/gtk/guimap.h: Single
+ click building
+ * common/log.c, common/log.h, common/gtk/common_gtk.c,
+ common/gtk/common_gtk.h: Log uses less memory
+ * server/player.c: Fix for lost longest road on reconnect
+
+2004-10-08 0.8.1.38 Roland Clobus <rclobus at bigfoot.com>
+ * All *.c: Added #include "config.h"
+ * configure.in, ai/ai.c, client/ai/ai.c, client/gtk/connect.c,
+ client/gtk/offline.c, common/Makefile.am,
+ meta-server/gnocatan-meta-server.c, server/gnocatan-server-console.c,
+ server/gnocatan-server.c, server/gtk/gnocatan-server-gtk.c,
+ server/meta.c, server/server.c: Moved contents of meta.h and port
+ numbers to configure.in
+ * common/meta.h: Replaced by contents in configure.in
+ * client/callback.h, client/common/i18n.c, client/gtk/offline.c: Added
+ commandline to gnocatan client
+ * rules.make, client/common/resource.c, client/gtk/callbacks.c,
+ client/gtk/gui.c, client/gtk/guimap.c, client/gtk/histogram.c,
+ client/gtk/player.c, client/gtk/trade.c, common/game.c,
+ common/network.c: Added -pedantic to --enable-debug, and resolving
+ many warnings
+ * client/gtk/develop.c, client/gtk/connect.c, client/gtk/discard.c,
+ client/gtk/frontend.c, client/gtk/gameover.c, client/gtk/gold.c,
+ client/gtk/monopoly.c, client/gtk/plenty.c, client/gtk/polygon.c,
+ client/gtk/quote.c, client/gtk/settingscreen.c: Replace gnome.h
+ includes with gtk and/or gdk
+ * client/gtk/gui.c: Removed language setting in GUI. Override is now
+ only possible with the normal environment variables, and the
+ commandline
+ * client/gtk/name.c: Added per default the current name
+ * common/gtk/game-settings.c, common/gtk/common_gtk.c: Added some stub
+ functions for compatibility with versions of Gtk before 2.4
+ * client/help/C/gnocatan.xml: Added technical chapter
+ * server/gnocatan-server.c, server/server.c, server/server.h: Enabled
+ server-stop for administrator, added a few checks to admin interface
+
+2004-10-01 0.8.1.37 Roland Clobus <rclobus at bigfoot.com>
+ * client/help/C/gnocatan-C.omf: Added line with DTD to make xmllint
+ happy.
+ * ai/computer_names: moved to client/ai
+ * server/gnocatan-server-gtk.c, server/gnocatan-server.desktop: moved
+ to server/gtk
+ * common/select-game.c, common/select-game.h, common/config-gnome.c,
+ common/config-gnome.h, common/common_gtk.c, common/common_gtk.h,
+ common/game-settings.c, common/game-settings.h: moved to common/gtk.
+ All gtk related code is now in separate subdirectories.
+ * server/gtk/.cvsignore, server/gtk/Makefile.am,
+ common/gtk/.cvsignore, common/gtk/Makefile.am: Initial versions, based
+ on the parent directories.
+ * Makefile.am: Don't try to build ai, if no gnome found
+ * ai/Makefile.am: Removed dependency on gtk libraries, installation
+ of computer_names move to client/ai/Makefile.am
+ * client/ai/Makefile.am: Now installs computer_names
+ * configure.in, client/gtk/Makefile.am, common/Makefile.am,
+ server/.cvsignore, server/Makefile.am: Adjustment for the new
+ directories.
+ * common/.cvsignore: Removed gnocatan-path.h
+ * po/ChangeLog: Add changes regarding the po directory will be loggged
+ in po/ChangeLog, and not in this file.
+ * configure.in, ai/Makefile.am, client/ai/Makefile.am, ai/ai.c: Added
+ option to install new or old ai. Current default: old ai
+
+2004-09-26 0.8.1.36 Roland Clobus <rclobus at bigfoot.com>
+ * Makefile.am, autogen.sh, configure.in, omf.make, rules.make,
+ xmldocs.make, ai/Makefile.am, client/Makefile.am,
+ client/ai/Makefile.am, client/common/Makefile.am, common/Makefile.am,
+ meta-server/Makefile.am, client/gtk/Makefile.am, server/Makefile.am,
+ server/gnocatan-server-gtk.c: New autogen.sh script, with optional
+ Gnome/Gtk and scrollkeeper.
+ * ai/ai.c, client/ai/ai.h, meta-server/gnocatan-meta-server.c,
+ server/gnocatan-server.h, server/server.c: Removed the need for the
+ generated file gnocatan-path.h
+ * client/callback.h, client/ai/ai.c, client/common/gnocatan.c,
+ client/common/i18n.c, client/gtk/callbacks.c, client/gtk/offline.c:
+ The new frontend_init uses the argc and argv, instead of set_callbacks
+ * client/ai/greedy.c, client/common/resource.c: Removed unneeded Gnome
+ dependency
+ * .cvsignore, common/.cvsignore: updated for removed files
+ * depcomp, install-sh, missing, mkinstalldirs, stamp.h.in,
+ po/Makefile.in.in: Removed (autogenerated files)
+ * common/gnocatan-path.h.in: Removed (replaced by rules.make)
+ * intl/*, ABOUT-NLS: Removed (using glib-gettext instead)
+ * macros/type_socklen_t.m4: Added check for struct socklen_t
+
+2004-09-06 0.8.1.35 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/gui.c, client/gtk/gui.h: Made left pane resizable.
+ * client/gtk/identity.c: Made identity panel resizable.
+ * client/gtk/player.c: Player summary uses Gtk2 widget, is resizable.
+ * client/gtk/resource.c(resource_build_panel): Resource panel
+ resizable.
+
+2004-09-03 Jeff Breidenbach <jab at debian.org>
+
+ * debian/changelog: sync Debian & upstream versioning.
+
+2004-08-29 0.8.1.34 Roland Clobus <rclobus at bigfoot.com>
+ * ai/client.c: Added global flag 'played_soldier_card' to fix stack
+ overflow.
+ * server/gnocatan-server-gtk.c(start_clicked_cb): Remembered game
+ did start with wrong map.
+ * client/common/resource.c(resource_modify), client/gtk/frontend.h:
+ Argument contains absolute value, not a difference.
+ * client/gtk/resource.c(resource_build_panel,
+ frontend_resource_change): Fixed size of resource counter to 2
+ positions.
+
+2004-08-21 Jeff Breidenbach <jab at debian.org>
+
+ * debian/control: added yelp dependency for gnocatan-help
+ * Released as Debian package, 0.8.1-6.
+
+2004-08-07 0.8.1.33 Roland Clobus <rclobus at bigfoot.com>
+ * common/game.c: changed server-port parameter to string, fixed memory
+ leak in params_free.
+ * server/gnocatan-server.c(start_server), server/gnocatan-server.h,
+ server/server.c(server_startup), server/server.h: added const in the
+ parameters.
+ * server/server.c, server/server.h: removed server_restart (not used).
+
+2004-08-07 Claudio Fontana (sick_soul at users.sourceforge.net>
+ * client/common/client.c: Removed deprecated lvalue casts.
+
+2004-07-31 0.8.1.32 Roland Clobus <rclobus at bigfoot.com>
+ * common/game-settings.c: more specific include files.
+ * common/select-game.c (select_game_add), server/gnocatan-server-gtk.c
+ (start_clicked_cb): Fixed bug that 'Default' game would be started
+ instead of preselected game.
+ * client/common/player.c, client/gtk/trade.c, common/game-settings.c,
+ common/select-game.c, server/gnocatan-server-gtk.c, server/server.c:
+ Added comments for translations.
+ * common/game-settings.c(game_settings_init): Spin button right
+ aligns, this code is disabled until the build requires Gtk2.4
+ * po/POTFILES.in: enabled translation for common/game-settings and
+ commong/select-game.
+ * po/nl.po: Updated translations
+
+2004-07-31 Hans Fugal <fugalh at users.sourceforge.net>
+ * client/gtk/interface.c: Quick fix for 'Second click on reject trade
+ crashes the server'.
+
+2004-07-31 Giancarlo Capella <giancarlo at comm.cc>
+ * po/it.po: Updated italian translation
+
+2004-07-24 0.8.1.31 Roland Clobus <rclobus at bigfoot.com>
+ * configure.in, client/common/i18n.c: Enabled italian in the UI, made
+ some checks more strict.
+ * ai/greedy.c, client/ai/greedy.c, client/common/chat.c, TODO:
+ Enabled translated chats for the AI
+ * client/gtk/legend.c, client/gtk/theme.c: Fixed display of tiles in
+ the legend dialog/tabpage. (Foundation layed by Giancarlo Capella)
+ Replaced deprecated function calls.
+ * client/gtk/theme.c: Fixed crash on theme change before a game is
+ started.
+ * rules.make, client/gtk/gui.c, common/common_gtk.c: Enabled
+ GDK_DISABLE_DEPRECATED check in --enable-debug mode, all deprecated
+ functions are replaced.
+ * client/callback.h: Removed prototypes for static functions
+ * client/common/callback.c(pirate_count_victims): Fixed small memory
+ leak.
+ * client/gtk/guimap.c, client/gtk/guimap.h, client/gtk/histogram.c:
+ Dynamic scaling of the font in the chit, removed duplicate code
+ * client/gtk/interface.c: Removed the need for some global variables.
+ Fixed bug that a ship to steal from could not be selected.
+ * client/gtk/polygon.c, client/gtk/polygon.h: Added some const
+ correctness.
+ * client/gtk/theme.c, client/gtk/theme.h: Port tiles are now always
+ centered.
+
+2004-07-24 Giancarlo Capella <giancarlo at comm.cc>
+ * po/it.po: Added italian translation
+
+2004-07-08 Jeff Breidenbach <jab at debian.org>
+
+ * Released as Debian package, 0.8.1-5.
+
+2004-07-08 0.8.1.30 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/histogram.c: Added more margins, last dice roll is shown
+ * ai/client.c, ai/greedy.c, client/ai/greedy.c, client/gtk/gui.c,
+ common/game.c, common/game.h, server/develop.c,
+ server/gnocatan-server-console.c, server/gnocatan-server-gtk.c,
+ server/gnocatan-server.c, server/gnocatan-server.h, server/turn.c:
+ Replaced all references to Exit with Quit
+ * ai/greedy.c (score_hex_hurt_opponents), client/ai/greedy.c
+ (score_hex_hurt_opponents): AI does not try to move the robber onto
+ water
+ * NEWS: Updated to reflect the release on SF
+ * rules.make: removed GTK_ITEM_FACTORY define, it will no longer work
+ with Gtk 2.4
+ * po/nl.po: Updated some translations
+
+2004-07-02 Jeff Breidenbach <jab at debian.org>
+
+ * Released as Debian package, 0.8.1-4.
+
+2004-07-01 Roland Clobus <rclobus at bigfoot.com>
+ * server/pregame.c, ai/client.c: Oops, forgot a ;
+
+2004-06-29 0.8.1.29 Roland Clobus <rclobus at bigfoot.com>
+ * ai/client.c, ai/trade.c, client/common/client.c,
+ client/gtk/frontend.h, client/gtk/interface.c, client/gtk/quote.c,
+ client/common/quoteinfo.c, common/quoteinfo.h, server/pregame.h:
+ Various changes. quotelist_new and quotelist_delete changed prototypes
+ to allow for checks on 'quote-leaks'.
+ * ai/greedy.c (trade_desired), client/ai/greedy.c (trade_desired): Fix
+ for AI losing resources during trade.
+ * client/callback.h, client/gtk/identity.c, client/gtk/player.c:
+ Removed unused color field, added player_or_viewer_color.
+ * client/gtk/chat.c, client/gtk/gui.c: Added flag to indicate whether
+ the focus can be grabbed.
+ * client/gtk/trade.c: Gtk2 widgets for trade page. Redesign.
+ * common/network.c: Removed an obsolete FIXME.
+ * server/trade.c: More informative error messages. Duplicate quote is
+ now a note, not an error.
+
+2004-05-30 0.8.1.28 Roland Clobus <rclobus at bigfoot.com>
+ * client/ai/greedy.c (greedy_year_of_plenty), ai/client.h
+ (mode_year_of_plenty), ai/computer.h, ai/greedy.c
+ (greedy_year_of_plenty): Fix year of plenty bug, AI will now always
+ choose available resources
+
+2004-05-26 Jeff Breidenbach <jab at debian.org>
+
+ * 0.8.1.27 Released as Debian package, 0.8.1-3.
+
+2004-05-23 0.8.1.27 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/chat.c, client/gtk/connect.c, client/gtk/histogram.c,
+ client/gtk/name.c, common/game-settings.c, common/select-game.c,
+ server/gnocatan-server-gtk.c: Removed *_DISABLE_DEPRECATED defines to
+ allow the code to build with Gtk 2.4.
+ * client/gtk/frontend.c, common/common_gtk.c: Replaced casts to
+ gpointer with more portable GINT_TO_POINTER.
+ * server/gnocatan-server-gtk.c: Added #include <locale.h>, needed when
+ building with gcc flag -O0.
+ * po/nl.po: Added dutch translations.
+
+2004-05-04 Roland Clobus <rclobus at bigfoot.com>
+ * po/de.po, po/es.po, po/nl.po, po/fr.po, po/gnocatan.pot: Updated
+ translation files to reflect current texts. (No changes to translated
+ texts)
+
+2004-04-25 0.8.1.26 Released as Debian package, 0.8.1-2
+
+2004-04-25 0.8.1.26 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/build.c (build_add), client/common/client.c
+ (mode_load_gameinfo), client/common/client.h (build_add),
+ common/buildrec.h (struct BuildRec), server/pregame.c (mode_pre_game):
+ Reconnect fix when something was built in the current turn.
+ * common/game-settings.c, common/game-settings.h,
+ common/select-game.c, common/select-game.h, common/Makefile.am: New
+ Gtk widgets for server and client.
+ * client/gtk/connect.c: New connection scheme.
+ * client/gtk/frontend.h: Cleanup connect_get_port_str.
+ * client/gtk/gui.c: Replaced some deprecated icons.
+ * client/gtk/name.c: Replaced deprecated code.
+ * client/gtk/offline.c: Moved code regarding settings to
+ client/gtk/connect.c.
+ * meta-server/gnocatan-meta-server.c (debug): Prototype fix.
+ * server/gnocatan-server-gtk.c: Replaced deprecated code, added
+ tooltips, used new widgets
+ * server/player.c, server/server.h: Some cleanup.
+
+2004-04-25 0.8.1.26 Tobias Jakobs <tobias.jakobs at web.de>
+ * client/gtk/data/splash.png: New image (400x400 pixels)
+ * client/gtk/data/splash.svg: Source for splash.png
+
+2004-04-25 0.8.1.25 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * client/callback.h (struct callbacks), client/common/client.c
+ (client_init, check_other_players), client/common/player.c
+ (player_stole_from), client/ai/greedy.c (greedy_new_statistics,
+ greedy_player_robbed, greedy_get_rolled_resources,
+ greedy_played_develop, greedy_init): added and used new callbacks for
+ ai chatting.
+ * client/gtk/callbacks.c (frontend_error, frontend_set_callbacks): gtk
+ client callback cleanup.
+
+2004-03-28 0.8.1.24 Roland Clobus <rclobus at bigfoot.com>
+ * ai/client.c (mode_play_develop_response), ai/develop.c
+ (can_play_develop), client/common/client.c
+ (mode_play_develop_response), client/common/develop.c
+ (can_play_develop): Less stringent check if Road building development
+ card can be played.
+ * client/common/callback.c (road_building_can_finish)m
+ client/common/client.c (mode_road_building): Road building
+ can be aborted when nothing can be built anymore.
+ * client/common/develop.c (develop_played): Out of resource is
+ a warning instead of an error.
+
+2004-03-23 0.8.1.23 Roland Clobus <rclobus at bigfoot.com>
+ * client/gtk/state.c (route_gui_event): Added #ifdef DEBUG
+
+2004-02-29 0.8.1.22 Roland Clobus <rclobus at bigfoot.com>
+ * client/common.client.c (mode_load_gameinfo): Fixed textual error.
+ * server/pregame.c (mode_pre_game): Fixed bugs for viewers with
+ ID >= MAX_PLAYERS.
+ * server/gnocatan-server-gtk.c (gui_player_change), server/gold.c
+ (distribute_next, distribute_first), server/player.c (next_player_num,
+ player_setup, player_free, player_archive, player_is_viewer),
+ server/pregame.c (mode_pre_game), server/server.h, server/trade.c
+ (trade_finish_domestic, process_call_domestic, trade_begin_domestic):
+ new function player_is_viewer.
+ * common/state.c (sm_pop): Fixed too relaxed assertion.
+ * client/gtk/chat.c (chat_build_panel, chat_set_focus): Avoided
+ selection of chat entry text on every gui update.
+
+2004-02-28 0.8.1.21 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/common/client.c (client_init): added initialisation for init
+ and new_bank
+ * client/common/resource.c (resource_format_type): added 'nothing'
+ when nothing is offered in a trade
+
+2004-02-08 0.8.1.20 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/common/player.c, client/gtk/gameover.c, common/common_gtk.c,
+ common/log.c, common/log.h: Removed MSG_NAMEANON, added prefixes to
+ log_message_string_console.
+ * client/common/develop.c: Removed selected_card_idx that was
+ originally used for the gtk interface.
+ * client/gtk/state.c, common/log.c, common/network.c,
+ common/network.h, common/state.c: Renamed LOG defines to DEBUG. Made
+ the log more readable.
+ * client/callback.h, client/common/client.c, client/gtk/callbacks.c,
+ client/gtk/frontend.h, client/gtk/player.c, client/common/player.c:
+ Added rename for viewers, viewers are shown in Player Summary again.
+ * client/callback.h, client/common/callback.c, client/common/client.c,
+ client/common/client.h, client/common/player.c,
+ client/common/resource.c, client/gtk/callbacks.c: Added support in the
+ client to count the resources in the bank.
+ * client/gtk/player.c: Added plurals for several development cards.
+
+2004-02-08 0.8.1.19 Bas Wijnen <b.wijnen at phys.rug.nl>, Roland Clobus <rclobus at bigfoot.com>
+
+ * client/common/client.c (mode_road_building): Changed interpretation
+ of argument of callbacks.roadbuilding to facilitate AI programs.
+
+2004-02-08 0.8.1.18 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/callback.h, client/common/callback.c, common/state.c,
+ common/state.h: Added cb_disconnect and sm_close
+
+2004-02-06 0.8.1.17 Roland Clobus <rclobus at bigfoot.com>
+
+ * client/gtk/player.c (player_show_connected_at_row): Fixed bug
+ displaying random line below player icon.
+
+2004-01-26 0.8.1.16 Roland Clobus <rclobus at bigfoot.com>
+
+ * server/server.c (game_server_start): Show random seed in the server.
+
+2004-01-25 0.8.1.15 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * common/state.c, common/state.h: Added a stackdump when overflow
+ occurs.
+ * client/common/client.c, common/state.c, common/state.h: Added
+ sm_push_noenter, sm_pop_noenter, sm_goto_noenter, needed for the AI.
+ * client/gtk/histogram.c: Added enter after last line
+
+2004-01-15 Jeff Breidenbach <jab at debian.org>
+
+ * doc/Makefile.am, doc/gnocatan-meta-server.6,
+ debian/gnocatan-meta-server.files: Added metaserver manpage.
+
+2004-01-11 0.8.1.14 Roland Clobus <rclobus at bigfoot.com>
+
+ * client/callback.h, client/common/client.c, client/common/turn.c,
+ client/gtk/callbacks.c: renamed callbacks.dice to
+ callbacks.rolled_dice.
+ * client/gtk/callbacks.c, client/gtk/frontend.h,
+ client/gtk/interface.c: renamed frontend_dice to frontend_rolled_dice.
+ * client/gtk/callbacks.c (frontend_init_game): added histogram_init.
+ * client/gtk/guimap.c, client/gtk/guimap.h: add color lightblue.
+ * client/gtk/histogram.c, client/gtk/histogram.h: complete rewrite of
+ the histogram diagram. Now fully scalable.
+ * client/common/resource.c (resource_format_num): support "no
+ resources" situation.
+
+2004-01-11 0.8.1.13 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/callback.h, client/common/client.c, client/gtk/callbacks.c,
+ client/gtk/frontend.c, client/gtk/ftontend.h, client/gtk/trade.c:
+ Fixes bug with maritime trade
+ * client/common/callback.c, client/gtk/offline.c: Fix for unknown host
+ bug
+ * ai/client.c: AI can handle auto-discard
+ * configure.in, client/Makefile.am, client/callback.h,
+ client/common/callback.c, client/ai/Makefile.am, client/ai/ai.c,
+ client/ai/ai.h, client/ai/greedy.c: Added first version of the AI in
+ the new structure.
+
+2004-01-02 0.8.1.12 Roland Clobus <rclobus at bigfoot.com>
+
+ * client/callback.h (struct callbacks), client/common/client.c
+ (mode_start, mode_load_game, mode_load_gameinfo, mode_start_response),
+ client/common/client.h, client/common/player.c (player_reset,
+ player_reset_statistic), client/gtk/callbacks.c (frontend_init_game,
+ forntend_start_game), client/gtk/frontend.h, client/gtk/player.c
+ (player_clear_summary): Fix bug #866431: Play several games with same
+ client.
+ * client/gtk/callbacks.c (frontend_start_game), client/gtk/frontend.h,
+ client/gtk/identity.c (top level, draw_building_and_count,
+ expose_identity_area_cb, identity_draw, identity_set_dice,
+ identity_build_panel, identity_reset): Fixed bug #824624: Polygons in
+ identity panel disappear under dice.
+
+2004-01-02 0.8.1.12 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * configure.in, Makefile.am, ai/Makefile.am, client/Makefile.am,
+ client/common/Makefile.am, client/gtk/Makefile.am,
+ client/gtk/data/Makefile.am, client/gtk/data/themes/Makefile.am,
+ client/gtk/data/themes/FreeCIV-like/Makefile.am,
+ client/gtk/data/themes/Iceland/Makefile.am,
+ client/gtk/data/themes/Tiny/Makefile.am, client/help/Makefile.am,
+ client/help/C/Makefile.am, common/Makefile.am, docs/Makefile.am,
+ macros/Makefile.am, meta-server/Makefile.am, server/Makefile.am,
+ rules.make (new file): Added support for --enable-debug to autogen.sh.
+ * common/network.c, client/gtk/state.c: Give debugging output when
+ --enable-debug is specified.
+
+2004-01-02 0.8.1.11 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * common/Makefile.am, common/Makefile.am, common/authors.h:
+ Moved authors.h from client/common to common
+ * client/common/i18n.c, client/common/gnocatan.c, client/common/i18n.h:
+ Removed i18n.h and merged into client/callback.h
+ * client/gtk/Makefile.am, client/gtk/frontend.h, client/gtk/gui.c:
+ Removed directories in #include statements
+ * client/Makefile.am, client/common/Makefile.am, client/callback.h:
+ Moved callback.h from client/common to client
+
+2004-01-02 0.8.1.10 Roland Clobus <rclobus at bigfoot.com>
+
+ * client/gtk/legend.c (legend_create_dlg): The legend dialog now has a
+ close button, like the other dialogs.
+ * client/gtk/quote.c (top level, quote_build_page): The translation
+ now works.
+ * client/gtk/settingscreen.c (top level, add_setting_val,
+ settings_create_dlg): Shuffled the boxed around in game settings
+ dialog, for better layout, numbers (where possible) right aligned.
+ * po/de.po, po/es.po, po/fr.po, po/nl.po, po/gnocatan.pot:
+ Translations modified for the new string 'Reject Domestic Trade'.
+ (still marked fuzzy, because I'm not a native speaker.)
+
+2004-01-01 0.8.1.9 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * (nearly) all files: Removed compiler warnings when compiling with
+ -Wall -W -Wpointer-arith -Wcast-qual -Wno-sign-compare
+ -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes
+ -Wmissing-declarations -Wredundant-decls -Wnested-externs
+ -Wwrite-strings.
+ * client/common/modes.h: Removed
+
+2003-12-30 0.8.1.8 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * client/common/build.c, client/common/callback.h,
+ * client/common/client.c, client/common/setup.c,
+ * client/gtk/frontend.h, client/gtk/interface.c: Removed dependency on
+ BuildRec, modified prototype of callbacks.setup.
+
+2003-12-29 0.8.1.7 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * client/common/build.c (build_move), client/common/callback.h
+ * (top level, struct callbacks), client/common/client.c (top level,
+ * client_init, mode_domestic_trade), client/gtk/callbacks.c
+ * (frontend_trade, frontend_set_callbacks), client/gtk/trade.c
+ * (trade_update, trade_perform_maritime, trade_perform_domestic): Fixed
+ bug #863901: maritime quote doesn't disappear when resources are no
+ longer available.
+ * client/common/client.c (mode_discard, mode_domestic_trade),
+ * client/common/player.c (player_build_add, player_build_remove): Code
+ cleanup.
+ * Added can_play_any_develop, get_devel_deck, get_bank, get_map,
+ * callbacks.error, frontend_error: Preparation for new AI structure.
+ * cb_place_robber, client_start, frontend_init: Changed prototype.
+
+2003-12-28 0.8.1.6 Roland Clobus <rclobus at bigfoot.com>
+
+ * client/common/player.c (player_has_quit): Fix for (null) receives...
+ (Bug #865870).
+ * clinet/gtk/player.c (calc_statistic_row): Fix for viewers.
+ * client/gtk/name.c (name_create_dlg): Remove scrolling from name
+ change dialog.
+
+2003-12-25 Jeff Breidenbach <jab at debian.org>
+
+ * docs/Makefile.am: registered gnocatanai manpage
+
+2003-12-21 0.8.1.5 Roland Clobus <rclobus at bigfoot.com>
+
+ * po/nl.po: Improved translation.
+
+2003-12-21 0.8.1.4 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * client/gtk/interface.c (frontend_discard_remove),
+ client/gtk/discard.c (discard_player_did): Removed warning at
+ automatic discard.
+
+2003-12-21 0.8.1.3 Roland Clobus <rclobus at bigfoot.com>
+
+ * ai/client.c, ai/greedy.c, ai/trade.c, client/common/callback.c,
+ client/common/client.h, client/common/gnocatan.c,
+ client/common/player.c, client/gtk/frontend.h, client/gtk/gui.c,
+ client/gtk/player.c, common/game.c, server/gold.c, server/player.c,
+ server/pregame.c, server/turn.c: Code cleanup.
+
+2003-12-21 0.8.1.2 Roland Clobus <rclobus at bigfoot.com>
+
+ * client/gtk/guimap.c (guimap_draw_hex): Fixed bug #230252; draw
+ complete hex, not only robber/pirate area.
+
+2003-12-21 0.8.1.1 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/common/callback.h: Added comments
+ * client/common/callback.h, client/common/client.c (client_start),
+ * client/common/gnocatan.c, client/gtk/callbacks.c,
+ * client/gtk/frontend.h, client/gtk/offline.c: Changes to frontend
+ intialisation
+
+2003-12-21 0.8.1.1 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/common/Makefile.am: Generalized file generation for
+ authors.h.
+ * client/gtk/develop.c: Removed debugging statements.
+ * client/gtk/interface.c (global, frontend_discard_remove,
+ place_robber, frontend_robber): Fixed state bug (#863836).
+
+2003-12-20 Bas Wijnen <b.wijnen at phys.rug.nl> and Roland Clobus
+<rclobus at bigfoot.com>
+ * theme/*/Makefile.am: Added Makefile.am in all directories
+ * client/gtk/data/Makefile.am, client/gtk/theme.c,
+ * client/gtk/guimap.c: renamed images directory to themes
+ directory. splash.png moved to pixmap directory
+ * po/fr.po, po/de.po: removed some obvious wrong fuzzy translations
+
+2003-12-17 Roland Clobus <rclobus at bigfoot.com>
+ * client/common/i18n.c, po/fr.po: Added french translation by Arnaud MALON
+ <moko at geumeuleu.com>
+ * client/common/i18n.c, client/gtk/gui.c: The untranslated language
+ strings will be converted to UTF-8.
+
+2003-12-16 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * All files except ai: Added proper copyright notice.
+ * client/admin-gtk.c, client/build.c, client/client.c,
+ client/client.h, client/chat.c, client/connect.c, client/develop.c,
+ client/discard.c, gameover.c, gnocatan.c, gold.c, gui.c, gui.h,
+ guimap.c, guimap.h, histogram.c, histogram.h, i18n.c, i18n.h,
+ identity.c, legend.c, monopoly.c, name.c, player.c, player.h,
+ plenty.c, polygon.c, polygon.h, quote.c, resource.c, road_building.c,
+ robber.c, setup.c, settingscreen.c, stock.c, theme.c, theme.h,
+ trade.c, turn.c: removed.
+ * client/common/authors.h, client/common/build.c,
+ client/common/callback.c, client/common/callback.h,
+ client/common/chat.c, client/common/client.c, client/common/client.h,
+ client/common/develop.c, client/common/gnocatan.c,
+ client/common/i18n.c, client/common/i18n.h, client/common/modes.h,
+ client/common/player.c, client/common/resource.c,
+ client/common/robber.c, client/common/setup.c, client/common/stock.c,
+ client/common/turn.c, client/gtk/admin-gtk.c, client/gtk/frontend.h,
+ client/gtk/gui.h, client/gtk/guimap.h, client/gtk/histogram.h,
+ client/gtk/polygon.h, client/gtk/theme.h, client/gtk/callbacks.c,
+ client/gtk/chat.c, client/gtk/connect.c, client/gtk/develop.c,
+ client/gtk/discard.c, client/gtk/frontend.c, client/gtk/gameover.c,
+ client/gtk/gold.c, client/gtk/gui.c, client/gtk/guimap.c,
+ client/gtk/histogram.c, client/gtk/identity.c, client/gtk/interface.c,
+ client/gtk/legend.c, client/gtk/monopoly.c, client/gtk/name.c,
+ client/gtk/offline.c, client/gtk/plenty.c, client/gtk/polygon.c,
+ client/gtk/player.c, client/gtk/quote.c, client/gtk/resource.c,
+ client/gtk/settingscreen.c, client/gtk/state.c, client/gtk/theme.c,
+ client/gtk/trade.c: Added.
+ Seperated gui from network in client as a preparation to other
+ clients, including the AI.
+
+2003-12-02 Roland Clobus <rclobus at bigfoot.com>
+ * client/gui.c, client/guimap.c: When applying a new theme, the tiles
+ were not scaled correctly.
+ * legend.c: When showing the legend tabpage, the client would crash when
+ a scaled theme was active.
+ * client/theme.c: the extra colors of the tile for gold were not
+ correctly used.
+ * client/theme.c: the board tile in the theme is never scaled, but
+ tiled.
+ * client/theme.h: the size of arrays in the struct MapTheme was
+ defined by digits, not by constants in variable names.
+
+2003-12-02 Roland Clobus <rclobus at bigfoot.com>
+ * seafarers.game, seafarers-gold.game: removed unknown keyword.
+ * Cube.game, Another_swimming_in_the_wall.game, Evil_square.game,
+
+2003-12-06 Roland Clobus <rclobus at bigfoot.com>
+ * client/client.c, client/player.c, common/common-gtk.c,
+ * common/driver.h, common/game.c, common/state.c, common/state.h,
+ * server/buildutil.c, server/glib-driver.c, server/glib-driver.h,
+ * server/gnocatan-server-console.c, server/gnocatan-server-gtk.c,
+ * server/gold.c, server/player.c, server/pregame.c, server/server.c,
+ * server/server.h, server/turn.c: Fixed reconnect (excluding gold),
+ client does not crash when added lots of viewers, some variable
+ declarations moved for gcc-2.95 compatibility, replace the clist
+ widget in server-gtk, removed calls to player_name, fixed server
+ crash when reconnecting, server now keeps the current player by
+ number, not by name.
+
+2003-12-02 Roland Clobus <rclobus at bigfoot.com>
+ * seafarers.game, seafarers-gold.game: removed unknown keyword.
+ * Cube.game, Another_swimming_in_the_wall.game, Evil_square.game,
+
+2003-12-11 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * server/trade.c: Fixed bug #848386, state stack overflow. Allow
+ asking for free resources in server.
+
+2003-12-10 Roland Clobus <rclobus at bigfoot.com>
+ * ai/greedy.c: Fixed AI to build only on land.
+ * common/map_query.c: Fixed AI placing robber in water.
+
+2003-12-05 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * common/build_rec.h, common/cards.h, common/common_gtk.h,
+ common/cost.h: Added some #include statements
+ * common/network.h, common/state.h: Removed the comma after the last
+ value in the enum.
+
+2003-12-02 Roland Clobus <rclobus at bigfoot.com>
+ * seafarers.game, seafarers-gold.game: removed unknown keyword.
+ * Cube.game, Another_swimming_in_the_wall.game, Evil_square.game,
+ GuerreDe100ans.game, Mini_another_swimming_pool_in_the_wall.game:
+ Added games by LT-P <LT-P at LT-P.net>
+ * henjes.game: Added game by Robert Henjes <robert.henjes at web.de>
+ * lorindol.game: Added game by Martin Brotzeller
+ <lorindol at cip.informatik.uni-wuerzburg.de>
+ * server/Makefile.am: changed to add the new games
+ * server/gnocatan-server-gtk.c: raised the limit for victory points
+
+2003-11-16 Roland Clobus <rclobus at bigfoot.com>
+ * client/gui.c: Reduced startup window size for smaller displays.
+ * client/player.c (player_build_add), server/pregame.c
+ (send_gameinfo): Fixed bridges.
+
+2003-11-05 Roland Clobus <rclobus at bigfoot.com>
+ * server/gnocatan-server-gtk.c: Fixed bug 816848
+
+2003-11-05 Roland Clobus <rclobus at bigfoot.com>
+ * client/chat.c, client/player.c, common/log.c, common/log.h: Bug
+ #826894: First message is not time stamped.
+
+2003-11-05 Roland Clobus <rclobus at bigfoot.com>
+ * ai/client.c, server/player.c, server/server.c: Refuse connection
+ when a game is over.
+ * common/game.c, common/game.h, server/gnocatan-server-gtk.c,
+ server/server.c, server/server.h: Repaired -x option, implemented
+ rudimentary restart.
+ * client/Makefile.am, common/Makefile.am, */config-gnome.c,
+ */config-gnome.h: Moved config-gnome.* from client/ to common/
+ * server/gnocatan-server-gtk.c: Added save settings.
+ * server/gnocatan-server.c, server/gnocatan-server.h: Ordered the
+ names of the games.
+
+2003-10-29 Roman Hodek <roman at hodek.net>
+
+ * po/de.po: removed fuzzy tags, cared for two untranslated msgs,
+ made some items sound better in German.
+ * ai/monopoly.c (monopoly_player), client/monopoly.c
+ (monopoly_create_dlg): joined the two messages for better
+ translations, needed a tmp string for that.
+
+2003-10-28 Roman Hodek <roman at hodek.net>
+
+ * server/gnocatan-server-console.c (main): New option -n to set
+ hostname reported to meta server (analogous field in GTK server).
+ * meta-server/README.protocol: updated
+
+2003-10-26 Jeff Breidenbach <jab at debian.org>
+
+ * docs/gnocatan*.6: added gnocatanai man page
+
+2003-10-25 Roman Hodek <roman at hodek.net>
+
+ * server/meta.c (meta_send_details): send PROTOCOL_VERSION, not
+ program VERSION.
+ * meta-server/README.protocol: new file
+
+2003-10-25 Roland Clobus <rclobus at bigfoot.com>
+ * gnocatan.spec: Applied patch 829404 by Daniel Jensen
+ * client/gui.c: Removed compiler warning introduced at 2003-10-19
+
+2003-10-24 Jeff Breidenbach <jab at debian.org>
+
+ * debian/*: More scrollkeeper packaging fixes.
+
+2003-10-20 Jeff Breidenbach <jab at debian.org>
+
+ * debian/rules, debian/control: Better scrollkeeper-ing.
+
+2003-10-19 Roland Clobus <rclobus at bigfoot.com>
+ * client/gui.c: Added word wrap to client messages window.
+
+2003-10-17 Roland Clobus <rclobus at bigfoot.com>
+ * ai/player.c, client/player.c, po/de.po, po/es.po, po/gnocatan.pot:
+ Updated german translations.
+
+2003-10-17 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/client.c, client/player.c, client/player.h: Fixed reconnect
+ bug.
+ * common/network.c, server/gnocatan-server.c: Fixed broken pipe bug.
+
+2003-10-17 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * po/de.po, po/es.po, po/gnocatan.pot: Updated.
+ * server/gnocatan-server-gtk.c: Improved code.
+ * server/gnocatan-server.c: Ignored broken pipe.
+
+2003-10-15 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+2003-10-14 Jason Long <jlong at messiah.edu>
+ * INSTALL: removed note about requiring the Gnome prefix.
+ * client/gui.c, server/gnocatan-server-gtk.c: replace gnome_pixmap_file
+ with gnome_program_locate_file, which uses the application-specific
+ pixmap directory instead of Gnome's pixmap directory.
+ * server/Makefile.am: make DATADIR available to gnocatan-server-gtk.
+ * client/trade.c: Fixed reconnect bug.
+ * po/de.po, po/es.po, po/gnocatan.pot: Updated.
+ * server/conquest+ports.game, server/conquest.game,
+ server/four-islands.game, server/seafarers-gold.game,
+ server/seafarers.game, server/x.game: Added pirate.
+
+2003-10-15 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * README: Changed version number.
+ * client/player.c: bugfix.
+ * po/de.po, po/es.po, po/gnocatan.pot: updated.
+
+2003-10-15 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * ai/client.c: Use new disconnect protocol.
+ * client/build.c: Fixed ship move undo bug.
+ * server/gold.c, server/robber.c, server/trade.c: Fixed viewer bugs.
+ * po/de.po, po/es.po, po/gnocatan.pot: Updated.
+
+2003-10-13 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/client.c, server/pregame.c: Added pirate position to
+ reconnect info.
+ * common/game.c, server/player.c, server/pregame.c, server/server.h:
+ Bugfixes.
+ * common/game.c, server/player.c, server/pregame.c: Bugfixes.
+
+2003-10-12 Roland Clobus <rclobus at bigfoot.com>
+ * client/admin_gtk.c, client/connect.c, common/network.c,
+ common/network.h, common/state.c, meta-server/gnocatan-meta-server.c,
+ server/gnocatan-server.c, server/meta.c: Changed net_free to NULLify
+ the session, changed the meta-server connection dialog, fixed bug
+ #717982, added meta-server redirections without port-number.
+
+2003-10-12 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * AUTHORS: Added my name.
+ * Makefile.am: Fixed make distcheck bug.
+ * po/de.po, po/es.po, po/gnocatan.pot: Updated.
+
+2003-10-12 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * ai/client.c, client/client.c: Fixed version conflict bug.
+ * po/de.po, po/es.po, po/gnocatan.pot: Updated.
+
+2003-10-10 Jason Long <jlong at messiah.edu>
+ * Removed client/help/C/images/*.gif client/help/C/gnocatan.sgml,
+ client/help/C/topic.dat; added xmldocs.make, omf.make,
+ client/help/C/gnocatan.xml, client/help/C/gnocatan-C.omf,
+ client/help/C/legal.xml, client/help/C/images/*.png; changed
+ client/help/C/Makefile.am, Makefile.am, client/Makefile.am,
+ client/gnocatan.c: bring Gnocatan help system up to Gnome2 standards.
+
+2003-10-04 Roland Clobus <rclobus at bigfoot.com>
+ * client/client.c,client/config-gnome.c,client/config-gnome.h,
+ client/connect.c,client/gui.c,client/i18n.c: Settings dialog uses
+ config-gnome.c. Removed French and Italian, due to unavailable
+ translations.
+
+2003-10-04 Roland Clobus <rclobus at bigfoot.com>
+ * client/gui.c,server/gnocatan-server-gtk.c: The application icons are
+ now shown.
+
+2003-10-12 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * common/game.c, common/map.c, common/map.h, common/map_query.c: Added
+ support for nodes where setup is not allowed.
+
+2003-10-12 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/client.c, client/player.c, client/player.h, common/game.h,
+ server/server.h: Added arbitrary point tokens.
+
+2003-10-12 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/identity.c, client/player.c, client/player.h,
+ server/player.c, server/pregame.c: Finished viewer support.
+ * common/map_query.c: Fixed bug with pirate.
+
+2003-10-12 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * server/develop.c, server/player.c, server/server.h: Allowed multiple
+ development cards of the same type.
+ * client/client.c, server/discard.c, server/gold.c, server/robber.c,
+ server/server.c, server/player.c, server/pregame.c, server/server.h,
+ server/turn.c: Added support for viewers and disconnected players.
+ * server/develop.c, server/player.c, server/pregame.c,
+ server/resource.c, server/robber.c, server/turn.c: Cleanup.
+
+2003-10-12 Jeff Breidenbach <jab at debian.org>
+
+ * debian/control, debian/changelog: prepare for 0.8.0 package
+
+2003-10-11 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * ai/greedy.c, client/client.c, client/client.h, client/guimap.c,
+ client/robber.c, common/map.c, common/map.h, common/map_query.c,
+ server/robber.c: Prepared client for pirates, bugfixes.
+ * client/build.c, client/client.c. client/guimap.c, client/robber.c,
+ client/turn.c, common/map.h, common/map_query.c, server/buildutil.c,
+ server/robber.c server/server.h server/turn.c: Completed pirates in
+ server and client. Bugfixes.
+ * common/log.c: Code cleanup.
+ * server/gnocatan-server-gtk.c: Used message window for log.
+
+2003-10-10 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * common/game.c, common/game.h, common/map.c, common/map.h,
+ common/map_query.c, server/robber.c, server/turn.c: prepared server
+ for pirates.
+
+2003-10-10 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * ai/client.c: Fixed AI naming bug.
+ * client/gui.c: Made code nicer, fixed bugs.
+ * client/robber.c: Fixed language bug.
+ * client/theme.c: Made code nicer, fixed scaling bugs.
+
+2003-10-03 Roland Clobus <rclobus at bigfoot.com>
+ * client/gold.c: Cosmetic change for the Choose Gold dialog.
+
+2003-10-03 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * server/player.c: Bugfix.
+ * server/buildutil.c: Fixed bug #817465.
+ * server/gold.c: Removed debugging statement.
+ * client/gui.c: Inserted startsize patch (fixes bug #722641).
+
+2003-10-03 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * server/player.c: Bugfix.
+
+2003-10-01 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * ai/client.c, client/client.c, server/player.c, server/pregame.c,
+ server/server.c, server/server.h: Changed protocol for sending initial
+ player name.
+ * ai/client.c, client/client.c, server/player.c: Added extensions to
+ protocol, to allow future features without needing a minor version
+ change (which would break compatibility).
+
+2003-09-30 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * many files, didn't record which: Fixed const<->non-const warnings
+ introduced by previous 2 patches.
+ * client/theme.c: Bugfixes in scaling tiles.
+ * client/guimap.c: Improved code.
+ * client/gui.c: Fixed settings update bug.
+
+2003-08-17 Jason Long <jasonlong at users.sourceforge.net>
+ * client/admin-gtk.c, client/connect.c, client/discard.c,
+ client/gameover.c, client/gui.c, client/histogram.c,
+ client/legend.c, client/monopoly.c, client/name.c,
+ client/plenty.c, client/settingscreen.c: use GtkDialog
+ instead of deprecated GnomeDialog
+
+2003-08-17 Jason Long <jasonlong at users.sourceforge.net>
+ * configure.in: remove references to macros directory and
+ add checks for Gnome2
+ * client/Makefile.am, common/Makefile.am, server/Makefile.am,
+ ai/Makefile.am, meta-server/Makefile.am:
+ use GNOME2_CFLAGS and GNOME2_LIBS or GLIB2_LIBS for INCLUDES
+ and LDADD
+ * client/connect.c: don't destroy cserver_dlg a second time
+ * client/gui.c (gui_draw_hex, gui_draw_edge, gui_highlight_chits,
+ expose_map_cb), client/guimap.c (redraw_node): fixed some
+ drawing issues (Gnocatan was trying to draw to the backing
+ store before it was created)
+ * client/gui.c (build_messages_panel), common/common_gtk.c,
+ server/gnocatan-server-gtk.c (build_interface): use
+ GtkTextView instead of deprecated GtkText
+ * client/gui.c (register_gnocatan_pixmaps): use GtkIconFactory
+ instead of deprecated gnome_stock_pixmap_register
+ * client/guimap.c (guimap_terrain), client/theme.c: use
+ GdkPixbuf instead of Imlib
+ * client/config-gnome.c, client/gui.c, client/i18n.c,
+ client/identity.c, server/gnocatan-server-gtk.c: miscellaneous
+ changes for Gnome2
+
+2003-09-29 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * ai/client.c, client/client.c, server/turn.c: made ship move back
+ more logical in protocol.
+ * server/buildutil.c, server/buildutil.c: bugfixes.
+ * common/map_query.c: Made query more general.
+
+2003-09-29 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * server/buildutil.c, server/server.h, server/turn.c: Fixed longest
+ road bug.
+ * ai/client.h: Fixed bug.
+ * client/client.c, server/buildutil.c, server/develop.c,
+ server/pregame.c, server/server.h, server/turn.c: Changed undo protocol
+ to let the server do the thinking.
+ * server/turn.c: Fixed bug #698611
+
+2003-09-28 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * server/gnocatan-server-gtk.c: Fixed UI bug in sevens rule.
+
+2003-09-28 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * ai/ai.c, ai/client.h, ai/greedy.c: Chat when aborting a game with
+ gold. Function is not actually implemented yet.
+ * client/client.c, client/client.h, client/gold.c: Fixed bugs in
+ gold and changed some states from goto to push/pop.
+ * common/buildrec.h: Preparing to fix longest road undo bug.
+ * common/map_query.c, server/buildutil.c: Fixed longest road bug.
+ * server/develop.c, server/discard.c, server/gold.c, server/player.c,
+ server/pregame.c, server/robber.c, server/server.h, server/trade.c,
+ server/turn.c: Fixed bugs and changed most states from goto to
+ push/pop.
+ * docs/server_states.fig, docs/client_states.fig, docs/README.states:
+ New files documenting the (new) state model of server and client.
+
+2003-09-26 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * ai/client.c, ai/computer.h, ai/greedy.c: AI crashed when there
+ was gold in the game. Now it exits gracefully.
+
+2003-08-15 Roland Clobus <rclobus at bigfoot.com>
+ * common/Makefile.am, meta-server/Makefile.am, po/Makefile.in.in:
+ 'make distcheck' aborted with an error. Removed reference to
+ non-existing po/Changelog and updated the generation of
+ common/gnocatan-path.h
+ * po/de.po, po/es.po, po/gnocatan.pot: Changed automatically (line
+ numbers in comments) by make distcheck.
+
+2003-09-25 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * ai/greedy.c: Fixed bug.
+ * server/player.c, client/player.c, client/client.c: Fixed bug.
+ * common/map_query.c, server/gold.c: Fixed incorrect C.
+
+2003-08-15 Yusei <yusei at ragondux.com>
+ * server/player.c: fixed a bug with anonymous players that caused the
+ first player to get their turn.
+
+2003-08-15 Roland Clobus <rclobus at bigfoot.com>
+ * client/legend.c: fixed text-display for gold in legend-dialog
+
+2003-09-25 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * ai/client.c: Let ai prefer 2:1 trade.
+
+2003-08-18 Roland Clobus <rclobus at bigfoot.com>
+ * client/client.c, server/resource.c, ai/client.c, ai/greedy.c,
+ ai/client.h: Fixed bug 652707. The ai now correctly handles the
+ out-of-resource-card situation. Also the client is fixed. As a side
+ effect, I enabled the 2:1 trade for the AI. Applied with minor
+ changes by Bas Wijnen.
+
+2003-09-25 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * po/de.po: Fixed a translation.
+
+2003-08-14 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * server/gold.c, client/gold.c: fixed bug that gold was not taken out
+ of the bank. Added support for giving out gold during setup. Fixed
+ display of gold choosing dialog (update bank etc).
+
+2003-08-14 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * server/pregame.c server/gold.c server/server.h: gold is now also
+ given out in setup phase.
+
+2003-08-14 Bas Wijnen <b.wijnen at phys.rug.nl>
+ * client/themes/Iceland/theme.cfg: Made the Iceland theme use its gold
+ tile.
+
+2003-08-14 Yusei <yusei at ragondux.com>
+ * new file client/ship_move.c; common/game.c, client/gui.c,
+ client/Makefile.am, common/common_gtk.c: Fixed truncated long lines
+ from server, added a ship move icon, added possibility to make message
+ window a fifo.
+
+2003-08-09 Roland Clobus <rclobus at bigfoot.com>
+ * client/player.c: Keep showing the names and scores of disconnected
+ players. Now you can see the scores of the other players at the end
+ of the game.
+
+2003-08-03 Roland Clobus <rclobus at bigfoot.com>
+ * client/client.c, client/client.h, client/develop.c, client/player.c,
+ client/player.h, client/resource.c: Fixed bug 600765. The client can
+ now play several consecutive games, restart is not needed anymore.
+
+2003-08-02 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * new files client/gold.c, client/gold.png, server/gold.c,
+ server/seafarers-gold.game; configure.in, client/Makefile.am,
+ client/admin-gtk.c, client/client.c, client/client.h, client/gui.c,
+ client/gui.h, client/guimap.c, client/legend.c, client/resource.c,
+ client/theme.c, client/theme.h, common/map.c, common/map.h,
+ common/network.h, po/Makefile.in.in, server/Makefile.am,
+ server/glib-driver.c, server/gnocatan-server.c, server/player.c,
+ server/pregame.c, server/resource.c, server/server.h, server/turn.c:
+ Some bugfixes, added support for gold terrain. Set version to 0.8.0
+ due to changes in the protocol.
+
+2003-07-26 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * ai/client.c, ai/player.c, ai/player.h, client/build.c,
+ client/client.c, client/client.h, client/gui.c, client/guimap.c,
+ client/player.c, client/player.h, client/turn.c, common/buildrec.c,
+ common/map.h, common/map_query.c, common/state.c, server/buildutil.c,
+ server/server.h, server/turn.c: Added sailing of ships.
+
+ * Fixed bug that ships may disappear on reconnect.
+
+2003-07-19 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * ai/greedy.c: Fixed ai building bug 772865
+
+ * server/gnocatan-server-gtk.c, server/meta.c, server/server.h:
+ Added "Send hostname" for metaserver to allow masqueraded hosts to
+ show correctly (they need a forwarded port).
+
+ * server/player.c, server/pregame.c: Fixed bug 770314.
+
+ * common/map_query.c: New longest road algorithm, fixes bugs
+ #762927 and #774107.
+
+2003-07-04 Bas Wijnen <b.wijnen at phys.rug.nl>
+
+ * client/gui.c: Added hotkey support for standard actions
+
+2003-05-31 Jeff Breidenbach <jab at debian.org>
+
+ * Security fixes courtesy of Bas Wijnen
+
+2003-02-21 Jeff Breidenbach <jab at debian.org>
+
+ * debian/rules: Adjusted .deb build rules to Steve's suggestion.
+ Allows debuild to run from pristine CVS checkout while still
+ allowing debian/ tweakers to avoid some build latency.
+
+2003-02-14 Andy Heroff <aheroff at ameritech.net>
+
+ * server/player.c: Fixed several GList usage issues in player
+ reconnection code. Need to always store the return value from
+ an append or remove, also don't need to allocate a list node
+ when the GList pointer is NULL. NULL is considered the empty
+ list value.
+
+ * server/turn.c: Check for NULL player when trying to hand out
+ resources after a roll. We can run into this if a player drops
+ and a roll occurs while he is disconnected. Fixes bug 621358,
+ but creates bug 686956.
+
+2003-02-13 Andy Heroff <aheroff at ameritech.net>
+
+ * Batch fix of bugs 205475, 480328, 482336, 482744. Cleaned up
+ compiler warnings.
+
+ * ai/ai.c: Removed goto. Added warning when the computer names file
+ can't be found.
+
+ * server/gnocatan-server-console.c: Added printing of usage
+ information if attempt to start server returns FALSE.
+
+ * server/gnocatan-server.c: Added missing CR to log message. Changed
+ g_error call to g_critical call when game params are not found to
+ prevent server from exiting at that point, also allowing the call
+ to return FALSE in that case.
+
+2003-02-11 Andy Heroff <aheroff at ameritech.net>
+
+ * server/trade.c: Fixed SF bug 660814 regarding server crash during
+ trading. Wrong quote list nodes were being deleted when a new
+ quote was issued which removed a request for a resource for which
+ there was already a quote on the table.
+
+2003-01-24 Steve Langasek <vorlon at debian.org>
+
+ * client/settingscreen.c, po/gnocatan.pot, po/de.po: fix misspelling.
+
+ * po/es.po: translation improvements. Although only 60% of the
+ gettext strings are translated, the game is now almost
+ completely playable in Spanish.
+
+ * debian/rules: tweak Debian build script so that we can skip
+ certain developer-only tasks, and so we don't end up with an
+ extra changelog in the directory.
+
+2003-01-23 Steve Langasek <vorlon at debian.org>
+
+ * client/connect.c, common/meta.h: automatically upgrade the
+ metaserver setting to one that works if the old metaserver is
+ saved in the client settings.
+
+2003-01-21 Steve Langasek <vorlon at debian.org>
+
+ * client/client.h, client/resource.c, client/monopoly.c,
+ client/player.c: use caller-provided buffer for
+ resource_cards(), to eliminate the previous kludge :)
+
+2003-01-21 Roman Hodek <roman at hodek.net>
+
+ * po/de.po: Fixed a few German translations after Steves changes
+ below.
+
+ * client/resource.c (resource_cards): let it use two alternating
+ static buffers, because this function is sometimes called twice as
+ function argument.
+
+2003-01-21 Steve Langasek <vorlon at debian.org>
+ * client/client.c, client/client.h, client/player.c,
+ client/resource.c, client/trade.c: extensive reworking of
+ string handling for better i18n support. The code still needs
+ some work to not depend on English-style plural rules, but the
+ game should now be sanely translatable to a wide range of
+ languages.
+
+ * po/de.po, po/es.po, po/gnocatan.pot: update the Spanish and
+ German translations in accordance with the above.
+
+2003-01-19 Roman Hodek <roman at hodek.net>
+
+ * po/gnocatan.pot: rebuilt
+
+ * po/de.po, po/es.po: updated from new .pot; de is fixed already
+ (not many changes...), es still needs more translations
+
+ * ai/greedy.c: AI chat spelling fixes by Tril <tril at tunes.org>
+
+ * client/trade.c (is_domestic_trade_allowed): patch by Tril
+ <tril at tunes.org>: allow trade even if nobody has the resource in
+ question, in case somebody wants to give away for free :)
+
+ * gnocatan.spec: applied patch by Daniel Jensen
+ <jensend at iname.com>, adding manpages and fixing images (release 3)
+
+2003-01-16 Steve Langasek <vorlon at debian.org>
+ * common/meta.h, meta-server/meta-report: change to using
+ gnocatan.debian.net as the default metaserver instead of
+ the defunct term1.dccs.com.au.
+
+2003-01-15 Jeff Breidenbach <jab at debian.org>
+
+ * themes.c: incorporate string terminator patch from Hal Eisen
+
+2003-01-15 Steve Langasek <vorlon at debian.org>
+ * gnocatan.spec: RPM packaging updates from Daniel Jensen
+
+2003-01-14 Steve Langasek <vorlon at debian.org>
+ * client/Makefile.am: add an explicit dependency on authors.h to
+ make sure it's generated when we need it.
+
+2003-01-12 Jeff Breidenbach <jab at debian.org>
+
+ * AUTHORS: adjust my email
+
+2003-01-12 Steve Langasek <vorlon at debian.org>
+ * ai/Makefile.am: don't link GNOME libs for a binary that has
+ no gui.
+
+2003-01-11 Steve Langasek <vorlon at debian.org>
+ * client/Makefile.am, client/guimap.c, client/theme.c,
+ debian/rules: further refine the placement of image files.
+
+ * configure.in, ai/client.c, ai/develop.c, ai/player.c,
+ ai/resource.c, client/chat.c, client/client.c,
+ client/develop.c, client/player.c, client/resource.c,
+ client/settingscreen.c, po/de.po, po/es.po, po/gnocatan.pot:
+ Gettext enhancements: don't construct strings by
+ concatenation, don't mark strings for translation with _N()
+ that are non-translatable (such as '%s').
+ Add Spanish to the list of supported languages and begin
+ localizing.
+ Revert accidental breakage of the de.po file.
+
+ * server/Makefile.am, server/gnocatan-server-gtk.c:
+ fix the directory lookup for game themes
+
+2003-01-10 Steve Langasek <vorlon at debian.org>
+ * docs/Makefile.am, docs/gnocatan.6, docs/gnocatan-server-gtk.6,
+ docs/gnocatan-server-console.6, Makefile.am, configure.in,
+ docs/.cvsignore, debian/gnocatan-server-console.files,
+ debian/gnocatan-server-gtk.files, debian/rules: add
+ preliminary manpages.
+
+ * debian/gnocatan-server-console.undocumented,
+ debian/gnocatan-server-gtk.undocumented,
+ debian/gnocatan-client.undocumented:
+ Not undocumented anymore.
+
+2003-01-09 Steve Langasek <vorlon at debian.org>
+ * AUTHORS, client/Makefile.am, client/gui.c, po/gnocatan.pot,
+ po/de.po: bring the AUTHORS file up-to-date, and autogenerate
+ the about box list from this file.
+
+ * client/Makefile.am: s/pixmap_DATA/image_DATA/, to please
+ automake.
+
+2003-01-08 Steve Langasek <vorlon at debian.org>
+
+ * client/theme.c: use a more portable variadic macro
+ syntax, to address OS X concerns
+
+ * server/gnocatan-server.desktop, server/Makefile.am: add a
+ GNOME desktop entry for the GTK server, so it's easier to
+ start from the menu.
+
+ * ai/Makefile.am, client/Makefile.am, common/gnocatan-path.h.in,
+ server/Makefile.am, debian/dirs, debian/gnocatan-ai.files,
+ debian/gnocatan-server-data.files, debian/rules, gnocatan.spec,
+ server/gnocatan-server.c: move /usr/share/gnocatan to
+ /usr/share/games/gnocatan, per the FHS; move
+ things-that-are-not-pixmaps out of /usr/share/pixmaps.
+
+2003-01-01 Jeff Breidenbach <jab at debian.org>
+
+ * debian/gnocatan-meta-server.init: privilige reduction
+
+ * debian/control: adjust dependencies, add co-maintainers.
+
+ * debian/changelong: prepare for upload to Debian
+
+2002-12-25 Roman Hodek <roman at hodek.net>
+
+ * configure.in: Some changes to make it work with autoconf2.50 and
+ automake-1.7.
+ Set version to 0.7.1.90 [internal snapshot]
+
+ * depcomp, po/ChangeLog: new
+
+ * acconfig.h: removed obsolete file
+
+ * Makefile.am (distclean-local): remove some more stuff
+
+ * gnocatan.spec: applied patch by Brian Wellington
+
+ * client/player.c (player_has_quit): remove player also from
+ internal list for a more meaningful message on reconnection.
+
+ * server/player.c, server/pregame.c, server/server.h: remove
+ redundant is_game_full variable and replace by
+ game->num_players == game->params->num_players
+
+ * server/player.c (player_revive): send an explicit note to
+ players that a reconnection has happened
+
+ * server/player.c (player_set_name): explicitly tell if name was
+ already in use and so why one is 'anonymous'
+
+2002-07-22 Roman Hodek <roman at hodek.net>
+
+ * client/Makefile.am (install-data-hook): fix silly thinko.
+
+2002-07-21 Roman Hodek <roman at hodek.net>
+
+ * 0.7.1 released!!
+
+ * debian/changelog, gnocatan.spec: bump version number to 0.7.1.
+
+ * client/gui.c (menu_settings_cb): use GTK_EXPAND attribute in x
+ dir (looks better). Delay signal_connect calls for language
+ buttons to avoid gtk assertation failures.
+
+ * client/Makefile.am: omit CVS dirs for theme file installing and
+ exporting
+
+ * client/help/C/Makefile.am: $(DESTDIR) was missing
+
+2002-07-09 Roman Hodek <roman at hodek.net>
+
+ * ai/greedy.c: Introduce better, situation-related chat messages.
+
+ * ai/client.c (client_chat): obey chatty parameter, call
+ computer_funcs.chat() with occasion parameters
+
+ * ai/client.c: added hooks for client_chat()
+
+ * ai/client.h, ai/computer: changed prototypes for client_chat()
+ et al.
+
+ * po/de.po: updated
+
+2002-07-06 Jeff Breidenbach <jeff at jab.org>
+
+ * debian/rules: package upstream changelog, readme
+
+2002-07-06 Roman Hodek <roman at hodek.net>
+
+ * theme.c, theme.h: new files for theme handling
+
+ * client/Makefile.am: added theme.[ch], added hook for installing
+ theme data
+
+ * client/gnocatan.c: call init_themes()
+
+ * client/gui.c (menu_settings_cb, settings_apply_cb): new option
+ menu to select theme added to setting dialog
+
+ * client/guimap.c: in many places replace hardcoded pixmaps/colors
+ by what's defined in current theme
+
+ * client/guimap.h: New parameter 'terrain' for draw_dice_roll().
+
+ * client/histogram.c: pass new parameter to draw_dice_roll().
+
+ * po/de.po: updated
+
+2002-06-19 Jeff Breidenbach <jeff at jab.org>
+
+ * debian/rules: adapt to non-temporary Makefile.in files
+
+2002-06-17 Roman Hodek <roman at hodek.net>
+
+ * ai/ai.c (main): result of getopt must be stored in an int.
+
+ * client/connect.c (connect_create_dlg): saved_meta_server must be
+ strdup-ped if coming from env or fixed str.
+
+2002-06-12 Jeff Breidenbach <jab at debian.org>
+
+ * debian/control: package description tweaks
+
+2002-06-09 Roman Hodek <roman at hodek.net>
+
+ * ai/greedy.c (greedy_consider_quote, trade_desired), ai/trade.c,
+ ai/client.c: new functions to make AI respond to trade requests;
+ maybe not really clever yet, but at least a start.
+ Again removed some unnecessary printf()s.
+
+ * ai/greedy.c (best_road_to_road_spot): don't set up roads on sea.
+
+ * ai/client.c (mode_year_of_plenty): send plenty selection _after_
+ receiving what is in bank to avoid protocol error.
+
+ * client/client.c (mode_game_over): accept all messages in
+ mode_game_over to avoid error messages.
+
+ * client/monopoly.c: added #include "config.h" before gnome.h to
+ make gettext work
+
+ * common/state.c (sm_pop_all_and_goto): new func to avoid
+ undefined state after sm_pop_all().
+
+ * client/client.c (check_other_players): when receiving game won
+ message, use sm_pop_all_and_goto(), otherwise it can happen that
+ the NET_CLOSE event is already received during processing of the
+ sm_goto() and the state is undefined and an assertation fails.
+
+ * server/gnocatan-server.c (cfg_set_*): check for params != NULL.
+
+2002-06-07 Jeff Breidenbach <jab at debian.org>
+
+ * debian/contol: merge debian packaging update
+
+2002-06-06 Roman Hodek <roman at hodek.net>
+
+ * configure.in, acconfig.h: export ALL_LINGUAS to config.h
+
+ * client/i18n.[ch]: new files for language setting handling
+ handles available languages, initializing NLS from saved setting
+ or environment, and changing language
+
+ * client/Makefile.am: added i18n.[ch]
+
+ * client/gnocatan.c (main): call init_nls() instead of doing stuff
+ itself
+
+ * client/gui.c: make settings dialog have separate pages, now that
+ the number of setting grows...
+ new page for language setting (TODO: dynamic GUI switch!)
+
+ * po/de.po: updated
+
+2002-06-03 Roman Hodek <roman at hodek.net>
+
+ * client/gui.c (splash_build_page): use a viewport widget around
+ the splash pixmap to avoid it is drawn over the tab area if space
+ is too small for it.
+
+ * po/.cvsignore, intl/.cvsignore: new
+
+2002-06-02 Roman Hodek <roman at hodek.net>
+
+ * configure.in: bumped version to 0.7.1 (prelim.), enabled NLS
+
+ * client/chat.c (chat_set_focus): new function to grab focus for
+ chat entry window (to not have to type on it all the time...)
+ client/client.c: call chat_set_focus in various places
+
+ * everywhere: run gettextize to create po/ subdir, change
+ configure.in and Makefiles for gettext, created German
+ translation, add more _() marks in a bunch of places, include
+ config.h where needed before gnome.h
+
+ * ai/client.c: one more exit fix, remove some unnecessary printfs.
+
+ * ai/*.c: started to prepare AI player for domestic trade
+
+ * client/histogram.c: Force histogram_dlg and table to NULL if
+ dialog is closed.
+
+ * maintained */.cvsignore
+
+2002-05-31 Roman Hodek <roman at hodek.net>
+
+ * meta-server/gnocatan-meta-server.c (client_create_new_server):
+ revert -m localhost to -r
+
+2002-05-28 Andy Heroff <aheroff at ameritech.net>
+
+ * client/chat.c: Fixed parsing of /me command in chat.
+
+2002-05-27 Roman Hodek <roman at hodek.net>
+
+ * 0.7.0 released!!
+
+ * configure.in, gnocatan.spec, debian/changelog: bumped version to
+ 0.7.0.
+
+ * server/pregame.c, ai/greedy.c, common/map_query.c: catched a
+ bunch of NULL pointer accesses revealed by 'The Pond' that isn't
+ totally surrounded by sea.
+
+ * INSTALL, README: modernized a bit
+
+ * server/Makefile.am: added $(includedir) to INCLUDES so that
+ gdk_imlib.h is found in all cases.
+
+2002-05-24 Roman Hodek <roman at hodek.net>
+
+ * configure.in: set default prefix to output of gnome-config
+ --prefix (if available)
+
+ * common/Makefile.am: new rule to generate gnocatan-path.h from
+ gnocatan-path.h.in with datadir and bindir substituted
+
+2002-05-23 Roman Hodek <roman at hodek.net>
+
+ * client/histogram.c: if new value is registered, update the
+ graph; this revealed that the drawing worked only by incident, the
+ curve area overlayed the bars... solution was to draw bars and
+ curve in the same expose callback.
+
+ * common/common_gtk.c (check_gtk_widget): Work around a GTK bug:
+ if mouse is inside a toolbar button that becomes sensitive (e.g.
+ the "Roll Dice" button), you had to move out and in the mouse
+ before you could click.
+
+ * server/gnocatan-server-console.c (main): added new option -m to
+ set meta server name
+
+ * server/gnocatan-server-gtk.c (build_interface): added new field
+ for meta server name
+
+ * server/meta.c: make name of meta server to connect to a global var
+
+ * client/connect.c (create_server_dlg): remove "start server"
+ button in create server dialog, and use standard OK/Cancel buttons
+ instead. (I finally found out how to do this :)
+
+2002-05-22 Roman Hodek <roman at hodek.net>
+
+ * client/gui.c: new option to show legend as a page besides the
+ map (someone with lack of screen space for the dialog suggested
+ that)
+
+ * client/legend.c (legend_create_content): separated out from
+ legend_create_dialog so legend page can use same code
+
+ * client/gui.c: two new checkboxes in the settings dialog to
+ disable use of colors in the message window and player summary.
+
+ * common/common_gtk.c (log_set_func_message_color_enable): new
+ interface to en/disable colors in message window
+ (message_window_log_message_string): if msg_colors is false, use
+ black
+
+ * client/player.c (player_modify_statistic): obey
+ color_summary_enabled
+
+2002-05-21 Roman Hodek <roman at hodek.net>
+
+ * client/help/C/gnocatan.sgml: Updated with respect to recent
+ developments/changes, updated some images to match current
+ looking.
+
+ * meta-server/gnocatan-meta-server.c (client_create_new_server):
+ Pass full hostname to created servers in environment. Otherwise
+ the server will register to the meta-server as running on
+ "localhost" and it won't be reachable from outside.
+
+ * debian/gnocatan-ai.menu: Fix typo ('-' too much again)
+
+ * debian/gnocatan-meta-server.conffiles: init.d files is a conffile
+
+2002-05-20 Jeff Breidenbach <jab at debian.org>
+
+ * Fix splash screen packaging bug.
+
+2002-05-20 Roman Hodek <roman at hodek.net>
+
+ * client/gui.[ch], client/client.c: on startup show a splash
+ screen that disappears on the first connect. Image contributed by
+ Tobias Jakobs.
+
+ * client/gui.c (help_about_cb): collected more names from
+ the ChangeLog and added them to the about box.
+
+ * client/histogram.c: paint chips as x axis labelling like on map;
+ probability is a triangle rather Gaussian!! fix drawing.
+
+ * client/guimap.c (display_hex): separate out drawing of dice chip
+ into draw_dice_roll (needed by histogram also now).
+
+ * ai/client.c (global_filter): if net connection was close, print
+ message and exit.
+
+ * client/client.c (global_filter): likewise, but set status to
+ offline.
+
+ * client/histogram.c: added y axis labelling, draw normal
+ distribution
+
+ * server/server.c (new_computer_player): close inherited fd's, use
+ _exit normally to avoid GTK atexit procedures running.
+
+ * deian/gnocatan-ai.menu: fix typo
+
+2002-05-19 Roman Hodek <roman at hodek.net>
+
+ * Release 0.6.99 here as beta for 0.7.0.
+
+ * client/connect.c (build_create_interface): new spin for number
+ of ai players.
+
+ * ai/ai.c (random_name): don't open computer_names in rw mode;
+ added srand to avoid rather likely case that two ai players
+ started closely together choose the same name.
+
+ * server/player.c: made tournament mode work;
+ Added PB_SILENT mode for player_broadcast.
+
+ * server/server.c (new_computer_player): new argument 'server'
+ (for completeness), simplify a bit, start a second child to avoid
+ zombies
+
+ * server/gnocatan-server-console.c: new -c option to start a
+ number of computer players
+
+ * meta-server/gnocatan-meta-server.c (client_create_new_server):
+ parse number of ai players and pass it on to server
+
+ * ai/Makefile.am: remove admin-gtk stuff, obviously copied from
+ client/Makefile.am
+
+ * Makefile.am (dist-hook): added spec file, autogen.sh, and debian
+ files to dist tarball
+
+ * server/Makefile.am: added new games
+
+ * common/Makefile.am: added gnocatan-path.h
+
+ * client/help/C/Makefile.am (dist-hook): add images to dist tarball
+
+ * gnocatan.spec: best-effort try to implement same sub packages
+ scheme as for Debian, but untested
+
+ * debian/control: added Recommends: gnocatan-ai to both server
+ packages, as they can start ai clients
+
+2002-05-16 Roman Hodek <roman at hodek.net>
+
+ * client/chat.c (chat_parser): Fix /me.
+
+ * meta-server/gnocatan-meta-server.c (client_create_new_server):
+ Emit an syslog error message if server cannot be exec-ed.
+
+ * Make everything compile also with -Werror.
+
+ * debian subdir:
+ New package layout:
+ - merge -data into -client, data are too small to justify a
+ separate Arch: all package
+ - split -server into -server-gtk, -server-console (much less
+ dependencies!), and -server-data (common stuff)
+ - new -meta-server and -ai packages
+ A few debian/rules cleanups.
+
+2002-05-13 Roman Hodek <roman at hodek.net>
+
+ * client/connect.c (show_waiting_box, close_waiting_box): new
+ dialog box indicating the we're waiting for an answer from a meta
+ server
+ add net functions for querying meta server about game types and
+ creating a new server
+ (meta_notify): parse welcome line for protocol version, send own
+ version, parse proto 1.0 data
+ (create_server_dlg): new dialog for creating a new game server via
+ meta server
+ (create_meta_dlg): add proto 1.0 data (victory points, sevens
+ rule) and a button to create a new server (if proto >= 1.0)
+
+ * client/client.c: implemented server notes (not used yet).
+
+ * client/chat.c: implemented IRC-compatible /me.
+
+ * ai/ai.c: use gnocatan-path.h
+
+ * server/player.c (check_versions): ignore rightmost number (after
+ final '.') because patchlevel changes shouldn't make protocol
+ incompatible, otherwise simplify
+ (mode_bad_version, mode_game_full): send ERR to client
+ (mode_global): call start_timeout
+
+ * server/server.c (game_server_start): pass Game* to
+ meta_send_details
+ implemented timeout to exit server after some time without
+ players.
+
+ * server/server.h (struct Game): add client_version
+ (prototypes): pass Game* to meta_send_details
+
+ * server/gnocatan-server.h: use gnocatan-path.h
+
+ * server/meta.c (meta_send_details): send proto 1.0 data if server
+ can take it, need Game* as argument for current number of players
+ (meta_event): parse welcome message for version, send own version
+ generally pass Game* instead of GameParams* to meta_send_details
+
+ * server/gnocatan-server.c (cfg_set_timeout): new
+
+ * server/gnocatan-server-console.c (main): new options -k (kill
+ server after some with no players), -T (terrain type),
+ remove unneeded optarg for -r
+ (usage): clean up
+
+ * meta-server/gnocatan-meta-server.c (struct Client): add
+ protocol_{major,minor}
+ (client_list_servers): send more data for proto 1.0 clients
+ (client_list_types): new function to list available game types
+ (client_create_new_server): new function to start a game server on
+ client request
+ (try_make_server_complete): cope with proto 0 clients
+ (client_process_line): process proto 1.0 requests and version info
+ coming from client
+ (select_loop): call new reap_children to get rid of zombie servers
+ (setup_accept_sock): loop over addrinfos to not miss the IPv4 one :)
+ (setmyhostname): new, hostname needed when starting a server
+ (general): undefine LOG
+ (general): do some logging via syslog
+
+ * meta-server/meta-report: New calling syntax:
+ meta-report [request [server [protocol]]]
+ defaults: request=client, server=$GNOCATAN_META_SERVER, protocol=1.0
+
+ * meta-server/Makefile.am: also include from common/
+
+ * common/network.c:
+ (write_ready, net_write): protect against closed sessions.
+ PF_UNSPEC cleaner than AF_UNSPEC.
+ Undefine LOG.
+
+ * configure.in: introduce META_PROTOCOL_VERSION,
+ bump version to 0.6.99 (beta for 0.7.0)
+
+ * acconfig.h: added META_PROTOCOL_VERSION
+
+2002-05-06 Roman Hodek <roman at hodek.net>
+
+ * ai/greedy.c, ai/client.h: Fix "no prototype for foobar" warnings
+ by introducing some statics and a new prototype.
+
+ * Merged in latest Debian version (0.6.1-6), including:
+ - IPv6 support by using getaddrinfo()
+ - my connect dialog changes that add a new field for naming the
+ meta server to contact
+
+ * Added new games in server/, contributed by <piman at sacredchao.net>:
+ canyon.game conquest.game pond.game square.game star.game x.game
+ And one extended by me to have ports:
+ conquest+ports.game
+
+2002-03-10 Steve Langasek <vorlon at dodds.net>
+
+ * clean up the SGML handling so that it matches the behavior of
+ the Debian tools (which everyone seems to be using).
+
+2002-03-10 Andy Heroff <aheroff at ameritech.net>
+
+ * Modified call to execv, as per SF bug 482743.
+
+2002-03-10 Steve Langasek <vorlon at dodds.net>
+
+ * Begin cleaning up the source to make it usable again.
+ * Bump the protocol version, since, well, that's what you're
+ supposed to do when you change the bloody protocol.
+
+2001-05-29 David Fallon <davef at tetsubo.com>
+
+ * Added Geoff Hanson's <gwhizz at usa.net> reconnect patch. The short version
+ of how this works is when someone disconnects, instead of the usual
+ cleanup, player_archive is called which saves the names of the
+ disconnected individuals. On all connects, the player name is
+ searched for to see if this is a player that has been archived,
+ and if so, the player_revive function is called to bring them back.
+ There's also a new gameinfo struct that is used to pass the game
+ state back to the client. Note, if we ever have a gnocatan
+ tournament, we'll have some security problems, but that's okay as
+ there's no other security anyways.
+ * Changed client/build.c, client.c, client.h, develop.c, player.c, player.h
+ * Changed server/develop.c, discard.c, player.c, pregame.c, robber.c,
+ server.h, trade.c, turn.c
+
+2001-03-09 Matt Waggoner <matt at waggoner.com>
+
+ * One of the official rule variants for Settlers of Catan is
+ to disallow rolling a 7 on the first two rounds. This has been
+ added as a feature of gnocatan, as well as an additional variant:
+ always reroll 7s. These are accessed from the console server
+ with the "-R n" parameter (n = 0 is normal, n = 1 is no 7s on first
+ 2 turns, and n = 2 is reroll all 7s), and via radio buttons in
+ the GTK+ server.
+
+2001-03-06 Matt Waggoner <matt at waggoner.com>
+
+ * Changed some more chat text colors; added a color for the
+ beep message.
+
+2001-03-03 Dave Cole <dave at dccs.com.au>
+
+ * client/client.c: Fixed bad explanation in comment.
+
+2001-03-02 Matt Waggoner <matt at waggoner.com>
+
+ * client/connect.c: fixed a minor bug with the server MRU list.
+
+2001-03-01 Matt Waggoner <matt at waggoner.com>
+
+ * client/connect.c and client/client.c: Changed the server MRU
+ list so that it also handles the user name, not just the server
+ and port values.
+
+2001-03-01 Dave Cole <dave at dccs.com.au>
+
+ * common/state.c (sm_vnformat): Caught a segfault which appeared
+ to be a buffer overrun in sm_vnformat(). Added code to actaully
+ limit formatting to buffer length and abort if overrun to allow
+ real bug to be found.
+
+2001-02-28 David Falllon <davef at getacard.com>
+
+ * Changed client/client.h, client/gui.h, client/gnocatan.c
+ to fix misc. compiler warnings. :) It offended my sensibilities.
+
+2001-02-28 Matt Waggoner <matt at waggoner.com>
+
+ * Changed client/connect.c and client/client.c to add a "Recent
+ Servers" drop-box to the connection dialog. It saves the last
+ 100 servers connected to, moving the most recently used one
+ to the top of the list. There's not currently any way to
+ delete an entry from the list, but you can manually edit your
+ ~/.gnome/gnocatan file if you feel so inclined. Only servers
+ that you actually successfully connect to, will be added to
+ the MRU list.
+
+2001-02-27 Matt Waggoner <matt at waggoner.com>
+
+ * Changed client/gui.c to have the Game > Settings dialog box
+ include an option regarding whether or not each user's chat
+ text appears in their text color. Added a global config var
+ to client/gui.h and appropriate checking code to client/chat.c.
+
+2001-02-23 Matt Waggoner <matt at waggoner.com>
+
+ * Changed client/chat.c to intercept chat text that begins with a
+ slash. This could be the start of a general-purpose slash-command
+ syntax. The only command that is intercepted now is /beep NAME,
+ where NAME is a name of one of the players in the game. If you are
+ the player whose name is NAME, a beep sound is generated; otherwise,
+ it is ignored. The purpose of this command is for players to be
+ able to get someone's attention.
+ * Changed client/histogram.c to include number of times each value
+ was rolled, percentage of the time each value was rolled, and
+ text labels along the left side.
+
+2001-02-22 David Fallon <davef at tetsubo.com>
+
+ * Added walrusmonkey's port background patch. (SF Patch #103768)
+ I like this patch... One change might be to make the port icons
+ a little larger, but all in all, the more I use it, the more I
+ prefer it over the old tiles.
+
+ * client/guimap.c: Changes how the port background rendering works. I
+ changed the radius from 13 to 15 and the x/y offsets to make the
+ circle a bit bigger (so the "type" is easier to figure out) and
+ the 2:1/3:1 be centered. (in addition to the raw patch)
+
+2001-02-22 Matt Waggoner <matt at waggoner.com>
+
+ * Added a chat window message when someone wins.
+ In shiny purple!
+
+2001-02-16 David Fallon <davef at tetsubo.com>
+
+ * Added Jeff Breidenbach's <jeff at alum.mit.edu> histogram patch.
+ (SF Patch # 103459, 103460, 103461)
+
+ * client/Makefile.am: Added histogram.[ch] to sources
+ * client/histogram.c: Added the file - it handles the dice recording
+ and the actual histogram dialog generation
+ * client/histogram.h: Added the file - heade file for histogram.c
+ * client/gui.c - Added help_histogram_cb function, added "Dice Histogram"
+ menu option to the Help menu.
+ * client/turn.c - Added call to "dice_histogram" function to record
+ dice rolls for the histogram generation.
+
+2001-02-16 Matt Waggoner <matt at waggoner.com>
+
+ * A whole bunch of changes to various files, implementing
+ multiple message colors (i.e. resource gain messages are
+ now blue), chat messages are in the player's color,
+ a timestamp before each message in the window, and the
+ player summary box has each line in a different color
+ now!
+
+ Also note that because SourceForge is broken at the moment,
+ I was not able to make these commits using my regular account
+ (dirtside), which is why they show up under dfallon.
+
+ List of files changed:
+ * common/log.h: added several new MSG_* defines and a global
+ log_timestamp variable
+ * common/log.c: added a timestamp to each log message
+ * common/common_gtk.c: added many new colors and associated
+ those colors with the new MSG types defined in log.h
+ * client/develop.c: changed several MSG_INFO to MSG_DEVCARD
+ * client/player.h: changed the definition of the statistics struct
+ to contain a pointer to a GdkColor object
+ * client/player.c: added several new color types, associated those
+ colors with items in the statistics array, made the statistic
+ update function use the colors, and also changed many many
+ MSG_INFO messages to various other MSG types
+ * client/resource.c: changed MSG_INFO to MSG_RESOURCE
+ * client/turn.c: changed MSG_INFO to MSG_DICE
+
+2001-02-16 David Fallon <davef at tetsubo.com>
+
+ * client/build.c: Fixed SF Bug #108981
+
+2000-09-03 Jeff Breidenbach <jeff at alum.mit.edu>
+
+ * debian/gnocatan-server.menu: Fix Debian bug #70831
+
+2000-09-18 Andy Heroff <aheroff at mediaone.net>
+
+ * server/5-6-player.game: Set default number of players to 5.
+
+ * server/buildutil.c: Fixed bug where any edge build (road, ship
+ bridge) would count against total number of roads.
+
+2000-09-03 Jeff Breidenbach <jeff at alum.mit.edu>
+
+ * debian/copyright: Added link to Gnocatan website
+
+2000-08-26 Andy Heroff <aheroff at mediaone.net>
+
+ * Version 0.6.1 released!
+
+ * configure.in: Version update to 0.6.1.
+
+ * server/develop.c: In Road Building dev card code, modified code
+ so that when RB is complete, edges build during process are
+ removed from the build list. Affects ability to trade.
+
+ * server/trade.c: In domestic trade code, added check for valid
+ trade conditions (No trade before the roll, and if strict trade is
+ active, no trade after building or buying a dev card).
+
+ * client/help/C/gnocatan.sgml: Started to update help code. This is
+ by no means a finished product.
+
+2000-08-25 Jeff Breidenbach <jeff at alum.mit.edu>
+
+ * debian/control, debian/changelog: preparation for point release
+
+2000-08-24 Daniel Kobras <kobras at tat.physik.uni-tuebingen.de>
+
+ * configure.in: Fix handling of 'PROTOCOL_VERSION' so it shows
+ up as a string in config.h, not as an int.
+
+2000-08-21 Andy Heroff <aheroff at mediaone.net>
+
+ * client/settingscreen.c: Modified justifications. Added i8n calls
+ to all text.
+
+2000-08-21 Steve Langasek <vorlon at dodds.net>
+
+ * server/player.c, client/client.c, acconfig.h, configure.in:
+ Use a distinct protocol version number for client-server
+ negotiation, so that versions of the client and server that behave
+ compatibly will be able to connect to one another.
+
+2000-08-18 Andy Heroff <aheroff at mediaone.net>
+
+ * client/settingscreen.c, client/gui.c, client/client.h,
+ client/Makefile.am: Added file. Added game settings screen.
+
+2000-08-06 Jeff Breidenbach <jeff at alum.mit.edu>
+
+ * debian/control: Tweak build dependencies (Debian bug #68516)
+
+2000-08-01 Andy Heroff <aheroff at mediaone.net>
+
+ * client/gui.c: Quick change to VP target text to make less
+ ambiguous.
+
+ * server/turn.c: Added debug for 'too-many' error. In the future,
+ all errors should be unique in some way (An identifier after the
+ description) so we can track the source of bugs.
+
+2000-07-31 Andy Heroff <aheroff at mediaone.net>
+
+ * client/gui.c: Fixed resize bug once and for all. Added VP target
+ listing in the status bar.
+
+2000-07-30 Jeff Breidenbach <jeff at alum.mit.edu>
+
+ * debian/rules: Explicitly clean client/help/C/gnocatan to
+ fix Debian bug #67287 (problem with the debian build of
+ gnocatan-help). This is a non-beautiful solution.
+
+2000-07-19 Bibek Sahu <scorpio at dodds.net>
+
+ * client/client.c, client/config-gnome.c, client/config-gnome.h,
+ client/connect.c, client/gnocatan.c, client/gui.c: Abstracted
+ getting/setting configuration values to be platform-agnostic.
+ Still based on gnome-config, though; perhaps we want to stratify
+ the 'config path' into its various components?
+
+2000-07-17 Andy Heroff <aheroff at mediaone.net>
+
+ * server/turn.c, server/develop.c, server/server.h: Fixed bug in
+ which the server would not check for a player victory after a
+ road building card had been played.
+
+2000-07-09 Jeff Breidenbach <jeff at alum.mit.edu>
+
+ * debian/control: First pass at Build-Depends: field. (presumably
+ useful for the Debian autobuilders.)
+
+2000-07-08 Andy Heroff <aheroff at mediaone.net>
+
+ * client/gui.c: Changed notebook tabs from left to top to fix the
+ client resizing bug seen going in and out of trade.
+
+2000-06-23 Jeff Breidenbach <jeff at alum.mit.edu>
+
+ * debian/README.debian: removed as recommended by
+ http://www.debian.org/doc/maint-guide/ch-dother.html#s-readme
+
+2000-06-21 Andy Heroff <aheroff at mediaone.net>
+
+ * server/player.c: Fixed a bug where a player with an older client
+ that doesn't report its version would have a player number of 0.
+
+2000-06-19 Jeff Breidenbach <jeff at alum.mit.edu>
+
+ * debian/control, debian/changelog: update maintainer name,
+ version numbers for debian packages.
+
+2000-06-19 Dave Cole <dave at dccs.com.au>
+
+ * client/connect.c (connect_create_dlg): Removed code which forced
+ uppercase first character on gnome config player name.
+
+2000-06-18 Andy Heroff <aheroff at mediaone.net>
+
+ * Version 0.6.0 released for general consumption!
+
+ * client/player.c: Added a couple clauses for BUILD_BRIDGE to remove
+ compile time warnings.
+
+2000-06-18 Bibek Sahu <scorpio at dodds.net>
+
+ * configure.in, client/Makefile.am, client/gui.c: Made network
+ administration code optional in client.
+
+ * server/gnocatan-server.[ch]: Code cleanups to remove warnings.
+ Also changed some comments in gnocatan-server.h to make section
+ breaks stand out more.
+
+2000-06-18 Andy Heroff <aheroff at mediaone.net>
+
+ * debian/control, debian/rules, debian/gnocatan-server.undocumented,
+ debian/gnocatan-client.undocumented: Applied patches submitted by
+ Jeff Breidenbach to bring Debian build files up to compliance for
+ submission to the Debian release group. We're going to be a part
+ of the official distro! Yay!
+
+ * server/STATES, server/player.c, server/server.h, client/client.c:
+ Added version checking to the connect sequence. Also added
+ connection error messages.
+
+2000-06-15 Steve Langasek <vorlon at dodds.net>
+
+ * gnocatan.spec: cleaned up RedHat build to not include files twice.
+
+2000-06-15 Andy Heroff <aheroff at mediaone.net>
+
+ * Bumped version again to 0.5.6, just in case, to prepare for
+ another package release, mostly to get Gnocatan in the Debian
+ distro.
+
+2000-06-12 Andy Heroff <aheroff at mediaone.net>
+
+ * debian/gnocatan-server.files: Applied patch from Aaron Denney
+ that fixes build problems with the Debian packages.
+
+2000-06-08 Bibek Sahu <scorpio at dodds.net>
+
+ * common/network.c: changed net_write() to queue data on in-progress
+ connections. The queueing logic was already there; just fixed that
+ bit of logic.
+
+ * client/admin-gtk.c: made the system clean up after a failed
+ admin connection (same code as closing an admin connection).
+
+2000-06-07 Steve Langasek <vorlon at dodds.net>
+
+ * common/game.h: Removed redundant 'VERSION' define in header.
+ We have config.h, let's start using it.
+
+2000-06-07 Dave Cole <dave at dccs.com.au>
+
+ * client/legend.c (legend_create_dlg): Fixed segfault
+ dereferencing NULL game_params before game connection established.
+
+2000-06-06 Andy Heroff <aheroff at mediaone.net>
+
+ * Changed version number to 0.5.5 to prevent CVS users from using
+ incompatable versions.
+
+2000-06-06 Roderick Schertler <roderick at argon.org>
+
+ * client/resource.c: add a 'total' field to your list of resources.
+
+2000-06-04 Steve Langasek <vorlon at dodds.net>
+
+ * server/into-the-desert.map, server/greater-catan.map:
+ Removed old-style .map files; these have been obsoleted by the
+ .game files.
+
+2000-06-01 Steve Langasek <vorlon at dodds.net>
+
+ * gnocatan.spec: RPM layout fixed up to conform with the rest
+ of Gnome packages.
+
+2000-05-30 Bibek Sahu <scorpio at dodds.net>
+
+ * server/gnocatan-server.c: Fixed a minor bug where the game was no
+ longer being set to the first one loaded.
+
+2000-05-30 Steve Langasek <vorlon at dodds.net>
+
+ * acconfig.h, configure.in, common/map.[ch], server/server.c:
+ Added support for new glib g_rand functions. Untested.
+
+2000-05-28 Dave Cole <dave at dccs.com.au>
+
+ * client/client.c (mode_start): Goto mode_offline after
+ sm_pop_all(), prevents stack underflow.
+
+2000-05-28 Bibek Sahu <scorpio at dodds.net>
+ * client/Makefile.am client/gui.c client/gui.h client/admin-gtk.c
+ server/gnocatan-server.c: Added a basic network administration
+ interface (stole the interface from the gtk server). Needs work.
+
+2000-05-27 Steve Langasek <vorlon at dodds.net>
+
+ * common/map.c, server/server.c: Converted common/map.c to use the
+ Mersenne Twister PRNG; further tweaks in g_rand() (non)support.
+
+ * server/mt_rand.[ch], server/Makefile.am, common/mt_rand.[ch],
+ common/Makefile.am: Moved Mersenne Twister to the common/ subdir,
+ as it's needed elsewhere.
+
+2000-05-27 Andy Heroff <aheroff at mediaone.net>
+
+ * client/gui.c: Added total functionality to what is in the settings
+ dialog. What's there works. More settings will be added as needed.
+
+ * server/.cvsignore: Readded gnocatan-server to the ignore list for
+ now for those with dirty build directories. Will remove later.
+
+2000-05-27 Bibek Sahu <scorpio at dodds.net>
+
+ * server/gnocatan-server.c: added a little debugging output. Will
+ be useful soon for network configuration.
+
+ * server/Makefile.am, server/gnocatan-server.c,
+ server/gnocatan-server.h, server/gnocatan-server-gtk.c,
+ server/gnocatan-server-console.c: Made as much code as possible
+ common between the two servers. Added rudimentary network
+ administration functions.
+
+ * server/server.c: separated networking code from player connection
+ code so I could use it elsewhere w/o having to rewrite it.
+
+ * server/Makefile.am: removed line where console server was being
+ linked against common gtk code.
+
+2000-05-27 Steve Langasek <vorlon at dodds.net>
+
+ * server/server.c, server/mt_rand.[ch], server/Makefile.am,
+ configure.in: Switched to using the Mersenne Twister for our
+ PRNG; should give better dice rolls.
+
+2000-05-25 Steve Langasek <vorlon at dodds.net>
+
+ * configure.in, acconfig.h: Set up for the use of glib's grand()
+ function as a better PRNG.
+
+ * client/client.c: Squashed that nasty robber bug. If it comes
+ back to life, we know it's a roach.
+
+2000-05-22 Andy Heroff <aheroff at mediaone.net>
+
+ * server/buildutils.c: Removed longest road debug define to prevent
+ spamming the server's console. The debug code is still in there.
+
+ * client/gui.c: Built a settings dialog. It only has one setting,
+ and it doesn't work yet. That's next.
+
+2000-05-22 Roderick Schertler <roderick at argon.org>
+
+ * client/player.c: Added player's total victory points to the stat
+ window
+
+ * common/network.c: Fixed name resolution code to honor hostnames
+ that begin with a digit
+
+2000-05-18 Steve Langasek <vorlon at dodds.net>
+
+ * server/gnocatan-server-console.c: Plugged in getopt() support so
+ that the user has (some) control over the game settings in the
+ console server. Documentation later.
+
+2000-05-17 Bibek Sahu <scorpio at dodds.net>
+
+ * server/gnocatan-server-console.c: removed game_list_item_t
+ structure. The params structure stores a title, so just use that
+ instead. Original filename is not all that relevant; if it becomes
+ relevant, we can add it to GameParams later. Also added a function
+ to lookup parameters by title. Changed hash table to store/lookup
+ by string, rather than pointer address.
+
+2000-05-17 Bibek Sahu <scorpio at dodds.net>
+
+ * server/gnocatan-server-console.c: filled in global variables, and
+ added a function to stuff all the game types in a hash. This will
+ be relevant later when it can be changed over the network.
+ ----> Made the console-only server work. :-)
+
+2000-05-17 Steve Langasek <vorlon at dodds.net>
+
+ * common/driver.c, server/glib-driver.c: Finished moving glib
+ driver to the common/ subdirectory.
+
+ * common/common_gtk.c: Removed gdk-dependent input functions.
+
+ * server/gnocatan-server-console.c: Moved some initialization code
+ for the console server's UI driver into the main loop.
+
+ * server/server.h: Polished the include list to eliminate redundancies.
+
+ * common/Makefile.am: Added common_glib.c, common_glib.h to file list.
+
+ * common/common_glib.[ch]: Added generic glib driver for common
+ code.
+
+ * common/driver.h: Fixed prototypes within the UI driver to use
+ guint in place of gint.
+
+ * common/common_gtk.h: Changed __common_gui_h to __common_gtk_h.
+
+ * server/glib-driver.c: Used the G_PRIORITY_DEFAULT define in
+ place of constant as argument.
+
+2000-05-17 Bibek Sahu <scorpio at dodds.net>
+
+ * server/Makefile.am: Added glib-driver.c and glib-driver.h, which
+ are used by the console server.
+
+ * server/glib-driver.[ch]: Functions necessary for the console
+ server.
+
+ * server/gnocatan-server-console.c: Added some muscle to the
+ skeleton: Implemented some of the stuff necessary for a console
+ server.
+
+ * server/server.h: Added some headers that it depended on, so it
+ didn't scream at me when I tried to include it just for the Player
+ structure.
+
+2000-05-17 Bibek Sahu <scorpio at dodds.net>
+
+ * configure.in: added GLIB configuration.
+
+ * common/common_gtk.c, common/driver.h: Added hooks for input
+ read/write callbacks and [server] player update callbacks.
+ Actually put the input read/write callbacks into
+ common/common_gtk.c.
+
+ * common/network.c, server/server.c: Switched to using driver's
+ input read/write callbacks.
+
+ * server/server.c, server/player.c: Switched to using driver's
+ player update callbacks.
+
+ * server/Makefile.am: Added preliminary files for gui-less server.
+
+ * server/gnocatan-server.c: Connect the server player-update
+ functions.
+
+ * server/gnocatan-server-console.c: Preliminary skeleton code for
+ gui-less server.
+
+2000-05-15 Steve Langasek <vorlon at dodds.net>
+
+ * client/connect.c: Set reasonable defaults for the connect dialog
+ if there isn't a saved config (shuts up GTK, too).
+
+ * common/Makefile.am, client/Makefile.am, server/Makefile.am:
+ Changed library name from libgnocatan_gui.a to libgnocatan_gtk.a,
+ allowing for the possibility of multiple front-ends
+
+2000-05-13 Bibek Sahu <scorpio at dodds.net>
+
+ * common/driver.[ch], client/gnocatan.c, server/gnocatan-server.c:
+ Moved the global driver definition to driver.c, and added a function
+ set_ui_driver( UIDriver* ). Moved logging into the driver
+ structure. Note that the gtk driver starts by logging to the
+ console and must be told to move that to a window later on.
+
+2000-05-12 Steve Langasek <vorlon at dodds.net>
+
+ * common/common_gtk.c, common/state.c: Pulled all GTK-specific code
+ out of state.c, moving it to common_gtk.c.
+
+ * client/gnocatan.c, server/gnocatan-server.c: Changed main() loops
+ to initialize an appropriate UIDriver.
+
+ * common/state.h: Exported [inc,dec]_use_count() so that they're
+ available to the interface drivers.
+
+ * common/driver.h, common/game.h, common/state.h: Fixed some
+ header files so that they automatically include headers on which
+ they depend, instead of expecting the c file to take care of it all.
+
+ * common/driver.h, common_gtk.h: Began creating the structure for
+ independent interface drivers (GTK, console).
+
+2000-05-12 Bibek Sahu <scorpio at dodds.net>
+
+ * common/common_gui.[ch], common/common_gtk.[ch]: Renamed
+ common/common_gui.[ch] -> common/common_gtk.[ch] per Steve's
+ request. More appropriate, considering its function.
+
+2000-05-12 Steve Langasek <vorlon at dodds.net>
+
+ * common/state.[ch], server/buildutil.c, server/develop.c,
+ server/discard.c, server/meta.c, server/player.c, server/pregame.c,
+ server/resource.c, server/robber.c, server/server.c, server/trade.c,
+ server/turn.c: Made the 'widget' within the StateMachine an opaque
+ pointer, so that code that depends on the StateMachine is not bound
+ to any one GUI.
+
+ * configure.in, meta-server/gnocatan-meta-server.c:
+ Included autoconf fix for cross-platform getopt support
+
+2000-05-12 Bibek Sahu <scorpio at dodds.net>
+
+ * Moved the common gui stuff into a separate library, so a non-gui
+ program won't depend on the gui functions.
+
+2000-05-12 Dave Cole <dave at dccs.com.au>
+
+ * client/client.c, common/state.c, common/state.h,
+ server/develop.c, server/discard.c, server/player.c,
+ server/pregame.c, server/robber.c, server/trade.c, server/turn.c:
+ Removed all of the sm_resp_{ok,err,handler}() API from the state
+ machine. Simplified each entry on the state stack down to a
+ single StateFunc. Modified client state machine to use simplified
+ state machine API.
+
+ * client/client.c, client/trade.c, client/turn.c: Fixed (untested)
+ bug where could not trade after playing road building card before
+ rolling dice. Altered is_maritime_trade_allowed() to look at the
+ strict_trade flag.
+
+2000-05-12 Bibek Sahu <scorpio at dodds.net>
+
+ * Completely rewrote logging setup. It's now very modular in
+ design, and the main logging stuff does not depend on gtk/gnome
+ (which is the reason it was done). Most files that did logging were
+ moderately modified -- the following functions were converted:
+ log_error(...) -> log_message( MSG_ERROR, ... )
+ log_info(...) -> log_message( MSG_INFO, ... )
+ log_color(...) -> log_message( MSG_CHAT, ... )
+
+ * The client's initialization sequence now logs to the console until
+ all the windows are set up, then switches logging to the message
+ window. This is step 1 on the road to a server that doesn't require
+ a gui...
+
+2000-05-11 Dave Cole <dave at dccs.com.au>
+
+ * client/client.c, common/state.[ch]: Removed all of the resphook
+ from the state machine API code and replaced it with some wrappers
+ to sm_resp_{ok,err,handler}() in client.c. First stage in
+ reducing the client state machine complexity. Moved a lot of code
+ around in client.c in an effort to partition the functionality so
+ the stack overflow bug can be found.
+
+2000-05-10 Steve Langasek <vorlon at dodds.net>
+
+ * common/buildrec.c, common/cards.c, common/cost.c, common/game.c,
+ common/map.c, common/map_query.c, common/network.c, common/quoteinfo.c,
+ common/state.c, server/buildutil.c, server/develop.c, server/discard.c,
+ server/meta.c, server/player.c, server/pregame.c, server/resource.c,
+ server/robber.c, server/server.c, server/trade.c, server/turn.c:
+ Removed <gnome.h> includes where they aren't necessary, to ease the
+ transition to a gui-less or gtk-only server.
+
+ * common/log.h: Internationalization definitions handled internally,
+ so we don't have to include <gnome.h> to get them.
+
+2000-05-08 Dave Cole <dave at dccs.com.au>
+
+ * common/map.h: Changed the visited attribute in Edge and Node to
+ gint for new longest road algorithm.
+
+ * common/map_query.c: Implemented new longest road algorithm which
+ can handle edge cycles.
+
+ * server/develop.c: Fixed "ERR wrong-plenty" bug. Was using
+ variable before it received a value in resource_available().
+
+2000-05-07 Andy Heroff <aheroff at mediaone.net>
+
+ * common/log.c, common/log.h: Added log to console if use_console
+ boolean is set by call to log_set_use_console_bool().
+
+2000-05-07 Dave Cole <dave at dccs.com.au>
+
+ * common/cost.c: Fixed cost of bridges.
+
+ * client/legend.c: Show cost of ships and bridges when
+ appropriate.
+
+ * client/setup.c: Check num_build_type[] in setup_can_build_*().
+
+2000-05-06 Dave Cole <dave at dccs.com.au>
+
+ * client/Makefile.am: Added bridge.png, removed ship_building.c
+
+ * gnocatan.spec, debian/gnocatan-server.files,
+ server/four-islands.game: Added basic Seafarers game and
+ bridge.png.
+
+ * client/road.png: Rotated road bitmap to match drawing in
+ identity panel.
+
+ * client/bridge.png: Added bridge bitmap.
+
+ * client/build.c, client/stock.c, client/turn.c,
+ client/identity.c: Added bridge support.
+
+ * client/client.c: Added bridge support. Fixed setup statusbar
+ prompts. Merged road/ship/bridge setup code. Fixed road building
+ development to allow ships and bridges and removed ship building
+ development.
+
+ * client/ship_building.c: Deleted file - code was obsolete.
+
+ * client/client.h, client/develop.c: Fixed road building
+ development to allow ships and bridges and removed ship building
+ development.
+
+ * client/gui.c: Added bridge toolbar button.
+
+ * client/guimap.c, client/guimap.h: Added polygon for bridge
+ shape. Added bridge drawing and cursor BRIDGE_CURSOR.
+
+ * client/road_building.c: Fix road building to build ships and
+ bridges in games which use them.
+
+ * client/setup.c: Add support for ships and bridges in games which
+ use them.
+
+ * common/buildrec.c: Almost complete rewrite/restructure to fix
+ setup support for ships and bridges.
+
+ * common/buildrec.h: Added buildrec_get_edge()
+
+ * common/cost.c, common/cost.h: Added cost_bridge().
+
+ * common/game.c (params_load_finish): Set have_bridges flag in map
+ if game with bridges.
+
+ * common/game.h: Removed DEVEL_SHIP_BUILDING.
+
+ * common/map.c, common/map.h: Added map pointer to owner Map in
+ Hex, Node, and Edge structures.
+
+ * common/map.h, common/map_query.c: Added
+ node_has_ship_owned_by(), node_has_bridge_owned_by(),
+ can_bridge_be_setup(), can_bridge_be_built(),
+ map_can_place_bridge(), map_bridge_vacant(),
+ map_bridge_connect_ok(). Fixed is_node_spacing_ok(),
+ is_road_valid(), can_settlement_be_built(), can_city_be_built(),
+ map_building_connect_ok() to handle bridges.
+
+ * common/state.h: Fixed comments; removed DEVEL_SHIP_BUILDING,
+ added BUILD_BRIDGE.
+
+ * server/buildutil.c, server/server.h: Merged road_add() and
+ ship_add() into edge_add() which handles bridges as well.
+
+ * server/develop.c (mode_road_building): Fixed road building to
+ support ships and bridges as well.
+
+ * server/pregame.c: Added support for bridge building.
+
+ * server/turn.c (build_add): Added bridge building support.
+
+ * server/Makefile.am: Added basic Seafarers game.
+
+2000-05-06 Andy Heroff <aheroff at mediaone.net>
+
+ * client/client.c, client/connect.c: Connect dialogue now
+ 'remembers' your last server, port, and name.
+
+2000-05-04 Andy Heroff <aheroff at mediaone.net>
+
+ * client/player.c: Modified all colors to less intense shades.
+ Changed first four colors to match those of the board game.
+
+2000-05-02 Andy Heroff <aheroff at mediaone.net>
+
+ * Project imported into the SourceForge CVS server.
+
+ * INSTALL: Added 'simple' instructions for building Debian and Red
+ Hat binary packages.
+
+ * Updated all version references to 0.5.0 for release.
+
+ * Released version 0.5.0.
+
+2000-04-28 Andy Heroff <aheroff at mediaone.net>
+
+ * client/connect.c, client/name.c: Added "<enter> closes dialog"
+ functionality to both of the above files/dialogs.
+
+ * client/chat.c, client/client.c: Added chat parser with posing (:)
+ and semi-posing (;) functionality.
+
+1999-12-22 Dan Egnor <egnor at ofb.net>
+
+ * server/STATES: Attempt at documenting the server state machine.
+
+ * server/trade.c: Fixed? a possible trade race condition. Actually,
+ the fix was already there, I just think it wasn't quite right, since
+ it didn't reset the player's state properly. This should be reviewed.
+
+ * server/5-6-player.game: New game file for 5/6 player expansion
+ (from tlau at cs.washington.edu).
+
+ * client/turn.c, server/trade.c: Implemented option to remove
+ build/trade order restriction, as per 5/6 player expansion rules
+ (from tlau at cs.washington.edu).
+
+ * server/gnocatan-server.c, meta-server/gnocatan-meta-server.c:
+ Portability fixes (e.g. for Solaris).
+
+ * client/Makefile.am, meta-server/Makefile.am, server/Makefile.am:
+ Removed silly setgid "games" from install target.
+
+ * client/help/C/gnocatan.sgml: Fixed some errors in the SGML help-file
+ source. (Too bad this help file is getting out of date anyway...)
+
+ * macros/Makefile.in: removed from CVS, since it's generated.
+
+1999-12-16 Dan Egnor <egnor at ofb.net>
+
+ * Fixed bug which prevented anyone who didn't build a ship during setup
+ from building a ship later (the check to see if the user was out of ships
+ was incorrect).
+
+ * "make dist" works now, and has the right version number.
+
+ * Fixed bug #2 (the "domestic-trade delete" bug).
+
+ * Added .cvsignore files to kill those pesky ?'s.
+
+ * client/player.c: Beep when it's your turn. Is this a good idea?
+ I know I'm often distracted and don't notice when my turn comes up.
+ It should probably be an option, but I hate to get into the business
+ of having "gnocatan preferences"...
+
+ * server/gnocatan-server.c: Fix some problems with the terrain
+ randomization toggle; clean up (?) the UI enable/disable logic some
+ (the UI is now fully disabled when you start a game).
+
+ * server/seafarers.game: Added chit placement numbers to the tiles.
+ Without this, there are no chits, which makes this map a little less
+ useful. I'm pretty sure the numbers aren't in the right places
+ (there are lots of neighboring 8's and such); I'll get out our copy
+ of Seafarers and do the right thing at some point. At least this way
+ we can start testing.
+
+ * server/server.c: setsockopt(SO_REUSEADDR) *before* bind().
+
+1999-12-16 Dave Cole <dave at dccs.com.au>
+
+ * client/gui.c: Added gui_set_game_params() to notify gui code
+ when map is available, and to pass game parameters. Hide toolbar
+ buttons that are not used in the game.
+
+ * client/identity.c: Do not display shapes that are not used in
+ the game.
+
+1999-11-20 Dave Cole <dave at dccs.com.au>
+
+ * client/guimap.c: Replaced all of the bogus hand building of
+ ships, roads, settlements and cities with a single shape for each
+ which is scaled and rotated as required.
+
+ * client/chat.c: Small code reformat.
+
+1999-09-04 Dave Cole <dave at dccs.com.au>
+
+ * gnocatan.spec, debian/gnocatan-server.files,
+ server/Makefile.am, server/small.game: Added small.game.
+
+ * server/gnocatan-server.c (build_interface): Call
+ load_game_types() to after creating all widgets.
+
+ * client/trade.c, common/game.c, common/game.h,
+ server/default.game, seafarers.game, server/trade.c,
+ server/turn.c: Added domestic_trade flag to allow domestic trading
+ to be disabled for in a game. When disabled, the domestic trading
+ GUI is not shown.
+
+ * server/robber.c (mode_place_robber): Fixed core dump in games
+ where the robber is not initially displayed (small.game).
+
+ * client/client.c, client/client.h, client/develop.c: Dynamically
+ allocate the development card deck when the game parameters have
+ been received from the server. Fixes bug where
+ DevelDeck.max_cards was not being initialised for player.
+
+ * server/develop.c, server/player.c, server/server.h: Dynamically
+ allocate the development card deck for each player when allocated.
+ Fixes bug where DevelDeck.max_cards was not being initialised for
+ player.
+
+1999-09-03 Dave Cole <dave at dccs.com.au>
+
+ * common/game.[ch]: Added params_copy() to create an independant
+ copy of a GameParams structure.
+
+ * common/map.[ch]: Added map_copy() to create an independant copy
+ of a Map structure.
+
+ * server/buildutil.c, server/develop.c, server/player.c,
+ server/pregame.c, server/robber.c, server/server.c,
+ server/server.h, server/trade.c, server/turn.c: Changed
+ game->params into a pointer to a copy of the GameParams loaded
+ from the game file. This enables the map to be reinitialised
+ properly on game restart. Removed unused game->map and use
+ game->params->map instead.
+
+ * common/map.c (layout_chits): Fixed bug which assumed that the
+ number of terrain hexes equaled the number of chits in the layout
+ sequence.
+
+ * README: Updated version number to 0.4.0
+
+ * gnocatan.spec, client/Makefile.am, server/Makefile.am,
+ debian/changelog, debian/control, debian/gnocatan-server.files:
+ Updated to include new 0.4.0 files.
+
+1999-09-02 Dave Cole <dave at dccs.com.au>
+
+ * client/client.c: Removed global Map @game_map and replaced it
+ with GameParams @game_params, which includes the game map.
+ Removed mode_map(), mode_map_load() and replaced them with
+ mode_load_game() which encapsulates the entire game loading.
+
+ * client/client.h: Removed global Map @game_map and replaced it
+ with GameParams @game_params, which includes the game map.
+
+ * client/develop.c, common/cards.[ch]: Renamed card_*() functions
+ to deck_card_*().
+
+ * client/develop.c (can_play_develop): Rearranged logic to improve
+ clarity.
+
+ * common/cards.[ch]: Added deck_new(), deck_free(). Development
+ card decks are now dynamically allocated.
+
+ * client/gui.c (gui_build_interface): Moved call to stock_init()
+ to client.c (mode_load_game).
+
+ * client/guimap.c (display_hex): Fixed inconsistent indentation.
+
+ * client/guimap.c, client/player.c, client/robber.c,
+ client/setup.c, common/buildrec.c, common/map_query.c,
+ server/buildutil.c, server/pregame.c, server/robber.c,
+ server/turn.c, common/game.h, common/map.h, server/server.h:
+ Removed EdgeType and Building enums, expanded BuildType enum to
+ describe all types of building. Renamed Node.building to
+ Node.type to be consistent with Edge.type.
+
+ * client/guimap.c: Deleted find_ship(), build_ship_regions() as
+ they were identical to find_road(), build_road_regions(). Renamed
+ find_road(), build_road_regions() to find_edge(),
+ build_edge_regions().
+
+ * client/player.[ch], client/quote.c, client/trade.c: Replaced
+ max_players/num_players() with game_params->num_players.
+
+ * client/quote.c, common/game.h, server/server.c: Replaced
+ RESOURCE_LIMIT with game_params->resource_count.
+
+ * client/stock.c, common/game.h: Replaced DEF_MAX_ROADS,
+ DEF_MAX_SHIPS, DEF_MAX_SETTLEMENTS, DEF_MAX_CITIES with
+ game_params->num_build_type[BUILD_*]. Replaced NUM_DEVELOP with
+ total of game_params->num_develop_type[].
+
+ * common/Makefile.am: Added game.c.
+
+ * common/buildrec.c (ship_has_place_for_settlement): Added check
+ is_node_on_land(). Fixed formatting of a lot of code.
+
+ * common/buildrec.h, common/map.h: Moved enum BuildType, enum
+ Terrain, enum Resources to common/map.h
+
+ * common/game.h: Removed NUM_DEVELOP. Expanded GameParams to make
+ all previously static game parameters dynamic. Added params_*()
+ functions to encapsulate GameParams loading / saving / parsing.
+
+ * server/develop.c, server/server.h: Replaced static description
+ of development card deck with dynamic description from
+ game_params.
+
+ * common/map.[ch]: Removed static chat_values[] chit layout
+ sequence and replaced it with dynamically defined sequence in
+ GameParams. Added map_set_chits() to bind a chit sequence to a
+ map.
+
+ * server/buildutil.c, server/player.c, server/turn.c: Made
+ player->num_* count the number of each type that the player has
+ built, instead of store the number of each type the player has
+ left to build.
+
+ * server/gnocatan-server.c: Almost completely reworked GUI
+ handling code.
+
+ * server/pregame.c: Removed send_game_map() as this task is now
+ performed during GameParam transfer.
+
+ * server/resource.c, server/robber.c, server/server.h,
+ server/trade.c: Removed obsolete FIND_STUPID_RESOURCE_BUG code.
+
+1999-06-29 JT <jtraub at dragoncat.net>
+
+ * server/*.c: Made sure the server reset features were correct.
+
+1999-06-16 JT <jtraub at dragoncat.net>
+
+ * server/server.c (close_player): Fixed bug where server was
+ reporting to the meta-server, players leaving the game who had
+ never joined it. It was possible to make the meta-server report
+ -ve player counts.
+
+1999-06-08 Dave Cole <dave at dccs.com.au>
+
+ * Released 0.3.3
+
+ * client/help/C/gnocatan.sgml: Updated help to include description
+ of the tick / cross in the trade list.
+
+ * client/help/C/images: Replaced trade.gif and quote.gif
+
+ * gnocatan.spec: Bumped version number and added new pixmap files.
+
+ * debian/control: Fixed bogus Recommend field to be Recommends.
+ Changed gnocatan-client to depend on gnocatan-data >= 0.3.3.
+
+ * client/tick.png, client/cross.png: Added new pixmaps for
+ domestic trade list.
+
+ * client/guimap.[ch] (load_pixmap): Made function global and added
+ mask parameter to return pixmap mask from
+ gdk_imlib_load_file_to_pixmap().
+
+ * client/player.c (player_set_name): When changing player name,
+ report player by previous name when possible.
+
+ * client/quote.c (quote_finish): Do not clear quote_list, as we
+ need to be able to interpret quotes accepted even after we have
+ rejected domestic trade.
+
+ * client/quote.c (add_reject_row, remove_reject_rows): Pasted
+ these functions from trade.c. Should clean up trading code for
+ 0.4.x.
+
+ * client/trade.c (quote_trade_call, quote_trade_reject): Add
+ player rejected trade row to indicate that other players are
+ rejecting domestic trade.
+
+ * client/quote.c (quote_trade_accept): Monitor domestic trade
+ activity even after we have rejected trade. This allows us to
+ maintain correct resource counts in the player summary.
+
+ * client/trade.c (is_good_quote, load_pixmaps,
+ check_domestic_trades, trade_domestic_quote): Added pixmaps for
+ tick and cross to indicate validity of each quote from other
+ players.
+
+ * common/game.h: Bumped version number to 0.3.3.
+
+ * server/server.c, server/server.h (get_rand): Modified random
+ number generation to match the technique described in the rand()
+ man page.
+
+ * server/robber.c, server/turn.c: Use new get_rand() function for
+ all random numbers.
+
+1999-05-29 Dave Cole <dave at dccs.com.au>
+
+ * Released 0.3.2
+
+1999-05-28 Dave Cole <dave at dccs.com.au>
+
+ * ChangeLog: Started on a real ChangeLog since I just received the
+ first code contribution.
+
+ * client/chat.c (chat_cb): Strip '\n' out of message text
+
+ * client/client.c (is_player_status), client.h, client/resource.c
+ (resource_player_check), server/develop.c (monopoly_mode),
+ server/resource.c (resource_debug, resource_maritime_trade,
+ resource_end), server/robber.c (steal_card_from), server/server.h,
+ server/trade.c (domestic_initiate_mode): Added debug code to check
+ that the client and server have the same resource counts for each
+ player. This was to help find a reported bug, but no luck so far.
+
+ * client/connect.c (connect_create_dlg): Removed term1.dccs.com.au
+ as the default server host. Set input focus to the server
+ textfield on initialisation.
+
+ * client/name.c (name_create_dlg): Set input focus to the name
+ textfield on initialisation.
+
+ * client/quote.c (more_resource_cb): Limit the number of resources
+ in a quote to RESOURCE_LIMIT.
+
+ * client/trade.c (mode_domestic_response, accept_trade_cb):
+ Eliminate the trade_quote static variable.
+
+ * common/game.h: Bumped game version to "0.3.2"
+
+ * debian/changelog: Bumped game version to 0.32-1
+
+ * gnocatan.spec: Changed homepage. Bumped version to 0.32
+
+ * server/trade.c (domestic_initiate_mode): After a domestic trade
+ has been performed, remove all trades that the quoting player can
+ no longer accomodate.
+
+1999-05-23 Thomas Koester <Thomas.Koester at rz.Uni-Osnabrueck.DE>
+
+ * client/player.c (player_domestic_trade): Fixed trading where one
+ party does not supply anything
+
+1999-05-23 Preben Randhol <randhol at pvv.org>
+
+ * gnocatan.spec: Sent file to Dave for integration with
+ distribution.
Added: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am (rev 0)
+++ trunk/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,192 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# some settings
+console_cflags = \
+ -I$(top_srcdir)/common \
+ -I$(top_builddir)/common \
+ -I$(includedir) \
+ $(GLIB2_CFLAGS) \
+ $(WARNINGS) \
+ $(DEBUGGING) \
+ $(GLIB_DEPRECATION) \
+ -DDATADIR=\""$(pioneers_datadir)"\" \
+ -DTHEMEDIR=\""$(pioneers_themedir_embed)"\" \
+ -DLOCALEDIR=\""$(pioneers_localedir)"\" \
+ -DPIONEERS_DIR_DEFAULT=\""$(pioneers_datadir)/games/pioneers"\" \
+ -DPIONEERS_SERVER_CONSOLE_PATH=\""$(bindir)/pioneers-server-console"\" \
+ -DPIONEERS_SERVER_GTK_PATH=\""$(bindir)/pioneers-server-gtk"\" \
+ -DPIONEERS_CLIENT_GTK_PATH=\""$(bindir)/pioneers"\" \
+ -DPIONEERS_AI_PATH=\""$(bindir)/pioneersai"\"
+
+gtk_cflags = \
+ $(console_cflags) \
+ -I$(top_srcdir)/common/gtk \
+ $(GNOME2_CFLAGS) \
+ $(GTK2_CFLAGS) \
+ $(GTK_DEPRECATION)
+
+# The Fink port needs an explicit reference to driver.o
+console_libs = \
+ libpioneers.a \
+ $(top_builddir)/common/libpioneers_a-driver.o \
+ $(GLIB2_LIBS)
+
+gtk_libs = \
+ $(console_libs) \
+ libpioneers_gtk.a \
+ $(GNOME2_LIBS) \
+ $(GTK2_LIBS)
+
+configdir = $(datadir)/games/pioneers
+icondir = $(datadir)/pixmaps
+pixmapdir = $(datadir)/pixmaps/pioneers
+desktopdir = $(datadir)/applications
+
+# Let object files be generated in their own subdirectories
+AUTOMAKE_OPTIONS = subdir-objects
+
+# set up these variables so the included Makefile.ams can use +=
+SUBDIRS =
+bin_PROGRAMS =
+noinst_PROGRAMS =
+noinst_LIBRARIES =
+man_MANS =
+config_DATA =
+icon_DATA =
+pixmap_DATA =
+desktop_DATA =
+CLEANFILES =
+MAINTAINERCLEANFILES =
+EXTRA_DIST = autogen.sh pioneers.spec xmldocs.make omf.make README.Cygwin README.MinGW debian/changelog debian/control debian/compat debian/copyright debian/rules debian/docs
+BUILT_SOURCES =
+windows_resources_input =
+windows_resources_output =
+
+# creating icons
+%.png: %.svg
+ @mkdir_p@ $(dir $@)
+ $(svg_renderer_path) $(svg_renderer_width)48$(svg_renderer_height)48 $< $@
+
+if CREATE_WINDOWS_ICON
+# Only maintainers need to do this. It is distributed in the tarball
+%.ico: %.svg
+ @mkdir_p@ $(dir $@)
+ $(svg_renderer_path) $(svg_renderer_width)16$(svg_renderer_height)16 $< $@-p16.png
+ $(pngtopnm) $@-p16.png > $@-p16.pnm
+ pngtopnm -alpha $@-p16.png > $@-p16a.pnm
+ pnmcolormap 256 $@-p16.pnm > $@-p16colormap.pnm
+ pnmremap -mapfile=$@-p16colormap.pnm $@-p16.pnm > $@-p16256.pnm
+ $(svg_renderer_path) $(svg_renderer_width)32$(svg_renderer_height)32 $< $@-p32.png
+ pngtopnm $@-p32.png > $@-p32.pnm
+ pngtopnm -alpha $@-p32.png > $@-p32a.pnm
+ pnmcolormap 256 $@-p32.pnm > $@-p32colormap.pnm
+ pnmremap -mapfile=$@-p32colormap.pnm $@-p32.pnm > $@-p32256.pnm
+ $(svg_renderer_path) $(svg_renderer_width)48$(svg_renderer_height)48 $< $@-p48.png
+ pngtopnm $@-p48.png > $@-p48.pnm
+ pngtopnm -alpha $@-p48.png > $@-p48a.pnm
+ pnmcolormap 256 $@-p48.pnm > $@-p48colormap.pnm
+ pnmremap -mapfile=$@-p48colormap.pnm $@-p48.pnm > $@-p48256.pnm
+ ppmtowinicon -andpgms $@-p48256.pnm $@-p48a.pnm $@-p32256.pnm $@-p32a.pnm $@-p16256.pnm $@-p16a.pnm > $@
+ rm $@-p16.png
+ rm $@-p16.pnm
+ rm $@-p16a.pnm
+ rm $@-p16colormap.pnm
+ rm $@-p16256.pnm
+ rm $@-p32.png
+ rm $@-p32.pnm
+ rm $@-p32a.pnm
+ rm $@-p32colormap.pnm
+ rm $@-p32256.pnm
+ rm $@-p48.png
+ rm $@-p48.pnm
+ rm $@-p48a.pnm
+ rm $@-p48colormap.pnm
+ rm $@-p48256.pnm
+else
+%.ico: %.svg
+ @$(ECHO) Microsoft Windows icons cannot be generated
+ @$(ECHO) Run configure again with --enable-maintainer-mode
+ @exit 1
+endif
+
+if USE_WINDOWS_ICON
+# Will be used in Windows builds
+%.res: %.rc %.ico
+ @mkdir_p@ $(dir $@)
+ windres -I$(top_srcdir) -O coff -o $@ $<
+endif
+
+if BUILD_CLIENT
+include client/Makefile.am
+endif
+
+#if BUILD_SERVER
+include server/Makefile.am
+#endif
+
+if BUILD_META_SERVER
+include meta-server/Makefile.am
+endif
+
+if BUILD_EDITOR
+include editor/Makefile.am
+endif
+
+include common/Makefile.am
+include docs/Makefile.am
+include macros/Makefile.am
+
+# Make use of some of the variables that were filled in by the included
+# Makefile.ams
+MAINTAINERCLEANFILES += $(icon_DATA) $(windows_resources_output)
+EXTRA_DIST += \
+ $(man_MANS) \
+ $(desktop_DATA) \
+ $(config_DATA) \
+ $(pixmap_DATA) \
+ $(icon_DATA) \
+ $(subst png,svg,$(icon_DATA)) \
+ $(windows_resources_input) \
+ $(windows_resources_output)
+
+# po doesn't use automake, but creates its own Makefile
+SUBDIRS += po
+
+distclean-local:
+ rm -f *~
+ rm -rf autom4te.cache
+
+# This line is added, because scrollkeeper leaves many files
+# in /var/scrollkeeper, that makes 'make distcheck' fail
+distuninstallcheck_listfiles = find . -type f -print | grep -v '^\./var/scrollkeeper'
+
+# Reformat the code.
+reindent:
+ find . -name '*.[ch]' -exec indent -kr -i8 '{}' ';'
+
+restorepo:
+ svn revert po/*.po po/pioneers.pot
+
+deb: dist
+ -mkdir $(top_builddir)/debian-build
+ cd $(top_builddir)/debian-build && tar zxf ../$(top_builddir)/maemo-pioneers-0.11.3.1.tar.gz
+ cd $(top_builddir)/debian-build/maemo-pioneers-0.11.3.1 && dpkg-buildpackage -rfakeroot
+ -rm -rf $(top_builddir)/debian-build/maemo-pioneers-0.11.3.1
Added: trunk/NEWS
===================================================================
--- trunk/NEWS (rev 0)
+++ trunk/NEWS 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,183 @@
+Subversion Snapshot release 0.11.3
+* Update for the server only: resolved issues for servers that run for a long
+ time.
+
+Subversion Snapshot release 0.11.2
+* Fixed a bug: It as not possible to press the OK button when discard cards
+ after a seven was rolled
+
+Subversion Snapshot release 0.11.1
+* New languages: Afrikaans and Japanese
+* Added customizable player icons
+* Added winnable check in the server and editor
+* New game feature: city walls
+* Map preview in the server
+* Cluster development cards of the same type
+* The chat panel can be moved to the right
+* Lauch the client from the server
+* Cosmetic changes
+* Various bugfixes
+* The 0.11 server can also handle 0.10 clients
+
+Subversion Snapshot release 0.10.2
+* Added --version for all executables
+* Workaround for a Gtk+ bug
+* The metaserver unregisters inactive servers
+* The contents of the tarball is more complete
+* Various bugfixes
+
+Subversion Snapshot release 0.10.1
+* Build script updated for easier building
+* Switch between games without quitting the client
+* Victory points for discovering an island
+* More strings are translatable
+* Announce new players when they enter the game
+* Lobby + robot
+* Better handling for disconnected players
+* Register games with the correct hostname at the metaserver
+* Various bugfixes
+
+Subversion Snapshot release 0.9.64
+* Fix for the bugs introduced in 0.9.63 and 0.9.62
+
+Subversion Snapshot release 0.9.63
+* Minimum required versions: Glib 2.6, Gtk+ 2.6
+* Does not use Gtk+ 2.8 icons anymore
+
+Subversion Snapshot release 0.9.62
+* Several cosmetic changes
+* You can now choose to connect as a viewer
+* Several small fixes
+* Visual display of the resources
+* New quote tab page
+
+Subversion Snapshot release 0.9.61
+* Manual updated
+* Several small fixes
+
+Security release 0.9.55
+* Fixes the meta server for meta servers that do allow the creation of new
+ games
+
+Security release 0.9.54 [revoked]
+* Fixes crashes in the public meta server
+
+CVS Snapshot release 0.9.49
+* New theme, based on Battle of Wesnoth
+* Configure script updated
+* Added Swedish translation
+* Client and server chat length limited to safer lengths
+* Windows installer checks for the Gtk+ runtime
+* Several small bugs fixed, code cleanup
+
+CVS Snapshot release 0.9.40
+* Released Microsoft Windows Native port, requires Gtk+ runtime libraries
+* Fink port patches integrated
+* New icons
+* Fixed the server to allow connections of many players at once
+* Several small bugs fixed
+
+CVS Snapshot release 0.9.33
+* Fixed infinite loop when AI tries to trade for something that is not in the
+ bank anymore
+* Fixed PPC: the cursor on the map is now working again
+* Introduced extra options to ./configure
+* Workaround for Gtk-bug with button
+* Added Hungarian translation
+* Several small bugs fixed
+* Added several portability patches
+
+CVS Snapshot release 0.9.23
+* Fixed: Several bug fixes
+* New: Left panel shows information during the game
+
+First release of Pioneers 0.9.19
+* An editor has been added
+* The AI is stronger, can also play on maps with gold
+* We have a new name: Pioneers
+* Pioneers client runs under Cygwin (server not yet implemented)
+* New maps have been added
+* Bug fixes, and code cleanup
+
+CVS Snapshot release 0.8.1.59
+Random player seating order
+Metaserver can serve a limited number of games
+Updated man pages
+
+CVS Snapshot release 0.8.1.54
+Fix for maritime trade
+
+CVS Snapshot release 0.8.1.53
+Update of gnocatan.spec
+Fixed about dialog
+Less severe errors when writing new themes or games
+Disabled 'Add Computer Player' button in server when gnocatanai is not installed
+New functionality in meta server: it will tell whether it supports creation of new games
+
+CVS Snapshot release 0.8.1.51
+Restored compatibility with Gtk+-2.0 and 2.2
+Restored compatibility with FreeBSD
+
+CVS Snapshot release 0.8.1.50
+Fixed reconnect during distribution of gold
+Tiles can be excluded from shuffling
+
+CVS Snapshot release 0.8.1.48
+New about dialog
+Player did not get a turn when playing a second game with the same client
+Made rules for building roads near 'nosetup' nodes more strict
+
+CVS Snapshot release 0.8.1.45
+Reconnect fixed when robber active
+Cosmetic fix on initial size of the map
+
+CVS Snapshot release 0.8.1.43
+Bugfixes
+Fixed crash with cursor on the border of a map
+
+CVS Snapshot release 0.8.1.42
+New preference dialog
+Development cards cleared when playing second game
+
+CVS Snapshot release 0.8.1.40
+New again: probability dots are back
+Code cleanup
+
+CVS Snapshot release 0.8.1.39
+New: single click building
+Fixed: longest road detection
+
+CVS Snapshot release 0.8.1.38
+New: commandline for the client
+New: compiles with Gtk-2.0, 2.2 and 2.4
+Fixed: replaces 127.0.0.1 with localhost
+
+CVS Snapshot release 0.8.1.37
+
+What's new/fixed:
+* Gnocatan can now build the console-only applications if GNOME2/Gtk+ is not
+ found
+* Several cosmetic changes in the client
+* Fixed a bug in the ai when playing too many soldier cards
+* Server-gtk remembers the previous map
+* Quick fix applied for crash after pressing 'Reject Trade'
+* Italian translation added
+* Removed a few memory leaks
+
+Release 0.8.1.30
+
+What's new/fixed:
+* Fixed many bugs regarding the 'Trade Page'
+* Fixed AI losing resources when offering a trade
+* Fixed AI choosing unavailable resources when playing the Year of Plenty card
+* New connection scheme
+* Added tooltips in the server-gtk
+* New image for the splash screen, provided by Tobias Jakobs
+* Fixed bugs regarding the Road Building card
+* Connection as viewer in a game with more than 8 players+viewers is possible
+* Updated the log in the console
+* Minor user interface issues
+
+Release 0.8.1.16
+
+Previous release on SF
Added: trunk/README
===================================================================
--- trunk/README (rev 0)
+++ trunk/README 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,73 @@
+Pioneers
+
+Pioneers is an Internet playable implementation of the Settlers of
+Catan board game. The aim is to remain as faithful to the board game
+as is possible.
+
+Playing the Game
+================
+
+Pioneers is a multi-player game. Each player must run the Pioneers
+client: pioneers. One of the players must also run the Pioneers
+server: pioneers-server-gtk or pioneers-server-console.
+
+The GTK server has a user interface in which you can customise the
+game parameters. Once you are happy with the game parameters, press
+the Start Server button, and the server will start listening for
+client connections.
+
+When you start the client program, it displays a connect dialog. You
+must define the hostname and port where the server can be located.
+You can enter these manually, or press the Meta Server button. The
+meta server maintains a list of all registered Pioneers servers that
+are currently running a game. This allows you to join a game anywhere
+on the Internet.
+
+Pioneers is most fun with three or four players, but two players is
+still ok, or you can add some computer players if you like.
+
+Simple install procedure
+========================
+
+ % tar xvzf pioneers-<version>.tar.gz # unpack the sources
+ % cd pioneers # change to the toplevel directory
+ % ./configure # regenerate configure and run it
+ % make # build Pioneers
+ [ Become root if necessary ]
+ % make install # install Pioneers
+
+Building RPM Binary Packages
+============================
+This section is intended to make it easier for those people that wish to
+build RPMs from the source included in this package, but aren't sure how.
+
+1) Copy pioneers-<version>.tar.gz to your RPM SOURCES directory. Usually
+ this is /usr/src/packages/SOURCES
+
+2) In your RPM SOURCES directory, issue the command
+ 'rpmbuild -ta pioneers.spec'.
+ This will cause rpm to extract the pioneers sources to a temporary
+ directory, build them, and build rpm packages based on the information in
+ the spec file. The binary rpms will be put into your RPM RPMS directory.
+ Usually this is /usr/src/packages/RPMS/<platform>/.
+
+If you have any further questions, please refer to the RPM documentation.
+
+Building Debian Binary Packages
+===============================
+This section is intended to make it easier for those people that wish to
+build Debian binary packages (.deb's) from the source included in this
+package, but aren't sure how.
+
+1) Extract pioneers-<version>.tar.gz inside a temporary directory. The
+ Debian binaries will be placed in this directory. A directory named
+ pioneers-<version> will be created when you extract the archive.
+
+2) Change into the pioneers-<version> directory.
+
+3) Issue the command dpkg-buildpackage (You must have dpkg-dev installed in
+ order to issue this command). This will configure and build the Debian
+ binaries, placing them in the parent directory of your current directory.
+
+If you have any further questions, please refer to the Debian dpkg
+documentation.
Added: trunk/README.Cygwin
===================================================================
--- trunk/README.Cygwin (rev 0)
+++ trunk/README.Cygwin 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,82 @@
+Short guide to install Pioneers in Cygwin
+
+Install a minimal setup
+=======================
+1) Get 'setup.exe' from the Cygwin site (www.cygwin.com)
+2) Select (additional packages will automatically be selected):
+ Category Gnome:
+ libgnome2
+ Category X11:
+ xorg-x11-fscl
+ xorg-x11-fsrv
+ Category Devel:
+ atk-devel
+ gcc
+ gettext-devel
+ gtk-x11-devel
+ intltool
+ libXft-devel
+ libtool1.5
+ make
+ pango-devel
+ pkgconfig
+You now have a minimal setup needed to build and run Pioneers.
+
+Build Pioneers from the repository
+==================================
+If you only want to use released versions, skip to the 'Install Pioneers'
+section.
+
+To compile Pioneers from the Subversion repository,
+you need some extra packages:
+ Category devel:
+ subversion
+ gnome-common
+ Category graphics:
+ ImageMagick
+ ghostscript-base
+ netpbm (10.30-1 does not work, 10.29-1 works ok)
+ Category net:
+ openssh
+
+1) Get the code from the Subversion repository
+ svn checkout https://svn.sourceforge.net/svnroot/pio/trunk/pioneers pioneers
+2) Go to the pioneers directory
+3) Run automake, build and install
+ ./autogen.sh
+ make
+ make install
+
+Install Pioneers
+================
+1) Download the source tarball to your Cygwin home directory
+ (c:\cygwin\home\%username%)
+2) Start the Cygwin shell
+3) Expand the source tarball
+ (tar xvzf pioneers-%versionnumber%.tar.gz)
+4) Enter the source directory (cd pioneers-%versionnumber%)
+5) Configure, build and install
+ ./configure
+ make
+ make install
+
+Start Pioneers
+==============
+6) Start the X server (startx)
+7) Start Pioneers from the XTerm (pioneers)
+
+Known limitations
+=================
+* The help is not built
+* The server will not create new games
+* The metaserver does not work
+
+Miscellaneous
+=============
+I've added the Cygwin Ports project (cygwinports.dotsrc.org)
+URL: ftp://sunsite.dk/projects/cygwinports
+It adds rsvg and newer versions of Gtk+.
+More news later...
+
+Roland Clobus
+2006-08-31 (Pioneers 0.10.1)
Added: trunk/README.MinGW
===================================================================
--- trunk/README.MinGW (rev 0)
+++ trunk/README.MinGW 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,61 @@
+Short guide to build Pioneers in MinGW
+
+Install a minimal setup
+=======================
+* The required files can be found at the following locations:
+
+ http://www.gimp.org/~tml/gimp/win32/downloads.html
+
+glib-dev-2.6.6.zip
+gtk+-dev-2.6.9.zip
+pango-dev-1.8.2.zip
+atk-dev-1.9.0.zip
+pkgconfig-0.15.zip
+libiconv-1.9.1-bin.woe32.zip
+gettext-dev-0.14.5.zip
+
+ http://sourceforge.net/project/showfiles.php?group_id=2435
+
+mingw-runtime-3.8.tar.gz
+w32api-3.3.tar.gz
+binutils-2.15.91-20040904-1.tar.gz
+gcc-core-3.4.2-20040616-1.tar.gz
+gcc-g++-3.4.2-20040916-1.tar.gz
+MSYS-1.0.10.exe
+
+ http://sourceforge.net/project/showfiles.php?group_id=235&package_id=119698
+
+gtk-runtime-2.6.9-rev-a.exe
+
+* Unzip and untar all files to c:\mingw
+* Install MSYS, and give 'c:/mingw' as path for MinGW
+* Install the GTK+ runtime
+
+If any of the files cannot be found, a newer version will probably work too.
+
+Install Pioneers
+================
+1) Download the source tarball to your home directory
+ (c:\msys\1.0\home\%username%)
+2) Start the MSYS shell
+3) Expand the source tarball
+ (tar xvzf pioneers-%versionnumber%.tar.gz)
+4) Enter the source directory (cd pioneers-%versionnumber%)
+5) Configure, build and install
+ ./configure
+ make
+ make install
+
+Start Pioneers
+==============
+6a) Start Pioneers by double clicking on the executable
+ (found in C:\msys\1.0\usr\local)
+6b) or start pioneers.exe from /usr/local in the shell
+
+Known limitations
+=================
+* The online help is not built
+* The server and metaserver are not built
+
+Roland Clobus
+2005-11-15 (Pioneers-0.9.35)
Added: trunk/TODO
===================================================================
--- trunk/TODO (rev 0)
+++ trunk/TODO 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,23 @@
+ - If the trade page is already shown, and the player initiating the
+ trade asks for new quotes, it's easy to oversee the changed trade
+ parameters in the top line. This should be made clearer somehow,
+ e.g. by a beep and/or a note in the messages window.
+
+ - During a setup phase, the client allowed the player to place a road
+ nearly everywhere (at least the road cursor was visible). Should
+ try to reproduce this and find the cause. Hint: The settlement was
+ built first and was on the coast.
+
+ - The meta server should be somehow configurable to:
+ - start only a certain max. number of servers on the local machine
+ - if this number is reached, start servers on other machines
+ (maybe with a proxy meta server running there, or via ssh)
+ [Done]
+ - be able to restrict access in some forms, maybe based on host
+ name and/or IP, and permission to request running server data
+ and start new servers
+
+ - Maybe implement ranking of players somehow: In a user's home dir,
+ the client could record how often this player won a game, was
+ second (point-wise), and so on... The server could collect these
+ data on game start, update it at the end and show some statistics.
Added: trunk/autogen.sh
===================================================================
--- trunk/autogen.sh (rev 0)
+++ trunk/autogen.sh 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+PKG_NAME="Pioneers"
+
+REQUIRED_AUTOMAKE_VERSION="1.9"
+
+(test -f $srcdir/configure.ac \
+ && test -f $srcdir/ChangeLog \
+ && test -d $srcdir/client \
+ && test -d $srcdir/server) || {
+ echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
+ echo " top-level $PKG_NAME directory"
+ exit 1
+}
+
+# Create acinclude.m4 from the extra macro
+cp macros/type_socklen_t.m4 acinclude.m4
+
+which gnome-autogen.sh || {
+ echo "gnome-common not found, using the included version"
+ . $srcdir/macros/gnome-autogen.sh
+ exit 0
+}
+. gnome-autogen.sh
Property changes on: trunk/autogen.sh
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/client/Makefile.am
===================================================================
--- trunk/client/Makefile.am (rev 0)
+++ trunk/client/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,28 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+include client/common/Makefile.am
+include client/ai/Makefile.am
+if HAVE_SCROLLKEEPER
+include client/help/Makefile.am
+endif
+
+if HAVE_GNOME
+include client/gtk/Makefile.am
+endif
Added: trunk/client/ai/Makefile.am
===================================================================
--- trunk/client/ai/Makefile.am (rev 0)
+++ trunk/client/ai/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,35 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+bin_PROGRAMS += pioneersai
+
+pioneersai_CPPFLAGS = -I$(top_srcdir)/client $(console_cflags)
+
+pioneersai_SOURCES = \
+ client/callback.h \
+ client/ai/ai.h \
+ client/ai/ai.c \
+ client/ai/greedy.c \
+ client/ai/lobbybot.c
+
+pioneersai_LDADD = libpioneersclient.a $(console_libs)
+
+config_DATA += \
+ client/ai/computer_names
Added: trunk/client/ai/ai.c
===================================================================
--- trunk/client/ai/ai.c (rev 0)
+++ trunk/client/ai/ai.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,225 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003,2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "version.h"
+#include "game.h"
+#include "ai.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+
+static char *server = NULL;
+static char *port = NULL;
+static char *name = NULL;
+static char *ai;
+static int waittime = 1000;
+static gboolean silent = FALSE;
+static gboolean enable_debug = FALSE;
+static gboolean show_version = FALSE;
+
+static const struct algorithm_info {
+ /** Name of the algorithm (for commandline) */
+ const gchar *name;
+ /** Init function */
+ void (*init_func) (int argc, char **argv);
+ /** Request to be a player? */
+ gboolean request_player;
+ /** Quit if request not honoured */
+ gboolean quit_if_not_request;
+} algorithms[] = {
+/* *INDENT-OFF* */
+ { "greedy", &greedy_init, TRUE, TRUE},
+ { "lobbybot", &lobbybot_init, FALSE, TRUE},
+/* *INDENT-ON* */
+};
+static int active_algorithm = 0;
+
+static gchar *random_name(void)
+{
+ gchar *filename;
+ FILE *stream;
+ gchar *line;
+ gchar *name = NULL;
+ int num = 1;
+
+ filename =
+ g_build_filename(get_pioneers_dir(), "computer_names", NULL);
+ stream = fopen(filename, "r");
+ if (!stream) {
+ g_warning("Unable to open %s", filename);
+ /* Default name for the AI when the computer_names file
+ * is not found or empty.
+ */
+ name = g_strdup(_("Computer Player"));
+ } else {
+ while (read_line_from_file(&line, stream)) {
+ if (g_random_int_range(0, num) == 0) {
+ if (name)
+ g_free(name);
+ name = g_strdup(line);
+ }
+ num++;
+ }
+ fclose(stream);
+ if (num == 1) {
+ g_warning("Empty file: %s", filename);
+ /* Default name for the AI when the computer_names file
+ * is not found or empty.
+ */
+ name = g_strdup(_("Computer Player"));
+ }
+ }
+ g_free(filename);
+ return name;
+}
+
+UIDriver Glib_Driver;
+
+static GOptionEntry commandline_entries[] = {
+ {"server", 's', 0, G_OPTION_ARG_STRING, &server,
+ /* Commandline pioneersai: server */
+ N_("Server Host"), PIONEERS_DEFAULT_GAME_HOST},
+ {"port", 'p', 0, G_OPTION_ARG_STRING, &port,
+ /* Commandline pioneersai: port */
+ N_("Server Port"), PIONEERS_DEFAULT_GAME_PORT},
+ {"name", 'n', 0, G_OPTION_ARG_STRING, &name,
+ /* Commandline pioneersai: name */
+ N_("Computer name (leave absent for random name)"), NULL},
+ {"time", 't', 0, G_OPTION_ARG_INT, &waittime,
+ /* Commandline pioneersai: time */
+ N_("Time to wait between turns (in milliseconds)"), "1000"},
+ {"chat-free", 'c', 0, G_OPTION_ARG_NONE, &silent,
+ /* Commandline pioneersai: chat-free */
+ N_("Stop computer player from talking"), NULL},
+ {"algorithm", 'a', 0, G_OPTION_ARG_STRING, &ai,
+ /* Commandline pioneersai: algorithm */
+ N_("Type of computer player"), "greedy"},
+ {"debug", '\0', 0, G_OPTION_ARG_NONE, &enable_debug,
+ /* Commandline option of ai: enable debug logging */
+ N_("Enable debug messages"), NULL},
+ {"version", '\0', 0, G_OPTION_ARG_NONE, &show_version,
+ /* Commandline option of ai: version */
+ N_("Show version information"), NULL},
+ {NULL, '\0', 0, 0, NULL, NULL, NULL}
+};
+
+static void ai_init(int argc, char **argv)
+{
+ GOptionContext *context;
+ GError *error = NULL;
+
+ /* Long description in the commandline for pioneersai: help */
+ context =
+ g_option_context_new(_("- Computer player for Pioneers"));
+ g_option_context_add_main_entries(context, commandline_entries,
+ PACKAGE);
+ g_option_context_parse(context, &argc, &argv, &error);
+ if (error != NULL) {
+ g_print("%s\n", error->message);
+ g_error_free(error);
+ exit(1);
+ }
+ if (show_version) {
+ g_print(_("Pioneers version:"));
+ g_print(" ");
+ g_print(FULL_VERSION);
+ g_print("\n");
+ exit(0);
+ }
+
+ set_enable_debug(enable_debug);
+
+ if (server == NULL)
+ server = g_strdup(PIONEERS_DEFAULT_GAME_HOST);
+ if (port == NULL)
+ port = g_strdup(PIONEERS_DEFAULT_GAME_PORT);
+
+ printf("ai port is %s\n", port);
+
+ g_random_set_seed(time(NULL) + getpid());
+
+ if (!name) {
+ name = random_name();
+ }
+
+ set_ui_driver(&Glib_Driver);
+ log_set_func_default();
+
+ if (ai != NULL) {
+ gint i;
+ for (i = 0; i < G_N_ELEMENTS(algorithms); i++) {
+ if (!strcmp(algorithms[i].name, ai))
+ active_algorithm = i;
+ }
+ }
+ log_message(MSG_INFO, _("Type of computer player: %s\n"),
+ algorithms[active_algorithm].name);
+ algorithms[active_algorithm].init_func(argc, argv);
+}
+
+void ai_panic(const char *message)
+{
+ cb_chat(message);
+ callbacks.quit();
+}
+
+static void ai_offline(void)
+{
+ gchar *style;
+
+ callbacks.offline = callbacks.quit;
+ style =
+ g_strdup_printf("ai %s", algorithms[active_algorithm].name);
+ cb_connect(server, port, name,
+ !algorithms[active_algorithm].request_player, style);
+ g_free(style);
+ g_free(name);
+}
+
+static void ai_start_game(void)
+{
+ if (algorithms[active_algorithm].request_player ==
+ my_player_viewer()
+ && algorithms[active_algorithm].quit_if_not_request) {
+ ai_panic(N_("The game is already full. I'm leaving."));
+ }
+}
+
+void ai_wait(void)
+{
+ g_usleep(waittime * 1000);
+}
+
+void ai_chat(const char *message)
+{
+ if (!silent)
+ cb_chat(message);
+}
+
+void frontend_set_callbacks(void)
+{
+ callbacks.init = &ai_init;
+ callbacks.offline = &ai_offline;
+ callbacks.start_game = &ai_start_game;
+}
Added: trunk/client/ai/ai.h
===================================================================
--- trunk/client/ai/ai.h (rev 0)
+++ trunk/client/ai/ai.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,33 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _ai_h
+#define _ai_h
+
+#include <glib.h>
+#include "callback.h"
+
+void ai_panic(const char *message);
+void ai_wait(void);
+void ai_chat(const char *message);
+void greedy_init(int argc, char **argv);
+void lobbybot_init(int argc, char **argv);
+
+#endif
Added: trunk/client/ai/computer_names
===================================================================
--- trunk/client/ai/computer_names (rev 0)
+++ trunk/client/ai/computer_names 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,25 @@
+Computer Dude
+Napoleon
+Gorbachev
+Bob Dole
+Abraham Lincoln
+Joan of Arc
+Gödel
+Escher
+Bach
+Pikachu
+Richard Nixon
+Checkers
+Saddam Hussein
+Kermit the Frog
+Ernie and Bert
+Jesse 'The Body' Ventura
+Winston Churchill
+Attila the Hun
+Chairman Mao
+Richard Stallman
+Coolio
+Rupert Murdoch
+Commander Taco
+Godzilla
+Jaws
Added: trunk/client/ai/greedy.c
===================================================================
--- trunk/client/ai/greedy.c (rev 0)
+++ trunk/client/ai/greedy.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,2020 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2005 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "ai.h"
+#include "cost.h"
+#include <stdio.h>
+#include <stdlib.h>
+/*
+ * This is a rudimentary AI for Pioneers.
+ *
+ * What it does _NOT_ do:
+ *
+ * -Make roads explicitly to get the longest road card
+ * -Initiate trade with other players
+ * -Do anything seafarers
+ *
+ */
+
+#define DEVEL_CARD 222
+
+typedef struct resource_values_s {
+ float value[NO_RESOURCE];
+ MaritimeInfo info;
+} resource_values_t;
+
+static int quote_num;
+/* used to avoid multiple chat messages when more than one other player
+ * must discard resources */
+static gboolean discard_starting;
+
+/* things we can buy, in the order that we want them. */
+static BuildType build_preferences[] = { BUILD_CITY, BUILD_SETTLEMENT,
+ BUILD_ROAD, DEVEL_CARD
+};
+
+/*
+ * Forward declarations
+ */
+static Edge *best_road_to_road_spot(Node * n, float *score,
+ const resource_values_t * resval);
+
+static Edge *best_road_to_road(const resource_values_t * resval);
+
+static Edge *best_road_spot(const resource_values_t * resval);
+
+static Node *best_city_spot(const resource_values_t * resval);
+
+static Node *best_settlement_spot(gboolean during_setup,
+ const resource_values_t * resval);
+
+static int places_can_build_settlement(void);
+
+/*
+ * Functions to keep track of what nodes we've visited
+ */
+
+typedef struct node_seen_set_s {
+
+ Node *seen[MAP_SIZE * MAP_SIZE];
+ int size;
+
+} node_seen_set_t;
+
+static void nodeset_reset(node_seen_set_t * set)
+{
+ set->size = 0;
+}
+
+static void nodeset_set(node_seen_set_t * set, Node * n)
+{
+ int i;
+
+ for (i = 0; i < set->size; i++)
+ if (set->seen[i] == n)
+ return;
+
+ set->seen[set->size] = n;
+ set->size++;
+}
+
+static int nodeset_isset(node_seen_set_t * set, Node * n)
+{
+ int i;
+
+ for (i = 0; i < set->size; i++)
+ if (set->seen[i] == n)
+ return 1;
+
+ return 0;
+}
+
+typedef void iterate_node_func_t(Node * n, void *rock);
+
+/*
+ * Iterate over all the nodes on the map calling func() with 'rock'
+ *
+ */
+static void for_each_node(iterate_node_func_t * func, void *rock)
+{
+ int i, j, k;
+
+ for (i = 0; i < get_map()->x_size; i++) {
+ for (j = 0; j < get_map()->y_size; j++) {
+ for (k = 0; k < 6; k++) {
+ Node *n = map_node(get_map(), i, j, k);
+
+ if (n)
+ func(n, rock);
+ }
+ }
+ }
+
+}
+
+/** Determine the required resources.
+ * @param assets The resources that are available
+ * @param cost The cost to buy something
+ * @retval need The additional resources required to buy this
+ * @return TRUE if the assets are enough
+ */
+static gboolean can_pay_for(const gint assets[NO_RESOURCE],
+ const gint cost[NO_RESOURCE],
+ gint need[NO_RESOURCE])
+{
+ gint i;
+ gboolean have_enough;
+
+ have_enough = TRUE;
+ for (i = 0; i < NO_RESOURCE; i++) {
+ if (assets[i] >= cost[i])
+ need[i] = 0;
+ else {
+ need[i] = cost[i] - assets[i];
+ have_enough = FALSE;
+ }
+ }
+ return have_enough;
+}
+
+/* How much does this cost to build? */
+static const gint *cost_of(BuildType bt)
+{
+ switch (bt) {
+ case BUILD_CITY:
+ return cost_upgrade_settlement();
+ case BUILD_SETTLEMENT:
+ return cost_settlement();
+ case BUILD_ROAD:
+ return cost_road();
+ case DEVEL_CARD:
+ return cost_development();
+ default:
+ g_assert(0);
+ return NULL;
+ }
+}
+
+/*
+ * Do I have the resources to buy this, is it available, and do I want it?
+ */
+static gboolean should_buy(const gint assets[NO_RESOURCE], BuildType bt,
+ const resource_values_t * resval,
+ gint need[NO_RESOURCE])
+{
+ if (!can_pay_for(assets, cost_of(bt), need))
+ return FALSE;
+
+ switch (bt) {
+ case BUILD_CITY:
+ return (stock_num_cities() > 0 &&
+ best_city_spot(resval) != NULL);
+ case BUILD_SETTLEMENT:
+ return (stock_num_settlements() > 0 &&
+ best_settlement_spot(FALSE, resval) != NULL);
+ case BUILD_ROAD:
+ /* don't sprawl :) */
+ return (stock_num_roads() > 0 &&
+ places_can_build_settlement() <= 2 &&
+ (best_road_spot(resval) != NULL ||
+ best_road_to_road(resval) != NULL));
+ case DEVEL_CARD:
+ return (can_buy_develop());
+ default:
+ /* xxx bridge, ship */
+ return FALSE;
+ }
+}
+
+/*
+ * If I buy this, what will I have left? Note that some values in need[]
+ * can be negative if I can't afford it.
+ */
+static void leftover_resources(const gint assets[NO_RESOURCE],
+ BuildType bt, gint need[NO_RESOURCE])
+{
+ gint i;
+ const gint *cost = cost_of(bt);
+
+ for (i = 0; i < NO_RESOURCE; i++)
+ need[i] = assets[i] - cost[i];
+}
+
+/*
+ * Probability of a dice roll
+ */
+
+static float dice_prob(int roll)
+{
+ switch (roll) {
+ case 2:
+ case 12:
+ return 3;
+ case 3:
+ case 11:
+ return 6;
+ case 4:
+ case 10:
+ return 8;
+ case 5:
+ case 9:
+ return 11;
+ case 6:
+ case 8:
+ return 14;
+ default:
+ return 0;
+ }
+}
+
+/*
+ * By default how valuable is this resource?
+ */
+
+static float default_score_resource(Resource resource)
+{
+ float score;
+
+ switch (resource) {
+ case GOLD_TERRAIN: /* gold */
+ score = 1.25;
+ break;
+ case HILL_TERRAIN: /* brick */
+ score = 1.1;
+ break;
+ case FIELD_TERRAIN: /* grain */
+ score = 1.0;
+ break;
+ case MOUNTAIN_TERRAIN: /* rock */
+ score = 1.05;
+ break;
+ case PASTURE_TERRAIN: /* sheep */
+ score = 1.0;
+ break;
+ case FOREST_TERRAIN: /* wood */
+ score = 1.1;
+ break;
+ case DESERT_TERRAIN:
+ case SEA_TERRAIN:
+ default:
+ score = 0;
+ break;
+ }
+
+ return score;
+}
+
+/* For each node I own see how much i produce with it. keep a
+ * tally with 'produce'
+ */
+
+static void reevaluate_iterator(Node * n, void *rock)
+{
+ float *produce = (float *) rock;
+
+ /* if i own this node */
+ if ((n) && (n->owner == my_player_num())) {
+ int l;
+ for (l = 0; l < 3; l++) {
+ Hex *h = n->hexes[l];
+ float mult = 1.0;
+
+ if (n->type == BUILD_CITY)
+ mult = 2.0;
+
+ if (h && h->terrain < NO_RESOURCE) {
+ produce[h->terrain] +=
+ mult *
+ default_score_resource(h->terrain) *
+ dice_prob(h->roll);
+ }
+
+ }
+ }
+
+}
+
+/*
+ * Reevaluate the value of all the resources to us
+ */
+
+static void reevaluate_resources(resource_values_t * outval)
+{
+ float produce[NO_RESOURCE];
+ int i;
+
+ for (i = 0; i < NO_RESOURCE; i++) {
+ produce[i] = 0;
+ }
+
+ for_each_node(&reevaluate_iterator, (void *) produce);
+
+ /* Now invert all the positive numbers and give any zeros a weight of 2
+ *
+ */
+ for (i = 0; i < NO_RESOURCE; i++) {
+ if (produce[i] == 0) {
+ outval->value[i] = default_score_resource(i);
+ } else {
+ outval->value[i] = 1.0 / produce[i];
+ }
+
+ }
+
+ /*
+ * Save the maritime info too so we know if we can do port trades
+ */
+ map_maritime_info(get_map(), &outval->info, my_player_num());
+}
+
+
+/*
+ *
+ */
+static float resource_value(Resource resource,
+ const resource_values_t * resval)
+{
+ if (resource < NO_RESOURCE)
+ return resval->value[resource];
+ else if (resource == GOLD_RESOURCE)
+ return default_score_resource(resource);
+ else
+ return 0.0;
+}
+
+
+/*
+ * How valuable is this hex to me?
+ */
+static float score_hex(Hex * hex, const resource_values_t * resval)
+{
+ float score;
+
+ if (hex == NULL)
+ return 0;
+
+ /* multiple resource value by dice probability */
+ score =
+ resource_value(hex->terrain, resval) * dice_prob(hex->roll);
+
+ /* if we don't have a 3 for 1 port yet and this is one it's valuable! */
+ if (!resval->info.any_resource) {
+ if (hex->resource == ANY_RESOURCE)
+ score += 0.5;
+ }
+
+ return score;
+}
+
+/*
+ * How valuable is this hex to others
+ */
+static float default_score_hex(Hex * hex)
+{
+ int score;
+
+ if (hex == NULL)
+ return 0;
+
+ /* multiple resource value by dice probability */
+ score =
+ default_score_resource(hex->terrain) * dice_prob(hex->roll);
+
+ return score;
+}
+
+/*
+ * Give a numerical score to how valuable putting a settlement/city on this spot is
+ *
+ */
+static float score_node(Node * node, int city,
+ const resource_values_t * resval)
+{
+ int i;
+ float score = 0;
+
+ /* if not a node, how did this happen? */
+ g_assert(node != NULL);
+
+ /* if already occupied, in water, or too close to others give a score of -1 */
+ if (is_node_on_land(node) == FALSE)
+ return -1;
+ if (is_node_spacing_ok(node) == FALSE)
+ return -1;
+ if (city == 0) {
+ if (node->owner != -1)
+ return -1;
+ }
+
+ for (i = 0; i < 3; i++) {
+ score += score_hex(node->hexes[i], resval);
+ }
+
+ return score;
+}
+
+/*
+ * Road connects here
+ */
+static int road_connects(Node * n)
+{
+ int i;
+
+ if (n == NULL)
+ return 0;
+
+ for (i = 0; i < 3; i++) {
+ Edge *e = n->edges[i];
+
+ if ((e) && (e->owner == my_player_num()))
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/** Find the best spot for a settlement
+ * @param during_setup Build a settlement during the setup phase?
+ * During setup: no connected road is required,
+ * and the no_setup must be taken into account
+ * Normal play: settlement must be next to a road we own.
+ */
+static Node *best_settlement_spot(gboolean during_setup,
+ const resource_values_t * resval)
+{
+ int i, j, k;
+ Node *best = NULL;
+ float bestscore = -1.0;
+ float score;
+
+ for (i = 0; i < get_map()->x_size; i++) {
+ for (j = 0; j < get_map()->y_size; j++) {
+ for (k = 0; k < 6; k++) {
+ Node *n = map_node(get_map(), i, j, k);
+ if (!n)
+ continue;
+ if (during_setup) {
+ if (n->no_setup)
+ continue;
+ } else {
+ if (!road_connects(n))
+ continue;
+ }
+
+ score = score_node(n, 0, resval);
+ if (score > bestscore) {
+ best = n;
+ bestscore = score;
+ }
+ }
+
+ }
+ }
+
+ return best;
+}
+
+
+/*
+ * What is the best settlement to upgrade to a city?
+ *
+ */
+static Node *best_city_spot(const resource_values_t * resval)
+{
+ int i, j, k;
+ Node *best = NULL;
+ float bestscore = -1.0;
+
+ for (i = 0; i < get_map()->x_size; i++) {
+ for (j = 0; j < get_map()->y_size; j++) {
+ for (k = 0; k < 6; k++) {
+ Node *n = map_node(get_map(), i, j, k);
+ if (!n)
+ continue;
+ if ((n->owner == my_player_num())
+ && (n->type == BUILD_SETTLEMENT)) {
+ float score =
+ score_node(n, 1, resval);
+
+ if (score > bestscore) {
+ best = n;
+ bestscore = score;
+ }
+ }
+ }
+
+ }
+ }
+
+ return best;
+}
+
+/*
+ * Return the opposite end of this node, edge
+ *
+ */
+static Node *other_node(Edge * e, Node * n)
+{
+ if (e->nodes[0] == n)
+ return e->nodes[1];
+ else
+ return e->nodes[0];
+}
+
+/*
+ *
+ *
+ */
+static Edge *traverse_out(Node * n, node_seen_set_t * set, float *score,
+ const resource_values_t * resval)
+{
+ float bscore = 0.0;
+ Edge *best = NULL;
+ int i;
+
+ /* mark this node as seen */
+ nodeset_set(set, n);
+
+ for (i = 0; i < 3; i++) {
+ Edge *e = n->edges[i];
+ Edge *cur_e = NULL;
+ Node *othernode;
+ float cur_score;
+
+ if (!e)
+ continue;
+
+ othernode = other_node(e, n);
+ g_assert(othernode != NULL);
+
+ /* if our road traverse it */
+ if (e->owner == my_player_num()) {
+
+ if (!nodeset_isset(set, othernode))
+ cur_e =
+ traverse_out(othernode, set,
+ &cur_score, resval);
+
+ } else if (can_road_be_built(e, my_player_num())) {
+
+ /* no owner, how good is the other node ? */
+ cur_e = e;
+
+ cur_score = score_node(othernode, 0, resval);
+
+ /* umm.. can we build here? */
+ /*if (!can_settlement_be_built(othernode, my_player_num ()))
+ cur_e = NULL; */
+ }
+
+ /* is this the best edge we've seen? */
+ if ((cur_e != NULL) && (cur_score > bscore)) {
+ best = cur_e;
+ bscore = cur_score;
+
+ }
+ }
+
+ *score = bscore;
+ return best;
+}
+
+/*
+ * Best road to a road
+ *
+ */
+static Edge *best_road_to_road_spot(Node * n, float *score,
+ const resource_values_t * resval)
+{
+ int bscore = -1.0;
+ Edge *best = NULL;
+ int i, j;
+
+ for (i = 0; i < 3; i++) {
+ Edge *e = n->edges[i];
+ if (e) {
+ Node *othernode = other_node(e, n);
+
+ if (can_road_be_built(e, my_player_num())) {
+
+ for (j = 0; j < 3; j++) {
+ Edge *e2 = othernode->edges[j];
+ if (e2 == NULL)
+ continue;
+
+ /* We need to look further, temporarily mark this edge as having our road on it. */
+ e->owner = my_player_num();
+ e->type = BUILD_ROAD;
+
+ if (can_road_be_built
+ (e2, my_player_num())) {
+ float score =
+ score_node(other_node
+ (e2,
+ othernode),
+ 0, resval);
+
+ if (score > bscore) {
+ bscore = score;
+ best = e;
+ }
+ }
+ /* restore map to its real state */
+ e->owner = -1;
+ e->type = BUILD_NONE;
+ }
+ }
+
+ }
+ }
+
+ *score = bscore;
+ return best;
+}
+
+/*
+ * Best road to road on whole map
+ *
+ */
+static Edge *best_road_to_road(const resource_values_t * resval)
+{
+ int i, j, k;
+ Edge *best = NULL;
+ float bestscore = -1.0;
+
+ for (i = 0; i < get_map()->x_size; i++) {
+ for (j = 0; j < get_map()->y_size; j++) {
+ for (k = 0; k < 6; k++) {
+ Node *n = map_node(get_map(), i, j, k);
+ Edge *e;
+ float score;
+
+ if ((n) && (n->owner == my_player_num())) {
+ e = best_road_to_road_spot(n,
+ &score,
+ resval);
+ if (score > bestscore) {
+ best = e;
+ bestscore = score;
+ }
+ }
+ }
+ }
+ }
+
+ return best;
+}
+
+/*
+ * Best road spot
+ *
+ */
+static Edge *best_road_spot(const resource_values_t * resval)
+{
+ int i, j, k;
+ Edge *best = NULL;
+ float bestscore = -1.0;
+ node_seen_set_t nodeseen;
+
+ /*
+ * For every node that we're the owner of traverse out to find the best
+ * node we're one road away from and build that road
+ *
+ *
+ * xxx loops
+ */
+
+ for (i = 0; i < get_map()->x_size; i++) {
+ for (j = 0; j < get_map()->y_size; j++) {
+ for (k = 0; k < 6; k++) {
+ Node *n = map_node(get_map(), i, j, k);
+
+ if ((n != NULL)
+ && (n->owner == my_player_num())) {
+ float score = -1.0;
+ Edge *e;
+
+ nodeset_reset(&nodeseen);
+
+ e = traverse_out(n, &nodeseen,
+ &score, resval);
+
+ if (score > bestscore) {
+ best = e;
+ bestscore = score;
+ }
+ }
+ }
+
+ }
+ }
+
+ return best;
+}
+
+
+/*
+ * Any road at all that's valid for us to build
+ */
+
+static void rand_road_iterator(Node * n, void *rock)
+{
+ int i;
+ Edge **out = (Edge **) rock;
+
+ if (n == NULL)
+ return;
+
+ for (i = 0; i < 3; i++) {
+ Edge *e = n->edges[i];
+
+ if ((e) && (can_road_be_built(e, my_player_num())))
+ *out = e;
+ }
+}
+
+/*
+ * Find any road we can legally build
+ *
+ */
+static Edge *find_random_road(void)
+{
+ Edge *e = NULL;
+
+ for_each_node(&rand_road_iterator, &e);
+
+ return e;
+}
+
+
+static void places_can_build_iterator(Node * n, void *rock)
+{
+ int *count = (int *) rock;
+
+ if (can_settlement_be_built(n, my_player_num()))
+ (*count)++;
+}
+
+static int places_can_build_settlement(void)
+{
+ int count = 0;
+
+ for_each_node(&places_can_build_iterator, (void *) &count);
+
+ return count;
+}
+
+/*
+ * How many resource cards does player have?
+ *
+ */
+static int num_assets(gint assets[NO_RESOURCE])
+{
+ int i;
+ int count = 0;
+
+ for (i = 0; i < NO_RESOURCE; i++) {
+ count += assets[i];
+ }
+
+ return count;
+}
+
+static int player_get_num_resource(int player)
+{
+ return player_get(player)->statistics[STAT_RESOURCES];
+}
+
+/*
+ * Does this resource list contain one element? If so return it
+ * otherwise return NO_RESOURCE
+ */
+static int which_one(gint assets[NO_RESOURCE])
+{
+ int i;
+ int res = NO_RESOURCE;
+ int tot = 0;
+
+ for (i = 0; i < NO_RESOURCE; i++) {
+
+ if (assets[i] > 0) {
+ tot += assets[i];
+ res = i;
+ }
+ }
+
+ if (tot == 1)
+ return res;
+
+ return NO_RESOURCE;
+}
+
+/*
+ * Does this resource list contain just one kind of element? If so return it
+ * otherwise return NO_RESOURCE
+ */
+static int which_resource(gint assets[NO_RESOURCE])
+{
+ int i;
+ int res = NO_RESOURCE;
+ int n_nonzero = 0;
+
+ for (i = 0; i < NO_RESOURCE; i++) {
+
+ if (assets[i] > 0) {
+ n_nonzero++;
+ res = i;
+ }
+ }
+
+ if (n_nonzero == 1)
+ return res;
+
+ return NO_RESOURCE;
+}
+
+/*
+ * What resource do we want the most?
+ *
+ * NOTE: If a resource is not available (players or bank), the
+ * resval->value[resource] should be zero.
+ */
+static int resource_desire(gint assets[NO_RESOURCE],
+ const resource_values_t * resval)
+{
+ int i;
+ int res = NO_RESOURCE;
+ float value = 0.0;
+ gint need[NO_RESOURCE];
+
+ /* do i need just 1 more for something? */
+ for (i = 0; i < G_N_ELEMENTS(build_preferences); i++) {
+ if (should_buy(assets, build_preferences[i], resval, need))
+ continue;
+ res = which_one(need);
+ if (res == NO_RESOURCE || resval->value[res] == 0)
+ continue;
+ return res;
+ }
+
+ /* desire the one we don't produce the most */
+ res = NO_RESOURCE;
+ for (i = 0; i < NO_RESOURCE; i++) {
+ if ((resval->value[i] > value) && (assets[i] < 2)) {
+ res = i;
+ value = resval->value[i];
+ }
+ }
+
+ return res;
+}
+
+
+static void findit_iterator(Node * n, void *rock)
+{
+ Node **node = (Node **) rock;
+ int i;
+
+ if (!n)
+ return;
+ if (n->owner != my_player_num())
+ return;
+
+ /* if i own this node */
+ for (i = 0; i < 3; i++) {
+ if (n->edges[i] == NULL)
+ continue;
+ if (n->edges[i]->owner == my_player_num())
+ return;
+ }
+
+ *node = n;
+}
+
+
+/* Find the settlement with no roads yet
+ *
+ */
+
+static Node *void_settlement(void)
+{
+ Node *ret = NULL;
+
+ for_each_node(&findit_iterator, (void *) &ret);
+
+ return ret;
+}
+
+/*
+ * Game setup
+ * Build one house and one road
+ */
+static void greedy_setup_house(void)
+{
+ Node *node;
+ resource_values_t resval;
+
+ reevaluate_resources(&resval);
+
+ if (stock_num_settlements() == 0) {
+ ai_panic(N_("No settlements in stock to use for setup"));
+ return;
+ }
+
+ node = best_settlement_spot(TRUE, &resval);
+
+ if (node == NULL) {
+ ai_panic(N_("There is no place to setup a settlement"));
+ return;
+ }
+
+ /*node_add(player, BUILD_SETTLEMENT, node->x, node->y, node->pos, FALSE); */
+ cb_build_settlement(node);
+}
+
+
+/*
+ * Game setup
+ * Build one house and one road
+ */
+static void greedy_setup_road(void)
+{
+ Node *node;
+ Edge *e = NULL;
+ int i;
+ resource_values_t resval;
+ float tmp;
+
+ reevaluate_resources(&resval);
+
+ if (stock_num_roads() == 0) {
+ ai_panic(N_("No roads in stock to use for setup"));
+ return;
+ }
+
+ node = void_settlement();
+
+ e = best_road_to_road_spot(node, &tmp, &resval);
+
+ /* if didn't find one just pick one randomly */
+ if (e == NULL) {
+ for (i = 0; i < G_N_ELEMENTS(node->edges); i++) {
+ if (is_edge_on_land(node->edges[i])) {
+ e = node->edges[i];
+ break;
+ }
+ }
+ if (e == NULL) {
+ ai_panic(N_("There is no place to setup a road"));
+ return;
+ }
+ }
+
+ cb_build_road(e);
+}
+
+/*
+ * Determine if there are any trades that I can do which will give me
+ * enough to buy something.
+ */
+static gboolean find_optimal_trade(gint assets[NO_RESOURCE],
+ const resource_values_t * resval,
+ gint ports[NO_RESOURCE],
+ gint * amount,
+ Resource * trade_away,
+ Resource * want_resource)
+{
+ int i;
+ Resource res = NO_RESOURCE;
+ Resource temp;
+ gint need[NO_RESOURCE];
+ BuildType bt = BUILD_NONE;
+
+ for (i = 0; i < G_N_ELEMENTS(build_preferences); i++) {
+ bt = build_preferences[i];
+
+ /* If we should buy something, why haven't we bought it? */
+ if (should_buy(assets, bt, resval, need))
+ continue;
+
+ /* See what we need, and if we can get it. */
+ res = which_one(need);
+ if (res == NO_RESOURCE || get_bank()[res] == 0)
+ continue;
+
+ /* See what we have left after we buy this (one value
+ * will be negative), and whether we have enough of something
+ * to trade for what's missing.
+ */
+ leftover_resources(assets, bt, need);
+ for (temp = 0; temp < NO_RESOURCE; temp++) {
+ if (temp == res)
+ continue;
+ if (need[temp] > ports[temp]) {
+ *amount = ports[temp];
+ *trade_away = temp;
+ *want_resource = res;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+/** I am allowed to do a maritime trade, but will I do it?
+ * @param assets The resources I already have
+ * @param resval The value of the resources
+ * @retval amount The amount to trade
+ * @retval trade_away The resource to trade away
+ * @retval want_resource The resource I want to have
+ * @return TRUE if I want to do the trade
+ */
+static gboolean will_do_maritime_trade(gint assets[NO_RESOURCE],
+ const resource_values_t * resval,
+ gint * amount,
+ Resource * trade_away,
+ Resource * want_resource)
+{
+ MaritimeInfo info;
+ Resource res, want, discard;
+ gint ports[NO_RESOURCE];
+
+ map_maritime_info(get_map(), &info, my_player_num());
+
+ for (res = 0; res < NO_RESOURCE; res++) {
+ if (info.specific_resource[res])
+ ports[res] = 2;
+ else if (info.any_resource)
+ ports[res] = 3;
+ else
+ ports[res] = 4;
+ }
+
+ /* See if we can trade at all. */
+ for (res = 0; res < NO_RESOURCE; res++) {
+ if (assets[res] >= ports[res])
+ break;
+ }
+ if (res == NO_RESOURCE)
+ return FALSE;
+
+ /* See if we can do a single trade that allows us to buy something. */
+ if (find_optimal_trade(assets, resval, ports, amount, trade_away,
+ want_resource))
+ return TRUE;
+
+ /*
+ * We can trade, but we won't be able to buy anything.
+ *
+ * Try a simple heuristic - if there's a resource we can trade away
+ * and still have at least 1 left, and we need something (and we can
+ * get it), do the trade. Try to use the best port for this.
+ */
+ want = resource_desire(assets, resval);
+ if (want == NO_RESOURCE || get_bank()[want] == 0)
+ return FALSE;
+
+ discard = NO_RESOURCE;
+ for (res = 0; res < NO_RESOURCE; res++) {
+ if (res == want)
+ continue;
+ if (assets[res] > ports[res] &&
+ (discard == NO_RESOURCE
+ || ports[discard] > ports[res]))
+ discard = res;
+ }
+
+ if (discard != NO_RESOURCE) {
+ *trade_away = discard;
+ *want_resource = want;
+ *amount = ports[discard];
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** I can play the card, but will I do it?
+ * @param cardtype The type of card to consider
+ * @return TRUE if the card is to be played
+ */
+static gboolean will_play_development_card(DevelType cardtype)
+{
+ gint amount, cards, i;
+
+ if (is_victory_card(cardtype)) {
+ return TRUE;
+ }
+
+ switch (cardtype) {
+ case DEVEL_SOLDIER:
+ return TRUE;
+ case DEVEL_YEAR_OF_PLENTY:
+ /* only when the bank is full enough */
+ amount = 0;
+ for (i = 0; i < NO_RESOURCE; i++)
+ amount += get_bank()[i];
+ if (amount >= 2) {
+ return TRUE;
+ }
+ break;
+ case DEVEL_ROAD_BUILDING:
+ /* don't if don't have two roads left */
+ if (stock_num_roads() < 2)
+ break;
+ return TRUE;
+ case DEVEL_MONOPOLY:
+ /* don't unless there are enough cards out */
+ for (i = 0, cards = 0; i < num_players(); i++)
+ if (i != my_player_num())
+ cards += player_get_num_resource(i);
+ if (cards >= 6)
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*
+ * What to do? what to do?
+ *
+ */
+
+static void greedy_turn(void)
+{
+ resource_values_t resval;
+ int i;
+ gint need[NO_RESOURCE], assets[NO_RESOURCE];
+
+ if (!have_rolled_dice()) {
+ cb_roll();
+ return;
+ }
+
+ /* Don't wait before the dice roll, that will take too long */
+ ai_wait();
+ for (i = 0; i < NO_RESOURCE; ++i)
+ assets[i] = resource_asset(i);
+
+ reevaluate_resources(&resval);
+
+ /* if can then buy city */
+ if (should_buy(assets, BUILD_CITY, &resval, need)) {
+
+ Node *n = best_city_spot(&resval);
+ if (n != NULL) {
+ cb_build_city(n);
+ return;
+ }
+ }
+
+ /* if can then buy settlement */
+ if (should_buy(assets, BUILD_SETTLEMENT, &resval, need)) {
+
+ Node *n = best_settlement_spot(FALSE, &resval);
+ if (n != NULL) {
+ cb_build_settlement(n);
+ return;
+ }
+
+ }
+
+ if (should_buy(assets, BUILD_ROAD, &resval, need)) {
+
+ Edge *e = best_road_spot(&resval);
+
+ if (e == NULL) {
+ e = best_road_to_road(&resval);
+ }
+
+ if (e != NULL) {
+ cb_build_road(e);
+ return;
+ }
+ }
+
+ /* if we can buy a development card and there are some left */
+ if (should_buy(assets, DEVEL_CARD, &resval, need)) {
+ cb_buy_develop();
+ return;
+ }
+
+ /* if we have a lot of cards see if we can trade anything */
+ if (num_assets(assets) >= 3) {
+ if (can_trade_maritime()) {
+ gint amount;
+ Resource trade_away, want_resource;
+ if (will_do_maritime_trade
+ (assets, &resval, &amount, &trade_away,
+ &want_resource)) {
+ cb_maritime(amount, trade_away,
+ want_resource);
+ return;
+ }
+ }
+ }
+
+ /* play development cards */
+ if (can_play_any_develop()) {
+ const DevelDeck *deck = get_devel_deck();
+ gint num_victory_cards = 0;
+ gint victory_point_target, my_points;
+
+ for (i = 0; i < deck->num_cards; i++) {
+ DevelType cardtype = deck_card_type(deck, i);
+
+ /* if it's a vp card, note this for later */
+ if (is_victory_card(cardtype)) {
+ num_victory_cards++;
+ continue;
+ }
+
+ /* can't play card we just bought */
+ if (can_play_develop(i)) {
+ if (will_play_development_card(cardtype)) {
+ cb_play_develop(i);
+ return;
+ }
+ }
+ }
+
+ /* if we have enough victory cards to win, then play them */
+ victory_point_target = game_victory_points();
+ my_points = player_get_score(my_player_num());
+ if (num_victory_cards + my_points >= victory_point_target) {
+ for (i = 0; i < deck->num_cards; i++) {
+ DevelType cardtype =
+ deck_card_type(deck, i);
+
+ if (is_victory_card(cardtype)) {
+ cb_play_develop(i);
+ return;
+ }
+ }
+ }
+ }
+ cb_end_turn();
+}
+
+#define randchat(array,nochat_percent) \
+ do { \
+ int p = (G_N_ELEMENTS(array)*1000/nochat_percent); \
+ int n = (rand() % p) / 10; \
+ if (n < G_N_ELEMENTS(array) ) \
+ ai_chat (array[n]); \
+ } while(0)
+
+static const char *chat_turn_start[] = {
+ N_("Ok, let's go!"),
+ N_("I'll beat you all now! ;)"),
+ N_("Now for another try..."),
+};
+
+static const char *chat_receive_one[] = {
+ N_("At least I get something..."),
+ N_("One is better than none..."),
+};
+
+static const char *chat_receive_many[] = {
+ N_("Wow!"),
+ N_("Ey, I'm becoming rich ;)"),
+ N_("This is really a good year!"),
+};
+static const char *chat_other_receive_many[] = {
+ N_("You really don't deserve that much!"),
+ N_("You don't know what to do with that many resources ;)"),
+ N_("Ey, wait for my robber and lose all this again!"),
+};
+static const char *chat_self_moved_robber[] = {
+ N_("Hehe!"),
+ N_("Go, robber, go!"),
+};
+static const char *chat_moved_robber_to_me[] = {
+ N_("You bastard!"),
+ N_("Can't you move that robber somewhere else?!"),
+ N_("Why always me??"),
+};
+static const char *chat_discard_self[] = {
+ N_("Oh no!"),
+ N_("Grrr!"),
+ N_("Who the hell rolled that 7??"),
+ N_("Why always me?!?"),
+};
+static const char *chat_discard_other[] = {
+ N_("Say good bye to your cards... :)"),
+ N_("*evilgrin*"),
+ N_("/me says farewell to your cards ;)"),
+ N_("That's the price for being rich... :)"),
+};
+static const char *chat_stole_from_me[] = {
+ N_("Ey! Where's that card gone?"),
+ N_("Thieves! Thieves!!"),
+ N_("Wait for my revenge..."),
+};
+static const char *chat_monopoly_other[] = {
+ N_("Oh no :("),
+ N_("Must this happen NOW??"),
+ N_("Args"),
+};
+static const char *chat_largestarmy_self[] = {
+ N_("Hehe, my soldiers rule!"),
+};
+static const char *chat_largestarmy_other[] = {
+ N_("First robbing us, then grabbing the points..."),
+};
+static const char *chat_longestroad_self[] = {
+ N_("See that road!"),
+};
+static const char *chat_longestroad_other[] = {
+ N_("Pf, you won't win with roads alone..."),
+};
+
+static float score_node_hurt_opponents(Node * node)
+{
+ /* no building there */
+ if (node->owner == -1)
+ return 0;
+
+ /* do I have a house there? */
+ if (my_player_num() == node->owner) {
+ if (node->type == BUILD_SETTLEMENT) {
+ return -2.0;
+ } else {
+ return -3.5;
+ }
+ }
+
+ /* opponent has house there */
+ if (node->type == BUILD_SETTLEMENT) {
+ return 1.5;
+ } else {
+ return 2.5;
+ }
+}
+
+/*
+ * How much does putting the robber here hurt my opponents?
+ */
+static float score_hex_hurt_opponents(Hex * hex)
+{
+ int i;
+ float score = 0;
+
+ if (hex == NULL)
+ return -1000;
+
+ /* don't move the pirate. */
+ if (!can_robber_or_pirate_be_moved(hex)
+ || hex->terrain == SEA_TERRAIN)
+ return -1000;
+
+ for (i = 0; i < 6; i++) {
+ score += score_node_hurt_opponents(hex->nodes[i]);
+ }
+
+ /* multiply by resource/roll value */
+ score *= default_score_hex(hex);
+
+ return score;
+}
+
+/*
+ * Find the best (worst for opponents) place to put the robber
+ *
+ */
+static void greedy_place_robber(void)
+{
+ int i, j;
+ float bestscore = -1000;
+ Hex *besthex = NULL;
+
+ ai_wait();
+ for (i = 0; i < get_map()->x_size; i++) {
+ for (j = 0; j < get_map()->y_size; j++) {
+ Hex *hex = map_hex(get_map(), i, j);
+ float score = score_hex_hurt_opponents(hex);
+
+ if (score > bestscore) {
+ bestscore = score;
+ besthex = hex;
+ }
+
+ }
+ }
+ cb_place_robber(besthex);
+}
+
+static void greedy_steal_building(void)
+{
+ int i;
+ int victim = -1;
+ int victim_resources = -1;
+ Hex *hex = map_robber_hex(get_map());
+
+ /* which opponent to steal from */
+ for (i = 0; i < 6; i++) {
+ int numres = 0;
+
+ /* if has owner (and isn't me) */
+ if ((hex->nodes[i]->owner != -1) &&
+ (hex->nodes[i]->owner != my_player_num())) {
+
+ numres =
+ player_get_num_resource(hex->nodes[i]->owner);
+ }
+
+ if (numres > victim_resources) {
+ victim = hex->nodes[i]->owner;
+ victim_resources = numres;
+ }
+ }
+ cb_rob(victim);
+ randchat(chat_self_moved_robber, 15);
+}
+
+/*
+ * A devel card game us two free roads. let's build them
+ *
+ */
+
+static void greedy_free_road(void)
+{
+ Edge *e;
+ resource_values_t resval;
+
+ reevaluate_resources(&resval);
+
+ e = best_road_spot(&resval);
+
+ if (e == NULL) {
+ e = best_road_to_road(&resval);
+ }
+
+ if (e == NULL) {
+ e = find_random_road();
+ }
+
+ if (e != NULL) {
+
+ cb_build_road(e);
+ return;
+
+ } else {
+ log_message(MSG_ERROR,
+ "unable to find spot to build free road\n");
+ cb_disconnect();
+ }
+}
+
+/*
+ * We played a year of plenty card. pick the two resources we most need
+ */
+
+static void greedy_year_of_plenty(const gint bank[NO_RESOURCE])
+{
+ gint want[NO_RESOURCE];
+ gint assets[NO_RESOURCE];
+ int i;
+ int r1, r2;
+ resource_values_t resval;
+
+ ai_wait();
+ for (i = 0; i < NO_RESOURCE; i++) {
+ want[i] = 0;
+ assets[i] = resource_asset(i);
+ }
+
+ /* what two resources do we desire most */
+ reevaluate_resources(&resval);
+
+ r1 = resource_desire(assets, &resval);
+
+ /* If we don't desire anything anymore, ask for a road.
+ * This happens if we have at least 2 of each resource
+ */
+ if (r1 == NO_RESOURCE)
+ r1 = BRICK_RESOURCE;
+
+ assets[r1]++;
+
+ reevaluate_resources(&resval);
+
+ r2 = resource_desire(assets, &resval);
+
+ if (r2 == NO_RESOURCE)
+ r2 = LUMBER_RESOURCE;
+
+ assets[r1]--;
+
+ /* If we want something that is not in the bank, request something else */
+ /* WARNING: This code can cause a lockup if the bank is empty, but
+ * then the year of plenty must not have been playable */
+ while (bank[r1] < 1)
+ r1 = (r1 + 1) % NO_RESOURCE;
+ while (bank[r2] < (r1 == r2 ? 2 : 1))
+ r2 = (r2 + 1) % NO_RESOURCE;
+
+ want[r1]++;
+ want[r2]++;
+
+ cb_choose_plenty(want);
+}
+
+/*
+ * We played a monopoly card. Pick a resource
+ */
+
+static gint other_players_have(Resource res)
+{
+ return game_resources() - get_bank()[res] - resource_asset(res);
+}
+
+static void greedy_monopoly(void)
+{
+ gint assets[NO_RESOURCE];
+ int i;
+ int r, best;
+ resource_values_t resval;
+
+ ai_wait();
+ for (i = 0; i < NO_RESOURCE; i++)
+ assets[i] = resource_asset(i);
+
+ /* order resources by preference */
+ reevaluate_resources(&resval);
+
+ /* try to get something we need */
+ while (TRUE) {
+ r = resource_desire(assets, &resval);
+ if (r == NO_RESOURCE)
+ break;
+ if (other_players_have(r) > 0) {
+ cb_choose_monopoly(r);
+ return;
+ }
+ resval.value[r] = 0;
+ }
+
+ /* there's nothing we really need, so get what we can get most of. */
+ best = 0;
+ for (r = 1; r < NO_RESOURCE; r++) {
+ if (other_players_have(r) > other_players_have(best))
+ best = r;
+ }
+ cb_choose_monopoly(best);
+}
+
+
+/*
+ * Of these resources which is least valuable to us
+ *
+ * Get rid of the one we have the most of
+ * if there's a tie let resource_values_t settle it
+ */
+
+static int least_valuable(gint assets[NO_RESOURCE],
+ resource_values_t * resval)
+{
+ int ret = NO_RESOURCE;
+ int res;
+ int most = 0;
+ float mostval = -1;
+
+ for (res = 0; res < NO_RESOURCE; res++) {
+ if (assets[res] > most) {
+ if (resval->value[res] > mostval) {
+ ret = res;
+ most = assets[res];
+ mostval = resval->value[res];
+ }
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * Which resource do we desire the least?
+ */
+
+static int resource_desire_least(gint my_assets[NO_RESOURCE],
+ resource_values_t * resval)
+{
+ int i;
+ int res;
+ gint assets[NO_RESOURCE];
+ gint need[NO_RESOURCE];
+ int leastval;
+
+ /* make copy of what we got */
+ for (res = 0; res != NO_RESOURCE; res++) {
+ assets[res] = my_assets[res];
+ }
+
+ /* eliminate things we need to build stuff */
+ for (i = 0; i < G_N_ELEMENTS(build_preferences); i++) {
+ BuildType bt = build_preferences[i];
+ if (should_buy(assets, bt, resval, need)) {
+ cost_buy(cost_of(bt), assets);
+ }
+ }
+
+ /* of what's left what do do we care for least */
+ leastval = least_valuable(assets, resval);
+ if (leastval != NO_RESOURCE)
+ return leastval;
+
+ /* otherwise least valuable of what we have in total */
+ leastval = least_valuable(my_assets, resval);
+ if (leastval != NO_RESOURCE)
+ return leastval;
+
+ /* last resort just pick something */
+ for (res = 0; res < NO_RESOURCE; res++) {
+ if (my_assets[res] > 0)
+ return res;
+ }
+
+ /* Should never get here */
+ g_assert_not_reached();
+ return 0;
+}
+
+
+/*
+ * A seven was rolled. we need to discard some resources :(
+ *
+ */
+static void greedy_discard(int num)
+{
+ int res;
+ gint todiscard[NO_RESOURCE];
+ int i;
+ resource_values_t resval;
+ gint assets[NO_RESOURCE];
+
+ /* zero out */
+ for (res = 0; res != NO_RESOURCE; res++) {
+ todiscard[res] = 0;
+ assets[res] = resource_asset(res);
+ }
+
+ for (i = 0; i < num; i++) {
+
+ reevaluate_resources(&resval);
+
+ res = resource_desire_least(assets, &resval);
+
+ todiscard[res]++;
+ assets[res]--;
+ }
+
+ cb_discard(todiscard);
+}
+
+/*
+ * Domestic Trade
+ *
+ */
+static int quote_next_num(void)
+{
+ return quote_num++;
+}
+
+static void greedy_quote_start(void)
+{
+ quote_num = 0;
+}
+
+static int trade_desired(gint assets[NO_RESOURCE], gint give, gint take,
+ gboolean free_offer)
+{
+ int i, n;
+ int res = NO_RESOURCE;
+ resource_values_t resval;
+ float value = 0.0;
+ gint need[NO_RESOURCE];
+
+ if (!free_offer) {
+ /* don't give away cards we have only once */
+ if (assets[give] <= 1) {
+ return 0;
+ }
+
+ /* make it as if we don't have what we're trading away */
+ assets[give] -= 1;
+ }
+
+ for (n = 1; n <= 3; ++n) {
+ /* do i need something more for something? */
+ if (!should_buy(assets, BUILD_CITY, &resval, need)) {
+ if ((res = which_resource(need)) == take
+ && need[res] == n)
+ break;
+ }
+ if (!should_buy(assets, BUILD_SETTLEMENT, &resval, need)) {
+ if ((res = which_resource(need)) == take
+ && need[res] == n)
+ break;
+ }
+ if (!should_buy(assets, BUILD_ROAD, &resval, need)) {
+ if ((res = which_resource(need)) == take
+ && need[res] == n)
+ break;
+ }
+ if (!should_buy(assets, DEVEL_CARD, &resval, need)) {
+ if ((res = which_resource(need)) == take
+ && need[res] == n)
+ break;
+ }
+ }
+ if (!free_offer)
+ assets[give] += 1;
+ if (n <= 3)
+ return n;
+
+ /* desire the one we don't produce the most */
+ reevaluate_resources(&resval);
+ for (i = 0; i < NO_RESOURCE; i++) {
+ if ((resval.value[i] > value) && (assets[i] < 2)) {
+ res = i;
+ value = resval.value[i];
+ }
+ }
+
+ if (res == take && assets[give] > 2) {
+ return 1;
+ }
+
+ return 0;
+}
+
+static void greedy_consider_quote(G_GNUC_UNUSED gint partner,
+ gint we_receive[NO_RESOURCE],
+ gint we_supply[NO_RESOURCE])
+{
+ gint give, take, ntake;
+ gint give_res[NO_RESOURCE], take_res[NO_RESOURCE],
+ my_assets[NO_RESOURCE];
+ gint i;
+ gboolean free_offer;
+
+ free_offer = TRUE;
+ for (i = 0; i < NO_RESOURCE; ++i) {
+ my_assets[i] = resource_asset(i);
+ free_offer &= we_supply[i] == 0;
+ }
+
+ for (give = 0; give < NO_RESOURCE; give++) {
+ /* A free offer is always accepted */
+ if (!free_offer) {
+ if (we_supply[give] == 0)
+ continue;
+ if (my_assets[give] == 0)
+ continue;
+ }
+ for (take = 0; take < NO_RESOURCE; take++) {
+ /* Don't do stupid offers */
+ if (!free_offer && take == give)
+ continue;
+ if (we_receive[take] == 0)
+ continue;
+ if ((ntake =
+ trade_desired(my_assets, give, take,
+ free_offer)) > 0)
+ goto doquote;
+ }
+ }
+
+ /* Do not decline anything for free, just take it all */
+ if (free_offer) {
+ cb_quote(quote_next_num(), we_supply, we_receive);
+ log_message(MSG_INFO, "Taking the whole free offer.\n");
+ return;
+ }
+
+ log_message(MSG_INFO, _("Rejecting trade.\n"));
+ cb_end_quote();
+ return;
+
+ doquote:
+ for (i = 0; i < NO_RESOURCE; ++i) {
+ give_res[i] = (give == i && !free_offer) ? 1 : 0;
+ take_res[i] = take == i ? ntake : 0;
+ }
+ cb_quote(quote_next_num(), give_res, take_res);
+ log_message(MSG_INFO, "Quoting.\n");
+}
+
+static void greedy_setup(unsigned num_settlements, unsigned num_roads)
+{
+ ai_wait();
+ if (num_settlements > 0)
+ greedy_setup_house();
+ else if (num_roads > 0)
+ greedy_setup_road();
+ else
+ cb_end_turn();
+}
+
+static void greedy_roadbuilding(gint num_roads)
+{
+ ai_wait();
+ if (num_roads > 0)
+ greedy_free_road();
+ else
+ cb_end_turn();
+}
+
+static void greedy_discard_start(void)
+{
+ discard_starting = TRUE;
+}
+
+static void greedy_discard_add(gint player_num, gint discard_num)
+{
+ if (player_num == my_player_num()) {
+ randchat(chat_discard_self, 10);
+ ai_wait();
+ greedy_discard(discard_num);
+ } else {
+ if (discard_starting) {
+ discard_starting = FALSE;
+ randchat(chat_discard_other, 10);
+ }
+ }
+}
+
+static void greedy_gold_choose(gint gold_num, const gint * bank)
+{
+ resource_values_t resval;
+ gint assets[NO_RESOURCE];
+ gint want[NO_RESOURCE];
+ gint my_bank[NO_RESOURCE];
+ gint i;
+ int r1;
+
+ for (i = 0; i < NO_RESOURCE; i++) {
+ want[i] = 0;
+ assets[i] = resource_asset(i);
+ my_bank[i] = bank[i];
+ }
+
+ for (i = 0; i < gold_num; i++) {
+ reevaluate_resources(&resval);
+
+ r1 = resource_desire(assets, &resval);
+ /* If we don't want anything, start emptying the bank */
+ if (r1 == NO_RESOURCE) {
+ r1 = 0;
+ /* Potential deadlock, but bank is always full enough */
+ while (my_bank[r1] == 0)
+ r1++;
+ }
+ want[r1]++;
+ assets[r1]++;
+ my_bank[r1]--;
+ }
+ cb_choose_gold(want);
+
+}
+
+static void greedy_error(const gchar * message)
+{
+ gchar *buffer;
+
+ buffer =
+ g_strdup_printf(_
+ ("Received error from server: %s. Quitting\n"),
+ message);
+ cb_chat(buffer);
+ g_free(buffer);
+ cb_disconnect();
+}
+
+static void greedy_game_over(gint player_num, G_GNUC_UNUSED gint points)
+{
+ if (player_num == my_player_num())
+ ai_chat(N_("Yippie!"));
+ else
+ ai_chat(N_("My congratulations"));
+ cb_disconnect();
+}
+
+/* functions for chatting follow */
+static void greedy_player_turn(gint player)
+{
+ if (player == my_player_num())
+ randchat(chat_turn_start, 70);
+}
+
+static void greedy_robber_moved(G_GNUC_UNUSED Hex * old, Hex * new)
+{
+ int idx;
+ gboolean iam_affected = FALSE;
+ for (idx = 0; idx < G_N_ELEMENTS(new->nodes); idx++) {
+ if (new->nodes[idx]->owner == my_player_num())
+ iam_affected = TRUE;
+ }
+ if (iam_affected)
+ randchat(chat_moved_robber_to_me, 20);
+}
+
+static void greedy_player_robbed(G_GNUC_UNUSED gint robber_num,
+ gint victim_num,
+ G_GNUC_UNUSED Resource resource)
+{
+ if (victim_num == my_player_num())
+ randchat(chat_stole_from_me, 15);
+}
+
+static void greedy_get_rolled_resources(gint player_num,
+ const gint * resources,
+ G_GNUC_UNUSED const gint * wanted)
+{
+ gint total = 0, i;
+ for (i = 0; i < NO_RESOURCE; ++i)
+ total += resources[i];
+ if (player_num == my_player_num()) {
+ if (total == 1)
+ randchat(chat_receive_one, 60);
+ else if (total >= 3)
+ randchat(chat_receive_many, 20);
+ } else if (total >= 3)
+ randchat(chat_other_receive_many, 30);
+}
+
+static void greedy_played_develop(gint player_num,
+ G_GNUC_UNUSED gint card_idx,
+ DevelType type)
+{
+ if (player_num != my_player_num() && type == DEVEL_MONOPOLY)
+ randchat(chat_monopoly_other, 20);
+}
+
+static void greedy_new_statistics(gint player_num, StatisticType type,
+ gint num)
+{
+ if (num != 1)
+ return;
+ if (type == STAT_LONGEST_ROAD) {
+ if (player_num == my_player_num())
+ randchat(chat_longestroad_self, 10);
+ else
+ randchat(chat_longestroad_other, 10);
+ } else if (type == STAT_LARGEST_ARMY) {
+ if (player_num == my_player_num())
+ randchat(chat_largestarmy_self, 10);
+ else
+ randchat(chat_largestarmy_other, 10);
+ }
+}
+
+void greedy_init(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
+{
+ callbacks.setup = &greedy_setup;
+ callbacks.turn = &greedy_turn;
+ callbacks.robber = &greedy_place_robber;
+ callbacks.steal_building = &greedy_steal_building;
+ callbacks.roadbuilding = &greedy_roadbuilding;
+ callbacks.plenty = &greedy_year_of_plenty;
+ callbacks.monopoly = &greedy_monopoly;
+ callbacks.discard_add = &greedy_discard_add;
+ callbacks.quote_start = &greedy_quote_start;
+ callbacks.quote = &greedy_consider_quote;
+ callbacks.game_over = &greedy_game_over;
+ callbacks.error = &greedy_error;
+
+ /* chatting */
+ callbacks.player_turn = &greedy_player_turn;
+ callbacks.robber_moved = &greedy_robber_moved;
+ callbacks.discard = &greedy_discard_start;
+ callbacks.gold_choose = &greedy_gold_choose;
+ callbacks.player_robbed = &greedy_player_robbed;
+ callbacks.get_rolled_resources = &greedy_get_rolled_resources;
+ callbacks.played_develop = &greedy_played_develop;
+ callbacks.new_statistics = &greedy_new_statistics;
+}
Added: trunk/client/ai/lobbybot.c
===================================================================
--- trunk/client/ai/lobbybot.c (rev 0)
+++ trunk/client/ai/lobbybot.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,170 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "ai.h"
+#include "cost.h"
+#include <stdio.h>
+#include <string.h>
+/*
+ * This is a chatty AI for Pioneers.
+ *
+ * It is intended to populate the lobby and to give help to new players.
+ * When used in other games, it will leave the game when it starts.
+*/
+
+static GHashTable *players = NULL;
+static gboolean chatting = FALSE;
+
+struct _PlayerInfo {
+ /** Name of the player */
+ gchar *name;
+};
+
+typedef struct _PlayerInfo PlayerInfo;
+
+static PlayerInfo *player_info_new(const gchar * name)
+{
+ PlayerInfo *object = g_malloc(sizeof(PlayerInfo));
+ object->name = g_strdup(name);
+ return object;
+}
+
+static void player_info_free(PlayerInfo * player_info)
+{
+ g_return_if_fail(player_info != NULL);
+ g_free(player_info->name);
+ g_free(player_info);
+}
+
+static void player_info_set_name(PlayerInfo * player_info,
+ const gchar * name)
+{
+ g_return_if_fail(player_info != NULL);
+ if (player_info->name != NULL)
+ g_free(player_info->name);
+ player_info->name = g_strdup(name);
+}
+
+static void lobbybot_player_name_changed(gint player_num,
+ const gchar * name)
+{
+ PlayerInfo *info =
+ g_hash_table_lookup(players, GINT_TO_POINTER(player_num));
+ if (info) {
+ player_info_set_name(info, name);
+ } else {
+ info = player_info_new(name);
+ g_hash_table_insert(players, GINT_TO_POINTER(player_num),
+ info);
+
+ if (my_player_num() != player_num && chatting)
+ /* Translators: don't translate '/help' */
+ ai_chat(N_("Hello, welcome to the lobby. I am a "
+ "simple robot. Type '/help' in the chat "
+ "to see the list of commands I know."));
+ }
+}
+
+static void lobbybot_player_quit(gint player_num)
+{
+ gboolean did_remove =
+ g_hash_table_remove(players, GINT_TO_POINTER(player_num));
+ g_return_if_fail(did_remove);
+}
+
+static void lobbybot_chat_parser(gint player_num, const gchar * chat)
+{
+ PlayerInfo *info;
+
+ if (player_num == my_player_num()) {
+ /* Don't log own responses */
+ return;
+ }
+
+ info = g_hash_table_lookup(players, GINT_TO_POINTER(player_num));
+ g_assert(info != NULL);
+
+ if (!strncmp(chat, "/help", 5)) {
+ /* Translators: don't translate '/help' */
+ ai_chat(N_("'/help' shows this message again"));
+
+ /* Translators: don't translate '/why' */
+ ai_chat(N_("'/why' explains the purpose of this strange "
+ "board layout"));
+ /* Translators: don't translate '/news' */
+ ai_chat(N_("'/news' tells the last released version"));
+ return;
+ }
+
+ if (!strncmp(chat, "/why", 4)) {
+ ai_chat(N_("This board is not intended to be a game that "
+ "can be played. Instead, players can find "
+ "eachother here, and decide which board they "
+ "want to play. Then, one of the players will "
+ "host the proposed game by starting a server, "
+ "and registers it at the metaserver. The other "
+ "players can subsequently disconnect from the "
+ "lobby, and enter that game."));
+ return;
+ }
+ if (!strncmp(chat, "/news", 5)) {
+ ai_chat(N_("The last released version of Pioneers is"));
+ /* Update this string when releasing a new version */
+ ai_chat("0.11.3");
+ return;
+ }
+}
+
+static void hash_data_free(gpointer data)
+{
+ player_info_free((PlayerInfo *) data);
+}
+
+static void lobbybot_turn(G_GNUC_UNUSED gint player_num)
+{
+ ai_chat(N_
+ ("The game is starting. I'm not needed anymore. Goodbye."));
+ cb_disconnect();
+}
+
+static void lobbybot_start_game(void)
+{
+ /* The rules are known, enable chat */
+ chatting = TRUE;
+}
+
+void lobbybot_init(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
+{
+ g_assert(players == NULL);
+ players =
+ g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL,
+ hash_data_free);
+ /* Don't chat before the rules are known */
+ chatting = FALSE;
+
+ callbacks.viewer_name = &lobbybot_player_name_changed;
+ callbacks.player_name = &lobbybot_player_name_changed;
+ callbacks.viewer_quit = &lobbybot_player_quit;
+ callbacks.player_quit = &lobbybot_player_quit;
+ callbacks.incoming_chat = &lobbybot_chat_parser;
+ callbacks.player_turn = &lobbybot_turn;
+ callbacks.start_game = &lobbybot_start_game;
+}
Added: trunk/client/callback.h
===================================================================
--- trunk/client/callback.h (rev 0)
+++ trunk/client/callback.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,415 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003,2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _callback_h
+#define _callback_h
+
+/* this function should be defined by the frontend. */
+void frontend_set_callbacks(void);
+
+/* this file should only include what the frontend needs, to prevent the
+ * frontend's namespace to be too full. Especially client.h should not
+ * be included. Any function a frontend may need should be declared here,
+ * not in client.h */
+#include <glib.h> /* for gboolean, and probably many other things */
+#include "map.h" /* for Edge, Node and Hex */
+#include "game.h" /* for DevelType */
+#include "authors.h" /* defines AUTHORLIST, as a char **, NULL-ended */
+#include "cards.h"
+
+/* types */
+typedef enum {
+ STAT_SETTLEMENTS,
+ STAT_CITIES,
+ STAT_CITY_WALLS,
+ STAT_LARGEST_ARMY,
+ STAT_LONGEST_ROAD,
+ STAT_CHAPEL,
+ STAT_UNIVERSITY,
+ STAT_GOVERNORS_HOUSE,
+ STAT_LIBRARY,
+ STAT_MARKET,
+ STAT_SOLDIERS,
+ STAT_RESOURCES,
+ STAT_DEVELOPMENT
+} StatisticType;
+
+typedef struct {
+ gchar *name;
+ gchar *style;
+ gint statistics[STAT_DEVELOPMENT + 1];
+ GList *points; /* bonus points from special actions */
+} Player;
+
+typedef struct {
+ gchar *name;
+ gchar *style;
+ gint num;
+} Viewer;
+
+enum callback_mode {
+ MODE_INIT, /* not connected */
+ MODE_WAIT_TURN, /* wait for your turn */
+ MODE_SETUP, /* do a setup */
+ MODE_TURN, /* your turn */
+ MODE_ROBBER, /* place robber */
+ MODE_ROB, /* select a building/ship to rob */
+ MODE_MONOPOLY, /* choose monopoly resource */
+ MODE_MONOPOLY_RESPONSE, /* chosen monopoly resource, waiting */
+ MODE_PLENTY, /* choose year of plenty resources */
+ MODE_PLENTY_RESPONSE, /* chosen year of plenty resources, waiting */
+ MODE_ROAD_BUILD, /* build two roads/ships/bridges */
+ MODE_DOMESTIC, /* called for quotes */
+ MODE_QUOTE, /* got a call for quotes */
+ MODE_DISCARD, /* discard resources */
+ MODE_DISCARD_WAIT, /* wait for others discarding resources */
+ MODE_GOLD, /* choose gold */
+ MODE_GOLD_WAIT, /* wait for others choosing gold */
+ MODE_GAME_OVER /* the game is over, nothing can be done */
+};
+
+/* functions to be implemented by front ends */
+struct callbacks {
+ /* This function is called when the client is initialized. The
+ * frontend should initialize itself now */
+ void (*init) (int argc, char **argv);
+ /* Allows the frontend to show a message considering the network
+ * status, probably in the status bar */
+ void (*network_status) (const gchar * description);
+ /* playing instructions. conventionally shown in the "development
+ * panel", but they can of course be put anywhere */
+ void (*instructions) (const gchar * message);
+ /* Message if client is waiting for network. If it is, it may be
+ * a good idea to disable all user controls and put a message in the
+ * status bar. */
+ void (*network_wait) (gboolean is_waiting);
+ /* we are in mode_offline, do something (probably call cb_connect).
+ * This function is called every time the mode is entered, which is
+ * at the start of the game and after every network event (after a
+ * failed connect, that is) */
+ void (*offline) (void);
+ /* some people must discard resources. this hook allows the frontend
+ * to prepare for it. */
+ void (*discard) (void);
+ /* add a player to the list of players who must discard. Note that
+ * if player_num == my_player_num (), the frontend is supposed to
+ * call cb_discard. */
+ void (*discard_add) (gint player_num, gint discard_num);
+ /* a player discarded resources */
+ void (*discard_remove) (gint player_num);
+ /* discard mode is finished. */
+ void (*discard_done) (void);
+ /* starting gold distribution */
+ void (*gold) (void);
+ /* someone is added to the list of receiving players. No special
+ * reaction is required if player_num == my_player_num () */
+ void (*gold_add) (gint player_num, gint gold_num);
+ /* someone chose gold resources */
+ void (*gold_remove) (gint player_num, gint * resources);
+ /* You must choose the resources for your gold. */
+ void (*gold_choose) (gint gold_num, const gint * bank);
+ /* all players chose their gold, the game continues. */
+ void (*gold_done) (void);
+ /* the game is over, someone won. */
+ void (*game_over) (gint player_num, gint points);
+ /* The game is about to (re)start, nothing is known about the new game */
+ void (*init_game) (void);
+ /* The game is about to start, all rules are known. */
+ void (*start_game) (void);
+ /* You must setup. Num_* is the number of settlements/roads that
+ * should still be built. */
+ void (*setup) (unsigned num_settlements, unsigned num_roads);
+ /* Someone did a call for quotes */
+ void (*quote) (gint player_num, gint * they_supply,
+ gint * they_receive);
+ /* you played a roadbuilding development card, so start building. */
+ void (*roadbuilding) (gint num_roads);
+ /* choose your monopoly. */
+ void (*monopoly) (void);
+ /* choose the resources for your year of plenty. */
+ void (*plenty) (const gint * bank);
+ /* it's your turn, do something */
+ void (*turn) (void);
+ /* it's someone else's turn */
+ void (*player_turn) (gint player_num);
+ /* you're trading */
+ void (*trade) (void);
+ /* while you're trading, someone else rejects the trade */
+ void (*trade_player_end) (gint player_num);
+ /* while you're trading, someone else offers you a quote */
+ void (*trade_add_quote) (gint player_num, gint quote_num,
+ const gint * they_supply,
+ const gint * they_receive);
+ /* while you're trading, someone revokes a quote */
+ void (*trade_remove_quote) (gint player_num, gint quote_num);
+ /* you're trading, and a trade has just been performed. */
+ void (*trade_domestic) (gint partner_num, gint quote_num,
+ const gint * we_supply,
+ const gint * we_receive);
+ /* you're trading, and a trade has just been performed. */
+ void (*trade_maritime) (gint ratio, Resource we_supply,
+ Resource we_receive);
+ /* while someone else is trading, a player rejects the trade */
+ void (*quote_player_end) (gint player_num);
+ /* while someone else is trading, a player makes a quote */
+ void (*quote_add) (gint player_num, gint quote_num,
+ const gint * they_supply,
+ const gint * they_receive);
+ /* while someone else is trading, a player revokes a quote */
+ void (*quote_remove) (gint player_num, gint quote_num);
+ /* someone else makes a call for quotes. This is an initialization
+ * callback, it is only called once. After that, quote is called
+ * for every call for quotes (at least once, immediately after this
+ * function returns. quote can be called more times, until quote_end
+ * is called, which marks the end of the trading session. */
+ void (*quote_start) (void);
+ /* someone else finishes trading */
+ void (*quote_end) (void);
+ /* you rejected the trade, now you're monitoring it */
+ void (*quote_monitor) (void);
+ /* while someone else is trading, a quote is accepted. */
+ void (*quote_trade) (gint player_num, gint partner_num,
+ gint quote_num, const gint * they_supply,
+ const gint * they_receive);
+ /* the dice have been rolled */
+ void (*rolled_dice) (gint die1, gint die2, gint player_num);
+ /* An edge changed, it should be drawn */
+ void (*draw_edge) (Edge * edge);
+ /* A node changed, it should be drawn */
+ void (*draw_node) (Node * node);
+ /* You bought a development card */
+ void (*bought_develop) (DevelType type);
+ /* someone played a development card */
+ void (*played_develop) (gint player_num, gint card_idx,
+ DevelType type);
+ /* Something happened to your resources. The frontend should not
+ * apply the change. When this function is called, the value is
+ * already changed. */
+ void (*resource_change) (Resource type, gint num);
+ /* a hex has changed, it should be drawn. */
+ void (*draw_hex) (Hex * hex);
+ /* something happened to your pieces stock (ships, roads, etc.) */
+ void (*update_stock) (void);
+ /* You should move the robber or pirate */
+ void (*robber) (void);
+ /* Someone moved the robber */
+ void (*robber_moved) (Hex * old, Hex * new);
+ /* You should steal something from a building */
+ void (*steal_building) (void);
+ /* The robber placement has finished, continue normally */
+ void (*robber_done) (void);
+ /* You should steal something from a ship */
+ void (*steal_ship) (void);
+ /* Someone has been robbed. The frontend should allow player_num to
+ * be negative, meaning noone was robbed. This is not implemented
+ * yet. */
+ void (*player_robbed) (gint robber_num, gint victim_num,
+ Resource resource);
+ /* The dice have been rolled, and resources are being distributed.
+ * This is called once for every player receiving resources. The
+ * frontend should also be able to handle players not getting any
+ * resources, because it may be called for all players in the future
+ * The value of the resources has already been updated, and there has
+ * been a call to resource_change when this is called.
+ * If resources is different from wanted, the player should have
+ * received resources, but the bank was empty. */
+ void (*get_rolled_resources) (gint player_num,
+ const gint * resources,
+ const gint * wanted);
+ /* Something happened to someones stats. As with resource_change,
+ * the value must not be updated by the frontend, it has already been
+ * done by the client. */
+ void (*new_statistics) (gint player_num, StatisticType type,
+ gint num);
+ /* Something happened to someones special points. As with
+ * resource_change, the value must not be updated by the frontend,
+ * it has already been done by the client. */
+ void (*new_points) (gint player_num, Points * points,
+ gboolean added);
+ /* a viewer changed his/her name */
+ void (*viewer_name) (gint viewer_num, const gchar * name);
+ /* a player changed his/her name */
+ void (*player_name) (gint player_num, const gchar * name);
+ /* a player changed his/her style */
+ void (*player_style) (gint player_num, const gchar * style);
+ /* a player left the game */
+ void (*player_quit) (gint player_num);
+ /* a viewer left the game */
+ void (*viewer_quit) (gint player_num);
+ /* respond to incoming chat messages */
+ void (*incoming_chat) (gint player_num, const gchar * chat);
+ /* something changed in the bank. */
+ void (*new_bank) (const gint * new_bank);
+ /* some communication error occurred, and it has already been logged */
+ void (*error) (const gchar * message);
+ /* mainloop. This is initialized to run the glib main loop. It can
+ * be overridden */
+ void (*mainloop) (void);
+ /* exit the main loop. The program will then quit. This is
+ * initialized to quit the main loop. It should be overridden if
+ * mainloop is. */
+ void (*quit) (void);
+};
+
+#if ENABLE_NLS
+typedef struct {
+ const char *code;
+ const char *name;
+ const char *localedef;
+ gboolean supported;
+ void *widget;
+} lang_desc;
+
+void init_nls(void);
+gboolean change_nls(lang_desc * ld);
+lang_desc *find_lang_desc(const gchar * code);
+#endif
+
+extern struct callbacks callbacks;
+extern enum callback_mode callback_mode;
+/* It seems this should be part of the gui, but it is in fact part of the log,
+ * which is in common, and included by the client, not the gui. */
+extern gboolean color_chat_enabled;
+
+/* functions for use by front ends */
+/* these functions do things for the frontends, they should be used to make
+ * changes to the board, etc. The frontend should NEVER touch any game
+ * structures directly (except for reading). */
+void cb_connect(const gchar * server, const gchar * port,
+ const gchar * name, gboolean viewer, const gchar * style);
+void cb_disconnect(void);
+void cb_roll(void);
+void cb_build_road(const Edge * edge);
+void cb_build_ship(const Edge * edge);
+void cb_build_bridge(const Edge * edge);
+void cb_move_ship(const Edge * from, const Edge * to);
+void cb_build_settlement(const Node * node);
+void cb_build_city(const Node * node);
+void cb_build_city_wall(const Node * node);
+void cb_buy_develop(void);
+void cb_play_develop(int card);
+void cb_undo(void);
+void cb_maritime(gint ratio, Resource supply, Resource receive);
+void cb_domestic(const gint * supply, const gint * receive);
+void cb_end_turn(void);
+void cb_place_robber(const Hex * hex);
+void cb_rob(gint victim_num);
+void cb_choose_monopoly(gint resource);
+void cb_choose_plenty(gint * resources);
+void cb_trade(gint player, gint quote, const gint * supply,
+ const gint * receive);
+void cb_end_trade(void);
+void cb_quote(gint num, const gint * supply, const gint * receive);
+void cb_delete_quote(gint num);
+void cb_end_quote(void);
+void cb_chat(const gchar * text);
+void cb_name_change(const gchar * name);
+void cb_style_change(const gchar * name);
+void cb_discard(const gint * resources);
+void cb_choose_gold(const gint * resources);
+
+/* check functions used by front ends and internally */
+/* these functions don't change anything in the program, they are used to get
+ * information about the current state of the game. */
+gboolean have_rolled_dice(void);
+gboolean can_buy_develop(void);
+gboolean can_play_develop(int card);
+gboolean can_play_any_develop(void);
+Player *player_get(gint num);
+gboolean player_is_viewer(gint num);
+Viewer *viewer_get(gint num);
+const gchar *player_name(gint player_num, gboolean word_caps);
+gint player_get_score(gint player_num);
+gint my_player_num(void);
+const gchar *my_player_name(void);
+gboolean my_player_viewer(void);
+const gchar *my_player_style(void);
+const gchar *player_get_style(gint player_num);
+void player_set_style(gint player_num, const gchar * style);
+gint num_players(void);
+gint current_player(void);
+/** Find the player or viewer with name
+ * @param name The name to search for
+ * @return the player/viewer number or -1 if the name was not found
+ */
+gint find_player_by_name(const gchar * name);
+gint build_count_edges(void);
+gint build_count_settlements(void);
+gint build_count(BuildType type);
+gint stock_num_roads(void);
+gint stock_num_ships(void);
+gint stock_num_bridges(void);
+gint stock_num_settlements(void);
+gint stock_num_cities(void);
+gint stock_num_city_walls(void);
+gint stock_num_develop(void);
+gint resource_asset(Resource which);
+gint resource_count(const gint * resources);
+gint resource_total(void);
+void resource_format_type(gchar * buffer, const gint * resources);
+const gchar *resource_name(Resource which, gboolean capital);
+gint game_resources(void);
+gint game_victory_points(void);
+gint stat_get_vp_value(StatisticType type);
+gboolean is_setup_double(void);
+gint turn_num(void);
+gboolean can_trade_domestic(void);
+gboolean can_trade_maritime(void);
+gboolean can_undo(void);
+gboolean can_move_ship(const Edge * from, const Edge * to);
+gboolean road_building_can_build_road(void);
+gboolean road_building_can_build_ship(void);
+gboolean road_building_can_build_bridge(void);
+gboolean road_building_can_finish(void);
+gboolean turn_can_build_road(void);
+gboolean turn_can_build_ship(void);
+gboolean turn_can_move_ship(void);
+gboolean turn_can_build_bridge(void);
+gboolean turn_can_build_settlement(void);
+gboolean turn_can_build_city(void);
+gboolean turn_can_build_city_wall(void);
+gboolean turn_can_trade(void);
+gboolean turn_can_finish(void);
+gboolean can_afford(const gint * cost);
+gboolean setup_can_build_road(void);
+gboolean setup_can_build_ship(void);
+gboolean setup_can_build_bridge(void);
+gboolean setup_can_build_settlement(void);
+gboolean setup_can_finish(void);
+gboolean setup_check_road(const Edge * edge);
+gboolean setup_check_ship(const Edge * edge);
+gboolean setup_check_bridge(const Edge * edge);
+gboolean setup_check_settlement(const Node * node);
+gboolean have_ships(void);
+gboolean have_bridges(void);
+gboolean have_city_walls(void);
+const GameParams *get_game_params(void);
+int pirate_count_victims(const Hex * hex, gint * victim_list);
+int robber_count_victims(const Hex * hex, gint * victim_list);
+const gint *get_bank(void);
+const DevelDeck *get_devel_deck(void);
+const gchar *get_devel_name(DevelType type);
+Map *get_map(void);
+
+/** Returns instructions for the user */
+const gchar *road_building_message(gint build_amount);
+
+#endif
Added: trunk/client/common/Makefile.am
===================================================================
--- trunk/client/common/Makefile.am (rev 0)
+++ trunk/client/common/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,39 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+noinst_LIBRARIES += libpioneersclient.a
+
+libpioneersclient_a_CPPFLAGS = -I$(top_srcdir)/client $(console_cflags)
+
+libpioneersclient_a_SOURCES = \
+ client/callback.h \
+ client/common/build.c \
+ client/common/callback.c \
+ client/common/client.c \
+ client/common/client.h \
+ client/common/develop.c \
+ client/common/i18n.c \
+ client/common/main.c \
+ client/common/player.c \
+ client/common/resource.c \
+ client/common/robber.c \
+ client/common/setup.c \
+ client/common/stock.c \
+ client/common/turn.c
Added: trunk/client/common/build.c
===================================================================
--- trunk/client/common/build.c (rev 0)
+++ trunk/client/common/build.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,203 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <math.h>
+#include <ctype.h>
+
+#include "game.h"
+#include "cards.h"
+#include "map.h"
+#include "client.h"
+#include "log.h"
+#include "buildrec.h"
+
+static GList *build_list;
+static gboolean built; /* have we buld road / settlement / city? */
+static gint num_edges, num_settlements;
+
+void build_clear(void)
+{
+ build_list = buildrec_free(build_list);
+ num_edges = num_settlements = 0;
+}
+
+void build_new_turn(void)
+{
+ build_list = buildrec_free(build_list);
+ built = FALSE;
+}
+
+void build_remove(BuildType type, gint x, gint y, gint pos)
+{
+ GList *list;
+ BuildRec *rec;
+
+ g_assert(build_list != NULL);
+
+ list = g_list_last(build_list);
+ rec = list->data;
+ build_list = g_list_remove(build_list, rec);
+ g_assert(rec->type == type
+ && rec->x == x && rec->y == y && rec->pos == pos);
+ g_free(rec);
+
+ switch (type) {
+ case BUILD_SETTLEMENT:
+ --num_settlements;
+ break;
+ case BUILD_ROAD:
+ case BUILD_SHIP:
+ case BUILD_BRIDGE:
+ --num_edges;
+ break;
+ default:
+ break;
+ }
+
+ /* If the build_list is now empty (no more items to undo), clear built flag
+ so trading is reallowed with strict-trade */
+ if (build_list == NULL)
+ built = FALSE;
+
+ player_build_remove(my_player_num(), type, x, y, pos);
+}
+
+/* Move a ship */
+void build_move(gint sx, gint sy, gint spos, gint dx, gint dy, gint dpos,
+ gint isundo)
+{
+ GList *list;
+ BuildRec *rec;
+ if (isundo) {
+ map->has_moved_ship = FALSE;
+ list = g_list_last(build_list);
+ rec = list->data;
+ if (rec->type != BUILD_MOVE_SHIP && rec->x != sx
+ && rec->y != sy && rec->pos != spos) {
+ log_message(MSG_ERROR,
+ "undo ship move mismatch: %d<->%d %d<->%d %d<->%d %d<->%d\n",
+ BUILD_MOVE_SHIP, rec->type, sx, rec->x,
+ sy, rec->y, spos, rec->pos);
+ }
+ build_list = g_list_remove(build_list, rec);
+ g_free(rec);
+ /* If the build_list is now empty (no more items to undo),
+ * clear built flag so trading is reallowed with
+ * strict-trade */
+ if (build_list == NULL)
+ built = FALSE;
+ } else {
+ rec = buildrec_new(BUILD_MOVE_SHIP, sx, sy, spos);
+ build_list = g_list_append(build_list, rec);
+ built = TRUE;
+ map->has_moved_ship = TRUE;
+ }
+ player_build_move(my_player_num(), sx, sy, spos, dx, dy, dpos,
+ isundo);
+}
+
+void build_add(BuildType type, gint x, gint y, gint pos, gboolean newbuild)
+{
+ BuildRec *rec = buildrec_new(type, x, y, pos);
+ build_list = g_list_append(build_list, rec);
+ built = TRUE;
+
+ switch (type) {
+ case BUILD_SETTLEMENT:
+ ++num_settlements;
+ break;
+ case BUILD_ROAD:
+ case BUILD_SHIP:
+ case BUILD_BRIDGE:
+ ++num_edges;
+ break;
+ default:
+ break;
+ }
+
+ if (newbuild) {
+ player_build_add(my_player_num(), type, x, y, pos, TRUE);
+ }
+}
+
+gint build_count_edges(void)
+{
+ return num_edges;
+}
+
+gint build_count_settlements(void)
+{
+ return num_settlements;
+}
+
+gint build_count(BuildType type)
+{
+ return buildrec_count_type(build_list, type);
+}
+
+gboolean build_is_valid(void)
+{
+ return buildrec_is_valid(build_list, map, my_player_num());
+}
+
+gboolean build_can_undo(void)
+{
+ return build_list != NULL;
+}
+
+gboolean have_built(void)
+{
+ return built;
+}
+
+/* Place some restrictions on road placement during setup phase
+ */
+gboolean build_can_setup_road(const Edge * edge, gboolean double_setup)
+{
+ return buildrec_can_setup_road(build_list, map, edge,
+ double_setup);
+}
+
+/* Place some restrictions on ship placement during setup phase
+ */
+gboolean build_can_setup_ship(const Edge * edge, gboolean double_setup)
+{
+ return buildrec_can_setup_ship(build_list, map, edge,
+ double_setup);
+}
+
+/* Place some restrictions on bridge placement during setup phase
+ */
+gboolean build_can_setup_bridge(const Edge * edge, gboolean double_setup)
+{
+ return buildrec_can_setup_bridge(build_list, map, edge,
+ double_setup);
+}
+
+/* Place some restrictions on road placement during setup phase
+ */
+gboolean build_can_setup_settlement(const Node * node,
+ gboolean double_setup)
+{
+ return buildrec_can_setup_settlement(build_list, map, node,
+ double_setup);
+}
Added: trunk/client/common/callback.c
===================================================================
--- trunk/client/common/callback.c (rev 0)
+++ trunk/client/common/callback.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,620 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2003,2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include "callback.h"
+#include "state.h"
+#include "client.h"
+#include "cost.h"
+
+/* callbacks is a pointer to an array of function pointers.
+ * It is filled in by the front end. */
+struct callbacks callbacks;
+
+/* these variables must be remembered between connect and handshake */
+gchar *requested_name = NULL;
+gboolean requested_viewer;
+gchar *requested_style = NULL;
+
+/* current callback mode */
+enum callback_mode callback_mode;
+
+/* is chat currently colourful? */
+gboolean color_chat_enabled;
+
+void cb_connect(const gchar * server, const gchar * port,
+ const gchar * name, gboolean viewer, const gchar * style)
+{
+ /* connect to a server */
+ g_assert(callback_mode == MODE_INIT);
+ if (requested_name)
+ g_free(requested_name);
+ requested_name = g_strdup(name);
+ requested_viewer = viewer;
+ if (requested_style)
+ g_free(requested_style);
+ requested_style = g_strdup(style);
+ if (sm_connect(SM(), server, port)) {
+ if (sm_is_connected(SM())) {
+ sm_goto(SM(), mode_start);
+ } else {
+ sm_goto(SM(), mode_connecting);
+ }
+ } else {
+ callbacks.offline();
+ }
+}
+
+void cb_disconnect(void)
+{
+ sm_close(SM());
+ callback_mode = MODE_INIT;
+ callbacks.offline();
+}
+
+void cb_roll(void)
+{
+ /* roll dice */
+ g_assert(callback_mode == MODE_TURN && !have_rolled_dice());
+ sm_send(SM(), "roll\n");
+ /* This should really be sm_push, but on return it should be
+ * sm_pop_noenter; sm_goto_noenter; sm_push, and since sm_pop_noenter
+ * doesn't exist, the combination is changed into
+ * sm_goto here and sm_goto_noenter; sm_push later. */
+ sm_goto(SM(), mode_roll_response);
+}
+
+void cb_build_road(const Edge * edge)
+{
+ /* build road */
+ g_assert(callback_mode == MODE_TURN
+ || callback_mode == MODE_ROAD_BUILD
+ || callback_mode == MODE_SETUP);
+ sm_send(SM(), "build road %d %d %d\n", edge->x, edge->y,
+ edge->pos);
+ sm_push(SM(), mode_build_response);
+}
+
+void cb_build_ship(const Edge * edge)
+{
+ /* build ship */
+ g_assert(callback_mode == MODE_TURN
+ || callback_mode == MODE_ROAD_BUILD
+ || callback_mode == MODE_SETUP);
+ sm_send(SM(), "build ship %d %d %d\n", edge->x, edge->y,
+ edge->pos);
+ sm_push(SM(), mode_build_response);
+}
+
+void cb_build_bridge(const Edge * edge)
+{
+ /* build bridge */
+ g_assert(callback_mode == MODE_TURN
+ || callback_mode == MODE_ROAD_BUILD
+ || callback_mode == MODE_SETUP);
+ sm_send(SM(), "build bridge %d %d %d\n", edge->x, edge->y,
+ edge->pos);
+ sm_push(SM(), mode_build_response);
+}
+
+void cb_move_ship(const Edge * from, const Edge * to)
+{
+ /* move ship */
+ g_assert(callback_mode == MODE_TURN);
+ sm_send(SM(), "move %d %d %d %d %d %d\n",
+ from->x, from->y, from->pos, to->x, to->y, to->pos);
+ sm_push(SM(), mode_move_response);
+}
+
+void cb_build_settlement(const Node * node)
+{
+ /* build settlement */
+ g_assert(callback_mode == MODE_TURN
+ || callback_mode == MODE_SETUP);
+ sm_send(SM(), "build settlement %d %d %d\n",
+ node->x, node->y, node->pos);
+ sm_push(SM(), mode_build_response);
+}
+
+void cb_build_city(const Node * node)
+{
+ /* build city */
+ g_assert(callback_mode == MODE_TURN);
+ sm_send(SM(), "build city %d %d %d\n", node->x, node->y,
+ node->pos);
+ sm_push(SM(), mode_build_response);
+}
+
+void cb_build_city_wall(const Node * node)
+{
+ /* build city */
+ g_assert(callback_mode == MODE_TURN);
+ sm_send(SM(), "build city_wall %d %d %d\n", node->x, node->y,
+ node->pos);
+ sm_push(SM(), mode_build_response);
+}
+
+void cb_buy_develop(void)
+{
+ /* buy development card */
+ g_assert(callback_mode == MODE_TURN && can_buy_develop());
+ sm_send(SM(), "buy-develop\n");
+ sm_push(SM(), mode_buy_develop_response);
+}
+
+void cb_play_develop(int card)
+{
+ /* play development card */
+ g_assert(callback_mode == MODE_TURN && can_play_develop(card));
+ sm_send(SM(), "play-develop %d\n", card);
+ sm_push(SM(), mode_play_develop_response);
+}
+
+void cb_undo(void)
+{
+ /* undo a move */
+ g_assert(callback_mode == MODE_TURN
+ || callback_mode == MODE_ROAD_BUILD
+ || callback_mode == MODE_SETUP
+ || callback_mode == MODE_ROB);
+ sm_send(SM(), "undo\n");
+ sm_push(SM(), mode_undo_response);
+}
+
+void cb_maritime(gint ratio, Resource supply, Resource receive)
+{
+ /* trade with the bank */
+ g_assert(callback_mode == MODE_TURN
+ || callback_mode == MODE_DOMESTIC);
+ sm_send(SM(), "maritime-trade %d supply %r receive %r\n",
+ ratio, supply, receive);
+ sm_push(SM(), mode_trade_maritime_response);
+}
+
+void cb_domestic(const gint * supply, const gint * receive)
+{
+ /* call for quotes */
+ g_assert(callback_mode == MODE_TURN
+ || callback_mode == MODE_DOMESTIC);
+ sm_send(SM(), "domestic-trade call supply %R receive %R\n",
+ supply, receive);
+ if (callback_mode == MODE_DOMESTIC) {
+ sm_push(SM(), mode_trade_call_again_response);
+ } else {
+ sm_push(SM(), mode_trade_call_response);
+ }
+}
+
+void cb_end_turn(void)
+{
+ /* end turn or road building or setup */
+ g_assert(callback_mode == MODE_TURN
+ || callback_mode == MODE_ROAD_BUILD
+ || callback_mode == MODE_SETUP);
+ sm_send(SM(), "done\n");
+ sm_push(SM(), mode_done_response);
+}
+
+void cb_place_robber(const Hex * hex)
+{
+ /* place robber */
+ g_assert(callback_mode == MODE_ROBBER);
+ sm_send(SM(), "move-robber %d %d\n", hex->x, hex->y);
+ sm_push(SM(), mode_robber_move_response);
+}
+
+void cb_rob(gint victim_num)
+{
+ /* after placing the robber, rob someone */
+ g_assert(callback_mode == MODE_ROB);
+ sm_send(SM(), "rob %d\n", victim_num);
+ sm_push(SM(), mode_robber_response);
+}
+
+void cb_choose_monopoly(gint resource)
+{
+ /* choose a monopoly resource */
+ g_assert(callback_mode == MODE_MONOPOLY);
+ sm_send(SM(), "monopoly %r\n", resource);
+ sm_push(SM(), mode_monopoly_response);
+}
+
+void cb_choose_plenty(gint * resources)
+{
+ /* choose year of plenty resources */
+ g_assert(callback_mode == MODE_PLENTY);
+ sm_send(SM(), "plenty %R\n", resources);
+ sm_push(SM(), mode_year_of_plenty_response);
+}
+
+void cb_trade(gint player, gint quote, const gint * supply,
+ const gint * receive)
+{
+ /* accept a domestic trade */
+ g_assert(callback_mode == MODE_DOMESTIC);
+ sm_send(SM(),
+ "domestic-trade accept player %d quote %d supply %R receive %R\n",
+ player, quote, supply, receive);
+ sm_push(SM(), mode_trade_domestic_response);
+}
+
+void cb_end_trade(void)
+{
+ /* stop trading */
+ g_assert(callback_mode == MODE_DOMESTIC);
+ sm_send(SM(), "domestic-trade finish\n");
+ sm_push(SM(), mode_domestic_finish_response);
+}
+
+void cb_quote(gint num, const gint * supply, const gint * receive)
+{
+ /* make a quote */
+ g_assert(callback_mode == MODE_QUOTE);
+ sm_send(SM(), "domestic-quote quote %d supply %R receive %R\n",
+ num, supply, receive);
+ sm_push(SM(), mode_quote_submit_response);
+}
+
+void cb_delete_quote(gint num)
+{
+ /* revoke a quote */
+ g_assert(callback_mode == MODE_QUOTE);
+ sm_send(SM(), "domestic-quote delete %d\n", num);
+ sm_push(SM(), mode_quote_delete_response);
+}
+
+void cb_end_quote(void)
+{
+ /* stop trading */
+ g_assert(callback_mode == MODE_QUOTE);
+ sm_send(SM(), "domestic-quote finish\n");
+ sm_push(SM(), mode_quote_finish_response);
+}
+
+void cb_chat(const gchar * text)
+{
+ /* chat a message */
+ g_assert(callback_mode != MODE_INIT);
+ sm_send(SM(), "chat %s\n", text);
+}
+
+void cb_name_change(const gchar * name)
+{
+ /* change your name */
+ g_assert(callback_mode != MODE_INIT);
+ sm_send(SM(), "name %s\n", name);
+}
+
+void cb_style_change(const gchar * style)
+{
+ /* change your style */
+ g_assert(callback_mode != MODE_INIT);
+ sm_send(SM(), "style %s\n", style);
+}
+
+void cb_discard(const gint * resources)
+{
+ /* discard resources */
+ g_assert(callback_mode == MODE_DISCARD);
+ callback_mode = MODE_DISCARD_WAIT;
+ sm_send(SM(), "discard %R\n", resources);
+}
+
+void cb_choose_gold(const gint * resources)
+{
+ /* choose gold */
+ g_assert(callback_mode == MODE_GOLD);
+ callback_mode = MODE_GOLD_WAIT;
+ sm_send(SM(), "chose-gold %R\n", resources);
+}
+
+gboolean have_ships(void)
+{
+ return game_params == NULL
+ || game_params->num_build_type[BUILD_SHIP] > 0;
+}
+
+gboolean have_bridges(void)
+{
+ return game_params == NULL
+ || game_params->num_build_type[BUILD_BRIDGE] > 0;
+}
+
+gboolean have_city_walls(void)
+{
+ return game_params == NULL
+ || game_params->num_build_type[BUILD_CITY_WALL] > 0;
+}
+
+const GameParams *get_game_params(void)
+{
+ return game_params;
+}
+
+gint game_resources(void)
+{
+ return game_params->resource_count;
+}
+
+gint game_victory_points(void)
+{
+ return game_params->victory_points;
+}
+
+gint stat_get_vp_value(StatisticType type)
+{
+ /* victory point values of all the statistic types */
+ static gint stat_vp_values[] = {
+ 1, /* settlement */
+ 2, /* city */
+ 0, /* city wall */
+ 2, /* largest army */
+ 2, /* longest road */
+ 1, /* chapel */
+ 1, /* pioneer university */
+ 1, /* governor's house */
+ 1, /* library */
+ 1, /* market */
+ 0, /* soldier */
+ 0, /* resource card */
+ 0, /* development card */
+ };
+
+ return stat_vp_values[type];
+}
+
+gboolean can_undo(void)
+{
+ return build_can_undo();
+}
+
+gboolean road_building_can_build_road(void)
+{
+ return build_count_edges() < 2
+ && stock_num_roads() > 0
+ && map_can_place_road(map, my_player_num());
+}
+
+gboolean road_building_can_build_ship(void)
+{
+ return build_count_edges() < 2
+ && stock_num_ships() > 0
+ && map_can_place_ship(map, my_player_num());
+}
+
+gboolean road_building_can_build_bridge(void)
+{
+ return build_count_edges() < 2
+ && stock_num_bridges() > 0
+ && map_can_place_bridge(map, my_player_num());
+}
+
+gboolean road_building_can_finish(void)
+{
+ return !road_building_can_build_road()
+ && !road_building_can_build_ship()
+ && !road_building_can_build_bridge()
+ && build_is_valid();
+}
+
+gboolean turn_can_build_road(void)
+{
+ return have_rolled_dice()
+ && stock_num_roads() > 0 && can_afford(cost_road())
+ && map_can_place_road(map, my_player_num());
+}
+
+gboolean turn_can_build_ship(void)
+{
+ return have_rolled_dice()
+ && stock_num_ships() > 0 && can_afford(cost_ship())
+ && map_can_place_ship(map, my_player_num());
+}
+
+gboolean turn_can_build_bridge(void)
+{
+ return have_rolled_dice()
+ && stock_num_bridges() > 0 && can_afford(cost_bridge())
+ && map_can_place_bridge(map, my_player_num());
+}
+
+gboolean turn_can_build_settlement(void)
+{
+ return have_rolled_dice()
+ && stock_num_settlements() > 0 && can_afford(cost_settlement())
+ && map_can_place_settlement(map, my_player_num());
+}
+
+gboolean turn_can_build_city(void)
+{
+ return have_rolled_dice()
+ && stock_num_cities() > 0
+ && can_afford(cost_upgrade_settlement())
+ && map_can_upgrade_settlement(map, my_player_num());
+}
+
+gboolean turn_can_build_city_wall(void)
+{
+ return have_rolled_dice()
+ && stock_num_city_walls() > 0 && can_afford(cost_city_wall())
+ && map_can_place_city_wall(map, my_player_num());
+}
+
+gboolean turn_can_trade(void)
+{
+ /* We are not allowed to trade before we have rolled the dice,
+ * or after we have done built a settlement / city, or after
+ * buying a development card.
+ */
+ if (!have_rolled_dice())
+ return FALSE;
+
+ if (game_params->strict_trade
+ && (have_built() || have_bought_develop()))
+ return FALSE;
+
+ return can_trade_maritime()
+ || can_trade_domestic();
+}
+
+static gboolean really_try_move_ship(G_GNUC_UNUSED Map * map, Hex * hex,
+ Edge * from)
+{
+ gint idx;
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); ++idx) {
+ Edge *edge;
+ edge = hex->edges[idx];
+ if (edge->x != hex->x || edge->y != hex->y)
+ continue;
+ if (can_move_ship(from, edge))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean can_move_ship(const Edge * from, const Edge * to)
+{
+ gboolean retval;
+ gint owner;
+ Edge *ship_sailed_from_here;
+
+ if (to == from)
+ return FALSE;
+ g_assert(from->type == BUILD_SHIP);
+ owner = from->owner;
+ if (!can_ship_be_moved(from, owner))
+ return FALSE;
+ ship_sailed_from_here = map_edge(map, from->x, from->y, from->pos); /* Copy to non-const pointer */
+ ship_sailed_from_here->owner = -1;
+ ship_sailed_from_here->type = BUILD_NONE;
+ retval = can_ship_be_built(to, owner);
+ ship_sailed_from_here->owner = owner;
+ ship_sailed_from_here->type = BUILD_SHIP;
+ return retval;
+}
+
+static gboolean try_move_ship(Map * map, Hex * hex)
+{
+ gint idx;
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); ++idx) {
+ Edge *edge;
+ edge = hex->edges[idx];
+ if (edge->x != hex->x || edge->y != hex->y)
+ continue;
+ if (edge->owner != my_player_num()
+ || edge->type != BUILD_SHIP)
+ continue;
+ if (map_traverse
+ (map, (HexFunc) really_try_move_ship, edge))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean turn_can_move_ship(void)
+{
+ if (!have_rolled_dice() || map->has_moved_ship)
+ return FALSE;
+ return map_traverse(map, (HexFunc) try_move_ship, NULL);
+}
+
+int robber_count_victims(const Hex * hex, gint * victim_list)
+{
+ gint idx;
+ gint node_idx;
+ gint num_victims;
+
+ /* If there is no-one to steal from, or the players have no
+ * resources, we do not go into steal_resource.
+ */
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); idx++)
+ victim_list[idx] = -1;
+ num_victims = 0;
+ for (node_idx = 0; node_idx < G_N_ELEMENTS(hex->nodes); node_idx++) {
+ Node *node = hex->nodes[node_idx];
+ Player *owner;
+
+ if (node->type == BUILD_NONE
+ || node->owner == my_player_num())
+ /* Can't steal from myself
+ */
+ continue;
+
+ /* Check if the node owner has any resources
+ */
+ owner = player_get(node->owner);
+ if (owner->statistics[STAT_RESOURCES] > 0) {
+ /* Has resources - we can steal
+ */
+ for (idx = 0; idx < num_victims; idx++)
+ if (victim_list[idx] == node->owner)
+ break;
+ if (idx == num_victims)
+ victim_list[num_victims++] = node->owner;
+ }
+ }
+
+ return num_victims;
+}
+
+int pirate_count_victims(const Hex * hex, gint * victim_list)
+{
+ gint idx;
+ gint edge_idx;
+ gint num_victims;
+
+ /* If there is no-one to steal from, or the players have no
+ * resources, we do not go into steal_resource.
+ */
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); idx++)
+ victim_list[idx] = -1;
+ num_victims = 0;
+ for (edge_idx = 0; edge_idx < G_N_ELEMENTS(hex->edges); edge_idx++) {
+ Edge *edge = hex->edges[edge_idx];
+ Player *owner;
+
+ if (edge->type != BUILD_SHIP
+ || edge->owner == my_player_num())
+ /* Can't steal from myself
+ */
+ continue;
+
+ /* Check if the node owner has any resources
+ */
+ owner = player_get(edge->owner);
+ if (owner->statistics[STAT_RESOURCES] > 0) {
+ /* Has resources - we can steal
+ */
+ for (idx = 0; idx < num_victims; idx++)
+ if (victim_list[idx] == edge->owner)
+ break;
+ if (idx == num_victims)
+ victim_list[num_victims++] = edge->owner;
+ }
+ }
+
+ return num_victims;
+}
+
+Map *get_map(void)
+{
+ return map;
+}
Added: trunk/client/common/client.c
===================================================================
--- trunk/client/common/client.c (rev 0)
+++ trunk/client/common/client.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,2642 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003-2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <ctype.h>
+#include <string.h>
+#include "game.h"
+#include "cards.h"
+#include "map.h"
+#include "network.h"
+#include "log.h"
+#include "cost.h"
+#include "client.h"
+#include "state.h"
+#include "callback.h"
+#include "buildrec.h"
+#include "quoteinfo.h"
+
+static enum callback_mode previous_mode;
+GameParams *game_params;
+Map *map;
+static struct recovery_info_t {
+ gchar *prevstate;
+ gint turnnum;
+ gint playerturn;
+ gint numdiscards;
+ gboolean rolled_dice;
+ gint die1, die2;
+ gboolean played_develop;
+ gboolean bought_develop;
+ GList *build_list;
+ gboolean ship_moved;
+} recovery_info;
+
+static gboolean global_unhandled(StateMachine * sm, gint event);
+static gboolean global_filter(StateMachine * sm, gint event);
+static gboolean mode_offline(StateMachine * sm, gint event);
+static gboolean mode_players(StateMachine * sm, gint event);
+static gboolean mode_player_list(StateMachine * sm, gint event);
+static gboolean mode_load_game(StateMachine * sm, gint event);
+static gboolean mode_load_gameinfo(StateMachine * sm, gint event);
+static gboolean mode_start_response(StateMachine * sm, gint event);
+static gboolean mode_setup(StateMachine * sm, gint event);
+static gboolean mode_idle(StateMachine * sm, gint event);
+static gboolean mode_wait_for_robber(StateMachine * sm, gint event);
+static gboolean mode_road_building(StateMachine * sm, gint event);
+static gboolean mode_monopoly(StateMachine * sm, gint event);
+static gboolean mode_year_of_plenty(StateMachine * sm, gint event);
+static gboolean mode_robber(StateMachine * sm, gint event);
+static gboolean mode_discard(StateMachine * sm, gint event);
+static gboolean mode_turn(StateMachine * sm, gint event);
+static gboolean mode_turn_rolled(StateMachine * sm, gint event);
+static gboolean mode_domestic_trade(StateMachine * sm, gint event);
+static gboolean mode_domestic_quote(StateMachine * sm, gint event);
+static gboolean mode_domestic_monitor(StateMachine * sm, gint event);
+static gboolean mode_game_over(StateMachine * sm, gint event);
+static gboolean mode_wait_resources(StateMachine * sm, gint event);
+static gboolean mode_recovery_wait_start_response(StateMachine * sm,
+ gint event);
+static void recover_from_disconnect(StateMachine * sm,
+ struct recovery_info_t *rinfo);
+
+/* Create and/or return the client state machine.
+ */
+StateMachine *SM(void)
+{
+ static StateMachine *state_machine;
+ if (state_machine == NULL) {
+ state_machine = sm_new(NULL);
+ sm_global_set(state_machine, global_filter);
+ sm_unhandled_set(state_machine, global_unhandled);
+ }
+ return state_machine;
+}
+
+/* When commands are sent to the server, front ends may want to update
+ * the status bar or something to indicate the the game is currently
+ * waiting for server respose.
+ * Since the GUI may get disabled while waiting, it is good to let the
+ * user know why all controls are unresponsive.
+ */
+static void waiting_for_network(gboolean is_waiting)
+{
+ if (is_waiting) {
+ callbacks.network_status(_("Waiting"));
+ } else {
+ callbacks.network_status(_("Idle"));
+ }
+ callbacks.network_wait(is_waiting);
+}
+
+/* Dummy callback functions. They do nothing */
+static void dummy_init(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
+{;
+}
+static void dummy_network_status(G_GNUC_UNUSED const gchar * description)
+{;
+}
+static void dummy_instructions(G_GNUC_UNUSED const gchar * message)
+{;
+}
+static void dummy_network_wait(G_GNUC_UNUSED gboolean is_waiting)
+{;
+}
+static void dummy_offline(void)
+{;
+}
+static void dummy_discard(void)
+{;
+}
+static void dummy_discard_add(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint discard_num)
+{;
+}
+static void dummy_discard_remove(G_GNUC_UNUSED gint player_num)
+{;
+}
+static void dummy_discard_done(void)
+{;
+}
+static void dummy_gold(void)
+{;
+}
+static void dummy_gold_add(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint gold_num)
+{;
+}
+static void dummy_gold_remove(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint * resources)
+{;
+}
+static void dummy_gold_choose(G_GNUC_UNUSED gint gold_num,
+ G_GNUC_UNUSED const gint * bank)
+{;
+}
+static void dummy_gold_done(void)
+{;
+}
+static void dummy_game_over(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint points)
+{;
+}
+static void dummy_init_game(void)
+{;
+}
+static void dummy_start_game(void)
+{;
+}
+static void dummy_setup(G_GNUC_UNUSED unsigned num_settlements,
+ G_GNUC_UNUSED unsigned num_roads)
+{;
+}
+static void dummy_quote(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint * they_supply,
+ G_GNUC_UNUSED gint * they_receive)
+{;
+}
+static void dummy_roadbuilding(G_GNUC_UNUSED gint num_roads)
+{;
+}
+static void dummy_monopoly(void)
+{;
+}
+static void dummy_plenty(G_GNUC_UNUSED const gint * bank)
+{;
+}
+static void dummy_turn(void)
+{;
+}
+static void dummy_player_turn(G_GNUC_UNUSED gint player_num)
+{;
+}
+static void dummy_trade(void)
+{;
+}
+static void dummy_trade_player_end(G_GNUC_UNUSED gint player_num)
+{;
+}
+static void dummy_trade_add_quote(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint quote_num,
+ G_GNUC_UNUSED const gint * they_supply,
+ G_GNUC_UNUSED const gint * they_receive)
+{;
+}
+static void dummy_trade_remove_quote(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint quote_num)
+{;
+}
+static void dummy_trade_domestic(G_GNUC_UNUSED gint partner_num,
+ G_GNUC_UNUSED gint quote_num,
+ G_GNUC_UNUSED const gint * we_supply,
+ G_GNUC_UNUSED const gint * we_receive)
+{;
+}
+static void dummy_trade_maritime(G_GNUC_UNUSED gint ratio,
+ G_GNUC_UNUSED Resource we_supply,
+ G_GNUC_UNUSED Resource we_receive)
+{;
+}
+static void dummy_quote_player_end(G_GNUC_UNUSED gint player_num)
+{;
+}
+static void dummy_quote_add(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint quote_num,
+ G_GNUC_UNUSED const gint * they_supply,
+ G_GNUC_UNUSED const gint * they_receive)
+{;
+}
+static void dummy_quote_remove(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint quote_num)
+{;
+}
+static void dummy_quote_start(void)
+{;
+}
+static void dummy_quote_end(void)
+{;
+}
+static void dummy_quote_monitor(void)
+{;
+}
+static void dummy_quote_trade(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint partner_num,
+ G_GNUC_UNUSED gint quote_num,
+ G_GNUC_UNUSED const gint * they_supply,
+ G_GNUC_UNUSED const gint * they_receive)
+{;
+}
+static void dummy_rolled_dice(G_GNUC_UNUSED gint die1,
+ G_GNUC_UNUSED gint die2,
+ G_GNUC_UNUSED gint player_num)
+{;
+}
+static void dummy_draw_edge(G_GNUC_UNUSED Edge * edge)
+{;
+}
+static void dummy_draw_node(G_GNUC_UNUSED Node * node)
+{;
+}
+static void dummy_bought_develop(G_GNUC_UNUSED DevelType type)
+{;
+}
+static void dummy_played_develop(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED gint card_idx,
+ G_GNUC_UNUSED DevelType type)
+{;
+}
+static void dummy_resource_change(G_GNUC_UNUSED Resource type,
+ G_GNUC_UNUSED gint num)
+{;
+}
+static void dummy_draw_hex(G_GNUC_UNUSED Hex * hex)
+{;
+}
+static void dummy_update_stock(void)
+{;
+}
+static void dummy_robber(void)
+{;
+}
+static void dummy_robber_moved(G_GNUC_UNUSED Hex * old,
+ G_GNUC_UNUSED Hex * new)
+{
+};
+static void dummy_steal_building(void)
+{;
+}
+static void dummy_steal_ship(void)
+{;
+}
+static void dummy_robber_done(void)
+{;
+}
+static void dummy_player_robbed(G_GNUC_UNUSED gint robber_num,
+ G_GNUC_UNUSED gint victim_num,
+ G_GNUC_UNUSED Resource resource)
+{;
+}
+static void dummy_get_rolled_resources(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED const gint *
+ resources,
+ G_GNUC_UNUSED const gint * wanted)
+{;
+}
+static void dummy_new_statistics(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED StatisticType type,
+ G_GNUC_UNUSED gint num)
+{;
+}
+static void dummy_new_points(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED Points * points,
+ G_GNUC_UNUSED gboolean added)
+{
+}
+static void dummy_viewer_name(G_GNUC_UNUSED gint viewer_num,
+ G_GNUC_UNUSED const gchar * name)
+{;
+}
+static void dummy_player_name(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED const gchar * name)
+{;
+}
+static void dummy_player_style(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED const gchar * style)
+{;
+}
+static void dummy_player_quit(G_GNUC_UNUSED gint player_num)
+{;
+}
+static void dummy_viewer_quit(G_GNUC_UNUSED gint player_num)
+{;
+}
+static void dummy_incoming_chat(G_GNUC_UNUSED gint player_num,
+ G_GNUC_UNUSED const gchar * chat)
+{;
+}
+static void dummy_new_bank(G_GNUC_UNUSED const gint * new_bank)
+{;
+}
+static void dummy_error(G_GNUC_UNUSED const gchar * message)
+{;
+}
+
+/*----------------------------------------------------------------------
+ * Entry point for the client state machine
+ */
+void client_init(void)
+{
+ /* first set everything to 0, so we are sure it segfaults if
+ * someone forgets to update this when adding a new callback */
+ memset(&callbacks, 0, sizeof(callbacks));
+ /* set all callbacks to their default value: doing nothing */
+ callbacks.init = &dummy_init;
+ callbacks.network_status = &dummy_network_status;
+ callbacks.instructions = &dummy_instructions;
+ callbacks.network_wait = &dummy_network_wait;
+ callbacks.offline = &dummy_offline;
+ callbacks.discard = &dummy_discard;
+ callbacks.discard_add = &dummy_discard_add;
+ callbacks.discard_remove = &dummy_discard_remove;
+ callbacks.discard_done = &dummy_discard_done;
+ callbacks.gold = &dummy_gold;
+ callbacks.gold_add = &dummy_gold_add;
+ callbacks.gold_remove = &dummy_gold_remove;
+ callbacks.gold_choose = &dummy_gold_choose;
+ callbacks.gold_done = &dummy_gold_done;
+ callbacks.game_over = &dummy_game_over;
+ callbacks.init_game = &dummy_init_game;
+ callbacks.start_game = &dummy_start_game;
+ callbacks.setup = &dummy_setup;
+ callbacks.quote = &dummy_quote;
+ callbacks.roadbuilding = &dummy_roadbuilding;
+ callbacks.monopoly = &dummy_monopoly;
+ callbacks.plenty = &dummy_plenty;
+ callbacks.turn = &dummy_turn;
+ callbacks.player_turn = &dummy_player_turn;
+ callbacks.trade = &dummy_trade;
+ callbacks.trade_player_end = &dummy_trade_player_end;
+ callbacks.trade_add_quote = &dummy_trade_add_quote;
+ callbacks.trade_remove_quote = &dummy_trade_remove_quote;
+ callbacks.trade_domestic = &dummy_trade_domestic;
+ callbacks.trade_maritime = &dummy_trade_maritime;
+ callbacks.quote_player_end = &dummy_quote_player_end;
+ callbacks.quote_add = &dummy_quote_add;
+ callbacks.quote_remove = &dummy_quote_remove;
+ callbacks.quote_start = &dummy_quote_start;
+ callbacks.quote_end = &dummy_quote_end;
+ callbacks.quote_monitor = &dummy_quote_monitor;
+ callbacks.quote_trade = &dummy_quote_trade;
+ callbacks.rolled_dice = &dummy_rolled_dice;
+ callbacks.draw_edge = &dummy_draw_edge;
+ callbacks.draw_node = &dummy_draw_node;
+ callbacks.bought_develop = &dummy_bought_develop;
+ callbacks.played_develop = &dummy_played_develop;
+ callbacks.resource_change = &dummy_resource_change;
+ callbacks.draw_hex = &dummy_draw_hex;
+ callbacks.update_stock = &dummy_update_stock;
+ callbacks.robber = &dummy_robber;
+ callbacks.robber_moved = &dummy_robber_moved;
+ callbacks.steal_building = &dummy_steal_building;
+ callbacks.steal_ship = &dummy_steal_ship;
+ callbacks.robber_done = &dummy_robber_done;
+ callbacks.player_robbed = &dummy_player_robbed;
+ callbacks.get_rolled_resources = &dummy_get_rolled_resources;
+ callbacks.new_statistics = &dummy_new_statistics;
+ callbacks.new_points = &dummy_new_points;
+ callbacks.viewer_name = &dummy_viewer_name;
+ callbacks.player_name = &dummy_player_name;
+ callbacks.player_style = &dummy_player_style;
+ callbacks.player_quit = &dummy_player_quit;
+ callbacks.viewer_quit = &dummy_viewer_quit;
+ callbacks.incoming_chat = &dummy_incoming_chat;
+ callbacks.new_bank = &dummy_new_bank;
+ callbacks.error = &dummy_error;
+ /* mainloop and quit are not set here */
+ resource_init();
+}
+
+void client_start(int argc, char **argv)
+{
+ callbacks.init(argc, argv);
+ sm_goto(SM(), mode_offline);
+}
+
+/*----------------------------------------------------------------------
+ * The state machine API supports two global event handling callbacks.
+ *
+ * All events are sent to the global event handler before they are
+ * sent to the current state function. If the global event handler
+ * handles the event and returns TRUE, the event will not be sent to
+ * the current state function. is which allow unhandled events to be
+ * processed via a callback.
+ *
+ * If an event is not handled by either the global event handler, or
+ * the current state function, then it will be sent to the unhandled
+ * event handler. Using this, the client code implements some of the
+ * error handling globally.
+ */
+
+/* Global event handler - this get first crack at events. If we
+ * return TRUE, the event will not be passed to the current state
+ * function.
+ */
+static gboolean global_filter(StateMachine * sm, gint event)
+{
+ switch (event) {
+ case SM_NET_CLOSE:
+ log_message(MSG_ERROR,
+ _("We have been kicked out of the game.\n"));
+ waiting_for_network(FALSE);
+ sm_pop_all_and_goto(sm, mode_offline);
+ callbacks.network_status(_("Offline"));
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/* Global unhandled event handler - this get called for events that
+ * fall through the state machine without being handled.
+ */
+static gboolean global_unhandled(StateMachine * sm, gint event)
+{
+ gchar *str;
+
+ switch (event) {
+ case SM_NET_CLOSE:
+ g_error("SM_NET_CLOSE not caught by global_filter");
+ case SM_RECV:
+ /* all errors start with ERR */
+ if (sm_recv(sm, "ERR %S", &str)) {
+ log_message(MSG_ERROR, _("Error (%s): %s\n"),
+ sm_current_name(sm), str);
+ callbacks.error(str);
+ g_free(str);
+ return TRUE;
+ }
+ /* notices which are not errors should appear in the message
+ * window */
+ if (sm_recv(sm, "NOTE %S", &str)) {
+ log_message(MSG_ERROR, _("Notice: %s\n"), _(str));
+ g_free(str);
+ return TRUE;
+ }
+ /* A notice with 1 argument */
+ if (sm_recv(sm, "NOTE1 %S", &str)) {
+ gchar *message;
+ gchar **parts;
+
+ parts = g_strsplit(str, "|", 2);
+ message = g_strdup_printf(_(parts[1]), parts[0]);
+ log_message(MSG_ERROR, _("Notice: %s\n"), message);
+ g_strfreev(parts);
+ g_free(message);
+ g_free(str);
+ return TRUE;
+ }
+ /* protocol extensions which may be ignored have this prefix
+ * before the next protocol changing version of the game is
+ * released. Notify the client about it anyway. */
+ if (sm_recv(sm, "extension %S", &str)) {
+ log_message(MSG_INFO,
+ "Ignoring extension used by server: %s\n",
+ str);
+ g_free(str);
+ return TRUE;
+ }
+ /* we're receiving strange things */
+ if (sm_recv(sm, "%S", &str)) {
+ log_message(MSG_ERROR,
+ "Unknown message in %s: %s\n",
+ sm_current_name(sm), str);
+ g_free(str);
+ return TRUE;
+ }
+ /* this is never reached: everything matches "%S" */
+ g_error
+ ("This should not be possible, please report this bug.\n");
+ default:
+ break;
+ }
+ /* this may happen, for example when a hotkey is used for a function
+ * which cannot be activated */
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Server notifcations about player name changes and chat messages.
+ * These can happen in any state (maybe this should be moved to
+ * global_filter()?).
+ */
+static gboolean check_chat_or_name(StateMachine * sm)
+{
+ gint player_num;
+ gchar *str;
+
+ if (sm_recv(sm, "player %d chat %S", &player_num, &str)) {
+ callbacks.incoming_chat(player_num, str);
+ g_free(str);
+ return TRUE;
+ }
+ if (sm_recv(sm, "player %d is %S", &player_num, &str)) {
+ player_change_name(player_num, str);
+ g_free(str);
+ return TRUE;
+ }
+ if (sm_recv(sm, "player %d style %S", &player_num, &str)) {
+ player_change_style(player_num, str);
+ g_free(str);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Server notifcations about other players name changes and chat
+ * messages. These can happen in almost any state in which the game
+ * is running.
+ */
+static gboolean check_other_players(StateMachine * sm)
+{
+ BuildType build_type;
+ DevelType devel_type;
+ Resource resource_type, supply_type, receive_type;
+ gint player_num, victim_num, card_idx, backwards;
+ gint turn_num, discard_num, num, ratio, die1, die2, x, y, pos;
+ gint id;
+ gint resource_list[NO_RESOURCE], wanted_list[NO_RESOURCE];
+ gint sx, sy, spos, dx, dy, dpos;
+ gchar *str;
+
+ if (check_chat_or_name(sm))
+ return TRUE;
+
+ if (!sm_recv_prefix(sm, "player %d ", &player_num))
+ return FALSE;
+
+ if (sm_recv(sm, "built %B %d %d %d", &build_type, &x, &y, &pos)) {
+ player_build_add(player_num, build_type, x, y, pos, TRUE);
+ return TRUE;
+ }
+ if (sm_recv
+ (sm, "move %d %d %d %d %d %d", &sx, &sy, &spos, &dx, &dy,
+ &dpos)) {
+ player_build_move(player_num, sx, sy, spos, dx, dy, dpos,
+ FALSE);
+ return TRUE;
+ }
+ if (sm_recv
+ (sm, "move-back %d %d %d %d %d %d", &sx, &sy, &spos, &dx, &dy,
+ &dpos)) {
+ player_build_move(player_num, sx, sy, spos, dx, dy, dpos,
+ TRUE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "remove %B %d %d %d", &build_type, &x, &y, &pos)) {
+ player_build_remove(player_num, build_type, x, y, pos);
+ return TRUE;
+ }
+ if (sm_recv(sm, "receives %R %R", resource_list, wanted_list)) {
+ gint i;
+ for (i = 0; i < NO_RESOURCE; ++i) {
+ if (resource_list[i] == wanted_list[i])
+ continue;
+ if (resource_list[i] == 0) {
+ log_message(MSG_RESOURCE,
+ _
+ ("%s does not receive any %s, because the bank is empty.\n"),
+ player_name(player_num, TRUE),
+ resource_name(i, FALSE));
+ } else {
+ gint j, list[NO_RESOURCE];
+ gchar *buff;
+ for (j = 0; j < NO_RESOURCE; ++j)
+ list[j] = 0;
+ list[i] = resource_list[i];
+ resource_list[i] = 0;
+ buff = resource_format_num(list);
+ log_message(MSG_RESOURCE,
+ _
+ ("%s only receives %s, because the bank didn't have any more.\n"),
+ player_name(player_num, TRUE),
+ buff);
+ g_free(buff);
+ resource_apply_list(player_num, list, 1);
+ }
+ }
+ if (resource_count(resource_list) != 0)
+ player_resource_action(player_num,
+ _("%s receives %s.\n"),
+ resource_list, 1);
+ callbacks.get_rolled_resources(player_num, resource_list,
+ wanted_list);
+ return TRUE;
+ }
+ if (sm_recv(sm, "plenty %R", resource_list)) {
+ /* Year of Plenty */
+ player_resource_action(player_num, _("%s takes %s.\n"),
+ resource_list, 1);
+ return TRUE;
+ }
+ if (sm_recv(sm, "spent %R", resource_list)) {
+ player_resource_action(player_num, _("%s spent %s.\n"),
+ resource_list, -1);
+ return TRUE;
+ }
+ if (sm_recv(sm, "refund %R", resource_list)) {
+ player_resource_action(player_num,
+ _("%s is refunded %s.\n"),
+ resource_list, 1);
+ return TRUE;
+ }
+ if (sm_recv(sm, "bought-develop")) {
+ develop_bought(player_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "play-develop %d %D", &card_idx, &devel_type)) {
+ develop_played(player_num, card_idx, devel_type);
+ return TRUE;
+ }
+ if (sm_recv(sm, "turn %d", &turn_num)) {
+ turn_begin(player_num, turn_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "rolled %d %d", &die1, &die2)) {
+ turn_rolled_dice(player_num, die1, die2);
+ if (die1 + die2 != 7)
+ sm_push(sm, mode_wait_resources);
+ return TRUE;
+ }
+ if (sm_recv(sm, "must-discard %d", &discard_num)) {
+ waiting_for_network(FALSE);
+ sm_push(sm, mode_discard);
+ if (player_num == my_player_num())
+ callback_mode = MODE_DISCARD;
+ callbacks.discard_add(player_num, discard_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "discarded %R", resource_list)) {
+ player_resource_action(player_num, _("%s discarded %s.\n"),
+ resource_list, -1);
+ callbacks.discard_remove(player_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "is-robber")) {
+ robber_begin_move(player_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "moved-robber %d %d", &x, &y)) {
+ robber_moved(player_num, x, y, FALSE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "moved-pirate %d %d", &x, &y)) {
+ pirate_moved(player_num, x, y, FALSE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "unmoved-robber %d %d", &x, &y)) {
+ robber_moved(player_num, x, y, TRUE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "unmoved-pirate %d %d", &x, &y)) {
+ pirate_moved(player_num, x, y, TRUE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "stole from %d", &victim_num)) {
+ player_stole_from(player_num, victim_num, NO_RESOURCE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "stole %r from %d", &resource_type, &victim_num)) {
+ player_stole_from(player_num, victim_num, resource_type);
+ return TRUE;
+ }
+ if (sm_recv
+ (sm, "monopoly %d %r from %d", &num, &resource_type,
+ &victim_num)) {
+ monopoly_player(player_num, victim_num, num,
+ resource_type);
+ return TRUE;
+ }
+ if (sm_recv(sm, "largest-army")) {
+ player_largest_army(player_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "longest-road")) {
+ player_longest_road(player_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "get-point %d %d %S", &id, &num, &str)) {
+ player_get_point(player_num, id, str, num);
+ g_free(str);
+ return TRUE;
+ }
+ if (sm_recv(sm, "lose-point %d", &id)) {
+ player_lose_point(player_num, id);
+ return TRUE;
+ }
+ if (sm_recv(sm, "take-point %d %d", &id, &victim_num)) {
+ player_take_point(player_num, id, victim_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "setup %d", &backwards)) {
+ setup_begin(player_num);
+ if (backwards)
+ sm_push(sm, mode_wait_resources);
+ return TRUE;
+ }
+ if (sm_recv(sm, "setup-double")) {
+ setup_begin_double(player_num);
+ sm_push(sm, mode_wait_resources);
+ return TRUE;
+ }
+ if (sm_recv(sm, "won with %d", &num)) {
+ callbacks.game_over(player_num, num);
+ sm_pop_all_and_goto(sm, mode_game_over);
+ return TRUE;
+ }
+ if (sm_recv(sm, "has quit")) {
+ player_has_quit(player_num);
+ return TRUE;
+ }
+
+ if (sm_recv(sm, "maritime-trade %d supply %r receive %r",
+ &ratio, &supply_type, &receive_type)) {
+ player_maritime_trade(player_num, ratio, supply_type,
+ receive_type);
+ return TRUE;
+ }
+
+ sm_cancel_prefix(sm);
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * State machine state functions.
+ *
+ * The state machine API works like this:
+ *
+ * SM_ENTER:
+ * When a state is entered the new state function is called with the
+ * SM_ENTER event. This allows the client to perform state
+ * initialisation.
+ *
+ * SM_INIT:
+ * When a state is entered, and every time an event is handled, the
+ * state machine code calls the current state function with an
+ * SM_INIT event.
+ *
+ * SM_RECV:
+ * Indicates that a message has been received from the server.
+ *
+ * SM_NET_*:
+ * These are network connection related events.
+ *
+ * To change current state function, use sm_goto().
+ *
+ * The state machine API also implements a state stack. This allows
+ * us to reuse parts of the state machine by pushing the current
+ * state, and then returning to it when the nested processing is
+ * complete.
+ *
+ * The state machine nesting can be used via sm_push() and sm_pop().
+ */
+
+/*----------------------------------------------------------------------
+ * Game startup and offline handling
+ */
+
+static gboolean mode_offline(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_offline");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_INIT;
+ callbacks.offline();
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/* Waiting for connect to complete
+ */
+gboolean mode_connecting(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_connecting");
+ switch (event) {
+ case SM_NET_CONNECT:
+ sm_goto(sm, mode_start);
+ return TRUE;
+ case SM_NET_CONNECT_FAIL:
+ sm_goto(sm, mode_offline);
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/* Handle initial signon message
+ */
+gboolean mode_start(StateMachine * sm, gint event)
+{
+ gint player_num, total_num;
+ gchar *version;
+
+ sm_state_name(sm, "mode_start");
+
+ if (event == SM_ENTER) {
+ callbacks.network_status(_("Loading"));
+ player_reset();
+ callbacks.init_game();
+ }
+
+ if (event != SM_RECV)
+ return FALSE;
+ if (sm_recv(sm, "version report")) {
+ sm_send(sm, "version %s\n", PROTOCOL_VERSION);
+ return TRUE;
+ }
+ if (sm_recv(sm, "status report")) {
+ if (requested_viewer) {
+ if (requested_name[0] != '\0') {
+ sm_send(sm, "status viewer %s\n",
+ requested_name);
+ } else {
+ sm_send(sm, "status newviewer\n");
+ }
+ } else {
+ if (requested_name[0] != '\0') {
+ sm_send(sm, "status reconnect %s\n",
+ requested_name);
+ } else {
+ sm_send(sm, "status newplayer\n");
+ }
+ }
+ return TRUE;
+ }
+ if (sm_recv(sm, "player %d of %d, welcome to pioneers server %S",
+ &player_num, &total_num, &version)) {
+ g_free(version);
+ player_set_my_num(player_num);
+ player_set_total_num(total_num);
+ sm_send(sm, "style %s\n", requested_style);
+ sm_send(sm, "players\n");
+ sm_goto(sm, mode_players);
+
+ return TRUE;
+ }
+ if (sm_recv(sm, "ERR sorry, version conflict")) {
+ sm_pop_all_and_goto(sm, mode_offline);
+ callbacks.network_status(_("Offline"));
+ callbacks.instructions(_("Version mismatch"));
+ log_message(MSG_ERROR,
+ _("Version mismatch. Please make sure client "
+ "and server are up to date.\n"));
+ return TRUE;
+ }
+ return check_chat_or_name(sm);
+}
+
+/* Response to "players" command
+ */
+static gboolean mode_players(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_players");
+ if (event != SM_RECV)
+ return FALSE;
+ if (sm_recv(sm, "players follow")) {
+ sm_goto(sm, mode_player_list);
+ return TRUE;
+ }
+ return check_other_players(sm);
+}
+
+/* Handle list of players
+ */
+static gboolean mode_player_list(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_player_list");
+ if (event != SM_RECV)
+ return FALSE;
+ if (sm_recv(sm, ".")) {
+ sm_send(sm, "game\n");
+ sm_goto(sm, mode_load_game);
+ return TRUE;
+ }
+ return check_other_players(sm);
+}
+
+/* Response to "game" command
+ */
+static gboolean mode_load_game(StateMachine * sm, gint event)
+{
+ gchar *str;
+
+ sm_state_name(sm, "mode_load_game");
+ if (event != SM_RECV)
+ return FALSE;
+ if (sm_recv(sm, "game")) {
+ if (game_params != NULL)
+ params_free(game_params);
+ game_params = params_new();
+ return TRUE;
+ }
+ if (sm_recv(sm, "end")) {
+ params_load_finish(game_params);
+ map = game_params->map;
+ stock_init();
+ develop_init();
+ /* initialize global recovery info struct */
+ recovery_info.prevstate = NULL;
+ recovery_info.turnnum = -1;
+ recovery_info.playerturn = -1;
+ recovery_info.numdiscards = -1;
+ recovery_info.rolled_dice = FALSE;
+ recovery_info.die1 = -1;
+ recovery_info.die2 = -1;
+ recovery_info.played_develop = FALSE;
+ recovery_info.bought_develop = FALSE;
+ recovery_info.build_list = NULL;
+ recovery_info.ship_moved = FALSE;
+
+ sm_send(sm, "gameinfo\n");
+ sm_goto(sm, mode_load_gameinfo);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ if (sm_recv(sm, "%S", &str)) {
+ params_load_line(game_params, str);
+ g_free(str);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Response to "gameinfo" command
+ */
+static gboolean mode_load_gameinfo(StateMachine * sm, gint event)
+{
+ gint x, y, pos, owner;
+ static gboolean disconnected = FALSE;
+ static gboolean have_bank = FALSE;
+ static gint devcardidx = -1;
+ static gint numdevcards = -1;
+ gint num_roads, num_bridges, num_ships, num_settlements,
+ num_cities, num_soldiers, road_len;
+ gint opnum, opnassets, opncards, opnsoldiers;
+ gboolean pchapel, puniv, pgov, plibr, pmarket, plongestroad,
+ plargestarmy;
+ gint point_id, point_points;
+ gchar *point_name;
+ DevelType devcard;
+ gint devcardturnbought;
+ BuildType btype;
+ gint resources[NO_RESOURCE];
+ gint tmp_bank[NO_RESOURCE];
+ gint devbought;
+
+ sm_state_name(sm, "mode_load_gameinfo");
+ if (event == SM_ENTER) {
+ gint idx;
+
+ have_bank = FALSE;
+ for (idx = 0; idx < NO_RESOURCE; ++idx)
+ tmp_bank[idx] = game_params->resource_count;
+ set_bank(tmp_bank);
+ }
+ if (event != SM_RECV)
+ return FALSE;
+ if (sm_recv(sm, "gameinfo")) {
+ return TRUE;
+ }
+ if (sm_recv(sm, ".")) {
+ return TRUE;
+ }
+ if (sm_recv(sm, "end")) {
+ callback_mode = MODE_WAIT_TURN; /* allow chatting */
+ callbacks.start_game();
+ if (disconnected) {
+ sm_goto(sm, mode_recovery_wait_start_response);
+ } else {
+ sm_send(sm, "start\n");
+ sm_goto(sm, mode_start_response);
+ }
+ return TRUE;
+ }
+ if (sm_recv(sm, "bank %R", tmp_bank)) {
+ set_bank(tmp_bank);
+ have_bank = TRUE;
+ return TRUE;
+ }
+ if (sm_recv(sm, "development-bought %d", &devbought)) {
+ gint i;
+ for (i = 0; i < devbought; i++)
+ stock_use_develop();
+ return TRUE;
+ }
+ if (sm_recv(sm, "turn num %d", &recovery_info.turnnum)) {
+ return TRUE;
+ }
+ if (sm_recv(sm, "player turn: %d", &recovery_info.playerturn)) {
+ return TRUE;
+ }
+ if (sm_recv
+ (sm, "dice rolled: %d %d", &recovery_info.die1,
+ &recovery_info.die2)) {
+ recovery_info.rolled_dice = TRUE;
+ return TRUE;
+ }
+ if (sm_recv
+ (sm, "dice value: %d %d", &recovery_info.die1,
+ &recovery_info.die2)) {
+ return TRUE;
+ }
+ if (sm_recv(sm, "played develop")) {
+ recovery_info.played_develop = TRUE;
+ return TRUE;
+ }
+ if (sm_recv(sm, "moved ship")) {
+ recovery_info.ship_moved = TRUE;
+ return TRUE;
+ }
+ if (sm_recv(sm, "bought develop")) {
+ recovery_info.bought_develop = TRUE;
+ return TRUE;
+ }
+ if (sm_recv(sm, "player disconnected")) {
+ disconnected = TRUE;
+ return TRUE;
+ }
+ if (sm_recv(sm, "state %S", &recovery_info.prevstate)) {
+ return TRUE;
+ }
+ if (sm_recv(sm, "playerinfo: resources: %R", resources)) {
+ resource_init();
+ resource_apply_list(my_player_num(), resources, 1);
+ /* If the bank was copied from the server, it should not be
+ * compensated for my own resources, because it was already
+ * correct. So we compensate it back. */
+ if (have_bank)
+ modify_bank(resources);
+ return TRUE;
+ }
+ if (sm_recv(sm, "playerinfo: numdevcards: %d", &numdevcards)) {
+ devcardidx = 0;
+ return TRUE;
+ }
+ if (sm_recv
+ (sm, "playerinfo: devcard: %d %d", &devcard,
+ &devcardturnbought)) {
+ if (devcardidx >= numdevcards) {
+ return FALSE;
+ }
+
+ develop_bought_card_turn(devcard, devcardturnbought);
+
+ devcardidx++;
+ if (devcardidx >= numdevcards) {
+ devcardidx = numdevcards = -1;
+ }
+ return TRUE;
+ }
+ if (sm_recv
+ (sm, "playerinfo: %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
+ &num_roads, &num_bridges, &num_ships, &num_settlements,
+ &num_cities, &num_soldiers, &road_len, &pchapel, &puniv,
+ &pgov, &plibr, &pmarket, &plongestroad, &plargestarmy)) {
+ player_modify_statistic(my_player_num(), STAT_SOLDIERS,
+ num_soldiers);
+ if (pchapel) {
+ player_modify_statistic(my_player_num(),
+ STAT_CHAPEL, 1);
+ }
+ if (puniv) {
+ player_modify_statistic(my_player_num(),
+ STAT_UNIVERSITY, 1);
+ }
+ if (pgov) {
+ player_modify_statistic(my_player_num(),
+ STAT_GOVERNORS_HOUSE, 1);
+ }
+ if (plibr) {
+ player_modify_statistic(my_player_num(),
+ STAT_LIBRARY, 1);
+ }
+ if (pmarket) {
+ player_modify_statistic(my_player_num(),
+ STAT_MARKET, 1);
+ }
+ if (plongestroad) {
+ player_modify_statistic(my_player_num(),
+ STAT_LONGEST_ROAD, 1);
+ }
+ if (plargestarmy) {
+ player_modify_statistic(my_player_num(),
+ STAT_LARGEST_ARMY, 1);
+ }
+ return TRUE;
+ }
+ if (sm_recv
+ (sm, "get-point %d %d %d %S", &opnum, &point_id, &point_points,
+ &point_name)) {
+ Points *points =
+ points_new(point_id, point_name, point_points);
+ player_modify_points(opnum, points, TRUE); /* Added */
+ return TRUE;
+ }
+
+ if (sm_recv
+ (sm, "otherplayerinfo: %d %d %d %d %d %d %d %d %d %d %d",
+ &opnum, &opnassets, &opncards, &opnsoldiers, &pchapel, &puniv,
+ &pgov, &plibr, &pmarket, &plongestroad, &plargestarmy)) {
+ player_modify_statistic(opnum, STAT_RESOURCES, opnassets);
+ player_modify_statistic(opnum, STAT_DEVELOPMENT, opncards);
+ player_modify_statistic(opnum, STAT_SOLDIERS, opnsoldiers);
+ if (opnassets != 0)
+ g_assert(have_bank);
+ if (pchapel) {
+ player_modify_statistic(opnum, STAT_CHAPEL, 1);
+ }
+ if (puniv) {
+ player_modify_statistic(opnum, STAT_UNIVERSITY, 1);
+ }
+ if (pgov) {
+ player_modify_statistic(opnum,
+ STAT_GOVERNORS_HOUSE, 1);
+ }
+ if (plibr) {
+ player_modify_statistic(opnum, STAT_LIBRARY, 1);
+ }
+ if (pmarket) {
+ player_modify_statistic(opnum, STAT_MARKET, 1);
+ }
+ if (plongestroad) {
+ player_modify_statistic(opnum, STAT_LONGEST_ROAD,
+ 1);
+ }
+ if (plargestarmy) {
+ player_modify_statistic(opnum, STAT_LARGEST_ARMY,
+ 1);
+ }
+ return TRUE;
+ }
+ if (sm_recv(sm, "buildinfo: %B %d %d %d", &btype, &x, &y, &pos)) {
+ BuildRec *rec;
+ rec = g_malloc0(sizeof(*rec));
+ rec->type = btype;
+ rec->x = x;
+ rec->y = y;
+ rec->pos = pos;
+ recovery_info.build_list =
+ g_list_append(recovery_info.build_list, rec);
+ return TRUE;
+ }
+ if (sm_recv(sm, "RO%d,%d", &x, &y)) {
+ robber_move_on_map(x, y);
+ return TRUE;
+ }
+ if (sm_recv(sm, "P%d,%d", &x, &y)) {
+ pirate_move_on_map(x, y);
+ return TRUE;
+ }
+ if (sm_recv(sm, "S%d,%d,%d,%d", &x, &y, &pos, &owner)) {
+ player_build_add(owner, BUILD_SETTLEMENT, x, y, pos,
+ FALSE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "C%d,%d,%d,%d", &x, &y, &pos, &owner)) {
+ player_build_add(owner, BUILD_CITY, x, y, pos, FALSE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "W%d,%d,%d,%d", &x, &y, &pos, &owner)) {
+ player_build_add(owner, BUILD_CITY_WALL, x, y, pos, FALSE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "R%d,%d,%d,%d", &x, &y, &pos, &owner)) {
+ player_build_add(owner, BUILD_ROAD, x, y, pos, FALSE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "SH%d,%d,%d,%d", &x, &y, &pos, &owner)) {
+ player_build_add(owner, BUILD_SHIP, x, y, pos, FALSE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "B%d,%d,%d,%d", &x, &y, &pos, &owner)) {
+ player_build_add(owner, BUILD_BRIDGE, x, y, pos, FALSE);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Response to the "start" command
+ */
+static gboolean mode_start_response(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_start_response");
+ if (event != SM_RECV)
+ return FALSE;
+ if (sm_recv(sm, "OK")) {
+ sm_goto(sm, mode_idle);
+ callbacks.network_status(_("Idle"));
+ return TRUE;
+ }
+ return check_other_players(sm);
+}
+
+/*----------------------------------------------------------------------
+ * Build command processing
+ */
+
+/* Handle response to build command
+ */
+gboolean mode_build_response(StateMachine * sm, gint event)
+{
+ BuildType build_type;
+ gint x, y, pos;
+
+ sm_state_name(sm, "mode_build_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "built %B %d %d %d",
+ &build_type, &x, &y, &pos)) {
+ build_add(build_type, x, y, pos, TRUE);
+ waiting_for_network(FALSE);
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Handle response to move ship command
+ */
+gboolean mode_move_response(StateMachine * sm, gint event)
+{
+ gint sx, sy, spos, dx, dy, dpos;
+
+ sm_state_name(sm, "mode_move_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "move %d %d %d %d %d %d",
+ &sx, &sy, &spos, &dx, &dy, &dpos)) {
+ build_move(sx, sy, spos, dx, dy, dpos, FALSE);
+ waiting_for_network(FALSE);
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Setup phase handling
+ */
+
+/* Response to a "done"
+ */
+gboolean mode_done_response(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_done_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "OK")) {
+ build_clear();
+ waiting_for_network(FALSE);
+ /* pop back to parent's parent if "done" worked */
+ sm_multipop(sm, 2);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+static char *setup_msg(void)
+{
+ gchar *msg;
+ const gchar *parts[3];
+ int num_parts;
+ int idx;
+
+ if (is_setup_double())
+ msg = g_strdup(_("Build two settlements, "
+ "each with a connecting"));
+ else
+ msg = g_strdup(_("Build a settlement with a connecting"));
+ num_parts = 0;
+ if (setup_can_build_road())
+ parts[num_parts++] = _("road");
+ if (setup_can_build_bridge())
+ parts[num_parts++] = _("bridge");
+ if (setup_can_build_ship())
+ parts[num_parts++] = _("ship");
+
+ for (idx = 0; idx < num_parts; idx++) {
+ gchar *old;
+ if (idx > 0) {
+ if (idx == num_parts - 1) {
+ old = msg;
+ msg =
+ g_strdup_printf("%s%s", msg, _(" or"));
+ g_free(old);
+ } else {
+ old = msg;
+ msg = g_strdup_printf("%s,", msg);
+ g_free(old);
+ }
+ }
+ old = msg;
+ msg = g_strdup_printf("%s %s", msg, parts[idx]);
+ g_free(old);
+ }
+
+ return msg;
+}
+
+static gboolean mode_setup(StateMachine * sm, gint event)
+{
+ unsigned total;
+ sm_state_name(sm, "mode_setup");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_SETUP;
+ callbacks.instructions(setup_msg());
+ total = is_setup_double()? 2 : 1;
+ callbacks.setup(total - build_count_settlements(),
+ total - build_count_edges());
+ break;
+ case SM_RECV:
+ /* When a line of text comes in from the network, the
+ * state machine will call us with SM_RECV.
+ */
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Game is up and running - waiting for our turn
+ */
+
+/* Waiting for your turn to come around
+ */
+static gboolean mode_idle(StateMachine * sm, gint event)
+{
+ gint num, player_num, backwards;
+ gint they_supply[NO_RESOURCE];
+ gint they_receive[NO_RESOURCE];
+
+ sm_state_name(sm, "mode_idle");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_WAIT_TURN;
+ if (!player_is_viewer(my_player_num()))
+ callbacks.instructions(_("Waiting for your turn"));
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "setup %d", &backwards)) {
+ setup_begin(my_player_num());
+ if (backwards)
+ sm_push_noenter(sm, mode_wait_resources);
+ sm_push(sm, mode_setup);
+ return TRUE;
+ }
+ if (sm_recv(sm, "setup-double")) {
+ setup_begin_double(my_player_num());
+ sm_push_noenter(sm, mode_wait_resources);
+ sm_push(sm, mode_setup);
+ return TRUE;
+ }
+ if (sm_recv(sm, "turn %d", &num)) {
+ turn_begin(my_player_num(), num);
+ sm_push(sm, mode_turn);
+ return TRUE;
+ }
+ if (sm_recv
+ (sm,
+ "player %d domestic-trade call supply %R receive %R",
+ &player_num, they_supply, they_receive)) {
+ sm_push(sm, mode_domestic_quote);
+ callbacks.quote(player_num, they_supply,
+ they_receive);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Nested state machine for robber handling
+ */
+
+/* Get user to steal from a building
+ */
+static gboolean mode_robber_steal_building(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_robber_steal_building");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_ROB;
+ callbacks.
+ instructions(_("Select the building to steal from."));
+ callbacks.steal_building();
+ break;
+ case SM_RECV:
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/* Get user to steal from a ship
+ */
+static gboolean mode_robber_steal_ship(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_robber_steal_ship");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_ROB;
+ callbacks.
+ instructions(_("Select the ship to steal from."));
+ callbacks.steal_ship();
+ break;
+ case SM_RECV:
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/* Handle response to move robber
+ */
+gboolean mode_robber_move_response(StateMachine * sm, gint event)
+{
+ gint x, y;
+
+ sm_state_name(sm, "mode_robber_move_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "robber-done")) {
+ waiting_for_network(FALSE);
+ sm_multipop(sm, 2);
+ callbacks.robber_done();
+ return TRUE;
+ }
+ if (sm_recv(sm, "rob %d %d", &x, &y)) {
+ Hex *hex;
+ waiting_for_network(FALSE);
+ hex = map_hex(map, x, y);
+ if (hex->terrain == SEA_TERRAIN)
+ sm_push(sm, mode_robber_steal_ship);
+ else
+ sm_push(sm, mode_robber_steal_building);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Wait for server to say robber-done */
+gboolean mode_robber_response(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_robber_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "robber-done")) {
+ waiting_for_network(FALSE);
+ sm_stack_dump(sm);
+ /* current state is response
+ * parent is steal
+ * parent is move_response
+ * parent is mode_robber
+ * all four must be popped.
+ */
+ sm_multipop(sm, 4);
+ callbacks.robber_done();
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Get user to place robber
+ */
+static gboolean mode_robber(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_robber");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_ROBBER;
+ callbacks.instructions(_("Place the robber"));
+ robber_begin_move(my_player_num());
+ callbacks.robber();
+ break;
+ case SM_RECV:
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/* We rolled a 7, or played a soldier card - any time now the server
+ * is going to tell us to place the robber. Going into this state as
+ * soon as we roll a 7 stops a race condition where the user presses a
+ * GUI control in the window between receiving the die roll result and
+ * the command to enter robber mode.
+ */
+static gboolean mode_wait_for_robber(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_wait_for_robber");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "you-are-robber")) {
+ waiting_for_network(FALSE);
+ sm_goto(sm, mode_robber);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Road building
+ */
+
+const gchar *road_building_message(gint build_amount)
+{
+ switch (build_amount) {
+ case 0:
+ return _("Finish the road building action.");
+ case 1:
+ return _("Build one road segment.");
+ case 2:
+ return _("Build two road segments.");
+ default:
+ g_error("Unknown road building amount");
+ return "";
+ };
+}
+
+static gboolean mode_road_building(StateMachine * sm, gint event)
+{
+ gint build_amount; /* The amount of available 'roads' */
+ sm_state_name(sm, "mode_road_building");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_ROAD_BUILD;
+ /* Determine the possible amount of road segments */
+ build_amount = 0;
+ if (road_building_can_build_road())
+ build_amount += stock_num_roads();
+ if (road_building_can_build_ship())
+ build_amount += stock_num_ships();
+ if (road_building_can_build_bridge())
+ build_amount += stock_num_bridges();
+ /* Now determine the amount of segments left to play */
+ build_amount = MIN(build_amount, 2 - build_count_edges());
+ callbacks.roadbuilding(build_amount);
+ callbacks.
+ instructions(road_building_message(build_amount));
+ break;
+ case SM_RECV:
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Monopoly development card
+ */
+
+/* Response to "monopoly"
+ */
+gboolean mode_monopoly_response(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_monopoly_response");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_MONOPOLY_RESPONSE;
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "OK")) {
+ waiting_for_network(FALSE);
+ /* pop to parent's parent if it worked */
+ sm_multipop(sm, 2);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean mode_monopoly(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_monopoly");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_MONOPOLY;
+ callbacks.monopoly();
+ break;
+ case SM_RECV:
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Year of Plenty development card
+ */
+
+/* Response to "plenty"
+ */
+gboolean mode_year_of_plenty_response(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_year_of_plenty_response");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_PLENTY_RESPONSE;
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "OK")) {
+ waiting_for_network(FALSE);
+ /* action is done, go to parent's parent */
+ sm_multipop(sm, 2);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean mode_year_of_plenty(StateMachine * sm, gint event)
+{
+ gint plenty[NO_RESOURCE];
+
+ sm_state_name(sm, "mode_year_of_plenty");
+ switch (event) {
+ case SM_RECV:
+ if (sm_recv(sm, "plenty %R", plenty)) {
+ callback_mode = MODE_PLENTY;
+ callbacks.plenty(plenty);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Nested state machine for handling development card play response
+ */
+
+/* Handle response to play develop card
+ */
+gboolean mode_play_develop_response(StateMachine * sm, gint event)
+{
+ gint card_idx;
+ DevelType card_type;
+
+ sm_state_name(sm, "mode_play_develop_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv
+ (sm, "play-develop %d %D", &card_idx, &card_type)) {
+ build_clear();
+ waiting_for_network(FALSE);
+ develop_played(my_player_num(), card_idx,
+ card_type);
+ /* This mode should be popped off after the response
+ * has been handled. However, for the development
+ * card, a new mode must be pushed immediately. Due
+ * to the lack of sm_pop_noenter this is combined as
+ * sm_goto */
+ switch (card_type) {
+ case DEVEL_ROAD_BUILDING:
+ sm_goto(sm, mode_road_building);
+ break;
+ case DEVEL_MONOPOLY:
+ sm_goto(sm, mode_monopoly);
+ break;
+ case DEVEL_YEAR_OF_PLENTY:
+ sm_goto(sm, mode_year_of_plenty);
+ break;
+ case DEVEL_SOLDIER:
+ sm_goto(sm, mode_wait_for_robber);
+ break;
+ default:
+ sm_pop(sm);
+ break;
+ }
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Nested state machine for handling resource card discards. We enter
+ * discard mode whenever any player has to discard resources.
+ *
+ * When in discard mode, a section of the GUI changes to list all
+ * players who must discard resources. This is important because if
+ * during our turn we roll 7, but have less than 7 resources, we do
+ * not have to discard. The list tells us which players have still
+ * not discarded resources.
+ */
+static gboolean mode_discard(StateMachine * sm, gint event)
+{
+ gint player_num, discard_num;
+
+ sm_state_name(sm, "mode_discard");
+ switch (event) {
+ case SM_ENTER:
+ if (callback_mode != MODE_DISCARD
+ && callback_mode != MODE_DISCARD_WAIT) {
+ previous_mode = callback_mode;
+ callback_mode = MODE_DISCARD_WAIT;
+ }
+ callbacks.discard();
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "player %d must-discard %d",
+ &player_num, &discard_num)) {
+ if (player_num == my_player_num())
+ callback_mode = MODE_DISCARD;
+ callbacks.discard_add(player_num, discard_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "discard-done")) {
+ callback_mode = previous_mode;
+ callbacks.discard_done();
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Turn mode processing - before dice have been rolled
+ */
+
+/* Handle response to "roll dice"
+ */
+gboolean mode_roll_response(StateMachine * sm, gint event)
+{
+ gint die1, die2;
+
+ sm_state_name(sm, "mode_roll_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "rolled %d %d", &die1, &die2)) {
+ turn_rolled_dice(my_player_num(), die1, die2);
+ waiting_for_network(FALSE);
+ sm_goto_noenter(sm, mode_turn_rolled);
+ if (die1 + die2 == 7) {
+ sm_push(sm, mode_wait_for_robber);
+ } else
+ sm_push(sm, mode_wait_resources);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean mode_turn(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_turn");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_TURN;
+ callbacks.instructions(_("It is your turn."));
+ callbacks.turn();
+ break;
+ case SM_RECV:
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Turn mode processing - after dice have been rolled
+ */
+
+/* Handle response to buy development card
+ */
+gboolean mode_buy_develop_response(StateMachine * sm, gint event)
+{
+ DevelType card_type;
+
+ sm_state_name(sm, "mode_buy_develop_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "bought-develop %D", &card_type)) {
+ develop_bought_card(card_type);
+ sm_pop(sm);
+ waiting_for_network(FALSE);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Response to "undo"
+ */
+gboolean mode_undo_response(StateMachine * sm, gint event)
+{
+ BuildType build_type;
+ gint x, y, pos;
+ gint sx, sy, spos, dx, dy, dpos;
+
+ sm_state_name(sm, "mode_undo_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "remove %B %d %d %d",
+ &build_type, &x, &y, &pos)) {
+ build_remove(build_type, x, y, pos);
+ waiting_for_network(FALSE);
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (sm_recv(sm, "move-back %d %d %d %d %d %d",
+ &sx, &sy, &spos, &dx, &dy, &dpos)) {
+ build_move(sx, sy, spos, dx, dy, dpos, TRUE);
+ waiting_for_network(FALSE);
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (sm_recv(sm, "undo-robber")) {
+ waiting_for_network(FALSE);
+ /* current state is undo-response
+ * parent is steal
+ * parent is move_response
+ * parent is mode_robber
+ * the first three must be popped.
+ */
+ sm_multipop(sm, 3);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean mode_turn_rolled(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_turn_rolled");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_TURN;
+ callbacks.instructions(_("It is your turn."));
+ callbacks.turn();
+ break;
+ case SM_RECV:
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Trade processing - all trading done inside a nested state machine
+ * to allow trading to be invoked from multiple states.
+ */
+
+static gboolean check_trading(StateMachine * sm)
+{
+ gint player_num, quote_num;
+ gint they_supply[NO_RESOURCE];
+ gint they_receive[NO_RESOURCE];
+
+ if (!sm_recv_prefix(sm, "player %d ", &player_num))
+ return FALSE;
+
+ if (sm_recv(sm, "domestic-quote finish")) {
+ callbacks.trade_player_end(player_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "domestic-quote quote %d supply %R receive %R",
+ "e_num, they_supply, they_receive)) {
+ callbacks.trade_add_quote(player_num, quote_num,
+ they_supply, they_receive);
+ return TRUE;
+ }
+ if (sm_recv(sm, "domestic-quote delete %d", "e_num)) {
+ callbacks.trade_remove_quote(player_num, quote_num);
+ return TRUE;
+ }
+
+ sm_cancel_prefix(sm);
+ return FALSE;
+}
+
+/* Handle response to call for domestic trade quotes
+ */
+gboolean mode_trade_call_response(StateMachine * sm, gint event)
+{
+ gint we_supply[NO_RESOURCE];
+ gint we_receive[NO_RESOURCE];
+
+ sm_state_name(sm, "mode_trade_call_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "domestic-trade call supply %R receive %R",
+ we_supply, we_receive)) {
+ waiting_for_network(FALSE);
+ /* pop response state + push trade state == goto */
+ sm_goto(sm, mode_domestic_trade);
+ return TRUE;
+ }
+ if (check_trading(sm) || check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Handle response to maritime trade
+ */
+gboolean mode_trade_maritime_response(StateMachine * sm, gint event)
+{
+ gint ratio;
+ Resource we_supply;
+ Resource we_receive;
+
+ Resource no_receive;
+
+ sm_state_name(sm, "mode_trade_maritime_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ /* Handle out-of-resource-cards */
+ if (sm_recv(sm, "ERR no-cards %r", &no_receive)) {
+ gchar *buf_receive;
+
+ buf_receive = resource_cards(0, no_receive);
+ log_message(MSG_TRADE, _("Sorry, %s available.\n"),
+ buf_receive);
+ g_free(buf_receive);
+ waiting_for_network(FALSE);
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (sm_recv(sm, "maritime-trade %d supply %r receive %r",
+ &ratio, &we_supply, &we_receive)) {
+ player_maritime_trade(my_player_num(), ratio,
+ we_supply, we_receive);
+ waiting_for_network(FALSE);
+ sm_pop(sm);
+ callbacks.trade_maritime(ratio, we_supply,
+ we_receive);
+ return TRUE;
+ }
+ if (check_trading(sm) || check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Handle response to call for quotes during domestic trade
+ */
+gboolean mode_trade_call_again_response(StateMachine * sm, gint event)
+{
+ gint we_supply[NO_RESOURCE];
+ gint we_receive[NO_RESOURCE];
+
+ sm_state_name(sm, "mode_trade_call_again_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "domestic-trade call supply %R receive %R",
+ we_supply, we_receive)) {
+ waiting_for_network(FALSE);
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (check_trading(sm) || check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Handle response to domestic trade
+ */
+gboolean mode_trade_domestic_response(StateMachine * sm, gint event)
+{
+ gint partner_num;
+ gint quote_num;
+ gint they_supply[NO_RESOURCE];
+ gint they_receive[NO_RESOURCE];
+
+ sm_state_name(sm, "mode_trade_domestic_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv
+ (sm,
+ "domestic-trade accept player %d quote %d supply %R receive %R",
+ &partner_num, "e_num, &they_supply,
+ &they_receive)) {
+ player_domestic_trade(my_player_num(), partner_num,
+ they_supply, they_receive);
+ waiting_for_network(FALSE);
+ callbacks.trade_domestic(partner_num, quote_num,
+ they_receive,
+ they_supply);
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (check_trading(sm) || check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Handle response to domestic trade finish
+ */
+gboolean mode_domestic_finish_response(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_domestic_finish_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "domestic-trade finish")) {
+ callback_mode = MODE_TURN;
+ waiting_for_network(FALSE);
+ /* pop to parent's parent on finish */
+ sm_multipop(sm, 2);
+ return TRUE;
+ }
+ if (check_trading(sm) || check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean mode_domestic_trade(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_domestic_trade");
+ switch (event) {
+ case SM_ENTER:
+ if (callback_mode != MODE_DOMESTIC) {
+ callback_mode = MODE_DOMESTIC;
+ }
+ callbacks.trade();
+ break;
+ case SM_RECV:
+ if (check_trading(sm) || check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * Quote processing - all quoting done inside a nested state machine.
+ */
+
+static gboolean check_quoting(StateMachine * sm, gint exitdepth,
+ gboolean monitor)
+{
+ gint player_num, partner_num, quote_num;
+ gint they_supply[NO_RESOURCE];
+ gint they_receive[NO_RESOURCE];
+
+ if (!sm_recv_prefix(sm, "player %d ", &player_num))
+ return FALSE;
+
+ if (sm_recv(sm, "domestic-quote finish")) {
+ callbacks.quote_player_end(player_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "domestic-quote quote %d supply %R receive %R",
+ "e_num, they_supply, they_receive)) {
+ callbacks.quote_add(player_num, quote_num, they_supply,
+ they_receive);
+ return TRUE;
+ }
+ if (sm_recv(sm, "domestic-quote delete %d", "e_num)) {
+ callbacks.quote_remove(player_num, quote_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "domestic-trade call supply %R receive %R",
+ they_supply, they_receive)) {
+ if (monitor)
+ sm_pop(sm);
+ callbacks.quote(player_num, they_supply, they_receive);
+ return TRUE;
+ }
+ if (sm_recv
+ (sm,
+ "domestic-trade accept player %d quote %d supply %R receive %R",
+ &partner_num, "e_num, they_supply, they_receive)) {
+ player_domestic_trade(player_num, partner_num, they_supply,
+ they_receive);
+ callbacks.quote_trade(player_num, partner_num, quote_num,
+ they_supply, they_receive);
+ return TRUE;
+ }
+ if (sm_recv(sm, "domestic-trade finish")) {
+ callback_mode = previous_mode;
+ callbacks.quote_end();
+ sm_send(sm, "domestic-quote exit\n");
+ sm_multipop(sm, exitdepth);
+ return TRUE;
+ }
+
+ sm_cancel_prefix(sm);
+ return FALSE;
+}
+
+/* Handle response to domestic quote finish
+ */
+gboolean mode_quote_finish_response(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_quote_finish_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "domestic-quote finish")) {
+ waiting_for_network(FALSE);
+ /* pop response + push monitor == goto */
+ sm_goto(sm, mode_domestic_monitor);
+ callbacks.quote_monitor();
+ return TRUE;
+ }
+ if (check_quoting(sm, 2, FALSE) || check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Handle response to domestic quote submit
+ */
+gboolean mode_quote_submit_response(StateMachine * sm, gint event)
+{
+ gint quote_num;
+ gint we_supply[NO_RESOURCE];
+ gint we_receive[NO_RESOURCE];
+
+ sm_state_name(sm, "mode_quote_submit_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv
+ (sm, "domestic-quote quote %d supply %R receive %R",
+ "e_num, we_supply, we_receive)) {
+ callbacks.quote_add(my_player_num(), quote_num,
+ we_supply, we_receive);
+ waiting_for_network(FALSE);
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (check_quoting(sm, 2, FALSE) || check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Handle response to domestic quote delete
+ */
+gboolean mode_quote_delete_response(StateMachine * sm, gint event)
+{
+ gint quote_num;
+
+ sm_state_name(sm, "mode_quote_delete_response");
+ switch (event) {
+ case SM_ENTER:
+ waiting_for_network(TRUE);
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "domestic-quote delete %d", "e_num)) {
+ callbacks.quote_remove(my_player_num(), quote_num);
+ waiting_for_network(FALSE);
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (check_quoting(sm, 2, FALSE) || check_other_players(sm))
+ return TRUE;
+ break;
+ }
+ return FALSE;
+}
+
+/* Another player has called for quotes for domestic trade
+ */
+static gboolean mode_domestic_quote(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_domestic_quote");
+ switch (event) {
+ case SM_ENTER:
+ if (callback_mode != MODE_QUOTE) {
+ previous_mode = callback_mode;
+ callback_mode = MODE_QUOTE;
+ callbacks.quote_start();
+ }
+ break;
+ case SM_RECV:
+ if (check_quoting(sm, 1, FALSE) || check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/* We have rejected domestic trade, now just monitor
+ */
+static gboolean mode_domestic_monitor(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_domestic_monitor");
+ switch (event) {
+ case SM_RECV:
+ if (check_quoting(sm, 2, TRUE) || check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*----------------------------------------------------------------------
+ * The game is over
+ */
+
+static gboolean mode_game_over(StateMachine * sm, gint event)
+{
+ sm_state_name(sm, "mode_game_over");
+ switch (event) {
+ case SM_ENTER:
+ callback_mode = MODE_GAME_OVER;
+ callbacks.instructions(_("The game is over."));
+ break;
+ case SM_RECV:
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean mode_recovery_wait_start_response(StateMachine * sm,
+ gint event)
+{
+ sm_state_name(sm, "mode_recovery_wait_start_response");
+ switch (event) {
+ case SM_ENTER:
+ sm_send(sm, "start\n");
+ break;
+ case SM_RECV:
+ if (sm_recv(sm, "OK")) {
+ recover_from_disconnect(sm, &recovery_info);
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static void recover_from_disconnect(StateMachine * sm,
+ struct recovery_info_t *rinfo)
+{
+ StateFunc modeturn;
+ GList *next;
+
+ callbacks.start_game();
+ if (rinfo->turnnum > 0)
+ turn_begin(rinfo->playerturn, rinfo->turnnum);
+ if (rinfo->rolled_dice) {
+ turn_rolled_dice(rinfo->playerturn, rinfo->die1,
+ rinfo->die2);
+ } else if (rinfo->die1 + rinfo->die2 > 1) {
+ callbacks.rolled_dice(rinfo->die1, rinfo->die2,
+ rinfo->playerturn);
+ }
+
+ if (rinfo->rolled_dice)
+ modeturn = mode_turn_rolled;
+ else
+ modeturn = mode_turn;
+
+ if (rinfo->played_develop || rinfo->bought_develop) {
+ develop_reset_have_played_bought(rinfo->played_develop,
+ rinfo->bought_develop);
+ }
+
+ /* setup_begin must be called before the build list is created,
+ * because it contains a call to build_clear() */
+ if (strcmp(rinfo->prevstate, "SETUP") == 0 ||
+ strcmp(rinfo->prevstate, "RSETUP") == 0 ||
+ strcmp(rinfo->prevstate, "SETUPDOUBLE") == 0) {
+ if (strcmp(rinfo->prevstate, "SETUPDOUBLE") == 0) {
+ setup_begin_double(my_player_num());
+ } else {
+ setup_begin(my_player_num());
+ }
+ }
+
+ /* The build list must be created before the state is entered,
+ * because when the state is entered the frontend is called and
+ * it will want to have the build list present. */
+ if (rinfo->build_list) {
+ for (next = rinfo->build_list; next != NULL;
+ next = g_list_next(next)) {
+ BuildRec *build = (BuildRec *) next->data;
+ build_add(build->type, build->x, build->y,
+ build->pos, FALSE);
+ }
+ rinfo->build_list = buildrec_free(rinfo->build_list);
+ }
+
+ if (strcmp(rinfo->prevstate, "PREGAME") == 0) {
+ sm_goto(sm, mode_idle);
+ } else if (strcmp(rinfo->prevstate, "IDLE") == 0) {
+ sm_goto(sm, mode_idle);
+ } else if (strcmp(rinfo->prevstate, "SETUP") == 0 ||
+ strcmp(rinfo->prevstate, "RSETUP") == 0 ||
+ strcmp(rinfo->prevstate, "SETUPDOUBLE") == 0) {
+ sm_goto_noenter(sm, mode_idle);
+ if (strcmp(rinfo->prevstate, "SETUP") != 0) {
+ sm_push_noenter(sm, mode_wait_resources);
+ }
+ sm_push(sm, mode_setup);
+ } else if (strcmp(rinfo->prevstate, "TURN") == 0) {
+ sm_goto_noenter(sm, mode_idle);
+ sm_push(sm, modeturn);
+ } else if (strcmp(rinfo->prevstate, "YOUAREROBBER") == 0) {
+ sm_goto_noenter(sm, mode_idle);
+ sm_push_noenter(sm, modeturn);
+ sm_push(sm, mode_robber);
+ } else if (strcmp(rinfo->prevstate, "DISCARD") == 0) {
+ sm_goto_noenter(sm, mode_idle);
+ if (my_player_num() == rinfo->playerturn) {
+ sm_push_noenter(sm, mode_turn_rolled);
+ sm_push_noenter(sm, mode_wait_for_robber);
+ }
+ /* Allow gui to fill previous_state when entering
+ * mode_discard. */
+ callbacks.turn();
+ sm_push(sm, mode_discard);
+ } else if (strcmp(rinfo->prevstate, "MONOPOLY") == 0) {
+ sm_goto_noenter(sm, mode_idle);
+ sm_push_noenter(sm, modeturn);
+ callback_mode = MODE_TURN;
+ sm_push(sm, mode_monopoly);
+ } else if (strcmp(rinfo->prevstate, "PLENTY") == 0) {
+ sm_goto_noenter(sm, mode_idle);
+ sm_push_noenter(sm, modeturn);
+ callback_mode = MODE_TURN;
+ sm_push(sm, mode_year_of_plenty);
+ } else if (strcmp(rinfo->prevstate, "GOLD") == 0) {
+ sm_goto_noenter(sm, mode_idle);
+ sm_push_noenter(sm, modeturn);
+ callback_mode = MODE_TURN;
+ sm_push(sm, mode_wait_resources);
+ } else if (strcmp(rinfo->prevstate, "ROADBUILDING") == 0) {
+ sm_goto_noenter(sm, mode_idle);
+ sm_push_noenter(sm, modeturn);
+ callback_mode = MODE_TURN;
+ sm_push(sm, mode_road_building);
+ } else
+ g_warning("Not entering any state after reconnect, "
+ "please report this as a bug. "
+ "Should enter state \"%s\"", rinfo->prevstate);
+ g_free(rinfo->prevstate);
+}
+
+/*----------------------------------------------------------------------
+ * Nested state machine for handling resource card distribution. We enter
+ * here whenever resources might be distributed.
+ *
+ * This also includes choosing gold. Gold-choose mode is entered the first
+ * time prepare-gold is received.
+ *
+ * When in gold-choose mode, as in discard mode, a section of the GUI
+ * changes to list all players who must choose resources. This is
+ * important because if during our turn we do not receive gold, but others
+ * do, the list tells us which players have still not chosen resources.
+ * Only the top player in the list can actually choose, the rest is waiting
+ * for their turn.
+ */
+static gboolean mode_wait_resources(StateMachine * sm, gint event)
+{
+ gint resource_list[NO_RESOURCE], bank[NO_RESOURCE];
+ gint player_num, gold_num;
+
+ sm_state_name(sm, "mode_wait_resources");
+ switch (event) {
+ case SM_RECV:
+ if (sm_recv(sm, "player %d prepare-gold %d", &player_num,
+ &gold_num)) {
+ if (callback_mode != MODE_GOLD
+ && callback_mode != MODE_GOLD_WAIT) {
+ previous_mode = callback_mode;
+ callback_mode = MODE_GOLD_WAIT;
+ callbacks.gold();
+ }
+ callbacks.gold_add(player_num, gold_num);
+ return TRUE;
+ }
+ if (sm_recv(sm, "choose-gold %d %R", &gold_num, &bank)) {
+ callback_mode = MODE_GOLD;
+ callbacks.gold_choose(gold_num, bank);
+ return TRUE;
+ }
+ if (sm_recv(sm, "player %d receive-gold %R",
+ &player_num, resource_list)) {
+ player_resource_action(player_num,
+ _("%s takes %s.\n"),
+ resource_list, 1);
+ callbacks.gold_remove(player_num, resource_list);
+ return TRUE;
+ }
+ if (sm_recv(sm, "done-resources")) {
+ if (callback_mode == MODE_GOLD
+ || callback_mode == MODE_GOLD_WAIT) {
+ callback_mode = previous_mode;
+ callbacks.gold_done();
+ }
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (check_other_players(sm))
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+gboolean can_trade_domestic(void)
+{
+ return game_params->domestic_trade;
+}
+
+gboolean can_trade_maritime(void)
+{
+ MaritimeInfo info;
+ gint idx;
+ gboolean can_trade;
+ /* We are not allowed to trade before we have rolled the dice,
+ * or after we have done built a settlement / city, or after
+ * buying a development card. */
+ if (!have_rolled_dice()
+ || (game_params->strict_trade
+ && (have_built() || have_bought_develop())))
+ return FALSE;
+ can_trade = FALSE;
+ /* Check if we can do a maritime trade */
+ map_maritime_info(map, &info, my_player_num());
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ if (info.specific_resource[idx]
+ && resource_asset(idx) >= 2) {
+ can_trade = TRUE;
+ break;
+ } else if (info.any_resource && resource_asset(idx) >= 3) {
+ can_trade = TRUE;
+ break;
+ } else if (resource_asset(idx) >= 4) {
+ can_trade = TRUE;
+ break;
+ }
+ return can_trade;
+}
Added: trunk/client/common/client.h
===================================================================
--- trunk/client/common/client.h (rev 0)
+++ trunk/client/common/client.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,175 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2003,2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _client_h
+#define _client_h
+
+#include "state.h"
+#include "game.h"
+#include "map.h"
+#include "callback.h"
+
+/* variables */
+extern Map *map;
+extern GameParams *game_params;
+extern gchar *requested_name;
+extern gboolean requested_viewer;
+extern gchar *requested_style;
+
+/********* client.c ***********/
+/* client initialization */
+void client_init(void); /* before frontend initialization */
+void client_start(int argc, char **argv); /* after frontend initialization */
+
+/* access the state machine (a client has only one state machine) */
+StateMachine *SM(void);
+
+/* state machine modes */
+gboolean mode_connecting(StateMachine * sm, gint event);
+gboolean mode_start(StateMachine * sm, gint event);
+gboolean mode_build_response(StateMachine * sm, gint event);
+gboolean mode_move_response(StateMachine * sm, gint event);
+gboolean mode_done_response(StateMachine * sm, gint event);
+gboolean mode_robber_response(StateMachine * sm, gint event);
+gboolean mode_robber_move_response(StateMachine * sm, gint event);
+gboolean mode_monopoly_response(StateMachine * sm, gint event);
+gboolean mode_year_of_plenty_response(StateMachine * sm, gint event);
+gboolean mode_play_develop_response(StateMachine * sm, gint event);
+gboolean mode_roll_response(StateMachine * sm, gint event);
+gboolean mode_buy_develop_response(StateMachine * sm, gint event);
+gboolean mode_undo_response(StateMachine * sm, gint event);
+gboolean mode_trade_call_response(StateMachine * sm, gint event);
+gboolean mode_trade_maritime_response(StateMachine * sm, gint event);
+gboolean mode_trade_call_again_response(StateMachine * sm, gint event);
+gboolean mode_trade_domestic_response(StateMachine * sm, gint event);
+gboolean mode_domestic_finish_response(StateMachine * sm, gint event);
+gboolean mode_quote_finish_response(StateMachine * sm, gint event);
+gboolean mode_quote_submit_response(StateMachine * sm, gint event);
+gboolean mode_quote_delete_response(StateMachine * sm, gint event);
+
+/******* player.c **********/
+void player_reset(void);
+void player_set_my_num(gint player_num);
+void player_modify_statistic(gint player_num, StatisticType type,
+ gint num);
+void player_modify_points(gint player_num, Points * points,
+ gboolean added);
+void player_change_name(gint player_num, const gchar * name);
+void player_has_quit(gint player_num);
+void player_largest_army(gint player_num);
+void player_longest_road(gint player_num);
+void player_set_current(gint player_num);
+void player_set_total_num(gint num);
+void player_stole_from(gint player_num, gint victim_num,
+ Resource resource);
+void player_domestic_trade(gint player_num, gint partner_num,
+ gint * supply, gint * receive);
+void player_maritime_trade(gint player_num, gint ratio, Resource supply,
+ Resource receive);
+void player_build_add(gint player_num, BuildType type, gint x, gint y,
+ gint pos, gboolean log_changes);
+void player_build_remove(gint player_num, BuildType type, gint x, gint y,
+ gint pos);
+void player_build_move(gint player_num, gint sx, gint sy, gint spos,
+ gint dx, gint dy, gint dpos, gint isundo);
+void player_resource_action(gint player_num, const gchar * action,
+ const gint * resource_list, gint mult);
+void player_get_point(gint player_num, gint id, const gchar * str,
+ gint num);
+void player_lose_point(gint player_num, gint id);
+void player_take_point(gint player_num, gint id, gint old_owner);
+void player_change_style(gint player_num, const gchar * style);
+
+gint find_viewer_by_name(const gchar * name);
+
+/********* build.c **********/
+void build_clear(void);
+void build_new_turn(void);
+void build_remove(BuildType build_type, gint x, gint y, gint pos);
+void build_move(gint sx, gint sy, gint spos, gint dx, gint dy, gint dpos,
+ gint isundo);
+void build_add(BuildType type, gint x, gint y, gint pos,
+ gboolean newbuild);
+gboolean build_can_undo(void);
+gboolean build_is_valid(void);
+gboolean have_built(void);
+gboolean build_can_setup_road(const Edge * edge, gboolean double_setup);
+gboolean build_can_setup_ship(const Edge * edge, gboolean double_setup);
+gboolean build_can_setup_bridge(const Edge * edge, gboolean double_setup);
+gboolean build_can_setup_settlement(const Node * node,
+ gboolean double_setup);
+
+/********** develop.c **********/
+void develop_init(void);
+void develop_bought_card_turn(DevelType type, gint turnbought);
+void develop_bought_card(DevelType type);
+void develop_reset_have_played_bought(gboolean played_develop,
+ gboolean bought_develop);
+void develop_bought(gint player_num);
+void develop_played(gint player_num, gint card_idx, DevelType type);
+void monopoly_player(gint player_num, gint victim_num, gint num,
+ Resource type);
+void develop_begin_turn(void);
+gboolean have_bought_develop(void);
+
+/********** stock.c **********/
+void stock_init(void);
+void stock_use_road(void);
+void stock_replace_road(void);
+void stock_use_ship(void);
+void stock_replace_ship(void);
+void stock_use_bridge(void);
+void stock_replace_bridge(void);
+void stock_use_settlement(void);
+void stock_replace_settlement(void);
+void stock_use_city(void);
+void stock_replace_city(void);
+void stock_use_city_wall(void);
+void stock_replace_city_wall(void);
+void stock_use_develop(void);
+
+/********** resource.c **********/
+void resource_init(void);
+void resource_apply_list(gint player_num, const gint * resources,
+ gint multiplier);
+gchar *resource_cards(gint num, Resource which);
+gchar *resource_format_num(const gint * resources);
+void resource_log_list(gint player_num, const gchar * action,
+ const gint * resources);
+void resource_modify(Resource type, gint num);
+void set_bank(const gint * new_bank);
+void modify_bank(const gint * bank_change);
+
+/********** robber.c **********/
+void robber_move_on_map(gint x, gint y);
+void pirate_move_on_map(gint x, gint y);
+void robber_moved(gint player_num, gint x, gint y, gboolean is_undo);
+void pirate_moved(gint player_num, gint x, gint y, gboolean is_undo);
+void robber_begin_move(gint player_num);
+
+/********* setup.c *********/
+void setup_begin(gint player_num);
+void setup_begin_double(gint player_num);
+
+/********* turn.c *********/
+void turn_rolled_dice(gint player_num, gint die1, gint die2);
+void turn_begin(gint player_num, gint turn_num);
+
+#endif
Added: trunk/client/common/develop.c
===================================================================
--- trunk/client/common/develop.c (rev 0)
+++ trunk/client/common/develop.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,256 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <math.h>
+#include <ctype.h>
+
+#include "game.h"
+#include "cards.h"
+#include "map.h"
+#include "client.h"
+#include "cost.h"
+#include "log.h"
+#include "state.h"
+#include "callback.h"
+
+static gboolean played_develop; /* already played a non-victory card? */
+static gboolean bought_develop; /* have we bought a development card? */
+
+static struct {
+ const gchar *name;
+ gboolean is_unique;
+} devel_cards[] = {
+ {
+ N_("Road Building"), FALSE}, {
+ N_("Monopoly"), FALSE}, {
+ N_("Year of Plenty"), FALSE}, {
+ N_("Chapel"), TRUE}, {
+ N_("Pioneer University"), TRUE}, {
+ N_("Governor's House"), TRUE}, {
+ N_("Library"), TRUE}, {
+ N_("Market"), TRUE}, {
+ N_("Soldier"), FALSE}
+};
+
+static DevelDeck *develop_deck; /* our deck of development cards */
+
+void develop_init(void)
+{
+ int idx;
+ if (develop_deck != NULL)
+ deck_free(develop_deck);
+ develop_deck = deck_new(game_params);
+ for (idx = 0; idx < G_N_ELEMENTS(devel_cards); idx++)
+ devel_cards[idx].is_unique =
+ game_params->num_develop_type[idx] == 1;
+}
+
+void develop_bought_card_turn(DevelType type, gint turnbought)
+{
+ deck_card_add(develop_deck, type, turnbought);
+ if (turnbought == turn_num()) {
+ /* Cannot undo build after buying a development card
+ */
+ build_clear();
+ bought_develop = TRUE;
+ /* Only log if the cards is bought in the current turn.
+ * This function is also called during reconnect
+ */
+ if (devel_cards[type].is_unique)
+ log_message(MSG_DEVCARD,
+ /* This card is unique */
+ _
+ ("You bought the %s development card.\n"),
+ gettext(devel_cards[type].name));
+ else
+ log_message(MSG_DEVCARD,
+ /* This card is not unique */
+ _
+ ("You bought a %s development card.\n"),
+ gettext(devel_cards[type].name));
+ };
+ player_modify_statistic(my_player_num(), STAT_DEVELOPMENT, 1);
+ stock_use_develop();
+ callbacks.bought_develop(type);
+}
+
+void develop_bought_card(DevelType type)
+{
+ develop_bought_card_turn(type, turn_num());
+}
+
+void develop_reset_have_played_bought(gboolean have_played,
+ gboolean have_bought)
+{
+ played_develop = have_played;
+ bought_develop = have_bought;
+}
+
+void develop_bought(gint player_num)
+{
+ log_message(MSG_DEVCARD, _("%s bought a development card.\n"),
+ player_name(player_num, TRUE));
+
+ player_modify_statistic(player_num, STAT_DEVELOPMENT, 1);
+ stock_use_develop();
+}
+
+void develop_played(gint player_num, gint card_idx, DevelType type)
+{
+ if (player_num == my_player_num()) {
+ deck_card_play(develop_deck,
+ played_develop, card_idx, turn_num());
+ if (!is_victory_card(type))
+ played_develop = TRUE;
+ }
+ callbacks.played_develop(player_num, card_idx, type);
+
+ if (devel_cards[type].is_unique)
+ log_message(MSG_DEVCARD,
+ _("%s played the %s development card.\n"),
+ player_name(player_num, TRUE),
+ gettext(devel_cards[type].name));
+ else
+ log_message(MSG_DEVCARD,
+ _("%s played a %s development card.\n"),
+ player_name(player_num, TRUE),
+ gettext(devel_cards[type].name));
+
+ player_modify_statistic(player_num, STAT_DEVELOPMENT, -1);
+ switch (type) {
+ case DEVEL_ROAD_BUILDING:
+ if (player_num == my_player_num()) {
+ if (stock_num_roads() == 0
+ && stock_num_ships() == 0
+ && stock_num_bridges() == 0)
+ log_message(MSG_INFO,
+ _
+ ("You have run out of road segments.\n"));
+ }
+ break;
+ case DEVEL_CHAPEL:
+ player_modify_statistic(player_num, STAT_CHAPEL, 1);
+ break;
+ case DEVEL_UNIVERSITY:
+ player_modify_statistic(player_num, STAT_UNIVERSITY, 1);
+ break;
+ case DEVEL_GOVERNORS_HOUSE:
+ player_modify_statistic(player_num, STAT_GOVERNORS_HOUSE,
+ 1);
+ break;
+ case DEVEL_LIBRARY:
+ player_modify_statistic(player_num, STAT_LIBRARY, 1);
+ break;
+ case DEVEL_MARKET:
+ player_modify_statistic(player_num, STAT_MARKET, 1);
+ break;
+ case DEVEL_SOLDIER:
+ player_modify_statistic(player_num, STAT_SOLDIERS, 1);
+ break;
+ default:
+ break;
+ }
+}
+
+void monopoly_player(gint player_num, gint victim_num, gint num,
+ Resource type)
+{
+ gchar *buf;
+ gchar *tmp;
+
+ player_modify_statistic(player_num, STAT_RESOURCES, num);
+ player_modify_statistic(victim_num, STAT_RESOURCES, -num);
+
+ buf = resource_cards(num, type);
+ if (player_num == my_player_num()) {
+ /* I get the cards!
+ */
+ log_message(MSG_STEAL, _("You get %s from %s.\n"),
+ buf, player_name(victim_num, FALSE));
+ resource_modify(type, num);
+ } else if (victim_num == my_player_num()) {
+ /* I lose the cards!
+ */
+ log_message(MSG_STEAL, _("%s took %s from you.\n"),
+ player_name(player_num, TRUE), buf);
+ resource_modify(type, -num);
+ } else {
+ /* I am a bystander
+ */
+ tmp = g_strdup(player_name(player_num, TRUE));
+ log_message(MSG_STEAL, _("%s took %s from %s.\n"),
+ tmp, buf, player_name(victim_num, FALSE));
+ g_free(tmp);
+ }
+ g_free(buf);
+}
+
+void develop_begin_turn(void)
+{
+ played_develop = FALSE;
+ bought_develop = FALSE;
+}
+
+gboolean can_play_develop(gint card)
+{
+ if (card < 0
+ || !deck_card_playable(develop_deck, played_develop, card,
+ turn_num()))
+ return FALSE;
+ if (deck_card_type(develop_deck, card) == DEVEL_ROAD_BUILDING
+ && !road_building_can_build_road()
+ && !road_building_can_build_ship()
+ && !road_building_can_build_bridge())
+ return FALSE;
+
+ return TRUE;
+}
+
+gboolean can_play_any_develop(void)
+{
+ int i;
+ for (i = 0; i < develop_deck->num_cards; ++i)
+ if (can_play_develop(i))
+ return TRUE;
+ return FALSE;
+}
+
+gboolean can_buy_develop(void)
+{
+ return have_rolled_dice()
+ && stock_num_develop() > 0 && can_afford(cost_development());
+}
+
+gboolean have_bought_develop(void)
+{
+ return bought_develop;
+}
+
+const DevelDeck *get_devel_deck(void)
+{
+ return develop_deck;
+}
+
+const gchar *get_devel_name(DevelType type)
+{
+ return gettext(devel_cards[type].name);
+}
Added: trunk/client/common/i18n.c
===================================================================
--- trunk/client/common/i18n.c (rev 0)
+++ trunk/client/common/i18n.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,130 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <locale.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#if ENABLE_NLS
+
+#include "callback.h"
+
+/* Needed below for a dirty trick */
+#ifndef G_OS_WIN32
+extern int _nl_msg_cat_cntr;
+#endif
+
+static lang_desc languages[] = {
+ /* language names not translated intentionally! */
+ /* FIXME: locale must match exactly, e.g.
+ * it_IT.UTF-8 at euro != it_IT
+ */
+ {"en", "English", "en_US", TRUE, NULL},
+ {"de", "Deutsch", "de_DE", FALSE, NULL},
+ {"fr", "Français", "fr_FR", FALSE, NULL},
+ {"it", "Italiano", "it_IT", FALSE, NULL},
+ {"es", "Español", "es_ES", FALSE, NULL},
+ {"nl", "Nederlands", "nl_NL", FALSE, NULL},
+ {"hu", "Hungarian", "hu_HU", FALSE, NULL},
+ {NULL, NULL, NULL, FALSE, NULL}
+};
+
+static gchar *current_language = NULL;
+
+lang_desc *find_lang_desc(const gchar * code)
+{
+ lang_desc *ld;
+
+ for (ld = languages; ld->code; ++ld) {
+ if (strcmp(ld->code, code) == 0)
+ return ld;
+ }
+ return NULL;
+}
+
+void init_nls(void)
+{
+ gchar *linguas;
+ gchar *p;
+ lang_desc *ld;
+ const gchar *set_locale;
+
+ /* mark languages supported from ALL_LINGUAS (+English) */
+ linguas = g_strdup(ALL_LINGUAS);
+ for (p = strtok(linguas, " "); p; p = strtok(NULL, " ")) {
+ if ((ld = find_lang_desc(p)))
+ ld->supported =
+ setlocale(LC_ALL, ld->localedef) != NULL;
+ }
+ g_free(linguas);
+
+ set_locale = setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /* have gettext return strings in UTF-8 */
+ bind_textdomain_codeset(PACKAGE, "UTF-8");
+
+ /* determine language setting after setlocale()
+ * empty setting, "C", or "POSIX" are treated as English
+ * for others the country part after '_' is cut away
+ * if the found language isn't supported, fall back to English
+ */
+ if (!set_locale || strcmp(set_locale, "C") == 0 ||
+ strcmp(set_locale, "POSIX") == 0) {
+ current_language = g_strdup("en");
+ } else {
+ int len = strcspn(set_locale, "_ at +,");
+ current_language = g_strndup(set_locale, len);
+ if (!(ld = find_lang_desc(current_language)) ||
+ !ld->supported) {
+ g_free(current_language);
+ current_language = g_strdup("en");
+ }
+ }
+}
+
+gboolean change_nls(lang_desc * ld)
+{
+ if (!setlocale(LC_ALL, ld->localedef)) {
+ /* args */
+ fprintf(stderr, "Locale %s not supported by C library!\n",
+ ld->localedef);
+ return FALSE;
+ }
+
+ /* Change language, method found at
+ * http://www.gnu.org/software/gettext/manual/html_chapter/gettext_10.html#SEC154
+ */
+ g_setenv("LANGUAGE", ld->code, TRUE);
+ g_setenv("LC_ALL", ld->localedef, TRUE); /* Do this too, so setlocale works too */
+ /* Make change known */
+#ifndef G_OS_WIN32
+ ++_nl_msg_cat_cntr;
+#endif
+
+ g_free(current_language);
+ current_language = g_strdup(ld->code);
+ return TRUE;
+}
+#endif
Added: trunk/client/common/main.c
===================================================================
--- trunk/client/common/main.c (rev 0)
+++ trunk/client/common/main.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,65 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <locale.h>
+
+#include "client.h"
+#include "callback.h"
+#include <glib.h>
+
+static GMainLoop *loop;
+
+static void run_main(void)
+{
+ loop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(loop);
+ g_main_loop_unref(loop);
+}
+
+static void quit(void)
+{
+ g_main_loop_quit(loop);
+}
+
+int main(int argc, char *argv[])
+{
+ net_init();
+
+ client_init();
+ callbacks.mainloop = &run_main;
+ callbacks.quit = &quit;
+
+#if ENABLE_NLS
+ init_nls();
+#endif
+
+ frontend_set_callbacks();
+
+ /* this must come after the frontend_set_callbacks, because it sets the
+ * mode to offline, which means a callback is called. */
+ client_start(argc, argv);
+
+ callbacks.mainloop();
+
+ net_finish();
+ return 0;
+}
Added: trunk/client/common/player.c
===================================================================
--- trunk/client/common/player.c (rev 0)
+++ trunk/client/common/player.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,819 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003,2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+
+#include "game.h"
+#include "map.h"
+#include "client.h"
+#include "cost.h"
+#include "log.h"
+#include "callback.h"
+
+static Player players[MAX_PLAYERS];
+static GList *viewers;
+
+static gint turn_player = -1; /* whose turn is it */
+static gint my_player_id = -1; /* what is my player number */
+static gint num_total_players = 4; /* total number of players in the game */
+
+/* this function is called when the game starts, to clean up from the
+ * previous game. */
+void player_reset(void)
+{
+ gint i, idx;
+
+ /* remove all viewers */
+ while (viewers != NULL) {
+ Viewer *viewer = viewers->data;
+ g_free(viewer->name);
+ g_free(viewer->style);
+ viewers = g_list_remove(viewers, viewer);
+ }
+ /* free player's memory */
+ for (i = 0; i < MAX_PLAYERS; ++i) {
+ if (players[i].name != NULL) {
+ g_free(players[i].name);
+ players[i].name = NULL;
+ }
+ if (players[i].style != NULL) {
+ g_free(players[i].style);
+ players[i].style = NULL;
+ }
+ while (players[i].points != NULL) {
+ Points *points = players[i].points->data;
+ players[i].points =
+ g_list_remove(players[i].points, points);
+ points_free(points);
+ g_free(points);
+ }
+ for (idx = 0; idx < G_N_ELEMENTS(players[i].statistics);
+ ++idx)
+ players[i].statistics[idx] = 0;
+ }
+}
+
+Player *player_get(gint num)
+{
+ return &players[num];
+}
+
+gboolean player_is_viewer(gint num)
+{
+ return num < 0 || num >= num_total_players;
+}
+
+Viewer *viewer_get(gint num)
+{
+ GList *list;
+ for (list = viewers; list != NULL; list = g_list_next(list)) {
+ Viewer *viewer = list->data;
+ if (viewer->num == num)
+ break;
+ }
+ if (list)
+ return list->data;
+ return NULL;
+}
+
+/** Find a viewer with the given name.
+ * @param name The name to find
+ * @return -1 if the name is not found
+ */
+gint find_viewer_by_name(const gchar * name)
+{
+ GList *list;
+ for (list = viewers; list != NULL; list = g_list_next(list)) {
+ Viewer *viewer = list->data;
+ if (!strcmp(viewer->name, name))
+ return viewer->num;
+ }
+ return -1;
+}
+
+const gchar *player_name(gint player_num, gboolean word_caps)
+{
+ static gchar buff[256];
+ if (player_num >= num_total_players) {
+ /* this is about a viewer */
+ Viewer *viewer = viewer_get(player_num);
+ if (viewer != NULL)
+ return viewer->name;
+ else {
+ if (word_caps)
+ sprintf(buff, _("Viewer %d"), player_num);
+ else
+ sprintf(buff, _("viewer %d"), player_num);
+ return buff;
+ }
+ } else if (player_num >= 0) {
+ Player *player = player_get(player_num);
+ return player->name;
+ }
+ if (word_caps)
+ sprintf(buff, _("Player %d"), player_num);
+ else
+ sprintf(buff, _("player %d"), player_num);
+ return buff;
+}
+
+gint player_get_score(gint player_num)
+{
+ Player *player = player_get(player_num);
+ GList *list;
+ gint i, score;
+
+ for (i = 0, score = 0; i < G_N_ELEMENTS(player->statistics); i++) {
+ score += stat_get_vp_value(i) * player->statistics[i];
+ }
+
+ list = player->points;
+ while (list) {
+ Points *points = list->data;
+ score += points->points;
+ list = g_list_next(list);
+ }
+ return score;
+}
+
+gint my_player_num(void)
+{
+ return my_player_id;
+}
+
+gint num_players(void)
+{
+ return num_total_players;
+}
+
+void player_set_my_num(gint player_num)
+{
+ my_player_id = player_num;
+}
+
+void player_modify_statistic(gint player_num, StatisticType type, gint num)
+{
+ Player *player = player_get(player_num);
+ player->statistics[type] += num;
+ callbacks.new_statistics(player_num, type, num);
+}
+
+void player_modify_points(gint player_num, Points * points, gboolean added)
+{
+ Player *player = player_get(player_num);
+ /* if !added -> is already removed */
+ if (added)
+ player->points = g_list_append(player->points, points);
+ callbacks.new_points(player_num, points, added);
+}
+
+void player_change_name(gint player_num, const gchar * name)
+{
+ Player *player;
+ gchar *old_name;
+
+ if (player_num < 0)
+ return;
+ if (player_num >= num_total_players) {
+ /* this is about a viewer */
+ Viewer *viewer = viewer_get(player_num);
+ if (viewer == NULL) {
+ /* there is a new viewer */
+ viewer = g_malloc0(sizeof(*viewer));
+ viewers = g_list_prepend(viewers, viewer);
+ viewer->num = player_num;
+ viewer->name = NULL;
+ viewer->style = g_strdup("square");
+ old_name = NULL;
+ } else {
+ old_name = viewer->name;
+ }
+ if (old_name == NULL)
+ log_message(MSG_INFO, _("New viewer: %s.\n"),
+ name);
+ else
+ log_message(MSG_INFO, _("%s is now %s.\n"),
+ old_name, name);
+ viewer->name = g_strdup(name);
+ if (old_name != NULL)
+ g_free(old_name);
+ callbacks.viewer_name(player_num, name);
+ return;
+ }
+
+ player = player_get(player_num);
+ old_name = player->name;
+ player->name = g_strdup(name);
+ if (old_name == NULL)
+ log_message(MSG_INFO, _("Player %d is now %s.\n"),
+ player_num, name);
+ else if (strcmp(old_name, name))
+ log_message(MSG_INFO, _("%s is now %s.\n"), old_name,
+ name);
+ if (old_name != NULL)
+ g_free(old_name);
+ callbacks.player_name(player_num, name);
+}
+
+void player_change_style(gint player_num, const gchar * style)
+{
+ player_set_style(player_num, style);
+ callbacks.player_style(player_num, style);
+}
+
+void player_has_quit(gint player_num)
+{
+ Player *player;
+ Viewer *viewer;
+
+ if (player_num < 0)
+ return;
+
+ /* usually callbacks are called after the event has been handled.
+ * Here it is called before, so the frontend can access the
+ * information about the quitting player/viewer */
+
+ if (player_num >= num_total_players) {
+ /* a viewer has quit */
+ callbacks.viewer_quit(player_num);
+ viewer = viewer_get(player_num);
+ g_free(viewer->name);
+ g_free(viewer->style);
+ viewers = g_list_remove(viewers, viewer);
+ return;
+ }
+ callbacks.player_quit(player_num);
+ player = player_get(player_num);
+ log_message(MSG_INFO, _("%s has quit\n"), player_name(player_num,
+ TRUE));
+}
+
+void player_largest_army(gint player_num)
+{
+ gint idx;
+ if (player_num < 0)
+ log_message(MSG_LARGESTARMY,
+ _("There is no largest army.\n"));
+ else
+ log_message(MSG_LARGESTARMY,
+ _("%s has the largest army.\n"),
+ player_name(player_num, TRUE));
+ for (idx = 0; idx < num_total_players; idx++) {
+ Player *player = player_get(idx);
+ if (player->statistics[STAT_LARGEST_ARMY] != 0
+ && idx != player_num)
+ player_modify_statistic(idx, STAT_LARGEST_ARMY,
+ -1);
+ if (player->statistics[STAT_LARGEST_ARMY] == 0
+ && idx == player_num)
+ player_modify_statistic(idx, STAT_LARGEST_ARMY, 1);
+ }
+}
+
+
+void player_longest_road(gint player_num)
+{
+ gint idx;
+
+ if (player_num < 0)
+ log_message(MSG_LONGESTROAD,
+ _("There is no longest road.\n"));
+ else
+ log_message(MSG_LONGESTROAD,
+ _("%s has the longest road.\n"),
+ player_name(player_num, TRUE));
+
+ for (idx = 0; idx < num_total_players; idx++) {
+ Player *player = player_get(idx);
+
+ if (player->statistics[STAT_LONGEST_ROAD] != 0
+ && idx != player_num)
+ player_modify_statistic(idx, STAT_LONGEST_ROAD,
+ -1);
+ if (player->statistics[STAT_LONGEST_ROAD] == 0
+ && idx == player_num)
+ player_modify_statistic(idx, STAT_LONGEST_ROAD, 1);
+ }
+}
+
+void player_set_current(gint player_num)
+{
+ turn_player = player_num;
+ if (player_num != my_player_num()) {
+ gchar *buffer;
+ buffer = g_strdup_printf(_("Waiting for %s."),
+ player_name(player_num, FALSE));
+ callbacks.instructions(buffer);
+ g_free(buffer);
+ return;
+ }
+ build_new_turn();
+}
+
+void player_set_total_num(gint num)
+{
+ num_total_players = num;
+}
+
+void player_stole_from(gint player_num, gint victim_num, Resource resource)
+{
+ player_modify_statistic(player_num, STAT_RESOURCES, 1);
+ player_modify_statistic(victim_num, STAT_RESOURCES, -1);
+
+ if (resource == NO_RESOURCE) {
+ /* CHECK THIS: Since anonymous players (NULL) no longer exist,
+ * player_name doesn't use its static buffer anymore, and
+ * two calls can be safely combined. If not: ai/player.c should also be fixed */
+ /* FIXME: in the client, anonymous players can exist.
+ * I prefer changing that instead of this function */
+ log_message(MSG_STEAL,
+ /* We are not in on the action
+ someone stole a resource from someone else */
+ _("%s stole a resource from %s.\n"),
+ player_name(player_num, TRUE),
+ player_name(victim_num, FALSE));
+ } else {
+ gchar *buf;
+
+ buf = resource_cards(1, resource);
+ if (player_num == my_player_num()) {
+ /* We stole a card :-) */
+ log_message(MSG_STEAL,
+ _("You stole %s from %s.\n"), buf,
+ player_name(victim_num, FALSE));
+ resource_modify(resource, 1);
+ } else {
+ /* Someone stole our card :-( */
+ log_message(MSG_STEAL,
+ _("%s stole %s from you.\n"),
+ player_name(player_num, TRUE), buf);
+ resource_modify(resource, -1);
+ }
+ g_free(buf);
+ }
+ callbacks.player_robbed(player_num, victim_num, resource);
+}
+
+void player_domestic_trade(gint player_num, gint partner_num,
+ gint * supply, gint * receive)
+{
+ gchar *supply_desc;
+ gchar *receive_desc;
+ gint diff;
+ gint idx;
+
+ diff = resource_count(receive) - resource_count(supply);
+ player_modify_statistic(player_num, STAT_RESOURCES, -diff);
+ player_modify_statistic(partner_num, STAT_RESOURCES, diff);
+ if (player_num == my_player_num()) {
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ resource_modify(idx, supply[idx]);
+ resource_modify(idx, -receive[idx]);
+ }
+ } else if (partner_num == my_player_num()) {
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ resource_modify(idx, -supply[idx]);
+ resource_modify(idx, receive[idx]);
+ }
+ }
+
+ if (!resource_count(supply)) {
+ if (!resource_count(receive)) {
+ log_message(MSG_TRADE, _("%s gave %s nothing!?\n"),
+ player_name(player_num, TRUE),
+ player_name(partner_num, FALSE));
+ } else {
+ receive_desc = resource_format_num(receive);
+ log_message(MSG_TRADE,
+ _("%s gave %s %s for free.\n"),
+ player_name(player_num, TRUE),
+ player_name(partner_num, FALSE),
+ receive_desc);
+ g_free(receive_desc);
+ }
+ } else if (!resource_count(receive)) {
+ supply_desc = resource_format_num(supply);
+ log_message(MSG_TRADE, _("%s gave %s %s for free.\n"),
+ player_name(partner_num, TRUE),
+ player_name(player_num, FALSE), supply_desc);
+ g_free(supply_desc);
+ } else {
+ supply_desc = resource_format_num(supply);
+ receive_desc = resource_format_num(receive);
+ log_message(MSG_TRADE,
+ _("%s gave %s %s in exchange for %s.\n"),
+ player_name(player_num, TRUE),
+ player_name(partner_num, FALSE), receive_desc,
+ supply_desc);
+ g_free(supply_desc);
+ g_free(receive_desc);
+ }
+}
+
+void player_maritime_trade(gint player_num,
+ gint ratio, Resource supply, Resource receive)
+{
+ gchar *buf_give;
+ gchar *buf_receive;
+ gint resources[NO_RESOURCE];
+ gint idx;
+
+ for (idx = 0; idx < NO_RESOURCE; ++idx)
+ resources[idx] = 0;
+ resources[supply] = ratio;
+ resources[receive] = -1;
+ modify_bank(resources);
+
+ player_modify_statistic(player_num, STAT_RESOURCES, 1 - ratio);
+ if (player_num == my_player_num()) {
+ resource_modify(supply, -ratio);
+ resource_modify(receive, 1);
+ }
+
+ buf_give = resource_cards(ratio, supply);
+ buf_receive = resource_cards(1, receive);
+ log_message(MSG_TRADE, _("%s exchanged %s for %s.\n"),
+ player_name(player_num, TRUE), buf_give, buf_receive);
+ g_free(buf_give);
+ g_free(buf_receive);
+}
+
+void player_build_add(gint player_num,
+ BuildType type, gint x, gint y, gint pos,
+ gboolean log_changes)
+{
+ Edge *edge;
+ Node *node;
+
+ switch (type) {
+ case BUILD_ROAD:
+ edge = map_edge(map, x, y, pos);
+ edge->owner = player_num;
+ edge->type = BUILD_ROAD;
+ callbacks.draw_edge(edge);
+ if (log_changes) {
+ log_message(MSG_BUILD, _("%s built a road.\n"),
+ player_name(player_num, TRUE));
+ }
+ if (player_num == my_player_num())
+ stock_use_road();
+ break;
+ case BUILD_SHIP:
+ edge = map_edge(map, x, y, pos);
+ edge->owner = player_num;
+ edge->type = BUILD_SHIP;
+ callbacks.draw_edge(edge);
+ if (log_changes) {
+ log_message(MSG_BUILD, _("%s built a ship.\n"),
+ player_name(player_num, TRUE));
+ }
+ if (player_num == my_player_num())
+ stock_use_ship();
+ break;
+ case BUILD_SETTLEMENT:
+ node = map_node(map, x, y, pos);
+ node->type = BUILD_SETTLEMENT;
+ node->owner = player_num;
+ callbacks.draw_node(node);
+ if (log_changes) {
+ log_message(MSG_BUILD,
+ _("%s built a settlement.\n"),
+ player_name(player_num, TRUE));
+ }
+ player_modify_statistic(player_num, STAT_SETTLEMENTS, 1);
+ if (player_num == my_player_num())
+ stock_use_settlement();
+ break;
+ case BUILD_CITY:
+ node = map_node(map, x, y, pos);
+ if (node->type == BUILD_SETTLEMENT) {
+ player_modify_statistic(player_num,
+ STAT_SETTLEMENTS, -1);
+ if (player_num == my_player_num())
+ stock_replace_settlement();
+ }
+ node->type = BUILD_CITY;
+ node->owner = player_num;
+ callbacks.draw_node(node);
+ if (log_changes) {
+ log_message(MSG_BUILD, _("%s built a city.\n"),
+ player_name(player_num, TRUE));
+ }
+ player_modify_statistic(player_num, STAT_CITIES, 1);
+ if (player_num == my_player_num())
+ stock_use_city();
+ break;
+ case BUILD_CITY_WALL:
+ node = map_node(map, x, y, pos);
+ node->city_wall = TRUE;
+ node->owner = player_num;
+ callbacks.draw_node(node);
+ if (log_changes) {
+ log_message(MSG_BUILD,
+ _("%s built a city wall.\n"),
+ player_name(player_num, TRUE));
+ }
+ player_modify_statistic(player_num, STAT_CITY_WALLS, 1);
+ if (player_num == my_player_num())
+ stock_use_city_wall();
+ break;
+
+ case BUILD_NONE:
+ log_message(MSG_ERROR,
+ _
+ ("player_build_add called with BUILD_NONE for user %s\n"),
+ player_name(player_num, TRUE));
+ break;
+ case BUILD_BRIDGE:
+ edge = map_edge(map, x, y, pos);
+ edge->owner = player_num;
+ edge->type = BUILD_BRIDGE;
+ callbacks.draw_edge(edge);
+ if (log_changes) {
+ log_message(MSG_BUILD, _("%s built a bridge.\n"),
+ player_name(player_num, TRUE));
+ }
+ if (player_num == my_player_num())
+ stock_use_bridge();
+ break;
+ case BUILD_MOVE_SHIP:
+ /* This clause here to remove a compiler warning.
+ It should not be possible to reach this code. */
+ g_error("Bug: unreachable code reached");
+ break;
+ }
+}
+
+void player_build_remove(gint player_num,
+ BuildType type, gint x, gint y, gint pos)
+{
+ Edge *edge;
+ Node *node;
+
+ switch (type) {
+ case BUILD_ROAD:
+ edge = map_edge(map, x, y, pos);
+ edge->owner = -1;
+ callbacks.draw_edge(edge);
+ edge->type = BUILD_NONE;
+ log_message(MSG_BUILD, _("%s removed a road.\n"),
+ player_name(player_num, TRUE));
+ if (player_num == my_player_num())
+ stock_replace_road();
+ break;
+ case BUILD_SHIP:
+ edge = map_edge(map, x, y, pos);
+ edge->owner = -1;
+ callbacks.draw_edge(edge);
+ edge->type = BUILD_NONE;
+ log_message(MSG_BUILD, _("%s removed a ship.\n"),
+ player_name(player_num, TRUE));
+ if (player_num == my_player_num())
+ stock_replace_ship();
+ break;
+ case BUILD_SETTLEMENT:
+ node = map_node(map, x, y, pos);
+ node->type = BUILD_NONE;
+ node->owner = -1;
+ callbacks.draw_node(node);
+ log_message(MSG_BUILD, _("%s removed a settlement.\n"),
+ player_name(player_num, TRUE));
+ player_modify_statistic(player_num, STAT_SETTLEMENTS, -1);
+ if (player_num == my_player_num())
+ stock_replace_settlement();
+ break;
+ case BUILD_CITY:
+ node = map_node(map, x, y, pos);
+ node->type = BUILD_SETTLEMENT;
+ node->owner = player_num;
+ callbacks.draw_node(node);
+ log_message(MSG_BUILD, _("%s removed a city.\n"),
+ player_name(player_num, TRUE));
+ player_modify_statistic(player_num, STAT_SETTLEMENTS, 1);
+ player_modify_statistic(player_num, STAT_CITIES, -1);
+ if (player_num == my_player_num()) {
+ stock_use_settlement();
+ stock_replace_city();
+ }
+ break;
+ case BUILD_CITY_WALL:
+ node = map_node(map, x, y, pos);
+ node->city_wall = FALSE;
+ node->owner = player_num;
+ callbacks.draw_node(node);
+ log_message(MSG_BUILD, _("%s removed a city wall.\n"),
+ player_name(player_num, TRUE));
+ player_modify_statistic(player_num, STAT_CITY_WALLS, -1);
+ if (player_num == my_player_num())
+ stock_replace_city_wall();
+ break;
+
+ case BUILD_NONE:
+ log_message(MSG_ERROR,
+ _
+ ("player_build_remove called with BUILD_NONE for user %s\n"),
+ player_name(player_num, TRUE));
+ break;
+ case BUILD_BRIDGE:
+ edge = map_edge(map, x, y, pos);
+ edge->owner = -1;
+ callbacks.draw_edge(edge);
+ edge->type = BUILD_NONE;
+ log_message(MSG_BUILD, _("%s removed a bridge.\n"),
+ player_name(player_num, TRUE));
+ if (player_num == my_player_num())
+ stock_replace_bridge();
+ break;
+ case BUILD_MOVE_SHIP:
+ /* This clause here to remove a compiler warning.
+ It should not be possible to reach this case. */
+ g_error("Bug: unreachable code reached");
+ break;
+ }
+}
+
+void player_build_move(gint player_num, gint sx, gint sy, gint spos,
+ gint dx, gint dy, gint dpos, gint isundo)
+{
+ Edge *from = map_edge(map, sx, sy, spos),
+ *to = map_edge(map, dx, dy, dpos);
+ if (isundo) {
+ Edge *tmp = from;
+ from = to;
+ to = tmp;
+ }
+ from->owner = -1;
+ callbacks.draw_edge(from);
+ from->type = BUILD_NONE;
+ to->owner = player_num;
+ to->type = BUILD_SHIP;
+ callbacks.draw_edge(to);
+ if (isundo)
+ log_message(MSG_BUILD,
+ _("%s has cancelled a ship's movement.\n"),
+ player_name(player_num, TRUE));
+ else
+ log_message(MSG_BUILD, _("%s moved a ship.\n"),
+ player_name(player_num, TRUE));
+}
+
+void player_resource_action(gint player_num, const gchar * action,
+ const gint * resource_list, gint mult)
+{
+ resource_log_list(player_num, action, resource_list);
+ resource_apply_list(player_num, resource_list, mult);
+}
+
+/* get a new point */
+void player_get_point(gint player_num, gint id, const gchar * str,
+ gint num)
+{
+ Player *player = player_get(player_num);
+ /* create the point */
+ Points *point = points_new(id, str, num);
+ player_modify_points(player_num, point, TRUE);
+ /* tell the user that someone got something */
+ log_message(MSG_INFO, _("%s received %s.\n"), player->name, str);
+}
+
+/* lose a point: noone gets it */
+void player_lose_point(gint player_num, gint id)
+{
+ Player *player = player_get(player_num);
+ Points *point;
+ GList *list;
+ /* look up the point in the list */
+ for (list = player->points; list != NULL; list = g_list_next(list)) {
+ point = list->data;
+ if (point->id == id)
+ break;
+ }
+ /* communication error: the point doesn't exist */
+ if (list == NULL) {
+ log_message(MSG_ERROR,
+ _("server asks to lose invalid point.\n"));
+ return;
+ }
+ player->points = g_list_remove(player->points, point);
+ player_modify_points(player_num, point, FALSE);
+ /* tell the user the point is lost */
+ log_message(MSG_INFO, _("%s lost %s.\n"), player->name,
+ point->name);
+ /* free the memory */
+ points_free(point);
+ g_free(point);
+}
+
+/* take a point from an other player */
+void player_take_point(gint player_num, gint id, gint old_owner)
+{
+ Player *player = player_get(player_num);
+ Player *victim = player_get(old_owner);
+ Points *point;
+ GList *list;
+ /* look up the point in the list */
+ for (list = victim->points; list != NULL; list = g_list_next(list)) {
+ point = list->data;
+ if (point->id == id)
+ break;
+ }
+ /* communication error: the point doesn't exist */
+ if (list == NULL) {
+ log_message(MSG_ERROR,
+ _("server asks to move invalid point.\n"));
+ return;
+ }
+ /* move the point in memory */
+ victim->points = g_list_remove(victim->points, point);
+ player->points = g_list_append(player->points, point);
+ /* tell the user someone (1) lost something (2) to someone else (3) */
+ log_message(MSG_INFO, _("%s lost %s to %s.\n"), victim->name,
+ point->name, player->name);
+}
+
+void player_set_style(gint player_num, const gchar * style)
+{
+ if (player_num >= num_total_players) {
+ Viewer *viewer = viewer_get(player_num);
+ if (viewer->style)
+ g_free(viewer->style);
+ viewer->style = g_strdup(style);
+ } else if (player_num >= 0) {
+ Player *player = player_get(player_num);
+ if (player->style)
+ g_free(player->style);
+ player->style = g_strdup(style);
+ }
+}
+
+const gchar *player_get_style(gint player_num)
+{
+ const gchar *style = NULL;
+ if (player_num >= num_total_players) {
+ Viewer *viewer = viewer_get(player_num);
+ style = viewer->style;
+ } else if (player_num >= 0) {
+ Player *player = player_get(player_num);
+ style = player->style;
+ }
+ return style == NULL ? "square" : style;
+}
+
+gint current_player(void)
+{
+ return turn_player;
+}
+
+const gchar *my_player_name(void)
+{
+ return player_name(my_player_num(), TRUE);
+}
+
+gboolean my_player_viewer(void)
+{
+ return player_is_viewer(my_player_num());
+}
+
+const gchar *my_player_style(void)
+{
+ return player_get_style(my_player_num());
+}
+
+gint find_player_by_name(const gchar * name)
+{
+ gint i;
+ GList *list;
+
+ for (i = 0; i < num_total_players; i++) {
+ Player *player = player_get(i);
+ if (player->name && !strcmp(player->name, name))
+ return i;
+ }
+
+ for (list = viewers; list != NULL; list = g_list_next(list)) {
+ Viewer *viewer = list->data;
+ if (!strcmp(viewer->name, name))
+ return viewer->num;
+ }
+ return -1;
+}
Added: trunk/client/common/resource.c
===================================================================
--- trunk/client/common/resource.c (rev 0)
+++ trunk/client/common/resource.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,279 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include <stdio.h>
+
+#include "cost.h"
+#include "log.h"
+#include "client.h"
+#include "game.h"
+#include "map.h"
+
+static gint bank[NO_RESOURCE];
+
+static const gchar *resource_names[][2] = {
+ {N_("brick"), N_("Brick")},
+ {N_("grain"), N_("Grain")},
+ {N_("ore"), N_("Ore")},
+ {N_("wool"), N_("Wool")},
+ {N_("lumber"), N_("Lumber")},
+ {N_("no resource (bug)"), N_("No resource (bug)")},
+ {N_("any resource (bug)"), N_("Any resource (bug)")},
+ {N_("gold"), N_("Gold")}
+};
+
+
+static const gchar *resource_lists[][2] = {
+ {N_("a brick card"), N_("%d brick cards")},
+ {N_("a grain card"), N_("%d grain cards")},
+ {N_("an ore card"), N_("%d ore cards")},
+ {N_("a wool card"), N_("%d wool cards")},
+ {N_("a lumber card"), N_("%d lumber cards")}
+};
+
+typedef enum {
+ RESOURCE_SINGLECARD = 0,
+ RESOURCE_MULTICARD
+} ResourceListType;
+
+static gint my_assets[NO_RESOURCE]; /* my resources */
+
+static const gchar *resource_list(Resource type, ResourceListType grammar)
+{
+ return _(resource_lists[type][grammar]);
+}
+
+/* Clear all */
+void resource_init(void)
+{
+ gint idx;
+
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ my_assets[idx] = 0;
+ resource_modify(idx, 0);
+ };
+}
+
+void resource_apply_list(gint player_num, const gint * resources,
+ gint mult)
+{
+ gint idx;
+ gint bank_change[NO_RESOURCE];
+
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ gint num = resources[idx] * mult;
+
+ bank_change[idx] = -num;
+ if (num == 0)
+ continue;
+ player_modify_statistic(player_num, STAT_RESOURCES, num);
+ if (player_num == my_player_num())
+ resource_modify(idx, num);
+ }
+ modify_bank(bank_change);
+}
+
+gchar *resource_cards(gint num, Resource type)
+{
+ /* FIXME: this should be touched up to take advantage of the
+ GNU ngettext API */
+ if (num != 1)
+ return
+ g_strdup_printf(resource_list
+ (type, RESOURCE_MULTICARD), num);
+ else
+ return g_strdup(resource_list(type, RESOURCE_SINGLECARD));
+}
+
+gint resource_count(const gint * resources)
+{
+ gint num;
+ gint idx;
+
+ num = 0;
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ num += resources[idx];
+
+ return num;
+}
+
+gint resource_total(void)
+{
+ return resource_count(my_assets);
+}
+
+gchar *resource_format_num(const gint * resources)
+{
+ gint idx;
+ gint num_types;
+ gchar *str;
+
+ /* Count how many different resources in list
+ */
+ num_types = 0;
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ if (resources[idx] != 0)
+ num_types++;
+
+ if (num_types == 0) {
+ return g_strdup(_("nothing"));
+ }
+
+ if (num_types == 1) {
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ gint num = resources[idx];
+ if (num == 0)
+ continue;
+ return g_strdup(resource_cards(num, idx));
+ }
+ }
+
+ str = NULL;
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ gchar *old;
+ gint num = resources[idx];
+ if (num == 0)
+ continue;
+
+ if (str == NULL) {
+ str = g_strdup(resource_cards(num, idx));
+ num_types--;
+ continue;
+ }
+ old = str;
+ if (num_types == 1) {
+ /* Construct "A, B and C" for resources */
+ str = g_strdup_printf(_("%s and %s"), str,
+ resource_cards(num, idx));
+ } else {
+ /* Construct "A, B and C" for resources */
+ str = g_strdup_printf(_("%s, %s"), str,
+ resource_cards(num, idx));
+ }
+ g_free(old);
+ num_types--;
+ }
+ return str;
+}
+
+void resource_log_list(gint player_num, const gchar * action,
+ const gint * resources)
+{
+ gchar *buff;
+
+ buff = resource_format_num(resources);
+ log_message(MSG_RESOURCE, action,
+ player_name(player_num, TRUE), buff);
+ g_free(buff);
+}
+
+void resource_modify(Resource type, gint num)
+{
+ my_assets[type] += num;
+ callbacks.resource_change(type, my_assets[type]);
+}
+
+gboolean can_afford(const gint * cost)
+{
+ return cost_can_afford(cost, my_assets);
+}
+
+gint resource_asset(Resource type)
+{
+ return my_assets[type];
+}
+
+const gchar *resource_name(Resource type, gboolean word_caps)
+{
+ return _(resource_names[type][word_caps ? 1 : 0]);
+}
+
+void resource_format_type(gchar * str, const gint * resources)
+{
+ gint idx;
+ gint num_types;
+ gboolean add_comma;
+
+ /* Count how many different resources in list
+ */
+ num_types = 0;
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ if (resources[idx] != 0)
+ num_types++;
+
+ if (num_types == 0) {
+ strcpy(str, _("nothing"));
+ return;
+ }
+
+ if (num_types == 1) {
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ gint num = resources[idx];
+ if (num == 0)
+ continue;
+
+ strcpy(str, resource_name(idx, FALSE));
+ }
+ return;
+ }
+
+ add_comma = FALSE;
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ gint num = resources[idx];
+ if (num == 0)
+ continue;
+
+ if (add_comma) {
+ strcpy(str, " + ");
+ str += strlen(str);
+ }
+ if (num > 1)
+ sprintf(str, "%d %s", num,
+ resource_name(idx, FALSE));
+ else
+ sprintf(str, "%s", resource_name(idx, FALSE));
+ add_comma = TRUE;
+ str += strlen(str);
+ }
+}
+
+const gint *get_bank(void)
+{
+ return bank;
+}
+
+void set_bank(const gint * new_bank)
+{
+ gint idx;
+ for (idx = 0; idx < NO_RESOURCE; ++idx)
+ bank[idx] = new_bank[idx];
+ callbacks.new_bank(bank);
+}
+
+void modify_bank(const gint * bank_change)
+{
+ gint idx;
+ for (idx = 0; idx < NO_RESOURCE; ++idx)
+ bank[idx] += bank_change[idx];
+ callbacks.new_bank(bank);
+}
Added: trunk/client/common/robber.c
===================================================================
--- trunk/client/common/robber.c (rev 0)
+++ trunk/client/common/robber.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,87 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdio.h>
+
+#include "game.h"
+#include "map.h"
+#include "client.h"
+#include "log.h"
+#include "callback.h"
+
+void robber_move_on_map(gint x, gint y)
+{
+ Hex *hex = map_hex(map, x, y);
+ Hex *old_robber = map_robber_hex(map);
+
+ map_move_robber(map, x, y);
+
+ callbacks.draw_hex(old_robber);
+ callbacks.draw_hex(hex);
+ callbacks.robber_moved(old_robber, hex);
+}
+
+void pirate_move_on_map(gint x, gint y)
+{
+ Hex *hex = map_hex(map, x, y);
+ Hex *old_pirate = map_pirate_hex(map);
+
+ map_move_pirate(map, x, y);
+
+ callbacks.draw_hex(old_pirate);
+ callbacks.draw_hex(hex);
+ callbacks.robber_moved(old_pirate, hex);
+}
+
+void robber_moved(gint player_num, gint x, gint y, gboolean is_undo)
+{
+ robber_move_on_map(x, y);
+ if (is_undo)
+ log_message(MSG_STEAL,
+ _("%s has undone the robber movement.\n"),
+ player_name(player_num, TRUE));
+ else
+ log_message(MSG_STEAL, _("%s moved the robber.\n"),
+ player_name(player_num, TRUE));
+}
+
+
+void pirate_moved(gint player_num, gint x, gint y, gboolean is_undo)
+{
+ pirate_move_on_map(x, y);
+ if (is_undo)
+ log_message(MSG_STEAL,
+ _("%s has undone the pirate movement.\n"),
+ player_name(player_num, TRUE));
+ else
+ log_message(MSG_STEAL, _("%s moved the pirate.\n"),
+ player_name(player_num, TRUE));
+}
+
+void robber_begin_move(gint player_num)
+{
+ gchar *buffer;
+ buffer = g_strdup_printf(_("%s must move the robber."),
+ player_name(player_num, TRUE));
+ callbacks.instructions(buffer);
+ g_free(buffer);
+}
Added: trunk/client/common/setup.c
===================================================================
--- trunk/client/common/setup.c (rev 0)
+++ trunk/client/common/setup.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,160 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <ctype.h>
+
+#include "game.h"
+#include "cards.h"
+#include "map.h"
+#include "network.h"
+#include "log.h"
+#include "client.h"
+
+static gboolean double_setup;
+
+gboolean is_setup_double(void)
+{
+ return double_setup;
+}
+
+gboolean setup_can_build_road(void)
+{
+ if (game_params->num_build_type[BUILD_ROAD] == 0)
+ return FALSE;
+ if (double_setup) {
+ if (build_count_edges() == 2)
+ return FALSE;
+ return build_count_settlements() < 2
+ || map_can_place_road(map, my_player_num());
+ } else {
+ if (build_count_edges() == 1)
+ return FALSE;
+ return build_count_settlements() < 1
+ || map_can_place_road(map, my_player_num());
+ }
+}
+
+gboolean setup_can_build_ship(void)
+{
+ if (game_params->num_build_type[BUILD_SHIP] == 0)
+ return FALSE;
+ if (double_setup) {
+ if (build_count_edges() == 2)
+ return FALSE;
+ return build_count_settlements() < 2
+ || map_can_place_ship(map, my_player_num());
+ } else {
+ if (build_count_edges() == 1)
+ return FALSE;
+ return build_count_settlements() < 1
+ || map_can_place_ship(map, my_player_num());
+ }
+}
+
+gboolean setup_can_build_bridge(void)
+{
+ if (game_params->num_build_type[BUILD_BRIDGE] == 0)
+ return FALSE;
+ if (double_setup) {
+ if (build_count_edges() == 2)
+ return FALSE;
+ return build_count_settlements() < 2
+ || map_can_place_bridge(map, my_player_num());
+ } else {
+ if (build_count_edges() == 1)
+ return FALSE;
+ return build_count_settlements() < 1
+ || map_can_place_bridge(map, my_player_num());
+ }
+}
+
+gboolean setup_can_build_settlement(void)
+{
+ if (game_params->num_build_type[BUILD_SETTLEMENT] == 0)
+ return FALSE;
+ if (double_setup)
+ return build_count_settlements() < 2;
+ else
+ return build_count_settlements() < 1;
+}
+
+gboolean setup_can_finish(void)
+{
+ if (double_setup)
+ return build_count_edges() == 2
+ && build_count_settlements() == 2 && build_is_valid();
+ else
+ return build_count_edges() == 1
+ && build_count_settlements() == 1 && build_is_valid();
+}
+
+/* Place some restrictions on road placement during setup phase
+ */
+gboolean setup_check_road(const Edge * edge)
+{
+ return build_can_setup_road(edge, double_setup);
+}
+
+/* Place some restrictions on ship placement during setup phase
+ */
+gboolean setup_check_ship(const Edge * edge)
+{
+ return build_can_setup_ship(edge, double_setup);
+}
+
+/* Place some restrictions on bridge placement during setup phase
+ */
+gboolean setup_check_bridge(const Edge * edge)
+{
+ return build_can_setup_bridge(edge, double_setup);
+}
+
+/* Place some restrictions on settlement placement during setup phase
+ */
+gboolean setup_check_settlement(const Node * node)
+{
+ return build_can_setup_settlement(node, double_setup);
+}
+
+void setup_begin(gint player_num)
+{
+ log_message(MSG_INFO, _("Setup for %s.\n"),
+ player_name(player_num, FALSE));
+ player_set_current(player_num);
+ if (player_num != my_player_num())
+ return;
+
+ double_setup = FALSE;
+ build_clear();
+}
+
+void setup_begin_double(gint player_num)
+{
+ log_message(MSG_INFO, _("Double setup for %s.\n"),
+ player_name(player_num, FALSE));
+ player_set_current(player_num);
+ if (player_num != my_player_num())
+ return;
+
+ double_setup = TRUE;
+ build_clear();
+}
Added: trunk/client/common/stock.c
===================================================================
--- trunk/client/common/stock.c (rev 0)
+++ trunk/client/common/stock.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,167 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <math.h>
+#include <ctype.h>
+
+#include "game.h"
+#include "map.h"
+#include "client.h"
+#include "callback.h"
+
+static gint num_roads; /* number of roads available */
+static gint num_ships; /* number of ships available */
+static gint num_bridges; /* number of bridges available */
+static gint num_settlements; /* settlements available */
+static gint num_cities; /* cities available */
+static gint num_city_walls; /* city walls available */
+static gint num_develop; /* development cards left */
+
+void stock_init(void)
+{
+ int idx;
+
+ num_roads = game_params->num_build_type[BUILD_ROAD];
+ num_ships = game_params->num_build_type[BUILD_SHIP];
+ num_bridges = game_params->num_build_type[BUILD_BRIDGE];
+ num_settlements = game_params->num_build_type[BUILD_SETTLEMENT];
+ num_cities = game_params->num_build_type[BUILD_CITY];
+ num_city_walls = game_params->num_build_type[BUILD_CITY_WALL];
+
+ num_develop = 0;
+ for (idx = 0; idx < G_N_ELEMENTS(game_params->num_develop_type);
+ idx++)
+ num_develop += game_params->num_develop_type[idx];
+}
+
+gint stock_num_roads(void)
+{
+ return num_roads;
+}
+
+void stock_use_road(void)
+{
+ num_roads--;
+ callbacks.update_stock();
+}
+
+void stock_replace_road(void)
+{
+ num_roads++;
+ callbacks.update_stock();
+}
+
+gint stock_num_ships(void)
+{
+ return num_ships;
+}
+
+void stock_use_ship(void)
+{
+ num_ships--;
+ callbacks.update_stock();
+}
+
+void stock_replace_ship(void)
+{
+ num_ships++;
+ callbacks.update_stock();
+}
+
+gint stock_num_bridges(void)
+{
+ return num_bridges;
+}
+
+void stock_use_bridge(void)
+{
+ num_bridges--;
+ callbacks.update_stock();
+}
+
+void stock_replace_bridge(void)
+{
+ num_bridges++;
+ callbacks.update_stock();
+}
+
+gint stock_num_settlements(void)
+{
+ return num_settlements;
+}
+
+void stock_use_settlement(void)
+{
+ num_settlements--;
+ callbacks.update_stock();
+}
+
+void stock_replace_settlement(void)
+{
+ num_settlements++;
+ callbacks.update_stock();
+}
+
+gint stock_num_cities(void)
+{
+ return num_cities;
+}
+
+void stock_use_city(void)
+{
+ num_cities--;
+ callbacks.update_stock();
+}
+
+void stock_replace_city(void)
+{
+ num_cities++;
+ callbacks.update_stock();
+}
+
+gint stock_num_city_walls(void)
+{
+ return num_city_walls;
+}
+
+void stock_use_city_wall(void)
+{
+ num_city_walls--;
+ callbacks.update_stock();
+}
+
+void stock_replace_city_wall(void)
+{
+ num_city_walls++;
+ callbacks.update_stock();
+}
+
+
+gint stock_num_develop(void)
+{
+ return num_develop;
+}
+
+void stock_use_develop(void)
+{
+ num_develop--;
+}
Added: trunk/client/common/turn.c
===================================================================
--- trunk/client/common/turn.c (rev 0)
+++ trunk/client/common/turn.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,67 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <ctype.h>
+
+#include "log.h"
+#include "client.h"
+#include "callback.h"
+
+static gboolean rolled_dice; /* have we rolled the dice? */
+static gint current_turn;
+
+void turn_rolled_dice(gint player_num, gint die1, gint die2)
+{
+ int roll;
+
+ roll = die1 + die2;
+ log_message(MSG_DICE, _("%s rolled %d.\n"),
+ player_name(player_num, TRUE), roll);
+
+ if (player_num == my_player_num()) {
+ rolled_dice = TRUE;
+ map->has_moved_ship = FALSE;
+ }
+ callbacks.rolled_dice(die1, die2, player_num);
+}
+
+void turn_begin(gint player_num, gint num)
+{
+ current_turn = num;
+ log_message(MSG_DICE, _("Begin turn %d for %s.\n"),
+ num, player_name(player_num, FALSE));
+ rolled_dice = FALSE;
+ player_set_current(player_num);
+ develop_begin_turn();
+ build_clear();
+ callbacks.player_turn(player_num);
+}
+
+gint turn_num(void)
+{
+ return current_turn;
+}
+
+gboolean have_rolled_dice(void)
+{
+ return rolled_dice;
+}
Added: trunk/client/gtk/Makefile.am
===================================================================
--- trunk/client/gtk/Makefile.am (rev 0)
+++ trunk/client/gtk/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,77 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+bin_PROGRAMS += pioneers
+
+# if anyone knows a cleaner way to do this, be my guest. Automake screamed
+# at me when I tried to do it more directly.
+if ADMIN_GTK_SUPPORT
+ADMIN_GTK = -DADMIN_GTK
+ADMIN_GTK_FILES_ACTIVE = client/gtk/admin-gtk.c
+ADMIN_GTK_FILES_INACTIVE =
+else
+ADMIN_GTK =
+ADMIN_GTK_FILES_ACTIVE =
+ADMIN_GTK_FILES_INACTIVE = client/gtk/admin-gtk.c
+endif
+
+pioneers_CPPFLAGS = -I$(top_srcdir)/client $(gtk_cflags) $(ADMIN_GTK)
+
+EXTRA_pioneers_SOURCES = $(ADMIN_GTK_FILES_INACTIVE)
+
+pioneers_SOURCES = \
+ $(ADMIN_GTK_FILES_ACTIVE) \
+ client/callback.h \
+ client/gtk/frontend.h \
+ client/gtk/gui.h \
+ client/gtk/histogram.h \
+ client/gtk/callbacks.c \
+ client/gtk/chat.c \
+ client/gtk/connect.c \
+ client/gtk/develop.c \
+ client/gtk/discard.c \
+ client/gtk/frontend.c \
+ client/gtk/gameover.c \
+ client/gtk/gold.c \
+ client/gtk/gui.c \
+ client/gtk/histogram.c \
+ client/gtk/identity.c \
+ client/gtk/interface.c \
+ client/gtk/legend.c \
+ client/gtk/monopoly.c \
+ client/gtk/name.c \
+ client/gtk/offline.c \
+ client/gtk/plenty.c \
+ client/gtk/player.c \
+ client/gtk/quote.c \
+ client/gtk/quote-view.c \
+ client/gtk/quote-view.h \
+ client/gtk/resource.c \
+ client/gtk/resource-table.c \
+ client/gtk/resource-table.h \
+ client/gtk/settingscreen.c \
+ client/gtk/state.c \
+ client/gtk/trade.c
+
+pioneers_LDADD = libpioneersclient.a $(gtk_libs)
+
+# Include the data here, not at the top,
+# it can add extra resources to the executable
+include client/gtk/data/Makefile.am
Added: trunk/client/gtk/admin-gtk.c
===================================================================
--- trunk/client/gtk/admin-gtk.c (rev 0)
+++ trunk/client/gtk/admin-gtk.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,389 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file has not been maintained for a long time */
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <limits.h>
+#include <gnome.h>
+
+#include "driver.h"
+#include "game.h"
+#include "cards.h"
+#include "map.h"
+#include "network.h"
+#include "log.h"
+#include "buildrec.h"
+#include "common_gtk.h"
+
+static GtkWidget *game_combo; /* select game type */
+static GtkWidget *terrain_toggle; /* random terrain Yes/No */
+static GtkWidget *victory_spin; /* victory point target */
+static GtkWidget *players_spin; /* number of players */
+static GtkWidget *register_toggle; /* register with meta server? */
+static GtkWidget *port_spin; /* server port */
+
+static GtkWidget *clist; /* currently connected players */
+
+static Session *_admin_session = 0;
+
+/* this really needs to be eliminated from here */
+static gchar *server_port = "5556";
+static gint server_port_int = 5556;
+
+/* network event handler, just like the one in meta.c, state.c, etc. */
+void admin_net_event(NetEvent event, Session * admin_session, gchar * line)
+{
+#ifdef PRINT_INFO
+ g_print
+ ("admin_event: event = %#x, admin_session = %p, line = %s\n",
+ event, admin_session, line);
+#endif
+
+ switch (event) {
+ case NET_READ:
+ /* there is data to be read */
+
+#ifdef PRINT_INFO
+ g_print("admin_event: NET_READ: line = '%s'\n", line);
+#endif
+ break;
+
+ case NET_CONNECT:
+ /* connect() succeeded */
+
+#ifdef PRINT_INFO
+ g_print("admin_event: NET_CONNECT\n");
+#endif
+ break;
+
+ case NET_CONNECT_FAIL:
+ /* connect() failed */
+
+#ifdef PRINT_INFO
+ g_print
+ ("admin_event: NET_CONNECT_FAIL (falling through to NET_CLOSE...)\n");
+#endif
+
+ /* fall through to NET_CLOSE */
+
+ case NET_CLOSE:
+ /* connection has been closed */
+
+#ifdef PRINT_INFO
+ g_print("admin_event: NET_CLOSE\n");
+#endif
+ net_free(&admin_session);
+ break;
+
+ default:
+ }
+}
+
+static void admin_open_session(void)
+{
+ _admin_session = net_new(admin_net_event, NULL);
+ _admin_session->user_data = _admin_session;
+
+ /* TODO: tie the connect dialog to this */
+ net_connect(_admin_session, "localhost", 5555);
+}
+
+static void admin_close_session(void)
+{
+ if (_admin_session) {
+ net_close(_admin_session);
+ _admin_session = 0;
+ }
+}
+
+#define ADMIN_BUFSIZE 4096
+#define ADMIN_PREFIX_LEN 6
+static void admin_write(gchar * fmt, ...)
+{
+ char buff[ADMIN_BUFSIZE];
+ va_list ap;
+
+ strncpy(buff, "admin ", ADMIN_PREFIX_LEN);
+
+ if (!_admin_session) {
+ admin_open_session();
+ }
+
+ va_start(ap, fmt);
+ g_vsnprintf(&buff[ADMIN_PREFIX_LEN],
+ ADMIN_BUFSIZE - ADMIN_PREFIX_LEN, fmt, ap);
+ va_end(ap);
+
+ net_write(_admin_session, buff);
+}
+
+
+static void port_spin_changed_cb(GtkWidget * widget, gpointer user_data)
+{
+ gint server_port_int =
+ gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
+ snprintf(server_port, sizeof(server_port), "%d", server_port_int);
+
+ admin_write("set-port %s\n", server_port);
+}
+
+static void register_toggle_cb(GtkToggleButton * toggle,
+ gpointer user_data)
+{
+ GtkWidget *label = GTK_BIN(toggle)->child;
+
+ gint register_server = gtk_toggle_button_get_active(toggle);
+ gtk_label_set_text(GTK_LABEL(label),
+ register_server ? _("Yes") : _("No"));
+
+ admin_write("set-register-server %d\n", register_server);
+}
+
+static void players_spin_changed_cb(GtkWidget * widget, gpointer user_data)
+{
+ admin_write("set-num-players %d\n",
+ gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
+ (widget)));
+}
+
+static void victory_spin_changed_cb(GtkWidget * widget, gpointer user_data)
+{
+ admin_write("set-victory-points %d\n",
+ gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
+ (widget)));
+}
+
+static void game_select_cb(GtkWidget * list, gpointer user_data)
+{
+}
+
+static void terrain_toggle_cb(GtkToggleButton * toggle, gpointer user_data)
+{
+ GtkWidget *label = GTK_BIN(toggle)->child;
+
+ gint random_terrain = gtk_toggle_button_get_active(toggle);
+ gtk_label_set_text(GTK_LABEL(label),
+ random_terrain ? _("Random") : _("Default"));
+
+ admin_write("set-random-terrain %d\n", random_terrain);
+}
+
+static void start_clicked_cb(GtkWidget * start_btn, gpointer user_data)
+{
+ admin_write("start-server\n");
+}
+
+void show_admin_interface()
+{
+ GtkWidget *admin_if;
+ GtkDialog *dialog;
+
+ dialog = gtk_dialog_new();
+ gtk_window_set_title("Administration");
+ admin_if = build_admin_interface(dialog->vbox);
+ gtk_widget_show_all(dialog);
+ admin_open_session();
+}
+
+GtkWidget *build_admin_interface(GtkWidget * vbox)
+{
+ GtkWidget *hbox;
+ GtkWidget *frame;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkObject *adj;
+ GtkWidget *start_btn;
+ GtkWidget *scroll_win;
+ GtkWidget *message_text;
+
+ static gchar *titles[2];
+
+ if (!vbox)
+ vbox = gtk_vbox_new(FALSE, 0);
+
+ if (!titles[0]) {
+ titles[0] = _("Name");
+ titles[1] = _("Location");
+ }
+
+ gtk_widget_show(vbox);
+ gtk_container_border_width(GTK_CONTAINER(vbox), 5);
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+
+ frame = gtk_frame_new(_("Server Parameters"));
+ gtk_widget_show(frame);
+ gtk_box_pack_start(GTK_BOX(hbox), frame, FALSE, TRUE, 0);
+
+ table = gtk_table_new(6, 3, FALSE);
+ gtk_widget_show(table);
+ gtk_container_add(GTK_CONTAINER(frame), table);
+ gtk_container_border_width(GTK_CONTAINER(table), 3);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 5);
+
+ label = gtk_label_new(_("Game Name"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ game_combo = gtk_combo_new();
+ gtk_editable_set_editable(GTK_EDITABLE
+ (GTK_COMBO(game_combo)->entry), FALSE);
+ gtk_widget_set_usize(game_combo, 100, -1);
+ gtk_signal_connect(GTK_OBJECT(GTK_COMBO(game_combo)->list),
+ "select_child",
+ GTK_SIGNAL_FUNC(game_select_cb), NULL);
+ gtk_widget_show(game_combo);
+ gtk_table_attach(GTK_TABLE(table), game_combo, 1, 3, 0, 1,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+
+ label = gtk_label_new(_("Map Terrain"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ terrain_toggle = gtk_toggle_button_new_with_label("");
+ gtk_widget_show(terrain_toggle);
+ gtk_table_attach(GTK_TABLE(table), terrain_toggle, 1, 2, 1, 2,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_signal_connect(GTK_OBJECT(terrain_toggle), "toggled",
+ GTK_SIGNAL_FUNC(terrain_toggle_cb), NULL);
+
+ label = gtk_label_new(_("Number of Players"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ adj = gtk_adjustment_new(0, 2, MAX_PLAYERS, 1, 1, 1);
+ players_spin = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
+ gtk_widget_show(players_spin);
+ gtk_table_attach(GTK_TABLE(table), players_spin, 1, 2, 2, 3,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_signal_connect(GTK_OBJECT(players_spin), "changed",
+ GTK_SIGNAL_FUNC(players_spin_changed_cb), NULL);
+
+ label = gtk_label_new(_("Victory Point Target"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ adj = gtk_adjustment_new(10, 5, 20, 1, 1, 1);
+ victory_spin = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
+ gtk_widget_show(victory_spin);
+ gtk_table_attach(GTK_TABLE(table), victory_spin, 1, 2, 3, 4,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_signal_connect(GTK_OBJECT(victory_spin), "changed",
+ GTK_SIGNAL_FUNC(victory_spin_changed_cb), NULL);
+
+ label = gtk_label_new(_("Register Server"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ register_toggle = gtk_toggle_button_new_with_label(_("No"));
+ gtk_widget_show(register_toggle);
+ gtk_table_attach(GTK_TABLE(table), register_toggle, 1, 2, 4, 5,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_signal_connect(GTK_OBJECT(register_toggle), "toggled",
+ GTK_SIGNAL_FUNC(register_toggle_cb), NULL);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(register_toggle),
+ TRUE);
+ /* gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(register_toggle)); */
+
+ label = gtk_label_new("Server Port");
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ adj = gtk_adjustment_new(server_port_int, 1024, 32767, 1, 1, 1);
+ port_spin = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
+ gtk_widget_show(port_spin);
+ gtk_table_attach(GTK_TABLE(table), port_spin, 1, 2, 5, 6,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_widget_set_usize(port_spin, 60, -1);
+ gtk_signal_connect(GTK_OBJECT(port_spin), "changed",
+ GTK_SIGNAL_FUNC(port_spin_changed_cb), NULL);
+
+ start_btn = gtk_button_new_with_label(_("Start Server"));
+ gtk_widget_show(start_btn);
+ gtk_table_attach(GTK_TABLE(table), start_btn, 0, 2, 6, 7,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_signal_connect(GTK_OBJECT(start_btn), "clicked",
+ GTK_SIGNAL_FUNC(start_clicked_cb), NULL);
+
+ frame = gtk_frame_new(_("Players Connected"));
+ gtk_widget_show(frame);
+ gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0);
+ gtk_widget_set_usize(frame, 250, -1);
+
+ scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_widget_show(scroll_win);
+ gtk_container_add(GTK_CONTAINER(frame), scroll_win);
+ gtk_container_border_width(GTK_CONTAINER(scroll_win), 3);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ clist = gtk_clist_new_with_titles(2, titles);
+ gtk_widget_show(clist);
+ gtk_container_add(GTK_CONTAINER(scroll_win), clist);
+ gtk_clist_set_column_width(GTK_CLIST(clist), 0, 80);
+ gtk_clist_set_column_width(GTK_CLIST(clist), 1, 80);
+ gtk_clist_column_titles_show(GTK_CLIST(clist));
+ gtk_clist_column_titles_passive(GTK_CLIST(clist));
+
+ frame = gtk_frame_new(_("Messages"));
+ gtk_widget_show(frame);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+
+ scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_widget_show(scroll_win);
+ gtk_container_add(GTK_CONTAINER(frame), scroll_win);
+ gtk_container_border_width(GTK_CONTAINER(scroll_win), 3);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ return vbox;
+}
Added: trunk/client/gtk/callbacks.c
===================================================================
--- trunk/client/gtk/callbacks.c (rev 0)
+++ trunk/client/gtk/callbacks.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,171 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "histogram.h"
+
+static void frontend_network_status(const gchar * description)
+{
+ gui_set_net_status(description);
+ frontend_gui_update();
+}
+
+static void frontend_instructions(const gchar * message)
+{
+ gui_set_instructions(message);
+ frontend_gui_update();
+}
+
+static void frontend_network_wait(gboolean is_waiting)
+{
+ frontend_waiting_for_network = is_waiting;
+ frontend_gui_update();
+}
+
+static void frontend_init_game(void)
+{
+ player_clear_summary();
+ chat_clear_names();
+ develop_reset();
+ histogram_reset();
+ gui_reset();
+}
+
+static void frontend_start_game(void)
+{
+ gui_set_game_params(get_game_params());
+ set_num_players(num_players());
+ identity_reset();
+ gui_set_show_no_setup_nodes(!player_is_viewer(my_player_num()));
+ frontend_gui_update();
+}
+
+static void frontend_draw_edge(Edge * edge)
+{
+ gui_draw_edge(edge);
+ frontend_gui_update();
+}
+
+static void frontend_draw_node(Node * node)
+{
+ gui_draw_node(node);
+ frontend_gui_update();
+}
+
+static void frontend_draw_hex(Hex * hex)
+{
+ gui_draw_hex(hex);
+ frontend_gui_update();
+}
+
+static void frontend_update_stock(void)
+{
+ identity_draw();
+ frontend_gui_update();
+}
+
+static void frontend_player_turn(gint player)
+{
+ gui_set_show_no_setup_nodes(FALSE);
+ player_show_current(player);
+}
+
+static void frontend_trade(void)
+{
+ frontend_gui_update();
+}
+
+static void frontend_robber_moved(G_GNUC_UNUSED Hex * old,
+ G_GNUC_UNUSED Hex * new)
+{
+}
+
+static void frontend_new_bank(G_GNUC_UNUSED const gint * new_bank)
+{
+#ifdef DEBUG_BANK
+ debug("New bank: %d %d %d %d %d", new_bank[0], new_bank[1],
+ new_bank[2], new_bank[3], new_bank[4]);
+#endif
+}
+
+/* set all the callbacks. */
+void frontend_set_callbacks(void)
+{
+ callbacks.init = &frontend_init;
+ callbacks.network_status = &frontend_network_status;
+ callbacks.instructions = &frontend_instructions;
+ callbacks.network_wait = &frontend_network_wait;
+ callbacks.offline = &frontend_offline;
+ callbacks.discard = &frontend_discard;
+ callbacks.discard_add = &frontend_discard_add;
+ callbacks.discard_remove = &frontend_discard_remove;
+ callbacks.discard_done = &frontend_discard_done;
+ callbacks.gold = &frontend_gold;
+ callbacks.gold_add = &frontend_gold_add;
+ callbacks.gold_remove = &frontend_gold_remove;
+ callbacks.game_over = &frontend_game_over;
+ callbacks.init_game = &frontend_init_game;
+ callbacks.start_game = &frontend_start_game;
+ callbacks.setup = &frontend_setup;
+ callbacks.quote = &frontend_quote;
+ callbacks.roadbuilding = &frontend_roadbuilding;
+ callbacks.monopoly = &frontend_monopoly;
+ callbacks.plenty = &frontend_plenty;
+ callbacks.turn = &frontend_turn;
+ callbacks.player_turn = &frontend_player_turn;
+ callbacks.trade = &frontend_trade;
+ callbacks.trade_player_end = &frontend_trade_player_end;
+ callbacks.trade_add_quote = &frontend_trade_add_quote;
+ callbacks.trade_remove_quote = &frontend_trade_remove_quote;
+ callbacks.trade_domestic = &frontend_trade_domestic;
+ callbacks.trade_maritime = &frontend_trade_maritime;
+ callbacks.quote_player_end = &frontend_quote_player_end;
+ callbacks.quote_add = &frontend_quote_add;
+ callbacks.quote_remove = &frontend_quote_remove;
+ callbacks.quote_start = &frontend_quote_start;
+ callbacks.quote_end = &frontend_quote_end;
+ callbacks.quote_monitor = &frontend_quote_monitor;
+ callbacks.quote_trade = &frontend_quote_trade;
+ callbacks.rolled_dice = &frontend_rolled_dice;
+ callbacks.gold_choose = &frontend_gold_choose;
+ callbacks.gold_done = &frontend_gold_done;
+ callbacks.draw_edge = &frontend_draw_edge;
+ callbacks.draw_node = &frontend_draw_node;
+ callbacks.bought_develop = &frontend_bought_develop;
+ callbacks.played_develop = &frontend_played_develop;
+ callbacks.resource_change = &frontend_resource_change;
+ callbacks.draw_hex = &frontend_draw_hex;
+ callbacks.update_stock = &frontend_update_stock;
+ callbacks.robber = &frontend_robber;
+ callbacks.robber_moved = &frontend_robber_moved;
+ callbacks.steal_building = &frontend_steal_building;
+ callbacks.steal_ship = &frontend_steal_ship;
+ callbacks.robber_done = &frontend_robber_done;
+ callbacks.new_statistics = &frontend_new_statistics;
+ callbacks.new_points = &frontend_new_points;
+ callbacks.viewer_name = &frontend_viewer_name;
+ callbacks.player_name = &frontend_player_name;
+ callbacks.player_style = &frontend_player_style;
+ callbacks.player_quit = &frontend_player_quit;
+ callbacks.viewer_quit = &frontend_viewer_quit;
+ callbacks.incoming_chat = &chat_parser;
+ callbacks.new_bank = &frontend_new_bank;
+}
Added: trunk/client/gtk/chat.c
===================================================================
--- trunk/client/gtk/chat.c (rev 0)
+++ trunk/client/gtk/chat.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,332 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "common_gtk.h"
+
+static GtkWidget *chat_entry; /* messages text widget */
+static GtkListStore *chat_completion_model = NULL;
+static gboolean chat_grab_focus_on_update = FALSE; /**< Flag to indicate
+ * whether the chat widget should grab the focus whenever a GUI_UPDATE is sent */
+
+enum {
+ CHAT_PLAYER_NUM, /**< Player number */
+ CHAT_PLAYER_ICON, /**< The player icon */
+ CHAT_BEEP_TEXT, /**< Text for the completion */
+ CHAT_COLUMN_LAST
+};
+
+static void chat_cb(GtkEntry * entry, G_GNUC_UNUSED gpointer user_data)
+{
+ const gchar *text = gtk_entry_get_text(entry);
+
+ if (text[0] != '\0') {
+ gchar buff[MAX_CHAT + 1];
+ gint idx;
+
+ strncpy(buff, text, sizeof(buff) - 1);
+ buff[sizeof(buff) - 1] = '\0';
+ /* Replace newlines in message with spaces. In a line
+ * oriented protocol, newlines are a bit confusing :-)
+ */
+ for (idx = 0; buff[idx] != '\0'; idx++)
+ if (buff[idx] == '\n')
+ buff[idx] = ' ';
+
+ cb_chat(buff);
+ gtk_entry_set_text(entry, "");
+ }
+}
+
+GtkWidget *chat_build_panel(void)
+{
+ GtkWidget *hbox;
+ GtkWidget *label;
+ GtkEntryCompletion *completion;
+ GtkCellRenderer *cell;
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_widget_show(hbox);
+
+ label = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(label), _("<b>Chat</b>"));
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+
+ chat_entry = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(chat_entry), MAX_CHAT);
+ g_signal_connect(G_OBJECT(chat_entry), "activate",
+ G_CALLBACK(chat_cb), NULL);
+ gtk_widget_show(chat_entry);
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), chat_entry);
+
+ completion = gtk_entry_completion_new();
+ gtk_entry_set_completion(GTK_ENTRY(chat_entry), completion);
+
+ chat_completion_model =
+ gtk_list_store_new(CHAT_COLUMN_LAST, G_TYPE_INT,
+ GDK_TYPE_PIXBUF, G_TYPE_STRING);
+ gtk_entry_completion_set_model(completion,
+ GTK_TREE_MODEL
+ (chat_completion_model));
+ g_object_unref(chat_completion_model);
+
+ /* In GTK 2.4 the text column cannot be set with g_object_set yet.
+ * Set the column, clear the renderers, and add our own. */
+ gtk_entry_completion_set_text_column(completion, CHAT_BEEP_TEXT);
+
+ gtk_cell_layout_clear(GTK_CELL_LAYOUT(completion));
+
+ cell = gtk_cell_renderer_pixbuf_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(completion),
+ cell, FALSE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(completion),
+ cell,
+ "pixbuf", CHAT_PLAYER_ICON, NULL);
+
+ cell = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(completion),
+ cell, TRUE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(completion),
+ cell, "text", CHAT_BEEP_TEXT, NULL);
+
+ gtk_entry_completion_set_minimum_key_length(completion, 2);
+ g_object_unref(completion);
+
+ return hbox;
+}
+
+void chat_set_grab_focus_on_update(gboolean grab)
+{
+ chat_grab_focus_on_update = grab;
+}
+
+void chat_set_focus(void)
+{
+ if (chat_grab_focus_on_update && !gtk_widget_is_focus(chat_entry)) {
+ gtk_widget_grab_focus(chat_entry);
+ gtk_editable_set_position(GTK_EDITABLE(chat_entry), -1);
+ }
+}
+
+void chat_player_name(gint player_num, const gchar * name)
+{
+ GtkTreeIter iter;
+ enum TFindResult found;
+ GdkPixbuf *pixbuf;
+
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(chat_completion_model),
+ &iter, CHAT_PLAYER_NUM, player_num);
+
+ switch (found) {
+ case FIND_NO_MATCH:
+ gtk_list_store_append(chat_completion_model, &iter);
+ break;
+ case FIND_MATCH_INSERT_BEFORE:
+ gtk_list_store_insert_before(chat_completion_model, &iter,
+ &iter);
+ break;
+ case FIND_MATCH_EXACT:
+ break;
+ };
+
+ /* connected icon */
+ pixbuf = player_create_icon(chat_entry, player_num, TRUE);
+ gtk_list_store_set(chat_completion_model, &iter,
+ CHAT_PLAYER_NUM, player_num,
+ CHAT_PLAYER_ICON, pixbuf,
+ CHAT_BEEP_TEXT, g_strdup_printf("/beep %s",
+ name), -1);
+ g_object_unref(pixbuf);
+}
+
+void chat_player_style(gint player_num)
+{
+ GtkTreeIter iter;
+ enum TFindResult found;
+ GdkPixbuf *pixbuf;
+
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(chat_completion_model),
+ &iter, CHAT_PLAYER_NUM, player_num);
+
+ g_return_if_fail(found == FIND_MATCH_EXACT);
+
+ /* connected icon */
+ pixbuf = player_create_icon(chat_entry, player_num, TRUE);
+ gtk_list_store_set(chat_completion_model, &iter,
+ CHAT_PLAYER_ICON, pixbuf, -1);
+ g_object_unref(pixbuf);
+}
+
+void chat_player_quit(gint player_num)
+{
+ GtkTreeIter iter;
+ enum TFindResult found;
+
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(chat_completion_model),
+ &iter, CHAT_PLAYER_NUM, player_num);
+ if (found == FIND_MATCH_EXACT) {
+ /* not connected icon */
+ GdkPixbuf *pixbuf =
+ player_create_icon(chat_entry, player_num, FALSE);
+
+ gtk_list_store_set(chat_completion_model,
+ &iter, CHAT_PLAYER_ICON, pixbuf, -1);
+ g_object_unref(pixbuf);
+ }
+}
+
+void chat_viewer_quit(gint viewer_num)
+{
+ GtkTreeIter iter;
+ enum TFindResult found;
+
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(chat_completion_model),
+ &iter, CHAT_PLAYER_NUM, viewer_num);
+ if (found == FIND_MATCH_EXACT) {
+ gtk_list_store_remove(chat_completion_model, &iter);
+ }
+}
+
+void chat_clear_names(void)
+{
+ gtk_list_store_clear(chat_completion_model);
+}
+
+/** Beep a player (if the name is found)
+ * @param beeping_player The player that sent the /beep
+ * @param name The name of the beeped player
+ */
+static void beep_player(gint beeping_player, const gchar * name)
+{
+ gint beeped_player = find_player_by_name(name);
+ if (beeped_player != -1) {
+ if (beeped_player == my_player_num()) {
+ gdk_beep();
+ frontend_gui_update();
+ if (beeping_player == my_player_num())
+ log_message(MSG_BEEP, _("Beeper test.\n"));
+ else
+ log_message(MSG_BEEP,
+ _("%s beeped you.\n"),
+ player_name(beeping_player,
+ TRUE));
+ } else if (beeping_player == my_player_num()) {
+ log_message(MSG_BEEP, _("You beeped %s.\n"), name);
+ }
+ } else {
+ if (beeping_player == my_player_num()) {
+ /* No success */
+ log_message(MSG_BEEP,
+ _("You could not beep %s.\n"), name);
+ }
+ }
+}
+
+void chat_parser(gint player_num, const gchar * chat)
+{
+ int tempchatcolor = MSG_INFO;
+ gchar *chat_str;
+ gchar *chat_alloc;
+ const gchar *joining_text;
+
+ /* If the chat matches chat from the AI, translate it.
+ * FIXME: There should be a flag to indicate the player is an AI,
+ * so that chat from human players will not be translated
+ */
+ chat_alloc = g_strdup(_(chat));
+ chat_str = chat_alloc;
+
+ if (!strncmp(chat_str, "/beep", 5)) {
+ chat_str += 5;
+ chat_str += strspn(chat_str, " \t");
+ if (chat_str != NULL) {
+ beep_player(player_num, chat_str);
+ }
+ g_free(chat_alloc);
+ return;
+ } else if (!strncmp(chat_str, "/me", 3)) {
+ /* IRC-compatible /me */
+ chat_str += 3;
+ chat_str += strspn(chat_str, " \t") - 1;
+ chat_str[0] = ':';
+ }
+
+ switch (chat_str[0]) {
+ case ':':
+ chat_str += 1;
+ joining_text = " ";
+ break;
+ case ';':
+ chat_str += 1;
+ joining_text = "";
+ break;
+ default:
+ joining_text = _(" said: ");
+ break;
+ }
+
+ if (color_chat_enabled) {
+ if (player_is_viewer(player_num))
+ tempchatcolor = MSG_VIEWER_CHAT;
+ else
+ switch (player_num) {
+ case 0:
+ tempchatcolor = MSG_PLAYER1;
+ break;
+ case 1:
+ tempchatcolor = MSG_PLAYER2;
+ break;
+ case 2:
+ tempchatcolor = MSG_PLAYER3;
+ break;
+ case 3:
+ tempchatcolor = MSG_PLAYER4;
+ break;
+ case 4:
+ tempchatcolor = MSG_PLAYER5;
+ break;
+ case 5:
+ tempchatcolor = MSG_PLAYER6;
+ break;
+ case 6:
+ tempchatcolor = MSG_PLAYER7;
+ break;
+ case 7:
+ tempchatcolor = MSG_PLAYER8;
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+ } else {
+ tempchatcolor = MSG_CHAT;
+ }
+ log_message_chat(player_name(player_num, TRUE), joining_text,
+ tempchatcolor, chat_str);
+ g_free(chat_alloc);
+ return;
+}
Added: trunk/client/gtk/connect.c
===================================================================
--- trunk/client/gtk/connect.c (rev 0)
+++ trunk/client/gtk/connect.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,1546 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003,2006 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "frontend.h"
+#include "network.h"
+#include "log.h"
+#include "config-gnome.h"
+#include "select-game.h"
+#include "game-settings.h"
+#include "game-rules.h"
+
+const int PRIVATE_GAME_HISTORY_SIZE = 10;
+
+static gchar *connect_name; /* Name of the player */
+static gboolean connect_viewer; /* Prefer to be a viewer */
+static gboolean connect_viewer_allowed; /* Viewer allowed */
+static gchar *connect_server; /* Name of the server */
+static gchar *connect_port; /* Port of the server */
+static gchar *connect_style = NULL; /* Style of the player */
+
+static GtkWidget *connect_dlg; /* Dialog for starting a new game */
+static GtkWidget *name_entry; /* Name of the player */
+static GtkWidget *viewer_toggle; /* Prefer to be a viewer */
+static GtkWidget *meta_server_entry; /* Name of the metaserver */
+
+
+static GtkWidget *meta_dlg; /* Dialog for joining a public game */
+static GtkWidget *server_status; /* Description of the current metaserver */
+static GtkListStore *meta_games_model; /* The list of the games at the metaserver */
+static GtkWidget *meta_games_view; /* The view on meta_games_model */
+
+enum {
+ META_RESPONSE_NEW = 1, /* Response for new game */
+ META_RESPONSE_REFRESH = 2 /* Response for refresh of the list */
+};
+
+enum { /* The columns of the meta_games_model */
+ C_META_HOST,
+ C_META_PORT,
+ C_META_VERSION,
+ C_META_MAX,
+ C_META_CUR,
+ C_META_TERRAIN,
+ C_META_VICTORY,
+ C_META_SEVENS,
+ C_META_MAP,
+ META_N_COLUMNS
+};
+
+static Session *ses;
+
+static GtkWidget *cserver_dlg; /* Dialog for creating a public game */
+static GtkWidget *select_game; /* select game type */
+static GtkWidget *game_settings; /* game settings widget */
+static GtkWidget *aiplayers_spin; /* number of AI players */
+static GtkWidget *game_rules; /* Adjust some rules */
+
+static gboolean cfg_terrain; /* Random terrain */
+static guint cfg_num_players, cfg_victory_points, cfg_sevens_rule;
+static guint cfg_ai_players;
+static const gchar *cfg_gametype; /* Will be set be the widget */
+
+static GtkWidget *connect_private_dlg; /* Join a private game */
+static GtkWidget *host_entry; /* Host name entry */
+static GtkWidget *port_entry; /* Host port entry */
+
+static enum {
+ GAMETYPE_MODE_SIGNON,
+ GAMETYPE_MODE_LIST
+} gametype_mode;
+
+static enum {
+ CREATE_MODE_SIGNON,
+ CREATE_MODE_WAIT_FOR_INFO
+} create_mode;
+
+static enum {
+ MODE_SIGNON,
+ MODE_REDIRECT,
+ MODE_LIST,
+ MODE_CAPABILITY
+} meta_mode;
+
+static Session *gametype_ses;
+static Session *create_ses;
+
+/** Information about the metaserver */
+static struct {
+ /** Server name */
+ gchar *server;
+ /** Port */
+ gchar *port;
+ /** Major version number of metaserver protocol */
+ gint version_major;
+ /** Minor version number of metaserver protocol */
+ gint version_minor;
+ /** Number of times the metaserver has redirected */
+ gint num_redirects;
+ /** The metaserver can create remote games */
+ gboolean can_create_games;
+ /** The metaserver can send information about a game */
+ gboolean can_send_game_settings;
+} metaserver_info = {
+NULL, NULL, 0, 0, 0, FALSE, FALSE};
+
+#define STRARG_LEN 128
+#define INTARG_LEN 16
+
+static gchar server_host[STRARG_LEN];
+static gchar server_port[STRARG_LEN];
+static gchar server_version[STRARG_LEN];
+static gchar server_max[INTARG_LEN];
+static gchar server_curr[INTARG_LEN];
+static gchar server_vpoints[STRARG_LEN];
+static gchar *server_sevenrule = NULL;
+static gchar *server_terrain = NULL;
+static gchar server_title[STRARG_LEN];
+
+static void query_meta_server(const gchar * server, const gchar * port);
+static void show_waiting_box(const gchar * message, const gchar * server,
+ const gchar * port);
+static void close_waiting_box(void);
+
+static void connect_set_field(gchar ** field, const gchar * value);
+static void connect_close_all(gboolean user_pressed_ok,
+ gboolean can_be_viewer);
+static void set_meta_serverinfo(void);
+static void connect_private_dialog(G_GNUC_UNUSED GtkWidget * widget,
+ GtkWindow * parent);
+
+static void connect_set_field(gchar ** field, const gchar * value)
+{
+ gchar *temp = g_strdup(value);
+ if (*field)
+ g_free(*field);
+ *field = g_strdup(g_strstrip(temp));
+ g_free(temp);
+}
+
+/* Public functions */
+const gchar *connect_get_name(void)
+{
+ return connect_name;
+}
+
+void connect_set_name(const gchar * name)
+{
+ connect_set_field(&connect_name, name);
+ if (name_entry != NULL)
+ gtk_entry_set_text(GTK_ENTRY(name_entry), connect_name);
+}
+
+gboolean connect_get_viewer(void)
+{
+ return connect_viewer && connect_viewer_allowed;
+}
+
+void connect_set_viewer(gboolean viewer)
+{
+ connect_viewer = viewer;
+ connect_viewer_allowed = TRUE;
+ if (viewer_toggle != NULL)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (viewer_toggle),
+ connect_viewer);
+}
+
+const gchar *connect_get_server(void)
+{
+ return connect_server;
+}
+
+void connect_set_server(const gchar * server)
+{
+ connect_set_field(&connect_server, server);
+}
+
+static const gchar *connect_get_meta_server(void)
+{
+ const gchar *text;
+
+ if (meta_server_entry == NULL)
+ return NULL;
+ text = gtk_entry_get_text(GTK_ENTRY(meta_server_entry));
+ while (*text != '\0' && isspace(*text))
+ text++;
+ return text;
+}
+
+void connect_set_meta_server(const gchar * meta_server)
+{
+ connect_set_field(&metaserver_info.server, meta_server);
+ if (meta_server_entry != NULL)
+ gtk_entry_set_text(GTK_ENTRY(meta_server_entry),
+ metaserver_info.server);
+}
+
+const gchar *connect_get_port(void)
+{
+ return connect_port;
+}
+
+void connect_set_port(const gchar * port)
+{
+ connect_set_field(&connect_port, port);
+}
+
+const gchar *connect_get_style(void)
+{
+ return connect_style;
+}
+
+void connect_set_style(const gchar * style)
+{
+ g_free(connect_style);
+ connect_style = g_strdup(style);
+}
+
+static void connect_close_all(gboolean user_pressed_ok,
+ gboolean can_be_viewer)
+{
+ connect_viewer_allowed = can_be_viewer;
+ if (user_pressed_ok) {
+ connect_set_field(&connect_name,
+ gtk_entry_get_text(GTK_ENTRY
+ (name_entry)));
+ connect_viewer =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
+ (viewer_toggle));
+ /* Save connect dialogue entries */
+ config_set_string("connect/meta-server",
+ connect_get_meta_server());
+ config_set_string("connect/name", connect_name);
+ config_set_int("connect/viewer", connect_viewer);
+
+ frontend_gui_register_destroy(connect_dlg,
+ GUI_CONNECT_TRY);
+ } else {
+ frontend_gui_register_destroy(connect_dlg,
+ GUI_CONNECT_CANCEL);
+ }
+ if (connect_dlg)
+ gtk_widget_destroy(GTK_WIDGET(connect_dlg));
+ if (meta_dlg)
+ gtk_widget_destroy(GTK_WIDGET(meta_dlg));
+ if (cserver_dlg)
+ gtk_widget_destroy(GTK_WIDGET(cserver_dlg));
+ if (connect_private_dlg)
+ gtk_widget_destroy(GTK_WIDGET(connect_private_dlg));
+}
+
+/* Messages explaining some delays */
+static void show_waiting_box(const gchar * message, const gchar * server,
+ const gchar * port)
+{
+ if (meta_dlg) {
+ gchar *s = g_strdup_printf(_("Meta-server at %s, port %s"),
+ server, port);
+ gtk_label_set_text(GTK_LABEL(server_status), s);
+ g_free(s);
+ }
+ log_message(MSG_INFO, message);
+}
+
+static void close_waiting_box(void)
+{
+ log_message(MSG_INFO, _("Finished.\n"));
+}
+
+/* -------------------- get game types -------------------- */
+
+static void meta_gametype_notify(NetEvent event,
+ G_GNUC_UNUSED void *user_data, char *line)
+{
+ switch (event) {
+ case NET_CONNECT:
+ break;
+ case NET_CONNECT_FAIL:
+ net_free(&gametype_ses);
+ break;
+ case NET_CLOSE:
+ if (gametype_mode == GAMETYPE_MODE_SIGNON)
+ log_message(MSG_ERROR,
+ _("Meta-server kicked us off\n"));
+ net_free(&gametype_ses);
+ close_waiting_box();
+ break;
+ case NET_READ:
+ switch (gametype_mode) {
+ case GAMETYPE_MODE_SIGNON:
+ net_printf(gametype_ses, "listtypes\n");
+ gametype_mode = GAMETYPE_MODE_LIST;
+ break;
+ case GAMETYPE_MODE_LIST:
+ /* A server description looks like this:
+ * title=%s\n
+ */
+ if (strncmp(line, "title=", 6) == 0)
+ select_game_add(SELECTGAME(select_game),
+ line + 6);
+ break;
+ }
+ break;
+ }
+}
+
+static void get_meta_server_games_types(gchar * server, gchar * port)
+{
+ show_waiting_box(_("Receiving game names from the meta server.\n"),
+ server, port);
+ gametype_ses = net_new(meta_gametype_notify, NULL);
+ if (net_connect(gametype_ses, server, port))
+ gametype_mode = GAMETYPE_MODE_SIGNON;
+ else {
+ net_free(&gametype_ses);
+ close_waiting_box();
+ }
+}
+
+/* -------------------- create game server -------------------- */
+
+static void meta_create_notify(NetEvent event,
+ G_GNUC_UNUSED void *user_data, char *line)
+{
+ switch (event) {
+ case NET_CONNECT:
+ break;
+ case NET_CONNECT_FAIL:
+ net_free(&create_ses);
+ break;
+ case NET_CLOSE:
+ if (create_mode == CREATE_MODE_SIGNON)
+ log_message(MSG_ERROR,
+ _("Meta-server kicked us off\n"));
+ net_free(&create_ses);
+ break;
+ case NET_READ:
+ switch (create_mode) {
+ case CREATE_MODE_SIGNON:
+ net_printf(create_ses,
+ "create %d %d %d %d %d %s\n",
+ cfg_terrain, cfg_num_players,
+ cfg_victory_points, cfg_sevens_rule,
+ cfg_ai_players, cfg_gametype);
+ create_mode = CREATE_MODE_WAIT_FOR_INFO;
+ break;
+
+ case CREATE_MODE_WAIT_FOR_INFO:
+ if (strncmp(line, "host=", 5) == 0)
+ connect_set_field(&connect_server,
+ line + 5);
+ else if (strncmp(line, "port=", 5) == 0)
+ connect_set_field(&connect_port, line + 5);
+ else if (strcmp(line, "started") == 0) {
+ log_message(MSG_INFO,
+ _
+ ("New game server requested on %s port %s\n"),
+ connect_server, connect_port);
+ /* The meta server is now busy creating the new game.
+ * UGLY FIX: Wait for some time */
+ g_usleep(500000);
+ connect_close_all(TRUE, FALSE);
+ } else
+ log_message(MSG_ERROR,
+ _
+ ("Unknown message from the metaserver: %s\n"),
+ line);
+ break;
+ }
+ }
+}
+
+/* -------------------- get running servers info -------------------- */
+
+static gboolean check_str_info(const gchar * line, const gchar * prefix,
+ gchar * data)
+{
+ gint len = strlen(prefix);
+
+ if (strncmp(line, prefix, len) != 0)
+ return FALSE;
+ strncpy(data, line + len, STRARG_LEN);
+ return TRUE;
+}
+
+static gboolean check_int_info(const gchar * line, const gchar * prefix,
+ gchar * data)
+{
+ gint len = strlen(prefix);
+
+ if (strncmp(line, prefix, len) != 0)
+ return FALSE;
+ sprintf(data, "%d", atoi(line + len));
+ return TRUE;
+}
+
+static void server_end(void)
+{
+ GtkTreeIter iter;
+
+ if (meta_dlg) {
+ gtk_list_store_append(meta_games_model, &iter);
+ gtk_list_store_set(meta_games_model, &iter,
+ C_META_HOST, server_host,
+ C_META_PORT, server_port,
+ C_META_VERSION, server_version,
+ C_META_MAX, server_max,
+ C_META_CUR, server_curr,
+ C_META_TERRAIN, server_terrain,
+ C_META_VICTORY, server_vpoints,
+ C_META_SEVENS, server_sevenrule,
+ C_META_MAP, server_title, -1);
+ }
+}
+
+static void meta_notify(NetEvent event, G_GNUC_UNUSED void *user_data,
+ char *line)
+{
+ gchar argument[STRARG_LEN];
+
+ switch (event) {
+ case NET_CONNECT:
+ break;
+ case NET_CONNECT_FAIL: /* Can't connect to the metaserver, don't show the GUI */
+ if (meta_dlg)
+ gtk_widget_destroy(GTK_WIDGET(meta_dlg)); /* Close the dialog */
+ break;
+ case NET_CLOSE:
+ if (meta_mode == MODE_SIGNON)
+ log_message(MSG_ERROR,
+ _("Meta-server kicked us off\n"));
+ close_waiting_box();
+ net_free(&ses);
+ break;
+ case NET_READ:
+ switch (meta_mode) {
+ case MODE_SIGNON:
+ case MODE_REDIRECT:
+ if (strncmp(line, "goto ", 5) == 0) {
+ gchar **split_result;
+ const gchar *port;
+ meta_mode = MODE_REDIRECT;
+ net_close(ses);
+ if (metaserver_info.num_redirects++ == 10) {
+ log_message(MSG_INFO,
+ _
+ ("Too many meta-server redirects\n"));
+ return;
+ }
+ split_result = g_strsplit(line, " ", 0);
+ g_assert(split_result[0] != NULL);
+ g_assert(!strcmp(split_result[0], "goto"));
+ if (split_result[1]) {
+ if (metaserver_info.server)
+ g_free(metaserver_info.
+ server);
+ metaserver_info.server =
+ g_strdup(split_result[1]);
+ if (metaserver_info.port)
+ g_free(metaserver_info.
+ port);
+ port = PIONEERS_DEFAULT_META_PORT;
+ if (split_result[2])
+ port = split_result[2];
+ metaserver_info.port =
+ g_strdup(port);
+ query_meta_server(metaserver_info.
+ server,
+ metaserver_info.
+ port);
+ } else {
+ log_message(MSG_ERROR,
+ _
+ ("Bad redirect line: %s\n"),
+ line);
+ };
+ g_strfreev(split_result);
+ break;
+ }
+ metaserver_info.version_major =
+ metaserver_info.version_minor = 0;
+ metaserver_info.can_create_games = FALSE;
+ metaserver_info.can_send_game_settings = FALSE;
+ if (strncmp(line, "welcome ", 8) == 0) {
+ char *p = strstr(line, "version ");
+ if (p) {
+ p += 8;
+ metaserver_info.version_major =
+ atoi(p);
+ p += strspn(p, "0123456789");
+ if (*p == '.')
+ metaserver_info.
+ version_minor =
+ atoi(p + 1);
+ }
+ }
+ if (metaserver_info.version_major < 1) {
+ log_message(MSG_INFO,
+ _
+ ("Meta server too old to create "
+ "servers (version %d.%d)\n"),
+ metaserver_info.version_major,
+ metaserver_info.version_minor);
+ } else {
+ net_printf(ses, "version %s\n",
+ META_PROTOCOL_VERSION);
+ }
+
+ if ((metaserver_info.version_major > 1) ||
+ (metaserver_info.version_major == 1
+ && metaserver_info.version_minor >= 1)) {
+ net_printf(ses, "capability\n");
+ meta_mode = MODE_CAPABILITY;
+ } else {
+ net_printf(ses,
+ metaserver_info.version_major >=
+ 1 ? "listservers\n" :
+ "client\n");
+ meta_mode = MODE_LIST;
+ }
+ gtk_dialog_set_response_sensitive(GTK_DIALOG
+ (meta_dlg),
+ META_RESPONSE_REFRESH,
+ TRUE);
+ break;
+ case MODE_CAPABILITY:
+ if (!strcmp(line, "create games")) {
+ metaserver_info.can_create_games = TRUE;
+ } else if (!strcmp(line, "send game settings")) {
+ metaserver_info.can_send_game_settings =
+ TRUE;
+ } else if (!strcmp(line, "end")) {
+ gtk_dialog_set_response_sensitive
+ (GTK_DIALOG(meta_dlg),
+ META_RESPONSE_NEW,
+ metaserver_info.can_create_games);
+ net_printf(ses,
+ metaserver_info.version_major >=
+ 1 ? "listservers\n" :
+ "client\n");
+ meta_mode = MODE_LIST;
+ }
+ break;
+ case MODE_LIST:
+ if (strcmp(line, "server") == 0); /* Information will come shortly */
+ else if (strcmp(line, "end") == 0) {
+ server_end();
+ } else
+ if (check_str_info(line, "host=", server_host))
+ break;
+ else if (check_str_info
+ (line, "port=", server_port))
+ break;
+ else if (check_str_info
+ (line, "version=", server_version))
+ break;
+ else if (check_int_info(line, "max=", server_max))
+ break;
+ else if (check_int_info
+ (line, "curr=", server_curr))
+ break;
+ else if (check_str_info
+ (line, "vpoints=", server_vpoints))
+ break;
+ else if (check_str_info
+ (line, "sevenrule=", argument)) {
+ if (server_sevenrule)
+ g_free(server_sevenrule);
+ if (!strcmp(argument, "normal")) {
+ server_sevenrule =
+ g_strdup(_("Normal"));
+ } else
+ if (!strcmp
+ (argument, "reroll first 2")) {
+ server_sevenrule =
+ g_strdup(_
+ ("Reroll on 1st 2 turns"));
+ } else if (!strcmp(argument, "reroll all")) {
+ server_sevenrule =
+ g_strdup(_("Reroll all 7s"));
+ } else {
+ g_warning("Unknown seven rule: %s",
+ argument);
+ server_sevenrule =
+ g_strdup(argument);
+ }
+ break;
+ } else if (check_str_info
+ (line, "terrain=", argument)) {
+ if (server_terrain)
+ g_free(server_terrain);
+ if (!strcmp(argument, "default"))
+ server_terrain =
+ g_strdup(_("Default"));
+ else if (!strcmp(argument, "random"))
+ server_terrain =
+ g_strdup(_("Random"));
+ else {
+ g_warning
+ ("Unknown terrain type: %s",
+ argument);
+ server_terrain =
+ g_strdup(argument);
+ }
+ break;
+ } else
+ if (check_str_info
+ (line, "title=", server_title))
+ break;
+ /* meta-protocol 0 compat */
+ else if (check_str_info
+ (line, "map=", server_terrain))
+ break;
+ else if (check_str_info
+ (line, "comment=", server_title))
+ break;
+ break;
+ }
+ break;
+ }
+}
+
+static void query_meta_server(const gchar * server, const gchar * port)
+{
+ if (metaserver_info.num_redirects > 0)
+ log_message(MSG_INFO,
+ _
+ ("Redirected to meta-server at %s, port %s\n"),
+ server, port);
+ show_waiting_box(_
+ ("Receiving a list of Pioneers servers from the meta server.\n"),
+ server, port);
+
+ ses = net_new(meta_notify, NULL);
+ if (net_connect(ses, server, port))
+ meta_mode = MODE_SIGNON;
+ else {
+ net_free(&ses);
+ close_waiting_box();
+ }
+}
+
+/* -------------------- create server dialog -------------------- */
+
+static void player_change_cb(GameSettings * gs,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ guint players;
+ guint ai_players;
+ GtkSpinButton *ai_spin;
+
+ ai_spin = GTK_SPIN_BUTTON(aiplayers_spin);
+ players = game_settings_get_players(gs);
+ ai_players = gtk_spin_button_get_value_as_int(ai_spin);
+ gtk_spin_button_set_range(ai_spin, 0, players - 1);
+ if (ai_players >= players)
+ gtk_spin_button_set_value(ai_spin, players - 1);
+}
+
+
+static GtkWidget *build_create_interface(void)
+{
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkObject *adj;
+ guint row;
+ GtkTooltips *tooltips;
+
+ tooltips = gtk_tooltips_new();
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
+
+ select_game = select_game_new();
+ gtk_widget_show(select_game);
+ gtk_box_pack_start(GTK_BOX(vbox), select_game, FALSE, FALSE, 3);
+ /* The meta server does not send information about the game,
+ * so don't adjust the game settings when another game is chosen.
+ g_signal_connect(G_OBJECT(select_game),
+ "activate",
+ G_CALLBACK(game_select_cb), NULL);
+ */
+
+ if (!metaserver_info.can_send_game_settings) {
+ label = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(label),
+ _("<b>Note</b>:\n"
+ "\tThe metaserver does not send information about the games.\n"
+ "\tPlease set appropriate values yourself."));
+ gtk_widget_show(label);
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), label);
+ }
+
+ game_settings = game_settings_new(FALSE);
+ gtk_widget_show(game_settings);
+ gtk_box_pack_start(GTK_BOX(vbox), game_settings, FALSE, FALSE, 3);
+
+ /* Dynamically adjust the maximum number of AI's */
+ g_signal_connect(G_OBJECT(game_settings),
+ "change-players",
+ G_CALLBACK(player_change_cb), NULL);
+
+ row = GTK_TABLE(game_settings)->nrows;
+ label = gtk_label_new(_("Number of AI Players"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(game_settings), label, 0, 1, row,
+ row + 1, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ adj = gtk_adjustment_new(0,
+ 0,
+ game_settings_get_players(GAMESETTINGS
+ (game_settings))
+ - 1, 1, 1, 1);
+ aiplayers_spin = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(aiplayers_spin), TRUE);
+ gtk_widget_show(aiplayers_spin);
+ gtk_entry_set_alignment(GTK_ENTRY(aiplayers_spin), 1.0);
+ gtk_table_attach(GTK_TABLE(game_settings), aiplayers_spin,
+ 1, 2, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip(tooltips, aiplayers_spin,
+ _("The number of AI players"), NULL);
+
+ game_rules = game_rules_new_metaserver();
+ gtk_widget_show(game_rules);
+ gtk_box_pack_start(GTK_BOX(vbox), game_rules, FALSE, FALSE, 3);
+
+ get_meta_server_games_types(metaserver_info.server,
+ metaserver_info.port);
+
+ return vbox;
+}
+
+static void create_server_dlg_cb(GtkDialog * dlg, gint arg1,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ GameSettings *gs = GAMESETTINGS(game_settings);
+ SelectGame *sg = SELECTGAME(select_game);
+ GameRules *gr = GAMERULES(game_rules);
+
+ switch (arg1) {
+ case GTK_RESPONSE_OK:
+ log_message(MSG_INFO, _("Requesting new game server\n"));
+
+ cfg_terrain = game_rules_get_random_terrain(gr);
+ cfg_num_players = game_settings_get_players(gs);
+ cfg_victory_points = game_settings_get_victory_points(gs);
+ cfg_sevens_rule = game_rules_get_sevens_rule(gr);
+ cfg_ai_players =
+ gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON
+ (aiplayers_spin));
+ cfg_gametype = select_game_get_active(sg);
+
+ create_ses = net_new(meta_create_notify, NULL);
+ if (net_connect
+ (create_ses, metaserver_info.server,
+ metaserver_info.port))
+ create_mode = CREATE_MODE_SIGNON;
+ else
+ net_free(&create_ses);
+ break;
+ case GTK_RESPONSE_CANCEL:
+ default: /* For the compiler */
+ gtk_widget_destroy(GTK_WIDGET(dlg));
+ break;
+ };
+}
+
+/** Launch the server gtk. */
+static void launch_server_gtk(G_GNUC_UNUSED GtkWidget * widget,
+ G_GNUC_UNUSED GtkWindow * parent)
+{
+ gchar *child_argv[3];
+ GSpawnFlags flags = G_SPAWN_STDOUT_TO_DEV_NULL |
+ G_SPAWN_STDERR_TO_DEV_NULL;
+ GError *error = NULL;
+ gint i;
+
+ child_argv[0] = g_strdup(PIONEERS_SERVER_GTK_PATH);
+ child_argv[1] = g_strdup(PIONEERS_SERVER_GTK_PATH);
+ child_argv[2] = NULL;
+ if (!g_spawn_async(NULL, child_argv, NULL, flags, NULL, NULL, NULL,
+ &error)) {
+ /* Error message when program %1 is started, reason is %2 */
+ log_message(MSG_ERROR,
+ _("Error starting %s: %s"),
+ PIONEERS_SERVER_GTK_PATH, error->message);
+ g_error_free(error);
+ }
+ for (i = 0; child_argv[i] != NULL; i++)
+ g_free(child_argv[i]);
+}
+
+static void create_server_dlg(G_GNUC_UNUSED GtkWidget * widget,
+ GtkWindow * parent)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *vbox;
+
+ if (cserver_dlg) {
+ gtk_window_present(GTK_WINDOW(cserver_dlg));
+ return;
+ }
+ set_meta_serverinfo();
+
+ cserver_dlg =
+ gtk_dialog_new_with_buttons(_("Create a public game"), parent,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL, GTK_STOCK_OK,
+ GTK_RESPONSE_OK, NULL);
+ g_signal_connect(G_OBJECT(cserver_dlg), "destroy",
+ G_CALLBACK(gtk_widget_destroyed), &cserver_dlg);
+ gtk_widget_realize(cserver_dlg);
+
+ dlg_vbox = GTK_DIALOG(cserver_dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ vbox = build_create_interface();
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, TRUE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+
+ g_signal_connect(G_OBJECT(cserver_dlg), "response",
+ G_CALLBACK(create_server_dlg_cb), NULL);
+ gtk_widget_show(cserver_dlg);
+}
+
+/* -------------------- select server dialog -------------------- */
+
+static gint meta_click_cb(G_GNUC_UNUSED GtkWidget * widget,
+ G_GNUC_UNUSED GdkEventButton * event,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ if (event->type == GDK_2BUTTON_PRESS) {
+ gtk_dialog_response(GTK_DIALOG(meta_dlg), GTK_RESPONSE_OK);
+ };
+ return FALSE;
+}
+
+static void meta_select_cb(G_GNUC_UNUSED GtkTreeSelection * selection,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(meta_dlg),
+ GTK_RESPONSE_OK, TRUE);
+}
+
+static void meta_dlg_cb(GtkDialog * dlg, gint arg1,
+ G_GNUC_UNUSED gpointer userdata)
+{
+ GtkTreePath *path;
+ GtkTreeViewColumn *column;
+ GtkTreeIter iter;
+ gchar *host;
+ gchar *port;
+
+ switch (arg1) {
+ case META_RESPONSE_REFRESH: /* Refresh the list */
+ gtk_list_store_clear(meta_games_model);
+ metaserver_info.num_redirects = 0;
+ query_meta_server(metaserver_info.server,
+ metaserver_info.port);
+ break;
+ case META_RESPONSE_NEW: /* Add a server */
+ create_server_dlg(NULL, GTK_WINDOW(dlg));
+ break;
+ case GTK_RESPONSE_OK: /* Select this server */
+ gtk_tree_view_get_cursor(GTK_TREE_VIEW(meta_games_view),
+ &path, &column);
+ if (path != NULL) {
+ gtk_tree_model_get_iter(GTK_TREE_MODEL
+ (meta_games_model), &iter,
+ path);
+ gtk_tree_model_get(GTK_TREE_MODEL
+ (meta_games_model), &iter,
+ C_META_HOST, &host, C_META_PORT,
+ &port, -1);
+ connect_set_field(&connect_server, host);
+ connect_set_field(&connect_port, port);
+ g_free(host);
+ g_free(port);
+ gtk_tree_path_free(path);
+ connect_close_all(TRUE, TRUE);
+ }
+ break;
+ case GTK_RESPONSE_CANCEL: /* Cancel */
+ default:
+ gtk_widget_destroy(GTK_WIDGET(dlg));
+ break;
+ }
+}
+
+static void set_meta_serverinfo(void)
+{
+ gchar *meta_tmp;
+
+ meta_tmp =
+ g_strdup(gtk_entry_get_text(GTK_ENTRY(meta_server_entry)));
+ if (meta_tmp[0] == '\0') {
+ g_free(meta_tmp);
+ meta_tmp = get_meta_server_name(TRUE);
+ gtk_entry_set_text(GTK_ENTRY(meta_server_entry), meta_tmp);
+ }
+ metaserver_info.server = meta_tmp; /* Take-over of the pointer */
+ if (!metaserver_info.port)
+ metaserver_info.port =
+ g_strdup(PIONEERS_DEFAULT_META_PORT);
+}
+
+static void create_meta_dlg(G_GNUC_UNUSED GtkWidget * widget,
+ GtkWidget * parent)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *vbox;
+ GtkWidget *scroll_win;
+ GtkTooltips *tooltips;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+
+ set_meta_serverinfo();
+
+ if (meta_dlg != NULL) {
+ if (ses == NULL) {
+ metaserver_info.num_redirects = 0;
+ query_meta_server(metaserver_info.server,
+ metaserver_info.port);
+ }
+ return;
+ }
+
+ if (meta_dlg) {
+ gtk_window_present(GTK_WINDOW(meta_dlg));
+ return;
+ }
+
+ tooltips = gtk_tooltips_new();
+
+ meta_dlg = gtk_dialog_new_with_buttons(_("Join a public game"),
+ GTK_WINDOW(parent),
+ 0,
+ GTK_STOCK_REFRESH,
+ META_RESPONSE_REFRESH,
+ _("_New remote game"),
+ META_RESPONSE_NEW,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK, NULL);
+ g_signal_connect(G_OBJECT(meta_dlg), "destroy",
+ G_CALLBACK(gtk_widget_destroyed), &meta_dlg);
+ g_signal_connect(G_OBJECT(meta_dlg), "response",
+ G_CALLBACK(meta_dlg_cb), NULL);
+ gtk_widget_realize(meta_dlg);
+ gtk_tooltips_set_tip(tooltips,
+ gui_get_dialog_button(GTK_DIALOG(meta_dlg),
+ 0),
+ _("Refresh the list of games"), NULL);
+ gtk_tooltips_set_tip(tooltips,
+ gui_get_dialog_button(GTK_DIALOG(meta_dlg),
+ 1),
+ _
+ ("Create a new public game at the meta server"),
+ NULL);
+ gtk_tooltips_set_tip(tooltips,
+ gui_get_dialog_button(GTK_DIALOG(meta_dlg),
+ 2),
+ _("Don't join a public game"), NULL);
+ gtk_tooltips_set_tip(tooltips,
+ gui_get_dialog_button(GTK_DIALOG(meta_dlg),
+ 3),
+ _("Join the selected game"), NULL);
+
+ dlg_vbox = GTK_DIALOG(meta_dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ vbox = gtk_vbox_new(FALSE, 2);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, TRUE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+
+ server_status = gtk_label_new("");
+ gtk_widget_show(server_status);
+ gtk_box_pack_start(GTK_BOX(vbox), server_status, FALSE, TRUE, 0);
+
+ scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
+ (scroll_win), GTK_SHADOW_IN);
+ gtk_widget_show(scroll_win);
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), scroll_win);
+
+ meta_games_model = gtk_list_store_new(META_N_COLUMNS,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING);
+
+ meta_games_view =
+ gtk_tree_view_new_with_model(GTK_TREE_MODEL(meta_games_model));
+ gtk_widget_show(meta_games_view);
+ gtk_container_add(GTK_CONTAINER(scroll_win), meta_games_view);
+ gtk_tooltips_set_tip(tooltips, meta_games_view,
+ _("Select a game to join"), NULL);
+
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Map Name"),
+ gtk_cell_renderer_text_new
+ (), "text",
+ C_META_MAP, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(meta_games_view),
+ column);
+ gtk_tree_view_column_set_sort_column_id(column, C_META_MAP);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Name of the game"), NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "xalign", 1.0f, NULL);
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Curr"), renderer,
+ "text", C_META_CUR,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(meta_games_view),
+ column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Number of players in the game"), NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "xalign", 1.0f, NULL);
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Max"), renderer,
+ "text", C_META_MAX,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(meta_games_view),
+ column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Maximum players for the game"), NULL);
+
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Terrain"),
+ gtk_cell_renderer_text_new
+ (), "text",
+ C_META_TERRAIN, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(meta_games_view),
+ column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Random of default terrain"), NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "xalign", 1.0f, NULL);
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Vic. Points"),
+ renderer, "text",
+ C_META_VICTORY, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(meta_games_view),
+ column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Points needed to win"), NULL);
+
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Sevens Rule"),
+ gtk_cell_renderer_text_new
+ (), "text",
+ C_META_SEVENS, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(meta_games_view),
+ column);
+ gtk_tooltips_set_tip(tooltips, column->button, _("Sevens rule"),
+ NULL);
+
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Host"),
+ gtk_cell_renderer_text_new
+ (), "text",
+ C_META_HOST, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(meta_games_view),
+ column);
+ gtk_tree_view_column_set_sort_column_id(column, C_META_HOST);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Host of the game"), NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ g_object_set(renderer, "xalign", 1.0f, NULL);
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Port"), renderer,
+ "text", C_META_PORT,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(meta_games_view),
+ column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Port of the the game"), NULL);
+
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Version"),
+ gtk_cell_renderer_text_new
+ (), "text",
+ C_META_VERSION, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(meta_games_view),
+ column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Version of the host"), NULL);
+
+ /* Register double-click */
+ g_signal_connect(G_OBJECT(meta_games_view), "button_press_event",
+ G_CALLBACK(meta_click_cb), NULL);
+
+ g_signal_connect(G_OBJECT
+ (gtk_tree_view_get_selection
+ (GTK_TREE_VIEW(meta_games_view))), "changed",
+ G_CALLBACK(meta_select_cb), NULL);
+
+ /* This button will be enabled when a game is selected */
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(meta_dlg),
+ GTK_RESPONSE_OK, FALSE);
+
+ /* These buttons will be enabled when the metaserver has responded */
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(meta_dlg),
+ META_RESPONSE_NEW, FALSE);
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(meta_dlg),
+ META_RESPONSE_REFRESH, FALSE);
+
+ gtk_widget_show(meta_dlg);
+
+ metaserver_info.num_redirects = 0;
+ query_meta_server(metaserver_info.server, metaserver_info.port);
+
+ /* Workaround: Set the size of the widget as late as possible, to avoid a strange display */
+ gtk_widget_set_size_request(scroll_win, -1, 150);
+}
+
+static void connect_dlg_cb(G_GNUC_UNUSED GtkDialog * dlg,
+ G_GNUC_UNUSED gint arg1,
+ G_GNUC_UNUSED gpointer userdata)
+{
+ connect_close_all(FALSE, FALSE);
+}
+
+void connect_create_dlg(void)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *table;
+ GtkWidget *lbl;
+ GtkWidget *hbox;
+ GtkWidget *btn;
+ GtkWidget *sep;
+ GtkTooltips *tooltips;
+ gchar *fullname;
+
+ if (connect_dlg) {
+ gtk_window_present(GTK_WINDOW(connect_dlg));
+ return;
+ }
+
+ tooltips = gtk_tooltips_new();
+
+ connect_dlg = gtk_dialog_new_with_buttons(_("Start a new game"),
+ GTK_WINDOW(app_window),
+ 0,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ NULL);
+ g_signal_connect(G_OBJECT(connect_dlg), "response",
+ G_CALLBACK(connect_dlg_cb), NULL);
+ g_signal_connect(G_OBJECT(connect_dlg), "destroy",
+ G_CALLBACK(gtk_widget_destroyed), &connect_dlg);
+
+ gtk_widget_realize(connect_dlg);
+ gdk_window_set_functions(connect_dlg->window,
+ GDK_FUNC_MOVE | GDK_FUNC_CLOSE);
+
+ dlg_vbox = GTK_DIALOG(connect_dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ table = gtk_table_new(4, 3, FALSE);
+ gtk_widget_show(table);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), table, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 5);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 5);
+
+ lbl = gtk_label_new(_("Player Name"));
+ gtk_widget_show(lbl);
+ gtk_table_attach(GTK_TABLE(table), lbl, 0, 1, 0, 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(lbl), 0, 0.5);
+
+ name_entry = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(name_entry), MAX_NAME_LENGTH);
+ gtk_widget_show(name_entry);
+ gtk_entry_set_text(GTK_ENTRY(name_entry), connect_name);
+
+ gtk_table_attach(GTK_TABLE(table), name_entry, 1, 2, 0, 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip(tooltips, name_entry,
+ _("Enter your name"), NULL);
+
+ viewer_toggle = gtk_check_button_new_with_label(_("Viewer"));
+ gtk_widget_show(viewer_toggle);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(viewer_toggle),
+ connect_viewer);
+
+ gtk_table_attach(GTK_TABLE(table), viewer_toggle, 2, 3, 0, 1, 0,
+ GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip(tooltips, viewer_toggle,
+ _("Do you want to be a viewer?"), NULL);
+
+ sep = gtk_hseparator_new();
+ gtk_widget_show(sep);
+ gtk_table_attach(GTK_TABLE(table), sep, 0, 3, 1, 2,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 6);
+
+ lbl = gtk_label_new(_("Meta Server"));
+ gtk_widget_show(lbl);
+ gtk_table_attach(GTK_TABLE(table), lbl, 0, 1, 2, 3,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(lbl), 0, 0.5);
+
+ meta_server_entry = gtk_entry_new();
+ gtk_widget_show(meta_server_entry);
+ gtk_table_attach(GTK_TABLE(table), meta_server_entry, 1, 3, 2, 3,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_entry_set_text(GTK_ENTRY(meta_server_entry),
+ metaserver_info.server);
+ gtk_tooltips_set_tip(tooltips, meta_server_entry,
+ _("Leave empty for the default meta server"),
+ NULL);
+
+ hbox = gtk_hbox_new(FALSE, 3);
+ gtk_widget_show(hbox);
+ gtk_table_attach(GTK_TABLE(table), hbox, 0, 3, 3, 4,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 3);
+
+ btn = gtk_button_new_with_label(_("Join public game"));
+ gtk_widget_show(btn);
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), btn);
+ g_signal_connect(G_OBJECT(btn), "clicked",
+ G_CALLBACK(create_meta_dlg), app_window);
+ gtk_tooltips_set_tip(tooltips, btn, _("Join a public game"), NULL);
+ GTK_WIDGET_SET_FLAGS(btn, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(btn);
+
+ btn = gtk_button_new_with_label(_("Create game"));
+ gtk_widget_show(btn);
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), btn);
+ gtk_tooltips_set_tip(tooltips, btn, _("Create a game"), NULL);
+ g_signal_connect(G_OBJECT(btn), "clicked",
+ G_CALLBACK(launch_server_gtk), app_window);
+ fullname = g_find_program_in_path(PIONEERS_SERVER_GTK_PATH);
+ if (fullname) {
+ g_free(fullname);
+ } else {
+ gtk_widget_set_sensitive(GTK_WIDGET(btn), FALSE);
+ }
+
+ btn = gtk_button_new_with_label(_("Join private game"));
+ gtk_widget_show(btn);
+ gtk_box_pack_start_defaults(GTK_BOX(hbox), btn);
+ gtk_tooltips_set_tip(tooltips, btn,
+ _("Join a private game"), NULL);
+ g_signal_connect(G_OBJECT(btn), "clicked",
+ G_CALLBACK(connect_private_dialog), app_window);
+
+ gtk_entry_set_activates_default(GTK_ENTRY(name_entry), TRUE);
+
+ gtk_widget_show(connect_dlg);
+
+ gtk_widget_grab_focus(name_entry);
+}
+
+/* ------------ Join a private game dialog ------------------- */
+
+static void update_recent_servers_list(void)
+{
+ gchar keyname1[50], keyname2[50];
+ gchar *temp_name, *temp_port;
+ gchar *cur_name, *cur_port;
+ gchar *conn_name, *conn_port;
+ gboolean default_used;
+ gboolean done;
+ gint i;
+
+ done = FALSE;
+ i = 0;
+
+ conn_name = g_strdup(connect_get_server());
+ conn_port = g_strdup(connect_get_port());
+
+ temp_name = g_strdup(conn_name);
+ temp_port = g_strdup(conn_port);
+
+ do {
+ sprintf(keyname1, "favorites/server%dname=", i);
+ sprintf(keyname2, "favorites/server%dport=", i);
+ cur_name =
+ g_strdup(config_get_string(keyname1, &default_used));
+ cur_port =
+ g_strdup(config_get_string(keyname2, &default_used));
+
+ if (temp_name) {
+ sprintf(keyname1, "favorites/server%dname", i);
+ sprintf(keyname2, "favorites/server%dport", i);
+ config_set_string(keyname1, temp_name);
+ config_set_string(keyname2, temp_port);
+ } else {
+ break;
+ }
+
+ if (strlen(cur_name) == 0) {
+ break;
+ }
+
+ if (!strcmp(cur_name, conn_name)
+ && !strcmp(cur_port, conn_port)) {
+ temp_name = NULL;
+ temp_port = NULL;
+ } else {
+ g_free(temp_name);
+ g_free(temp_port);
+ temp_name = g_strdup(cur_name);
+ temp_port = g_strdup(cur_port);
+ }
+
+ i++;
+ if (i > PRIVATE_GAME_HISTORY_SIZE) {
+ done = TRUE;
+ }
+ g_free(cur_name);
+ g_free(cur_port);
+ } while (!done);
+ g_free(cur_name);
+ g_free(cur_port);
+ g_free(temp_name);
+ g_free(temp_port);
+ g_free(conn_name);
+ g_free(conn_port);
+}
+
+static void host_list_select_cb(GtkWidget * widget, gpointer user_data)
+{
+ GPtrArray *host_entries = user_data;
+ gint index;
+ gchar *entry;
+ gchar **strs;
+
+ index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+ entry = g_ptr_array_index(host_entries, index);
+ strs = g_strsplit(entry, ":", 2);
+
+ connect_set_field(&connect_server, strs[0]);
+ connect_set_field(&connect_port, strs[1]);
+ gtk_entry_set_text(GTK_ENTRY(host_entry), connect_server);
+ gtk_entry_set_text(GTK_ENTRY(port_entry), connect_port);
+ g_strfreev(strs);
+}
+
+
+static void connect_private_dlg_cb(GtkDialog * dlg, gint arg1,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ switch (arg1) {
+ case GTK_RESPONSE_OK:
+ connect_set_field(&connect_server,
+ gtk_entry_get_text(GTK_ENTRY
+ (host_entry)));
+ connect_set_field(&connect_port,
+ gtk_entry_get_text(GTK_ENTRY
+ (port_entry)));
+ update_recent_servers_list();
+ config_set_string("connect/server", connect_server);
+ config_set_string("connect/port", connect_port);
+ connect_close_all(TRUE, TRUE);
+ break;
+ case GTK_RESPONSE_CANCEL:
+ default: /* For the compiler */
+ gtk_widget_destroy(GTK_WIDGET(dlg));
+ break;
+ };
+}
+
+static void connect_private_dialog(G_GNUC_UNUSED GtkWidget * widget,
+ GtkWindow * parent)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *table;
+ GtkWidget *lbl;
+ GtkWidget *hbox;
+ GtkTooltips *tooltips;
+
+ GtkWidget *host_list;
+ GPtrArray *host_entries;
+
+ gint i;
+ gchar *host_name, *host_port, *host_name_port, temp_str[50];
+ gboolean default_returned;
+
+ if (connect_private_dlg) {
+ gtk_window_present(GTK_WINDOW(connect_private_dlg));
+ return;
+ }
+
+ tooltips = gtk_tooltips_new();
+
+ connect_private_dlg =
+ gtk_dialog_new_with_buttons(_("Join a private game"),
+ GTK_WINDOW(parent), 0,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL, GTK_STOCK_OK,
+ GTK_RESPONSE_OK, NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(connect_private_dlg),
+ GTK_RESPONSE_OK);
+ g_signal_connect(G_OBJECT(connect_private_dlg), "response",
+ G_CALLBACK(connect_private_dlg_cb), NULL);
+ g_signal_connect(G_OBJECT(connect_private_dlg), "destroy",
+ G_CALLBACK(gtk_widget_destroyed),
+ &connect_private_dlg);
+
+
+ gtk_widget_realize(connect_private_dlg);
+ gdk_window_set_functions(connect_private_dlg->window,
+ GDK_FUNC_MOVE | GDK_FUNC_CLOSE);
+
+ dlg_vbox = GTK_DIALOG(connect_private_dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ table = gtk_table_new(3, 2, FALSE);
+ gtk_widget_show(table);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), table, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 5);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 5);
+
+ lbl = gtk_label_new(_("Server Host"));
+ gtk_widget_show(lbl);
+ gtk_table_attach(GTK_TABLE(table), lbl, 0, 1, 0, 1,
+ GTK_FILL, GTK_EXPAND, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(lbl), 0, 0.5);
+
+ host_entry = gtk_entry_new();
+ gtk_widget_show(host_entry);
+ gtk_table_attach(GTK_TABLE(table), host_entry, 1, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL,
+ GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_entry_set_text(GTK_ENTRY(host_entry), connect_server);
+ gtk_tooltips_set_tip(tooltips, host_entry,
+ _("Name of the host of the game"), NULL);
+ connect_set_field(&connect_server, connect_server);
+
+ lbl = gtk_label_new(_("Server Port"));
+ gtk_widget_show(lbl);
+ gtk_table_attach(GTK_TABLE(table), lbl, 0, 1, 1, 2,
+ GTK_FILL, GTK_EXPAND, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(lbl), 0, 0.5);
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(hbox);
+ gtk_table_attach(GTK_TABLE(table), hbox, 1, 2, 1, 2,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+ port_entry = gtk_entry_new();
+ gtk_widget_show(port_entry);
+ gtk_box_pack_start(GTK_BOX(hbox), port_entry, FALSE, TRUE, 0);
+ gtk_entry_set_text(GTK_ENTRY(port_entry), connect_port);
+ gtk_tooltips_set_tip(tooltips, port_entry,
+ _("Port of the host of the game"), NULL);
+ connect_set_field(&connect_port, connect_port);
+
+ host_list = gtk_combo_box_new_text();
+ host_entries = g_ptr_array_new();
+
+ gtk_widget_show(host_list);
+
+ for (i = 0; i < PRIVATE_GAME_HISTORY_SIZE; i++) {
+ sprintf(temp_str, "favorites/server%dname=", i);
+ host_name = config_get_string(temp_str, &default_returned);
+ if (default_returned || !strlen(host_name)) {
+ g_free(host_name);
+ break;
+ }
+
+ sprintf(temp_str, "favorites/server%dport=", i);
+ host_port = config_get_string(temp_str, &default_returned);
+ if (default_returned || !strlen(host_port)) {
+ g_free(host_name);
+ g_free(host_port);
+ break;
+ }
+
+ host_name_port =
+ g_strconcat(host_name, ":", host_port, NULL);
+ g_free(host_name);
+ g_free(host_port);
+
+ g_ptr_array_add(host_entries, host_name_port);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(host_list),
+ host_name_port);
+ }
+ if (i > 0)
+ gtk_combo_box_set_active(GTK_COMBO_BOX(host_list), 0);
+ g_signal_connect(G_OBJECT(host_list), "changed",
+ G_CALLBACK(host_list_select_cb), host_entries);
+
+ gtk_table_attach(GTK_TABLE(table), host_list, 1, 2, 2, 3,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip(tooltips, host_list, _("Recent games"), NULL);
+
+ lbl = gtk_label_new(_("Recent Games"));
+ gtk_widget_show(lbl);
+ gtk_table_attach(GTK_TABLE(table), lbl, 0, 1, 2, 3,
+ GTK_FILL, GTK_EXPAND, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(lbl), 0, 0.5);
+
+ gtk_entry_set_activates_default(GTK_ENTRY(host_entry), TRUE);
+ gtk_entry_set_activates_default(GTK_ENTRY(port_entry), TRUE);
+
+ gtk_widget_show(connect_private_dlg);
+}
Added: trunk/client/gtk/data/Makefile.am
===================================================================
--- trunk/client/gtk/data/Makefile.am (rev 0)
+++ trunk/client/gtk/data/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,69 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+# Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+include client/gtk/data/themes/Makefile.am
+
+icon_DATA += client/gtk/data/pioneers.png
+
+pixmap_DATA += \
+ client/gtk/data/bridge.png \
+ client/gtk/data/city.png \
+ client/gtk/data/city_wall.png \
+ client/gtk/data/develop.png \
+ client/gtk/data/dice.png \
+ client/gtk/data/finish.png \
+ client/gtk/data/road.png \
+ client/gtk/data/settlement.png \
+ client/gtk/data/ship.png \
+ client/gtk/data/ship_move.png \
+ client/gtk/data/splash.png \
+ client/gtk/data/trade.png \
+ client/gtk/data/brick.png \
+ client/gtk/data/grain.png \
+ client/gtk/data/lumber.png \
+ client/gtk/data/ore.png \
+ client/gtk/data/wool.png \
+ client/gtk/data/style-human.png \
+ client/gtk/data/style-human-1.png \
+ client/gtk/data/style-human-2.png \
+ client/gtk/data/style-human-3.png \
+ client/gtk/data/style-human-4.png \
+ client/gtk/data/style-human-5.png \
+ client/gtk/data/style-human-6.png \
+ client/gtk/data/style-human-7.png \
+ client/gtk/data/style-ai.png
+
+desktop_DATA += client/gtk/data/pioneers.desktop
+
+EXTRA_DIST += client/gtk/data/splash.svg
+MAINTAINERCLEANFILES += client/gtk/data/splash.png
+
+client/gtk/data/splash.png: client/gtk/data/splash.svg
+ @mkdir_p@ $(dir $@)
+ $(svg_renderer_path) $(svg_renderer_width)400$(svg_renderer_height)400 $< $@
+
+if USE_WINDOWS_ICON
+pioneers_LDADD += client/gtk/data/pioneers.res
+CLEANFILES += client/gtk/data/pioneers.res
+endif
+
+windows_resources_output += client/gtk/data/pioneers.ico
+windows_resources_input += client/gtk/data/pioneers.rc
Added: trunk/client/gtk/data/brick.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/brick.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/bridge.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/bridge.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/city.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/city.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/city_wall.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/city_wall.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/develop.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/develop.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/dice.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/dice.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/finish.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/finish.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/grain.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/grain.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/lumber.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/lumber.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/ore.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/ore.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/pioneers.desktop
===================================================================
--- trunk/client/gtk/data/pioneers.desktop (rev 0)
+++ trunk/client/gtk/data/pioneers.desktop 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Version=1.0
+Encoding=UTF-8
+Name=Pioneers
+Comment=Play a game of Pioneers
+Exec=pioneers
+Icon=pioneers.png
+Terminal=false
+Type=Application
+Categories=Game;BoardGame;StrategyGame;GNOME;GTK;
Added: trunk/client/gtk/data/pioneers.rc
===================================================================
--- trunk/client/gtk/data/pioneers.rc (rev 0)
+++ trunk/client/gtk/data/pioneers.rc 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1 @@
+1 ICON DISCARDABLE "client/gtk/data/pioneers.ico"
Added: trunk/client/gtk/data/pioneers.svg
===================================================================
--- trunk/client/gtk/data/pioneers.svg (rev 0)
+++ trunk/client/gtk/data/pioneers.svg 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ x="0"
+ y="0"
+ width="354.330688"
+ height="354.330688"
+ id="svg620"
+ xml:space="preserve"><defs
+ id="defs622" /><g
+ transform="matrix(1.38939,0,0,1.38939,-162.8163,-618.7101)"
+ style="font-size:12;"
+ id="g638"><path
+ d="M 184.1155 485.4331 L 245.4874 450 L 306.8593 485.4331 L 306.8593 556.2992 L 245.4874 591.7323 L 184.1155 556.2992 L 184.1155 485.4331 z "
+ style="fill:#800000;fill-rule:evenodd;stroke:#000000;stroke-width:3.5433;"
+ id="path616" /><path
+ d="M 306.8593 556.2992 L 368.2311 591.7323 L 368.2311 662.5984 L 306.8593 698.0315 L 245.4874 662.5984 L 245.4874 591.7323 L 306.8593 556.2992 z "
+ style="fill:#008000;fill-rule:evenodd;stroke:#000000;stroke-width:3.5433;"
+ id="path617" /><path
+ d="M 184.1155 556.2939 L 122.7437 591.7283 L 122.7437 662.597 L 184.1155 698.0314 L 245.4874 662.597 L 245.4874 591.7283 L 184.1155 556.2939 z "
+ style="fill:#c37f41;fill-rule:evenodd;stroke:#000000;stroke-width:3.543365;"
+ id="path618" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,81.85915,-132.835)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path624" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,-40.88452,-132.835)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path625" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,21.57656,-239.1342)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path626" /><text
+ x="95.3142548"
+ y="212.637573"
+ transform="translate(141.3132,320.9463)"
+ style="font-size:36;font-weight:normal;fill:#ff0000;stroke-width:1;font-family:FreeSans;"
+ id="text627"><tspan
+ id="tspan628">8</tspan></text><text
+ x="70.7458191"
+ y="254.86348"
+ transform="translate(104.0006,385.1866)"
+ style="font-size:36;font-weight:normal;stroke-width:1;font-family:FreeSans;"
+ id="text630"><tspan
+ id="tspan631">4</tspan></text><text
+ x="88.1663055"
+ y="224.654419"
+ transform="translate(208.7261,415.2287)"
+ style="font-size:36;font-weight:normal;stroke-width:1;font-family:FreeSans;"
+ id="text633"><tspan
+ id="tspan634">9</tspan></text></g></svg>
Added: trunk/client/gtk/data/road.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/road.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/settlement.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/settlement.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/ship.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/ship.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/ship_move.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/ship_move.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/splash.svg
===================================================================
--- trunk/client/gtk/data/splash.svg (rev 0)
+++ trunk/client/gtk/data/splash.svg 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,1350 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ id="svg559"
+ sodipodi:version="0.34"
+ width="210mm"
+ height="210mm"
+ inkscape:version="0.37"
+ sodipodi:docname="splash.svg">
+ <defs
+ id="defs561">
+ <linearGradient
+ id="linearGradient636">
+ <stop
+ style="stop-color:#b51e00;stop-opacity:1;"
+ offset="0.00000000"
+ id="stop637" />
+ <stop
+ style="stop-color:#b51e00;stop-opacity:0;"
+ offset="1.00000000"
+ id="stop638" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient569">
+ <stop
+ style="stop-color:#deaa00;stop-opacity:1.0000;"
+ offset="0"
+ id="stop570" />
+ <stop
+ style="stop-color:#deaa00;stop-opacity:0;"
+ offset="1"
+ id="stop571" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient563">
+ <stop
+ style="stop-color:#940000;stop-opacity:1.0000;"
+ offset="0"
+ id="stop564" />
+ <stop
+ style="stop-color:#ff6d00;stop-opacity:1.0000;"
+ offset="1"
+ id="stop565" />
+ </linearGradient>
+ <linearGradient
+ xlink:href="#linearGradient563"
+ id="linearGradient566"
+ x1="0.488372"
+ y1="7.812500e-3"
+ x2="0.496124"
+ y2="0.968750" />
+ <linearGradient
+ xlink:href="#linearGradient569"
+ id="linearGradient568"
+ x1="0.496126"
+ y1="2.343799e-2"
+ x2="0.480620"
+ y2="0.851563" />
+ <radialGradient
+ xlink:href="#linearGradient636"
+ id="radialGradient635"
+ cx="0.50000000"
+ cy="0.50000000"
+ r="0.50000000"
+ fx="0.50000000"
+ fy="0.50000000" />
+ <radialGradient
+ xlink:href="#linearGradient636"
+ id="radialGradient1010" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ snaptoguides="true"
+ inkscape:zoom="1"
+ inkscape:cx="302.563385"
+ inkscape:cy="344.156921"
+ inkscape:window-width="786"
+ inkscape:window-height="1012"
+ inkscape:window-x="386"
+ inkscape:window-y="77" />
+ <rect
+ style="font-size:12.000;fill:url(#linearGradient566);fill-rule:evenodd;stroke-width:1;fill-opacity:1.0000;"
+ id="rect562"
+ width="744.0946"
+ height="744.0945"
+ x="-3.814697e-6"
+ y="-3.051758e-5" />
+ <path
+ sodipodi:type="arc"
+ style="fill-rule:evenodd;stroke:none;fill:url(#linearGradient568);fill-opacity:1;stroke-opacity:1;stroke-width:1pt;stroke-linejoin:miter;stroke-linecap:butt;"
+ id="path567"
+ d="M 608.5885 385.1224 A 244.8618 244.8618 0 1 0 118.8649 385.1224 A 244.8618 244.8618 0 1 0 608.5885 385.1224 z"
+ sodipodi:cx="363.7267"
+ sodipodi:cy="385.1224"
+ sodipodi:rx="244.8618"
+ sodipodi:ry="244.8618"
+ transform="translate(8.320580,-13.07516)" />
+ <text
+ style="fill:black;stroke:none;font-family:Bitstream Charter;font-style:normal;font-weight:bold;font-size:120.0000;fill-opacity:1;stroke-opacity:1;stroke-width:1pt;stroke-linejoin:miter;stroke-linecap:butt;text-anchor:start;writing-mode:lr;"
+ x="160.382759"
+ y="179.277161"
+ id="text573"
+ sodipodi:linespacing="100%">
+ <tspan
+ x="160.382751"
+ y="179.277161"
+ sodipodi:role="line"
+ id="tspan580">IONEER</tspan>
+ </text>
+ <text
+ style="font-size:120;font-weight:bold;fill:#ffd200;stroke-width:1;font-family:Bitstream Charter;"
+ x="157.662651"
+ y="173.815201"
+ id="text609"
+ sodipodi:linespacing="100%">
+ <tspan
+ x="157.662643"
+ y="173.815201"
+ sodipodi:role="line"
+ id="tspan610"
+ style="fill:#ffd200;fill-opacity:1;">IONEER</tspan>
+ </text>
+ <text
+ xml:space="preserve"
+ style="fill:#000000;stroke:none;font-family:Bitstream Charter;font-style:normal;font-weight:bold;font-size:56;fill-opacity:1;stroke-opacity:1;stroke-width:3pt;stroke-linejoin:miter;stroke-linecap:butt;text-anchor:start;writing-mode:lr;opacity:1;"
+ x="213.289298"
+ y="258.424174"
+ id="text604"
+ sodipodi:linespacing="100%"
+ transform="scale(1,0.851389)"><tspan
+ x="213.289291"
+ y="258.424164"
+ sodipodi:role="line"
+ id="tspan614">Version 0.11</tspan></text>
+ <path
+ style="fill-rule:evenodd;stroke:none;fill:#000000;fill-opacity:1.0000;stroke-opacity:1;stroke-width:1pt;stroke-linejoin:miter;stroke-linecap:butt;"
+ d="M 367.28125 610.57269 C 219.21977 610.57269 86.995276 634.23885 0 671.24218 L 0 744.09375 L 744.09375 744.09375 L 744.09375 675.44052 C 657.40008 636.04073 520.85728 610.57267 367.28125 610.57269 z "
+ id="path633" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path634"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="translate(-41.24667,45.48047)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path639"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="translate(-8.589744,11.86539)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path640"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="translate(292.8346,146.2979)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path641"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="translate(365.9767,-73.12829)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path642"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="translate(338.3013,-61.26741)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path643"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="translate(395.6289,-51.38335)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path644"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="matrix(0.893334,0.000000,0.000000,1.000000,476.2317,3.967402)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path645"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="matrix(0.477338,0.000000,0.000000,1.000000,602.1924,16.81668)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path646"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="matrix(0.914667,0.000000,0.000000,1.000000,466.8323,36.58481)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path647"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="translate(438.1304,46.46887)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path648"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="translate(432.1999,55.36453)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path649"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="matrix(1.044536,0.000000,0.000000,1.000000,425.1311,49.43409)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path650"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="matrix(0.941334,0.000000,0.000000,1.000000,458.0483,65.24859)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path651"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="matrix(0.669337,0.000000,0.000000,1.000000,538.3544,72.16744)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path652"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="matrix(1.269898,0.000000,0.000000,1.000000,56.50726,77.10947)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path653"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="matrix(1.438585,0.000000,0.000000,1.000000,-35.35246,59.31815)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path654"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="matrix(1.000000,0.000000,0.000000,1.938097,7.185234,-212.5805)" />
+ <path
+ sodipodi:type="arc"
+ style="font-size:12;fill:url(#radialGradient635);fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ id="path655"
+ sodipodi:cx="187.13369751"
+ sodipodi:cy="307.85821533"
+ sodipodi:rx="117.18864441"
+ sodipodi:ry="10.43040276"
+ d="M 304.3223 307.8582 A 117.1886 10.4304 0 1 0 69.94505 307.8582 A 117.1886 10.4304 0 1 0 304.3223 307.8582 z"
+ transform="matrix(1.018733,0.000000,0.000000,1.000000,-62.76205,72.16744)" />
+ <g
+ id="g667"
+ transform="matrix(0.165518,0.000000,0.000000,0.165518,358.1883,622.8139)">
+ <path
+ style="font-size:12;fill-rule:evenodd;stroke-width:3pt;"
+ d="M 81.073425 -172.87383 L 218.05954 -172.87383 L 149.56648 -251.15162 L 81.073425 -172.87383 z "
+ id="path668"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="font-size:12;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect669"
+ width="120.212311"
+ height="120.212311"
+ x="71.2886963"
+ y="-132.337128"
+ transform="translate(18.17163,-40.53671)" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect670"
+ width="36.34325790"
+ height="40.53670883"
+ x="106.23413826"
+ y="-125.34804535" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect671"
+ width="36.3432579"
+ height="40.5367088"
+ x="160.749023"
+ y="-125.348045"
+ transform="translate(-4.193453,1.397818)" />
+ </g>
+ <g
+ id="g672"
+ transform="matrix(0.165518,0.000000,0.000000,0.165518,372.0700,622.1198)">
+ <path
+ style="font-size:12;fill-rule:evenodd;stroke-width:3pt;"
+ d="M 81.073425 -172.87383 L 218.05954 -172.87383 L 149.56648 -251.15162 L 81.073425 -172.87383 z "
+ id="path673"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="font-size:12;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect674"
+ width="120.212311"
+ height="120.212311"
+ x="71.2886963"
+ y="-132.337128"
+ transform="translate(18.17163,-40.53671)" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect675"
+ width="36.34325790"
+ height="40.53670883"
+ x="106.23413826"
+ y="-125.34804535" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect676"
+ width="36.3432579"
+ height="40.5367088"
+ x="160.749023"
+ y="-125.348045"
+ transform="translate(-4.193453,1.397818)" />
+ </g>
+ <g
+ id="g701"
+ transform="matrix(0.154930,0.000000,0.000000,0.154930,305.8857,666.6518)">
+ <rect
+ style="font-size:12;fill:#ffff00;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect661"
+ width="36.34325790"
+ height="40.53670883"
+ x="171.93157069"
+ y="-410.50284535" />
+ <g
+ id="g682"
+ transform="translate(-40.53671,-286.5526)">
+ <path
+ style="font-size:12;fill-rule:evenodd;stroke-width:3pt;"
+ d="M 81.073425 -172.87383 L 218.05954 -172.87383 L 149.56648 -251.15162 L 81.073425 -172.87383 z "
+ id="path683"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="font-size:12;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect684"
+ width="120.212311"
+ height="120.212311"
+ x="71.2886963"
+ y="-132.337128"
+ transform="translate(18.17163,-40.53671)" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect685"
+ width="36.34325790"
+ height="40.53670883"
+ x="106.23413826"
+ y="-125.34804535" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect686"
+ width="36.3432579"
+ height="40.5367088"
+ x="160.749023"
+ y="-125.348045"
+ transform="translate(-4.193453,1.397818)" />
+ </g>
+ <path
+ style="font-size:12;fill-rule:evenodd;stroke-width:3pt;"
+ d="M 159.35122 -459.42643 L 296.33734 -459.42643 L 227.84428 -526.52168 L 159.35122 -459.42643 z "
+ id="path688"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="font-size:12;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect689"
+ width="120.21231079"
+ height="120.21231079"
+ x="167.73809354"
+ y="-459.42642769" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect690"
+ width="36.34325790"
+ height="40.53670883"
+ x="184.51193574"
+ y="-411.90064535" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect691"
+ width="36.34325790"
+ height="40.53670883"
+ x="234.83332069"
+ y="-410.50284535" />
+ <rect
+ style="font-size:12;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect700"
+ width="118.81449121"
+ height="67.09524536"
+ x="106.23413914"
+ y="-525.12384033" />
+ </g>
+ <g
+ id="g726"
+ transform="translate(-23.75000,-2.500000)">
+ <path
+ style="font-size:12;fill-rule:evenodd;stroke-width:3pt;"
+ d="M 546.10623 605.61179 L 570.22346 605.61179 L 558.16485 591.83052 L 546.10623 605.61179 z "
+ id="path678"
+ sodipodi:nodetypes="cccc" />
+ <rect
+ style="font-size:12;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect679"
+ width="120.212311"
+ height="120.212311"
+ x="71.2886963"
+ y="-132.337128"
+ transform="matrix(0.176056,0.000000,0.000000,0.176056,535.1181,628.8125)" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect680"
+ width="36.34325790"
+ height="40.53670883"
+ x="106.23413826"
+ y="-125.34804535"
+ transform="matrix(0.176056,0.000000,0.000000,0.176056,531.9189,635.9492)" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect681"
+ width="36.3432579"
+ height="40.5367088"
+ x="160.749023"
+ y="-125.348045"
+ transform="matrix(0.176056,0.000000,0.000000,0.176056,531.1806,636.1953)" />
+ </g>
+ <path
+ style="font-size:12;fill-rule:evenodd;stroke-width:3pt;"
+ d="M 431.21627 550.6336 L 431.21627 551.55221 L 430.12154 551.55221 L 430.12154 552.1013 L 431.21627 552.1013 L 431.21627 554.96072 L 426.34845 565.49015 L 426.34845 617.84379 L 436.69345 617.84379 L 481.57446 617.84379 L 481.57446 592.84113 L 472.07973 582.61905 L 436.69345 582.61905 L 436.69345 565.49015 L 431.85752 555.02979 L 431.85752 552.1013 L 432.99122 552.1013 L 432.99122 551.55221 L 431.85752 551.55221 L 431.85752 550.6336 L 431.21627 550.6336 z "
+ id="path740"
+ sodipodi:nodetypes="ccccccccccccccccccccc" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect741"
+ width="1.93390763"
+ height="3.31527019"
+ x="428.263153"
+ y="566.042801" />
+ <rect
+ style="font-size:12;fill:#ffff00;fill-rule:evenodd;stroke-width:3pt;"
+ id="rect742"
+ width="17.5000000"
+ height="30"
+ x="95.0000000"
+ y="-623.405518"
+ transform="matrix(0.110509,0.000000,0.000000,0.110509,422.6188,634.9347)" />
+ <g
+ id="g919"
+ transform="matrix(4.664220e-2,0.000000,0.000000,5.609369e-2,640.7260,625.5025)"
+ style="fill:#000000;fill-opacity:1;">
+ <defs
+ id="defs573"
+ style="fill:#000000;fill-opacity:1;" />
+ <sodipodi:namedview
+ id="namedview921"
+ inkscape:zoom="3.07667732"
+ inkscape:cx="420.999993"
+ inkscape:cy="238.500019"
+ inkscape:window-width="1404"
+ inkscape:window-height="1085"
+ inkscape:window-x="134"
+ inkscape:window-y="446"
+ style="fill:#000000;fill-opacity:1;" />
+ <path
+ style="fill:#000000;fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-width:1.25;stroke-linejoin:round;stroke-linecap:round;fill-opacity:1;stroke-dasharray:none;"
+ d="M 536.00321 -6.377304 C 535.13922 3.027496 534.27346 12.436646 533.40946 21.841446 C 530.24248 22.321347 527.07646 22.799146 523.90946 23.278946 C 523.90945 23.278945 530.50746 27.004996 531.65946 30.747696 C 532.81047 34.490494 523.59696 33.341446 523.59696 33.341446 C 523.59695 33.341445 531.08346 39.694396 531.65946 41.997696 C 532.23447 44.300896 521.31571 44.872696 521.31571 44.872696 C 521.31571 44.872698 530.52096 51.473746 531.09696 55.216446 C 531.67296 58.959246 531.09696 60.997696 531.09696 60.997696 C 531.09696 60.997694 515.82346 47.754896 506.03446 51.497696 C 500.94746 54.155395 517.69346 55.384446 528.78446 65.028946 C 528.75846 67.176743 501.86921 58.469896 500.87821 63.872696 C 501.50222 65.376396 529.58846 69.417646 531.65946 73.091446 C 521.39047 73.475449 500.17621 70.818546 500.87821 74.216446 C 498.73222 78.139449 520.91496 75.923696 530.22196 79.122696 C 532.94997 82.222694 532.68671 84.826946 527.94071 85.153946 C 518.9707 80.864947 498.89496 77.677946 498.84696 83.153946 C 498.96895 84.615945 519.58971 83.664696 527.06571 88.622696 C 517.08671 90.892695 483.24846 84.017696 483.03446 87.372696 C 483.99845 88.939694 489.35271 95.816946 498.56571 95.528946 C 507.77873 95.240948 529.09446 99.274946 530.53446 102.15395 C 531.97347 105.03294 502.88071 96.096946 491.94071 101.27895 C 481.0007 106.46195 523.31196 103.31995 530.22196 109.65395 C 537.13197 115.98795 516.40946 109.0602 516.40946 109.0602 C 516.40947 109.0602 487.63371 105.0452 483.31571 107.0602 C 478.9967 109.07619 474.09696 113.6852 474.09696 113.6852 C 474.09696 113.6852 476.96796 119.42995 479.84696 118.27895 C 482.72596 117.12695 478.97196 121.7477 478.97196 121.7477 C 478.97195 121.7477 519.29696 131.51695 528.22196 140.15395 C 537.14695 148.79195 476.97196 126.6227 476.97196 126.6227 C 476.97196 126.62269 452.78646 135.5467 478.40946 136.1227 C 475.46147 140.4357 479.84696 143.02895 479.84696 143.02895 C 479.84696 143.02895 522.46646 151.9627 526.78446 158.8727 C 531.10346 165.78269 497.70796 152.2397 490.22196 148.4977 C 482.73695 144.75469 461.43396 150.8087 461.72196 152.2477 C 462.00997 153.6877 472.09121 155.7192 472.37821 158.3102 C 472.66621 160.9012 459.97196 161.7572 459.97196 164.0602 C 459.97195 166.3642 513.82696 177.5932 528.22196 189.6852 C 542.61695 201.77719 485.90946 175.27895 485.90946 175.27895 C 485.90947 175.27895 489.07646 179.5957 485.90946 180.7477 C 482.74247 181.8987 471.49171 164.62595 453.06571 175.27895 C 449.70971 179.66195 469.15396 183.1407 474.09696 183.6227 C 472.40896 187.9627 470.93696 189.39845 477.84696 193.71645 C 484.75595 198.03545 464.31571 187.3602 464.31571 187.9352 C 464.31571 188.51119 465.75321 195.4352 465.75321 195.4352 C 459.37421 190.2532 451.66371 188.6907 444.44071 193.9977 C 444.4407 193.9977 444.14321 199.17445 451.62821 202.34145 C 447.54121 210.69245 456.24671 208.0997 470.06571 215.8727 C 449.52672 210.50469 447.88271 220.47595 462.56571 222.77895 C 477.2487 225.08195 517.56471 226.52495 527.06571 238.90395 C 536.56671 251.28394 513.56471 234.15145 510.94071 233.71645 C 510.36472 234.00445 509.78446 240.0602 509.78446 240.0602 C 503.64245 236.50518 498.00646 233.3162 490.65946 231.8102 C 490.08347 232.96119 490.20421 234.5967 489.62821 235.7477 C 482.96121 230.93968 477.15296 227.55945 467.47196 227.09145 C 467.08797 228.62744 466.69971 230.18045 466.31571 231.71645 C 466.31573 231.71643 458.24446 221.63945 442.40946 231.71645 C 433.56747 238.05543 475.81196 234.0117 482.72196 241.4977 C 489.63197 248.98271 484.15946 250.1227 484.15946 250.1227 C 478.40147 248.01169 472.66746 245.9212 466.90946 243.8102 C 466.90946 243.8102 446.44871 240.04795 440.69071 244.65395 C 434.93271 249.26095 524.75596 260.4927 527.34696 272.8727 C 529.09397 279.5867 506.24296 265.8422 486.47196 259.9352 C 485.70396 262.14219 484.92746 264.3532 484.15946 266.5602 C 484.15947 266.56018 476.31896 258.66745 467.47196 257.34145 C 467.18397 257.34145 469.19071 265.1227 469.19071 265.1227 C 469.1907 265.12271 447.04371 254.74645 435.81571 260.21645 C 424.58673 265.68645 474.95971 268.5647 479.56571 273.7477 C 484.17171 278.92969 464.29271 270.2927 462.56571 273.7477 C 460.8377 277.20269 436.37146 267.42295 436.65946 272.02895 C 436.94747 276.63593 440.12821 279.21645 440.12821 279.21645 C 440.1282 279.21643 491.08771 284.10795 492.81571 290.15395 C 494.54272 296.19993 464.59696 286.71645 464.59696 286.71645 C 464.59697 286.71645 461.70021 291.01395 464.00321 293.02895 C 466.30621 295.04493 446.74496 281.5102 448.47196 290.4352 C 442.12295 287.90719 425.73146 280.0767 428.03446 286.1227 C 430.33746 292.16871 474.37821 300.8102 474.37821 300.8102 C 474.37822 300.8102 455.07671 302.25895 455.94071 307.15395 C 431.12571 292.03593 431.77096 301.67845 432.34696 301.96645 C 432.92296 302.25445 400.37596 293.90995 424.84696 307.15395 C 449.31895 320.39693 438.09021 318.0847 438.37821 318.3727 C 438.66622 318.66069 440.98546 324.9977 440.40946 324.9977 C 439.83346 324.99771 423.72321 316.35395 418.25321 315.77895 C 412.78221 315.20294 386.86421 322.9682 414.50321 335.0602 C 442.14222 347.15219 459.11921 332.17595 474.37821 333.90395 C 489.63722 335.63094 496.84846 338.2277 495.40946 343.1227 C 493.96947 348.01671 479.80046 327.0772 464.90946 345.1852 C 447.97047 341.83321 436.47796 339.89345 445.22196 352.34145 C 417.55895 342.00346 400.66621 355.49545 435.50321 360.96645 C 469.73622 361.97545 490.78446 352.6227 490.78446 352.6227 C 490.78446 352.62271 496.55946 363.2962 504.90946 355.8102 C 513.25846 348.32518 513.52771 358.6852 513.81571 358.6852 C 514.10272 358.68519 521.87821 355.21645 521.87821 355.21645 C 522.55022 355.21645 523.23746 355.21645 523.90946 355.21645 C 523.90945 378.24845 523.90946 401.2782 523.90946 424.3102 C 533.21845 424.40619 542.50671 424.49545 551.81571 424.59145 C 551.8157 424.59144 542.89046 364.4337 547.78446 356.3727 C 552.67946 348.3117 557.28446 349.46645 557.28446 349.46645 C 557.28445 349.46645 575.42571 354.9242 577.44071 354.0602 C 579.45669 353.1962 577.15171 347.16495 586.94071 348.02895 C 590.10771 346.87694 588.40546 341.4107 591.28446 341.1227 C 594.16349 340.8347 649.72371 356.6562 661.81571 341.6852 C 658.64873 333.33621 647.69471 341.11595 644.81571 341.40395 C 642.22469 341.40395 631.27571 336.22195 624.94071 341.40395 C 619.18272 337.08595 593.00321 334.21645 593.00321 334.21645 C 589.54819 330.76145 655.47896 335.93245 659.22196 333.34145 C 666.99498 325.56746 644.83321 326.43795 641.37821 329.02895 C 635.23621 325.28596 627.51871 325.56295 622.81571 328.15395 C 620.5607 322.75993 599.15321 325.0962 587.25321 323.5602 C 583.44418 321.32621 584.07846 320.04395 586.65946 318.65395 C 611.51548 319.70994 636.24496 322.95545 661.22196 321.84145 C 667.97297 313.04045 652.72321 309.72145 643.37821 317.21645 C 637.89219 308.19444 626.67671 316.9232 619.19071 316.0602 C 611.70571 315.1962 615.15946 305.9962 624.65946 307.4352 C 634.16049 308.8752 651.14871 306.84795 654.31571 302.52895 C 657.48171 298.21096 652.42521 293.8362 636.75321 297.9352 C 631.4492 292.7512 619.78571 297.92695 614.31571 299.65395 C 607.0377 295.59396 590.10496 299.08895 584.34696 300.52895 C 578.70996 297.02494 614.00321 291.3102 614.00321 291.3102 C 627.62622 291.0692 635.31021 288.7122 639.62821 287.5602 C 660.22223 276.52219 639.34146 275.3497 628.53446 283.3727 C 621.82647 278.1357 615.45546 283.82545 609.40946 285.84145 C 603.36349 287.85646 591.84696 289.2992 591.84696 288.4352 C 591.84698 287.5712 608.25321 277.4977 608.25321 277.4977 C 608.25322 277.49768 628.40971 276.04245 632.44071 275.46645 C 636.47169 274.89045 657.08596 264.3032 628.97196 271.4352 C 619.18296 272.2992 613.43371 271.74095 609.69071 272.02895 C 587.98569 269.78493 611.72196 267.6852 611.72196 267.6852 C 611.72195 267.68521 642.45371 264.8667 642.81571 263.3727 C 643.41874 251.39071 617.75996 257.0602 617.47196 257.0602 C 617.54595 248.50019 593.56571 257.3482 593.56571 257.0602 C 588.9847 254.36119 596.15946 251.59145 596.15946 251.59145 C 602.49345 250.05644 611.96371 249.5772 614.44071 247.5602 C 614.4407 247.56018 632.31771 247.40295 634.44071 242.65395 C 630.05374 230.55096 596.60721 244.79645 592.12821 246.96645 C 586.0822 246.96646 596.15271 237.19195 596.44071 236.90395 C 596.72873 236.61596 624.07946 235.46695 637.03446 217.90395 C 637.93449 207.21394 621.78446 223.9352 621.78446 223.9352 C 620.57846 210.0712 604.22296 224.81445 594.72196 225.96645 C 585.22195 227.11744 584.94371 221.64295 591.56571 220.77895 C 598.18671 219.91594 605.66646 220.48095 609.40946 210.40395 C 613.15149 200.32694 624.39446 210.9907 626.40946 207.2477 C 628.42447 203.5047 622.37821 200.34145 622.37821 200.34145 C 622.37822 200.34145 630.72171 191.67845 617.19071 191.96645 C 603.65873 192.25445 586.09696 190.2477 586.09696 190.2477 C 586.09697 190.24769 600.19771 184.7722 613.44071 185.0602 C 626.68471 185.34819 619.48371 175.5602 606.81571 175.5602 C 594.14872 175.56019 587.53446 171.2477 587.53446 171.2477 C 594.73247 168.56069 601.93021 165.8722 609.12821 163.1852 C 608.6482 161.17019 608.17071 159.16895 607.69071 157.15395 C 607.6907 157.15395 620.35321 147.0697 602.50321 149.3727 C 584.65321 151.6767 582.62821 151.96645 582.62821 151.96645 C 582.6282 151.96645 546.94746 157.4352 546.65946 157.4352 C 546.37146 157.43519 536.85271 154.5517 546.06571 152.2477 C 555.27873 149.9447 587.82796 143.3322 592.72196 145.0602 C 597.61696 146.78719 592.12096 132.9757 574.84696 131.2477 C 557.57294 129.5207 546.94071 135.5602 546.94071 135.5602 C 546.94072 135.5602 535.70071 131.5152 546.06571 128.0602 C 556.42973 124.60619 572.84696 129.21645 572.84696 129.21645 C 572.84695 129.21645 591.26221 123.7382 576.00321 121.4352 C 560.74421 119.1312 555.93271 123.5067 548.94071 123.7477 C 546.1497 120.2637 572.89671 119.4412 574.56571 116.5602 C 571.74471 111.3762 555.19621 116.5602 545.50321 116.5602 C 541.38022 114.8112 541.10746 111.96545 545.78446 110.21645 C 555.66947 109.83245 564.96196 110.41295 574.84696 110.02895 C 574.55898 104.75095 574.85371 98.494446 574.56571 93.216446 C 562.02771 90.92545 547.32346 94.894196 540.28446 94.560196 C 542.16746 88.801199 569.23921 87.314696 572.25321 85.747696 C 578.52219 77.911693 545.79121 85.747696 545.50321 85.747696 C 539.79022 84.903693 540.13621 81.292696 543.75321 79.122696 C 552.10221 78.162694 570.82546 80.346196 569.40946 74.685196 C 568.32449 69.380493 556.42846 72.220696 551.53446 73.372696 C 546.64048 74.523697 539.44071 73.653946 539.44071 73.653946 C 536.30671 69.434445 567.66521 71.159046 567.37821 67.903946 C 566.96923 64.166645 547.50021 66.740946 540.87821 67.028946 C 535.70421 63.459046 565.73996 61.093796 566.22196 60.685196 C 567.30696 51.114397 546.06546 60.685196 542.03446 60.685196 C 538.00345 60.685197 540.03446 54.653946 540.03446 54.653946 C 540.03447 54.653944 548.38496 50.917246 548.09696 50.341446 C 547.80896 49.765649 541.73546 47.747696 541.15946 47.747696 C 540.58447 47.747694 541.15946 41.122696 541.15946 41.122696 C 541.15947 41.122696 548.07921 35.937196 547.50321 34.497696 C 546.9272 33.058096 539.44071 35.653946 539.44071 35.653946 C 539.44071 33.734547 539.44071 31.823346 539.44071 29.903946 C 539.44071 29.903945 544.92721 29.307546 545.50321 26.716446 C 546.07922 24.125246 538.87821 23.841446 538.87821 23.841446 C 537.91823 13.764847 536.96321 3.699296 536.00321 -6.377304 z M 530.87821 92.278946 L 530.87821 96.278946 C 530.87823 96.278945 520.99846 95.779446 523.40946 94.091446 C 525.82045 92.403444 530.87821 92.639946 530.87821 92.278946 z M 540.03446 97.591446 C 540.27546 97.591446 554.99847 97.698693 554.03446 99.747696 C 553.06946 101.7977 540.28446 103.02895 540.28446 103.02895 L 540.03446 97.591446 z M 539.31571 105.4352 C 539.79771 105.6762 547.05698 105.79669 545.97196 107.1227 C 544.88696 108.4487 540.05671 108.8102 539.81571 108.8102 C 539.57471 108.8102 539.3157 105.43519 539.31571 105.4352 z M 503.40946 115.90395 C 508.07587 116.12581 515.85846 117.39157 528.47196 120.8727 C 528.47196 121.2337 528.83796 126.0562 528.59696 125.9352 C 528.35596 125.8142 500.62896 117.84645 498.09696 117.96645 C 496.51509 118.04207 495.63211 115.53418 503.40946 115.90395 z M 514.65946 127.6852 C 518.84743 127.28787 530.75321 130.2207 530.75321 129.90395 C 530.7532 130.86895 531.37446 135.9262 530.40946 135.6852 C 529.44545 135.4442 511.60146 129.77945 513.40946 128.09145 C 513.63546 127.88045 514.06118 127.74196 514.65946 127.6852 z M 562.22196 138.6852 C 564.36181 138.84907 565.50671 139.27995 564.75321 140.15395 C 561.73921 143.64995 540.90947 146.52894 540.90946 146.52895 L 540.53446 140.15395 C 540.44446 140.15395 555.80243 138.19357 562.22196 138.6852 z M 499.19071 158.46645 C 502.82246 158.34582 511.10721 160.3427 529.19071 167.9977 L 529.31571 172.59145 C 529.31572 172.59145 498.21321 163.15845 497.12821 161.59145 C 496.58571 160.80795 495.55896 158.58707 499.19071 158.46645 z M 559.97196 165.3102 C 561.56567 165.22917 562.35146 165.49645 561.62821 166.3102 C 558.73421 169.5662 543.19071 172.8102 543.19071 172.8102 C 543.19071 172.8102 543.19071 168.71245 543.19071 168.59145 C 543.19071 168.7722 555.19085 165.55329 559.97196 165.3102 z M 492.22196 165.8727 C 497.07421 165.7972 507.62446 168.42645 530.40946 179.21645 C 530.40945 179.33745 530.65546 183.5602 530.53446 183.5602 C 530.41348 183.56019 488.22196 168.71645 488.22196 168.71645 C 488.22196 168.71645 487.36971 165.9482 492.22196 165.8727 z M 568.78446 183.90395 C 571.20306 183.71751 572.43771 183.9037 571.50321 184.7477 C 567.76621 188.1227 543.7977 192.21645 543.31571 192.21645 C 542.83371 192.21645 543.53446 188.3637 543.53446 188.1227 C 543.80596 188.3942 561.52868 184.46326 568.78446 183.90395 z M 501.44071 194.34145 C 509.69821 195.02245 529.56571 204.2097 529.56571 204.02895 C 529.44472 204.51095 529.43671 208.7427 529.31571 208.6227 C 529.19572 208.5017 499.30696 196.1002 498.22196 197.1852 C 497.22946 194.85944 498.68821 194.11445 501.44071 194.34145 z M 563.22196 196.8727 C 565.25068 196.79362 566.38946 196.9217 565.84696 197.40395 C 563.67696 199.33295 543.53446 203.3102 543.53446 203.3102 C 543.53446 203.3102 543.4407 199.57844 543.44071 199.21645 C 543.16921 199.21645 557.1358 197.10993 563.22196 196.8727 z M 561.37821 209.77895 C 563.19223 209.71873 564.30572 209.85795 564.03446 210.3102 C 562.94946 212.1182 544.62822 215.96645 544.62821 215.96645 C 544.62821 215.96645 544.15946 211.8687 544.15946 211.7477 C 544.15946 211.83845 555.93617 209.9596 561.37821 209.77895 z M 491.03446 210.8102 C 496.03634 211.04995 506.59946 213.32095 528.84696 221.40395 L 529.69071 226.34145 C 529.69072 226.34145 486.41346 212.3727 486.53446 212.3727 C 486.59447 212.3727 486.03259 210.57045 491.03446 210.8102 z M 544.59696 221.52895 C 544.59696 221.64995 554.6507 221.8722 553.56571 223.5602 C 552.48071 225.2482 545.12822 225.8727 545.12821 225.8727 C 545.12821 225.8727 544.76698 222.56495 544.59696 221.52895 z M 563.34696 231.21645 C 564.86149 231.39345 565.29146 231.98094 563.78446 233.21645 C 557.75646 238.15945 544.62822 239.1227 544.62821 239.1227 C 544.62821 239.1227 544.62822 233.80518 544.62821 233.6852 C 544.62821 233.7752 558.80337 230.68544 563.34696 231.21645 z M 579.31571 236.21645 C 583.10233 236.33932 581.4652 238.2832 580.44071 239.2477 C 578.39071 241.1767 545.72197 251.52895 545.72196 251.52895 C 545.72196 251.52895 545.47597 244.6622 545.59696 244.0602 C 566.31596 237.7812 575.52909 236.09357 579.31571 236.21645 z M 555.50321 255.7477 C 559.27384 255.4837 562.27022 255.59494 561.37821 256.96645 C 558.58321 259.70945 545.0032 260.1227 545.00321 260.1227 L 545.00321 256.71645 C 547.20871 256.64195 551.73259 256.0117 555.50321 255.7477 z M 569.62821 261.3727 C 571.73981 261.12596 572.64071 261.31445 571.28446 262.27895 C 565.85946 266.13595 545.47197 270.09144 545.47196 270.09145 C 545.47196 270.09145 545.72597 267.31945 545.84696 266.71645 C 546.02771 266.8072 563.29343 262.1129 569.62821 261.3727 z M 580.50321 265.6227 C 583.75076 265.40106 586.24796 265.68495 587.53446 266.6227 C 587.77646 266.6227 586.59569 270.82393 580.56571 272.52895 C 573.81471 271.92595 544.99922 280.46643 544.87821 280.46645 C 544.75821 280.46645 545.22197 276.96643 545.22196 276.96645 C 554.44471 271.45095 570.76057 266.28762 580.50321 265.6227 z M 509.65946 282.02895 C 521.95646 283.35495 526.54896 287.95818 527.84696 289.8102 C 525.10596 294.6202 501.11346 282.00095 509.65946 282.02895 z M 580.34696 282.8727 C 581.14576 282.93424 581.68796 283.30719 581.75321 284.21645 C 580.42721 286.26545 573.37821 285.27895 573.37821 285.27895 C 573.37821 285.36895 577.95057 282.68805 580.34696 282.8727 z M 552.50321 296.3102 C 553.50983 296.20033 554.41865 296.18021 555.06571 296.3102 C 555.92846 296.48351 556.32922 296.9372 555.84696 297.84145 C 553.91796 301.45845 545.47197 300.12269 545.47196 300.1227 L 545.47196 297.59145 C 545.60752 297.72701 549.48336 296.6398 552.50321 296.3102 z M 503.90946 305.7477 C 506.47474 305.65488 508.74121 307.33519 511.09696 308.6852 C 516.40096 307.6002 527.28445 309.52895 527.28446 309.52895 C 527.28446 309.52895 527.28445 313.97946 527.28446 314.34145 C 527.28446 314.58245 513.59323 314.06119 510.62821 312.1852 C 508.09721 312.1852 500.49796 308.09595 501.22196 306.52895 C 502.16021 306.02895 503.05437 305.77863 503.90946 305.7477 z M 559.37821 308.15395 C 561.563 307.97793 562.53695 308.53595 560.90946 310.84145 C 556.56946 316.98945 545.34697 314.46645 545.34696 314.46645 L 544.87821 310.65395 C 548.74009 310.80457 555.7369 308.44732 559.37821 308.15395 z M 519.90946 320.65395 C 523.69959 320.93494 527.15946 322.1852 527.15946 322.1852 C 527.28046 322.4262 529.81645 327.3592 527.28446 328.6852 C 524.75246 330.0112 512.6507 327.64895 511.94071 322.77895 C 513.02571 321.6337 514.49837 321.0504 516.12821 320.77895 C 517.3506 320.57536 518.64609 320.56028 519.90946 320.65395 z M 473.03446 323.0602 C 476.82164 323.56054 480.36121 325.63695 480.25321 325.52895 C 480.2532 325.67295 480.09696 330.15395 480.09696 330.15395 C 480.09696 330.15395 471.88146 327.8637 469.28446 323.2477 C 470.47472 322.92319 471.77207 322.89342 473.03446 323.0602 z M 550.28446 323.59145 C 555.8225 323.6199 562.50194 325.16796 560.78446 327.2477 C 558.49346 330.0197 545.47197 327.49768 545.47196 327.4977 L 545.47196 324.1227 C 546.70771 323.7612 548.43845 323.58196 550.28446 323.59145 z "
+ id="path922" />
+ </g>
+ <g
+ id="g923"
+ transform="matrix(7.059591e-2,0,0,7.059591e-2,581.1598,605.9706)"
+ style="fill:#000000;fill-opacity:1;">
+ <defs
+ id="defs924"
+ style="fill:#000000;fill-opacity:1;" />
+ <sodipodi:namedview
+ id="namedview925"
+ inkscape:zoom="3.07667732"
+ inkscape:cx="420.999993"
+ inkscape:cy="238.500019"
+ inkscape:window-width="1404"
+ inkscape:window-height="1085"
+ inkscape:window-x="134"
+ inkscape:window-y="446"
+ style="fill:#000000;fill-opacity:1;" />
+ <path
+ style="fill:#000000;fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-width:1.25;stroke-linejoin:round;stroke-linecap:round;fill-opacity:1;stroke-dasharray:none;"
+ d="M 536.00321 -6.377304 C 535.13922 3.027496 534.27346 12.436646 533.40946 21.841446 C 530.24248 22.321347 527.07646 22.799146 523.90946 23.278946 C 523.90945 23.278945 530.50746 27.004996 531.65946 30.747696 C 532.81047 34.490494 523.59696 33.341446 523.59696 33.341446 C 523.59695 33.341445 531.08346 39.694396 531.65946 41.997696 C 532.23447 44.300896 521.31571 44.872696 521.31571 44.872696 C 521.31571 44.872698 530.52096 51.473746 531.09696 55.216446 C 531.67296 58.959246 531.09696 60.997696 531.09696 60.997696 C 531.09696 60.997694 515.82346 47.754896 506.03446 51.497696 C 500.94746 54.155395 517.69346 55.384446 528.78446 65.028946 C 528.75846 67.176743 501.86921 58.469896 500.87821 63.872696 C 501.50222 65.376396 529.58846 69.417646 531.65946 73.091446 C 521.39047 73.475449 500.17621 70.818546 500.87821 74.216446 C 498.73222 78.139449 520.91496 75.923696 530.22196 79.122696 C 532.94997 82.222694 532.68671 84.826946 527.94071 85.153946 C 518.9707 80.864947 498.89496 77.677946 498.84696 83.153946 C 498.96895 84.615945 519.58971 83.664696 527.06571 88.622696 C 517.08671 90.892695 483.24846 84.017696 483.03446 87.372696 C 483.99845 88.939694 489.35271 95.816946 498.56571 95.528946 C 507.77873 95.240948 529.09446 99.274946 530.53446 102.15395 C 531.97347 105.03294 502.88071 96.096946 491.94071 101.27895 C 481.0007 106.46195 523.31196 103.31995 530.22196 109.65395 C 537.13197 115.98795 516.40946 109.0602 516.40946 109.0602 C 516.40947 109.0602 487.63371 105.0452 483.31571 107.0602 C 478.9967 109.07619 474.09696 113.6852 474.09696 113.6852 C 474.09696 113.6852 476.96796 119.42995 479.84696 118.27895 C 482.72596 117.12695 478.97196 121.7477 478.97196 121.7477 C 478.97195 121.7477 519.29696 131.51695 528.22196 140.15395 C 537.14695 148.79195 476.97196 126.6227 476.97196 126.6227 C 476.97196 126.62269 452.78646 135.5467 478.40946 136.1227 C 475.46147 140.4357 479.84696 143.02895 479.84696 143.02895 C 479.84696 143.02895 522.46646 151.9627 526.78446 158.8727 C 531.10346 165.78269 497.70796 152.2397 490.22196 148.4977 C 482.73695 144.75469 461.43396 150.8087 461.72196 152.2477 C 462.00997 153.6877 472.09121 155.7192 472.37821 158.3102 C 472.66621 160.9012 459.97196 161.7572 459.97196 164.0602 C 459.97195 166.3642 513.82696 177.5932 528.22196 189.6852 C 542.61695 201.77719 485.90946 175.27895 485.90946 175.27895 C 485.90947 175.27895 489.07646 179.5957 485.90946 180.7477 C 482.74247 181.8987 471.49171 164.62595 453.06571 175.27895 C 449.70971 179.66195 469.15396 183.1407 474.09696 183.6227 C 472.40896 187.9627 470.93696 189.39845 477.84696 193.71645 C 484.75595 198.03545 464.31571 187.3602 464.31571 187.9352 C 464.31571 188.51119 465.75321 195.4352 465.75321 195.4352 C 459.37421 190.2532 451.66371 188.6907 444.44071 193.9977 C 444.4407 193.9977 444.14321 199.17445 451.62821 202.34145 C 447.54121 210.69245 456.24671 208.0997 470.06571 215.8727 C 449.52672 210.50469 447.88271 220.47595 462.56571 222.77895 C 477.2487 225.08195 517.56471 226.52495 527.06571 238.90395 C 536.56671 251.28394 513.56471 234.15145 510.94071 233.71645 C 510.36472 234.00445 509.78446 240.0602 509.78446 240.0602 C 503.64245 236.50518 498.00646 233.3162 490.65946 231.8102 C 490.08347 232.96119 490.20421 234.5967 489.62821 235.7477 C 482.96121 230.93968 477.15296 227.55945 467.47196 227.09145 C 467.08797 228.62744 466.69971 230.18045 466.31571 231.71645 C 466.31573 231.71643 458.24446 221.63945 442.40946 231.71645 C 433.56747 238.05543 475.81196 234.0117 482.72196 241.4977 C 489.63197 248.98271 484.15946 250.1227 484.15946 250.1227 C 478.40147 248.01169 472.66746 245.9212 466.90946 243.8102 C 466.90946 243.8102 446.44871 240.04795 440.69071 244.65395 C 434.93271 249.26095 524.75596 260.4927 527.34696 272.8727 C 529.09397 279.5867 506.24296 265.8422 486.47196 259.9352 C 485.70396 262.14219 484.92746 264.3532 484.15946 266.5602 C 484.15947 266.56018 476.31896 258.66745 467.47196 257.34145 C 467.18397 257.34145 469.19071 265.1227 469.19071 265.1227 C 469.1907 265.12271 447.04371 254.74645 435.81571 260.21645 C 424.58673 265.68645 474.95971 268.5647 479.56571 273.7477 C 484.17171 278.92969 464.29271 270.2927 462.56571 273.7477 C 460.8377 277.20269 436.37146 267.42295 436.65946 272.02895 C 436.94747 276.63593 440.12821 279.21645 440.12821 279.21645 C 440.1282 279.21643 491.08771 284.10795 492.81571 290.15395 C 494.54272 296.19993 464.59696 286.71645 464.59696 286.71645 C 464.59697 286.71645 461.70021 291.01395 464.00321 293.02895 C 466.30621 295.04493 446.74496 281.5102 448.47196 290.4352 C 442.12295 287.90719 425.73146 280.0767 428.03446 286.1227 C 430.33746 292.16871 474.37821 300.8102 474.37821 300.8102 C 474.37822 300.8102 455.07671 302.25895 455.94071 307.15395 C 431.12571 292.03593 431.77096 301.67845 432.34696 301.96645 C 432.92296 302.25445 400.37596 293.90995 424.84696 307.15395 C 449.31895 320.39693 438.09021 318.0847 438.37821 318.3727 C 438.66622 318.66069 440.98546 324.9977 440.40946 324.9977 C 439.83346 324.99771 423.72321 316.35395 418.25321 315.77895 C 412.78221 315.20294 386.86421 322.9682 414.50321 335.0602 C 442.14222 347.15219 459.11921 332.17595 474.37821 333.90395 C 489.63722 335.63094 496.84846 338.2277 495.40946 343.1227 C 493.96947 348.01671 479.80046 327.0772 464.90946 345.1852 C 447.97047 341.83321 436.47796 339.89345 445.22196 352.34145 C 417.55895 342.00346 400.66621 355.49545 435.50321 360.96645 C 469.73622 361.97545 490.78446 352.6227 490.78446 352.6227 C 490.78446 352.62271 496.55946 363.2962 504.90946 355.8102 C 513.25846 348.32518 513.52771 358.6852 513.81571 358.6852 C 514.10272 358.68519 521.87821 355.21645 521.87821 355.21645 C 522.55022 355.21645 523.23746 355.21645 523.90946 355.21645 C 523.90945 378.24845 523.90946 401.2782 523.90946 424.3102 C 533.21845 424.40619 542.50671 424.49545 551.81571 424.59145 C 551.8157 424.59144 542.89046 364.4337 547.78446 356.3727 C 552.67946 348.3117 557.28446 349.46645 557.28446 349.46645 C 557.28445 349.46645 575.42571 354.9242 577.44071 354.0602 C 579.45669 353.1962 577.15171 347.16495 586.94071 348.02895 C 590.10771 346.87694 588.40546 341.4107 591.28446 341.1227 C 594.16349 340.8347 649.72371 356.6562 661.81571 341.6852 C 658.64873 333.33621 647.69471 341.11595 644.81571 341.40395 C 642.22469 341.40395 631.27571 336.22195 624.94071 341.40395 C 619.18272 337.08595 593.00321 334.21645 593.00321 334.21645 C 589.54819 330.76145 655.47896 335.93245 659.22196 333.34145 C 666.99498 325.56746 644.83321 326.43795 641.37821 329.02895 C 635.23621 325.28596 627.51871 325.56295 622.81571 328.15395 C 620.5607 322.75993 599.15321 325.0962 587.25321 323.5602 C 583.44418 321.32621 584.07846 320.04395 586.65946 318.65395 C 611.51548 319.70994 636.24496 322.95545 661.22196 321.84145 C 667.97297 313.04045 652.72321 309.72145 643.37821 317.21645 C 637.89219 308.19444 626.67671 316.9232 619.19071 316.0602 C 611.70571 315.1962 615.15946 305.9962 624.65946 307.4352 C 634.16049 308.8752 651.14871 306.84795 654.31571 302.52895 C 657.48171 298.21096 652.42521 293.8362 636.75321 297.9352 C 631.4492 292.7512 619.78571 297.92695 614.31571 299.65395 C 607.0377 295.59396 590.10496 299.08895 584.34696 300.52895 C 578.70996 297.02494 614.00321 291.3102 614.00321 291.3102 C 627.62622 291.0692 635.31021 288.7122 639.62821 287.5602 C 660.22223 276.52219 639.34146 275.3497 628.53446 283.3727 C 621.82647 278.1357 615.45546 283.82545 609.40946 285.84145 C 603.36349 287.85646 591.84696 289.2992 591.84696 288.4352 C 591.84698 287.5712 608.25321 277.4977 608.25321 277.4977 C 608.25322 277.49768 628.40971 276.04245 632.44071 275.46645 C 636.47169 274.89045 657.08596 264.3032 628.97196 271.4352 C 619.18296 272.2992 613.43371 271.74095 609.69071 272.02895 C 587.98569 269.78493 611.72196 267.6852 611.72196 267.6852 C 611.72195 267.68521 642.45371 264.8667 642.81571 263.3727 C 643.41874 251.39071 617.75996 257.0602 617.47196 257.0602 C 617.54595 248.50019 593.56571 257.3482 593.56571 257.0602 C 588.9847 254.36119 596.15946 251.59145 596.15946 251.59145 C 602.49345 250.05644 611.96371 249.5772 614.44071 247.5602 C 614.4407 247.56018 632.31771 247.40295 634.44071 242.65395 C 630.05374 230.55096 596.60721 244.79645 592.12821 246.96645 C 586.0822 246.96646 596.15271 237.19195 596.44071 236.90395 C 596.72873 236.61596 624.07946 235.46695 637.03446 217.90395 C 637.93449 207.21394 621.78446 223.9352 621.78446 223.9352 C 620.57846 210.0712 604.22296 224.81445 594.72196 225.96645 C 585.22195 227.11744 584.94371 221.64295 591.56571 220.77895 C 598.18671 219.91594 605.66646 220.48095 609.40946 210.40395 C 613.15149 200.32694 624.39446 210.9907 626.40946 207.2477 C 628.42447 203.5047 622.37821 200.34145 622.37821 200.34145 C 622.37822 200.34145 630.72171 191.67845 617.19071 191.96645 C 603.65873 192.25445 586.09696 190.2477 586.09696 190.2477 C 586.09697 190.24769 600.19771 184.7722 613.44071 185.0602 C 626.68471 185.34819 619.48371 175.5602 606.81571 175.5602 C 594.14872 175.56019 587.53446 171.2477 587.53446 171.2477 C 594.73247 168.56069 601.93021 165.8722 609.12821 163.1852 C 608.6482 161.17019 608.17071 159.16895 607.69071 157.15395 C 607.6907 157.15395 620.35321 147.0697 602.50321 149.3727 C 584.65321 151.6767 582.62821 151.96645 582.62821 151.96645 C 582.6282 151.96645 546.94746 157.4352 546.65946 157.4352 C 546.37146 157.43519 536.85271 154.5517 546.06571 152.2477 C 555.27873 149.9447 587.82796 143.3322 592.72196 145.0602 C 597.61696 146.78719 592.12096 132.9757 574.84696 131.2477 C 557.57294 129.5207 546.94071 135.5602 546.94071 135.5602 C 546.94072 135.5602 535.70071 131.5152 546.06571 128.0602 C 556.42973 124.60619 572.84696 129.21645 572.84696 129.21645 C 572.84695 129.21645 591.26221 123.7382 576.00321 121.4352 C 560.74421 119.1312 555.93271 123.5067 548.94071 123.7477 C 546.1497 120.2637 572.89671 119.4412 574.56571 116.5602 C 571.74471 111.3762 555.19621 116.5602 545.50321 116.5602 C 541.38022 114.8112 541.10746 111.96545 545.78446 110.21645 C 555.66947 109.83245 564.96196 110.41295 574.84696 110.02895 C 574.55898 104.75095 574.85371 98.494446 574.56571 93.216446 C 562.02771 90.92545 547.32346 94.894196 540.28446 94.560196 C 542.16746 88.801199 569.23921 87.314696 572.25321 85.747696 C 578.52219 77.911693 545.79121 85.747696 545.50321 85.747696 C 539.79022 84.903693 540.13621 81.292696 543.75321 79.122696 C 552.10221 78.162694 570.82546 80.346196 569.40946 74.685196 C 568.32449 69.380493 556.42846 72.220696 551.53446 73.372696 C 546.64048 74.523697 539.44071 73.653946 539.44071 73.653946 C 536.30671 69.434445 567.66521 71.159046 567.37821 67.903946 C 566.96923 64.166645 547.50021 66.740946 540.87821 67.028946 C 535.70421 63.459046 565.73996 61.093796 566.22196 60.685196 C 567.30696 51.114397 546.06546 60.685196 542.03446 60.685196 C 538.00345 60.685197 540.03446 54.653946 540.03446 54.653946 C 540.03447 54.653944 548.38496 50.917246 548.09696 50.341446 C 547.80896 49.765649 541.73546 47.747696 541.15946 47.747696 C 540.58447 47.747694 541.15946 41.122696 541.15946 41.122696 C 541.15947 41.122696 548.07921 35.937196 547.50321 34.497696 C 546.9272 33.058096 539.44071 35.653946 539.44071 35.653946 C 539.44071 33.734547 539.44071 31.823346 539.44071 29.903946 C 539.44071 29.903945 544.92721 29.307546 545.50321 26.716446 C 546.07922 24.125246 538.87821 23.841446 538.87821 23.841446 C 537.91823 13.764847 536.96321 3.699296 536.00321 -6.377304 z M 530.87821 92.278946 L 530.87821 96.278946 C 530.87823 96.278945 520.99846 95.779446 523.40946 94.091446 C 525.82045 92.403444 530.87821 92.639946 530.87821 92.278946 z M 540.03446 97.591446 C 540.27546 97.591446 554.99847 97.698693 554.03446 99.747696 C 553.06946 101.7977 540.28446 103.02895 540.28446 103.02895 L 540.03446 97.591446 z M 539.31571 105.4352 C 539.79771 105.6762 547.05698 105.79669 545.97196 107.1227 C 544.88696 108.4487 540.05671 108.8102 539.81571 108.8102 C 539.57471 108.8102 539.3157 105.43519 539.31571 105.4352 z M 503.40946 115.90395 C 508.07587 116.12581 515.85846 117.39157 528.47196 120.8727 C 528.47196 121.2337 528.83796 126.0562 528.59696 125.9352 C 528.35596 125.8142 500.62896 117.84645 498.09696 117.96645 C 496.51509 118.04207 495.63211 115.53418 503.40946 115.90395 z M 514.65946 127.6852 C 518.84743 127.28787 530.75321 130.2207 530.75321 129.90395 C 530.7532 130.86895 531.37446 135.9262 530.40946 135.6852 C 529.44545 135.4442 511.60146 129.77945 513.40946 128.09145 C 513.63546 127.88045 514.06118 127.74196 514.65946 127.6852 z M 562.22196 138.6852 C 564.36181 138.84907 565.50671 139.27995 564.75321 140.15395 C 561.73921 143.64995 540.90947 146.52894 540.90946 146.52895 L 540.53446 140.15395 C 540.44446 140.15395 555.80243 138.19357 562.22196 138.6852 z M 499.19071 158.46645 C 502.82246 158.34582 511.10721 160.3427 529.19071 167.9977 L 529.31571 172.59145 C 529.31572 172.59145 498.21321 163.15845 497.12821 161.59145 C 496.58571 160.80795 495.55896 158.58707 499.19071 158.46645 z M 559.97196 165.3102 C 561.56567 165.22917 562.35146 165.49645 561.62821 166.3102 C 558.73421 169.5662 543.19071 172.8102 543.19071 172.8102 C 543.19071 172.8102 543.19071 168.71245 543.19071 168.59145 C 543.19071 168.7722 555.19085 165.55329 559.97196 165.3102 z M 492.22196 165.8727 C 497.07421 165.7972 507.62446 168.42645 530.40946 179.21645 C 530.40945 179.33745 530.65546 183.5602 530.53446 183.5602 C 530.41348 183.56019 488.22196 168.71645 488.22196 168.71645 C 488.22196 168.71645 487.36971 165.9482 492.22196 165.8727 z M 568.78446 183.90395 C 571.20306 183.71751 572.43771 183.9037 571.50321 184.7477 C 567.76621 188.1227 543.7977 192.21645 543.31571 192.21645 C 542.83371 192.21645 543.53446 188.3637 543.53446 188.1227 C 543.80596 188.3942 561.52868 184.46326 568.78446 183.90395 z M 501.44071 194.34145 C 509.69821 195.02245 529.56571 204.2097 529.56571 204.02895 C 529.44472 204.51095 529.43671 208.7427 529.31571 208.6227 C 529.19572 208.5017 499.30696 196.1002 498.22196 197.1852 C 497.22946 194.85944 498.68821 194.11445 501.44071 194.34145 z M 563.22196 196.8727 C 565.25068 196.79362 566.38946 196.9217 565.84696 197.40395 C 563.67696 199.33295 543.53446 203.3102 543.53446 203.3102 C 543.53446 203.3102 543.4407 199.57844 543.44071 199.21645 C 543.16921 199.21645 557.1358 197.10993 563.22196 196.8727 z M 561.37821 209.77895 C 563.19223 209.71873 564.30572 209.85795 564.03446 210.3102 C 562.94946 212.1182 544.62822 215.96645 544.62821 215.96645 C 544.62821 215.96645 544.15946 211.8687 544.15946 211.7477 C 544.15946 211.83845 555.93617 209.9596 561.37821 209.77895 z M 491.03446 210.8102 C 496.03634 211.04995 506.59946 213.32095 528.84696 221.40395 L 529.69071 226.34145 C 529.69072 226.34145 486.41346 212.3727 486.53446 212.3727 C 486.59447 212.3727 486.03259 210.57045 491.03446 210.8102 z M 544.59696 221.52895 C 544.59696 221.64995 554.6507 221.8722 553.56571 223.5602 C 552.48071 225.2482 545.12822 225.8727 545.12821 225.8727 C 545.12821 225.8727 544.76698 222.56495 544.59696 221.52895 z M 563.34696 231.21645 C 564.86149 231.39345 565.29146 231.98094 563.78446 233.21645 C 557.75646 238.15945 544.62822 239.1227 544.62821 239.1227 C 544.62821 239.1227 544.62822 233.80518 544.62821 233.6852 C 544.62821 233.7752 558.80337 230.68544 563.34696 231.21645 z M 579.31571 236.21645 C 583.10233 236.33932 581.4652 238.2832 580.44071 239.2477 C 578.39071 241.1767 545.72197 251.52895 545.72196 251.52895 C 545.72196 251.52895 545.47597 244.6622 545.59696 244.0602 C 566.31596 237.7812 575.52909 236.09357 579.31571 236.21645 z M 555.50321 255.7477 C 559.27384 255.4837 562.27022 255.59494 561.37821 256.96645 C 558.58321 259.70945 545.0032 260.1227 545.00321 260.1227 L 545.00321 256.71645 C 547.20871 256.64195 551.73259 256.0117 555.50321 255.7477 z M 569.62821 261.3727 C 571.73981 261.12596 572.64071 261.31445 571.28446 262.27895 C 565.85946 266.13595 545.47197 270.09144 545.47196 270.09145 C 545.47196 270.09145 545.72597 267.31945 545.84696 266.71645 C 546.02771 266.8072 563.29343 262.1129 569.62821 261.3727 z M 580.50321 265.6227 C 583.75076 265.40106 586.24796 265.68495 587.53446 266.6227 C 587.77646 266.6227 586.59569 270.82393 580.56571 272.52895 C 573.81471 271.92595 544.99922 280.46643 544.87821 280.46645 C 544.75821 280.46645 545.22197 276.96643 545.22196 276.96645 C 554.44471 271.45095 570.76057 266.28762 580.50321 265.6227 z M 509.65946 282.02895 C 521.95646 283.35495 526.54896 287.95818 527.84696 289.8102 C 525.10596 294.6202 501.11346 282.00095 509.65946 282.02895 z M 580.34696 282.8727 C 581.14576 282.93424 581.68796 283.30719 581.75321 284.21645 C 580.42721 286.26545 573.37821 285.27895 573.37821 285.27895 C 573.37821 285.36895 577.95057 282.68805 580.34696 282.8727 z M 552.50321 296.3102 C 553.50983 296.20033 554.41865 296.18021 555.06571 296.3102 C 555.92846 296.48351 556.32922 296.9372 555.84696 297.84145 C 553.91796 301.45845 545.47197 300.12269 545.47196 300.1227 L 545.47196 297.59145 C 545.60752 297.72701 549.48336 296.6398 552.50321 296.3102 z M 503.90946 305.7477 C 506.47474 305.65488 508.74121 307.33519 511.09696 308.6852 C 516.40096 307.6002 527.28445 309.52895 527.28446 309.52895 C 527.28446 309.52895 527.28445 313.97946 527.28446 314.34145 C 527.28446 314.58245 513.59323 314.06119 510.62821 312.1852 C 508.09721 312.1852 500.49796 308.09595 501.22196 306.52895 C 502.16021 306.02895 503.05437 305.77863 503.90946 305.7477 z M 559.37821 308.15395 C 561.563 307.97793 562.53695 308.53595 560.90946 310.84145 C 556.56946 316.98945 545.34697 314.46645 545.34696 314.46645 L 544.87821 310.65395 C 548.74009 310.80457 555.7369 308.44732 559.37821 308.15395 z M 519.90946 320.65395 C 523.69959 320.93494 527.15946 322.1852 527.15946 322.1852 C 527.28046 322.4262 529.81645 327.3592 527.28446 328.6852 C 524.75246 330.0112 512.6507 327.64895 511.94071 322.77895 C 513.02571 321.6337 514.49837 321.0504 516.12821 320.77895 C 517.3506 320.57536 518.64609 320.56028 519.90946 320.65395 z M 473.03446 323.0602 C 476.82164 323.56054 480.36121 325.63695 480.25321 325.52895 C 480.2532 325.67295 480.09696 330.15395 480.09696 330.15395 C 480.09696 330.15395 471.88146 327.8637 469.28446 323.2477 C 470.47472 322.92319 471.77207 322.89342 473.03446 323.0602 z M 550.28446 323.59145 C 555.8225 323.6199 562.50194 325.16796 560.78446 327.2477 C 558.49346 330.0197 545.47197 327.49768 545.47196 327.4977 L 545.47196 324.1227 C 546.70771 323.7612 548.43845 323.58196 550.28446 323.59145 z "
+ id="path926" />
+ </g>
+ <g
+ id="g927"
+ transform="matrix(7.059591e-2,0.000000,0.000000,7.059591e-2,592.3472,609.3450)"
+ style="fill:#000000;fill-opacity:1;">
+ <defs
+ id="defs928"
+ style="fill:#000000;fill-opacity:1;" />
+ <sodipodi:namedview
+ id="namedview929"
+ inkscape:zoom="3.07667732"
+ inkscape:cx="420.999993"
+ inkscape:cy="238.500019"
+ inkscape:window-width="1404"
+ inkscape:window-height="1085"
+ inkscape:window-x="134"
+ inkscape:window-y="446"
+ style="fill:#000000;fill-opacity:1;" />
+ <path
+ style="fill:#000000;fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-width:1.25;stroke-linejoin:round;stroke-linecap:round;fill-opacity:1;stroke-dasharray:none;"
+ d="M 536.00321 -6.377304 C 535.13922 3.027496 534.27346 12.436646 533.40946 21.841446 C 530.24248 22.321347 527.07646 22.799146 523.90946 23.278946 C 523.90945 23.278945 530.50746 27.004996 531.65946 30.747696 C 532.81047 34.490494 523.59696 33.341446 523.59696 33.341446 C 523.59695 33.341445 531.08346 39.694396 531.65946 41.997696 C 532.23447 44.300896 521.31571 44.872696 521.31571 44.872696 C 521.31571 44.872698 530.52096 51.473746 531.09696 55.216446 C 531.67296 58.959246 531.09696 60.997696 531.09696 60.997696 C 531.09696 60.997694 515.82346 47.754896 506.03446 51.497696 C 500.94746 54.155395 517.69346 55.384446 528.78446 65.028946 C 528.75846 67.176743 501.86921 58.469896 500.87821 63.872696 C 501.50222 65.376396 529.58846 69.417646 531.65946 73.091446 C 521.39047 73.475449 500.17621 70.818546 500.87821 74.216446 C 498.73222 78.139449 520.91496 75.923696 530.22196 79.122696 C 532.94997 82.222694 532.68671 84.826946 527.94071 85.153946 C 518.9707 80.864947 498.89496 77.677946 498.84696 83.153946 C 498.96895 84.615945 519.58971 83.664696 527.06571 88.622696 C 517.08671 90.892695 483.24846 84.017696 483.03446 87.372696 C 483.99845 88.939694 489.35271 95.816946 498.56571 95.528946 C 507.77873 95.240948 529.09446 99.274946 530.53446 102.15395 C 531.97347 105.03294 502.88071 96.096946 491.94071 101.27895 C 481.0007 106.46195 523.31196 103.31995 530.22196 109.65395 C 537.13197 115.98795 516.40946 109.0602 516.40946 109.0602 C 516.40947 109.0602 487.63371 105.0452 483.31571 107.0602 C 478.9967 109.07619 474.09696 113.6852 474.09696 113.6852 C 474.09696 113.6852 476.96796 119.42995 479.84696 118.27895 C 482.72596 117.12695 478.97196 121.7477 478.97196 121.7477 C 478.97195 121.7477 519.29696 131.51695 528.22196 140.15395 C 537.14695 148.79195 476.97196 126.6227 476.97196 126.6227 C 476.97196 126.62269 452.78646 135.5467 478.40946 136.1227 C 475.46147 140.4357 479.84696 143.02895 479.84696 143.02895 C 479.84696 143.02895 522.46646 151.9627 526.78446 158.8727 C 531.10346 165.78269 497.70796 152.2397 490.22196 148.4977 C 482.73695 144.75469 461.43396 150.8087 461.72196 152.2477 C 462.00997 153.6877 472.09121 155.7192 472.37821 158.3102 C 472.66621 160.9012 459.97196 161.7572 459.97196 164.0602 C 459.97195 166.3642 513.82696 177.5932 528.22196 189.6852 C 542.61695 201.77719 485.90946 175.27895 485.90946 175.27895 C 485.90947 175.27895 489.07646 179.5957 485.90946 180.7477 C 482.74247 181.8987 471.49171 164.62595 453.06571 175.27895 C 449.70971 179.66195 469.15396 183.1407 474.09696 183.6227 C 472.40896 187.9627 470.93696 189.39845 477.84696 193.71645 C 484.75595 198.03545 464.31571 187.3602 464.31571 187.9352 C 464.31571 188.51119 465.75321 195.4352 465.75321 195.4352 C 459.37421 190.2532 451.66371 188.6907 444.44071 193.9977 C 444.4407 193.9977 444.14321 199.17445 451.62821 202.34145 C 447.54121 210.69245 456.24671 208.0997 470.06571 215.8727 C 449.52672 210.50469 447.88271 220.47595 462.56571 222.77895 C 477.2487 225.08195 517.56471 226.52495 527.06571 238.90395 C 536.56671 251.28394 513.56471 234.15145 510.94071 233.71645 C 510.36472 234.00445 509.78446 240.0602 509.78446 240.0602 C 503.64245 236.50518 498.00646 233.3162 490.65946 231.8102 C 490.08347 232.96119 490.20421 234.5967 489.62821 235.7477 C 482.96121 230.93968 477.15296 227.55945 467.47196 227.09145 C 467.08797 228.62744 466.69971 230.18045 466.31571 231.71645 C 466.31573 231.71643 458.24446 221.63945 442.40946 231.71645 C 433.56747 238.05543 475.81196 234.0117 482.72196 241.4977 C 489.63197 248.98271 484.15946 250.1227 484.15946 250.1227 C 478.40147 248.01169 472.66746 245.9212 466.90946 243.8102 C 466.90946 243.8102 446.44871 240.04795 440.69071 244.65395 C 434.93271 249.26095 524.75596 260.4927 527.34696 272.8727 C 529.09397 279.5867 506.24296 265.8422 486.47196 259.9352 C 485.70396 262.14219 484.92746 264.3532 484.15946 266.5602 C 484.15947 266.56018 476.31896 258.66745 467.47196 257.34145 C 467.18397 257.34145 469.19071 265.1227 469.19071 265.1227 C 469.1907 265.12271 447.04371 254.74645 435.81571 260.21645 C 424.58673 265.68645 474.95971 268.5647 479.56571 273.7477 C 484.17171 278.92969 464.29271 270.2927 462.56571 273.7477 C 460.8377 277.20269 436.37146 267.42295 436.65946 272.02895 C 436.94747 276.63593 440.12821 279.21645 440.12821 279.21645 C 440.1282 279.21643 491.08771 284.10795 492.81571 290.15395 C 494.54272 296.19993 464.59696 286.71645 464.59696 286.71645 C 464.59697 286.71645 461.70021 291.01395 464.00321 293.02895 C 466.30621 295.04493 446.74496 281.5102 448.47196 290.4352 C 442.12295 287.90719 425.73146 280.0767 428.03446 286.1227 C 430.33746 292.16871 474.37821 300.8102 474.37821 300.8102 C 474.37822 300.8102 455.07671 302.25895 455.94071 307.15395 C 431.12571 292.03593 431.77096 301.67845 432.34696 301.96645 C 432.92296 302.25445 400.37596 293.90995 424.84696 307.15395 C 449.31895 320.39693 438.09021 318.0847 438.37821 318.3727 C 438.66622 318.66069 440.98546 324.9977 440.40946 324.9977 C 439.83346 324.99771 423.72321 316.35395 418.25321 315.77895 C 412.78221 315.20294 386.86421 322.9682 414.50321 335.0602 C 442.14222 347.15219 459.11921 332.17595 474.37821 333.90395 C 489.63722 335.63094 496.84846 338.2277 495.40946 343.1227 C 493.96947 348.01671 479.80046 327.0772 464.90946 345.1852 C 447.97047 341.83321 436.47796 339.89345 445.22196 352.34145 C 417.55895 342.00346 400.66621 355.49545 435.50321 360.96645 C 469.73622 361.97545 490.78446 352.6227 490.78446 352.6227 C 490.78446 352.62271 496.55946 363.2962 504.90946 355.8102 C 513.25846 348.32518 513.52771 358.6852 513.81571 358.6852 C 514.10272 358.68519 521.87821 355.21645 521.87821 355.21645 C 522.55022 355.21645 523.23746 355.21645 523.90946 355.21645 C 523.90945 378.24845 523.90946 401.2782 523.90946 424.3102 C 533.21845 424.40619 542.50671 424.49545 551.81571 424.59145 C 551.8157 424.59144 542.89046 364.4337 547.78446 356.3727 C 552.67946 348.3117 557.28446 349.46645 557.28446 349.46645 C 557.28445 349.46645 575.42571 354.9242 577.44071 354.0602 C 579.45669 353.1962 577.15171 347.16495 586.94071 348.02895 C 590.10771 346.87694 588.40546 341.4107 591.28446 341.1227 C 594.16349 340.8347 649.72371 356.6562 661.81571 341.6852 C 658.64873 333.33621 647.69471 341.11595 644.81571 341.40395 C 642.22469 341.40395 631.27571 336.22195 624.94071 341.40395 C 619.18272 337.08595 593.00321 334.21645 593.00321 334.21645 C 589.54819 330.76145 655.47896 335.93245 659.22196 333.34145 C 666.99498 325.56746 644.83321 326.43795 641.37821 329.02895 C 635.23621 325.28596 627.51871 325.56295 622.81571 328.15395 C 620.5607 322.75993 599.15321 325.0962 587.25321 323.5602 C 583.44418 321.32621 584.07846 320.04395 586.65946 318.65395 C 611.51548 319.70994 636.24496 322.95545 661.22196 321.84145 C 667.97297 313.04045 652.72321 309.72145 643.37821 317.21645 C 637.89219 308.19444 626.67671 316.9232 619.19071 316.0602 C 611.70571 315.1962 615.15946 305.9962 624.65946 307.4352 C 634.16049 308.8752 651.14871 306.84795 654.31571 302.52895 C 657.48171 298.21096 652.42521 293.8362 636.75321 297.9352 C 631.4492 292.7512 619.78571 297.92695 614.31571 299.65395 C 607.0377 295.59396 590.10496 299.08895 584.34696 300.52895 C 578.70996 297.02494 614.00321 291.3102 614.00321 291.3102 C 627.62622 291.0692 635.31021 288.7122 639.62821 287.5602 C 660.22223 276.52219 639.34146 275.3497 628.53446 283.3727 C 621.82647 278.1357 615.45546 283.82545 609.40946 285.84145 C 603.36349 287.85646 591.84696 289.2992 591.84696 288.4352 C 591.84698 287.5712 608.25321 277.4977 608.25321 277.4977 C 608.25322 277.49768 628.40971 276.04245 632.44071 275.46645 C 636.47169 274.89045 657.08596 264.3032 628.97196 271.4352 C 619.18296 272.2992 613.43371 271.74095 609.69071 272.02895 C 587.98569 269.78493 611.72196 267.6852 611.72196 267.6852 C 611.72195 267.68521 642.45371 264.8667 642.81571 263.3727 C 643.41874 251.39071 617.75996 257.0602 617.47196 257.0602 C 617.54595 248.50019 593.56571 257.3482 593.56571 257.0602 C 588.9847 254.36119 596.15946 251.59145 596.15946 251.59145 C 602.49345 250.05644 611.96371 249.5772 614.44071 247.5602 C 614.4407 247.56018 632.31771 247.40295 634.44071 242.65395 C 630.05374 230.55096 596.60721 244.79645 592.12821 246.96645 C 586.0822 246.96646 596.15271 237.19195 596.44071 236.90395 C 596.72873 236.61596 624.07946 235.46695 637.03446 217.90395 C 637.93449 207.21394 621.78446 223.9352 621.78446 223.9352 C 620.57846 210.0712 604.22296 224.81445 594.72196 225.96645 C 585.22195 227.11744 584.94371 221.64295 591.56571 220.77895 C 598.18671 219.91594 605.66646 220.48095 609.40946 210.40395 C 613.15149 200.32694 624.39446 210.9907 626.40946 207.2477 C 628.42447 203.5047 622.37821 200.34145 622.37821 200.34145 C 622.37822 200.34145 630.72171 191.67845 617.19071 191.96645 C 603.65873 192.25445 586.09696 190.2477 586.09696 190.2477 C 586.09697 190.24769 600.19771 184.7722 613.44071 185.0602 C 626.68471 185.34819 619.48371 175.5602 606.81571 175.5602 C 594.14872 175.56019 587.53446 171.2477 587.53446 171.2477 C 594.73247 168.56069 601.93021 165.8722 609.12821 163.1852 C 608.6482 161.17019 608.17071 159.16895 607.69071 157.15395 C 607.6907 157.15395 620.35321 147.0697 602.50321 149.3727 C 584.65321 151.6767 582.62821 151.96645 582.62821 151.96645 C 582.6282 151.96645 546.94746 157.4352 546.65946 157.4352 C 546.37146 157.43519 536.85271 154.5517 546.06571 152.2477 C 555.27873 149.9447 587.82796 143.3322 592.72196 145.0602 C 597.61696 146.78719 592.12096 132.9757 574.84696 131.2477 C 557.57294 129.5207 546.94071 135.5602 546.94071 135.5602 C 546.94072 135.5602 535.70071 131.5152 546.06571 128.0602 C 556.42973 124.60619 572.84696 129.21645 572.84696 129.21645 C 572.84695 129.21645 591.26221 123.7382 576.00321 121.4352 C 560.74421 119.1312 555.93271 123.5067 548.94071 123.7477 C 546.1497 120.2637 572.89671 119.4412 574.56571 116.5602 C 571.74471 111.3762 555.19621 116.5602 545.50321 116.5602 C 541.38022 114.8112 541.10746 111.96545 545.78446 110.21645 C 555.66947 109.83245 564.96196 110.41295 574.84696 110.02895 C 574.55898 104.75095 574.85371 98.494446 574.56571 93.216446 C 562.02771 90.92545 547.32346 94.894196 540.28446 94.560196 C 542.16746 88.801199 569.23921 87.314696 572.25321 85.747696 C 578.52219 77.911693 545.79121 85.747696 545.50321 85.747696 C 539.79022 84.903693 540.13621 81.292696 543.75321 79.122696 C 552.10221 78.162694 570.82546 80.346196 569.40946 74.685196 C 568.32449 69.380493 556.42846 72.220696 551.53446 73.372696 C 546.64048 74.523697 539.44071 73.653946 539.44071 73.653946 C 536.30671 69.434445 567.66521 71.159046 567.37821 67.903946 C 566.96923 64.166645 547.50021 66.740946 540.87821 67.028946 C 535.70421 63.459046 565.73996 61.093796 566.22196 60.685196 C 567.30696 51.114397 546.06546 60.685196 542.03446 60.685196 C 538.00345 60.685197 540.03446 54.653946 540.03446 54.653946 C 540.03447 54.653944 548.38496 50.917246 548.09696 50.341446 C 547.80896 49.765649 541.73546 47.747696 541.15946 47.747696 C 540.58447 47.747694 541.15946 41.122696 541.15946 41.122696 C 541.15947 41.122696 548.07921 35.937196 547.50321 34.497696 C 546.9272 33.058096 539.44071 35.653946 539.44071 35.653946 C 539.44071 33.734547 539.44071 31.823346 539.44071 29.903946 C 539.44071 29.903945 544.92721 29.307546 545.50321 26.716446 C 546.07922 24.125246 538.87821 23.841446 538.87821 23.841446 C 537.91823 13.764847 536.96321 3.699296 536.00321 -6.377304 z M 530.87821 92.278946 L 530.87821 96.278946 C 530.87823 96.278945 520.99846 95.779446 523.40946 94.091446 C 525.82045 92.403444 530.87821 92.639946 530.87821 92.278946 z M 540.03446 97.591446 C 540.27546 97.591446 554.99847 97.698693 554.03446 99.747696 C 553.06946 101.7977 540.28446 103.02895 540.28446 103.02895 L 540.03446 97.591446 z M 539.31571 105.4352 C 539.79771 105.6762 547.05698 105.79669 545.97196 107.1227 C 544.88696 108.4487 540.05671 108.8102 539.81571 108.8102 C 539.57471 108.8102 539.3157 105.43519 539.31571 105.4352 z M 503.40946 115.90395 C 508.07587 116.12581 515.85846 117.39157 528.47196 120.8727 C 528.47196 121.2337 528.83796 126.0562 528.59696 125.9352 C 528.35596 125.8142 500.62896 117.84645 498.09696 117.96645 C 496.51509 118.04207 495.63211 115.53418 503.40946 115.90395 z M 514.65946 127.6852 C 518.84743 127.28787 530.75321 130.2207 530.75321 129.90395 C 530.7532 130.86895 531.37446 135.9262 530.40946 135.6852 C 529.44545 135.4442 511.60146 129.77945 513.40946 128.09145 C 513.63546 127.88045 514.06118 127.74196 514.65946 127.6852 z M 562.22196 138.6852 C 564.36181 138.84907 565.50671 139.27995 564.75321 140.15395 C 561.73921 143.64995 540.90947 146.52894 540.90946 146.52895 L 540.53446 140.15395 C 540.44446 140.15395 555.80243 138.19357 562.22196 138.6852 z M 499.19071 158.46645 C 502.82246 158.34582 511.10721 160.3427 529.19071 167.9977 L 529.31571 172.59145 C 529.31572 172.59145 498.21321 163.15845 497.12821 161.59145 C 496.58571 160.80795 495.55896 158.58707 499.19071 158.46645 z M 559.97196 165.3102 C 561.56567 165.22917 562.35146 165.49645 561.62821 166.3102 C 558.73421 169.5662 543.19071 172.8102 543.19071 172.8102 C 543.19071 172.8102 543.19071 168.71245 543.19071 168.59145 C 543.19071 168.7722 555.19085 165.55329 559.97196 165.3102 z M 492.22196 165.8727 C 497.07421 165.7972 507.62446 168.42645 530.40946 179.21645 C 530.40945 179.33745 530.65546 183.5602 530.53446 183.5602 C 530.41348 183.56019 488.22196 168.71645 488.22196 168.71645 C 488.22196 168.71645 487.36971 165.9482 492.22196 165.8727 z M 568.78446 183.90395 C 571.20306 183.71751 572.43771 183.9037 571.50321 184.7477 C 567.76621 188.1227 543.7977 192.21645 543.31571 192.21645 C 542.83371 192.21645 543.53446 188.3637 543.53446 188.1227 C 543.80596 188.3942 561.52868 184.46326 568.78446 183.90395 z M 501.44071 194.34145 C 509.69821 195.02245 529.56571 204.2097 529.56571 204.02895 C 529.44472 204.51095 529.43671 208.7427 529.31571 208.6227 C 529.19572 208.5017 499.30696 196.1002 498.22196 197.1852 C 497.22946 194.85944 498.68821 194.11445 501.44071 194.34145 z M 563.22196 196.8727 C 565.25068 196.79362 566.38946 196.9217 565.84696 197.40395 C 563.67696 199.33295 543.53446 203.3102 543.53446 203.3102 C 543.53446 203.3102 543.4407 199.57844 543.44071 199.21645 C 543.16921 199.21645 557.1358 197.10993 563.22196 196.8727 z M 561.37821 209.77895 C 563.19223 209.71873 564.30572 209.85795 564.03446 210.3102 C 562.94946 212.1182 544.62822 215.96645 544.62821 215.96645 C 544.62821 215.96645 544.15946 211.8687 544.15946 211.7477 C 544.15946 211.83845 555.93617 209.9596 561.37821 209.77895 z M 491.03446 210.8102 C 496.03634 211.04995 506.59946 213.32095 528.84696 221.40395 L 529.69071 226.34145 C 529.69072 226.34145 486.41346 212.3727 486.53446 212.3727 C 486.59447 212.3727 486.03259 210.57045 491.03446 210.8102 z M 544.59696 221.52895 C 544.59696 221.64995 554.6507 221.8722 553.56571 223.5602 C 552.48071 225.2482 545.12822 225.8727 545.12821 225.8727 C 545.12821 225.8727 544.76698 222.56495 544.59696 221.52895 z M 563.34696 231.21645 C 564.86149 231.39345 565.29146 231.98094 563.78446 233.21645 C 557.75646 238.15945 544.62822 239.1227 544.62821 239.1227 C 544.62821 239.1227 544.62822 233.80518 544.62821 233.6852 C 544.62821 233.7752 558.80337 230.68544 563.34696 231.21645 z M 579.31571 236.21645 C 583.10233 236.33932 581.4652 238.2832 580.44071 239.2477 C 578.39071 241.1767 545.72197 251.52895 545.72196 251.52895 C 545.72196 251.52895 545.47597 244.6622 545.59696 244.0602 C 566.31596 237.7812 575.52909 236.09357 579.31571 236.21645 z M 555.50321 255.7477 C 559.27384 255.4837 562.27022 255.59494 561.37821 256.96645 C 558.58321 259.70945 545.0032 260.1227 545.00321 260.1227 L 545.00321 256.71645 C 547.20871 256.64195 551.73259 256.0117 555.50321 255.7477 z M 569.62821 261.3727 C 571.73981 261.12596 572.64071 261.31445 571.28446 262.27895 C 565.85946 266.13595 545.47197 270.09144 545.47196 270.09145 C 545.47196 270.09145 545.72597 267.31945 545.84696 266.71645 C 546.02771 266.8072 563.29343 262.1129 569.62821 261.3727 z M 580.50321 265.6227 C 583.75076 265.40106 586.24796 265.68495 587.53446 266.6227 C 587.77646 266.6227 586.59569 270.82393 580.56571 272.52895 C 573.81471 271.92595 544.99922 280.46643 544.87821 280.46645 C 544.75821 280.46645 545.22197 276.96643 545.22196 276.96645 C 554.44471 271.45095 570.76057 266.28762 580.50321 265.6227 z M 509.65946 282.02895 C 521.95646 283.35495 526.54896 287.95818 527.84696 289.8102 C 525.10596 294.6202 501.11346 282.00095 509.65946 282.02895 z M 580.34696 282.8727 C 581.14576 282.93424 581.68796 283.30719 581.75321 284.21645 C 580.42721 286.26545 573.37821 285.27895 573.37821 285.27895 C 573.37821 285.36895 577.95057 282.68805 580.34696 282.8727 z M 552.50321 296.3102 C 553.50983 296.20033 554.41865 296.18021 555.06571 296.3102 C 555.92846 296.48351 556.32922 296.9372 555.84696 297.84145 C 553.91796 301.45845 545.47197 300.12269 545.47196 300.1227 L 545.47196 297.59145 C 545.60752 297.72701 549.48336 296.6398 552.50321 296.3102 z M 503.90946 305.7477 C 506.47474 305.65488 508.74121 307.33519 511.09696 308.6852 C 516.40096 307.6002 527.28445 309.52895 527.28446 309.52895 C 527.28446 309.52895 527.28445 313.97946 527.28446 314.34145 C 527.28446 314.58245 513.59323 314.06119 510.62821 312.1852 C 508.09721 312.1852 500.49796 308.09595 501.22196 306.52895 C 502.16021 306.02895 503.05437 305.77863 503.90946 305.7477 z M 559.37821 308.15395 C 561.563 307.97793 562.53695 308.53595 560.90946 310.84145 C 556.56946 316.98945 545.34697 314.46645 545.34696 314.46645 L 544.87821 310.65395 C 548.74009 310.80457 555.7369 308.44732 559.37821 308.15395 z M 519.90946 320.65395 C 523.69959 320.93494 527.15946 322.1852 527.15946 322.1852 C 527.28046 322.4262 529.81645 327.3592 527.28446 328.6852 C 524.75246 330.0112 512.6507 327.64895 511.94071 322.77895 C 513.02571 321.6337 514.49837 321.0504 516.12821 320.77895 C 517.3506 320.57536 518.64609 320.56028 519.90946 320.65395 z M 473.03446 323.0602 C 476.82164 323.56054 480.36121 325.63695 480.25321 325.52895 C 480.2532 325.67295 480.09696 330.15395 480.09696 330.15395 C 480.09696 330.15395 471.88146 327.8637 469.28446 323.2477 C 470.47472 322.92319 471.77207 322.89342 473.03446 323.0602 z M 550.28446 323.59145 C 555.8225 323.6199 562.50194 325.16796 560.78446 327.2477 C 558.49346 330.0197 545.47197 327.49768 545.47196 327.4977 L 545.47196 324.1227 C 546.70771 323.7612 548.43845 323.58196 550.28446 323.59145 z "
+ id="path930" />
+ </g>
+ <g
+ id="g931"
+ transform="matrix(7.059591e-2,0.000000,0.000000,7.059591e-2,571.0972,609.3450)"
+ style="fill:#000000;fill-opacity:1;">
+ <defs
+ id="defs932"
+ style="fill:#000000;fill-opacity:1;" />
+ <sodipodi:namedview
+ id="namedview933"
+ inkscape:zoom="3.07667732"
+ inkscape:cx="420.999993"
+ inkscape:cy="238.500019"
+ inkscape:window-width="1404"
+ inkscape:window-height="1085"
+ inkscape:window-x="134"
+ inkscape:window-y="446"
+ style="fill:#000000;fill-opacity:1;" />
+ <path
+ style="fill:#000000;fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-width:1.25;stroke-linejoin:round;stroke-linecap:round;fill-opacity:1;stroke-dasharray:none;"
+ d="M 536.00321 -6.377304 C 535.13922 3.027496 534.27346 12.436646 533.40946 21.841446 C 530.24248 22.321347 527.07646 22.799146 523.90946 23.278946 C 523.90945 23.278945 530.50746 27.004996 531.65946 30.747696 C 532.81047 34.490494 523.59696 33.341446 523.59696 33.341446 C 523.59695 33.341445 531.08346 39.694396 531.65946 41.997696 C 532.23447 44.300896 521.31571 44.872696 521.31571 44.872696 C 521.31571 44.872698 530.52096 51.473746 531.09696 55.216446 C 531.67296 58.959246 531.09696 60.997696 531.09696 60.997696 C 531.09696 60.997694 515.82346 47.754896 506.03446 51.497696 C 500.94746 54.155395 517.69346 55.384446 528.78446 65.028946 C 528.75846 67.176743 501.86921 58.469896 500.87821 63.872696 C 501.50222 65.376396 529.58846 69.417646 531.65946 73.091446 C 521.39047 73.475449 500.17621 70.818546 500.87821 74.216446 C 498.73222 78.139449 520.91496 75.923696 530.22196 79.122696 C 532.94997 82.222694 532.68671 84.826946 527.94071 85.153946 C 518.9707 80.864947 498.89496 77.677946 498.84696 83.153946 C 498.96895 84.615945 519.58971 83.664696 527.06571 88.622696 C 517.08671 90.892695 483.24846 84.017696 483.03446 87.372696 C 483.99845 88.939694 489.35271 95.816946 498.56571 95.528946 C 507.77873 95.240948 529.09446 99.274946 530.53446 102.15395 C 531.97347 105.03294 502.88071 96.096946 491.94071 101.27895 C 481.0007 106.46195 523.31196 103.31995 530.22196 109.65395 C 537.13197 115.98795 516.40946 109.0602 516.40946 109.0602 C 516.40947 109.0602 487.63371 105.0452 483.31571 107.0602 C 478.9967 109.07619 474.09696 113.6852 474.09696 113.6852 C 474.09696 113.6852 476.96796 119.42995 479.84696 118.27895 C 482.72596 117.12695 478.97196 121.7477 478.97196 121.7477 C 478.97195 121.7477 519.29696 131.51695 528.22196 140.15395 C 537.14695 148.79195 476.97196 126.6227 476.97196 126.6227 C 476.97196 126.62269 452.78646 135.5467 478.40946 136.1227 C 475.46147 140.4357 479.84696 143.02895 479.84696 143.02895 C 479.84696 143.02895 522.46646 151.9627 526.78446 158.8727 C 531.10346 165.78269 497.70796 152.2397 490.22196 148.4977 C 482.73695 144.75469 461.43396 150.8087 461.72196 152.2477 C 462.00997 153.6877 472.09121 155.7192 472.37821 158.3102 C 472.66621 160.9012 459.97196 161.7572 459.97196 164.0602 C 459.97195 166.3642 513.82696 177.5932 528.22196 189.6852 C 542.61695 201.77719 485.90946 175.27895 485.90946 175.27895 C 485.90947 175.27895 489.07646 179.5957 485.90946 180.7477 C 482.74247 181.8987 471.49171 164.62595 453.06571 175.27895 C 449.70971 179.66195 469.15396 183.1407 474.09696 183.6227 C 472.40896 187.9627 470.93696 189.39845 477.84696 193.71645 C 484.75595 198.03545 464.31571 187.3602 464.31571 187.9352 C 464.31571 188.51119 465.75321 195.4352 465.75321 195.4352 C 459.37421 190.2532 451.66371 188.6907 444.44071 193.9977 C 444.4407 193.9977 444.14321 199.17445 451.62821 202.34145 C 447.54121 210.69245 456.24671 208.0997 470.06571 215.8727 C 449.52672 210.50469 447.88271 220.47595 462.56571 222.77895 C 477.2487 225.08195 517.56471 226.52495 527.06571 238.90395 C 536.56671 251.28394 513.56471 234.15145 510.94071 233.71645 C 510.36472 234.00445 509.78446 240.0602 509.78446 240.0602 C 503.64245 236.50518 498.00646 233.3162 490.65946 231.8102 C 490.08347 232.96119 490.20421 234.5967 489.62821 235.7477 C 482.96121 230.93968 477.15296 227.55945 467.47196 227.09145 C 467.08797 228.62744 466.69971 230.18045 466.31571 231.71645 C 466.31573 231.71643 458.24446 221.63945 442.40946 231.71645 C 433.56747 238.05543 475.81196 234.0117 482.72196 241.4977 C 489.63197 248.98271 484.15946 250.1227 484.15946 250.1227 C 478.40147 248.01169 472.66746 245.9212 466.90946 243.8102 C 466.90946 243.8102 446.44871 240.04795 440.69071 244.65395 C 434.93271 249.26095 524.75596 260.4927 527.34696 272.8727 C 529.09397 279.5867 506.24296 265.8422 486.47196 259.9352 C 485.70396 262.14219 484.92746 264.3532 484.15946 266.5602 C 484.15947 266.56018 476.31896 258.66745 467.47196 257.34145 C 467.18397 257.34145 469.19071 265.1227 469.19071 265.1227 C 469.1907 265.12271 447.04371 254.74645 435.81571 260.21645 C 424.58673 265.68645 474.95971 268.5647 479.56571 273.7477 C 484.17171 278.92969 464.29271 270.2927 462.56571 273.7477 C 460.8377 277.20269 436.37146 267.42295 436.65946 272.02895 C 436.94747 276.63593 440.12821 279.21645 440.12821 279.21645 C 440.1282 279.21643 491.08771 284.10795 492.81571 290.15395 C 494.54272 296.19993 464.59696 286.71645 464.59696 286.71645 C 464.59697 286.71645 461.70021 291.01395 464.00321 293.02895 C 466.30621 295.04493 446.74496 281.5102 448.47196 290.4352 C 442.12295 287.90719 425.73146 280.0767 428.03446 286.1227 C 430.33746 292.16871 474.37821 300.8102 474.37821 300.8102 C 474.37822 300.8102 455.07671 302.25895 455.94071 307.15395 C 431.12571 292.03593 431.77096 301.67845 432.34696 301.96645 C 432.92296 302.25445 400.37596 293.90995 424.84696 307.15395 C 449.31895 320.39693 438.09021 318.0847 438.37821 318.3727 C 438.66622 318.66069 440.98546 324.9977 440.40946 324.9977 C 439.83346 324.99771 423.72321 316.35395 418.25321 315.77895 C 412.78221 315.20294 386.86421 322.9682 414.50321 335.0602 C 442.14222 347.15219 459.11921 332.17595 474.37821 333.90395 C 489.63722 335.63094 496.84846 338.2277 495.40946 343.1227 C 493.96947 348.01671 479.80046 327.0772 464.90946 345.1852 C 447.97047 341.83321 436.47796 339.89345 445.22196 352.34145 C 417.55895 342.00346 400.66621 355.49545 435.50321 360.96645 C 469.73622 361.97545 490.78446 352.6227 490.78446 352.6227 C 490.78446 352.62271 496.55946 363.2962 504.90946 355.8102 C 513.25846 348.32518 513.52771 358.6852 513.81571 358.6852 C 514.10272 358.68519 521.87821 355.21645 521.87821 355.21645 C 522.55022 355.21645 523.23746 355.21645 523.90946 355.21645 C 523.90945 378.24845 523.90946 401.2782 523.90946 424.3102 C 533.21845 424.40619 542.50671 424.49545 551.81571 424.59145 C 551.8157 424.59144 542.89046 364.4337 547.78446 356.3727 C 552.67946 348.3117 557.28446 349.46645 557.28446 349.46645 C 557.28445 349.46645 575.42571 354.9242 577.44071 354.0602 C 579.45669 353.1962 577.15171 347.16495 586.94071 348.02895 C 590.10771 346.87694 588.40546 341.4107 591.28446 341.1227 C 594.16349 340.8347 649.72371 356.6562 661.81571 341.6852 C 658.64873 333.33621 647.69471 341.11595 644.81571 341.40395 C 642.22469 341.40395 631.27571 336.22195 624.94071 341.40395 C 619.18272 337.08595 593.00321 334.21645 593.00321 334.21645 C 589.54819 330.76145 655.47896 335.93245 659.22196 333.34145 C 666.99498 325.56746 644.83321 326.43795 641.37821 329.02895 C 635.23621 325.28596 627.51871 325.56295 622.81571 328.15395 C 620.5607 322.75993 599.15321 325.0962 587.25321 323.5602 C 583.44418 321.32621 584.07846 320.04395 586.65946 318.65395 C 611.51548 319.70994 636.24496 322.95545 661.22196 321.84145 C 667.97297 313.04045 652.72321 309.72145 643.37821 317.21645 C 637.89219 308.19444 626.67671 316.9232 619.19071 316.0602 C 611.70571 315.1962 615.15946 305.9962 624.65946 307.4352 C 634.16049 308.8752 651.14871 306.84795 654.31571 302.52895 C 657.48171 298.21096 652.42521 293.8362 636.75321 297.9352 C 631.4492 292.7512 619.78571 297.92695 614.31571 299.65395 C 607.0377 295.59396 590.10496 299.08895 584.34696 300.52895 C 578.70996 297.02494 614.00321 291.3102 614.00321 291.3102 C 627.62622 291.0692 635.31021 288.7122 639.62821 287.5602 C 660.22223 276.52219 639.34146 275.3497 628.53446 283.3727 C 621.82647 278.1357 615.45546 283.82545 609.40946 285.84145 C 603.36349 287.85646 591.84696 289.2992 591.84696 288.4352 C 591.84698 287.5712 608.25321 277.4977 608.25321 277.4977 C 608.25322 277.49768 628.40971 276.04245 632.44071 275.46645 C 636.47169 274.89045 657.08596 264.3032 628.97196 271.4352 C 619.18296 272.2992 613.43371 271.74095 609.69071 272.02895 C 587.98569 269.78493 611.72196 267.6852 611.72196 267.6852 C 611.72195 267.68521 642.45371 264.8667 642.81571 263.3727 C 643.41874 251.39071 617.75996 257.0602 617.47196 257.0602 C 617.54595 248.50019 593.56571 257.3482 593.56571 257.0602 C 588.9847 254.36119 596.15946 251.59145 596.15946 251.59145 C 602.49345 250.05644 611.96371 249.5772 614.44071 247.5602 C 614.4407 247.56018 632.31771 247.40295 634.44071 242.65395 C 630.05374 230.55096 596.60721 244.79645 592.12821 246.96645 C 586.0822 246.96646 596.15271 237.19195 596.44071 236.90395 C 596.72873 236.61596 624.07946 235.46695 637.03446 217.90395 C 637.93449 207.21394 621.78446 223.9352 621.78446 223.9352 C 620.57846 210.0712 604.22296 224.81445 594.72196 225.96645 C 585.22195 227.11744 584.94371 221.64295 591.56571 220.77895 C 598.18671 219.91594 605.66646 220.48095 609.40946 210.40395 C 613.15149 200.32694 624.39446 210.9907 626.40946 207.2477 C 628.42447 203.5047 622.37821 200.34145 622.37821 200.34145 C 622.37822 200.34145 630.72171 191.67845 617.19071 191.96645 C 603.65873 192.25445 586.09696 190.2477 586.09696 190.2477 C 586.09697 190.24769 600.19771 184.7722 613.44071 185.0602 C 626.68471 185.34819 619.48371 175.5602 606.81571 175.5602 C 594.14872 175.56019 587.53446 171.2477 587.53446 171.2477 C 594.73247 168.56069 601.93021 165.8722 609.12821 163.1852 C 608.6482 161.17019 608.17071 159.16895 607.69071 157.15395 C 607.6907 157.15395 620.35321 147.0697 602.50321 149.3727 C 584.65321 151.6767 582.62821 151.96645 582.62821 151.96645 C 582.6282 151.96645 546.94746 157.4352 546.65946 157.4352 C 546.37146 157.43519 536.85271 154.5517 546.06571 152.2477 C 555.27873 149.9447 587.82796 143.3322 592.72196 145.0602 C 597.61696 146.78719 592.12096 132.9757 574.84696 131.2477 C 557.57294 129.5207 546.94071 135.5602 546.94071 135.5602 C 546.94072 135.5602 535.70071 131.5152 546.06571 128.0602 C 556.42973 124.60619 572.84696 129.21645 572.84696 129.21645 C 572.84695 129.21645 591.26221 123.7382 576.00321 121.4352 C 560.74421 119.1312 555.93271 123.5067 548.94071 123.7477 C 546.1497 120.2637 572.89671 119.4412 574.56571 116.5602 C 571.74471 111.3762 555.19621 116.5602 545.50321 116.5602 C 541.38022 114.8112 541.10746 111.96545 545.78446 110.21645 C 555.66947 109.83245 564.96196 110.41295 574.84696 110.02895 C 574.55898 104.75095 574.85371 98.494446 574.56571 93.216446 C 562.02771 90.92545 547.32346 94.894196 540.28446 94.560196 C 542.16746 88.801199 569.23921 87.314696 572.25321 85.747696 C 578.52219 77.911693 545.79121 85.747696 545.50321 85.747696 C 539.79022 84.903693 540.13621 81.292696 543.75321 79.122696 C 552.10221 78.162694 570.82546 80.346196 569.40946 74.685196 C 568.32449 69.380493 556.42846 72.220696 551.53446 73.372696 C 546.64048 74.523697 539.44071 73.653946 539.44071 73.653946 C 536.30671 69.434445 567.66521 71.159046 567.37821 67.903946 C 566.96923 64.166645 547.50021 66.740946 540.87821 67.028946 C 535.70421 63.459046 565.73996 61.093796 566.22196 60.685196 C 567.30696 51.114397 546.06546 60.685196 542.03446 60.685196 C 538.00345 60.685197 540.03446 54.653946 540.03446 54.653946 C 540.03447 54.653944 548.38496 50.917246 548.09696 50.341446 C 547.80896 49.765649 541.73546 47.747696 541.15946 47.747696 C 540.58447 47.747694 541.15946 41.122696 541.15946 41.122696 C 541.15947 41.122696 548.07921 35.937196 547.50321 34.497696 C 546.9272 33.058096 539.44071 35.653946 539.44071 35.653946 C 539.44071 33.734547 539.44071 31.823346 539.44071 29.903946 C 539.44071 29.903945 544.92721 29.307546 545.50321 26.716446 C 546.07922 24.125246 538.87821 23.841446 538.87821 23.841446 C 537.91823 13.764847 536.96321 3.699296 536.00321 -6.377304 z M 530.87821 92.278946 L 530.87821 96.278946 C 530.87823 96.278945 520.99846 95.779446 523.40946 94.091446 C 525.82045 92.403444 530.87821 92.639946 530.87821 92.278946 z M 540.03446 97.591446 C 540.27546 97.591446 554.99847 97.698693 554.03446 99.747696 C 553.06946 101.7977 540.28446 103.02895 540.28446 103.02895 L 540.03446 97.591446 z M 539.31571 105.4352 C 539.79771 105.6762 547.05698 105.79669 545.97196 107.1227 C 544.88696 108.4487 540.05671 108.8102 539.81571 108.8102 C 539.57471 108.8102 539.3157 105.43519 539.31571 105.4352 z M 503.40946 115.90395 C 508.07587 116.12581 515.85846 117.39157 528.47196 120.8727 C 528.47196 121.2337 528.83796 126.0562 528.59696 125.9352 C 528.35596 125.8142 500.62896 117.84645 498.09696 117.96645 C 496.51509 118.04207 495.63211 115.53418 503.40946 115.90395 z M 514.65946 127.6852 C 518.84743 127.28787 530.75321 130.2207 530.75321 129.90395 C 530.7532 130.86895 531.37446 135.9262 530.40946 135.6852 C 529.44545 135.4442 511.60146 129.77945 513.40946 128.09145 C 513.63546 127.88045 514.06118 127.74196 514.65946 127.6852 z M 562.22196 138.6852 C 564.36181 138.84907 565.50671 139.27995 564.75321 140.15395 C 561.73921 143.64995 540.90947 146.52894 540.90946 146.52895 L 540.53446 140.15395 C 540.44446 140.15395 555.80243 138.19357 562.22196 138.6852 z M 499.19071 158.46645 C 502.82246 158.34582 511.10721 160.3427 529.19071 167.9977 L 529.31571 172.59145 C 529.31572 172.59145 498.21321 163.15845 497.12821 161.59145 C 496.58571 160.80795 495.55896 158.58707 499.19071 158.46645 z M 559.97196 165.3102 C 561.56567 165.22917 562.35146 165.49645 561.62821 166.3102 C 558.73421 169.5662 543.19071 172.8102 543.19071 172.8102 C 543.19071 172.8102 543.19071 168.71245 543.19071 168.59145 C 543.19071 168.7722 555.19085 165.55329 559.97196 165.3102 z M 492.22196 165.8727 C 497.07421 165.7972 507.62446 168.42645 530.40946 179.21645 C 530.40945 179.33745 530.65546 183.5602 530.53446 183.5602 C 530.41348 183.56019 488.22196 168.71645 488.22196 168.71645 C 488.22196 168.71645 487.36971 165.9482 492.22196 165.8727 z M 568.78446 183.90395 C 571.20306 183.71751 572.43771 183.9037 571.50321 184.7477 C 567.76621 188.1227 543.7977 192.21645 543.31571 192.21645 C 542.83371 192.21645 543.53446 188.3637 543.53446 188.1227 C 543.80596 188.3942 561.52868 184.46326 568.78446 183.90395 z M 501.44071 194.34145 C 509.69821 195.02245 529.56571 204.2097 529.56571 204.02895 C 529.44472 204.51095 529.43671 208.7427 529.31571 208.6227 C 529.19572 208.5017 499.30696 196.1002 498.22196 197.1852 C 497.22946 194.85944 498.68821 194.11445 501.44071 194.34145 z M 563.22196 196.8727 C 565.25068 196.79362 566.38946 196.9217 565.84696 197.40395 C 563.67696 199.33295 543.53446 203.3102 543.53446 203.3102 C 543.53446 203.3102 543.4407 199.57844 543.44071 199.21645 C 543.16921 199.21645 557.1358 197.10993 563.22196 196.8727 z M 561.37821 209.77895 C 563.19223 209.71873 564.30572 209.85795 564.03446 210.3102 C 562.94946 212.1182 544.62822 215.96645 544.62821 215.96645 C 544.62821 215.96645 544.15946 211.8687 544.15946 211.7477 C 544.15946 211.83845 555.93617 209.9596 561.37821 209.77895 z M 491.03446 210.8102 C 496.03634 211.04995 506.59946 213.32095 528.84696 221.40395 L 529.69071 226.34145 C 529.69072 226.34145 486.41346 212.3727 486.53446 212.3727 C 486.59447 212.3727 486.03259 210.57045 491.03446 210.8102 z M 544.59696 221.52895 C 544.59696 221.64995 554.6507 221.8722 553.56571 223.5602 C 552.48071 225.2482 545.12822 225.8727 545.12821 225.8727 C 545.12821 225.8727 544.76698 222.56495 544.59696 221.52895 z M 563.34696 231.21645 C 564.86149 231.39345 565.29146 231.98094 563.78446 233.21645 C 557.75646 238.15945 544.62822 239.1227 544.62821 239.1227 C 544.62821 239.1227 544.62822 233.80518 544.62821 233.6852 C 544.62821 233.7752 558.80337 230.68544 563.34696 231.21645 z M 579.31571 236.21645 C 583.10233 236.33932 581.4652 238.2832 580.44071 239.2477 C 578.39071 241.1767 545.72197 251.52895 545.72196 251.52895 C 545.72196 251.52895 545.47597 244.6622 545.59696 244.0602 C 566.31596 237.7812 575.52909 236.09357 579.31571 236.21645 z M 555.50321 255.7477 C 559.27384 255.4837 562.27022 255.59494 561.37821 256.96645 C 558.58321 259.70945 545.0032 260.1227 545.00321 260.1227 L 545.00321 256.71645 C 547.20871 256.64195 551.73259 256.0117 555.50321 255.7477 z M 569.62821 261.3727 C 571.73981 261.12596 572.64071 261.31445 571.28446 262.27895 C 565.85946 266.13595 545.47197 270.09144 545.47196 270.09145 C 545.47196 270.09145 545.72597 267.31945 545.84696 266.71645 C 546.02771 266.8072 563.29343 262.1129 569.62821 261.3727 z M 580.50321 265.6227 C 583.75076 265.40106 586.24796 265.68495 587.53446 266.6227 C 587.77646 266.6227 586.59569 270.82393 580.56571 272.52895 C 573.81471 271.92595 544.99922 280.46643 544.87821 280.46645 C 544.75821 280.46645 545.22197 276.96643 545.22196 276.96645 C 554.44471 271.45095 570.76057 266.28762 580.50321 265.6227 z M 509.65946 282.02895 C 521.95646 283.35495 526.54896 287.95818 527.84696 289.8102 C 525.10596 294.6202 501.11346 282.00095 509.65946 282.02895 z M 580.34696 282.8727 C 581.14576 282.93424 581.68796 283.30719 581.75321 284.21645 C 580.42721 286.26545 573.37821 285.27895 573.37821 285.27895 C 573.37821 285.36895 577.95057 282.68805 580.34696 282.8727 z M 552.50321 296.3102 C 553.50983 296.20033 554.41865 296.18021 555.06571 296.3102 C 555.92846 296.48351 556.32922 296.9372 555.84696 297.84145 C 553.91796 301.45845 545.47197 300.12269 545.47196 300.1227 L 545.47196 297.59145 C 545.60752 297.72701 549.48336 296.6398 552.50321 296.3102 z M 503.90946 305.7477 C 506.47474 305.65488 508.74121 307.33519 511.09696 308.6852 C 516.40096 307.6002 527.28445 309.52895 527.28446 309.52895 C 527.28446 309.52895 527.28445 313.97946 527.28446 314.34145 C 527.28446 314.58245 513.59323 314.06119 510.62821 312.1852 C 508.09721 312.1852 500.49796 308.09595 501.22196 306.52895 C 502.16021 306.02895 503.05437 305.77863 503.90946 305.7477 z M 559.37821 308.15395 C 561.563 307.97793 562.53695 308.53595 560.90946 310.84145 C 556.56946 316.98945 545.34697 314.46645 545.34696 314.46645 L 544.87821 310.65395 C 548.74009 310.80457 555.7369 308.44732 559.37821 308.15395 z M 519.90946 320.65395 C 523.69959 320.93494 527.15946 322.1852 527.15946 322.1852 C 527.28046 322.4262 529.81645 327.3592 527.28446 328.6852 C 524.75246 330.0112 512.6507 327.64895 511.94071 322.77895 C 513.02571 321.6337 514.49837 321.0504 516.12821 320.77895 C 517.3506 320.57536 518.64609 320.56028 519.90946 320.65395 z M 473.03446 323.0602 C 476.82164 323.56054 480.36121 325.63695 480.25321 325.52895 C 480.2532 325.67295 480.09696 330.15395 480.09696 330.15395 C 480.09696 330.15395 471.88146 327.8637 469.28446 323.2477 C 470.47472 322.92319 471.77207 322.89342 473.03446 323.0602 z M 550.28446 323.59145 C 555.8225 323.6199 562.50194 325.16796 560.78446 327.2477 C 558.49346 330.0197 545.47197 327.49768 545.47196 327.4977 L 545.47196 324.1227 C 546.70771 323.7612 548.43845 323.58196 550.28446 323.59145 z "
+ id="path934" />
+ </g>
+ <g
+ id="g935"
+ transform="matrix(7.059591e-2,0.000000,0.000000,7.059591e-2,601.0972,614.3450)"
+ style="fill:#000000;fill-opacity:1;">
+ <defs
+ id="defs936"
+ style="fill:#000000;fill-opacity:1;" />
+ <sodipodi:namedview
+ id="namedview937"
+ inkscape:zoom="3.07667732"
+ inkscape:cx="420.999993"
+ inkscape:cy="238.500019"
+ inkscape:window-width="1404"
+ inkscape:window-height="1085"
+ inkscape:window-x="134"
+ inkscape:window-y="446"
+ style="fill:#000000;fill-opacity:1;" />
+ <path
+ style="fill:#000000;fill-rule:evenodd;stroke:black;stroke-opacity:1;stroke-width:1.25;stroke-linejoin:round;stroke-linecap:round;fill-opacity:1;stroke-dasharray:none;"
+ d="M 536.00321 -6.377304 C 535.13922 3.027496 534.27346 12.436646 533.40946 21.841446 C 530.24248 22.321347 527.07646 22.799146 523.90946 23.278946 C 523.90945 23.278945 530.50746 27.004996 531.65946 30.747696 C 532.81047 34.490494 523.59696 33.341446 523.59696 33.341446 C 523.59695 33.341445 531.08346 39.694396 531.65946 41.997696 C 532.23447 44.300896 521.31571 44.872696 521.31571 44.872696 C 521.31571 44.872698 530.52096 51.473746 531.09696 55.216446 C 531.67296 58.959246 531.09696 60.997696 531.09696 60.997696 C 531.09696 60.997694 515.82346 47.754896 506.03446 51.497696 C 500.94746 54.155395 517.69346 55.384446 528.78446 65.028946 C 528.75846 67.176743 501.86921 58.469896 500.87821 63.872696 C 501.50222 65.376396 529.58846 69.417646 531.65946 73.091446 C 521.39047 73.475449 500.17621 70.818546 500.87821 74.216446 C 498.73222 78.139449 520.91496 75.923696 530.22196 79.122696 C 532.94997 82.222694 532.68671 84.826946 527.94071 85.153946 C 518.9707 80.864947 498.89496 77.677946 498.84696 83.153946 C 498.96895 84.615945 519.58971 83.664696 527.06571 88.622696 C 517.08671 90.892695 483.24846 84.017696 483.03446 87.372696 C 483.99845 88.939694 489.35271 95.816946 498.56571 95.528946 C 507.77873 95.240948 529.09446 99.274946 530.53446 102.15395 C 531.97347 105.03294 502.88071 96.096946 491.94071 101.27895 C 481.0007 106.46195 523.31196 103.31995 530.22196 109.65395 C 537.13197 115.98795 516.40946 109.0602 516.40946 109.0602 C 516.40947 109.0602 487.63371 105.0452 483.31571 107.0602 C 478.9967 109.07619 474.09696 113.6852 474.09696 113.6852 C 474.09696 113.6852 476.96796 119.42995 479.84696 118.27895 C 482.72596 117.12695 478.97196 121.7477 478.97196 121.7477 C 478.97195 121.7477 519.29696 131.51695 528.22196 140.15395 C 537.14695 148.79195 476.97196 126.6227 476.97196 126.6227 C 476.97196 126.62269 452.78646 135.5467 478.40946 136.1227 C 475.46147 140.4357 479.84696 143.02895 479.84696 143.02895 C 479.84696 143.02895 522.46646 151.9627 526.78446 158.8727 C 531.10346 165.78269 497.70796 152.2397 490.22196 148.4977 C 482.73695 144.75469 461.43396 150.8087 461.72196 152.2477 C 462.00997 153.6877 472.09121 155.7192 472.37821 158.3102 C 472.66621 160.9012 459.97196 161.7572 459.97196 164.0602 C 459.97195 166.3642 513.82696 177.5932 528.22196 189.6852 C 542.61695 201.77719 485.90946 175.27895 485.90946 175.27895 C 485.90947 175.27895 489.07646 179.5957 485.90946 180.7477 C 482.74247 181.8987 471.49171 164.62595 453.06571 175.27895 C 449.70971 179.66195 469.15396 183.1407 474.09696 183.6227 C 472.40896 187.9627 470.93696 189.39845 477.84696 193.71645 C 484.75595 198.03545 464.31571 187.3602 464.31571 187.9352 C 464.31571 188.51119 465.75321 195.4352 465.75321 195.4352 C 459.37421 190.2532 451.66371 188.6907 444.44071 193.9977 C 444.4407 193.9977 444.14321 199.17445 451.62821 202.34145 C 447.54121 210.69245 456.24671 208.0997 470.06571 215.8727 C 449.52672 210.50469 447.88271 220.47595 462.56571 222.77895 C 477.2487 225.08195 517.56471 226.52495 527.06571 238.90395 C 536.56671 251.28394 513.56471 234.15145 510.94071 233.71645 C 510.36472 234.00445 509.78446 240.0602 509.78446 240.0602 C 503.64245 236.50518 498.00646 233.3162 490.65946 231.8102 C 490.08347 232.96119 490.20421 234.5967 489.62821 235.7477 C 482.96121 230.93968 477.15296 227.55945 467.47196 227.09145 C 467.08797 228.62744 466.69971 230.18045 466.31571 231.71645 C 466.31573 231.71643 458.24446 221.63945 442.40946 231.71645 C 433.56747 238.05543 475.81196 234.0117 482.72196 241.4977 C 489.63197 248.98271 484.15946 250.1227 484.15946 250.1227 C 478.40147 248.01169 472.66746 245.9212 466.90946 243.8102 C 466.90946 243.8102 446.44871 240.04795 440.69071 244.65395 C 434.93271 249.26095 524.75596 260.4927 527.34696 272.8727 C 529.09397 279.5867 506.24296 265.8422 486.47196 259.9352 C 485.70396 262.14219 484.92746 264.3532 484.15946 266.5602 C 484.15947 266.56018 476.31896 258.66745 467.47196 257.34145 C 467.18397 257.34145 469.19071 265.1227 469.19071 265.1227 C 469.1907 265.12271 447.04371 254.74645 435.81571 260.21645 C 424.58673 265.68645 474.95971 268.5647 479.56571 273.7477 C 484.17171 278.92969 464.29271 270.2927 462.56571 273.7477 C 460.8377 277.20269 436.37146 267.42295 436.65946 272.02895 C 436.94747 276.63593 440.12821 279.21645 440.12821 279.21645 C 440.1282 279.21643 491.08771 284.10795 492.81571 290.15395 C 494.54272 296.19993 464.59696 286.71645 464.59696 286.71645 C 464.59697 286.71645 461.70021 291.01395 464.00321 293.02895 C 466.30621 295.04493 446.74496 281.5102 448.47196 290.4352 C 442.12295 287.90719 425.73146 280.0767 428.03446 286.1227 C 430.33746 292.16871 474.37821 300.8102 474.37821 300.8102 C 474.37822 300.8102 455.07671 302.25895 455.94071 307.15395 C 431.12571 292.03593 431.77096 301.67845 432.34696 301.96645 C 432.92296 302.25445 400.37596 293.90995 424.84696 307.15395 C 449.31895 320.39693 438.09021 318.0847 438.37821 318.3727 C 438.66622 318.66069 440.98546 324.9977 440.40946 324.9977 C 439.83346 324.99771 423.72321 316.35395 418.25321 315.77895 C 412.78221 315.20294 386.86421 322.9682 414.50321 335.0602 C 442.14222 347.15219 459.11921 332.17595 474.37821 333.90395 C 489.63722 335.63094 496.84846 338.2277 495.40946 343.1227 C 493.96947 348.01671 479.80046 327.0772 464.90946 345.1852 C 447.97047 341.83321 436.47796 339.89345 445.22196 352.34145 C 417.55895 342.00346 400.66621 355.49545 435.50321 360.96645 C 469.73622 361.97545 490.78446 352.6227 490.78446 352.6227 C 490.78446 352.62271 496.55946 363.2962 504.90946 355.8102 C 513.25846 348.32518 513.52771 358.6852 513.81571 358.6852 C 514.10272 358.68519 521.87821 355.21645 521.87821 355.21645 C 522.55022 355.21645 523.23746 355.21645 523.90946 355.21645 C 523.90945 378.24845 523.90946 401.2782 523.90946 424.3102 C 533.21845 424.40619 542.50671 424.49545 551.81571 424.59145 C 551.8157 424.59144 542.89046 364.4337 547.78446 356.3727 C 552.67946 348.3117 557.28446 349.46645 557.28446 349.46645 C 557.28445 349.46645 575.42571 354.9242 577.44071 354.0602 C 579.45669 353.1962 577.15171 347.16495 586.94071 348.02895 C 590.10771 346.87694 588.40546 341.4107 591.28446 341.1227 C 594.16349 340.8347 649.72371 356.6562 661.81571 341.6852 C 658.64873 333.33621 647.69471 341.11595 644.81571 341.40395 C 642.22469 341.40395 631.27571 336.22195 624.94071 341.40395 C 619.18272 337.08595 593.00321 334.21645 593.00321 334.21645 C 589.54819 330.76145 655.47896 335.93245 659.22196 333.34145 C 666.99498 325.56746 644.83321 326.43795 641.37821 329.02895 C 635.23621 325.28596 627.51871 325.56295 622.81571 328.15395 C 620.5607 322.75993 599.15321 325.0962 587.25321 323.5602 C 583.44418 321.32621 584.07846 320.04395 586.65946 318.65395 C 611.51548 319.70994 636.24496 322.95545 661.22196 321.84145 C 667.97297 313.04045 652.72321 309.72145 643.37821 317.21645 C 637.89219 308.19444 626.67671 316.9232 619.19071 316.0602 C 611.70571 315.1962 615.15946 305.9962 624.65946 307.4352 C 634.16049 308.8752 651.14871 306.84795 654.31571 302.52895 C 657.48171 298.21096 652.42521 293.8362 636.75321 297.9352 C 631.4492 292.7512 619.78571 297.92695 614.31571 299.65395 C 607.0377 295.59396 590.10496 299.08895 584.34696 300.52895 C 578.70996 297.02494 614.00321 291.3102 614.00321 291.3102 C 627.62622 291.0692 635.31021 288.7122 639.62821 287.5602 C 660.22223 276.52219 639.34146 275.3497 628.53446 283.3727 C 621.82647 278.1357 615.45546 283.82545 609.40946 285.84145 C 603.36349 287.85646 591.84696 289.2992 591.84696 288.4352 C 591.84698 287.5712 608.25321 277.4977 608.25321 277.4977 C 608.25322 277.49768 628.40971 276.04245 632.44071 275.46645 C 636.47169 274.89045 657.08596 264.3032 628.97196 271.4352 C 619.18296 272.2992 613.43371 271.74095 609.69071 272.02895 C 587.98569 269.78493 611.72196 267.6852 611.72196 267.6852 C 611.72195 267.68521 642.45371 264.8667 642.81571 263.3727 C 643.41874 251.39071 617.75996 257.0602 617.47196 257.0602 C 617.54595 248.50019 593.56571 257.3482 593.56571 257.0602 C 588.9847 254.36119 596.15946 251.59145 596.15946 251.59145 C 602.49345 250.05644 611.96371 249.5772 614.44071 247.5602 C 614.4407 247.56018 632.31771 247.40295 634.44071 242.65395 C 630.05374 230.55096 596.60721 244.79645 592.12821 246.96645 C 586.0822 246.96646 596.15271 237.19195 596.44071 236.90395 C 596.72873 236.61596 624.07946 235.46695 637.03446 217.90395 C 637.93449 207.21394 621.78446 223.9352 621.78446 223.9352 C 620.57846 210.0712 604.22296 224.81445 594.72196 225.96645 C 585.22195 227.11744 584.94371 221.64295 591.56571 220.77895 C 598.18671 219.91594 605.66646 220.48095 609.40946 210.40395 C 613.15149 200.32694 624.39446 210.9907 626.40946 207.2477 C 628.42447 203.5047 622.37821 200.34145 622.37821 200.34145 C 622.37822 200.34145 630.72171 191.67845 617.19071 191.96645 C 603.65873 192.25445 586.09696 190.2477 586.09696 190.2477 C 586.09697 190.24769 600.19771 184.7722 613.44071 185.0602 C 626.68471 185.34819 619.48371 175.5602 606.81571 175.5602 C 594.14872 175.56019 587.53446 171.2477 587.53446 171.2477 C 594.73247 168.56069 601.93021 165.8722 609.12821 163.1852 C 608.6482 161.17019 608.17071 159.16895 607.69071 157.15395 C 607.6907 157.15395 620.35321 147.0697 602.50321 149.3727 C 584.65321 151.6767 582.62821 151.96645 582.62821 151.96645 C 582.6282 151.96645 546.94746 157.4352 546.65946 157.4352 C 546.37146 157.43519 536.85271 154.5517 546.06571 152.2477 C 555.27873 149.9447 587.82796 143.3322 592.72196 145.0602 C 597.61696 146.78719 592.12096 132.9757 574.84696 131.2477 C 557.57294 129.5207 546.94071 135.5602 546.94071 135.5602 C 546.94072 135.5602 535.70071 131.5152 546.06571 128.0602 C 556.42973 124.60619 572.84696 129.21645 572.84696 129.21645 C 572.84695 129.21645 591.26221 123.7382 576.00321 121.4352 C 560.74421 119.1312 555.93271 123.5067 548.94071 123.7477 C 546.1497 120.2637 572.89671 119.4412 574.56571 116.5602 C 571.74471 111.3762 555.19621 116.5602 545.50321 116.5602 C 541.38022 114.8112 541.10746 111.96545 545.78446 110.21645 C 555.66947 109.83245 564.96196 110.41295 574.84696 110.02895 C 574.55898 104.75095 574.85371 98.494446 574.56571 93.216446 C 562.02771 90.92545 547.32346 94.894196 540.28446 94.560196 C 542.16746 88.801199 569.23921 87.314696 572.25321 85.747696 C 578.52219 77.911693 545.79121 85.747696 545.50321 85.747696 C 539.79022 84.903693 540.13621 81.292696 543.75321 79.122696 C 552.10221 78.162694 570.82546 80.346196 569.40946 74.685196 C 568.32449 69.380493 556.42846 72.220696 551.53446 73.372696 C 546.64048 74.523697 539.44071 73.653946 539.44071 73.653946 C 536.30671 69.434445 567.66521 71.159046 567.37821 67.903946 C 566.96923 64.166645 547.50021 66.740946 540.87821 67.028946 C 535.70421 63.459046 565.73996 61.093796 566.22196 60.685196 C 567.30696 51.114397 546.06546 60.685196 542.03446 60.685196 C 538.00345 60.685197 540.03446 54.653946 540.03446 54.653946 C 540.03447 54.653944 548.38496 50.917246 548.09696 50.341446 C 547.80896 49.765649 541.73546 47.747696 541.15946 47.747696 C 540.58447 47.747694 541.15946 41.122696 541.15946 41.122696 C 541.15947 41.122696 548.07921 35.937196 547.50321 34.497696 C 546.9272 33.058096 539.44071 35.653946 539.44071 35.653946 C 539.44071 33.734547 539.44071 31.823346 539.44071 29.903946 C 539.44071 29.903945 544.92721 29.307546 545.50321 26.716446 C 546.07922 24.125246 538.87821 23.841446 538.87821 23.841446 C 537.91823 13.764847 536.96321 3.699296 536.00321 -6.377304 z M 530.87821 92.278946 L 530.87821 96.278946 C 530.87823 96.278945 520.99846 95.779446 523.40946 94.091446 C 525.82045 92.403444 530.87821 92.639946 530.87821 92.278946 z M 540.03446 97.591446 C 540.27546 97.591446 554.99847 97.698693 554.03446 99.747696 C 553.06946 101.7977 540.28446 103.02895 540.28446 103.02895 L 540.03446 97.591446 z M 539.31571 105.4352 C 539.79771 105.6762 547.05698 105.79669 545.97196 107.1227 C 544.88696 108.4487 540.05671 108.8102 539.81571 108.8102 C 539.57471 108.8102 539.3157 105.43519 539.31571 105.4352 z M 503.40946 115.90395 C 508.07587 116.12581 515.85846 117.39157 528.47196 120.8727 C 528.47196 121.2337 528.83796 126.0562 528.59696 125.9352 C 528.35596 125.8142 500.62896 117.84645 498.09696 117.96645 C 496.51509 118.04207 495.63211 115.53418 503.40946 115.90395 z M 514.65946 127.6852 C 518.84743 127.28787 530.75321 130.2207 530.75321 129.90395 C 530.7532 130.86895 531.37446 135.9262 530.40946 135.6852 C 529.44545 135.4442 511.60146 129.77945 513.40946 128.09145 C 513.63546 127.88045 514.06118 127.74196 514.65946 127.6852 z M 562.22196 138.6852 C 564.36181 138.84907 565.50671 139.27995 564.75321 140.15395 C 561.73921 143.64995 540.90947 146.52894 540.90946 146.52895 L 540.53446 140.15395 C 540.44446 140.15395 555.80243 138.19357 562.22196 138.6852 z M 499.19071 158.46645 C 502.82246 158.34582 511.10721 160.3427 529.19071 167.9977 L 529.31571 172.59145 C 529.31572 172.59145 498.21321 163.15845 497.12821 161.59145 C 496.58571 160.80795 495.55896 158.58707 499.19071 158.46645 z M 559.97196 165.3102 C 561.56567 165.22917 562.35146 165.49645 561.62821 166.3102 C 558.73421 169.5662 543.19071 172.8102 543.19071 172.8102 C 543.19071 172.8102 543.19071 168.71245 543.19071 168.59145 C 543.19071 168.7722 555.19085 165.55329 559.97196 165.3102 z M 492.22196 165.8727 C 497.07421 165.7972 507.62446 168.42645 530.40946 179.21645 C 530.40945 179.33745 530.65546 183.5602 530.53446 183.5602 C 530.41348 183.56019 488.22196 168.71645 488.22196 168.71645 C 488.22196 168.71645 487.36971 165.9482 492.22196 165.8727 z M 568.78446 183.90395 C 571.20306 183.71751 572.43771 183.9037 571.50321 184.7477 C 567.76621 188.1227 543.7977 192.21645 543.31571 192.21645 C 542.83371 192.21645 543.53446 188.3637 543.53446 188.1227 C 543.80596 188.3942 561.52868 184.46326 568.78446 183.90395 z M 501.44071 194.34145 C 509.69821 195.02245 529.56571 204.2097 529.56571 204.02895 C 529.44472 204.51095 529.43671 208.7427 529.31571 208.6227 C 529.19572 208.5017 499.30696 196.1002 498.22196 197.1852 C 497.22946 194.85944 498.68821 194.11445 501.44071 194.34145 z M 563.22196 196.8727 C 565.25068 196.79362 566.38946 196.9217 565.84696 197.40395 C 563.67696 199.33295 543.53446 203.3102 543.53446 203.3102 C 543.53446 203.3102 543.4407 199.57844 543.44071 199.21645 C 543.16921 199.21645 557.1358 197.10993 563.22196 196.8727 z M 561.37821 209.77895 C 563.19223 209.71873 564.30572 209.85795 564.03446 210.3102 C 562.94946 212.1182 544.62822 215.96645 544.62821 215.96645 C 544.62821 215.96645 544.15946 211.8687 544.15946 211.7477 C 544.15946 211.83845 555.93617 209.9596 561.37821 209.77895 z M 491.03446 210.8102 C 496.03634 211.04995 506.59946 213.32095 528.84696 221.40395 L 529.69071 226.34145 C 529.69072 226.34145 486.41346 212.3727 486.53446 212.3727 C 486.59447 212.3727 486.03259 210.57045 491.03446 210.8102 z M 544.59696 221.52895 C 544.59696 221.64995 554.6507 221.8722 553.56571 223.5602 C 552.48071 225.2482 545.12822 225.8727 545.12821 225.8727 C 545.12821 225.8727 544.76698 222.56495 544.59696 221.52895 z M 563.34696 231.21645 C 564.86149 231.39345 565.29146 231.98094 563.78446 233.21645 C 557.75646 238.15945 544.62822 239.1227 544.62821 239.1227 C 544.62821 239.1227 544.62822 233.80518 544.62821 233.6852 C 544.62821 233.7752 558.80337 230.68544 563.34696 231.21645 z M 579.31571 236.21645 C 583.10233 236.33932 581.4652 238.2832 580.44071 239.2477 C 578.39071 241.1767 545.72197 251.52895 545.72196 251.52895 C 545.72196 251.52895 545.47597 244.6622 545.59696 244.0602 C 566.31596 237.7812 575.52909 236.09357 579.31571 236.21645 z M 555.50321 255.7477 C 559.27384 255.4837 562.27022 255.59494 561.37821 256.96645 C 558.58321 259.70945 545.0032 260.1227 545.00321 260.1227 L 545.00321 256.71645 C 547.20871 256.64195 551.73259 256.0117 555.50321 255.7477 z M 569.62821 261.3727 C 571.73981 261.12596 572.64071 261.31445 571.28446 262.27895 C 565.85946 266.13595 545.47197 270.09144 545.47196 270.09145 C 545.47196 270.09145 545.72597 267.31945 545.84696 266.71645 C 546.02771 266.8072 563.29343 262.1129 569.62821 261.3727 z M 580.50321 265.6227 C 583.75076 265.40106 586.24796 265.68495 587.53446 266.6227 C 587.77646 266.6227 586.59569 270.82393 580.56571 272.52895 C 573.81471 271.92595 544.99922 280.46643 544.87821 280.46645 C 544.75821 280.46645 545.22197 276.96643 545.22196 276.96645 C 554.44471 271.45095 570.76057 266.28762 580.50321 265.6227 z M 509.65946 282.02895 C 521.95646 283.35495 526.54896 287.95818 527.84696 289.8102 C 525.10596 294.6202 501.11346 282.00095 509.65946 282.02895 z M 580.34696 282.8727 C 581.14576 282.93424 581.68796 283.30719 581.75321 284.21645 C 580.42721 286.26545 573.37821 285.27895 573.37821 285.27895 C 573.37821 285.36895 577.95057 282.68805 580.34696 282.8727 z M 552.50321 296.3102 C 553.50983 296.20033 554.41865 296.18021 555.06571 296.3102 C 555.92846 296.48351 556.32922 296.9372 555.84696 297.84145 C 553.91796 301.45845 545.47197 300.12269 545.47196 300.1227 L 545.47196 297.59145 C 545.60752 297.72701 549.48336 296.6398 552.50321 296.3102 z M 503.90946 305.7477 C 506.47474 305.65488 508.74121 307.33519 511.09696 308.6852 C 516.40096 307.6002 527.28445 309.52895 527.28446 309.52895 C 527.28446 309.52895 527.28445 313.97946 527.28446 314.34145 C 527.28446 314.58245 513.59323 314.06119 510.62821 312.1852 C 508.09721 312.1852 500.49796 308.09595 501.22196 306.52895 C 502.16021 306.02895 503.05437 305.77863 503.90946 305.7477 z M 559.37821 308.15395 C 561.563 307.97793 562.53695 308.53595 560.90946 310.84145 C 556.56946 316.98945 545.34697 314.46645 545.34696 314.46645 L 544.87821 310.65395 C 548.74009 310.80457 555.7369 308.44732 559.37821 308.15395 z M 519.90946 320.65395 C 523.69959 320.93494 527.15946 322.1852 527.15946 322.1852 C 527.28046 322.4262 529.81645 327.3592 527.28446 328.6852 C 524.75246 330.0112 512.6507 327.64895 511.94071 322.77895 C 513.02571 321.6337 514.49837 321.0504 516.12821 320.77895 C 517.3506 320.57536 518.64609 320.56028 519.90946 320.65395 z M 473.03446 323.0602 C 476.82164 323.56054 480.36121 325.63695 480.25321 325.52895 C 480.2532 325.67295 480.09696 330.15395 480.09696 330.15395 C 480.09696 330.15395 471.88146 327.8637 469.28446 323.2477 C 470.47472 322.92319 471.77207 322.89342 473.03446 323.0602 z M 550.28446 323.59145 C 555.8225 323.6199 562.50194 325.16796 560.78446 327.2477 C 558.49346 330.0197 545.47197 327.49768 545.47196 327.4977 L 545.47196 324.1227 C 546.70771 323.7612 548.43845 323.58196 550.28446 323.59145 z "
+ id="path938" />
+ </g>
+ <g
+ id="g952"
+ transform="translate(28.47853,-0.412732)">
+ <path
+ style="font-size:12;fill:#0000ff;fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ d="M 440.30019 593.07202 L 440.16206 610.73373 L 446.7926 610.73373 L 446.51632 593.07202 C 446.05587 591.45848 445.45728 589.84494 443.47733 589.80133 C 441.31319 589.58328 440.39228 591.72013 440.30019 593.07202 z "
+ id="path894"
+ sodipodi:nodetypes="cccccc"
+ transform="translate(-0.167181,-5.684342e-14)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon895"
+ sodipodi:sides="5"
+ sodipodi:cx="202.500000"
+ sodipodi:cy="-347.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="211.25,-337.156 203.101,-340.539 195.693,-335.744 196.393,-344.54 189.543,-350.103 198.125,-352.156 201.299,-360.389 205.903,-352.861 214.714,-352.387 208.978,-345.682 211.25,-337.156 "
+ transform="matrix(0.161163,0.000000,0.000000,0.161163,409.7265,650.3555)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff0000;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon896"
+ sodipodi:sides="5"
+ sodipodi:cx="216.250000"
+ sodipodi:cy="-318.405518"
+ sodipodi:r1="11.7924764"
+ sodipodi:r2="5.89623821"
+ sodipodi:arg1="1.01219701"
+ sodipodi:arg2="1.64051554"
+ points="222.5,-308.406 215.839,-312.524 208.671,-309.371 210.529,-316.979 205.316,-322.822 213.125,-323.406 217.071,-330.169 220.04,-322.923 227.692,-321.259 221.717,-316.197 222.5,-308.406 "
+ transform="matrix(0.166300,0.000000,0.000000,0.166300,407.8862,650.5378)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon897"
+ sodipodi:sides="5"
+ sodipodi:cx="193.750000"
+ sodipodi:cy="-290.905518"
+ sodipodi:r1="10.6066017"
+ sodipodi:r2="5.30330086"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="201.25,-283.406 194.58,-285.668 188.935,-281.455 189.025,-288.498 183.274,-292.565 190,-294.656 192.091,-301.382 196.158,-295.631 203.201,-295.721 198.988,-290.076 201.25,-283.406 "
+ transform="matrix(0.173158,0.000000,0.000000,0.173158,407.8589,650.9816)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon898"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,402.1340,645.5944)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon899"
+ sodipodi:sides="5"
+ sodipodi:cx="195.000000"
+ sodipodi:cy="-230.905518"
+ sodipodi:r1="11.5244306"
+ sodipodi:r2="5.76221529"
+ sodipodi:arg1="0.86217005"
+ sodipodi:arg2="1.49048859"
+ points="202.5,-222.156 195.462,-225.162 188.996,-221.069 189.68,-228.691 183.789,-233.576 191.25,-235.281 194.075,-242.393 198.002,-235.824 205.639,-235.335 200.605,-229.57 202.5,-222.156 "
+ transform="matrix(0.139076,0.000000,0.000000,0.139076,414.4027,639.3444)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon900"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,410.1770,640.8358)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon946"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.4360,640.6559)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon947"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.2561,633.1020)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon948"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,409.6374,629.6847)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon949"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.2561,625.0085)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon950"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,402.8534,654.7670)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon951"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,401.2347,653.1483)" />
+ </g>
+ <g
+ id="g966"
+ transform="translate(0.825465,-5.684342e-14)">
+ <path
+ style="font-size:12;fill:#0000ff;fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ d="M 440.30019 593.07202 L 440.16206 610.73373 L 446.7926 610.73373 L 446.51632 593.07202 C 446.05587 591.45848 445.45728 589.84494 443.47733 589.80133 C 441.31319 589.58328 440.39228 591.72013 440.30019 593.07202 z "
+ id="path967"
+ sodipodi:nodetypes="cccccc"
+ transform="translate(-0.167181,-5.684342e-14)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon968"
+ sodipodi:sides="5"
+ sodipodi:cx="202.500000"
+ sodipodi:cy="-347.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="211.25,-337.156 203.101,-340.539 195.693,-335.744 196.393,-344.54 189.543,-350.103 198.125,-352.156 201.299,-360.389 205.903,-352.861 214.714,-352.387 208.978,-345.682 211.25,-337.156 "
+ transform="matrix(0.161163,0.000000,0.000000,0.161163,409.7265,650.3555)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff0000;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon969"
+ sodipodi:sides="5"
+ sodipodi:cx="216.250000"
+ sodipodi:cy="-318.405518"
+ sodipodi:r1="11.7924764"
+ sodipodi:r2="5.89623821"
+ sodipodi:arg1="1.01219701"
+ sodipodi:arg2="1.64051554"
+ points="222.5,-308.406 215.839,-312.524 208.671,-309.371 210.529,-316.979 205.316,-322.822 213.125,-323.406 217.071,-330.169 220.04,-322.923 227.692,-321.259 221.717,-316.197 222.5,-308.406 "
+ transform="matrix(0.166300,0.000000,0.000000,0.166300,407.8862,650.5378)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon970"
+ sodipodi:sides="5"
+ sodipodi:cx="193.750000"
+ sodipodi:cy="-290.905518"
+ sodipodi:r1="10.6066017"
+ sodipodi:r2="5.30330086"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="201.25,-283.406 194.58,-285.668 188.935,-281.455 189.025,-288.498 183.274,-292.565 190,-294.656 192.091,-301.382 196.158,-295.631 203.201,-295.721 198.988,-290.076 201.25,-283.406 "
+ transform="matrix(0.173158,0.000000,0.000000,0.173158,407.8589,650.9816)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon971"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,402.1340,645.5944)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon972"
+ sodipodi:sides="5"
+ sodipodi:cx="195.000000"
+ sodipodi:cy="-230.905518"
+ sodipodi:r1="11.5244306"
+ sodipodi:r2="5.76221529"
+ sodipodi:arg1="0.86217005"
+ sodipodi:arg2="1.49048859"
+ points="202.5,-222.156 195.462,-225.162 188.996,-221.069 189.68,-228.691 183.789,-233.576 191.25,-235.281 194.075,-242.393 198.002,-235.824 205.639,-235.335 200.605,-229.57 202.5,-222.156 "
+ transform="matrix(0.139076,0.000000,0.000000,0.139076,414.4027,639.3444)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon973"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,410.1770,640.8358)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon974"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.4360,640.6559)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon975"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.2561,633.1020)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon976"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,409.6374,629.6847)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon977"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.2561,625.0085)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon978"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,402.8534,654.7670)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon979"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,401.2347,653.1483)" />
+ </g>
+ <g
+ id="g980"
+ transform="translate(10.31831,-5.684342e-14)">
+ <path
+ style="font-size:12;fill:#0000ff;fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ d="M 440.30019 593.07202 L 440.16206 610.73373 L 446.7926 610.73373 L 446.51632 593.07202 C 446.05587 591.45848 445.45728 589.84494 443.47733 589.80133 C 441.31319 589.58328 440.39228 591.72013 440.30019 593.07202 z "
+ id="path981"
+ sodipodi:nodetypes="cccccc"
+ transform="translate(-0.167181,-5.684342e-14)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon982"
+ sodipodi:sides="5"
+ sodipodi:cx="202.500000"
+ sodipodi:cy="-347.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="211.25,-337.156 203.101,-340.539 195.693,-335.744 196.393,-344.54 189.543,-350.103 198.125,-352.156 201.299,-360.389 205.903,-352.861 214.714,-352.387 208.978,-345.682 211.25,-337.156 "
+ transform="matrix(0.161163,0.000000,0.000000,0.161163,409.7265,650.3555)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff0000;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon983"
+ sodipodi:sides="5"
+ sodipodi:cx="216.250000"
+ sodipodi:cy="-318.405518"
+ sodipodi:r1="11.7924764"
+ sodipodi:r2="5.89623821"
+ sodipodi:arg1="1.01219701"
+ sodipodi:arg2="1.64051554"
+ points="222.5,-308.406 215.839,-312.524 208.671,-309.371 210.529,-316.979 205.316,-322.822 213.125,-323.406 217.071,-330.169 220.04,-322.923 227.692,-321.259 221.717,-316.197 222.5,-308.406 "
+ transform="matrix(0.166300,0.000000,0.000000,0.166300,407.8862,650.5378)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon984"
+ sodipodi:sides="5"
+ sodipodi:cx="193.750000"
+ sodipodi:cy="-290.905518"
+ sodipodi:r1="10.6066017"
+ sodipodi:r2="5.30330086"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="201.25,-283.406 194.58,-285.668 188.935,-281.455 189.025,-288.498 183.274,-292.565 190,-294.656 192.091,-301.382 196.158,-295.631 203.201,-295.721 198.988,-290.076 201.25,-283.406 "
+ transform="matrix(0.173158,0.000000,0.000000,0.173158,407.8589,650.9816)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon985"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,402.1340,645.5944)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon986"
+ sodipodi:sides="5"
+ sodipodi:cx="195.000000"
+ sodipodi:cy="-230.905518"
+ sodipodi:r1="11.5244306"
+ sodipodi:r2="5.76221529"
+ sodipodi:arg1="0.86217005"
+ sodipodi:arg2="1.49048859"
+ points="202.5,-222.156 195.462,-225.162 188.996,-221.069 189.68,-228.691 183.789,-233.576 191.25,-235.281 194.075,-242.393 198.002,-235.824 205.639,-235.335 200.605,-229.57 202.5,-222.156 "
+ transform="matrix(0.139076,0.000000,0.000000,0.139076,414.4027,639.3444)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon987"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,410.1770,640.8358)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon988"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.4360,640.6559)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon989"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.2561,633.1020)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon990"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,409.6374,629.6847)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon991"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.2561,625.0085)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon992"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,402.8534,654.7670)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon993"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,401.2347,653.1483)" />
+ </g>
+ <g
+ id="g994"
+ transform="translate(19.39842,-5.684342e-14)">
+ <path
+ style="font-size:12;fill:#0000ff;fill-opacity:0.75;fill-rule:evenodd;stroke-width:3pt;"
+ d="M 440.30019 593.07202 L 440.16206 610.73373 L 446.7926 610.73373 L 446.51632 593.07202 C 446.05587 591.45848 445.45728 589.84494 443.47733 589.80133 C 441.31319 589.58328 440.39228 591.72013 440.30019 593.07202 z "
+ id="path995"
+ sodipodi:nodetypes="cccccc"
+ transform="translate(-0.167181,-5.684342e-14)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon996"
+ sodipodi:sides="5"
+ sodipodi:cx="202.500000"
+ sodipodi:cy="-347.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="211.25,-337.156 203.101,-340.539 195.693,-335.744 196.393,-344.54 189.543,-350.103 198.125,-352.156 201.299,-360.389 205.903,-352.861 214.714,-352.387 208.978,-345.682 211.25,-337.156 "
+ transform="matrix(0.161163,0.000000,0.000000,0.161163,409.7265,650.3555)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff0000;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon997"
+ sodipodi:sides="5"
+ sodipodi:cx="216.250000"
+ sodipodi:cy="-318.405518"
+ sodipodi:r1="11.7924764"
+ sodipodi:r2="5.89623821"
+ sodipodi:arg1="1.01219701"
+ sodipodi:arg2="1.64051554"
+ points="222.5,-308.406 215.839,-312.524 208.671,-309.371 210.529,-316.979 205.316,-322.822 213.125,-323.406 217.071,-330.169 220.04,-322.923 227.692,-321.259 221.717,-316.197 222.5,-308.406 "
+ transform="matrix(0.166300,0.000000,0.000000,0.166300,407.8862,650.5378)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon998"
+ sodipodi:sides="5"
+ sodipodi:cx="193.750000"
+ sodipodi:cy="-290.905518"
+ sodipodi:r1="10.6066017"
+ sodipodi:r2="5.30330086"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="201.25,-283.406 194.58,-285.668 188.935,-281.455 189.025,-288.498 183.274,-292.565 190,-294.656 192.091,-301.382 196.158,-295.631 203.201,-295.721 198.988,-290.076 201.25,-283.406 "
+ transform="matrix(0.173158,0.000000,0.000000,0.173158,407.8589,650.9816)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon999"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,402.1340,645.5944)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon1000"
+ sodipodi:sides="5"
+ sodipodi:cx="195.000000"
+ sodipodi:cy="-230.905518"
+ sodipodi:r1="11.5244306"
+ sodipodi:r2="5.76221529"
+ sodipodi:arg1="0.86217005"
+ sodipodi:arg2="1.49048859"
+ points="202.5,-222.156 195.462,-225.162 188.996,-221.069 189.68,-228.691 183.789,-233.576 191.25,-235.281 194.075,-242.393 198.002,-235.824 205.639,-235.335 200.605,-229.57 202.5,-222.156 "
+ transform="matrix(0.139076,0.000000,0.000000,0.139076,414.4027,639.3444)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon1001"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,410.1770,640.8358)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon1002"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.4360,640.6559)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon1003"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.2561,633.1020)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon1004"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,409.6374,629.6847)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ff00ff;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon1005"
+ sodipodi:sides="5"
+ sodipodi:cx="220.000000"
+ sodipodi:cy="-217.155518"
+ sodipodi:r1="13.2876823"
+ sodipodi:r2="6.64384113"
+ sodipodi:arg1="0.85196633"
+ sodipodi:arg2="1.48028486"
+ points="228.75,-207.156 220.601,-210.539 213.193,-205.744 213.893,-214.54 207.043,-220.103 215.625,-222.156 218.799,-230.389 223.403,-222.861 232.214,-222.387 226.478,-215.682 228.75,-207.156 "
+ transform="matrix(0.147705,0.000000,0.000000,0.147705,411.2561,625.0085)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon1006"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,402.8534,654.7670)" />
+ <polygon
+ sodipodi:type="star"
+ style="font-size:12;fill:#ffff00;fill-opacity:1;fill-rule:evenodd;stroke-width:3pt;"
+ id="polygon1007"
+ sodipodi:sides="5"
+ sodipodi:cx="217.500000"
+ sodipodi:cy="-259.655518"
+ sodipodi:r1="12.3743687"
+ sodipodi:r2="6.18718434"
+ sodipodi:arg1="0.78539816"
+ sodipodi:arg2="1.41371669"
+ points="226.25,-250.906 218.468,-253.545 211.882,-248.63 211.987,-256.847 205.278,-261.591 213.125,-264.031 215.564,-271.878 220.309,-265.168 228.526,-265.273 223.611,-258.688 226.25,-250.906 "
+ transform="matrix(0.191059,0.000000,0.000000,0.191059,401.2347,653.1483)" />
+ </g>
+ <g
+ id="g799"
+ transform="translate(9.626073,1.525879e-5)">
+ <text
+ style="fill:black;stroke:none;font-family:Bitstream Charter;font-style:normal;font-weight:normal;font-size:130;fill-opacity:1;stroke-opacity:1;stroke-width:1pt;stroke-linejoin:miter;stroke-linecap:butt;text-anchor:start;writing-mode:lr;"
+ x="77.6037369"
+ y="178.872375"
+ id="text582"
+ sodipodi:linespacing="100%">
+ <tspan
+ x="77.6037369"
+ y="178.872375"
+ sodipodi:role="line"
+ id="tspan596">P</tspan>
+ </text>
+ <text
+ style="font-size:130;font-weight:normal;fill:#ffd200;stroke-width:1;font-family:Bitstream Charter;"
+ x="74.7134628"
+ y="173.835907"
+ id="text612"
+ sodipodi:linespacing="100%">
+ <tspan
+ x="74.7134628"
+ y="173.835907"
+ sodipodi:role="line"
+ id="tspan613"
+ style="fill:#ffd200;fill-opacity:1;">P</tspan>
+ </text>
+ </g>
+ <g
+ id="g806"
+ transform="translate(-4.813036,1.525879e-5)">
+ <text
+ style="fill:black;stroke:none;font-family:Bitstream Charter;font-style:normal;font-weight:normal;font-size:130;fill-opacity:1;stroke-opacity:1;stroke-width:1pt;stroke-linejoin:miter;stroke-linecap:butt;text-anchor:start;writing-mode:lr;"
+ x="609.758812"
+ y="180.622284"
+ id="text598"
+ sodipodi:linespacing="100%">
+ <tspan
+ x="609.758789"
+ y="180.622284"
+ sodipodi:role="line"
+ id="tspan601">S</tspan>
+ </text>
+ <text
+ style="font-size:130;font-weight:normal;fill:#ffd200;stroke-width:1;font-family:Bitstream Charter;"
+ x="607.038719"
+ y="175.160202"
+ id="text615"
+ sodipodi:linespacing="100%">
+ <tspan
+ x="607.038696"
+ y="175.160202"
+ sodipodi:role="line"
+ id="tspan616"
+ style="fill:#ffd200;fill-opacity:1;">S</tspan>
+ </text>
+ </g>
+</svg>
Added: trunk/client/gtk/data/style-ai.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/style-ai.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/style-human-1.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/style-human-1.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/style-human-2.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/style-human-2.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/style-human-3.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/style-human-3.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/style-human-4.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/style-human-4.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/style-human-5.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/style-human-5.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/style-human-6.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/style-human-6.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/style-human-7.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/style-human-7.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/style-human.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/style-human.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/FreeCIV-like/Makefile.am
===================================================================
--- trunk/client/gtk/data/themes/FreeCIV-like/Makefile.am (rev 0)
+++ trunk/client/gtk/data/themes/FreeCIV-like/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,33 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+freecivthemedir = $(pioneers_themedir)/FreeCIV-like
+
+freecivtheme_DATA = \
+ client/gtk/data/themes/FreeCIV-like/desert.png \
+ client/gtk/data/themes/FreeCIV-like/forest.png \
+ client/gtk/data/themes/FreeCIV-like/mountain.png \
+ client/gtk/data/themes/FreeCIV-like/sea.png \
+ client/gtk/data/themes/FreeCIV-like/board.png \
+ client/gtk/data/themes/FreeCIV-like/field.png \
+ client/gtk/data/themes/FreeCIV-like/hill.png \
+ client/gtk/data/themes/FreeCIV-like/pasture.png \
+ client/gtk/data/themes/FreeCIV-like/theme.cfg
+
+EXTRA_DIST += $(freecivtheme_DATA)
Added: trunk/client/gtk/data/themes/FreeCIV-like/board.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/FreeCIV-like/board.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/FreeCIV-like/desert.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/FreeCIV-like/desert.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/FreeCIV-like/field.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/FreeCIV-like/field.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/FreeCIV-like/forest.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/FreeCIV-like/forest.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/FreeCIV-like/hill.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/FreeCIV-like/hill.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/FreeCIV-like/mountain.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/FreeCIV-like/mountain.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/FreeCIV-like/pasture.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/FreeCIV-like/pasture.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/FreeCIV-like/sea.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/FreeCIV-like/sea.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/FreeCIV-like/theme.cfg
===================================================================
--- trunk/client/gtk/data/themes/FreeCIV-like/theme.cfg (rev 0)
+++ trunk/client/gtk/data/themes/FreeCIV-like/theme.cfg 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,8 @@
+hill-tile = hill.png
+field-tile = field.png
+mountain-tile = mountain.png
+pasture-tile = pasture.png
+forest-tile = forest.png
+desert-tile = desert.png
+sea-tile = sea.png
+board-tile = board.png
Added: trunk/client/gtk/data/themes/Iceland/Makefile.am
===================================================================
--- trunk/client/gtk/data/themes/Iceland/Makefile.am (rev 0)
+++ trunk/client/gtk/data/themes/Iceland/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,32 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+icelandthemedir = $(pioneers_themedir)/Iceland
+
+icelandtheme_DATA = \
+ client/gtk/data/themes/Iceland/desert.png \
+ client/gtk/data/themes/Iceland/field_grain.png \
+ client/gtk/data/themes/Iceland/forest_lumber.png \
+ client/gtk/data/themes/Iceland/gold.png \
+ client/gtk/data/themes/Iceland/hill_brick.png \
+ client/gtk/data/themes/Iceland/mountain_ore.png \
+ client/gtk/data/themes/Iceland/pasture_wool.png \
+ client/gtk/data/themes/Iceland/theme.cfg
+
+EXTRA_DIST += $(icelandtheme_DATA)
Added: trunk/client/gtk/data/themes/Iceland/desert.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Iceland/desert.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Iceland/field_grain.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Iceland/field_grain.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Iceland/forest_lumber.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Iceland/forest_lumber.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Iceland/gold.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Iceland/gold.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Iceland/hill_brick.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Iceland/hill_brick.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Iceland/mountain_ore.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Iceland/mountain_ore.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Iceland/pasture_wool.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Iceland/pasture_wool.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Iceland/theme.cfg
===================================================================
--- trunk/client/gtk/data/themes/Iceland/theme.cfg (rev 0)
+++ trunk/client/gtk/data/themes/Iceland/theme.cfg 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,19 @@
+scaling = always
+hill-tile = hill_brick.png
+field-tile = field_grain.png none #d0d0d0 none #303030 #ffffff
+mountain-tile = mountain_ore.png none #d0d0d0 none #303030 #ffffff
+pasture-tile = pasture_wool.png
+forest-tile = forest_lumber.png none #d0d0d0 none #303030 #ffffff
+gold-tile = gold.png
+desert-tile = desert.png
+chip-bg-color = none
+chip-fg-color = #202020
+chip-bd-color = none
+chip-hi-bg-color= #c0c0c0
+chip-hi-fg-color= #000000
+port-bg-color = #3bf3f9
+port-fg-color = #000000
+port-bd-color = #ffffff
+robber-fg-color = #f46a0e
+robber-bd-color = #000000
+hex-bd-color = #000000
Added: trunk/client/gtk/data/themes/Makefile.am
===================================================================
--- trunk/client/gtk/data/themes/Makefile.am (rev 0)
+++ trunk/client/gtk/data/themes/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,39 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+include client/gtk/data/themes/FreeCIV-like/Makefile.am
+include client/gtk/data/themes/Iceland/Makefile.am
+include client/gtk/data/themes/Tiny/Makefile.am
+include client/gtk/data/themes/Wesnoth-like/Makefile.am
+
+defaultthemedir = $(pioneers_themedir)
+
+defaulttheme_DATA = \
+ client/gtk/data/themes/board.png \
+ client/gtk/data/themes/desert.png \
+ client/gtk/data/themes/field.png \
+ client/gtk/data/themes/forest.png \
+ client/gtk/data/themes/hill.png \
+ client/gtk/data/themes/mountain.png \
+ client/gtk/data/themes/pasture.png \
+ client/gtk/data/themes/plain.png \
+ client/gtk/data/themes/sea.png \
+ client/gtk/data/themes/gold.png
+
+EXTRA_DIST += $(defaulttheme_DATA)
Added: trunk/client/gtk/data/themes/Tiny/Makefile.am
===================================================================
--- trunk/client/gtk/data/themes/Tiny/Makefile.am (rev 0)
+++ trunk/client/gtk/data/themes/Tiny/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,39 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+tinythemedir = $(pioneers_themedir)/Tiny
+
+tinytheme_DATA = \
+ client/gtk/data/themes/Tiny/board.png \
+ client/gtk/data/themes/Tiny/brick-lorindol.png \
+ client/gtk/data/themes/Tiny/brick-port.png \
+ client/gtk/data/themes/Tiny/desert-lorindol.png \
+ client/gtk/data/themes/Tiny/gold-lorindol.png \
+ client/gtk/data/themes/Tiny/grain-lorindol.png \
+ client/gtk/data/themes/Tiny/grain-port.png \
+ client/gtk/data/themes/Tiny/lumber-lorindol.png \
+ client/gtk/data/themes/Tiny/lumber-port.png \
+ client/gtk/data/themes/Tiny/ore-lorindol.png \
+ client/gtk/data/themes/Tiny/ore-port.png \
+ client/gtk/data/themes/Tiny/sea-lorindol.png \
+ client/gtk/data/themes/Tiny/theme.cfg \
+ client/gtk/data/themes/Tiny/wool-lorindol.png \
+ client/gtk/data/themes/Tiny/wool-port.png
+
+EXTRA_DIST += $(tinytheme_DATA)
Added: trunk/client/gtk/data/themes/Tiny/board.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/board.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/brick-lorindol.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/brick-lorindol.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/brick-port.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/brick-port.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/desert-lorindol.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/desert-lorindol.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/gold-lorindol.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/gold-lorindol.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/grain-lorindol.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/grain-lorindol.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/grain-port.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/grain-port.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/lumber-lorindol.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/lumber-lorindol.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/lumber-port.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/lumber-port.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/ore-lorindol.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/ore-lorindol.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/ore-port.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/ore-port.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/sea-lorindol.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/sea-lorindol.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/theme.cfg
===================================================================
--- trunk/client/gtk/data/themes/Tiny/theme.cfg (rev 0)
+++ trunk/client/gtk/data/themes/Tiny/theme.cfg 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,28 @@
+# Theme created by Martin Brotzeller <lorindol at cip.informatik.uni-wuerzburg.de>
+# 2 december 2003
+scaling = always
+hill-tile = brick-lorindol.png none #000000 none #33b033 #e03030
+field-tile = grain-lorindol.png none #000000 none #33b033 #ff3030
+mountain-tile = ore-lorindol.png none #ffffff none #33b033 #ffb0b0
+pasture-tile = wool-lorindol.png none #000000 none #33b033 #ff3030
+forest-tile = lumber-lorindol.png none #ffffff none #33b033 #c03030
+desert-tile = desert-lorindol.png
+gold-tile = gold-lorindol.png none #000000 none #33b033 #ff3030
+sea-tile = sea-lorindol.png
+lumber-port-tile = lumber-port.png
+brick-port-tile = brick-port.png
+grain-port-tile = grain-port.png
+ore-port-tile = ore-port.png
+wool-port-tile = wool-port.png
+board-tile = board.png
+chip-bg-color = none
+chip-fg-color = #202020
+chip-bd-color = none
+chip-hi-bg-color= #c0c0c0
+chip-hi-fg-color= #000000
+port-bg-color = #9080d0
+port-fg-color = #000000
+port-bd-color = #ffffff
+robber-fg-color = #700707
+robber-bd-color = #000000
+hex-bd-color = #ddbb55
Added: trunk/client/gtk/data/themes/Tiny/wool-lorindol.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/wool-lorindol.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Tiny/wool-port.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Tiny/wool-port.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Wesnoth-like/Makefile.am
===================================================================
--- trunk/client/gtk/data/themes/Wesnoth-like/Makefile.am (rev 0)
+++ trunk/client/gtk/data/themes/Wesnoth-like/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,34 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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
+
+wesnoththemedir = $(pioneers_themedir)/Wesnoth-like
+
+wesnoththeme_DATA = \
+ client/gtk/data/themes/Wesnoth-like/board.png \
+ client/gtk/data/themes/Wesnoth-like/desert.png \
+ client/gtk/data/themes/Wesnoth-like/field.png \
+ client/gtk/data/themes/Wesnoth-like/forest.png \
+ client/gtk/data/themes/Wesnoth-like/gold.png \
+ client/gtk/data/themes/Wesnoth-like/hill.png \
+ client/gtk/data/themes/Wesnoth-like/mountain.png \
+ client/gtk/data/themes/Wesnoth-like/pasture.png \
+ client/gtk/data/themes/Wesnoth-like/sea.png \
+ client/gtk/data/themes/Wesnoth-like/theme.cfg
+
+EXTRA_DIST += $(wesnoththeme_DATA)
Added: trunk/client/gtk/data/themes/Wesnoth-like/board.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Wesnoth-like/board.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Wesnoth-like/desert.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Wesnoth-like/desert.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Wesnoth-like/field.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Wesnoth-like/field.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Wesnoth-like/forest.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Wesnoth-like/forest.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Wesnoth-like/gold.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Wesnoth-like/gold.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Wesnoth-like/hill.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Wesnoth-like/hill.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Wesnoth-like/mountain.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Wesnoth-like/mountain.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Wesnoth-like/pasture.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Wesnoth-like/pasture.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Wesnoth-like/sea.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/Wesnoth-like/sea.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/Wesnoth-like/theme.cfg
===================================================================
--- trunk/client/gtk/data/themes/Wesnoth-like/theme.cfg (rev 0)
+++ trunk/client/gtk/data/themes/Wesnoth-like/theme.cfg 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,10 @@
+scaling = always
+hill-tile = hill.png
+field-tile = field.png
+mountain-tile = mountain.png
+pasture-tile = pasture.png
+forest-tile = forest.png
+gold-tile = gold.png
+desert-tile = desert.png
+sea-tile = sea.png
+board-tile = board.png
Added: trunk/client/gtk/data/themes/board.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/board.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/desert.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/desert.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/field.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/field.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/forest.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/forest.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/gold.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/gold.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/hill.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/hill.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/mountain.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/mountain.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/pasture.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/pasture.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/plain.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/plain.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/themes/sea.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/themes/sea.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/trade.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/trade.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/data/wool.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/gtk/data/wool.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/gtk/develop.c
===================================================================
--- trunk/client/gtk/develop.c (rev 0)
+++ trunk/client/gtk/develop.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,281 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "common_gtk.h"
+
+/** Reorder the development types:
+ * Road building
+ * Monopoly
+ * Year of Plenty
+ * Soldier
+ * Victory points
+ */
+static gint develtype_to_sortorder(DevelType type)
+{
+ switch (type) {
+ case DEVEL_ROAD_BUILDING:
+ return 0;
+ case DEVEL_MONOPOLY:
+ return 1;
+ case DEVEL_YEAR_OF_PLENTY:
+ return 2;
+ case DEVEL_SOLDIER:
+ return 10;
+ case DEVEL_CHAPEL:
+ return 20;
+ case DEVEL_UNIVERSITY:
+ return 21;
+ case DEVEL_GOVERNORS_HOUSE:
+ return 22;
+ case DEVEL_LIBRARY:
+ return 23;
+ case DEVEL_MARKET:
+ return 24;
+ default:
+ g_assert_not_reached();
+ return 99;
+ };
+};
+
+enum {
+ DEVELOP_COLUMN_TYPE, /**< Development card type */
+ DEVELOP_COLUMN_ORDER, /**< Sort order */
+ DEVELOP_COLUMN_DESCRIPTION, /**< Description of the card */
+ DEVELOP_COLUMN_AMOUNT, /**< Amount of the cards */
+ DEVELOP_COLUMN_LAST
+};
+
+static GtkListStore *store; /**< The data for the GUI */
+static gint selected_card_idx; /**< currently selected development card */
+
+gint develop_current_idx(void)
+{
+ return selected_card_idx;
+}
+
+static gint develop_click_cb(G_GNUC_UNUSED GtkWidget * widget,
+ G_GNUC_UNUSED GdkEventButton * event,
+ gpointer play_develop_btn)
+{
+ if (event->type == GDK_2BUTTON_PRESS) {
+ if (can_play_develop(develop_current_idx()))
+ gtk_button_clicked(GTK_BUTTON(play_develop_btn));
+ };
+ return FALSE;
+}
+
+static void develop_select_cb(GtkTreeSelection * selection,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+
+ g_assert(selection != NULL);
+ if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
+ DevelType type;
+ gtk_tree_model_get(model, &iter, DEVELOP_COLUMN_TYPE,
+ &type, -1);
+ selected_card_idx =
+ deck_card_oldest_card(get_devel_deck(), type);
+ } else
+ selected_card_idx = -1;
+ frontend_gui_update();
+}
+
+GtkWidget *develop_build_page(void)
+{
+ GtkWidget *label;
+ GtkWidget *vbox;
+ GtkWidget *scroll_win;
+ GtkWidget *bbox;
+ GtkWidget *alignment;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkWidget *play_develop_btn;
+ GtkWidget *develop_list;
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 3, 3);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
+
+ label = gtk_label_new(NULL);
+ /* Caption for list of bought development cards */
+ gtk_label_set_markup(GTK_LABEL(label),
+ _("<b>Development Cards</b>"));
+ gtk_widget_show(label);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_container_add(GTK_CONTAINER(alignment), label);
+
+ /* Create model */
+ store = gtk_list_store_new(DEVELOP_COLUMN_LAST,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_STRING, G_TYPE_STRING);
+
+ scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_widget_set_size_request(scroll_win, -1, 100);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
+ (scroll_win), GTK_SHADOW_IN);
+ gtk_widget_show(scroll_win);
+ gtk_box_pack_start(GTK_BOX(vbox), scroll_win, TRUE, TRUE, 0);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+
+ /* Create graphical representation of the model */
+ develop_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(develop_list),
+ FALSE);
+ gtk_container_add(GTK_CONTAINER(scroll_win), develop_list);
+
+ /* First create the button, it is used as user_data for the listview */
+ play_develop_btn = gtk_button_new_with_label(
+ /* Button text: play development card */
+ _
+ ("Play Card"));
+
+ /* Register double-click */
+ g_signal_connect(G_OBJECT(develop_list), "button_press_event",
+ G_CALLBACK(develop_click_cb), play_develop_btn);
+
+ g_signal_connect(G_OBJECT
+ (gtk_tree_view_get_selection
+ (GTK_TREE_VIEW(develop_list))), "changed",
+ G_CALLBACK(develop_select_cb), NULL);
+
+ /* Now create columns */
+ column = gtk_tree_view_column_new_with_attributes(
+ /* Not translated: it is not visible */
+ "Development Cards",
+ gtk_cell_renderer_text_new
+ (),
+ "text",
+ DEVELOP_COLUMN_DESCRIPTION,
+ NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_column_set_expand(column, TRUE);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(develop_list), column);
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(
+ /* Not translated: it is not visible */
+ "Amount",
+ renderer,
+ "text",
+ DEVELOP_COLUMN_AMOUNT,
+ NULL);
+ g_object_set(renderer, "xalign", 1.0f, NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_GROW_ONLY);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(develop_list), column);
+
+ gtk_widget_show(develop_list);
+
+ bbox = gtk_hbutton_box_new();
+ gtk_widget_show(bbox);
+ gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
+
+ frontend_gui_register(play_develop_btn, GUI_PLAY_DEVELOP,
+ "clicked");
+ gtk_widget_show(play_develop_btn);
+ gtk_container_add(GTK_CONTAINER(bbox), play_develop_btn);
+
+ selected_card_idx = -1;
+ return vbox;
+}
+
+static void update_model(GtkTreeIter * iter, DevelType type)
+{
+ gchar amount_string[16];
+ gint amount;
+
+ /* Only show the amount when you have more than one */
+ amount = deck_card_amount(get_devel_deck(), type);
+ if (amount == 1)
+ amount_string[0] = '\0';
+ else
+ snprintf(amount_string, sizeof(amount_string), "%d",
+ amount);
+
+ gtk_list_store_set(store, iter,
+ DEVELOP_COLUMN_DESCRIPTION,
+ get_devel_name(type), DEVELOP_COLUMN_AMOUNT,
+ amount_string, DEVELOP_COLUMN_TYPE, type,
+ DEVELOP_COLUMN_ORDER,
+ develtype_to_sortorder(type), -1);
+}
+
+void frontend_bought_develop(DevelType type)
+{
+ GtkTreeIter iter;
+ enum TFindResult found;
+
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(store), &iter,
+ DEVELOP_COLUMN_ORDER,
+ develtype_to_sortorder(type));
+
+ switch (found) {
+ case FIND_MATCH_EXACT:
+ /* Don't add new items */
+ break;
+ case FIND_MATCH_INSERT_BEFORE:
+ gtk_list_store_insert_before(store, &iter, &iter);
+ break;
+ case FIND_NO_MATCH:
+ gtk_list_store_append(store, &iter);
+ };
+
+ update_model(&iter, type);
+}
+
+void frontend_played_develop(gint player_num, G_GNUC_UNUSED gint card_idx,
+ DevelType type)
+{
+ GtkTreeIter iter;
+ enum TFindResult found;
+
+ if (player_num == my_player_num()) {
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(store), &iter,
+ DEVELOP_COLUMN_ORDER,
+ develtype_to_sortorder(type));
+ g_assert(found == FIND_MATCH_EXACT);
+ if (deck_card_amount(get_devel_deck(), type) == 0)
+ gtk_list_store_remove(store, &iter);
+ else
+ update_model(&iter, type);
+ };
+}
+
+void develop_reset(void)
+{
+ selected_card_idx = -1;
+ gtk_list_store_clear(store);
+}
Added: trunk/client/gtk/discard.c
===================================================================
--- trunk/client/gtk/discard.c (rev 0)
+++ trunk/client/gtk/discard.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,284 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "resource-table.h"
+#include "gtkbugs.h"
+#include "common_gtk.h"
+
+enum {
+ DISCARD_COLUMN_PLAYER_ICON, /**< Player icon */
+ DISCARD_COLUMN_PLAYER_NUM, /**< Internal: player number */
+ DISCARD_COLUMN_PLAYER_NAME, /**< Player name */
+ DISCARD_COLUMN_AMOUNT, /**< The amount to discard */
+ DISCARD_COLUMN_LAST
+};
+
+static GtkListStore *discard_store; /**< the discard data */
+static GtkWidget *discard_widget; /**< the discard widget */
+
+static struct {
+ GtkWidget *dlg;
+ GtkWidget *resource_widget;
+} discard;
+
+/* Local function prototypes */
+static GtkWidget *discard_create_dlg(gint num);
+
+gboolean can_discard(void)
+{
+ if (discard.dlg == NULL)
+ return FALSE;
+
+ return
+ resource_table_is_total_reached(RESOURCETABLE
+ (discard.resource_widget));
+}
+
+static void amount_changed_cb(G_GNUC_UNUSED ResourceTable * rt,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ frontend_gui_update();
+}
+
+static void button_destroyed(G_GNUC_UNUSED GtkWidget * w, gpointer num)
+{
+ if (callback_mode == MODE_DISCARD)
+ discard_create_dlg(GPOINTER_TO_INT(num));
+}
+
+static GtkWidget *discard_create_dlg(gint num)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *vbox;
+ char buff[128];
+
+ discard.dlg = gtk_dialog_new_with_buttons(_("Discard resources"),
+ GTK_WINDOW(app_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK, NULL);
+ g_signal_connect(G_OBJECT(discard.dlg), "destroy",
+ G_CALLBACK(gtk_widget_destroyed), &discard.dlg);
+ gtk_widget_realize(discard.dlg);
+ /* Disable close */
+ gdk_window_set_functions(discard.dlg->window,
+ GDK_FUNC_ALL | GDK_FUNC_CLOSE);
+
+ dlg_vbox = GTK_DIALOG(discard.dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
+
+ sprintf(buff, _("You must discard %d resources"), num);
+ discard.resource_widget =
+ resource_table_new(buff, RESOURCE_TABLE_LESS_IN_HAND, FALSE,
+ TRUE);
+ resource_table_set_total(RESOURCETABLE(discard.resource_widget),
+ _("Total discards"), num);
+ gtk_widget_show(discard.resource_widget);
+ gtk_box_pack_start(GTK_BOX(vbox), discard.resource_widget, FALSE,
+ TRUE, 0);
+ g_signal_connect(G_OBJECT(discard.resource_widget), "change",
+ G_CALLBACK(amount_changed_cb), NULL);
+
+ frontend_gui_register(gui_get_dialog_button
+ (GTK_DIALOG(discard.dlg), 0), GUI_DISCARD,
+ "clicked");
+ /* This _must_ be after frontend_gui_register, otherwise the
+ * regeneration of the button happens before the destruction, which
+ * results in an incorrectly sensitive OK button. */
+ g_signal_connect(gui_get_dialog_button(GTK_DIALOG(discard.dlg), 0),
+ "destroy", G_CALLBACK(button_destroyed),
+ GINT_TO_POINTER(num));
+ gtk_widget_show(discard.dlg);
+ frontend_gui_update();
+
+ return discard.dlg;
+}
+
+void discard_get_list(gint * discards)
+{
+ if (discard.dlg != NULL)
+ resource_table_get_amount(RESOURCETABLE
+ (discard.resource_widget),
+ discards);
+ else
+ memset(discards, 0, sizeof(discards));
+}
+
+void discard_player_did(gint player_num)
+{
+ GtkTreeIter iter;
+ enum TFindResult found;
+ /* check if the player was in the list. If not, it is not an error.
+ * That happens if the player auto-discards. */
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(discard_store), &iter,
+ DISCARD_COLUMN_PLAYER_NUM, player_num);
+
+ if (found == FIND_MATCH_EXACT) {
+ gtk_list_store_remove(discard_store, &iter);
+ if (player_num == my_player_num()) {
+ gtk_widget_destroy(discard.dlg);
+ discard.dlg = NULL;
+ }
+ }
+}
+
+void discard_player_must(gint player_num, gint num)
+{
+ GtkTreeIter iter;
+ GdkPixbuf *pixbuf;
+ enum TFindResult found;
+
+ /* Search for a place to add information about the player */
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(discard_store), &iter,
+ DISCARD_COLUMN_PLAYER_NUM, player_num);
+ switch (found) {
+ case FIND_NO_MATCH:
+ gtk_list_store_append(discard_store, &iter);
+ break;
+ case FIND_MATCH_INSERT_BEFORE:
+ gtk_list_store_insert_before(discard_store, &iter, &iter);
+ break;
+ case FIND_MATCH_EXACT:
+ break;
+ default:
+ g_error("unknown case in discard_player_must");
+ };
+
+ pixbuf = player_create_icon(discard_widget, player_num, TRUE);
+ gtk_list_store_set(discard_store, &iter,
+ DISCARD_COLUMN_PLAYER_ICON, pixbuf,
+ DISCARD_COLUMN_PLAYER_NUM, player_num,
+ DISCARD_COLUMN_PLAYER_NAME,
+ player_name(player_num, TRUE),
+ DISCARD_COLUMN_AMOUNT, num, -1);
+ g_object_unref(pixbuf);
+
+ if (player_num != my_player_num())
+ return;
+
+ discard_create_dlg(num);
+}
+
+void discard_begin(void)
+{
+ gtk_list_store_clear(GTK_LIST_STORE(discard_store));
+ gui_discard_show();
+}
+
+void discard_end(void)
+{
+ if (discard.dlg) {
+ gtk_widget_destroy(discard.dlg);
+ discard.dlg = NULL;
+ }
+
+ gui_discard_hide();
+}
+
+GtkWidget *discard_build_page(void)
+{
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *alignment;
+ GtkWidget *scroll_win;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ vbox = gtk_vbox_new(FALSE, 6);
+ gtk_widget_show(vbox);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 3, 3);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
+
+ label = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(label),
+ /* Caption for list of player that must discard cards */
+ _("<b>Waiting for players to discard</b>"));
+ gtk_widget_show(label);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_container_add(GTK_CONTAINER(alignment), label);
+
+ scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
+ (scroll_win), GTK_SHADOW_IN);
+ gtk_widget_show(scroll_win);
+ gtk_box_pack_start(GTK_BOX(vbox), scroll_win, TRUE, TRUE, 0);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ discard_store = gtk_list_store_new(DISCARD_COLUMN_LAST, GDK_TYPE_PIXBUF, /* player icon */
+ G_TYPE_INT, /* player number */
+ G_TYPE_STRING, /* text */
+ G_TYPE_INT); /* amount to discard */
+ discard_widget =
+ gtk_tree_view_new_with_model(GTK_TREE_MODEL(discard_store));
+
+ column = gtk_tree_view_column_new_with_attributes("",
+ gtk_cell_renderer_pixbuf_new
+ (), "pixbuf",
+ DISCARD_COLUMN_PLAYER_ICON,
+ NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_GROW_ONLY);
+ set_pixbuf_tree_view_column_autogrow(discard_widget, column);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(discard_widget), column);
+
+ column = gtk_tree_view_column_new_with_attributes("",
+ gtk_cell_renderer_text_new
+ (), "text",
+ DISCARD_COLUMN_PLAYER_NAME,
+ NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_column_set_expand(column, TRUE);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(discard_widget), column);
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes("",
+ renderer,
+ "text",
+ DISCARD_COLUMN_AMOUNT,
+ NULL);
+ g_object_set(renderer, "xalign", 1.0f, NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_GROW_ONLY);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(discard_widget), column);
+
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(discard_widget),
+ FALSE);
+ gtk_widget_show(discard_widget);
+ gtk_container_add(GTK_CONTAINER(scroll_win), discard_widget);
+
+ return vbox;
+}
Added: trunk/client/gtk/frontend.c
===================================================================
--- trunk/client/gtk/frontend.c (rev 0)
+++ trunk/client/gtk/frontend.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,210 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "gtkbugs.h"
+#include <gdk/gdkkeysyms.h>
+
+static const int MAX_NUMBER_OF_WIDGETS_PER_EVENT = 2;
+
+GHashTable *frontend_widgets;
+gboolean frontend_waiting_for_network;
+
+static void set_sensitive(G_GNUC_UNUSED void *key, GuiWidgetState * gui,
+ G_GNUC_UNUSED void *user_data)
+{
+ if (gui->destroy_only)
+ /* Do not modify sensitivity on destroy only events
+ */
+ return;
+
+ if (frontend_waiting_for_network)
+ gui->next = FALSE;
+
+ if (gui->widget != NULL && gui->next != gui->current) {
+ if (GTK_IS_ACTION(gui->widget))
+ action_set_sensitive(GTK_ACTION(gui->widget),
+ gui->next);
+ else
+ widget_set_sensitive(gui->widget, gui->next);
+ }
+ if (gui->next != gui->current) {
+ switch (gui->id) {
+ case GUI_ROAD:
+ guimap_single_click_set_road_mask(gui->next);
+ break;
+ case GUI_SHIP:
+ guimap_single_click_set_ship_mask(gui->next);
+ break;
+ case GUI_BRIDGE:
+ guimap_single_click_set_bridge_mask(gui->next);
+ break;
+ case GUI_SETTLEMENT:
+ guimap_single_click_set_settlement_mask(gui->next);
+ break;
+ case GUI_CITY:
+ guimap_single_click_set_city_mask(gui->next);
+ break;
+ case GUI_CITY_WALL:
+ guimap_single_click_set_city_wall_mask(gui->next);
+ break;
+ case GUI_MOVE_SHIP:
+ guimap_single_click_set_ship_move_mask(gui->next);
+ break;
+ default:
+ break;
+ }
+ }
+ gui->current = gui->next;
+ gui->next = FALSE;
+}
+
+void frontend_gui_register_init(void)
+{
+ frontend_widgets = g_hash_table_new(NULL, NULL);
+}
+
+void frontend_gui_update(void)
+{
+ route_gui_event(GUI_UPDATE);
+ g_hash_table_foreach(frontend_widgets, (GHFunc) set_sensitive,
+ NULL);
+}
+
+void frontend_gui_check(GuiEvent event, gboolean sensitive)
+{
+ GuiWidgetState *gui;
+ gint i;
+ gint key = event * MAX_NUMBER_OF_WIDGETS_PER_EVENT;
+
+ /* Set all related widgets */
+ for (i = 0; i < MAX_NUMBER_OF_WIDGETS_PER_EVENT; ++i) {
+ gui = g_hash_table_lookup(frontend_widgets,
+ GINT_TO_POINTER(key + i));
+ if (gui != NULL)
+ gui->next = sensitive;
+ }
+}
+
+static GuiWidgetState *gui_new(void *widget, gint id)
+{
+ gint i;
+ gint key = id * MAX_NUMBER_OF_WIDGETS_PER_EVENT;
+ GuiWidgetState *gui = g_malloc0(sizeof(*gui));
+ gui->widget = widget;
+ gui->id = id;
+
+ /* Find an empty key */
+ i = 0;
+ while (i < MAX_NUMBER_OF_WIDGETS_PER_EVENT) {
+ if (g_hash_table_lookup(frontend_widgets,
+ GINT_TO_POINTER(key + i)))
+ ++i;
+ else
+ break;
+ }
+ g_assert(i != MAX_NUMBER_OF_WIDGETS_PER_EVENT);
+ g_hash_table_insert(frontend_widgets, GINT_TO_POINTER(key + i),
+ gui);
+ return gui;
+}
+
+static void gui_free(GuiWidgetState * gui)
+{
+ gint i;
+ gint key = gui->id * MAX_NUMBER_OF_WIDGETS_PER_EVENT;
+
+ /* Find an empty key */
+ for (i = 0; i < MAX_NUMBER_OF_WIDGETS_PER_EVENT; ++i) {
+ g_hash_table_remove(frontend_widgets,
+ GINT_TO_POINTER(key + i));
+ }
+ g_free(gui);
+}
+
+static void route_event(G_GNUC_UNUSED void *widget, GuiWidgetState * gui)
+{
+ route_gui_event(gui->id);
+}
+
+static void destroy_event_cb(G_GNUC_UNUSED void *widget,
+ GuiWidgetState * gui)
+{
+ gui_free(gui);
+}
+
+static void destroy_route_event_cb(G_GNUC_UNUSED void *widget,
+ GuiWidgetState * gui)
+{
+ route_gui_event(gui->id);
+ gui_free(gui);
+}
+
+void frontend_gui_register_destroy(GtkWidget * widget, GuiEvent id)
+{
+ GuiWidgetState *gui = gui_new(widget, id);
+ gui->destroy_only = TRUE;
+ g_signal_connect(G_OBJECT(widget), "destroy",
+ G_CALLBACK(destroy_route_event_cb), gui);
+}
+
+void frontend_gui_register_action(GtkAction * action, GuiEvent id)
+{
+ GuiWidgetState *gui = gui_new(action, id);
+ gui->signal = NULL;
+ gui->current = TRUE;
+ gui->next = FALSE;
+}
+
+void frontend_gui_register(GtkWidget * widget, GuiEvent id,
+ const gchar * signal)
+{
+ GuiWidgetState *gui = gui_new(widget, id);
+ gui->signal = signal;
+ gui->current = TRUE;
+ gui->next = FALSE;
+ g_signal_connect(G_OBJECT(widget), "destroy",
+ G_CALLBACK(destroy_event_cb), gui);
+ if (signal != NULL)
+ g_signal_connect(G_OBJECT(widget), signal,
+ G_CALLBACK(route_event), gui);
+}
+
+gint hotkeys_handler(G_GNUC_UNUSED GtkWidget * w, GdkEvent * e,
+ G_GNUC_UNUSED gpointer data)
+{
+ GuiWidgetState *gui;
+ GuiEvent arg;
+ switch (e->key.keyval) {
+ case GDK_Escape:
+ arg = GUI_QUOTE_REJECT;
+ break;
+ default:
+ return 0; /* not handled */
+ }
+ gui = g_hash_table_lookup(frontend_widgets,
+ GINT_TO_POINTER(arg *
+ MAX_NUMBER_OF_WIDGETS_PER_EVENT));
+ if (!gui || !gui->current)
+ return 0; /* not handled */
+ route_gui_event(arg);
+ return 1; /* handled */
+}
Added: trunk/client/gtk/frontend.h
===================================================================
--- trunk/client/gtk/frontend.h (rev 0)
+++ trunk/client/gtk/frontend.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,336 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2003,2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _frontend_h
+#define _frontend_h
+
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <string.h>
+#include "callback.h"
+#include "colors.h"
+#include "quoteinfo.h"
+
+/* All graphics events. */
+typedef enum {
+ GUI_UPDATE,
+ GUI_CONNECT,
+ GUI_CONNECT_TRY,
+ GUI_CONNECT_CANCEL,
+ GUI_DISCONNECT,
+ GUI_CHANGE_NAME,
+ GUI_QUIT,
+ GUI_ROLL,
+ GUI_TRADE,
+ GUI_UNDO,
+ GUI_FINISH,
+ GUI_ROAD,
+ GUI_SHIP,
+ GUI_MOVE_SHIP,
+ GUI_BRIDGE,
+ GUI_SETTLEMENT,
+ GUI_CITY,
+ GUI_CITY_WALL,
+ GUI_BUY_DEVELOP,
+ GUI_PLAY_DEVELOP,
+ GUI_MONOPOLY,
+ GUI_PLENTY,
+ GUI_DISCARD,
+ GUI_CHOOSE_GOLD,
+ GUI_TRADE_CALL,
+ GUI_TRADE_ACCEPT,
+ GUI_TRADE_FINISH,
+ GUI_QUOTE_SUBMIT,
+ GUI_QUOTE_DELETE,
+ GUI_QUOTE_REJECT
+} GuiEvent;
+
+#include "gui.h"
+
+/* Information about a GUI component */
+typedef struct {
+ GtkWidget *widget; /* the GTK widget */
+ GuiEvent id; /* widget id */
+ gboolean destroy_only; /* react to destroy signal */
+ const gchar *signal; /* signal attached */
+ gboolean current; /* is widget currently sensitive? */
+ gboolean next; /* should widget be sensitive? */
+} GuiWidgetState;
+
+/** all widgets are inactive while waiting for network. */
+extern gboolean frontend_waiting_for_network;
+
+/** set all widgets to their programmed state. */
+void frontend_gui_update(void);
+
+/** program the state of a widget for when frontend_gui_update is called. */
+void frontend_gui_check(GuiEvent event, gboolean sensitive);
+
+/** initialise the frontend_gui_register_* functions */
+void frontend_gui_register_init(void);
+
+/** register a new destroy-only widget. */
+void frontend_gui_register_destroy(GtkWidget * widget, GuiEvent id);
+
+/** register an action. */
+void frontend_gui_register_action(GtkAction * action, GuiEvent id);
+
+/** register a new "normal" widget. */
+void frontend_gui_register(GtkWidget * widget, GuiEvent id,
+ const gchar * signal);
+
+/** route an event to the gui event function */
+void frontend_gui_route_event(GuiEvent event);
+
+/* callbacks */
+void frontend_init(int argc, char **argv);
+void frontend_new_statistics(gint player_num, StatisticType type,
+ gint num);
+void frontend_new_points(gint player_num, Points * points, gboolean added);
+void frontend_viewer_name(gint viewer_num, const gchar * name);
+void frontend_player_name(gint player_num, const gchar * name);
+void frontend_player_style(gint player_num, const gchar * style);
+void frontend_player_quit(gint player_num);
+void frontend_viewer_quit(gint player_num);
+void frontend_disconnect(void);
+void frontend_offline(void);
+void frontend_discard(void);
+void frontend_discard_add(gint player_num, gint discard_num);
+void frontend_discard_remove(gint player_num);
+void frontend_discard_done(void);
+void frontend_gold(void);
+void frontend_gold_add(gint player_num, gint gold_num);
+void frontend_gold_remove(gint player_num, gint * resources);
+void frontend_gold_choose(gint gold_num, const gint * bank);
+void frontend_gold_done(void);
+void frontend_setup(unsigned num_settlements, unsigned num_roads);
+void frontend_quote(gint player_num, gint * they_supply,
+ gint * they_receive);
+void frontend_roadbuilding(gint num_roads);
+void frontend_monopoly(void);
+void frontend_plenty(const gint * bank);
+void frontend_turn(void);
+void frontend_trade_player_end(gint player_num);
+void frontend_trade_add_quote(gint player_num, gint quote_num,
+ const gint * they_supply,
+ const gint * they_receive);
+void frontend_trade_remove_quote(int player_num, int quote_num);
+void frontend_quote_player_end(gint player_num);
+void frontend_quote_add(gint player_num, gint quote_num,
+ const gint * they_supply,
+ const gint * they_receive);
+void frontend_quote_remove(gint player_num, gint quote_num);
+void frontend_quote_start(void);
+void frontend_quote_end(void);
+void frontend_quote_monitor(void);
+void frontend_rolled_dice(gint die1, gint die2, gint player_num);
+void frontend_bought_develop(DevelType type);
+void frontend_played_develop(gint player_num, gint card_idx,
+ DevelType type);
+void frontend_resource_change(Resource type, gint new_amount);
+void frontend_robber(void);
+void frontend_steal_building(void);
+void frontend_steal_ship(void);
+void frontend_robber_done(void);
+void frontend_game_over(gint player, gint points);
+
+/* connect.c */
+const gchar *connect_get_server(void);
+const gchar *connect_get_port(void);
+const gchar *connect_get_name(void);
+gboolean connect_get_viewer(void);
+const gchar *connect_get_style(void);
+void connect_set_server(const gchar * server);
+void connect_set_port(const gchar * port);
+void connect_set_name(const gchar * name);
+void connect_set_viewer(gboolean viewer);
+void connect_set_style(const gchar * style);
+void connect_set_meta_server(const gchar * meta_server);
+void connect_create_dlg(void);
+
+/* trade.c */
+GtkWidget *trade_build_page(void);
+gboolean can_call_for_quotes(void);
+gboolean trade_valid_selection(void);
+const gint *trade_we_supply(void);
+const gint *trade_we_receive(void);
+const QuoteInfo *trade_current_quote(void);
+void trade_finish(void);
+void trade_add_quote(int player_num, int quote_num,
+ const gint * they_supply, const gint * they_receive);
+void trade_delete_quote(int player_num, int quote_num);
+void trade_player_finish(gint player_num);
+void trade_begin(void);
+void trade_format_quote(const QuoteInfo * quote, gchar * buffer);
+void trade_new_trade(void);
+void trade_perform_maritime(gint ratio, Resource supply, Resource receive);
+void trade_perform_domestic(gint player_num, gint partner_num,
+ gint quote_num, const gint * they_supply,
+ const gint * they_receive);
+void frontend_trade_domestic(gint partner_num, gint quote_num,
+ const gint * we_supply,
+ const gint * we_receive);
+void frontend_trade_maritime(gint ratio, Resource we_supply,
+ Resource we_receive);
+
+/* quote.c */
+GtkWidget *quote_build_page(void);
+gboolean can_submit_quote(void);
+gboolean can_delete_quote(void);
+gboolean can_reject_quote(void);
+gint quote_next_num(void);
+const gint *quote_we_supply(void);
+const gint *quote_we_receive(void);
+const QuoteInfo *quote_current_quote(void);
+void quote_begin_again(gint player_num, const gint * they_supply,
+ const gint * they_receive);
+void quote_begin(gint player_num, const gint * they_supply,
+ const gint * they_receive);
+void quote_add_quote(gint player_num, gint quote_num,
+ const gint * they_supply, const gint * they_receive);
+void quote_delete_quote(gint player_num, gint quote_num);
+void quote_player_finish(gint player_num);
+void quote_finish(void);
+void frontend_quote_trade(gint player_num, gint partner_num,
+ gint quote_num, const gint * they_supply,
+ const gint * they_receive);
+
+/* legend.c */
+GtkWidget *legend_create_dlg(void);
+GtkWidget *legend_create_content(void);
+
+/* gui_develop.c */
+GtkWidget *develop_build_page(void);
+gint develop_current_idx(void);
+void develop_reset(void);
+
+/* discard.c */
+GtkWidget *discard_build_page(void);
+gboolean can_discard(void);
+void discard_get_list(gint * discards);
+void discard_begin(void);
+void discard_player_must(gint player_num, gint discard_num);
+void discard_player_did(gint player_num);
+void discard_end(void);
+
+/* gold.c */
+GtkWidget *gold_build_page(void);
+gboolean can_choose_gold(void);
+void choose_gold_get_list(gint * choice);
+void gold_choose_begin(void);
+void gold_choose_player_prepare(gint player_num, gint gold_num);
+void gold_choose_player_must(gint gold_num, const gint * bank);
+void gold_choose_player_did(gint player_num, gint * resource_list);
+void gold_choose_end(void);
+
+/* identity.c */
+GtkWidget *identity_build_panel(void);
+void identity_draw(void);
+void identity_set_dice(gint die1, gint die2);
+void identity_reset(void);
+
+/* resource.c */
+GtkWidget *resource_build_panel(void);
+/** Draw the resources on the image.
+ * @param image The image to draw the resources on
+ * @param resources The resources
+ * @param max_width If > 0, use this for the maximum width
+ */
+void resource_format_type_image(GtkImage * image, const gint * resources,
+ gint max_width);
+
+/* player.c */
+GtkWidget *player_build_summary(void);
+GtkWidget *player_build_turn_area(void);
+void player_clear_summary(void);
+void player_init(void);
+/** The colour of the player, or viewer */
+GdkColor *player_or_viewer_color(gint player_num);
+/** The colour of the player */
+GdkColor *player_color(gint player_num);
+/** Create an icon of the player, suitable for display on widget,
+ * for player_num, who is connected.
+ * You should unref the pixbuf when it is no longer needed
+ */
+GdkPixbuf *player_create_icon(GtkWidget * widget, gint player_num,
+ gboolean connected);
+void player_show_current(gint player_num);
+void set_num_players(gint num);
+
+/* chat.c */
+/** Create the chat widget */
+GtkWidget *chat_build_panel(void);
+/** Determine if the focus should be moved to the chat widget */
+void chat_set_grab_focus_on_update(gboolean grab);
+/** Set the focus to the chat widget */
+void chat_set_focus(void);
+/** A player/viewer has changed his name */
+void chat_player_name(gint player_num, const gchar * name);
+/** A player/viewer has changed his style */
+void chat_player_style(gint player_num);
+/** A player has quit */
+void chat_player_quit(gint player_num);
+/** A viewer has quit */
+void chat_viewer_quit(gint viewer_num);
+/** Clear all names */
+void chat_clear_names(void);
+/** Parse the chat for commands */
+void chat_parser(gint player_num, const gchar * chat_str);
+
+/* name.c */
+void name_create_dlg(void);
+
+/* settingscreen.c */
+void settings_init(void);
+GtkWidget *settings_create_dlg(void);
+
+/* monopoly.c */
+Resource monopoly_type(void);
+void monopoly_destroy_dlg(void);
+void monopoly_create_dlg(void);
+
+/* plenty.c */
+void plenty_resources(gint * plenty);
+void plenty_destroy_dlg(void);
+void plenty_create_dlg(const gint * bank);
+gboolean plenty_can_activate(void);
+
+/* gameover.c */
+GtkWidget *gameover_create_dlg(gint player_num, gint num_points);
+
+#define PIONEERS_PIXMAP_DICE "pioneers/dice.png"
+#define PIONEERS_PIXMAP_TRADE "pioneers/trade.png"
+#define PIONEERS_PIXMAP_ROAD "pioneers/road.png"
+#define PIONEERS_PIXMAP_SHIP "pioneers/ship.png"
+#define PIONEERS_PIXMAP_SHIP_MOVEMENT "pioneers/ship_move.png"
+#define PIONEERS_PIXMAP_BRIDGE "pioneers/bridge.png"
+#define PIONEERS_PIXMAP_SETTLEMENT "pioneers/settlement.png"
+#define PIONEERS_PIXMAP_CITY "pioneers/city.png"
+#define PIONEERS_PIXMAP_CITY_WALL "pioneers/city_wall.png"
+#define PIONEERS_PIXMAP_DEVELOP "pioneers/develop.png"
+#define PIONEERS_PIXMAP_FINISH "pioneers/finish.png"
+
+#define PIONEERS_PIXMAP_BRICK "pioneers/brick.png"
+#define PIONEERS_PIXMAP_GRAIN "pioneers/grain.png"
+#define PIONEERS_PIXMAP_LUMBER "pioneers/lumber.png"
+#define PIONEERS_PIXMAP_ORE "pioneers/ore.png"
+#define PIONEERS_PIXMAP_WOOL "pioneers/wool.png"
+
+#endif
Added: trunk/client/gtk/gameover.c
===================================================================
--- trunk/client/gtk/gameover.c (rev 0)
+++ trunk/client/gtk/gameover.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,69 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+
+GtkWidget *gameover_create_dlg(gint player_num, gint num_points)
+{
+ GtkWidget *dlg;
+ GtkWidget *dlg_vbox;
+ GtkWidget *vbox;
+ GtkWidget *lbl;
+ char buff[512];
+
+ dlg = gtk_dialog_new_with_buttons(_("Game over"),
+ GTK_WINDOW(app_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK, GTK_RESPONSE_OK,
+ NULL);
+ gtk_widget_realize(dlg);
+ gdk_window_set_functions(dlg->window,
+ GDK_FUNC_MOVE | GDK_FUNC_CLOSE);
+
+ dlg_vbox = GTK_DIALOG(dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ vbox = gtk_vbox_new(FALSE, 50);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 20);
+
+ sprintf(buff, _("%s has won the game with %d victory points!"),
+ player_name(player_num, TRUE), num_points);
+ log_message(MSG_INFO,
+ _("%s has won the game with %d victory points!\n"),
+ player_name(player_num, TRUE), num_points);
+ lbl = gtk_label_new(buff);
+ gtk_widget_show(lbl);
+ gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, TRUE, 0);
+
+ sprintf(buff, _("All praise %s, Lord of the known world!"),
+ player_name(player_num, TRUE));
+ lbl = gtk_label_new(buff);
+ gtk_widget_show(lbl);
+ gtk_box_pack_start(GTK_BOX(vbox), lbl, FALSE, TRUE, 0);
+
+ gtk_widget_show(dlg);
+ g_signal_connect(dlg, "response",
+ G_CALLBACK(gtk_widget_destroy), NULL);
+
+ return dlg;
+}
Added: trunk/client/gtk/gold.c
===================================================================
--- trunk/client/gtk/gold.c (rev 0)
+++ trunk/client/gtk/gold.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,281 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "resource-table.h"
+#include "gtkbugs.h"
+#include "common_gtk.h"
+
+enum {
+ GOLD_COLUMN_PLAYER_ICON, /**< Player icon */
+ GOLD_COLUMN_PLAYER_NUM, /**< Internal: player number */
+ GOLD_COLUMN_PLAYER_NAME, /**< Player name */
+ GOLD_COLUMN_AMOUNT, /**< The amount to choose */
+ GOLD_COLUMN_LAST
+};
+
+static GtkListStore *gold_store; /**< the gold data */
+static GtkWidget *gold_widget; /**< the gold widget */
+
+static struct {
+ GtkWidget *dlg;
+ GtkWidget *resource_widget;
+} gold;
+
+static void amount_changed_cb(G_GNUC_UNUSED ResourceTable * rt,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ frontend_gui_update();
+}
+
+/* fill an array with the current choice, to send to the server */
+void choose_gold_get_list(gint * choice)
+{
+ if (gold.dlg != NULL)
+ resource_table_get_amount(RESOURCETABLE
+ (gold.resource_widget), choice);
+}
+
+static void button_destroyed(G_GNUC_UNUSED GtkWidget * w, gpointer num)
+{
+ if (callback_mode == MODE_GOLD)
+ gold_choose_player_must(GPOINTER_TO_INT(num), get_bank());
+}
+
+void gold_choose_player_must(gint num, const gint * bank)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *vbox;
+ char buff[128];
+
+ gold.dlg = gtk_dialog_new_with_buttons(_("Choose resources"),
+ GTK_WINDOW(app_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK, NULL);
+ g_signal_connect(G_OBJECT(gold.dlg), "destroy",
+ G_CALLBACK(gtk_widget_destroyed), &gold.dlg);
+ gtk_widget_realize(gold.dlg);
+ /* Disable close */
+ gdk_window_set_functions(gold.dlg->window,
+ GDK_FUNC_ALL | GDK_FUNC_CLOSE);
+
+ dlg_vbox = GTK_DIALOG(gold.dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+
+ if (num == 1)
+ sprintf(buff, _("You may choose 1 resource"));
+ else
+ sprintf(buff, _("You may choose %d resources"), num);
+
+ gold.resource_widget =
+ resource_table_new(buff, RESOURCE_TABLE_MORE_IN_HAND, TRUE,
+ TRUE);
+ resource_table_set_total(RESOURCETABLE(gold.resource_widget),
+ /* Text for total in choose gold dialog */
+ _("Total resources"), num);
+ resource_table_limit_bank(RESOURCETABLE(gold.resource_widget),
+ TRUE);
+ resource_table_set_bank(RESOURCETABLE(gold.resource_widget), bank);
+ gtk_widget_show(gold.resource_widget);
+ gtk_box_pack_start(GTK_BOX(vbox), gold.resource_widget, FALSE,
+ TRUE, 0);
+ g_signal_connect(G_OBJECT(gold.resource_widget), "change",
+ G_CALLBACK(amount_changed_cb), NULL);
+
+ frontend_gui_register(gui_get_dialog_button
+ (GTK_DIALOG(gold.dlg), 0), GUI_CHOOSE_GOLD,
+ "clicked");
+ /* This _must_ be after frontend_gui_register, otherwise the
+ * regeneration of the button happens before the destruction, which
+ * results in an incorrectly sensitive OK button. */
+ g_signal_connect(gui_get_dialog_button(GTK_DIALOG(gold.dlg), 0),
+ "destroy", G_CALLBACK(button_destroyed),
+ GINT_TO_POINTER(num));
+ frontend_gui_update();
+ gtk_widget_show(gold.dlg);
+}
+
+void gold_choose_player_prepare(gint player_num, gint num)
+{
+ GtkTreeIter iter;
+ GdkPixbuf *pixbuf;
+ enum TFindResult found;
+
+ /* Search for a place to add information about the player */
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(gold_store), &iter,
+ GOLD_COLUMN_PLAYER_NUM, player_num);
+ switch (found) {
+ case FIND_NO_MATCH:
+ gtk_list_store_append(gold_store, &iter);
+ break;
+ case FIND_MATCH_INSERT_BEFORE:
+ gtk_list_store_insert_before(gold_store, &iter, &iter);
+ break;
+ case FIND_MATCH_EXACT:
+ break;
+ default:
+ g_error("unknown case in gold_choose_player_prepare");
+ };
+
+ pixbuf = player_create_icon(gold_widget, player_num, TRUE);
+ gtk_list_store_set(gold_store, &iter,
+ GOLD_COLUMN_PLAYER_ICON, pixbuf,
+ GOLD_COLUMN_PLAYER_NUM, player_num,
+ GOLD_COLUMN_PLAYER_NAME, player_name(player_num,
+ TRUE),
+ GOLD_COLUMN_AMOUNT, num, -1);
+ g_object_unref(pixbuf);
+}
+
+void gold_choose_player_did(gint player_num,
+ G_GNUC_UNUSED gint * resources)
+{
+ GtkTreeIter iter;
+ enum TFindResult found;
+
+ /* check if the player was in the list. If not, it is not an error.
+ * That happens if the player auto-discards. */
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(gold_store), &iter,
+ GOLD_COLUMN_PLAYER_NUM, player_num);
+ if (found == FIND_MATCH_EXACT) {
+ gtk_list_store_remove(gold_store, &iter);
+ if (player_num == my_player_num()) {
+ gtk_widget_destroy(gold.dlg);
+ gold.dlg = NULL;
+ }
+ }
+}
+
+void gold_choose_begin(void)
+{
+ gtk_list_store_clear(GTK_LIST_STORE(gold_store));
+ gui_gold_show();
+}
+
+void gold_choose_end(void)
+{
+ gtk_list_store_clear(GTK_LIST_STORE(gold_store));
+ gui_gold_hide();
+ if (gold.dlg != NULL) { /* shouldn't happen */
+ gtk_widget_destroy(gold.dlg);
+ gold.dlg = NULL;
+ }
+}
+
+GtkWidget *gold_build_page(void)
+{
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *alignment;
+ GtkWidget *scroll_win;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 3, 3);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
+
+ label = gtk_label_new(NULL);
+ /* Caption for list of player that must choose gold */
+ gtk_label_set_markup(GTK_LABEL(label),
+ _("<b>Waiting for players to choose</b>"));
+ gtk_widget_show(label);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_container_add(GTK_CONTAINER(alignment), label);
+
+ scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
+ (scroll_win), GTK_SHADOW_IN);
+ gtk_widget_show(scroll_win);
+ gtk_box_pack_start(GTK_BOX(vbox), scroll_win, TRUE, TRUE, 0);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ gold_store = gtk_list_store_new(GOLD_COLUMN_LAST, GDK_TYPE_PIXBUF, /* player icon */
+ G_TYPE_INT, /* player number */
+ G_TYPE_STRING, /* text */
+ G_TYPE_INT); /* amount to choose */
+ gold_widget =
+ gtk_tree_view_new_with_model(GTK_TREE_MODEL(gold_store));
+
+ column = gtk_tree_view_column_new_with_attributes("",
+ gtk_cell_renderer_pixbuf_new
+ (), "pixbuf",
+ GOLD_COLUMN_PLAYER_ICON,
+ NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_GROW_ONLY);
+ set_pixbuf_tree_view_column_autogrow(gold_widget, column);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(gold_widget), column);
+
+ column = gtk_tree_view_column_new_with_attributes("",
+ gtk_cell_renderer_text_new
+ (), "text",
+ GOLD_COLUMN_PLAYER_NAME,
+ NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_column_set_expand(column, TRUE);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(gold_widget), column);
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes("",
+ renderer,
+ "text",
+ GOLD_COLUMN_AMOUNT,
+ NULL);
+ g_object_set(renderer, "xalign", 1.0f, NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_GROW_ONLY);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(gold_widget), column);
+
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(gold_widget),
+ FALSE);
+ gtk_widget_show(gold_widget);
+ gtk_container_add(GTK_CONTAINER(scroll_win), gold_widget);
+
+ return vbox;
+}
+
+gboolean can_choose_gold(void)
+{
+ if (gold.dlg == NULL)
+ return FALSE;
+
+ return
+ resource_table_is_total_reached(RESOURCETABLE
+ (gold.resource_widget));
+}
Added: trunk/client/gtk/gui.c
===================================================================
--- trunk/client/gtk/gui.c (rev 0)
+++ trunk/client/gtk/gui.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,1625 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004-2005 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <math.h>
+#include <ctype.h>
+#include <assert.h>
+#ifdef HAVE_HELP
+#include <libgnome/libgnome.h>
+#endif
+
+#include <hildon-widgets/hildon-program.h>
+
+#include "aboutbox.h"
+#include "frontend.h"
+#include "cards.h"
+#include "cost.h"
+#include "log.h"
+#include "common_gtk.h"
+#include "histogram.h"
+#include "theme.h"
+#include "config-gnome.h"
+
+static GtkWidget *preferences_dlg;
+GtkWidget *app_window; /* main application window */
+
+#define MAP_WIDTH 350 /* default map width */
+#define MAP_HEIGHT 200 /* default map height */
+
+#define PIONEERS_ICON_FILE "pioneers.png"
+
+static GuiMap *gmap; /* handle to map drawing code */
+
+enum {
+ MAP_PAGE, /* the map */
+ TRADE_PAGE, /* trading interface */
+ QUOTE_PAGE, /* submit quotes page */
+ LEGEND_PAGE, /* legend */
+ SPLASH_PAGE /* splash screen */
+};
+
+static GtkWidget *map_notebook; /* map area panel */
+static GtkWidget *trade_page; /* trade page in map area */
+static GtkWidget *quote_page; /* quote page in map area */
+static GtkWidget *legend_page; /* splash page in map area */
+static GtkWidget *splash_page; /* splash page in map area */
+
+static GtkWidget *develop_notebook; /* development card area panel */
+
+static GtkWidget *messages_txt; /* messages text widget */
+static GtkWidget *prompt_lbl; /* big prompt messages */
+
+static GtkWidget *app_bar;
+static GtkWidget *net_status;
+static GtkWidget *vp_target_status;
+
+static GtkWidget *main_paned; /* Horizontal for 16:9, Vertical for 4:3 mode */
+static GtkWidget *chat_panel = NULL; /* Panel for chat, placed below or to the right */
+
+static GtkUIManager *ui_manager = NULL; /* The manager of the GtkActions */
+static GtkWidget *toolbar = NULL; /* The toolbar */
+
+static gboolean toolbar_show_accelerators = TRUE;
+static gboolean color_messages_enabled = TRUE;
+static gboolean legend_page_enabled = TRUE;
+
+static GList *rules_callback_list = NULL;
+
+#define PIONEERS_PIXMAP_SPLASH "pioneers/splash.png"
+
+static const gchar *pioneers_pixmaps[] = {
+ PIONEERS_PIXMAP_DICE,
+ PIONEERS_PIXMAP_TRADE,
+ PIONEERS_PIXMAP_ROAD,
+ PIONEERS_PIXMAP_SHIP,
+ PIONEERS_PIXMAP_SHIP_MOVEMENT,
+ PIONEERS_PIXMAP_BRIDGE,
+ PIONEERS_PIXMAP_SETTLEMENT,
+ PIONEERS_PIXMAP_CITY,
+ PIONEERS_PIXMAP_CITY_WALL,
+ PIONEERS_PIXMAP_DEVELOP,
+ PIONEERS_PIXMAP_FINISH
+};
+
+static const gchar *resources_pixmaps[] = {
+ PIONEERS_PIXMAP_BRICK,
+ PIONEERS_PIXMAP_GRAIN,
+ PIONEERS_PIXMAP_ORE,
+ PIONEERS_PIXMAP_WOOL,
+ PIONEERS_PIXMAP_LUMBER
+};
+
+static struct {
+ GdkPixmap *p;
+ GdkBitmap *b;
+ GdkGC *gcp, *gcb;
+} resource_pixmap[NO_RESOURCE];
+static gint resource_pixmap_res = 0;
+
+static void gui_set_toolbar_visible(void);
+static void gui_toolbar_show_accelerators(gboolean show_accelerators);
+
+static void game_new_cb(void)
+{
+ route_gui_event(GUI_CONNECT);
+}
+
+static void game_leave_cb(void)
+{
+ route_gui_event(GUI_DISCONNECT);
+}
+
+static void playername_cb(void)
+{
+ route_gui_event(GUI_CHANGE_NAME);
+}
+
+static void game_quit_cb(void)
+{
+ route_gui_event(GUI_QUIT);
+}
+
+static void roll_dice_cb(void)
+{
+ route_gui_event(GUI_ROLL);
+}
+
+static void trade_cb(void)
+{
+ route_gui_event(GUI_TRADE);
+}
+
+static void undo_cb(void)
+{
+ route_gui_event(GUI_UNDO);
+}
+
+static void finish_cb(void)
+{
+ route_gui_event(GUI_FINISH);
+}
+
+static void build_road_cb(void)
+{
+ route_gui_event(GUI_ROAD);
+}
+
+static void build_ship_cb(void)
+{
+ route_gui_event(GUI_SHIP);
+}
+
+static void move_ship_cb(void)
+{
+ route_gui_event(GUI_MOVE_SHIP);
+}
+
+static void build_bridge_cb(void)
+{
+ route_gui_event(GUI_BRIDGE);
+}
+
+static void build_settlement_cb(void)
+{
+ route_gui_event(GUI_SETTLEMENT);
+}
+
+static void build_city_cb(void)
+{
+ route_gui_event(GUI_CITY);
+}
+
+static void buy_development_cb(void)
+{
+ route_gui_event(GUI_BUY_DEVELOP);
+}
+
+static void build_city_wall_cb(void)
+{
+ route_gui_event(GUI_CITY_WALL);
+}
+
+static void showhide_toolbar_cb(void);
+static void preferences_cb(void);
+
+static void help_about_cb(void);
+static void game_legend_cb(void);
+static void game_histogram_cb(void);
+static void game_settings_cb(void);
+#ifdef HAVE_HELP
+static void help_manual_cb(void);
+#endif
+
+/* Normal items */
+static GtkActionEntry entries[] = {
+ {"GameMenu", NULL, N_("_Game"), NULL, NULL, NULL},
+ {"GameNew", GTK_STOCK_NEW, N_("_New game"), "<control>N",
+ N_("Start a new game"), game_new_cb},
+ {"GameLeave", GTK_STOCK_STOP, N_("_Leave game"), NULL,
+ N_("Leave this game"), game_leave_cb},
+#ifdef ADMIN_GTK
+ {"GameAdmin", NULL, N_("_Admin"), "<control>A",
+ N_("Administer Pioneers server"), show_admin_interface},
+#endif
+ {"PlayerName", NULL, N_("_Player name"), "<control>P",
+ N_("Change your player name"), playername_cb},
+ {"Legend", GTK_STOCK_DIALOG_INFO, N_("_Legend"), NULL,
+ N_("Terrain legend and building costs"), game_legend_cb},
+ {"GameSettings", GTK_STOCK_DIALOG_INFO, N_("_Game Settings"), NULL,
+ N_("Settings for the current game"), game_settings_cb},
+ {"DiceHistogram", GTK_STOCK_DIALOG_INFO, N_("_Dice Histogram"),
+ NULL, N_("Histogram of dice rolls"), game_histogram_cb},
+ {"GameQuit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q",
+ N_("Quit the program"), game_quit_cb},
+ {"ActionsMenu", NULL, N_("_Actions"), NULL, NULL, NULL},
+ {"RollDice", PIONEERS_PIXMAP_DICE, N_("Roll Dice"), "F1",
+ N_("Roll the dice"), roll_dice_cb},
+ {"Trade", PIONEERS_PIXMAP_TRADE, N_("Trade"), "F2", N_("Trade"),
+ trade_cb},
+ {"Undo", GTK_STOCK_UNDO, N_("Undo"), "F3", N_("Undo"), undo_cb},
+ {"Finish", PIONEERS_PIXMAP_FINISH, N_("Finish"), "F4",
+ N_("Finish"), finish_cb},
+ {"BuildRoad", PIONEERS_PIXMAP_ROAD, N_("Road"), "F5",
+ N_("Build a road"), build_road_cb},
+ {"BuildShip", PIONEERS_PIXMAP_SHIP, N_("Ship"), "F6",
+ N_("Build a ship"), build_ship_cb},
+ {"MoveShip", PIONEERS_PIXMAP_SHIP_MOVEMENT, N_("Move Ship"), "F7",
+ N_("Move a ship"), move_ship_cb},
+ {"BuildBridge", PIONEERS_PIXMAP_BRIDGE, N_("Bridge"), "F8",
+ N_("Build a bridge"), build_bridge_cb},
+ {"BuildSettlement", PIONEERS_PIXMAP_SETTLEMENT, N_("Settlement"),
+ "F9", N_("Build a settlement"), build_settlement_cb},
+ {"BuildCity", PIONEERS_PIXMAP_CITY, N_("City"), "F10",
+ N_("Build a city"), build_city_cb},
+ {"BuyDevelopment", PIONEERS_PIXMAP_DEVELOP, N_("Develop"), "F11",
+ N_("Buy a development card"), buy_development_cb},
+ {"BuildCityWall", PIONEERS_PIXMAP_CITY_WALL, N_("City Wall"), NULL,
+ N_("Build a city wall"), build_city_wall_cb},
+
+ {"SettingsMenu", NULL, N_("_Settings"), NULL, NULL, NULL},
+ {"Preferences", GTK_STOCK_PREFERENCES, N_("Prefere_nces"), NULL,
+ N_("Configure the application"), preferences_cb},
+
+ {"HelpMenu", NULL, N_("_Help"), NULL, NULL, NULL},
+ {"HelpAbout", NULL, N_("_About Pioneers"), NULL,
+ N_("Information about Pioneers"), help_about_cb},
+#ifdef HAVE_HELP
+ {"HelpManual", GTK_STOCK_HELP, N_("_Help"), "<control>H",
+ N_("Show the manual"), help_manual_cb}
+#endif
+};
+
+/* Toggle items */
+static GtkToggleActionEntry toggle_entries[] = {
+ {"ShowHideToolbar", NULL, N_("_Toolbar"), NULL,
+ N_("Show or hide the toolbar"), showhide_toolbar_cb, TRUE}
+};
+
+/* *INDENT-OFF* */
+static const char *ui_description =
+"<ui>"
+" <menubar name='MainMenu'>"
+" <menu action='GameMenu'>"
+" <menuitem action='GameNew'/>"
+" <menuitem action='GameLeave'/>"
+#ifdef ADMIN_GTK
+" <menuitem action='GameAdmin'/>"
+#endif
+" <separator/>"
+" <menuitem action='PlayerName'/>"
+" <separator/>"
+" <menuitem action='Legend'/>"
+" <menuitem action='GameSettings'/>"
+" <menuitem action='DiceHistogram'/>"
+" <separator/>"
+" <menuitem action='GameQuit'/>"
+" </menu>"
+" <menu action='ActionsMenu'>"
+" <menuitem action='RollDice'/>"
+" <menuitem action='Trade'/>"
+" <menuitem action='Undo'/>"
+" <menuitem action='Finish'/>"
+" <separator/>"
+" <menuitem action='BuildRoad'/>"
+" <menuitem action='BuildShip'/>"
+" <menuitem action='MoveShip'/>"
+" <menuitem action='BuildBridge'/>"
+" <menuitem action='BuildSettlement'/>"
+" <menuitem action='BuildCity'/>"
+" <menuitem action='BuyDevelopment'/>"
+" <menuitem action='BuildCityWall'/>"
+" </menu>"
+" <menu action='SettingsMenu'>"
+" <menuitem action='ShowHideToolbar'/>"
+" <menuitem action='Preferences'/>"
+" </menu>"
+" <menu action='HelpMenu'>"
+" <menuitem action='HelpAbout'/>"
+#ifdef HAVE_HELP
+" <menuitem action='HelpManual'/>"
+#endif
+" </menu>"
+" </menubar>"
+" <toolbar name='MainToolbar'>"
+" <toolitem action='RollDice'/>"
+" <toolitem action='Trade'/>"
+" <toolitem action='Undo'/>"
+" <toolitem action='Finish'/>"
+" <toolitem action='BuildRoad'/>"
+" <toolitem action='BuildShip'/>"
+" <toolitem action='MoveShip'/>"
+" <toolitem action='BuildBridge'/>"
+" <toolitem action='BuildSettlement'/>"
+" <toolitem action='BuildCity'/>"
+" <toolitem action='BuyDevelopment'/>"
+" <toolitem action='BuildCityWall'/>"
+" </toolbar>"
+"</ui>";
+/* *INDENT-ON* */
+
+GtkWidget *gui_get_dialog_button(GtkDialog * dlg, gint button)
+{
+ GList *list;
+
+ g_return_val_if_fail(dlg != NULL, NULL);
+ g_assert(dlg->action_area != NULL);
+
+ list = g_list_nth(GTK_BOX(dlg->action_area)->children, button);
+ if (list != NULL) {
+ g_assert(list->data != NULL);
+ return ((GtkBoxChild *) list->data)->widget;
+ }
+ return NULL;
+}
+
+void gui_reset(void)
+{
+ guimap_reset(gmap);
+}
+
+void gui_set_instructions(const gchar * text)
+{
+ gtk_statusbar_push(GTK_STATUSBAR(app_bar), 0, text);
+}
+
+void gui_set_vp_target_value(gint vp)
+{
+ gchar *vp_text;
+
+ /* Victory points target in statusbar */
+ vp_text = g_strdup_printf(_("Points Needed to Win: %i"), vp);
+
+ gtk_label_set_text(GTK_LABEL(vp_target_status), vp_text);
+ g_free(vp_text);
+}
+
+void gui_set_net_status(const gchar * text)
+{
+ gtk_label_set_text(GTK_LABEL(net_status), text);
+}
+
+void gui_cursor_none(void)
+{
+ MapElement dummyElement;
+ dummyElement.pointer = NULL;
+ guimap_cursor_set(gmap, NO_CURSOR, -1, NULL, NULL, NULL,
+ &dummyElement, FALSE);
+}
+
+void gui_cursor_set(CursorType type,
+ CheckFunc check_func, SelectFunc select_func,
+ CancelFunc cancel_func, const MapElement * user_data)
+{
+ guimap_cursor_set(gmap, type, my_player_num(),
+ check_func, select_func, cancel_func, user_data,
+ FALSE);
+}
+
+void gui_draw_hex(const Hex * hex)
+{
+ if (gmap->pixmap != NULL)
+ guimap_draw_hex(gmap, hex);
+}
+
+void gui_draw_edge(const Edge * edge)
+{
+ if (gmap->pixmap != NULL)
+ guimap_draw_edge(gmap, edge);
+}
+
+void gui_draw_node(const Node * node)
+{
+ if (gmap->pixmap != NULL)
+ guimap_draw_node(gmap, node);
+}
+
+void gui_highlight_chits(gint roll)
+{
+ guimap_highlight_chits(gmap, roll);
+}
+
+static gint button_press_map_cb(GtkWidget * area, GdkEventButton * event,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ if (area->window == NULL || gmap->map == NULL)
+ return FALSE;
+
+ if (event->button == 1 && event->type == GDK_BUTTON_PRESS) {
+ guimap_cursor_select(gmap, event->x, event->y);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static GtkWidget *build_map_area(void)
+{
+ GtkWidget *map_area = guimap_build_drawingarea(gmap, MAP_WIDTH,
+ MAP_HEIGHT);
+ gtk_widget_add_events(map_area, GDK_BUTTON_PRESS_MASK);
+ g_signal_connect(G_OBJECT(map_area), "button_press_event",
+ G_CALLBACK(button_press_map_cb), NULL);
+
+ return map_area;
+}
+
+static GtkWidget *build_messages_panel(void)
+{
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *scroll_win;
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox);
+
+ /* Label for messages log */
+ label = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(label), _("<b>Messages</b>"));
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
+
+ scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_widget_set_size_request(scroll_win, -1, 80);
+ gtk_widget_show(scroll_win);
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), scroll_win);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ messages_txt = gtk_text_view_new();
+ gtk_widget_show(messages_txt);
+ gtk_container_add(GTK_CONTAINER(scroll_win), messages_txt);
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(messages_txt), FALSE);
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(messages_txt),
+ GTK_WRAP_WORD);
+
+ message_window_set_text(messages_txt);
+
+ return vbox;
+}
+
+void gui_show_trade_page(gboolean show)
+{
+ /* Normal keyboard focus when visible */
+ chat_set_grab_focus_on_update(!show);
+ if (show) {
+ gtk_widget_show(trade_page);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(map_notebook),
+ TRADE_PAGE);
+ } else {
+ gtk_notebook_prev_page(GTK_NOTEBOOK(map_notebook));
+ gtk_widget_hide(trade_page);
+ }
+}
+
+void gui_show_quote_page(gboolean show)
+{
+ /* Normal keyboard focus when visible */
+ chat_set_grab_focus_on_update(!show);
+ if (show) {
+ gtk_widget_show(quote_page);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(map_notebook),
+ QUOTE_PAGE);
+ } else {
+ gtk_notebook_prev_page(GTK_NOTEBOOK(map_notebook));
+ gtk_widget_hide(quote_page);
+ }
+}
+
+static void gui_theme_changed(void)
+{
+ g_assert(legend_page != NULL);
+ gtk_widget_queue_draw(legend_page);
+ gtk_widget_queue_draw_area(gmap->area, 0, 0, gmap->width,
+ gmap->height);
+}
+
+void gui_show_legend_page(gboolean show)
+{
+ if (show) {
+ gtk_widget_show(legend_page);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(map_notebook),
+ LEGEND_PAGE);
+ } else
+ gtk_widget_hide(legend_page);
+}
+
+void gui_show_splash_page(gboolean show)
+{
+ chat_set_grab_focus_on_update(TRUE);
+ if (show) {
+ gtk_widget_show(splash_page);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(map_notebook),
+ SPLASH_PAGE);
+ } else {
+ gtk_widget_hide(splash_page);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(map_notebook),
+ MAP_PAGE);
+ }
+}
+
+static GtkWidget *splash_build_page(void)
+{
+ GtkWidget *pm;
+ GtkWidget *viewport;
+ gchar *filename;
+
+ filename = g_build_filename(DATADIR, "pixmaps", "pioneers",
+ "splash.png", NULL);
+ pm = gtk_image_new_from_file(filename);
+ g_free(filename);
+
+ /* The viewport avoids that the pixmap is drawn up into the tab area if
+ * it's too large for the space provided. */
+ viewport = gtk_viewport_new(NULL, NULL);
+ gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewport),
+ GTK_SHADOW_NONE);
+ gtk_widget_show(viewport);
+ gtk_widget_set_size_request(pm, 1, 1);
+ gtk_widget_show(pm);
+ gtk_container_add(GTK_CONTAINER(viewport), pm);
+ return viewport;
+}
+
+static GtkWidget *build_map_panel(void)
+{
+ GtkWidget *lbl;
+
+ map_notebook = gtk_notebook_new();
+ gtk_notebook_set_tab_pos(GTK_NOTEBOOK(map_notebook), GTK_POS_TOP);
+ gtk_widget_show(map_notebook);
+
+ /* Tab page name */
+ lbl = gtk_label_new(_("Map"));
+ gtk_widget_show(lbl);
+ gtk_notebook_insert_page(GTK_NOTEBOOK(map_notebook),
+ build_map_area(), lbl, MAP_PAGE);
+
+ /* Tab page name */
+ lbl = gtk_label_new(_("Trade"));
+ gtk_widget_show(lbl);
+ trade_page = trade_build_page();
+ gtk_notebook_insert_page(GTK_NOTEBOOK(map_notebook),
+ trade_page, lbl, TRADE_PAGE);
+ gtk_widget_hide(trade_page);
+
+ /* Tab page name */
+ lbl = gtk_label_new(_("Quote"));
+ gtk_widget_show(lbl);
+ quote_page = quote_build_page();
+ gtk_notebook_insert_page(GTK_NOTEBOOK(map_notebook),
+ quote_page, lbl, QUOTE_PAGE);
+ gtk_widget_hide(quote_page);
+
+ /* Tab page name */
+ lbl = gtk_label_new(_("Legend"));
+ gtk_widget_show(lbl);
+ legend_page = legend_create_content();
+ gtk_notebook_insert_page(GTK_NOTEBOOK(map_notebook),
+ legend_page, lbl, LEGEND_PAGE);
+ if (!legend_page_enabled)
+ gui_show_legend_page(FALSE);
+ theme_register_callback(G_CALLBACK(gui_theme_changed));
+
+ /* Tab page name, shown for the splash screen */
+ lbl = gtk_label_new(_("Welcome to Pioneers"));
+ gtk_widget_show(lbl);
+ splash_page = splash_build_page();
+ gtk_notebook_insert_page(GTK_NOTEBOOK(map_notebook),
+ splash_page, lbl, SPLASH_PAGE);
+ gui_show_splash_page(TRUE);
+
+ return map_notebook;
+}
+
+void gui_discard_show(void)
+{
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(develop_notebook), 1);
+}
+
+void gui_discard_hide(void)
+{
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(develop_notebook), 0);
+}
+
+void gui_gold_show(void)
+{
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(develop_notebook), 2);
+}
+
+void gui_gold_hide(void)
+{
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(develop_notebook), 0);
+}
+
+void gui_prompt_show(const gchar * message)
+{
+ gtk_label_set_text(GTK_LABEL(prompt_lbl), message);
+ /* Force resize of the notebook, this is needed because
+ * GTK does not redraw when the text in a label changes.
+ */
+ gtk_container_check_resize(GTK_CONTAINER(develop_notebook));
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(develop_notebook), 3);
+}
+
+void gui_prompt_hide(void)
+{
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(develop_notebook), 0);
+}
+
+static GtkWidget *prompt_build_page(void)
+{
+ prompt_lbl = gtk_label_new("");
+ gtk_widget_show(prompt_lbl);
+ return prompt_lbl;
+}
+
+static GtkWidget *build_develop_panel(void)
+{
+ develop_notebook = gtk_notebook_new();
+ gtk_notebook_set_show_tabs(GTK_NOTEBOOK(develop_notebook), FALSE);
+ gtk_notebook_set_show_border(GTK_NOTEBOOK(develop_notebook),
+ FALSE);
+ gtk_widget_show(develop_notebook);
+
+ gtk_notebook_insert_page(GTK_NOTEBOOK(develop_notebook),
+ develop_build_page(), NULL, 0);
+ gtk_notebook_insert_page(GTK_NOTEBOOK(develop_notebook),
+ discard_build_page(), NULL, 1);
+ gtk_notebook_insert_page(GTK_NOTEBOOK(develop_notebook),
+ gold_build_page(), NULL, 2);
+ gtk_notebook_insert_page(GTK_NOTEBOOK(develop_notebook),
+ prompt_build_page(), NULL, 3);
+
+ return develop_notebook;
+}
+
+static gboolean get_16_9_layout(void)
+{
+ GtkWidget *paned;
+
+ g_return_val_if_fail(main_paned != NULL, FALSE);
+ g_return_val_if_fail(chat_panel != NULL, FALSE);
+
+ paned = gtk_paned_get_child1(GTK_PANED(main_paned));
+ if (gtk_widget_get_parent(chat_panel) == paned)
+ return FALSE;
+ return TRUE;
+}
+
+static void set_16_9_layout(gboolean layout_16_9)
+{
+ GtkWidget *paned;
+ gboolean can_remove;
+
+ g_return_if_fail(main_paned != NULL);
+ g_return_if_fail(chat_panel != NULL);
+
+ paned = gtk_paned_get_child1(GTK_PANED(main_paned));
+
+ /* Increase reference count, otherwise it will be destroyed */
+ g_object_ref(chat_panel);
+
+ /* Initially the widget has no parent, and cannot be removed */
+ can_remove = gtk_widget_get_parent(chat_panel) != NULL;
+
+ if (layout_16_9) {
+ if (can_remove)
+ gtk_container_remove(GTK_CONTAINER(paned),
+ chat_panel);
+ gtk_container_add(GTK_CONTAINER(main_paned), chat_panel);
+ } else {
+ if (can_remove)
+ gtk_container_remove(GTK_CONTAINER(main_paned),
+ chat_panel);
+ gtk_container_add(GTK_CONTAINER(paned), chat_panel);
+ }
+ g_object_unref(chat_panel);
+}
+
+static GtkWidget *build_main_interface(void)
+{
+ GtkWidget *vbox;
+ GtkWidget *hpaned;
+ GtkWidget *vpaned;
+ GtkWidget *panel;
+
+ hpaned = gtk_hpaned_new();
+ gtk_widget_show(hpaned);
+
+ vbox = gtk_vbox_new(FALSE, 3);
+ gtk_widget_show(vbox);
+ gtk_paned_pack1(GTK_PANED(hpaned), vbox, FALSE, TRUE);
+
+ gtk_box_pack_start(GTK_BOX(vbox),
+ identity_build_panel(), FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox),
+ resource_build_panel(), FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox),
+ build_develop_panel(), FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox),
+ player_build_summary(), TRUE, TRUE, 0);
+
+ main_paned = gtk_hpaned_new();
+ gtk_widget_show(main_paned);
+
+ vpaned = gtk_vpaned_new();
+ gtk_widget_show(vpaned);
+
+ gtk_paned_pack1(GTK_PANED(main_paned), vpaned, TRUE, TRUE);
+
+ gtk_paned_pack1(GTK_PANED(vpaned), build_map_panel(), TRUE, TRUE);
+
+ chat_panel = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(chat_panel);
+
+ panel = chat_build_panel();
+ frontend_gui_register(panel, GUI_DISCONNECT, NULL);
+ gtk_box_pack_start(GTK_BOX(chat_panel), panel, FALSE, TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(chat_panel),
+ build_messages_panel(), TRUE, TRUE, 0);
+
+ set_16_9_layout(config_get_int_with_default
+ ("settings/layout_16_9", FALSE));
+
+ gtk_paned_pack2(GTK_PANED(hpaned), main_paned, TRUE, TRUE);
+ return hpaned;
+}
+
+static void quit_cb(G_GNUC_UNUSED GtkWidget * widget,
+ G_GNUC_UNUSED void *data)
+{
+ guimap_delete(gmap);
+ gtk_main_quit();
+}
+
+static void theme_change_cb(GtkWidget * widget, G_GNUC_UNUSED void *data)
+{
+ gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
+ MapTheme *theme = g_list_nth_data(theme_get_list(), index);
+ if (theme != theme_get_current()) {
+ config_set_string("settings/theme", theme->name);
+ theme_set_current(theme);
+ if (gmap->pixmap != NULL) {
+ g_object_unref(gmap->pixmap);
+ gmap->pixmap = NULL;
+ }
+ theme_rescale(2 * gmap->x_point);
+ }
+
+}
+
+static void show_legend_cb(GtkToggleButton * widget,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ legend_page_enabled = gtk_toggle_button_get_active(widget);
+ gui_show_legend_page(legend_page_enabled);
+ config_set_int("settings/legend_page", legend_page_enabled);
+}
+
+static void message_color_cb(GtkToggleButton * widget,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ color_messages_enabled = gtk_toggle_button_get_active(widget);
+ config_set_int("settings/color_messages", color_messages_enabled);
+ log_set_func_message_color_enable(color_messages_enabled);
+}
+
+static void chat_color_cb(GtkToggleButton * widget,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ color_chat_enabled = gtk_toggle_button_get_active(widget);
+ config_set_int("settings/color_chat", color_chat_enabled);
+}
+
+static void summary_color_cb(GtkToggleButton * widget,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ gboolean color_summary = gtk_toggle_button_get_active(widget);
+ config_set_int("settings/color_summary", color_summary);
+ set_color_summary(color_summary);
+}
+
+static void announce_player_cb(GtkToggleButton * widget,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ gboolean announce_player = gtk_toggle_button_get_active(widget);
+ config_set_int("settings/announce_player", announce_player);
+ set_announce_player(announce_player);
+}
+
+static void toggle_16_9_cb(GtkToggleButton * widget,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ gboolean layout_16_9 = gtk_toggle_button_get_active(widget);
+ config_set_int("settings/layout_16_9", layout_16_9);
+ set_16_9_layout(layout_16_9);
+}
+
+static void showhide_toolbar_cb(void)
+{
+ gui_set_toolbar_visible();
+}
+
+static void toolbar_shortcuts_cb(void)
+{
+ gui_toolbar_show_accelerators(!toolbar_show_accelerators);
+}
+
+static void preferences_cb(void)
+{
+ GtkWidget *widget;
+ GtkWidget *dlg_vbox;
+ GtkWidget *theme_label;
+ GtkWidget *theme_list;
+ GtkWidget *layout;
+ GtkTooltips *tooltips;
+
+ guint row;
+ gint color_summary;
+ GList *theme_elt;
+ int i;
+
+ if (preferences_dlg != NULL) {
+ gtk_window_present(GTK_WINDOW(preferences_dlg));
+ return;
+ };
+
+ /* Caption of preferences dialog */
+ preferences_dlg = gtk_dialog_new_with_buttons(_
+ ("Pioneers Preferences"),
+ GTK_WINDOW
+ (app_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(preferences_dlg),
+ GTK_RESPONSE_CLOSE);
+ g_signal_connect(G_OBJECT(preferences_dlg), "destroy",
+ G_CALLBACK(gtk_widget_destroyed),
+ &preferences_dlg);
+ g_signal_connect(G_OBJECT(preferences_dlg), "response",
+ G_CALLBACK(gtk_widget_destroy), NULL);
+ gtk_widget_show(preferences_dlg);
+
+ tooltips = gtk_tooltips_new();
+
+ dlg_vbox = GTK_DIALOG(preferences_dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ layout = gtk_table_new(6, 2, FALSE);
+ gtk_widget_show(layout);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), layout, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(layout), 5);
+
+ row = 0;
+
+ theme_list = gtk_combo_box_new_text();
+ /* Label for changing the theme, in the preferences dialog */
+ theme_label = gtk_label_new(_("Theme:"));
+ gtk_misc_set_alignment(GTK_MISC(theme_label), 0, 0.5);
+ gtk_widget_show(theme_list);
+ gtk_widget_show(theme_label);
+
+ for (i = 0, theme_elt = theme_get_list();
+ theme_elt != NULL; ++i, theme_elt = g_list_next(theme_elt)) {
+ MapTheme *theme = theme_elt->data;
+ gtk_combo_box_append_text(GTK_COMBO_BOX(theme_list),
+ theme->name);
+ if (theme == theme_get_current())
+ gtk_combo_box_set_active(GTK_COMBO_BOX(theme_list),
+ i);
+ }
+ g_signal_connect(G_OBJECT(theme_list), "changed",
+ G_CALLBACK(theme_change_cb), NULL);
+
+ gtk_table_attach_defaults(GTK_TABLE(layout), theme_label,
+ 0, 1, row, row + 1);
+ gtk_table_attach_defaults(GTK_TABLE(layout), theme_list,
+ 1, 2, row, row + 1);
+ /* Tooltip for changing the theme in the preferences dialog */
+ gtk_tooltips_set_tip(tooltips, theme_list,
+ _("Choose one of the themes"), NULL);
+ row++;
+
+ /* Label for the option to show the legend */
+ widget = gtk_check_button_new_with_label(_("Show legend"));
+ gtk_widget_show(widget);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
+ legend_page_enabled);
+ g_signal_connect(G_OBJECT(widget), "toggled",
+ G_CALLBACK(show_legend_cb), NULL);
+ gtk_table_attach_defaults(GTK_TABLE(layout), widget,
+ 0, 2, row, row + 1);
+ gtk_tooltips_set_tip(tooltips, widget,
+ /* Tooltip for the option to show the legend */
+ _("Show the legend as a page beside the map"),
+ NULL);
+ row++;
+
+ /* Label for the option to display log messages in color */
+ widget = gtk_check_button_new_with_label(_("Messages with color"));
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(layout), widget,
+ 0, 2, row, row + 1);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
+ color_messages_enabled);
+ g_signal_connect(G_OBJECT(widget), "toggled",
+ G_CALLBACK(message_color_cb), NULL);
+ /* Tooltip for the option to display log messages in color */
+ gtk_tooltips_set_tip(tooltips, widget,
+ _("Show new messages with color"), NULL);
+ row++;
+
+ /* Label for the option to display chat in color of player */
+ widget = gtk_check_button_new_with_label(_
+ ("Chat in color of player"));
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(layout), widget,
+ 0, 2, row, row + 1);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
+ color_chat_enabled);
+ g_signal_connect(G_OBJECT(widget), "toggled",
+ G_CALLBACK(chat_color_cb), NULL);
+ gtk_tooltips_set_tip(tooltips, widget,
+ /* Tooltip for the option to display chat in color of player */
+ _
+ ("Show new chat messages in the color of the player"),
+ NULL);
+ row++;
+
+ /* Label for the option to display the summary with colors */
+ widget = gtk_check_button_new_with_label(_("Summary with color"));
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(layout), widget,
+ 0, 2, row, row + 1);
+ color_summary =
+ config_get_int_with_default("settings/color_summary", TRUE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), color_summary); /* @todo RC use correct variable */
+ g_signal_connect(G_OBJECT(widget), "toggled",
+ G_CALLBACK(summary_color_cb), NULL);
+ /* Tooltip for the option to display the summary with colors */
+ gtk_tooltips_set_tip(tooltips, widget,
+ _("Use colors in the player summary"), NULL);
+ row++;
+
+ /* Label for the option to display keyboard accelerators in the toolbar */
+ widget =
+ gtk_check_button_new_with_label(_("Toolbar with shortcuts"));
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(layout), widget,
+ 0, 2, row, row + 1);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
+ toolbar_show_accelerators);
+ g_signal_connect(G_OBJECT(widget), "toggled",
+ G_CALLBACK(toolbar_shortcuts_cb), NULL);
+ /* Tooltip for the option to display keyboard accelerators in the toolbar */
+ gtk_tooltips_set_tip(tooltips, widget,
+ _("Show keyboard shortcuts in the toolbar"),
+ NULL);
+ row++;
+
+ /* Label for the option to announce when players/viewer enter */
+ widget =
+ gtk_check_button_new_with_label(_("Announce new players"));
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(layout), widget,
+ 0, 2, row, row + 1);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
+ get_announce_player());
+ g_signal_connect(G_OBJECT(widget), "toggled",
+ G_CALLBACK(announce_player_cb), NULL);
+ /* Tooltip for the option to use sound */
+ gtk_tooltips_set_tip(tooltips, widget,
+ _
+ ("Make a sound when a new player or viewer enters the game"),
+ NULL);
+ row++;
+
+ /* Label for the option to use the 16:9 layout. */
+ widget = gtk_check_button_new_with_label(_("Use 16:9 layout"));
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(layout), widget,
+ 0, 2, row, row + 1);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget),
+ get_16_9_layout());
+ g_signal_connect(G_OBJECT(widget), "toggled",
+ G_CALLBACK(toggle_16_9_cb), NULL);
+ /* Tooltip for 16:9 option. */
+ gtk_tooltips_set_tip(tooltips, widget,
+ _
+ ("Use a 16:9 friendly layout for the window"),
+ NULL);
+ row++;
+
+}
+
+static void help_about_cb(void)
+{
+ const gchar *authors[] = {
+ AUTHORLIST
+ };
+ aboutbox_display(_("The Pioneers Game"), authors);
+}
+
+static void game_legend_cb(void)
+{
+ legend_create_dlg();
+}
+
+static void game_histogram_cb(void)
+{
+ histogram_create_dlg();
+}
+
+static void game_settings_cb(void)
+{
+ settings_create_dlg();
+}
+
+#ifdef HAVE_HELP
+static void help_manual_cb(void)
+{
+ GError *error = NULL;
+ gnome_help_display("pioneers", NULL, &error);
+ if (error) {
+ log_message(MSG_ERROR, "%s: %s\n", _("Show the manual"),
+ error->message);
+ g_error_free(error);
+ }
+}
+#endif
+
+static GtkAction *getAction(GuiEvent id)
+{
+ const gchar *path = NULL;
+ gchar *full_path;
+ GtkAction *action;
+#ifdef ADMIN_GTK
+ frontend_gui_register_action(gtk_ui_manager_get_action
+ (manager,
+ "ui/MainMenu/GameMenu/GameAdmin"),
+ GUI_CONNECT);
+#endif
+
+ switch (id) {
+ case GUI_CONNECT:
+ path = "GameMenu/GameNew";
+ break;
+ case GUI_DISCONNECT:
+ path = "GameMenu/GameLeave";
+ break;
+ case GUI_CHANGE_NAME:
+ path = "GameMenu/PlayerName";
+ break;
+ case GUI_ROLL:
+ path = "ActionsMenu/RollDice";
+ break;
+ case GUI_TRADE:
+ path = "ActionsMenu/Trade";
+ break;
+ case GUI_UNDO:
+ path = "ActionsMenu/Undo";
+ break;
+ case GUI_FINISH:
+ path = "ActionsMenu/Finish";
+ break;
+ case GUI_ROAD:
+ path = "ActionsMenu/BuildRoad";
+ break;
+ case GUI_SHIP:
+ path = "ActionsMenu/BuildShip";
+ break;
+ case GUI_MOVE_SHIP:
+ path = "ActionsMenu/MoveShip";
+ break;
+ case GUI_BRIDGE:
+ path = "ActionsMenu/BuildBridge";
+ break;
+ case GUI_SETTLEMENT:
+ path = "ActionsMenu/BuildSettlement";
+ break;
+ case GUI_CITY:
+ path = "ActionsMenu/BuildCity";
+ break;
+ case GUI_BUY_DEVELOP:
+ path = "ActionsMenu/BuyDevelopment";
+ break;
+ case GUI_CITY_WALL:
+ path = "ActionsMenu/BuildCityWall";
+ break;
+ default:
+ break;
+ };
+
+ if (!path)
+ return NULL;
+
+ full_path = g_strdup_printf("ui/MainMenu/%s", path);
+ action = gtk_ui_manager_get_action(ui_manager, full_path);
+ g_free(full_path);
+ return action;
+}
+
+/** Set the visibility of the toolbar */
+static void gui_set_toolbar_visible(void)
+{
+ GSList *list;
+ gboolean visible;
+
+ list = gtk_ui_manager_get_toplevels(ui_manager,
+ GTK_UI_MANAGER_TOOLBAR);
+ g_assert(g_slist_length(list) == 1);
+ visible = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION
+ (gtk_ui_manager_get_action
+ (ui_manager,
+ "ui/MainMenu/SettingsMenu/ShowHideToolbar")));
+ if (visible)
+ gtk_widget_show(GTK_WIDGET(list->data));
+ else
+ gtk_widget_hide(GTK_WIDGET(list->data));
+ config_set_int("settings/show_toolbar", visible);
+ g_slist_free(list);
+}
+
+/** Show the accelerators in the toolbar */
+static void gui_toolbar_show_accelerators(gboolean show_accelerators)
+{
+ GtkToolbar *tb;
+ gint n, i;
+
+ toolbar_show_accelerators = show_accelerators;
+
+ tb = GTK_TOOLBAR(toolbar);
+
+ n = gtk_toolbar_get_n_items(tb);
+ for (i = 0; i < n; i++) {
+ GtkToolItem *ti;
+ GtkToolButton *tbtn;
+ gchar *text;
+ gint j;
+
+ ti = gtk_toolbar_get_nth_item(tb, i);
+ tbtn = GTK_TOOL_BUTTON(ti);
+ g_assert(tbtn != NULL);
+ if (gtk_major_version == 2 && gtk_minor_version == 10) {
+ /* Work around a gtk+ 2.10 bug (#434261) that
+ * mishandles strings like (Fn) in labels.
+ */
+ /** @todo BW 2007-04-29 Remove this when gtk 2.10
+ * is no longer supported. */
+ gtk_tool_button_set_use_underline(tbtn, FALSE);
+ }
+ text = g_strdup(gtk_tool_button_get_label(tbtn));
+ if (strchr(text, '\n'))
+ *strchr(text, '\n') = '\0';
+ /* Find the matching entry */
+ for (j = 0; j < G_N_ELEMENTS(entries); j++) {
+ if (strcmp(text, _(entries[j].label)) == 0) {
+ if (show_accelerators) {
+ gchar *label;
+
+ if (entries[j].accelerator == NULL
+ || strlen(entries[j].
+ accelerator)
+ == 0)
+ label =
+ g_strdup_printf("%s\n",
+ text);
+ else {
+ gchar *accelerator_text;
+ guint accelerator_key;
+ GdkModifierType
+ accelerator_mods;
+ gtk_accelerator_parse
+ (entries[j].
+ accelerator,
+ &accelerator_key,
+ &accelerator_mods);
+ accelerator_text =
+ gtk_accelerator_get_label
+ (accelerator_key,
+ accelerator_mods);
+ label =
+ g_strdup_printf
+ ("%s\n(%s)", text,
+ accelerator_text);
+ g_free(accelerator_text);
+ }
+ gtk_tool_button_set_label(tbtn,
+ label);
+ g_free(label);
+ } else {
+ gtk_tool_button_set_label(tbtn,
+ _(entries
+ [j].
+ label));
+ }
+ break;
+ }
+ }
+ g_free(text);
+ }
+ config_set_int("settings/toolbar_show_accelerators",
+ toolbar_show_accelerators);
+}
+
+/** Show or hide a button in the toolbar */
+static void gui_toolbar_show_button(const gchar * path, gboolean visible)
+{
+ gchar *fullpath;
+ GtkWidget *w;
+ GtkToolItem *item;
+
+ fullpath = g_strdup_printf("ui/MainToolbar/%s", path);
+ w = gtk_ui_manager_get_widget(ui_manager, fullpath);
+ if (w == NULL) {
+ g_assert(!"Widget not found");
+ return;
+ }
+ item = GTK_TOOL_ITEM(w);
+ if (item == NULL) {
+ g_assert(!"Widget is not a tool button");
+ return;
+ }
+ gtk_tool_item_set_visible_horizontal(item, visible);
+
+ g_free(fullpath);
+}
+
+void gui_rules_register_callback(GCallback callback)
+{
+ rules_callback_list = g_list_append(rules_callback_list, callback);
+}
+
+void gui_set_game_params(const GameParams * params)
+{
+ GList *list;
+ GtkWidget *label;
+
+ gmap->map = params->map;
+ gmap->player_num = my_player_num();
+ gtk_widget_queue_resize(gmap->area);
+
+ gui_toolbar_show_button("BuildRoad",
+ params->num_build_type[BUILD_ROAD] > 0);
+ gui_toolbar_show_button("BuildShip",
+ params->num_build_type[BUILD_SHIP] > 0);
+ gui_toolbar_show_button("MoveShip",
+ params->num_build_type[BUILD_SHIP] > 0);
+ gui_toolbar_show_button("BuildBridge",
+ params->num_build_type[BUILD_BRIDGE] > 0);
+ /* In theory, it is possible to play a game without cities */
+ gui_toolbar_show_button("BuildCity",
+ params->num_build_type[BUILD_CITY] > 0);
+ gui_toolbar_show_button("BuildCityWall",
+ params->num_build_type[BUILD_CITY_WALL] >
+ 0);
+
+ identity_draw();
+
+ gui_set_vp_target_value(params->victory_points);
+
+ list = rules_callback_list;
+ while (list) {
+ G_CALLBACK(list->data) ();
+ list = g_list_next(list);
+ }
+
+ label =
+ gtk_notebook_get_tab_label(GTK_NOTEBOOK(map_notebook),
+ legend_page);
+ g_object_ref(label);
+
+ gtk_widget_destroy(legend_page);
+ legend_page = legend_create_content();
+ gtk_notebook_insert_page(GTK_NOTEBOOK(map_notebook),
+ legend_page, label, LEGEND_PAGE);
+ if (!legend_page_enabled)
+ gui_show_legend_page(FALSE);
+ g_object_unref(label);
+}
+
+static GtkWidget *build_status_bar(void)
+{
+ GtkWidget *vsep;
+
+ app_bar = gtk_statusbar_new();
+ gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(app_bar), TRUE);
+ gtk_widget_show(app_bar);
+
+ vp_target_status = gtk_label_new("");
+ gtk_widget_show(vp_target_status);
+ gtk_box_pack_start(GTK_BOX(app_bar), vp_target_status, FALSE, TRUE,
+ 0);
+
+ vsep = gtk_vseparator_new();
+ gtk_widget_show(vsep);
+ gtk_box_pack_start(GTK_BOX(app_bar), vsep, FALSE, TRUE, 0);
+
+ /* Network status: offline */
+ net_status = gtk_label_new(_("Offline"));
+ gtk_widget_show(net_status);
+ gtk_box_pack_start(GTK_BOX(app_bar), net_status, FALSE, TRUE, 0);
+
+ vsep = gtk_vseparator_new();
+ gtk_widget_show(vsep);
+ gtk_box_pack_start(GTK_BOX(app_bar), vsep, FALSE, TRUE, 0);
+
+ gtk_box_pack_start(GTK_BOX(app_bar),
+ player_build_turn_area(), FALSE, TRUE, 0);
+
+ /* Initial text in status bar */
+ gui_set_instructions(_("Welcome to Pioneers!"));
+
+ return app_bar;
+}
+
+static void register_pixmaps(void)
+{
+ gint idx;
+
+ GtkIconFactory *factory = gtk_icon_factory_new();
+
+ for (idx = 0; idx < G_N_ELEMENTS(pioneers_pixmaps); idx++) {
+ gchar *filename;
+ GtkIconSet *icon;
+
+ icon = gtk_icon_set_new();
+ /* determine full path to pixmap file */
+ filename = g_build_filename(DATADIR, "pixmaps",
+ pioneers_pixmaps[idx], NULL);
+ if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
+ GtkIconSource *source;
+ GdkPixbuf *pixbuf;
+ GError *error = NULL;
+ pixbuf =
+ gdk_pixbuf_new_from_file(filename, &error);
+ if (error != NULL) {
+ g_warning("Error loading pixmap %s\n",
+ filename);
+ g_error_free(error);
+ } else {
+ source = gtk_icon_source_new();
+ gtk_icon_source_set_pixbuf(source, pixbuf);
+ g_object_unref(pixbuf);
+ gtk_icon_set_add_source(icon, source);
+ gtk_icon_source_free(source);
+ }
+ } else {
+ /* Missing pixmap */
+ g_warning("Pixmap not found: %s", filename);
+ }
+
+ gtk_icon_factory_add(factory, pioneers_pixmaps[idx], icon);
+ g_free(filename);
+ gtk_icon_set_unref(icon);
+ }
+
+ gtk_icon_factory_add_default(factory);
+ g_object_unref(factory);
+
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ gchar *filename;
+
+ /* determine full path to pixmap file */
+ filename = g_build_filename(DATADIR, "pixmaps",
+ resources_pixmaps[idx], NULL);
+ if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
+ GdkPixbuf *pixbuf;
+ GError *error = NULL;
+ pixbuf =
+ gdk_pixbuf_new_from_file(filename, &error);
+ if (error != NULL) {
+ g_warning("Error loading pixmap %s\n",
+ filename);
+ g_error_free(error);
+ } else {
+ gdk_pixbuf_render_pixmap_and_mask(pixbuf,
+ &resource_pixmap
+ [idx].p,
+ &resource_pixmap
+ [idx].b,
+ 128);
+ resource_pixmap[idx].gcb =
+ gdk_gc_new(resource_pixmap[idx].b);
+ gdk_gc_set_function(resource_pixmap[idx].
+ gcb, GDK_OR);
+ resource_pixmap[idx].gcp =
+ gdk_gc_new(resource_pixmap[idx].p);
+ gdk_gc_set_clip_mask(resource_pixmap[idx].
+ gcp,
+ resource_pixmap[idx].
+ b);
+ if (!resource_pixmap_res)
+ resource_pixmap_res =
+ gdk_pixbuf_get_width(pixbuf);
+ g_object_unref(pixbuf);
+ }
+ } else {
+ /* Missing pixmap */
+ g_warning("Pixmap not found: %s", filename);
+ }
+
+ g_free(filename);
+ }
+}
+
+GtkWidget *gui_build_interface(void)
+{
+ GtkWidget *vbox;
+ GtkWidget *menubar;
+ GtkActionGroup *action_group;
+ GtkAccelGroup *accel_group;
+ GError *error = NULL;
+ gchar *icon_file;
+ HildonProgram *program;
+ GtkWidget *menu;
+
+ player_init();
+
+ gmap = guimap_new();
+
+ register_pixmaps();
+
+ program = HILDON_PROGRAM(hildon_program_get_instance());
+ app_window = hildon_window_new();
+ hildon_program_add_window(program, HILDON_WINDOW(app_window));
+ g_set_application_name(_("Pioneers"));
+
+#if 0
+ app_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ /* The name of the application */
+ gtk_window_set_title(GTK_WINDOW(app_window), _("Pioneers"));
+#endif
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(vbox);
+ gtk_container_add(GTK_CONTAINER(app_window), vbox);
+
+ action_group = gtk_action_group_new("MenuActions");
+ gtk_action_group_set_translation_domain(action_group, PACKAGE);
+ gtk_action_group_add_actions(action_group, entries,
+ G_N_ELEMENTS(entries), app_window);
+ gtk_action_group_add_toggle_actions(action_group, toggle_entries,
+ G_N_ELEMENTS(toggle_entries),
+ app_window);
+
+ ui_manager = gtk_ui_manager_new();
+ gtk_ui_manager_insert_action_group(ui_manager, action_group, 0);
+
+ accel_group = gtk_ui_manager_get_accel_group(ui_manager);
+ gtk_window_add_accel_group(GTK_WINDOW(app_window), accel_group);
+
+ error = NULL;
+ if (!gtk_ui_manager_add_ui_from_string
+ (ui_manager, ui_description, -1, &error)) {
+ g_message("building menus failed: %s", error->message);
+ g_error_free(error);
+ return NULL;
+ }
+
+ icon_file =
+ g_build_filename(DATADIR, "pixmaps", PIONEERS_ICON_FILE, NULL);
+ if (g_file_test(icon_file, G_FILE_TEST_EXISTS)) {
+ gtk_window_set_default_icon_from_file(icon_file, NULL);
+ } else {
+ /* Missing pixmap, main icon file */
+ g_warning("Pixmap not found: %s", icon_file);
+ }
+ g_free(icon_file);
+
+ color_chat_enabled =
+ config_get_int_with_default("settings/color_chat", TRUE);
+
+ color_messages_enabled =
+ config_get_int_with_default("settings/color_messages", TRUE);
+ log_set_func_message_color_enable(color_messages_enabled);
+
+ set_color_summary(config_get_int_with_default
+ ("settings/color_summary", TRUE));
+
+ set_announce_player(config_get_int_with_default
+ ("settings/announce_player", TRUE));
+
+ legend_page_enabled =
+ config_get_int_with_default("settings/legend_page", FALSE);
+
+ menubar = gtk_ui_manager_get_widget(ui_manager, "/MainMenu");
+ //gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
+ ////hildon_window_set_menu(HILDON_WINDOW(app_window), GTK_MENU(menubar));
+ menu = gtk_menu_new();
+ gtk_container_foreach(GTK_CONTAINER(menubar), (GtkCallback)gtk_widget_reparent, menu);
+ hildon_window_set_menu(HILDON_WINDOW(app_window), GTK_MENU(menu));
+
+ toolbar = gtk_ui_manager_get_widget(ui_manager, "/MainToolbar");
+ gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), build_main_interface(), TRUE,
+ TRUE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), build_status_bar(), FALSE, FALSE,
+ 0);
+
+ gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS);
+
+ gtk_toggle_action_set_active(GTK_TOGGLE_ACTION
+ (gtk_ui_manager_get_action
+ (ui_manager,
+ "ui/MainMenu/SettingsMenu/ShowHideToolbar")),
+ config_get_int_with_default
+ ("settings/show_toolbar", TRUE));
+
+ g_signal_connect(G_OBJECT(app_window), "key_press_event",
+ G_CALLBACK(hotkeys_handler), NULL);
+
+ gtk_widget_show(app_window);
+
+ frontend_gui_register_action(getAction(GUI_CONNECT), GUI_CONNECT);
+ frontend_gui_register_action(getAction(GUI_DISCONNECT),
+ GUI_DISCONNECT);
+#ifdef ADMIN_GTK
+ /** @todo RC 2005-05-26 Admin interface: Not tested */
+ frontend_gui_register_action(gtk_ui_manager_get_action
+ (manager,
+ "ui/MainMenu/GameMenu/GameAdmin"),
+ GUI_ADMIN);
+#endif
+ frontend_gui_register_action(getAction(GUI_CHANGE_NAME),
+ GUI_CHANGE_NAME);
+ frontend_gui_register_action(getAction(GUI_ROLL), GUI_ROLL);
+ frontend_gui_register_action(getAction(GUI_TRADE), GUI_TRADE);
+ frontend_gui_register_action(getAction(GUI_UNDO), GUI_UNDO);
+ frontend_gui_register_action(getAction(GUI_FINISH), GUI_FINISH);
+ frontend_gui_register_action(getAction(GUI_ROAD), GUI_ROAD);
+ frontend_gui_register_action(getAction(GUI_SHIP), GUI_SHIP);
+ frontend_gui_register_action(getAction(GUI_MOVE_SHIP),
+ GUI_MOVE_SHIP);
+ frontend_gui_register_action(getAction(GUI_BRIDGE), GUI_BRIDGE);
+ frontend_gui_register_action(getAction(GUI_SETTLEMENT),
+ GUI_SETTLEMENT);
+ frontend_gui_register_action(getAction(GUI_CITY), GUI_CITY);
+ frontend_gui_register_action(getAction(GUI_BUY_DEVELOP),
+ GUI_BUY_DEVELOP);
+ frontend_gui_register_action(getAction(GUI_CITY_WALL),
+ GUI_CITY_WALL);
+#if 0
+ frontend_gui_register_destroy(gtk_ui_manager_get_action
+ (manager, "GameQuit"), GUI_QUIT);
+#endif
+
+ gui_toolbar_show_button("BuildShip", FALSE);
+ gui_toolbar_show_button("MoveShip", FALSE);
+ gui_toolbar_show_button("BuildBridge", FALSE);
+
+ gui_toolbar_show_accelerators(config_get_int_with_default
+ ("settings/toolbar_show_accelerators",
+ TRUE));
+
+ gtk_ui_manager_ensure_update(ui_manager);
+ gtk_widget_show(app_window);
+ g_signal_connect(G_OBJECT(app_window), "delete_event",
+ G_CALLBACK(quit_cb), NULL);
+
+ return app_window;
+}
+
+void gui_get_resource_pixmap(gint idx, GdkPixmap ** p, GdkBitmap ** b,
+ GdkGC ** gcp, GdkGC ** gcb)
+{
+ g_assert(idx < NO_RESOURCE);
+ *p = resource_pixmap[idx].p;
+ *b = resource_pixmap[idx].b;
+ if (gcp)
+ *gcp = resource_pixmap[idx].gcp;
+ if (gcb)
+ *gcb = resource_pixmap[idx].gcb;
+}
+
+gint gui_get_resource_pixmap_res()
+{
+ return resource_pixmap_res;
+}
+
+void gui_set_show_no_setup_nodes(gboolean show)
+{
+ guimap_set_show_no_setup_nodes(gmap, show);
+}
Added: trunk/client/gtk/gui.h
===================================================================
--- trunk/client/gtk/gui.h (rev 0)
+++ trunk/client/gtk/gui.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,88 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __gui_h
+#define __gui_h
+
+#include "guimap.h"
+
+void set_color_summary(gboolean flag);
+gboolean get_announce_player(void);
+void set_announce_player(gboolean announce);
+
+GtkWidget *gui_get_dialog_button(GtkDialog * dlg, gint button);
+
+void gui_reset(void);
+void gui_set_instructions(const gchar * text);
+void gui_set_vp_target_value(gint vp);
+void gui_set_net_status(const gchar * text);
+
+void gui_show_trade_page(gboolean show);
+void gui_show_quote_page(gboolean show);
+void gui_show_legend_page(gboolean show);
+void gui_show_splash_page(gboolean show);
+
+void gui_discard_show(void);
+void gui_discard_hide(void);
+void gui_gold_show(void);
+void gui_gold_hide(void);
+void gui_prompt_show(const gchar * message);
+void gui_prompt_hide(void);
+
+void gui_cursor_none(void);
+void gui_cursor_set(CursorType type,
+ CheckFunc check_func, SelectFunc select_func,
+ CancelFunc cancel_func, const MapElement * user_data);
+void gui_draw_hex(const Hex * hex);
+void gui_draw_edge(const Edge * edge);
+void gui_draw_node(const Node * node);
+
+void gui_set_game_params(const GameParams * params);
+void gui_setup_mode(gint player_num);
+void gui_double_setup_mode(gint player_num);
+void gui_highlight_chits(gint roll);
+
+GtkWidget *gui_build_interface(void);
+void show_admin_interface(GtkWidget * vbox);
+
+gint hotkeys_handler(GtkWidget * w, GdkEvent * e, gpointer data);
+
+extern GtkWidget *app_window; /* main application window */
+
+/* gui states */
+typedef void (*GuiState) (GuiEvent event);
+
+#define set_gui_state(A) do \
+ { debug("New GUI_state: %s\n", #A); \
+ set_gui_state_nomacro(A); } while (0)
+void set_gui_state_nomacro(GuiState state);
+
+GuiState get_gui_state(void);
+void route_gui_event(GuiEvent event);
+
+void gui_rules_register_callback(GCallback callback);
+
+void gui_get_resource_pixmap(gint idx, GdkPixmap ** p, GdkBitmap ** b,
+ GdkGC ** gcp, GdkGC ** gcb);
+gint gui_get_resource_pixmap_res(void);
+void gui_set_show_no_setup_nodes(gboolean show);
+
+#endif
Added: trunk/client/gtk/histogram.c
===================================================================
--- trunk/client/gtk/histogram.c (rev 0)
+++ trunk/client/gtk/histogram.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,307 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2004 Roland Clobus
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "histogram.h"
+#include "theme.h"
+
+static const int DIALOG_HEIGHT = 270;
+static const int DIALOG_WIDTH = 450;
+static const int GRID_DIVISIONS = 4;
+static const int BAR_SEPARATION = 3;
+static const int CHIT_DIAGRAM_SEPARATION = 3;
+static const int SPACING_AROUND = 6;
+
+static void histogram_update(gint roll);
+
+static GtkWidget *histogram_dlg;
+static GtkWidget *histogram_area;
+static gint last_roll;
+
+static int histogram[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+/*
+ *
+ * Non-Gui stuff -- maintain dice histogram state
+ *
+ */
+
+void histogram_dice_rolled(gint roll, G_GNUC_UNUSED gint playernum)
+{
+ g_assert(roll >= 2 && roll <= 12);
+
+ ++histogram[roll];
+ if (histogram_dlg && GTK_WIDGET_VISIBLE(histogram_dlg))
+ histogram_update(roll);
+}
+
+static gint histogram_dice_retrieve(gint roll)
+{
+ g_assert(roll >= 2 && roll <= 12);
+ return histogram[roll];
+}
+
+/*
+ *
+ * GUI Stuff -- draw a pretty histogram picture
+ *
+ */
+
+/* Draw the histogram */
+static gboolean expose_histogram_cb(GtkWidget * area,
+ G_GNUC_UNUSED GdkEventExpose * event,
+ gpointer terrain)
+{
+ gint w;
+ gint h;
+ gint total;
+ gint max;
+ gint le;
+ gint mi;
+ gint ri;
+ gint grid_width;
+ gint grid_height;
+ gint grid_offset_x;
+ gint grid_offset_y;
+ float by_36;
+ gint expected_low_y, expected_high_y;
+ gint i;
+ gchar buff[30];
+ gint label_width, label_height; /* Maximum size of the labels of the y-axis */
+ gint width, height; /* size of the individual labels */
+ gint bar_width;
+ PangoLayout *layout;
+ gboolean seven_thrown;
+ gboolean draw_labels_and_chits;
+ gint CHIT_RADIUS;
+ GdkPixmap *pixmap;
+ GdkGC *histogram_gc;
+
+ if (area->window == NULL)
+ return TRUE;
+
+ pixmap = guimap_terrain(GPOINTER_TO_INT(terrain));
+
+ histogram_gc = gdk_gc_new(area->window);
+ gdk_gc_set_line_attributes(histogram_gc, 1, GDK_LINE_SOLID,
+ GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+ gdk_gc_set_tile(histogram_gc, pixmap);
+
+ w = area->allocation.width;
+ h = area->allocation.height;
+
+ /* Calculate the highest dice throw */
+ max = 0;
+ for (i = 2; i <= 12; i++) {
+ if (histogram_dice_retrieve(i) > max) {
+ max = histogram_dice_retrieve(i);
+ }
+ /* Make max a multiple of GRID_DIVISIONS */
+ if (max % GRID_DIVISIONS != 0)
+ max += GRID_DIVISIONS - (max % GRID_DIVISIONS);
+ }
+ if (max == 0)
+ max = GRID_DIVISIONS;
+
+ /* Calculate size of the labels of the y-axis */
+ sprintf(buff, "%d", max);
+ layout = gtk_widget_create_pango_layout(area, buff);
+ pango_layout_get_pixel_size(layout, &label_width, &label_height);
+
+ CHIT_RADIUS = guimap_get_chit_radius(layout, TRUE);
+
+ /* Determine if the drawing area is large enough to draw the labels */
+ draw_labels_and_chits = TRUE;
+ if (label_width + (CHIT_RADIUS + 1) * 2 * 11 > w)
+ draw_labels_and_chits = FALSE;
+ if (label_height * 5 + CHIT_RADIUS * 2 > h)
+ draw_labels_and_chits = FALSE;
+
+ grid_offset_x =
+ (draw_labels_and_chits ? label_width : 0) + SPACING_AROUND;
+ grid_width = w - grid_offset_x - SPACING_AROUND;
+ grid_offset_y = (draw_labels_and_chits ? label_height : 0);
+ grid_height =
+ h - grid_offset_y -
+ (draw_labels_and_chits ? 2 * CHIT_RADIUS : 0) -
+ CHIT_DIAGRAM_SEPARATION;
+
+ /* horizontal grid */
+ for (i = 0; i <= GRID_DIVISIONS; ++i) {
+ gint y =
+ grid_offset_y + grid_height -
+ i * grid_height / GRID_DIVISIONS;
+ gdk_gc_set_foreground(histogram_gc, &lightblue);
+ gdk_draw_line(area->window, histogram_gc, grid_offset_x,
+ y - 1, w - SPACING_AROUND, y - 1);
+
+ if (draw_labels_and_chits) {
+ sprintf(buff, "%d", i * max / GRID_DIVISIONS);
+ pango_layout_set_text(layout, buff, -1);
+ pango_layout_get_pixel_size(layout, &width,
+ &height);
+ gdk_gc_set_foreground(histogram_gc, &black);
+ gdk_draw_layout(area->window, histogram_gc,
+ label_width - width +
+ SPACING_AROUND, y - height,
+ layout);
+ }
+ }
+
+ bar_width = (grid_width - 12 * BAR_SEPARATION) / 11;
+ grid_offset_x += BAR_SEPARATION;
+
+ /* histogram bars */
+ gdk_gc_set_fill(histogram_gc, GDK_TILED);
+
+ for (i = 2; i <= 12; i++) {
+ gint bh =
+ (float) grid_height * histogram_dice_retrieve(i) /
+ max + 0.5;
+ gint x =
+ grid_offset_x + (i - 2) * (bar_width + BAR_SEPARATION);
+ gdk_gc_set_fill(histogram_gc, GDK_TILED);
+ gdk_draw_rectangle(area->window, histogram_gc, TRUE,
+ x, grid_height + grid_offset_y - bh,
+ bar_width, bh);
+
+ if (draw_labels_and_chits) {
+ gdk_gc_set_fill(histogram_gc, GDK_SOLID);
+ sprintf(buff, "%d", histogram_dice_retrieve(i));
+ pango_layout_set_markup(layout, buff, -1);
+ pango_layout_get_pixel_size(layout, &width,
+ &height);
+ gdk_gc_set_foreground(histogram_gc, &black);
+ gdk_draw_layout(area->window, histogram_gc,
+ x + (bar_width - width) / 2,
+ grid_height + grid_offset_y - bh -
+ height, layout);
+
+ draw_dice_roll(layout, area->window, histogram_gc,
+ x + bar_width / 2,
+ h - CHIT_RADIUS - 1,
+ CHIT_RADIUS,
+ i, SEA_TERRAIN, i == last_roll);
+ }
+ }
+
+ /* expected value */
+ seven_thrown = histogram_dice_retrieve(7) != 0;
+
+ total = 0;
+ for (i = 2; i <= 12; i++) {
+ total += histogram_dice_retrieve(i);
+ }
+
+ by_36 = total * grid_height / max / (seven_thrown ? 36.0 : 30.0);
+ expected_low_y = grid_height + grid_offset_y - 1 - by_36;
+ expected_high_y =
+ grid_height + grid_offset_y - 1 -
+ (seven_thrown ? 6 : 5) * by_36;
+ gdk_gc_set_fill(histogram_gc, GDK_SOLID);
+ gdk_gc_set_foreground(histogram_gc, &red);
+
+ le = grid_offset_x + bar_width / 2;
+ mi = le + 5 * (bar_width + BAR_SEPARATION);
+ ri = mi + 5 * (bar_width + BAR_SEPARATION);
+ gdk_draw_line(area->window, histogram_gc, le, expected_low_y,
+ mi - (seven_thrown ? 0 : bar_width + BAR_SEPARATION),
+ expected_high_y);
+ gdk_draw_line(area->window, histogram_gc,
+ mi + (seven_thrown ? 0 : bar_width + BAR_SEPARATION),
+ expected_high_y, ri, expected_low_y);
+
+ g_object_unref(layout);
+ g_object_unref(histogram_gc);
+ return TRUE;
+}
+
+static void histogram_destroyed_cb(GtkWidget * widget, gpointer arg)
+{
+ gtk_widget_destroyed(widget, arg);
+ gtk_widget_destroyed(histogram_area, &histogram_area);
+}
+
+GtkWidget *histogram_create_dlg(void)
+{
+ GtkWidget *dlg_vbox;
+
+ if (histogram_dlg != NULL) {
+ return histogram_dlg;
+ }
+
+ histogram_dlg = gtk_dialog_new_with_buttons(_("Dice Histogram"),
+ GTK_WINDOW(app_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE,
+ NULL);
+ g_signal_connect(G_OBJECT(histogram_dlg), "destroy",
+ G_CALLBACK(histogram_destroyed_cb),
+ &histogram_dlg);
+ gtk_window_set_default_size(GTK_WINDOW(histogram_dlg),
+ DIALOG_WIDTH, DIALOG_HEIGHT);
+
+ dlg_vbox = GTK_DIALOG(histogram_dlg)->vbox;
+
+ histogram_area = gtk_drawing_area_new();
+ g_signal_connect(G_OBJECT(histogram_area), "expose_event",
+ G_CALLBACK(expose_histogram_cb),
+ GINT_TO_POINTER(SEA_TERRAIN));
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), histogram_area, TRUE, TRUE,
+ SPACING_AROUND);
+ gtk_widget_show(histogram_area);
+
+ gtk_widget_show(histogram_dlg);
+ g_signal_connect(histogram_dlg, "response",
+ G_CALLBACK(gtk_widget_destroy), NULL);
+
+ histogram_update(0);
+
+ return histogram_dlg;
+}
+
+static void histogram_update(gint roll)
+{
+ last_roll = roll;
+ gtk_widget_queue_draw(histogram_area);
+}
+
+static void histogram_theme_changed(void)
+{
+ if (histogram_dlg && GTK_WIDGET_VISIBLE(histogram_dlg))
+ gtk_widget_queue_draw(histogram_area);
+}
+
+void histogram_init(void)
+{
+ theme_register_callback(G_CALLBACK(histogram_theme_changed));
+}
+
+void histogram_reset(void)
+{
+ gint i;
+ for (i = 2; i <= 12; ++i)
+ histogram[i] = 0;
+ if (histogram_dlg && GTK_WIDGET_VISIBLE(histogram_dlg))
+ histogram_update(0);
+}
Added: trunk/client/gtk/histogram.h
===================================================================
--- trunk/client/gtk/histogram.h (rev 0)
+++ trunk/client/gtk/histogram.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,30 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __histogram_h
+#define __histogram_h
+
+void histogram_dice_rolled(gint roll, gint playernum);
+
+GtkWidget *histogram_create_dlg(void);
+void histogram_init(void);
+void histogram_reset(void);
+#endif
Added: trunk/client/gtk/identity.c
===================================================================
--- trunk/client/gtk/identity.c (rev 0)
+++ trunk/client/gtk/identity.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,315 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+
+static GtkWidget *identity_area;
+static GuiMap bogus_map;
+static GdkGC *identity_gc;
+
+static int die1_num;
+static int die2_num;
+
+static void calculate_width(GtkWidget * area, const Polygon * poly,
+ gint num, gint * fixedwidth,
+ gint * variablewidth)
+{
+ GdkRectangle rect;
+ char buff[10];
+ gint width, height;
+ PangoLayout *layout;
+
+ poly_bound_rect(poly, 0, &rect);
+
+ sprintf(buff, "%d", num);
+ layout = gtk_widget_create_pango_layout(area, buff);
+ pango_layout_get_pixel_size(layout, &width, &height);
+ g_object_unref(layout);
+
+ *fixedwidth += width + 10;
+ *variablewidth += rect.width;
+}
+
+static void calculate_optimum_size(GtkWidget * area, gint size)
+{
+ const GameParams *game_params = get_game_params();
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+ gint new_size;
+ gint fixedwidth; /* Size of fixed part (digits + spacing) */
+ gint variablewidth; /* Size of variable part (polygons) */
+
+ if (game_params == NULL)
+ return;
+
+ guimap_scale_with_radius(&bogus_map, size);
+
+ if (bogus_map.hex_radius <= MIN_HEX_RADIUS)
+ return;
+
+ fixedwidth = 0;
+ variablewidth = 0;
+
+ poly.points = points;
+ if (game_params->num_build_type[BUILD_ROAD] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_road_polygon(&bogus_map, NULL, &poly);
+ calculate_width(area, &poly, stock_num_roads(),
+ &fixedwidth, &variablewidth);
+ }
+ if (game_params->num_build_type[BUILD_SHIP] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_ship_polygon(&bogus_map, NULL, &poly);
+ calculate_width(area, &poly, stock_num_ships(),
+ &fixedwidth, &variablewidth);
+ }
+ if (game_params->num_build_type[BUILD_BRIDGE] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_bridge_polygon(&bogus_map, NULL, &poly);
+ calculate_width(area, &poly, stock_num_bridges(),
+ &fixedwidth, &variablewidth);
+ }
+ if (game_params->num_build_type[BUILD_SETTLEMENT] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_settlement_polygon(&bogus_map, NULL, &poly);
+ calculate_width(area, &poly, stock_num_settlements(),
+ &fixedwidth, &variablewidth);
+ }
+ if (game_params->num_build_type[BUILD_CITY] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_city_polygon(&bogus_map, NULL, &poly);
+ calculate_width(area, &poly, stock_num_cities(),
+ &fixedwidth, &variablewidth);
+ }
+ if (game_params->num_build_type[BUILD_CITY_WALL] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_city_wall_polygon(&bogus_map, NULL, &poly);
+ calculate_width(area, &poly, stock_num_city_walls(),
+ &fixedwidth, &variablewidth);
+ }
+
+ new_size = bogus_map.hex_radius *
+ (area->allocation.width - 75 - fixedwidth) / variablewidth;
+ if (new_size < bogus_map.hex_radius) {
+ calculate_optimum_size(area, new_size);
+ }
+}
+
+static int draw_building_and_count(GdkGC * gc, GtkWidget * area,
+ gint offset, Polygon * poly, gint num)
+{
+ GdkRectangle rect;
+ char buff[10];
+ gint width, height;
+ PangoLayout *layout;
+
+ poly_bound_rect(poly, 0, &rect);
+ poly_offset(poly,
+ offset - rect.x,
+ area->allocation.height - 5 - rect.y - rect.height);
+ poly_draw(area->window, gc, FALSE, poly);
+
+ offset += 5 + rect.width;
+
+ sprintf(buff, "%d", num);
+ layout = gtk_widget_create_pango_layout(area, buff);
+ pango_layout_get_pixel_size(layout, &width, &height);
+ gdk_draw_layout(area->window, gc, offset,
+ area->allocation.height - height - 5, layout);
+ g_object_unref(layout);
+
+ offset += 5 + width;
+
+ return offset;
+}
+
+static void show_die(GdkGC * gc, GtkWidget * area, gint x_offset, gint num)
+{
+ static GdkPoint die_points[4] = {
+ {0, 0}, {30, 0}, {30, 30}, {0, 30}
+ };
+ static Polygon die_shape =
+ { die_points, G_N_ELEMENTS(die_points) };
+ static GdkPoint dot_pos[7] = {
+ {7, 7}, {22, 7},
+ {7, 15}, {15, 15}, {22, 15},
+ {7, 22}, {22, 22}
+ };
+ static gint draw_list[6][7] = {
+ {0, 0, 0, 1, 0, 0, 0},
+ {0, 1, 0, 0, 0, 1, 0},
+ {1, 0, 0, 1, 0, 0, 1},
+ {1, 1, 0, 0, 0, 1, 1},
+ {1, 1, 0, 1, 0, 1, 1},
+ {1, 1, 1, 0, 1, 1, 1}
+ };
+ gint y_offset = (area->allocation.height - 30) / 2;
+ gint *list = draw_list[num - 1];
+ gint idx;
+
+ poly_offset(&die_shape, x_offset, y_offset);
+
+ gdk_gc_set_foreground(gc, &white);
+ poly_draw(area->window, gc, TRUE, &die_shape);
+ gdk_gc_set_foreground(gc, &black);
+ poly_draw(area->window, gc, FALSE, &die_shape);
+
+ poly_offset(&die_shape, -x_offset, -y_offset);
+
+ gdk_gc_set_foreground(gc, &black);
+ for (idx = 0; idx < 7; idx++) {
+ if (list[idx] == 0)
+ continue;
+
+ gdk_draw_arc(area->window, gc, TRUE,
+ x_offset + dot_pos[idx].x - 3,
+ y_offset + dot_pos[idx].y - 3,
+ 7, 7, 0, 360 * 64);
+ }
+}
+
+static void identity_resize_cb(GtkWidget * area,
+ G_GNUC_UNUSED GtkAllocation * allocation,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ calculate_optimum_size(area, 50);
+}
+
+static gint expose_identity_area_cb(GtkWidget * area,
+ G_GNUC_UNUSED GdkEventExpose * event,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+ gint offset;
+ GdkColor *colour;
+ const GameParams *game_params;
+
+ if (area->window == NULL || my_player_num() < 0)
+ return FALSE;
+
+ if (identity_gc == NULL)
+ identity_gc = gdk_gc_new(area->window);
+
+ colour = player_or_viewer_color(my_player_num());
+ gdk_gc_set_foreground(identity_gc, colour);
+ gdk_draw_rectangle(area->window, identity_gc, TRUE, 0, 0,
+ area->allocation.width,
+ area->allocation.height);
+
+ if (my_player_viewer())
+ colour = &white;
+ else
+ colour = &black;
+ gdk_gc_set_foreground(identity_gc, colour);
+
+ game_params = get_game_params();
+ if (game_params == NULL)
+ return TRUE;
+ offset = 5;
+
+ poly.points = points;
+ if (game_params->num_build_type[BUILD_ROAD] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_road_polygon(&bogus_map, NULL, &poly);
+ offset = draw_building_and_count(identity_gc, area, offset,
+ &poly, stock_num_roads());
+ }
+ if (game_params->num_build_type[BUILD_SHIP] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_ship_polygon(&bogus_map, NULL, &poly);
+ offset = draw_building_and_count(identity_gc, area, offset,
+ &poly, stock_num_ships());
+ }
+ if (game_params->num_build_type[BUILD_BRIDGE] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_bridge_polygon(&bogus_map, NULL, &poly);
+ offset = draw_building_and_count(identity_gc, area, offset,
+ &poly,
+ stock_num_bridges());
+ }
+ if (game_params->num_build_type[BUILD_SETTLEMENT] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_settlement_polygon(&bogus_map, NULL, &poly);
+ offset = draw_building_and_count(identity_gc, area, offset,
+ &poly,
+ stock_num_settlements());
+ }
+ if (game_params->num_build_type[BUILD_CITY] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_city_polygon(&bogus_map, NULL, &poly);
+ offset = draw_building_and_count(identity_gc, area, offset,
+ &poly,
+ stock_num_cities());
+ }
+ if (game_params->num_build_type[BUILD_CITY_WALL] > 0) {
+ poly.num_points = MAX_POINTS;
+ guimap_city_wall_polygon(&bogus_map, NULL, &poly);
+ offset = draw_building_and_count(identity_gc, area, offset,
+ &poly,
+ stock_num_city_walls());
+ }
+
+ if (die1_num > 0 && die2_num > 0) {
+ show_die(identity_gc, area, area->allocation.width - 35,
+ die1_num);
+ show_die(identity_gc, area, area->allocation.width - 70,
+ die2_num);
+ }
+
+ return TRUE;
+}
+
+void identity_draw(void)
+{
+ gtk_widget_queue_draw(identity_area);
+}
+
+void identity_set_dice(gint die1, gint die2)
+{
+ die1_num = die1;
+ die2_num = die2;
+ gtk_widget_queue_draw(identity_area);
+}
+
+GtkWidget *identity_build_panel(void)
+{
+ identity_area = gtk_drawing_area_new();
+ g_signal_connect(G_OBJECT(identity_area), "expose_event",
+ G_CALLBACK(expose_identity_area_cb), NULL);
+ g_signal_connect(G_OBJECT(identity_area), "size-allocate",
+ G_CALLBACK(identity_resize_cb), NULL);
+ gtk_widget_set_size_request(identity_area, -1, 40);
+ identity_reset();
+ gtk_widget_show(identity_area);
+ return identity_area;
+}
+
+void identity_reset(void)
+{
+ die1_num = 0;
+ die2_num = 0;
+ /* 50 seems to give a good upper limit */
+ if (identity_area != NULL)
+ calculate_optimum_size(identity_area, 50);
+}
Added: trunk/client/gtk/interface.c
===================================================================
--- trunk/client/gtk/interface.c (rev 0)
+++ trunk/client/gtk/interface.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,883 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* This file consists of gui state functions and callbacks to set them */
+#include "config.h"
+#include "frontend.h"
+#include "cost.h"
+#include "histogram.h"
+
+/* local functions */
+static void frontend_state_turn(GuiEvent event);
+static void build_road_cb(MapElement edge, MapElement extra);
+static void build_ship_cb(MapElement edge, MapElement extra);
+static void build_bridge_cb(MapElement edge, MapElement extra);
+static void move_ship_cb(MapElement edge, MapElement extra);
+static void build_settlement_cb(MapElement node, MapElement extra);
+static void build_city_cb(MapElement node, MapElement extra);
+static void build_city_wall_cb(MapElement node, MapElement extra);
+
+static void dummy_state(G_GNUC_UNUSED GuiEvent event)
+{
+}
+
+/* for gold and discard, remember the previous gui state */
+static GuiState previous_state = dummy_state;
+
+static gboolean discard_busy = FALSE, robber_busy = FALSE;
+
+static void frontend_state_idle(G_GNUC_UNUSED GuiEvent event)
+{
+ /* don't react on any event when idle. */
+ /* (except of course chat and name change events, but they are
+ * handled in route_event) */
+}
+
+void build_road_cb(MapElement edge, G_GNUC_UNUSED MapElement extra)
+{
+ cb_build_road(edge.edge);
+}
+
+void build_ship_cb(MapElement edge, G_GNUC_UNUSED MapElement extra)
+{
+ cb_build_ship(edge.edge);
+}
+
+static void do_move_ship_cb(MapElement edge, MapElement ship_from)
+{
+ cb_move_ship(ship_from.edge, edge.edge);
+ gui_prompt_hide();
+}
+
+/** Edge cursor check function.
+ *
+ * Determine whether or not a ship can be moved to this edge by the
+ * specified player. Perform the following checks:
+ * 1 - Ship cannot be moved to where it comes from
+ * 2 - A ship must be buildable at the destination if the ship is moved away
+ * from its current location.
+ */
+static gboolean can_ship_be_moved_to(MapElement ship_to,
+ G_GNUC_UNUSED gint owner,
+ MapElement ship_from)
+{
+ return can_move_ship(ship_from.edge, ship_to.edge);
+}
+
+void build_bridge_cb(MapElement edge, G_GNUC_UNUSED MapElement extra)
+{
+ cb_build_bridge(edge.edge);
+}
+
+static void cancel_move_ship_cb(void)
+{
+ callbacks.instructions(_("Ship movement canceled."));
+ gui_prompt_hide();
+}
+
+void move_ship_cb(MapElement edge, G_GNUC_UNUSED MapElement extra)
+{
+ MapElement ship_from;
+ ship_from.edge = edge.edge;
+ callbacks.instructions(_("Select a new location for the ship."));
+ gui_prompt_show(_("Select a new location for the ship."));
+ gui_cursor_set(SHIP_CURSOR, can_ship_be_moved_to, do_move_ship_cb,
+ cancel_move_ship_cb, &ship_from);
+}
+
+void build_settlement_cb(MapElement node, G_GNUC_UNUSED MapElement extra)
+{
+ cb_build_settlement(node.node);
+}
+
+void build_city_cb(MapElement node, G_GNUC_UNUSED MapElement extra)
+{
+ cb_build_city(node.node);
+}
+
+void build_city_wall_cb(MapElement node, G_GNUC_UNUSED MapElement extra)
+{
+ cb_build_city_wall(node.node);
+}
+
+/* trade */
+static void frontend_state_trade(GuiEvent event)
+{
+ static gboolean trading = FALSE;
+ const QuoteInfo *quote;
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_TRADE_CALL, can_call_for_quotes());
+ frontend_gui_check(GUI_TRADE_ACCEPT,
+ trade_valid_selection());
+ frontend_gui_check(GUI_TRADE_FINISH, TRUE);
+ frontend_gui_check(GUI_TRADE, TRUE);
+ gui_cursor_none(); /* Finish single click build */
+ break;
+ case GUI_TRADE_CALL:
+ trading = TRUE;
+ trade_new_trade();
+ cb_domestic(trade_we_supply(), trade_we_receive());
+ return;
+ case GUI_TRADE_ACCEPT:
+ quote = trade_current_quote();
+ g_assert(quote != NULL);
+ if (quote->is_domestic) {
+ trade_perform_domestic(my_player_num(),
+ quote->var.d.player_num,
+ quote->var.d.quote_num,
+ quote->var.d.supply,
+ quote->var.d.receive);
+ } else {
+ trade_perform_maritime(quote->var.m.ratio,
+ quote->var.m.supply,
+ quote->var.m.receive);
+ }
+ return;
+ case GUI_TRADE_FINISH:
+ case GUI_TRADE:
+ /* stop trading. Only let the network know about it if it
+ * knew we were trading in the first place. */
+ if (trading)
+ cb_end_trade();
+ trading = FALSE;
+ trade_finish();
+ set_gui_state(frontend_state_turn);
+ return;
+ default:
+ break;
+ }
+}
+
+void frontend_trade_add_quote(int player_num, int quote_num,
+ const gint * they_supply,
+ const gint * they_receive)
+{
+ trade_add_quote(player_num, quote_num, they_supply, they_receive);
+ frontend_gui_update();
+}
+
+void frontend_trade_remove_quote(int player_num, int quote_num)
+{
+ trade_delete_quote(player_num, quote_num);
+ frontend_gui_update();
+}
+
+void frontend_trade_player_end(gint player_num)
+{
+ trade_player_finish(player_num);
+ frontend_gui_update();
+}
+
+static void frontend_state_quote(GuiEvent event)
+{
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_QUOTE_SUBMIT, can_submit_quote());
+ frontend_gui_check(GUI_QUOTE_DELETE, can_delete_quote());
+ frontend_gui_check(GUI_QUOTE_REJECT, can_reject_quote());
+ break;
+ case GUI_QUOTE_SUBMIT:
+ cb_quote(quote_next_num(), quote_we_supply(),
+ quote_we_receive());
+ return;
+ case GUI_QUOTE_DELETE:
+ cb_delete_quote(quote_current_quote()->var.d.quote_num);
+ return;
+ case GUI_QUOTE_REJECT:
+ quote_player_finish(my_player_num());
+ cb_end_quote();
+ return;
+ default:
+ break;
+ }
+}
+
+void frontend_quote(gint player_num, gint * they_supply,
+ gint * they_receive)
+{
+ if (get_gui_state() == frontend_state_quote) {
+ quote_begin_again(player_num, they_supply, they_receive);
+ } else {
+ quote_begin(player_num, they_supply, they_receive);
+ set_gui_state(frontend_state_quote);
+ }
+ frontend_gui_update();
+}
+
+void frontend_quote_add(int player_num, int quote_num,
+ const gint * they_supply,
+ const gint * they_receive)
+{
+ quote_add_quote(player_num, quote_num, they_supply, they_receive);
+ frontend_gui_update();
+}
+
+void frontend_quote_remove(int player_num, int quote_num)
+{
+ quote_delete_quote(player_num, quote_num);
+ frontend_gui_update();
+}
+
+void frontend_quote_player_end(gint player_num)
+{
+ quote_player_finish(player_num);
+ frontend_gui_update();
+}
+
+void frontend_quote_end(void)
+{
+ quote_finish();
+ set_gui_state(frontend_state_idle);
+}
+
+void frontend_quote_start(void)
+{
+ /*set_gui_state (frontend_state_quote); */
+}
+
+void frontend_quote_monitor(void)
+{
+}
+
+static gboolean check_road(MapElement element, gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return can_road_be_built(element.edge, owner);
+}
+
+static gboolean check_ship(MapElement element, gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return can_ship_be_built(element.edge, owner);
+}
+
+static gboolean check_ship_move(MapElement element, gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return can_ship_be_moved(element.edge, owner);
+}
+
+static gboolean check_bridge(MapElement element, gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return can_bridge_be_built(element.edge, owner);
+}
+
+static gboolean check_settlement(MapElement element, gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return can_settlement_be_built(element.node, owner);
+}
+
+static gboolean check_city(MapElement element, gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return can_settlement_be_upgraded(element.node, owner);
+}
+
+static gboolean check_city_wall(MapElement element, gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return can_city_wall_be_built(element.node, owner);
+}
+
+/* turn */
+static void frontend_state_turn(GuiEvent event)
+{
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_ROLL, !have_rolled_dice());
+ frontend_gui_check(GUI_UNDO, can_undo());
+ frontend_gui_check(GUI_ROAD, turn_can_build_road());
+ frontend_gui_check(GUI_SHIP, turn_can_build_ship());
+ frontend_gui_check(GUI_MOVE_SHIP, turn_can_move_ship());
+ frontend_gui_check(GUI_BRIDGE, turn_can_build_bridge());
+ frontend_gui_check(GUI_SETTLEMENT,
+ turn_can_build_settlement());
+ frontend_gui_check(GUI_CITY, turn_can_build_city());
+ frontend_gui_check(GUI_CITY_WALL,
+ turn_can_build_city_wall());
+ frontend_gui_check(GUI_TRADE, turn_can_trade());
+ frontend_gui_check(GUI_PLAY_DEVELOP,
+ can_play_develop(develop_current_idx
+ ()));
+ frontend_gui_check(GUI_BUY_DEVELOP, can_buy_develop());
+ frontend_gui_check(GUI_FINISH, have_rolled_dice());
+
+ guimap_single_click_set_functions(check_road,
+ build_road_cb,
+ check_ship,
+ build_ship_cb,
+ check_bridge,
+ build_bridge_cb,
+ check_settlement,
+ build_settlement_cb,
+ check_city,
+ build_city_cb,
+ check_city_wall,
+ build_city_wall_cb,
+ check_ship_move,
+ move_ship_cb,
+ cancel_move_ship_cb);
+ break;
+ case GUI_ROLL:
+ cb_roll();
+ break;
+ case GUI_UNDO:
+ cb_undo();
+ return;
+ case GUI_ROAD:
+ gui_cursor_set(ROAD_CURSOR, check_road, build_road_cb,
+ NULL, NULL);
+ return;
+ case GUI_SHIP:
+ gui_cursor_set(SHIP_CURSOR, check_ship, build_ship_cb,
+ NULL, NULL);
+ return;
+ case GUI_MOVE_SHIP:
+ gui_cursor_set(SHIP_CURSOR, check_ship_move, move_ship_cb,
+ NULL, NULL);
+ return;
+ case GUI_BRIDGE:
+ gui_cursor_set(BRIDGE_CURSOR, check_bridge,
+ build_bridge_cb, NULL, NULL);
+ return;
+ case GUI_SETTLEMENT:
+ gui_cursor_set(SETTLEMENT_CURSOR, check_settlement,
+ build_settlement_cb, NULL, NULL);
+ return;
+ case GUI_CITY:
+ gui_cursor_set(CITY_CURSOR, check_city, build_city_cb,
+ NULL, NULL);
+ return;
+ case GUI_CITY_WALL:
+ gui_cursor_set(CITY_WALL_CURSOR, check_city_wall,
+ build_city_wall_cb, NULL, NULL);
+ return;
+ case GUI_TRADE:
+ trade_begin();
+ set_gui_state(frontend_state_trade);
+ return;
+ case GUI_PLAY_DEVELOP:
+ cb_play_develop(develop_current_idx());
+ return;
+ case GUI_BUY_DEVELOP:
+ cb_buy_develop();
+ return;
+ case GUI_FINISH:
+ cb_end_turn();
+ gui_cursor_none(); /* Finish single click build */
+ set_gui_state(frontend_state_idle);
+ return;
+ default:
+ break;
+ }
+}
+
+void frontend_turn(void)
+{
+ /* if it already is our turn, just update the gui (maybe something
+ * happened), but don't beep */
+ if (get_gui_state() == frontend_state_turn
+ || get_gui_state() == frontend_state_trade) {
+ /* this is in the if, because it gets called from set_gui_state
+ * anyway. */
+ frontend_gui_update();
+ return;
+ }
+ set_gui_state(frontend_state_turn);
+ gdk_beep();
+}
+
+/* development card actions */
+/* road building */
+static void frontend_state_roadbuilding(GuiEvent event)
+{
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_UNDO, can_undo());
+ frontend_gui_check(GUI_ROAD,
+ road_building_can_build_road());
+ frontend_gui_check(GUI_SHIP,
+ road_building_can_build_ship());
+ frontend_gui_check(GUI_BRIDGE,
+ road_building_can_build_bridge());
+ frontend_gui_check(GUI_FINISH, road_building_can_finish());
+ guimap_single_click_set_functions(check_road,
+ build_road_cb,
+ check_ship,
+ build_ship_cb,
+ check_bridge,
+ build_bridge_cb,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL);
+ break;
+ case GUI_UNDO:
+ cb_undo();
+ return;
+ case GUI_ROAD:
+ gui_cursor_set(ROAD_CURSOR, check_road, build_road_cb,
+ NULL, NULL);
+ return;
+ case GUI_SHIP:
+ gui_cursor_set(SHIP_CURSOR, check_ship, build_ship_cb,
+ NULL, NULL);
+ return;
+ case GUI_BRIDGE:
+ gui_cursor_set(BRIDGE_CURSOR, check_bridge,
+ build_bridge_cb, NULL, NULL);
+ return;
+ case GUI_FINISH:
+ cb_end_turn();
+ gui_cursor_none(); /* Finish single click build */
+ set_gui_state(frontend_state_turn);
+ gui_prompt_hide();
+ return;
+ default:
+ break;
+ }
+}
+
+void frontend_roadbuilding(gint num_roads)
+{
+ gui_prompt_show(road_building_message(num_roads));
+ if (get_gui_state() == frontend_state_roadbuilding)
+ return;
+ set_gui_state(frontend_state_roadbuilding);
+}
+
+/* monopoly */
+static void frontend_state_monopoly(GuiEvent event)
+{
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_MONOPOLY, TRUE);
+ break;
+ case GUI_MONOPOLY:
+ cb_choose_monopoly(monopoly_type());
+ monopoly_destroy_dlg();
+ set_gui_state(frontend_state_turn);
+ return;
+ default:
+ break;
+ }
+}
+
+void frontend_monopoly(void)
+{
+ monopoly_create_dlg();
+ set_gui_state(frontend_state_monopoly);
+}
+
+/* year of plenty */
+static void frontend_state_plenty(GuiEvent event)
+{
+ gint plenty[NO_RESOURCE];
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_PLENTY, plenty_can_activate());
+ break;
+ case GUI_PLENTY:
+ plenty_resources(plenty);
+ cb_choose_plenty(plenty);
+ plenty_destroy_dlg();
+ set_gui_state(frontend_state_turn);
+ return;
+ default:
+ break;
+ }
+}
+
+void frontend_plenty(const gint * bank)
+{
+ plenty_create_dlg(bank);
+ set_gui_state(frontend_state_plenty);
+}
+
+/* general actions */
+/* discard */
+static void frontend_state_discard(GuiEvent event)
+{
+ gint discards[NO_RESOURCE];
+
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_DISCARD, can_discard());
+ break;
+ case GUI_DISCARD:
+ discard_get_list(discards);
+ cb_discard(discards);
+ return;
+ default:
+ break;
+ }
+}
+
+void frontend_discard(void)
+{
+ /* set state to idle until we must discard (or discard ends) */
+ if (!discard_busy) {
+ discard_busy = TRUE;
+ discard_begin();
+ g_assert(previous_state == dummy_state);
+ previous_state = get_gui_state();
+ set_gui_state(frontend_state_idle);
+ gui_cursor_none(); /* Clear possible cursor */
+ }
+}
+
+void frontend_discard_add(gint player_num, gint discard_num)
+{
+ if (player_num == my_player_num())
+ g_assert(callback_mode == MODE_DISCARD);
+ discard_player_must(player_num, discard_num);
+ if (player_num == my_player_num())
+ set_gui_state(frontend_state_discard);
+ frontend_gui_update();
+}
+
+void frontend_discard_remove(gint player_num)
+{
+ if (discard_busy) {
+ discard_player_did(player_num);
+ if (player_num == my_player_num())
+ set_gui_state(frontend_state_idle);
+ }
+ frontend_gui_update();
+}
+
+void frontend_discard_done(void)
+{
+ discard_busy = FALSE;
+ discard_end();
+ if (previous_state != dummy_state) {
+ set_gui_state(previous_state);
+ previous_state = dummy_state;
+ }
+}
+
+/* gold */
+static void frontend_state_gold(GuiEvent event)
+{
+ gint gold[NO_RESOURCE];
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_CHOOSE_GOLD, can_choose_gold());
+ break;
+ case GUI_CHOOSE_GOLD:
+ choose_gold_get_list(gold);
+ cb_choose_gold(gold);
+ return;
+ default:
+ break;
+ }
+}
+
+void frontend_gold(void)
+{
+ if (get_gui_state() != frontend_state_gold) {
+ gold_choose_begin();
+ g_assert(previous_state == dummy_state);
+ previous_state = get_gui_state();
+ set_gui_state(frontend_state_gold);
+ gui_cursor_none(); /* Clear possible cursor */
+ }
+}
+
+void frontend_gold_add(gint player_num, gint gold_num)
+{
+ gold_choose_player_prepare(player_num, gold_num);
+ frontend_gui_update();
+}
+
+void frontend_gold_choose(gint gold_num, const gint * bank)
+{
+ gold_choose_player_must(gold_num, bank);
+ frontend_gui_update();
+}
+
+void frontend_gold_remove(gint player_num, gint * resources)
+{
+ gold_choose_player_did(player_num, resources);
+ frontend_gui_update();
+}
+
+void frontend_gold_done(void)
+{
+ gold_choose_end();
+ if (previous_state != dummy_state) {
+ set_gui_state(previous_state);
+ previous_state = dummy_state;
+ }
+}
+
+void frontend_game_over(gint player, gint points)
+{
+ gui_cursor_none(); /* Clear possible (robber) cursor */
+ if (robber_busy) {
+ robber_busy = FALSE;
+ gui_prompt_hide();
+ }
+ gameover_create_dlg(player, points);
+ set_gui_state(frontend_state_idle);
+}
+
+void frontend_rolled_dice(gint die1, gint die2, gint player_num)
+{
+ histogram_dice_rolled(die1 + die2, player_num);
+ identity_set_dice(die1, die2);
+ gui_highlight_chits(die1 + die2);
+ frontend_gui_update();
+}
+
+static void frontend_state_robber(GuiEvent event)
+{
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_UNDO, callback_mode == MODE_ROB);
+ break;
+ case GUI_UNDO:
+ cb_undo();
+ /* restart robber placement. */
+ frontend_robber();
+ break;
+ default:
+ break;
+ }
+}
+
+static void rob_building(MapElement node, G_GNUC_UNUSED MapElement extra)
+{
+ cb_rob(node.node->owner);
+}
+
+static void rob_edge(MapElement edge, G_GNUC_UNUSED MapElement extra)
+{
+ cb_rob(edge.edge->owner);
+}
+
+/* Return TRUE if the node can be robbed. */
+static gboolean can_building_be_robbed(MapElement node,
+ G_GNUC_UNUSED int owner,
+ MapElement robber)
+{
+ gint idx;
+
+ /* Can only steal from buildings that are not owned by me */
+ if (node.node->type == BUILD_NONE
+ || node.node->owner == my_player_num())
+ return FALSE;
+
+ /* Can only steal if the owner has some resources */
+ if (player_get(node.node->owner)->statistics[STAT_RESOURCES] == 0)
+ return FALSE;
+
+ /* Can only steal from buildings adjacent to hex with robber */
+ for (idx = 0; idx < G_N_ELEMENTS(node.node->hexes); idx++)
+ if (node.node->hexes[idx] == robber.hex)
+ return TRUE;
+ return FALSE;
+}
+
+/** Returns TRUE if the edge can be robbed. */
+static gboolean can_edge_be_robbed(MapElement edge,
+ G_GNUC_UNUSED int owner,
+ MapElement pirate)
+{
+ gint idx;
+
+ /* Can only steal from ships that are not owned by me */
+ if (edge.edge->type != BUILD_SHIP
+ || edge.edge->owner == my_player_num())
+ return FALSE;
+
+ /* Can only steal if the owner has some resources */
+ if (player_get(edge.edge->owner)->statistics[STAT_RESOURCES] == 0)
+ return FALSE;
+
+ /* Can only steal from edges adjacent to hex with pirate */
+ for (idx = 0; idx < G_N_ELEMENTS(edge.edge->hexes); idx++)
+ if (edge.edge->hexes[idx] == pirate.hex)
+ return TRUE;
+ return FALSE;
+}
+
+/* User just placed the robber
+ */
+static void place_robber_or_pirate_cb(MapElement hex,
+ G_GNUC_UNUSED MapElement extra)
+{
+ cb_place_robber(hex.hex);
+}
+
+void frontend_steal_ship(void)
+{
+ MapElement hex;
+ hex.hex = map_pirate_hex(get_map());
+
+ gui_cursor_set(STEAL_SHIP_CURSOR, can_edge_be_robbed, rob_edge,
+ NULL, &hex);
+ gui_prompt_show(_("Select the ship to steal from"));
+}
+
+void frontend_steal_building(void)
+{
+ MapElement hex;
+ hex.hex = map_robber_hex(get_map());
+
+ gui_cursor_set(STEAL_BUILDING_CURSOR, can_building_be_robbed,
+ rob_building, NULL, &hex);
+ gui_prompt_show(_("Select the building to steal from"));
+}
+
+void frontend_robber_done(void)
+{
+ robber_busy = FALSE;
+ if (previous_state != dummy_state) {
+ set_gui_state(previous_state);
+ previous_state = dummy_state;
+ }
+ gui_prompt_hide();
+}
+
+static gboolean check_move_robber_or_pirate(MapElement element,
+ G_GNUC_UNUSED int owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return can_robber_or_pirate_be_moved(element.hex);
+}
+
+void frontend_robber(void)
+{
+ if (!robber_busy) {
+ /* Do this only once. */
+ robber_busy = TRUE;
+ g_assert(previous_state == dummy_state);
+ previous_state = get_gui_state();
+ }
+ /* These things are redone at undo. */
+ set_gui_state(frontend_state_robber);
+ gui_cursor_set(ROBBER_CURSOR, check_move_robber_or_pirate,
+ place_robber_or_pirate_cb, NULL, NULL);
+ gui_prompt_show(_("Place the robber"));
+ frontend_gui_update();
+}
+
+static gboolean check_road_setup(MapElement element,
+ G_GNUC_UNUSED gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return setup_check_road(element.edge);
+}
+
+static gboolean check_ship_setup(MapElement element,
+ G_GNUC_UNUSED gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return setup_check_ship(element.edge);
+}
+
+static gboolean check_bridge_setup(MapElement element,
+ G_GNUC_UNUSED gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return setup_check_bridge(element.edge);
+}
+
+static gboolean check_settlement_setup(MapElement element,
+ G_GNUC_UNUSED gint owner,
+ G_GNUC_UNUSED MapElement extra)
+{
+ return setup_check_settlement(element.node);
+}
+
+static void frontend_mode_setup(GuiEvent event)
+{
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_UNDO, can_undo());
+ frontend_gui_check(GUI_ROAD, setup_can_build_road());
+ frontend_gui_check(GUI_BRIDGE, setup_can_build_bridge());
+ frontend_gui_check(GUI_SHIP, setup_can_build_ship());
+ frontend_gui_check(GUI_SETTLEMENT,
+ setup_can_build_settlement());
+ frontend_gui_check(GUI_FINISH, setup_can_finish());
+ guimap_single_click_set_functions(check_road_setup,
+ build_road_cb,
+ check_ship_setup,
+ build_ship_cb,
+ check_bridge_setup,
+ build_bridge_cb,
+ check_settlement_setup,
+ build_settlement_cb,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL);
+ break;
+ case GUI_UNDO:
+ /* The user has pressed the "Undo" button. Send a
+ * command to the server to attempt the undo. The
+ * server will respond telling us whether the undo was
+ * successful or not.
+ */
+ cb_undo();
+ return;
+ case GUI_ROAD:
+ gui_cursor_set(ROAD_CURSOR,
+ check_road_setup, build_road_cb, NULL,
+ NULL);
+ return;
+ case GUI_SHIP:
+ gui_cursor_set(SHIP_CURSOR,
+ check_ship_setup, build_ship_cb, NULL,
+ NULL);
+ return;
+ case GUI_BRIDGE:
+ gui_cursor_set(BRIDGE_CURSOR,
+ check_bridge_setup, build_bridge_cb, NULL,
+ NULL);
+ return;
+ case GUI_SETTLEMENT:
+ gui_cursor_set(SETTLEMENT_CURSOR,
+ check_settlement_setup,
+ build_settlement_cb, NULL, NULL);
+ return;
+ case GUI_FINISH:
+ cb_end_turn();
+ gui_cursor_none(); /* Finish single click build */
+ set_gui_state(frontend_state_idle);
+ return;
+ default:
+ break;
+ }
+}
+
+void frontend_setup(G_GNUC_UNUSED unsigned num_settlements,
+ G_GNUC_UNUSED unsigned num_roads)
+{
+ if (get_gui_state() == frontend_mode_setup) {
+ frontend_gui_update();
+ return;
+ }
+ set_gui_state(frontend_mode_setup);
+ gdk_beep();
+}
Added: trunk/client/gtk/legend.c
===================================================================
--- trunk/client/gtk/legend.c (rev 0)
+++ trunk/client/gtk/legend.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,313 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2005 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "theme.h"
+#include "cost.h"
+
+/* The order of the terrain_names is EXTREMELY important! The order
+ * must match the enum Terrain.
+ */
+static const gchar *terrain_names[] = {
+ N_("Hill"),
+ N_("Field"),
+ N_("Mountain"),
+ N_("Pasture"),
+ N_("Forest"),
+ N_("Desert"),
+ N_("Sea"),
+ N_("Gold")
+};
+
+static GtkWidget *legend_dlg = NULL;
+static gboolean legend_did_connect = FALSE;
+
+static void legend_theme_changed(void);
+static void legend_rules_changed(void);
+
+static gint expose_legend_cb(GtkWidget * area,
+ G_GNUC_UNUSED GdkEventExpose * event,
+ gpointer terraindata)
+{
+ MapTheme *theme = theme_get_current();
+ static GdkGC *legend_gc;
+ GdkPixbuf *p;
+ gint height;
+ Terrain terrain = GPOINTER_TO_INT(terraindata);
+
+ if (area->window == NULL)
+ return FALSE;
+
+ if (legend_gc == NULL)
+ legend_gc = gdk_gc_new(area->window);
+
+ gdk_gc_set_fill(legend_gc, GDK_TILED);
+ gdk_gc_set_tile(legend_gc, guimap_terrain(terrain));
+
+ height = area->allocation.width / theme->scaledata[terrain].aspect;
+ p = gdk_pixbuf_scale_simple(theme->scaledata[terrain].
+ native_image, area->allocation.width,
+ height, GDK_INTERP_BILINEAR);
+
+ /* Center the image in the available space */
+ gdk_draw_pixbuf(area->window, legend_gc, p,
+ 0, 0, 0, (area->allocation.height - height) / 2,
+ -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
+ gdk_pixbuf_unref(p);
+ return FALSE;
+}
+
+static void add_legend_terrain(GtkWidget * table, guint row, guint col,
+ Terrain terrain, Resource resource)
+{
+ GtkWidget *area;
+ GtkWidget *label;
+ GdkPixmap *p;
+ GdkBitmap *b;
+
+ area = gtk_drawing_area_new();
+ gtk_widget_show(area);
+ gtk_table_attach(GTK_TABLE(table), area,
+ col, col + 1, row, row + 1,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_FILL, 0, 0);
+ gtk_widget_set_size_request(area, 30, 34);
+ g_signal_connect(G_OBJECT(area), "expose_event",
+ G_CALLBACK(expose_legend_cb),
+ GINT_TO_POINTER(terrain));
+
+ label = gtk_label_new(_(terrain_names[terrain]));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label,
+ col + 1, col + 2, row, row + 1,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ if (resource < NO_RESOURCE) {
+ gui_get_resource_pixmap(resource, &p, &b, NULL, NULL);
+ label = gtk_image_new_from_pixmap(p, b);
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label,
+ col + 2, col + 3, row, row + 1,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_FILL, 0, 0);
+ }
+
+ if (resource != NO_RESOURCE) {
+ label = gtk_label_new(resource_name(resource, TRUE));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label,
+ col + 3, col + 4, row, row + 1,
+ (GtkAttachOptions) GTK_FILL,
+ (GtkAttachOptions) GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ }
+}
+
+static void add_legend_cost(GtkWidget * table, guint row,
+ const gchar * iconname, const gchar * item,
+ const gint * cost)
+{
+ GtkWidget *label;
+ GtkWidget *icon;
+
+ icon = gtk_image_new_from_stock(iconname, GTK_ICON_SIZE_MENU);
+ gtk_widget_show(icon);
+ gtk_table_attach(GTK_TABLE(table), icon, 0, 1, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ label = gtk_label_new(item);
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 1, 2, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ label = gtk_image_new();
+ resource_format_type_image(GTK_IMAGE(label), cost, -1);
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 2, 3, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+}
+
+GtkWidget *legend_create_content(void)
+{
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *table;
+ GtkWidget *vsep;
+ GtkWidget *alignment;
+ guint num_rows;
+
+ hbox = gtk_hbox_new(FALSE, 6);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 6);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
+
+ label = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(label), _("<b>Terrain Yield</b>"));
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
+
+ table = gtk_table_new(4, 9, FALSE);
+ gtk_widget_show(table);
+ gtk_container_add(GTK_CONTAINER(alignment), table);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 6);
+
+ add_legend_terrain(table, 0, 0, HILL_TERRAIN, BRICK_RESOURCE);
+ add_legend_terrain(table, 1, 0, FIELD_TERRAIN, GRAIN_RESOURCE);
+ add_legend_terrain(table, 2, 0, MOUNTAIN_TERRAIN, ORE_RESOURCE);
+ add_legend_terrain(table, 3, 0, PASTURE_TERRAIN, WOOL_RESOURCE);
+
+ vsep = gtk_vseparator_new();
+ gtk_widget_show(vsep);
+ gtk_table_attach(GTK_TABLE(table), vsep, 4, 5, 0, 4,
+ GTK_FILL, GTK_FILL, 0, 0);
+
+ add_legend_terrain(table, 0, 5, FOREST_TERRAIN, LUMBER_RESOURCE);
+ add_legend_terrain(table, 1, 5, GOLD_TERRAIN, GOLD_RESOURCE);
+ add_legend_terrain(table, 2, 5, DESERT_TERRAIN, NO_RESOURCE);
+ add_legend_terrain(table, 3, 5, SEA_TERRAIN, NO_RESOURCE);
+
+ label = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(label), _("<b>Building Costs</b>"));
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
+
+ num_rows = 4;
+ if (have_ships())
+ num_rows++;
+ if (have_bridges())
+ num_rows++;
+ if (have_city_walls())
+ num_rows++;
+ table = gtk_table_new(num_rows, 3, FALSE);
+ gtk_widget_show(table);
+ gtk_container_add(GTK_CONTAINER(alignment), table);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 5);
+
+ num_rows = 0;
+ add_legend_cost(table, num_rows++, PIONEERS_PIXMAP_ROAD, _("Road"),
+ cost_road());
+ if (have_ships())
+ add_legend_cost(table, num_rows++, PIONEERS_PIXMAP_SHIP,
+ _("Ship"), cost_ship());
+ if (have_bridges())
+ add_legend_cost(table, num_rows++, PIONEERS_PIXMAP_BRIDGE,
+ _("Bridge"), cost_bridge());
+ add_legend_cost(table, num_rows++, PIONEERS_PIXMAP_SETTLEMENT,
+ _("Settlement"), cost_settlement());
+ add_legend_cost(table, num_rows++, PIONEERS_PIXMAP_CITY, _("City"),
+ cost_upgrade_settlement());
+ if (have_city_walls())
+ add_legend_cost(table, num_rows++,
+ PIONEERS_PIXMAP_CITY_WALL, _("City Wall"),
+ cost_city_wall());
+ add_legend_cost(table, num_rows++, PIONEERS_PIXMAP_DEVELOP,
+ _("Development Card"), cost_development());
+
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
+ gtk_widget_show(hbox);
+ return hbox;
+}
+
+GtkWidget *legend_create_dlg(void)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *vbox;
+
+ if (legend_dlg != NULL) {
+ gtk_window_present(GTK_WINDOW(legend_dlg));
+ return legend_dlg;
+ }
+
+ legend_dlg = gtk_dialog_new_with_buttons(_("Legend"),
+ GTK_WINDOW(app_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE, NULL);
+ g_signal_connect(G_OBJECT(legend_dlg), "destroy",
+ G_CALLBACK(gtk_widget_destroyed), &legend_dlg);
+
+ dlg_vbox = GTK_DIALOG(legend_dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ vbox = legend_create_content();
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, TRUE, TRUE, 0);
+
+ gtk_widget_show(legend_dlg);
+
+ if (!legend_did_connect) {
+ theme_register_callback(G_CALLBACK(legend_theme_changed));
+ gui_rules_register_callback(G_CALLBACK
+ (legend_rules_changed));
+ legend_did_connect = TRUE;
+ }
+
+ /* destroy dialog when OK is clicked */
+ g_signal_connect(legend_dlg, "response",
+ G_CALLBACK(gtk_widget_destroy), NULL);
+
+ return legend_dlg;
+}
+
+static void legend_theme_changed(void)
+{
+ if (legend_dlg)
+ gtk_widget_queue_draw(legend_dlg);
+}
+
+static void legend_rules_changed(void)
+{
+ if (legend_dlg) {
+ GtkWidget *dlg_vbox = GTK_DIALOG(legend_dlg)->vbox;
+ GtkWidget *vbox;
+ GList *list =
+ gtk_container_get_children(GTK_CONTAINER(dlg_vbox));
+
+ if (g_list_length(list) > 0)
+ gtk_widget_destroy(GTK_WIDGET(list->data));
+
+ vbox = legend_create_content();
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, TRUE, TRUE, 0);
+
+ g_list_free(list);
+ }
+}
Added: trunk/client/gtk/monopoly.c
===================================================================
--- trunk/client/gtk/monopoly.c (rev 0)
+++ trunk/client/gtk/monopoly.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,137 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+
+static GtkWidget *monop_dlg;
+static Resource monop_type;
+
+static void monop_toggled(GtkToggleButton * btn, gpointer type)
+{
+ if (gtk_toggle_button_get_active(btn))
+ monop_type = GPOINTER_TO_INT(type);
+}
+
+static GSList *add_resource_btn(GtkWidget * vbox,
+ GSList * grp, Resource resource)
+{
+ GtkWidget *btn;
+ gboolean active;
+
+ active = grp == NULL;
+ btn = gtk_radio_button_new_with_label(grp,
+ resource_name(resource,
+ TRUE));
+ grp = gtk_radio_button_get_group(GTK_RADIO_BUTTON(btn));
+ gtk_widget_show(btn);
+ gtk_box_pack_start(GTK_BOX(vbox), btn, TRUE, TRUE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(btn), active);
+
+ g_signal_connect(G_OBJECT(btn), "toggled",
+ G_CALLBACK(monop_toggled),
+ GINT_TO_POINTER(resource));
+ if (active)
+ monop_type = resource;
+
+ return grp;
+}
+
+static void monopoly_destroyed(G_GNUC_UNUSED GtkWidget * widget,
+ G_GNUC_UNUSED gpointer data)
+{
+ if (callback_mode == MODE_MONOPOLY)
+ monopoly_create_dlg();
+}
+
+Resource monopoly_type(void)
+{
+ return monop_type;
+}
+
+void monopoly_create_dlg(void)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *vbox;
+ GtkWidget *lbl;
+ GSList *monop_grp = NULL;
+
+ if (monop_dlg != NULL) {
+ gtk_window_present(GTK_WINDOW(monop_dlg));
+ return;
+ };
+
+ monop_dlg = gtk_dialog_new_with_buttons(_("Monopoly"),
+ GTK_WINDOW(app_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK, NULL);
+ g_signal_connect(G_OBJECT(monop_dlg), "destroy",
+ G_CALLBACK(gtk_widget_destroyed), &monop_dlg);
+ gtk_widget_realize(monop_dlg);
+ /* Disable close */
+ gdk_window_set_functions(monop_dlg->window,
+ GDK_FUNC_ALL | GDK_FUNC_CLOSE);
+
+ dlg_vbox = GTK_DIALOG(monop_dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+
+ lbl =
+ gtk_label_new(_
+ ("Select the resource you wish to monopolise."));
+ gtk_widget_show(lbl);
+ gtk_box_pack_start(GTK_BOX(vbox), lbl, TRUE, TRUE, 0);
+ gtk_misc_set_alignment(GTK_MISC(lbl), 0, 0.5);
+
+ monop_grp = add_resource_btn(vbox, monop_grp, BRICK_RESOURCE);
+ monop_grp = add_resource_btn(vbox, monop_grp, GRAIN_RESOURCE);
+ monop_grp = add_resource_btn(vbox, monop_grp, ORE_RESOURCE);
+ monop_grp = add_resource_btn(vbox, monop_grp, WOOL_RESOURCE);
+ monop_grp = add_resource_btn(vbox, monop_grp, LUMBER_RESOURCE);
+
+ frontend_gui_register(gui_get_dialog_button
+ (GTK_DIALOG(monop_dlg), 0), GUI_MONOPOLY,
+ "clicked");
+ gtk_dialog_set_default_response(GTK_DIALOG(monop_dlg),
+ GTK_RESPONSE_OK);
+ /* This _must_ be after frontend_gui_register, otherwise the
+ * regeneration of the button happens before the destruction, which
+ * results in an incorrectly sensitive OK button. */
+ g_signal_connect(gui_get_dialog_button(GTK_DIALOG(monop_dlg), 0),
+ "destroy", G_CALLBACK(monopoly_destroyed), NULL);
+ gtk_widget_show(monop_dlg);
+ frontend_gui_update();
+}
+
+void monopoly_destroy_dlg(void)
+{
+ if (monop_dlg == NULL)
+ return;
+
+ gtk_widget_destroy(monop_dlg);
+ monop_dlg = NULL;
+}
Added: trunk/client/gtk/name.c
===================================================================
--- trunk/client/gtk/name.c (rev 0)
+++ trunk/client/gtk/name.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,261 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003,2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include "frontend.h"
+#include "player-icon.h"
+#include "config-gnome.h"
+
+typedef struct {
+ GtkWidget *dlg;
+ GtkWidget *name_entry;
+ GtkWidget *check_btn;
+ GtkWidget *image;
+ GtkWidget *style_hbox;
+ GtkWidget *color_btn1;
+ GtkWidget *color_btn2;
+ GtkWidget *variant_btn;
+ gchar *original_name;
+ gchar *original_style;
+ gchar *current_style;
+} DialogData;
+
+static DialogData name_dialog;
+
+static GdkPixbuf *create_icon(GtkWidget * widget, const gchar * style);
+
+static void change_name_cb(G_GNUC_UNUSED GtkDialog * dlg, int response_id,
+ gpointer user_data)
+{
+ DialogData *dialog = user_data;
+ if (response_id == GTK_RESPONSE_OK) {
+ const gchar *new_name =
+ gtk_entry_get_text(GTK_ENTRY(dialog->name_entry));
+ const gchar *new_style = dialog->current_style;
+ if (0 != strcmp(new_name, dialog->original_name)) {
+ cb_name_change(new_name);
+ config_set_string("connect/name", new_name);
+ }
+ if (0 != strcmp(new_style, dialog->original_style)) {
+ cb_style_change(new_style);
+ config_set_string("connect/style", new_style);
+ }
+ }
+ g_free(dialog->original_name);
+ g_free(dialog->original_style);
+ g_free(dialog->current_style);
+ gtk_widget_destroy(GTK_WIDGET(dialog->dlg));
+}
+
+static void change_style_cb(G_GNUC_UNUSED GtkWidget * widget,
+ gpointer user_data)
+{
+ GdkPixbuf *icon;
+ DialogData *dialog = user_data;
+
+ g_free(dialog->current_style);
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(dialog->check_btn))) {
+ GdkColor c1;
+ GdkColor c2;
+ gint variant;
+ gtk_color_button_get_color(GTK_COLOR_BUTTON
+ (dialog->color_btn1), &c1);
+ gtk_color_button_get_color(GTK_COLOR_BUTTON
+ (dialog->color_btn2), &c2);
+ variant = (int)
+ gtk_range_get_value(GTK_RANGE(dialog->variant_btn)) -
+ 1;
+ dialog->current_style =
+ playericon_create_human_style(&c1, variant, &c2);
+ } else {
+ dialog->current_style = g_strdup("square");
+ }
+ icon = create_icon(dialog->image, dialog->current_style);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->image), icon);
+ g_object_unref(icon);
+}
+
+static void activate_style_cb(GtkWidget * widget, gpointer user_data)
+{
+ DialogData *dialog = user_data;
+ gtk_widget_set_sensitive(dialog->style_hbox,
+ gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(dialog->check_btn)));
+ change_style_cb(widget, user_data);
+}
+
+void name_create_dlg(void)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *hbox;
+ GtkWidget *lbl;
+ GdkPixbuf *icon;
+ GdkColor face_color, variant_color;
+ gint variant;
+ gboolean parse_ok;
+
+ if (name_dialog.dlg != NULL) {
+ gtk_window_present(GTK_WINDOW(name_dialog.dlg));
+ return;
+ };
+
+ name_dialog.dlg =
+ gtk_dialog_new_with_buttons(_("Change player name"),
+ GTK_WINDOW(app_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL, GTK_STOCK_OK,
+ GTK_RESPONSE_OK, NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(name_dialog.dlg),
+ GTK_RESPONSE_OK);
+ g_signal_connect(G_OBJECT(name_dialog.dlg), "destroy",
+ G_CALLBACK(gtk_widget_destroyed),
+ &name_dialog.dlg);
+ gtk_widget_realize(name_dialog.dlg);
+ gdk_window_set_functions(name_dialog.dlg->window,
+ GDK_FUNC_MOVE | GDK_FUNC_CLOSE);
+
+ dlg_vbox = GTK_DIALOG(name_dialog.dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), hbox, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+
+ lbl = gtk_label_new(_("Player Name:"));
+ gtk_widget_show(lbl);
+ gtk_box_pack_start(GTK_BOX(hbox), lbl, FALSE, TRUE, 0);
+ gtk_misc_set_alignment(GTK_MISC(lbl), 1, 0.5);
+
+ name_dialog.name_entry = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(name_dialog.name_entry),
+ MAX_NAME_LENGTH);
+ gtk_widget_show(name_dialog.name_entry);
+ gtk_box_pack_start(GTK_BOX(hbox), name_dialog.name_entry, TRUE,
+ TRUE, 0);
+ gtk_entry_set_width_chars(GTK_ENTRY(name_dialog.name_entry),
+ MAX_NAME_LENGTH);
+ name_dialog.original_name = g_strdup(my_player_name());
+ gtk_entry_set_text(GTK_ENTRY(name_dialog.name_entry),
+ name_dialog.original_name);
+
+ gtk_entry_set_activates_default(GTK_ENTRY(name_dialog.name_entry),
+ TRUE);
+
+ name_dialog.original_style = g_strdup(my_player_style());
+ name_dialog.current_style = g_strdup(my_player_style());
+ parse_ok =
+ playericon_parse_human_style(name_dialog.current_style,
+ &face_color, &variant,
+ &variant_color);
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), hbox, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+
+ name_dialog.style_hbox = gtk_hbox_new(FALSE, 5);
+ gtk_widget_set_sensitive(name_dialog.style_hbox, FALSE);
+
+ name_dialog.check_btn = gtk_check_button_new();
+ gtk_widget_show(name_dialog.check_btn);
+ gtk_box_pack_start(GTK_BOX(hbox), name_dialog.check_btn, FALSE,
+ TRUE, 0);
+ g_signal_connect(name_dialog.check_btn, "toggled",
+ G_CALLBACK(activate_style_cb), &name_dialog);
+
+ icon = create_icon(hbox, name_dialog.original_style);
+ name_dialog.image = gtk_image_new_from_pixbuf(icon);
+ g_object_unref(icon);
+ gtk_widget_show(name_dialog.image);
+ gtk_box_pack_start(GTK_BOX(hbox), name_dialog.image, FALSE, TRUE,
+ 0);
+
+ gtk_widget_show(name_dialog.style_hbox);
+ gtk_box_pack_start(GTK_BOX(hbox), name_dialog.style_hbox, TRUE,
+ TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER
+ (name_dialog.style_hbox), 5);
+
+ /* Set icon preferences */
+ lbl = gtk_label_new(_("Face:"));
+ gtk_widget_show(lbl);
+ gtk_box_pack_start(GTK_BOX(name_dialog.style_hbox), lbl, FALSE,
+ TRUE, 0);
+ gtk_misc_set_alignment(GTK_MISC(lbl), 1, 0.5);
+
+ name_dialog.color_btn1 = gtk_color_button_new();
+ gtk_color_button_set_color(GTK_COLOR_BUTTON
+ (name_dialog.color_btn1), &face_color);
+ gtk_widget_show(name_dialog.color_btn1);
+ gtk_box_pack_start(GTK_BOX(name_dialog.style_hbox),
+ name_dialog.color_btn1, FALSE, TRUE, 0);
+ g_signal_connect(name_dialog.color_btn1, "color-set",
+ G_CALLBACK(change_style_cb), &name_dialog);
+
+ lbl = gtk_label_new(_("Variant:"));
+ gtk_widget_show(lbl);
+ gtk_box_pack_start(GTK_BOX(name_dialog.style_hbox), lbl, FALSE,
+ TRUE, 0);
+ gtk_misc_set_alignment(GTK_MISC(lbl), 1, 0.5);
+
+ name_dialog.color_btn2 = gtk_color_button_new();
+ gtk_color_button_set_color(GTK_COLOR_BUTTON
+ (name_dialog.color_btn2),
+ &variant_color);
+ gtk_widget_show(name_dialog.color_btn2);
+ gtk_box_pack_start(GTK_BOX(name_dialog.style_hbox),
+ name_dialog.color_btn2, FALSE, TRUE, 0);
+ g_signal_connect(name_dialog.color_btn2, "color-set",
+ G_CALLBACK(change_style_cb), &name_dialog);
+
+ name_dialog.variant_btn = gtk_hscale_new_with_range(1.0, 7.0, 1.0);
+ gtk_scale_set_digits(GTK_SCALE(name_dialog.variant_btn), 0);
+ gtk_scale_set_value_pos(GTK_SCALE(name_dialog.variant_btn),
+ GTK_POS_LEFT);
+ gtk_range_set_value(GTK_RANGE(name_dialog.variant_btn),
+ variant + 1);
+ gtk_widget_show(name_dialog.variant_btn);
+ gtk_box_pack_start(GTK_BOX(name_dialog.style_hbox),
+ name_dialog.variant_btn, TRUE, TRUE, 0);
+ g_signal_connect(name_dialog.variant_btn, "value-changed",
+ G_CALLBACK(change_style_cb), &name_dialog);
+ /* destroy dialog when OK or Cancel button gets clicked */
+ g_signal_connect(name_dialog.dlg, "response",
+ G_CALLBACK(change_name_cb), &name_dialog);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (name_dialog.check_btn), parse_ok);
+
+ gtk_widget_show(name_dialog.dlg);
+ gtk_widget_grab_focus(name_dialog.name_entry);
+}
+
+GdkPixbuf *create_icon(GtkWidget * widget, const gchar * style)
+{
+ return playericon_create_icon(widget, style,
+ player_or_viewer_color(my_player_num
+ ()),
+ my_player_viewer(), TRUE, TRUE);
+}
Added: trunk/client/gtk/offline.c
===================================================================
--- trunk/client/gtk/offline.c (rev 0)
+++ trunk/client/gtk/offline.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,275 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003,2006 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004,2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include "frontend.h"
+#ifdef HAVE_LIBGNOME
+#include <libgnome/libgnome.h>
+#endif
+#include "common_gtk.h"
+#include "config-gnome.h"
+#include "theme.h"
+#include "histogram.h"
+#include "version.h"
+
+static gboolean have_dlg = FALSE;
+static gboolean connectable = FALSE;
+
+static const gchar *name = NULL;
+static gboolean viewer = FALSE;
+static const gchar *server = NULL;
+static const gchar *port = NULL;
+static const gchar *meta_server = NULL;
+static gboolean server_from_commandline = FALSE;
+static gboolean quit_when_offline = FALSE;
+#ifdef ENABLE_NLS
+static const gchar *override_language = NULL;
+#endif
+static gboolean enable_debug = FALSE;
+static gboolean show_version = FALSE;
+
+static GOptionEntry commandline_entries[] = {
+ /* Commandline option of client: hostname of the server */
+ {"server", 's', 0, G_OPTION_ARG_STRING, &server, N_("Server Host"),
+ PIONEERS_DEFAULT_GAME_HOST},
+ /* Commandline option of client: port of the server */
+ {"port", 'p', 0, G_OPTION_ARG_STRING, &port, N_("Server Port"),
+ PIONEERS_DEFAULT_GAME_PORT},
+ /* Commandline option of client: name of the player */
+ {"name", 'n', 0, G_OPTION_ARG_STRING, &name, N_("Player name"),
+ NULL},
+ /* Commandline option of client: do we want to be a viewer */
+ {"viewer", 'v', 0, G_OPTION_ARG_NONE, &viewer,
+ N_("Connect as a viewer"), NULL},
+ /* Commandline option of client: hostname of the meta-server */
+ {"meta-server", 'm', 0, G_OPTION_ARG_STRING, &meta_server,
+ N_("Meta-server Host"), PIONEERS_DEFAULT_META_SERVER},
+#ifdef ENABLE_NLS
+ /* Commandline option of client: override the language */
+ {"language", '\0', 0, G_OPTION_ARG_STRING, &override_language,
+ N_("Override the language of the system"), "en " ALL_LINGUAS},
+#endif
+ {"debug", '\0', 0, G_OPTION_ARG_NONE, &enable_debug,
+ /* Commandline option of client: enable debug logging */
+ N_("Enable debug messages"), NULL},
+ {"version", '\0', 0, G_OPTION_ARG_NONE, &show_version,
+ /* Commandline option of client: version */
+ N_("Show version information"), NULL},
+ {NULL, '\0', 0, 0, NULL, NULL, NULL}
+};
+
+static void frontend_offline_start_connect_cb(void)
+{
+ connect_create_dlg();
+ have_dlg = TRUE;
+ frontend_gui_update();
+}
+
+/* gui function to handle gui events in offline mode */
+static void frontend_offline_gui(GuiEvent event)
+{
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_CONNECT_TRY, TRUE);
+ frontend_gui_check(GUI_CONNECT, !have_dlg && connectable);
+ frontend_gui_check(GUI_DISCONNECT, !have_dlg
+ && !connectable);
+ break;
+ case GUI_CONNECT_TRY:
+ gui_show_splash_page(FALSE);
+ gui_set_net_status(_("Connecting"));
+
+ connectable = FALSE;
+ have_dlg = FALSE;
+ cb_connect(connect_get_server(), connect_get_port(),
+ connect_get_name(), connect_get_viewer(),
+ connect_get_style());
+ frontend_gui_update();
+ break;
+ case GUI_CONNECT:
+ frontend_offline_start_connect_cb();
+ break;
+ case GUI_CONNECT_CANCEL:
+ have_dlg = FALSE;
+ frontend_gui_update();
+ break;
+ default:
+ break;
+ }
+}
+
+void frontend_disconnect(void)
+{
+ quit_when_offline = FALSE;
+ cb_disconnect();
+}
+
+/* this function is called when offline mode is entered. */
+void frontend_offline(void)
+{
+ connectable = TRUE;
+
+ if (have_dlg)
+ return;
+
+ gui_cursor_none(); /* Clear possible cursor */
+ frontend_discard_done();
+ frontend_gold_done();
+
+ /* set the callback for gui events */
+ set_gui_state(frontend_offline_gui);
+
+ if (quit_when_offline) {
+ route_gui_event(GUI_QUIT);
+ }
+
+ /* Commandline overrides the dialog */
+ if (server_from_commandline) {
+ server_from_commandline = FALSE;
+ quit_when_offline = TRUE;
+ route_gui_event(GUI_CONNECT_TRY);
+ } else {
+ frontend_offline_start_connect_cb();
+ }
+}
+
+/* this function is called to let the frontend initialize itself. */
+void frontend_init(int argc, char **argv)
+{
+ GtkWidget *app;
+ gboolean default_returned;
+#if ENABLE_NLS
+ lang_desc *ld;
+#endif
+ GOptionContext *context;
+ GError *error = NULL;
+ gchar *style;
+
+ frontend_gui_register_init();
+
+ set_ui_driver(>K_Driver);
+
+ config_init("pioneers");
+
+ /* Long description in the commandline for pioneers: help */
+ context = g_option_context_new(_("- Play a game of Pioneers"));
+ g_option_context_add_main_entries(context, commandline_entries,
+ PACKAGE);
+ g_option_context_add_group(context, gtk_get_option_group(TRUE));
+ g_option_context_parse(context, &argc, &argv, &error);
+ if (error != NULL) {
+ g_print("%s\n", error->message);
+ g_error_free(error);
+ exit(1);
+ }
+ if (show_version) {
+ g_print(_("Pioneers version:"));
+ g_print(" ");
+ g_print(FULL_VERSION);
+ g_print("\n");
+ exit(0);
+ }
+
+
+ set_enable_debug(enable_debug);
+
+#if defined(HAVE_HELP) && defined(HAVE_LIBGNOME)
+ gnome_program_init(PACKAGE, FULL_VERSION,
+ LIBGNOME_MODULE, argc, argv,
+ GNOME_PARAM_APP_DATADIR, DATADIR, NULL);
+#endif /* HAVE_HELP && HAVE_LIBGNOME */
+
+#if ENABLE_NLS
+ /* Gtk+ handles the locale, we must bind the translations */
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+ bind_textdomain_codeset(PACKAGE, "UTF-8");
+
+ /* Override the language if it is set in the command line */
+ if (override_language && (ld = find_lang_desc(override_language)))
+ change_nls(ld);
+#endif
+
+ /* Create the application window
+ */
+ themes_init();
+ settings_init();
+ histogram_init();
+ app = gui_build_interface();
+
+ callbacks.mainloop = >k_main;
+ callbacks.quit = >k_main_quit;
+
+ /* in theory, all windows are created now...
+ * set logging to message window */
+ log_set_func_message_window();
+
+ if (!name) {
+ name =
+ config_get_string("connect/name", &default_returned);
+ if (default_returned) {
+ name = g_strdup(g_get_user_name());
+ }
+ /* If --viewer is used, we are now a viewer. If not, get the
+ * correct value from the config file.
+ * To allow specifying "don't be a viewer", only check the
+ * config file if --name is not used. */
+ if (!viewer) {
+ viewer =
+ config_get_int_with_default("connect/viewer",
+ 0) ? TRUE : FALSE;
+ }
+ }
+ style = config_get_string("connect/style", &default_returned);
+ if (default_returned) {
+ style = g_strdup("square");
+ }
+
+ connect_set_name(name);
+ connect_set_viewer(viewer);
+ connect_set_style(style);
+ g_free(style);
+
+ if (server && port) {
+ server_from_commandline = TRUE;
+ } else {
+ if (server || port)
+ g_warning("Only server or port set, "
+ "ignoring command line");
+ server_from_commandline = FALSE;
+ server = config_get_string("connect/server="
+ PIONEERS_DEFAULT_GAME_HOST,
+ &default_returned);
+ port = config_get_string("connect/port="
+ PIONEERS_DEFAULT_GAME_PORT,
+ &default_returned);
+ }
+ connect_set_server(server);
+ connect_set_port(port);
+
+ if (!meta_server)
+ meta_server = config_get_string("connect/meta-server="
+ PIONEERS_DEFAULT_META_SERVER,
+ &default_returned);
+ connect_set_meta_server(meta_server);
+}
Added: trunk/client/gtk/player.c
===================================================================
--- trunk/client/gtk/player.c (rev 0)
+++ trunk/client/gtk/player.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,705 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include "colors.h"
+#include "frontend.h"
+#include "log.h"
+#include "gtkbugs.h"
+#include "common_gtk.h"
+#include "player-icon.h"
+
+static void player_show_connected_at_iter(gint player_num,
+ gboolean connected,
+ GtkTreeIter * iter);
+
+static GdkColor ps_settlement = { 0, 0xbb00, 0x0000, 0x0000 };
+static GdkColor ps_city = { 0, 0xff00, 0x0000, 0x0000 };
+static GdkColor ps_city_wall = { 0, 0xff00, 0x0000, 0x0000 };
+static GdkColor ps_largest = { 0, 0x1c00, 0xb500, 0xed00 };
+static GdkColor ps_soldier = { 0, 0xe500, 0x8f00, 0x1600 };
+static GdkColor ps_resource = { 0, 0x0000, 0x0000, 0xFF00 };
+static GdkColor ps_development = { 0, 0xc600, 0xc600, 0x1300 };
+static GdkColor ps_building = { 0, 0x0b00, 0xed00, 0x8900 };
+
+typedef struct {
+ const gchar *singular;
+ const gchar *plural;
+ GdkColor *textcolor;
+} Statistic;
+
+static Statistic statistics[] = {
+ {N_("Settlement"), N_("Settlements"), &ps_settlement},
+ {N_("City"), N_("Cities"), &ps_city},
+ {N_("City Wall"), N_("City Walls"), &ps_city_wall},
+ {N_("Largest Army"), NULL, &ps_largest},
+ {N_("Longest Road"), NULL, &ps_largest},
+ {N_("Chapel"), N_("Chapels"), &ps_building},
+ {N_("Pioneer University"), N_("Pioneer Universities"),
+ &ps_building},
+ {N_("Governor's House"), N_("Governor's Houses"), &ps_building},
+ {N_("Library"), N_("Libraries"), &ps_building},
+ {N_("Market"), N_("Markets"), &ps_building},
+ {N_("Soldier"), N_("Soldiers"), &ps_soldier},
+ {N_("Resource card"), N_("Resource cards"), &ps_resource},
+ {N_("Development card"), N_("Development cards"), &ps_development}
+};
+
+enum {
+ SUMMARY_COLUMN_PLAYER_ICON, /**< Player icon */
+ SUMMARY_COLUMN_PLAYER_NUM, /**< Internal: player number */
+ SUMMARY_COLUMN_TEXT, /**< Description of the items */
+ SUMMARY_COLUMN_TEXT_COLOUR, /**< Colour of the description */
+ SUMMARY_COLUMN_SCORE, /**< Score of the items (as string) */
+ SUMMARY_COLUMN_STATISTIC, /**< enum Statistic value+1, or 0 if not in the enum */
+ SUMMARY_COLUMN_POINTS_ID, /**< Id of points, or -1 */
+ SUMMARY_COLUMN_LAST
+};
+
+static Player players[MAX_PLAYERS];
+static GtkListStore *summary_store; /**< the player summary data */
+static GtkWidget *summary_widget; /**< the player summary widget */
+static gboolean summary_color_enabled = TRUE;
+static gboolean announce_player = FALSE;
+
+/** Structure to find combination of player and statistic */
+struct Player_statistic {
+ enum TFindResult result;
+ GtkTreeIter iter;
+ gint player_num;
+ gint statistic;
+};
+
+/** Structure to find combination of player and points */
+struct Player_point {
+ enum TFindResult result;
+ GtkTreeIter iter;
+ gint player_num;
+ gint point_id;
+};
+
+static GtkWidget *turn_area; /** turn indicator in status bar */
+static const gint turn_area_icon_width = 30;
+
+void player_init(void)
+{
+ colors_init();
+ playericon_init();
+}
+
+GdkColor *player_color(gint player_num)
+{
+ return colors_get_player(player_num);
+}
+
+GdkColor *player_or_viewer_color(gint player_num)
+{
+ if (player_is_viewer(player_num)) {
+ /* viewer color is always black */
+ return &black;
+ }
+ return colors_get_player(player_num);
+}
+
+GdkPixbuf *player_create_icon(GtkWidget * widget, gint player_num,
+ gboolean connected)
+{
+ return playericon_create_icon(widget, player_get_style(player_num),
+ player_or_viewer_color(player_num),
+ player_is_viewer(player_num),
+ connected, FALSE);
+}
+
+/** Locate a line suitable for the statistic */
+static gboolean summary_locate_statistic(GtkTreeModel * model,
+ G_GNUC_UNUSED GtkTreePath * path,
+ GtkTreeIter * iter,
+ gpointer user_data)
+{
+ struct Player_statistic *ps =
+ (struct Player_statistic *) user_data;
+ gint current_player;
+ gint current_statistic;
+ gtk_tree_model_get(model, iter,
+ SUMMARY_COLUMN_PLAYER_NUM, ¤t_player,
+ SUMMARY_COLUMN_STATISTIC, ¤t_statistic,
+ -1);
+ if (current_player > ps->player_num) {
+ ps->result = FIND_MATCH_INSERT_BEFORE;
+ ps->iter = *iter;
+ return TRUE;
+ } else if (current_player == ps->player_num) {
+ if (current_statistic > ps->statistic) {
+ ps->result = FIND_MATCH_INSERT_BEFORE;
+ ps->iter = *iter;
+ return TRUE;
+ } else if (current_statistic == ps->statistic) {
+ ps->result = FIND_MATCH_EXACT;
+ ps->iter = *iter;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/** Locate a line suitable for the statistic */
+static gboolean summary_locate_point(GtkTreeModel * model,
+ G_GNUC_UNUSED GtkTreePath * path,
+ GtkTreeIter * iter,
+ gpointer user_data)
+{
+ struct Player_point *pp = (struct Player_point *) user_data;
+ gint current_player;
+ gint current_point_id;
+ gint current_statistic;
+
+ gtk_tree_model_get(model, iter,
+ SUMMARY_COLUMN_PLAYER_NUM, ¤t_player,
+ SUMMARY_COLUMN_STATISTIC, ¤t_statistic,
+ SUMMARY_COLUMN_POINTS_ID, ¤t_point_id,
+ -1);
+ if (current_player > pp->player_num) {
+ pp->result = FIND_MATCH_INSERT_BEFORE;
+ pp->iter = *iter;
+ return TRUE;
+ } else if (current_player == pp->player_num) {
+ if (current_statistic >= STAT_SOLDIERS) {
+ pp->result = FIND_MATCH_INSERT_BEFORE;
+ pp->iter = *iter;
+ return TRUE;
+ }
+ if (current_point_id > pp->point_id) {
+ pp->result = FIND_MATCH_INSERT_BEFORE;
+ pp->iter = *iter;
+ return TRUE;
+ } else if (current_point_id == pp->point_id) {
+ pp->result = FIND_MATCH_EXACT;
+ pp->iter = *iter;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/** Function to redisplay the running point total for the indicated player */
+static void refresh_victory_point_total(int player_num)
+{
+ gchar points[16];
+ GtkTreeIter iter;
+ enum TFindResult found;
+
+ if (player_num < 0 || player_num >= G_N_ELEMENTS(players))
+ return;
+
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(summary_store), &iter,
+ SUMMARY_COLUMN_PLAYER_NUM, player_num);
+
+ if (found == FIND_MATCH_EXACT) {
+ snprintf(points, sizeof(points), "%d",
+ player_get_score(player_num));
+ gtk_list_store_set(summary_store, &iter,
+ SUMMARY_COLUMN_SCORE, points, -1);
+ }
+}
+
+/** Apply colors to the summary */
+static gboolean summary_apply_colors_cb(GtkTreeModel * model,
+ G_GNUC_UNUSED GtkTreePath * path,
+ GtkTreeIter * iter,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ gint current_statistic;
+ gint point_id;
+
+ gtk_tree_model_get(model, iter,
+ SUMMARY_COLUMN_STATISTIC, ¤t_statistic,
+ SUMMARY_COLUMN_POINTS_ID, &point_id, -1);
+ if (current_statistic > 0)
+ gtk_list_store_set(summary_store, iter,
+ SUMMARY_COLUMN_TEXT_COLOUR,
+ summary_color_enabled ?
+ statistics[current_statistic -
+ 1].textcolor : &black, -1);
+ else if (point_id >= 0)
+ gtk_list_store_set(summary_store, iter,
+ SUMMARY_COLUMN_TEXT_COLOUR,
+ summary_color_enabled ?
+ &ps_largest : &black, -1);
+ return FALSE;
+}
+
+void set_color_summary(gboolean flag)
+{
+ if (flag != summary_color_enabled) {
+ summary_color_enabled = flag;
+ if (summary_store)
+ gtk_tree_model_foreach(GTK_TREE_MODEL
+ (summary_store),
+ summary_apply_colors_cb,
+ NULL);
+ }
+}
+
+gboolean get_announce_player(void)
+{
+ return announce_player;
+}
+
+void set_announce_player(gboolean announce)
+{
+ announce_player = announce;
+}
+
+void frontend_new_statistics(gint player_num, StatisticType type,
+ G_GNUC_UNUSED gint num)
+{
+ Player *player = player_get(player_num);
+ gint value;
+ gchar points[16];
+ GtkTreeIter iter;
+ struct Player_statistic ps;
+
+ value = player->statistics[type];
+ if (stat_get_vp_value(type) > 0)
+ refresh_victory_point_total(player_num);
+
+ ps.result = FIND_NO_MATCH;
+ ps.player_num = player_num;
+ ps.statistic = type + 1;
+ gtk_tree_model_foreach(GTK_TREE_MODEL(summary_store),
+ summary_locate_statistic, &ps);
+
+ if (value == 0) {
+ if (ps.result == FIND_MATCH_EXACT)
+ gtk_list_store_remove(summary_store, &ps.iter);
+ } else {
+ gchar *desc;
+ if (value == 1) {
+ if (statistics[type].plural != NULL)
+ desc = g_strdup_printf("%d %s", value,
+ gettext(statistics
+ [type].
+ singular));
+ else
+ desc = g_strdup(gettext
+ (statistics[type].
+ singular));
+ } else
+ desc = g_strdup_printf("%d %s", value,
+ gettext(statistics[type].
+ plural));
+ if (stat_get_vp_value(type) > 0)
+ sprintf(points, "%d",
+ value * stat_get_vp_value(type));
+ else
+ strcpy(points, "");
+
+ switch (ps.result) {
+ case FIND_NO_MATCH:
+ gtk_list_store_append(summary_store, &iter);
+ break;
+ case FIND_MATCH_INSERT_BEFORE:
+ gtk_list_store_insert_before(summary_store, &iter,
+ &ps.iter);
+ break;
+ case FIND_MATCH_EXACT:
+ iter = ps.iter;
+ break;
+ default:
+ g_error("unknown case in frontend_new_statistics");
+ };
+ gtk_list_store_set(summary_store, &iter,
+ SUMMARY_COLUMN_PLAYER_NUM, player_num,
+ SUMMARY_COLUMN_TEXT, desc,
+ SUMMARY_COLUMN_TEXT_COLOUR,
+ summary_color_enabled ?
+ statistics[type].textcolor : &black,
+ SUMMARY_COLUMN_STATISTIC, type + 1,
+ SUMMARY_COLUMN_POINTS_ID, -1,
+ SUMMARY_COLUMN_SCORE, points, -1);
+ g_free(desc);
+ }
+ frontend_gui_update();
+}
+
+void frontend_new_points(gint player_num, Points * points, gboolean added)
+{
+ GtkTreeIter iter;
+ struct Player_point pp;
+ gchar score[16];
+
+ refresh_victory_point_total(player_num);
+
+ pp.result = FIND_NO_MATCH;
+ pp.player_num = player_num;
+ pp.point_id = points->id;
+ gtk_tree_model_foreach(GTK_TREE_MODEL(summary_store),
+ summary_locate_point, &pp);
+
+ if (!added) {
+ if (pp.result != FIND_MATCH_EXACT)
+ g_error("cannot remove point");
+ gtk_list_store_remove(summary_store, &pp.iter);
+ frontend_gui_update();
+ return;
+ }
+
+ switch (pp.result) {
+ case FIND_NO_MATCH:
+ gtk_list_store_append(summary_store, &iter);
+ break;
+ case FIND_MATCH_INSERT_BEFORE:
+ gtk_list_store_insert_before(summary_store, &iter,
+ &pp.iter);
+ break;
+ case FIND_MATCH_EXACT:
+ iter = pp.iter;
+ break;
+ default:
+ g_error("unknown case in frontend_new_points");
+ };
+ snprintf(score, sizeof(score), "%d", points->points);
+ gtk_list_store_set(summary_store, &iter,
+ SUMMARY_COLUMN_PLAYER_NUM, player_num,
+ SUMMARY_COLUMN_TEXT, _(points->name),
+ SUMMARY_COLUMN_TEXT_COLOUR,
+ summary_color_enabled ? &ps_largest : &black,
+ SUMMARY_COLUMN_STATISTIC, 0,
+ SUMMARY_COLUMN_POINTS_ID, points->id,
+ SUMMARY_COLUMN_SCORE, score, -1);
+ frontend_gui_update();
+}
+
+static void player_create_find_player(gint player_num, GtkTreeIter * iter)
+{
+ GtkTreeIter found_iter;
+ enum TFindResult result;
+
+ /* Search for a place to add information about the player/viewer */
+ result =
+ find_integer_in_tree(GTK_TREE_MODEL(summary_store),
+ &found_iter, SUMMARY_COLUMN_PLAYER_NUM,
+ player_num);
+
+ switch (result) {
+ case FIND_NO_MATCH:
+ gtk_list_store_append(summary_store, iter);
+ gtk_list_store_set(summary_store, iter,
+ SUMMARY_COLUMN_PLAYER_NUM, player_num,
+ SUMMARY_COLUMN_POINTS_ID, -1, -1);
+ break;
+ case FIND_MATCH_INSERT_BEFORE:
+ gtk_list_store_insert_before(summary_store, iter,
+ &found_iter);
+ gtk_list_store_set(summary_store, iter,
+ SUMMARY_COLUMN_PLAYER_NUM, player_num,
+ SUMMARY_COLUMN_POINTS_ID, -1, -1);
+ break;
+ case FIND_MATCH_EXACT:
+ *iter = found_iter;
+ break;
+ default:
+ g_error("unknown case in player_create_find_player");
+ };
+}
+
+void frontend_player_name(gint player_num, const gchar * name)
+{
+ GtkTreeIter iter;
+
+ player_create_find_player(player_num, &iter);
+ gtk_list_store_set(summary_store, &iter,
+ SUMMARY_COLUMN_TEXT, name, -1);
+
+ player_show_connected_at_iter(player_num, TRUE, &iter);
+ if (announce_player && callback_mode != MODE_INIT)
+ gdk_beep();
+
+ chat_player_name(player_num, name);
+}
+
+void frontend_player_style(gint player_num,
+ G_GNUC_UNUSED const gchar * style)
+{
+ GtkTreeIter iter;
+
+ player_create_find_player(player_num, &iter);
+ player_show_connected_at_iter(player_num, TRUE, &iter);
+ chat_player_style(player_num);
+}
+
+void frontend_viewer_name(gint viewer_num, const gchar * name)
+{
+ GtkTreeIter iter;
+
+ player_create_find_player(viewer_num, &iter);
+ gtk_list_store_set(summary_store, &iter,
+ SUMMARY_COLUMN_TEXT, name, -1);
+ if (announce_player && callback_mode != MODE_INIT)
+ gdk_beep();
+
+ chat_player_name(viewer_num, name);
+}
+
+void frontend_player_quit(gint player_num)
+{
+ GtkTreeIter iter;
+
+ player_create_find_player(player_num, &iter);
+ player_show_connected_at_iter(player_num, FALSE, &iter);
+
+ chat_player_quit(player_num);
+}
+
+void frontend_viewer_quit(gint viewer_num)
+{
+ GtkTreeIter iter;
+
+ player_create_find_player(viewer_num, &iter);
+ gtk_list_store_remove(summary_store, &iter);
+
+ chat_viewer_quit(viewer_num);
+}
+
+static void player_show_connected_at_iter(gint player_num,
+ gboolean connected,
+ GtkTreeIter * iter)
+{
+ GdkPixbuf *pixbuf =
+ player_create_icon(summary_widget, player_num, connected);
+
+ gtk_list_store_set(summary_store, iter,
+ SUMMARY_COLUMN_PLAYER_ICON, pixbuf, -1);
+ g_object_unref(pixbuf);
+}
+
+/* Get the top and bottom row for player summary and make sure player
+ * is visible
+ */
+static void player_show_summary(gint player_num)
+{
+ GtkTreeIter found_iter;
+ enum TFindResult result;
+ gboolean scroll_to_end = FALSE;
+
+ result =
+ find_integer_in_tree(GTK_TREE_MODEL(summary_store),
+ &found_iter, SUMMARY_COLUMN_PLAYER_NUM,
+ player_num + 1);
+
+ if (result == FIND_NO_MATCH) {
+ scroll_to_end = TRUE;
+ } else {
+ GtkTreePath *path =
+ gtk_tree_model_get_path(GTK_TREE_MODEL(summary_store),
+ &found_iter);
+ if (gtk_tree_path_prev(path))
+ gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW
+ (summary_widget),
+ path, NULL, FALSE,
+ 0.0, 0.0);
+ gtk_tree_path_free(path);
+ }
+
+ result =
+ find_integer_in_tree(GTK_TREE_MODEL(summary_store),
+ &found_iter, SUMMARY_COLUMN_PLAYER_NUM,
+ player_num);
+ if (result != FIND_NO_MATCH) {
+ GtkTreePath *path =
+ gtk_tree_model_get_path(GTK_TREE_MODEL(summary_store),
+ &found_iter);
+ gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(summary_widget),
+ path, NULL, scroll_to_end,
+ 0.0, 0.0);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(summary_widget),
+ path, NULL, FALSE);
+ gtk_tree_path_free(path);
+ }
+}
+
+GtkWidget *player_build_summary(void)
+{
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *scroll_win;
+ GtkWidget *alignment;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 3, 3);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
+
+ label = gtk_label_new(NULL);
+ /* Caption for the overview of the points and card of other players */
+ gtk_label_set_markup(GTK_LABEL(label), _("<b>Player Summary</b>"));
+ gtk_widget_show(label);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+ gtk_container_add(GTK_CONTAINER(alignment), label);
+
+ summary_store = gtk_list_store_new(SUMMARY_COLUMN_LAST, GDK_TYPE_PIXBUF, /* player icon */
+ G_TYPE_INT, /* player number */
+ G_TYPE_STRING, /* text */
+ GDK_TYPE_COLOR, /* text colour */
+ G_TYPE_STRING, /* score */
+ G_TYPE_INT, /* statistic */
+ G_TYPE_INT); /* points */
+ summary_widget =
+ gtk_tree_view_new_with_model(GTK_TREE_MODEL(summary_store));
+
+ column = gtk_tree_view_column_new_with_attributes("",
+ gtk_cell_renderer_pixbuf_new
+ (), "pixbuf",
+ SUMMARY_COLUMN_PLAYER_ICON,
+ NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_GROW_ONLY);
+ set_pixbuf_tree_view_column_autogrow(summary_widget, column);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(summary_widget), column);
+
+ column = gtk_tree_view_column_new_with_attributes("",
+ gtk_cell_renderer_text_new
+ (), "text",
+ SUMMARY_COLUMN_TEXT,
+ "foreground-gdk",
+ SUMMARY_COLUMN_TEXT_COLOUR,
+ NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_column_set_expand(column, TRUE);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(summary_widget), column);
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes("",
+ renderer,
+ "text",
+ SUMMARY_COLUMN_SCORE,
+ "foreground-gdk",
+ SUMMARY_COLUMN_TEXT_COLOUR,
+ NULL);
+ g_object_set(renderer, "xalign", 1.0f, NULL);
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_GROW_ONLY);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(summary_widget), column);
+
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(summary_widget),
+ FALSE);
+ gtk_widget_show(summary_widget);
+
+ scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
+ (scroll_win), GTK_SHADOW_IN);
+ gtk_widget_show(scroll_win);
+ gtk_box_pack_start_defaults(GTK_BOX(vbox), scroll_win);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ gtk_container_add(GTK_CONTAINER(scroll_win), summary_widget);
+
+ return vbox;
+}
+
+static gint expose_turn_area_cb(GtkWidget * area,
+ G_GNUC_UNUSED GdkEventExpose * event,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ static GdkGC *turn_gc;
+ gint offset;
+ gint idx;
+
+ if (area->window == NULL)
+ return FALSE;
+
+ if (turn_gc == NULL)
+ turn_gc = gdk_gc_new(area->window);
+
+ offset = 0;
+ for (idx = 0; idx < num_players(); idx++) {
+ gdk_gc_set_foreground(turn_gc, player_color(idx));
+ gdk_draw_rectangle(area->window, turn_gc, TRUE,
+ offset + 2, 2,
+ turn_area_icon_width - 4,
+ area->allocation.height - 4);
+ gdk_gc_set_foreground(turn_gc, &black);
+ if (idx == current_player()) {
+ gdk_gc_set_line_attributes(turn_gc, 3,
+ GDK_LINE_SOLID,
+ GDK_CAP_BUTT,
+ GDK_JOIN_MITER);
+ gdk_draw_rectangle(area->window, turn_gc, FALSE,
+ offset + 3, 3,
+ turn_area_icon_width - 6,
+ area->allocation.height - 6);
+ } else {
+ gdk_gc_set_line_attributes(turn_gc, 1,
+ GDK_LINE_SOLID,
+ GDK_CAP_BUTT,
+ GDK_JOIN_MITER);
+ gdk_draw_rectangle(area->window, turn_gc, FALSE,
+ offset + 2, 2,
+ turn_area_icon_width - 4,
+ area->allocation.height - 4);
+ }
+
+ offset += turn_area_icon_width;
+ }
+
+ return FALSE;
+}
+
+GtkWidget *player_build_turn_area(void)
+{
+ turn_area = gtk_drawing_area_new();
+ g_signal_connect(G_OBJECT(turn_area), "expose_event",
+ G_CALLBACK(expose_turn_area_cb), NULL);
+ gtk_widget_set_size_request(turn_area,
+ turn_area_icon_width * num_players(),
+ -1);
+ gtk_widget_show(turn_area);
+
+ return turn_area;
+}
+
+void set_num_players(gint num)
+{
+ gtk_widget_set_size_request(turn_area, turn_area_icon_width * num,
+ -1);
+}
+
+void player_show_current(gint player_num)
+{
+ gtk_widget_queue_draw(turn_area);
+ player_show_summary(player_num);
+}
+
+void player_clear_summary(void)
+{
+ gtk_list_store_clear(GTK_LIST_STORE(summary_store));
+}
Added: trunk/client/gtk/plenty.c
===================================================================
--- trunk/client/gtk/plenty.c (rev 0)
+++ trunk/client/gtk/plenty.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,135 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "resource-table.h"
+
+static struct {
+ GtkWidget *dlg;
+ GtkWidget *resource_widget;
+ gint bank[NO_RESOURCE];
+} plenty;
+
+static void amount_changed_cb(G_GNUC_UNUSED ResourceTable * rt,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ frontend_gui_update();
+}
+
+void plenty_resources(gint * resources)
+{
+ resource_table_get_amount(RESOURCETABLE(plenty.resource_widget),
+ resources);
+}
+
+static void plenty_destroyed(G_GNUC_UNUSED GtkWidget * widget,
+ G_GNUC_UNUSED gpointer data)
+{
+ if (callback_mode == MODE_PLENTY)
+ plenty_create_dlg(NULL);
+}
+
+void plenty_create_dlg(const gint * bank)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *vbox;
+ const char *str;
+ gint r;
+ gint total;
+
+ plenty.dlg = gtk_dialog_new_with_buttons(_("Year of Plenty"),
+ GTK_WINDOW(app_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK, NULL);
+ g_signal_connect(GTK_OBJECT(plenty.dlg), "destroy",
+ GTK_SIGNAL_FUNC(gtk_widget_destroyed),
+ &plenty.dlg);
+ gtk_widget_realize(plenty.dlg);
+ /* Disable close */
+ gdk_window_set_functions(plenty.dlg->window,
+ GDK_FUNC_ALL | GDK_FUNC_CLOSE);
+
+ dlg_vbox = GTK_DIALOG(plenty.dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+
+ total = 0;
+ if (bank != NULL)
+ for (r = 0; r < NO_RESOURCE; ++r) {
+ plenty.bank[r] = bank[r];
+ total += bank[r];
+ }
+ if (total == 1)
+ str = _("Please choose one resource from the bank");
+ else if (total >= 2) {
+ total = 2;
+ str = _("Please choose two resources from the bank");
+ } else
+ str = _("The bank is empty");
+ plenty.resource_widget =
+ resource_table_new(str, RESOURCE_TABLE_MORE_IN_HAND, TRUE,
+ TRUE);
+ resource_table_set_total(RESOURCETABLE(plenty.resource_widget),
+ /* Text for total in year of plenty dialog */
+ _("Total resources"), total);
+ resource_table_limit_bank(RESOURCETABLE(plenty.resource_widget),
+ TRUE);
+ resource_table_set_bank(RESOURCETABLE(plenty.resource_widget),
+ plenty.bank);
+
+ gtk_widget_show(plenty.resource_widget);
+ gtk_box_pack_start(GTK_BOX(vbox), plenty.resource_widget, FALSE,
+ TRUE, 0);
+ g_signal_connect(G_OBJECT(plenty.resource_widget), "change",
+ G_CALLBACK(amount_changed_cb), NULL);
+
+ frontend_gui_register(gui_get_dialog_button
+ (GTK_DIALOG(plenty.dlg), 0), GUI_PLENTY,
+ "clicked");
+ /* This _must_ be after frontend_gui_register, otherwise the
+ * regeneration of the button happens before the destruction, which
+ * results in an incorrectly sensitive OK button. */
+ g_signal_connect(gui_get_dialog_button(GTK_DIALOG(plenty.dlg), 0),
+ "destroy", G_CALLBACK(plenty_destroyed), NULL);
+ gtk_widget_show(plenty.dlg);
+ frontend_gui_update();
+}
+
+void plenty_destroy_dlg(void)
+{
+ if (plenty.dlg == NULL)
+ return;
+ gtk_widget_destroy(plenty.dlg);
+ plenty.dlg = NULL;
+}
+
+gboolean plenty_can_activate(void)
+{
+ return
+ resource_table_is_total_reached(RESOURCETABLE
+ (plenty.resource_widget));
+}
Added: trunk/client/gtk/quote-view.c
===================================================================
--- trunk/client/gtk/quote-view.c (rev 0)
+++ trunk/client/gtk/quote-view.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,768 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2004-2006 Roland Clobus <rclobus at bigfoot.com>
+ * Copyright (C) 2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "quote-view.h"
+#include "map.h" /* For NO_RESOURCE */
+#include "game.h"
+#include "quoteinfo.h"
+#include <gtk/gtk.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include "colors.h"
+#include "frontend.h"
+#include "theme.h"
+#include "common_gtk.h"
+
+enum {
+ TRADE_COLUMN_PLAYER, /**< Player icon */
+ TRADE_COLUMN_POSSIBLE, /**< Good/bad trade icon */
+ TRADE_COLUMN_DESCRIPTION, /**< Trade description */
+ TRADE_COLUMN_QUOTE, /**< Internal data: contains the quotes. Not for display */
+ TRADE_COLUMN_REJECT, /**< Internal data: contains the rejected players. Not for display */
+ TRADE_COLUMN_PLAYER_NUM, /**< The player number, or -1 for maritime trade */
+ TRADE_COLUMN_LAST
+};
+
+/** The quote is found here */
+static GtkTreeIter quote_found_iter;
+/** Has the quote been found ? */
+static gboolean quote_found_flag;
+
+/** Icon for rejected trade */
+static GdkPixbuf *cross_pixbuf;
+/** Icon for the maritime trade */
+static GdkPixbuf *maritime_pixbuf;
+
+/* The signals */
+enum {
+ SELECTION_CHANGED,
+ SELECTION_ACTIVATED,
+ LAST_SIGNAL
+};
+
+static void quote_view_class_init(QuoteViewClass * klass);
+static void quote_view_init(QuoteView * qv);
+
+static gint quote_click_cb(GtkWidget * widget,
+ GdkEventButton * event, gpointer user_data);
+static void quote_select_cb(GtkTreeSelection * selection,
+ gpointer user_data);
+static void load_pixmaps(QuoteView * qv);
+static void set_selected_quote(QuoteView * qv, const QuoteInfo * quote);
+static gboolean trade_locate_quote(GtkTreeModel * model,
+ G_GNUC_UNUSED GtkTreePath * path,
+ GtkTreeIter * iter, gpointer user_data);
+
+/* All signals */
+static guint quote_view_signals[LAST_SIGNAL] = { 0, 0 };
+
+/* Register the class */
+GType quote_view_get_type(void)
+{
+ static GType rt_type = 0;
+
+ if (!rt_type) {
+ static const GTypeInfo rt_info = {
+ sizeof(QuoteViewClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) quote_view_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(QuoteView),
+ 0,
+ (GInstanceInitFunc) quote_view_init,
+ NULL
+ };
+ rt_type =
+ g_type_register_static(GTK_TYPE_SCROLLED_WINDOW,
+ "QuoteView", &rt_info, 0);
+ }
+ return rt_type;
+}
+
+/* Register the signals.
+ * QuoteView will emit these signals:
+ * 'selection-changed' when the selection changes.
+ * 'selection-activated' when the selection is double-clicked
+ */
+static void quote_view_class_init(QuoteViewClass * klass)
+{
+ quote_view_signals[SELECTION_CHANGED] =
+ g_signal_new("selection-changed",
+ G_TYPE_FROM_CLASS
+ (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET
+ (QuoteViewClass,
+ selection_changed), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+ quote_view_signals[SELECTION_ACTIVATED] =
+ g_signal_new("selection-activated",
+ G_TYPE_FROM_CLASS
+ (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET
+ (QuoteViewClass,
+ selection_activated), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+}
+
+/* Initialise the composite widget */
+static void quote_view_init(QuoteView * qv)
+{
+ GtkTreeViewColumn *column;
+
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW
+ (qv), GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(qv),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_hadjustment(GTK_SCROLLED_WINDOW(qv), NULL);
+ gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(qv), NULL);
+
+ /* Create model */
+ qv->store = gtk_list_store_new(TRADE_COLUMN_LAST,
+ GDK_TYPE_PIXBUF,
+ GDK_TYPE_PIXBUF,
+ G_TYPE_STRING,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER, G_TYPE_INT);
+
+ /* Create graphical representation of the model */
+ qv->quotes =
+ gtk_tree_view_new_with_model(GTK_TREE_MODEL(qv->store));
+ gtk_container_add(GTK_CONTAINER(qv), qv->quotes);
+
+ /* Register double-click */
+ g_signal_connect(G_OBJECT(qv->quotes), "button_press_event",
+ G_CALLBACK(quote_click_cb), qv);
+
+ g_signal_connect(G_OBJECT
+ (gtk_tree_view_get_selection
+ (GTK_TREE_VIEW(qv->quotes))), "changed",
+ G_CALLBACK(quote_select_cb), qv);
+
+ /* Now create columns */
+
+ /* Table header: Player who trades */
+ column = gtk_tree_view_column_new_with_attributes(_("Player"),
+ gtk_cell_renderer_pixbuf_new
+ (), "pixbuf",
+ TRADE_COLUMN_PLAYER,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(qv->quotes), column);
+
+ column = gtk_tree_view_column_new_with_attributes("",
+ gtk_cell_renderer_pixbuf_new
+ (), "pixbuf",
+ TRADE_COLUMN_POSSIBLE,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(qv->quotes), column);
+
+ /* Table header: Quote */
+ column = gtk_tree_view_column_new_with_attributes(_("Quotes"),
+ gtk_cell_renderer_text_new
+ (), "text",
+ TRADE_COLUMN_DESCRIPTION,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(qv->quotes), column);
+ gtk_widget_show(qv->quotes);
+
+ load_pixmaps(qv);
+
+ qv->with_maritime = FALSE;
+ qv->quote_list = NULL;
+}
+
+/* Create a new QuoteView */
+GtkWidget *quote_view_new(gboolean with_maritime,
+ CheckQuoteFunc check_quote_func,
+ const gchar * true_pixbuf_id,
+ const gchar * false_pixbuf_id)
+{
+ QuoteView *qv;
+
+ qv = g_object_new(quote_view_get_type(), NULL);
+ qv->with_maritime = with_maritime;
+ qv->check_quote_func = check_quote_func;
+
+ if (true_pixbuf_id)
+ qv->true_pixbuf =
+ gtk_widget_render_icon(qv->quotes, true_pixbuf_id,
+ GTK_ICON_SIZE_MENU, NULL);
+ else
+ qv->true_pixbuf = NULL;
+
+ if (false_pixbuf_id)
+ qv->false_pixbuf =
+ gtk_widget_render_icon(qv->quotes, false_pixbuf_id,
+ GTK_ICON_SIZE_MENU, NULL);
+ else
+ qv->false_pixbuf = NULL;
+
+ return GTK_WIDGET(qv);
+}
+
+static gint quote_click_cb(G_GNUC_UNUSED GtkWidget * widget,
+ GdkEventButton * event, gpointer quoteview)
+{
+ if (event->type == GDK_2BUTTON_PRESS) {
+ g_signal_emit(G_OBJECT(quoteview),
+ quote_view_signals[SELECTION_ACTIVATED], 0);
+ };
+ return FALSE;
+}
+
+static void quote_select_cb(GtkTreeSelection * selection,
+ gpointer quoteview)
+{
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ QuoteInfo *quote;
+
+ g_assert(selection != NULL);
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ gtk_tree_model_get(model, &iter, TRADE_COLUMN_QUOTE,
+ "e, -1);
+ else
+ quote = NULL;
+ set_selected_quote(QUOTEVIEW(quoteview), quote);
+}
+
+/** Load/construct the images */
+static void load_pixmaps(QuoteView * qv)
+{
+ static gboolean init = FALSE;
+ int width, height;
+ GdkPixmap *pixmap;
+ GdkGC *gc;
+
+ if (init)
+ return;
+
+ gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
+ pixmap =
+ gdk_pixmap_new(qv->quotes->window, width, height,
+ gtk_widget_get_visual(qv->quotes)->depth);
+
+ gc = gdk_gc_new(pixmap);
+ gdk_gc_set_fill(gc, GDK_TILED);
+ gdk_gc_set_tile(gc, guimap_terrain(SEA_TERRAIN));
+ gdk_gc_set_foreground(gc, &black);
+ gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, width, height);
+ maritime_pixbuf =
+ gdk_pixbuf_get_from_drawable(NULL, pixmap, NULL, 0, 0, 0, 0,
+ -1, -1);
+ g_object_unref(pixmap);
+ g_object_unref(gc);
+
+ cross_pixbuf =
+ gtk_widget_render_icon(qv->quotes, GTK_STOCK_CANCEL,
+ GTK_ICON_SIZE_MENU, NULL);
+
+ init = TRUE;
+}
+
+static void trade_format_maritime(const QuoteInfo * quote, gchar * desc)
+{
+ /* trade: maritime quote: %1 resources of type %2 for
+ * one resource of type %3 */
+ sprintf(desc, _("%d:1 %s for %s"),
+ quote->var.m.ratio,
+ resource_name(quote->var.m.supply, FALSE),
+ resource_name(quote->var.m.receive, FALSE));
+}
+
+/** Add a maritime trade */
+static void add_maritime_trade(QuoteView * qv, G_GNUC_UNUSED gint ratio,
+ G_GNUC_UNUSED Resource receive,
+ G_GNUC_UNUSED Resource supply)
+{
+ QuoteInfo *quote;
+ QuoteInfo *prev;
+ gchar quote_desc[128];
+ GtkTreeIter iter;
+
+ for (quote = quotelist_first(qv->quote_list);
+ quote != NULL; quote = quotelist_next(quote))
+ if (quote->is_domestic)
+ break;
+ else if (quote->var.m.ratio == ratio
+ && quote->var.m.supply == supply
+ && quote->var.m.receive == receive)
+ return;
+
+ quote =
+ quotelist_add_maritime(qv->quote_list, ratio, supply, receive);
+
+ trade_format_maritime(quote, quote_desc);
+ prev = quotelist_prev(quote);
+
+ quote_found_flag = FALSE;
+ if (prev != NULL)
+ gtk_tree_model_foreach(GTK_TREE_MODEL(qv->store),
+ trade_locate_quote, prev);
+ if (quote_found_flag)
+ gtk_list_store_insert_after(qv->store, &iter,
+ "e_found_iter);
+ else
+ gtk_list_store_prepend(qv->store, &iter);
+ gtk_list_store_set(qv->store, &iter, TRADE_COLUMN_PLAYER, maritime_pixbuf, TRADE_COLUMN_POSSIBLE, NULL, TRADE_COLUMN_DESCRIPTION, quote_desc, TRADE_COLUMN_QUOTE, quote, TRADE_COLUMN_PLAYER_NUM, -1, /*
+ Maritime trade */
+ -1);
+}
+
+/** Locate the QuoteInfo* in user_data. Return TRUE if is found. The iter
+ * is set in quote_found_iter. The flag quote_found_flag is set to TRUE
+ */
+static gboolean trade_locate_quote(GtkTreeModel * model,
+ G_GNUC_UNUSED GtkTreePath * path,
+ GtkTreeIter * iter, gpointer user_data)
+{
+ QuoteInfo *wanted = user_data;
+ QuoteInfo *current;
+ gtk_tree_model_get(model, iter, TRADE_COLUMN_QUOTE, ¤t, -1);
+ if (current == wanted) {
+ quote_found_iter = *iter;
+ quote_found_flag = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/** Remove a quote from the list */
+static void remove_quote(QuoteView * qv, QuoteInfo * quote)
+{
+ if (quote == qv->selected_quote)
+ set_selected_quote(qv, NULL);
+
+ quote_found_flag = FALSE;
+ gtk_tree_model_foreach(GTK_TREE_MODEL(qv->store),
+ trade_locate_quote, quote);
+ if (quote_found_flag)
+ gtk_list_store_remove(qv->store, "e_found_iter);
+ quotelist_delete(qv->quote_list, quote);
+}
+
+/** Locate the Player* in user_data. Return TRUE if is found. The iter
+ * is set in quote_found_iter. The flag quote_found_flag is set to TRUE
+ */
+static gboolean trade_locate_reject(GtkTreeModel * model,
+ G_GNUC_UNUSED GtkTreePath * path,
+ GtkTreeIter * iter, gpointer user_data)
+{
+ Player *wanted = user_data;
+ Player *current;
+ gtk_tree_model_get(model, iter, TRADE_COLUMN_REJECT, ¤t, -1);
+ if (current == wanted) {
+ quote_found_iter = *iter;
+ quote_found_flag = TRUE;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/** Player <I>player_num</I> has rejected trade */
+void quote_view_reject(QuoteView * qv, gint player_num)
+{
+ Player *player = player_get(player_num);
+ QuoteInfo *quote;
+ GtkTreeIter iter;
+ enum TFindResult found;
+ GdkPixbuf *pixbuf;
+
+ if (qv->quote_list == NULL)
+ return;
+
+ while ((quote =
+ quotelist_find_domestic(qv->quote_list, player_num,
+ -1)) != NULL) {
+ remove_quote(qv, quote);
+ }
+
+ quote_found_flag = FALSE;
+ gtk_tree_model_foreach(GTK_TREE_MODEL(qv->store),
+ trade_locate_reject, player);
+ if (quote_found_flag) /* Already removed */
+ return;
+
+ /* work out where to put the reject row
+ */
+ for (quote = quotelist_first(qv->quote_list);
+ quote != NULL; quote = quotelist_next(quote))
+ if (!quote->is_domestic)
+ continue;
+ else if (quote->var.d.player_num >= player_num)
+ break;
+
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(qv->store), &iter,
+ TRADE_COLUMN_PLAYER_NUM, player_num);
+ if (found != FIND_NO_MATCH)
+ gtk_list_store_insert_before(qv->store, &iter, &iter);
+ else
+ gtk_list_store_append(qv->store, &iter);
+ pixbuf = player_create_icon(GTK_WIDGET(qv), player_num, TRUE);
+ gtk_list_store_set(qv->store, &iter, TRADE_COLUMN_PLAYER, pixbuf,
+ TRADE_COLUMN_POSSIBLE, cross_pixbuf,
+ /* Trade: a player has rejected trade */
+ TRADE_COLUMN_DESCRIPTION, _("Rejected trade"),
+ TRADE_COLUMN_QUOTE, NULL,
+ TRADE_COLUMN_REJECT, player,
+ TRADE_COLUMN_PLAYER_NUM, player_num, -1);
+ g_object_unref(pixbuf);
+}
+
+/** How many of this resource do we need for a maritime trade? If the trade is
+ * not possible, return 0.
+ */
+static gint maritime_amount(QuoteView * qv, gint resource)
+{
+ if (qv->maritime_info.specific_resource[resource]) {
+ if (resource_asset(resource) >= 2)
+ return 2;
+ } else if (qv->maritime_info.any_resource) {
+ if (resource_asset(resource) >= 3)
+ return 3;
+ } else if (resource_asset(resource) >= 4)
+ return 4;
+ return 0;
+}
+
+/** Check if all existing maritime trades are valid.
+ * Add and remove maritime trades as needed
+ */
+static void check_maritime_trades(QuoteView * qv)
+{
+ QuoteInfo *quote;
+ gint idx;
+ gboolean check_supply = FALSE;
+ gint maritime_supply[NO_RESOURCE];
+
+ if (!qv->with_maritime)
+ return;
+
+ /* Check supply whenever any supply box is selected. */
+ for (idx = 0; idx < NO_RESOURCE; ++idx) {
+ if (qv->maritime_filter_supply[idx])
+ check_supply = TRUE;
+ }
+
+ /* Check how many of which resources can be used for maritime supply.
+ */
+ for (idx = 0; idx < NO_RESOURCE; ++idx) {
+ if (check_supply && !qv->maritime_filter_supply[idx])
+ maritime_supply[idx] = 0;
+ else
+ maritime_supply[idx] = maritime_amount(qv, idx);
+ }
+
+ /* Remove invalid quotes. */
+ quote = quotelist_first(qv->quote_list);
+ while (quote != NULL) {
+ QuoteInfo *curr = quote;
+
+ quote = quotelist_next(quote);
+ if (curr->is_domestic)
+ break;
+
+ /* Is the current quote valid? */
+ if (qv->maritime_filter_receive[curr->var.m.receive] == 0
+ || maritime_supply[curr->var.m.supply] == 0)
+ remove_quote(qv, curr);
+ }
+
+ /* Add all of the maritime trades that can be performed
+ */
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ gint supply_idx;
+
+ if (!qv->maritime_filter_receive[idx])
+ continue;
+
+ for (supply_idx = 0; supply_idx < NO_RESOURCE;
+ supply_idx++) {
+ if (supply_idx == idx)
+ continue;
+
+ if (!maritime_supply[supply_idx])
+ continue;
+
+ if (resource_asset(supply_idx)
+ >= maritime_supply[supply_idx])
+ add_maritime_trade(qv,
+ maritime_supply
+ [supply_idx], idx,
+ supply_idx);
+ }
+ }
+}
+
+/** Check if the quote still is valid. Update the icon.
+ */
+static gboolean check_valid_trade(GtkTreeModel * model,
+ G_GNUC_UNUSED GtkTreePath * path,
+ GtkTreeIter * iter, gpointer user_data)
+{
+ QuoteView *quoteview = QUOTEVIEW(user_data);
+ QuoteInfo *quote;
+ gtk_tree_model_get(model, iter, TRADE_COLUMN_QUOTE, "e, -1);
+ if (quote != NULL)
+ if (quote->is_domestic) {
+ gtk_list_store_set(quoteview->store, iter,
+ TRADE_COLUMN_POSSIBLE,
+ quoteview->
+ check_quote_func(quote) ?
+ quoteview->true_pixbuf :
+ quoteview->false_pixbuf, -1);
+ }
+ return FALSE;
+}
+
+/** Add a quote from a player */
+void quote_view_add_quote(QuoteView * qv, gint player_num,
+ gint quote_num, const gint * supply,
+ const gint * receive)
+{
+ GtkTreeIter iter;
+ enum TFindResult found;
+ QuoteInfo *quote;
+ gchar quote_desc[128];
+ GdkPixbuf *pixbuf;
+
+ if (qv->quote_list == NULL)
+ quotelist_new(&qv->quote_list);
+
+ /* If the trade is already listed, don't duplicate */
+ if (quotelist_find_domestic(qv->quote_list, player_num, quote_num)
+ != NULL)
+ return;
+
+ quote = quotelist_add_domestic(qv->quote_list,
+ player_num, quote_num, supply,
+ receive);
+ trade_format_quote(quote, quote_desc);
+
+ found =
+ find_integer_in_tree(GTK_TREE_MODEL(qv->store), &iter,
+ TRADE_COLUMN_PLAYER_NUM, player_num + 1);
+
+ if (found != FIND_NO_MATCH)
+ gtk_list_store_insert_before(qv->store, &iter, &iter);
+ else
+ gtk_list_store_append(qv->store, &iter);
+ pixbuf = player_create_icon(GTK_WIDGET(qv), player_num, TRUE);
+ gtk_list_store_set(qv->store, &iter, TRADE_COLUMN_PLAYER, pixbuf,
+ TRADE_COLUMN_POSSIBLE,
+ qv->check_quote_func(quote) ? qv->
+ true_pixbuf : qv->false_pixbuf,
+ TRADE_COLUMN_DESCRIPTION, quote_desc,
+ TRADE_COLUMN_QUOTE, quote,
+ TRADE_COLUMN_PLAYER_NUM, player_num, -1);
+ g_object_unref(pixbuf);
+}
+
+void quote_view_remove_quote(QuoteView * qv, gint partner_num,
+ gint quote_num)
+{
+ QuoteInfo *quote;
+
+ if (qv->quote_list == NULL)
+ return;
+
+ g_assert(qv->quote_list != NULL);
+ quote =
+ quotelist_find_domestic(qv->quote_list, partner_num,
+ quote_num);
+
+ if (quote == NULL)
+ return;
+ g_assert(quote != NULL);
+ remove_quote(qv, quote);
+}
+
+void quote_view_begin(QuoteView * qv)
+{
+ quotelist_new(&qv->quote_list);
+ if (qv->with_maritime) {
+ map_maritime_info(get_map(), &qv->maritime_info,
+ my_player_num());
+ }
+
+ gtk_list_store_clear(qv->store);
+}
+
+void quote_view_finish(QuoteView * qv)
+{
+ if (qv->quote_list != NULL)
+ quotelist_free(&qv->quote_list);
+}
+
+void quote_view_check_validity_of_trades(QuoteView * qv)
+{
+ check_maritime_trades(qv);
+
+ /* Check if all quotes are still valid */
+ gtk_tree_model_foreach(GTK_TREE_MODEL(qv->store),
+ check_valid_trade, qv);
+}
+
+/** Activate a new quote.
+ * If the quote == NULL, clear the selection in the listview too */
+static void set_selected_quote(QuoteView * qv, const QuoteInfo * quote)
+{
+ if (qv->selected_quote == quote)
+ return; /* Don't do the same thing again */
+
+ qv->selected_quote = quote;
+ if (quote == NULL)
+ gtk_tree_selection_unselect_all(gtk_tree_view_get_selection
+ (GTK_TREE_VIEW
+ (qv->quotes)));
+
+ g_signal_emit(G_OBJECT(qv), quote_view_signals[SELECTION_CHANGED],
+ 0);
+}
+
+void quote_view_clear_selected_quote(QuoteView * qv)
+{
+ set_selected_quote(qv, NULL);
+}
+
+const QuoteInfo *quote_view_get_selected_quote(QuoteView * qv)
+{
+ return qv->selected_quote;
+}
+
+void quote_view_remove_rejected_quotes(QuoteView * qv)
+{
+ gint idx;
+
+ for (idx = 0; idx < num_players(); idx++) {
+ Player *player = player_get(idx);
+ quote_found_flag = FALSE;
+ gtk_tree_model_foreach(GTK_TREE_MODEL(qv->store),
+ trade_locate_reject, player);
+ if (quote_found_flag)
+ gtk_list_store_remove(qv->store,
+ "e_found_iter);
+ }
+}
+
+void quote_view_set_maritime_filters(QuoteView * qv,
+ const gboolean * filter_supply,
+ const gboolean * filter_receive)
+{
+ gint idx;
+
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ qv->maritime_filter_supply[idx] = filter_supply[idx];
+ qv->maritime_filter_receive[idx] = filter_receive[idx];
+ }
+ check_maritime_trades(qv);
+}
+
+void quote_view_theme_changed(QuoteView * qv)
+{
+ int width, height;
+ GdkPixmap *pixmap;
+ GdkGC *gc;
+ QuoteInfo *quote;
+
+ if (!qv->with_maritime)
+ return;
+
+ gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
+
+ pixmap =
+ gdk_pixmap_new(qv->quotes->window, width, height,
+ gtk_widget_get_visual(qv->quotes)->depth);
+
+ gc = gdk_gc_new(pixmap);
+ gdk_gc_set_foreground(gc, &black);
+ gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, width, height);
+ gdk_gc_set_fill(gc, GDK_TILED);
+ gdk_gc_set_tile(gc, guimap_terrain(SEA_TERRAIN));
+ gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, width, height);
+ if (maritime_pixbuf)
+ g_object_unref(maritime_pixbuf);
+ maritime_pixbuf =
+ gdk_pixbuf_get_from_drawable(NULL, pixmap, NULL, 0, 0, 0, 0,
+ -1, -1);
+ g_object_unref(gc);
+ g_object_unref(pixmap);
+
+ /* Remove all maritime quotes */
+ quote = quotelist_first(qv->quote_list);
+ while (quote != NULL) {
+ QuoteInfo *curr = quote;
+ quote = quotelist_next(quote);
+ if (curr->is_domestic)
+ break;
+ remove_quote(qv, curr);
+ }
+
+ /* Add all of the maritime trades that can be performed */
+ check_maritime_trades(qv);
+}
+
+gboolean quote_view_trade_exists(QuoteView * qv, const gint * supply,
+ const gint * receive)
+{
+ const QuoteInfo *quote;
+ gboolean match;
+ gint idx;
+
+ /* Find the quote which equals the parameters
+ */
+ for (quote = quotelist_first(qv->quote_list);
+ quote != NULL; quote = quotelist_next(quote)) {
+ if (quote->var.d.player_num != my_player_num())
+ continue;
+ /* Does this quote equal the parameters?
+ */
+ match = TRUE;
+ for (idx = 0; idx < NO_RESOURCE && match; idx++)
+ if (quote->var.d.supply[idx] != supply[idx]
+ || quote->var.d.receive[idx] != receive[idx])
+ match = FALSE;
+ if (match)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean quote_view_has_reject(QuoteView * qv, gint player_num)
+{
+ Player *player = player_get(player_num);
+
+ if (qv->quote_list == NULL)
+ return FALSE;
+
+ quote_found_flag = FALSE;
+ gtk_tree_model_foreach(GTK_TREE_MODEL(qv->store),
+ trade_locate_reject, player);
+ return quote_found_flag;
+}
Added: trunk/client/gtk/quote-view.h
===================================================================
--- trunk/client/gtk/quote-view.h (rev 0)
+++ trunk/client/gtk/quote-view.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,106 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+ * Copyright (C) 2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __quoteview_h
+#define __quoteview_h
+
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkliststore.h>
+#include "map.h" /* For NO_RESOURCE */
+#include "quoteinfo.h"
+
+G_BEGIN_DECLS
+#define QUOTEVIEW_TYPE (quote_view_get_type ())
+#define QUOTEVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), QUOTEVIEW_TYPE, QuoteView))
+#define QUOTEVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), QUOTEVIEW_TYPE, QuoteViewClass))
+#define IS_QUOTEVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QUOTEVIEW_TYPE))
+#define IS_QUOTEVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), QUOTEVIEW_TYPE))
+typedef struct _QuoteView QuoteView;
+typedef struct _QuoteViewClass QuoteViewClass;
+
+typedef gboolean(*CheckQuoteFunc) (const QuoteInfo * quote);
+
+struct _QuoteView {
+ GtkScrolledWindow scrolled_window;
+
+ /** The data */
+ GtkListStore *store;
+
+ /** The tree view widget */
+ GtkWidget *quotes;
+
+ /** All quotes */
+ QuoteList *quote_list;
+
+ /** Show maritime quotes? */
+ gboolean with_maritime;
+
+ /** Information about available maritime trades */
+ MaritimeInfo maritime_info;
+
+ gboolean maritime_filter_supply[NO_RESOURCE];
+ gboolean maritime_filter_receive[NO_RESOURCE];
+
+ CheckQuoteFunc check_quote_func;
+
+ /** The currently selected quote, or NULL */
+ const QuoteInfo *selected_quote;
+
+ /** CheckQuoteFunc returns true */
+ GdkPixbuf *true_pixbuf;
+
+ /** CheckQuoteFunc returns false */
+ GdkPixbuf *false_pixbuf;
+};
+
+struct _QuoteViewClass {
+ GtkScrolledWindowClass parent_class;
+
+ void (*selection_changed) (QuoteView * qv);
+ void (*selection_activated) (QuoteView * qv);
+};
+
+GType quote_view_get_type(void);
+GtkWidget *quote_view_new(gboolean with_maritime,
+ CheckQuoteFunc check_quote_func,
+ const gchar * true_pixbuf_id,
+ const gchar * false_pixbuf_id);
+void quote_view_begin(QuoteView * qv);
+void quote_view_add_quote(QuoteView * qv, gint player_num,
+ gint quote_num, const gint * supply,
+ const gint * receive);
+void quote_view_remove_quote(QuoteView * qv, gint partner_num,
+ gint quote_num);
+void quote_view_reject(QuoteView * qv, gint player_num);
+void quote_view_finish(QuoteView * qv);
+void quote_view_check_validity_of_trades(QuoteView * qv);
+void quote_view_clear_selected_quote(QuoteView * qv);
+const QuoteInfo *quote_view_get_selected_quote(QuoteView * qv);
+void quote_view_remove_rejected_quotes(QuoteView * qv);
+void quote_view_set_maritime_filters(QuoteView * qv,
+ const gboolean * filter_supply,
+ const gboolean * filter_receive);
+void quote_view_theme_changed(QuoteView * qv);
+gboolean quote_view_trade_exists(QuoteView * qv, const gint * supply,
+ const gint * receive);
+gboolean quote_view_has_reject(QuoteView * qv, gint player_num);
+G_END_DECLS
+#endif
Added: trunk/client/gtk/quote.c
===================================================================
--- trunk/client/gtk/quote.c (rev 0)
+++ trunk/client/gtk/quote.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,353 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "quoteinfo.h"
+#include "resource-table.h"
+#include "quote-view.h"
+
+static gint trade_player;
+
+static GtkWidget *player_icon;
+static GtkWidget *desc_lbl;
+static GtkWidget *submit_btn;
+static GtkWidget *delete_btn;
+static GtkWidget *reject_btn;
+static GtkWidget *quoteview;
+
+static GtkWidget *want_table;
+static GtkWidget *give_table;
+
+static gint next_quote_num;
+
+static gint we_supply[NO_RESOURCE];
+static gint we_receive[NO_RESOURCE];
+
+static gboolean can_delete_this_quote(const QuoteInfo * quote)
+{
+ g_assert(quote->is_domestic);
+ return quote->var.d.player_num == my_player_num();;
+}
+
+gboolean can_submit_quote(void)
+{
+ gint want_quote[NO_RESOURCE];
+ gint give_quote[NO_RESOURCE];
+
+ resource_table_get_amount(RESOURCETABLE(want_table), want_quote);
+ resource_table_get_amount(RESOURCETABLE(give_table), give_quote);
+
+ if (resource_count(want_quote) == 0
+ && resource_count(give_quote) == 0)
+ return FALSE;
+
+ return !quote_view_trade_exists(QUOTEVIEW(quoteview), give_quote,
+ want_quote)
+ && !player_is_viewer(my_player_num());
+}
+
+gboolean can_delete_quote(void)
+{
+ const QuoteInfo *selected_quote = quote_current_quote();
+ return selected_quote != NULL
+ && can_delete_this_quote(selected_quote);
+}
+
+gboolean can_reject_quote(void)
+{
+ return !player_is_viewer(my_player_num()) &&
+ !quote_view_has_reject(QUOTEVIEW(quoteview), my_player_num());
+}
+
+const QuoteInfo *quote_current_quote(void)
+{
+ return quote_view_get_selected_quote(QUOTEVIEW(quoteview));
+}
+
+const gint *quote_we_supply(void)
+{
+ static gint we_supply[NO_RESOURCE];
+
+ resource_table_get_amount(RESOURCETABLE(give_table), we_supply);
+ return we_supply;
+}
+
+const gint *quote_we_receive(void)
+{
+ static gint we_receive[NO_RESOURCE];
+
+ resource_table_get_amount(RESOURCETABLE(want_table), we_receive);
+ return we_receive;
+}
+
+gint quote_next_num(void)
+{
+ return next_quote_num;
+}
+
+static void quote_update(void)
+{
+ resource_table_update_hand(RESOURCETABLE(want_table));
+ resource_table_update_hand(RESOURCETABLE(give_table));
+}
+
+static void lock_resource_tables(void)
+{
+ gint idx;
+ gint filter[NO_RESOURCE];
+
+ /* Lock the UI */
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ filter[idx] = 0;
+ resource_table_set_filter(RESOURCETABLE(want_table), filter);
+ resource_table_set_filter(RESOURCETABLE(give_table), filter);
+ resource_table_clear(RESOURCETABLE(want_table));
+ resource_table_clear(RESOURCETABLE(give_table));
+}
+
+static void set_resource_tables_filter(const gint * we_receive, const gint
+ * we_supply)
+{
+ if (player_is_viewer(my_player_num())) {
+ lock_resource_tables();
+ } else {
+ resource_table_set_filter(RESOURCETABLE(want_table),
+ we_receive);
+ resource_table_set_filter(RESOURCETABLE(give_table),
+ we_supply);
+ resource_table_clear(RESOURCETABLE(want_table));
+ resource_table_clear(RESOURCETABLE(give_table));
+ }
+}
+
+void quote_add_quote(gint player_num,
+ gint quote_num, const gint * we_supply,
+ const gint * we_receive)
+{
+ quote_view_add_quote(QUOTEVIEW(quoteview), player_num, quote_num,
+ we_supply, we_receive);
+ next_quote_num++;
+}
+
+void quote_delete_quote(gint player_num, gint quote_num)
+{
+ quote_view_remove_quote(QUOTEVIEW(quoteview), player_num,
+ quote_num);
+}
+
+void quote_player_finish(gint player_num)
+{
+ quote_view_reject(QUOTEVIEW(quoteview), player_num);
+ if (player_num == my_player_num()) {
+ /* Lock the UI */
+ lock_resource_tables();
+ }
+}
+
+void quote_finish(void)
+{
+ quote_view_finish(QUOTEVIEW(quoteview));
+ gui_show_quote_page(FALSE);
+}
+
+static void show_quote_params(gint player_num,
+ const gint * they_supply,
+ const gint * they_receive)
+{
+ gchar we_supply_desc[512];
+ gchar we_receive_desc[512];
+ gchar desc[512];
+ GdkPixbuf *icon;
+
+ trade_player = player_num;
+ resource_format_type(we_supply_desc, they_receive);
+ resource_format_type(we_receive_desc, they_supply);
+ g_snprintf(desc, sizeof(desc),
+ _("%s has %s, and is looking for %s"),
+ player_name(player_num, TRUE), we_receive_desc,
+ we_supply_desc);
+ gtk_label_set_text(GTK_LABEL(desc_lbl), desc);
+
+ icon = player_create_icon(player_icon, player_num, TRUE);
+ gtk_image_set_from_pixbuf(GTK_IMAGE(player_icon), icon);
+ g_object_unref(icon);
+
+ memcpy(we_supply, they_receive, sizeof(we_supply));
+ memcpy(we_receive, they_supply, sizeof(we_receive));
+}
+
+void quote_begin_again(gint player_num, const gint * we_receive,
+ const gint * we_supply)
+{
+ /* show the new parameters */
+ show_quote_params(player_num, we_receive, we_supply);
+ /* throw out reject rows: everyone can quote again */
+ quote_view_remove_rejected_quotes(QUOTEVIEW(quoteview));
+ /* check if existing quotes are still valid */
+ quote_view_check_validity_of_trades(QUOTEVIEW(quoteview));
+ /* update everything */
+ quote_update();
+ set_resource_tables_filter(we_receive, we_supply);
+ frontend_gui_update();
+}
+
+void quote_begin(gint player_num, const gint * we_receive,
+ const gint * we_supply)
+{
+ /* show what is asked */
+ show_quote_params(player_num, we_receive, we_supply);
+ /* reset variables */
+ next_quote_num = 0;
+ /* clear the gui list */
+ quote_view_begin(QUOTEVIEW(quoteview));
+ /* initialize our offer */
+ quote_update();
+ set_resource_tables_filter(we_receive, we_supply);
+ frontend_gui_update();
+ /* finally, show the page so the user can see it */
+ gui_show_quote_page(TRUE);
+}
+
+static void quote_selected_cb(G_GNUC_UNUSED QuoteView * quoteview,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ /** @todo RC 2006-05-27 Update the resource tables,
+ * to show the effect of the selected quote
+ */
+ frontend_gui_update();
+}
+
+static void quote_dblclick_cb(G_GNUC_UNUSED QuoteView * quoteview,
+ gpointer delete_btn)
+{
+ if (can_delete_quote())
+ gtk_button_clicked(GTK_BUTTON(delete_btn));
+}
+
+static void amount_changed_cb(G_GNUC_UNUSED ResourceTable * rt,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ quote_view_clear_selected_quote(QUOTEVIEW(quoteview));
+ frontend_gui_update();
+}
+
+GtkWidget *quote_build_page(void)
+{
+ GtkWidget *panel_vbox;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *bbox;
+
+ panel_vbox = gtk_vbox_new(FALSE, 3);
+ gtk_widget_show(panel_vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(panel_vbox), 6);
+
+ hbox = gtk_hbox_new(FALSE, 6);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(panel_vbox), hbox, FALSE, TRUE, 0);
+
+ player_icon = gtk_image_new();
+ gtk_widget_show(player_icon);
+ gtk_box_pack_start(GTK_BOX(hbox), player_icon, FALSE, FALSE, 0);
+
+ desc_lbl = gtk_label_new("");
+ gtk_widget_show(desc_lbl);
+ gtk_box_pack_start(GTK_BOX(hbox), desc_lbl, TRUE, TRUE, 0);
+ gtk_misc_set_alignment(GTK_MISC(desc_lbl), 0, 0.5);
+
+ hbox = gtk_hbox_new(FALSE, 6);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(panel_vbox), hbox, TRUE, TRUE, 0);
+
+ vbox = gtk_vbox_new(FALSE, 3);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, TRUE, 0);
+
+ want_table =
+ resource_table_new(_("I Want"), RESOURCE_TABLE_MORE_IN_HAND,
+ FALSE, FALSE);
+ gtk_widget_show(want_table);
+ gtk_box_pack_start(GTK_BOX(vbox), want_table, FALSE, TRUE, 0);
+ g_signal_connect(G_OBJECT(want_table), "change",
+ G_CALLBACK(amount_changed_cb), NULL);
+
+ give_table =
+ resource_table_new(_("Give Them"), RESOURCE_TABLE_LESS_IN_HAND,
+ FALSE, FALSE);
+ gtk_widget_show(give_table);
+ gtk_box_pack_start(GTK_BOX(vbox), give_table, FALSE, TRUE, 0);
+ g_signal_connect(G_OBJECT(give_table), "change",
+ G_CALLBACK(amount_changed_cb), NULL);
+
+ bbox = gtk_hbutton_box_new();
+ gtk_widget_show(bbox);
+ gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
+
+ submit_btn = gtk_button_new_with_label(_("Quote"));
+ frontend_gui_register(submit_btn, GUI_QUOTE_SUBMIT, "clicked");
+ gtk_widget_show(submit_btn);
+ gtk_container_add(GTK_CONTAINER(bbox), submit_btn);
+
+ delete_btn = gtk_button_new_with_label(_("Delete"));
+ frontend_gui_register(delete_btn, GUI_QUOTE_DELETE, "clicked");
+ gtk_widget_show(delete_btn);
+ gtk_container_add(GTK_CONTAINER(bbox), delete_btn);
+
+ vbox = gtk_vbox_new(FALSE, 3);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
+
+ quoteview = quote_view_new(FALSE, can_delete_this_quote,
+ GTK_STOCK_DELETE, NULL);
+ gtk_widget_show(quoteview);
+ gtk_box_pack_start(GTK_BOX(vbox), quoteview, TRUE, TRUE, 0);
+ g_signal_connect(QUOTEVIEW(quoteview), "selection-changed",
+ G_CALLBACK(quote_selected_cb), NULL);
+ g_signal_connect(G_OBJECT(quoteview), "selection-activated",
+ G_CALLBACK(quote_dblclick_cb), delete_btn);
+
+ bbox = gtk_hbutton_box_new();
+ gtk_widget_show(bbox);
+ gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox),
+ GTK_BUTTONBOX_SPREAD);
+
+ reject_btn = gtk_button_new_with_label(_("Reject Domestic Trade"));
+ frontend_gui_register(reject_btn, GUI_QUOTE_REJECT, "clicked");
+ gtk_widget_show(reject_btn);
+ gtk_container_add(GTK_CONTAINER(bbox), reject_btn);
+
+ return panel_vbox;
+}
+
+void frontend_quote_trade(G_GNUC_UNUSED gint player_num, gint partner_num,
+ gint quote_num,
+ G_GNUC_UNUSED const gint * they_supply,
+ G_GNUC_UNUSED const gint * they_receive)
+{
+ /* a quote has been accepted, remove it from the list. */
+ quote_view_remove_quote(QUOTEVIEW(quoteview), partner_num,
+ quote_num);
+ quote_update();
+ frontend_gui_update();
+}
Added: trunk/client/gtk/resource-table.c
===================================================================
--- trunk/client/gtk/resource-table.c (rev 0)
+++ trunk/client/gtk/resource-table.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,461 @@
+/* A custom widget for selecting resources
+ *
+ * The code is based on the TICTACTOE and DIAL examples
+ * http://www.gtk.org/tutorial/app-codeexamples.html
+ * http://www.gtk.org/tutorial/sec-gtkdial.html
+ *
+ * Adaptation for Pioneers: 2004 Roland Clobus
+ *
+ */
+
+#include "config.h"
+#include <gtk/gtksignal.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkspinbutton.h>
+#include <string.h>
+#include <stdio.h>
+#include <glib.h>
+
+#include "resource-table.h"
+
+#include "callback.h"
+/* The signals */
+enum {
+ CHANGE,
+ LAST_SIGNAL
+};
+
+static void resource_table_class_init(ResourceTableClass * klass);
+static void resource_table_init(ResourceTable * rt);
+static void resource_table_update(ResourceTable * rt);
+
+static void less_resource_cb(GtkButton * widget, gpointer user_data);
+static void more_resource_cb(GtkButton * widget, gpointer user_data);
+static void value_changed_cb(GtkSpinButton * widget, gpointer user_data);
+
+/* All signals */
+static guint resource_table_signals[LAST_SIGNAL] = { 0 };
+
+/* Register the class */
+GType resource_table_get_type(void)
+{
+ static GType rt_type = 0;
+
+ if (!rt_type) {
+ static const GTypeInfo rt_info = {
+ sizeof(ResourceTableClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) resource_table_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(ResourceTable),
+ 0,
+ (GInstanceInitFunc) resource_table_init,
+ NULL
+ };
+ rt_type =
+ g_type_register_static(GTK_TYPE_TABLE, "ResourceTable",
+ &rt_info, 0);
+ }
+ return rt_type;
+}
+
+/* Register the signals.
+ * ResourceTable will emit this signal:
+ * 'change' when any change in the amount occurs.
+ */
+static void resource_table_class_init(ResourceTableClass * klass)
+{
+ resource_table_signals[CHANGE] = g_signal_new("change",
+ G_TYPE_FROM_CLASS
+ (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET
+ (ResourceTableClass,
+ change), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/* Initialise the composite widget */
+static void resource_table_init(ResourceTable * rt)
+{
+ gint i;
+
+ for (i = 0; i < NO_RESOURCE; i++) {
+ rt->row[i].hand = 0;
+ rt->row[i].bank = 0;
+ rt->row[i].amount = 0;
+ rt->row[i].hand_widget = NULL;
+ rt->row[i].bank_widget = NULL;
+ rt->row[i].amount_widget = NULL;
+ rt->row[i].less_widget = NULL;
+ rt->row[i].more_widget = NULL;
+ }
+ rt->total_target = 0;
+ rt->total_current = 0;
+ rt->total_widget = NULL;
+
+ rt->limit_bank = FALSE;
+ rt->with_bank = FALSE;
+ rt->with_total = FALSE;
+ rt->direction = RESOURCE_TABLE_MORE_IN_HAND;
+ rt->tooltips = gtk_tooltips_new();
+
+}
+
+static void resource_table_set_limit(ResourceTable * rt, gint row)
+{
+ gint limit;
+
+ if (rt->with_total)
+ limit =
+ rt->with_bank ?
+ MIN(rt->total_target, rt->row[row].bank) :
+ MIN(rt->total_target, rt->row[row].hand);
+ else
+ limit = rt->with_bank ? rt->row[row].bank :
+ rt->direction ==
+ RESOURCE_TABLE_MORE_IN_HAND ? 99 : rt->row[row].hand;
+ rt->row[row].limit = limit;
+ gtk_spin_button_set_range(GTK_SPIN_BUTTON
+ (rt->row[row].amount_widget), 0, limit);
+ gtk_widget_set_sensitive(rt->row[row].amount_widget, limit > 0);
+}
+
+/* Create a new ResourceTable */
+GtkWidget *resource_table_new(const gchar * title,
+ ResourceTableDirection direction,
+ gboolean with_bank, gboolean with_total)
+{
+ ResourceTable *rt;
+
+ gchar *temp;
+ GtkWidget *widget;
+ gint i;
+ gint row;
+
+ rt = g_object_new(resource_table_get_type(), NULL);
+
+ rt->direction = direction;
+
+ rt->with_bank = with_bank;
+ /* Don't set rt->with_total yet, wait for _set_total */
+
+ rt->bank_offset = with_bank ? 1 : 0;
+ gtk_table_resize(GTK_TABLE(rt),
+ NO_RESOURCE + 1 + with_total ? 1 : 0,
+ 5 + rt->bank_offset);
+ gtk_table_set_row_spacings(GTK_TABLE(rt), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(rt), 6);
+
+ temp = g_strconcat("<b>", title, "</b>", NULL);
+ widget = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(widget), temp);
+ g_free(temp);
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(rt), widget,
+ 0, 5 + rt->bank_offset, 0, 1);
+ gtk_misc_set_alignment(GTK_MISC(widget), 0, 0.5);
+
+ row = 1;
+ for (i = 0; i < NO_RESOURCE; i++) {
+ rt->row[i].filter = FALSE;
+
+ widget = rt->row[i].label_widget =
+ gtk_label_new(resource_name(i, TRUE));
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(rt), widget,
+ 0, 1, row, row + 1);
+ gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.5);
+
+ widget = rt->row[i].hand_widget = gtk_entry_new();
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(rt), widget,
+ 1, 2, row, row + 1);
+ gtk_entry_set_width_chars(GTK_ENTRY(widget), 3);
+ gtk_widget_set_sensitive(widget, FALSE);
+ gtk_entry_set_alignment(GTK_ENTRY(widget), 1.0);
+ gtk_tooltips_set_tip(rt->tooltips, widget,
+ /* Tooltip for the amount of resources in the hand */
+ _("Amount in hand"), NULL);
+
+ rt->row[i].hand = resource_asset(i);
+ widget = rt->row[i].less_widget =
+ gtk_button_new_with_label(_("<less"));
+ gtk_widget_set_sensitive(widget, FALSE);
+ g_signal_connect(G_OBJECT(widget), "clicked",
+ G_CALLBACK(less_resource_cb),
+ &rt->row[i]);
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(rt), widget,
+ 2, 3, row, row + 1);
+ gtk_tooltips_set_tip(rt->tooltips, widget,
+ /* Tooltip for decreasing the selected amount */
+ _("Decrease the selected amount"),
+ NULL);
+
+ if (with_bank) {
+ rt->row[i].bank = get_bank()[i];
+ widget = rt->row[i].bank_widget = gtk_entry_new();
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(rt), widget,
+ 3, 4, row, row + 1);
+ gtk_entry_set_width_chars(GTK_ENTRY(widget), 3);
+ gtk_widget_set_sensitive(widget, FALSE);
+ gtk_entry_set_alignment(GTK_ENTRY(widget), 1.0);
+ gtk_tooltips_set_tip(rt->tooltips, widget,
+ /* Tooltip for the amount of resources in the bank */
+ _("Amount in the bank"),
+ NULL);
+ }
+ widget = rt->row[i].more_widget =
+ gtk_button_new_with_label(_("more>"));
+ gtk_widget_set_sensitive(widget, FALSE);
+ g_signal_connect(G_OBJECT(widget), "clicked",
+ G_CALLBACK(more_resource_cb),
+ &rt->row[i]);
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(rt), widget,
+ 3 + rt->bank_offset,
+ 4 + rt->bank_offset, row,
+ row + 1);
+ gtk_tooltips_set_tip(rt->tooltips, widget,
+ /* Tooltip for increasing the selected amount */
+ _("Increase the selected amount"),
+ NULL);
+
+ widget = rt->row[i].amount_widget =
+ gtk_spin_button_new_with_range(0, 99, 1);
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(rt), widget,
+ 4 + rt->bank_offset,
+ 5 + rt->bank_offset, row,
+ row + 1);
+ gtk_entry_set_width_chars(GTK_ENTRY(widget), 3);
+ gtk_entry_set_alignment(GTK_ENTRY(widget), 1.0);
+ g_signal_connect(G_OBJECT(widget), "value-changed",
+ G_CALLBACK(value_changed_cb),
+ &rt->row[i]);
+ gtk_tooltips_set_tip(rt->tooltips, widget,
+ /* Tooltip for the selected amount */
+ _("Selected amount"), NULL);
+
+ resource_table_set_limit(rt, i);
+ row++;
+ }
+ resource_table_update(rt);
+ return GTK_WIDGET(rt);
+}
+
+void resource_table_limit_bank(ResourceTable * rt, gboolean limit)
+{
+ rt->limit_bank = limit;
+ resource_table_update(rt);
+}
+
+void resource_table_set_total(ResourceTable * rt, const gchar * text,
+ gint total)
+{
+ GtkWidget *widget;
+ gint row;
+ gint i;
+
+ g_assert(IS_RESOURCETABLE(rt));
+ rt->with_total = TRUE;
+ rt->total_target = total;
+ rt->total_current = 0;
+ row = NO_RESOURCE + 1;
+
+ widget = gtk_label_new(text);
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(rt), widget,
+ 0, 4 + rt->bank_offset, row, row + 1);
+ gtk_misc_set_alignment(GTK_MISC(widget), 1.0, 0.5);
+
+ widget = rt->total_widget =
+ gtk_spin_button_new_with_range(0, total, 1);
+ gtk_widget_show(widget);
+ gtk_table_attach_defaults(GTK_TABLE(rt), widget,
+ 4 + rt->bank_offset, 5 + rt->bank_offset,
+ row, row + 1);
+ gtk_entry_set_width_chars(GTK_ENTRY(widget), 3);
+ gtk_widget_set_sensitive(widget, FALSE);
+ gtk_entry_set_alignment(GTK_ENTRY(widget), 1.0);
+ gtk_tooltips_set_tip(rt->tooltips, widget,
+ /* Tooltip for the total selected amount */
+ _("Total selected amount"), NULL);
+
+ for (i = 0; i < NO_RESOURCE; i++) {
+ resource_table_set_limit(rt, i);
+ }
+ resource_table_update(rt);
+}
+
+void resource_table_set_bank(ResourceTable * rt, const gint * bank)
+{
+ gint i;
+
+ for (i = 0; i < NO_RESOURCE; i++) {
+ rt->row[i].bank = bank[i];
+ resource_table_set_limit(rt, i);
+ if (rt->limit_bank && rt->with_total
+ && bank[i] > rt->total_target) {
+ gtk_tooltips_set_tip(rt->tooltips,
+ rt->row[i].bank_widget,
+ /* Tooltip when the bank cannot be emptied */
+ _
+ ("The bank cannot be emptied"),
+ NULL);
+ }
+ }
+ resource_table_update(rt);
+}
+
+/* Update the display to the current state */
+static void resource_table_update(ResourceTable * rt)
+{
+ gchar buff[16];
+ gint i;
+ struct _ResourceRow *row;
+ gboolean less_enabled;
+ gboolean more_enabled;
+
+ g_assert(IS_RESOURCETABLE(rt));
+ rt->total_current = 0;
+ for (i = 0; i < NO_RESOURCE; i++)
+ rt->total_current += rt->row[i].amount;
+
+ if (rt->with_total) {
+ sprintf(buff, "%d", rt->total_current);
+ gtk_entry_set_text(GTK_ENTRY(rt->total_widget), buff);
+ }
+
+ for (i = 0; i < NO_RESOURCE; i++) {
+ row = &rt->row[i];
+
+ sprintf(buff, "%d", row->amount);
+ gtk_entry_set_text(GTK_ENTRY(row->amount_widget), buff);
+
+ less_enabled = row->amount > 0;
+ more_enabled = row->amount < row->limit;
+ if (rt->with_total
+ && rt->total_current >= rt->total_target)
+ more_enabled = FALSE;
+
+ if (rt->direction == RESOURCE_TABLE_MORE_IN_HAND)
+ sprintf(buff, "%d", row->hand + row->amount);
+ else
+ sprintf(buff, "%d", row->hand - row->amount);
+
+ gtk_entry_set_text(GTK_ENTRY(row->hand_widget), buff);
+
+ if (rt->with_bank) {
+ if (rt->limit_bank && rt->with_total
+ && row->bank > rt->total_target)
+ sprintf(buff, "%s", "++");
+ else
+ sprintf(buff, "%d",
+ row->bank - row->amount);
+ gtk_entry_set_text(GTK_ENTRY(row->bank_widget),
+ buff);
+ }
+
+ gtk_widget_set_sensitive(row->label_widget, !row->filter);
+ gtk_widget_set_sensitive(row->less_widget, less_enabled
+ && !row->filter);
+ gtk_widget_set_sensitive(row->more_widget, more_enabled
+ && !row->filter);
+ gtk_widget_set_sensitive(row->amount_widget,
+ (less_enabled || more_enabled)
+ && !row->filter);
+ }
+}
+
+static void less_resource_cb(GtkButton * widget, gpointer user_data)
+{
+ struct _ResourceRow *row = user_data;
+ ResourceTable *rt =
+ RESOURCETABLE(gtk_widget_get_parent(GTK_WIDGET(widget)));
+
+ row->amount--;
+ resource_table_update(rt);
+ g_signal_emit(G_OBJECT(rt), resource_table_signals[CHANGE], 0);
+}
+
+static void more_resource_cb(GtkButton * widget, gpointer user_data)
+{
+ struct _ResourceRow *row = user_data;
+ ResourceTable *rt =
+ RESOURCETABLE(gtk_widget_get_parent(GTK_WIDGET(widget)));
+
+ row->amount++;
+ resource_table_update(rt);
+ g_signal_emit(G_OBJECT(rt), resource_table_signals[CHANGE], 0);
+}
+
+static void value_changed_cb(GtkSpinButton * widget, gpointer user_data)
+{
+ struct _ResourceRow *row = user_data;
+ ResourceTable *rt =
+ RESOURCETABLE(gtk_widget_get_parent(GTK_WIDGET(widget)));
+
+ row->amount = gtk_spin_button_get_value_as_int(widget);
+ resource_table_update(rt);
+ g_signal_emit(G_OBJECT(rt), resource_table_signals[CHANGE], 0);
+}
+
+void resource_table_get_amount(ResourceTable * rt, gint * amount)
+{
+ gint i;
+
+ g_assert(IS_RESOURCETABLE(rt));
+ for (i = 0; i < NO_RESOURCE; i++)
+ amount[i] = rt->row[i].amount;
+}
+
+gboolean resource_table_is_total_reached(ResourceTable * rt)
+{
+ g_assert(IS_RESOURCETABLE(rt));
+ return (rt->total_current == rt->total_target);
+}
+
+void resource_table_update_hand(ResourceTable * rt)
+{
+ gint i;
+
+ g_assert(IS_RESOURCETABLE(rt));
+ for (i = 0; i < NO_RESOURCE; i++) {
+ rt->row[i].hand = resource_asset(i);
+ resource_table_set_limit(rt, i);
+ }
+ resource_table_update(rt);
+}
+
+void resource_table_set_filter(ResourceTable * rt, const gint * resource)
+{
+ gint i;
+
+ g_assert(IS_RESOURCETABLE(rt));
+ for (i = 0; i < NO_RESOURCE; i++) {
+ rt->row[i].filter = resource[i] == 0;
+ }
+ resource_table_update(rt);
+}
+
+void resource_table_clear(ResourceTable * rt)
+{
+ gint i;
+
+ g_assert(IS_RESOURCETABLE(rt));
+ for (i = 0; i < NO_RESOURCE; i++) {
+ rt->row[i].amount = 0;
+ }
+ resource_table_update(rt);
+}
Added: trunk/client/gtk/resource-table.h
===================================================================
--- trunk/client/gtk/resource-table.h (rev 0)
+++ trunk/client/gtk/resource-table.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,90 @@
+/* A custom widget for selecting resources
+ *
+ * The code is based on the TICTACTOE and DIAL examples
+ * http://www.gtk.org/tutorial/app-codeexamples.html
+ * http://www.gtk.org/tutorial/sec-gtkdial.html
+ *
+ * Adaptation for Pioneers: 2004 Roland Clobus
+ *
+ */
+#ifndef __RESOURCETABLE_H__
+#define __RESOURCETABLE_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtktable.h>
+
+#include "map.h" /* For NO_RESOURCE */
+
+G_BEGIN_DECLS
+#define RESOURCETABLE_TYPE (resource_table_get_type ())
+#define RESOURCETABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RESOURCETABLE_TYPE, ResourceTable))
+#define RESOURCETABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RESOURCETABLE_TYPE, ResourceTableClass))
+#define IS_RESOURCETABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RESOURCETABLE_TYPE))
+#define IS_RESOURCETABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RESOURCETABLE_TYPE))
+typedef struct _ResourceTable ResourceTable;
+typedef struct _ResourceTableClass ResourceTableClass;
+
+struct _ResourceRow {
+ gboolean filter;
+
+ gint hand;
+ gint bank;
+ gint amount;
+ GtkWidget *label_widget;
+ GtkWidget *hand_widget;
+ GtkWidget *bank_widget;
+ GtkWidget *amount_widget;
+
+ gint limit;
+ GtkWidget *less_widget;
+ GtkWidget *more_widget;
+};
+
+enum _ResourceTableDirection {
+ RESOURCE_TABLE_MORE_IN_HAND,
+ RESOURCE_TABLE_LESS_IN_HAND
+};
+typedef enum _ResourceTableDirection ResourceTableDirection;
+
+struct _ResourceTable {
+ GtkTable table;
+ GtkTooltips *tooltips;
+
+ struct _ResourceRow row[NO_RESOURCE];
+
+ gint total_target;
+ gint total_current;
+ GtkWidget *total_widget;
+
+ gboolean limit_bank;
+ gboolean with_bank;
+ gboolean with_total;
+ gint bank_offset;
+ ResourceTableDirection direction;
+};
+
+struct _ResourceTableClass {
+ GtkTableClass parent_class;
+
+ void (*change) (ResourceTable * rt);
+};
+
+GType resource_table_get_type(void);
+GtkWidget *resource_table_new(const gchar * title,
+ ResourceTableDirection direction,
+ gboolean with_bank, gboolean with_total);
+
+void resource_table_limit_bank(ResourceTable * rt, gboolean limit);
+void resource_table_set_total(ResourceTable * rt, const gchar * text,
+ gint total);
+void resource_table_set_bank(ResourceTable * rt, const gint * bank);
+void resource_table_get_amount(ResourceTable * rt, gint * amount);
+gboolean resource_table_is_total_reached(ResourceTable * rt);
+void resource_table_update_hand(ResourceTable * rt);
+void resource_table_set_filter(ResourceTable * rt, const gint * resource);
+void resource_table_clear(ResourceTable * rt);
+
+G_END_DECLS
+#endif /* __RESOURCETABLE_H__ */
Added: trunk/client/gtk/resource.c
===================================================================
--- trunk/client/gtk/resource.c (rev 0)
+++ trunk/client/gtk/resource.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,243 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2006 Giancarlo Capella <giancarlo at comm.cc>
+ * Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+
+/* image widgets showing resources */
+static GtkWidget *asset_images[NO_RESOURCE];
+
+/* 'total' label widget */
+static GtkWidget *asset_total_label;
+
+/* tooltips for the resources */
+static GtkTooltips *tooltips = NULL;
+
+/* eventboxes for the tooltips */
+static GtkWidget *eventbox[NO_RESOURCE];
+static gint asset_size[NO_RESOURCE];
+
+static void rebuild_single_resource(gint resource_type)
+{
+ gint res[NO_RESOURCE];
+ gchar *tooltip_text;
+
+ memset(res, 0, sizeof(res));
+ res[resource_type] = resource_asset(resource_type);
+
+ resource_format_type_image(GTK_IMAGE(asset_images[resource_type]),
+ res, asset_size[resource_type]);
+ tooltip_text =
+ g_strdup_printf("%s: %d", resource_name(resource_type, TRUE),
+ resource_asset(resource_type));
+ gtk_tooltips_set_tip(tooltips, eventbox[resource_type],
+ tooltip_text, NULL);
+ g_free(tooltip_text);
+}
+
+/* Set available width of resource table cell. */
+static void on_image_size_allocate(G_GNUC_UNUSED GtkWidget * widget,
+ GtkAllocation * allocation,
+ gpointer user_data)
+{
+ gint resource_type = GPOINTER_TO_INT(user_data);
+ gint old_size = asset_size[resource_type];
+
+ if (old_size == allocation->width)
+ return;
+ asset_size[resource_type] = allocation->width;
+ rebuild_single_resource(resource_type);
+}
+
+static void create_resource_image(GtkTable * table, gint resource_type,
+ guint column, guint row)
+{
+ GtkWidget *box;
+ GtkWidget *image;
+
+ eventbox[resource_type] = box = gtk_event_box_new();
+ gtk_widget_show(box);
+ gtk_table_attach(table, box, column, column + 1, row, row + 1,
+ GTK_EXPAND | GTK_FILL, GTK_FILL, 3, 0);
+ asset_images[resource_type] = image = gtk_image_new();
+ gtk_widget_show(image);
+ gtk_container_add(GTK_CONTAINER(box), image);
+ gtk_tooltips_set_tip(tooltips, box,
+ resource_name(resource_type, TRUE), NULL);
+
+ g_signal_connect(G_OBJECT(image), "size_allocate",
+ G_CALLBACK(on_image_size_allocate),
+ GINT_TO_POINTER(resource_type));
+}
+
+GtkWidget *resource_build_panel(void)
+{
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *alignment;
+ GtkWidget *total;
+ PangoLayout *layout;
+ gint width_00, height_00;
+
+ table = gtk_table_new(4, 2, TRUE);
+ gtk_widget_show(table);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 5);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 3, 3);
+ gtk_widget_show(alignment);
+ gtk_table_attach_defaults(GTK_TABLE(table), alignment, 0, 2, 0, 1);
+
+ label = gtk_label_new(NULL);
+ /* Caption for overview of the resources of the player */
+ gtk_label_set_markup(GTK_LABEL(label), _("<b>Resources</b>"));
+ gtk_widget_show(label);
+ gtk_container_add(GTK_CONTAINER(alignment), label);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+
+ tooltips = gtk_tooltips_new();
+
+ create_resource_image(GTK_TABLE(table), BRICK_RESOURCE, 0, 1);
+ create_resource_image(GTK_TABLE(table), GRAIN_RESOURCE, 0, 2);
+ create_resource_image(GTK_TABLE(table), ORE_RESOURCE, 0, 3);
+ create_resource_image(GTK_TABLE(table), WOOL_RESOURCE, 1, 1);
+ create_resource_image(GTK_TABLE(table), LUMBER_RESOURCE, 1, 2);
+
+ total = gtk_hbox_new(FALSE, 0);
+ gtk_widget_show(total);
+
+ label = gtk_label_new(_("Total"));
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(total), label, TRUE, TRUE, 3);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ asset_total_label = label = gtk_label_new("-");
+ /* Measure the size of '00' to avoid resizing problems */
+ layout = gtk_widget_create_pango_layout(label, "00");
+ pango_layout_get_pixel_size(layout, &width_00, &height_00);
+ g_object_unref(layout);
+ gtk_widget_set_size_request(label, width_00, height_00);
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(total), label, TRUE, TRUE, 3);
+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+
+ gtk_table_attach(GTK_TABLE(table), total, 1, 2, 3, 4,
+ (GtkAttachOptions) GTK_EXPAND | GTK_FILL,
+ (GtkAttachOptions) GTK_FILL, 3, 0);
+
+ return table;
+}
+
+void frontend_resource_change(Resource type, gint new_amount)
+{
+ if (type < NO_RESOURCE) {
+ char buff[16];
+ gint res[NO_RESOURCE];
+
+ memset(res, 0, sizeof(res));
+ res[type] = new_amount;
+
+ snprintf(buff, sizeof(buff), "%d", resource_total());
+ gtk_label_set_text(GTK_LABEL(asset_total_label), buff);
+ /* Force resize of the table, this is needed because
+ * GTK does not correctly redraw a label when the amounts
+ * cross the barrier of 1 or 2 positions.
+ */
+ gtk_container_check_resize(GTK_CONTAINER
+ (gtk_widget_get_parent
+ (asset_total_label)));
+ rebuild_single_resource(type);
+ }
+ frontend_gui_update();
+}
+
+void resource_format_type_image(GtkImage * image, const gint * resources,
+ gint max_width)
+{
+ gint num_res, tot_res, idx, i, pos;
+
+ GdkPixmap *p, *pdest;
+ GdkBitmap *b, *bdest;
+ GdkGC *gcp, *gcb;
+ gchar *data;
+ gint size, step;
+ gint width;
+
+ num_res = tot_res = 0;
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ if (resources[idx]) {
+ num_res++;
+ tot_res += resources[idx];
+ }
+ }
+
+ if (tot_res == 0) {
+ tot_res = 1; /* Avoid division by zero */
+ }
+
+ size = gui_get_resource_pixmap_res();
+ pos = 0;
+
+ if (max_width <= 0 || tot_res == num_res
+ || max_width >= size * tot_res) {
+ step = size;
+ width = size * num_res + step * (tot_res - num_res);
+ if (width < max_width)
+ width = max_width;
+ } else {
+ step = (max_width - num_res * size) / (tot_res - num_res);
+ if (step <= 0)
+ step = 1;
+ width = max_width;
+ }
+
+ pdest =
+ gdk_pixmap_new(NULL,
+ width, size, gdk_visual_get_system()->depth);
+ data = g_malloc0((((width + 7) >> 3) * size));
+ bdest =
+ gdk_bitmap_create_from_data(NULL, data,
+ size * num_res + step * (tot_res -
+ num_res),
+ size);
+ g_free(data);
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ if (!resources[idx])
+ continue;
+ gui_get_resource_pixmap(idx, &p, &b, &gcp, &gcb);
+ for (i = 0; i < resources[idx]; i++) {
+ gdk_gc_set_clip_origin(gcp, pos, 0);
+ gdk_draw_drawable(pdest, gcp, p, 0, 0, pos, 0, -1,
+ -1);
+ gdk_draw_drawable(bdest, gcb, b, 0, 0, pos, 0, -1,
+ -1);
+ pos += step;
+ }
+ pos += size - step;
+ }
+
+ gtk_image_set_from_pixmap(image, pdest, bdest);
+
+ g_object_unref(pdest);
+ g_object_unref(bdest);
+}
Added: trunk/client/gtk/settingscreen.c
===================================================================
--- trunk/client/gtk/settingscreen.c (rev 0)
+++ trunk/client/gtk/settingscreen.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,396 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2005 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "gui.h"
+
+static GtkWidget *settings_dlg = NULL;
+
+enum { TYPE_NUM,
+ TYPE_BOOL,
+ TYPE_STRING
+};
+
+static void add_setting_desc(GtkWidget * table, gint row, gint col,
+ const gchar * desc)
+{
+ GtkWidget *label;
+
+ label = gtk_label_new(desc);
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, col, col + 1, row,
+ row + 1, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+}
+
+static void add_setting_desc_with_image(GtkWidget * table, gint row,
+ gint col, const gchar * desc,
+ const gchar * iconname)
+{
+ GtkWidget *icon;
+
+ icon = gtk_image_new_from_stock(iconname, GTK_ICON_SIZE_MENU);
+ gtk_widget_show(icon);
+ gtk_table_attach(GTK_TABLE(table), icon, col, col + 1, row,
+ row + 1, GTK_FILL, GTK_FILL, 0, 0);
+
+ add_setting_desc(table, row, col + 1, desc);
+}
+
+static void add_setting_val(GtkWidget * table, gint row, gint col,
+ gint type, gint int_val,
+ const gchar * char_val, gboolean right_aligned)
+{
+ GtkWidget *label;
+ gchar *label_var;
+
+ switch (type) {
+ case TYPE_NUM:
+ label_var = g_strdup_printf("%i", int_val);
+ break;
+
+ case TYPE_BOOL:
+ if (int_val != 0) {
+ label_var = g_strdup(_("Yes"));
+ } else {
+ label_var = g_strdup(_("No"));
+ }
+ break;
+ case TYPE_STRING:
+ if (char_val == NULL) {
+ char_val = " ";
+ }
+ label_var = g_strdup_printf("%s", char_val);
+ break;
+
+ default:
+ label_var = g_strdup(_("Unknown"));
+ break;
+ }
+
+ label = gtk_label_new(label_var);
+ g_free(label_var);
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label,
+ col, col + 1, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label),
+ (right_aligned ? 1.0 : 0.0), 0.5);
+}
+
+static GtkWidget *settings_create_content(void)
+{
+ const GameParams *game_params;
+ GtkWidget *dlg_vbox;
+ GtkWidget *alignment;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *table;
+ GtkWidget *label;
+ gchar *sevens_desc;
+ gchar *island_bonus;
+ guint row;
+
+ /* Create some space inside the dialog */
+ dlg_vbox = gtk_vbox_new(FALSE, 6);
+ gtk_container_set_border_width(GTK_CONTAINER(dlg_vbox), 6);
+ gtk_widget_show(dlg_vbox);
+
+ game_params = get_game_params();
+ if (game_params == NULL) {
+ label = gtk_label_new(_("No game in progress..."));
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), label, TRUE, TRUE,
+ 6);
+ gtk_widget_show(label);
+
+ return dlg_vbox;
+ }
+
+ label = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(label),
+ _("<b>General Settings</b>"));
+ gtk_widget_show(label);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), label, FALSE, TRUE, 0);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), alignment, FALSE, FALSE, 0);
+
+ table = gtk_table_new(9, 2, FALSE);
+ gtk_widget_show(table);
+ gtk_container_add(GTK_CONTAINER(alignment), table);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 6);
+
+ add_setting_desc(table, 0, 0, _("Number of players:"));
+ add_setting_val(table, 0, 1, TYPE_NUM, game_params->num_players,
+ NULL, FALSE);
+ add_setting_desc(table, 1, 0, _("Victory Point Target:"));
+ add_setting_val(table, 1, 1, TYPE_NUM, game_params->victory_points,
+ NULL, FALSE);
+ add_setting_desc(table, 2, 0, _("Random Terrain?"));
+ add_setting_val(table, 2, 1, TYPE_BOOL,
+ game_params->random_terrain, NULL, FALSE);
+ add_setting_desc(table, 3, 0, _("Interplayer Trading Allowed?"));
+ add_setting_val(table, 3, 1, TYPE_BOOL,
+ game_params->domestic_trade, NULL, FALSE);
+ add_setting_desc(table, 4, 0,
+ _("Trading allowed only before build/buy?"));
+ add_setting_val(table, 4, 1, TYPE_BOOL, game_params->strict_trade,
+ NULL, FALSE);
+ add_setting_desc(table, 5, 0, _("Amount of Each Resource:"));
+ add_setting_val(table, 5, 1, TYPE_NUM, game_params->resource_count,
+ NULL, FALSE);
+
+ if (game_params->sevens_rule == 0) {
+ sevens_desc = g_strdup(_("Normal"));
+ } else if (game_params->sevens_rule == 1) {
+ sevens_desc = g_strdup(_("Reroll on 1st 2 turns"));
+ } else if (game_params->sevens_rule == 2) {
+ sevens_desc = g_strdup(_("Reroll all 7s"));
+ } else {
+ sevens_desc = g_strdup(_("Unknown"));
+ }
+
+ add_setting_desc(table, 6, 0, _("Sevens Rule:"));
+ add_setting_val(table, 6, 1, TYPE_STRING, 0, sevens_desc, FALSE);
+ g_free(sevens_desc);
+
+ add_setting_desc(table, 7, 0, _("Use Pirate:"));
+ add_setting_val(table, 7, 1, TYPE_BOOL, game_params->use_pirate,
+ NULL, FALSE);
+
+ if (game_params->island_discovery_bonus) {
+ gint idx;
+ island_bonus =
+ g_strdup_printf("%d",
+ g_array_index(game_params->
+ island_discovery_bonus,
+ gint, 0));
+ for (idx = 1;
+ idx < game_params->island_discovery_bonus->len;
+ idx++) {
+ gchar *old = island_bonus;
+ gchar *number = g_strdup_printf("%d",
+ g_array_index
+ (game_params->
+ island_discovery_bonus,
+ gint, idx));
+ island_bonus =
+ g_strconcat(island_bonus, ", ", number, NULL);
+ g_free(old);
+ g_free(number);
+ }
+ } else {
+ island_bonus = g_strdup(_("No"));
+ }
+ add_setting_desc(table, 8, 0, _("Island Discovery Bonuses:"));
+ add_setting_val(table, 8, 1, TYPE_STRING, 0, island_bonus, FALSE);
+ g_free(island_bonus);
+
+ /* Double space, otherwise the columns are too close */
+ hbox = gtk_hbox_new(FALSE, 24);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), hbox, TRUE, FALSE, 0);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
+
+ label = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(label),
+ _("<b>Building Quotas</b>"));
+ gtk_widget_show(label);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, TRUE, 0);
+
+ table = gtk_table_new(6, 3, FALSE);
+ gtk_widget_show(table);
+ gtk_container_add(GTK_CONTAINER(alignment), table);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 6);
+ row = 0;
+
+ add_setting_desc_with_image(table, row, 0, _("Roads:"),
+ PIONEERS_PIXMAP_ROAD);
+ add_setting_val(table, row, 2, TYPE_NUM,
+ game_params->num_build_type[BUILD_ROAD], NULL,
+ TRUE);
+ row++;
+ add_setting_desc_with_image(table, row, 0, _("Settlements:"),
+ PIONEERS_PIXMAP_SETTLEMENT);
+ add_setting_val(table, row, 2, TYPE_NUM,
+ game_params->num_build_type[BUILD_SETTLEMENT],
+ NULL, TRUE);
+ row++;
+ add_setting_desc_with_image(table, row, 0, _("Cities:"),
+ PIONEERS_PIXMAP_CITY);
+ add_setting_val(table, row, 2, TYPE_NUM,
+ game_params->num_build_type[BUILD_CITY], NULL,
+ TRUE);
+ row++;
+ add_setting_desc_with_image(table, row, 0, _("City Walls:"),
+ PIONEERS_PIXMAP_CITY_WALL);
+ add_setting_val(table, row, 2, TYPE_NUM,
+ game_params->num_build_type[BUILD_CITY_WALL], NULL,
+ TRUE);
+ row++;
+ add_setting_desc_with_image(table, row, 0, _("Ships:"),
+ PIONEERS_PIXMAP_SHIP);
+ add_setting_val(table, row, 2, TYPE_NUM,
+ game_params->num_build_type[BUILD_SHIP], NULL,
+ TRUE);
+ row++;
+ add_setting_desc_with_image(table, row, 0, _("Bridges:"),
+ PIONEERS_PIXMAP_BRIDGE);
+ add_setting_val(table, row, 2, TYPE_NUM,
+ game_params->num_build_type[BUILD_BRIDGE], NULL,
+ TRUE);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, TRUE, 0);
+
+ label = gtk_label_new(NULL);
+ gtk_label_set_markup(GTK_LABEL(label),
+ _("<b>Development Card Deck</b>"));
+ gtk_widget_show(label);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 12, 0);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, TRUE, 0);
+
+ table = gtk_table_new(9, 2, FALSE);
+ gtk_widget_show(table);
+ gtk_container_add(GTK_CONTAINER(alignment), table);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 6);
+
+ add_setting_desc(table, 0, 0, _("Road Building Cards:"));
+ add_setting_val(table, 0, 1, TYPE_NUM,
+ game_params->num_develop_type[DEVEL_ROAD_BUILDING],
+ NULL, TRUE);
+ add_setting_desc(table, 1, 0, _("Monopoly Cards:"));
+ add_setting_val(table, 1, 1, TYPE_NUM,
+ game_params->num_develop_type[DEVEL_MONOPOLY],
+ NULL, TRUE);
+ add_setting_desc(table, 2, 0, _("Year of Plenty Cards:"));
+ add_setting_val(table, 2, 1, TYPE_NUM,
+ game_params->
+ num_develop_type[DEVEL_YEAR_OF_PLENTY], NULL,
+ TRUE);
+ add_setting_desc(table, 3, 0, _("Chapel Cards:"));
+ add_setting_val(table, 3, 1, TYPE_NUM,
+ game_params->num_develop_type[DEVEL_CHAPEL], NULL,
+ TRUE);
+ add_setting_desc(table, 4, 0, _("Pioneer University Cards:"));
+ add_setting_val(table, 4, 1, TYPE_NUM,
+ game_params->
+ num_develop_type[DEVEL_UNIVERSITY], NULL, TRUE);
+ add_setting_desc(table, 5, 0, _("Governor's House Cards:"));
+ add_setting_val(table, 5, 1, TYPE_NUM,
+ game_params->
+ num_develop_type[DEVEL_GOVERNORS_HOUSE], NULL,
+ TRUE);
+ add_setting_desc(table, 6, 0, _("Library Cards:"));
+ add_setting_val(table, 6, 1, TYPE_NUM,
+ game_params->num_develop_type[DEVEL_LIBRARY], NULL,
+ TRUE);
+ add_setting_desc(table, 7, 0, _("Market Cards:"));
+ add_setting_val(table, 7, 1, TYPE_NUM,
+ game_params->num_develop_type[DEVEL_MARKET], NULL,
+ TRUE);
+ add_setting_desc(table, 8, 0, _("Soldier Cards:"));
+ add_setting_val(table, 8, 1, TYPE_NUM,
+ game_params->num_develop_type[DEVEL_SOLDIER], NULL,
+ TRUE);
+
+ return dlg_vbox;
+}
+
+static void settings_rules_changed(void)
+{
+ if (settings_dlg) {
+ GtkWidget *vbox;
+ GtkWidget *dlg_vbox;
+ GList *list;
+
+ dlg_vbox = GTK_DIALOG(settings_dlg)->vbox;
+ list = gtk_container_get_children(GTK_CONTAINER(dlg_vbox));
+
+ if (g_list_length(list) > 0)
+ gtk_widget_destroy(GTK_WIDGET(list->data));
+ g_list_free(list);
+
+ vbox = settings_create_content();
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, FALSE, FALSE,
+ 0);
+ }
+}
+
+GtkWidget *settings_create_dlg(void)
+{
+ GtkWidget *dlg_vbox;
+ GtkWidget *vbox;
+
+ if (settings_dlg != NULL)
+ return settings_dlg;
+
+ settings_dlg =
+ gtk_dialog_new_with_buttons(_("Current Game Settings"),
+ GTK_WINDOW(app_window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE, NULL);
+ g_signal_connect(GTK_OBJECT(settings_dlg), "destroy",
+ GTK_SIGNAL_FUNC(gtk_widget_destroyed),
+ &settings_dlg);
+
+ dlg_vbox = GTK_DIALOG(settings_dlg)->vbox;
+ gtk_widget_show(dlg_vbox);
+
+ vbox = settings_create_content();
+ gtk_box_pack_start(GTK_BOX(dlg_vbox), vbox, FALSE, FALSE, 0);
+
+ g_signal_connect(settings_dlg, "response",
+ G_CALLBACK(gtk_widget_destroy), NULL);
+
+ gtk_widget_show(settings_dlg);
+
+ return settings_dlg;
+}
+
+void settings_init(void)
+{
+ gui_rules_register_callback(G_CALLBACK(settings_rules_changed));
+}
Added: trunk/client/gtk/state.c
===================================================================
--- trunk/client/gtk/state.c (rev 0)
+++ trunk/client/gtk/state.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,62 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+
+static GuiState current_state;
+
+void set_gui_state_nomacro(GuiState state)
+{
+ current_state = state;
+ frontend_gui_update();
+}
+
+GuiState get_gui_state(void)
+{
+ return current_state;
+}
+
+void route_gui_event(GuiEvent event)
+{
+ switch (event) {
+ case GUI_UPDATE:
+ frontend_gui_check(GUI_CHANGE_NAME, TRUE);
+ frontend_gui_check(GUI_QUIT, TRUE);
+ /* The routed event could disable disconnect again */
+ frontend_gui_check(GUI_DISCONNECT, TRUE);
+ break;
+ case GUI_CHANGE_NAME:
+ name_create_dlg();
+ return;
+ case GUI_DISCONNECT:
+ frontend_disconnect();
+ return;
+ case GUI_QUIT:
+ debug("quitting");
+ gtk_main_quit();
+ return;
+ default:
+ break;
+ }
+ current_state(event);
+ /* set the focus to the chat window, no matter what happened */
+ chat_set_focus();
+}
Added: trunk/client/gtk/trade.c
===================================================================
--- trunk/client/gtk/trade.c (rev 0)
+++ trunk/client/gtk/trade.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,547 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004,2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "frontend.h"
+#include "cost.h"
+#include "theme.h"
+#include "common_gtk.h"
+#include "quote-view.h"
+
+static void trade_update(void);
+
+typedef struct {
+ GtkWidget *chk; /**< Checkbox to activate trade in this resource */
+ GtkWidget *curr; /**< Amount in possession of this resource */
+ Resource resource; /**< The resource */
+ gboolean enabled; /**< Trading enabled */
+} TradeRow;
+
+static GtkWidget *quoteview;
+
+static TradeRow we_supply_rows[NO_RESOURCE];
+static TradeRow we_receive_rows[NO_RESOURCE];
+
+static gint active_supply_request[NO_RESOURCE];
+static gint active_receive_request[NO_RESOURCE];
+static gboolean trade_since_selection_changed;
+
+/** This button can be hidden in games without interplayer trade */
+static GtkWidget *call_btn;
+/** This frame can be hidden in games without interplayer trade */
+static GtkWidget *we_receive_frame;
+/** The last quote that is called */
+static GtkWidget *active_quote_label;
+
+/** @return TRUE is we can accept this domestic quote */
+static gboolean is_good_quote(const QuoteInfo * quote)
+{
+ gint idx;
+ g_assert(quote != NULL);
+ g_assert(quote->is_domestic);
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ gint we_supply = quote->var.d.receive[idx];
+
+ if (we_supply > resource_asset(idx)
+ || (we_supply > 0 && !we_supply_rows[idx].enabled))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/** @return TRUE if at least one resource is asked/offered */
+gboolean can_call_for_quotes(void)
+{
+ gint idx;
+ gboolean have_we_receive;
+ gboolean have_we_supply;
+ gboolean different_call;
+
+ different_call = FALSE;
+ have_we_receive = have_we_supply = FALSE;
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ if (we_receive_rows[idx].enabled !=
+ active_receive_request[idx])
+ different_call = TRUE;
+ if (we_supply_rows[idx].enabled !=
+ active_supply_request[idx])
+ different_call = TRUE;
+ if (we_receive_rows[idx].enabled)
+ have_we_receive = TRUE;
+ if (we_supply_rows[idx].enabled)
+ have_we_supply = TRUE;
+ }
+ /* don't require both supply and receive, for resources may be
+ * given away for free */
+ return (have_we_receive || have_we_supply)
+ && can_trade_domestic()
+ && (different_call || trade_since_selection_changed);
+}
+
+/** @return the current quote */
+const QuoteInfo *trade_current_quote(void)
+{
+ return quote_view_get_selected_quote(QUOTEVIEW(quoteview));
+}
+
+/** Show what the resources will be if the quote is accepted */
+static void update_rows(void)
+{
+ gint idx;
+ gint amount;
+ gchar str[16];
+ const QuoteInfo *quote = trade_current_quote();
+
+ for (idx = 0; idx < G_N_ELEMENTS(we_supply_rows); idx++) {
+ Resource resource = we_receive_rows[idx].resource;
+ if (!trade_valid_selection())
+ amount = 0;
+ else if (quote->is_domestic)
+ amount =
+ quote->var.d.receive[idx] -
+ quote->var.d.supply[idx];
+ else
+ amount =
+ (quote->var.m.supply ==
+ resource ? quote->var.m.ratio : 0)
+ - (quote->var.m.receive == resource ? 1 : 0);
+ sprintf(str, "%d", resource_asset(resource) - amount);
+ gtk_entry_set_text(GTK_ENTRY(we_receive_rows[idx].curr),
+ str);
+ gtk_entry_set_text(GTK_ENTRY(we_supply_rows[idx].curr),
+ str);
+ }
+}
+
+/** @return all resources we supply */
+const gint *trade_we_supply(void)
+{
+ return active_supply_request;
+}
+
+/** @return all resources we want to have */
+const gint *trade_we_receive(void)
+{
+ return active_receive_request;
+}
+
+/** @return TRUE if a selection is made, and it is valid */
+gboolean trade_valid_selection(void)
+{
+ const QuoteInfo *quote;
+
+ quote = quote_view_get_selected_quote(QUOTEVIEW(quoteview));
+ if (quote == NULL)
+ return FALSE;
+ if (!quote->is_domestic)
+ return TRUE;
+ return is_good_quote(quote);
+}
+
+static void trade_theme_changed(void)
+{
+ quote_view_theme_changed(QUOTEVIEW(quoteview));
+}
+
+static void format_list(gchar * desc, const gint * resources)
+{
+ gint idx;
+ gboolean is_first;
+
+ is_first = TRUE;
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ if (resources[idx] > 0) {
+ if (!is_first)
+ *desc++ = '+';
+ if (resources[idx] > 1) {
+ sprintf(desc, "%d ", resources[idx]);
+ desc += strlen(desc);
+ }
+ strcpy(desc, resource_name(idx, FALSE));
+ desc += strlen(desc);
+ is_first = FALSE;
+ }
+}
+
+void trade_format_quote(const QuoteInfo * quote, gchar * desc)
+{
+ const gchar *format = NULL;
+ gchar buf1[128];
+ gchar buf2[128];
+
+ if (resource_count(quote->var.d.supply) == 0) {
+ /* trade: you ask for something for free */
+ format = _("ask for %s for free");
+ format_list(buf1, quote->var.d.receive);
+ sprintf(desc, format, buf1);
+ } else if (resource_count(quote->var.d.receive) == 0) {
+ /* trade: you give something away for free */
+ format = _("give %s for free");
+ format_list(buf1, quote->var.d.supply);
+ sprintf(desc, format, buf1);
+ } else {
+ /* trade: you trade something for something else */
+ format = _("give %s for %s");
+ format_list(buf1, quote->var.d.supply);
+ format_list(buf2, quote->var.d.receive);
+ sprintf(desc, format, buf1, buf2);
+ }
+}
+
+/** A new trade is started. Keep old quotes, and remove rejection messages.
+ */
+void trade_new_trade(void)
+{
+ gint idx;
+ gchar we_supply_desc[512];
+ gchar we_receive_desc[512];
+ gchar desc[512];
+
+ quote_view_remove_rejected_quotes(QUOTEVIEW(quoteview));
+
+ for (idx = 0; idx < G_N_ELEMENTS(active_supply_request); idx++) {
+ active_supply_request[idx] = we_supply_rows[idx].enabled;
+ active_receive_request[idx] = we_receive_rows[idx].enabled;
+ }
+ trade_since_selection_changed = FALSE;
+
+ resource_format_type(we_supply_desc, active_supply_request);
+ resource_format_type(we_receive_desc, active_receive_request);
+ /* I want some resources, and give them some resources */
+ g_snprintf(desc, sizeof(desc), _("I want %s, and give them %s"),
+ we_receive_desc, we_supply_desc);
+ gtk_label_set_text(GTK_LABEL(active_quote_label), desc);
+}
+
+/** A resource checkbox is toggled */
+static void toggled_cb(GtkWidget * widget, TradeRow * row)
+{
+ gint idx;
+ gboolean filter[2][NO_RESOURCE];
+
+ row->enabled =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ filter[0][idx] = we_supply_rows[idx].enabled;
+ filter[1][idx] = we_receive_rows[idx].enabled;
+ }
+ quote_view_clear_selected_quote(QUOTEVIEW(quoteview));
+ quote_view_set_maritime_filters(QUOTEVIEW(quoteview), filter[0],
+ filter[1]);
+ trade_update();
+ frontend_gui_update();
+}
+
+/** Add a row with widgets for a resource */
+static void add_trade_row(GtkWidget * table, TradeRow * row,
+ Resource resource)
+{
+ gint col;
+
+ col = 0;
+ row->resource = resource;
+ row->chk =
+ gtk_check_button_new_with_label(resource_name(resource, TRUE));
+ g_signal_connect(G_OBJECT(row->chk), "toggled",
+ G_CALLBACK(toggled_cb), row);
+ gtk_widget_show(row->chk);
+ gtk_table_attach(GTK_TABLE(table), row->chk,
+ col, col + 1, resource, resource + 1,
+ GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ col++;
+
+ row->curr = gtk_entry_new();
+ gtk_entry_set_width_chars(GTK_ENTRY(row->curr), 3);
+ gtk_entry_set_alignment(GTK_ENTRY(row->curr), 1.0);
+ gtk_widget_set_sensitive(row->curr, FALSE);
+ gtk_widget_show(row->curr);
+ gtk_table_attach(GTK_TABLE(table), row->curr,
+ col, col + 1, resource, resource + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+}
+
+/** Set the sensitivity of the row, and update the assets when applicable */
+static void set_row_sensitive(TradeRow * row)
+{
+ gtk_widget_set_sensitive(row->chk,
+ resource_asset(row->resource) > 0);
+}
+
+/** Actions before a domestic trade is performed */
+void trade_perform_domestic(G_GNUC_UNUSED gint player_num,
+ gint partner_num, gint quote_num,
+ const gint * they_supply,
+ const gint * they_receive)
+{
+ cb_trade(partner_num, quote_num, they_supply, they_receive);
+}
+
+/** Actions after a domestic trade is performed */
+void frontend_trade_domestic(gint partner_num, gint quote_num,
+ G_GNUC_UNUSED const gint * we_supply,
+ G_GNUC_UNUSED const gint * we_receive)
+{
+ quote_view_remove_quote(QUOTEVIEW(quoteview), partner_num,
+ quote_num);
+ trade_update();
+}
+
+/** Actions before a maritime trade is performed */
+void trade_perform_maritime(gint ratio, Resource supply, Resource receive)
+{
+ cb_maritime(ratio, supply, receive);
+}
+
+/** Actions after a maritime trade is performed */
+void frontend_trade_maritime(G_GNUC_UNUSED gint ratio,
+ G_GNUC_UNUSED Resource we_supply,
+ G_GNUC_UNUSED Resource we_receive)
+{
+ quote_view_clear_selected_quote(QUOTEVIEW(quoteview));
+ trade_update();
+}
+
+/** Add a quote from a player */
+void trade_add_quote(gint player_num,
+ gint quote_num, const gint * supply,
+ const gint * receive)
+{
+ quote_view_add_quote(QUOTEVIEW(quoteview), player_num, quote_num,
+ supply, receive);
+}
+
+void trade_delete_quote(gint player_num, gint quote_num)
+{
+ quote_view_remove_quote(QUOTEVIEW(quoteview), player_num,
+ quote_num);
+}
+
+/** A player has rejected the trade. Removes all quotes, and adds a reject
+ * notification.
+ */
+void trade_player_finish(gint player_num)
+{
+ quote_view_reject(QUOTEVIEW(quoteview), player_num);
+}
+
+/** The trade is finished, hide the page */
+void trade_finish(void)
+{
+ quote_view_finish(QUOTEVIEW(quoteview));
+ gui_show_trade_page(FALSE);
+}
+
+/** Start a new trade */
+void trade_begin(void)
+{
+ gint idx;
+
+ quote_view_begin(QUOTEVIEW(quoteview));
+
+ for (idx = 0; idx < G_N_ELEMENTS(we_supply_rows); idx++) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (we_supply_rows[idx].chk),
+ FALSE);
+ we_supply_rows[idx].enabled = FALSE;
+ set_row_sensitive(we_supply_rows + idx);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (we_receive_rows[idx].chk),
+ FALSE);
+ we_receive_rows[idx].enabled = FALSE;
+ active_receive_request[idx] = 0;
+ active_supply_request[idx] = 0;
+ }
+
+ if (!can_trade_domestic()) {
+ gtk_widget_hide(we_receive_frame);
+ gtk_widget_hide(call_btn);
+ gtk_widget_hide(active_quote_label);
+ } else {
+ gtk_widget_show(we_receive_frame);
+ gtk_widget_show(call_btn);
+ gtk_widget_show(active_quote_label);
+ gtk_label_set_text(GTK_LABEL(active_quote_label), "");
+ }
+ quote_view_clear_selected_quote(QUOTEVIEW(quoteview));
+ update_rows(); /* Always update */
+ gui_show_trade_page(TRUE);
+}
+
+static void quote_dblclick_cb(G_GNUC_UNUSED QuoteView * quoteview,
+ gpointer accept_btn)
+{
+ if (trade_valid_selection())
+ gtk_button_clicked(GTK_BUTTON(accept_btn));
+}
+
+static void quote_selected_cb(G_GNUC_UNUSED QuoteView * quoteview,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ update_rows();
+ frontend_gui_update();
+}
+
+/** Build the page */
+GtkWidget *trade_build_page(void)
+{
+ GtkWidget *panel_mainbox;
+ GtkWidget *vbox;
+ GtkWidget *label;
+ GtkWidget *alignment;
+ GtkWidget *table;
+ GtkWidget *bbox;
+ GtkWidget *finish_btn;
+ GtkWidget *accept_btn;
+ gint idx;
+
+ panel_mainbox = gtk_hbox_new(FALSE, 6);
+ gtk_widget_show(panel_mainbox);
+ gtk_container_set_border_width(GTK_CONTAINER(panel_mainbox), 6);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(panel_mainbox), vbox, FALSE, TRUE, 0);
+
+ label = gtk_label_new(NULL);
+ /* Frame title, trade: I want to trade these resources */
+ gtk_label_set_markup(GTK_LABEL(label), _("<b>I Want</b>"));
+ gtk_widget_show(label);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 3, 0 * 12,
+ 0);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0);
+
+ table = gtk_table_new(NO_RESOURCE, 2, FALSE);
+ gtk_widget_show(table);
+ gtk_container_add(GTK_CONTAINER(alignment), table);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 0);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 3);
+
+ for (idx = 0; idx < NO_RESOURCE; ++idx)
+ add_trade_row(table, we_receive_rows + idx, idx);
+
+ we_receive_frame = gtk_vbox_new(FALSE, 6);
+ gtk_widget_show(we_receive_frame);
+ gtk_box_pack_start(GTK_BOX(vbox), we_receive_frame, FALSE, TRUE,
+ 0);
+
+ label = gtk_label_new(NULL);
+ /* Frame title, trade: I want these resources in return */
+ gtk_label_set_markup(GTK_LABEL(label), _("<b>Give Them</b>"));
+ gtk_widget_show(label);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(we_receive_frame), label, FALSE, TRUE,
+ 0);
+
+ alignment = gtk_alignment_new(0.0, 0.0, 0.0, 0.0);
+ gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 3, 0 * 12,
+ 0);
+ gtk_widget_show(alignment);
+ gtk_box_pack_start(GTK_BOX(we_receive_frame), alignment, FALSE,
+ FALSE, 0);
+
+ table = gtk_table_new(NO_RESOURCE, 2, FALSE);
+ gtk_widget_show(table);
+ gtk_container_add(GTK_CONTAINER(alignment), table);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 0);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 3);
+
+ for (idx = 0; idx < NO_RESOURCE; ++idx)
+ add_trade_row(table, we_supply_rows + idx, idx);
+
+ bbox = gtk_hbutton_box_new();
+ gtk_widget_show(bbox);
+ gtk_box_pack_start(GTK_BOX(we_receive_frame), bbox, FALSE, TRUE,
+ 0);
+
+ /* Button text, trade: call for quotes from other players */
+ call_btn = gtk_button_new_with_mnemonic(_("_Call for Quotes"));
+ frontend_gui_register(call_btn, GUI_TRADE_CALL, "clicked");
+ gtk_widget_show(call_btn);
+ gtk_container_add(GTK_CONTAINER(bbox), call_btn);
+
+ vbox = gtk_vbox_new(FALSE, 6);
+ gtk_widget_show(vbox);
+ gtk_box_pack_start(GTK_BOX(panel_mainbox), vbox, TRUE, TRUE, 0);
+
+ active_quote_label = gtk_label_new("");
+ gtk_widget_show(active_quote_label);
+ gtk_misc_set_alignment(GTK_MISC(active_quote_label), 0, 0.5);
+ gtk_box_pack_start(GTK_BOX(vbox), active_quote_label,
+ FALSE, FALSE, 0);
+
+ quoteview = quote_view_new(TRUE, is_good_quote, GTK_STOCK_APPLY,
+ GTK_STOCK_CANCEL);
+ gtk_widget_show(quoteview);
+ gtk_box_pack_start(GTK_BOX(vbox), quoteview, TRUE, TRUE, 0);
+ g_signal_connect(QUOTEVIEW(quoteview), "selection-changed",
+ G_CALLBACK(quote_selected_cb), NULL);
+
+ bbox = gtk_hbutton_box_new();
+ gtk_widget_show(bbox);
+ gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
+ gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+
+ /* Button text: Trade page, accept selected quote */
+ accept_btn = gtk_button_new_with_mnemonic(_("_Accept Quote"));
+ frontend_gui_register(accept_btn, GUI_TRADE_ACCEPT, "clicked");
+ gtk_widget_show(accept_btn);
+ gtk_container_add(GTK_CONTAINER(bbox), accept_btn);
+
+ /* Button text: Trade page, finish trading */
+ finish_btn = gtk_button_new_with_mnemonic(_("_Finish Trading"));
+ frontend_gui_register(finish_btn, GUI_TRADE_FINISH, "clicked");
+ gtk_widget_show(finish_btn);
+ gtk_container_add(GTK_CONTAINER(bbox), finish_btn);
+
+ g_signal_connect(G_OBJECT(quoteview), "selection-activated",
+ G_CALLBACK(quote_dblclick_cb), accept_btn);
+
+ theme_register_callback(G_CALLBACK(trade_theme_changed));
+
+ return panel_mainbox;
+}
+
+/** A trade is performed/a new trade is possible */
+static void trade_update(void)
+{
+ gint idx;
+
+ for (idx = 0; idx < G_N_ELEMENTS(we_supply_rows); idx++) {
+ if (resource_asset(idx) == 0) {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (we_supply_rows[idx].
+ chk), FALSE);
+ we_supply_rows[idx].enabled = FALSE;
+ }
+ set_row_sensitive(we_supply_rows + idx);
+ }
+ quote_view_check_validity_of_trades(QUOTEVIEW(quoteview));
+ trade_since_selection_changed = TRUE;
+}
Added: trunk/client/help/C/Makefile.am
===================================================================
--- trunk/client/help/C/Makefile.am (rev 0)
+++ trunk/client/help/C/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,39 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# see http://developer.gnome.org/dotplan/porting/ar01s06.html
+
+figdir = images
+docname = pioneers
+lang = C
+omffile = pioneers-C.omf
+entities = legal.xml
+include $(top_srcdir)/xmldocs.make
+dist-hook: app-dist-hook
+
+# HTMLHelp is the compressed help format for Microsoft Windows
+htmlhelp: pioneers.xml
+ xmlto -m custom.xsl htmlhelp pioneers.xml
+ -/cygdrive/c/Program\ Files/HTML\ Help\ Workshop/hhc.exe htmlhelp.hhp
+ rm htmlhelp.hhp
+ rm toc.hhc
+ rm *.html
+
+html: pioneers.xml
+ xmlto -m custom.xsl html pioneers.xml
Added: trunk/client/help/C/Makefile.in
===================================================================
--- trunk/client/help/C/Makefile.in (rev 0)
+++ trunk/client/help/C/Makefile.in 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,574 @@
+# Makefile.in generated by automake 1.9.5 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 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.
+
+ at SET_MAKE@
+
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# see http://developer.gnome.org/dotplan/porting/ar01s06.html
+
+#
+# No modifications of this Makefile should be necessary.
+#
+# To use this template:
+# 1) Define: figdir, docname, lang, omffile, and entities in
+# your Makefile.am file for each document directory,
+# although figdir, omffile, and entities may be empty
+# 2) Make sure the Makefile in (1) also includes
+# "include $(top_srcdir)/xmldocs.make" and
+# "dist-hook: app-dist-hook".
+# 3) Optionally define 'entities' to hold xml entities which
+# you would also like installed
+# 4) Figures must go under $(figdir)/ and be in PNG format
+# 5) You should only have one document per directory
+# 6) Note that the figure directory, $(figdir)/, should not have its
+# own Makefile since this Makefile installs those figures.
+#
+# example Makefile.am:
+# figdir = figures
+# docname = scrollkeeper-manual
+# lang = C
+# omffile=scrollkeeper-manual-C.omf
+# entities = fdl.xml
+# include $(top_srcdir)/xmldocs.make
+# dist-hook: app-dist-hook
+#
+# About this file:
+# This file was taken from scrollkeeper_example2, a package illustrating
+# how to install documentation and OMF files for use with ScrollKeeper
+# 0.3.x and 0.4.x. For more information, see:
+# http://scrollkeeper.sourceforge.net/
+# Version: 0.1.2 (last updated: March 20, 2002)
+#
+
+#
+# No modifications of this Makefile should be necessary.
+#
+# This file contains the build instructions for installing OMF files. It is
+# generally called from the makefiles for particular formats of documentation.
+#
+# Note that you must configure your package with --localstatedir=/var
+# so that the scrollkeeper-update command below will update the database
+# in the standard scrollkeeper directory.
+#
+# If it is impossible to configure with --localstatedir=/var, then
+# modify the definition of scrollkeeper_localstate_dir so that
+# it points to the correct location. Note that you must still use
+# $(localstatedir) in this or when people build RPMs it will update
+# the real database on their system instead of the one under RPM_BUILD_ROOT.
+#
+# Note: This make file is not incorporated into xmldocs.make because, in
+# general, there will be other documents install besides XML documents
+# and the makefiles for these formats should also include this file.
+#
+# About this file:
+# This file was derived from scrollkeeper_example2, a package
+# illustrating how to install documentation and OMF files for use with
+# ScrollKeeper 0.3.x and 0.4.x. For more information, see:
+# http://scrollkeeper.sourceforge.net/
+# Version: 0.1.3 (last updated: March 20, 2002)
+#
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/omf.make $(top_srcdir)/xmldocs.make
+subdir = client/help/C
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+ADMIN_GTK_SUPPORT_FALSE = @ADMIN_GTK_SUPPORT_FALSE@
+ADMIN_GTK_SUPPORT_TRUE = @ADMIN_GTK_SUPPORT_TRUE@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AM_CFLAGS = @AM_CFLAGS@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_CLIENT_FALSE = @BUILD_CLIENT_FALSE@
+BUILD_CLIENT_TRUE = @BUILD_CLIENT_TRUE@
+BUILD_EDITOR_FALSE = @BUILD_EDITOR_FALSE@
+BUILD_EDITOR_TRUE = @BUILD_EDITOR_TRUE@
+BUILD_META_SERVER_FALSE = @BUILD_META_SERVER_FALSE@
+BUILD_META_SERVER_TRUE = @BUILD_META_SERVER_TRUE@
+BUILD_SERVER_FALSE = @BUILD_SERVER_FALSE@
+BUILD_SERVER_TRUE = @BUILD_SERVER_TRUE@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CREATE_WINDOWS_ICON_FALSE = @CREATE_WINDOWS_ICON_FALSE@
+CREATE_WINDOWS_ICON_TRUE = @CREATE_WINDOWS_ICON_TRUE@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
+DEBUGGING = @DEBUGGING@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLIB2_CFLAGS = @GLIB2_CFLAGS@
+GLIB2_LIBS = @GLIB2_LIBS@
+GLIB_DEPRECATION = @GLIB_DEPRECATION@
+GLIB_REQUIRED_VERSION = @GLIB_REQUIRED_VERSION@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GNOME2_CFLAGS = @GNOME2_CFLAGS@
+GNOME2_LIBS = @GNOME2_LIBS@
+GTK2_CFLAGS = @GTK2_CFLAGS@
+GTK2_LIBS = @GTK2_LIBS@
+GTK_DEPRECATION = @GTK_DEPRECATION@
+GTK_REQUIRED_VERSION = @GTK_REQUIRED_VERSION@
+HAVE_GNOME_FALSE = @HAVE_GNOME_FALSE@
+HAVE_GNOME_TRUE = @HAVE_GNOME_TRUE@
+HAVE_GTK2_FALSE = @HAVE_GTK2_FALSE@
+HAVE_GTK2_TRUE = @HAVE_GTK2_TRUE@
+HAVE_SCROLLKEEPER_FALSE = @HAVE_SCROLLKEEPER_FALSE@
+HAVE_SCROLLKEEPER_TRUE = @HAVE_SCROLLKEEPER_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
+RANLIB = @RANLIB@
+SCROLLKEEPER_CONFIG = @SCROLLKEEPER_CONFIG@
+SCROLLKEEPER_REQUIRED = @SCROLLKEEPER_REQUIRED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+UI_CFLAGS = @UI_CFLAGS@
+UI_LIBS = @UI_LIBS@
+USE_NLS = @USE_NLS@
+USE_WINDOWS_ICON_FALSE = @USE_WINDOWS_ICON_FALSE@
+USE_WINDOWS_ICON_TRUE = @USE_WINDOWS_ICON_TRUE@
+VERSION = @VERSION@
+WARNINGS = @WARNINGS@
+XGETTEXT = @XGETTEXT@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+ac_pt_PKG_CONFIG = @ac_pt_PKG_CONFIG@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pioneers_datadir = @pioneers_datadir@
+pioneers_localedir = @pioneers_localedir@
+pioneers_themedir = @pioneers_themedir@
+pioneers_themedir_embed = @pioneers_themedir_embed@
+pngtopnm = @pngtopnm@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+svg_renderer_height = @svg_renderer_height@
+svg_renderer_path = @svg_renderer_path@
+svg_renderer_width = @svg_renderer_width@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+whitespace_trick = @whitespace_trick@
+figdir = images
+docname = pioneers
+lang = C
+omffile = pioneers-C.omf
+entities = legal.xml
+
+# ********** Begin of section some packagers may need to modify **********
+# This variable (docdir) specifies where the documents should be installed.
+# This default value should work for most packages.
+docdir = $(datadir)/gnome/help/$(docname)/$(lang)
+
+# ********** You should not have to edit below this line **********
+xml_files = $(entities) $(docname).xml
+EXTRA_DIST = $(xml_files) $(omffile)
+CLEANFILES = omf_timestamp
+omf_dest_dir = $(datadir)/omf/@PACKAGE@
+scrollkeeper_localstate_dir = $(localstatedir)/scrollkeeper
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/xmldocs.make $(top_srcdir)/omf.make $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu client/help/C/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu client/help/C/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ $(mkdir_p) $(distdir)/../../..
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) \
+ top_distdir="$(top_distdir)" distdir="$(distdir)" \
+ dist-hook
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-data-local
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-data-hook
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-local
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ clean-local dist-hook distclean distclean-generic \
+ distclean-libtool distdir dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am \
+ install-data-hook install-data-local install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am uninstall-info-am uninstall-local
+
+
+# At some point, it may be wise to change to something like this:
+# scrollkeeper_localstate_dir = @SCROLLKEEPER_STATEDIR@
+
+omf: omf_timestamp
+
+omf_timestamp: $(omffile)
+ -for file in $(omffile); do \
+ scrollkeeper-preinstall $(docdir)/$(docname).xml $(srcdir)/$$file $$file.out; \
+ done; \
+ touch omf_timestamp
+
+install-data-hook-omf:
+ $(mkinstalldirs) $(DESTDIR)$(omf_dest_dir)
+ for file in $(omffile); do \
+ $(INSTALL_DATA) $$file.out $(DESTDIR)$(omf_dest_dir)/$$file; \
+ done
+ -scrollkeeper-update -p $(scrollkeeper_localstate_dir) -o $(DESTDIR)$(omf_dest_dir)
+
+uninstall-local-omf:
+ -for file in $(srcdir)/*.omf; do \
+ basefile=`basename $$file`; \
+ rm -f $(omf_dest_dir)/$$basefile; \
+ done
+ -rmdir $(omf_dest_dir)
+ -scrollkeeper-update -p $(scrollkeeper_localstate_dir)
+
+clean-local-omf:
+ -for file in $(omffile); do \
+ rm -f $$file.out; \
+ done
+
+all: omf
+
+$(docname).xml: $(entities)
+ -ourdir=`pwd`; \
+ cd $(srcdir); \
+ cp $(entities) $$ourdir
+
+app-dist-hook:
+ if test "$(figdir)"; then \
+ $(mkinstalldirs) $(distdir)/$(figdir); \
+ for file in $(srcdir)/$(figdir)/*.png; do \
+ basefile=`echo $$file | sed -e 's,^.*/,,'`; \
+ $(INSTALL_DATA) $$file $(distdir)/$(figdir)/$$basefile; \
+ done \
+ fi
+
+install-data-local: omf
+ $(mkinstalldirs) $(DESTDIR)$(docdir)
+ for file in $(xml_files); do \
+ cp $(srcdir)/$$file $(DESTDIR)$(docdir); \
+ done
+ if test "$(figdir)"; then \
+ $(mkinstalldirs) $(DESTDIR)$(docdir)/$(figdir); \
+ for file in $(srcdir)/$(figdir)/*.png; do \
+ basefile=`echo $$file | sed -e 's,^.*/,,'`; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(docdir)/$(figdir)/$$basefile; \
+ done \
+ fi
+
+install-data-hook: install-data-hook-omf
+
+uninstall-local: uninstall-local-doc uninstall-local-omf
+
+uninstall-local-doc:
+ -if test "$(figdir)"; then \
+ for file in $(srcdir)/$(figdir)/*.png; do \
+ basefile=`echo $$file | sed -e 's,^.*/,,'`; \
+ rm -f $(DESTDIR)$(docdir)/$(figdir)/$$basefile; \
+ done; \
+ rmdir $(DESTDIR)$(docdir)/$(figdir); \
+ fi
+ -for file in $(xml_files); do \
+ rm -f $(DESTDIR)$(docdir)/$$file; \
+ done
+ -rmdir $(DESTDIR)$(docdir)
+
+clean-local: clean-local-omf
+dist-hook: app-dist-hook
+
+# HTMLHelp is the compressed help format for Microsoft Windows
+htmlhelp: pioneers.xml
+ xmlto -m custom.xsl htmlhelp pioneers.xml
+ -/cygdrive/c/Program\ Files/HTML\ Help\ Workshop/hhc.exe htmlhelp.hhp
+ rm htmlhelp.hhp
+ rm toc.hhc
+ rm *.html
+
+html: pioneers.xml
+ xmlto -m custom.xsl html pioneers.xml
+# 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:
Added: trunk/client/help/C/images/actions.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/actions.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/brick.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/brick.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/chat.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/chat.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/client.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/client.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/connect-dialog.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/connect-dialog.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/desert.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/desert.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/develop-cards.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/develop-cards.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/discard-dialog.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/discard-dialog.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/discards.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/discards.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/field.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/field.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/forest.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/forest.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/gameover-dialog.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/gameover-dialog.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/gold.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/gold.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/grain.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/grain.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/hill.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/hill.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/identity.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/identity.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/join-private-dialog.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/join-private-dialog.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/legend-dialog.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/legend-dialog.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/lumber.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/lumber.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/map.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/map.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/messages.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/messages.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/monopoly-dialog.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/monopoly-dialog.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/mountain.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/mountain.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/ore.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/ore.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/pasture.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/pasture.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/place-robber.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/place-robber.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/player-summary.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/player-summary.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/plenty-dialog.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/plenty-dialog.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/quote.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/quote.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/resources.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/resources.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/sea.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/sea.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/server-create.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/server-create.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/servers-dialog.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/servers-dialog.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/status.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/status.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/steal-from.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/steal-from.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/trade.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/trade.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/images/wool.png
===================================================================
(Binary files differ)
Property changes on: trunk/client/help/C/images/wool.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: trunk/client/help/C/legal.xml
===================================================================
--- trunk/client/help/C/legal.xml (rev 0)
+++ trunk/client/help/C/legal.xml 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,6 @@
+<legalnotice>
+ <para>
+ This document can be freely redistributed according to the
+ terms of the GNU General Public License.
+ </para>
+</legalnotice>
Added: trunk/client/help/C/pioneers-C.omf
===================================================================
--- trunk/client/help/C/pioneers-C.omf (rev 0)
+++ trunk/client/help/C/pioneers-C.omf 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,33 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE omf PUBLIC "-//OMF//DTD Scrollkeeper OMF Variant V1.0//EN" "http://scrollkeeper.sourceforge.net/dtds/scrollkeeper-omf-1.0/scrollkeeper-omf.dtd">
+<omf>
+ <resource>
+ <creator>
+ Dave Cole
+ </creator>
+ <creator>
+ Andy Heroff
+ </creator>
+ <title>
+ Pioneers Player's Guide
+ </title>
+ <date>
+ 2000-05-03
+ </date>
+ <version identifier="1.0" date="2003-10-07" description="Updated to full OMF format"/>
+ <subject category="GNOME|Games"/>
+ <description>
+ Pioneers is an Internet playable implementation of
+ the Settlers of Catan board game.
+ </description>
+ <type>
+ user's guide
+ </type>
+ <format mime="text/xml" dtd="-//OASIS//DTD DocBook XML V4.1.2//EN"/>
+ <identifier url="file://usr/share/gnome/help/pioneers/C/pioneers.xml"/>
+ <language code="C"/>
+<!-- for information on how Scrollkeeper uses the following relation element,
+ see http://scrollkeeper.sourceforge.net/documentation/writing_scrollkeeper_omf_files/index.html -->
+ <relation seriesid="b1c831b6-f920-11d7-9e65-963f05991571"/>
+ </resource>
+</omf>
Added: trunk/client/help/C/pioneers.xml
===================================================================
--- trunk/client/help/C/pioneers.xml (rev 0)
+++ trunk/client/help/C/pioneers.xml 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,2013 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
+<!ENTITY legal SYSTEM "legal.xml">
+]>
+<book id="index" lang="en">
+ <title>Pioneers player's guide</title>
+ <bookinfo>
+ <authorgroup>
+ <author>
+ <firstname>Dave</firstname>
+ <surname>Cole</surname>
+ </author>
+ <author>
+ <firstname>Andy</firstname>
+ <surname>Heroff</surname>
+ </author>
+ </authorgroup>
+ <authorgroup>
+ <author>
+ <firstname>Roland</firstname>
+ <surname>Clobus</surname>
+ </author>
+ </authorgroup>
+ <releaseinfo>Documentation in progress</releaseinfo>
+ <copyright>
+ <year>2000</year> <holder>Andy Heroff</holder>
+ </copyright>
+ <copyright>
+ <year>2004, 2006</year> <holder>Roland Clobus</holder>
+ </copyright>
+ &legal;
+ </bookinfo>
+
+ <part id="players">
+ <title>For players</title>
+ <preface id="introduction">
+ <title>Introduction</title>
+
+ <simplesect id="download">
+ <title>Obtaining newer versions</title>
+ <para>
+ New versions of Pioneers are regularly made available.
+ See the <ulink url="http://pio.sourceforge.net">homepage</ulink>
+ for latest version.
+ </para>
+ </simplesect>
+
+ <simplesect id="bugs">
+ <title>Reporting Bugs</title>
+ <para>
+ If you encounter a bug, report it with the bug tracker on SourceForge.
+ (<ulink url="https://sourceforge.net/tracker/?group_id=5095&atid=105095">
+ https://sourceforge.net/tracker/?group_id=5095&atid=105095
+ </ulink>). Please check first if you have the latest version.
+ </para>
+ </simplesect>
+
+ <simplesect id="Authors">
+ <title>Authors and History</title>
+ <para>
+ Pioneers is a GNOME game based upon the board game Settlers of Catan
+ created by Mayfair Games. Pioneers was originally authored by Dave
+ Cole in the spring and summer of 1999, under the name Gnocatan.
+ Dave wanted to be able to
+ play the game without having to travel, so he developed a computer
+ implementation of the game. The Pioneers project stalled in the late
+ summer of 1999 and saw little development until the early spring of
+ 2000 when the project was taken over by Andy Heroff and moved to
+ SourceForge. Andy recruited several developers (including Dave) and
+ they improved upon the original game as well as
+ fixed bugs that have been found in older versions.
+ </para>
+ <para>
+ After summer 2002 the Pioneers project lay dormant again, when
+ in summer 2003 Bas
+ Wijnen found some security bugs, and started programming new features.
+ A little later he was joined by Roland Clobus. Bas made the split
+ between the core code and the user interface, while Roland was working
+ on the user interface.
+ </para>
+ <para>
+ In June 2005 the project was renamed from Gnocatan to Pioneers.
+ </para>
+ <para>
+ To be continued...
+ </para>
+ </simplesect>
+ </preface>
+ <chapter id="pioneers_ui">
+ <title>The Pioneers user interface</title>
+
+ <para>When you start <application>Pioneers</application>, the main
+ window is displayed. The user interface is built up from a
+ number of panels.</para>
+
+ <figure id="pioneers-FIG-clientui">
+ <title>The client user interface</title>
+ <screenshot>
+ <graphic fileref="images/client.png"/>
+ </screenshot>
+ </figure>
+
+ <sect1 id="identity">
+ <title>The identity panel</title>
+
+ <para>Before you have connected to a server, this panel will not
+ be displayed. Once you have connected, the panel is painted
+ with your player color. It also shows how many roads,
+ settlements, and cities are still available to be
+ built.</para>
+
+ <para>Once the game play starts, the last dice roll performed by
+ a player is also displayed.</para>
+
+ <figure id="pioneers-FIG-identity">
+ <title>The identity panel</title>
+ <screenshot>
+ <graphic fileref="images/identity.png"/>
+ </screenshot>
+ </figure>
+ </sect1>
+
+ <sect1 id="actions">
+ <title>The actions panel</title>
+
+ <sect2 id="waiting_prompt">
+ <title>The waiting prompt</title>
+
+ <para>When it is not your turn, a message is displayed in the
+ status line at the very bottom for whom the game is waiting.</para>
+
+ </sect2>
+
+ <sect2 id="actions_buttons">
+ <title>The actions buttons</title>
+
+ <para>When it is your turn, one more more of the buttons in
+ the action toolbar are active.
+ Only the actions that you are allowed to perform will be
+ enabled.</para>
+
+ <figure id="pioneers-FIG-actions">
+ <title>The actions buttons</title>
+ <screenshot>
+ <graphic fileref="images/actions.png"/>
+ </screenshot>
+ </figure>
+
+ <table id="pioneers-TBL-actions">
+ <title>Action panel buttons</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Button</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Roll Dice</entry>
+ <entry>Roll the dice to start your turn.</entry>
+ </row>
+ <row>
+ <entry>Trade</entry>
+ <entry>Perform trade with either the bank (maritime),
+ or with other players (domestic).</entry>
+ </row>
+ <row>
+ <entry>Undo</entry>
+ <entry>You can undo road, settlement,
+ and city building that has just been performed. As
+ soon as you buy a development card, play a development
+ card, or finish your turn, you will not be able to
+ undo building.</entry>
+ </row>
+ <row>
+ <entry>Finish</entry>
+ <entry>Indicate that you have finished performing setup,
+ your turn, or road building.</entry>
+ </row>
+ <row>
+ <entry>Road</entry>
+ <entry>Build a road segment. It must join one of your own
+ settlements or cities, or one of your own roads. It can be
+ built on land or on the coast.
+ </entry>
+ </row>
+ <row>
+ <entry>Ship</entry>
+ <entry>Build a ship. It must join one of your own settlements
+ or cities at the coast, or one of your own ships.
+ It can be built on water or on the coast.
+ </entry>
+ </row>
+ <row>
+ <entry>Move Ship</entry>
+ <entry>Move a ship that is at the end of the line to another
+ place.
+ </entry>
+ </row>
+ <row>
+ <entry>Bridge</entry>
+ <entry>Build a bridge. It must join one of you own settlements
+ or cities on the coast, one of your own bridges, or a road.
+ It can only be built on water.
+ </entry>
+ </row>
+ <row>
+ <entry>Settlement</entry>
+ <entry>Build a settlement.</entry>
+ </row>
+ <row>
+ <entry>City</entry>
+ <entry>Upgrade a settlement to a city.</entry>
+ </row>
+ <row>
+ <entry>Develop</entry>
+ <entry>Purchase a development card from the bank.</entry>
+ </row>
+ <row>
+ <entry>City Wall</entry>
+ <entry>Build a wall around a city. Each city can have at most
+ one wall. For each wall you are allowed to keep two more
+ resource cards when a seven is thrown.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect2>
+
+ <sect2 id="robber_prompt">
+ <title>The robber prompt</title>
+
+ <para>If you roll 7 on the dice, all players who are holding
+ more than 7 resources will be prompted to discard half of
+ them (rounded down). While there are still players who have to
+ discard resources, the actions panel will be replaced by a list of
+ those players. Next to each player name is the number of
+ resources that they must discard.</para>
+
+ <figure id="pioneers-FIG-discards">
+ <title>The discard list</title>
+ <screenshot>
+ <graphic fileref="images/discards.png"/>
+ </screenshot>
+ </figure>
+ </sect2>
+
+ <sect2 id="place_robber_prompt">
+ <title>The place robber prompt</title>
+
+ <para>After all excess resources have been discarded, if you
+ were the player who rolled 7 on the dice, you must place the
+ robber on the map. The actions panel is replaced by a
+ prompt to that effect.</para>
+
+ <para>When you play a soldier development card, you must place
+ the robber on the map. The actions panel is replaced by a
+ prompt to that effect.</para>
+
+ <figure id="pioneers-FIG-place-robber">
+ <title>The place robber prompt</title>
+ <screenshot>
+ <graphic fileref="images/place-robber.png"/>
+ </screenshot>
+ </figure>
+ </sect2>
+
+ <sect2 id="steal_prompt">
+ <title>The steal from prompt</title>
+
+ <para>If you ever place the robber on a hex which has
+ buildings owned by more than one other player, and more than
+ one of them is holding resources, you will need to select
+ the player from which you wish to steal resources. The
+ actions panel will be replaced by a prompt which instructs
+ you to chose the victim of the robber by selecting one of
+ the buildings on the hex.</para>
+
+ <figure id="pioneers-FIG-steal-from">
+ <title>The steal from prompt</title>
+ <screenshot>
+ <graphic fileref="images/steal-from.png"/>
+ </screenshot>
+ </figure>
+ </sect2>
+ </sect1>
+
+ <sect1 id="resources">
+ <title>The resources panel</title>
+
+ <para>As the game progresses you will accumulate resources. The
+ resources panel displays how many of each resource type you
+ are holding.</para>
+
+ <figure id="pioneers-FIG-resources">
+ <title>The resources panel</title>
+ <screenshot>
+ <graphic fileref="images/resources.png"/>
+ </screenshot>
+ </figure>
+ </sect1>
+
+ <sect1 id="develop-cards">
+ <title>The development cards panel</title>
+
+ <para>If you spend the right combination of resources, you can
+ purchase development cards from the bank. All of the
+ development cards that you are currently holding are displayed
+ in this list. Note that any cards in this list are not yet in
+ play. Other players only know how many development cards you
+ are holding, not the types of those cards. Once you play a
+ development card, it will be removed from this list.</para>
+
+ <figure id="pioneers-FIG-develop-cards">
+ <title>The development cards panel</title>
+ <screenshot>
+ <graphic fileref="images/develop-cards.png"/>
+ </screenshot>
+ </figure>
+ </sect1>
+
+ <sect1 id="player-summary">
+ <title>The player summary panel</title>
+
+ <para>This panel contains a summary of public statistics about
+ all players in the game. Some of the rows in the summary have
+ a number displayed on the right. This number represents the
+ number of victory points that have been earned by that
+ statistic.</para>
+
+ <para>If the panel grows too large to fit in the available
+ space, it will automatically scroll to display the summary
+ about the current player.</para>
+
+ <figure id="pioneers-FIG-player-summary">
+ <title>The player summary panel</title>
+ <screenshot>
+ <graphic fileref="images/player-summary.png"/>
+ </screenshot>
+ </figure>
+ </sect1>
+
+ <sect1 id="map">
+ <title>The Pioneers map</title>
+
+ <figure id="pioneers-FIG-map">
+ <title>The Pioneers map</title>
+ <screenshot>
+ <graphic fileref="images/map.png"/>
+ </screenshot>
+ </figure>
+
+ <para>Pioneers is played on a map which is built up from a grid
+ of terrain hexes. Each hex on the map has a terrain type
+ which defines the resources, if any, that are produced by that
+ hex.</para>
+
+ <para>Settlements and cities are built on the corners of land
+ hexes, while roads are built along the edges of land
+ hexes.</para>
+
+ <para>In the center of resource producing hexes, there is a
+ circle containing a number. At the start of each turn, two
+ dice are rolled, all hexes that are labeled with a number
+ equaling the sum of the two dice will produce resources for
+ buildings on that hex. Underneath the number in the circle
+ are some dots. The number of dots is equal to the number of
+ different dice combinations that will generate this number.
+ To highlight the two most commonly rolled numbers, the 6 and 8
+ are displayed in red (there is no label with the number 7).
+ In addition, the hexes that produced resources this turn are
+ painted with a green background.</para>
+
+ <para>The sea hexes which have a circle in them have building
+ sites for ports where maritime trading can be performed. The
+ location of the building sites is indicated by a dashed line
+ drawn from the circle to a hex corner. The image in the circle
+ indicates the resource type which may be traded at the ports.
+ At the blue circles all resource types can be traded.</para>
+
+ <para>The brown bottle shape is the robber.</para>
+
+ <para>The following table shows each terrain type, and the resources
+ produced by that terrain.</para>
+
+ <table id="pioneers-TBL-terrain-types">
+ <title>Pioneers terrain types</title>
+ <tgroup cols="5">
+ <thead>
+ <row>
+ <entry>Graphic</entry>
+ <entry>Terrain</entry>
+ <entry>Graphic</entry>
+ <entry>Resource</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>
+ <inlinegraphic fileref="images/hill.png"/>
+ </entry>
+ <entry>Hill</entry>
+ <entry>
+ <inlinegraphic fileref="images/brick.png"/>
+ </entry>
+ <entry>Brick</entry>
+ <entry>Bricks are produced from the clay found in
+ hills.</entry>
+ </row>
+ <row>
+ <entry>
+ <inlinegraphic fileref="images/field.png"/>
+ </entry>
+ <entry>Field</entry>
+ <entry>
+ <inlinegraphic fileref="images/grain.png"/>
+ </entry>
+ <entry>Grain</entry>
+ <entry>Grain is produced by crops grown in
+ fields.</entry>
+ </row>
+ <row>
+ <entry>
+ <inlinegraphic fileref="images/mountain.png"/>
+ </entry>
+ <entry>Mountain</entry>
+ <entry>
+ <inlinegraphic fileref="images/ore.png"/>
+ </entry>
+ <entry>Ore</entry>
+ <entry>Ore is produced by quarries in mountains.</entry>
+ </row>
+ <row>
+ <entry>
+ <inlinegraphic fileref="images/pasture.png"/>
+ </entry>
+ <entry>Pasture</entry>
+ <entry>
+ <inlinegraphic fileref="images/wool.png"/>
+ </entry>
+ <entry>Wool</entry>
+ <entry>Wool is produced by sheep in pastures.</entry>
+ </row>
+ <row>
+ <entry>
+ <inlinegraphic fileref="images/forest.png"/>
+ </entry>
+ <entry>Forest</entry>
+ <entry>
+ <inlinegraphic fileref="images/lumber.png"/>
+ </entry>
+ <entry>Lumber</entry>
+ <entry>Lumber is produced by trees in forests.</entry>
+ </row>
+ <row>
+ <entry>
+ <inlinegraphic fileref="images/gold.png"/>
+ </entry>
+ <entry>Gold mine</entry>
+ <entry/>
+ <entry>Any</entry>
+ <entry>Any resource can be bought from the mined gold.</entry>
+ </row>
+ <row>
+ <entry>
+ <inlinegraphic fileref="images/desert.png"/>
+ </entry>
+ <entry>Desert</entry>
+ <entry/>
+ <entry/>
+ <entry>No resources are produced in the desert.</entry>
+ </row>
+ <row>
+ <entry>
+ <inlinegraphic fileref="images/sea.png"/>
+ </entry>
+ <entry>Sea</entry>
+ <entry/>
+ <entry/>
+ <entry>No resources are produced in the sea, but
+ maritime trading may be performed at ports.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+
+ <sect1 id="chat">
+ <title>The chat panel</title>
+
+ <para>Underneath the map is a field where you can enter
+ messages that will be broadcast to all other players. When
+ you type a message and press <keycap>Return</keycap>, the
+ message will be broadcast to all players.</para>
+
+ <figure id="pioneers-FIG-chat">
+ <title>The chat panel</title>
+ <screenshot>
+ <graphic fileref="images/chat.png"/>
+ </screenshot>
+ </figure>
+
+ <para>Normally, text that you type will appear with your player
+ name, for example "<computeroutput>player1 said:
+ foo</computeroutput>". If you start your text with
+ "<userinput>:</userinput>" the output will omit the "said",
+ like "<computeroutput>player1 needs more
+ lumber</computeroutput>".</para>
+
+ <para>The chat also knows some special commands that start with
+ "<userinput>/</userinput>". The commands currently defined are:
+ <table id="pioneers-TBL-chatcommands">
+ <title>Chat Commands</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Command</entry>
+ <entry>Arguments</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><userinput>;</userinput></entry>
+ <entry>chat message</entry>
+ <entry>The chat message is added directly behind the name of
+ the player.
+ Example: <userinput>;'s victory is imminent</userinput>
+ will become <quote>player name's victory is imminent</quote>
+ </entry>
+ </row>
+ <row>
+ <entry><userinput>:</userinput></entry>
+ <entry>chat message</entry>
+ <entry>The chat message is added after the name of the player
+ with a space in between.
+ Example: <userinput>:needs lumber</userinput> will become
+ <quote>player name needs lumber</quote>
+ </entry>
+ </row>
+ <row>
+ <entry><userinput>/me</userinput></entry>
+ <entry>chat message</entry>
+ <entry>This is the same as the
+ "<userinput>:</userinput>" described above, but IRC
+ addicts might prefer this variant.</entry>
+ </row>
+ <row>
+ <entry><userinput>/beep</userinput></entry>
+ <entry><replaceable>player name</replaceable></entry>
+ <entry>Let <replaceable>player name</replaceable>'s client
+ beep.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ <para>If you want to send a smiley that starts with a <symbol>:</symbol>
+ or <symbol>;</symbol>, type a <symbol>space</symbol> before the smiley.
+ </para>
+ </sect1>
+
+ <sect1 id="messages">
+ <title>The messages panel</title>
+
+ <para>Underneath the chat panel is a message area where all
+ interesting game events are logged.</para>
+
+ <figure id="pioneers-FIG-messages">
+ <title>The messages panel</title>
+ <screenshot>
+ <graphic fileref="images/messages.png"/>
+ </screenshot>
+ </figure>
+ </sect1>
+
+ <sect1 id="statusbar">
+ <title>The status bar</title>
+
+ <para>The status bar is used for providing instructions about
+ the current state of the game.</para>
+
+ <para>To the right of the instructional message is an indicator
+ which shows when the client program is waiting for response to
+ a command sent to the server. When packets are dropped
+ between the server and client, the indicator will display the
+ text "Waiting", and the game will be temporarily
+ unresponsive.</para>
+
+ <para>Rightmost in the status bar is the turn indicator. This
+ area identifies the player turn sequence. The current player
+ is highlighted with a thick black border.</para>
+
+ <figure id="pioneers-FIG-status">
+ <title>The status bar</title>
+ <screenshot>
+ <graphic fileref="images/status.png"/>
+ </screenshot>
+ </figure>
+ </sect1>
+ </chapter>
+
+ <chapter id="playing">
+ <title>Playing Pioneers</title>
+
+ <sect1 id="joining">
+ <title>Joining a Pioneers game</title>
+
+ <para>The Pioneers client program is
+ "<application>pioneers</application>". When you run this
+ program, you will be presented with the connect dialog.</para>
+
+ <sect2 id="connect-dialog">
+ <title>The connect dialog</title>
+
+ <para>Using the connect dialog, you identify the game which
+ you wish to join. This dialog is automatically invoked when
+ you start Pioneers. If the initial
+ connection fails, you can invoke the dialog from the
+ <guimenu>Game</guimenu>/<guimenuitem>New game</guimenuitem>
+ menu, or by using the
+ <keycombo><keycap>Ctrl</keycap><keycap>N</keycap></keycombo>
+ keyboard shortcut.</para>
+
+ <figure id="pioneers-FIG-connect-dialog">
+ <title>The connect dialog</title>
+ <screenshot>
+ <graphic fileref="images/connect-dialog.png"/>
+ </screenshot>
+ </figure>
+
+ <para>Enter your name, and join an existing game or create a
+ new game.</para>
+
+ <para>Only if <application>pioneers-server-gtk</application> is
+ installed, you can create new games.</para>
+ </sect2>
+
+ <sect2 id="server-dialog">
+ <title>Join public game</title>
+
+ <para>The dialog displays a list of Pioneers games
+ that are currently running on the Internet. The default
+ meta server is <symbol>pioneers.debian.net</symbol></para>
+
+ <figure id="pioneers-FIG-servers-dialog">
+ <title>The Join a public game dialog</title>
+ <screenshot>
+ <graphic fileref="images/servers-dialog.png"/>
+ </screenshot>
+ </figure>
+
+ <para>You join a game by selecting it and pressing the OK
+ button in the connect dialog. To obtain an updated list, push
+ the Refresh button.</para>
+
+ <para>Enter the 'Lobby' to meet other players and arrange that
+ one player will start the server with the game you've agreed
+ upon.</para>
+
+ <para>Some meta servers also allow you to start new games
+ on their host (e.g. <symbol>pioneers.game-host.org</symbol>).
+ If this is possible, the New remote game button will be active
+ and will bring you to the Create a public game dialog.</para>
+
+ </sect2>
+
+ <sect2 id="server-create-dialog">
+ <title>The Create a public game dialog</title>
+
+ <para>In this dialog, you can select various parameters for
+ the new game: board name (available types will be retrieved
+ from the meta-server), the number of players, victory points
+ to reach, how many computer players should join the game,
+ which sevens rule to apply and whether the terrain should be
+ randomized.</para>
+
+ <figure id="pioneers-FIG-server-create">
+ <title>The Create a public game dialog</title>
+ <screenshot>
+ <graphic fileref="images/server-create.png"/>
+ </screenshot>
+ </figure>
+
+ <para>Once you're satisfied with your choices, press the OK
+ button. The game will be started once enough players have
+ entered the game. The new game will of course be
+ registered to the meta server it was started from. Other players
+ can see it in the list if they press the Join public game button,
+ or refresh the list of public games.</para>
+
+ <para>The server started remotely will terminate itself
+ automatically when the game is finished, or if sits around for
+ more than 20 minutes without any connected players. Please
+ also note that adding computer players will silently fail if the
+ <application>pioneersai</application> program is not installed
+ on the meta server.</para>
+
+ </sect2>
+
+ <sect2>
+ <title>Join private game</title>
+ <para>You can manually specify the game that you wish to join
+ by entering the server host and port in the Server Host and
+ Server Port fields. The hostname/port combinations you used
+ recently are remembered. You can recall them quickly with the Recent
+ Games button at the bottom.</para>
+ <figure id="pioneers-FIG-join-private-game">
+ <title>The Join a private game dialog</title>
+ <screenshot>
+ <graphic fileref="images/join-private-dialog.png"/>
+ </screenshot>
+ </figure>
+
+ </sect2>
+ </sect1>
+
+ <sect1 id="setup">
+ <title>Pioneers setup phase</title>
+
+ <para>Once you have successfully connected to a Pioneers game
+ server, the game map will be downloaded from the server and
+ displayed in the map area of the display. You will be
+ assigned a player color, which will be displayed in the
+ identity panel, the player summary, and in the status bar. As
+ soon as all other players have connected to the server, the
+ setup phase will begin.</para>
+
+ <para>During the setup phase you must build one settlement and
+ one road segment on the map. The settlement can be built on
+ any land hex, and the road must be built on a land edge
+ connected to the settlement.</para>
+
+ <para>Once you have built both your settlement and road, you
+ must press the Finish Setup button. The next player will then
+ enter the setup phase. The last player performs a double
+ setup, that is, they build two settlements, each with a
+ connecting road. Once the last player has completed setup,
+ all other players perform a second setup in reverse
+ sequence.</para>
+
+ <para>Once the first player has completed their second setup,
+ the game will begin.</para>
+ </sect1>
+
+ <sect1 id="turn">
+ <title>Pioneers turn sequence</title>
+
+ <para>When it is your turn, the actions panel will show all of
+ the actions that you can perform. Some care must be
+ exercised, as some actions can only be performed once per
+ turn, and other actions can only be performed in strict
+ sequence.</para>
+
+ <procedure id="pioneers-turn-sequence">
+ <title>Simplified turn sequence</title>
+ <step>
+ <para>Roll the dice.</para>
+ </step>
+ <step>
+ <para>Optionally trade with the bank, or other
+ players.</para>
+ </step>
+ <step>
+ <para>Optionally build roads, settlements, and cities.
+ Optionally buy development cards.</para>
+ </step>
+ <step>
+ <para>Finish your turn.</para>
+ </step>
+ </procedure>
+
+ <para>You may play one non-victory point development card at any
+ time during your turn, even before you roll the dice. You
+ may play as many victory point cards as you like at any time
+ during your turn.</para>
+
+ <para>As soon as you have built a road, settlement, or city, you
+ will not be able to trade for the rest of the turn. Likewise,
+ if you buy a development card, you will not be able to trade
+ for the rest of the turn.</para>
+
+ <sect2 id="pioneers-dice-roll">
+ <title>Dice roll / resource collection</title>
+
+ <para>When the dice are rolled, they are added together,
+ the total determines the resources that each player collects
+ during that turn. In the center of each land hex (except
+ for the desert) is a number. Whenever the dice roll matches
+ the number in the hex, all buildings on the corners of that
+ hex will collect resources of the type generated by that
+ hex.</para>
+
+ <para>Settlements collect one resource, and cities receive two
+ resources. If a player has multiple buildings on a hex,
+ each of those buildings will collect resources.</para>
+
+ <para>The hex containing the robber never generates
+ resources.</para>
+
+ <para>If you roll 7 on the dice, all players with excess
+ resources must discard them, then you must move the
+ robber.</para>
+ </sect2>
+
+ <sect2 id="discarding_resources">
+ <title>Discarding resources</title>
+
+ <para>If you roll 7 on the dice, all players holding more than
+ 7 resources must discard half of them. The discard
+ resources dialog will be displayed for all players who must
+ discard.</para>
+
+ <figure id="pioneers-FIG-discard-dialog">
+ <title>The discard dialog</title>
+ <screenshot>
+ <graphic fileref="images/discard-dialog.png"/>
+ </screenshot>
+ </figure>
+
+ <para>You must choose the resources to be given back to the
+ bank.</para>
+
+ <para>Once all players have discarded their excess resources,
+ the player who rolled the 7 will have to move the
+ robber.</para>
+ </sect2>
+
+ <sect2 id="moving_robber">
+ <title>Moving the robber</title>
+
+ <para>The robber begins the game in the desert, but can never
+ be moved back into the desert.</para>
+
+ <para>If you roll 7 on the dice, you must move the robber to a
+ new location on the map.</para>
+
+ <para>Whenever you play a soldier development card, you must
+ move the robber to a new location on the map.</para>
+
+ <para>Once you have moved the robber to a new hex, the robber
+ will steal a random resource from another player who has a
+ building on that hex. If there are multiple potential
+ victims for the robber, you will need to choose the victim
+ by selecting one of the buildings on the hex. When the
+ robber steals the resource, only the players involved in the
+ transaction will be told which resource was stolen.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="trade">
+ <title>Trade</title>
+
+ <para>You may trade resources only after you have rolled the
+ dice, but before you build anything, or buy a development
+ card. When you wish to trade resources, press the Trade
+ button in the actions panel and the trade interface will be
+ displayed.</para>
+
+ <figure id="pioneers-FIG-trade">
+ <title>The trade interface</title>
+ <screenshot>
+ <graphic fileref="images/trade.png"/>
+ </screenshot>
+ </figure>
+
+ <para>On the left side of the interface are two tables; the
+ top table is where you specify which resources you wish to
+ receive in a trade, and the bottom table is where you
+ optionally specify which resources you wish to give to other
+ players during a trade.</para>
+
+ <para>Each row of the table describes one resource.
+ From left to right, the columns are:</para>
+
+ <table id="pioneers-TBL-resource-controls">
+ <title>Trade resource controls</title>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>Check</entry>
+ <entry>Controls whether or not this resource will be
+ involved in the trade. Trade quotes submitted by
+ either the bank or other players can only include
+ resource types that are checked.</entry>
+ </row>
+ <row>
+ <entry>Name</entry>
+ <entry>The resource type.</entry>
+ </row>
+ <row>
+ <entry>In hand</entry>
+ <entry>Shows how many of each resource type you have
+ in hand. If you select a valid trade, you see the
+ amount you will have if you accept the quote.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>The Call for Quotes button underneath the two tables is
+ used to invite other players to trade resources with
+ you.</para>
+
+ <para>To the right of the tables is the list where all quotes
+ will be displayed. The bank quotes are listed first,
+ followed by all quotes supplied by other players.
+ Next to each quote is tick or cross which indicates
+ whether or not you have the resources to perform the trade.
+ As you select quotes from the list, the Accept Quote button
+ sensitivity will also indicate whether or not you have the
+ resources required to perform the trade. Also the amount
+ of each resource shows a preview how many you will have
+ if you accept the quote.</para>
+
+ <para>To finish trading, press the Finish Trading button at
+ the bottom right of the trading interface.</para>
+
+ <sect2 id="bank_trading">
+ <title>Trading with the bank</title>
+
+ <para>Maritime trade is trade performed with the bank. To
+ perform maritime trading, check one or more resources in
+ the I Want table. If you have sufficient resources to
+ perform maritime trading, the bank will quote for each
+ possible trade. You don't have to press the Call for
+ Quotes button.</para>
+
+ <itemizedlist id="pioneers-bank-trading-procedure">
+ <listitem>
+ <para>Players who have built on a port with a resource
+ label may trade two identical resources of that type
+ for single resource of their choice.</para>
+ </listitem>
+ <listitem>
+ <para>Players who have built on a port with the question
+ mark label may trade three identical resources of any
+ type for single resource of their choice.</para>
+ </listitem>
+ <listitem>
+ <para>All players may trade four identical resources of
+ any type for a single resource of their choice.</para>
+ </listitem>
+ </itemizedlist>
+
+ <para>Select the trade that you wish to perform, then press
+ the Accept Quote button.</para>
+ </sect2>
+
+ <sect2 id="trading_players">
+ <title>Trading with other players</title>
+
+ <para>Domestic trade is trade performed with other players.
+ To perform domestic trading, check one or more resources
+ in the I Want table, and one or more resources in the Give
+ Them table. Once you have specified the resources that
+ you wish to exchange in the trade, click the Call For
+ Quotes button. All other players will then use the quote
+ interface to submit quotes within the trade parameters you
+ have set.</para>
+
+ <para>Select the trade that you wish to perform, then press
+ the Accept Quote button.</para>
+ </sect2>
+
+ <sect2 id="trade_quote_submit">
+ <title>Submitting trade quotes</title>
+
+ <para>When another player presses the Call For Quotes button
+ in the trade interface, the quote interface will be
+ displayed.</para>
+
+ <figure id="pioneers-FIG-quote">
+ <title>The quote interface</title>
+ <screenshot>
+ <graphic fileref="images/quote.png"/>
+ </screenshot>
+ </figure>
+
+ <para>The top of the interface has an indicator to show
+ which player initiated the trade. It also describes the
+ trade parameters.</para>
+
+ <para>On the left side of the interface are two tables; the
+ top table is where you specify which resources you wish to
+ receive in a trade, and the bottom table is where you
+ specify which resources you wish to give to the player who
+ initiated the trade exchange.</para>
+
+ <para>Each row of the table
+ describes one resource. The player who initiated the
+ trade controls which rows in each table can be used. If
+ the initiating player calls for a resource that you do not
+ have, the corresponding row in the Give Them table will be
+ disabled. From left to right, the columns are:</para>
+
+ <table id="pioneers-TBL-quote-controls">
+ <title>Quote resource controls</title>
+ <tgroup cols="2">
+ <tbody>
+ <row>
+ <entry>Name</entry>
+ <entry>The resource type.</entry>
+ </row>
+ <row>
+ <entry>In hand</entry>
+ <entry>Shows how many of each resource type you will
+ have in hand after performing trade.</entry>
+ </row>
+ <row>
+ <entry>Less</entry>
+ <entry>Press this to decrease the number of the
+ resource you wish to receive / give.</entry>
+ </row>
+ <row>
+ <entry>More</entry>
+ <entry>Press this to increase the number of the
+ resource you wish to receive / give.</entry>
+ </row>
+ <row>
+ <entry>Number to trade</entry>
+ <entry>Shows how many of the resource you wish to
+ trade.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <para>Underneath the tables are two buttons. Press the
+ Quote button to submit a new quote, or press the Delete
+ button to retract a quote. Note that the Quote button
+ will be disabled if you have already submitted a matching
+ quote.</para>
+
+ <para>To the right of the tables is the list where all
+ quotes will be displayed. Quotes from all players are
+ listed. The first quote from each player is highlighted
+ with an indicator.</para>
+
+ <para>To decline the offer to perform trading, press the
+ Reject Domestic Trade button at the bottom right of the
+ interface.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="development">
+ <title>Development cards</title>
+
+ <para>There are 24 development cards in the game, they are
+ shuffled at the start of the game. When you buy a development
+ card from the bank, it is held secret in your hand. Other
+ players only learn how many development cards you have, not
+ the types of those cards.</para>
+
+ <para>When you play a development card, all other players will
+ see the card. There are victory point, and non victory point
+ development cards. Victory point development cards earn you
+ one victory point as soon as you play them. Non-victory point
+ development cards have special effects as described
+ below.</para>
+
+ <table id="pioneers-TBL-development-cards">
+ <title>Development cards</title>
+ <tgroup cols="4">
+ <colspec colnum="1" align="right"/>
+ <colspec colnum="3" align="right"/>
+ <thead>
+ <row>
+ <entry>VP</entry>
+ <entry>Card</entry>
+ <entry>Number</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry/>
+ <entry>Road Building</entry>
+ <entry>2</entry>
+ <entry>When you play this card, you can build two road
+ segments for free. The normal limits on road building
+ apply.</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry>Monopoly</entry>
+ <entry>2</entry>
+ <entry>When you play this card, you choose a resource type
+ that you want to monopolize. All resources of that type
+ that are held by other players will transferred to your
+ hand.</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry>Year of Plenty</entry>
+ <entry>2</entry>
+ <entry>When you play this card you can take any two
+ resource cards from the bank.</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry>Soldier</entry>
+ <entry>13</entry>
+ <entry>When you play this card, you must move the robber
+ to a new hex. The first player to play three soldiers
+ will earn the largest army award.</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Chapel</entry>
+ <entry>1</entry>
+ <entry>No special effects.</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Pioneer University</entry>
+ <entry>1</entry>
+ <entry>No special effects.</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Governors House</entry>
+ <entry>1</entry>
+ <entry>No special effects.</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Library</entry>
+ <entry>1</entry>
+ <entry>No special effects.</entry>
+ </row>
+ <row>
+ <entry>1</entry>
+ <entry>Market</entry>
+ <entry>1</entry>
+ <entry>No special effects.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ <sect2 id="monopolydlg">
+ <title>The monopoly development card</title>
+
+ <para>When you play the monopoly development card, the
+ monopoly dialog will be displayed.</para>
+
+ <figure id="pioneers-FIG-monopoly-dialog">
+ <title>The monopoly dialog</title>
+ <screenshot>
+ <graphic fileref="images/monopoly-dialog.png"/>
+ </screenshot>
+ </figure>
+
+ <para>You must choose the resource type that you wish to
+ monopolize. When you press OK, all resources of the
+ selected type held by other players will be transferred to
+ your hand.</para>
+ </sect2>
+
+ <sect2 id="yearofplentydlg">
+ <title>The year of plenty development card</title>
+
+ <para>When you play the year of plenty development card, the
+ year of plenty dialog will be displayed.</para>
+
+ <figure id="pioneers-FIG-plenty-dialog">
+ <title>The year of plenty dialog</title>
+ <screenshot>
+ <graphic fileref="images/plenty-dialog.png"/>
+ </screenshot>
+ </figure>
+
+ <para>You must select any two resource cards that you wish to
+ take from the bank.</para>
+ <para>If the bank has enough cards, <symbol>++</symbol> is shown
+ between the less and more buttons. Otherwise, the amount in the
+ bank is shown.</para>
+ </sect2>
+
+ <sect2 id="largest_army">
+ <title>Largest army award</title>
+
+ <para>The first player to play three soldier cards will earn
+ the largest army award. This award is worth 2 victory
+ points.</para>
+
+ <para>Only one player can have the largest army award at a
+ time.</para>
+
+ <para>Ownership of the largest army award will change only
+ when another player builds a larger army.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="building">
+ <title>Building</title>
+
+ <para>By spending the right combination of resources, you can
+ build roads, settlements, and cities. At any time during the
+ game you can check the resource cost of each type of building
+ by consulting the legend dialog.</para>
+
+ <figure id="pioneers-FIG-legend-dialog">
+ <title>The legend dialog</title>
+ <screenshot>
+ <graphic fileref="images/legend-dialog.png"/>
+ </screenshot>
+ </figure>
+
+ <para>At the start of the game, you have 15 road segments, five
+ settlements, and four cities available. You will not be able
+ to build more of any item than you have available. The
+ identity panel tells you how many of each item you currently
+ have available.</para>
+
+ <para>A city is built by upgrading a settlement. When you
+ upgrade an existing settlement, that settlement is again
+ available for building somewhere else on the map.</para>
+
+ <para>Buildings must not be placed next to each other. This
+ means that a hex can have, at most, three buildings on it.
+ During game play, you can only place a building adjacent to
+ one of your road segments.</para>
+
+ <para>Roads must be placed adjacent to one of your buildings, or
+ one of your roads. You cannot extend your road through a
+ building owned by another player.</para>
+
+ <sect2 id="longest_road">
+ <title>Longest road</title>
+
+ <para>The first player to build a continuous path of five or
+ more road segments will earn the longest road award. The
+ length of your road is measured by determining the greatest
+ distance that can be traveled from one point on your road
+ to another without traveling over the same segment more
+ than once, and without backtracking.</para>
+
+ <para>This award is worth 2 victory points. Only one player
+ can have the longest road award at a time.</para>
+
+ <para>If another player builds a longer road, the longest road
+ award will be transferred to that player.</para>
+
+ <para>If the longest road is cut by a player placing a
+ building which divides the road, the ownership of the
+ longest road award is re-evaluated. If after the longest
+ road has been cut, and more than one player has the longest
+ road, the award is temporarily removed from play. If no
+ player has a road of five or more segments, the award is
+ temporarily removed from play.</para>
+ </sect2>
+ </sect1>
+
+ <sect1 id="objective">
+ <title>Game objective</title>
+
+ <para>The objective of the game is to achieve a certain number
+ of victory points before all other players. There are several
+ ways to earn victory points.</para>
+
+ <itemizedlist mark="bullet">
+ <listitem>
+ <para>For each settlement you have on the map, you earn 1
+ victory point.</para>
+ </listitem>
+ <listitem>
+ <para>For each city you have on the map, you earn 2
+ victory points.</para>
+ </listitem>
+ <listitem>
+ <para>The player with the longest road of five or more
+ segments earns 2 victory points.</para>
+ </listitem>
+ <listitem>
+ <para>The player with the largest number of soldiers in
+ play (minimum of three) earns 2 victory points.</para>
+ </listitem>
+ <listitem>
+ <para>There are a number of special development cards which
+ when played are each worth 1 victory point.</para>
+ </listitem>
+ </itemizedlist>
+
+ <sect2 id="gameoverdlg">
+ <title>The game over dialog</title>
+
+ <para>Once you have won the game, all players will to notified
+ of your glorious victory.</para>
+
+ <figure id="pioneers-FIG-gameover-dialog">
+ <title>The game over dialog</title>
+ <screenshot>
+ <graphic fileref="images/gameover-dialog.png"/>
+ </screenshot>
+ </figure>
+ </sect2>
+ </sect1>
+ </chapter>
+ <chapter id="faq">
+ <title>Frequently asked questions</title>
+ <qandaset defaultlabel="qanda">
+ <title>Playing games</title>
+ <qandaentry>
+ <question><para>
+ Where can I find games?
+ </para></question>
+ <answer><para>
+ You can find games at the metaserver (pioneers.debian.net)
+ </para></answer>
+ </qandaentry>
+ <qandaentry>
+ <question><para>
+ But there hardly are any games present?
+ </para></question>
+ <answer><para>Perhaps people don't register their games (it is optional),
+ or use their own metaservers.
+ </para></answer>
+ </qandaentry>
+ <qandaentry>
+ <question><para>
+ I've seen a game at the metaserver, but I cannot join?
+ </para></question>
+ <answer><para>
+ Is the Host something like 'localhost' or without dots?
+ In that case someone did register the game,
+ but it is not accessible from the outside of the intranet that hosts
+ the game.
+ </para></answer>
+ </qandaentry>
+ <qandaentry>
+ <question><para>
+ I get the error: <quote>Error connecting to host 'AA.BB.CC.DD':
+ Connection refused</quote>, what now?
+ </para></question>
+ <answer><para>The person hosting the game has incorrectly
+ configured his firewall. See also 'Creating games'.
+ </para></answer>
+ </qandaentry>
+ <qandaentry>
+ <question><para>
+ The button '<guibutton>New remote game</guibutton>' is always disabled.
+ Why?
+ </para></question>
+ <answer><para>
+ The metaserver at pioneers.debian.net acts only as a point where games
+ can register. It has been configured not to create new games.
+ </para></answer>
+ </qandaentry>
+ <qandaentry>
+ <question><para>
+ How can I play against the computer players, without starting a server?
+ </para></question>
+ <answer><para>
+ You can play games at an alternative metaserver
+ <quote>pioneers.game-host.org</quote>. It has a limited number
+ of games that can be started. <guibutton>New remote game</guibutton>
+ is available on this metaserver.
+ </para></answer>
+ </qandaentry>
+ </qandaset>
+ <qandaset defaultlabel="qanda">
+ <title>The Lobby</title>
+ <qandaentry>
+ <question><para>
+ Why is nobody responding?
+ </para></question>
+ <answer><para>
+ If you enter the lobby, and see several squares in the icon before
+ the name of a player, it means that that player is disconnected.
+ </para></answer>
+ <answer><para>
+ Perhaps they are playing another game, and don't monitor the Lobby.
+ </para></answer>
+ </qandaentry>
+ <qandaentry>
+ <question><para>
+ This game will never start. How can I play?
+ </para></question>
+ <answer><para>
+ One person has to create a new game. If it is set up, you can leave
+ the lobby, and join that game (<guimenu>Game</guimenu>->
+ <guimenuitem>Leave game</guimenuitem>).
+ </para></answer>
+ </qandaentry>
+ </qandaset>
+ <qandaset defaultlabel="qanda">
+ <title>Creating games</title>
+ <qandaentry>
+ <question><para>
+ How do I do create new games?
+ </para></question>
+ <answer><para>
+ Start <application>pioneers-server-gtk</application>.
+ In the <guilabel>Server Parameters</guilabel>:
+ <itemizedlist>
+ <listitem><para>
+ Choose a <guilabel>Server Port</guilabel> that is publicly
+ accessible (create a hole in your firewall if needed)
+ </para></listitem>
+ <listitem><para>
+ Set <guilabel>Register Server</guilabel> to 'yes', so other people
+ can find the game
+ </para></listitem>
+ <listitem><para>
+ Leave <guilabel>Meta Server</guilabel> empty,
+ or use 'pioneers.debian.net'
+ </para></listitem>
+ <listitem><para>
+ <guilabel>Reported hostname</guilabel> can be left empty
+ </para></listitem>
+ <listitem><para>
+ Select a game of your liking, and click on
+ <guibutton>Start Server</guibutton>
+ </para></listitem>
+ </itemizedlist>
+ </para></answer>
+ </qandaentry>
+ <qandaentry>
+ <question><para>
+ What exactly does '<guilabel>Reported hostname</guilabel>' do?
+ </para></question>
+ <answer><para>It overrides the hostname that is automatically
+ detected by the metaserver.</para>
+ <para>Only in special cases do you need to enter something:
+ <itemizedlist>
+ <listitem><para>You have an extra DNS name, and would like
+ to show that name instead of your normal DNS name.
+ </para></listitem>
+ <listitem><para>You run a private, publicly accessible metaserver,
+ and start a game from inside your local network.
+ </para></listitem>
+ </itemizedlist></para>
+ <para>In all other cases, you are advised to keep it
+ <emphasis>empty</emphasis>.</para>
+ </answer>
+ </qandaentry>
+ <qandaentry>
+ <question><para>
+ How do I configure my router?
+ </para></question>
+ <answer><para>
+ Henner Keßler wrote a small
+ <ulink url="http://people.freenet.de/aitsch/pio/howto.htm">HOWTO</ulink>
+ describing a possible way to configure your router, using dyndns.
+ </para></answer>
+ </qandaentry>
+ <qandaentry>
+ <question><para>
+ What if I only want to play against the computer players?
+ </para></question>
+ <answer><para>
+ Start <application>pioneers-server-gtk</application>,
+ and set <guilabel>Register Server</guilabel> to 'no', and add as many
+ computer players as needed.
+ In the client, choose '<guibutton>Join private game</guibutton>',
+ the host is 'localhost',
+ and use the port you have selected in the server.
+ </para></answer>
+ <answer><para>
+ You can play games at an alternative metaserver
+ <quote>pioneers.game-host.org</quote>. It has a limited number
+ of games that can be started.
+ </para></answer>
+ </qandaentry>
+ <qandaentry>
+ <question><para>
+ What if I only want to play games inside my own intranet?
+ </para></question>
+ <answer><para>
+ Do not register your game at the metaserver, and choose 'Join
+ private game' on each computer that joins the game. Use the ip address
+ of the server, and the port you have selected in the server.
+ </para></answer>
+ </qandaentry>
+ </qandaset>
+ </chapter>
+ </part>
+ <part id="gamemasters">
+ <title>For game masters</title>
+ <chapter id="ai">
+ <title>The Computer Player</title>
+
+ <para>
+ Pioneers comes with a computer player,
+ <application>pioneersai</application>.
+ This player isn't too bad at the moment, but
+ not finished yet. Most notably, it cannot initiate domestic
+ trade, and use the maritime rules yet.
+ </para>
+
+ <para>
+ <application>pioneersai</application> is a terminal application
+ without GUI. Its command line options are:
+
+ <table id="pioneers-TBL-ai-options">
+ <title><application>pioneersai</application> command line options
+ </title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Option</entry>
+ <entry>Arguments</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>-s</entry>
+ <entry><replaceable>servername</replaceable></entry>
+ <entry>Connect to <replaceable>servername</replaceable></entry>
+ </row>
+ <row>
+ <entry>-p</entry>
+ <entry><replaceable>port</replaceable></entry>
+ <entry>Connect to port <replaceable>port</replaceable></entry>
+ </row>
+ <row>
+ <entry>-n</entry>
+ <entry><replaceable>name</replaceable></entry>
+ <entry>Set the player name. If this option is absent, a
+ random name will be choosen.</entry>
+ </row>
+ <row>
+ <entry>-a</entry>
+ <entry><replaceable>playertype</replaceable></entry>
+ <entry>Choose the type of computer player. Currently, there is
+ only one type <userinput>greedy</userinput>, which is
+ obviously also the default.</entry>
+ </row>
+ <row>
+ <entry>-t</entry>
+ <entry><replaceable>milliseconds</replaceable></entry>
+ <entry>Set time to wait between turns.</entry>
+ </row>
+ <row>
+ <entry>-c</entry>
+ <entry/>
+ <entry>Stop the computer player from giving comments.</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+
+ <para>
+ However, most of the time you won't start
+ <application>pioneersai</application> manually. Both game
+ servers offer ways to start a number of computer players.
+ </para>
+
+ </chapter>
+ <chapter id="configuration">
+ <title>Configuration</title>
+ <para>
+ This chapter is included for the people who wish to control
+ exactly the way <symbol>Pioneers</symbol> is running.
+ </para>
+ <para>The extra configuration options are processed in this order:
+ <orderedlist>
+ <listitem><para>Command line</para></listitem>
+ <listitem><para>Settings file</para></listitem>
+ <listitem><para>Environment</para></listitem>
+ <listitem><para>Built-in settings</para></listitem>
+ </orderedlist>
+ </para>
+ <sect1 id="configuration-client">
+ <title><application>pioneers</application></title>
+ <para>
+ The client is controlled by the command line, the environment
+ and the settings file.
+ </para>
+
+ <table id="configuration-client-commandline">
+ <title><application>pioneers</application> command line options
+ </title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>Short</entry>
+ <entry>Long</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>-s</entry>
+ <entry>--server</entry>
+ <entry>Hostname of the server</entry>
+ </row>
+ <row>
+ <entry>-p</entry>
+ <entry>--port</entry>
+ <entry>Port of the server</entry>
+ </row>
+ <row>
+ <entry>-n</entry>
+ <entry>--name</entry>
+ <entry>Player name</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry>--language</entry>
+ <entry>Override the language as set in the environment.
+ Valid choices: de en es fr hu it nl sv
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ When both the server and port are set, the client will not display
+ the connect dialog, but will directly connect to this port.
+ When the connection is closed (because the game is over, or the
+ connection fails), the client quits.
+ </para>
+ <para>
+ Server and port need both to be set, or not at all.
+ </para>
+ <table id="configuration-client-settingsfile">
+ <title>Settings file <application>~/.config/pioneers</application></title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Section</entry>
+ <entry>Key</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>connect</entry>
+ <entry>server</entry>
+ <entry>string</entry>
+ <entry>Last used server for private game</entry>
+ </row>
+ <row>
+ <entry>connect</entry>
+ <entry>port</entry>
+ <entry>string</entry>
+ <entry>Last used port for private game</entry>
+ </row>
+ <row>
+ <entry>connect</entry>
+ <entry>meta-server</entry>
+ <entry>string</entry>
+ <entry>Address of the meta server</entry>
+ </row>
+ <row>
+ <entry>connect</entry>
+ <entry>name</entry>
+ <entry>string</entry>
+ <entry>Last used player name</entry>
+ </row>
+ <row>
+ <entry>favorites</entry>
+ <entry>server%dname</entry>
+ <entry>string</entry>
+ <entry>History entry of private server games</entry>
+ </row>
+ <row>
+ <entry>favorites</entry>
+ <entry>server%dport</entry>
+ <entry>string</entry>
+ <entry>History entry of private server games</entry>
+ </row>
+ <row>
+ <entry>settings</entry>
+ <entry>color_chat</entry>
+ <entry>boolean</entry>
+ <entry>Display chat messages in user's color</entry>
+ </row>
+ <row>
+ <entry>settings</entry>
+ <entry>color_messages</entry>
+ <entry>boolean</entry>
+ <entry>Display colors in the message log</entry>
+ </row>
+ <row>
+ <entry>settings</entry>
+ <entry>color_summary</entry>
+ <entry>boolean</entry>
+ <entry>Use colors in the summary</entry>
+ </row>
+ <row>
+ <entry>settings</entry>
+ <entry>toolbar_show_accelerators</entry>
+ <entry>boolean</entry>
+ <entry>Show the keyboard accelerators in the toolbar</entry>
+ </row>
+ <row>
+ <entry>settings</entry>
+ <entry>show_toolbar</entry>
+ <entry>boolean</entry>
+ <entry>Show the toolbar</entry>
+ </row>
+ <row>
+ <entry>settings</entry>
+ <entry>legend_page</entry>
+ <entry>boolean</entry>
+ <entry>Display the legend page beside the map</entry>
+ </row>
+ <row>
+ <entry>settings</entry>
+ <entry>theme</entry>
+ <entry>string</entry>
+ <entry>The theme</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table id="configuration-client-environment">
+ <title><application>pioneers</application> environment</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>PIONEERS_META_SERVER</entry>
+ <entry>The host name of the meta server</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ When the host name is not provided in the client, this environment
+ variable will be used. If it is not set, the default
+ (<symbol>pioneers.debian.net</symbol>) will be used.
+ </para>
+ </sect1>
+ <sect1 id="configuration-server">
+ <title><application>pioneers-server-console</application></title>
+ <table id="configuration-server-console-commandline">
+ <title><application>pioneers-server-console</application>
+ command line</title>
+ <tgroup cols="3">
+ <thead>
+ <row>
+ <entry>M</entry>
+ <entry>Short</entry>
+ <entry>Long</entry>
+ <entry>Type</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry/>
+ <entry>-h</entry>
+ <entry>--help-all</entry>
+ <entry/>
+ <entry>Show help</entry>
+ </row>
+ <row>
+ <entry>*</entry>
+ <entry>-r</entry>
+ <entry>--register</entry>
+ <entry/>
+ <entry>Register with meta-server</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry>-m</entry>
+ <entry>--meta-server</entry>
+ <entry>string</entry>
+ <entry>Register at meta-server name (implies -r)</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry>-n</entry>
+ <entry>--hostname</entry>
+ <entry>string</entry>
+ <entry>Use this hostname when registering at the meta-server</entry>
+ </row>
+ <row>
+ <entry>*</entry>
+ <entry>-x</entry>
+ <entry>--auto-quit</entry>
+ <entry/>
+ <entry>Quit after a player has won</entry>
+ </row>
+ <row>
+ <entry>*</entry>
+ <entry>-k</entry>
+ <entry>--empty-timeout</entry>
+ <entry>integer</entry>
+ <entry>Kill after <symbol>n</symbol> seconds with no player</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry>-t</entry>
+ <entry>--tournament</entry>
+ <entry>integer</entry>
+ <entry>Tournament mode. Computer players are added after %d minutes</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry>-a</entry>
+ <entry>--admin-port</entry>
+ <entry>integer</entry>
+ <entry>Admin port to listen on</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry>-s</entry>
+ <entry>--admin-wait</entry>
+ <entry/>
+ <entry>Don't start game immediately, wait for command on admin port</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry/>
+ <entry>--fixed-seating-order</entry>
+ <entry/>
+ <entry>Give players numbers according to the order they enter
+ the game</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry/>
+ <entry>--debug</entry>
+ <entry/>
+ <entry>Enable debug messages</entry>
+ </row>
+ <row>
+ <entry>*</entry>
+ <entry>-g</entry>
+ <entry>--game-title</entry>
+ <entry>string</entry>
+ <entry>Game name to use</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry/>
+ <entry>--file</entry>
+ <entry>string</entry>
+ <entry>Game file to use</entry>
+ </row>
+ <row>
+ <entry>*</entry>
+ <entry>-p</entry>
+ <entry>--port</entry>
+ <entry>string</entry>
+ <entry>Port to listen on</entry>
+ </row>
+ <row>
+ <entry>*</entry>
+ <entry>-P</entry>
+ <entry>--players</entry>
+ <entry>integer</entry>
+ <entry>Number of players</entry>
+ </row>
+ <row>
+ <entry>*</entry>
+ <entry>-v</entry>
+ <entry>--point</entry>
+ <entry>integer</entry>
+ <entry>Number of points needed to win</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry>-R</entry>
+ <entry>--seven-rule</entry>
+ <entry>0|1|2</entry>
+ <entry>Seven rule</entry>
+ </row>
+ <row>
+ <entry>*</entry>
+ <entry>-T</entry>
+ <entry>--terrain</entry>
+ <entry>0|1</entry>
+ <entry>Select terrain type (0=default, 1=random)</entry>
+ </row>
+ <row>
+ <entry>*</entry>
+ <entry>-c</entry>
+ <entry>--computer-players</entry>
+ <entry>integer</entry>
+ <entry>Number of computer players to add</entry>
+ </row>
+ <row>
+ <entry/>
+ <entry/>
+ <entry>--version</entry>
+ <entry/>
+ <entry>Show version information</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ The column 'M' shows whether the switch is used by the meta-server
+ </para>
+ <table id="configuration-server-console-environment">
+ <title><application>pioneers-server-console</application>
+ environment</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Variable</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>PIONEERS_DIR</entry>
+ <entry>The location of the *.game files</entry>
+ </row>
+ <row>
+ <entry>PIONEERS_META_SERVER</entry>
+ <entry>The host name of the meta server</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </sect1>
+ <sect1 id="server-admin-interface">
+ <title>Server admin interface protocol</title>
+ <para>
+ When the server is started with the command line switch
+ <userinput>-a</userinput>, the following commands can be
+ sent to that port:
+ </para>
+ <table id="configuration-server-console-admin">
+ <title>Admin interface commands</title>
+ <tgroup cols="2">
+ <thead>
+ <row>
+ <entry>Command</entry>
+ <entry>Argument type</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry><userinput>admin set-game</userinput></entry>
+ <entry>string</entry>
+ </row>
+ <row>
+ <entry><userinput>admin set-register-server</userinput></entry>
+ <entry>integer</entry>
+ </row>
+ <row>
+ <entry><userinput>admin set-num-players</userinput></entry>
+ <entry>integer</entry>
+ </row>
+ <row>
+ <entry><userinput>admin set-sevens-rule</userinput></entry>
+ <entry>integer</entry>
+ </row>
+ <row>
+ <entry><userinput>admin set-victory-points</userinput></entry>
+ <entry>integer</entry>
+ </row>
+ <row>
+ <entry><userinput>admin set-random-terrain</userinput></entry>
+ <entry>integer</entry>
+ </row>
+ <row>
+ <entry><userinput>admin set-port</userinput></entry>
+ <entry>integer</entry>
+ </row>
+ <row>
+ <entry><userinput>admin start-server</userinput></entry>
+ <entry>none</entry>
+ </row>
+ <row>
+ <entry><userinput>admin stop-server</userinput></entry>
+ <entry>none</entry>
+ </row>
+ <row>
+ <entry><userinput>admin quit</userinput></entry>
+ <entry>none</entry>
+ </row>
+ <row>
+ <entry><userinput>admin send-message</userinput></entry>
+ <entry>string</entry>
+ </row>
+ <row>
+ <entry><userinput>admin help</userinput></entry>
+ <entry>none</entry>
+ </row>
+ <row>
+ <entry><userinput>admin info</userinput></entry>
+ <entry>none</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <para>
+ <userinput>admin set-game</userinput> should be used before the
+ other game parameters are changed, because it changes all game
+ parameters.
+ </para>
+ <note><para>
+ If a game was running while a game parameter is changed,
+ it will be aborted.
+ </para></note>
+ <para>
+ When no game is running when <userinput>admin quit</userinput>
+ is issued, the server will quit.
+ </para>
+ </sect1>
+ </chapter>
+ </part>
+</book>
Added: trunk/client/help/Makefile.am
===================================================================
--- trunk/client/help/Makefile.am (rev 0)
+++ trunk/client/help/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,23 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# I don't know enough about the po build system, so I'll use a recursive
+# make for it.
+SUBDIRS += client/help/C
Added: trunk/common/Makefile.am
===================================================================
--- trunk/common/Makefile.am (rev 0)
+++ trunk/common/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,85 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+# Copyright (C) 2004 Roland Clobus <rclobus at bigfoot.com>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+noinst_LIBRARIES += libpioneers.a
+
+if HAVE_GNOME
+include common/gtk/Makefile.am
+endif
+
+libpioneers_a_CPPFLAGS = $(console_cflags)
+
+libpioneers_a_SOURCES = \
+ common/authors.h \
+ common/buildrec.c \
+ common/buildrec.h \
+ common/cards.c \
+ common/cards.h \
+ common/common_glib.c \
+ common/common_glib.h \
+ common/cost.c \
+ common/cost.h \
+ common/driver.c \
+ common/driver.h \
+ common/game.c \
+ common/game.h \
+ common/log.c \
+ common/log.h \
+ common/map.c \
+ common/map.h \
+ common/map_query.c \
+ common/network.c \
+ common/network.h \
+ common/quoteinfo.c \
+ common/quoteinfo.h \
+ common/state.c \
+ common/state.h
+
+common/authors.h: AUTHORS
+ @mkdir_p@ common
+ echo -n "#define AUTHORLIST " > $@
+ sed -e's/ <.*//; s/$$/", \\/; s/^/"/; /^"[[:space:]]*", \\$$/d' $< >> $@
+ echo "NULL" >> $@
+
+# This target is not called common/version.h (although it builds that file),
+# because it must be PHONY, but should only be rebuilt once.
+build_version:
+ @mkdir_p@ common
+ echo -n '#define FULL_VERSION "$(VERSION)' >> common/version.new
+ if svn info > /dev/null 2>&1; then \
+ echo -n ".r`svn info | grep Revision | cut -f2 -d\ `" \
+ >> common/version.new ;\
+ if svn status | grep -vq ^\? ; then \
+ echo -n '.M' >> common/version.new ;\
+ fi ;\
+ fi
+ echo '"' >> common/version.new
+ if diff common/version.h common/version.new > /dev/null 2>&1; then \
+ rm common/version.new ;\
+ else \
+ mv common/version.new common/version.h ;\
+ fi
+
+BUILT_SOURCES += common/authors.h build_version
+CLEANFILES += common/authors.h common/version.h
+
+# always try to rebuild version.h
+.PHONY: build_version
Added: trunk/common/buildrec.c
===================================================================
--- trunk/common/buildrec.c (rev 0)
+++ trunk/common/buildrec.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,508 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <math.h>
+#include <ctype.h>
+
+#include <glib.h>
+
+#include "game.h"
+#include "map.h"
+#include "buildrec.h"
+
+/* Local function prototypes. */
+static gboolean buildrec_can_setup_edge(GList * list, Map * map,
+ const Edge * edge,
+ gboolean is_double);
+
+
+BuildRec *buildrec_new(BuildType type, gint x, gint y, gint pos)
+{
+ BuildRec *rec = g_malloc0(sizeof(*rec));
+ rec->type = type;
+ rec->x = x;
+ rec->y = y;
+ rec->pos = pos;
+ rec->special_points_id = -1;
+ return rec;
+}
+
+GList *buildrec_free(GList * list)
+{
+ while (list != NULL) {
+ BuildRec *rec = list->data;
+ list = g_list_remove(list, rec);
+ g_free(rec);
+ }
+
+ return NULL;
+}
+
+gint buildrec_count_type(GList * list, BuildType type)
+{
+ gint num = 0;
+
+ while (list != NULL) {
+ BuildRec *rec = list->data;
+ list = g_list_next(list);
+ if (rec->type == type)
+ num++;
+ }
+
+ return num;
+}
+
+gint buildrec_count_edges(GList * list)
+{
+ gint num = 0;
+
+ while (list != NULL) {
+ BuildRec *rec = list->data;
+ list = g_list_next(list);
+ if (rec->type == BUILD_ROAD
+ || rec->type == BUILD_SHIP
+ || rec->type == BUILD_BRIDGE)
+ num++;
+ }
+
+ return num;
+}
+
+BuildRec *buildrec_get(GList * list, BuildType type, gint idx)
+{
+
+ while (list != NULL) {
+ BuildRec *rec = list->data;
+ list = g_list_next(list);
+ if (rec->type == type && idx-- == 0)
+ return rec;
+ }
+
+ return NULL;
+}
+
+BuildRec *buildrec_get_edge(GList * list, gint idx)
+{
+
+ while (list != NULL) {
+ BuildRec *rec = list->data;
+ list = g_list_next(list);
+ if ((rec->type == BUILD_ROAD
+ || rec->type == BUILD_SHIP
+ || rec->type == BUILD_BRIDGE) && idx-- == 0)
+ return rec;
+ }
+
+ return NULL;
+}
+
+gboolean buildrec_is_valid(GList * list, Map * map, gint owner)
+{
+ while (list != NULL) {
+ BuildRec *rec = list->data;
+ list = g_list_next(list);
+
+ switch (rec->type) {
+ case BUILD_NONE:
+ g_warning("BUILD_NONE in buildrec_is_valid");
+ continue;
+ case BUILD_ROAD:
+ /* Roads have to be adjacent to buildings / road
+ */
+ if (!map_road_connect_ok(map, owner,
+ rec->x, rec->y, rec->pos))
+ return FALSE;
+ continue;
+ case BUILD_BRIDGE:
+ /* Bridges have to be adjacent to buildings /
+ * road, and they have to be over water.
+ */
+ if (!map_bridge_connect_ok(map, owner,
+ rec->x, rec->y,
+ rec->pos))
+ return FALSE;
+ continue;
+ case BUILD_SHIP:
+ case BUILD_MOVE_SHIP:
+ /* ships have to be adjacent to buildings /
+ * ships, and they have to be over water /
+ * coast.
+ */
+ if (!map_ship_connect_ok(map, owner,
+ rec->x, rec->y, rec->pos))
+ return FALSE;
+ continue;
+ case BUILD_SETTLEMENT:
+ case BUILD_CITY:
+ case BUILD_CITY_WALL:
+ /* Buildings must be adjacent to a road
+ */
+ if (!map_building_connect_ok(map, owner, rec->type,
+ rec->x, rec->y,
+ rec->pos))
+ return FALSE;
+ continue;
+ }
+ }
+
+ return TRUE;
+}
+
+static gboolean edge_has_place_for_settlement(const Edge * edge)
+{
+ gint idx;
+
+ for (idx = 0; idx < G_N_ELEMENTS(edge->nodes); idx++) {
+ const Node *node = edge->nodes[idx];
+ if (node->type == BUILD_NONE && is_node_on_land(node)
+ && is_node_spacing_ok(node))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Check if we can place this edge with 0 existing settlements during setup
+ */
+static gboolean can_setup_edge_0(GList * list, Map * map,
+ const Edge * edge)
+{
+ BuildRec *rec = buildrec_get_edge(list, 0);
+ Edge *other_edge;
+ int idx;
+
+ if (rec == NULL)
+ /* This is the only edge - it can only placed if one
+ * of its nodes is a legal location for a new
+ * settlement.
+ */
+ return edge_has_place_for_settlement(edge);
+
+ /* There is already one edge placed. We can only place this
+ * edge if it creates a second legal place for settlements.
+ * If I place a settlement on one of the edges, make sure
+ * there is still a place where the second settlement can be
+ * placed.
+ */
+ other_edge = map_edge(map, rec->x, rec->y, rec->pos);
+ for (idx = 0; idx < G_N_ELEMENTS(edge->nodes); idx++) {
+ Node *node = edge->nodes[idx];
+
+ if (node->type == BUILD_NONE && is_node_spacing_ok(node)) {
+ gboolean ok;
+
+ node->type = BUILD_SETTLEMENT;
+ ok = edge_has_place_for_settlement(other_edge);
+ node->type = BUILD_NONE;
+
+ if (ok)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/* Check if we can place this edge with 1 existing settlement during setup
+ */
+static gboolean can_setup_edge_1(GList * list, Map * map,
+ const Edge * edge)
+{
+ BuildRec *rec = buildrec_get(list, BUILD_SETTLEMENT, 0);
+ Node *node = map_node(map, rec->x, rec->y, rec->pos);
+ Edge *other_edge;
+
+ rec = buildrec_get_edge(list, 0);
+ if (rec == NULL)
+ /* No other edges placed yet, we can either place this
+ * edge next to the existing settlement, or somewhere
+ * which has a legal place for an additional
+ * settlement.
+ */
+ return is_edge_adjacent_to_node(edge, node)
+ || edge_has_place_for_settlement(edge);
+
+ /* This is the second edge, we must ensure that one of the
+ * edges is adjacent to the settlement, and the other has a
+ * place for the second settlement.
+ */
+ other_edge = map_edge(map, rec->x, rec->y, rec->pos);
+ return (is_edge_adjacent_to_node(edge, node)
+ && edge_has_place_for_settlement(other_edge))
+ || (is_edge_adjacent_to_node(other_edge, node)
+ && edge_has_place_for_settlement(edge));
+}
+
+/* Check if we can place this edge with 2 existing settlements during setup
+ */
+static gboolean can_setup_edge_2(GList * list, Map * map,
+ const Edge * edge)
+{
+ BuildRec *rec = buildrec_get(list, BUILD_SETTLEMENT, 0);
+ Node *node = map_node(map, rec->x, rec->y, rec->pos);
+ Node *other_node;
+ Edge *other_edge;
+
+ rec = buildrec_get(list, BUILD_SETTLEMENT, 1);
+ other_node = map_node(map, rec->x, rec->y, rec->pos);
+
+ rec = buildrec_get_edge(list, 0);
+ if (rec == NULL)
+ /* No other edges placed yet, we must place this edge
+ * next to either settlement.
+ */
+ return is_edge_adjacent_to_node(edge, node)
+ || is_edge_adjacent_to_node(edge, other_node);
+
+ /* Two settlements and one edge placed, we must make sure that
+ * we place this edge next to a settlement and both
+ * settlements then have an adjacent edge. If we have
+ * bridges, it is possible to have both settlements adjacent
+ * to a single bridge.
+ */
+ other_edge = map_edge(map, rec->x, rec->y, rec->pos);
+ if (is_edge_adjacent_to_node(other_edge, node)
+ && is_edge_adjacent_to_node(other_edge, other_node))
+ /* other_edge is a bridge connecting both settlements
+ * -> edge can connect to either settlement.
+ */
+ return is_edge_adjacent_to_node(edge, node)
+ || is_edge_adjacent_to_node(edge, other_node);
+ if (is_edge_adjacent_to_node(edge, node)
+ && is_edge_adjacent_to_node(edge, other_node)
+ && !is_edge_on_land(edge))
+ /* This edge is a bridge connecting both settlements
+ */
+ return TRUE;
+ /* No bridges -> edge must be adjacent to the settlement which
+ * other_edge is not adjacent to.
+ */
+ if (is_edge_adjacent_to_node(other_edge, other_node))
+ return is_edge_adjacent_to_node(edge, node);
+ else
+ return is_edge_adjacent_to_node(edge, other_node);
+}
+
+static gboolean buildrec_can_setup_edge(GList * list, Map * map,
+ const Edge * edge,
+ gboolean is_double)
+{
+ if (!is_double) {
+ BuildRec *rec = buildrec_get(list, BUILD_SETTLEMENT, 0);
+ if (rec != NULL) {
+ /* We have placed a settlement, the edge must
+ * be placed adjacent to that settlement.
+ */
+ Node *node =
+ map_node(map, rec->x, rec->y, rec->pos);
+ return is_edge_adjacent_to_node(edge, node);
+ }
+ /* We have not placed a settlement yet, the edge can
+ * only placed if one of its nodes is a legal location
+ * for a new settlement.
+ */
+ return edge_has_place_for_settlement(edge);
+ }
+
+ /* Double setup is more difficult - there are a lot more
+ * situations to be handled.
+ */
+ switch (buildrec_count_type(list, BUILD_SETTLEMENT)) {
+ case 0:
+ return can_setup_edge_0(list, map, edge);
+ case 1:
+ return can_setup_edge_1(list, map, edge);
+ case 2:
+ return can_setup_edge_2(list, map, edge);
+ }
+ g_warning("more than 2 settlements in setup!!!");
+ return FALSE;
+}
+
+gboolean buildrec_can_setup_road(GList * list, Map * map,
+ const Edge * edge, gboolean is_double)
+{
+ if (!can_road_be_setup(edge))
+ return FALSE;
+
+ return buildrec_can_setup_edge(list, map, edge, is_double);
+}
+
+gboolean buildrec_can_setup_ship(GList * list, Map * map,
+ const Edge * edge, gboolean is_double)
+{
+ if (!can_ship_be_setup(edge))
+ return FALSE;
+
+ return buildrec_can_setup_edge(list, map, edge, is_double);
+}
+
+gboolean buildrec_can_setup_bridge(GList * list, Map * map,
+ const Edge * edge, gboolean is_double)
+{
+ if (!can_bridge_be_setup(edge))
+ return FALSE;
+
+ return buildrec_can_setup_edge(list, map, edge, is_double);
+}
+
+/* Check if we can place this settlement with 0 existing edges during setup
+ */
+static gboolean can_setup_settlement_0(G_GNUC_UNUSED GList * list,
+ G_GNUC_UNUSED Map * map,
+ G_GNUC_UNUSED const Node * node)
+{
+ return TRUE;
+}
+
+/* Check if we can place this settlement with 1 existing edge during setup
+ */
+static gboolean can_setup_settlement_1(GList * list, Map * map,
+ const Node * node)
+{
+ BuildRec *rec = buildrec_get_edge(list, 0);
+ Edge *edge = map_edge(map, rec->x, rec->y, rec->pos);
+ Node *other_node;
+
+ /* Make sure that we place one settlement next to the existing edge.
+ */
+ rec = buildrec_get(list, BUILD_SETTLEMENT, 0);
+ if (rec == NULL)
+ /* No other settlements placed yet.
+ */
+ return TRUE;
+
+ /* There is one edge and one settlement placed. One of the
+ * settlements must be placed next to the edge.
+ */
+ other_node = map_node(map, rec->x, rec->y, rec->pos);
+ return is_edge_adjacent_to_node(edge, node)
+ || is_edge_adjacent_to_node(edge, other_node);
+}
+
+/* Check if we can place this settlement with 2 existing edges during setup
+ */
+static gboolean can_setup_settlement_2(GList * list, Map * map,
+ const Node * node)
+{
+ BuildRec *rec = buildrec_get_edge(list, 0);
+ Edge *edge = map_edge(map, rec->x, rec->y, rec->pos);
+ Edge *other_edge;
+ Node *other_node;
+ Node *try_build_here;
+
+ rec = buildrec_get_edge(list, 1);
+ other_edge = map_edge(map, rec->x, rec->y, rec->pos);
+
+ /* Two edges placed, we must make sure that we place this
+ * settlement adjacent to an edge.
+ */
+ if (!is_edge_adjacent_to_node(edge, node)
+ && !is_edge_adjacent_to_node(other_edge, node))
+ return FALSE;
+
+ rec = buildrec_get(list, BUILD_SETTLEMENT, 0);
+ if (rec == NULL) {
+ /* No settlements placed yet, place the settlement and
+ * make sure that there is still a valid place for the
+ * second settlement.
+ */
+ gboolean is_ok = FALSE;
+
+ try_build_here = map_node(map, node->x, node->y, node->pos); /* Copy to non-const pointer */
+ try_build_here->type = BUILD_SETTLEMENT;
+ try_build_here->owner = edge->owner;
+ if (is_edge_adjacent_to_node(edge, node)) {
+ if (is_edge_adjacent_to_node(other_edge, node))
+ /* Node is adjacent to both edges -
+ * make sure there is still a valid
+ * location on either edge.
+ */
+ is_ok = edge_has_place_for_settlement(edge)
+ ||
+ edge_has_place_for_settlement
+ (other_edge);
+ else
+ /* Node is adjacent to edge, make sure
+ * other edge has location for
+ * settlement.
+ */
+ is_ok =
+ edge_has_place_for_settlement
+ (other_edge);
+ } else
+ /* Node is adjacent to other edge - make sure
+ * edge has location for settlement.
+ */
+ is_ok = edge_has_place_for_settlement(edge);
+ try_build_here->type = BUILD_NONE;
+ try_build_here->owner = -1;
+ return is_ok;
+ }
+
+ /* Two edges and one settlement placed, ensure that each edge
+ * is adjacent to at least one settlement.
+ */
+ other_node = map_node(map, rec->x, rec->y, rec->pos);
+ if (is_edge_adjacent_to_node(edge, other_node)) {
+ if (is_edge_adjacent_to_node(other_edge, other_node))
+ return TRUE;
+ else
+ return is_edge_adjacent_to_node(edge, other_node);
+ } else
+ return is_edge_adjacent_to_node(edge, node);
+}
+
+gboolean buildrec_can_setup_settlement(GList * list, Map * map,
+ const Node * node,
+ gboolean is_double)
+{
+ if (!can_settlement_be_setup(node))
+ return FALSE;
+
+ if (!is_double) {
+ BuildRec *rec = buildrec_get_edge(list, 0);
+ if (rec != NULL) {
+ /* We have placed an edge, the settlement must
+ * be placed adjacent to that edge.
+ */
+ Edge *edge =
+ map_edge(map, rec->x, rec->y, rec->pos);
+ return is_edge_adjacent_to_node(edge, node);
+ }
+ /* We have not placed an edge yet, the settlement is OK.
+ */
+ return TRUE;
+ }
+
+ /* Double setup is more difficult - there are a lot more
+ * situations to be handled.
+ */
+ switch (buildrec_count_edges(list)) {
+ case 0:
+ return can_setup_settlement_0(list, map, node);
+ case 1:
+ return can_setup_settlement_1(list, map, node);
+ case 2:
+ return can_setup_settlement_2(list, map, node);
+ }
+ g_warning("more than 2 settlements in setup!!!");
+ return FALSE;
+}
Added: trunk/common/buildrec.h
===================================================================
--- trunk/common/buildrec.h (rev 0)
+++ trunk/common/buildrec.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,60 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __buildrec_h
+#define __buildrec_h
+#include "map.h"
+
+/** information about building. Used for undo */
+typedef struct {
+ BuildType type; /**< type of building performed */
+ int x; /**< x-pos of hex of build action */
+ int y; /**< x-pos of hex of build action */
+ int pos; /**< location on hex of build action */
+ BuildType prev_status; /**< build city without settlement only: previous status of node */
+ const gint *cost; /**< resources spent */
+ int prev_x; /**< moving ships only: previous x hex */
+ int prev_y; /**< moving ships only: previous y hex */
+ int prev_pos; /**< moving ships only: previous position */
+ /* this is an int, because only the server uses it, and the client
+ * doesn't know about Players. */
+ int longest_road; /**< who had the longest road before this build */
+ int special_points_id; /**< Id of the special points or -1 */
+} BuildRec;
+
+int buildrec_count_type(GList * list, BuildType type);
+BuildRec *buildrec_get(GList * list, BuildType type, gint idx);
+BuildRec *buildrec_get_edge(GList * list, gint idx);
+BuildRec *buildrec_new(BuildType type, gint x, gint y, gint pos);
+GList *buildrec_free(GList * list);
+gboolean buildrec_is_valid(GList * list, Map * map, int owner);
+gboolean buildrec_can_setup_road(GList * list, Map * map,
+ const Edge * edge, gboolean is_double);
+gboolean buildrec_can_setup_ship(GList * list, Map * map,
+ const Edge * edge, gboolean is_double);
+gboolean buildrec_can_setup_settlement(GList * list, Map * map,
+ const Node * node,
+ gboolean is_double);
+gboolean buildrec_can_setup_bridge(GList * list, Map * map,
+ const Edge * edge, gboolean is_double);
+gint buildrec_count_edges(GList * list);
+
+#endif
Added: trunk/common/cards.c
===================================================================
--- trunk/common/cards.c (rev 0)
+++ trunk/common/cards.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,115 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include <glib.h>
+
+#include "game.h"
+#include "cards.h"
+
+DevelDeck *deck_new(GameParams * params)
+{
+ DevelDeck *deck;
+ gint num;
+ gint idx;
+
+ deck = g_malloc0(sizeof(*deck));
+ for (num = idx = 0; idx < G_N_ELEMENTS(params->num_develop_type);
+ idx++)
+ num += params->num_develop_type[idx];
+ deck->max_cards = num;
+ deck->cards = g_malloc0(deck->max_cards * sizeof(*deck->cards));
+ return deck;
+}
+
+void deck_free(DevelDeck * deck)
+{
+ if (deck->cards != NULL)
+ g_free(deck->cards);
+ g_free(deck);
+}
+
+void deck_card_add(DevelDeck * deck, DevelType type, gint turn_bought)
+{
+ if (deck->num_cards >= deck->max_cards)
+ return;
+ deck->cards[deck->num_cards].type = type;
+ deck->cards[deck->num_cards].turn_bought = turn_bought;
+ deck->num_cards++;
+}
+
+gboolean is_victory_card(DevelType type)
+{
+ return type == DEVEL_CHAPEL
+ || type == DEVEL_UNIVERSITY
+ || type == DEVEL_GOVERNORS_HOUSE
+ || type == DEVEL_LIBRARY || type == DEVEL_MARKET;
+}
+
+DevelType deck_card_type(const DevelDeck * deck, gint idx)
+{
+ return deck->cards[idx].type;
+}
+
+gboolean deck_card_playable(const DevelDeck * deck,
+ gboolean played_develop, gint idx, gint turn)
+{
+ if (idx >= deck->num_cards)
+ return FALSE;
+
+ if (is_victory_card(deck->cards[idx].type))
+ return TRUE;
+
+ return !played_develop && deck->cards[idx].turn_bought < turn;
+}
+
+gboolean deck_card_play(DevelDeck * deck,
+ gboolean played_develop, gint idx, gint turn)
+{
+ if (!deck_card_playable(deck, played_develop, idx, turn))
+ return FALSE;
+
+ deck->num_cards--;
+ memmove(deck->cards + idx, deck->cards + idx + 1,
+ (deck->num_cards - idx) * sizeof(*deck->cards));
+
+ return TRUE;
+}
+
+gint deck_card_amount(const DevelDeck * deck, DevelType type)
+{
+ gint idx;
+ gint amount = 0;
+
+ for (idx = 0; idx < deck->num_cards; ++idx)
+ if (deck->cards[idx].type == type)
+ ++amount;
+ return amount;
+}
+
+gint deck_card_oldest_card(const DevelDeck * deck, DevelType type)
+{
+ gint idx;
+ for (idx = 0; idx < deck->num_cards; ++idx)
+ if (deck->cards[idx].type == type)
+ return idx;
+ return -1;
+}
Added: trunk/common/cards.h
===================================================================
--- trunk/common/cards.h (rev 0)
+++ trunk/common/cards.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,53 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __cards_h
+#define __cards_h
+
+#include "game.h"
+
+/* It is important to know which turn a development card was bought
+ * in. You cannot play a card in the same turn that it was bought.
+ */
+typedef struct {
+ DevelType type;
+ gint turn_bought;
+} DevelCard;
+
+typedef struct {
+ DevelCard *cards;
+ gint num_cards;
+ gint max_cards;
+} DevelDeck;
+
+gboolean is_victory_card(DevelType type);
+
+DevelDeck *deck_new(GameParams * params);
+void deck_free(DevelDeck * deck);
+void deck_card_add(DevelDeck * deck, DevelType type, gint turn_bought);
+gboolean deck_card_playable(const DevelDeck * deck,
+ gboolean played_develop, gint idx, gint turn);
+gboolean deck_card_play(DevelDeck * deck,
+ gboolean played_develop, gint idx, gint turn);
+DevelType deck_card_type(const DevelDeck * deck, gint idx);
+
+gint deck_card_amount(const DevelDeck * deck, DevelType type);
+gint deck_card_oldest_card(const DevelDeck * deck, DevelType type);
+#endif
Added: trunk/common/common_glib.c
===================================================================
--- trunk/common/common_glib.c (rev 0)
+++ trunk/common/common_glib.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,128 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <glib.h>
+#include "game.h"
+#include "driver.h"
+
+typedef struct {
+ void (*func) (gpointer);
+ gpointer param;
+ GIOChannel *channel;
+} evl_io_func;
+
+
+GHashTable *_evl_glib_hash = NULL;
+
+/* Local function prototypes. */
+guint evl_glib_input_add_read(gint fd, void (*func) (gpointer),
+ gpointer param);
+guint evl_glib_input_add_write(gint fd, void (*func) (gpointer),
+ gpointer param);
+void evl_glib_input_remove(guint tag);
+
+
+/* event-loop related functions */
+static gboolean evl_glib_call_func(G_GNUC_UNUSED GIOChannel * source,
+ G_GNUC_UNUSED GIOCondition condition,
+ gpointer data)
+{
+ evl_io_func *io_func = (evl_io_func *) data;
+ io_func->func(io_func->param);
+ return TRUE;
+}
+
+static void evl_glib_channel_destroyed(gpointer data)
+{
+ GIOChannel *io_channel = (GIOChannel *) data;
+ /* free the srv_io_func structure associated with the channel */
+ evl_io_func *io_func =
+ g_hash_table_lookup(_evl_glib_hash, io_channel);
+
+ if (io_func)
+ g_free(io_func);
+
+ g_hash_table_remove(_evl_glib_hash, io_channel);
+}
+
+
+static guint evl_glib_input_add_watch(gint fd, GIOCondition condition,
+ void (*func) (gpointer),
+ gpointer param)
+{
+ GIOChannel *io_channel;
+ evl_io_func *io_func = g_malloc0(sizeof(evl_io_func));
+ guint tag;
+
+ io_channel = g_io_channel_unix_new(fd);
+ io_func->func = func;
+ io_func->param = param;
+ io_func->channel = io_channel;
+
+ tag =
+ g_io_add_watch_full(io_channel, G_PRIORITY_DEFAULT, condition,
+ evl_glib_call_func, io_func,
+ evl_glib_channel_destroyed);
+
+ /* allocate hash table if it hasn't yet been done */
+ if (!_evl_glib_hash)
+ _evl_glib_hash = g_hash_table_new(NULL, NULL);
+
+ /* insert the channel and function into a hash table; key on channel */
+ g_hash_table_insert(_evl_glib_hash, io_channel, io_func);
+
+ return tag;
+}
+
+
+guint evl_glib_input_add_read(gint fd, InputFunc func, gpointer param)
+{
+ return evl_glib_input_add_watch(fd, G_IO_IN | G_IO_HUP, func,
+ param);
+}
+
+guint evl_glib_input_add_write(gint fd, InputFunc func, gpointer param)
+{
+ return evl_glib_input_add_watch(fd, G_IO_OUT | G_IO_HUP, func,
+ param);
+}
+
+void evl_glib_input_remove(guint tag)
+{
+ g_source_remove(tag);
+}
+
+
+UIDriver Glib_Driver = {
+ NULL, /* event_queue */
+
+ log_message_string_console, /* log_write */
+
+ evl_glib_input_add_read, /* add read input */
+ evl_glib_input_add_write, /* add write input */
+ evl_glib_input_remove, /* remove input */
+
+ NULL, /* player just added */
+ NULL, /* player just renamed */
+ NULL, /* player just removed */
+ NULL /* player just renamed */
+};
Added: trunk/common/common_glib.h
===================================================================
--- trunk/common/common_glib.h (rev 0)
+++ trunk/common/common_glib.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,30 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __common_glib_h
+#define __common_glib_h
+
+extern guint evl_glib_input_add_read(gint fd, InputFunc func,
+ gpointer param);
+extern guint evl_glib_input_add_write(gint fd, InputFunc func,
+ gpointer param);
+extern void evl_glib_input_remove(guint tag);
+
+#endif
Added: trunk/common/cost.c
===================================================================
--- trunk/common/cost.c (rev 0)
+++ trunk/common/cost.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,154 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include <glib.h>
+
+#include "game.h"
+#include "cost.h"
+
+const gint *cost_road(void)
+{
+ static gint cost[NO_RESOURCE] = {
+ 1, /* brick */
+ 0, /* grain */
+ 0, /* ore */
+ 0, /* wool */
+ 1 /* lumber */
+ };
+ return cost;
+}
+
+const gint *cost_ship(void)
+{
+ static gint cost[NO_RESOURCE] = {
+ 0, /* brick */
+ 0, /* grain */
+ 0, /* ore */
+ 1, /* wool */
+ 1 /* lumber */
+ };
+ return cost;
+}
+
+const gint *cost_bridge(void)
+{
+ static gint cost[NO_RESOURCE] = {
+ 1, /* brick */
+ 0, /* grain */
+ 0, /* ore */
+ 1, /* wool */
+ 1 /* lumber */
+ };
+ return cost;
+}
+
+const gint *cost_settlement(void)
+{
+ static gint cost[NO_RESOURCE] = {
+ 1, /* brick */
+ 1, /* grain */
+ 0, /* ore */
+ 1, /* wool */
+ 1 /* lumber */
+ };
+ return cost;
+}
+
+const gint *cost_upgrade_settlement(void)
+{
+ static gint cost[NO_RESOURCE] = {
+ 0, /* brick */
+ 2, /* grain */
+ 3, /* ore */
+ 0, /* wool */
+ 0 /* lumber */
+ };
+ return cost;
+}
+
+const gint *cost_city(void)
+{
+ static gint cost[NO_RESOURCE] = {
+ 1, /* brick */
+ 3, /* grain */
+ 3, /* ore */
+ 1, /* wool */
+ 1 /* lumber */
+ };
+ return cost;
+}
+
+const gint *cost_city_wall(void)
+{
+ static gint cost[NO_RESOURCE] = {
+ 2, /* brick */
+ 0, /* grain */
+ 0, /* ore */
+ 0, /* wool */
+ 0 /* lumber */
+ };
+ return cost;
+}
+
+const gint *cost_development(void)
+{
+ static gint cost[NO_RESOURCE] = {
+ 0, /* brick */
+ 1, /* grain */
+ 1, /* ore */
+ 1, /* wool */
+ 0 /* lumber */
+ };
+ return cost;
+}
+
+gboolean cost_buy(const gint * cost, gint * assets)
+{
+ gint idx;
+
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ assets[idx] -= cost[idx];
+ if (assets[idx] < 0)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void cost_refund(const gint * cost, gint * assets)
+{
+ gint idx;
+
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ assets[idx] += cost[idx];
+}
+
+gboolean cost_can_afford(const gint * cost, const gint * assets)
+{
+ gint tmp[NO_RESOURCE];
+
+ gint idx;
+
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ tmp[idx] = assets[idx];
+
+ return cost_buy(cost, tmp);
+}
Added: trunk/common/cost.h
===================================================================
--- trunk/common/cost.h (rev 0)
+++ trunk/common/cost.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,39 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __cost_h
+#define __cost_h
+
+#include <glib.h>
+
+const gint *cost_road(void);
+const gint *cost_ship(void);
+const gint *cost_bridge(void);
+const gint *cost_settlement(void);
+const gint *cost_upgrade_settlement(void);
+const gint *cost_city(void);
+const gint *cost_city_wall(void);
+const gint *cost_development(void);
+
+gboolean cost_buy(const gint * cost, gint * assets);
+void cost_refund(const gint * cost, gint * assets);
+gboolean cost_can_afford(const gint * cost, const gint * assets);
+
+#endif
Added: trunk/common/driver.c
===================================================================
--- trunk/common/driver.c (rev 0)
+++ trunk/common/driver.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,45 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2000 Bibek Sahu
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Implementation of generic driver-manipulation functions.
+ * Creation of relevant globals.
+ */
+
+#include "config.h"
+#include "driver.h"
+#include "common_glib.h"
+
+UIDriver *driver;
+
+void set_ui_driver(UIDriver * d)
+{
+ driver = d;
+
+ /* For now, these are universal functions that can't be hooked in
+ at compile time. We may need to move these out of here if
+ other ports will be using something other than glib.
+ */
+ if (driver) {
+ driver->input_add_read = evl_glib_input_add_read;
+ driver->input_add_write = evl_glib_input_add_write;
+ driver->input_remove = evl_glib_input_remove;
+ }
+}
Added: trunk/common/driver.h
===================================================================
--- trunk/common/driver.h (rev 0)
+++ trunk/common/driver.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,54 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2000 Steve Langasek
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __driver_h
+#define __driver_h
+
+#include "log.h"
+#include "state.h"
+
+typedef void (*InputFunc) (gpointer);
+
+typedef struct {
+ /* function for clearing the event queue */
+ void (*event_queue) (void);
+
+ /* Function to write logs and data to the system display */
+ LogFunc log_write; /* ==> void log_write( gint msg_type, gchar *text ); */
+
+ /* event-loop related functions */
+ guint(*input_add_read) (gint fd, InputFunc func, gpointer param);
+ guint(*input_add_write) (gint fd, InputFunc func, gpointer param);
+ void (*input_remove) (guint tag);
+
+ /* callbacks for the server */
+ void (*player_added) (void *player); /* these really should be ... */
+ void (*player_renamed) (void *player); /* ... `Player *player', but */
+ void (*player_removed) (void *player); /* that requires more headers */
+
+ void (*player_change) (void *game); /* Should be Game *game */
+
+} UIDriver;
+
+extern UIDriver *driver;
+
+void set_ui_driver(UIDriver * d);
+
+#endif /* __driver_h */
Added: trunk/common/game.c
===================================================================
--- trunk/common/game.c (rev 0)
+++ trunk/common/game.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,674 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include <math.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <stdio.h>
+
+#include "game.h"
+#include "cards.h"
+
+typedef enum {
+ PARAM_STRING,
+ PARAM_INT,
+ PARAM_BOOL,
+ PARAM_INTLIST
+} ParamType;
+
+typedef struct {
+ const gchar *name;
+ ParamType type;
+ int offset;
+} Param;
+
+#define PARAM_V(name, type, var) #name, type, G_STRUCT_OFFSET(GameParams, var)
+#define PARAM(var, type) PARAM_V(var, type, var)
+
+/* *INDENT-OFF* */
+static Param game_params[] = {
+ {PARAM(title, PARAM_STRING)},
+ {PARAM_V(random-terrain, PARAM_BOOL, random_terrain)},
+ {PARAM_V(strict-trade, PARAM_BOOL, strict_trade)},
+ {PARAM_V(domestic-trade, PARAM_BOOL, domestic_trade)},
+ {PARAM_V(num-players, PARAM_INT, num_players)},
+ {PARAM_V(sevens-rule, PARAM_INT, sevens_rule)},
+ {PARAM_V(victory-points, PARAM_INT, victory_points)},
+ {PARAM_V(num-roads, PARAM_INT, num_build_type[BUILD_ROAD])},
+ {PARAM_V(num-bridges, PARAM_INT, num_build_type[BUILD_BRIDGE])},
+ {PARAM_V(num-ships, PARAM_INT, num_build_type[BUILD_SHIP])},
+ {PARAM_V(num-settlements, PARAM_INT, num_build_type[BUILD_SETTLEMENT])},
+ {PARAM_V(num-cities, PARAM_INT, num_build_type[BUILD_CITY])},
+ {PARAM_V(num-city-walls, PARAM_INT, num_build_type[BUILD_CITY_WALL])},
+ {PARAM_V(resource-count, PARAM_INT, resource_count)},
+ {PARAM_V(develop-road, PARAM_INT, num_develop_type[DEVEL_ROAD_BUILDING])},
+ {PARAM_V(develop-monopoly, PARAM_INT, num_develop_type[DEVEL_MONOPOLY])},
+ {PARAM_V(develop-plenty, PARAM_INT, num_develop_type[DEVEL_YEAR_OF_PLENTY])},
+ {PARAM_V(develop-chapel, PARAM_INT, num_develop_type[DEVEL_CHAPEL])},
+ {PARAM_V(develop-university, PARAM_INT, num_develop_type[DEVEL_UNIVERSITY])},
+ {PARAM_V(develop-governor, PARAM_INT, num_develop_type[DEVEL_GOVERNORS_HOUSE])},
+ {PARAM_V(develop-library, PARAM_INT, num_develop_type[DEVEL_LIBRARY])},
+ {PARAM_V(develop-market, PARAM_INT, num_develop_type[DEVEL_MARKET])},
+ {PARAM_V(develop-soldier, PARAM_INT, num_develop_type[DEVEL_SOLDIER])},
+ {PARAM_V(use-pirate, PARAM_BOOL, use_pirate)},
+ {PARAM_V(island-discovery-bonus, PARAM_INTLIST, island_discovery_bonus)}
+};
+/* *INDENT-ON* */
+
+GameParams *params_new(void)
+{
+ GameParams *params;
+
+ params = g_malloc0(sizeof(*params));
+ return params;
+}
+
+void params_free(GameParams * params)
+{
+ if (params == NULL)
+ return;
+
+ if (params->title != NULL)
+ g_free(params->title);
+ if (params->map != NULL)
+ map_free(params->map);
+ g_free(params);
+}
+
+static gchar *skip_space(gchar * str)
+{
+ while (isspace(*str))
+ str++;
+ return str;
+}
+
+static gboolean match_word(gchar ** str, const gchar * word)
+{
+ gint word_len;
+
+ word_len = strlen(word);
+ if (strncmp(*str, word, word_len) == 0) {
+ *str += word_len;
+ *str = skip_space(*str);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Create a new array, filled with the list in str.
+ * If the array has length zero, NULL is returned.
+ */
+static GArray *build_int_list(const gchar * str)
+{
+ GArray *array = g_array_new(FALSE, FALSE, sizeof(gint));
+ while (*str != '\0') {
+ gint num;
+ gint sign = +1;
+
+ /* Skip leading space */
+ while (isspace(*str))
+ str++;
+ if (*str == '\0')
+ break;
+ /* Get the next number and add it to the array */
+ num = 0;
+ if (*str == '-') {
+ sign = -1;
+ str++;
+ }
+ while (isdigit(*str))
+ num = num * 10 + *str++ - '0';
+ num *= sign;
+ g_array_append_val(array, num);
+
+ /* Skip the non-digits */
+ while (!isdigit(*str) && *str != '-' && *str != '\0')
+ str++;
+ }
+ if (array->len == 0) {
+ g_array_free(array, FALSE);
+ array = NULL;
+ }
+ return array;
+}
+
+/* This function allocates a buffer and returns it. It must be freed by the
+ * caller. */
+static gchar *format_int_list(const gchar * name, GArray * array)
+{
+ gchar *old, *str = NULL;
+ int idx;
+
+ if (array == NULL)
+ return NULL;
+
+ if (array->len == 0) {
+ str = g_strdup(name);
+ return str;
+ }
+ for (idx = 0; idx < array->len; idx++) {
+ old = str;
+ if (idx == 0)
+ str = g_strdup_printf("%s %d", name,
+ g_array_index(array, gint,
+ idx));
+ else
+ str = g_strdup_printf("%s,%d", str,
+ g_array_index(array, gint,
+ idx));
+ if (old)
+ g_free(old);
+ }
+ return str;
+}
+
+struct nosetup_t {
+ WriteLineFunc func;
+ gpointer user_data;
+};
+
+static gboolean find_no_setup(G_GNUC_UNUSED Map * map, Hex * hex,
+ struct nosetup_t *data)
+{
+ gint idx;
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); ++idx) {
+ Node *node = hex->nodes[idx];
+ if (node->no_setup) {
+ gchar buff[50];
+ if (node->x != hex->x || node->y != hex->y)
+ continue;
+ snprintf(buff, sizeof(buff), "nosetup %d %d %d",
+ node->x, node->y, node->pos);
+ data->func(data->user_data, buff);
+ }
+ }
+ return FALSE;
+}
+
+void params_write_lines(GameParams * params, gboolean write_secrets,
+ WriteLineFunc func, gpointer user_data)
+{
+ gint idx;
+ gint y;
+ gchar *buff;
+ gchar *str;
+
+ switch (params->variant) {
+ case VAR_DEFAULT:
+ func(user_data, "variant default");
+ break;
+ case VAR_ISLANDS:
+ func(user_data, "variant islands");
+ break;
+ case VAR_INTIMATE:
+ func(user_data, "variant intimate");
+ break;
+ }
+ for (idx = 0; idx < G_N_ELEMENTS(game_params); idx++) {
+ Param *param = game_params + idx;
+
+ switch (param->type) {
+ case PARAM_STRING:
+ str =
+ G_STRUCT_MEMBER(gchar *, params,
+ param->offset);
+ if (!str)
+ continue;
+ buff = g_strdup_printf("%s %s", param->name, str);
+ func(user_data, buff);
+ g_free(buff);
+ break;
+ case PARAM_INT:
+ buff = g_strdup_printf("%s %d", param->name,
+ G_STRUCT_MEMBER(gint,
+ params,
+ param->
+ offset));
+ func(user_data, buff);
+ g_free(buff);
+ break;
+ case PARAM_BOOL:
+ if (G_STRUCT_MEMBER
+ (gboolean, params, param->offset)) {
+ func(user_data, param->name);
+ }
+ break;
+ case PARAM_INTLIST:
+ buff =
+ format_int_list(param->name,
+ G_STRUCT_MEMBER(GArray *,
+ params,
+ param->
+ offset));
+ /* Don't send empty intlists */
+ if (buff != NULL) {
+ func(user_data, buff);
+ g_free(buff);
+ }
+ break;
+ }
+ }
+ buff = format_int_list("chits", params->map->chits);
+ func(user_data, buff);
+ g_free(buff);
+ func(user_data, "map");
+ for (y = 0; y < params->map->y_size; y++) {
+ buff = map_format_line(params->map, write_secrets, y);
+ func(user_data, buff);
+ g_free(buff);
+ }
+ func(user_data, ".");
+ if (params->map) {
+ struct nosetup_t tmp;
+ tmp.user_data = user_data;
+ tmp.func = func;
+ map_traverse(params->map, (HexFunc) find_no_setup, &tmp);
+ }
+}
+
+gboolean params_load_line(GameParams * params, gchar * line)
+{
+ gint idx;
+
+ if (params->map == NULL)
+ params->map = map_new();
+ if (params->parsing_map) {
+ if (strcmp(line, ".") == 0) {
+ params->parsing_map = FALSE;
+ if (!map_parse_finish(params->map)) {
+ map_free(params->map);
+ params->map = NULL;
+ return FALSE;
+ }
+ } else
+ return map_parse_line(params->map, line);
+ return TRUE;
+ }
+ line = skip_space(line);
+ if (*line == '#')
+ return TRUE;
+ if (*line == 0)
+ return TRUE;
+ if (match_word(&line, "variant")) {
+ if (match_word(&line, "islands"))
+ params->variant = VAR_ISLANDS;
+ else if (match_word(&line, "intimate"))
+ params->variant = VAR_INTIMATE;
+ else
+ params->variant = VAR_DEFAULT;
+ return TRUE;
+ }
+ if (match_word(&line, "map")) {
+ params->parsing_map = TRUE;
+ return TRUE;
+ }
+ if (match_word(&line, "chits")) {
+ if (params->map->chits != NULL)
+ g_array_free(params->map->chits, TRUE);
+ params->map->chits = build_int_list(line);
+ if (params->map->chits == NULL) {
+ g_warning("Zero length chits array");
+ return FALSE;
+ }
+ return TRUE;
+ }
+ if (match_word(&line, "nosetup")) {
+ gint x = 0, y = 0, pos = 0;
+ Node *node;
+ /* don't tolerate invalid game descriptions */
+ g_assert(params->map != NULL);
+ sscanf(line, "%d %d %d", &x, &y, &pos);
+ node = map_node(params->map, x, y, pos);
+ if (node) {
+ node->no_setup = TRUE;
+ } else {
+ g_warning
+ ("Nosetup node %d %d %d is not in the map", x,
+ y, pos);
+ }
+ return TRUE;
+ }
+
+ for (idx = 0; idx < G_N_ELEMENTS(game_params); idx++) {
+ Param *param = game_params + idx;
+ gchar *str;
+ GArray *array;
+
+ if (!match_word(&line, param->name))
+ continue;
+ switch (param->type) {
+ case PARAM_STRING:
+ str =
+ G_STRUCT_MEMBER(gchar *, params,
+ param->offset);
+ if (str)
+ g_free(str);
+ str = g_strchomp(g_strdup(line));
+ G_STRUCT_MEMBER(gchar *, params, param->offset) =
+ str;
+ return TRUE;
+ case PARAM_INT:
+ G_STRUCT_MEMBER(gint, params, param->offset) =
+ atoi(line);
+ return TRUE;
+ case PARAM_BOOL:
+ G_STRUCT_MEMBER(gboolean, params, param->offset) =
+ TRUE;
+ return TRUE;
+ case PARAM_INTLIST:
+ array =
+ G_STRUCT_MEMBER(GArray *, params,
+ param->offset);
+ if (array != NULL)
+ g_array_free(array, TRUE);
+ array = build_int_list(line);
+ if (array == NULL) {
+ g_warning("Zero length array for %s",
+ param->name);
+ }
+ G_STRUCT_MEMBER(GArray *, params, param->offset) =
+ array;
+ return array != NULL;
+ }
+ }
+ g_warning("Unknown keyword: %s", line);
+ return FALSE;
+}
+
+/* read a line from a file. The memory needed is allocated. The returned line
+ * is unbounded. Returns FALSE if no (partial) line could be read */
+gboolean read_line_from_file(gchar ** line, FILE * f)
+{
+ gchar part[512];
+ gint len;
+
+ if (fgets(part, sizeof(part), f) == NULL)
+ return FALSE;
+
+ len = strlen(part);
+ g_assert(len > 0);
+ *line = g_strdup(part);
+ while ((*line)[len - 1] != '\n') {
+ gchar *oldline;
+ if (fgets(part, sizeof(part), f) == NULL)
+ break;
+ oldline = *line;
+ *line = g_strdup_printf("%s%s", *line, part);
+ g_free(oldline);
+ len = strlen(*line);
+ }
+ /* In case of error or EOF, just return the part we have.
+ * Otherwise, strip the newline. */
+ if ((*line)[len - 1] == '\n')
+ (*line)[len - 1] = '\0';
+ return TRUE;
+}
+
+GameParams *params_load_file(const gchar * fname)
+{
+ FILE *fp;
+ gchar *line;
+ GameParams *params;
+
+ if ((fp = fopen(fname, "r")) == NULL) {
+ g_warning("could not open '%s'", fname);
+ return NULL;
+ }
+
+ params = params_new();
+ while (read_line_from_file(&line, fp) && params) {
+ if (!params_load_line(params, line)) {
+ params_free(params);
+ params = NULL;
+ }
+ g_free(line);
+ }
+ fclose(fp);
+ if (params && !params_load_finish(params)) {
+ params_free(params);
+ return NULL;
+ }
+ return params;
+}
+
+GameParams *params_copy(const GameParams * params)
+{
+ /* Copy the const parameter to a non-const version, because
+ * G_STRUCT_MEMBER doesn't want const values. Note that this
+ * variable does not own its pointers, that is, they don't have to
+ * be freed when it goes out of scope. */
+ GameParams nonconst;
+ GameParams *copy;
+ gint idx;
+ gchar *buff;
+
+ if (params == NULL)
+ return NULL;
+
+ memcpy(&nonconst, params, sizeof(GameParams));
+ copy = params_new();
+ copy->map = map_copy(params->map);
+ copy->variant = params->variant;
+
+ for (idx = 0; idx < G_N_ELEMENTS(game_params); idx++) {
+ Param *param = game_params + idx;
+
+ switch (param->type) {
+ case PARAM_STRING:
+ G_STRUCT_MEMBER(gchar *, copy, param->offset)
+ =
+ g_strdup(G_STRUCT_MEMBER
+ (gchar *, &nonconst, param->offset));
+ break;
+ case PARAM_INT:
+ G_STRUCT_MEMBER(gint, copy, param->offset)
+ = G_STRUCT_MEMBER(gint, &nonconst,
+ param->offset);
+ break;
+ case PARAM_BOOL:
+ G_STRUCT_MEMBER(gboolean, copy, param->offset)
+ = G_STRUCT_MEMBER(gboolean, &nonconst,
+ param->offset);
+ break;
+ case PARAM_INTLIST:
+ buff =
+ format_int_list("",
+ G_STRUCT_MEMBER(GArray *,
+ &nonconst,
+ param->
+ offset));
+ if (buff != NULL) {
+ G_STRUCT_MEMBER(GArray *, copy,
+ param->offset) =
+ build_int_list(buff);
+ g_free(buff);
+ }
+ break;
+ }
+ }
+
+ copy->quit_when_done = params->quit_when_done;
+ copy->tournament_time = params->tournament_time;
+ return copy;
+}
+
+/** Returns TRUE if the params are valid */
+gboolean params_load_finish(GameParams * params)
+{
+ if (!params->map) {
+ g_warning("Missing map");
+ return FALSE;
+ }
+ if (params->parsing_map) {
+ g_warning("Map not complete. Missing . after the map?");
+ return FALSE;
+ }
+ if (!params->map->chits) {
+ g_warning("No chits defined");
+ return FALSE;
+ }
+ if (params->map->chits->len < 1) {
+ g_warning("At least one chit must be defined");
+ return FALSE;
+ }
+ if (!params->title) {
+ g_warning("Game has no title");
+ return FALSE;
+ }
+ params->map->have_bridges =
+ params->num_build_type[BUILD_BRIDGE] > 0;
+ params->map->has_pirate = params->use_pirate;
+ return TRUE;
+}
+
+static void write_one_line(gpointer user_data, const gchar * line)
+{
+ FILE *fp = user_data;
+ fprintf(fp, "%s\n", line);
+}
+
+gboolean params_write_file(GameParams * params, const gchar * fname)
+{
+ FILE *fp;
+
+ if ((fp = fopen(fname, "w")) == NULL) {
+ g_warning("could not open '%s'", fname);
+ return FALSE;
+ }
+ params_write_lines(params, TRUE, write_one_line, fp);
+
+ fclose(fp);
+
+ return TRUE;
+}
+
+WinnableState params_check_winnable_state(const GameParams * params,
+ gchar ** win_message,
+ gchar ** point_specification)
+{
+ gint target, building, development;
+ gint road, army;
+ gint idx;
+ WinnableState return_value;
+ gint total_island, max_island;
+ guint number_of_islands;
+
+ if (params == NULL) {
+ *win_message = g_strdup("Error: no GameParams provided");
+ *point_specification = g_strdup("");
+ return PARAMS_NO_WIN;
+ }
+
+ /* Check whether the game is winnable at all */
+ target = params->victory_points;
+ building =
+ params->num_build_type[BUILD_SETTLEMENT] +
+ (params->num_build_type[BUILD_SETTLEMENT] > 0 ?
+ params->num_build_type[BUILD_CITY] * 2 : 0);
+ road =
+ (params->num_build_type[BUILD_ROAD] +
+ params->num_build_type[BUILD_SHIP] +
+ params->num_build_type[BUILD_BRIDGE]) >= 5 ? 2 : 0;
+ army = params->num_develop_type[DEVEL_SOLDIER] >= 3 ? 2 : 0;
+ development = 0;
+ for (idx = 0; idx < NUM_DEVEL_TYPES; idx++) {
+ if (is_victory_card(idx))
+ development += params->num_develop_type[idx];
+ }
+
+ number_of_islands = map_count_islands(params->map);
+ if (number_of_islands == 0) {
+ *win_message = g_strdup(_("This game cannot be won."));
+ *point_specification = g_strdup(_("There is no land."));
+ return PARAMS_NO_WIN;
+ }
+
+ /* It is not guaranteed that the islands can be reached */
+ total_island = 0;
+ max_island = 0;
+ if (params->island_discovery_bonus != NULL
+ && params->island_discovery_bonus->len > 0
+ && (params->num_build_type[BUILD_SHIP] +
+ params->num_build_type[BUILD_BRIDGE] > 0)) {
+ gint i;
+ for (i = 0; i < number_of_islands - 1; i++) {
+ total_island +=
+ g_array_index(params->island_discovery_bonus,
+ gint,
+ MIN(params->
+ island_discovery_bonus->len -
+ 1, i));
+ /* The island score can be negative */
+ if (max_island < total_island)
+ max_island = total_island;
+ }
+ }
+
+ if (target > building) {
+ if (target >
+ building + development + road + army + max_island) {
+ *win_message =
+ g_strdup(_("This game cannot be won."));
+ return_value = PARAMS_NO_WIN;
+ } else {
+ *win_message =
+ g_strdup(_
+ ("It is possible that this "
+ "game cannot be won."));
+ return_value = PARAMS_WIN_PERHAPS;
+ }
+ } else {
+ *win_message = g_strdup(_("This game can be won by only "
+ "building all settlements and "
+ "cities."));
+ return_value = PARAMS_WIN_BUILD_ALL;
+ }
+ *point_specification =
+ g_strdup_printf(_
+ ("Required victory points: %d\n"
+ "Points obtained by building all: %d\n"
+ "Points in development cards: %d\n"
+ "Longest road/largest army: %d+%d\n"
+ "Maximum island discovery bonus: %d\n"
+ "Total: %d"), target, building, development,
+ road, army, max_island,
+ building + development + road + army +
+ max_island);
+ return return_value;
+}
+
+Points *points_new(gint id, const gchar * name, gint points)
+{
+ Points *p = g_malloc0(sizeof(Points));
+ p->id = id;
+ p->name = g_strdup(name);
+ p->points = points;
+ return p;
+}
+
+void points_free(Points * points)
+{
+ g_free(points->name);
+}
Added: trunk/common/game.h
===================================================================
--- trunk/common/game.h (rev 0)
+++ trunk/common/game.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,113 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __game_h
+#define __game_h
+
+#include <stdio.h>
+#include "map.h"
+#include "driver.h"
+
+typedef enum {
+ DEVEL_ROAD_BUILDING,
+ DEVEL_MONOPOLY,
+ DEVEL_YEAR_OF_PLENTY,
+ DEVEL_CHAPEL,
+ DEVEL_UNIVERSITY,
+ DEVEL_GOVERNORS_HOUSE,
+ DEVEL_LIBRARY,
+ DEVEL_MARKET,
+ DEVEL_SOLDIER
+} DevelType;
+#define NUM_DEVEL_TYPES (DEVEL_SOLDIER + 1)
+
+#define MAX_PLAYERS 8 /* maximum number of players supported */
+#define MAX_CHAT 496 /* maximum chat message size
+ * (512 - strlen("player 0 chat \n") - 1) */
+#define MAX_NAME_LENGTH 30 /* maximum length for the name of a player */
+
+typedef enum {
+ VAR_DEFAULT, /* plain out-of-the-box game */
+ VAR_ISLANDS, /* Islands of Catan */
+ VAR_INTIMATE /* Intimate Catan */
+} GameVariant;
+
+typedef struct {
+ gchar *title; /* title of the game */
+ GameVariant variant; /* which variant is being played */
+ gboolean random_terrain; /* shuffle terrain location? */
+ gboolean strict_trade; /* trade only before build/buy? */
+ gboolean domestic_trade; /* player trading allowed? */
+ gint num_players; /* number of players in the game */
+ gint sevens_rule; /* what to do when a seven is rolled */
+ /* 0 = normal, 1 = no 7s on first 2 turns (official rule variant),
+ * 2 = all 7s rerolled */
+ gint victory_points; /* target number of victory points */
+ gint num_build_type[NUM_BUILD_TYPES]; /* number of each build type */
+ gint resource_count; /* number of each resource */
+ gint num_develop_type[NUM_DEVEL_TYPES]; /* number of each development */
+ Map *map; /* the game map */
+ gboolean parsing_map; /* currently parsing map? *//* Not in game_params[] */
+ gint tournament_time; /* time to start tournament time in minutes *//* Not in game_params[] */
+ gboolean quit_when_done; /* server quits after someone wins *//* Not in game_params[] */
+ gboolean use_pirate; /* is there a pirate in this game? */
+ GArray *island_discovery_bonus; /* list of VPs for discovering an island */
+} GameParams;
+
+typedef struct {
+ gint id; /* identification for client-server communication */
+ gchar *name; /* name of the item */
+ gint points; /* number of points */
+} Points;
+
+typedef enum {
+ PARAMS_WINNABLE, /* the game can be won */
+ PARAMS_WIN_BUILD_ALL, /* the game can be won by building all */
+ PARAMS_WIN_PERHAPS, /* the game could be won */
+ PARAMS_NO_WIN /* the game cannot be won */
+} WinnableState;
+
+typedef void (*WriteLineFunc) (gpointer user_data, const gchar *);
+
+GameParams *params_new(void);
+GameParams *params_copy(const GameParams * params);
+GameParams *params_load_file(const gchar * fname);
+void params_free(GameParams * params);
+void params_write_lines(GameParams * params, gboolean write_secrets,
+ WriteLineFunc func, gpointer user_data);
+gboolean params_write_file(GameParams * params, const gchar * fname);
+gboolean params_load_line(GameParams * params, gchar * line);
+gboolean params_load_finish(GameParams * params);
+gboolean read_line_from_file(gchar ** line, FILE * f);
+/** Check whether, in theory, the game could be won by a player.
+ * @param params The game parameters
+ * @retval win_message A message describing how/when the game can be won
+ * @retval point_specification A message describing how the points are distributed
+ * @return Whether the game can be won
+ */
+WinnableState params_check_winnable_state(const GameParams * params,
+ gchar ** win_message,
+ gchar ** point_specification);
+
+Points *points_new(gint id, const gchar * name, gint points);
+void points_free(Points * points);
+#endif
Added: trunk/common/gtk/Makefile.am
===================================================================
--- trunk/common/gtk/Makefile.am (rev 0)
+++ trunk/common/gtk/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,49 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+noinst_LIBRARIES += libpioneers_gtk.a
+
+libpioneers_gtk_a_CPPFLAGS = $(gtk_cflags)
+
+libpioneers_gtk_a_SOURCES = \
+ common/gtk/aboutbox.c \
+ common/gtk/aboutbox.h \
+ common/gtk/colors.c \
+ common/gtk/colors.h \
+ common/gtk/common_gtk.c \
+ common/gtk/common_gtk.h \
+ common/gtk/config-gnome.c \
+ common/gtk/config-gnome.h \
+ common/gtk/game-rules.c \
+ common/gtk/game-rules.h \
+ common/gtk/game-settings.c \
+ common/gtk/game-settings.h \
+ common/gtk/gtkbugs.c \
+ common/gtk/gtkbugs.h \
+ common/gtk/guimap.c \
+ common/gtk/guimap.h \
+ common/gtk/player-icon.c \
+ common/gtk/player-icon.h \
+ common/gtk/polygon.c \
+ common/gtk/polygon.h \
+ common/gtk/select-game.c \
+ common/gtk/select-game.h \
+ common/gtk/theme.c \
+ common/gtk/theme.h
Added: trunk/common/gtk/aboutbox.c
===================================================================
--- trunk/common/gtk/aboutbox.c (rev 0)
+++ trunk/common/gtk/aboutbox.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,119 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2005 Brian Wellington <bwelling at xbill.org>
+ * Copyright (C) 2005 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Common code for displaying an about box.
+ *
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+
+#include "aboutbox.h"
+#include "game.h"
+#include "version.h"
+
+static GtkWidget *about = NULL; /* The about window */
+
+void aboutbox_display(const gchar * title, const gchar ** authors)
+{
+ GtkWidget *splash = NULL, *view = NULL;
+ GtkTextBuffer *buffer = NULL;
+ GtkTextIter iter;
+ gchar *imagefile = NULL;
+ gint i;
+
+ if (about != NULL) {
+ gtk_window_present(GTK_WINDOW(about));
+ return;
+ }
+ about = gtk_dialog_new_with_buttons(title, NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CLOSE,
+ GTK_RESPONSE_CLOSE, NULL);
+
+ g_signal_connect_swapped(about,
+ "response",
+ G_CALLBACK(gtk_widget_destroy), about);
+ g_signal_connect(G_OBJECT(about), "destroy",
+ G_CALLBACK(gtk_widget_destroyed), &about);
+
+ imagefile = g_build_filename(DATADIR, "pixmaps", "pioneers",
+ "splash.png", NULL);
+ splash = gtk_image_new_from_file(imagefile);
+ g_free(imagefile);
+
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(about)->vbox), splash, FALSE,
+ FALSE, 0);
+
+ buffer = gtk_text_buffer_new(NULL);
+ gtk_text_buffer_get_start_iter(buffer, &iter);
+ gtk_text_buffer_create_tag(buffer, "bold",
+ "weight", PANGO_WEIGHT_BOLD, NULL);
+
+ gtk_text_buffer_insert(buffer, &iter,
+ _("Pioneers is based upon the excellent\n"
+ "Settlers of Catan board game.\n"), -1);
+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,
+ _("Version"), -1,
+ "bold", NULL);
+ gtk_text_buffer_insert(buffer, &iter, ": ", -1);
+ gtk_text_buffer_insert(buffer, &iter, FULL_VERSION, -1);
+ gtk_text_buffer_insert(buffer, &iter, "\n", -1);
+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,
+ _("Homepage"), -1,
+ "bold", NULL);
+ gtk_text_buffer_insert(buffer, &iter,
+ ": http://pio.sourceforge.net\n", -1);
+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,
+ _("Authors"), -1, "bold",
+ NULL);
+ gtk_text_buffer_insert(buffer, &iter, ":\n", -1);
+
+ for (i = 0; authors[i] != NULL; i++) {
+ if (i != 0)
+ gtk_text_buffer_insert(buffer, &iter, "\n", 1);
+ gtk_text_buffer_insert(buffer, &iter, " ", 2);
+ gtk_text_buffer_insert(buffer, &iter, authors[i], -1);
+ }
+
+ gtk_text_buffer_get_start_iter(buffer, &iter);
+ gtk_text_buffer_place_cursor(buffer, &iter);
+
+ view = gtk_text_view_new_with_buffer(buffer);
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(view), FALSE);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(about)->vbox), view, FALSE,
+ FALSE, 0);
+
+ /* XXX GTK+ 2.6
+ gtk_show_about_dialog(NULL,
+ "version", FULL_VERSION,
+ "copyright", _("(C) 2002 the Free Software Foundation"),
+ "comments",
+ _("Pioneers is based upon the excellent\n"
+ "Settlers of Catan board game.\n"),
+ "authors", authors,
+ "website", "http://pio.sourceforge.net",
+ NULL);
+ */
+ gtk_widget_show_all(about);
+}
Added: trunk/common/gtk/aboutbox.h
===================================================================
--- trunk/common/gtk/aboutbox.h (rev 0)
+++ trunk/common/gtk/aboutbox.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,35 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2005 Brian Wellington <bwelling at xbill.org>
+ * Copyright (C) 2005 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/*
+ * Common code for displaying an about box.
+ */
+#ifndef __ABOUTBOX_H__
+#define __ABOUTBOX_H__
+
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+ void aboutbox_display(const gchar * title, const gchar ** authors);
+
+G_END_DECLS
+#endif /* __ABOUTBOX_H__ */
Added: trunk/common/gtk/colors.c
===================================================================
--- trunk/common/gtk/colors.c (rev 0)
+++ trunk/common/gtk/colors.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,70 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2005 Brian Wellington <bwelling at xbill.org>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <gdk/gdk.h>
+
+#include "colors.h"
+#include "game.h"
+
+GdkColor black = { 0, 0, 0, 0 };
+GdkColor white = { 0, 0xff00, 0xff00, 0xff00 };
+GdkColor red = { 0, 0xff00, 0, 0 };
+GdkColor green = { 0, 0, 0xff00, 0 };
+GdkColor blue = { 0, 0, 0, 0xff00 };
+GdkColor lightblue = { 0, 0xbe00, 0xbe00, 0xff00 };
+
+static GdkColor token_colors[MAX_PLAYERS] = {
+ {0, 0xCD00, 0x0000, 0x0000}, /* red */
+ {0, 0x1E00, 0x9000, 0xFF00}, /* blue */
+ {0, 0xE800, 0xE800, 0xE800}, /* white */
+ {0, 0xFF00, 0x7F00, 0x0000}, /* orange */
+ {0, 0xEE00, 0xEE00, 0x0000}, /* yellow */
+ {0, 0x8E00, 0xE500, 0xEE00}, /* cyan */
+ {0, 0xD100, 0x5F00, 0xEE00}, /* magenta */
+ {0, 0x0000, 0xEE00, 0x7600} /* green */
+};
+
+void colors_init(void)
+{
+ GdkColormap *cmap;
+ gint idx;
+
+ cmap = gdk_colormap_get_system();
+ for (idx = 0; idx < G_N_ELEMENTS(token_colors); idx++) {
+ /* allocate colours for the players */
+ gdk_colormap_alloc_color(cmap, &token_colors[idx], FALSE,
+ TRUE);
+ }
+
+ gdk_colormap_alloc_color(cmap, &black, FALSE, TRUE);
+ gdk_colormap_alloc_color(cmap, &white, FALSE, TRUE);
+ gdk_colormap_alloc_color(cmap, &red, FALSE, TRUE);
+ gdk_colormap_alloc_color(cmap, &green, FALSE, TRUE);
+ gdk_colormap_alloc_color(cmap, &blue, FALSE, TRUE);
+ gdk_colormap_alloc_color(cmap, &lightblue, FALSE, TRUE);
+}
+
+GdkColor *colors_get_player(gint player_num)
+{
+ g_assert(player_num >= 0);
+ g_assert(player_num < MAX_PLAYERS);
+ return &token_colors[player_num];
+}
Added: trunk/common/gtk/colors.h
===================================================================
--- trunk/common/gtk/colors.h (rev 0)
+++ trunk/common/gtk/colors.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,37 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __colors_h
+#define __colors_h
+
+#include <gdk/gdk.h>
+
+extern GdkColor black;
+extern GdkColor white;
+extern GdkColor red;
+extern GdkColor green;
+extern GdkColor blue;
+extern GdkColor lightblue;
+
+void colors_init(void);
+
+GdkColor *colors_get_player(gint player_num);
+
+#endif
Added: trunk/common/gtk/common_gtk.c
===================================================================
--- trunk/common/gtk/common_gtk.c (rev 0)
+++ trunk/common/gtk/common_gtk.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,327 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <gtk/gtk.h>
+#include <string.h>
+#include "game.h"
+#include "state.h"
+#include "common_gtk.h"
+#include "cards.h"
+
+static GtkWidget *message_txt;
+static gboolean msg_colors = TRUE;
+
+/* Local function prototypes */
+static void gtk_event_cleanup(void);
+static void message_window_log_message_string(gint msg_type,
+ const gchar * text);
+
+/* Set the default logging function to write to the message window. */
+void log_set_func_message_window(void)
+{
+ driver->log_write = message_window_log_message_string;
+}
+
+void log_set_func_message_color_enable(gboolean enable)
+{
+ msg_colors = enable;
+}
+
+/* Write a message string to the console, setting its color based on its
+ * type.
+ */
+void message_window_log_message_string(gint msg_type, const gchar * text)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+ GtkTextMark *end_mark;
+ const gchar *tagname;
+
+ if (message_txt == NULL)
+ return; /* No widget set */
+
+ /* First determine if the requested color is for chat.
+ * Chat colors are separately turned on/off
+ */
+ switch (msg_type) {
+ case MSG_PLAYER1:
+ tagname = "player1";
+ break;
+ case MSG_PLAYER2:
+ tagname = "player2";
+ break;
+ case MSG_PLAYER3:
+ tagname = "player3";
+ break;
+ case MSG_PLAYER4:
+ tagname = "player4";
+ break;
+ case MSG_PLAYER5:
+ tagname = "player5";
+ break;
+ case MSG_PLAYER6:
+ tagname = "player6";
+ break;
+ case MSG_PLAYER7:
+ tagname = "player7";
+ break;
+ case MSG_PLAYER8:
+ tagname = "player8";
+ break;
+ default:
+ /* Not chat related, check whether other messages
+ * use color
+ */
+ if (!msg_colors)
+ tagname = "black";
+ else
+ switch (msg_type) {
+ case MSG_ERROR:
+ tagname = "red";
+ break;
+ case MSG_TIMESTAMP:
+ case MSG_INFO:
+ tagname = "info";
+ break;
+ case MSG_CHAT:
+ tagname = "chat";
+ break;
+ case MSG_VIEWER_CHAT:
+ tagname = "chat";
+ break;
+ case MSG_RESOURCE:
+ tagname = "resource";
+ break;
+ case MSG_BUILD:
+ tagname = "build";
+ break;
+ case MSG_DICE:
+ tagname = "dice";
+ break;
+ case MSG_STEAL:
+ tagname = "steal";
+ break;
+ case MSG_TRADE:
+ tagname = "trade";
+ break;
+ case MSG_DEVCARD:
+ tagname = "devcard";
+ break;
+ case MSG_LARGESTARMY:
+ tagname = "largest";
+ break;
+ case MSG_LONGESTROAD:
+ tagname = "longest";
+ break;
+ case MSG_BEEP:
+ tagname = "beep";
+ break;
+ default:
+ tagname = "green";
+ };
+ break;
+ }
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(message_txt));
+
+ /* insert text at the end */
+ gtk_text_buffer_get_end_iter(buffer, &iter);
+ gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, text, -1,
+ tagname, NULL);
+
+ /* move cursor to the end */
+ gtk_text_buffer_get_end_iter(buffer, &iter);
+ gtk_text_buffer_place_cursor(buffer, &iter);
+
+ end_mark = gtk_text_buffer_get_mark(buffer, "end-mark");
+ g_assert(end_mark != NULL);
+ gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(message_txt), end_mark,
+ 0.0, FALSE, 0.0, 0.0);
+}
+
+/* set the text widget. */
+void message_window_set_text(GtkWidget * textWidget)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter iter;
+
+ message_txt = textWidget;
+
+ /* Prepare all tags */
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(message_txt));
+ gtk_text_buffer_create_tag(buffer, "black", "foreground", "black",
+ NULL);
+ gtk_text_buffer_create_tag(buffer, "red", "foreground", "red",
+ NULL);
+ gtk_text_buffer_create_tag(buffer, "green", "foreground", "green",
+ NULL);
+ gtk_text_buffer_create_tag(buffer, "build", "foreground",
+ "#BB0000", NULL);
+ gtk_text_buffer_create_tag(buffer, "chat", "foreground", "#0000FF",
+ NULL);
+ gtk_text_buffer_create_tag(buffer, "devcard", "foreground",
+ "#C6C613", NULL);
+ gtk_text_buffer_create_tag(buffer, "dice", "foreground", "#00AA00",
+ NULL);
+ gtk_text_buffer_create_tag(buffer, "info", "foreground", "#000000",
+ NULL);
+ gtk_text_buffer_create_tag(buffer, "largest", "foreground",
+ "#1CB5ED", NULL);
+ gtk_text_buffer_create_tag(buffer, "longest", "foreground",
+ "#1CB5ED", NULL);
+ gtk_text_buffer_create_tag(buffer, "resource", "foreground",
+ "#0000FF", NULL);
+ gtk_text_buffer_create_tag(buffer, "steal", "foreground",
+ "#A613C6", NULL);
+ gtk_text_buffer_create_tag(buffer, "trade", "foreground",
+ "#006600", NULL);
+ gtk_text_buffer_create_tag(buffer, "beep", "foreground", "#B7AE07",
+ NULL);
+ gtk_text_buffer_create_tag(buffer, "player1", "foreground",
+ "#CD0000", NULL);
+ gtk_text_buffer_create_tag(buffer, "player2", "foreground",
+ "#1E90FF", NULL);
+ gtk_text_buffer_create_tag(buffer, "player3", "foreground",
+ "#808080", NULL);
+ gtk_text_buffer_create_tag(buffer, "player4", "foreground",
+ "#FF7F00", NULL);
+ gtk_text_buffer_create_tag(buffer, "player5", "foreground",
+ "#AEAE00", NULL);
+ gtk_text_buffer_create_tag(buffer, "player6", "foreground",
+ "#8EB5BE", NULL);
+ gtk_text_buffer_create_tag(buffer, "player7", "foreground",
+ "#D15FBE", NULL);
+ gtk_text_buffer_create_tag(buffer, "player8", "foreground",
+ "#00BE76", NULL);
+ /* Set the mark that will mark the end of the text */
+ gtk_text_buffer_get_end_iter(buffer, &iter);
+ gtk_text_buffer_create_mark(buffer, "end-mark", &iter, FALSE);
+}
+
+static void gtk_event_cleanup(void)
+{
+ while (gtk_events_pending())
+ gtk_main_iteration();
+}
+
+UIDriver GTK_Driver = {
+ gtk_event_cleanup,
+
+ /* initially log to the console; change it to the message window after
+ * the message window is created. */
+ log_message_string_console,
+
+ NULL, /* add read input */
+ NULL, /* add write input */
+ NULL, /* remove input */
+
+ /* callbacks for the server; NULL for now -- let the server set them */
+ NULL, /* player added */
+ NULL, /* player renamed */
+ NULL, /* player removed */
+ NULL /* player renamed */
+};
+
+struct TFindData {
+ GtkTreeIter iter;
+ enum TFindResult result;
+ gint column;
+ gint number;
+};
+
+static gboolean find_integer_cb(GtkTreeModel * model,
+ G_GNUC_UNUSED GtkTreePath * path,
+ GtkTreeIter * iter, gpointer user_data)
+{
+ struct TFindData *data = (struct TFindData *) user_data;
+
+ int wanted = data->number;
+ int current;
+ gtk_tree_model_get(model, iter, data->column, ¤t, -1);
+ if (current > wanted) {
+ data->result = FIND_MATCH_INSERT_BEFORE;
+ data->iter = *iter;
+ return TRUE;
+ } else if (current == wanted) {
+ data->result = FIND_MATCH_EXACT;
+ data->iter = *iter;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+enum TFindResult find_integer_in_tree(GtkTreeModel * model,
+ GtkTreeIter * iter, gint column,
+ gint number)
+{
+ struct TFindData data;
+ data.column = column;
+ data.number = number;
+ data.result = FIND_NO_MATCH;
+ gtk_tree_model_foreach(model, find_integer_cb, &data);
+ if (data.result != FIND_NO_MATCH)
+ *iter = data.iter;
+ return data.result;
+}
+
+void check_victory_points(GameParams * params, GtkWindow * main_window)
+{
+ gchar *win_message;
+ gchar *point_specification;
+ WinnableState state;
+ GtkMessageType message_type;
+ GtkWidget *dialog;
+
+ state =
+ params_check_winnable_state(params, &win_message,
+ &point_specification);
+
+ switch (state) {
+ case PARAMS_WINNABLE:
+ message_type = GTK_MESSAGE_INFO;
+ break;
+ case PARAMS_WIN_BUILD_ALL:
+ message_type = GTK_MESSAGE_INFO;
+ break;
+ case PARAMS_WIN_PERHAPS:
+ message_type = GTK_MESSAGE_WARNING;
+ break;
+ case PARAMS_NO_WIN:
+ message_type = GTK_MESSAGE_ERROR;
+ break;
+ default:
+ message_type = GTK_MESSAGE_ERROR;
+ break; /* Avoid a GCC warning about message_type being possibly uninitialized */
+ }
+ dialog = gtk_message_dialog_new(main_window,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ message_type,
+ GTK_BUTTONS_OK, win_message);
+
+ gtk_message_dialog_format_secondary_text
+ (GTK_MESSAGE_DIALOG(dialog), "%s", point_specification);
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+
+ g_free(win_message);
+ g_free(point_specification);
+}
Added: trunk/common/gtk/common_gtk.h
===================================================================
--- trunk/common/gtk/common_gtk.h (rev 0)
+++ trunk/common/gtk/common_gtk.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,56 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __common_gtk_h
+#define __common_gtk_h
+
+#include "driver.h"
+#include "log.h"
+#include <gtk/gtk.h>
+
+/* Set the default logging function to write to the message window. */
+void log_set_func_message_window(void);
+
+/* Set if colors in message window are enabled */
+void log_set_func_message_color_enable(gboolean enable);
+
+/* set the text widget. */
+void message_window_set_text(GtkWidget * textWidget);
+
+enum TFindResult {
+ FIND_MATCH_EXACT,
+ FIND_MATCH_INSERT_BEFORE,
+ FIND_NO_MATCH
+};
+
+enum TFindResult find_integer_in_tree(GtkTreeModel * model,
+ GtkTreeIter * iter, gint column,
+ gint number);
+
+/** Check whether the game can be won, and display a messagebox
+ * about the distribution of the points.
+ * @param param The game
+ * @param main_window The main window for the dialog
+ */
+void check_victory_points(GameParams * param, GtkWindow * main_window);
+
+extern UIDriver GTK_Driver;
+
+#endif /* __common_gtk_h */
Added: trunk/common/gtk/config-gnome.c
===================================================================
--- trunk/common/gtk/config-gnome.c (rev 0)
+++ trunk/common/gtk/config-gnome.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,265 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2000 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2005 Roland Clobus <rclobus at bigfoot.com>
+ * Copyright (C) 2005 Ferenc Bánhidi <banhidi at inf.elte.hu>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* config-gnome.c -- configuration via. gnome-config
+ * initial draft
+ *
+ * 19 July 2000
+ * Bibek Sahu
+ */
+
+/*
+Functions that need mapping (so far):
+ // get
+ gnome_config_get_string_with_default( path, default_used_bool )
+ gnome_config_get_int_with_default( path, default_used_bool )
+
+ // set
+ gnome_config_set_string( path, string )
+ gnome_config_set_int( path, int )
+
+ // sync
+ gnome_config_sync() [?]
+
+----
+
+ To simplify a cross-platform API, we'll just demand that all
+configuration sets be synchronous. This is what most people expect, anyway.
+
+ Also, all the paths used for getting/setting items will be made
+relative, and a config prefix will be pushed on the stack by config_init().
+
+ The API is essentially mimics a subset of the gnome_config API, but I
+believe it's similar (at least in spirit) to the Windows Registry, at least
+on the surface.
+*/
+
+/*
+ The config API will contain the following items (for now):
+
+ void config_init( string absolute_path_prefix )
+
+ string config_get_string( string relative_path, pointer_to_bool default_used )
+ int config_get_int( string relative_path, pointer_to_bool default_used )
+
+ // all config_set_* functions must be synchronous
+ void config_set_string( string relative_path, string value )
+ void config_set_int( string relative_path, int value )
+*/
+
+#include "config.h"
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include "config-gnome.h"
+
+/* initialize configuration setup */
+
+static GKeyFile *keyfile = NULL;
+static gchar *filename = NULL;
+
+static void config_sync(void)
+{
+ gsize length;
+ GError *error = NULL;
+ gchar *data;
+
+ g_return_if_fail(filename != NULL);
+
+ data = g_key_file_to_data(keyfile, &length, &error);
+
+ if (!error) {
+ int f = open(filename, O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR);
+ if (f == -1) {
+ /* Create the config dir, if it is missing */
+ /* Access mode: 0700 (drwx------) */
+ g_mkdir(g_get_user_config_dir(), S_IRWXU);
+ f = open(filename, O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR);
+ };
+ if (f != -1) {
+ write(f, data, length);
+ close(f);
+ } else {
+ g_warning("Could not write settings file");
+ }
+ } else {
+ g_warning("Could not write settings file: %s",
+ error->message);
+ g_error_free(error);
+ }
+}
+
+/* set the prefix in some static manner so that we don't need to hard-code
+ * it in the main code. Thus, different architectures can have different
+ * prefixes depending on what's relevant for said arch.
+ */
+void config_init(const gchar * path_prefix)
+{
+ GError *error = NULL;
+
+ /* Don't initialize more than once */
+ g_return_if_fail(keyfile == NULL);
+
+ keyfile = g_key_file_new();
+
+ filename =
+ g_build_filename(g_get_user_config_dir(), path_prefix, NULL);
+
+ g_key_file_load_from_file(keyfile, filename,
+ G_KEY_FILE_KEEP_COMMENTS |
+ G_KEY_FILE_KEEP_TRANSLATIONS, &error);
+
+ if (error != NULL) {
+ g_warning("Error while loading settings: %s",
+ error->message);
+ g_error_free(error);
+ }
+}
+
+void config_finish(void)
+{
+ g_free(filename);
+ g_key_file_free(keyfile);
+}
+
+/* get configuration settings */
+
+/* get a string. If a default is sent as part of the path, and the default
+ * is returned, set *default_used to TRUE.
+ */
+gchar *config_get_string(const gchar * path, gboolean * default_used)
+{
+ gchar **tokens;
+ gchar *value;
+ GError *error = NULL;
+
+ g_return_val_if_fail(keyfile != NULL, g_strdup(""));
+
+ tokens = g_strsplit_set(path, "/=", 3);
+
+ value =
+ g_key_file_get_string(keyfile, tokens[0], tokens[1], &error);
+ if (error != NULL) {
+ if (tokens[2] == NULL) {
+ value = g_strdup("");
+ } else {
+ value = g_strdup(tokens[2]);
+ }
+ *default_used = TRUE;
+ g_error_free(error);
+ } else {
+ *default_used = FALSE;
+ }
+ g_strfreev(tokens);
+ return value;
+}
+
+/* get an integer. If a default is sent as part of the path, and the
+ * default is returned, set *default_used to TRUE.
+ */
+gint config_get_int(const gchar * path, gboolean * default_used)
+{
+ gchar **tokens;
+ gint value;
+ GError *error = NULL;
+
+ g_return_val_if_fail(keyfile != NULL, 0);
+
+ tokens = g_strsplit_set(path, "/=", 3);
+
+ value =
+ g_key_file_get_integer(keyfile, tokens[0], tokens[1], &error);
+ if (error != NULL) {
+ if (tokens[2] == NULL) {
+ value = 0;
+ } else {
+ value = atoi(tokens[2]);
+ }
+ *default_used = TRUE;
+ g_error_free(error);
+ } else {
+ *default_used = FALSE;
+ }
+ g_strfreev(tokens);
+ return value;
+}
+
+/* get an integer. If the setting is not found, return the default value */
+gint config_get_int_with_default(const gchar * path, gint default_value)
+{
+ gboolean default_used;
+ gchar *temp;
+ gint value;
+
+ temp = g_strdup_printf("%s=%d", path, default_value);
+ value = config_get_int(temp, &default_used);
+ g_free(temp);
+ return value;
+}
+
+/* set configuration settings */
+/* these MUST be synchronous */
+
+/* set a string; make sure the configuration set is sync'd afterwards. */
+void config_set_string(const gchar * path, const gchar * value)
+{
+ gchar **tokens;
+
+ g_return_if_fail(keyfile != NULL);
+
+ tokens = g_strsplit_set(path, "/", 2);
+
+ if (tokens[1] == NULL) {
+ g_warning("Key is missing");
+ } else {
+ g_key_file_set_string(keyfile, tokens[0], tokens[1],
+ value);
+ }
+ g_strfreev(tokens);
+ config_sync();
+}
+
+/* set an int; make sure the configuration set is sync'd afterwards. */
+void config_set_int(const gchar * path, gint value)
+{
+ gchar **tokens;
+
+ g_return_if_fail(keyfile != NULL);
+
+ tokens = g_strsplit_set(path, "/", 2);
+
+ if (tokens[1] == NULL) {
+ g_warning("Key is missing");
+ } else {
+ g_key_file_set_integer(keyfile, tokens[0], tokens[1],
+ value);
+ }
+ g_strfreev(tokens);
+ config_sync();
+}
Added: trunk/common/gtk/config-gnome.h
===================================================================
--- trunk/common/gtk/config-gnome.h (rev 0)
+++ trunk/common/gtk/config-gnome.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,93 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2000 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* config-gnome.h -- configuration via. gnome-config (header)
+ * initial draft
+ *
+ * 19 July 2000
+ * Bibek Sahu
+ */
+
+/*************************** description *******************************
+
+ To simplify a cross-platform API, we'll just demand that all
+configuration sets be synchronous. This is what most people expect, anyway.
+
+ Also, all the paths used for getting/setting items will be made
+relative, and a config prefix will be pushed on the stack by config_init().
+
+ The API is essentially mimics a subset of the gnome_config API, but I
+believe it's similar (at least in spirit) to the Windows Registry, at least
+on the surface.
+
+
+ The config API will contain the following items (for now):
+
+ void config_init( string absolute_path_prefix )
+
+ string config_get_string( string relative_path, pointer_to_bool default_used )
+ int config_get_int( string relative_path, pointer_to_bool default_used )
+
+ // all config_set_* functions must be synchronous
+ void config_set_string( string relative_path, string value )
+ void config_set_int( string relative_path, int value )
+
+************************* end description *****************************/
+
+/* necessary headers */
+#include <glib.h>
+
+/******************************* functions **************************/
+
+/**** initialize configuration setup ****/
+
+/* set the prefix in some static manner so that we don't need to hard-code
+ * it in the main code. Thus, different architectures can have different
+ * prefixes depending on what's relevant for said arch.
+ */
+void config_init(const gchar * path_prefix);
+
+/** Free resources */
+void config_finish(void);
+
+/**** get configuration settings ****/
+
+/* get a string. If a default is sent as part of the path, and the default
+ * is returned, set *default_used to 1.
+ */
+gchar *config_get_string(const gchar * path, gboolean * default_used);
+
+/* get an integer. If a default is sent as part of the path, and the
+ * default is returned, set *default_used to 1.
+ */
+gint config_get_int(const gchar * path, gboolean * default_used);
+
+/* get an integer. If the setting is not found, return the default value */
+gint config_get_int_with_default(const gchar * path, gint default_value);
+
+/**** set configuration settings ****/
+/* these MUST be synchronous */
+
+/* set a string; make sure the configuration set is sync'd afterwards. */
+void config_set_string(const gchar * path, const gchar * value);
+
+/* set an int; make sure the configuration set is sync'd afterwards. */
+void config_set_int(const gchar * path, gint value);
Added: trunk/common/gtk/game-rules.c
===================================================================
--- trunk/common/gtk/game-rules.c (rev 0)
+++ trunk/common/gtk/game-rules.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,239 @@
+#include "config.h"
+#include "game.h"
+#include <gtk/gtksignal.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkcheckbutton.h>
+#include <gtk/gtkradiobutton.h>
+#include <gtk/gtkvbox.h>
+#include <string.h>
+#include <glib.h>
+
+#include "game-rules.h"
+
+static void game_rules_init(GameRules * sg);
+
+/* Register the class */
+GType game_rules_get_type(void)
+{
+ static GType gp_type = 0;
+
+ if (!gp_type) {
+ static const GTypeInfo gp_info = {
+ sizeof(GameRulesClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(GameRules),
+ 0,
+ (GInstanceInitFunc) game_rules_init,
+ NULL
+ };
+ gp_type =
+ g_type_register_static(GTK_TYPE_TABLE,
+ "GameRules", &gp_info, 0);
+ }
+ return gp_type;
+}
+
+static void add_row(GameRules * gr, const gchar * name,
+ const gchar * tooltip, gint row,
+ GtkCheckButton ** check)
+{
+ GtkWidget *check_btn;
+
+ check_btn = gtk_check_button_new_with_label(name);
+ gtk_widget_show(check_btn);
+ gtk_table_attach_defaults(GTK_TABLE(gr), check_btn,
+ 0, 2, row, row + 1);
+ *check = GTK_CHECK_BUTTON(check_btn);
+
+ gtk_tooltips_set_tip(gr->tooltips, check_btn, tooltip, NULL);
+}
+
+/* Build the composite widget */
+static void game_rules_init(GameRules * gr)
+{
+ GtkWidget *label;
+ GtkWidget *vbox_sevens;
+ gint idx;
+ gint row;
+
+ gr->tooltips = gtk_tooltips_new();
+
+ gtk_table_resize(GTK_TABLE(gr), 5, 2);
+ gtk_table_set_row_spacings(GTK_TABLE(gr), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(gr), 5);
+
+ row = 0;
+
+ label = gtk_label_new(_("Sevens Rule"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(gr), label, 0, 1, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ gr->radio_sevens[0] = gtk_radio_button_new_with_label(NULL,
+ /* Sevens rule: normal */
+ _("Normal"));
+ gr->radio_sevens[1] =
+ gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON
+ (gr->
+ radio_sevens[0]),
+ /* Sevens rule: reroll on 1st 2 turns */
+ _
+ ("Reroll on 1st 2 turns"));
+ gr->radio_sevens[2] =
+ gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON
+ (gr->
+ radio_sevens[0]),
+ /* Sevens rule: reroll all 7s */
+ _
+ ("Reroll all 7s"));
+
+ vbox_sevens = gtk_vbox_new(TRUE, 2);
+ gtk_widget_show(vbox_sevens);
+ gtk_tooltips_set_tip(gr->tooltips, gr->radio_sevens[0],
+ /* Tooltip for sevens rule normal */
+ _("All sevens move the robber or pirate"),
+ NULL);
+ gtk_tooltips_set_tip(gr->tooltips, gr->radio_sevens[1],
+ /* Tooltip for sevens rule reroll on 1st 2 turns */
+ _
+ ("In the first two turns all sevens are rerolled"),
+ NULL);
+ gtk_tooltips_set_tip(gr->tooltips, gr->radio_sevens[2],
+ /* Tooltip for sevens rule reroll all */
+ _("All sevens are rerolled"), NULL);
+
+ for (idx = 0; idx < 3; ++idx) {
+ gtk_widget_show(gr->radio_sevens[idx]);
+ gtk_box_pack_start_defaults(GTK_BOX(vbox_sevens),
+ gr->radio_sevens[idx]);
+ }
+ gtk_table_attach(GTK_TABLE(gr), vbox_sevens, 1, 2, row, row + 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+
+ row++;
+ add_row(gr, _("Randomize Terrain"), _("Randomize the terrain"),
+ row++, &gr->random_terrain);
+ add_row(gr, _("Use Pirate"), _("Use the pirate to block ships"),
+ row++, &gr->use_pirate);
+ add_row(gr, _("Strict Trade"),
+ _("Allow trade only before building or buying"), row++,
+ &gr->strict_trade);
+ add_row(gr, _("Domestic Trade"), _("Allow trade between players"),
+ row++, &gr->domestic_trade);
+}
+
+/* Create a new instance of the widget */
+GtkWidget *game_rules_new(void)
+{
+ return GTK_WIDGET(g_object_new(game_rules_get_type(), NULL));
+}
+
+/* Create a new instance with only the changes that can be applied by the metaserver */
+GtkWidget *game_rules_new_metaserver(void)
+{
+ GameRules *widget =
+ GAMERULES(g_object_new(game_rules_get_type(), NULL));
+ gtk_widget_hide(GTK_WIDGET(widget->use_pirate));
+ gtk_widget_hide(GTK_WIDGET(widget->strict_trade));
+ gtk_widget_hide(GTK_WIDGET(widget->domestic_trade));
+ return GTK_WIDGET(widget);
+}
+
+void game_rules_set_random_terrain(GameRules * gr, gboolean val)
+{
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gr->random_terrain),
+ val);
+}
+
+gboolean game_rules_get_random_terrain(GameRules * gr)
+{
+ return
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
+ (gr->random_terrain));
+}
+
+/* Set the sevens rule
+ * 0 = Normal
+ * 1 = Reroll first two turns
+ * 2 = Reroll all
+ */
+void game_rules_set_sevens_rule(GameRules * gr, guint sevens_rule)
+{
+ g_return_if_fail(sevens_rule < G_N_ELEMENTS(gr->radio_sevens));
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (gr->radio_sevens[sevens_rule]),
+ TRUE);
+
+}
+
+/* Get the sevens rule */
+guint game_rules_get_sevens_rule(GameRules * gr)
+{
+ gint idx;
+
+ for (idx = 0; idx < G_N_ELEMENTS(gr->radio_sevens); idx++)
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON(gr->radio_sevens[idx])))
+ return idx;
+ return 0;
+}
+
+
+void game_rules_set_use_pirate(GameRules * gr, gboolean val,
+ gint num_ships)
+{
+ if (num_ships == 0) {
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
+ (gr->use_pirate), TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(gr->use_pirate),
+ FALSE);
+ } else {
+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON
+ (gr->use_pirate),
+ FALSE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON
+ (gr->use_pirate), val);
+ gtk_widget_set_sensitive(GTK_WIDGET(gr->use_pirate), TRUE);
+ }
+}
+
+gboolean game_rules_get_use_pirate(GameRules * gr)
+{
+ return
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
+ (gr->use_pirate));
+}
+
+void game_rules_set_strict_trade(GameRules * gr, gboolean val)
+{
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gr->strict_trade),
+ val);
+}
+
+gboolean game_rules_get_strict_trade(GameRules * gr)
+{
+ return
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
+ (gr->strict_trade));
+}
+
+void game_rules_set_domestic_trade(GameRules * gr, gboolean val)
+{
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gr->domestic_trade),
+ val);
+}
+
+gboolean game_rules_get_domestic_trade(GameRules * gr)
+{
+ return
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON
+ (gr->domestic_trade));
+}
Added: trunk/common/gtk/game-rules.h
===================================================================
--- trunk/common/gtk/game-rules.h (rev 0)
+++ trunk/common/gtk/game-rules.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,51 @@
+#ifndef __GAMERULES_H__
+#define __GAMERULES_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtktable.h>
+
+G_BEGIN_DECLS
+#define GAMERULES_TYPE (game_rules_get_type ())
+#define GAMERULES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMERULES_TYPE, GameRules))
+#define GAMERULES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMERULES_TYPE, GameRulesClass))
+#define IS_GAMERULES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMERULES_TYPE))
+#define IS_GAMERULES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMERULES_TYPE))
+typedef struct _GameRules GameRules;
+typedef struct _GameRulesClass GameRulesClass;
+
+struct _GameRules {
+ GtkTable table;
+
+ GtkTooltips *tooltips;
+
+ GtkCheckButton *random_terrain;
+ GtkWidget *radio_sevens[3]; /* radio buttons for sevens rules */
+ GtkCheckButton *use_pirate;
+ GtkCheckButton *strict_trade;
+ GtkCheckButton *domestic_trade;
+};
+
+struct _GameRulesClass {
+ GtkTableClass parent_class;
+};
+
+GType game_rules_get_type(void);
+GtkWidget *game_rules_new(void);
+GtkWidget *game_rules_new_metaserver(void);
+
+void game_rules_set_random_terrain(GameRules * gr, gboolean val);
+gboolean game_rules_get_random_terrain(GameRules * gr);
+void game_rules_set_sevens_rule(GameRules * gr, guint sevens_rule);
+guint game_rules_get_sevens_rule(GameRules * gr);
+void game_rules_set_use_pirate(GameRules * gr, gboolean val,
+ gint num_ships);
+gboolean game_rules_get_use_pirate(GameRules * gr);
+void game_rules_set_strict_trade(GameRules * gr, gboolean val);
+gboolean game_rules_get_strict_trade(GameRules * gr);
+void game_rules_set_domestic_trade(GameRules * gr, gboolean val);
+gboolean game_rules_get_domestic_trade(GameRules * gr);
+
+G_END_DECLS
+#endif /* __GAMERULES_H__ */
Added: trunk/common/gtk/game-settings.c
===================================================================
--- trunk/common/gtk/game-settings.c (rev 0)
+++ trunk/common/gtk/game-settings.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,271 @@
+/* A custom widget for adjusting the game settings.
+ *
+ * The code is based on the TICTACTOE example
+ * www.gtk.org/tutorial/app-codeexamples.html#SEC-TICTACTOE
+ *
+ * Adaptation for Pioneers: 2004 Roland Clobus
+ *
+ */
+
+#include "config.h"
+#include "game.h"
+#include <gtk/gtksignal.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkspinbutton.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtkbutton.h>
+//#include <string.h>
+#include <gtk/gtkmessagedialog.h>
+#include <glib.h>
+
+#include "game-settings.h"
+#include "game.h"
+
+/* The signals */
+enum {
+ CHANGE,
+ CHANGE_PLAYERS,
+ CHECK,
+ LAST_SIGNAL
+};
+
+static void game_settings_class_init(GameSettingsClass * klass);
+static void game_settings_init(GameSettings * sg);
+static void game_settings_change_players(GtkSpinButton * widget,
+ GameSettings * gs);
+static void game_settings_change_victory_points(GtkSpinButton * widget,
+ GameSettings * gs);
+static void game_settings_check(GtkButton * widget, GameSettings * gs);
+static void game_settings_update(GameSettings * gs);
+
+/* All signals */
+static guint game_settings_signals[LAST_SIGNAL] = { 0, 0 };
+
+/* Register the class */
+GType game_settings_get_type(void)
+{
+ static GType gs_type = 0;
+
+ if (!gs_type) {
+ static const GTypeInfo gs_info = {
+ sizeof(GameSettingsClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) game_settings_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(GameSettings),
+ 0,
+ (GInstanceInitFunc) game_settings_init,
+ NULL
+ };
+ gs_type =
+ g_type_register_static(GTK_TYPE_TABLE, "GameSettings",
+ &gs_info, 0);
+ }
+ return gs_type;
+}
+
+/* Register the signals.
+ * GameSettings will emit two signals:
+ * 'change' when any change to one of the controls occurs.
+ * 'change-players' when the amount of player has changed.
+ */
+static void game_settings_class_init(GameSettingsClass * klass)
+{
+ game_settings_signals[CHANGE] = g_signal_new("change",
+ G_TYPE_FROM_CLASS
+ (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET
+ (GameSettingsClass,
+ change), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+ game_settings_signals[CHANGE_PLAYERS] =
+ g_signal_new("change-players", G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(GameSettingsClass,
+ change_players), NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
+ game_settings_signals[CHECK] =
+ g_signal_new("check", G_TYPE_FROM_CLASS(klass),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET(GameSettingsClass, check), NULL,
+ NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
+ 0);
+}
+
+/* Build the composite widget */
+static void game_settings_init(GameSettings * gs)
+{
+ GtkTooltips *tooltips;
+ GtkWidget *label;
+ GtkWidget *hbox;
+ GtkObject *adj;
+
+ tooltips = gtk_tooltips_new();
+
+ gtk_table_resize(GTK_TABLE(gs), 4, 2);
+ gtk_table_set_row_spacings(GTK_TABLE(gs), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(gs), 5);
+
+ /* Label text for customising a game */
+ label = gtk_label_new(_("Number of Players"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(gs), label, 0, 1, 1, 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ adj = gtk_adjustment_new(0, 2, MAX_PLAYERS, 1, 1, 1);
+ gs->players_spin = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
+ gtk_entry_set_alignment(GTK_ENTRY(gs->players_spin), 1.0);
+ gtk_widget_show(gs->players_spin);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(gs->players_spin),
+ TRUE);
+ gtk_table_attach(GTK_TABLE(gs), gs->players_spin, 1, 2, 1, 2,
+ GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ g_signal_connect(G_OBJECT(gs->players_spin), "value-changed",
+ G_CALLBACK(game_settings_change_players), gs);
+ gtk_tooltips_set_tip(tooltips, gs->players_spin,
+ /* Tooltip for 'Number of Players' */
+ _("The number of players"), NULL);
+
+ /* Label for customising a game */
+ label = gtk_label_new(_("Victory Point Target"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(gs), label, 0, 1, 2, 3,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ hbox = gtk_hbox_new(FALSE, 3);
+
+ adj = gtk_adjustment_new(10, 3, 99, 1, 1, 1);
+ gs->victory_spin = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
+ gtk_entry_set_alignment(GTK_ENTRY(gs->victory_spin), 1.0);
+ gtk_widget_show(gs->victory_spin);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(gs->victory_spin),
+ TRUE);
+ gtk_box_pack_start(GTK_BOX(hbox), gs->victory_spin, TRUE, TRUE, 0);
+ g_signal_connect(G_OBJECT(gs->victory_spin), "value-changed",
+ G_CALLBACK(game_settings_change_victory_points),
+ gs);
+ gtk_tooltips_set_tip(tooltips, gs->victory_spin,
+ /* Tooltip for Victory Point Target */
+ _("The points needed to win the game"), NULL);
+
+ gs->check_button = gtk_button_new();
+ gtk_button_set_image(GTK_BUTTON(gs->check_button),
+ gtk_image_new_from_stock(GTK_STOCK_APPLY,
+ GTK_ICON_SIZE_BUTTON));
+ gtk_widget_show(gs->check_button);
+ gtk_box_pack_start(GTK_BOX(hbox), gs->check_button, FALSE, FALSE,
+ 0);
+ g_signal_connect(G_OBJECT(gs->check_button), "clicked",
+ G_CALLBACK(game_settings_check), gs);
+ gtk_tooltips_set_tip(tooltips, gs->check_button,
+ /* Tooltip for the check button */
+ _("Is it possible to win this game?"), NULL);
+
+ gtk_table_attach(GTK_TABLE(gs), hbox, 1, 2, 2, 3,
+ GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show(hbox);
+
+ gs->players = 4;
+ gs->victory_points = 10;
+ game_settings_update(gs);
+}
+
+/* Create a new instance of the widget */
+GtkWidget *game_settings_new(gboolean with_check_button)
+{
+ GtkWidget *widget =
+ GTK_WIDGET(g_object_new(game_settings_get_type(), NULL));
+ if (with_check_button)
+ gtk_widget_show(GAMESETTINGS(widget)->check_button);
+ else
+ gtk_widget_hide(GAMESETTINGS(widget)->check_button);
+ return widget;
+}
+
+/* Emits 'change-players' when the number of players has changed */
+static void game_settings_change_players(GtkSpinButton * widget,
+ GameSettings * gs)
+{
+ gs->players = gtk_spin_button_get_value_as_int(widget);
+ game_settings_update(gs);
+ g_signal_emit(G_OBJECT(gs), game_settings_signals[CHANGE_PLAYERS],
+ 0);
+ g_signal_emit(G_OBJECT(gs), game_settings_signals[CHANGE], 0);
+}
+
+/* Callback when the points needed to win have changed */
+static void game_settings_change_victory_points(GtkSpinButton * widget,
+ GameSettings * gs)
+{
+ gs->victory_points = gtk_spin_button_get_value_as_int(widget);
+ game_settings_update(gs);
+ g_signal_emit(G_OBJECT(gs), game_settings_signals[CHANGE], 0);
+}
+
+/* Set the number of players */
+void game_settings_set_players(GameSettings * gs, guint players)
+{
+ gs->players = players;
+ game_settings_update(gs);
+}
+
+/* Get the number of players */
+guint game_settings_get_players(GameSettings * gs)
+{
+ return gs->players;
+}
+
+/* Set the points needed to win */
+void game_settings_set_victory_points(GameSettings * gs,
+ guint victory_points)
+{
+ gs->victory_points = victory_points;
+ game_settings_update(gs);
+}
+
+/* Get the points needed to win */
+guint game_settings_get_victory_points(GameSettings * gs)
+{
+ return gs->victory_points;
+}
+
+static void game_settings_check(G_GNUC_UNUSED GtkButton * widget,
+ GameSettings * gs)
+{
+ g_signal_emit(G_OBJECT(gs), game_settings_signals[CHECK], 0);
+}
+
+/* Update the display to the current state */
+static void game_settings_update(GameSettings * gs)
+{
+ /* Disable signals, to avoid recursive updates */
+ g_signal_handlers_block_matched(G_OBJECT(gs->players_spin),
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, gs);
+ g_signal_handlers_block_matched(G_OBJECT(gs->victory_spin),
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, gs);
+
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(gs->players_spin),
+ gs->players);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(gs->victory_spin),
+ gs->victory_points);
+
+ /* Reenable the signals */
+ g_signal_handlers_unblock_matched(G_OBJECT(gs->players_spin),
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, gs);
+ g_signal_handlers_unblock_matched(G_OBJECT(gs->victory_spin),
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, gs);
+}
Added: trunk/common/gtk/game-settings.h
===================================================================
--- trunk/common/gtk/game-settings.h (rev 0)
+++ trunk/common/gtk/game-settings.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,55 @@
+/* A custom widget for adjusting the game settings.
+ *
+ * The code is based on the TICTACTOE example
+ * www.gtk.oorg/tutorial/app-codeexamples.html#SEC-TICTACTOE
+ *
+ * Adaptation for Pioneers: 2004 Roland Clobus
+ *
+ */
+#ifndef __GAMESETTINGS_H__
+#define __GAMESETTINGS_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtktable.h>
+
+G_BEGIN_DECLS
+#define GAMESETTINGS_TYPE (game_settings_get_type ())
+#define GAMESETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMESETTINGS_TYPE, GameSettings))
+#define GAMESETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMESETTINGS_TYPE, GameSettingsClass))
+#define IS_GAMESETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMESETTINGS_TYPE))
+#define IS_GAMESETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMESETTINGS_TYPE))
+typedef struct _GameSettings GameSettings;
+typedef struct _GameSettingsClass GameSettingsClass;
+
+struct _GameSettings {
+ GtkTable table;
+
+ GtkWidget *victory_spin; /* victory point target */
+ GtkWidget *players_spin; /* number of players */
+ GtkWidget *check_button; /* check whether the game can be won */
+
+ guint players; /* The number of players */
+ guint victory_points; /* The points needed to win */
+};
+
+struct _GameSettingsClass {
+ GtkTableClass parent_class;
+
+ void (*change) (GameSettings * gs);
+ void (*change_players) (GameSettings * gs);
+ void (*check) (GameSettings * gs);
+};
+
+GType game_settings_get_type(void);
+GtkWidget *game_settings_new(gboolean with_check_button);
+
+void game_settings_set_players(GameSettings * gs, guint players);
+guint game_settings_get_players(GameSettings * gs);
+void game_settings_set_victory_points(GameSettings * gs,
+ guint victory_points);
+guint game_settings_get_victory_points(GameSettings * gs);
+
+G_END_DECLS
+#endif /* __GAMESETTINGS_H__ */
Added: trunk/common/gtk/gtkbugs.c
===================================================================
--- trunk/common/gtk/gtkbugs.c (rev 0)
+++ trunk/common/gtk/gtkbugs.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,91 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2005 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "gtkbugs.h"
+
+void set_pixbuf_tree_view_column_autogrow(GtkWidget * parent_widget,
+ GtkTreeViewColumn * column)
+{
+ if (gtk_major_version == 2
+ && (gtk_minor_version >= 5 && gtk_minor_version <= 6)) {
+ gint horizontal_separator, focus_line_width, icon_width;
+
+ gtk_tree_view_column_set_sizing(column,
+ GTK_TREE_VIEW_COLUMN_FIXED);
+ gtk_widget_style_get(parent_widget,
+ "horizontal_separator",
+ &horizontal_separator,
+ "focus-line-width", &focus_line_width,
+ NULL);
+ gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &icon_width,
+ NULL);
+ gtk_tree_view_column_set_fixed_width(column,
+ icon_width +
+ 2 *
+ horizontal_separator +
+ focus_line_width);
+ }
+}
+
+/** Since Gtk+ 2.6 you cannot press a button twice, without moving the
+ * mouse.
+ */
+void action_set_sensitive(GtkAction * action, gboolean sensitive)
+{
+ GSList *widgets;
+ widgets = gtk_action_get_proxies(action);
+ while (widgets) {
+ widget_set_sensitive(GTK_WIDGET(widgets->data), sensitive);
+ widgets = g_slist_next(widgets);
+ }
+ gtk_action_set_sensitive(action, sensitive);
+}
+
+void widget_set_sensitive(GtkWidget * widget, gboolean sensitive)
+{
+ GtkWidget *button;
+
+ gtk_widget_set_sensitive(widget, sensitive);
+
+ /** @bug Gtk bug 56070. If the mouse is over a toolbar button that
+ * becomes sensitive, one can't click it without moving the mouse out
+ * and in again. This bug is registered in Bugzilla as a Gtk bug. The
+ * workaround tests if the mouse is inside the currently sensitivized
+ * button, and if yes call button_enter()
+ */
+ if (!GTK_IS_BIN(widget))
+ return;
+
+ button = gtk_bin_get_child(GTK_BIN(widget));
+ if (sensitive && GTK_IS_BUTTON(button)) {
+ gint x, y, state;
+ gtk_widget_get_pointer(button, &x, &y);
+ state = GTK_WIDGET_STATE(button);
+ if ((state == GTK_STATE_NORMAL
+ || state == GTK_STATE_PRELIGHT) && x >= 0 && y >= 0
+ && x < button->allocation.width
+ && y < button->allocation.height) {
+ gtk_button_enter(GTK_BUTTON(button));
+ GTK_BUTTON(button)->in_button = TRUE;
+ gtk_widget_set_state(widget, GTK_STATE_PRELIGHT);
+ }
+ }
+}
Added: trunk/common/gtk/gtkbugs.h
===================================================================
--- trunk/common/gtk/gtkbugs.h (rev 0)
+++ trunk/common/gtk/gtkbugs.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,45 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2005 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __gtkbugs_h
+#define __gtkbugs_h
+
+#include <gtk/gtk.h>
+
+/** @bug 2005-07-25 In Gtk+ 2.6 the pixbuf column is
+ * one pixel too small, the focus_line_width is not used correctly.
+ * See also http://bugzilla.gnome.org/show_bug.cgi?id=147867
+ */
+void set_pixbuf_tree_view_column_autogrow(GtkWidget * parent_widget,
+ GtkTreeViewColumn * column);
+
+/** @bug 2006-01-15 In Gtk+ 2.4 it is not possible to disable actions.
+ * This will be close to its functionality, but will show -/- in the
+ * menus for the shortcut keys.
+ */
+void action_set_sensitive(GtkAction * action, gboolean sensitive);
+
+/** @bug Gtk bug 56070. If the mouse is over a button that becomes
+ * sensitive, one can't click it without moving the mouse out and in again.
+ */
+void widget_set_sensitive(GtkWidget * widget, gboolean sensitive);
+
+#endif
Added: trunk/common/gtk/guimap.c
===================================================================
--- trunk/common/gtk/guimap.c (rev 0)
+++ trunk/common/gtk/guimap.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,2034 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004-2007 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+
+#include "game.h"
+#include "map.h"
+#include "colors.h"
+#include "guimap.h"
+#include "log.h"
+#include "theme.h"
+
+static gboolean single_click_build_active = FALSE;
+
+typedef struct {
+ GuiMap *gmap;
+ gint old_highlight;
+} HighlightInfo;
+
+enum MapElementType {
+ MAP_EDGE,
+ MAP_NODE,
+ MAP_HEX
+};
+
+/* Local function prototypes */
+static void calc_edge_poly(const GuiMap * gmap, const Edge * edge,
+ const Polygon * shape, Polygon * poly);
+static void calc_node_poly(const GuiMap * gmap, const Node * node,
+ const Polygon * shape, Polygon * poly);
+static void calc_hex_poly(const GuiMap * gmap, const Hex * hex,
+ const Polygon * shape, Polygon * poly,
+ double scale_factor, gint x_shift);
+static void guimap_cursor_move(GuiMap * gmap, gint x, gint y,
+ MapElement * element);
+
+/* Square */
+static gint sqr(gint a)
+{
+ return a * a;
+}
+
+GdkPixmap *guimap_terrain(Terrain terrain)
+{
+ return theme_get_current()->terrain_tiles[terrain];
+}
+
+GuiMap *guimap_new(void)
+{
+ GuiMap *gmap;
+
+ gmap = g_malloc0(sizeof(*gmap));
+ gmap->highlight_chit = -1;
+ gmap->initial_font_size = -1;
+ gmap->show_nosetup_nodes = FALSE;
+ return gmap;
+}
+
+void guimap_delete(GuiMap * gmap)
+{
+ gint idx;
+
+ if (gmap->area != NULL) {
+ g_object_unref(gmap->area);
+ gmap->area = NULL;
+ }
+ if (gmap->pixmap != NULL) {
+ g_object_unref(gmap->pixmap);
+ gmap->pixmap = NULL;
+ }
+ if (gmap->gc != NULL) {
+ g_object_unref(gmap->gc);
+ gmap->gc = NULL;
+ }
+ if (gmap->hex_region != NULL) {
+ gdk_region_destroy(gmap->hex_region);
+ gmap->hex_region = NULL;
+ }
+ for (idx = 0; idx < 6; idx++) {
+ if (gmap->edge_region[idx] != NULL) {
+ gdk_region_destroy(gmap->edge_region[idx]);
+ gmap->edge_region[idx] = NULL;
+ }
+ if (gmap->node_region[idx] != NULL) {
+ gdk_region_destroy(gmap->node_region[idx]);
+ gmap->node_region[idx] = NULL;
+ }
+ }
+ if (gmap->layout) {
+ /* Restore the font size */
+ PangoContext *pc;
+ PangoFontDescription *pfd;
+
+ pc = pango_layout_get_context(gmap->layout);
+ pfd = pango_context_get_font_description(pc);
+
+ if (gmap->initial_font_size != -1) {
+ pango_font_description_set_size(pfd,
+ gmap->
+ initial_font_size);
+ }
+
+ g_object_unref(gmap->layout);
+ gmap->layout = NULL;
+ }
+ gmap->map = NULL;
+ g_free(gmap);
+}
+
+void guimap_reset(GuiMap * gmap)
+{
+ gmap->highlight_chit = -1;
+ gmap->player_num = -1;
+}
+
+static gint expose_map_cb(GtkWidget * area, GdkEventExpose * event,
+ gpointer user_data)
+{
+ GuiMap *gmap = user_data;
+
+ if (area->window == NULL || gmap->map == NULL)
+ return FALSE;
+
+ if (gmap->pixmap == NULL) {
+ gmap->pixmap = gdk_pixmap_new(area->window,
+ area->allocation.width,
+ area->allocation.height, -1);
+ guimap_display(gmap);
+ }
+
+ gdk_draw_drawable(area->window,
+ area->style->fg_gc[GTK_WIDGET_STATE(area)],
+ gmap->pixmap,
+ event->area.x, event->area.y,
+ event->area.x, event->area.y,
+ event->area.width, event->area.height);
+ return FALSE;
+}
+
+static gint configure_map_cb(GtkWidget * area,
+ G_GNUC_UNUSED GdkEventConfigure * event,
+ gpointer user_data)
+{
+ GuiMap *gmap = user_data;
+
+ if (area->window == NULL || gmap->map == NULL)
+ return FALSE;
+
+ if (gmap->pixmap) {
+ g_object_unref(gmap->pixmap);
+ gmap->pixmap = NULL;
+ }
+ guimap_scale_to_size(gmap,
+ area->allocation.width,
+ area->allocation.height);
+
+ gtk_widget_queue_draw(area);
+ return FALSE;
+}
+
+static gint motion_notify_map_cb(GtkWidget * area, GdkEventMotion * event,
+ gpointer user_data)
+{
+ GuiMap *gmap = user_data;
+ gint x;
+ gint y;
+ GdkModifierType state;
+ MapElement dummyElement;
+ g_assert(area != NULL);
+
+ if (area->window == NULL || gmap->map == NULL)
+ return FALSE;
+
+ if (event->is_hint)
+ gdk_window_get_pointer(event->window, &x, &y, &state);
+ else {
+ x = event->x;
+ y = event->y;
+ state = event->state;
+ }
+
+ dummyElement.pointer = NULL;
+ guimap_cursor_move(gmap, x, y, &dummyElement);
+
+ return TRUE;
+}
+
+GtkWidget *guimap_build_drawingarea(GuiMap * gmap, gint width, gint height)
+{
+ gmap->area = gtk_drawing_area_new();
+ g_object_ref(gmap->area);
+
+ gtk_widget_set_events(gmap->area, GDK_EXPOSURE_MASK
+ | GDK_POINTER_MOTION_MASK
+ | GDK_POINTER_MOTION_HINT_MASK);
+
+ gtk_widget_set_size_request(gmap->area, width, height);
+ g_signal_connect(G_OBJECT(gmap->area), "expose_event",
+ G_CALLBACK(expose_map_cb), gmap);
+ g_signal_connect(G_OBJECT(gmap->area), "configure_event",
+ G_CALLBACK(configure_map_cb), gmap);
+
+ g_signal_connect(G_OBJECT(gmap->area), "motion_notify_event",
+ G_CALLBACK(motion_notify_map_cb), gmap);
+
+ gtk_widget_show(gmap->area);
+
+ return gmap->area;
+}
+
+static GdkPoint settlement_points[] = {
+ {20, 20}, {20, -8}, {0, -28}, {-20, -8},
+ {-20, 20}, {20, 20}
+};
+static Polygon settlement_poly = {
+ settlement_points,
+ G_N_ELEMENTS(settlement_points)
+};
+static GdkPoint city_points[] = {
+ {40, 20}, {40, -16}, {2, -16}, {2, -28},
+ {-19, -48}, {-40, -28}, {-40, 20}, {40, 20}
+};
+static Polygon city_poly = {
+ city_points,
+ G_N_ELEMENTS(city_points)
+};
+static GdkPoint city_wall_points[] = {
+ {50, 36}, {50, -64}, {-50, -64}, {-50, 36}
+};
+static Polygon city_wall_poly = {
+ city_wall_points,
+ G_N_ELEMENTS(city_wall_points)
+};
+static GdkPoint nosetup_points[] = {
+ {0, 30}, {26, 15}, {26, -15}, {0, -30},
+ {-26, -15}, {-26, 15}, {0, 30}
+};
+static Polygon nosetup_poly = {
+ nosetup_points,
+ G_N_ELEMENTS(nosetup_points)
+};
+
+/* Update this when a node polygon is changed */
+#define NODE_MIN_X -50
+#define NODE_MAX_X 50
+#define NODE_MIN_Y -64
+#define NODE_MAX_Y 36
+
+static GdkPoint largest_node_points[] = {
+ {NODE_MIN_X, NODE_MIN_Y},
+ {NODE_MIN_X, NODE_MAX_Y},
+ {NODE_MAX_X, NODE_MAX_Y},
+ {NODE_MAX_X, NODE_MIN_Y}
+};
+static Polygon largest_node_poly = {
+ largest_node_points,
+ G_N_ELEMENTS(largest_node_points)
+};
+static GdkPoint road_points[] = {
+ {10, 40}, {10, -40}, {-10, -40}, {-10, 40},
+ {10, 40}
+};
+static Polygon road_poly = {
+ road_points,
+ G_N_ELEMENTS(road_points)
+};
+static GdkPoint ship_points[] = {
+ {10, 32}, {10, 8}, {24, 18}, {42, 8},
+ {48, 0}, {50, -12}, {10, -12}, {10, -32},
+ {2, -32}, {-6, -26}, {-10, -16}, {-10, 16},
+ {-6, 26}, {2, 32}, {10, 32}
+};
+static Polygon ship_poly = {
+ ship_points,
+ G_N_ELEMENTS(ship_points)
+};
+static GdkPoint bridge_points[] = {
+ {13, 40}, {-14, 40}, {-14, 30}, {-1, 15},
+ {-1, -15}, {-14, -30}, {-14, -40}, {13, -40},
+ {13, 40}
+};
+static Polygon bridge_poly = {
+ bridge_points,
+ G_N_ELEMENTS(bridge_points)
+};
+
+/* Update this when an edge polygon is changed */
+#define EDGE_MIN_X -14
+#define EDGE_MAX_X 50
+#define EDGE_MIN_Y -40
+#define EDGE_MAX_Y 40
+
+static GdkPoint largest_edge_points[] = {
+ {EDGE_MIN_X, EDGE_MIN_Y},
+ {EDGE_MIN_X, EDGE_MAX_Y},
+ {EDGE_MAX_X, EDGE_MAX_Y},
+ {EDGE_MAX_X, EDGE_MIN_Y}
+};
+static Polygon largest_edge_poly = {
+ largest_edge_points,
+ G_N_ELEMENTS(largest_edge_points)
+};
+
+static GdkPoint robber_points[] = {
+ {30, 60}, {30, 4}, {28, -6}, {22, -15},
+ {12, -20}, {22, -32}, {22, -48}, {10, -60},
+ {-10, -60}, {-22, -48}, {-22, -32}, {-12, -20},
+ {-22, -15}, {-28, -6}, {-30, 4}, {-30, 60},
+ {30, 60}
+};
+static Polygon robber_poly = {
+ robber_points,
+ G_N_ELEMENTS(robber_points)
+};
+static GdkPoint pirate_points[] = {
+ {42, 15}, {18, 15}, {28, 1}, {18, -17},
+ {10, -23}, {-2, -25}, {-2, 15}, {-22, 15},
+ {-22, 23}, {-16, 31}, {-6, 35}, {26, 35},
+ {36, 31}, {42, 23}, {42, 15}
+};
+static Polygon pirate_poly = {
+ pirate_points,
+ G_N_ELEMENTS(pirate_points)
+};
+
+static gint chances[13] = {
+ 0, 0, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1
+};
+
+static void calc_hex_pos(const GuiMap * gmap,
+ gint x, gint y, gint * x_offset, gint * y_offset)
+{
+ *x_offset = gmap->x_margin
+ + gmap->x_point + ((y % 2) ? gmap->x_point : 0)
+ + x * gmap->x_point * 2;
+ if (gmap->map->shrink_left)
+ *x_offset -= gmap->x_point;
+ *y_offset = gmap->y_margin
+ + gmap->hex_radius + y * (gmap->hex_radius + gmap->y_point);
+}
+
+static void get_hex_polygon(const GuiMap * gmap, Polygon * poly,
+ gboolean draw)
+{
+ GdkPoint *points;
+
+ g_assert(poly->num_points >= 6);
+
+ poly->num_points = 6;
+ points = poly->points;
+ points[0].x = gmap->x_point - draw;
+ points[0].y = -gmap->y_point;
+ points[1].x = 0;
+ points[1].y = -gmap->hex_radius;
+ points[2].x = -gmap->x_point;
+ points[2].y = -gmap->y_point;
+ points[3].x = -gmap->x_point;
+ points[3].y = gmap->y_point;
+ points[4].x = 0;
+ points[4].y = gmap->hex_radius;
+ points[5].x = gmap->x_point - draw;
+ points[5].y = gmap->y_point;
+}
+
+static void calc_edge_poly(const GuiMap * gmap, const Edge * edge,
+ const Polygon * shape, Polygon * poly)
+{
+ gint idx;
+ GdkPoint *poly_point, *shape_point;
+ double theta, cos_theta, sin_theta, scale;
+
+ g_assert(poly->num_points >= shape->num_points);
+ poly->num_points = shape->num_points;
+
+ /* Determine the angle for the polygon:
+ * Polygons on edges are rotated 0, 60 or 120 degrees CCW
+ * Polygons without edges are rotated 90 degrees CCW
+ */
+ theta =
+ 2 * M_PI * (edge != NULL ? 1 - (edge->pos % 3) / 6.0 : -0.25);
+ cos_theta = cos(theta);
+ sin_theta = sin(theta);
+ scale = (2 * gmap->y_point) / 120.0;
+
+ /* Rotate / scale all points
+ */
+ poly_point = poly->points;
+ shape_point = shape->points;
+ for (idx = 0; idx < shape->num_points;
+ idx++, shape_point++, poly_point++) {
+ poly_point->x = rint(scale * shape_point->x);
+ poly_point->y = rint(scale * shape_point->y);
+ if (edge == NULL || edge->pos % 3 > 0) {
+ gint x = poly_point->x;
+ gint y = poly_point->y;
+ poly_point->x =
+ rint(x * cos_theta - y * sin_theta);
+ poly_point->y =
+ rint(x * sin_theta + y * cos_theta);
+ }
+ }
+
+ /* Offset shape to hex & edge
+ */
+ if (edge != NULL) {
+ gint x_offset, y_offset;
+
+ /* Recalculate the angle for the position of the edge */
+ theta = 2 * M_PI * (1 - edge->pos / 6.0);
+ cos_theta = cos(theta);
+ sin_theta = sin(theta);
+
+ calc_hex_pos(gmap, edge->x, edge->y, &x_offset, &y_offset);
+ x_offset += gmap->x_point * cos_theta;
+ y_offset += gmap->x_point * sin_theta;
+ poly_offset(poly, x_offset, y_offset);
+ }
+}
+
+static void calc_node_poly(const GuiMap * gmap, const Node * node,
+ const Polygon * shape, Polygon * poly)
+{
+ gint idx;
+ GdkPoint *poly_point, *shape_point;
+ double scale;
+
+ g_assert(poly->num_points >= shape->num_points);
+ poly->num_points = shape->num_points;
+
+ scale = (2 * gmap->y_point) / 120.0;
+
+ /* Scale all points
+ */
+ poly_point = poly->points;
+ shape_point = shape->points;
+ for (idx = 0; idx < shape->num_points;
+ idx++, shape_point++, poly_point++) {
+ poly_point->x = rint(scale * shape_point->x);
+ poly_point->y = rint(scale * shape_point->y);
+ }
+
+ /* Offset shape to hex & node
+ */
+ if (node != NULL) {
+ gint x_offset, y_offset;
+ double theta;
+
+ calc_hex_pos(gmap, node->x, node->y, &x_offset, &y_offset);
+ theta = 2 * M_PI / 6.0 * node->pos + M_PI / 6.0;
+ theta = 2 * M_PI - theta;
+ x_offset += gmap->hex_radius * cos(theta);
+ y_offset += gmap->hex_radius * sin(theta);
+ poly_offset(poly, x_offset, y_offset);
+ }
+}
+
+static void calc_hex_poly(const GuiMap * gmap, const Hex * hex,
+ const Polygon * shape, Polygon * poly,
+ double scale_factor, gint x_shift)
+{
+ GdkPoint *poly_point, *shape_point;
+ double scale;
+ gint x_offset, y_offset;
+ gint idx;
+
+ g_assert(poly->num_points >= shape->num_points);
+ poly->num_points = shape->num_points;
+ scale = (2 * gmap->y_point) / scale_factor;
+
+ if (hex != NULL) {
+ calc_hex_pos(gmap, hex->x, hex->y, &x_offset, &y_offset);
+ x_offset += rint(scale * x_shift);
+ } else
+ x_offset = y_offset = 0;
+
+ /* Scale all points, offset to right
+ */
+ poly_point = poly->points;
+ shape_point = shape->points;
+ for (idx = 0; idx < shape->num_points;
+ idx++, shape_point++, poly_point++) {
+ poly_point->x = x_offset + rint(scale * shape_point->x);
+ poly_point->y = y_offset + rint(scale * shape_point->y);
+ }
+}
+
+void guimap_road_polygon(const GuiMap * gmap, const Edge * edge,
+ Polygon * poly)
+{
+ calc_edge_poly(gmap, edge, &road_poly, poly);
+}
+
+void guimap_ship_polygon(const GuiMap * gmap, const Edge * edge,
+ Polygon * poly)
+{
+ calc_edge_poly(gmap, edge, &ship_poly, poly);
+}
+
+void guimap_bridge_polygon(const GuiMap * gmap, const Edge * edge,
+ Polygon * poly)
+{
+ calc_edge_poly(gmap, edge, &bridge_poly, poly);
+}
+
+void guimap_city_polygon(const GuiMap * gmap, const Node * node,
+ Polygon * poly)
+{
+ calc_node_poly(gmap, node, &city_poly, poly);
+}
+
+void guimap_settlement_polygon(const GuiMap * gmap, const Node * node,
+ Polygon * poly)
+{
+ calc_node_poly(gmap, node, &settlement_poly, poly);
+}
+
+void guimap_city_wall_polygon(const GuiMap * gmap, const Node * node,
+ Polygon * poly)
+{
+ calc_node_poly(gmap, node, &city_wall_poly, poly);
+}
+
+static void guimap_nosetup_polygon(const GuiMap * gmap, const Node * node,
+ Polygon * poly)
+{
+ calc_node_poly(gmap, node, &nosetup_poly, poly);
+}
+
+static void guimap_robber_polygon(const GuiMap * gmap, const Hex * hex,
+ Polygon * poly)
+{
+ calc_hex_poly(gmap, hex, &robber_poly, poly, 140.0, 50);
+}
+
+static void guimap_pirate_polygon(const GuiMap * gmap, const Hex * hex,
+ Polygon * poly)
+{
+ calc_hex_poly(gmap, hex, &pirate_poly, poly, 80.0, 0);
+}
+
+void draw_dice_roll(PangoLayout * layout, GdkPixmap * pixmap, GdkGC * gc,
+ gint x_offset, gint y_offset, gint radius,
+ gint n, gint terrain, gboolean highlight)
+{
+ gchar num[10];
+ gint height;
+ gint width;
+ gint x, y;
+ gint idx;
+ MapTheme *theme = theme_get_current();
+ THEME_COLOR col;
+ TColor *tcol;
+ gint width_sqr;
+
+#define col_or_ovr(ter,cno) \
+ ((terrain < TC_MAX_OVRTILE && theme->ovr_colors[ter][cno].set) ? \
+ &(theme->ovr_colors[ter][cno]) : \
+ &(theme->colors[cno]))
+
+ gdk_gc_set_fill(gc, GDK_SOLID);
+ col = highlight ? TC_CHIP_H_BG : TC_CHIP_BG;
+ tcol = col_or_ovr(terrain, col);
+ if (!tcol->transparent) {
+ gdk_gc_set_foreground(gc, &(tcol->color));
+ gdk_draw_arc(pixmap, gc, TRUE,
+ x_offset - radius, y_offset - radius,
+ 2 * radius, 2 * radius, 0, 360 * 64);
+ }
+ tcol = col_or_ovr(terrain, TC_CHIP_BD);
+ if (!tcol->transparent) {
+ gdk_gc_set_foreground(gc, &(tcol->color));
+ gdk_draw_arc(pixmap, gc, FALSE,
+ x_offset - radius, y_offset - radius,
+ 2 * radius, 2 * radius, 0, 360 * 64);
+ }
+ col = (n == 6 || n == 8) ? TC_CHIP_H_FG : TC_CHIP_FG;
+ tcol = col_or_ovr(terrain, col);
+ if (!tcol->transparent) {
+ sprintf(num, "<b>%d</b>", n);
+ pango_layout_set_markup(layout, num, -1);
+ pango_layout_get_pixel_size(layout, &width, &height);
+ gdk_gc_set_foreground(gc, &(tcol->color));
+ gdk_draw_layout(pixmap, gc,
+ x_offset - width / 2,
+ y_offset - height / 2, layout);
+
+ width_sqr = sqr(radius) - sqr(height / 2);
+ if (width_sqr >= sqr(6 * 2)) {
+ /* Enough space available for the dots */
+ x = x_offset - chances[n] * 4 / 2;
+ y = y_offset - 1 + height / 2;
+ for (idx = 0; idx < chances[n]; idx++) {
+ gdk_draw_arc(pixmap, gc, TRUE,
+ x, y, 3, 3, 0, 360 * 64);
+ x += 4;
+ }
+ }
+ }
+}
+
+static gboolean display_hex(const Map * map, const Hex * hex,
+ const GuiMap * gmap)
+{
+ gint x_offset, y_offset;
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+ int idx;
+ const MapTheme *theme = theme_get_current();
+
+ calc_hex_pos(gmap, hex->x, hex->y, &x_offset, &y_offset);
+
+ /* Fill the hex with the nice pattern */
+ gdk_gc_set_line_attributes(gmap->gc, 1, GDK_LINE_SOLID,
+ GDK_CAP_BUTT, GDK_JOIN_MITER);
+ gdk_region_offset(gmap->hex_region, x_offset, y_offset);
+ gdk_gc_set_clip_region(gmap->gc, gmap->hex_region);
+ gdk_gc_set_fill(gmap->gc, GDK_TILED);
+ gdk_gc_set_tile(gmap->gc, theme->terrain_tiles[hex->terrain]);
+ gdk_gc_set_ts_origin(gmap->gc,
+ x_offset - gmap->x_point,
+ y_offset - gmap->hex_radius);
+ gdk_draw_rectangle(gmap->pixmap, gmap->gc, TRUE,
+ x_offset - gmap->hex_radius,
+ y_offset - gmap->hex_radius,
+ gmap->hex_radius * 2, gmap->hex_radius * 2);
+ gdk_region_offset(gmap->hex_region, -x_offset, -y_offset);
+ gdk_gc_set_clip_region(gmap->gc, NULL);
+
+ /* Draw border around hex */
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ get_hex_polygon(gmap, &poly, TRUE);
+ poly_offset(&poly, x_offset, y_offset);
+
+ gdk_gc_set_fill(gmap->gc, GDK_SOLID);
+ if (!theme->colors[TC_HEX_BD].transparent) {
+ gdk_gc_set_foreground(gmap->gc,
+ &theme->colors[TC_HEX_BD].color);
+ if (hex->terrain != SEA_TERRAIN)
+ poly_draw(gmap->pixmap, gmap->gc, FALSE, &poly);
+ }
+
+ /* Draw the dice roll */
+ if (hex->roll > 0 && gmap->chit_radius > 0) {
+ g_assert(gmap->layout);
+ draw_dice_roll(gmap->layout, gmap->pixmap, gmap->gc,
+ x_offset, y_offset, gmap->chit_radius,
+ hex->roll, hex->terrain,
+ !hex->robber
+ && hex->roll == gmap->highlight_chit);
+ }
+
+ /* Draw ports */
+ if (hex->resource != NO_RESOURCE && gmap->chit_radius > 0) {
+ const gchar *str = "";
+ gint width, height;
+ int tileno = hex->resource == ANY_RESOURCE ?
+ ANY_PORT_TILE : hex->resource;
+ gboolean drawit;
+ gboolean typeind;
+
+ /* Draw lines from port to shore */
+ gdk_gc_set_foreground(gmap->gc, &white);
+ gdk_gc_set_line_attributes(gmap->gc, 1,
+ GDK_LINE_ON_OFF_DASH,
+ GDK_CAP_BUTT, GDK_JOIN_MITER);
+ gdk_draw_line(gmap->pixmap, gmap->gc, x_offset, y_offset,
+ points[(hex->facing + 5) % 6].x,
+ points[(hex->facing + 5) % 6].y);
+ gdk_draw_line(gmap->pixmap, gmap->gc, x_offset, y_offset,
+ points[hex->facing].x,
+ points[hex->facing].y);
+ /* Fill/tile port indicator */
+ if (theme->port_tiles[tileno]) {
+ gdk_gc_set_fill(gmap->gc, GDK_TILED);
+ gdk_gc_set_tile(gmap->gc,
+ theme->port_tiles[tileno]);
+ gdk_gc_set_ts_origin(gmap->gc,
+ x_offset -
+ theme->
+ port_tiles_width[tileno] / 2,
+ y_offset -
+ theme->
+ port_tiles_height[tileno] /
+ 2);
+ typeind = TRUE;
+ drawit = TRUE;
+ } else if (!theme->colors[TC_PORT_BG].transparent) {
+ gdk_gc_set_fill(gmap->gc, GDK_SOLID);
+ gdk_gc_set_foreground(gmap->gc,
+ &theme->colors[TC_PORT_BG].
+ color);
+ typeind = FALSE;
+ drawit = TRUE;
+ } else {
+ typeind = FALSE;
+ drawit = FALSE;
+ }
+ if (drawit) {
+ gdk_draw_arc(gmap->pixmap, gmap->gc, TRUE,
+ x_offset - gmap->chit_radius,
+ y_offset - gmap->chit_radius,
+ 2 * gmap->chit_radius,
+ 2 * gmap->chit_radius, 0, 360 * 64);
+ }
+ gdk_gc_set_fill(gmap->gc, GDK_SOLID);
+ /* Outline port indicator */
+ if (!theme->colors[TC_PORT_BD].transparent) {
+ gdk_gc_set_line_attributes(gmap->gc, 1,
+ GDK_LINE_SOLID,
+ GDK_CAP_BUTT,
+ GDK_JOIN_MITER);
+ gdk_gc_set_foreground(gmap->gc,
+ &theme->colors[TC_PORT_BD].
+ color);
+ gdk_draw_arc(gmap->pixmap, gmap->gc, FALSE,
+ x_offset - gmap->chit_radius,
+ y_offset - gmap->chit_radius,
+ 2 * gmap->chit_radius,
+ 2 * gmap->chit_radius, 0, 360 * 64);
+ }
+ /* Print trading ratio */
+ if (!theme->colors[TC_PORT_FG].transparent) {
+ if (typeind) {
+ if (hex->resource < NO_RESOURCE)
+ /* Port indicator for a resource: trade 2 for 1 */
+ str = _("2:1");
+ else
+ /* Port indicator: trade 3 for 1 */
+ str = _("3:1");
+ } else {
+ switch (hex->resource) {
+ case BRICK_RESOURCE:
+ /* Port indicator for brick */
+ str = Q_("Brick port|B");
+ break;
+ case GRAIN_RESOURCE:
+ /* Port indicator for grain */
+ str = Q_("Grain port|G");
+ break;
+ case ORE_RESOURCE:
+ /* Port indicator for ore */
+ str = Q_("Ore port|O");
+ break;
+ case WOOL_RESOURCE:
+ /* Port indicator for wool */
+ str = Q_("Wool port|W");
+ break;
+ case LUMBER_RESOURCE:
+ /* Port indicator for lumber */
+ str = Q_("Lumber port|L");
+ break;
+ default:
+ /* General port indicator */
+ str = _("3:1");
+ break;
+ }
+ }
+ pango_layout_set_markup(gmap->layout, str, -1);
+ pango_layout_get_pixel_size(gmap->layout, &width,
+ &height);
+ gdk_gc_set_foreground(gmap->gc,
+ &theme->colors[TC_PORT_FG].
+ color);
+ gdk_draw_layout(gmap->pixmap, gmap->gc,
+ x_offset - width / 2,
+ y_offset - height / 2,
+ gmap->layout);
+ }
+ }
+
+ gdk_gc_set_line_attributes(gmap->gc, 1, GDK_LINE_SOLID,
+ GDK_CAP_BUTT, GDK_JOIN_MITER);
+ /* Draw all roads and ships */
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); idx++) {
+ const Edge *edge = hex->edges[idx];
+ if (edge->owner < 0)
+ continue;
+
+ poly.num_points = G_N_ELEMENTS(points);
+ switch (edge->type) {
+ case BUILD_ROAD:
+ guimap_road_polygon(gmap, edge, &poly);
+ break;
+ case BUILD_SHIP:
+ guimap_ship_polygon(gmap, edge, &poly);
+ break;
+ case BUILD_BRIDGE:
+ guimap_bridge_polygon(gmap, edge, &poly);
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+ poly_draw_with_border(gmap->pixmap, gmap->gc,
+ colors_get_player(edge->owner),
+ &black, &poly);
+ }
+
+ /* Draw all buildings */
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); idx++) {
+ const Node *node = hex->nodes[idx];
+ const GdkColor *color;
+
+ if (node->owner < 0 && !gmap->show_nosetup_nodes)
+ continue;
+
+ if (node->owner < 0) {
+ if (!node->no_setup)
+ continue;
+ color = &white;
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_nosetup_polygon(gmap, node, &poly);
+ } else {
+ color = colors_get_player(node->owner);
+
+ /* If there are city walls, draw them. */
+ if (node->city_wall) {
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_city_wall_polygon(gmap, node,
+ &poly);
+ poly_draw_with_border(gmap->pixmap,
+ gmap->gc, color,
+ &black, &poly);
+ }
+ /* Draw the building */
+ color = colors_get_player(node->owner);
+ poly.num_points = G_N_ELEMENTS(points);
+ if (node->type == BUILD_CITY)
+ guimap_city_polygon(gmap, node, &poly);
+ else
+ guimap_settlement_polygon(gmap, node,
+ &poly);
+ }
+
+ poly_draw_with_border(gmap->pixmap, gmap->gc, color,
+ &black, &poly);
+ }
+
+ /* Draw the robber */
+ if (hex->robber) {
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_robber_polygon(gmap, hex, &poly);
+ gdk_gc_set_line_attributes(gmap->gc, 1, GDK_LINE_SOLID,
+ GDK_CAP_BUTT, GDK_JOIN_MITER);
+ if (!theme->colors[TC_ROBBER_FG].transparent) {
+ gdk_gc_set_foreground(gmap->gc,
+ &theme->colors[TC_ROBBER_FG].
+ color);
+ poly_draw(gmap->pixmap, gmap->gc, TRUE, &poly);
+ }
+ if (!theme->colors[TC_ROBBER_BD].transparent) {
+ gdk_gc_set_foreground(gmap->gc,
+ &theme->colors[TC_ROBBER_BD].
+ color);
+ poly_draw(gmap->pixmap, gmap->gc, FALSE, &poly);
+ }
+ }
+
+ /* Draw the pirate */
+ if (hex == map->pirate_hex) {
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_pirate_polygon(gmap, hex, &poly);
+ gdk_gc_set_line_attributes(gmap->gc, 1, GDK_LINE_SOLID,
+ GDK_CAP_BUTT, GDK_JOIN_MITER);
+ if (!theme->colors[TC_ROBBER_FG].transparent) {
+ gdk_gc_set_foreground(gmap->gc,
+ &theme->colors[TC_ROBBER_FG].
+ color);
+ poly_draw(gmap->pixmap, gmap->gc, TRUE, &poly);
+ }
+ if (!theme->colors[TC_ROBBER_BD].transparent) {
+ gdk_gc_set_foreground(gmap->gc,
+ &theme->colors[TC_ROBBER_BD].
+ color);
+ poly_draw(gmap->pixmap, gmap->gc, FALSE, &poly);
+ }
+ }
+
+ return FALSE;
+}
+
+void guimap_scale_with_radius(GuiMap * gmap, gint radius)
+{
+ int idx;
+
+ if (radius < MIN_HEX_RADIUS)
+ radius = MIN_HEX_RADIUS;
+
+ gmap->hex_radius = radius;
+ gmap->x_point = radius * cos(M_PI / 6.0);
+ gmap->y_point = radius * sin(M_PI / 6.0);
+
+ gmap->x_margin = gmap->y_margin = 0;
+
+ if (gmap->map == NULL)
+ return;
+
+ gmap->width =
+ gmap->map->x_size * 2 * gmap->x_point + gmap->x_point;
+ gmap->height =
+ (gmap->map->y_size - 1) * (gmap->hex_radius + gmap->y_point)
+ + 2 * gmap->hex_radius;
+
+ if (gmap->map->shrink_left)
+ gmap->width -= gmap->x_point;
+ if (gmap->map->shrink_right)
+ gmap->width -= gmap->x_point;
+
+ if (gmap->gc != NULL) {
+ g_object_unref(gmap->gc);
+ gmap->gc = NULL;
+ }
+ if (gmap->hex_region != NULL) {
+ gdk_region_destroy(gmap->hex_region);
+ gmap->hex_region = NULL;
+ }
+ for (idx = 0; idx < 6; idx++) {
+ if (gmap->edge_region[idx] != NULL) {
+ gdk_region_destroy(gmap->edge_region[idx]);
+ gmap->edge_region[idx] = NULL;
+ }
+ if (gmap->node_region[idx] != NULL) {
+ gdk_region_destroy(gmap->node_region[idx]);
+ gmap->node_region[idx] = NULL;
+ }
+ }
+
+ gmap->chit_radius = 15;
+
+ theme_rescale(2 * gmap->x_point);
+}
+
+void guimap_scale_to_size(GuiMap * gmap, gint width, gint height)
+{
+ const gint reserved_width = 0;
+ const gint reserved_height = 0;
+ gint width_radius;
+ gint height_radius;
+ width_radius = (width - reserved_width)
+ / ((gmap->map->x_size * 2 + 1
+ - gmap->map->shrink_left
+ - gmap->map->shrink_right) * cos(M_PI / 6.0));
+ height_radius = (height - reserved_height)
+ / ((gmap->map->y_size - 1)
+ * (sin(M_PI / 6.0) + 1) + 2);
+
+ if (width_radius < height_radius)
+ guimap_scale_with_radius(gmap, width_radius);
+ else
+ guimap_scale_with_radius(gmap, height_radius);
+
+ gmap->x_margin += (width - gmap->width) / 2;
+ gmap->y_margin += (height - gmap->height) / 2;
+
+ gmap->width = width;
+ gmap->height = height;
+}
+
+static void build_hex_region(GuiMap * gmap)
+{
+ GdkPoint points[6];
+ Polygon poly;
+
+ if (gmap->hex_region != NULL)
+ return;
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ get_hex_polygon(gmap, &poly, FALSE);
+ gmap->hex_region = gdk_region_polygon(points, G_N_ELEMENTS(points),
+ GDK_EVEN_ODD_RULE);
+}
+
+/** @return The radius of the chit for the current font size */
+gint guimap_get_chit_radius(PangoLayout * layout, gboolean show_dots)
+{
+ gint width, height;
+ gint size_for_99_sqr;
+ gint size_for_port_sqr;
+ gint size_for_text_sqr;
+
+ /* Calculate the maximum size of the text in the chits */
+ pango_layout_set_markup(layout, "<b>99</b>", -1);
+ pango_layout_get_pixel_size(layout, &width, &height);
+ size_for_99_sqr = sqr(width) + sqr(height);
+
+ pango_layout_set_markup(layout, "3:1", -1);
+ pango_layout_get_pixel_size(layout, &width, &height);
+ size_for_port_sqr = sqr(width) + sqr(height);
+
+ size_for_text_sqr = MAX(size_for_99_sqr, size_for_port_sqr);
+ if (show_dots) {
+ gint size_with_dots = sqr(height / 2 + 2) + sqr(6 * 2);
+ if (size_with_dots * 4 > size_for_text_sqr)
+ return sqrt(size_with_dots);
+ }
+ /* Divide: calculations should have been sqr(width/2)+sqr(height/2) */
+ return sqrt(size_for_text_sqr) / 2;
+}
+
+void guimap_display(GuiMap * gmap)
+{
+ gint maximum_size;
+ gint size_for_text;
+ PangoContext *pc;
+ PangoFontDescription *pfd;
+ gint font_size;
+
+ if (gmap->pixmap == NULL)
+ return;
+
+ if (gmap->gc != NULL) {
+ /* Unref old gc */
+ g_object_unref(gmap->gc);
+ }
+
+ gmap->gc = gdk_gc_new(gmap->pixmap);
+ build_hex_region(gmap);
+
+ gdk_gc_set_fill(gmap->gc, GDK_TILED);
+ gdk_gc_set_tile(gmap->gc,
+ theme_get_current()->terrain_tiles[BOARD_TILE]);
+ gdk_draw_rectangle(gmap->pixmap, gmap->gc, TRUE, 0, 0,
+ gmap->width, gmap->height);
+
+ if (gmap->layout != NULL)
+ g_object_unref(gmap->layout);
+ gmap->layout = gtk_widget_create_pango_layout(gmap->area, "");
+
+ /* Manipulate the font size */
+ pc = pango_layout_get_context(gmap->layout);
+ pfd = pango_context_get_font_description(pc);
+
+ /* Store the initial font size, since it is remembered for the area */
+ if (gmap->initial_font_size == -1) {
+ font_size = pango_font_description_get_size(pfd);
+ gmap->initial_font_size = font_size;
+ } else {
+ font_size = gmap->initial_font_size;
+ }
+
+ /* The radius of the chit is at most 67% of the tile,
+ * so the terrain can be seen.
+ */
+ maximum_size = gmap->hex_radius * 2 / 3;
+
+ /* First attempt to fit the text and the dots in the chit */
+ pango_font_description_set_size(pfd, font_size);
+ pango_layout_set_font_description(gmap->layout, pfd);
+
+ size_for_text = guimap_get_chit_radius(gmap->layout, TRUE);
+
+ /* Shrink the font size until the letters fit in the chit */
+ while (maximum_size < size_for_text && font_size > 0) {
+ pango_font_description_set_size(pfd, font_size);
+ pango_layout_set_font_description(gmap->layout, pfd);
+ font_size -= PANGO_SCALE;
+
+ size_for_text =
+ guimap_get_chit_radius(gmap->layout, FALSE);
+ };
+ if (font_size <= 0) {
+ gmap->chit_radius = 0;
+ } else {
+ gmap->chit_radius = size_for_text;
+ }
+
+ map_traverse(gmap->map, (HexFunc) display_hex, gmap);
+}
+
+static const Edge *find_hex_edge(GuiMap * gmap, const Hex * hex, gint x,
+ gint y)
+{
+ gint x_offset, y_offset;
+ int idx;
+
+ calc_hex_pos(gmap, hex->x, hex->y, &x_offset, &y_offset);
+ x -= x_offset;
+ y -= y_offset;
+ for (idx = 0; idx < 6; idx++)
+ if (gdk_region_point_in(gmap->edge_region[idx], x, y))
+ return hex->edges[idx];
+ return NULL;
+}
+
+static void build_edge_regions(GuiMap * gmap)
+{
+ int idx;
+ GdkPoint points[6];
+ Polygon poly;
+
+ if (gmap->edge_region[0] != NULL)
+ return;
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ get_hex_polygon(gmap, &poly, FALSE);
+ for (idx = 0; idx < 6; idx++) {
+ GdkPoint edge[4];
+
+ edge[0].x = edge[0].y = 0;
+ edge[1] = points[idx];
+ edge[3] = points[(idx + 5) % 6];
+ switch (idx) {
+ case 0:
+ edge[2].x = 2 * gmap->x_point;
+ edge[2].y = 0;
+ break;
+ case 1:
+ edge[2].x = gmap->x_point;
+ edge[2].y = -gmap->hex_radius - gmap->y_point;
+ break;
+ case 2:
+ edge[2].x = -gmap->x_point;
+ edge[2].y = -gmap->hex_radius - gmap->y_point;
+ break;
+ case 3:
+ edge[2].x = -2 * gmap->x_point;
+ edge[2].y = 0;
+ break;
+ case 4:
+ edge[2].x = -gmap->x_point;
+ edge[2].y = gmap->hex_radius + gmap->y_point;
+ break;
+ case 5:
+ edge[2].x = gmap->x_point;
+ edge[2].y = gmap->hex_radius + gmap->y_point;
+ break;
+ }
+ gmap->edge_region[idx]
+ = gdk_region_polygon(edge, 4, GDK_EVEN_ODD_RULE);
+ }
+}
+
+static void find_edge(GuiMap * gmap, gint x, gint y, MapElement * element)
+{
+ gint y_hex;
+ gint x_hex;
+
+ build_edge_regions(gmap);
+ for (x_hex = 0; x_hex < gmap->map->x_size; x_hex++)
+ for (y_hex = 0; y_hex < gmap->map->y_size; y_hex++) {
+ const Hex *hex;
+ const Edge *edge;
+
+ hex = gmap->map->grid[y_hex][x_hex];
+ if (hex != NULL) {
+ edge = find_hex_edge(gmap, hex, x, y);
+ if (edge != NULL) {
+ element->edge = edge;
+ return;
+ }
+ }
+ }
+ element->pointer = NULL;
+}
+
+static Node *find_hex_node(GuiMap * gmap, const Hex * hex, gint x, gint y)
+{
+ gint x_offset, y_offset;
+ int idx;
+
+ calc_hex_pos(gmap, hex->x, hex->y, &x_offset, &y_offset);
+ x -= x_offset;
+ y -= y_offset;
+ for (idx = 0; idx < 6; idx++)
+ if (gdk_region_point_in(gmap->node_region[idx], x, y))
+ return hex->nodes[idx];
+ return NULL;
+}
+
+static void build_node_regions(GuiMap * gmap)
+{
+ int idx;
+
+ if (gmap->node_region[0] != NULL)
+ return;
+
+ for (idx = 0; idx < 6; idx++) {
+ GdkPoint node[3];
+
+ node[0].x = node[0].y = 0;
+ switch (idx) {
+ case 0:
+ node[1].x = 2 * gmap->x_point;
+ node[1].y = 0;
+ node[2].x = gmap->x_point;
+ node[2].y = -gmap->hex_radius - gmap->y_point;
+ break;
+ case 1:
+ node[1].x = gmap->x_point;
+ node[1].y = -gmap->hex_radius - gmap->y_point;
+ node[2].x = -gmap->x_point;
+ node[2].y = -gmap->hex_radius - gmap->y_point;
+ break;
+ case 2:
+ node[1].x = -gmap->x_point;
+ node[1].y = -gmap->hex_radius - gmap->y_point;
+ node[2].x = -2 * gmap->x_point;
+ node[2].y = 0;
+ break;
+ case 3:
+ node[1].x = -2 * gmap->x_point;
+ node[1].y = 0;
+ node[2].x = -gmap->x_point;
+ node[2].y = gmap->hex_radius + gmap->y_point;
+ break;
+ case 4:
+ node[1].x = -gmap->x_point;
+ node[1].y = gmap->hex_radius + gmap->y_point;
+ node[2].x = gmap->x_point;
+ node[2].y = gmap->hex_radius + gmap->y_point;
+ break;
+ case 5:
+ node[1].x = gmap->x_point;
+ node[1].y = gmap->hex_radius + gmap->y_point;
+ node[2].x = 2 * gmap->x_point;
+ node[2].y = 0;
+ break;
+ }
+ gmap->node_region[idx] = gdk_region_polygon(node, 3,
+ GDK_EVEN_ODD_RULE);
+ }
+}
+
+static void find_node(GuiMap * gmap, gint x, gint y, MapElement * element)
+{
+ gint y_hex;
+ gint x_hex;
+
+ build_node_regions(gmap);
+ for (x_hex = 0; x_hex < gmap->map->x_size; x_hex++)
+ for (y_hex = 0; y_hex < gmap->map->y_size; y_hex++) {
+ const Hex *hex;
+ const Node *node;
+
+ hex = gmap->map->grid[y_hex][x_hex];
+ if (hex != NULL) {
+ node = find_hex_node(gmap, hex, x, y);
+ if (node != NULL) {
+ element->node = node;
+ return;
+ }
+ }
+ }
+ element->pointer = NULL;
+}
+
+static Hex *find_hex_internal(GuiMap * gmap, gint x, gint y)
+{
+ gint y_hex;
+ gint x_hex;
+
+ for (x_hex = 0; x_hex < gmap->map->x_size; x_hex++)
+ for (y_hex = 0; y_hex < gmap->map->y_size; y_hex++) {
+ Hex *hex;
+ gint x_offset, y_offset;
+
+ hex = gmap->map->grid[y_hex][x_hex];
+ if (hex == NULL)
+ continue;
+
+ calc_hex_pos(gmap, x_hex, y_hex,
+ &x_offset, &y_offset);
+ x -= x_offset;
+ y -= y_offset;
+ if (gdk_region_point_in(gmap->hex_region, x, y))
+ return hex;
+ x += x_offset;
+ y += y_offset;
+ }
+ return NULL;
+}
+
+static void find_hex(GuiMap * gmap, gint x, gint y, MapElement * element)
+{
+ element->hex = find_hex_internal(gmap, x, y);
+}
+
+void guimap_draw_edge(GuiMap * gmap, const Edge * edge)
+{
+ GdkRectangle rect;
+ gint idx;
+ Polygon poly;
+ GdkPoint points[MAX_POINTS];
+
+ g_return_if_fail(edge != NULL);
+ g_return_if_fail(gmap->pixmap != NULL);
+
+ poly.num_points = G_N_ELEMENTS(points);
+ poly.points = points;
+ calc_edge_poly(gmap, edge, &largest_edge_poly, &poly);
+ poly_bound_rect(&poly, 1, &rect);
+ gdk_gc_set_fill(gmap->gc, GDK_TILED);
+ gdk_gc_set_tile(gmap->gc,
+ theme_get_current()->terrain_tiles[BOARD_TILE]);
+ gdk_draw_rectangle(gmap->pixmap, gmap->gc, TRUE,
+ rect.x, rect.y, rect.width, rect.height);
+
+ for (idx = 0; idx < G_N_ELEMENTS(edge->hexes); idx++)
+ if (edge->hexes[idx] != NULL)
+ display_hex(gmap->map, edge->hexes[idx], gmap);
+
+ gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
+}
+
+static void draw_cursor(GuiMap * gmap, gint owner, const Polygon * poly)
+{
+ GdkRectangle rect;
+
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+
+ gdk_gc_set_line_attributes(gmap->gc, 2, GDK_LINE_SOLID,
+ GDK_CAP_BUTT, GDK_JOIN_MITER);
+ gdk_gc_set_fill(gmap->gc, GDK_SOLID);
+ poly_draw_with_border(gmap->pixmap, gmap->gc,
+ colors_get_player(owner), &green, poly);
+
+ poly_bound_rect(poly, 1, &rect);
+ gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
+}
+
+static void erase_edge_cursor(GuiMap * gmap)
+{
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+ guimap_draw_edge(gmap, gmap->cursor.edge);
+}
+
+static void draw_road_cursor(GuiMap * gmap)
+{
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_road_polygon(gmap, gmap->cursor.edge, &poly);
+ draw_cursor(gmap, gmap->cursor_owner, &poly);
+}
+
+static void draw_ship_cursor(GuiMap * gmap)
+{
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_ship_polygon(gmap, gmap->cursor.edge, &poly);
+ draw_cursor(gmap, gmap->cursor_owner, &poly);
+}
+
+static void draw_bridge_cursor(GuiMap * gmap)
+{
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_bridge_polygon(gmap, gmap->cursor.edge, &poly);
+ draw_cursor(gmap, gmap->cursor_owner, &poly);
+}
+
+void guimap_draw_node(GuiMap * gmap, const Node * node)
+{
+ GdkRectangle rect;
+ int idx;
+ Polygon poly;
+ GdkPoint points[MAX_POINTS];
+
+ g_return_if_fail(node != NULL);
+ g_return_if_fail(gmap->pixmap != NULL);
+
+ poly.num_points = G_N_ELEMENTS(points);
+ poly.points = points;
+ calc_node_poly(gmap, node, &largest_node_poly, &poly);
+ poly_bound_rect(&poly, 1, &rect);
+ gdk_gc_set_fill(gmap->gc, GDK_TILED);
+ gdk_gc_set_tile(gmap->gc,
+ theme_get_current()->terrain_tiles[BOARD_TILE]);
+ gdk_draw_rectangle(gmap->pixmap, gmap->gc, TRUE,
+ rect.x, rect.y, rect.width, rect.height);
+ for (idx = 0; idx < G_N_ELEMENTS(node->hexes); idx++)
+ if (node->hexes[idx] != NULL)
+ display_hex(gmap->map, node->hexes[idx], gmap);
+
+ gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
+}
+
+static void erase_node_cursor(GuiMap * gmap)
+{
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+ guimap_draw_node(gmap, gmap->cursor.node);
+}
+
+static void draw_settlement_cursor(GuiMap * gmap)
+{
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_settlement_polygon(gmap, gmap->cursor.node, &poly);
+ draw_cursor(gmap, gmap->cursor_owner, &poly);
+}
+
+static void draw_city_cursor(GuiMap * gmap)
+{
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_city_polygon(gmap, gmap->cursor.node, &poly);
+ draw_cursor(gmap, gmap->cursor_owner, &poly);
+}
+
+static void draw_city_wall_cursor(GuiMap * gmap)
+{
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_city_wall_polygon(gmap, gmap->cursor.node, &poly);
+ draw_cursor(gmap, gmap->cursor_owner, &poly);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ guimap_city_polygon(gmap, gmap->cursor.node, &poly);
+ draw_cursor(gmap, gmap->cursor_owner, &poly);
+}
+
+static void draw_steal_building_cursor(GuiMap * gmap)
+{
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+ const Node *node;
+
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ node = gmap->cursor.node;
+ switch (node->type) {
+ case BUILD_SETTLEMENT:
+ guimap_settlement_polygon(gmap, node, &poly);
+ draw_cursor(gmap, node->owner, &poly);
+ break;
+ case BUILD_CITY:
+ guimap_city_polygon(gmap, node, &poly);
+ draw_cursor(gmap, node->owner, &poly);
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+}
+
+static void draw_steal_ship_cursor(GuiMap * gmap)
+{
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+ const Edge *edge;
+
+ g_return_if_fail(gmap->cursor.pointer != NULL);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ edge = gmap->cursor.edge;
+ switch (edge->type) {
+ case BUILD_SHIP:
+ guimap_ship_polygon(gmap, edge, &poly);
+ draw_cursor(gmap, edge->owner, &poly);
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+}
+
+static void erase_robber_cursor(GuiMap * gmap)
+{
+ const Hex *hex = gmap->cursor.hex;
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+ GdkRectangle rect;
+
+ if (hex == NULL)
+ return;
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ if (hex->terrain == SEA_TERRAIN)
+ guimap_pirate_polygon(gmap, hex, &poly);
+ else
+ guimap_robber_polygon(gmap, hex, &poly);
+ poly_bound_rect(&poly, 1, &rect);
+
+ display_hex(gmap->map, hex, gmap);
+
+ gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
+}
+
+static void draw_robber_cursor(GuiMap * gmap)
+{
+ const Hex *hex = gmap->cursor.hex;
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+ GdkRectangle rect;
+
+ if (hex == NULL)
+ return;
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ if (hex->terrain == SEA_TERRAIN)
+ guimap_pirate_polygon(gmap, hex, &poly);
+ else
+ guimap_robber_polygon(gmap, hex, &poly);
+ poly_bound_rect(&poly, 1, &rect);
+
+ gdk_gc_set_line_attributes(gmap->gc, 2, GDK_LINE_SOLID,
+ GDK_CAP_BUTT, GDK_JOIN_MITER);
+ gdk_gc_set_foreground(gmap->gc, &green);
+ poly_draw(gmap->pixmap, gmap->gc, FALSE, &poly);
+
+ gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
+}
+
+static gboolean highlight_chits(G_GNUC_UNUSED Map * map, const Hex * hex,
+ HighlightInfo * closure)
+{
+ GuiMap *gmap = closure->gmap;
+ GdkPoint points[6];
+ Polygon poly;
+ gint x_offset, y_offset;
+ GdkRectangle rect;
+
+ if (hex->roll != closure->old_highlight
+ && hex->roll != gmap->highlight_chit)
+ return FALSE;
+
+ display_hex(gmap->map, hex, gmap);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ get_hex_polygon(gmap, &poly, FALSE);
+ calc_hex_pos(gmap, hex->x, hex->y, &x_offset, &y_offset);
+ poly_offset(&poly, x_offset, y_offset);
+ poly_bound_rect(&poly, 1, &rect);
+
+ gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
+ return FALSE;
+}
+
+void guimap_highlight_chits(GuiMap * gmap, gint roll)
+{
+ HighlightInfo closure;
+
+ if (roll == gmap->highlight_chit)
+ return;
+ closure.gmap = gmap;
+ closure.old_highlight = gmap->highlight_chit;
+ gmap->highlight_chit = roll;
+ if (gmap->pixmap != NULL)
+ map_traverse(gmap->map, (HexFunc) highlight_chits,
+ &closure);
+}
+
+void guimap_draw_hex(GuiMap * gmap, const Hex * hex)
+{
+ GdkPoint points[MAX_POINTS];
+ Polygon poly;
+ GdkRectangle rect;
+ gint x_offset, y_offset;
+
+ if (hex == NULL)
+ return;
+
+ display_hex(gmap->map, hex, gmap);
+
+ poly.points = points;
+ poly.num_points = G_N_ELEMENTS(points);
+ get_hex_polygon(gmap, &poly, FALSE);
+ calc_hex_pos(gmap, hex->x, hex->y, &x_offset, &y_offset);
+ poly_offset(&poly, x_offset, y_offset);
+ poly_bound_rect(&poly, 1, &rect);
+
+ gdk_window_invalidate_rect(gmap->area->window, &rect, FALSE);
+}
+
+Hex *guimap_find_hex(GuiMap * gmap, gint x, gint y)
+{
+ return find_hex_internal(gmap, x, y);
+}
+
+typedef struct {
+ void (*find) (GuiMap * gmap, gint x, gint y, MapElement * element);
+ void (*erase_cursor) (GuiMap * gmap);
+ void (*draw_cursor) (GuiMap * gmap);
+} ModeCursor;
+
+/* This array must follow the enum CursorType */
+static ModeCursor cursors[] = {
+ {NULL, NULL, NULL}, /* NO_CURSOR */
+ {find_edge, erase_edge_cursor, draw_road_cursor}, /* ROAD_CURSOR */
+ {find_edge, erase_edge_cursor, draw_ship_cursor}, /* SHIP_CURSOR */
+ {find_edge, erase_edge_cursor, draw_bridge_cursor}, /* BRIDGE_CURSOR */
+ {find_node, erase_node_cursor, draw_settlement_cursor}, /* SETTLEMENT_CURSOR */
+ {find_node, erase_node_cursor, draw_city_cursor}, /* CITY_CURSOR */
+ {find_node, erase_node_cursor, draw_city_wall_cursor}, /* CITY_WALL_CURSOR */
+ {find_node, erase_node_cursor, draw_steal_building_cursor}, /* STEAL_BUILDING_CURSOR */
+ {find_edge, erase_edge_cursor, draw_steal_ship_cursor}, /* STEAL_SHIP_CURSOR */
+ {find_hex, erase_robber_cursor, draw_robber_cursor} /* ROBBER_CURSOR */
+};
+
+gboolean roadM, shipM, bridgeM, settlementM, cityM, cityWallM, shipMoveM;
+CheckFunc roadF, shipF, bridgeF, settlementF, cityF, cityWallF, shipMoveF;
+SelectFunc roadS, shipS, bridgeS, settlementS, cityS, cityWallS, shipMoveS;
+CancelFunc shipMoveC;
+
+/** Calculate the distance between the element and the cursor.
+ * @param gmap The GuiMap
+ * @param element An Edge or a Node
+ * @param isEdge TRUE if element is an Edge
+ * @param cursor_x X position of the cursor
+ * @param cursor_y Y position of the cursor
+ * @return The square of the distance
+ */
+static gint distance_cursor(const GuiMap * gmap,
+ const MapElement * element,
+ enum MapElementType type, gint cursor_x,
+ gint cursor_y)
+{
+ static GdkPoint single_point = { 0, 0 };
+ static const Polygon simple_poly = { &single_point, 1 };
+ GdkPoint translated_point;
+ Polygon poly;
+ poly.num_points = 1;
+ poly.points = &translated_point;
+ switch (type) {
+ case MAP_EDGE:
+ calc_edge_poly(gmap, element->edge, &simple_poly, &poly);
+ break;
+ case MAP_NODE:
+ calc_node_poly(gmap, element->node, &simple_poly, &poly);
+ break;
+ case MAP_HEX:
+ calc_hex_poly(gmap, element->hex, &simple_poly, &poly,
+ 120.0, 0);
+ break;
+ }
+ return sqr(cursor_x - poly.points[0].x) + sqr(cursor_y -
+ poly.points[0].y);
+}
+
+void guimap_cursor_move(GuiMap * gmap, gint x, gint y,
+ MapElement * element)
+{
+ ModeCursor *mode;
+
+ if (single_click_build_active) {
+ MapElement dummyElement;
+ gboolean can_build_road = FALSE;
+ gboolean can_build_ship = FALSE;
+ gboolean can_build_bridge = FALSE;
+ gboolean can_build_settlement = FALSE;
+ gboolean can_build_city = FALSE;
+ gboolean can_build_city_wall = FALSE;
+ gboolean can_move_ship = FALSE;
+ gboolean can_build_edge = FALSE;
+ gboolean can_build_node = FALSE;
+ gint distance_edge = 0;
+ gint distance_node = 0;
+
+ dummyElement.pointer = NULL;
+ find_edge(gmap, x, y, element);
+ if (element->pointer) {
+ can_build_road = (roadM
+ && roadF(*element,
+ gmap->player_num,
+ dummyElement));
+ can_build_ship = (shipM
+ && shipF(*element,
+ gmap->player_num,
+ dummyElement));
+ can_build_bridge = (bridgeM
+ && bridgeF(*element,
+ gmap->player_num,
+ dummyElement));
+ can_move_ship = (shipMoveM &&
+ shipMoveF(*element,
+ gmap->player_num,
+ dummyElement));
+
+ /* When both a road and a ship can be built,
+ * build a road when the cursor is over land,
+ * build a ship when the cursor is over sea
+ */
+ if (can_build_road && can_build_ship) {
+ MapElement hex1, hex2;
+ gint distance1, distance2;
+ hex1.hex = element->edge->hexes[0];
+ hex2.hex = element->edge->hexes[1];
+ distance1 =
+ distance_cursor(gmap, &hex1, MAP_HEX,
+ x, y);
+ distance2 =
+ distance_cursor(gmap, &hex2, MAP_HEX,
+ x, y);
+ if (distance1 == distance2)
+ can_build_ship = FALSE;
+ else {
+ if (distance2 < distance1)
+ hex1.hex = hex2.hex;
+ if (hex1.hex->terrain ==
+ SEA_TERRAIN)
+ can_build_road = FALSE;
+ else
+ can_build_ship = FALSE;
+ }
+ }
+
+ /* When both a ship and a bridge can be built,
+ * divide the edge in four segments.
+ * The two segments near the nodes are for the
+ * bridge (the pillars).
+ * The two segments in the middle are for the
+ * ship (open sea).
+ */
+ if (can_build_ship && can_build_bridge) {
+ MapElement node1, node2;
+ gint distanceNode, distanceEdge;
+ node1.node = element->edge->nodes[0];
+ node2.node = element->edge->nodes[1];
+ distanceNode =
+ MIN(distance_cursor
+ (gmap, &node1, MAP_NODE, x, y),
+ distance_cursor(gmap, &node2,
+ MAP_NODE, x, y));
+ distanceEdge =
+ distance_cursor(gmap, element,
+ MAP_EDGE, x, y);
+ if (distanceNode < distanceEdge)
+ can_build_ship = FALSE;
+ else
+ can_build_bridge = FALSE;
+ }
+
+ can_build_edge = can_build_road || can_build_ship
+ || can_build_bridge || can_move_ship;
+ if (can_build_edge)
+ distance_edge =
+ distance_cursor(gmap, element,
+ MAP_EDGE, x, y);
+ }
+
+ find_node(gmap, x, y, element);
+ if (element->pointer) {
+ can_build_settlement = (settlementM
+ && settlementF(*element,
+ gmap->
+ player_num,
+ dummyElement));
+ can_build_city = (cityM
+ && cityF(*element,
+ gmap->player_num,
+ dummyElement));
+ can_build_city_wall = (cityWallM
+ && cityWallF(*element,
+ gmap->
+ player_num,
+ dummyElement));
+ can_build_node = can_build_settlement
+ || can_build_city || can_build_city_wall;
+ if (can_build_node)
+ distance_node =
+ distance_cursor(gmap, element,
+ MAP_NODE, x, y);
+ }
+
+ /* When both edge and node can be built,
+ * build closest to the cursor.
+ * When equidistant, prefer the node.
+ */
+ if (can_build_edge && can_build_node) {
+ if (distance_node <= distance_edge)
+ can_build_edge = FALSE;
+ else
+ can_build_node = FALSE;
+ }
+
+ /* Prefer the most special road segment, if possible */
+ if (can_build_bridge && can_build_edge)
+ guimap_cursor_set(gmap, BRIDGE_CURSOR,
+ gmap->player_num, bridgeF,
+ bridgeS, NULL, NULL, TRUE);
+ else if (can_build_ship && can_build_edge)
+ guimap_cursor_set(gmap, SHIP_CURSOR,
+ gmap->player_num, shipF, shipS,
+ NULL, NULL, TRUE);
+ else if (can_build_road && can_build_edge)
+ guimap_cursor_set(gmap, ROAD_CURSOR,
+ gmap->player_num, roadF, roadS,
+ NULL, NULL, TRUE);
+ else if (can_build_settlement && can_build_node)
+ guimap_cursor_set(gmap, SETTLEMENT_CURSOR,
+ gmap->player_num, settlementF,
+ settlementS, NULL, NULL, TRUE);
+ else if (can_build_city && can_build_node)
+ guimap_cursor_set(gmap, CITY_CURSOR,
+ gmap->player_num, cityF, cityS,
+ NULL, NULL, TRUE);
+ else if (can_build_city_wall && can_build_node)
+ guimap_cursor_set(gmap, CITY_WALL_CURSOR,
+ gmap->player_num, cityWallF,
+ cityWallS, NULL, NULL, TRUE);
+ else if (can_move_ship && can_build_edge)
+ guimap_cursor_set(gmap, SHIP_CURSOR,
+ gmap->player_num, shipMoveF,
+ shipMoveS, NULL, NULL, TRUE);
+ else
+ guimap_cursor_set(gmap, NO_CURSOR,
+ gmap->player_num, NULL, NULL,
+ NULL, NULL, TRUE);
+ }
+
+ if (gmap->cursor_type == NO_CURSOR) {
+ element->pointer = NULL;
+ return;
+ }
+
+ mode = cursors + gmap->cursor_type;
+ mode->find(gmap, x, y, element);
+ if (element->pointer != gmap->cursor.pointer) {
+ if (gmap->cursor.pointer != NULL)
+ mode->erase_cursor(gmap);
+ if (gmap->check_func == NULL
+ || (element->pointer != NULL
+ && gmap->check_func(*element, gmap->cursor_owner,
+ gmap->user_data))) {
+ gmap->cursor = *element;
+ mode->draw_cursor(gmap);
+ } else {
+ gmap->cursor.pointer = NULL;
+ }
+ }
+}
+
+void guimap_cursor_select(GuiMap * gmap, gint x, gint y)
+{
+ MapElement cursor;
+ SelectFunc select;
+ MapElement user_data;
+ guimap_cursor_move(gmap, x, y, &cursor);
+
+ if (cursor.pointer == NULL)
+ return;
+
+ if (gmap->check_func != NULL
+ && !gmap->check_func(cursor, gmap->cursor_owner,
+ gmap->user_data)) {
+ if (gmap->check_cancel != NULL)
+ gmap->check_cancel();
+ return;
+ }
+
+ if (gmap->check_select != NULL) {
+ /* Before processing the select, clear the cursor */
+ select = gmap->check_select;
+ user_data.pointer = gmap->user_data.pointer;
+
+ if (gmap->cursor.pointer != NULL)
+ cursors[gmap->cursor_type].erase_cursor(gmap);
+ gmap->cursor_owner = -1;
+ gmap->check_func = NULL;
+ gmap->cursor_type = NO_CURSOR;
+ gmap->cursor.pointer = NULL;
+ gmap->user_data.pointer = NULL;
+ gmap->check_select = NULL;
+ select(cursor, user_data);
+ }
+}
+
+void guimap_cursor_set(GuiMap * gmap, CursorType cursor_type, gint owner,
+ CheckFunc check_func, SelectFunc check_select,
+ CancelFunc cancel_func,
+ const MapElement * user_data,
+ gboolean set_by_single_click)
+{
+ single_click_build_active = set_by_single_click;
+ if (cursor_type != NO_CURSOR)
+ g_assert(owner >= 0);
+ if (gmap->check_cancel != NULL)
+ gmap->check_cancel();
+ gmap->cursor_owner = owner;
+ gmap->check_func = check_func;
+ gmap->check_select = check_select;
+ gmap->check_cancel = cancel_func;
+ if (user_data != NULL) {
+ gmap->user_data.pointer = user_data->pointer;
+ } else {
+ gmap->user_data.pointer = NULL;
+ }
+ if (cursor_type == gmap->cursor_type)
+ return;
+
+ if (gmap->cursor.pointer != NULL) {
+ g_assert(gmap->cursor_type != NO_CURSOR);
+ cursors[gmap->cursor_type].erase_cursor(gmap);
+ }
+ gmap->cursor_type = cursor_type;
+ gmap->cursor.pointer = NULL;
+}
+
+void guimap_single_click_set_functions(CheckFunc road_check_func,
+ SelectFunc road_select_func,
+ CheckFunc ship_check_func,
+ SelectFunc ship_select_func,
+ CheckFunc bridge_check_func,
+ SelectFunc bridge_select_func,
+ CheckFunc
+ settlement_check_func,
+ SelectFunc
+ settlement_select_func,
+ CheckFunc city_check_func,
+ SelectFunc city_select_func,
+ CheckFunc city_wall_check_func,
+ SelectFunc city_wall_select_func,
+ CheckFunc
+ ship_move_check_func,
+ SelectFunc
+ ship_move_select_func,
+ CancelFunc ship_move_cancel_func)
+{
+ roadF = road_check_func;
+ roadS = road_select_func;
+ shipF = ship_check_func;
+ shipS = ship_select_func;
+ bridgeF = bridge_check_func;
+ bridgeS = bridge_select_func;
+ settlementF = settlement_check_func;
+ settlementS = settlement_select_func;
+ cityF = city_check_func;
+ cityS = city_select_func;
+ cityWallF = city_wall_check_func;
+ cityWallS = city_wall_select_func;
+ shipMoveF = ship_move_check_func;
+ shipMoveS = ship_move_select_func;
+ shipMoveC = ship_move_cancel_func;
+ single_click_build_active = TRUE;
+}
+
+void guimap_single_click_set_road_mask(gboolean mask)
+{
+ roadM = mask;
+}
+
+void guimap_single_click_set_ship_mask(gboolean mask)
+{
+ shipM = mask;
+}
+
+void guimap_single_click_set_bridge_mask(gboolean mask)
+{
+ bridgeM = mask;
+}
+
+void guimap_single_click_set_settlement_mask(gboolean mask)
+{
+ settlementM = mask;
+}
+
+void guimap_single_click_set_city_mask(gboolean mask)
+{
+ cityM = mask;
+}
+
+void guimap_single_click_set_city_wall_mask(gboolean mask)
+{
+ cityWallM = mask;
+}
+
+void guimap_single_click_set_ship_move_mask(gboolean mask)
+{
+ shipMoveM = mask;
+}
+
+void guimap_set_show_no_setup_nodes(GuiMap * gmap, gboolean show)
+{
+ gboolean old_show = gmap->show_nosetup_nodes;
+ gmap->show_nosetup_nodes = show;
+ if (old_show != show) {
+ /* Repaint and redraw the map */
+ guimap_display(gmap);
+ if (gmap->area)
+ gtk_widget_queue_draw(gmap->area);
+ }
+}
Added: trunk/common/gtk/guimap.h
===================================================================
--- trunk/common/gtk/guimap.h (rev 0)
+++ trunk/common/gtk/guimap.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,174 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004-2007 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __guimap_h
+#define __guimap_h
+
+#include "polygon.h"
+#include <gtk/gtk.h>
+
+#define MAX_POINTS 32 /* maximum points in a polygon */
+#define MIN_HEX_RADIUS 3 /* minimum hex_radius */
+
+typedef enum {
+ NO_CURSOR,
+ ROAD_CURSOR,
+ SHIP_CURSOR,
+ BRIDGE_CURSOR,
+ SETTLEMENT_CURSOR,
+ CITY_CURSOR,
+ CITY_WALL_CURSOR,
+ STEAL_BUILDING_CURSOR,
+ STEAL_SHIP_CURSOR,
+ ROBBER_CURSOR
+} CursorType;
+
+typedef union {
+ const Hex *hex;
+ const Node *node;
+ const Edge *edge;
+ gconstpointer pointer;
+} MapElement;
+
+typedef gboolean(*CheckFunc) (const MapElement element, gint owner,
+ const MapElement user_data);
+typedef void (*SelectFunc) (const MapElement obj,
+ const MapElement user_data);
+typedef void (*CancelFunc) (void);
+
+typedef struct _Mode Mode;
+typedef struct {
+ GtkWidget *area; /**< render map in this drawing area */
+ GdkPixmap *pixmap; /**< off screen pixmap for drawing */
+ GdkGC *gc; /**< gc for map drawing */
+ GdkRegion *hex_region; /**< region for filling hex */
+ GdkRegion *node_region[6]; /**< region for filling node */
+ GdkRegion *edge_region[6]; /**< regions for locating edges */
+ PangoLayout *layout; /**< layout object for rendering text */
+ gint initial_font_size; /**< initial font size */
+
+ Map *map; /**< map that is displayed */
+ gboolean show_nosetup_nodes; /**< show the nosetup nodes */
+
+ CursorType cursor_type; /**< current cursor type */
+ gint cursor_owner; /**< owner of the cursor */
+ CheckFunc check_func; /**< check object under cursor */
+ SelectFunc check_select; /**< when user selects cursor */
+ CancelFunc check_cancel; /**< when user clicks in illegal position */
+ MapElement user_data; /**< passed to callback functions */
+ MapElement cursor; /**< current GUI mode edge/node/hex cursor */
+
+ gint highlight_chit; /**< chit number to highlight */
+ gint chit_radius; /**< radius of the chit */
+
+ gint hex_radius; /**< size of hex on display */
+ gint x_point; /**< x offset of node 0 from centre */
+ gint y_point; /**< y offset of node 0 from centre */
+
+ gint x_margin; /**< margin to leave empty */
+ gint y_margin; /**< margin to leave empty */
+ gint width; /**< pixel width of map */
+ gint height; /**< pixel height of map */
+ gint player_num; /**< player displaying this map */
+} GuiMap;
+
+GuiMap *guimap_new(void);
+void guimap_delete(GuiMap * gmap);
+void guimap_reset(GuiMap * gmap);
+GtkWidget *guimap_build_drawingarea(GuiMap * gmap, gint width,
+ gint height);
+GdkPixmap *guimap_terrain(Terrain terrain);
+
+void guimap_road_polygon(const GuiMap * gmap, const Edge * edge,
+ Polygon * poly);
+void guimap_ship_polygon(const GuiMap * gmap, const Edge * edge,
+ Polygon * poly);
+void guimap_bridge_polygon(const GuiMap * gmap, const Edge * edge,
+ Polygon * poly);
+void guimap_city_polygon(const GuiMap * gmap, const Node * node,
+ Polygon * poly);
+void guimap_settlement_polygon(const GuiMap * gmap, const Node * node,
+ Polygon * poly);
+void guimap_city_wall_polygon(const GuiMap * gmap, const Node * node,
+ Polygon * poly);
+
+gint guimap_get_chit_radius(PangoLayout * layout, gboolean show_dots);
+void draw_dice_roll(PangoLayout * layout, GdkPixmap * pixmap, GdkGC * gc,
+ gint x_offset, gint y_offset, gint radius,
+ gint n, gint terrain, gboolean highlight);
+
+void guimap_scale_with_radius(GuiMap * gmap, gint radius);
+void guimap_scale_to_size(GuiMap * gmap, gint width, gint height);
+void guimap_display(GuiMap * gmap);
+
+void guimap_highlight_chits(GuiMap * gmap, gint roll);
+void guimap_draw_edge(GuiMap * gmap, const Edge * edge);
+void guimap_draw_node(GuiMap * gmap, const Node * node);
+void guimap_draw_hex(GuiMap * gmap, const Hex * hex);
+
+Hex *guimap_find_hex(GuiMap * gmap, gint x, gint y);
+
+void guimap_cursor_set(GuiMap * gmap, CursorType cursor_type, gint owner,
+ CheckFunc check_func, SelectFunc select_func,
+ CancelFunc cancel_func,
+ const MapElement * user_data,
+ gboolean set_by_single_click);
+
+/* Single click building.
+ * Single click building is aborted by explicitly setting the cursor
+ * CheckFunc: check function for a certain resource type
+ * SelectFunc: function to call when the resource is selected
+ */
+void guimap_single_click_set_functions(CheckFunc road_check_func,
+ SelectFunc road_select_func,
+ CheckFunc ship_check_func,
+ SelectFunc ship_select_func,
+ CheckFunc bridge_check_func,
+ SelectFunc bridge_select_func,
+ CheckFunc
+ settlement_check_func,
+ SelectFunc
+ settlement_select_func,
+ CheckFunc city_check_func,
+ SelectFunc city_select_func,
+ CheckFunc city_wall_check_func,
+ SelectFunc city_wall_select_func,
+ CheckFunc
+ ship_move_check_func,
+ SelectFunc
+ ship_move_select_func,
+ CancelFunc ship_move_cancel_func);
+
+/* guimap_single_click_set_*_mask:
+ * mask to determine whether the CheckFunc or SelectFunc can be used
+ */
+void guimap_single_click_set_road_mask(gboolean mask);
+void guimap_single_click_set_ship_mask(gboolean mask);
+void guimap_single_click_set_bridge_mask(gboolean mask);
+void guimap_single_click_set_settlement_mask(gboolean mask);
+void guimap_single_click_set_city_mask(gboolean mask);
+void guimap_single_click_set_city_wall_mask(gboolean mask);
+void guimap_single_click_set_ship_move_mask(gboolean mask);
+
+void guimap_cursor_select(GuiMap * gmap, gint x, gint y);
+void guimap_set_show_no_setup_nodes(GuiMap * gmap, gboolean show);
+#endif
Added: trunk/common/gtk/player-icon.c
===================================================================
--- trunk/common/gtk/player-icon.c (rev 0)
+++ trunk/common/gtk/player-icon.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,372 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2007 Giancarlo Capella <giancarlo at comm.cc>
+ * Copyright (C) 2007 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "colors.h"
+#include "player-icon.h"
+#include <gtk/gtk.h>
+#include <string.h>
+#include <stdlib.h>
+
+static gboolean load_pixbuf(const gchar * name, GdkPixbuf ** pixbuf);
+static void replace_colors(GdkPixbuf * pixbuf,
+ const GdkColor * replace_this,
+ const GdkColor * replace_with);
+
+GdkColor default_face_color = { 0, 0xd500, 0x7f00, 0x2000 };
+GdkColor default_variant_color = { 0, 0, 0, 0 };
+
+typedef struct PlayerAvatar {
+ GdkPixbuf *base;
+ GSList *variation;
+} PlayerAvatar;
+
+PlayerAvatar player_avatar;
+GdkPixbuf *ai_avatar;
+
+static gboolean load_pixbuf(const gchar * name, GdkPixbuf ** pixbuf)
+{
+ gchar *filename;
+
+ /* determine full path to pixmap file */
+ filename =
+ g_build_filename(DATADIR, "pixmaps", "pioneers", name, NULL);
+ if (g_file_test(filename, G_FILE_TEST_EXISTS)) {
+ GError *error = NULL;
+ *pixbuf = gdk_pixbuf_new_from_file(filename, &error);
+ if (error != NULL) {
+ g_warning("Error loading pixmap %s\n", filename);
+ g_error_free(error);
+ return FALSE;
+ }
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+void playericon_init(void)
+{
+ GdkColormap *cmap;
+ gint idx;
+ gboolean good;
+
+ cmap = gdk_colormap_get_system();
+ gdk_colormap_alloc_color(cmap, &default_face_color, FALSE, TRUE);
+ gdk_colormap_alloc_color(cmap, &default_variant_color, FALSE,
+ TRUE);
+
+ load_pixbuf("style-human.png", &player_avatar.base);
+ player_avatar.variation = NULL;
+ idx = 1;
+ do {
+ gchar *name;
+ GdkPixbuf *pixbuf;
+
+ name = g_strdup_printf("style-human-%d.png", idx);
+ good = load_pixbuf(name, &pixbuf);
+ if (good) {
+ player_avatar.variation =
+ g_slist_append(player_avatar.variation,
+ pixbuf);
+ }
+ ++idx;
+ g_free(name);
+ } while (good);
+
+ load_pixbuf("style-ai.png", &ai_avatar);
+}
+
+static void replace_colors(GdkPixbuf * pixbuf,
+ const GdkColor * replace_this,
+ const GdkColor * replace_with)
+{
+ gint i;
+ guint new_color;
+ guint old_color;
+ guint *pixel;
+
+ g_assert(gdk_pixbuf_get_colorspace(pixbuf) == GDK_COLORSPACE_RGB);
+ g_assert(gdk_pixbuf_get_bits_per_sample(pixbuf) == 8);
+ g_assert(gdk_pixbuf_get_has_alpha(pixbuf));
+ g_assert(gdk_pixbuf_get_n_channels(pixbuf) == 4);
+
+ pixel = (guint *) gdk_pixbuf_get_pixels(pixbuf);
+ new_color = 0xff000000 |
+ ((replace_with->red >> 8) & 0xff) |
+ ((replace_with->green >> 8) & 0xff) << 8 |
+ ((replace_with->blue >> 8) & 0xff) << 16;
+ old_color = 0xff000000 |
+ ((replace_this->red >> 8) & 0xff) |
+ ((replace_this->green >> 8) & 0xff) << 8 |
+ ((replace_this->blue >> 8) & 0xff) << 16;
+ for (i = 0;
+ i <
+ (gdk_pixbuf_get_rowstride(pixbuf) / 4 *
+ gdk_pixbuf_get_height(pixbuf)); i++) {
+ if (*pixel == old_color)
+ *pixel = new_color;
+ pixel++;
+ }
+}
+
+GdkPixbuf *playericon_create_icon(GtkWidget * widget, const gchar * style,
+ GdkColor * color, gboolean viewer,
+ gboolean connected, gboolean double_size)
+{
+ gint width, height;
+ GdkPixbuf *basic_image, *overlay_image, *scaled_image;
+ gchar **style_parts;
+ gboolean basic_substitute;
+
+ /* Determine the style for the player/viewer */
+ style_parts = g_strsplit(style, " ", 0);
+
+ gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &width, &height);
+ if (double_size) {
+ width *= 2;
+ height *= 2;
+ }
+ basic_image = NULL;
+ overlay_image = NULL;
+ if (!strcmp(style_parts[0], "ai")) {
+ /* This is an AI */
+ basic_image = gdk_pixbuf_copy(ai_avatar);
+ basic_substitute = TRUE;
+ /** @todo RC 2007-07-17 For now, the AI does not have different appearances */
+ } else if (!strcmp(style_parts[0], "human")) {
+ /* Draw a bust */
+ gint variant;
+ GdkColor face_color, variant_color;
+
+ playericon_parse_human_style(style, &face_color, &variant,
+ &variant_color);
+ basic_image = gdk_pixbuf_copy(player_avatar.base);
+ basic_substitute = TRUE;
+
+ /* Substitute the pure red face with the face color */
+ replace_colors(basic_image, &red, &face_color);
+
+ /* Substitute the pure blue base with the variant color */
+ overlay_image =
+ gdk_pixbuf_copy(g_slist_nth
+ (player_avatar.variation,
+ variant)->data);
+ replace_colors(overlay_image, &blue, &variant_color);
+ } else {
+ /* Unknown or square */
+ GdkGC *gc;
+ GdkPixmap *pixmap;
+
+ pixmap =
+ gdk_pixmap_new(widget->window, width, height,
+ gdk_visual_get_system()->depth);
+ gc = gdk_gc_new(pixmap);
+ if (viewer) {
+ GdkPixbuf *tmp;
+ /* Viewers have a transparent icon */
+ gdk_gc_set_foreground(gc, &black);
+ gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, width,
+ height);
+
+ tmp =
+ gdk_pixbuf_get_from_drawable(NULL, pixmap,
+ NULL, 0, 0, 0, 0,
+ -1, -1);
+ basic_image =
+ gdk_pixbuf_add_alpha(tmp, TRUE, 0, 0, 0);
+ } else {
+ gdk_gc_set_foreground(gc, &black);
+ gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, width,
+ height);
+
+ gdk_gc_set_foreground(gc, color);
+ gdk_draw_rectangle(pixmap, gc, TRUE, 1, 1,
+ width - 2, height - 2);
+
+ if (!connected) {
+ gdk_gc_set_foreground(gc, &black);
+ gdk_draw_rectangle(pixmap, gc, FALSE,
+ 3, 3, width - 7,
+ height - 7);
+ gdk_draw_rectangle(pixmap, gc, FALSE, 6, 6,
+ width - 13,
+ height - 13);
+ /* Don't draw the other emblem */
+ connected = TRUE;
+ }
+
+ basic_image =
+ gdk_pixbuf_get_from_drawable(NULL, pixmap,
+ NULL, 0, 0, 0, 0,
+ -1, -1);
+ }
+ basic_substitute = FALSE;
+ g_object_unref(gc);
+ g_object_unref(pixmap);
+ }
+ g_strfreev(style_parts);
+
+ if (basic_image && basic_substitute) {
+ /* Substitute the pure blue base with the player color */
+ replace_colors(basic_image, &blue, color);
+ }
+
+ if (overlay_image) {
+ gdk_pixbuf_composite(overlay_image, basic_image, 0, 0,
+ gdk_pixbuf_get_width(basic_image),
+ gdk_pixbuf_get_height(basic_image),
+ 0.0, 0.0, 1.0, 1.0,
+ GDK_INTERP_NEAREST, 255);
+ g_object_unref(overlay_image);
+ }
+
+ scaled_image =
+ gdk_pixbuf_scale_simple(basic_image, width, height,
+ GDK_INTERP_BILINEAR);
+ g_object_unref(basic_image);
+
+ if (!connected) {
+ GdkGC *gc;
+ GdkPixmap *pixmap;
+ GdkPixbuf *tmp1, *tmp2;
+
+ pixmap =
+ gdk_pixmap_new(widget->window, width, height,
+ gdk_visual_get_system()->depth);
+ gc = gdk_gc_new(pixmap);
+
+ gdk_gc_set_foreground(gc, &black); /* Black will become transparent */
+ gdk_draw_rectangle(pixmap, gc, TRUE, 0, 0, width, height);
+
+ gdk_gc_set_foreground(gc, &red);
+ gdk_draw_arc(pixmap, gc, TRUE, width / 2, 0, width / 2,
+ height / 2, 0, 360 * 64);
+ gdk_gc_set_foreground(gc, &white);
+ gdk_draw_rectangle(pixmap, gc, TRUE,
+ width / 2 + 2, height / 4 - 1,
+ width / 2 - 4, height / 8);
+
+ tmp1 =
+ gdk_pixbuf_get_from_drawable(NULL, pixmap, NULL, 0, 0,
+ 0, 0, -1, -1);
+ tmp2 = gdk_pixbuf_add_alpha(tmp1, TRUE, 0, 0, 0);
+ gdk_pixbuf_composite(tmp2, scaled_image, 0, 0, width,
+ height, 0.0, 0.0, 1.0, 1.0,
+ GDK_INTERP_NEAREST, 255);
+ g_object_unref(tmp2);
+ g_object_unref(tmp1);
+ g_object_unref(gc);
+ g_object_unref(pixmap);
+ }
+ return scaled_image;
+}
+
+gchar *playericon_create_human_style(const GdkColor * face_color,
+ gint variant,
+ const GdkColor * variant_color)
+{
+ gchar *c1;
+ gchar *c2;
+ gchar *style;
+
+ c1 = color_to_string(*face_color);
+ c2 = color_to_string(*variant_color);
+
+ style = g_strdup_printf("human %s %d %s", c1, variant, c2);
+
+ g_free(c1);
+ g_free(c2);
+ return style;
+}
+
+gboolean playericon_parse_human_style(const gchar * style,
+ GdkColor * face_color,
+ gint * variant,
+ GdkColor * variant_color)
+{
+ gchar **style_parts;
+ gboolean parse_ok;
+
+ /* Determine the style for the player/viewer */
+ style_parts = g_strsplit(style, " ", 0);
+ parse_ok = FALSE;
+ if (!strcmp(style_parts[0], "human")) {
+ parse_ok = style_parts[1] != NULL
+ && string_to_color(style_parts[1], face_color);
+ if (parse_ok) {
+ parse_ok = style_parts[2] != NULL;
+ }
+ if (parse_ok) {
+ *variant = atoi(style_parts[2]);
+ parse_ok =
+ *variant <=
+ g_slist_length(player_avatar.variation);
+ }
+ if (parse_ok) {
+ parse_ok = style_parts[3] != NULL
+ && string_to_color(style_parts[3],
+ variant_color);
+ }
+ }
+
+ if (!parse_ok) {
+ /* Something was wrong, revert to the default */
+ *face_color = default_face_color;
+ *variant = 0;
+ *variant_color = default_variant_color;
+ }
+ g_strfreev(style_parts);
+ return parse_ok;
+}
+
+
+gboolean string_to_color(const gchar * spec, GdkColor * color)
+{
+ PangoColor pango_color;
+ GdkColormap *cmap;
+
+ if (pango_color_parse(&pango_color, spec)) {
+ color->red = pango_color.red;
+ color->green = pango_color.green;
+ color->blue = pango_color.blue;
+
+ cmap = gdk_colormap_get_system();
+ gdk_colormap_alloc_color(cmap, color, FALSE, TRUE);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gchar *color_to_string(GdkColor color)
+{
+ return g_strdup_printf("#%04x%04x%04x", color.red, color.green,
+ color.blue);
+/** @todo RC Enable this code when the minimum Gtk+ version is high enough
+ PangoColor pango_color;
+
+ pango_color.red = color.red;
+ pango_color.green = color.green;
+ pango_color.blue = color.blue;
+
+ return pango_color_to_string(&pango_color);
+*/
+}
Added: trunk/common/gtk/player-icon.h
===================================================================
--- trunk/common/gtk/player-icon.h (rev 0)
+++ trunk/common/gtk/player-icon.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,82 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2007 Giancarlo Capella <giancarlo at comm.cc>
+ * Copyright (C) 2007 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __playericon_h
+#define __playericon_h
+
+#include <gtk/gtk.h>
+
+/** Initialize the player icons */
+void playericon_init(void);
+
+/** Create an icon for a player.
+ * The default size is suitable for a list view item.
+ * @param widget The widget that will display the icon
+ * @param style The style of the icon
+ * @param color The base color of the player
+ * @param viewer TRUE if a viewer icon is requested
+ * @param connected Is the player currently connected
+ * @param double_size Generate a double size pixmap
+ * @return THe icon for the player. Call g_object_unref() when not needed anymore.
+ */
+GdkPixbuf *playericon_create_icon(GtkWidget * widget, const gchar * style,
+ GdkColor * color, gboolean viewer,
+ gboolean connected,
+ gboolean double_size);
+
+/** Create a style string for the player.
+ * @param face_color The color of the face
+ * @param variant The variant
+ * @param variant_color The color of the variant
+ * @return The style string. Call g_free() when not needed anymore.
+ */
+gchar *playericon_create_human_style(const GdkColor * face_color,
+ gint variant,
+ const GdkColor * variant_color);
+
+/** Parse the style string in its components.
+ * @param style The style
+ * @retval face_color The color of the face
+ * @retval variant The variant
+ * @retval variant_color The color of the variant
+ * @return TRUE if the style could be parsed. When FALSE, the return values contain the default values
+ */
+gboolean playericon_parse_human_style(const gchar * style,
+ GdkColor * face_color,
+ gint * variant,
+ GdkColor * variant_color);
+
+/** Convert a string to a color.
+ * The color is allocated in the system colormap.
+ * @param spec The name of the color
+ * @retval color The color
+ * @return TRUE if the conversion succeeded.
+ */
+gboolean string_to_color(const gchar * spec, GdkColor * color);
+
+/** Convert a color to a string.
+ * After use, the string must be freed with g_free()
+ * @param color The color
+ * @return the string
+ */
+gchar *color_to_string(GdkColor color);
+
+#endif
Added: trunk/common/gtk/polygon.c
===================================================================
--- trunk/common/gtk/polygon.c (rev 0)
+++ trunk/common/gtk/polygon.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,83 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <math.h>
+#include <ctype.h>
+#include <gdk/gdk.h>
+
+#include "polygon.h"
+
+void poly_offset(Polygon * poly, gint x_offset, gint y_offset)
+{
+ int idx;
+ GdkPoint *points;
+
+ for (idx = 0, points = poly->points; idx < poly->num_points;
+ idx++, points++) {
+ points->x += x_offset;
+ points->y += y_offset;
+ }
+}
+
+void poly_bound_rect(const Polygon * poly, int pad, GdkRectangle * rect)
+{
+ int idx;
+ GdkPoint tl;
+ GdkPoint br;
+ GdkPoint *points;
+
+ points = poly->points;
+ tl = points[0];
+ br = points[0];
+ for (idx = 1, points++; idx < poly->num_points; idx++, points++) {
+ if (points->x < tl.x)
+ tl.x = points->x;
+ else if (points->x > br.x)
+ br.x = points->x;
+ if (points->y < tl.y)
+ tl.y = points->y;
+ else if (points->y > br.y)
+ br.y = points->y;
+ }
+ rect->x = tl.x - pad;
+ rect->y = tl.y - pad;
+ rect->width = br.x - tl.x + pad + 1;
+ rect->height = br.y - tl.y + pad + 1;
+}
+
+void poly_draw(GdkDrawable * drawable, GdkGC * gc, gint filled,
+ const Polygon * poly)
+{
+ gdk_draw_polygon(drawable, gc, filled, poly->points,
+ poly->num_points);
+}
+
+void poly_draw_with_border(GdkDrawable * drawable, GdkGC * gc,
+ const GdkColor * color,
+ const GdkColor * border_color,
+ const Polygon * poly)
+{
+ gdk_gc_set_foreground(gc, color);
+ poly_draw(drawable, gc, TRUE, poly);
+
+ gdk_gc_set_foreground(gc, border_color);
+ poly_draw(drawable, gc, FALSE, poly);
+}
Added: trunk/common/gtk/polygon.h
===================================================================
--- trunk/common/gtk/polygon.h (rev 0)
+++ trunk/common/gtk/polygon.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,40 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __polygon_h
+#define __polygon_h
+
+#include <gdk/gdk.h>
+
+typedef struct {
+ GdkPoint *points;
+ gint num_points;
+} Polygon;
+
+void poly_offset(Polygon * poly, gint x_offset, gint y_offset);
+void poly_bound_rect(const Polygon * poly, int pad, GdkRectangle * rect);
+void poly_draw(GdkDrawable * drawable, GdkGC * gc, gint filled,
+ const Polygon * poly);
+void poly_draw_with_border(GdkDrawable * drawable, GdkGC * gc,
+ const GdkColor * color,
+ const GdkColor * border_color,
+ const Polygon * poly);
+
+#endif
Added: trunk/common/gtk/select-game.c
===================================================================
--- trunk/common/gtk/select-game.c (rev 0)
+++ trunk/common/gtk/select-game.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,205 @@
+/* A custom widget for selecting a game from a list of games.
+ *
+ * The code is based on the TICTACTOE example
+ * www.gtk.oorg/tutorial/app-codeexamples.html#SEC-TICTACTOE
+ *
+ * Adaptation for Pioneers: 2004 Roland Clobus
+ *
+ */
+
+#include "config.h"
+#include "game.h"
+#include <gtk/gtksignal.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtkcombobox.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtklabel.h>
+#include <string.h>
+#include "guimap.h"
+
+#include "select-game.h"
+
+/* The signals */
+enum {
+ ACTIVATE,
+ LAST_SIGNAL
+};
+
+static void select_game_class_init(SelectGameClass * klass);
+static void select_game_init(SelectGame * sg);
+static void select_game_item_changed(GtkWidget * widget, SelectGame * sg);
+
+/* All signals */
+static guint select_game_signals[LAST_SIGNAL] = { 0 };
+
+/* Register the class */
+GType select_game_get_type(void)
+{
+ static GType sg_type = 0;
+
+ if (!sg_type) {
+ static const GTypeInfo sg_info = {
+ sizeof(SelectGameClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) select_game_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(SelectGame),
+ 0,
+ (GInstanceInitFunc) select_game_init,
+ NULL
+ };
+ sg_type =
+ g_type_register_static(GTK_TYPE_TABLE, "SelectGame",
+ &sg_info, 0);
+ }
+ return sg_type;
+}
+
+/* Register the signals.
+ * SelectGame will emit one signal: 'activate' with the text of the
+ * active game in user_data
+ */
+static void select_game_class_init(SelectGameClass * klass)
+{
+ select_game_signals[ACTIVATE] = g_signal_new("activate",
+ G_TYPE_FROM_CLASS
+ (klass),
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET
+ (SelectGameClass,
+ activate), NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+/* Build the composite widget */
+static void select_game_init(SelectGame * sg)
+{
+ GtkCellRenderer *cell;
+ GtkTooltips *tooltips;
+
+ tooltips = gtk_tooltips_new();
+
+ /* Create model */
+ sg->data = gtk_list_store_new(2, G_TYPE_STRING, GDK_TYPE_PIXBUF);
+ sg->combo_box =
+ gtk_combo_box_new_with_model(GTK_TREE_MODEL(sg->data));
+
+ cell = gtk_cell_renderer_text_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(sg->combo_box),
+ cell, TRUE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(sg->combo_box),
+ cell, "text", 0, NULL);
+
+ cell = gtk_cell_renderer_pixbuf_new();
+ gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(sg->combo_box),
+ cell, FALSE);
+ gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(sg->combo_box),
+ cell, "pixbuf", 1, NULL);
+
+ sg->game_names = g_ptr_array_new();
+
+ gtk_widget_show(sg->combo_box);
+ gtk_tooltips_set_tip(tooltips, sg->combo_box,
+ /* Tooltip for the list of games */
+ _("Select a game"), NULL);
+ gtk_table_resize(GTK_TABLE(sg), 1, 1);
+ gtk_table_attach_defaults(GTK_TABLE(sg), sg->combo_box,
+ 0, 1, 0, 1);
+ sg->default_game = g_strdup("Default");
+ g_signal_connect(G_OBJECT(sg->combo_box), "changed",
+ G_CALLBACK(select_game_item_changed), sg);
+}
+
+/* Create a new instance of the widget */
+GtkWidget *select_game_new(void)
+{
+ return GTK_WIDGET(g_object_new(select_game_get_type(), NULL));
+}
+
+/* Set the default game */
+void select_game_set_default(SelectGame * sg, const gchar * game_title)
+{
+ if (sg->default_game)
+ g_free(sg->default_game);
+ sg->default_game = g_strdup(game_title);
+}
+
+/* Add a game title to the list.
+ * The default game will be the active item.
+ */
+void select_game_add(SelectGame * sg, const gchar * game_title)
+{
+ GtkTreeIter iter;
+ gchar *title = g_strdup(game_title);
+
+ g_ptr_array_add(sg->game_names, title);
+ gtk_list_store_insert_with_values(sg->data, &iter, 999,
+ 0, game_title, -1);
+
+ if (!strcmp(game_title, sg->default_game))
+ gtk_combo_box_set_active(GTK_COMBO_BOX(sg->combo_box),
+ sg->game_names->len - 1);
+}
+
+/* Add a game title to the list, and add the map.
+ * The default game will be the active item.
+ */
+void select_game_add_with_map(SelectGame * sg, const gchar * game_title,
+ Map * map)
+{
+ GtkTreeIter iter;
+ gchar *title = g_strdup(game_title);
+
+ int width, height;
+ GdkPixbuf *pixbuf;
+
+ GuiMap *gmap;
+
+ width = 64;
+ height = 48;
+
+ gmap = guimap_new();
+ gmap->pixmap =
+ gdk_pixmap_new(sg->combo_box->window, width, height,
+ gdk_visual_get_system()->depth);
+ gmap->width = width;
+ gmap->height = height;
+ gmap->area = sg->combo_box;
+ g_object_ref(gmap->area);
+ gmap->map = map;
+ guimap_scale_to_size(gmap, width, height);
+ guimap_display(gmap);
+
+ pixbuf =
+ gdk_pixbuf_get_from_drawable(NULL, gmap->pixmap, NULL, 0, 0, 0,
+ 0, -1, -1);
+ guimap_delete(gmap);
+
+ g_ptr_array_add(sg->game_names, title);
+ gtk_list_store_insert_with_values(sg->data, &iter, 999,
+ 0, game_title, 1, pixbuf, -1);
+ g_object_unref(pixbuf);
+
+ if (!strcmp(game_title, sg->default_game))
+ gtk_combo_box_set_active(GTK_COMBO_BOX(sg->combo_box),
+ sg->game_names->len - 1);
+}
+
+static void select_game_item_changed(G_GNUC_UNUSED GtkWidget * widget,
+ SelectGame * sg)
+{
+ g_signal_emit(G_OBJECT(sg), select_game_signals[ACTIVATE], 0);
+}
+
+const gchar *select_game_get_active(SelectGame * sg)
+{
+ gint idx = gtk_combo_box_get_active(GTK_COMBO_BOX(sg->combo_box));
+ return g_ptr_array_index(sg->game_names, idx);
+}
Added: trunk/common/gtk/select-game.h
===================================================================
--- trunk/common/gtk/select-game.h (rev 0)
+++ trunk/common/gtk/select-game.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,51 @@
+/* A custom widget for selecting a game from a list of games.
+ *
+ * The code is based on the TICTACTOE example
+ * www.gtk.oorg/tutorial/app-codeexamples.html#SEC-TICTACTOE
+ *
+ * Adaptation for Pioneers: 2004 Roland Clobus
+ *
+ */
+#ifndef __SELECTGAME_H__
+#define __SELECTGAME_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtktable.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+#define SELECTGAME_TYPE (select_game_get_type ())
+#define SELECTGAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SELECTGAME_TYPE, SelectGame))
+#define SELECTGAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SELECTGAME_TYPE, SelectGameClass))
+#define IS_SELECTGAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SELECTGAME_TYPE))
+#define IS_SELECTGAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SELECTGAME_TYPE))
+typedef struct _SelectGame SelectGame;
+typedef struct _SelectGameClass SelectGameClass;
+
+struct _SelectGame {
+ GtkTable table;
+
+ GtkWidget *combo_box;
+ GtkListStore *data;
+ GPtrArray *game_names;
+ gchar *default_game;
+};
+
+struct _SelectGameClass {
+ GtkTableClass parent_class;
+
+ void (*activate) (SelectGame * sg);
+};
+
+GType select_game_get_type(void);
+GtkWidget *select_game_new(void);
+void select_game_set_default(SelectGame * sg, const gchar * game_title);
+void select_game_add(SelectGame * sg, const gchar * game_title);
+void select_game_add_with_map(SelectGame * sg, const gchar * game_title,
+ Map * map);
+const gchar *select_game_get_active(SelectGame * sg);
+
+G_END_DECLS
+#endif /* __SELECTGAME_H__ */
Added: trunk/common/gtk/theme.c
===================================================================
--- trunk/common/gtk/theme.c (rev 0)
+++ trunk/common/gtk/theme.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,732 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2005 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "game.h"
+#include "theme.h"
+#include "config-gnome.h"
+
+/*
+
+ Description of theme.cfg:
+ -------------------------
+
+ A theme.cfg file is a series of definitions, one per line. Lines starting
+ with '#' are comments. A definition looks like
+
+ VARIABLE = VALUE
+
+ There are three types of variables: pixmaps, colors, and the scaling mode.
+ The value for a pixmap is a filename, relative to the theme directory. A
+ color can be either 'none' or 'transparent' (both equivalent), or '#rrggbb'.
+ (It's also allowed to use 1, 3, or 4 digits per color component.)
+
+ Pixmaps can be defined for hex backgrounds (hill-tile, field-tile,
+ mountain-tile, pasture-tile, forest-tile, desert-tile, sea-tile, board-tile)
+ and port backgrounds (brick-port-tile, grain-port-tile, ore-port-tile,
+ wool-port-tile, and lumber-port-tile). If a hex tile is not defined, the
+ pixmap from the default theme will be used. If a port tile is not given, the
+ corresponding 2:1 ports will be painted in solid background color.
+
+ chip-bg-color, chip-fg-color, and chip-bd-color are the colors for the dice
+ roll chips in the middle of a hex. port-{bg,fg,bd}-color are the same for
+ ports. chip-hi-bg-color is used as background for chips that correspond to
+ the current roll, chip-hi-fg-color is chips showing 6 or 8. You can also
+ define robber-{fg,bg}-color for the robber and hex-bd-color for the border
+ of hexes (around the background image). If any color is not defined, the
+ default color will be used. If a color is 'none' the corresponding element
+ won't be painted at all.
+
+ The five chip colors can also be different for each terrain type. To
+ override the general colors, add color definitions after the name of the
+ pixmap, e.g.:
+
+ field-tile = field_grain.png none #d0d0d0 none #303030 #ffffff
+
+ The order is bg, fg, bd, hi-bg, hi-fg. Sorry, you can't skip definitions at
+ the beginning...
+
+ Normally, all pixmaps are used in their native size and repeat over their
+ area as needed (tiling). This doesn't look good for photo-like images, so
+ you can add "scaling = always" in that case. Then images will always be
+ scaled to the current size of a hex. (BTW, the height should be 1/cos(pi/6)
+ (~ 1.1547) times the width of the image.) Two other available modes are
+ 'only-downscale' and 'only-upscale' to make images only smaller or larger,
+ resp. (in case it's needed sometimes...)
+
+*/
+
+#define TCOL_INIT(r,g,b) { TRUE, FALSE, FALSE, { 0, r, g, b } }
+#define TCOL_TRANSP() { TRUE, TRUE, FALSE, { 0, 0, 0, 0 } }
+#define TCOL_UNSET() { FALSE, FALSE, FALSE, { 0, 0, 0, 0 } }
+#define TSCALE { NULL, NULL, 0, 0.0 }
+
+static gchar default_name[] = "Classic";
+
+static MapTheme default_theme = {
+ default_name,
+ NEVER,
+ /* terrain tile names */
+ {"hill.png", "field.png", "mountain.png", "pasture.png",
+ "forest.png",
+ "desert.png", "sea.png", "gold.png", "board.png"},
+ /* port tile names */
+ {"hill.png", "field.png", "mountain.png", "pasture.png",
+ "forest.png",
+ NULL},
+ /* terrain tile pixmaps */
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* port tile pixmaps */
+ {NULL, NULL, NULL, NULL, NULL, NULL},
+ /* port tile width */
+ {0, 0, 0, 0, 0, 0},
+ /* port tile height */
+ {0, 0, 0, 0, 0, 0},
+ /* terrain tile scale data */
+ {TSCALE, TSCALE, TSCALE, TSCALE, TSCALE, TSCALE, TSCALE, TSCALE,
+ TSCALE},
+ /* colours */
+ {
+ TCOL_INIT(0xff00, 0xda00, 0xb900),
+ TCOL_INIT(0, 0, 0),
+ TCOL_INIT(0, 0, 0),
+ TCOL_INIT(0, 0xff00, 0),
+ TCOL_INIT(0xff00, 0, 0),
+ TCOL_INIT(0, 0, 0xff00),
+ TCOL_INIT(0xff00, 0xff00, 0xff00),
+ TCOL_INIT(0, 0, 0),
+ TCOL_INIT(0, 0, 0),
+ TCOL_INIT(0xff00, 0xff00, 0xff00),
+ TCOL_INIT(0xff00, 0xda00, 0xb900),
+ },
+ /* colours per tile */
+ {
+ {TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET()}, /* Hill */
+ {TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET()}, /* Field */
+ {TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET()}, /* Mountain */
+ {TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET()}, /* Pasture */
+ {TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET()}, /* Forest */
+ {TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET()}, /* unused: desert */
+ {TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET()}, /* unused: sea */
+ {TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET(), TCOL_UNSET()} /* Gold */
+ }
+};
+
+static GList *theme_list = NULL;
+static MapTheme *current_theme = NULL;
+static GList *callback_list = NULL;
+
+static gboolean theme_initialize(MapTheme * t, const gchar * subdir);
+static struct tvars *getvar(char **p, const gchar * filename, int lno);
+static char *getval(char **p, const gchar * filename, int lno);
+static gboolean parsecolor(char *p, TColor * tc, const gchar * filename,
+ int lno);
+static MapTheme *theme_config_parse(const gchar * themename,
+ const gchar * filename);
+static gboolean theme_load_pixmap(const gchar * file,
+ const gchar * themename,
+ GdkPixbuf ** pixbuf,
+ GdkPixmap ** pixmap_return,
+ GdkBitmap ** mask_return);
+
+/** Find a theme with the given name */
+static gint theme_list_locate(gconstpointer item, gconstpointer data)
+{
+ const MapTheme *theme = item;
+ const gchar *name = data;
+ return strcmp(theme->name, name);
+}
+
+/** Insert the theme alphabetically in the list */
+static gint theme_insert_sorted(gconstpointer new, gconstpointer first)
+{
+ const MapTheme *newTheme = new;
+ const MapTheme *firstTheme = first;
+ return strcmp(newTheme->name, firstTheme->name);
+}
+
+void themes_init(void)
+{
+ GDir *dir;
+ const gchar *dirname;
+ gchar *fname;
+ gchar *path;
+ MapTheme *t;
+ gint novar;
+ gchar *user_theme;
+
+ /* initialize default theme */
+ if (!theme_initialize(&default_theme, "")) {
+ g_error("Could not initialize default theme.");
+ }
+ g_assert(theme_list == NULL);
+ theme_list = g_list_append(NULL, &default_theme);
+
+ /* scan image dir for theme descriptor files */
+ if (!(dir = g_dir_open(THEMEDIR, 0, NULL)))
+ return;
+ while ((dirname = g_dir_read_name(dir))) {
+ fname = g_build_filename(THEMEDIR, dirname, NULL);
+ if (g_file_test(fname, G_FILE_TEST_IS_DIR)) {
+ path = g_build_filename(fname, "theme.cfg", NULL);
+ if ((t = theme_config_parse(dirname, path))) {
+ if (theme_initialize(t, dirname)) {
+ theme_list =
+ g_list_insert_sorted
+ (theme_list, t,
+ theme_insert_sorted);
+ } else {
+ g_warning
+ ("Theme %s not loaded due to errors.",
+ t->name);
+ }
+ } else {
+ g_warning
+ ("Theme %s not loaded due to errors.",
+ dirname);
+ }
+ g_free(path);
+ }
+ g_free(fname);
+ }
+ g_dir_close(dir);
+
+ t = NULL;
+ user_theme = config_get_string("settings/theme=Tiny", &novar);
+ if (!(!user_theme || !*user_theme)) {
+ GList *result = g_list_find_custom(theme_list, user_theme,
+ theme_list_locate);
+ if (result)
+ t = result->data;
+ }
+ g_free(user_theme);
+ if (!t) {
+ t = &default_theme;
+ }
+ current_theme = t;
+}
+
+void theme_set_current(MapTheme * t)
+{
+ GList *list = callback_list;
+ current_theme = t;
+ while (list) {
+ G_CALLBACK(list->data) ();
+ list = g_list_next(list);
+ }
+}
+
+MapTheme *theme_get_current(void)
+{
+ return current_theme;
+}
+
+GList *theme_get_list(void)
+{
+ return theme_list;
+}
+
+/** Load a pixbuf, its pixmap and its mask.
+ * If loading fails, no objects need to be freed.
+ * @return TRUE if succesful
+ */
+gboolean theme_load_pixmap(const gchar * file, const gchar * themename,
+ GdkPixbuf ** pixbuf,
+ GdkPixmap ** pixmap_return,
+ GdkBitmap ** mask_return)
+{
+ g_return_val_if_fail(themename != NULL, FALSE);
+ g_return_val_if_fail(pixbuf != NULL, FALSE);
+ g_return_val_if_fail(file != NULL, FALSE);
+ g_return_val_if_fail(pixmap_return != NULL, FALSE);
+
+ *pixbuf = NULL;
+ *pixmap_return = NULL;
+
+ /* check that file exists */
+ if (!g_file_test(file, G_FILE_TEST_EXISTS)) {
+ g_warning
+ ("Could not find \'%s\' pixmap file in theme \'%s\'.",
+ file, themename);
+ return FALSE;
+ }
+
+ /* load pixmap/mask */
+ *pixbuf = gdk_pixbuf_new_from_file(file, NULL);
+ *pixmap_return = NULL;
+ if (*pixbuf != NULL) {
+ gdk_pixbuf_render_pixmap_and_mask(*pixbuf,
+ pixmap_return,
+ mask_return, 1);
+ }
+
+ /* check result */
+ if (*pixmap_return == NULL) {
+ if (*pixbuf)
+ g_object_unref(*pixbuf);
+ g_warning
+ ("Could not load \'%s\' pixmap file in theme \'%s\'.",
+ file, themename);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/** Initialize the theme.
+ * Revert to pixmaps from the default theme if loading fails
+ * @return TRUE if succesful
+ */
+static gboolean theme_initialize(MapTheme * t, const gchar * subdir)
+{
+ int i, j;
+ GdkColormap *cmap;
+
+ /* load terrain tiles */
+ for (i = 0; i < G_N_ELEMENTS(t->terrain_tiles); ++i) {
+ GdkPixbuf *pixbuf, *pixbuf_copy;
+ gchar *file;
+ /* if a theme doesn't define a terrain tile, use the default
+ * one */
+ if (t->terrain_tile_names[i])
+ file = g_build_filename(THEMEDIR, subdir,
+ t->terrain_tile_names[i],
+ NULL);
+ else
+ file = g_build_filename(THEMEDIR,
+ default_theme.
+ terrain_tile_names[i],
+ NULL);
+ if (!theme_load_pixmap
+ (file, t->name, &pixbuf, &(t->terrain_tiles[i]),
+ NULL)) {
+ /* Fall back to default theme images */
+ g_free(file);
+ file = g_build_filename(THEMEDIR,
+ default_theme.
+ terrain_tile_names[i],
+ NULL);
+ if (!theme_load_pixmap
+ (file, t->name, &pixbuf,
+ &(t->terrain_tiles[i]), NULL)) {
+ g_error
+ ("Could not find default pixmap file: %s",
+ file);
+ g_free(file);
+ exit(1);
+ }
+ };
+ g_free(file);
+ pixbuf_copy = gdk_pixbuf_copy(pixbuf);
+ if (pixbuf_copy == NULL) {
+ return FALSE;
+ }
+ t->scaledata[i].image = pixbuf;
+ t->scaledata[i].native_image = pixbuf_copy;
+ t->scaledata[i].native_width =
+ gdk_pixbuf_get_width(pixbuf);
+ t->scaledata[i].aspect =
+ (float) gdk_pixbuf_get_width(pixbuf) /
+ gdk_pixbuf_get_height(pixbuf);
+ gdk_pixbuf_render_pixmap_and_mask(pixbuf,
+ &(t->terrain_tiles[i]),
+ NULL, 1);
+ }
+
+ /* load port tiles */
+ for (i = 0; i < G_N_ELEMENTS(t->port_tiles); ++i) {
+ /* if a theme doesn't define a port tile, it will be drawn with
+ * its resource letter instead */
+ if (t->port_tile_names[i]) {
+ GdkPixbuf *pixbuf;
+ gchar *fname = g_build_filename(THEMEDIR, subdir,
+ t->
+ port_tile_names[i],
+ NULL);
+ if (theme_load_pixmap
+ (fname, t->name, &pixbuf, &(t->port_tiles[i]),
+ NULL)) {
+ gdk_drawable_get_size(t->port_tiles[i],
+ &t->
+ port_tiles_width[i],
+ &t->
+ port_tiles_height
+ [i]);
+ g_object_unref(pixbuf);
+ } else {
+ /* Fall back on the default port tile */
+ g_free(fname);
+ fname = g_build_filename(THEMEDIR,
+ default_theme.
+ port_tile_names
+ [i], NULL);
+ if (theme_load_pixmap
+ (fname, t->name, &pixbuf,
+ &(t->port_tiles[i]), NULL)) {
+ gdk_drawable_get_size(t->
+ port_tiles
+ [i],
+ &t->
+ port_tiles_width
+ [i],
+ &t->
+ port_tiles_height
+ [i]);
+ g_object_unref(pixbuf);
+ }
+ }
+ g_free(fname);
+ } else
+ t->port_tiles[i] = NULL;
+ }
+
+ /* allocate defined colors */
+ cmap = gdk_colormap_get_system();
+
+ for (i = 0; i < G_N_ELEMENTS(t->colors); ++i) {
+ TColor *tc = &(t->colors[i]);
+ if (!tc->set)
+ *tc = default_theme.colors[i];
+ else if (!tc->transparent && !tc->allocated) {
+ gdk_colormap_alloc_color(cmap, &(tc->color), FALSE,
+ TRUE);
+ tc->allocated = TRUE;
+ }
+ }
+
+ for (i = 0; i < TC_MAX_OVRTILE; ++i) {
+ for (j = 0; j < TC_MAX_OVERRIDE; ++j) {
+ TColor *tc = &(t->ovr_colors[i][j]);
+ if (tc->set && !tc->transparent && !tc->allocated) {
+ gdk_colormap_alloc_color(cmap,
+ &(tc->color),
+ FALSE, TRUE);
+ tc->allocated = TRUE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+void theme_rescale(int new_width)
+{
+ int i;
+
+ switch (current_theme->scaling) {
+ case NEVER:
+ return;
+
+ case ONLY_DOWNSCALE:
+ if (new_width > current_theme->scaledata[0].native_width)
+ new_width =
+ current_theme->scaledata[0].native_width;
+ break;
+
+ case ONLY_UPSCALE:
+ if (new_width < current_theme->scaledata[0].native_width)
+ new_width =
+ current_theme->scaledata[0].native_width;
+ break;
+
+ case ALWAYS:
+ break;
+ }
+
+ /* if the size is 0, gdk_pixbuf_scale_simple fails */
+ if (new_width <= 0)
+ new_width = 1;
+
+ for (i = 0; i < G_N_ELEMENTS(current_theme->terrain_tiles); ++i) {
+ int new_height;
+ if (i == BOARD_TILE)
+ continue; /* Don't scale the board-tile */
+ new_height =
+ new_width / current_theme->scaledata[i].aspect;
+ /* gdk_pixbuf_scale_simple cannot handle 0 height */
+ if (new_height <= 0)
+ new_height = 1;
+ /* rescale the pixbuf */
+ gdk_pixbuf_unref(current_theme->scaledata[i].image);
+ current_theme->scaledata[i].image =
+ gdk_pixbuf_scale_simple(current_theme->scaledata[i].
+ native_image, new_width,
+ new_height,
+ GDK_INTERP_BILINEAR);
+
+ /* render a new pixmap */
+ g_object_unref(current_theme->terrain_tiles[i]);
+ gdk_pixbuf_render_pixmap_and_mask(current_theme->
+ scaledata[i].image,
+ &(current_theme->
+ terrain_tiles[i]),
+ NULL, 1);
+ }
+}
+
+#define offs(elem) ((size_t)(&(((MapTheme *)0)->elem)))
+#define telem(type,theme,tv) (*((type *)((char *)theme + tv->offset)))
+
+typedef enum { STR, COL, SCMODE } vartype;
+
+static struct tvars {
+ const char *name;
+ vartype type;
+ int override;
+ size_t offset;
+} theme_vars[] = {
+ {
+ "name", STR, -1, offs(name)}, {
+ "hill-tile", STR, HILL_TILE, offs(terrain_tile_names[HILL_TILE])},
+ {
+ "field-tile", STR, FIELD_TILE,
+ offs(terrain_tile_names[FIELD_TILE])}, {
+ "mountain-tile", STR, MOUNTAIN_TILE,
+ offs(terrain_tile_names[MOUNTAIN_TILE])}, {
+ "pasture-tile", STR, PASTURE_TILE,
+ offs(terrain_tile_names[PASTURE_TILE])}, {
+ "forest-tile", STR, FOREST_TILE,
+ offs(terrain_tile_names[FOREST_TILE])}, {
+ "desert-tile", STR, -1, offs(terrain_tile_names[DESERT_TILE])},
+ {
+ "sea-tile", STR, -1, offs(terrain_tile_names[SEA_TILE])}, {
+ "gold-tile", STR, GOLD_TILE, offs(terrain_tile_names[GOLD_TILE])},
+ {
+ "board-tile", STR, -1, offs(terrain_tile_names[BOARD_TILE])}, {
+ "brick-port-tile", STR, -1, offs(port_tile_names[HILL_PORT_TILE])},
+ {
+ "grain-port-tile", STR, -1,
+ offs(port_tile_names[FIELD_PORT_TILE])}, {
+ "ore-port-tile", STR, -1,
+ offs(port_tile_names[MOUNTAIN_PORT_TILE])}, {
+ "wool-port-tile", STR, -1,
+ offs(port_tile_names[PASTURE_PORT_TILE])}, {
+ "lumber-port-tile", STR, -1,
+ offs(port_tile_names[FOREST_PORT_TILE])}, {
+ "nores-port-tile", STR, -1, offs(port_tile_names[ANY_PORT_TILE])},
+ {
+ "chip-bg-color", COL, -1, offs(colors[TC_CHIP_BG])}, {
+ "chip-fg-color", COL, -1, offs(colors[TC_CHIP_FG])}, {
+ "chip-bd-color", COL, -1, offs(colors[TC_CHIP_BD])}, {
+ "chip-hi-bg-color", COL, -1, offs(colors[TC_CHIP_H_BG])}, {
+ "chip-hi-fg-color", COL, -1, offs(colors[TC_CHIP_H_FG])}, {
+ "port-bg-color", COL, -1, offs(colors[TC_PORT_BG])}, {
+ "port-fg-color", COL, -1, offs(colors[TC_PORT_FG])}, {
+ "port-bd-color", COL, -1, offs(colors[TC_PORT_BD])}, {
+ "robber-fg-color", COL, -1, offs(colors[TC_ROBBER_FG])}, {
+ "robber-bd-color", COL, -1, offs(colors[TC_ROBBER_BD])}, {
+ "hex-bd-color", COL, -1, offs(colors[TC_HEX_BD])}, {
+ "scaling", SCMODE, -1, offs(scaling)}, {
+ NULL, 0, -1, 0}
+};
+
+#define ERR1(formatstring, argument) \
+ g_warning("While reading %s at line %d:", filename, lno); \
+ g_warning(formatstring, argument);
+#define ERR0(string) \
+ ERR1("%s", string);
+
+static struct tvars *getvar(char **p, const gchar * filename, int lno)
+{
+ char *q, qsave;
+ struct tvars *tv;
+
+ *p += strspn(*p, " \t");
+ if (!**p || **p == '\n')
+ return NULL; /* empty line */
+
+ q = *p + strcspn(*p, " \t=\n");
+ if (q == *p) {
+ ERR1("variable name missing: %s", *p);
+ return NULL;
+ }
+ qsave = *q;
+ *q++ = '\0';
+
+ for (tv = theme_vars; tv->name; ++tv) {
+ if (strcmp(*p, tv->name) == 0)
+ break;
+ }
+ if (!tv->name) {
+ ERR1("unknown config variable '%s'", *p);
+ return NULL;
+ }
+
+ *p = q;
+ if (qsave != '=') {
+ *p += strspn(*p, " \t");
+ if (**p != '=') {
+ ERR1("'=' missing: %s", *p);
+ return NULL;
+ }
+ ++*p;
+ }
+ *p += strspn(*p, " \t");
+
+ return tv;
+}
+
+static char *getval(char **p, const gchar * filename, int lno)
+{
+ char *q;
+
+ q = *p;
+ *p += strcspn(*p, " \t\n");
+ if (q == *p) {
+ ERR0("missing value");
+ return FALSE;
+ }
+ if (**p) {
+ *(*p)++ = '\0';
+ *p += strspn(*p, " \t");
+ }
+ return q;
+}
+
+static gboolean checkend(const char *p)
+{
+ p += strspn(p, " \t");
+ return !*p || *p == '\n';
+}
+
+static gboolean parsecolor(char *p, TColor * tc, const gchar * filename,
+ int lno)
+{
+ if (strcmp(p, "none") == 0 || strcmp(p, "transparent") == 0) {
+ tc->set = TRUE;
+ tc->transparent = TRUE;
+ return TRUE;
+ }
+ tc->transparent = FALSE;
+ if (!gdk_color_parse(p, &tc->color)) {
+ ERR1("invalid color: %s", p);
+ return FALSE;
+ }
+
+ tc->set = TRUE;
+ return TRUE;
+}
+
+static MapTheme *theme_config_parse(const gchar * themename,
+ const gchar * filename)
+{
+ FILE *f;
+ gchar *line = NULL;
+ char *p, *q;
+ int lno;
+ MapTheme *t;
+ struct tvars *tv;
+ gboolean ok = TRUE;
+
+ if (!(f = fopen(filename, "r")))
+ return NULL;
+
+ t = g_malloc0(sizeof(MapTheme));
+ /* Initially the theme name is equal to the directory name */
+ t->name = g_filename_to_utf8(themename, -1, NULL, NULL, NULL);
+
+ lno = 0;
+ while (read_line_from_file(&line, f)) {
+ ++lno;
+ if (line[0] == '#') {
+ g_free(line);
+ continue;
+ }
+ p = line;
+ if (!(tv = getvar(&p, filename, lno)) ||
+ !(q = getval(&p, filename, lno))) {
+ ok = FALSE;
+ g_free(line);
+ continue;
+ }
+
+ switch (tv->type) {
+ case STR:
+ telem(char *, t, tv) = g_strdup(q);
+ if (tv->override >= 0 && !checkend(p)) {
+ int terrain = tv->override;
+ int i;
+
+ for (i = 0; i < TC_MAX_OVERRIDE; ++i) {
+ if (checkend(p))
+ break;
+ if (!
+ (q =
+ getval(&p, filename, lno))) {
+ ok = FALSE;
+ break;
+ }
+ if (!parsecolor
+ (q,
+ &(t->ovr_colors[terrain][i]),
+ filename, lno)) {
+ ok = FALSE;
+ break;
+ }
+ }
+ }
+ break;
+ case COL:
+ if (!parsecolor
+ (q, &telem(TColor, t, tv), filename, lno)) {
+ ok = FALSE;
+ g_free(line);
+ continue;
+ }
+ break;
+ case SCMODE:
+ if (strcmp(q, "never") == 0)
+ t->scaling = NEVER;
+ else if (strcmp(q, "always") == 0)
+ t->scaling = ALWAYS;
+ else if (strcmp(q, "only-downscale") == 0)
+ t->scaling = ONLY_DOWNSCALE;
+ else if (strcmp(q, "only-upscale") == 0)
+ t->scaling = ONLY_UPSCALE;
+ else {
+ ERR1(_("bad scaling mode '%s'"), q);
+ ok = FALSE;
+ }
+ break;
+ }
+ if (!checkend(p)) {
+ ERR1("unexpected rest at end of line: '%s'", p);
+ ok = FALSE;
+ }
+ g_free(line);
+ }
+ fclose(f);
+
+ if (ok)
+ return t;
+ g_free(t->name);
+ g_free(t);
+ return NULL;
+}
+
+void theme_register_callback(GCallback callback)
+{
+ callback_list = g_list_append(callback_list, callback);
+}
Added: trunk/common/gtk/theme.h
===================================================================
--- trunk/common/gtk/theme.h (rev 0)
+++ trunk/common/gtk/theme.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,111 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __theme_h
+#define __theme_h
+
+#include <gtk/gtk.h>
+
+typedef struct {
+ gboolean set;
+ gboolean transparent;
+ gboolean allocated;
+ GdkColor color;
+} TColor;
+
+typedef struct {
+ GdkPixbuf *image;
+ GdkPixbuf *native_image;
+ gint native_width;
+ float aspect;
+} TScaleData;
+
+typedef enum {
+ TC_CHIP_BG = 0,
+ TC_CHIP_FG,
+ TC_CHIP_BD,
+ TC_CHIP_H_BG,
+ TC_CHIP_H_FG,
+ TC_PORT_BG,
+ TC_PORT_FG,
+ TC_PORT_BD,
+ TC_ROBBER_FG,
+ TC_ROBBER_BD,
+ TC_HEX_BD,
+ TC_MAX
+} THEME_COLOR;
+#define TC_MAX_OVERRIDE (TC_CHIP_H_FG+1)
+
+/* The order of the TERRAIN_TILES enum is EXTREMELY important! The order
+ * must match the resources indicated in enum Terrain.
+ */
+typedef enum {
+ HILL_TILE = 0,
+ FIELD_TILE,
+ MOUNTAIN_TILE,
+ PASTURE_TILE,
+ FOREST_TILE,
+ DESERT_TILE,
+ SEA_TILE,
+ GOLD_TILE,
+ BOARD_TILE,
+ TERRAIN_TILE_MAX
+} TERRAIN_TILES;
+#define TC_MAX_OVRTILE (GOLD_TILE+1)
+
+typedef enum {
+ HILL_PORT_TILE = 0,
+ FIELD_PORT_TILE,
+ MOUNTAIN_PORT_TILE,
+ PASTURE_PORT_TILE,
+ FOREST_PORT_TILE,
+ ANY_PORT_TILE,
+ PORT_TILE_MAX
+} PORT_TILES;
+
+typedef enum {
+ NEVER,
+ ALWAYS,
+ ONLY_DOWNSCALE,
+ ONLY_UPSCALE
+} SCALEMODE;
+
+typedef struct _MapTheme {
+ gchar *name;
+ SCALEMODE scaling;
+ const gchar *terrain_tile_names[TERRAIN_TILE_MAX];
+ const gchar *port_tile_names[PORT_TILE_MAX];
+ GdkPixmap *terrain_tiles[TERRAIN_TILE_MAX];
+ GdkPixmap *port_tiles[PORT_TILE_MAX];
+ gint port_tiles_width[PORT_TILE_MAX];
+ gint port_tiles_height[PORT_TILE_MAX];
+ TScaleData scaledata[TERRAIN_TILE_MAX];
+ TColor colors[TC_MAX];
+ TColor ovr_colors[TC_MAX_OVRTILE][TC_MAX_OVERRIDE];
+} MapTheme;
+
+void theme_rescale(int radius);
+void theme_set_current(MapTheme * t);
+MapTheme *theme_get_current(void);
+GList *theme_get_list(void);
+void themes_init(void);
+void theme_register_callback(GCallback callback);
+#endif
Added: trunk/common/log.c
===================================================================
--- trunk/common/log.c (rev 0)
+++ trunk/common/log.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,224 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+
+#include "log.h"
+#include "driver.h"
+
+/* The default function to use to write messages, when nothing else has been
+ * specified.
+ */
+#define LOG_FUNC_DEFAULT log_message_string_console
+
+void log_set_func(LogFunc func)
+{
+ if (func != NULL)
+ driver->log_write = func;
+ else
+ driver->log_write = LOG_FUNC_DEFAULT;
+}
+
+void log_set_func_default(void)
+{
+ driver->log_write = LOG_FUNC_DEFAULT;
+}
+
+void log_message_string_console(gint msg_type, const gchar * text)
+{
+ const gchar *prefix = NULL;
+
+ switch (msg_type) {
+ case MSG_ERROR:
+ prefix = _("*ERROR* ");
+ break;
+ case MSG_INFO:
+ prefix = "- ";
+ break;
+ case MSG_CHAT:
+ prefix = _("Chat: ");
+ break;
+ case MSG_RESOURCE:
+ prefix = _("Resource: ");
+ break;
+ case MSG_BUILD:
+ prefix = _("Build: ");
+ break;
+ case MSG_DICE:
+ prefix = _("Dice: ");
+ break;
+ case MSG_STEAL:
+ prefix = _("Steal: ");
+ break;
+ case MSG_TRADE:
+ prefix = _("Trade: ");
+ break;
+ case MSG_DEVCARD:
+ prefix = _("Development: ");
+ break;
+ case MSG_LARGESTARMY:
+ prefix = _("Army: ");
+ break;
+ case MSG_LONGESTROAD:
+ prefix = _("Road: ");
+ break;
+ case MSG_BEEP:
+ prefix = _("*BEEP* ");
+ break;
+ case MSG_TIMESTAMP:
+ break; /* No prefix */
+ case MSG_PLAYER1:
+ prefix = _("Player 1: ");
+ break;
+ case MSG_PLAYER2:
+ prefix = _("Player 2: ");
+ break;
+ case MSG_PLAYER3:
+ prefix = _("Player 3: ");
+ break;
+ case MSG_PLAYER4:
+ prefix = _("Player 4: ");
+ break;
+ case MSG_PLAYER5:
+ prefix = _("Player 5: ");
+ break;
+ case MSG_PLAYER6:
+ prefix = _("Player 6: ");
+ break;
+ case MSG_PLAYER7:
+ prefix = _("Player 7: ");
+ break;
+ case MSG_PLAYER8:
+ prefix = _("Player 8: ");
+ break;
+ case MSG_VIEWER_CHAT:
+ prefix = _("Viewer: ");
+ break;
+ default:
+ prefix = _("** UNKNOWN MESSAGE TYPE ** ");
+ }
+
+ if (prefix)
+ fprintf(stderr, "%s%s", prefix, text);
+ else
+ fprintf(stderr, "%s", text);
+}
+
+static const char *debug_type(int type)
+{
+ switch (type) {
+ case MSG_ERROR:
+ return "ERROR";
+ case MSG_INFO:
+ return "INFO";
+ case MSG_CHAT:
+ return "CHAT";
+ case MSG_RESOURCE:
+ return "RESOURCE";
+ case MSG_BUILD:
+ return "BUILD";
+ case MSG_DICE:
+ return "DICE";
+ case MSG_STEAL:
+ return "STEAL";
+ case MSG_TRADE:
+ return "TRADE";
+ case MSG_DEVCARD:
+ return "DEVCARD";
+ case MSG_LARGESTARMY:
+ return "LARGESTARMY";
+ case MSG_LONGESTROAD:
+ return "LONGESTROAD";
+ case MSG_BEEP:
+ return "BEEP";
+ case MSG_PLAYER1:
+ return "PLAYER1";
+ case MSG_PLAYER2:
+ return "PLAYER2";
+ case MSG_PLAYER3:
+ return "PLAYER3";
+ case MSG_PLAYER4:
+ return "PLAYER4";
+ case MSG_PLAYER5:
+ return "PLAYER5";
+ case MSG_PLAYER6:
+ return "PLAYER6";
+ case MSG_PLAYER7:
+ return "PLAYER7";
+ case MSG_PLAYER8:
+ return "PLAYER8";
+ case MSG_VIEWER_CHAT:
+ return "VIEWER_CHAT";
+ default:
+ return "*UNKNOWN MESSAGE TYPE*";
+ }
+}
+
+void log_message_chat(const gchar * player_name,
+ const gchar * joining_text, gint msg_type,
+ const gchar * chat)
+{
+ if (driver->log_write && driver->log_write != LOG_FUNC_DEFAULT) {
+ log_message(MSG_INFO, "%s%s", player_name, joining_text);
+ debug("[%s] %s", debug_type(msg_type), chat);
+
+ /* No timestamp here: */
+ driver->log_write(msg_type, chat);
+ driver->log_write(msg_type, "\n");
+ } else {
+ log_message(msg_type, "%s%s%s\n", player_name,
+ joining_text, chat);
+ }
+}
+
+void log_message(gint msg_type, const gchar * fmt, ...)
+{
+ gchar *text;
+ gchar *timestamp;
+ va_list ap;
+ time_t t;
+ struct tm *alpha;
+
+ va_start(ap, fmt);
+ text = g_strdup_vprintf(fmt, ap);
+ va_end(ap);
+
+ debug("[%s] %s", debug_type(msg_type), text);
+
+ t = time(NULL);
+ alpha = localtime(&t);
+
+ timestamp = g_strdup_printf("%02d:%02d:%02d ", alpha->tm_hour,
+ alpha->tm_min, alpha->tm_sec);
+
+ if (driver->log_write) {
+ driver->log_write(MSG_TIMESTAMP, timestamp);
+ driver->log_write(msg_type, text);
+ } else {
+ LOG_FUNC_DEFAULT(MSG_TIMESTAMP, timestamp);
+ LOG_FUNC_DEFAULT(msg_type, text);
+ }
+ g_free(text);
+ g_free(timestamp);
+}
Added: trunk/common/log.h
===================================================================
--- trunk/common/log.h (rev 0)
+++ trunk/common/log.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,79 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __log_h
+#define __log_h
+
+#include <glib.h>
+#include <glib/gi18n.h>
+
+/** Type of logging functions */
+typedef void (*LogFunc) (gint msg_type, const gchar * text);
+
+/* Message Types */
+#define MSG_ERROR 1
+#define MSG_INFO 2
+#define MSG_CHAT 3
+#define MSG_RESOURCE 4
+#define MSG_BUILD 5
+#define MSG_DICE 6
+#define MSG_STEAL 7
+#define MSG_TRADE 8
+#define MSG_DEVCARD 9
+#define MSG_LARGESTARMY 10
+#define MSG_LONGESTROAD 11
+#define MSG_BEEP 12
+#define MSG_TIMESTAMP 13
+#define MSG_PLAYER1 101
+#define MSG_PLAYER2 102
+#define MSG_PLAYER3 103
+#define MSG_PLAYER4 104
+#define MSG_PLAYER5 105
+#define MSG_PLAYER6 106
+#define MSG_PLAYER7 107
+#define MSG_PLAYER8 108
+#define MSG_VIEWER_CHAT 199
+
+/** Set the logging function to 'func'. */
+void log_set_func(LogFunc func);
+
+/** Set the logging function to the system default (stderr) */
+void log_set_func_default(void);
+
+/** Write a message string to the console, adding a prefix depending on
+ * its type.
+ */
+void log_message_string_console(gint msg_type, const gchar * text);
+
+/** Log a message after turning the params into a single string. */
+void log_message(gint msg_type, const gchar * fmt, ...);
+
+/** Log a chat message.
+ * When the log function is not the default, only the chat is shown
+ * with msg_type, the other parts are shown with MSG_INFO.
+ * This means that player_name and joining_text are shown black,
+ * and the chat is in the colour of the player.
+ */
+void log_message_chat(const gchar * player_name,
+ const gchar * joining_text, gint msg_type,
+ const gchar * chat);
+#endif /* __log_h */
Added: trunk/common/map.c
===================================================================
--- trunk/common/map.c (rev 0)
+++ trunk/common/map.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,950 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <ctype.h>
+#include <string.h>
+#include <glib.h>
+
+#include "game.h"
+#include "map.h"
+
+GRand *g_rand_ctx = NULL;
+
+Hex *map_hex(Map * map, gint x, gint y)
+{
+ if (x < 0 || x >= map->x_size || y < 0 || y >= map->y_size)
+ return NULL;
+
+ return map->grid[y][x];
+}
+
+Hex *hex_in_direction(Map * map, const Hex * hex, HexDirection direction)
+{
+ gint x = hex->x;
+ gint y = hex->y;
+
+ switch (direction) {
+ case HEX_DIR_E:
+ x++;
+ break;
+ case HEX_DIR_NE:
+ if (y % 2 == 1)
+ x++;
+ y--;
+ break;
+ case HEX_DIR_NW:
+ if (y % 2 == 0)
+ x--;
+ y--;
+ break;
+ case HEX_DIR_W:
+ x--;
+ break;
+ case HEX_DIR_SW:
+ if (y % 2 == 0)
+ x--;
+ y++;
+ break;
+ case HEX_DIR_SE:
+ if (y % 2 == 1)
+ x++;
+ y++;
+ break;
+ }
+ return map_hex(map, x, y);
+}
+
+Node *map_node(Map * map, gint x, gint y, gint pos)
+{
+ Hex *hex;
+
+ if (x < 0 || x >= map->x_size
+ || y < 0 || y >= map->y_size || pos < 0 || pos >= 6)
+ return NULL;
+
+ hex = map->grid[y][x];
+ if (hex == NULL)
+ return NULL;
+ return hex->nodes[pos];
+}
+
+Edge *map_edge(Map * map, gint x, gint y, gint pos)
+{
+ Hex *hex;
+
+ if (x < 0 || x >= map->x_size
+ || y < 0 || y >= map->y_size || pos < 0 || pos >= 6)
+ return NULL;
+
+ hex = map->grid[y][x];
+ if (hex == NULL)
+ return NULL;
+ return hex->edges[pos];
+}
+
+/* Traverse the map and perform processing at a each node.
+ *
+ * If the callback function returns TRUE, stop traversal immediately
+ * and return TRUE to caller,
+ */
+gboolean map_traverse(Map * map, HexFunc func, void *closure)
+{
+ gint x;
+
+ for (x = 0; x < map->x_size; x++) {
+ gint y;
+
+ for (y = 0; y < map->y_size; y++) {
+ Hex *hex;
+
+ hex = map->grid[y][x];
+ if (hex != NULL && func(map, hex, closure))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/* The x.y grid of hexes are joined into a network, with adjacent
+ * hexes are numbered 0 to 5. The x and y coordinate offsets to each
+ * adjacent hex depend on whether the current hex is at an even or odd
+ * y grid position.
+ *
+ * Nodes are numbered 0 to 5 starting at 0 radians. Edges are numbered
+ * identically to adjacent hexes.
+ */
+
+/* x and y offsets from a hex to find the adjacent hexes.
+ */
+typedef struct {
+ gint x_offset;
+ gint y_offset;
+} HexOffset;
+static HexOffset even_offsets[6] = {
+ {1, 0}, /* 0 */
+ {0, -1}, /* 1 */
+ {-1, -1}, /* 2 */
+ {-1, 0}, /* 3 */
+ {-1, 1}, /* 4 */
+ {0, 1} /* 5 */
+};
+static HexOffset odd_offsets[6] = {
+ {1, 0}, /* 0 */
+ {1, -1}, /* 1 */
+ {0, -1}, /* 2 */
+ {-1, 0}, /* 3 */
+ {0, 1}, /* 4 */
+ {1, 1} /* 5 */
+};
+
+/* Build an array of adjacent hexes
+ */
+static void calc_adjacent(Map * map, gint x, gint y, Hex * adjacent[6])
+{
+ HexOffset *offset;
+ gint idx;
+
+ offset = (y % 2) ? odd_offsets : even_offsets;
+ for (idx = 0; idx < 6; idx++, offset++) {
+ gint x_hex = x + offset->x_offset;
+ gint y_hex = y + offset->y_offset;
+
+ if (x_hex >= 0
+ && y_hex >= 0
+ && x_hex < map->x_size && y_hex < map->y_size)
+ adjacent[idx] = map->grid[y_hex][x_hex];
+ else
+ adjacent[idx] = NULL;
+ }
+}
+
+static gint opposite(gint idx)
+{
+ return (idx + 3) % 6;
+}
+
+/* To expand the grid to a network, we build a chain of nodes and
+ * edges around the current node. Before allocating a new node or
+ * edge, we must check if the node or edge has already been created by
+ * processing an adjacent hex.
+ *
+ * Each node has three adjacent hexes, so we must check two other
+ * hexes to see if the node has already been created. Once we have
+ * found or created the node for a specific position, we must attach
+ * this hex to a specific position on that node.
+ *
+ * Each edge has only two adjacent hexes, so we check the other hex to
+ * see if the edge exists before creating it.
+ *
+ * To see how the nodes, edges and hexes are arranged, look at map.gif
+ */
+typedef struct {
+ gint hex0_pos; /* position of node in adjacent hex */
+ gint hex1_pos; /* position of node in other adjacent hex */
+ gint node_pos; /* node position to connect this hex to */
+
+ gint edge_pos; /* edge position to connect this hex to */
+} ChainPart;
+static ChainPart node_chain[] = {
+ {2, 4, 1, 1}, /* 0 */
+ {3, 5, 2, 1}, /* 1 */
+ {4, 0, 2, 0}, /* 2 */
+ {5, 1, 0, 0}, /* 3 */
+ {0, 2, 0, 0}, /* 4 */
+ {1, 3, 1, 1} /* 5 */
+};
+
+/* Build ring of nodes and edges around the current hex
+ */
+static gboolean build_network(Map * map, Hex * hex,
+ G_GNUC_UNUSED void *closure)
+{
+ Hex *adjacent[6];
+ gint idx;
+ ChainPart *part;
+
+ calc_adjacent(map, hex->x, hex->y, adjacent);
+
+ for (idx = 0, part = node_chain; idx < 6; idx++, part++) {
+ Node *node = NULL;
+ Edge *edge = NULL;
+
+ if (adjacent[idx] != NULL)
+ node = adjacent[idx]->nodes[part->hex0_pos];
+ if (node == NULL && adjacent[(idx + 1) % 6] != NULL)
+ node =
+ adjacent[(idx + 1) % 6]->nodes[part->hex1_pos];
+ if (node == NULL) {
+ node = g_malloc0(sizeof(*node));
+ node->map = map;
+ node->owner = -1;
+ node->x = hex->x;
+ node->y = hex->y;
+ node->pos = idx;
+ }
+ hex->nodes[idx] = node;
+ node->hexes[part->node_pos] = hex;
+
+ if (adjacent[idx] != NULL)
+ edge = adjacent[idx]->edges[opposite(idx)];
+ if (edge == NULL) {
+ edge = g_malloc0(sizeof(*edge));
+ edge->map = map;
+ edge->owner = -1;
+ edge->x = hex->x;
+ edge->y = hex->y;
+ edge->pos = idx;
+ }
+ hex->edges[idx] = edge;
+ edge->hexes[part->edge_pos] = hex;
+ }
+
+ return FALSE;
+}
+
+/* Connect all of the adjacent nodes and edges to each other.
+ *
+ * A node connects to three edges, but we only bother connecting the
+ * edges that are adjacent to this hex. Once the entire grid of hexes
+ * has been processed, all nodes (which require them) will have three
+ * edges.
+ */
+typedef struct {
+ gint node0_pos; /* node 0 connect position in edge */
+ gint node1_pos; /* node 1 connect position in edge */
+ gint edge0_pos; /* edge 0 connect position in node */
+ gint edge1_pos; /* edge 1 connect position in node */
+} ChainConnect;
+static ChainConnect node_connect[] = {
+ {0, 1, 2, 1}, /* 0 */
+ {0, 1, 2, 1}, /* 1 */
+ {0, 1, 0, 2}, /* 2 */
+ {0, 1, 0, 2}, /* 3 */
+ {0, 1, 1, 0}, /* 4 */
+ {0, 1, 1, 0} /* 5 */
+};
+
+/* Connect the the ring of nodes and edges to each other
+ */
+static gboolean connect_network(Map * map, Hex * hex,
+ G_GNUC_UNUSED void *closure)
+{
+ Hex *adjacent[6];
+ gint idx;
+ ChainConnect *connect;
+
+ calc_adjacent(map, hex->x, hex->y, adjacent);
+
+ for (idx = 0, connect = node_connect; idx < 6; idx++, connect++) {
+ Node *node;
+ Edge *edge;
+
+ /* Connect current edge to adjacent nodes
+ */
+ edge = hex->edges[idx];
+ edge->nodes[connect->node0_pos] =
+ hex->nodes[(idx + 5) % 6];
+ edge->nodes[connect->node1_pos] = hex->nodes[idx];
+ /* Connect current node to adjacent edges
+ */
+ node = hex->nodes[idx];
+ node->edges[connect->edge0_pos] = hex->edges[idx];
+ node->edges[connect->edge1_pos] =
+ hex->edges[(idx + 1) % 6];
+ }
+
+ return FALSE;
+}
+
+/* Layout the dice chits on the map according to the order specified.
+ * When laying out the chits, we do not place one on the desert hex.
+ * The maps only specify the layout sequence. When loading the map,
+ * the program when performs the layout, skipping the desert hex.
+ *
+ * By making the program perform the layout, we have the ability to
+ * shuffle the terrain hexes and then lay the chits out accounting for
+ * the new position of the desert.
+ * Returns TRUE if the chits could be distributed without errors
+ */
+static gboolean layout_chits(Map * map)
+{
+ Hex **hexes;
+ gint num_chits;
+ gint x, y;
+ gint idx;
+ gint chit_idx;
+ gint num_deserts;
+
+ g_return_val_if_fail(map != NULL, FALSE);
+ g_return_val_if_fail(map->chits != NULL, FALSE);
+ g_return_val_if_fail(map->chits->len > 0, FALSE);
+
+ /* Count the number of hexes that have chits on them
+ */
+ num_chits = 0;
+ num_deserts = 0;
+ for (x = 0; x < map->x_size; x++)
+ for (y = 0; y < map->y_size; y++) {
+ Hex *hex = map->grid[y][x];
+ if (hex != NULL && hex->chit_pos >= num_chits)
+ num_chits = hex->chit_pos + 1;
+ if (hex != NULL && hex->terrain == DESERT_TERRAIN)
+ num_deserts++;
+ }
+
+ /* Traverse the map and build an array of hexes in chit layout
+ * sequence.
+ */
+ hexes = g_malloc0(num_chits * sizeof(*hexes));
+ for (x = 0; x < map->x_size; x++)
+ for (y = 0; y < map->y_size; y++) {
+ Hex *hex = map->grid[y][x];
+ if (hex == NULL || hex->chit_pos < 0)
+ continue;
+ if (hexes[hex->chit_pos] != NULL) {
+ g_warning("Sequence number %d used again",
+ hex->chit_pos);
+ return FALSE;
+ }
+ hexes[hex->chit_pos] = hex;
+ }
+
+ /* Check the number of chits */
+ if (num_chits < map->chits->len + num_deserts) {
+ g_warning("More chits (%d + %d) than available tiles (%d)",
+ map->chits->len, num_deserts, num_chits);
+ return FALSE;
+ }
+ /* If less chits are defined than tiles that need chits,
+ * the sequence is used again
+ */
+
+ /* Now layout the chits in the sequence specified, skipping
+ * the desert hex.
+ */
+ chit_idx = 0;
+ for (idx = 0; idx < num_chits; idx++) {
+ Hex *hex = hexes[idx];
+ if (hex == NULL)
+ continue;
+
+ if (hex->terrain == DESERT_TERRAIN) {
+ /* Robber always starts in the desert
+ */
+ hex->roll = 0;
+ if (map->robber_hex == NULL) {
+ hex->robber = TRUE;
+ map->robber_hex = hex;
+ }
+ } else {
+ hex->robber = FALSE;
+ hex->roll =
+ g_array_index(map->chits, gint, chit_idx);
+ chit_idx++;
+ if (chit_idx == map->chits->len)
+ chit_idx = 0;
+ }
+ }
+ g_free(hexes);
+ return TRUE;
+}
+
+/* Randomise a map. We do this by shuffling all of the land hexes,
+ * and randomly reassigning port types. This is the procedure
+ * described in the board game rules.
+ */
+void map_shuffle_terrain(Map * map)
+{
+ gint terrain_count[LAST_TERRAIN];
+ gint port_count[ANY_RESOURCE + 1];
+ gint x, y;
+ gint num_terrain;
+ gint num_port;
+
+ /* Remove robber, because the desert will probably move.
+ * It will be restored by layout_chits.
+ */
+ if (map->robber_hex) {
+ map->robber_hex->robber = FALSE;
+ map->robber_hex = NULL;
+ }
+
+ /* Count number of each terrain type
+ */
+ memset(terrain_count, 0, sizeof(terrain_count));
+ memset(port_count, 0, sizeof(port_count));
+ num_terrain = num_port = 0;
+ for (x = 0; x < map->x_size; x++) {
+ for (y = 0; y < map->y_size; y++) {
+ Hex *hex = map->grid[y][x];
+ if (hex == NULL || hex->shuffle == FALSE)
+ continue;
+ if (hex->terrain == SEA_TERRAIN) {
+ if (hex->resource == NO_RESOURCE)
+ continue;
+ port_count[hex->resource]++;
+ num_port++;
+ } else {
+ terrain_count[hex->terrain]++;
+ num_terrain++;
+ }
+ }
+ }
+
+ /* Shuffle the terrain / port types
+ */
+ for (x = 0; x < map->x_size; x++) {
+ for (y = 0; y < map->y_size; y++) {
+ Hex *hex = map->grid[y][x];
+ gint num;
+ gint idx;
+
+ if (hex == NULL || hex->shuffle == FALSE)
+ continue;
+ if (hex->terrain == SEA_TERRAIN) {
+ if (hex->resource == NO_RESOURCE)
+ continue;
+ num =
+ g_rand_int_range(g_rand_ctx, 0,
+ num_port);
+ for (idx = 0;
+ idx < G_N_ELEMENTS(port_count);
+ idx++) {
+ num -= port_count[idx];
+ if (num < 0)
+ break;
+ }
+ port_count[idx]--;
+ num_port--;
+ hex->resource = idx;
+ } else {
+ num = g_rand_int_range(g_rand_ctx, 0,
+ num_terrain);
+ for (idx = 0;
+ idx < G_N_ELEMENTS(terrain_count);
+ idx++) {
+ num -= terrain_count[idx];
+ if (num < 0)
+ break;
+ }
+ terrain_count[idx]--;
+ num_terrain--;
+ hex->terrain = idx;
+ }
+ }
+ }
+
+ /* Fix the chits - the desert probably moved
+ */
+ layout_chits(map);
+}
+
+Hex *map_robber_hex(Map * map)
+{
+ return map->robber_hex;
+}
+
+Hex *map_pirate_hex(Map * map)
+{
+ return map->pirate_hex;
+}
+
+void map_move_robber(Map * map, gint x, gint y)
+{
+ if (map->robber_hex != NULL)
+ map->robber_hex->robber = FALSE;
+ map->robber_hex = map_hex(map, x, y);
+ if (map->robber_hex != NULL)
+ map->robber_hex->robber = TRUE;
+}
+
+void map_move_pirate(Map * map, gint x, gint y)
+{
+ map->pirate_hex = map_hex(map, x, y);
+}
+
+/* Allocate a new map
+ */
+Map *map_new(void)
+{
+ return g_malloc0(sizeof(Map));
+}
+
+static Hex *copy_hex(Map * map, Hex * hex)
+{
+ Hex *copy;
+
+ if (hex == NULL)
+ return NULL;
+ copy = g_malloc0(sizeof(*copy));
+ copy->map = map;
+ copy->y = hex->y;
+ copy->x = hex->x;
+ copy->terrain = hex->terrain;
+ copy->resource = hex->resource;
+ copy->facing = hex->facing;
+ copy->chit_pos = hex->chit_pos;
+ copy->roll = hex->roll;
+ copy->robber = hex->robber;
+ copy->shuffle = hex->shuffle;
+
+ return copy;
+}
+
+static gboolean set_nosetup_nodes(G_GNUC_UNUSED Map * map, Hex * hex,
+ Map * copy)
+{
+ gint idx;
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); ++idx) {
+ Node *node = hex->nodes[idx];
+ /* only handle nodes which are owned by the hex, to
+ * prevent doing every node three times */
+ if (hex->x != node->x || hex->y != node->y)
+ continue;
+ map_node(copy, node->x, node->y, node->pos)->no_setup
+ = node->no_setup;
+ }
+ return FALSE;
+}
+
+static GArray *copy_int_list(GArray * array)
+{
+ GArray *copy = g_array_new(FALSE, FALSE, sizeof(gint));
+ int idx;
+
+ for (idx = 0; idx < array->len; idx++)
+ g_array_append_val(copy, g_array_index(array, gint, idx));
+
+ return copy;
+}
+
+/* Make a copy of an existing map
+ */
+Map *map_copy(Map * map)
+{
+ Map *copy = map_new();
+ int x, y;
+
+ copy->y = map->y;
+ copy->x_size = map->x_size;
+ copy->y_size = map->y_size;
+ for (y = 0; y < MAP_SIZE; y++)
+ for (x = 0; x < MAP_SIZE; x++)
+ copy->grid[y][x] = copy_hex(copy, map->grid[y][x]);
+ map_traverse(copy, build_network, NULL);
+ map_traverse(copy, connect_network, NULL);
+ map_traverse(map, (HexFunc) set_nosetup_nodes, copy);
+ if (map->robber_hex == NULL)
+ copy->robber_hex = NULL;
+ else
+ copy->robber_hex =
+ copy->grid[map->robber_hex->y][map->robber_hex->x];
+ if (map->pirate_hex == NULL)
+ copy->pirate_hex = NULL;
+ else
+ copy->pirate_hex =
+ copy->grid[map->pirate_hex->y][map->pirate_hex->x];
+ copy->shrink_left = map->shrink_left;
+ copy->shrink_right = map->shrink_right;
+ copy->has_moved_ship = map->has_moved_ship;
+ copy->have_bridges = map->have_bridges;
+ copy->has_pirate = map->has_pirate;
+ copy->shrink_left = map->shrink_left;
+ copy->shrink_right = map->shrink_right;
+ copy->chits = copy_int_list(map->chits);
+
+ return copy;
+}
+
+/* Maps are sent from the server to the client a line at a time. This
+ * routine formats a line of a map for just that purpose.
+ * It returns an allocated buffer, which must be freed by the caller.
+ */
+gchar *map_format_line(Map * map, gboolean write_secrets, gint y)
+{
+ gchar *line = NULL;
+ gchar buffer[20]; /* Buffer for the info about one hex */
+ gint x;
+
+ for (x = 0; x < map->x_size; x++) {
+ gchar *bufferpos = buffer;
+ Hex *hex = map->grid[y][x];
+
+ if (x > 0)
+ *bufferpos++ = ',';
+ if (hex == NULL) {
+ *bufferpos++ = '-';
+ } else {
+ switch (hex->terrain) {
+ case HILL_TERRAIN:
+ *bufferpos++ = 'h';
+ break;
+ case FIELD_TERRAIN:
+ *bufferpos++ = 'f';
+ break;
+ case MOUNTAIN_TERRAIN:
+ *bufferpos++ = 'm';
+ break;
+ case PASTURE_TERRAIN:
+ *bufferpos++ = 'p';
+ break;
+ case FOREST_TERRAIN:
+ *bufferpos++ = 't'; /* tree */
+ break;
+ case DESERT_TERRAIN:
+ *bufferpos++ = 'd';
+ break;
+ case GOLD_TERRAIN:
+ *bufferpos++ = 'g';
+ break;
+ case SEA_TERRAIN:
+ *bufferpos++ = 's';
+ if (hex == map->pirate_hex)
+ *bufferpos++ = 'R';
+ if (hex->resource == NO_RESOURCE)
+ break;
+ switch (hex->resource) {
+ case BRICK_RESOURCE:
+ *bufferpos++ = 'b';
+ break;
+ case GRAIN_RESOURCE:
+ *bufferpos++ = 'g';
+ break;
+ case ORE_RESOURCE:
+ *bufferpos++ = 'o';
+ break;
+ case WOOL_RESOURCE:
+ *bufferpos++ = 'w';
+ break;
+ case LUMBER_RESOURCE:
+ *bufferpos++ = 'l';
+ break;
+ case ANY_RESOURCE:
+ *bufferpos++ = '?';
+ break;
+ case NO_RESOURCE:
+ break;
+ case GOLD_RESOURCE:
+ g_assert_not_reached();
+ }
+ *bufferpos++ = hex->facing + '0';
+ break;
+ case LAST_TERRAIN:
+ *bufferpos++ = '-';
+ break;
+ default:
+ g_assert_not_reached();
+ break;
+ }
+ if (hex->chit_pos >= 0) {
+ sprintf(bufferpos, "%d", hex->chit_pos);
+ bufferpos += strlen(bufferpos);
+ }
+ if (write_secrets && !hex->shuffle) {
+ *bufferpos++ = '+';
+ }
+ }
+ *bufferpos = '\0';
+ if (line) {
+ gchar *old = line;
+ line = g_strdup_printf("%s%s", line, buffer);
+ g_free(old);
+ } else {
+ line = g_strdup(buffer);
+ }
+ }
+ return line;
+}
+
+/* Read a map line into the grid
+ */
+gboolean map_parse_line(Map * map, const gchar * line)
+{
+ gint x = 0;
+
+ for (;;) {
+ Hex *hex;
+
+ switch (*line++) {
+ case '\0':
+ case '\n':
+ map->y++;
+ return TRUE;
+ case '-':
+ x++;
+ continue;
+ case ',':
+ case ' ':
+ case '\t':
+ continue;
+ }
+ --line;
+
+ if (x >= MAP_SIZE || map->y >= MAP_SIZE)
+ continue;
+
+ hex = g_malloc0(sizeof(*hex));
+ hex->map = map;
+ hex->y = map->y;
+ hex->x = x;
+ hex->terrain = SEA_TERRAIN;
+ hex->resource = NO_RESOURCE;
+ hex->facing = 0;
+ hex->chit_pos = -1;
+ hex->shuffle = TRUE;
+
+ switch (*line++) {
+ case 's': /* sea */
+ hex->terrain = SEA_TERRAIN;
+ if (*line == 'R') {
+ ++line;
+ map->pirate_hex = hex;
+ map->has_pirate = TRUE;
+ }
+ switch (*line++) {
+ case 'b':
+ hex->resource = BRICK_RESOURCE;
+ break;
+ case 'g':
+ hex->resource = GRAIN_RESOURCE;
+ break;
+ case 'o':
+ hex->resource = ORE_RESOURCE;
+ break;
+ case 'w':
+ hex->resource = WOOL_RESOURCE;
+ break;
+ case 'l':
+ hex->resource = LUMBER_RESOURCE;
+ break;
+ case 'm': /* mine */
+ hex->resource = GOLD_RESOURCE;
+ break;
+ case '?':
+ hex->resource = ANY_RESOURCE;
+ break;
+ default:
+ hex->resource = NO_RESOURCE;
+ --line;
+ break;
+ }
+ hex->facing = 0;
+ if (hex->resource != NO_RESOURCE) {
+ if (isdigit(*line))
+ hex->facing = *line++ - '0';
+ }
+ break;
+ case 't': /* tree */
+ hex->terrain = FOREST_TERRAIN;
+ break;
+ case 'p':
+ hex->terrain = PASTURE_TERRAIN;
+ break;
+ case 'f':
+ hex->terrain = FIELD_TERRAIN;
+ break;
+ case 'h':
+ hex->terrain = HILL_TERRAIN;
+ break;
+ case 'm':
+ hex->terrain = MOUNTAIN_TERRAIN;
+ break;
+ case 'd':
+ hex->terrain = DESERT_TERRAIN;
+ break;
+ case 'g':
+ hex->terrain = GOLD_TERRAIN;
+ break;
+ default:
+ g_free(hex);
+ continue;
+ }
+
+ /* Read the chit sequence number
+ */
+ if (isdigit(*line)) {
+ hex->chit_pos = 0;
+ while (isdigit(*line))
+ hex->chit_pos = hex->chit_pos * 10
+ + *line++ - '0';
+ }
+
+ /* Check if hex can be randomly shuffled
+ */
+ if (*line == '+') {
+ hex->shuffle = FALSE;
+ line++;
+ }
+ if (hex->chit_pos < 0 && hex->terrain != SEA_TERRAIN) {
+ g_warning
+ ("Land tile without chit sequence number");
+ return FALSE;
+ }
+
+ map->grid[map->y][x] = hex;
+ if (x >= map->x_size)
+ map->x_size = x + 1;
+ if (map->y >= map->y_size)
+ map->y_size = map->y + 1;
+ x++;
+ }
+ return TRUE;
+}
+
+/* Finalise the map loading by building a network of nodes, edges and
+ * hexes. Since every second row of hexes is offset, we might be able
+ * to shrink the left / right margins depending on the distribution of
+ * hexes.
+ * Returns true if the map could be finalised.
+ */
+gboolean map_parse_finish(Map * map)
+{
+ gint y;
+ gboolean success;
+
+ success = layout_chits(map);
+
+ map_traverse(map, build_network, NULL);
+ map_traverse(map, connect_network, NULL);
+
+ map->shrink_left = TRUE;
+ map->shrink_right = TRUE;
+ for (y = 0; y < map->y_size; y += 2)
+ if (map->grid[y][0] != NULL) {
+ map->shrink_left = FALSE;
+ break;
+ }
+ for (y = 1; y < map->y_size; y += 2)
+ if (map->grid[y][map->x_size - 1] != NULL) {
+ map->shrink_right = FALSE;
+ break;
+ }
+ return success;
+}
+
+/* Disconnect a hex from all nodes and edges that it does not "own"
+ */
+static gboolean disconnect_hex(G_GNUC_UNUSED Map * map, Hex * hex,
+ G_GNUC_UNUSED void *closure)
+{
+ gint idx;
+
+ for (idx = 0; idx < 6; idx++) {
+ const Node *node = hex->nodes[idx];
+ const Edge *edge = hex->edges[idx];
+
+ if (node && (node->x != hex->x || node->y != hex->y))
+ hex->nodes[idx] = NULL;
+ if (edge && (edge->x != hex->x || edge->y != hex->y))
+ hex->edges[idx] = NULL;
+ }
+
+ return FALSE;
+}
+
+/* Free a node and all of the hexes and nodes that it is connected to.
+ */
+static gboolean free_hex(G_GNUC_UNUSED Map * map, Hex * hex,
+ G_GNUC_UNUSED void *closure)
+{
+ gint idx;
+
+ for (idx = 0; idx < 6; idx++) {
+ Node *node = hex->nodes[idx];
+ Edge *edge = hex->edges[idx];
+
+ if (node != NULL)
+ g_free(node);
+ if (edge != NULL)
+ g_free(edge);
+ }
+ g_free(hex);
+
+ return FALSE;
+}
+
+/* Free a map
+ */
+void map_free(Map * map)
+{
+ map_traverse(map, disconnect_hex, NULL);
+ map_traverse(map, free_hex, NULL);
+ g_array_free(map->chits, TRUE);
+ g_free(map);
+}
+
+Hex *map_add_hex(Map * map, gint x, gint y)
+{
+ Hex *hex;
+
+ g_assert(x < map->x_size);
+ g_assert(y < map->y_size);
+ hex = g_malloc0(sizeof(*hex));
+ hex->map = map;
+ hex->y = y;
+ hex->x = x;
+ map->grid[y][x] = hex;
+ build_network(map, hex, NULL);
+ connect_network(map, hex, NULL);
+ return hex;
+}
Added: trunk/common/map.h
===================================================================
--- trunk/common/map.h (rev 0)
+++ trunk/common/map.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,247 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __map_h
+#define __map_h
+
+#include <glib.h>
+
+/* The order of the Terrain enums is EXTREMELY important! The order
+ * must match the resources indicated in enum Resource.
+ */
+typedef enum {
+ HILL_TERRAIN,
+ FIELD_TERRAIN,
+ MOUNTAIN_TERRAIN,
+ PASTURE_TERRAIN,
+ FOREST_TERRAIN,
+ DESERT_TERRAIN,
+ SEA_TERRAIN,
+ GOLD_TERRAIN,
+ LAST_TERRAIN /* New terrain types go before this */
+} Terrain;
+
+/* The order of the Resource enums up to NO_RESOURCE is EXTREMELY important!
+ * The numbers are used to index arrays in cost_*(), and to identify
+ * resource accumulators in player statistics. The NO_RESOURCE marks
+ * the end of the actual resources.
+ */
+typedef enum {
+ BRICK_RESOURCE,
+ GRAIN_RESOURCE,
+ ORE_RESOURCE,
+ WOOL_RESOURCE,
+ LUMBER_RESOURCE,
+ NO_RESOURCE, /* All normal producing resources go before this */
+ ANY_RESOURCE, /* Used for 3:1 ports */
+ GOLD_RESOURCE /* Gold */
+} Resource;
+
+/* Types of structure that can be built
+ */
+typedef enum {
+ BUILD_NONE, /* vacant node/edge */
+ BUILD_ROAD, /* road was built */
+ BUILD_BRIDGE, /* bridge was built */
+ BUILD_SHIP, /* ship was built */
+ BUILD_SETTLEMENT, /* settlement was built */
+ BUILD_CITY, /* city was built */
+ BUILD_CITY_WALL, /* city wall was built */
+ BUILD_MOVE_SHIP /* a ship was moved (only used for undo list) */
+} BuildType;
+
+#define NUM_BUILD_TYPES (BUILD_CITY_WALL + 1)
+
+/* Maps are built up from a network of hexes, edges, and nodes.
+ *
+ * Each hex has connections to six edges, and six nodes. Each node
+ * connects to three hexes and three edges, and each edge connects to
+ * two hexes and two nodes.
+ */
+typedef struct _Node Node;
+typedef struct _Edge Edge;
+typedef struct _Hex Hex;
+typedef struct _Map Map;
+struct _Hex {
+ Map *map; /* owner map */
+ gint x; /* x-pos on grid */
+ gint y; /* y-pos on grid */
+
+ Node *nodes[6]; /* adjacent nodes */
+ Edge *edges[6]; /* adjacent edges */
+ Terrain terrain; /* type of terrain for this hex */
+ Resource resource; /* resource at this port */
+ gint facing; /* direction port is facing */
+ gint chit_pos; /* position in chit layout sequence */
+
+ gint roll; /* 2..12 number allocated to hex */
+ gboolean robber; /* is the robber here */
+ gboolean shuffle; /* can the hex be shuffled? */
+};
+
+struct _Node {
+ Map *map; /* owner map */
+ gint x; /* x-pos of owner hex */
+ gint y; /* y-pos of owner hex */
+ gint pos; /* location of node on hex */
+
+ Hex *hexes[3]; /* adjacent hexes */
+ Edge *edges[3]; /* adjacent edges */
+ gint owner; /* building owner, -1 == no building */
+ BuildType type; /* type of node (if owner defined) */
+
+ gboolean visited; /* used for longest road */
+ gboolean no_setup; /* setup is not allowed on this node */
+ gboolean city_wall; /* has city wall */
+};
+
+struct _Edge {
+ Map *map; /* owner map */
+ gint x; /* x-pos of owner hex */
+ gint y; /* y-pos of owner hex */
+ gint pos; /* location of edge on hex */
+
+ Hex *hexes[2]; /* adjacent hexes */
+ Node *nodes[2]; /* adjacent nodes */
+ gint owner; /* road owner, -1 == no road */
+ BuildType type; /* type of edge (if owner defined) */
+
+ gboolean visited; /* used for longest road */
+};
+
+/* All of the hexes are stored in a 2 dimensional array laid out as
+ * shown in grid.gif
+ */
+#define MAP_SIZE 32 /* maximum map dimension */
+
+struct _Map {
+ gint y; /* current y-pos during parse */
+
+ gboolean have_bridges; /* are bridges legal on map? */
+ gboolean has_pirate; /* is the pirate allowed in this game? */
+ gint x_size; /* number of hexes across map */
+ gint y_size; /* number of hexes down map */
+ Hex *grid[MAP_SIZE][MAP_SIZE]; /* hexes arranged onto a grid */
+ Hex *robber_hex; /* which hex is the robber on */
+ Hex *pirate_hex; /* which hex is the pirate on */
+ gboolean has_moved_ship; /* has the player moved a ship already? */
+
+ gboolean shrink_left; /* shrink left x-margin? */
+ gboolean shrink_right; /* shrink right x-margin? */
+ GArray *chits; /* chit number sequence */
+};
+
+typedef struct {
+ gint owner;
+ gboolean any_resource;
+ gboolean specific_resource[NO_RESOURCE];
+} MaritimeInfo;
+
+typedef enum {
+ HEX_DIR_E,
+ HEX_DIR_NE,
+ HEX_DIR_NW,
+ HEX_DIR_W,
+ HEX_DIR_SW,
+ HEX_DIR_SE
+} HexDirection;
+
+/* map.c
+ */
+Hex *map_hex(Map * map, gint x, gint y);
+Hex *hex_in_direction(Map * map, const Hex * hex, HexDirection direction);
+Edge *map_edge(Map * map, gint x, gint y, gint pos);
+Node *map_node(Map * map, gint x, gint y, gint pos);
+typedef gboolean(*HexFunc) (Map * map, Hex * hex, void *closure);
+gboolean map_traverse(Map * map, HexFunc func, void *closure);
+void map_shuffle_terrain(Map * map);
+Hex *map_robber_hex(Map * map);
+Hex *map_pirate_hex(Map * map);
+void map_move_robber(Map * map, gint x, gint y);
+void map_move_pirate(Map * map, gint x, gint y);
+
+Map *map_new(void);
+Map *map_copy(Map * map);
+gchar *map_format_line(Map * map, gboolean write_secrets, gint y);
+gboolean map_parse_line(Map * map, const gchar * line);
+gboolean map_parse_finish(Map * map);
+void map_free(Map * map);
+Hex *map_add_hex(Map * map, gint x, gint y);
+
+/* map_query.c
+ */
+/* simple checks */
+gboolean is_edge_adjacent_to_node(const Edge * edge, const Node * node);
+gboolean is_edge_on_land(const Edge * edge);
+gboolean is_edge_on_sea(const Edge * edge);
+gboolean is_node_on_land(const Node * node);
+gboolean node_has_road_owned_by(const Node * node, gint owner);
+gboolean node_has_ship_owned_by(const Node * node, gint owner);
+gboolean node_has_bridge_owned_by(const Node * node, gint owner);
+gboolean is_node_spacing_ok(const Node * node);
+gboolean is_node_proximity_ok(const Node * node);
+gboolean is_node_next_to_robber(const Node * node);
+/* cursor checks */
+gboolean can_road_be_setup(const Edge * edge);
+gboolean can_road_be_built(const Edge * edge, gint owner);
+gboolean can_ship_be_setup(const Edge * edge);
+gboolean can_ship_be_built(const Edge * edge, gint owner);
+gboolean can_ship_be_moved(const Edge * edge, gint owner);
+gboolean can_bridge_be_setup(const Edge * edge);
+gboolean can_bridge_be_built(const Edge * edge, gint owner);
+gboolean can_settlement_be_setup(const Node * node);
+gboolean can_settlement_be_built(const Node * node, gint owner);
+gboolean can_settlement_be_upgraded(const Node * node, gint owner);
+gboolean can_city_be_built(const Node * node, int owner);
+gboolean can_city_wall_be_built(const Node * node, int owner);
+gboolean can_robber_or_pirate_be_moved(const Hex * hex);
+/* map global queries */
+gboolean map_can_place_road(Map * map, int owner);
+gboolean map_can_place_ship(Map * map, int owner);
+gboolean map_can_place_bridge(Map * map, int owner);
+gboolean map_can_place_settlement(Map * map, int owner);
+gboolean map_can_place_city_wall(Map * map, int owner);
+gboolean map_can_upgrade_settlement(Map * map, int owner);
+
+gboolean map_building_spacing_ok(Map * map, gint owner, BuildType type,
+ gint x, gint y, gint pos);
+gboolean map_building_connect_ok(Map * map, gint owner, BuildType type,
+ gint x, gint y, gint pos);
+gboolean map_building_vacant(Map * map, BuildType type,
+ gint x, gint y, gint pos);
+gboolean map_road_vacant(Map * map, gint x, gint y, gint pos);
+gboolean map_road_connect_ok(Map * map, gint owner, gint x, gint y,
+ gint pos);
+gboolean map_ship_vacant(Map * map, gint x, gint y, gint pos);
+gboolean map_ship_connect_ok(Map * map, gint owner, gint x, gint y,
+ gint pos);
+gboolean map_bridge_vacant(Map * map, gint x, gint y, gint pos);
+gboolean map_bridge_connect_ok(Map * map, gint owner, gint x, gint y,
+ gint pos);
+/* information gathering */
+void map_longest_road(Map * map, gint * lengths, gint num_players);
+gboolean map_is_island_discovered(Map * map, Node * node, gint owner);
+void map_maritime_info(Map * map, MaritimeInfo * info, gint owner);
+guint map_count_islands(Map * map);
+
+extern GRand *g_rand_ctx;
+
+#endif
Added: trunk/common/map_query.c
===================================================================
--- trunk/common/map_query.c (rev 0)
+++ trunk/common/map_query.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,1169 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <math.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "game.h"
+#include "map.h"
+
+/* Local function prototypes */
+gboolean node_has_edge_owned_by(const Node * node, gint owner,
+ BuildType type);
+gboolean is_road_valid(const Edge * edge, gint owner);
+gboolean is_ship_valid(const Edge * edge, gint owner);
+gboolean is_bridge_valid(const Edge * edge, gint owner);
+
+
+/* This file is broken into a number of sections:
+ *
+ * Simple Checks:
+ *
+ * Most map queries require a number of checks to be performed. The
+ * results of the checks are combined to provide a more complex
+ * answer.
+ *
+ * Cursor Checks:
+ *
+ * When interacting with the user, the GUI needs to establish whether
+ * or not to draw a cursor over a specific edge, node or hex. Cursor
+ * check functions are designed to be passed as the check_func
+ * parameter to the gui_map_set_cursor() function.
+ *
+ * Queries:
+ *
+ * Provides an answer to a specific question about the entire map.
+ */
+
+/* Return whether or not an edge is adjacent to a node
+ */
+gboolean is_edge_adjacent_to_node(const Edge * edge, const Node * node)
+{
+ g_return_val_if_fail(edge != NULL, FALSE);
+ g_return_val_if_fail(node != NULL, FALSE);
+ return edge->nodes[0] == node || edge->nodes[1] == node;
+}
+
+/* Return whether or not an edge is on land or coast
+ */
+gboolean is_edge_on_land(const Edge * edge)
+{
+ gint idx;
+
+ g_return_val_if_fail(edge != NULL, FALSE);
+
+ for (idx = 0; idx < G_N_ELEMENTS(edge->hexes); idx++) {
+ Hex *hex = edge->hexes[idx];
+ if (hex != NULL && hex->terrain != SEA_TERRAIN)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Return whether or not an edge is on sea or coast (used only for ships)
+ */
+gboolean is_edge_on_sea(const Edge * edge)
+{
+ gint idx;
+
+ g_return_val_if_fail(edge != NULL, FALSE);
+
+ /* If the pirate is currently next to the edge, then specific sea
+ * actions should not be possible (building ships is the only
+ * specific sea action). */
+ for (idx = 0; idx < G_N_ELEMENTS(edge->hexes); idx++) {
+ Hex *hex = edge->hexes[idx];
+ if (hex && edge->map->pirate_hex == hex)
+ return FALSE;
+ }
+ /* The pirate is not next to the edge, return true if there is sea */
+ for (idx = 0; idx < G_N_ELEMENTS(edge->hexes); idx++) {
+ Hex *hex = edge->hexes[idx];
+ if (hex != NULL && hex->terrain == SEA_TERRAIN)
+ return TRUE;
+ }
+
+ /* There is no sea */
+ return FALSE;
+}
+
+/* Return whether or not a node is on land
+ */
+gboolean is_node_on_land(const Node * node)
+{
+ gint idx;
+
+ g_return_val_if_fail(node != NULL, FALSE);
+
+ for (idx = 0; idx < G_N_ELEMENTS(node->hexes); idx++) {
+ Hex *hex = node->hexes[idx];
+ if (hex != NULL && hex->terrain != SEA_TERRAIN)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Check if a node has a adjacent road/ship/bridge owned by the
+ * specified player
+ */
+gboolean node_has_edge_owned_by(const Node * node, gint owner,
+ BuildType type)
+{
+ gint idx;
+
+ g_return_val_if_fail(node != NULL, FALSE);
+
+ for (idx = 0; idx < G_N_ELEMENTS(node->edges); idx++)
+ if (node->edges[idx] != NULL
+ && node->edges[idx]->owner == owner
+ && node->edges[idx]->type == type)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Check if a node has a adjacent road owned by the specified player
+ */
+gboolean node_has_road_owned_by(const Node * node, gint owner)
+{
+ g_return_val_if_fail(node != NULL, FALSE);
+ return node_has_edge_owned_by(node, owner, BUILD_ROAD);
+}
+
+/* Check if a node has a adjacent ship owned by the specified player
+ */
+gboolean node_has_ship_owned_by(const Node * node, gint owner)
+{
+ g_return_val_if_fail(node != NULL, FALSE);
+ return node_has_edge_owned_by(node, owner, BUILD_SHIP);
+}
+
+/* Check if a node has a adjacent bridge owned by the specified player
+ */
+gboolean node_has_bridge_owned_by(const Node * node, gint owner)
+{
+ g_return_val_if_fail(node != NULL, FALSE);
+ return node_has_edge_owned_by(node, owner, BUILD_BRIDGE);
+}
+
+/* Check node proximity to other buildings. A building can be
+ * constructed on a node if none of the adjacent nodes have buildings
+ * on them. There is an exception when bridges are being used - two
+ * buildings may be on adjacent nodes if separated by water.
+ */
+gboolean is_node_spacing_ok(const Node * node)
+{
+ gint idx;
+
+ g_return_val_if_fail(node != NULL, FALSE);
+ for (idx = 0; idx < G_N_ELEMENTS(node->edges); idx++) {
+ Edge *edge = node->edges[idx];
+ gint idx2;
+
+ if (edge == NULL)
+ continue;
+ if (node->map->have_bridges && !is_edge_on_land(edge))
+ continue;
+ else
+ for (idx2 = 0; idx2 < G_N_ELEMENTS(edge->nodes);
+ ++idx2) {
+ Node *scan = edge->nodes[idx2];
+ if (scan == node)
+ continue;
+ if (scan->type != BUILD_NONE)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Check if the specified node is next to the hex with the robber
+ */
+gboolean is_node_next_to_robber(const Node * node)
+{
+ gint idx;
+
+ g_return_val_if_fail(node != NULL, FALSE);
+ for (idx = 0; idx < G_N_ELEMENTS(node->hexes); idx++)
+ if (node->hexes[idx]->robber)
+ return TRUE;
+
+ return FALSE;
+}
+
+/* Check if a road has been positioned properly
+ */
+gboolean is_road_valid(const Edge * edge, gint owner)
+{
+ gint idx;
+
+ g_return_val_if_fail(edge != NULL, FALSE);
+
+ /* Can only build road if edge is adjacent to a land hex
+ */
+ if (!is_edge_on_land(edge))
+ return FALSE;
+
+ /* Road can be build adjacent to building we own, or a road we
+ * own that is not separated by a building owned by someone else
+ */
+ for (idx = 0; idx < G_N_ELEMENTS(edge->nodes); idx++) {
+ Node *node = edge->nodes[idx];
+
+ if (node->owner == owner)
+ return TRUE;
+ if (node->owner >= 0)
+ continue;
+
+ if (node_has_road_owned_by(node, owner)
+ || node_has_bridge_owned_by(node, owner))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Check if a ship has been positioned properly
+ */
+gboolean is_ship_valid(const Edge * edge, gint owner)
+{
+ gint idx;
+
+ g_return_val_if_fail(edge != NULL, FALSE);
+
+ /* Can only build ship if edge is adjacent to a sea hex
+ */
+ if (!is_edge_on_sea(edge))
+ return FALSE;
+
+ /* Ship can be build adjacent to building we own, or a ship we
+ * own that is not separated by a building owned by someone else
+ */
+ for (idx = 0; idx < G_N_ELEMENTS(edge->nodes); idx++) {
+ Node *node = edge->nodes[idx];
+
+ if (node->owner == owner)
+ return TRUE;
+ if (node->owner >= 0)
+ continue;
+
+ if (node_has_ship_owned_by(node, owner))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Check if a bridge has been positioned properly
+ */
+gboolean is_bridge_valid(const Edge * edge, gint owner)
+{
+ gint idx;
+
+ g_return_val_if_fail(edge != NULL, FALSE);
+
+ /* Can only build bridge if edge is not on land
+ */
+ if (is_edge_on_land(edge))
+ return FALSE;
+
+ /* Bridge can be build adjacent to building we own, or a road we
+ * own that is not separated by a building owned by someone else
+ */
+ for (idx = 0; idx < G_N_ELEMENTS(edge->nodes); idx++) {
+ Node *node = edge->nodes[idx];
+
+ if (node->owner == owner)
+ return TRUE;
+ if (node->owner >= 0)
+ continue;
+
+ if (node_has_road_owned_by(node, owner)
+ || node_has_bridge_owned_by(node, owner))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Returns TRUE if one of the nodes can be used for setup,
+ * or if it already has been used.
+ * A full check (to see if the owner of the road matches the owner
+ * of the settlement) is performed in another function
+ */
+static gboolean can_adjacent_settlement_be_built(const Edge * edge)
+{
+ g_return_val_if_fail(edge != NULL, FALSE);
+ return can_settlement_be_setup(edge->nodes[0]) ||
+ can_settlement_be_setup(edge->nodes[1]) ||
+ edge->nodes[0]->owner >= 0 || edge->nodes[1]->owner >= 0;
+}
+
+/* Edge cursor check function.
+ *
+ * Determine whether or not a road can be built in this edge by the
+ * specified player during the setup phase. Perform the following checks:
+ *
+ * 1 - Edge must not currently have a road on it.
+ * 2 - Edge must be adjacent to a land hex.
+ * 3 - At least one node must available for a settlement
+ *
+ * The checks are not as strict as for normal play. This allows the
+ * player to try a few different configurations without layout
+ * restrictions. The server will enfore correct placement at the end
+ * of the setup phase.
+ */
+gboolean can_road_be_setup(const Edge * edge)
+{
+ g_return_val_if_fail(edge != NULL, FALSE);
+ return edge->owner < 0 && is_edge_on_land(edge)
+ && can_adjacent_settlement_be_built(edge);
+}
+
+/* Edge cursor check function.
+ *
+ * Determine whether or not a ship can be built in this edge by the
+ * specified player during the setup phase. Perform the following checks:
+ *
+ * 1 - Edge must not currently have a ship on it.
+ * 2 - Edge must be adjacent to a sea hex.
+ * 3 - At least one node must available for a settlement
+ *
+ * The checks are not as strict as for normal play. This allows the
+ * player to try a few different configurations without layout
+ * restrictions. The server will enfore correct placement at the end
+ * of the setup phase.
+ */
+gboolean can_ship_be_setup(const Edge * edge)
+{
+ g_return_val_if_fail(edge != NULL, FALSE);
+ return edge->owner < 0 && is_edge_on_sea(edge)
+ && can_adjacent_settlement_be_built(edge);
+}
+
+/* Edge cursor check function.
+ *
+ * Determine whether or not a bridge can be built in this edge by the
+ * specified player during the setup phase. Perform the following checks:
+ *
+ * 1 - Edge must not currently have a road on it.
+ * 2 - Edge must not be adjacent to a land hex.
+ * 3 - At least one node must available for a settlement
+ *
+ * The checks are not as strict as for normal play. This allows the
+ * player to try a few different configurations without layout
+ * restrictions. The server will enfore correct placement at the end
+ * of the setup phase.
+ */
+gboolean can_bridge_be_setup(const Edge * edge)
+{
+ g_return_val_if_fail(edge != NULL, FALSE);
+ return edge->owner < 0 && !is_edge_on_land(edge)
+ && can_adjacent_settlement_be_built(edge);
+}
+
+/* Edge cursor check function.
+ *
+ * Determine whether or not a road can be built on this edge by the
+ * specified player. Perform the following checks:
+ *
+ * 1 - Edge must not currently have a road on it.
+ * 2 - Edge must be adjacent to a land hex.
+ * 3 - Edge must be adjacent to a building that is owned by the
+ * specified player, or must be adjacent to another road segment
+ * owned by the specifed player, but not separated by a building
+ * owned by a different player.
+ */
+gboolean can_road_be_built(const Edge * edge, gint owner)
+{
+ g_return_val_if_fail(edge != NULL, FALSE);
+ return edge->owner < 0 && is_road_valid(edge, owner);
+}
+
+/* Edge cursor check function.
+ *
+ * Determine whether or not a ship can be built on this edge by the
+ * specified player. Perform the following checks:
+ *
+ * 1 - Edge must not currently have a road or ship on it.
+ * 2 - Edge must be adjacent to a sea hex.
+ * 3 - Edge must be adjacent to a building that is owned by the
+ * specified player, or must be adjacent to another ship segment
+ * owned by the specifed player, but not separated by a building
+ * owned by a different player.
+ */
+gboolean can_ship_be_built(const Edge * edge, gint owner)
+{
+ g_return_val_if_fail(edge != NULL, FALSE);
+ return edge->owner < 0 && is_ship_valid(edge, owner);
+}
+
+/* Helper function for can_ship_be_moved */
+static gboolean can_ship_be_moved_node(const Node * node, gint owner,
+ const Edge * not)
+{
+ gint idx;
+
+ g_return_val_if_fail(node != NULL, FALSE);
+ g_return_val_if_fail(not != NULL, FALSE);
+
+ /* if a building of a different player is on it, it is
+ * unconnected */
+ if (node->type != BUILD_NONE && node->owner != owner)
+ return TRUE;
+ /* if there is a building of the player, it is connected */
+ if (node->type != BUILD_NONE)
+ return FALSE;
+ /* no buildings: check all edges for ships */
+ for (idx = 0; idx < G_N_ELEMENTS(node->edges); idx++) {
+ Edge *edge = node->edges[idx];
+ /* If this is a ship of the player, it is connected */
+ if (edge && edge->owner == owner && edge != not
+ && edge->type == BUILD_SHIP)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Edge cursor check function.
+ *
+ * Determine whether or not a ship can be moved from this edge by the
+ * specified player. Perform the following checks:
+ *
+ * 1 - Edge must currently have a ship on it.
+ * 2 - On one side, there must be neither a building, nor a ship of the
+ * specified player. A ship is allowed, if there is building of a
+ * different player in between.
+ */
+gboolean can_ship_be_moved(const Edge * edge, gint owner)
+{
+ gint idx;
+ g_return_val_if_fail(edge != NULL, FALSE);
+ /* edge must be a ship of the correct user */
+ if (edge->owner != owner || edge->type != BUILD_SHIP)
+ return FALSE;
+ /* if the pirate is next to the edge, it is not allowed to move */
+ if (!is_edge_on_sea(edge))
+ return FALSE;
+ /* check all nodes, until one is found that is not connected */
+ for (idx = 0; idx < G_N_ELEMENTS(edge->nodes); idx++)
+ if (can_ship_be_moved_node(edge->nodes[idx], owner, edge))
+ return TRUE;
+ return FALSE;
+}
+
+/* Edge cursor check function.
+ *
+ * Determine whether or not a bridge can be built on this edge by the
+ * specified player. Perform the following checks:
+ *
+ * 1 - Edge must not currently have a road on it.
+ * 2 - Edge must not be adjacent to a land hex.
+ * 3 - Edge must be adjacent to a building that is owned by the
+ * specified player, or must be adjacent to another road/bridge
+ * segment owned by the specifed player, but not separated by a
+ * building owned by a different player.
+ */
+gboolean can_bridge_be_built(const Edge * edge, gint owner)
+{
+ g_return_val_if_fail(edge != NULL, FALSE);
+ return edge->owner < 0 && is_bridge_valid(edge, owner);
+}
+
+/* Node cursor check function.
+ *
+ * Determine whether or not a settlement can be built on this node by
+ * the specified player during the setup phase. Perform the following
+ * checks:
+ *
+ * 1 - Node must not be in the no-setup list.
+ * 2 - Node must be vacant.
+ * 3 - Node must be adjacent to a land hex.
+ * 4 - Node must not be within one node of another building.
+ *
+ * The checks are not as strict as for normal play. This allows the
+ * player to try a few different configurations without layout
+ * restrictions. The server will enfore correct placement at the end
+ * of the setup phase.
+ */
+gboolean can_settlement_be_setup(const Node * node)
+{
+ g_return_val_if_fail(node != NULL, FALSE);
+ return !node->no_setup && node->owner < 0 && is_node_on_land(node)
+ && is_node_spacing_ok(node);
+}
+
+/* Node cursor check function.
+ *
+ * Determine whether or not a settlement can be built on this node by the
+ * specified player. Perform the following checks:
+ *
+ * 1 - Node must be vacant.
+ * 2 - Node must be adjacent to a road owned by the specified player
+ * 3 - Node must be adjacent to a land hex.
+ * 4 - Node must not be within one node of another building.
+ */
+gboolean can_settlement_be_built(const Node * node, gint owner)
+{
+ g_return_val_if_fail(node != NULL, FALSE);
+ return node->owner < 0 && (node_has_road_owned_by(node, owner)
+ || node_has_ship_owned_by(node, owner)
+ || node_has_bridge_owned_by(node,
+ owner))
+ && is_node_on_land(node)
+ && is_node_spacing_ok(node);
+}
+
+/* Node cursor check function.
+ *
+ * Determine whether or not a settlement can be upgraded to a city by
+ * the specified player.
+ */
+gboolean can_settlement_be_upgraded(const Node * node, gint owner)
+{
+ g_return_val_if_fail(node != NULL, FALSE);
+ return node->owner == owner && node->type == BUILD_SETTLEMENT;
+}
+
+/* Node cursor check function.
+ *
+ * Determine whether or not a city can be built on this node by the
+ * specified player. Perform the following checks:
+ *
+ * 1 - Node must either be vacant, or have settlement owned by the
+ * specified player on it.
+ * 2 - If vacant, node must be adjacent to a road owned by the
+ * specified player
+ * 3 - If vacant, node must be adjacent to a land hex.
+ * 4 - If vacent, node must not be within one node of another
+ * building.
+ */
+gboolean can_city_be_built(const Node * node, gint owner)
+{
+ g_return_val_if_fail(node != NULL, FALSE);
+ if (can_settlement_be_upgraded(node, owner))
+ return TRUE;
+
+ return node->owner < 0 && (node_has_road_owned_by(node, owner)
+ || node_has_ship_owned_by(node, owner)
+ || node_has_bridge_owned_by(node,
+ owner))
+ && is_node_on_land(node)
+ && is_node_spacing_ok(node);
+}
+
+/* Node cursor check function.
+ *
+ * Determine whether or not a city wall can be built by
+ * the specified player.
+ */
+gboolean can_city_wall_be_built(const Node * node, gint owner)
+{
+ g_return_val_if_fail(node != NULL, FALSE);
+ return node->owner == owner && node->type == BUILD_CITY &&
+ !node->city_wall;
+}
+
+/* Hex cursor check function.
+ *
+ * Determine whether or not the robber be moved to the specified hex.
+ *
+ * Can only move the robber to hex which produces resources (roll >
+ * 0). We cannot move the robber to the same hex it is already on.
+ * Also check if pirate can be moved.
+ */
+gboolean can_robber_or_pirate_be_moved(const Hex * hex)
+{
+ g_return_val_if_fail(hex != NULL, FALSE);
+ if (hex->terrain == SEA_TERRAIN)
+ return (hex->map->has_pirate)
+ && (hex != hex->map->pirate_hex);
+ else
+ return (hex->roll > 0) && (!hex->robber);
+}
+
+/* Iterator function for map_can_place_road() query
+ */
+static gboolean can_place_road_check(G_GNUC_UNUSED Map * map, Hex * hex,
+ gint * owner)
+{
+ gint idx;
+
+ g_return_val_if_fail(hex != NULL, FALSE);
+ g_return_val_if_fail(owner != NULL, FALSE);
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); idx++)
+ if (can_road_be_built(hex->edges[idx], *owner))
+ return TRUE;
+ return FALSE;
+}
+
+/* Iterator function for map_can_place_ship() query
+ */
+static gboolean can_place_ship_check(G_GNUC_UNUSED Map * map, Hex * hex,
+ gint * owner)
+{
+ gint idx;
+
+ g_return_val_if_fail(hex != NULL, FALSE);
+ g_return_val_if_fail(owner != NULL, FALSE);
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); idx++)
+ if (can_ship_be_built(hex->edges[idx], *owner))
+ return TRUE;
+ return FALSE;
+}
+
+/* Iterator function for map_can_place_bridge() query
+ */
+static gboolean can_place_bridge_check(G_GNUC_UNUSED Map * map, Hex * hex,
+ gint * owner)
+{
+ gint idx;
+
+ g_return_val_if_fail(hex != NULL, FALSE);
+ g_return_val_if_fail(owner != NULL, FALSE);
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); idx++)
+ if (can_bridge_be_built(hex->edges[idx], *owner))
+ return TRUE;
+ return FALSE;
+}
+
+/* Query.
+ *
+ * Determine if there are any edges on the map where a player can
+ * place a road.
+ */
+gboolean map_can_place_road(Map * map, gint owner)
+{
+ g_return_val_if_fail(map != NULL, FALSE);
+ return map_traverse(map, (HexFunc) can_place_road_check, &owner);
+}
+
+/* Query.
+ *
+ * Determine if there are any edges on the map where a player can
+ * place a ship.
+ */
+gboolean map_can_place_ship(Map * map, gint owner)
+{
+ g_return_val_if_fail(map != NULL, FALSE);
+ return map_traverse(map, (HexFunc) can_place_ship_check, &owner);
+}
+
+/* Query.
+ *
+ * Determine if there are any edges on the map where a player can
+ * place a bridge.
+ */
+gboolean map_can_place_bridge(Map * map, gint owner)
+{
+ g_return_val_if_fail(map != NULL, FALSE);
+ return map_traverse(map, (HexFunc) can_place_bridge_check, &owner);
+}
+
+/* Iterator function for map_can_place_settlement() query
+ */
+static gboolean can_place_settlement_check(G_GNUC_UNUSED Map * map,
+ Hex * hex, gint * owner)
+{
+ gint idx;
+
+ g_return_val_if_fail(hex != NULL, FALSE);
+ g_return_val_if_fail(owner != NULL, FALSE);
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); idx++)
+ if (can_settlement_be_built(hex->nodes[idx], *owner))
+ return TRUE;
+ return FALSE;
+}
+
+/* Query.
+ *
+ * Determine if there are any nodes on the map where a player can
+ * place a settlement
+ */
+gboolean map_can_place_settlement(Map * map, gint owner)
+{
+ g_return_val_if_fail(map != NULL, FALSE);
+ return map_traverse(map, (HexFunc) can_place_settlement_check,
+ &owner);
+}
+
+/* Iterator function for map_can_upgrade_settlement() query
+ */
+static gboolean can_upgrade_settlement_check(G_GNUC_UNUSED Map * map,
+ Hex * hex, gint * owner)
+{
+ gint idx;
+
+ g_return_val_if_fail(hex != NULL, FALSE);
+ g_return_val_if_fail(owner != NULL, FALSE);
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); idx++)
+ if (can_settlement_be_upgraded(hex->nodes[idx], *owner))
+ return TRUE;
+ return FALSE;
+}
+
+/* Query.
+ *
+ * Determine if there are any nodes on the map where a player can
+ * upgrade a settlement
+ */
+gboolean map_can_upgrade_settlement(Map * map, gint owner)
+{
+ g_return_val_if_fail(map != NULL, FALSE);
+ return map_traverse(map, (HexFunc) can_upgrade_settlement_check,
+ &owner);
+}
+
+/* Iterator function for map_can_place_city_wall() query
+ */
+static gboolean can_place_city_wall_check(G_GNUC_UNUSED Map * map,
+ Hex * hex, gint * owner)
+{
+ gint idx;
+
+ g_return_val_if_fail(hex != NULL, FALSE);
+ g_return_val_if_fail(owner != NULL, FALSE);
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); idx++)
+ if (can_city_wall_be_built(hex->nodes[idx], *owner))
+ return TRUE;
+ return FALSE;
+}
+
+/* Query.
+ *
+ * Determine if there are any nodes on the map where a player can
+ * place a settlement
+ */
+gboolean map_can_place_city_wall(Map * map, gint owner)
+{
+ g_return_val_if_fail(map != NULL, FALSE);
+ return map_traverse(map, (HexFunc) can_place_city_wall_check,
+ &owner);
+}
+
+/* Ignoring road connectivity, decide whether or not a settlement/city
+ * can be placed at the specified location.
+ */
+gboolean map_building_spacing_ok(Map * map, gint owner,
+ BuildType type, gint x, gint y, gint pos)
+{
+ Node *node;
+ g_return_val_if_fail(map != NULL, FALSE);
+ node = map_node(map, x, y, pos);
+ if (node == NULL)
+ return FALSE;
+
+ if (node->type == BUILD_NONE)
+ /* Node is vacant. Make sure that all adjacent nodes
+ * are also vacant
+ */
+ return is_node_spacing_ok(node);
+
+ /* Node is not vacant, make sure I am the current owner, and I
+ * am trying to upgrade a settlement to a city.
+ */
+ return node->owner == owner
+ && node->type == BUILD_SETTLEMENT && type == BUILD_CITY;
+}
+
+/* Ignoring building spacing, check if the building connects to a road.
+ */
+gboolean map_building_connect_ok(Map * map, gint owner,
+ G_GNUC_UNUSED BuildType type, gint x,
+ gint y, gint pos)
+{
+ Node *node;
+ g_return_val_if_fail(map != NULL, FALSE);
+ node = map_node(map, x, y, pos);
+ if (node == NULL)
+ return FALSE;
+
+ return node_has_road_owned_by(node, owner)
+ || node_has_ship_owned_by(node, owner)
+ || node_has_bridge_owned_by(node, owner);
+}
+
+gboolean map_building_vacant(Map * map, BuildType type,
+ gint x, gint y, gint pos)
+{
+ Node *node;
+ g_return_val_if_fail(map != NULL, FALSE);
+ node = map_node(map, x, y, pos);
+ if (node == NULL)
+ return FALSE;
+
+ switch (type) {
+ case BUILD_NONE:
+ case BUILD_SETTLEMENT:
+ return node->type == BUILD_NONE;
+ case BUILD_CITY:
+ return node->type == BUILD_NONE
+ || node->type == BUILD_SETTLEMENT;
+ case BUILD_ROAD:
+ case BUILD_SHIP:
+ case BUILD_MOVE_SHIP:
+ case BUILD_BRIDGE:
+ g_error("map_building_vacant() called with edge");
+ return FALSE;
+ case BUILD_CITY_WALL:
+ g_error("map_building_vacant() called with city wall");
+ return FALSE;
+ }
+ return FALSE;
+}
+
+gboolean map_road_vacant(Map * map, gint x, gint y, gint pos)
+{
+ Edge *edge;
+ g_return_val_if_fail(map != NULL, FALSE);
+ edge = map_edge(map, x, y, pos);
+
+ return edge != NULL && edge->owner < 0;
+}
+
+gboolean map_ship_vacant(Map * map, gint x, gint y, gint pos)
+{
+ Edge *edge;
+ g_return_val_if_fail(map != NULL, FALSE);
+ edge = map_edge(map, x, y, pos);
+
+ return edge != NULL && edge->owner < 0;
+}
+
+gboolean map_bridge_vacant(Map * map, gint x, gint y, gint pos)
+{
+ Edge *edge;
+ g_return_val_if_fail(map != NULL, FALSE);
+ edge = map_edge(map, x, y, pos);
+
+ return edge != NULL && edge->owner < 0;
+}
+
+/* Ignoring whether or not a road already exists at this point, check
+ * that it has the right connectivity.
+ */
+gboolean map_road_connect_ok(Map * map, gint owner, gint x, gint y,
+ gint pos)
+{
+ Edge *edge;
+ g_return_val_if_fail(map != NULL, FALSE);
+ edge = map_edge(map, x, y, pos);
+ if (edge == NULL)
+ return FALSE;
+
+ return is_road_valid(edge, owner);
+}
+
+/* Ignoring whether or not a ship already exists at this point, check
+ * that it has the right connectivity.
+ */
+gboolean map_ship_connect_ok(Map * map, gint owner, gint x, gint y,
+ gint pos)
+{
+ Edge *edge;
+ g_return_val_if_fail(map != NULL, FALSE);
+ edge = map_edge(map, x, y, pos);
+ if (edge == NULL)
+ return FALSE;
+
+ return is_ship_valid(edge, owner);
+}
+
+/* Ignoring whether or not a bridge already exists at this point, check
+ * that it has the right connectivity.
+ */
+gboolean map_bridge_connect_ok(Map * map, gint owner, gint x, gint y,
+ gint pos)
+{
+ Edge *edge;
+ g_return_val_if_fail(map != NULL, FALSE);
+ edge = map_edge(map, x, y, pos);
+ if (edge == NULL)
+ return FALSE;
+
+ return is_bridge_valid(edge, owner);
+}
+
+static BuildType bridge_as_road(BuildType type)
+{
+ if (type == BUILD_BRIDGE)
+ return BUILD_ROAD;
+ else
+ return type;
+}
+
+/* calculate the longest road */
+static gint find_longest_road_recursive(Edge * edge)
+{
+ gint len = 0;
+ gint nodeidx, edgeidx;
+ g_return_val_if_fail(edge != NULL, 0);
+ edge->visited = TRUE;
+ /* check all nodes to see which one make the longer road. */
+ for (nodeidx = 0; nodeidx < G_N_ELEMENTS(edge->nodes); nodeidx++) {
+ Node *node = edge->nodes[nodeidx];
+ /* don't go back to where we came from */
+ if (node->visited)
+ continue;
+ /* don't continue counting if someone else's building is on
+ * the node. */
+ if (node->type != BUILD_NONE && node->owner != edge->owner)
+ continue;
+ /* don't let other go back here */
+ node->visited = TRUE;
+ /* try all edges */
+ for (edgeidx = 0; edgeidx < G_N_ELEMENTS(node->edges);
+ edgeidx++) {
+ Edge *here = node->edges[edgeidx];
+ if (here && !here->visited
+ && here->owner == edge->owner) {
+ /* don't allow ships to extend roads, except
+ * if there is a construction in between */
+ /* bridges are treated as roads */
+ if (node->type != BUILD_NONE ||
+ bridge_as_road(here->type) ==
+ bridge_as_road(edge->type)) {
+ gint thislen =
+ find_longest_road_recursive
+ (here);
+ /* take the maximum of all paths */
+ if (thislen > len)
+ len = thislen;
+ }
+ }
+ }
+ /* Allow other roads to use this node again. */
+ node->visited = FALSE;
+ }
+ edge->visited = FALSE;
+ return len + 1;
+}
+
+static gboolean find_longest_road(G_GNUC_UNUSED Map * map, Hex * hex,
+ gint * lengths)
+{
+ gint idx;
+ g_return_val_if_fail(hex != NULL, FALSE);
+ g_return_val_if_fail(lengths != NULL, FALSE);
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); idx++) {
+ Edge *edge = hex->edges[idx];
+ gint len;
+ /* skip unowned edges, and edges that will be handled by
+ * other hexes */
+ if (edge->owner < 0 || edge->x != hex->x
+ || edge->y != hex->y)
+ continue;
+ len = find_longest_road_recursive(edge);
+ if (len > lengths[edge->owner])
+ lengths[edge->owner] = len;
+ }
+ return FALSE;
+}
+
+/* Zero the visited attribute for all edges and nodes.
+ */
+static gboolean zero_visited(G_GNUC_UNUSED Map * map, Hex * hex,
+ G_GNUC_UNUSED void *closure)
+{
+ gint idx;
+
+ g_return_val_if_fail(hex != NULL, FALSE);
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); idx++) {
+ Edge *edge = hex->edges[idx];
+ edge->visited = FALSE;
+ }
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); idx++) {
+ Node *node = hex->nodes[idx];
+ node->visited = FALSE;
+ }
+
+ return FALSE;
+}
+
+/* Finding the longest road:
+ * 1 - set the visited attribute of all edges and nodes to FALSE
+ * 2 - for every edge, find the longest road using this one as a tail
+ */
+void map_longest_road(Map * map, gint * lengths, gint num_players)
+{
+ g_return_if_fail(map != NULL);
+ g_return_if_fail(lengths != NULL);
+
+ map_traverse(map, (HexFunc) zero_visited, NULL);
+ memset(lengths, 0, num_players * sizeof(*lengths));
+ map_traverse(map, (HexFunc) find_longest_road, lengths);
+}
+
+static gboolean map_island_recursive(Map * map, Node * node, gint owner)
+{
+ gint idx;
+ gboolean discovered;
+
+ g_return_val_if_fail(map != NULL, FALSE);
+
+ if (node == NULL)
+ return FALSE;
+ if (node->owner == owner)
+ return TRUE; /* Already discovered */
+ if (node->visited)
+ return FALSE; /* Not discovered */
+ node->visited = TRUE;
+
+ discovered = FALSE;
+ for (idx = 0; idx < G_N_ELEMENTS(node->edges) && !discovered;
+ idx++) {
+ gint num_sea;
+ gint idx2;
+ Edge *edge = node->edges[idx];
+ if (edge == NULL)
+ continue;
+ if (edge->visited)
+ continue;
+ edge->visited = TRUE;
+
+ /* If the edge points into the sea, or along the border,
+ * don't follow it */
+ num_sea = 0;
+ for (idx2 = 0; idx2 < G_N_ELEMENTS(edge->hexes); idx2++) {
+ const Hex *hex = edge->hexes[idx2];
+ if (hex == NULL) {
+ num_sea++;
+ continue;
+ }
+ if (hex->terrain == SEA_TERRAIN)
+ num_sea++;
+ }
+ if (num_sea == G_N_ELEMENTS(edge->hexes))
+ continue;
+
+ /* Follow the other node */
+ for (idx2 = 0;
+ idx2 < G_N_ELEMENTS(edge->nodes) && !discovered;
+ ++idx2) {
+ Node *node2 = edge->nodes[idx2];
+ if (node == node2)
+ continue;
+ discovered |=
+ map_island_recursive(map, node2, owner);
+ }
+ }
+ return discovered;
+}
+
+/* Has anything be built by this player on this island */
+gboolean map_is_island_discovered(Map * map, Node * node, gint owner)
+{
+ g_return_val_if_fail(map != NULL, FALSE);
+ g_return_val_if_fail(node != NULL, FALSE);
+ map_traverse(map, (HexFunc) zero_visited, NULL);
+ return map_island_recursive(map, node, owner);
+}
+
+/* Determine the maritime trading capabilities for the specified player
+ */
+static gboolean find_maritime(G_GNUC_UNUSED Map * map, Hex * hex,
+ MaritimeInfo * info)
+{
+ g_return_val_if_fail(hex != NULL, FALSE);
+ g_return_val_if_fail(info != NULL, FALSE);
+
+ if (hex->terrain != SEA_TERRAIN || hex->resource == NO_RESOURCE)
+ return FALSE;
+
+ if (hex->nodes[hex->facing]->owner != info->owner
+ && hex->nodes[(hex->facing + 5) % 6]->owner != info->owner)
+ return FALSE;
+
+ if (hex->resource == ANY_RESOURCE)
+ info->any_resource = TRUE;
+ else
+ info->specific_resource[hex->resource] = TRUE;
+
+ return FALSE;
+}
+
+/* Determine the maritime trading capacity of the specified player
+ */
+void map_maritime_info(Map * map, MaritimeInfo * info, gint owner)
+{
+ g_return_if_fail(map != NULL);
+ g_return_if_fail(info != NULL);
+ memset(info, 0, sizeof(*info));
+ info->owner = owner;
+ map_traverse(map, (HexFunc) find_maritime, info);
+}
+
+typedef struct {
+ gboolean visited[MAP_SIZE][MAP_SIZE];
+ guint count;
+ guint recursion_level;
+} IslandCount;
+
+static gboolean count_islands(Map * map, Hex * hex, gpointer info)
+{
+ IslandCount *count = info;
+ HexDirection direction;
+
+ g_return_val_if_fail(map != NULL, FALSE);
+
+ if (hex == NULL)
+ return FALSE;
+
+ if (count->visited[hex->y][hex->x])
+ return FALSE;
+
+ if (hex->terrain == SEA_TERRAIN)
+ return FALSE;
+
+ count->visited[hex->y][hex->x] = TRUE;
+ count->recursion_level++;
+ for (direction = 0; direction < 6; direction++) {
+ count_islands(map, hex_in_direction(map, hex, direction),
+ count);
+ }
+ count->recursion_level--;
+ if (count->recursion_level == 0)
+ count->count++;
+ return FALSE;
+}
+
+guint map_count_islands(Map * map)
+{
+ IslandCount island_count;
+
+ g_return_val_if_fail(map != NULL, 0u);
+
+ memset(island_count.visited, 0, sizeof(island_count.visited));
+ island_count.count = 0;
+ island_count.recursion_level = 0;
+
+ map_traverse(map, count_islands, &island_count);
+
+ return island_count.count;
+}
Added: trunk/common/network.c
===================================================================
--- trunk/common/network.c (rev 0)
+++ trunk/common/network.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,894 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2005-2007 Roland Clobus <rclobus at bigfoot.com>
+ * Copyright (C) 2005 Keishi Suenaga
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <ctype.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#include <errno.h>
+#include <string.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#ifndef HAVE_GETADDRINFO_ET_AL
+#include <stdlib.h> /* For atoi */
+#endif /* ndef HAVE_GETADDRINFO_ET_AL */
+
+#include <time.h>
+#include "config.h"
+#include "driver.h"
+#include "game.h"
+#include "map.h"
+#include "network.h"
+#include "log.h"
+
+typedef union {
+ struct sockaddr sa;
+ struct sockaddr_in in;
+#ifdef HAVE_GETADDRINFO_ET_AL
+ struct sockaddr_in6 in6;
+#endif /* HAVE_GETADDRINFO_ET_AL */
+} sockaddr_t;
+
+static gboolean debug_enabled = FALSE;
+
+/* Number of seconds between pings
+ * (in the absence of other network activity). */
+static const int PING_PERIOD = 30;
+
+void set_enable_debug(gboolean enabled)
+{
+ debug_enabled = enabled;
+}
+
+void debug(const gchar * fmt, ...)
+{
+ va_list ap;
+ gchar *buff;
+ gint idx;
+ time_t t;
+ struct tm *alpha;
+
+ if (!debug_enabled)
+ return;
+
+ va_start(ap, fmt);
+ buff = g_strdup_vprintf(fmt, ap);
+ va_end(ap);
+
+ t = time(NULL);
+ alpha = localtime(&t);
+
+ g_print("%02d:%02d:%02d ", alpha->tm_hour,
+ alpha->tm_min, alpha->tm_sec);
+
+ for (idx = 0; buff[idx] != '\0'; idx++) {
+ if (isprint(buff[idx]))
+ g_print("%c", buff[idx]);
+ else
+ switch (buff[idx]) {
+ case '\n':
+ g_print("\\n");
+ break;
+ case '\r':
+ g_print("\\r");
+ break;
+ case '\t':
+ g_print("\\t");
+ break;
+ default:
+ g_print("\\x%02x", (buff[idx] & 0xff));
+ break;
+ }
+ }
+ g_print("\n");
+}
+
+static void read_ready(Session * ses);
+static void write_ready(Session * ses);
+
+static void listen_read(Session * ses, gboolean monitor)
+{
+ if (monitor && ses->read_tag == 0)
+ ses->read_tag =
+ driver->input_add_read(ses->fd, (InputFunc) read_ready,
+ ses);
+ if (!monitor && ses->read_tag != 0) {
+ driver->input_remove(ses->read_tag);
+ ses->read_tag = 0;
+ }
+
+}
+
+static void listen_write(Session * ses, gboolean monitor)
+{
+ if (monitor && ses->write_tag == 0)
+ ses->write_tag =
+ driver->input_add_write(ses->fd,
+ (InputFunc) write_ready, ses);
+ if (!monitor && ses->write_tag != 0) {
+ driver->input_remove(ses->write_tag);
+ ses->write_tag = 0;
+ }
+}
+
+static void notify(Session * ses, NetEvent event, gchar * line)
+{
+ if (ses->notify_func != NULL)
+ ses->notify_func(event, ses->user_data, line);
+}
+
+static gboolean net_would_block(void)
+{
+#ifdef G_OS_WIN32
+ return WSAGetLastError() == WSAEWOULDBLOCK;
+#else /* G_OS_WIN32 */
+ return errno == EAGAIN;
+#endif /* G_OS_WIN32 */
+}
+
+static gboolean net_write_error(void)
+{
+#ifdef G_OS_WIN32
+ int lerror = WSAGetLastError();
+ return (lerror != WSAECONNRESET
+ && lerror != WSAECONNABORTED && lerror != WSAESHUTDOWN);
+#else /* G_OS_WIN32 */
+ return errno != EPIPE;
+#endif /* G_OS_WIN32 */
+}
+
+/* Returns the message for error# number */
+static const gchar *net_errormsg_nr(gint number)
+{
+ return g_strerror(number);
+}
+
+/* Returns the message for the current error */
+static const gchar *net_errormsg(void)
+{
+ return net_errormsg_nr(errno);
+}
+
+gboolean net_close(Session * ses)
+{
+ if (ses->timer_id != 0) {
+ g_source_remove(ses->timer_id);
+ ses->timer_id = 0;
+ }
+
+ if (ses->fd >= 0) {
+ listen_read(ses, FALSE);
+ listen_write(ses, FALSE);
+ net_closesocket(ses->fd);
+ ses->fd = -1;
+
+ while (ses->write_queue != NULL) {
+ char *data = ses->write_queue->data;
+
+ ses->write_queue
+ = g_list_remove(ses->write_queue, data);
+ g_free(data);
+ }
+ }
+ return !ses->entered;
+}
+
+void net_close_when_flushed(Session * ses)
+{
+ ses->waiting_for_close = TRUE;
+ if (ses->write_queue != NULL)
+ return;
+
+ if (net_close(ses))
+ notify(ses, NET_CLOSE, NULL);
+}
+
+void net_wait_for_close(Session * ses)
+{
+ ses->waiting_for_close = TRUE;
+}
+
+static void close_and_callback(Session * ses)
+{
+ if (net_close(ses))
+ notify(ses, NET_CLOSE, NULL);
+}
+
+static gboolean ping_function(gpointer s)
+{
+ Session *ses = (Session *) s;
+ double interval = difftime(time(NULL), ses->last_response);
+ /* Ask for activity every PING_PERIOD seconds, but don't ask if there
+ * was activity anyway. */
+ if (interval >= 2 * PING_PERIOD) {
+ /* There was no response to the ping in time. The connection
+ * should be considered dead. */
+ log_message(MSG_ERROR,
+ "No activity and no response to ping. Closing connection\n");
+ debug("(%d) --> %s", ses->fd, "no response");
+ close_and_callback(ses);
+ } else if (interval >= PING_PERIOD) {
+ /* There was no activity.
+ * Send a ping (but don't update activity time). */
+ net_write(ses, "hello\n");
+ ses->timer_id =
+ g_timeout_add(PING_PERIOD * 1000, ping_function, s);
+ } else {
+ /* Everything is fine. Reschedule this check. */
+ ses->timer_id =
+ g_timeout_add((PING_PERIOD - interval) * 1000,
+ ping_function, s);
+ }
+ /* Return FALSE to not reschedule this timeout. If it needed to be
+ * rescheduled, it has been done explicitly above (with a different
+ * timeout). */
+ return FALSE;
+}
+
+static void write_ready(Session * ses)
+{
+ if (!ses || ses->fd < 0)
+ return;
+ if (ses->connect_in_progress) {
+ /* We were waiting to connect to server
+ */
+ int error;
+ socklen_t error_len;
+
+ error_len = sizeof(error);
+ if (getsockopt(ses->fd, SOL_SOCKET, SO_ERROR,
+ (GETSOCKOPT_ARG3) & error,
+ &error_len) < 0) {
+ notify(ses, NET_CONNECT_FAIL, NULL);
+ log_message(MSG_ERROR,
+ _
+ ("Error checking connect status: %s\n"),
+ net_errormsg());
+ net_close(ses);
+ } else if (error != 0) {
+ notify(ses, NET_CONNECT_FAIL, NULL);
+ log_message(MSG_ERROR,
+ _
+ ("Error connecting to host '%s': %s\n"),
+ ses->host, net_errormsg_nr(error));
+ net_close(ses);
+ } else {
+ ses->connect_in_progress = FALSE;
+ notify(ses, NET_CONNECT, NULL);
+ listen_write(ses, FALSE);
+ listen_read(ses, TRUE);
+ }
+ return;
+ }
+
+ while (ses->write_queue != NULL) {
+ int num;
+ char *data = ses->write_queue->data;
+ int len = strlen(data);
+
+ num = send(ses->fd, data, len, 0);
+ debug("write_ready: write(%d, \"%.*s\", %d) = %d",
+ ses->fd, len, data, len, num);
+ if (num < 0) {
+ if (net_would_block())
+ break;
+ if (net_write_error())
+ log_message(MSG_ERROR,
+ _
+ ("Error writing socket: %s\n"),
+ net_errormsg());
+ close_and_callback(ses);
+ return;
+ } else if (num == len) {
+ ses->write_queue
+ = g_list_remove(ses->write_queue, data);
+ g_free(data);
+ } else {
+ memmove(data, data + num, len - num + 1);
+ break;
+ }
+ }
+
+ /* Stop spinning when nothing to do.
+ */
+ if (ses->write_queue == NULL) {
+ if (ses->waiting_for_close)
+ close_and_callback(ses);
+ else
+ listen_write(ses, FALSE);
+ }
+}
+
+void net_write(Session * ses, const gchar * data)
+{
+ if (!ses || ses->fd < 0)
+ return;
+ if (ses->write_queue != NULL || !net_connected(ses)) {
+ /* reassign the pointer, because the glib docs say it may
+ * change and because if we're in the process of connecting the
+ * pointer may currently be null. */
+ ses->write_queue =
+ g_list_append(ses->write_queue, g_strdup(data));
+ } else {
+ int len;
+ int num;
+
+ len = strlen(data);
+ num = send(ses->fd, data, len, 0);
+ if (num > 0) {
+ if (strcmp(data, "yes\n")
+ && strcmp(data, "hello\n"))
+ debug("(%d) --> %s", ses->fd, data);
+ } else if (!net_would_block())
+ debug("(%d) --- Error writing to socket.",
+ ses->fd);
+ if (num < 0) {
+ if (!net_would_block()) {
+ log_message(MSG_ERROR,
+ _
+ ("Error writing to socket: %s\n"),
+ net_errormsg());
+ close_and_callback(ses);
+ return;
+ }
+ num = 0;
+ }
+ if (num != len) {
+ ses->write_queue
+ = g_list_append(NULL, g_strdup(data + num));
+ listen_write(ses, TRUE);
+ }
+ }
+}
+
+void net_printf(Session * ses, const gchar * fmt, ...)
+{
+ char *buff;
+ va_list ap;
+
+ va_start(ap, fmt);
+ buff = g_strdup_vprintf(fmt, ap);
+ va_end(ap);
+
+ net_write(ses, buff);
+ g_free(buff);
+}
+
+static int find_line(char *buff, int len)
+{
+ int idx;
+
+ for (idx = 0; idx < len; idx++)
+ if (buff[idx] == '\n')
+ return idx;
+ return -1;
+}
+
+static void read_ready(Session * ses)
+{
+ int num;
+ int offset;
+
+ /* There is data from this connection: record the time. */
+ ses->last_response = time(NULL);
+
+ if (ses->read_len == sizeof(ses->read_buff)) {
+ /* We are in trouble now - the application has not
+ * been processing the data we have been
+ * reading. Assume something has gone wrong and
+ * disconnect
+ */
+ log_message(MSG_ERROR,
+ _("Read buffer overflow - disconnecting\n"));
+ close_and_callback(ses);
+ return;
+ }
+
+ num = recv(ses->fd, ses->read_buff + ses->read_len,
+ sizeof(ses->read_buff) - ses->read_len, 0);
+ if (num < 0) {
+ if (net_would_block())
+ return;
+ log_message(MSG_ERROR, _("Error reading socket: %s\n"),
+ net_errormsg());
+ close_and_callback(ses);
+ return;
+ }
+
+ if (num == 0) {
+ close_and_callback(ses);
+ return;
+ }
+
+ ses->read_len += num;
+
+ if (ses->entered)
+ return;
+ ses->entered = TRUE;
+
+ offset = 0;
+ while (ses->fd >= 0 && offset < ses->read_len) {
+ char *line = ses->read_buff + offset;
+ int len = find_line(line, ses->read_len - offset);
+
+ if (len < 0)
+ break;
+ line[len] = '\0';
+ offset += len + 1;
+
+ if (!strcmp(line, "hello")) {
+ net_write(ses, "yes\n");
+ continue;
+ }
+ if (!strcmp(line, "yes")) {
+ continue; /* Don't notify the program */
+ }
+
+ debug("(%d) <-- %s", ses->fd, line);
+
+ notify(ses, NET_READ, line);
+ }
+
+ if (offset < ses->read_len) {
+ /* Did not process all data in buffer - discard
+ * processed data and copy remaining data to beginning
+ * of buffer until next time
+ */
+ memmove(ses->read_buff, ses->read_buff + offset,
+ ses->read_len - offset);
+ ses->read_len -= offset;
+ } else
+ /* Processed all data in buffer, discard it
+ */
+ ses->read_len = 0;
+
+ ses->entered = FALSE;
+ if (ses->fd < 0) {
+ close_and_callback(ses);
+ }
+}
+
+Session *net_new(NetNotifyFunc notify_func, void *user_data)
+{
+ Session *ses;
+
+ ses = g_malloc0(sizeof(*ses));
+ ses->notify_func = notify_func;
+ ses->user_data = user_data;
+ ses->fd = -1;
+
+ return ses;
+}
+
+void net_use_fd(Session * ses, int fd, gboolean do_ping)
+{
+ ses->fd = fd;
+ if (do_ping) {
+ ses->last_response = time(NULL);
+ ses->timer_id =
+ g_timeout_add(PING_PERIOD * 1000, ping_function, ses);
+ }
+ listen_read(ses, TRUE);
+}
+
+gboolean net_connected(Session * ses)
+{
+ return ses->fd >= 0 && !ses->connect_in_progress;
+}
+
+/* Set the socket to non-blocking
+ * @param fd The file descriptor of the socket
+ * @return TRUE if an error occurred
+ */
+static gboolean net_set_socket_non_blocking(int fd)
+{
+#ifdef HAVE_FCNTL
+ return fcntl(fd, F_SETFL, O_NDELAY) < 0;
+#else /* HAVE_FCNTL */
+#ifdef HAVE_WS2TCPIP_H
+ unsigned long nonblocking = 1;
+ return ioctlsocket(fd, FIONBIO, &nonblocking) != 0;
+#else /* HAVE_FCNTL && HAVE_WS2TCPIP_H */
+#error "Don't know how to set a socket non-blocking"
+#error "Please contact the mailing list,"
+#error "and send the file config.h"
+ return TRUE;
+#endif
+#endif
+}
+
+/* Is the connection in progress?
+ * @return TRUE The connection is in progress
+ */
+static gboolean net_is_connection_in_progress(void)
+{
+#ifdef G_OS_WIN32
+ return WSAGetLastError() == WSAEWOULDBLOCK;
+#else
+ return errno == EINPROGRESS;
+#endif
+}
+
+gboolean net_connect(Session * ses, const gchar * host, const gchar * port)
+{
+#ifdef HAVE_GETADDRINFO_ET_AL
+ int err;
+ struct addrinfo hints, *ai, *aip;
+#else
+ gint iii;
+ struct hostent *he;
+ struct sockaddr_in addr;
+#endif /* HAVE_GETADDRINFO_ET_AL */
+
+ net_close(ses);
+ if (ses->host != NULL)
+ g_free(ses->host);
+ if (ses->port != NULL)
+ g_free(ses->port);
+ ses->host = g_strdup(host);
+ ses->port = g_strdup(port);
+
+#ifdef HAVE_GETADDRINFO_ET_AL
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+
+ if ((err = getaddrinfo(host, port, &hints, &ai))) {
+ log_message(MSG_ERROR,
+ _("Cannot resolve %s port %s: %s\n"), host,
+ port, gai_strerror(err));
+ return FALSE;
+ }
+ if (!ai) {
+ log_message(MSG_ERROR,
+ _
+ ("Cannot resolve %s port %s: host not found\n"),
+ host, port);
+ return FALSE;
+ }
+#endif /* HAVE_GETADDRINFO_ET_AL */
+
+#ifdef HAVE_GETADDRINFO_ET_AL
+ for (aip = ai; aip; aip = aip->ai_next) {
+ ses->fd = socket(aip->ai_family, SOCK_STREAM, 0);
+#else /* HAVE_GETADDRINFO_ET_AL */
+ for (iii = 0; iii < 1; ++iii) { /* Loop only once */
+ ses->fd = socket(AF_INET, SOCK_STREAM, 0);
+#endif /* HAVE_GETADDRINFO_ET_AL */
+ if (ses->fd < 0) {
+ log_message(MSG_ERROR,
+ _("Error creating socket: %s\n"),
+ net_errormsg());
+ continue;
+ }
+#ifdef HAVE_FCNTL
+ if (fcntl(ses->fd, F_SETFD, 1) < 0) {
+ log_message(MSG_ERROR,
+ _
+ ("Error setting socket close-on-exec: %s\n"),
+ net_errormsg());
+ net_closesocket(ses->fd);
+ ses->fd = -1;
+ continue;
+ }
+#endif
+ if (net_set_socket_non_blocking(ses->fd)) {
+ log_message(MSG_ERROR,
+ _
+ ("Error setting socket non-blocking: %s\n"),
+ net_errormsg());
+ net_closesocket(ses->fd);
+ ses->fd = -1;
+ continue;
+ }
+#ifdef HAVE_GETADDRINFO_ET_AL
+ if (connect(ses->fd, aip->ai_addr, aip->ai_addrlen) < 0) {
+#else /* HAVE_GETADDRINFO_ET_AL */
+ he = gethostbyname(host);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(atoi(port));
+ addr.sin_addr = *((struct in_addr *) he->h_addr);
+ memset(&addr.sin_zero, 0, 8);
+ if (connect
+ (ses->fd, (struct sockaddr *) &addr,
+ sizeof(struct sockaddr)) < 0) {
+#endif /* HAVE_GETADDRINFO_ET_AL */
+ if (net_is_connection_in_progress()) {
+ ses->connect_in_progress = TRUE;
+ listen_write(ses, TRUE);
+ break;
+ } else {
+ log_message(MSG_ERROR,
+ _
+ ("Error connecting to %s: %s\n"),
+ host, net_errormsg());
+ net_closesocket(ses->fd);
+ ses->fd = -1;
+ continue;
+ }
+ } else
+ listen_read(ses, TRUE);
+ }
+
+#ifdef HAVE_GETADDRINFO_ET_AL
+ freeaddrinfo(ai);
+#endif /* HAVE_GETADDRINFO_ET_AL */
+
+ if (ses->fd >= 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/* Free and NULL-ify the session *ses */
+void net_free(Session ** ses)
+{
+ /* If the sessions is still in use, do not free it */
+ if (!net_close(*ses)) {
+ return;
+ }
+ if ((*ses)->host != NULL)
+ g_free((*ses)->host);
+ if ((*ses)->port != NULL)
+ g_free((*ses)->port);
+ g_free(*ses);
+ *ses = NULL;
+}
+
+gchar *get_my_hostname(void)
+{
+/* The following code fragment is taken from glib-2.0 v2.8 */
+ gchar hostname[100];
+#ifndef G_OS_WIN32
+ gboolean hostname_fail =
+ (gethostname(hostname, sizeof(hostname)) == -1);
+#else
+ DWORD size = sizeof(hostname);
+ gboolean hostname_fail = (!GetComputerName(hostname, &size));
+#endif
+ return g_strdup(hostname_fail ? "localhost" : hostname);
+/* End of copy from glib-2.0 v2.8 */
+}
+
+gchar *get_meta_server_name(gboolean use_default)
+{
+ gchar *temp;
+
+ temp = g_strdup(g_getenv("PIONEERS_META_SERVER"));
+ if (!temp)
+ temp = g_strdup(g_getenv("GNOCATAN_META_SERVER"));
+ if (!temp) {
+ if (use_default)
+ temp = g_strdup(PIONEERS_DEFAULT_META_SERVER);
+ else {
+ temp = get_my_hostname();
+ }
+ }
+ return temp;
+}
+
+const gchar *get_pioneers_dir(void)
+{
+ const gchar *pioneers_dir = g_getenv("PIONEERS_DIR");
+ if (!pioneers_dir)
+ pioneers_dir = g_getenv("GNOCATAN_DIR");
+ if (!pioneers_dir)
+ pioneers_dir = PIONEERS_DIR_DEFAULT;
+ return pioneers_dir;
+}
+
+int net_open_listening_socket(const gchar * port, gchar ** error_message)
+{
+#ifdef HAVE_GETADDRINFO_ET_AL
+ int err;
+ struct addrinfo hints, *ai, *aip;
+ int yes;
+ gint fd = -1;
+
+ memset(&hints, 0, sizeof(hints));
+
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_flags = AI_PASSIVE;
+
+ if ((err = getaddrinfo(NULL, port, &hints, &ai)) || !ai) {
+ *error_message =
+ g_strdup_printf(_
+ ("Error creating struct addrinfo: %s"),
+ gai_strerror(err));
+ return -1;
+ }
+
+ for (aip = ai; aip; aip = aip->ai_next) {
+ fd = socket(aip->ai_family, SOCK_STREAM, 0);
+ if (fd < 0) {
+ continue;
+ }
+ yes = 1;
+
+ /* setsockopt() before bind(); otherwise it has no effect! -- egnor */
+ if (setsockopt
+ (fd, SOL_SOCKET, SO_REUSEADDR, &yes,
+ sizeof(yes)) < 0) {
+ net_closesocket(fd);
+ continue;
+ }
+ if (bind(fd, aip->ai_addr, aip->ai_addrlen) < 0) {
+ net_closesocket(fd);
+ continue;
+ }
+
+ break;
+ }
+
+ if (!aip) {
+ *error_message =
+ g_strdup_printf(_
+ ("Error creating listening socket: %s\n"),
+ net_errormsg());
+ freeaddrinfo(ai);
+ return -1;
+ }
+
+ freeaddrinfo(ai);
+
+ if (net_set_socket_non_blocking(fd)) {
+ *error_message =
+ g_strdup_printf(_
+ ("Error setting socket non-blocking: %s\n"),
+ net_errormsg());
+ net_closesocket(fd);
+ return -1;
+ }
+
+ if (listen(fd, 5) < 0) {
+ *error_message =
+ g_strdup_printf(_
+ ("Error during listen on socket: %s\n"),
+ net_errormsg());
+ net_closesocket(fd);
+ return -1;
+ }
+ *error_message = NULL;
+ return fd;
+#else /* HAVE_GETADDRINFO_ET_AL */
+ *error_message =
+ g_strdup(_("Listening not yet supported on this platform."));
+ return -1;
+#endif /* HAVE_GETADDRINFO_ET_AL */
+}
+
+void net_closesocket(int fd)
+{
+#ifdef G_OS_WIN32
+ closesocket(fd);
+#else /* G_OS_WIN32 */
+ close(fd);
+#endif /* G_OS_WIN32 */
+}
+
+gboolean net_get_peer_name(gint fd, gchar ** hostname, gchar ** servname,
+ gchar ** error_message)
+{
+#ifdef HAVE_GETADDRINFO_ET_AL
+ sockaddr_t peer;
+ socklen_t peer_len;
+#endif /* HAVE_GETADDRINFO_ET_AL */
+
+ *hostname = g_strdup(_("unknown"));
+ *servname = g_strdup(_("unknown"));
+
+#ifdef HAVE_GETADDRINFO_ET_AL
+ peer_len = sizeof(peer);
+ if (getpeername(fd, &peer.sa, &peer_len) < 0) {
+ *error_message =
+ g_strdup_printf(_("Error getting peer name: %s"),
+ net_errormsg());
+ return FALSE;
+ } else {
+ int err;
+ char host[NI_MAXHOST];
+ char port[NI_MAXSERV];
+
+ if ((err =
+ getnameinfo(&peer.sa, peer_len, host, NI_MAXHOST,
+ port, NI_MAXSERV, 0))) {
+ *error_message =
+ g_strdup_printf(_
+ ("Error resolving address: %s"),
+ gai_strerror(err));
+ return FALSE;
+ } else {
+ g_free(*hostname);
+ g_free(*servname);
+ *hostname = g_strdup(host);
+ *servname = g_strdup(port);
+ return TRUE;
+ }
+ }
+#else /* HAVE_GETADDRINFO_ET_AL */
+ *error_message =
+ g_strdup(_
+ ("Net_get_peer_name not yet supported on this platform."));
+ return FALSE;
+#endif /* HAVE_GETADDRINFO_ET_AL */
+}
+
+gint net_accept(gint accept_fd, gchar ** error_message)
+{
+ gint fd;
+ sockaddr_t addr;
+ socklen_t addr_len;
+
+ addr_len = sizeof(addr);
+ fd = accept(accept_fd, &addr.sa, &addr_len);
+ if (fd < 0) {
+ *error_message =
+ g_strdup_printf(_("Error accepting connection: %s"),
+ net_errormsg());
+ }
+ return fd;
+}
+
+void net_init(void)
+{
+#ifdef G_OS_WIN32
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD(2, 2);
+
+ if (0 != WSAStartup(wVersionRequested, &wsaData)) {
+ g_error("No usable version of WinSock was found.");
+ }
+#else /* G_OS_WIN32 */
+ /* Do nothing on unix like platforms */
+#endif /* G_OS_WIN32 */
+}
+
+void net_finish(void)
+{
+#ifdef G_OS_WIN32
+ WSACleanup();
+#else /* G_OS_WIN32 */
+ /* Do nothing on unix like platforms */
+#endif /* G_OS_WIN32 */
+}
Added: trunk/common/network.h
===================================================================
--- trunk/common/network.h (rev 0)
+++ trunk/common/network.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,142 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __network_h
+#define __network_h
+
+#include <glib.h>
+#include <time.h>
+
+typedef enum {
+ NET_CONNECT,
+ NET_CONNECT_FAIL,
+ NET_CLOSE,
+ NET_READ
+} NetEvent;
+
+typedef void (*NetNotifyFunc) (NetEvent event, void *user_data,
+ gchar * line);
+
+typedef struct _Session Session;
+struct _Session {
+ int fd;
+ time_t last_response; /* used for activity detection. */
+ guint timer_id;
+ void *user_data;
+
+ gboolean connect_in_progress;
+ gboolean waiting_for_close;
+ char *host;
+ char *port;
+
+ gint read_tag;
+ char read_buff[16 * 1024];
+ int read_len;
+ gboolean entered;
+ gint write_tag;
+ GList *write_queue;
+
+ NetNotifyFunc notify_func;
+};
+
+void set_enable_debug(gboolean enabled);
+void debug(const gchar * fmt, ...);
+
+/** Initialize the network drivers */
+void net_init(void);
+
+/* Finish the network drivers */
+void net_finish(void);
+
+Session *net_new(NetNotifyFunc notify_func, void *user_data);
+void net_free(Session ** ses);
+
+void net_use_fd(Session * ses, int fd, gboolean do_ping);
+gboolean net_connect(Session * ses, const gchar * host,
+ const gchar * port);
+gboolean net_connected(Session * ses);
+
+/** Open a socket for listening.
+ * @param port The port
+ * @retval error_message If opening fails, a description of the error
+ * You should g_free the error_message
+ * @return A file descriptor if succesfull, or -1 if it fails
+ */
+int net_open_listening_socket(const gchar * port, gchar ** error_message);
+
+/** Close a socket
+ */
+void net_closesocket(int fd);
+
+/** Get peer name
+ * @param fd File descriptor to resolve
+ * @retval hostname The resolved hostname
+ * @retval servname The resolved port name/service name
+ * @retval error_message The error message when it fails
+ * @return TRUE is successful
+ */
+gboolean net_get_peer_name(gint fd, gchar ** hostname, gchar ** servname,
+ gchar ** error_message);
+
+/** Accept incoming connections
+ * @param accept_fd The file descriptor
+ * @retval error_message The message if it fails
+ * @return The file descriptor of the connection
+ */
+gint net_accept(gint accept_fd, gchar ** error_message);
+
+/** Close a session
+ * @param ses The session to close
+ * @return TRUE if the session can be removed
+ */
+gboolean net_close(Session * ses);
+void net_close_when_flushed(Session * ses);
+void net_wait_for_close(Session * ses);
+void net_printf(Session * ses, const gchar * fmt, ...);
+
+/** Write data.
+ * @param ses The session
+ * @param data The data to send
+ */
+void net_write(Session * ses, const gchar * data);
+
+/** Get the hostname of this computer.
+ * @return "localhost" if the hostname could not be determined.
+ */
+gchar *get_my_hostname(void);
+
+/** Get the name of the meta server.
+ * First the environment variable PIONEERS_META_SERVER is queried
+ * If it is not set, the use_default flag is used.
+ * @param use_default If true, return the default meta server if the
+ * environment variable is not set.
+ * If false, return the hostname of this computer.
+ * @return The hostname of the meta server
+ */
+gchar *get_meta_server_name(gboolean use_default);
+
+/** Get the directory of the game related files.
+ * First the environment variable PIONEERS_DIR is queried
+ * If it is not set, the default value is returned
+ */
+const gchar *get_pioneers_dir(void);
+
+#endif
Added: trunk/common/quoteinfo.c
===================================================================
--- trunk/common/quoteinfo.c (rev 0)
+++ trunk/common/quoteinfo.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,178 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <math.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "game.h"
+#include "quoteinfo.h"
+
+void quotelist_new(QuoteList ** list)
+{
+ g_assert(*list == NULL);
+ quotelist_free(list);
+ *list = g_malloc0(sizeof(**list));
+}
+
+void quotelist_free(QuoteList ** list)
+{
+ if (*list == NULL)
+ return; /* Already free */
+ while ((*list)->quotes != NULL) {
+ QuoteInfo *quote = (*list)->quotes->data;
+ (*list)->quotes = g_list_remove((*list)->quotes, quote);
+ g_free(quote);
+ }
+ g_free(*list);
+ *list = NULL;
+}
+
+static gint sort_quotes(QuoteInfo * a, QuoteInfo * b)
+{
+ gint res;
+
+ res = a->is_domestic - b->is_domestic;
+ if (res != 0)
+ return res;
+ if (a->is_domestic) {
+ res = a->var.d.player_num - b->var.d.player_num;
+ if (res != 0)
+ return res;
+ return a->var.d.quote_num - b->var.d.quote_num;
+ }
+ res = a->var.m.ratio - b->var.m.ratio;
+ if (res != 0)
+ return res;
+ res = a->var.m.receive - b->var.m.receive;
+ if (res != 0)
+ return res;
+ return a->var.m.supply - b->var.m.supply;
+}
+
+QuoteInfo *quotelist_add_maritime(QuoteList * list,
+ gint ratio, Resource supply,
+ Resource receive)
+{
+ QuoteInfo *quote;
+
+ quote = g_malloc0(sizeof(*quote));
+ quote->is_domestic = FALSE;
+ quote->var.m.ratio = ratio;
+ quote->var.m.supply = supply;
+ quote->var.m.receive = receive;
+
+ list->quotes = g_list_insert_sorted(list->quotes, quote,
+ (GCompareFunc) sort_quotes);
+ quote->list = g_list_find(list->quotes, quote);
+
+ return quote;
+}
+
+QuoteInfo *quotelist_add_domestic(QuoteList * list, gint player_num,
+ gint quote_num, const gint * supply,
+ const gint * receive)
+{
+ QuoteInfo *quote;
+
+ quote = g_malloc0(sizeof(*quote));
+ quote->is_domestic = TRUE;
+ quote->var.d.player_num = player_num;
+ quote->var.d.quote_num = quote_num;
+ memcpy(quote->var.d.supply, supply, sizeof(quote->var.d.supply));
+ memcpy(quote->var.d.receive, receive,
+ sizeof(quote->var.d.receive));
+
+ list->quotes = g_list_insert_sorted(list->quotes, quote,
+ (GCompareFunc) sort_quotes);
+ quote->list = g_list_find(list->quotes, quote);
+
+ return quote;
+}
+
+QuoteInfo *quotelist_find_domestic(QuoteList * list, gint player_num,
+ gint quote_num)
+{
+ GList *scan;
+
+ for (scan = list->quotes; scan != NULL; scan = g_list_next(scan)) {
+ QuoteInfo *quote = scan->data;
+
+ if (!quote->is_domestic)
+ continue;
+ if (quote->var.d.player_num != player_num)
+ continue;
+ if (quote->var.d.quote_num == quote_num || quote_num < 0)
+ return quote;
+ }
+
+ return NULL;
+}
+
+QuoteInfo *quotelist_first(QuoteList * list)
+{
+ if (list == NULL || list->quotes == NULL)
+ return NULL;
+ return list->quotes->data;
+}
+
+QuoteInfo *quotelist_prev(const QuoteInfo * quote)
+{
+ GList *list = g_list_previous(quote->list);
+
+ if (list == NULL)
+ return NULL;
+ return list->data;
+}
+
+QuoteInfo *quotelist_next(const QuoteInfo * quote)
+{
+ GList *list = g_list_next(quote->list);
+
+ if (list == NULL)
+ return NULL;
+ return list->data;
+}
+
+gboolean quotelist_is_player_first(const QuoteInfo * quote)
+{
+ const QuoteInfo *prev = quotelist_prev(quote);
+ return prev == NULL
+ || !prev->is_domestic
+ || prev->var.d.player_num != quote->var.d.player_num;
+}
+
+void quotelist_delete(QuoteList * list, QuoteInfo * quote)
+{
+ GList *scan;
+
+ for (scan = list->quotes; scan != NULL; scan = g_list_next(scan)) {
+ if (scan->data == quote) {
+ list->quotes =
+ g_list_remove_link(list->quotes, scan);
+ g_list_free_1(scan);
+ g_free(quote);
+ return;
+ }
+ }
+}
Added: trunk/common/quoteinfo.h
===================================================================
--- trunk/common/quoteinfo.h (rev 0)
+++ trunk/common/quoteinfo.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,63 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __quoteinfo_h
+#define __quoteinfo_h
+
+typedef struct {
+ GList *list; /* list entry which owns the quote */
+ gboolean is_domestic; /* is this a maritime trade? */
+ union {
+ struct {
+ gint player_num; /* player who make the quote */
+ gint quote_num; /* quote identifier */
+ gint supply[NO_RESOURCE]; /* resources supplied in the quote */
+ gint receive[NO_RESOURCE]; /* resources received in the quote */
+ } d;
+ struct {
+ gint ratio;
+ Resource supply;
+ Resource receive;
+ } m;
+ } var;
+} QuoteInfo;
+
+typedef struct {
+ GList *quotes;
+} QuoteList;
+
+/** Create a new quote list, and remove the old list if needed */
+void quotelist_new(QuoteList ** list);
+/** Free the QuoteList (if needed), and set it to NULL */
+void quotelist_free(QuoteList ** list);
+QuoteInfo *quotelist_add_domestic(QuoteList * list, gint player_num,
+ gint quote_num, const gint * supply,
+ const gint * receive);
+QuoteInfo *quotelist_add_maritime(QuoteList * list, gint ratio,
+ Resource supply, Resource receive);
+QuoteInfo *quotelist_first(QuoteList * list);
+QuoteInfo *quotelist_prev(const QuoteInfo * quote);
+QuoteInfo *quotelist_next(const QuoteInfo * quote);
+gboolean quotelist_is_player_first(const QuoteInfo * quote);
+QuoteInfo *quotelist_find_domestic(QuoteList * list, gint player_num,
+ gint quote_num);
+void quotelist_delete(QuoteList * list, QuoteInfo * quote);
+
+#endif
Added: trunk/common/state.c
===================================================================
--- trunk/common/state.c (rev 0)
+++ trunk/common/state.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,685 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <glib.h>
+
+#include "game.h"
+#include "cards.h"
+#include "map.h"
+#include "network.h"
+#include "log.h"
+#include "buildrec.h"
+#include "state.h"
+#include "cost.h"
+
+static void route_event(StateMachine * sm, gint event);
+
+void sm_inc_use_count(StateMachine * sm)
+{
+ sm->use_count++;
+}
+
+void sm_dec_use_count(StateMachine * sm)
+{
+ if (!--sm->use_count && sm->is_dead)
+ sm_free(sm);
+}
+
+const gchar *sm_current_name(StateMachine * sm)
+{
+ return sm->current_state;
+}
+
+void sm_state_name(StateMachine * sm, const gchar * name)
+{
+ sm->current_state = name;
+ sm->stack_name[sm->stack_ptr] = name;
+}
+
+gboolean sm_is_connected(StateMachine * sm)
+{
+ return sm->ses != NULL && net_connected(sm->ses);
+}
+
+static void route_event(StateMachine * sm, gint event)
+{
+ StateFunc curr_state;
+ gpointer user_data;
+
+ curr_state = sm_current(sm);
+ user_data = sm->user_data;
+ if (user_data == NULL)
+ user_data = sm;
+
+ /* send death notification even when dead */
+ if (event == SM_FREE) {
+ /* send death notifications only to global handler */
+ if (sm->global !=NULL)
+ sm->global (user_data, event);
+ return;
+ }
+
+ if (sm->is_dead)
+ return;
+
+ switch (event) {
+ case SM_ENTER:
+ curr_state(user_data, event);
+ break;
+ case SM_INIT:
+ curr_state(user_data, event);
+ if (!sm->is_dead && sm->global !=NULL)
+ sm->global (user_data, event);
+ break;
+ case SM_RECV:
+ sm_cancel_prefix(sm);
+ if (curr_state(user_data, event))
+ break;
+ sm_cancel_prefix(sm);
+ if (!sm->is_dead
+ && sm->global !=NULL && sm->global (user_data, event))
+ break;
+
+ sm_cancel_prefix(sm);
+ if (!sm->is_dead && sm->unhandled != NULL)
+ sm->unhandled(user_data, event);
+ break;
+ case SM_NET_CLOSE:
+ sm_close(sm);
+ default:
+ curr_state(user_data, event);
+ if (!sm->is_dead && sm->global !=NULL)
+ sm->global (user_data, event);
+ break;
+ }
+}
+
+void sm_cancel_prefix(StateMachine * sm)
+{
+ sm->line_offset = 0;
+}
+
+static void net_event(NetEvent event, StateMachine * sm, gchar * line)
+{
+ sm_inc_use_count(sm);
+
+ switch (event) {
+ case NET_CONNECT:
+ route_event(sm, SM_NET_CONNECT);
+ break;
+ case NET_CONNECT_FAIL:
+ route_event(sm, SM_NET_CONNECT_FAIL);
+ break;
+ case NET_CLOSE:
+ route_event(sm, SM_NET_CLOSE);
+ break;
+ case NET_READ:
+ sm->line = line;
+ /* Only handle data if there is a context. Fixes bug that
+ * clients starting to send data immediately crash the
+ * server */
+ if (sm->stack_ptr != -1)
+ route_event(sm, SM_RECV);
+ else {
+ sm_dec_use_count(sm);
+ return;
+ }
+ break;
+ }
+ route_event(sm, SM_INIT);
+
+ sm_dec_use_count(sm);
+}
+
+gboolean sm_connect(StateMachine * sm, const gchar * host,
+ const gchar * port)
+{
+ if (sm->ses != NULL)
+ net_free(&(sm->ses));
+
+ sm->ses = net_new((NetNotifyFunc) net_event, sm);
+ log_message(MSG_INFO, _("Connecting to %s, port %s\n"), host,
+ port);
+ if (net_connect(sm->ses, host, port))
+ return TRUE;
+
+ net_free(&(sm->ses));
+ return FALSE;
+}
+
+void sm_use_fd(StateMachine * sm, gint fd, gboolean do_ping)
+{
+ if (sm->ses != NULL)
+ net_free(&(sm->ses));
+
+ sm->ses = net_new((NetNotifyFunc) net_event, sm);
+ net_use_fd(sm->ses, fd, do_ping);
+}
+
+static gint get_num(gchar * str, gint * num)
+{
+ gint len = 0;
+ gboolean is_negative = FALSE;
+
+ if (*str == '-') {
+ is_negative = TRUE;
+ str++;
+ len++;
+ }
+ *num = 0;
+ while (isdigit(*str)) {
+ *num = *num * 10 + *str++ - '0';
+ len++;
+ }
+ if (is_negative)
+ *num = -*num;
+ return len;
+}
+
+static const gchar *resource_types[] = {
+ "brick",
+ "grain",
+ "ore",
+ "wool",
+ "lumber"
+};
+
+static gint try_recv(StateMachine * sm, const gchar * fmt, va_list ap)
+{
+ gint offset = 0;
+ gchar *line = sm->line + sm->line_offset;
+
+ while (*fmt != '\0' && line[offset] != '\0') {
+ gchar **str;
+ gint *num;
+ gint idx;
+ gint len;
+ BuildType *build_type;
+ Resource *resource;
+
+ if (*fmt != '%') {
+ if (line[offset] != *fmt)
+ return -1;
+ fmt++;
+ offset++;
+ continue;
+ }
+ fmt++;
+
+ switch (*fmt++) {
+ case 'S': /* string from current position to end of line */
+ str = va_arg(ap, gchar **);
+ *str = g_strdup(line + offset);
+ offset += strlen(*str);
+ break;
+ case 'd': /* integer */
+ num = va_arg(ap, gint *);
+ len = get_num(line + offset, num);
+ if (len == 0)
+ return -1;
+ offset += len;
+ break;
+ case 'B': /* build type */
+ build_type = va_arg(ap, BuildType *);
+ if (strncmp(line + offset, "road", 4) == 0) {
+ *build_type = BUILD_ROAD;
+ offset += 4;
+ } else if (strncmp(line + offset, "bridge", 6) ==
+ 0) {
+ *build_type = BUILD_BRIDGE;
+ offset += 6;
+ } else if (strncmp(line + offset, "ship", 4) == 0) {
+ *build_type = BUILD_SHIP;
+ offset += 4;
+ } else if (strncmp(line + offset, "settlement", 10)
+ == 0) {
+ *build_type = BUILD_SETTLEMENT;
+ offset += 10;
+ } else if (strncmp(line + offset, "city_wall", 9)
+ == 0) {
+ *build_type = BUILD_CITY_WALL;
+ offset += 9;
+ } else if (strncmp(line + offset, "city", 4) == 0) {
+ *build_type = BUILD_CITY;
+ offset += 4;
+ } else
+ return -1;
+ break;
+ case 'R': /* list of 5 integer resource counts */
+ num = va_arg(ap, gint *);
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ while (line[offset] == ' ')
+ offset++;
+ len = get_num(line + offset, num);
+ if (len == 0)
+ return -1;
+ offset += len;
+ num++;
+ }
+ break;
+ case 'D': /* development card type */
+ num = va_arg(ap, gint *);
+ len = get_num(line + offset, num);
+ if (len == 0)
+ return -1;
+ offset += len;
+ break;
+ case 'r': /* resource type */
+ resource = va_arg(ap, Resource *);
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ const gchar *type = resource_types[idx];
+ len = strlen(type);
+ if (strncmp(line + offset, type, len) == 0) {
+ offset += len;
+ *resource = idx;
+ break;
+ }
+ }
+ if (idx == NO_RESOURCE)
+ return -1;
+ break;
+ }
+ }
+ if (*fmt != '\0')
+ return -1;
+ return offset;
+}
+
+gboolean sm_recv(StateMachine * sm, const gchar * fmt, ...)
+{
+ va_list ap;
+ gint offset;
+
+ va_start(ap, fmt);
+ offset = try_recv(sm, fmt, ap);
+ va_end(ap);
+
+ return offset > 0 && sm->line[sm->line_offset + offset] == '\0';
+}
+
+gboolean sm_recv_prefix(StateMachine * sm, const gchar * fmt, ...)
+{
+ va_list ap;
+ gint offset;
+
+ va_start(ap, fmt);
+ offset = try_recv(sm, fmt, ap);
+ va_end(ap);
+
+ if (offset < 0)
+ return FALSE;
+ sm->line_offset += offset;
+ return TRUE;
+}
+
+#define buff_append(result, format, value) \
+ do { \
+ gchar *old = result; \
+ result = g_strdup_printf("%s" format, result, value); \
+ g_free(old); \
+ } while (0)
+
+gchar *sm_vformat(const gchar * fmt, va_list ap)
+{
+ /* initialize result to an allocated empty string */
+ gchar *result = g_strdup("");
+
+ while (*fmt != '\0') {
+ gchar *pos = strchr(fmt, '%');
+ if (pos == NULL) {
+ buff_append(result, "%s", fmt);
+ break;
+ }
+ /* add format until next % to result */
+ result = g_realloc(result, strlen(result) + pos - fmt + 1);
+ result[strlen(result) + pos - fmt] = '\0';
+ memcpy(&result[strlen(result)], fmt, pos - fmt);
+ fmt = pos + 1;
+
+ switch (*fmt++) {
+ BuildType build_type;
+ const gint *num;
+ gint idx;
+ case 's': /* string */
+ buff_append(result, "%s", va_arg(ap, gchar *));
+ break;
+ case 'd': /* integer */
+ case 'D': /* development card type */
+ buff_append(result, "%d", va_arg(ap, gint));
+ break;
+ case 'B': /* build type */
+ build_type = va_arg(ap, BuildType);
+ switch (build_type) {
+ case BUILD_ROAD:
+ buff_append(result, "%s", "road");
+ break;
+ case BUILD_BRIDGE:
+ buff_append(result, "%s", "bridge");
+ break;
+ case BUILD_SHIP:
+ buff_append(result, "%s", "ship");
+ break;
+ case BUILD_SETTLEMENT:
+ buff_append(result, "%s", "settlement");
+ break;
+ case BUILD_CITY:
+ buff_append(result, "%s", "city");
+ break;
+ case BUILD_CITY_WALL:
+ buff_append(result, "%s", "city_wall");
+ break;
+ case BUILD_NONE:
+ g_error("BUILD_NONE passed to sm_vformat");
+ break;
+ case BUILD_MOVE_SHIP:
+ g_error
+ ("BUILD_MOVE_SHIP passed to sm_vformat");
+ break;
+ }
+ break;
+ case 'R': /* list of 5 integer resource counts */
+ num = va_arg(ap, gint *);
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ if (idx > 0)
+ buff_append(result, " %d",
+ num[idx]);
+ else
+ buff_append(result, "%d",
+ num[idx]);
+ }
+ break;
+ case 'r': /* resource type */
+ buff_append(result, "%s",
+ resource_types[va_arg(ap, Resource)]);
+ break;
+ }
+ }
+ return result;
+}
+
+void sm_write(StateMachine * sm, const gchar * str)
+{
+ if (sm->use_cache) {
+ /* Protect against strange/slow connects */
+ if (g_list_length(sm->cache) > 1000) {
+ net_write(sm->ses, "ERR connection too slow\n");
+ net_close_when_flushed(sm->ses);
+ } else {
+ sm->cache =
+ g_list_append(sm->cache, g_strdup(str));
+ }
+ } else
+ net_write(sm->ses, str);
+}
+
+void sm_write_uncached(StateMachine * sm, const gchar * str)
+{
+ g_assert(sm->ses);
+ g_assert(sm->use_cache);
+
+ net_write(sm->ses, str);
+}
+
+void sm_send(StateMachine * sm, const gchar * fmt, ...)
+{
+ va_list ap;
+ gchar *buff;
+
+ if (!sm->ses)
+ return;
+
+ va_start(ap, fmt);
+ buff = sm_vformat(fmt, ap);
+ va_end(ap);
+
+ sm_write(sm, buff);
+ g_free(buff);
+}
+
+void sm_set_use_cache(StateMachine * sm, gboolean use_cache)
+{
+ if (sm->use_cache == use_cache)
+ return;
+
+ if (!use_cache) {
+ /* The cache is turned off, send the delayed data */
+ GList *list = sm->cache;
+ while (list) {
+ gchar *data = list->data;
+ net_write(sm->ses, data);
+ list = g_list_remove(list, data);
+ g_free(data);
+ }
+ sm->cache = NULL;
+ } else {
+ /* Be sure that the cache is empty */
+ g_assert(!sm->cache);
+ }
+ sm->use_cache = use_cache;
+}
+
+void sm_global_set(StateMachine * sm, StateFunc state)
+{
+ sm->global = state;
+}
+
+void sm_unhandled_set(StateMachine * sm, StateFunc state)
+{
+ sm->unhandled = state;
+}
+
+static void push_new_state(StateMachine * sm)
+{
+ ++sm->stack_ptr;
+ /* check for stack overflows */
+ if (sm->stack_ptr >= G_N_ELEMENTS(sm->stack)) {
+ log_message(MSG_ERROR,
+ _
+ ("State stack overflow. Stack dump sent to standard error.\n"));
+ sm_stack_dump(sm);
+ g_error("State stack overflow");
+ }
+ sm->stack[sm->stack_ptr] = NULL;
+ sm->stack_name[sm->stack_ptr] = NULL;
+}
+
+static void do_goto(StateMachine * sm, StateFunc new_state, gboolean enter)
+{
+ sm_inc_use_count(sm);
+
+ if (sm->stack_ptr < 0) {
+ /* Wait until the application window is fully
+ * displayed before starting state machine.
+ */
+ if (driver != NULL && driver->event_queue != NULL)
+ driver->event_queue();
+ push_new_state(sm);
+ }
+
+ sm->stack[sm->stack_ptr] = new_state;
+ if (enter)
+ route_event(sm, SM_ENTER);
+ route_event(sm, SM_INIT);
+
+#ifdef STACK_DEBUG
+ debug("sm_goto -> %d:%s", sm->stack_ptr, sm->current_state);
+#endif
+
+ sm_dec_use_count(sm);
+}
+
+void sm_goto(StateMachine * sm, StateFunc new_state)
+{
+ do_goto(sm, new_state, TRUE);
+}
+
+void sm_goto_noenter(StateMachine * sm, StateFunc new_state)
+{
+ do_goto(sm, new_state, FALSE);
+}
+
+static void do_push(StateMachine * sm, StateFunc new_state, gboolean enter)
+{
+ sm_inc_use_count(sm);
+
+ push_new_state(sm);
+ sm->stack[sm->stack_ptr] = new_state;
+ if (enter)
+ route_event(sm, SM_ENTER);
+ route_event(sm, SM_INIT);
+#ifdef STACK_DEBUG
+ debug("sm_push -> %d:%s (enter=%d)", sm->stack_ptr,
+ sm->current_state, enter);
+#endif
+ sm_dec_use_count(sm);
+}
+
+void sm_push(StateMachine * sm, StateFunc new_state)
+{
+ do_push(sm, new_state, TRUE);
+}
+
+void sm_push_noenter(StateMachine * sm, StateFunc new_state)
+{
+ do_push(sm, new_state, FALSE);
+}
+
+void sm_pop(StateMachine * sm)
+{
+ sm_inc_use_count(sm);
+
+ g_assert(sm->stack_ptr > 0);
+ sm->stack_ptr--;
+ route_event(sm, SM_ENTER);
+#ifdef STACK_DEBUG
+ debug("sm_pop -> %d:%s", sm->stack_ptr, sm->current_state);
+#endif
+ route_event(sm, SM_INIT);
+ sm_dec_use_count(sm);
+}
+
+void sm_multipop(StateMachine * sm, gint depth)
+{
+ sm_inc_use_count(sm);
+
+ g_assert(sm->stack_ptr >= depth - 1);
+ sm->stack_ptr -= depth;
+ route_event(sm, SM_ENTER);
+#ifdef STACK_DEBUG
+ debug("sm_multipop -> %d:%s", sm->stack_ptr, sm->current_state);
+#endif
+ route_event(sm, SM_INIT);
+
+ sm_dec_use_count(sm);
+}
+
+void sm_pop_all_and_goto(StateMachine * sm, StateFunc new_state)
+{
+ sm_inc_use_count(sm);
+
+ sm->stack_ptr = 0;
+ sm->stack[sm->stack_ptr] = new_state;
+ sm->stack_name[sm->stack_ptr] = NULL;
+ route_event(sm, SM_ENTER);
+ route_event(sm, SM_INIT);
+
+ sm_dec_use_count(sm);
+}
+
+/** Return the state at offset from the top of the stack.
+ * @param sm The StateMachine
+ * @param offset Offset from the top (0=top, 1=previous)
+ * @return The StateFunc, or NULL if the stack contains
+ * less than offset entries
+ */
+StateFunc sm_stack_inspect(const StateMachine * sm, guint offset)
+{
+ if (sm->stack_ptr >= offset)
+ return sm->stack[sm->stack_ptr - offset];
+ else
+ return NULL;
+}
+
+StateFunc sm_current(StateMachine * sm)
+{
+ g_assert(sm->stack_ptr >= 0);
+
+ return sm->stack[sm->stack_ptr];
+}
+
+/* Build a new state machine instance
+ */
+StateMachine *sm_new(gpointer user_data)
+{
+ StateMachine *sm = g_malloc0(sizeof(*sm));
+
+ sm->user_data = user_data;
+ sm->stack_ptr = -1;
+
+ return sm;
+}
+
+/* Free a state machine
+ */
+void sm_free(StateMachine * sm)
+{
+ if (sm->ses != NULL) {
+ net_free(&(sm->ses));
+ g_return_if_fail(sm->ses == NULL);
+ }
+ if (sm->use_count > 0)
+ sm->is_dead = TRUE;
+ else {
+ route_event(sm, SM_FREE);
+ g_free(sm);
+ }
+}
+
+void sm_close(StateMachine * sm)
+{
+ net_free(&(sm->ses));
+ if (sm->use_cache) {
+ /* Purge the cache */
+ GList *list = sm->cache;
+ sm->cache = NULL;
+ sm_set_use_cache(sm, FALSE);
+ while (list) {
+ gchar *data = list->data;
+ list = g_list_remove(list, data);
+ g_free(data);
+ }
+ }
+}
+
+void sm_stack_dump(StateMachine * sm)
+{
+ gint sp;
+ for (sp = 0; sp <= sm->stack_ptr; ++sp) {
+ fprintf(stderr, "Stack %2d: %s\n", sp, sm->stack_name[sp]);
+ }
+}
Added: trunk/common/state.h
===================================================================
--- trunk/common/state.h (rev 0)
+++ trunk/common/state.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,187 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __state_h
+#define __state_h
+
+#include "network.h"
+
+/* sm_ API:
+ *
+ * The server output is handled one line at a time. For each line
+ * received, the current state is called with the SM_RECV event. The
+ * [fmt] format string is modelled on the printf format string. It
+ * understands the following types:
+ * %S - string from current position to end of line
+ * this takes a gchar ** argument, in which an allocated buffer
+ * is returned. It must be freed by the caller.
+ * %d - integer
+ * %B - build type;
+ * 'road' = BUILD_ROAD,
+ * 'ship' = BUILD_SHIP,
+ * 'bridge' = BUILD_BRIDGE,
+ * 'settlement' = BUILD_SETTLEMENT
+ * 'city' = BUILD_CITY
+ * %R - list of 5 integer resource counts;
+ * brick, grain, ore, wool, lumber
+ * %D - development card type;
+ * 0 = DEVEL_ROAD_BUILDING,
+ * 1 = DEVEL_MONOPOLY,
+ * 2 = DEVEL_YEAR_OF_PLENTY,
+ * 3 = DEVEL_CHAPEL,
+ * 4 = DEVEL_UNIVERSITY,
+ * 5 = DEVEL_GOVERNORS_HOUSE,
+ * 6 = DEVEL_LIBRARY,
+ * 7 = DEVEL_MARKET,
+ * 8 = DEVEL_SOLDIER
+ * %r - resource type;
+ * 'brick' = BRICK_RESOURCE,
+ * 'grain' = GRAIN_RESOURCE,
+ * 'ore' = ORE_RESOURCE,
+ * 'wool' = WOOL_RESOURCE,
+ * 'lumber' = LUMBER_RESOURCE,
+ *
+ * sm_recv(fmt, ...)
+ * Match the entire current line from the start position.
+ * Returns TRUE if there is a match
+ *
+ * sm_recv_prefix(fmt, ...)
+ * Match a prefix of the current line from the start position.
+ * Returns TRUE if there is a match, and sets the start position
+ * to the character following the prefix. If the prefix does not
+ * match, the function returns FALSE, and does not alter the
+ * start position.
+ *
+ * sm_cancel_prefix()
+ * Set start position in current line back to beginning.
+ *
+ * sm_send(fmt, ...)
+ * Send data back to the server.
+ *
+ * The sm_ API maintains a record of the current state, and a stack of
+ * previous states. Code can move to new states using the following
+ * functions.
+ *
+ * sm_goto(new_state)
+ * Set the current state to [new_state]
+ *
+ * sm_push(new_state)
+ * Save the current state on the stack, then set the current
+ * state to [new_state]
+ *
+ * sm_pop()
+ * Pop the top state off the stack and make it the current state.
+ *
+ * sm_multipop()
+ * Pop a number of states off the stack and set a new current state
+ * accordingly.
+ *
+ * sm_pop_all_and_goto(new_state)
+ * Clear the state stack, set the current state to [new_state]
+ *
+ * sm_stack_inspect()
+ * Return the state at offset from the top of the stack.
+ */
+
+typedef enum {
+ SM_NET_CONNECT = 10000,
+ SM_NET_CONNECT_FAIL,
+ SM_NET_CLOSE,
+
+ SM_ENTER,
+ SM_INIT,
+ SM_RECV,
+ SM_FREE
+} EventType;
+
+typedef struct StateMachine StateMachine;
+
+/* All state functions look like this
+ */
+typedef gboolean(*StateFunc) (StateMachine * sm, gint event);
+
+struct StateMachine {
+ gpointer user_data; /* parameter for mode functions */
+ /* FIXME RC 2004-11-13 in practice:
+ * it is NULL or a Player*
+ * the value is set by sm_new.
+ * Why? Can the player not be bound to a
+ * StateMachine otherwise? */
+
+ StateFunc global; /* global state - test after current state */
+ StateFunc unhandled; /* global state - process unhandled states */
+ StateFunc stack[16]; /* handle sm_push() to save context */
+ const gchar *stack_name[16]; /* state names used for a stack dump */
+ gint stack_ptr; /* stack index */
+ const gchar *current_state; /* name of current state */
+
+ gchar *line; /* line passed in from network event */
+ gint line_offset; /* line prefix handling */
+
+ Session *ses; /* network session feeding state machine */
+ gint use_count; /* # functions is in use by */
+ gboolean is_dead; /* is this machine waiting to be killed? */
+
+ gboolean use_cache; /* cache the data that is sent */
+ GList *cache; /* cache for the delayed data */
+};
+
+StateMachine *sm_new(gpointer user_data);
+void sm_free(StateMachine * sm);
+void sm_close(StateMachine * sm);
+const gchar *sm_current_name(StateMachine * sm);
+void sm_state_name(StateMachine * sm, const gchar * name);
+gboolean sm_recv(StateMachine * sm, const gchar * fmt, ...);
+gboolean sm_recv_prefix(StateMachine * sm, const gchar * fmt, ...);
+void sm_cancel_prefix(StateMachine * sm);
+gchar *sm_vformat(const gchar * fmt, va_list ap);
+void sm_write(StateMachine * sm, const gchar * str);
+/** Send the data, even when caching is turned on */
+void sm_write_uncached(StateMachine * sm, const gchar * str);
+void sm_send(StateMachine * sm, const gchar * fmt, ...);
+/** Cache the messages that are sent.
+ * When the caching is turned off, all cached data is sent.
+ * @param sm The statemachine
+ * @param use_cache Turn the caching on/off
+ */
+void sm_set_use_cache(StateMachine * sm, gboolean use_cache);
+
+void sm_goto(StateMachine * sm, StateFunc new_state);
+void sm_goto_noenter(StateMachine * sm, StateFunc new_state);
+void sm_push(StateMachine * sm, StateFunc new_state);
+void sm_push_noenter(StateMachine * sm, StateFunc new_state);
+void sm_pop(StateMachine * sm);
+void sm_multipop(StateMachine * sm, gint depth);
+void sm_pop_all_and_goto(StateMachine * sm, StateFunc new_state);
+StateFunc sm_current(StateMachine * sm);
+StateFunc sm_stack_inspect(const StateMachine * sm, guint offset);
+void sm_global_set(StateMachine * sm, StateFunc state);
+void sm_unhandled_set(StateMachine * sm, StateFunc state);
+
+gboolean sm_is_connected(StateMachine * sm);
+gboolean sm_connect(StateMachine * sm, const gchar * host,
+ const gchar * port);
+void sm_use_fd(StateMachine * sm, gint fd, gboolean do_ping);
+void sm_dec_use_count(StateMachine * sm);
+void sm_inc_use_count(StateMachine * sm);
+/** Dump the stack */
+void sm_stack_dump(StateMachine * sm);
+#endif
Added: trunk/configure.ac
===================================================================
--- trunk/configure.ac (rev 0)
+++ trunk/configure.ac 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,475 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2003-2007 Bas Wijnen <shevek at fmf.nl>
+# Copyright (C) 2004-2007 Roland Clobus <rclobus at bigfoot.com>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+AC_PREREQ(2.53)
+AC_INIT([pioneers],[0.11.3],[pio-develop at lists.sourceforge.net])
+AC_CONFIG_AUX_DIR([.])
+AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
+AC_CONFIG_SRCDIR([client])
+AM_CONFIG_HEADER(config.h)
+
+PROTOCOL_VERSION=0.11
+META_PROTOCOL_VERSION=1.3
+PIONEERS_DEFAULT_GAME_PORT=5556
+PIONEERS_DEFAULT_GAME_HOST=localhost
+PIONEERS_DEFAULT_ADMIN_PORT=5555
+PIONEERS_DEFAULT_META_PORT=5557
+PIONEERS_DEFAULT_META_SERVER=pioneers.debian.net
+
+GLIB_REQUIRED_VERSION=2.6
+GTK_REQUIRED_VERSION=2.6
+
+AC_SUBST(GLIB_REQUIRED_VERSION)
+AC_SUBST(GTK_REQUIRED_VERSION)
+
+AM_MAINTAINER_MODE
+
+AC_PROG_LIBTOOL
+
+AC_PROG_CC
+AM_PROG_CC_C_O
+AM_PROG_MKDIR_P
+AC_HEADER_STDC
+
+if test $USE_MAINTAINER_MODE = yes; then
+ pioneers_warnings=yes;
+ pioneers_debug=yes;
+ pioneers_deprecationChecks=yes;
+else
+ pioneers_warnings=no;
+ pioneers_debug=no;
+ pioneers_deprecationChecks=no;
+fi
+
+# Try to find a suitable renderer for the svg images
+AC_PATH_PROG(svg_renderer_path, rsvg)
+AC_SUBST(whitespace_trick, [" "])
+if test x$svg_renderer_path != x; then
+ AC_SUBST(svg_renderer_width, ["--width \$(whitespace_trick)"])
+ AC_SUBST(svg_renderer_height, ["\$(whitespace_trick) --height \$(whitespace_trick)"])
+else
+AC_PATH_PROG(svg_renderer_path, convert)
+if test x$svg_renderer_path != x; then
+ AC_SUBST(svg_renderer_width, ["-background \"\#000001\" -transparent \"\#000001\" -resize \$(whitespace_trick)"])
+ AC_SUBST(svg_renderer_height, ["x"])
+else
+ # Add other SVG rendering programs here
+ # Don't let configure fail, in the distributed tarballs is already
+ # a current .png file
+ AC_SUBST(svg_renderer_path, [false])
+fi
+fi
+
+# Is netpbm installed (should be needed only for maintainer builds)
+# netpbm will generate the icon for the Windows executables
+AC_PATH_PROG(pngtopnm, pngtopnm)
+if test "$pngtopnm" = ""; then
+ # Don't let configure fail, in the distributed tarballs is already
+ # a current .png file
+ AC_SUBST(pngtopnm, [false])
+fi
+
+AC_ARG_ENABLE([warnings], AC_HELP_STRING([--enable-warnings],
+ [Compile with check for compiler warnings (gcc-only).]),
+[case "${enableval}" in
+ full) pioneers_warnings=full;;
+ yes) pioneers_warnings=yes ;;
+ "") pioneers_warnings=yes ;;
+ *) pioneers_warnings=no ;;
+esac])
+
+AC_ARG_ENABLE([debug], AC_HELP_STRING([--enable-debug],
+ [Enable debug information.]),
+[case "${enableval}" in
+ yes) pioneers_debug=yes ;;
+ "") pioneers_debug=yes ;;
+ *) pioneers_debug=no ;;
+esac])
+
+AC_ARG_ENABLE([deprecation-checks],
+ AC_HELP_STRING([--enable-deprecation-checks],
+ [Enable strict deprecation checks.]),
+[case "${enableval}" in
+ yes) pioneers_deprecationChecks=yes ;;
+ "") pioneers_deprecationChecks=yes ;;
+ *) pioneers_deprecationChecks=no ;;
+esac])
+
+## The warnings are in the same order as in 'man gcc'
+if test "x$GCC" = xyes; then
+ if test "$pioneers_warnings" = yes -o "$pioneers_warnings" = full; then
+ AC_SUBST(WARNINGS, "-Wall")
+ AC_SUBST(WARNINGS, "$WARNINGS -W")
+ AC_SUBST(WARNINGS, "$WARNINGS -Wpointer-arith")
+ AC_SUBST(WARNINGS, "$WARNINGS -Wcast-qual")
+ AC_SUBST(WARNINGS, "$WARNINGS -Wwrite-strings")
+ AC_SUBST(WARNINGS, "$WARNINGS -Wno-sign-compare")
+ AC_SUBST(WARNINGS, "$WARNINGS -Waggregate-return")
+ AC_SUBST(WARNINGS, "$WARNINGS -Wstrict-prototypes")
+ AC_SUBST(WARNINGS, "$WARNINGS -Wmissing-prototypes")
+ AC_SUBST(WARNINGS, "$WARNINGS -Wmissing-declarations")
+ AC_SUBST(WARNINGS, "$WARNINGS -Wredundant-decls")
+ AC_SUBST(WARNINGS, "$WARNINGS -Wnested-externs")
+ AC_SUBST(WARNINGS, "$WARNINGS -O")
+ fi
+ if test "$pioneers_warnings" = full; then
+ flags="-Wfloat-equal"
+ flags="$flags -Wdeclaration-after-statement"
+ flags="$flags -Wundef"
+ flags="$flags -Wendif-labels"
+ flags="$flags -Wshadow"
+ flags="$flags -Wbad-function-cast"
+ flags="$flags -Wconversion"
+ flags="$flags -Wold-style-definition"
+ flags="$flags -Wunreachable-code"
+ flags="$flags -pedantic"
+
+ # This for loop comes from gnome-compiler-flags.m4
+ for option in $flags; do
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $option"
+ AC_MSG_CHECKING([whether gcc understands $option])
+ AC_TRY_COMPILE([], [],
+ has_option=yes,
+ has_option=no,)
+ CFLAGS="$SAVE_CFLAGS"
+ AC_MSG_RESULT($has_option)
+ if test $has_option = yes; then
+ AC_SUBST(WARNINGS, "$WARNINGS $option")
+ fi
+ unset has_option
+ unset SAVE_CFLAGS
+ done
+ unset option
+ unset flags
+ fi
+fi
+AC_SUBST(WARNINGS)
+
+if test "$pioneers_debug" = yes; then
+ AC_SUBST(DEBUGGING, "-ggdb3")
+fi
+AC_SUBST(DEBUGGING)
+
+if test "$pioneers_deprecationChecks" = yes; then
+ AC_SUBST(GLIB_DEPRECATION, "-DG_DISABLE_DEPRECATED")
+ AC_SUBST(GTK_DEPRECATION, "-DGDK_DISABLE_DEPRECATED")
+ AC_SUBST(GTK_DEPRECATION, "$GTK_DEPRECATION -DGTK_DISABLE_DEPRECATED")
+ AC_SUBST(GTK_DEPRECATION, "$GTK_DEPRECATION -DGNOME_DISABLE_DEPRECATED")
+fi
+AC_SUBST(GLIB_DEPRECATION)
+AC_SUBST(GTK_DEPRECATION)
+
+if test "$with_help" = no; then
+ pioneers_help="no, disabled in configure"
+ have_scrollkeeper=no
+else
+ ## Scrollkeeper dependency test taken from gnome-games 2.6.2
+ ## Begin tests for scrollkeeper
+ # SCROLLKEEPER_REQUIRED is never used?
+ SCROLLKEEPER_REQUIRED=0.3.8
+ AC_SUBST(SCROLLKEEPER_REQUIRED)
+
+ AC_PATH_PROG(SCROLLKEEPER_CONFIG, scrollkeeper-config,no)
+ if test x$SCROLLKEEPER_CONFIG = xno; then
+ have_scrollkeeper=no
+ pioneers_help="no, scrollkeeper not found"
+ else
+ have_scrollkeeper=yes
+ pioneers_help="yes"
+ fi
+fi
+
+# glib is always needed
+PKG_CHECK_MODULES(GLIB2, glib-2.0 >= $GLIB_REQUIRED_VERSION)
+
+# Gtk+ support
+if test x$with_gtk = xno; then
+ have_gtk2="no, disabled in configure"
+else
+ PKG_CHECK_MODULES(GTK2, gtk+-2.0 >= $GTK_REQUIRED_VERSION,
+ have_gtk2=yes,
+ [PKG_CHECK_EXISTS(gtk+-2.0,
+ [have_gtk2="no, Gtk+ version too old"],
+ [have_gtk2="no, Gtk+ not installed"])
+ AC_MSG_RESULT($have_gtk2)
+ ])
+fi
+AM_CONDITIONAL(HAVE_GTK2, [test "$have_gtk2" = "yes"])
+
+# Gtk ScrollKeeper -> Test Build
+# libgnome Help
+# N X N N
+# Y N N N
+# Y Y Y if have libgnome
+# libgnome is only needed for help
+if test "$have_gtk2" = "yes"; then
+ test_libgnome=$have_scrollkeeper;
+else
+ test_libgnome=no;
+fi
+
+have_graphical=$have_gtk2;
+if test "$test_libgnome" = "yes"; then
+ # libgnome-2.0 support
+ PKG_CHECK_MODULES(GNOME2, libgnome-2.0,
+ [have_gnome="yes"],
+ [have_gnome="no, libgnome-2.0 not installed"
+ AC_MSG_RESULT($have_gnome)])
+ if test "$have_gnome" = "yes"; then
+ AC_DEFINE(HAVE_LIBGNOME, 1,
+ [Defined if libgnome is present and needed])
+ fi
+ if test "$have_scrollkeeper" = "yes"; then
+ # Turn off the help if libgnome not installed
+ have_scrollkeeper=$have_gnome;
+ fi
+fi
+AM_CONDITIONAL(HAVE_GNOME, [test "$have_graphical" = "yes"])
+
+AM_CONDITIONAL(HAVE_SCROLLKEEPER, [test "$have_scrollkeeper" = "yes"])
+
+AC_ARG_ENABLE([admin-gtk], AC_HELP_STRING([--enable-admin-gtk],
+ [Turn on (unstable) network administration support.]),
+[case "${enableval}" in
+ yes) admin_gtk_support=yes ;;
+ "") admin_gtk_support=yes ;;
+ *) admin_gtk_support=no ;;
+esac], [admin_gtk_support=no])
+AM_CONDITIONAL(ADMIN_GTK_SUPPORT, [test x$admin_gtk_support = xyes])
+
+AC_CHECK_HEADERS([netdb.h fcntl.h netinet/in.h sys/socket.h])
+AC_CHECK_HEADERS([limits.h])
+AC_CHECK_HEADERS([syslog.h],
+ [pioneers_have_syslog=yes;],
+ [pioneers_have_syslog=no;])
+AC_HEADER_SYS_WAIT
+AC_HEADER_TIME
+
+AC_C_CONST
+
+# Functions
+AC_FUNC_FORK
+AC_FUNC_SELECT_ARGTYPES
+
+# Mathematics
+AC_CHECK_FUNCS([rint sqrt])
+# String functions
+AC_CHECK_FUNCS([strchr strspn strstr strcspn])
+AC_CHECK_FUNCS([memmove memset])
+# Network and I/O functions
+AC_CHECK_FUNCS([gethostname gethostbyname select socket])
+getsockopt_arg3="void *";
+# getaddrinfo and friends
+AC_CHECK_FUNCS([getaddrinfo gai_strerror freeaddrinfo],
+ AC_DEFINE_UNQUOTED(HAVE_GETADDRINFO_ET_AL, [1],
+ [Defined when getaddrinfo. gai_strerror and freeaddrinfo are present]))
+
+# The Windows ports (Cygwin and MinGW) are client-only
+pioneers_is_mingw_port=no;
+case $host in
+ *-*-cygwin*)
+ pioneers_is_windows_port=yes;;
+ *-*-mingw*)
+ pioneers_is_windows_port=yes;
+ pioneers_is_mingw_port=yes;;
+ *)
+ pioneers_is_windows_port=no;;
+esac
+
+# Can a non-blocking socket be created?
+pioneers_have_non_blocking_sockets=no;
+AC_CHECK_FUNCS([fcntl],[pioneers_have_non_blocking_sockets=yes])
+if test "$pioneers_have_non_blocking_sockets" = "no"; then
+ # Only check for ws2tcpip now,
+ # because it will cause problems under Cygwin
+ AC_CHECK_HEADERS([ws2tcpip.h],
+ [pioneers_have_non_blocking_sockets=yes;
+ getsockopt_arg3="char *";
+ ])
+fi
+AC_DEFINE_UNQUOTED(GETSOCKOPT_ARG3, $getsockopt_arg3, [The type of the third argument of getsockopt])
+
+if test $pioneers_is_mingw_port = yes; then
+ # The check for WSACleanup in ws2_32 needs an include of ws2tcpip.h
+ # This is not possible with the AC_CHECK_LIB macro
+ # AC_CHECK_LIB(ws2_32, WSACleanup)
+ # Just add ws2_32 to the list of libraries
+ AC_SUBST(LIBS, "-lws2_32 $LIBS")
+ AC_SUBST(AM_CFLAGS, "-mms-bitfields $AM_CFLAGS")
+ AC_SUBST(AM_CFLAGS, "$AM_CFLAGS -DWIN32_LEAN_AND_MEAN")
+ # No console window for the graphical applications
+ AC_SUBST(GTK2_LIBS, "$GTK2_LIBS -mwindows")
+ # Don't use bin, lib and share subdirectories
+ datadir='${prefix}'
+ bindir='${prefix}'
+ libdir='${prefix}'
+ pioneers_datadir=.
+ pioneers_themedir=$datadir/themes
+ pioneers_themedir_embed=themes
+ pioneers_localedir=locale
+else
+ pioneers_datadir=$datadir
+ pioneers_themedir=$datadir/games/pioneers/themes
+ pioneers_themedir_embed=$pioneers_themedir
+ pioneers_localedir=$datadir/locale
+fi
+AC_SUBST(pioneers_datadir)
+AC_SUBST(pioneers_themedir)
+AC_SUBST(pioneers_themedir_embed)
+AC_SUBST(pioneers_localedir)
+
+# Functions needed for the hack to override the language
+AC_CHECK_FUNCS([setlocale])
+
+# Data types
+AC_STRUCT_TM
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+# Check if socklen_t is present
+TYPE_SOCKLEN_T
+
+# Defines, accessible for all source files
+AC_DEFINE_UNQUOTED(PROTOCOL_VERSION, "$PROTOCOL_VERSION",
+ [Protocol version used by the program])
+AC_DEFINE_UNQUOTED(META_PROTOCOL_VERSION, "$META_PROTOCOL_VERSION",
+ [Protocol version used by the meta server])
+AC_DEFINE_UNQUOTED(PIONEERS_DEFAULT_GAME_PORT, "$PIONEERS_DEFAULT_GAME_PORT",
+ [The default port for a new game])
+AC_DEFINE_UNQUOTED(PIONEERS_DEFAULT_GAME_HOST, "$PIONEERS_DEFAULT_GAME_HOST",
+ [The default host for a new game])
+AC_DEFINE_UNQUOTED(PIONEERS_DEFAULT_ADMIN_PORT, "$PIONEERS_DEFAULT_ADMIN_PORT",
+ [The default port for the admin interface])
+AC_DEFINE_UNQUOTED(PIONEERS_DEFAULT_META_PORT, "$PIONEERS_DEFAULT_META_PORT",
+ [The port for the meta server])
+AC_DEFINE_UNQUOTED(PIONEERS_DEFAULT_META_SERVER,
+ "$PIONEERS_DEFAULT_META_SERVER", [The default meta server])
+
+## internationalization support
+ALL_LINGUAS="af de es fr hu it ja nl sv"
+
+GETTEXT_PACKAGE=pioneers
+AC_SUBST(GETTEXT_PACKAGE)
+AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [The gettext package name])
+AM_GLIB_GNU_GETTEXT
+AC_DEFINE_UNQUOTED(ALL_LINGUAS, "$ALL_LINGUAS", [Available languages])
+
+PKG_CHECK_MODULES(UI, [ hildon-libs libosso ])
+AC_SUBST(CFLAGS, "$CFLAGS $UI_CFLAGS")
+AC_SUBST(LIBS, "$LIBS $UI_LIBS")
+
+# All checks are completed.
+# Determine which executables cannot be built
+pioneers_build_client_ai=yes;
+pioneers_build_client_gtk=yes;
+pioneers_build_editor=yes;
+pioneers_build_server_console=yes;
+pioneers_build_server_gtk=yes;
+pioneers_build_metaserver=yes;
+
+if test "$pioneers_have_syslog" = "no"; then
+ pioneers_build_metaserver=no;
+fi
+if test "$have_graphical" != "yes"; then
+ pioneers_build_client_gtk=$have_graphical;
+ pioneers_build_editor=$have_graphical;
+ pioneers_build_server_gtk=$have_graphical;
+fi
+if test "$pioneers_have_non_blocking_sockets" = "no"; then
+ pioneers_build_client_ai=no;
+ pioneers_build_client_gtk=no;
+ pioneers_build_server_console=no;
+ pioneers_build_server_gtk=no;
+ pioneers_build_metaserver=no;
+fi
+
+# The server functionality is not ported to MS Windows
+if test "$pioneers_is_windows_port" = "yes"; then
+ pioneers_build_server_console="no, not implemented for MS Windows";
+ pioneers_build_server_gtk="no, not implemented for MS Windows";
+ pioneers_build_metaserver="no, not implemented for MS Windows";
+fi
+
+# Construct a nice text about Microsoft Windows icons
+if test $USE_MAINTAINER_MODE = yes; then
+ if test "$with_ms_icons" = "no"; then
+ if test $pioneers_is_windows_port = yes; then
+ AC_MSG_ERROR([Icons cannot be disabled in maintainermode in MS Windows])
+ fi
+ pioneers_ms_icons="Disabled, make dist is disabled too"
+ else
+ if test "$pngtopnm" = "false"; then
+ AC_MSG_ERROR([Icons cannot be generated, rerun configure with --without-ms-icons or install netpbm])
+ fi
+ pioneers_ms_icons="Icons generated"
+ fi
+else
+ if test $pioneers_is_windows_port = yes; then
+ pioneers_ms_icons="Icons are used"
+ else
+ pioneers_ms_icons="Not needed"
+ fi
+fi
+
+AM_CONDITIONAL(CREATE_WINDOWS_ICON, [test $USE_MAINTAINER_MODE = yes -a "$with_ms_icons" != "no"])
+AM_CONDITIONAL(USE_WINDOWS_ICON, [test $pioneers_is_windows_port = yes])
+
+AM_CONDITIONAL(BUILD_CLIENT, [test "$pioneers_build_client_gtk" = "yes" -o "$pioneers_build_client_ai" = yes])
+AM_CONDITIONAL(BUILD_EDITOR, [test "$pioneers_build_editor" = "yes"])
+AM_CONDITIONAL(BUILD_SERVER, [test "$pioneers_build_server_gtk" = "yes" -o "$pioneers_build_server_console" = "yes"])
+AM_CONDITIONAL(BUILD_META_SERVER, [test "$pioneers_build_metaserver" = "yes"])
+
+if test "$have_scrollkeeper" = "yes"; then
+ AC_DEFINE(HAVE_HELP, 1,
+ [Defined when online help is present])
+ pioneers_help="yes, scrollkeeper";
+fi
+
+AC_CONFIG_FILES([ \
+ Makefile \
+ pioneers.spec \
+ pioneers.nsi \
+ po/Makefile.in \
+ client/help/C/Makefile \
+ ])
+
+AC_OUTPUT
+
+AC_MSG_NOTICE([
+$PACKAGE v$VERSION configuration:
+
+ Source code location: ${srcdir}
+ Install location: ${prefix}
+ Compiler: ${CC}
+ Build graphical client $pioneers_build_client_gtk
+ Build computer player $pioneers_build_client_ai
+ Build game editor $pioneers_build_editor
+ Build graphical server $pioneers_build_server_gtk
+ Build console server $pioneers_build_server_console
+ Build metaserver $pioneers_build_metaserver
+ Build help $pioneers_help
+ Developers only:
+ Use compiler warnings $pioneers_warnings
+ Add debug information $pioneers_debug
+ Enable deprecation checks $pioneers_deprecationChecks
+ Maintainers only:
+ Microsoft Windows icons $pioneers_ms_icons
+])
Added: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog (rev 0)
+++ trunk/debian/changelog 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,6 @@
+maemo-pioneers (0.0.1-1) unstable; urgency=low
+
+ * Initial Release.
+
+ -- Alexey Antipovsky <alexey.antipovsky at gmail.com> Sun, 23 Dec 2007 22:30:28 +0300
+
Added: trunk/debian/compat
===================================================================
--- trunk/debian/compat (rev 0)
+++ trunk/debian/compat 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1 @@
+4
Added: trunk/debian/conffiles.ex
===================================================================
--- trunk/debian/conffiles.ex (rev 0)
+++ trunk/debian/conffiles.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,7 @@
+#
+# If you want to use this conffile, remove all comments and put files that
+# you want dpkg to process here using their absolute pathnames.
+# See the policy manual
+#
+# for example:
+# /etc/maemo-pioneers/maemo-pioneers.conf
Added: trunk/debian/control
===================================================================
--- trunk/debian/control (rev 0)
+++ trunk/debian/control 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,18 @@
+Source: maemo-pioneers
+Section: user/games
+Priority: optional
+Maintainer: Alexey Antipovsky <alexey.antipovsky at gmail.com>
+Build-Depends: debhelper (>= 4.0.0), hildon-libs0, libosso1
+Standards-Version: 3.6.1
+
+Package: maemo-pioneers
+Architecture: armel
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: computer version of the Settlers of Catan board game
+ Pioneers, formerly known as Gnocatan, is an emulation of the Settlers
+ of Catan board game which can be played over the internet.
+ .
+ This is the game client which displays the board and interacts with a
+ player. It connects to a game server that can be local or on a remote
+ host.
+
Added: trunk/debian/copyright
===================================================================
--- trunk/debian/copyright (rev 0)
+++ trunk/debian/copyright 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,12 @@
+This package was debianized by Alexey Antipovsky <alexey.antipovsky at gmail.com> on
+Sun, 23 Dec 2007 22:30:28 +0300.
+
+It was downloaded from <fill in ftp site>
+
+Copyright:
+
+Upstream Author(s): <put author(s) name and email here>
+
+License:
+
+<Must follow here>
Added: trunk/debian/cron.d.ex
===================================================================
--- trunk/debian/cron.d.ex (rev 0)
+++ trunk/debian/cron.d.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,4 @@
+#
+# Regular cron jobs for the maemo-pioneers package
+#
+0 4 * * * root maemo-pioneers_maintenance
Added: trunk/debian/dirs
===================================================================
--- trunk/debian/dirs (rev 0)
+++ trunk/debian/dirs 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,2 @@
+usr/bin
+usr/sbin
Added: trunk/debian/docs
===================================================================
--- trunk/debian/docs (rev 0)
+++ trunk/debian/docs 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,5 @@
+NEWS
+README
+README.Cygwin
+README.MinGW
+TODO
Added: trunk/debian/emacsen-install.ex
===================================================================
--- trunk/debian/emacsen-install.ex (rev 0)
+++ trunk/debian/emacsen-install.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,45 @@
+#! /bin/sh -e
+# /usr/lib/emacsen-common/packages/install/maemo-pioneers
+
+# Written by Jim Van Zandt <jrv at vanzandt.mv.com>, borrowing heavily
+# from the install scripts for gettext by Santiago Vila
+# <sanvila at ctv.es> and octave by Dirk Eddelbuettel <edd at debian.org>.
+
+FLAVOR=$1
+PACKAGE=maemo-pioneers
+
+if [ ${FLAVOR} = emacs ]; then exit 0; fi
+
+echo install/${PACKAGE}: Handling install for emacsen flavor ${FLAVOR}
+
+#FLAVORTEST=`echo $FLAVOR | cut -c-6`
+#if [ ${FLAVORTEST} = xemacs ] ; then
+# SITEFLAG="-no-site-file"
+#else
+# SITEFLAG="--no-site-file"
+#fi
+FLAGS="${SITEFLAG} -q -batch -l path.el -f batch-byte-compile"
+
+ELDIR=/usr/share/emacs/site-lisp/${PACKAGE}
+ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE}
+
+# Install-info-altdir does not actually exist.
+# Maybe somebody will write it.
+if test -x /usr/sbin/install-info-altdir; then
+ echo install/${PACKAGE}: install Info links for ${FLAVOR}
+ install-info-altdir --quiet --section "" "" --dirname=${FLAVOR} /usr/info/${PACKAGE}.info.gz
+fi
+
+install -m 755 -d ${ELCDIR}
+cd ${ELDIR}
+FILES=`echo *.el`
+cp ${FILES} ${ELCDIR}
+cd ${ELCDIR}
+
+cat << EOF > path.el
+(setq load-path (cons "." load-path) byte-compile-warnings nil)
+EOF
+${FLAVOR} ${FLAGS} ${FILES}
+rm -f *.el path.el
+
+exit 0
Added: trunk/debian/emacsen-remove.ex
===================================================================
--- trunk/debian/emacsen-remove.ex (rev 0)
+++ trunk/debian/emacsen-remove.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,15 @@
+#!/bin/sh -e
+# /usr/lib/emacsen-common/packages/remove/maemo-pioneers
+
+FLAVOR=$1
+PACKAGE=maemo-pioneers
+
+if [ ${FLAVOR} != emacs ]; then
+ if test -x /usr/sbin/install-info-altdir; then
+ echo remove/${PACKAGE}: removing Info links for ${FLAVOR}
+ install-info-altdir --quiet --remove --dirname=${FLAVOR} /usr/info/maemo-pioneers.info.gz
+ fi
+
+ echo remove/${PACKAGE}: purging byte-compiled files for ${FLAVOR}
+ rm -rf /usr/share/${FLAVOR}/site-lisp/${PACKAGE}
+fi
Added: trunk/debian/emacsen-startup.ex
===================================================================
--- trunk/debian/emacsen-startup.ex (rev 0)
+++ trunk/debian/emacsen-startup.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,19 @@
+;; -*-emacs-lisp-*-
+;;
+;; Emacs startup file for the Debian maemo-pioneers package
+;;
+;; Originally contributed by Nils Naumann <naumann at unileoben.ac.at>
+;; Modified by Dirk Eddelbuettel <edd at debian.org>
+;; Adapted for dh-make by Jim Van Zandt <jrv at vanzandt.mv.com>
+
+;; The maemo-pioneers package follows the Debian/GNU Linux 'emacsen' policy and
+;; byte-compiles its elisp files for each 'emacs flavor' (emacs19,
+;; xemacs19, emacs20, xemacs20...). The compiled code is then
+;; installed in a subdirectory of the respective site-lisp directory.
+;; We have to add this to the load-path:
+(let ((package-dir (concat "/usr/share/"
+ (symbol-name flavor)
+ "/site-lisp/maemo-pioneers")))
+ (when (file-directory-p package-dir)
+ (setq load-path (cons package-dir load-path))))
+
Added: trunk/debian/init.d.ex
===================================================================
--- trunk/debian/init.d.ex (rev 0)
+++ trunk/debian/init.d.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,74 @@
+#! /bin/sh
+#
+# skeleton example file to build /etc/init.d/ scripts.
+# This file should be used to construct scripts for /etc/init.d.
+#
+# Written by Miquel van Smoorenburg <miquels at cistron.nl>.
+# Modified for Debian
+# by Ian Murdock <imurdock at gnu.ai.mit.edu>.
+#
+# Version: @(#)skeleton 1.9 26-Feb-2001 miquels at cistron.nl
+#
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+DAEMON=/usr/sbin/maemo-pioneers
+NAME=maemo-pioneers
+DESC=maemo-pioneers
+
+test -x $DAEMON || exit 0
+
+# Include maemo-pioneers defaults if available
+if [ -f /etc/default/maemo-pioneers ] ; then
+ . /etc/default/maemo-pioneers
+fi
+
+set -e
+
+case "$1" in
+ start)
+ echo -n "Starting $DESC: "
+ start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
+ --exec $DAEMON -- $DAEMON_OPTS
+ echo "$NAME."
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
+ --exec $DAEMON
+ echo "$NAME."
+ ;;
+ #reload)
+ #
+ # If the daemon can reload its config files on the fly
+ # for example by sending it SIGHUP, do it here.
+ #
+ # If the daemon responds to changes in its config file
+ # directly anyway, make this a do-nothing entry.
+ #
+ # echo "Reloading $DESC configuration files."
+ # start-stop-daemon --stop --signal 1 --quiet --pidfile \
+ # /var/run/$NAME.pid --exec $DAEMON
+ #;;
+ restart|force-reload)
+ #
+ # If the "reload" option is implemented, move the "force-reload"
+ # option to the "reload" entry above. If not, "force-reload" is
+ # just the same as "restart".
+ #
+ echo -n "Restarting $DESC: "
+ start-stop-daemon --stop --quiet --pidfile \
+ /var/run/$NAME.pid --exec $DAEMON
+ sleep 1
+ start-stop-daemon --start --quiet --pidfile \
+ /var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
+ echo "$NAME."
+ ;;
+ *)
+ N=/etc/init.d/$NAME
+ # echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
+ echo "Usage: $N {start|stop|restart|force-reload}" >&2
+ exit 1
+ ;;
+esac
+
+exit 0
Added: trunk/debian/maemo-pioneers-default.ex
===================================================================
--- trunk/debian/maemo-pioneers-default.ex (rev 0)
+++ trunk/debian/maemo-pioneers-default.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,10 @@
+# Defaults for maemo-pioneers initscript
+# sourced by /etc/init.d/maemo-pioneers
+# installed at /etc/default/maemo-pioneers by the maintainer scripts
+
+#
+# This is a POSIX shell fragment
+#
+
+# Additional options that are passed to the Daemon.
+DAEMON_OPTS=""
Added: trunk/debian/maemo-pioneers-doc.docs
===================================================================
--- trunk/debian/maemo-pioneers-doc.docs (rev 0)
+++ trunk/debian/maemo-pioneers-doc.docs 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,2 @@
+#DOCS#
+
Added: trunk/debian/maemo-pioneers-doc.install
===================================================================
--- trunk/debian/maemo-pioneers-doc.install (rev 0)
+++ trunk/debian/maemo-pioneers-doc.install 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,2 @@
+#DOCS#
+
Added: trunk/debian/maemo-pioneers.doc-base.EX
===================================================================
--- trunk/debian/maemo-pioneers.doc-base.EX (rev 0)
+++ trunk/debian/maemo-pioneers.doc-base.EX 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,22 @@
+Document: maemo-pioneers
+Title: Debian maemo-pioneers Manual
+Author: <insert document author here>
+Abstract: This manual describes what maemo-pioneers is
+ and how it can be used to
+ manage online manuals on Debian systems.
+Section: unknown
+
+Format: debiandoc-sgml
+Files: /usr/share/doc/maemo-pioneers/maemo-pioneers.sgml.gz
+
+Format: postscript
+Files: /usr/share/doc/maemo-pioneers/maemo-pioneers.ps.gz
+
+Format: text
+Files: /usr/share/doc/maemo-pioneers/maemo-pioneers.text.gz
+
+Format: HTML
+Index: /usr/share/doc/maemo-pioneers/html/index.html
+Files: /usr/share/doc/maemo-pioneers/html/*.html
+
+
Added: trunk/debian/manpage.1.ex
===================================================================
--- trunk/debian/manpage.1.ex (rev 0)
+++ trunk/debian/manpage.1.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,59 @@
+.\" Hey, EMACS: -*- nroff -*-
+.\" First parameter, NAME, should be all caps
+.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
+.\" other parameters are allowed: see man(7), man(1)
+.TH MAEMO-PIONEERS SECTION "December 23, 2007"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh disable hyphenation
+.\" .hy enable hyphenation
+.\" .ad l left justify
+.\" .ad b justify to both left and right margins
+.\" .nf disable filling
+.\" .fi enable filling
+.\" .br insert line break
+.\" .sp <n> insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+maemo-pioneers \- program to do something
+.SH SYNOPSIS
+.B maemo-pioneers
+.RI [ options ] " files" ...
+.br
+.B bar
+.RI [ options ] " files" ...
+.SH DESCRIPTION
+This manual page documents briefly the
+.B maemo-pioneers
+and
+.B bar
+commands.
+.PP
+.\" TeX users may be more comfortable with the \fB<whatever>\fP and
+.\" \fI<whatever>\fP escape sequences to invode bold face and italics,
+.\" respectively.
+\fBmaemo-pioneers\fP is a program that...
+.SH OPTIONS
+These programs follow the usual GNU command line syntax, with long
+options starting with two dashes (`-').
+A summary of options is included below.
+For a complete description, see the Info files.
+.TP
+.B \-h, \-\-help
+Show summary of options.
+.TP
+.B \-v, \-\-version
+Show version of program.
+.SH SEE ALSO
+.BR bar (1),
+.BR baz (1).
+.br
+The programs are documented fully by
+.IR "The Rise and Fall of a Fooish Bar" ,
+available via the Info system.
+.SH AUTHOR
+maemo-pioneers was written by <upstream author>.
+.PP
+This manual page was written by Alexey Antipovsky <alexey.antipovsky at gmail.com>,
+for the Debian project (but may be used by others).
Added: trunk/debian/manpage.sgml.ex
===================================================================
--- trunk/debian/manpage.sgml.ex (rev 0)
+++ trunk/debian/manpage.sgml.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,156 @@
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+
+<!-- Process this file with docbook-to-man to generate an nroff manual
+ page: `docbook-to-man manpage.sgml > manpage.1'. You may view
+ the manual page with: `docbook-to-man manpage.sgml | nroff -man |
+ less'. A typical entry in a Makefile or Makefile.am is:
+
+manpage.1: manpage.sgml
+ docbook-to-man $< > $@
+
+
+ The docbook-to-man binary is found in the docbook-to-man package.
+ Please remember that if you create the nroff version in one of the
+ debian/rules file targets (such as build), you will need to include
+ docbook-to-man in your Build-Depends control field.
+
+ -->
+
+ <!-- Fill in your name for FIRSTNAME and SURNAME. -->
+ <!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
+ <!ENTITY dhsurname "<surname>SURNAME</surname>">
+ <!-- Please adjust the date whenever revising the manpage. -->
+ <!ENTITY dhdate "<date>December 23, 2007</date>">
+ <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
+ allowed: see man(7), man(1). -->
+ <!ENTITY dhsection "<manvolnum>SECTION</manvolnum>">
+ <!ENTITY dhemail "<email>alexey.antipovsky at gmail.com</email>">
+ <!ENTITY dhusername "Alexey Antipovsky">
+ <!ENTITY dhucpackage "<refentrytitle>MAEMO-PIONEERS</refentrytitle>">
+ <!ENTITY dhpackage "maemo-pioneers">
+
+ <!ENTITY debian "<productname>Debian</productname>">
+ <!ENTITY gnu "<acronym>GNU</acronym>">
+ <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
+]>
+
+<refentry>
+ <refentryinfo>
+ <address>
+ &dhemail;
+ </address>
+ <author>
+ &dhfirstname;
+ &dhsurname;
+ </author>
+ <copyright>
+ <year>2003</year>
+ <holder>&dhusername;</holder>
+ </copyright>
+ &dhdate;
+ </refentryinfo>
+ <refmeta>
+ &dhucpackage;
+
+ &dhsection;
+ </refmeta>
+ <refnamediv>
+ <refname>&dhpackage;</refname>
+
+ <refpurpose>program to do something</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>&dhpackage;</command>
+
+ <arg><option>-e <replaceable>this</replaceable></option></arg>
+
+ <arg><option>--example <replaceable>that</replaceable></option></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This manual page documents briefly the
+ <command>&dhpackage;</command> and <command>bar</command>
+ commands.</para>
+
+ <para>This manual page was written for the &debian; distribution
+ because the original program does not have a manual page.
+ Instead, it has documentation in the &gnu;
+ <application>Info</application> format; see below.</para>
+
+ <para><command>&dhpackage;</command> is a program that...</para>
+
+ </refsect1>
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <para>These programs follow the usual &gnu; command line syntax,
+ with long options starting with two dashes (`-'). A summary of
+ options is included below. For a complete description, see the
+ <application>Info</application> files.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h</option>
+ <option>--help</option>
+ </term>
+ <listitem>
+ <para>Show summary of options.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-v</option>
+ <option>--version</option>
+ </term>
+ <listitem>
+ <para>Show version of program.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>SEE ALSO</title>
+
+ <para>bar (1), baz (1).</para>
+
+ <para>The programs are documented fully by <citetitle>The Rise and
+ Fall of a Fooish Bar</citetitle> available via the
+ <application>Info</application> system.</para>
+ </refsect1>
+ <refsect1>
+ <title>AUTHOR</title>
+
+ <para>This manual page was written by &dhusername; &dhemail; for
+ the &debian; system (but may be used by others). Permission is
+ granted to copy, distribute and/or modify this document under
+ the terms of the &gnu; General Public License, Version 2 any
+ later version published by the Free Software Foundation.
+ </para>
+ <para>
+ On Debian systems, the complete text of the GNU General Public
+ License can be found in /usr/share/common-licenses/GPL.
+ </para>
+
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
+
+
Added: trunk/debian/manpage.xml.ex
===================================================================
--- trunk/debian/manpage.xml.ex (rev 0)
+++ trunk/debian/manpage.xml.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,148 @@
+<?xml version='1.0' encoding='ISO-8859-1'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
+"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
+
+<!--
+
+Process this file with an XSLT processor: `xsltproc \
+-''-nonet /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
+manpages/docbook.xsl manpage.dbk'. A manual page
+<package>.<section> will be generated. You may view the
+manual page with: nroff -man <package>.<section> | less'. A
+typical entry in a Makefile or Makefile.am is:
+
+DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
+manpages/docbook.xsl
+XP=xsltproc -''-nonet
+
+manpage.1: manpage.dbk
+ $(XP) $(DB2MAN) $<
+
+The xsltproc binary is found in the xsltproc package. The
+XSL files are in docbook-xsl. Please remember that if you
+create the nroff version in one of the debian/rules file
+targets (such as build), you will need to include xsltproc
+and docbook-xsl in your Build-Depends control field.
+
+-->
+
+ <!-- Fill in your name for FIRSTNAME and SURNAME. -->
+ <!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
+ <!ENTITY dhsurname "<surname>SURNAME</surname>">
+ <!-- Please adjust the date whenever revising the manpage. -->
+ <!ENTITY dhdate "<date>December 23, 2007</date>">
+ <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
+ allowed: see man(7), man(1). -->
+ <!ENTITY dhsection "<manvolnum>SECTION</manvolnum>">
+ <!ENTITY dhemail "<email>alexey.antipovsky at gmail.com</email>">
+ <!ENTITY dhusername "Alexey Antipovsky">
+ <!ENTITY dhucpackage "<refentrytitle>MAEMO-PIONEERS</refentrytitle>">
+ <!ENTITY dhpackage "maemo-pioneers">
+
+ <!ENTITY debian "<productname>Debian</productname>">
+ <!ENTITY gnu "<acronym>GNU</acronym>">
+ <!ENTITY gpl "&gnu; <acronym>GPL</acronym>">
+]>
+
+<refentry>
+ <refentryinfo>
+ <address>
+ &dhemail;
+ </address>
+ <author>
+ &dhfirstname;
+ &dhsurname;
+ </author>
+ <copyright>
+ <year>2003</year>
+ <holder>&dhusername;</holder>
+ </copyright>
+ &dhdate;
+ </refentryinfo>
+ <refmeta>
+ &dhucpackage;
+
+ &dhsection;
+ </refmeta>
+ <refnamediv>
+ <refname>&dhpackage;</refname>
+
+ <refpurpose>program to do something</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>&dhpackage;</command>
+
+ <arg><option>-e <replaceable>this</replaceable></option></arg>
+
+ <arg><option>--example <replaceable>that</replaceable></option></arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>This manual page documents briefly the
+ <command>&dhpackage;</command> and <command>bar</command>
+ commands.</para>
+
+ <para>This manual page was written for the &debian; distribution
+ because the original program does not have a manual page.
+ Instead, it has documentation in the &gnu;
+ <application>Info</application> format; see below.</para>
+
+ <para><command>&dhpackage;</command> is a program that...</para>
+
+ </refsect1>
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <para>These programs follow the usual &gnu; command line syntax,
+ with long options starting with two dashes (`-'). A summary of
+ options is included below. For a complete description, see the
+ <application>Info</application> files.</para>
+
+ <variablelist>
+ <varlistentry>
+ <term><option>-h</option>
+ <option>--help</option>
+ </term>
+ <listitem>
+ <para>Show summary of options.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>-v</option>
+ <option>--version</option>
+ </term>
+ <listitem>
+ <para>Show version of program.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+ <refsect1>
+ <title>SEE ALSO</title>
+
+ <para>bar (1), baz (1).</para>
+
+ <para>The programs are documented fully by <citetitle>The Rise and
+ Fall of a Fooish Bar</citetitle> available via the
+ <application>Info</application> system.</para>
+ </refsect1>
+ <refsect1>
+ <title>AUTHOR</title>
+
+ <para>This manual page was written by &dhusername; &dhemail; for
+ the &debian; system (but may be used by others). Permission is
+ granted to copy, distribute and/or modify this document under
+ the terms of the &gnu; General Public License, Version 2 any
+ later version published by the Free Software Foundation.
+ </para>
+ <para>
+ On Debian systems, the complete text of the GNU General Public
+ License can be found in /usr/share/common-licenses/GPL.
+ </para>
+
+ </refsect1>
+</refentry>
+
Added: trunk/debian/menu.ex
===================================================================
--- trunk/debian/menu.ex (rev 0)
+++ trunk/debian/menu.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,2 @@
+?package(maemo-pioneers):needs="X11|text|vc|wm" section="Apps/see-menu-manual"\
+ title="maemo-pioneers" command="/usr/bin/maemo-pioneers"
Added: trunk/debian/postinst.ex
===================================================================
--- trunk/debian/postinst.ex (rev 0)
+++ trunk/debian/postinst.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,42 @@
+#! /bin/sh
+# postinst script for maemo-pioneers
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postinst> `configure' <most-recently-configured-version>
+# * <old-postinst> `abort-upgrade' <new version>
+# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+# <new-version>
+# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+# <failed-install-package> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+#
+
+case "$1" in
+ configure)
+
+ ;;
+
+ abort-upgrade|abort-remove|abort-deconfigure)
+
+ ;;
+
+ *)
+ echo "postinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
Added: trunk/debian/postrm.ex
===================================================================
--- trunk/debian/postrm.ex (rev 0)
+++ trunk/debian/postrm.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,38 @@
+#! /bin/sh
+# postrm script for maemo-pioneers
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <postrm> `remove'
+# * <postrm> `purge'
+# * <old-postrm> `upgrade' <new-version>
+# * <new-postrm> `failed-upgrade' <old-version>
+# * <new-postrm> `abort-install'
+# * <new-postrm> `abort-install' <old-version>
+# * <new-postrm> `abort-upgrade' <old-version>
+# * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+
+
+ ;;
+
+ *)
+ echo "postrm called with unknown argument \`$1'" >&2
+ exit 1
+
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
Added: trunk/debian/preinst.ex
===================================================================
--- trunk/debian/preinst.ex (rev 0)
+++ trunk/debian/preinst.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,44 @@
+#! /bin/sh
+# preinst script for maemo-pioneers
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <new-preinst> `install'
+# * <new-preinst> `install' <old-version>
+# * <new-preinst> `upgrade' <old-version>
+# * <old-preinst> `abort-upgrade' <new-version>
+#
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ install|upgrade)
+# if [ "$1" = "upgrade" ]
+# then
+# start-stop-daemon --stop --quiet --oknodo \
+# --pidfile /var/run/maemo-pioneers.pid \
+# --exec /usr/sbin/maemo-pioneers 2>/dev/null || true
+# fi
+ ;;
+
+ abort-upgrade)
+ ;;
+
+ *)
+ echo "preinst called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
Added: trunk/debian/prerm.ex
===================================================================
--- trunk/debian/prerm.ex (rev 0)
+++ trunk/debian/prerm.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,39 @@
+#! /bin/sh
+# prerm script for maemo-pioneers
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+# * <prerm> `remove'
+# * <old-prerm> `upgrade' <new-version>
+# * <new-prerm> `failed-upgrade' <old-version>
+# * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
+# * <deconfigured's-prerm> `deconfigure' `in-favour'
+# <package-being-installed> <version> `removing'
+# <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+ remove|upgrade|deconfigure)
+# install-info --quiet --remove /usr/info/maemo-pioneers.info.gz
+ ;;
+ failed-upgrade)
+ ;;
+ *)
+ echo "prerm called with unknown argument \`$1'" >&2
+ exit 1
+ ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
+
+
Added: trunk/debian/rules
===================================================================
--- trunk/debian/rules (rev 0)
+++ trunk/debian/rules 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,137 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+#
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+#
+# Modified to make a template file for a multi-binary package with separated
+# build-arch and build-indep targets by Bill Allombert 2001
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# This has to be exported to make some magic below work.
+export DH_OPTIONS
+
+# These are used for cross-compiling and for saving the configure script
+# from having to guess our platform (since we know it already)
+DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+
+config.status: configure
+ dh_testdir
+ # Add here commands to configure the package.
+ CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
+
+
+#Architecture
+build: build-arch build-indep
+
+build-arch: build-arch-stamp
+build-arch-stamp: config.status
+
+ # Add here commands to compile the arch part of the package.
+ #$(MAKE)
+ touch build-arch-stamp
+
+build-indep: build-indep-stamp
+build-indep-stamp: config.status
+
+ # Add here commands to compile the indep part of the package.
+ #$(MAKE) doc
+ touch build-indep-stamp
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-arch-stamp build-indep-stamp #CONFIGURE-STAMP#
+
+ # Add here commands to clean up after the build process.
+ -$(MAKE) distclean
+ifneq "$(wildcard /usr/share/misc/config.sub)" ""
+ cp -f /usr/share/misc/config.sub config.sub
+endif
+ifneq "$(wildcard /usr/share/misc/config.guess)" ""
+ cp -f /usr/share/misc/config.guess config.guess
+endif
+
+
+ dh_clean
+
+install: install-indep install-arch
+install-indep:
+ dh_testdir
+ dh_testroot
+ dh_clean -k -i
+ dh_installdirs -i
+
+ # Add here commands to install the indep part of the package into
+ # debian/<package>-doc.
+ #INSTALLDOC#
+
+ dh_install -i
+
+install-arch:
+ dh_testdir
+ dh_testroot
+ dh_clean -k -s
+ dh_installdirs -s
+
+ # Add here commands to install the arch part of the package into
+ # debian/tmp.
+ $(MAKE) install DESTDIR=$(CURDIR)/debian/maemo-pioneers
+
+ dh_install -s
+# Must not depend on anything. This is to be called by
+# binary-arch/binary-indep
+# in another 'make' thread.
+binary-common:
+ dh_testdir
+ dh_testroot
+ dh_installchangelogs ChangeLog
+ dh_installdocs
+ dh_installexamples
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+# dh_perl
+# dh_python
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+# Build architecture independant packages using the common target.
+binary-indep: build-indep install-indep
+ $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
+
+# Build architecture dependant packages using the common target.
+binary-arch: build-arch install-arch
+ $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
+
+binary: binary-arch binary-indep
+.PHONY: build clean binary-indep binary-arch binary install install-indep install-arch
Property changes on: trunk/debian/rules
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/debian/watch.ex
===================================================================
--- trunk/debian/watch.ex (rev 0)
+++ trunk/debian/watch.ex 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,6 @@
+# Example watch control file for uscan
+# Rename this file to "watch" and then you can run the "uscan" command
+# to check for upstream updates and more.
+# Site Directory Pattern Version Script
+version=2
+sunsite.unc.edu /pub/Linux/Incoming maemo-pioneers-(.*)\.tar\.gz debian uupdate
Added: trunk/docs/Makefile.am
===================================================================
--- trunk/docs/Makefile.am (rev 0)
+++ trunk/docs/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,20 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+man_MANS += docs/pioneers.6 docs/pioneers-server-gtk.6 docs/pioneers-server-console.6 docs/pioneersai.6 docs/pioneers-meta-server.6
Added: trunk/docs/pioneers-meta-server.6
===================================================================
--- trunk/docs/pioneers-meta-server.6 (rev 0)
+++ trunk/docs/pioneers-meta-server.6 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,80 @@
+.TH pioneers-meta-server 6 "May 9, 2006" "pioneers"
+.SH NAME
+pioneers-meta-server \- meta game server for Pioneers
+
+.SH SYNOPSIS
+.B pioneers-meta-server
+.RI [ options ]
+
+.SH DESCRIPTION
+.B Pioneers
+is an implementation of the popular, award-winning "Settlers of Catan"
+board game. It uses a client/server model for networked play. This program
+provides a piece of network infrastructure that helps match pioneers clients to
+pioneers servers. Casual players of pioneers probably do not need to run this
+program.
+
+.SH OPTIONS
+
+.TP
+.B \-h
+Print a short help text and exit.
+
+.TP
+.B \-d
+Run in daemon mode.
+
+.TP
+.BI \-r " location"
+.RI "Redirect to " location "."
+
+.TP
+.BI \-s " hostname"
+.RI "Use " hostname " as hostname when creating servers."
+
+.TP
+.BI \-p " from" \- "to"
+.RI "Use ports in the range " from "-" to " (inclusive) for started servers."
+It is advised not to include port 5555 in the range. (See BUGS below.)
+
+.SH ENVIRONMENT
+The default settings of the meta-server can be influenced with the
+following three environment variables:
+.TP
+.B PIONEERS_META_SERVER
+The hostname the meta-server will use when creating new games. This should
+be a hostname that can be resolved by all clients that will connect.
+.TP
+.B PIONEERS_SERVER_CONSOLE
+.RB "The path to " pioneers-server-console "."
+If it is not set, the default installation path will be used.
+.TP
+.B PIONEERS_DIR
+The path to the game definition files.
+If it is not set, the default installation path will be used.
+
+.SH FILES
+.B /usr/share/games/pioneers/*.game
+.RS
+Game definitions
+.RE
+
+.SH BUGS
+.I pioneers-server-console
+uses port 5555 for its admin connection. This means that only the first server
+started from the meta-server will actually succeed in binding to that. For all
+subsequent servers, the admin socket fails to open, and thus cannot be
+connected to.
+
+.SH AUTHOR
+This manual page was written by Jeff Breidenbach <jab at debian.org>,
+and updated by Roland Clobus <rclobus at bigfoot.com> and
+Bas Wijnen <shevek at fmf.nl>.
+Pioneers was written by Dave Cole <dave at dccs.com.au>, Andy Heroff
+<aheroff at mediaone.net>, and Roman Hodek <roman at hodek.net>, with
+contributions from many other developers on the Internet; see the
+AUTHORS file in the pioneers distribution or the help->about dialog in one of
+the graphical programs for a complete list of contributing authors.
+
+.SH SEE ALSO
+.BR pioneers(6) ", " pioneers-server-gtk(6) ", " pioneers-server-console(6)
Added: trunk/docs/pioneers-server-console.6
===================================================================
--- trunk/docs/pioneers-server-console.6 (rev 0)
+++ trunk/docs/pioneers-server-console.6 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,150 @@
+.TH pioneers-server-console 6 "April 9, 2006" "pioneers"
+.SH NAME
+pioneers-server-console \- command-line game server for Pioneers
+
+.SH SYNOPSIS
+.B pioneers-server-console
+[
+.BI \-a " port"
+] [
+.BI \-c " AI count"
+] [
+.BI \-g " game title"
+]
+.if n .ti +5n
+[
+.BI \-k " seconds"
+] [
+.BI \-m " metaserver"
+] [
+.BI \-n " hostname"
+]
+.if n .ti +5n
+[
+.BI \-P " player count"
+] [
+.BI \-p " port"
+] [
+.BI \-R " [0|1|2]"
+] [
+.BI \-r
+] [
+.BI \-s
+]
+.if n .ti +5n
+[
+.BI \-t " minutes"
+] [
+.BI \-T " [0|1]"
+] [
+.BI \-v " points"
+] [
+.BI \-x
+]
+
+.SH DESCRIPTION
+This manual page documents briefly the
+.B pioneers-server-console
+command.
+.PP
+.B Pioneers
+is an implementation of the popular, award-winning "Settlers of Catan"
+board game for the GNOME desktop environment. It uses a client/server
+model for networked play of between two and eight players. This program
+provides a console-only server that \fBpioneers\fP clients can connect
+to.
+
+.SH OPTIONS
+.TP 12
+.BI \-a " port"
+Listen for administrative commands on port \fIport\fP.
+.TP
+.BI \-c " num"
+Start up \fInum\fP computer players.
+.TP
+.BI \-g " game title"
+Load the ruleset specified by \fIgame title\fP. The title can be found in
+the *.game files. You need quotes for titles with spaces.
+.TP
+.BI \-k " secs"
+Automatically stop the server if no one has connected after \fIsecs\fP
+seconds.
+.TP
+.BI \-m " metaserver"
+Register this server with the metaserver at the specified address.
+.TP
+.BI \-n " hostname"
+Use this hostname instead of the hostname reported by
+.BR hostname(1) .
+.TP
+.BI \-P " num"
+Start a game for \fInum\fP total players (including computer players).
+.TP
+.BI \-p " port"
+Use port \fIport\fP for player connections.
+.TP
+.B \-R [0|1|2]
+"Sevens rule": Specify gameplay behavior when a player rolls a seven. A
+value of \fI0\fP (the default) means that rolling a seven always moves
+the robber. A value of \fI1\fP requires the player to re-roll if a
+seven is rolled on the first two turns. A value of \fI2\fP means the
+player always re-rolls.
+.TP
+.B \-r
+Register with a meta server. The meta server to use can be overriden
+with the
+.B \-m
+option. Default meta sever: pioneers.debian.net
+.TP
+.B \-s
+Don't start the game immediately; wait for a command on the admin port
+.RB ( \-a )
+instead.
+.TP
+.B -T [0|1]
+Choose a terrain type: \fI0\fP for the default, or \fI1\fP for random
+terrain.
+.TP
+.BI \-t " mins"
+Tournament mode: add AI players after \fImins\fP minutes.
+.TP
+.BI \-v " points"
+Specify the number of "victory points" required to win the game.
+.TP
+.B \-x
+Automatically exit after a player has won.
+
+.SH ENVIRONMENT
+The default settings of the server can be influenced with the
+following three environment variables:
+.TP
+.B PIONEERS_META_SERVER
+The hostname of the meta-server when no meta-server is specified on the
+command-line.
+.TP
+.B PIONEERS_SERVER_NAME
+The hostname of the server.
+If it is not set, the hostname is determined by
+.BR hostname(1) .
+.TP
+.B PIONEERS_DIR
+The path to the game definition files.
+If it is not set, the default installation path will be used.
+
+.SH FILES
+.B /usr/share/games/pioneers/*.game
+.RS
+Game definitions
+.RE
+
+.SH AUTHOR
+This manual page was written by Steve Langasek <vorlon at debian.org>,
+and updated by Roland Clobus <rclobus at bigfoot.com>.
+Pioneers was written by Dave Cole <dave at dccs.com.au>, Andy Heroff
+<aheroff at mediaone.net>, and Roman Hodek <roman at hodek.net>, with
+contributions from many other developers on the Internet; see the
+AUTHORS file in the pioneers distribution for a complete list of
+contributing authors.
+
+.SH SEE ALSO
+.BR pioneers(6) ", " pioneers-server-gtk(6) ", " pioneersai(6) ", " hostname(1)
Added: trunk/docs/pioneers-server-gtk.6
===================================================================
--- trunk/docs/pioneers-server-gtk.6 (rev 0)
+++ trunk/docs/pioneers-server-gtk.6 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,68 @@
+.TH pioneers-server-gtk 6 "April 9, 2006" "pioneers"
+.SH NAME
+pioneers-server-gtk \- graphical game server for Pioneers
+
+.SH SYNOPSIS
+.B pioneers-server-gtk
+.RI [ options ]
+
+.SH DESCRIPTION
+This manual page documents briefly the
+.B pioneers-server-gtk
+command.
+.PP
+.B Pioneers
+is an implementation of the popular, award-winning "Settlers of Catan"
+board game for the GNOME desktop environment. It uses a client/server
+model for networked play of between two and eight players. This program
+provides a GUI-configurable stand-alone server which you connect to
+from
+.B pioneers
+itself.
+
+.SH OPTIONS
+Pioneers accepts the standard GTK+/GNOME commandline options.
+
+.SH ENVIRONMENT
+The default settings of the server can be influenced with the
+following three environment variables:
+.TP
+.B PIONEERS_META_SERVER
+The hostname of the meta-server when no meta-server is specified in the
+user interface. (The settings file takes precedence)
+.TP
+.B PIONEERS_SERVER_NAME
+The hostname of the server.
+If it is not set, the hostname is determined by
+.BR hostname(1) .
+(The settings file takes precedence)
+.TP
+.B PIONEERS_DIR
+The path to the game definition files.
+If it is not set, the default installation path will be used.
+
+.SH FILES
+.B /usr/share/games/pioneers/*.game
+.RS
+Game definitions
+.RE
+.B /usr/share/pixmaps/pioneers-server.png
+.RS
+Game icon
+.RE
+.B $HOME/.config/pioneers-server
+.RS
+Saved settings
+.RE
+
+.SH AUTHOR
+This manual page was written by Steve Langasek <vorlon at debian.org>,
+and updated by Roland Clobus <rclobus at bigfoot.com>.
+Pioneers was written by Dave Cole <dave at dccs.com.au>, Andy Heroff
+<aheroff at mediaone.net>, and Roman Hodek <roman at hodek.net>, with
+contributions from many other developers on the Internet; see the
+AUTHORS file in the pioneers distribution for a complete list of
+contributing authors.
+
+.SH SEE ALSO
+.BR pioneers(6) ", " pioneers-server-console(6) ", " pioneersai(6)
Added: trunk/docs/pioneers.6
===================================================================
--- trunk/docs/pioneers.6 (rev 0)
+++ trunk/docs/pioneers.6 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,102 @@
+.TH pioneers 6 "April 9, 2006" "pioneers"
+.SH NAME
+pioneers \- network implementation of Settlers of Catan
+
+.SH SYNOPSIS
+.B pioneers
+[
+.BI \-s " server"
+] [
+.BI \-\-server " server"
+] [
+.BI \-p " port"
+] [
+.BI \-\-port " port"
+] [
+.BI \-n " name"
+] [
+.BI \-\-name " name"
+]
+
+.SH DESCRIPTION
+This manual page documents briefly the
+.B pioneers
+command.
+.PP
+.B Pioneers
+is an implementation of the popular, award-winning "Settlers of Catan"
+board game for the GNOME desktop environment. It uses a client/server
+model for networked play of between two and eight players. You will
+need to connect to a machine running either \fBpioneers-server-gtk\fP
+or \fBpioneers-server-console\fP to play. An AI client, \fBpioneersai\fP,
+is also available.
+
+.SH OPTIONS
+Pioneers accepts the standard GTK+/GNOME commandline options,
+and the following options:
+.TP
+.BI "\-s, \-\-server" " server"
+Hostname of the server
+.TP
+.BI "\-p, \-\-port" " port"
+Portname of the server
+.TP
+.BI "\-n, \-\-name" " name"
+Name of the player
+
+.PP
+When the options are provided, the client automatically quits when
+the connection is broken.
+
+.SH ENVIRONMENT
+The default settings can be influenced with the
+following environment variable:
+.TP
+.B PIONEERS_META_SERVER
+The hostname of the meta-server.
+If it is not set, the default meta-server will be used.
+
+.SH DEVELOPERS AND TRANSLATORS
+With the commandline option
+.B \-\-language
+.I code
+the values of the environment variables
+.B LANGUAGE
+and
+.B LC_ALL
+can be overriden. The
+.I code
+should be one of the 2-letter language code pioneers understands.
+
+.SH FILES
+.B /usr/share/games/pioneers/themes/*
+.RS
+Themes for display of the map. Each theme goes in a separate subdirectory.
+.RE
+.B /usr/share/pixmaps/pioneers/*
+.RS
+Icons
+.RE
+.B /usr/share/pixmaps/pioneers.png
+.RS
+Main icon
+.RE
+.B $HOME/.config/pioneers
+.RS
+Saved settings
+.RE
+
+.SH AUTHOR
+This manual page was written by Steve Langasek <vorlon at debian.org>,
+and updated by Roland Clobus <rclobus at bigfoot.com>.
+Pioneers was written by Dave Cole <dave at dccs.com.au>, Andy Heroff
+<aheroff at mediaone.net>, and Roman Hodek <roman at hodek.net>, with
+contributions from many other developers on the Internet; see the
+AUTHORS file in the pioneers distribution for a complete list of
+contributing authors.
+
+.SH SEE ALSO
+More detailed user documentation is available in the online help.
+.PP
+.BR pioneers-server-gtk(6) ", " pioneers-server-console(6) ", "
+.B pioneersai(6)
Added: trunk/docs/pioneersai.6
===================================================================
--- trunk/docs/pioneersai.6 (rev 0)
+++ trunk/docs/pioneersai.6 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,78 @@
+.TH pioneersai 6 "March 5, 2005" "pioneers"
+.SH NAME
+pioneersai \- AI player for Pioneers
+
+.SH SYNOPSIS
+.B pioneersai
+[
+.BI \-s " server"
+] [
+.BI \-p " port"
+] [
+.BI \-n " name"
+]
+.if n .ti +5n
+[
+.BI \-a " algorithm"
+] [
+.BI \-t " milliseconds"
+] [
+.BI \-c
+]
+
+.SH DESCRIPTION
+This manual page documents briefly the
+.B pioneersai
+command.
+.PP
+.B Pioneers
+is an emulation of the Settlers of Catan board game which can
+be played over the internet. This is an AI player
+implementation that can take part in Pioneers games.
+
+.SH OPTIONS
+.TP 12
+.BI \-s " server"
+Connect to a pioneers game running on \fIserver\fP.
+.TP
+.BI \-p " port"
+Connect to a pioneers game running on \fIport\fP.
+.TP
+.BI \-n " name"
+Specify \fIname\fP of AI player. Leave absent for a random name.
+.TP
+.BI \-a " algorithm"
+Specify \fIalgorithm\fP of AI player. The only possible value
+is "greedy"
+.TP
+.BI \-t " milliseconds"
+Time to wait between turns, in \fImilliseconds\fP. Default is 1000.
+.TP
+.BI \-c
+Do not chat with other players.
+
+.SH ENVIRONMENT
+The default settings of the AI can be influenced with the
+following environment variable:
+.TP
+.B PIONEERS_DIR
+The path to the file with player names.
+If it is not set, the default installation path will be used.
+
+.SH FILES
+.B /usr/share/games/pioneers/computer_names
+.RS
+A list of names the AI can use
+.RE
+
+.SH AUTHOR
+This manual page was written by Jeff Breidenbach <jab at debian.org>,
+and updated by Roland Clobus <rclobus at bigfoot.com>.
+Pioneers was written by Dave Cole <dave at dccs.com.au>, Andy Heroff
+<aheroff at mediaone.net>, and Roman Hodek <roman at hodek.net>, with
+contributions from many other developers on the Internet; see the
+AUTHORS file in the pioneers distribution for a complete list of
+contributing authors.
+
+.SH SEE ALSO
+.BR pioneers(6) ", " pioneers-server-gtk(6) ", " pioneers-server-console(6)
Added: trunk/editor/Makefile.am
===================================================================
--- trunk/editor/Makefile.am (rev 0)
+++ trunk/editor/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,22 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+if HAVE_GNOME
+include editor/gtk/Makefile.am
+endif
Added: trunk/editor/gtk/Makefile.am
===================================================================
--- trunk/editor/gtk/Makefile.am (rev 0)
+++ trunk/editor/gtk/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,45 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+# Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+icon_DATA += editor/gtk/pioneers-editor.png
+desktop_DATA += editor/gtk/pioneers-editor.desktop
+bin_PROGRAMS += pioneers-editor
+
+pioneers_editor_CPPFLAGS = $(gtk_cflags)
+
+pioneers_editor_SOURCES = \
+ editor/gtk/editor.c \
+ editor/gtk/game-devcards.c \
+ editor/gtk/game-devcards.h \
+ editor/gtk/game-buildings.c \
+ editor/gtk/game-buildings.h \
+ editor/gtk/game-resources.c \
+ editor/gtk/game-resources.h
+
+pioneers_editor_LDADD = $(gtk_libs)
+
+if USE_WINDOWS_ICON
+pioneers_editor_LDADD += editor/gtk/pioneers-editor.res
+CLEANFILES += editor/gtk/pioneers-editor.res
+endif
+
+windows_resources_output += editor/gtk/pioneers-editor.ico
+windows_resources_input += editor/gtk/pioneers-editor.rc
Added: trunk/editor/gtk/editor.c
===================================================================
--- trunk/editor/gtk/editor.c (rev 0)
+++ trunk/editor/gtk/editor.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,1207 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 2005 Brian Wellington
+ * Copyright (C) 2005,2006 Roland Clobus
+ * Copyright (C) 2005,2006 Bas Wijnen
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "config.h"
+#include "version.h"
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#include <string.h>
+#include "authors.h"
+#include "aboutbox.h"
+#include "config-gnome.h"
+#include "game.h"
+#include "game-settings.h"
+#include "game-rules.h"
+#include "game-devcards.h"
+#include "game-buildings.h"
+#include "game-resources.h"
+#include "guimap.h"
+#include "theme.h"
+#include "colors.h"
+#include "common_gtk.h"
+#include "cards.h"
+
+#define MAINICON_FILE "pioneers-editor.png"
+
+#define MAP_WIDTH 550 /* default map width */
+#define MAP_HEIGHT 400 /* default map height */
+
+static GtkWidget *toplevel;
+static gchar *default_game;
+static GameParams *params;
+static gchar *window_title;
+static gchar *open_filename;
+static GameSettings *game_settings;
+static GameRules *game_rules;
+static GameDevCards *game_devcards;
+static GameBuildings *game_buildings;
+static GameResources *game_resources;
+static GtkWidget *terrain_menu;
+static GtkWidget *roll_menu;
+static GtkWidget *roll_numbers[12 + 1];
+static GtkCheckMenuItem *shuffle_tile;
+static GtkWidget *port_menu;
+static GtkWidget *port_directions[6];
+static GtkWidget *hresize_buttons[2];
+static GtkWidget *vresize_buttons[2];
+static GuiMap *gmap;
+static Hex *current_hex;
+
+static const gchar *terrain_names[] = {
+ /* Use an unique shortcut key for each resource */
+ N_("_Hill"),
+ /* Use an unique shortcut key for each resource */
+ N_("_Field"),
+ /* Use an unique shortcut key for each resource */
+ N_("_Mountain"),
+ /* Use an unique shortcut key for each resource */
+ N_("_Pasture"),
+ /* Use an unique shortcut key for each resource */
+ N_("F_orest"),
+ /* Use an unique shortcut key for each resource */
+ N_("_Desert"),
+ /* Use an unique shortcut key for each resource */
+ N_("_Sea"),
+ /* Use an unique shortcut key for each resource */
+ N_("_Gold"),
+ /* Use an unique shortcut key for each resource */
+ N_("_None")
+};
+
+static const gchar *port_names[] = {
+ /* Use an unique shortcut key for each port type */
+ N_("_Brick (2:1)"),
+ /* Use an unique shortcut key for each port type */
+ N_("_Grain (2:1)"),
+ /* Use an unique shortcut key for each port type */
+ N_("_Ore (2:1)"),
+ /* Use an unique shortcut key for each port type */
+ N_("_Wool (2:1)"),
+ /* Use an unique shortcut key for each port type */
+ N_("_Lumber (2:1)"),
+ /* Use an unique shortcut key for each port type */
+ N_("_None"),
+ /* Use an unique shortcut key for each port type */
+ N_("_Any (3:1)")
+};
+
+static const gchar *port_direction_names[] = {
+ /* East */
+ N_("East|E"),
+ /* North east */
+ N_("North East|NE"),
+ /* North west */
+ N_("North West|NW"),
+ /* West */
+ N_("West|W"),
+ /* South west */
+ N_("South West|SW"),
+ /* South east */
+ N_("South East|SE")
+};
+
+static void check_vp_cb(GObject * caller, gpointer main_window);
+
+static void error_dialog(const char *fmt, ...)
+{
+ GtkWidget *dialog;
+ gchar *buf;
+ va_list ap;
+
+ va_start(ap, fmt);
+ buf = g_strdup_vprintf(fmt, ap);
+ va_end(ap);
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(toplevel),
+ GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE, "%s", buf);
+ g_free(buf);
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+}
+
+static void clear_hex(Hex * hex)
+{
+ g_return_if_fail(hex != NULL);
+ hex->terrain = LAST_TERRAIN;
+ hex->resource = NO_RESOURCE;
+ hex->chit_pos = -1;
+ hex->roll = 0;
+ hex->shuffle = TRUE;
+}
+
+static void fill_map(Map * map)
+{
+ gint x, y;
+
+ for (y = 0; y < map->y_size; y++) {
+ for (x = 0; x < map->x_size; x++) {
+ if (x == map->x_size - 1 && y % 2 == 1)
+ continue;
+ if (map->grid[y][x] != NULL)
+ continue;
+ clear_hex(map_add_hex(map, x, y));
+ }
+ }
+}
+
+static void canonicalize_map(Map * map)
+{
+ GArray *chits;
+ Hex *hex;
+ gint x, y;
+ gint sequence_number;
+
+ chits = g_array_new(FALSE, FALSE, sizeof(gint));
+ sequence_number = 0;
+ for (y = 0; y < map->y_size; y++) {
+ for (x = 0; x < map->x_size; x++) {
+ hex = map->grid[y][x];
+ if (hex == NULL)
+ continue;
+ if (hex->roll > 0) {
+ g_array_append_val(chits, hex->roll);
+ hex->chit_pos = sequence_number++;
+ } else if (hex->terrain == DESERT_TERRAIN) {
+ hex->chit_pos = sequence_number++;
+ }
+ }
+ }
+ if (map->chits != NULL)
+ g_array_free(map->chits, TRUE);
+ map->chits = chits;
+}
+
+static gboolean terrain_has_chit(Terrain terrain)
+{
+ if (terrain == HILL_TERRAIN || terrain == FIELD_TERRAIN ||
+ terrain == MOUNTAIN_TERRAIN || terrain == PASTURE_TERRAIN ||
+ terrain == FOREST_TERRAIN || terrain == GOLD_TERRAIN)
+ return TRUE;
+ return FALSE;
+}
+
+static void build_map_resize(GtkWidget * table, gint row, gint col,
+ GtkOrientation dir, GtkWidget ** buttons,
+ GCallback resize_callback)
+{
+ static const char *symbols[] = { "+", "--" };
+ static gint values[] = { +1, -1 };
+ GtkWidget *box;
+ gint i;
+
+ if (dir == GTK_ORIENTATION_VERTICAL)
+ box = gtk_vbox_new(FALSE, 0);
+ else
+ box = gtk_hbox_new(FALSE, 0);
+
+ gtk_box_pack_start(GTK_BOX(box), gtk_fixed_new(), TRUE, TRUE, 0);
+
+ for (i = 0; i < 2; i++) {
+ buttons[i] = gtk_button_new_with_label(symbols[i]);
+ gtk_box_pack_start(GTK_BOX(box), buttons[i], FALSE, TRUE,
+ 0);
+ g_signal_connect(G_OBJECT(buttons[i]), "clicked",
+ resize_callback,
+ GINT_TO_POINTER(values[i]));
+ }
+
+ gtk_box_pack_start(GTK_BOX(box), gtk_fixed_new(), TRUE, TRUE, 0);
+
+ gtk_table_attach(GTK_TABLE(table), box, row, row + 1, col, col + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+}
+
+static void scale_map(GuiMap * gmap)
+{
+ guimap_scale_to_size(gmap,
+ gmap->area->allocation.width,
+ gmap->area->allocation.height);
+ gtk_widget_queue_draw(gmap->area);
+}
+
+static gint button_press_map_cb(GtkWidget * area, GdkEventButton * event,
+ gpointer user_data)
+{
+ GuiMap *gmap = user_data;
+ GtkWidget *menu;
+ Hex *adjacent;
+ gboolean port_ok;
+ gint num_ports;
+ gint i;
+
+ if (area->window == NULL || gmap->map == NULL)
+ return FALSE;
+
+ current_hex = guimap_find_hex(gmap, event->x, event->y);
+ if (current_hex == NULL)
+ return TRUE;
+
+ menu = NULL;
+ if (event->button == 1)
+ menu = terrain_menu;
+ else if (current_hex->roll > 0) {
+ menu = roll_menu;
+ for (i = 2; i <= 12; i++) {
+ if (roll_numbers[i] != NULL)
+ gtk_check_menu_item_set_active
+ (GTK_CHECK_MENU_ITEM(roll_numbers[i]),
+ current_hex->roll == i);
+ }
+ gtk_check_menu_item_set_active(shuffle_tile,
+ current_hex->shuffle);
+ } else if (current_hex->terrain == SEA_TERRAIN) {
+ num_ports = 0;
+ for (i = 0; i < 6; i++) {
+ adjacent = hex_in_direction(gmap->map,
+ current_hex, i);
+ port_ok = FALSE;
+ if (adjacent != NULL &&
+ adjacent->terrain != LAST_TERRAIN &&
+ adjacent->terrain != SEA_TERRAIN) {
+ num_ports++;
+ if (current_hex->resource != NO_RESOURCE)
+ port_ok = TRUE;
+ }
+ gtk_widget_set_sensitive(port_directions[i],
+ port_ok);
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM
+ (port_directions
+ [i]),
+ current_hex->
+ facing == i
+ && port_ok);
+ }
+
+ if (num_ports > 0)
+ menu = port_menu;
+ }
+
+ if (menu != NULL)
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
+ event->button, event->time);
+
+ return TRUE;
+}
+
+static gint key_press_map_cb(GtkWidget * area, GdkEventKey * event,
+ gpointer user_data)
+{
+ static gint last_x, last_y;
+ static gchar *last_key;
+ GuiMap *gmap = user_data;
+ gint x, y;
+ gboolean plus10;
+
+ if (area->window == NULL || gmap->map == NULL)
+ return FALSE;
+
+ gtk_widget_get_pointer(area, &x, &y);
+
+ current_hex = guimap_find_hex(gmap, x, y);
+ if (current_hex == NULL || !terrain_has_chit(current_hex->terrain))
+ return TRUE;
+
+ if (last_x == x && last_y == y && strcmp(last_key, "1") == 0)
+ plus10 = TRUE;
+ else
+ plus10 = FALSE;
+
+ if (!plus10 && strcmp(event->string, "2") == 0)
+ current_hex->roll = 2;
+ else if (strcmp(event->string, "3") == 0)
+ current_hex->roll = 3;
+ else if (strcmp(event->string, "4") == 0)
+ current_hex->roll = 4;
+ else if (strcmp(event->string, "5") == 0)
+ current_hex->roll = 5;
+ else if (strcmp(event->string, "6") == 0)
+ current_hex->roll = 6;
+ else if (strcmp(event->string, "8") == 0)
+ current_hex->roll = 8;
+ else if (strcmp(event->string, "9") == 0)
+ current_hex->roll = 9;
+ else if (plus10 && strcmp(event->string, "0") == 0)
+ current_hex->roll = 10;
+ else if (plus10 && strcmp(event->string, "1") == 0)
+ current_hex->roll = 11;
+ else if (plus10 && strcmp(event->string, "2") == 0)
+ current_hex->roll = 12;
+ guimap_draw_hex(gmap, current_hex);
+ last_x = x;
+ last_y = y;
+ g_free(last_key);
+ last_key = g_strdup(event->string);
+ return TRUE;
+}
+
+static void post_change(gint * size, GtkWidget ** buttons, gint amt)
+{
+ *size += amt;
+ gtk_widget_set_sensitive(buttons[0], *size < MAP_SIZE);
+ gtk_widget_set_sensitive(buttons[1], *size > 1);
+ fill_map(gmap->map);
+ scale_map(gmap);
+ guimap_display(gmap);
+}
+
+static void change_height(G_GNUC_UNUSED GtkWidget * menu,
+ gpointer user_data)
+{
+ if (GPOINTER_TO_INT(user_data) < 0) {
+ gint x;
+ for (x = 0; x < gmap->map->x_size; x++)
+ clear_hex(gmap->map->
+ grid[gmap->map->y_size - 1][x]);
+ }
+ post_change(&gmap->map->y_size, vresize_buttons,
+ GPOINTER_TO_INT(user_data));
+}
+
+static void change_width(G_GNUC_UNUSED GtkWidget * menu,
+ gpointer user_data)
+{
+ if (GPOINTER_TO_INT(user_data) < 0) {
+ gint x, y;
+ for (y = 0; y < gmap->map->y_size; y++) {
+ if (y % 2 == 0)
+ x = gmap->map->x_size - 1;
+ else
+ x = gmap->map->x_size - 2;
+ clear_hex(gmap->map->grid[y][x]);
+ }
+ }
+ post_change(&gmap->map->x_size, hresize_buttons,
+ GPOINTER_TO_INT(user_data));
+}
+
+static GtkWidget *build_map(void)
+{
+ GtkWidget *table;
+ GtkWidget *area;
+
+ table = gtk_table_new(2, 2, FALSE);
+
+ gmap = guimap_new();
+ guimap_set_show_no_setup_nodes(gmap, TRUE);
+ area = guimap_build_drawingarea(gmap, MAP_WIDTH, MAP_HEIGHT);
+
+ GTK_WIDGET_SET_FLAGS(area, GTK_CAN_FOCUS);
+ gtk_widget_add_events(gmap->area, GDK_ENTER_NOTIFY_MASK
+ | GDK_BUTTON_PRESS_MASK
+ | GDK_KEY_PRESS_MASK);
+ g_signal_connect(G_OBJECT(gmap->area), "enter_notify_event",
+ G_CALLBACK(gtk_widget_grab_focus), gmap);
+ g_signal_connect(G_OBJECT(gmap->area), "button_press_event",
+ G_CALLBACK(button_press_map_cb), gmap);
+ g_signal_connect(G_OBJECT(gmap->area), "key_press_event",
+ G_CALLBACK(key_press_map_cb), gmap);
+ gtk_table_attach(GTK_TABLE(table), gmap->area, 0, 1, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0,
+ 0);
+
+ build_map_resize(table, 0, 1, GTK_ORIENTATION_HORIZONTAL,
+ vresize_buttons, G_CALLBACK(change_height));
+ build_map_resize(table, 1, 0, GTK_ORIENTATION_VERTICAL,
+ hresize_buttons, G_CALLBACK(change_width));
+
+ return table;
+}
+
+static gint select_terrain_cb(G_GNUC_UNUSED GtkWidget * menu,
+ gpointer user_data)
+{
+ Terrain terrain = GPOINTER_TO_INT(user_data);
+ Hex *adjacent;
+ gint i;
+
+ if (terrain == current_hex->terrain)
+ return TRUE;
+
+ current_hex->terrain = terrain;
+ if (terrain_has_chit(terrain)) {
+ if (current_hex->roll == 0)
+ current_hex->roll = 2;
+ } else
+ current_hex->roll = 0;
+
+ if (terrain != SEA_TERRAIN)
+ current_hex->resource = NO_RESOURCE;
+ if (terrain == SEA_TERRAIN || terrain == LAST_TERRAIN) {
+ for (i = 0; i < 6; i++) {
+ adjacent =
+ hex_in_direction(gmap->map, current_hex, i);
+ if (adjacent != NULL
+ && adjacent->resource != NO_RESOURCE
+ && adjacent->facing == (i + 3) % 6) {
+ adjacent->resource = NO_RESOURCE;
+ adjacent->facing = 0;
+ guimap_draw_hex(gmap, adjacent);
+ }
+ }
+ }
+ guimap_draw_hex(gmap, current_hex);
+
+ /* XXX Since some edges may have changed, we need to redisplay */
+ guimap_display(gmap);
+
+ return TRUE;
+}
+
+static GtkWidget *build_terrain_menu(void)
+{
+ gint i;
+ GtkWidget *menu;
+ GtkWidget *item;
+ GdkPixmap *pixmap;
+ GtkWidget *image;
+ MapTheme *theme = theme_get_current();
+
+ menu = gtk_menu_new();
+
+ for (i = 0; i <= LAST_TERRAIN; i++) {
+ item =
+ gtk_image_menu_item_new_with_mnemonic(gettext
+ (terrain_names
+ [i]));
+
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ g_signal_connect(G_OBJECT(item), "activate",
+ G_CALLBACK(select_terrain_cb),
+ GINT_TO_POINTER(i));
+
+ pixmap = theme->terrain_tiles[i];
+ if (i == LAST_TERRAIN || pixmap == NULL)
+ continue;
+
+ image = gtk_image_new_from_pixmap(pixmap, NULL);
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
+ image);
+ }
+
+ gtk_widget_show_all(menu);
+ return menu;
+}
+
+static void select_roll_cb(GtkCheckMenuItem * menu_item,
+ gpointer user_data)
+{
+ if (gtk_check_menu_item_get_active(menu_item)) {
+ current_hex->roll = GPOINTER_TO_INT(user_data);
+ guimap_draw_hex(gmap, current_hex);
+ }
+}
+
+static void select_shuffle_cb(GtkCheckMenuItem * menu_item,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ current_hex->shuffle = gtk_check_menu_item_get_active(menu_item);
+}
+
+static GtkWidget *build_roll_menu(void)
+{
+ GtkWidget *menu;
+ gint i;
+ gchar buffer[128];
+ MapTheme *theme = theme_get_current();
+ THEME_COLOR tcolor;
+ GdkColor *color;
+ GtkWidget *item;
+ GtkWidget *label;
+
+ menu = gtk_menu_new();
+
+ for (i = 2; i <= 12; i++) {
+ if (i == 7)
+ continue;
+
+ tcolor = (i == 6 || i == 8) ? TC_CHIP_H_FG : TC_CHIP_FG;
+ color = &theme->colors[tcolor].color;
+ sprintf(buffer,
+ "<span foreground=\"#%04x%04x%04x\">%d</span>",
+ color->red, color->green, color->blue, i);
+
+ item = gtk_check_menu_item_new();
+ label = gtk_label_new("");
+ gtk_label_set_markup(GTK_LABEL(label), buffer);
+ gtk_container_add(GTK_CONTAINER(item), label);
+
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ g_signal_connect(G_OBJECT(item), "toggled",
+ G_CALLBACK(select_roll_cb),
+ GINT_TO_POINTER(i));
+ gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM
+ (item), TRUE);
+ roll_numbers[i] = item;
+ }
+
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu),
+ gtk_separator_menu_item_new());
+
+ item = gtk_check_menu_item_new_with_label(_("Shuffle"));
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ g_signal_connect(G_OBJECT(item), "toggled",
+ G_CALLBACK(select_shuffle_cb), NULL);
+ shuffle_tile = GTK_CHECK_MENU_ITEM(item);
+
+ gtk_widget_show_all(menu);
+ return menu;
+}
+
+static gint select_port_resource_cb(G_GNUC_UNUSED GtkWidget * menu,
+ gpointer user_data)
+{
+ gint i;
+
+ if (current_hex->resource == NO_RESOURCE) {
+ for (i = 0; i < 6; i++) {
+ Hex *adjacent;
+
+ adjacent = hex_in_direction(gmap->map,
+ current_hex, i);
+ if (adjacent != NULL &&
+ adjacent->terrain != LAST_TERRAIN &&
+ adjacent->terrain != SEA_TERRAIN) {
+ current_hex->facing = i;
+ break;
+ }
+ }
+ }
+ current_hex->resource = GPOINTER_TO_INT(user_data);
+ guimap_draw_hex(gmap, current_hex);
+ return TRUE;
+}
+
+static void select_port_direction_cb(GtkCheckMenuItem * menu_item,
+ gpointer user_data)
+{
+ if (gtk_check_menu_item_get_active(menu_item)) {
+ current_hex->facing = GPOINTER_TO_INT(user_data);
+ guimap_draw_hex(gmap, current_hex);
+ }
+}
+
+static GtkWidget *build_port_menu(void)
+{
+ gint i;
+ GtkWidget *item;
+ GdkPixmap *pixmap;
+ GtkWidget *image;
+ GtkWidget *menu;
+ MapTheme *theme = theme_get_current();
+
+ menu = gtk_menu_new();
+
+ for (i = 0; i <= ANY_RESOURCE; i++) {
+ item =
+ gtk_image_menu_item_new_with_mnemonic(gettext
+ (port_names[i]));
+
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ g_signal_connect(G_OBJECT(item), "activate",
+ G_CALLBACK(select_port_resource_cb),
+ GINT_TO_POINTER(i));
+
+ pixmap = theme->port_tiles[i];
+ if (i >= NO_RESOURCE || pixmap == NULL)
+ continue;
+
+ image = gtk_image_new_from_pixmap(pixmap, NULL);
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item),
+ image);
+ }
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu),
+ gtk_separator_menu_item_new());
+ for (i = 0; i < 6; i++) {
+ item =
+ gtk_check_menu_item_new_with_label(Q_
+ (port_direction_names
+ [i]));
+ gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM
+ (item), TRUE);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
+ g_signal_connect(G_OBJECT(item), "toggled",
+ G_CALLBACK(select_port_direction_cb),
+ GINT_TO_POINTER(i));
+ port_directions[i] = item;
+ }
+ gtk_widget_show_all(menu);
+
+ return menu;
+}
+
+static GtkWidget *build_frame(GtkWidget * parent, const gchar * title,
+ GtkWidget * element)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+
+ frame = gtk_frame_new(title);
+ gtk_box_pack_start(GTK_BOX(parent), frame, FALSE, TRUE, 0);
+
+ vbox = gtk_vbox_new(FALSE, 3);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
+
+ gtk_box_pack_start(GTK_BOX(vbox), element, FALSE, TRUE, 0);
+
+ return frame;
+}
+
+static GtkWidget *build_settings(GtkWindow * main_window)
+{
+ GtkWidget *vbox, *hbox, *lvbox, *rvbox;
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+
+ hbox = gtk_hbox_new(TRUE, 10);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+
+ lvbox = gtk_vbox_new(FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox), lvbox, FALSE, TRUE, 0);
+
+ rvbox = gtk_vbox_new(FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox), rvbox, FALSE, TRUE, 0);
+
+ game_settings = GAMESETTINGS(game_settings_new(TRUE));
+ game_rules = GAMERULES(game_rules_new());
+ game_resources = GAMERESOURCES(game_resources_new());
+ game_devcards = GAMEDEVCARDS(game_devcards_new());
+ game_buildings = GAMEBUILDINGS(game_buildings_new());
+
+ build_frame(lvbox, _("Game Parameters"),
+ GTK_WIDGET(game_settings));
+ build_frame(lvbox, _("Rules"), GTK_WIDGET(game_rules));
+ build_frame(lvbox, _("Resources"), GTK_WIDGET(game_resources));
+ build_frame(rvbox, _("Buildings"), GTK_WIDGET(game_buildings));
+ build_frame(rvbox, _("Development Cards"),
+ GTK_WIDGET(game_devcards));
+
+ g_signal_connect(G_OBJECT(game_settings), "check",
+ G_CALLBACK(check_vp_cb), main_window);
+ return vbox;
+}
+
+static void set_window_title(const gchar * title)
+{
+ gchar *str;
+ g_free(window_title);
+ if (title == NULL) {
+ title = "Untitled";
+ window_title = NULL;
+ } else
+ window_title = g_strdup(title);
+ str = g_strdup_printf("%s: %s", _("Pioneers Editor"), title);
+
+ gtk_window_set_title(GTK_WINDOW(toplevel), str);
+ g_free(str);
+}
+
+static void apply_params(GameParams * params)
+{
+ gint i;
+
+ set_window_title(params->title);
+
+ game_rules_set_random_terrain(game_rules, params->random_terrain);
+ game_rules_set_sevens_rule(game_rules, params->sevens_rule);
+ /* Do not disable the pirate rule if currently no ships are present */
+ game_rules_set_use_pirate(game_rules, params->use_pirate, 1);
+ game_rules_set_strict_trade(game_rules, params->strict_trade);
+ game_rules_set_domestic_trade(game_rules, params->domestic_trade);
+
+ game_settings_set_players(game_settings, params->num_players);
+ game_settings_set_victory_points(game_settings,
+ params->victory_points);
+
+ game_resources_set_num_resources(game_resources,
+ params->resource_count);
+
+ for (i = 0; i < NUM_DEVEL_TYPES; i++)
+ game_devcards_set_num_cards(game_devcards, i,
+ params->num_develop_type[i]);
+
+ for (i = 1; i < NUM_BUILD_TYPES; i++)
+ game_buildings_set_num_buildings(game_buildings, i,
+ params->
+ num_build_type[i]);
+
+ gmap->map = params->map;
+
+}
+
+static GameParams *get_params(void)
+{
+ GameParams *params = params_new();
+ gint i;
+
+ params->title = g_strdup(window_title);
+
+ params->random_terrain = game_rules_get_random_terrain(game_rules);
+ params->sevens_rule = game_rules_get_sevens_rule(game_rules);
+ params->use_pirate = game_rules_get_use_pirate(game_rules);
+ params->strict_trade = game_rules_get_strict_trade(game_rules);
+ params->domestic_trade = game_rules_get_domestic_trade(game_rules);
+
+ params->num_players = game_settings_get_players(game_settings);
+ params->victory_points =
+ game_settings_get_victory_points(game_settings);
+
+ params->resource_count =
+ game_resources_get_num_resources(game_resources);
+
+ for (i = 0; i < NUM_DEVEL_TYPES; i++)
+ params->num_develop_type[i] =
+ game_devcards_get_num_cards(game_devcards, i);
+
+ for (i = 1; i < NUM_BUILD_TYPES; i++)
+ params->num_build_type[i] =
+ game_buildings_get_num_buildings(game_buildings, i);
+
+ params->map = gmap->map;
+
+ return params;
+}
+
+static void load_game(const gchar * file, gboolean is_reload)
+{
+ const gchar *gamefile;
+ GameParams *new_params;
+ gchar *new_filename;
+
+ if (file == NULL)
+ gamefile = default_game;
+ else
+ gamefile = file;
+
+ new_params = params_load_file(gamefile);
+ if (new_params == NULL) {
+ error_dialog(_("Failed to load '%s'"), file);
+ return;
+ }
+
+ if (file == NULL) {
+ g_free(new_params->title);
+ new_params->title = g_strdup("Untitled");
+ map_free(new_params->map);
+ new_params->map = map_new();
+ new_params->map->x_size = 6;
+ new_params->map->y_size = 6;
+ new_params->map->chits =
+ g_array_new(FALSE, FALSE, sizeof(gint));
+ new_filename = NULL;
+ } else {
+ new_filename = g_strdup(file);
+ config_set_string("editor/last-game", new_filename);
+ }
+
+ guimap_reset(gmap);
+ if (params != NULL)
+ params_free(params);
+ params = new_params;
+ apply_params(params);
+ if (open_filename != NULL)
+ g_free(open_filename);
+ open_filename = new_filename;
+ map_move_robber(gmap->map, -1, -1);
+ fill_map(gmap->map);
+ if (is_reload) {
+ scale_map(gmap);
+ guimap_display(gmap);
+ }
+}
+
+static void save_game(const gchar * file)
+{
+ params = get_params();
+ canonicalize_map(gmap->map);
+ if (!params_write_file(params, file))
+ error_dialog(_("Failed to save to '%s'"), file);
+ else
+ config_set_string("editor/last-game", file);
+ fill_map(gmap->map);
+}
+
+static void new_game_menu_cb(void)
+{
+ load_game(NULL, TRUE);
+}
+
+static void load_game_menu_cb(void)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_file_chooser_dialog_new(_("Open Game"),
+ GTK_WINDOW(toplevel),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN,
+ GTK_RESPONSE_OK, NULL);
+ gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
+ default_game);
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
+ char *file;
+ file =
+ gtk_file_chooser_get_filename(GTK_FILE_CHOOSER
+ (dialog));
+ load_game(file, TRUE);
+ g_free(file);
+ scale_map(gmap);
+ guimap_display(gmap);
+ }
+ gtk_widget_destroy(dialog);
+}
+
+static void save_as_menu_cb(void)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_file_chooser_dialog_new(_("Save as..."),
+ GTK_WINDOW(toplevel),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE,
+ GTK_RESPONSE_ACCEPT, NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog),
+ GTK_RESPONSE_ACCEPT);
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+ char *file;
+ file =
+ gtk_file_chooser_get_filename(GTK_FILE_CHOOSER
+ (dialog));
+ save_game(file);
+ if (open_filename == NULL)
+ open_filename = file;
+ else
+ g_free(file);
+ }
+ gtk_widget_destroy(dialog);
+}
+
+static void save_game_menu_cb(void)
+{
+ if (open_filename == NULL)
+ save_as_menu_cb();
+ else
+ save_game(open_filename);
+}
+
+static void change_title_menu_cb(void)
+{
+ GtkWidget *dialog, *vbox, *hbox, *label, *entry;
+
+ dialog = gtk_dialog_new_with_buttons(_("Change Title"),
+ GTK_WINDOW(toplevel),
+ GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK, NULL);
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog),
+ GTK_RESPONSE_OK);
+ g_signal_connect(G_OBJECT(dialog), "destroy",
+ G_CALLBACK(gtk_widget_destroyed), &dialog);
+ gtk_widget_realize(dialog);
+ gdk_window_set_functions(dialog->window,
+ GDK_FUNC_MOVE | GDK_FUNC_CLOSE);
+
+ vbox = GTK_DIALOG(dialog)->vbox;
+
+ hbox = gtk_hbox_new(FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+
+ label = gtk_label_new(_("New Title:"));
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+
+ entry = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(entry), 60);
+ gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
+ if (window_title != NULL)
+ gtk_entry_set_text(GTK_ENTRY(entry), window_title);
+
+ gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+
+ gtk_widget_show_all(dialog);
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
+ set_window_title(gtk_entry_get_text(GTK_ENTRY(entry)));
+ gtk_widget_destroy(dialog);
+}
+
+static void check_vp_cb(G_GNUC_UNUSED GObject * caller,
+ gpointer main_window)
+{
+ GameParams *params;
+
+ params = get_params();
+ check_victory_points(params, main_window);
+}
+
+static void exit_cb(void)
+{
+ gtk_main_quit();
+}
+
+#ifdef HAVE_HELP
+/* Commented out, until the help is written
+static void contents_menu_cb(void)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new(GTK_WINDOW(toplevel),
+ GTK_DIALOG_MODAL |
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_CLOSE,
+ _("There is no help"));
+ gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+}
+*/
+#endif
+
+static void about_menu_cb(void)
+{
+ const gchar *authors[] = {
+ AUTHORLIST
+ };
+
+ aboutbox_display(_("Pioneers Game Editor"), authors);
+}
+
+static GtkActionEntry entries[] = {
+ {"FileMenu", NULL, N_("_File"), NULL, NULL, NULL},
+ {"HelpMenu", NULL, N_("_Help"), NULL, NULL, NULL},
+
+ {"New", GTK_STOCK_NEW, N_("_New"), "<control>N",
+ N_("Create a new game"), new_game_menu_cb},
+ {"Open", GTK_STOCK_OPEN, N_("_Open..."), "<control>O",
+ N_("Open an existing game"), load_game_menu_cb},
+ {"Save", GTK_STOCK_SAVE, N_("_Save"), "<control>S",
+ N_("Save game"), save_game_menu_cb},
+ {"SaveAs", GTK_STOCK_SAVE_AS, N_("Save _As..."),
+ "<control><shift>S",
+ N_("Save as"), save_as_menu_cb},
+ {"ChangeTitle", NULL, N_("_Change title"), "<control>T",
+ N_("Change game title"), change_title_menu_cb},
+ {"CheckVP", GTK_STOCK_APPLY, N_("_Check Victory Point Target"),
+ NULL,
+ N_("Check whether the game can be won"), G_CALLBACK(check_vp_cb)},
+ {"Quit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q",
+ N_("Quit"), exit_cb},
+
+#ifdef HAVE_HELP
+ /* Disable this item, until the help is written
+ {"Contents", GTK_STOCK_HELP, N_("_Contents"), "F1",
+ N_("Contents"), contents_menu_cb},
+ */
+#endif
+ {"About", NULL, N_("_About Pioneers Editor"), NULL,
+ N_("Information about Pioneers Editor"), about_menu_cb}
+};
+
+/* *INDENT-OFF* */
+static const char *ui_description =
+"<ui>"
+" <menubar name='MainMenu'>"
+" <menu action='FileMenu'>"
+" <menuitem action='New'/>"
+" <menuitem action='Open'/>"
+" <menuitem action='Save'/>"
+" <menuitem action='SaveAs'/>"
+" <separator/>"
+" <menuitem action='CheckVP'/>"
+" <menuitem action='ChangeTitle'/>"
+" <separator/>"
+" <menuitem action='Quit'/>"
+" </menu>"
+" <menu action='HelpMenu'>"
+#ifdef HAVE_HELP
+/* Disable this menu item, until the help is written
+" <menuitem action='Contents'/>"
+" <separator/>"
+*/
+#endif
+" <menuitem action='About'/>"
+" </menu>"
+" </menubar>"
+"</ui>";
+/* *INDENT-ON* */
+
+gchar **filenames;
+gboolean show_version = FALSE;
+
+static GOptionEntry commandline_entries[] = {
+ {G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY,
+ &filenames,
+ /* Long help for commandline option (editor): filename */
+ N_("Open this file"),
+ /* Commandline option for editor: filename */
+ N_("filename")},
+ {"version", '\0', 0, G_OPTION_ARG_NONE, &show_version,
+ /* Commandline option of editor: version */
+ N_("Show version information"), NULL},
+ {NULL, '\0', 0, 0, NULL, NULL, NULL}
+};
+
+int main(int argc, char *argv[])
+{
+ gchar *filename;
+ gboolean default_used;
+ GtkWidget *notebook;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ GtkWidget *vbox;
+ GtkWidget *menubar;
+ GtkAccelGroup *accel_group;
+ GError *error = NULL;
+ gchar *icon_file;
+ GOptionContext *context;
+
+ default_game = g_build_filename(get_pioneers_dir(), "default.game",
+ NULL);
+
+ /* Gtk+ handles the locale, we must bind the translations */
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+ bind_textdomain_codeset(PACKAGE, "UTF-8");
+
+ /* Long description in the command line: --help */
+ context =
+ g_option_context_new(_("- Editor for games of Pioneers"));
+ g_option_context_add_main_entries(context, commandline_entries,
+ GETTEXT_PACKAGE);
+ g_option_context_add_group(context, gtk_get_option_group(TRUE));
+ g_option_context_parse(context, &argc, &argv, &error);
+ if (error != NULL) {
+ g_print("%s\n", error->message);
+ g_error_free(error);
+ return 1;
+ }
+ if (show_version) {
+ g_print(_("Pioneers version:"));
+ g_print(" ");
+ g_print(FULL_VERSION);
+ g_print("\n");
+ return 0;
+ }
+
+ if (filenames != NULL)
+ filename = g_strdup(filenames[0]);
+ else
+ filename = NULL;
+
+ toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ g_signal_connect(G_OBJECT(toplevel), "delete_event",
+ G_CALLBACK(exit_cb), NULL);
+
+ action_group = gtk_action_group_new("MenuActions");
+ gtk_action_group_set_translation_domain(action_group, PACKAGE);
+ gtk_action_group_add_actions(action_group, entries,
+ G_N_ELEMENTS(entries), toplevel);
+
+ ui_manager = gtk_ui_manager_new();
+ gtk_ui_manager_insert_action_group(ui_manager, action_group, 0);
+
+ accel_group = gtk_ui_manager_get_accel_group(ui_manager);
+ gtk_window_add_accel_group(GTK_WINDOW(toplevel), accel_group);
+
+ error = NULL;
+ if (!gtk_ui_manager_add_ui_from_string(ui_manager, ui_description,
+ -1, &error)) {
+ g_message(_("Building menus failed: %s"), error->message);
+ g_error_free(error);
+ return 1;
+ }
+
+ config_init("pioneers-editor");
+
+ icon_file =
+ g_build_filename(DATADIR, "pixmaps", MAINICON_FILE, NULL);
+ if (g_file_test(icon_file, G_FILE_TEST_EXISTS)) {
+ gtk_window_set_default_icon_from_file(icon_file, NULL);
+ } else {
+ /* Missing pixmap, main icon file */
+ g_warning("Pixmap not found: %s", icon_file);
+ }
+ g_free(icon_file);
+
+ themes_init();
+ colors_init();
+
+ notebook = gtk_notebook_new();
+ gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_TOP);
+
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook), build_map(),
+ gtk_label_new(_("Map")));
+
+ gtk_notebook_append_page(GTK_NOTEBOOK(notebook),
+ build_settings(GTK_WINDOW(toplevel)),
+ gtk_label_new(_("Settings")));
+
+ terrain_menu = build_terrain_menu();
+ roll_menu = build_roll_menu();
+ port_menu = build_port_menu();
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(toplevel), vbox);
+
+ menubar = gtk_ui_manager_get_widget(ui_manager, "/MainMenu");
+ gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
+
+ if (filename == NULL) {
+ filename =
+ config_get_string("editor/last-game", &default_used);
+ if (default_used
+ || !g_file_test(filename, G_FILE_TEST_EXISTS)) {
+ g_free(filename);
+ filename = NULL;
+ }
+ }
+
+ load_game(filename, FALSE);
+ g_free(filename);
+ if (params == NULL)
+ return 1;
+
+ gtk_widget_show_all(toplevel);
+
+ gtk_main();
+
+ config_finish();
+ guimap_delete(gmap);
+ g_free(default_game);
+
+ g_option_context_free(context);
+ return 0;
+}
Added: trunk/editor/gtk/game-buildings.c
===================================================================
--- trunk/editor/gtk/game-buildings.c (rev 0)
+++ trunk/editor/gtk/game-buildings.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,89 @@
+#include "config.h"
+#include "game.h"
+#include <gtk/gtktable.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkspinbutton.h>
+#include <string.h>
+#include <glib.h>
+
+#include "game-buildings.h"
+
+static const gchar *building_names[NUM_BUILD_TYPES] = {
+ NULL, N_("Road"), N_("Bridge"), N_("Ship"), N_("Settlement"),
+ N_("City"), N_("City Wall")
+};
+
+static void game_buildings_init(GameBuildings * gb);
+
+/* Register the class */
+GType game_buildings_get_type(void)
+{
+ static GType gb_type = 0;
+
+ if (!gb_type) {
+ static const GTypeInfo gb_info = {
+ sizeof(GameBuildingsClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(GameBuildings),
+ 0,
+ (GInstanceInitFunc) game_buildings_init,
+ NULL
+ };
+ gb_type =
+ g_type_register_static(GTK_TYPE_TABLE, "GameBuildings",
+ &gb_info, 0);
+ }
+ return gb_type;
+}
+
+/* Build the composite widget */
+static void game_buildings_init(GameBuildings * gb)
+{
+ GtkWidget *label;
+ GtkWidget *spin;
+ GtkObject *adjustment;
+ gint row;
+
+ gtk_table_resize(GTK_TABLE(gb), NUM_BUILD_TYPES - 1, 2);
+ gtk_table_set_row_spacings(GTK_TABLE(gb), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(gb), 5);
+ gtk_table_set_homogeneous(GTK_TABLE(gb), TRUE);
+
+ for (row = 1; row < NUM_BUILD_TYPES; row++) {
+ label = gtk_label_new(gettext(building_names[row]));
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_table_attach_defaults(GTK_TABLE(gb), label,
+ 0, 1, row - 1, row);
+
+ adjustment = gtk_adjustment_new(0, 0, 100, 1, 1, 1);
+ spin =
+ gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 1, 0);
+ gtk_entry_set_alignment(GTK_ENTRY(spin), 1.0);
+ gtk_table_attach_defaults(GTK_TABLE(gb), spin,
+ 1, 2, row - 1, row);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin), TRUE);
+ gb->num_buildings[row] = GTK_SPIN_BUTTON(spin);
+ }
+}
+
+/* Create a new instance of the widget */
+GtkWidget *game_buildings_new(void)
+{
+ return GTK_WIDGET(g_object_new(game_buildings_get_type(), NULL));
+}
+
+void game_buildings_set_num_buildings(GameBuildings * gb, gint type,
+ gint num)
+{
+ gtk_spin_button_set_value(gb->num_buildings[type], num);
+}
+
+gint game_buildings_get_num_buildings(GameBuildings * gb, gint type)
+{
+ return gtk_spin_button_get_value(gb->num_buildings[type]);
+}
Added: trunk/editor/gtk/game-buildings.h
===================================================================
--- trunk/editor/gtk/game-buildings.h (rev 0)
+++ trunk/editor/gtk/game-buildings.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,36 @@
+#ifndef __GAMEBUILDINGS_H__
+#define __GAMEBUILDINGS_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtktable.h>
+
+G_BEGIN_DECLS
+#define GAMEBUILDINGS_TYPE (game_buildings_get_type ())
+#define GAMEBUILDINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMEBUILDINGS_TYPE, GameBuildings))
+#define GAMEBUILDINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMEBUILDINGS_TYPE, GameBuildingsClass))
+#define IS_GAMEBUILDINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMEBUILDINGS_TYPE))
+#define IS_GAMEBUILDINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMEBUILDINGS_TYPE))
+typedef struct _GameBuildings GameBuildings;
+typedef struct _GameBuildingsClass GameBuildingsClass;
+
+struct _GameBuildings {
+ GtkTable table;
+
+ GtkSpinButton *num_buildings[NUM_BUILD_TYPES];
+};
+
+struct _GameBuildingsClass {
+ GtkTableClass parent_class;
+};
+
+GType game_buildings_get_type(void);
+GtkWidget *game_buildings_new(void);
+
+void game_buildings_set_num_buildings(GameBuildings * gb, gint type,
+ gint num);
+gint game_buildings_get_num_buildings(GameBuildings * gb, gint type);
+
+G_END_DECLS
+#endif /* __GAMEBUILDINGS_H__ */
Added: trunk/editor/gtk/game-devcards.c
===================================================================
--- trunk/editor/gtk/game-devcards.c (rev 0)
+++ trunk/editor/gtk/game-devcards.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,90 @@
+#include "config.h"
+#include "game.h"
+#include <gtk/gtktable.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkspinbutton.h>
+#include <string.h>
+#include <glib.h>
+
+#include "game-devcards.h"
+
+static const gchar *devcard_names[NUM_DEVEL_TYPES] = {
+ N_("Road Building"), N_("Monopoly"), N_("Year of Plenty"),
+ N_("Chapel"), N_("Pioneer University"),
+ N_("Governor's House"), N_("Library"), N_("Market"),
+ N_("Soldier")
+};
+
+static void game_devcards_init(GameDevCards * gd);
+
+/* Register the class */
+GType game_devcards_get_type(void)
+{
+ static GType gd_type = 0;
+
+ if (!gd_type) {
+ static const GTypeInfo gd_info = {
+ sizeof(GameDevCardsClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(GameDevCards),
+ 0,
+ (GInstanceInitFunc) game_devcards_init,
+ NULL
+ };
+ gd_type =
+ g_type_register_static(GTK_TYPE_TABLE, "GameDevCards",
+ &gd_info, 0);
+ }
+ return gd_type;
+}
+
+/* Build the composite widget */
+static void game_devcards_init(GameDevCards * gd)
+{
+ GtkWidget *label;
+ GtkWidget *spin;
+ GtkObject *adjustment;
+ gint row;
+
+ gtk_table_resize(GTK_TABLE(gd), NUM_DEVEL_TYPES, 2);
+ gtk_table_set_row_spacings(GTK_TABLE(gd), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(gd), 5);
+ gtk_table_set_homogeneous(GTK_TABLE(gd), TRUE);
+
+ for (row = 0; row < NUM_DEVEL_TYPES; row++) {
+ label = gtk_label_new(gettext(devcard_names[row]));
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_table_attach_defaults(GTK_TABLE(gd), label,
+ 0, 1, row, row + 1);
+
+ adjustment = gtk_adjustment_new(0, 0, 100, 1, 1, 1);
+ spin =
+ gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 1, 0);
+ gtk_entry_set_alignment(GTK_ENTRY(spin), 1.0);
+ gtk_table_attach_defaults(GTK_TABLE(gd), spin,
+ 1, 2, row, row + 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin), TRUE);
+ gd->num_cards[row] = GTK_SPIN_BUTTON(spin);
+ }
+}
+
+/* Create a new instance of the widget */
+GtkWidget *game_devcards_new(void)
+{
+ return GTK_WIDGET(g_object_new(game_devcards_get_type(), NULL));
+}
+
+void game_devcards_set_num_cards(GameDevCards * gd, gint type, gint num)
+{
+ gtk_spin_button_set_value(gd->num_cards[type], num);
+}
+
+gint game_devcards_get_num_cards(GameDevCards * gd, gint type)
+{
+ return gtk_spin_button_get_value(gd->num_cards[type]);
+}
Added: trunk/editor/gtk/game-devcards.h
===================================================================
--- trunk/editor/gtk/game-devcards.h (rev 0)
+++ trunk/editor/gtk/game-devcards.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,35 @@
+#ifndef __GAMEDEVCARDS_H__
+#define __GAMEDEVCARDS_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtktable.h>
+
+G_BEGIN_DECLS
+#define GAMEDEVCARDS_TYPE (game_devcards_get_type ())
+#define GAMEDEVCARDS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMEDEVCARDS_TYPE, GameDevCards))
+#define GAMEDEVCARDS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMEDEVCARDS_TYPE, GameDevCardsClass))
+#define IS_GAMEDEVCARDS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMEDEVCARDS_TYPE))
+#define IS_GAMEDEVCARDS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMEDEVCARDS_TYPE))
+typedef struct _GameDevCards GameDevCards;
+typedef struct _GameDevCardsClass GameDevCardsClass;
+
+struct _GameDevCards {
+ GtkTable table;
+
+ GtkSpinButton *num_cards[NUM_DEVEL_TYPES];
+};
+
+struct _GameDevCardsClass {
+ GtkTableClass parent_class;
+};
+
+GType game_devcards_get_type(void);
+GtkWidget *game_devcards_new(void);
+
+void game_devcards_set_num_cards(GameDevCards * gd, gint type, gint num);
+gint game_devcards_get_num_cards(GameDevCards * gd, gint type);
+
+G_END_DECLS
+#endif /* __GAMEDEVCARDS_H__ */
Added: trunk/editor/gtk/game-resources.c
===================================================================
--- trunk/editor/gtk/game-resources.c (rev 0)
+++ trunk/editor/gtk/game-resources.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,77 @@
+#include "config.h"
+#include "game.h"
+#include <gtk/gtktable.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkspinbutton.h>
+#include <string.h>
+#include <glib.h>
+
+#include "game-resources.h"
+
+static void game_resources_init(GameResources * gr);
+
+/* Register the class */
+GType game_resources_get_type(void)
+{
+ static GType gr_type = 0;
+
+ if (!gr_type) {
+ static const GTypeInfo gr_info = {
+ sizeof(GameResourcesClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof(GameResources),
+ 0,
+ (GInstanceInitFunc) game_resources_init,
+ NULL
+ };
+ gr_type =
+ g_type_register_static(GTK_TYPE_TABLE, "GameResources",
+ &gr_info, 0);
+ }
+ return gr_type;
+}
+
+/* Build the composite widget */
+static void game_resources_init(GameResources * gr)
+{
+ GtkWidget *label;
+ GtkWidget *spin;
+ GtkObject *adjustment;
+
+ gtk_table_resize(GTK_TABLE(gr), 1, 2);
+ gtk_table_set_row_spacings(GTK_TABLE(gr), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(gr), 5);
+ gtk_table_set_homogeneous(GTK_TABLE(gr), TRUE);
+
+ label = gtk_label_new(_("Resource Count"));
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+ gtk_table_attach_defaults(GTK_TABLE(gr), label, 0, 1, 0, 1);
+
+ adjustment = gtk_adjustment_new(0, 0, 100, 1, 1, 1);
+ spin = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 1, 0);
+ gtk_entry_set_alignment(GTK_ENTRY(spin), 1.0);
+ gtk_table_attach_defaults(GTK_TABLE(gr), spin, 1, 2, 0, 1);
+ gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(spin), TRUE);
+ gr->num_resources = GTK_SPIN_BUTTON(spin);
+}
+
+/* Create a new instance of the widget */
+GtkWidget *game_resources_new(void)
+{
+ return GTK_WIDGET(g_object_new(game_resources_get_type(), NULL));
+}
+
+void game_resources_set_num_resources(GameResources * gr, gint num)
+{
+ gtk_spin_button_set_value(gr->num_resources, num);
+}
+
+gint game_resources_get_num_resources(GameResources * gr)
+{
+ return gtk_spin_button_get_value(gr->num_resources);
+}
Added: trunk/editor/gtk/game-resources.h
===================================================================
--- trunk/editor/gtk/game-resources.h (rev 0)
+++ trunk/editor/gtk/game-resources.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,35 @@
+#ifndef __GAMERESOURCES_H__
+#define __GAMERESOURCES_H__
+
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtktable.h>
+
+G_BEGIN_DECLS
+#define GAMERESOURCES_TYPE (game_resources_get_type ())
+#define GAMERESOURCES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAMERESOURCES_TYPE, GameResources))
+#define GAMERESOURCES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAMERESOURCES_TYPE, GameResourcesClass))
+#define IS_GAMERESOURCES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAMERESOURCES_TYPE))
+#define IS_GAMERESOURCES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAMERESOURCES_TYPE))
+typedef struct _GameResources GameResources;
+typedef struct _GameResourcesClass GameResourcesClass;
+
+struct _GameResources {
+ GtkTable table;
+
+ GtkSpinButton *num_resources;
+};
+
+struct _GameResourcesClass {
+ GtkTableClass parent_class;
+};
+
+GType game_resources_get_type(void);
+GtkWidget *game_resources_new(void);
+
+void game_resources_set_num_resources(GameResources * gr, gint num);
+gint game_resources_get_num_resources(GameResources * gr);
+
+G_END_DECLS
+#endif /* __GAMERESOURCES_H__ */
Added: trunk/editor/gtk/pioneers-editor.desktop
===================================================================
--- trunk/editor/gtk/pioneers-editor.desktop (rev 0)
+++ trunk/editor/gtk/pioneers-editor.desktop 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Version=1.0
+Encoding=UTF-8
+Name=Pioneers Editor
+Comment=Create your own game for Pioneers
+Exec=pioneers-editor
+Icon=pioneers-editor.png
+Terminal=false
+Type=Application
+Categories=Game;BoardGame;StrategyGame;GNOME;GTK;
Added: trunk/editor/gtk/pioneers-editor.rc
===================================================================
--- trunk/editor/gtk/pioneers-editor.rc (rev 0)
+++ trunk/editor/gtk/pioneers-editor.rc 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1 @@
+1 ICON DISCARDABLE "editor/gtk/pioneers-editor.ico"
Added: trunk/editor/gtk/pioneers-editor.svg
===================================================================
--- trunk/editor/gtk/pioneers-editor.svg (rev 0)
+++ trunk/editor/gtk/pioneers-editor.svg 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ x="0"
+ y="0"
+ width="354.330688"
+ height="354.330688"
+ id="svg620"
+ xml:space="preserve"><defs
+ id="defs622" /><g
+ transform="matrix(1.38939,0,0,1.38939,-162.8163,-618.7101)"
+ style="font-size:12;"
+ id="g638"><path
+ d="M 184.1155 485.4331 L 245.4874 450 L 306.8593 485.4331 L 306.8593 556.2992 L 245.4874 591.7323 L 184.1155 556.2992 L 184.1155 485.4331 z "
+ style="fill:#800000;fill-rule:evenodd;stroke:#000000;stroke-width:3.5433;"
+ id="path616" /><path
+ d="M 306.8593 556.2992 L 368.2311 591.7323 L 368.2311 662.5984 L 306.8593 698.0315 L 245.4874 662.5984 L 245.4874 591.7323 L 306.8593 556.2992 z "
+ style="fill:#008000;fill-rule:evenodd;stroke:#000000;stroke-width:3.5433;"
+ id="path617" /><path
+ d="M 184.1155 556.2939 L 122.7437 591.7283 L 122.7437 662.597 L 184.1155 698.0314 L 245.4874 662.597 L 245.4874 591.7283 L 184.1155 556.2939 z "
+ style="fill:#c37f41;fill-rule:evenodd;stroke:#000000;stroke-width:3.543365;"
+ id="path618" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,81.85915,-132.835)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path624" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,-40.88452,-132.835)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path625" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,21.57656,-239.1342)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path626" /><text
+ x="95.3142548"
+ y="212.637573"
+ transform="translate(141.3132,320.9463)"
+ style="font-size:36;font-weight:normal;fill:#ff0000;stroke-width:1;font-family:FreeSans;"
+ id="text627"><tspan
+ id="tspan628">8</tspan></text><text
+ x="70.7458191"
+ y="254.86348"
+ transform="translate(104.0006,385.1866)"
+ style="font-size:36;font-weight:normal;stroke-width:1;font-family:FreeSans;"
+ id="text630"><tspan
+ id="tspan631">4</tspan></text><text
+ x="88.1663055"
+ y="224.654419"
+ transform="translate(208.7261,415.2287)"
+ style="font-size:36;font-weight:normal;stroke-width:1;font-family:FreeSans;"
+ id="text633"><tspan
+ id="tspan634">9</tspan></text></g><g
+ transform="matrix(-8.159846,-14.13326,14.13326,-8.159846,174.0987,427.4272)"
+ style="font-size:12;stroke:#000000;"
+ id="Layer_x0020_5"><path
+ d="M 6.4 6.6 L 12 9.6 L 18 17.7 L 17.9 19 L 16.5 20.4 L 15 20.2 L 8.7 12.5 L 6.4 6.6 z "
+ style="fill:none;stroke-width:1.8415;stroke-linecap:round;stroke-linejoin:round;"
+ id="path795" /><linearGradient
+ x1="9.87650013"
+ y1="14.6738005"
+ x2="14.1429005"
+ y2="11.3717003"
+ id="aigrd3"
+ gradientUnits="userSpaceOnUse"><stop
+ style="stop-color:#eff0ce;stop-opacity:1;"
+ offset="0"
+ id="stop797" /><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0.5"
+ id="stop798" /><stop
+ style="stop-color:#eff0ce;stop-opacity:1;"
+ offset="1"
+ id="stop799" /></linearGradient><path
+ d="M 6.4 6.6 L 12 9.6 L 18 17.7 L 17.9 19 L 16.5 20.4 L 15 20.2 L 8.7 12.5 L 6.4 6.6 z "
+ style="fill:url(#aigrd3);stroke:none;"
+ id="path800" /><path
+ d="M 10.6 13 L 16.4 20.3 L 15 20.2 L 8.7 12.5 L 10.6 13 z "
+ style="fill:#e0c35d;stroke:none;"
+ id="path801" /><path
+ d="M 12.2 11.5 L 17.9 18.9 L 16.5 20.3 L 10.6 13 L 12.1 11.5 L 12.2 11.5 z "
+ style="fill:#c8af53;stroke:none;"
+ id="path802" /><path
+ d="M 11.9 9.6 L 17.9 17.7 L 17.8 19 L 12.1 11.6 L 11.9 9.6 L 11.9 9.6 z "
+ style="fill:#f7e46e;stroke:none;"
+ id="path803" /><linearGradient
+ x1="6.89550018"
+ y1="7.99900007"
+ x2="7.77199984"
+ y2="7.44390011"
+ id="aigrd4"
+ gradientUnits="userSpaceOnUse"><stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop805" /><stop
+ style="stop-color:#616061;stop-opacity:1;"
+ offset="0.5"
+ id="stop806" /><stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="1"
+ id="stop807" /></linearGradient><path
+ d="M 8.9 7.9 C 8.9 8.8 8.4 9.3 7.5 9.3 L 6.4 6.6 L 8.9 7.9 L 8.9 7.9 z "
+ style="fill:url(#aigrd4);stroke:none;"
+ id="path808" /></g><g
+ transform="translate(55.26862,-23.22408)"
+ style="font-size:12;stroke:#000000;"
+ id="Layer_x0020_6"><path
+ d="M 24 24 L 0 24 L 0 0 L 24 0 L 24 24 z "
+ style="fill:none;stroke:none;"
+ id="path810" /></g></svg>
Added: trunk/macros/Makefile.am
===================================================================
--- trunk/macros/Makefile.am (rev 0)
+++ trunk/macros/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,21 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+# Copyright (C) 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+EXTRA_DIST += macros/gnome-autogen.sh macros/type_socklen_t.m4
Added: trunk/macros/gnome-autogen.sh
===================================================================
--- trunk/macros/gnome-autogen.sh (rev 0)
+++ trunk/macros/gnome-autogen.sh 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,468 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+#name of package
+PKG_NAME=${PKG_NAME:-Package}
+srcdir=${srcdir:-.}
+
+# default version requirements ...
+REQUIRED_AUTOCONF_VERSION=${REQUIRED_AUTOCONF_VERSION:-2.53}
+REQUIRED_AUTOMAKE_VERSION=${REQUIRED_AUTOMAKE_VERSION:-1.4}
+REQUIRED_LIBTOOL_VERSION=${REQUIRED_LIBTOOL_VERSION:-1.5}
+REQUIRED_GETTEXT_VERSION=${REQUIRED_GETTEXT_VERSION:-0.12}
+REQUIRED_GLIB_GETTEXT_VERSION=${REQUIRED_GLIB_GETTEXT_VERSION:-2.2.0}
+REQUIRED_INTLTOOL_VERSION=${REQUIRED_INTLTOOL_VERSION:-0.30}
+REQUIRED_PKG_CONFIG_VERSION=${REQUIRED_PKG_CONFIG_VERSION:-0.14.0}
+REQUIRED_GTK_DOC_VERSION=${REQUIRED_GTK_DOC_VERSION:-1.0}
+REQUIRED_DOC_COMMON_VERSION=${REQUIRED_DOC_COMMON_VERSION:-2.3.0}
+REQUIRED_GNOME_DOC_UTILS_VERSION=${REQUIRED_GNOME_DOC_UTILS_VERSION:-0.3.2}
+
+# a list of required m4 macros. Package can set an initial value
+REQUIRED_M4MACROS=${REQUIRED_M4MACROS:-}
+FORBIDDEN_M4MACROS=${FORBIDDEN_M4MACROS:-}
+
+# Not all echo versions allow -n, so we check what is possible. This test is
+# based on the one in autoconf.
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+ *c*,-n*) ECHO_N= ;;
+ *c*,* ) ECHO_N=-n ;;
+ *) ECHO_N= ;;
+esac
+
+# some terminal codes ...
+boldface="`tput bold 2>/dev/null`"
+normal="`tput sgr0 2>/dev/null`"
+printbold() {
+ echo $ECHO_N "$boldface"
+ echo "$@"
+ echo $ECHO_N "$normal"
+}
+printerr() {
+ echo "$@" >&2
+}
+
+# Usage:
+# compare_versions MIN_VERSION ACTUAL_VERSION
+# returns true if ACTUAL_VERSION >= MIN_VERSION
+compare_versions() {
+ ch_min_version=$1
+ ch_actual_version=$2
+ ch_status=0
+ IFS="${IFS= }"; ch_save_IFS="$IFS"; IFS="."
+ set $ch_actual_version
+ for ch_min in $ch_min_version; do
+ ch_cur=`echo $1 | sed 's/[^0-9].*$//'`; shift # remove letter suffixes
+ if [ -z "$ch_min" ]; then break; fi
+ if [ -z "$ch_cur" ]; then ch_status=1; break; fi
+ if [ $ch_cur -gt $ch_min ]; then break; fi
+ if [ $ch_cur -lt $ch_min ]; then ch_status=1; break; fi
+ done
+ IFS="$ch_save_IFS"
+ return $ch_status
+}
+
+# Usage:
+# version_check PACKAGE VARIABLE CHECKPROGS MIN_VERSION SOURCE
+# checks to see if the package is available
+version_check() {
+ vc_package=$1
+ vc_variable=$2
+ vc_checkprogs=$3
+ vc_min_version=$4
+ vc_source=$5
+ vc_status=1
+
+ vc_checkprog=`eval echo "\\$$vc_variable"`
+ if [ -n "$vc_checkprog" ]; then
+ printbold "using $vc_checkprog for $vc_package"
+ return 0
+ fi
+
+ if test "x$vc_package" = "xautomake" -a "x$vc_min_version" = "x1.4"; then
+ vc_comparator="="
+ else
+ vc_comparator=">="
+ fi
+ printbold "checking for $vc_package $vc_comparator $vc_min_version..."
+ for vc_checkprog in $vc_checkprogs; do
+ echo $ECHO_N " testing $vc_checkprog... "
+ if $vc_checkprog --version < /dev/null > /dev/null 2>&1; then
+ vc_actual_version=`$vc_checkprog --version | head -n 1 | \
+ sed 's/^.*[ ]\([0-9.]*[a-z]*\).*$/\1/'`
+ if compare_versions $vc_min_version $vc_actual_version; then
+ echo "found $vc_actual_version"
+ # set variables
+ eval "$vc_variable=$vc_checkprog; \
+ ${vc_variable}_VERSION=$vc_actual_version"
+ vc_status=0
+ break
+ else
+ echo "too old (found version $vc_actual_version)"
+ fi
+ else
+ echo "not found."
+ fi
+ done
+ if [ "$vc_status" != 0 ]; then
+ printerr "***Error***: You must have $vc_package $vc_comparator $vc_min_version installed"
+ printerr " to build $PKG_NAME. Download the appropriate package for"
+ printerr " from your distribution or get the source tarball at"
+ printerr " $vc_source"
+ printerr
+ fi
+ return $vc_status
+}
+
+# Usage:
+# require_m4macro filename.m4
+# adds filename.m4 to the list of required macros
+require_m4macro() {
+ case "$REQUIRED_M4MACROS" in
+ $1\ * | *\ $1\ * | *\ $1) ;;
+ *) REQUIRED_M4MACROS="$REQUIRED_M4MACROS $1" ;;
+ esac
+}
+
+forbid_m4macro() {
+ case "$FORBIDDEN_M4MACROS" in
+ $1\ * | *\ $1\ * | *\ $1) ;;
+ *) FORBIDDEN_M4MACROS="$FORBIDDEN_M4MACROS $1" ;;
+ esac
+}
+
+# Usage:
+# add_to_cm_macrodirs dirname
+# Adds the dir to $cm_macrodirs, if it's not there yet.
+add_to_cm_macrodirs() {
+ case $cm_macrodirs in
+ "$1 "* | *" $1 "* | *" $1") ;;
+ *) cm_macrodirs="$cm_macrodirs $1";;
+ esac
+}
+
+# Usage:
+# check_m4macros
+# Checks that all the requested macro files are in the aclocal macro path
+# Uses REQUIRED_M4MACROS and ACLOCAL variables.
+check_m4macros() {
+ # construct list of macro directories
+ cm_macrodirs=`$ACLOCAL --print-ac-dir`
+ # aclocal also searches a version specific dir, eg. /usr/share/aclocal-1.9
+ # but it contains only Automake's own macros, so we can ignore it.
+
+ # Read the dirlist file, supported by Automake >= 1.7.
+ if compare_versions 1.7 $AUTOMAKE_VERSION && [ -s $cm_macrodirs/dirlist ]; then
+ cm_dirlist=`sed 's/[ ]*#.*//;/^$/d' $cm_macrodirs/dirlist`
+ if [ -n "$cm_dirlist" ] ; then
+ for cm_dir in $cm_dirlist; do
+ if [ -d $cm_dir ]; then
+ add_to_cm_macrodirs $cm_dir
+ fi
+ done
+ fi
+ fi
+
+ # Parse $ACLOCAL_FLAGS
+ set - $ACLOCAL_FLAGS
+ while [ $# -gt 0 ]; do
+ if [ "$1" = "-I" ]; then
+ add_to_cm_macrodirs "$2"
+ shift
+ fi
+ shift
+ done
+
+ cm_status=0
+ if [ -n "$REQUIRED_M4MACROS" ]; then
+ printbold "Checking for required M4 macros..."
+ # check that each macro file is in one of the macro dirs
+ for cm_macro in $REQUIRED_M4MACROS; do
+ cm_macrofound=false
+ for cm_dir in $cm_macrodirs; do
+ if [ -f "$cm_dir/$cm_macro" ]; then
+ cm_macrofound=true
+ break
+ fi
+ # The macro dir in Cygwin environments may contain a file
+ # called dirlist containing other directories to look in.
+ if [ -f "$cm_dir/dirlist" ]; then
+ for cm_otherdir in `cat $cm_dir/dirlist`; do
+ if [ -f "$cm_otherdir/$cm_macro" ]; then
+ cm_macrofound=true
+ break
+ fi
+ done
+ fi
+ done
+ if $cm_macrofound; then
+ :
+ else
+ printerr " $cm_macro not found"
+ cm_status=1
+ fi
+ done
+ fi
+ if [ -n "$FORBIDDEN_M4MACROS" ]; then
+ printbold "Checking for forbidden M4 macros..."
+ # check that each macro file is in one of the macro dirs
+ for cm_macro in $FORBIDDEN_M4MACROS; do
+ cm_macrofound=false
+ for cm_dir in $cm_macrodirs; do
+ if [ -f "$cm_dir/$cm_macro" ]; then
+ cm_macrofound=true
+ break
+ fi
+ done
+ if $cm_macrofound; then
+ printerr " $cm_macro found (should be cleared from macros dir)"
+ cm_status=1
+ fi
+ done
+ fi
+ if [ "$cm_status" != 0 ]; then
+ printerr "***Error***: some autoconf macros required to build $PKG_NAME"
+ printerr " were not found in your aclocal path, or some forbidden"
+ printerr " macros were found. Perhaps you need to adjust your"
+ printerr " ACLOCAL_FLAGS?"
+ printerr
+ fi
+ return $cm_status
+}
+
+# try to catch the case where the macros2/ directory hasn't been cleared out.
+forbid_m4macro gnome-cxx-check.m4
+
+want_libtool=false
+want_gettext=false
+want_glib_gettext=false
+want_intltool=false
+want_pkg_config=false
+want_gtk_doc=false
+want_gnome_doc_utils=false
+
+configure_files="`find $srcdir -name '{arch}' -prune -o -name '.?*' -prune -o -name configure.ac -print -o -name configure.in -print`"
+for configure_ac in $configure_files; do
+ if grep "^A[CM]_PROG_LIBTOOL" $configure_ac >/dev/null ||
+ grep "^LT_INIT" $configure_ac >/dev/null; then
+ want_libtool=true
+ fi
+ if grep "^AM_GNU_GETTEXT" $configure_ac >/dev/null; then
+ want_gettext=true
+ fi
+ if grep "^AM_GLIB_GNU_GETTEXT" $configure_ac >/dev/null; then
+ want_glib_gettext=true
+ fi
+ if grep "^AC_PROG_INTLTOOL" $configure_ac >/dev/null ||
+ grep "^IT_PROG_INTLTOOL" $configure_ac >/dev/null; then
+ want_intltool=true
+ fi
+ if grep "^PKG_CHECK_MODULES" $configure_ac >/dev/null; then
+ want_pkg_config=true
+ fi
+ if grep "^GTK_DOC_CHECK" $configure_ac >/dev/null; then
+ want_gtk_doc=true
+ fi
+ if grep "^GNOME_DOC_INIT" $configure_ac >/dev/null; then
+ want_gnome_doc_utils=true
+ fi
+
+ # check to make sure gnome-common macros can be found ...
+ if grep "^GNOME_COMMON_INIT" $configure_ac >/dev/null ||
+ grep "^GNOME_DEBUG_CHECK" $configure_ac >/dev/null ||
+ grep "^GNOME_MAINTAINER_MODE_DEFINES" $configure_ac >/dev/null; then
+ require_m4macro gnome-common.m4
+ fi
+ if grep "^GNOME_COMPILE_WARNINGS" $configure_ac >/dev/null ||
+ grep "^GNOME_CXX_WARNINGS" $configure_ac >/dev/null; then
+ require_m4macro gnome-compiler-flags.m4
+ fi
+done
+
+DIE=0
+
+#tell Mandrake autoconf wrapper we want autoconf 2.5x, not 2.13
+WANT_AUTOCONF_2_5=1
+export WANT_AUTOCONF_2_5
+version_check autoconf AUTOCONF 'autoconf2.50 autoconf autoconf-2.53' $REQUIRED_AUTOCONF_VERSION \
+ "http://ftp.gnu.org/pub/gnu/autoconf/autoconf-$REQUIRED_AUTOCONF_VERSION.tar.gz" || DIE=1
+AUTOHEADER=`echo $AUTOCONF | sed s/autoconf/autoheader/`
+
+case $REQUIRED_AUTOMAKE_VERSION in
+ 1.4*) automake_progs="automake-1.4" ;;
+ 1.5*) automake_progs="automake-1.5 automake-1.6 automake-1.7 automake-1.8 automake-1.9" ;;
+ 1.6*) automake_progs="automake-1.6 automake-1.7 automake-1.8 automake-1.9" ;;
+ 1.7*) automake_progs="automake-1.7 automake-1.8 automake-1.9" ;;
+ 1.8*) automake_progs="automake-1.8 automake-1.9" ;;
+ 1.9*) automake_progs="automake-1.9" ;;
+esac
+version_check automake AUTOMAKE "$automake_progs" $REQUIRED_AUTOMAKE_VERSION \
+ "http://ftp.gnu.org/pub/gnu/automake/automake-$REQUIRED_AUTOMAKE_VERSION.tar.gz" || DIE=1
+ACLOCAL=`echo $AUTOMAKE | sed s/automake/aclocal/`
+
+if $want_libtool; then
+ version_check libtool LIBTOOLIZE libtoolize $REQUIRED_LIBTOOL_VERSION \
+ "http://ftp.gnu.org/pub/gnu/libtool/libtool-$REQUIRED_LIBTOOL_VERSION.tar.gz" || DIE=1
+ require_m4macro libtool.m4
+fi
+
+if $want_gettext; then
+ version_check gettext GETTEXTIZE gettextize $REQUIRED_GETTEXT_VERSION \
+ "http://ftp.gnu.org/pub/gnu/gettext/gettext-$REQUIRED_GETTEXT_VERSION.tar.gz" || DIE=1
+ require_m4macro gettext.m4
+fi
+
+if $want_glib_gettext; then
+ version_check glib-gettext GLIB_GETTEXTIZE glib-gettextize $REQUIRED_GLIB_GETTEXT_VERSION \
+ "ftp://ftp.gtk.org/pub/gtk/v2.2/glib-$REQUIRED_GLIB_GETTEXT_VERSION.tar.gz" || DIE=1
+ require_m4macro glib-gettext.m4
+fi
+
+if $want_intltool; then
+ version_check intltool INTLTOOLIZE intltoolize $REQUIRED_INTLTOOL_VERSION \
+ "http://ftp.gnome.org/pub/GNOME/sources/intltool/" || DIE=1
+ require_m4macro intltool.m4
+fi
+
+if $want_pkg_config; then
+ version_check pkg-config PKG_CONFIG pkg-config $REQUIRED_PKG_CONFIG_VERSION \
+ "'http://www.freedesktop.org/software/pkgconfig/releases/pkgconfig-$REQUIRED_PKG_CONFIG_VERSION.tar.gz" || DIE=1
+ require_m4macro pkg.m4
+fi
+
+if $want_gtk_doc; then
+ version_check gtk-doc GTKDOCIZE gtkdocize $REQUIRED_GTK_DOC_VERSION \
+ "http://ftp.gnome.org/pub/GNOME/sources/gtk-doc/" || DIE=1
+ require_m4macro gtk-doc.m4
+fi
+
+if $want_gnome_doc_utils; then
+ version_check gnome-doc-utils GNOME_DOC_PREPARE gnome-doc-prepare $REQUIRED_GNOME_DOC_UTILS_VERSION \
+ "http://ftp.gnome.org/pub/GNOME/sources/gnome-doc-utils/" || DIE=1
+fi
+
+if [ "x$USE_COMMON_DOC_BUILD" = "xyes" ]; then
+ version_check gnome-common DOC_COMMON gnome-doc-common \
+ $REQUIRED_DOC_COMMON_VERSION " " || DIE=1
+fi
+
+check_m4macros || DIE=1
+
+if [ "$DIE" -eq 1 ]; then
+ exit 1
+fi
+
+if [ "$#" = 0 ]; then
+ printerr "**Warning**: I am going to run \`configure' with no arguments."
+ printerr "If you wish to pass any to it, please specify them on the"
+ printerr \`$0\'" command line."
+ printerr
+fi
+
+topdir=`pwd`
+for configure_ac in $configure_files; do
+ dirname=`dirname $configure_ac`
+ basename=`basename $configure_ac`
+ if [ -f $dirname/NO-AUTO-GEN ]; then
+ echo skipping $dirname -- flagged as no auto-gen
+ elif [ ! -w $dirname ]; then
+ echo skipping $dirname -- directory is read only
+ else
+ printbold "Processing $configure_ac"
+ cd $dirname
+
+ # Note that the order these tools are called should match what
+ # autoconf's "autoupdate" package does. See bug 138584 for
+ # details.
+
+ # programs that might install new macros get run before aclocal
+ if grep "^A[CM]_PROG_LIBTOOL" $basename >/dev/null ||
+ grep "^LT_INIT" $basename >/dev/null; then
+ printbold "Running $LIBTOOLIZE..."
+ $LIBTOOLIZE --force --copy || exit 1
+ fi
+
+ if grep "^AM_GLIB_GNU_GETTEXT" $basename >/dev/null; then
+ printbold "Running $GLIB_GETTEXTIZE... Ignore non-fatal messages."
+ echo "no" | $GLIB_GETTEXTIZE --force --copy || exit 1
+ elif grep "^AM_GNU_GETTEXT" $basename >/dev/null; then
+ if grep "^AM_GNU_GETTEXT_VERSION" $basename > /dev/null; then
+ printbold "Running autopoint..."
+ autopoint --force || exit 1
+ else
+ printbold "Running $GETTEXTIZE... Ignore non-fatal messages."
+ echo "no" | $GETTEXTIZE --force --copy || exit 1
+ fi
+ fi
+
+ if grep "^AC_PROG_INTLTOOL" $basename >/dev/null ||
+ grep "^IT_PROG_INTLTOOL" $basename >/dev/null; then
+ printbold "Running $INTLTOOLIZE..."
+ $INTLTOOLIZE --force --copy --automake || exit 1
+ fi
+ if grep "^GTK_DOC_CHECK" $basename >/dev/null; then
+ printbold "Running $GTKDOCIZE..."
+ $GTKDOCIZE --copy || exit 1
+ fi
+
+ if [ "x$USE_COMMON_DOC_BUILD" = "xyes" ]; then
+ printbold "Running gnome-doc-common..."
+ gnome-doc-common --copy || exit 1
+ fi
+ if grep "^GNOME_DOC_INIT" $basename >/dev/null; then
+ printbold "Running $GNOME_DOC_PREPARE..."
+ $GNOME_DOC_PREPARE --force --copy || exit 1
+ fi
+
+ # Now run aclocal to pull in any additional macros needed
+
+ # if the AC_CONFIG_MACRO_DIR() macro is used, pass that
+ # directory to aclocal.
+ m4dir=`cat "$basename" | grep '^AC_CONFIG_MACRO_DIR' | sed -n -e 's/AC_CONFIG_MACRO_DIR(\([^()]*\))/\1/p' | sed -e 's/^\[\(.*\)\]$/\1/' | sed -e 1q`
+ if [ -n "$m4dir" ]; then
+ m4dir="-I $m4dir"
+ fi
+ printbold "Running $ACLOCAL..."
+ $ACLOCAL $m4dir $ACLOCAL_FLAGS || exit 1
+
+ if grep "GNOME_AUTOGEN_OBSOLETE" aclocal.m4 >/dev/null; then
+ printerr "*** obsolete gnome macros were used in $configure_ac"
+ fi
+
+ # Now that all the macros are sorted, run autoconf and autoheader ...
+ printbold "Running $AUTOCONF..."
+ $AUTOCONF || exit 1
+ if grep "^A[CM]_CONFIG_HEADER" $basename >/dev/null; then
+ printbold "Running $AUTOHEADER..."
+ $AUTOHEADER || exit 1
+ # this prevents automake from thinking config.h.in is out of
+ # date, since autoheader doesn't touch the file if it doesn't
+ # change.
+ test -f config.h.in && touch config.h.in
+ fi
+
+ # Finally, run automake to create the makefiles ...
+ printbold "Running $AUTOMAKE..."
+ cp -pf COPYING COPYING.autogen_bak
+ cp -pf INSTALL INSTALL.autogen_bak
+ if [ $REQUIRED_AUTOMAKE_VERSION != 1.4 ]; then
+ $AUTOMAKE --gnu --add-missing --force --copy || exit 1
+ else
+ $AUTOMAKE --gnu --add-missing --copy || exit 1
+ fi
+ cmp COPYING COPYING.autogen_bak || cp -pf COPYING.autogen_bak COPYING
+ cmp INSTALL INSTALL.autogen_bak || cp -pf INSTALL.autogen_bak INSTALL
+ rm -f COPYING.autogen_bak INSTALL.autogen_bak
+
+ cd "$topdir"
+ fi
+done
+
+conf_flags="--enable-maintainer-mode"
+
+if test x$NOCONFIGURE = x; then
+ printbold Running $srcdir/configure $conf_flags "$@" ...
+ $srcdir/configure $conf_flags "$@" \
+ && echo Now type \`make\' to compile $PKG_NAME || exit 1
+else
+ echo Skipping configure process.
+fi
Property changes on: trunk/macros/gnome-autogen.sh
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/macros/type_socklen_t.m4
===================================================================
--- trunk/macros/type_socklen_t.m4 (rev 0)
+++ trunk/macros/type_socklen_t.m4 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,23 @@
+dnl @synopsis TYPE_SOCKLEN_T
+dnl
+dnl Check whether sys/socket.h defines type socklen_t. Please note
+dnl that some systems require sys/types.h to be included before
+dnl sys/socket.h can be compiled.
+dnl
+dnl @version $Id: type_socklen_t.m4 597 2004-09-26 20:02:05Z rclobus $
+dnl @author Lars Brinkhoff <lars at nocrew.org>
+dnl
+AC_DEFUN([TYPE_SOCKLEN_T],
+[AC_CACHE_CHECK([for socklen_t], ac_cv_type_socklen_t,
+[
+ AC_TRY_COMPILE(
+ [#include <sys/types.h>
+ #include <sys/socket.h>],
+ [socklen_t len = 42; return 0;],
+ ac_cv_type_socklen_t=yes,
+ ac_cv_type_socklen_t=no)
+])
+ if test $ac_cv_type_socklen_t != yes; then
+ AC_DEFINE(socklen_t, int, [Substitute for socklen_t])
+ fi
+])
Added: trunk/meta-server/Makefile.am
===================================================================
--- trunk/meta-server/Makefile.am (rev 0)
+++ trunk/meta-server/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,26 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+bin_PROGRAMS += pioneers-meta-server
+
+pioneers_meta_server_CPPFLAGS = $(console_cflags)
+pioneers_meta_server_LDADD = $(console_libs)
+
+pioneers_meta_server_SOURCES = \
+ meta-server/main.c
Added: trunk/meta-server/main.c
===================================================================
--- trunk/meta-server/main.c (rev 0)
+++ trunk/meta-server/main.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,1137 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <netdb.h>
+#include <time.h>
+
+#include <glib.h>
+#include "network.h"
+#include "game.h"
+#include "version.h"
+
+typedef enum {
+ META_UNKNOWN,
+ META_CLIENT,
+ META_SERVER_ALMOST,
+ META_SERVER
+} ClientType;
+
+typedef struct _Client Client;
+struct _Client {
+ ClientType type;
+ gint fd;
+ time_t event_at; /* when is the next timeout for this client? */
+ void (*event_func) (Client * client);
+ gboolean read_anything; /* Is anything read since the last event? */
+
+ char read_buff[16 * 1024];
+ int read_len;
+ GList *write_queue;
+ gboolean waiting_for_close;
+ gint protocol_major;
+ gint protocol_minor;
+
+ /* The rest of the structure is only used for META_SERVER clients
+ */
+ gchar *host;
+ gchar *port;
+ gchar *version;
+ gint max;
+ gint curr;
+ gint previous_curr;
+ gchar *terrain;
+ gchar *title;
+ gchar *vpoints;
+ gchar *sevenrule;
+};
+
+static gchar *redirect_location = NULL;
+static gchar *myhostname = NULL;
+static gboolean can_create_games;
+
+static int port_low = 0, port_high = 0;
+
+static GList *client_list;
+
+static fd_set read_fds;
+static fd_set write_fds;
+static int accept_fd;
+static gint max_fd;
+
+/* Command line data */
+static gboolean make_daemon = FALSE;
+static gchar *port_range = NULL;
+static gboolean enable_debug = FALSE;
+static gboolean enable_syslog_debug = FALSE;
+static gboolean show_version = FALSE;
+
+static void client_printf(Client * client, const char *fmt, ...);
+
+#define MINUTE 60
+#define HOUR (60 * MINUTE)
+
+#define MODE_TIMEOUT (2 * MINUTE) /* delay allowed to define mode */
+#define CLIENT_TIMEOUT (2 * MINUTE) /* delay allowed while listing servers */
+#define HELLO_TIMEOUT (8 * MINUTE) /* delay allowed between server hello */
+
+static void my_syslog(gint type, const gchar * fmt, ...)
+{
+ va_list ap;
+ gchar *buff;
+
+ va_start(ap, fmt);
+ buff = g_strdup_vprintf(fmt, ap);
+ va_end(ap);
+
+ syslog(type, buff);
+
+ if (enable_syslog_debug)
+ g_print("Syslog %d: %s\n", type, buff);
+
+ g_free(buff);
+}
+
+static void meta_debug(const gchar * fmt, ...)
+{
+ static FILE *fp;
+ va_list ap;
+ gchar *buff;
+ gint idx;
+ gint len;
+
+ if (!enable_debug)
+ return;
+
+ if (fp == NULL) {
+ gchar *fullpath;
+ gchar *filename;
+ filename = g_strdup_printf("pioneers-meta.%d", getpid());
+ fullpath =
+ g_build_filename(g_get_tmp_dir(), filename, NULL);
+ fp = fopen(fullpath, "w");
+ g_free(fullpath);
+ g_free(filename);
+ }
+ if (fp == NULL)
+ return;
+
+ va_start(ap, fmt);
+ buff = g_strdup_vprintf(fmt, ap);
+ va_end(ap);
+
+ len = strlen(buff);
+ for (idx = 0; idx < len; idx++) {
+ if (isprint(buff[idx]) || idx == len - 1)
+ fputc(buff[idx], fp);
+ else
+ switch (buff[idx]) {
+ case '\n':
+ fputc('\\', fp);
+ fputc('n', fp);
+ break;
+ case '\r':
+ fputc('\\', fp);
+ fputc('r', fp);
+ break;
+ case '\t':
+ fputc('\\', fp);
+ fputc('t', fp);
+ break;
+ default:
+ fprintf(fp, "\\x%02x", (buff[idx] & 0xff));
+ break;
+ }
+ }
+ fflush(fp);
+
+ debug(buff);
+ g_free(buff);
+}
+
+static void find_new_max_fd(void)
+{
+ GList *list;
+
+ max_fd = accept_fd;
+ for (list = client_list; list != NULL; list = g_list_next(list)) {
+ Client *client = list->data;
+
+ if (client->fd > max_fd)
+ max_fd = client->fd;
+ }
+}
+
+static void client_free(Client * client)
+{
+ if (client->type == META_SERVER)
+ my_syslog(LOG_INFO, "server %s on port %s unregistered",
+ client->host, client->port);
+
+ if (client->host != NULL)
+ g_free(client->host);
+ if (client->port != NULL)
+ g_free(client->port);
+ if (client->version != NULL)
+ g_free(client->version);
+ if (client->terrain != NULL)
+ g_free(client->terrain);
+ if (client->title != NULL)
+ g_free(client->title);
+ if (client->vpoints != NULL)
+ g_free(client->vpoints);
+ if (client->sevenrule != NULL)
+ g_free(client->sevenrule);
+ g_free(client);
+}
+
+static void client_close(Client * client)
+{
+ client_list = g_list_remove(client_list, client);
+
+ if (client->fd == max_fd)
+ find_new_max_fd();
+
+ FD_CLR(client->fd, &read_fds);
+ FD_CLR(client->fd, &write_fds);
+ net_closesocket(client->fd);
+
+ while (client->write_queue != NULL) {
+ char *data = client->write_queue->data;
+
+ client->write_queue =
+ g_list_remove(client->write_queue, data);
+ g_free(data);
+ }
+
+ client->waiting_for_close = FALSE;
+ client->fd = -1;
+}
+
+static void client_hello(Client * client)
+{
+ if (client->read_anything) {
+ client_printf(client, "hello\n");
+ client->read_anything = FALSE;
+ } else {
+ my_syslog(LOG_INFO,
+ "server %s on port %s did not respond, deregistering",
+ client->host, client->port);
+ client_close(client);
+ }
+}
+
+static void set_client_event_at(Client * client)
+{
+ time_t now = time(NULL);
+ client->event_func = client_close;
+ switch (client->type) {
+ case META_UNKNOWN:
+ client->event_at = now + MODE_TIMEOUT;
+ break;
+ case META_CLIENT:
+ client->event_at = now + CLIENT_TIMEOUT;
+ break;
+ case META_SERVER_ALMOST:
+ case META_SERVER:
+ client->event_at = now + HELLO_TIMEOUT;
+ client->event_func = client_hello;
+ break;
+ }
+}
+
+static void client_do_write(Client * client)
+{
+ while (client->write_queue != NULL) {
+ char *data = client->write_queue->data;
+ guint len = strlen(data);
+ int num;
+
+ num = write(client->fd, data, len);
+ meta_debug
+ ("client_do_write: write(%d, \"%.*s\", %d) = %d\n",
+ client->fd, len, data, len, num);
+ if (num < 0) {
+ if (errno == EAGAIN)
+ break;
+ my_syslog(LOG_ERR, "writing socket: %s",
+ g_strerror(errno));
+ client_close(client);
+ return;
+ } else if (num == len) {
+ client->write_queue
+ = g_list_remove(client->write_queue, data);
+ g_free(data);
+ } else {
+ memmove(data, data + num, len - num + 1);
+ break;
+ }
+ }
+
+ /* Stop spinning when nothing to do.
+ */
+ if (client->write_queue == NULL) {
+ if (client->waiting_for_close) {
+ client_close(client);
+ return;
+ } else
+ FD_CLR(client->fd, &write_fds);
+ }
+
+ set_client_event_at(client);
+}
+
+static void client_printf(Client * client, const char *fmt, ...)
+{
+ gchar *buff;
+ va_list ap;
+
+ va_start(ap, fmt);
+ buff = g_strdup_vprintf(fmt, ap);
+ va_end(ap);
+
+ client->write_queue = g_list_append(client->write_queue, buff);
+ FD_SET(client->fd, &write_fds);
+
+ set_client_event_at(client);
+}
+
+static void client_list_servers(Client * client)
+{
+ GList *list;
+
+ for (list = client_list; list != NULL; list = g_list_next(list)) {
+ Client *scan = list->data;
+
+ if (scan->type != META_SERVER)
+ continue;
+ client_printf(client,
+ "server\n"
+ "host=%s\n"
+ "port=%s\n"
+ "version=%s\n"
+ "max=%d\n"
+ "curr=%d\n",
+ scan->host, scan->port, scan->version,
+ scan->max, scan->curr);
+ if (client->protocol_major == 0) {
+ client_printf(client,
+ "map=%s\n"
+ "comment=%s\n",
+ scan->terrain, scan->title);
+ } else if (client->protocol_major >= 1) {
+ client_printf(client,
+ "vpoints=%s\n"
+ "sevenrule=%s\n"
+ "terrain=%s\n"
+ "title=%s\n",
+ scan->vpoints,
+ scan->sevenrule,
+ scan->terrain, scan->title);
+ }
+ client_printf(client, "end\n");
+ }
+}
+
+static GList *load_game_desc(gchar * fname, GList * titles)
+{
+ FILE *fp;
+ gchar *line, *title;
+
+ if ((fp = fopen(fname, "r")) == NULL) {
+ g_warning("could not open '%s'", fname);
+ return NULL;
+ }
+ while (read_line_from_file(&line, fp)) {
+ if (strncmp(line, "title ", 6) == 0) {
+ title = line + 6;
+ title += strspn(title, " \t");
+ titles =
+ g_list_insert_sorted(titles, g_strdup(title),
+ (GCompareFunc) strcmp);
+ break;
+ }
+ g_free(line);
+ }
+ fclose(fp);
+ return titles;
+}
+
+static GList *load_game_types(void)
+{
+ GDir *dir;
+ GList *titles = NULL;
+ const gchar *fname;
+ gchar *fullname;
+
+ const gchar *pioneers_dir = get_pioneers_dir();
+
+ if ((dir = g_dir_open(pioneers_dir, 0, NULL)) == NULL) {
+ return NULL;
+ }
+
+ while ((fname = g_dir_read_name(dir))) {
+ gint len = strlen(fname);
+
+ if (len < 6 || strcmp(fname + len - 5, ".game") != 0)
+ continue;
+ fullname = g_build_filename(pioneers_dir, fname, NULL);
+ if (fullname) {
+ titles = load_game_desc(fullname, titles);
+ g_free(fullname);
+ };
+ }
+
+ g_dir_close(dir);
+ return titles;
+}
+
+static void client_list_types(Client * client)
+{
+ GList *list = load_game_types();
+
+ for (; list != NULL; list = g_list_next(list)) {
+ client_printf(client, "title=%s\n", list->data);
+ }
+ g_list_free(list);
+}
+
+static void client_list_capability(Client * client)
+{
+ if (can_create_games) {
+ client_printf(client, "create games\n");
+ }
+ /** @todo RC 2005-01-30 Implement this in the metaserver */
+ if (FALSE)
+ client_printf(client, "send game settings\n");
+ client_printf(client, "deregister dead connections\n");
+ client_printf(client, "end\n");
+}
+
+static const gchar *get_server_path(void)
+{
+ const gchar *console_server;
+ if (!(console_server = g_getenv("PIONEERS_SERVER_CONSOLE")))
+ if (!
+ (console_server = g_getenv("GNOCATAN_SERVER_CONSOLE")))
+ console_server = PIONEERS_SERVER_CONSOLE_PATH;
+ return console_server;
+}
+
+static void client_create_new_server(Client * client, gchar * line)
+{
+#ifdef HAVE_GETADDRINFO_ET_AL
+ char *terrain, *numplayers, *points, *sevens_rule, *numai, *type;
+ int fd, port_used;
+ gboolean found_used = TRUE;
+ socklen_t yes = 1;
+ struct sockaddr_in sa;
+ const char *console_server;
+ unsigned int n;
+ GList *list;
+ GSpawnFlags spawn_flags = G_SPAWN_STDOUT_TO_DEV_NULL |
+ G_SPAWN_STDERR_TO_DEV_NULL;
+ gchar *child_argv[32];
+ gchar *port;
+ GError *error = NULL;
+
+ line += strspn(line, " \t");
+ terrain = line;
+ line += strspn(line, "0123456789");
+ if (line == terrain)
+ goto bad;
+ *line++ = 0;
+ line += strspn(line, " \t");
+ numplayers = line;
+ line += strspn(line, "0123456789");
+ if (line == numplayers)
+ goto bad;
+ *line++ = 0;
+ line += strspn(line, " \t");
+ points = line;
+ line += strspn(line, "0123456789");
+ if (line == points)
+ goto bad;
+ *line++ = 0;
+ line += strspn(line, " \t");
+ sevens_rule = line;
+ line += strspn(line, "0123456789");
+ if (line == points)
+ goto bad;
+ *line++ = 0;
+ line += strspn(line, " \t");
+ numai = line;
+ line += strspn(line, "0123456789");
+ if (line == points)
+ goto bad;
+ *line++ = 0;
+ line += strspn(line, " \t");
+ type = line;
+ line += strlen(line) - 1;
+ while (line >= type && isspace(*line))
+ *line-- = 0;
+ if (line < type)
+ goto bad;
+
+ console_server = get_server_path();
+
+ fd = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd < 0) {
+ client_printf(client, "Creating socket failed: %s\n",
+ g_strerror(errno));
+ return;
+ }
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) <
+ 0) {
+ client_printf(client, "Setting socket reuse failed: %s\n",
+ g_strerror(errno));
+ return;
+ }
+ sa.sin_family = AF_INET;
+ if ((port_low == 0) && (port_high == 0)) {
+ sa.sin_port = 0;
+ } else {
+ for (port_used = port_low;
+ ((found_used == TRUE) && (port_used <= port_high));
+ port_used++) {
+ found_used = FALSE;
+ for (list = client_list; list != NULL;
+ list = g_list_next(list)) {
+ Client *scan = list->data;
+ if ((scan->port != NULL)
+ && (atoi(scan->port) == port_used)) {
+ found_used = TRUE;
+ }
+ }
+ if (found_used == FALSE) {
+ sa.sin_port = port_used;
+ }
+ }
+ if (found_used == TRUE) {
+ client_printf(client,
+ "Starting server failed: no port available\n");
+ return;
+ }
+ }
+ sa.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
+ client_printf(client, "Binding socket failed: %s\n",
+ g_strerror(errno));
+ return;
+ }
+ yes = sizeof(sa);
+ if (getsockname(fd, (struct sockaddr *) &sa, &yes) < 0) {
+ client_printf(client,
+ "Getting socket address failed: %s\n",
+ g_strerror(errno));
+ return;
+ }
+ port = g_strdup_printf("%d", sa.sin_port);
+
+ n = 0;
+ child_argv[n++] = g_strdup(console_server);
+ child_argv[n++] = g_strdup(console_server);
+ child_argv[n++] = g_strdup("-g");
+ child_argv[n++] = g_strdup(type);
+ child_argv[n++] = g_strdup("-P");
+ child_argv[n++] = g_strdup(numplayers);
+ child_argv[n++] = g_strdup("-v");
+ child_argv[n++] = g_strdup(points);
+ child_argv[n++] = g_strdup("-R");
+ child_argv[n++] = g_strdup(sevens_rule);
+ child_argv[n++] = g_strdup("-T");
+ child_argv[n++] = g_strdup(terrain);
+ child_argv[n++] = g_strdup("-p");
+ child_argv[n++] = g_strdup(port);
+ child_argv[n++] = g_strdup("-c");
+ child_argv[n++] = g_strdup(numai);
+ child_argv[n++] = g_strdup("-k");
+ child_argv[n++] = g_strdup("1200");
+ child_argv[n++] = g_strdup("-m");
+ child_argv[n++] = g_strdup(myhostname);
+ child_argv[n++] = g_strdup("-n");
+ child_argv[n++] = g_strdup(myhostname);
+ child_argv[n++] = g_strdup("-x");
+ child_argv[n++] = g_strdup("-r");
+ child_argv[n] = NULL;
+ g_assert(n < 32);
+
+ if (!g_spawn_async(NULL, child_argv, NULL, spawn_flags, NULL, NULL,
+ NULL, &error)) {
+ my_syslog(LOG_ERR, "cannot exec %s: %s", console_server,
+ error->message);
+ g_error_free(error);
+ }
+ for (n = 0; child_argv[n] != NULL; n++)
+ g_free(child_argv[n]);
+
+ client_printf(client, "host=%s\n", myhostname);
+ client_printf(client, "port=%s\n", port);
+ client_printf(client, "started\n");
+ my_syslog(LOG_INFO, "new local server started on port %s", port);
+ g_free(port);
+ return;
+ bad:
+ client_printf(client, "Badly formatted request\n");
+#else /* HAVE_GETADDRINFO_ET_AL */
+ client_printf(client,
+ "Create new server not yet supported on this platform'n");
+#endif /* HAVE_GETADDRINFO_ET_AL */
+}
+
+static gboolean check_str_info(gchar * line, const gchar * prefix,
+ gchar ** data)
+{
+ guint len = strlen(prefix);
+
+ if (strncmp(line, prefix, len) != 0)
+ return FALSE;
+ if (*data != NULL)
+ g_free(*data);
+ *data = g_strdup(line + len);
+ return TRUE;
+}
+
+static gboolean check_int_info(gchar * line, const gchar * prefix,
+ gint * data)
+{
+ guint len = strlen(prefix);
+
+ if (strncmp(line, prefix, len) != 0)
+ return FALSE;
+ *data = atoi(line + len);
+ return TRUE;
+}
+
+static void try_make_server_complete(Client * client)
+{
+ gboolean ok = FALSE;
+
+ if (client->type == META_SERVER) {
+ if (client->curr != client->previous_curr) {
+ my_syslog(LOG_INFO,
+ "server %s on port %s: now %d of %d players",
+ client->host, client->port, client->curr,
+ client->max);
+ client->previous_curr = client->curr;
+ }
+ return;
+ }
+
+ if (client->host != NULL
+ && client->port != NULL
+ && client->version != NULL
+ && client->max >= 0
+ && client->curr >= 0
+ && client->terrain != NULL && client->title != NULL) {
+ if (client->protocol_major < 1) {
+ if (!client->vpoints)
+ client->vpoints = g_strdup("?");
+ if (!client->sevenrule)
+ client->sevenrule = g_strdup("?");
+ ok = TRUE;
+ } else {
+ if (client->vpoints != NULL
+ && client->sevenrule != NULL)
+ ok = TRUE;
+ }
+ }
+
+ if (ok) {
+ client->type = META_SERVER;
+ my_syslog(LOG_INFO,
+ "server %s on port %s registered",
+ client->host, client->port);
+ }
+}
+
+static void get_peer_name(gint fd, gchar ** hostname, gchar ** servname)
+{
+ gchar *error_message;
+
+ if (!net_get_peer_name(fd, hostname, servname, &error_message)) {
+ my_syslog(LOG_ERR, "%s", error_message);
+ g_free(error_message);
+ }
+}
+
+static void client_process_line(Client * client, gchar * line)
+{
+ switch (client->type) {
+ case META_UNKNOWN:
+ case META_CLIENT:
+ if (strncmp(line, "version ", 8) == 0) {
+ char *p = line + 8;
+ client->protocol_major = atoi(p);
+ p += strspn(p, "0123456789");
+ if (*p == '.')
+ client->protocol_minor = atoi(p + 1);
+ } else if (strcmp(line, "listservers") == 0 ||
+ /* still accept "client" request from proto 0 clients
+ * so we don't have to distinguish between client versions */
+ strcmp(line, "client") == 0) {
+ client->type = META_CLIENT;
+ client_list_servers(client);
+ client->waiting_for_close = TRUE;
+ } else if (strcmp(line, "listtypes") == 0) {
+ client->type = META_CLIENT;
+ client_list_types(client);
+ client->waiting_for_close = TRUE;
+ } else if (strncmp(line, "create ", 7) == 0
+ && can_create_games) {
+ client->type = META_CLIENT;
+ client_create_new_server(client, line + 7);
+ client->waiting_for_close = TRUE;
+ } else if (strcmp(line, "server") == 0) {
+ client->type = META_SERVER_ALMOST;
+ client->max = client->curr = -1;
+ client->previous_curr = -1;
+ get_peer_name(client->fd, &client->host,
+ &client->port);
+ } else if (strcmp(line, "capability") == 0) {
+ client->type = META_CLIENT;
+ client_list_capability(client);
+ } else {
+ client_printf(client, "bad command\n");
+ client->waiting_for_close = TRUE;
+ }
+ break;
+ case META_SERVER:
+ case META_SERVER_ALMOST:
+ if (check_str_info(line, "host=", &client->host)
+ || check_str_info(line, "port=", &client->port)
+ || check_str_info(line, "version=", &client->version)
+ || check_int_info(line, "max=", &client->max)
+ || check_int_info(line, "curr=", &client->curr)
+ || check_str_info(line, "terrain=", &client->terrain)
+ || check_str_info(line, "title=", &client->title)
+ || check_str_info(line, "vpoints=", &client->vpoints)
+ || check_str_info(line, "sevenrule=",
+ &client->sevenrule)
+ /* meta-protocol 0.0 compat */
+ || check_str_info(line, "map=", &client->terrain)
+ || check_str_info(line, "comment=", &client->title))
+ try_make_server_complete(client);
+ else if (strcmp(line, "begin") == 0)
+ client_close(client);
+ break;
+ }
+}
+
+static int find_line(char *buff, int len)
+{
+ int idx;
+
+ for (idx = 0; idx < len; idx++)
+ if (buff[idx] == '\n')
+ return idx;
+ return -1;
+}
+
+static void client_do_read(Client * client)
+{
+ int num;
+ int offset;
+ gboolean finished;
+
+ if (client->read_len == sizeof(client->read_buff)) {
+ /* We are in trouble now - something has gone
+ * seriously wrong.
+ */
+ my_syslog(LOG_ERR, "read buffer overflow - disconnecting");
+ client_close(client);
+ return;
+ }
+
+ num = read(client->fd, client->read_buff + client->read_len,
+ sizeof(client->read_buff) - client->read_len);
+
+ if (num > 0) {
+ meta_debug("client_do_read: read(%d, %d) = %d, \"%.*s\"\n",
+ client->fd,
+ sizeof(client->read_buff) - client->read_len,
+ num, num, client->read_buff + client->read_len);
+ client->read_anything = TRUE;
+ } else if (num < 0) {
+ if (errno == EAGAIN)
+ return;
+ my_syslog(LOG_ERR, "reading socket: %s",
+ g_strerror(errno));
+ client_close(client);
+ return;
+ } else {
+ meta_debug("client_do_read: EOF seen on fd %d\n",
+ client->fd);
+ client_close(client);
+ return;
+ }
+
+ client->read_len += num;
+ offset = 0;
+ finished = FALSE;
+ while (offset < client->read_len) {
+ char *line = client->read_buff + offset;
+ int len = find_line(line, client->read_len - offset);
+
+ if (len < 0)
+ break;
+ line[len] = '\0';
+ offset += len + 1;
+
+ client_process_line(client, line);
+ }
+
+ if (offset < client->read_len) {
+ /* Did not process all data in buffer - discard
+ * processed data and copy remaining data to beginning
+ * of buffer until next time
+ */
+ memmove(client->read_buff, client->read_buff + offset,
+ client->read_len - offset);
+ client->read_len -= offset;
+ } else
+ /* Processed all data in buffer, discard it
+ */
+ client->read_len = 0;
+
+ set_client_event_at(client);
+}
+
+static void accept_new_client(void)
+{
+ int fd;
+ gchar *error_message;
+ Client *client;
+
+ fd = net_accept(accept_fd, &error_message);
+ if (fd < 0) {
+ my_syslog(LOG_ERR, "%s", error_message);
+ g_free(error_message);
+ return;
+ }
+ if (fd > max_fd)
+ max_fd = fd;
+
+ client = g_malloc0(sizeof(*client));
+ client_list = g_list_append(client_list, client);
+
+ client->type = META_UNKNOWN;
+ client->protocol_major = 0;
+ client->protocol_minor = 0;
+ client->fd = fd;
+
+ if (redirect_location != NULL) {
+ client_printf(client, "goto %s\n", redirect_location);
+ client->waiting_for_close = TRUE;
+ } else {
+ client_printf(client,
+ "welcome to the pioneers-meta-server version %s\n",
+ META_PROTOCOL_VERSION);
+ FD_SET(client->fd, &read_fds);
+ }
+ set_client_event_at(client);
+}
+
+static struct timeval *find_next_delay(void)
+{
+ GList *list;
+ static struct timeval timeout;
+ time_t now = time(NULL);
+
+ timeout.tv_sec = 30 * 60 * 60; /* 30 minutes */
+ timeout.tv_usec = 0;
+
+ for (list = client_list; list != NULL; list = g_list_next(list)) {
+ Client *client = list->data;
+ time_t delay;
+
+ if (now > client->event_at)
+ delay = 0;
+ else
+ delay = client->event_at - now;
+
+ if (delay < timeout.tv_sec)
+ timeout.tv_sec = delay;
+ }
+
+ return &timeout;
+}
+
+static void reap_children(void)
+{
+ int dummy;
+
+ while (waitpid(-1, &dummy, WNOHANG) > 0);
+}
+
+static void check_timeouts(void)
+{
+ time_t now = time(NULL);
+ GList *list;
+
+ list = client_list;
+ while (list != NULL) {
+ Client *client = list->data;
+ list = g_list_next(list);
+
+ if (now < client->event_at)
+ continue;
+ if (client->event_func == NULL)
+ client_close(client);
+ else
+ client->event_func(client);
+ }
+}
+
+static void select_loop(void)
+{
+ for (;;) {
+ fd_set read_res;
+ fd_set write_res;
+ int num;
+ struct timeval *timeout;
+ GList *list;
+
+ reap_children();
+ check_timeouts();
+ timeout = find_next_delay();
+
+ read_res = read_fds;
+ write_res = write_fds;
+
+ num =
+ select(max_fd + 1, &read_res, &write_res, NULL,
+ timeout);
+ if (num < 0) {
+ if (errno == EINTR)
+ continue;
+ else {
+ my_syslog(LOG_ALERT,
+ "could not select: %s",
+ g_strerror(errno));
+ exit(1);
+ }
+ }
+
+ if (FD_ISSET(accept_fd, &read_res)) {
+ accept_new_client();
+ num--;
+ }
+
+ list = client_list;
+ while (num > 0 && list != NULL) {
+ Client *client = list->data;
+ list = g_list_next(list);
+
+ if (client->fd >= 0
+ && FD_ISSET(client->fd, &read_res)) {
+ client_do_read(client);
+ num--;
+ }
+ if (client->fd >= 0
+ && FD_ISSET(client->fd, &write_res)) {
+ client_do_write(client);
+ num--;
+ }
+
+ if (client->waiting_for_close
+ && client->write_queue == NULL)
+ client_close(client);
+
+ if (client->fd < 0)
+ client_free(client);
+ }
+ }
+}
+
+static gboolean setup_accept_sock(const gchar * port)
+{
+ int fd;
+ gchar *error_message;
+
+ fd = net_open_listening_socket(port, &error_message);
+ if (fd == -1) {
+ my_syslog(LOG_ERR, "%s", error_message);
+ g_free(error_message);
+ return FALSE;
+ }
+ accept_fd = max_fd = fd;
+ FD_SET(accept_fd, &read_fds);
+ return TRUE;
+}
+
+static void convert_to_daemon(void)
+{
+ pid_t pid;
+
+ pid = fork();
+ if (pid < 0) {
+ my_syslog(LOG_ALERT, "could not fork: %s",
+ g_strerror(errno));
+ exit(1);
+ }
+ if (pid != 0)
+ /* I am the parent, if I exit then init(8) will become
+ * my the parent of the child process
+ */
+ exit(0);
+
+ /* Create a new session to become a process group leader
+ */
+ if (setsid() < 0) {
+ my_syslog(LOG_ALERT, "could not setsid: %s",
+ g_strerror(errno));
+ exit(1);
+ }
+ if (chdir("/") < 0) {
+ my_syslog(LOG_ALERT, "could not chdir to /: %s",
+ g_strerror(errno));
+ exit(1);
+ }
+ umask(0);
+}
+
+static GOptionEntry commandline_entries[] = {
+ {"daemon", 'd', 0, G_OPTION_ARG_NONE, &make_daemon,
+ /* Commandline meta-server: daemon */
+ N_("Daemonize the metaserver on start"), NULL},
+ {"redirect", 'r', 0, G_OPTION_ARG_STRING, &redirect_location,
+ /* Commandline meta-server: redirect */
+ N_("Redirect clients to another metaserver"), NULL},
+ {"servername", 's', 0, G_OPTION_ARG_STRING, &myhostname,
+ /* Commandline meta-server: server */
+ N_("Use this hostname when creating new games"),
+ /* Commandline meta-server: server argument */
+ N_("hostname")},
+ {"port-range", 'p', 0, G_OPTION_ARG_STRING, &port_range,
+ /* Commandline meta-server: port-range */
+ N_("Use this ports range when creating new games"),
+ /* Commandline meta-server: port-range argument */
+ N_("from-to")},
+ {"debug", '\0', 0, G_OPTION_ARG_NONE, &enable_debug,
+ /* Commandline option of meta server: enable debug logging */
+ N_("Enable debug messages"), NULL},
+ {"syslog-debug", '\0', 0, G_OPTION_ARG_NONE, &enable_syslog_debug,
+ /* Commandline option of meta server: syslog-debug */
+ N_("Debug syslog messages"), NULL},
+ {"version", '\0', 0, G_OPTION_ARG_NONE, &show_version,
+ /* Commandline option of meta server: version */
+ N_("Show version information"), NULL},
+ {NULL, '\0', 0, 0, NULL, NULL, NULL}
+};
+
+int main(int argc, char *argv[])
+{
+ GOptionContext *context;
+ GError *error = NULL;
+ GList *game_list;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /* have gettext return strings in UTF-8 */
+ bind_textdomain_codeset(PACKAGE, "UTF-8");
+
+ /* Long description in the commandline for server-console: help */
+ context = g_option_context_new(_("- Meta server for Pioneers"));
+ g_option_context_add_main_entries(context,
+ commandline_entries, PACKAGE);
+ g_option_context_parse(context, &argc, &argv, &error);
+ if (error != NULL) {
+ g_print("%s\n", error->message);
+ g_error_free(error);
+ return 1;
+ };
+
+ if (show_version) {
+ g_print(_("Pioneers version:"));
+ g_print(" ");
+ g_print(FULL_VERSION);
+ g_print(", ");
+ g_print(_("metaserver protocol:"));
+ g_print(" ");
+ g_print(META_PROTOCOL_VERSION);
+ g_print("\n");
+ return 0;
+ }
+ set_enable_debug(enable_debug);
+
+ if (port_range) {
+ gint count;
+
+ count = sscanf(port_range, "%d-%d", &port_low, &port_high);
+ if ((count != 2) || (port_low < 0)
+ || (port_low > port_high)) {
+ g_print("Port range '%s' is not valid\n",
+ port_range);
+ return 1;
+ }
+ }
+
+ net_init();
+ openlog("pioneers-meta", LOG_PID, LOG_USER);
+ if (make_daemon)
+ convert_to_daemon();
+
+ can_create_games = FALSE;
+ game_list = load_game_types();
+ if (game_list) {
+ gchar *server_name;
+ g_list_free(game_list);
+ server_name = g_find_program_in_path(get_server_path());
+ if (server_name) {
+ g_free(server_name);
+#ifdef HAVE_GETADDRINFO_ET_AL
+ can_create_games = TRUE;
+#endif /* HAVE_GETADDRINFO_ET_AL */
+ }
+ }
+
+ if (!myhostname)
+ myhostname = get_meta_server_name(FALSE);
+ if (!setup_accept_sock(PIONEERS_DEFAULT_META_PORT))
+ return 1;
+
+ my_syslog(LOG_INFO, "Pioneers meta server started.");
+ select_loop();
+
+ net_finish();
+ return 0;
+}
Added: trunk/omf.make
===================================================================
--- trunk/omf.make (rev 0)
+++ trunk/omf.make 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,61 @@
+#
+# No modifications of this Makefile should be necessary.
+#
+# This file contains the build instructions for installing OMF files. It is
+# generally called from the makefiles for particular formats of documentation.
+#
+# Note that you must configure your package with --localstatedir=/var
+# so that the scrollkeeper-update command below will update the database
+# in the standard scrollkeeper directory.
+#
+# If it is impossible to configure with --localstatedir=/var, then
+# modify the definition of scrollkeeper_localstate_dir so that
+# it points to the correct location. Note that you must still use
+# $(localstatedir) in this or when people build RPMs it will update
+# the real database on their system instead of the one under RPM_BUILD_ROOT.
+#
+# Note: This make file is not incorporated into xmldocs.make because, in
+# general, there will be other documents install besides XML documents
+# and the makefiles for these formats should also include this file.
+#
+# About this file:
+# This file was derived from scrollkeeper_example2, a package
+# illustrating how to install documentation and OMF files for use with
+# ScrollKeeper 0.3.x and 0.4.x. For more information, see:
+# http://scrollkeeper.sourceforge.net/
+# Version: 0.1.3 (last updated: March 20, 2002)
+#
+
+omf_dest_dir=$(datadir)/omf/@PACKAGE@
+scrollkeeper_localstate_dir = $(localstatedir)/scrollkeeper
+
+# At some point, it may be wise to change to something like this:
+# scrollkeeper_localstate_dir = @SCROLLKEEPER_STATEDIR@
+
+omf: omf_timestamp
+
+omf_timestamp: $(omffile)
+ -for file in $(omffile); do \
+ scrollkeeper-preinstall $(docdir)/$(docname).xml $(srcdir)/$$file $$file.out; \
+ done; \
+ touch omf_timestamp
+
+install-data-hook-omf:
+ $(mkinstalldirs) $(DESTDIR)$(omf_dest_dir)
+ for file in $(omffile); do \
+ $(INSTALL_DATA) $$file.out $(DESTDIR)$(omf_dest_dir)/$$file; \
+ done
+ -scrollkeeper-update -p $(scrollkeeper_localstate_dir) -o $(DESTDIR)$(omf_dest_dir)
+
+uninstall-local-omf:
+ -for file in $(srcdir)/*.omf; do \
+ basefile=`basename $$file`; \
+ rm -f $(omf_dest_dir)/$$basefile; \
+ done
+ -rmdir $(omf_dest_dir)
+ -scrollkeeper-update -p $(scrollkeeper_localstate_dir)
+
+clean-local-omf:
+ -for file in $(omffile); do \
+ rm -f $$file.out; \
+ done
Added: trunk/pioneers.nsi.in
===================================================================
--- trunk/pioneers.nsi.in (rev 0)
+++ trunk/pioneers.nsi.in 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,560 @@
+; Script generated with the aid of the HM NIS Edit Script Wizard.
+; Adapted for Pioneers by Roland Clobus <rclobus at bigfoot.com>
+
+;Global Variables
+Var FOUND_GTK_VERSION
+
+!define GTK_VERSION "@GTK_REQUIRED_VERSION@"
+!define GTK_UPGRADE_TEXT "(Minimum version: ${GTK_VERSION}, current version: $FOUND_GTK_VERSION)"
+!define GTK_NOT_FOUND_TEXT "(Minimum version: ${GTK_VERSION}) If you just installed the runtime, try to reboot first."
+
+; HM NIS Edit Wizard helper defines
+!define PRODUCT_NAME "Pioneers"
+!define PRODUCT_VERSION "@VERSION@"
+!define PRODUCT_WEB_SITE "http://pio.sf.net"
+!define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\pioneers.exe"
+!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
+!define PRODUCT_UNINST_ROOT_KEY "HKLM"
+!define PRODUCT_STARTMENU_REGVAL "NSIS:StartMenuDir"
+
+SetCompressor bzip2
+
+; MUI 1.67 compatible ------
+!include "MUI.nsh"
+
+; MUI Settings
+!define MUI_ABORTWARNING
+!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
+!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
+
+; Language Selection Dialog Settings
+!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
+!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
+!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"
+
+; Check whether the Gtk+ runtime is installed
+!define MUI_PAGE_CUSTOMFUNCTION_PRE preWelcomePage
+; Welcome page
+!insertmacro MUI_PAGE_WELCOME
+; License page
+!insertmacro MUI_PAGE_LICENSE "COPYING"
+; Components page
+!insertmacro MUI_PAGE_COMPONENTS
+; Directory page
+!insertmacro MUI_PAGE_DIRECTORY
+; Start menu page
+var ICONS_GROUP
+!define MUI_STARTMENUPAGE_NODISABLE
+!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Pioneers"
+!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
+!define MUI_STARTMENUPAGE_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
+!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${PRODUCT_STARTMENU_REGVAL}"
+!insertmacro MUI_PAGE_STARTMENU Application $ICONS_GROUP
+; Instfiles page
+!insertmacro MUI_PAGE_INSTFILES
+; Finish page
+!define MUI_FINISHPAGE_RUN "$INSTDIR\pioneers.exe"
+!insertmacro MUI_PAGE_FINISH
+
+; Uninstaller pages
+!insertmacro MUI_UNPAGE_INSTFILES
+
+; Language files
+!insertmacro MUI_LANGUAGE "Afrikaans"
+!insertmacro MUI_LANGUAGE "Dutch"
+!insertmacro MUI_LANGUAGE "English"
+!insertmacro MUI_LANGUAGE "French"
+!insertmacro MUI_LANGUAGE "German"
+!insertmacro MUI_LANGUAGE "Hungarian"
+!insertmacro MUI_LANGUAGE "Japanese"
+!insertmacro MUI_LANGUAGE "Spanish"
+!insertmacro MUI_LANGUAGE "Swedish"
+
+; Reserve files
+!insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
+
+; MUI end ------
+
+Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
+OutFile "Pioneers-${PRODUCT_VERSION}-setup.exe"
+InstallDir "$PROGRAMFILES\Pioneers"
+InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
+ShowInstDetails show
+ShowUnInstDetails show
+
+Function .onInit
+ !insertmacro MUI_LANGDLL_DISPLAY
+FunctionEnd
+
+Section "!Minimal install" SEC01
+ SetOutPath "$INSTDIR"
+ SetOverwrite ifnewer
+ File "..\..\..\local\pioneers.exe"
+
+ SetOverwrite TRY
+; Translations
+ SetOutPath "$INSTDIR\locale\af\LC_MESSAGES"
+ File "..\..\..\local\locale\af\LC_MESSAGES\pioneers.mo"
+ SetOutPath "$INSTDIR\locale\de\LC_MESSAGES"
+ File "..\..\..\local\locale\de\LC_MESSAGES\pioneers.mo"
+ SetOutPath "$INSTDIR\locale\es\LC_MESSAGES"
+ File "..\..\..\local\locale\es\LC_MESSAGES\pioneers.mo"
+ SetOutPath "$INSTDIR\locale\fr\LC_MESSAGES"
+ File "..\..\..\local\locale\fr\LC_MESSAGES\pioneers.mo"
+ SetOutPath "$INSTDIR\locale\hu\LC_MESSAGES"
+ File "..\..\..\local\locale\hu\LC_MESSAGES\pioneers.mo"
+ SetOutPath "$INSTDIR\locale\it\LC_MESSAGES"
+ File "..\..\..\local\locale\it\LC_MESSAGES\pioneers.mo"
+ SetOutPath "$INSTDIR\locale\ja\LC_MESSAGES"
+ File "..\..\..\local\locale\ja\LC_MESSAGES\pioneers.mo"
+ SetOutPath "$INSTDIR\locale\nl\LC_MESSAGES"
+ File "..\..\..\local\locale\nl\LC_MESSAGES\pioneers.mo"
+ SetOutPath "$INSTDIR\locale\sv\LC_MESSAGES"
+ File "..\..\..\local\locale\sv\LC_MESSAGES\pioneers.mo"
+; No man pages for Windows native distribution
+; SetOutPath "$INSTDIR\man\man6"
+; File "..\..\..\local\man\man6\pioneers-meta-server.6"
+; File "..\..\..\local\man\man6\pioneers-server-console.6"
+; File "..\..\..\local\man\man6\pioneers-server-gtk.6"
+; File "..\..\..\local\man\man6\pioneers.6"
+; File "..\..\..\local\man\man6\pioneersai.6"
+; Main toolbar icons
+ SetOutPath "$INSTDIR\pixmaps\pioneers"
+ File "..\..\..\local\pixmaps\pioneers\bridge.png"
+ File "..\..\..\local\pixmaps\pioneers\city.png"
+ File "..\..\..\local\pixmaps\pioneers\city_wall.png"
+ File "..\..\..\local\pixmaps\pioneers\develop.png"
+ File "..\..\..\local\pixmaps\pioneers\dice.png"
+ File "..\..\..\local\pixmaps\pioneers\finish.png"
+ File "..\..\..\local\pixmaps\pioneers\road.png"
+ File "..\..\..\local\pixmaps\pioneers\settlement.png"
+ File "..\..\..\local\pixmaps\pioneers\ship.png"
+ File "..\..\..\local\pixmaps\pioneers\ship_move.png"
+ File "..\..\..\local\pixmaps\pioneers\splash.png"
+ File "..\..\..\local\pixmaps\pioneers\trade.png"
+ File "..\..\..\local\pixmaps\pioneers\brick.png"
+ File "..\..\..\local\pixmaps\pioneers\grain.png"
+ File "..\..\..\local\pixmaps\pioneers\ore.png"
+ File "..\..\..\local\pixmaps\pioneers\wool.png"
+ File "..\..\..\local\pixmaps\pioneers\lumber.png"
+ File "..\..\..\local\pixmaps\pioneers\style-ai.png"
+ File "..\..\..\local\pixmaps\pioneers\style-human.png"
+ File "..\..\..\local\pixmaps\pioneers\style-human-1.png"
+ File "..\..\..\local\pixmaps\pioneers\style-human-2.png"
+ File "..\..\..\local\pixmaps\pioneers\style-human-3.png"
+ File "..\..\..\local\pixmaps\pioneers\style-human-4.png"
+ File "..\..\..\local\pixmaps\pioneers\style-human-5.png"
+ File "..\..\..\local\pixmaps\pioneers\style-human-6.png"
+ File "..\..\..\local\pixmaps\pioneers\style-human-7.png"
+; Themes
+ SetOutPath "$INSTDIR\themes"
+ File "..\..\..\local\themes\board.png"
+ File "..\..\..\local\themes\desert.png"
+ File "..\..\..\local\themes\field.png"
+ File "..\..\..\local\themes\forest.png"
+ File "..\..\..\local\themes\gold.png"
+ File "..\..\..\local\themes\hill.png"
+ File "..\..\..\local\themes\mountain.png"
+ File "..\..\..\local\themes\pasture.png"
+ File "..\..\..\local\themes\plain.png"
+ File "..\..\..\local\themes\sea.png"
+ SetOutPath "$INSTDIR\themes\FreeCIV-like"
+ File "..\..\..\local\themes\FreeCIV-like\board.png"
+ File "..\..\..\local\themes\FreeCIV-like\desert.png"
+ File "..\..\..\local\themes\FreeCIV-like\field.png"
+ File "..\..\..\local\themes\FreeCIV-like\forest.png"
+ File "..\..\..\local\themes\FreeCIV-like\hill.png"
+ File "..\..\..\local\themes\FreeCIV-like\mountain.png"
+ File "..\..\..\local\themes\FreeCIV-like\pasture.png"
+ File "..\..\..\local\themes\FreeCIV-like\sea.png"
+ File "..\..\..\local\themes\FreeCIV-like\theme.cfg"
+ SetOutPath "$INSTDIR\themes\Iceland"
+ File "..\..\..\local\themes\Iceland\desert.png"
+ File "..\..\..\local\themes\Iceland\field_grain.png"
+ File "..\..\..\local\themes\Iceland\forest_lumber.png"
+ File "..\..\..\local\themes\Iceland\gold.png"
+ File "..\..\..\local\themes\Iceland\hill_brick.png"
+ File "..\..\..\local\themes\Iceland\mountain_ore.png"
+ File "..\..\..\local\themes\Iceland\pasture_wool.png"
+ File "..\..\..\local\themes\Iceland\theme.cfg"
+ SetOutPath "$INSTDIR\themes\Tiny"
+ File "..\..\..\local\themes\Tiny\board.png"
+ File "..\..\..\local\themes\Tiny\brick-lorindol.png"
+ File "..\..\..\local\themes\Tiny\brick-port.png"
+ File "..\..\..\local\themes\Tiny\desert-lorindol.png"
+ File "..\..\..\local\themes\Tiny\gold-lorindol.png"
+ File "..\..\..\local\themes\Tiny\grain-lorindol.png"
+ File "..\..\..\local\themes\Tiny\grain-port.png"
+ File "..\..\..\local\themes\Tiny\lumber-lorindol.png"
+ File "..\..\..\local\themes\Tiny\lumber-port.png"
+ File "..\..\..\local\themes\Tiny\ore-lorindol.png"
+ File "..\..\..\local\themes\Tiny\ore-port.png"
+ File "..\..\..\local\themes\Tiny\sea-lorindol.png"
+ File "..\..\..\local\themes\Tiny\theme.cfg"
+ File "..\..\..\local\themes\Tiny\wool-lorindol.png"
+ File "..\..\..\local\themes\Tiny\wool-port.png"
+ SetOutPath "$INSTDIR\themes\Wesnoth-like"
+ File "..\..\..\local\themes\Wesnoth-like\board.png"
+ File "..\..\..\local\themes\Wesnoth-like\desert.png"
+ File "..\..\..\local\themes\Wesnoth-like\field.png"
+ File "..\..\..\local\themes\Wesnoth-like\forest.png"
+ File "..\..\..\local\themes\Wesnoth-like\gold.png"
+ File "..\..\..\local\themes\Wesnoth-like\hill.png"
+ File "..\..\..\local\themes\Wesnoth-like\mountain.png"
+ File "..\..\..\local\themes\Wesnoth-like\pasture.png"
+ File "..\..\..\local\themes\Wesnoth-like\sea.png"
+ File "..\..\..\local\themes\Wesnoth-like\theme.cfg"
+
+; Shortcuts
+ SetOutPath "$INSTDIR"
+ !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+ CreateDirectory "$SMPROGRAMS\$ICONS_GROUP"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Pioneers.lnk" "$INSTDIR\pioneers.exe"
+ CreateShortCut "$DESKTOP\Pioneers.lnk" "$INSTDIR\pioneers.exe"
+ !insertmacro MUI_STARTMENU_WRITE_END
+SectionEnd
+
+Section /o "Additional programs" SEC02
+ SetOutPath "$INSTDIR"
+ SetOverwrite ifnewer
+ File "..\..\..\local\pioneersai.exe"
+ File "..\..\..\local\pioneers-editor.exe"
+
+ SetOverwrite TRY
+ SetOutPath "$INSTDIR\games\pioneers"
+; Names for the AI
+ File "..\..\..\local\games\pioneers\computer_names"
+; Games for the editor (and server)
+ File "..\..\..\local\games\pioneers\5-6-player.game"
+ File "..\..\..\local\games\pioneers\Another_swimming_pool_in_the_wall.game"
+ File "..\..\..\local\games\pioneers\archipel_gold.game"
+ File "..\..\..\local\games\pioneers\canyon.game"
+ File "..\..\..\local\games\pioneers\coeur.game"
+ File "..\..\..\local\games\pioneers\conquest+ports.game"
+ File "..\..\..\local\games\pioneers\conquest.game"
+ File "..\..\..\local\games\pioneers\crane_island.game"
+ File "..\..\..\local\games\pioneers\Cube.game"
+ File "..\..\..\local\games\pioneers\default.game"
+ File "..\..\..\local\games\pioneers\Evil_square.game"
+ File "..\..\..\local\games\pioneers\four-islands.game"
+ File "..\..\..\local\games\pioneers\GuerreDe100ans.game"
+ File "..\..\..\local\games\pioneers\henjes.game"
+ File "..\..\..\local\games\pioneers\iles.game"
+ File "..\..\..\local\games\pioneers\lorindol.game"
+ File "..\..\..\local\games\pioneers\Mini_another_swimming_pool_in_the_wall.game"
+ File "..\..\..\local\games\pioneers\pond.game"
+ File "..\..\..\local\games\pioneers\seafarers-gold.game"
+ File "..\..\..\local\games\pioneers\seafarers.game"
+ File "..\..\..\local\games\pioneers\small.game"
+ File "..\..\..\local\games\pioneers\square.game"
+ File "..\..\..\local\games\pioneers\star.game"
+ File "..\..\..\local\games\pioneers\x.game"
+; Shortcuts
+ SetOutPath "$INSTDIR"
+ !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+ CreateDirectory "$SMPROGRAMS\$ICONS_GROUP"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Pioneers Editor.lnk" "$INSTDIR\pioneers-editor.exe"
+ CreateShortCut "$DESKTOP\Pioneers Editor.lnk" "$INSTDIR\pioneers-editor.exe"
+ !insertmacro MUI_STARTMENU_WRITE_END
+SectionEnd
+
+Section -AdditionalIcons
+ !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
+ WriteIniStr "$INSTDIR\${PRODUCT_NAME}.url" "InternetShortcut" "URL" "${PRODUCT_WEB_SITE}"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Website.lnk" "$INSTDIR\${PRODUCT_NAME}.url"
+ CreateShortCut "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk" "$INSTDIR\uninst.exe"
+ !insertmacro MUI_STARTMENU_WRITE_END
+SectionEnd
+
+Section -Post
+ WriteUninstaller "$INSTDIR\uninst.exe"
+ WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\pioneers.exe"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "UninstallString" "$INSTDIR\uninst.exe"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayIcon" "$INSTDIR\pioneers.exe"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}"
+ WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "URLInfoAbout" "${PRODUCT_WEB_SITE}"
+SectionEnd
+
+; Section descriptions
+!insertmacro MUI_FUNCTION_DESCRIPTION_BEGIN
+ !insertmacro MUI_DESCRIPTION_TEXT ${SEC01} "Play games of Pioneers"
+ !insertmacro MUI_DESCRIPTION_TEXT ${SEC02} "Install a game editor and a computer player"
+!insertmacro MUI_FUNCTION_DESCRIPTION_END
+
+
+Function un.onUninstSuccess
+ HideWindow
+ MessageBox MB_ICONINFORMATION|MB_OK "$(^Name) was successfully removed from your computer."
+FunctionEnd
+
+Function un.onInit
+!insertmacro MUI_UNGETLANGUAGE
+ MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "Are you sure you want to completely remove $(^Name) and all of its components?" IDYES +2
+ Abort
+FunctionEnd
+
+Section Uninstall
+ !insertmacro MUI_STARTMENU_GETFOLDER "Application" $ICONS_GROUP
+ Delete "$INSTDIR\${PRODUCT_NAME}.url"
+ Delete "$INSTDIR\uninst.exe"
+ Delete "$INSTDIR\pioneers-editor.exe"
+ Delete "$INSTDIR\pioneersai.exe"
+ Delete "$INSTDIR\pioneers.exe"
+ Delete "$INSTDIR\themes\sea.png"
+ Delete "$INSTDIR\themes\plain.png"
+ Delete "$INSTDIR\themes\pasture.png"
+ Delete "$INSTDIR\themes\mountain.png"
+ Delete "$INSTDIR\themes\hill.png"
+ Delete "$INSTDIR\themes\gold.png"
+ Delete "$INSTDIR\themes\forest.png"
+ Delete "$INSTDIR\themes\field.png"
+ Delete "$INSTDIR\themes\desert.png"
+ Delete "$INSTDIR\themes\board.png"
+ Delete "$INSTDIR\themes\Wesnoth-like\theme.cfg"
+ Delete "$INSTDIR\themes\Wesnoth-like\sea.png"
+ Delete "$INSTDIR\themes\Wesnoth-like\pasture.png"
+ Delete "$INSTDIR\themes\Wesnoth-like\mountain.png"
+ Delete "$INSTDIR\themes\Wesnoth-like\hill.png"
+ Delete "$INSTDIR\themes\Wesnoth-like\gold.png"
+ Delete "$INSTDIR\themes\Wesnoth-like\forest.png"
+ Delete "$INSTDIR\themes\Wesnoth-like\field.png"
+ Delete "$INSTDIR\themes\Wesnoth-like\desert.png"
+ Delete "$INSTDIR\themes\Wesnoth-like\board.png"
+ Delete "$INSTDIR\themes\Tiny\wool-port.png"
+ Delete "$INSTDIR\themes\Tiny\wool-lorindol.png"
+ Delete "$INSTDIR\themes\Tiny\theme.cfg"
+ Delete "$INSTDIR\themes\Tiny\sea-lorindol.png"
+ Delete "$INSTDIR\themes\Tiny\ore-port.png"
+ Delete "$INSTDIR\themes\Tiny\ore-lorindol.png"
+ Delete "$INSTDIR\themes\Tiny\lumber-port.png"
+ Delete "$INSTDIR\themes\Tiny\lumber-lorindol.png"
+ Delete "$INSTDIR\themes\Tiny\grain-port.png"
+ Delete "$INSTDIR\themes\Tiny\grain-lorindol.png"
+ Delete "$INSTDIR\themes\Tiny\gold-lorindol.png"
+ Delete "$INSTDIR\themes\Tiny\desert-lorindol.png"
+ Delete "$INSTDIR\themes\Tiny\brick-port.png"
+ Delete "$INSTDIR\themes\Tiny\brick-lorindol.png"
+ Delete "$INSTDIR\themes\Tiny\board.png"
+ Delete "$INSTDIR\themes\Iceland\theme.cfg"
+ Delete "$INSTDIR\themes\Iceland\pasture_wool.png"
+ Delete "$INSTDIR\themes\Iceland\mountain_ore.png"
+ Delete "$INSTDIR\themes\Iceland\hill_brick.png"
+ Delete "$INSTDIR\themes\Iceland\gold.png"
+ Delete "$INSTDIR\themes\Iceland\forest_lumber.png"
+ Delete "$INSTDIR\themes\Iceland\field_grain.png"
+ Delete "$INSTDIR\themes\Iceland\desert.png"
+ Delete "$INSTDIR\themes\FreeCIV-like\theme.cfg"
+ Delete "$INSTDIR\themes\FreeCIV-like\sea.png"
+ Delete "$INSTDIR\themes\FreeCIV-like\pasture.png"
+ Delete "$INSTDIR\themes\FreeCIV-like\mountain.png"
+ Delete "$INSTDIR\themes\FreeCIV-like\hill.png"
+ Delete "$INSTDIR\themes\FreeCIV-like\forest.png"
+ Delete "$INSTDIR\themes\FreeCIV-like\field.png"
+ Delete "$INSTDIR\themes\FreeCIV-like\desert.png"
+ Delete "$INSTDIR\themes\FreeCIV-like\board.png"
+ Delete "$INSTDIR\pixmaps\pioneers\style-human-7.png"
+ Delete "$INSTDIR\pixmaps\pioneers\style-human-6.png"
+ Delete "$INSTDIR\pixmaps\pioneers\style-human-5.png"
+ Delete "$INSTDIR\pixmaps\pioneers\style-human-4.png"
+ Delete "$INSTDIR\pixmaps\pioneers\style-human-3.png"
+ Delete "$INSTDIR\pixmaps\pioneers\style-human-2.png"
+ Delete "$INSTDIR\pixmaps\pioneers\style-human-1.png"
+ Delete "$INSTDIR\pixmaps\pioneers\style-human.png"
+ Delete "$INSTDIR\pixmaps\pioneers\style-ai.png"
+ Delete "$INSTDIR\pixmaps\pioneers\brick.png"
+ Delete "$INSTDIR\pixmaps\pioneers\grain.png"
+ Delete "$INSTDIR\pixmaps\pioneers\ore.png"
+ Delete "$INSTDIR\pixmaps\pioneers\wool.png"
+ Delete "$INSTDIR\pixmaps\pioneers\lumber.png"
+ Delete "$INSTDIR\pixmaps\pioneers\trade.png"
+ Delete "$INSTDIR\pixmaps\pioneers\splash.png"
+ Delete "$INSTDIR\pixmaps\pioneers\ship_move.png"
+ Delete "$INSTDIR\pixmaps\pioneers\ship.png"
+ Delete "$INSTDIR\pixmaps\pioneers\settlement.png"
+ Delete "$INSTDIR\pixmaps\pioneers\road.png"
+ Delete "$INSTDIR\pixmaps\pioneers\finish.png"
+ Delete "$INSTDIR\pixmaps\pioneers\dice.png"
+ Delete "$INSTDIR\pixmaps\pioneers\develop.png"
+ Delete "$INSTDIR\pixmaps\pioneers\city_wall.png"
+ Delete "$INSTDIR\pixmaps\pioneers\city.png"
+ Delete "$INSTDIR\pixmaps\pioneers\bridge.png"
+; Delete "$INSTDIR\man\man6\pioneersai.6"
+; Delete "$INSTDIR\man\man6\pioneers.6"
+; Delete "$INSTDIR\man\man6\pioneers-server-gtk.6"
+; Delete "$INSTDIR\man\man6\pioneers-server-console.6"
+; Delete "$INSTDIR\man\man6\pioneers-meta-server.6"
+ Delete "$INSTDIR\locale\sv\LC_MESSAGES\pioneers.mo"
+ Delete "$INSTDIR\locale\nl\LC_MESSAGES\pioneers.mo"
+ Delete "$INSTDIR\locale\ja\LC_MESSAGES\pioneers.mo"
+ Delete "$INSTDIR\locale\it\LC_MESSAGES\pioneers.mo"
+ Delete "$INSTDIR\locale\hu\LC_MESSAGES\pioneers.mo"
+ Delete "$INSTDIR\locale\fr\LC_MESSAGES\pioneers.mo"
+ Delete "$INSTDIR\locale\es\LC_MESSAGES\pioneers.mo"
+ Delete "$INSTDIR\locale\de\LC_MESSAGES\pioneers.mo"
+ Delete "$INSTDIR\locale\af\LC_MESSAGES\pioneers.mo"
+ Delete "$INSTDIR\games\pioneers\x.game"
+ Delete "$INSTDIR\games\pioneers\star.game"
+ Delete "$INSTDIR\games\pioneers\square.game"
+ Delete "$INSTDIR\games\pioneers\small.game"
+ Delete "$INSTDIR\games\pioneers\seafarers.game"
+ Delete "$INSTDIR\games\pioneers\seafarers-gold.game"
+ Delete "$INSTDIR\games\pioneers\pond.game"
+ Delete "$INSTDIR\games\pioneers\Mini_another_swimming_pool_in_the_wall.game"
+ Delete "$INSTDIR\games\pioneers\lorindol.game"
+ Delete "$INSTDIR\games\pioneers\iles.game"
+ Delete "$INSTDIR\games\pioneers\henjes.game"
+ Delete "$INSTDIR\games\pioneers\GuerreDe100ans.game"
+ Delete "$INSTDIR\games\pioneers\four-islands.game"
+ Delete "$INSTDIR\games\pioneers\Evil_square.game"
+ Delete "$INSTDIR\games\pioneers\default.game"
+ Delete "$INSTDIR\games\pioneers\Cube.game"
+ Delete "$INSTDIR\games\pioneers\crane_island.game"
+ Delete "$INSTDIR\games\pioneers\conquest.game"
+ Delete "$INSTDIR\games\pioneers\conquest+ports.game"
+ Delete "$INSTDIR\games\pioneers\computer_names"
+ Delete "$INSTDIR\games\pioneers\coeur.game"
+ Delete "$INSTDIR\games\pioneers\canyon.game"
+ Delete "$INSTDIR\games\pioneers\archipel_gold.game"
+ Delete "$INSTDIR\games\pioneers\Another_swimming_pool_in_the_wall.game"
+ Delete "$INSTDIR\games\pioneers\5-6-player.game"
+
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Uninstall.lnk"
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Website.lnk"
+ Delete "$DESKTOP\Pioneers.lnk"
+ Delete "$DESKTOP\Pioneers Editor.lnk"
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Pioneers.lnk"
+ Delete "$SMPROGRAMS\$ICONS_GROUP\Pioneers Editor.lnk"
+
+ RMDir "$SMPROGRAMS\$ICONS_GROUP"
+ RMDir "$INSTDIR\themes\Wesnoth-like"
+ RMDir "$INSTDIR\themes\Tiny"
+ RMDir "$INSTDIR\themes\Iceland"
+ RMDir "$INSTDIR\themes\FreeCIV-like"
+ RMDir "$INSTDIR\themes"
+ RMDir "$INSTDIR\pixmaps\pioneers"
+ RMDir "$INSTDIR\pixmaps"
+ RMDir "$INSTDIR\locale\sv\LC_MESSAGES"
+ RMDir "$INSTDIR\locale\sv"
+ RMDir "$INSTDIR\locale\nl\LC_MESSAGES"
+ RMDir "$INSTDIR\locale\nl"
+ RMDir "$INSTDIR\locale\ja\LC_MESSAGES"
+ RMDir "$INSTDIR\locale\ja"
+ RMDir "$INSTDIR\locale\it\LC_MESSAGES"
+ RMDir "$INSTDIR\locale\it"
+ RMDir "$INSTDIR\locale\hu\LC_MESSAGES"
+ RMDir "$INSTDIR\locale\hu"
+ RMDir "$INSTDIR\locale\fr\LC_MESSAGES"
+ RMDir "$INSTDIR\locale\fr"
+ RMDir "$INSTDIR\locale\es\LC_MESSAGES"
+ RMDir "$INSTDIR\locale\es"
+ RMDir "$INSTDIR\locale\de\LC_MESSAGES"
+ RMDir "$INSTDIR\locale\de"
+ RMDir "$INSTDIR\locale\af\LC_MESSAGES"
+ RMDir "$INSTDIR\locale\af"
+ RMDir "$INSTDIR\locale"
+ RMDir "$INSTDIR\games\pioneers"
+ RMDir "$INSTDIR\games"
+ RMDir "$INSTDIR"
+
+ DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}"
+ DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}"
+ SetAutoClose true
+SectionEnd
+
+!include "WordFunc.nsh"
+!insertMacro VersionCompare
+;
+; Usage:
+; Call DoWeNeedGtk
+; First Pop:
+; 0 - We have the correct version
+; Second Pop: Current version
+; 1 - We have an old version that needs to be upgraded
+; Second Pop: Current version
+; 2 - We don't have Gtk+ at all
+; Second Pop: "GTK+ not found"
+;
+; The version of the Gtk dll will be checked.
+; This means that the DLL must be found in the path,
+; using the default DLL location functions that Pioneers uses.
+;
+Function DoWeNeedGtk
+ Push $0
+ Push $2
+ Push $3
+ Push $4
+ Push $5
+
+ GetDllVersion "libgtk-win32-2.0-0.dll" $R0 $R1
+ IfErrors no_gtk
+ IntOp $R2 $R0 / 0x00010000
+ IntOp $R3 $R0 & 0x0000FFFF
+ IntOp $R4 $R1 / 0x00010000
+ IntOp $R5 $R1 & 0x0000FFFF
+ StrCpy $0 "$R2.$R3.$R4.$R5"
+
+ ; GTK+ is already installed.. check version.
+ ${VersionCompare} ${GTK_VERSION} $0 $2
+ StrCmp $2 "1" bad_version good_version
+ bad_version:
+ StrCpy $2 "1"
+ Push $0
+ Push $2
+ Goto done
+
+ good_version:
+ StrCpy $2 "0"
+ Push $0
+ Push $2
+ Goto done
+
+ no_gtk:
+ StrCpy $2 "2"
+ StrCpy $0 "GTK not found"
+ Push $0
+ Push $2
+ Goto done
+
+ done:
+ ; The top two items on the stack are what we want to return
+ Exch 5
+ Pop $0
+ Exch 5
+ Pop $2
+ Pop $5
+ Pop $4
+ Pop $3
+FunctionEnd
+
+Function preWelcomePage
+ ; If this installer doesn't have GTK, check whether we need it.
+ ; We do this here an not in .onInit because language change in
+ ; .onInit doesn't take effect until it is finished.
+ Push $R0
+ Push $R1
+ Call DoWeNeedGtk
+ Pop $R0
+ Pop $R1
+ StrCpy $FOUND_GTK_VERSION "$R1"
+
+ StrCmp $R0 "0" have_gtk might_need_gtk
+ might_need_gtk:
+ StrCmp $R0 "1" upgrade_gtk need_gtk
+ upgrade_gtk:
+ StrCpy $R0 "${GTK_UPGRADE_TEXT}"
+ Goto gtk_display_message
+ need_gtk:
+ StrCpy $R0 "${GTK_NOT_FOUND_TEXT}"
+ Goto gtk_display_message
+ gtk_display_message:
+ Push $R2
+ StrCpy $R2 "You need to the Gtk+ runtime first.$\n$R0$\n$\nThe runtime can be downloaded from$\nhttp://gimp-win.sourceforge.net/stable.html$\n$\nDo you want to continue anyway?"
+ MessageBox MB_ICONQUESTION|MB_YESNO "$R2" IDYES have_gtk IDNO no_gtk
+ Pop $R2
+ no_gtk:
+ Quit
+ have_gtk:
+ Pop $R1
+ Pop $R0
+FunctionEnd
Added: trunk/pioneers.spec.in
===================================================================
--- trunk/pioneers.spec.in (rev 0)
+++ trunk/pioneers.spec.in 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,168 @@
+Name: @PACKAGE_NAME@
+Summary: Playable implementation of the Settlers of Catan
+Version: @VERSION@
+Release: 1
+Group: Amusements/Games
+License: GPL
+Url: http://pio.sourceforge.net/
+Packager: The Pioneers developers <pio-develop at lists.sourceforge.net>
+Source: http://downloads.sourceforge.net/pio/@PACKAGE_TARNAME@-@VERSION@.tar.gz
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
+BuildRequires: libgnome-devel, scrollkeeper
+BuildRequires: gtk2-devel >= @GTK_REQUIRED_VERSION@
+BuildRequires: glib2-devel >= @GLIB_REQUIRED_VERSION@
+Requires(post): scrollkeeper
+
+%description
+Pioneers is an Internet playable implementation of the Settlers of
+Catan board game. The aim is to remain as faithful to the board game
+as is possible.
+
+This is the client software to play the game.
+
+%package ai
+Summary: Pioneers AI Player
+Group: Amusements/Games
+
+%description ai
+Pioneers is an Internet playable implementation of the Settlers of
+Catan board game. The aim is to remain as faithful to the board game
+as is possible.
+
+This package contains a computer player that can take part in Pioneers games.
+
+%package server-console
+Summary: Pioneers Console Server
+Group: Amusements/Games
+Requires: pioneers-server-data
+
+%description server-console
+Pioneers is an Internet playable implementation of the Settlers of
+Catan board game. The aim is to remain as faithful to the board game
+as is possible.
+
+%package server-gtk
+Summary: Pioneers GTK Server
+Group: Amusements/Games
+Requires: pioneers, pioneers-server-data
+
+%description server-gtk
+Pioneers is an Internet playable implementation of the Settlers of
+Catan board game. The aim is to remain as faithful to the board game
+as is possible.
+
+The server has a user interface in which you can customise the game
+parameters. Customisation is fairly limited at the moment, but this
+should change in later versions. Once you are happy with the game
+parameters, press the Start Server button, and the server will start
+listening for client connections.
+
+%package server-data
+Summary: Pioneers Data
+Group: Amusements/Games
+
+%description server-data
+Pioneers is an Internet playable implementation of the Settlers of
+Catan board game. The aim is to remain as faithful to the board game
+as is possible.
+
+This package contains the data files for a game server.
+
+%package meta-server
+Summary: Pioneers Meta Server
+Group: Amusements/Games
+
+%description meta-server
+Pioneers is an Internet playable implementation of the Settlers of
+Catan board game. The aim is to remain as faithful to the board game
+as is possible.
+
+The meta server registers available game servers and offers them to new
+players. It can also create new servers on client request.
+
+%package editor
+Summary: Pioneers Game Editor
+Group: Amusements/Games
+Requires: pioneers, pioneers-server-data
+
+%description editor
+Pioneers is an Internet playable implementation of the Settlers of
+Catan board game. The aim is to remain as faithful to the board game
+as is possible.
+
+The game editor allows maps and game descriptions to be created and edited
+graphically.
+
+%prep
+%setup -q
+
+%build
+%configure
+make
+
+%install
+make install DESTDIR="%buildroot"
+rm -rf %{buildroot}%{localstatedir}/scrollkeeper/
+%find_lang %{name}
+
+%clean
+rm -rf %{buildroot}
+
+%files -f %name.lang
+%defattr(-,root,root)
+%doc AUTHORS COPYING ChangeLog INSTALL README NEWS
+%doc %_mandir/man6/pioneers.6.gz
+%{_bindir}/pioneers
+%{_datadir}/applications/pioneers.desktop
+%{_datadir}/pixmaps/pioneers.png
+%{_datadir}/pixmaps/pioneers/*
+%{_datadir}/games/pioneers/themes/*
+%{_datadir}/gnome/help/pioneers/C/*.xml
+%{_datadir}/gnome/help/pioneers/C/images/*
+%{_datadir}/omf/pioneers/pioneers-C.omf
+
+%post
+scrollkeeper-update -q -o %{_datadir}/omf/pioneers
+
+%postun
+scrollkeeper-update -q
+
+%files ai
+%defattr(-,root,root)
+%doc AUTHORS COPYING ChangeLog INSTALL README NEWS
+%doc %_mandir/man6/pioneersai.6.gz
+%{_bindir}/pioneersai
+%{_datadir}/games/pioneers/computer_names
+
+%files server-console
+%defattr(-,root,root)
+%doc AUTHORS COPYING ChangeLog INSTALL README NEWS
+%doc %_mandir/man6/pioneers-server-console.6.gz
+%{_bindir}/pioneers-server-console
+
+%files server-gtk
+%defattr(-,root,root)
+%doc AUTHORS COPYING ChangeLog INSTALL README NEWS
+%doc %_mandir/man6/pioneers-server-gtk.6.gz
+%{_bindir}/pioneers-server-gtk
+%{_datadir}/pixmaps/pioneers-server.png
+%{_datadir}/applications/pioneers-server.desktop
+
+%files server-data
+%defattr(-,root,root)
+%doc AUTHORS COPYING ChangeLog INSTALL README NEWS
+%{_datadir}/games/pioneers/*.game
+
+%files meta-server
+%defattr(-,root,root)
+%doc %_mandir/man6/pioneers-meta-server.6.gz
+%doc AUTHORS COPYING ChangeLog INSTALL README NEWS
+%{_bindir}/pioneers-meta-server
+
+%files editor
+%defattr(-,root,root)
+%doc AUTHORS COPYING ChangeLog INSTALL README NEWS
+%{_bindir}/pioneers-editor
+%{_datadir}/pixmaps/pioneers-editor.png
+%{_datadir}/applications/pioneers-editor.desktop
+
Added: trunk/po/ChangeLog
===================================================================
--- trunk/po/ChangeLog (rev 0)
+++ trunk/po/ChangeLog 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,287 @@
+2007-10-07 Roland Clobus <rclobus at bigfoot.com>
+ * all: Updated linenumbers for 0.11.3 release
+ * de.po, fr.po, hu.po, it.po, ja.po, nl.po, sv.po: Updated version
+ number to 0.11.3
+
+2007-08-05 Roland Clobus <rclobus at bigfoot.com>
+ * all: Updated linenumbers for 0.11.2 release
+
+2007-07-22 Roland Clobus <rclobus at bigfoot.com>
+ * all: Updated to 0.11.1 release
+
+2007-07-22 Pit Garbe <piiit at gmx.de>
+ * de.po: Small update
+
+2007-07-21 Ferenc Bánhidi <bferike at mailbox.hu>
+ * hu.po: Updated for 0.11.1
+
+2007-07-20 Yasuhiko Takasugi <takasugi at flcl.org>
+ * ja.po: Small update
+
+2007-07-19 Yasuhiko Takasugi <takasugi at flcl.org>
+ * ja.po: Updated to 0.11.1
+
+2007-07-18 Giancarlo Capella <giancarlo at comm.cc>
+ * it.po: Updated to 0.11.1
+
+2007-07-17 Daniel Nylander <po at danielnylander.se>
+ * sv.po: Updated to 0.11.1
+
+2007-07-17 Jean-Charles GRANGER <traduction at vecteur.org>
+ * fr.po: Updated
+
+2007-07-16 Jean-Charles GRANGER <traduction at vecteur.org>
+ * fr.po: Updated to 0.11.1
+
+2007-07-14 Pit Garbe <piiit at gmx.de>
+ * de.po: Updated to 0.11.1
+
+2007-07-12 Roland Clobus <rclobus at bigfoot.com>
+ * nl.po: Updated to 0.11.1
+ * All: updated the *.po files for the pending release
+ The strings for player shape and the robber fix have also been
+ added.
+
+2007-05-13 Roland Clobus <rclobus at bigfoot.com>
+ * POTFILES.in: editor/gtk/game-settings.c was renamed to
+ common/gtk/game-rules.c
+ * POTFILES.in: common/game.c also contains translatable strings
+
+2007-04-08 Yasuhiko Takasugi <takasugi at flcl.org>
+ * ja.po: Updated (File date 2007-01-28)
+
+2007-04-08 Daniel Nylander <po at danielnylander.se>
+ * sv.po: Updated to 0.10.2 (File date 2007-01-10)
+
+2006-11-17 Roland Clobus <rclobus at bigfoot.com>
+ * All Project-Id-Version fields use the same style
+
+2006-11-16 Jean-Charles GRANGER <traduction at vecteur.org>
+ * fr.po: Updated
+
+2006-11-16 Petri Jooste <petri.jooste at gmail.com>
+ * af.po: Updated
+
+2006-11-14 Roland Clobus <rclobus at bigfoot.com>
+ * ja.po: Fixed the last fuzzy translation
+
+2006-11-13 Yasuhiko Takasugi <takasugi at flcl.org>
+ * ja.po: Updated
+
+2006-11-10 Jean-Charles GRANGER <traduction at vecteur.org>
+ * fr.po: Updated
+
+2006-11-10 Petri Jooste <petri.jooste at gmail.com>
+ * af.po: Updated
+
+2006-11-10 Yasuhiko Takasugi <takasugi at flcl.org>
+ * ja.po: Added initial version
+
+2006-10-19 Petri Jooste <petri.jooste at gmail.com>
+ * af.po: Added initial version
+
+2006-10-17 Roland Clobus <rclobus at bigfoot.com>
+ * de.po: Added shortcuts for the resources in the editor
+
+2006-10-17 Giancarlo Capella <giancarlo at comm.cc>
+ * it.po: Updated to 0.10.2
+
+2006-09-16 Roland Cloubs <rclobus at bigfoot.com>
+ * Release 0.10.2
+
+2006-09-13 Roland Clobus <rclobus at bigfoot.com>
+ * Updated templates for release 0.10.2
+ * nl.po: Updated
+
+2006-08-30 Roland Clobus <rclobus at bigfoot.com>
+ * nl.po: Fixed a typo
+
+2006-08-26 Roland Clobus <rclobus at bigfoot.com>
+ * Last update before the release of 0.10.1
+
+2006-08-23 Marco Antonio Giraldo <m.a.giraldo at rug.nl>
+ * es.po: Some corrections
+
+2006-08-21 Marco Antonio Giraldo <m.a.giraldo at rug.nl>
+ * es.po: Updated
+
+2006-08-20 Giancarlo Capella <giancarlo at comm.cc>
+ * it.po: Updated and converted to utf8
+
+2006-08-18 Daniel Nylander <po at danielnylander.se>
+ * sv.po: Updated
+
+2006-08-17 Roland Clobus <rclobus at bigfoot.com>
+ * Updated templates for release 0.10.1
+ * nl.po: Updated
+
+2006-08-11 Pit Garbe <piiit at gmx.de>
+ * de.po: Small correction
+
+2006-08-10 Roland Clobus <rclobus at bigfoot.com>
+ * Updated templates for 0.10.1
+ * nl.po: Updated for 0.10.1
+
+2006-08-06 Roland Clobus <rclobus at bigfoot.com>
+ * de.po: Use Lehm instead of Stein for brick
+
+2006-08-05 Roland Clobus <rclobus at bigfoot.com>
+ * POTFILES.in: added client/ai/lobbybot.c, removed client/common/chat.c
+
+2006-07-24 Roland Clobus <rclobus at bigfoot.com>
+ * it.po: Restored old translations for quote-view.c
+
+2006-07-05 Roland Clobus <rclobus at bigfoot.com>
+ * Translation markup removed for g_error and g_warning messages
+ * Updated all templates
+
+2006-07-05 Ronny Standtke <Ronny.Standtke at gmx.net>
+ * POTFILES.in: added missing quote-view.c
+ * de.po: Added missing translations
+
+2006-06-23 Daniel Nylander <po at danielnylander.se>
+ * sv.po: Updated for 0.9.64
+
+2006-06-23 Pit Garbe <piiit at gmx.de>
+ * de.po: Updated for 0.9.64
+
+2006-05-28 Roland Clobus <rclobus at bigfoot.com>
+ * Regenerated all, update case changes
+
+2006-05-24 LT-P <LT-P at LT-P.net>
+ * fr.po: Some updates
+
+2006-05-24 Giancarlo Capella <giancarlo at comm.cc>
+ * it.po: Updated for 0.9.62 (621t)
+
+2006-05-23 Roland Clobus <rclobus at bigfoot.com>
+ * Updated templates for 0.9.62
+ * nl.po: Updated for 0.9.62 (621t)
+
+2006-03-08 Ferenc Bánhidi <banhidi at inf.elte.hu>
+ * hu.po: Updated for 0.9.61
+
+2006-03-08 Roland Clobus <rclobus at bigfoot.com>
+ * fr.po: Updated translations for ports
+
+2006-03-08 Giancarlo Capella <giancarlo at comm.cc>
+ * it.po: Minor updates
+
+2006-03-07 LT-P <LT-P at LT-P.net>
+ * fr.po: Updated for 0.9.61, changed encoding to UTF-8
+
+2006-03-07 Daniel Nylander <po at danielnylander.se>
+ * sv.po : Updated for 0.9.61
+
+2006-03-04 Roland Clobus <rclobus at bigfoot.com>
+ * nl.po: Updated for 0.9.61
+
+2006-03-04 Giancarlo Capella <giancarlo at comm.cc>
+ * it.po: Updated for 0.9.61
+
+2006-02-02 Daniel Nylander <po at danielnylander.se>
+ * sv.po: Added the missing translations
+
+2006-01-25 Roland Clobus <rclobus at bigfoot.com>
+ * nl.po: Added the new strings
+ * de.po, fr.po, it.po: Removed some obviously wrong translated fuzzy
+ entries
+ * Updated line numbers to match 0.9.49
+
+2006-01-12 Daniel Nylander <po at danielnylander.se>
+ * sv.po: Added Swedish translation
+
+2005-12-30 Roland Clobus <rclobus at bigfoot.com>
+ * nl.po: Fixed a typo
+
+2005-12-21 Roland Clobus <rclobus at bigfoot.com>
+ * Updated the translations to match the 0.9.40 release
+ * nl.po: Added one translation
+
+2005-11-16 Roland Clobus <rclobus at bigfoot.com>
+ * nl.po: Fixed 2 typos
+
+2005-10-02 Roland Clobus <rclobus at bigfoot.com>
+ * Updated line numbers to match 0.9.32
+
+2005-09-09 Ferenc Bánhidi <banhidi at inf.elte.hu>
+ * hu.po: Added Hungarian translation
+
+2005-08-14 Roland Clobus <rclobus at bigfoot.com>
+ * Added formatting tags to modified strings in 0.9.22
+ * nl.po: Added a new string
+
+2005-07-14 Roland Clobus <rclobus at bigfoot.com>
+ * Updated the translations for the shortcut keys in the toolbar,
+ removed again in 0.9.19
+
+2005-07-06 Giancarlo Capella <giancarlo at comm.cc>
+ * it.po: Updated to 0.9.17
+
+2005-07-03 Roland Clobus <rclobus at bigfoot.com>
+ * Updated for Q_() patch
+
+2005-07-03 Jens Seidel <jensseidel at users.sf.net>
+ * de.po: Minor translation update (Debian bug #314082)
+
+2005-06-30 Roland Clobus <rclobus at bigfoot.com>
+ * nl.po, pioneers.pot: Complete Gnocatan free
+
+2005-06-25 Steve Langasek <vorlon at debian.org>
+ * pioneers.pot: new gettext package name
+ * de.po, es.po, fr.po, it.po, nl.po: sync translations to
+ match the Gnocatan->Pioneers rebranding, where possible
+ * de.po, nl.po: fix up a C string translation in each of these
+ files which gets rejected by current gettext as being invalid
+
+2005-06-05 Roland Clobus <rclobus at bigfoot.com>
+ * fr.po, nl.po: Updated for Q_() patch
+
+2005-05-01 Roland Clobus <rclobus at bigfoot.com>
+ * Updated to build 0.9.11
+
+2005-04-26 Roland Clobus <rclobus at bigfoot.com>
+ * nl.po: Updated Dutch translations to CVS 0.9.10
+ * it.po: Removed clearly wrong Italian translations
+
+2005-03-20 Roland Clobus <rclobus at bigfoot.com>
+ * Updated to build 0.8.1.57
+
+2005-03-02 Roland Clobus <rclobus at bigfoot.com>
+ * Updated to build 0.8.1.54
+
+2005-02-03 Roland Clobus <rclobus at bigfoot.com>
+ * Updated translations to build 0.8.1.52
+ * es.po: Removed some clearly wrong translations
+
+2005-01-09 Roland Clobus <rclobus at bigfoot.com>
+ * Marked several clearly wrong translations as not translated instead
+ of fuzzy.
+
+2004-11-21 Roland Clobus <rclobus at bigfoot.com>
+ * Applied bold tags to translations, where applicable
+
+2004-11-05 LT-P <LT-P at LT-P.net>
+ * fr.po: Spelling corrections
+
+2004-10-27 Roland Clobus <rclobus at bigfoot.com>
+ * Updated all files to fit 0.8.1.41
+ * nl.po: Added the missing translations. Changed translation of 'chat'
+
+2004-10-13 Roland Clobus <rclobus at bigfoot.com>
+ * nl.po: fixing a typo
+
+2004-10-01 Roland Clobus <rclobus at bigfoot.com>
+ * POTFILES.in: Regenerated from scratch, removed admin-gtk.c (old)
+ * Updated all files to fit 0.8.1.37
+
+2004-09-26 Roland Clobus <rclobus at bigfoot.com>
+ * .cvsignore: Added Makefile.in.in, it is a generated file
+ * POTFILES.in: Added client/ai/greedy.c, server/turn.c
+
+2004-09-15 Arjen Schrijver <a.schrijver at skydec.nl>
+ * nl.po: fixing a typo
+
+2004-09-15 Roland Clobus <rclobus at bigfoot.com>
+ * ChangeLog: Added the ChangeLog again, it is required for
+ 'make distcheck' and automake-1.7
Added: trunk/po/Makefile.in.in
===================================================================
--- trunk/po/Makefile.in.in (rev 0)
+++ trunk/po/Makefile.in.in 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,269 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper at gnu.ai.mit.edu>
+#
+# This file file 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.
+#
+# - Modified by Owen Taylor <otaylor at redhat.com> to use GETTEXT_PACKAGE
+# instead of PACKAGE and to look for po2tbl in ./ not in intl/
+#
+# - Modified by jacob berkman <jacob at ximian.com> to install
+# Makefile.in.in and po2tbl.sed.in for use with glib-gettextize
+
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+ at SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = @datadir@
+libdir = @libdir@
+localedir = $(libdir)/locale
+gnulocaledir = $(datadir)/locale
+gettextsrcdir = $(datadir)/glib-2.0/gettext/po
+subdir = po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = $(top_srcdir)/@MKINSTALLDIRS@
+
+CC = @CC@
+GENCAT = @GENCAT@
+GMSGFMT = @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = @XGETTEXT@
+MSGMERGE = msgmerge
+
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+
+INCLUDES = -I.. -I$(top_srcdir)/intl
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+SOURCES =
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(GETTEXT_PACKAGE).pot \
+$(POFILES) $(GMOFILES) $(SOURCES)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
+
+.c.o:
+ $(COMPILE) $<
+
+.po.pox:
+ $(MAKE) $(GETTEXT_PACKAGE).pot
+ $(MSGMERGE) $< $(srcdir)/$(GETTEXT_PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.gmo:
+ file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -c -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && $(GENCAT) $@ $*.msg
+
+
+all: all- at USE_NLS@
+
+all-yes: $(CATALOGS)
+all-no:
+
+$(srcdir)/$(GETTEXT_PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(GETTEXT_PACKAGE) --directory=$(top_srcdir) \
+ --add-comments --keyword=_ --keyword=N_ \
+ --flag=g_strdup_printf:1:c-format \
+ --flag=g_string_printf:2:c-format \
+ --flag=g_string_append_printf:2:c-format \
+ --flag=g_error_new:3:c-format \
+ --flag=g_set_error:4:c-format \
+ --flag=g_markup_printf_escaped:1:c-format \
+ --flag=g_log:3:c-format \
+ --flag=g_print:1:c-format \
+ --flag=g_printerr:1:c-format \
+ --flag=g_printf:1:c-format \
+ --flag=g_fprintf:2:c-format \
+ --flag=g_sprintf:2:c-format \
+ --flag=g_snprintf:3:c-format \
+ --flag=g_scanner_error:2:c-format \
+ --flag=g_scanner_warn:2:c-format \
+ --files-from=$(srcdir)/POTFILES.in \
+ && test ! -f $(GETTEXT_PACKAGE).po \
+ || ( rm -f $(srcdir)/$(GETTEXT_PACKAGE).pot \
+ && mv $(GETTEXT_PACKAGE).po $(srcdir)/$(GETTEXT_PACKAGE).pot )
+
+install: install-exec install-data
+install-exec:
+install-data: install-data- at USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r "$(MKINSTALLDIRS)"; then \
+ $(MKINSTALLDIRS) $(DESTDIR)$(datadir); \
+ else \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir); \
+ fi
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ case "$$cat" in \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
+ esac; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ dir=$(DESTDIR)$$destdir/$$lang/LC_MESSAGES; \
+ if test -r "$(MKINSTALLDIRS)"; then \
+ $(MKINSTALLDIRS) $$dir; \
+ else \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $$dir; \
+ fi; \
+ if test -r $$cat; then \
+ $(INSTALL_DATA) $$cat $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \
+ echo "installing $$cat as $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT)"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT)"; \
+ fi; \
+ if test -r $$cat.m; then \
+ $(INSTALL_DATA) $$cat.m $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $$cat.m as $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ if test -r $(srcdir)/$$cat.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$cat.m \
+ $$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+ if test "$(PACKAGE)" = "glib"; then \
+ if test -r "$(MKINSTALLDIRS)"; then \
+ $(MKINSTALLDIRS) $(DESTDIR)$(gettextsrcdir); \
+ else \
+ $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(gettextsrcdir); \
+ fi; \
+ $(INSTALL_DATA) $(srcdir)/Makefile.in.in \
+ $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT); \
+ rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE)$(INSTOBJEXT).m; \
+ done
+ if test "$(PACKAGE)" = "glib"; then \
+ rm -f $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \
+ fi
+
+check: all
+
+dvi info tags TAGS ID:
+
+mostlyclean:
+ rm -f core core.* *.pox $(GETTEXT_PACKAGE).po *.old.po cat-id-tbl.tmp
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f $(GMOFILES)
+
+distdir = ../$(GETTEXT_PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: update-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ for file in $$dists; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(GETTEXT_PACKAGE).pot
+ tmpdir=`pwd`; \
+ cd $(srcdir); \
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \
+ echo "$$lang:"; \
+ if $(MSGMERGE) $$lang.po $(GETTEXT_PACKAGE).pot -o $$tmpdir/$$lang.new.po; then \
+ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+ rm -f $$tmpdir/$$lang.new.po; \
+ else \
+ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+ :; \
+ else \
+ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
+ rm -f $$tmpdir/$$lang.new.po; \
+ exit 1; \
+ fi; \
+ fi; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$tmpdir/$$lang.new.po; \
+ fi; \
+ done
+
+# POTFILES is created from POTFILES.in by stripping comments, empty lines
+# and Intltool tags (enclosed in square brackets), and appending a full
+# relative path to them
+POTFILES: POTFILES.in
+ ( if test 'x$(srcdir)' != 'x.'; then \
+ posrcprefix='$(top_srcdir)/'; \
+ else \
+ posrcprefix="../"; \
+ fi; \
+ rm -f $@-t $@ \
+ && (sed -e '/^#/d' \
+ -e "s/^\[.*\] +//" \
+ -e '/^[ ]*$$/d' \
+ -e "s at .*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \
+ | sed -e '$$s/\\$$//') > $@-t \
+ && chmod a-w $@-t \
+ && mv $@-t $@ )
+
+Makefile: Makefile.in.in ../config.status POTFILES
+ cd .. \
+ && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \
+ $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Added: trunk/po/POTFILES.in
===================================================================
--- trunk/po/POTFILES.in (rev 0)
+++ trunk/po/POTFILES.in 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,53 @@
+client/ai/ai.c
+client/ai/greedy.c
+client/ai/lobbybot.c
+client/common/client.c
+client/common/develop.c
+client/common/player.c
+client/common/resource.c
+client/common/robber.c
+client/common/setup.c
+client/common/turn.c
+client/gtk/chat.c
+client/gtk/connect.c
+client/gtk/develop.c
+client/gtk/discard.c
+client/gtk/gameover.c
+client/gtk/gold.c
+client/gtk/gui.c
+client/gtk/histogram.c
+client/gtk/interface.c
+client/gtk/legend.c
+client/gtk/monopoly.c
+client/gtk/name.c
+client/gtk/offline.c
+client/gtk/player.c
+client/gtk/plenty.c
+client/gtk/quote.c
+client/gtk/quote-view.c
+client/gtk/resource.c
+client/gtk/resource-table.c
+client/gtk/settingscreen.c
+client/gtk/trade.c
+common/gtk/aboutbox.c
+common/gtk/game-rules.c
+common/gtk/game-settings.c
+common/gtk/guimap.c
+common/gtk/select-game.c
+common/gtk/theme.c
+common/game.c
+common/log.c
+common/network.c
+common/state.c
+editor/gtk/editor.c
+editor/gtk/game-buildings.c
+editor/gtk/game-devcards.c
+editor/gtk/game-resources.c
+meta-server/main.c
+server/admin.c
+server/gtk/main.c
+server/main.c
+server/meta.c
+server/player.c
+server/server.c
+server/turn.c
Added: trunk/po/af.po
===================================================================
--- trunk/po/af.po (rev 0)
+++ trunk/po/af.po 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,3104 @@
+# Pioneers - Settlers of Catan for GNOME.
+# This file is distributed under the same license as the pioneers package.
+#
+# Petri Jooste <petri.jooste at gmail.com>, 2006.
+# Petri Jooste <Petri.Jooste at nwu.ac.za>, 2006.
+msgid ""
+msgstr ""
+"Project-Id-Version: Pioneers 0.10.2\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-07 20:43+0200\n"
+"PO-Revision-Date: 2006-11-11 01:38+0200\n"
+"Last-Translator: Petri Jooste <petri.jooste at gmail.com>\n"
+"Language-Team: Afrikaans <af at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Afrikaans\n"
+"X-Generator: KBabel 1.11.2\n"
+
+#. Default name for the AI when the computer_names file
+#. * is not found or empty.
+#.
+#: client/ai/ai.c:74 client/ai/ai.c:90
+msgid "Computer Player"
+msgstr "Robotspeler"
+
+#. Commandline pioneersai: server
+#. Commandline option of client: hostname of the server
+#: client/ai/ai.c:102 client/gtk/connect.c:1462 client/gtk/offline.c:53
+msgid "Server Host"
+msgstr "Bedienernaam"
+
+#. Commandline pioneersai: port
+#. Commandline option of client: port of the server
+#: client/ai/ai.c:105 client/gtk/connect.c:1478 client/gtk/offline.c:56
+#: server/gtk/main.c:612
+msgid "Server Port"
+msgstr "Bedienerpoort"
+
+#. Commandline pioneersai: name
+#: client/ai/ai.c:108
+msgid "Computer name (leave absent for random name)"
+msgstr "Naam vir robotspeler (leeg = enige naam)"
+
+#. Commandline pioneersai: time
+#: client/ai/ai.c:111
+msgid "Time to wait between turns (in milliseconds)"
+msgstr "Tyd om te wag tussen beurte (in millisekondes)"
+
+#. Commandline pioneersai: chat-free
+#: client/ai/ai.c:114
+msgid "Stop computer player from talking"
+msgstr "Robotspelers moenie gesels nie"
+
+#. Commandline pioneersai: algorithm
+#: client/ai/ai.c:117
+msgid "Type of computer player"
+msgstr "Tipe robotspeler"
+
+#. Commandline option of ai: enable debug logging
+#. Commandline option of client: enable debug logging
+#. Commandline option of meta server: enable debug logging
+#. Commandline option of server-gtk: enable debug logging
+#. Commandline option of server: enable debug logging
+#: client/ai/ai.c:120 client/gtk/offline.c:74 meta-server/main.c:1049
+#: server/gtk/main.c:952 server/main.c:144
+msgid "Enable debug messages"
+msgstr "Skakel ontfoutboodskappe aan"
+
+#. Commandline option of ai: version
+#. Commandline option of client: version
+#. Commandline option of editor: version
+#. Commandline option of meta server: version
+#. Commandline option of server-gtk: version
+#. Commandline option of server-console: version
+#: client/ai/ai.c:123 client/gtk/offline.c:77 editor/gtk/editor.c:1071
+#: meta-server/main.c:1055 server/gtk/main.c:955 server/main.c:99
+msgid "Show version information"
+msgstr "Wys weergawe-inligting"
+
+#: client/ai/ai.c:134
+msgid "- Computer player for Pioneers"
+msgstr "- Robotspeler vir Pioniers"
+
+#: client/ai/ai.c:144 client/gtk/offline.c:186 editor/gtk/editor.c:1111
+#: meta-server/main.c:1084 server/gtk/main.c:1005 server/main.c:206
+#, c-format
+msgid "Pioneers version:"
+msgstr "Pioniers weergawe:"
+
+#: client/ai/ai.c:176
+#, c-format
+msgid "Type of computer player: %s\n"
+msgstr "Tipe robotspeler: %s\n"
+
+#: client/ai/ai.c:205
+msgid "The game is already full. I'm leaving."
+msgstr "Die spel is reeds vol. Ek gaan weg."
+
+#: client/ai/greedy.c:941
+msgid "No settlements in stock to use for setup"
+msgstr "Geen dorpe in voorraad om op te stel nie"
+
+#: client/ai/greedy.c:948
+msgid "There is no place to setup a settlement"
+msgstr "Daar is nie plek om 'n dorp te bou nie"
+
+#: client/ai/greedy.c:972
+msgid "No roads in stock to use for setup"
+msgstr "Geen paaie in voorraad om op te stel nie"
+
+#: client/ai/greedy.c:989
+msgid "There is no place to setup a road"
+msgstr "Daar is nie plek om 'n pad te bou nie"
+
+#: client/ai/greedy.c:1291
+msgid "Ok, let's go!"
+msgstr "Goed, kom ons begin!"
+
+#: client/ai/greedy.c:1292
+msgid "I'll beat you all now! ;)"
+msgstr "Nou gaan ek julle almal wen! ;)"
+
+#: client/ai/greedy.c:1293
+msgid "Now for another try..."
+msgstr "Nou vir nog 'n probeerslag ..."
+
+#: client/ai/greedy.c:1297
+msgid "At least I get something..."
+msgstr "Ten minste kry ek iets ..."
+
+#: client/ai/greedy.c:1298
+msgid "One is better than none..."
+msgstr "Een is beter as niks!"
+
+#: client/ai/greedy.c:1302
+msgid "Wow!"
+msgstr "Wow!"
+
+#: client/ai/greedy.c:1303
+msgid "Ey, I'm becoming rich ;)"
+msgstr "Kyk net, ek word nou ryk ;-)"
+
+#: client/ai/greedy.c:1304
+msgid "This is really a good year!"
+msgstr "Hierdie is regtig 'n goeie jaar vir my!"
+
+#: client/ai/greedy.c:1307
+msgid "You really don't deserve that much!"
+msgstr "Jy verdien nie regtig soveel nie!"
+
+#: client/ai/greedy.c:1308
+msgid "You don't know what to do with that many resources ;)"
+msgstr "Jy sal nie weet wat om met soveel hulpbronne te maak nie ;-)"
+
+#: client/ai/greedy.c:1309
+msgid "Ey, wait for my robber and lose all this again!"
+msgstr "Toemaar, wag net vir my rower en jy verloor dit alles weer!"
+
+#: client/ai/greedy.c:1312
+msgid "Hehe!"
+msgstr "He he he!"
+
+#: client/ai/greedy.c:1313
+msgid "Go, robber, go!"
+msgstr "Rower, hou so aan!"
+
+#: client/ai/greedy.c:1316
+msgid "You bastard!"
+msgstr "Jou vuilgoed!"
+
+#: client/ai/greedy.c:1317
+msgid "Can't you move that robber somewhere else?!"
+msgstr "Kan jy nie dalk die rower iewers anders heen skuif nie?!"
+
+#: client/ai/greedy.c:1318
+msgid "Why always me??"
+msgstr "Hoekom altyd ek??"
+
+#: client/ai/greedy.c:1321
+msgid "Oh no!"
+msgstr "Ag Nee!"
+
+#: client/ai/greedy.c:1322
+msgid "Grrr!"
+msgstr "Grrr!"
+
+#: client/ai/greedy.c:1323
+msgid "Who the hell rolled that 7??"
+msgstr "Wie de duiwel het daardie 7 gerol??"
+
+#: client/ai/greedy.c:1324
+msgid "Why always me?!?"
+msgstr "Hoekom altyd ek?!?"
+
+#: client/ai/greedy.c:1327
+msgid "Say good bye to your cards... :)"
+msgstr "Sê totsiens vir jou kaarte ... :-)"
+
+#: client/ai/greedy.c:1328
+msgid "*evilgrin*"
+msgstr "*grynslag*"
+
+#: client/ai/greedy.c:1329
+msgid "/me says farewell to your cards ;)"
+msgstr "/me sê vaarwel aan jou kaarte ;-)"
+
+#: client/ai/greedy.c:1330
+msgid "That's the price for being rich... :)"
+msgstr "Dit is wat dit kos om ryk te wees ... :-)"
+
+#: client/ai/greedy.c:1333
+msgid "Ey! Where's that card gone?"
+msgstr "Haai! Waar is daardie kaart heen?"
+
+#: client/ai/greedy.c:1334
+msgid "Thieves! Thieves!!"
+msgstr "Dief! Dief!!"
+
+#: client/ai/greedy.c:1335
+msgid "Wait for my revenge..."
+msgstr "Wag maar net tot ek wraak neem ..."
+
+#: client/ai/greedy.c:1338
+msgid "Oh no :("
+msgstr "Ag Nee :("
+
+#: client/ai/greedy.c:1339
+msgid "Must this happen NOW??"
+msgstr "Moet dit NOU gebeur??"
+
+#: client/ai/greedy.c:1340
+msgid "Args"
+msgstr "Args"
+
+#: client/ai/greedy.c:1343
+msgid "Hehe, my soldiers rule!"
+msgstr "Ha ha ha, my soldate is die beste!"
+
+#: client/ai/greedy.c:1346
+msgid "First robbing us, then grabbing the points..."
+msgstr "Eers beroof jy ons, dan gryp jy die punte..."
+
+#: client/ai/greedy.c:1349
+msgid "See that road!"
+msgstr "Kyk daardie pad!"
+
+#: client/ai/greedy.c:1352
+msgid "Pf, you won't win with roads alone..."
+msgstr "Gmf, jy sal nie met paaie alleen kan wen nie..."
+
+#: client/ai/greedy.c:1819
+msgid "Rejecting trade.\n"
+msgstr "Handel word afgewys.\n"
+
+#: client/ai/greedy.c:1911
+#, c-format
+msgid "Received error from server: %s. Quitting\n"
+msgstr "Foutboodskap ontvang van bediener: %s. Besig om uit te gaan\n"
+
+#: client/ai/greedy.c:1921
+msgid "Yippie!"
+msgstr "Jippie!"
+
+#: client/ai/greedy.c:1923
+msgid "My congratulations"
+msgstr "Geluk van my kant af!"
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:80
+msgid ""
+"Hello, welcome to the lobby. I am a simple robot. Type '/help' in the chat "
+"to see the list of commands I know."
+msgstr ""
+"Hallo, welkom in die voorportaal. Ek is 'n eenvoudige robot. Tik '/help' in "
+"die geselsvenster om te sien watter opdragte ek ken."
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:107
+msgid "'/help' shows this message again"
+msgstr "'/help' sal weer hierdie boodskap wys"
+
+#. Translators: don't translate '/why'
+#: client/ai/lobbybot.c:110
+msgid "'/why' explains the purpose of this strange board layout"
+msgstr "'/why' sal verduidelik wat die doel is met hierdie vreemde borduitleg"
+
+#. Translators: don't translate '/news'
+#: client/ai/lobbybot.c:113
+msgid "'/news' tells the last released version"
+msgstr "'/news' sal wys wat is die mees onlangse weergawe"
+
+#: client/ai/lobbybot.c:118
+msgid ""
+"This board is not intended to be a game that can be played. Instead, players "
+"can find eachother here, and decide which board they want to play. Then, one "
+"of the players will host the proposed game by starting a server, and "
+"registers it at the metaserver. The other players can subsequently "
+"disconnect from the lobby, and enter that game."
+msgstr ""
+"Hierdie bord word nie bedoel as 'n spel wat gespeel moet word nie. Spelers "
+"kan mekaar hier ontmoet en dan besluit watter bord hulle wil speel. Dan "
+"moet een van die spelers die voorgestelde spel opstel en aanbied deur 'n "
+"bediener daarvoor aan die gang te sit en dit by 'n metabediener te "
+"registreer. Die ander spelers kan daarna die voorportaal verlaat en by die "
+"nuwe spel aansluit."
+
+#: client/ai/lobbybot.c:129
+msgid "The last released version of Pioneers is"
+msgstr "Die mees onlangse weergawe van Pioniers is"
+
+#: client/ai/lobbybot.c:144
+msgid "The game is starting. I'm not needed anymore. Goodbye."
+msgstr "Die spel begin nou. Ek word nie meer hier benodig nie. Totsiens."
+
+#: client/common/client.c:103
+msgid "Waiting"
+msgstr "Wagtend"
+
+#: client/common/client.c:105 client/common/client.c:1241
+msgid "Idle"
+msgstr "Ledig"
+
+#: client/common/client.c:447
+msgid "We have been kicked out of the game.\n"
+msgstr "Ons is uit die spel geskop.\n"
+
+#. Network status: offline
+#: client/common/client.c:450 client/common/client.c:891 client/gtk/gui.c:1340
+msgid "Offline"
+msgstr "Nie gekoppel nie"
+
+#: client/common/client.c:471
+#, c-format
+msgid "Error (%s): %s\n"
+msgstr "Fout (%s): %s\n"
+
+#: client/common/client.c:480 client/common/client.c:491
+#, c-format
+msgid "Notice: %s\n"
+msgstr "Kennisgewing: %s\n"
+
+#: client/common/client.c:607
+#, c-format
+msgid "%s does not receive any %s, because the bank is empty.\n"
+msgstr "%s ontvang geen %s nie, want die bank is leeg.\n"
+
+#: client/common/client.c:620
+#, c-format
+msgid "%s only receives %s, because the bank didn't have any more.\n"
+msgstr "%s ontvang slegs %s, want die bank het nie meer daarvan oor nie.\n"
+
+#: client/common/client.c:629
+#, c-format
+msgid "%s receives %s.\n"
+msgstr "%s ontvang %s.\n"
+
+#. Year of Plenty
+#: client/common/client.c:637 client/common/client.c:2586
+#, c-format
+msgid "%s takes %s.\n"
+msgstr "%s vat %s.\n"
+
+#: client/common/client.c:642
+#, c-format
+msgid "%s spent %s.\n"
+msgstr "%s spandeer %s.\n"
+
+#: client/common/client.c:648
+#, c-format
+msgid "%s is refunded %s.\n"
+msgstr "%s word %s terugbetaal.\n"
+
+#: client/common/client.c:679
+#, c-format
+msgid "%s discarded %s.\n"
+msgstr "%s weggegooi %s.\n"
+
+#: client/common/client.c:849
+msgid "Loading"
+msgstr "Laai tans"
+
+#: client/common/client.c:892
+msgid "Version mismatch"
+msgstr "Weergawes pas nie"
+
+#: client/common/client.c:894
+msgid "Version mismatch. Please make sure client and server are up to date.\n"
+msgstr ""
+"Weergawes pas nie. Maak asb. seker die kliënt en bediener is op datum.\n"
+
+#: client/common/client.c:1340
+msgid "Build two settlements, each with a connecting"
+msgstr "Bou twee dorpe, elkeen met 'n verbindende"
+
+#: client/common/client.c:1343
+msgid "Build a settlement with a connecting"
+msgstr "Bou 'n dorp met 'n verbindende"
+
+#: client/common/client.c:1346
+msgid "road"
+msgstr "pad"
+
+#: client/common/client.c:1348
+msgid "bridge"
+msgstr "brug"
+
+#: client/common/client.c:1350
+msgid "ship"
+msgstr "skip"
+
+#: client/common/client.c:1358
+msgid " or"
+msgstr " of"
+
+#: client/common/client.c:1416
+msgid "Waiting for your turn"
+msgstr "Wag vir jou beurt"
+
+#: client/common/client.c:1468
+msgid "Select the building to steal from."
+msgstr "Kies die gebou om van te steel."
+
+#: client/common/client.c:1490
+msgid "Select the ship to steal from."
+msgstr "Kies die skip om van te steel."
+
+#: client/common/client.c:1575 client/gtk/interface.c:782
+msgid "Place the robber"
+msgstr "Plaas die rower"
+
+#: client/common/client.c:1625
+msgid "Finish the road building action."
+msgstr "Maak die padbou klaar."
+
+#: client/common/client.c:1627
+msgid "Build one road segment."
+msgstr "Bou een padsegment."
+
+#: client/common/client.c:1629
+msgid "Build two road segments."
+msgstr "Bou twee padsegmente."
+
+#: client/common/client.c:1902 client/common/client.c:1996
+msgid "It is your turn."
+msgstr "Dit is jou beurt."
+
+#: client/common/client.c:2090
+#, c-format
+msgid "Sorry, %s available.\n"
+msgstr "Jammer, %s is beskikbaar.\n"
+
+#: client/common/client.c:2405
+msgid "The game is over."
+msgstr "Die spel is verby."
+
+#: client/common/develop.c:43 editor/gtk/game-devcards.c:13
+msgid "Road Building"
+msgstr "Padbou"
+
+#: client/common/develop.c:44 client/gtk/monopoly.c:83
+#: editor/gtk/game-devcards.c:13
+msgid "Monopoly"
+msgstr "Monopolie"
+
+#: client/common/develop.c:45 client/gtk/plenty.c:59
+#: editor/gtk/game-devcards.c:13
+msgid "Year of Plenty"
+msgstr "Oorvloedjaar"
+
+#: client/common/develop.c:46 client/gtk/player.c:57
+#: editor/gtk/game-devcards.c:14
+msgid "Chapel"
+msgstr "Kapel"
+
+#: client/common/develop.c:47 client/gtk/player.c:58
+#: editor/gtk/game-devcards.c:14
+msgid "Pioneer University"
+msgstr "Pionier Universiteit"
+
+#: client/common/develop.c:48 client/gtk/player.c:60
+#: editor/gtk/game-devcards.c:15
+msgid "Governor's House"
+msgstr "Ampswoning"
+
+#: client/common/develop.c:49 client/gtk/player.c:61
+#: editor/gtk/game-devcards.c:15
+msgid "Library"
+msgstr "Biblioteek"
+
+#: client/common/develop.c:50 client/gtk/player.c:62
+#: editor/gtk/game-devcards.c:15
+msgid "Market"
+msgstr "Mark"
+
+#: client/common/develop.c:51 client/gtk/player.c:63
+#: editor/gtk/game-devcards.c:16
+msgid "Soldier"
+msgstr "Soldaat"
+
+#: client/common/develop.c:82
+#, c-format
+msgid "You bought the %s development card.\n"
+msgstr "Jy het die %s ontwikkelingskaart gekoop.\n"
+
+#: client/common/develop.c:88
+#, c-format
+msgid "You bought a %s development card.\n"
+msgstr "Jy het 'n %s ontwikkelingskaart gekoop.\n"
+
+#: client/common/develop.c:110
+#, c-format
+msgid "%s bought a development card.\n"
+msgstr "%s het 'n ontwikkelingskaart gekoop.\n"
+
+#: client/common/develop.c:129
+#, c-format
+msgid "%s played the %s development card.\n"
+msgstr "%s het die %s ontwikkelingskaart gespeel.\n"
+
+#: client/common/develop.c:134
+#, c-format
+msgid "%s played a %s development card.\n"
+msgstr "%s het 'n %s ontwikkelingskaart gespeel.\n"
+
+#: client/common/develop.c:147
+msgid "You have run out of road segments.\n"
+msgstr "Jy het nie meer padsegmente oor nie.\n"
+
+#. I get the cards!
+#.
+#: client/common/develop.c:187
+#, c-format
+msgid "You get %s from %s.\n"
+msgstr "Jy kry %s vanaf %s.\n"
+
+#. I lose the cards!
+#.
+#: client/common/develop.c:193
+#, c-format
+msgid "%s took %s from you.\n"
+msgstr "%s het %s by jou gevat.\n"
+
+#: client/common/develop.c:200
+#, c-format
+msgid "%s took %s from %s.\n"
+msgstr "%s het %s by %s gevat.\n"
+
+#: client/common/player.c:124 server/player.c:405
+#, c-format
+msgid "Viewer %d"
+msgstr "Toeskouer %d"
+
+#: client/common/player.c:126
+#, c-format
+msgid "viewer %d"
+msgstr "toeskouer %d"
+
+#: client/common/player.c:134 server/player.c:408
+#, c-format
+msgid "Player %d"
+msgstr "Speler %d"
+
+#: client/common/player.c:136
+#, c-format
+msgid "player %d"
+msgstr "speler %d"
+
+#: client/common/player.c:212
+#, c-format
+msgid "New viewer: %s.\n"
+msgstr "Nuwe toeskouer %s.\n"
+
+#: client/common/player.c:215 client/common/player.c:231
+#, c-format
+msgid "%s is now %s.\n"
+msgstr "%s is nou %s.\n"
+
+#: client/common/player.c:228
+#, c-format
+msgid "Player %d is now %s.\n"
+msgstr "Speler %d is nou %s.\n"
+
+#: client/common/player.c:267
+#, c-format
+msgid "%s has quit\n"
+msgstr "%s is weg\n"
+
+#: client/common/player.c:276
+msgid "There is no largest army.\n"
+msgstr "Daar is nie 'n grootste weermag nie.\n"
+
+#: client/common/player.c:279
+#, c-format
+msgid "%s has the largest army.\n"
+msgstr "%s het die grootste weermag.\n"
+
+#: client/common/player.c:300
+msgid "There is no longest road.\n"
+msgstr "Daar is nie 'n langste pad nie.\n"
+
+#: client/common/player.c:303
+#, c-format
+msgid "%s has the longest road.\n"
+msgstr "%s het die langste pad.\n"
+
+#: client/common/player.c:324
+#, c-format
+msgid "Waiting for %s."
+msgstr "Ek wag vir %s."
+
+#. We are not in on the action
+#. someone stole a resource from someone else
+#: client/common/player.c:352
+#, c-format
+msgid "%s stole a resource from %s.\n"
+msgstr "%s het 'n hulpbron gesteel by %s.\n"
+
+#: client/common/player.c:362
+#, c-format
+msgid "You stole %s from %s.\n"
+msgstr "Jy het %s gesteel by %s.\n"
+
+#: client/common/player.c:368
+#, c-format
+msgid "%s stole %s from you.\n"
+msgstr "%s het %s by jou gesteel.\n"
+
+#: client/common/player.c:402
+#, c-format
+msgid "%s gave %s nothing!?\n"
+msgstr "%s het vir %s niks gegee nie!?\n"
+
+#: client/common/player.c:408 client/common/player.c:416
+#, c-format
+msgid "%s gave %s %s for free.\n"
+msgstr "%s het vir %s %s verniet gegee.\n"
+
+#: client/common/player.c:424
+#, c-format
+msgid "%s gave %s %s in exchange for %s.\n"
+msgstr "%s het vir %s %s gegee in ruil vir %s.\n"
+
+#: client/common/player.c:455
+#, c-format
+msgid "%s exchanged %s for %s.\n"
+msgstr "%s het %s omgeruil vir %s.\n"
+
+#: client/common/player.c:475
+#, c-format
+msgid "%s built a road.\n"
+msgstr "%s het 'n pad gebou.\n"
+
+#: client/common/player.c:487
+#, c-format
+msgid "%s built a ship.\n"
+msgstr "%s het 'n skip gebou.\n"
+
+#: client/common/player.c:500
+#, c-format
+msgid "%s built a settlement.\n"
+msgstr "%s het 'n dorp gebou.\n"
+
+#: client/common/player.c:519
+#, c-format
+msgid "%s built a city.\n"
+msgstr "%s het 'n stad gebou.\n"
+
+#: client/common/player.c:533
+#, fuzzy, c-format
+msgid "%s built a city wall.\n"
+msgstr "%s het 'n stad gebou.\n"
+
+#: client/common/player.c:544
+#, c-format
+msgid "player_build_add called with BUILD_NONE for user %s\n"
+msgstr "player_build_add geroep met BUILD_NONE vir gebruiker %s\n"
+
+#: client/common/player.c:553
+#, c-format
+msgid "%s built a bridge.\n"
+msgstr "%s het 'n brug gebou.\n"
+
+#: client/common/player.c:579
+#, c-format
+msgid "%s removed a road.\n"
+msgstr "%s het 'n pad weggevat.\n"
+
+#: client/common/player.c:589
+#, c-format
+msgid "%s removed a ship.\n"
+msgstr "%s het 'n skip weggevat.\n"
+
+#: client/common/player.c:599
+#, c-format
+msgid "%s removed a settlement.\n"
+msgstr "%s het 'n dorp weggevat.\n"
+
+#: client/common/player.c:610
+#, c-format
+msgid "%s removed a city.\n"
+msgstr "%s het 'n stad weggevat.\n"
+
+#: client/common/player.c:624
+#, fuzzy, c-format
+msgid "%s removed a city wall.\n"
+msgstr "%s het 'n stad weggevat.\n"
+
+#: client/common/player.c:634
+#, c-format
+msgid "player_build_remove called with BUILD_NONE for user %s\n"
+msgstr "player_build_remove geroep met BUILD_NONE vir gebruiker %s\n"
+
+#: client/common/player.c:642
+#, c-format
+msgid "%s removed a bridge.\n"
+msgstr "%s het 'n brug weggevat.\n"
+
+#: client/common/player.c:673
+#, c-format
+msgid "%s has cancelled a ship's movement.\n"
+msgstr "%s het 'n skip se skuif gekanselleer.\n"
+
+#: client/common/player.c:676
+#, c-format
+msgid "%s moved a ship.\n"
+msgstr "%s het 'n skip geskuif.\n"
+
+#. tell the user that someone got something
+#: client/common/player.c:696
+#, c-format
+msgid "%s received %s.\n"
+msgstr "%s het %s ontvang.\n"
+
+#: client/common/player.c:714
+msgid "server asks to lose invalid point.\n"
+msgstr "bediener vra om ongeldige punt weg te vat.\n"
+
+#. tell the user the point is lost
+#: client/common/player.c:720
+#, c-format
+msgid "%s lost %s.\n"
+msgstr "%s het %s verloor.\n"
+
+#: client/common/player.c:743
+msgid "server asks to move invalid point.\n"
+msgstr "bediener vra om ongeldige punt te beweeg.\n"
+
+#. tell the user someone (1) lost something (2) to someone else (3)
+#: client/common/player.c:750
+#, c-format
+msgid "%s lost %s to %s.\n"
+msgstr "%s het %s verloor aan %s.\n"
+
+#: client/common/resource.c:35
+msgid "brick"
+msgstr "baksteen"
+
+#: client/common/resource.c:35
+msgid "Brick"
+msgstr "Baksteen"
+
+#: client/common/resource.c:36
+msgid "grain"
+msgstr "graan"
+
+#: client/common/resource.c:36
+msgid "Grain"
+msgstr "Graan"
+
+#: client/common/resource.c:37
+msgid "ore"
+msgstr "erts"
+
+#: client/common/resource.c:37
+msgid "Ore"
+msgstr "Erts"
+
+#: client/common/resource.c:38
+msgid "wool"
+msgstr "wol"
+
+#: client/common/resource.c:38
+msgid "Wool"
+msgstr "Wol"
+
+#: client/common/resource.c:39
+msgid "lumber"
+msgstr "hout"
+
+#: client/common/resource.c:39
+msgid "Lumber"
+msgstr "Hout"
+
+#: client/common/resource.c:40
+msgid "no resource (bug)"
+msgstr "geen hulpbron (fout)"
+
+#: client/common/resource.c:40
+msgid "No resource (bug)"
+msgstr "Geen hulpbron (fout)"
+
+#: client/common/resource.c:41
+msgid "any resource (bug)"
+msgstr "enige hulpbron (fout)"
+
+#: client/common/resource.c:41
+msgid "Any resource (bug)"
+msgstr "Enige hulpbron (fout)"
+
+#: client/common/resource.c:42
+msgid "gold"
+msgstr "goud"
+
+#: client/common/resource.c:42 client/gtk/legend.c:39
+msgid "Gold"
+msgstr "Goud"
+
+#: client/common/resource.c:47
+msgid "a brick card"
+msgstr "'n baksteenkaart"
+
+#: client/common/resource.c:47
+#, c-format
+msgid "%d brick cards"
+msgstr "%d baksteenkaarte"
+
+#: client/common/resource.c:48
+msgid "a grain card"
+msgstr "'n graankaart"
+
+#: client/common/resource.c:48
+#, c-format
+msgid "%d grain cards"
+msgstr "%d graankaarte"
+
+#: client/common/resource.c:49
+msgid "an ore card"
+msgstr "'n ertskaart"
+
+#: client/common/resource.c:49
+#, c-format
+msgid "%d ore cards"
+msgstr "%d ertskaarte"
+
+#: client/common/resource.c:50
+msgid "a wool card"
+msgstr "'n wolkaart"
+
+#: client/common/resource.c:50
+#, c-format
+msgid "%d wool cards"
+msgstr "%d wolkaarte"
+
+#: client/common/resource.c:51
+msgid "a lumber card"
+msgstr "'n houtkaart"
+
+#: client/common/resource.c:51
+#, c-format
+msgid "%d lumber cards"
+msgstr "%d houtkaarte"
+
+#: client/common/resource.c:139 client/common/resource.c:225
+msgid "nothing"
+msgstr "niks"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:166
+#, c-format
+msgid "%s and %s"
+msgstr "%s en %s"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:170
+#, c-format
+msgid "%s, %s"
+msgstr "%s, %s"
+
+#: client/common/robber.c:60
+#, fuzzy, c-format
+msgid "%s has undone the robber movement.\n"
+msgstr "%s moet die rower skuif."
+
+#: client/common/robber.c:63
+#, c-format
+msgid "%s moved the robber.\n"
+msgstr "%s het die rower geskuif.\n"
+
+#: client/common/robber.c:73
+#, fuzzy, c-format
+msgid "%s has undone the pirate movement.\n"
+msgstr "%s het 'n skip se skuif gekanselleer.\n"
+
+#: client/common/robber.c:76
+#, c-format
+msgid "%s moved the pirate.\n"
+msgstr "%s het die seerower geskuif.\n"
+
+#: client/common/robber.c:83
+#, c-format
+msgid "%s must move the robber."
+msgstr "%s moet die rower skuif."
+
+#: client/common/setup.c:140
+#, c-format
+msgid "Setup for %s.\n"
+msgstr "Opstelling vir %s.\n"
+
+#: client/common/setup.c:152
+#, c-format
+msgid "Double setup for %s.\n"
+msgstr "Dubbele opstelling vir %s.\n"
+
+#: client/common/turn.c:37
+#, c-format
+msgid "%s rolled %d.\n"
+msgstr "%s het %d gerol.\n"
+
+#: client/common/turn.c:50
+#, c-format
+msgid "Begin turn %d for %s.\n"
+msgstr "Beurt %d vir %s het nou begin.\n"
+
+#: client/gtk/chat.c:71
+msgid "<b>Chat</b>"
+msgstr "<b>Gesels</b>"
+
+#: client/gtk/chat.c:231
+msgid "Beeper test.\n"
+msgstr "Biepertoets.\n"
+
+#: client/gtk/chat.c:234
+#, c-format
+msgid "%s beeped you.\n"
+msgstr "%s het jou gebiep.\n"
+
+#: client/gtk/chat.c:238
+#, c-format
+msgid "You beeped %s.\n"
+msgstr "Jy het %s gebiep.\n"
+
+#: client/gtk/chat.c:244
+#, c-format
+msgid "You could not beep %s.\n"
+msgstr "Jy kon nie %s biep nie.\n"
+
+#: client/gtk/chat.c:288
+msgid " said: "
+msgstr " het gesê:"
+
+#: client/gtk/connect.c:282
+#, c-format
+msgid "Meta-server at %s, port %s"
+msgstr "Metabediener by %s, poort %s"
+
+#: client/gtk/connect.c:292
+msgid "Finished.\n"
+msgstr "Klaar.\n"
+
+#: client/gtk/connect.c:309 client/gtk/connect.c:359 client/gtk/connect.c:456
+#: server/meta.c:174
+msgid "Meta-server kicked us off\n"
+msgstr "Meta-bediener het ons afgeskop\n"
+
+#: client/gtk/connect.c:334
+msgid "Receiving game names from the meta server.\n"
+msgstr "Besig om name te kry vanaf metabediener.\n"
+
+#: client/gtk/connect.c:382
+#, c-format
+msgid "New game server requested on %s port %s\n"
+msgstr "Nuwe spelbediener aangevra op %s poort %s\n"
+
+#: client/gtk/connect.c:391 server/meta.c:168
+#, c-format
+msgid "Unknown message from the metaserver: %s\n"
+msgstr "Onbekende boodskap vanaf die metabediener: %s\n"
+
+#: client/gtk/connect.c:472 server/meta.c:125
+msgid "Too many meta-server redirects\n"
+msgstr "Te veel metabediener herleidings\n"
+
+#: client/gtk/connect.c:499 server/meta.c:140
+#, c-format
+msgid "Bad redirect line: %s\n"
+msgstr "Foutiewe verwysing: %s\n"
+
+#: client/gtk/connect.c:525
+#, c-format
+msgid "Meta server too old to create servers (version %d.%d)\n"
+msgstr "Metabediener te oud om nuwe bedieners te skep (weergawe %d.%d)\n"
+
+#. Sevens rule: normal
+#: client/gtk/connect.c:596 client/gtk/settingscreen.c:168
+#: common/gtk/game-rules.c:81
+msgid "Normal"
+msgstr "Normaal"
+
+#: client/gtk/connect.c:602 client/gtk/settingscreen.c:170
+#: common/gtk/game-rules.c:88
+msgid "Reroll on 1st 2 turns"
+msgstr "Rol weer op 1ste en 2e beurte"
+
+#: client/gtk/connect.c:605 client/gtk/settingscreen.c:172
+#: common/gtk/game-rules.c:95
+msgid "Reroll all 7s"
+msgstr "Rol weer alle 7s"
+
+#: client/gtk/connect.c:619
+msgid "Default"
+msgstr "Verstek"
+
+#: client/gtk/connect.c:622
+msgid "Random"
+msgstr "Ewekansig"
+
+#: client/gtk/connect.c:653 server/meta.c:188
+#, c-format
+msgid "Redirected to meta-server at %s, port %s\n"
+msgstr "Herlei na metabediener by %s, poort %s\n"
+
+#: client/gtk/connect.c:656
+msgid "Receiving a list of Pioneers servers from the meta server.\n"
+msgstr "Ontvang tans 'n lys van Pioniersbedieners vanaf die meta-bediener.\n"
+
+#: client/gtk/connect.c:713
+msgid ""
+"<b>Note</b>:\n"
+"\tThe metaserver does not send information about the games.\n"
+"\tPlease set appropriate values yourself."
+msgstr ""
+"<b>Nota</b>:\n"
+"\tDie Metabediener stuur geen inligting oor die spel nie.\n"
+"\tStel asb. self geskikte waardes op."
+
+#: client/gtk/connect.c:730
+msgid "Number of AI Players"
+msgstr "Aantal robotspelers"
+
+#: client/gtk/connect.c:749
+msgid "The number of AI players"
+msgstr "Die aantal robotspeler"
+
+#: client/gtk/connect.c:770
+msgid "Requesting new game server\n"
+msgstr "Nuwe spelbediener word aangevra\n"
+
+#: client/gtk/connect.c:813 server/gtk/main.c:328 server/server.c:160
+#, c-format
+msgid "Error starting %s: %s"
+msgstr "Fout met begin van diens %s: %s"
+
+#: client/gtk/connect.c:834
+msgid "Create a public game"
+msgstr "Skep 'n openbare spel"
+
+#: client/gtk/connect.c:965 client/gtk/connect.c:1268
+msgid "Join a public game"
+msgstr "Betree 'n openbare spel"
+
+#: client/gtk/connect.c:970
+msgid "_New remote game"
+msgstr "_Nuwe afgeleë spel"
+
+#: client/gtk/connect.c:984
+msgid "Refresh the list of games"
+msgstr "Verfris die lys van spelle"
+
+#: client/gtk/connect.c:989
+msgid "Create a new public game at the meta server"
+msgstr "Skep 'n nuwe openbare spel by die metabediener"
+
+#: client/gtk/connect.c:994
+msgid "Don't join a public game"
+msgstr "Moenie 'n openbare spel betree nie"
+
+#: client/gtk/connect.c:998
+msgid "Join the selected game"
+msgstr "Betree die gekose spel"
+
+#: client/gtk/connect.c:1033
+msgid "Select a game to join"
+msgstr "Kies 'n spel om te betree"
+
+#: client/gtk/connect.c:1036
+msgid "Map Name"
+msgstr "Kaartnaam"
+
+#: client/gtk/connect.c:1044
+msgid "Name of the game"
+msgstr "Naam van die spel"
+
+#: client/gtk/connect.c:1049
+msgid "Curr"
+msgstr "Tans"
+
+#: client/gtk/connect.c:1055
+msgid "Number of players in the game"
+msgstr "Aantal spelers in die spel"
+
+#: client/gtk/connect.c:1060
+msgid "Max"
+msgstr "Maks"
+
+#: client/gtk/connect.c:1066
+msgid "Maximum players for the game"
+msgstr "Maksimum spelers vir die spel"
+
+#: client/gtk/connect.c:1069
+msgid "Terrain"
+msgstr "Terrein"
+
+#: client/gtk/connect.c:1076
+msgid "Random of default terrain"
+msgstr "Geskommelde verstekterrein"
+
+#: client/gtk/connect.c:1081
+msgid "Vic. Points"
+msgstr "Wenpunte"
+
+#: client/gtk/connect.c:1087
+msgid "Points needed to win"
+msgstr "Punte nodig om te wen"
+
+#: client/gtk/connect.c:1090 common/gtk/game-rules.c:73
+msgid "Sevens Rule"
+msgstr "Sewes-reël"
+
+#: client/gtk/connect.c:1096
+msgid "Sevens rule"
+msgstr "Sewes-reël"
+
+#: client/gtk/connect.c:1100
+msgid "Host"
+msgstr "Gasheer"
+
+#: client/gtk/connect.c:1108
+msgid "Host of the game"
+msgstr "Gasheer van die spel"
+
+#: client/gtk/connect.c:1113
+msgid "Port"
+msgstr "Poort"
+
+#: client/gtk/connect.c:1119
+msgid "Port of the the game"
+msgstr "Poort van die spel"
+
+#: client/gtk/connect.c:1122 common/gtk/aboutbox.c:77
+msgid "Version"
+msgstr "Weergawe"
+
+#: client/gtk/connect.c:1129
+msgid "Version of the host"
+msgstr "Weergawe van die gasheer"
+
+#: client/gtk/connect.c:1184 client/gtk/gui.c:215
+msgid "Start a new game"
+msgstr "Begin 'n nuwe spel"
+
+#: client/gtk/connect.c:1209
+msgid "Player Name"
+msgstr "Spelernaam"
+
+#: client/gtk/connect.c:1223
+msgid "Enter your name"
+msgstr "Tik jou naam"
+
+#. Role of the player: viewer
+#: client/gtk/connect.c:1225 server/gtk/main.c:511
+msgid "Viewer"
+msgstr "Toeskouer"
+
+#: client/gtk/connect.c:1233
+msgid "Do you want to be a viewer?"
+msgstr "Wil jy 'n toeskouer wees?"
+
+#: client/gtk/connect.c:1240 server/gtk/main.c:640
+msgid "Meta Server"
+msgstr "Meta-bediener"
+
+#: client/gtk/connect.c:1255
+msgid "Leave empty for the default meta server"
+msgstr "Los oop vir die verstek metabediener"
+
+#: client/gtk/connect.c:1263
+msgid "Join public game"
+msgstr "Betree openbare spel"
+
+#: client/gtk/connect.c:1272
+msgid "Create game"
+msgstr "Skep spel"
+
+#: client/gtk/connect.c:1275
+msgid "Create a game"
+msgstr "Skep 'n spel"
+
+#: client/gtk/connect.c:1285
+msgid "Join private game"
+msgstr "Betree privaatspel"
+
+#: client/gtk/connect.c:1289 client/gtk/connect.c:1434
+msgid "Join a private game"
+msgstr "Betree 'n private spel"
+
+#: client/gtk/connect.c:1475
+msgid "Name of the host of the game"
+msgstr "Naam van die gasheer van die spel"
+
+#: client/gtk/connect.c:1494
+msgid "Port of the host of the game"
+msgstr "Poort van die gasheer van die spel"
+
+#: client/gtk/connect.c:1534
+msgid "Recent games"
+msgstr "Onlangse spelle"
+
+#: client/gtk/connect.c:1536
+msgid "Recent Games"
+msgstr "Onlangse Spelle"
+
+#: client/gtk/develop.c:129
+msgid "<b>Development Cards</b>"
+msgstr "<b>Ontwikkelingskaarte</b>"
+
+#: client/gtk/develop.c:160
+msgid "Play Card"
+msgstr "Speel kaart"
+
+#: client/gtk/discard.c:76
+msgid "Discard resources"
+msgstr "Gooi hulpbronne weg"
+
+#: client/gtk/discard.c:96
+#, c-format
+msgid "You must discard %d resources"
+msgstr "Jy moet %d hulpbronne weggooi"
+
+#: client/gtk/discard.c:101
+msgid "Total discards"
+msgstr "Totaal weggegooi"
+
+#. Caption for list of player that must discard cards
+#: client/gtk/discard.c:226
+msgid "<b>Waiting for players to discard</b>"
+msgstr "<b>Wag tans dat spelers hulpbronne opgee</b>"
+
+#: client/gtk/gameover.c:32
+msgid "Game over"
+msgstr "Spel verby"
+
+#: client/gtk/gameover.c:49
+#, c-format
+msgid "%s has won the game with %d victory points!"
+msgstr "%s het die spel gewen met %d oorwinningspunte!"
+
+#: client/gtk/gameover.c:52
+#, c-format
+msgid "%s has won the game with %d victory points!\n"
+msgstr "%s het die spel gewen met %d oorwinningspunte!\n"
+
+#: client/gtk/gameover.c:58
+#, c-format
+msgid "All praise %s, Lord of the known world!"
+msgstr "Geluk aan %s, heerser van hierdie wêreld!"
+
+#: client/gtk/gold.c:71
+msgid "Choose resources"
+msgstr "Kies hulpbronne"
+
+#: client/gtk/gold.c:92
+#, c-format
+msgid "You may choose 1 resource"
+msgstr "Jy mag een hulpbron kies"
+
+#: client/gtk/gold.c:94
+#, c-format
+msgid "You may choose %d resources"
+msgstr "Jy mag %d hulpbronne kies"
+
+#. Text for total in choose gold dialog
+#. Text for total in year of plenty dialog
+#: client/gtk/gold.c:101 client/gtk/plenty.c:98
+msgid "Total resources"
+msgstr "Hulpbrontotaal"
+
+#: client/gtk/gold.c:213
+msgid "<b>Waiting for players to choose</b>"
+msgstr "<b>Wag tans vir spelers om te kies</b>"
+
+#: client/gtk/gui.c:213 server/gtk/main.c:98
+msgid "_Game"
+msgstr "_Spel"
+
+#: client/gtk/gui.c:214
+msgid "_New game"
+msgstr "_Nuwe Spel"
+
+#: client/gtk/gui.c:216
+msgid "_Leave game"
+msgstr "Ver_laat spel"
+
+#: client/gtk/gui.c:217
+msgid "Leave this game"
+msgstr "Verlaat hierdie spel"
+
+#: client/gtk/gui.c:219
+msgid "_Admin"
+msgstr "_Admin"
+
+#: client/gtk/gui.c:220
+msgid "Administer Pioneers server"
+msgstr "Administreer Pioniers-bediener"
+
+#: client/gtk/gui.c:222
+msgid "_Player name"
+msgstr "S_pelernaam"
+
+#: client/gtk/gui.c:223
+msgid "Change your player name"
+msgstr "Verander jou spelernaam"
+
+#: client/gtk/gui.c:224
+msgid "_Legend"
+msgstr "_Uiteensetting"
+
+#: client/gtk/gui.c:225
+msgid "Terrain legend and building costs"
+msgstr "Terreinuiteensetting en boukostes"
+
+#: client/gtk/gui.c:226
+msgid "_Game Settings"
+msgstr "_Spel-instellings"
+
+#: client/gtk/gui.c:227
+msgid "Settings for the current game"
+msgstr "Instellings vir die huidige spel"
+
+#: client/gtk/gui.c:228
+msgid "_Dice Histogram"
+msgstr "_Histogram van kansgetalle"
+
+#: client/gtk/gui.c:229
+msgid "Histogram of dice rolls"
+msgstr "Histogram van kansgetalle"
+
+#: client/gtk/gui.c:230 editor/gtk/editor.c:1018 server/gtk/main.c:103
+msgid "_Quit"
+msgstr "_Verlaat"
+
+#: client/gtk/gui.c:231 server/gtk/main.c:104
+msgid "Quit the program"
+msgstr "Verlaat die program"
+
+#: client/gtk/gui.c:232
+msgid "_Actions"
+msgstr "_Aksies"
+
+#: client/gtk/gui.c:233
+msgid "Roll Dice"
+msgstr "Gooi"
+
+#: client/gtk/gui.c:234
+msgid "Roll the dice"
+msgstr "Gooi kanssteentjies"
+
+#. Tab page name
+#: client/gtk/gui.c:235 client/gtk/gui.c:577
+msgid "Trade"
+msgstr "Ruilhandel"
+
+#: client/gtk/gui.c:237
+msgid "Undo"
+msgstr "Herroep "
+
+#: client/gtk/gui.c:238 client/gtk/gui.c:239
+msgid "Finish"
+msgstr "Klaar"
+
+#: client/gtk/gui.c:240 client/gtk/legend.c:226 editor/gtk/game-buildings.c:13
+msgid "Road"
+msgstr "Pad"
+
+#: client/gtk/gui.c:241
+msgid "Build a road"
+msgstr "Bou 'n pad"
+
+#: client/gtk/gui.c:242 client/gtk/legend.c:230 editor/gtk/game-buildings.c:13
+msgid "Ship"
+msgstr "Skip"
+
+#: client/gtk/gui.c:243
+msgid "Build a ship"
+msgstr "Bou 'n skip"
+
+#: client/gtk/gui.c:244
+msgid "Move Ship"
+msgstr "Skuif 'n skip"
+
+#: client/gtk/gui.c:245
+msgid "Move a ship"
+msgstr "Bou 'n skip"
+
+#: client/gtk/gui.c:246 client/gtk/legend.c:233 editor/gtk/game-buildings.c:13
+msgid "Bridge"
+msgstr "Brug"
+
+#: client/gtk/gui.c:247
+msgid "Build a bridge"
+msgstr "Bou 'n brug"
+
+#: client/gtk/gui.c:248 client/gtk/legend.c:235 client/gtk/player.c:52
+#: editor/gtk/game-buildings.c:13
+msgid "Settlement"
+msgstr "Dorp"
+
+#: client/gtk/gui.c:249
+msgid "Build a settlement"
+msgstr "Bou 'n dorp"
+
+#: client/gtk/gui.c:250 client/gtk/legend.c:236 client/gtk/player.c:53
+#: editor/gtk/game-buildings.c:14
+msgid "City"
+msgstr "Stad"
+
+#: client/gtk/gui.c:251
+msgid "Build a city"
+msgstr "Bou 'n stad"
+
+#: client/gtk/gui.c:252
+msgid "Develop"
+msgstr "Ontwikkel"
+
+#: client/gtk/gui.c:253
+msgid "Buy a development card"
+msgstr "Koop 'n ontwikkelingskaart"
+
+#: client/gtk/gui.c:254 client/gtk/legend.c:240 client/gtk/player.c:54
+#: editor/gtk/game-buildings.c:14
+#, fuzzy
+msgid "City Wall"
+msgstr "Stad"
+
+#: client/gtk/gui.c:255
+#, fuzzy
+msgid "Build a city wall"
+msgstr "Bou 'n stad"
+
+#: client/gtk/gui.c:257
+msgid "_Settings"
+msgstr "Op_stellings"
+
+#: client/gtk/gui.c:258
+msgid "Prefere_nces"
+msgstr "Voor_keure"
+
+#: client/gtk/gui.c:259
+msgid "Configure the application"
+msgstr "Konfigureer die toepassing"
+
+#: client/gtk/gui.c:261 client/gtk/gui.c:265 editor/gtk/editor.c:1002
+#: server/gtk/main.c:99
+msgid "_Help"
+msgstr "_Hulp"
+
+#: client/gtk/gui.c:262
+msgid "_About Pioneers"
+msgstr "Aangaande Pioniers"
+
+#: client/gtk/gui.c:263
+msgid "Information about Pioneers"
+msgstr "Inligting oor Pioniers"
+
+#: client/gtk/gui.c:266 client/gtk/gui.c:1065
+msgid "Show the manual"
+msgstr "Wys die handleiding"
+
+#: client/gtk/gui.c:272
+msgid "_Toolbar"
+msgstr "_Nutsbalk"
+
+#: client/gtk/gui.c:273
+msgid "Show or hide the toolbar"
+msgstr "Wys of verberg die nutsbalk"
+
+#. Victory points target in statusbar
+#: client/gtk/gui.c:368
+#, c-format
+msgid "Points Needed to Win: %i"
+msgstr "Punte nodig om te wen: %i"
+
+#: client/gtk/gui.c:454
+msgid "<b>Messages</b>"
+msgstr "<b>Boodskappe</b>"
+
+#. Tab page name
+#: client/gtk/gui.c:571 editor/gtk/editor.c:1165
+msgid "Map"
+msgstr "Landkaart"
+
+#. Tab page name
+#: client/gtk/gui.c:585 client/gtk/quote.c:306
+msgid "Quote"
+msgstr "Kwotasie"
+
+#. Tab page name
+#: client/gtk/gui.c:593 client/gtk/legend.c:261
+msgid "Legend"
+msgstr "Uiteensetting"
+
+#. Tab page name, shown for the splash screen
+#: client/gtk/gui.c:603
+msgid "Welcome to Pioneers"
+msgstr "Welkom by Pioniers"
+
+#: client/gtk/gui.c:868
+msgid "Pioneers Preferences"
+msgstr "Pioniers voorkeure"
+
+#. Label for changing the theme, in the preferences dialog
+#: client/gtk/gui.c:898
+msgid "Theme:"
+msgstr "Tema:"
+
+#: client/gtk/gui.c:921
+msgid "Choose one of the themes"
+msgstr "Kies een van die temas"
+
+#. Label for the option to show the legend
+#: client/gtk/gui.c:925
+msgid "Show legend"
+msgstr "Wys uiteensetting"
+
+#. Tooltip for the option to show the legend
+#: client/gtk/gui.c:935
+msgid "Show the legend as a page beside the map"
+msgstr "Wys die uiteensetting as 'n bladsy langs die landkaart"
+
+#. Label for the option to display log messages in color
+#: client/gtk/gui.c:940
+msgid "Messages with color"
+msgstr "Boodskappe in kleur"
+
+#: client/gtk/gui.c:950
+msgid "Show new messages with color"
+msgstr "Wys nuwe boodskappe in kleur"
+
+#: client/gtk/gui.c:955
+msgid "Chat in color of player"
+msgstr "Gesels in die kleur van die speler"
+
+#: client/gtk/gui.c:966
+msgid "Show new chat messages in the color of the player"
+msgstr "Wys nuwe boodskappe in die kleur van die speler"
+
+#. Label for the option to display the summary with colors
+#: client/gtk/gui.c:971
+msgid "Summary with color"
+msgstr "Opsomming met kleure"
+
+#: client/gtk/gui.c:982
+msgid "Use colors in the player summary"
+msgstr "Gebruikl kleure in die speleropsomming"
+
+#: client/gtk/gui.c:987
+msgid "Toolbar with shortcuts"
+msgstr "Nutsbalk met kortpaaie"
+
+#: client/gtk/gui.c:997
+msgid "Show keyboard shortcuts in the toolbar"
+msgstr "Wys sleutelbordkortpaaie in die nutsbalk"
+
+#: client/gtk/gui.c:1003
+msgid "Announce new players"
+msgstr "Kondig nuwe spelers aan"
+
+#: client/gtk/gui.c:1014
+msgid "Make a sound when a new player or viewer enters the game"
+msgstr "Maak 'n geluid wanner 'n nuwe speler of toeskouer die spel betree"
+
+#. Label for the option to use the 16:9 layout.
+#: client/gtk/gui.c:1019
+msgid "Use 16:9 layout"
+msgstr ""
+
+#: client/gtk/gui.c:1030
+msgid "Use a 16:9 friendly layout for the window"
+msgstr ""
+
+#: client/gtk/gui.c:1041
+msgid "The Pioneers Game"
+msgstr "Die Pioniers-spel"
+
+#. Initial text in status bar
+#: client/gtk/gui.c:1352
+msgid "Welcome to Pioneers!"
+msgstr "Welkom by Pioniers!"
+
+#. The name of the application
+#: client/gtk/gui.c:1463
+msgid "Pioneers"
+msgstr "Pioniers"
+
+#: client/gtk/histogram.c:252
+msgid "Dice Histogram"
+msgstr "Kansgetalhistogram"
+
+#: client/gtk/interface.c:92
+msgid "Ship movement canceled."
+msgstr "Skip-skuif gekanselleer."
+
+#: client/gtk/interface.c:100 client/gtk/interface.c:101
+msgid "Select a new location for the ship."
+msgstr "Kies 'n nuwe plek vir die skip."
+
+#: client/gtk/interface.c:740
+msgid "Select the ship to steal from"
+msgstr "Kies die skip om van te steel"
+
+#: client/gtk/interface.c:750
+msgid "Select the building to steal from"
+msgstr "Kies die gebou om van te steel"
+
+#: client/gtk/legend.c:32
+msgid "Hill"
+msgstr "Heuwel"
+
+#: client/gtk/legend.c:33
+msgid "Field"
+msgstr "Veld"
+
+#: client/gtk/legend.c:34
+msgid "Mountain"
+msgstr "Berg"
+
+#: client/gtk/legend.c:35
+msgid "Pasture"
+msgstr "Weiveld"
+
+#: client/gtk/legend.c:36
+msgid "Forest"
+msgstr "Woud"
+
+#: client/gtk/legend.c:37
+msgid "Desert"
+msgstr "Woestyn"
+
+#: client/gtk/legend.c:38
+msgid "Sea"
+msgstr "See"
+
+#: client/gtk/legend.c:170
+msgid "<b>Terrain Yield</b>"
+msgstr "<b>Terrein-opbrengs</b>"
+
+#: client/gtk/legend.c:202
+msgid "<b>Building Costs</b>"
+msgstr "<b>Boukoste</b>"
+
+#: client/gtk/legend.c:243
+msgid "Development Card"
+msgstr "Ontwikkelingskaart"
+
+#: client/gtk/monopoly.c:105
+msgid "Select the resource you wish to monopolise."
+msgstr "Kies die hulpbron wat jy wil monopoliseer."
+
+#: client/gtk/name.c:123
+msgid "Change player name"
+msgstr "Verander spelernaam"
+
+#: client/gtk/name.c:146
+msgid "Player Name:"
+msgstr "Spelernaam:"
+
+#. Set icon preferences
+#: client/gtk/name.c:202
+msgid "Face:"
+msgstr ""
+
+#: client/gtk/name.c:217
+msgid "Variant:"
+msgstr ""
+
+#. Commandline option of client: name of the player
+#: client/gtk/offline.c:59
+msgid "Player name"
+msgstr "Spelernaam"
+
+#: client/gtk/offline.c:63
+msgid "Connect as a viewer"
+msgstr "Skakel in as 'n toeskouer"
+
+#: client/gtk/offline.c:66
+msgid "Meta-server Host"
+msgstr "Metabediener gasheer"
+
+#: client/gtk/offline.c:70
+msgid "Override the language of the system"
+msgstr "Oorheers die taal van die stelsel"
+
+#: client/gtk/offline.c:100
+msgid "Connecting"
+msgstr "Besig om te koppel"
+
+#. Long description in the commandline for pioneers: help
+#: client/gtk/offline.c:175
+msgid "- Play a game of Pioneers"
+msgstr "- Speel 'n Pioniers-spel"
+
+#: client/gtk/player.c:52
+msgid "Settlements"
+msgstr "Dorpe"
+
+#: client/gtk/player.c:53
+msgid "Cities"
+msgstr "Stede"
+
+#: client/gtk/player.c:54
+msgid "City Walls"
+msgstr ""
+
+#: client/gtk/player.c:55
+msgid "Largest Army"
+msgstr "Grootste weermag"
+
+#: client/gtk/player.c:56
+msgid "Longest Road"
+msgstr "Langste pad"
+
+#: client/gtk/player.c:57
+msgid "Chapels"
+msgstr "Kapelle"
+
+#: client/gtk/player.c:58
+msgid "Pioneer Universities"
+msgstr "Pionier Universiteite"
+
+#: client/gtk/player.c:60
+msgid "Governor's Houses"
+msgstr "Ampswonings"
+
+#: client/gtk/player.c:61
+msgid "Libraries"
+msgstr "Biblioteke"
+
+#: client/gtk/player.c:62
+msgid "Markets"
+msgstr "Markte"
+
+#: client/gtk/player.c:63
+msgid "Soldiers"
+msgstr "Soldate"
+
+#: client/gtk/player.c:64
+msgid "Resource card"
+msgstr "Hulpbronkaart"
+
+#: client/gtk/player.c:64
+msgid "Resource cards"
+msgstr "Hulpbronkaarte"
+
+#: client/gtk/player.c:65
+msgid "Development card"
+msgstr "Ontwikkelingskaart"
+
+#: client/gtk/player.c:65
+msgid "Development cards"
+msgstr "Ontwikkelingskaarte"
+
+#. Caption for the overview of the points and card of other players
+#: client/gtk/player.c:561
+msgid "<b>Player Summary</b>"
+msgstr "<b>Speler-opsomming</b>"
+
+#: client/gtk/plenty.c:87
+msgid "Please choose one resource from the bank"
+msgstr "Kies asb. een hulpbron van die bank"
+
+#: client/gtk/plenty.c:90
+msgid "Please choose two resources from the bank"
+msgstr "Kies asb. twee hulpbronne van die bank"
+
+#: client/gtk/plenty.c:92
+msgid "The bank is empty"
+msgstr "Die bank is leeg"
+
+#: client/gtk/quote.c:186
+#, c-format
+msgid "%s has %s, and is looking for %s"
+msgstr "%s het %s, en wil graag %s hê"
+
+#: client/gtk/quote.c:287
+msgid "I Want"
+msgstr "Ek wil hê"
+
+#: client/gtk/quote.c:295
+msgid "Give Them"
+msgstr "Ek gee"
+
+#: client/gtk/quote.c:311
+msgid "Delete"
+msgstr "Vee uit"
+
+#: client/gtk/quote.c:335
+msgid "Reject Domestic Trade"
+msgstr "Verwerp plaaslike handel"
+
+#. Now create columns
+#. Table header: Player who trades
+#. Role of the player: player
+#: client/gtk/quote-view.c:170 server/gtk/main.c:513
+msgid "Player"
+msgstr "Speler"
+
+#. Table header: Quote
+#: client/gtk/quote-view.c:185
+msgid "Quotes"
+msgstr "Kwotasies"
+
+#. trade: maritime quote: %1 resources of type %2 for
+#. * one resource of type %3
+#: client/gtk/quote-view.c:292
+#, c-format
+msgid "%d:1 %s for %s"
+msgstr "%d:1 %s vir %s"
+
+#. Trade: a player has rejected trade
+#: client/gtk/quote-view.c:431
+msgid "Rejected trade"
+msgstr "Handel verwerp"
+
+#. Caption for overview of the resources of the player
+#: client/gtk/resource.c:113
+msgid "<b>Resources</b>"
+msgstr "<b>Hulpbronne</b>"
+
+#: client/gtk/resource.c:129
+msgid "Total"
+msgstr "Totaal"
+
+#. Tooltip for the amount of resources in the hand
+#: client/gtk/resource-table.c:187
+msgid "Amount in hand"
+msgstr "Aantal beskikbaar"
+
+#: client/gtk/resource-table.c:191
+msgid "<less"
+msgstr "<minder"
+
+#. Tooltip for decreasing the selected amount
+#: client/gtk/resource-table.c:201
+msgid "Decrease the selected amount"
+msgstr "Verminder die aantal"
+
+#. Tooltip for the amount of resources in the bank
+#: client/gtk/resource-table.c:215
+msgid "Amount in the bank"
+msgstr "Aantal in die bank"
+
+#: client/gtk/resource-table.c:219
+msgid "more>"
+msgstr "meer>"
+
+#. Tooltip for increasing the selected amount
+#: client/gtk/resource-table.c:231
+msgid "Increase the selected amount"
+msgstr "Vermeerder die hoeveelheid"
+
+#. Tooltip for the selected amount
+#: client/gtk/resource-table.c:248
+msgid "Selected amount"
+msgstr "Gekose hoeveelheid"
+
+#. Tooltip for the total selected amount
+#: client/gtk/resource-table.c:293
+msgid "Total selected amount"
+msgstr "Die huidig geselekteerde lêernaam"
+
+#: client/gtk/resource-table.c:314
+msgid "The bank cannot be emptied"
+msgstr "Die kleur kan nie geïnstalleer word nie."
+
+#: client/gtk/settingscreen.c:74
+msgid "Yes"
+msgstr "Ja"
+
+#: client/gtk/settingscreen.c:76 client/gtk/settingscreen.c:207
+msgid "No"
+msgstr "Nee"
+
+#: client/gtk/settingscreen.c:87 client/gtk/settingscreen.c:174
+msgid "Unknown"
+msgstr "Onbekend"
+
+#: client/gtk/settingscreen.c:121
+msgid "No game in progress..."
+msgstr "Geen spel is tans besig nie..."
+
+#: client/gtk/settingscreen.c:131
+msgid "<b>General Settings</b>"
+msgstr "<b>Algemene instellings</b>"
+
+#: client/gtk/settingscreen.c:147
+msgid "Number of players:"
+msgstr "Aantal spelers:"
+
+#: client/gtk/settingscreen.c:150
+msgid "Victory Point Target:"
+msgstr "Wenpunteteiken:"
+
+#: client/gtk/settingscreen.c:153
+msgid "Random Terrain?"
+msgstr "Geskommelde verstekterrein?"
+
+#: client/gtk/settingscreen.c:156
+msgid "Interplayer Trading Allowed?"
+msgstr "Word tussenspeler ruilhandel toegelaat?"
+
+#: client/gtk/settingscreen.c:160
+msgid "Trading allowed only before build/buy?"
+msgstr "Word ruilhandel slegs toegelaat voor bou/koop?"
+
+#: client/gtk/settingscreen.c:163
+msgid "Amount of Each Resource:"
+msgstr "Aantal van elke hulpbron:"
+
+#: client/gtk/settingscreen.c:177
+msgid "Sevens Rule:"
+msgstr "Sewes-reël:"
+
+#: client/gtk/settingscreen.c:181
+msgid "Use Pirate:"
+msgstr "Gebruik seerower:"
+
+#: client/gtk/settingscreen.c:209
+msgid "Island Discovery Bonuses:"
+msgstr "Eiland-ontdekbonusse:"
+
+#: client/gtk/settingscreen.c:224
+msgid "<b>Building Quotas</b>"
+msgstr "<b>Boukwotas</b>"
+
+#: client/gtk/settingscreen.c:241
+msgid "Roads:"
+msgstr "Paaie:"
+
+#: client/gtk/settingscreen.c:247
+msgid "Settlements:"
+msgstr "Dorpe:"
+
+#: client/gtk/settingscreen.c:253
+msgid "Cities:"
+msgstr "Stede:"
+
+#: client/gtk/settingscreen.c:259
+msgid "City Walls:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:265
+msgid "Ships:"
+msgstr "Skepe:"
+
+#: client/gtk/settingscreen.c:271
+msgid "Bridges:"
+msgstr "Br"
+
+#: client/gtk/settingscreen.c:283
+msgid "<b>Development Card Deck</b>"
+msgstr "<b>Stapel van ontwikkelingskaarte</b>"
+
+#: client/gtk/settingscreen.c:299
+msgid "Road Building Cards:"
+msgstr "Padboukaarte:"
+
+#: client/gtk/settingscreen.c:303
+msgid "Monopoly Cards:"
+msgstr "Monopoliekaarte"
+
+#: client/gtk/settingscreen.c:307
+msgid "Year of Plenty Cards:"
+msgstr "Oorvloedjaarkaarte:"
+
+#: client/gtk/settingscreen.c:312
+msgid "Chapel Cards:"
+msgstr "Kapelkaarte:"
+
+#: client/gtk/settingscreen.c:316
+msgid "Pioneer University Cards:"
+msgstr "Pionier Universiteitkaarte:"
+
+#: client/gtk/settingscreen.c:320
+msgid "Governor's House Cards:"
+msgstr "Ampswoningkaarte:"
+
+#: client/gtk/settingscreen.c:325
+msgid "Library Cards:"
+msgstr "Biblioteekkaarte:"
+
+#: client/gtk/settingscreen.c:329
+msgid "Market Cards:"
+msgstr "Markkaarte:"
+
+#: client/gtk/settingscreen.c:333
+msgid "Soldier Cards:"
+msgstr "Soldaatkaarte:"
+
+#: client/gtk/settingscreen.c:370
+msgid "Current Game Settings"
+msgstr "Huidige spelinstellings"
+
+#. trade: you ask for something for free
+#: client/gtk/trade.c:193
+#, c-format
+msgid "ask for %s for free"
+msgstr "vra vir gratis %s"
+
+#. trade: you give something away for free
+#: client/gtk/trade.c:198
+#, c-format
+msgid "give %s for free"
+msgstr "gee %s gratis"
+
+#. trade: you trade something for something else
+#: client/gtk/trade.c:203
+#, c-format
+msgid "give %s for %s"
+msgstr "gee %s vir %s"
+
+#. I want some resources, and give them some resources
+#: client/gtk/trade.c:230
+#, c-format
+msgid "I want %s, and give them %s"
+msgstr "Ek wil %s hê en sal %s gee"
+
+#. Frame title, trade: I want to trade these resources
+#: client/gtk/trade.c:427
+msgid "<b>I Want</b>"
+msgstr "<b>Ek wil hê</b>"
+
+#. Frame title, trade: I want these resources in return
+#: client/gtk/trade.c:455
+msgid "<b>Give Them</b>"
+msgstr "<b>Ek gee</b>"
+
+#. Button text, trade: call for quotes from other players
+#: client/gtk/trade.c:484
+msgid "_Call for Quotes"
+msgstr "_Vra vir kwotasies"
+
+#. Button text: Trade page, accept selected quote
+#: client/gtk/trade.c:512
+msgid "_Accept Quote"
+msgstr "Aanvaar kwotasie"
+
+#. Button text: Trade page, finish trading
+#: client/gtk/trade.c:518
+msgid "_Finish Trading"
+msgstr "Stop met ruilhandel"
+
+#: common/gtk/aboutbox.c:74
+msgid ""
+"Pioneers is based upon the excellent\n"
+"Settlers of Catan board game.\n"
+msgstr ""
+"Pioniers is gebaseer op die uitstekende\n"
+"bordspel \"Settlers of Catan\".\n"
+
+#: common/gtk/aboutbox.c:83
+msgid "Homepage"
+msgstr "Tuisblad"
+
+#: common/gtk/aboutbox.c:88
+msgid "Authors"
+msgstr "Outeurs"
+
+#. Tooltip for sevens rule normal
+#: common/gtk/game-rules.c:101
+msgid "All sevens move the robber or pirate"
+msgstr "Alle sewes skuif die rower of seerower"
+
+#: common/gtk/game-rules.c:106
+msgid "In the first two turns all sevens are rerolled"
+msgstr "In die eerste twee beurte word alle sewes vervang"
+
+#. Tooltip for sevens rule reroll all
+#: common/gtk/game-rules.c:110
+msgid "All sevens are rerolled"
+msgstr "Alle sewes word vervang"
+
+#: common/gtk/game-rules.c:121
+#, fuzzy
+msgid "Randomize Terrain"
+msgstr "Geskommelde verstekterrein?"
+
+#: common/gtk/game-rules.c:121
+#, fuzzy
+msgid "Randomize the terrain"
+msgstr "Geskommelde verstekterrein?"
+
+#: common/gtk/game-rules.c:123
+msgid "Use Pirate"
+msgstr "Gebruik seerower"
+
+#: common/gtk/game-rules.c:123
+msgid "Use the pirate to block ships"
+msgstr ""
+
+#: common/gtk/game-rules.c:125
+msgid "Strict Trade"
+msgstr "Streng handel"
+
+#: common/gtk/game-rules.c:126
+#, fuzzy
+msgid "Allow trade only before building or buying"
+msgstr "Word ruilhandel slegs toegelaat voor bou/koop?"
+
+#: common/gtk/game-rules.c:128
+msgid "Domestic Trade"
+msgstr "Plaaslike handel"
+
+#: common/gtk/game-rules.c:128
+msgid "Allow trade between players"
+msgstr ""
+
+#. Label text for customising a game
+#: common/gtk/game-settings.c:118
+msgid "Number of Players"
+msgstr "Aantal spelers"
+
+#. Tooltip for 'Number of Players'
+#: common/gtk/game-settings.c:136
+msgid "The number of players"
+msgstr "Die hoeveelheid spelers"
+
+#. Label for customising a game
+#: common/gtk/game-settings.c:139
+msgid "Victory Point Target"
+msgstr "Wenpuntteiken"
+
+#. Tooltip for Victory Point Target
+#: common/gtk/game-settings.c:159
+msgid "The points needed to win the game"
+msgstr "Die punte wat nodig is om die spel te wen"
+
+#. Tooltip for the check button
+#: common/gtk/game-settings.c:172
+#, fuzzy
+msgid "Is it possible to win this game?"
+msgstr "Die punte wat nodig is om die spel te wen"
+
+#. Port indicator for a resource: trade 2 for 1
+#: common/gtk/guimap.c:750
+msgid "2:1"
+msgstr "2:1"
+
+#. Port indicator: trade 3 for 1
+#. General port indicator
+#: common/gtk/guimap.c:753 common/gtk/guimap.c:778
+msgid "3:1"
+msgstr "3:1"
+
+#. Tooltip for the list of games
+#: common/gtk/select-game.c:111
+msgid "Select a game"
+msgstr "Kies 'n spel"
+
+#: common/gtk/theme.c:709
+#, c-format
+msgid "bad scaling mode '%s'"
+msgstr "foutiewe skaalmodus '%s'"
+
+#: common/game.c:603 common/game.c:633
+#, fuzzy
+msgid "This game cannot be won."
+msgstr "Hierdie spel gaan binnekort begin."
+
+#: common/game.c:604
+#, fuzzy
+msgid "There is no land."
+msgstr "Daar is nie 'n langste pad nie.\n"
+
+#: common/game.c:638
+msgid "It is possible that this game cannot be won."
+msgstr ""
+
+#: common/game.c:643
+msgid "This game can be won by only building all settlements and cities."
+msgstr ""
+
+#: common/game.c:650
+#, c-format
+msgid ""
+"Required victory points: %d\n"
+"Points obtained by building all: %d\n"
+"Points in development cards: %d\n"
+"Longest road/largest army: %d+%d\n"
+"Maximum island discovery bonus: %d\n"
+"Total: %d"
+msgstr ""
+
+#: common/log.c:54
+msgid "*ERROR* "
+msgstr "*Fout* "
+
+#: common/log.c:60
+msgid "Chat: "
+msgstr "Gesels: "
+
+#: common/log.c:63
+msgid "Resource: "
+msgstr "Hulpbron: "
+
+#: common/log.c:66
+msgid "Build: "
+msgstr "Bou: "
+
+#: common/log.c:69
+msgid "Dice: "
+msgstr "Kansstene: "
+
+#: common/log.c:72
+msgid "Steal: "
+msgstr "Steel: "
+
+#: common/log.c:75
+msgid "Trade: "
+msgstr "Ruil: "
+
+#: common/log.c:78
+msgid "Development: "
+msgstr "Ontwikkeling: "
+
+#: common/log.c:81
+msgid "Army: "
+msgstr "Weermag: "
+
+#: common/log.c:84
+msgid "Road: "
+msgstr "Pad: "
+
+#: common/log.c:87
+msgid "*BEEP* "
+msgstr "*BIEP* "
+
+#: common/log.c:92
+msgid "Player 1: "
+msgstr "Speler 1: "
+
+#: common/log.c:95
+msgid "Player 2: "
+msgstr "Speler 2: "
+
+#: common/log.c:98
+msgid "Player 3: "
+msgstr "Speler 3: "
+
+#: common/log.c:101
+msgid "Player 4: "
+msgstr "Speler 4: "
+
+#: common/log.c:104
+msgid "Player 5: "
+msgstr "Speler 5: "
+
+#: common/log.c:107
+msgid "Player 6: "
+msgstr "Speler 6: "
+
+#: common/log.c:110
+msgid "Player 7: "
+msgstr "Speler 7: "
+
+#: common/log.c:113
+msgid "Player 8: "
+msgstr "Speler 8: "
+
+#: common/log.c:116
+msgid "Viewer: "
+msgstr "Toeskouer: "
+
+#: common/log.c:119
+msgid "** UNKNOWN MESSAGE TYPE ** "
+msgstr "** Onbekende boodskaptipe ** "
+
+#: common/network.c:281
+#, c-format
+msgid "Error checking connect status: %s\n"
+msgstr "Fout met nagaan van konneksiestatus: %s\n"
+
+#: common/network.c:288
+#, c-format
+msgid "Error connecting to host '%s': %s\n"
+msgstr "Fout met koppeling na gasheer '%s': %s\n"
+
+#: common/network.c:314
+#, c-format
+msgid "Error writing socket: %s\n"
+msgstr "Fout tydens sokskrywing: %s\n"
+
+#: common/network.c:365
+#, c-format
+msgid "Error writing to socket: %s\n"
+msgstr "Fout met skryf na sok: %s\n"
+
+#: common/network.c:418
+msgid "Read buffer overflow - disconnecting\n"
+msgstr "Leesbuffer het oorgeloop - ontkoppel tans\n"
+
+#: common/network.c:428
+#, c-format
+msgid "Error reading socket: %s\n"
+msgstr "Fout tydens lees van sok: %s\n"
+
+#: common/network.c:575
+#, c-format
+msgid "Cannot resolve %s port %s: %s\n"
+msgstr "Kan nie %s poort %s uitvind nie: %s\n"
+
+#: common/network.c:582
+#, c-format
+msgid "Cannot resolve %s port %s: host not found\n"
+msgstr "Kan nie %s se poort %s bepaal nie: gasheer nie gevind\n"
+
+#: common/network.c:597
+#, c-format
+msgid "Error creating socket: %s\n"
+msgstr "Fout met skep van sok: %s\n"
+
+#: common/network.c:605
+#, c-format
+msgid "Error setting socket close-on-exec: %s\n"
+msgstr "Fout met stel van sok na \"close-on-exec\": %s\n"
+
+#: common/network.c:615 common/network.c:776
+#, c-format
+msgid "Error setting socket non-blocking: %s\n"
+msgstr "Fout met stel van sok na \"non-blocking\": %s\n"
+
+#: common/network.c:640
+#, c-format
+msgid "Error connecting to %s: %s\n"
+msgstr "Kon nie aan %s koppel nie: %s\n"
+
+#: common/network.c:735
+#, c-format
+msgid "Error creating struct addrinfo: %s"
+msgstr "Fout tydens skep van \"addrinfo\": %s"
+
+#: common/network.c:765
+#, c-format
+msgid "Error creating listening socket: %s\n"
+msgstr "Fout tydens skep van luister-sok: %s\n"
+
+#: common/network.c:785
+#, c-format
+msgid "Error during listen on socket: %s\n"
+msgstr "Fout tydens luister op sok: %s\n"
+
+#: common/network.c:794
+msgid "Listening not yet supported on this platform."
+msgstr "Luister word nog nie ondersteun op hierdie platform nie."
+
+#: common/network.c:816 common/network.c:817
+msgid "unknown"
+msgstr "onbekend"
+
+#: common/network.c:823
+#, c-format
+msgid "Error getting peer name: %s"
+msgstr "Kon naam nie opspoor nie: %s"
+
+#: common/network.c:836
+#, c-format
+msgid "Error resolving address: %s"
+msgstr "Kon nie masjienadres opspoor nie: %s"
+
+#: common/network.c:850
+msgid "Net_get_peer_name not yet supported on this platform."
+msgstr "\"Net_get_peer_name\" word nog nie op hierdie platform ondersteun nie."
+
+#: common/network.c:865
+#, c-format
+msgid "Error accepting connection: %s"
+msgstr "Kon nie die konneksie aanvaar nie: %s"
+
+#: common/state.c:166
+#, c-format
+msgid "Connecting to %s, port %s\n"
+msgstr "Konnekteer aan %s, poort %s\n"
+
+#: common/state.c:503
+msgid "State stack overflow. Stack dump sent to standard error.\n"
+msgstr "Statusstapel loop oor. Stapel word gestort op standaardfoutafvoer.\n"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:73
+msgid "_Hill"
+msgstr "_Heuwel"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:75
+msgid "_Field"
+msgstr "_Veld"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:77
+msgid "_Mountain"
+msgstr "_Berg"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:79
+msgid "_Pasture"
+msgstr "_Weiveld"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:81
+msgid "F_orest"
+msgstr "W_oud"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:83
+msgid "_Desert"
+msgstr "Woest_yn"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:85
+msgid "_Sea"
+msgstr "_See"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:87
+msgid "_Gold"
+msgstr "_Goud"
+
+#. Use an unique shortcut key for each resource
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:89 editor/gtk/editor.c:104
+msgid "_None"
+msgstr "_Niks"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:94
+msgid "_Brick (2:1)"
+msgstr "_Baksteen (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:96
+msgid "_Grain (2:1)"
+msgstr "_Graan (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:98
+msgid "_Ore (2:1)"
+msgstr "_Erts (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:100
+msgid "_Wool (2:1)"
+msgstr "_Wol (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:102
+msgid "_Lumber (2:1)"
+msgstr "_Hout (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:106
+msgid "_Any (3:1)"
+msgstr "_Alles (3:1)"
+
+#. East
+#: editor/gtk/editor.c:111
+msgid "East|E"
+msgstr "O"
+
+#. North east
+#: editor/gtk/editor.c:113
+msgid "North East|NE"
+msgstr "NO"
+
+#. North west
+#: editor/gtk/editor.c:115
+msgid "North West|NW"
+msgstr "NW"
+
+#. West
+#: editor/gtk/editor.c:117
+msgid "West|W"
+msgstr "W"
+
+#. South west
+#: editor/gtk/editor.c:119
+msgid "South West|SW"
+msgstr "SW"
+
+#. South east
+#: editor/gtk/editor.c:121
+msgid "South East|SE"
+msgstr "SO"
+
+#: editor/gtk/editor.c:564
+msgid "Shuffle"
+msgstr "Skommel"
+
+#: editor/gtk/editor.c:696 server/gtk/main.c:450
+msgid "Game Parameters"
+msgstr "Spelparameters"
+
+#: editor/gtk/editor.c:698 server/gtk/main.c:482
+msgid "Rules"
+msgstr "Reëls"
+
+#: editor/gtk/editor.c:699
+msgid "Resources"
+msgstr "Hulpbronne"
+
+#: editor/gtk/editor.c:700
+msgid "Buildings"
+msgstr "Geboue"
+
+#: editor/gtk/editor.c:701
+msgid "Development Cards"
+msgstr "Ontwikkelingskaarte"
+
+#: editor/gtk/editor.c:718
+msgid "Pioneers Editor"
+msgstr "Pioniers-redigeerder"
+
+#: editor/gtk/editor.c:803
+#, c-format
+msgid "Failed to load '%s'"
+msgstr "Kon nie '%s' laai nie"
+
+#: editor/gtk/editor.c:843
+#, c-format
+msgid "Failed to save to '%s'"
+msgstr "Kon nie '%s' stoor nie"
+
+#: editor/gtk/editor.c:858
+msgid "Open Game"
+msgstr "Maak spel oop"
+
+#: editor/gtk/editor.c:884
+msgid "Save as..."
+msgstr "Stoor as..."
+
+#: editor/gtk/editor.c:919
+msgid "Change Title"
+msgstr "Verander titel"
+
+#: editor/gtk/editor.c:941
+msgid "New Title:"
+msgstr "Nuwe titel:"
+
+#: editor/gtk/editor.c:997
+msgid "Pioneers Game Editor"
+msgstr "Pioniersspelredigeerder"
+
+#: editor/gtk/editor.c:1001
+msgid "_File"
+msgstr "_Lêer"
+
+#: editor/gtk/editor.c:1004
+msgid "_New"
+msgstr "_Nuwe"
+
+#: editor/gtk/editor.c:1005
+msgid "Create a new game"
+msgstr "Skep nuwe spel"
+
+#: editor/gtk/editor.c:1006
+msgid "_Open..."
+msgstr "_Open..."
+
+#: editor/gtk/editor.c:1007
+msgid "Open an existing game"
+msgstr "Maak 'n bestaande spel oop"
+
+#: editor/gtk/editor.c:1008
+msgid "_Save"
+msgstr "_Stoor"
+
+#: editor/gtk/editor.c:1009
+msgid "Save game"
+msgstr "Stoor spel"
+
+#: editor/gtk/editor.c:1010
+msgid "Save _As..."
+msgstr "Stoor _As..."
+
+#: editor/gtk/editor.c:1012
+msgid "Save as"
+msgstr "Stoor as"
+
+#: editor/gtk/editor.c:1013
+msgid "_Change title"
+msgstr "_Verander titel"
+
+#: editor/gtk/editor.c:1014
+msgid "Change game title"
+msgstr "Verander die spel se titel"
+
+#: editor/gtk/editor.c:1015 server/gtk/main.c:100
+#, fuzzy
+msgid "_Check Victory Point Target"
+msgstr "Wenpuntteiken"
+
+#: editor/gtk/editor.c:1017 server/gtk/main.c:102
+msgid "Check whether the game can be won"
+msgstr ""
+
+#: editor/gtk/editor.c:1019
+msgid "Quit"
+msgstr "Verlaat"
+
+#: editor/gtk/editor.c:1027
+msgid "_About Pioneers Editor"
+msgstr "_Aangaande die Pioniersredigeerder"
+
+#: editor/gtk/editor.c:1028
+msgid "Information about Pioneers Editor"
+msgstr "Inligting oor Pioniersredigeerder"
+
+#. Long help for commandline option (editor): filename
+#: editor/gtk/editor.c:1066
+msgid "Open this file"
+msgstr "Maak hierdie lêer oop"
+
+#. Commandline option for editor: filename
+#: editor/gtk/editor.c:1068
+msgid "filename"
+msgstr "Lêernaam"
+
+#: editor/gtk/editor.c:1100
+msgid "- Editor for games of Pioneers"
+msgstr "- Redigeerder vir Pioniersspelle"
+
+#: editor/gtk/editor.c:1141 server/gtk/main.c:1035
+#, c-format
+msgid "Building menus failed: %s"
+msgstr "Bou van kieslyste het misluk: %s"
+
+#: editor/gtk/editor.c:1169
+msgid "Settings"
+msgstr "Instellings"
+
+#: editor/gtk/game-resources.c:51
+msgid "Resource Count"
+msgstr "Aantal hulpbronne"
+
+#. Commandline meta-server: daemon
+#: meta-server/main.c:1033
+msgid "Daemonize the metaserver on start"
+msgstr "Loop die metabediener in die agtergrond wanneer dit begin"
+
+#. Commandline meta-server: redirect
+#: meta-server/main.c:1036
+msgid "Redirect clients to another metaserver"
+msgstr "Herlei kliënte na 'n ander metabediener"
+
+#. Commandline meta-server: server
+#: meta-server/main.c:1039
+msgid "Use this hostname when creating new games"
+msgstr "Gebruik hierdie masjiennaam wanneer nuwe spelle geskep word"
+
+#. Commandline meta-server: server argument
+#: meta-server/main.c:1041
+msgid "hostname"
+msgstr "masjiennaam"
+
+#. Commandline meta-server: port-range
+#: meta-server/main.c:1044
+msgid "Use this ports range when creating new games"
+msgstr "Gebruik hierdie poortreeks wanneer nuwe spelle geskep word"
+
+#. Commandline meta-server: port-range argument
+#: meta-server/main.c:1046
+msgid "from-to"
+msgstr "vanaf-na"
+
+#. Commandline option of meta server: syslog-debug
+#: meta-server/main.c:1052
+msgid "Debug syslog messages"
+msgstr "Ontfout syslog-boodskappe"
+
+#. Long description in the commandline for server-console: help
+#: meta-server/main.c:1073
+msgid "- Meta server for Pioneers"
+msgstr "- Metabediener vir Pioniers"
+
+#: meta-server/main.c:1088
+#, c-format
+msgid "metaserver protocol:"
+msgstr "metabediener protokol:"
+
+#: server/gtk/main.c:105
+msgid "_About Pioneers Server"
+msgstr "_Aangaande Pioniersbediener"
+
+#: server/gtk/main.c:106
+msgid "Information about Pioneers Server"
+msgstr "Inligting oor Pioniersbediener"
+
+#: server/gtk/main.c:222
+msgid "Stop server"
+msgstr "Stop bediener"
+
+#: server/gtk/main.c:223
+msgid "Start server"
+msgstr "Begin bediener"
+
+#: server/gtk/main.c:225
+msgid "Stop the server"
+msgstr "Stop die bediener"
+
+#: server/gtk/main.c:226
+msgid "Start the server"
+msgstr "Begin die bediener"
+
+#: server/gtk/main.c:351
+#, c-format
+msgid "Player %s from %s entered\n"
+msgstr "Speler %s van %s tree in\n"
+
+#: server/gtk/main.c:358
+#, c-format
+msgid "Player %s from %s left\n"
+msgstr "Speler %s van %s tree uit\n"
+
+#: server/gtk/main.c:365
+#, c-format
+msgid "Player %d is now %s\n"
+msgstr "Speler %d is nou %s\n"
+
+#: server/gtk/main.c:554
+msgid "Game Settings"
+msgstr "Spelinstellings"
+
+#: server/gtk/main.c:600
+msgid "Server Parameters"
+msgstr "Bedienerparameters"
+
+#: server/gtk/main.c:626
+msgid "The port for the game server"
+msgstr "Die poort vir die spelbediener"
+
+#: server/gtk/main.c:629
+msgid "Register Server"
+msgstr "Registreer bediener"
+
+#: server/gtk/main.c:637
+msgid "Register this game at the meta server"
+msgstr "Registreer hierdie spel by die metabediener"
+
+#: server/gtk/main.c:654
+msgid "The address of the meta server"
+msgstr "Die adres van die metabediener"
+
+#: server/gtk/main.c:656
+msgid "Reported Hostname"
+msgstr "Masjiennaam soos verskaf"
+
+#: server/gtk/main.c:671
+msgid ""
+"The public name of this computer (needed when playing behind a firewall)"
+msgstr ""
+"Publieke naam van hierdie rekenaar (nodig wanneer van agter 'n netskans "
+"\"firewall\" gespeel word)"
+
+#: server/gtk/main.c:675
+msgid "Random Turn Order"
+msgstr "Ewekansige beurtvolgorde"
+
+#: server/gtk/main.c:683
+msgid "Randomize turn order"
+msgstr "Maak beurtvolgorde deurmekaar"
+
+#: server/gtk/main.c:722
+msgid "Running Game"
+msgstr "Spel word tans geloop"
+
+#: server/gtk/main.c:724
+msgid "Players Connected"
+msgstr "Spelers het toegetree"
+
+#: server/gtk/main.c:758
+msgid "Shows all players and viewers connected to the server"
+msgstr "Wys alle spelers en toeskouers wat aan die bediener gekoppel is"
+
+#: server/gtk/main.c:763
+msgid "Connected"
+msgstr "Gekonnekteer"
+
+#: server/gtk/main.c:770
+msgid "Is the player currently connected?"
+msgstr "Is die speler tans gekonnekteer?"
+
+#: server/gtk/main.c:773
+msgid "Name"
+msgstr "Naam"
+
+#: server/gtk/main.c:780
+msgid "Name of the player"
+msgstr "Spelernaam"
+
+#: server/gtk/main.c:782
+msgid "Location"
+msgstr "Plek"
+
+#: server/gtk/main.c:789
+msgid "Host name of the player"
+msgstr "Masjiennaam van die speler"
+
+#: server/gtk/main.c:793
+msgid "Number"
+msgstr "Nommer"
+
+#: server/gtk/main.c:800
+msgid "Player number"
+msgstr "Spelernommer"
+
+#: server/gtk/main.c:804
+msgid "Role"
+msgstr "Rol"
+
+#: server/gtk/main.c:808
+msgid "Player of viewer"
+msgstr "Speler van toeskouer"
+
+#: server/gtk/main.c:819
+#, fuzzy
+msgid "Launch Pioneers Client"
+msgstr "Die Pioniers-spel"
+
+#: server/gtk/main.c:826
+#, fuzzy
+msgid "Launch the Pioneers Client"
+msgstr "Die Pioniers-spel"
+
+#: server/gtk/main.c:828
+msgid "Computer Players"
+msgstr "Robotspelers"
+
+#: server/gtk/main.c:837
+msgid "Enable Chat"
+msgstr "Skakel gesels aan"
+
+#: server/gtk/main.c:843
+msgid "Enable chat messages"
+msgstr "Skakel geselsboodskappe aan"
+
+#: server/gtk/main.c:850
+msgid "Add Computer Player"
+msgstr "Voeg robotspeler by"
+
+#: server/gtk/main.c:857
+msgid "Add a computer player to the game"
+msgstr "Voeg 'n robotspeler by die spel"
+
+#: server/gtk/main.c:866
+msgid "Messages"
+msgstr "Boodskappe"
+
+#: server/gtk/main.c:884
+msgid "Messages from the server"
+msgstr "Boodskappe vanaf die bediener"
+
+#: server/gtk/main.c:932
+msgid "The Pioneers Game Server"
+msgstr "Die Pioniers-spelbediener"
+
+#. Wait for all players to disconnect,
+#. * then enable the UI
+#.
+#: server/gtk/main.c:940
+msgid "The game is over.\n"
+msgstr "Die spel is verby.\n"
+
+#. Long description in the commandline for server-gtk: help
+#. Long description in the commandline for server-console: help
+#: server/gtk/main.c:994 server/main.c:174
+msgid "- Host a game of Pioneers"
+msgstr "- Skep 'n Pioniersspel"
+
+#. Name in the titlebar of the server
+#: server/gtk/main.c:1016
+msgid "Pioneers Server"
+msgstr "Pioniersbediener"
+
+#. Commandline server-console: game-title
+#: server/main.c:75
+msgid "Game title to use"
+msgstr "Speltitel om te gebruik"
+
+#. Commandline server-console: file
+#: server/main.c:78
+msgid "Game file to use"
+msgstr "Spellêer om te gebruik"
+
+#. Commandline server-console: port
+#: server/main.c:81
+msgid "Port to listen on"
+msgstr "Poort om na te luister"
+
+#. Commandline server-console: players
+#: server/main.c:84
+msgid "Override number of players"
+msgstr "Beheer aantal spelers"
+
+#. Commandline server-console: points
+#: server/main.c:87
+msgid "Override number of points needed to win"
+msgstr "Verander die aantal punte wat nodig is om die spel te wen"
+
+#. Commandline server-console: seven-rule
+#: server/main.c:90
+msgid "Override seven-rule handling"
+msgstr "Verander die sewes-reëlhantering"
+
+#. Commandline server-console: terrain
+#: server/main.c:93
+msgid "Override terrain type, 0=default 1=random"
+msgstr "Verander die terreintipe, 0=verstek, 1=ewekansig"
+
+#. Commandline server-console: computer-players
+#: server/main.c:96
+msgid "Add N computer players"
+msgstr "Voeg N robotspelers by"
+
+#. Commandline server-console: register
+#: server/main.c:106
+msgid "Register server with meta-server"
+msgstr "Registreer bediener by metabediener"
+
+#. Commandline server-console: meta-server
+#: server/main.c:109
+msgid "Register at meta-server name (implies -r)"
+msgstr "Registreer by die metabediener (impliseer -r)"
+
+#. Commandline server-console: hostname
+#: server/main.c:113
+msgid "Use this hostname when registering"
+msgstr "Gebruik hierdie masjiennaam vir registrasie"
+
+#. Commandline server-console: auto-quit
+#: server/main.c:120
+msgid "Quit after a player has won"
+msgstr "Verlaat die spel wanneer 'n speler gewen het"
+
+#. Commandline server-console: empty-timeout
+#: server/main.c:123
+msgid "Quit after N seconds with no players"
+msgstr "Verlaat die spel na N sekondes sonder spelers"
+
+#. Commandline server-console: tournament
+#: server/main.c:126
+msgid "Tournament mode, computer players added after N minutes"
+msgstr "Toernooi-modus, rekenaars bygevoeg na N minute"
+
+#. Commandline server-console: admin-port
+#: server/main.c:130
+msgid "Admin port to listen on"
+msgstr "Adminpoort om op te luister"
+
+#: server/main.c:134
+msgid "Don't start game immediately, wait for a command on admin port"
+msgstr "Moenie die spel dadelik begin nie, wag vir 'n opdrag op die adminpoort"
+
+#: server/main.c:140
+msgid "Give players numbers according to the order they enter the game"
+msgstr "Gee nommers aan spelers soos wat hulle die spel betree"
+
+#. Commandline server-console: Short description of meta group
+#: server/main.c:180
+msgid "Meta-server Options"
+msgstr "Opsies vir die metabediener"
+
+#: server/main.c:183
+msgid "Options for the meta-server"
+msgstr "Opsies vir die metabediener"
+
+#. Commandline server-console: Short description of misc group
+#: server/main.c:191
+msgid "Miscellaneous Options"
+msgstr "Verskeie opsies"
+
+#. Commandline server-console: Long description of misc group
+#: server/main.c:193
+msgid "Miscellaneous options"
+msgstr "Verskeie opsies"
+
+#: server/meta.c:193
+#, c-format
+msgid "Register with meta-server at %s, port %s\n"
+msgstr "Registreer by metabediener %s, poort %s\n"
+
+#: server/meta.c:210
+msgid "Unregister from meta-server\n"
+msgstr "Verbreek koppeling met meta-bediener\n"
+
+#: server/player.c:130
+msgid "chat too long"
+msgstr "geselslyn te lank"
+
+#: server/player.c:147
+msgid "name too long"
+msgstr "naam te lank"
+
+#: server/player.c:179
+msgid "ignoring unknown extension"
+msgstr "onbekende uitbreiding word geïgnoreer"
+
+#: server/player.c:209
+msgid "Game starts, adding computer players"
+msgstr "Die spel begin, robotspelers word bygevoeg"
+
+#: server/player.c:234
+#, c-format
+msgid "The game starts in %s minutes."
+msgstr "Die spel begin oor %s minute."
+
+#: server/player.c:235
+#, c-format
+msgid "The game starts in %s minute."
+msgstr "Die spel begin oor %s minuut."
+
+#: server/player.c:280
+msgid "Sorry, game is over."
+msgstr "Jammer, die spel is verby."
+
+#: server/player.c:283
+#, c-format
+msgid "Player from %s is refused: game is over\n"
+msgstr "Speler vanaf %s word weggewys: spel is verby\n"
+
+#: server/player.c:331
+msgid "This game will start soon."
+msgstr "Hierdie spel gaan binnekort begin."
+
+#: server/player.c:359
+msgid "Name not changed: new name is already in use"
+msgstr "Naam is nie verander nie: nuwe naam word reeds gebruik"
+
+#. %s is the name of the reconnecting player
+#: server/player.c:648
+#, c-format
+msgid "%s has reconnected."
+msgstr "%s het weer gekonnekteer."
+
+#: server/player.c:776
+#, c-format
+msgid "Version mismatch: %s"
+msgstr "Weergawes pas nie: %s"
+
+#: server/server.c:47
+msgid "Was hanging around for too long without players... bye.\n"
+msgstr ""
+
+#. Server: preparing game #.....
+#: server/server.c:219
+msgid "Preparing game"
+msgstr "Spel word voorberei"
+
+#: server/server.c:337
+msgid "Missing game directory\n"
+msgstr "Spelgids ontbreek\n"
+
+#: server/turn.c:253
+msgid "Island Discovery Bonus"
+msgstr "Bonus vir eilandontdekking"
+
+#: server/turn.c:256
+msgid "Additional Island Bonus"
+msgstr "Addisionele eilandbonus"
+
+#: server/turn.c:388
+msgid "Tried to assign resources to NULL player.\n"
+msgstr "Het probeer om hulpbronne toe te ken aan die NULL-speler.\n"
+
+#~ msgid "Brick port|B"
+#~ msgstr "Baksteenhawe"
+
+#~ msgid "Grain port|G"
+#~ msgstr "Graanhawe"
+
+#~ msgid "Ore port|O"
+#~ msgstr "Ertshawe"
+
+#~ msgid "Wool port|W"
+#~ msgstr "Wolhawe"
+
+#~ msgid "Lumber port|L"
+#~ msgstr "Houthawe"
+
+#~ msgid "Continue with your turn."
+#~ msgstr "Gaan voort met jou beurt."
+
+#~ msgid "Map Terrain"
+#~ msgstr "Landkaartterrein"
+
+#~ msgid "Default map or a random map"
+#~ msgstr "Verstekkaart of ewekansige kaart"
Added: trunk/po/de.po
===================================================================
--- trunk/po/de.po (rev 0)
+++ trunk/po/de.po 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,3153 @@
+# Pioneers - Settlers of Catan for GNOME.
+# Copyright (C) 1999-2001 Dave Cole
+# Copyright (C) 2000-2002 Andy Heroff
+# This file is distributed under the same license as the pioneers package.
+# Roman Hodek <roman at hodek.net>, 2002.
+# Pit Garbe <piiit at gmx.de>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Pioneers 0.11.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-07 20:43+0200\n"
+"PO-Revision-Date: 2007-07-22 16:35+0000\n"
+"Last-Translator: Pit Garbe <piiit at gmx.de>\n"
+"Language-Team: Pit Garbe <piiit at gmx.de>, Roman Hodek <roman at hodek.net>, de "
+"<de at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Default name for the AI when the computer_names file
+#. * is not found or empty.
+#.
+#: client/ai/ai.c:74 client/ai/ai.c:90
+msgid "Computer Player"
+msgstr "Computerspieler"
+
+#. Commandline pioneersai: server
+#. Commandline option of client: hostname of the server
+#: client/ai/ai.c:102 client/gtk/connect.c:1462 client/gtk/offline.c:53
+msgid "Server Host"
+msgstr "Serverrechner"
+
+#. Commandline pioneersai: port
+#. Commandline option of client: port of the server
+#: client/ai/ai.c:105 client/gtk/connect.c:1478 client/gtk/offline.c:56
+#: server/gtk/main.c:612
+msgid "Server Port"
+msgstr "Serverport"
+
+#. Commandline pioneersai: name
+#: client/ai/ai.c:108
+msgid "Computer name (leave absent for random name)"
+msgstr "Computername (frei lassen für zufälligen Namen)"
+
+#. Commandline pioneersai: time
+#: client/ai/ai.c:111
+msgid "Time to wait between turns (in milliseconds)"
+msgstr "Zeit zwischen den Zügen (in Millisekunden)"
+
+#. Commandline pioneersai: chat-free
+#: client/ai/ai.c:114
+msgid "Stop computer player from talking"
+msgstr "Computerspielern das Chatten verbieten"
+
+#. Commandline pioneersai: algorithm
+#: client/ai/ai.c:117
+msgid "Type of computer player"
+msgstr "Computerspieler-Typ"
+
+#. Commandline option of ai: enable debug logging
+#. Commandline option of client: enable debug logging
+#. Commandline option of meta server: enable debug logging
+#. Commandline option of server-gtk: enable debug logging
+#. Commandline option of server: enable debug logging
+#: client/ai/ai.c:120 client/gtk/offline.c:74 meta-server/main.c:1049
+#: server/gtk/main.c:952 server/main.c:144
+msgid "Enable debug messages"
+msgstr "Debug-Nachrichten einschalten"
+
+#. Commandline option of ai: version
+#. Commandline option of client: version
+#. Commandline option of editor: version
+#. Commandline option of meta server: version
+#. Commandline option of server-gtk: version
+#. Commandline option of server-console: version
+#: client/ai/ai.c:123 client/gtk/offline.c:77 editor/gtk/editor.c:1071
+#: meta-server/main.c:1055 server/gtk/main.c:955 server/main.c:99
+msgid "Show version information"
+msgstr "Versionsnummer anzeigen"
+
+#: client/ai/ai.c:134
+msgid "- Computer player for Pioneers"
+msgstr "- Computerspieler für Pioneers"
+
+#: client/ai/ai.c:144 client/gtk/offline.c:186 editor/gtk/editor.c:1111
+#: meta-server/main.c:1084 server/gtk/main.c:1005 server/main.c:206
+#, c-format
+msgid "Pioneers version:"
+msgstr "Pioneers Version:"
+
+#: client/ai/ai.c:176
+#, c-format
+msgid "Type of computer player: %s\n"
+msgstr "Computerspieler-Typ: %s\n"
+
+#: client/ai/ai.c:205
+msgid "The game is already full. I'm leaving."
+msgstr "Das Spiel ist schon voll, ich gehe."
+
+#: client/ai/greedy.c:941
+msgid "No settlements in stock to use for setup"
+msgstr "Keine Siedlungen mehr übrig"
+
+#: client/ai/greedy.c:948
+msgid "There is no place to setup a settlement"
+msgstr "Es gibt keinen Platz für eine Siedlung"
+
+#: client/ai/greedy.c:972
+msgid "No roads in stock to use for setup"
+msgstr "Keine Straßen mehr übrig"
+
+#: client/ai/greedy.c:989
+msgid "There is no place to setup a road"
+msgstr "Es gibt keinen Platz für eine Straße"
+
+#: client/ai/greedy.c:1291
+msgid "Ok, let's go!"
+msgstr "Auf geht's!"
+
+#: client/ai/greedy.c:1292
+msgid "I'll beat you all now! ;)"
+msgstr "Ich werd euch jetzt alle abhängen! ;)"
+
+#: client/ai/greedy.c:1293
+msgid "Now for another try..."
+msgstr "Ok, noch ein Versuch..."
+
+#: client/ai/greedy.c:1297
+msgid "At least I get something..."
+msgstr "Wenigstens bekomme ich irgendwas..."
+
+#: client/ai/greedy.c:1298
+msgid "One is better than none..."
+msgstr "Eine ist besser als keine..."
+
+#: client/ai/greedy.c:1302
+msgid "Wow!"
+msgstr "Toll!"
+
+#: client/ai/greedy.c:1303
+msgid "Ey, I'm becoming rich ;)"
+msgstr "Hey, ich werde reich! ;)"
+
+#: client/ai/greedy.c:1304
+msgid "This is really a good year!"
+msgstr "Das ist wirklich ein gutes Jahr!"
+
+#: client/ai/greedy.c:1307
+msgid "You really don't deserve that much!"
+msgstr "Du verdienst wirklich nicht so viel!"
+
+#: client/ai/greedy.c:1308
+msgid "You don't know what to do with that many resources ;)"
+msgstr "Du weißt eh nicht, was du mit sovielen Karten anfangen sollst ;)"
+
+#: client/ai/greedy.c:1309
+msgid "Ey, wait for my robber and lose all this again!"
+msgstr "He, warte auf meinen Räuber, dann ist das alles wieder weg!"
+
+#: client/ai/greedy.c:1312
+msgid "Hehe!"
+msgstr "Hehe!"
+
+#: client/ai/greedy.c:1313
+msgid "Go, robber, go!"
+msgstr "Los, Räuber, los!"
+
+#: client/ai/greedy.c:1316
+msgid "You bastard!"
+msgstr "Schweinehund!"
+
+#: client/ai/greedy.c:1317
+msgid "Can't you move that robber somewhere else?!"
+msgstr "Kannst du den Räuber nicht woanders hinstellen?!"
+
+#: client/ai/greedy.c:1318
+msgid "Why always me??"
+msgstr "Warum immer ich??"
+
+#: client/ai/greedy.c:1321
+msgid "Oh no!"
+msgstr "Oh nein!"
+
+#: client/ai/greedy.c:1322
+msgid "Grrr!"
+msgstr "Grrr!"
+
+#: client/ai/greedy.c:1323
+msgid "Who the hell rolled that 7??"
+msgstr "Wer zum Teufel hat die 7 gewürfelt??"
+
+#: client/ai/greedy.c:1324
+msgid "Why always me?!?"
+msgstr "Warum immer ich?!?"
+
+#: client/ai/greedy.c:1327
+msgid "Say good bye to your cards... :)"
+msgstr "Sag Tschüss zu deinen Karten... :)"
+
+#: client/ai/greedy.c:1328
+msgid "*evilgrin*"
+msgstr "*bösegrins*"
+
+#: client/ai/greedy.c:1329
+msgid "/me says farewell to your cards ;)"
+msgstr "/me sagt Lebwohl zu deinen Karten ;)"
+
+#: client/ai/greedy.c:1330
+msgid "That's the price for being rich... :)"
+msgstr "Das ist der Preis für's Reichsein... :)"
+
+#: client/ai/greedy.c:1333
+msgid "Ey! Where's that card gone?"
+msgstr "He! Wo ist die Karte hin?"
+
+#: client/ai/greedy.c:1334
+msgid "Thieves! Thieves!!"
+msgstr "Diebe! Diebe!!"
+
+#: client/ai/greedy.c:1335
+msgid "Wait for my revenge..."
+msgstr "Warte auf meine Rache..."
+
+#: client/ai/greedy.c:1338
+msgid "Oh no :("
+msgstr "Oh nein :("
+
+#: client/ai/greedy.c:1339
+msgid "Must this happen NOW??"
+msgstr "Muß das ausgerechnet jetzt passieren??"
+
+#: client/ai/greedy.c:1340
+msgid "Args"
+msgstr "Args"
+
+#: client/ai/greedy.c:1343
+msgid "Hehe, my soldiers rule!"
+msgstr "Hehe, meine Ritter geben hier den Ton an!"
+
+#: client/ai/greedy.c:1346
+msgid "First robbing us, then grabbing the points..."
+msgstr "Erst uns ausrauben und dann noch Punkte dafür kassieren..."
+
+#: client/ai/greedy.c:1349
+msgid "See that road!"
+msgstr "Schaut euch diese Straße an!"
+
+#: client/ai/greedy.c:1352
+msgid "Pf, you won't win with roads alone..."
+msgstr "Pft, mit Straßen allein gewinnt keiner..."
+
+#: client/ai/greedy.c:1819
+msgid "Rejecting trade.\n"
+msgstr "Handel abgelehnt.\n"
+
+#: client/ai/greedy.c:1911
+#, c-format
+msgid "Received error from server: %s. Quitting\n"
+msgstr "Fehler vom Server erhalten: %s. Verlasse das Spiel\n"
+
+#: client/ai/greedy.c:1921
+msgid "Yippie!"
+msgstr "Juhu!"
+
+#: client/ai/greedy.c:1923
+msgid "My congratulations"
+msgstr "Glückwunsch!"
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:80
+msgid ""
+"Hello, welcome to the lobby. I am a simple robot. Type '/help' in the chat "
+"to see the list of commands I know."
+msgstr ""
+"Willkommen in der Lobby. Ich bin ein einfacher Roboter. Sende '/help' im "
+"Chat um die Liste der Befehle, die ich kenne, zu sehen."
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:107
+msgid "'/help' shows this message again"
+msgstr "'/help' zeigt diese Nachricht nochmals"
+
+#. Translators: don't translate '/why'
+#: client/ai/lobbybot.c:110
+msgid "'/why' explains the purpose of this strange board layout"
+msgstr "'/why' erklärt den Grund für dieses komische Brettlayout"
+
+#. Translators: don't translate '/news'
+#: client/ai/lobbybot.c:113
+msgid "'/news' tells the last released version"
+msgstr "'/news' zeigt die zuletzt erschienene Version"
+
+#: client/ai/lobbybot.c:118
+msgid ""
+"This board is not intended to be a game that can be played. Instead, players "
+"can find eachother here, and decide which board they want to play. Then, one "
+"of the players will host the proposed game by starting a server, and "
+"registers it at the metaserver. The other players can subsequently "
+"disconnect from the lobby, and enter that game."
+msgstr ""
+"Dieses Brett ist nicht zum Spielen vorgesehen. Dafür können sich Spieler "
+"hier treffen und entscheiden, auf welchem Brett sie miteinander spielen "
+"wollen. Dann muss einer der Spieler das Spiel eröffnen, indem er einen "
+"Server startet und ihn beim Metaserver registriert. Die anderen Spieler "
+"können dann die Lobby verlassen und das neue Spiel betreten."
+
+#: client/ai/lobbybot.c:129
+msgid "The last released version of Pioneers is"
+msgstr "Die zuletzt veröffentlichte Version von Pioneers ist"
+
+#: client/ai/lobbybot.c:144
+msgid "The game is starting. I'm not needed anymore. Goodbye."
+msgstr "Das Spiel beginnt. Ich werde nicht mehr benötigt. Auf Wiedersehen."
+
+#: client/common/client.c:103
+msgid "Waiting"
+msgstr "Warte"
+
+#: client/common/client.c:105 client/common/client.c:1241
+msgid "Idle"
+msgstr "Untätig"
+
+#: client/common/client.c:447
+msgid "We have been kicked out of the game.\n"
+msgstr "Du wurdest aus dem Spiel geworfen.\n"
+
+#. Network status: offline
+#: client/common/client.c:450 client/common/client.c:891 client/gtk/gui.c:1340
+msgid "Offline"
+msgstr "Offline"
+
+#: client/common/client.c:471
+#, c-format
+msgid "Error (%s): %s\n"
+msgstr "Fehler (%s): %s\n"
+
+#: client/common/client.c:480 client/common/client.c:491
+#, c-format
+msgid "Notice: %s\n"
+msgstr "Mitteilung: %s\n"
+
+#: client/common/client.c:607
+#, c-format
+msgid "%s does not receive any %s, because the bank is empty.\n"
+msgstr "%s bekommt kein %s, weil die Bank leer is.\n"
+
+#: client/common/client.c:620
+#, c-format
+msgid "%s only receives %s, because the bank didn't have any more.\n"
+msgstr "%s bekommt nur %s, weil die Bank nicht mehr davon hat.\n"
+
+#: client/common/client.c:629
+#, c-format
+msgid "%s receives %s.\n"
+msgstr "%s bekommt %s.\n"
+
+#. Year of Plenty
+#: client/common/client.c:637 client/common/client.c:2586
+#, c-format
+msgid "%s takes %s.\n"
+msgstr "%s nimmt %s.\n"
+
+#: client/common/client.c:642
+#, c-format
+msgid "%s spent %s.\n"
+msgstr "%s zahlt %s.\n"
+
+#: client/common/client.c:648
+#, c-format
+msgid "%s is refunded %s.\n"
+msgstr "%s erhält %s zurück.\n"
+
+#: client/common/client.c:679
+#, c-format
+msgid "%s discarded %s.\n"
+msgstr "%s hat %s abgelegt.\n"
+
+#: client/common/client.c:849
+msgid "Loading"
+msgstr "Lade"
+
+#: client/common/client.c:892
+msgid "Version mismatch"
+msgstr "Versionsunterschied"
+
+#: client/common/client.c:894
+msgid "Version mismatch. Please make sure client and server are up to date.\n"
+msgstr ""
+"Versionsunterschied. Bitte stelle sicher, dass der Client und der Server auf "
+"dem neuesten Stand sind.\n"
+
+#: client/common/client.c:1340
+msgid "Build two settlements, each with a connecting"
+msgstr "Baue zwei Siedlungen mit je einer verbundenen"
+
+#: client/common/client.c:1343
+msgid "Build a settlement with a connecting"
+msgstr "Baue eine Siedlung mit einer verbundenen"
+
+#: client/common/client.c:1346
+msgid "road"
+msgstr "Straße"
+
+#: client/common/client.c:1348
+msgid "bridge"
+msgstr "Brücke"
+
+#: client/common/client.c:1350
+msgid "ship"
+msgstr "Schiff"
+
+#: client/common/client.c:1358
+msgid " or"
+msgstr " oder"
+
+#: client/common/client.c:1416
+msgid "Waiting for your turn"
+msgstr "Warte auf deinen Zug"
+
+#: client/common/client.c:1468
+msgid "Select the building to steal from."
+msgstr "Wähle das Gebäude, von dem gestohlen werden soll."
+
+#: client/common/client.c:1490
+msgid "Select the ship to steal from."
+msgstr "Wähle das Schiff, von dem du stehlen willst."
+
+#: client/common/client.c:1575 client/gtk/interface.c:782
+msgid "Place the robber"
+msgstr "Setze den Räuber"
+
+#: client/common/client.c:1625
+msgid "Finish the road building action."
+msgstr "Beende die Straßenbauaktion."
+
+#: client/common/client.c:1627
+msgid "Build one road segment."
+msgstr "Baue eine Straße."
+
+#: client/common/client.c:1629
+msgid "Build two road segments."
+msgstr "Baue zwei Straßen."
+
+#: client/common/client.c:1902 client/common/client.c:1996
+msgid "It is your turn."
+msgstr "Du bist am Zug."
+
+#: client/common/client.c:2090
+#, c-format
+msgid "Sorry, %s available.\n"
+msgstr "Entschuldigung, %s verfügbar.\n"
+
+#: client/common/client.c:2405
+msgid "The game is over."
+msgstr "Das Spiel ist beendet."
+
+#: client/common/develop.c:43 editor/gtk/game-devcards.c:13
+msgid "Road Building"
+msgstr "Straßenbau"
+
+#: client/common/develop.c:44 client/gtk/monopoly.c:83
+#: editor/gtk/game-devcards.c:13
+msgid "Monopoly"
+msgstr "Monopol"
+
+#: client/common/develop.c:45 client/gtk/plenty.c:59
+#: editor/gtk/game-devcards.c:13
+msgid "Year of Plenty"
+msgstr "Erfindung"
+
+#: client/common/develop.c:46 client/gtk/player.c:57
+#: editor/gtk/game-devcards.c:14
+msgid "Chapel"
+msgstr "Kathedrale"
+
+#: client/common/develop.c:47 client/gtk/player.c:58
+#: editor/gtk/game-devcards.c:14
+msgid "Pioneer University"
+msgstr "Pioneer Universität"
+
+#: client/common/develop.c:48 client/gtk/player.c:60
+#: editor/gtk/game-devcards.c:15
+msgid "Governor's House"
+msgstr "Regierungsgebäude"
+
+#: client/common/develop.c:49 client/gtk/player.c:61
+#: editor/gtk/game-devcards.c:15
+msgid "Library"
+msgstr "Bibliothek"
+
+#: client/common/develop.c:50 client/gtk/player.c:62
+#: editor/gtk/game-devcards.c:15
+msgid "Market"
+msgstr "Marktplatz"
+
+#: client/common/develop.c:51 client/gtk/player.c:63
+#: editor/gtk/game-devcards.c:16
+msgid "Soldier"
+msgstr "Ritter"
+
+#: client/common/develop.c:82
+#, c-format
+msgid "You bought the %s development card.\n"
+msgstr "Du hast die %s-Entwicklungskarte gekauft.\n"
+
+#: client/common/develop.c:88
+#, c-format
+msgid "You bought a %s development card.\n"
+msgstr "Du hast eine %s-Entwicklungskarte gekauft.\n"
+
+#: client/common/develop.c:110
+#, c-format
+msgid "%s bought a development card.\n"
+msgstr "%s hat eine Entwicklungskarte gekauft.\n"
+
+#: client/common/develop.c:129
+#, c-format
+msgid "%s played the %s development card.\n"
+msgstr "%s hat die %s-Entwicklungskarte ausgespielt.\n"
+
+#: client/common/develop.c:134
+#, c-format
+msgid "%s played a %s development card.\n"
+msgstr "%s hat eine %s-Entwicklungskarte ausgespielt.\n"
+
+#: client/common/develop.c:147
+msgid "You have run out of road segments.\n"
+msgstr "Du hast keine Straßensegmente mehr.\n"
+
+#. I get the cards!
+#.
+#: client/common/develop.c:187
+#, c-format
+msgid "You get %s from %s.\n"
+msgstr "Du bekommst %s von %s.\n"
+
+#. I lose the cards!
+#.
+#: client/common/develop.c:193
+#, c-format
+msgid "%s took %s from you.\n"
+msgstr "%s hat %s von dir genommen.\n"
+
+#: client/common/develop.c:200
+#, c-format
+msgid "%s took %s from %s.\n"
+msgstr "%s hat %s von %s genommen.\n"
+
+#: client/common/player.c:124 server/player.c:405
+#, c-format
+msgid "Viewer %d"
+msgstr "Zuschauer %d"
+
+#: client/common/player.c:126
+#, c-format
+msgid "viewer %d"
+msgstr "Zuschauer %d"
+
+#: client/common/player.c:134 server/player.c:408
+#, c-format
+msgid "Player %d"
+msgstr "Spieler %d"
+
+#: client/common/player.c:136
+#, c-format
+msgid "player %d"
+msgstr "Spieler %d"
+
+#: client/common/player.c:212
+#, c-format
+msgid "New viewer: %s.\n"
+msgstr "Neue Zuschauer: %s.\n"
+
+#: client/common/player.c:215 client/common/player.c:231
+#, c-format
+msgid "%s is now %s.\n"
+msgstr "%s heißt jetzt %s.\n"
+
+#: client/common/player.c:228
+#, c-format
+msgid "Player %d is now %s.\n"
+msgstr "Spieler %d heißt jetzt %s.\n"
+
+#: client/common/player.c:267
+#, c-format
+msgid "%s has quit\n"
+msgstr "%s hat das Spiel verlassen\n"
+
+#: client/common/player.c:276
+msgid "There is no largest army.\n"
+msgstr "Es gibt keine größte Rittermacht.\n"
+
+#: client/common/player.c:279
+#, c-format
+msgid "%s has the largest army.\n"
+msgstr "%s hat die größte Rittermacht.\n"
+
+#: client/common/player.c:300
+msgid "There is no longest road.\n"
+msgstr "Es gibt keine längste Handelsstraße.\n"
+
+#: client/common/player.c:303
+#, c-format
+msgid "%s has the longest road.\n"
+msgstr "%s hat die längste Handelsstraße.\n"
+
+#: client/common/player.c:324
+#, c-format
+msgid "Waiting for %s."
+msgstr "Warte auf %s."
+
+#. We are not in on the action
+#. someone stole a resource from someone else
+#: client/common/player.c:352
+#, c-format
+msgid "%s stole a resource from %s.\n"
+msgstr "%s hat eine Karte von %s gestohlen.\n"
+
+#: client/common/player.c:362
+#, c-format
+msgid "You stole %s from %s.\n"
+msgstr "Du hast %s von %s gestohlen.\n"
+
+#: client/common/player.c:368
+#, c-format
+msgid "%s stole %s from you.\n"
+msgstr "%s hat %s von dir gestohlen.\n"
+
+#: client/common/player.c:402
+#, c-format
+msgid "%s gave %s nothing!?\n"
+msgstr "%s hat %s nichts gegeben!?\n"
+
+#: client/common/player.c:408 client/common/player.c:416
+#, c-format
+msgid "%s gave %s %s for free.\n"
+msgstr "%s hat %s %s gratis gegeben.\n"
+
+#: client/common/player.c:424
+#, c-format
+msgid "%s gave %s %s in exchange for %s.\n"
+msgstr "%1$s hat von %2$s %4$s für %3$s bekommen.\n"
+
+#: client/common/player.c:455
+#, c-format
+msgid "%s exchanged %s for %s.\n"
+msgstr "%s hat %s gegen %s getauscht.\n"
+
+#: client/common/player.c:475
+#, c-format
+msgid "%s built a road.\n"
+msgstr "%s hat eine Straße gebaut.\n"
+
+#: client/common/player.c:487
+#, c-format
+msgid "%s built a ship.\n"
+msgstr "%s hat ein Schiff gebaut.\n"
+
+#: client/common/player.c:500
+#, c-format
+msgid "%s built a settlement.\n"
+msgstr "%s hat eine Siedlung gebaut.\n"
+
+#: client/common/player.c:519
+#, c-format
+msgid "%s built a city.\n"
+msgstr "%s hat eine Stadt gebaut.\n"
+
+#: client/common/player.c:533
+#, c-format
+msgid "%s built a city wall.\n"
+msgstr "%s hat eine Stadtmauer gebaut.\n"
+
+#: client/common/player.c:544
+#, c-format
+msgid "player_build_add called with BUILD_NONE for user %s\n"
+msgstr "player_build_add mit BUILD_NONE für Benutzer %s aufgerufen\n"
+
+#: client/common/player.c:553
+#, c-format
+msgid "%s built a bridge.\n"
+msgstr "%s hat eine Brücke gebaut.\n"
+
+#: client/common/player.c:579
+#, c-format
+msgid "%s removed a road.\n"
+msgstr "%s hat eine Straße entfernt.\n"
+
+#: client/common/player.c:589
+#, c-format
+msgid "%s removed a ship.\n"
+msgstr "%s hat ein Schiff entfernt.\n"
+
+#: client/common/player.c:599
+#, c-format
+msgid "%s removed a settlement.\n"
+msgstr "%s hat eine Siedlung entfernt.\n"
+
+#: client/common/player.c:610
+#, c-format
+msgid "%s removed a city.\n"
+msgstr "%s hat eine Stadt entfernt.\n"
+
+#: client/common/player.c:624
+#, c-format
+msgid "%s removed a city wall.\n"
+msgstr "%s hat eine Stadtmauer entfernt.\n"
+
+#: client/common/player.c:634
+#, c-format
+msgid "player_build_remove called with BUILD_NONE for user %s\n"
+msgstr "player_build_remove mit BUILD_NONE für Benutzer %s aufgerufen\n"
+
+#: client/common/player.c:642
+#, c-format
+msgid "%s removed a bridge.\n"
+msgstr "%s hat eine Brücke entfernt.\n"
+
+#: client/common/player.c:673
+#, c-format
+msgid "%s has cancelled a ship's movement.\n"
+msgstr "%s hat eine Schiffsbewegung zurückgenommen.\n"
+
+#: client/common/player.c:676
+#, c-format
+msgid "%s moved a ship.\n"
+msgstr "%s hat ein Schiff bewegt.\n"
+
+#. tell the user that someone got something
+#: client/common/player.c:696
+#, c-format
+msgid "%s received %s.\n"
+msgstr "%s hat %s bekommen.\n"
+
+#: client/common/player.c:714
+msgid "server asks to lose invalid point.\n"
+msgstr "Server will einen nicht vorhandenen Punkt wegnehmen.\n"
+
+#. tell the user the point is lost
+#: client/common/player.c:720
+#, c-format
+msgid "%s lost %s.\n"
+msgstr "%s hat %s verloren.\n"
+
+#: client/common/player.c:743
+msgid "server asks to move invalid point.\n"
+msgstr "Server will einen nicht vorhandenen Punkt übertragen.\n"
+
+#. tell the user someone (1) lost something (2) to someone else (3)
+#: client/common/player.c:750
+#, c-format
+msgid "%s lost %s to %s.\n"
+msgstr "%s hat %s an %s verloren.\n"
+
+#: client/common/resource.c:35
+msgid "brick"
+msgstr "Lehm"
+
+#: client/common/resource.c:35
+msgid "Brick"
+msgstr "Lehm"
+
+#: client/common/resource.c:36
+msgid "grain"
+msgstr "Getreide"
+
+#: client/common/resource.c:36
+msgid "Grain"
+msgstr "Getreide"
+
+#: client/common/resource.c:37
+msgid "ore"
+msgstr "Erz"
+
+#: client/common/resource.c:37
+msgid "Ore"
+msgstr "Erz"
+
+#: client/common/resource.c:38
+msgid "wool"
+msgstr "Wolle"
+
+#: client/common/resource.c:38
+msgid "Wool"
+msgstr "Wolle"
+
+#: client/common/resource.c:39
+msgid "lumber"
+msgstr "Holz"
+
+#: client/common/resource.c:39
+msgid "Lumber"
+msgstr "Holz"
+
+#: client/common/resource.c:40
+msgid "no resource (bug)"
+msgstr "kein Rohstoff (Fehler)"
+
+#: client/common/resource.c:40
+msgid "No resource (bug)"
+msgstr "Kein Rohstoff (Fehler)"
+
+#: client/common/resource.c:41
+msgid "any resource (bug)"
+msgstr "beliebiger Rohstoff (Fehler)"
+
+#: client/common/resource.c:41
+msgid "Any resource (bug)"
+msgstr "Beliebiger Rohstoff (Fehler)"
+
+#: client/common/resource.c:42
+msgid "gold"
+msgstr "Gold"
+
+#: client/common/resource.c:42 client/gtk/legend.c:39
+msgid "Gold"
+msgstr "Gold"
+
+#: client/common/resource.c:47
+msgid "a brick card"
+msgstr "eine Lehm-Karte"
+
+#: client/common/resource.c:47
+#, c-format
+msgid "%d brick cards"
+msgstr "%d Lehm-Karten"
+
+#: client/common/resource.c:48
+msgid "a grain card"
+msgstr "eine Getreide-Karte"
+
+#: client/common/resource.c:48
+#, c-format
+msgid "%d grain cards"
+msgstr "%d Getreide-Karten"
+
+#: client/common/resource.c:49
+msgid "an ore card"
+msgstr "eine Erz-Karte"
+
+#: client/common/resource.c:49
+#, c-format
+msgid "%d ore cards"
+msgstr "%d Erz-Karten"
+
+#: client/common/resource.c:50
+msgid "a wool card"
+msgstr "eine Wolle-Karte"
+
+#: client/common/resource.c:50
+#, c-format
+msgid "%d wool cards"
+msgstr "%d Wolle-Karten"
+
+#: client/common/resource.c:51
+msgid "a lumber card"
+msgstr "eine Holz-Karte"
+
+#: client/common/resource.c:51
+#, c-format
+msgid "%d lumber cards"
+msgstr "%d Holz-Karten"
+
+#: client/common/resource.c:139 client/common/resource.c:225
+msgid "nothing"
+msgstr "nichts"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:166
+#, c-format
+msgid "%s and %s"
+msgstr "%s und %s"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:170
+#, c-format
+msgid "%s, %s"
+msgstr "%s, %s"
+
+#: client/common/robber.c:60
+#, c-format
+msgid "%s has undone the robber movement.\n"
+msgstr "%s hat den Räuber zurückgesetzt.\n"
+
+#: client/common/robber.c:63
+#, c-format
+msgid "%s moved the robber.\n"
+msgstr "%s hat den Räuber gesetzt.\n"
+
+#: client/common/robber.c:73
+#, c-format
+msgid "%s has undone the pirate movement.\n"
+msgstr "%s hat eine Piratenbewegung zurückgenommen.\n"
+
+#: client/common/robber.c:76
+#, c-format
+msgid "%s moved the pirate.\n"
+msgstr "%s hat den Pirat gesetzt.\n"
+
+#: client/common/robber.c:83
+#, c-format
+msgid "%s must move the robber."
+msgstr "%s muß den Räuber setzen."
+
+#: client/common/setup.c:140
+#, c-format
+msgid "Setup for %s.\n"
+msgstr "Gründungsphase für %s.\n"
+
+#: client/common/setup.c:152
+#, c-format
+msgid "Double setup for %s.\n"
+msgstr "Doppelte Gründungsphase für %s.\n"
+
+#: client/common/turn.c:37
+#, c-format
+msgid "%s rolled %d.\n"
+msgstr "%s hat %d gewürfelt.\n"
+
+#: client/common/turn.c:50
+#, c-format
+msgid "Begin turn %d for %s.\n"
+msgstr "Beginn Runde %d für %s.\n"
+
+#: client/gtk/chat.c:71
+msgid "<b>Chat</b>"
+msgstr "<b>Chat</b>"
+
+#: client/gtk/chat.c:231
+msgid "Beeper test.\n"
+msgstr "Piepser-Test.\n"
+
+#: client/gtk/chat.c:234
+#, c-format
+msgid "%s beeped you.\n"
+msgstr "%s hat dich angepiepst.\n"
+
+#: client/gtk/chat.c:238
+#, c-format
+msgid "You beeped %s.\n"
+msgstr "Du hast %s angepiepst.\n"
+
+#: client/gtk/chat.c:244
+#, c-format
+msgid "You could not beep %s.\n"
+msgstr "Du konntest %s nicht anpiepsen.\n"
+
+#: client/gtk/chat.c:288
+msgid " said: "
+msgstr " sagte: "
+
+#: client/gtk/connect.c:282
+#, c-format
+msgid "Meta-server at %s, port %s"
+msgstr "Metaserver auf %s, Port %s"
+
+#: client/gtk/connect.c:292
+msgid "Finished.\n"
+msgstr "Fertig.\n"
+
+#: client/gtk/connect.c:309 client/gtk/connect.c:359 client/gtk/connect.c:456
+#: server/meta.c:174
+msgid "Meta-server kicked us off\n"
+msgstr "Metaserver hat die Verbindung beendet.\n"
+
+#: client/gtk/connect.c:334
+msgid "Receiving game names from the meta server.\n"
+msgstr "Empfange Spielenamen vom Metaserver.\n"
+
+#: client/gtk/connect.c:382
+#, c-format
+msgid "New game server requested on %s port %s\n"
+msgstr "Neuer Spielserver angefordert auf %s port %s\n"
+
+#: client/gtk/connect.c:391 server/meta.c:168
+#, c-format
+msgid "Unknown message from the metaserver: %s\n"
+msgstr "Unbekannte Nachricht vom Metaserver: %s\n"
+
+#: client/gtk/connect.c:472 server/meta.c:125
+msgid "Too many meta-server redirects\n"
+msgstr "Zu viele Metaserver-Weiterleitungen\n"
+
+#: client/gtk/connect.c:499 server/meta.c:140
+#, c-format
+msgid "Bad redirect line: %s\n"
+msgstr "Fehlerhafte Weiterleitungszeile: %s\n"
+
+#: client/gtk/connect.c:525
+#, c-format
+msgid "Meta server too old to create servers (version %d.%d)\n"
+msgstr "Metaserver zu alt, um Spielserver zu starten (Version %d.%d)\n"
+
+#. Sevens rule: normal
+#: client/gtk/connect.c:596 client/gtk/settingscreen.c:168
+#: common/gtk/game-rules.c:81
+msgid "Normal"
+msgstr "Standard"
+
+#: client/gtk/connect.c:602 client/gtk/settingscreen.c:170
+#: common/gtk/game-rules.c:88
+msgid "Reroll on 1st 2 turns"
+msgstr "Wiederholen in ersten 2 Runden"
+
+#: client/gtk/connect.c:605 client/gtk/settingscreen.c:172
+#: common/gtk/game-rules.c:95
+msgid "Reroll all 7s"
+msgstr "Immer wiederholen"
+
+#: client/gtk/connect.c:619
+msgid "Default"
+msgstr "Standard"
+
+#: client/gtk/connect.c:622
+msgid "Random"
+msgstr "Zufällig"
+
+#: client/gtk/connect.c:653 server/meta.c:188
+#, c-format
+msgid "Redirected to meta-server at %s, port %s\n"
+msgstr "Weitergeleitet zu Metaserver auf %s, Port %s\n"
+
+#: client/gtk/connect.c:656
+msgid "Receiving a list of Pioneers servers from the meta server.\n"
+msgstr "Empfange eine Liste von Pioneers-Servern vom Metaserver.\n"
+
+#: client/gtk/connect.c:713
+msgid ""
+"<b>Note</b>:\n"
+"\tThe metaserver does not send information about the games.\n"
+"\tPlease set appropriate values yourself."
+msgstr ""
+"<b>Notiz</b>:\n"
+"\tDer Metaserver sendet keine Informationen über die Spiele.\n"
+"\tBitte setze die entsprechenden Werte selbst."
+
+#: client/gtk/connect.c:730
+msgid "Number of AI Players"
+msgstr "Anzahl Computerspieler"
+
+#: client/gtk/connect.c:749
+msgid "The number of AI players"
+msgstr "Anzahl der Computerspieler"
+
+#: client/gtk/connect.c:770
+msgid "Requesting new game server\n"
+msgstr "Anfrage für einen neuen Spielserver gesendet\n"
+
+#: client/gtk/connect.c:813 server/gtk/main.c:328 server/server.c:160
+#, c-format
+msgid "Error starting %s: %s"
+msgstr "Fehler beim Starten von %s: %s"
+
+#: client/gtk/connect.c:834
+msgid "Create a public game"
+msgstr "Ein öffentliches Spiel erstellen"
+
+#: client/gtk/connect.c:965 client/gtk/connect.c:1268
+msgid "Join a public game"
+msgstr "An einem öffentlichen Spiel teilnehmen"
+
+#: client/gtk/connect.c:970
+msgid "_New remote game"
+msgstr "_Neues Netzwerkspiel"
+
+#: client/gtk/connect.c:984
+msgid "Refresh the list of games"
+msgstr "Spiel-Liste aktualisieren"
+
+#: client/gtk/connect.c:989
+msgid "Create a new public game at the meta server"
+msgstr "Neues öffentliches Spiel auf dem Metaserver erstellen"
+
+#: client/gtk/connect.c:994
+msgid "Don't join a public game"
+msgstr "Nicht an öffentlichem Spiel teilnehmen"
+
+#: client/gtk/connect.c:998
+msgid "Join the selected game"
+msgstr "An ausgewähltem Spiel teilnehmen"
+
+#: client/gtk/connect.c:1033
+msgid "Select a game to join"
+msgstr "Wähle ein Spiel zur Teilnahme"
+
+#: client/gtk/connect.c:1036
+msgid "Map Name"
+msgstr "Kartenname"
+
+#: client/gtk/connect.c:1044
+msgid "Name of the game"
+msgstr "Name des Spiels"
+
+#: client/gtk/connect.c:1049
+msgid "Curr"
+msgstr "Akt"
+
+#: client/gtk/connect.c:1055
+msgid "Number of players in the game"
+msgstr "Anzahl der Spieler im Spiel"
+
+#: client/gtk/connect.c:1060
+msgid "Max"
+msgstr "Max"
+
+#: client/gtk/connect.c:1066
+msgid "Maximum players for the game"
+msgstr "Höchste Spieleranzahl für das Spiel"
+
+#: client/gtk/connect.c:1069
+msgid "Terrain"
+msgstr "Gelände"
+
+#: client/gtk/connect.c:1076
+msgid "Random of default terrain"
+msgstr "Zufällige Geländeverteilung"
+
+#: client/gtk/connect.c:1081
+msgid "Vic. Points"
+msgstr "Siegpunkte"
+
+#: client/gtk/connect.c:1087
+msgid "Points needed to win"
+msgstr "Punkte für Sieg"
+
+#: client/gtk/connect.c:1090 common/gtk/game-rules.c:73
+msgid "Sevens Rule"
+msgstr "7-Regel"
+
+#: client/gtk/connect.c:1096
+msgid "Sevens rule"
+msgstr "7-Regel"
+
+#: client/gtk/connect.c:1100
+msgid "Host"
+msgstr "Host-Rechner"
+
+#: client/gtk/connect.c:1108
+msgid "Host of the game"
+msgstr "Host des Spiels"
+
+#: client/gtk/connect.c:1113
+msgid "Port"
+msgstr "Port"
+
+#: client/gtk/connect.c:1119
+msgid "Port of the the game"
+msgstr "Spielport"
+
+#: client/gtk/connect.c:1122 common/gtk/aboutbox.c:77
+msgid "Version"
+msgstr "Version"
+
+#: client/gtk/connect.c:1129
+msgid "Version of the host"
+msgstr "Version des Hosts"
+
+#: client/gtk/connect.c:1184 client/gtk/gui.c:215
+msgid "Start a new game"
+msgstr "Ein neues Spiel starten"
+
+#: client/gtk/connect.c:1209
+msgid "Player Name"
+msgstr "Spielername"
+
+#: client/gtk/connect.c:1223
+msgid "Enter your name"
+msgstr "Gib deinen Namen ein"
+
+#. Role of the player: viewer
+#: client/gtk/connect.c:1225 server/gtk/main.c:511
+msgid "Viewer"
+msgstr "Zuschauer"
+
+#: client/gtk/connect.c:1233
+msgid "Do you want to be a viewer?"
+msgstr "Willst du Zuschauer sein?"
+
+#: client/gtk/connect.c:1240 server/gtk/main.c:640
+msgid "Meta Server"
+msgstr "Metaserver"
+
+#: client/gtk/connect.c:1255
+msgid "Leave empty for the default meta server"
+msgstr "Frei lassen, um den Standard Metaserver zu nutzen"
+
+#: client/gtk/connect.c:1263
+msgid "Join public game"
+msgstr "An öffentlichem Spiel teilnehmen"
+
+#: client/gtk/connect.c:1272
+msgid "Create game"
+msgstr "Spiel erstellen"
+
+#: client/gtk/connect.c:1275
+msgid "Create a game"
+msgstr "Ein Spiel erstellen"
+
+#: client/gtk/connect.c:1285
+msgid "Join private game"
+msgstr "An privatem Spiel teilnehmen"
+
+#: client/gtk/connect.c:1289 client/gtk/connect.c:1434
+msgid "Join a private game"
+msgstr "An einem privaten Spiel teilnehmen"
+
+#: client/gtk/connect.c:1475
+msgid "Name of the host of the game"
+msgstr "Name des Spiel-Hosts"
+
+#: client/gtk/connect.c:1494
+msgid "Port of the host of the game"
+msgstr "Port des Spiel-Hosts"
+
+#: client/gtk/connect.c:1534
+msgid "Recent games"
+msgstr "Zuletzt besuchte Spielserver"
+
+#: client/gtk/connect.c:1536
+msgid "Recent Games"
+msgstr "Zuletzt besuchte Spielserver"
+
+#: client/gtk/develop.c:129
+msgid "<b>Development Cards</b>"
+msgstr "<b>Entwicklungskarten</b>"
+
+#: client/gtk/develop.c:160
+msgid "Play Card"
+msgstr "Karte ausspielen"
+
+#: client/gtk/discard.c:76
+msgid "Discard resources"
+msgstr "Karten ablegen"
+
+#: client/gtk/discard.c:96
+#, c-format
+msgid "You must discard %d resources"
+msgstr "Du mußt %d Karten ablegen"
+
+#: client/gtk/discard.c:101
+msgid "Total discards"
+msgstr "Insgesamt abgelegte Karten"
+
+#. Caption for list of player that must discard cards
+#: client/gtk/discard.c:226
+msgid "<b>Waiting for players to discard</b>"
+msgstr "<b>Warte auf Spieler, die ablegen müssen</b>"
+
+#: client/gtk/gameover.c:32
+msgid "Game over"
+msgstr "Spiel beendet"
+
+#: client/gtk/gameover.c:49
+#, c-format
+msgid "%s has won the game with %d victory points!"
+msgstr "%s hat das Spiel mit %d Punkten gewonnen!"
+
+#: client/gtk/gameover.c:52
+#, c-format
+msgid "%s has won the game with %d victory points!\n"
+msgstr "%s hat das Spiel mit %d Punkten gewonnen!\n"
+
+#: client/gtk/gameover.c:58
+#, c-format
+msgid "All praise %s, Lord of the known world!"
+msgstr "Lobet %s, den Herrscher der bekannten Welt!"
+
+#: client/gtk/gold.c:71
+msgid "Choose resources"
+msgstr "Karten wählen"
+
+#: client/gtk/gold.c:92
+#, c-format
+msgid "You may choose 1 resource"
+msgstr "Du mußt 1 Karte wählen"
+
+#: client/gtk/gold.c:94
+#, c-format
+msgid "You may choose %d resources"
+msgstr "Du mußt %d Karten wählen"
+
+#. Text for total in choose gold dialog
+#. Text for total in year of plenty dialog
+#: client/gtk/gold.c:101 client/gtk/plenty.c:98
+msgid "Total resources"
+msgstr "Insgesamt"
+
+#: client/gtk/gold.c:213
+msgid "<b>Waiting for players to choose</b>"
+msgstr "<b>Warte auf Spieler, die wählen müssen</b>"
+
+#: client/gtk/gui.c:213 server/gtk/main.c:98
+msgid "_Game"
+msgstr "_Spiel"
+
+#: client/gtk/gui.c:214
+msgid "_New game"
+msgstr "_Neues Spiel"
+
+#: client/gtk/gui.c:216
+msgid "_Leave game"
+msgstr "Spiel ver_lassen"
+
+#: client/gtk/gui.c:217
+msgid "Leave this game"
+msgstr "Dieses Spiel verlassen"
+
+#: client/gtk/gui.c:219
+msgid "_Admin"
+msgstr "_Administration"
+
+#: client/gtk/gui.c:220
+msgid "Administer Pioneers server"
+msgstr "Pioneers-Server verwalten"
+
+#: client/gtk/gui.c:222
+msgid "_Player name"
+msgstr "S_pielername"
+
+#: client/gtk/gui.c:223
+msgid "Change your player name"
+msgstr "Ändern des Spielernamens"
+
+#: client/gtk/gui.c:224
+msgid "_Legend"
+msgstr "_Erklärung"
+
+#: client/gtk/gui.c:225
+msgid "Terrain legend and building costs"
+msgstr "Geländeerklärung und Gebäudekosten"
+
+#: client/gtk/gui.c:226
+msgid "_Game Settings"
+msgstr "_Spieleinstellungen"
+
+#: client/gtk/gui.c:227
+msgid "Settings for the current game"
+msgstr "Einstellungen des aktuellen Spiels"
+
+#: client/gtk/gui.c:228
+msgid "_Dice Histogram"
+msgstr "_Würfelhistogramm"
+
+#: client/gtk/gui.c:229
+msgid "Histogram of dice rolls"
+msgstr "Histogramm der Würfelergebnisse"
+
+#: client/gtk/gui.c:230 editor/gtk/editor.c:1018 server/gtk/main.c:103
+msgid "_Quit"
+msgstr "_Quit"
+
+#: client/gtk/gui.c:231 server/gtk/main.c:104
+msgid "Quit the program"
+msgstr "Das Programm verlassen"
+
+#: client/gtk/gui.c:232
+msgid "_Actions"
+msgstr "_Aktionen"
+
+#: client/gtk/gui.c:233
+msgid "Roll Dice"
+msgstr "Würfeln"
+
+#: client/gtk/gui.c:234
+msgid "Roll the dice"
+msgstr "Würfeln"
+
+#. Tab page name
+#: client/gtk/gui.c:235 client/gtk/gui.c:577
+msgid "Trade"
+msgstr "Handel"
+
+#: client/gtk/gui.c:237
+msgid "Undo"
+msgstr "Rückgängig"
+
+#: client/gtk/gui.c:238 client/gtk/gui.c:239
+msgid "Finish"
+msgstr "Fertig"
+
+#: client/gtk/gui.c:240 client/gtk/legend.c:226 editor/gtk/game-buildings.c:13
+msgid "Road"
+msgstr "Straße"
+
+#: client/gtk/gui.c:241
+msgid "Build a road"
+msgstr "Baue eine Straße"
+
+#: client/gtk/gui.c:242 client/gtk/legend.c:230 editor/gtk/game-buildings.c:13
+msgid "Ship"
+msgstr "Schiff"
+
+#: client/gtk/gui.c:243
+msgid "Build a ship"
+msgstr "Baue ein Schiff"
+
+#: client/gtk/gui.c:244
+msgid "Move Ship"
+msgstr "Schiff verlegen"
+
+#: client/gtk/gui.c:245
+msgid "Move a ship"
+msgstr "Bewege ein Schiff"
+
+#: client/gtk/gui.c:246 client/gtk/legend.c:233 editor/gtk/game-buildings.c:13
+msgid "Bridge"
+msgstr "Brücke"
+
+#: client/gtk/gui.c:247
+msgid "Build a bridge"
+msgstr "Baue eine Brücke"
+
+#: client/gtk/gui.c:248 client/gtk/legend.c:235 client/gtk/player.c:52
+#: editor/gtk/game-buildings.c:13
+msgid "Settlement"
+msgstr "Siedlung"
+
+#: client/gtk/gui.c:249
+msgid "Build a settlement"
+msgstr "Baue eine Siedlung"
+
+#: client/gtk/gui.c:250 client/gtk/legend.c:236 client/gtk/player.c:53
+#: editor/gtk/game-buildings.c:14
+msgid "City"
+msgstr "Stadt"
+
+#: client/gtk/gui.c:251
+msgid "Build a city"
+msgstr "Baue eine Stadt"
+
+#: client/gtk/gui.c:252
+msgid "Develop"
+msgstr "Entwicklungskarte"
+
+#: client/gtk/gui.c:253
+msgid "Buy a development card"
+msgstr "Kaufe eine Entwicklungskarte"
+
+#: client/gtk/gui.c:254 client/gtk/legend.c:240 client/gtk/player.c:54
+#: editor/gtk/game-buildings.c:14
+msgid "City Wall"
+msgstr "Stadtmauer"
+
+#: client/gtk/gui.c:255
+msgid "Build a city wall"
+msgstr "Baue eine Stadtmauer"
+
+#: client/gtk/gui.c:257
+msgid "_Settings"
+msgstr "_Einstellungen"
+
+#: client/gtk/gui.c:258
+msgid "Prefere_nces"
+msgstr "Einstellu_ngen"
+
+#: client/gtk/gui.c:259
+msgid "Configure the application"
+msgstr "Konfiguriere die Anwendung"
+
+#: client/gtk/gui.c:261 client/gtk/gui.c:265 editor/gtk/editor.c:1002
+#: server/gtk/main.c:99
+msgid "_Help"
+msgstr "_Hilfe"
+
+#: client/gtk/gui.c:262
+msgid "_About Pioneers"
+msgstr "Ü_ber Pioneers"
+
+#: client/gtk/gui.c:263
+msgid "Information about Pioneers"
+msgstr "Informationen über Pioneers"
+
+#: client/gtk/gui.c:266 client/gtk/gui.c:1065
+msgid "Show the manual"
+msgstr "Das Handbuch zeigen"
+
+#: client/gtk/gui.c:272
+msgid "_Toolbar"
+msgstr "_Werkzeugleiste"
+
+#: client/gtk/gui.c:273
+msgid "Show or hide the toolbar"
+msgstr "Werkzeugleiste zeigen oder verstecken"
+
+#. Victory points target in statusbar
+#: client/gtk/gui.c:368
+#, c-format
+msgid "Points Needed to Win: %i"
+msgstr "Punkte für Sieg: %i"
+
+#: client/gtk/gui.c:454
+msgid "<b>Messages</b>"
+msgstr "<b>Nachrichten</b>"
+
+#. Tab page name
+#: client/gtk/gui.c:571 editor/gtk/editor.c:1165
+msgid "Map"
+msgstr "Karte"
+
+#. Tab page name
+#: client/gtk/gui.c:585 client/gtk/quote.c:306
+msgid "Quote"
+msgstr "Angebot"
+
+#. Tab page name
+#: client/gtk/gui.c:593 client/gtk/legend.c:261
+msgid "Legend"
+msgstr "Erklärung"
+
+#. Tab page name, shown for the splash screen
+#: client/gtk/gui.c:603
+msgid "Welcome to Pioneers"
+msgstr "Willkommen zu Pioneers"
+
+#: client/gtk/gui.c:868
+msgid "Pioneers Preferences"
+msgstr "Pioneers Einstellungen"
+
+#. Label for changing the theme, in the preferences dialog
+#: client/gtk/gui.c:898
+msgid "Theme:"
+msgstr "Thema:"
+
+#: client/gtk/gui.c:921
+msgid "Choose one of the themes"
+msgstr "Wähle eins der Themen"
+
+#. Label for the option to show the legend
+#: client/gtk/gui.c:925
+msgid "Show legend"
+msgstr "Legende Anzeigen"
+
+#. Tooltip for the option to show the legend
+#: client/gtk/gui.c:935
+msgid "Show the legend as a page beside the map"
+msgstr "Erklärung als eigene Seite neben der Karte anzeigen"
+
+#. Label for the option to display log messages in color
+#: client/gtk/gui.c:940
+msgid "Messages with color"
+msgstr "Nachrichten mit Farben anzeigen"
+
+#: client/gtk/gui.c:950
+msgid "Show new messages with color"
+msgstr "Neue Nachrichten mit Farben anzeigen"
+
+#: client/gtk/gui.c:955
+msgid "Chat in color of player"
+msgstr "Chat in den Spielerfarben"
+
+#: client/gtk/gui.c:966
+msgid "Show new chat messages in the color of the player"
+msgstr "Neue Chatnachrichten in den Farben der Spieler zeigen"
+
+#. Label for the option to display the summary with colors
+#: client/gtk/gui.c:971
+msgid "Summary with color"
+msgstr "Zusammenfassung mit Farben anzeigen"
+
+#: client/gtk/gui.c:982
+msgid "Use colors in the player summary"
+msgstr "Farben in der Spielerzusammenfassung benutzen"
+
+#: client/gtk/gui.c:987
+msgid "Toolbar with shortcuts"
+msgstr "Werkzeugleiste mit Shortcuts"
+
+#: client/gtk/gui.c:997
+msgid "Show keyboard shortcuts in the toolbar"
+msgstr "Tastatur-Shortcuts in der Werkzeugleiste zeigen"
+
+#: client/gtk/gui.c:1003
+msgid "Announce new players"
+msgstr "Neue Spieler ankündigen"
+
+#: client/gtk/gui.c:1014
+msgid "Make a sound when a new player or viewer enters the game"
+msgstr ""
+"Spiele ein Geräusch, wenn ein neuer Spieler oder Zuschauer das Spiel betritt"
+
+#. Label for the option to use the 16:9 layout.
+#: client/gtk/gui.c:1019
+msgid "Use 16:9 layout"
+msgstr "Benutze 16:9 Layout"
+
+#: client/gtk/gui.c:1030
+msgid "Use a 16:9 friendly layout for the window"
+msgstr "Benutze ein 16:9-freundliches Layout für das Fenster"
+
+#: client/gtk/gui.c:1041
+msgid "The Pioneers Game"
+msgstr "Das Pioneers-Spiel"
+
+#. Initial text in status bar
+#: client/gtk/gui.c:1352
+msgid "Welcome to Pioneers!"
+msgstr "Willkommen zu Pioneers!"
+
+#. The name of the application
+#: client/gtk/gui.c:1463
+msgid "Pioneers"
+msgstr "Pioneers"
+
+#: client/gtk/histogram.c:252
+msgid "Dice Histogram"
+msgstr "Würfelhistogramm"
+
+#: client/gtk/interface.c:92
+msgid "Ship movement canceled."
+msgstr "Schiff-Bewegung abgebrochen."
+
+#: client/gtk/interface.c:100 client/gtk/interface.c:101
+msgid "Select a new location for the ship."
+msgstr "Wähle die neue Position des Schiffes."
+
+#: client/gtk/interface.c:740
+msgid "Select the ship to steal from"
+msgstr "Wähle das Schiff, von dem gestohlen werden soll"
+
+#: client/gtk/interface.c:750
+msgid "Select the building to steal from"
+msgstr "Wähle das Gebäude, von dem gestohlen werden soll"
+
+#: client/gtk/legend.c:32
+msgid "Hill"
+msgstr "Hügelland"
+
+#: client/gtk/legend.c:33
+msgid "Field"
+msgstr "Ackerland"
+
+#: client/gtk/legend.c:34
+msgid "Mountain"
+msgstr "Gebirge"
+
+#: client/gtk/legend.c:35
+msgid "Pasture"
+msgstr "Weideland"
+
+#: client/gtk/legend.c:36
+msgid "Forest"
+msgstr "Wald"
+
+#: client/gtk/legend.c:37
+msgid "Desert"
+msgstr "Wüste"
+
+#: client/gtk/legend.c:38
+msgid "Sea"
+msgstr "Meer"
+
+#: client/gtk/legend.c:170
+msgid "<b>Terrain Yield</b>"
+msgstr "<b>Geländeerträge</b>"
+
+#: client/gtk/legend.c:202
+msgid "<b>Building Costs</b>"
+msgstr "<b>Gebäudekosten</b>"
+
+#: client/gtk/legend.c:243
+msgid "Development Card"
+msgstr "Entwicklungskarte"
+
+#: client/gtk/monopoly.c:105
+msgid "Select the resource you wish to monopolise."
+msgstr "Wähle den zu monopolisierenden Rohstoff."
+
+#: client/gtk/name.c:123
+msgid "Change player name"
+msgstr "Spielernamen ändern"
+
+#: client/gtk/name.c:146
+msgid "Player Name:"
+msgstr "Spielername:"
+
+#. Set icon preferences
+#: client/gtk/name.c:202
+msgid "Face:"
+msgstr "Gesicht:"
+
+#: client/gtk/name.c:217
+msgid "Variant:"
+msgstr "Variante:"
+
+#. Commandline option of client: name of the player
+#: client/gtk/offline.c:59
+msgid "Player name"
+msgstr "Spielername"
+
+#: client/gtk/offline.c:63
+msgid "Connect as a viewer"
+msgstr "Als Zuschauer verbinden"
+
+#: client/gtk/offline.c:66
+msgid "Meta-server Host"
+msgstr "Metaserver-Rechner"
+
+#: client/gtk/offline.c:70
+msgid "Override the language of the system"
+msgstr "Umgehe die Systemsprache"
+
+#: client/gtk/offline.c:100
+msgid "Connecting"
+msgstr "Verbinde"
+
+#. Long description in the commandline for pioneers: help
+#: client/gtk/offline.c:175
+msgid "- Play a game of Pioneers"
+msgstr "- Spiel ein Spiel Pioneers"
+
+#: client/gtk/player.c:52
+msgid "Settlements"
+msgstr "Siedlungen"
+
+#: client/gtk/player.c:53
+msgid "Cities"
+msgstr "Städte"
+
+#: client/gtk/player.c:54
+msgid "City Walls"
+msgstr "Stadtmauern"
+
+#: client/gtk/player.c:55
+msgid "Largest Army"
+msgstr "Größte Rittermacht"
+
+#: client/gtk/player.c:56
+msgid "Longest Road"
+msgstr "Längste Handelsstraße"
+
+#: client/gtk/player.c:57
+msgid "Chapels"
+msgstr "Kathedralen"
+
+#: client/gtk/player.c:58
+msgid "Pioneer Universities"
+msgstr "Pioneer Universitäten"
+
+#: client/gtk/player.c:60
+msgid "Governor's Houses"
+msgstr "Regierungsgebäude"
+
+#: client/gtk/player.c:61
+msgid "Libraries"
+msgstr "Bibliotheken"
+
+#: client/gtk/player.c:62
+msgid "Markets"
+msgstr "Marktplätze"
+
+#: client/gtk/player.c:63
+msgid "Soldiers"
+msgstr "Ritter"
+
+#: client/gtk/player.c:64
+msgid "Resource card"
+msgstr "Rohstoffkarte"
+
+#: client/gtk/player.c:64
+msgid "Resource cards"
+msgstr "Rohstoffkarten"
+
+#: client/gtk/player.c:65
+msgid "Development card"
+msgstr "Entwicklungskarte"
+
+#: client/gtk/player.c:65
+msgid "Development cards"
+msgstr "Entwicklungskarten"
+
+#. Caption for the overview of the points and card of other players
+#: client/gtk/player.c:561
+msgid "<b>Player Summary</b>"
+msgstr "<b>Spielerübersicht</b>"
+
+#: client/gtk/plenty.c:87
+msgid "Please choose one resource from the bank"
+msgstr "Bitte nimm einen Rohstoff von der Bank"
+
+#: client/gtk/plenty.c:90
+msgid "Please choose two resources from the bank"
+msgstr "Bitte nimm zwei Rohstoffe von der Bank"
+
+#: client/gtk/plenty.c:92
+msgid "The bank is empty"
+msgstr "Die Bank ist leer"
+
+#: client/gtk/quote.c:186
+#, c-format
+msgid "%s has %s, and is looking for %s"
+msgstr "%s hat %s und möchte %s"
+
+#: client/gtk/quote.c:287
+msgid "I Want"
+msgstr "Ich will"
+
+#: client/gtk/quote.c:295
+msgid "Give Them"
+msgstr "Ich gebe dafür"
+
+#: client/gtk/quote.c:311
+msgid "Delete"
+msgstr "Löschen"
+
+#: client/gtk/quote.c:335
+msgid "Reject Domestic Trade"
+msgstr "Handel ablehnen"
+
+#. Now create columns
+#. Table header: Player who trades
+#. Role of the player: player
+#: client/gtk/quote-view.c:170 server/gtk/main.c:513
+msgid "Player"
+msgstr "Spieler"
+
+#. Table header: Quote
+#: client/gtk/quote-view.c:185
+msgid "Quotes"
+msgstr "Angebote"
+
+#. trade: maritime quote: %1 resources of type %2 for
+#. * one resource of type %3
+#: client/gtk/quote-view.c:292
+#, c-format
+msgid "%d:1 %s for %s"
+msgstr "%d:1 %s für %s"
+
+#. Trade: a player has rejected trade
+#: client/gtk/quote-view.c:431
+msgid "Rejected trade"
+msgstr "Handel abgelehnt"
+
+#. Caption for overview of the resources of the player
+#: client/gtk/resource.c:113
+msgid "<b>Resources</b>"
+msgstr "<b>Rohstoffe</b>"
+
+#: client/gtk/resource.c:129
+msgid "Total"
+msgstr "Insgesamt"
+
+#. Tooltip for the amount of resources in the hand
+#: client/gtk/resource-table.c:187
+msgid "Amount in hand"
+msgstr "Karten in der Hand"
+
+#: client/gtk/resource-table.c:191
+msgid "<less"
+msgstr "<weniger"
+
+#. Tooltip for decreasing the selected amount
+#: client/gtk/resource-table.c:201
+msgid "Decrease the selected amount"
+msgstr "Die gewählte Menge verringern"
+
+#. Tooltip for the amount of resources in the bank
+#: client/gtk/resource-table.c:215
+msgid "Amount in the bank"
+msgstr "Menge in der Bank"
+
+#: client/gtk/resource-table.c:219
+msgid "more>"
+msgstr "mehr>"
+
+#. Tooltip for increasing the selected amount
+#: client/gtk/resource-table.c:231
+msgid "Increase the selected amount"
+msgstr "Die gewählte Menge erhöhen"
+
+#. Tooltip for the selected amount
+#: client/gtk/resource-table.c:248
+msgid "Selected amount"
+msgstr "Gewählte Menge"
+
+#. Tooltip for the total selected amount
+#: client/gtk/resource-table.c:293
+msgid "Total selected amount"
+msgstr "Gesamte ausgewählte Menge"
+
+#: client/gtk/resource-table.c:314
+msgid "The bank cannot be emptied"
+msgstr "Die Bank kann nicht geleert werden"
+
+#: client/gtk/settingscreen.c:74
+msgid "Yes"
+msgstr "Ja"
+
+#: client/gtk/settingscreen.c:76 client/gtk/settingscreen.c:207
+msgid "No"
+msgstr "Nein"
+
+#: client/gtk/settingscreen.c:87 client/gtk/settingscreen.c:174
+msgid "Unknown"
+msgstr "Unbekannt"
+
+#: client/gtk/settingscreen.c:121
+msgid "No game in progress..."
+msgstr "Es läuft gerade kein Spiel..."
+
+#: client/gtk/settingscreen.c:131
+msgid "<b>General Settings</b>"
+msgstr "<b>Allgemein</b>"
+
+#: client/gtk/settingscreen.c:147
+msgid "Number of players:"
+msgstr "Anzahl Spieler:"
+
+#: client/gtk/settingscreen.c:150
+msgid "Victory Point Target:"
+msgstr "Siegpunkte:"
+
+#: client/gtk/settingscreen.c:153
+msgid "Random Terrain?"
+msgstr "Zufällige Geländeverteilung?"
+
+#: client/gtk/settingscreen.c:156
+msgid "Interplayer Trading Allowed?"
+msgstr "Handel zwischen Spielern erlaubt?"
+
+#: client/gtk/settingscreen.c:160
+msgid "Trading allowed only before build/buy?"
+msgstr "Handel nur vor dem Bauen erlaubt?"
+
+#: client/gtk/settingscreen.c:163
+msgid "Amount of Each Resource:"
+msgstr "Anzahl aller Rohstoffkarten:"
+
+#: client/gtk/settingscreen.c:177
+msgid "Sevens Rule:"
+msgstr "7-Regel:"
+
+#: client/gtk/settingscreen.c:181
+msgid "Use Pirate:"
+msgstr "Pirat verwenden:"
+
+#: client/gtk/settingscreen.c:209
+msgid "Island Discovery Bonuses:"
+msgstr "Insel-Entdeckungs-Bonus:"
+
+#: client/gtk/settingscreen.c:224
+msgid "<b>Building Quotas</b>"
+msgstr "<b>Gebäudeanzahl</b>"
+
+#: client/gtk/settingscreen.c:241
+msgid "Roads:"
+msgstr "Straßen:"
+
+#: client/gtk/settingscreen.c:247
+msgid "Settlements:"
+msgstr "Siedlungen:"
+
+#: client/gtk/settingscreen.c:253
+msgid "Cities:"
+msgstr "Städte:"
+
+#: client/gtk/settingscreen.c:259
+msgid "City Walls:"
+msgstr "Stadtmauern:"
+
+#: client/gtk/settingscreen.c:265
+msgid "Ships:"
+msgstr "Schiffe:"
+
+#: client/gtk/settingscreen.c:271
+msgid "Bridges:"
+msgstr "Brücken:"
+
+#: client/gtk/settingscreen.c:283
+msgid "<b>Development Card Deck</b>"
+msgstr "<b>Entwicklungskartenstapel</b>"
+
+#: client/gtk/settingscreen.c:299
+msgid "Road Building Cards:"
+msgstr "Straßenbau-Karten:"
+
+#: client/gtk/settingscreen.c:303
+msgid "Monopoly Cards:"
+msgstr "Monopol-Karten:"
+
+#: client/gtk/settingscreen.c:307
+msgid "Year of Plenty Cards:"
+msgstr "Erfindungs-Karten:"
+
+#: client/gtk/settingscreen.c:312
+msgid "Chapel Cards:"
+msgstr "Kathedralen-Karten:"
+
+#: client/gtk/settingscreen.c:316
+msgid "Pioneer University Cards:"
+msgstr "Pioneer-Universitäts-Karten:"
+
+#: client/gtk/settingscreen.c:320
+msgid "Governor's House Cards:"
+msgstr "Regierungsgebäude-Karten:"
+
+#: client/gtk/settingscreen.c:325
+msgid "Library Cards:"
+msgstr "Bibliotheks-Karten:"
+
+#: client/gtk/settingscreen.c:329
+msgid "Market Cards:"
+msgstr "Marktplatz-Karten:"
+
+#: client/gtk/settingscreen.c:333
+msgid "Soldier Cards:"
+msgstr "Ritter-Karten:"
+
+#: client/gtk/settingscreen.c:370
+msgid "Current Game Settings"
+msgstr "Aktuelle Spieleinstellungen"
+
+#. trade: you ask for something for free
+#: client/gtk/trade.c:193
+#, c-format
+msgid "ask for %s for free"
+msgstr "möchte %s gratis"
+
+#. trade: you give something away for free
+#: client/gtk/trade.c:198
+#, c-format
+msgid "give %s for free"
+msgstr "gibt %s gratis"
+
+#. trade: you trade something for something else
+#: client/gtk/trade.c:203
+#, c-format
+msgid "give %s for %s"
+msgstr "gibt %s für %s"
+
+#. I want some resources, and give them some resources
+#: client/gtk/trade.c:230
+#, c-format
+msgid "I want %s, and give them %s"
+msgstr "Ich möchte %s, und gebe dafür %s"
+
+#. Frame title, trade: I want to trade these resources
+#: client/gtk/trade.c:427
+msgid "<b>I Want</b>"
+msgstr "<b>Ich will</b>"
+
+#. Frame title, trade: I want these resources in return
+#: client/gtk/trade.c:455
+msgid "<b>Give Them</b>"
+msgstr "<b>Ich gebe dafür</b>"
+
+#. Button text, trade: call for quotes from other players
+#: client/gtk/trade.c:484
+msgid "_Call for Quotes"
+msgstr "Angebote einholen"
+
+#. Button text: Trade page, accept selected quote
+#: client/gtk/trade.c:512
+msgid "_Accept Quote"
+msgstr "Angebot annehmen"
+
+#. Button text: Trade page, finish trading
+#: client/gtk/trade.c:518
+msgid "_Finish Trading"
+msgstr "Handel beenden"
+
+#: common/gtk/aboutbox.c:74
+msgid ""
+"Pioneers is based upon the excellent\n"
+"Settlers of Catan board game.\n"
+msgstr ""
+"Pioneers basiert auf dem exzellenten\n"
+"Brettspiel 'Die Siedler von Catan'.\n"
+
+#: common/gtk/aboutbox.c:83
+msgid "Homepage"
+msgstr "Homepage"
+
+#: common/gtk/aboutbox.c:88
+msgid "Authors"
+msgstr "Autoren"
+
+#. Tooltip for sevens rule normal
+#: common/gtk/game-rules.c:101
+msgid "All sevens move the robber or pirate"
+msgstr "Jede 7 bewegt den Räuber oder Pirat"
+
+#: common/gtk/game-rules.c:106
+msgid "In the first two turns all sevens are rerolled"
+msgstr "In den ersten beiden Runden wird jede 7 wiederholt gewürfelt."
+
+#. Tooltip for sevens rule reroll all
+#: common/gtk/game-rules.c:110
+msgid "All sevens are rerolled"
+msgstr "Jede 7 wird wiederholt gewürfelt"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize Terrain"
+msgstr "Zufällige Geländeverteilung"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize the terrain"
+msgstr "Zufällige Geländeverteilung"
+
+#: common/gtk/game-rules.c:123
+msgid "Use Pirate"
+msgstr "Pirat benutzen"
+
+#: common/gtk/game-rules.c:123
+msgid "Use the pirate to block ships"
+msgstr "Den Pirat benutzen, um Schiffe zu blockieren"
+
+#: common/gtk/game-rules.c:125
+msgid "Strict Trade"
+msgstr "Strenger Handel"
+
+#: common/gtk/game-rules.c:126
+msgid "Allow trade only before building or buying"
+msgstr "Handel nur vor dem Bauen oder Kaufen erlauben"
+
+#: common/gtk/game-rules.c:128
+msgid "Domestic Trade"
+msgstr "Binnenhandel"
+
+#: common/gtk/game-rules.c:128
+msgid "Allow trade between players"
+msgstr "Handel unter den Spielern erlauben"
+
+#. Label text for customising a game
+#: common/gtk/game-settings.c:118
+msgid "Number of Players"
+msgstr "Anzahl der Spieler"
+
+#. Tooltip for 'Number of Players'
+#: common/gtk/game-settings.c:136
+msgid "The number of players"
+msgstr "Die Anzahl der Spieler"
+
+#. Label for customising a game
+#: common/gtk/game-settings.c:139
+msgid "Victory Point Target"
+msgstr "Siegpunkte"
+
+#. Tooltip for Victory Point Target
+#: common/gtk/game-settings.c:159
+msgid "The points needed to win the game"
+msgstr "Punkte für Sieg"
+
+#. Tooltip for the check button
+#: common/gtk/game-settings.c:172
+msgid "Is it possible to win this game?"
+msgstr "Ist es möglich, dieses Spiel zu gewinnen?"
+
+#. Port indicator for a resource: trade 2 for 1
+#: common/gtk/guimap.c:750
+msgid "2:1"
+msgstr "2:1"
+
+#. Port indicator: trade 3 for 1
+#. General port indicator
+#: common/gtk/guimap.c:753 common/gtk/guimap.c:778
+msgid "3:1"
+msgstr "3:1"
+
+#. Tooltip for the list of games
+#: common/gtk/select-game.c:111
+msgid "Select a game"
+msgstr "Wähle ein Spiel"
+
+#: common/gtk/theme.c:709
+#, c-format
+msgid "bad scaling mode '%s'"
+msgstr "falscher Skaliermodus '%s'"
+
+#: common/game.c:603 common/game.c:633
+msgid "This game cannot be won."
+msgstr "Dieses Spiel kann nicht gewonnen werden."
+
+#: common/game.c:604
+msgid "There is no land."
+msgstr "Hier gibt es kein Land."
+
+#: common/game.c:638
+msgid "It is possible that this game cannot be won."
+msgstr "Es ist möglich, dass dieses Spiel unentschieden endet."
+
+#: common/game.c:643
+msgid "This game can be won by only building all settlements and cities."
+msgstr ""
+"Dieses Spiel kann nur noch durch das Bauen aller Siedlungen und Städte "
+"gewonnen werden."
+
+#: common/game.c:650
+#, c-format
+msgid ""
+"Required victory points: %d\n"
+"Points obtained by building all: %d\n"
+"Points in development cards: %d\n"
+"Longest road/largest army: %d+%d\n"
+"Maximum island discovery bonus: %d\n"
+"Total: %d"
+msgstr ""
+"Benötigte Siegpunkte: %d\n"
+"Punkte durch Gebäude: %d\n"
+"Punkte durch Entwicklungskarten: %d\n"
+"Längste Straße/Stärkste Rittermacht: %d+%d\n"
+"Größter Insel-Entdeckungs-Bonus: %d\n"
+"Gesamt: %d"
+
+#: common/log.c:54
+msgid "*ERROR* "
+msgstr "*FEHLER*"
+
+#: common/log.c:60
+msgid "Chat: "
+msgstr "Chat: "
+
+#: common/log.c:63
+msgid "Resource: "
+msgstr "Rohstoff: "
+
+#: common/log.c:66
+msgid "Build: "
+msgstr "Bauen:"
+
+#: common/log.c:69
+msgid "Dice: "
+msgstr "Würfeln:"
+
+#: common/log.c:72
+msgid "Steal: "
+msgstr "Stehlen:"
+
+#: common/log.c:75
+msgid "Trade: "
+msgstr "Handel: "
+
+#: common/log.c:78
+msgid "Development: "
+msgstr "Entwicklung: "
+
+#: common/log.c:81
+msgid "Army: "
+msgstr "Ritter:"
+
+#: common/log.c:84
+msgid "Road: "
+msgstr "Straße: "
+
+#: common/log.c:87
+msgid "*BEEP* "
+msgstr "*PIEP*"
+
+#: common/log.c:92
+msgid "Player 1: "
+msgstr "Spieler 1: "
+
+#: common/log.c:95
+msgid "Player 2: "
+msgstr "Spieler 2: "
+
+#: common/log.c:98
+msgid "Player 3: "
+msgstr "Spieler 3: "
+
+#: common/log.c:101
+msgid "Player 4: "
+msgstr "Spieler 4: "
+
+#: common/log.c:104
+msgid "Player 5: "
+msgstr "Spieler 5: "
+
+#: common/log.c:107
+msgid "Player 6: "
+msgstr "Spieler 6: "
+
+#: common/log.c:110
+msgid "Player 7: "
+msgstr "Spieler 7: "
+
+#: common/log.c:113
+msgid "Player 8: "
+msgstr "Spieler 8: "
+
+#: common/log.c:116
+msgid "Viewer: "
+msgstr "Zuschauer: "
+
+#: common/log.c:119
+msgid "** UNKNOWN MESSAGE TYPE ** "
+msgstr "** UNBEKANNTER NACHRICHTENTYP ** "
+
+#: common/network.c:281
+#, c-format
+msgid "Error checking connect status: %s\n"
+msgstr "Fehler beim Prüfen des Verbindungsstatus: %s\n"
+
+#: common/network.c:288
+#, c-format
+msgid "Error connecting to host '%s': %s\n"
+msgstr "Fehler beim Verbinden zum Rechner '%s': %s\n"
+
+#: common/network.c:314
+#, c-format
+msgid "Error writing socket: %s\n"
+msgstr "Fehler beim Schreiben auf Socket: %s\n"
+
+#: common/network.c:365
+#, c-format
+msgid "Error writing to socket: %s\n"
+msgstr "Fehler beim Schreiben auf Socket: %s\n"
+
+#: common/network.c:418
+msgid "Read buffer overflow - disconnecting\n"
+msgstr "Überlauf des Lesepuffers - Ende der Verbindung\n"
+
+#: common/network.c:428
+#, c-format
+msgid "Error reading socket: %s\n"
+msgstr "Fehler beim Lesen des Sockets: %s\n"
+
+#: common/network.c:575
+#, c-format
+msgid "Cannot resolve %s port %s: %s\n"
+msgstr "Kann %s Port %s nicht auflösen: %s\n"
+
+#: common/network.c:582
+#, c-format
+msgid "Cannot resolve %s port %s: host not found\n"
+msgstr "Kann %s Port %s nicht auflösen: Rechner unbekannt\n"
+
+#: common/network.c:597
+#, c-format
+msgid "Error creating socket: %s\n"
+msgstr "Fehler beim Anlegen eines Sockets: %s\n"
+
+#: common/network.c:605
+#, c-format
+msgid "Error setting socket close-on-exec: %s\n"
+msgstr "Fehler beim Setzen von close-on-exec beim Socket: %s\n"
+
+#: common/network.c:615 common/network.c:776
+#, c-format
+msgid "Error setting socket non-blocking: %s\n"
+msgstr "Fehler, den Socket nicht-blockierend zu machen: %s\n"
+
+#: common/network.c:640
+#, c-format
+msgid "Error connecting to %s: %s\n"
+msgstr "Fehler beim Verbinden zu %s: %s\n"
+
+#: common/network.c:735
+#, c-format
+msgid "Error creating struct addrinfo: %s"
+msgstr "Fehler beim Erzeugen einer struct addrinfo: %s"
+
+#: common/network.c:765
+#, c-format
+msgid "Error creating listening socket: %s\n"
+msgstr "Fehler beim Anlegen des annehmenden Sockets: %s\n"
+
+#: common/network.c:785
+#, c-format
+msgid "Error during listen on socket: %s\n"
+msgstr "Fehler beim Versetzen des Sockets in Annahme-Zustand: %s\n"
+
+#: common/network.c:794
+msgid "Listening not yet supported on this platform."
+msgstr "Listen-Modus wird auf dieser Plattform noch nicht unterstützt."
+
+#: common/network.c:816 common/network.c:817
+msgid "unknown"
+msgstr "unbekannt"
+
+#: common/network.c:823
+#, c-format
+msgid "Error getting peer name: %s"
+msgstr "Fehler beim Holen des Namens des Kommunikationspartners: %s"
+
+#: common/network.c:836
+#, c-format
+msgid "Error resolving address: %s"
+msgstr "Fehler beim Auflösen der Adresse: %s"
+
+#: common/network.c:850
+msgid "Net_get_peer_name not yet supported on this platform."
+msgstr "Net_get_peer_name wird auf dieser Plattform noch nicht unterstützt."
+
+#: common/network.c:865
+#, c-format
+msgid "Error accepting connection: %s"
+msgstr "Fehler beim Annehmen einer Verbindung: %s"
+
+#: common/state.c:166
+#, c-format
+msgid "Connecting to %s, port %s\n"
+msgstr "Verbinde zu %s Port %s\n"
+
+#: common/state.c:503
+msgid "State stack overflow. Stack dump sent to standard error.\n"
+msgstr "Zustandsstack-Überlauf. Stack dump an 'standard error' gesendet.\n"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:73
+msgid "_Hill"
+msgstr "_Hügelland"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:75
+msgid "_Field"
+msgstr "_Ackerland"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:77
+msgid "_Mountain"
+msgstr "_Gebirge"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:79
+msgid "_Pasture"
+msgstr "We_ideland"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:81
+msgid "F_orest"
+msgstr "Wa_ld"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:83
+msgid "_Desert"
+msgstr "Wü_ste"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:85
+msgid "_Sea"
+msgstr "_Meer"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:87
+msgid "_Gold"
+msgstr "G_old"
+
+#. Use an unique shortcut key for each resource
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:89 editor/gtk/editor.c:104
+msgid "_None"
+msgstr "_Keine"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:94
+msgid "_Brick (2:1)"
+msgstr "_Lehm (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:96
+msgid "_Grain (2:1)"
+msgstr "_Getreide (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:98
+msgid "_Ore (2:1)"
+msgstr "_Erz (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:100
+msgid "_Wool (2:1)"
+msgstr "_Wolle (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:102
+msgid "_Lumber (2:1)"
+msgstr "_Holz (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:106
+msgid "_Any (3:1)"
+msgstr "_Alles (3:1)"
+
+#. East
+#: editor/gtk/editor.c:111
+msgid "East|E"
+msgstr "O"
+
+#. North east
+#: editor/gtk/editor.c:113
+msgid "North East|NE"
+msgstr "NO"
+
+#. North west
+#: editor/gtk/editor.c:115
+msgid "North West|NW"
+msgstr "NW"
+
+#. West
+#: editor/gtk/editor.c:117
+msgid "West|W"
+msgstr "W"
+
+#. South west
+#: editor/gtk/editor.c:119
+msgid "South West|SW"
+msgstr "SW"
+
+#. South east
+#: editor/gtk/editor.c:121
+msgid "South East|SE"
+msgstr "SO"
+
+#: editor/gtk/editor.c:564
+msgid "Shuffle"
+msgstr "Mischen"
+
+#: editor/gtk/editor.c:696 server/gtk/main.c:450
+msgid "Game Parameters"
+msgstr "Spiel-Parameter"
+
+#: editor/gtk/editor.c:698 server/gtk/main.c:482
+msgid "Rules"
+msgstr "Regeln"
+
+#: editor/gtk/editor.c:699
+msgid "Resources"
+msgstr "Rohstoffe"
+
+#: editor/gtk/editor.c:700
+msgid "Buildings"
+msgstr "Gebäude"
+
+#: editor/gtk/editor.c:701
+msgid "Development Cards"
+msgstr "Entwicklungskarten"
+
+#: editor/gtk/editor.c:718
+msgid "Pioneers Editor"
+msgstr "Pioneers Editor"
+
+#: editor/gtk/editor.c:803
+#, c-format
+msgid "Failed to load '%s'"
+msgstr "Laden von '%s' fehlgeschlagen"
+
+#: editor/gtk/editor.c:843
+#, c-format
+msgid "Failed to save to '%s'"
+msgstr "Speichern nach '%s' fehlgeschlagen"
+
+#: editor/gtk/editor.c:858
+msgid "Open Game"
+msgstr "Spiel öffnen"
+
+#: editor/gtk/editor.c:884
+msgid "Save as..."
+msgstr "Speichern unter..."
+
+#: editor/gtk/editor.c:919
+msgid "Change Title"
+msgstr "Titel ändern"
+
+#: editor/gtk/editor.c:941
+msgid "New Title:"
+msgstr "Neuer Titel:"
+
+#: editor/gtk/editor.c:997
+msgid "Pioneers Game Editor"
+msgstr "Pioneers Spiel-Editior"
+
+#: editor/gtk/editor.c:1001
+msgid "_File"
+msgstr "_Datei"
+
+#: editor/gtk/editor.c:1004
+msgid "_New"
+msgstr "_Neu"
+
+#: editor/gtk/editor.c:1005
+msgid "Create a new game"
+msgstr "Neues Spiel erstellen"
+
+#: editor/gtk/editor.c:1006
+msgid "_Open..."
+msgstr "Ö_ffnen..."
+
+#: editor/gtk/editor.c:1007
+msgid "Open an existing game"
+msgstr "Existierendes Spiel öffnen"
+
+#: editor/gtk/editor.c:1008
+msgid "_Save"
+msgstr "_Speichern"
+
+#: editor/gtk/editor.c:1009
+msgid "Save game"
+msgstr "Spiel speichern"
+
+#: editor/gtk/editor.c:1010
+msgid "Save _As..."
+msgstr "Speichern _unter..."
+
+#: editor/gtk/editor.c:1012
+msgid "Save as"
+msgstr "Speichern unter"
+
+#: editor/gtk/editor.c:1013
+msgid "_Change title"
+msgstr "_Titel ändern"
+
+#: editor/gtk/editor.c:1014
+msgid "Change game title"
+msgstr "Spieltitel ändern"
+
+#: editor/gtk/editor.c:1015 server/gtk/main.c:100
+msgid "_Check Victory Point Target"
+msgstr "Zeige die Anzahl der benötigten Siegpunkte"
+
+#: editor/gtk/editor.c:1017 server/gtk/main.c:102
+msgid "Check whether the game can be won"
+msgstr "Überprüfe, ob das Spiel gewonnen werden kann"
+
+#: editor/gtk/editor.c:1019
+msgid "Quit"
+msgstr "Quit"
+
+#: editor/gtk/editor.c:1027
+msgid "_About Pioneers Editor"
+msgstr "Ü_ber Pioneers Editor"
+
+#: editor/gtk/editor.c:1028
+msgid "Information about Pioneers Editor"
+msgstr "Informationen über den Pioneers Editor"
+
+#. Long help for commandline option (editor): filename
+#: editor/gtk/editor.c:1066
+msgid "Open this file"
+msgstr "Diese Datei öffnen"
+
+#. Commandline option for editor: filename
+#: editor/gtk/editor.c:1068
+msgid "filename"
+msgstr "Dateiname"
+
+#: editor/gtk/editor.c:1100
+msgid "- Editor for games of Pioneers"
+msgstr "- Editor für Pioneers-Spiele"
+
+#: editor/gtk/editor.c:1141 server/gtk/main.c:1035
+#, c-format
+msgid "Building menus failed: %s"
+msgstr "Menüaufbau fehlgeschlagen: %s"
+
+#: editor/gtk/editor.c:1169
+msgid "Settings"
+msgstr "Einstellungen"
+
+#: editor/gtk/game-resources.c:51
+msgid "Resource Count"
+msgstr "Rohstoffe"
+
+#. Commandline meta-server: daemon
+#: meta-server/main.c:1033
+msgid "Daemonize the metaserver on start"
+msgstr "Metaserver als Daemon starten"
+
+#. Commandline meta-server: redirect
+#: meta-server/main.c:1036
+msgid "Redirect clients to another metaserver"
+msgstr "Leitet Spieler auf einen anderen Metaserver um"
+
+#. Commandline meta-server: server
+#: meta-server/main.c:1039
+msgid "Use this hostname when creating new games"
+msgstr "Diesen Host beim Erstellen neuer Spiele benutzen"
+
+#. Commandline meta-server: server argument
+#: meta-server/main.c:1041
+msgid "hostname"
+msgstr "Hostname"
+
+#. Commandline meta-server: port-range
+#: meta-server/main.c:1044
+msgid "Use this ports range when creating new games"
+msgstr "Diese Ports beim Erstellen neuer Spiele benutzen"
+
+#. Commandline meta-server: port-range argument
+#: meta-server/main.c:1046
+msgid "from-to"
+msgstr "von-bis"
+
+#. Commandline option of meta server: syslog-debug
+#: meta-server/main.c:1052
+msgid "Debug syslog messages"
+msgstr "Debugge Syslog Nachrichten"
+
+#. Long description in the commandline for server-console: help
+#: meta-server/main.c:1073
+msgid "- Meta server for Pioneers"
+msgstr "- Metaserver für Pioneers"
+
+#: meta-server/main.c:1088
+#, c-format
+msgid "metaserver protocol:"
+msgstr "Metaserver Protokoll:"
+
+#: server/gtk/main.c:105
+msgid "_About Pioneers Server"
+msgstr "Ü_ber Pioneers-Server"
+
+#: server/gtk/main.c:106
+msgid "Information about Pioneers Server"
+msgstr "Informationen über den Pioneers-Server"
+
+#: server/gtk/main.c:222
+msgid "Stop server"
+msgstr "Server stoppen"
+
+#: server/gtk/main.c:223
+msgid "Start server"
+msgstr "Server starten"
+
+#: server/gtk/main.c:225
+msgid "Stop the server"
+msgstr "Den Server anhalten"
+
+#: server/gtk/main.c:226
+msgid "Start the server"
+msgstr "Den Server starten"
+
+#: server/gtk/main.c:351
+#, c-format
+msgid "Player %s from %s entered\n"
+msgstr "Spieler %s von %s eingetreten\n"
+
+#: server/gtk/main.c:358
+#, c-format
+msgid "Player %s from %s left\n"
+msgstr "Spieler %s von %s gegangen\n"
+
+#: server/gtk/main.c:365
+#, c-format
+msgid "Player %d is now %s\n"
+msgstr "Spieler %d heißt jetzt %s.\n"
+
+#: server/gtk/main.c:554
+msgid "Game Settings"
+msgstr "Spieleinstellungen"
+
+#: server/gtk/main.c:600
+msgid "Server Parameters"
+msgstr "Server-Einstellungen"
+
+#: server/gtk/main.c:626
+msgid "The port for the game server"
+msgstr "Der Port für den Spielserver"
+
+#: server/gtk/main.c:629
+msgid "Register Server"
+msgstr "Server registrieren"
+
+#: server/gtk/main.c:637
+msgid "Register this game at the meta server"
+msgstr "Dieses Spiel beim Metaserver registrieren"
+
+#: server/gtk/main.c:654
+msgid "The address of the meta server"
+msgstr "Die Adresse des Metaservers"
+
+#: server/gtk/main.c:656
+msgid "Reported Hostname"
+msgstr "Angezeigter Hostname"
+
+#: server/gtk/main.c:671
+msgid ""
+"The public name of this computer (needed when playing behind a firewall)"
+msgstr ""
+"Öffentlicher Name dieses Computers (wird benötigt, wenn er hinter einer "
+"Firewall steht)"
+
+#: server/gtk/main.c:675
+msgid "Random Turn Order"
+msgstr "Zufällige Rundenreihenfolge"
+
+#: server/gtk/main.c:683
+msgid "Randomize turn order"
+msgstr "Rundenreihenfilge mischen"
+
+#: server/gtk/main.c:722
+msgid "Running Game"
+msgstr "Laufendes Spiel"
+
+#: server/gtk/main.c:724
+msgid "Players Connected"
+msgstr "Verbundene Spieler"
+
+#: server/gtk/main.c:758
+msgid "Shows all players and viewers connected to the server"
+msgstr "Zeigt alle Spieler und Zuschauer die zum Server verbunden sind"
+
+#: server/gtk/main.c:763
+msgid "Connected"
+msgstr "Verbunden"
+
+#: server/gtk/main.c:770
+msgid "Is the player currently connected?"
+msgstr "Ist der Spieler zur Zeit verbunden?"
+
+#: server/gtk/main.c:773
+msgid "Name"
+msgstr "Name"
+
+#: server/gtk/main.c:780
+msgid "Name of the player"
+msgstr "Name des Spielers"
+
+#: server/gtk/main.c:782
+msgid "Location"
+msgstr "Standort"
+
+#: server/gtk/main.c:789
+msgid "Host name of the player"
+msgstr "Hostname des Spielers"
+
+#: server/gtk/main.c:793
+msgid "Number"
+msgstr "Nummer"
+
+#: server/gtk/main.c:800
+msgid "Player number"
+msgstr "Spielernummer"
+
+#: server/gtk/main.c:804
+msgid "Role"
+msgstr "Rolle"
+
+#: server/gtk/main.c:808
+msgid "Player of viewer"
+msgstr "Spieler oder Zuschauer"
+
+#: server/gtk/main.c:819
+msgid "Launch Pioneers Client"
+msgstr "Pioneers-Client starten"
+
+#: server/gtk/main.c:826
+msgid "Launch the Pioneers Client"
+msgstr "Den Pioneers-Client starten"
+
+#: server/gtk/main.c:828
+msgid "Computer Players"
+msgstr "Computerspieler"
+
+#: server/gtk/main.c:837
+msgid "Enable Chat"
+msgstr "Chat aktivieren"
+
+#: server/gtk/main.c:843
+msgid "Enable chat messages"
+msgstr "Chatnachrichten aktivieren"
+
+#: server/gtk/main.c:850
+msgid "Add Computer Player"
+msgstr "Computerspieler hinzufügen"
+
+#: server/gtk/main.c:857
+msgid "Add a computer player to the game"
+msgstr "Einen Computerspieler hinzufügen"
+
+#: server/gtk/main.c:866
+msgid "Messages"
+msgstr "Nachrichten"
+
+#: server/gtk/main.c:884
+msgid "Messages from the server"
+msgstr "Nachrichten vom Server"
+
+#: server/gtk/main.c:932
+msgid "The Pioneers Game Server"
+msgstr "Der Pioneers-Spielserver"
+
+#. Wait for all players to disconnect,
+#. * then enable the UI
+#.
+#: server/gtk/main.c:940
+msgid "The game is over.\n"
+msgstr "Ende des Spiels.\n"
+
+#. Long description in the commandline for server-gtk: help
+#. Long description in the commandline for server-console: help
+#: server/gtk/main.c:994 server/main.c:174
+msgid "- Host a game of Pioneers"
+msgstr "- Einen Pioneerserver betreiben"
+
+#. Name in the titlebar of the server
+#: server/gtk/main.c:1016
+msgid "Pioneers Server"
+msgstr "Pioneers-Server"
+
+#. Commandline server-console: game-title
+#: server/main.c:75
+msgid "Game title to use"
+msgstr "Zu benutzender Spieltitel"
+
+#. Commandline server-console: file
+#: server/main.c:78
+msgid "Game file to use"
+msgstr "Zu verwendende Spieldatei"
+
+#. Commandline server-console: port
+#: server/main.c:81
+msgid "Port to listen on"
+msgstr "Port auf dem gewartet werden soll"
+
+#. Commandline server-console: players
+#: server/main.c:84
+msgid "Override number of players"
+msgstr "Überschreibe die Anzahl der Spieler"
+
+#. Commandline server-console: points
+#: server/main.c:87
+msgid "Override number of points needed to win"
+msgstr "Überschreibe die Anzahl der Siegpunkte"
+
+#. Commandline server-console: seven-rule
+#: server/main.c:90
+msgid "Override seven-rule handling"
+msgstr "Überschreibe die 7-Regel"
+
+#. Commandline server-console: terrain
+#: server/main.c:93
+msgid "Override terrain type, 0=default 1=random"
+msgstr "Überschreibe den Gelände-Typ, 0=Standard 1=Zufällig"
+
+#. Commandline server-console: computer-players
+#: server/main.c:96
+msgid "Add N computer players"
+msgstr "N Computerspieler hinzufügen"
+
+#. Commandline server-console: register
+#: server/main.c:106
+msgid "Register server with meta-server"
+msgstr "Server beim Metaserver registrieren"
+
+#. Commandline server-console: meta-server
+#: server/main.c:109
+msgid "Register at meta-server name (implies -r)"
+msgstr "Bei ausgewähltem Metaserver registrieren (impliziert -r)"
+
+#. Commandline server-console: hostname
+#: server/main.c:113
+msgid "Use this hostname when registering"
+msgstr "Diesen Hostnamen beim Registrieren benutzen"
+
+#. Commandline server-console: auto-quit
+#: server/main.c:120
+msgid "Quit after a player has won"
+msgstr "Beenden nachdem ein Spieler gewonnen hat"
+
+#. Commandline server-console: empty-timeout
+#: server/main.c:123
+msgid "Quit after N seconds with no players"
+msgstr "Nach N Sekunden ohne Spieler beenden"
+
+#. Commandline server-console: tournament
+#: server/main.c:126
+msgid "Tournament mode, computer players added after N minutes"
+msgstr "Turniermodus, nach N Minuten werden Computerspieler hinzugefügt"
+
+#. Commandline server-console: admin-port
+#: server/main.c:130
+msgid "Admin port to listen on"
+msgstr "Administrator-Port"
+
+#: server/main.c:134
+msgid "Don't start game immediately, wait for a command on admin port"
+msgstr ""
+"Das Spiel nicht sofort starten, sondern auf den Befehl auf dem Adminport "
+"hören"
+
+#: server/main.c:140
+msgid "Give players numbers according to the order they enter the game"
+msgstr "Den Spielern in der Reihenfolge der Teilnahme Nummern zuteilen"
+
+#. Commandline server-console: Short description of meta group
+#: server/main.c:180
+msgid "Meta-server Options"
+msgstr "Metaserver-Optionen"
+
+#: server/main.c:183
+msgid "Options for the meta-server"
+msgstr "Optionen für den Metaserver"
+
+#. Commandline server-console: Short description of misc group
+#: server/main.c:191
+msgid "Miscellaneous Options"
+msgstr "Diverse Optionen"
+
+#. Commandline server-console: Long description of misc group
+#: server/main.c:193
+msgid "Miscellaneous options"
+msgstr "Diverse Optionen"
+
+#: server/meta.c:193
+#, c-format
+msgid "Register with meta-server at %s, port %s\n"
+msgstr "Registriere bei Metaserver %s Port %s\n"
+
+#: server/meta.c:210
+msgid "Unregister from meta-server\n"
+msgstr "Beim Meta-Server austragen\n"
+
+#: server/player.c:130
+msgid "chat too long"
+msgstr "Chat ist zu lang"
+
+#: server/player.c:147
+msgid "name too long"
+msgstr "Name ist zu lang"
+
+#: server/player.c:179
+msgid "ignoring unknown extension"
+msgstr "ignoriere unbekannte Erweiterung"
+
+#: server/player.c:209
+msgid "Game starts, adding computer players"
+msgstr "Das Spiel beginnt, füge Computerspieler hinzu"
+
+#: server/player.c:234
+#, c-format
+msgid "The game starts in %s minutes."
+msgstr "Das Spiel beginnt in %s Minuten."
+
+#: server/player.c:235
+#, c-format
+msgid "The game starts in %s minute."
+msgstr "Das Spiel beginnt in %s Minute."
+
+#: server/player.c:280
+msgid "Sorry, game is over."
+msgstr "Das Spiel ist beendet."
+
+#: server/player.c:283
+#, c-format
+msgid "Player from %s is refused: game is over\n"
+msgstr "Spieler von %s abgelehnt: Das Spiel ist vorbei\n"
+
+#: server/player.c:331
+msgid "This game will start soon."
+msgstr "Das Spiel beginnt bald."
+
+#: server/player.c:359
+msgid "Name not changed: new name is already in use"
+msgstr "Name nicht geändert: neuer Name wird schon benutzt"
+
+#. %s is the name of the reconnecting player
+#: server/player.c:648
+#, c-format
+msgid "%s has reconnected."
+msgstr "%s hat sich neu verbunden."
+
+#: server/player.c:776
+#, c-format
+msgid "Version mismatch: %s"
+msgstr "Versionsunterschied: %s"
+
+#: server/server.c:47
+msgid "Was hanging around for too long without players... bye.\n"
+msgstr "Habe zu lange auf andere Spieler gewartet... tschüss.\n"
+
+#. Server: preparing game #.....
+#: server/server.c:219
+msgid "Preparing game"
+msgstr "Bereite Spiel vor"
+
+#: server/server.c:337
+msgid "Missing game directory\n"
+msgstr "Spielverzeichnis fehlt\n"
+
+#: server/turn.c:253
+msgid "Island Discovery Bonus"
+msgstr "Insel-Entdeckungs-Bonus"
+
+#: server/turn.c:256
+msgid "Additional Island Bonus"
+msgstr "Extra Insel-Bonus"
+
+#: server/turn.c:388
+msgid "Tried to assign resources to NULL player.\n"
+msgstr "Versuchte Ressourcen NULL Spieler zuzuteilen.\n"
+
+#~ msgid "Brick port|B"
+#~ msgstr "S"
+
+#~ msgid "Grain port|G"
+#~ msgstr "G"
+
+#~ msgid "Ore port|O"
+#~ msgstr "E"
+
+#~ msgid "Wool port|W"
+#~ msgstr "W"
+
+#~ msgid "Lumber port|L"
+#~ msgstr "H"
+
+#~ msgid "Continue with your turn."
+#~ msgstr "Fahre mit deinem Zug fort."
+
+#~ msgid "Map Terrain"
+#~ msgstr "Geländeverteilung"
+
+#~ msgid "Default map or a random map"
+#~ msgstr "Standardkarte oder Zufallskarte"
+
+#~ msgid "NOTE Expecting version %s, not %s\n"
+#~ msgstr "NOTE Erwarte Version %s, nicht %s\n"
+
+#~ msgid "Pixmap not found: %s\n"
+#~ msgstr "Pixmap nicht gefunden: %s\n"
+
+#~ msgid "Only server or port set, ignoring command line"
+#~ msgstr "Nur Server oder Port eingestellt, ignoriere Kommandozeile"
+
+#~ msgid "Could not initialize default theme."
+#~ msgstr "Konnte das Standard-Thema nicht initialisieren"
+
+#~ msgid "Theme %s not loaded due to errors."
+#~ msgstr "Thema %s nicht geladen auf Grund von Fehlern."
+
+#~ msgid "Could not find '%s' pixmap file in theme '%s'."
+#~ msgstr "Bilddatei %s (Thema %s) nicht gefunden."
+
+#~ msgid "Could not load '%s' pixmap file in theme '%s'."
+#~ msgstr "Bilddatei %s (Thema %s) konnte nicht geladen werden."
+
+#~ msgid "Could not find default pixmap file: %s"
+#~ msgstr "Standard Bilddatei %s nicht gefunden."
+
+#~ msgid "While reading %s at line %d:"
+#~ msgstr "Während des Lesens von %s in Zeile %d:"
+
+#~ msgid "variable name missing: %s"
+#~ msgstr "Variablenname fehlt: %s"
+
+#~ msgid "unknown config variable '%s'"
+#~ msgstr "Unbekannte Konfugurationsvariable '%s'"
+
+#~ msgid "'=' missing: %s"
+#~ msgstr "'=' fehlt: %s"
+
+#~ msgid "missing value"
+#~ msgstr "fehlender Wert"
+
+#~ msgid "invalid color: %s"
+#~ msgstr "unzulässige Farbe: %s"
+
+#~ msgid "unexpected rest at end of line: '%s'"
+#~ msgstr "Unerwarteter Rest am Zeilenende: '%s'"
+
+#~ msgid "No usable version of WinSock was found."
+#~ msgstr "Keine brauchbare Version von WinSock gefunden."
Added: trunk/po/es.po
===================================================================
--- trunk/po/es.po (rev 0)
+++ trunk/po/es.po 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,3283 @@
+# Pioneers - Settlers of Catan for GNOME.
+# Copyright (C) 1999-2001 Dave Cole
+# Copyright (C) 2000-2002 Andy Heroff
+# Copyright (C) 2006 Marco Antonio Giraldo <m.a.giraldo at rug.nl>
+# This file is distributed under the same license as the pioneers package.
+# Steve Langasek <vorlon at dodds.net>, 2002-2003.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Pioneers 0.10.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-07 20:43+0200\n"
+"PO-Revision-Date: 2006-08-23 15:14+0200\n"
+"Last-Translator: Marco Antonio Giraldo <m.a.giraldo at rug.nl>\n"
+"Language-Team: Spanish <debian-l10n-spanish at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Default name for the AI when the computer_names file
+#. * is not found or empty.
+#.
+#: client/ai/ai.c:74 client/ai/ai.c:90
+msgid "Computer Player"
+msgstr "Adversario electrónico"
+
+#. Commandline pioneersai: server
+#. Commandline option of client: hostname of the server
+#: client/ai/ai.c:102 client/gtk/connect.c:1462 client/gtk/offline.c:53
+msgid "Server Host"
+msgstr "Servidor"
+
+#. Commandline pioneersai: port
+#. Commandline option of client: port of the server
+#: client/ai/ai.c:105 client/gtk/connect.c:1478 client/gtk/offline.c:56
+#: server/gtk/main.c:612
+msgid "Server Port"
+msgstr "Puerto"
+
+#. Commandline pioneersai: name
+#: client/ai/ai.c:108
+msgid "Computer name (leave absent for random name)"
+msgstr "Nombre del ordenador (dejar vacÃo para nombre aleatorio)"
+
+#. Commandline pioneersai: time
+#: client/ai/ai.c:111
+msgid "Time to wait between turns (in milliseconds)"
+msgstr "Tiempo de espera entre turnos (en milisegundos)"
+
+#. Commandline pioneersai: chat-free
+#: client/ai/ai.c:114
+msgid "Stop computer player from talking"
+msgstr "Parar de hablar el adversario electrónico"
+
+#. Commandline pioneersai: algorithm
+#: client/ai/ai.c:117
+msgid "Type of computer player"
+msgstr "Tipo de adversario electrónico"
+
+#. Commandline option of ai: enable debug logging
+#. Commandline option of client: enable debug logging
+#. Commandline option of meta server: enable debug logging
+#. Commandline option of server-gtk: enable debug logging
+#. Commandline option of server: enable debug logging
+#: client/ai/ai.c:120 client/gtk/offline.c:74 meta-server/main.c:1049
+#: server/gtk/main.c:952 server/main.c:144
+msgid "Enable debug messages"
+msgstr "Activar mensajes depurados"
+
+#. Commandline option of ai: version
+#. Commandline option of client: version
+#. Commandline option of editor: version
+#. Commandline option of meta server: version
+#. Commandline option of server-gtk: version
+#. Commandline option of server-console: version
+#: client/ai/ai.c:123 client/gtk/offline.c:77 editor/gtk/editor.c:1071
+#: meta-server/main.c:1055 server/gtk/main.c:955 server/main.c:99
+msgid "Show version information"
+msgstr ""
+
+#: client/ai/ai.c:134
+msgid "- Computer player for Pioneers"
+msgstr "- Adversario electrónico de Pioneers"
+
+#: client/ai/ai.c:144 client/gtk/offline.c:186 editor/gtk/editor.c:1111
+#: meta-server/main.c:1084 server/gtk/main.c:1005 server/main.c:206
+#, c-format
+msgid "Pioneers version:"
+msgstr ""
+
+#: client/ai/ai.c:176
+#, c-format
+msgid "Type of computer player: %s\n"
+msgstr "Tiempo de adversario electrónico: %s\n"
+
+#: client/ai/ai.c:205
+msgid "The game is already full. I'm leaving."
+msgstr "El juego ya está lleno. Me voy."
+
+#: client/ai/greedy.c:941
+msgid "No settlements in stock to use for setup"
+msgstr "No hay asentamientos en reservas para usar en el montaje"
+
+#: client/ai/greedy.c:948
+msgid "There is no place to setup a settlement"
+msgstr "No hay lugar para instalar un asentamiento"
+
+#: client/ai/greedy.c:972
+msgid "No roads in stock to use for setup"
+msgstr "No hay caminos en reservas para usar en el montaje"
+
+#: client/ai/greedy.c:989
+msgid "There is no place to setup a road"
+msgstr "No hay lugar para instalar un camino"
+
+#: client/ai/greedy.c:1291
+msgid "Ok, let's go!"
+msgstr "Ok, ¡vamos!"
+
+#: client/ai/greedy.c:1292
+msgid "I'll beat you all now! ;)"
+msgstr "Ahora los venceré a todos"
+
+#: client/ai/greedy.c:1293
+msgid "Now for another try..."
+msgstr "Intentemos otra vez..."
+
+#: client/ai/greedy.c:1297
+msgid "At least I get something..."
+msgstr "Al menos obtuve algo..."
+
+#: client/ai/greedy.c:1298
+msgid "One is better than none..."
+msgstr "Es mejor que nada..."
+
+#: client/ai/greedy.c:1302
+msgid "Wow!"
+msgstr "Wow!"
+
+#: client/ai/greedy.c:1303
+msgid "Ey, I'm becoming rich ;)"
+msgstr "Ey, me estoy enriqueciendo ;)"
+
+#: client/ai/greedy.c:1304
+msgid "This is really a good year!"
+msgstr "¡Este es realmente un buen año!"
+
+#: client/ai/greedy.c:1307
+msgid "You really don't deserve that much!"
+msgstr "¡Realmente no mereces tanto!"
+
+#: client/ai/greedy.c:1308
+msgid "You don't know what to do with that many resources ;)"
+msgstr "No sabes qué hacer con tantos recursos ;)"
+
+#: client/ai/greedy.c:1309
+msgid "Ey, wait for my robber and lose all this again!"
+msgstr "¡Ey, espera a mi ladrón y pierde todo de nuevo!"
+
+#: client/ai/greedy.c:1312
+msgid "Hehe!"
+msgstr "¡Ejeje!"
+
+#: client/ai/greedy.c:1313
+msgid "Go, robber, go!"
+msgstr "¡Ve ladron, ve!"
+
+#: client/ai/greedy.c:1316
+msgid "You bastard!"
+msgstr "¡Maldito!"
+
+#: client/ai/greedy.c:1317
+msgid "Can't you move that robber somewhere else?!"
+msgstr "¿No puedes mover ese ladrón a otra parte?"
+
+#: client/ai/greedy.c:1318
+msgid "Why always me??"
+msgstr "¿Por qué siempre yo?"
+
+#: client/ai/greedy.c:1321
+msgid "Oh no!"
+msgstr "¡Oh, no!"
+
+#: client/ai/greedy.c:1322
+msgid "Grrr!"
+msgstr "¡Grr!"
+
+#: client/ai/greedy.c:1323
+msgid "Who the hell rolled that 7??"
+msgstr "¿Quién diablos tiró ese 7?"
+
+#: client/ai/greedy.c:1324
+msgid "Why always me?!?"
+msgstr "¿Por qué siempre yo?"
+
+#: client/ai/greedy.c:1327
+msgid "Say good bye to your cards... :)"
+msgstr "Dile adios a tus cartas... :)"
+
+#: client/ai/greedy.c:1328
+msgid "*evilgrin*"
+msgstr "Diablillo!!"
+
+#: client/ai/greedy.c:1329
+msgid "/me says farewell to your cards ;)"
+msgstr "/me dice adios a tus cartas ;)"
+
+#: client/ai/greedy.c:1330
+msgid "That's the price for being rich... :)"
+msgstr "Ese es el precio de ser rico... :)"
+
+#: client/ai/greedy.c:1333
+msgid "Ey! Where's that card gone?"
+msgstr "¡Ey!, ¿a donde se fue esa carta?"
+
+#: client/ai/greedy.c:1334
+msgid "Thieves! Thieves!!"
+msgstr "¡Ladrón, ladrón!"
+
+#: client/ai/greedy.c:1335
+msgid "Wait for my revenge..."
+msgstr "Espera mi revancha..."
+
+#: client/ai/greedy.c:1338
+msgid "Oh no :("
+msgstr "Oh no :("
+
+#: client/ai/greedy.c:1339
+msgid "Must this happen NOW??"
+msgstr "¿TenÃa que pasar ahora?"
+
+#: client/ai/greedy.c:1340
+msgid "Args"
+msgstr "Vaya!!"
+
+#: client/ai/greedy.c:1343
+msgid "Hehe, my soldiers rule!"
+msgstr "Je je, mis soldados mandan"
+
+#: client/ai/greedy.c:1346
+msgid "First robbing us, then grabbing the points..."
+msgstr "Primero nos robas, luego nos coges los puntos..."
+
+#: client/ai/greedy.c:1349
+msgid "See that road!"
+msgstr "¡Mira ese camino!"
+
+#: client/ai/greedy.c:1352
+msgid "Pf, you won't win with roads alone..."
+msgstr "Pff, no ganarás solo con caminos..."
+
+#: client/ai/greedy.c:1819
+msgid "Rejecting trade.\n"
+msgstr "Rechazando negocio.\n"
+
+#: client/ai/greedy.c:1911
+#, c-format
+msgid "Received error from server: %s. Quitting\n"
+msgstr "Error recibido del servidor: %s. Saliendo\n"
+
+#: client/ai/greedy.c:1921
+msgid "Yippie!"
+msgstr "Yupi!"
+
+#: client/ai/greedy.c:1923
+msgid "My congratulations"
+msgstr "Mis felicitaciones"
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:80
+msgid ""
+"Hello, welcome to the lobby. I am a simple robot. Type '/help' in the chat "
+"to see the list of commands I know."
+msgstr ""
+"Hola, bienvenido al salón. Soy un simple robot. Escriba '/help' en la sala "
+"de charla para ver la lista de comandos que conozco."
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:107
+msgid "'/help' shows this message again"
+msgstr "'/help' muestra este mensaje de nuevo"
+
+#. Translators: don't translate '/why'
+#: client/ai/lobbybot.c:110
+msgid "'/why' explains the purpose of this strange board layout"
+msgstr "'/why' explica el propósito de esta extraña presentación del tablero"
+
+#. Translators: don't translate '/news'
+#: client/ai/lobbybot.c:113
+msgid "'/news' tells the last released version"
+msgstr "'/news' dice cuál es la ultima versión que ha salido"
+
+#: client/ai/lobbybot.c:118
+msgid ""
+"This board is not intended to be a game that can be played. Instead, players "
+"can find eachother here, and decide which board they want to play. Then, one "
+"of the players will host the proposed game by starting a server, and "
+"registers it at the metaserver. The other players can subsequently "
+"disconnect from the lobby, and enter that game."
+msgstr ""
+"Este tablero no pretende ser sólo un juego que pueda ser jugado. En lugar de "
+"ello, los jugadores se pueden encontrar aquà y decidir que trablero quieren "
+"usar. Entonces, uno de los jugadores será el anfitrión del juego propuesto "
+"iniciando un servidor y registrándolo en el Meta-servidor. Los otros "
+"jugadores pueden seguidamente salir del salón y entrar al juego."
+
+#: client/ai/lobbybot.c:129
+msgid "The last released version of Pioneers is"
+msgstr "La más reciente versión de Pioneers es"
+
+#: client/ai/lobbybot.c:144
+msgid "The game is starting. I'm not needed anymore. Goodbye."
+msgstr "El juego está comenzando. No me necesitan más. Adios."
+
+#: client/common/client.c:103
+msgid "Waiting"
+msgstr "Esperando"
+
+#: client/common/client.c:105 client/common/client.c:1241
+msgid "Idle"
+msgstr "Libre"
+
+#: client/common/client.c:447
+msgid "We have been kicked out of the game.\n"
+msgstr "Hemos sido expulsados del juego.\n"
+
+#. Network status: offline
+#: client/common/client.c:450 client/common/client.c:891 client/gtk/gui.c:1340
+msgid "Offline"
+msgstr "desconectado"
+
+#: client/common/client.c:471
+#, c-format
+msgid "Error (%s): %s\n"
+msgstr "Error (%s): %s\n"
+
+#: client/common/client.c:480 client/common/client.c:491
+#, c-format
+msgid "Notice: %s\n"
+msgstr "Note: %s\n"
+
+#: client/common/client.c:607
+#, c-format
+msgid "%s does not receive any %s, because the bank is empty.\n"
+msgstr "%s no recibe %s, porque el banco está vacÃo.\n"
+
+#: client/common/client.c:620
+#, c-format
+msgid "%s only receives %s, because the bank didn't have any more.\n"
+msgstr "%s sólo recibe %s, porque el banco no tiene más.\n"
+
+#: client/common/client.c:629
+#, c-format
+msgid "%s receives %s.\n"
+msgstr "%s recibe %s.\n"
+
+#. Year of Plenty
+#: client/common/client.c:637 client/common/client.c:2586
+#, c-format
+msgid "%s takes %s.\n"
+msgstr "%s toma a %s.\n"
+
+#: client/common/client.c:642
+#, c-format
+msgid "%s spent %s.\n"
+msgstr "%s gasta %s.\n"
+
+#: client/common/client.c:648
+#, c-format
+msgid "%s is refunded %s.\n"
+msgstr "Se reembolsa %2s a %1s.\n"
+
+#: client/common/client.c:679
+#, c-format
+msgid "%s discarded %s.\n"
+msgstr "%s desecha %s.\n"
+
+#: client/common/client.c:849
+msgid "Loading"
+msgstr "Bajando"
+
+#: client/common/client.c:892
+msgid "Version mismatch"
+msgstr "Versión no coincide"
+
+#: client/common/client.c:894
+msgid "Version mismatch. Please make sure client and server are up to date.\n"
+msgstr ""
+"Versión no coincide, Por favor asegúrese de que el cliente y el servidor "
+"están actualizados.\n"
+
+#: client/common/client.c:1340
+msgid "Build two settlements, each with a connecting"
+msgstr "Contruya dos asentamientos, cada uno con una conexión"
+
+#: client/common/client.c:1343
+msgid "Build a settlement with a connecting"
+msgstr "Construya un asentamiento con una conexión"
+
+#: client/common/client.c:1346
+msgid "road"
+msgstr "camino"
+
+#: client/common/client.c:1348
+msgid "bridge"
+msgstr "puente"
+
+#: client/common/client.c:1350
+msgid "ship"
+msgstr "barco"
+
+#: client/common/client.c:1358
+msgid " or"
+msgstr " o"
+
+#: client/common/client.c:1416
+msgid "Waiting for your turn"
+msgstr "Esperando tu turno"
+
+#: client/common/client.c:1468
+msgid "Select the building to steal from."
+msgstr "Escoge el edificio que quieres robar."
+
+#: client/common/client.c:1490
+msgid "Select the ship to steal from."
+msgstr "Seleccione el barco a robar"
+
+#: client/common/client.c:1575 client/gtk/interface.c:782
+msgid "Place the robber"
+msgstr "Coloca el ladrón"
+
+#: client/common/client.c:1625
+msgid "Finish the road building action."
+msgstr "Termina la acción de construcción del camino"
+
+#: client/common/client.c:1627
+msgid "Build one road segment."
+msgstr "Construir un segmento de camino."
+
+#: client/common/client.c:1629
+msgid "Build two road segments."
+msgstr "Construyir dos trechossegmentos de camino."
+
+#: client/common/client.c:1902 client/common/client.c:1996
+msgid "It is your turn."
+msgstr "Te toca a tÃ."
+
+#: client/common/client.c:2090
+#, c-format
+msgid "Sorry, %s available.\n"
+msgstr "Lo siento, %s disponible.\n"
+
+#: client/common/client.c:2405
+msgid "The game is over."
+msgstr "Fin del juego"
+
+#: client/common/develop.c:43 editor/gtk/game-devcards.c:13
+msgid "Road Building"
+msgstr "Construcción de caminos"
+
+#: client/common/develop.c:44 client/gtk/monopoly.c:83
+#: editor/gtk/game-devcards.c:13
+msgid "Monopoly"
+msgstr "Monopolio"
+
+#: client/common/develop.c:45 client/gtk/plenty.c:59
+#: editor/gtk/game-devcards.c:13
+msgid "Year of Plenty"
+msgstr "Año de Abundancia"
+
+#: client/common/develop.c:46 client/gtk/player.c:57
+#: editor/gtk/game-devcards.c:14
+msgid "Chapel"
+msgstr "Capilla"
+
+#: client/common/develop.c:47 client/gtk/player.c:58
+#: editor/gtk/game-devcards.c:14
+msgid "Pioneer University"
+msgstr "Universidad Pionera"
+
+#: client/common/develop.c:48 client/gtk/player.c:60
+#: editor/gtk/game-devcards.c:15
+msgid "Governor's House"
+msgstr "Palacio del Gobernador"
+
+#: client/common/develop.c:49 client/gtk/player.c:61
+#: editor/gtk/game-devcards.c:15
+msgid "Library"
+msgstr "Biblioteca"
+
+#: client/common/develop.c:50 client/gtk/player.c:62
+#: editor/gtk/game-devcards.c:15
+msgid "Market"
+msgstr "Mercado"
+
+#: client/common/develop.c:51 client/gtk/player.c:63
+#: editor/gtk/game-devcards.c:16
+msgid "Soldier"
+msgstr "Soldado"
+
+#: client/common/develop.c:82
+#, c-format
+msgid "You bought the %s development card.\n"
+msgstr "Has comprado la carta de desarrollo «%s».\n"
+
+#: client/common/develop.c:88
+#, c-format
+msgid "You bought a %s development card.\n"
+msgstr "Has comprado una carta de desarrollo «%s».\n"
+
+#: client/common/develop.c:110
+#, c-format
+msgid "%s bought a development card.\n"
+msgstr "%s ha comprado una carta de desarrollo.\n"
+
+#: client/common/develop.c:129
+#, c-format
+msgid "%s played the %s development card.\n"
+msgstr "%s ha usado la carta de desarrollo «%s».\n"
+
+#: client/common/develop.c:134
+#, c-format
+msgid "%s played a %s development card.\n"
+msgstr "%s ha usado una carta de desarrollo «%s».\n"
+
+#: client/common/develop.c:147
+msgid "You have run out of road segments.\n"
+msgstr "Has gastado todos los segmentos de camino.\n"
+
+#. I get the cards!
+#.
+#: client/common/develop.c:187
+#, c-format
+msgid "You get %s from %s.\n"
+msgstr "Recibes %s de %s.\n"
+
+#. I lose the cards!
+#.
+#: client/common/develop.c:193
+#, c-format
+msgid "%s took %s from you.\n"
+msgstr "%s te quita %s.\n"
+
+#: client/common/develop.c:200
+#, c-format
+msgid "%s took %s from %s.\n"
+msgstr "%s toma %s de %s.\n"
+
+#: client/common/player.c:124 server/player.c:405
+#, c-format
+msgid "Viewer %d"
+msgstr "Visor %d"
+
+#: client/common/player.c:126
+#, c-format
+msgid "viewer %d"
+msgstr "visor %d"
+
+#: client/common/player.c:134 server/player.c:408
+#, c-format
+msgid "Player %d"
+msgstr "Jugador %d"
+
+#: client/common/player.c:136
+#, c-format
+msgid "player %d"
+msgstr "jugador %d"
+
+#: client/common/player.c:212
+#, c-format
+msgid "New viewer: %s.\n"
+msgstr "Nuevo visor: %s.\n"
+
+#: client/common/player.c:215 client/common/player.c:231
+#, c-format
+msgid "%s is now %s.\n"
+msgstr "%s es ahora %s.\n"
+
+#: client/common/player.c:228
+#, c-format
+msgid "Player %d is now %s.\n"
+msgstr "Jugador %d se llama ahora %s.\n"
+
+#: client/common/player.c:267
+#, c-format
+msgid "%s has quit\n"
+msgstr "%s ha salido\n"
+
+#: client/common/player.c:276
+msgid "There is no largest army.\n"
+msgstr "No hay un ejército más grande.\n"
+
+#: client/common/player.c:279
+#, c-format
+msgid "%s has the largest army.\n"
+msgstr "%s tiene el ejército más grande.\n"
+
+#: client/common/player.c:300
+msgid "There is no longest road.\n"
+msgstr "No hay un camino más largo.\n"
+
+#: client/common/player.c:303
+#, c-format
+msgid "%s has the longest road.\n"
+msgstr "%s tiene el camino más largo.\n"
+
+#: client/common/player.c:324
+#, c-format
+msgid "Waiting for %s."
+msgstr "Esperando a %s."
+
+#. We are not in on the action
+#. someone stole a resource from someone else
+#: client/common/player.c:352
+#, c-format
+msgid "%s stole a resource from %s.\n"
+msgstr "%s le roba una carta de recurso a %s.\n"
+
+#: client/common/player.c:362
+#, c-format
+msgid "You stole %s from %s.\n"
+msgstr "Robas %s a %s.\n"
+
+#: client/common/player.c:368
+#, c-format
+msgid "%s stole %s from you.\n"
+msgstr "%s te roba %s.\n"
+
+#: client/common/player.c:402
+#, c-format
+msgid "%s gave %s nothing!?\n"
+msgstr "¿¡%s no da nada a %s!?\n"
+
+#: client/common/player.c:408 client/common/player.c:416
+#, c-format
+msgid "%s gave %s %s for free.\n"
+msgstr "%s da %s a %s gratis.\n"
+
+#: client/common/player.c:424
+#, c-format
+msgid "%s gave %s %s in exchange for %s.\n"
+msgstr "%1s le da %3s a %2s a cambio de %4s.\n"
+
+#: client/common/player.c:455
+#, c-format
+msgid "%s exchanged %s for %s.\n"
+msgstr "%s cambia %s por %s.\n"
+
+#: client/common/player.c:475
+#, c-format
+msgid "%s built a road.\n"
+msgstr "%s construye un camino.\n"
+
+#: client/common/player.c:487
+#, c-format
+msgid "%s built a ship.\n"
+msgstr "%s construye un barco.\n"
+
+#: client/common/player.c:500
+#, c-format
+msgid "%s built a settlement.\n"
+msgstr "%s edifica un pueblo.\n"
+
+#: client/common/player.c:519
+#, c-format
+msgid "%s built a city.\n"
+msgstr "%s edifica una ciudad.\n"
+
+#: client/common/player.c:533
+#, fuzzy, c-format
+msgid "%s built a city wall.\n"
+msgstr "%s edifica una ciudad.\n"
+
+#: client/common/player.c:544
+#, c-format
+msgid "player_build_add called with BUILD_NONE for user %s\n"
+msgstr "Se llamó player_build_add con BUILD_NONE para el usuario %s\n"
+
+#: client/common/player.c:553
+#, c-format
+msgid "%s built a bridge.\n"
+msgstr "%s construye un puente.\n"
+
+#: client/common/player.c:579
+#, c-format
+msgid "%s removed a road.\n"
+msgstr "%s quita un camino.\n"
+
+#: client/common/player.c:589
+#, c-format
+msgid "%s removed a ship.\n"
+msgstr "%s quita un barco.\n"
+
+#: client/common/player.c:599
+#, c-format
+msgid "%s removed a settlement.\n"
+msgstr "%s quita un pueblo.\n"
+
+#: client/common/player.c:610
+#, c-format
+msgid "%s removed a city.\n"
+msgstr "%s quita una ciudad.\n"
+
+#: client/common/player.c:624
+#, fuzzy, c-format
+msgid "%s removed a city wall.\n"
+msgstr "%s quita una ciudad.\n"
+
+#: client/common/player.c:634
+#, c-format
+msgid "player_build_remove called with BUILD_NONE for user %s\n"
+msgstr "Se llamó player_build_remove con BUILD_NONE para el usuario %s\n"
+
+#: client/common/player.c:642
+#, c-format
+msgid "%s removed a bridge.\n"
+msgstr "%s quita un puente.\n"
+
+#: client/common/player.c:673
+#, c-format
+msgid "%s has cancelled a ship's movement.\n"
+msgstr "%s cancela un movimiento de barco.\n"
+
+#: client/common/player.c:676
+#, c-format
+msgid "%s moved a ship.\n"
+msgstr "%s mueve un barco.\n"
+
+#. tell the user that someone got something
+#: client/common/player.c:696
+#, c-format
+msgid "%s received %s.\n"
+msgstr "%s recibe %s.\n"
+
+#: client/common/player.c:714
+msgid "server asks to lose invalid point.\n"
+msgstr "El servidor pide perder punto invalido.\n"
+
+#. tell the user the point is lost
+#: client/common/player.c:720
+#, c-format
+msgid "%s lost %s.\n"
+msgstr "%s gasta %s.\n"
+
+#: client/common/player.c:743
+msgid "server asks to move invalid point.\n"
+msgstr "El servidor pide mover punto inválido.\n"
+
+#. tell the user someone (1) lost something (2) to someone else (3)
+#: client/common/player.c:750
+#, c-format
+msgid "%s lost %s to %s.\n"
+msgstr "%s pierde %s a %s.\n"
+
+#: client/common/resource.c:35
+msgid "brick"
+msgstr "ladrillo"
+
+#: client/common/resource.c:35
+msgid "Brick"
+msgstr "Ladrillo"
+
+#: client/common/resource.c:36
+msgid "grain"
+msgstr "cereales"
+
+#: client/common/resource.c:36
+msgid "Grain"
+msgstr "Cereales"
+
+#: client/common/resource.c:37
+msgid "ore"
+msgstr "minerales"
+
+#: client/common/resource.c:37
+msgid "Ore"
+msgstr "Minerales"
+
+#: client/common/resource.c:38
+msgid "wool"
+msgstr "lana"
+
+#: client/common/resource.c:38
+msgid "Wool"
+msgstr "Lana"
+
+#: client/common/resource.c:39
+msgid "lumber"
+msgstr "madera"
+
+#: client/common/resource.c:39
+msgid "Lumber"
+msgstr "Madera"
+
+#: client/common/resource.c:40
+msgid "no resource (bug)"
+msgstr "no recurso (gusano)"
+
+#: client/common/resource.c:40
+msgid "No resource (bug)"
+msgstr "No recurso (gusano)"
+
+#: client/common/resource.c:41
+msgid "any resource (bug)"
+msgstr "cualquier recurso (gusano)"
+
+#: client/common/resource.c:41
+msgid "Any resource (bug)"
+msgstr "Cualquier recurso (gusano)"
+
+#: client/common/resource.c:42
+msgid "gold"
+msgstr "oro"
+
+#: client/common/resource.c:42 client/gtk/legend.c:39
+msgid "Gold"
+msgstr "Oro"
+
+#: client/common/resource.c:47
+msgid "a brick card"
+msgstr "una carta de ladrillo"
+
+#: client/common/resource.c:47
+#, c-format
+msgid "%d brick cards"
+msgstr "%d cartas de ladrillo"
+
+#: client/common/resource.c:48
+msgid "a grain card"
+msgstr "una carta de cereales"
+
+#: client/common/resource.c:48
+#, c-format
+msgid "%d grain cards"
+msgstr "%d cartas de cereales"
+
+#: client/common/resource.c:49
+msgid "an ore card"
+msgstr "una carta de minerales"
+
+#: client/common/resource.c:49
+#, c-format
+msgid "%d ore cards"
+msgstr "%d cartas de minerales"
+
+#: client/common/resource.c:50
+msgid "a wool card"
+msgstr "una carta de lana"
+
+#: client/common/resource.c:50
+#, c-format
+msgid "%d wool cards"
+msgstr "%d cartas de lana"
+
+#: client/common/resource.c:51
+msgid "a lumber card"
+msgstr "una carta de madera"
+
+#: client/common/resource.c:51
+#, c-format
+msgid "%d lumber cards"
+msgstr "%d cartas de madera"
+
+#: client/common/resource.c:139 client/common/resource.c:225
+msgid "nothing"
+msgstr "nada"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:166
+#, c-format
+msgid "%s and %s"
+msgstr "%s y %s"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:170
+#, c-format
+msgid "%s, %s"
+msgstr "%s, %s"
+
+#: client/common/robber.c:60
+#, fuzzy, c-format
+msgid "%s has undone the robber movement.\n"
+msgstr "%s debe mover el ladrón."
+
+#: client/common/robber.c:63
+#, c-format
+msgid "%s moved the robber.\n"
+msgstr "%s mueve el ladrón.\n"
+
+#: client/common/robber.c:73
+#, fuzzy, c-format
+msgid "%s has undone the pirate movement.\n"
+msgstr "%s cancela un movimiento de barco.\n"
+
+#: client/common/robber.c:76
+#, c-format
+msgid "%s moved the pirate.\n"
+msgstr "%s mueve el pirata.\n"
+
+#: client/common/robber.c:83
+#, c-format
+msgid "%s must move the robber."
+msgstr "%s debe mover el ladrón."
+
+#: client/common/setup.c:140
+#, c-format
+msgid "Setup for %s.\n"
+msgstr "Instalación para %s.\n"
+
+#: client/common/setup.c:152
+#, c-format
+msgid "Double setup for %s.\n"
+msgstr "Doble instalación para %s.\n"
+
+#: client/common/turn.c:37
+#, c-format
+msgid "%s rolled %d.\n"
+msgstr "%s tiró %d.\n"
+
+#: client/common/turn.c:50
+#, c-format
+msgid "Begin turn %d for %s.\n"
+msgstr "Comienza turno %d para %s.\n"
+
+#: client/gtk/chat.c:71
+msgid "<b>Chat</b>"
+msgstr "<b>Charlar</b>"
+
+#: client/gtk/chat.c:231
+msgid "Beeper test.\n"
+msgstr "Prueba de pito.\n"
+
+#: client/gtk/chat.c:234
+#, c-format
+msgid "%s beeped you.\n"
+msgstr "%s te pita.\n"
+
+#: client/gtk/chat.c:238
+#, c-format
+msgid "You beeped %s.\n"
+msgstr "Has pitado a %s.\n"
+
+#: client/gtk/chat.c:244
+#, c-format
+msgid "You could not beep %s.\n"
+msgstr "No pudiste pitar a %s.\n"
+
+#: client/gtk/chat.c:288
+msgid " said: "
+msgstr " dice: "
+
+#: client/gtk/connect.c:282
+#, c-format
+msgid "Meta-server at %s, port %s"
+msgstr "Meta-servidor en %s, puerto %s"
+
+#: client/gtk/connect.c:292
+msgid "Finished.\n"
+msgstr "Terminado.\n"
+
+#: client/gtk/connect.c:309 client/gtk/connect.c:359 client/gtk/connect.c:456
+#: server/meta.c:174
+msgid "Meta-server kicked us off\n"
+msgstr "Meta-servidor nos sacó\n"
+
+#: client/gtk/connect.c:334
+msgid "Receiving game names from the meta server.\n"
+msgstr "Recibiendo nombres del juego de Meta-servidor.\n"
+
+#: client/gtk/connect.c:382
+#, c-format
+msgid "New game server requested on %s port %s\n"
+msgstr "Nuevo servidor de juego solicitado en %s puerto %s.\n"
+
+#: client/gtk/connect.c:391 server/meta.c:168
+#, c-format
+msgid "Unknown message from the metaserver: %s\n"
+msgstr "Mensaje desconocido del Meta-servidor: %s\n"
+
+#: client/gtk/connect.c:472 server/meta.c:125
+msgid "Too many meta-server redirects\n"
+msgstr "Demasiados desvÃos del meta-servidor\n"
+
+#: client/gtk/connect.c:499 server/meta.c:140
+#, c-format
+msgid "Bad redirect line: %s\n"
+msgstr "Mala linea de desvÃo: %s\n"
+
+#: client/gtk/connect.c:525
+#, c-format
+msgid "Meta server too old to create servers (version %d.%d)\n"
+msgstr "Meta-servidor muy viejo para crear servidores(versión %d.%d)\n"
+
+#. Sevens rule: normal
+#: client/gtk/connect.c:596 client/gtk/settingscreen.c:168
+#: common/gtk/game-rules.c:81
+msgid "Normal"
+msgstr "Normal"
+
+#: client/gtk/connect.c:602 client/gtk/settingscreen.c:170
+#: common/gtk/game-rules.c:88
+msgid "Reroll on 1st 2 turns"
+msgstr "Tirar de nuevo durante las dos primeras vueltas"
+
+#: client/gtk/connect.c:605 client/gtk/settingscreen.c:172
+#: common/gtk/game-rules.c:95
+msgid "Reroll all 7s"
+msgstr "Tirar de nuevo cada siete"
+
+#: client/gtk/connect.c:619
+msgid "Default"
+msgstr "Por defecto"
+
+#: client/gtk/connect.c:622
+msgid "Random"
+msgstr "Al azar"
+
+#: client/gtk/connect.c:653 server/meta.c:188
+#, c-format
+msgid "Redirected to meta-server at %s, port %s\n"
+msgstr "Desviado al Meta-servidor en %s, puerto %s\n"
+
+#: client/gtk/connect.c:656
+msgid "Receiving a list of Pioneers servers from the meta server.\n"
+msgstr "Recibiendo una lista de servidores Pioneers del Meta-servidor.\n"
+
+#: client/gtk/connect.c:713
+msgid ""
+"<b>Note</b>:\n"
+"\tThe metaserver does not send information about the games.\n"
+"\tPlease set appropriate values yourself."
+msgstr ""
+"<b>Nota</b>:\n"
+"\tThe Meta-servidor no envÃa información acerca de los juegos.\n"
+"\tPor favor ajuste los valores apropiados usted mismo."
+
+#: client/gtk/connect.c:730
+msgid "Number of AI Players"
+msgstr "Número de adversarios electrónicos"
+
+#: client/gtk/connect.c:749
+msgid "The number of AI players"
+msgstr "Número de adversarios electrónicos"
+
+#: client/gtk/connect.c:770
+msgid "Requesting new game server\n"
+msgstr "Pidiendo nuevo servidor de juego\n"
+
+#: client/gtk/connect.c:813 server/gtk/main.c:328 server/server.c:160
+#, c-format
+msgid "Error starting %s: %s"
+msgstr "Error al empezar %s: %s"
+
+#: client/gtk/connect.c:834
+msgid "Create a public game"
+msgstr "Crear un juego publico"
+
+#: client/gtk/connect.c:965 client/gtk/connect.c:1268
+msgid "Join a public game"
+msgstr "Adherir a un juego publico"
+
+#: client/gtk/connect.c:970
+msgid "_New remote game"
+msgstr "_Nuevo juego remoto"
+
+#: client/gtk/connect.c:984
+msgid "Refresh the list of games"
+msgstr "Renovar la lista de juegos"
+
+#: client/gtk/connect.c:989
+msgid "Create a new public game at the meta server"
+msgstr "Crear un nuevo juego publicoen el Meta-servidor"
+
+#: client/gtk/connect.c:994
+msgid "Don't join a public game"
+msgstr "No adherir a un juego publico"
+
+#: client/gtk/connect.c:998
+msgid "Join the selected game"
+msgstr "Adherir al juego seleccionado"
+
+#: client/gtk/connect.c:1033
+msgid "Select a game to join"
+msgstr "Seleccionar un juego para adherir"
+
+#: client/gtk/connect.c:1036
+msgid "Map Name"
+msgstr "Nombre de mapa"
+
+#: client/gtk/connect.c:1044
+msgid "Name of the game"
+msgstr "Nombre del juego"
+
+#: client/gtk/connect.c:1049
+msgid "Curr"
+msgstr "Corr."
+
+#: client/gtk/connect.c:1055
+msgid "Number of players in the game"
+msgstr "Número de jugadores en el juego"
+
+#: client/gtk/connect.c:1060
+msgid "Max"
+msgstr "Máx."
+
+#: client/gtk/connect.c:1066
+msgid "Maximum players for the game"
+msgstr "Maximo de jugadores para el juego"
+
+#: client/gtk/connect.c:1069
+msgid "Terrain"
+msgstr "Terreno"
+
+#: client/gtk/connect.c:1076
+msgid "Random of default terrain"
+msgstr "Terreno por defecto al azar"
+
+#: client/gtk/connect.c:1081
+msgid "Vic. Points"
+msgstr "Puntos de Vic."
+
+#: client/gtk/connect.c:1087
+msgid "Points needed to win"
+msgstr "Puntos necesitados para ganar"
+
+#: client/gtk/connect.c:1090 common/gtk/game-rules.c:73
+msgid "Sevens Rule"
+msgstr "Regla de los sietes"
+
+#: client/gtk/connect.c:1096
+msgid "Sevens rule"
+msgstr "Regla de los sietes"
+
+#: client/gtk/connect.c:1100
+msgid "Host"
+msgstr "Servidor"
+
+#: client/gtk/connect.c:1108
+msgid "Host of the game"
+msgstr "Servidor del juego"
+
+#: client/gtk/connect.c:1113
+msgid "Port"
+msgstr "Puerto"
+
+#: client/gtk/connect.c:1119
+msgid "Port of the the game"
+msgstr "Puerto del juego"
+
+#: client/gtk/connect.c:1122 common/gtk/aboutbox.c:77
+msgid "Version"
+msgstr "Versión"
+
+#: client/gtk/connect.c:1129
+msgid "Version of the host"
+msgstr "Versión del anfitrion"
+
+#: client/gtk/connect.c:1184 client/gtk/gui.c:215
+msgid "Start a new game"
+msgstr "Comenzar un nuevo juego"
+
+#: client/gtk/connect.c:1209
+msgid "Player Name"
+msgstr "Nombre de jugador"
+
+#: client/gtk/connect.c:1223
+msgid "Enter your name"
+msgstr "Entra tu nombre de jugador"
+
+#. Role of the player: viewer
+#: client/gtk/connect.c:1225 server/gtk/main.c:511
+msgid "Viewer"
+msgstr "Visor"
+
+#: client/gtk/connect.c:1233
+msgid "Do you want to be a viewer?"
+msgstr "¿Quiere tener un visor?"
+
+#: client/gtk/connect.c:1240 server/gtk/main.c:640
+msgid "Meta Server"
+msgstr "Meta-servidor"
+
+#: client/gtk/connect.c:1255
+msgid "Leave empty for the default meta server"
+msgstr "Dejar vacio para el Meta-servidor por defecto"
+
+#: client/gtk/connect.c:1263
+msgid "Join public game"
+msgstr "Adherir a juego publico"
+
+#: client/gtk/connect.c:1272
+msgid "Create game"
+msgstr "Crear juego"
+
+#: client/gtk/connect.c:1275
+msgid "Create a game"
+msgstr "Crear un juego"
+
+#: client/gtk/connect.c:1285
+msgid "Join private game"
+msgstr "Adherir a juego privado"
+
+#: client/gtk/connect.c:1289 client/gtk/connect.c:1434
+msgid "Join a private game"
+msgstr "Adherir a juego privado"
+
+#: client/gtk/connect.c:1475
+msgid "Name of the host of the game"
+msgstr "Nombre del anfitrion del juego"
+
+#: client/gtk/connect.c:1494
+msgid "Port of the host of the game"
+msgstr "Puerto del anfitrion del juego"
+
+#: client/gtk/connect.c:1534
+msgid "Recent games"
+msgstr "Juegos recientes"
+
+#: client/gtk/connect.c:1536
+msgid "Recent Games"
+msgstr "Juegos recientes"
+
+#: client/gtk/develop.c:129
+msgid "<b>Development Cards</b>"
+msgstr "<b>Cartas de desarrollo</b>"
+
+#: client/gtk/develop.c:160
+msgid "Play Card"
+msgstr "Carta de jeugo"
+
+#: client/gtk/discard.c:76
+msgid "Discard resources"
+msgstr "Desecha recursos"
+
+#: client/gtk/discard.c:96
+#, c-format
+msgid "You must discard %d resources"
+msgstr "Tienes que descartar %d cartas de recurso"
+
+#: client/gtk/discard.c:101
+msgid "Total discards"
+msgstr "Rechazos totales"
+
+#. Caption for list of player that must discard cards
+#: client/gtk/discard.c:226
+msgid "<b>Waiting for players to discard</b>"
+msgstr "<b>Esperando a que los jugadores descarten</b>"
+
+#: client/gtk/gameover.c:32
+msgid "Game over"
+msgstr "Fin del juego"
+
+#: client/gtk/gameover.c:49
+#, c-format
+msgid "%s has won the game with %d victory points!"
+msgstr "%s ha ganado con %d puntos!"
+
+#: client/gtk/gameover.c:52
+#, c-format
+msgid "%s has won the game with %d victory points!\n"
+msgstr "%s ha ganado con %d puntos!\n"
+
+#: client/gtk/gameover.c:58
+#, c-format
+msgid "All praise %s, Lord of the known world!"
+msgstr "Alabanzas a %s, Señor del mundo conocido!"
+
+#: client/gtk/gold.c:71
+msgid "Choose resources"
+msgstr "Elige recursos"
+
+#: client/gtk/gold.c:92
+#, c-format
+msgid "You may choose 1 resource"
+msgstr "Puedes escoger 1 recurso"
+
+#: client/gtk/gold.c:94
+#, c-format
+msgid "You may choose %d resources"
+msgstr "Puedes escoger %d recursos"
+
+#. Text for total in choose gold dialog
+#. Text for total in year of plenty dialog
+#: client/gtk/gold.c:101 client/gtk/plenty.c:98
+msgid "Total resources"
+msgstr "Recursos totales"
+
+#: client/gtk/gold.c:213
+msgid "<b>Waiting for players to choose</b>"
+msgstr "<b>Esperando a que los jugadores escojan</b>"
+
+#: client/gtk/gui.c:213 server/gtk/main.c:98
+msgid "_Game"
+msgstr "_Juego"
+
+#: client/gtk/gui.c:214
+msgid "_New game"
+msgstr "_Nuevo juego"
+
+#: client/gtk/gui.c:216
+msgid "_Leave game"
+msgstr "_Dejar juego"
+
+#: client/gtk/gui.c:217
+msgid "Leave this game"
+msgstr "Dejar este juego"
+
+#: client/gtk/gui.c:219
+msgid "_Admin"
+msgstr "_Admin"
+
+#: client/gtk/gui.c:220
+msgid "Administer Pioneers server"
+msgstr "Administrar servidor de Pioneers"
+
+#: client/gtk/gui.c:222
+msgid "_Player name"
+msgstr "Nombre de _jugador"
+
+#: client/gtk/gui.c:223
+msgid "Change your player name"
+msgstr "Cambiar tu nombre de jugador"
+
+#: client/gtk/gui.c:224
+msgid "_Legend"
+msgstr "_Leyenda"
+
+#: client/gtk/gui.c:225
+msgid "Terrain legend and building costs"
+msgstr "Leyenda de terreno y costos de construccion"
+
+#: client/gtk/gui.c:226
+msgid "_Game Settings"
+msgstr "_Ajustes de juego"
+
+#: client/gtk/gui.c:227
+msgid "Settings for the current game"
+msgstr "Ajustes del juego actual"
+
+#: client/gtk/gui.c:228
+msgid "_Dice Histogram"
+msgstr "_Histograma de los dados"
+
+#: client/gtk/gui.c:229
+msgid "Histogram of dice rolls"
+msgstr "Histograma de las tiradas"
+
+#: client/gtk/gui.c:230 editor/gtk/editor.c:1018 server/gtk/main.c:103
+msgid "_Quit"
+msgstr "_Salir"
+
+#: client/gtk/gui.c:231 server/gtk/main.c:104
+msgid "Quit the program"
+msgstr "Salir del programa"
+
+#: client/gtk/gui.c:232
+msgid "_Actions"
+msgstr "_Acciones"
+
+#: client/gtk/gui.c:233
+msgid "Roll Dice"
+msgstr "Tirar los dados"
+
+#: client/gtk/gui.c:234
+msgid "Roll the dice"
+msgstr "Tirar los dados"
+
+#. Tab page name
+#: client/gtk/gui.c:235 client/gtk/gui.c:577
+msgid "Trade"
+msgstr "Comercio"
+
+#: client/gtk/gui.c:237
+msgid "Undo"
+msgstr "Deshacer"
+
+#: client/gtk/gui.c:238 client/gtk/gui.c:239
+msgid "Finish"
+msgstr "Terminar"
+
+#: client/gtk/gui.c:240 client/gtk/legend.c:226 editor/gtk/game-buildings.c:13
+msgid "Road"
+msgstr "Camino"
+
+#: client/gtk/gui.c:241
+msgid "Build a road"
+msgstr "Construir camino"
+
+#: client/gtk/gui.c:242 client/gtk/legend.c:230 editor/gtk/game-buildings.c:13
+msgid "Ship"
+msgstr "Barco"
+
+#: client/gtk/gui.c:243
+msgid "Build a ship"
+msgstr "Construir un barco"
+
+#: client/gtk/gui.c:244
+msgid "Move Ship"
+msgstr "Quitar barco"
+
+#: client/gtk/gui.c:245
+msgid "Move a ship"
+msgstr "Quitar un barco"
+
+#: client/gtk/gui.c:246 client/gtk/legend.c:233 editor/gtk/game-buildings.c:13
+msgid "Bridge"
+msgstr "Puente"
+
+#: client/gtk/gui.c:247
+msgid "Build a bridge"
+msgstr "Construir un puente"
+
+#: client/gtk/gui.c:248 client/gtk/legend.c:235 client/gtk/player.c:52
+#: editor/gtk/game-buildings.c:13
+msgid "Settlement"
+msgstr "Asentamiento"
+
+#: client/gtk/gui.c:249
+msgid "Build a settlement"
+msgstr "Construir un asentamiento"
+
+#: client/gtk/gui.c:250 client/gtk/legend.c:236 client/gtk/player.c:53
+#: editor/gtk/game-buildings.c:14
+msgid "City"
+msgstr "Ciudad"
+
+#: client/gtk/gui.c:251
+msgid "Build a city"
+msgstr "Construir una ciudad"
+
+#: client/gtk/gui.c:252
+msgid "Develop"
+msgstr "Desarrollar"
+
+#: client/gtk/gui.c:253
+msgid "Buy a development card"
+msgstr "Comprar una carta de desarrollo"
+
+#: client/gtk/gui.c:254 client/gtk/legend.c:240 client/gtk/player.c:54
+#: editor/gtk/game-buildings.c:14
+#, fuzzy
+msgid "City Wall"
+msgstr "Ciudad"
+
+#: client/gtk/gui.c:255
+#, fuzzy
+msgid "Build a city wall"
+msgstr "Construir una ciudad"
+
+#: client/gtk/gui.c:257
+msgid "_Settings"
+msgstr "_Ajustes"
+
+#: client/gtk/gui.c:258
+msgid "Prefere_nces"
+msgstr "Prefere_ncias"
+
+#: client/gtk/gui.c:259
+msgid "Configure the application"
+msgstr "Configurar aplicacion"
+
+#: client/gtk/gui.c:261 client/gtk/gui.c:265 editor/gtk/editor.c:1002
+#: server/gtk/main.c:99
+msgid "_Help"
+msgstr "A_yuda"
+
+#: client/gtk/gui.c:262
+msgid "_About Pioneers"
+msgstr "_Acerca de Pioneers"
+
+#: client/gtk/gui.c:263
+msgid "Information about Pioneers"
+msgstr "Informacion acerca de Pioneers"
+
+#: client/gtk/gui.c:266 client/gtk/gui.c:1065
+msgid "Show the manual"
+msgstr "Mostrar el manual"
+
+#: client/gtk/gui.c:272
+msgid "_Toolbar"
+msgstr "_Barra de herramientas"
+
+#: client/gtk/gui.c:273
+msgid "Show or hide the toolbar"
+msgstr "Muestre o esconder barra de herramientas"
+
+#. Victory points target in statusbar
+#: client/gtk/gui.c:368
+#, c-format
+msgid "Points Needed to Win: %i"
+msgstr "Puntos necesarios para ganar: %i"
+
+#: client/gtk/gui.c:454
+msgid "<b>Messages</b>"
+msgstr "<b>Mensajes</b>"
+
+#. Tab page name
+#: client/gtk/gui.c:571 editor/gtk/editor.c:1165
+msgid "Map"
+msgstr "Mapa"
+
+#. Tab page name
+#: client/gtk/gui.c:585 client/gtk/quote.c:306
+msgid "Quote"
+msgstr "Presupuestos"
+
+#. Tab page name
+#: client/gtk/gui.c:593 client/gtk/legend.c:261
+msgid "Legend"
+msgstr "Leyenda"
+
+#. Tab page name, shown for the splash screen
+#: client/gtk/gui.c:603
+msgid "Welcome to Pioneers"
+msgstr "Bienvenido al Pioneers"
+
+#: client/gtk/gui.c:868
+msgid "Pioneers Preferences"
+msgstr "Preferencias de Pioneers"
+
+#. Label for changing the theme, in the preferences dialog
+#: client/gtk/gui.c:898
+msgid "Theme:"
+msgstr "Tema:"
+
+#: client/gtk/gui.c:921
+msgid "Choose one of the themes"
+msgstr "Escoger uno de los temas"
+
+#. Label for the option to show the legend
+#: client/gtk/gui.c:925
+msgid "Show legend"
+msgstr "Mostrar leyenda"
+
+#. Tooltip for the option to show the legend
+#: client/gtk/gui.c:935
+msgid "Show the legend as a page beside the map"
+msgstr "¿Mostrar la leyenda como una página junto al mapa?"
+
+#. Label for the option to display log messages in color
+#: client/gtk/gui.c:940
+msgid "Messages with color"
+msgstr "¿Usar colores en los mensajes?"
+
+#: client/gtk/gui.c:950
+msgid "Show new messages with color"
+msgstr "¿Usar colores en los mensajes nuevos?"
+
+#: client/gtk/gui.c:955
+msgid "Chat in color of player"
+msgstr "¿Charlar con el color del jugador?"
+
+#: client/gtk/gui.c:966
+msgid "Show new chat messages in the color of the player"
+msgstr "Mostrar nuevos mensajes de charla en el color del jugador"
+
+#. Label for the option to display the summary with colors
+#: client/gtk/gui.c:971
+msgid "Summary with color"
+msgstr "Resumen en color"
+
+#: client/gtk/gui.c:982
+msgid "Use colors in the player summary"
+msgstr "Usar color en el resumen del jugador"
+
+#: client/gtk/gui.c:987
+msgid "Toolbar with shortcuts"
+msgstr "Barra de herramientas con acceso directo"
+
+#: client/gtk/gui.c:997
+msgid "Show keyboard shortcuts in the toolbar"
+msgstr "Mostrar accesos directos de teclado en barra de herramientas"
+
+#: client/gtk/gui.c:1003
+msgid "Announce new players"
+msgstr "Anunciar nuevos jugadores"
+
+#: client/gtk/gui.c:1014
+msgid "Make a sound when a new player or viewer enters the game"
+msgstr "Hacer sonido cuando un nuevo jugador o visor entre al juego"
+
+#. Label for the option to use the 16:9 layout.
+#: client/gtk/gui.c:1019
+msgid "Use 16:9 layout"
+msgstr ""
+
+#: client/gtk/gui.c:1030
+msgid "Use a 16:9 friendly layout for the window"
+msgstr ""
+
+#: client/gtk/gui.c:1041
+msgid "The Pioneers Game"
+msgstr "El Juego de Pioneers"
+
+#. Initial text in status bar
+#: client/gtk/gui.c:1352
+msgid "Welcome to Pioneers!"
+msgstr "¡Bienvenido a Pioneers!"
+
+#. The name of the application
+#: client/gtk/gui.c:1463
+msgid "Pioneers"
+msgstr "Pioneers"
+
+#: client/gtk/histogram.c:252
+msgid "Dice Histogram"
+msgstr "Histograma de los dados"
+
+#: client/gtk/interface.c:92
+msgid "Ship movement canceled."
+msgstr "Movimiento de barco cancelado"
+
+#: client/gtk/interface.c:100 client/gtk/interface.c:101
+msgid "Select a new location for the ship."
+msgstr "Seleccione una nueva locacion para el barco"
+
+#: client/gtk/interface.c:740
+msgid "Select the ship to steal from"
+msgstr "Seleccione el barco a robar"
+
+#: client/gtk/interface.c:750
+msgid "Select the building to steal from"
+msgstr "Escoge el edificio que quieres robar"
+
+#: client/gtk/legend.c:32
+msgid "Hill"
+msgstr "Colina"
+
+#: client/gtk/legend.c:33
+msgid "Field"
+msgstr "Vega"
+
+#: client/gtk/legend.c:34
+msgid "Mountain"
+msgstr "Montaña"
+
+#: client/gtk/legend.c:35
+msgid "Pasture"
+msgstr "Pasto"
+
+#: client/gtk/legend.c:36
+msgid "Forest"
+msgstr "Selva"
+
+#: client/gtk/legend.c:37
+msgid "Desert"
+msgstr "Desierto"
+
+#: client/gtk/legend.c:38
+msgid "Sea"
+msgstr "Mar"
+
+#: client/gtk/legend.c:170
+msgid "<b>Terrain Yield</b>"
+msgstr "<b>Produccion de terreno</b>"
+
+#: client/gtk/legend.c:202
+msgid "<b>Building Costs</b>"
+msgstr "<b>Costes de construcción</b>"
+
+#: client/gtk/legend.c:243
+msgid "Development Card"
+msgstr "Carta de desarrollo"
+
+#: client/gtk/monopoly.c:105
+msgid "Select the resource you wish to monopolise."
+msgstr "Escoge el recurso que quieres monopolizar."
+
+#: client/gtk/name.c:123
+msgid "Change player name"
+msgstr "Cambiar tu nombre de jugador"
+
+#: client/gtk/name.c:146
+msgid "Player Name:"
+msgstr "Nombre de jugador:"
+
+#. Set icon preferences
+#: client/gtk/name.c:202
+msgid "Face:"
+msgstr ""
+
+#: client/gtk/name.c:217
+msgid "Variant:"
+msgstr ""
+
+#. Commandline option of client: name of the player
+#: client/gtk/offline.c:59
+msgid "Player name"
+msgstr "Nombre de jugador"
+
+#: client/gtk/offline.c:63
+msgid "Connect as a viewer"
+msgstr "Conectar como visor"
+
+#: client/gtk/offline.c:66
+msgid "Meta-server Host"
+msgstr "Meta-servidor del anfitrion"
+
+#: client/gtk/offline.c:70
+msgid "Override the language of the system"
+msgstr "Invalidar el lenguaje del sistema"
+
+#: client/gtk/offline.c:100
+msgid "Connecting"
+msgstr "Conectando"
+
+#. Long description in the commandline for pioneers: help
+#: client/gtk/offline.c:175
+msgid "- Play a game of Pioneers"
+msgstr "- Jugar un juego de Pioneers"
+
+#: client/gtk/player.c:52
+msgid "Settlements"
+msgstr "Asentamientos"
+
+#: client/gtk/player.c:53
+msgid "Cities"
+msgstr "Ciudades"
+
+#: client/gtk/player.c:54
+msgid "City Walls"
+msgstr ""
+
+#: client/gtk/player.c:55
+msgid "Largest Army"
+msgstr "Ejército Mayor"
+
+#: client/gtk/player.c:56
+msgid "Longest Road"
+msgstr "Camino Más Largo"
+
+#: client/gtk/player.c:57
+msgid "Chapels"
+msgstr "Capillas"
+
+#: client/gtk/player.c:58
+msgid "Pioneer Universities"
+msgstr "Universidades Pioneras"
+
+#: client/gtk/player.c:60
+msgid "Governor's Houses"
+msgstr "Palacio del Gobernador"
+
+#: client/gtk/player.c:61
+msgid "Libraries"
+msgstr "Biblioteca"
+
+#: client/gtk/player.c:62
+msgid "Markets"
+msgstr "Mercados"
+
+#: client/gtk/player.c:63
+msgid "Soldiers"
+msgstr "Soldados"
+
+#: client/gtk/player.c:64
+msgid "Resource card"
+msgstr "Carta de recurso"
+
+#: client/gtk/player.c:64
+msgid "Resource cards"
+msgstr "Cartas de recurso"
+
+#: client/gtk/player.c:65
+msgid "Development card"
+msgstr "Carta de desarrollo"
+
+#: client/gtk/player.c:65
+msgid "Development cards"
+msgstr "Cartas de desarrollo"
+
+#. Caption for the overview of the points and card of other players
+#: client/gtk/player.c:561
+msgid "<b>Player Summary</b>"
+msgstr "<b>Resumen de jugadores</b>"
+
+#: client/gtk/plenty.c:87
+msgid "Please choose one resource from the bank"
+msgstr "Por favor escoja un recurso del banco"
+
+#: client/gtk/plenty.c:90
+msgid "Please choose two resources from the bank"
+msgstr "Por favor escoja dos recursos del banco"
+
+#: client/gtk/plenty.c:92
+msgid "The bank is empty"
+msgstr "El banco esta vacio"
+
+#: client/gtk/quote.c:186
+#, c-format
+msgid "%s has %s, and is looking for %s"
+msgstr "%s tiene %s y quiere %s"
+
+#: client/gtk/quote.c:287
+msgid "I Want"
+msgstr "Quiero..."
+
+#: client/gtk/quote.c:295
+msgid "Give Them"
+msgstr "Dales..."
+
+#: client/gtk/quote.c:311
+msgid "Delete"
+msgstr "Borrar"
+
+#: client/gtk/quote.c:335
+msgid "Reject Domestic Trade"
+msgstr "Rechazar Negocio Domestico"
+
+#. Now create columns
+#. Table header: Player who trades
+#. Role of the player: player
+#: client/gtk/quote-view.c:170 server/gtk/main.c:513
+msgid "Player"
+msgstr "Jugador"
+
+#. Table header: Quote
+#: client/gtk/quote-view.c:185
+msgid "Quotes"
+msgstr "Presupuestos"
+
+#. trade: maritime quote: %1 resources of type %2 for
+#. * one resource of type %3
+#: client/gtk/quote-view.c:292
+#, c-format
+msgid "%d:1 %s for %s"
+msgstr "%d:1 %s por %s"
+
+#. Trade: a player has rejected trade
+#: client/gtk/quote-view.c:431
+msgid "Rejected trade"
+msgstr "Negocio rechazado"
+
+#. Caption for overview of the resources of the player
+#: client/gtk/resource.c:113
+msgid "<b>Resources</b>"
+msgstr "<b>Recursos</b>"
+
+#: client/gtk/resource.c:129
+msgid "Total"
+msgstr "Total"
+
+#. Tooltip for the amount of resources in the hand
+#: client/gtk/resource-table.c:187
+msgid "Amount in hand"
+msgstr "Cartas de recurso en mano"
+
+#: client/gtk/resource-table.c:191
+msgid "<less"
+msgstr "<menos"
+
+#. Tooltip for decreasing the selected amount
+#: client/gtk/resource-table.c:201
+msgid "Decrease the selected amount"
+msgstr "Reducir la cantidad seleccionada"
+
+#. Tooltip for the amount of resources in the bank
+#: client/gtk/resource-table.c:215
+msgid "Amount in the bank"
+msgstr "Cantidad en el banco"
+
+#: client/gtk/resource-table.c:219
+msgid "more>"
+msgstr "más>"
+
+#. Tooltip for increasing the selected amount
+#: client/gtk/resource-table.c:231
+msgid "Increase the selected amount"
+msgstr "Incrementar la cantidad seleccionada"
+
+#. Tooltip for the selected amount
+#: client/gtk/resource-table.c:248
+msgid "Selected amount"
+msgstr "Cantidad seleccionada"
+
+#. Tooltip for the total selected amount
+#: client/gtk/resource-table.c:293
+msgid "Total selected amount"
+msgstr "Cantidad seleccionada total"
+
+#: client/gtk/resource-table.c:314
+msgid "The bank cannot be emptied"
+msgstr "El banco no se puede vaciar"
+
+#: client/gtk/settingscreen.c:74
+msgid "Yes"
+msgstr "SÃ"
+
+#: client/gtk/settingscreen.c:76 client/gtk/settingscreen.c:207
+msgid "No"
+msgstr "No"
+
+#: client/gtk/settingscreen.c:87 client/gtk/settingscreen.c:174
+msgid "Unknown"
+msgstr "Desconocido"
+
+#: client/gtk/settingscreen.c:121
+msgid "No game in progress..."
+msgstr "No hay juego en proceso"
+
+#: client/gtk/settingscreen.c:131
+msgid "<b>General Settings</b>"
+msgstr "<b>Ajuste general</b>"
+
+#: client/gtk/settingscreen.c:147
+msgid "Number of players:"
+msgstr "Número de jugadores:"
+
+#: client/gtk/settingscreen.c:150
+msgid "Victory Point Target:"
+msgstr "Punto de victoria:"
+
+#: client/gtk/settingscreen.c:153
+msgid "Random Terrain?"
+msgstr "¿Terreno Aleatorio?"
+
+#: client/gtk/settingscreen.c:156
+msgid "Interplayer Trading Allowed?"
+msgstr "¿Se permite comercio entre los jugadores?"
+
+#: client/gtk/settingscreen.c:160
+msgid "Trading allowed only before build/buy?"
+msgstr "¿Comercio permitido solo antes de construir/comprar?"
+
+#: client/gtk/settingscreen.c:163
+msgid "Amount of Each Resource:"
+msgstr "Cantidad de cada recurso:"
+
+#: client/gtk/settingscreen.c:177
+msgid "Sevens Rule:"
+msgstr "Regla de los sietes:"
+
+#: client/gtk/settingscreen.c:181
+msgid "Use Pirate:"
+msgstr "Use Pirata:"
+
+#: client/gtk/settingscreen.c:209
+msgid "Island Discovery Bonuses:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:224
+msgid "<b>Building Quotas</b>"
+msgstr "<b>Costes de construcción</b>"
+
+#: client/gtk/settingscreen.c:241
+msgid "Roads:"
+msgstr "Caminos:"
+
+#: client/gtk/settingscreen.c:247
+msgid "Settlements:"
+msgstr "Asentamientos:"
+
+#: client/gtk/settingscreen.c:253
+msgid "Cities:"
+msgstr "Ciudades:"
+
+#: client/gtk/settingscreen.c:259
+msgid "City Walls:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:265
+msgid "Ships:"
+msgstr "Barcos:"
+
+#: client/gtk/settingscreen.c:271
+msgid "Bridges:"
+msgstr "Puentes:"
+
+#: client/gtk/settingscreen.c:283
+msgid "<b>Development Card Deck</b>"
+msgstr "<b>Cartas de desarrollo</b>"
+
+#: client/gtk/settingscreen.c:299
+msgid "Road Building Cards:"
+msgstr "Cartas de construir caminos:"
+
+#: client/gtk/settingscreen.c:303
+msgid "Monopoly Cards:"
+msgstr "Cartas de monopolio:"
+
+#: client/gtk/settingscreen.c:307
+msgid "Year of Plenty Cards:"
+msgstr "Cartas de año de abundancia:"
+
+#: client/gtk/settingscreen.c:312
+msgid "Chapel Cards:"
+msgstr "Cartas de capilla:"
+
+#: client/gtk/settingscreen.c:316
+msgid "Pioneer University Cards:"
+msgstr "Cartas Universidad de Pioneers:"
+
+#: client/gtk/settingscreen.c:320
+msgid "Governor's House Cards:"
+msgstr "Cartas Palacio del Gobernador:"
+
+#: client/gtk/settingscreen.c:325
+msgid "Library Cards:"
+msgstr "Cartas de biblioteca:"
+
+#: client/gtk/settingscreen.c:329
+msgid "Market Cards:"
+msgstr "Cartas de mercado:"
+
+#: client/gtk/settingscreen.c:333
+msgid "Soldier Cards:"
+msgstr "Cartas de soldado:"
+
+#: client/gtk/settingscreen.c:370
+msgid "Current Game Settings"
+msgstr "Ajusted de juego actual"
+
+#. trade: you ask for something for free
+#: client/gtk/trade.c:193
+#, c-format
+msgid "ask for %s for free"
+msgstr "pide %s gratis"
+
+#. trade: you give something away for free
+#: client/gtk/trade.c:198
+#, c-format
+msgid "give %s for free"
+msgstr "ofrece %s gratis"
+
+#. trade: you trade something for something else
+#: client/gtk/trade.c:203
+#, c-format
+msgid "give %s for %s"
+msgstr "ofrece %s por %s"
+
+#. I want some resources, and give them some resources
+#: client/gtk/trade.c:230
+#, c-format
+msgid "I want %s, and give them %s"
+msgstr "Quiero %s, y darles %s"
+
+#. Frame title, trade: I want to trade these resources
+#: client/gtk/trade.c:427
+msgid "<b>I Want</b>"
+msgstr "<b>Quiero...</b>"
+
+#. Frame title, trade: I want these resources in return
+#: client/gtk/trade.c:455
+msgid "<b>Give Them</b>"
+msgstr "<b>Dales...</b>"
+
+#. Button text, trade: call for quotes from other players
+#: client/gtk/trade.c:484
+msgid "_Call for Quotes"
+msgstr "Pedir presupuestos"
+
+#. Button text: Trade page, accept selected quote
+#: client/gtk/trade.c:512
+msgid "_Accept Quote"
+msgstr "_Aceptar presupuesto"
+
+#. Button text: Trade page, finish trading
+#: client/gtk/trade.c:518
+msgid "_Finish Trading"
+msgstr "Terminar negocio"
+
+#: common/gtk/aboutbox.c:74
+msgid ""
+"Pioneers is based upon the excellent\n"
+"Settlers of Catan board game.\n"
+msgstr ""
+"Pioneers está basado en el excelente\n"
+"juego de mesa 'Los fundadores de Catán'.\n"
+
+#: common/gtk/aboutbox.c:83
+msgid "Homepage"
+msgstr "Pagina principal"
+
+#: common/gtk/aboutbox.c:88
+msgid "Authors"
+msgstr "Autores"
+
+#. Tooltip for sevens rule normal
+#: common/gtk/game-rules.c:101
+msgid "All sevens move the robber or pirate"
+msgstr "Todos los 7 quitan el ladron o pirata"
+
+#: common/gtk/game-rules.c:106
+msgid "In the first two turns all sevens are rerolled"
+msgstr "En los primeros dos turnos todos los 7 se tiran de nuevo"
+
+#. Tooltip for sevens rule reroll all
+#: common/gtk/game-rules.c:110
+msgid "All sevens are rerolled"
+msgstr "Todos los 7 se tiran de nuevo"
+
+#: common/gtk/game-rules.c:121
+#, fuzzy
+msgid "Randomize Terrain"
+msgstr "¿Terreno Aleatorio?"
+
+#: common/gtk/game-rules.c:121
+#, fuzzy
+msgid "Randomize the terrain"
+msgstr "¿Terreno Aleatorio?"
+
+#: common/gtk/game-rules.c:123
+msgid "Use Pirate"
+msgstr "Use Pirata"
+
+#: common/gtk/game-rules.c:123
+msgid "Use the pirate to block ships"
+msgstr ""
+
+#: common/gtk/game-rules.c:125
+msgid "Strict Trade"
+msgstr "Negocio riguroso"
+
+#: common/gtk/game-rules.c:126
+#, fuzzy
+msgid "Allow trade only before building or buying"
+msgstr "¿Comercio permitido solo antes de construir/comprar?"
+
+#: common/gtk/game-rules.c:128
+msgid "Domestic Trade"
+msgstr "Negocio local"
+
+#: common/gtk/game-rules.c:128
+msgid "Allow trade between players"
+msgstr ""
+
+#. Label text for customising a game
+#: common/gtk/game-settings.c:118
+msgid "Number of Players"
+msgstr "Número de jugadores"
+
+#. Tooltip for 'Number of Players'
+#: common/gtk/game-settings.c:136
+msgid "The number of players"
+msgstr "Número de jugadores"
+
+#. Label for customising a game
+#: common/gtk/game-settings.c:139
+msgid "Victory Point Target"
+msgstr "Punto de victoria"
+
+#. Tooltip for Victory Point Target
+#: common/gtk/game-settings.c:159
+msgid "The points needed to win the game"
+msgstr "Puntos necesarios para ganar el juego"
+
+#. Tooltip for the check button
+#: common/gtk/game-settings.c:172
+#, fuzzy
+msgid "Is it possible to win this game?"
+msgstr "Puntos necesarios para ganar el juego"
+
+#. Port indicator for a resource: trade 2 for 1
+#: common/gtk/guimap.c:750
+msgid "2:1"
+msgstr "2:1"
+
+#. Port indicator: trade 3 for 1
+#. General port indicator
+#: common/gtk/guimap.c:753 common/gtk/guimap.c:778
+msgid "3:1"
+msgstr "3:1"
+
+#. Tooltip for the list of games
+#: common/gtk/select-game.c:111
+msgid "Select a game"
+msgstr "Seleccione un juego"
+
+#: common/gtk/theme.c:709
+#, c-format
+msgid "bad scaling mode '%s'"
+msgstr "Mal modo de escala '%s'"
+
+#: common/game.c:603 common/game.c:633
+#, fuzzy
+msgid "This game cannot be won."
+msgstr "Este juego comenzará pronto"
+
+#: common/game.c:604
+#, fuzzy
+msgid "There is no land."
+msgstr "No hay un camino más largo.\n"
+
+#: common/game.c:638
+msgid "It is possible that this game cannot be won."
+msgstr ""
+
+#: common/game.c:643
+msgid "This game can be won by only building all settlements and cities."
+msgstr ""
+
+#: common/game.c:650
+#, c-format
+msgid ""
+"Required victory points: %d\n"
+"Points obtained by building all: %d\n"
+"Points in development cards: %d\n"
+"Longest road/largest army: %d+%d\n"
+"Maximum island discovery bonus: %d\n"
+"Total: %d"
+msgstr ""
+
+#: common/log.c:54
+msgid "*ERROR* "
+msgstr "*ERROR* "
+
+#: common/log.c:60
+msgid "Chat: "
+msgstr "Charlar: "
+
+#: common/log.c:63
+msgid "Resource: "
+msgstr "Recursos: "
+
+#: common/log.c:66
+msgid "Build: "
+msgstr "Construir: "
+
+#: common/log.c:69
+msgid "Dice: "
+msgstr "Dados: "
+
+#: common/log.c:72
+msgid "Steal: "
+msgstr "Robar: "
+
+#: common/log.c:75
+msgid "Trade: "
+msgstr "Comercio: "
+
+#: common/log.c:78
+msgid "Development: "
+msgstr "Desarrollo: "
+
+#: common/log.c:81
+msgid "Army: "
+msgstr "Ejercito"
+
+#: common/log.c:84
+msgid "Road: "
+msgstr "Camino: "
+
+#: common/log.c:87
+msgid "*BEEP* "
+msgstr "*PITO* "
+
+#: common/log.c:92
+msgid "Player 1: "
+msgstr "Jugador 1: "
+
+#: common/log.c:95
+msgid "Player 2: "
+msgstr "Jugador 2: "
+
+#: common/log.c:98
+msgid "Player 3: "
+msgstr "Jugador 3: "
+
+#: common/log.c:101
+msgid "Player 4: "
+msgstr "Jugador 4: "
+
+#: common/log.c:104
+msgid "Player 5: "
+msgstr "Jugador 5: "
+
+#: common/log.c:107
+msgid "Player 6: "
+msgstr "Jugador 6: "
+
+#: common/log.c:110
+msgid "Player 7: "
+msgstr "Jugador 7: "
+
+#: common/log.c:113
+msgid "Player 8: "
+msgstr "Jugador 8: "
+
+#: common/log.c:116
+msgid "Viewer: "
+msgstr "Visor: "
+
+#: common/log.c:119
+msgid "** UNKNOWN MESSAGE TYPE ** "
+msgstr "** TIPO DE MENSAJE DESCONOCIDO ** "
+
+#: common/network.c:281
+#, c-format
+msgid "Error checking connect status: %s\n"
+msgstr "Error chequeando estado de conexion: %s\n"
+
+#: common/network.c:288
+#, c-format
+msgid "Error connecting to host '%s': %s\n"
+msgstr "Error conectando a anfitrion '%s': %s\n"
+
+#: common/network.c:314
+#, c-format
+msgid "Error writing socket: %s\n"
+msgstr "Error escribiendo conector: %s\n"
+
+#: common/network.c:365
+#, c-format
+msgid "Error writing to socket: %s\n"
+msgstr "error escribiendo conector: %s\n"
+
+#: common/network.c:418
+msgid "Read buffer overflow - disconnecting\n"
+msgstr "Leer buffer sobreflujo - desconectando\n"
+
+#: common/network.c:428
+#, c-format
+msgid "Error reading socket: %s\n"
+msgstr "Error leyendo conector: %s\n"
+
+#: common/network.c:575
+#, c-format
+msgid "Cannot resolve %s port %s: %s\n"
+msgstr "No se puede resolver %s puerto %s: %s\n"
+
+#: common/network.c:582
+#, c-format
+msgid "Cannot resolve %s port %s: host not found\n"
+msgstr "No se puede resolver %s puerto %s: anfitrion no encontrado\n"
+
+#: common/network.c:597
+#, c-format
+msgid "Error creating socket: %s\n"
+msgstr "Error creando conector: %s\n"
+
+#: common/network.c:605
+#, c-format
+msgid "Error setting socket close-on-exec: %s\n"
+msgstr "Error ajustando conector close-on-exec: %s\n"
+
+#: common/network.c:615 common/network.c:776
+#, c-format
+msgid "Error setting socket non-blocking: %s\n"
+msgstr "Error setting socket non-blocking: %s\n"
+
+#: common/network.c:640
+#, c-format
+msgid "Error connecting to %s: %s\n"
+msgstr "Error conectando a %s: %s\n"
+
+#: common/network.c:735
+#, c-format
+msgid "Error creating struct addrinfo: %s"
+msgstr "Error creando struct addrinfo: %s"
+
+#: common/network.c:765
+#, c-format
+msgid "Error creating listening socket: %s\n"
+msgstr "Error creando conector de escucha: %s\n"
+
+#: common/network.c:785
+#, c-format
+msgid "Error during listen on socket: %s\n"
+msgstr "Error durante la escucha en conector: %s\n"
+
+#: common/network.c:794
+msgid "Listening not yet supported on this platform."
+msgstr "Escucha no soportada aun en esta plataforma."
+
+#: common/network.c:816 common/network.c:817
+msgid "unknown"
+msgstr "Desconocido"
+
+#: common/network.c:823
+#, c-format
+msgid "Error getting peer name: %s"
+msgstr "Error obteniendo nombre de camarada: %s"
+
+#: common/network.c:836
+#, c-format
+msgid "Error resolving address: %s"
+msgstr "Error consiguiendo direccion: %s"
+
+#: common/network.c:850
+msgid "Net_get_peer_name not yet supported on this platform."
+msgstr "Net_get_peer_name no soportada aun en esta plataforma"
+
+#: common/network.c:865
+#, c-format
+msgid "Error accepting connection: %s"
+msgstr "Error aceptando coneccion: %s"
+
+#: common/state.c:166
+#, c-format
+msgid "Connecting to %s, port %s\n"
+msgstr "Conectando a %s, puert %s\n"
+
+#: common/state.c:503
+msgid "State stack overflow. Stack dump sent to standard error.\n"
+msgstr "State stack overflow. Stack dump sent to standard error.\n"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:73
+msgid "_Hill"
+msgstr "_Colina"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:75
+msgid "_Field"
+msgstr "_Siembra"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:77
+msgid "_Mountain"
+msgstr "_Montaña"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:79
+msgid "_Pasture"
+msgstr "_Pasto"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:81
+msgid "F_orest"
+msgstr "_Bosque"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:83
+msgid "_Desert"
+msgstr "_Desierto"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:85
+msgid "_Sea"
+msgstr "M_ar"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:87
+msgid "_Gold"
+msgstr "_Oro"
+
+#. Use an unique shortcut key for each resource
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:89 editor/gtk/editor.c:104
+msgid "_None"
+msgstr "_Ninguno"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:94
+msgid "_Brick (2:1)"
+msgstr "La_drillo (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:96
+msgid "_Grain (2:1)"
+msgstr "_Cereales (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:98
+msgid "_Ore (2:1)"
+msgstr "Mine_rales (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:100
+msgid "_Wool (2:1)"
+msgstr "_Lana (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:102
+msgid "_Lumber (2:1)"
+msgstr "_Madera (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:106
+msgid "_Any (3:1)"
+msgstr "Cualquiera (_3:1)"
+
+#. East
+#: editor/gtk/editor.c:111
+msgid "East|E"
+msgstr "E"
+
+#. North east
+#: editor/gtk/editor.c:113
+msgid "North East|NE"
+msgstr "NE"
+
+#. North west
+#: editor/gtk/editor.c:115
+msgid "North West|NW"
+msgstr "NO"
+
+#. West
+#: editor/gtk/editor.c:117
+msgid "West|W"
+msgstr "O"
+
+#. South west
+#: editor/gtk/editor.c:119
+msgid "South West|SW"
+msgstr "SO"
+
+#. South east
+#: editor/gtk/editor.c:121
+msgid "South East|SE"
+msgstr "SE"
+
+#: editor/gtk/editor.c:564
+msgid "Shuffle"
+msgstr "Desordenar"
+
+#: editor/gtk/editor.c:696 server/gtk/main.c:450
+msgid "Game Parameters"
+msgstr "Parametros de juego"
+
+#: editor/gtk/editor.c:698 server/gtk/main.c:482
+msgid "Rules"
+msgstr "Reglas"
+
+#: editor/gtk/editor.c:699
+msgid "Resources"
+msgstr "Recursos"
+
+#: editor/gtk/editor.c:700
+msgid "Buildings"
+msgstr "Construcciones"
+
+#: editor/gtk/editor.c:701
+msgid "Development Cards"
+msgstr "Carta de desarrollo"
+
+#: editor/gtk/editor.c:718
+msgid "Pioneers Editor"
+msgstr "Editos de Pioneers"
+
+#: editor/gtk/editor.c:803
+#, c-format
+msgid "Failed to load '%s'"
+msgstr "Falla al bajar '%s'"
+
+#: editor/gtk/editor.c:843
+#, c-format
+msgid "Failed to save to '%s'"
+msgstr "Falla al salvar a '%s'"
+
+#: editor/gtk/editor.c:858
+msgid "Open Game"
+msgstr "Juego abierto"
+
+#: editor/gtk/editor.c:884
+msgid "Save as..."
+msgstr "Guardar como..."
+
+#: editor/gtk/editor.c:919
+msgid "Change Title"
+msgstr "Cambiar titulo"
+
+#: editor/gtk/editor.c:941
+msgid "New Title:"
+msgstr "Nuevo titulo:"
+
+#: editor/gtk/editor.c:997
+msgid "Pioneers Game Editor"
+msgstr "Editor del juego Pioneers"
+
+#: editor/gtk/editor.c:1001
+msgid "_File"
+msgstr "_Archivo"
+
+#: editor/gtk/editor.c:1004
+msgid "_New"
+msgstr "_Nuevo"
+
+#: editor/gtk/editor.c:1005
+msgid "Create a new game"
+msgstr "Crear un nuevo juego"
+
+#: editor/gtk/editor.c:1006
+msgid "_Open..."
+msgstr "_Abrir"
+
+#: editor/gtk/editor.c:1007
+msgid "Open an existing game"
+msgstr "Abrir un juego existente"
+
+#: editor/gtk/editor.c:1008
+msgid "_Save"
+msgstr "_Grabar"
+
+#: editor/gtk/editor.c:1009
+msgid "Save game"
+msgstr "Grabar juego"
+
+#: editor/gtk/editor.c:1010
+msgid "Save _As..."
+msgstr "Grabar _como..."
+
+#: editor/gtk/editor.c:1012
+msgid "Save as"
+msgstr "Grabar como"
+
+#: editor/gtk/editor.c:1013
+msgid "_Change title"
+msgstr "Cambiar _titulo"
+
+#: editor/gtk/editor.c:1014
+msgid "Change game title"
+msgstr "Cambiar titulo del juego"
+
+#: editor/gtk/editor.c:1015 server/gtk/main.c:100
+#, fuzzy
+msgid "_Check Victory Point Target"
+msgstr "Punto de victoria"
+
+#: editor/gtk/editor.c:1017 server/gtk/main.c:102
+msgid "Check whether the game can be won"
+msgstr ""
+
+#: editor/gtk/editor.c:1019
+msgid "Quit"
+msgstr "Salir"
+
+#: editor/gtk/editor.c:1027
+msgid "_About Pioneers Editor"
+msgstr "_Acerca de Editor de Pioneers"
+
+#: editor/gtk/editor.c:1028
+msgid "Information about Pioneers Editor"
+msgstr "Informacion acerca de Editor de Pioneers"
+
+#. Long help for commandline option (editor): filename
+#: editor/gtk/editor.c:1066
+msgid "Open this file"
+msgstr "Abrir este archivo"
+
+#. Commandline option for editor: filename
+#: editor/gtk/editor.c:1068
+msgid "filename"
+msgstr "Nombre de archivo"
+
+#: editor/gtk/editor.c:1100
+msgid "- Editor for games of Pioneers"
+msgstr "- Editor para juegos de Pioneers"
+
+#: editor/gtk/editor.c:1141 server/gtk/main.c:1035
+#, c-format
+msgid "Building menus failed: %s"
+msgstr "Construcción menus fallida: %s"
+
+#: editor/gtk/editor.c:1169
+msgid "Settings"
+msgstr "Ajustes"
+
+#: editor/gtk/game-resources.c:51
+msgid "Resource Count"
+msgstr "Cuenta de Recursos"
+
+#. Commandline meta-server: daemon
+#: meta-server/main.c:1033
+msgid "Daemonize the metaserver on start"
+msgstr ""
+
+#. Commandline meta-server: redirect
+#: meta-server/main.c:1036
+msgid "Redirect clients to another metaserver"
+msgstr ""
+
+#. Commandline meta-server: server
+#: meta-server/main.c:1039
+msgid "Use this hostname when creating new games"
+msgstr ""
+
+#. Commandline meta-server: server argument
+#: meta-server/main.c:1041
+msgid "hostname"
+msgstr ""
+
+#. Commandline meta-server: port-range
+#: meta-server/main.c:1044
+msgid "Use this ports range when creating new games"
+msgstr ""
+
+#. Commandline meta-server: port-range argument
+#: meta-server/main.c:1046
+msgid "from-to"
+msgstr ""
+
+#. Commandline option of meta server: syslog-debug
+#: meta-server/main.c:1052
+msgid "Debug syslog messages"
+msgstr ""
+
+#. Long description in the commandline for server-console: help
+#: meta-server/main.c:1073
+msgid "- Meta server for Pioneers"
+msgstr ""
+
+#: meta-server/main.c:1088
+#, c-format
+msgid "metaserver protocol:"
+msgstr ""
+
+#: server/gtk/main.c:105
+msgid "_About Pioneers Server"
+msgstr "_Acerca del Servidor Pioneers"
+
+#: server/gtk/main.c:106
+msgid "Information about Pioneers Server"
+msgstr "Información del Servidor Pioneers"
+
+#: server/gtk/main.c:222
+msgid "Stop server"
+msgstr "Parar servidor"
+
+#: server/gtk/main.c:223
+msgid "Start server"
+msgstr "Comience el servidor"
+
+#: server/gtk/main.c:225
+msgid "Stop the server"
+msgstr "Parar el servidor"
+
+#: server/gtk/main.c:226
+msgid "Start the server"
+msgstr "Comience el servidor"
+
+#: server/gtk/main.c:351
+#, c-format
+msgid "Player %s from %s entered\n"
+msgstr "Jugador %s de %s ha entrado\n"
+
+#: server/gtk/main.c:358
+#, c-format
+msgid "Player %s from %s left\n"
+msgstr "Jugador %s de %s se ha ido\n"
+
+#: server/gtk/main.c:365
+#, c-format
+msgid "Player %d is now %s\n"
+msgstr "Jugador %d es ahora %s\n"
+
+#: server/gtk/main.c:554
+msgid "Game Settings"
+msgstr "Ajuste del juego"
+
+#: server/gtk/main.c:600
+msgid "Server Parameters"
+msgstr "Parámetros del servidor"
+
+#: server/gtk/main.c:626
+msgid "The port for the game server"
+msgstr "El puerto para el servidor el juego"
+
+#: server/gtk/main.c:629
+msgid "Register Server"
+msgstr "Hacer incribirse el servidor"
+
+#: server/gtk/main.c:637
+msgid "Register this game at the meta server"
+msgstr "Registrar este juego en el Meta-servidor"
+
+#: server/gtk/main.c:654
+msgid "The address of the meta server"
+msgstr "La dirección de un metaservidor"
+
+#: server/gtk/main.c:656
+msgid "Reported Hostname"
+msgstr "Nombre de Anfitrión Reportado"
+
+#: server/gtk/main.c:671
+msgid ""
+"The public name of this computer (needed when playing behind a firewall)"
+msgstr ""
+"El nombre público de este computador (necesario cuando se juega a través de "
+"un firewall)"
+
+#: server/gtk/main.c:675
+msgid "Random Turn Order"
+msgstr "Orden de turnos aleatorio"
+
+#: server/gtk/main.c:683
+msgid "Randomize turn order"
+msgstr "Desordenar orden de turnos"
+
+#: server/gtk/main.c:722
+msgid "Running Game"
+msgstr "Juego actual"
+
+#: server/gtk/main.c:724
+msgid "Players Connected"
+msgstr "Jugadores conectados"
+
+#: server/gtk/main.c:758
+msgid "Shows all players and viewers connected to the server"
+msgstr "Mostrar todos los jugadores y visores conectados al servidor"
+
+#: server/gtk/main.c:763
+msgid "Connected"
+msgstr "Conectado"
+
+#: server/gtk/main.c:770
+msgid "Is the player currently connected?"
+msgstr "¿Está el jugador actualmente conectado?"
+
+#: server/gtk/main.c:773
+msgid "Name"
+msgstr "Nombre"
+
+#: server/gtk/main.c:780
+msgid "Name of the player"
+msgstr "Nombre del jugador"
+
+#: server/gtk/main.c:782
+msgid "Location"
+msgstr "Sitio"
+
+#: server/gtk/main.c:789
+msgid "Host name of the player"
+msgstr "Nombre del jugador anfitrión"
+
+#: server/gtk/main.c:793
+msgid "Number"
+msgstr "Número"
+
+#: server/gtk/main.c:800
+msgid "Player number"
+msgstr "Número del jugador"
+
+#: server/gtk/main.c:804
+msgid "Role"
+msgstr "Función"
+
+#: server/gtk/main.c:808
+msgid "Player of viewer"
+msgstr "Jugador de visor"
+
+#: server/gtk/main.c:819
+#, fuzzy
+msgid "Launch Pioneers Client"
+msgstr "El Juego de Pioneers"
+
+#: server/gtk/main.c:826
+#, fuzzy
+msgid "Launch the Pioneers Client"
+msgstr "El Juego de Pioneers"
+
+#: server/gtk/main.c:828
+msgid "Computer Players"
+msgstr "Adversario electrónico"
+
+#: server/gtk/main.c:837
+msgid "Enable Chat"
+msgstr "Habilitar charla"
+
+#: server/gtk/main.c:843
+msgid "Enable chat messages"
+msgstr "Habilitar mensajes de charla"
+
+#: server/gtk/main.c:850
+msgid "Add Computer Player"
+msgstr "Añadir un adversario electrónico"
+
+#: server/gtk/main.c:857
+msgid "Add a computer player to the game"
+msgstr "Añadir un adversario electrónico"
+
+#: server/gtk/main.c:866
+msgid "Messages"
+msgstr "Mensajes"
+
+#: server/gtk/main.c:884
+msgid "Messages from the server"
+msgstr "Mensaje del servidor"
+
+#: server/gtk/main.c:932
+msgid "The Pioneers Game Server"
+msgstr "El servidor del Juego Pionners"
+
+#. Wait for all players to disconnect,
+#. * then enable the UI
+#.
+#: server/gtk/main.c:940
+msgid "The game is over.\n"
+msgstr "El juego ha terminado.\n"
+
+#. Long description in the commandline for server-gtk: help
+#. Long description in the commandline for server-console: help
+#: server/gtk/main.c:994 server/main.c:174
+msgid "- Host a game of Pioneers"
+msgstr "- Organice un juego de Pioneers"
+
+#. Name in the titlebar of the server
+#: server/gtk/main.c:1016
+msgid "Pioneers Server"
+msgstr "Servidor de Pioneers"
+
+#. Commandline server-console: game-title
+#: server/main.c:75
+msgid "Game title to use"
+msgstr "Titulo de juego para usar"
+
+#. Commandline server-console: file
+#: server/main.c:78
+msgid "Game file to use"
+msgstr "Archivo de juego para usar"
+
+#. Commandline server-console: port
+#: server/main.c:81
+msgid "Port to listen on"
+msgstr "Puerto para escuchar"
+
+#. Commandline server-console: players
+#: server/main.c:84
+msgid "Override number of players"
+msgstr "Invalidar número de adversarios"
+
+#. Commandline server-console: points
+#: server/main.c:87
+msgid "Override number of points needed to win"
+msgstr "Invalidar número de puntos necesarios para ganar"
+
+#. Commandline server-console: seven-rule
+#: server/main.c:90
+msgid "Override seven-rule handling"
+msgstr "Invalidar regla del 7"
+
+#. Commandline server-console: terrain
+#: server/main.c:93
+msgid "Override terrain type, 0=default 1=random"
+msgstr "Invalidar tipo de terreno, 0=Omisión 1=aleatorio"
+
+#. Commandline server-console: computer-players
+#: server/main.c:96
+msgid "Add N computer players"
+msgstr "Añadir N adversarios electrónicos"
+
+#. Commandline server-console: register
+#: server/main.c:106
+msgid "Register server with meta-server"
+msgstr "Hacer incribirse el servidor con el Meta-servidor"
+
+#. Commandline server-console: meta-server
+#: server/main.c:109
+msgid "Register at meta-server name (implies -r)"
+msgstr "Registro en nombre de Meta-servidor (supone -r)"
+
+#. Commandline server-console: hostname
+#: server/main.c:113
+msgid "Use this hostname when registering"
+msgstr "Usar este nombre de huesped cuando se registre"
+
+#. Commandline server-console: auto-quit
+#: server/main.c:120
+msgid "Quit after a player has won"
+msgstr "Salir luego de que un jugador ha ganado"
+
+#. Commandline server-console: empty-timeout
+#: server/main.c:123
+msgid "Quit after N seconds with no players"
+msgstr "Salir luego de N segundos sin jugadores"
+
+#. Commandline server-console: tournament
+#: server/main.c:126
+msgid "Tournament mode, computer players added after N minutes"
+msgstr "Modo de torneo, adversarios electrónicos agregados luego de N minutos"
+
+#. Commandline server-console: admin-port
+#: server/main.c:130
+msgid "Admin port to listen on"
+msgstr "Puerto Admin para escucha"
+
+#: server/main.c:134
+msgid "Don't start game immediately, wait for a command on admin port"
+msgstr ""
+"No comience el juego inmediatamente, espere un comando del puerto "
+"administrador"
+
+#: server/main.c:140
+msgid "Give players numbers according to the order they enter the game"
+msgstr "Dar números de jugadores de acuerdo al orden en que entren al juego"
+
+#. Commandline server-console: Short description of meta group
+#: server/main.c:180
+msgid "Meta-server Options"
+msgstr "Opciones de Meta-servidor"
+
+#: server/main.c:183
+msgid "Options for the meta-server"
+msgstr "Opciones para el Meta-servidor"
+
+#. Commandline server-console: Short description of misc group
+#: server/main.c:191
+msgid "Miscellaneous Options"
+msgstr "Opciones variadas"
+
+#. Commandline server-console: Long description of misc group
+#: server/main.c:193
+msgid "Miscellaneous options"
+msgstr "Opciones variadas"
+
+#: server/meta.c:193
+#, c-format
+msgid "Register with meta-server at %s, port %s\n"
+msgstr "Registro con Meta-servidor en %s, puerto %s\n"
+
+#: server/meta.c:210
+msgid "Unregister from meta-server\n"
+msgstr "Registro del Meta-servidor\n"
+
+#: server/player.c:130
+msgid "chat too long"
+msgstr "Charla demasiado larga"
+
+#: server/player.c:147
+msgid "name too long"
+msgstr "Nombre demasiado largo"
+
+#: server/player.c:179
+msgid "ignoring unknown extension"
+msgstr "ignorar extension desconocida"
+
+#: server/player.c:209
+msgid "Game starts, adding computer players"
+msgstr "El juego comienza, añadir un adversario electrónico"
+
+#: server/player.c:234
+#, c-format
+msgid "The game starts in %s minutes."
+msgstr "El juego comienza en %s minutos."
+
+#: server/player.c:235
+#, c-format
+msgid "The game starts in %s minute."
+msgstr "El juego comienza en %s minutos."
+
+#: server/player.c:280
+msgid "Sorry, game is over."
+msgstr "El juego ha terminado."
+
+#: server/player.c:283
+#, c-format
+msgid "Player from %s is refused: game is over\n"
+msgstr "Jugador de %s rechazado: fin del juego\n"
+
+#: server/player.c:331
+msgid "This game will start soon."
+msgstr "Este juego comenzará pronto"
+
+#: server/player.c:359
+msgid "Name not changed: new name is already in use"
+msgstr "Nombre no ha cambiado: nuevo nombre está ya en uso"
+
+#. %s is the name of the reconnecting player
+#: server/player.c:648
+#, c-format
+msgid "%s has reconnected."
+msgstr "%s se ha reconectado."
+
+#: server/player.c:776
+#, c-format
+msgid "Version mismatch: %s"
+msgstr "Versión no coincide: %s"
+
+#: server/server.c:47
+msgid "Was hanging around for too long without players... bye.\n"
+msgstr ""
+
+#. Server: preparing game #.....
+#: server/server.c:219
+msgid "Preparing game"
+msgstr "Preparando juego"
+
+#: server/server.c:337
+msgid "Missing game directory\n"
+msgstr "Directorio de juego perdido\n"
+
+#: server/turn.c:253
+msgid "Island Discovery Bonus"
+msgstr ""
+
+#: server/turn.c:256
+msgid "Additional Island Bonus"
+msgstr ""
+
+#: server/turn.c:388
+msgid "Tried to assign resources to NULL player.\n"
+msgstr "Tried to assign resources to NULL player.\n"
+
+#~ msgid "Brick port|B"
+#~ msgstr "Ld"
+
+#~ msgid "Grain port|G"
+#~ msgstr "C"
+
+#~ msgid "Ore port|O"
+#~ msgstr "Mi"
+
+#~ msgid "Wool port|W"
+#~ msgstr "Ln"
+
+#~ msgid "Lumber port|L"
+#~ msgstr "Ma"
+
+#~ msgid "Continue with your turn."
+#~ msgstr "Sigue con tu turno."
+
+#~ msgid "Map Terrain"
+#~ msgstr "Mapa de terreno"
+
+#~ msgid "Default map or a random map"
+#~ msgstr "Mapa por defecto o aleatorio"
+
+#~ msgid "No hay resource (bug)"
+#~ msgstr "No hay recurso (gusano)"
+
+#~ msgid "%s has requested a connection check"
+#~ msgstr "%s ha solicitado un chequeo de la conexión"
+
+#~ msgid "The metaserver has rejected the reported hostname. Try %s instead"
+#~ msgstr ""
+#~ "El Meta-servidor ha rechazado el nombre de huesped reportado. Intente %s"
+
+#~ msgid "brick + lumber"
+#~ msgstr "ladrillo y madera"
+
+#~ msgid "wool + lumber"
+#~ msgstr "lana y madera"
+
+#~ msgid "brick + wool + lumber"
+#~ msgstr "ladrillo, lana y madera"
+
+#~ msgid "brick + grain + wool + lumber"
+#~ msgstr "ladrillo, cereal, lana y madera"
+
+#~ msgid "2 grain + 3 ore"
+#~ msgstr "dos cereales y tres minerales"
+
+#~ msgid "grain + ore + wool"
+#~ msgstr "cereales, minerales y lana"
+
+#~ msgid ""
+#~ "Trade\n"
+#~ "(F2)"
+#~ msgstr ""
+#~ "Comercio\n"
+#~ "(F2)"
+
+#~ msgid ""
+#~ "Finish\n"
+#~ "(F4)"
+#~ msgstr ""
+#~ "Terminar\n"
+#~ "(F4)"
+
+#~ msgid ""
+#~ "Road\n"
+#~ "(F5)"
+#~ msgstr ""
+#~ "Camino\n"
+#~ "(F5)"
+
+#~ msgid ""
+#~ "Ship\n"
+#~ "(F6)"
+#~ msgstr ""
+#~ "Barco\n"
+#~ "(F6)"
+
+#~ msgid ""
+#~ "Bridge\n"
+#~ "(F8)"
+#~ msgstr ""
+#~ "Puente\n"
+#~ "(F8)"
+
+#~ msgid ""
+#~ "Settlement\n"
+#~ "(F9)"
+#~ msgstr ""
+#~ "Pueblo\n"
+#~ "(F9)"
+
+#~ msgid ""
+#~ "Develop\n"
+#~ "(F11)"
+#~ msgstr ""
+#~ "Desarrollar\n"
+#~ "(F11)"
+
+#~ msgid "B"
+#~ msgstr "Ld"
+
+#~ msgid "G"
+#~ msgstr "C"
+
+#~ msgid "O"
+#~ msgstr "Mi"
+
+#~ msgid "W"
+#~ msgstr "Ln"
+
+#~ msgid "L"
+#~ msgstr "Ma"
+
+#~ msgid "%s receives %s\n"
+#~ msgstr "%s recibe %s\n"
+
+#~ msgid "%s spent %s\n"
+#~ msgstr "%s gasta %s\n"
+
+#~ msgid "%s is refunded %s\n"
+#~ msgstr "Se reembolsa %2s a %1s\n"
+
+#~ msgid "%s discarded %s\n"
+#~ msgstr "%s desecha %s\n"
+
+#~ msgid "Player %d is now anonymous.\n"
+#~ msgstr "Jugador %d se hace anónimo.\n"
+
+#~ msgid "%s is now anonymous.\n"
+#~ msgstr "%s se hace anónimo.\n"
+
+#~ msgid "ask"
+#~ msgstr "pedir"
+
+#~ msgid "give "
+#~ msgstr "dar"
+
+#~ msgid "for free"
+#~ msgstr "ofrece gratis"
+
+#~ msgid " for "
+#~ msgstr "por"
+
+#~ msgid "Trading started by %s\n"
+#~ msgstr "%s ofrece comercios\n"
+
+#~ msgid "Quote from player %d: %s.\n"
+#~ msgstr "Presupuesto de jugador %d: %s\n"
+
+#~ msgid "Trading finished.\n"
+#~ msgstr "Los comercios han terminado.\n"
+
+#~ msgid "Resource to take"
+#~ msgstr "Recurso a tomar"
+
+#~ msgid "Take"
+#~ msgstr "Tomar"
+
+#~ msgid "Hand"
+#~ msgstr "Mano"
+
+#~ msgid "Discards"
+#~ msgstr "Descartados"
+
+#~ msgid "Player _Name"
+#~ msgstr "_Nombre de jugador"
+
+#~ msgid "Appearance"
+#~ msgstr "Apariencia"
+
+#~ msgid "Display chat messages in user's color?"
+#~ msgstr "¿Mostrar los mensajes con el color del jugador?"
+
+#~ msgid "Language"
+#~ msgstr "Idioma"
+
+#~ msgid "Resource Type"
+#~ msgstr "Tipo de recurso"
+
+#~ msgid "Server"
+#~ msgstr "Servidor"
+
+#~ msgid "E_xit"
+#~ msgstr "_Salir"
+
+#~ msgid ""
+#~ "Rolls\n"
+#~ "Percentage"
+#~ msgstr ""
+#~ "Tiradas\n"
+#~ "Porcentaje"
+
+#~ msgid "%s moved a ship back.\n"
+#~ msgstr "%s quita un barco.\n"
+
+#~ msgid "Game is full"
+#~ msgstr "Ya no hay espacio en el juego"
Added: trunk/po/fr.po
===================================================================
--- trunk/po/fr.po (rev 0)
+++ trunk/po/fr.po 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,3315 @@
+# Pioneers - Settlers of Catan for GNOME.
+# Copyright (C) 1999-2001 Dave Cole
+# Copyright (C) 2000-2002 Andy Heroff
+# This file is distributed under the same license as the pioneers package.
+# Arnaud MALON <moko at geumeuleu.com>, 2003.
+# Jean-Charles GRANGER <traduction at vecteur.org>, 2006.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Pioneers 0.11.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-07 20:43+0200\n"
+"PO-Revision-Date: 2007-07-16 18:52+0100\n"
+"Last-Translator: Jean-Charles GRANGER <traduction at vecteur.org>\n"
+"Language-Team: Français <LL at li.org>, LT-P <LT-P at LT-P.net>, Yusei "
+"<yusei at ragondux.com>, Arnaud MALON <moko at geumeuleu.com>, Jean-Charles "
+"GRANGER <traduction at vecteur.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Country: FRANCE\n"
+"X-Poedit-SourceCharset: utf-8\n"
+"X-Poedit-Language: French\n"
+
+#. Default name for the AI when the computer_names file
+#. * is not found or empty.
+#.
+#: client/ai/ai.c:74 client/ai/ai.c:90
+msgid "Computer Player"
+msgstr "IA"
+
+#. Commandline pioneersai: server
+#. Commandline option of client: hostname of the server
+#: client/ai/ai.c:102 client/gtk/connect.c:1462 client/gtk/offline.c:53
+msgid "Server Host"
+msgstr "Adresse du serveur"
+
+#. Commandline pioneersai: port
+#. Commandline option of client: port of the server
+#: client/ai/ai.c:105 client/gtk/connect.c:1478 client/gtk/offline.c:56
+#: server/gtk/main.c:612
+msgid "Server Port"
+msgstr "Port du serveur"
+
+#. Commandline pioneersai: name
+#: client/ai/ai.c:108
+msgid "Computer name (leave absent for random name)"
+msgstr "Nom de l'AI (laisser vide pour un nom aléatoire)"
+
+#. Commandline pioneersai: time
+#: client/ai/ai.c:111
+msgid "Time to wait between turns (in milliseconds)"
+msgstr "Intervalle entre chaque tour (en millisecondes)"
+
+#. Commandline pioneersai: chat-free
+#: client/ai/ai.c:114
+msgid "Stop computer player from talking"
+msgstr "Empêcher l'AI de parler"
+
+#. Commandline pioneersai: algorithm
+#: client/ai/ai.c:117
+msgid "Type of computer player"
+msgstr "Type d'AI"
+
+#. Commandline option of ai: enable debug logging
+#. Commandline option of client: enable debug logging
+#. Commandline option of meta server: enable debug logging
+#. Commandline option of server-gtk: enable debug logging
+#. Commandline option of server: enable debug logging
+#: client/ai/ai.c:120 client/gtk/offline.c:74 meta-server/main.c:1049
+#: server/gtk/main.c:952 server/main.c:144
+msgid "Enable debug messages"
+msgstr "Activer les messages de débogage"
+
+#. Commandline option of ai: version
+#. Commandline option of client: version
+#. Commandline option of editor: version
+#. Commandline option of meta server: version
+#. Commandline option of server-gtk: version
+#. Commandline option of server-console: version
+#: client/ai/ai.c:123 client/gtk/offline.c:77 editor/gtk/editor.c:1071
+#: meta-server/main.c:1055 server/gtk/main.c:955 server/main.c:99
+msgid "Show version information"
+msgstr "Voir les informations de version"
+
+#: client/ai/ai.c:134
+msgid "- Computer player for Pioneers"
+msgstr "- AI pour Pioneers"
+
+#: client/ai/ai.c:144 client/gtk/offline.c:186 editor/gtk/editor.c:1111
+#: meta-server/main.c:1084 server/gtk/main.c:1005 server/main.c:206
+#, c-format
+msgid "Pioneers version:"
+msgstr "Version de Pioneers :"
+
+#: client/ai/ai.c:176
+#, c-format
+msgid "Type of computer player: %s\n"
+msgstr "Type d'AI : %s\n"
+
+#: client/ai/ai.c:205
+msgid "The game is already full. I'm leaving."
+msgstr "Tous les joueurs sont déjà présents. On arrête."
+
+#: client/ai/greedy.c:941
+msgid "No settlements in stock to use for setup"
+msgstr "Il n'y a plus de colonie en réserve pour le placement"
+
+#: client/ai/greedy.c:948
+msgid "There is no place to setup a settlement"
+msgstr "Il n'y a plus de place pour fonder une colonie"
+
+#: client/ai/greedy.c:972
+msgid "No roads in stock to use for setup"
+msgstr "Il n'y a pas de route en réserve pour le placement"
+
+#: client/ai/greedy.c:989
+msgid "There is no place to setup a road"
+msgstr "Il n'y a plus de place pour construire une route"
+
+#: client/ai/greedy.c:1291
+msgid "Ok, let's go!"
+msgstr "Ok, allons-y !"
+
+#: client/ai/greedy.c:1292
+msgid "I'll beat you all now! ;)"
+msgstr "Je vais tous vous battre ! ;)"
+
+#: client/ai/greedy.c:1293
+msgid "Now for another try..."
+msgstr "Essayons encore..."
+
+#: client/ai/greedy.c:1297
+msgid "At least I get something..."
+msgstr "Enfin, je reçois quelque chose..."
+
+#: client/ai/greedy.c:1298
+msgid "One is better than none..."
+msgstr "C'est toujours mieux que rien..."
+
+#: client/ai/greedy.c:1302
+msgid "Wow!"
+msgstr "Waouh !"
+
+#: client/ai/greedy.c:1303
+msgid "Ey, I'm becoming rich ;)"
+msgstr "Hé, je deviens riche ;)"
+
+#: client/ai/greedy.c:1304
+msgid "This is really a good year!"
+msgstr "C'est vraiment une bonne année !"
+
+#: client/ai/greedy.c:1307
+msgid "You really don't deserve that much!"
+msgstr "Vous ne méritez pas tout cela !"
+
+#: client/ai/greedy.c:1308
+msgid "You don't know what to do with that many resources ;)"
+msgstr "Et vous savez quoi faire avec toutes ces ressources ? ;)"
+
+#: client/ai/greedy.c:1309
+msgid "Ey, wait for my robber and lose all this again!"
+msgstr ""
+"Hé, attendez un peu que je vous présente mon voleur et que vous perdiez "
+"tout !"
+
+#: client/ai/greedy.c:1312
+msgid "Hehe!"
+msgstr "Hé hé !"
+
+#: client/ai/greedy.c:1313
+msgid "Go, robber, go!"
+msgstr "Allez le voleur, allez !"
+
+#: client/ai/greedy.c:1316
+msgid "You bastard!"
+msgstr "Salopard !"
+
+#: client/ai/greedy.c:1317
+msgid "Can't you move that robber somewhere else?!"
+msgstr "Vous ne pouviez pas mettre ce voleur ailleurs ?!"
+
+#: client/ai/greedy.c:1318
+msgid "Why always me??"
+msgstr "Pourquoi toujours moi ??"
+
+#: client/ai/greedy.c:1321
+msgid "Oh no!"
+msgstr "Oh non !"
+
+#: client/ai/greedy.c:1322
+msgid "Grrr!"
+msgstr "Grrr !"
+
+#: client/ai/greedy.c:1323
+msgid "Who the hell rolled that 7??"
+msgstr "Qui a fait ce satané 7 ??"
+
+#: client/ai/greedy.c:1324
+msgid "Why always me?!?"
+msgstr "Pourquoi toujours moi ?"
+
+#: client/ai/greedy.c:1327
+msgid "Say good bye to your cards... :)"
+msgstr "Dites au revoir à vos cartes... :)"
+
+#: client/ai/greedy.c:1328
+msgid "*evilgrin*"
+msgstr "*rire sadique*"
+
+#: client/ai/greedy.c:1329
+msgid "/me says farewell to your cards ;)"
+msgstr "/me dit adieu à vos cartes... ;)"
+
+#: client/ai/greedy.c:1330
+msgid "That's the price for being rich... :)"
+msgstr "C'est le prix de la richesse... :)"
+
+#: client/ai/greedy.c:1333
+msgid "Ey! Where's that card gone?"
+msgstr "Hé ! Où est passé cette carte ?"
+
+#: client/ai/greedy.c:1334
+msgid "Thieves! Thieves!!"
+msgstr "Au voleur ! Au voleur !"
+
+#: client/ai/greedy.c:1335
+msgid "Wait for my revenge..."
+msgstr "Vous ne perdez rien pour attendre..."
+
+#: client/ai/greedy.c:1338
+msgid "Oh no :("
+msgstr "Oh non :("
+
+#: client/ai/greedy.c:1339
+msgid "Must this happen NOW??"
+msgstr "Est-ce que cela devait vraiment arriver MAINTENANT ??"
+
+#: client/ai/greedy.c:1340
+msgid "Args"
+msgstr "Arg"
+
+#: client/ai/greedy.c:1343
+msgid "Hehe, my soldiers rule!"
+msgstr "Hé hé, trop fort mon chevalier !"
+
+#: client/ai/greedy.c:1346
+msgid "First robbing us, then grabbing the points..."
+msgstr "D'abord je vous vole, et ensuite j'engrange les points..."
+
+#: client/ai/greedy.c:1349
+msgid "See that road!"
+msgstr "Regarde cette route !"
+
+#: client/ai/greedy.c:1352
+msgid "Pf, you won't win with roads alone..."
+msgstr "Pfff, on ne gagne pas qu'avec des routes..."
+
+#: client/ai/greedy.c:1819
+msgid "Rejecting trade.\n"
+msgstr "Offre rejetée.\n"
+
+#: client/ai/greedy.c:1911
+#, c-format
+msgid "Received error from server: %s. Quitting\n"
+msgstr "Reçu une erreur du serveur : %s. Sortie\n"
+
+#: client/ai/greedy.c:1921
+msgid "Yippie!"
+msgstr "Youpi !"
+
+#: client/ai/greedy.c:1923
+msgid "My congratulations"
+msgstr "Félicitations"
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:80
+msgid ""
+"Hello, welcome to the lobby. I am a simple robot. Type '/help' in the chat "
+"to see the list of commands I know."
+msgstr ""
+"Bonjour, bienvenue dans le Hall d'Accueil. Je suis un simple robot. Tapez la "
+"commande '/help' dans la zone de discussion pour voir la liste des commandes "
+"que je connais."
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:107
+msgid "'/help' shows this message again"
+msgstr "'/help' affiche ce message à nouveau"
+
+#. Translators: don't translate '/why'
+#: client/ai/lobbybot.c:110
+msgid "'/why' explains the purpose of this strange board layout"
+msgstr "'/why' explique le pourquoi de cet étrange plateau de jeu"
+
+#. Translators: don't translate '/news'
+#: client/ai/lobbybot.c:113
+msgid "'/news' tells the last released version"
+msgstr "'/news' indique quelle est la dernière version de Pioneers"
+
+#: client/ai/lobbybot.c:118
+msgid ""
+"This board is not intended to be a game that can be played. Instead, players "
+"can find eachother here, and decide which board they want to play. Then, one "
+"of the players will host the proposed game by starting a server, and "
+"registers it at the metaserver. The other players can subsequently "
+"disconnect from the lobby, and enter that game."
+msgstr ""
+"Ce plateau n'est pas une partie où l'on peut jouer : c'est un lieu où l'on "
+"peut rencontrer d'autres joueurs et décider quel plateau jouer. L'un des "
+"joueurs hébergera la partie choisie en démarrant un serveur et en "
+"l'enregistrant sur le metaserveur. Les autres joueurs pourront ensuite se "
+"déconnecter du Hall d'Accueil, et entrer dans la partie."
+
+#: client/ai/lobbybot.c:129
+msgid "The last released version of Pioneers is"
+msgstr "La dernière version de Pioneers est"
+
+#: client/ai/lobbybot.c:144
+msgid "The game is starting. I'm not needed anymore. Goodbye."
+msgstr "La partie démarre. Je ne vous suis plus d'aucune utilité. Au revoir."
+
+#: client/common/client.c:103
+msgid "Waiting"
+msgstr "En attente"
+
+#: client/common/client.c:105 client/common/client.c:1241
+msgid "Idle"
+msgstr "Inactif"
+
+#: client/common/client.c:447
+msgid "We have been kicked out of the game.\n"
+msgstr "Vous avez été expulsé de la partie.\n"
+
+#. Network status: offline
+#: client/common/client.c:450 client/common/client.c:891 client/gtk/gui.c:1340
+msgid "Offline"
+msgstr "Déconnecté"
+
+#: client/common/client.c:471
+#, c-format
+msgid "Error (%s): %s\n"
+msgstr "Erreur (%s) : %s\n"
+
+#: client/common/client.c:480 client/common/client.c:491
+#, c-format
+msgid "Notice: %s\n"
+msgstr "Avertissement : %s\n"
+
+#: client/common/client.c:607
+#, c-format
+msgid "%s does not receive any %s, because the bank is empty.\n"
+msgstr "%s n'a reçu aucune ressource %s (la banque est vide).\n"
+
+#: client/common/client.c:620
+#, c-format
+msgid "%s only receives %s, because the bank didn't have any more.\n"
+msgstr "%s a reçu uniquement %s, car la banque n'en a pas plus.\n"
+
+#: client/common/client.c:629
+#, c-format
+msgid "%s receives %s.\n"
+msgstr "%s reçoit %s.\n"
+
+#. Year of Plenty
+#: client/common/client.c:637 client/common/client.c:2586
+#, c-format
+msgid "%s takes %s.\n"
+msgstr "%s prend %s.\n"
+
+#: client/common/client.c:642
+#, c-format
+msgid "%s spent %s.\n"
+msgstr "%s dépense %s.\n"
+
+#: client/common/client.c:648
+#, c-format
+msgid "%s is refunded %s.\n"
+msgstr "%s est remboursé de %s.\n"
+
+#: client/common/client.c:679
+#, c-format
+msgid "%s discarded %s.\n"
+msgstr "%s jete %s.\n"
+
+#: client/common/client.c:849
+msgid "Loading"
+msgstr "Chargement"
+
+#: client/common/client.c:892
+msgid "Version mismatch"
+msgstr "Versions incompatibles"
+
+#: client/common/client.c:894
+msgid "Version mismatch. Please make sure client and server are up to date.\n"
+msgstr ""
+"Versions incompatibles. Vérifiez que le client et le serveur sont à jour.\n"
+
+#: client/common/client.c:1340
+msgid "Build two settlements, each with a connecting"
+msgstr "Fondez deux colonies avec une voie de liaison pour chacune"
+
+#: client/common/client.c:1343
+msgid "Build a settlement with a connecting"
+msgstr "Fondez une colonie et sa voie de liaison"
+
+#: client/common/client.c:1346
+msgid "road"
+msgstr "route"
+
+#: client/common/client.c:1348
+msgid "bridge"
+msgstr "pont"
+
+#: client/common/client.c:1350
+msgid "ship"
+msgstr "navire"
+
+#: client/common/client.c:1358
+msgid " or"
+msgstr " ou"
+
+#: client/common/client.c:1416
+msgid "Waiting for your turn"
+msgstr "Nous attendons notre tour"
+
+#: client/common/client.c:1468
+msgid "Select the building to steal from."
+msgstr "Choisissez la construction à voler."
+
+#: client/common/client.c:1490
+msgid "Select the ship to steal from."
+msgstr "Choisissez le navire à voler."
+
+#: client/common/client.c:1575 client/gtk/interface.c:782
+msgid "Place the robber"
+msgstr "Déplacez le voleur"
+
+#: client/common/client.c:1625
+msgid "Finish the road building action."
+msgstr "Finissez la construction des routes."
+
+#: client/common/client.c:1627
+msgid "Build one road segment."
+msgstr "Construit un segment de route."
+
+#: client/common/client.c:1629
+msgid "Build two road segments."
+msgstr "Construit deux segments de route"
+
+#: client/common/client.c:1902 client/common/client.c:1996
+msgid "It is your turn."
+msgstr "C'est votre tour."
+
+#: client/common/client.c:2090
+#, c-format
+msgid "Sorry, %s available.\n"
+msgstr "Désolé, %s indisponible.\n"
+
+#: client/common/client.c:2405
+msgid "The game is over."
+msgstr "La partie est finie."
+
+#: client/common/develop.c:43 editor/gtk/game-devcards.c:13
+msgid "Road Building"
+msgstr "Construction de route"
+
+#: client/common/develop.c:44 client/gtk/monopoly.c:83
+#: editor/gtk/game-devcards.c:13
+msgid "Monopoly"
+msgstr "Monopole"
+
+#: client/common/develop.c:45 client/gtk/plenty.c:59
+#: editor/gtk/game-devcards.c:13
+msgid "Year of Plenty"
+msgstr "Année faste"
+
+#: client/common/develop.c:46 client/gtk/player.c:57
+#: editor/gtk/game-devcards.c:14
+msgid "Chapel"
+msgstr "Chapelle"
+
+#: client/common/develop.c:47 client/gtk/player.c:58
+#: editor/gtk/game-devcards.c:14
+msgid "Pioneer University"
+msgstr "Université"
+
+#: client/common/develop.c:48 client/gtk/player.c:60
+#: editor/gtk/game-devcards.c:15
+msgid "Governor's House"
+msgstr "Palais du Gouverneur"
+
+#: client/common/develop.c:49 client/gtk/player.c:61
+#: editor/gtk/game-devcards.c:15
+msgid "Library"
+msgstr "Bibliothèque"
+
+#: client/common/develop.c:50 client/gtk/player.c:62
+#: editor/gtk/game-devcards.c:15
+msgid "Market"
+msgstr "Marché"
+
+#: client/common/develop.c:51 client/gtk/player.c:63
+#: editor/gtk/game-devcards.c:16
+msgid "Soldier"
+msgstr "Chevalier"
+
+#: client/common/develop.c:82
+#, c-format
+msgid "You bought the %s development card.\n"
+msgstr "Vous avez acheté la carte de développement %s.\n"
+
+#: client/common/develop.c:88
+#, c-format
+msgid "You bought a %s development card.\n"
+msgstr "Vous avez acheté une carte de développement %s.\n"
+
+#: client/common/develop.c:110
+#, c-format
+msgid "%s bought a development card.\n"
+msgstr "%s achète une carte de développement.\n"
+
+#: client/common/develop.c:129
+#, c-format
+msgid "%s played the %s development card.\n"
+msgstr "%s joue la carte de développement %s.\n"
+
+#: client/common/develop.c:134
+#, c-format
+msgid "%s played a %s development card.\n"
+msgstr "%s joue la carte de développement %s.\n"
+
+#: client/common/develop.c:147
+msgid "You have run out of road segments.\n"
+msgstr "Vous êtes à court de routes.\n"
+
+#. I get the cards!
+#.
+#: client/common/develop.c:187
+#, c-format
+msgid "You get %s from %s.\n"
+msgstr "Vous recevez %s de %s.\n"
+
+#. I lose the cards!
+#.
+#: client/common/develop.c:193
+#, c-format
+msgid "%s took %s from you.\n"
+msgstr "%s vous prend %s.\n"
+
+#: client/common/develop.c:200
+#, c-format
+msgid "%s took %s from %s.\n"
+msgstr "%s prend %s à %s.\n"
+
+#: client/common/player.c:124 server/player.c:405
+#, c-format
+msgid "Viewer %d"
+msgstr "Spectateur %d"
+
+#: client/common/player.c:126
+#, c-format
+msgid "viewer %d"
+msgstr "spectateur %d"
+
+#: client/common/player.c:134 server/player.c:408
+#, c-format
+msgid "Player %d"
+msgstr "Joueur %d"
+
+#: client/common/player.c:136
+#, c-format
+msgid "player %d"
+msgstr "joueur %d"
+
+#: client/common/player.c:212
+#, c-format
+msgid "New viewer: %s.\n"
+msgstr "Nouveau spectateur : %s.\n"
+
+#: client/common/player.c:215 client/common/player.c:231
+#, c-format
+msgid "%s is now %s.\n"
+msgstr "%s s'appelle maintenant %s.\n"
+
+#: client/common/player.c:228
+#, c-format
+msgid "Player %d is now %s.\n"
+msgstr "Le joueur %d s'appelle maintenant %s.\n"
+
+#: client/common/player.c:267
+#, c-format
+msgid "%s has quit\n"
+msgstr "%s est parti\n"
+
+#: client/common/player.c:276
+msgid "There is no largest army.\n"
+msgstr "Il n'y a pas de chevalier le plus puissant.\n"
+
+#: client/common/player.c:279
+#, c-format
+msgid "%s has the largest army.\n"
+msgstr "%s détient le chevalier le plus puissant.\n"
+
+#: client/common/player.c:300
+msgid "There is no longest road.\n"
+msgstr "Il n'y a pas de route la plus longue.\n"
+
+#: client/common/player.c:303
+#, c-format
+msgid "%s has the longest road.\n"
+msgstr "%s a la route la plus longue.\n"
+
+#: client/common/player.c:324
+#, c-format
+msgid "Waiting for %s."
+msgstr "En attende de %s."
+
+#. We are not in on the action
+#. someone stole a resource from someone else
+#: client/common/player.c:352
+#, c-format
+msgid "%s stole a resource from %s.\n"
+msgstr "%s vole une ressource à %s.\n"
+
+#: client/common/player.c:362
+#, c-format
+msgid "You stole %s from %s.\n"
+msgstr "Vous volez %s à %s.\n"
+
+#: client/common/player.c:368
+#, c-format
+msgid "%s stole %s from you.\n"
+msgstr "%s vous vole %s.\n"
+
+#: client/common/player.c:402
+#, c-format
+msgid "%s gave %s nothing!?\n"
+msgstr "%s ne donne rien à %s !?\n"
+
+#: client/common/player.c:408 client/common/player.c:416
+#, c-format
+msgid "%s gave %s %s for free.\n"
+msgstr "%s donne %s %s gratuitement.\n"
+
+#: client/common/player.c:424
+#, c-format
+msgid "%s gave %s %s in exchange for %s.\n"
+msgstr "%s donne %s %s en échange de %s.\n"
+
+#: client/common/player.c:455
+#, c-format
+msgid "%s exchanged %s for %s.\n"
+msgstr "%s échange %s contre %s.\n"
+
+#: client/common/player.c:475
+#, c-format
+msgid "%s built a road.\n"
+msgstr "%s construit une route.\n"
+
+#: client/common/player.c:487
+#, c-format
+msgid "%s built a ship.\n"
+msgstr "%s construire un navire.\n"
+
+#: client/common/player.c:500
+#, c-format
+msgid "%s built a settlement.\n"
+msgstr "%s fonde une colonie.\n"
+
+#: client/common/player.c:519
+#, c-format
+msgid "%s built a city.\n"
+msgstr "%s érige une ville.\n"
+
+#: client/common/player.c:533
+#, c-format
+msgid "%s built a city wall.\n"
+msgstr "%s construit un rempart.\n"
+
+#: client/common/player.c:544
+#, c-format
+msgid "player_build_add called with BUILD_NONE for user %s\n"
+msgstr "player_build_add est appellé avec BUILD_NONE pour le joueur %s\n"
+
+#: client/common/player.c:553
+#, c-format
+msgid "%s built a bridge.\n"
+msgstr "%s construit un pont.\n"
+
+#: client/common/player.c:579
+#, c-format
+msgid "%s removed a road.\n"
+msgstr "%s retire une route.\n"
+
+#: client/common/player.c:589
+#, c-format
+msgid "%s removed a ship.\n"
+msgstr "%s retire un navire.\n"
+
+#: client/common/player.c:599
+#, c-format
+msgid "%s removed a settlement.\n"
+msgstr "%s retire une colonie.\n"
+
+#: client/common/player.c:610
+#, c-format
+msgid "%s removed a city.\n"
+msgstr "%s retire une ville.\n"
+
+#: client/common/player.c:624
+#, c-format
+msgid "%s removed a city wall.\n"
+msgstr "%s supprime un rempart.\n"
+
+#: client/common/player.c:634
+#, c-format
+msgid "player_build_remove called with BUILD_NONE for user %s\n"
+msgstr "player_build_remove est appellé avec BUILD_NONE pour le joueur %s\n"
+
+#: client/common/player.c:642
+#, c-format
+msgid "%s removed a bridge.\n"
+msgstr "%s retire un pont.\n"
+
+#: client/common/player.c:673
+#, c-format
+msgid "%s has cancelled a ship's movement.\n"
+msgstr "%s a annulé un mouvement de navire.\n"
+
+#: client/common/player.c:676
+#, c-format
+msgid "%s moved a ship.\n"
+msgstr "%s déplace un navire.\n"
+
+#. tell the user that someone got something
+#: client/common/player.c:696
+#, c-format
+msgid "%s received %s.\n"
+msgstr "%s a reçu %s.\n"
+
+#: client/common/player.c:714
+msgid "server asks to lose invalid point.\n"
+msgstr "le serveur demande la perte du point incorrect.\n"
+
+#. tell the user the point is lost
+#: client/common/player.c:720
+#, c-format
+msgid "%s lost %s.\n"
+msgstr "%s perd %s.\n"
+
+#: client/common/player.c:743
+msgid "server asks to move invalid point.\n"
+msgstr "le serveur demande de déplacer le point incorrect.\n"
+
+#. tell the user someone (1) lost something (2) to someone else (3)
+#: client/common/player.c:750
+#, c-format
+msgid "%s lost %s to %s.\n"
+msgstr "%s perd %s à %s.\n"
+
+#: client/common/resource.c:35
+msgid "brick"
+msgstr "argile"
+
+#: client/common/resource.c:35
+msgid "Brick"
+msgstr "Argile"
+
+#: client/common/resource.c:36
+msgid "grain"
+msgstr "blé"
+
+#: client/common/resource.c:36
+msgid "Grain"
+msgstr "Blé"
+
+#: client/common/resource.c:37
+msgid "ore"
+msgstr "pierre"
+
+#: client/common/resource.c:37
+msgid "Ore"
+msgstr "Pierre"
+
+#: client/common/resource.c:38
+msgid "wool"
+msgstr "laine"
+
+#: client/common/resource.c:38
+msgid "Wool"
+msgstr "Laine"
+
+#: client/common/resource.c:39
+msgid "lumber"
+msgstr "bois"
+
+#: client/common/resource.c:39
+msgid "Lumber"
+msgstr "Bois"
+
+#: client/common/resource.c:40
+msgid "no resource (bug)"
+msgstr "pas de ressources (bug)"
+
+#: client/common/resource.c:40
+msgid "No resource (bug)"
+msgstr "Pas de ressources (bug)"
+
+#: client/common/resource.c:41
+msgid "any resource (bug)"
+msgstr "n'importe quelle ressource (bug)"
+
+#: client/common/resource.c:41
+msgid "Any resource (bug)"
+msgstr "N'importe quelle ressource (bug)"
+
+#: client/common/resource.c:42
+msgid "gold"
+msgstr "or"
+
+#: client/common/resource.c:42 client/gtk/legend.c:39
+msgid "Gold"
+msgstr "Or"
+
+#: client/common/resource.c:47
+msgid "a brick card"
+msgstr "une carte d'argile"
+
+#: client/common/resource.c:47
+#, c-format
+msgid "%d brick cards"
+msgstr "%d cartes d'argile"
+
+#: client/common/resource.c:48
+msgid "a grain card"
+msgstr "une carte de blé"
+
+#: client/common/resource.c:48
+#, c-format
+msgid "%d grain cards"
+msgstr "%d cartes de blés"
+
+#: client/common/resource.c:49
+msgid "an ore card"
+msgstr "une carte de pierre"
+
+#: client/common/resource.c:49
+#, c-format
+msgid "%d ore cards"
+msgstr "%d cartes de pierre"
+
+#: client/common/resource.c:50
+msgid "a wool card"
+msgstr "une carte de laine"
+
+#: client/common/resource.c:50
+#, c-format
+msgid "%d wool cards"
+msgstr "%d cartes de laine"
+
+#: client/common/resource.c:51
+msgid "a lumber card"
+msgstr "une carte de bois"
+
+#: client/common/resource.c:51
+#, c-format
+msgid "%d lumber cards"
+msgstr "%d cartes de bois"
+
+#: client/common/resource.c:139 client/common/resource.c:225
+msgid "nothing"
+msgstr "rien"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:166
+#, c-format
+msgid "%s and %s"
+msgstr "%s et %s"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:170
+#, c-format
+msgid "%s, %s"
+msgstr "%s, %s"
+
+#: client/common/robber.c:60
+#, c-format
+msgid "%s has undone the robber movement.\n"
+msgstr "%s a annulé le déplacement du voleur.\n"
+
+#: client/common/robber.c:63
+#, c-format
+msgid "%s moved the robber.\n"
+msgstr "%s déplace le voleur.\n"
+
+#: client/common/robber.c:73
+#, c-format
+msgid "%s has undone the pirate movement.\n"
+msgstr "%s a annulé le déplacement du pirate.\n"
+
+#: client/common/robber.c:76
+#, c-format
+msgid "%s moved the pirate.\n"
+msgstr "%s déplace le pirate.\n"
+
+#: client/common/robber.c:83
+#, c-format
+msgid "%s must move the robber."
+msgstr "%s doit déplacer le voleur."
+
+#: client/common/setup.c:140
+#, c-format
+msgid "Setup for %s.\n"
+msgstr "Placement pour %s.\n"
+
+#: client/common/setup.c:152
+#, c-format
+msgid "Double setup for %s.\n"
+msgstr "Double placement pour %s.\n"
+
+#: client/common/turn.c:37
+#, c-format
+msgid "%s rolled %d.\n"
+msgstr "%s a fait %d.\n"
+
+#: client/common/turn.c:50
+#, c-format
+msgid "Begin turn %d for %s.\n"
+msgstr "Début du tour %d pour %s.\n"
+
+#: client/gtk/chat.c:71
+msgid "<b>Chat</b>"
+msgstr "<b>Dialogue</b>"
+
+#: client/gtk/chat.c:231
+msgid "Beeper test.\n"
+msgstr "Essai de bip.\n"
+
+#: client/gtk/chat.c:234
+#, c-format
+msgid "%s beeped you.\n"
+msgstr "%s vous bipe.\n"
+
+#: client/gtk/chat.c:238
+#, c-format
+msgid "You beeped %s.\n"
+msgstr "Vous bipez %s.\n"
+
+#: client/gtk/chat.c:244
+#, c-format
+msgid "You could not beep %s.\n"
+msgstr "Vous ne pouved pas biper %s.\n"
+
+#: client/gtk/chat.c:288
+msgid " said: "
+msgstr " a dit : "
+
+#: client/gtk/connect.c:282
+#, c-format
+msgid "Meta-server at %s, port %s"
+msgstr "Meta-serveur à l'adresse %s, port %s"
+
+#: client/gtk/connect.c:292
+msgid "Finished.\n"
+msgstr "Terminé.\n"
+
+#: client/gtk/connect.c:309 client/gtk/connect.c:359 client/gtk/connect.c:456
+#: server/meta.c:174
+msgid "Meta-server kicked us off\n"
+msgstr "Le meta-serveur nous a expulsé\n"
+
+#: client/gtk/connect.c:334
+msgid "Receiving game names from the meta server.\n"
+msgstr "Reception du nom des parties du meta-serveur.\n"
+
+#: client/gtk/connect.c:382
+#, c-format
+msgid "New game server requested on %s port %s\n"
+msgstr "Une nouvelle partie commence sur le serveur %s, port %s.\n"
+
+#: client/gtk/connect.c:391 server/meta.c:168
+#, c-format
+msgid "Unknown message from the metaserver: %s\n"
+msgstr "Message inconnu du meta-serveur : %s\n"
+
+#: client/gtk/connect.c:472 server/meta.c:125
+msgid "Too many meta-server redirects\n"
+msgstr "Trop de redirections du meta-serveur\n"
+
+#: client/gtk/connect.c:499 server/meta.c:140
+#, c-format
+msgid "Bad redirect line: %s\n"
+msgstr "Mauvaise redirection ligne %s\n"
+
+#: client/gtk/connect.c:525
+#, c-format
+msgid "Meta server too old to create servers (version %d.%d)\n"
+msgstr ""
+"Le meta-serveur est trop vieux pour créer des parties (version %d.%d)\n"
+
+#. Sevens rule: normal
+#: client/gtk/connect.c:596 client/gtk/settingscreen.c:168
+#: common/gtk/game-rules.c:81
+msgid "Normal"
+msgstr "Normal"
+
+#: client/gtk/connect.c:602 client/gtk/settingscreen.c:170
+#: common/gtk/game-rules.c:88
+msgid "Reroll on 1st 2 turns"
+msgstr "Relancer les dés les 2 premiers tours"
+
+#: client/gtk/connect.c:605 client/gtk/settingscreen.c:172
+#: common/gtk/game-rules.c:95
+msgid "Reroll all 7s"
+msgstr "Relancer tous les 7"
+
+#: client/gtk/connect.c:619
+msgid "Default"
+msgstr "Par défaut"
+
+#: client/gtk/connect.c:622
+msgid "Random"
+msgstr "Aléatoire"
+
+#: client/gtk/connect.c:653 server/meta.c:188
+#, c-format
+msgid "Redirected to meta-server at %s, port %s\n"
+msgstr "Redirection sur le meta-serveur %s, port %s.\n"
+
+#: client/gtk/connect.c:656
+msgid "Receiving a list of Pioneers servers from the meta server.\n"
+msgstr "Réception d'une liste de serveurs Pioneers depuis le meta-serveur.\n"
+
+#: client/gtk/connect.c:713
+msgid ""
+"<b>Note</b>:\n"
+"\tThe metaserver does not send information about the games.\n"
+"\tPlease set appropriate values yourself."
+msgstr ""
+"<b>Note</b> :\n"
+"\tLe meta-server n'envoit pas d'information sur les parties.\n"
+"\tA vous de les définir vous-même."
+
+#: client/gtk/connect.c:730
+msgid "Number of AI Players"
+msgstr "Nombre d'IA"
+
+#: client/gtk/connect.c:749
+msgid "The number of AI players"
+msgstr "Nombre d'IA"
+
+#: client/gtk/connect.c:770
+msgid "Requesting new game server\n"
+msgstr "Demander une nouvelle partie\n"
+
+#: client/gtk/connect.c:813 server/gtk/main.c:328 server/server.c:160
+#, c-format
+msgid "Error starting %s: %s"
+msgstr "Erreur en démarrant %s : %s"
+
+#: client/gtk/connect.c:834
+msgid "Create a public game"
+msgstr "Créer une partie publique"
+
+#: client/gtk/connect.c:965 client/gtk/connect.c:1268
+msgid "Join a public game"
+msgstr "Rejoindre une partie publique"
+
+#: client/gtk/connect.c:970
+msgid "_New remote game"
+msgstr "_Nouvelle partie distante"
+
+#: client/gtk/connect.c:984
+msgid "Refresh the list of games"
+msgstr "Rafraîchir la liste des parties"
+
+#: client/gtk/connect.c:989
+msgid "Create a new public game at the meta server"
+msgstr "Créer une nouvelle partie publique sur le meta-serveur"
+
+#: client/gtk/connect.c:994
+msgid "Don't join a public game"
+msgstr "Ne pas rejoindre une partie publique"
+
+#: client/gtk/connect.c:998
+msgid "Join the selected game"
+msgstr "Rejoindre la partie sélectionnée"
+
+#: client/gtk/connect.c:1033
+msgid "Select a game to join"
+msgstr "Choisir une partie à rejoindre"
+
+#: client/gtk/connect.c:1036
+msgid "Map Name"
+msgstr "Nom de la carte"
+
+#: client/gtk/connect.c:1044
+msgid "Name of the game"
+msgstr "Nom de la partie"
+
+#: client/gtk/connect.c:1049
+msgid "Curr"
+msgstr "Cour."
+
+#: client/gtk/connect.c:1055
+msgid "Number of players in the game"
+msgstr "Nombre de joueurs"
+
+#: client/gtk/connect.c:1060
+msgid "Max"
+msgstr "Max"
+
+#: client/gtk/connect.c:1066
+msgid "Maximum players for the game"
+msgstr "Nombre maximum de joueurs"
+
+#: client/gtk/connect.c:1069
+msgid "Terrain"
+msgstr "Carte"
+
+#: client/gtk/connect.c:1076
+msgid "Random of default terrain"
+msgstr "Carte aléatoire"
+
+#: client/gtk/connect.c:1081
+msgid "Vic. Points"
+msgstr "Pts de Vic."
+
+#: client/gtk/connect.c:1087
+msgid "Points needed to win"
+msgstr "Points requis pour gagner"
+
+#: client/gtk/connect.c:1090 common/gtk/game-rules.c:73
+msgid "Sevens Rule"
+msgstr "Règle des sept"
+
+#: client/gtk/connect.c:1096
+msgid "Sevens rule"
+msgstr "Règle des sept"
+
+#: client/gtk/connect.c:1100
+msgid "Host"
+msgstr "Adresse"
+
+#: client/gtk/connect.c:1108
+msgid "Host of the game"
+msgstr "Adresse de la partie"
+
+#: client/gtk/connect.c:1113
+msgid "Port"
+msgstr "Port"
+
+#: client/gtk/connect.c:1119
+msgid "Port of the the game"
+msgstr "Port de la partie"
+
+#: client/gtk/connect.c:1122 common/gtk/aboutbox.c:77
+msgid "Version"
+msgstr "Version"
+
+#: client/gtk/connect.c:1129
+msgid "Version of the host"
+msgstr "Version du serveur"
+
+#: client/gtk/connect.c:1184 client/gtk/gui.c:215
+msgid "Start a new game"
+msgstr "Commencer une nouvelle partie"
+
+#: client/gtk/connect.c:1209
+msgid "Player Name"
+msgstr "Nom du joueur"
+
+#: client/gtk/connect.c:1223
+msgid "Enter your name"
+msgstr "Entrez votre nom"
+
+#. Role of the player: viewer
+#: client/gtk/connect.c:1225 server/gtk/main.c:511
+msgid "Viewer"
+msgstr "Spectateur"
+
+#: client/gtk/connect.c:1233
+msgid "Do you want to be a viewer?"
+msgstr "Souhaitez-vous être spectateur ?"
+
+#: client/gtk/connect.c:1240 server/gtk/main.c:640
+msgid "Meta Server"
+msgstr "Meta-serveur"
+
+#: client/gtk/connect.c:1255
+msgid "Leave empty for the default meta server"
+msgstr "Laissez vide pour le meta-serveur par défaut"
+
+#: client/gtk/connect.c:1263
+msgid "Join public game"
+msgstr "Rejoindre une partie publique"
+
+#: client/gtk/connect.c:1272
+msgid "Create game"
+msgstr "Créer une partie"
+
+#: client/gtk/connect.c:1275
+msgid "Create a game"
+msgstr "Créer une partie"
+
+#: client/gtk/connect.c:1285
+msgid "Join private game"
+msgstr "Rejoindre une partie privée"
+
+#: client/gtk/connect.c:1289 client/gtk/connect.c:1434
+msgid "Join a private game"
+msgstr "Rejoindre une partie privée"
+
+#: client/gtk/connect.c:1475
+msgid "Name of the host of the game"
+msgstr "Nom du serveur hébergeant la partie"
+
+#: client/gtk/connect.c:1494
+msgid "Port of the host of the game"
+msgstr "Port du serveur hébergeant la partie"
+
+#: client/gtk/connect.c:1534
+msgid "Recent games"
+msgstr "Serveurs récents"
+
+#: client/gtk/connect.c:1536
+msgid "Recent Games"
+msgstr "Serveurs récents"
+
+#: client/gtk/develop.c:129
+msgid "<b>Development Cards</b>"
+msgstr "<b>Pioche des cartes de développement</b>"
+
+#: client/gtk/develop.c:160
+msgid "Play Card"
+msgstr "Jouer la carte"
+
+#: client/gtk/discard.c:76
+msgid "Discard resources"
+msgstr "Jeter les ressources"
+
+#: client/gtk/discard.c:96
+#, c-format
+msgid "You must discard %d resources"
+msgstr "Vous devez jeter %d ressources"
+
+#: client/gtk/discard.c:101
+msgid "Total discards"
+msgstr "Total des cartes jetées"
+
+#. Caption for list of player that must discard cards
+#: client/gtk/discard.c:226
+msgid "<b>Waiting for players to discard</b>"
+msgstr "<b>En attente des joueurs jetant des cartes</b>"
+
+#: client/gtk/gameover.c:32
+msgid "Game over"
+msgstr "Partie terminée"
+
+#: client/gtk/gameover.c:49
+#, c-format
+msgid "%s has won the game with %d victory points!"
+msgstr "%s a gagné la partie avec %d points de victoire !"
+
+#: client/gtk/gameover.c:52
+#, c-format
+msgid "%s has won the game with %d victory points!\n"
+msgstr "%s a gagné la partie avec %d points de victoire !\n"
+
+#: client/gtk/gameover.c:58
+#, c-format
+msgid "All praise %s, Lord of the known world!"
+msgstr "Gloire à %s, seigneur du monde connu !"
+
+#: client/gtk/gold.c:71
+msgid "Choose resources"
+msgstr "Choisissez des ressources"
+
+#: client/gtk/gold.c:92
+#, c-format
+msgid "You may choose 1 resource"
+msgstr "Vous pouvez choisir 1 ressource"
+
+#: client/gtk/gold.c:94
+#, c-format
+msgid "You may choose %d resources"
+msgstr "Vous pouvez choisir %d ressources"
+
+#. Text for total in choose gold dialog
+#. Text for total in year of plenty dialog
+#: client/gtk/gold.c:101 client/gtk/plenty.c:98
+msgid "Total resources"
+msgstr "Total des ressources"
+
+#: client/gtk/gold.c:213
+msgid "<b>Waiting for players to choose</b>"
+msgstr "<b>En attente des joueurs qui choisissent</b>"
+
+#: client/gtk/gui.c:213 server/gtk/main.c:98
+msgid "_Game"
+msgstr "_Partie"
+
+#: client/gtk/gui.c:214
+msgid "_New game"
+msgstr "_Nouvelle partie"
+
+#: client/gtk/gui.c:216
+msgid "_Leave game"
+msgstr "Abandonner _la partie"
+
+#: client/gtk/gui.c:217
+msgid "Leave this game"
+msgstr "Quitter cette partie"
+
+#: client/gtk/gui.c:219
+msgid "_Admin"
+msgstr "_Administrateur"
+
+#: client/gtk/gui.c:220
+msgid "Administer Pioneers server"
+msgstr "Administrer le serveur Pioneers"
+
+#: client/gtk/gui.c:222
+msgid "_Player name"
+msgstr "_Pseudonyme du joueur"
+
+#: client/gtk/gui.c:223
+msgid "Change your player name"
+msgstr "Changer de pseudonyme"
+
+#: client/gtk/gui.c:224
+msgid "_Legend"
+msgstr "_Légende"
+
+#: client/gtk/gui.c:225
+msgid "Terrain legend and building costs"
+msgstr "Légende des terrains et des coûts de construction"
+
+#: client/gtk/gui.c:226
+msgid "_Game Settings"
+msgstr "_Paramètres de la partie"
+
+#: client/gtk/gui.c:227
+msgid "Settings for the current game"
+msgstr "Paramètres de la partie actuelle"
+
+#: client/gtk/gui.c:228
+msgid "_Dice Histogram"
+msgstr "_Histogramme des lancers de dés"
+
+#: client/gtk/gui.c:229
+msgid "Histogram of dice rolls"
+msgstr "Histogramme des lancers de dés"
+
+#: client/gtk/gui.c:230 editor/gtk/editor.c:1018 server/gtk/main.c:103
+msgid "_Quit"
+msgstr "_Quitter"
+
+#: client/gtk/gui.c:231 server/gtk/main.c:104
+msgid "Quit the program"
+msgstr "Quitter le programme"
+
+#: client/gtk/gui.c:232
+msgid "_Actions"
+msgstr "_Actions"
+
+#: client/gtk/gui.c:233
+msgid "Roll Dice"
+msgstr "Lancer les dés"
+
+#: client/gtk/gui.c:234
+msgid "Roll the dice"
+msgstr "Lancer les dés"
+
+#. Tab page name
+#: client/gtk/gui.c:235 client/gtk/gui.c:577
+msgid "Trade"
+msgstr "Ãchanges"
+
+#: client/gtk/gui.c:237
+msgid "Undo"
+msgstr "Annuler"
+
+#: client/gtk/gui.c:238 client/gtk/gui.c:239
+msgid "Finish"
+msgstr "Terminer"
+
+#: client/gtk/gui.c:240 client/gtk/legend.c:226 editor/gtk/game-buildings.c:13
+msgid "Road"
+msgstr "Route"
+
+#: client/gtk/gui.c:241
+msgid "Build a road"
+msgstr "Construire une route"
+
+#: client/gtk/gui.c:242 client/gtk/legend.c:230 editor/gtk/game-buildings.c:13
+msgid "Ship"
+msgstr "Navire"
+
+#: client/gtk/gui.c:243
+msgid "Build a ship"
+msgstr "Construire un navire"
+
+#: client/gtk/gui.c:244
+msgid "Move Ship"
+msgstr "Déplacer un navire"
+
+#: client/gtk/gui.c:245
+msgid "Move a ship"
+msgstr "Déplacer un navire"
+
+#: client/gtk/gui.c:246 client/gtk/legend.c:233 editor/gtk/game-buildings.c:13
+msgid "Bridge"
+msgstr "Pont"
+
+#: client/gtk/gui.c:247
+msgid "Build a bridge"
+msgstr "Construire un pont"
+
+#: client/gtk/gui.c:248 client/gtk/legend.c:235 client/gtk/player.c:52
+#: editor/gtk/game-buildings.c:13
+msgid "Settlement"
+msgstr "Colonie"
+
+#: client/gtk/gui.c:249
+msgid "Build a settlement"
+msgstr "Fonder une colonie"
+
+#: client/gtk/gui.c:250 client/gtk/legend.c:236 client/gtk/player.c:53
+#: editor/gtk/game-buildings.c:14
+msgid "City"
+msgstr "Ville"
+
+#: client/gtk/gui.c:251
+msgid "Build a city"
+msgstr "Eriger une cité"
+
+#: client/gtk/gui.c:252
+msgid "Develop"
+msgstr "Carte de Dév."
+
+#: client/gtk/gui.c:253
+msgid "Buy a development card"
+msgstr "Acheter une carte de développement"
+
+#: client/gtk/gui.c:254 client/gtk/legend.c:240 client/gtk/player.c:54
+#: editor/gtk/game-buildings.c:14
+msgid "City Wall"
+msgstr "Rempart"
+
+#: client/gtk/gui.c:255
+msgid "Build a city wall"
+msgstr "Construire un rempart"
+
+#: client/gtk/gui.c:257
+msgid "_Settings"
+msgstr "Préférence_s"
+
+#: client/gtk/gui.c:258
+msgid "Prefere_nces"
+msgstr "Préfére_nces"
+
+#: client/gtk/gui.c:259
+msgid "Configure the application"
+msgstr "Configurer l'application"
+
+#: client/gtk/gui.c:261 client/gtk/gui.c:265 editor/gtk/editor.c:1002
+#: server/gtk/main.c:99
+msgid "_Help"
+msgstr "_Aide"
+
+#: client/gtk/gui.c:262
+msgid "_About Pioneers"
+msgstr "_Ã propos de Pioneers"
+
+#: client/gtk/gui.c:263
+msgid "Information about Pioneers"
+msgstr "Informations à propos de Pioneers"
+
+#: client/gtk/gui.c:266 client/gtk/gui.c:1065
+msgid "Show the manual"
+msgstr "Montrer le manuel"
+
+#: client/gtk/gui.c:272
+msgid "_Toolbar"
+msgstr "Barre d'ou_tils"
+
+#: client/gtk/gui.c:273
+msgid "Show or hide the toolbar"
+msgstr "Afficher ou masquer la barre d'outils"
+
+#. Victory points target in statusbar
+#: client/gtk/gui.c:368
+#, c-format
+msgid "Points Needed to Win: %i"
+msgstr "Pts requis pour gagner : %i"
+
+#: client/gtk/gui.c:454
+msgid "<b>Messages</b>"
+msgstr "<b>Messages</b>"
+
+#. Tab page name
+#: client/gtk/gui.c:571 editor/gtk/editor.c:1165
+msgid "Map"
+msgstr "Carte"
+
+#. Tab page name
+#: client/gtk/gui.c:585 client/gtk/quote.c:306
+msgid "Quote"
+msgstr "Offre"
+
+#. Tab page name
+#: client/gtk/gui.c:593 client/gtk/legend.c:261
+msgid "Legend"
+msgstr "Légende"
+
+#. Tab page name, shown for the splash screen
+#: client/gtk/gui.c:603
+msgid "Welcome to Pioneers"
+msgstr "Bienvenue à Pioneers"
+
+#: client/gtk/gui.c:868
+msgid "Pioneers Preferences"
+msgstr "Préférences de Pioneers"
+
+#. Label for changing the theme, in the preferences dialog
+#: client/gtk/gui.c:898
+msgid "Theme:"
+msgstr "Thème :"
+
+#: client/gtk/gui.c:921
+msgid "Choose one of the themes"
+msgstr "Choisissez un thème"
+
+#. Label for the option to show the legend
+#: client/gtk/gui.c:925
+msgid "Show legend"
+msgstr "Afficher la légende"
+
+#. Tooltip for the option to show the legend
+#: client/gtk/gui.c:935
+msgid "Show the legend as a page beside the map"
+msgstr "Afficher la légende en dessous de la carte"
+
+#. Label for the option to display log messages in color
+#: client/gtk/gui.c:940
+msgid "Messages with color"
+msgstr "Afficher les messages en couleur"
+
+#: client/gtk/gui.c:950
+msgid "Show new messages with color"
+msgstr "Afficher les nouveaux messages en couleur"
+
+#: client/gtk/gui.c:955
+msgid "Chat in color of player"
+msgstr "Afficher les dialogues en couleur"
+
+#: client/gtk/gui.c:966
+msgid "Show new chat messages in the color of the player"
+msgstr "Afficher les nouveaux messages des joueurs en couleurs"
+
+#. Label for the option to display the summary with colors
+#: client/gtk/gui.c:971
+msgid "Summary with color"
+msgstr "Afficher les joueurs en couleur"
+
+#: client/gtk/gui.c:982
+msgid "Use colors in the player summary"
+msgstr "Utiliser des couleurs pour afficher les joueurs"
+
+#: client/gtk/gui.c:987
+msgid "Toolbar with shortcuts"
+msgstr "Barre d'outils avec ses raccorucis"
+
+#: client/gtk/gui.c:997
+msgid "Show keyboard shortcuts in the toolbar"
+msgstr "Afficher les raccourcis clavier dans la barre d'outils"
+
+#: client/gtk/gui.c:1003
+msgid "Announce new players"
+msgstr "Annoncer les nouveaux joueurs"
+
+#: client/gtk/gui.c:1014
+msgid "Make a sound when a new player or viewer enters the game"
+msgstr ""
+"Jouer un son quand un nouveau joueur ou un spectateur entre dans la partie"
+
+#. Label for the option to use the 16:9 layout.
+#: client/gtk/gui.c:1019
+msgid "Use 16:9 layout"
+msgstr "Utiliser un plateau de jeu 16:9"
+
+#: client/gtk/gui.c:1030
+msgid "Use a 16:9 friendly layout for the window"
+msgstr "Utiliser pour la fenêtre un plateau de jeu compatible 16:9"
+
+#: client/gtk/gui.c:1041
+msgid "The Pioneers Game"
+msgstr "Pioneers"
+
+#. Initial text in status bar
+#: client/gtk/gui.c:1352
+msgid "Welcome to Pioneers!"
+msgstr "Bienvenue dans Pioneers !"
+
+#. The name of the application
+#: client/gtk/gui.c:1463
+msgid "Pioneers"
+msgstr "Pioneers"
+
+#: client/gtk/histogram.c:252
+msgid "Dice Histogram"
+msgstr "Histogramme des lancers de dés"
+
+#: client/gtk/interface.c:92
+msgid "Ship movement canceled."
+msgstr "Déplacement du navire annulé"
+
+#: client/gtk/interface.c:100 client/gtk/interface.c:101
+msgid "Select a new location for the ship."
+msgstr "Choisissez un nouvel emplacement pour le navire"
+
+#: client/gtk/interface.c:740
+msgid "Select the ship to steal from"
+msgstr "Choisissez le navire à voler."
+
+#: client/gtk/interface.c:750
+msgid "Select the building to steal from"
+msgstr "Choisissez la construction à voler."
+
+#: client/gtk/legend.c:32
+msgid "Hill"
+msgstr "Colline"
+
+#: client/gtk/legend.c:33
+msgid "Field"
+msgstr "Champs"
+
+#: client/gtk/legend.c:34
+msgid "Mountain"
+msgstr "Montagne"
+
+#: client/gtk/legend.c:35
+msgid "Pasture"
+msgstr "Pré"
+
+#: client/gtk/legend.c:36
+msgid "Forest"
+msgstr "Forêt"
+
+#: client/gtk/legend.c:37
+msgid "Desert"
+msgstr "Désert"
+
+#: client/gtk/legend.c:38
+msgid "Sea"
+msgstr "Mer"
+
+#: client/gtk/legend.c:170
+msgid "<b>Terrain Yield</b>"
+msgstr "<b>Production des terrains</b>"
+
+#: client/gtk/legend.c:202
+msgid "<b>Building Costs</b>"
+msgstr "<b>Coûts de construction</b>"
+
+#: client/gtk/legend.c:243
+msgid "Development Card"
+msgstr "Carte de développement"
+
+#: client/gtk/monopoly.c:105
+msgid "Select the resource you wish to monopolise."
+msgstr "Choisissez la ressource à monopoliser"
+
+#: client/gtk/name.c:123
+msgid "Change player name"
+msgstr "Renommer"
+
+#: client/gtk/name.c:146
+msgid "Player Name:"
+msgstr "Nom du joueur :"
+
+#. Set icon preferences
+#: client/gtk/name.c:202
+msgid "Face:"
+msgstr "Figure :"
+
+#: client/gtk/name.c:217
+msgid "Variant:"
+msgstr "Variante :"
+
+#. Commandline option of client: name of the player
+#: client/gtk/offline.c:59
+msgid "Player name"
+msgstr "Nom du joueur"
+
+#: client/gtk/offline.c:63
+msgid "Connect as a viewer"
+msgstr "Se connecter en tant que spectateur"
+
+#: client/gtk/offline.c:66
+msgid "Meta-server Host"
+msgstr "Hôte du meta-serveur"
+
+#: client/gtk/offline.c:70
+msgid "Override the language of the system"
+msgstr "Passer outre le language défini dans le système"
+
+#: client/gtk/offline.c:100
+msgid "Connecting"
+msgstr "Connexion"
+
+#. Long description in the commandline for pioneers: help
+#: client/gtk/offline.c:175
+msgid "- Play a game of Pioneers"
+msgstr "- Jouer à une partie de Pionneers"
+
+#: client/gtk/player.c:52
+msgid "Settlements"
+msgstr "Colonies"
+
+#: client/gtk/player.c:53
+msgid "Cities"
+msgstr "Villes"
+
+#: client/gtk/player.c:54
+msgid "City Walls"
+msgstr "Remparts"
+
+#: client/gtk/player.c:55
+msgid "Largest Army"
+msgstr "Le chevalier le plus puissant"
+
+#: client/gtk/player.c:56
+msgid "Longest Road"
+msgstr "La route la plus longue"
+
+#: client/gtk/player.c:57
+msgid "Chapels"
+msgstr "Chapelles"
+
+#: client/gtk/player.c:58
+msgid "Pioneer Universities"
+msgstr "Universités"
+
+#: client/gtk/player.c:60
+msgid "Governor's Houses"
+msgstr "Palais du Gouverneur"
+
+#: client/gtk/player.c:61
+msgid "Libraries"
+msgstr "Bibliothèques"
+
+#: client/gtk/player.c:62
+msgid "Markets"
+msgstr "Marchés"
+
+#: client/gtk/player.c:63
+msgid "Soldiers"
+msgstr "Chevaliers"
+
+#: client/gtk/player.c:64
+msgid "Resource card"
+msgstr "Carte de ressource"
+
+#: client/gtk/player.c:64
+msgid "Resource cards"
+msgstr "Cartes de ressource"
+
+#: client/gtk/player.c:65
+msgid "Development card"
+msgstr "Carte de développement"
+
+#: client/gtk/player.c:65
+msgid "Development cards"
+msgstr "Cartes de développement"
+
+#. Caption for the overview of the points and card of other players
+#: client/gtk/player.c:561
+msgid "<b>Player Summary</b>"
+msgstr "<b>Les joueurs</b>"
+
+#: client/gtk/plenty.c:87
+msgid "Please choose one resource from the bank"
+msgstr "Prenez une ressource à la banque"
+
+#: client/gtk/plenty.c:90
+msgid "Please choose two resources from the bank"
+msgstr "Prenez deux ressources à la banque"
+
+#: client/gtk/plenty.c:92
+msgid "The bank is empty"
+msgstr "La banque est vide"
+
+#: client/gtk/quote.c:186
+#, c-format
+msgid "%s has %s, and is looking for %s"
+msgstr "%s a %s et cherche %s"
+
+#: client/gtk/quote.c:287
+msgid "I Want"
+msgstr "Je voudrais"
+
+#: client/gtk/quote.c:295
+msgid "Give Them"
+msgstr "Accepter"
+
+#: client/gtk/quote.c:311
+msgid "Delete"
+msgstr "Effacer"
+
+#: client/gtk/quote.c:335
+msgid "Reject Domestic Trade"
+msgstr "Refuser l'offre"
+
+#. Now create columns
+#. Table header: Player who trades
+#. Role of the player: player
+#: client/gtk/quote-view.c:170 server/gtk/main.c:513
+msgid "Player"
+msgstr "Joueur"
+
+#. Table header: Quote
+#: client/gtk/quote-view.c:185
+msgid "Quotes"
+msgstr "Offres"
+
+#. trade: maritime quote: %1 resources of type %2 for
+#. * one resource of type %3
+#: client/gtk/quote-view.c:292
+#, c-format
+msgid "%d:1 %s for %s"
+msgstr "%d : 1 %s pour %s"
+
+#. Trade: a player has rejected trade
+#: client/gtk/quote-view.c:431
+msgid "Rejected trade"
+msgstr "Offre refusée"
+
+#. Caption for overview of the resources of the player
+#: client/gtk/resource.c:113
+msgid "<b>Resources</b>"
+msgstr "<b>Ressources</b>"
+
+#: client/gtk/resource.c:129
+msgid "Total"
+msgstr "Total"
+
+#. Tooltip for the amount of resources in the hand
+#: client/gtk/resource-table.c:187
+msgid "Amount in hand"
+msgstr "Ressources en main"
+
+#: client/gtk/resource-table.c:191
+msgid "<less"
+msgstr "<moins"
+
+#. Tooltip for decreasing the selected amount
+#: client/gtk/resource-table.c:201
+msgid "Decrease the selected amount"
+msgstr "Diminuer le montant sélectionné"
+
+#. Tooltip for the amount of resources in the bank
+#: client/gtk/resource-table.c:215
+msgid "Amount in the bank"
+msgstr "Montant dans la banque"
+
+#: client/gtk/resource-table.c:219
+msgid "more>"
+msgstr "plus>"
+
+#. Tooltip for increasing the selected amount
+#: client/gtk/resource-table.c:231
+msgid "Increase the selected amount"
+msgstr "Augmenter le montant sélectionné"
+
+#. Tooltip for the selected amount
+#: client/gtk/resource-table.c:248
+msgid "Selected amount"
+msgstr "Montant sélectionné"
+
+#. Tooltip for the total selected amount
+#: client/gtk/resource-table.c:293
+msgid "Total selected amount"
+msgstr "Montant total sélectionné"
+
+#: client/gtk/resource-table.c:314
+msgid "The bank cannot be emptied"
+msgstr "La banque ne peut pas être vide"
+
+#: client/gtk/settingscreen.c:74
+msgid "Yes"
+msgstr "Oui"
+
+#: client/gtk/settingscreen.c:76 client/gtk/settingscreen.c:207
+msgid "No"
+msgstr "Non"
+
+#: client/gtk/settingscreen.c:87 client/gtk/settingscreen.c:174
+msgid "Unknown"
+msgstr "Inconnu"
+
+#: client/gtk/settingscreen.c:121
+msgid "No game in progress..."
+msgstr "Pas de parties en cours..."
+
+#: client/gtk/settingscreen.c:131
+msgid "<b>General Settings</b>"
+msgstr "<b>Paramètres généraux</b>"
+
+#: client/gtk/settingscreen.c:147
+msgid "Number of players:"
+msgstr "Nombre de joueurs :"
+
+#: client/gtk/settingscreen.c:150
+msgid "Victory Point Target:"
+msgstr "Pts de Victoire requis :"
+
+#: client/gtk/settingscreen.c:153
+msgid "Random Terrain?"
+msgstr "Carte aléatoire ?"
+
+#: client/gtk/settingscreen.c:156
+msgid "Interplayer Trading Allowed?"
+msgstr "Autoriser les échanges entre joueurs ?"
+
+#: client/gtk/settingscreen.c:160
+msgid "Trading allowed only before build/buy?"
+msgstr "Autoriser les échanges avant de construire ?"
+
+#: client/gtk/settingscreen.c:163
+msgid "Amount of Each Resource:"
+msgstr "Nombre de chaque ressource :"
+
+#: client/gtk/settingscreen.c:177
+msgid "Sevens Rule:"
+msgstr "Règle des sept :"
+
+#: client/gtk/settingscreen.c:181
+msgid "Use Pirate:"
+msgstr "Jouer avec le pirate :"
+
+#: client/gtk/settingscreen.c:209
+msgid "Island Discovery Bonuses:"
+msgstr "Bonus pour la découverte d'une île :"
+
+#: client/gtk/settingscreen.c:224
+msgid "<b>Building Quotas</b>"
+msgstr "<b>Constructions disponibles</b>"
+
+#: client/gtk/settingscreen.c:241
+msgid "Roads:"
+msgstr "Routes :"
+
+#: client/gtk/settingscreen.c:247
+msgid "Settlements:"
+msgstr "Colonies :"
+
+#: client/gtk/settingscreen.c:253
+msgid "Cities:"
+msgstr "Villes :"
+
+#: client/gtk/settingscreen.c:259
+msgid "City Walls:"
+msgstr "Remparts :"
+
+#: client/gtk/settingscreen.c:265
+msgid "Ships:"
+msgstr "Navires :"
+
+#: client/gtk/settingscreen.c:271
+msgid "Bridges:"
+msgstr "Ponts :"
+
+#: client/gtk/settingscreen.c:283
+msgid "<b>Development Card Deck</b>"
+msgstr "<b>Pioche des cartes de développement</b>"
+
+#: client/gtk/settingscreen.c:299
+msgid "Road Building Cards:"
+msgstr "Cartes Construction de routes :"
+
+#: client/gtk/settingscreen.c:303
+msgid "Monopoly Cards:"
+msgstr "Cartes Monopole :"
+
+#: client/gtk/settingscreen.c:307
+msgid "Year of Plenty Cards:"
+msgstr "Cartes Année faste :"
+
+#: client/gtk/settingscreen.c:312
+msgid "Chapel Cards:"
+msgstr "Cartes Chapelle :"
+
+#: client/gtk/settingscreen.c:316
+msgid "Pioneer University Cards:"
+msgstr "Cartes Université :"
+
+#: client/gtk/settingscreen.c:320
+msgid "Governor's House Cards:"
+msgstr "Cartes Palais du Gouverneur :"
+
+#: client/gtk/settingscreen.c:325
+msgid "Library Cards:"
+msgstr "Cartes Bibliothèque :"
+
+#: client/gtk/settingscreen.c:329
+msgid "Market Cards:"
+msgstr "Cartes Marché :"
+
+#: client/gtk/settingscreen.c:333
+msgid "Soldier Cards:"
+msgstr "Cartes Chevalier :"
+
+#: client/gtk/settingscreen.c:370
+msgid "Current Game Settings"
+msgstr "Paramètres de la partie en cours"
+
+#. trade: you ask for something for free
+#: client/gtk/trade.c:193
+#, c-format
+msgid "ask for %s for free"
+msgstr "demande %s gratuitement"
+
+#. trade: you give something away for free
+#: client/gtk/trade.c:198
+#, c-format
+msgid "give %s for free"
+msgstr "donne %s gratuitement"
+
+#. trade: you trade something for something else
+#: client/gtk/trade.c:203
+#, c-format
+msgid "give %s for %s"
+msgstr "donne %s contre %s"
+
+#. I want some resources, and give them some resources
+#: client/gtk/trade.c:230
+#, c-format
+msgid "I want %s, and give them %s"
+msgstr "Je voudrais %s, et donner %s"
+
+#. Frame title, trade: I want to trade these resources
+#: client/gtk/trade.c:427
+msgid "<b>I Want</b>"
+msgstr "<b>Je voudrais</b>"
+
+#. Frame title, trade: I want these resources in return
+#: client/gtk/trade.c:455
+msgid "<b>Give Them</b>"
+msgstr "<b>Accepter</b>"
+
+#. Button text, trade: call for quotes from other players
+#: client/gtk/trade.c:484
+msgid "_Call for Quotes"
+msgstr "_Appel d'offre"
+
+#. Button text: Trade page, accept selected quote
+#: client/gtk/trade.c:512
+msgid "_Accept Quote"
+msgstr "_Accepter l'offre"
+
+#. Button text: Trade page, finish trading
+#: client/gtk/trade.c:518
+msgid "_Finish Trading"
+msgstr "_Fin des échanges"
+
+#: common/gtk/aboutbox.c:74
+msgid ""
+"Pioneers is based upon the excellent\n"
+"Settlers of Catan board game.\n"
+msgstr ""
+"Pioneers est basé sur l'excellent\n"
+"jeu de plateau 'Les colons de Catan'.\n"
+
+#: common/gtk/aboutbox.c:83
+msgid "Homepage"
+msgstr "Page d'accueil"
+
+#: common/gtk/aboutbox.c:88
+msgid "Authors"
+msgstr "Ãcrit par"
+
+#. Tooltip for sevens rule normal
+#: common/gtk/game-rules.c:101
+msgid "All sevens move the robber or pirate"
+msgstr "Sur 7, il faut déplacer le voleur ou le pirate"
+
+#: common/gtk/game-rules.c:106
+msgid "In the first two turns all sevens are rerolled"
+msgstr "Durant les 2 premier tours, on relance les 7"
+
+#. Tooltip for sevens rule reroll all
+#: common/gtk/game-rules.c:110
+msgid "All sevens are rerolled"
+msgstr "Tous les 7 sont relancés"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize Terrain"
+msgstr "Carte aléatoire"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize the terrain"
+msgstr "Carte aléatoire"
+
+#: common/gtk/game-rules.c:123
+msgid "Use Pirate"
+msgstr "Jouer avec le pirate"
+
+#: common/gtk/game-rules.c:123
+msgid "Use the pirate to block ships"
+msgstr "Utiliser le pirate pour bloquer les bateaux"
+
+#: common/gtk/game-rules.c:125
+msgid "Strict Trade"
+msgstr "Ãchanges stricts"
+
+#: common/gtk/game-rules.c:126
+msgid "Allow trade only before building or buying"
+msgstr "Autoriser les échanges uniquement avant de construire ou d'acheter"
+
+#: common/gtk/game-rules.c:128
+msgid "Domestic Trade"
+msgstr "Ãchanges commerciaux"
+
+#: common/gtk/game-rules.c:128
+msgid "Allow trade between players"
+msgstr "Autoriser les échanges entre joueurs"
+
+#. Label text for customising a game
+#: common/gtk/game-settings.c:118
+msgid "Number of Players"
+msgstr "Nombre de joueurs"
+
+#. Tooltip for 'Number of Players'
+#: common/gtk/game-settings.c:136
+msgid "The number of players"
+msgstr "Nombre de joueurs"
+
+#. Label for customising a game
+#: common/gtk/game-settings.c:139
+msgid "Victory Point Target"
+msgstr "Pts de victoire requis"
+
+#. Tooltip for Victory Point Target
+#: common/gtk/game-settings.c:159
+msgid "The points needed to win the game"
+msgstr "Pts requis pour gagner : %i"
+
+#. Tooltip for the check button
+#: common/gtk/game-settings.c:172
+msgid "Is it possible to win this game?"
+msgstr "Est-il possible de gagner ce jeu ?"
+
+#. Port indicator for a resource: trade 2 for 1
+#: common/gtk/guimap.c:750
+msgid "2:1"
+msgstr "2:1"
+
+#. Port indicator: trade 3 for 1
+#. General port indicator
+#: common/gtk/guimap.c:753 common/gtk/guimap.c:778
+msgid "3:1"
+msgstr "3:1"
+
+#. Tooltip for the list of games
+#: common/gtk/select-game.c:111
+msgid "Select a game"
+msgstr "Serveurs récents"
+
+#: common/gtk/theme.c:709
+#, c-format
+msgid "bad scaling mode '%s'"
+msgstr "mauvais mode scalaire '%s'"
+
+#: common/game.c:603 common/game.c:633
+msgid "This game cannot be won."
+msgstr "Cette partie ne peut pas être gagnée."
+
+#: common/game.c:604
+msgid "There is no land."
+msgstr "Il n'y a pas de terrain."
+
+#: common/game.c:638
+msgid "It is possible that this game cannot be won."
+msgstr "Il est possible que ce jeu ne puissent pas être gagné."
+
+#: common/game.c:643
+msgid "This game can be won by only building all settlements and cities."
+msgstr ""
+"Cette partie ne peut pas être gagnée uniquement en construisant des colonies "
+"et des villes."
+
+#: common/game.c:650
+#, c-format
+msgid ""
+"Required victory points: %d\n"
+"Points obtained by building all: %d\n"
+"Points in development cards: %d\n"
+"Longest road/largest army: %d+%d\n"
+"Maximum island discovery bonus: %d\n"
+"Total: %d"
+msgstr ""
+"Points de victoire requis : %d\n"
+"Points obtenus en tout construisant : %d\n"
+"Points dans les cartes de développement : %d\n"
+"Route la plus longue / chevalier le plus puissant : %d+%d\n"
+"Bonus maximum pour la découverte d'iles : %d\n"
+"Total : %d"
+
+#: common/log.c:54
+msgid "*ERROR* "
+msgstr "*ERREUR*"
+
+#: common/log.c:60
+msgid "Chat: "
+msgstr "Dialogue : "
+
+#: common/log.c:63
+msgid "Resource: "
+msgstr "Ressources : "
+
+#: common/log.c:66
+msgid "Build: "
+msgstr "Construction : "
+
+#: common/log.c:69
+msgid "Dice: "
+msgstr "Dé : "
+
+#: common/log.c:72
+msgid "Steal: "
+msgstr "Vole : "
+
+#: common/log.c:75
+msgid "Trade: "
+msgstr "Echanges :"
+
+#: common/log.c:78
+msgid "Development: "
+msgstr "Carte de développement :"
+
+#: common/log.c:81
+msgid "Army: "
+msgstr "Armée : "
+
+#: common/log.c:84
+msgid "Road: "
+msgstr "Route :"
+
+#: common/log.c:87
+msgid "*BEEP* "
+msgstr "*BIP*"
+
+#: common/log.c:92
+msgid "Player 1: "
+msgstr "Joueur 1 : "
+
+#: common/log.c:95
+msgid "Player 2: "
+msgstr "Joueur 2 : "
+
+#: common/log.c:98
+msgid "Player 3: "
+msgstr "Joueur 3 : "
+
+#: common/log.c:101
+msgid "Player 4: "
+msgstr "Joueur 4 : "
+
+#: common/log.c:104
+msgid "Player 5: "
+msgstr "Joueur 5 : "
+
+#: common/log.c:107
+msgid "Player 6: "
+msgstr "Joueur 6 : "
+
+#: common/log.c:110
+msgid "Player 7: "
+msgstr "Joueur 7 : "
+
+#: common/log.c:113
+msgid "Player 8: "
+msgstr "Joueur 8 : "
+
+#: common/log.c:116
+msgid "Viewer: "
+msgstr "Spectateur : "
+
+#: common/log.c:119
+msgid "** UNKNOWN MESSAGE TYPE ** "
+msgstr "** TYPE DE MESSAGE INCONNU ** "
+
+#: common/network.c:281
+#, c-format
+msgid "Error checking connect status: %s\n"
+msgstr "Erreur lors de la vérification de la connexion : %s\n"
+
+#: common/network.c:288
+#, c-format
+msgid "Error connecting to host '%s': %s\n"
+msgstr "Erreur lors de la connexion à '%s' : %s\n"
+
+#: common/network.c:314
+#, c-format
+msgid "Error writing socket: %s\n"
+msgstr "Erreur lors de l'écriture du socket : %s\n"
+
+#: common/network.c:365
+#, c-format
+msgid "Error writing to socket: %s\n"
+msgstr "Erreur lors de l'écriture du socket : %s\n"
+
+#: common/network.c:418
+msgid "Read buffer overflow - disconnecting\n"
+msgstr "Débordement du tampon de lecture - déconnexion\n"
+
+#: common/network.c:428
+#, c-format
+msgid "Error reading socket: %s\n"
+msgstr "Erreur lors de la lecture du socket : %s\n"
+
+#: common/network.c:575
+#, c-format
+msgid "Cannot resolve %s port %s: %s\n"
+msgstr "Impossible de trouver le serveur %s port %s : %s\n"
+
+#: common/network.c:582
+#, c-format
+msgid "Cannot resolve %s port %s: host not found\n"
+msgstr "Impossible de trouver le serveur %s port %s : serveur introuvable\n"
+
+#: common/network.c:597
+#, c-format
+msgid "Error creating socket: %s\n"
+msgstr "Erreur lors de la création du socket : %s\n"
+
+#: common/network.c:605
+#, c-format
+msgid "Error setting socket close-on-exec: %s\n"
+msgstr "Erreur lors de la définition du socket 'close-on-exec' : %s\n"
+
+#: common/network.c:615 common/network.c:776
+#, c-format
+msgid "Error setting socket non-blocking: %s\n"
+msgstr "Erreur lors de la définition du socket 'non-blocking' : %s\n"
+
+#: common/network.c:640
+#, c-format
+msgid "Error connecting to %s: %s\n"
+msgstr "Erreur lors de la connexion à %s : %s\n"
+
+#: common/network.c:735
+#, c-format
+msgid "Error creating struct addrinfo: %s"
+msgstr "Erreur lors de la création de la structure addrinfo : %s"
+
+#: common/network.c:765
+#, c-format
+msgid "Error creating listening socket: %s\n"
+msgstr "Erreur lors de la création du socket d'écoute : %s\n"
+
+#: common/network.c:785
+#, c-format
+msgid "Error during listen on socket: %s\n"
+msgstr "Erreur lors de l'écoute sur le socket : %s\n"
+
+#: common/network.c:794
+msgid "Listening not yet supported on this platform."
+msgstr "L'écoute n'est pas encore supportée sur cette plate-forme."
+
+#: common/network.c:816 common/network.c:817
+msgid "unknown"
+msgstr "inconnu"
+
+#: common/network.c:823
+#, c-format
+msgid "Error getting peer name: %s"
+msgstr "Erreur en récupérant le nom du pair : %s"
+
+#: common/network.c:836
+#, c-format
+msgid "Error resolving address: %s"
+msgstr "Erreur durant la résolution de l'adresse : %s"
+
+#: common/network.c:850
+msgid "Net_get_peer_name not yet supported on this platform."
+msgstr "Net_get_peer_name n'est pas encore supporté sur cette plate-forme."
+
+#: common/network.c:865
+#, c-format
+msgid "Error accepting connection: %s"
+msgstr "Erreur en acceptant la connexion : %s"
+
+#: common/state.c:166
+#, c-format
+msgid "Connecting to %s, port %s\n"
+msgstr "Connexion à %s, port %s\n"
+
+#: common/state.c:503
+msgid "State stack overflow. Stack dump sent to standard error.\n"
+msgstr ""
+"Débordement de la pile d'état. Copie de la pile sur la sortie d'erreur.\n"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:73
+msgid "_Hill"
+msgstr "_Colline"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:75
+msgid "_Field"
+msgstr "C_hamps"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:77
+msgid "_Mountain"
+msgstr "_Montagne"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:79
+msgid "_Pasture"
+msgstr "_Pré"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:81
+msgid "F_orest"
+msgstr "F_orêt"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:83
+msgid "_Desert"
+msgstr "_Désert"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:85
+msgid "_Sea"
+msgstr "Me_r"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:87
+msgid "_Gold"
+msgstr "_Or"
+
+#. Use an unique shortcut key for each resource
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:89 editor/gtk/editor.c:104
+msgid "_None"
+msgstr "Aucu_n"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:94
+msgid "_Brick (2:1)"
+msgstr "_Argile (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:96
+msgid "_Grain (2:1)"
+msgstr "_Blé (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:98
+msgid "_Ore (2:1)"
+msgstr "_Pierre (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:100
+msgid "_Wool (2:1)"
+msgstr "_Laine (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:102
+msgid "_Lumber (2:1)"
+msgstr "B_ois (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:106
+msgid "_Any (3:1)"
+msgstr "N'importe _quoi (3:1)"
+
+#. East
+#: editor/gtk/editor.c:111
+msgid "East|E"
+msgstr "E"
+
+#. North east
+#: editor/gtk/editor.c:113
+msgid "North East|NE"
+msgstr "NE"
+
+#. North west
+#: editor/gtk/editor.c:115
+msgid "North West|NW"
+msgstr "NO"
+
+#. West
+#: editor/gtk/editor.c:117
+msgid "West|W"
+msgstr "O"
+
+#. South west
+#: editor/gtk/editor.c:119
+msgid "South West|SW"
+msgstr "SO"
+
+#. South east
+#: editor/gtk/editor.c:121
+msgid "South East|SE"
+msgstr "SE"
+
+#: editor/gtk/editor.c:564
+msgid "Shuffle"
+msgstr "Mélanger"
+
+#: editor/gtk/editor.c:696 server/gtk/main.c:450
+msgid "Game Parameters"
+msgstr "Paramètres de la partie"
+
+#: editor/gtk/editor.c:698 server/gtk/main.c:482
+msgid "Rules"
+msgstr "Règles"
+
+#: editor/gtk/editor.c:699
+msgid "Resources"
+msgstr "Ressources"
+
+#: editor/gtk/editor.c:700
+msgid "Buildings"
+msgstr "Constructions"
+
+#: editor/gtk/editor.c:701
+msgid "Development Cards"
+msgstr "Cartes de développement"
+
+#: editor/gtk/editor.c:718
+msgid "Pioneers Editor"
+msgstr "Ãditeur de partie"
+
+#: editor/gtk/editor.c:803
+#, c-format
+msgid "Failed to load '%s'"
+msgstr "N'a pas réussi à charger '%s'"
+
+#: editor/gtk/editor.c:843
+#, c-format
+msgid "Failed to save to '%s'"
+msgstr "N'a pas réussi à enregistrer '%s'"
+
+#: editor/gtk/editor.c:858
+msgid "Open Game"
+msgstr "Ouvrir une partie"
+
+#: editor/gtk/editor.c:884
+msgid "Save as..."
+msgstr "Enregistrer sous..."
+
+#: editor/gtk/editor.c:919
+msgid "Change Title"
+msgstr "Changer le nom"
+
+#: editor/gtk/editor.c:941
+msgid "New Title:"
+msgstr "Nouveau nom :"
+
+#: editor/gtk/editor.c:997
+msgid "Pioneers Game Editor"
+msgstr "Ãditeur de partie"
+
+#: editor/gtk/editor.c:1001
+msgid "_File"
+msgstr "_Fichier"
+
+#: editor/gtk/editor.c:1004
+msgid "_New"
+msgstr "_Nouveau"
+
+#: editor/gtk/editor.c:1005
+msgid "Create a new game"
+msgstr "Créer une nouvelle partie"
+
+#: editor/gtk/editor.c:1006
+msgid "_Open..."
+msgstr "_Ouvrir..."
+
+#: editor/gtk/editor.c:1007
+msgid "Open an existing game"
+msgstr "Ouvrir une partie existante"
+
+#: editor/gtk/editor.c:1008
+msgid "_Save"
+msgstr "Enregi_strer"
+
+#: editor/gtk/editor.c:1009
+msgid "Save game"
+msgstr "Enregistrer une partie"
+
+#: editor/gtk/editor.c:1010
+msgid "Save _As..."
+msgstr "Enregistrer sous..."
+
+#: editor/gtk/editor.c:1012
+msgid "Save as"
+msgstr "Enregistrer sous"
+
+#: editor/gtk/editor.c:1013
+msgid "_Change title"
+msgstr "_Changer le nom"
+
+#: editor/gtk/editor.c:1014
+msgid "Change game title"
+msgstr "Changer le nom de la partie"
+
+#: editor/gtk/editor.c:1015 server/gtk/main.c:100
+msgid "_Check Victory Point Target"
+msgstr "Vérifier les points de vi_ctoire requis"
+
+#: editor/gtk/editor.c:1017 server/gtk/main.c:102
+msgid "Check whether the game can be won"
+msgstr "Vérifier si le jeu peut être gagné"
+
+#: editor/gtk/editor.c:1019
+msgid "Quit"
+msgstr "Quitter"
+
+#: editor/gtk/editor.c:1027
+msgid "_About Pioneers Editor"
+msgstr "_à propos de l'éditeur de partie"
+
+#: editor/gtk/editor.c:1028
+msgid "Information about Pioneers Editor"
+msgstr "Informations à propos de l'éditeur de partie"
+
+#. Long help for commandline option (editor): filename
+#: editor/gtk/editor.c:1066
+msgid "Open this file"
+msgstr "Ouvrir le fichier"
+
+#. Commandline option for editor: filename
+#: editor/gtk/editor.c:1068
+msgid "filename"
+msgstr "nom de fichier"
+
+#: editor/gtk/editor.c:1100
+msgid "- Editor for games of Pioneers"
+msgstr "- Editeur de parties pour Pioneers"
+
+#: editor/gtk/editor.c:1141 server/gtk/main.c:1035
+#, c-format
+msgid "Building menus failed: %s"
+msgstr "Ãchec de la construction des menus : %s"
+
+#: editor/gtk/editor.c:1169
+msgid "Settings"
+msgstr "Préférences"
+
+#: editor/gtk/game-resources.c:51
+msgid "Resource Count"
+msgstr "Nombre de ressources"
+
+#. Commandline meta-server: daemon
+#: meta-server/main.c:1033
+msgid "Daemonize the metaserver on start"
+msgstr "Démoniser le meta-serveur au démarrage"
+
+#. Commandline meta-server: redirect
+#: meta-server/main.c:1036
+msgid "Redirect clients to another metaserver"
+msgstr "Rediriger les clients vers un autre meta-serveur"
+
+#. Commandline meta-server: server
+#: meta-server/main.c:1039
+msgid "Use this hostname when creating new games"
+msgstr "Utiliser ce nom d'hôte lors de la création de nouvelles parties"
+
+#. Commandline meta-server: server argument
+#: meta-server/main.c:1041
+msgid "hostname"
+msgstr "nom d'hôte"
+
+#. Commandline meta-server: port-range
+#: meta-server/main.c:1044
+msgid "Use this ports range when creating new games"
+msgstr "Utiliser cette plage de ports lors de la création de nouvelles parties"
+
+#. Commandline meta-server: port-range argument
+#: meta-server/main.c:1046
+msgid "from-to"
+msgstr "de-Ã "
+
+#. Commandline option of meta server: syslog-debug
+#: meta-server/main.c:1052
+msgid "Debug syslog messages"
+msgstr "Messages de débogage système (syslog)"
+
+#. Long description in the commandline for server-console: help
+#: meta-server/main.c:1073
+msgid "- Meta server for Pioneers"
+msgstr "- Meta-serveur pour Pioneers"
+
+#: meta-server/main.c:1088
+#, c-format
+msgid "metaserver protocol:"
+msgstr "protocole du meta-serveur"
+
+#: server/gtk/main.c:105
+msgid "_About Pioneers Server"
+msgstr "_Ã propos du serveur de Pioneers"
+
+#: server/gtk/main.c:106
+msgid "Information about Pioneers Server"
+msgstr "Information sur le serveur de Pioneers"
+
+#: server/gtk/main.c:222
+msgid "Stop server"
+msgstr "Arrêter le serveur"
+
+#: server/gtk/main.c:223
+msgid "Start server"
+msgstr "Démarrer le serveur"
+
+#: server/gtk/main.c:225
+msgid "Stop the server"
+msgstr "Arrêter le serveur"
+
+#: server/gtk/main.c:226
+msgid "Start the server"
+msgstr "Démarrer le serveur"
+
+#: server/gtk/main.c:351
+#, c-format
+msgid "Player %s from %s entered\n"
+msgstr "Arrivé du joueur %s depuis %s\n"
+
+#: server/gtk/main.c:358
+#, c-format
+msgid "Player %s from %s left\n"
+msgstr "Départ du joueur %s depuis %s\n"
+
+#: server/gtk/main.c:365
+#, c-format
+msgid "Player %d is now %s\n"
+msgstr "Le joueur %d s'appelle maintenant %s\n"
+
+#: server/gtk/main.c:554
+msgid "Game Settings"
+msgstr "Paramètres de la partie"
+
+#: server/gtk/main.c:600
+msgid "Server Parameters"
+msgstr "Paramètres du serveur"
+
+#: server/gtk/main.c:626
+msgid "The port for the game server"
+msgstr "Le port du serveur"
+
+#: server/gtk/main.c:629
+msgid "Register Server"
+msgstr "Annoncer le serveur"
+
+#: server/gtk/main.c:637
+msgid "Register this game at the meta server"
+msgstr "Annoncer cette partie sur le meta-serveur"
+
+#: server/gtk/main.c:654
+msgid "The address of the meta server"
+msgstr "L'adresse du meta-serveur"
+
+#: server/gtk/main.c:656
+msgid "Reported Hostname"
+msgstr "Nom de l'ordinateur"
+
+#: server/gtk/main.c:671
+msgid ""
+"The public name of this computer (needed when playing behind a firewall)"
+msgstr ""
+"Le nom de cet ordinateur (nécessaire pour jouer depuis derrière un pare-feu)"
+
+#: server/gtk/main.c:675
+msgid "Random Turn Order"
+msgstr "Tour de jeu aléatoire"
+
+#: server/gtk/main.c:683
+msgid "Randomize turn order"
+msgstr "Rendre les tours de jeu aléatoires"
+
+#: server/gtk/main.c:722
+msgid "Running Game"
+msgstr "Partie en cours"
+
+#: server/gtk/main.c:724
+msgid "Players Connected"
+msgstr "Joueurs connectés"
+
+#: server/gtk/main.c:758
+msgid "Shows all players and viewers connected to the server"
+msgstr "Montrer tous les joueurs et spectateurs connectés à ce serveur"
+
+#: server/gtk/main.c:763
+msgid "Connected"
+msgstr "Connecté"
+
+#: server/gtk/main.c:770
+msgid "Is the player currently connected?"
+msgstr "Est-ce que le joueur est bien connecté ?"
+
+#: server/gtk/main.c:773
+msgid "Name"
+msgstr "Nom"
+
+#: server/gtk/main.c:780
+msgid "Name of the player"
+msgstr "Nom du joueur"
+
+#: server/gtk/main.c:782
+msgid "Location"
+msgstr "Adresse"
+
+#: server/gtk/main.c:789
+msgid "Host name of the player"
+msgstr "Adresse du joueur"
+
+#: server/gtk/main.c:793
+msgid "Number"
+msgstr "Nombre"
+
+#: server/gtk/main.c:800
+msgid "Player number"
+msgstr "Nombre de joueurs"
+
+#: server/gtk/main.c:804
+msgid "Role"
+msgstr "Rôle"
+
+#: server/gtk/main.c:808
+msgid "Player of viewer"
+msgstr "Joueur"
+
+#: server/gtk/main.c:819
+msgid "Launch Pioneers Client"
+msgstr "Lancer le client Pioneers"
+
+#: server/gtk/main.c:826
+msgid "Launch the Pioneers Client"
+msgstr "Lancer le client Pioneers"
+
+#: server/gtk/main.c:828
+msgid "Computer Players"
+msgstr "IA"
+
+#: server/gtk/main.c:837
+msgid "Enable Chat"
+msgstr "Dialogue autorisé"
+
+#: server/gtk/main.c:843
+msgid "Enable chat messages"
+msgstr "Autoriser les messages"
+
+#: server/gtk/main.c:850
+msgid "Add Computer Player"
+msgstr "Ajouter une IA"
+
+#: server/gtk/main.c:857
+msgid "Add a computer player to the game"
+msgstr "Ajouter une IA"
+
+#: server/gtk/main.c:866
+msgid "Messages"
+msgstr "Messages"
+
+#: server/gtk/main.c:884
+msgid "Messages from the server"
+msgstr "Messaage du serveur"
+
+#: server/gtk/main.c:932
+msgid "The Pioneers Game Server"
+msgstr "Le serveur Pioneers"
+
+#. Wait for all players to disconnect,
+#. * then enable the UI
+#.
+#: server/gtk/main.c:940
+msgid "The game is over.\n"
+msgstr "La partie est terminée.\n"
+
+#. Long description in the commandline for server-gtk: help
+#. Long description in the commandline for server-console: help
+#: server/gtk/main.c:994 server/main.c:174
+msgid "- Host a game of Pioneers"
+msgstr "- Héberger une partie de Pioneers"
+
+#. Name in the titlebar of the server
+#: server/gtk/main.c:1016
+msgid "Pioneers Server"
+msgstr "Serveur Pioneers"
+
+#. Commandline server-console: game-title
+#: server/main.c:75
+msgid "Game title to use"
+msgstr "Nom de la partie"
+
+#. Commandline server-console: file
+#: server/main.c:78
+msgid "Game file to use"
+msgstr "Fichier de partie à utiliser"
+
+#. Commandline server-console: port
+#: server/main.c:81
+msgid "Port to listen on"
+msgstr "Port à écouter"
+
+#. Commandline server-console: players
+#: server/main.c:84
+msgid "Override number of players"
+msgstr "Outrepasser le nombre de joueurs"
+
+#. Commandline server-console: points
+#: server/main.c:87
+msgid "Override number of points needed to win"
+msgstr "Outrepasser le nombre de points requis pour gagner"
+
+#. Commandline server-console: seven-rule
+#: server/main.c:90
+msgid "Override seven-rule handling"
+msgstr "Outrepasser la gestion de la règle des 7"
+
+#. Commandline server-console: terrain
+#: server/main.c:93
+msgid "Override terrain type, 0=default 1=random"
+msgstr "Outrepasser le type de terrain : 0 = défaut, 1 = aléatoire"
+
+#. Commandline server-console: computer-players
+#: server/main.c:96
+msgid "Add N computer players"
+msgstr "Ajouter N joueurs IA"
+
+#. Commandline server-console: register
+#: server/main.c:106
+msgid "Register server with meta-server"
+msgstr "Annoncer cette partie sur le meta-serveur"
+
+#. Commandline server-console: meta-server
+#: server/main.c:109
+msgid "Register at meta-server name (implies -r)"
+msgstr "Nom du meta-serveur d'enregistrement (implique -r)"
+
+#. Commandline server-console: hostname
+#: server/main.c:113
+msgid "Use this hostname when registering"
+msgstr "Utiliser ce nom d'hôte lors de l'enregistrement"
+
+#. Commandline server-console: auto-quit
+#: server/main.c:120
+msgid "Quit after a player has won"
+msgstr "Quitter après qu'un joueur ait gagné"
+
+#. Commandline server-console: empty-timeout
+#: server/main.c:123
+msgid "Quit after N seconds with no players"
+msgstr "Quitter après N secondes sans joueurs"
+
+#. Commandline server-console: tournament
+#: server/main.c:126
+msgid "Tournament mode, computer players added after N minutes"
+msgstr "Mode tournoi, joueurs AI ajoutés après N minutes"
+
+#. Commandline server-console: admin-port
+#: server/main.c:130
+msgid "Admin port to listen on"
+msgstr "Port à écouter pour l'administration"
+
+#: server/main.c:134
+msgid "Don't start game immediately, wait for a command on admin port"
+msgstr ""
+"Ne pas démarrer la partie immédiatement, attendre une commande sur le port "
+"d'administration"
+
+#: server/main.c:140
+msgid "Give players numbers according to the order they enter the game"
+msgstr ""
+"Attribuer aux joueurs un numéro selon leur ordre d'arrivée dans la partie"
+
+#. Commandline server-console: Short description of meta group
+#: server/main.c:180
+msgid "Meta-server Options"
+msgstr "Options du meta-serveur"
+
+#: server/main.c:183
+msgid "Options for the meta-server"
+msgstr "Options du meta-serveur"
+
+#. Commandline server-console: Short description of misc group
+#: server/main.c:191
+msgid "Miscellaneous Options"
+msgstr "Options Diverses"
+
+#. Commandline server-console: Long description of misc group
+#: server/main.c:193
+msgid "Miscellaneous options"
+msgstr "Options diverses"
+
+#: server/meta.c:193
+#, c-format
+msgid "Register with meta-server at %s, port %s\n"
+msgstr "Annoncé sur le meta-serveur : %s, port %s\n"
+
+#: server/meta.c:210
+msgid "Unregister from meta-server\n"
+msgstr "Se désinscrire du meta-serveur\n"
+
+#: server/player.c:130
+msgid "chat too long"
+msgstr "dialogue trop long"
+
+#: server/player.c:147
+msgid "name too long"
+msgstr "nom trop grand"
+
+#: server/player.c:179
+msgid "ignoring unknown extension"
+msgstr "ignorer les extensions inconnues"
+
+#: server/player.c:209
+msgid "Game starts, adding computer players"
+msgstr "La partie démarre, ajout des IA"
+
+#: server/player.c:234
+#, c-format
+msgid "The game starts in %s minutes."
+msgstr "La partie démarre dans %s minutes."
+
+#: server/player.c:235
+#, c-format
+msgid "The game starts in %s minute."
+msgstr "La partie démarre dans %s minute."
+
+#: server/player.c:280
+msgid "Sorry, game is over."
+msgstr "La partie est terminée."
+
+#: server/player.c:283
+#, c-format
+msgid "Player from %s is refused: game is over\n"
+msgstr "Le joueur depuis %s a été rejeté : la partie est terminée\n"
+
+#: server/player.c:331
+msgid "This game will start soon."
+msgstr "La partie va bientôt démarrer."
+
+#: server/player.c:359
+msgid "Name not changed: new name is already in use"
+msgstr "Le nom n'a pas été changé : le nouveau nom est déjà pris"
+
+#. %s is the name of the reconnecting player
+#: server/player.c:648
+#, c-format
+msgid "%s has reconnected."
+msgstr "%s s'est reconnecté."
+
+#: server/player.c:776
+#, c-format
+msgid "Version mismatch: %s"
+msgstr "Versions incompatibles : %s"
+
+#: server/server.c:47
+msgid "Was hanging around for too long without players... bye.\n"
+msgstr ""
+"Le serveur fonctionne depuis trop longtemps sans qu'il n'y ait de joueurs... "
+"Au revoir.\n"
+
+#. Server: preparing game #.....
+#: server/server.c:219
+msgid "Preparing game"
+msgstr "Préparation de la partie"
+
+#: server/server.c:337
+msgid "Missing game directory\n"
+msgstr "Répertoire du jeu absent\n"
+
+#: server/turn.c:253
+msgid "Island Discovery Bonus"
+msgstr "Bonus de découverte d'île"
+
+#: server/turn.c:256
+msgid "Additional Island Bonus"
+msgstr "Bonus dîle supplémentaire"
+
+#: server/turn.c:388
+msgid "Tried to assign resources to NULL player.\n"
+msgstr "tentative d'attribuer des ressources au joueur NULL.\n"
+
+#~ msgid "Brick port|B"
+#~ msgstr "A"
+
+#~ msgid "Grain port|G"
+#~ msgstr "Bl"
+
+#~ msgid "Ore port|O"
+#~ msgstr "P"
+
+#~ msgid "Wool port|W"
+#~ msgstr "L"
+
+#~ msgid "Lumber port|L"
+#~ msgstr "Bo"
+
+#~ msgid "Continue with your turn."
+#~ msgstr "Continuez votre tour."
+
+#~ msgid "Map Terrain"
+#~ msgstr "Carte"
+
+#~ msgid "Default map or a random map"
+#~ msgstr "Carte par défaut ou carte aléatoire"
+
+#~ msgid "NOTE Expecting version %s, not %s\n"
+#~ msgstr "NOTE On attendait la version %s et non pas %s\n"
+
+#~ msgid "Pixmap not found: %s\n"
+#~ msgstr "Pixmap introuvable: %s\n"
+
+#~ msgid "Only server or port set, ignoring command line"
+#~ msgstr ""
+#~ "Seul le serveur ou le port a été défini, la ligne de commande a été "
+#~ "ignorée"
+
+#~ msgid "Could not initialize default theme."
+#~ msgstr "Impossible d'initialiser le thème par défaut"
+
+#~ msgid "Theme %s not loaded due to errors."
+#~ msgstr "Le thème %s n'a pas pu être chargé a cause d'une erreur."
+
+#~ msgid "Could not find '%s' pixmap file in theme '%s'."
+#~ msgstr "Impossible de trouver le pixmap %s (%s)."
+
+#~ msgid "Could not load '%s' pixmap file in theme '%s'."
+#~ msgstr "Impossible de charger le pixmap %s (%s)."
+
+#~ msgid "Could not find default pixmap file: %s"
+#~ msgstr "Impossible de trouver le pixmap %s."
+
+#~ msgid "While reading %s at line %d:"
+#~ msgstr "En lisant %s à la ligne %d:"
+
+#~ msgid "variable name missing: %s"
+#~ msgstr "nom de variable manquant: %s"
+
+#~ msgid "unknown config variable '%s'"
+#~ msgstr "variable inconnue '%s'"
+
+#~ msgid "'=' missing: %s"
+#~ msgstr "'=' manquant: %s"
+
+#~ msgid "missing value"
+#~ msgstr "valeur manquante"
+
+#~ msgid "invalid color: %s"
+#~ msgstr "couleur incorrecte: %s"
+
+#~ msgid "unexpected rest at end of line: '%s'"
+#~ msgstr "problème à la fin de la ligne %s"
+
+#~ msgid "No usable version of WinSock was found."
+#~ msgstr "Aucune version exploitable de WinSock n'a été trouvée."
+
+#~ msgid "State stack overflow"
+#~ msgstr "Débordement de la pile d'état"
+
+#~ msgid "Development Card Deck"
+#~ msgstr "Pioche des cartes de développement"
+
+#~ msgid "%s receives %s\n"
+#~ msgstr "%s reçoit %s\n"
+
+#~ msgid "%s spent %s\n"
+#~ msgstr "%s dépense %s\n"
+
+#~ msgid "%s is refunded %s\n"
+#~ msgstr "%2s est remboursé de %1s\n"
+
+#~ msgid "%s discarded %s\n"
+#~ msgstr "%s jete %s\n"
+
+#~ msgid "Sorry, I do not know how to play with gold.\n"
+#~ msgstr "Désolé, je sais pas jouer avec l'or.\n"
+
+#~ msgid "Player %d is now anonymous.\n"
+#~ msgstr "Le joueur %d devient anonyme.\n"
+
+#~ msgid "%s is now anonymous.\n"
+#~ msgstr "%s devient anonyme.\n"
+
+#~ msgid "%s moved robber.\n"
+#~ msgstr "%s déplace le voleur.\n"
+
+#~ msgid "ask"
+#~ msgstr "demande"
+
+#~ msgid "give "
+#~ msgstr "donne "
+
+#~ msgid "for free"
+#~ msgstr "gratuitement"
+
+#~ msgid " for "
+#~ msgstr " pour "
+
+#~ msgid "Trading started by %s\n"
+#~ msgstr "%s propose des échanges.\n"
+
+#~ msgid "Trading restarted by %s\n"
+#~ msgstr "%s repropose des échanges.\n"
+
+#~ msgid "Quote from player %d: %s.\n"
+#~ msgstr "Offre du joueur %d: %s.\n"
+
+#~ msgid "Removed quote from player %d: %s\n"
+#~ msgstr "Offre annulée du joueur %d: %s\n"
+
+#~ msgid "Trading finished.\n"
+#~ msgstr "Fin des échanges.\n"
+
+#~ msgid "Cannot determine bank, expect out of resource errors\n"
+#~ msgstr ""
+#~ "Impossible de connaître le montant de la banque, attendez-vous à des "
+#~ "erreurs de ressources\n"
+
+#~ msgid "Warning - there are shortages."
+#~ msgstr "Attention, il y a une rupture de stocks !"
+
+#~ msgid "Resource to take"
+#~ msgstr "Ressource à prendrer"
+
+#~ msgid "color must be 'none' or start with '#': %s"
+#~ msgstr "la couleur doit être 'none' ou bien commencer par '#': %s"
+
+#~ msgid "color value contains non-hex character '%c'"
+#~ msgstr "la couleur contient de caractères non-héxadécimaux: '%c'"
+
+#~ msgid "bits per color component must be 4, 8, 12, or 16: #%s"
+#~ msgstr "les bits de couleurs doivent être 4, 8, 12 ou 16: #%s"
+
+#~ msgid "Create a new public game"
+#~ msgstr "Créer une nouvelle partie publique"
+
+#~ msgid "Take"
+#~ msgstr "Prend"
+
+#~ msgid "Hand"
+#~ msgstr "Main"
+
+#~ msgid "Discards"
+#~ msgstr "Jete"
+
+#~ msgid "(C) 2002 the Free Software Foundation"
+#~ msgstr "© 2002 Free Software Foundation"
+
+#~ msgid "Player _Name"
+#~ msgstr "_Nom du joueur"
+
+#~ msgid "Appearance"
+#~ msgstr "Apparence"
+
+#~ msgid "Text Only"
+#~ msgstr "Seulement du texte"
+
+#~ msgid "Icons Only"
+#~ msgstr "Seulement des icônes"
+
+#~ msgid "Both Icons and Text"
+#~ msgstr "Des icônes et du texte"
+
+#~ msgid "Color Settings"
+#~ msgstr "Jeu de couleurs"
+
+#~ msgid "Display chat messages in user's color?"
+#~ msgstr "Afficher les messages du chat dans les couleurs des utilisateurs?"
+
+#~ msgid "Language"
+#~ msgstr "Langue"
+
+#~ msgid "Language setting takes full effect only after client restart!"
+#~ msgstr ""
+#~ "Le changement de langue prendra effet seulement après un redémarrage!"
+
+#~ msgid "Resource Type"
+#~ msgstr "Type de ressource"
+
+#~ msgid "E_xit"
+#~ msgstr "_Quitter"
+
+#~ msgid "Game Name"
+#~ msgstr "Nom de la partie"
+
+#~ msgid "Query Meta Server"
+#~ msgstr "Interroger le meta-serveur"
+
+#~ msgid "Start Server"
+#~ msgstr "Démarrer le serveur"
+
+#~ msgid "no Resource (bug)"
+#~ msgstr "pas de ressources (bug)"
+
+#~ msgid "%s took %s from"
+#~ msgstr "%s prends %s à "
+
+#~ msgid " stole a resource from "
+#~ msgstr "vole une ressource à "
+
+#~ msgid "Create New Server"
+#~ msgstr "Créer un nouveau serveur"
+
+#~ msgid "Game is full"
+#~ msgstr "On a tout le monde qui nous faut!"
Added: trunk/po/hu.po
===================================================================
--- trunk/po/hu.po (rev 0)
+++ trunk/po/hu.po 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,3105 @@
+# Pioneers - Settlers of Catan for GNOME.
+# Copyright (C) 1999-2001 Dave Cole
+# Copyright (C) 2000-2002 Andy Heroff
+# This file is distributed under the same license as the pioneers package.
+# Ferenc Bánhidi <bferike at mailbox.hu>, 2005-2007.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Pioneers 0.11.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-07 20:43+0200\n"
+"PO-Revision-Date: 2007-07-20 05:47+0100\n"
+"Last-Translator: Ferenc Bánhidi <bferike at mailbox.hu>\n"
+"Language-Team: Hungarian <bferike at mailbox.hu>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Poedit-Language: Hungarian\n"
+"X-Poedit-Country: HUNGARY\n"
+
+#. Default name for the AI when the computer_names file
+#. * is not found or empty.
+#.
+#: client/ai/ai.c:74 client/ai/ai.c:90
+msgid "Computer Player"
+msgstr "Számítógép játékos"
+
+#. Commandline pioneersai: server
+#. Commandline option of client: hostname of the server
+#: client/ai/ai.c:102 client/gtk/connect.c:1462 client/gtk/offline.c:53
+msgid "Server Host"
+msgstr "Szerver gép"
+
+#. Commandline pioneersai: port
+#. Commandline option of client: port of the server
+#: client/ai/ai.c:105 client/gtk/connect.c:1478 client/gtk/offline.c:56
+#: server/gtk/main.c:612
+msgid "Server Port"
+msgstr "Szerver port"
+
+#. Commandline pioneersai: name
+#: client/ai/ai.c:108
+msgid "Computer name (leave absent for random name)"
+msgstr "Játékos neve (véletlen névhez hagyd üresen)"
+
+#. Commandline pioneersai: time
+#: client/ai/ai.c:111
+msgid "Time to wait between turns (in milliseconds)"
+msgstr "Körök között ennyit vár (milliszekundumban)"
+
+#. Commandline pioneersai: chat-free
+#: client/ai/ai.c:114
+msgid "Stop computer player from talking"
+msgstr "Robot játékos nem beszél"
+
+#. Commandline pioneersai: algorithm
+#: client/ai/ai.c:117
+msgid "Type of computer player"
+msgstr "A játékos típusa"
+
+#. Commandline option of ai: enable debug logging
+#. Commandline option of client: enable debug logging
+#. Commandline option of meta server: enable debug logging
+#. Commandline option of server-gtk: enable debug logging
+#. Commandline option of server: enable debug logging
+#: client/ai/ai.c:120 client/gtk/offline.c:74 meta-server/main.c:1049
+#: server/gtk/main.c:952 server/main.c:144
+msgid "Enable debug messages"
+msgstr "Debug üzenetek engedélyezése"
+
+#. Commandline option of ai: version
+#. Commandline option of client: version
+#. Commandline option of editor: version
+#. Commandline option of meta server: version
+#. Commandline option of server-gtk: version
+#. Commandline option of server-console: version
+#: client/ai/ai.c:123 client/gtk/offline.c:77 editor/gtk/editor.c:1071
+#: meta-server/main.c:1055 server/gtk/main.c:955 server/main.c:99
+msgid "Show version information"
+msgstr "Verzió információ"
+
+#: client/ai/ai.c:134
+msgid "- Computer player for Pioneers"
+msgstr "- Robot játékos a Pioneers játékhoz"
+
+#: client/ai/ai.c:144 client/gtk/offline.c:186 editor/gtk/editor.c:1111
+#: meta-server/main.c:1084 server/gtk/main.c:1005 server/main.c:206
+#, c-format
+msgid "Pioneers version:"
+msgstr "Pioneers verzió"
+
+#: client/ai/ai.c:176
+#, c-format
+msgid "Type of computer player: %s\n"
+msgstr "Robot játékos típusa: %s\n"
+
+#: client/ai/ai.c:205
+msgid "The game is already full. I'm leaving."
+msgstr "Ez a játék már megtelt. Távozom."
+
+#: client/ai/greedy.c:941
+msgid "No settlements in stock to use for setup"
+msgstr "Nincsenek települések a készletben"
+
+#: client/ai/greedy.c:948
+msgid "There is no place to setup a settlement"
+msgstr "Nincs hely beállítani egy települést"
+
+#: client/ai/greedy.c:972
+msgid "No roads in stock to use for setup"
+msgstr "Nincsenek utak raktáron, melyek használhatók a beállításhoz"
+
+#: client/ai/greedy.c:989
+msgid "There is no place to setup a road"
+msgstr "Nincs hely beállíani egy utat"
+
+#: client/ai/greedy.c:1291
+msgid "Ok, let's go!"
+msgstr "Oké, na rajta!"
+
+#: client/ai/greedy.c:1292
+msgid "I'll beat you all now! ;)"
+msgstr "Most mindenkit legyõzök ;)"
+
+#: client/ai/greedy.c:1293
+msgid "Now for another try..."
+msgstr "Most még egy kísérlet..."
+
+#: client/ai/greedy.c:1297
+msgid "At least I get something..."
+msgstr "Legalább kapok valami keveset..."
+
+#: client/ai/greedy.c:1298
+msgid "One is better than none..."
+msgstr "Egy több mint a semmi..."
+
+#: client/ai/greedy.c:1302
+msgid "Wow!"
+msgstr "Remek!"
+
+#: client/ai/greedy.c:1303
+msgid "Ey, I'm becoming rich ;)"
+msgstr "Én leszek a legjobb ;)"
+
+#: client/ai/greedy.c:1304
+msgid "This is really a good year!"
+msgstr "Ez valóban egy jó év!"
+
+#: client/ai/greedy.c:1307
+msgid "You really don't deserve that much!"
+msgstr "Te valóban nem érdemelsz többet!"
+
+#: client/ai/greedy.c:1308
+msgid "You don't know what to do with that many resources ;)"
+msgstr "Nem tudsz mit csinálni a rengeteg nyersanyaggal ;)"
+
+#: client/ai/greedy.c:1309
+msgid "Ey, wait for my robber and lose all this again!"
+msgstr "Na, várj csak majd kirabollak, és elveszítesz mindent újból!"
+
+#: client/ai/greedy.c:1312
+msgid "Hehe!"
+msgstr "Hehe!"
+
+#: client/ai/greedy.c:1313
+msgid "Go, robber, go!"
+msgstr "Menj, rabló menj!"
+
+#: client/ai/greedy.c:1316
+msgid "You bastard!"
+msgstr "Szemét!"
+
+#: client/ai/greedy.c:1317
+msgid "Can't you move that robber somewhere else?!"
+msgstr "Nem tennéd a rablót valahová máshová?!"
+
+#: client/ai/greedy.c:1318
+msgid "Why always me??"
+msgstr "Miért mindig én??"
+
+#: client/ai/greedy.c:1321
+msgid "Oh no!"
+msgstr "Ó, ne!"
+
+#: client/ai/greedy.c:1322
+msgid "Grrr!"
+msgstr "Grrr!"
+
+#: client/ai/greedy.c:1323
+msgid "Who the hell rolled that 7??"
+msgstr "Ki a bánat dobta azt a 7-est??"
+
+#: client/ai/greedy.c:1324
+msgid "Why always me?!?"
+msgstr "Miért mindig én?!?"
+
+#: client/ai/greedy.c:1327
+msgid "Say good bye to your cards... :)"
+msgstr "Búcsúzz el a kártyáidtól... :)"
+
+#: client/ai/greedy.c:1328
+msgid "*evilgrin*"
+msgstr "*sátáni vigyor*"
+
+#: client/ai/greedy.c:1329
+msgid "/me says farewell to your cards ;)"
+msgstr "/mondtam, hogy mondj búcsút a kártyáidnak ;)"
+
+#: client/ai/greedy.c:1330
+msgid "That's the price for being rich... :)"
+msgstr "Ez az ár a létezõ legjobb... ;)"
+
+#: client/ai/greedy.c:1333
+msgid "Ey! Where's that card gone?"
+msgstr "Ej! Hol veszet el az a kártya?"
+
+#: client/ai/greedy.c:1334
+msgid "Thieves! Thieves!!"
+msgstr "Tolvaj! Tolvaj!"
+
+#: client/ai/greedy.c:1335
+msgid "Wait for my revenge..."
+msgstr "Várd csak a bosszúmat..."
+
+#: client/ai/greedy.c:1338
+msgid "Oh no :("
+msgstr "Ó ne :("
+
+#: client/ai/greedy.c:1339
+msgid "Must this happen NOW??"
+msgstr "Csak ez adódik MOST??"
+
+#: client/ai/greedy.c:1340
+msgid "Args"
+msgstr "Args"
+
+#: client/ai/greedy.c:1343
+msgid "Hehe, my soldiers rule!"
+msgstr "Hehe, én vagyok a hódító!"
+
+#: client/ai/greedy.c:1346
+msgid "First robbing us, then grabbing the points..."
+msgstr "Kiraboltak minket, majd elvették a pontjainkat..."
+
+#: client/ai/greedy.c:1349
+msgid "See that road!"
+msgstr "Nézd az utat!"
+
+#: client/ai/greedy.c:1352
+msgid "Pf, you won't win with roads alone..."
+msgstr "Pf, te csak utépíéssel akarsz nyerni..."
+
+#: client/ai/greedy.c:1819
+msgid "Rejecting trade.\n"
+msgstr "Elutasított üzlet.\n"
+
+#: client/ai/greedy.c:1911
+#, c-format
+msgid "Received error from server: %s. Quitting\n"
+msgstr "Hiba vétele a szervertõl: %s. Kilépés\n"
+
+#: client/ai/greedy.c:1921
+msgid "Yippie!"
+msgstr "Hurrá!"
+
+#: client/ai/greedy.c:1923
+msgid "My congratulations"
+msgstr "Gratulálok"
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:80
+msgid ""
+"Hello, welcome to the lobby. I am a simple robot. Type '/help' in the chat "
+"to see the list of commands I know."
+msgstr ""
+"Hello, üdvözöllek a hallban. Én egy egyszerû robot vagyok. Írd a chat-be '/"
+"help' és megmutatom milyen parancsokat ismerek."
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:107
+msgid "'/help' shows this message again"
+msgstr "'help' megmutatja ezt az üzenetet újra"
+
+#. Translators: don't translate '/why'
+#: client/ai/lobbybot.c:110
+msgid "'/why' explains the purpose of this strange board layout"
+msgstr "'/why' elmagyarázza a célját, ennek a különleges táblának"
+
+#. Translators: don't translate '/news'
+#: client/ai/lobbybot.c:113
+msgid "'/news' tells the last released version"
+msgstr "'/news' megtudhatod az utolsó kiadott verziót"
+
+#: client/ai/lobbybot.c:118
+msgid ""
+"This board is not intended to be a game that can be played. Instead, players "
+"can find eachother here, and decide which board they want to play. Then, one "
+"of the players will host the proposed game by starting a server, and "
+"registers it at the metaserver. The other players can subsequently "
+"disconnect from the lobby, and enter that game."
+msgstr ""
+"Ez a tábla nem játékra lett tervezve. Helyette a játékosok itt "
+"megtalálhatják egymást, és eldönthetik melyik táblán akarnak játszani. "
+"Megállapodnak ki lesz a tervezett játék gazdája. Õ indít egy szervert, "
+"melyet regisztrál a metaszerverhez. A többi játékos kilép a hallból, és "
+"csatlakozik ahhoz a játékhoz. "
+
+#: client/ai/lobbybot.c:129
+msgid "The last released version of Pioneers is"
+msgstr "Az utolsó kiadott Pioneers verzió:"
+
+#: client/ai/lobbybot.c:144
+msgid "The game is starting. I'm not needed anymore. Goodbye."
+msgstr "A játék indul. Már nem kellek többet. Viszlát."
+
+#: client/common/client.c:103
+msgid "Waiting"
+msgstr "Várj"
+
+#: client/common/client.c:105 client/common/client.c:1241
+msgid "Idle"
+msgstr "Tétlen"
+
+#: client/common/client.c:447
+msgid "We have been kicked out of the game.\n"
+msgstr "Minket kirúgtak a játékból.\n"
+
+#. Network status: offline
+#: client/common/client.c:450 client/common/client.c:891 client/gtk/gui.c:1340
+msgid "Offline"
+msgstr "Nincs kapcsolatban"
+
+#: client/common/client.c:471
+#, c-format
+msgid "Error (%s): %s\n"
+msgstr "Hiba (%s): %s\n"
+
+#: client/common/client.c:480 client/common/client.c:491
+#, c-format
+msgid "Notice: %s\n"
+msgstr "Figyelmeztetés: %s\n"
+
+#: client/common/client.c:607
+#, c-format
+msgid "%s does not receive any %s, because the bank is empty.\n"
+msgstr "A bank üres, %s nem kap semmi %s.\n"
+
+#: client/common/client.c:620
+#, c-format
+msgid "%s only receives %s, because the bank didn't have any more.\n"
+msgstr "%s kaphat csak %s, mert a banknak nincs több.\n"
+
+#: client/common/client.c:629
+#, c-format
+msgid "%s receives %s.\n"
+msgstr "%s kap %s.\n"
+
+#. Year of Plenty
+#: client/common/client.c:637 client/common/client.c:2586
+#, c-format
+msgid "%s takes %s.\n"
+msgstr "%s felhasznál %s.\n"
+
+#: client/common/client.c:642
+#, c-format
+msgid "%s spent %s.\n"
+msgstr "%s elhasznált %s.\n"
+
+#: client/common/client.c:648
+#, c-format
+msgid "%s is refunded %s.\n"
+msgstr "%s visszafizet %s.\n"
+
+#: client/common/client.c:679
+#, c-format
+msgid "%s discarded %s.\n"
+msgstr "%s eldob %s.\n"
+
+#: client/common/client.c:849
+msgid "Loading"
+msgstr "Betöltés"
+
+#: client/common/client.c:892
+msgid "Version mismatch"
+msgstr "Eltérõ verzió"
+
+#: client/common/client.c:894
+msgid "Version mismatch. Please make sure client and server are up to date.\n"
+msgstr ""
+"Verzió eltérés. Kérlek ellenõrizd van-e frissítés a klienshez és a "
+"szerverhez.\n"
+
+#: client/common/client.c:1340
+msgid "Build two settlements, each with a connecting"
+msgstr "Építs két falut, és mindegyikhez csatlakozzon egy"
+
+#: client/common/client.c:1343
+msgid "Build a settlement with a connecting"
+msgstr "Építs egy falut és csatlakozzon hozzá egy"
+
+#: client/common/client.c:1346
+msgid "road"
+msgstr "út"
+
+#: client/common/client.c:1348
+msgid "bridge"
+msgstr "híd"
+
+#: client/common/client.c:1350
+msgid "ship"
+msgstr "hajó"
+
+#: client/common/client.c:1358
+msgid " or"
+msgstr "vagy"
+
+#: client/common/client.c:1416
+msgid "Waiting for your turn"
+msgstr "Várj a körödre."
+
+#: client/common/client.c:1468
+msgid "Select the building to steal from."
+msgstr ""
+"Válaszd ki az épüetet\n"
+"akitõl lopni szeretnél."
+
+#: client/common/client.c:1490
+msgid "Select the ship to steal from."
+msgstr ""
+"Válaszd ki a hajót\n"
+"akitõl lopni szeretnél."
+
+#: client/common/client.c:1575 client/gtk/interface.c:782
+msgid "Place the robber"
+msgstr "Helyezd el a rablót"
+
+#: client/common/client.c:1625
+msgid "Finish the road building action."
+msgstr "Vége az útépítésnek."
+
+#: client/common/client.c:1627
+msgid "Build one road segment."
+msgstr "Épít egy utat."
+
+#: client/common/client.c:1629
+msgid "Build two road segments."
+msgstr "Épít két utat."
+
+#: client/common/client.c:1902 client/common/client.c:1996
+msgid "It is your turn."
+msgstr "Ez a te köröd."
+
+#: client/common/client.c:2090
+#, c-format
+msgid "Sorry, %s available.\n"
+msgstr "Bocs, %s használható.\n"
+
+#: client/common/client.c:2405
+msgid "The game is over."
+msgstr "A játéknak vége."
+
+#: client/common/develop.c:43 editor/gtk/game-devcards.c:13
+msgid "Road Building"
+msgstr "Út építés"
+
+#: client/common/develop.c:44 client/gtk/monopoly.c:83
+#: editor/gtk/game-devcards.c:13
+msgid "Monopoly"
+msgstr "Monopólium"
+
+#: client/common/develop.c:45 client/gtk/plenty.c:59
+#: editor/gtk/game-devcards.c:13
+msgid "Year of Plenty"
+msgstr "Bõség éve"
+
+#: client/common/develop.c:46 client/gtk/player.c:57
+#: editor/gtk/game-devcards.c:14
+msgid "Chapel"
+msgstr "Kápolna"
+
+#: client/common/develop.c:47 client/gtk/player.c:58
+#: editor/gtk/game-devcards.c:14
+msgid "Pioneer University"
+msgstr "Pioneers egyetem"
+
+#: client/common/develop.c:48 client/gtk/player.c:60
+#: editor/gtk/game-devcards.c:15
+msgid "Governor's House"
+msgstr "Kormányzók háza"
+
+#: client/common/develop.c:49 client/gtk/player.c:61
+#: editor/gtk/game-devcards.c:15
+msgid "Library"
+msgstr "Könyvtár"
+
+#: client/common/develop.c:50 client/gtk/player.c:62
+#: editor/gtk/game-devcards.c:15
+msgid "Market"
+msgstr "Piac"
+
+#: client/common/develop.c:51 client/gtk/player.c:63
+#: editor/gtk/game-devcards.c:16
+msgid "Soldier"
+msgstr "Katona"
+
+#: client/common/develop.c:82
+#, c-format
+msgid "You bought the %s development card.\n"
+msgstr "Vásároltál egy %s fejlesztés kártyát.\n"
+
+#: client/common/develop.c:88
+#, c-format
+msgid "You bought a %s development card.\n"
+msgstr "Vásároltál egy %s fejlesztés kártyát.\n"
+
+#: client/common/develop.c:110
+#, c-format
+msgid "%s bought a development card.\n"
+msgstr "%s vásárolt egy fejlesztés kártyát.\n"
+
+#: client/common/develop.c:129
+#, c-format
+msgid "%s played the %s development card.\n"
+msgstr "%s kijátszotta %s fejlesztés kártyáját.\n"
+
+#: client/common/develop.c:134
+#, c-format
+msgid "%s played a %s development card.\n"
+msgstr "%s kijátszotta egy %s fejlesztés kártyáját.\n"
+
+#: client/common/develop.c:147
+msgid "You have run out of road segments.\n"
+msgstr "Nincs több köved az útépítéshez.\n"
+
+#. I get the cards!
+#.
+#: client/common/develop.c:187
+#, c-format
+msgid "You get %s from %s.\n"
+msgstr "Kaptál %s %s játékostól.\n"
+
+#. I lose the cards!
+#.
+#: client/common/develop.c:193
+#, c-format
+msgid "%s took %s from you.\n"
+msgstr "%s elvesz tõled %s.\n"
+
+#: client/common/develop.c:200
+#, c-format
+msgid "%s took %s from %s.\n"
+msgstr "%s elvesz %s játékostól %s.\n"
+
+#: client/common/player.c:124 server/player.c:405
+#, c-format
+msgid "Viewer %d"
+msgstr "Szemlélõ %d"
+
+#: client/common/player.c:126
+#, c-format
+msgid "viewer %d"
+msgstr "szemlélõ %d"
+
+#: client/common/player.c:134 server/player.c:408
+#, c-format
+msgid "Player %d"
+msgstr "Játékos %d"
+
+#: client/common/player.c:136
+#, c-format
+msgid "player %d"
+msgstr "játékos %d"
+
+#: client/common/player.c:212
+#, c-format
+msgid "New viewer: %s.\n"
+msgstr "Új szemlélõ: %s.\n"
+
+#: client/common/player.c:215 client/common/player.c:231
+#, c-format
+msgid "%s is now %s.\n"
+msgstr "%s most %s lett.\n"
+
+#: client/common/player.c:228
+#, c-format
+msgid "Player %d is now %s.\n"
+msgstr "%d játékos %s.\n"
+
+#: client/common/player.c:267
+#, c-format
+msgid "%s has quit\n"
+msgstr "%s kilépett\n"
+
+#: client/common/player.c:276
+msgid "There is no largest army.\n"
+msgstr "Az ott nem a legnagyobb hadsereg.\n"
+
+#: client/common/player.c:279
+#, c-format
+msgid "%s has the largest army.\n"
+msgstr "%s vezeti a legnagyobb hasereget.\n"
+
+#: client/common/player.c:300
+msgid "There is no longest road.\n"
+msgstr "Az ott nem a leghosszabb út.\n"
+
+#: client/common/player.c:303
+#, c-format
+msgid "%s has the longest road.\n"
+msgstr "%s építette a leghosszabb utat.\n"
+
+#: client/common/player.c:324
+#, c-format
+msgid "Waiting for %s."
+msgstr "%s játékosra várunk."
+
+#. We are not in on the action
+#. someone stole a resource from someone else
+#: client/common/player.c:352
+#, c-format
+msgid "%s stole a resource from %s.\n"
+msgstr "%s lop egy nyersanyagot %s játékostól.\n"
+
+#: client/common/player.c:362
+#, c-format
+msgid "You stole %s from %s.\n"
+msgstr "Lopsz %s %s játékostól.\n"
+
+#: client/common/player.c:368
+#, c-format
+msgid "%s stole %s from you.\n"
+msgstr "%s lop tõled %s.\n"
+
+#: client/common/player.c:402
+#, c-format
+msgid "%s gave %s nothing!?\n"
+msgstr "%s ad %s semmit!?\n"
+
+#: client/common/player.c:408 client/common/player.c:416
+#, c-format
+msgid "%s gave %s %s for free.\n"
+msgstr "%s ad %s %s ingyen.\n"
+
+#: client/common/player.c:424
+#, c-format
+msgid "%s gave %s %s in exchange for %s.\n"
+msgstr "%s játékos ad %s játékosnak %s cserébe kap %s.\n"
+
+#: client/common/player.c:455
+#, c-format
+msgid "%s exchanged %s for %s.\n"
+msgstr "%s cserélt %s kapott érte %s.\n"
+
+#: client/common/player.c:475
+#, c-format
+msgid "%s built a road.\n"
+msgstr "%s épített egy utat.\n"
+
+#: client/common/player.c:487
+#, c-format
+msgid "%s built a ship.\n"
+msgstr "%s épített egy hajót.\n"
+
+#: client/common/player.c:500
+#, c-format
+msgid "%s built a settlement.\n"
+msgstr "%s épített egy falut.\n"
+
+#: client/common/player.c:519
+#, c-format
+msgid "%s built a city.\n"
+msgstr "%s épített egy várost.\n"
+
+#: client/common/player.c:533
+#, c-format
+msgid "%s built a city wall.\n"
+msgstr "%s épített egy város falatt.\n"
+
+#: client/common/player.c:544
+#, c-format
+msgid "player_build_add called with BUILD_NONE for user %s\n"
+msgstr "%s felhasználó a player_build_add függvényt 'BUILD_NONE'-val hívta\n"
+
+#: client/common/player.c:553
+#, c-format
+msgid "%s built a bridge.\n"
+msgstr "%s épített egy hidat.\n"
+
+#: client/common/player.c:579
+#, c-format
+msgid "%s removed a road.\n"
+msgstr "%s megszüntet egy utat.\n"
+
+#: client/common/player.c:589
+#, c-format
+msgid "%s removed a ship.\n"
+msgstr "%s megszüntet egy hajót.\n"
+
+#: client/common/player.c:599
+#, c-format
+msgid "%s removed a settlement.\n"
+msgstr "%s megszüntet egy falut.\n"
+
+#: client/common/player.c:610
+#, c-format
+msgid "%s removed a city.\n"
+msgstr "%s megszüntet egy várost.\n"
+
+#: client/common/player.c:624
+#, c-format
+msgid "%s removed a city wall.\n"
+msgstr "%s megszüntet egy város falat.\n"
+
+#: client/common/player.c:634
+#, c-format
+msgid "player_build_remove called with BUILD_NONE for user %s\n"
+msgstr ""
+"%s felhasználó a player_build_remove függvényt 'BUILD_NONE'-val hívta\n"
+
+#: client/common/player.c:642
+#, c-format
+msgid "%s removed a bridge.\n"
+msgstr "%s megszüntet egy hidat.\n"
+
+#: client/common/player.c:673
+#, c-format
+msgid "%s has cancelled a ship's movement.\n"
+msgstr "%s törölte a hajók mozgását.\n"
+
+#: client/common/player.c:676
+#, c-format
+msgid "%s moved a ship.\n"
+msgstr "%s mozgat egy hajót.\n"
+
+#. tell the user that someone got something
+#: client/common/player.c:696
+#, c-format
+msgid "%s received %s.\n"
+msgstr "%s kap %s.\n"
+
+#: client/common/player.c:714
+msgid "server asks to lose invalid point.\n"
+msgstr "érvénytelen pont.\n"
+
+#. tell the user the point is lost
+#: client/common/player.c:720
+#, c-format
+msgid "%s lost %s.\n"
+msgstr "%s elvesztett %s.\n"
+
+#: client/common/player.c:743
+msgid "server asks to move invalid point.\n"
+msgstr "érvénytelen pontra történõ mozgás.\n"
+
+#. tell the user someone (1) lost something (2) to someone else (3)
+#: client/common/player.c:750
+#, c-format
+msgid "%s lost %s to %s.\n"
+msgstr "%s elvesztett %s %s ért.\n"
+
+#: client/common/resource.c:35
+msgid "brick"
+msgstr "tégla"
+
+#: client/common/resource.c:35
+msgid "Brick"
+msgstr "Tégla"
+
+#: client/common/resource.c:36
+msgid "grain"
+msgstr "gabona"
+
+#: client/common/resource.c:36
+msgid "Grain"
+msgstr "Gabona"
+
+#: client/common/resource.c:37
+msgid "ore"
+msgstr "érc"
+
+#: client/common/resource.c:37
+msgid "Ore"
+msgstr "Érc"
+
+#: client/common/resource.c:38
+msgid "wool"
+msgstr "gyapjú"
+
+#: client/common/resource.c:38
+msgid "Wool"
+msgstr "Gyapjú"
+
+#: client/common/resource.c:39
+msgid "lumber"
+msgstr "rönk"
+
+#: client/common/resource.c:39
+msgid "Lumber"
+msgstr "Rönk"
+
+#: client/common/resource.c:40
+msgid "no resource (bug)"
+msgstr "nincs nyersanyag (bug)"
+
+#: client/common/resource.c:40
+msgid "No resource (bug)"
+msgstr "Nincs nyersanyag (bug)"
+
+#: client/common/resource.c:41
+msgid "any resource (bug)"
+msgstr "bármelyik nyersanyag (bug)"
+
+#: client/common/resource.c:41
+msgid "Any resource (bug)"
+msgstr "Bármelyik nyersanyag (bug)"
+
+#: client/common/resource.c:42
+msgid "gold"
+msgstr "aranyat"
+
+#: client/common/resource.c:42 client/gtk/legend.c:39
+msgid "Gold"
+msgstr "Arany"
+
+#: client/common/resource.c:47
+msgid "a brick card"
+msgstr "egy darab tégla kártyát"
+
+#: client/common/resource.c:47
+#, c-format
+msgid "%d brick cards"
+msgstr "%d db tégla kártyát"
+
+#: client/common/resource.c:48
+msgid "a grain card"
+msgstr "egy darab gabona kártyát"
+
+#: client/common/resource.c:48
+#, c-format
+msgid "%d grain cards"
+msgstr "%d db gabona kártyát"
+
+#: client/common/resource.c:49
+msgid "an ore card"
+msgstr "egy darab érc kártyát"
+
+#: client/common/resource.c:49
+#, c-format
+msgid "%d ore cards"
+msgstr "%d db érc kártyát"
+
+#: client/common/resource.c:50
+msgid "a wool card"
+msgstr "egy darab gyapjú kártyát"
+
+#: client/common/resource.c:50
+#, c-format
+msgid "%d wool cards"
+msgstr "%d db gyapjú kártyát"
+
+#: client/common/resource.c:51
+msgid "a lumber card"
+msgstr "egy darab rönk kártyát"
+
+#: client/common/resource.c:51
+#, c-format
+msgid "%d lumber cards"
+msgstr "%d db rönk kártyát"
+
+#: client/common/resource.c:139 client/common/resource.c:225
+msgid "nothing"
+msgstr "semmit"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:166
+#, c-format
+msgid "%s and %s"
+msgstr "%s és %s"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:170
+#, c-format
+msgid "%s, %s"
+msgstr "%s, %s"
+
+#: client/common/robber.c:60
+#, c-format
+msgid "%s has undone the robber movement.\n"
+msgstr "%s törölte a rabló mozgását.\n"
+
+#: client/common/robber.c:63
+#, c-format
+msgid "%s moved the robber.\n"
+msgstr "%s áthelyezte a rablót.\n"
+
+#: client/common/robber.c:73
+#, c-format
+msgid "%s has undone the pirate movement.\n"
+msgstr "%s törölte a hajók mozgását.\n"
+
+#: client/common/robber.c:76
+#, c-format
+msgid "%s moved the pirate.\n"
+msgstr "%s áthelyezte a kalózt.\n"
+
+#: client/common/robber.c:83
+#, c-format
+msgid "%s must move the robber."
+msgstr "%s mozgatja a rablót."
+
+#: client/common/setup.c:140
+#, c-format
+msgid "Setup for %s.\n"
+msgstr "%s beállítása.\n"
+
+#: client/common/setup.c:152
+#, c-format
+msgid "Double setup for %s.\n"
+msgstr "%s kétszeres beállítása.\n"
+
+#: client/common/turn.c:37
+#, c-format
+msgid "%s rolled %d.\n"
+msgstr "%s dobása %d.\n"
+
+#: client/common/turn.c:50
+#, c-format
+msgid "Begin turn %d for %s.\n"
+msgstr "%d. köre kezdõdik, %s játékosnak.\n"
+
+#: client/gtk/chat.c:71
+msgid "<b>Chat</b>"
+msgstr "<b>Chat</b>"
+
+#: client/gtk/chat.c:231
+msgid "Beeper test.\n"
+msgstr "Teszt sípolás.\n"
+
+#: client/gtk/chat.c:234
+#, c-format
+msgid "%s beeped you.\n"
+msgstr "%s sípolt neked.\n"
+
+#: client/gtk/chat.c:238
+#, c-format
+msgid "You beeped %s.\n"
+msgstr "Te sípoltál %s.\n"
+
+#: client/gtk/chat.c:244
+#, c-format
+msgid "You could not beep %s.\n"
+msgstr "Te nem tudsz sípolni %s.\n"
+
+#: client/gtk/chat.c:288
+msgid " said: "
+msgstr " mondja: "
+
+#: client/gtk/connect.c:282
+#, c-format
+msgid "Meta-server at %s, port %s"
+msgstr "Meta szerver: %s, port: %s"
+
+#: client/gtk/connect.c:292
+msgid "Finished.\n"
+msgstr "Kész.\n"
+
+#: client/gtk/connect.c:309 client/gtk/connect.c:359 client/gtk/connect.c:456
+#: server/meta.c:174
+msgid "Meta-server kicked us off\n"
+msgstr "A meta szerver kirúgott minket\n"
+
+#: client/gtk/connect.c:334
+msgid "Receiving game names from the meta server.\n"
+msgstr "Játékok vétele a meta szerverrõl.\n"
+
+#: client/gtk/connect.c:382
+#, c-format
+msgid "New game server requested on %s port %s\n"
+msgstr "Szerver kérés új játékra: %s, port: %s\n"
+
+#: client/gtk/connect.c:391 server/meta.c:168
+#, c-format
+msgid "Unknown message from the metaserver: %s\n"
+msgstr "Ismeretlen üzenet a metaszervertõl: %s\n"
+
+#: client/gtk/connect.c:472 server/meta.c:125
+msgid "Too many meta-server redirects\n"
+msgstr "Túl sok meta szerver átirányítás\n"
+
+#: client/gtk/connect.c:499 server/meta.c:140
+#, c-format
+msgid "Bad redirect line: %s\n"
+msgstr "Hibás átirányított vonal: %s\n"
+
+#: client/gtk/connect.c:525
+#, c-format
+msgid "Meta server too old to create servers (version %d.%d)\n"
+msgstr "Meta szerver túl régi a szerver létrehozáshoz (verzió %d.%d)\n"
+
+#. Sevens rule: normal
+#: client/gtk/connect.c:596 client/gtk/settingscreen.c:168
+#: common/gtk/game-rules.c:81
+msgid "Normal"
+msgstr "Normál"
+
+#: client/gtk/connect.c:602 client/gtk/settingscreen.c:170
+#: common/gtk/game-rules.c:88
+msgid "Reroll on 1st 2 turns"
+msgstr "Elsõ két körben újradobás"
+
+#: client/gtk/connect.c:605 client/gtk/settingscreen.c:172
+#: common/gtk/game-rules.c:95
+msgid "Reroll all 7s"
+msgstr "Mindig újradobás"
+
+#: client/gtk/connect.c:619
+msgid "Default"
+msgstr "Alapértelmezett"
+
+#: client/gtk/connect.c:622
+msgid "Random"
+msgstr "Véletlen"
+
+#: client/gtk/connect.c:653 server/meta.c:188
+#, c-format
+msgid "Redirected to meta-server at %s, port %s\n"
+msgstr "Átirányítva %s meta szerverhez, %s portra\n"
+
+#: client/gtk/connect.c:656
+msgid "Receiving a list of Pioneers servers from the meta server.\n"
+msgstr "Pioneers szerver lista fogadása a meta szervertõl.\n"
+
+#: client/gtk/connect.c:713
+msgid ""
+"<b>Note</b>:\n"
+"\tThe metaserver does not send information about the games.\n"
+"\tPlease set appropriate values yourself."
+msgstr ""
+"<b>Megjegyzés</b>:\n"
+"\tA meta szerver nem küld információt a játékokról.\n"
+"\tKérlek állítds be magad a megfelelõ értékeket."
+
+#: client/gtk/connect.c:730
+msgid "Number of AI Players"
+msgstr "Robot játékosok száma"
+
+#: client/gtk/connect.c:749
+msgid "The number of AI players"
+msgstr "A robot játékosok száma"
+
+#: client/gtk/connect.c:770
+msgid "Requesting new game server\n"
+msgstr "Új játékszerver kérés\n"
+
+#: client/gtk/connect.c:813 server/gtk/main.c:328 server/server.c:160
+#, c-format
+msgid "Error starting %s: %s"
+msgstr "Inditási hiba %s: %s"
+
+#: client/gtk/connect.c:834
+msgid "Create a public game"
+msgstr "Új játék"
+
+#: client/gtk/connect.c:965 client/gtk/connect.c:1268
+msgid "Join a public game"
+msgstr "Játékba jelentkezés"
+
+#: client/gtk/connect.c:970
+msgid "_New remote game"
+msgstr "Ú_j távoli játék"
+
+#: client/gtk/connect.c:984
+msgid "Refresh the list of games"
+msgstr "Játéklista frissitése"
+
+#: client/gtk/connect.c:989
+msgid "Create a new public game at the meta server"
+msgstr "Új publikus játék létrehozása meta szerverre"
+
+#: client/gtk/connect.c:994
+msgid "Don't join a public game"
+msgstr "Nem tud kapcsolódni nyilvános játékhoz"
+
+#: client/gtk/connect.c:998
+msgid "Join the selected game"
+msgstr "Jelentkezés a kiválasztott játékba"
+
+#: client/gtk/connect.c:1033
+msgid "Select a game to join"
+msgstr "Válassz egy játékot"
+
+#: client/gtk/connect.c:1036
+msgid "Map Name"
+msgstr "Térkép név"
+
+#: client/gtk/connect.c:1044
+msgid "Name of the game"
+msgstr "Játék neve"
+
+#: client/gtk/connect.c:1049
+msgid "Curr"
+msgstr "Belépett"
+
+#: client/gtk/connect.c:1055
+msgid "Number of players in the game"
+msgstr "Belépett játékosok száma"
+
+#: client/gtk/connect.c:1060
+msgid "Max"
+msgstr "Maximum"
+
+#: client/gtk/connect.c:1066
+msgid "Maximum players for the game"
+msgstr "Játékosok száma maximum"
+
+#: client/gtk/connect.c:1069
+msgid "Terrain"
+msgstr "Terep"
+
+#: client/gtk/connect.c:1076
+msgid "Random of default terrain"
+msgstr "Véletlen vagy alapértelmezett táj"
+
+#: client/gtk/connect.c:1081
+msgid "Vic. Points"
+msgstr "Gy. pontok"
+
+#: client/gtk/connect.c:1087
+msgid "Points needed to win"
+msgstr "Gyõzelemhez szükséges pontok"
+
+#: client/gtk/connect.c:1090 common/gtk/game-rules.c:73
+msgid "Sevens Rule"
+msgstr "Hetes szabály"
+
+#: client/gtk/connect.c:1096
+msgid "Sevens rule"
+msgstr "Hetes szabály"
+
+#: client/gtk/connect.c:1100
+msgid "Host"
+msgstr "Host"
+
+#: client/gtk/connect.c:1108
+msgid "Host of the game"
+msgstr "A játokot futtató számítógép"
+
+#: client/gtk/connect.c:1113
+msgid "Port"
+msgstr "Port"
+
+#: client/gtk/connect.c:1119
+msgid "Port of the the game"
+msgstr "A játék portja"
+
+#: client/gtk/connect.c:1122 common/gtk/aboutbox.c:77
+msgid "Version"
+msgstr "Verzió"
+
+#: client/gtk/connect.c:1129
+msgid "Version of the host"
+msgstr "A host gép verziója"
+
+#: client/gtk/connect.c:1184 client/gtk/gui.c:215
+msgid "Start a new game"
+msgstr "Új játék indítása"
+
+#: client/gtk/connect.c:1209
+msgid "Player Name"
+msgstr "Játékos neve"
+
+#: client/gtk/connect.c:1223
+msgid "Enter your name"
+msgstr "Add meg a neved"
+
+#. Role of the player: viewer
+#: client/gtk/connect.c:1225 server/gtk/main.c:511
+msgid "Viewer"
+msgstr "Szemlélõ"
+
+#: client/gtk/connect.c:1233
+msgid "Do you want to be a viewer?"
+msgstr "Szemlélõ akarsz lenni?"
+
+#: client/gtk/connect.c:1240 server/gtk/main.c:640
+msgid "Meta Server"
+msgstr "Meta szerver"
+
+#: client/gtk/connect.c:1255
+msgid "Leave empty for the default meta server"
+msgstr "Hagyd üresen az alapértelmezett meta szerverhez"
+
+#: client/gtk/connect.c:1263
+msgid "Join public game"
+msgstr "Csatlakozás nyilvános játékhoz"
+
+#: client/gtk/connect.c:1272
+msgid "Create game"
+msgstr "Játék létrehozása"
+
+#: client/gtk/connect.c:1275
+msgid "Create a game"
+msgstr "Játék létrehozása"
+
+#: client/gtk/connect.c:1285
+msgid "Join private game"
+msgstr "Csatlakozás privát játékhoz"
+
+#: client/gtk/connect.c:1289 client/gtk/connect.c:1434
+msgid "Join a private game"
+msgstr "Csatlakozás egy privát játékhoz"
+
+#: client/gtk/connect.c:1475
+msgid "Name of the host of the game"
+msgstr "A játékot futtató gép neve"
+
+#: client/gtk/connect.c:1494
+msgid "Port of the host of the game"
+msgstr "A játékot futtató gép portja"
+
+#: client/gtk/connect.c:1534
+msgid "Recent games"
+msgstr "Legutóbbi játékok"
+
+#: client/gtk/connect.c:1536
+msgid "Recent Games"
+msgstr "Legutóbbi játékok"
+
+#: client/gtk/develop.c:129
+msgid "<b>Development Cards</b>"
+msgstr "<b>Fejlesztés kátyák</b>"
+
+#: client/gtk/develop.c:160
+msgid "Play Card"
+msgstr "Kártya kijátszása"
+
+#: client/gtk/discard.c:76
+msgid "Discard resources"
+msgstr "Nyersanyagok eldobása"
+
+#: client/gtk/discard.c:96
+#, c-format
+msgid "You must discard %d resources"
+msgstr "El kell dobnod %d db nyersanyagot"
+
+#: client/gtk/discard.c:101
+msgid "Total discards"
+msgstr "Összes eldobása"
+
+#. Caption for list of player that must discard cards
+#: client/gtk/discard.c:226
+msgid "<b>Waiting for players to discard</b>"
+msgstr "<b>Várunk míg dobnak a játékosok</b>"
+
+#: client/gtk/gameover.c:32
+msgid "Game over"
+msgstr "Játék vége"
+
+#: client/gtk/gameover.c:49
+#, c-format
+msgid "%s has won the game with %d victory points!"
+msgstr "%s megnyerte a játékot, %d ponttal!"
+
+#: client/gtk/gameover.c:52
+#, c-format
+msgid "%s has won the game with %d victory points!\n"
+msgstr "%s megnyerte a játékot, %d ponttal!\n"
+
+#: client/gtk/gameover.c:58
+#, c-format
+msgid "All praise %s, Lord of the known world!"
+msgstr "%s minden elismerésünk. Te vagy a világ ura!"
+
+#: client/gtk/gold.c:71
+msgid "Choose resources"
+msgstr "Válassz nyersanyagokat"
+
+#: client/gtk/gold.c:92
+#, c-format
+msgid "You may choose 1 resource"
+msgstr "Választhatsz egy nyersanyagot"
+
+#: client/gtk/gold.c:94
+#, c-format
+msgid "You may choose %d resources"
+msgstr "Választhatsz %d db nyersanyagot"
+
+#. Text for total in choose gold dialog
+#. Text for total in year of plenty dialog
+#: client/gtk/gold.c:101 client/gtk/plenty.c:98
+msgid "Total resources"
+msgstr "Összes nyersanyag"
+
+#: client/gtk/gold.c:213
+msgid "<b>Waiting for players to choose</b>"
+msgstr "<b>Várunk a játékosokra, hogy válasszanak</b>"
+
+#: client/gtk/gui.c:213 server/gtk/main.c:98
+msgid "_Game"
+msgstr "_Játék"
+
+#: client/gtk/gui.c:214
+msgid "_New game"
+msgstr "Új já_ték"
+
+#: client/gtk/gui.c:216
+msgid "_Leave game"
+msgstr "Játék _elhagyása"
+
+#: client/gtk/gui.c:217
+msgid "Leave this game"
+msgstr "Játék elhagyása"
+
+#: client/gtk/gui.c:219
+msgid "_Admin"
+msgstr "_Adminsztárció"
+
+#: client/gtk/gui.c:220
+msgid "Administer Pioneers server"
+msgstr "Pioneers szerver adminisztrálás"
+
+#: client/gtk/gui.c:222
+msgid "_Player name"
+msgstr "Játékos _neve"
+
+#: client/gtk/gui.c:223
+msgid "Change your player name"
+msgstr "Játékos neved módostása"
+
+#: client/gtk/gui.c:224
+msgid "_Legend"
+msgstr "_Jelmagyarázat"
+
+#: client/gtk/gui.c:225
+msgid "Terrain legend and building costs"
+msgstr "Táj magyarázat és építmény árak"
+
+#: client/gtk/gui.c:226
+msgid "_Game Settings"
+msgstr "_Játék beállítások"
+
+#: client/gtk/gui.c:227
+msgid "Settings for the current game"
+msgstr "Aktuális játék beállitásai"
+
+#: client/gtk/gui.c:228
+msgid "_Dice Histogram"
+msgstr "_Dobás statisztika"
+
+#: client/gtk/gui.c:229
+msgid "Histogram of dice rolls"
+msgstr "Kocka dobások statisztikája"
+
+#: client/gtk/gui.c:230 editor/gtk/editor.c:1018 server/gtk/main.c:103
+msgid "_Quit"
+msgstr "_Kilépés"
+
+#: client/gtk/gui.c:231 server/gtk/main.c:104
+msgid "Quit the program"
+msgstr "Kilépés a programból"
+
+#: client/gtk/gui.c:232
+msgid "_Actions"
+msgstr "_Tevékenység"
+
+#: client/gtk/gui.c:233
+msgid "Roll Dice"
+msgstr "Kocka dobás"
+
+#: client/gtk/gui.c:234
+msgid "Roll the dice"
+msgstr "A kocka dobása"
+
+#. Tab page name
+#: client/gtk/gui.c:235 client/gtk/gui.c:577
+msgid "Trade"
+msgstr "Kereskedelem"
+
+#: client/gtk/gui.c:237
+msgid "Undo"
+msgstr "Visszavonás"
+
+#: client/gtk/gui.c:238 client/gtk/gui.c:239
+msgid "Finish"
+msgstr "Kész"
+
+#: client/gtk/gui.c:240 client/gtk/legend.c:226 editor/gtk/game-buildings.c:13
+msgid "Road"
+msgstr "Út"
+
+#: client/gtk/gui.c:241
+msgid "Build a road"
+msgstr "Út építés"
+
+#: client/gtk/gui.c:242 client/gtk/legend.c:230 editor/gtk/game-buildings.c:13
+msgid "Ship"
+msgstr "Hajó"
+
+#: client/gtk/gui.c:243
+msgid "Build a ship"
+msgstr "Hajó építés"
+
+#: client/gtk/gui.c:244
+msgid "Move Ship"
+msgstr "Hajó mozgatás"
+
+#: client/gtk/gui.c:245
+msgid "Move a ship"
+msgstr "Hajó mozgatás"
+
+#: client/gtk/gui.c:246 client/gtk/legend.c:233 editor/gtk/game-buildings.c:13
+msgid "Bridge"
+msgstr "Híd"
+
+#: client/gtk/gui.c:247
+msgid "Build a bridge"
+msgstr "Híd építés"
+
+#: client/gtk/gui.c:248 client/gtk/legend.c:235 client/gtk/player.c:52
+#: editor/gtk/game-buildings.c:13
+msgid "Settlement"
+msgstr "Falu"
+
+#: client/gtk/gui.c:249
+msgid "Build a settlement"
+msgstr "Falu építés"
+
+#: client/gtk/gui.c:250 client/gtk/legend.c:236 client/gtk/player.c:53
+#: editor/gtk/game-buildings.c:14
+msgid "City"
+msgstr "Város"
+
+#: client/gtk/gui.c:251
+msgid "Build a city"
+msgstr "Város építés"
+
+#: client/gtk/gui.c:252
+msgid "Develop"
+msgstr "Fejlesztés"
+
+#: client/gtk/gui.c:253
+msgid "Buy a development card"
+msgstr "Fejlesztés kártya vásárlás"
+
+#: client/gtk/gui.c:254 client/gtk/legend.c:240 client/gtk/player.c:54
+#: editor/gtk/game-buildings.c:14
+msgid "City Wall"
+msgstr "Város fal"
+
+#: client/gtk/gui.c:255
+msgid "Build a city wall"
+msgstr "Város építés"
+
+#: client/gtk/gui.c:257
+msgid "_Settings"
+msgstr "_Beállítások"
+
+#: client/gtk/gui.c:258
+msgid "Prefere_nces"
+msgstr "_Beállítások"
+
+#: client/gtk/gui.c:259
+msgid "Configure the application"
+msgstr "Program konfigurálás"
+
+#: client/gtk/gui.c:261 client/gtk/gui.c:265 editor/gtk/editor.c:1002
+#: server/gtk/main.c:99
+msgid "_Help"
+msgstr "_Súgó"
+
+#: client/gtk/gui.c:262
+msgid "_About Pioneers"
+msgstr "Pioneers _névjegy"
+
+#: client/gtk/gui.c:263
+msgid "Information about Pioneers"
+msgstr "Információ a Pioneersrõl"
+
+#: client/gtk/gui.c:266 client/gtk/gui.c:1065
+msgid "Show the manual"
+msgstr "Kézikönyv"
+
+#: client/gtk/gui.c:272
+msgid "_Toolbar"
+msgstr "_Eszköztár"
+
+#: client/gtk/gui.c:273
+msgid "Show or hide the toolbar"
+msgstr "Eszköztár megjelenítése vagy elrejtése"
+
+#. Victory points target in statusbar
+#: client/gtk/gui.c:368
+#, c-format
+msgid "Points Needed to Win: %i"
+msgstr "Nyeréshez szükséges pontok: %i"
+
+#: client/gtk/gui.c:454
+msgid "<b>Messages</b>"
+msgstr "<b>Üzenetek</b>"
+
+#. Tab page name
+#: client/gtk/gui.c:571 editor/gtk/editor.c:1165
+msgid "Map"
+msgstr "Térkép"
+
+#. Tab page name
+#: client/gtk/gui.c:585 client/gtk/quote.c:306
+msgid "Quote"
+msgstr "Kínál"
+
+#. Tab page name
+#: client/gtk/gui.c:593 client/gtk/legend.c:261
+msgid "Legend"
+msgstr "Jelmagyarázat"
+
+#. Tab page name, shown for the splash screen
+#: client/gtk/gui.c:603
+msgid "Welcome to Pioneers"
+msgstr "Üdvözlünk a Pioneersban"
+
+#: client/gtk/gui.c:868
+msgid "Pioneers Preferences"
+msgstr "Pioneers beállítások"
+
+#. Label for changing the theme, in the preferences dialog
+#: client/gtk/gui.c:898
+msgid "Theme:"
+msgstr "Téma:"
+
+#: client/gtk/gui.c:921
+msgid "Choose one of the themes"
+msgstr "Válassz egyett a témák közül"
+
+#. Label for the option to show the legend
+#: client/gtk/gui.c:925
+msgid "Show legend"
+msgstr "Jelmagyarázat megjelenítése"
+
+#. Tooltip for the option to show the legend
+#: client/gtk/gui.c:935
+msgid "Show the legend as a page beside the map"
+msgstr "Jelmagyarázat megjelenítése a térkép mellett"
+
+#. Label for the option to display log messages in color
+#: client/gtk/gui.c:940
+msgid "Messages with color"
+msgstr "Színes üzenetek"
+
+#: client/gtk/gui.c:950
+msgid "Show new messages with color"
+msgstr "Új üzenetek megjelenítése színesen"
+
+#: client/gtk/gui.c:955
+msgid "Chat in color of player"
+msgstr "Játékosok üzenetei színesen"
+
+#: client/gtk/gui.c:966
+msgid "Show new chat messages in the color of the player"
+msgstr "Új üzenetek megjelenítése a játékosok színével"
+
+#. Label for the option to display the summary with colors
+#: client/gtk/gui.c:971
+msgid "Summary with color"
+msgstr "Összesítés színesben"
+
+#: client/gtk/gui.c:982
+msgid "Use colors in the player summary"
+msgstr "Színek használata a játékos összesítésben"
+
+#: client/gtk/gui.c:987
+msgid "Toolbar with shortcuts"
+msgstr "Eszköztár gyorsbillentyûkkel"
+
+#: client/gtk/gui.c:997
+msgid "Show keyboard shortcuts in the toolbar"
+msgstr "Gyorsbillentyûk megjelenítése az eszköztáron"
+
+#: client/gtk/gui.c:1003
+msgid "Announce new players"
+msgstr "Új játékosok jelzése"
+
+#: client/gtk/gui.c:1014
+msgid "Make a sound when a new player or viewer enters the game"
+msgstr "Hangjelzés, amikor egy új játékos vagy szemlélõ belép a játékba"
+
+#. Label for the option to use the 16:9 layout.
+#: client/gtk/gui.c:1019
+msgid "Use 16:9 layout"
+msgstr "16:9-es elrendezés"
+
+#: client/gtk/gui.c:1030
+msgid "Use a 16:9 friendly layout for the window"
+msgstr "Elrendezés 16:9-es ablakhoz"
+
+#: client/gtk/gui.c:1041
+msgid "The Pioneers Game"
+msgstr "Pioneers"
+
+#. Initial text in status bar
+#: client/gtk/gui.c:1352
+msgid "Welcome to Pioneers!"
+msgstr "Üdvözlünk a Pioneersban!"
+
+#. The name of the application
+#: client/gtk/gui.c:1463
+msgid "Pioneers"
+msgstr "Pioneers"
+
+#: client/gtk/histogram.c:252
+msgid "Dice Histogram"
+msgstr "Dobás statisztka"
+
+#: client/gtk/interface.c:92
+msgid "Ship movement canceled."
+msgstr "Hajó mozgás törölve."
+
+#: client/gtk/interface.c:100 client/gtk/interface.c:101
+msgid "Select a new location for the ship."
+msgstr "Válaszd ki a hajó új helyét."
+
+#: client/gtk/interface.c:740
+msgid "Select the ship to steal from"
+msgstr ""
+"Válaszd ki a hajót\n"
+"akitõl lopni szeretnél"
+
+#: client/gtk/interface.c:750
+msgid "Select the building to steal from"
+msgstr ""
+"Válaszd ki az épületet\n"
+"akitõl lopni szeretnél"
+
+#: client/gtk/legend.c:32
+msgid "Hill"
+msgstr "Domb"
+
+#: client/gtk/legend.c:33
+msgid "Field"
+msgstr "Szántóföld"
+
+#: client/gtk/legend.c:34
+msgid "Mountain"
+msgstr "Hegy"
+
+#: client/gtk/legend.c:35
+msgid "Pasture"
+msgstr "Legelõ"
+
+#: client/gtk/legend.c:36
+msgid "Forest"
+msgstr "Erdõ"
+
+#: client/gtk/legend.c:37
+msgid "Desert"
+msgstr "Sivatag"
+
+#: client/gtk/legend.c:38
+msgid "Sea"
+msgstr "Tenger"
+
+#: client/gtk/legend.c:170
+msgid "<b>Terrain Yield</b>"
+msgstr "<b>Vidék hozama:</b>"
+
+#: client/gtk/legend.c:202
+msgid "<b>Building Costs</b>"
+msgstr "<b>Építmény árak:</b>"
+
+#: client/gtk/legend.c:243
+msgid "Development Card"
+msgstr "Fejlesztés kártya"
+
+#: client/gtk/monopoly.c:105
+msgid "Select the resource you wish to monopolise."
+msgstr "Válassz monopól nyersanyagot"
+
+#: client/gtk/name.c:123
+msgid "Change player name"
+msgstr "Játékos név módosítása"
+
+#: client/gtk/name.c:146
+msgid "Player Name:"
+msgstr "Játékos neve:"
+
+#. Set icon preferences
+#: client/gtk/name.c:202
+msgid "Face:"
+msgstr "Arc:"
+
+#: client/gtk/name.c:217
+msgid "Variant:"
+msgstr "Változat:"
+
+#. Commandline option of client: name of the player
+#: client/gtk/offline.c:59
+msgid "Player name"
+msgstr "Játékos neve"
+
+#: client/gtk/offline.c:63
+msgid "Connect as a viewer"
+msgstr "Csatlakozás szemlélõként"
+
+#: client/gtk/offline.c:66
+msgid "Meta-server Host"
+msgstr "Meta-szerver host"
+
+#: client/gtk/offline.c:70
+msgid "Override the language of the system"
+msgstr "A rendszer nyelvének felülbírálása"
+
+#: client/gtk/offline.c:100
+msgid "Connecting"
+msgstr "Kapcsolódás"
+
+#. Long description in the commandline for pioneers: help
+#: client/gtk/offline.c:175
+msgid "- Play a game of Pioneers"
+msgstr "- Játzs egy játékot a Pioneers-vel"
+
+#: client/gtk/player.c:52
+msgid "Settlements"
+msgstr "Falu"
+
+#: client/gtk/player.c:53
+msgid "Cities"
+msgstr "Városok"
+
+#: client/gtk/player.c:54
+msgid "City Walls"
+msgstr "Város falak"
+
+#: client/gtk/player.c:55
+msgid "Largest Army"
+msgstr "Legnagyobb hadsereg"
+
+#: client/gtk/player.c:56
+msgid "Longest Road"
+msgstr "Leghosszab út"
+
+#: client/gtk/player.c:57
+msgid "Chapels"
+msgstr "Kápolnák"
+
+#: client/gtk/player.c:58
+msgid "Pioneer Universities"
+msgstr "Pioneer egyetemek"
+
+#: client/gtk/player.c:60
+msgid "Governor's Houses"
+msgstr "Kormányzó házak"
+
+#: client/gtk/player.c:61
+msgid "Libraries"
+msgstr "Könyvtárak"
+
+#: client/gtk/player.c:62
+msgid "Markets"
+msgstr "Piacok"
+
+#: client/gtk/player.c:63
+msgid "Soldiers"
+msgstr "Katonák"
+
+#: client/gtk/player.c:64
+msgid "Resource card"
+msgstr "Nyersanyag kártya"
+
+#: client/gtk/player.c:64
+msgid "Resource cards"
+msgstr "Nyersanyag kártya"
+
+#: client/gtk/player.c:65
+msgid "Development card"
+msgstr "Fejlesztés kártya"
+
+#: client/gtk/player.c:65
+msgid "Development cards"
+msgstr "Fejlesztés kártyák"
+
+#. Caption for the overview of the points and card of other players
+#: client/gtk/player.c:561
+msgid "<b>Player Summary</b>"
+msgstr "<b>Játékos összesítés</b>"
+
+#: client/gtk/plenty.c:87
+msgid "Please choose one resource from the bank"
+msgstr "Válassz két nyersanyagot a bankból"
+
+#: client/gtk/plenty.c:90
+msgid "Please choose two resources from the bank"
+msgstr "Válassz két nyersanyagot a bankból"
+
+#: client/gtk/plenty.c:92
+msgid "The bank is empty"
+msgstr "A bank üres"
+
+#: client/gtk/quote.c:186
+#, c-format
+msgid "%s has %s, and is looking for %s"
+msgstr "%s kínál %s nyersanyagot, és cserébe szeretne %s nyersanyagot"
+
+#: client/gtk/quote.c:287
+msgid "I Want"
+msgstr "Szeretnék"
+
+#: client/gtk/quote.c:295
+msgid "Give Them"
+msgstr "Adok érte"
+
+#: client/gtk/quote.c:311
+msgid "Delete"
+msgstr "Törlés"
+
+#: client/gtk/quote.c:335
+msgid "Reject Domestic Trade"
+msgstr "Elutasított belsõ üzlet"
+
+#. Now create columns
+#. Table header: Player who trades
+#. Role of the player: player
+#: client/gtk/quote-view.c:170 server/gtk/main.c:513
+msgid "Player"
+msgstr "Játékos"
+
+#. Table header: Quote
+#: client/gtk/quote-view.c:185
+msgid "Quotes"
+msgstr "Ajánlatok"
+
+#. trade: maritime quote: %1 resources of type %2 for
+#. * one resource of type %3
+#: client/gtk/quote-view.c:292
+#, c-format
+msgid "%d:1 %s for %s"
+msgstr "%d:1 %s:%s"
+
+#. Trade: a player has rejected trade
+#: client/gtk/quote-view.c:431
+msgid "Rejected trade"
+msgstr "Elutasított üzlet"
+
+#. Caption for overview of the resources of the player
+#: client/gtk/resource.c:113
+msgid "<b>Resources</b>"
+msgstr "<b>Nyersanyagok</b>"
+
+#: client/gtk/resource.c:129
+msgid "Total"
+msgstr "Összes"
+
+#. Tooltip for the amount of resources in the hand
+#: client/gtk/resource-table.c:187
+msgid "Amount in hand"
+msgstr "Összeg a kézben"
+
+#: client/gtk/resource-table.c:191
+msgid "<less"
+msgstr "<kevesebb"
+
+#. Tooltip for decreasing the selected amount
+#: client/gtk/resource-table.c:201
+msgid "Decrease the selected amount"
+msgstr "Kiválasztott mennyiség csökkentése"
+
+#. Tooltip for the amount of resources in the bank
+#: client/gtk/resource-table.c:215
+msgid "Amount in the bank"
+msgstr "Összeg a bankban"
+
+#: client/gtk/resource-table.c:219
+msgid "more>"
+msgstr ">több"
+
+#. Tooltip for increasing the selected amount
+#: client/gtk/resource-table.c:231
+msgid "Increase the selected amount"
+msgstr "Kiválasztott mennyiség növelése"
+
+#. Tooltip for the selected amount
+#: client/gtk/resource-table.c:248
+msgid "Selected amount"
+msgstr "Kiválasztott összeg"
+
+#. Tooltip for the total selected amount
+#: client/gtk/resource-table.c:293
+msgid "Total selected amount"
+msgstr "Összes kválasztott összeg"
+
+#: client/gtk/resource-table.c:314
+msgid "The bank cannot be emptied"
+msgstr "A bank nem lehet üres"
+
+#: client/gtk/settingscreen.c:74
+msgid "Yes"
+msgstr "Igen"
+
+#: client/gtk/settingscreen.c:76 client/gtk/settingscreen.c:207
+msgid "No"
+msgstr "Nem"
+
+#: client/gtk/settingscreen.c:87 client/gtk/settingscreen.c:174
+msgid "Unknown"
+msgstr "Ismeretlen"
+
+#: client/gtk/settingscreen.c:121
+msgid "No game in progress..."
+msgstr "Nincs játék folyamatban..."
+
+#: client/gtk/settingscreen.c:131
+msgid "<b>General Settings</b>"
+msgstr "<b>Általános beállítások</b>"
+
+#: client/gtk/settingscreen.c:147
+msgid "Number of players:"
+msgstr "Játékosok száma:"
+
+#: client/gtk/settingscreen.c:150
+msgid "Victory Point Target:"
+msgstr "Nyerõ pont:"
+
+#: client/gtk/settingscreen.c:153
+msgid "Random Terrain?"
+msgstr "Véletlen táj?"
+
+#: client/gtk/settingscreen.c:156
+msgid "Interplayer Trading Allowed?"
+msgstr "Játékosok közötti üzlet engedélyezett?"
+
+#: client/gtk/settingscreen.c:160
+msgid "Trading allowed only before build/buy?"
+msgstr "Kereskedés csak építkezés / vásálás elõtt?"
+
+#: client/gtk/settingscreen.c:163
+msgid "Amount of Each Resource:"
+msgstr "Összes nyersanyag száma:"
+
+#: client/gtk/settingscreen.c:177
+msgid "Sevens Rule:"
+msgstr "Hetes szabály:"
+
+#: client/gtk/settingscreen.c:181
+msgid "Use Pirate:"
+msgstr "Kalóz használat:"
+
+#: client/gtk/settingscreen.c:209
+msgid "Island Discovery Bonuses:"
+msgstr "Sziget felfedezés bónuszok:"
+
+#: client/gtk/settingscreen.c:224
+msgid "<b>Building Quotas</b>"
+msgstr "<b>Épület árak</b>"
+
+#: client/gtk/settingscreen.c:241
+msgid "Roads:"
+msgstr "Utak:"
+
+#: client/gtk/settingscreen.c:247
+msgid "Settlements:"
+msgstr "Falvak:"
+
+#: client/gtk/settingscreen.c:253
+msgid "Cities:"
+msgstr "Városok"
+
+#: client/gtk/settingscreen.c:259
+msgid "City Walls:"
+msgstr "Város falak:"
+
+#: client/gtk/settingscreen.c:265
+msgid "Ships:"
+msgstr "Hajók:"
+
+#: client/gtk/settingscreen.c:271
+msgid "Bridges:"
+msgstr "Hidak:"
+
+#: client/gtk/settingscreen.c:283
+msgid "<b>Development Card Deck</b>"
+msgstr "<b>Fejlesztés kátyák</b>"
+
+#: client/gtk/settingscreen.c:299
+msgid "Road Building Cards:"
+msgstr "Útépítõ kártyák:"
+
+#: client/gtk/settingscreen.c:303
+msgid "Monopoly Cards:"
+msgstr "Monopólium kártyák:"
+
+#: client/gtk/settingscreen.c:307
+msgid "Year of Plenty Cards:"
+msgstr "Bõség éve kártyák:"
+
+#: client/gtk/settingscreen.c:312
+msgid "Chapel Cards:"
+msgstr "Kápolna kártyák:"
+
+#: client/gtk/settingscreen.c:316
+msgid "Pioneer University Cards:"
+msgstr "Pioneer egyetem kártyák:"
+
+#: client/gtk/settingscreen.c:320
+msgid "Governor's House Cards:"
+msgstr "Kormányzók háza kártyák:"
+
+#: client/gtk/settingscreen.c:325
+msgid "Library Cards:"
+msgstr "Könyvtár kártyák:"
+
+#: client/gtk/settingscreen.c:329
+msgid "Market Cards:"
+msgstr "Piac kártyák:"
+
+#: client/gtk/settingscreen.c:333
+msgid "Soldier Cards:"
+msgstr "Katona kártyák:"
+
+#: client/gtk/settingscreen.c:370
+msgid "Current Game Settings"
+msgstr "Aktuális játék beállítások"
+
+#. trade: you ask for something for free
+#: client/gtk/trade.c:193
+#, c-format
+msgid "ask for %s for free"
+msgstr "%s nyersanyagot kérek ingyen"
+
+#. trade: you give something away for free
+#: client/gtk/trade.c:198
+#, c-format
+msgid "give %s for free"
+msgstr "Adok %s ingyen"
+
+#. trade: you trade something for something else
+#: client/gtk/trade.c:203
+#, c-format
+msgid "give %s for %s"
+msgstr "Ad %s kér %s"
+
+#. I want some resources, and give them some resources
+#: client/gtk/trade.c:230
+#, c-format
+msgid "I want %s, and give them %s"
+msgstr "Szeretnék %s nyersanyagot, cserébe adok %s nyersanyagot"
+
+#. Frame title, trade: I want to trade these resources
+#: client/gtk/trade.c:427
+msgid "<b>I Want</b>"
+msgstr "<b>Szeretnék</b>"
+
+#. Frame title, trade: I want these resources in return
+#: client/gtk/trade.c:455
+msgid "<b>Give Them</b>"
+msgstr "<b>Adok érte</b>"
+
+#. Button text, trade: call for quotes from other players
+#: client/gtk/trade.c:484
+msgid "_Call for Quotes"
+msgstr "_Ajánlatot kér"
+
+#. Button text: Trade page, accept selected quote
+#: client/gtk/trade.c:512
+msgid "_Accept Quote"
+msgstr "_Ajánlat elfogadása"
+
+#. Button text: Trade page, finish trading
+#: client/gtk/trade.c:518
+msgid "_Finish Trading"
+msgstr "_Kereskedés befejezése"
+
+#: common/gtk/aboutbox.c:74
+msgid ""
+"Pioneers is based upon the excellent\n"
+"Settlers of Catan board game.\n"
+msgstr ""
+"A Pioneers a kíváló táblajáték a\n"
+"Catan telepesei alapján készült.\n"
+
+#: common/gtk/aboutbox.c:83
+msgid "Homepage"
+msgstr "Honlap"
+
+#: common/gtk/aboutbox.c:88
+msgid "Authors"
+msgstr "Szerzõk"
+
+#. Tooltip for sevens rule normal
+#: common/gtk/game-rules.c:101
+msgid "All sevens move the robber or pirate"
+msgstr "Minden hetes dobás mozgatja a rablót vagy a kalózt"
+
+#: common/gtk/game-rules.c:106
+msgid "In the first two turns all sevens are rerolled"
+msgstr "Az elsõ két körben minden hetes dobás újradobandó"
+
+#. Tooltip for sevens rule reroll all
+#: common/gtk/game-rules.c:110
+msgid "All sevens are rerolled"
+msgstr "Minden hetes dobás újradobandó"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize Terrain"
+msgstr "Véletlen táj?"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize the terrain"
+msgstr "Véletlen táj?"
+
+#: common/gtk/game-rules.c:123
+msgid "Use Pirate"
+msgstr "Kalóz használat"
+
+#: common/gtk/game-rules.c:123
+msgid "Use the pirate to block ships"
+msgstr "Használj kalózt a hajók megállítására"
+
+#: common/gtk/game-rules.c:125
+msgid "Strict Trade"
+msgstr "Szigorú kereskedés"
+
+#: common/gtk/game-rules.c:126
+msgid "Allow trade only before building or buying"
+msgstr "Kereskedés csak építkezés / vásárlás elõtt?"
+
+#: common/gtk/game-rules.c:128
+msgid "Domestic Trade"
+msgstr "Játékosok közötti kereskedés"
+
+#: common/gtk/game-rules.c:128
+msgid "Allow trade between players"
+msgstr "Engedélyezett játékosok közötti kereskedés"
+
+#. Label text for customising a game
+#: common/gtk/game-settings.c:118
+msgid "Number of Players"
+msgstr "Játékosok száma"
+
+#. Tooltip for 'Number of Players'
+#: common/gtk/game-settings.c:136
+msgid "The number of players"
+msgstr "A játékosok száma"
+
+#. Label for customising a game
+#: common/gtk/game-settings.c:139
+msgid "Victory Point Target"
+msgstr "Gyõzelemhez szükséges pontok"
+
+#. Tooltip for Victory Point Target
+#: common/gtk/game-settings.c:159
+msgid "The points needed to win the game"
+msgstr "A gyõzelemhez szükséges pontok"
+
+#. Tooltip for the check button
+#: common/gtk/game-settings.c:172
+msgid "Is it possible to win this game?"
+msgstr "Meg lehet nyerni ezt a játékot?"
+
+#. Port indicator for a resource: trade 2 for 1
+#: common/gtk/guimap.c:750
+msgid "2:1"
+msgstr "2:1"
+
+#. Port indicator: trade 3 for 1
+#. General port indicator
+#: common/gtk/guimap.c:753 common/gtk/guimap.c:778
+msgid "3:1"
+msgstr "3:1"
+
+#. Tooltip for the list of games
+#: common/gtk/select-game.c:111
+msgid "Select a game"
+msgstr "Válassz egy játékot"
+
+#: common/gtk/theme.c:709
+#, c-format
+msgid "bad scaling mode '%s'"
+msgstr "Hibás mérték '%s'"
+
+#: common/game.c:603 common/game.c:633
+msgid "This game cannot be won."
+msgstr "A játékot nem lehet megnyerni."
+
+#: common/game.c:604
+msgid "There is no land."
+msgstr "Nincs vidék"
+
+#: common/game.c:638
+msgid "It is possible that this game cannot be won."
+msgstr "Lehet, hogy a játékot nem lehet megnyerni."
+
+#: common/game.c:643
+msgid "This game can be won by only building all settlements and cities."
+msgstr "A játékot csak az összes falu és város megépítésével lehet megnyerni."
+
+#: common/game.c:650
+#, c-format
+msgid ""
+"Required victory points: %d\n"
+"Points obtained by building all: %d\n"
+"Points in development cards: %d\n"
+"Longest road/largest army: %d+%d\n"
+"Maximum island discovery bonus: %d\n"
+"Total: %d"
+msgstr ""
+"Gyõzelemhez szükséges pontok: %d\n"
+"Elérhetõ pontok mindent felépítve: %d\n"
+"Pontok fejlesztés kártyákban: %d\n"
+"Leghosszabb út / legnagyobb hadsereg: %d+%d\n"
+"Maximum sziget felfedezés bónusz: %d\n"
+"Összesen: %d"
+
+#: common/log.c:54
+msgid "*ERROR* "
+msgstr "*HIBA* "
+
+#: common/log.c:60
+msgid "Chat: "
+msgstr "Chat: "
+
+#: common/log.c:63
+msgid "Resource: "
+msgstr "Nyersanyag: "
+
+#: common/log.c:66
+msgid "Build: "
+msgstr "Épít:"
+
+#: common/log.c:69
+msgid "Dice: "
+msgstr "Dob:"
+
+#: common/log.c:72
+msgid "Steal: "
+msgstr "Lop: "
+
+#: common/log.c:75
+msgid "Trade: "
+msgstr "Kereskedi: "
+
+#: common/log.c:78
+msgid "Development: "
+msgstr "Fejleszt: "
+
+#: common/log.c:81
+msgid "Army: "
+msgstr "Hadsereg: "
+
+#: common/log.c:84
+msgid "Road: "
+msgstr "Út: "
+
+#: common/log.c:87
+msgid "*BEEP* "
+msgstr "*BEEP "
+
+#: common/log.c:92
+msgid "Player 1: "
+msgstr "1. játékos:"
+
+#: common/log.c:95
+msgid "Player 2: "
+msgstr "2. játékos:"
+
+#: common/log.c:98
+msgid "Player 3: "
+msgstr "3. játékos:"
+
+#: common/log.c:101
+msgid "Player 4: "
+msgstr "4. játékos:"
+
+#: common/log.c:104
+msgid "Player 5: "
+msgstr "5. játékos:"
+
+#: common/log.c:107
+msgid "Player 6: "
+msgstr "6. játékos:"
+
+#: common/log.c:110
+msgid "Player 7: "
+msgstr "7. játékos:"
+
+#: common/log.c:113
+msgid "Player 8: "
+msgstr "8. játékos:"
+
+#: common/log.c:116
+msgid "Viewer: "
+msgstr "Szemlélõ:"
+
+#: common/log.c:119
+msgid "** UNKNOWN MESSAGE TYPE ** "
+msgstr "** ISMERETLEN ÜZENET TÍPUS **"
+
+#: common/network.c:281
+#, c-format
+msgid "Error checking connect status: %s\n"
+msgstr "Hiba csatlakozás státusz vizsgálat: %s\n"
+
+#: common/network.c:288
+#, c-format
+msgid "Error connecting to host '%s': %s\n"
+msgstr "Hiba a csatlakozáskor '%s': %s\n"
+
+#: common/network.c:314
+#, c-format
+msgid "Error writing socket: %s\n"
+msgstr "Hiba socket írásakor: %s\n"
+
+#: common/network.c:365
+#, c-format
+msgid "Error writing to socket: %s\n"
+msgstr "Hiba socket írásakor: %s\n"
+
+#: common/network.c:418
+msgid "Read buffer overflow - disconnecting\n"
+msgstr "Olvasási tároló túlcsordulás - kapcsolat bontás\n"
+
+#: common/network.c:428
+#, c-format
+msgid "Error reading socket: %s\n"
+msgstr "Hiba socket olvasáskor: %s\n"
+
+#: common/network.c:575
+#, c-format
+msgid "Cannot resolve %s port %s: %s\n"
+msgstr "Nem lehet feloldani %s port %s: %s\n"
+
+#: common/network.c:582
+#, c-format
+msgid "Cannot resolve %s port %s: host not found\n"
+msgstr "Nem lehet feloldni %s port %s: gép nem található\n"
+
+#: common/network.c:597
+#, c-format
+msgid "Error creating socket: %s\n"
+msgstr "Hiba a socket létrehozásakor: %s\n"
+
+#: common/network.c:605
+#, c-format
+msgid "Error setting socket close-on-exec: %s\n"
+msgstr "Hiba a socket beállításakor 'close-on-exec': %s\n"
+
+#: common/network.c:615 common/network.c:776
+#, c-format
+msgid "Error setting socket non-blocking: %s\n"
+msgstr "Hiba a socket beállításakor 'non-blocking': %s\n"
+
+#: common/network.c:640
+#, c-format
+msgid "Error connecting to %s: %s\n"
+msgstr "Hiba a csatlakozáskor %s: %s\n"
+
+#: common/network.c:735
+#, c-format
+msgid "Error creating struct addrinfo: %s"
+msgstr "Hiba az addrinfo létrehozásakor: %s"
+
+#: common/network.c:765
+#, c-format
+msgid "Error creating listening socket: %s\n"
+msgstr "Hiba a szerver socket létrehozásakor: %s\n"
+
+#: common/network.c:785
+#, c-format
+msgid "Error during listen on socket: %s\n"
+msgstr "Hiba a figyelõ socket végrahajtásakor: %s\n"
+
+#: common/network.c:794
+msgid "Listening not yet supported on this platform."
+msgstr "Ez a platform nem támogatja a szerver socketeket."
+
+#: common/network.c:816 common/network.c:817
+msgid "unknown"
+msgstr "ismeretlen"
+
+#: common/network.c:823
+#, c-format
+msgid "Error getting peer name: %s"
+msgstr "Hiba a látható név kérésekor: %s"
+
+#: common/network.c:836
+#, c-format
+msgid "Error resolving address: %s"
+msgstr "Hiba a címfeloldáskor: %s"
+
+#: common/network.c:850
+msgid "Net_get_peer_name not yet supported on this platform."
+msgstr "Ez a platform nem támogatja a net_get_peer_name függvényt."
+
+#: common/network.c:865
+#, c-format
+msgid "Error accepting connection: %s"
+msgstr "Hiba csatlakozás elfogadásakor: %s"
+
+#: common/state.c:166
+#, c-format
+msgid "Connecting to %s, port %s\n"
+msgstr "Kapcsolódás: %s , port: %s\n"
+
+#: common/state.c:503
+msgid "State stack overflow. Stack dump sent to standard error.\n"
+msgstr ""
+"Állapot verem túlcsordulás. A verem tartalmát elküldtem a standard hiba "
+"kimenetre.\n"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:73
+msgid "_Hill"
+msgstr "_Domb"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:75
+msgid "_Field"
+msgstr "_Szántóföld"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:77
+msgid "_Mountain"
+msgstr "_Hegy"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:79
+msgid "_Pasture"
+msgstr "_Legelõ"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:81
+msgid "F_orest"
+msgstr "_Erdõ"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:83
+msgid "_Desert"
+msgstr "S_ivatag"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:85
+msgid "_Sea"
+msgstr "_Tenger"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:87
+msgid "_Gold"
+msgstr "_Arany"
+
+#. Use an unique shortcut key for each resource
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:89 editor/gtk/editor.c:104
+msgid "_None"
+msgstr "Se_mmi"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:94
+msgid "_Brick (2:1)"
+msgstr "Té_gla (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:96
+msgid "_Grain (2:1)"
+msgstr "_Gabona (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:98
+msgid "_Ore (2:1)"
+msgstr "É_rc (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:100
+msgid "_Wool (2:1)"
+msgstr "Gy_apjú (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:102
+msgid "_Lumber (2:1)"
+msgstr "Rö_nk (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:106
+msgid "_Any (3:1)"
+msgstr "_Bármi (3:1)"
+
+#. East
+#: editor/gtk/editor.c:111
+msgid "East|E"
+msgstr "Kelet|K"
+
+#. North east
+#: editor/gtk/editor.c:113
+msgid "North East|NE"
+msgstr "Észak Kelet|ÉK"
+
+#. North west
+#: editor/gtk/editor.c:115
+msgid "North West|NW"
+msgstr "Észak Nyugat|ÉNY"
+
+#. West
+#: editor/gtk/editor.c:117
+msgid "West|W"
+msgstr "Nyugat|W"
+
+#. South west
+#: editor/gtk/editor.c:119
+msgid "South West|SW"
+msgstr "Dél Nyugat|DNY"
+
+#. South east
+#: editor/gtk/editor.c:121
+msgid "South East|SE"
+msgstr "Dél Kelet|DK"
+
+#: editor/gtk/editor.c:564
+msgid "Shuffle"
+msgstr "Keverés"
+
+#: editor/gtk/editor.c:696 server/gtk/main.c:450
+msgid "Game Parameters"
+msgstr "Játék paraméterek"
+
+#: editor/gtk/editor.c:698 server/gtk/main.c:482
+msgid "Rules"
+msgstr "Szabályok"
+
+#: editor/gtk/editor.c:699
+msgid "Resources"
+msgstr "Nyersanyagok"
+
+#: editor/gtk/editor.c:700
+msgid "Buildings"
+msgstr "Építmények"
+
+#: editor/gtk/editor.c:701
+msgid "Development Cards"
+msgstr "Fejlesztés kártyák"
+
+#: editor/gtk/editor.c:718
+msgid "Pioneers Editor"
+msgstr "Pioneers szerkesztõ"
+
+#: editor/gtk/editor.c:803
+#, c-format
+msgid "Failed to load '%s'"
+msgstr "Hiba a betöltékor '%s'"
+
+#: editor/gtk/editor.c:843
+#, c-format
+msgid "Failed to save to '%s'"
+msgstr "Hiba a mentéskor '%s'"
+
+#: editor/gtk/editor.c:858
+msgid "Open Game"
+msgstr "Játék megnyitása"
+
+#: editor/gtk/editor.c:884
+msgid "Save as..."
+msgstr "Mentés másként..."
+
+#: editor/gtk/editor.c:919
+msgid "Change Title"
+msgstr "Cím módosítás"
+
+#: editor/gtk/editor.c:941
+msgid "New Title:"
+msgstr "Új cím:"
+
+#: editor/gtk/editor.c:997
+msgid "Pioneers Game Editor"
+msgstr "Pioneers játék szerkesztõ"
+
+#: editor/gtk/editor.c:1001
+msgid "_File"
+msgstr "_Fájl"
+
+#: editor/gtk/editor.c:1004
+msgid "_New"
+msgstr "Ú_j"
+
+#: editor/gtk/editor.c:1005
+msgid "Create a new game"
+msgstr "Új játék létrehozása"
+
+#: editor/gtk/editor.c:1006
+msgid "_Open..."
+msgstr "_Megnyitás..."
+
+#: editor/gtk/editor.c:1007
+msgid "Open an existing game"
+msgstr "Létezõ játék megnyitása"
+
+#: editor/gtk/editor.c:1008
+msgid "_Save"
+msgstr "_Mentés"
+
+#: editor/gtk/editor.c:1009
+msgid "Save game"
+msgstr "Játék mentése"
+
+#: editor/gtk/editor.c:1010
+msgid "Save _As..."
+msgstr "_Men_tés másként..."
+
+#: editor/gtk/editor.c:1012
+msgid "Save as"
+msgstr "Mentés másként"
+
+#: editor/gtk/editor.c:1013
+msgid "_Change title"
+msgstr "_Cím módosítás"
+
+#: editor/gtk/editor.c:1014
+msgid "Change game title"
+msgstr "Játék címének módosítása"
+
+#: editor/gtk/editor.c:1015 server/gtk/main.c:100
+msgid "_Check Victory Point Target"
+msgstr "_Ellenõrizd a gyõzelemhez szükséges pontokat"
+
+#: editor/gtk/editor.c:1017 server/gtk/main.c:102
+msgid "Check whether the game can be won"
+msgstr "Ellenõizd, vajon a játék megnyerhetõ-e"
+
+#: editor/gtk/editor.c:1019
+msgid "Quit"
+msgstr "Kilépés"
+
+#: editor/gtk/editor.c:1027
+msgid "_About Pioneers Editor"
+msgstr "_Pioneers szerkesztõrõl"
+
+#: editor/gtk/editor.c:1028
+msgid "Information about Pioneers Editor"
+msgstr "Információ a Pioneers szerkesztõrõl"
+
+#. Long help for commandline option (editor): filename
+#: editor/gtk/editor.c:1066
+msgid "Open this file"
+msgstr "Ennek a fájlnak a megnyitása"
+
+#. Commandline option for editor: filename
+#: editor/gtk/editor.c:1068
+msgid "filename"
+msgstr "fájlnév"
+
+#: editor/gtk/editor.c:1100
+msgid "- Editor for games of Pioneers"
+msgstr "- Szerkesztõ a Pioneers játékokhoz"
+
+#: editor/gtk/editor.c:1141 server/gtk/main.c:1035
+#, c-format
+msgid "Building menus failed: %s"
+msgstr "Hiba a menû felépítésekor: %s"
+
+#: editor/gtk/editor.c:1169
+msgid "Settings"
+msgstr "Beállítások"
+
+#: editor/gtk/game-resources.c:51
+msgid "Resource Count"
+msgstr "Nyersanyagok száma"
+
+#. Commandline meta-server: daemon
+#: meta-server/main.c:1033
+msgid "Daemonize the metaserver on start"
+msgstr "A metaszerver démonként induljon"
+
+#. Commandline meta-server: redirect
+#: meta-server/main.c:1036
+msgid "Redirect clients to another metaserver"
+msgstr "Irányítsd a klienseket egy másik metaszeverhez"
+
+#. Commandline meta-server: server
+#: meta-server/main.c:1039
+msgid "Use this hostname when creating new games"
+msgstr "Használd ezt a host nevet új játék létrehozásához"
+
+#. Commandline meta-server: server argument
+#: meta-server/main.c:1041
+msgid "hostname"
+msgstr "host név"
+
+#. Commandline meta-server: port-range
+#: meta-server/main.c:1044
+msgid "Use this ports range when creating new games"
+msgstr "Használd ezt a port tartományt új játék létrehozásához"
+
+#. Commandline meta-server: port-range argument
+#: meta-server/main.c:1046
+msgid "from-to"
+msgstr "tól-ig"
+
+#. Commandline option of meta server: syslog-debug
+#: meta-server/main.c:1052
+msgid "Debug syslog messages"
+msgstr "Debug syslog üzenetek"
+
+#. Long description in the commandline for server-console: help
+#: meta-server/main.c:1073
+msgid "- Meta server for Pioneers"
+msgstr "- Meta szerver a Pioneers játékhoz"
+
+#: meta-server/main.c:1088
+#, c-format
+msgid "metaserver protocol:"
+msgstr "metaszerver protokoll:"
+
+#: server/gtk/main.c:105
+msgid "_About Pioneers Server"
+msgstr "_Pioneers szerverrõl"
+
+#: server/gtk/main.c:106
+msgid "Information about Pioneers Server"
+msgstr "Információ a Pioneers szerverrõl"
+
+#: server/gtk/main.c:222
+msgid "Stop server"
+msgstr "Szerver leállítása"
+
+#: server/gtk/main.c:223
+msgid "Start server"
+msgstr "Szerver indítása"
+
+#: server/gtk/main.c:225
+msgid "Stop the server"
+msgstr "A szerver leállítása"
+
+#: server/gtk/main.c:226
+msgid "Start the server"
+msgstr "A szerver indítása"
+
+#: server/gtk/main.c:351
+#, c-format
+msgid "Player %s from %s entered\n"
+msgstr "%s játékos belépett a következõ géprõl %s\n"
+
+#: server/gtk/main.c:358
+#, c-format
+msgid "Player %s from %s left\n"
+msgstr "%s játékos kilépett a következõ géprõl %s\n"
+
+#: server/gtk/main.c:365
+#, c-format
+msgid "Player %d is now %s\n"
+msgstr "%d. játékos most %s\n"
+
+#: server/gtk/main.c:554
+msgid "Game Settings"
+msgstr "Játék beállítások"
+
+#: server/gtk/main.c:600
+msgid "Server Parameters"
+msgstr "Szerver paraméterek"
+
+#: server/gtk/main.c:626
+msgid "The port for the game server"
+msgstr "Port a játék szerverhez"
+
+#: server/gtk/main.c:629
+msgid "Register Server"
+msgstr "Szerver regisztrálás"
+
+#: server/gtk/main.c:637
+msgid "Register this game at the meta server"
+msgstr "Játék regisztrálása a meta szerverre"
+
+#: server/gtk/main.c:654
+msgid "The address of the meta server"
+msgstr "A meta szerver címe"
+
+#: server/gtk/main.c:656
+msgid "Reported Hostname"
+msgstr "A közölt host név"
+
+#: server/gtk/main.c:671
+msgid ""
+"The public name of this computer (needed when playing behind a firewall)"
+msgstr "A gép nyilvános neve (szükséges ha tûzfal mögül játszol)"
+
+#: server/gtk/main.c:675
+msgid "Random Turn Order"
+msgstr "Véletlen kör sorrend"
+
+#: server/gtk/main.c:683
+msgid "Randomize turn order"
+msgstr "Játékosok sorrnedje véletlen"
+
+#: server/gtk/main.c:722
+msgid "Running Game"
+msgstr "Aktuális játék"
+
+#: server/gtk/main.c:724
+msgid "Players Connected"
+msgstr "Csatlakozott játékosok"
+
+#: server/gtk/main.c:758
+msgid "Shows all players and viewers connected to the server"
+msgstr "Minden szerverhez csatlakozott játékos és szemlélõ megjelenítése"
+
+#: server/gtk/main.c:763
+msgid "Connected"
+msgstr "Csatlakozva"
+
+#: server/gtk/main.c:770
+msgid "Is the player currently connected?"
+msgstr "A játékos jelenleg csatlakozva?"
+
+#: server/gtk/main.c:773
+msgid "Name"
+msgstr "Név"
+
+#: server/gtk/main.c:780
+msgid "Name of the player"
+msgstr "A játékos neve"
+
+#: server/gtk/main.c:782
+msgid "Location"
+msgstr "Hely"
+
+#: server/gtk/main.c:789
+msgid "Host name of the player"
+msgstr "A játékos host neve"
+
+#: server/gtk/main.c:793
+msgid "Number"
+msgstr "Szám"
+
+#: server/gtk/main.c:800
+msgid "Player number"
+msgstr "A játékos száma"
+
+#: server/gtk/main.c:804
+msgid "Role"
+msgstr "Szabály"
+
+#: server/gtk/main.c:808
+msgid "Player of viewer"
+msgstr "Játékos a nézõkbõl"
+
+#: server/gtk/main.c:819
+msgid "Launch Pioneers Client"
+msgstr "Pioneers kliens indítása"
+
+#: server/gtk/main.c:826
+msgid "Launch the Pioneers Client"
+msgstr "A Pioneers kliens indítása"
+
+#: server/gtk/main.c:828
+msgid "Computer Players"
+msgstr "Számítógép játékosok"
+
+#: server/gtk/main.c:837
+msgid "Enable Chat"
+msgstr "Chat engedélyezése"
+
+#: server/gtk/main.c:843
+msgid "Enable chat messages"
+msgstr "Chat üzenetek engedélyezése"
+
+#: server/gtk/main.c:850
+msgid "Add Computer Player"
+msgstr "Robot játékos hozzáadása"
+
+#: server/gtk/main.c:857
+msgid "Add a computer player to the game"
+msgstr "Robot játékos hozzáadása a játékhoz"
+
+#: server/gtk/main.c:866
+msgid "Messages"
+msgstr "Üzenetek"
+
+#: server/gtk/main.c:884
+msgid "Messages from the server"
+msgstr "Üzenetek a szervertõl"
+
+#: server/gtk/main.c:932
+msgid "The Pioneers Game Server"
+msgstr "A pioneers játék szerver"
+
+#. Wait for all players to disconnect,
+#. * then enable the UI
+#.
+#: server/gtk/main.c:940
+msgid "The game is over.\n"
+msgstr "A játéknak vége.\n"
+
+#. Long description in the commandline for server-gtk: help
+#. Long description in the commandline for server-console: help
+#: server/gtk/main.c:994 server/main.c:174
+msgid "- Host a game of Pioneers"
+msgstr "- a Pioneers játékot futtató"
+
+#. Name in the titlebar of the server
+#: server/gtk/main.c:1016
+msgid "Pioneers Server"
+msgstr "Pioneers szerver"
+
+#. Commandline server-console: game-title
+#: server/main.c:75
+msgid "Game title to use"
+msgstr "Játék cím"
+
+#. Commandline server-console: file
+#: server/main.c:78
+msgid "Game file to use"
+msgstr "Játék fájl"
+
+#. Commandline server-console: port
+#: server/main.c:81
+msgid "Port to listen on"
+msgstr "Szzerver port"
+
+#. Commandline server-console: players
+#: server/main.c:84
+msgid "Override number of players"
+msgstr "A játékosok számánk felülbírálása"
+
+#. Commandline server-console: points
+#: server/main.c:87
+msgid "Override number of points needed to win"
+msgstr "Gyõzelemhez szükséges pontok felülbírálása"
+
+#. Commandline server-console: seven-rule
+#: server/main.c:90
+msgid "Override seven-rule handling"
+msgstr "Hetes szabály felülbírálása"
+
+#. Commandline server-console: terrain
+#: server/main.c:93
+msgid "Override terrain type, 0=default 1=random"
+msgstr "Terep felülbírálása, 0=alapértelmezett 1=véletlen"
+
+#. Commandline server-console: computer-players
+#: server/main.c:96
+msgid "Add N computer players"
+msgstr "N db robot játékos hozzáadása"
+
+#. Commandline server-console: register
+#: server/main.c:106
+msgid "Register server with meta-server"
+msgstr "Szerver regisztrálása a meta szerverre"
+
+#. Commandline server-console: meta-server
+#: server/main.c:109
+msgid "Register at meta-server name (implies -r)"
+msgstr "Regisztrálj a meta-szerver névre (beleértve -r)"
+
+#. Commandline server-console: hostname
+#: server/main.c:113
+msgid "Use this hostname when registering"
+msgstr "Használd ezt a host nevet regisztráláshoz"
+
+#. Commandline server-console: auto-quit
+#: server/main.c:120
+msgid "Quit after a player has won"
+msgstr "Kilép miután a játékos nyert"
+
+#. Commandline server-console: empty-timeout
+#: server/main.c:123
+msgid "Quit after N seconds with no players"
+msgstr "Kilép N másodperc múlva, ha nincsenek játékosok"
+
+#. Commandline server-console: tournament
+#: server/main.c:126
+msgid "Tournament mode, computer players added after N minutes"
+msgstr "Verseny mód, robot játékos hozzáadása N perc elteltével"
+
+#. Commandline server-console: admin-port
+#: server/main.c:130
+msgid "Admin port to listen on"
+msgstr "A szerver admin portja"
+
+#: server/main.c:134
+msgid "Don't start game immediately, wait for a command on admin port"
+msgstr "Nem indul a játék azonnal, parancsra vár az admin porton"
+
+#: server/main.c:140
+msgid "Give players numbers according to the order they enter the game"
+msgstr "Add meg a játékosok számát, ahányan játszanak a játékban"
+
+#. Commandline server-console: Short description of meta group
+#: server/main.c:180
+msgid "Meta-server Options"
+msgstr "Meta szerver kapcsolók"
+
+#: server/main.c:183
+msgid "Options for the meta-server"
+msgstr "meta-szerver kapcsolók"
+
+#. Commandline server-console: Short description of misc group
+#: server/main.c:191
+msgid "Miscellaneous Options"
+msgstr "Egyéb kapcsolók"
+
+#. Commandline server-console: Long description of misc group
+#: server/main.c:193
+msgid "Miscellaneous options"
+msgstr "Egyéb kapcsolók"
+
+#: server/meta.c:193
+#, c-format
+msgid "Register with meta-server at %s, port %s\n"
+msgstr "Regisztrálás a meta szerverrel %s, port %s\n"
+
+#: server/meta.c:210
+msgid "Unregister from meta-server\n"
+msgstr "Ismeretlen üzenet a metaszervertõl\n"
+
+#: server/player.c:130
+msgid "chat too long"
+msgstr "túl hosszú chat"
+
+#: server/player.c:147
+msgid "name too long"
+msgstr "túl hosszú név"
+
+#: server/player.c:179
+msgid "ignoring unknown extension"
+msgstr "ismeretlen bõvítések figyelmen kívül hagyása"
+
+#: server/player.c:209
+msgid "Game starts, adding computer players"
+msgstr "Játék indul, robot játékosok hozzáadva"
+
+#: server/player.c:234
+#, c-format
+msgid "The game starts in %s minutes."
+msgstr "A játék %s percen belül kezdõdik."
+
+#: server/player.c:235
+#, c-format
+msgid "The game starts in %s minute."
+msgstr "A játék %s perc múlva kezdõdik."
+
+#: server/player.c:280
+msgid "Sorry, game is over."
+msgstr "Bocs, a játék vége."
+
+#: server/player.c:283
+#, c-format
+msgid "Player from %s is refused: game is over\n"
+msgstr "Játékos a %s géprõl visszautasíta: a játéknak vége\n"
+
+#: server/player.c:331
+msgid "This game will start soon."
+msgstr "Ez a játék hamarosan kezdõdik."
+
+#: server/player.c:359
+msgid "Name not changed: new name is already in use"
+msgstr "Név nincs megváltoztatva: az új név már használatban"
+
+#. %s is the name of the reconnecting player
+#: server/player.c:648
+#, c-format
+msgid "%s has reconnected."
+msgstr "%s újra csatlakoztatva."
+
+#: server/player.c:776
+#, c-format
+msgid "Version mismatch: %s"
+msgstr "Verzió eltérés: %s"
+
+#: server/server.c:47
+msgid "Was hanging around for too long without players... bye.\n"
+msgstr "Túl sokáig voltam játékosok nélkül...viszlát.\n"
+
+#. Server: preparing game #.....
+#: server/server.c:219
+msgid "Preparing game"
+msgstr "Játék indítása"
+
+#: server/server.c:337
+msgid "Missing game directory\n"
+msgstr "Hiányzó játék könyvtár\n"
+
+#: server/turn.c:253
+msgid "Island Discovery Bonus"
+msgstr "Sziget felfedezés bónusz"
+
+#: server/turn.c:256
+msgid "Additional Island Bonus"
+msgstr "További sziget bónusz"
+
+#: server/turn.c:388
+msgid "Tried to assign resources to NULL player.\n"
+msgstr "NULL játékosnak próbált erõforrást kiosztani.\n"
+
+#~ msgid "Brick port|B"
+#~ msgstr "T"
+
+#~ msgid "Grain port|G"
+#~ msgstr "G"
+
+#~ msgid "Ore port|O"
+#~ msgstr "É"
+
+#~ msgid "Wool port|W"
+#~ msgstr "Gy"
+
+#~ msgid "Lumber port|L"
+#~ msgstr "R"
+
+#~ msgid "Continue with your turn."
+#~ msgstr "Folytatjuk a köröddel."
Added: trunk/po/it.po
===================================================================
--- trunk/po/it.po (rev 0)
+++ trunk/po/it.po 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,3101 @@
+# Pioneers - Settlers of Catan for GNOME.
+# Copyright (C) 1999-2001 Dave Cole
+# Copyright (C) 2000-2002 Andy Heroff
+# This file is distributed under the same license as the pioneers package.
+# Giancarlo Capella <giancarlo at comm.cc>, 2005-2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Pioneers 0.11.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-07 20:43+0200\n"
+"PO-Revision-Date: 2007-07-13 14:50+0200\n"
+"Last-Translator: Giancarlo Capella <giancarlo at comm.cc>\n"
+"Language-Team: it <it at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Default name for the AI when the computer_names file
+#. * is not found or empty.
+#.
+#: client/ai/ai.c:74 client/ai/ai.c:90
+msgid "Computer Player"
+msgstr "Giocatore AI"
+
+#. Commandline pioneersai: server
+#. Commandline option of client: hostname of the server
+#: client/ai/ai.c:102 client/gtk/connect.c:1462 client/gtk/offline.c:53
+msgid "Server Host"
+msgstr "Server Host"
+
+#. Commandline pioneersai: port
+#. Commandline option of client: port of the server
+#: client/ai/ai.c:105 client/gtk/connect.c:1478 client/gtk/offline.c:56
+#: server/gtk/main.c:612
+msgid "Server Port"
+msgstr "Porta Server"
+
+#. Commandline pioneersai: name
+#: client/ai/ai.c:108
+msgid "Computer name (leave absent for random name)"
+msgstr "Nome giocatore AI (nome casuale se nulla)"
+
+#. Commandline pioneersai: time
+#: client/ai/ai.c:111
+msgid "Time to wait between turns (in milliseconds)"
+msgstr "Tempo di attesa tra i turni (in millisecondi)"
+
+#. Commandline pioneersai: chat-free
+#: client/ai/ai.c:114
+msgid "Stop computer player from talking"
+msgstr "Blocca il dialogo del giocatore AI"
+
+#. Commandline pioneersai: algorithm
+#: client/ai/ai.c:117
+msgid "Type of computer player"
+msgstr "Tipo di giocatore AI"
+
+#. Commandline option of ai: enable debug logging
+#. Commandline option of client: enable debug logging
+#. Commandline option of meta server: enable debug logging
+#. Commandline option of server-gtk: enable debug logging
+#. Commandline option of server: enable debug logging
+#: client/ai/ai.c:120 client/gtk/offline.c:74 meta-server/main.c:1049
+#: server/gtk/main.c:952 server/main.c:144
+msgid "Enable debug messages"
+msgstr "Abilita messaggi di debug"
+
+#. Commandline option of ai: version
+#. Commandline option of client: version
+#. Commandline option of editor: version
+#. Commandline option of meta server: version
+#. Commandline option of server-gtk: version
+#. Commandline option of server-console: version
+#: client/ai/ai.c:123 client/gtk/offline.c:77 editor/gtk/editor.c:1071
+#: meta-server/main.c:1055 server/gtk/main.c:955 server/main.c:99
+msgid "Show version information"
+msgstr "Mostra informazioni di versione"
+
+#: client/ai/ai.c:134
+msgid "- Computer player for Pioneers"
+msgstr "- Giocatore AI di Pioneers"
+
+#: client/ai/ai.c:144 client/gtk/offline.c:186 editor/gtk/editor.c:1111
+#: meta-server/main.c:1084 server/gtk/main.c:1005 server/main.c:206
+#, c-format
+msgid "Pioneers version:"
+msgstr "Pioneers, versione:"
+
+#: client/ai/ai.c:176
+#, c-format
+msgid "Type of computer player: %s\n"
+msgstr "Tipo di giocatore AI: %s\n"
+
+#: client/ai/ai.c:205
+msgid "The game is already full. I'm leaving."
+msgstr "La partita è completa. Esco."
+
+#: client/ai/greedy.c:941
+msgid "No settlements in stock to use for setup"
+msgstr "Nessuna colonia disponibile da posizionare"
+
+#: client/ai/greedy.c:948
+msgid "There is no place to setup a settlement"
+msgstr "Non c'è nessun punto per posizionare una colonia"
+
+#: client/ai/greedy.c:972
+msgid "No roads in stock to use for setup"
+msgstr "Nessuna strada disponibile da posizionare"
+
+#: client/ai/greedy.c:989
+msgid "There is no place to setup a road"
+msgstr "Non c'è nessun punto per posizionare una strada"
+
+#: client/ai/greedy.c:1291
+msgid "Ok, let's go!"
+msgstr "Ok, andiamo!"
+
+#: client/ai/greedy.c:1292
+msgid "I'll beat you all now! ;)"
+msgstr "Vi batterò tutti! ;)"
+
+#: client/ai/greedy.c:1293
+msgid "Now for another try..."
+msgstr "Riproviamo..."
+
+#: client/ai/greedy.c:1297
+msgid "At least I get something..."
+msgstr "Almeno ho preso qualcosa..."
+
+#: client/ai/greedy.c:1298
+msgid "One is better than none..."
+msgstr "Uno è meglio di niente..."
+
+#: client/ai/greedy.c:1302
+msgid "Wow!"
+msgstr "Uau!"
+
+#: client/ai/greedy.c:1303
+msgid "Ey, I'm becoming rich ;)"
+msgstr "Ehi, sto diventando ricco ;)"
+
+#: client/ai/greedy.c:1304
+msgid "This is really a good year!"
+msgstr "Questa è proprio una buona annata!"
+
+#: client/ai/greedy.c:1307
+msgid "You really don't deserve that much!"
+msgstr "Non ti meriti tutto questo!"
+
+#: client/ai/greedy.c:1308
+msgid "You don't know what to do with that many resources ;)"
+msgstr "Non sai nemmeno che farci con così tante materie prime ;)"
+
+#: client/ai/greedy.c:1309
+msgid "Ey, wait for my robber and lose all this again!"
+msgstr "Vedrai, il mio brigante ti farà di nuovo perdere tutto!"
+
+#: client/ai/greedy.c:1312
+msgid "Hehe!"
+msgstr "Hehehe!"
+
+#: client/ai/greedy.c:1313
+msgid "Go, robber, go!"
+msgstr "Vai brigante, vai!"
+
+#: client/ai/greedy.c:1316
+msgid "You bastard!"
+msgstr "Che bastardo!"
+
+#: client/ai/greedy.c:1317
+msgid "Can't you move that robber somewhere else?!"
+msgstr "Non potevi mettere il brigante da qualche altra parte?!"
+
+#: client/ai/greedy.c:1318
+msgid "Why always me??"
+msgstr "Perché sempre me??"
+
+#: client/ai/greedy.c:1321
+msgid "Oh no!"
+msgstr "Oh, no!"
+
+#: client/ai/greedy.c:1322
+msgid "Grrr!"
+msgstr "Grrr!"
+
+#: client/ai/greedy.c:1323
+msgid "Who the hell rolled that 7??"
+msgstr "Chi diavolo ha tirato quel 7??"
+
+#: client/ai/greedy.c:1324
+msgid "Why always me?!?"
+msgstr "Perché sempre me?!?"
+
+#: client/ai/greedy.c:1327
+msgid "Say good bye to your cards... :)"
+msgstr "Saluta le tue carte... :)"
+
+#: client/ai/greedy.c:1328
+msgid "*evilgrin*"
+msgstr "*ghigno malefico*"
+
+#: client/ai/greedy.c:1329
+msgid "/me says farewell to your cards ;)"
+msgstr "/me dice addio alle tue carte ;)"
+
+#: client/ai/greedy.c:1330
+msgid "That's the price for being rich... :)"
+msgstr "Quello è il prezzo della ricchezza... :)"
+
+#: client/ai/greedy.c:1333
+msgid "Ey! Where's that card gone?"
+msgstr "Ehi, dov'è andata quella carta?"
+
+#: client/ai/greedy.c:1334
+msgid "Thieves! Thieves!!"
+msgstr "Ladri! Ladri!"
+
+#: client/ai/greedy.c:1335
+msgid "Wait for my revenge..."
+msgstr "Aspettati la mia vendetta..."
+
+#: client/ai/greedy.c:1338
+msgid "Oh no :("
+msgstr "Oh no :("
+
+#: client/ai/greedy.c:1339
+msgid "Must this happen NOW??"
+msgstr "Deve proprio accadere ORA??"
+
+#: client/ai/greedy.c:1340
+msgid "Args"
+msgstr "Argh"
+
+#: client/ai/greedy.c:1343
+msgid "Hehe, my soldiers rule!"
+msgstr "Hehe, sono i miei cavalieri a comandare!"
+
+#: client/ai/greedy.c:1346
+msgid "First robbing us, then grabbing the points..."
+msgstr "Prima ci ruba, poi ci frega i punti..."
+
+#: client/ai/greedy.c:1349
+msgid "See that road!"
+msgstr "Guarda quella strada!"
+
+#: client/ai/greedy.c:1352
+msgid "Pf, you won't win with roads alone..."
+msgstr "Pfui, non puoi vincere solo con strade..."
+
+#: client/ai/greedy.c:1819
+msgid "Rejecting trade.\n"
+msgstr "Nessun commercio.\n"
+
+#: client/ai/greedy.c:1911
+#, c-format
+msgid "Received error from server: %s. Quitting\n"
+msgstr "Ricevuto un errore dal server: %s. In uscita.\n"
+
+#: client/ai/greedy.c:1921
+msgid "Yippie!"
+msgstr "Yuppi!"
+
+#: client/ai/greedy.c:1923
+msgid "My congratulations"
+msgstr "I miei complimenti"
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:80
+msgid ""
+"Hello, welcome to the lobby. I am a simple robot. Type '/help' in the chat "
+"to see the list of commands I know."
+msgstr ""
+"Salve, benvenuto nella lobby. Io sono un semplice robot. Scrivi '/help' "
+"nella chat per vedere la lista dei comandi che conosco."
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:107
+msgid "'/help' shows this message again"
+msgstr "'/help' mostra questo messaggio"
+
+#. Translators: don't translate '/why'
+#: client/ai/lobbybot.c:110
+msgid "'/why' explains the purpose of this strange board layout"
+msgstr "'/why' spiega lo scopo di questa strana disposizione di gioco"
+
+#. Translators: don't translate '/news'
+#: client/ai/lobbybot.c:113
+msgid "'/news' tells the last released version"
+msgstr "'/news' indica l'ultima versione rilasciata"
+
+#: client/ai/lobbybot.c:118
+msgid ""
+"This board is not intended to be a game that can be played. Instead, players "
+"can find eachother here, and decide which board they want to play. Then, one "
+"of the players will host the proposed game by starting a server, and "
+"registers it at the metaserver. The other players can subsequently "
+"disconnect from the lobby, and enter that game."
+msgstr ""
+"Questa disposizione non è una partita che possa essere giocata. Qui i "
+"giocatori si possono incontrare e decidere quale disposizione vogliono "
+"giocare. Dopodiché uno dei giocatori ospiterà la partita proposta avviando "
+"un server e registrandolo sul metaserver. Gli altri giocatori si possono "
+"quindi sconnettere dalla lobby ed unirsi alla partita."
+
+#: client/ai/lobbybot.c:129
+msgid "The last released version of Pioneers is"
+msgstr "L'ultima versione rilasciata di Pioneers è"
+
+#: client/ai/lobbybot.c:144
+msgid "The game is starting. I'm not needed anymore. Goodbye."
+msgstr "La partita sta per iniziare. Non sono più necessario. Addio."
+
+#: client/common/client.c:103
+msgid "Waiting"
+msgstr "In attesa"
+
+#: client/common/client.c:105 client/common/client.c:1241
+msgid "Idle"
+msgstr "Inattivo"
+
+#: client/common/client.c:447
+msgid "We have been kicked out of the game.\n"
+msgstr "Siamo stati buttati fuori dalla partita.\n"
+
+#. Network status: offline
+#: client/common/client.c:450 client/common/client.c:891 client/gtk/gui.c:1340
+msgid "Offline"
+msgstr "Scollegato"
+
+#: client/common/client.c:471
+#, c-format
+msgid "Error (%s): %s\n"
+msgstr "Errore (%s): %s\n"
+
+#: client/common/client.c:480 client/common/client.c:491
+#, c-format
+msgid "Notice: %s\n"
+msgstr "Avviso: %s\n"
+
+#: client/common/client.c:607
+#, c-format
+msgid "%s does not receive any %s, because the bank is empty.\n"
+msgstr "%s non riceve nessun %s, poiché la banca è vuota.\n"
+
+#: client/common/client.c:620
+#, c-format
+msgid "%s only receives %s, because the bank didn't have any more.\n"
+msgstr "%s riceve solo %s, poiché la banca non ne ha oltre.\n"
+
+#: client/common/client.c:629
+#, c-format
+msgid "%s receives %s.\n"
+msgstr "%s riceve %s.\n"
+
+#. Year of Plenty
+#: client/common/client.c:637 client/common/client.c:2586
+#, c-format
+msgid "%s takes %s.\n"
+msgstr "%s prende %s.\n"
+
+#: client/common/client.c:642
+#, c-format
+msgid "%s spent %s.\n"
+msgstr "%s ha speso %s.\n"
+
+#: client/common/client.c:648
+#, c-format
+msgid "%s is refunded %s.\n"
+msgstr "%s è rimborsato con %s.\n"
+
+#: client/common/client.c:679
+#, c-format
+msgid "%s discarded %s.\n"
+msgstr "%s ha scartato %s.\n"
+
+#: client/common/client.c:849
+msgid "Loading"
+msgstr "In caricamento"
+
+#: client/common/client.c:892
+msgid "Version mismatch"
+msgstr "Versione non corrispondente"
+
+#: client/common/client.c:894
+msgid "Version mismatch. Please make sure client and server are up to date.\n"
+msgstr ""
+"Versione non corrispondente. Assicurarsi che client e server siano "
+"aggiornati.\n"
+
+#: client/common/client.c:1340
+msgid "Build two settlements, each with a connecting"
+msgstr "Costruisci due colonie, ognuna con una connessione"
+
+#: client/common/client.c:1343
+msgid "Build a settlement with a connecting"
+msgstr "Costruisci una colonia con"
+
+#: client/common/client.c:1346
+msgid "road"
+msgstr "una strada"
+
+#: client/common/client.c:1348
+msgid "bridge"
+msgstr "un ponte"
+
+#: client/common/client.c:1350
+msgid "ship"
+msgstr "una nave"
+
+#: client/common/client.c:1358
+msgid " or"
+msgstr " o"
+
+#: client/common/client.c:1416
+msgid "Waiting for your turn"
+msgstr "In attesa del tuo turno"
+
+#: client/common/client.c:1468
+msgid "Select the building to steal from."
+msgstr "Seleziona la costruzione da cui rubare."
+
+#: client/common/client.c:1490
+msgid "Select the ship to steal from."
+msgstr "Seleziona la nave da cui rubare."
+
+#: client/common/client.c:1575 client/gtk/interface.c:782
+msgid "Place the robber"
+msgstr "Posiziona il brigante"
+
+#: client/common/client.c:1625
+msgid "Finish the road building action."
+msgstr "Termina la costruzione della strada."
+
+#: client/common/client.c:1627
+msgid "Build one road segment."
+msgstr "Costruisci una strada."
+
+#: client/common/client.c:1629
+msgid "Build two road segments."
+msgstr "Costruisci due strade."
+
+#: client/common/client.c:1902 client/common/client.c:1996
+msgid "It is your turn."
+msgstr "E' il tuo turno."
+
+#: client/common/client.c:2090
+#, c-format
+msgid "Sorry, %s available.\n"
+msgstr "Mi dispiace, %s disponibile.\n"
+
+#: client/common/client.c:2405
+msgid "The game is over."
+msgstr "La partita è finita"
+
+#: client/common/develop.c:43 editor/gtk/game-devcards.c:13
+msgid "Road Building"
+msgstr "Costruzione di Strade"
+
+#: client/common/develop.c:44 client/gtk/monopoly.c:83
+#: editor/gtk/game-devcards.c:13
+msgid "Monopoly"
+msgstr "Monopolio"
+
+#: client/common/develop.c:45 client/gtk/plenty.c:59
+#: editor/gtk/game-devcards.c:13
+msgid "Year of Plenty"
+msgstr "Scoperta"
+
+#: client/common/develop.c:46 client/gtk/player.c:57
+#: editor/gtk/game-devcards.c:14
+msgid "Chapel"
+msgstr "Cattedrale"
+
+#: client/common/develop.c:47 client/gtk/player.c:58
+#: editor/gtk/game-devcards.c:14
+msgid "Pioneer University"
+msgstr "Università "
+
+#: client/common/develop.c:48 client/gtk/player.c:60
+#: editor/gtk/game-devcards.c:15
+msgid "Governor's House"
+msgstr "Parlamento"
+
+#: client/common/develop.c:49 client/gtk/player.c:61
+#: editor/gtk/game-devcards.c:15
+msgid "Library"
+msgstr "Biblioteca"
+
+#: client/common/develop.c:50 client/gtk/player.c:62
+#: editor/gtk/game-devcards.c:15
+msgid "Market"
+msgstr "Mercato"
+
+#: client/common/develop.c:51 client/gtk/player.c:63
+#: editor/gtk/game-devcards.c:16
+msgid "Soldier"
+msgstr "Cavaliere"
+
+#: client/common/develop.c:82
+#, c-format
+msgid "You bought the %s development card.\n"
+msgstr "Hai comprato la carta sviluppo %s.\n"
+
+#: client/common/develop.c:88
+#, c-format
+msgid "You bought a %s development card.\n"
+msgstr "Hai comprato una carta sviluppo %s.\n"
+
+#: client/common/develop.c:110
+#, c-format
+msgid "%s bought a development card.\n"
+msgstr "%s ha comprato una carta sviluppo.\n"
+
+#: client/common/develop.c:129
+#, c-format
+msgid "%s played the %s development card.\n"
+msgstr "%s ha giocato la carta sviluppo %s.\n"
+
+#: client/common/develop.c:134
+#, c-format
+msgid "%s played a %s development card.\n"
+msgstr "%s ha giocato una carta sviluppo %s.\n"
+
+#: client/common/develop.c:147
+msgid "You have run out of road segments.\n"
+msgstr "Hai terminato i segmenti di strada.\n"
+
+#. I get the cards!
+#.
+#: client/common/develop.c:187
+#, c-format
+msgid "You get %s from %s.\n"
+msgstr "Hai preso %s da %s.\n"
+
+#. I lose the cards!
+#.
+#: client/common/develop.c:193
+#, c-format
+msgid "%s took %s from you.\n"
+msgstr "%s ti ha preso %s.\n"
+
+#: client/common/develop.c:200
+#, c-format
+msgid "%s took %s from %s.\n"
+msgstr "%s ha preso %s da %s.\n"
+
+#: client/common/player.c:124 server/player.c:405
+#, c-format
+msgid "Viewer %d"
+msgstr "Spettatore %d"
+
+#: client/common/player.c:126
+#, c-format
+msgid "viewer %d"
+msgstr "spettatore %d"
+
+#: client/common/player.c:134 server/player.c:408
+#, c-format
+msgid "Player %d"
+msgstr "Giocatore %d"
+
+#: client/common/player.c:136
+#, c-format
+msgid "player %d"
+msgstr "giocatore %d"
+
+#: client/common/player.c:212
+#, c-format
+msgid "New viewer: %s.\n"
+msgstr "Nuovo spettatore: %s.\n"
+
+#: client/common/player.c:215 client/common/player.c:231
+#, c-format
+msgid "%s is now %s.\n"
+msgstr "%s è ora %s.\n"
+
+#: client/common/player.c:228
+#, c-format
+msgid "Player %d is now %s.\n"
+msgstr "Il giocatore %d è ora %s.\n"
+
+#: client/common/player.c:267
+#, c-format
+msgid "%s has quit\n"
+msgstr "%s ha lasciato\n"
+
+#: client/common/player.c:276
+msgid "There is no largest army.\n"
+msgstr "Non c'è cavaliere più potente.\n"
+
+#: client/common/player.c:279
+#, c-format
+msgid "%s has the largest army.\n"
+msgstr "%s ha il cavaliere più potente.\n"
+
+#: client/common/player.c:300
+msgid "There is no longest road.\n"
+msgstr "Non c'è la strada più lunga.\n"
+
+#: client/common/player.c:303
+#, c-format
+msgid "%s has the longest road.\n"
+msgstr "%s ha la strada più lunga.\n"
+
+#: client/common/player.c:324
+#, c-format
+msgid "Waiting for %s."
+msgstr "In attesa di %s."
+
+#. We are not in on the action
+#. someone stole a resource from someone else
+#: client/common/player.c:352
+#, c-format
+msgid "%s stole a resource from %s.\n"
+msgstr "%s ha rubato una materia prima da %s.\n"
+
+#: client/common/player.c:362
+#, c-format
+msgid "You stole %s from %s.\n"
+msgstr "Hai rubato %s da %s.\n"
+
+#: client/common/player.c:368
+#, c-format
+msgid "%s stole %s from you.\n"
+msgstr "%s ti ha rubato %s.\n"
+
+#: client/common/player.c:402
+#, c-format
+msgid "%s gave %s nothing!?\n"
+msgstr "%s non ha dato nulla a %s!?\n"
+
+#: client/common/player.c:408 client/common/player.c:416
+#, c-format
+msgid "%s gave %s %s for free.\n"
+msgstr "%s ha dato a %s %s gratis.\n"
+
+#: client/common/player.c:424
+#, c-format
+msgid "%s gave %s %s in exchange for %s.\n"
+msgstr "%s ha dato a %s %s in cambio di %s.\n"
+
+#: client/common/player.c:455
+#, c-format
+msgid "%s exchanged %s for %s.\n"
+msgstr "%s ha scambiato %s per %s.\n"
+
+#: client/common/player.c:475
+#, c-format
+msgid "%s built a road.\n"
+msgstr "%s ha costruito una strada.\n"
+
+#: client/common/player.c:487
+#, c-format
+msgid "%s built a ship.\n"
+msgstr "%s ha costruito una nave.\n"
+
+#: client/common/player.c:500
+#, c-format
+msgid "%s built a settlement.\n"
+msgstr "%s ha costruito una colonia.\n"
+
+#: client/common/player.c:519
+#, c-format
+msgid "%s built a city.\n"
+msgstr "%s ha costruito una città .\n"
+
+#: client/common/player.c:533
+#, c-format
+msgid "%s built a city wall.\n"
+msgstr "%s ha costruito una fortificazione.\n"
+
+#: client/common/player.c:544
+#, c-format
+msgid "player_build_add called with BUILD_NONE for user %s\n"
+msgstr "player_build_add chiamata con BUILD_NONE per l'utente %s\n"
+
+#: client/common/player.c:553
+#, c-format
+msgid "%s built a bridge.\n"
+msgstr "%s ha costruito un ponte.\n"
+
+#: client/common/player.c:579
+#, c-format
+msgid "%s removed a road.\n"
+msgstr "%s ha rimosso una strada.\n"
+
+#: client/common/player.c:589
+#, c-format
+msgid "%s removed a ship.\n"
+msgstr "%s ha rimosso una nave.\n"
+
+#: client/common/player.c:599
+#, c-format
+msgid "%s removed a settlement.\n"
+msgstr "%s ha rimosso una colonia.\n"
+
+#: client/common/player.c:610
+#, c-format
+msgid "%s removed a city.\n"
+msgstr "%s ha rimosso una città .\n"
+
+#: client/common/player.c:624
+#, c-format
+msgid "%s removed a city wall.\n"
+msgstr "%s ha rimosso una fortificazione.\n"
+
+#: client/common/player.c:634
+#, c-format
+msgid "player_build_remove called with BUILD_NONE for user %s\n"
+msgstr "player_build_remove chiamata con BUILD_NONE per l'utente %s\n"
+
+#: client/common/player.c:642
+#, c-format
+msgid "%s removed a bridge.\n"
+msgstr "%s ha tolto un ponte.\n"
+
+#: client/common/player.c:673
+#, c-format
+msgid "%s has cancelled a ship's movement.\n"
+msgstr "%s ha annullato un movimento di nave.\n"
+
+#: client/common/player.c:676
+#, c-format
+msgid "%s moved a ship.\n"
+msgstr "%s ha mosso una nave.\n"
+
+#. tell the user that someone got something
+#: client/common/player.c:696
+#, c-format
+msgid "%s received %s.\n"
+msgstr "%s ha ricevuto %s.\n"
+
+#: client/common/player.c:714
+msgid "server asks to lose invalid point.\n"
+msgstr "il server richiede di perdere un punto invalido.\n"
+
+#. tell the user the point is lost
+#: client/common/player.c:720
+#, c-format
+msgid "%s lost %s.\n"
+msgstr "%s ha perso %s.\n"
+
+#: client/common/player.c:743
+msgid "server asks to move invalid point.\n"
+msgstr "il server richiede di spostare un punto invalido.\n"
+
+#. tell the user someone (1) lost something (2) to someone else (3)
+#: client/common/player.c:750
+#, c-format
+msgid "%s lost %s to %s.\n"
+msgstr "%s ha perso %s per %s.\n"
+
+#: client/common/resource.c:35
+msgid "brick"
+msgstr "argilla"
+
+#: client/common/resource.c:35
+msgid "Brick"
+msgstr "Argilla"
+
+#: client/common/resource.c:36
+msgid "grain"
+msgstr "grano"
+
+#: client/common/resource.c:36
+msgid "Grain"
+msgstr "Grano"
+
+#: client/common/resource.c:37
+msgid "ore"
+msgstr "minerale"
+
+#: client/common/resource.c:37
+msgid "Ore"
+msgstr "Minerale"
+
+#: client/common/resource.c:38
+msgid "wool"
+msgstr "lana"
+
+#: client/common/resource.c:38
+msgid "Wool"
+msgstr "Lana"
+
+#: client/common/resource.c:39
+msgid "lumber"
+msgstr "legno"
+
+#: client/common/resource.c:39
+msgid "Lumber"
+msgstr "Legno"
+
+#: client/common/resource.c:40
+msgid "no resource (bug)"
+msgstr "nessuna materia prima (bug)"
+
+#: client/common/resource.c:40
+msgid "No resource (bug)"
+msgstr "Nessuna materia prima (bug)"
+
+#: client/common/resource.c:41
+msgid "any resource (bug)"
+msgstr "qualunque materia prima (bug)"
+
+#: client/common/resource.c:41
+msgid "Any resource (bug)"
+msgstr "Qualunque materia prima (bug)"
+
+#: client/common/resource.c:42
+msgid "gold"
+msgstr "oro"
+
+#: client/common/resource.c:42 client/gtk/legend.c:39
+msgid "Gold"
+msgstr "Oro"
+
+#: client/common/resource.c:47
+msgid "a brick card"
+msgstr "una carta argilla"
+
+#: client/common/resource.c:47
+#, c-format
+msgid "%d brick cards"
+msgstr "%d carte argilla"
+
+#: client/common/resource.c:48
+msgid "a grain card"
+msgstr "una carta grano"
+
+#: client/common/resource.c:48
+#, c-format
+msgid "%d grain cards"
+msgstr "%d carte grano"
+
+#: client/common/resource.c:49
+msgid "an ore card"
+msgstr "una carta minerale"
+
+#: client/common/resource.c:49
+#, c-format
+msgid "%d ore cards"
+msgstr "%d carte minerale"
+
+#: client/common/resource.c:50
+msgid "a wool card"
+msgstr "una carta lana"
+
+#: client/common/resource.c:50
+#, c-format
+msgid "%d wool cards"
+msgstr "%d carte lana"
+
+#: client/common/resource.c:51
+msgid "a lumber card"
+msgstr "una carta legno"
+
+#: client/common/resource.c:51
+#, c-format
+msgid "%d lumber cards"
+msgstr "%d carte legno"
+
+#: client/common/resource.c:139 client/common/resource.c:225
+msgid "nothing"
+msgstr "nulla"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:166
+#, c-format
+msgid "%s and %s"
+msgstr "%s e %s"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:170
+#, c-format
+msgid "%s, %s"
+msgstr "%s, %s"
+
+#: client/common/robber.c:60
+#, c-format
+msgid "%s has undone the robber movement.\n"
+msgstr "%s ha annullato il movimento del brigante.\n"
+
+#: client/common/robber.c:63
+#, c-format
+msgid "%s moved the robber.\n"
+msgstr "%s ha mosso il brigante.\n"
+
+#: client/common/robber.c:73
+#, c-format
+msgid "%s has undone the pirate movement.\n"
+msgstr "%s ha annullato il movimento dei pirati.\n"
+
+#: client/common/robber.c:76
+#, c-format
+msgid "%s moved the pirate.\n"
+msgstr "%s ha mosso il pirata.\n"
+
+#: client/common/robber.c:83
+#, c-format
+msgid "%s must move the robber."
+msgstr "%s deve muovere il brigante."
+
+#: client/common/setup.c:140
+#, c-format
+msgid "Setup for %s.\n"
+msgstr "Setup per %s.\n"
+
+#: client/common/setup.c:152
+#, c-format
+msgid "Double setup for %s.\n"
+msgstr "Doppio setup per %s.\n"
+
+#: client/common/turn.c:37
+#, c-format
+msgid "%s rolled %d.\n"
+msgstr "%s ha tirato %d.\n"
+
+#: client/common/turn.c:50
+#, c-format
+msgid "Begin turn %d for %s.\n"
+msgstr "Inizia il turno %d per %s.\n"
+
+#: client/gtk/chat.c:71
+msgid "<b>Chat</b>"
+msgstr "<b>Chat</b>"
+
+#: client/gtk/chat.c:231
+msgid "Beeper test.\n"
+msgstr "Suono di prova.\n"
+
+#: client/gtk/chat.c:234
+#, c-format
+msgid "%s beeped you.\n"
+msgstr "%s ti ha suonato.\n"
+
+#: client/gtk/chat.c:238
+#, c-format
+msgid "You beeped %s.\n"
+msgstr "Hai suonato a %s.\n"
+
+#: client/gtk/chat.c:244
+#, c-format
+msgid "You could not beep %s.\n"
+msgstr "Non puoi suonare a %s.\n"
+
+#: client/gtk/chat.c:288
+msgid " said: "
+msgstr " dice: "
+
+#: client/gtk/connect.c:282
+#, c-format
+msgid "Meta-server at %s, port %s"
+msgstr "Meta-server su %s, porta %s"
+
+#: client/gtk/connect.c:292
+msgid "Finished.\n"
+msgstr "Finito.\n"
+
+#: client/gtk/connect.c:309 client/gtk/connect.c:359 client/gtk/connect.c:456
+#: server/meta.c:174
+msgid "Meta-server kicked us off\n"
+msgstr "Il meta-server ci ha buttati fuori\n"
+
+#: client/gtk/connect.c:334
+msgid "Receiving game names from the meta server.\n"
+msgstr "Ricezione dei nomi partita dal meta server.\n"
+
+#: client/gtk/connect.c:382
+#, c-format
+msgid "New game server requested on %s port %s\n"
+msgstr "Nuovo server di partita richiesto su %s porta %s\n"
+
+#: client/gtk/connect.c:391 server/meta.c:168
+#, c-format
+msgid "Unknown message from the metaserver: %s\n"
+msgstr "Messaggio sconosciuto dal metaserver: %s\n"
+
+#: client/gtk/connect.c:472 server/meta.c:125
+msgid "Too many meta-server redirects\n"
+msgstr "Troppe redirezioni del metaserver\n"
+
+#: client/gtk/connect.c:499 server/meta.c:140
+#, c-format
+msgid "Bad redirect line: %s\n"
+msgstr "Riga di redirezione errata: %s\n"
+
+#: client/gtk/connect.c:525
+#, c-format
+msgid "Meta server too old to create servers (version %d.%d)\n"
+msgstr "Meta server troppo vecchio per creare server (versione %d.%d)\n"
+
+#. Sevens rule: normal
+#: client/gtk/connect.c:596 client/gtk/settingscreen.c:168
+#: common/gtk/game-rules.c:81
+msgid "Normal"
+msgstr "Normale"
+
+#: client/gtk/connect.c:602 client/gtk/settingscreen.c:170
+#: common/gtk/game-rules.c:88
+msgid "Reroll on 1st 2 turns"
+msgstr "Ritira i primi 2 turni"
+
+#: client/gtk/connect.c:605 client/gtk/settingscreen.c:172
+#: common/gtk/game-rules.c:95
+msgid "Reroll all 7s"
+msgstr "Ritira tutti i 7"
+
+#: client/gtk/connect.c:619
+msgid "Default"
+msgstr "Default"
+
+#: client/gtk/connect.c:622
+msgid "Random"
+msgstr "Casuale"
+
+#: client/gtk/connect.c:653 server/meta.c:188
+#, c-format
+msgid "Redirected to meta-server at %s, port %s\n"
+msgstr "Rediretto sul meta-server %s, porta %s\n"
+
+#: client/gtk/connect.c:656
+msgid "Receiving a list of Pioneers servers from the meta server.\n"
+msgstr "Ricezione della lista dei server Pioneers dal meta server.\n"
+
+#: client/gtk/connect.c:713
+msgid ""
+"<b>Note</b>:\n"
+"\tThe metaserver does not send information about the games.\n"
+"\tPlease set appropriate values yourself."
+msgstr ""
+"<b>Nota</b>:\n"
+"\tIl metaserver non invia informazioni relative alle partite.\n"
+"\tImposta i valori appropriati."
+
+#: client/gtk/connect.c:730
+msgid "Number of AI Players"
+msgstr "Numero di Giocatori AI"
+
+#: client/gtk/connect.c:749
+msgid "The number of AI players"
+msgstr "Numero di Giocatori AI"
+
+#: client/gtk/connect.c:770
+msgid "Requesting new game server\n"
+msgstr "Richiesta nuovo server di partita\n"
+
+#: client/gtk/connect.c:813 server/gtk/main.c:328 server/server.c:160
+#, c-format
+msgid "Error starting %s: %s"
+msgstr "Errore avviando %s: %s"
+
+#: client/gtk/connect.c:834
+msgid "Create a public game"
+msgstr "Crea una partita pubblica"
+
+#: client/gtk/connect.c:965 client/gtk/connect.c:1268
+msgid "Join a public game"
+msgstr "Unisciti a partita pubblica"
+
+#: client/gtk/connect.c:970
+msgid "_New remote game"
+msgstr "_Nuova partita remota"
+
+#: client/gtk/connect.c:984
+msgid "Refresh the list of games"
+msgstr "Aggiorna la lista delle partita"
+
+#: client/gtk/connect.c:989
+msgid "Create a new public game at the meta server"
+msgstr "Registra questa partita sul meta server"
+
+#: client/gtk/connect.c:994
+msgid "Don't join a public game"
+msgstr "Non unirti a partita pubblica"
+
+#: client/gtk/connect.c:998
+msgid "Join the selected game"
+msgstr "Unisciti alla partita selezionata"
+
+#: client/gtk/connect.c:1033
+msgid "Select a game to join"
+msgstr "Seleziona una partita a cui unirti"
+
+#: client/gtk/connect.c:1036
+msgid "Map Name"
+msgstr "Nome mappa"
+
+#: client/gtk/connect.c:1044
+msgid "Name of the game"
+msgstr "Nome della partita"
+
+#: client/gtk/connect.c:1049
+msgid "Curr"
+msgstr "Corr"
+
+#: client/gtk/connect.c:1055
+msgid "Number of players in the game"
+msgstr "Numero di giocatori in partita"
+
+#: client/gtk/connect.c:1060
+msgid "Max"
+msgstr "Max"
+
+#: client/gtk/connect.c:1066
+msgid "Maximum players for the game"
+msgstr "Massimo numero di giocatori"
+
+#: client/gtk/connect.c:1069
+msgid "Terrain"
+msgstr "Terreno"
+
+#: client/gtk/connect.c:1076
+msgid "Random of default terrain"
+msgstr "Terreno default casuale"
+
+#: client/gtk/connect.c:1081
+msgid "Vic. Points"
+msgstr "Punti Vitt."
+
+#: client/gtk/connect.c:1087
+msgid "Points needed to win"
+msgstr "Punti per vincere"
+
+#: client/gtk/connect.c:1090 common/gtk/game-rules.c:73
+msgid "Sevens Rule"
+msgstr "Regola Sette"
+
+#: client/gtk/connect.c:1096
+msgid "Sevens rule"
+msgstr "Regola sette"
+
+#: client/gtk/connect.c:1100
+msgid "Host"
+msgstr "Host"
+
+#: client/gtk/connect.c:1108
+msgid "Host of the game"
+msgstr "Host della partita"
+
+#: client/gtk/connect.c:1113
+msgid "Port"
+msgstr "Porta"
+
+#: client/gtk/connect.c:1119
+msgid "Port of the the game"
+msgstr "Porta della partita"
+
+#: client/gtk/connect.c:1122 common/gtk/aboutbox.c:77
+msgid "Version"
+msgstr "Versione"
+
+#: client/gtk/connect.c:1129
+msgid "Version of the host"
+msgstr "Versione dell'host"
+
+#: client/gtk/connect.c:1184 client/gtk/gui.c:215
+msgid "Start a new game"
+msgstr "Inizia una nuova partita"
+
+#: client/gtk/connect.c:1209
+msgid "Player Name"
+msgstr "Nome Giocatore"
+
+#: client/gtk/connect.c:1223
+msgid "Enter your name"
+msgstr "Inserisci il tuo nome"
+
+#. Role of the player: viewer
+#: client/gtk/connect.c:1225 server/gtk/main.c:511
+msgid "Viewer"
+msgstr "Spettatore"
+
+#: client/gtk/connect.c:1233
+msgid "Do you want to be a viewer?"
+msgstr "Vuoi essere uno spettatore?"
+
+#: client/gtk/connect.c:1240 server/gtk/main.c:640
+msgid "Meta Server"
+msgstr "Metaserver"
+
+#: client/gtk/connect.c:1255
+msgid "Leave empty for the default meta server"
+msgstr "Lascia vuoti per il meta server di default"
+
+#: client/gtk/connect.c:1263
+msgid "Join public game"
+msgstr "Unisciti a partita pubblica"
+
+#: client/gtk/connect.c:1272
+msgid "Create game"
+msgstr "Crea partita"
+
+#: client/gtk/connect.c:1275
+msgid "Create a game"
+msgstr "Crea una partita"
+
+#: client/gtk/connect.c:1285
+msgid "Join private game"
+msgstr "Unisciti a partita privata"
+
+#: client/gtk/connect.c:1289 client/gtk/connect.c:1434
+msgid "Join a private game"
+msgstr "Unisciti ad un partita privata"
+
+#: client/gtk/connect.c:1475
+msgid "Name of the host of the game"
+msgstr "Nome dell'host della partita"
+
+#: client/gtk/connect.c:1494
+msgid "Port of the host of the game"
+msgstr "Porta dell'host della partita"
+
+#: client/gtk/connect.c:1534
+msgid "Recent games"
+msgstr "Partite recenti"
+
+#: client/gtk/connect.c:1536
+msgid "Recent Games"
+msgstr "Partite Recenti"
+
+#: client/gtk/develop.c:129
+msgid "<b>Development Cards</b>"
+msgstr "<b>Carte Sviluppo</b>"
+
+#: client/gtk/develop.c:160
+msgid "Play Card"
+msgstr "Gioca Carta"
+
+#: client/gtk/discard.c:76
+msgid "Discard resources"
+msgstr "Scarta materie prime"
+
+#: client/gtk/discard.c:96
+#, c-format
+msgid "You must discard %d resources"
+msgstr "Devi scartare %d materie prime"
+
+#: client/gtk/discard.c:101
+msgid "Total discards"
+msgstr "Totale scarti"
+
+#. Caption for list of player that must discard cards
+#: client/gtk/discard.c:226
+msgid "<b>Waiting for players to discard</b>"
+msgstr "<b>In attesa degli scarti dei giocatori</b>"
+
+#: client/gtk/gameover.c:32
+msgid "Game over"
+msgstr "Fine partita"
+
+#: client/gtk/gameover.c:49
+#, c-format
+msgid "%s has won the game with %d victory points!"
+msgstr "%s ha vinto la partita con %d punti vittoria!"
+
+#: client/gtk/gameover.c:52
+#, c-format
+msgid "%s has won the game with %d victory points!\n"
+msgstr "%s ha vinto la partita con %d punti vittoria!\n"
+
+#: client/gtk/gameover.c:58
+#, c-format
+msgid "All praise %s, Lord of the known world!"
+msgstr "Onori a %s, Signore del Mondo conosciuto!"
+
+#: client/gtk/gold.c:71
+msgid "Choose resources"
+msgstr "Scegli materie prime"
+
+#: client/gtk/gold.c:92
+#, c-format
+msgid "You may choose 1 resource"
+msgstr "Puoi scegliere 1 materia prima"
+
+#: client/gtk/gold.c:94
+#, c-format
+msgid "You may choose %d resources"
+msgstr "Puoi scegliere %d materie prime"
+
+#. Text for total in choose gold dialog
+#. Text for total in year of plenty dialog
+#: client/gtk/gold.c:101 client/gtk/plenty.c:98
+msgid "Total resources"
+msgstr "Materie prime totali"
+
+#: client/gtk/gold.c:213
+msgid "<b>Waiting for players to choose</b>"
+msgstr "<b>In attesa di scelta dei giocatori</b>"
+
+#: client/gtk/gui.c:213 server/gtk/main.c:98
+msgid "_Game"
+msgstr "_Partita"
+
+#: client/gtk/gui.c:214
+msgid "_New game"
+msgstr "_Nuova partita"
+
+#: client/gtk/gui.c:216
+msgid "_Leave game"
+msgstr "_Lascia partita"
+
+#: client/gtk/gui.c:217
+msgid "Leave this game"
+msgstr "Lascia questa partita"
+
+#: client/gtk/gui.c:219
+msgid "_Admin"
+msgstr "_Amministra"
+
+#: client/gtk/gui.c:220
+msgid "Administer Pioneers server"
+msgstr "Amministra server Pioneers"
+
+#: client/gtk/gui.c:222
+msgid "_Player name"
+msgstr "Nome _Giocatore"
+
+#: client/gtk/gui.c:223
+msgid "Change your player name"
+msgstr "Cambia il tuo nome di giocatore"
+
+#: client/gtk/gui.c:224
+msgid "_Legend"
+msgstr "_Legenda"
+
+#: client/gtk/gui.c:225
+msgid "Terrain legend and building costs"
+msgstr "Legenda terreno e costi di costruzione"
+
+#: client/gtk/gui.c:226
+msgid "_Game Settings"
+msgstr "Impostazioni _Partita"
+
+#: client/gtk/gui.c:227
+msgid "Settings for the current game"
+msgstr "Impostazioni per la partita corrente"
+
+#: client/gtk/gui.c:228
+msgid "_Dice Histogram"
+msgstr "Istogramma _Tiri"
+
+#: client/gtk/gui.c:229
+msgid "Histogram of dice rolls"
+msgstr "Istogramma dei tiri dei dadi"
+
+#: client/gtk/gui.c:230 editor/gtk/editor.c:1018 server/gtk/main.c:103
+msgid "_Quit"
+msgstr "_Esci"
+
+#: client/gtk/gui.c:231 server/gtk/main.c:104
+msgid "Quit the program"
+msgstr "Esci dal programma"
+
+#: client/gtk/gui.c:232
+msgid "_Actions"
+msgstr "_Azioni"
+
+#: client/gtk/gui.c:233
+msgid "Roll Dice"
+msgstr "Tira Dadi"
+
+#: client/gtk/gui.c:234
+msgid "Roll the dice"
+msgstr "Tira i dadi"
+
+#. Tab page name
+#: client/gtk/gui.c:235 client/gtk/gui.c:577
+msgid "Trade"
+msgstr "Commercio"
+
+#: client/gtk/gui.c:237
+msgid "Undo"
+msgstr "Indietro"
+
+#: client/gtk/gui.c:238 client/gtk/gui.c:239
+msgid "Finish"
+msgstr "Finito"
+
+#: client/gtk/gui.c:240 client/gtk/legend.c:226 editor/gtk/game-buildings.c:13
+msgid "Road"
+msgstr "Strada"
+
+#: client/gtk/gui.c:241
+msgid "Build a road"
+msgstr "Costruisci una strada"
+
+#: client/gtk/gui.c:242 client/gtk/legend.c:230 editor/gtk/game-buildings.c:13
+msgid "Ship"
+msgstr "Nave"
+
+#: client/gtk/gui.c:243
+msgid "Build a ship"
+msgstr "Costruisci una nave"
+
+#: client/gtk/gui.c:244
+msgid "Move Ship"
+msgstr "Muovi Nave"
+
+#: client/gtk/gui.c:245
+msgid "Move a ship"
+msgstr "Muovi una nave"
+
+#: client/gtk/gui.c:246 client/gtk/legend.c:233 editor/gtk/game-buildings.c:13
+msgid "Bridge"
+msgstr "Ponte"
+
+#: client/gtk/gui.c:247
+msgid "Build a bridge"
+msgstr "Costruisci un ponte"
+
+#: client/gtk/gui.c:248 client/gtk/legend.c:235 client/gtk/player.c:52
+#: editor/gtk/game-buildings.c:13
+msgid "Settlement"
+msgstr "Colonia"
+
+#: client/gtk/gui.c:249
+msgid "Build a settlement"
+msgstr "Costruisci una colonia"
+
+#: client/gtk/gui.c:250 client/gtk/legend.c:236 client/gtk/player.c:53
+#: editor/gtk/game-buildings.c:14
+msgid "City"
+msgstr "Città "
+
+#: client/gtk/gui.c:251
+msgid "Build a city"
+msgstr "Costruisci una città "
+
+#: client/gtk/gui.c:252
+msgid "Develop"
+msgstr "Sviluppo"
+
+#: client/gtk/gui.c:253
+msgid "Buy a development card"
+msgstr "Compra una carta sviluppo"
+
+#: client/gtk/gui.c:254 client/gtk/legend.c:240 client/gtk/player.c:54
+#: editor/gtk/game-buildings.c:14
+msgid "City Wall"
+msgstr "Fortificazione"
+
+#: client/gtk/gui.c:255
+msgid "Build a city wall"
+msgstr "Costruisci una fortificazione"
+
+#: client/gtk/gui.c:257
+msgid "_Settings"
+msgstr "_Impostazioni"
+
+#: client/gtk/gui.c:258
+msgid "Prefere_nces"
+msgstr "Prefere_nze"
+
+#: client/gtk/gui.c:259
+msgid "Configure the application"
+msgstr "Configura l'applicazione"
+
+#: client/gtk/gui.c:261 client/gtk/gui.c:265 editor/gtk/editor.c:1002
+#: server/gtk/main.c:99
+msgid "_Help"
+msgstr "_Aiuto"
+
+#: client/gtk/gui.c:262
+msgid "_About Pioneers"
+msgstr "_Riguardo Pioneers"
+
+#: client/gtk/gui.c:263
+msgid "Information about Pioneers"
+msgstr "Informazioni su Pioneers"
+
+#: client/gtk/gui.c:266 client/gtk/gui.c:1065
+msgid "Show the manual"
+msgstr "Visualizza il manuale"
+
+#: client/gtk/gui.c:272
+msgid "_Toolbar"
+msgstr "_Toolbar"
+
+#: client/gtk/gui.c:273
+msgid "Show or hide the toolbar"
+msgstr "Mostra o nasconde la toolbar"
+
+#. Victory points target in statusbar
+#: client/gtk/gui.c:368
+#, c-format
+msgid "Points Needed to Win: %i"
+msgstr "Punti per Vincere: %i"
+
+#: client/gtk/gui.c:454
+msgid "<b>Messages</b>"
+msgstr "<b>Messaggi</b>"
+
+#. Tab page name
+#: client/gtk/gui.c:571 editor/gtk/editor.c:1165
+msgid "Map"
+msgstr "Mappa"
+
+#. Tab page name
+#: client/gtk/gui.c:585 client/gtk/quote.c:306
+msgid "Quote"
+msgstr "Quotazione"
+
+#. Tab page name
+#: client/gtk/gui.c:593 client/gtk/legend.c:261
+msgid "Legend"
+msgstr "Legenda"
+
+#. Tab page name, shown for the splash screen
+#: client/gtk/gui.c:603
+msgid "Welcome to Pioneers"
+msgstr "Benvenuto a Pioneers"
+
+#: client/gtk/gui.c:868
+msgid "Pioneers Preferences"
+msgstr "Preferenze Pioneers"
+
+#. Label for changing the theme, in the preferences dialog
+#: client/gtk/gui.c:898
+msgid "Theme:"
+msgstr "Tema:"
+
+#: client/gtk/gui.c:921
+msgid "Choose one of the themes"
+msgstr "Scegli uno dei temi"
+
+#. Label for the option to show the legend
+#: client/gtk/gui.c:925
+msgid "Show legend"
+msgstr "Visualizza legenda"
+
+#. Tooltip for the option to show the legend
+#: client/gtk/gui.c:935
+msgid "Show the legend as a page beside the map"
+msgstr "Visualizza legenda a lato della mappa"
+
+#. Label for the option to display log messages in color
+#: client/gtk/gui.c:940
+msgid "Messages with color"
+msgstr "Messaggi colorati"
+
+#: client/gtk/gui.c:950
+msgid "Show new messages with color"
+msgstr "Visualizza nuovi messaggi colorati"
+
+#: client/gtk/gui.c:955
+msgid "Chat in color of player"
+msgstr "Chatta a colori"
+
+#: client/gtk/gui.c:966
+msgid "Show new chat messages in the color of the player"
+msgstr "Visualizza i nuovi messaggi di chat a colori"
+
+#. Label for the option to display the summary with colors
+#: client/gtk/gui.c:971
+msgid "Summary with color"
+msgstr "Riassunto giocatore colorato"
+
+#: client/gtk/gui.c:982
+msgid "Use colors in the player summary"
+msgstr "Usa i colori nel riassunto giocatore"
+
+#: client/gtk/gui.c:987
+msgid "Toolbar with shortcuts"
+msgstr "Toolbar con acceleratore"
+
+#: client/gtk/gui.c:997
+msgid "Show keyboard shortcuts in the toolbar"
+msgstr "Visualizza acceleratori nella toolbar"
+
+#: client/gtk/gui.c:1003
+msgid "Announce new players"
+msgstr "Annuncia nuovi giocatori"
+
+#: client/gtk/gui.c:1014
+msgid "Make a sound when a new player or viewer enters the game"
+msgstr ""
+"Esegue un suono quando un nuovo giocatore o spettatore entra nella partita"
+
+#. Label for the option to use the 16:9 layout.
+#: client/gtk/gui.c:1019
+msgid "Use 16:9 layout"
+msgstr "Usa disposizione 16:9"
+
+#: client/gtk/gui.c:1030
+msgid "Use a 16:9 friendly layout for the window"
+msgstr "Usa la disposizione 16:9 per la finestra"
+
+#: client/gtk/gui.c:1041
+msgid "The Pioneers Game"
+msgstr "Pioneers - Il gioco"
+
+#. Initial text in status bar
+#: client/gtk/gui.c:1352
+msgid "Welcome to Pioneers!"
+msgstr "Benvenuto a Pioneers!"
+
+#. The name of the application
+#: client/gtk/gui.c:1463
+msgid "Pioneers"
+msgstr "Pioneers"
+
+#: client/gtk/histogram.c:252
+msgid "Dice Histogram"
+msgstr "Istogramma dei Tiri"
+
+#: client/gtk/interface.c:92
+msgid "Ship movement canceled."
+msgstr "Movimento della nave annullato."
+
+#: client/gtk/interface.c:100 client/gtk/interface.c:101
+msgid "Select a new location for the ship."
+msgstr "Seleziona una nuova posizione per la nave."
+
+#: client/gtk/interface.c:740
+msgid "Select the ship to steal from"
+msgstr "Seleziona la nave da cui rubare"
+
+#: client/gtk/interface.c:750
+msgid "Select the building to steal from"
+msgstr ""
+"Seleziona la costruzione\n"
+"da cui rubare"
+
+#: client/gtk/legend.c:32
+msgid "Hill"
+msgstr "Collina"
+
+#: client/gtk/legend.c:33
+msgid "Field"
+msgstr "Campo"
+
+#: client/gtk/legend.c:34
+msgid "Mountain"
+msgstr "Montagna"
+
+#: client/gtk/legend.c:35
+msgid "Pasture"
+msgstr "Pascolo"
+
+#: client/gtk/legend.c:36
+msgid "Forest"
+msgstr "Foresta"
+
+#: client/gtk/legend.c:37
+msgid "Desert"
+msgstr "Deserto"
+
+#: client/gtk/legend.c:38
+msgid "Sea"
+msgstr "Mare"
+
+#: client/gtk/legend.c:170
+msgid "<b>Terrain Yield</b>"
+msgstr "<b>Produzione Terreno</b>"
+
+#: client/gtk/legend.c:202
+msgid "<b>Building Costs</b>"
+msgstr "<b>Costi di Costruzione</b>"
+
+#: client/gtk/legend.c:243
+msgid "Development Card"
+msgstr "Carta Sviluppo"
+
+#: client/gtk/monopoly.c:105
+msgid "Select the resource you wish to monopolise."
+msgstr "Scegli la materia prima da monopolizzare."
+
+#: client/gtk/name.c:123
+msgid "Change player name"
+msgstr "Cambia nome giocatore"
+
+#: client/gtk/name.c:146
+msgid "Player Name:"
+msgstr "Nome Giocatore:"
+
+#. Set icon preferences
+#: client/gtk/name.c:202
+msgid "Face:"
+msgstr "Volto:"
+
+#: client/gtk/name.c:217
+msgid "Variant:"
+msgstr "Variante:"
+
+#. Commandline option of client: name of the player
+#: client/gtk/offline.c:59
+msgid "Player name"
+msgstr "Nome Giocatore"
+
+#: client/gtk/offline.c:63
+msgid "Connect as a viewer"
+msgstr "Connetti come spettatore"
+
+#: client/gtk/offline.c:66
+msgid "Meta-server Host"
+msgstr "Metaserver Host"
+
+#: client/gtk/offline.c:70
+msgid "Override the language of the system"
+msgstr "Scavalca la lingua del sistema"
+
+#: client/gtk/offline.c:100
+msgid "Connecting"
+msgstr "Connessione"
+
+#. Long description in the commandline for pioneers: help
+#: client/gtk/offline.c:175
+msgid "- Play a game of Pioneers"
+msgstr "- Gioca una partita a Pioneers"
+
+#: client/gtk/player.c:52
+msgid "Settlements"
+msgstr "Colonie"
+
+#: client/gtk/player.c:53
+msgid "Cities"
+msgstr "Città "
+
+#: client/gtk/player.c:54
+msgid "City Walls"
+msgstr "Fortificazioni"
+
+#: client/gtk/player.c:55
+msgid "Largest Army"
+msgstr "Cavaliere più potente"
+
+#: client/gtk/player.c:56
+msgid "Longest Road"
+msgstr "Strada più lunga"
+
+#: client/gtk/player.c:57
+msgid "Chapels"
+msgstr "Cappelle"
+
+#: client/gtk/player.c:58
+msgid "Pioneer Universities"
+msgstr "Università del Pioniere"
+
+#: client/gtk/player.c:60
+msgid "Governor's Houses"
+msgstr "Case del Governatore"
+
+#: client/gtk/player.c:61
+msgid "Libraries"
+msgstr "Biblioteche"
+
+#: client/gtk/player.c:62
+msgid "Markets"
+msgstr "Mercati"
+
+#: client/gtk/player.c:63
+msgid "Soldiers"
+msgstr "Cavalieri"
+
+#: client/gtk/player.c:64
+msgid "Resource card"
+msgstr "Materia prima"
+
+#: client/gtk/player.c:64
+msgid "Resource cards"
+msgstr "Materie prime"
+
+#: client/gtk/player.c:65
+msgid "Development card"
+msgstr "Carta sviluppo"
+
+#: client/gtk/player.c:65
+msgid "Development cards"
+msgstr "Carte sviluppo"
+
+#. Caption for the overview of the points and card of other players
+#: client/gtk/player.c:561
+msgid "<b>Player Summary</b>"
+msgstr "<b>Riassunto Giocatore</b>"
+
+#: client/gtk/plenty.c:87
+msgid "Please choose one resource from the bank"
+msgstr "Scegli una materia prima dalla banca"
+
+#: client/gtk/plenty.c:90
+msgid "Please choose two resources from the bank"
+msgstr "Prendi due materie prime dalla banca"
+
+#: client/gtk/plenty.c:92
+msgid "The bank is empty"
+msgstr "La banca è vuota"
+
+#: client/gtk/quote.c:186
+#, c-format
+msgid "%s has %s, and is looking for %s"
+msgstr "%s ha %s, e cerca %s"
+
+#: client/gtk/quote.c:287
+msgid "I Want"
+msgstr "Voglio"
+
+#: client/gtk/quote.c:295
+msgid "Give Them"
+msgstr "Dai Loro"
+
+#: client/gtk/quote.c:311
+msgid "Delete"
+msgstr "Cancella"
+
+#: client/gtk/quote.c:335
+msgid "Reject Domestic Trade"
+msgstr "Rifiuta Commercio Interno"
+
+#. Now create columns
+#. Table header: Player who trades
+#. Role of the player: player
+#: client/gtk/quote-view.c:170 server/gtk/main.c:513
+msgid "Player"
+msgstr "Giocatore"
+
+#. Table header: Quote
+#: client/gtk/quote-view.c:185
+msgid "Quotes"
+msgstr "Quotazione"
+
+#. trade: maritime quote: %1 resources of type %2 for
+#. * one resource of type %3
+#: client/gtk/quote-view.c:292
+#, c-format
+msgid "%d:1 %s for %s"
+msgstr "%d:1 %s per %s"
+
+#. Trade: a player has rejected trade
+#: client/gtk/quote-view.c:431
+msgid "Rejected trade"
+msgstr "Scambio rifiutato"
+
+#. Caption for overview of the resources of the player
+#: client/gtk/resource.c:113
+msgid "<b>Resources</b>"
+msgstr "<b>Materie prime</b>"
+
+#: client/gtk/resource.c:129
+msgid "Total"
+msgstr "Totale"
+
+#. Tooltip for the amount of resources in the hand
+#: client/gtk/resource-table.c:187
+msgid "Amount in hand"
+msgstr "Ammontare in mano"
+
+#: client/gtk/resource-table.c:191
+msgid "<less"
+msgstr "<meno"
+
+#. Tooltip for decreasing the selected amount
+#: client/gtk/resource-table.c:201
+msgid "Decrease the selected amount"
+msgstr "Decrementa l'ammontare selezionato"
+
+#. Tooltip for the amount of resources in the bank
+#: client/gtk/resource-table.c:215
+msgid "Amount in the bank"
+msgstr "Ammontare in banca"
+
+#: client/gtk/resource-table.c:219
+msgid "more>"
+msgstr "più>"
+
+#. Tooltip for increasing the selected amount
+#: client/gtk/resource-table.c:231
+msgid "Increase the selected amount"
+msgstr "Incrementa l'ammontare selezionato"
+
+#. Tooltip for the selected amount
+#: client/gtk/resource-table.c:248
+msgid "Selected amount"
+msgstr "Ammontare selezionato"
+
+#. Tooltip for the total selected amount
+#: client/gtk/resource-table.c:293
+msgid "Total selected amount"
+msgstr "Ammontare selezionato totale"
+
+#: client/gtk/resource-table.c:314
+msgid "The bank cannot be emptied"
+msgstr "La banca non può essere svuotata"
+
+#: client/gtk/settingscreen.c:74
+msgid "Yes"
+msgstr "Sì"
+
+#: client/gtk/settingscreen.c:76 client/gtk/settingscreen.c:207
+msgid "No"
+msgstr "No"
+
+#: client/gtk/settingscreen.c:87 client/gtk/settingscreen.c:174
+msgid "Unknown"
+msgstr "Sconosciuto"
+
+#: client/gtk/settingscreen.c:121
+msgid "No game in progress..."
+msgstr "Nessuna partita in corso..."
+
+#: client/gtk/settingscreen.c:131
+msgid "<b>General Settings</b>"
+msgstr "<b>Impostazioni Generali</b>"
+
+#: client/gtk/settingscreen.c:147
+msgid "Number of players:"
+msgstr "Numero di giocatori:"
+
+#: client/gtk/settingscreen.c:150
+msgid "Victory Point Target:"
+msgstr "Obiettivo Punti Vittoria:"
+
+#: client/gtk/settingscreen.c:153
+msgid "Random Terrain?"
+msgstr "Terreno Casuale?"
+
+#: client/gtk/settingscreen.c:156
+msgid "Interplayer Trading Allowed?"
+msgstr "Commercio tra giocatori?"
+
+#: client/gtk/settingscreen.c:160
+msgid "Trading allowed only before build/buy?"
+msgstr "Commercio permesso solo prima di costruire/comprare?"
+
+#: client/gtk/settingscreen.c:163
+msgid "Amount of Each Resource:"
+msgstr "Quantità per Ogni Materia prima:"
+
+#: client/gtk/settingscreen.c:177
+msgid "Sevens Rule:"
+msgstr "Regola Sette:"
+
+#: client/gtk/settingscreen.c:181
+msgid "Use Pirate:"
+msgstr "Usa i pirati:"
+
+#: client/gtk/settingscreen.c:209
+msgid "Island Discovery Bonuses:"
+msgstr "Bonus per scoperta isole:"
+
+#: client/gtk/settingscreen.c:224
+msgid "<b>Building Quotas</b>"
+msgstr "<b>Quotazioni costruzioni</b>"
+
+#: client/gtk/settingscreen.c:241
+msgid "Roads:"
+msgstr "Strade:"
+
+#: client/gtk/settingscreen.c:247
+msgid "Settlements:"
+msgstr "Colonie:"
+
+#: client/gtk/settingscreen.c:253
+msgid "Cities:"
+msgstr "Città :"
+
+#: client/gtk/settingscreen.c:259
+msgid "City Walls:"
+msgstr "Fortificazioni:"
+
+#: client/gtk/settingscreen.c:265
+msgid "Ships:"
+msgstr "Navi:"
+
+#: client/gtk/settingscreen.c:271
+msgid "Bridges:"
+msgstr "Ponti:"
+
+#: client/gtk/settingscreen.c:283
+msgid "<b>Development Card Deck</b>"
+msgstr "<b>Mazzo Carte Sviluppo</b>"
+
+#: client/gtk/settingscreen.c:299
+msgid "Road Building Cards:"
+msgstr "Carte Costruzione di Strade:"
+
+#: client/gtk/settingscreen.c:303
+msgid "Monopoly Cards:"
+msgstr "Carte Monopolio:"
+
+#: client/gtk/settingscreen.c:307
+msgid "Year of Plenty Cards:"
+msgstr "Carte Scoperta:"
+
+#: client/gtk/settingscreen.c:312
+msgid "Chapel Cards:"
+msgstr "Carte Cattedrale:"
+
+#: client/gtk/settingscreen.c:316
+msgid "Pioneer University Cards:"
+msgstr "Carte Università :"
+
+#: client/gtk/settingscreen.c:320
+msgid "Governor's House Cards:"
+msgstr "Carte Parlamento:"
+
+#: client/gtk/settingscreen.c:325
+msgid "Library Cards:"
+msgstr "Carte Biblioteca:"
+
+#: client/gtk/settingscreen.c:329
+msgid "Market Cards:"
+msgstr "Carte Mercato:"
+
+#: client/gtk/settingscreen.c:333
+msgid "Soldier Cards:"
+msgstr "Carte Cavaliere:"
+
+#: client/gtk/settingscreen.c:370
+msgid "Current Game Settings"
+msgstr "Impostazioni per la partita corrente"
+
+#. trade: you ask for something for free
+#: client/gtk/trade.c:193
+#, c-format
+msgid "ask for %s for free"
+msgstr "chiedi %s gratis"
+
+#. trade: you give something away for free
+#: client/gtk/trade.c:198
+#, c-format
+msgid "give %s for free"
+msgstr "cede %s gratis"
+
+#. trade: you trade something for something else
+#: client/gtk/trade.c:203
+#, c-format
+msgid "give %s for %s"
+msgstr "cede %s per %s"
+
+#. I want some resources, and give them some resources
+#: client/gtk/trade.c:230
+#, c-format
+msgid "I want %s, and give them %s"
+msgstr "Io voglio %s, dai loro %s"
+
+#. Frame title, trade: I want to trade these resources
+#: client/gtk/trade.c:427
+msgid "<b>I Want</b>"
+msgstr "<b>Voglio</b>"
+
+#. Frame title, trade: I want these resources in return
+#: client/gtk/trade.c:455
+msgid "<b>Give Them</b>"
+msgstr "<b>Dai Loro</b>"
+
+#. Button text, trade: call for quotes from other players
+#: client/gtk/trade.c:484
+msgid "_Call for Quotes"
+msgstr "_Chiedi Quotazioni"
+
+#. Button text: Trade page, accept selected quote
+#: client/gtk/trade.c:512
+msgid "_Accept Quote"
+msgstr "_Accetta Quotazione"
+
+#. Button text: Trade page, finish trading
+#: client/gtk/trade.c:518
+msgid "_Finish Trading"
+msgstr "_Termina Contrattazioni"
+
+#: common/gtk/aboutbox.c:74
+msgid ""
+"Pioneers is based upon the excellent\n"
+"Settlers of Catan board game.\n"
+msgstr ""
+"Pioneers è basato sull'eccellente gioco\n"
+"I Coloni di Catan.\n"
+
+#: common/gtk/aboutbox.c:83
+msgid "Homepage"
+msgstr "Homepage"
+
+#: common/gtk/aboutbox.c:88
+msgid "Authors"
+msgstr "Autori"
+
+#. Tooltip for sevens rule normal
+#: common/gtk/game-rules.c:101
+msgid "All sevens move the robber or pirate"
+msgstr "Tutti i sette muovono il brigante o i pirati"
+
+#: common/gtk/game-rules.c:106
+msgid "In the first two turns all sevens are rerolled"
+msgstr "Nei primi due turni tutti i sette vengono ritirati"
+
+#. Tooltip for sevens rule reroll all
+#: common/gtk/game-rules.c:110
+msgid "All sevens are rerolled"
+msgstr "Tutti i sette vengono ritirati"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize Terrain"
+msgstr "Terreno Casuale"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize the terrain"
+msgstr "Rende il terreno casuale"
+
+#: common/gtk/game-rules.c:123
+msgid "Use Pirate"
+msgstr "Usa i pirati"
+
+#: common/gtk/game-rules.c:123
+msgid "Use the pirate to block ships"
+msgstr "Usa i pirati per bloccare le navi"
+
+#: common/gtk/game-rules.c:125
+msgid "Strict Trade"
+msgstr "Commercio rigoroso"
+
+#: common/gtk/game-rules.c:126
+msgid "Allow trade only before building or buying"
+msgstr "Commercio permesso solo prima di costruire/comprare"
+
+#: common/gtk/game-rules.c:128
+msgid "Domestic Trade"
+msgstr "Commercio interno"
+
+#: common/gtk/game-rules.c:128
+msgid "Allow trade between players"
+msgstr "Commercio permesso tra i giocatori"
+
+#. Label text for customising a game
+#: common/gtk/game-settings.c:118
+msgid "Number of Players"
+msgstr "Numero di Giocatori"
+
+#. Tooltip for 'Number of Players'
+#: common/gtk/game-settings.c:136
+msgid "The number of players"
+msgstr "Il numero di giocatori"
+
+#. Label for customising a game
+#: common/gtk/game-settings.c:139
+msgid "Victory Point Target"
+msgstr "Obiettivo Punti Vittoria"
+
+#. Tooltip for Victory Point Target
+#: common/gtk/game-settings.c:159
+msgid "The points needed to win the game"
+msgstr "I punti per vincere la partita"
+
+#. Tooltip for the check button
+#: common/gtk/game-settings.c:172
+msgid "Is it possible to win this game?"
+msgstr "E' possibile vincere questa partita?"
+
+#. Port indicator for a resource: trade 2 for 1
+#: common/gtk/guimap.c:750
+msgid "2:1"
+msgstr "2:1"
+
+#. Port indicator: trade 3 for 1
+#. General port indicator
+#: common/gtk/guimap.c:753 common/gtk/guimap.c:778
+msgid "3:1"
+msgstr "3:1"
+
+#. Tooltip for the list of games
+#: common/gtk/select-game.c:111
+msgid "Select a game"
+msgstr "Seleziona una partita"
+
+#: common/gtk/theme.c:709
+#, c-format
+msgid "bad scaling mode '%s'"
+msgstr "modo '%s' non riconosciuto"
+
+#: common/game.c:603 common/game.c:633
+msgid "This game cannot be won."
+msgstr "Questa partita non può essere vinta."
+
+#: common/game.c:604
+msgid "There is no land."
+msgstr "Non c'è più terreno."
+
+#: common/game.c:638
+msgid "It is possible that this game cannot be won."
+msgstr "E' possibile che questa partita non possa essere vinta."
+
+#: common/game.c:643
+msgid "This game can be won by only building all settlements and cities."
+msgstr ""
+"Questa partita può essere solo vinta costruendo tutte le colonie e le città "
+
+#: common/game.c:650
+#, c-format
+msgid ""
+"Required victory points: %d\n"
+"Points obtained by building all: %d\n"
+"Points in development cards: %d\n"
+"Longest road/largest army: %d+%d\n"
+"Maximum island discovery bonus: %d\n"
+"Total: %d"
+msgstr ""
+"Punti vittoria richiesti: %d\n"
+"Punti ottenuti costruendo tutto: %d\n"
+"Punti nelle carte sviluppo: %d\n"
+"Strada più lunga/cavaliere più potente: %d+%d\n"
+"Massimo bonus per scoperta isole: %d\n"
+"Totale: %d"
+
+#: common/log.c:54
+msgid "*ERROR* "
+msgstr "*ERRORE*"
+
+#: common/log.c:60
+msgid "Chat: "
+msgstr "Chat: "
+
+#: common/log.c:63
+msgid "Resource: "
+msgstr "Materia prima: "
+
+#: common/log.c:66
+msgid "Build: "
+msgstr "Costruzioni:"
+
+#: common/log.c:69
+msgid "Dice: "
+msgstr "Dadi: "
+
+#: common/log.c:72
+msgid "Steal: "
+msgstr "Furti: "
+
+#: common/log.c:75
+msgid "Trade: "
+msgstr "Commercio: "
+
+#: common/log.c:78
+msgid "Development: "
+msgstr "Sviluppo: "
+
+#: common/log.c:81
+msgid "Army: "
+msgstr "Cavaliere: "
+
+#: common/log.c:84
+msgid "Road: "
+msgstr "Strada: "
+
+#: common/log.c:87
+msgid "*BEEP* "
+msgstr "*BEEP* "
+
+#: common/log.c:92
+msgid "Player 1: "
+msgstr "Giocatore 1: "
+
+#: common/log.c:95
+msgid "Player 2: "
+msgstr "Giocatore 2: "
+
+#: common/log.c:98
+msgid "Player 3: "
+msgstr "Giocatore 3: "
+
+#: common/log.c:101
+msgid "Player 4: "
+msgstr "Giocatore 4: "
+
+#: common/log.c:104
+msgid "Player 5: "
+msgstr "Giocatore 5: "
+
+#: common/log.c:107
+msgid "Player 6: "
+msgstr "Giocatore 6: "
+
+#: common/log.c:110
+msgid "Player 7: "
+msgstr "Giocatore 7: "
+
+#: common/log.c:113
+msgid "Player 8: "
+msgstr "Giocatore 8: "
+
+#: common/log.c:116
+msgid "Viewer: "
+msgstr "Spettatore: "
+
+#: common/log.c:119
+msgid "** UNKNOWN MESSAGE TYPE ** "
+msgstr "** TIPO MESSAGGIO SCONOSCIUTO **"
+
+#: common/network.c:281
+#, c-format
+msgid "Error checking connect status: %s\n"
+msgstr "Errore verifica stato connessione: %s\n"
+
+#: common/network.c:288
+#, c-format
+msgid "Error connecting to host '%s': %s\n"
+msgstr "Errore connessione a host '%s': %s\n"
+
+#: common/network.c:314
+#, c-format
+msgid "Error writing socket: %s\n"
+msgstr "Errore scrittura socket: %s\n"
+
+#: common/network.c:365
+#, c-format
+msgid "Error writing to socket: %s\n"
+msgstr "Errore scrittura su socket: %s\n"
+
+#: common/network.c:418
+msgid "Read buffer overflow - disconnecting\n"
+msgstr "Overflow del buffer di lettura - disconnessione\n"
+
+#: common/network.c:428
+#, c-format
+msgid "Error reading socket: %s\n"
+msgstr "Errore lettura socket: %s\n"
+
+#: common/network.c:575
+#, c-format
+msgid "Cannot resolve %s port %s: %s\n"
+msgstr "Impossibile risolvere %s porta %s: %s\n"
+
+#: common/network.c:582
+#, c-format
+msgid "Cannot resolve %s port %s: host not found\n"
+msgstr "Impossibile risolvere %s porta %s: host non trovato\n"
+
+#: common/network.c:597
+#, c-format
+msgid "Error creating socket: %s\n"
+msgstr "Errore creazione socket: %s\n"
+
+#: common/network.c:605
+#, c-format
+msgid "Error setting socket close-on-exec: %s\n"
+msgstr "Errore nell'impostazione close-on-exec per il socket: %s\n"
+
+#: common/network.c:615 common/network.c:776
+#, c-format
+msgid "Error setting socket non-blocking: %s\n"
+msgstr "Errore nell'impostazione non-blocking per il socket: %s\n"
+
+#: common/network.c:640
+#, c-format
+msgid "Error connecting to %s: %s\n"
+msgstr "Errore di connessione a %s: %s\n"
+
+#: common/network.c:735
+#, c-format
+msgid "Error creating struct addrinfo: %s"
+msgstr "Errore nella creazione della struct addrinfo: %s"
+
+#: common/network.c:765
+#, c-format
+msgid "Error creating listening socket: %s\n"
+msgstr "Errore nella creazione del socket di ascolto: %s\n"
+
+#: common/network.c:785
+#, c-format
+msgid "Error during listen on socket: %s\n"
+msgstr "Errore di ascolto sul socket: %s\n"
+
+#: common/network.c:794
+msgid "Listening not yet supported on this platform."
+msgstr "Ascolto non ancora supportato su questa piattaforma."
+
+#: common/network.c:816 common/network.c:817
+msgid "unknown"
+msgstr "sconosciuto"
+
+#: common/network.c:823
+#, c-format
+msgid "Error getting peer name: %s"
+msgstr "Errore recupero nome: %s"
+
+#: common/network.c:836
+#, c-format
+msgid "Error resolving address: %s"
+msgstr "Errore in risoluzione dell'indirizzo: %s"
+
+#: common/network.c:850
+msgid "Net_get_peer_name not yet supported on this platform."
+msgstr "Net_get_peer_name non ancora supportato su questa piattaforma."
+
+#: common/network.c:865
+#, c-format
+msgid "Error accepting connection: %s"
+msgstr "Errore accettando la connessione: %s"
+
+#: common/state.c:166
+#, c-format
+msgid "Connecting to %s, port %s\n"
+msgstr "Connessione a %s, porta %s\n"
+
+#: common/state.c:503
+msgid "State stack overflow. Stack dump sent to standard error.\n"
+msgstr ""
+"Overflow dello stack di stato. Dump dello stack inviato sullo standard "
+"error.\n"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:73
+msgid "_Hill"
+msgstr "C_ollina"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:75
+msgid "_Field"
+msgstr "_Campo"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:77
+msgid "_Mountain"
+msgstr "_Montagna"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:79
+msgid "_Pasture"
+msgstr "_Pascolo"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:81
+msgid "F_orest"
+msgstr "_Foresta"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:83
+msgid "_Desert"
+msgstr "_Deserto"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:85
+msgid "_Sea"
+msgstr "M_are"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:87
+msgid "_Gold"
+msgstr "_Oro"
+
+#. Use an unique shortcut key for each resource
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:89 editor/gtk/editor.c:104
+msgid "_None"
+msgstr "_Nulla"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:94
+msgid "_Brick (2:1)"
+msgstr "_Argilla (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:96
+msgid "_Grain (2:1)"
+msgstr "_Grano (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:98
+msgid "_Ore (2:1)"
+msgstr "_Minerale (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:100
+msgid "_Wool (2:1)"
+msgstr "_Lana (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:102
+msgid "_Lumber (2:1)"
+msgstr "L_egno (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:106
+msgid "_Any (3:1)"
+msgstr "_Qualunque (3:1)"
+
+#. East
+#: editor/gtk/editor.c:111
+msgid "East|E"
+msgstr "E"
+
+#. North east
+#: editor/gtk/editor.c:113
+msgid "North East|NE"
+msgstr "NE"
+
+#. North west
+#: editor/gtk/editor.c:115
+msgid "North West|NW"
+msgstr "NO"
+
+#. West
+#: editor/gtk/editor.c:117
+msgid "West|W"
+msgstr "O"
+
+#. South west
+#: editor/gtk/editor.c:119
+msgid "South West|SW"
+msgstr "SO"
+
+#. South east
+#: editor/gtk/editor.c:121
+msgid "South East|SE"
+msgstr "SE"
+
+#: editor/gtk/editor.c:564
+msgid "Shuffle"
+msgstr "Mescola"
+
+#: editor/gtk/editor.c:696 server/gtk/main.c:450
+msgid "Game Parameters"
+msgstr "Parametri di Partita"
+
+#: editor/gtk/editor.c:698 server/gtk/main.c:482
+msgid "Rules"
+msgstr "Regole"
+
+#: editor/gtk/editor.c:699
+msgid "Resources"
+msgstr "Materie prime"
+
+#: editor/gtk/editor.c:700
+msgid "Buildings"
+msgstr "Costruzioni"
+
+#: editor/gtk/editor.c:701
+msgid "Development Cards"
+msgstr "Carte Sviluppo"
+
+#: editor/gtk/editor.c:718
+msgid "Pioneers Editor"
+msgstr "Editor Pioneers"
+
+#: editor/gtk/editor.c:803
+#, c-format
+msgid "Failed to load '%s'"
+msgstr "Impossibile caricare '%s'"
+
+#: editor/gtk/editor.c:843
+#, c-format
+msgid "Failed to save to '%s'"
+msgstr "Impossibile salvare '%s'"
+
+#: editor/gtk/editor.c:858
+msgid "Open Game"
+msgstr "Carica partita"
+
+#: editor/gtk/editor.c:884
+msgid "Save as..."
+msgstr "Salva come..."
+
+#: editor/gtk/editor.c:919
+msgid "Change Title"
+msgstr "Cambia Titolo"
+
+#: editor/gtk/editor.c:941
+msgid "New Title:"
+msgstr "Nuovo Titolo:"
+
+#: editor/gtk/editor.c:997
+msgid "Pioneers Game Editor"
+msgstr "Editor Pioneers"
+
+#: editor/gtk/editor.c:1001
+msgid "_File"
+msgstr "_File"
+
+#: editor/gtk/editor.c:1004
+msgid "_New"
+msgstr "_Nuovo"
+
+#: editor/gtk/editor.c:1005
+msgid "Create a new game"
+msgstr "Crea una nuova partita"
+
+#: editor/gtk/editor.c:1006
+msgid "_Open..."
+msgstr "_Apri..."
+
+#: editor/gtk/editor.c:1007
+msgid "Open an existing game"
+msgstr "Apri una partita esistente"
+
+#: editor/gtk/editor.c:1008
+msgid "_Save"
+msgstr "_Salva"
+
+#: editor/gtk/editor.c:1009
+msgid "Save game"
+msgstr "Salva partita"
+
+#: editor/gtk/editor.c:1010
+msgid "Save _As..."
+msgstr "S_alva come..."
+
+#: editor/gtk/editor.c:1012
+msgid "Save as"
+msgstr "Salva come"
+
+#: editor/gtk/editor.c:1013
+msgid "_Change title"
+msgstr "_Cambia titolo"
+
+#: editor/gtk/editor.c:1014
+msgid "Change game title"
+msgstr "Cambia il titolo della partita"
+
+#: editor/gtk/editor.c:1015 server/gtk/main.c:100
+msgid "_Check Victory Point Target"
+msgstr "_Verifica Obiettivo Punti Vittoria"
+
+#: editor/gtk/editor.c:1017 server/gtk/main.c:102
+msgid "Check whether the game can be won"
+msgstr "Verifica se la partita può essere vinta"
+
+#: editor/gtk/editor.c:1019
+msgid "Quit"
+msgstr "Esci"
+
+#: editor/gtk/editor.c:1027
+msgid "_About Pioneers Editor"
+msgstr "_Riguardo Pioneers Editor"
+
+#: editor/gtk/editor.c:1028
+msgid "Information about Pioneers Editor"
+msgstr "Informazioni su Pioneers Editor"
+
+#. Long help for commandline option (editor): filename
+#: editor/gtk/editor.c:1066
+msgid "Open this file"
+msgstr "Apri questo file"
+
+#. Commandline option for editor: filename
+#: editor/gtk/editor.c:1068
+msgid "filename"
+msgstr "nome file"
+
+#: editor/gtk/editor.c:1100
+msgid "- Editor for games of Pioneers"
+msgstr "- Editor per le partite di Pioneers"
+
+#: editor/gtk/editor.c:1141 server/gtk/main.c:1035
+#, c-format
+msgid "Building menus failed: %s"
+msgstr "Costruzione menù fallita: %s"
+
+#: editor/gtk/editor.c:1169
+msgid "Settings"
+msgstr "Impostazioni"
+
+#: editor/gtk/game-resources.c:51
+msgid "Resource Count"
+msgstr "Conto materie prime"
+
+#. Commandline meta-server: daemon
+#: meta-server/main.c:1033
+msgid "Daemonize the metaserver on start"
+msgstr "Demonizza il metaserver all'avvio"
+
+#. Commandline meta-server: redirect
+#: meta-server/main.c:1036
+msgid "Redirect clients to another metaserver"
+msgstr "Redirigi i client ad un altro metaserver"
+
+#. Commandline meta-server: server
+#: meta-server/main.c:1039
+msgid "Use this hostname when creating new games"
+msgstr "Utilizza questo hostname creando nuove partite"
+
+#. Commandline meta-server: server argument
+#: meta-server/main.c:1041
+msgid "hostname"
+msgstr "hostname"
+
+#. Commandline meta-server: port-range
+#: meta-server/main.c:1044
+msgid "Use this ports range when creating new games"
+msgstr "Usa queste porte creando nuove partite"
+
+#. Commandline meta-server: port-range argument
+#: meta-server/main.c:1046
+msgid "from-to"
+msgstr "da-a"
+
+#. Commandline option of meta server: syslog-debug
+#: meta-server/main.c:1052
+msgid "Debug syslog messages"
+msgstr "Messaggi di debug su syslog"
+
+#. Long description in the commandline for server-console: help
+#: meta-server/main.c:1073
+msgid "- Meta server for Pioneers"
+msgstr "- Meta server per Pioneers"
+
+#: meta-server/main.c:1088
+#, c-format
+msgid "metaserver protocol:"
+msgstr "protocollo metaserver:"
+
+#: server/gtk/main.c:105
+msgid "_About Pioneers Server"
+msgstr "_Riguardo Server Pioneers"
+
+#: server/gtk/main.c:106
+msgid "Information about Pioneers Server"
+msgstr "Informazioni sul Server Pioneers"
+
+#: server/gtk/main.c:222
+msgid "Stop server"
+msgstr "Ferma Server"
+
+#: server/gtk/main.c:223
+msgid "Start server"
+msgstr "Avvia Server"
+
+#: server/gtk/main.c:225
+msgid "Stop the server"
+msgstr "Ferma il Server"
+
+#: server/gtk/main.c:226
+msgid "Start the server"
+msgstr "Avvia il Server"
+
+#: server/gtk/main.c:351
+#, c-format
+msgid "Player %s from %s entered\n"
+msgstr "Entrato giocatore %s da %s\n"
+
+#: server/gtk/main.c:358
+#, c-format
+msgid "Player %s from %s left\n"
+msgstr "Uscito giocatore %s da %s\n"
+
+#: server/gtk/main.c:365
+#, c-format
+msgid "Player %d is now %s\n"
+msgstr "Giocatore %d è ora %s\n"
+
+#: server/gtk/main.c:554
+msgid "Game Settings"
+msgstr "Impostazioni Partita"
+
+#: server/gtk/main.c:600
+msgid "Server Parameters"
+msgstr "Parametri Server"
+
+#: server/gtk/main.c:626
+msgid "The port for the game server"
+msgstr "La porta del server di partita"
+
+#: server/gtk/main.c:629
+msgid "Register Server"
+msgstr "Registra Server"
+
+#: server/gtk/main.c:637
+msgid "Register this game at the meta server"
+msgstr "Registra questa partita sul meta server"
+
+#: server/gtk/main.c:654
+msgid "The address of the meta server"
+msgstr "L'indirizzo del meta server"
+
+#: server/gtk/main.c:656
+msgid "Reported Hostname"
+msgstr "Hostname Indicato"
+
+#: server/gtk/main.c:671
+msgid ""
+"The public name of this computer (needed when playing behind a firewall)"
+msgstr ""
+"Il nome pubblico di questo computer (necessario giocando attraverso un "
+"firewall)"
+
+#: server/gtk/main.c:675
+msgid "Random Turn Order"
+msgstr "Ordine casuale dei turni"
+
+#: server/gtk/main.c:683
+msgid "Randomize turn order"
+msgstr "Rendi casuale l'ordine dei turni"
+
+#: server/gtk/main.c:722
+msgid "Running Game"
+msgstr "Partita in corso"
+
+#: server/gtk/main.c:724
+msgid "Players Connected"
+msgstr "Giocatori Connessi"
+
+#: server/gtk/main.c:758
+msgid "Shows all players and viewers connected to the server"
+msgstr "Visualizza tutti i giocatori e gli spettatori connessi"
+
+#: server/gtk/main.c:763
+msgid "Connected"
+msgstr "Connesso"
+
+#: server/gtk/main.c:770
+msgid "Is the player currently connected?"
+msgstr "Il giocatore è attualmente connesso?"
+
+#: server/gtk/main.c:773
+msgid "Name"
+msgstr "Nome"
+
+#: server/gtk/main.c:780
+msgid "Name of the player"
+msgstr "Nome del giocatore"
+
+#: server/gtk/main.c:782
+msgid "Location"
+msgstr "Postazione"
+
+#: server/gtk/main.c:789
+msgid "Host name of the player"
+msgstr "Nome del computer del giocatore"
+
+#: server/gtk/main.c:793
+msgid "Number"
+msgstr "Numero"
+
+#: server/gtk/main.c:800
+msgid "Player number"
+msgstr "Numero del giocatore"
+
+#: server/gtk/main.c:804
+msgid "Role"
+msgstr "Ruolo"
+
+#: server/gtk/main.c:808
+msgid "Player of viewer"
+msgstr "Giocatore o spettatore"
+
+#: server/gtk/main.c:819
+msgid "Launch Pioneers Client"
+msgstr "Avvia Client Pioneers"
+
+#: server/gtk/main.c:826
+msgid "Launch the Pioneers Client"
+msgstr "Avvia il client di Pioneers"
+
+#: server/gtk/main.c:828
+msgid "Computer Players"
+msgstr "Giocatori AI"
+
+#: server/gtk/main.c:837
+msgid "Enable Chat"
+msgstr "Abilita chat"
+
+#: server/gtk/main.c:843
+msgid "Enable chat messages"
+msgstr "Abilita i messaggi chat"
+
+#: server/gtk/main.c:850
+msgid "Add Computer Player"
+msgstr "Aggiungi Giocatore AI"
+
+#: server/gtk/main.c:857
+msgid "Add a computer player to the game"
+msgstr "Aggiungi alla partita un giocatore controllato dal computer"
+
+#: server/gtk/main.c:866
+msgid "Messages"
+msgstr "Messaggi"
+
+#: server/gtk/main.c:884
+msgid "Messages from the server"
+msgstr "Messaggi dal server"
+
+#: server/gtk/main.c:932
+msgid "The Pioneers Game Server"
+msgstr "Server della partita di Pioneers"
+
+#. Wait for all players to disconnect,
+#. * then enable the UI
+#.
+#: server/gtk/main.c:940
+msgid "The game is over.\n"
+msgstr "La partita è finita.\n"
+
+#. Long description in the commandline for server-gtk: help
+#. Long description in the commandline for server-console: help
+#: server/gtk/main.c:994 server/main.c:174
+msgid "- Host a game of Pioneers"
+msgstr "- Ospita una partita di Pioneers"
+
+#. Name in the titlebar of the server
+#: server/gtk/main.c:1016
+msgid "Pioneers Server"
+msgstr "Server Pioneers"
+
+#. Commandline server-console: game-title
+#: server/main.c:75
+msgid "Game title to use"
+msgstr "Nome della partita"
+
+#. Commandline server-console: file
+#: server/main.c:78
+msgid "Game file to use"
+msgstr "File di partita da usare"
+
+#. Commandline server-console: port
+#: server/main.c:81
+msgid "Port to listen on"
+msgstr "Porta su cui ascoltare"
+
+#. Commandline server-console: players
+#: server/main.c:84
+msgid "Override number of players"
+msgstr "Forza il numero di giocatori"
+
+#. Commandline server-console: points
+#: server/main.c:87
+msgid "Override number of points needed to win"
+msgstr "Forza il numero di punti vittoria"
+
+#. Commandline server-console: seven-rule
+#: server/main.c:90
+msgid "Override seven-rule handling"
+msgstr "Forza la gestione della regola sette"
+
+#. Commandline server-console: terrain
+#: server/main.c:93
+msgid "Override terrain type, 0=default 1=random"
+msgstr "Forza il tipo di terreno, 0=default 1=casuale"
+
+#. Commandline server-console: computer-players
+#: server/main.c:96
+msgid "Add N computer players"
+msgstr "Aggiungi N giocatori AI"
+
+#. Commandline server-console: register
+#: server/main.c:106
+msgid "Register server with meta-server"
+msgstr "Registra il server sul meta server"
+
+#. Commandline server-console: meta-server
+#: server/main.c:109
+msgid "Register at meta-server name (implies -r)"
+msgstr "Registra sul metaserver con nome (implica -r)"
+
+#. Commandline server-console: hostname
+#: server/main.c:113
+msgid "Use this hostname when registering"
+msgstr "Usa questo hostname per la registrazione"
+
+#. Commandline server-console: auto-quit
+#: server/main.c:120
+msgid "Quit after a player has won"
+msgstr "Esci quando un giocatore vince"
+
+#. Commandline server-console: empty-timeout
+#: server/main.c:123
+msgid "Quit after N seconds with no players"
+msgstr "Esci dopo N secondi senza giocatori"
+
+#. Commandline server-console: tournament
+#: server/main.c:126
+msgid "Tournament mode, computer players added after N minutes"
+msgstr "Modalità torneo, giocatori AI aggiunti dopo N secondi"
+
+#. Commandline server-console: admin-port
+#: server/main.c:130
+msgid "Admin port to listen on"
+msgstr "Porta di admin su cui ascoltare"
+
+#: server/main.c:134
+msgid "Don't start game immediately, wait for a command on admin port"
+msgstr ""
+"Non iniziare la partita immediatamente, aspetta un comando dalla porta di "
+"amministrazione"
+
+#: server/main.c:140
+msgid "Give players numbers according to the order they enter the game"
+msgstr ""
+"Assegna il numero di giocatore secondo l'ordine di entrata nella partita"
+
+#. Commandline server-console: Short description of meta group
+#: server/main.c:180
+msgid "Meta-server Options"
+msgstr "Opzioni meta-server"
+
+#: server/main.c:183
+msgid "Options for the meta-server"
+msgstr "Opzioni per il meta-server"
+
+#. Commandline server-console: Short description of misc group
+#: server/main.c:191
+msgid "Miscellaneous Options"
+msgstr "Opzioni generiche"
+
+#. Commandline server-console: Long description of misc group
+#: server/main.c:193
+msgid "Miscellaneous options"
+msgstr "Opzioni generiche"
+
+#: server/meta.c:193
+#, c-format
+msgid "Register with meta-server at %s, port %s\n"
+msgstr "Registra sul meta-server %s, porta %s\n"
+
+#: server/meta.c:210
+msgid "Unregister from meta-server\n"
+msgstr "Deregistra dal metaserver\n"
+
+#: server/player.c:130
+msgid "chat too long"
+msgstr "messaggio troppo lungo"
+
+#: server/player.c:147
+msgid "name too long"
+msgstr "nome troppo lungo"
+
+#: server/player.c:179
+msgid "ignoring unknown extension"
+msgstr "estensione sconosciuta ingorata"
+
+#: server/player.c:209
+msgid "Game starts, adding computer players"
+msgstr "La partita inizia, aggiungo giocatori AI"
+
+#: server/player.c:234
+#, c-format
+msgid "The game starts in %s minutes."
+msgstr "La partita inizia tra %s minuti."
+
+#: server/player.c:235
+#, c-format
+msgid "The game starts in %s minute."
+msgstr "La partita inizia tra %s minuto."
+
+#: server/player.c:280
+msgid "Sorry, game is over."
+msgstr "Mi dispiace, la partita è terminata."
+
+#: server/player.c:283
+#, c-format
+msgid "Player from %s is refused: game is over\n"
+msgstr "Giocatore da %s rifiutato: la partita è terminata\n"
+
+#: server/player.c:331
+msgid "This game will start soon."
+msgstr "Questa partita inizierà presto."
+
+#: server/player.c:359
+msgid "Name not changed: new name is already in use"
+msgstr "Nome non variato: il nuovo nome è già in uso"
+
+#. %s is the name of the reconnecting player
+#: server/player.c:648
+#, c-format
+msgid "%s has reconnected."
+msgstr "%s si è riconnesso."
+
+#: server/player.c:776
+#, c-format
+msgid "Version mismatch: %s"
+msgstr "Versione non corrispondente: %s"
+
+#: server/server.c:47
+msgid "Was hanging around for too long without players... bye.\n"
+msgstr "Rimasto in attesa senza giocatori per troppo tempo... addio.\n"
+
+#. Server: preparing game #.....
+#: server/server.c:219
+msgid "Preparing game"
+msgstr "Partita in preparazione"
+
+#: server/server.c:337
+msgid "Missing game directory\n"
+msgstr "Manca la directory di partita\n"
+
+#: server/turn.c:253
+msgid "Island Discovery Bonus"
+msgstr "Bonus scoperta isole"
+
+#: server/turn.c:256
+msgid "Additional Island Bonus"
+msgstr "Bonus aggiuntivo isole"
+
+#: server/turn.c:388
+msgid "Tried to assign resources to NULL player.\n"
+msgstr "Si è cercato di assegnare le materie prime al giocatore NULL\n"
+
+#~ msgid "Brick port|B"
+#~ msgstr "A"
+
+#~ msgid "Grain port|G"
+#~ msgstr "G"
+
+#~ msgid "Ore port|O"
+#~ msgstr "M"
+
+#~ msgid "Wool port|W"
+#~ msgstr "La"
+
+#~ msgid "Lumber port|L"
+#~ msgstr "Le"
+
+#~ msgid "Continue with your turn."
+#~ msgstr "Continua il tuo turno."
Added: trunk/po/ja.po
===================================================================
--- trunk/po/ja.po (rev 0)
+++ trunk/po/ja.po 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,3095 @@
+# Pioneers - Settlers of Catan for GNOME.
+# Copyright (C) 1999-2001 Dave Cole
+# Copyright (C) 2000-2002 Andy Heroff
+# This file is distributed under the same license as the pioneers package.
+# Yasuhiko Takasugi <takasugi at flcl.org>, 2006-2007.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Pioneers 0.11.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-07 20:43+0200\n"
+"PO-Revision-Date: 2007-07-20 05:45+0900\n"
+"Last-Translator: Yasuhiko Takasugi <takasugi at flcl.org>\n"
+"Language-Team: Japanese <gnome-translation at gnome.gr.jp>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Default name for the AI when the computer_names file
+#. * is not found or empty.
+#.
+#: client/ai/ai.c:74 client/ai/ai.c:90
+msgid "Computer Player"
+msgstr "ã³ã³ãã¥ã¼ã¿ ãã¬ã¤ã¤ã¼"
+
+#. Commandline pioneersai: server
+#. Commandline option of client: hostname of the server
+#: client/ai/ai.c:102 client/gtk/connect.c:1462 client/gtk/offline.c:53
+msgid "Server Host"
+msgstr "ãµã¼ãããã¹ã"
+
+#. Commandline pioneersai: port
+#. Commandline option of client: port of the server
+#: client/ai/ai.c:105 client/gtk/connect.c:1478 client/gtk/offline.c:56
+#: server/gtk/main.c:612
+msgid "Server Port"
+msgstr "ãµã¼ãããã¼ã"
+
+#. Commandline pioneersai: name
+#: client/ai/ai.c:108
+msgid "Computer name (leave absent for random name)"
+msgstr "ã³ã³ãã¥ã¼ã¿åï¼èªåã§ã¤ããå ´åã¯ç©ºç½ã«ãã¦ãã ãããï¼"
+
+#. Commandline pioneersai: time
+#: client/ai/ai.c:111
+msgid "Time to wait between turns (in milliseconds)"
+msgstr "ã¿ã¼ã³éã®å¾
ã¡æéï¼ããªç§åä½ï¼"
+
+#. Commandline pioneersai: chat-free
+#: client/ai/ai.c:114
+msgid "Stop computer player from talking"
+msgstr "ä¼è©±ããã³ã³ãã¥ã¼ã¿ãã¬ã¤ã¤ã¼ã忢"
+
+#. Commandline pioneersai: algorithm
+#: client/ai/ai.c:117
+msgid "Type of computer player"
+msgstr "ã³ã³ãã¥ã¼ã¿ãã¬ã¤ã¤ã¼ã®ç¨®é¡"
+
+#. Commandline option of ai: enable debug logging
+#. Commandline option of client: enable debug logging
+#. Commandline option of meta server: enable debug logging
+#. Commandline option of server-gtk: enable debug logging
+#. Commandline option of server: enable debug logging
+#: client/ai/ai.c:120 client/gtk/offline.c:74 meta-server/main.c:1049
+#: server/gtk/main.c:952 server/main.c:144
+msgid "Enable debug messages"
+msgstr "ãããã°ã¡ãã»ã¼ã¸ãå¯è½ã«ãã"
+
+#. Commandline option of ai: version
+#. Commandline option of client: version
+#. Commandline option of editor: version
+#. Commandline option of meta server: version
+#. Commandline option of server-gtk: version
+#. Commandline option of server-console: version
+#: client/ai/ai.c:123 client/gtk/offline.c:77 editor/gtk/editor.c:1071
+#: meta-server/main.c:1055 server/gtk/main.c:955 server/main.c:99
+msgid "Show version information"
+msgstr "ãã¼ã¸ã§ã³æ
å ±ã表示"
+
+#: client/ai/ai.c:134
+msgid "- Computer player for Pioneers"
+msgstr "- ãã¤ãªãã¢ã®ã³ã³ãã¥ã¼ã¿ãã¬ã¤ã¤ã¼"
+
+#: client/ai/ai.c:144 client/gtk/offline.c:186 editor/gtk/editor.c:1111
+#: meta-server/main.c:1084 server/gtk/main.c:1005 server/main.c:206
+#, c-format
+msgid "Pioneers version:"
+msgstr "ãã¤ãªãã¢ãã¼ã¸ã§ã³"
+
+#: client/ai/ai.c:176
+#, c-format
+msgid "Type of computer player: %s\n"
+msgstr "ã³ã³ãã¥ã¼ã¿ãã¬ã¤ã¤ã¼ã®ç¨®é¡: %s\n"
+
+#: client/ai/ai.c:205
+msgid "The game is already full. I'm leaving."
+msgstr "ã²ã¼ã ã¯ãã§ã«ä¸æ¯ã§ããç§ã¯æãã¾ãã"
+
+#: client/ai/greedy.c:941
+msgid "No settlements in stock to use for setup"
+msgstr "ã»ããã¢ããã®ããã«ãã以ä¸ãã¾ã£ã¦ããæ¤æ°å°ã¯ããã¾ããã"
+
+#: client/ai/greedy.c:948
+msgid "There is no place to setup a settlement"
+msgstr "æ¤æ°å°ãé
ç½®ããä½å°ãããã¾ããã"
+
+#: client/ai/greedy.c:972
+msgid "No roads in stock to use for setup"
+msgstr "ã»ããã¢ããã®ããã«ãã以ä¸ãã¾ã£ã¦ããéã¯ããã¾ããã"
+
+#: client/ai/greedy.c:989
+msgid "There is no place to setup a road"
+msgstr "éãè¨ç½®ããä½å°ã¯ããã¾ããã"
+
+#: client/ai/greedy.c:1291
+msgid "Ok, let's go!"
+msgstr "OK, ã¬ããã´ã¼!"
+
+#: client/ai/greedy.c:1292
+msgid "I'll beat you all now! ;)"
+msgstr "ãã£ã¤ãã¦ããï¼"
+
+#: client/ai/greedy.c:1293
+msgid "Now for another try..."
+msgstr "å¥ãªãã©ã¤éå§ä¸..."
+
+#: client/ai/greedy.c:1297
+msgid "At least I get something..."
+msgstr "å°ãªãã¨ãä½ãã¨ãã..."
+
+#: client/ai/greedy.c:1298
+msgid "One is better than none..."
+msgstr "ãããã®ãä½ããªã..."
+
+#: client/ai/greedy.c:1302
+msgid "Wow!"
+msgstr "ããï¼"
+
+#: client/ai/greedy.c:1303
+msgid "Ey, I'm becoming rich ;)"
+msgstr "ããããéæã¡ã«ãªã£ãã"
+
+#: client/ai/greedy.c:1304
+msgid "This is really a good year!"
+msgstr "è¯ãå¹´ã ï¼"
+
+#: client/ai/greedy.c:1307
+msgid "You really don't deserve that much!"
+msgstr "ãããªã«åãå
¥ããããªãï¼"
+
+#: client/ai/greedy.c:1308
+msgid "You don't know what to do with that many resources ;)"
+msgstr "ãããªã«å¤ãã®è³æºã§ä½ãããã°ãããããããªãã"
+
+#: client/ai/greedy.c:1309
+msgid "Ey, wait for my robber and lose all this again!"
+msgstr "ãããçè³ãå¾
ã¤ããã¾ããå
¨é¨ãªãããï¼"
+
+#: client/ai/greedy.c:1312
+msgid "Hehe!"
+msgstr "ã¸ã¸ï¼"
+
+#: client/ai/greedy.c:1313
+msgid "Go, robber, go!"
+msgstr "ãããçè³ã ï¼"
+
+#: client/ai/greedy.c:1316
+msgid "You bastard!"
+msgstr "ããã§ãªãï¼"
+
+#: client/ai/greedy.c:1317
+msgid "Can't you move that robber somewhere else?!"
+msgstr "çè³ãã©ã£ãä»ã«ç§»ããªãã®?!"
+
+#: client/ai/greedy.c:1318
+msgid "Why always me??"
+msgstr "ä½ã§ãã¤ãç§??"
+
+#: client/ai/greedy.c:1321
+msgid "Oh no!"
+msgstr "ãªã¼ããã¼ï¼"
+
+#: client/ai/greedy.c:1322
+msgid "Grrr!"
+msgstr "ãã¼ï¼"
+
+#: client/ai/greedy.c:1323
+msgid "Who the hell rolled that 7??"
+msgstr "7 ã®ç®ãã ããã®ã¯ã ãã ??"
+
+#: client/ai/greedy.c:1324
+msgid "Why always me?!?"
+msgstr "ä½ã§ãã¤ãç§?!?"
+
+#: client/ai/greedy.c:1327
+msgid "Say good bye to your cards... :)"
+msgstr "ããã ãã¼"
+
+#: client/ai/greedy.c:1328
+msgid "*evilgrin*"
+msgstr "*evilgrin*"
+
+#: client/ai/greedy.c:1329
+msgid "/me says farewell to your cards ;)"
+msgstr "/me ããªãã®ã«ã¼ãã«ãããªã;)"
+
+#: client/ai/greedy.c:1330
+msgid "That's the price for being rich... :)"
+msgstr "éæã¡ã«ãªãããã®è²»ç¨ã..."
+
+#: client/ai/greedy.c:1333
+msgid "Ey! Where's that card gone?"
+msgstr "ããï¼ã«ã¼ãã¯ã©ãã«ãã£ã¦ãã¾ã£ãã®ï¼"
+
+#: client/ai/greedy.c:1334
+msgid "Thieves! Thieves!!"
+msgstr "æ³¥æ£ï¼æ³¥æ£ï¼"
+
+#: client/ai/greedy.c:1335
+msgid "Wait for my revenge..."
+msgstr "復è®ãã¦ãã...."
+
+#: client/ai/greedy.c:1338
+msgid "Oh no :("
+msgstr "ãã¼ãã®ã¼"
+
+#: client/ai/greedy.c:1339
+msgid "Must this happen NOW??"
+msgstr "ä»ãããããããã®ã??"
+
+#: client/ai/greedy.c:1340
+msgid "Args"
+msgstr "Args"
+
+#: client/ai/greedy.c:1343
+msgid "Hehe, my soldiers rule!"
+msgstr "ã¸ã¸ãå
µå£«ãæ¯é
ï¼"
+
+#: client/ai/greedy.c:1346
+msgid "First robbing us, then grabbing the points..."
+msgstr "æåã«ç§ãã¡ã奪ããããããã¦ãã¤ã³ãã奪ããã..."
+
+#: client/ai/greedy.c:1349
+msgid "See that road!"
+msgstr "éãã¿ã!"
+
+#: client/ai/greedy.c:1352
+msgid "Pf, you won't win with roads alone..."
+msgstr "ãµã
ãéã ãããåã¦ãªãã.."
+
+#: client/ai/greedy.c:1819
+msgid "Rejecting trade.\n"
+msgstr "交ææå¦\n"
+
+#: client/ai/greedy.c:1911
+#, c-format
+msgid "Received error from server: %s. Quitting\n"
+msgstr "ãµã¼ã: %s ããã¨ã©ã¼ãåãåã£ã. çµäºããã\n"
+
+#: client/ai/greedy.c:1921
+msgid "Yippie!"
+msgstr "ã¤ããã¼ï¼"
+
+#: client/ai/greedy.c:1923
+msgid "My congratulations"
+msgstr "ããã§ã¨ã"
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:80
+msgid ""
+"Hello, welcome to the lobby. I am a simple robot. Type '/help' in the chat "
+"to see the list of commands I know."
+msgstr ""
+"ããã«ã¡ã¯ãããããããã¼ã¸ãç§ã¯åç´ãªããããã§ããç§ãç¥ã£ã¦ããã³ãã³ã"
+"ã®ä¸è¦§ãè¦ãããã«ã¯ããã£ããã§'/help'ã¨æã¡è¾¼ãã§ãã ããã"
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:107
+msgid "'/help' shows this message again"
+msgstr "'/help' ã¯ããã®ã¡ãã»ã¼ã¸ãå度表示ãã¾ãã"
+
+#. Translators: don't translate '/why'
+#: client/ai/lobbybot.c:110
+msgid "'/why' explains the purpose of this strange board layout"
+msgstr "'/why'ã¯ããã®ä¸æè°ãªãã¼ãé
ç½®ã®ç®çã説æãã"
+
+#. Translators: don't translate '/news'
+#: client/ai/lobbybot.c:113
+msgid "'/news' tells the last released version"
+msgstr "'/news'ã¯ãææ°ã®ãªãªã¼ã¹ãã¼ã¸ã§ã³ã表示"
+
+#: client/ai/lobbybot.c:118
+msgid ""
+"This board is not intended to be a game that can be played. Instead, players "
+"can find eachother here, and decide which board they want to play. Then, one "
+"of the players will host the proposed game by starting a server, and "
+"registers it at the metaserver. The other players can subsequently "
+"disconnect from the lobby, and enter that game."
+msgstr ""
+"ãã®ãã¼ãã¯ã²ã¼ã ãããã«ã¯åãã¦ããªãããã®ä»£ããããã¬ã¤ã¤ã¼ã¯ããã§ä»ã®"
+"ãã¬ã¤ã¤ã¼ãè¦ã¤ãã¦ãã©ã®ãã¼ãã§éã³ãããããããããããã¦ããã¬ã¤ã¤ã¼ã®"
+"ä¸äººããµã¼ããã¹ã¿ã¼ãããããã¨ã§ãã¹ãã«ãªãããããã¡ã¿ãµã¼ãã«ç»é²ããã"
+"ãã®æ¬¡ã«ãä»ã®ãã¬ã¤ã¤ã¼ã¯ããã¼ããã¯ãªããã²ã¼ã ãéå§ããã"
+
+#: client/ai/lobbybot.c:129
+msgid "The last released version of Pioneers is"
+msgstr "ãã¤ãªãã¢ã®ææ°ãã¼ã¸ã§ã³ã¯"
+
+#: client/ai/lobbybot.c:144
+msgid "The game is starting. I'm not needed anymore. Goodbye."
+msgstr "ã²ã¼ã éå§ãç§ã®ä»äºã¯çµãããã§ã¯ã"
+
+#: client/common/client.c:103
+msgid "Waiting"
+msgstr "å¾
æ©ä¸"
+
+#: client/common/client.c:105 client/common/client.c:1241
+msgid "Idle"
+msgstr "å¾
æ©"
+
+#: client/common/client.c:447
+msgid "We have been kicked out of the game.\n"
+msgstr "ã²ã¼ã ããã¯ããåºãããã\n"
+
+#. Network status: offline
+#: client/common/client.c:450 client/common/client.c:891 client/gtk/gui.c:1340
+msgid "Offline"
+msgstr "ãªãã©ã¤ã³"
+
+#: client/common/client.c:471
+#, c-format
+msgid "Error (%s): %s\n"
+msgstr "ã¨ã©ã¼ (%s): %s\n"
+
+#: client/common/client.c:480 client/common/client.c:491
+#, c-format
+msgid "Notice: %s\n"
+msgstr "è¦å: %s\n"
+
+#: client/common/client.c:607
+#, c-format
+msgid "%s does not receive any %s, because the bank is empty.\n"
+msgstr "%s ã¯ã©ã㪠%s ããåãåããªã, ãªããªããå±±ã¯ç©ºã ããã\n"
+
+#: client/common/client.c:620
+#, c-format
+msgid "%s only receives %s, because the bank didn't have any more.\n"
+msgstr "%s ã¯ã %sã ãåãåã, ãªããªããå±±ã¯ãããªã«ããªããªã£ãããã\n"
+
+#: client/common/client.c:629
+#, c-format
+msgid "%s receives %s.\n"
+msgstr "%s ã¯ã %s ãåãã¨ã£ãã\n"
+
+#. Year of Plenty
+#: client/common/client.c:637 client/common/client.c:2586
+#, c-format
+msgid "%s takes %s.\n"
+msgstr "%s ã¯ã%sããã¨ãã\n"
+
+#: client/common/client.c:642
+#, c-format
+msgid "%s spent %s.\n"
+msgstr "%s ã¯ã %sãã使ç¨ããã.\n"
+
+#: client/common/client.c:648
+#, c-format
+msgid "%s is refunded %s.\n"
+msgstr "%s 㯠%s ãè¦ã¤ãããã.\n"
+
+#: client/common/client.c:679
+#, c-format
+msgid "%s discarded %s.\n"
+msgstr "%s ã¯ã %sãã失ã£ã.\n"
+
+#: client/common/client.c:849
+msgid "Loading"
+msgstr "ãã¼ãä¸"
+
+#: client/common/client.c:892
+msgid "Version mismatch"
+msgstr "ãã¼ã¸ã§ã³ä¸æ´å"
+
+#: client/common/client.c:894
+msgid "Version mismatch. Please make sure client and server are up to date.\n"
+msgstr "ãã¼ã¸ã§ã³ä¸æ´åãã¯ã©ã¤ã¢ã³ãããã§ãã¯ãã¦ãã ããã\n"
+
+#: client/common/client.c:1340
+msgid "Build two settlements, each with a connecting"
+msgstr "ï¼ã¤ã®æ¤æ°å°ã建ã¦ã¨ããããã¤ãªã"
+
+#: client/common/client.c:1343
+msgid "Build a settlement with a connecting"
+msgstr "æ¥ç¶ããæ¤æ°å°ã建ç¯"
+
+#: client/common/client.c:1346
+msgid "road"
+msgstr "é"
+
+#: client/common/client.c:1348
+msgid "bridge"
+msgstr "æ©"
+
+#: client/common/client.c:1350
+msgid "ship"
+msgstr "è¹"
+
+#: client/common/client.c:1358
+msgid " or"
+msgstr " ã¾ãã¯"
+
+#: client/common/client.c:1416
+msgid "Waiting for your turn"
+msgstr "ããªãã®é çªå¾
ã¡"
+
+#: client/common/client.c:1468
+msgid "Select the building to steal from."
+msgstr "強奪ãã建ç¯ç©ã鏿"
+
+#: client/common/client.c:1490
+msgid "Select the ship to steal from."
+msgstr "強奪ããè¹ã鏿"
+
+#: client/common/client.c:1575 client/gtk/interface.c:782
+msgid "Place the robber"
+msgstr "çè³é
ç½®"
+
+#: client/common/client.c:1625
+msgid "Finish the road building action."
+msgstr "é建è¨çµäº"
+
+#: client/common/client.c:1627
+msgid "Build one road segment."
+msgstr "éï¼ã¤å»ºç¯"
+
+#: client/common/client.c:1629
+msgid "Build two road segments."
+msgstr "éï¼ã¤å»ºç¯"
+
+#: client/common/client.c:1902 client/common/client.c:1996
+msgid "It is your turn."
+msgstr "ããªãã®çª"
+
+#: client/common/client.c:2090
+#, c-format
+msgid "Sorry, %s available.\n"
+msgstr "ãã¿ã¾ããã %s 使ç¨å¯è½\n"
+
+#: client/common/client.c:2405
+msgid "The game is over."
+msgstr "ã²ã¼ã çµäº"
+
+#: client/common/develop.c:43 editor/gtk/game-devcards.c:13
+msgid "Road Building"
+msgstr "é路建ç¯"
+
+#: client/common/develop.c:44 client/gtk/monopoly.c:83
+#: editor/gtk/game-devcards.c:13
+msgid "Monopoly"
+msgstr "ã¢ãããªã¼"
+
+#: client/common/develop.c:45 client/gtk/plenty.c:59
+#: editor/gtk/game-devcards.c:13
+msgid "Year of Plenty"
+msgstr "è±å¹´"
+
+#: client/common/develop.c:46 client/gtk/player.c:57
+#: editor/gtk/game-devcards.c:14
+msgid "Chapel"
+msgstr "æä¼"
+
+#: client/common/develop.c:47 client/gtk/player.c:58
+#: editor/gtk/game-devcards.c:14
+msgid "Pioneer University"
+msgstr "ãã¤ãªãã¢å¤§å¦"
+
+#: client/common/develop.c:48 client/gtk/player.c:60
+#: editor/gtk/game-devcards.c:15
+msgid "Governor's House"
+msgstr "å®è"
+
+#: client/common/develop.c:49 client/gtk/player.c:61
+#: editor/gtk/game-devcards.c:15
+msgid "Library"
+msgstr "峿¸é¤¨"
+
+#: client/common/develop.c:50 client/gtk/player.c:62
+#: editor/gtk/game-devcards.c:15
+msgid "Market"
+msgstr "å¸å ´"
+
+#: client/common/develop.c:51 client/gtk/player.c:63
+#: editor/gtk/game-devcards.c:16
+msgid "Soldier"
+msgstr "å
µå£«"
+
+#: client/common/develop.c:82
+#, c-format
+msgid "You bought the %s development card.\n"
+msgstr "%s éçºã«ã¼ããè²·ã£ã\n"
+
+#: client/common/develop.c:88
+#, c-format
+msgid "You bought a %s development card.\n"
+msgstr "%s éçºã«ã¼ããè²·ã£ãã\n"
+
+#: client/common/develop.c:110
+#, c-format
+msgid "%s bought a development card.\n"
+msgstr "%s ã¯ãéçºã«ã¼ããè²·ã£ãã\n"
+
+#: client/common/develop.c:129
+#, c-format
+msgid "%s played the %s development card.\n"
+msgstr "%s ã¯ãéçºã«ã¼ã %s ã使ã£ã\n"
+
+#: client/common/develop.c:134
+#, c-format
+msgid "%s played a %s development card.\n"
+msgstr "%s ã¯ãéçºã«ã¼ã %s ã使ã£ãã\n"
+
+#: client/common/develop.c:147
+msgid "You have run out of road segments.\n"
+msgstr "建è¨ã§ããéãããã¾ããã\n"
+
+#. I get the cards!
+#.
+#: client/common/develop.c:187
+#, c-format
+msgid "You get %s from %s.\n"
+msgstr "%s ã %s ããå¾ãã\n"
+
+#. I lose the cards!
+#.
+#: client/common/develop.c:193
+#, c-format
+msgid "%s took %s from you.\n"
+msgstr "%s ã¯ãããªããã %s ã奪ã£ã\n"
+
+#: client/common/develop.c:200
+#, c-format
+msgid "%s took %s from %s.\n"
+msgstr "%s ã¯ã%s ã %sããã¨ã£ãã\n"
+
+#: client/common/player.c:124 server/player.c:405
+#, c-format
+msgid "Viewer %d"
+msgstr "観æ¦è
%d"
+
+#: client/common/player.c:126
+#, c-format
+msgid "viewer %d"
+msgstr "観æ¦è
%d"
+
+#: client/common/player.c:134 server/player.c:408
+#, c-format
+msgid "Player %d"
+msgstr "ãã¬ã¤ã¤ã¼ %d"
+
+#: client/common/player.c:136
+#, c-format
+msgid "player %d"
+msgstr "ãã¬ã¤ã¤ã¼ %d"
+
+#: client/common/player.c:212
+#, c-format
+msgid "New viewer: %s.\n"
+msgstr "æ°ãã観æ¦è
: %s.\n"
+
+#: client/common/player.c:215 client/common/player.c:231
+#, c-format
+msgid "%s is now %s.\n"
+msgstr "%s ã¯ãä» %s \n"
+
+#: client/common/player.c:228
+#, c-format
+msgid "Player %d is now %s.\n"
+msgstr "ãã¬ã¤ã¤ã¼ %d ã¯ãä»ã %s.\n"
+
+#: client/common/player.c:267
+#, c-format
+msgid "%s has quit\n"
+msgstr "%s ã¯ãæ¢ãã\n"
+
+#: client/common/player.c:276
+msgid "There is no largest army.\n"
+msgstr "æå¤§å
µåãªã\n"
+
+#: client/common/player.c:279
+#, c-format
+msgid "%s has the largest army.\n"
+msgstr "%s ãæå¤§å
µå\n"
+
+#: client/common/player.c:300
+msgid "There is no longest road.\n"
+msgstr "æé·éã¯ãªã\n"
+
+#: client/common/player.c:303
+#, c-format
+msgid "%s has the longest road.\n"
+msgstr "%s ã¯ãæé·éããã£ãã\n"
+
+#: client/common/player.c:324
+#, c-format
+msgid "Waiting for %s."
+msgstr "%s ãå¾
ã£ã¦ã."
+
+#. We are not in on the action
+#. someone stole a resource from someone else
+#: client/common/player.c:352
+#, c-format
+msgid "%s stole a resource from %s.\n"
+msgstr "%s ã¯ãè³æºã %s ããçãã ã\n"
+
+#: client/common/player.c:362
+#, c-format
+msgid "You stole %s from %s.\n"
+msgstr "%s ã %s ããçãã ã\n"
+
+#: client/common/player.c:368
+#, c-format
+msgid "%s stole %s from you.\n"
+msgstr "%s ã¯ã%s ãããªãããçãã ã\n"
+
+#: client/common/player.c:402
+#, c-format
+msgid "%s gave %s nothing!?\n"
+msgstr "%s ã¯ã%s ã«ä½ãä¸ããªã!?\n"
+
+#: client/common/player.c:408 client/common/player.c:416
+#, c-format
+msgid "%s gave %s %s for free.\n"
+msgstr "%s ã¯ãç¡æã§ %s ã« %s ããããã\n"
+
+#: client/common/player.c:424
+#, c-format
+msgid "%s gave %s %s in exchange for %s.\n"
+msgstr "%s ã¯ã %s ã« %s ã %s ã¨äº¤æã§ä¸ããã\n"
+
+#: client/common/player.c:455
+#, c-format
+msgid "%s exchanged %s for %s.\n"
+msgstr "%s ã¯ã%s ã %sã«äº¤æããã\n"
+
+#: client/common/player.c:475
+#, c-format
+msgid "%s built a road.\n"
+msgstr "%s ã¯ãéã建ç¯ããã\n"
+
+#: client/common/player.c:487
+#, c-format
+msgid "%s built a ship.\n"
+msgstr "%s ã¯ãè¹ãé è¹ããã\n"
+
+#: client/common/player.c:500
+#, c-format
+msgid "%s built a settlement.\n"
+msgstr "%s ã¯ãæ¤æ°å°ã建ç¯ããã\n"
+
+#: client/common/player.c:519
+#, c-format
+msgid "%s built a city.\n"
+msgstr "%s ã¯ãé½å¸ã建ç¯ããã\n"
+
+#: client/common/player.c:533
+#, c-format
+msgid "%s built a city wall.\n"
+msgstr "%s ã¯ãé½å¸åå£ã建ç¯ããã\n"
+
+#: client/common/player.c:544
+#, c-format
+msgid "player_build_add called with BUILD_NONE for user %s\n"
+msgstr "player_build_add called with BUILD_NONE for user %s\n"
+
+#: client/common/player.c:553
+#, c-format
+msgid "%s built a bridge.\n"
+msgstr "%s ã¯ãæ©ã建ç¯ããã\n"
+
+#: client/common/player.c:579
+#, c-format
+msgid "%s removed a road.\n"
+msgstr "%s ã¯ãéãåãé¤ããã\n"
+
+#: client/common/player.c:589
+#, c-format
+msgid "%s removed a ship.\n"
+msgstr "%s ã¯ãè¹ãåãé¤ããã\n"
+
+#: client/common/player.c:599
+#, c-format
+msgid "%s removed a settlement.\n"
+msgstr "%s ã¯ãæ¤æ°å°ãåãé¤ããã\n"
+
+#: client/common/player.c:610
+#, c-format
+msgid "%s removed a city.\n"
+msgstr "%s ã¯ãé½å¸ãåãé¤ããã\n"
+
+#: client/common/player.c:624
+#, c-format
+msgid "%s removed a city wall.\n"
+msgstr "%s ã¯ãé½å¸åå£ãåãé¤ããã\n"
+
+#: client/common/player.c:634
+#, c-format
+msgid "player_build_remove called with BUILD_NONE for user %s\n"
+msgstr "player_build_remove alled with BUILD_NONE for user %s\n"
+
+#: client/common/player.c:642
+#, c-format
+msgid "%s removed a bridge.\n"
+msgstr "%s ã¯ãæ©ãåãé¤ããã\n"
+
+#: client/common/player.c:673
+#, c-format
+msgid "%s has cancelled a ship's movement.\n"
+msgstr "%s ã¯ãè¹ã®ç§»åãåãæ¶ããã\n"
+
+#: client/common/player.c:676
+#, c-format
+msgid "%s moved a ship.\n"
+msgstr "%s ã¯ãè¹ãç§»åããã\n"
+
+#. tell the user that someone got something
+#: client/common/player.c:696
+#, c-format
+msgid "%s received %s.\n"
+msgstr "%s ã¯ã%sããåãåã£ãã \n"
+
+#: client/common/player.c:714
+msgid "server asks to lose invalid point.\n"
+msgstr "ãµã¼ãã¯ä¸æ£ãªæ¥ç¶ã¨ãã£ã¦ã\n"
+
+#. tell the user the point is lost
+#: client/common/player.c:720
+#, c-format
+msgid "%s lost %s.\n"
+msgstr "%s ã¯ã%s ã失ã£ãã\n"
+
+#: client/common/player.c:743
+msgid "server asks to move invalid point.\n"
+msgstr "ãµã¼ãã¯ä¸æ£ãªç«¯æ«ãåé¤ãã¦ãããã¨è¨ªãã¦ãã\n"
+
+#. tell the user someone (1) lost something (2) to someone else (3)
+#: client/common/player.c:750
+#, c-format
+msgid "%s lost %s to %s.\n"
+msgstr "%s ã¯ã%s ã« %s ã§è² ããã\n"
+
+#: client/common/resource.c:35
+msgid "brick"
+msgstr "ç
ç¦"
+
+#: client/common/resource.c:35
+msgid "Brick"
+msgstr "ç
ç¦"
+
+#: client/common/resource.c:36
+msgid "grain"
+msgstr "麦"
+
+#: client/common/resource.c:36
+msgid "Grain"
+msgstr "麦"
+
+#: client/common/resource.c:37
+msgid "ore"
+msgstr "é±ç³"
+
+#: client/common/resource.c:37
+msgid "Ore"
+msgstr "é±ç³"
+
+#: client/common/resource.c:38
+msgid "wool"
+msgstr "ç¾æ¯"
+
+#: client/common/resource.c:38
+msgid "Wool"
+msgstr "ç¾æ¯"
+
+#: client/common/resource.c:39
+msgid "lumber"
+msgstr "æ¨æ"
+
+#: client/common/resource.c:39
+msgid "Lumber"
+msgstr "æ¨æ"
+
+#: client/common/resource.c:40
+msgid "no resource (bug)"
+msgstr "no resource (bug)"
+
+#: client/common/resource.c:40
+msgid "No resource (bug)"
+msgstr "no resource (bug)"
+
+#: client/common/resource.c:41
+msgid "any resource (bug)"
+msgstr "any resource (bug)"
+
+#: client/common/resource.c:41
+msgid "Any resource (bug)"
+msgstr "Any resource (bug)"
+
+#: client/common/resource.c:42
+msgid "gold"
+msgstr "é"
+
+#: client/common/resource.c:42 client/gtk/legend.c:39
+msgid "Gold"
+msgstr "é"
+
+#: client/common/resource.c:47
+msgid "a brick card"
+msgstr "ç
ç¦ã«ã¼ã"
+
+#: client/common/resource.c:47
+#, c-format
+msgid "%d brick cards"
+msgstr "%d æç
ç¦ã«ã¼ã"
+
+#: client/common/resource.c:48
+msgid "a grain card"
+msgstr "麦ã«ã¼ã"
+
+#: client/common/resource.c:48
+#, c-format
+msgid "%d grain cards"
+msgstr "%d æéº¦ã«ã¼ã"
+
+#: client/common/resource.c:49
+msgid "an ore card"
+msgstr "é±ç³ã«ã¼ã"
+
+#: client/common/resource.c:49
+#, c-format
+msgid "%d ore cards"
+msgstr "%d æé±ç³ã«ã¼ã"
+
+#: client/common/resource.c:50
+msgid "a wool card"
+msgstr "ç¾æ¯ã«ã¼ã"
+
+#: client/common/resource.c:50
+#, c-format
+msgid "%d wool cards"
+msgstr "%d æç¾æ¯ã«ã¼ã"
+
+#: client/common/resource.c:51
+msgid "a lumber card"
+msgstr "æ¨æã«ã¼ã"
+
+#: client/common/resource.c:51
+#, c-format
+msgid "%d lumber cards"
+msgstr "%d ææ¨æã«ã¼ã"
+
+#: client/common/resource.c:139 client/common/resource.c:225
+msgid "nothing"
+msgstr "ãªã"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:166
+#, c-format
+msgid "%s and %s"
+msgstr "%s ããã¦ã%s"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:170
+#, c-format
+msgid "%s, %s"
+msgstr "%s, %s"
+
+#: client/common/robber.c:60
+#, c-format
+msgid "%s has undone the robber movement.\n"
+msgstr "%s ã¯ãçè³ãç§»åãåãæ¶ããã\n"
+
+#: client/common/robber.c:63
+#, c-format
+msgid "%s moved the robber.\n"
+msgstr "%s ã¯ãçè³ãç§»åããã\n"
+
+#: client/common/robber.c:73
+#, c-format
+msgid "%s has undone the pirate movement.\n"
+msgstr "%s ã¯ãæµ·è³ã®ç§»åãåãæ¶ããã\n"
+
+#: client/common/robber.c:76
+#, c-format
+msgid "%s moved the pirate.\n"
+msgstr "%s ã¯ãæµ·è³ãç§»åããã\n"
+
+#: client/common/robber.c:83
+#, c-format
+msgid "%s must move the robber."
+msgstr "%s ã¯ãçè³ãç§»åããªãã°ãªããªãã"
+
+#: client/common/setup.c:140
+#, c-format
+msgid "Setup for %s.\n"
+msgstr "%s ã®æºå.\n"
+
+#: client/common/setup.c:152
+#, c-format
+msgid "Double setup for %s.\n"
+msgstr "%s ã®äºéè¨å®\n"
+
+#: client/common/turn.c:37
+#, c-format
+msgid "%s rolled %d.\n"
+msgstr "%s ã¯ã%d ãã ããã \n"
+
+#: client/common/turn.c:50
+#, c-format
+msgid "Begin turn %d for %s.\n"
+msgstr "%2$s ã«å¯¾ã㦠ã¿ã¼ã³ %1$d ãå§ã¾ã.\n"
+
+#: client/gtk/chat.c:71
+msgid "<b>Chat</b>"
+msgstr "<b>ãã£ãã</b>"
+
+#: client/gtk/chat.c:231
+msgid "Beeper test.\n"
+msgstr "Beeper test.\n"
+
+#: client/gtk/chat.c:234
+#, c-format
+msgid "%s beeped you.\n"
+msgstr "%s ãè²´æ¹ãå¼ã³åºãã.\n"
+
+#: client/gtk/chat.c:238
+#, c-format
+msgid "You beeped %s.\n"
+msgstr "%s ãå¼ã³åºã.\n"
+
+#: client/gtk/chat.c:244
+#, c-format
+msgid "You could not beep %s.\n"
+msgstr "%s ãå¼ã³åºããã¨ãã§ããªã.\n"
+
+#: client/gtk/chat.c:288
+msgid " said: "
+msgstr "è¨ã£ã:·"
+
+#: client/gtk/connect.c:282
+#, c-format
+msgid "Meta-server at %s, port %s"
+msgstr "ã¡ã¿ãµã¼ã %s, ãã¼ã %s"
+
+#: client/gtk/connect.c:292
+msgid "Finished.\n"
+msgstr "çµäº\n"
+
+#: client/gtk/connect.c:309 client/gtk/connect.c:359 client/gtk/connect.c:456
+#: server/meta.c:174
+msgid "Meta-server kicked us off\n"
+msgstr "ã¡ã¿ãµã¼ããæã
ãããåºããã\n"
+
+#: client/gtk/connect.c:334
+msgid "Receiving game names from the meta server.\n"
+msgstr "ã¡ã¿ãµã¼ãããã²ã¼ã åãåä¿¡ä¸ \n"
+
+#: client/gtk/connect.c:382
+#, c-format
+msgid "New game server requested on %s port %s\n"
+msgstr "æ°ããã²ã¼ã ãµã¼ã %s ãã¼ã %s ã§è¦æ±ããã¦ãã\n"
+
+#: client/gtk/connect.c:391 server/meta.c:168
+#, c-format
+msgid "Unknown message from the metaserver: %s\n"
+msgstr "ã¡ã¿ãµã¼ãããã®ä¸æã¡ãã»ã¼ã¸: %s\n"
+
+#: client/gtk/connect.c:472 server/meta.c:125
+msgid "Too many meta-server redirects\n"
+msgstr "ã¡ã¿ãµã¼ãã®ãªãã¤ã¬ã¯ããå¤ããã\n"
+
+#: client/gtk/connect.c:499 server/meta.c:140
+#, c-format
+msgid "Bad redirect line: %s\n"
+msgstr "䏿£ãªãªãã¤ã¬ã¯ã: %s\n"
+
+#: client/gtk/connect.c:525
+#, c-format
+msgid "Meta server too old to create servers (version %d.%d)\n"
+msgstr "ã¡ã¿ãµã¼ãã¯å¤ããã¦ãµã¼ã(ãã¼ã¸ã§ã³ %d.%d)ãä½ããã¨ãã§ããªã\n"
+
+#. Sevens rule: normal
+#: client/gtk/connect.c:596 client/gtk/settingscreen.c:168
+#: common/gtk/game-rules.c:81
+msgid "Normal"
+msgstr "é常"
+
+#: client/gtk/connect.c:602 client/gtk/settingscreen.c:170
+#: common/gtk/game-rules.c:88
+msgid "Reroll on 1st 2 turns"
+msgstr "æåã®2ã¿ã¼ã³ãµãç´ã"
+
+#: client/gtk/connect.c:605 client/gtk/settingscreen.c:172
+#: common/gtk/game-rules.c:95
+msgid "Reroll all 7s"
+msgstr "ãã¹ã¦ã®7ã®ç®ã§ãµãç´ã"
+
+#: client/gtk/connect.c:619
+msgid "Default"
+msgstr "æ¨æº"
+
+#: client/gtk/connect.c:622
+msgid "Random"
+msgstr "ã©ã³ãã "
+
+#: client/gtk/connect.c:653 server/meta.c:188
+#, c-format
+msgid "Redirected to meta-server at %s, port %s\n"
+msgstr "%s ã®ãã¼ã %s ã®ã¡ã¿ãµã¼ãã«ãªãã¤ã¬ã¯ã\n"
+
+#: client/gtk/connect.c:656
+msgid "Receiving a list of Pioneers servers from the meta server.\n"
+msgstr "ã¡ã¿ãµã¼ããããã¤ãªãã¢ãµã¼ãã®ä¸è¦§ãåå¾ä¸\n"
+
+#: client/gtk/connect.c:713
+msgid ""
+"<b>Note</b>:\n"
+"\tThe metaserver does not send information about the games.\n"
+"\tPlease set appropriate values yourself."
+msgstr ""
+"<b>注æ</b>:\n"
+"\tã¡ã¿ãµã¼ãã¯ã²ã¼ã ã«ã¤ãã¦ã®æ
å ±ãéããªãã\n"
+"\tèªåã§å¿
è¦ãªå¤ãè¨å®ãã¦ãã ããã"
+
+#: client/gtk/connect.c:730
+msgid "Number of AI Players"
+msgstr "AIãã¬ã¤ã¤ã¼ã®æ°"
+
+#: client/gtk/connect.c:749
+msgid "The number of AI players"
+msgstr "AIãã¬ã¤ã¤ã¼ã®æ°"
+
+#: client/gtk/connect.c:770
+msgid "Requesting new game server\n"
+msgstr "æ°ããã²ã¼ã ãµã¼ããè¦æ±ä¸\n"
+
+#: client/gtk/connect.c:813 server/gtk/main.c:328 server/server.c:160
+#, c-format
+msgid "Error starting %s: %s"
+msgstr "Error starting %s: %s"
+
+#: client/gtk/connect.c:834
+msgid "Create a public game"
+msgstr "å
¬éã²ã¼ã 使"
+
+#: client/gtk/connect.c:965 client/gtk/connect.c:1268
+msgid "Join a public game"
+msgstr "å
¬éã²ã¼ã ã«åå "
+
+#: client/gtk/connect.c:970
+msgid "_New remote game"
+msgstr "_New remote game"
+
+#: client/gtk/connect.c:984
+msgid "Refresh the list of games"
+msgstr "ã²ã¼ã ãªã¹ããæ´æ°"
+
+#: client/gtk/connect.c:989
+msgid "Create a new public game at the meta server"
+msgstr "ã¡ã¿ãµã¼ãã«æ°ããå
¬éã²ã¼ã ã使"
+
+#: client/gtk/connect.c:994
+msgid "Don't join a public game"
+msgstr "å
¬éã²ã¼ã ã«åå ããªã"
+
+#: client/gtk/connect.c:998
+msgid "Join the selected game"
+msgstr "å
¬éã²ã¼ã ã«åå "
+
+#: client/gtk/connect.c:1033
+msgid "Select a game to join"
+msgstr "åå ããã²ã¼ã ã鏿"
+
+#: client/gtk/connect.c:1036
+msgid "Map Name"
+msgstr "å°å³å"
+
+#: client/gtk/connect.c:1044
+msgid "Name of the game"
+msgstr "ã²ã¼ã ã®åå"
+
+#: client/gtk/connect.c:1049
+msgid "Curr"
+msgstr "ç¾å¨"
+
+#: client/gtk/connect.c:1055
+msgid "Number of players in the game"
+msgstr "ã²ã¼ã å
ã®ãã¬ã¤ã¤ã¼ã®æ°"
+
+#: client/gtk/connect.c:1060
+msgid "Max"
+msgstr "æå¤§"
+
+#: client/gtk/connect.c:1066
+msgid "Maximum players for the game"
+msgstr "ã²ã¼ã ã®æå¤§ãã¬ã¤ã¤ã¼æ°"
+
+#: client/gtk/connect.c:1069
+msgid "Terrain"
+msgstr "å°å½¢"
+
+#: client/gtk/connect.c:1076
+msgid "Random of default terrain"
+msgstr "æ¨æºé¸å°ã®ã©ã³ãã "
+
+#: client/gtk/connect.c:1081
+msgid "Vic. Points"
+msgstr "åå©å¾ç¹"
+
+#: client/gtk/connect.c:1087
+msgid "Points needed to win"
+msgstr "åå©ã«å¿
è¦ãªãã¤ã³ã"
+
+#: client/gtk/connect.c:1090 common/gtk/game-rules.c:73
+msgid "Sevens Rule"
+msgstr "7ã«ã¼ã«"
+
+#: client/gtk/connect.c:1096
+msgid "Sevens rule"
+msgstr "7ã«ã¼ã«"
+
+#: client/gtk/connect.c:1100
+msgid "Host"
+msgstr "ãã¹ã"
+
+#: client/gtk/connect.c:1108
+msgid "Host of the game"
+msgstr "ã²ã¼ã ãã¹ã"
+
+#: client/gtk/connect.c:1113
+msgid "Port"
+msgstr "ãã¼ã"
+
+#: client/gtk/connect.c:1119
+msgid "Port of the the game"
+msgstr "ã²ã¼ã ãµã¼ãã®ãã¼ã"
+
+#: client/gtk/connect.c:1122 common/gtk/aboutbox.c:77
+msgid "Version"
+msgstr "ãã¼ã¸ã§ã³"
+
+#: client/gtk/connect.c:1129
+msgid "Version of the host"
+msgstr "ãã¹ãã®ãã¼ã¸ã§ã³"
+
+#: client/gtk/connect.c:1184 client/gtk/gui.c:215
+msgid "Start a new game"
+msgstr "æ°ã²ã¼ã éå§"
+
+#: client/gtk/connect.c:1209
+msgid "Player Name"
+msgstr "ãã¬ã¤ã¤ã¼å"
+
+#: client/gtk/connect.c:1223
+msgid "Enter your name"
+msgstr "ããªãã®ååãå
¥å"
+
+#. Role of the player: viewer
+#: client/gtk/connect.c:1225 server/gtk/main.c:511
+msgid "Viewer"
+msgstr "観æ¦è
"
+
+#: client/gtk/connect.c:1233
+msgid "Do you want to be a viewer?"
+msgstr "観æ¦ãããã§ãã?"
+
+#: client/gtk/connect.c:1240 server/gtk/main.c:640
+msgid "Meta Server"
+msgstr "ã¡ã¿ãµã¼ã"
+
+#: client/gtk/connect.c:1255
+msgid "Leave empty for the default meta server"
+msgstr "åæã¡ã¿ãµã¼ããå©ç¨ããå ´åã空ã«ãã¦ãã"
+
+#: client/gtk/connect.c:1263
+msgid "Join public game"
+msgstr "å
¬éã²ã¼ã ã«åå "
+
+#: client/gtk/connect.c:1272
+msgid "Create game"
+msgstr "å
¬éã²ã¼ã 使"
+
+#: client/gtk/connect.c:1275
+msgid "Create a game"
+msgstr "å
¬éã²ã¼ã 使"
+
+#: client/gtk/connect.c:1285
+msgid "Join private game"
+msgstr "éå
¬éã²ã¼ã ã«åå "
+
+#: client/gtk/connect.c:1289 client/gtk/connect.c:1434
+msgid "Join a private game"
+msgstr "éå
¬éå
¬éã²ã¼ã ã«åå "
+
+#: client/gtk/connect.c:1475
+msgid "Name of the host of the game"
+msgstr "ã²ã¼ã ãã¹ãã®åå"
+
+#: client/gtk/connect.c:1494
+msgid "Port of the host of the game"
+msgstr "ã²ã¼ã ãã¹ãã®ãã¼ã"
+
+#: client/gtk/connect.c:1534
+msgid "Recent games"
+msgstr "æè¿è¡ã£ãã²ã¼ã "
+
+#: client/gtk/connect.c:1536
+msgid "Recent Games"
+msgstr "æè¿è¡ã£ãã²ã¼ã "
+
+#: client/gtk/develop.c:129
+msgid "<b>Development Cards</b>"
+msgstr "<b>éçºã«ã¼ã</b>"
+
+#: client/gtk/develop.c:160
+msgid "Play Card"
+msgstr "使ç¨ã«ã¼ã"
+
+#: client/gtk/discard.c:76
+msgid "Discard resources"
+msgstr "ãªã½ã¼ã¹å»æ£"
+
+#: client/gtk/discard.c:96
+#, c-format
+msgid "You must discard %d resources"
+msgstr "%d è³æºãæ¨ã¦ãªããã°ãªããªãã"
+
+#: client/gtk/discard.c:101
+msgid "Total discards"
+msgstr "ç·å»æ£æ°"
+
+#. Caption for list of player that must discard cards
+#: client/gtk/discard.c:226
+msgid "<b>Waiting for players to discard</b>"
+msgstr "<b>ãã¬ã¤ã¤ã¼ã®å»æ£å¾
ã¡</b>"
+
+#: client/gtk/gameover.c:32
+msgid "Game over"
+msgstr "ã²ã¼ã çµäº"
+
+#: client/gtk/gameover.c:49
+#, c-format
+msgid "%s has won the game with %d victory points!"
+msgstr "%s ã¯ãåå©ãã¤ã³ã %d ã§åå©ãã!"
+
+#: client/gtk/gameover.c:52
+#, c-format
+msgid "%s has won the game with %d victory points!\n"
+msgstr "%s ã¯ãåå©ãã¤ã³ã %d ã§åå©ãã!\n"
+
+#: client/gtk/gameover.c:58
+#, c-format
+msgid "All praise %s, Lord of the known world!"
+msgstr "ãã°ããã %s,ä¸çã®æ¯é
è
!"
+
+#: client/gtk/gold.c:71
+msgid "Choose resources"
+msgstr "è³æºé¸æ"
+
+#: client/gtk/gold.c:92
+#, c-format
+msgid "You may choose 1 resource"
+msgstr "1ã¤ãªã½ã¼ã¹ã鏿ãã¦ãã ãã"
+
+#: client/gtk/gold.c:94
+#, c-format
+msgid "You may choose %d resources"
+msgstr "%d è³æºã鏿ãã¦ãã ãã"
+
+#. Text for total in choose gold dialog
+#. Text for total in year of plenty dialog
+#: client/gtk/gold.c:101 client/gtk/plenty.c:98
+msgid "Total resources"
+msgstr "è³æºåè¨"
+
+#: client/gtk/gold.c:213
+msgid "<b>Waiting for players to choose</b>"
+msgstr "<b>ãã¬ã¤ã¤ã¼é¸æå¾
ã¡</b>"
+
+#: client/gtk/gui.c:213 server/gtk/main.c:98
+msgid "_Game"
+msgstr "_Game"
+
+#: client/gtk/gui.c:214
+msgid "_New game"
+msgstr "_New game"
+
+#: client/gtk/gui.c:216
+msgid "_Leave game"
+msgstr "_Leave·game"
+
+#: client/gtk/gui.c:217
+msgid "Leave this game"
+msgstr "ãã®ã²ã¼ã ãå»ã"
+
+#: client/gtk/gui.c:219
+msgid "_Admin"
+msgstr "_Admin"
+
+#: client/gtk/gui.c:220
+msgid "Administer Pioneers server"
+msgstr "管çãã¤ãªãã¢ãµã¼ã"
+
+#: client/gtk/gui.c:222
+msgid "_Player name"
+msgstr "_Player·name"
+
+#: client/gtk/gui.c:223
+msgid "Change your player name"
+msgstr "ãã¬ã¤ã¤ã¼å夿´"
+
+#: client/gtk/gui.c:224
+msgid "_Legend"
+msgstr "_Legend"
+
+#: client/gtk/gui.c:225
+msgid "Terrain legend and building costs"
+msgstr "é¸å°é åã¨å»ºç¯ã³ã¹ã"
+
+#: client/gtk/gui.c:226
+msgid "_Game Settings"
+msgstr "_Game·Settings"
+
+#: client/gtk/gui.c:227
+msgid "Settings for the current game"
+msgstr "ç¾å¨ã®ã²ã¼ã è¨å®"
+
+#: client/gtk/gui.c:228
+msgid "_Dice Histogram"
+msgstr "_Dice·Histogram"
+
+#: client/gtk/gui.c:229
+msgid "Histogram of dice rolls"
+msgstr "ãã¤ã¹æå°ãã¹ãã°ã©ã "
+
+#: client/gtk/gui.c:230 editor/gtk/editor.c:1018 server/gtk/main.c:103
+msgid "_Quit"
+msgstr "_Quit"
+
+#: client/gtk/gui.c:231 server/gtk/main.c:104
+msgid "Quit the program"
+msgstr "ããã°ã©ã çµäº"
+
+#: client/gtk/gui.c:232
+msgid "_Actions"
+msgstr "_Actions"
+
+#: client/gtk/gui.c:233
+msgid "Roll Dice"
+msgstr "ãã¤ã¹æå°"
+
+#: client/gtk/gui.c:234
+msgid "Roll the dice"
+msgstr "ãã¤ã¹æå°"
+
+#. Tab page name
+#: client/gtk/gui.c:235 client/gtk/gui.c:577
+msgid "Trade"
+msgstr "交æ"
+
+#: client/gtk/gui.c:237
+msgid "Undo"
+msgstr "ããç´ã"
+
+#: client/gtk/gui.c:238 client/gtk/gui.c:239
+msgid "Finish"
+msgstr "çµäº"
+
+#: client/gtk/gui.c:240 client/gtk/legend.c:226 editor/gtk/game-buildings.c:13
+msgid "Road"
+msgstr "é"
+
+#: client/gtk/gui.c:241
+msgid "Build a road"
+msgstr "é路建ç¯"
+
+#: client/gtk/gui.c:242 client/gtk/legend.c:230 editor/gtk/game-buildings.c:13
+msgid "Ship"
+msgstr "è¹"
+
+#: client/gtk/gui.c:243
+msgid "Build a ship"
+msgstr "é è¹"
+
+#: client/gtk/gui.c:244
+msgid "Move Ship"
+msgstr "è¹ç§»å"
+
+#: client/gtk/gui.c:245
+msgid "Move a ship"
+msgstr "è¹ç§»å"
+
+#: client/gtk/gui.c:246 client/gtk/legend.c:233 editor/gtk/game-buildings.c:13
+msgid "Bridge"
+msgstr "æ©"
+
+#: client/gtk/gui.c:247
+msgid "Build a bridge"
+msgstr "æ©å»ºç¯"
+
+#: client/gtk/gui.c:248 client/gtk/legend.c:235 client/gtk/player.c:52
+#: editor/gtk/game-buildings.c:13
+msgid "Settlement"
+msgstr "æ¤æ°å°"
+
+#: client/gtk/gui.c:249
+msgid "Build a settlement"
+msgstr "æ¤æ°å°å»ºç¯"
+
+#: client/gtk/gui.c:250 client/gtk/legend.c:236 client/gtk/player.c:53
+#: editor/gtk/game-buildings.c:14
+msgid "City"
+msgstr "é½å¸"
+
+#: client/gtk/gui.c:251
+msgid "Build a city"
+msgstr "é½å¸å»ºç¯"
+
+#: client/gtk/gui.c:252
+msgid "Develop"
+msgstr "éçº"
+
+#: client/gtk/gui.c:253
+msgid "Buy a development card"
+msgstr "éçºã«ã¼ãè³¼å
¥"
+
+#: client/gtk/gui.c:254 client/gtk/legend.c:240 client/gtk/player.c:54
+#: editor/gtk/game-buildings.c:14
+msgid "City Wall"
+msgstr "é½å¸åå£"
+
+#: client/gtk/gui.c:255
+msgid "Build a city wall"
+msgstr "é½å¸åå£å»ºç¯"
+
+#: client/gtk/gui.c:257
+msgid "_Settings"
+msgstr "_Settings"
+
+#: client/gtk/gui.c:258
+msgid "Prefere_nces"
+msgstr "Prefere_nces"
+
+#: client/gtk/gui.c:259
+msgid "Configure the application"
+msgstr "ã¢ããªã±ã¼ã·ã§ã³è¨å®"
+
+#: client/gtk/gui.c:261 client/gtk/gui.c:265 editor/gtk/editor.c:1002
+#: server/gtk/main.c:99
+msgid "_Help"
+msgstr "_Help"
+
+#: client/gtk/gui.c:262
+msgid "_About Pioneers"
+msgstr "_About·Pioneers"
+
+#: client/gtk/gui.c:263
+msgid "Information about Pioneers"
+msgstr "ãã¤ãªãã¢ã«é¢ãã¦ã®æ
å ±"
+
+#: client/gtk/gui.c:266 client/gtk/gui.c:1065
+msgid "Show the manual"
+msgstr "ããã¥ã¢ã«ãè¦ã"
+
+#: client/gtk/gui.c:272
+msgid "_Toolbar"
+msgstr "_Toolbar"
+
+#: client/gtk/gui.c:273
+msgid "Show or hide the toolbar"
+msgstr "ãã¼ã«ãã¼å¯è¦ä¸å¯è¦"
+
+#. Victory points target in statusbar
+#: client/gtk/gui.c:368
+#, c-format
+msgid "Points Needed to Win: %i"
+msgstr "åå©ã«å¿
è¦ãªãã¤ã³ã: %i"
+
+#: client/gtk/gui.c:454
+msgid "<b>Messages</b>"
+msgstr "<b>ã¡ãã»ã¼ã¸</b>"
+
+#. Tab page name
+#: client/gtk/gui.c:571 editor/gtk/editor.c:1165
+msgid "Map"
+msgstr "å°å³"
+
+#. Tab page name
+#: client/gtk/gui.c:585 client/gtk/quote.c:306
+msgid "Quote"
+msgstr "è¦ç©ãã"
+
+#. Tab page name
+#: client/gtk/gui.c:593 client/gtk/legend.c:261
+msgid "Legend"
+msgstr "é å"
+
+#. Tab page name, shown for the splash screen
+#: client/gtk/gui.c:603
+msgid "Welcome to Pioneers"
+msgstr "ãã¤ãªãã¢ã¸ãããã"
+
+#: client/gtk/gui.c:868
+msgid "Pioneers Preferences"
+msgstr "ãã¤ãªãã¢è¨å®"
+
+#. Label for changing the theme, in the preferences dialog
+#: client/gtk/gui.c:898
+msgid "Theme:"
+msgstr "ãã¼ã:"
+
+#: client/gtk/gui.c:921
+msgid "Choose one of the themes"
+msgstr "ãã¼ãã®1ã¤ã鏿"
+
+#. Label for the option to show the legend
+#: client/gtk/gui.c:925
+msgid "Show legend"
+msgstr "é åãè¦ã"
+
+#. Tooltip for the option to show the legend
+#: client/gtk/gui.c:935
+msgid "Show the legend as a page beside the map"
+msgstr "å°å³ã®åã«ãã¼ã¸ã¨ãã¦é åãè¦ãã¾ã"
+
+#. Label for the option to display log messages in color
+#: client/gtk/gui.c:940
+msgid "Messages with color"
+msgstr "è²ä»ãã¡ãã»ã¼ã¸"
+
+#: client/gtk/gui.c:950
+msgid "Show new messages with color"
+msgstr "è²ä»ãã§æ°ããã¡ãã»ã¼ã¸ãè¦ãã"
+
+#: client/gtk/gui.c:955
+msgid "Chat in color of player"
+msgstr "ãã¬ã¤ã¤ã¼ã®è²ã§ãã£ãã"
+
+#: client/gtk/gui.c:966
+msgid "Show new chat messages in the color of the player"
+msgstr "ãã¬ã¤ã¤ã¼ã®è²ã§ãã£ããã®æ°ããã¡ãã»ã¼ã¸ã表示"
+
+#. Label for the option to display the summary with colors
+#: client/gtk/gui.c:971
+msgid "Summary with color"
+msgstr "è²ä»ããµããªã¼"
+
+#: client/gtk/gui.c:982
+msgid "Use colors in the player summary"
+msgstr "ãã¬ã¤ã¤ã¼æ¦è¦ã«è²ãã¤ãã"
+
+#: client/gtk/gui.c:987
+msgid "Toolbar with shortcuts"
+msgstr "ã·ã§ã¼ãã«ããä»ããã¼ã«ãã¼"
+
+#: client/gtk/gui.c:997
+msgid "Show keyboard shortcuts in the toolbar"
+msgstr "ãã¼ã«ãã¼ã§ãã¼ãã¼ãã·ã§ã¼ãã«ãã表示"
+
+#: client/gtk/gui.c:1003
+msgid "Announce new players"
+msgstr "æ°ããã¬ã¤ã¤ã¼ãã¢ãã¦ã³ã¹"
+
+#: client/gtk/gui.c:1014
+msgid "Make a sound when a new player or viewer enters the game"
+msgstr "æ°ããã¬ã¤ã¤ã¼ã観æ¦è
ãã²ã¼ã ã«ã¯ãã£ãã¨ãã«é³ããªãã"
+
+#. Label for the option to use the 16:9 layout.
+#: client/gtk/gui.c:1019
+msgid "Use 16:9 layout"
+msgstr "16:9 ã¬ã¤ã¢ã¦ãã使ç¨"
+
+#: client/gtk/gui.c:1030
+msgid "Use a 16:9 friendly layout for the window"
+msgstr "ã¦ã£ã³ãã¦ã«16:9ã®ä½¿ãæãã¬ã¤ã¢ã¦ãã使ç¨"
+
+#: client/gtk/gui.c:1041
+msgid "The Pioneers Game"
+msgstr "ãã¤ãªãã¢ã²ã¼ã "
+
+#. Initial text in status bar
+#: client/gtk/gui.c:1352
+msgid "Welcome to Pioneers!"
+msgstr "ãããããã¤ãªãã¢ã¸!"
+
+#. The name of the application
+#: client/gtk/gui.c:1463
+msgid "Pioneers"
+msgstr "ãã¤ãªãã¢"
+
+#: client/gtk/histogram.c:252
+msgid "Dice Histogram"
+msgstr "ãã¤ã¹ãã¹ãã°ã©ã "
+
+#: client/gtk/interface.c:92
+msgid "Ship movement canceled."
+msgstr "è¹ç§»åãåãæ¶ã"
+
+#: client/gtk/interface.c:100 client/gtk/interface.c:101
+msgid "Select a new location for the ship."
+msgstr "è¹ã®æ°ããé
ç½®ã鏿"
+
+#: client/gtk/interface.c:740
+msgid "Select the ship to steal from"
+msgstr "強奪ããè¹ã鏿"
+
+#: client/gtk/interface.c:750
+msgid "Select the building to steal from"
+msgstr "強奪ãã建ç¯ç©ã鏿"
+
+#: client/gtk/legend.c:32
+msgid "Hill"
+msgstr "ä¸"
+
+#: client/gtk/legend.c:33
+msgid "Field"
+msgstr "èå"
+
+#: client/gtk/legend.c:34
+msgid "Mountain"
+msgstr "å±±"
+
+#: client/gtk/legend.c:35
+msgid "Pasture"
+msgstr "ç§èå°"
+
+#: client/gtk/legend.c:36
+msgid "Forest"
+msgstr "森æ"
+
+#: client/gtk/legend.c:37
+msgid "Desert"
+msgstr "ç æ¼ "
+
+#: client/gtk/legend.c:38
+msgid "Sea"
+msgstr "æµ·"
+
+#: client/gtk/legend.c:170
+msgid "<b>Terrain Yield</b>"
+msgstr "<b>é¸å°åç©«</b>"
+
+#: client/gtk/legend.c:202
+msgid "<b>Building Costs</b>"
+msgstr "<b>建ç¯ã³ã¹ã</b>"
+
+#: client/gtk/legend.c:243
+msgid "Development Card"
+msgstr "éçºã«ã¼ã"
+
+#: client/gtk/monopoly.c:105
+msgid "Select the resource you wish to monopolise."
+msgstr "éãããè³æºã鏿"
+
+#: client/gtk/name.c:123
+msgid "Change player name"
+msgstr "ãã¬ã¤ã¤ã¼åã夿´"
+
+#: client/gtk/name.c:146
+msgid "Player Name:"
+msgstr "ãã¬ã¤ã¤ã¼å:"
+
+#. Set icon preferences
+#: client/gtk/name.c:202
+msgid "Face:"
+msgstr "é¡:"
+
+#: client/gtk/name.c:217
+msgid "Variant:"
+msgstr "夿´:"
+
+#. Commandline option of client: name of the player
+#: client/gtk/offline.c:59
+msgid "Player name"
+msgstr "ãã¬ã¤ã¤ã¼å"
+
+#: client/gtk/offline.c:63
+msgid "Connect as a viewer"
+msgstr "観æ¦è
ã¨ãã¦æ¥ç¶"
+
+#: client/gtk/offline.c:66
+msgid "Meta-server Host"
+msgstr "ã¡ã¿ãµã¼ãããã¹ã"
+
+#: client/gtk/offline.c:70
+msgid "Override the language of the system"
+msgstr "ã·ã¹ãã ã®è¨èªã䏿¸ã"
+
+#: client/gtk/offline.c:100
+msgid "Connecting"
+msgstr "æ¥ç¶"
+
+#. Long description in the commandline for pioneers: help
+#: client/gtk/offline.c:175
+msgid "- Play a game of Pioneers"
+msgstr "- ãã¤ãªãã¢ã®ã²ã¼ã ãæ¥½ãã"
+
+#: client/gtk/player.c:52
+msgid "Settlements"
+msgstr "æ¤æ°å°"
+
+#: client/gtk/player.c:53
+msgid "Cities"
+msgstr "é½å¸"
+
+#: client/gtk/player.c:54
+msgid "City Walls"
+msgstr "é½å¸åå£"
+
+#: client/gtk/player.c:55
+msgid "Largest Army"
+msgstr "æå¤§å
µå"
+
+#: client/gtk/player.c:56
+msgid "Longest Road"
+msgstr "æé·éè·¯"
+
+#: client/gtk/player.c:57
+msgid "Chapels"
+msgstr "æä¼"
+
+#: client/gtk/player.c:58
+msgid "Pioneer Universities"
+msgstr "ãã¤ãªãã¢å¤§å¦"
+
+#: client/gtk/player.c:60
+msgid "Governor's Houses"
+msgstr "å®è"
+
+#: client/gtk/player.c:61
+msgid "Libraries"
+msgstr "峿¸é¤¨"
+
+#: client/gtk/player.c:62
+msgid "Markets"
+msgstr "å¸å ´"
+
+#: client/gtk/player.c:63
+msgid "Soldiers"
+msgstr "å
µå£«é"
+
+#: client/gtk/player.c:64
+msgid "Resource card"
+msgstr "è³æºã«ã¼ã"
+
+#: client/gtk/player.c:64
+msgid "Resource cards"
+msgstr "è³æºã«ã¼ã"
+
+#: client/gtk/player.c:65
+msgid "Development card"
+msgstr "éçºã«ã¼ã"
+
+#: client/gtk/player.c:65
+msgid "Development cards"
+msgstr "éçºã«ã¼ã"
+
+#. Caption for the overview of the points and card of other players
+#: client/gtk/player.c:561
+msgid "<b>Player Summary</b>"
+msgstr "<b>ãã¬ã¤ã¤ã¼æ¦è¦</b>"
+
+#: client/gtk/plenty.c:87
+msgid "Please choose one resource from the bank"
+msgstr "å±±ãã1ã¤è³æºã鏿ãã¦ãã ãã"
+
+#: client/gtk/plenty.c:90
+msgid "Please choose two resources from the bank"
+msgstr "å±±ãã2ã¤ã®è³æºãã鏿ãã¦ãã ãã"
+
+#: client/gtk/plenty.c:92
+msgid "The bank is empty"
+msgstr "å±±ã空ã§ã"
+
+#: client/gtk/quote.c:186
+#, c-format
+msgid "%s has %s, and is looking for %s"
+msgstr "%s ã¯ã %s ããã£ã¦ããã %s ãæ¢ãã¦ãã"
+
+#: client/gtk/quote.c:287
+msgid "I Want"
+msgstr "欲ãã"
+
+#: client/gtk/quote.c:295
+msgid "Give Them"
+msgstr "ä¸ããã"
+
+#: client/gtk/quote.c:311
+msgid "Delete"
+msgstr "åé¤"
+
+#: client/gtk/quote.c:335
+msgid "Reject Domestic Trade"
+msgstr "å
å°äº¤ææå¦"
+
+#. Now create columns
+#. Table header: Player who trades
+#. Role of the player: player
+#: client/gtk/quote-view.c:170 server/gtk/main.c:513
+msgid "Player"
+msgstr "ãã¬ã¤ã¤ã¼"
+
+#. Table header: Quote
+#: client/gtk/quote-view.c:185
+msgid "Quotes"
+msgstr "è¦ç©ã"
+
+#. trade: maritime quote: %1 resources of type %2 for
+#. * one resource of type %3
+#: client/gtk/quote-view.c:292
+#, c-format
+msgid "%d:1 %s for %s"
+msgstr "%d:1ãã§ %s ã %s ã«äº¤æ"
+
+#. Trade: a player has rejected trade
+#: client/gtk/quote-view.c:431
+msgid "Rejected trade"
+msgstr "交ææå¦"
+
+#. Caption for overview of the resources of the player
+#: client/gtk/resource.c:113
+msgid "<b>Resources</b>"
+msgstr "<b>è³æº</b>"
+
+#: client/gtk/resource.c:129
+msgid "Total"
+msgstr "åè¨"
+
+#. Tooltip for the amount of resources in the hand
+#: client/gtk/resource-table.c:187
+msgid "Amount in hand"
+msgstr "ææã®åè¨"
+
+#: client/gtk/resource-table.c:191
+msgid "<less"
+msgstr "<æ¸å°"
+
+#. Tooltip for decreasing the selected amount
+#: client/gtk/resource-table.c:201
+msgid "Decrease the selected amount"
+msgstr "鏿ç·éãæ¸å°"
+
+#. Tooltip for the amount of resources in the bank
+#: client/gtk/resource-table.c:215
+msgid "Amount in the bank"
+msgstr "å±±ã®ç·é"
+
+#: client/gtk/resource-table.c:219
+msgid "more>"
+msgstr "å¢å >"
+
+#. Tooltip for increasing the selected amount
+#: client/gtk/resource-table.c:231
+msgid "Increase the selected amount"
+msgstr "鏿ç·éãå¢å "
+
+#. Tooltip for the selected amount
+#: client/gtk/resource-table.c:248
+msgid "Selected amount"
+msgstr "鏿ç·é"
+
+#. Tooltip for the total selected amount
+#: client/gtk/resource-table.c:293
+msgid "Total selected amount"
+msgstr "鏿éã®åè¨"
+
+#: client/gtk/resource-table.c:314
+msgid "The bank cannot be emptied"
+msgstr "å±±ã¯ç©ºã«ã§ããªã"
+
+#: client/gtk/settingscreen.c:74
+msgid "Yes"
+msgstr "ã¯ã"
+
+#: client/gtk/settingscreen.c:76 client/gtk/settingscreen.c:207
+msgid "No"
+msgstr "ããã"
+
+#: client/gtk/settingscreen.c:87 client/gtk/settingscreen.c:174
+msgid "Unknown"
+msgstr "䏿"
+
+#: client/gtk/settingscreen.c:121
+msgid "No game in progress..."
+msgstr "é²è¡ä¸ã®ã²ã¼ã ãªã"
+
+#: client/gtk/settingscreen.c:131
+msgid "<b>General Settings</b>"
+msgstr "<b>ä¸è¬è¨å®</b>"
+
+#: client/gtk/settingscreen.c:147
+msgid "Number of players:"
+msgstr "ãã¬ã¤ã¤ã¼æ°:"
+
+#: client/gtk/settingscreen.c:150
+msgid "Victory Point Target:"
+msgstr "ç®æ¨åå©ãã¤ã³ã:"
+
+#: client/gtk/settingscreen.c:153
+msgid "Random Terrain?"
+msgstr "ã©ã³ãã é¸å°?"
+
+#: client/gtk/settingscreen.c:156
+msgid "Interplayer Trading Allowed?"
+msgstr "ãã¬ã¤ã¤ã¼é交æã許å¯ãã¾ãã?"
+
+#: client/gtk/settingscreen.c:160
+msgid "Trading allowed only before build/buy?"
+msgstr "建ç¯ç©/売買ã®åã ã交æã許å¯"
+
+#: client/gtk/settingscreen.c:163
+msgid "Amount of Each Resource:"
+msgstr "åã
ã®è³æºã®ç·é:"
+
+#: client/gtk/settingscreen.c:177
+msgid "Sevens Rule:"
+msgstr "7ã«ã¼ã«:"
+
+#: client/gtk/settingscreen.c:181
+msgid "Use Pirate:"
+msgstr "æµ·è³ä½¿ç¨:"
+
+#: client/gtk/settingscreen.c:209
+msgid "Island Discovery Bonuses:"
+msgstr "å³¶çºè¦ãã¼ãã¹:"
+
+#: client/gtk/settingscreen.c:224
+msgid "<b>Building Quotas</b>"
+msgstr "<b>建ç¯è¦ç©ã</b>"
+
+#: client/gtk/settingscreen.c:241
+msgid "Roads:"
+msgstr "é:"
+
+#: client/gtk/settingscreen.c:247
+msgid "Settlements:"
+msgstr "æ¤æ°å°:"
+
+#: client/gtk/settingscreen.c:253
+msgid "Cities:"
+msgstr "é½å¸:"
+
+#: client/gtk/settingscreen.c:259
+msgid "City Walls:"
+msgstr "é½å¸åå£:"
+
+#: client/gtk/settingscreen.c:265
+msgid "Ships:"
+msgstr "è¹:"
+
+#: client/gtk/settingscreen.c:271
+msgid "Bridges:"
+msgstr "æ©:"
+
+#: client/gtk/settingscreen.c:283
+msgid "<b>Development Card Deck</b>"
+msgstr "<b>éçºã«ã¼ãããã</b>"
+
+#: client/gtk/settingscreen.c:299
+msgid "Road Building Cards:"
+msgstr "é路建ç¯ã«ã¼ã:"
+
+#: client/gtk/settingscreen.c:303
+msgid "Monopoly Cards:"
+msgstr "ã¢ãããªã¼ã«ã¼ã:"
+
+#: client/gtk/settingscreen.c:307
+msgid "Year of Plenty Cards:"
+msgstr "è±å¹´ã«ã¼ã:"
+
+#: client/gtk/settingscreen.c:312
+msgid "Chapel Cards:"
+msgstr "æä¼ã«ã¼ã:"
+
+#: client/gtk/settingscreen.c:316
+msgid "Pioneer University Cards:"
+msgstr "ãã¤ãªãã¢å¤§å¦ã«ã¼ã:"
+
+#: client/gtk/settingscreen.c:320
+msgid "Governor's House Cards:"
+msgstr "å®èã«ã¼ã:"
+
+#: client/gtk/settingscreen.c:325
+msgid "Library Cards:"
+msgstr "峿¸é¤¨ã«ã¼ã:"
+
+#: client/gtk/settingscreen.c:329
+msgid "Market Cards:"
+msgstr "å¸å ´ã«ã¼ã:"
+
+#: client/gtk/settingscreen.c:333
+msgid "Soldier Cards:"
+msgstr "å
µå£«ã«ã¼ã:"
+
+#: client/gtk/settingscreen.c:370
+msgid "Current Game Settings"
+msgstr "ç¾å¨ã®ã²ã¼ã è¨å®"
+
+#. trade: you ask for something for free
+#: client/gtk/trade.c:193
+#, c-format
+msgid "ask for %s for free"
+msgstr "ç¡æã§ %s ã æ±ããã"
+
+#. trade: you give something away for free
+#: client/gtk/trade.c:198
+#, c-format
+msgid "give %s for free"
+msgstr "ç¡æã§ %s ããããã"
+
+#. trade: you trade something for something else
+#: client/gtk/trade.c:203
+#, c-format
+msgid "give %s for %s"
+msgstr "%s ã« %s ãä¸ãã"
+
+#. I want some resources, and give them some resources
+#: client/gtk/trade.c:230
+#, c-format
+msgid "I want %s, and give them %s"
+msgstr "%s 欲ããã%s ãããã¾ã"
+
+#. Frame title, trade: I want to trade these resources
+#: client/gtk/trade.c:427
+msgid "<b>I Want</b>"
+msgstr "<b>欲ãã</b>"
+
+#. Frame title, trade: I want these resources in return
+#: client/gtk/trade.c:455
+msgid "<b>Give Them</b>"
+msgstr "<b>ä¸ãã</b>"
+
+#. Button text, trade: call for quotes from other players
+#: client/gtk/trade.c:484
+msgid "_Call for Quotes"
+msgstr "_Call·for·Quotes"
+
+#. Button text: Trade page, accept selected quote
+#: client/gtk/trade.c:512
+msgid "_Accept Quote"
+msgstr "_Accept·Quote"
+
+#. Button text: Trade page, finish trading
+#: client/gtk/trade.c:518
+msgid "_Finish Trading"
+msgstr "_Finish·Trading"
+
+#: common/gtk/aboutbox.c:74
+msgid ""
+"Pioneers is based upon the excellent\n"
+"Settlers of Catan board game.\n"
+msgstr ""
+"ãã¤ãªãã¢ã¯ãã«ã¿ã³ã®æ¤æ°ãã¨ãã\n"
+"ãã°ããããã¼ãã²ã¼ã ãå
ã«ãªã£ã¦ãã¾ã.\n"
+
+#: common/gtk/aboutbox.c:83
+msgid "Homepage"
+msgstr "ãã¼ã ãã¼ã¸"
+
+#: common/gtk/aboutbox.c:88
+msgid "Authors"
+msgstr "èè
"
+
+#. Tooltip for sevens rule normal
+#: common/gtk/game-rules.c:101
+msgid "All sevens move the robber or pirate"
+msgstr "å
¨ã¦ã®7ã®ç®ã¯ãçè³ãæµ·è³ãç§»åããã"
+
+#: common/gtk/game-rules.c:106
+msgid "In the first two turns all sevens are rerolled"
+msgstr "æåã®2ã¿ã¼ã³ã§ã¯ãå
¨ã¦ã®7ã®ç®ã¯æ¯ãç´ã"
+
+#. Tooltip for sevens rule reroll all
+#: common/gtk/game-rules.c:110
+msgid "All sevens are rerolled"
+msgstr "å
¨ã¦ã®7ã®ç®ã¯æ¯ãç´ã"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize Terrain"
+msgstr "ã©ã³ãã é¸å°"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize the terrain"
+msgstr "ã©ã³ãã é¸å°"
+
+#: common/gtk/game-rules.c:123
+msgid "Use Pirate"
+msgstr "æµ·è³ä½¿ç¨"
+
+#: common/gtk/game-rules.c:123
+msgid "Use the pirate to block ships"
+msgstr "è¹ãæ¢ããããã«æµ·è³ã使ã"
+
+#: common/gtk/game-rules.c:125
+msgid "Strict Trade"
+msgstr "å¶é交æ"
+
+#: common/gtk/game-rules.c:126
+msgid "Allow trade only before building or buying"
+msgstr "建ç¯/売買ã®åã ã交æã許å¯"
+
+#: common/gtk/game-rules.c:128
+msgid "Domestic Trade"
+msgstr "å
å°äº¤æ"
+
+#: common/gtk/game-rules.c:128
+msgid "Allow trade between players"
+msgstr "ãã¬ã¤ã¤ã¼éã®äº¤æã許å¯"
+
+#. Label text for customising a game
+#: common/gtk/game-settings.c:118
+msgid "Number of Players"
+msgstr "ãã¬ã¤ã¤ã¼æ°"
+
+#. Tooltip for 'Number of Players'
+#: common/gtk/game-settings.c:136
+msgid "The number of players"
+msgstr "ãã¬ã¤ã¤ã¼æ°"
+
+#. Label for customising a game
+#: common/gtk/game-settings.c:139
+msgid "Victory Point Target"
+msgstr "ç®æ¨åå©ãã¤ã³ã"
+
+#. Tooltip for Victory Point Target
+#: common/gtk/game-settings.c:159
+msgid "The points needed to win the game"
+msgstr "ã²ã¼ã åå©ã«å¿
è¦ãªãã¤ã³ã"
+
+#. Tooltip for the check button
+#: common/gtk/game-settings.c:172
+msgid "Is it possible to win this game?"
+msgstr "ãã®ã²ã¼ã ã«åå©å¯è½ãï¼"
+
+#. Port indicator for a resource: trade 2 for 1
+#: common/gtk/guimap.c:750
+msgid "2:1"
+msgstr "2:1"
+
+#. Port indicator: trade 3 for 1
+#. General port indicator
+#: common/gtk/guimap.c:753 common/gtk/guimap.c:778
+msgid "3:1"
+msgstr "3:1"
+
+#. Tooltip for the list of games
+#: common/gtk/select-game.c:111
+msgid "Select a game"
+msgstr "ã²ã¼ã 鏿"
+
+#: common/gtk/theme.c:709
+#, c-format
+msgid "bad scaling mode '%s'"
+msgstr "䏿£ã¹ã±ã¼ãªã³ã°ã¢ã¼ã '%s'"
+
+#: common/game.c:603 common/game.c:633
+msgid "This game cannot be won."
+msgstr "ãã®ã²ã¼ã ã«åå©ä¸å¯è½"
+
+#: common/game.c:604
+msgid "There is no land."
+msgstr "é¸å°ã¯ãªã"
+
+#: common/game.c:638
+msgid "It is possible that this game cannot be won."
+msgstr "ãã®ã²ã¼ã ãåã¦ãªããã¨ãã§ããã"
+
+#: common/game.c:643
+msgid "This game can be won by only building all settlements and cities."
+msgstr "å
¨ã¦ã®æ¤æ°å°ãé½å¸ã建ç¯ããã ãã§ã¯ãã®ã²ã¼ã ã«åã¦ãªã."
+
+#: common/game.c:650
+#, c-format
+msgid ""
+"Required victory points: %d\n"
+"Points obtained by building all: %d\n"
+"Points in development cards: %d\n"
+"Longest road/largest army: %d+%d\n"
+"Maximum island discovery bonus: %d\n"
+"Total: %d"
+msgstr ""
+"è¦æ±ãããåå©ãã¤ã³ã: %d\n"
+"建è¨ã«ãããã¤ã³ã: %d\n"
+"éçºã«ã¼ãã«ãããã¤ã³ã: %d\n"
+"æé·éè·¯/æå¤§å
µå: %d+%d\n"
+"æå¤§å³¶æ°çºè¦ãã¼ãã¹: %d\n"
+"åè¨: %d"
+
+#: common/log.c:54
+msgid "*ERROR* "
+msgstr "*ERROR*·"
+
+#: common/log.c:60
+msgid "Chat: "
+msgstr "ãã£ãã:"
+
+#: common/log.c:63
+msgid "Resource: "
+msgstr "è³æº:"
+
+#: common/log.c:66
+msgid "Build: "
+msgstr "建è¨:"
+
+#: common/log.c:69
+msgid "Dice: "
+msgstr "ãã¤ã¹:"
+
+#: common/log.c:72
+msgid "Steal: "
+msgstr "çè³:"
+
+#: common/log.c:75
+msgid "Trade: "
+msgstr "交æ:"
+
+#: common/log.c:78
+msgid "Development: "
+msgstr "éçº:"
+
+#: common/log.c:81
+msgid "Army: "
+msgstr "å
µå£«:"
+
+#: common/log.c:84
+msgid "Road: "
+msgstr "é:·"
+
+#: common/log.c:87
+msgid "*BEEP* "
+msgstr "*BEEP*·"
+
+#: common/log.c:92
+msgid "Player 1: "
+msgstr "ãã¬ã¤ã¤ã¼ 1:"
+
+#: common/log.c:95
+msgid "Player 2: "
+msgstr "ãã¬ã¤ã¤ã¼ 2:"
+
+#: common/log.c:98
+msgid "Player 3: "
+msgstr "ãã¬ã¤ã¤ã¼ 3:"
+
+#: common/log.c:101
+msgid "Player 4: "
+msgstr "ãã¬ã¤ã¤ã¼ 4:"
+
+#: common/log.c:104
+msgid "Player 5: "
+msgstr "ãã¬ã¤ã¤ã¼ 5:"
+
+#: common/log.c:107
+msgid "Player 6: "
+msgstr "ãã¬ã¤ã¤ã¼ 6:"
+
+#: common/log.c:110
+msgid "Player 7: "
+msgstr "ãã¬ã¤ã¤ã¼ 7:"
+
+#: common/log.c:113
+msgid "Player 8: "
+msgstr "ãã¬ã¤ã¤ã¼ 8:"
+
+#: common/log.c:116
+msgid "Viewer: "
+msgstr "観æ¦è
:"
+
+#: common/log.c:119
+msgid "** UNKNOWN MESSAGE TYPE ** "
+msgstr "**·UNKNOWN·MESSAGE·TYPE·**·"
+
+#: common/network.c:281
+#, c-format
+msgid "Error checking connect status: %s\n"
+msgstr "æ¥ç¶ç¶æ
æ¤æ»ã¨ã©ã¼: %s\n"
+
+#: common/network.c:288
+#, c-format
+msgid "Error connecting to host '%s': %s\n"
+msgstr "ãã¹ã %sã¸ã®æ¥ç¶ã¨ã©ã¼: %s\n"
+
+#: common/network.c:314
+#, c-format
+msgid "Error writing socket: %s\n"
+msgstr "ã½ã±ããæ¸ãè¾¼ã¿ã¨ã©ã¼: %s\n"
+
+#: common/network.c:365
+#, c-format
+msgid "Error writing to socket: %s\n"
+msgstr "ã½ã±ããæ¸ãè¾¼ã¨ã©ã¼: %s\n"
+
+#: common/network.c:418
+msgid "Read buffer overflow - disconnecting\n"
+msgstr "Read·buffer·overflow·-·disconnecting\n"
+
+#: common/network.c:428
+#, c-format
+msgid "Error reading socket: %s\n"
+msgstr "ã½ã±ããèªã¿è¾¼ã¿ã¨ã©ã¼: %s\n"
+
+#: common/network.c:575
+#, c-format
+msgid "Cannot resolve %s port %s: %s\n"
+msgstr "%s ãã¼ã %s ã解決ã§ããªã: %s\n"
+
+#: common/network.c:582
+#, c-format
+msgid "Cannot resolve %s port %s: host not found\n"
+msgstr "%s ãã¼ã %s ã解決ã§ããªã: ãã¹ããè¦ã¤ãããªã\n"
+
+#: common/network.c:597
+#, c-format
+msgid "Error creating socket: %s\n"
+msgstr "ã½ã±ãã使ã¨ã©ã¼: %s\n"
+
+#: common/network.c:605
+#, c-format
+msgid "Error setting socket close-on-exec: %s\n"
+msgstr "Error·setting·socket·close-on-exec:·%s\n"
+
+#: common/network.c:615 common/network.c:776
+#, c-format
+msgid "Error setting socket non-blocking: %s\n"
+msgstr "Error·setting·socket·non-blocking:·%s\n"
+
+#: common/network.c:640
+#, c-format
+msgid "Error connecting to %s: %s\n"
+msgstr "%s ã¸ã®æ¥ç¶ã¨ã©ã¼: %s\n"
+
+#: common/network.c:735
+#, c-format
+msgid "Error creating struct addrinfo: %s"
+msgstr "Error·creating·struct·addrinfo:·%s"
+
+#: common/network.c:765
+#, c-format
+msgid "Error creating listening socket: %s\n"
+msgstr "ãªã¹ãã³ã°ã½ã±ãã使ã¨ã©ã¼: %s\n"
+
+#: common/network.c:785
+#, c-format
+msgid "Error during listen on socket: %s\n"
+msgstr "ã½ã±ãããèãã¦ããæä¸ã®ã¨ã©ã¼: %s\n"
+
+#: common/network.c:794
+msgid "Listening not yet supported on this platform."
+msgstr "ãªã¹ãã³ã°ã¯ãã®ãã©ãããã©ã¼ã ã§ã¯ã¾ã ãµãã¼ãããã¦ããªã"
+
+#: common/network.c:816 common/network.c:817
+msgid "unknown"
+msgstr "䏿"
+
+#: common/network.c:823
+#, c-format
+msgid "Error getting peer name: %s"
+msgstr "peer åã®åå¾ã¨ã©ã¼: %s"
+
+#: common/network.c:836
+#, c-format
+msgid "Error resolving address: %s"
+msgstr "ã¢ãã¬ã¹è§£æ±ºã¨ã©ã¼: %s"
+
+#: common/network.c:850
+msgid "Net_get_peer_name not yet supported on this platform."
+msgstr ""
+"Net_get_peer_name ã¯ããã®ãã©ãããã©ã¼ã ã§ã¯ã¾ã ãµãã¼ãããã¦ããªãã"
+
+#: common/network.c:865
+#, c-format
+msgid "Error accepting connection: %s"
+msgstr "æ¥ç¶åä»ã¨ã©ã¼: %s"
+
+#: common/state.c:166
+#, c-format
+msgid "Connecting to %s, port %s\n"
+msgstr "%s, ãã¼ã %s ã«æ¥ç¶\n"
+
+#: common/state.c:503
+msgid "State stack overflow. Stack dump sent to standard error.\n"
+msgstr "ç¶æ
ã¹ã¿ãã¯ãªã¼ãããã¼ãæ¨æºã¨ã©ã¼åºåã«ã¹ã¿ãã¯ãã³ããéãã¾ãã\n"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:73
+msgid "_Hill"
+msgstr "_Hill"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:75
+msgid "_Field"
+msgstr "_Field"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:77
+msgid "_Mountain"
+msgstr "_Mountain"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:79
+msgid "_Pasture"
+msgstr "_Pasture"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:81
+msgid "F_orest"
+msgstr "F_orest"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:83
+msgid "_Desert"
+msgstr "_Desert"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:85
+msgid "_Sea"
+msgstr "_Sea"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:87
+msgid "_Gold"
+msgstr "_Gold"
+
+#. Use an unique shortcut key for each resource
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:89 editor/gtk/editor.c:104
+msgid "_None"
+msgstr "_None"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:94
+msgid "_Brick (2:1)"
+msgstr "_Brick·(2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:96
+msgid "_Grain (2:1)"
+msgstr "_Grain·(2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:98
+msgid "_Ore (2:1)"
+msgstr "_Ore·(2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:100
+msgid "_Wool (2:1)"
+msgstr "_Wool·(2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:102
+msgid "_Lumber (2:1)"
+msgstr "_Lumber·(2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:106
+msgid "_Any (3:1)"
+msgstr "_Any·(3:1)"
+
+#. East
+#: editor/gtk/editor.c:111
+msgid "East|E"
+msgstr "æ±"
+
+#. North east
+#: editor/gtk/editor.c:113
+msgid "North East|NE"
+msgstr "åæ±"
+
+#. North west
+#: editor/gtk/editor.c:115
+msgid "North West|NW"
+msgstr "å西"
+
+#. West
+#: editor/gtk/editor.c:117
+msgid "West|W"
+msgstr "西"
+
+#. South west
+#: editor/gtk/editor.c:119
+msgid "South West|SW"
+msgstr "å西"
+
+#. South east
+#: editor/gtk/editor.c:121
+msgid "South East|SE"
+msgstr "åæ±"
+
+#: editor/gtk/editor.c:564
+msgid "Shuffle"
+msgstr "ã·ã£ããã«"
+
+#: editor/gtk/editor.c:696 server/gtk/main.c:450
+msgid "Game Parameters"
+msgstr "ã²ã¼ã ãã©ã¡ã¼ã¿"
+
+#: editor/gtk/editor.c:698 server/gtk/main.c:482
+msgid "Rules"
+msgstr "ã«ã¼ã«"
+
+#: editor/gtk/editor.c:699
+msgid "Resources"
+msgstr "è³æº"
+
+#: editor/gtk/editor.c:700
+msgid "Buildings"
+msgstr "建è¨"
+
+#: editor/gtk/editor.c:701
+msgid "Development Cards"
+msgstr "éçºã«ã¼ã"
+
+#: editor/gtk/editor.c:718
+msgid "Pioneers Editor"
+msgstr "ãã¤ãªãã¢ã¨ãã£ã¿"
+
+#: editor/gtk/editor.c:803
+#, c-format
+msgid "Failed to load '%s'"
+msgstr "'%s' ããã¼ãã§ããªã"
+
+#: editor/gtk/editor.c:843
+#, c-format
+msgid "Failed to save to '%s'"
+msgstr "'%s' ãä¿åã§ããªã"
+
+#: editor/gtk/editor.c:858
+msgid "Open Game"
+msgstr "ã²ã¼ã ãéã"
+
+#: editor/gtk/editor.c:884
+msgid "Save as..."
+msgstr "å¥åã§ä¿å"
+
+#: editor/gtk/editor.c:919
+msgid "Change Title"
+msgstr "ã¿ã¤ãã«ã夿´"
+
+#: editor/gtk/editor.c:941
+msgid "New Title:"
+msgstr "æ°ããã¿ã¤ãã«:"
+
+#: editor/gtk/editor.c:997
+msgid "Pioneers Game Editor"
+msgstr "ãã¤ãªãã¢ã¨ãã£ã¿"
+
+#: editor/gtk/editor.c:1001
+msgid "_File"
+msgstr "_File"
+
+#: editor/gtk/editor.c:1004
+msgid "_New"
+msgstr "_New"
+
+#: editor/gtk/editor.c:1005
+msgid "Create a new game"
+msgstr "æ°ã²ã¼ã 使"
+
+#: editor/gtk/editor.c:1006
+msgid "_Open..."
+msgstr "_Open..."
+
+#: editor/gtk/editor.c:1007
+msgid "Open an existing game"
+msgstr "åå¨ããã²ã¼ã ãéã"
+
+#: editor/gtk/editor.c:1008
+msgid "_Save"
+msgstr "_Save"
+
+#: editor/gtk/editor.c:1009
+msgid "Save game"
+msgstr "ã²ã¼ã ãä¿å"
+
+#: editor/gtk/editor.c:1010
+msgid "Save _As..."
+msgstr "Save·_As..."
+
+#: editor/gtk/editor.c:1012
+msgid "Save as"
+msgstr "å¥å"
+
+#: editor/gtk/editor.c:1013
+msgid "_Change title"
+msgstr "_Change·title"
+
+#: editor/gtk/editor.c:1014
+msgid "Change game title"
+msgstr "ã²ã¼ã ã¿ã¤ãã«ã夿´"
+
+#: editor/gtk/editor.c:1015 server/gtk/main.c:100
+msgid "_Check Victory Point Target"
+msgstr "_C ç®æ¨åå©ãã¤ã³ããã§ãã¯"
+
+#: editor/gtk/editor.c:1017 server/gtk/main.c:102
+msgid "Check whether the game can be won"
+msgstr "ã²ã¼ã ã«åå©ãããã©ãããã§ãã¯"
+
+#: editor/gtk/editor.c:1019
+msgid "Quit"
+msgstr "çµäº"
+
+#: editor/gtk/editor.c:1027
+msgid "_About Pioneers Editor"
+msgstr "_About·Pioneers·Editor"
+
+#: editor/gtk/editor.c:1028
+msgid "Information about Pioneers Editor"
+msgstr "ãã¤ãªãã¢ã¨ãã£ã¿ã®ä»ãã¦ã®æ
å ±"
+
+#. Long help for commandline option (editor): filename
+#: editor/gtk/editor.c:1066
+msgid "Open this file"
+msgstr "ãã®ãã¡ã¤ã«ãéã"
+
+#. Commandline option for editor: filename
+#: editor/gtk/editor.c:1068
+msgid "filename"
+msgstr "ãã¡ã¤ã«å"
+
+#: editor/gtk/editor.c:1100
+msgid "- Editor for games of Pioneers"
+msgstr "- ãã¤ãªãã¢ã²ã¼ã ã®ã¨ãã£ã¿"
+
+#: editor/gtk/editor.c:1141 server/gtk/main.c:1035
+#, c-format
+msgid "Building menus failed: %s"
+msgstr "ã¡ãã¥ã¼æ§ç¯ã«å¤±æ: %s"
+
+#: editor/gtk/editor.c:1169
+msgid "Settings"
+msgstr "è¨å®"
+
+#: editor/gtk/game-resources.c:51
+msgid "Resource Count"
+msgstr "è³æºæ°"
+
+#. Commandline meta-server: daemon
+#: meta-server/main.c:1033
+msgid "Daemonize the metaserver on start"
+msgstr "ã¡ã¿ãµã¼ãããã¼ã¢ã³ã¨ãã¦éå§"
+
+#. Commandline meta-server: redirect
+#: meta-server/main.c:1036
+msgid "Redirect clients to another metaserver"
+msgstr "ã¯ã©ã¤ã¢ã³ããä»ã®ã¡ã¿ãµã¼ãã«è»¢é"
+
+#. Commandline meta-server: server
+#: meta-server/main.c:1039
+msgid "Use this hostname when creating new games"
+msgstr "æ°ãã²ã¼ã ã使ããã¨ããã®ãã¹ãåã使ç¨"
+
+#. Commandline meta-server: server argument
+#: meta-server/main.c:1041
+msgid "hostname"
+msgstr "ãã¹ãå"
+
+#. Commandline meta-server: port-range
+#: meta-server/main.c:1044
+msgid "Use this ports range when creating new games"
+msgstr "æ°ããã²ã¼ã ã使ããã¨ãã«ãã®ãã¼ãã®ç¯å²ã使ç¨"
+
+#. Commandline meta-server: port-range argument
+#: meta-server/main.c:1046
+msgid "from-to"
+msgstr "from-to"
+
+#. Commandline option of meta server: syslog-debug
+#: meta-server/main.c:1052
+msgid "Debug syslog messages"
+msgstr "Debug·syslog·messages"
+
+#. Long description in the commandline for server-console: help
+#: meta-server/main.c:1073
+msgid "- Meta server for Pioneers"
+msgstr "- ãã¤ãªãã¢ã®ã¡ã¿ãµã¼ã"
+
+#: meta-server/main.c:1088
+#, c-format
+msgid "metaserver protocol:"
+msgstr "ã¡ã¿ãµã¼ããããã³ã«:"
+
+#: server/gtk/main.c:105
+msgid "_About Pioneers Server"
+msgstr "_About·Pioneers·Server"
+
+#: server/gtk/main.c:106
+msgid "Information about Pioneers Server"
+msgstr "ãã¤ãªãã¢ãµã¼ãã«é¢ããæ
å ±"
+
+#: server/gtk/main.c:222
+msgid "Stop server"
+msgstr "ãµã¼ã忢"
+
+#: server/gtk/main.c:223
+msgid "Start server"
+msgstr "ãµã¼ãéå§"
+
+#: server/gtk/main.c:225
+msgid "Stop the server"
+msgstr "ãµã¼ã忢"
+
+#: server/gtk/main.c:226
+msgid "Start the server"
+msgstr "ãµã¼ãéå§"
+
+#: server/gtk/main.c:351
+#, c-format
+msgid "Player %s from %s entered\n"
+msgstr "%s ãããã¬ã¤ã¤ã¼ %s ãåå .\n"
+
+#: server/gtk/main.c:358
+#, c-format
+msgid "Player %s from %s left\n"
+msgstr "%s ããã®ãã¬ã¤ã¤ã¼ %s ãæ®ã\n"
+
+#: server/gtk/main.c:365
+#, c-format
+msgid "Player %d is now %s\n"
+msgstr "ãã¬ã¤ã¤ã¼ %d ã¯ãä»ã %s.\n"
+
+#: server/gtk/main.c:554
+msgid "Game Settings"
+msgstr "ã²ã¼ã è¨å®"
+
+#: server/gtk/main.c:600
+msgid "Server Parameters"
+msgstr "ãµã¼ããã©ã¡ã¼ã¿"
+
+#: server/gtk/main.c:626
+msgid "The port for the game server"
+msgstr "ã²ã¼ã ãµã¼ãã®ãã¼ã"
+
+#: server/gtk/main.c:629
+msgid "Register Server"
+msgstr "ç»é²ãµã¼ã"
+
+#: server/gtk/main.c:637
+msgid "Register this game at the meta server"
+msgstr "ã¡ã¿ãµã¼ãã«ãã®ã²ã¼ã ã使"
+
+#: server/gtk/main.c:654
+msgid "The address of the meta server"
+msgstr "ã¡ã¿ãµã¼ãã®ã¢ãã¬ã¹"
+
+#: server/gtk/main.c:656
+msgid "Reported Hostname"
+msgstr "å ±åããããã¹ãå"
+
+#: server/gtk/main.c:671
+msgid ""
+"The public name of this computer (needed when playing behind a firewall)"
+msgstr "ãã®ã³ã³ãã¥ã¼ã¿ã®å
¬éå(ãã¡ã¤ã¢ã¼ã¦ã©ã¼ã«ãè¶ãã¦è¡ãæã«å¿
è¦)"
+
+#: server/gtk/main.c:675
+msgid "Random Turn Order"
+msgstr "ã©ã³ãã ãªã¿ã¼ã³é çª"
+
+#: server/gtk/main.c:683
+msgid "Randomize turn order"
+msgstr "ã©ã³ãã ãªã¿ã¼ã³é çª"
+
+#: server/gtk/main.c:722
+msgid "Running Game"
+msgstr "ã²ã¼ã é²è¡ä¸"
+
+#: server/gtk/main.c:724
+msgid "Players Connected"
+msgstr "ãã¬ã¤ã¤ã¼æ¥ç¶"
+
+#: server/gtk/main.c:758
+msgid "Shows all players and viewers connected to the server"
+msgstr "ãµã¼ãã«æ¥ç¶ãã¦ããå
¨ã¦ã®ãã¬ã¤ã¤ã¼ã¨è¦³æ¦è
ã表示"
+
+#: server/gtk/main.c:763
+msgid "Connected"
+msgstr "æ¥ç¶"
+
+#: server/gtk/main.c:770
+msgid "Is the player currently connected?"
+msgstr "ãã¬ã¤ã¤ã¼ã¯ç¾å¨æ¥ç¶ãã¦ããã?"
+
+#: server/gtk/main.c:773
+msgid "Name"
+msgstr "åå"
+
+#: server/gtk/main.c:780
+msgid "Name of the player"
+msgstr "ã²ã¼ã ã®åå"
+
+#: server/gtk/main.c:782
+msgid "Location"
+msgstr "å ´æ"
+
+#: server/gtk/main.c:789
+msgid "Host name of the player"
+msgstr "ãã¬ã¤ã¤ã¼ã®ãã¹ãå"
+
+#: server/gtk/main.c:793
+msgid "Number"
+msgstr "æ°"
+
+#: server/gtk/main.c:800
+msgid "Player number"
+msgstr "ãã¬ã¤ã¤ã¼æ°"
+
+#: server/gtk/main.c:804
+msgid "Role"
+msgstr "å½¹å²"
+
+#: server/gtk/main.c:808
+msgid "Player of viewer"
+msgstr "観æ¦è
"
+
+#: server/gtk/main.c:819
+msgid "Launch Pioneers Client"
+msgstr "ãã¤ãªãã¢ã²ã¼ã ã¯ã©ã¤ã¢ã³ãèµ·å"
+
+#: server/gtk/main.c:826
+msgid "Launch the Pioneers Client"
+msgstr "ãã¤ãªãã¢ã²ã¼ã ã¯ã©ã¤ã¢ã³ãèµ·å"
+
+#: server/gtk/main.c:828
+msgid "Computer Players"
+msgstr "ã³ã³ãã¥ã¼ã¿ ãã¬ã¤ã¤ã¼"
+
+#: server/gtk/main.c:837
+msgid "Enable Chat"
+msgstr "ãã£ããå¯"
+
+#: server/gtk/main.c:843
+msgid "Enable chat messages"
+msgstr "ãã£ãããå¯è½ã«ãã"
+
+#: server/gtk/main.c:850
+msgid "Add Computer Player"
+msgstr "ã³ã³ãã¥ã¼ã¿ ãã¬ã¤ã¤ã¼è¿½å "
+
+#: server/gtk/main.c:857
+msgid "Add a computer player to the game"
+msgstr "ã²ã¼ã ã«ã³ã³ãã¥ã¼ã¿ãã¬ã¤ã¤ã¼ã追å "
+
+#: server/gtk/main.c:866
+msgid "Messages"
+msgstr "ã¡ãã»ã¼ã¸"
+
+#: server/gtk/main.c:884
+msgid "Messages from the server"
+msgstr "ã¡ã¿ãµã¼ãããã®ã¡ãã»ã¼ã¸"
+
+#: server/gtk/main.c:932
+msgid "The Pioneers Game Server"
+msgstr "ãã¤ãªãã¢ã²ã¼ã ãµã¼ã"
+
+#. Wait for all players to disconnect,
+#. * then enable the UI
+#.
+#: server/gtk/main.c:940
+msgid "The game is over.\n"
+msgstr "ã²ã¼ã çµäº\n"
+
+#. Long description in the commandline for server-gtk: help
+#. Long description in the commandline for server-console: help
+#: server/gtk/main.c:994 server/main.c:174
+msgid "- Host a game of Pioneers"
+msgstr "- ãã¤ãªãã¢ã²ã¼ã ã主å¬ãã"
+
+#. Name in the titlebar of the server
+#: server/gtk/main.c:1016
+msgid "Pioneers Server"
+msgstr "ãã¤ãªãã¢ãµã¼ã"
+
+#. Commandline server-console: game-title
+#: server/main.c:75
+msgid "Game title to use"
+msgstr "使ç¨ããã²ã¼ã ã¿ã¤ãã«"
+
+#. Commandline server-console: file
+#: server/main.c:78
+msgid "Game file to use"
+msgstr "使ç¨ããã²ã¼ã ãã¡ã¤ã«"
+
+#. Commandline server-console: port
+#: server/main.c:81
+msgid "Port to listen on"
+msgstr "å¾
ã¡åãããã¼ã"
+
+#. Commandline server-console: players
+#: server/main.c:84
+msgid "Override number of players"
+msgstr "ãã¬ã¤ã¤ã¼ã®æ°ç¡å¹ã«ãã"
+
+#. Commandline server-console: points
+#: server/main.c:87
+msgid "Override number of points needed to win"
+msgstr "åå©ãã¤ã³ãæ°ãç¡å¹"
+
+#. Commandline server-console: seven-rule
+#: server/main.c:90
+msgid "Override seven-rule handling"
+msgstr "7ã®ç®ã«ã¼ã«ã®ãã³ãã«ã䏿¸ã"
+
+#. Commandline server-console: terrain
+#: server/main.c:93
+msgid "Override terrain type, 0=default 1=random"
+msgstr "é¸å°é åã䏿¸ã,·0=åæÂ·1=ã©ã³ãã "
+
+#. Commandline server-console: computer-players
+#: server/main.c:96
+msgid "Add N computer players"
+msgstr "N ã³ã³ãã¥ã¼ã¿ãã¬ã¤ã¤ã¼ã追å "
+
+#. Commandline server-console: register
+#: server/main.c:106
+msgid "Register server with meta-server"
+msgstr "ã¡ã¿ãµã¼ãã«ãµã¼ãã追å "
+
+#. Commandline server-console: meta-server
+#: server/main.c:109
+msgid "Register at meta-server name (implies -r)"
+msgstr "ã¡ã¿ãµã¼ãåãç»é²(-r ãä»ãã)"
+
+#. Commandline server-console: hostname
+#: server/main.c:113
+msgid "Use this hostname when registering"
+msgstr "ç»é²æã«ãã®ãã¹ãåãå©ç¨"
+
+#. Commandline server-console: auto-quit
+#: server/main.c:120
+msgid "Quit after a player has won"
+msgstr "ãã¬ã¤ã¤ã¼ãåå©ããå¾ã«çµäº"
+
+#. Commandline server-console: empty-timeout
+#: server/main.c:123
+msgid "Quit after N seconds with no players"
+msgstr "ãã¬ã¤ã¤ã¼ãããªããªã£ãå¾ãN ç§ã§çµäº"
+
+#. Commandline server-console: tournament
+#: server/main.c:126
+msgid "Tournament mode, computer players added after N minutes"
+msgstr "ãã¼ãã¡ã³ãã¢ã¼ããN åå¾ã«ã³ã³ãã¥ã¼ã¿ãã¬ã¤ã¤ã¼ã追å "
+
+#. Commandline server-console: admin-port
+#: server/main.c:130
+msgid "Admin port to listen on"
+msgstr "å¾
ã¡åã管çãã¼ã"
+
+#: server/main.c:134
+msgid "Don't start game immediately, wait for a command on admin port"
+msgstr "ç´ãã«ã¯ã²ã¼ã ãéå§ã§ãã¾ããã管çãã¼ãã¸ã®ã³ãã³ããå¾
ã£ã¦ãã¾ã"
+
+#: server/main.c:140
+msgid "Give players numbers according to the order they enter the game"
+msgstr "ã²ã¼ã ã«åå ããé çªã®ããã«ãã¬ã¤ã¤ã¼æ°ãå
¥åãã¦ãã ãã"
+
+#. Commandline server-console: Short description of meta group
+#: server/main.c:180
+msgid "Meta-server Options"
+msgstr "ã¡ã¿ãµã¼ããªãã·ã§ã³"
+
+#: server/main.c:183
+msgid "Options for the meta-server"
+msgstr "ã¡ã¿ãµã¼ãã¸ã®ãªãã·ã§ã³"
+
+#. Commandline server-console: Short description of misc group
+#: server/main.c:191
+msgid "Miscellaneous Options"
+msgstr "æ§ã
ãªãªãã·ã§ã³"
+
+#. Commandline server-console: Long description of misc group
+#: server/main.c:193
+msgid "Miscellaneous options"
+msgstr "æ§ã
ãªãªãã·ã§ã³"
+
+#: server/meta.c:193
+#, c-format
+msgid "Register with meta-server at %s, port %s\n"
+msgstr "%s ã®ãã¼ã %s ã§ã¡ã¿ãµã¼ãã«ç»é²\n"
+
+#: server/meta.c:210
+msgid "Unregister from meta-server\n"
+msgstr "ã¡ã¿ãµã¼ãããç»é²ä¸è½\n"
+
+#: server/player.c:130
+msgid "chat too long"
+msgstr "é·ããããã£ãã"
+
+#: server/player.c:147
+msgid "name too long"
+msgstr "é·ãããåå"
+
+#: server/player.c:179
+msgid "ignoring unknown extension"
+msgstr "ä¸æãªæ¡å¼µåãç¡è¦"
+
+#: server/player.c:209
+msgid "Game starts, adding computer players"
+msgstr "ã²ã¼ã éå§ãã³ã³ãã¥ã¼ã¿ãã¬ã¤ã¤ã¼è¿½å "
+
+#: server/player.c:234
+#, c-format
+msgid "The game starts in %s minutes."
+msgstr "%s å以å
ã«ã²ã¼ã éå§"
+
+#: server/player.c:235
+#, c-format
+msgid "The game starts in %s minute."
+msgstr "%s å以å
ã«ã²ã¼ã éå§"
+
+#: server/player.c:280
+msgid "Sorry, game is over."
+msgstr "ãã¿ã¾ãããã²ã¼ã çµäº"
+
+#: server/player.c:283
+#, c-format
+msgid "Player from %s is refused: game is over\n"
+msgstr "%s ã®ãã¬ã¤ã¤ã¼ã¯æå¦:ãã²ã¼ã çµäº\n"
+
+#: server/player.c:331
+msgid "This game will start soon."
+msgstr "ãã®ã²ã¼ã ã¯ç´ãã«å§ã¾ã"
+
+#: server/player.c:359
+msgid "Name not changed: new name is already in use"
+msgstr "夿´ä¸å¯è½ãªåå: æ°ããååã¯æ¢ã«ä½¿ç¨ããã¦ã"
+
+#. %s is the name of the reconnecting player
+#: server/player.c:648
+#, c-format
+msgid "%s has reconnected."
+msgstr "%s ã¯ã忥ç¶ã"
+
+#: server/player.c:776
+#, c-format
+msgid "Version mismatch: %s"
+msgstr "ãã¼ã¸ã§ã³ä¸æ´å: %s"
+
+#: server/server.c:47
+msgid "Was hanging around for too long without players... bye.\n"
+msgstr "ãã¬ã¤ã¤ã¼ãªãã§é·ãã¨ã¾ããã....ã°ã.\n"
+
+#. Server: preparing game #.....
+#: server/server.c:219
+msgid "Preparing game"
+msgstr "ã²ã¼ã æºå"
+
+#: server/server.c:337
+msgid "Missing game directory\n"
+msgstr "ã²ã¼ã ãã£ã¬ã¯ããªã䏿\n"
+
+#: server/turn.c:253
+msgid "Island Discovery Bonus"
+msgstr "å³¶çºè¦ãã¼ãã¹"
+
+#: server/turn.c:256
+msgid "Additional Island Bonus"
+msgstr "島追å ãã¼ãã¹"
+
+#: server/turn.c:388
+msgid "Tried to assign resources to NULL player.\n"
+msgstr "NULL ãã¬ã¤ã¤ã¼ã«ãè³æºã使ããããã¨ãã\n"
+
+#~ msgid "Brick port|B"
+#~ msgstr "ç
ç¦æ¸¯|B"
+
+#~ msgid "Grain port|G"
+#~ msgstr "å°éº¦æ¸¯|G"
+
+#~ msgid "Ore port|O"
+#~ msgstr "é±ç³æ¸¯|O"
+
+#~ msgid "Wool port|W"
+#~ msgstr "ç¾æ¯æ¸¯|W"
+
+#~ msgid "Lumber port|L"
+#~ msgstr "æ¨ææ¸¯|L"
+
+#~ msgid "Continue with your turn."
+#~ msgstr "ããªãã®çªãé²è¡ä¸"
+
+#~ msgid "Map Terrain"
+#~ msgstr "é¸ä¸å°å³"
+
+#~ msgid "Default map or a random map"
+#~ msgstr "åæå°å³ãã©ã³ãã å°å³"
Added: trunk/po/nl.po
===================================================================
--- trunk/po/nl.po (rev 0)
+++ trunk/po/nl.po 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,3298 @@
+# Translation to dutch
+# Copyright (C) 2003 Bas Wijnen
+# This file is distributed under the same license as the pioneers package.
+# Bas Wijnen <b.wijnen at phys.rug.nl>, 2003-2004
+# Roland Clobus <rclobus at bigfoot.com>, 2005-2006
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Pioneers 0.11.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-07 20:43+0200\n"
+"PO-Revision-Date: 2007-07-12 22:00+0200\n"
+"Last-Translator: Roland Clobus <rclobus at bigfoot.com>\n"
+"Language-Team: Bas Wijnen <shevek at fmf.nl> Roland Clobus <rclobus at bigfoot."
+"com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Default name for the AI when the computer_names file
+#. * is not found or empty.
+#.
+#: client/ai/ai.c:74 client/ai/ai.c:90
+msgid "Computer Player"
+msgstr "Computer speler"
+
+#. Commandline pioneersai: server
+#. Commandline option of client: hostname of the server
+#: client/ai/ai.c:102 client/gtk/connect.c:1462 client/gtk/offline.c:53
+msgid "Server Host"
+msgstr "Computer"
+
+#. Commandline pioneersai: port
+#. Commandline option of client: port of the server
+#: client/ai/ai.c:105 client/gtk/connect.c:1478 client/gtk/offline.c:56
+#: server/gtk/main.c:612
+msgid "Server Port"
+msgstr "Poort"
+
+#. Commandline pioneersai: name
+#: client/ai/ai.c:108
+msgid "Computer name (leave absent for random name)"
+msgstr "Computerspelernaam (laat leeg voor een willekeurige naam)"
+
+#. Commandline pioneersai: time
+#: client/ai/ai.c:111
+msgid "Time to wait between turns (in milliseconds)"
+msgstr "Tijd tussen twee beurten (in milliseconde)"
+
+#. Commandline pioneersai: chat-free
+#: client/ai/ai.c:114
+msgid "Stop computer player from talking"
+msgstr "Laat computerspeler zwijgen"
+
+#. Commandline pioneersai: algorithm
+#: client/ai/ai.c:117
+msgid "Type of computer player"
+msgstr "Soort computerspeler"
+
+#. Commandline option of ai: enable debug logging
+#. Commandline option of client: enable debug logging
+#. Commandline option of meta server: enable debug logging
+#. Commandline option of server-gtk: enable debug logging
+#. Commandline option of server: enable debug logging
+#: client/ai/ai.c:120 client/gtk/offline.c:74 meta-server/main.c:1049
+#: server/gtk/main.c:952 server/main.c:144
+msgid "Enable debug messages"
+msgstr "Toon debug boodschappen"
+
+#. Commandline option of ai: version
+#. Commandline option of client: version
+#. Commandline option of editor: version
+#. Commandline option of meta server: version
+#. Commandline option of server-gtk: version
+#. Commandline option of server-console: version
+#: client/ai/ai.c:123 client/gtk/offline.c:77 editor/gtk/editor.c:1071
+#: meta-server/main.c:1055 server/gtk/main.c:955 server/main.c:99
+msgid "Show version information"
+msgstr "Toon versie informatie"
+
+#: client/ai/ai.c:134
+msgid "- Computer player for Pioneers"
+msgstr "- Computerspeler voor Pioniers"
+
+#: client/ai/ai.c:144 client/gtk/offline.c:186 editor/gtk/editor.c:1111
+#: meta-server/main.c:1084 server/gtk/main.c:1005 server/main.c:206
+#, c-format
+msgid "Pioneers version:"
+msgstr "Pioniers versie:"
+
+#: client/ai/ai.c:176
+#, c-format
+msgid "Type of computer player: %s\n"
+msgstr "Soort computerspeler: %s\n"
+
+#: client/ai/ai.c:205
+msgid "The game is already full. I'm leaving."
+msgstr "Het spel is al vol. Ik blijf niet kijken."
+
+#: client/ai/greedy.c:941
+msgid "No settlements in stock to use for setup"
+msgstr "Er zijn geen dorpen beschikbaar om te bouwen"
+
+#: client/ai/greedy.c:948
+msgid "There is no place to setup a settlement"
+msgstr "Er is geen plek om een dorp te bouwen"
+
+#: client/ai/greedy.c:972
+msgid "No roads in stock to use for setup"
+msgstr "Er zijn geen wegen beschikbaar om te bouwen"
+
+#: client/ai/greedy.c:989
+msgid "There is no place to setup a road"
+msgstr "Er is geen plek om een weg te bouwen"
+
+#: client/ai/greedy.c:1291
+msgid "Ok, let's go!"
+msgstr "We gaan ervoor!"
+
+#: client/ai/greedy.c:1292
+msgid "I'll beat you all now! ;)"
+msgstr "Deze keer gaat het me lukken! ;-)"
+
+#: client/ai/greedy.c:1293
+msgid "Now for another try..."
+msgstr "Nog een keer proberen..."
+
+#: client/ai/greedy.c:1297
+msgid "At least I get something..."
+msgstr "Ik krijg ten minste iets..."
+
+#: client/ai/greedy.c:1298
+msgid "One is better than none..."
+msgstr "Iets is beter dan niets..."
+
+#: client/ai/greedy.c:1302
+msgid "Wow!"
+msgstr "Wauw!"
+
+#: client/ai/greedy.c:1303
+msgid "Ey, I'm becoming rich ;)"
+msgstr "Ha, ik word rijk ;-)"
+
+#: client/ai/greedy.c:1304
+msgid "This is really a good year!"
+msgstr "Dit is echt een goed jaar!"
+
+#: client/ai/greedy.c:1307
+msgid "You really don't deserve that much!"
+msgstr "Jij zou minder moeten krijgen!"
+
+#: client/ai/greedy.c:1308
+msgid "You don't know what to do with that many resources ;)"
+msgstr "Je weet niet wat je aan moet met al die grondstoffen ;-)"
+
+#: client/ai/greedy.c:1309
+msgid "Ey, wait for my robber and lose all this again!"
+msgstr "Wacht maar op mijn struikrover, dan raak je het wel weer kwijt!"
+
+#: client/ai/greedy.c:1312
+msgid "Hehe!"
+msgstr "Hehe!"
+
+#: client/ai/greedy.c:1313
+msgid "Go, robber, go!"
+msgstr "Toe maar, struikrover!"
+
+#: client/ai/greedy.c:1316
+msgid "You bastard!"
+msgstr "Schurk!"
+
+#: client/ai/greedy.c:1317
+msgid "Can't you move that robber somewhere else?!"
+msgstr "Kan je die struikrover niet ergens anders neerzetten?"
+
+#: client/ai/greedy.c:1318
+msgid "Why always me??"
+msgstr "Waarom moet je mij altijd hebben?"
+
+#: client/ai/greedy.c:1321
+msgid "Oh no!"
+msgstr "Oh nee!"
+
+#: client/ai/greedy.c:1322
+msgid "Grrr!"
+msgstr "Grrr!"
+
+#: client/ai/greedy.c:1323
+msgid "Who the hell rolled that 7??"
+msgstr "Welke idioot rolt er nou weer een 7?"
+
+#: client/ai/greedy.c:1324
+msgid "Why always me?!?"
+msgstr "Waarom gebeurt mij dat altijd?"
+
+#: client/ai/greedy.c:1327
+msgid "Say good bye to your cards... :)"
+msgstr "Zeg maar dag tegen je kaarten... :-)"
+
+#: client/ai/greedy.c:1328
+msgid "*evilgrin*"
+msgstr "Haha!"
+
+#: client/ai/greedy.c:1329
+msgid "/me says farewell to your cards ;)"
+msgstr "/me zegt je kaarten vaarwel ;-)"
+
+#: client/ai/greedy.c:1330
+msgid "That's the price for being rich... :)"
+msgstr "Dat is de prijs van het rijk zijn... :-)"
+
+#: client/ai/greedy.c:1333
+msgid "Ey! Where's that card gone?"
+msgstr "Hé! Waar is die kaart heen?"
+
+#: client/ai/greedy.c:1334
+msgid "Thieves! Thieves!!"
+msgstr "Houd de dief!"
+
+#: client/ai/greedy.c:1335
+msgid "Wait for my revenge..."
+msgstr "Wacht maar, ik krijg je nog wel..."
+
+#: client/ai/greedy.c:1338
+msgid "Oh no :("
+msgstr "Oh nee!"
+
+#: client/ai/greedy.c:1339
+msgid "Must this happen NOW??"
+msgstr "Moet dat _nu_?"
+
+#: client/ai/greedy.c:1340
+msgid "Args"
+msgstr "Arg"
+
+#: client/ai/greedy.c:1343
+msgid "Hehe, my soldiers rule!"
+msgstr "Haha, mijn ridders zijn stoer!"
+
+#: client/ai/greedy.c:1346
+msgid "First robbing us, then grabbing the points..."
+msgstr "Eerst worden we beroofd, en dan wil je er nog punten voor ook..."
+
+#: client/ai/greedy.c:1349
+msgid "See that road!"
+msgstr "Moet je die weg zien!"
+
+#: client/ai/greedy.c:1352
+msgid "Pf, you won't win with roads alone..."
+msgstr "Pff, met alleen wegen win je het spel niet..."
+
+#: client/ai/greedy.c:1819
+msgid "Rejecting trade.\n"
+msgstr "Handelsvoorstel wordt afgewezen.\n"
+
+#: client/ai/greedy.c:1911
+#, c-format
+msgid "Received error from server: %s. Quitting\n"
+msgstr ""
+"Foutmelding van de server ontvangen: %s. Het programma wordt afgesloten\n"
+
+#: client/ai/greedy.c:1921
+msgid "Yippie!"
+msgstr "Hoera!"
+
+#: client/ai/greedy.c:1923
+msgid "My congratulations"
+msgstr "Gefeliciteerd"
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:80
+msgid ""
+"Hello, welcome to the lobby. I am a simple robot. Type '/help' in the chat "
+"to see the list of commands I know."
+msgstr ""
+"Hallo, welkom in the ontvangstruimte. Ik ben een eenvoudige robot. Typ '/"
+"help' in de chat om de lijst van commando's te zien."
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:107
+msgid "'/help' shows this message again"
+msgstr "'/help' toont deze boodschap opnieuw"
+
+#. Translators: don't translate '/why'
+#: client/ai/lobbybot.c:110
+msgid "'/why' explains the purpose of this strange board layout"
+msgstr "'/why' verklaart het doel van dit bord"
+
+#. Translators: don't translate '/news'
+#: client/ai/lobbybot.c:113
+msgid "'/news' tells the last released version"
+msgstr "'/news' geeft de laatst vrijgegeven versie"
+
+#: client/ai/lobbybot.c:118
+msgid ""
+"This board is not intended to be a game that can be played. Instead, players "
+"can find eachother here, and decide which board they want to play. Then, one "
+"of the players will host the proposed game by starting a server, and "
+"registers it at the metaserver. The other players can subsequently "
+"disconnect from the lobby, and enter that game."
+msgstr ""
+"Dit bord is niet bedoeld om op te spelen. In plaats daarvan is het een "
+"ontmoetingspunt voor spelers die kunnen afspreken welk spel ze willen "
+"spelen. Vervolgens kan een van de spelers het afgesproken spel hosten door "
+"een server te starten en die te registreren op de metaserver. Vervolgens "
+"kunnen de andere spelers de ontvangstruimte verlaten en het spel binnengaan."
+
+#: client/ai/lobbybot.c:129
+msgid "The last released version of Pioneers is"
+msgstr "De laatst vrijgegeven versie van Pioneers is"
+
+#: client/ai/lobbybot.c:144
+msgid "The game is starting. I'm not needed anymore. Goodbye."
+msgstr "Het spel begint. Ik ben niet meer nodig. Tot ziens."
+
+#: client/common/client.c:103
+msgid "Waiting"
+msgstr "Wachten op reaktie van de server."
+
+#: client/common/client.c:105 client/common/client.c:1241
+msgid "Idle"
+msgstr "Klaar"
+
+#: client/common/client.c:447
+msgid "We have been kicked out of the game.\n"
+msgstr "De verbinding met de server is verbroken.\n"
+
+#. Network status: offline
+#: client/common/client.c:450 client/common/client.c:891 client/gtk/gui.c:1340
+msgid "Offline"
+msgstr "Er is geen verbinding met een server."
+
+#: client/common/client.c:471
+#, c-format
+msgid "Error (%s): %s\n"
+msgstr "Fout (%s): %s\n"
+
+#: client/common/client.c:480 client/common/client.c:491
+#, c-format
+msgid "Notice: %s\n"
+msgstr "Bericht: %s\n"
+
+#: client/common/client.c:607
+#, c-format
+msgid "%s does not receive any %s, because the bank is empty.\n"
+msgstr "%s heeft geen %s ontvangen, omdat de bank leeg is.\n"
+
+#: client/common/client.c:620
+#, c-format
+msgid "%s only receives %s, because the bank didn't have any more.\n"
+msgstr "%s ontvangt slechts %s, omdat de bank niet meer bevat.\n"
+
+#: client/common/client.c:629
+#, c-format
+msgid "%s receives %s.\n"
+msgstr "%s krijgt %s.\n"
+
+#. Year of Plenty
+#: client/common/client.c:637 client/common/client.c:2586
+#, c-format
+msgid "%s takes %s.\n"
+msgstr "%s neemt %s.\n"
+
+#: client/common/client.c:642
+#, c-format
+msgid "%s spent %s.\n"
+msgstr "%s betaalt %s.\n"
+
+#: client/common/client.c:648
+#, c-format
+msgid "%s is refunded %s.\n"
+msgstr "%s krijgt %s terug.\n"
+
+#: client/common/client.c:679
+#, c-format
+msgid "%s discarded %s.\n"
+msgstr "%s gooit %s weg.\n"
+
+#: client/common/client.c:849
+msgid "Loading"
+msgstr "Het spel wordt gestart"
+
+#: client/common/client.c:892
+msgid "Version mismatch"
+msgstr "Versie verschillend"
+
+#: client/common/client.c:894
+msgid "Version mismatch. Please make sure client and server are up to date.\n"
+msgstr "De versies van de de server en de client komen niet overeen.\n"
+
+#: client/common/client.c:1340
+msgid "Build two settlements, each with a connecting"
+msgstr "Bouw twee dorpen, elk met een aangesloten"
+
+#: client/common/client.c:1343
+msgid "Build a settlement with a connecting"
+msgstr "Bouw een dorp met een aangesloten"
+
+#: client/common/client.c:1346
+msgid "road"
+msgstr "straat"
+
+#: client/common/client.c:1348
+msgid "bridge"
+msgstr "brug"
+
+#: client/common/client.c:1350
+msgid "ship"
+msgstr "schip"
+
+#: client/common/client.c:1358
+msgid " or"
+msgstr " of"
+
+#: client/common/client.c:1416
+msgid "Waiting for your turn"
+msgstr "Wacht op je beurt."
+
+#: client/common/client.c:1468
+msgid "Select the building to steal from."
+msgstr "Kies een gebouw om te bestelen."
+
+#: client/common/client.c:1490
+msgid "Select the ship to steal from."
+msgstr "Kies een schip om te bestelen."
+
+#: client/common/client.c:1575 client/gtk/interface.c:782
+msgid "Place the robber"
+msgstr "Plaats de struikrover"
+
+#: client/common/client.c:1625
+msgid "Finish the road building action."
+msgstr "Beëindig de bouwkaart"
+
+#: client/common/client.c:1627
+msgid "Build one road segment."
+msgstr "Bouw een straat."
+
+#: client/common/client.c:1629
+msgid "Build two road segments."
+msgstr "Bouw twee straten."
+
+#: client/common/client.c:1902 client/common/client.c:1996
+msgid "It is your turn."
+msgstr "Je bent aan de beurt."
+
+#: client/common/client.c:2090
+#, c-format
+msgid "Sorry, %s available.\n"
+msgstr "Sorry, %s beschikbaar.\n"
+
+#: client/common/client.c:2405
+msgid "The game is over."
+msgstr "Het spel is afgelopen."
+
+#: client/common/develop.c:43 editor/gtk/game-devcards.c:13
+msgid "Road Building"
+msgstr "Stratenbouw"
+
+#: client/common/develop.c:44 client/gtk/monopoly.c:83
+#: editor/gtk/game-devcards.c:13
+msgid "Monopoly"
+msgstr "Monopolie"
+
+#: client/common/develop.c:45 client/gtk/plenty.c:59
+#: editor/gtk/game-devcards.c:13
+msgid "Year of Plenty"
+msgstr "Goed Jaar"
+
+#: client/common/develop.c:46 client/gtk/player.c:57
+#: editor/gtk/game-devcards.c:14
+msgid "Chapel"
+msgstr "Kapel"
+
+#: client/common/develop.c:47 client/gtk/player.c:58
+#: editor/gtk/game-devcards.c:14
+msgid "Pioneer University"
+msgstr "Pioniers universiteit"
+
+#: client/common/develop.c:48 client/gtk/player.c:60
+#: editor/gtk/game-devcards.c:15
+msgid "Governor's House"
+msgstr "Gouverneurshuis"
+
+#: client/common/develop.c:49 client/gtk/player.c:61
+#: editor/gtk/game-devcards.c:15
+msgid "Library"
+msgstr "Bibliotheek"
+
+#: client/common/develop.c:50 client/gtk/player.c:62
+#: editor/gtk/game-devcards.c:15
+msgid "Market"
+msgstr "Markt"
+
+#: client/common/develop.c:51 client/gtk/player.c:63
+#: editor/gtk/game-devcards.c:16
+msgid "Soldier"
+msgstr "Ridder"
+
+#: client/common/develop.c:82
+#, c-format
+msgid "You bought the %s development card.\n"
+msgstr "Je hebt de %s ontwikkelingskaart gekocht.\n"
+
+#: client/common/develop.c:88
+#, c-format
+msgid "You bought a %s development card.\n"
+msgstr "Je hebt een %s ontwikkelingskaart gekocht.\n"
+
+#: client/common/develop.c:110
+#, c-format
+msgid "%s bought a development card.\n"
+msgstr "%s koopt een ontwikkelingskaart.\n"
+
+#: client/common/develop.c:129
+#, c-format
+msgid "%s played the %s development card.\n"
+msgstr "%s speelt de %s ontwikkelingskaart.\n"
+
+#: client/common/develop.c:134
+#, c-format
+msgid "%s played a %s development card.\n"
+msgstr "%s speelt een %s ontwikkelingskaart.\n"
+
+#: client/common/develop.c:147
+msgid "You have run out of road segments.\n"
+msgstr "Je hebt geen straten meer.\n"
+
+#. I get the cards!
+#.
+#: client/common/develop.c:187
+#, c-format
+msgid "You get %s from %s.\n"
+msgstr "Je krijgt %s van %s.\n"
+
+#. I lose the cards!
+#.
+#: client/common/develop.c:193
+#, c-format
+msgid "%s took %s from you.\n"
+msgstr "Je geeft %s %s.\n"
+
+#: client/common/develop.c:200
+#, c-format
+msgid "%s took %s from %s.\n"
+msgstr "%3$s geeft %2$s aan %1$s.\n"
+
+#: client/common/player.c:124 server/player.c:405
+#, c-format
+msgid "Viewer %d"
+msgstr "Toeschouwer %d"
+
+#: client/common/player.c:126
+#, c-format
+msgid "viewer %d"
+msgstr "toeschouwer %d"
+
+#: client/common/player.c:134 server/player.c:408
+#, c-format
+msgid "Player %d"
+msgstr "Speler %d"
+
+#: client/common/player.c:136
+#, c-format
+msgid "player %d"
+msgstr "speler %d"
+
+#: client/common/player.c:212
+#, c-format
+msgid "New viewer: %s.\n"
+msgstr "Er is een nieuwe toeschouwer: %s.\n"
+
+#: client/common/player.c:215 client/common/player.c:231
+#, c-format
+msgid "%s is now %s.\n"
+msgstr "%s is nu %s.\n"
+
+#: client/common/player.c:228
+#, c-format
+msgid "Player %d is now %s.\n"
+msgstr "Speler %d is nu %s.\n"
+
+#: client/common/player.c:267
+#, c-format
+msgid "%s has quit\n"
+msgstr "%s heeft de verbinding verbroken.\n"
+
+#: client/common/player.c:276
+msgid "There is no largest army.\n"
+msgstr "Er is geen grootste riddermacht.\n"
+
+#: client/common/player.c:279
+#, c-format
+msgid "%s has the largest army.\n"
+msgstr "%s heeft de grootste riddermacht.\n"
+
+#: client/common/player.c:300
+msgid "There is no longest road.\n"
+msgstr "Er is geen langste handelsroute.\n"
+
+#: client/common/player.c:303
+#, c-format
+msgid "%s has the longest road.\n"
+msgstr "%s heeft de langste handelsroute.\n"
+
+#: client/common/player.c:324
+#, c-format
+msgid "Waiting for %s."
+msgstr "Wacht op %s."
+
+#. We are not in on the action
+#. someone stole a resource from someone else
+#: client/common/player.c:352
+#, c-format
+msgid "%s stole a resource from %s.\n"
+msgstr "%s steelt een kaart van %s.\n"
+
+#: client/common/player.c:362
+#, c-format
+msgid "You stole %s from %s.\n"
+msgstr "Je hebt %s van %s gestolen.\n"
+
+#: client/common/player.c:368
+#, c-format
+msgid "%s stole %s from you.\n"
+msgstr "%s heeft %s van jou gestolen.\n"
+
+#: client/common/player.c:402
+#, c-format
+msgid "%s gave %s nothing!?\n"
+msgstr "%s gaf %s niks!?\n"
+
+#: client/common/player.c:408 client/common/player.c:416
+#, c-format
+msgid "%s gave %s %s for free.\n"
+msgstr "%s gaf %s gratis %s.\n"
+
+#: client/common/player.c:424
+#, c-format
+msgid "%s gave %s %s in exchange for %s.\n"
+msgstr "%s gaf %s %s in ruil voor %s.\n"
+
+#: client/common/player.c:455
+#, c-format
+msgid "%s exchanged %s for %s.\n"
+msgstr "%s ruilt %s tegen %s met de bank.\n"
+
+#: client/common/player.c:475
+#, c-format
+msgid "%s built a road.\n"
+msgstr "%s bouwt een weg.\n"
+
+#: client/common/player.c:487
+#, c-format
+msgid "%s built a ship.\n"
+msgstr "%s bouwt een schip.\n"
+
+#: client/common/player.c:500
+#, c-format
+msgid "%s built a settlement.\n"
+msgstr "%s bouwt een dorp.\n"
+
+#: client/common/player.c:519
+#, c-format
+msgid "%s built a city.\n"
+msgstr "%s bouwt een stad.\n"
+
+#: client/common/player.c:533
+#, c-format
+msgid "%s built a city wall.\n"
+msgstr "%s bouwt een stadsmuur.\n"
+
+#: client/common/player.c:544
+#, c-format
+msgid "player_build_add called with BUILD_NONE for user %s\n"
+msgstr "player_build_add aangeroepen met BUILD_NONE voor %s\n"
+
+#: client/common/player.c:553
+#, c-format
+msgid "%s built a bridge.\n"
+msgstr "%s heeft een brug gebouwd.\n"
+
+#: client/common/player.c:579
+#, c-format
+msgid "%s removed a road.\n"
+msgstr "%s haalt een straat weg.\n"
+
+#: client/common/player.c:589
+#, c-format
+msgid "%s removed a ship.\n"
+msgstr "%s haalt een schip weg.\n"
+
+#: client/common/player.c:599
+#, c-format
+msgid "%s removed a settlement.\n"
+msgstr "%s haalt een dorp weg.\n"
+
+#: client/common/player.c:610
+#, c-format
+msgid "%s removed a city.\n"
+msgstr "%s haalt een stad weg.\n"
+
+#: client/common/player.c:624
+#, c-format
+msgid "%s removed a city wall.\n"
+msgstr "%s haalt een stadsmuur weg.\n"
+
+#: client/common/player.c:634
+#, c-format
+msgid "player_build_remove called with BUILD_NONE for user %s\n"
+msgstr "player_build_remove aangeroepen met BUILD_NONE voor %s\n"
+
+#: client/common/player.c:642
+#, c-format
+msgid "%s removed a bridge.\n"
+msgstr "%s heeft een brug weggehaald.\n"
+
+#: client/common/player.c:673
+#, c-format
+msgid "%s has cancelled a ship's movement.\n"
+msgstr "%s laat het schip toch maar niet varen.\n"
+
+#: client/common/player.c:676
+#, c-format
+msgid "%s moved a ship.\n"
+msgstr "%s vaart met een schip.\n"
+
+#. tell the user that someone got something
+#: client/common/player.c:696
+#, c-format
+msgid "%s received %s.\n"
+msgstr "%s krijgt %s.\n"
+
+#: client/common/player.c:714
+msgid "server asks to lose invalid point.\n"
+msgstr "De server probeert een ongeldig punt te verwijderen.\n"
+
+#. tell the user the point is lost
+#: client/common/player.c:720
+#, c-format
+msgid "%s lost %s.\n"
+msgstr "%s heeft %s verloren.\n"
+
+#: client/common/player.c:743
+msgid "server asks to move invalid point.\n"
+msgstr ""
+"De server probeert een ongeldig punt van eigenaar te laten veranderen.\n"
+
+#. tell the user someone (1) lost something (2) to someone else (3)
+#: client/common/player.c:750
+#, c-format
+msgid "%s lost %s to %s.\n"
+msgstr "%s verliest %s aan %s.\n"
+
+#: client/common/resource.c:35
+msgid "brick"
+msgstr "baksteen"
+
+#: client/common/resource.c:35
+msgid "Brick"
+msgstr "Baksteen"
+
+#: client/common/resource.c:36
+msgid "grain"
+msgstr "graan"
+
+#: client/common/resource.c:36
+msgid "Grain"
+msgstr "Graan"
+
+#: client/common/resource.c:37
+msgid "ore"
+msgstr "ijzererts"
+
+#: client/common/resource.c:37
+msgid "Ore"
+msgstr "IJzererts"
+
+#: client/common/resource.c:38
+msgid "wool"
+msgstr "wol"
+
+#: client/common/resource.c:38
+msgid "Wool"
+msgstr "Wol"
+
+#: client/common/resource.c:39
+msgid "lumber"
+msgstr "hout"
+
+#: client/common/resource.c:39
+msgid "Lumber"
+msgstr "Hout"
+
+#: client/common/resource.c:40
+msgid "no resource (bug)"
+msgstr "geen grondstof (fout)"
+
+#: client/common/resource.c:40
+msgid "No resource (bug)"
+msgstr "Geen grondstof (fout)"
+
+#: client/common/resource.c:41
+msgid "any resource (bug)"
+msgstr "enige grondstof (fout)"
+
+#: client/common/resource.c:41
+msgid "Any resource (bug)"
+msgstr "Enige grondstof (fout)"
+
+#: client/common/resource.c:42
+msgid "gold"
+msgstr "goud"
+
+#: client/common/resource.c:42 client/gtk/legend.c:39
+msgid "Gold"
+msgstr "Goud"
+
+#: client/common/resource.c:47
+msgid "a brick card"
+msgstr "een baksteenkaart"
+
+#: client/common/resource.c:47
+#, c-format
+msgid "%d brick cards"
+msgstr "%d baksteenkaarten"
+
+#: client/common/resource.c:48
+msgid "a grain card"
+msgstr "een graankaart"
+
+#: client/common/resource.c:48
+#, c-format
+msgid "%d grain cards"
+msgstr "%d graankaarten"
+
+#: client/common/resource.c:49
+msgid "an ore card"
+msgstr "een ijzerertskaart"
+
+#: client/common/resource.c:49
+#, c-format
+msgid "%d ore cards"
+msgstr "%d ijzerertskaarten"
+
+#: client/common/resource.c:50
+msgid "a wool card"
+msgstr "een wolkaart"
+
+#: client/common/resource.c:50
+#, c-format
+msgid "%d wool cards"
+msgstr "%d wolkaarten"
+
+#: client/common/resource.c:51
+msgid "a lumber card"
+msgstr "een houtkaart"
+
+#: client/common/resource.c:51
+#, c-format
+msgid "%d lumber cards"
+msgstr "%d houtkaarten"
+
+#: client/common/resource.c:139 client/common/resource.c:225
+msgid "nothing"
+msgstr "niks"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:166
+#, c-format
+msgid "%s and %s"
+msgstr "%s en %s"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:170
+#, c-format
+msgid "%s, %s"
+msgstr "%s, %s"
+
+#: client/common/robber.c:60
+#, c-format
+msgid "%s has undone the robber movement.\n"
+msgstr "%s heeft de struikrover teruggezet.\n"
+
+#: client/common/robber.c:63
+#, c-format
+msgid "%s moved the robber.\n"
+msgstr "%s verplaatst de struikrover.\n"
+
+#: client/common/robber.c:73
+#, c-format
+msgid "%s has undone the pirate movement.\n"
+msgstr "%s heeft de piraat teruggezet.\n"
+
+#: client/common/robber.c:76
+#, c-format
+msgid "%s moved the pirate.\n"
+msgstr "%s heeft de piraat bewogen.\n"
+
+#: client/common/robber.c:83
+#, c-format
+msgid "%s must move the robber."
+msgstr "%s moet de struikrover verplaatsen."
+
+#: client/common/setup.c:140
+#, c-format
+msgid "Setup for %s.\n"
+msgstr "%s mag opzetten.\n"
+
+#: client/common/setup.c:152
+#, c-format
+msgid "Double setup for %s.\n"
+msgstr "%s mag dubbel opzetten.\n"
+
+#: client/common/turn.c:37
+#, c-format
+msgid "%s rolled %d.\n"
+msgstr "%s heeft %d gerold.\n"
+
+#: client/common/turn.c:50
+#, c-format
+msgid "Begin turn %d for %s.\n"
+msgstr "%2$s is aan de beurt voor beurt %1$d.\n"
+
+#: client/gtk/chat.c:71
+msgid "<b>Chat</b>"
+msgstr "<b>Chat</b>"
+
+#: client/gtk/chat.c:231
+msgid "Beeper test.\n"
+msgstr "Pieper test.\n"
+
+#: client/gtk/chat.c:234
+#, c-format
+msgid "%s beeped you.\n"
+msgstr "%s piept je.\n"
+
+#: client/gtk/chat.c:238
+#, c-format
+msgid "You beeped %s.\n"
+msgstr "Je piept %s.\n"
+
+#: client/gtk/chat.c:244
+#, c-format
+msgid "You could not beep %s.\n"
+msgstr "Je kon %s niet piepen.\n"
+
+#: client/gtk/chat.c:288
+msgid " said: "
+msgstr " zegt: "
+
+#: client/gtk/connect.c:282
+#, c-format
+msgid "Meta-server at %s, port %s"
+msgstr "Metaserver op %s, poort %s"
+
+#: client/gtk/connect.c:292
+msgid "Finished.\n"
+msgstr "Klaar.\n"
+
+#: client/gtk/connect.c:309 client/gtk/connect.c:359 client/gtk/connect.c:456
+#: server/meta.c:174
+msgid "Meta-server kicked us off\n"
+msgstr "De metaserver heeft de verbinding verbroken.\n"
+
+#: client/gtk/connect.c:334
+msgid "Receiving game names from the meta server.\n"
+msgstr "De metaserver stuurt de spelnamen door.\n"
+
+#: client/gtk/connect.c:382
+#, c-format
+msgid "New game server requested on %s port %s\n"
+msgstr "Er is een nieuwe server gestart op %s, poort %s.\n"
+
+#: client/gtk/connect.c:391 server/meta.c:168
+#, c-format
+msgid "Unknown message from the metaserver: %s\n"
+msgstr "Onbekende gegevens ontvangen van de metaserver: %s\n"
+
+#: client/gtk/connect.c:472 server/meta.c:125
+msgid "Too many meta-server redirects\n"
+msgstr "Teveel metaserver omleidingen.\n"
+
+#: client/gtk/connect.c:499 server/meta.c:140
+#, c-format
+msgid "Bad redirect line: %s\n"
+msgstr "Foute omleiding: %s\n"
+
+#: client/gtk/connect.c:525
+#, c-format
+msgid "Meta server too old to create servers (version %d.%d)\n"
+msgstr "De metaserver is te oud om servers te starten (versie %d.%d)\n"
+
+#. Sevens rule: normal
+#: client/gtk/connect.c:596 client/gtk/settingscreen.c:168
+#: common/gtk/game-rules.c:81
+msgid "Normal"
+msgstr "Normaal"
+
+#: client/gtk/connect.c:602 client/gtk/settingscreen.c:170
+#: common/gtk/game-rules.c:88
+msgid "Reroll on 1st 2 turns"
+msgstr "Rol de eerste 2 beurten opnieuw"
+
+#: client/gtk/connect.c:605 client/gtk/settingscreen.c:172
+#: common/gtk/game-rules.c:95
+msgid "Reroll all 7s"
+msgstr "Rol alle zevens opnieuw"
+
+#: client/gtk/connect.c:619
+msgid "Default"
+msgstr "Standaard"
+
+#: client/gtk/connect.c:622
+msgid "Random"
+msgstr "Willekeurig"
+
+#: client/gtk/connect.c:653 server/meta.c:188
+#, c-format
+msgid "Redirected to meta-server at %s, port %s\n"
+msgstr "We worden doorgestuurd naar de metaserver op %s, poort %s.\n"
+
+#: client/gtk/connect.c:656
+msgid "Receiving a list of Pioneers servers from the meta server.\n"
+msgstr "De metaserver stuurt een lijst Pioniers servers.\n"
+
+#: client/gtk/connect.c:713
+msgid ""
+"<b>Note</b>:\n"
+"\tThe metaserver does not send information about the games.\n"
+"\tPlease set appropriate values yourself."
+msgstr ""
+"<b>Opmerkingen</b>:\n"
+"\tDe metaserver verstrekt geen informatie over de spellen.\n"
+"\tKies zelf geschikte instellingen."
+
+#: client/gtk/connect.c:730
+msgid "Number of AI Players"
+msgstr "Aantal computerspelers"
+
+#: client/gtk/connect.c:749
+msgid "The number of AI players"
+msgstr "Aantal computerspelers"
+
+#: client/gtk/connect.c:770
+msgid "Requesting new game server\n"
+msgstr "Een nieuwe server wordt aangevraagd.\n"
+
+#: client/gtk/connect.c:813 server/gtk/main.c:328 server/server.c:160
+#, c-format
+msgid "Error starting %s: %s"
+msgstr "Fout bij het starten van %s: %s"
+
+#: client/gtk/connect.c:834
+msgid "Create a public game"
+msgstr "Maak een nieuw openbaar spel"
+
+#: client/gtk/connect.c:965 client/gtk/connect.c:1268
+msgid "Join a public game"
+msgstr "Meedoen aan een openbaar spel"
+
+#: client/gtk/connect.c:970
+msgid "_New remote game"
+msgstr "_Nieuw spel via metaserver"
+
+#: client/gtk/connect.c:984
+msgid "Refresh the list of games"
+msgstr "Ververs de lijst met spellen"
+
+#: client/gtk/connect.c:989
+msgid "Create a new public game at the meta server"
+msgstr "Start een nieuw spel bij de metaserver"
+
+#: client/gtk/connect.c:994
+msgid "Don't join a public game"
+msgstr "Niet meedoen"
+
+#: client/gtk/connect.c:998
+msgid "Join the selected game"
+msgstr "Doe mee met het geselecteerde spel"
+
+#: client/gtk/connect.c:1033
+msgid "Select a game to join"
+msgstr "Kies een spel om aan mee te doen"
+
+#: client/gtk/connect.c:1036
+msgid "Map Name"
+msgstr "Naam"
+
+#: client/gtk/connect.c:1044
+msgid "Name of the game"
+msgstr "Naam van het spel"
+
+#: client/gtk/connect.c:1049
+msgid "Curr"
+msgstr "Huidig"
+
+#: client/gtk/connect.c:1055
+msgid "Number of players in the game"
+msgstr "Aantal spelers"
+
+#: client/gtk/connect.c:1060
+msgid "Max"
+msgstr "Max"
+
+#: client/gtk/connect.c:1066
+msgid "Maximum players for the game"
+msgstr "Maximum aantal spelers voor dit spel"
+
+#: client/gtk/connect.c:1069
+msgid "Terrain"
+msgstr "Terrein"
+
+#: client/gtk/connect.c:1076
+msgid "Random of default terrain"
+msgstr "Willekeurig of standaard terrein"
+
+#: client/gtk/connect.c:1081
+msgid "Vic. Points"
+msgstr "Punten"
+
+#: client/gtk/connect.c:1087
+msgid "Points needed to win"
+msgstr "Het aantal benodigde punten om te winnen"
+
+#: client/gtk/connect.c:1090 common/gtk/game-rules.c:73
+msgid "Sevens Rule"
+msgstr "Regel voor zevens"
+
+#: client/gtk/connect.c:1096
+msgid "Sevens rule"
+msgstr "Regel voor zevens"
+
+#: client/gtk/connect.c:1100
+msgid "Host"
+msgstr "Computer"
+
+#: client/gtk/connect.c:1108
+msgid "Host of the game"
+msgstr "Spel server"
+
+#: client/gtk/connect.c:1113
+msgid "Port"
+msgstr "Poort"
+
+#: client/gtk/connect.c:1119
+msgid "Port of the the game"
+msgstr "Poort van het spel"
+
+#: client/gtk/connect.c:1122 common/gtk/aboutbox.c:77
+msgid "Version"
+msgstr "Versie"
+
+#: client/gtk/connect.c:1129
+msgid "Version of the host"
+msgstr "Versie van de server"
+
+#: client/gtk/connect.c:1184 client/gtk/gui.c:215
+msgid "Start a new game"
+msgstr "Start een nieuw spel"
+
+#: client/gtk/connect.c:1209
+msgid "Player Name"
+msgstr "Naam"
+
+#: client/gtk/connect.c:1223
+msgid "Enter your name"
+msgstr "Geef je naam"
+
+#. Role of the player: viewer
+#: client/gtk/connect.c:1225 server/gtk/main.c:511
+msgid "Viewer"
+msgstr "Toeschouwer"
+
+#: client/gtk/connect.c:1233
+msgid "Do you want to be a viewer?"
+msgstr "Meespelen als toeschouwer"
+
+#: client/gtk/connect.c:1240 server/gtk/main.c:640
+msgid "Meta Server"
+msgstr "Metaserver"
+
+#: client/gtk/connect.c:1255
+msgid "Leave empty for the default meta server"
+msgstr "Laat leeg om de standaard metaserver te gebruiken"
+
+#: client/gtk/connect.c:1263
+msgid "Join public game"
+msgstr "Meespelen met openbaar spel"
+
+#: client/gtk/connect.c:1272
+msgid "Create game"
+msgstr "Maak nieuw spel"
+
+#: client/gtk/connect.c:1275
+msgid "Create a game"
+msgstr "Maak een nieuw spel"
+
+#: client/gtk/connect.c:1285
+msgid "Join private game"
+msgstr "Privé spel"
+
+#: client/gtk/connect.c:1289 client/gtk/connect.c:1434
+msgid "Join a private game"
+msgstr "Meedoen aan een privé spel"
+
+#: client/gtk/connect.c:1475
+msgid "Name of the host of the game"
+msgstr "Naam van de server van het spel"
+
+#: client/gtk/connect.c:1494
+msgid "Port of the host of the game"
+msgstr "Poort van de spel server"
+
+#: client/gtk/connect.c:1534
+msgid "Recent games"
+msgstr "Recente spellen"
+
+#: client/gtk/connect.c:1536
+msgid "Recent Games"
+msgstr "Recente spellen"
+
+#: client/gtk/develop.c:129
+msgid "<b>Development Cards</b>"
+msgstr "<b>Ontwikkelingskaarten</b>"
+
+#: client/gtk/develop.c:160
+msgid "Play Card"
+msgstr "Speel kaart"
+
+#: client/gtk/discard.c:76
+msgid "Discard resources"
+msgstr "Gooi grondstoffen weg"
+
+#: client/gtk/discard.c:96
+#, c-format
+msgid "You must discard %d resources"
+msgstr "Je moet %d grondstofkaarten weggooien"
+
+#: client/gtk/discard.c:101
+msgid "Total discards"
+msgstr "Totaal"
+
+#. Caption for list of player that must discard cards
+#: client/gtk/discard.c:226
+msgid "<b>Waiting for players to discard</b>"
+msgstr "<b>Wacht op spelers die kaarten weggooien</b>"
+
+#: client/gtk/gameover.c:32
+msgid "Game over"
+msgstr "Het spel is afgelopen"
+
+#: client/gtk/gameover.c:49
+#, c-format
+msgid "%s has won the game with %d victory points!"
+msgstr "%s heeft gewonnen met %d punten!"
+
+#: client/gtk/gameover.c:52
+#, c-format
+msgid "%s has won the game with %d victory points!\n"
+msgstr "%s heeft gewonnen met %d punten!\n"
+
+#: client/gtk/gameover.c:58
+#, c-format
+msgid "All praise %s, Lord of the known world!"
+msgstr "Buig voor %s, heerser van de bekende wereld!"
+
+#: client/gtk/gold.c:71
+msgid "Choose resources"
+msgstr "Kies grondstoffen"
+
+#: client/gtk/gold.c:92
+#, c-format
+msgid "You may choose 1 resource"
+msgstr "Je mag 1 grondstofkaart kiezen"
+
+#: client/gtk/gold.c:94
+#, c-format
+msgid "You may choose %d resources"
+msgstr "Je mag %d grondstofkaarten kiezen"
+
+#. Text for total in choose gold dialog
+#. Text for total in year of plenty dialog
+#: client/gtk/gold.c:101 client/gtk/plenty.c:98
+msgid "Total resources"
+msgstr "Totaal"
+
+#: client/gtk/gold.c:213
+msgid "<b>Waiting for players to choose</b>"
+msgstr "<b>Wacht op anderen om grondstoffen te kiezen</b>"
+
+#: client/gtk/gui.c:213 server/gtk/main.c:98
+msgid "_Game"
+msgstr "_Spel"
+
+#: client/gtk/gui.c:214
+msgid "_New game"
+msgstr "_Nieuw spel"
+
+#: client/gtk/gui.c:216
+msgid "_Leave game"
+msgstr "Ver_laat spel"
+
+#: client/gtk/gui.c:217
+msgid "Leave this game"
+msgstr "Verlaat het spel"
+
+#: client/gtk/gui.c:219
+msgid "_Admin"
+msgstr "_Administratie"
+
+#: client/gtk/gui.c:220
+msgid "Administer Pioneers server"
+msgstr "Administreer een Pioniers server"
+
+#: client/gtk/gui.c:222
+msgid "_Player name"
+msgstr "Verander naam"
+
+#: client/gtk/gui.c:223
+msgid "Change your player name"
+msgstr "Verander de naam van je speler"
+
+#: client/gtk/gui.c:224
+msgid "_Legend"
+msgstr "_Legenda"
+
+#: client/gtk/gui.c:225
+msgid "Terrain legend and building costs"
+msgstr "Terreinlegenda en bouwkosten"
+
+#: client/gtk/gui.c:226
+msgid "_Game Settings"
+msgstr "_Spelinstellingen"
+
+#: client/gtk/gui.c:227
+msgid "Settings for the current game"
+msgstr "Instellingen van het lopende spel"
+
+#: client/gtk/gui.c:228
+msgid "_Dice Histogram"
+msgstr "_Dobbelsteen histogram"
+
+#: client/gtk/gui.c:229
+msgid "Histogram of dice rolls"
+msgstr "Histogram van de dobbelsteen tot nu toe"
+
+#: client/gtk/gui.c:230 editor/gtk/editor.c:1018 server/gtk/main.c:103
+msgid "_Quit"
+msgstr "_Afsluiten"
+
+#: client/gtk/gui.c:231 server/gtk/main.c:104
+msgid "Quit the program"
+msgstr "Sluit het programma af"
+
+#: client/gtk/gui.c:232
+msgid "_Actions"
+msgstr "H_andelingen"
+
+#: client/gtk/gui.c:233
+msgid "Roll Dice"
+msgstr "Rol"
+
+#: client/gtk/gui.c:234
+msgid "Roll the dice"
+msgstr "Rol de dobbelstenen"
+
+#. Tab page name
+#: client/gtk/gui.c:235 client/gtk/gui.c:577
+msgid "Trade"
+msgstr "Handel"
+
+#: client/gtk/gui.c:237
+msgid "Undo"
+msgstr "Herstel"
+
+#: client/gtk/gui.c:238 client/gtk/gui.c:239
+msgid "Finish"
+msgstr "Klaar"
+
+#: client/gtk/gui.c:240 client/gtk/legend.c:226 editor/gtk/game-buildings.c:13
+msgid "Road"
+msgstr "Weg"
+
+#: client/gtk/gui.c:241
+msgid "Build a road"
+msgstr "Bouw een weg"
+
+#: client/gtk/gui.c:242 client/gtk/legend.c:230 editor/gtk/game-buildings.c:13
+msgid "Ship"
+msgstr "Schip"
+
+#: client/gtk/gui.c:243
+msgid "Build a ship"
+msgstr "Bouw een schip"
+
+#: client/gtk/gui.c:244
+msgid "Move Ship"
+msgstr "Verplaats schip"
+
+#: client/gtk/gui.c:245
+msgid "Move a ship"
+msgstr "Vaar met een schip"
+
+#: client/gtk/gui.c:246 client/gtk/legend.c:233 editor/gtk/game-buildings.c:13
+msgid "Bridge"
+msgstr "Brug"
+
+#: client/gtk/gui.c:247
+msgid "Build a bridge"
+msgstr "Bouw een brug"
+
+#: client/gtk/gui.c:248 client/gtk/legend.c:235 client/gtk/player.c:52
+#: editor/gtk/game-buildings.c:13
+msgid "Settlement"
+msgstr "Dorp"
+
+#: client/gtk/gui.c:249
+msgid "Build a settlement"
+msgstr "Bouw een dorp"
+
+#: client/gtk/gui.c:250 client/gtk/legend.c:236 client/gtk/player.c:53
+#: editor/gtk/game-buildings.c:14
+msgid "City"
+msgstr "Stad"
+
+#: client/gtk/gui.c:251
+msgid "Build a city"
+msgstr "Bouw een stad"
+
+#: client/gtk/gui.c:252
+msgid "Develop"
+msgstr "Ontwikkelingskaart"
+
+#: client/gtk/gui.c:253
+msgid "Buy a development card"
+msgstr "Koop een ontwikkelingskaart"
+
+#: client/gtk/gui.c:254 client/gtk/legend.c:240 client/gtk/player.c:54
+#: editor/gtk/game-buildings.c:14
+msgid "City Wall"
+msgstr "Stadsmuur"
+
+#: client/gtk/gui.c:255
+msgid "Build a city wall"
+msgstr "Bouw een stadsmuur"
+
+#: client/gtk/gui.c:257
+msgid "_Settings"
+msgstr "_Instellingen"
+
+#: client/gtk/gui.c:258
+msgid "Prefere_nces"
+msgstr "_Voorkeuren"
+
+#: client/gtk/gui.c:259
+msgid "Configure the application"
+msgstr "Verander de instellingen van het programma"
+
+#: client/gtk/gui.c:261 client/gtk/gui.c:265 editor/gtk/editor.c:1002
+#: server/gtk/main.c:99
+msgid "_Help"
+msgstr "_Help"
+
+#: client/gtk/gui.c:262
+msgid "_About Pioneers"
+msgstr "_Over Pioniers"
+
+#: client/gtk/gui.c:263
+msgid "Information about Pioneers"
+msgstr "Informatie over Pioniers"
+
+#: client/gtk/gui.c:266 client/gtk/gui.c:1065
+msgid "Show the manual"
+msgstr "Toon de handleiding"
+
+#: client/gtk/gui.c:272
+msgid "_Toolbar"
+msgstr "_Knoppenbalk"
+
+#: client/gtk/gui.c:273
+msgid "Show or hide the toolbar"
+msgstr "Toon of verberg de knoppenbalk"
+
+#. Victory points target in statusbar
+#: client/gtk/gui.c:368
+#, c-format
+msgid "Points Needed to Win: %i"
+msgstr "De speler met %i punten wint"
+
+#: client/gtk/gui.c:454
+msgid "<b>Messages</b>"
+msgstr "<b>Berichten</b>"
+
+#. Tab page name
+#: client/gtk/gui.c:571 editor/gtk/editor.c:1165
+msgid "Map"
+msgstr "Kaart"
+
+#. Tab page name
+#: client/gtk/gui.c:585 client/gtk/quote.c:306
+msgid "Quote"
+msgstr "Handelsaanbod"
+
+#. Tab page name
+#: client/gtk/gui.c:593 client/gtk/legend.c:261
+msgid "Legend"
+msgstr "Legenda"
+
+#. Tab page name, shown for the splash screen
+#: client/gtk/gui.c:603
+msgid "Welcome to Pioneers"
+msgstr "Welkom bij Pioniers"
+
+#: client/gtk/gui.c:868
+msgid "Pioneers Preferences"
+msgstr "Pioniers Voorkeuren"
+
+#. Label for changing the theme, in the preferences dialog
+#: client/gtk/gui.c:898
+msgid "Theme:"
+msgstr "Thema:"
+
+#: client/gtk/gui.c:921
+msgid "Choose one of the themes"
+msgstr "Kies een van de thema's"
+
+#. Label for the option to show the legend
+#: client/gtk/gui.c:925
+msgid "Show legend"
+msgstr "Toon legenda"
+
+#. Tooltip for the option to show the legend
+#: client/gtk/gui.c:935
+msgid "Show the legend as a page beside the map"
+msgstr "Laat legenda zien naast de kaart"
+
+#. Label for the option to display log messages in color
+#: client/gtk/gui.c:940
+msgid "Messages with color"
+msgstr "Berichten in kleur"
+
+#: client/gtk/gui.c:950
+msgid "Show new messages with color"
+msgstr "Toon nieuwe berichten in kleur"
+
+#: client/gtk/gui.c:955
+msgid "Chat in color of player"
+msgstr "Chat in de kleur van de speler"
+
+#: client/gtk/gui.c:966
+msgid "Show new chat messages in the color of the player"
+msgstr "Toon de nieuwe chat in de kleur van de speler"
+
+#. Label for the option to display the summary with colors
+#: client/gtk/gui.c:971
+msgid "Summary with color"
+msgstr "Spelersoverzicht in kleur"
+
+#: client/gtk/gui.c:982
+msgid "Use colors in the player summary"
+msgstr "Gebruik kleur in het spelersoverzicht"
+
+#: client/gtk/gui.c:987
+msgid "Toolbar with shortcuts"
+msgstr "Knoppenbalk met sneltoetsen"
+
+#: client/gtk/gui.c:997
+msgid "Show keyboard shortcuts in the toolbar"
+msgstr "Toon de sneltoetsen in de knoppenbalk"
+
+#: client/gtk/gui.c:1003
+msgid "Announce new players"
+msgstr "Kondig nieuwe spelers aan"
+
+#: client/gtk/gui.c:1014
+msgid "Make a sound when a new player or viewer enters the game"
+msgstr "Maak geluid wanneer een nieuwe speler of toeschouwer het spel betreedt"
+
+#. Label for the option to use the 16:9 layout.
+#: client/gtk/gui.c:1019
+msgid "Use 16:9 layout"
+msgstr "Gebruik 16:9 layout"
+
+#: client/gtk/gui.c:1030
+msgid "Use a 16:9 friendly layout for the window"
+msgstr "Gebruik een 16:9 vriendelijke layout"
+
+#: client/gtk/gui.c:1041
+msgid "The Pioneers Game"
+msgstr "Pioniers"
+
+#. Initial text in status bar
+#: client/gtk/gui.c:1352
+msgid "Welcome to Pioneers!"
+msgstr "Welkom bij Pioniers!"
+
+#. The name of the application
+#: client/gtk/gui.c:1463
+msgid "Pioneers"
+msgstr "Pioniers"
+
+#: client/gtk/histogram.c:252
+msgid "Dice Histogram"
+msgstr "Dobbelsteenhistogram"
+
+#: client/gtk/interface.c:92
+msgid "Ship movement canceled."
+msgstr "Verplaatsen van het schip is geannuleerd."
+
+#: client/gtk/interface.c:100 client/gtk/interface.c:101
+msgid "Select a new location for the ship."
+msgstr "Selecteer een nieuwe plek voor het schip."
+
+#: client/gtk/interface.c:740
+msgid "Select the ship to steal from"
+msgstr "Kies een schip om te bestelen"
+
+#: client/gtk/interface.c:750
+msgid "Select the building to steal from"
+msgstr "Kies een gebouw om te bestelen"
+
+#: client/gtk/legend.c:32
+msgid "Hill"
+msgstr "Heuvels"
+
+#: client/gtk/legend.c:33
+msgid "Field"
+msgstr "Akker"
+
+#: client/gtk/legend.c:34
+msgid "Mountain"
+msgstr "Berg"
+
+#: client/gtk/legend.c:35
+msgid "Pasture"
+msgstr "Weide"
+
+#: client/gtk/legend.c:36
+msgid "Forest"
+msgstr "Bos"
+
+#: client/gtk/legend.c:37
+msgid "Desert"
+msgstr "Woestijn"
+
+#: client/gtk/legend.c:38
+msgid "Sea"
+msgstr "Zee"
+
+#: client/gtk/legend.c:170
+msgid "<b>Terrain Yield</b>"
+msgstr "<b>Terreinopbrengsten</b>"
+
+#: client/gtk/legend.c:202
+msgid "<b>Building Costs</b>"
+msgstr "<b>Bouwkosten</b>"
+
+#: client/gtk/legend.c:243
+msgid "Development Card"
+msgstr "Ontwikkelingskaart"
+
+#: client/gtk/monopoly.c:105
+msgid "Select the resource you wish to monopolise."
+msgstr "Kies de grondstof waar je een monopolie op wilt."
+
+#: client/gtk/name.c:123
+msgid "Change player name"
+msgstr "Verander naam"
+
+#: client/gtk/name.c:146
+msgid "Player Name:"
+msgstr "Naam:"
+
+#. Set icon preferences
+#: client/gtk/name.c:202
+msgid "Face:"
+msgstr "Gezicht:"
+
+#: client/gtk/name.c:217
+msgid "Variant:"
+msgstr "Variant:"
+
+#. Commandline option of client: name of the player
+#: client/gtk/offline.c:59
+msgid "Player name"
+msgstr "Speler naam"
+
+#: client/gtk/offline.c:63
+msgid "Connect as a viewer"
+msgstr "Meespelen as toeschouwer"
+
+#: client/gtk/offline.c:66
+msgid "Meta-server Host"
+msgstr "Computernaam van de metaserver"
+
+#: client/gtk/offline.c:70
+msgid "Override the language of the system"
+msgstr "Taalinstelling van het systeem teniet doen"
+
+#: client/gtk/offline.c:100
+msgid "Connecting"
+msgstr "Bezig verbinding te maken"
+
+#. Long description in the commandline for pioneers: help
+#: client/gtk/offline.c:175
+msgid "- Play a game of Pioneers"
+msgstr "- Speel een spel Pioniers"
+
+#: client/gtk/player.c:52
+msgid "Settlements"
+msgstr "Dorpen"
+
+#: client/gtk/player.c:53
+msgid "Cities"
+msgstr "Steden"
+
+#: client/gtk/player.c:54
+msgid "City Walls"
+msgstr "Stadsmuren"
+
+#: client/gtk/player.c:55
+msgid "Largest Army"
+msgstr "Grootste riddermacht"
+
+#: client/gtk/player.c:56
+msgid "Longest Road"
+msgstr "Langste handelsroute"
+
+#: client/gtk/player.c:57
+msgid "Chapels"
+msgstr "Kapellen"
+
+#: client/gtk/player.c:58
+msgid "Pioneer Universities"
+msgstr "Pioniers universiteiten"
+
+#: client/gtk/player.c:60
+msgid "Governor's Houses"
+msgstr "Gouverneurshuizen"
+
+#: client/gtk/player.c:61
+msgid "Libraries"
+msgstr "Bibliotheken"
+
+#: client/gtk/player.c:62
+msgid "Markets"
+msgstr "Markten"
+
+#: client/gtk/player.c:63
+msgid "Soldiers"
+msgstr "Ridders"
+
+#: client/gtk/player.c:64
+msgid "Resource card"
+msgstr "Grondstoffenkaart"
+
+#: client/gtk/player.c:64
+msgid "Resource cards"
+msgstr "Grondstoffenkaarten"
+
+#: client/gtk/player.c:65
+msgid "Development card"
+msgstr "Ontwikkelingskaart"
+
+#: client/gtk/player.c:65
+msgid "Development cards"
+msgstr "Ontwikkelingskaarten"
+
+#. Caption for the overview of the points and card of other players
+#: client/gtk/player.c:561
+msgid "<b>Player Summary</b>"
+msgstr "<b>Speleroverzicht</b>"
+
+#: client/gtk/plenty.c:87
+msgid "Please choose one resource from the bank"
+msgstr "Kies een grondstof uit de bank"
+
+#: client/gtk/plenty.c:90
+msgid "Please choose two resources from the bank"
+msgstr "Kies twee grondstoffen uit de bank"
+
+#: client/gtk/plenty.c:92
+msgid "The bank is empty"
+msgstr "De bank is leeg"
+
+#: client/gtk/quote.c:186
+#, c-format
+msgid "%s has %s, and is looking for %s"
+msgstr "%s heeft %s en zoekt %s"
+
+#: client/gtk/quote.c:287
+msgid "I Want"
+msgstr "Ik wil"
+
+#: client/gtk/quote.c:295
+msgid "Give Them"
+msgstr "Ik geef"
+
+#: client/gtk/quote.c:311
+msgid "Delete"
+msgstr "Intrekken"
+
+#: client/gtk/quote.c:335
+msgid "Reject Domestic Trade"
+msgstr "Handel afwijzen"
+
+#. Now create columns
+#. Table header: Player who trades
+#. Role of the player: player
+#: client/gtk/quote-view.c:170 server/gtk/main.c:513
+msgid "Player"
+msgstr "Speler"
+
+#. Table header: Quote
+#: client/gtk/quote-view.c:185
+msgid "Quotes"
+msgstr "Handelsaanbod"
+
+#. trade: maritime quote: %1 resources of type %2 for
+#. * one resource of type %3
+#: client/gtk/quote-view.c:292
+#, c-format
+msgid "%d:1 %s for %s"
+msgstr "%d:1 %s in ruil voor %s"
+
+#. Trade: a player has rejected trade
+#: client/gtk/quote-view.c:431
+msgid "Rejected trade"
+msgstr "Handel afgewezen"
+
+#. Caption for overview of the resources of the player
+#: client/gtk/resource.c:113
+msgid "<b>Resources</b>"
+msgstr "<b>Grondstoffen</b>"
+
+#: client/gtk/resource.c:129
+msgid "Total"
+msgstr "Totaal"
+
+#. Tooltip for the amount of resources in the hand
+#: client/gtk/resource-table.c:187
+msgid "Amount in hand"
+msgstr "Aantal in de hand"
+
+#: client/gtk/resource-table.c:191
+msgid "<less"
+msgstr "<minder"
+
+#. Tooltip for decreasing the selected amount
+#: client/gtk/resource-table.c:201
+msgid "Decrease the selected amount"
+msgstr "Verlaag het aantal van deze grondstof"
+
+#. Tooltip for the amount of resources in the bank
+#: client/gtk/resource-table.c:215
+msgid "Amount in the bank"
+msgstr "Aantal in de bank"
+
+#: client/gtk/resource-table.c:219
+msgid "more>"
+msgstr "meer>"
+
+#. Tooltip for increasing the selected amount
+#: client/gtk/resource-table.c:231
+msgid "Increase the selected amount"
+msgstr "Verhoog het aantal van deze grondstof"
+
+#. Tooltip for the selected amount
+#: client/gtk/resource-table.c:248
+msgid "Selected amount"
+msgstr "Aantal gekozen grondstoffen"
+
+#. Tooltip for the total selected amount
+#: client/gtk/resource-table.c:293
+msgid "Total selected amount"
+msgstr "Totaal aantal gekozen grondstoffen"
+
+#: client/gtk/resource-table.c:314
+msgid "The bank cannot be emptied"
+msgstr "De bank kan niet leeg gemaakt worden"
+
+#: client/gtk/settingscreen.c:74
+msgid "Yes"
+msgstr "Ja"
+
+#: client/gtk/settingscreen.c:76 client/gtk/settingscreen.c:207
+msgid "No"
+msgstr "Nee"
+
+#: client/gtk/settingscreen.c:87 client/gtk/settingscreen.c:174
+msgid "Unknown"
+msgstr "Onbekend"
+
+#: client/gtk/settingscreen.c:121
+msgid "No game in progress..."
+msgstr "Er is geen spel bezig."
+
+#: client/gtk/settingscreen.c:131
+msgid "<b>General Settings</b>"
+msgstr "<b>Algemene instellingen</b>"
+
+#: client/gtk/settingscreen.c:147
+msgid "Number of players:"
+msgstr "Aantal spelers:"
+
+#: client/gtk/settingscreen.c:150
+msgid "Victory Point Target:"
+msgstr "Punten benodigd om te winnen:"
+
+#: client/gtk/settingscreen.c:153
+msgid "Random Terrain?"
+msgstr "Willekeurig terrein?"
+
+#: client/gtk/settingscreen.c:156
+msgid "Interplayer Trading Allowed?"
+msgstr "Handel tussen spelers toegestaan?"
+
+#: client/gtk/settingscreen.c:160
+msgid "Trading allowed only before build/buy?"
+msgstr "Handelen alleen toegestaan voor het bouwen?"
+
+#: client/gtk/settingscreen.c:163
+msgid "Amount of Each Resource:"
+msgstr "Aantal grondstofkaarten van elke soort:"
+
+#: client/gtk/settingscreen.c:177
+msgid "Sevens Rule:"
+msgstr "Zevensregel:"
+
+#: client/gtk/settingscreen.c:181
+msgid "Use Pirate:"
+msgstr "Gebruik piraat:"
+
+#: client/gtk/settingscreen.c:209
+msgid "Island Discovery Bonuses:"
+msgstr "Eiland ontdekkingspunten:"
+
+#: client/gtk/settingscreen.c:224
+msgid "<b>Building Quotas</b>"
+msgstr "<b>Bouwbeperkingen</b>"
+
+#: client/gtk/settingscreen.c:241
+msgid "Roads:"
+msgstr "Straten:"
+
+#: client/gtk/settingscreen.c:247
+msgid "Settlements:"
+msgstr "Dorpen:"
+
+#: client/gtk/settingscreen.c:253
+msgid "Cities:"
+msgstr "Steden:"
+
+#: client/gtk/settingscreen.c:259
+msgid "City Walls:"
+msgstr "Stadsmuren:"
+
+#: client/gtk/settingscreen.c:265
+msgid "Ships:"
+msgstr "Schepen:"
+
+#: client/gtk/settingscreen.c:271
+msgid "Bridges:"
+msgstr "Bruggen:"
+
+#: client/gtk/settingscreen.c:283
+msgid "<b>Development Card Deck</b>"
+msgstr "<b>Ontwikkelingskaarten</b>"
+
+#: client/gtk/settingscreen.c:299
+msgid "Road Building Cards:"
+msgstr "Stratenbouw:"
+
+#: client/gtk/settingscreen.c:303
+msgid "Monopoly Cards:"
+msgstr "Monopolie:"
+
+#: client/gtk/settingscreen.c:307
+msgid "Year of Plenty Cards:"
+msgstr "Goed jaar:"
+
+#: client/gtk/settingscreen.c:312
+msgid "Chapel Cards:"
+msgstr "Kapel:"
+
+#: client/gtk/settingscreen.c:316
+msgid "Pioneer University Cards:"
+msgstr "Universiteit kaarten:"
+
+#: client/gtk/settingscreen.c:320
+msgid "Governor's House Cards:"
+msgstr "Gouverneurshuis:"
+
+#: client/gtk/settingscreen.c:325
+msgid "Library Cards:"
+msgstr "Bibliotheek:"
+
+#: client/gtk/settingscreen.c:329
+msgid "Market Cards:"
+msgstr "Markt:"
+
+#: client/gtk/settingscreen.c:333
+msgid "Soldier Cards:"
+msgstr "Ridder:"
+
+#: client/gtk/settingscreen.c:370
+msgid "Current Game Settings"
+msgstr "Huidige spelinstellingen"
+
+#. trade: you ask for something for free
+#: client/gtk/trade.c:193
+#, c-format
+msgid "ask for %s for free"
+msgstr "Vraag om gratis %s"
+
+#. trade: you give something away for free
+#: client/gtk/trade.c:198
+#, c-format
+msgid "give %s for free"
+msgstr "Geef gratis %s"
+
+#. trade: you trade something for something else
+#: client/gtk/trade.c:203
+#, c-format
+msgid "give %s for %s"
+msgstr "Geef %s in ruil voor %s"
+
+#. I want some resources, and give them some resources
+#: client/gtk/trade.c:230
+#, c-format
+msgid "I want %s, and give them %s"
+msgstr "Ik vraag %s en bied %s"
+
+#. Frame title, trade: I want to trade these resources
+#: client/gtk/trade.c:427
+msgid "<b>I Want</b>"
+msgstr "<b>Ik wil</b>"
+
+#. Frame title, trade: I want these resources in return
+#: client/gtk/trade.c:455
+msgid "<b>Give Them</b>"
+msgstr "<b>Ik geef</b>"
+
+#. Button text, trade: call for quotes from other players
+#: client/gtk/trade.c:484
+msgid "_Call for Quotes"
+msgstr "Vraag om voorstellen"
+
+#. Button text: Trade page, accept selected quote
+#: client/gtk/trade.c:512
+msgid "_Accept Quote"
+msgstr "Accepteer voorstel"
+
+#. Button text: Trade page, finish trading
+#: client/gtk/trade.c:518
+msgid "_Finish Trading"
+msgstr "Beëindig handelsfase"
+
+#: common/gtk/aboutbox.c:74
+msgid ""
+"Pioneers is based upon the excellent\n"
+"Settlers of Catan board game.\n"
+msgstr ""
+"Pioniers is gebaseerd op\n"
+"het bordspel \"de kolonisten van Catan\".\n"
+
+#: common/gtk/aboutbox.c:83
+msgid "Homepage"
+msgstr "Homepage"
+
+#: common/gtk/aboutbox.c:88
+msgid "Authors"
+msgstr "Geschreven door"
+
+#. Tooltip for sevens rule normal
+#: common/gtk/game-rules.c:101
+msgid "All sevens move the robber or pirate"
+msgstr "Bij een zeven wordt de rover of piraat verplaatst"
+
+#: common/gtk/game-rules.c:106
+msgid "In the first two turns all sevens are rerolled"
+msgstr "In de eerste twee beurten worden zevens opnieuw gerold"
+
+#. Tooltip for sevens rule reroll all
+#: common/gtk/game-rules.c:110
+msgid "All sevens are rerolled"
+msgstr "Alle zevens worden opnieuw gerold"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize Terrain"
+msgstr "Willekeurig terrein"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize the terrain"
+msgstr "Willekeurig terrein maken"
+
+#: common/gtk/game-rules.c:123
+msgid "Use Pirate"
+msgstr "Gebruik piraat"
+
+#: common/gtk/game-rules.c:123
+msgid "Use the pirate to block ships"
+msgstr "Gebruik de piraat om schepen te blokkeren"
+
+#: common/gtk/game-rules.c:125
+msgid "Strict Trade"
+msgstr "Handel voor bouwen"
+
+#: common/gtk/game-rules.c:126
+msgid "Allow trade only before building or buying"
+msgstr "Handelen alleen toegestaan voor het bouwen"
+
+#: common/gtk/game-rules.c:128
+msgid "Domestic Trade"
+msgstr "Handel tussen spelers"
+
+#: common/gtk/game-rules.c:128
+msgid "Allow trade between players"
+msgstr "Sta handel tussen spelers toe"
+
+#. Label text for customising a game
+#: common/gtk/game-settings.c:118
+msgid "Number of Players"
+msgstr "Aantal spelers"
+
+#. Tooltip for 'Number of Players'
+#: common/gtk/game-settings.c:136
+msgid "The number of players"
+msgstr "Het aantal spelers"
+
+#. Label for customising a game
+#: common/gtk/game-settings.c:139
+msgid "Victory Point Target"
+msgstr "Aantal winstpunten"
+
+#. Tooltip for Victory Point Target
+#: common/gtk/game-settings.c:159
+msgid "The points needed to win the game"
+msgstr "Het aantal benodigde punten om te winnen"
+
+#. Tooltip for the check button
+#: common/gtk/game-settings.c:172
+msgid "Is it possible to win this game?"
+msgstr "Is het mogelijk dit spel te winnen?"
+
+#. Port indicator for a resource: trade 2 for 1
+#: common/gtk/guimap.c:750
+msgid "2:1"
+msgstr "2:1"
+
+#. Port indicator: trade 3 for 1
+#. General port indicator
+#: common/gtk/guimap.c:753 common/gtk/guimap.c:778
+msgid "3:1"
+msgstr "3:1"
+
+#. Tooltip for the list of games
+#: common/gtk/select-game.c:111
+msgid "Select a game"
+msgstr "Kies een spel"
+
+#: common/gtk/theme.c:709
+#, c-format
+msgid "bad scaling mode '%s'"
+msgstr "Ongeldig schaaltype \"%s\""
+
+#: common/game.c:603 common/game.c:633
+msgid "This game cannot be won."
+msgstr "Dit spel kan niet gewonnen worden."
+
+#: common/game.c:604
+msgid "There is no land."
+msgstr "Er is geen land."
+
+#: common/game.c:638
+msgid "It is possible that this game cannot be won."
+msgstr "Het is mogelijk dat dit spel niet gewonnen kan worden."
+
+#: common/game.c:643
+msgid "This game can be won by only building all settlements and cities."
+msgstr ""
+"Dit spel kan gewonnen worden door uitsluitend alle dorpen en steden te "
+"bouwen."
+
+#: common/game.c:650
+#, c-format
+msgid ""
+"Required victory points: %d\n"
+"Points obtained by building all: %d\n"
+"Points in development cards: %d\n"
+"Longest road/largest army: %d+%d\n"
+"Maximum island discovery bonus: %d\n"
+"Total: %d"
+msgstr ""
+"Benodigd aantal overwinningspunten: %d\n"
+"Punten door alles te bouwen: %d\n"
+"Punten in ontwikkelingskaarten: %d\n"
+"Langste weg/grootste leger: %d+%d\n"
+"Hoogste aantal ontdekkingspunten: %d\n"
+"Totaal: %d"
+
+#: common/log.c:54
+msgid "*ERROR* "
+msgstr "*FOUT* "
+
+#: common/log.c:60
+msgid "Chat: "
+msgstr "Praten: "
+
+#: common/log.c:63
+msgid "Resource: "
+msgstr "Grondstof: "
+
+#: common/log.c:66
+msgid "Build: "
+msgstr "Bouwen: "
+
+#: common/log.c:69
+msgid "Dice: "
+msgstr "Dobbelsteen: "
+
+#: common/log.c:72
+msgid "Steal: "
+msgstr "Steel: "
+
+#: common/log.c:75
+msgid "Trade: "
+msgstr "Handel: "
+
+#: common/log.c:78
+msgid "Development: "
+msgstr "Ontwikkelingskaart: "
+
+#: common/log.c:81
+msgid "Army: "
+msgstr "Soldaat: "
+
+#: common/log.c:84
+msgid "Road: "
+msgstr "Straat: "
+
+#: common/log.c:87
+msgid "*BEEP* "
+msgstr "*BEEP* "
+
+#: common/log.c:92
+msgid "Player 1: "
+msgstr "Speler 1: "
+
+#: common/log.c:95
+msgid "Player 2: "
+msgstr "Speler 2: "
+
+#: common/log.c:98
+msgid "Player 3: "
+msgstr "Speler 3: "
+
+#: common/log.c:101
+msgid "Player 4: "
+msgstr "Speler 4: "
+
+#: common/log.c:104
+msgid "Player 5: "
+msgstr "Speler 5: "
+
+#: common/log.c:107
+msgid "Player 6: "
+msgstr "Speler 6: "
+
+#: common/log.c:110
+msgid "Player 7: "
+msgstr "Speler 7: "
+
+#: common/log.c:113
+msgid "Player 8: "
+msgstr "Speler 8: "
+
+#: common/log.c:116
+msgid "Viewer: "
+msgstr "Toeschouwer: "
+
+#: common/log.c:119
+msgid "** UNKNOWN MESSAGE TYPE ** "
+msgstr "** ONBEKEND BERICHTTYPE ** "
+
+#: common/network.c:281
+#, c-format
+msgid "Error checking connect status: %s\n"
+msgstr "Fout bij het controleren van verbinding: %s\n"
+
+#: common/network.c:288
+#, c-format
+msgid "Error connecting to host '%s': %s\n"
+msgstr "Kan geen verbinding maken met computer \"%s\": %s\n"
+
+#: common/network.c:314
+#, c-format
+msgid "Error writing socket: %s\n"
+msgstr "Fout bij het schrijven naar netwerk: %s\n"
+
+#: common/network.c:365
+#, c-format
+msgid "Error writing to socket: %s\n"
+msgstr "Fout bij het schrijven naar netwerk: %s\n"
+
+#: common/network.c:418
+msgid "Read buffer overflow - disconnecting\n"
+msgstr "Leesbuffer is vol - de verbinding wordt verbroken\n"
+
+#: common/network.c:428
+#, c-format
+msgid "Error reading socket: %s\n"
+msgstr "Fout bij het lezen van netwerk: %s\n"
+
+#: common/network.c:575
+#, c-format
+msgid "Cannot resolve %s port %s: %s\n"
+msgstr "Onbekende computer %s (poort %s): %s\n"
+
+#: common/network.c:582
+#, c-format
+msgid "Cannot resolve %s port %s: host not found\n"
+msgstr "Computer %s (poort %s) kan niet gevonden worden\n"
+
+#: common/network.c:597
+#, c-format
+msgid "Error creating socket: %s\n"
+msgstr "Fout bij het maken van een netwerkverbinding: %s\n"
+
+#: common/network.c:605
+#, c-format
+msgid "Error setting socket close-on-exec: %s\n"
+msgstr "Fout bij het instellen van netwerkverbinding op close-on-exec: %s\n"
+
+#: common/network.c:615 common/network.c:776
+#, c-format
+msgid "Error setting socket non-blocking: %s\n"
+msgstr "Fout bij het instellen van netwerkverbinding op non-blocking: %s\n"
+
+#: common/network.c:640
+#, c-format
+msgid "Error connecting to %s: %s\n"
+msgstr "Fout bij het verbinden naar %s: %s\n"
+
+#: common/network.c:735
+#, c-format
+msgid "Error creating struct addrinfo: %s"
+msgstr "Fout bij het maken van struct addrinfo: %s"
+
+#: common/network.c:765
+#, c-format
+msgid "Error creating listening socket: %s\n"
+msgstr "Fout bij het opzetten van de netwerkverbinding: %s\n"
+
+#: common/network.c:785
+#, c-format
+msgid "Error during listen on socket: %s\n"
+msgstr "Fout bij het wachten op verbindingen: %s\n"
+
+#: common/network.c:794
+msgid "Listening not yet supported on this platform."
+msgstr "Luisterende verbindingen nog niet ondersteund op dit platform."
+
+#: common/network.c:816 common/network.c:817
+msgid "unknown"
+msgstr "onbekend"
+
+#: common/network.c:823
+#, c-format
+msgid "Error getting peer name: %s"
+msgstr "Fout bij het opzoeken van de computernaam: %s"
+
+#: common/network.c:836
+#, c-format
+msgid "Error resolving address: %s"
+msgstr "Fout bij het opzoeken van de computernaam: %s"
+
+#: common/network.c:850
+msgid "Net_get_peer_name not yet supported on this platform."
+msgstr "De functie Net_get_peer_name is nog niet ondersteund op dit platform."
+
+#: common/network.c:865
+#, c-format
+msgid "Error accepting connection: %s"
+msgstr "Fout bij het accepteren van een verbinding: %s"
+
+#: common/state.c:166
+#, c-format
+msgid "Connecting to %s, port %s\n"
+msgstr "Bezig te verbinden met %s, poort %s\n"
+
+#: common/state.c:503
+msgid "State stack overflow. Stack dump sent to standard error.\n"
+msgstr ""
+"Toestandsstapel is vol. Toestanden op de stapel gaan naar standard error.\n"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:73
+msgid "_Hill"
+msgstr "_Heuvels"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:75
+msgid "_Field"
+msgstr "_Akker"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:77
+msgid "_Mountain"
+msgstr "_Berg"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:79
+msgid "_Pasture"
+msgstr "_Weide"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:81
+msgid "F_orest"
+msgstr "B_os"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:83
+msgid "_Desert"
+msgstr "Woes_tijn"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:85
+msgid "_Sea"
+msgstr "_Zee"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:87
+msgid "_Gold"
+msgstr "_Goud"
+
+#. Use an unique shortcut key for each resource
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:89 editor/gtk/editor.c:104
+msgid "_None"
+msgstr "Gee_n"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:94
+msgid "_Brick (2:1)"
+msgstr "_Baksteen (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:96
+msgid "_Grain (2:1)"
+msgstr "_Graan (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:98
+msgid "_Ore (2:1)"
+msgstr "_Erts (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:100
+msgid "_Wool (2:1)"
+msgstr "_Wol (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:102
+msgid "_Lumber (2:1)"
+msgstr "_Hout (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:106
+msgid "_Any (3:1)"
+msgstr "Ha_ven (3:1)"
+
+#. East
+#: editor/gtk/editor.c:111
+msgid "East|E"
+msgstr "O"
+
+#. North east
+#: editor/gtk/editor.c:113
+msgid "North East|NE"
+msgstr "NO"
+
+#. North west
+#: editor/gtk/editor.c:115
+msgid "North West|NW"
+msgstr "NW"
+
+#. West
+#: editor/gtk/editor.c:117
+msgid "West|W"
+msgstr "W"
+
+#. South west
+#: editor/gtk/editor.c:119
+msgid "South West|SW"
+msgstr "ZW"
+
+#. South east
+#: editor/gtk/editor.c:121
+msgid "South East|SE"
+msgstr "ZO"
+
+#: editor/gtk/editor.c:564
+msgid "Shuffle"
+msgstr "Schudden"
+
+#: editor/gtk/editor.c:696 server/gtk/main.c:450
+msgid "Game Parameters"
+msgstr "Spelinstellingen"
+
+#: editor/gtk/editor.c:698 server/gtk/main.c:482
+msgid "Rules"
+msgstr "Spelregels"
+
+#: editor/gtk/editor.c:699
+msgid "Resources"
+msgstr "Grondstoffen"
+
+#: editor/gtk/editor.c:700
+msgid "Buildings"
+msgstr "Gebouwen"
+
+#: editor/gtk/editor.c:701
+msgid "Development Cards"
+msgstr "Ontwikkelingskaarten"
+
+#: editor/gtk/editor.c:718
+msgid "Pioneers Editor"
+msgstr "Pioniers Editor"
+
+#: editor/gtk/editor.c:803
+#, c-format
+msgid "Failed to load '%s'"
+msgstr "Kan '%s' niet openen"
+
+#: editor/gtk/editor.c:843
+#, c-format
+msgid "Failed to save to '%s'"
+msgstr "Kan '%s' niet opslaan"
+
+#: editor/gtk/editor.c:858
+msgid "Open Game"
+msgstr "Open spel"
+
+#: editor/gtk/editor.c:884
+msgid "Save as..."
+msgstr "Opslaan als..."
+
+#: editor/gtk/editor.c:919
+msgid "Change Title"
+msgstr "Verander titel"
+
+#: editor/gtk/editor.c:941
+msgid "New Title:"
+msgstr "Nieuwe titel:"
+
+#: editor/gtk/editor.c:997
+msgid "Pioneers Game Editor"
+msgstr "Pioniers Spel Editor"
+
+#: editor/gtk/editor.c:1001
+msgid "_File"
+msgstr "_Bestand"
+
+#: editor/gtk/editor.c:1004
+msgid "_New"
+msgstr "_Nieuw"
+
+#: editor/gtk/editor.c:1005
+msgid "Create a new game"
+msgstr "Maak een nieuw spel"
+
+#: editor/gtk/editor.c:1006
+msgid "_Open..."
+msgstr "_Openen..."
+
+#: editor/gtk/editor.c:1007
+msgid "Open an existing game"
+msgstr "Open een bestaand spel"
+
+#: editor/gtk/editor.c:1008
+msgid "_Save"
+msgstr "Op_slaan"
+
+#: editor/gtk/editor.c:1009
+msgid "Save game"
+msgstr "Sla het spel op"
+
+#: editor/gtk/editor.c:1010
+msgid "Save _As..."
+msgstr "Opslaan _als..."
+
+#: editor/gtk/editor.c:1012
+msgid "Save as"
+msgstr "Sla het spel op onder een andere naam"
+
+#: editor/gtk/editor.c:1013
+msgid "_Change title"
+msgstr "_Verander titel"
+
+#: editor/gtk/editor.c:1014
+msgid "Change game title"
+msgstr "Verander de title van het spel"
+
+#: editor/gtk/editor.c:1015 server/gtk/main.c:100
+msgid "_Check Victory Point Target"
+msgstr "_Controleer winstpunten"
+
+#: editor/gtk/editor.c:1017 server/gtk/main.c:102
+msgid "Check whether the game can be won"
+msgstr "Controleer of het mogelijk is dit spel te winnen"
+
+#: editor/gtk/editor.c:1019
+msgid "Quit"
+msgstr "Sluit het programma af"
+
+#: editor/gtk/editor.c:1027
+msgid "_About Pioneers Editor"
+msgstr "_Over Pioniers Editor"
+
+#: editor/gtk/editor.c:1028
+msgid "Information about Pioneers Editor"
+msgstr "Informatie over Pioniers Editor"
+
+#. Long help for commandline option (editor): filename
+#: editor/gtk/editor.c:1066
+msgid "Open this file"
+msgstr "Open dit bestand"
+
+#. Commandline option for editor: filename
+#: editor/gtk/editor.c:1068
+msgid "filename"
+msgstr "bestandsnaam"
+
+#: editor/gtk/editor.c:1100
+msgid "- Editor for games of Pioneers"
+msgstr "- Editor for spellen Pioniers"
+
+#: editor/gtk/editor.c:1141 server/gtk/main.c:1035
+#, c-format
+msgid "Building menus failed: %s"
+msgstr "Opbouw menu niet gelukt: %s"
+
+#: editor/gtk/editor.c:1169
+msgid "Settings"
+msgstr "Instellingen"
+
+#: editor/gtk/game-resources.c:51
+msgid "Resource Count"
+msgstr "Grondstoffen"
+
+#. Commandline meta-server: daemon
+#: meta-server/main.c:1033
+msgid "Daemonize the metaserver on start"
+msgstr "Start de metaserver als achtergrond taak"
+
+#. Commandline meta-server: redirect
+#: meta-server/main.c:1036
+msgid "Redirect clients to another metaserver"
+msgstr "Omleiding naar een andere metaserver"
+
+#. Commandline meta-server: server
+#: meta-server/main.c:1039
+msgid "Use this hostname when creating new games"
+msgstr "Gebruik deze hostname bij nieuwe spellen"
+
+#. Commandline meta-server: server argument
+#: meta-server/main.c:1041
+msgid "hostname"
+msgstr "hostname"
+
+#. Commandline meta-server: port-range
+#: meta-server/main.c:1044
+msgid "Use this ports range when creating new games"
+msgstr "Gebruik dit bereik voor de poorten van nieuwe spellen"
+
+#. Commandline meta-server: port-range argument
+#: meta-server/main.c:1046
+msgid "from-to"
+msgstr "van-tot"
+
+#. Commandline option of meta server: syslog-debug
+#: meta-server/main.c:1052
+msgid "Debug syslog messages"
+msgstr "Toon debug boodschappen in de syslog"
+
+#. Long description in the commandline for server-console: help
+#: meta-server/main.c:1073
+msgid "- Meta server for Pioneers"
+msgstr "- Metaserver voor Pioniers"
+
+#: meta-server/main.c:1088
+#, c-format
+msgid "metaserver protocol:"
+msgstr "Metaserver protocol:"
+
+#: server/gtk/main.c:105
+msgid "_About Pioneers Server"
+msgstr "_Over Pioniers server"
+
+#: server/gtk/main.c:106
+msgid "Information about Pioneers Server"
+msgstr "Informatie over de Pioniers server"
+
+#: server/gtk/main.c:222
+msgid "Stop server"
+msgstr "Stop server"
+
+#: server/gtk/main.c:223
+msgid "Start server"
+msgstr "Start server"
+
+#: server/gtk/main.c:225
+msgid "Stop the server"
+msgstr "Stop de server"
+
+#: server/gtk/main.c:226
+msgid "Start the server"
+msgstr "Start de server"
+
+#: server/gtk/main.c:351
+#, c-format
+msgid "Player %s from %s entered\n"
+msgstr "Nieuwe speler: %s vanaf %s\n"
+
+#: server/gtk/main.c:358
+#, c-format
+msgid "Player %s from %s left\n"
+msgstr "Speler %s vanaf %s heeft de verbinding verbroken\n"
+
+#: server/gtk/main.c:365
+#, c-format
+msgid "Player %d is now %s\n"
+msgstr "Speler %d is nu %s\n"
+
+#: server/gtk/main.c:554
+msgid "Game Settings"
+msgstr "Spelinstellingen"
+
+#: server/gtk/main.c:600
+msgid "Server Parameters"
+msgstr "Serverinstellingen"
+
+#: server/gtk/main.c:626
+msgid "The port for the game server"
+msgstr "De poort van de server"
+
+#: server/gtk/main.c:629
+msgid "Register Server"
+msgstr "Registreer server"
+
+#: server/gtk/main.c:637
+msgid "Register this game at the meta server"
+msgstr "Registreer dit spel bij de metaserver"
+
+#: server/gtk/main.c:654
+msgid "The address of the meta server"
+msgstr "Het adres van de metaserver"
+
+#: server/gtk/main.c:656
+msgid "Reported Hostname"
+msgstr "Geregistreerde computernaam"
+
+#: server/gtk/main.c:671
+msgid ""
+"The public name of this computer (needed when playing behind a firewall)"
+msgstr ""
+"De naam van deze computer (is nodig om een spel te registreren vanachter een "
+"firewall)"
+
+#: server/gtk/main.c:675
+msgid "Random Turn Order"
+msgstr "Volgorde willekeurig"
+
+#: server/gtk/main.c:683
+msgid "Randomize turn order"
+msgstr "Is de spelervolgorde willekeurig"
+
+#: server/gtk/main.c:722
+msgid "Running Game"
+msgstr "Lopend spel"
+
+#: server/gtk/main.c:724
+msgid "Players Connected"
+msgstr "Huidige spelers"
+
+#: server/gtk/main.c:758
+msgid "Shows all players and viewers connected to the server"
+msgstr "Toont alle verbonden spelers en toeschouwers"
+
+#: server/gtk/main.c:763
+msgid "Connected"
+msgstr "Verbonden"
+
+#: server/gtk/main.c:770
+msgid "Is the player currently connected?"
+msgstr "Is de speler op het moment verbonden?"
+
+#: server/gtk/main.c:773
+msgid "Name"
+msgstr "Naam"
+
+#: server/gtk/main.c:780
+msgid "Name of the player"
+msgstr "Naam van de speler"
+
+#: server/gtk/main.c:782
+msgid "Location"
+msgstr "Computer"
+
+#: server/gtk/main.c:789
+msgid "Host name of the player"
+msgstr "Computernaam van de speler"
+
+#: server/gtk/main.c:793
+msgid "Number"
+msgstr "Nummer"
+
+#: server/gtk/main.c:800
+msgid "Player number"
+msgstr "Speler nummer"
+
+#: server/gtk/main.c:804
+msgid "Role"
+msgstr "Rol"
+
+#: server/gtk/main.c:808
+msgid "Player of viewer"
+msgstr "Speler of toeschouwer"
+
+#: server/gtk/main.c:819
+msgid "Launch Pioneers Client"
+msgstr "Start Pioniers"
+
+#: server/gtk/main.c:826
+msgid "Launch the Pioneers Client"
+msgstr "Start Pioniers"
+
+#: server/gtk/main.c:828
+msgid "Computer Players"
+msgstr "Computer spelers"
+
+#: server/gtk/main.c:837
+msgid "Enable Chat"
+msgstr "Chat mogelijk"
+
+#: server/gtk/main.c:843
+msgid "Enable chat messages"
+msgstr "De computer speler mag chat boodschappen versturen"
+
+#: server/gtk/main.c:850
+msgid "Add Computer Player"
+msgstr "Voeg computerspeler toe"
+
+#: server/gtk/main.c:857
+msgid "Add a computer player to the game"
+msgstr "Voeg computerspeler toe aan het spel"
+
+#: server/gtk/main.c:866
+msgid "Messages"
+msgstr "Berichten"
+
+#: server/gtk/main.c:884
+msgid "Messages from the server"
+msgstr "Berichten van de server"
+
+#: server/gtk/main.c:932
+msgid "The Pioneers Game Server"
+msgstr "De Pioniers server"
+
+#. Wait for all players to disconnect,
+#. * then enable the UI
+#.
+#: server/gtk/main.c:940
+msgid "The game is over.\n"
+msgstr "Het spel is afgelopen.\n"
+
+#. Long description in the commandline for server-gtk: help
+#. Long description in the commandline for server-console: help
+#: server/gtk/main.c:994 server/main.c:174
+msgid "- Host a game of Pioneers"
+msgstr "- Creeer een spel Pioniers"
+
+#. Name in the titlebar of the server
+#: server/gtk/main.c:1016
+msgid "Pioneers Server"
+msgstr "Pioniers Server"
+
+#. Commandline server-console: game-title
+#: server/main.c:75
+msgid "Game title to use"
+msgstr "Titel van het spel"
+
+#. Commandline server-console: file
+#: server/main.c:78
+msgid "Game file to use"
+msgstr "Bestandsnaam van het spel"
+
+#. Commandline server-console: port
+#: server/main.c:81
+msgid "Port to listen on"
+msgstr "Poort"
+
+#. Commandline server-console: players
+#: server/main.c:84
+msgid "Override number of players"
+msgstr "Het aantal spelers"
+
+#. Commandline server-console: points
+#: server/main.c:87
+msgid "Override number of points needed to win"
+msgstr "Het aantal benodigde punten om te winnen"
+
+#. Commandline server-console: seven-rule
+#: server/main.c:90
+msgid "Override seven-rule handling"
+msgstr "Zeven regel"
+
+#. Commandline server-console: terrain
+#: server/main.c:93
+msgid "Override terrain type, 0=default 1=random"
+msgstr "Terrein type, 0=standaard 1=willekeurig"
+
+#. Commandline server-console: computer-players
+#: server/main.c:96
+msgid "Add N computer players"
+msgstr "Voeg N computerspelers toe"
+
+#. Commandline server-console: register
+#: server/main.c:106
+msgid "Register server with meta-server"
+msgstr "Registreer dit spel bij de metaserver"
+
+#. Commandline server-console: meta-server
+#: server/main.c:109
+msgid "Register at meta-server name (implies -r)"
+msgstr "Registreer bij metaserver naam (betekent -r)"
+
+#. Commandline server-console: hostname
+#: server/main.c:113
+msgid "Use this hostname when registering"
+msgstr "Gebruik deze hostname bij registratie"
+
+#. Commandline server-console: auto-quit
+#: server/main.c:120
+msgid "Quit after a player has won"
+msgstr "Stop wanneer het spel gewonnen is"
+
+#. Commandline server-console: empty-timeout
+#: server/main.c:123
+msgid "Quit after N seconds with no players"
+msgstr "Stop wanneer na N seconden geen spelers gekomen zijn"
+
+#. Commandline server-console: tournament
+#: server/main.c:126
+msgid "Tournament mode, computer players added after N minutes"
+msgstr "Toernament modus, computerspelers worden toegevoegd na N minuten"
+
+#. Commandline server-console: admin-port
+#: server/main.c:130
+msgid "Admin port to listen on"
+msgstr "Administratie poort"
+
+#: server/main.c:134
+msgid "Don't start game immediately, wait for a command on admin port"
+msgstr "Start het spel na een commando via de administratie poort"
+
+#: server/main.c:140
+msgid "Give players numbers according to the order they enter the game"
+msgstr "Geef de spelers nummers in de volgorde waarin ze het spel betreden"
+
+#. Commandline server-console: Short description of meta group
+#: server/main.c:180
+msgid "Meta-server Options"
+msgstr "Metaserver opties"
+
+#: server/main.c:183
+msgid "Options for the meta-server"
+msgstr "Opties voor de metaserver"
+
+#. Commandline server-console: Short description of misc group
+#: server/main.c:191
+msgid "Miscellaneous Options"
+msgstr "Diverse opties"
+
+#. Commandline server-console: Long description of misc group
+#: server/main.c:193
+msgid "Miscellaneous options"
+msgstr "Diverse opties"
+
+#: server/meta.c:193
+#, c-format
+msgid "Register with meta-server at %s, port %s\n"
+msgstr "Bezig te verbinden met metaserver op %s, poort %s\n"
+
+#: server/meta.c:210
+msgid "Unregister from meta-server\n"
+msgstr "Verbreek de verbinding met de metaserver\n"
+
+#: server/player.c:130
+msgid "chat too long"
+msgstr "bericht te lang"
+
+#: server/player.c:147
+msgid "name too long"
+msgstr "naam te lang"
+
+#: server/player.c:179
+msgid "ignoring unknown extension"
+msgstr "onbekende extensie genegeerd"
+
+#: server/player.c:209
+msgid "Game starts, adding computer players"
+msgstr "Het spel gaat beginnen, computer spelers worden toegevoegd"
+
+#: server/player.c:234
+#, c-format
+msgid "The game starts in %s minutes."
+msgstr "Het spel start over %s minuten"
+
+#: server/player.c:235
+#, c-format
+msgid "The game starts in %s minute."
+msgstr "Het spel start over %s minuut"
+
+#: server/player.c:280
+msgid "Sorry, game is over."
+msgstr "Helaas, het spel is al afgelopen."
+
+#: server/player.c:283
+#, c-format
+msgid "Player from %s is refused: game is over\n"
+msgstr "Speler vanaf %s geweigerd: het spel is afgelopen\n"
+
+#: server/player.c:331
+msgid "This game will start soon."
+msgstr "Dit spel start binnenkort."
+
+#: server/player.c:359
+msgid "Name not changed: new name is already in use"
+msgstr "Naam niet veranderd: de nieuwe naam is al in gebruik"
+
+#. %s is the name of the reconnecting player
+#: server/player.c:648
+#, c-format
+msgid "%s has reconnected."
+msgstr "%s is weer terug."
+
+#: server/player.c:776
+#, c-format
+msgid "Version mismatch: %s"
+msgstr "De versies van de server en de client komen niet overeen: %s"
+
+#: server/server.c:47
+msgid "Was hanging around for too long without players... bye.\n"
+msgstr "Na lang wachten zijn er nog steeds geen spelers... Doei.\n"
+
+#. Server: preparing game #.....
+#: server/server.c:219
+msgid "Preparing game"
+msgstr "Voorbereiden spel"
+
+#: server/server.c:337
+msgid "Missing game directory\n"
+msgstr "Spellenmap niet gevonden\n"
+
+#: server/turn.c:253
+msgid "Island Discovery Bonus"
+msgstr "Eiland ontdekkingsbonus"
+
+#: server/turn.c:256
+msgid "Additional Island Bonus"
+msgstr "Extra eiland bonus"
+
+#: server/turn.c:388
+msgid "Tried to assign resources to NULL player.\n"
+msgstr "Poging om grondstoffen aan de NULL speler te geven.\n"
+
+#~ msgid "Brick port|B"
+#~ msgstr "B"
+
+#~ msgid "Grain port|G"
+#~ msgstr "G"
+
+#~ msgid "Ore port|O"
+#~ msgstr "IJ"
+
+#~ msgid "Wool port|W"
+#~ msgstr "W"
+
+#~ msgid "Lumber port|L"
+#~ msgstr "H"
+
+#~ msgid "Continue with your turn."
+#~ msgstr "Ga verder met je beurt."
+
+#~ msgid "Map Terrain"
+#~ msgstr "Terrein"
+
+#~ msgid "Default map or a random map"
+#~ msgstr "Standaard of willekeurig terrein"
+
+#~ msgid "%s has requested a connection check."
+#~ msgstr "%s heeft een verbindingscontrole aangevraagd."
+
+#~ msgid "The metaserver has rejected the reported hostname. Try %s instead."
+#~ msgstr ""
+#~ "De metaserver heeft de geregistreerde computernaam verworpen. Probeer %s "
+#~ "eens."
+
+#~ msgid "NOTE Expecting version %s, not %s\n"
+#~ msgstr "NOTE Verwachtte versie %s, niet %s\n"
+
+#~ msgid "Pixmap not found: %s\n"
+#~ msgstr "Plaatje \"%s\" werd niet gevonden\n"
+
+#~ msgid "Only server or port set, ignoring command line"
+#~ msgstr "Alleen server of poort ingesteld, commandoregel wordt genegeerd"
+
+#~ msgid "Could not initialize default theme."
+#~ msgstr "Kan het Default thema niet gebruiken."
+
+#~ msgid "Theme %s not loaded due to errors."
+#~ msgstr "Thema %s is niet ingeladen vanwege fouten."
+
+#~ msgid "Could not find '%s' pixmap file in theme '%s'."
+#~ msgstr "Plaatjesbestand \"%s\" van thema '%s' kon niet gevonden worden."
+
+#~ msgid "Could not load '%s' pixmap file in theme '%s'."
+#~ msgstr "Plaatjesbestand \"%s\" van thema '%s' kon niet geladen worden."
+
+#~ msgid "Could not find default pixmap file: %s"
+#~ msgstr "Plaatjesbestand \"%s\" van default thema kon niet gevonden worden."
+
+#~ msgid "While reading %s at line %d:"
+#~ msgstr "Tijdens het lezen van %s op regel %d:"
+
+#~ msgid "variable name missing: %s"
+#~ msgstr "variabelenaam mist: %s"
+
+#~ msgid "unknown config variable '%s'"
+#~ msgstr "onbekende configuratievariabele \"%s\""
+
+#~ msgid "'=' missing: %s"
+#~ msgstr "missende \"=\"i: %s"
+
+#~ msgid "missing value"
+#~ msgstr "missende waarde"
+
+#~ msgid "invalid color: %s"
+#~ msgstr "ongeldige kleur: %s"
+
+#~ msgid "unexpected rest at end of line: '%s'"
+#~ msgstr "onverwachte rommel aan het einde van de regel: \"%s\""
+
+#~ msgid "No usable version of WinSock was found."
+#~ msgstr "Geen bruikbare versie van WinSock gevonden."
+
+#~ msgid "State stack overflow"
+#~ msgstr "Toestandsstapel is vol"
+
+#~ msgid "_Contents"
+#~ msgstr "_Inhoud"
+
+#~ msgid "Contents"
+#~ msgstr "Inhoud"
+
+#~ msgid "Development Card Deck"
+#~ msgstr "Ontwikkelingskaarten"
+
+#~ msgid "_Save as..."
+#~ msgstr "Opslaan _als..."
+
+#~ msgid "%s receives %s\n"
+#~ msgstr "%s krijgt %s\n"
+
+#~ msgid "%s spent %s\n"
+#~ msgstr "%s betaalt %s\n"
+
+#~ msgid "%s is refunded %s\n"
+#~ msgstr "%s krijgt %s terug\n"
+
+#~ msgid "%s discarded %s\n"
+#~ msgstr "%s gooit %s weg\n"
+
+#~ msgid "Player %d is now anonymous.\n"
+#~ msgstr "Speler %d is nu anoniem.\n"
+
+#~ msgid "%s is now anonymous.\n"
+#~ msgstr "%s is nu anoniem.\n"
+
+#~ msgid "%s moved robber.\n"
+#~ msgstr "%s verplaatst de struikrover.\n"
+
+#~ msgid "Trading started by %s\n"
+#~ msgstr "%s wil handelen.\n"
+
+#~ msgid "Trading restarted by %s\n"
+#~ msgstr "%s vraagt opnieuw om te handelen.\n"
+
+#~ msgid "Quote from player %d: %s.\n"
+#~ msgstr "Speler %d doet een aanbod: %s.\n"
+
+#~ msgid "Removed quote from player %d: %s\n"
+#~ msgstr "Speler %d trekt een aanbod in: %s.\n"
+
+#~ msgid "Trading finished.\n"
+#~ msgstr "De handelsfase is beëindigd.\n"
+
+#~ msgid "Cannot determine bank, expect out of resource errors\n"
+#~ msgstr "Kan de bank niet bepalen.\n"
+
+#~ msgid "Warning - there are shortages."
+#~ msgstr "Waarschuwing: er is schaarste."
+
+#~ msgid "Resource to take"
+#~ msgstr "Grondstoffen"
+
+#~ msgid "color must be 'none' or start with '#': %s"
+#~ msgstr "Kleur moet \"none\" zijn, of beginnen met \"#\": %s"
+
+#~ msgid "color value contains non-hex character '%c'"
+#~ msgstr "Kleurwaarde bevat ongeldig teken '%c'"
+
+#~ msgid "bits per color component must be 4, 8, 12, or 16: #%s"
+#~ msgstr "bits per kleurcomponent moet 4, 8, 12, of 16 zijn: #%s"
+
+#~ msgid "Create a new public game"
+#~ msgstr "Maak een nieuw openbaar spel"
+
+#~ msgid "Take"
+#~ msgstr "Nemen"
+
+#~ msgid "Hand"
+#~ msgstr "Hand"
+
+#~ msgid "Discards"
+#~ msgstr "Weggooien"
+
+#~ msgid "Player _Name"
+#~ msgstr "Wijzig _Naam"
+
+#~ msgid "Appearance"
+#~ msgstr "Uiterlijk"
+
+#~ msgid "Text Only"
+#~ msgstr "alleen tekst"
+
+#~ msgid "Icons Only"
+#~ msgstr "alleen plaatjes"
+
+#~ msgid "Both Icons and Text"
+#~ msgstr "plaatjes met tekst"
+
+#~ msgid "Color Settings"
+#~ msgstr "Kleurinstellingen"
+
+#~ msgid "Display chat messages in user's color?"
+#~ msgstr "Praatberichten in de kleur van de speler"
+
+#~ msgid "Language"
+#~ msgstr "Taal"
+
+#~ msgid "Language setting takes full effect only after client restart!"
+#~ msgstr ""
+#~ "Taalinstelling werkt pas volledig bij het opnieuw opstarten van het "
+#~ "programma."
+
+#~ msgid "Resource Type"
+#~ msgstr "Grondstof"
+
+#~ msgid "player %d resource count wrong: server=%d, me=%d"
+#~ msgstr ""
+#~ "Server en client zijn het niet eens over grondstoffen van speler %d.\n"
+#~ "Server zegt %d, client zegt %d."
+
+#~ msgid "resources wrong:"
+#~ msgstr "foute grondstoffen:"
+
+#~ msgid ""
+#~ "\n"
+#~ "%s: server=%d, me=%d"
+#~ msgstr ""
+#~ "\n"
+#~ "%s: server zegt %d, client zegt %d"
+
+#~ msgid "E_xit"
+#~ msgstr "_Afsluiten"
+
+#~ msgid "Game Name"
+#~ msgstr "Spelnaam"
+
+#~ msgid "Query Meta Server"
+#~ msgstr "Zoek op de metaserver"
+
+#~ msgid "Start Server"
+#~ msgstr "Start Server"
Added: trunk/po/pioneers.pot
===================================================================
--- trunk/po/pioneers.pot (rev 0)
+++ trunk/po/pioneers.pot 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,3052 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-07 20:43+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Default name for the AI when the computer_names file
+#. * is not found or empty.
+#.
+#: client/ai/ai.c:74 client/ai/ai.c:90
+msgid "Computer Player"
+msgstr ""
+
+#. Commandline pioneersai: server
+#. Commandline option of client: hostname of the server
+#: client/ai/ai.c:102 client/gtk/connect.c:1462 client/gtk/offline.c:53
+msgid "Server Host"
+msgstr ""
+
+#. Commandline pioneersai: port
+#. Commandline option of client: port of the server
+#: client/ai/ai.c:105 client/gtk/connect.c:1478 client/gtk/offline.c:56
+#: server/gtk/main.c:612
+msgid "Server Port"
+msgstr ""
+
+#. Commandline pioneersai: name
+#: client/ai/ai.c:108
+msgid "Computer name (leave absent for random name)"
+msgstr ""
+
+#. Commandline pioneersai: time
+#: client/ai/ai.c:111
+msgid "Time to wait between turns (in milliseconds)"
+msgstr ""
+
+#. Commandline pioneersai: chat-free
+#: client/ai/ai.c:114
+msgid "Stop computer player from talking"
+msgstr ""
+
+#. Commandline pioneersai: algorithm
+#: client/ai/ai.c:117
+msgid "Type of computer player"
+msgstr ""
+
+#. Commandline option of ai: enable debug logging
+#. Commandline option of client: enable debug logging
+#. Commandline option of meta server: enable debug logging
+#. Commandline option of server-gtk: enable debug logging
+#. Commandline option of server: enable debug logging
+#: client/ai/ai.c:120 client/gtk/offline.c:74 meta-server/main.c:1049
+#: server/gtk/main.c:952 server/main.c:144
+msgid "Enable debug messages"
+msgstr ""
+
+#. Commandline option of ai: version
+#. Commandline option of client: version
+#. Commandline option of editor: version
+#. Commandline option of meta server: version
+#. Commandline option of server-gtk: version
+#. Commandline option of server-console: version
+#: client/ai/ai.c:123 client/gtk/offline.c:77 editor/gtk/editor.c:1071
+#: meta-server/main.c:1055 server/gtk/main.c:955 server/main.c:99
+msgid "Show version information"
+msgstr ""
+
+#: client/ai/ai.c:134
+msgid "- Computer player for Pioneers"
+msgstr ""
+
+#: client/ai/ai.c:144 client/gtk/offline.c:186 editor/gtk/editor.c:1111
+#: meta-server/main.c:1084 server/gtk/main.c:1005 server/main.c:206
+#, c-format
+msgid "Pioneers version:"
+msgstr ""
+
+#: client/ai/ai.c:176
+#, c-format
+msgid "Type of computer player: %s\n"
+msgstr ""
+
+#: client/ai/ai.c:205
+msgid "The game is already full. I'm leaving."
+msgstr ""
+
+#: client/ai/greedy.c:941
+msgid "No settlements in stock to use for setup"
+msgstr ""
+
+#: client/ai/greedy.c:948
+msgid "There is no place to setup a settlement"
+msgstr ""
+
+#: client/ai/greedy.c:972
+msgid "No roads in stock to use for setup"
+msgstr ""
+
+#: client/ai/greedy.c:989
+msgid "There is no place to setup a road"
+msgstr ""
+
+#: client/ai/greedy.c:1291
+msgid "Ok, let's go!"
+msgstr ""
+
+#: client/ai/greedy.c:1292
+msgid "I'll beat you all now! ;)"
+msgstr ""
+
+#: client/ai/greedy.c:1293
+msgid "Now for another try..."
+msgstr ""
+
+#: client/ai/greedy.c:1297
+msgid "At least I get something..."
+msgstr ""
+
+#: client/ai/greedy.c:1298
+msgid "One is better than none..."
+msgstr ""
+
+#: client/ai/greedy.c:1302
+msgid "Wow!"
+msgstr ""
+
+#: client/ai/greedy.c:1303
+msgid "Ey, I'm becoming rich ;)"
+msgstr ""
+
+#: client/ai/greedy.c:1304
+msgid "This is really a good year!"
+msgstr ""
+
+#: client/ai/greedy.c:1307
+msgid "You really don't deserve that much!"
+msgstr ""
+
+#: client/ai/greedy.c:1308
+msgid "You don't know what to do with that many resources ;)"
+msgstr ""
+
+#: client/ai/greedy.c:1309
+msgid "Ey, wait for my robber and lose all this again!"
+msgstr ""
+
+#: client/ai/greedy.c:1312
+msgid "Hehe!"
+msgstr ""
+
+#: client/ai/greedy.c:1313
+msgid "Go, robber, go!"
+msgstr ""
+
+#: client/ai/greedy.c:1316
+msgid "You bastard!"
+msgstr ""
+
+#: client/ai/greedy.c:1317
+msgid "Can't you move that robber somewhere else?!"
+msgstr ""
+
+#: client/ai/greedy.c:1318
+msgid "Why always me??"
+msgstr ""
+
+#: client/ai/greedy.c:1321
+msgid "Oh no!"
+msgstr ""
+
+#: client/ai/greedy.c:1322
+msgid "Grrr!"
+msgstr ""
+
+#: client/ai/greedy.c:1323
+msgid "Who the hell rolled that 7??"
+msgstr ""
+
+#: client/ai/greedy.c:1324
+msgid "Why always me?!?"
+msgstr ""
+
+#: client/ai/greedy.c:1327
+msgid "Say good bye to your cards... :)"
+msgstr ""
+
+#: client/ai/greedy.c:1328
+msgid "*evilgrin*"
+msgstr ""
+
+#: client/ai/greedy.c:1329
+msgid "/me says farewell to your cards ;)"
+msgstr ""
+
+#: client/ai/greedy.c:1330
+msgid "That's the price for being rich... :)"
+msgstr ""
+
+#: client/ai/greedy.c:1333
+msgid "Ey! Where's that card gone?"
+msgstr ""
+
+#: client/ai/greedy.c:1334
+msgid "Thieves! Thieves!!"
+msgstr ""
+
+#: client/ai/greedy.c:1335
+msgid "Wait for my revenge..."
+msgstr ""
+
+#: client/ai/greedy.c:1338
+msgid "Oh no :("
+msgstr ""
+
+#: client/ai/greedy.c:1339
+msgid "Must this happen NOW??"
+msgstr ""
+
+#: client/ai/greedy.c:1340
+msgid "Args"
+msgstr ""
+
+#: client/ai/greedy.c:1343
+msgid "Hehe, my soldiers rule!"
+msgstr ""
+
+#: client/ai/greedy.c:1346
+msgid "First robbing us, then grabbing the points..."
+msgstr ""
+
+#: client/ai/greedy.c:1349
+msgid "See that road!"
+msgstr ""
+
+#: client/ai/greedy.c:1352
+msgid "Pf, you won't win with roads alone..."
+msgstr ""
+
+#: client/ai/greedy.c:1819
+msgid "Rejecting trade.\n"
+msgstr ""
+
+#: client/ai/greedy.c:1911
+#, c-format
+msgid "Received error from server: %s. Quitting\n"
+msgstr ""
+
+#: client/ai/greedy.c:1921
+msgid "Yippie!"
+msgstr ""
+
+#: client/ai/greedy.c:1923
+msgid "My congratulations"
+msgstr ""
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:80
+msgid ""
+"Hello, welcome to the lobby. I am a simple robot. Type '/help' in the chat "
+"to see the list of commands I know."
+msgstr ""
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:107
+msgid "'/help' shows this message again"
+msgstr ""
+
+#. Translators: don't translate '/why'
+#: client/ai/lobbybot.c:110
+msgid "'/why' explains the purpose of this strange board layout"
+msgstr ""
+
+#. Translators: don't translate '/news'
+#: client/ai/lobbybot.c:113
+msgid "'/news' tells the last released version"
+msgstr ""
+
+#: client/ai/lobbybot.c:118
+msgid ""
+"This board is not intended to be a game that can be played. Instead, players "
+"can find eachother here, and decide which board they want to play. Then, one "
+"of the players will host the proposed game by starting a server, and "
+"registers it at the metaserver. The other players can subsequently "
+"disconnect from the lobby, and enter that game."
+msgstr ""
+
+#: client/ai/lobbybot.c:129
+msgid "The last released version of Pioneers is"
+msgstr ""
+
+#: client/ai/lobbybot.c:144
+msgid "The game is starting. I'm not needed anymore. Goodbye."
+msgstr ""
+
+#: client/common/client.c:103
+msgid "Waiting"
+msgstr ""
+
+#: client/common/client.c:105 client/common/client.c:1241
+msgid "Idle"
+msgstr ""
+
+#: client/common/client.c:447
+msgid "We have been kicked out of the game.\n"
+msgstr ""
+
+#. Network status: offline
+#: client/common/client.c:450 client/common/client.c:891 client/gtk/gui.c:1340
+msgid "Offline"
+msgstr ""
+
+#: client/common/client.c:471
+#, c-format
+msgid "Error (%s): %s\n"
+msgstr ""
+
+#: client/common/client.c:480 client/common/client.c:491
+#, c-format
+msgid "Notice: %s\n"
+msgstr ""
+
+#: client/common/client.c:607
+#, c-format
+msgid "%s does not receive any %s, because the bank is empty.\n"
+msgstr ""
+
+#: client/common/client.c:620
+#, c-format
+msgid "%s only receives %s, because the bank didn't have any more.\n"
+msgstr ""
+
+#: client/common/client.c:629
+#, c-format
+msgid "%s receives %s.\n"
+msgstr ""
+
+#. Year of Plenty
+#: client/common/client.c:637 client/common/client.c:2586
+#, c-format
+msgid "%s takes %s.\n"
+msgstr ""
+
+#: client/common/client.c:642
+#, c-format
+msgid "%s spent %s.\n"
+msgstr ""
+
+#: client/common/client.c:648
+#, c-format
+msgid "%s is refunded %s.\n"
+msgstr ""
+
+#: client/common/client.c:679
+#, c-format
+msgid "%s discarded %s.\n"
+msgstr ""
+
+#: client/common/client.c:849
+msgid "Loading"
+msgstr ""
+
+#: client/common/client.c:892
+msgid "Version mismatch"
+msgstr ""
+
+#: client/common/client.c:894
+msgid "Version mismatch. Please make sure client and server are up to date.\n"
+msgstr ""
+
+#: client/common/client.c:1340
+msgid "Build two settlements, each with a connecting"
+msgstr ""
+
+#: client/common/client.c:1343
+msgid "Build a settlement with a connecting"
+msgstr ""
+
+#: client/common/client.c:1346
+msgid "road"
+msgstr ""
+
+#: client/common/client.c:1348
+msgid "bridge"
+msgstr ""
+
+#: client/common/client.c:1350
+msgid "ship"
+msgstr ""
+
+#: client/common/client.c:1358
+msgid " or"
+msgstr ""
+
+#: client/common/client.c:1416
+msgid "Waiting for your turn"
+msgstr ""
+
+#: client/common/client.c:1468
+msgid "Select the building to steal from."
+msgstr ""
+
+#: client/common/client.c:1490
+msgid "Select the ship to steal from."
+msgstr ""
+
+#: client/common/client.c:1575 client/gtk/interface.c:782
+msgid "Place the robber"
+msgstr ""
+
+#: client/common/client.c:1625
+msgid "Finish the road building action."
+msgstr ""
+
+#: client/common/client.c:1627
+msgid "Build one road segment."
+msgstr ""
+
+#: client/common/client.c:1629
+msgid "Build two road segments."
+msgstr ""
+
+#: client/common/client.c:1902 client/common/client.c:1996
+msgid "It is your turn."
+msgstr ""
+
+#: client/common/client.c:2090
+#, c-format
+msgid "Sorry, %s available.\n"
+msgstr ""
+
+#: client/common/client.c:2405
+msgid "The game is over."
+msgstr ""
+
+#: client/common/develop.c:43 editor/gtk/game-devcards.c:13
+msgid "Road Building"
+msgstr ""
+
+#: client/common/develop.c:44 client/gtk/monopoly.c:83
+#: editor/gtk/game-devcards.c:13
+msgid "Monopoly"
+msgstr ""
+
+#: client/common/develop.c:45 client/gtk/plenty.c:59
+#: editor/gtk/game-devcards.c:13
+msgid "Year of Plenty"
+msgstr ""
+
+#: client/common/develop.c:46 client/gtk/player.c:57
+#: editor/gtk/game-devcards.c:14
+msgid "Chapel"
+msgstr ""
+
+#: client/common/develop.c:47 client/gtk/player.c:58
+#: editor/gtk/game-devcards.c:14
+msgid "Pioneer University"
+msgstr ""
+
+#: client/common/develop.c:48 client/gtk/player.c:60
+#: editor/gtk/game-devcards.c:15
+msgid "Governor's House"
+msgstr ""
+
+#: client/common/develop.c:49 client/gtk/player.c:61
+#: editor/gtk/game-devcards.c:15
+msgid "Library"
+msgstr ""
+
+#: client/common/develop.c:50 client/gtk/player.c:62
+#: editor/gtk/game-devcards.c:15
+msgid "Market"
+msgstr ""
+
+#: client/common/develop.c:51 client/gtk/player.c:63
+#: editor/gtk/game-devcards.c:16
+msgid "Soldier"
+msgstr ""
+
+#: client/common/develop.c:82
+#, c-format
+msgid "You bought the %s development card.\n"
+msgstr ""
+
+#: client/common/develop.c:88
+#, c-format
+msgid "You bought a %s development card.\n"
+msgstr ""
+
+#: client/common/develop.c:110
+#, c-format
+msgid "%s bought a development card.\n"
+msgstr ""
+
+#: client/common/develop.c:129
+#, c-format
+msgid "%s played the %s development card.\n"
+msgstr ""
+
+#: client/common/develop.c:134
+#, c-format
+msgid "%s played a %s development card.\n"
+msgstr ""
+
+#: client/common/develop.c:147
+msgid "You have run out of road segments.\n"
+msgstr ""
+
+#. I get the cards!
+#.
+#: client/common/develop.c:187
+#, c-format
+msgid "You get %s from %s.\n"
+msgstr ""
+
+#. I lose the cards!
+#.
+#: client/common/develop.c:193
+#, c-format
+msgid "%s took %s from you.\n"
+msgstr ""
+
+#: client/common/develop.c:200
+#, c-format
+msgid "%s took %s from %s.\n"
+msgstr ""
+
+#: client/common/player.c:124 server/player.c:405
+#, c-format
+msgid "Viewer %d"
+msgstr ""
+
+#: client/common/player.c:126
+#, c-format
+msgid "viewer %d"
+msgstr ""
+
+#: client/common/player.c:134 server/player.c:408
+#, c-format
+msgid "Player %d"
+msgstr ""
+
+#: client/common/player.c:136
+#, c-format
+msgid "player %d"
+msgstr ""
+
+#: client/common/player.c:212
+#, c-format
+msgid "New viewer: %s.\n"
+msgstr ""
+
+#: client/common/player.c:215 client/common/player.c:231
+#, c-format
+msgid "%s is now %s.\n"
+msgstr ""
+
+#: client/common/player.c:228
+#, c-format
+msgid "Player %d is now %s.\n"
+msgstr ""
+
+#: client/common/player.c:267
+#, c-format
+msgid "%s has quit\n"
+msgstr ""
+
+#: client/common/player.c:276
+msgid "There is no largest army.\n"
+msgstr ""
+
+#: client/common/player.c:279
+#, c-format
+msgid "%s has the largest army.\n"
+msgstr ""
+
+#: client/common/player.c:300
+msgid "There is no longest road.\n"
+msgstr ""
+
+#: client/common/player.c:303
+#, c-format
+msgid "%s has the longest road.\n"
+msgstr ""
+
+#: client/common/player.c:324
+#, c-format
+msgid "Waiting for %s."
+msgstr ""
+
+#. We are not in on the action
+#. someone stole a resource from someone else
+#: client/common/player.c:352
+#, c-format
+msgid "%s stole a resource from %s.\n"
+msgstr ""
+
+#: client/common/player.c:362
+#, c-format
+msgid "You stole %s from %s.\n"
+msgstr ""
+
+#: client/common/player.c:368
+#, c-format
+msgid "%s stole %s from you.\n"
+msgstr ""
+
+#: client/common/player.c:402
+#, c-format
+msgid "%s gave %s nothing!?\n"
+msgstr ""
+
+#: client/common/player.c:408 client/common/player.c:416
+#, c-format
+msgid "%s gave %s %s for free.\n"
+msgstr ""
+
+#: client/common/player.c:424
+#, c-format
+msgid "%s gave %s %s in exchange for %s.\n"
+msgstr ""
+
+#: client/common/player.c:455
+#, c-format
+msgid "%s exchanged %s for %s.\n"
+msgstr ""
+
+#: client/common/player.c:475
+#, c-format
+msgid "%s built a road.\n"
+msgstr ""
+
+#: client/common/player.c:487
+#, c-format
+msgid "%s built a ship.\n"
+msgstr ""
+
+#: client/common/player.c:500
+#, c-format
+msgid "%s built a settlement.\n"
+msgstr ""
+
+#: client/common/player.c:519
+#, c-format
+msgid "%s built a city.\n"
+msgstr ""
+
+#: client/common/player.c:533
+#, c-format
+msgid "%s built a city wall.\n"
+msgstr ""
+
+#: client/common/player.c:544
+#, c-format
+msgid "player_build_add called with BUILD_NONE for user %s\n"
+msgstr ""
+
+#: client/common/player.c:553
+#, c-format
+msgid "%s built a bridge.\n"
+msgstr ""
+
+#: client/common/player.c:579
+#, c-format
+msgid "%s removed a road.\n"
+msgstr ""
+
+#: client/common/player.c:589
+#, c-format
+msgid "%s removed a ship.\n"
+msgstr ""
+
+#: client/common/player.c:599
+#, c-format
+msgid "%s removed a settlement.\n"
+msgstr ""
+
+#: client/common/player.c:610
+#, c-format
+msgid "%s removed a city.\n"
+msgstr ""
+
+#: client/common/player.c:624
+#, c-format
+msgid "%s removed a city wall.\n"
+msgstr ""
+
+#: client/common/player.c:634
+#, c-format
+msgid "player_build_remove called with BUILD_NONE for user %s\n"
+msgstr ""
+
+#: client/common/player.c:642
+#, c-format
+msgid "%s removed a bridge.\n"
+msgstr ""
+
+#: client/common/player.c:673
+#, c-format
+msgid "%s has cancelled a ship's movement.\n"
+msgstr ""
+
+#: client/common/player.c:676
+#, c-format
+msgid "%s moved a ship.\n"
+msgstr ""
+
+#. tell the user that someone got something
+#: client/common/player.c:696
+#, c-format
+msgid "%s received %s.\n"
+msgstr ""
+
+#: client/common/player.c:714
+msgid "server asks to lose invalid point.\n"
+msgstr ""
+
+#. tell the user the point is lost
+#: client/common/player.c:720
+#, c-format
+msgid "%s lost %s.\n"
+msgstr ""
+
+#: client/common/player.c:743
+msgid "server asks to move invalid point.\n"
+msgstr ""
+
+#. tell the user someone (1) lost something (2) to someone else (3)
+#: client/common/player.c:750
+#, c-format
+msgid "%s lost %s to %s.\n"
+msgstr ""
+
+#: client/common/resource.c:35
+msgid "brick"
+msgstr ""
+
+#: client/common/resource.c:35
+msgid "Brick"
+msgstr ""
+
+#: client/common/resource.c:36
+msgid "grain"
+msgstr ""
+
+#: client/common/resource.c:36
+msgid "Grain"
+msgstr ""
+
+#: client/common/resource.c:37
+msgid "ore"
+msgstr ""
+
+#: client/common/resource.c:37
+msgid "Ore"
+msgstr ""
+
+#: client/common/resource.c:38
+msgid "wool"
+msgstr ""
+
+#: client/common/resource.c:38
+msgid "Wool"
+msgstr ""
+
+#: client/common/resource.c:39
+msgid "lumber"
+msgstr ""
+
+#: client/common/resource.c:39
+msgid "Lumber"
+msgstr ""
+
+#: client/common/resource.c:40
+msgid "no resource (bug)"
+msgstr ""
+
+#: client/common/resource.c:40
+msgid "No resource (bug)"
+msgstr ""
+
+#: client/common/resource.c:41
+msgid "any resource (bug)"
+msgstr ""
+
+#: client/common/resource.c:41
+msgid "Any resource (bug)"
+msgstr ""
+
+#: client/common/resource.c:42
+msgid "gold"
+msgstr ""
+
+#: client/common/resource.c:42 client/gtk/legend.c:39
+msgid "Gold"
+msgstr ""
+
+#: client/common/resource.c:47
+msgid "a brick card"
+msgstr ""
+
+#: client/common/resource.c:47
+#, c-format
+msgid "%d brick cards"
+msgstr ""
+
+#: client/common/resource.c:48
+msgid "a grain card"
+msgstr ""
+
+#: client/common/resource.c:48
+#, c-format
+msgid "%d grain cards"
+msgstr ""
+
+#: client/common/resource.c:49
+msgid "an ore card"
+msgstr ""
+
+#: client/common/resource.c:49
+#, c-format
+msgid "%d ore cards"
+msgstr ""
+
+#: client/common/resource.c:50
+msgid "a wool card"
+msgstr ""
+
+#: client/common/resource.c:50
+#, c-format
+msgid "%d wool cards"
+msgstr ""
+
+#: client/common/resource.c:51
+msgid "a lumber card"
+msgstr ""
+
+#: client/common/resource.c:51
+#, c-format
+msgid "%d lumber cards"
+msgstr ""
+
+#: client/common/resource.c:139 client/common/resource.c:225
+msgid "nothing"
+msgstr ""
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:166
+#, c-format
+msgid "%s and %s"
+msgstr ""
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:170
+#, c-format
+msgid "%s, %s"
+msgstr ""
+
+#: client/common/robber.c:60
+#, c-format
+msgid "%s has undone the robber movement.\n"
+msgstr ""
+
+#: client/common/robber.c:63
+#, c-format
+msgid "%s moved the robber.\n"
+msgstr ""
+
+#: client/common/robber.c:73
+#, c-format
+msgid "%s has undone the pirate movement.\n"
+msgstr ""
+
+#: client/common/robber.c:76
+#, c-format
+msgid "%s moved the pirate.\n"
+msgstr ""
+
+#: client/common/robber.c:83
+#, c-format
+msgid "%s must move the robber."
+msgstr ""
+
+#: client/common/setup.c:140
+#, c-format
+msgid "Setup for %s.\n"
+msgstr ""
+
+#: client/common/setup.c:152
+#, c-format
+msgid "Double setup for %s.\n"
+msgstr ""
+
+#: client/common/turn.c:37
+#, c-format
+msgid "%s rolled %d.\n"
+msgstr ""
+
+#: client/common/turn.c:50
+#, c-format
+msgid "Begin turn %d for %s.\n"
+msgstr ""
+
+#: client/gtk/chat.c:71
+msgid "<b>Chat</b>"
+msgstr ""
+
+#: client/gtk/chat.c:231
+msgid "Beeper test.\n"
+msgstr ""
+
+#: client/gtk/chat.c:234
+#, c-format
+msgid "%s beeped you.\n"
+msgstr ""
+
+#: client/gtk/chat.c:238
+#, c-format
+msgid "You beeped %s.\n"
+msgstr ""
+
+#: client/gtk/chat.c:244
+#, c-format
+msgid "You could not beep %s.\n"
+msgstr ""
+
+#: client/gtk/chat.c:288
+msgid " said: "
+msgstr ""
+
+#: client/gtk/connect.c:282
+#, c-format
+msgid "Meta-server at %s, port %s"
+msgstr ""
+
+#: client/gtk/connect.c:292
+msgid "Finished.\n"
+msgstr ""
+
+#: client/gtk/connect.c:309 client/gtk/connect.c:359 client/gtk/connect.c:456
+#: server/meta.c:174
+msgid "Meta-server kicked us off\n"
+msgstr ""
+
+#: client/gtk/connect.c:334
+msgid "Receiving game names from the meta server.\n"
+msgstr ""
+
+#: client/gtk/connect.c:382
+#, c-format
+msgid "New game server requested on %s port %s\n"
+msgstr ""
+
+#: client/gtk/connect.c:391 server/meta.c:168
+#, c-format
+msgid "Unknown message from the metaserver: %s\n"
+msgstr ""
+
+#: client/gtk/connect.c:472 server/meta.c:125
+msgid "Too many meta-server redirects\n"
+msgstr ""
+
+#: client/gtk/connect.c:499 server/meta.c:140
+#, c-format
+msgid "Bad redirect line: %s\n"
+msgstr ""
+
+#: client/gtk/connect.c:525
+#, c-format
+msgid "Meta server too old to create servers (version %d.%d)\n"
+msgstr ""
+
+#. Sevens rule: normal
+#: client/gtk/connect.c:596 client/gtk/settingscreen.c:168
+#: common/gtk/game-rules.c:81
+msgid "Normal"
+msgstr ""
+
+#: client/gtk/connect.c:602 client/gtk/settingscreen.c:170
+#: common/gtk/game-rules.c:88
+msgid "Reroll on 1st 2 turns"
+msgstr ""
+
+#: client/gtk/connect.c:605 client/gtk/settingscreen.c:172
+#: common/gtk/game-rules.c:95
+msgid "Reroll all 7s"
+msgstr ""
+
+#: client/gtk/connect.c:619
+msgid "Default"
+msgstr ""
+
+#: client/gtk/connect.c:622
+msgid "Random"
+msgstr ""
+
+#: client/gtk/connect.c:653 server/meta.c:188
+#, c-format
+msgid "Redirected to meta-server at %s, port %s\n"
+msgstr ""
+
+#: client/gtk/connect.c:656
+msgid "Receiving a list of Pioneers servers from the meta server.\n"
+msgstr ""
+
+#: client/gtk/connect.c:713
+msgid ""
+"<b>Note</b>:\n"
+"\tThe metaserver does not send information about the games.\n"
+"\tPlease set appropriate values yourself."
+msgstr ""
+
+#: client/gtk/connect.c:730
+msgid "Number of AI Players"
+msgstr ""
+
+#: client/gtk/connect.c:749
+msgid "The number of AI players"
+msgstr ""
+
+#: client/gtk/connect.c:770
+msgid "Requesting new game server\n"
+msgstr ""
+
+#: client/gtk/connect.c:813 server/gtk/main.c:328 server/server.c:160
+#, c-format
+msgid "Error starting %s: %s"
+msgstr ""
+
+#: client/gtk/connect.c:834
+msgid "Create a public game"
+msgstr ""
+
+#: client/gtk/connect.c:965 client/gtk/connect.c:1268
+msgid "Join a public game"
+msgstr ""
+
+#: client/gtk/connect.c:970
+msgid "_New remote game"
+msgstr ""
+
+#: client/gtk/connect.c:984
+msgid "Refresh the list of games"
+msgstr ""
+
+#: client/gtk/connect.c:989
+msgid "Create a new public game at the meta server"
+msgstr ""
+
+#: client/gtk/connect.c:994
+msgid "Don't join a public game"
+msgstr ""
+
+#: client/gtk/connect.c:998
+msgid "Join the selected game"
+msgstr ""
+
+#: client/gtk/connect.c:1033
+msgid "Select a game to join"
+msgstr ""
+
+#: client/gtk/connect.c:1036
+msgid "Map Name"
+msgstr ""
+
+#: client/gtk/connect.c:1044
+msgid "Name of the game"
+msgstr ""
+
+#: client/gtk/connect.c:1049
+msgid "Curr"
+msgstr ""
+
+#: client/gtk/connect.c:1055
+msgid "Number of players in the game"
+msgstr ""
+
+#: client/gtk/connect.c:1060
+msgid "Max"
+msgstr ""
+
+#: client/gtk/connect.c:1066
+msgid "Maximum players for the game"
+msgstr ""
+
+#: client/gtk/connect.c:1069
+msgid "Terrain"
+msgstr ""
+
+#: client/gtk/connect.c:1076
+msgid "Random of default terrain"
+msgstr ""
+
+#: client/gtk/connect.c:1081
+msgid "Vic. Points"
+msgstr ""
+
+#: client/gtk/connect.c:1087
+msgid "Points needed to win"
+msgstr ""
+
+#: client/gtk/connect.c:1090 common/gtk/game-rules.c:73
+msgid "Sevens Rule"
+msgstr ""
+
+#: client/gtk/connect.c:1096
+msgid "Sevens rule"
+msgstr ""
+
+#: client/gtk/connect.c:1100
+msgid "Host"
+msgstr ""
+
+#: client/gtk/connect.c:1108
+msgid "Host of the game"
+msgstr ""
+
+#: client/gtk/connect.c:1113
+msgid "Port"
+msgstr ""
+
+#: client/gtk/connect.c:1119
+msgid "Port of the the game"
+msgstr ""
+
+#: client/gtk/connect.c:1122 common/gtk/aboutbox.c:77
+msgid "Version"
+msgstr ""
+
+#: client/gtk/connect.c:1129
+msgid "Version of the host"
+msgstr ""
+
+#: client/gtk/connect.c:1184 client/gtk/gui.c:215
+msgid "Start a new game"
+msgstr ""
+
+#: client/gtk/connect.c:1209
+msgid "Player Name"
+msgstr ""
+
+#: client/gtk/connect.c:1223
+msgid "Enter your name"
+msgstr ""
+
+#. Role of the player: viewer
+#: client/gtk/connect.c:1225 server/gtk/main.c:511
+msgid "Viewer"
+msgstr ""
+
+#: client/gtk/connect.c:1233
+msgid "Do you want to be a viewer?"
+msgstr ""
+
+#: client/gtk/connect.c:1240 server/gtk/main.c:640
+msgid "Meta Server"
+msgstr ""
+
+#: client/gtk/connect.c:1255
+msgid "Leave empty for the default meta server"
+msgstr ""
+
+#: client/gtk/connect.c:1263
+msgid "Join public game"
+msgstr ""
+
+#: client/gtk/connect.c:1272
+msgid "Create game"
+msgstr ""
+
+#: client/gtk/connect.c:1275
+msgid "Create a game"
+msgstr ""
+
+#: client/gtk/connect.c:1285
+msgid "Join private game"
+msgstr ""
+
+#: client/gtk/connect.c:1289 client/gtk/connect.c:1434
+msgid "Join a private game"
+msgstr ""
+
+#: client/gtk/connect.c:1475
+msgid "Name of the host of the game"
+msgstr ""
+
+#: client/gtk/connect.c:1494
+msgid "Port of the host of the game"
+msgstr ""
+
+#: client/gtk/connect.c:1534
+msgid "Recent games"
+msgstr ""
+
+#: client/gtk/connect.c:1536
+msgid "Recent Games"
+msgstr ""
+
+#: client/gtk/develop.c:129
+msgid "<b>Development Cards</b>"
+msgstr ""
+
+#: client/gtk/develop.c:160
+msgid "Play Card"
+msgstr ""
+
+#: client/gtk/discard.c:76
+msgid "Discard resources"
+msgstr ""
+
+#: client/gtk/discard.c:96
+#, c-format
+msgid "You must discard %d resources"
+msgstr ""
+
+#: client/gtk/discard.c:101
+msgid "Total discards"
+msgstr ""
+
+#. Caption for list of player that must discard cards
+#: client/gtk/discard.c:226
+msgid "<b>Waiting for players to discard</b>"
+msgstr ""
+
+#: client/gtk/gameover.c:32
+msgid "Game over"
+msgstr ""
+
+#: client/gtk/gameover.c:49
+#, c-format
+msgid "%s has won the game with %d victory points!"
+msgstr ""
+
+#: client/gtk/gameover.c:52
+#, c-format
+msgid "%s has won the game with %d victory points!\n"
+msgstr ""
+
+#: client/gtk/gameover.c:58
+#, c-format
+msgid "All praise %s, Lord of the known world!"
+msgstr ""
+
+#: client/gtk/gold.c:71
+msgid "Choose resources"
+msgstr ""
+
+#: client/gtk/gold.c:92
+#, c-format
+msgid "You may choose 1 resource"
+msgstr ""
+
+#: client/gtk/gold.c:94
+#, c-format
+msgid "You may choose %d resources"
+msgstr ""
+
+#. Text for total in choose gold dialog
+#. Text for total in year of plenty dialog
+#: client/gtk/gold.c:101 client/gtk/plenty.c:98
+msgid "Total resources"
+msgstr ""
+
+#: client/gtk/gold.c:213
+msgid "<b>Waiting for players to choose</b>"
+msgstr ""
+
+#: client/gtk/gui.c:213 server/gtk/main.c:98
+msgid "_Game"
+msgstr ""
+
+#: client/gtk/gui.c:214
+msgid "_New game"
+msgstr ""
+
+#: client/gtk/gui.c:216
+msgid "_Leave game"
+msgstr ""
+
+#: client/gtk/gui.c:217
+msgid "Leave this game"
+msgstr ""
+
+#: client/gtk/gui.c:219
+msgid "_Admin"
+msgstr ""
+
+#: client/gtk/gui.c:220
+msgid "Administer Pioneers server"
+msgstr ""
+
+#: client/gtk/gui.c:222
+msgid "_Player name"
+msgstr ""
+
+#: client/gtk/gui.c:223
+msgid "Change your player name"
+msgstr ""
+
+#: client/gtk/gui.c:224
+msgid "_Legend"
+msgstr ""
+
+#: client/gtk/gui.c:225
+msgid "Terrain legend and building costs"
+msgstr ""
+
+#: client/gtk/gui.c:226
+msgid "_Game Settings"
+msgstr ""
+
+#: client/gtk/gui.c:227
+msgid "Settings for the current game"
+msgstr ""
+
+#: client/gtk/gui.c:228
+msgid "_Dice Histogram"
+msgstr ""
+
+#: client/gtk/gui.c:229
+msgid "Histogram of dice rolls"
+msgstr ""
+
+#: client/gtk/gui.c:230 editor/gtk/editor.c:1018 server/gtk/main.c:103
+msgid "_Quit"
+msgstr ""
+
+#: client/gtk/gui.c:231 server/gtk/main.c:104
+msgid "Quit the program"
+msgstr ""
+
+#: client/gtk/gui.c:232
+msgid "_Actions"
+msgstr ""
+
+#: client/gtk/gui.c:233
+msgid "Roll Dice"
+msgstr ""
+
+#: client/gtk/gui.c:234
+msgid "Roll the dice"
+msgstr ""
+
+#. Tab page name
+#: client/gtk/gui.c:235 client/gtk/gui.c:577
+msgid "Trade"
+msgstr ""
+
+#: client/gtk/gui.c:237
+msgid "Undo"
+msgstr ""
+
+#: client/gtk/gui.c:238 client/gtk/gui.c:239
+msgid "Finish"
+msgstr ""
+
+#: client/gtk/gui.c:240 client/gtk/legend.c:226 editor/gtk/game-buildings.c:13
+msgid "Road"
+msgstr ""
+
+#: client/gtk/gui.c:241
+msgid "Build a road"
+msgstr ""
+
+#: client/gtk/gui.c:242 client/gtk/legend.c:230 editor/gtk/game-buildings.c:13
+msgid "Ship"
+msgstr ""
+
+#: client/gtk/gui.c:243
+msgid "Build a ship"
+msgstr ""
+
+#: client/gtk/gui.c:244
+msgid "Move Ship"
+msgstr ""
+
+#: client/gtk/gui.c:245
+msgid "Move a ship"
+msgstr ""
+
+#: client/gtk/gui.c:246 client/gtk/legend.c:233 editor/gtk/game-buildings.c:13
+msgid "Bridge"
+msgstr ""
+
+#: client/gtk/gui.c:247
+msgid "Build a bridge"
+msgstr ""
+
+#: client/gtk/gui.c:248 client/gtk/legend.c:235 client/gtk/player.c:52
+#: editor/gtk/game-buildings.c:13
+msgid "Settlement"
+msgstr ""
+
+#: client/gtk/gui.c:249
+msgid "Build a settlement"
+msgstr ""
+
+#: client/gtk/gui.c:250 client/gtk/legend.c:236 client/gtk/player.c:53
+#: editor/gtk/game-buildings.c:14
+msgid "City"
+msgstr ""
+
+#: client/gtk/gui.c:251
+msgid "Build a city"
+msgstr ""
+
+#: client/gtk/gui.c:252
+msgid "Develop"
+msgstr ""
+
+#: client/gtk/gui.c:253
+msgid "Buy a development card"
+msgstr ""
+
+#: client/gtk/gui.c:254 client/gtk/legend.c:240 client/gtk/player.c:54
+#: editor/gtk/game-buildings.c:14
+msgid "City Wall"
+msgstr ""
+
+#: client/gtk/gui.c:255
+msgid "Build a city wall"
+msgstr ""
+
+#: client/gtk/gui.c:257
+msgid "_Settings"
+msgstr ""
+
+#: client/gtk/gui.c:258
+msgid "Prefere_nces"
+msgstr ""
+
+#: client/gtk/gui.c:259
+msgid "Configure the application"
+msgstr ""
+
+#: client/gtk/gui.c:261 client/gtk/gui.c:265 editor/gtk/editor.c:1002
+#: server/gtk/main.c:99
+msgid "_Help"
+msgstr ""
+
+#: client/gtk/gui.c:262
+msgid "_About Pioneers"
+msgstr ""
+
+#: client/gtk/gui.c:263
+msgid "Information about Pioneers"
+msgstr ""
+
+#: client/gtk/gui.c:266 client/gtk/gui.c:1065
+msgid "Show the manual"
+msgstr ""
+
+#: client/gtk/gui.c:272
+msgid "_Toolbar"
+msgstr ""
+
+#: client/gtk/gui.c:273
+msgid "Show or hide the toolbar"
+msgstr ""
+
+#. Victory points target in statusbar
+#: client/gtk/gui.c:368
+#, c-format
+msgid "Points Needed to Win: %i"
+msgstr ""
+
+#: client/gtk/gui.c:454
+msgid "<b>Messages</b>"
+msgstr ""
+
+#. Tab page name
+#: client/gtk/gui.c:571 editor/gtk/editor.c:1165
+msgid "Map"
+msgstr ""
+
+#. Tab page name
+#: client/gtk/gui.c:585 client/gtk/quote.c:306
+msgid "Quote"
+msgstr ""
+
+#. Tab page name
+#: client/gtk/gui.c:593 client/gtk/legend.c:261
+msgid "Legend"
+msgstr ""
+
+#. Tab page name, shown for the splash screen
+#: client/gtk/gui.c:603
+msgid "Welcome to Pioneers"
+msgstr ""
+
+#: client/gtk/gui.c:868
+msgid "Pioneers Preferences"
+msgstr ""
+
+#. Label for changing the theme, in the preferences dialog
+#: client/gtk/gui.c:898
+msgid "Theme:"
+msgstr ""
+
+#: client/gtk/gui.c:921
+msgid "Choose one of the themes"
+msgstr ""
+
+#. Label for the option to show the legend
+#: client/gtk/gui.c:925
+msgid "Show legend"
+msgstr ""
+
+#. Tooltip for the option to show the legend
+#: client/gtk/gui.c:935
+msgid "Show the legend as a page beside the map"
+msgstr ""
+
+#. Label for the option to display log messages in color
+#: client/gtk/gui.c:940
+msgid "Messages with color"
+msgstr ""
+
+#: client/gtk/gui.c:950
+msgid "Show new messages with color"
+msgstr ""
+
+#: client/gtk/gui.c:955
+msgid "Chat in color of player"
+msgstr ""
+
+#: client/gtk/gui.c:966
+msgid "Show new chat messages in the color of the player"
+msgstr ""
+
+#. Label for the option to display the summary with colors
+#: client/gtk/gui.c:971
+msgid "Summary with color"
+msgstr ""
+
+#: client/gtk/gui.c:982
+msgid "Use colors in the player summary"
+msgstr ""
+
+#: client/gtk/gui.c:987
+msgid "Toolbar with shortcuts"
+msgstr ""
+
+#: client/gtk/gui.c:997
+msgid "Show keyboard shortcuts in the toolbar"
+msgstr ""
+
+#: client/gtk/gui.c:1003
+msgid "Announce new players"
+msgstr ""
+
+#: client/gtk/gui.c:1014
+msgid "Make a sound when a new player or viewer enters the game"
+msgstr ""
+
+#. Label for the option to use the 16:9 layout.
+#: client/gtk/gui.c:1019
+msgid "Use 16:9 layout"
+msgstr ""
+
+#: client/gtk/gui.c:1030
+msgid "Use a 16:9 friendly layout for the window"
+msgstr ""
+
+#: client/gtk/gui.c:1041
+msgid "The Pioneers Game"
+msgstr ""
+
+#. Initial text in status bar
+#: client/gtk/gui.c:1352
+msgid "Welcome to Pioneers!"
+msgstr ""
+
+#. The name of the application
+#: client/gtk/gui.c:1463
+msgid "Pioneers"
+msgstr ""
+
+#: client/gtk/histogram.c:252
+msgid "Dice Histogram"
+msgstr ""
+
+#: client/gtk/interface.c:92
+msgid "Ship movement canceled."
+msgstr ""
+
+#: client/gtk/interface.c:100 client/gtk/interface.c:101
+msgid "Select a new location for the ship."
+msgstr ""
+
+#: client/gtk/interface.c:740
+msgid "Select the ship to steal from"
+msgstr ""
+
+#: client/gtk/interface.c:750
+msgid "Select the building to steal from"
+msgstr ""
+
+#: client/gtk/legend.c:32
+msgid "Hill"
+msgstr ""
+
+#: client/gtk/legend.c:33
+msgid "Field"
+msgstr ""
+
+#: client/gtk/legend.c:34
+msgid "Mountain"
+msgstr ""
+
+#: client/gtk/legend.c:35
+msgid "Pasture"
+msgstr ""
+
+#: client/gtk/legend.c:36
+msgid "Forest"
+msgstr ""
+
+#: client/gtk/legend.c:37
+msgid "Desert"
+msgstr ""
+
+#: client/gtk/legend.c:38
+msgid "Sea"
+msgstr ""
+
+#: client/gtk/legend.c:170
+msgid "<b>Terrain Yield</b>"
+msgstr ""
+
+#: client/gtk/legend.c:202
+msgid "<b>Building Costs</b>"
+msgstr ""
+
+#: client/gtk/legend.c:243
+msgid "Development Card"
+msgstr ""
+
+#: client/gtk/monopoly.c:105
+msgid "Select the resource you wish to monopolise."
+msgstr ""
+
+#: client/gtk/name.c:123
+msgid "Change player name"
+msgstr ""
+
+#: client/gtk/name.c:146
+msgid "Player Name:"
+msgstr ""
+
+#. Set icon preferences
+#: client/gtk/name.c:202
+msgid "Face:"
+msgstr ""
+
+#: client/gtk/name.c:217
+msgid "Variant:"
+msgstr ""
+
+#. Commandline option of client: name of the player
+#: client/gtk/offline.c:59
+msgid "Player name"
+msgstr ""
+
+#: client/gtk/offline.c:63
+msgid "Connect as a viewer"
+msgstr ""
+
+#: client/gtk/offline.c:66
+msgid "Meta-server Host"
+msgstr ""
+
+#: client/gtk/offline.c:70
+msgid "Override the language of the system"
+msgstr ""
+
+#: client/gtk/offline.c:100
+msgid "Connecting"
+msgstr ""
+
+#. Long description in the commandline for pioneers: help
+#: client/gtk/offline.c:175
+msgid "- Play a game of Pioneers"
+msgstr ""
+
+#: client/gtk/player.c:52
+msgid "Settlements"
+msgstr ""
+
+#: client/gtk/player.c:53
+msgid "Cities"
+msgstr ""
+
+#: client/gtk/player.c:54
+msgid "City Walls"
+msgstr ""
+
+#: client/gtk/player.c:55
+msgid "Largest Army"
+msgstr ""
+
+#: client/gtk/player.c:56
+msgid "Longest Road"
+msgstr ""
+
+#: client/gtk/player.c:57
+msgid "Chapels"
+msgstr ""
+
+#: client/gtk/player.c:58
+msgid "Pioneer Universities"
+msgstr ""
+
+#: client/gtk/player.c:60
+msgid "Governor's Houses"
+msgstr ""
+
+#: client/gtk/player.c:61
+msgid "Libraries"
+msgstr ""
+
+#: client/gtk/player.c:62
+msgid "Markets"
+msgstr ""
+
+#: client/gtk/player.c:63
+msgid "Soldiers"
+msgstr ""
+
+#: client/gtk/player.c:64
+msgid "Resource card"
+msgstr ""
+
+#: client/gtk/player.c:64
+msgid "Resource cards"
+msgstr ""
+
+#: client/gtk/player.c:65
+msgid "Development card"
+msgstr ""
+
+#: client/gtk/player.c:65
+msgid "Development cards"
+msgstr ""
+
+#. Caption for the overview of the points and card of other players
+#: client/gtk/player.c:561
+msgid "<b>Player Summary</b>"
+msgstr ""
+
+#: client/gtk/plenty.c:87
+msgid "Please choose one resource from the bank"
+msgstr ""
+
+#: client/gtk/plenty.c:90
+msgid "Please choose two resources from the bank"
+msgstr ""
+
+#: client/gtk/plenty.c:92
+msgid "The bank is empty"
+msgstr ""
+
+#: client/gtk/quote.c:186
+#, c-format
+msgid "%s has %s, and is looking for %s"
+msgstr ""
+
+#: client/gtk/quote.c:287
+msgid "I Want"
+msgstr ""
+
+#: client/gtk/quote.c:295
+msgid "Give Them"
+msgstr ""
+
+#: client/gtk/quote.c:311
+msgid "Delete"
+msgstr ""
+
+#: client/gtk/quote.c:335
+msgid "Reject Domestic Trade"
+msgstr ""
+
+#. Now create columns
+#. Table header: Player who trades
+#. Role of the player: player
+#: client/gtk/quote-view.c:170 server/gtk/main.c:513
+msgid "Player"
+msgstr ""
+
+#. Table header: Quote
+#: client/gtk/quote-view.c:185
+msgid "Quotes"
+msgstr ""
+
+#. trade: maritime quote: %1 resources of type %2 for
+#. * one resource of type %3
+#: client/gtk/quote-view.c:292
+#, c-format
+msgid "%d:1 %s for %s"
+msgstr ""
+
+#. Trade: a player has rejected trade
+#: client/gtk/quote-view.c:431
+msgid "Rejected trade"
+msgstr ""
+
+#. Caption for overview of the resources of the player
+#: client/gtk/resource.c:113
+msgid "<b>Resources</b>"
+msgstr ""
+
+#: client/gtk/resource.c:129
+msgid "Total"
+msgstr ""
+
+#. Tooltip for the amount of resources in the hand
+#: client/gtk/resource-table.c:187
+msgid "Amount in hand"
+msgstr ""
+
+#: client/gtk/resource-table.c:191
+msgid "<less"
+msgstr ""
+
+#. Tooltip for decreasing the selected amount
+#: client/gtk/resource-table.c:201
+msgid "Decrease the selected amount"
+msgstr ""
+
+#. Tooltip for the amount of resources in the bank
+#: client/gtk/resource-table.c:215
+msgid "Amount in the bank"
+msgstr ""
+
+#: client/gtk/resource-table.c:219
+msgid "more>"
+msgstr ""
+
+#. Tooltip for increasing the selected amount
+#: client/gtk/resource-table.c:231
+msgid "Increase the selected amount"
+msgstr ""
+
+#. Tooltip for the selected amount
+#: client/gtk/resource-table.c:248
+msgid "Selected amount"
+msgstr ""
+
+#. Tooltip for the total selected amount
+#: client/gtk/resource-table.c:293
+msgid "Total selected amount"
+msgstr ""
+
+#: client/gtk/resource-table.c:314
+msgid "The bank cannot be emptied"
+msgstr ""
+
+#: client/gtk/settingscreen.c:74
+msgid "Yes"
+msgstr ""
+
+#: client/gtk/settingscreen.c:76 client/gtk/settingscreen.c:207
+msgid "No"
+msgstr ""
+
+#: client/gtk/settingscreen.c:87 client/gtk/settingscreen.c:174
+msgid "Unknown"
+msgstr ""
+
+#: client/gtk/settingscreen.c:121
+msgid "No game in progress..."
+msgstr ""
+
+#: client/gtk/settingscreen.c:131
+msgid "<b>General Settings</b>"
+msgstr ""
+
+#: client/gtk/settingscreen.c:147
+msgid "Number of players:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:150
+msgid "Victory Point Target:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:153
+msgid "Random Terrain?"
+msgstr ""
+
+#: client/gtk/settingscreen.c:156
+msgid "Interplayer Trading Allowed?"
+msgstr ""
+
+#: client/gtk/settingscreen.c:160
+msgid "Trading allowed only before build/buy?"
+msgstr ""
+
+#: client/gtk/settingscreen.c:163
+msgid "Amount of Each Resource:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:177
+msgid "Sevens Rule:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:181
+msgid "Use Pirate:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:209
+msgid "Island Discovery Bonuses:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:224
+msgid "<b>Building Quotas</b>"
+msgstr ""
+
+#: client/gtk/settingscreen.c:241
+msgid "Roads:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:247
+msgid "Settlements:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:253
+msgid "Cities:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:259
+msgid "City Walls:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:265
+msgid "Ships:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:271
+msgid "Bridges:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:283
+msgid "<b>Development Card Deck</b>"
+msgstr ""
+
+#: client/gtk/settingscreen.c:299
+msgid "Road Building Cards:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:303
+msgid "Monopoly Cards:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:307
+msgid "Year of Plenty Cards:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:312
+msgid "Chapel Cards:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:316
+msgid "Pioneer University Cards:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:320
+msgid "Governor's House Cards:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:325
+msgid "Library Cards:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:329
+msgid "Market Cards:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:333
+msgid "Soldier Cards:"
+msgstr ""
+
+#: client/gtk/settingscreen.c:370
+msgid "Current Game Settings"
+msgstr ""
+
+#. trade: you ask for something for free
+#: client/gtk/trade.c:193
+#, c-format
+msgid "ask for %s for free"
+msgstr ""
+
+#. trade: you give something away for free
+#: client/gtk/trade.c:198
+#, c-format
+msgid "give %s for free"
+msgstr ""
+
+#. trade: you trade something for something else
+#: client/gtk/trade.c:203
+#, c-format
+msgid "give %s for %s"
+msgstr ""
+
+#. I want some resources, and give them some resources
+#: client/gtk/trade.c:230
+#, c-format
+msgid "I want %s, and give them %s"
+msgstr ""
+
+#. Frame title, trade: I want to trade these resources
+#: client/gtk/trade.c:427
+msgid "<b>I Want</b>"
+msgstr ""
+
+#. Frame title, trade: I want these resources in return
+#: client/gtk/trade.c:455
+msgid "<b>Give Them</b>"
+msgstr ""
+
+#. Button text, trade: call for quotes from other players
+#: client/gtk/trade.c:484
+msgid "_Call for Quotes"
+msgstr ""
+
+#. Button text: Trade page, accept selected quote
+#: client/gtk/trade.c:512
+msgid "_Accept Quote"
+msgstr ""
+
+#. Button text: Trade page, finish trading
+#: client/gtk/trade.c:518
+msgid "_Finish Trading"
+msgstr ""
+
+#: common/gtk/aboutbox.c:74
+msgid ""
+"Pioneers is based upon the excellent\n"
+"Settlers of Catan board game.\n"
+msgstr ""
+
+#: common/gtk/aboutbox.c:83
+msgid "Homepage"
+msgstr ""
+
+#: common/gtk/aboutbox.c:88
+msgid "Authors"
+msgstr ""
+
+#. Tooltip for sevens rule normal
+#: common/gtk/game-rules.c:101
+msgid "All sevens move the robber or pirate"
+msgstr ""
+
+#: common/gtk/game-rules.c:106
+msgid "In the first two turns all sevens are rerolled"
+msgstr ""
+
+#. Tooltip for sevens rule reroll all
+#: common/gtk/game-rules.c:110
+msgid "All sevens are rerolled"
+msgstr ""
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize Terrain"
+msgstr ""
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize the terrain"
+msgstr ""
+
+#: common/gtk/game-rules.c:123
+msgid "Use Pirate"
+msgstr ""
+
+#: common/gtk/game-rules.c:123
+msgid "Use the pirate to block ships"
+msgstr ""
+
+#: common/gtk/game-rules.c:125
+msgid "Strict Trade"
+msgstr ""
+
+#: common/gtk/game-rules.c:126
+msgid "Allow trade only before building or buying"
+msgstr ""
+
+#: common/gtk/game-rules.c:128
+msgid "Domestic Trade"
+msgstr ""
+
+#: common/gtk/game-rules.c:128
+msgid "Allow trade between players"
+msgstr ""
+
+#. Label text for customising a game
+#: common/gtk/game-settings.c:118
+msgid "Number of Players"
+msgstr ""
+
+#. Tooltip for 'Number of Players'
+#: common/gtk/game-settings.c:136
+msgid "The number of players"
+msgstr ""
+
+#. Label for customising a game
+#: common/gtk/game-settings.c:139
+msgid "Victory Point Target"
+msgstr ""
+
+#. Tooltip for Victory Point Target
+#: common/gtk/game-settings.c:159
+msgid "The points needed to win the game"
+msgstr ""
+
+#. Tooltip for the check button
+#: common/gtk/game-settings.c:172
+msgid "Is it possible to win this game?"
+msgstr ""
+
+#. Port indicator for a resource: trade 2 for 1
+#: common/gtk/guimap.c:750
+msgid "2:1"
+msgstr ""
+
+#. Port indicator: trade 3 for 1
+#. General port indicator
+#: common/gtk/guimap.c:753 common/gtk/guimap.c:778
+msgid "3:1"
+msgstr ""
+
+#. Tooltip for the list of games
+#: common/gtk/select-game.c:111
+msgid "Select a game"
+msgstr ""
+
+#: common/gtk/theme.c:709
+#, c-format
+msgid "bad scaling mode '%s'"
+msgstr ""
+
+#: common/game.c:603 common/game.c:633
+msgid "This game cannot be won."
+msgstr ""
+
+#: common/game.c:604
+msgid "There is no land."
+msgstr ""
+
+#: common/game.c:638
+msgid "It is possible that this game cannot be won."
+msgstr ""
+
+#: common/game.c:643
+msgid "This game can be won by only building all settlements and cities."
+msgstr ""
+
+#: common/game.c:650
+#, c-format
+msgid ""
+"Required victory points: %d\n"
+"Points obtained by building all: %d\n"
+"Points in development cards: %d\n"
+"Longest road/largest army: %d+%d\n"
+"Maximum island discovery bonus: %d\n"
+"Total: %d"
+msgstr ""
+
+#: common/log.c:54
+msgid "*ERROR* "
+msgstr ""
+
+#: common/log.c:60
+msgid "Chat: "
+msgstr ""
+
+#: common/log.c:63
+msgid "Resource: "
+msgstr ""
+
+#: common/log.c:66
+msgid "Build: "
+msgstr ""
+
+#: common/log.c:69
+msgid "Dice: "
+msgstr ""
+
+#: common/log.c:72
+msgid "Steal: "
+msgstr ""
+
+#: common/log.c:75
+msgid "Trade: "
+msgstr ""
+
+#: common/log.c:78
+msgid "Development: "
+msgstr ""
+
+#: common/log.c:81
+msgid "Army: "
+msgstr ""
+
+#: common/log.c:84
+msgid "Road: "
+msgstr ""
+
+#: common/log.c:87
+msgid "*BEEP* "
+msgstr ""
+
+#: common/log.c:92
+msgid "Player 1: "
+msgstr ""
+
+#: common/log.c:95
+msgid "Player 2: "
+msgstr ""
+
+#: common/log.c:98
+msgid "Player 3: "
+msgstr ""
+
+#: common/log.c:101
+msgid "Player 4: "
+msgstr ""
+
+#: common/log.c:104
+msgid "Player 5: "
+msgstr ""
+
+#: common/log.c:107
+msgid "Player 6: "
+msgstr ""
+
+#: common/log.c:110
+msgid "Player 7: "
+msgstr ""
+
+#: common/log.c:113
+msgid "Player 8: "
+msgstr ""
+
+#: common/log.c:116
+msgid "Viewer: "
+msgstr ""
+
+#: common/log.c:119
+msgid "** UNKNOWN MESSAGE TYPE ** "
+msgstr ""
+
+#: common/network.c:281
+#, c-format
+msgid "Error checking connect status: %s\n"
+msgstr ""
+
+#: common/network.c:288
+#, c-format
+msgid "Error connecting to host '%s': %s\n"
+msgstr ""
+
+#: common/network.c:314
+#, c-format
+msgid "Error writing socket: %s\n"
+msgstr ""
+
+#: common/network.c:365
+#, c-format
+msgid "Error writing to socket: %s\n"
+msgstr ""
+
+#: common/network.c:418
+msgid "Read buffer overflow - disconnecting\n"
+msgstr ""
+
+#: common/network.c:428
+#, c-format
+msgid "Error reading socket: %s\n"
+msgstr ""
+
+#: common/network.c:575
+#, c-format
+msgid "Cannot resolve %s port %s: %s\n"
+msgstr ""
+
+#: common/network.c:582
+#, c-format
+msgid "Cannot resolve %s port %s: host not found\n"
+msgstr ""
+
+#: common/network.c:597
+#, c-format
+msgid "Error creating socket: %s\n"
+msgstr ""
+
+#: common/network.c:605
+#, c-format
+msgid "Error setting socket close-on-exec: %s\n"
+msgstr ""
+
+#: common/network.c:615 common/network.c:776
+#, c-format
+msgid "Error setting socket non-blocking: %s\n"
+msgstr ""
+
+#: common/network.c:640
+#, c-format
+msgid "Error connecting to %s: %s\n"
+msgstr ""
+
+#: common/network.c:735
+#, c-format
+msgid "Error creating struct addrinfo: %s"
+msgstr ""
+
+#: common/network.c:765
+#, c-format
+msgid "Error creating listening socket: %s\n"
+msgstr ""
+
+#: common/network.c:785
+#, c-format
+msgid "Error during listen on socket: %s\n"
+msgstr ""
+
+#: common/network.c:794
+msgid "Listening not yet supported on this platform."
+msgstr ""
+
+#: common/network.c:816 common/network.c:817
+msgid "unknown"
+msgstr ""
+
+#: common/network.c:823
+#, c-format
+msgid "Error getting peer name: %s"
+msgstr ""
+
+#: common/network.c:836
+#, c-format
+msgid "Error resolving address: %s"
+msgstr ""
+
+#: common/network.c:850
+msgid "Net_get_peer_name not yet supported on this platform."
+msgstr ""
+
+#: common/network.c:865
+#, c-format
+msgid "Error accepting connection: %s"
+msgstr ""
+
+#: common/state.c:166
+#, c-format
+msgid "Connecting to %s, port %s\n"
+msgstr ""
+
+#: common/state.c:503
+msgid "State stack overflow. Stack dump sent to standard error.\n"
+msgstr ""
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:73
+msgid "_Hill"
+msgstr ""
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:75
+msgid "_Field"
+msgstr ""
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:77
+msgid "_Mountain"
+msgstr ""
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:79
+msgid "_Pasture"
+msgstr ""
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:81
+msgid "F_orest"
+msgstr ""
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:83
+msgid "_Desert"
+msgstr ""
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:85
+msgid "_Sea"
+msgstr ""
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:87
+msgid "_Gold"
+msgstr ""
+
+#. Use an unique shortcut key for each resource
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:89 editor/gtk/editor.c:104
+msgid "_None"
+msgstr ""
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:94
+msgid "_Brick (2:1)"
+msgstr ""
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:96
+msgid "_Grain (2:1)"
+msgstr ""
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:98
+msgid "_Ore (2:1)"
+msgstr ""
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:100
+msgid "_Wool (2:1)"
+msgstr ""
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:102
+msgid "_Lumber (2:1)"
+msgstr ""
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:106
+msgid "_Any (3:1)"
+msgstr ""
+
+#. East
+#: editor/gtk/editor.c:111
+msgid "East|E"
+msgstr ""
+
+#. North east
+#: editor/gtk/editor.c:113
+msgid "North East|NE"
+msgstr ""
+
+#. North west
+#: editor/gtk/editor.c:115
+msgid "North West|NW"
+msgstr ""
+
+#. West
+#: editor/gtk/editor.c:117
+msgid "West|W"
+msgstr ""
+
+#. South west
+#: editor/gtk/editor.c:119
+msgid "South West|SW"
+msgstr ""
+
+#. South east
+#: editor/gtk/editor.c:121
+msgid "South East|SE"
+msgstr ""
+
+#: editor/gtk/editor.c:564
+msgid "Shuffle"
+msgstr ""
+
+#: editor/gtk/editor.c:696 server/gtk/main.c:450
+msgid "Game Parameters"
+msgstr ""
+
+#: editor/gtk/editor.c:698 server/gtk/main.c:482
+msgid "Rules"
+msgstr ""
+
+#: editor/gtk/editor.c:699
+msgid "Resources"
+msgstr ""
+
+#: editor/gtk/editor.c:700
+msgid "Buildings"
+msgstr ""
+
+#: editor/gtk/editor.c:701
+msgid "Development Cards"
+msgstr ""
+
+#: editor/gtk/editor.c:718
+msgid "Pioneers Editor"
+msgstr ""
+
+#: editor/gtk/editor.c:803
+#, c-format
+msgid "Failed to load '%s'"
+msgstr ""
+
+#: editor/gtk/editor.c:843
+#, c-format
+msgid "Failed to save to '%s'"
+msgstr ""
+
+#: editor/gtk/editor.c:858
+msgid "Open Game"
+msgstr ""
+
+#: editor/gtk/editor.c:884
+msgid "Save as..."
+msgstr ""
+
+#: editor/gtk/editor.c:919
+msgid "Change Title"
+msgstr ""
+
+#: editor/gtk/editor.c:941
+msgid "New Title:"
+msgstr ""
+
+#: editor/gtk/editor.c:997
+msgid "Pioneers Game Editor"
+msgstr ""
+
+#: editor/gtk/editor.c:1001
+msgid "_File"
+msgstr ""
+
+#: editor/gtk/editor.c:1004
+msgid "_New"
+msgstr ""
+
+#: editor/gtk/editor.c:1005
+msgid "Create a new game"
+msgstr ""
+
+#: editor/gtk/editor.c:1006
+msgid "_Open..."
+msgstr ""
+
+#: editor/gtk/editor.c:1007
+msgid "Open an existing game"
+msgstr ""
+
+#: editor/gtk/editor.c:1008
+msgid "_Save"
+msgstr ""
+
+#: editor/gtk/editor.c:1009
+msgid "Save game"
+msgstr ""
+
+#: editor/gtk/editor.c:1010
+msgid "Save _As..."
+msgstr ""
+
+#: editor/gtk/editor.c:1012
+msgid "Save as"
+msgstr ""
+
+#: editor/gtk/editor.c:1013
+msgid "_Change title"
+msgstr ""
+
+#: editor/gtk/editor.c:1014
+msgid "Change game title"
+msgstr ""
+
+#: editor/gtk/editor.c:1015 server/gtk/main.c:100
+msgid "_Check Victory Point Target"
+msgstr ""
+
+#: editor/gtk/editor.c:1017 server/gtk/main.c:102
+msgid "Check whether the game can be won"
+msgstr ""
+
+#: editor/gtk/editor.c:1019
+msgid "Quit"
+msgstr ""
+
+#: editor/gtk/editor.c:1027
+msgid "_About Pioneers Editor"
+msgstr ""
+
+#: editor/gtk/editor.c:1028
+msgid "Information about Pioneers Editor"
+msgstr ""
+
+#. Long help for commandline option (editor): filename
+#: editor/gtk/editor.c:1066
+msgid "Open this file"
+msgstr ""
+
+#. Commandline option for editor: filename
+#: editor/gtk/editor.c:1068
+msgid "filename"
+msgstr ""
+
+#: editor/gtk/editor.c:1100
+msgid "- Editor for games of Pioneers"
+msgstr ""
+
+#: editor/gtk/editor.c:1141 server/gtk/main.c:1035
+#, c-format
+msgid "Building menus failed: %s"
+msgstr ""
+
+#: editor/gtk/editor.c:1169
+msgid "Settings"
+msgstr ""
+
+#: editor/gtk/game-resources.c:51
+msgid "Resource Count"
+msgstr ""
+
+#. Commandline meta-server: daemon
+#: meta-server/main.c:1033
+msgid "Daemonize the metaserver on start"
+msgstr ""
+
+#. Commandline meta-server: redirect
+#: meta-server/main.c:1036
+msgid "Redirect clients to another metaserver"
+msgstr ""
+
+#. Commandline meta-server: server
+#: meta-server/main.c:1039
+msgid "Use this hostname when creating new games"
+msgstr ""
+
+#. Commandline meta-server: server argument
+#: meta-server/main.c:1041
+msgid "hostname"
+msgstr ""
+
+#. Commandline meta-server: port-range
+#: meta-server/main.c:1044
+msgid "Use this ports range when creating new games"
+msgstr ""
+
+#. Commandline meta-server: port-range argument
+#: meta-server/main.c:1046
+msgid "from-to"
+msgstr ""
+
+#. Commandline option of meta server: syslog-debug
+#: meta-server/main.c:1052
+msgid "Debug syslog messages"
+msgstr ""
+
+#. Long description in the commandline for server-console: help
+#: meta-server/main.c:1073
+msgid "- Meta server for Pioneers"
+msgstr ""
+
+#: meta-server/main.c:1088
+#, c-format
+msgid "metaserver protocol:"
+msgstr ""
+
+#: server/gtk/main.c:105
+msgid "_About Pioneers Server"
+msgstr ""
+
+#: server/gtk/main.c:106
+msgid "Information about Pioneers Server"
+msgstr ""
+
+#: server/gtk/main.c:222
+msgid "Stop server"
+msgstr ""
+
+#: server/gtk/main.c:223
+msgid "Start server"
+msgstr ""
+
+#: server/gtk/main.c:225
+msgid "Stop the server"
+msgstr ""
+
+#: server/gtk/main.c:226
+msgid "Start the server"
+msgstr ""
+
+#: server/gtk/main.c:351
+#, c-format
+msgid "Player %s from %s entered\n"
+msgstr ""
+
+#: server/gtk/main.c:358
+#, c-format
+msgid "Player %s from %s left\n"
+msgstr ""
+
+#: server/gtk/main.c:365
+#, c-format
+msgid "Player %d is now %s\n"
+msgstr ""
+
+#: server/gtk/main.c:554
+msgid "Game Settings"
+msgstr ""
+
+#: server/gtk/main.c:600
+msgid "Server Parameters"
+msgstr ""
+
+#: server/gtk/main.c:626
+msgid "The port for the game server"
+msgstr ""
+
+#: server/gtk/main.c:629
+msgid "Register Server"
+msgstr ""
+
+#: server/gtk/main.c:637
+msgid "Register this game at the meta server"
+msgstr ""
+
+#: server/gtk/main.c:654
+msgid "The address of the meta server"
+msgstr ""
+
+#: server/gtk/main.c:656
+msgid "Reported Hostname"
+msgstr ""
+
+#: server/gtk/main.c:671
+msgid ""
+"The public name of this computer (needed when playing behind a firewall)"
+msgstr ""
+
+#: server/gtk/main.c:675
+msgid "Random Turn Order"
+msgstr ""
+
+#: server/gtk/main.c:683
+msgid "Randomize turn order"
+msgstr ""
+
+#: server/gtk/main.c:722
+msgid "Running Game"
+msgstr ""
+
+#: server/gtk/main.c:724
+msgid "Players Connected"
+msgstr ""
+
+#: server/gtk/main.c:758
+msgid "Shows all players and viewers connected to the server"
+msgstr ""
+
+#: server/gtk/main.c:763
+msgid "Connected"
+msgstr ""
+
+#: server/gtk/main.c:770
+msgid "Is the player currently connected?"
+msgstr ""
+
+#: server/gtk/main.c:773
+msgid "Name"
+msgstr ""
+
+#: server/gtk/main.c:780
+msgid "Name of the player"
+msgstr ""
+
+#: server/gtk/main.c:782
+msgid "Location"
+msgstr ""
+
+#: server/gtk/main.c:789
+msgid "Host name of the player"
+msgstr ""
+
+#: server/gtk/main.c:793
+msgid "Number"
+msgstr ""
+
+#: server/gtk/main.c:800
+msgid "Player number"
+msgstr ""
+
+#: server/gtk/main.c:804
+msgid "Role"
+msgstr ""
+
+#: server/gtk/main.c:808
+msgid "Player of viewer"
+msgstr ""
+
+#: server/gtk/main.c:819
+msgid "Launch Pioneers Client"
+msgstr ""
+
+#: server/gtk/main.c:826
+msgid "Launch the Pioneers Client"
+msgstr ""
+
+#: server/gtk/main.c:828
+msgid "Computer Players"
+msgstr ""
+
+#: server/gtk/main.c:837
+msgid "Enable Chat"
+msgstr ""
+
+#: server/gtk/main.c:843
+msgid "Enable chat messages"
+msgstr ""
+
+#: server/gtk/main.c:850
+msgid "Add Computer Player"
+msgstr ""
+
+#: server/gtk/main.c:857
+msgid "Add a computer player to the game"
+msgstr ""
+
+#: server/gtk/main.c:866
+msgid "Messages"
+msgstr ""
+
+#: server/gtk/main.c:884
+msgid "Messages from the server"
+msgstr ""
+
+#: server/gtk/main.c:932
+msgid "The Pioneers Game Server"
+msgstr ""
+
+#. Wait for all players to disconnect,
+#. * then enable the UI
+#.
+#: server/gtk/main.c:940
+msgid "The game is over.\n"
+msgstr ""
+
+#. Long description in the commandline for server-gtk: help
+#. Long description in the commandline for server-console: help
+#: server/gtk/main.c:994 server/main.c:174
+msgid "- Host a game of Pioneers"
+msgstr ""
+
+#. Name in the titlebar of the server
+#: server/gtk/main.c:1016
+msgid "Pioneers Server"
+msgstr ""
+
+#. Commandline server-console: game-title
+#: server/main.c:75
+msgid "Game title to use"
+msgstr ""
+
+#. Commandline server-console: file
+#: server/main.c:78
+msgid "Game file to use"
+msgstr ""
+
+#. Commandline server-console: port
+#: server/main.c:81
+msgid "Port to listen on"
+msgstr ""
+
+#. Commandline server-console: players
+#: server/main.c:84
+msgid "Override number of players"
+msgstr ""
+
+#. Commandline server-console: points
+#: server/main.c:87
+msgid "Override number of points needed to win"
+msgstr ""
+
+#. Commandline server-console: seven-rule
+#: server/main.c:90
+msgid "Override seven-rule handling"
+msgstr ""
+
+#. Commandline server-console: terrain
+#: server/main.c:93
+msgid "Override terrain type, 0=default 1=random"
+msgstr ""
+
+#. Commandline server-console: computer-players
+#: server/main.c:96
+msgid "Add N computer players"
+msgstr ""
+
+#. Commandline server-console: register
+#: server/main.c:106
+msgid "Register server with meta-server"
+msgstr ""
+
+#. Commandline server-console: meta-server
+#: server/main.c:109
+msgid "Register at meta-server name (implies -r)"
+msgstr ""
+
+#. Commandline server-console: hostname
+#: server/main.c:113
+msgid "Use this hostname when registering"
+msgstr ""
+
+#. Commandline server-console: auto-quit
+#: server/main.c:120
+msgid "Quit after a player has won"
+msgstr ""
+
+#. Commandline server-console: empty-timeout
+#: server/main.c:123
+msgid "Quit after N seconds with no players"
+msgstr ""
+
+#. Commandline server-console: tournament
+#: server/main.c:126
+msgid "Tournament mode, computer players added after N minutes"
+msgstr ""
+
+#. Commandline server-console: admin-port
+#: server/main.c:130
+msgid "Admin port to listen on"
+msgstr ""
+
+#: server/main.c:134
+msgid "Don't start game immediately, wait for a command on admin port"
+msgstr ""
+
+#: server/main.c:140
+msgid "Give players numbers according to the order they enter the game"
+msgstr ""
+
+#. Commandline server-console: Short description of meta group
+#: server/main.c:180
+msgid "Meta-server Options"
+msgstr ""
+
+#: server/main.c:183
+msgid "Options for the meta-server"
+msgstr ""
+
+#. Commandline server-console: Short description of misc group
+#: server/main.c:191
+msgid "Miscellaneous Options"
+msgstr ""
+
+#. Commandline server-console: Long description of misc group
+#: server/main.c:193
+msgid "Miscellaneous options"
+msgstr ""
+
+#: server/meta.c:193
+#, c-format
+msgid "Register with meta-server at %s, port %s\n"
+msgstr ""
+
+#: server/meta.c:210
+msgid "Unregister from meta-server\n"
+msgstr ""
+
+#: server/player.c:130
+msgid "chat too long"
+msgstr ""
+
+#: server/player.c:147
+msgid "name too long"
+msgstr ""
+
+#: server/player.c:179
+msgid "ignoring unknown extension"
+msgstr ""
+
+#: server/player.c:209
+msgid "Game starts, adding computer players"
+msgstr ""
+
+#: server/player.c:234
+#, c-format
+msgid "The game starts in %s minutes."
+msgstr ""
+
+#: server/player.c:235
+#, c-format
+msgid "The game starts in %s minute."
+msgstr ""
+
+#: server/player.c:280
+msgid "Sorry, game is over."
+msgstr ""
+
+#: server/player.c:283
+#, c-format
+msgid "Player from %s is refused: game is over\n"
+msgstr ""
+
+#: server/player.c:331
+msgid "This game will start soon."
+msgstr ""
+
+#: server/player.c:359
+msgid "Name not changed: new name is already in use"
+msgstr ""
+
+#. %s is the name of the reconnecting player
+#: server/player.c:648
+#, c-format
+msgid "%s has reconnected."
+msgstr ""
+
+#: server/player.c:776
+#, c-format
+msgid "Version mismatch: %s"
+msgstr ""
+
+#: server/server.c:47
+msgid "Was hanging around for too long without players... bye.\n"
+msgstr ""
+
+#. Server: preparing game #.....
+#: server/server.c:219
+msgid "Preparing game"
+msgstr ""
+
+#: server/server.c:337
+msgid "Missing game directory\n"
+msgstr ""
+
+#: server/turn.c:253
+msgid "Island Discovery Bonus"
+msgstr ""
+
+#: server/turn.c:256
+msgid "Additional Island Bonus"
+msgstr ""
+
+#: server/turn.c:388
+msgid "Tried to assign resources to NULL player.\n"
+msgstr ""
Added: trunk/po/sv.po
===================================================================
--- trunk/po/sv.po (rev 0)
+++ trunk/po/sv.po 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,3158 @@
+# Swedish translation of pioneers.
+# Copyright (C) 2005-2007 Daniel Nylander <po at danielnylander.se>
+# This file is distributed under the same license as the pioneers package.
+#
+# vim::set fileencoding=utf8
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Pioneers 0.11.3\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-07 20:43+0200\n"
+"PO-Revision-Date: 2007-07-16 20:54+0100\n"
+"Last-Translator: Daniel Nylander <po at danielnylander.se>\n"
+"Language-Team: Swedish <tp-sv at listor.tp-sv.se>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Default name for the AI when the computer_names file
+#. * is not found or empty.
+#.
+#: client/ai/ai.c:74 client/ai/ai.c:90
+msgid "Computer Player"
+msgstr "Datorspelare"
+
+#. Commandline pioneersai: server
+#. Commandline option of client: hostname of the server
+#: client/ai/ai.c:102 client/gtk/connect.c:1462 client/gtk/offline.c:53
+msgid "Server Host"
+msgstr "Servervärd"
+
+#. Commandline pioneersai: port
+#. Commandline option of client: port of the server
+#: client/ai/ai.c:105 client/gtk/connect.c:1478 client/gtk/offline.c:56
+#: server/gtk/main.c:612
+msgid "Server Port"
+msgstr "Serverport"
+
+#. Commandline pioneersai: name
+#: client/ai/ai.c:108
+msgid "Computer name (leave absent for random name)"
+msgstr "Datornamn (lämna blank för slumpmässigt namn)"
+
+#. Commandline pioneersai: time
+#: client/ai/ai.c:111
+msgid "Time to wait between turns (in milliseconds)"
+msgstr "Väntetid mellan turer (i millisekunder)"
+
+#. Commandline pioneersai: chat-free
+#: client/ai/ai.c:114
+msgid "Stop computer player from talking"
+msgstr "Stoppa datorspelare från att prata"
+
+#. Commandline pioneersai: algorithm
+#: client/ai/ai.c:117
+msgid "Type of computer player"
+msgstr "Typ av datorspelare"
+
+#. Commandline option of ai: enable debug logging
+#. Commandline option of client: enable debug logging
+#. Commandline option of meta server: enable debug logging
+#. Commandline option of server-gtk: enable debug logging
+#. Commandline option of server: enable debug logging
+#: client/ai/ai.c:120 client/gtk/offline.c:74 meta-server/main.c:1049
+#: server/gtk/main.c:952 server/main.c:144
+msgid "Enable debug messages"
+msgstr "Aktivera felsökningsmeddelanden"
+
+#. Commandline option of ai: version
+#. Commandline option of client: version
+#. Commandline option of editor: version
+#. Commandline option of meta server: version
+#. Commandline option of server-gtk: version
+#. Commandline option of server-console: version
+#: client/ai/ai.c:123 client/gtk/offline.c:77 editor/gtk/editor.c:1071
+#: meta-server/main.c:1055 server/gtk/main.c:955 server/main.c:99
+msgid "Show version information"
+msgstr "Visa versionsinformation"
+
+#: client/ai/ai.c:134
+msgid "- Computer player for Pioneers"
+msgstr "- Datorspelare för Pioneers"
+
+#: client/ai/ai.c:144 client/gtk/offline.c:186 editor/gtk/editor.c:1111
+#: meta-server/main.c:1084 server/gtk/main.c:1005 server/main.c:206
+#, c-format
+msgid "Pioneers version:"
+msgstr "Pioneers version:"
+
+#: client/ai/ai.c:176
+#, c-format
+msgid "Type of computer player: %s\n"
+msgstr "Typ av datorspelare: %s\n"
+
+#: client/ai/ai.c:205
+msgid "The game is already full. I'm leaving."
+msgstr "Spelet är redan fullt. Jag lämnar det."
+
+#: client/ai/greedy.c:941
+msgid "No settlements in stock to use for setup"
+msgstr "Inga bosättningar i lager att använda för detta"
+
+#: client/ai/greedy.c:948
+msgid "There is no place to setup a settlement"
+msgstr "Det finns ingen plats för att bygga en bosättning"
+
+#: client/ai/greedy.c:972
+msgid "No roads in stock to use for setup"
+msgstr "Inga vägar på lager att använda för detta"
+
+#: client/ai/greedy.c:989
+msgid "There is no place to setup a road"
+msgstr "Det finns ingen plats för att anlägga en väg"
+
+#: client/ai/greedy.c:1291
+msgid "Ok, let's go!"
+msgstr "Ok, nu kör vi!"
+
+#: client/ai/greedy.c:1292
+msgid "I'll beat you all now! ;)"
+msgstr "Jag slår er alla nu! ;)"
+
+#: client/ai/greedy.c:1293
+msgid "Now for another try..."
+msgstr "Ett nytt försök..."
+
+#: client/ai/greedy.c:1297
+msgid "At least I get something..."
+msgstr "Jag får något åtminstone..."
+
+#: client/ai/greedy.c:1298
+msgid "One is better than none..."
+msgstr "Ett är bättre än inget..."
+
+#: client/ai/greedy.c:1302
+msgid "Wow!"
+msgstr "Wow!"
+
+#: client/ai/greedy.c:1303
+msgid "Ey, I'm becoming rich ;)"
+msgstr "Tjo, Jag blir rikare ;)"
+
+#: client/ai/greedy.c:1304
+msgid "This is really a good year!"
+msgstr "Detta är verkligen ett bra år!"
+
+#: client/ai/greedy.c:1307
+msgid "You really don't deserve that much!"
+msgstr "Du är inte värd så mycket!"
+
+#: client/ai/greedy.c:1308
+msgid "You don't know what to do with that many resources ;)"
+msgstr "Du vet inte vad du ska göra med så många resurser ;)"
+
+#: client/ai/greedy.c:1309
+msgid "Ey, wait for my robber and lose all this again!"
+msgstr "Hey, vänta på min rånare och förlora allt detta igen!"
+
+#: client/ai/greedy.c:1312
+msgid "Hehe!"
+msgstr "Hehe!"
+
+#: client/ai/greedy.c:1313
+msgid "Go, robber, go!"
+msgstr "Kör på, rånare!"
+
+#: client/ai/greedy.c:1316
+msgid "You bastard!"
+msgstr "Din jäkel!"
+
+#: client/ai/greedy.c:1317
+msgid "Can't you move that robber somewhere else?!"
+msgstr "Kan du inte flytta den där rånaren någon annanstans?!"
+
+#: client/ai/greedy.c:1318
+msgid "Why always me??"
+msgstr "Varför är det alltid jag??"
+
+#: client/ai/greedy.c:1321
+msgid "Oh no!"
+msgstr "Ã
h nej!"
+
+#: client/ai/greedy.c:1322
+msgid "Grrr!"
+msgstr "Grrr!"
+
+#: client/ai/greedy.c:1323
+msgid "Who the hell rolled that 7??"
+msgstr "Vem i &/#\"(\" slog den 7:an??"
+
+#: client/ai/greedy.c:1324
+msgid "Why always me?!?"
+msgstr "Varför är det alltid jag??"
+
+#: client/ai/greedy.c:1327
+msgid "Say good bye to your cards... :)"
+msgstr "Säg adjö till dina kort... :)"
+
+#: client/ai/greedy.c:1328
+msgid "*evilgrin*"
+msgstr "*evilgrin*"
+
+#: client/ai/greedy.c:1329
+msgid "/me says farewell to your cards ;)"
+msgstr "/me säger adjö till dina kort ;)"
+
+#: client/ai/greedy.c:1330
+msgid "That's the price for being rich... :)"
+msgstr "Det är priset för att vara rik... :)"
+
+#: client/ai/greedy.c:1333
+msgid "Ey! Where's that card gone?"
+msgstr "Hey! Var tog det kortet vägen?"
+
+#: client/ai/greedy.c:1334
+msgid "Thieves! Thieves!!"
+msgstr "Tjuvar! Tjuvar!!"
+
+#: client/ai/greedy.c:1335
+msgid "Wait for my revenge..."
+msgstr "Vänta på min hämnd..."
+
+#: client/ai/greedy.c:1338
+msgid "Oh no :("
+msgstr "Ã
h nej :("
+
+#: client/ai/greedy.c:1339
+msgid "Must this happen NOW??"
+msgstr "Måste detta hända NU??"
+
+#: client/ai/greedy.c:1340
+msgid "Args"
+msgstr "Args"
+
+#: client/ai/greedy.c:1343
+msgid "Hehe, my soldiers rule!"
+msgstr "Hehe, mina soldater äger!"
+
+#: client/ai/greedy.c:1346
+msgid "First robbing us, then grabbing the points..."
+msgstr "Först råna oss sen sno åt sig poängen..."
+
+#: client/ai/greedy.c:1349
+msgid "See that road!"
+msgstr "Se på den vägen!"
+
+#: client/ai/greedy.c:1352
+msgid "Pf, you won't win with roads alone..."
+msgstr "Pfff, du vinner aldrig med bara vägar..."
+
+#: client/ai/greedy.c:1819
+msgid "Rejecting trade.\n"
+msgstr "Nekade handel.\n"
+
+#: client/ai/greedy.c:1911
+#, c-format
+msgid "Received error from server: %s. Quitting\n"
+msgstr "Mottog fel från server: %s. Avslutar\n"
+
+#: client/ai/greedy.c:1921
+msgid "Yippie!"
+msgstr "Jippi!"
+
+#: client/ai/greedy.c:1923
+msgid "My congratulations"
+msgstr "Mina gratulationer"
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:80
+msgid ""
+"Hello, welcome to the lobby. I am a simple robot. Type '/help' in the chat "
+"to see the list of commands I know."
+msgstr ""
+"Hej, välkommen till lobbyn. Jag är en enkel robot. Skriv \"/help\" i chatten "
+"för att se en lista på kommandon jag känner till."
+
+#. Translators: don't translate '/help'
+#: client/ai/lobbybot.c:107
+msgid "'/help' shows this message again"
+msgstr "\"/help\" visar detta meddelande igen"
+
+#. Translators: don't translate '/why'
+#: client/ai/lobbybot.c:110
+msgid "'/why' explains the purpose of this strange board layout"
+msgstr "\"/why\" förklarar meningen med denna konstiga brädlayout"
+
+#. Translators: don't translate '/news'
+#: client/ai/lobbybot.c:113
+msgid "'/news' tells the last released version"
+msgstr "\"/news\" talar om den senaste utgivna versionen"
+
+#: client/ai/lobbybot.c:118
+msgid ""
+"This board is not intended to be a game that can be played. Instead, players "
+"can find eachother here, and decide which board they want to play. Then, one "
+"of the players will host the proposed game by starting a server, and "
+"registers it at the metaserver. The other players can subsequently "
+"disconnect from the lobby, and enter that game."
+msgstr ""
+"Denna bräda är inte tänkt att vara ett spel som kan spelas. Istället kan "
+"spelare hitta varandra här, och bestämma vilken bräda de vill spela på. "
+"Sedan kan en av spelarna stå värd för det tänkta spelet genom att starta en "
+"server, och registrera den på metaservern. De andra spelarna kan därefter "
+"koppla ner från lobbyn, och ansluta till det spelet."
+
+#: client/ai/lobbybot.c:129
+msgid "The last released version of Pioneers is"
+msgstr "\"Den senaste utgivna versionen av Pioneers är"
+
+#: client/ai/lobbybot.c:144
+msgid "The game is starting. I'm not needed anymore. Goodbye."
+msgstr "Spelet startar. Jag behövs inte längre. Adjö."
+
+#: client/common/client.c:103
+msgid "Waiting"
+msgstr "Väntar"
+
+#: client/common/client.c:105 client/common/client.c:1241
+msgid "Idle"
+msgstr "Overksam"
+
+#: client/common/client.c:447
+msgid "We have been kicked out of the game.\n"
+msgstr "Vi har blivit utsparkade från spelet.\n"
+
+#. Network status: offline
+#: client/common/client.c:450 client/common/client.c:891 client/gtk/gui.c:1340
+msgid "Offline"
+msgstr "Offline"
+
+#: client/common/client.c:471
+#, c-format
+msgid "Error (%s): %s\n"
+msgstr "Fel (%s): %s\n"
+
+#: client/common/client.c:480 client/common/client.c:491
+#, c-format
+msgid "Notice: %s\n"
+msgstr "Notera: %s\n"
+
+#: client/common/client.c:607
+#, c-format
+msgid "%s does not receive any %s, because the bank is empty.\n"
+msgstr "%s tar inte emot några %s, därför att banken är tom.\n"
+
+#: client/common/client.c:620
+#, c-format
+msgid "%s only receives %s, because the bank didn't have any more.\n"
+msgstr "%s tar endast emot %s, därför att banken inte hade mer.\n"
+
+#: client/common/client.c:629
+#, c-format
+msgid "%s receives %s.\n"
+msgstr "%s tar emot %s.\n"
+
+#. Year of Plenty
+#: client/common/client.c:637 client/common/client.c:2586
+#, c-format
+msgid "%s takes %s.\n"
+msgstr "%s tar %s.\n"
+
+#: client/common/client.c:642
+#, c-format
+msgid "%s spent %s.\n"
+msgstr "%s spenderade %s.\n"
+
+#: client/common/client.c:648
+#, c-format
+msgid "%s is refunded %s.\n"
+msgstr "%s blir återbetalad %s.\n"
+
+#: client/common/client.c:679
+#, c-format
+msgid "%s discarded %s.\n"
+msgstr "%s kastade %s.\n"
+
+#: client/common/client.c:849
+msgid "Loading"
+msgstr "Läser in"
+
+#: client/common/client.c:892
+msgid "Version mismatch"
+msgstr "Version stämmer inte"
+
+#: client/common/client.c:894
+msgid "Version mismatch. Please make sure client and server are up to date.\n"
+msgstr ""
+"Versionen stämmer inte. Se till att klient och server är uppdaterade.\n"
+
+#: client/common/client.c:1340
+msgid "Build two settlements, each with a connecting"
+msgstr "Bygg två bosättningar, båda med en anslutande"
+
+#: client/common/client.c:1343
+msgid "Build a settlement with a connecting"
+msgstr "Bygg en bosättning med en anslutande"
+
+#: client/common/client.c:1346
+msgid "road"
+msgstr "väg"
+
+#: client/common/client.c:1348
+msgid "bridge"
+msgstr "bro"
+
+#: client/common/client.c:1350
+msgid "ship"
+msgstr "skepp"
+
+#: client/common/client.c:1358
+msgid " or"
+msgstr " eller"
+
+#: client/common/client.c:1416
+msgid "Waiting for your turn"
+msgstr "Väntar på din tur"
+
+#: client/common/client.c:1468
+msgid "Select the building to steal from."
+msgstr "Välj den byggnad du vill stjäla från."
+
+#: client/common/client.c:1490
+msgid "Select the ship to steal from."
+msgstr "Välj det skepp du vill stjäla från."
+
+#: client/common/client.c:1575 client/gtk/interface.c:782
+msgid "Place the robber"
+msgstr "Placera ut rånaren"
+
+#: client/common/client.c:1625
+msgid "Finish the road building action."
+msgstr "Gör klar vägbyggnationen."
+
+#: client/common/client.c:1627
+msgid "Build one road segment."
+msgstr "Bygg ett vägsegment."
+
+#: client/common/client.c:1629
+msgid "Build two road segments."
+msgstr "Bygg två vägsegment."
+
+#: client/common/client.c:1902 client/common/client.c:1996
+msgid "It is your turn."
+msgstr "Det är din tur."
+
+#: client/common/client.c:2090
+#, c-format
+msgid "Sorry, %s available.\n"
+msgstr "Tyvärr, %s tillgänglig.\n"
+
+#: client/common/client.c:2405
+msgid "The game is over."
+msgstr "Spelet är slut."
+
+#: client/common/develop.c:43 editor/gtk/game-devcards.c:13
+msgid "Road Building"
+msgstr "Vägbygge"
+
+#: client/common/develop.c:44 client/gtk/monopoly.c:83
+#: editor/gtk/game-devcards.c:13
+msgid "Monopoly"
+msgstr "Monopol"
+
+#: client/common/develop.c:45 client/gtk/plenty.c:59
+#: editor/gtk/game-devcards.c:13
+msgid "Year of Plenty"
+msgstr "Guldår"
+
+#: client/common/develop.c:46 client/gtk/player.c:57
+#: editor/gtk/game-devcards.c:14
+msgid "Chapel"
+msgstr "Kapell"
+
+#: client/common/develop.c:47 client/gtk/player.c:58
+#: editor/gtk/game-devcards.c:14
+msgid "Pioneer University"
+msgstr "Pioneer Universitet"
+
+#: client/common/develop.c:48 client/gtk/player.c:60
+#: editor/gtk/game-devcards.c:15
+msgid "Governor's House"
+msgstr "Guvernörens hus"
+
+#: client/common/develop.c:49 client/gtk/player.c:61
+#: editor/gtk/game-devcards.c:15
+msgid "Library"
+msgstr "Bibliotek"
+
+#: client/common/develop.c:50 client/gtk/player.c:62
+#: editor/gtk/game-devcards.c:15
+msgid "Market"
+msgstr "Marknad"
+
+#: client/common/develop.c:51 client/gtk/player.c:63
+#: editor/gtk/game-devcards.c:16
+msgid "Soldier"
+msgstr "Soldat"
+
+#: client/common/develop.c:82
+#, c-format
+msgid "You bought the %s development card.\n"
+msgstr "Du köpte utvecklingskortet för %s.\n"
+
+#: client/common/develop.c:88
+#, c-format
+msgid "You bought a %s development card.\n"
+msgstr "Du köpte ett utvecklingskort för %s.\n"
+
+#: client/common/develop.c:110
+#, c-format
+msgid "%s bought a development card.\n"
+msgstr "%s köpte ett utvecklingskort.\n"
+
+#: client/common/develop.c:129
+#, c-format
+msgid "%s played the %s development card.\n"
+msgstr "%s spelade utvecklingskortet för %s.\n"
+
+#: client/common/develop.c:134
+#, c-format
+msgid "%s played a %s development card.\n"
+msgstr "%s spelade ett utvecklingskort för %s.\n"
+
+#: client/common/develop.c:147
+msgid "You have run out of road segments.\n"
+msgstr "Du har slut på vägsegment.\n"
+
+#. I get the cards!
+#.
+#: client/common/develop.c:187
+#, c-format
+msgid "You get %s from %s.\n"
+msgstr "Du får %s från %s.\n"
+
+#. I lose the cards!
+#.
+#: client/common/develop.c:193
+#, c-format
+msgid "%s took %s from you.\n"
+msgstr "%s tog %s från dig.\n"
+
+#: client/common/develop.c:200
+#, c-format
+msgid "%s took %s from %s.\n"
+msgstr "%s tog %s från %s.\n"
+
+#: client/common/player.c:124 server/player.c:405
+#, c-format
+msgid "Viewer %d"
+msgstr "Ã
skådare %d"
+
+#: client/common/player.c:126
+#, c-format
+msgid "viewer %d"
+msgstr "åskådare %d"
+
+#: client/common/player.c:134 server/player.c:408
+#, c-format
+msgid "Player %d"
+msgstr "Spelare %d"
+
+#: client/common/player.c:136
+#, c-format
+msgid "player %d"
+msgstr "spelare %d"
+
+#: client/common/player.c:212
+#, c-format
+msgid "New viewer: %s.\n"
+msgstr "Ny åskådare: %s.\n"
+
+#: client/common/player.c:215 client/common/player.c:231
+#, c-format
+msgid "%s is now %s.\n"
+msgstr "%s är nu %s.\n"
+
+#: client/common/player.c:228
+#, c-format
+msgid "Player %d is now %s.\n"
+msgstr "Spelare %d är nu %s.\n"
+
+#: client/common/player.c:267
+#, c-format
+msgid "%s has quit\n"
+msgstr "%s har avslutat\n"
+
+#: client/common/player.c:276
+msgid "There is no largest army.\n"
+msgstr "Det finns ingen största armé.\n"
+
+#: client/common/player.c:279
+#, c-format
+msgid "%s has the largest army.\n"
+msgstr "%s har den största armén.\n"
+
+#: client/common/player.c:300
+msgid "There is no longest road.\n"
+msgstr "Det finns ingen längsta väg.\n"
+
+#: client/common/player.c:303
+#, c-format
+msgid "%s has the longest road.\n"
+msgstr "%s har den längsta vägen.\n"
+
+#: client/common/player.c:324
+#, c-format
+msgid "Waiting for %s."
+msgstr "Väntar på %s."
+
+#. We are not in on the action
+#. someone stole a resource from someone else
+#: client/common/player.c:352
+#, c-format
+msgid "%s stole a resource from %s.\n"
+msgstr "%s stal en resurs från %s.\n"
+
+#: client/common/player.c:362
+#, c-format
+msgid "You stole %s from %s.\n"
+msgstr "Du stal %s från %s.\n"
+
+#: client/common/player.c:368
+#, c-format
+msgid "%s stole %s from you.\n"
+msgstr "%s stal %s från dig.\n"
+
+#: client/common/player.c:402
+#, c-format
+msgid "%s gave %s nothing!?\n"
+msgstr "%s gav %s ingenting!?\n"
+
+#: client/common/player.c:408 client/common/player.c:416
+#, c-format
+msgid "%s gave %s %s for free.\n"
+msgstr "%s gav %s %s gratis.\n"
+
+#: client/common/player.c:424
+#, c-format
+msgid "%s gave %s %s in exchange for %s.\n"
+msgstr "%s gav %s %s i utbyte mot %s.\n"
+
+#: client/common/player.c:455
+#, c-format
+msgid "%s exchanged %s for %s.\n"
+msgstr "%s utbytte %s mot %s.\n"
+
+#: client/common/player.c:475
+#, c-format
+msgid "%s built a road.\n"
+msgstr "%s byggde en väg.\n"
+
+#: client/common/player.c:487
+#, c-format
+msgid "%s built a ship.\n"
+msgstr "%s byggde ett skepp.\n"
+
+#: client/common/player.c:500
+#, c-format
+msgid "%s built a settlement.\n"
+msgstr "%s byggde en bosättning.\n"
+
+#: client/common/player.c:519
+#, c-format
+msgid "%s built a city.\n"
+msgstr "%s byggde en stad.\n"
+
+#: client/common/player.c:533
+#, c-format
+msgid "%s built a city wall.\n"
+msgstr "%s byggde en stadsmur.\n"
+
+#: client/common/player.c:544
+#, c-format
+msgid "player_build_add called with BUILD_NONE for user %s\n"
+msgstr "player_build_add anropades med BUILD_NONE för användare %s\n"
+
+#: client/common/player.c:553
+#, c-format
+msgid "%s built a bridge.\n"
+msgstr "%s byggde en bro.\n"
+
+#: client/common/player.c:579
+#, c-format
+msgid "%s removed a road.\n"
+msgstr "%s tog bort en väg.\n"
+
+#: client/common/player.c:589
+#, c-format
+msgid "%s removed a ship.\n"
+msgstr "%s tog bort ett skepp.\n"
+
+#: client/common/player.c:599
+#, c-format
+msgid "%s removed a settlement.\n"
+msgstr "%s tog bort en bosättning.\n"
+
+#: client/common/player.c:610
+#, c-format
+msgid "%s removed a city.\n"
+msgstr "%s tog bort en stad.\n"
+
+#: client/common/player.c:624
+#, c-format
+msgid "%s removed a city wall.\n"
+msgstr "%s tog bort en stadsmur.\n"
+
+#: client/common/player.c:634
+#, c-format
+msgid "player_build_remove called with BUILD_NONE for user %s\n"
+msgstr "player_build_remove anropades med BUILD_NONE för användare %s\n"
+
+#: client/common/player.c:642
+#, c-format
+msgid "%s removed a bridge.\n"
+msgstr "%s tog bort en bro.\n"
+
+#: client/common/player.c:673
+#, c-format
+msgid "%s has cancelled a ship's movement.\n"
+msgstr "%s har avbrutit flyttning av ett skepp.\n"
+
+#: client/common/player.c:676
+#, c-format
+msgid "%s moved a ship.\n"
+msgstr "%s flyttade ett skepp.\n"
+
+#. tell the user that someone got something
+#: client/common/player.c:696
+#, c-format
+msgid "%s received %s.\n"
+msgstr "%s mottog %s.\n"
+
+#: client/common/player.c:714
+msgid "server asks to lose invalid point.\n"
+msgstr "server frågar om att förlora ogiltig poäng.\n"
+
+#. tell the user the point is lost
+#: client/common/player.c:720
+#, c-format
+msgid "%s lost %s.\n"
+msgstr "%s förlorade %s.\n"
+
+#: client/common/player.c:743
+msgid "server asks to move invalid point.\n"
+msgstr "server frågar om att flytta ogiltig poäng.\n"
+
+#. tell the user someone (1) lost something (2) to someone else (3)
+#: client/common/player.c:750
+#, c-format
+msgid "%s lost %s to %s.\n"
+msgstr "%s förlorade %s till %s.\n"
+
+#: client/common/resource.c:35
+msgid "brick"
+msgstr "tegel"
+
+#: client/common/resource.c:35
+msgid "Brick"
+msgstr "Tegel"
+
+#: client/common/resource.c:36
+msgid "grain"
+msgstr "spannmål"
+
+#: client/common/resource.c:36
+msgid "Grain"
+msgstr "Spannmål"
+
+#: client/common/resource.c:37
+msgid "ore"
+msgstr "malm"
+
+#: client/common/resource.c:37
+msgid "Ore"
+msgstr "Malm"
+
+#: client/common/resource.c:38
+msgid "wool"
+msgstr "ull"
+
+#: client/common/resource.c:38
+msgid "Wool"
+msgstr "Ull"
+
+#: client/common/resource.c:39
+msgid "lumber"
+msgstr "timmer"
+
+#: client/common/resource.c:39
+msgid "Lumber"
+msgstr "Timmer"
+
+#: client/common/resource.c:40
+msgid "no resource (bug)"
+msgstr "ingen resurs (fel)"
+
+#: client/common/resource.c:40
+msgid "No resource (bug)"
+msgstr "Ingen resurs (fel)"
+
+#: client/common/resource.c:41
+msgid "any resource (bug)"
+msgstr "någon resurs (fel)"
+
+#: client/common/resource.c:41
+msgid "Any resource (bug)"
+msgstr "NÃ¥gon resurs (fel)"
+
+#: client/common/resource.c:42
+msgid "gold"
+msgstr "guld"
+
+#: client/common/resource.c:42 client/gtk/legend.c:39
+msgid "Gold"
+msgstr "Guld"
+
+#: client/common/resource.c:47
+msgid "a brick card"
+msgstr "ett tegelkort"
+
+#: client/common/resource.c:47
+#, c-format
+msgid "%d brick cards"
+msgstr "%d tegelkort"
+
+#: client/common/resource.c:48
+msgid "a grain card"
+msgstr "ett spannmålskort"
+
+#: client/common/resource.c:48
+#, c-format
+msgid "%d grain cards"
+msgstr "%d spannmålskort"
+
+#: client/common/resource.c:49
+msgid "an ore card"
+msgstr "ett malmkort"
+
+#: client/common/resource.c:49
+#, c-format
+msgid "%d ore cards"
+msgstr "%d malmkort"
+
+#: client/common/resource.c:50
+msgid "a wool card"
+msgstr "ett ullkort"
+
+#: client/common/resource.c:50
+#, c-format
+msgid "%d wool cards"
+msgstr "%d ullkort"
+
+#: client/common/resource.c:51
+msgid "a lumber card"
+msgstr "ett timmerkort"
+
+#: client/common/resource.c:51
+#, c-format
+msgid "%d lumber cards"
+msgstr "%d timmerkort"
+
+#: client/common/resource.c:139 client/common/resource.c:225
+msgid "nothing"
+msgstr "ingenting"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:166
+#, c-format
+msgid "%s and %s"
+msgstr "%s och %s"
+
+#. Construct "A, B and C" for resources
+#: client/common/resource.c:170
+#, c-format
+msgid "%s, %s"
+msgstr "%s, %s"
+
+#: client/common/robber.c:60
+#, c-format
+msgid "%s has undone the robber movement.\n"
+msgstr "%s har ångrat förflyttningen av rånaren.\n"
+
+#: client/common/robber.c:63
+#, c-format
+msgid "%s moved the robber.\n"
+msgstr "%s flyttade rånaren.\n"
+
+#: client/common/robber.c:73
+#, c-format
+msgid "%s has undone the pirate movement.\n"
+msgstr "%s har ångrat förflyttning av piraten.\n"
+
+#: client/common/robber.c:76
+#, c-format
+msgid "%s moved the pirate.\n"
+msgstr "%s flyttade piraten.\n"
+
+#: client/common/robber.c:83
+#, c-format
+msgid "%s must move the robber."
+msgstr "%s måste flytta rånaren."
+
+#: client/common/setup.c:140
+#, c-format
+msgid "Setup for %s.\n"
+msgstr "Uppställning för %s.\n"
+
+#: client/common/setup.c:152
+#, c-format
+msgid "Double setup for %s.\n"
+msgstr "Dubbel uppställning för %s.\n"
+
+#: client/common/turn.c:37
+#, c-format
+msgid "%s rolled %d.\n"
+msgstr "%s slog %d.\n"
+
+#: client/common/turn.c:50
+#, c-format
+msgid "Begin turn %d for %s.\n"
+msgstr "Börja tur %d för %s.\n"
+
+#: client/gtk/chat.c:71
+msgid "<b>Chat</b>"
+msgstr "<b>Chatt</b>"
+
+#: client/gtk/chat.c:231
+msgid "Beeper test.\n"
+msgstr "Testa pip.\n"
+
+#: client/gtk/chat.c:234
+#, c-format
+msgid "%s beeped you.\n"
+msgstr "%s pingade dig.\n"
+
+#: client/gtk/chat.c:238
+#, c-format
+msgid "You beeped %s.\n"
+msgstr "Du pingade %s.\n"
+
+#: client/gtk/chat.c:244
+#, c-format
+msgid "You could not beep %s.\n"
+msgstr "Du kunde inte skicka ett pip till %s.\n"
+
+#: client/gtk/chat.c:288
+msgid " said: "
+msgstr " säger: "
+
+#: client/gtk/connect.c:282
+#, c-format
+msgid "Meta-server at %s, port %s"
+msgstr "Metaserver på %s, port %s"
+
+#: client/gtk/connect.c:292
+msgid "Finished.\n"
+msgstr "Klar.\n"
+
+#: client/gtk/connect.c:309 client/gtk/connect.c:359 client/gtk/connect.c:456
+#: server/meta.c:174
+msgid "Meta-server kicked us off\n"
+msgstr "Metaserver sparkade ut oss\n"
+
+#: client/gtk/connect.c:334
+msgid "Receiving game names from the meta server.\n"
+msgstr "Tar emot spelnamn från metaservern.\n"
+
+#: client/gtk/connect.c:382
+#, c-format
+msgid "New game server requested on %s port %s\n"
+msgstr "Ny spelserver begärd på %s port %s\n"
+
+#: client/gtk/connect.c:391 server/meta.c:168
+#, c-format
+msgid "Unknown message from the metaserver: %s\n"
+msgstr "Okänt meddelande från metaservern: %s\n"
+
+#: client/gtk/connect.c:472 server/meta.c:125
+msgid "Too many meta-server redirects\n"
+msgstr "För många omdirigeringar för metaserver\n"
+
+#: client/gtk/connect.c:499 server/meta.c:140
+#, c-format
+msgid "Bad redirect line: %s\n"
+msgstr "Felaktig rad för omdirigering: %s\n"
+
+#: client/gtk/connect.c:525
+#, c-format
+msgid "Meta server too old to create servers (version %d.%d)\n"
+msgstr "Metaserver för gammal för att skapa servrar (version %d.%d)\n"
+
+#. Sevens rule: normal
+#: client/gtk/connect.c:596 client/gtk/settingscreen.c:168
+#: common/gtk/game-rules.c:81
+msgid "Normal"
+msgstr "Normal"
+
+#: client/gtk/connect.c:602 client/gtk/settingscreen.c:170
+#: common/gtk/game-rules.c:88
+msgid "Reroll on 1st 2 turns"
+msgstr "Slå om på de första 2 turerna"
+
+#: client/gtk/connect.c:605 client/gtk/settingscreen.c:172
+#: common/gtk/game-rules.c:95
+msgid "Reroll all 7s"
+msgstr "Slå om alla 7:or"
+
+#: client/gtk/connect.c:619
+msgid "Default"
+msgstr "Förvald"
+
+#: client/gtk/connect.c:622
+msgid "Random"
+msgstr "Slumpad"
+
+#: client/gtk/connect.c:653 server/meta.c:188
+#, c-format
+msgid "Redirected to meta-server at %s, port %s\n"
+msgstr "Omdirigerad till metaserver på %s, port %s\n"
+
+#: client/gtk/connect.c:656
+msgid "Receiving a list of Pioneers servers from the meta server.\n"
+msgstr "Tar emot en lista av Pioneers-servrar från metaservern.\n"
+
+#: client/gtk/connect.c:713
+msgid ""
+"<b>Note</b>:\n"
+"\tThe metaserver does not send information about the games.\n"
+"\tPlease set appropriate values yourself."
+msgstr ""
+"<b>Notera</b>:\n"
+"\tMetaservern skickar inte information om spelen.\n"
+"\tStäll in lämpliga värden själv."
+
+#: client/gtk/connect.c:730
+msgid "Number of AI Players"
+msgstr "Antal AI-spelare"
+
+#: client/gtk/connect.c:749
+msgid "The number of AI players"
+msgstr "Antalet AI-spelare"
+
+#: client/gtk/connect.c:770
+msgid "Requesting new game server\n"
+msgstr "Begär en ny spelserver\n"
+
+#: client/gtk/connect.c:813 server/gtk/main.c:328 server/server.c:160
+#, c-format
+msgid "Error starting %s: %s"
+msgstr "Fel vid start av %s: %s"
+
+#: client/gtk/connect.c:834
+msgid "Create a public game"
+msgstr "Skapa ett publikt spel"
+
+#: client/gtk/connect.c:965 client/gtk/connect.c:1268
+msgid "Join a public game"
+msgstr "GÃ¥ in i ett publikt spel"
+
+#: client/gtk/connect.c:970
+msgid "_New remote game"
+msgstr "_Nytt fjärrspel"
+
+#: client/gtk/connect.c:984
+msgid "Refresh the list of games"
+msgstr "Uppdatera listan av spel"
+
+#: client/gtk/connect.c:989
+msgid "Create a new public game at the meta server"
+msgstr "Skapa ett nytt publikt spel på metaservern"
+
+#: client/gtk/connect.c:994
+msgid "Don't join a public game"
+msgstr "GÃ¥ inte in i ett publikt spel"
+
+#: client/gtk/connect.c:998
+msgid "Join the selected game"
+msgstr "GÃ¥ in i valt spel"
+
+#: client/gtk/connect.c:1033
+msgid "Select a game to join"
+msgstr "Välj ett spel att gå in i"
+
+#: client/gtk/connect.c:1036
+msgid "Map Name"
+msgstr "Kartnamn"
+
+#: client/gtk/connect.c:1044
+msgid "Name of the game"
+msgstr "Spelets namn"
+
+#: client/gtk/connect.c:1049
+msgid "Curr"
+msgstr "Nuvar"
+
+#: client/gtk/connect.c:1055
+msgid "Number of players in the game"
+msgstr "Antal spelare i spelet"
+
+#: client/gtk/connect.c:1060
+msgid "Max"
+msgstr "Max"
+
+#: client/gtk/connect.c:1066
+msgid "Maximum players for the game"
+msgstr "Max antal spelare för spelet"
+
+#: client/gtk/connect.c:1069
+msgid "Terrain"
+msgstr "Terräng"
+
+#: client/gtk/connect.c:1076
+msgid "Random of default terrain"
+msgstr "Slumpmässig standardterräng"
+
+#: client/gtk/connect.c:1081
+msgid "Vic. Points"
+msgstr "Segerpoäng"
+
+#: client/gtk/connect.c:1087
+msgid "Points needed to win"
+msgstr "Poäng för vinst"
+
+#: client/gtk/connect.c:1090 common/gtk/game-rules.c:73
+msgid "Sevens Rule"
+msgstr "Regel för 7:an"
+
+#: client/gtk/connect.c:1096
+msgid "Sevens rule"
+msgstr "Regel för 7:an"
+
+#: client/gtk/connect.c:1100
+msgid "Host"
+msgstr "Värd"
+
+#: client/gtk/connect.c:1108
+msgid "Host of the game"
+msgstr "Värd för spelet"
+
+#: client/gtk/connect.c:1113
+msgid "Port"
+msgstr "Port"
+
+#: client/gtk/connect.c:1119
+msgid "Port of the the game"
+msgstr "Port för spelet"
+
+#: client/gtk/connect.c:1122 common/gtk/aboutbox.c:77
+msgid "Version"
+msgstr "Version"
+
+#: client/gtk/connect.c:1129
+msgid "Version of the host"
+msgstr "Version hos värden"
+
+#: client/gtk/connect.c:1184 client/gtk/gui.c:215
+msgid "Start a new game"
+msgstr "Starta ett nytt spel"
+
+#: client/gtk/connect.c:1209
+msgid "Player Name"
+msgstr "Spelarens namn"
+
+#: client/gtk/connect.c:1223
+msgid "Enter your name"
+msgstr "Ange ditt namn"
+
+#. Role of the player: viewer
+#: client/gtk/connect.c:1225 server/gtk/main.c:511
+msgid "Viewer"
+msgstr "Ã
skådare"
+
+#: client/gtk/connect.c:1233
+msgid "Do you want to be a viewer?"
+msgstr "Vill du vara en åskådare?"
+
+#: client/gtk/connect.c:1240 server/gtk/main.c:640
+msgid "Meta Server"
+msgstr "Metaserver"
+
+#: client/gtk/connect.c:1255
+msgid "Leave empty for the default meta server"
+msgstr "Lämna blank för den förvalda metaservern"
+
+#: client/gtk/connect.c:1263
+msgid "Join public game"
+msgstr "GÃ¥ in i ett publikt spel"
+
+#: client/gtk/connect.c:1272
+msgid "Create game"
+msgstr "Skapa spel"
+
+#: client/gtk/connect.c:1275
+msgid "Create a game"
+msgstr "Skapa ett spel"
+
+#: client/gtk/connect.c:1285
+msgid "Join private game"
+msgstr "GÃ¥ in i privat spel"
+
+#: client/gtk/connect.c:1289 client/gtk/connect.c:1434
+msgid "Join a private game"
+msgstr "GÃ¥ in i ett privat spel"
+
+#: client/gtk/connect.c:1475
+msgid "Name of the host of the game"
+msgstr "Namn på värden som kör spelet"
+
+#: client/gtk/connect.c:1494
+msgid "Port of the host of the game"
+msgstr "Port på värden som kör spelet"
+
+#: client/gtk/connect.c:1534
+msgid "Recent games"
+msgstr "Tidigare spel"
+
+#: client/gtk/connect.c:1536
+msgid "Recent Games"
+msgstr "Tidigare spel"
+
+#: client/gtk/develop.c:129
+msgid "<b>Development Cards</b>"
+msgstr "<b>Utvecklingskort</b>"
+
+#: client/gtk/develop.c:160
+msgid "Play Card"
+msgstr "Spela kort"
+
+#: client/gtk/discard.c:76
+msgid "Discard resources"
+msgstr "Kasta resurser"
+
+#: client/gtk/discard.c:96
+#, c-format
+msgid "You must discard %d resources"
+msgstr "Du måste kasta %d resurser"
+
+#: client/gtk/discard.c:101
+msgid "Total discards"
+msgstr "Totala kastningar"
+
+#. Caption for list of player that must discard cards
+#: client/gtk/discard.c:226
+msgid "<b>Waiting for players to discard</b>"
+msgstr "<b>Väntar på att spelare ska kasta</b>"
+
+#: client/gtk/gameover.c:32
+msgid "Game over"
+msgstr "Spelet är över"
+
+#: client/gtk/gameover.c:49
+#, c-format
+msgid "%s has won the game with %d victory points!"
+msgstr "%s har vunnit spelet med %d segerpoäng!"
+
+#: client/gtk/gameover.c:52
+#, c-format
+msgid "%s has won the game with %d victory points!\n"
+msgstr "%s har vunnit spelet med %d segerpoäng!\n"
+
+#: client/gtk/gameover.c:58
+#, c-format
+msgid "All praise %s, Lord of the known world!"
+msgstr "Länge leve %s, Härskare över världen!"
+
+#: client/gtk/gold.c:71
+msgid "Choose resources"
+msgstr "Välj resurser"
+
+#: client/gtk/gold.c:92
+#, c-format
+msgid "You may choose 1 resource"
+msgstr "Du får välja 1 resurs"
+
+#: client/gtk/gold.c:94
+#, c-format
+msgid "You may choose %d resources"
+msgstr "Du får välja %d resurser"
+
+#. Text for total in choose gold dialog
+#. Text for total in year of plenty dialog
+#: client/gtk/gold.c:101 client/gtk/plenty.c:98
+msgid "Total resources"
+msgstr "Totala resurser"
+
+#: client/gtk/gold.c:213
+msgid "<b>Waiting for players to choose</b>"
+msgstr "<b>Väntar på att spelare ska välja</b>"
+
+#: client/gtk/gui.c:213 server/gtk/main.c:98
+msgid "_Game"
+msgstr "_Spel"
+
+#: client/gtk/gui.c:214
+msgid "_New game"
+msgstr "_Nytt spel"
+
+#: client/gtk/gui.c:216
+msgid "_Leave game"
+msgstr "_Lämna spel"
+
+#: client/gtk/gui.c:217
+msgid "Leave this game"
+msgstr "Lämna detta spel"
+
+#: client/gtk/gui.c:219
+msgid "_Admin"
+msgstr "_Administrera"
+
+#: client/gtk/gui.c:220
+msgid "Administer Pioneers server"
+msgstr "Administrera Pioneers-servern"
+
+#: client/gtk/gui.c:222
+msgid "_Player name"
+msgstr "_Spelarnamn"
+
+#: client/gtk/gui.c:223
+msgid "Change your player name"
+msgstr "Ãndra ditt spelarnamn"
+
+#: client/gtk/gui.c:224
+msgid "_Legend"
+msgstr "_Förklaring"
+
+#: client/gtk/gui.c:225
+msgid "Terrain legend and building costs"
+msgstr "Terrängförklaring och byggnadskostnader"
+
+#: client/gtk/gui.c:226
+msgid "_Game Settings"
+msgstr "S_pelinställningar"
+
+#: client/gtk/gui.c:227
+msgid "Settings for the current game"
+msgstr "Inställningar för nuvarande spel"
+
+#: client/gtk/gui.c:228
+msgid "_Dice Histogram"
+msgstr "_Tärningshistogram"
+
+#: client/gtk/gui.c:229
+msgid "Histogram of dice rolls"
+msgstr "Histogram för tärningskast"
+
+#: client/gtk/gui.c:230 editor/gtk/editor.c:1018 server/gtk/main.c:103
+msgid "_Quit"
+msgstr "_Avsluta"
+
+#: client/gtk/gui.c:231 server/gtk/main.c:104
+msgid "Quit the program"
+msgstr "Avsluta programmet"
+
+#: client/gtk/gui.c:232
+msgid "_Actions"
+msgstr "_Ã
tgärder"
+
+#: client/gtk/gui.c:233
+msgid "Roll Dice"
+msgstr "Kasta tärning"
+
+#: client/gtk/gui.c:234
+msgid "Roll the dice"
+msgstr "Kasta tärningen"
+
+#. Tab page name
+#: client/gtk/gui.c:235 client/gtk/gui.c:577
+msgid "Trade"
+msgstr "Handla"
+
+#: client/gtk/gui.c:237
+msgid "Undo"
+msgstr "Ã
ngra"
+
+#: client/gtk/gui.c:238 client/gtk/gui.c:239
+msgid "Finish"
+msgstr "Klar"
+
+#: client/gtk/gui.c:240 client/gtk/legend.c:226 editor/gtk/game-buildings.c:13
+msgid "Road"
+msgstr "Väg"
+
+#: client/gtk/gui.c:241
+msgid "Build a road"
+msgstr "Bygg en väg"
+
+#: client/gtk/gui.c:242 client/gtk/legend.c:230 editor/gtk/game-buildings.c:13
+msgid "Ship"
+msgstr "Skepp"
+
+#: client/gtk/gui.c:243
+msgid "Build a ship"
+msgstr "Bygg ett skepp"
+
+#: client/gtk/gui.c:244
+msgid "Move Ship"
+msgstr "Flytta skepp"
+
+#: client/gtk/gui.c:245
+msgid "Move a ship"
+msgstr "Flytta ett skepp"
+
+#: client/gtk/gui.c:246 client/gtk/legend.c:233 editor/gtk/game-buildings.c:13
+msgid "Bridge"
+msgstr "Bro"
+
+#: client/gtk/gui.c:247
+msgid "Build a bridge"
+msgstr "Bygg en bro"
+
+#: client/gtk/gui.c:248 client/gtk/legend.c:235 client/gtk/player.c:52
+#: editor/gtk/game-buildings.c:13
+msgid "Settlement"
+msgstr "Bosättning"
+
+#: client/gtk/gui.c:249
+msgid "Build a settlement"
+msgstr "Bygg en bosättning"
+
+#: client/gtk/gui.c:250 client/gtk/legend.c:236 client/gtk/player.c:53
+#: editor/gtk/game-buildings.c:14
+msgid "City"
+msgstr "Stad"
+
+#: client/gtk/gui.c:251
+msgid "Build a city"
+msgstr "Bygg en stad"
+
+#: client/gtk/gui.c:252
+msgid "Develop"
+msgstr "Utveckla"
+
+#: client/gtk/gui.c:253
+msgid "Buy a development card"
+msgstr "Köp ett utvecklingskort"
+
+#: client/gtk/gui.c:254 client/gtk/legend.c:240 client/gtk/player.c:54
+#: editor/gtk/game-buildings.c:14
+msgid "City Wall"
+msgstr "Stadsmur"
+
+#: client/gtk/gui.c:255
+msgid "Build a city wall"
+msgstr "Bygg en stadsmur"
+
+#: client/gtk/gui.c:257
+msgid "_Settings"
+msgstr "_Inställningar"
+
+#: client/gtk/gui.c:258
+msgid "Prefere_nces"
+msgstr "Inställ_ningar"
+
+#: client/gtk/gui.c:259
+msgid "Configure the application"
+msgstr "Konfigurera programmet"
+
+#: client/gtk/gui.c:261 client/gtk/gui.c:265 editor/gtk/editor.c:1002
+#: server/gtk/main.c:99
+msgid "_Help"
+msgstr "_Hjälp"
+
+#: client/gtk/gui.c:262
+msgid "_About Pioneers"
+msgstr "_Om Pioneers"
+
+#: client/gtk/gui.c:263
+msgid "Information about Pioneers"
+msgstr "Information om Pioneers"
+
+#: client/gtk/gui.c:266 client/gtk/gui.c:1065
+msgid "Show the manual"
+msgstr "Visa manualen"
+
+#: client/gtk/gui.c:272
+msgid "_Toolbar"
+msgstr "_Verktygsrad"
+
+#: client/gtk/gui.c:273
+msgid "Show or hide the toolbar"
+msgstr "Visa eller göm verktygsraden"
+
+#. Victory points target in statusbar
+#: client/gtk/gui.c:368
+#, c-format
+msgid "Points Needed to Win: %i"
+msgstr "Poäng krävs för vinst: %i"
+
+#: client/gtk/gui.c:454
+msgid "<b>Messages</b>"
+msgstr "<b>Meddelanden</b>"
+
+#. Tab page name
+#: client/gtk/gui.c:571 editor/gtk/editor.c:1165
+msgid "Map"
+msgstr "Karta"
+
+#. Tab page name
+#: client/gtk/gui.c:585 client/gtk/quote.c:306
+msgid "Quote"
+msgstr "Pris"
+
+#. Tab page name
+#: client/gtk/gui.c:593 client/gtk/legend.c:261
+msgid "Legend"
+msgstr "Förklaring"
+
+#. Tab page name, shown for the splash screen
+#: client/gtk/gui.c:603
+msgid "Welcome to Pioneers"
+msgstr "Välkommen till Pioneers"
+
+#: client/gtk/gui.c:868
+msgid "Pioneers Preferences"
+msgstr "Inställningar för Pioneers"
+
+#. Label for changing the theme, in the preferences dialog
+#: client/gtk/gui.c:898
+msgid "Theme:"
+msgstr "Tema:"
+
+#: client/gtk/gui.c:921
+msgid "Choose one of the themes"
+msgstr "Välj ett av dessa teman"
+
+#. Label for the option to show the legend
+#: client/gtk/gui.c:925
+msgid "Show legend"
+msgstr "Visa förklaring"
+
+#. Tooltip for the option to show the legend
+#: client/gtk/gui.c:935
+msgid "Show the legend as a page beside the map"
+msgstr "Visa förklaringen som en sida bredvid kartan"
+
+#. Label for the option to display log messages in color
+#: client/gtk/gui.c:940
+msgid "Messages with color"
+msgstr "Meddelanden med färg"
+
+#: client/gtk/gui.c:950
+msgid "Show new messages with color"
+msgstr "Visa nya meddelanden med färg"
+
+#: client/gtk/gui.c:955
+msgid "Chat in color of player"
+msgstr "Chatt i spelarens färg"
+
+#: client/gtk/gui.c:966
+msgid "Show new chat messages in the color of the player"
+msgstr "Visa nya chattmeddelanden i samma färg som spelaren"
+
+#. Label for the option to display the summary with colors
+#: client/gtk/gui.c:971
+msgid "Summary with color"
+msgstr "Sammanfattning i färg"
+
+#: client/gtk/gui.c:982
+msgid "Use colors in the player summary"
+msgstr "Använd färger i spelarnas sammanfattning"
+
+#: client/gtk/gui.c:987
+msgid "Toolbar with shortcuts"
+msgstr "Verktygsrad med genvägar"
+
+#: client/gtk/gui.c:997
+msgid "Show keyboard shortcuts in the toolbar"
+msgstr "Visa tangentbordsgenvägar i verktygsraden"
+
+#: client/gtk/gui.c:1003
+msgid "Announce new players"
+msgstr "Annonsera nya spelare"
+
+#: client/gtk/gui.c:1014
+msgid "Make a sound when a new player or viewer enters the game"
+msgstr "Spela ett ljud när en ny spelare eller åskådare kommer in i spelet"
+
+#. Label for the option to use the 16:9 layout.
+#: client/gtk/gui.c:1019
+msgid "Use 16:9 layout"
+msgstr "Använd bredbildslayout"
+
+#: client/gtk/gui.c:1030
+msgid "Use a 16:9 friendly layout for the window"
+msgstr "Använd en bredbildsvänlig layout för fönstret"
+
+#: client/gtk/gui.c:1041
+msgid "The Pioneers Game"
+msgstr "Spelet Pioneers"
+
+#. Initial text in status bar
+#: client/gtk/gui.c:1352
+msgid "Welcome to Pioneers!"
+msgstr "Välkommen till Pioneers!"
+
+#. The name of the application
+#: client/gtk/gui.c:1463
+msgid "Pioneers"
+msgstr "Pioneers"
+
+#: client/gtk/histogram.c:252
+msgid "Dice Histogram"
+msgstr "Tärningshistogram"
+
+#: client/gtk/interface.c:92
+msgid "Ship movement canceled."
+msgstr "Flyttning av skepp avbröts."
+
+#: client/gtk/interface.c:100 client/gtk/interface.c:101
+msgid "Select a new location for the ship."
+msgstr "Välj en ny plats för skeppet."
+
+#: client/gtk/interface.c:740
+msgid "Select the ship to steal from"
+msgstr "Välj det skepp du vill stjäla från"
+
+#: client/gtk/interface.c:750
+msgid "Select the building to steal from"
+msgstr "Välj den byggnad du vill stjäla från"
+
+#: client/gtk/legend.c:32
+msgid "Hill"
+msgstr "Kulle"
+
+#: client/gtk/legend.c:33
+msgid "Field"
+msgstr "Fält"
+
+#: client/gtk/legend.c:34
+msgid "Mountain"
+msgstr "Berg"
+
+#: client/gtk/legend.c:35
+msgid "Pasture"
+msgstr "Betesmark"
+
+#: client/gtk/legend.c:36
+msgid "Forest"
+msgstr "Skog"
+
+#: client/gtk/legend.c:37
+msgid "Desert"
+msgstr "Ãken"
+
+#: client/gtk/legend.c:38
+msgid "Sea"
+msgstr "Hav"
+
+#: client/gtk/legend.c:170
+msgid "<b>Terrain Yield</b>"
+msgstr "<b>Terrängavkastning</b>"
+
+#: client/gtk/legend.c:202
+msgid "<b>Building Costs</b>"
+msgstr "<b>Byggnadskostnader</b>"
+
+#: client/gtk/legend.c:243
+msgid "Development Card"
+msgstr "Utvecklingskort"
+
+#: client/gtk/monopoly.c:105
+msgid "Select the resource you wish to monopolise."
+msgstr "Välj den resurs du önskar monopolisera."
+
+#: client/gtk/name.c:123
+msgid "Change player name"
+msgstr "Ãndra spelarens namn"
+
+#: client/gtk/name.c:146
+msgid "Player Name:"
+msgstr "Spelarnamn:"
+
+#. Set icon preferences
+#: client/gtk/name.c:202
+msgid "Face:"
+msgstr "Yta:"
+
+#: client/gtk/name.c:217
+msgid "Variant:"
+msgstr "Variant:"
+
+#. Commandline option of client: name of the player
+#: client/gtk/offline.c:59
+msgid "Player name"
+msgstr "Spelarnamn"
+
+#: client/gtk/offline.c:63
+msgid "Connect as a viewer"
+msgstr "Anslut som en åskådare"
+
+#: client/gtk/offline.c:66
+msgid "Meta-server Host"
+msgstr "Metaservervärd"
+
+#: client/gtk/offline.c:70
+msgid "Override the language of the system"
+msgstr "Ställ in språk"
+
+#: client/gtk/offline.c:100
+msgid "Connecting"
+msgstr "Ansluter"
+
+#. Long description in the commandline for pioneers: help
+#: client/gtk/offline.c:175
+msgid "- Play a game of Pioneers"
+msgstr "- Spela en omgång av Pioneers"
+
+#: client/gtk/player.c:52
+msgid "Settlements"
+msgstr "Bosättningar"
+
+#: client/gtk/player.c:53
+msgid "Cities"
+msgstr "Städer"
+
+#: client/gtk/player.c:54
+msgid "City Walls"
+msgstr "Stadsmurar"
+
+#: client/gtk/player.c:55
+msgid "Largest Army"
+msgstr "Största armé"
+
+#: client/gtk/player.c:56
+msgid "Longest Road"
+msgstr "Längsta väg"
+
+#: client/gtk/player.c:57
+msgid "Chapels"
+msgstr "Kapell"
+
+#: client/gtk/player.c:58
+msgid "Pioneer Universities"
+msgstr "Pioneer Universitet"
+
+#: client/gtk/player.c:60
+msgid "Governor's Houses"
+msgstr "Guvenörshus"
+
+#: client/gtk/player.c:61
+msgid "Libraries"
+msgstr "Bibliotek"
+
+#: client/gtk/player.c:62
+msgid "Markets"
+msgstr "Marknader"
+
+#: client/gtk/player.c:63
+msgid "Soldiers"
+msgstr "Soldater"
+
+#: client/gtk/player.c:64
+msgid "Resource card"
+msgstr "Resurskort"
+
+#: client/gtk/player.c:64
+msgid "Resource cards"
+msgstr "Resurskort"
+
+#: client/gtk/player.c:65
+msgid "Development card"
+msgstr "Utvecklingskort"
+
+#: client/gtk/player.c:65
+msgid "Development cards"
+msgstr "Utvecklingskort"
+
+#. Caption for the overview of the points and card of other players
+#: client/gtk/player.c:561
+msgid "<b>Player Summary</b>"
+msgstr "<b>Sammandrag för spelare</b>"
+
+#: client/gtk/plenty.c:87
+msgid "Please choose one resource from the bank"
+msgstr "Välj en resurs från banken"
+
+#: client/gtk/plenty.c:90
+msgid "Please choose two resources from the bank"
+msgstr "Välj två resurser från banken"
+
+#: client/gtk/plenty.c:92
+msgid "The bank is empty"
+msgstr "Banken är tom"
+
+#: client/gtk/quote.c:186
+#, c-format
+msgid "%s has %s, and is looking for %s"
+msgstr "%s har %s och letar efter %s"
+
+#: client/gtk/quote.c:287
+msgid "I Want"
+msgstr "Jag vill ha"
+
+#: client/gtk/quote.c:295
+msgid "Give Them"
+msgstr "Ge dem"
+
+#: client/gtk/quote.c:311
+msgid "Delete"
+msgstr "Ta bort"
+
+#: client/gtk/quote.c:335
+msgid "Reject Domestic Trade"
+msgstr "Vägra inrikeshandel"
+
+#. Now create columns
+#. Table header: Player who trades
+#. Role of the player: player
+#: client/gtk/quote-view.c:170 server/gtk/main.c:513
+msgid "Player"
+msgstr "Spelare"
+
+#. Table header: Quote
+#: client/gtk/quote-view.c:185
+msgid "Quotes"
+msgstr "Pris"
+
+#. trade: maritime quote: %1 resources of type %2 for
+#. * one resource of type %3
+#: client/gtk/quote-view.c:292
+#, c-format
+msgid "%d:1 %s for %s"
+msgstr "%d:1 %s för %s"
+
+#. Trade: a player has rejected trade
+#: client/gtk/quote-view.c:431
+msgid "Rejected trade"
+msgstr "Vägrade handel"
+
+#. Caption for overview of the resources of the player
+#: client/gtk/resource.c:113
+msgid "<b>Resources</b>"
+msgstr "<b>Resurser</b>"
+
+#: client/gtk/resource.c:129
+msgid "Total"
+msgstr "Totalt"
+
+#. Tooltip for the amount of resources in the hand
+#: client/gtk/resource-table.c:187
+msgid "Amount in hand"
+msgstr "Mängd i handen"
+
+#: client/gtk/resource-table.c:191
+msgid "<less"
+msgstr "<mindre"
+
+#. Tooltip for decreasing the selected amount
+#: client/gtk/resource-table.c:201
+msgid "Decrease the selected amount"
+msgstr "Minska den valda mängden"
+
+#. Tooltip for the amount of resources in the bank
+#: client/gtk/resource-table.c:215
+msgid "Amount in the bank"
+msgstr "Mängd på banken"
+
+#: client/gtk/resource-table.c:219
+msgid "more>"
+msgstr "mer>"
+
+#. Tooltip for increasing the selected amount
+#: client/gtk/resource-table.c:231
+msgid "Increase the selected amount"
+msgstr "Ãka den valda mängden"
+
+#. Tooltip for the selected amount
+#: client/gtk/resource-table.c:248
+msgid "Selected amount"
+msgstr "Vald mängd"
+
+#. Tooltip for the total selected amount
+#: client/gtk/resource-table.c:293
+msgid "Total selected amount"
+msgstr "Totalt vald mängd"
+
+#: client/gtk/resource-table.c:314
+msgid "The bank cannot be emptied"
+msgstr "Banken kan inte tömmas"
+
+#: client/gtk/settingscreen.c:74
+msgid "Yes"
+msgstr "Ja"
+
+#: client/gtk/settingscreen.c:76 client/gtk/settingscreen.c:207
+msgid "No"
+msgstr "Nej"
+
+#: client/gtk/settingscreen.c:87 client/gtk/settingscreen.c:174
+msgid "Unknown"
+msgstr "Okänd"
+
+#: client/gtk/settingscreen.c:121
+msgid "No game in progress..."
+msgstr "Inget spel pågår..."
+
+#: client/gtk/settingscreen.c:131
+msgid "<b>General Settings</b>"
+msgstr "<b>Allmänna inställningar</b>"
+
+#: client/gtk/settingscreen.c:147
+msgid "Number of players:"
+msgstr "Antal spelare:"
+
+#: client/gtk/settingscreen.c:150
+msgid "Victory Point Target:"
+msgstr "Poängmål för seger:"
+
+#: client/gtk/settingscreen.c:153
+msgid "Random Terrain?"
+msgstr "Slumpad terräng?"
+
+#: client/gtk/settingscreen.c:156
+msgid "Interplayer Trading Allowed?"
+msgstr "Tillåta handel mellan spelare?"
+
+#: client/gtk/settingscreen.c:160
+msgid "Trading allowed only before build/buy?"
+msgstr "Handel tillåtet endast före byggnation/köp?"
+
+#: client/gtk/settingscreen.c:163
+msgid "Amount of Each Resource:"
+msgstr "Mängd av varje resurs:"
+
+#: client/gtk/settingscreen.c:177
+msgid "Sevens Rule:"
+msgstr "Regel för 7:an:"
+
+#: client/gtk/settingscreen.c:181
+msgid "Use Pirate:"
+msgstr "Använd pirat:"
+
+#: client/gtk/settingscreen.c:209
+msgid "Island Discovery Bonuses:"
+msgstr "Bonusar för upptäckter av öar:"
+
+#: client/gtk/settingscreen.c:224
+msgid "<b>Building Quotas</b>"
+msgstr "<b>Byggkostnad</b>"
+
+#: client/gtk/settingscreen.c:241
+msgid "Roads:"
+msgstr "Vägar:"
+
+#: client/gtk/settingscreen.c:247
+msgid "Settlements:"
+msgstr "Bosättningar:"
+
+#: client/gtk/settingscreen.c:253
+msgid "Cities:"
+msgstr "Städer:"
+
+#: client/gtk/settingscreen.c:259
+msgid "City Walls:"
+msgstr "Stadsmurar:"
+
+#: client/gtk/settingscreen.c:265
+msgid "Ships:"
+msgstr "Skepp:"
+
+#: client/gtk/settingscreen.c:271
+msgid "Bridges:"
+msgstr "Broar:"
+
+#: client/gtk/settingscreen.c:283
+msgid "<b>Development Card Deck</b>"
+msgstr "<b>Kortlek för utvecklingskort</b>"
+
+#: client/gtk/settingscreen.c:299
+msgid "Road Building Cards:"
+msgstr "Vägbyggnadskort:"
+
+#: client/gtk/settingscreen.c:303
+msgid "Monopoly Cards:"
+msgstr "Monopolkort:"
+
+#: client/gtk/settingscreen.c:307
+msgid "Year of Plenty Cards:"
+msgstr "Kort för Guldår:"
+
+#: client/gtk/settingscreen.c:312
+msgid "Chapel Cards:"
+msgstr "Kapellkort:"
+
+#: client/gtk/settingscreen.c:316
+msgid "Pioneer University Cards:"
+msgstr "Kort för Pioneer Universitet:"
+
+#: client/gtk/settingscreen.c:320
+msgid "Governor's House Cards:"
+msgstr "Kort för Guvenörshus:"
+
+#: client/gtk/settingscreen.c:325
+msgid "Library Cards:"
+msgstr "Bibliotekskort:"
+
+#: client/gtk/settingscreen.c:329
+msgid "Market Cards:"
+msgstr "Marknadskort:"
+
+#: client/gtk/settingscreen.c:333
+msgid "Soldier Cards:"
+msgstr "Soldatkort:"
+
+#: client/gtk/settingscreen.c:370
+msgid "Current Game Settings"
+msgstr "Inställningar för nuvarande spel"
+
+#. trade: you ask for something for free
+#: client/gtk/trade.c:193
+#, c-format
+msgid "ask for %s for free"
+msgstr "fråga efter %s gratis"
+
+#. trade: you give something away for free
+#: client/gtk/trade.c:198
+#, c-format
+msgid "give %s for free"
+msgstr "ge %s gratis"
+
+#. trade: you trade something for something else
+#: client/gtk/trade.c:203
+#, c-format
+msgid "give %s for %s"
+msgstr "ge %s för %s"
+
+#. I want some resources, and give them some resources
+#: client/gtk/trade.c:230
+#, c-format
+msgid "I want %s, and give them %s"
+msgstr "Jag vill ha %s och ge dem %s"
+
+#. Frame title, trade: I want to trade these resources
+#: client/gtk/trade.c:427
+msgid "<b>I Want</b>"
+msgstr "<b>Jag vill ha</b>"
+
+#. Frame title, trade: I want these resources in return
+#: client/gtk/trade.c:455
+msgid "<b>Give Them</b>"
+msgstr "<b>Ge dem</b>"
+
+#. Button text, trade: call for quotes from other players
+#: client/gtk/trade.c:484
+msgid "_Call for Quotes"
+msgstr "_Fråga efter pris"
+
+#. Button text: Trade page, accept selected quote
+#: client/gtk/trade.c:512
+msgid "_Accept Quote"
+msgstr "_Acceptera pris"
+
+#. Button text: Trade page, finish trading
+#: client/gtk/trade.c:518
+msgid "_Finish Trading"
+msgstr "Avsluta _handel"
+
+#: common/gtk/aboutbox.c:74
+msgid ""
+"Pioneers is based upon the excellent\n"
+"Settlers of Catan board game.\n"
+msgstr ""
+"Pioneers är baserad på det utmärkta\n"
+"brädspelet Settlers of Catan.\n"
+
+#: common/gtk/aboutbox.c:83
+msgid "Homepage"
+msgstr "Hemsida"
+
+#: common/gtk/aboutbox.c:88
+msgid "Authors"
+msgstr "Upphovsmän"
+
+#. Tooltip for sevens rule normal
+#: common/gtk/game-rules.c:101
+msgid "All sevens move the robber or pirate"
+msgstr "Alla 7:or flyttar rånaren eller piraten"
+
+#: common/gtk/game-rules.c:106
+msgid "In the first two turns all sevens are rerolled"
+msgstr "De två första turerna slås alla 7:or om"
+
+#. Tooltip for sevens rule reroll all
+#: common/gtk/game-rules.c:110
+msgid "All sevens are rerolled"
+msgstr "Alla sjuor slås om"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize Terrain"
+msgstr "Slumpa terräng"
+
+#: common/gtk/game-rules.c:121
+msgid "Randomize the terrain"
+msgstr "Slumpa terrängen"
+
+#: common/gtk/game-rules.c:123
+msgid "Use Pirate"
+msgstr "Använd pirat"
+
+#: common/gtk/game-rules.c:123
+msgid "Use the pirate to block ships"
+msgstr "Använd piraten för att blockera skepp"
+
+#: common/gtk/game-rules.c:125
+msgid "Strict Trade"
+msgstr "Strikt handel"
+
+#: common/gtk/game-rules.c:126
+msgid "Allow trade only before building or buying"
+msgstr "Tillåt handel endast före byggnation eller köp"
+
+#: common/gtk/game-rules.c:128
+msgid "Domestic Trade"
+msgstr "Inrikeshandel"
+
+#: common/gtk/game-rules.c:128
+msgid "Allow trade between players"
+msgstr "Tillåt handel mellan spelare"
+
+#. Label text for customising a game
+#: common/gtk/game-settings.c:118
+msgid "Number of Players"
+msgstr "Antal spelare"
+
+#. Tooltip for 'Number of Players'
+#: common/gtk/game-settings.c:136
+msgid "The number of players"
+msgstr "Antalet spelare"
+
+#. Label for customising a game
+#: common/gtk/game-settings.c:139
+msgid "Victory Point Target"
+msgstr "Poäng för vinst"
+
+#. Tooltip for Victory Point Target
+#: common/gtk/game-settings.c:159
+msgid "The points needed to win the game"
+msgstr "Poäng som krävs för att vinna spelet"
+
+#. Tooltip for the check button
+#: common/gtk/game-settings.c:172
+msgid "Is it possible to win this game?"
+msgstr "Ãr det möjligt att vinna det här spelet?"
+
+#. Port indicator for a resource: trade 2 for 1
+#: common/gtk/guimap.c:750
+msgid "2:1"
+msgstr "2:1"
+
+#. Port indicator: trade 3 for 1
+#. General port indicator
+#: common/gtk/guimap.c:753 common/gtk/guimap.c:778
+msgid "3:1"
+msgstr "3:1"
+
+#. Tooltip for the list of games
+#: common/gtk/select-game.c:111
+msgid "Select a game"
+msgstr "Välj ett spel"
+
+#: common/gtk/theme.c:709
+#, c-format
+msgid "bad scaling mode '%s'"
+msgstr "fel skalläge \"%s\""
+
+#: common/game.c:603 common/game.c:633
+msgid "This game cannot be won."
+msgstr "Detta spel kan inte vinnas."
+
+#: common/game.c:604
+msgid "There is no land."
+msgstr "Det finns inget land."
+
+#: common/game.c:638
+msgid "It is possible that this game cannot be won."
+msgstr "Det är möjligt att det här spelet inte kan vinnas."
+
+#: common/game.c:643
+msgid "This game can be won by only building all settlements and cities."
+msgstr ""
+"Det här spelet kan vinnas endast genom att bygga alla bosättningar och "
+"städer."
+
+#: common/game.c:650
+#, c-format
+msgid ""
+"Required victory points: %d\n"
+"Points obtained by building all: %d\n"
+"Points in development cards: %d\n"
+"Longest road/largest army: %d+%d\n"
+"Maximum island discovery bonus: %d\n"
+"Total: %d"
+msgstr ""
+"Nödvändiga vinstpoäng: %d\n"
+"Poäng för att bygga allt: %d\n"
+"Poäng i utvecklingskort: %d\n"
+"Längsta väg/största arme: %d+%d\n"
+"Maximal upptäcktsbonus för öar: %d\n"
+"Totalt: %d"
+
+#: common/log.c:54
+msgid "*ERROR* "
+msgstr "*FEL* "
+
+#: common/log.c:60
+msgid "Chat: "
+msgstr "Chatt: "
+
+#: common/log.c:63
+msgid "Resource: "
+msgstr "Resurs: "
+
+#: common/log.c:66
+msgid "Build: "
+msgstr "Bygg: "
+
+#: common/log.c:69
+msgid "Dice: "
+msgstr "Tärning: "
+
+#: common/log.c:72
+msgid "Steal: "
+msgstr "Stjäl: "
+
+#: common/log.c:75
+msgid "Trade: "
+msgstr "Handel: "
+
+#: common/log.c:78
+msgid "Development: "
+msgstr "Utveckling:"
+
+#: common/log.c:81
+msgid "Army: "
+msgstr "Armé: "
+
+#: common/log.c:84
+msgid "Road: "
+msgstr "Väg: "
+
+#: common/log.c:87
+msgid "*BEEP* "
+msgstr "*PIP*"
+
+#: common/log.c:92
+msgid "Player 1: "
+msgstr "Spelare 1: "
+
+#: common/log.c:95
+msgid "Player 2: "
+msgstr "Spelare 2: "
+
+#: common/log.c:98
+msgid "Player 3: "
+msgstr "Spelare 3: "
+
+#: common/log.c:101
+msgid "Player 4: "
+msgstr "Spelare 4: "
+
+#: common/log.c:104
+msgid "Player 5: "
+msgstr "Spelare 5: "
+
+#: common/log.c:107
+msgid "Player 6: "
+msgstr "Spelare 6: "
+
+#: common/log.c:110
+msgid "Player 7: "
+msgstr "Spelare 7: "
+
+#: common/log.c:113
+msgid "Player 8: "
+msgstr "Spelare 8: "
+
+#: common/log.c:116
+msgid "Viewer: "
+msgstr "Ã
skådare: "
+
+#: common/log.c:119
+msgid "** UNKNOWN MESSAGE TYPE ** "
+msgstr "** OKÃND MEDDELANDETYP ** "
+
+#: common/network.c:281
+#, c-format
+msgid "Error checking connect status: %s\n"
+msgstr "Fel vid kontroll av anslutningsstatus: %s\n"
+
+#: common/network.c:288
+#, c-format
+msgid "Error connecting to host '%s': %s\n"
+msgstr "Fel vid anslutning till värd \"%s\": %s\n"
+
+#: common/network.c:314
+#, c-format
+msgid "Error writing socket: %s\n"
+msgstr "Fel vid skrivning till uttag: %s\n"
+
+#: common/network.c:365
+#, c-format
+msgid "Error writing to socket: %s\n"
+msgstr "Fel vid skrivning till uttag: %s\n"
+
+#: common/network.c:418
+msgid "Read buffer overflow - disconnecting\n"
+msgstr "Ãverflöde i läsbuffert - kopplar ned\n"
+
+#: common/network.c:428
+#, c-format
+msgid "Error reading socket: %s\n"
+msgstr "Fel vid läsning av uttag: %s\n"
+
+#: common/network.c:575
+#, c-format
+msgid "Cannot resolve %s port %s: %s\n"
+msgstr "Kan inte slå upp %s port %s: %s\n"
+
+#: common/network.c:582
+#, c-format
+msgid "Cannot resolve %s port %s: host not found\n"
+msgstr "Kan inte slå upp %s port %s: värd hittades inte\n"
+
+#: common/network.c:597
+#, c-format
+msgid "Error creating socket: %s\n"
+msgstr "Fel vid skapandet av uttag: %s\n"
+
+#: common/network.c:605
+#, c-format
+msgid "Error setting socket close-on-exec: %s\n"
+msgstr "Fel vid inställande av uttag \"close-on-exec\": %s\n"
+
+#: common/network.c:615 common/network.c:776
+#, c-format
+msgid "Error setting socket non-blocking: %s\n"
+msgstr "Fel vid inställande av icke-blockerande uttag: %s\n"
+
+#: common/network.c:640
+#, c-format
+msgid "Error connecting to %s: %s\n"
+msgstr "Fel vid anslutning till %s: %s\n"
+
+#: common/network.c:735
+#, c-format
+msgid "Error creating struct addrinfo: %s"
+msgstr "Fel vid skapande av adressinfo: %s"
+
+#: common/network.c:765
+#, c-format
+msgid "Error creating listening socket: %s\n"
+msgstr "Fel vid skapandet av lyssningsuttag: %s\n"
+
+#: common/network.c:785
+#, c-format
+msgid "Error during listen on socket: %s\n"
+msgstr "Fel vid lyssning på uttag: %s\n"
+
+#: common/network.c:794
+msgid "Listening not yet supported on this platform."
+msgstr "Lyssning stöds ännu inte på denna plattform."
+
+#: common/network.c:816 common/network.c:817
+msgid "unknown"
+msgstr "okänd"
+
+#: common/network.c:823
+#, c-format
+msgid "Error getting peer name: %s"
+msgstr "Fel vid läsning av motpartens namn: %s"
+
+#: common/network.c:836
+#, c-format
+msgid "Error resolving address: %s"
+msgstr "Fel vid uppslag av adress: %s"
+
+#: common/network.c:850
+msgid "Net_get_peer_name not yet supported on this platform."
+msgstr "Net_get_peer_name stöds ännu inte på denna plattform."
+
+#: common/network.c:865
+#, c-format
+msgid "Error accepting connection: %s"
+msgstr "Fel vid mottagning av anslutning: %s"
+
+#: common/state.c:166
+#, c-format
+msgid "Connecting to %s, port %s\n"
+msgstr "Ansluter till %s, port %s\n"
+
+#: common/state.c:503
+msgid "State stack overflow. Stack dump sent to standard error.\n"
+msgstr "Ãverflöde i statusstack. Stackdump skickar till standard fel.\n"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:73
+msgid "_Hill"
+msgstr "_Kulle"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:75
+msgid "_Field"
+msgstr "_Fält"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:77
+msgid "_Mountain"
+msgstr "_Berg"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:79
+msgid "_Pasture"
+msgstr "Be_tesmark"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:81
+msgid "F_orest"
+msgstr "_Skog"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:83
+msgid "_Desert"
+msgstr "Ãk_en"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:85
+msgid "_Sea"
+msgstr "_Hav"
+
+#. Use an unique shortcut key for each resource
+#: editor/gtk/editor.c:87
+msgid "_Gold"
+msgstr "_Guld"
+
+#. Use an unique shortcut key for each resource
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:89 editor/gtk/editor.c:104
+msgid "_None"
+msgstr "_Ingen"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:94
+msgid "_Brick (2:1)"
+msgstr "Te_gel (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:96
+msgid "_Grain (2:1)"
+msgstr "_Spannmål (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:98
+msgid "_Ore (2:1)"
+msgstr "_Malm (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:100
+msgid "_Wool (2:1)"
+msgstr "_Ull (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:102
+msgid "_Lumber (2:1)"
+msgstr "_Timmer (2:1)"
+
+#. Use an unique shortcut key for each port type
+#: editor/gtk/editor.c:106
+msgid "_Any (3:1)"
+msgstr "_NÃ¥gon (3:1)"
+
+#. East
+#: editor/gtk/editor.c:111
+msgid "East|E"
+msgstr "Ã"
+
+#. North east
+#: editor/gtk/editor.c:113
+msgid "North East|NE"
+msgstr "NÃ"
+
+#. North west
+#: editor/gtk/editor.c:115
+msgid "North West|NW"
+msgstr "NV"
+
+#. West
+#: editor/gtk/editor.c:117
+msgid "West|W"
+msgstr "V"
+
+#. South west
+#: editor/gtk/editor.c:119
+msgid "South West|SW"
+msgstr "SV"
+
+#. South east
+#: editor/gtk/editor.c:121
+msgid "South East|SE"
+msgstr "SÃ"
+
+#: editor/gtk/editor.c:564
+msgid "Shuffle"
+msgstr "Blanda"
+
+#: editor/gtk/editor.c:696 server/gtk/main.c:450
+msgid "Game Parameters"
+msgstr "Spelparametrar"
+
+#: editor/gtk/editor.c:698 server/gtk/main.c:482
+msgid "Rules"
+msgstr "Regler"
+
+#: editor/gtk/editor.c:699
+msgid "Resources"
+msgstr "Resurser"
+
+#: editor/gtk/editor.c:700
+msgid "Buildings"
+msgstr "Byggnader"
+
+#: editor/gtk/editor.c:701
+msgid "Development Cards"
+msgstr "Utvecklingskort"
+
+#: editor/gtk/editor.c:718
+msgid "Pioneers Editor"
+msgstr "Redigerare för Pioneers"
+
+#: editor/gtk/editor.c:803
+#, c-format
+msgid "Failed to load '%s'"
+msgstr "Misslyckades att läsa in \"%s\""
+
+#: editor/gtk/editor.c:843
+#, c-format
+msgid "Failed to save to '%s'"
+msgstr "Misslyckades att spara till \"%s"
+
+#: editor/gtk/editor.c:858
+msgid "Open Game"
+msgstr "Ãppna spel"
+
+#: editor/gtk/editor.c:884
+msgid "Save as..."
+msgstr "Spara som..."
+
+#: editor/gtk/editor.c:919
+msgid "Change Title"
+msgstr "Ãndra titel"
+
+#: editor/gtk/editor.c:941
+msgid "New Title:"
+msgstr "Ny titel:"
+
+#: editor/gtk/editor.c:997
+msgid "Pioneers Game Editor"
+msgstr "Spelredigerare för Pioneers"
+
+#: editor/gtk/editor.c:1001
+msgid "_File"
+msgstr "_Fil"
+
+#: editor/gtk/editor.c:1004
+msgid "_New"
+msgstr "_Ny"
+
+#: editor/gtk/editor.c:1005
+msgid "Create a new game"
+msgstr "Skapa ett nytt spel"
+
+#: editor/gtk/editor.c:1006
+msgid "_Open..."
+msgstr "_Ãppna..."
+
+#: editor/gtk/editor.c:1007
+msgid "Open an existing game"
+msgstr "Ãppna ett existerande spel"
+
+#: editor/gtk/editor.c:1008
+msgid "_Save"
+msgstr "_Spara"
+
+#: editor/gtk/editor.c:1009
+msgid "Save game"
+msgstr "Spara spel"
+
+#: editor/gtk/editor.c:1010
+msgid "Save _As..."
+msgstr "Spar_a som..."
+
+#: editor/gtk/editor.c:1012
+msgid "Save as"
+msgstr "Spara som"
+
+#: editor/gtk/editor.c:1013
+msgid "_Change title"
+msgstr "Ãndra tit_el"
+
+#: editor/gtk/editor.c:1014
+msgid "Change game title"
+msgstr "Ãndra spelets titel"
+
+#: editor/gtk/editor.c:1015 server/gtk/main.c:100
+msgid "_Check Victory Point Target"
+msgstr "_Kontrollera poängmål för vinst"
+
+#: editor/gtk/editor.c:1017 server/gtk/main.c:102
+msgid "Check whether the game can be won"
+msgstr "Kontrollera huruvida spelet kan vinnas"
+
+#: editor/gtk/editor.c:1019
+msgid "Quit"
+msgstr "Avsluta"
+
+#: editor/gtk/editor.c:1027
+msgid "_About Pioneers Editor"
+msgstr "_Om redigeraren för Pioneers"
+
+#: editor/gtk/editor.c:1028
+msgid "Information about Pioneers Editor"
+msgstr "Information om redigeraren för Pioneers"
+
+#. Long help for commandline option (editor): filename
+#: editor/gtk/editor.c:1066
+msgid "Open this file"
+msgstr "Ãppna denna fil"
+
+#. Commandline option for editor: filename
+#: editor/gtk/editor.c:1068
+msgid "filename"
+msgstr "filnamn"
+
+#: editor/gtk/editor.c:1100
+msgid "- Editor for games of Pioneers"
+msgstr "- Redigerare för Pioneers-spel"
+
+#: editor/gtk/editor.c:1141 server/gtk/main.c:1035
+#, c-format
+msgid "Building menus failed: %s"
+msgstr "Misslyckade att bygga menyer: %s"
+
+#: editor/gtk/editor.c:1169
+msgid "Settings"
+msgstr "Inställningar"
+
+#: editor/gtk/game-resources.c:51
+msgid "Resource Count"
+msgstr "Resurser"
+
+#. Commandline meta-server: daemon
+#: meta-server/main.c:1033
+msgid "Daemonize the metaserver on start"
+msgstr "Kör metaservern i bakgrunden vid uppstart"
+
+#. Commandline meta-server: redirect
+#: meta-server/main.c:1036
+msgid "Redirect clients to another metaserver"
+msgstr "Omdirigera klienter till en annan metaserver"
+
+#. Commandline meta-server: server
+#: meta-server/main.c:1039
+msgid "Use this hostname when creating new games"
+msgstr "Använd det här värdnamnet när nya spel skapas"
+
+#. Commandline meta-server: server argument
+#: meta-server/main.c:1041
+msgid "hostname"
+msgstr "värdnamn"
+
+#. Commandline meta-server: port-range
+#: meta-server/main.c:1044
+msgid "Use this ports range when creating new games"
+msgstr "Använd det här portintervallet när nya spel skapas"
+
+#. Commandline meta-server: port-range argument
+#: meta-server/main.c:1046
+msgid "from-to"
+msgstr "från-till"
+
+#. Commandline option of meta server: syslog-debug
+#: meta-server/main.c:1052
+msgid "Debug syslog messages"
+msgstr "Felsökningsmeddelanden till syslog"
+
+#. Long description in the commandline for server-console: help
+#: meta-server/main.c:1073
+msgid "- Meta server for Pioneers"
+msgstr "- Metaserver för Pioneers"
+
+#: meta-server/main.c:1088
+#, c-format
+msgid "metaserver protocol:"
+msgstr "protokoll för metaserver:"
+
+#: server/gtk/main.c:105
+msgid "_About Pioneers Server"
+msgstr "_Om Pioneers Server"
+
+#: server/gtk/main.c:106
+msgid "Information about Pioneers Server"
+msgstr "Information om Pioneers Server"
+
+#: server/gtk/main.c:222
+msgid "Stop server"
+msgstr "Stoppa server"
+
+#: server/gtk/main.c:223
+msgid "Start server"
+msgstr "Starta server"
+
+#: server/gtk/main.c:225
+msgid "Stop the server"
+msgstr "Stoppa servern"
+
+#: server/gtk/main.c:226
+msgid "Start the server"
+msgstr "Starta servern"
+
+#: server/gtk/main.c:351
+#, c-format
+msgid "Player %s from %s entered\n"
+msgstr "Spelaren %s från %s kom in\n"
+
+#: server/gtk/main.c:358
+#, c-format
+msgid "Player %s from %s left\n"
+msgstr "Spelaren %s från %s lämnade\n"
+
+#: server/gtk/main.c:365
+#, c-format
+msgid "Player %d is now %s\n"
+msgstr "Spelare %d är nu %s\n"
+
+#: server/gtk/main.c:554
+msgid "Game Settings"
+msgstr "Spelinställningar"
+
+#: server/gtk/main.c:600
+msgid "Server Parameters"
+msgstr "Serverparametrar"
+
+#: server/gtk/main.c:626
+msgid "The port for the game server"
+msgstr "Porten för spelservern"
+
+#: server/gtk/main.c:629
+msgid "Register Server"
+msgstr "Registrera server"
+
+#: server/gtk/main.c:637
+msgid "Register this game at the meta server"
+msgstr "Registrera detta spel på metaservern"
+
+#: server/gtk/main.c:654
+msgid "The address of the meta server"
+msgstr "Adressen för metaservern"
+
+#: server/gtk/main.c:656
+msgid "Reported Hostname"
+msgstr "Rapporterat värdnamn"
+
+#: server/gtk/main.c:671
+msgid ""
+"The public name of this computer (needed when playing behind a firewall)"
+msgstr ""
+"Det publika namnet för denna dator (behövs vid spel bakom en brandvägg)"
+
+#: server/gtk/main.c:675
+msgid "Random Turn Order"
+msgstr "Slumpad turordning"
+
+#: server/gtk/main.c:683
+msgid "Randomize turn order"
+msgstr "Slumpa fram turordning"
+
+#: server/gtk/main.c:722
+msgid "Running Game"
+msgstr "Pågående spel"
+
+#: server/gtk/main.c:724
+msgid "Players Connected"
+msgstr "Anslutna spelare"
+
+#: server/gtk/main.c:758
+msgid "Shows all players and viewers connected to the server"
+msgstr "Visar alla spelare och åskådare anslutna till servern"
+
+#: server/gtk/main.c:763
+msgid "Connected"
+msgstr "Ansluten"
+
+#: server/gtk/main.c:770
+msgid "Is the player currently connected?"
+msgstr "Ãr spelaren ansluten för närvarande?"
+
+#: server/gtk/main.c:773
+msgid "Name"
+msgstr "Namn"
+
+#: server/gtk/main.c:780
+msgid "Name of the player"
+msgstr "Spelarens namn"
+
+#: server/gtk/main.c:782
+msgid "Location"
+msgstr "Plats"
+
+#: server/gtk/main.c:789
+msgid "Host name of the player"
+msgstr "Värdnamn för spelaren"
+
+#: server/gtk/main.c:793
+msgid "Number"
+msgstr "Nummer"
+
+#: server/gtk/main.c:800
+msgid "Player number"
+msgstr "Spelarens nummer"
+
+#: server/gtk/main.c:804
+msgid "Role"
+msgstr "Roll"
+
+#: server/gtk/main.c:808
+msgid "Player of viewer"
+msgstr "Ã
skådare"
+
+#: server/gtk/main.c:819
+msgid "Launch Pioneers Client"
+msgstr "Starta Pioneers-klient"
+
+#: server/gtk/main.c:826
+msgid "Launch the Pioneers Client"
+msgstr "Starta Pioneers-klienten"
+
+#: server/gtk/main.c:828
+msgid "Computer Players"
+msgstr "Datorspelare"
+
+#: server/gtk/main.c:837
+msgid "Enable Chat"
+msgstr "Aktivera chatt"
+
+#: server/gtk/main.c:843
+msgid "Enable chat messages"
+msgstr "Aktivera chattmeddelanden"
+
+#: server/gtk/main.c:850
+msgid "Add Computer Player"
+msgstr "Lägg till datorspelare"
+
+#: server/gtk/main.c:857
+msgid "Add a computer player to the game"
+msgstr "Lägg till en datorspelare till spelet"
+
+#: server/gtk/main.c:866
+msgid "Messages"
+msgstr "Meddelanden"
+
+#: server/gtk/main.c:884
+msgid "Messages from the server"
+msgstr "Meddelanden från servern"
+
+#: server/gtk/main.c:932
+msgid "The Pioneers Game Server"
+msgstr "Pioneers spelserver"
+
+#. Wait for all players to disconnect,
+#. * then enable the UI
+#.
+#: server/gtk/main.c:940
+msgid "The game is over.\n"
+msgstr "Spelet är över.\n"
+
+#. Long description in the commandline for server-gtk: help
+#. Long description in the commandline for server-console: help
+#: server/gtk/main.c:994 server/main.c:174
+msgid "- Host a game of Pioneers"
+msgstr "- Stå värd för en omgång av Pioneers"
+
+#. Name in the titlebar of the server
+#: server/gtk/main.c:1016
+msgid "Pioneers Server"
+msgstr "Pioneers-server"
+
+#. Commandline server-console: game-title
+#: server/main.c:75
+msgid "Game title to use"
+msgstr "Speltitel att använda"
+
+#. Commandline server-console: file
+#: server/main.c:78
+msgid "Game file to use"
+msgstr "Spelfil att använda"
+
+#. Commandline server-console: port
+#: server/main.c:81
+msgid "Port to listen on"
+msgstr "Port att lyssna på"
+
+#. Commandline server-console: players
+#: server/main.c:84
+msgid "Override number of players"
+msgstr "Ã
sidosätt antalet spelare"
+
+#. Commandline server-console: points
+#: server/main.c:87
+msgid "Override number of points needed to win"
+msgstr "Ã
sidosätt antalet poäng som behövs för att vinna"
+
+#. Commandline server-console: seven-rule
+#: server/main.c:90
+msgid "Override seven-rule handling"
+msgstr "Ã
sidosätt hantering av 7-regeln"
+
+#. Commandline server-console: terrain
+#: server/main.c:93
+msgid "Override terrain type, 0=default 1=random"
+msgstr "Ã
sidosätt terrängtyp, 0=standard 1=slumpad"
+
+#. Commandline server-console: computer-players
+#: server/main.c:96
+msgid "Add N computer players"
+msgstr "Lägg till N datorspelare"
+
+#. Commandline server-console: register
+#: server/main.c:106
+msgid "Register server with meta-server"
+msgstr "Registrera server med metaserver"
+
+#. Commandline server-console: meta-server
+#: server/main.c:109
+msgid "Register at meta-server name (implies -r)"
+msgstr "Registrera mot metaserver (förutsätter -r)"
+
+#. Commandline server-console: hostname
+#: server/main.c:113
+msgid "Use this hostname when registering"
+msgstr "Använd detta värdnamn vid registrering"
+
+#. Commandline server-console: auto-quit
+#: server/main.c:120
+msgid "Quit after a player has won"
+msgstr "Avsluta efter att en spelare har vunnit"
+
+#. Commandline server-console: empty-timeout
+#: server/main.c:123
+msgid "Quit after N seconds with no players"
+msgstr "Avsluta efter N sekunder utan spelare"
+
+#. Commandline server-console: tournament
+#: server/main.c:126
+msgid "Tournament mode, computer players added after N minutes"
+msgstr "Turneringsläge, datorspelare läggs till efter N minuter"
+
+#. Commandline server-console: admin-port
+#: server/main.c:130
+msgid "Admin port to listen on"
+msgstr "Administrationsport att lyssna på"
+
+#: server/main.c:134
+msgid "Don't start game immediately, wait for a command on admin port"
+msgstr ""
+"Starta inte spelet direkt, vänta på ett kommando på administrationsporten"
+
+#: server/main.c:140
+msgid "Give players numbers according to the order they enter the game"
+msgstr "Ge spelare nummer enligt den ordning de kom in i spelet"
+
+#. Commandline server-console: Short description of meta group
+#: server/main.c:180
+msgid "Meta-server Options"
+msgstr "Metaserveralternativ"
+
+#: server/main.c:183
+msgid "Options for the meta-server"
+msgstr "Alternativ för metaservern"
+
+#. Commandline server-console: Short description of misc group
+#: server/main.c:191
+msgid "Miscellaneous Options"
+msgstr "Diverse alternativ"
+
+#. Commandline server-console: Long description of misc group
+#: server/main.c:193
+msgid "Miscellaneous options"
+msgstr "Diverse alternativ"
+
+#: server/meta.c:193
+#, c-format
+msgid "Register with meta-server at %s, port %s\n"
+msgstr "Registrera mot metaservern på %s, port %s\n"
+
+#: server/meta.c:210
+msgid "Unregister from meta-server\n"
+msgstr "Avregistrera från metaserver\n"
+
+#: server/player.c:130
+msgid "chat too long"
+msgstr "chatt för lång"
+
+#: server/player.c:147
+msgid "name too long"
+msgstr "namn för långt"
+
+#: server/player.c:179
+msgid "ignoring unknown extension"
+msgstr "ignorerar okänd utökning"
+
+#: server/player.c:209
+msgid "Game starts, adding computer players"
+msgstr "Spelet startar, lägger till datorspelare"
+
+#: server/player.c:234
+#, c-format
+msgid "The game starts in %s minutes."
+msgstr "Spelet startar om %s minuter."
+
+#: server/player.c:235
+#, c-format
+msgid "The game starts in %s minute."
+msgstr "Spelet startar om %s minut."
+
+#: server/player.c:280
+msgid "Sorry, game is over."
+msgstr "Tyvärr, spelet är över."
+
+#: server/player.c:283
+#, c-format
+msgid "Player from %s is refused: game is over\n"
+msgstr "Spelare från %s nekas: spelet är över\n"
+
+#: server/player.c:331
+msgid "This game will start soon."
+msgstr "Detta spel kommer strax att startas."
+
+#: server/player.c:359
+msgid "Name not changed: new name is already in use"
+msgstr "Namn inte ändrat: nytt namn används redan"
+
+#. %s is the name of the reconnecting player
+#: server/player.c:648
+#, c-format
+msgid "%s has reconnected."
+msgstr "%s har återanslutit."
+
+#: server/player.c:776
+#, c-format
+msgid "Version mismatch: %s"
+msgstr "Versionen stämmer inte: %s"
+
+#: server/server.c:47
+msgid "Was hanging around for too long without players... bye.\n"
+msgstr "Väntade för länge utan några spelare... adjö.\n"
+
+#. Server: preparing game #.....
+#: server/server.c:219
+msgid "Preparing game"
+msgstr "Förbereder spel"
+
+#: server/server.c:337
+msgid "Missing game directory\n"
+msgstr "Saknar spelkatalog\n"
+
+#: server/turn.c:253
+msgid "Island Discovery Bonus"
+msgstr "Bonus för upptäckt av ö"
+
+#: server/turn.c:256
+msgid "Additional Island Bonus"
+msgstr "Bonus för ytterligare ö"
+
+#: server/turn.c:388
+msgid "Tried to assign resources to NULL player.\n"
+msgstr "Försökte tilldela resurser till NOLL spelare.\n"
+
+#~ msgid "Brick port|B"
+#~ msgstr "Te"
+
+#~ msgid "Grain port|G"
+#~ msgstr "Sä"
+
+#~ msgid "Ore port|O"
+#~ msgstr "Ma"
+
+#~ msgid "Wool port|W"
+#~ msgstr "Ul"
+
+#~ msgid "Lumber port|L"
+#~ msgstr "Ti"
+
+#~ msgid "Continue with your turn."
+#~ msgstr "Fortsätt med din tur."
+
+#~ msgid "Map Terrain"
+#~ msgstr "Kartterräng"
+
+#~ msgid "Default map or a random map"
+#~ msgstr "Förvald karta eller en slumpad karta"
+
+#~ msgid "%s has requested a connection check."
+#~ msgstr "%s har begärt en anslutningskontroll."
+
+#~ msgid "The metaserver has rejected the reported hostname. Try %s instead."
+#~ msgstr ""
+#~ "Metaservern har vägrat ta emot det rapporterade värdnamet. Prova %s "
+#~ "istället."
+
+#~ msgid "NOTE Expecting version %s, not %s\n"
+#~ msgstr "NOTERA Förväntade version %s, inte %s\n"
+
+#~ msgid "Pixmap not found: %s\n"
+#~ msgstr "Bild hittades inte: %s\n"
+
+#~ msgid "Only server or port set, ignoring command line"
+#~ msgstr "Endast server eller port satta, ignorerar kommandorad"
+
+#~ msgid "Could not initialize default theme."
+#~ msgstr "Kunde inte initiera förvalt tema."
+
+#~ msgid "Theme %s not loaded due to errors."
+#~ msgstr "Temat %s lästes inte in på grund av fel."
+
+#~ msgid "Could not find '%s' pixmap file in theme '%s'."
+#~ msgstr "Kunde inte hitta bildfilen \"%s\" i temat \"%s\"."
+
+#~ msgid "Could not load '%s' pixmap file in theme '%s'."
+#~ msgstr "Kunde inte läsa in bildfilen \"%s\" i temat \"%s\"."
+
+#~ msgid "Could not find default pixmap file: %s"
+#~ msgstr "Kunde inte hitta förvald bildfil: %s"
+
+#~ msgid "While reading %s at line %d:"
+#~ msgstr "Vid läsning av %s på rad %d."
+
+#~ msgid "variable name missing: %s"
+#~ msgstr "variabelnamn saknas: %s"
+
+#~ msgid "unknown config variable '%s'"
+#~ msgstr "okänd konfigurationsvariabel \"%s\"."
+
+#~ msgid "'=' missing: %s"
+#~ msgstr "'=' saknas: %s"
+
+#~ msgid "missing value"
+#~ msgstr "värde saknas"
+
+#~ msgid "invalid color: %s"
+#~ msgstr "ogiltig färg: %s"
+
+#~ msgid "unexpected rest at end of line: '%s'"
+#~ msgstr "oväntad data på slut av rad: \"%s\""
+
+#~ msgid "No usable version of WinSock was found."
+#~ msgstr "Ingen användbar version av WinSock hittades."
+
+#~ msgid "State stack overflow"
+#~ msgstr "Ãverflöde i statusstack"
Added: trunk/server/5-6-player.game
===================================================================
--- trunk/server/5-6-player.game (rev 0)
+++ trunk/server/5-6-player.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,30 @@
+title 5/6-player
+random-terrain
+domestic-trade
+num-players 5
+victory-points 10
+num-roads 15
+num-settlements 5
+num-cities 4
+resource-count 24
+develop-road 3
+develop-monopoly 3
+develop-plenty 3
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 19
+chits 2,5,4,6,3,9,8,11,11,10,6,3,8,4,8,10,11,12,10,5,4,9,5,9,12,3,2,6
+map
+-,-,s?5,s,sw4,s
+-,s,m0,m1,m2,sw4
+-,s?5,m15,m16,m17,h3,s
+s,h14,h25,h26,h18,h4,sg3
+s?0,p13,p24,p29,p27,p19,p5,s
+s,f12,f23,f28,f20,f6,sl3
+-,s?1,d11,d22,t21,t7,s
+-,s,t10,t9,t8,s?2
+-,-,so1,s,sb2,s
+.
Added: trunk/server/Another_swimming_pool_in_the_wall.game
===================================================================
--- trunk/server/Another_swimming_pool_in_the_wall.game (rev 0)
+++ trunk/server/Another_swimming_pool_in_the_wall.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,53 @@
+title Another swimming pool in the wall
+num-players 6
+victory-points 16
+domestic-trade
+num-roads 24
+num-bridges 4
+num-ships 8
+num-settlements 6
+num-cities 5
+resource-count 20
+develop-road 4
+develop-monopoly 2
+develop-plenty 4
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+
+chits 5,12,11,9,5,8,3,4,12,6,10,9,2,10,12,4,3,8,5,11,3,10,2,9,6,4,11
+
+map
+t000, p001, p002, t003, p004, t005, p006, p007, p008, f009, p010, f011, - , f012,
+ m013, t014, d015, d016, h017, f018, s , h020, p021, p022, - , - , m023, t024,
+p025, h026, d027, m028, d029, p030, t031, p032, m033, s , s , p034, h035, p036,
+ p037, p038, d039, d040, f041, h042, t043, - , - , p044, f045, p046, d047, f048,
+f049, h050, p051, h052, p053, m054, s , s , p055, h056, p057, t058, m059, p060,
+ p061, t062, p063, f064, - , s , p065, h066, t067, p068, s , s , p071, m072,
+m073, p074, h075, s , - , p076, f077, p078, m079, p080, s , s , t083, p084,
+ f085, - , s , p086, t087, p088, s , s , p091, f092, p093, p094, f095, p096,
+p097, - , p098, f099, h100, p101, m102, p103, m104, h105, p106, t107, p108, h109
+.
+
+# Another_swimming_pool_in_the_wall.game
+# v1.1, 4/08/2003
+# Copyright 2003 LT-P <LT-P at LT-P.net>
+
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Please provide some feedback ;)
Added: trunk/server/Cube.game
===================================================================
--- trunk/server/Cube.game (rev 0)
+++ trunk/server/Cube.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,51 @@
+title Cube
+num-players 4
+victory-points 12
+domestic-trade
+num-roads 20
+num-ships 10
+num-settlements 5
+num-cities 4
+resource-count 20
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 11
+
+chits 8,12,2,10,4,8,4,11,12,9,9,2,5,3,6,10,11,6,5,3
+
+map
+s , s , s , s , s , s , s , s , s , s ,
+ s , s , s , s , p0 , p1 , s , s , s , s ,
+s , s , s , s?5, p2 , p3 , s , s , s , s ,
+ s , m4 , m5 , d06, d07, f08, f09, t10, t11, s ,
+s , m12, m13, d14, d15, f16, f17, t18, t19, s ,
+ s , s , h20, h21, s?2, s , s , s , s , s ,
+s , s , h22, h23, s , s , s , s , s , s ,
+ s , s , s , s , s , s , s , s , s , s ,
+.
+
+# Cube.game
+# v1.0, 2/07/2003
+# Copyright 2003 LT-P <LT-P at LT-P.net>
+
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Please provide some feedback ;)
Added: trunk/server/Evil_square.game
===================================================================
--- trunk/server/Evil_square.game (rev 0)
+++ trunk/server/Evil_square.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,46 @@
+title Evil square
+num-players 4
+victory-points 12
+domestic-trade
+num-roads 16
+num-settlements 4
+num-cities 4
+resource-count 40
+develop-road 3
+develop-monopoly 3
+develop-plenty 3
+develop-soldier 9
+
+
+chits 3,9,2,5,11,4,6,10,4,8,10,5,11,12,3,9,2,12,3,9,2,5,11,4,6,10,4,8,10,5,11,12,3,9
+
+map
+s , s , s , s , s , s , s , s ,
+ s , p09, p10, p11, p12, p13, s , s ,
+s , p17, f18, p19, p20, t21, p22, s ,
+ s , p25, p26, p27, p28, p29, p30, s ,
+s , p33, p34, p35, p36, p37, p38, s ,
+ s , p41, h42, p43, p44, m45, p46, s ,
+s , s , p50, p51, p52, p53, p54, s ,
+ s , s , s , s , s , s , s , s
+.
+
+# Evil_square.game
+# v1.3, 14/09/2003
+# Copyright 2003 LT-P <LT-P at LT-P.net>
+
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Please provide some feedback ;)
Added: trunk/server/GuerreDe100ans.game
===================================================================
--- trunk/server/GuerreDe100ans.game (rev 0)
+++ trunk/server/GuerreDe100ans.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,62 @@
+title La guerre de 100 ans
+num-players 4
+victory-points 16
+domestic-trade
+num-roads 40
+num-ships 40
+num-settlements 10
+num-cities 5
+resource-count 20
+develop-road 4
+develop-monopoly 4
+develop-plenty 4
+develop-chapel 2
+develop-university 2
+develop-governor 2
+develop-library 2
+develop-market 2
+develop-soldier 30
+use-pirate
+island-discovery-bonus 1
+
+chits 8,9,5,6,4,9,8,10,5,6,10,6,5,9,8,5,6,4,9,8,3,2,10,12,3,4,9,5,3,11,4,4,10,11,5,9,10,12,5,4,2,9,2,4,10,11,12,9,11,10,3,4,2,5
+map
+s , s , s , t1 , t2 , t3 , t4 , p5 , h6 , h7 , h8 , p9 , p10 , p11 , f12 , f13 ,
+ s , s , s , s , p14 , p15 , t16 , p17 , f18 , p19 , f20 , t21 , t22 , f23 , f24 , s ,
+s , s , s , s , s , p25 , p26 , sw1 , f27 , p28 , h29 , f30 , p31 , f32 , f33 , sg3 ,
+ s , s , s , p34 , s , s , s , t35 , t36 , h37 , f38 , m39 , m40 , p41 , f42 , p43 ,
+s , s , s , p44 , f45 , p46 , f47 , p48 , h49 , t50 , m51 , m52 , s? , m53 , m54 , m55 ,
+ s , p56 , t57 , t58 , m59 , h60 , f61 , f62 , h63 , t64 , s , s , s , s , sl , s ,
+s , p65 , m66 , m67 , f68 , m69 , m70 , s? , t71 , s , s , s , s , s , s , p72 ,
+ s , t73 , sl , p74 , p75 , sw , p76 , s , s , s , s , s , s , s , sb , m77 ,
+s , s , s , s , s , s , s , s , s , s , s , s , s , h78 , m79 , h80 ,
+ s , s , s , s , s , s , s , s , s , p81 , h82 , t83 , sg0 , f84 , f85 , t86 ,
+s , s , s , s , s , s , s , s , s , h87 , t88 , p89 , p90 , s , t91 , p92 ,
+ s , s , s , s , s , s , s , p93 , s , m94 , f95 , f96 , f97 , s , s , p98 ,
+s , s , sl5 , s , s , s , s , m99 , s , p100, f101, t102, f103, p104, f105, s?4 ,
+ m146, m106, t107, m108, s , s , so , s , s?5 , m109, p110, p111, t112, t113, p114, f115,
+p147, p116, h117, p118, f119, p120, f121, m122, m123, m124, f125, f126, t127, t128, t129, p130,
+ t148, t131, t132, h133, t134, t135, h136, t137, t138, f139, p140, f141, h142, p143, f144, f145,
+.
+
+# GuerreDe100ans.game
+# v1.0, 2/07/2003
+# v1.1, 2006-09-10 Added pirate and island-discovery
+#
+# Copyright 2003, 2006 LT-P <LT-P at LT-P.net>
+
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Please provide some feedback ;)
Added: trunk/server/Makefile.am
===================================================================
--- trunk/server/Makefile.am (rev 0)
+++ trunk/server/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,84 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+if BUILD_SERVER
+
+if HAVE_GNOME
+include server/gtk/Makefile.am
+endif
+
+bin_PROGRAMS += pioneers-server-console
+noinst_LIBRARIES += libpioneers_server.a
+
+pioneers_server_console_CPPFLAGS = $(console_cflags)
+libpioneers_server_a_CPPFLAGS = $(console_cflags)
+
+libpioneers_server_a_SOURCES = \
+ server/admin.c \
+ server/admin.h \
+ server/buildutil.c \
+ server/develop.c \
+ server/discard.c \
+ server/gold.c \
+ server/meta.c \
+ server/player.c \
+ server/pregame.c \
+ server/resource.c \
+ server/robber.c \
+ server/server.c \
+ server/server.h \
+ server/trade.c \
+ server/turn.c
+
+pioneers_server_console_SOURCES = \
+ server/main.c \
+ server/glib-driver.c \
+ server/glib-driver.h
+
+pioneers_server_console_LDADD = libpioneers_server.a $(console_libs)
+
+endif # BUILD_SERVER
+
+config_DATA += \
+ server/default.game \
+ server/5-6-player.game \
+ server/four-islands.game \
+ server/seafarers.game \
+ server/seafarers-gold.game \
+ server/small.game \
+ server/archipel_gold.game \
+ server/canyon.game \
+ server/coeur.game \
+ server/conquest.game \
+ server/conquest+ports.game \
+ server/crane_island.game \
+ server/iles.game \
+ server/pond.game \
+ server/square.game \
+ server/star.game \
+ server/x.game \
+ server/Cube.game \
+ server/Another_swimming_pool_in_the_wall.game \
+ server/Evil_square.game \
+ server/GuerreDe100ans.game \
+ server/Mini_another_swimming_pool_in_the_wall.game \
+ server/henjes.game \
+ server/lorindol.game \
+ server/lobby.game
Added: trunk/server/Mini_another_swimming_pool_in_the_wall.game
===================================================================
--- trunk/server/Mini_another_swimming_pool_in_the_wall.game (rev 0)
+++ trunk/server/Mini_another_swimming_pool_in_the_wall.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,53 @@
+title Mini another swimming pool in the wall
+num-players 3
+victory-points 16
+domestic-trade
+num-roads 20
+num-ships 4
+num-bridges 4
+num-settlements 6
+num-cities 5
+resource-count 20
+develop-road 4
+develop-monopoly 2
+develop-plenty 4
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+
+chits 11,12,11,9,10,5,3,4,12,10,4,9,2,10,12,4,3,8,5,11,10,6,3,9,2,4,5
+
+map
+p001, p002, t003, p004, t005, p006, p008, f009, p010, f011, - ,
+ t014, d015, d016, h017, f018, s , p021, p022, - , - , m023,
+h026, d027, m028, d029, p030, t031, m033, s , s , p034, h035,
+ p038, d039, d040, f041, h042, s , - , p044, f045, d046, p047,
+h050, p051, h052, p053, m054, s , p055, h056, p057, t058, m059,
+ t062, p063, f064, - , s , p065, t067, p068, s , s , p071,
+p074, h075, s , - , p076, f077, m079, p080, s , s , t083,
+ - , s , p086, t087, p088, s , p091, f092, p093, p094, f095,
+- , p098, f099, h100, p101, m102, m104, h105, p106, t107, p108
+.
+
+# Mini_another_swimming_pool_in_the_wall.game
+# v1.1, 4/08/2003
+# Copyright 2003 LT-P <LT-P at LT-P.net>
+
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Please provide some feedback ;)
Added: trunk/server/admin.c
===================================================================
--- trunk/server/admin.c (rev 0)
+++ trunk/server/admin.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,371 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003, 2006 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2007 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Pioneers Console Server Adminstrator interface
+ *
+ * The strings in the admin interface are intentionally not translated.
+ * They would otherwise reflect the language of the server that is
+ * running the server, instead of the language of the connecting user.
+ */
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+
+#include "admin.h"
+#include "game.h"
+#include "server.h"
+
+/* network administration functions */
+comm_info *_accept_info = NULL;
+
+typedef enum {
+ BADCOMMAND,
+ SETPORT,
+ STARTSERVER,
+ STOPSERVER,
+ REGISTERSERVER,
+ NUMPLAYERS,
+ SEVENSRULE,
+ VICTORYPOINTS,
+ RANDOMTERRAIN,
+ SETGAME,
+ QUIT,
+ MESSAGE,
+ HELP,
+ INFO
+} AdminCommandType;
+
+typedef struct {
+ AdminCommandType type;
+ const gchar *command;
+ gboolean need_argument;
+ gboolean stop_server;
+ gboolean need_gameparam;
+} AdminCommand;
+
+/* *INDENT-OFF* */
+static AdminCommand admin_commands[] = {
+ { BADCOMMAND, "", FALSE, FALSE, FALSE },
+ { SETPORT, "set-port", TRUE, TRUE, TRUE },
+ { STARTSERVER, "start-server", FALSE, TRUE, TRUE },
+ { STOPSERVER, "stop-server", FALSE, TRUE, FALSE },
+ { REGISTERSERVER, "set-register-server", TRUE, TRUE, FALSE },
+ { NUMPLAYERS, "set-num-players", TRUE, TRUE, TRUE },
+ { SEVENSRULE, "set-sevens-rule", TRUE, TRUE, TRUE },
+ { VICTORYPOINTS, "set-victory-points", TRUE, TRUE, TRUE },
+ { RANDOMTERRAIN, "set-random-terrain", TRUE, TRUE, TRUE },
+ { SETGAME, "set-game", TRUE, TRUE, FALSE },
+ { QUIT, "quit", FALSE, FALSE, FALSE },
+ { MESSAGE, "send-message", TRUE, FALSE, TRUE },
+ { HELP, "help", FALSE, FALSE, FALSE },
+ { INFO, "info", FALSE, FALSE, FALSE }
+};
+/* *INDENT-ON* */
+
+/* parse 'line' and run the command requested */
+void admin_run_command(Session * admin_session, const gchar * line)
+{
+ const gchar *command_start;
+ gchar *command;
+ gchar *argument;
+ gint command_number;
+
+ static gchar *server_port = NULL;
+ static gboolean register_server = TRUE;
+ static GameParams *params = NULL;
+
+ if (!g_str_has_prefix(line, "admin")) {
+ net_printf(admin_session,
+ "no admin prefix in command: '%s'\n", line);
+ return;
+ }
+
+ line += 5; /* length of "admin" */
+ while (*line && g_ascii_isspace(*line))
+ ++line;
+ if (!*line) {
+ net_printf(admin_session, "no command found: '%s'\n",
+ line);
+ return;
+ }
+
+ /* parse the line down into command and argument */
+ command_start = line;
+ while (*line && !g_ascii_isspace(*line))
+ ++line;
+ command = g_strndup(command_start, line - command_start);
+
+ if (*line) {
+ while (*line && g_ascii_isspace(*line))
+ ++line;
+ argument = g_strdup(line);
+ } else {
+ argument = NULL;
+ }
+
+ /* command[0] is the fall-back */
+ for (command_number = 1;
+ command_number < G_N_ELEMENTS(admin_commands);
+ ++command_number) {
+ if (!strcmp
+ (command, admin_commands[command_number].command)) {
+ break;
+ }
+ }
+ if (command_number == G_N_ELEMENTS(admin_commands)) {
+ command_number = 0;
+ }
+ if (admin_commands[command_number].need_argument
+ && NULL == argument) {
+ net_printf(admin_session,
+ "ERROR command '%s' needs an argument\n",
+ command);
+ } else if (admin_commands[command_number].need_gameparam
+ && NULL == params) {
+ net_printf(admin_session,
+ "ERROR command '%s' needs a valid game\n",
+ command);
+ } else {
+ if (admin_commands[command_number].stop_server
+ && server_is_running()) {
+ server_stop();
+ net_write(admin_session, "INFO server stopped\n");
+ }
+ switch (admin_commands[command_number].type) {
+ case BADCOMMAND:
+ net_printf(admin_session,
+ "ERROR unrecognized command: '%s'\n",
+ command);
+ break;
+ case SETPORT:
+ if (server_port)
+ g_free(server_port);
+ server_port = g_strdup(argument);
+ break;
+ case STARTSERVER:
+ {
+ gchar *meta_server_name =
+ get_meta_server_name(TRUE);
+ if (!server_port)
+ server_port =
+ g_strdup
+ (PIONEERS_DEFAULT_GAME_PORT);
+ start_server(params, get_server_name(),
+ server_port, register_server,
+ meta_server_name, TRUE);
+ g_free(meta_server_name);
+ }
+ break;
+ case STOPSERVER:
+ server_stop();
+ break;
+ case REGISTERSERVER:
+ register_server = atoi(argument);
+ break;
+ case NUMPLAYERS:
+ cfg_set_num_players(params, atoi(argument));
+ break;
+ case SEVENSRULE:
+ cfg_set_sevens_rule(params, atoi(argument));
+ break;
+ case VICTORYPOINTS:
+ cfg_set_victory_points(params, atoi(argument));
+ break;
+ case RANDOMTERRAIN:
+ cfg_set_terrain_type(params, atoi(argument));
+ break;
+ case SETGAME:
+ if (params)
+ params_free(params);
+ params = cfg_set_game(argument);
+ if (!params) {
+ net_printf(admin_session,
+ "ERROR game '%s' not set\n",
+ argument);
+ }
+ break;
+ case QUIT:
+ net_close(admin_session);
+ /* Quit the server if the admin leaves */
+ if (!server_is_running())
+ exit(0);
+ break;
+ case MESSAGE:
+ g_strdelimit(argument, "|", '_');
+ if (server_is_running())
+ admin_broadcast(argument);
+ break;
+ case HELP:
+ for (command_number = 1;
+ command_number < G_N_ELEMENTS(admin_commands);
+ ++command_number) {
+ if (admin_commands[command_number].
+ need_argument) {
+ net_printf(admin_session,
+ "INFO %s argument\n",
+ admin_commands
+ [command_number].
+ command);
+ } else {
+ net_printf(admin_session,
+ "INFO %s\n",
+ admin_commands
+ [command_number].
+ command);
+ }
+ }
+ break;
+ case INFO:
+ net_printf(admin_session, "INFO server-port %s\n",
+ server_port ? server_port :
+ PIONEERS_DEFAULT_GAME_PORT);
+ net_printf(admin_session,
+ "INFO register-server %d\n",
+ register_server);
+ net_printf(admin_session,
+ "INFO server running %d\n",
+ server_is_running());
+ if (params) {
+ net_printf(admin_session, "INFO game %s\n",
+ params->title);
+ net_printf(admin_session,
+ "INFO players %d\n",
+ params->num_players);
+ net_printf(admin_session,
+ "INFO victory-points %d\n",
+ params->victory_points);
+ net_printf(admin_session,
+ "INFO random-terrain %d\n",
+ params->random_terrain);
+ net_printf(admin_session,
+ "INFO sevens-rule %d\n",
+ params->sevens_rule);
+ } else {
+ net_printf(admin_session,
+ "INFO no game set\n");
+ }
+ break;
+ }
+ }
+ g_free(command);
+ if (argument)
+ g_free(argument);
+}
+
+/* network event handler, just like the one in meta.c, state.c, etc. */
+void admin_event(NetEvent event, Session * admin_session,
+ const gchar * line)
+{
+#ifdef PRINT_INFO
+ g_print
+ ("admin_event: event = %#x, admin_session = %p, line = %s\n",
+ event, admin_session, line);
+#endif
+
+ switch (event) {
+ case NET_READ:
+ /* there is data to be read */
+
+#ifdef PRINT_INFO
+ g_print("admin_event: NET_READ: line = '%s'\n", line);
+#endif
+ admin_run_command(admin_session, line);
+ break;
+ case NET_CLOSE:
+ /* connection has been closed */
+
+#ifdef PRINT_INFO
+ g_print("admin_event: NET_CLOSE\n");
+#endif
+ net_free(&admin_session);
+ break;
+ case NET_CONNECT:
+ /* connect() succeeded -- shouldn't get here */
+
+#ifdef PRINT_INFO
+ g_print("admin_event: NET_CONNECT\n");
+#endif
+ break;
+ case NET_CONNECT_FAIL:
+ /* connect() failed -- shouldn't get here */
+
+#ifdef PRINT_INFO
+ g_print("admin_event: NET_CONNECT_FAIL\n");
+#endif
+ break;
+ default:
+ /* To kill a warning... */
+ break;
+ }
+}
+
+/* accept a connection made to the admin port */
+void admin_connect(comm_info * admin_info)
+{
+ Session *admin_session;
+ gint new_fd;
+ gchar *location;
+
+ /* somebody connected to the administration port, so we... */
+
+ /* (1) create a new network session */
+ admin_session = net_new((NetNotifyFunc) admin_event, NULL);
+
+ /* (2) set the session as the session's user data, so we can free it
+ * later (this way we don't have to keep any globals holding all the
+ * sessions) */
+ admin_session->user_data = admin_session;
+
+ /* (3) accept the connection into a new file descriptor */
+ new_fd = accept_connection(admin_info->fd, &location);
+
+ /* (4) tie the new file descriptor to the session we created earlier.
+ * Don't use keepalive pings on this connection. */
+ net_use_fd(admin_session, new_fd, FALSE);
+}
+
+/* set up the administration port */
+void admin_listen(const gchar * port)
+{
+ gchar *error_message;
+
+ if (!_accept_info) {
+ _accept_info = g_malloc0(sizeof(comm_info));
+ }
+
+ /* open up a socket on which to listen for connections */
+ _accept_info->fd = net_open_listening_socket(port, &error_message);
+ if (_accept_info->fd == -1) {
+ log_message(MSG_ERROR, "%s\n", error_message);
+ g_free(error_message);
+ return;
+ }
+#ifdef PRINT_INFO
+ g_print("admin_listen: fd = %d\n", _accept_info->fd);
+#endif
+
+ /* set up the callback to handle connections */
+ _accept_info->read_tag =
+ driver->input_add_read(_accept_info->fd,
+ (InputFunc) admin_connect,
+ _accept_info);
+}
Added: trunk/server/admin.h
===================================================================
--- trunk/server/admin.h (rev 0)
+++ trunk/server/admin.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,48 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __admin_h
+#define __admin_h
+
+#include "network.h"
+
+typedef struct _comm_info {
+ gint fd;
+ guint read_tag;
+ guint write_tag;
+} comm_info;
+
+/**** backend functions for network administration of the server ****/
+
+/* parse 'line' and run the command requested */
+void admin_run_command(Session * admin_session, const gchar * line);
+
+/* network event handler, just like the one in meta.c, state.c, etc. */
+void admin_event(NetEvent event, Session * admin_session,
+ const gchar * line);
+
+/* accept a connection made to the admin port */
+void admin_connect(comm_info * admin_info);
+
+/* set up the administration port */
+void admin_listen(const gchar * port);
+
+#endif /* __admin_h */
Added: trunk/server/archipel_gold.game
===================================================================
--- trunk/server/archipel_gold.game (rev 0)
+++ trunk/server/archipel_gold.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,52 @@
+title Archipelago with Gold
+num-players 4
+victory-points 12
+domestic-trade
+num-roads 5
+num-ships 20
+num-settlements 5
+num-cities 3
+num-bridges 0
+resource-count 19
+develop-road 4
+develop-monopoly 1
+develop-plenty 3
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+use-pirate
+chits 10,4,6,5,9,8,10,12,5,10,4,3,9,5,3,4,9,11,8,11,6,2,
+map
+- ,s ,s ,s ,s ,s ,s ,s ,s ,- ,
+s ,p0 ,s ,s ,s ,s ,s ,p1 ,sl4 ,- ,
+s ,t2 ,sl3 ,f3 ,s ,s ,t4 ,s ,t5 ,s ,
+s ,s ,m6 ,s ,s ,h7 ,f8 ,s ,s ,s ,
+s ,s ,s ,s ,m9 ,sg3 ,s ,s ,s ,s ,
+s ,m10 ,s ,s ,s ,s ,s ,s ,g11 ,s ,
+s ,s ,s ,f12 ,s?3 ,s ,s?5 ,h13 ,s ,s ,
+s ,t14 ,sw4 ,t15 ,s ,s ,p16 ,sw5 ,t17 ,s ,
+- ,s ,p18 ,s ,s ,m19 ,s ,s ,p20 ,f21 ,
+- ,s ,s ,s ,s ,s ,s ,s ,s ,- ,
+.
+# archipel_gold.game
+# Copyright 2005 Blyx <blyx at apshram.net>
+# v1.0, added to Pioneers 2005-04-09
+
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Please provide some feedback ;)
Added: trunk/server/buildutil.c
===================================================================
--- trunk/server/buildutil.c (rev 0)
+++ trunk/server/buildutil.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,478 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "buildrec.h"
+#include "cost.h"
+#include "server.h"
+
+void check_longest_road(Game * game, gboolean can_cut)
+{
+ Map *map = game->params->map;
+ gint road_len[MAX_PLAYERS]; /* work out the longest road */
+ GList *list;
+ Player *new_longest;
+ gint num_have_longest;
+ gboolean was_cut; /* was the longest road cut? */
+
+ map_longest_road(map, road_len, game->params->num_players);
+
+ new_longest = NULL;
+ was_cut = FALSE;
+ num_have_longest = 0;
+ for (list = player_first_real(game);
+ list != NULL; list = player_next_real(list)) {
+ Player *player = list->data;
+
+#ifdef DEBUG_LONGEST
+ log_message(MSG_INFO, "%s", player->name);
+ if (game->longest_road == player)
+ log_message(MSG_INFO, "(current)");
+ log_message(MSG_INFO, "=%d", road_len[player->num]);
+ if (player->road_len != road_len[player->num])
+ log_message(MSG_INFO, "(was %d)",
+ player->road_len);
+ log_message(MSG_INFO, " ");
+#endif
+
+ /* only see if the ongest road was cut if can_cut is true.
+ * If it is false, no building was built, and the road may
+ * have become shorter because a ship moved away. */
+ if (can_cut && player->road_len > road_len[player->num]
+ && game->longest_road == player)
+ /* My longest road has been cut, I Must
+ * re-earn longest road
+ */
+ was_cut = TRUE;
+ player->road_len = road_len[player->num];
+
+ /* Only 5 or more road segments can earn longest road
+ */
+ if (road_len[player->num] < 5)
+ continue;
+
+ if (new_longest == NULL
+ || road_len[player->num] >
+ road_len[new_longest->num]) {
+ new_longest = player;
+ num_have_longest = 1;
+ } else if (road_len[player->num] ==
+ road_len[new_longest->num])
+ num_have_longest++;
+ }
+
+ if (new_longest == NULL) {
+ if (game->longest_road != NULL) {
+ /* Ouch! Lost longest road
+ */
+#ifdef DEBUG_LONGEST
+ log_message(MSG_INFO, "lost longest road\n");
+#endif
+ player_broadcast(player_none(game), PB_ALL,
+ FIRST_VERSION, LATEST_VERSION,
+ "longest-road\n");
+ game->longest_road = NULL;
+ return;
+ }
+#ifdef DEBUG_LONGEST
+ log_message(MSG_INFO, "no longest road\n");
+#endif
+ return;
+ }
+
+ /* Handle multiple longest road owners - when there is more
+ * than one player with the longest road, we never award longest
+ * road, we can only take it away.
+ */
+ if (num_have_longest > 1) {
+ if (game->longest_road == NULL) {
+ /* No one had longest road, no one gets it
+ */
+#ifdef DEBUG_LONGEST
+ log_message(MSG_INFO,
+ "multiple longest road; no one gets it\n");
+#endif
+ return;
+ }
+ /* The current longest road owner only loses the
+ * longest road if he no longer has the longest road,
+ * or his road was cut.
+ */
+ if (game->longest_road->road_len < new_longest->road_len
+ || was_cut) {
+ player_broadcast(player_none(game), PB_ALL,
+ FIRST_VERSION, LATEST_VERSION,
+ "longest-road\n");
+ game->longest_road = NULL;
+#ifdef DEBUG_LONGEST
+ log_message(MSG_INFO,
+ "multiple longest road; no one gets it\n");
+#endif
+ return;
+ }
+#ifdef DEBUG_LONGEST
+ log_message(MSG_INFO,
+ "multiple longest road; no change in owner\n");
+#endif
+ return;
+ }
+
+ /* Now change the longest road owner if necessary
+ */
+ if (game->longest_road == NULL) {
+ game->longest_road = new_longest;
+ player_broadcast(game->longest_road, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION, "longest-road\n");
+#ifdef DEBUG_LONGEST
+ log_message(MSG_INFO, "%s has longest road\n",
+ new_longest->name);
+#endif
+ return;
+ }
+ /* Did longest road owner change?
+ */
+ if (new_longest != game->longest_road
+ && road_len[new_longest->num] >
+ road_len[game->longest_road->num]) {
+ game->longest_road = new_longest;
+ player_broadcast(game->longest_road, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION, "longest-road\n");
+#ifdef DEBUG_LONGEST
+ log_message(MSG_INFO, "%s has longest road\n",
+ new_longest->name);
+#endif
+ }
+#ifdef DEBUG_LONGEST
+ log_message(MSG_INFO, "no change\n");
+#endif
+}
+
+/* build something on a node */
+void node_add(Player * player,
+ BuildType type, int x, int y, int pos, gboolean paid_for,
+ Points * points)
+{
+ Game *game = player->game;
+ Map *map = game->params->map;
+ Node *node = map_node(map, x, y, pos);
+ BuildRec *rec;
+
+ /* administrate the built number of structures */
+ if (type == BUILD_SETTLEMENT)
+ player->num_settlements++;
+ else if (type == BUILD_CITY) {
+ if (node->type == BUILD_SETTLEMENT)
+ player->num_settlements--;
+ player->num_cities++;
+ } else if (type == BUILD_CITY_WALL) {
+ player->num_city_walls++;
+ }
+
+ /* fill the backup struct */
+ rec = buildrec_new(type, x, y, pos);
+ rec->prev_status = node->type;
+ rec->longest_road =
+ game->longest_road ? game->longest_road->num : -1;
+ rec->special_points_id = -1;
+
+ /* compute the cost */
+ if (paid_for) {
+ if (type == BUILD_CITY)
+ if (node->type == BUILD_SETTLEMENT)
+ rec->cost = cost_upgrade_settlement();
+ else
+ rec->cost = cost_city();
+ else if (type == BUILD_SETTLEMENT)
+ rec->cost = cost_settlement();
+ else if (type == BUILD_CITY_WALL)
+ rec->cost = cost_city_wall();
+
+ resource_spend(player, rec->cost);
+ } else
+ rec->cost = NULL;
+
+ if (points != NULL) {
+ rec->special_points_id = points->id;
+ }
+
+ /* put the struct in the undo list */
+ player->build_list = g_list_append(player->build_list, rec);
+
+ /* update the node information */
+ node->owner = player->num;
+ if (type == BUILD_CITY_WALL) {
+ node->city_wall = TRUE;
+ /* Older clients see an extension message */
+ player_broadcast_extension(player, PB_RESPOND,
+ FIRST_VERSION, V0_10,
+ "built city wall\n");
+ player_broadcast(player, PB_RESPOND, V0_11, LATEST_VERSION,
+ "built %B %d %d %d\n", type, x, y, pos);
+ } else {
+ node->type = type;
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION, "built %B %d %d %d\n",
+ type, x, y, pos);
+ }
+ if (points != NULL) {
+ player->special_points =
+ g_list_append(player->special_points, points);
+ player_broadcast(player, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION, "get-point %d %d %s\n",
+ points->id, points->points, points->name);
+ }
+
+ /* see if the longest road was cut */
+ check_longest_road(game, TRUE);
+}
+
+/* build something on an edge */
+void edge_add(Player * player, BuildType type, int x, int y, int pos,
+ gboolean paid_for)
+{
+ Game *game = player->game;
+ Map *map = game->params->map;
+ Edge *edge = map_edge(map, x, y, pos);
+ BuildRec *rec;
+
+ /* fill the undo struct */
+ rec = buildrec_new(type, x, y, pos);
+ rec->longest_road =
+ game->longest_road ? game->longest_road->num : -1;
+
+ /* take the money if needed */
+ if (paid_for) {
+ switch (type) {
+ case BUILD_ROAD:
+ rec->cost = cost_road();
+ break;
+ case BUILD_SHIP:
+ rec->cost = cost_ship();
+ break;
+ case BUILD_BRIDGE:
+ rec->cost = cost_bridge();
+ break;
+ case BUILD_MOVE_SHIP:
+ case BUILD_SETTLEMENT:
+ case BUILD_CITY:
+ case BUILD_CITY_WALL:
+ case BUILD_NONE:
+ log_message(MSG_ERROR,
+ "In buildutils.c::edge_add() - Invalid build type.\n");
+ break;
+ }
+ resource_spend(player, rec->cost);
+ } else
+ rec->cost = NULL;
+
+ /* put the struct in the undo list */
+ player->build_list = g_list_append(player->build_list, rec);
+
+ /* update the pieces */
+ switch (type) {
+ case BUILD_ROAD:
+ player->num_roads++;
+ break;
+ case BUILD_BRIDGE:
+ player->num_bridges++;
+ break;
+ case BUILD_SHIP:
+ player->num_ships++;
+ break;
+ case BUILD_MOVE_SHIP:
+ case BUILD_SETTLEMENT:
+ case BUILD_CITY:
+ case BUILD_CITY_WALL:
+ case BUILD_NONE:
+ log_message(MSG_ERROR,
+ "In buildutils.c::edge_add() - Invalid build type.\n");
+ break;
+ }
+
+ /* update the board */
+ edge->owner = player->num;
+ edge->type = type;
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION, LATEST_VERSION,
+ "built %B %d %d %d\n", type, x, y, pos);
+
+ /* perhaps the longest road changed owner */
+ check_longest_road(game, FALSE);
+}
+
+static gint find_points_by_id(gconstpointer a, gconstpointer b)
+{
+ const Points *points = a;
+ gint id = GPOINTER_TO_INT(b);
+
+ return points->id == id ? 0 : points->id < id ? -1 : +1;
+}
+
+/* undo a build action */
+gboolean perform_undo(Player * player)
+{
+ Game *game = player->game;
+ Map *map = game->params->map;
+ GList *list;
+ BuildRec *rec;
+ Hex *hex;
+ int longest_road;
+
+ /* If the player hasn't built anything, the undo fails */
+ if (player->build_list == NULL)
+ return FALSE;
+
+ /* Fill some convenience variables */
+ list = g_list_last(player->build_list);
+ rec = list->data;
+ hex = map_hex(map, rec->x, rec->y);
+
+ /* Remove the entry from the list (doesn't remove the data itself) */
+ player->build_list = g_list_remove_link(player->build_list, list);
+ g_list_free_1(list);
+
+ /* Do structure-specific things */
+ switch (rec->type) {
+ case BUILD_NONE:
+ g_error("BUILD_NONE in perform_undo()");
+ break;
+ case BUILD_ROAD:
+ player->num_roads--;
+
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION, "remove %B %d %d %d\n",
+ BUILD_ROAD, rec->x, rec->y, rec->pos);
+ hex->edges[rec->pos]->owner = -1;
+ hex->edges[rec->pos]->type = BUILD_NONE;
+ break;
+ case BUILD_BRIDGE:
+ player->num_bridges--;
+
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION, "remove %B %d %d %d\n",
+ BUILD_BRIDGE, rec->x, rec->y, rec->pos);
+ hex->edges[rec->pos]->owner = -1;
+ hex->edges[rec->pos]->type = BUILD_NONE;
+ break;
+ case BUILD_SHIP:
+ player->num_ships--;
+
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION, "remove %B %d %d %d\n",
+ BUILD_SHIP, rec->x, rec->y, rec->pos);
+ hex->edges[rec->pos]->owner = -1;
+ hex->edges[rec->pos]->type = BUILD_NONE;
+ break;
+ case BUILD_CITY:
+ player->num_cities--;
+ player->num_settlements++;
+
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION, "remove %B %d %d %d\n",
+ BUILD_CITY, rec->x, rec->y, rec->pos);
+ hex->nodes[rec->pos]->type = BUILD_SETTLEMENT;
+ if (rec->prev_status == BUILD_SETTLEMENT)
+ break;
+ /* Fall through and remove the settlement too
+ */
+ case BUILD_SETTLEMENT:
+ player->num_settlements--;
+
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION, "remove %B %d %d %d\n",
+ BUILD_SETTLEMENT, rec->x, rec->y,
+ rec->pos);
+ hex->nodes[rec->pos]->type = BUILD_NONE;
+ hex->nodes[rec->pos]->owner = -1;
+ break;
+ case BUILD_CITY_WALL:
+ player->num_city_walls--;
+ /* Older clients see an extension message */
+ player_broadcast_extension(player, PB_RESPOND,
+ FIRST_VERSION, V0_10,
+ "remove city wall\n");
+ player_broadcast(player, PB_RESPOND, V0_11, LATEST_VERSION,
+ "remove %B %d %d %d\n", BUILD_CITY_WALL,
+ rec->x, rec->y, rec->pos);
+ hex->nodes[rec->pos]->city_wall = FALSE;
+ break;
+ case BUILD_MOVE_SHIP:
+ hex->edges[rec->pos]->owner = -1;
+ hex->edges[rec->pos]->type = BUILD_NONE;
+ hex = map_hex(map, rec->prev_x, rec->prev_y);
+ hex->edges[rec->prev_pos]->owner = player->num;
+ hex->edges[rec->prev_pos]->type = BUILD_SHIP;
+ map->has_moved_ship = FALSE;
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION,
+ "move-back %d %d %d %d %d %d\n",
+ rec->prev_x, rec->prev_y, rec->prev_pos,
+ rec->x, rec->y, rec->pos);
+ break;
+ }
+
+ /* Give back the money, if any */
+ if (rec->cost != NULL)
+ resource_refund(player, rec->cost);
+
+ /* If the longest road changed, change it back */
+ longest_road = game->longest_road ? game->longest_road->num : -1;
+ if (longest_road != rec->longest_road) {
+ if (rec->longest_road >= 0)
+ player_broadcast(player_by_num
+ (game, rec->longest_road), PB_ALL,
+ FIRST_VERSION, LATEST_VERSION,
+ "longest-road\n");
+ else
+ player_broadcast(player_none(game), PB_ALL,
+ FIRST_VERSION, LATEST_VERSION,
+ "longest-road\n");
+ }
+ game->longest_road = player_by_num(game, rec->longest_road);
+
+ if (rec->special_points_id != -1) {
+ GList *points;
+ if (game->params->island_discovery_bonus != NULL) {
+ if (!map_is_island_discovered
+ (map, map_node(map, rec->x, rec->y, rec->pos),
+ player->num)) {
+ player->islands_discovered--;
+ }
+ }
+
+ player_broadcast(player, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION, "lose-point %d\n",
+ rec->special_points_id);
+ points =
+ g_list_find_custom(player->special_points,
+ GINT_TO_POINTER(rec->
+ special_points_id),
+ find_points_by_id);
+ if (points != NULL) {
+ points_free(points->data);
+ player->special_points =
+ g_list_remove(player->special_points,
+ points->data);
+ }
+ }
+ /* free the memory */
+ g_free(rec);
+
+ return TRUE;
+}
Added: trunk/server/canyon.game
===================================================================
--- trunk/server/canyon.game (rev 0)
+++ trunk/server/canyon.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,31 @@
+title Talon Canyon
+num-players 2
+victory-points 10
+domestic-trade
+num-roads 15
+num-settlements 6
+num-cities 3
+resource-count 20
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+chits 8, 4, 9, 8, 10, 10, 6, 4, 5, 5, 3, 11, 4, 9, 6, 8, 2, 10, 3, 9, 6, 11, 12, 5, 12, 9, 11, 2, 3, 3, 4, 2, 6, 10, 8, 5, 11
+map
+-, h0
+ f1, m2
+-, p3, t4, -, -, -, -, f5, p6, f7, m8
+ -, f9,h10, -, -, -,h11,t12,m13,t14
+-, -,m15,t16, -, -,p17
+ -, -,h18,t19,f20,h21
+-, -, -,p22,d37+,m23,m24
+ -, -, -,h25,f26,t27,p28
+-, -, -, -, -,t29,h30,f31
+ -, -, -, -, -, -,m32,t33,f34
+-, -, -, -, -, -, -,p35,h36
+.
Added: trunk/server/coeur.game
===================================================================
--- trunk/server/coeur.game (rev 0)
+++ trunk/server/coeur.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,59 @@
+title Heart
+num-players 3
+victory-points 14
+domestic-trade
+num-roads 15
+num-ships 10
+num-settlements 4
+num-cities 4
+num-bridges 2
+resource-count 19
+develop-road 3
+develop-monopoly 3
+develop-plenty 3
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 14
+use-pirate
+chits 5,12,11,9,12,8,3,5,2,11,6,2,10,4,4,10,4,11,5,9,3,4,10,4,10,6,3,9,8,2,10,12,
+map
+s ,s ,s ,s ,s ,s ,s ,s ,s ,s ,
+s ,p0 ,m1 ,s ,s ,s ,p2 ,m3 ,s ,s ,
+s ,f4 ,t5 ,t6 ,h7 ,h8 ,f9 ,f10 ,t11 ,s ,
+s ,f12 ,t13 ,s ,g14+,s ,f15 ,t16 ,s ,s ,
+s ,s ,t17 ,m18 ,s ,s ,p19 ,f20 ,s ,s ,
+s ,s ,p21 ,m22 ,s ,p23 ,m24 ,s ,s ,s ,
+s ,s ,s ,m25 ,h26 ,h27 ,p28 ,s ,s ,s ,
+s ,s ,s ,h29 ,g30+,h31 ,s ,s ,s ,s ,
+s ,s ,s ,s ,s ,s ,s ,s ,s ,s ,
+.
+nosetup 4 6 5
+nosetup 5 2 4
+nosetup 4 2 4
+nosetup 4 2 5
+nosetup 5 6 4
+nosetup 4 6 4
+
+# coeur.game
+# v1.0, 15/02/2004
+# v1.1, 02/08/2006 Gold excluded from shuffle
+# Copyright 2004 LT-P <LT-P at LT-P.net>
+
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Please provide some feedback ;)
Added: trunk/server/conquest+ports.game
===================================================================
--- trunk/server/conquest+ports.game (rev 0)
+++ trunk/server/conquest+ports.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,109 @@
+title Conquest w/ Ports
+num-players 4
+victory-points 16
+domestic-trade
+num-roads 20
+num-ships 16
+num-settlements 6
+num-cities 5
+resource-count 20
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+use-pirate
+island-discovery-bonus 1
+
+chits 8, 9, 5, 6, 4, 9, 8, 10, 5, 6, 10, 6, 5, 9, 8, 5, 6, 4, 9, 8, 3, 2, 10, 12, 3, 4, 9, 5, 3, 11, 4, 4, 10, 11, 5, 9, 10, 12, 5, 4, 2, 9, 2, 4, 10, 11, 12, 9, 11, 10, 3, 4, 2, 5
+map
+-, -, s, s, s, s,sw4, s, s, s, s, s, s
+ -, s, h0, s, s,m20,f21,p22,h23,sg4, s, f5, s,
+-, s, p1, f2, s,t24,m25, s,p26,m27, s, t6, m7, s,
+ s, t3, m4,s?5,f28,h29,h30,m31,t32,t33, s, p8, h9, s
+-, s, s, s,t34,p35,f36,d54,t37,f38,m39,s?3, s, s
+ s,m10,h11, s,m40,f41,m42,p43,h44,f45, s,f15,t16, s
+-, s,p12,f13,sb0,h46,m47, s,t48,h49, s,m17,p18, s
+ -, s,t14, s, s,f50,p51,m52,h53,sl3, s,h19, s
+-, -, s, s, s, s,so2, s, s, s, s, s, s
+.
+nosetup 10 1 4
+nosetup 2 0 4
+nosetup 10 1 5
+nosetup 1 2 5
+nosetup 1 3 4
+nosetup 2 1 4
+nosetup 2 0 5
+nosetup 10 2 5
+nosetup 1 4 4
+nosetup 1 3 5
+nosetup 10 3 5
+nosetup 1 5 4
+nosetup 1 4 5
+nosetup 11 0 4
+nosetup 10 5 4
+nosetup 0 3 5
+nosetup 1 5 5
+nosetup 11 0 5
+nosetup 11 1 4
+nosetup 2 2 4
+nosetup 2 1 5
+nosetup 10 5 5
+nosetup 1 6 5
+nosetup 11 1 5
+nosetup 11 2 4
+nosetup 2 2 5
+nosetup 2 3 4
+nosetup 10 6 5
+nosetup 0 5 5
+nosetup 1 7 5
+nosetup 11 2 5
+nosetup 11 3 4
+nosetup 2 4 4
+nosetup 2 3 5
+nosetup 3 0 4
+nosetup 10 7 5
+nosetup 11 3 5
+nosetup 11 4 4
+nosetup 2 5 4
+nosetup 2 4 5
+nosetup 12 0 4
+nosetup 11 4 5
+nosetup 11 5 4
+nosetup 2 6 4
+nosetup 2 5 5
+nosetup 3 1 4
+nosetup 11 6 4
+nosetup 12 1 4
+nosetup 11 5 5
+nosetup 2 6 5
+nosetup 2 7 4
+nosetup 3 2 4
+nosetup 11 7 4
+nosetup 11 6 5
+nosetup 12 2 4
+nosetup 2 7 5
+nosetup 3 2 5
+nosetup 11 7 5
+nosetup 12 2 5
+nosetup 12 3 4
+nosetup 3 4 4
+nosetup 12 3 5
+nosetup 12 4 4
+nosetup 3 5 4
+nosetup 3 6 4
+nosetup 12 4 5
+nosetup 12 5 4
+nosetup 12 6 4
+nosetup 12 5 5
+nosetup 3 6 5
+nosetup 13 2 4
+nosetup 12 6 5
+nosetup 13 4 4
+nosetup 1 1 4
+nosetup 1 2 4
+nosetup 1 1 5
Added: trunk/server/conquest.game
===================================================================
--- trunk/server/conquest.game (rev 0)
+++ trunk/server/conquest.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,109 @@
+title Conquest
+num-players 4
+victory-points 16
+domestic-trade
+num-roads 20
+num-ships 16
+num-settlements 6
+num-cities 5
+resource-count 20
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+use-pirate
+island-discovery-bonus 1
+
+chits 8, 9, 5, 6, 4, 9, 8, 10, 5, 6, 10, 6, 5, 9, 8, 5, 6, 4, 9, 8, 3, 2, 10, 12, 3, 4, 9, 5, 3, 11, 4, 4, 10, 11, 5, 9, 10, 12, 5, 4, 2, 9, 2, 4, 10, 11, 12, 9, 11, 10, 3, 4, 2, 5
+map
+-, -, s, s, s, s, s, s, s, s, s, s, s
+ -, s, h0, s, s,m20,f21,p22,h23, s, s, f5, s,
+-, s, p1, f2, s,t24,m25, s,p26,m27, s, t6, m7, s,
+ s, t3, m4, s,f28,h29,h30,m31,t32,t33, s, p8, h9, s
+-, s, s, s,t34,p35,f36,d54,t37,f38,m39, s, s, s
+ s,m10,h11, s,m40,f41,m42,p43,h44,f45, s,f15,t16, s
+-, s,p12,f13, s,h46,m47, s,t48,h49, s,m17,p18, s
+ -, s,t14, s, s,f50,p51,m52,h53, s, s,h19, s
+-, -, s, s, s, s, s, s, s, s, s, s, s
+.
+nosetup 10 1 4
+nosetup 2 0 4
+nosetup 10 1 5
+nosetup 1 2 5
+nosetup 1 3 4
+nosetup 2 1 4
+nosetup 2 0 5
+nosetup 10 2 5
+nosetup 1 4 4
+nosetup 1 3 5
+nosetup 10 3 5
+nosetup 1 5 4
+nosetup 1 4 5
+nosetup 11 0 4
+nosetup 10 5 4
+nosetup 0 3 5
+nosetup 1 5 5
+nosetup 11 0 5
+nosetup 11 1 4
+nosetup 2 2 4
+nosetup 2 1 5
+nosetup 10 5 5
+nosetup 1 6 5
+nosetup 11 1 5
+nosetup 11 2 4
+nosetup 2 2 5
+nosetup 2 3 4
+nosetup 10 6 5
+nosetup 0 5 5
+nosetup 1 7 5
+nosetup 11 2 5
+nosetup 11 3 4
+nosetup 2 4 4
+nosetup 2 3 5
+nosetup 3 0 4
+nosetup 10 7 5
+nosetup 11 3 5
+nosetup 11 4 4
+nosetup 2 5 4
+nosetup 2 4 5
+nosetup 12 0 4
+nosetup 11 4 5
+nosetup 11 5 4
+nosetup 2 6 4
+nosetup 2 5 5
+nosetup 3 1 4
+nosetup 11 6 4
+nosetup 12 1 4
+nosetup 11 5 5
+nosetup 2 6 5
+nosetup 2 7 4
+nosetup 3 2 4
+nosetup 11 7 4
+nosetup 11 6 5
+nosetup 12 2 4
+nosetup 2 7 5
+nosetup 3 2 5
+nosetup 11 7 5
+nosetup 12 2 5
+nosetup 12 3 4
+nosetup 3 4 4
+nosetup 12 3 5
+nosetup 12 4 4
+nosetup 3 5 4
+nosetup 3 6 4
+nosetup 12 4 5
+nosetup 12 5 4
+nosetup 12 6 4
+nosetup 12 5 5
+nosetup 3 6 5
+nosetup 13 2 4
+nosetup 12 6 5
+nosetup 13 4 4
+nosetup 1 1 4
+nosetup 1 2 4
+nosetup 1 1 5
Added: trunk/server/crane_island.game
===================================================================
--- trunk/server/crane_island.game (rev 0)
+++ trunk/server/crane_island.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,84 @@
+title Crane Island
+num-players 4
+victory-points 16
+domestic-trade
+num-roads 15
+num-ships 15
+num-settlements 6
+num-cities 4
+num-bridges 0
+resource-count 20
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+chits 8,6,4,10,6,5,10,9,2,4,4,11,5,3,9,10,8,3,12,4,4,3,9,5,8,6,8,9,6,5,
+map
+s ,s ,s ,s ,s ,s ,s ,s ,s ,s ,
+sl0 ,m0 ,s ,t1 ,h2 ,t3 ,s ,m4 ,sg3 ,- ,- ,
+s ,s ,s ,t5 ,f6 ,p7 ,f8 ,s ,s ,s ,
+s ,s ,f9 ,s ,p10 ,s ,t11 ,s ,s ,- ,- ,
+s ,s ,h12 ,m13 ,t14 ,h15 ,f16 ,p17 ,s ,s ,
+s ,s ,s?2 ,f18 ,s ,p19 ,s?1 ,s ,s ,- ,- ,
+s ,s ,s ,h20 ,p21 ,t22 ,f23 ,s ,s ,s ,
+s ,s ,s ,d24 ,d25 ,d26 ,s ,s ,s ,- ,- ,
+sw0 ,f27 ,m28 ,s ,p29 ,t30 ,s ,m31 ,h32 ,sb3 ,
+s ,s ,s ,s ,s ,s ,s ,s ,s ,- ,- ,
+.
+nosetup 6 8 5
+nosetup 0 1 5
+nosetup 7 7 4
+nosetup 7 8 4
+nosetup 7 7 5
+nosetup 8 7 4
+nosetup 6 1 5
+nosetup 1 7 4
+nosetup 8 8 4
+nosetup 7 8 5
+nosetup 1 7 5
+nosetup 2 7 4
+nosetup 1 8 4
+nosetup 8 8 5
+nosetup 2 8 4
+nosetup 1 8 5
+nosetup 7 0 4
+nosetup 1 0 4
+nosetup 2 8 5
+nosetup 0 7 4
+nosetup 7 1 4
+nosetup 7 0 5
+nosetup 8 0 4
+nosetup 1 1 4
+nosetup 1 0 5
+nosetup 2 0 4
+nosetup 0 7 5
+nosetup 6 7 4
+nosetup 7 1 5
+nosetup 1 1 5
+nosetup 0 8 5
+nosetup 6 7 5
+
+# crane_island.game
+# Copyright 2005 Yusei <yusei at ragondux.com>
+# v1.0, added to Pioneers 2005-04-09
+
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Please provide some feedback ;)
Added: trunk/server/default.game
===================================================================
--- trunk/server/default.game (rev 0)
+++ trunk/server/default.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,29 @@
+title Default
+random-terrain
+strict-trade
+domestic-trade
+num-players 4
+victory-points 10
+num-roads 15
+num-settlements 5
+num-cities 4
+resource-count 19
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+chits 5,2,6,3,8,10,9,12,11,4,8,10,9,4,5,6,3,11
+map
+-,-,sw5,s,s?4,s
+-,s,t8,p7,f6,sg4
+-,s?0,h9,m16,h15,p5,s
+s,d10,t17,f18,t14,f4,sl3
+-,s?0,h11,p12,p13,m3,s
+-,s,m0,f1,t2,s?2
+-,-,so1,s,sb2,s
+.
Added: trunk/server/develop.c
===================================================================
--- trunk/server/develop.c (rev 0)
+++ trunk/server/develop.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,459 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include "buildrec.h"
+#include "cost.h"
+#include "server.h"
+
+void develop_shuffle(Game * game)
+{
+ GameParams *params;
+ gint idx;
+ gint shuffle_idx;
+ gint shuffle_counts[NUM_DEVEL_TYPES];
+
+ params = game->params;
+ memcpy(shuffle_counts, params->num_develop_type,
+ sizeof(shuffle_counts));
+ game->num_develop = 0;
+ for (idx = 0; idx < NUM_DEVEL_TYPES; idx++)
+ game->num_develop += shuffle_counts[idx];
+ if (game->develop_deck != NULL)
+ g_free(game->develop_deck);
+ game->develop_deck =
+ g_malloc0(game->num_develop * sizeof(*game->develop_deck));
+
+ for (idx = 0; idx < game->num_develop; idx++) {
+ int card_idx;
+
+ card_idx = get_rand(game->num_develop - idx);
+ for (shuffle_idx = 0;
+ shuffle_idx < G_N_ELEMENTS(shuffle_counts);
+ shuffle_idx++) {
+ card_idx -= shuffle_counts[shuffle_idx];
+ if (card_idx < 0) {
+ shuffle_counts[shuffle_idx]--;
+ game->develop_deck[idx] = shuffle_idx;
+ break;
+ }
+ }
+ }
+
+ /* Check that the deck was shuffled correctly
+ */
+ memcpy(shuffle_counts, params->num_develop_type,
+ sizeof(shuffle_counts));
+ for (idx = 0; idx < game->num_develop; idx++)
+ shuffle_counts[game->develop_deck[idx]]--;
+ for (shuffle_idx = 0; shuffle_idx < G_N_ELEMENTS(shuffle_counts);
+ shuffle_idx++)
+ if (shuffle_counts[shuffle_idx] != 0) {
+ log_message(MSG_ERROR, "Bad shuffle\n");
+ break;
+ }
+ game->develop_next = 0;
+}
+
+void develop_buy(Player * player)
+{
+ Game *game = player->game;
+ DevelType card;
+
+ if (!game->rolled_dice) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR roll-dice\n");
+ return;
+ }
+ if (!cost_can_afford(cost_development(), player->assets)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-expensive\n");
+ return;
+ }
+ if (game->develop_next >= game->num_develop) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR no-cards\n");
+ return;
+ }
+
+ /* Clear the build list to prevent undo after buying
+ * development card
+ */
+ player->build_list = buildrec_free(player->build_list);
+ resource_spend(player, cost_development());
+ player_broadcast(player, PB_OTHERS, FIRST_VERSION, LATEST_VERSION,
+ "bought-develop\n");
+ game->bought_develop = TRUE;
+
+ card = game->develop_deck[game->develop_next++];
+ deck_card_add(player->devel, card, game->curr_turn);
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "bought-develop %d\n", card);
+}
+
+gboolean mode_road_building(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ Map *map = game->params->map;
+ BuildType type;
+ gint x, y, pos;
+ GList *rb_build_rec;
+
+ sm_state_name(sm, "mode_road_building");
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (sm_recv(sm, "done")) {
+ /* Make sure we have built the right number of roads
+ */
+ gint num_built;
+
+ num_built = buildrec_count_edges(player->build_list);
+ if (num_built < 2
+ &&
+ ((player->num_roads <
+ game->params->num_build_type[BUILD_ROAD]
+ && map_can_place_road(map, player->num))
+ || (player->num_ships <
+ game->params->num_build_type[BUILD_SHIP]
+ && map_can_place_ship(map, player->num))
+ || (player->num_bridges <
+ game->params->num_build_type[BUILD_BRIDGE]
+ && map_can_place_bridge(map, player->num)))) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR expected-build\n");
+ return TRUE;
+ }
+ /* We have the right number, now make sure that all
+ * roads are connected to buildings
+ */
+ if (!buildrec_is_valid
+ (player->build_list, map, player->num)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR unconnected\n");
+ return TRUE;
+ }
+
+ /* Player has finished road building
+ */
+
+ /* Remove the roads built from the player's build_list.
+ * If we don't, trading will fail when it shouldn't.
+ */
+ if (num_built >= 2) {
+ num_built = 2;
+ }
+ for (; num_built >= 0; num_built--) {
+ rb_build_rec = g_list_last(player->build_list);
+ player->build_list =
+ g_list_remove_link(player->build_list,
+ rb_build_rec);
+ g_list_free_1(rb_build_rec);
+ }
+
+ /* Send ack to client, check for victory, and quit.
+ */
+ player_send(player, FIRST_VERSION, LATEST_VERSION, "OK\n");
+ check_victory(player);
+ sm_pop(sm);
+ return TRUE;
+ }
+
+ if (sm_recv(sm, "build %B %d %d %d", &type, &x, &y, &pos)) {
+ if (buildrec_count_type(player->build_list, type) == 2) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many\n");
+ return TRUE;
+ }
+
+ /* Building a road / ship / bridge, make sure it is
+ * correctly placed
+ */
+ if (!map_road_vacant(map, x, y, pos)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return TRUE;
+ }
+ switch (type) {
+ case BUILD_ROAD:
+ if (map_road_connect_ok
+ (map, player->num, x, y, pos))
+ break;
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return TRUE;
+ case BUILD_SHIP:
+ if (map_ship_connect_ok
+ (map, player->num, x, y, pos))
+ break;
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return TRUE;
+ case BUILD_BRIDGE:
+ if (map_bridge_connect_ok
+ (map, player->num, x, y, pos))
+ break;
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return TRUE;
+ default:
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR expected-road\n");
+ return TRUE;
+ }
+
+ edge_add(player, type, x, y, pos, FALSE);
+ return TRUE;
+ }
+
+ if (sm_recv(sm, "undo")) {
+ if (!perform_undo(player))
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+gboolean mode_plenty_resources(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ int idx;
+ int num;
+ int num_in_bank;
+ int plenty[NO_RESOURCE];
+
+ sm_state_name(sm, "mode_plenty_resources");
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (!sm_recv(sm, "plenty %R", plenty))
+ return FALSE;
+
+ num = 0;
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ num += plenty[idx];
+
+ if (!resource_available(player, plenty, &num_in_bank)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR plenty-no-resources\n");
+ return TRUE;
+ }
+ if ((num_in_bank < 2 && num != num_in_bank)
+ || (num_in_bank >= 2 && num != 2)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR wrong-plenty\n");
+ return TRUE;
+ }
+
+ /* Give the resources to the player
+ */
+ resource_start(game);
+ cost_refund(plenty, player->assets);
+ resource_end(game, "plenty", 1);
+ player_send(player, FIRST_VERSION, LATEST_VERSION, "OK\n");
+ sm_pop(sm);
+ return TRUE;
+}
+
+/* monopoly <resource-type>
+ */
+gboolean mode_monopoly(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ GList *list;
+ Resource type;
+
+ sm_state_name(sm, "mode_monopoly");
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (!sm_recv(sm, "monopoly %r", &type))
+ return FALSE;
+
+ player_send(player, FIRST_VERSION, LATEST_VERSION, "OK\n");
+ /* Now inform the various parties of the monopoly.
+ */
+ for (list = player_first_real(game);
+ list != NULL; list = player_next_real(list)) {
+ Player *scan = list->data;
+
+ if (scan == player)
+ continue;
+
+ player_broadcast(player, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION,
+ "monopoly %d %r from %d\n",
+ scan->assets[type], type, scan->num);
+
+ /* Alter the assets of the respective players
+ */
+ player->assets[type] += scan->assets[type];
+ scan->assets[type] = 0;
+ }
+
+ sm_pop(sm);
+ return TRUE;
+}
+
+static void check_largest_army(Game * game)
+{
+ GList *list;
+ Player *new_largest;
+
+ new_largest = NULL;
+ for (list = player_first_real(game);
+ list != NULL; list = player_next_real(list)) {
+ Player *player = list->data;
+
+ /* Only 3 or more soldiers can earn largest army
+ */
+ if (player->num_soldiers < 3)
+ continue;
+ if (new_largest == NULL)
+ new_largest = player;
+ else if (player->num_soldiers > new_largest->num_soldiers)
+ /* Only get the largest if exceed the current
+ * largest
+ */
+ new_largest = player;
+ }
+ if (new_largest == NULL)
+ return;
+
+ /* Now change the largest army owner if necessary
+ */
+ if (game->largest_army == NULL) {
+ game->largest_army = new_largest;
+ player_broadcast(game->largest_army, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION, "largest-army\n");
+ return;
+ }
+ /* Did largest army owner change?
+ */
+ if (new_largest != game->largest_army
+ && new_largest->num_soldiers >
+ game->largest_army->num_soldiers) {
+ game->largest_army = new_largest;
+ player_broadcast(game->largest_army, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION, "largest-army\n");
+ }
+}
+
+void develop_play(Player * player, gint idx)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ DevelType card;
+
+ if (idx >= player->devel->num_cards) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR no-card\n");
+ return;
+ }
+
+ card = player->devel->cards[idx].type;
+ if (!deck_card_play(player->devel,
+ game->played_develop, idx, game->curr_turn)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR wrong-time\n");
+ return;
+ }
+
+ if (!is_victory_card(card))
+ game->played_develop = TRUE;
+
+ /* Cannot undo after playing development card
+ */
+ player->build_list = buildrec_free(player->build_list);
+
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION, LATEST_VERSION,
+ "play-develop %d %D\n", idx, card);
+
+ switch (card) {
+ case DEVEL_ROAD_BUILDING:
+ /* Place 2 new roads as if you had just built them.
+ */
+ sm_push(sm, (StateFunc) mode_road_building);
+ break;
+ case DEVEL_MONOPOLY:
+ /* When you play this card, announce one type of
+ * resource. All other players must give you all
+ * their resource cards of that type.
+ */
+ sm_push(sm, (StateFunc) mode_monopoly);
+ break;
+ case DEVEL_YEAR_OF_PLENTY:
+ /* Take any 2 resource cards from the bank and add
+ * them to your hand. They can be two different
+ * resources or two of the same resource. They may
+ * immediately be used to build.
+ */
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "plenty %R\n", game->bank_deck);
+ sm_push(sm, (StateFunc) mode_plenty_resources);
+ break;
+ case DEVEL_CHAPEL:
+ case DEVEL_UNIVERSITY:
+ case DEVEL_GOVERNORS_HOUSE:
+ case DEVEL_LIBRARY:
+ case DEVEL_MARKET:
+
+ switch (card) {
+ case DEVEL_CHAPEL:
+ ++player->chapel_played;
+ break;
+ case DEVEL_UNIVERSITY:
+ ++player->univ_played;
+ break;
+ case DEVEL_GOVERNORS_HOUSE:
+ ++player->gov_played;
+ break;
+ case DEVEL_LIBRARY:
+ ++player->libr_played;
+ break;
+ case DEVEL_MARKET:
+ ++player->market_played;
+ break;
+ default:
+ ;
+ }
+
+ /* One victory point
+ */
+ player->develop_points++;
+ break;
+
+ case DEVEL_SOLDIER:
+ /* Move the robber. Steal one resource card from the
+ * owner of an adjacent settlement or city.
+ */
+ player->num_soldiers++;
+ check_largest_army(game);
+ robber_place(player);
+ break;
+ }
+}
Added: trunk/server/discard.c
===================================================================
--- trunk/server/discard.c (rev 0)
+++ trunk/server/discard.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,184 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "cost.h"
+#include "server.h"
+
+static void check_finished_discard(Game * game, gboolean was_discard)
+{
+ GList *list;
+ /* is everyone finished yet? */
+ for (list = player_first_real(game);
+ list != NULL; list = player_next_real(list))
+ if (((Player *) list->data)->discard_num > 0)
+ break;
+ if (list != NULL)
+ return;
+
+ /* tell players the discarding phase is over, but only if there
+ * actually was a discarding phase */
+ if (was_discard)
+ player_broadcast(player_none(game), PB_SILENT,
+ FIRST_VERSION, LATEST_VERSION,
+ "discard-done\n");
+ /* everyone is done discarding, pop all the state machines to their
+ * original state and push the robber to whoever wants it. */
+ for (list = player_first_real(game);
+ list != NULL; list = player_next_real(list)) {
+ Player *scan = list->data;
+ sm_pop(scan->sm);
+ if (sm_current(scan->sm) == (StateFunc) mode_turn)
+ robber_place(scan);
+ }
+}
+
+/* Player should be idle - I will tell them when to do something
+ */
+gboolean mode_wait_for_other_discarding_players(Player * player,
+ G_GNUC_UNUSED gint event)
+{
+ StateMachine *sm = player->sm;
+ sm_state_name(sm, "mode_wait_for_other_discarding_players");
+ return FALSE;
+}
+
+
+gboolean mode_discard_resources(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ int idx;
+ int num;
+ int discards[NO_RESOURCE];
+
+ sm_state_name(sm, "mode_discard_resources");
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (!sm_recv(sm, "discard %R", discards))
+ return FALSE;
+
+ num = 0;
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ num += discards[idx];
+ if (num != player->discard_num
+ || !cost_can_afford(discards, player->assets)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR wrong-discard\n");
+ return TRUE;
+ }
+
+ /* Discard the resources
+ */
+ player->discard_num = 0;
+ resource_start(game);
+ cost_buy(discards, player->assets);
+ resource_end(game, "discarded", -1);
+ /* wait for other to finish discarding too. The state will be
+ * popped from check_finished_discard. */
+ sm_goto(sm, (StateFunc) mode_wait_for_other_discarding_players);
+ check_finished_discard(game, TRUE);
+ return TRUE;
+}
+
+/* Find all players that have exceeded the 7 resource card limit and
+ * get them to discard.
+ */
+void discard_resources(Game * game)
+{
+ GList *list;
+ gboolean have_discard = FALSE;
+
+ for (list = player_first_real(game);
+ list != NULL; list = player_next_real(list)) {
+ Player *scan = list->data;
+ gint num;
+ gint idx;
+ gint num_types;
+
+ num = 0;
+ num_types = 0;
+ for (idx = 0; idx < G_N_ELEMENTS(scan->assets); idx++) {
+ num += scan->assets[idx];
+ if (scan->assets[idx] > 0)
+ ++num_types;
+ }
+ if (num > 7 + scan->num_city_walls * 2) {
+ scan->discard_num = num / 2;
+ /* discard random resources of disconnected players */
+ /* also do auto-discard if there is no choice */
+ if (scan->disconnected || num_types == 1) {
+ gint total = 0, resource[NO_RESOURCE];
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ resource[idx] = 0;
+ total += scan->assets[idx];
+ }
+ while (scan->discard_num) {
+ gint choice = get_rand(total);
+ for (idx = 0; idx < NO_RESOURCE;
+ idx++) {
+ choice -=
+ scan->assets[idx];
+ if (choice < 0)
+ break;
+ }
+ ++resource[idx];
+ --total;
+ --scan->discard_num;
+ --scan->assets[idx];
+ ++game->bank_deck[idx];
+ }
+ player_broadcast(scan, PB_ALL,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "discarded %R\n",
+ resource);
+ /* push idle to be popped off when all
+ * players are finished discarding. */
+ sm_push(scan->sm, (StateFunc)
+ mode_wait_for_other_discarding_players);
+ } else {
+ have_discard = TRUE;
+ sm_push(scan->sm, (StateFunc)
+ mode_discard_resources);
+ player_broadcast(scan, PB_ALL,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "must-discard %d\n",
+ scan->discard_num);
+ }
+ } else {
+ scan->discard_num = 0;
+ /* nothing to do, but we need to push, because there
+ * will be a pop in check_finished_discard.
+ * The reason we cannot leave out both is that there
+ * really is nothing to do, so it shouldn't react
+ * on input. mode_idle does just that. All players
+ * except the one whose turn it is were idle anyway,
+ * so it only changes things for that player (he cannot
+ * just start playing, which is good). */
+ sm_push(scan->sm, (StateFunc)
+ mode_wait_for_other_discarding_players);
+ }
+ }
+ check_finished_discard(game, have_discard);
+}
Added: trunk/server/four-islands.game
===================================================================
--- trunk/server/four-islands.game (rev 0)
+++ trunk/server/four-islands.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,34 @@
+title The Four Islands
+strict-trade
+domestic-trade
+num-players 3
+victory-points 12
+num-roads 15
+num-ships 15
+num-settlements 5
+num-cities 4
+resource-count 19
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+use-pirate
+island-discovery-bonus 1,2
+
+chits 4,9,3,6,6,10,2,5,11,8,9,8,4,12,10
+map
+-,s,s,s,s,s,s
+ s,p0,t1,s,s,f2,s
+-,s,f3,s,s,t4,s
+ s,s,s,s,h5,m6,s
+-,s,s,s,s,s,s
+ s,h7,t8,s,s,s,s
+-,s,p9,h10,s,m11,s
+ s,m12,f13,s,s,p14,s
+-,s,s,s,s,s,s
+.
Added: trunk/server/glib-driver.c
===================================================================
--- trunk/server/glib-driver.c (rev 0)
+++ trunk/server/glib-driver.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,73 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "driver.h"
+#include "server.h"
+#include "common_glib.h"
+#include "glib-driver.h"
+
+/* callbacks for the server */
+void srv_glib_player_added(G_GNUC_UNUSED void *data)
+{
+#ifdef PRINT_INFO
+ Player *player = (Player *) data;
+ g_print("Player %d added: %s (from host %s)\n",
+ player->num, player->name, player->location);
+#endif
+}
+
+void srv_glib_player_renamed(G_GNUC_UNUSED void *data)
+{
+#ifdef PRINT_INFO
+ Player *player = (Player *) data;
+ g_print("Player %d renamed to %s (at host %s)\n",
+ player->num, player->name, player->location);
+#endif
+}
+
+void srv_player_removed(G_GNUC_UNUSED void *data)
+{
+#ifdef PRINT_INFO
+ Player *player = (Player *) data;
+ g_print("Player %d removed: %s (at host %s)\n",
+ player->num, player->name, player->location);
+#endif
+}
+
+
+void srv_player_change(G_GNUC_UNUSED void *data)
+{
+#ifdef PRINT_INFO
+ GList *current;
+ Game *game = (Game *) data;
+ g_print("Players connected:\n");
+ playerlist_inc_use_count(game);
+ for (current = game->player_list; current != NULL;
+ current = g_list_next(current)) {
+ Player *p = (Player *) current->data;
+ g_print("Player %d: %s (at host %s) is %s connected\n",
+ p->num, p->name, p->location,
+ p->disconnected ? "not" : "");
+ }
+ playerlist_dec_use_count(game);
+#endif
+}
Added: trunk/server/glib-driver.h
===================================================================
--- trunk/server/glib-driver.h (rev 0)
+++ trunk/server/glib-driver.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,35 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __glib_driver_h
+#define __glib_driver_h
+
+#include "server.h"
+#include "driver.h"
+
+void srv_glib_player_added(void *data);
+void srv_glib_player_renamed(void *data);
+void srv_player_removed(void *data);
+
+void srv_player_change(void *data);
+extern UIDriver Glib_Driver;
+
+#endif /* __glib_driver_h */
Added: trunk/server/gold.c
===================================================================
--- trunk/server/gold.c (rev 0)
+++ trunk/server/gold.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,252 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003-2005 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "server.h"
+
+/* Player should be idle - I will tell them when to do something
+ */
+gboolean mode_wait_for_gold_choosing_players(Player * player,
+ G_GNUC_UNUSED gint event)
+{
+ StateMachine *sm = player->sm;
+ sm_state_name(sm, "mode_wait_for_gold_choosing_players");
+ return FALSE;
+}
+
+/** Create a limited bank.
+ * @param game The game
+ * @param limit The amount of resources that will be distributed
+ * @retval limited_bank Returns a bank limited by limit. An amount of
+ * limit+1 means that the bank cannot be emptied
+ * @return TRUE if the gold can be distributed in only one way
+ */
+gboolean gold_limited_bank(const Game * game, int limit,
+ gint * limited_bank)
+{
+ gint idx;
+ gint total_in_bank = 0;
+ gint resources_available = 0;
+
+ for (idx = 0; idx < NO_RESOURCE; ++idx) {
+ if (game->bank_deck[idx] <= limit) {
+ limited_bank[idx] = game->bank_deck[idx];
+ } else {
+ limited_bank[idx] = limit + 1;
+ }
+ if (game->bank_deck[idx] > 0)
+ ++resources_available;
+ total_in_bank += game->bank_deck[idx];
+ };
+ return (resources_available <= 1) || (total_in_bank <= limit);
+}
+
+/* this function distributes resources until someone who receives gold is
+ * found. It is called again when that person chose his/her gold and
+ * continues the distribution */
+static void distribute_next(GList * list)
+{
+ Player *player = list->data;
+ Game *game = player->game;
+ gint idx;
+ gboolean in_setup = FALSE;
+
+ /* give resources until someone should choose gold */
+ for (; list != NULL; list = next_player_loop(list, player)) {
+ gint resource[NO_RESOURCE], wanted[NO_RESOURCE];
+ gboolean send_message = FALSE;
+ Player *scan = list->data;
+
+ /* calculate what resources to give */
+ for (idx = 0; idx < NO_RESOURCE; ++idx) {
+ gint num;
+ num = scan->assets[idx] - scan->prev_assets[idx];
+ wanted[idx] = num;
+ if (game->bank_deck[idx] - num < 0) {
+ num = game->bank_deck[idx];
+ scan->assets[idx]
+ = scan->prev_assets[idx] + num;
+ }
+ game->bank_deck[idx] -= num;
+ resource[idx] = num;
+ /* don't let a player receive the resources twice */
+ scan->prev_assets[idx] = scan->assets[idx];
+ if (wanted[idx] > 0)
+ send_message = TRUE;
+ }
+ if (send_message)
+ player_broadcast(scan, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION,
+ "receives %R %R\n", resource,
+ wanted);
+
+ /* give out gold (and return so gold-done is not broadcast) */
+ if (scan->gold > 0) {
+ gint limited_bank[NO_RESOURCE];
+ gboolean only_one_way =
+ gold_limited_bank(game, scan->gold,
+ limited_bank);
+
+ /* disconnected players get random gold */
+ if (scan->disconnected || only_one_way) {
+ gint totalbank = 0;
+ gint choice;
+ /* count the number of resources in the bank */
+ for (idx = 0; idx < NO_RESOURCE; ++idx) {
+ resource[idx] = 0;
+ totalbank += game->bank_deck[idx];
+ }
+ while ((scan->gold > 0) && (totalbank > 0)) {
+ /* choose one of them */
+ choice = get_rand(totalbank);
+ /* find out which resource it is */
+ for (idx = 0; idx < NO_RESOURCE;
+ ++idx) {
+ choice -=
+ game->bank_deck[idx];
+ if (choice < 0)
+ break;
+ }
+ ++resource[idx];
+ --scan->gold;
+ ++scan->assets[idx];
+ ++scan->prev_assets[idx];
+ --game->bank_deck[idx];
+ --totalbank;
+ }
+ player_broadcast(scan, PB_ALL,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "receive-gold %R\n",
+ resource);
+ } else {
+ player_send(scan, FIRST_VERSION,
+ LATEST_VERSION,
+ "choose-gold %d %R\n",
+ scan->gold, limited_bank);
+ sm_push(scan->sm,
+ (StateFunc) mode_choose_gold);
+ return;
+ }
+ }
+ /* no player is choosing gold, give resources to next player */
+ } /* end loop over all players */
+ /* tell everyone the resource distribution is finished */
+ player_broadcast(player, PB_SILENT, FIRST_VERSION, LATEST_VERSION,
+ "done-resources\n");
+ /* pop everyone back to the state before we started giving out
+ * resources */
+ for (list = player_first_real(game); list != NULL;
+ list = player_next_real(list)) {
+ Player *p = list->data;
+ /* viewers were not pushed, they should not be popped */
+ if (player_is_viewer(game, p->num))
+ continue;
+ sm_pop(p->sm);
+ /* this is a hack to get the next setup player. I'd like to
+ * do it differently, but I don't know how. */
+ if (sm_current(p->sm) == (StateFunc) mode_setup) {
+ sm_goto(p->sm, (StateFunc) mode_idle);
+ in_setup = TRUE;
+ }
+ }
+ if (in_setup)
+ next_setup_player(game);
+}
+
+gboolean mode_choose_gold(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ gint resources[NO_RESOURCE];
+ gint idx, num;
+ GList *list;
+
+ sm_state_name(sm, "mode_choose_gold");
+ if (event != SM_RECV)
+ return FALSE;
+ if (!sm_recv(sm, "chose-gold %R", resources))
+ return FALSE;
+ /* check if the bank can take it */
+ num = 0;
+ for (idx = 0; idx < NO_RESOURCE; ++idx) {
+ num += resources[idx];
+ if (game->bank_deck[idx] < resources[idx]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR wrong-gold\n");
+ return FALSE;
+ }
+ }
+ /* see if the right amount was taken */
+ if (num != player->gold) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR wrong-gold\n");
+ return FALSE;
+ }
+ /* give the gold */
+ player->gold = 0;
+ for (idx = 0; idx < NO_RESOURCE; ++idx) {
+ player->assets[idx] += resources[idx];
+ /* don't give them again when resources are dealt */
+ player->prev_assets[idx] += resources[idx];
+ /* take it out of the bank */
+ game->bank_deck[idx] -= resources[idx];
+ }
+ player_broadcast(player, PB_ALL, FIRST_VERSION, LATEST_VERSION,
+ "receive-gold %R\n", resources);
+ /* pop back to mode_idle */
+ sm_pop(sm);
+ list = next_player_loop(list_from_player(player), player);
+ distribute_next(list);
+ return TRUE;
+}
+
+/* this function is called by mode_turn to let resources and gold be
+ * distributed */
+void distribute_first(GList * list)
+{
+ GList *looper;
+ Player *player = list->data;
+ Game *game = player->game;
+ /* tell everybody who's receiving gold */
+ for (looper = list; looper != NULL;
+ looper = next_player_loop(looper, player)) {
+ Player *scan = looper->data;
+ /* leave the viewers out of this */
+ if (player_is_viewer(game, scan->num))
+ continue;
+ if (scan->gold > 0) {
+ player_broadcast(scan, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION,
+ "prepare-gold %d\n", scan->gold);
+ }
+ /* push everyone to idle, so nothing happens while giving out
+ * gold after the distribution of resources is done, they are
+ * all popped off again. This does not matter for most
+ * players, since they were idle anyway, but it can matter for
+ * the player who has the turn or is setting up.
+ */
+ sm_push(scan->sm,
+ (StateFunc) mode_wait_for_gold_choosing_players);
+ }
+ /* start giving out resources */
+ distribute_next(list);
+}
Added: trunk/server/gtk/Makefile.am
===================================================================
--- trunk/server/gtk/Makefile.am (rev 0)
+++ trunk/server/gtk/Makefile.am 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,37 @@
+# Pioneers - Implementation of the excellent Settlers of Catan board game.
+# Go buy a copy.
+#
+# Copyright (C) 1999 Dave Cole
+# Copyright (C) 2006 Bas Wijnen <shevek at fmf.nl>
+#
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+icon_DATA += server/gtk/pioneers-server.png
+desktop_DATA += server/gtk/pioneers-server.desktop
+bin_PROGRAMS += pioneers-server-gtk
+
+pioneers_server_gtk_CPPFLAGS = $(gtk_cflags) -I $(srcdir)/server
+pioneers_server_gtk_LDADD = libpioneers_server.a $(gtk_libs)
+
+pioneers_server_gtk_SOURCES = \
+ server/gtk/main.c
+
+if USE_WINDOWS_ICON
+pioneers_server_gtk_LDADD += server/gtk/pioneers-server.res
+CLEANFILES += server/gtk/pioneers-server.res
+endif
+
+windows_resources_output += server/gtk/pioneers-server.ico
+windows_resources_input += server/gtk/pioneers-server.rc
Added: trunk/server/gtk/main.c
===================================================================
--- trunk/server/gtk/main.c (rev 0)
+++ trunk/server/gtk/main.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,1101 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2004-2007 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "version.h"
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+#include <ctype.h>
+#include <gtk/gtk.h>
+#include <string.h>
+
+#include <hildon-widgets/hildon-program.h>
+
+#include "authors.h"
+#include "aboutbox.h"
+#include "game.h"
+#include "common_gtk.h"
+
+#include "config-gnome.h"
+#include "server.h"
+
+#include "select-game.h" /* Custom widget */
+#include "game-settings.h" /* Custom widget */
+#include "game-rules.h"
+#include "theme.h"
+
+#define MAINICON_FILE "pioneers-server.png"
+
+static GtkWidget *settings_notebook; /* relevant settings */
+static GtkWidget *game_frame; /* the frame containing all settings regarding the game */
+static GtkWidget *rules_frame; /* the frame containing all rules regarding the game */
+static GtkWidget *select_game; /* select game type */
+static GtkWidget *game_settings; /* the settings of the game */
+static GtkWidget *game_rules; /* the rules of the game */
+static GtkWidget *server_frame; /* the frame containing all settings regarding the server */
+static GtkWidget *ai_frame; /* the frame containing all settings regarding the ai */
+static GtkWidget *register_toggle; /* register with meta server? */
+static GtkWidget *chat_toggle; /* disable AI chatting? */
+static GtkWidget *meta_entry; /* name of meta server */
+static GtkWidget *overridden_hostname_entry; /* name of server (allows masquerading) */
+static GtkWidget *port_entry; /* server port */
+static GtkWidget *random_toggle; /* randomize seating order? */
+static GtkWidget *addcomputer_btn; /* button to add computer players */
+static GtkWidget *launchclient_btn; /* button to launch client window */
+
+static GtkWidget *start_btn; /* start/stop the server */
+static GtkTooltips *tooltips; /* tooltips */
+
+static GtkListStore *store; /* shows player connection status */
+static gboolean is_running; /* current server status */
+
+
+static gchar *overridden_hostname; /* override reported hostname */
+static gchar *server_port = NULL; /* port of the game */
+static gboolean register_server = TRUE; /* Register at the meta server */
+static const gchar *meta_server_name = NULL; /* hostname of the meta server */
+static gboolean want_ai_chat = TRUE;
+static gboolean random_order = TRUE; /* random seating order */
+static gboolean enable_debug = FALSE;
+static gboolean show_version = FALSE;
+
+/* Local function prototypes */
+static void add_game_to_list(gpointer name, gpointer user_data);
+static void check_vp_cb(GObject * caller, gpointer main_window);
+static void quit_cb(void);
+static void help_about_cb(void);
+
+enum {
+ PLAYER_COLUMN_CONNECTED,
+ PLAYER_COLUMN_NAME,
+ PLAYER_COLUMN_LOCATION,
+ PLAYER_COLUMN_NUMBER,
+ PLAYER_COLUMN_ISVIEWER,
+ PLAYER_COLUMN_LAST
+};
+
+/* Normal items */
+static GtkActionEntry entries[] = {
+ {"GameMenu", NULL, N_("_Game"), NULL, NULL, NULL},
+ {"HelpMenu", NULL, N_("_Help"), NULL, NULL, NULL},
+ {"GameCheckVP", GTK_STOCK_APPLY, N_("_Check Victory Point Target"),
+ NULL,
+ N_("Check whether the game can be won"), G_CALLBACK(check_vp_cb)},
+ {"GameQuit", GTK_STOCK_QUIT, N_("_Quit"), "<control>Q",
+ N_("Quit the program"), quit_cb},
+ {"HelpAbout", NULL, N_("_About Pioneers Server"), NULL,
+ N_("Information about Pioneers Server"), help_about_cb}
+};
+
+/* *INDENT-OFF* */
+static const char *ui_description =
+"<ui>"
+" <menubar name='MainMenu'>"
+" <menu action='GameMenu'>"
+" <menuitem action='GameCheckVP' />"
+" <separator/>"
+" <menuitem action='GameQuit' />"
+" </menu>"
+" <menu action='HelpMenu'>"
+" <menuitem action='HelpAbout' />"
+" </menu>"
+" </menubar>"
+"</ui>";
+/* *INDENT-ON* */
+
+static void port_entry_changed_cb(GtkWidget * widget,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ const gchar *text;
+
+ text = gtk_entry_get_text(GTK_ENTRY(widget));
+ if (server_port)
+ g_free(server_port);
+ server_port = g_strstrip(g_strdup(text));
+}
+
+static void register_toggle_cb(GtkToggleButton * toggle,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ register_server = gtk_toggle_button_get_active(toggle);
+ gtk_widget_set_sensitive(meta_entry, register_server);
+ gtk_widget_set_sensitive(overridden_hostname_entry,
+ register_server);
+}
+
+static void random_toggle_cb(GtkToggleButton * toggle,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ random_order = gtk_toggle_button_get_active(toggle);
+}
+
+static void chat_toggle_cb(GtkToggleButton * toggle,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ want_ai_chat = gtk_toggle_button_get_active(toggle);
+}
+
+/* The server does not need to respond to changed game settings directly
+ * RC: Leaving this code here, for when the admin-interface will be built
+static void game_settings_change_cb(GameSettings *gs, G_GNUC_UNUSED gpointer user_data)
+{
+ printf("Settings: %d %d %d %d\n",
+ game_settings_get_terrain(gs),
+ game_settings_get_players(gs),
+ game_settings_get_victory_points(gs),
+ game_settings_get_sevens_rule(gs)
+ );
+}
+*/
+
+static void update_game_settings(const GameParams * params)
+{
+ g_return_if_fail(params != NULL);
+
+ /* Update the UI */
+ game_settings_set_players(GAMESETTINGS(game_settings),
+ params->num_players);
+ game_settings_set_victory_points(GAMESETTINGS(game_settings),
+ params->victory_points);
+ game_rules_set_random_terrain(GAMERULES(game_rules),
+ params->random_terrain);
+ game_rules_set_sevens_rule(GAMERULES(game_rules),
+ params->sevens_rule);
+ game_rules_set_domestic_trade(GAMERULES(game_rules),
+ params->domestic_trade);
+ game_rules_set_strict_trade(GAMERULES(game_rules),
+ params->strict_trade);
+ game_rules_set_use_pirate(GAMERULES(game_rules),
+ params->use_pirate,
+ params->num_build_type[BUILD_SHIP]);
+}
+
+static void game_activate(GtkWidget * widget,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ const gchar *title;
+ const GameParams *params;
+
+ title = select_game_get_active(SELECTGAME(widget));
+ params = game_list_find_item(title);
+ update_game_settings(params);
+}
+
+static void gui_set_server_state(gboolean running)
+{
+ gboolean ai_settings_enabled = TRUE;
+ gchar *fullname;
+
+ is_running = running;
+
+ gtk_widget_set_sensitive(gtk_notebook_get_nth_page
+ (GTK_NOTEBOOK(settings_notebook), 0),
+ !running);
+ gtk_widget_set_sensitive(gtk_notebook_get_nth_page
+ (GTK_NOTEBOOK(settings_notebook), 1),
+ !running);
+ if (running)
+ gtk_widget_show(gtk_notebook_get_nth_page
+ (GTK_NOTEBOOK(settings_notebook), 2));
+ else
+ gtk_widget_hide(gtk_notebook_get_nth_page
+ (GTK_NOTEBOOK(settings_notebook), 2));
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(settings_notebook),
+ running ? 2 : 0);
+ gtk_button_set_label(GTK_BUTTON(start_btn),
+ running ? _("Stop server") :
+ _("Start server"));
+ gtk_tooltips_set_tip(tooltips, start_btn,
+ running ? _("Stop the server") :
+ _("Start the server"), NULL);
+
+ fullname = g_find_program_in_path(PIONEERS_AI_PATH);
+ if (fullname) {
+ g_free(fullname);
+ } else {
+ ai_settings_enabled = FALSE;
+ }
+ gtk_widget_set_sensitive(ai_frame, ai_settings_enabled);
+}
+
+static void start_clicked_cb(G_GNUC_UNUSED GtkButton * start_btn,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ if (is_running) {
+ if (server_stop())
+ gui_set_server_state(FALSE);
+ } else { /* not running */
+ const gchar *title;
+ GameParams *params;
+
+ title = select_game_get_active(SELECTGAME(select_game));
+ params = params_copy(game_list_find_item(title));
+ cfg_set_num_players(params,
+ game_settings_get_players(GAMESETTINGS
+ (game_settings)));
+ cfg_set_victory_points(params,
+ game_settings_get_victory_points
+ (GAMESETTINGS(game_settings)));
+ cfg_set_sevens_rule(params,
+ game_rules_get_sevens_rule
+ (GAMERULES(game_rules)));
+ cfg_set_terrain_type(params,
+ game_rules_get_random_terrain
+ (GAMERULES(game_rules)));
+ params->strict_trade =
+ game_rules_get_strict_trade(GAMERULES(game_rules));
+ params->use_pirate =
+ game_rules_get_use_pirate(GAMERULES(game_rules));
+ params->domestic_trade =
+ game_rules_get_domestic_trade(GAMERULES(game_rules));
+ update_game_settings(params);
+
+ g_assert(server_port != NULL);
+ if (start_server
+ (params, overridden_hostname, server_port,
+ register_server, meta_server_name, random_order)) {
+ gui_set_server_state(TRUE);
+ config_set_string("server/meta-server",
+ meta_server_name);
+ config_set_string("server/port", server_port);
+ config_set_int("server/register", register_server);
+ config_set_string("server/overridden-hostname",
+ overridden_hostname);
+ config_set_int("server/random-seating-order",
+ random_order);
+
+ config_set_string("game/name", params->title);
+ config_set_int("game/random-terrain",
+ params->random_terrain);
+ config_set_int("game/num-players",
+ params->num_players);
+ config_set_int("game/victory-points",
+ params->victory_points);
+ config_set_int("game/sevens-rule",
+ params->sevens_rule);
+ config_set_int("game/use-pirate",
+ params->use_pirate);
+ config_set_int("game/strict-trade",
+ params->strict_trade);
+ config_set_int("game/domestic-trade",
+ params->domestic_trade);
+ }
+ params_free(params);
+ }
+}
+
+static void launchclient_clicked_cb(G_GNUC_UNUSED GtkButton * start_btn,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ gchar *child_argv[7];
+ GSpawnFlags child_flags = G_SPAWN_STDOUT_TO_DEV_NULL |
+ G_SPAWN_STDERR_TO_DEV_NULL;
+ GError *error = NULL;
+ gint i;
+
+ g_assert(server_port != NULL);
+
+ /* Populate argv. */
+ child_argv[0] = g_strdup(PIONEERS_CLIENT_GTK_PATH);
+ child_argv[1] = g_strdup(PIONEERS_CLIENT_GTK_PATH);
+ child_argv[2] = g_strdup("-s");
+ child_argv[3] = g_strdup("localhost");
+ child_argv[4] = g_strdup("-p");
+ child_argv[5] = g_strdup(server_port);
+ child_argv[6] = NULL;
+
+ /* Spawn the child. */
+ if (!g_spawn_async(NULL, child_argv, NULL, child_flags,
+ NULL, NULL, NULL, &error)) {
+ /* Error message when program %1 is started, reason is %2 */
+ log_message(MSG_ERROR,
+ _("Error starting %s: %s"),
+ PIONEERS_CLIENT_GTK_PATH, error->message);
+ g_error_free(error);
+ }
+
+ /* Clean up after ourselves. */
+ for (i = 0; child_argv[i] != NULL; i++) {
+ g_free(child_argv[i]);
+ }
+}
+
+static void addcomputer_clicked_cb(G_GNUC_UNUSED GtkButton * start_btn,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ g_assert(server_port != NULL);
+ new_computer_player(NULL, server_port, want_ai_chat);
+ config_set_int("ai/enable-chat", want_ai_chat);
+}
+
+
+static void gui_player_add(void *data_in)
+{
+ Player *player = data_in;
+ log_message(MSG_INFO, _("Player %s from %s entered\n"),
+ player->name, player->location);
+}
+
+static void gui_player_remove(void *data)
+{
+ Player *player = data;
+ log_message(MSG_INFO, _("Player %s from %s left\n"), player->name,
+ player->location);
+}
+
+static void gui_player_rename(void *data)
+{
+ Player *player = data;
+ log_message(MSG_INFO, _("Player %d is now %s\n"), player->num,
+ player->name);
+}
+
+static gboolean everybody_left(G_GNUC_UNUSED gpointer data)
+{
+ if (server_stop())
+ gui_set_server_state(FALSE);
+ return FALSE;
+}
+
+static void gui_player_change(void *data)
+{
+ Game *game = data;
+ GList *current;
+ guint number_of_players = 0;
+
+ gtk_list_store_clear(store);
+ playerlist_inc_use_count(game);
+ for (current = game->player_list; current != NULL;
+ current = g_list_next(current)) {
+ GtkTreeIter iter;
+ Player *p = current->data;
+ gboolean isViewer;
+
+ isViewer = player_is_viewer(p->game, p->num);
+ if (!isViewer && !p->disconnected)
+ number_of_players++;
+
+ gtk_list_store_append(store, &iter);
+ gtk_list_store_set(store, &iter,
+ PLAYER_COLUMN_NAME, p->name,
+ PLAYER_COLUMN_LOCATION, p->location,
+ PLAYER_COLUMN_NUMBER, p->num,
+ PLAYER_COLUMN_CONNECTED,
+ !p->disconnected,
+ PLAYER_COLUMN_ISVIEWER, isViewer, -1);
+ }
+ playerlist_dec_use_count(game);
+ if (number_of_players == 0 && game->is_game_over) {
+ g_timeout_add(100, everybody_left, NULL);
+ }
+}
+
+static void add_game_to_list(gpointer name,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ GameParams *a = (GameParams *) name;
+ select_game_add_with_map(SELECTGAME(select_game), a->title,
+ a->map);
+}
+
+static void overridden_hostname_changed_cb(GtkEntry * widget,
+ G_GNUC_UNUSED gpointer
+ user_data)
+{
+ const gchar *text;
+
+ text = gtk_entry_get_text(widget);
+ while (*text != '\0' && isspace(*text))
+ text++;
+ if (overridden_hostname)
+ g_free(overridden_hostname);
+ overridden_hostname = g_strdup(text);
+}
+
+static void meta_server_changed_cb(GtkWidget * widget,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ const gchar *text;
+
+ text = gtk_entry_get_text(GTK_ENTRY(widget));
+ while (*text != '\0' && isspace(*text))
+ text++;
+ meta_server_name = text;
+}
+
+static GtkWidget *build_game_settings(GtkWidget * parent,
+ GtkWindow * main_window)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+
+ tooltips = gtk_tooltips_new();
+
+ frame = gtk_frame_new(_("Game Parameters"));
+ gtk_widget_show(frame);
+ gtk_box_pack_start(GTK_BOX(parent), frame, FALSE, TRUE, 0);
+
+ vbox = gtk_vbox_new(FALSE, 3);
+ gtk_widget_show(vbox);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
+
+ select_game = select_game_new();
+ gtk_widget_show(select_game);
+ g_signal_connect(G_OBJECT(select_game), "activate",
+ G_CALLBACK(game_activate), NULL);
+ gtk_box_pack_start(GTK_BOX(vbox), select_game, FALSE, FALSE, 0);
+
+ game_settings = game_settings_new(TRUE);
+ gtk_widget_show(game_settings);
+ gtk_box_pack_start(GTK_BOX(vbox), game_settings, TRUE, TRUE, 0);
+
+ g_signal_connect(G_OBJECT(game_settings), "check",
+ G_CALLBACK(check_vp_cb), main_window);
+
+ return frame;
+}
+
+static GtkWidget *build_game_rules(GtkWidget * parent)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+
+ tooltips = gtk_tooltips_new();
+
+ frame = gtk_frame_new(_("Rules"));
+ gtk_widget_show(frame);
+ gtk_box_pack_start(GTK_BOX(parent), frame, FALSE, TRUE, 0);
+
+ vbox = gtk_vbox_new(FALSE, 3);
+ gtk_widget_show(vbox);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 3);
+
+ game_rules = game_rules_new();
+ gtk_widget_show(game_rules);
+ gtk_box_pack_start(GTK_BOX(vbox), game_rules, TRUE, TRUE, 0);
+
+ return frame;
+}
+
+static void
+my_cell_player_viewer_to_text(G_GNUC_UNUSED GtkTreeViewColumn *
+ tree_column, GtkCellRenderer * cell,
+ GtkTreeModel * tree_model,
+ GtkTreeIter * iter, gpointer data)
+{
+ gboolean b;
+
+ /* Get the value from the model. */
+ gtk_tree_model_get(tree_model, iter, GPOINTER_TO_INT(data), &b,
+ -1);
+ g_object_set(cell, "text", b ?
+ /* Role of the player: viewer */
+ _("Viewer") :
+ /* Role of the player: player */
+ _("Player"), NULL);
+}
+
+static GtkWidget *build_interface(GtkWindow * main_window)
+{
+ GtkWidget *vbox;
+ GtkWidget *vbox_settings;
+ GtkWidget *vbox_connected;
+ GtkWidget *vbox_ai;
+ GtkWidget *frame;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *scroll_win;
+ GtkWidget *message_text;
+ GtkTooltips *tooltips;
+ gint novar;
+ gboolean default_returned;
+ gchar *gamename;
+ gint temp;
+ GameParams *params;
+ GtkWidget *vbox_rules;
+
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ tooltips = gtk_tooltips_new();
+
+ vbox = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+
+ settings_notebook = gtk_notebook_new();
+ gtk_widget_show(settings_notebook);
+ gtk_notebook_set_show_border(GTK_NOTEBOOK(settings_notebook),
+ FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox), settings_notebook, FALSE, TRUE,
+ 0);
+
+ vbox_settings = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox_settings);
+ gtk_notebook_append_page(GTK_NOTEBOOK(settings_notebook),
+ vbox_settings,
+ gtk_label_new(_("Game Settings")));
+
+ vbox_rules = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox_rules);
+ gtk_notebook_append_page(GTK_NOTEBOOK(settings_notebook),
+ vbox_rules,
+ gtk_label_new(_("Game Rules")));
+
+ /* Game settings frame */
+ game_frame = build_game_settings(vbox_settings, main_window);
+
+ /* Rules frame */
+ rules_frame = build_game_rules(vbox_rules);
+ gtk_widget_show(rules_frame);
+
+ /* Fill the GUI with the saved settings */
+ gamename =
+ config_get_string("game/name=Default", &default_returned);
+ load_game_types(get_pioneers_dir());
+ params = cfg_set_game(gamename);
+ if (params == NULL)
+ params = cfg_set_game("Default");
+ select_game_set_default(SELECTGAME(select_game), gamename);
+ game_list_foreach(add_game_to_list, NULL);
+ g_free(gamename);
+
+ /* If a setting is not found, don't override the settings that came
+ * with the game */
+ g_assert(params != NULL);
+ temp = config_get_int("game/random-terrain", &default_returned);
+ if (!default_returned)
+ cfg_set_terrain_type(params, temp);
+ temp = config_get_int("game/num-players", &default_returned);
+ if (!default_returned)
+ cfg_set_num_players(params, temp);
+ temp = config_get_int("game/victory-points", &default_returned);
+ if (!default_returned)
+ cfg_set_victory_points(params, temp);
+ temp = config_get_int("game/sevens-rule", &default_returned);
+ if (!default_returned)
+ cfg_set_sevens_rule(params, temp);
+ temp = config_get_int("game/use-pirate", &default_returned);
+ if (!default_returned)
+ params->use_pirate = temp;
+ temp = config_get_int("game/strict-trade", &default_returned);
+ if (!default_returned)
+ params->strict_trade = temp;
+ temp = config_get_int("game/domestic-trade", &default_returned);
+ if (!default_returned)
+ params->domestic_trade = temp;
+ update_game_settings(params);
+ params_free(params);
+
+ server_frame = gtk_frame_new(_("Server Parameters"));
+ gtk_widget_show(server_frame);
+ gtk_box_pack_start(GTK_BOX(vbox_settings), server_frame, FALSE,
+ TRUE, 0);
+
+ table = gtk_table_new(6, 2, FALSE);
+ gtk_widget_show(table);
+ gtk_container_add(GTK_CONTAINER(server_frame), table);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 3);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 5);
+
+ label = gtk_label_new(_("Server Port"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ port_entry = gtk_entry_new();
+ g_signal_connect(G_OBJECT(port_entry), "changed",
+ G_CALLBACK(port_entry_changed_cb), NULL);
+ gtk_widget_show(port_entry);
+ gtk_table_attach(GTK_TABLE(table), port_entry, 1, 2, 0, 1,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0,
+ 0);
+ gtk_tooltips_set_tip(tooltips, port_entry,
+ _("The port for the game server"), NULL);
+
+ register_toggle =
+ gtk_check_button_new_with_label(_("Register Server"));
+ gtk_widget_show(register_toggle);
+ gtk_table_attach(GTK_TABLE(table), register_toggle, 0, 2, 1, 2,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0,
+ 0);
+ g_signal_connect(G_OBJECT(register_toggle), "toggled",
+ G_CALLBACK(register_toggle_cb), NULL);
+ gtk_tooltips_set_tip(tooltips, register_toggle,
+ _("Register this game at the meta server"),
+ NULL);
+
+ label = gtk_label_new(_("Meta Server"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ meta_entry = gtk_entry_new();
+ g_signal_connect(G_OBJECT(meta_entry), "changed",
+ G_CALLBACK(meta_server_changed_cb), NULL);
+ gtk_widget_show(meta_entry);
+ gtk_table_attach(GTK_TABLE(table), meta_entry, 1, 2, 2, 3,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0,
+ 0);
+ gtk_tooltips_set_tip(tooltips, meta_entry,
+ _("The address of the meta server"), NULL);
+
+ label = gtk_label_new(_("Reported Hostname"));
+ gtk_widget_show(label);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4,
+ GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
+
+ overridden_hostname_entry = gtk_entry_new();
+ g_signal_connect(G_OBJECT(overridden_hostname_entry), "changed",
+ G_CALLBACK(overridden_hostname_changed_cb), NULL);
+ gtk_widget_show(overridden_hostname_entry);
+ gtk_table_attach(GTK_TABLE(table), overridden_hostname_entry, 1, 2,
+ 3, 4, GTK_EXPAND | GTK_FILL,
+ GTK_EXPAND | GTK_FILL, 0, 0);
+ gtk_tooltips_set_tip(tooltips, overridden_hostname_entry,
+ _
+ ("The public name of this computer (needed when playing behind a firewall)"),
+ NULL);
+
+ random_toggle =
+ gtk_check_button_new_with_label(_("Random Turn Order"));
+ gtk_widget_show(random_toggle);
+ gtk_table_attach(GTK_TABLE(table), random_toggle, 0, 2, 4, 5,
+ GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0,
+ 0);
+ g_signal_connect(G_OBJECT(random_toggle), "toggled",
+ G_CALLBACK(random_toggle_cb), NULL);
+ gtk_tooltips_set_tip(tooltips, random_toggle,
+ _("Randomize turn order"), NULL);
+
+ /* Initialize server-settings */
+ server_port = config_get_string("server/port="
+ PIONEERS_DEFAULT_GAME_PORT,
+ &novar);
+ gtk_entry_set_text(GTK_ENTRY(port_entry), server_port);
+
+ novar = 0;
+ meta_server_name = config_get_string("server/meta-server", &novar);
+ if (novar || !strlen(meta_server_name)
+ || !strncmp(meta_server_name, "gnocatan.debian.net",
+ strlen(meta_server_name) + 1))
+ meta_server_name = get_meta_server_name(TRUE);
+ gtk_entry_set_text(GTK_ENTRY(meta_entry), meta_server_name);
+
+ novar = 0;
+ overridden_hostname =
+ config_get_string("server/overridden-hostname", &novar);
+ if (novar)
+ overridden_hostname = g_strdup("");
+ gtk_entry_set_text(GTK_ENTRY(overridden_hostname_entry),
+ overridden_hostname);
+
+ register_server =
+ config_get_int_with_default("server/register", TRUE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(register_toggle),
+ register_server);
+ register_toggle_cb(GTK_TOGGLE_BUTTON(register_toggle), NULL);
+
+ random_order =
+ config_get_int_with_default("server/random-seating-order",
+ TRUE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(random_toggle),
+ random_order);
+
+ vbox_settings = gtk_vbox_new(FALSE, 5);
+ gtk_notebook_append_page(GTK_NOTEBOOK(settings_notebook),
+ vbox_settings,
+ gtk_label_new(_("Running Game")));
+
+ frame = gtk_frame_new(_("Players Connected"));
+ gtk_widget_show(frame);
+ gtk_box_pack_start(GTK_BOX(vbox_settings), frame, TRUE, TRUE, 0);
+
+ vbox_connected = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox_connected);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox_connected), 5);
+ gtk_container_add(GTK_CONTAINER(frame), vbox_connected);
+
+ scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_widget_show(scroll_win);
+ gtk_box_pack_start(GTK_BOX(vbox_connected), scroll_win, TRUE, TRUE,
+ 0);
+
+ gtk_container_set_border_width(GTK_CONTAINER(scroll_win), 3);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+
+ /* Create model */
+ store = gtk_list_store_new(PLAYER_COLUMN_LAST,
+ G_TYPE_BOOLEAN,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_INT, G_TYPE_BOOLEAN);
+
+ /* Create graphical representation of the model */
+ label = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
+ /* The theme should decide if hints are used */
+ /* gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(label), TRUE); */
+ gtk_container_add(GTK_CONTAINER(scroll_win), label);
+ tooltips = gtk_tooltips_new();
+ gtk_tooltips_set_tip(tooltips, label,
+ _
+ ("Shows all players and viewers connected to the server"),
+ NULL);
+
+ /* Now create columns */
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Connected"),
+ gtk_cell_renderer_toggle_new
+ (), "active",
+ PLAYER_COLUMN_CONNECTED,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(label), column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Is the player currently connected?"),
+ NULL);
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Name"),
+ gtk_cell_renderer_text_new
+ (), "text",
+ PLAYER_COLUMN_NAME,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(label), column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Name of the player"), NULL);
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Location"),
+ gtk_cell_renderer_text_new
+ (), "text",
+ PLAYER_COLUMN_LOCATION,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(label), column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Host name of the player"), NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Number"), renderer,
+ "text",
+ PLAYER_COLUMN_NUMBER,
+ NULL);
+ g_object_set(renderer, "xalign", 1.0f, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(label), column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Player number"), NULL);
+
+ renderer = gtk_cell_renderer_text_new();
+ column =
+ gtk_tree_view_column_new_with_attributes(_("Role"), renderer,
+ NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(label), column);
+ gtk_tooltips_set_tip(tooltips, column->button,
+ _("Player of viewer"), NULL);
+
+ gtk_tree_view_column_set_cell_data_func(column, renderer,
+ my_cell_player_viewer_to_text,
+ GINT_TO_POINTER
+ (PLAYER_COLUMN_ISVIEWER),
+ NULL);
+
+ gtk_widget_show(label);
+
+ launchclient_btn =
+ gtk_button_new_with_label(_("Launch Pioneers Client"));
+ gtk_widget_show(launchclient_btn);
+ gtk_box_pack_start(GTK_BOX(vbox_connected), launchclient_btn,
+ FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(launchclient_btn), "clicked",
+ G_CALLBACK(launchclient_clicked_cb), NULL);
+ gtk_tooltips_set_tip(tooltips, launchclient_btn,
+ _("Launch the Pioneers Client"), NULL);
+
+ ai_frame = gtk_frame_new(_("Computer Players"));
+ gtk_widget_show(ai_frame);
+ gtk_box_pack_start(GTK_BOX(vbox_settings), ai_frame, FALSE, FALSE,
+ 0);
+ vbox_ai = gtk_vbox_new(FALSE, 5);
+ gtk_widget_show(vbox_ai);
+ gtk_container_set_border_width(GTK_CONTAINER(vbox_ai), 5);
+ gtk_container_add(GTK_CONTAINER(ai_frame), vbox_ai);
+
+ chat_toggle = gtk_check_button_new_with_label(_("Enable Chat"));
+ gtk_widget_show(chat_toggle);
+ gtk_box_pack_start(GTK_BOX(vbox_ai), chat_toggle, TRUE, TRUE, 0);
+ g_signal_connect(G_OBJECT(chat_toggle), "toggled",
+ G_CALLBACK(chat_toggle_cb), NULL);
+ gtk_tooltips_set_tip(tooltips, chat_toggle,
+ _("Enable chat messages"), NULL);
+
+ want_ai_chat = config_get_int_with_default("ai/enable-chat", TRUE);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(chat_toggle),
+ want_ai_chat);
+
+ addcomputer_btn =
+ gtk_button_new_with_label(_("Add Computer Player"));
+ gtk_widget_show(addcomputer_btn);
+ gtk_box_pack_start(GTK_BOX(vbox_ai), addcomputer_btn, FALSE, FALSE,
+ 0);
+ g_signal_connect(G_OBJECT(addcomputer_btn), "clicked",
+ G_CALLBACK(addcomputer_clicked_cb), NULL);
+ gtk_tooltips_set_tip(tooltips, addcomputer_btn,
+ _("Add a computer player to the game"), NULL);
+
+ start_btn = gtk_button_new();
+ gtk_widget_show(start_btn);
+
+ gtk_box_pack_start(GTK_BOX(vbox), start_btn, FALSE, FALSE, 0);
+ g_signal_connect(G_OBJECT(start_btn), "clicked",
+ G_CALLBACK(start_clicked_cb), NULL);
+
+ frame = gtk_frame_new(_("Messages"));
+ gtk_widget_show(frame);
+ gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+
+ scroll_win = gtk_scrolled_window_new(NULL, NULL);
+ gtk_widget_show(scroll_win);
+ gtk_container_add(GTK_CONTAINER(frame), scroll_win);
+ gtk_container_set_border_width(GTK_CONTAINER(scroll_win), 3);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ message_text = gtk_text_view_new();
+ gtk_widget_show(message_text);
+ gtk_container_add(GTK_CONTAINER(scroll_win), message_text);
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(message_text),
+ GTK_WRAP_WORD);
+ gtk_tooltips_set_tip(tooltips, message_text,
+ _("Messages from the server"), NULL);
+ message_window_set_text(message_text);
+
+ gui_set_server_state(FALSE);
+ return vbox;
+}
+
+static void check_vp_cb(G_GNUC_UNUSED GObject * caller,
+ gpointer main_window)
+{
+ const gchar *title;
+ GameParams *params;
+
+ title = select_game_get_active(SELECTGAME(select_game));
+ params = params_copy(game_list_find_item(title));
+ cfg_set_num_players(params,
+ game_settings_get_players(GAMESETTINGS
+ (game_settings)));
+ cfg_set_victory_points(params,
+ game_settings_get_victory_points
+ (GAMESETTINGS(game_settings)));
+ cfg_set_sevens_rule(params,
+ game_rules_get_sevens_rule
+ (GAMERULES(game_rules)));
+ cfg_set_terrain_type(params,
+ game_rules_get_random_terrain
+ (GAMERULES(game_rules)));
+ params->strict_trade =
+ game_rules_get_strict_trade(GAMERULES(game_rules));
+ params->use_pirate =
+ game_rules_get_use_pirate(GAMERULES(game_rules));
+ params->domestic_trade =
+ game_rules_get_domestic_trade(GAMERULES(game_rules));
+ update_game_settings(params);
+
+ check_victory_points(params, main_window);
+}
+
+static void quit_cb(void)
+{
+ gtk_main_quit();
+}
+
+static void help_about_cb(void)
+{
+ const gchar *authors[] = {
+ AUTHORLIST
+ };
+ aboutbox_display(_("The Pioneers Game Server"), authors);
+}
+
+void game_is_over(G_GNUC_UNUSED Game * game)
+{
+ /* Wait for all players to disconnect,
+ * then enable the UI
+ */
+ log_message(MSG_INFO, _("The game is over.\n"));
+}
+
+void request_server_stop(void)
+{
+ if (server_stop())
+ gui_set_server_state(FALSE);
+}
+
+static GOptionEntry commandline_entries[] = {
+ {"debug", '\0', 0, G_OPTION_ARG_NONE, &enable_debug,
+ /* Commandline option of server-gtk: enable debug logging */
+ N_("Enable debug messages"), NULL},
+ {"version", '\0', 0, G_OPTION_ARG_NONE, &show_version,
+ /* Commandline option of server-gtk: version */
+ N_("Show version information"), NULL},
+ {NULL, '\0', 0, 0, NULL, NULL, NULL}
+};
+
+int main(int argc, char *argv[])
+{
+ gchar *icon_file;
+ GtkWidget *window;
+ GtkWidget *vbox;
+ GtkWidget *menubar;
+ GtkActionGroup *action_group;
+ GtkUIManager *ui_manager;
+ GtkAccelGroup *accel_group;
+ GError *error = NULL;
+ GOptionContext *context;
+ HildonProgram *program;
+ GtkWidget *menu;
+
+ net_init();
+
+ /* set the UI driver to GTK_Driver, since we're using gtk */
+ set_ui_driver(>K_Driver);
+
+ /* flush out the rest of the driver with the server callbacks */
+ driver->player_added = gui_player_add;
+ driver->player_renamed = gui_player_rename;
+ driver->player_removed = gui_player_remove;
+ driver->player_change = gui_player_change;
+
+ /* Initialize frontend inspecific things */
+ server_init();
+
+#ifdef ENABLE_NLS
+ setlocale(LC_ALL, "");
+ /* Gtk+ handles the locale, we must bind the translations */
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+ bind_textdomain_codeset(PACKAGE, "UTF-8");
+#endif
+
+ /* Long description in the commandline for server-gtk: help */
+ context = g_option_context_new(_("- Host a game of Pioneers"));
+ g_option_context_add_main_entries(context, commandline_entries,
+ PACKAGE);
+ g_option_context_add_group(context, gtk_get_option_group(TRUE));
+ g_option_context_parse(context, &argc, &argv, &error);
+ if (error != NULL) {
+ g_print("%s\n", error->message);
+ g_error_free(error);
+ return 1;
+ }
+ if (show_version) {
+ g_print(_("Pioneers version:"));
+ g_print(" ");
+ g_print(FULL_VERSION);
+ g_print("\n");
+ return 0;
+ }
+
+ set_enable_debug(enable_debug);
+
+#if 0
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ /* Name in the titlebar of the server */
+ gtk_window_set_title(GTK_WINDOW(window), _("Pioneers Server"));
+#endif
+
+ program = HILDON_PROGRAM(hildon_program_get_instance());
+ window = hildon_window_new();
+ hildon_program_add_window(program, HILDON_WINDOW(window));
+ g_set_application_name(_("Pioneers Server"));
+
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+
+ action_group = gtk_action_group_new("MenuActions");
+ gtk_action_group_set_translation_domain(action_group, PACKAGE);
+ gtk_action_group_add_actions(action_group, entries,
+ G_N_ELEMENTS(entries), window);
+
+ ui_manager = gtk_ui_manager_new();
+ gtk_ui_manager_insert_action_group(ui_manager, action_group, 0);
+
+ accel_group = gtk_ui_manager_get_accel_group(ui_manager);
+ gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
+
+ error = NULL;
+ if (!gtk_ui_manager_add_ui_from_string
+ (ui_manager, ui_description, -1, &error)) {
+ g_message(_("Building menus failed: %s"), error->message);
+ g_error_free(error);
+ return 1;
+ }
+
+ config_init("pioneers-server");
+
+ themes_init();
+
+ icon_file =
+ g_build_filename(DATADIR, "pixmaps", MAINICON_FILE, NULL);
+ if (g_file_test(icon_file, G_FILE_TEST_EXISTS)) {
+ gtk_window_set_default_icon_from_file(icon_file, NULL);
+ } else {
+ g_warning("Pixmap not found: %s", icon_file);
+ }
+ g_free(icon_file);
+
+ menubar = gtk_ui_manager_get_widget(ui_manager, "/MainMenu");
+ //gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
+
+ menu = gtk_menu_new();
+ gtk_container_foreach(GTK_CONTAINER(menubar), (GtkCallback)gtk_widget_reparent, menu);
+ hildon_window_set_menu(HILDON_WINDOW(window), GTK_MENU(menu));
+
+ gtk_box_pack_start(GTK_BOX(vbox),
+ build_interface(GTK_WINDOW(window)), TRUE, TRUE,
+ 0);
+
+ gtk_widget_show_all(window);
+ gui_set_server_state(FALSE);
+ g_signal_connect(G_OBJECT(window), "delete_event",
+ G_CALLBACK(quit_cb), NULL);
+
+ /* in theory, all windows are created now...
+ * set logging to message window */
+ log_set_func_message_window();
+
+ gtk_main();
+
+ config_finish();
+ net_finish();
+ g_option_context_free(context);
+ return 0;
+}
Added: trunk/server/gtk/pioneers-server.desktop
===================================================================
--- trunk/server/gtk/pioneers-server.desktop (rev 0)
+++ trunk/server/gtk/pioneers-server.desktop 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Version=1.0
+Encoding=UTF-8
+Name=Pioneers Server
+Comment=Host a game of Pioneers
+Exec=pioneers-server-gtk
+Icon=pioneers-server.png
+Terminal=false
+Type=Application
+Categories=Game;BoardGame;StrategyGame;GNOME;GTK;
Added: trunk/server/gtk/pioneers-server.rc
===================================================================
--- trunk/server/gtk/pioneers-server.rc (rev 0)
+++ trunk/server/gtk/pioneers-server.rc 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1 @@
+1 ICON DISCARDABLE "server/gtk/pioneers-server.ico"
Added: trunk/server/gtk/pioneers-server.svg
===================================================================
--- trunk/server/gtk/pioneers-server.svg (rev 0)
+++ trunk/server/gtk/pioneers-server.svg 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,645 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
+"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ version="1.0"
+ x="0"
+ y="0"
+ width="354.330688"
+ height="354.330688"
+ id="svg620"
+ xml:space="preserve"><defs
+ id="defs622" /><g
+ transform="matrix(1.38939,0,0,1.39,-162.8163,-618.7101)"
+ style="font-size:12;"
+ id="g638"><path
+ d="M 184.1155 485.4331 L 245.4874 450 L 306.8593 485.4331 L 306.8593 556.2992 L 245.4874 591.7323 L 184.1155 556.2992 L 184.1155 485.4331 z "
+ style="fill:#800000;fill-rule:evenodd;stroke:#000000;stroke-width:3.5433;"
+ id="path616" /><path
+ d="M 306.8593 556.2992 L 368.2311 591.7323 L 368.2311 662.5984 L 306.8593 698.0315 L 245.4874 662.5984 L 245.4874 591.7323 L 306.8593 556.2992 z "
+ style="fill:#008000;fill-rule:evenodd;stroke:#000000;stroke-width:3.5433;"
+ id="path617" /><path
+ d="M 184.1155 556.2939 L 122.7437 591.7283 L 122.7437 662.597 L 184.1155 698.0314 L 245.4874 662.597 L 245.4874 591.7283 L 184.1155 556.2939 z "
+ style="fill:#c37f41;fill-rule:evenodd;stroke:#000000;stroke-width:3.543365;"
+ id="path618" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,81.85915,-132.835)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path624" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,-40.88452,-132.835)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path625" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,21.57656,-239.1342)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path626" /><text
+ x="95.3142548"
+ y="212.637573"
+ transform="translate(141.3132,320.9463)"
+ style="font-size:36;font-weight:normal;fill:#ff0000;stroke-width:1;font-family:FreeSans;"
+ id="text627"><tspan
+ id="tspan628">8</tspan></text><text
+ x="70.7458191"
+ y="254.86348"
+ transform="translate(104.0006,385.1866)"
+ style="font-size:36;font-weight:normal;stroke-width:1;font-family:FreeSans;"
+ id="text630"><tspan
+ id="tspan631">4</tspan></text><text
+ x="88.1663055"
+ y="224.654419"
+ transform="translate(208.7261,415.2287)"
+ style="font-size:36;font-weight:normal;stroke-width:1;font-family:FreeSans;"
+ id="text633"><tspan
+ id="tspan634">9</tspan></text></g><g
+ transform="translate(11.43002,43.43407)"
+ style="font-size:12;stroke:#000000;"
+ id="Layer_x0020_7"><path
+ d="M 64 52 L 0 52 L 0 0 L 64 0 L 64 52 z "
+ style="fill:none;stroke:none;"
+ id="path2054" /></g><g
+ transform="matrix(1.328155,0,0,1.328155,-155.5644,-103.0208)"
+ style="font-size:12;"
+ id="g2638"><g
+ transform="matrix(7,0,0,7,-76.57004,-14.22342)"
+ style="fill:#dedede;stroke:#000000;"
+ id="Layer_x0020_5"><g
+ style="opacity:0.35;"
+ id="g1895"><path
+ d="M 30 43.4 L 41.1 35.9 C 41.7 35.5 42.6 35.4 43.3 35.6 L 62.1 41.5 C 62.7 41.7 62.8 42.2 62.3 42.6 L 61.6 43.1 C 60.5 44.1 63.7 43.9 62.3 45.1 L 55.8 50.3 C 54.7 51.4 53.2 49.4 52.1 50.2 L 50.9 51 C 50.4 51.4 45.6 51.2 45.6 51.2 L 30 43.4 z "
+ style="fill:#000000;stroke:none;"
+ id="path1896" /></g><path
+ d="M 57.4 36.4 C 57.4 36.4 57.4 36.4 57.4 36.4 C 57.4 36.4 57.3 36.4 57.3 36.3 C 56.8 36.1 44.3 32.2 43.7 32 C 43.1 31.8 42.3 31.7 42 31.8 C 41.7 31.9 31 37.5 30.4 37.9 C 30.3 37.9 30.3 38 30.2 38.1 C 29.4 38.7 29.4 39.7 29.4 39.7 C 29.4 39.7 29.4 39.7 29.4 39.6 C 29.4 39.6 29.4 39.7 29.4 39.7 L 29.5 42.4 C 29.5 42.9 29.6 43.2 30 43.4 C 30 43.4 43.3 49.3 44.9 49.7 C 45 49.7 45 49.7 45.1 49.7 C 45.1 49.7 45.1 49.7 45.1 49.7 C 45.8 49.9 46 49.8 46.4 49.6 C 46.4 49.6 46.5 49.6 46.5 49.5 C 46.8 49.3 57.4 41.8 57.8 41.5 C 58.1 41.2 58.2 41 58.2 40.7 C 58.2 40.4 58.5 38.3 58.5 37.9 C 58.5 37.9 58.5 37.8 58.5 37.8 C 58.5 37.8 58.5 37.8 58.5 37.8 C 58.6 37.4 58.6 36.6 57.4 36.3 L 57.4 36.4 z M 45.8 49.2 C 45.8 49.2 45.8 49.2 45.8 49.2 L 45.8 49.2 L 45.8 49.2 C 45.8 49.2 45.8 49.3 45.8 49.3 C 45.8 49.3 45.8 49.2 45.8 49.2 L 45.8 49.2 z M 57 38 C 57.4 37.7 57.7 37.5 57.7 37.5 C 57.7 37.5 57.4 37.7 57 38 C 56.3 38.5 55.3 39.1 54.2 39.8 C 56 38.6 57.6 37.6 58 37.3 C 57.9 37.4 57.6 37.6 57.1 37.9 L 57 38 z "
+ style="fill:#000000;stroke-width:3.0514;stroke-linecap:round;stroke-linejoin:round;"
+ id="path1897" /><linearGradient
+ x1="31.8530006"
+ y1="38.8017998"
+ x2="59.2714996"
+ y2="38.8017998"
+ id="aigrd78"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9935,0.1137,-0.1137,0.9935,3.2959,-5.4479)"><stop
+ style="stop-color:#ebebeb;stop-opacity:1;"
+ offset="0"
+ id="stop1899" /><stop
+ style="stop-color:#eaeaea;stop-opacity:1;"
+ offset="1"
+ id="stop1900" /></linearGradient><path
+ d="M 43.7 32.1 C 43.1 31.9 42.3 31.8 42 31.9 C 41.7 32 31 37.6 30.4 38 C 29.8 38.3 29.7 39 30.4 39.2 C 31.1 39.5 44.6 44.4 45.2 44.6 C 45.8 44.8 46.7 44.8 47 44.6 C 47.3 44.4 57.7 37.6 58.1 37.4 C 58.4 37.1 57.9 36.6 57.4 36.5 C 56.9 36.3 44.4 32.4 43.8 32.2 L 43.7 32.1 z "
+ style="fill:url(#aigrd78);stroke:none;"
+ id="path1901" /><linearGradient
+ x1="32.5639992"
+ y1="45.1171989"
+ x2="47.0684013"
+ y2="46.1618996"
+ id="aigrd79"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9935,0.1137,-0.1137,0.9935,3.2959,-5.4479)"><stop
+ style="stop-color:#f8f8f8;stop-opacity:1;"
+ offset="0"
+ id="stop1903" /><stop
+ style="stop-color:#c9c9c9;stop-opacity:1;"
+ offset="1"
+ id="stop1904" /></linearGradient><path
+ d="M 29.4 39.7 C 29.4 39.2 29.8 38.9 30.1 39 C 30.5 39.1 44.9 44.5 45.4 44.8 C 45.9 45.1 46.2 45.3 46.2 45.8 C 46.2 46.2 45.9 48.7 45.8 49 C 45.8 49.4 45.4 49.8 44.9 49.6 C 43.3 49.3 30 43.4 30 43.4 C 29.6 43.2 29.5 43 29.5 42.4 L 29.4 39.7 L 29.4 39.7 z "
+ style="fill:url(#aigrd79);stroke:none;"
+ id="path1905" /><linearGradient
+ x1="49.9141006"
+ y1="47.6913986"
+ x2="58.8602982"
+ y2="37.1593018"
+ id="aigrd80"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9935,0.1137,-0.1137,0.9935,3.2959,-5.4479)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop1907" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop1908" /></linearGradient><path
+ d="M 46.5 49.6 C 46.2 49.8 45.7 49.5 45.8 49 C 45.9 48.5 46.1 46.2 46.2 45.8 C 46.3 45.4 46.5 45 46.8 44.7 C 47.1 44.5 57.6 37.7 58 37.4 C 58.4 37.1 58.6 37.7 58.5 38 C 58.5 38.4 58.2 40.5 58.2 40.8 C 58.2 41.1 58.1 41.3 57.8 41.6 C 57.5 41.9 46.8 49.4 46.5 49.6 L 46.5 49.6 z "
+ style="fill:url(#aigrd80);stroke:none;"
+ id="path1909" /><g
+ style="fill:#ffffff;stroke:none;"
+ id="g1910"><path
+ d="M 45.8 44.5 C 44.9 44.4 30.1 38.8 30 38.8 C 29.9 38.8 30 38.2 30.4 38 C 29.4 38.6 29.4 39.7 29.4 39.7 C 29.4 39.7 29.5 39.2 30 39.1 C 31.8 39.8 44.6 44.8 45.1 44.9 C 45.6 45.1 45.8 45.7 45.8 46.2 L 45.9 49.2 L 46.3 46.2 C 46.4 45.7 46.6 44.8 47.2 44.5 C 47.5 44.3 54.3 39.8 56.8 38.1 C 54.2 39.8 47 44.5 45.8 44.4 L 45.8 44.5 z "
+ id="path1911" /><path
+ d="M 56.8 38.2 C 57.4 37.8 57.7 37.6 57.7 37.6 C 57.7 37.6 57.3 37.8 56.8 38.2 z "
+ id="path1912" /></g><path
+ d="M 46.4 49.6 C 46.1 49.9 45.8 49.9 45.1 49.7 C 45.6 49.6 45.8 49.2 45.8 49.2 C 45.8 49.2 45.9 49.5 46.4 49.5 L 46.4 49.6 z "
+ style="fill:#848484;stroke:none;"
+ id="path1913" /><path
+ d="M 57.4 36.4 C 58 36.7 58.2 37.1 57.9 37.4 C 58.2 37.2 58.4 38 58.4 38 C 58.5 37.6 58.5 36.8 57.3 36.5 L 57.4 36.4 z "
+ style="fill:#545454;stroke:none;"
+ id="path1914" /><linearGradient
+ x1="39.0839996"
+ y1="46.0723"
+ x2="44.1825981"
+ y2="46.0723"
+ id="aigrd81"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#2a2a2a;stop-opacity:1;"
+ offset="0"
+ id="stop1916" /><stop
+ style="stop-color:#585858;stop-opacity:1;"
+ offset="0.4743"
+ id="stop1917" /><stop
+ style="stop-color:#878787;stop-opacity:1;"
+ offset="1"
+ id="stop1918" /></linearGradient><path
+ d="M 39.2 44.4 L 39.2 45 L 44.2 47 L 44.2 46.4 L 39.2 44.4 z "
+ style="fill:url(#aigrd81);stroke:none;"
+ id="path1919" /><path
+ d="M 39.2 45 L 38.9 45.2 L 38.9 43.9 L 44.4 46.1 L 44.2 46.4 L 39.2 44.4 L 39.2 45 L 39.2 45 z "
+ style="opacity:0.22;fill:#000000;stroke:none;"
+ id="path1920" /><path
+ d="M 44.4 47.4 L 44.4 46.2 L 44.2 46.5 L 44.2 47.1 L 39.2 45.1 L 38.9 45.3 L 44.4 47.5 L 44.4 47.4 z "
+ style="opacity:0.72;fill:#ffffff;stroke:none;"
+ id="path1921" /><linearGradient
+ x1="55.0634995"
+ y1="38.9384995"
+ x2="51.4311981"
+ y2="45.7360992"
+ id="aigrd82"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop1923" /><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop1924" /></linearGradient><path
+ d="M 58.4 39.8 L 46.8 47.6 L 46.8 48 L 58.4 40.1 L 58.4 39.8 z "
+ style="opacity:0.13;fill:url(#aigrd82);stroke:none;"
+ id="path1925" /><linearGradient
+ x1="55.0634995"
+ y1="37.9443016"
+ x2="51.4308014"
+ y2="44.7425995"
+ id="aigrd83"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop1927" /><stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop1928" /></linearGradient><path
+ d="M 58.4 38.8 L 46.8 46.6 L 46.8 47 L 58.4 39.1 L 58.4 38.8 z "
+ style="opacity:0.13;fill:url(#aigrd83);stroke:none;"
+ id="path1929" /><linearGradient
+ x1="55.0634995"
+ y1="38.6171989"
+ x2="51.4300995"
+ y2="45.4166985"
+ id="aigrd84"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop1931" /><stop
+ style="stop-color:#6a6a6a;stop-opacity:1;"
+ offset="1"
+ id="stop1932" /></linearGradient><path
+ d="M 58.4 39.5 L 46.8 47.3 L 46.8 47.7 L 58.4 39.8 L 58.4 39.5 z "
+ style="opacity:0.13;fill:url(#aigrd84);stroke:none;"
+ id="path1933" /><linearGradient
+ x1="55.0615005"
+ y1="37.625"
+ x2="51.4295006"
+ y2="44.4221001"
+ id="aigrd85"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop1935" /><stop
+ style="stop-color:#6a6a6a;stop-opacity:1;"
+ offset="1"
+ id="stop1936" /></linearGradient><path
+ d="M 58.4 38.5 L 46.8 46.3 L 46.8 46.7 L 58.4 38.8 L 58.4 38.5 z "
+ style="opacity:0.13;fill:url(#aigrd85);stroke:none;"
+ id="path1937" /><g
+ style="opacity:0.45;"
+ id="g1938"><path
+ d="M 43.1 34.3 C 41.4 33.8 38.8 34 37.3 34.7 L 33.1 36.8 C 31.5 37.6 31.6 38.7 33.2 39.3 L 46.5 44.3 L 46.9 44.8 L 48.1 48.7 L 57.1 42.5 L 55.7 38.9 C 55.7 38.9 54.9 38.2 54 37.9 L 43 34.4 L 43.1 34.3 z "
+ style="opacity:0.3;fill:#000000;stroke:none;"
+ id="path1939" /></g><radialGradient
+ cx="41.7655983"
+ cy="33.1688995"
+ r="8.16800022"
+ fx="41.7655983"
+ fy="33.1688995"
+ id="aigrd86"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#b6b6b6;stop-opacity:1;"
+ offset="0"
+ id="stop1941" /><stop
+ style="stop-color:#878787;stop-opacity:1;"
+ offset="1"
+ id="stop1942" /></radialGradient><path
+ d="M 44.1 33 C 40.3 32.9 37.2 34.1 37.2 35.7 L 37.2 36.5 C 37.1 38.1 40.1 39.6 43.9 39.7 C 47.7 39.8 50.8 38.6 50.8 37 L 50.8 36.2 C 50.9 34.6 47.9 33.1 44.1 33 z "
+ style="fill:url(#aigrd86);stroke-width:1.9099;stroke-linecap:round;stroke-linejoin:round;"
+ id="path1943" /><path
+ d="M 44.1 33 C 40.3 32.9 37.2 34.1 37.2 35.7 L 37.2 36.5 C 37.1 38.1 40.1 39.6 43.9 39.7 C 47.7 39.8 50.8 38.6 50.8 37 L 50.8 36.2 C 50.9 34.6 47.9 33.1 44.1 33 z "
+ style="fill:url(#aigrd86);stroke:none;"
+ id="path1944" /><path
+ d="M 37.3 35.3 C 37.4 36.6 38.9 38.5 45.1 38.9 C 40.3 39.2 36.6 37.7 37.3 35.3 z "
+ style="fill:#b3b3b3;stroke:none;"
+ id="path1945" /><g
+ id="g1946"><path
+ d="M 53.1 20 C 53.2 19.7 53.1 19.3 52.9 19.3 C 52.7 19.3 52.6 19.2 52.6 19.2 C 52.6 19.2 52.6 19.2 52.6 19.2 C 52.6 19.2 52.3 19.1 52 19.1 L 34.9 15.3 C 34.6 15.2 34.1 15.2 33.9 15.2 C 33.7 15.2 33.4 15.2 33.2 15.2 C 33 15.2 32.9 15.5 32.8 15.8 L 29.8 32 C 29.7 32.3 30 32.7 30.3 32.8 L 46.5 38.2 C 46.8 38.3 47.1 38.4 47.1 38.4 C 47.1 38.4 47.2 38.4 47.4 38.5 C 47.6 38.6 47.8 38.6 47.9 38.6 C 48 38.6 48.1 38.6 48.2 38.5 C 48.3 38.5 48.5 38.4 48.5 38.4 C 48.5 38.4 48.7 38.4 48.9 38.3 C 49.1 38.2 49.3 37.9 49.4 37.6 L 53.1 20 z "
+ style="fill:#000000;stroke:none;"
+ id="path1947" /><path
+ d="M 53.1 20 C 53.2 19.7 53.1 19.3 52.9 19.3 C 52.7 19.3 52.6 19.2 52.6 19.2 C 52.6 19.2 52.6 19.2 52.6 19.2 C 52.6 19.2 52.3 19.1 52 19.1 L 34.9 15.3 C 34.6 15.2 34.1 15.2 33.9 15.2 C 33.7 15.2 33.4 15.2 33.2 15.2 C 33 15.2 32.9 15.5 32.8 15.8 L 29.8 32 C 29.7 32.3 30 32.7 30.3 32.8 L 46.5 38.2 C 46.8 38.3 47.1 38.4 47.1 38.4 C 47.1 38.4 47.2 38.4 47.4 38.5 C 47.6 38.6 47.8 38.6 47.9 38.6 C 48 38.6 48.1 38.6 48.2 38.5 C 48.3 38.5 48.5 38.4 48.5 38.4 C 48.5 38.4 48.7 38.4 48.9 38.3 C 49.1 38.2 49.3 37.9 49.4 37.6 L 53.1 20 z "
+ style="fill:none;stroke-width:3.0514;stroke-linecap:round;stroke-linejoin:round;"
+ id="path1948" /></g><g
+ id="g1949"><linearGradient
+ x1="31.6909008"
+ y1="26.7201996"
+ x2="48.2454987"
+ y2="27.9125996"
+ id="aigrd88"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#f8f8f8;stop-opacity:1;"
+ offset="0"
+ id="stop1951" /><stop
+ style="stop-color:#c9c9c9;stop-opacity:1;"
+ offset="1"
+ id="stop1952" /></linearGradient><path
+ d="M 33.7 15.3 C 33.3 15.2 32.8 15.5 32.7 15.9 L 29.8 31.7 C 29.7 32.2 30 32.6 30.4 32.8 L 47 38.4 C 47.4 38.5 47.9 38.3 48 37.8 L 51.8 20.1 C 51.9 19.7 51.6 19.2 51.2 19.1 L 33.8 15.3 L 33.7 15.3 z "
+ style="fill:url(#aigrd88);stroke:none;"
+ id="path1953" /></g><g
+ id="g1954"><linearGradient
+ x1="45.7695007"
+ y1="33.7275009"
+ x2="54.7426987"
+ y2="23.1637993"
+ id="aigrd89"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop1956" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop1957" /></linearGradient><path
+ d="M 49.5 37.5 C 49.4 37.9 49 38.4 48.6 38.5 C 48.2 38.6 47.9 38.3 48 37.8 L 51.8 20.1 C 51.9 19.7 52.3 19.3 52.6 19.3 C 53 19.3 53.2 19.7 53.1 20.1 L 49.5 37.4 L 49.5 37.5 z "
+ style="fill:url(#aigrd89);stroke:none;"
+ id="path1958" /></g><path
+ d="M 48.6 38.4 C 48.2 38.6 47.8 38.5 47.2 38.4 C 47.7 38.3 47.9 37.9 47.9 37.9 C 47.9 37.9 48 38.5 48.5 38.5 L 48.6 38.4 z "
+ style="fill:#848484;stroke:none;"
+ id="path1959" /><path
+ d="M 51.1 19.3 C 51.5 19.4 51.8 19.5 51.5 20.5 L 48.3 35.3 L 48 37.7 L 48.7 35.3 L 51.9 20.1 C 52 19.6 52.3 19.4 52.6 19.3 L 33.7 15.2 C 33.6 15.2 33.5 15.1 33.5 15.1 C 33.1 15.1 32.8 15.5 32.8 15.9 C 33 15.5 33.2 15.3 33.6 15.4 L 51.2 19.3 L 51.1 19.3 z "
+ style="fill:#ffffff;stroke:none;"
+ id="path1960" /><g
+ id="g1961"><linearGradient
+ x1="39.1200981"
+ y1="19.6478996"
+ x2="39.1200981"
+ y2="32.1001015"
+ id="aigrd90"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9994,3.430621e-2,-3.430621e-2,0.9994,1.5171,-1.6057)"><stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop1963" /><stop
+ style="stop-color:#3a4a70;stop-opacity:1;"
+ offset="1"
+ id="stop1964" /></linearGradient><path
+ d="M 44.8 34.4 L 31.7 30.1 L 34 17 L 47.8 20.2 L 44.8 34.5 L 44.8 34.4 z "
+ style="fill:url(#aigrd90);stroke-width:0.3945;"
+ id="path1965" /><linearGradient
+ x1="39.2969017"
+ y1="19.6928997"
+ x2="39.2969017"
+ y2="32.1450005"
+ id="aigrd91"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9994,3.430621e-2,-3.430621e-2,0.9994,1.5171,-1.6057)"><stop
+ style="stop-color:#343340;stop-opacity:1;"
+ offset="2.24717706e-2"
+ id="stop1967" /><stop
+ style="stop-color:#656796;stop-opacity:1;"
+ offset="1"
+ id="stop1968" /></linearGradient><path
+ d="M 45 34.5 L 31.9 30.2 L 34.1 17 L 48 20.2 L 45 34.5 z "
+ style="fill:url(#aigrd91);stroke:none;"
+ id="path1969" /><g
+ id="g1970"><linearGradient
+ x1="39.6445007"
+ y1="19.1322994"
+ x2="39.6445007"
+ y2="24.2212009"
+ id="aigrd92"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9994,3.430621e-2,-3.430621e-2,0.9994,1.5171,-1.6057)"><stop
+ style="stop-color:#e7ebef;stop-opacity:1;"
+ offset="0"
+ id="stop1972" /><stop
+ style="stop-color:#739167;stop-opacity:1;"
+ offset="1"
+ id="stop1973" /></linearGradient><path
+ d="M 34.9 17.8 C 34.8 17.8 34.7 17.9 34.7 18.1 L 33.6 24.5 C 33.6 24.7 33.6 24.8 33.7 24.8 C 37.3 25 43.4 23.5 46.8 22.1 C 46.9 22 47 21.9 47 21.7 L 47.1 21.1 C 47.1 20.9 47.1 20.8 47 20.7 L 34.8 17.8 L 34.9 17.8 z "
+ style="opacity:0.58;fill:url(#aigrd92);stroke:none;"
+ id="path1974" /></g><g
+ id="g1975" /></g><g
+ style="stroke:none;"
+ id="g1976"><g
+ id="g1977"><g
+ id="g1978"><g
+ id="g1979"><linearGradient
+ x1="46.8349991"
+ y1="31.5020008"
+ x2="47.4614983"
+ y2="30.7644005"
+ id="aigrd93"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop1981" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop1982" /></linearGradient><path
+ d="M 48.7 31.1 L 47 30.6 L 46.9 31 L 48.6 31 L 48.7 31.1 z "
+ style="fill:url(#aigrd93);"
+ id="path1983" /><path
+ d="M 48.5 31.5 L 48.6 31.1 L 46.9 31.1 L 48.5 31.5 z "
+ id="path1984" /></g><g
+ id="g1985"><linearGradient
+ x1="47.1533012"
+ y1="29.6044998"
+ x2="47.7798004"
+ y2="28.8668995"
+ id="aigrd94"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop1987" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop1988" /></linearGradient><path
+ d="M 49.1 29.2 L 47.4 28.8 L 47.3 29.2 L 49 29.2 L 49.1 29.2 z "
+ style="fill:url(#aigrd94);"
+ id="path1989" /><path
+ d="M 48.9 29.6 L 49 29.2 L 47.3 29.2 L 48.9 29.6 z "
+ id="path1990" /></g><g
+ id="g1991"><linearGradient
+ x1="47.4746017"
+ y1="27.7080002"
+ x2="48.1011009"
+ y2="26.9703999"
+ id="aigrd95"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop1993" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop1994" /></linearGradient><path
+ d="M 49.5 27.3 L 47.8 26.9 L 47.7 27.3 L 49.4 27.3 L 49.5 27.3 z "
+ style="fill:url(#aigrd95);"
+ id="path1995" /><path
+ d="M 49.3 27.7 L 49.4 27.3 L 47.7 27.3 L 49.3 27.7 z "
+ id="path1996" /></g><g
+ id="g1997"><linearGradient
+ x1="47.7938995"
+ y1="25.8115005"
+ x2="48.4205017"
+ y2="25.0739994"
+ id="aigrd96"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop1999" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop2000" /></linearGradient><path
+ d="M 49.8 25.4 L 48.2 25 L 48.1 25.4 L 49.8 25.4 L 49.8 25.4 z "
+ style="fill:url(#aigrd96);"
+ id="path2001" /><path
+ d="M 49.7 25.8 L 49.8 25.4 L 48.1 25.4 L 49.7 25.8 z "
+ id="path2002" /></g><g
+ id="g2003"><linearGradient
+ x1="48.1133003"
+ y1="23.9150009"
+ x2="48.7397995"
+ y2="23.1774998"
+ id="aigrd97"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop2005" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop2006" /></linearGradient><path
+ d="M 50.2 23.5 L 48.5 23.1 L 48.4 23.5 L 50.1 23.5 L 50.2 23.5 z "
+ style="fill:url(#aigrd97);"
+ id="path2007" /><path
+ d="M 50.1 23.9 L 50.2 23.5 L 48.5 23.5 L 50.1 23.9 z "
+ id="path2008" /></g><g
+ id="g2009"><linearGradient
+ x1="48.4325981"
+ y1="22.0186005"
+ x2="49.0591011"
+ y2="21.2810001"
+ id="aigrd98"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop2011" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop2012" /></linearGradient><path
+ d="M 50.6 21.6 L 49 21.2 L 48.9 21.6 L 50.6 21.6 L 50.6 21.6 z "
+ style="fill:url(#aigrd98);"
+ id="path2013" /><path
+ d="M 50.5 22.1 L 50.6 21.7 L 48.9 21.7 L 50.5 22.1 z "
+ id="path2014" /></g></g></g><g
+ id="g2015"><g
+ id="g2016"><g
+ id="g2017"><linearGradient
+ x1="48.7304993"
+ y1="21.9965992"
+ x2="49.1809998"
+ y2="21.4661999"
+ id="aigrd99"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop2019" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop2020" /></linearGradient><path
+ d="M 49.2 21.6 L 50.4 21.9 L 50.5 21.6 L 49.2 21.6 L 49.2 21.6 z "
+ style="fill:url(#aigrd99);"
+ id="path2021" /><path
+ d="M 49.3 21.3 L 49.2 21.6 L 50.5 21.6 L 49.3 21.3 L 49.3 21.3 z "
+ id="path2022" /></g><g
+ id="g2023"><linearGradient
+ x1="48.419899"
+ y1="23.8939991"
+ x2="48.8703995"
+ y2="23.3637009"
+ id="aigrd100"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop2025" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop2026" /></linearGradient><path
+ d="M 48.8 23.5 L 50 23.8 L 50.1 23.5 L 48.8 23.5 L 48.8 23.5 z "
+ style="fill:url(#aigrd100);"
+ id="path2027" /><path
+ d="M 48.9 23.2 L 48.8 23.5 L 50.1 23.5 L 48.9 23.2 L 48.9 23.2 z "
+ id="path2028" /></g><g
+ id="g2029"><linearGradient
+ x1="48.1094017"
+ y1="25.7905006"
+ x2="48.5598984"
+ y2="25.2600994"
+ id="aigrd101"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop2031" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop2032" /></linearGradient><path
+ d="M 48.4 25.4 L 49.6 25.7 L 49.7 25.4 L 48.4 25.4 L 48.4 25.4 z "
+ style="fill:url(#aigrd101);"
+ id="path2033" /><path
+ d="M 48.5 25.1 L 48.4 25.4 L 49.7 25.4 L 48.5 25.1 L 48.5 25.1 z "
+ id="path2034" /></g><g
+ id="g2035"><linearGradient
+ x1="47.7988014"
+ y1="27.6875"
+ x2="48.2498016"
+ y2="27.156601"
+ id="aigrd102"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop2037" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop2038" /></linearGradient><path
+ d="M 48.1 27.2 L 49.3 27.5 L 49.4 27.2 L 48.1 27.2 L 48.1 27.2 z "
+ style="fill:url(#aigrd102);"
+ id="path2039" /><path
+ d="M 48.2 27 L 48.1 27.3 L 49.4 27.3 L 48.2 27 z "
+ id="path2040" /></g><g
+ id="g2041"><linearGradient
+ x1="47.4883003"
+ y1="29.5830002"
+ x2="47.9384003"
+ y2="29.0531006"
+ id="aigrd103"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop2043" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop2044" /></linearGradient><path
+ d="M 47.7 29.1 L 48.9 29.4 L 49 29.1 L 47.7 29.1 L 47.7 29.1 z "
+ style="fill:url(#aigrd103);"
+ id="path2045" /><path
+ d="M 47.8 28.8 L 47.7 29.1 L 49 29.1 L 47.8 28.8 L 47.8 28.8 z "
+ id="path2046" /></g><g
+ id="g2047"><linearGradient
+ x1="47.1777"
+ y1="31.4804993"
+ x2="47.6286011"
+ y2="30.9496002"
+ id="aigrd104"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.9993,3.660465e-2,-3.660465e-2,0.9993,1.7818,-1.8851)"><stop
+ style="stop-color:#9f9f9f;stop-opacity:1;"
+ offset="0"
+ id="stop2049" /><stop
+ style="stop-color:#828282;stop-opacity:1;"
+ offset="1"
+ id="stop2050" /></linearGradient><path
+ d="M 47.3 31 L 48.5 31.3 L 48.6 31 L 47.3 31 L 47.3 31 z "
+ style="fill:url(#aigrd104);"
+ id="path2051" /><path
+ d="M 47.4 30.7 L 47.3 31 L 48.6 31 L 47.4 30.7 L 47.4 30.7 z "
+ id="path2052" /></g></g></g></g></g><g
+ transform="matrix(0.348803,7.673147e-2,-7.673147e-2,0.348803,160.1631,-52.15219)"
+ id="g2622"><path
+ d="M 184.1155 485.4331 L 245.4874 450 L 306.8593 485.4331 L 309.0378 554.0898 L 245.4874 591.7323 L 184.1155 556.2992 L 184.1155 485.4331 z "
+ style="fill:#800000;fill-rule:evenodd;stroke:#000000;stroke-width:3.5433;"
+ id="path2623" /><path
+ d="M 306.8593 556.2992 L 368.2311 591.7323 L 368.2311 662.5984 L 306.8593 698.0315 L 245.4874 662.5984 L 245.4874 591.7323 L 306.8593 556.2992 z "
+ style="fill:#008000;fill-rule:evenodd;stroke:#000000;stroke-width:3.5433;"
+ id="path2624" /><path
+ d="M 184.1155 556.2939 L 122.7437 591.7283 L 122.7437 662.597 L 184.1155 698.0314 L 245.4874 662.597 L 245.4874 591.7283 L 184.1155 556.2939 z "
+ style="fill:#c37f41;fill-rule:evenodd;stroke:#000000;stroke-width:3.543365;"
+ id="path2625" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,81.85915,-132.835)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path2626" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,-40.88452,-132.835)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path2627" /><ellipse
+ cx="276.17334"
+ cy="538.582642"
+ rx="30.6859283"
+ ry="17.7165222"
+ transform="matrix(0.814706,0,0,1.411112,21.57656,-239.1342)"
+ style="fill:#ffdab9;fill-rule:evenodd;stroke:#000000;stroke-width:1.6523;"
+ id="path2628" /><text
+ x="95.3142548"
+ y="212.637573"
+ transform="translate(141.3132,320.9463)"
+ style="font-size:36;font-weight:normal;fill:#ff0000;stroke-width:1;font-family:FreeSans;"
+ id="text2629"><tspan
+ id="tspan2630">8</tspan></text><text
+ x="70.7458191"
+ y="254.86348"
+ transform="translate(104.0006,385.1866)"
+ style="font-size:36;font-weight:normal;stroke-width:1;font-family:FreeSans;"
+ id="text2632"><tspan
+ id="tspan2633">4</tspan></text><text
+ x="88.1663055"
+ y="224.654419"
+ transform="translate(208.7261,415.2287)"
+ style="font-size:36;font-weight:normal;stroke-width:1;font-family:FreeSans;"
+ id="text2635"><tspan
+ id="tspan2636">9</tspan></text></g></g></svg>
Added: trunk/server/henjes.game
===================================================================
--- trunk/server/henjes.game (rev 0)
+++ trunk/server/henjes.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,36 @@
+title SmallEurope
+num-players 4
+victory-points 18
+domestic-trade
+num-roads 20
+num-ships 15
+num-settlements 8
+num-cities 6
+num-bridges 0
+resource-count 20
+develop-road 4
+develop-monopoly 4
+develop-plenty 4
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 15
+chits 2,5,4,3,6,3,8,11,10,11,9,12
+map
+s,g28+,p2,s,s,s,s,m5,t4,t3,h6,t20
+s,s?1,s,s,s,s,m8,t9,t10,h11,t21,g13+
+s,s,s,s,s,m14,m15,t16,sl0,t17,f18,t24
+s,s,p7,s,s,s,t31,s,t22,f36,h19,t25
+s,s,sw0,p26,s,p53,sl5,s,t1,h35,t30,f12
+s,s,s?5,s,s?5,p32,t33,h34,t29,p44,h37,p38
+s,s,t39,t45,f41,t42,f51,t23,f40,m60,m47,f85
+s,s,h49,f50,h46,t55,t27,m54,f52,p56,m67,t58
+s,m59,m43,m61,p62,m73,m64,m68,f79,h57,m66,s
+f69,t70,h71,f72,s,s,f63,s,m48,p75,s,s
+s,f76,f77,f78,sg2,s,s,f65,s,f80,t81,m74
+s,s,s,s,s,g83+,s,s,s,s?1,d84,g82+
+.
+# created 11/2003
+# by Robert Henjes <robert.henjes at web.de>
Added: trunk/server/iles.game
===================================================================
--- trunk/server/iles.game (rev 0)
+++ trunk/server/iles.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,54 @@
+title Islands
+num-players 3
+victory-points 10
+domestic-trade
+num-roads 10
+num-ships 15
+num-settlements 4
+num-cities 4
+num-bridges 2
+resource-count 15
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 11
+use-pirate
+island-discovery-bonus 1
+chits 2,6,2,4,6,3,5,10,8,10,4,9,11,12,8,12,3,5,9,11,
+map
+s ,s ,s ,s ,s ,s ,s ,s ,s ,
+s ,p0 ,h1 ,s ,s ,m2 ,p3 ,f4 ,s ,
+s ,f5 ,m6 ,sb5 ,m7 ,sl3 ,t8 ,h9 ,s ,
+s ,t10 ,sw2 ,t11 ,f12 ,so0 ,p13 ,s ,s ,
+s ,s ,s ,p14 ,h15 ,s ,s ,s ,s ,
+s ,s ,s ,s ,s?0 ,m16 ,f17 ,s ,s ,
+s ,s ,d18 ,s ,s ,h19 ,t20 ,s ,s ,
+s ,s ,s ,s ,s ,s ,s ,s ,s ,
+.
+
+# iles.game
+# v1.0, 19/02/2004
+# v1.1, 2006-09-10 Added island-discovery-bonus
+#
+# Copyright 2004, 2006 LT-P <LT-P at LT-P.net>
+
+# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Please provide some feedback ;)
Added: trunk/server/lobby.game
===================================================================
--- trunk/server/lobby.game (rev 0)
+++ trunk/server/lobby.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,33 @@
+# This is the lobby
+# People can gather here to meet, and talk about games to start.
+#
+variant default
+title Lobby
+strict-trade
+domestic-trade
+num-players 8
+sevens-rule 0
+victory-points 99
+num-roads 0
+num-bridges 0
+num-ships 0
+num-settlements 0
+num-cities 1
+resource-count 1
+develop-road 0
+develop-monopoly 0
+develop-plenty 0
+develop-chapel 0
+develop-university 0
+develop-governor 0
+develop-library 0
+develop-market 0
+develop-soldier 0
+chits 2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4,4,4,6,6,8,6,8,6,8,6,8,9,9,9,9,9,9,9,9,12,12,12,12,12,12,12,12,12,12,12,12,12
+map
+h0,s,s,s,f1,f2,s,m3,m4,m5,s,p6,p7,p8,s,t9,s,s,t10
+h11,s,s,f12,s,f13,s,m14,s,m15,s,p16,s,p17,s,t18,s,t19,-
+h20,s,s,f21,s,s,f22,s,m23,m24,s,s,p25,p26,s,s,t27,t28,s
+h29,s,s,f30,s,f31,s,m32,s,m33,s,p34,s,p35,s,s,t36,s,-
+h37,h38,h39,s,f40,f41,s,m42,m43,m44,s,p45,p46,p47,s,s,t48,s,g49
+.
Added: trunk/server/lorindol.game
===================================================================
--- trunk/server/lorindol.game (rev 0)
+++ trunk/server/lorindol.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,56 @@
+title CentralEurope
+domestic-trade
+num-players 4
+victory-points 40
+num-roads 80
+num-settlements 5
+num-cities 30
+num-ships 20
+resource-count 30
+develop-road 30
+develop-monopoly 2
+develop-plenty 30
+develop-soldier 30
+develop-market 5
+develop-chapel 5
+develop-university 5
+develop-governor 5
+chits 8,9,2,3,2,2,12,2,10,5,6,3,8,3,12,5,9,10,8,4,11,11,4,12,2,12,5,9,8,2,3,9,10,6,4,5,6,2,10,8,4,9,10,11,12,2,9,2,3,3,4,5,6,8,9,10,11,12,2,2,2,2,6,12,5,6,8,9,3,10,11,4,2,2,3,4,5,6,8,9,11,10,11,12,2,2,3,10,4,2,5,6,8,9,10,11,12,2,2,4,5,4,6,8,9,10,11,2,2,3,4,5,6,9,10,11,11,12,2,6,4,5,6,3,8,12,3,2,3,2,3,4,8,9,10,11,12,5,10,2,6,2,4,8,9,10,11,12,5,2,5,6,5,6,3,9,8,2,11,12,2,11,12,4,8
+map
+s,f0,d1+,f2,sg3,s,s,s,s,s,s,s,sg5,f3,d4+,f5,d6+,f7,d8+,d9+,f10,d11+,s,d12+,d13+
+s,f14,f15,f16,s,s,s,s,s,s,s,s,f17,d18+,f19,s,d20+,f21,d22+,d23+,f24,sg0,f25,f26,d27+
+s,d28+,f29,s,s,s,s,s,s,s,s,s,f30,d31+,f32,s,d33+,f34,d35+,f36,d37+,s,d38+,d39+,f40
+s,s,s,s,s,s,s,s,s,s,s,f41,d42+,f43,f44,s,f45,d46+,s,f47,d48+,f49,d50+,f51,d52+
+s,s,s,s,s,s,f53,s,s,s,s,s,f54,d55+,f56,s,s,f57,s,d58+,f59,d60+,f61,d62+,d63+
+s,s,s,s,s,s,s,s,s,s,s,f64,d65+,f66,d67+,s,s,s,f68,d69+,f70,d71+,f72,d73+,d74+
+s,s,s,s,s,s,s,f75,s,s,s,s,s,s,d76+,d77+,s,s,d78+,d79+,d80+,d81+,d82+,d83+,f84
+s,s,s,s,sg5,s,s,f85,s,sg5,s,d86+,f87,s,f88,s,s,d89+,f90,f91,d92+,f93,d94+,f95,d96+
+s,s,s,s,s,f97,s,f98,d99+,s,f100,s,f101,s,s,s,s,d102+,f103,d104+,f105,d106+,d107+,d108+,s
+s,s,s,s,d109+,f110,s,f111,s,s,s,s,f112,s,s,f113,d114+,d115+,d116+,f117,d118+,f119,d120+,f121,d122+
+s,s,s,s,f123,f124,s,f125,d126+,s,s,f127,d128+,f129,s,f130,d131+,f132,d133+,d134+,f135,d136+,f137,d138+,d139+
+s,s,s,s,s,s,f140,d141+,f142,s,f143,d144+,f145,d146+,d147+,f148,d149+,d150+,d151+,d152+,f153,d154+,f155,f156,d157+
+s,s,s,s,s,s,sg1,s,s,s,f158,d159+,f160,d161+,f162,d163+,d164+,f165,d166+,f167,d168+,f169,d170+,d171+,f172
+s,s,s,s,s,s,d173+,f174,d175+,d176+,f177,f178,d179+,f180,f181,d182+,f183,d184+,f185,d186+,f187,d188+,f189,d190+,d191+
+s,s,s,s,s,s,f192,d193+,f194,d195+,f196,d197+,f198,d199+,f200,d201+,d202+,d203+,d204+,d205+,f206,d207+,d208+,s,f209
+s,s,s,s,s,s,s,d210+,f211,d212+,f213,d214+,f215,d216+,d217+,f218,d219+,d220+,f221,d222+,f223,s,s,sg1,s
+s,s,s,s,s,s,s,f224,d225+,f226,d227+,d228+,f229,d230+,d231+,f232,d233+,f234,d235+,f236,d237+,d238+,s,s,s
+s,s,s,s,s,s,s,d239+,f240,d241+,f242,d243+,f244,d245+,s,d246+,f247,d248+,d249+,d250+,d251+,f252,s,s,s
+s,s,s,s,f253,d254+,f255,d256+,d257+,f258,d259+,f260,d261+,d262+,d263+,s,f264,d265+,d266+,f267,f268,d269+,s,s,s
+s,s,s,f270,d271+,d272+,f273,d274+,s,s,s,s,s,f275,f276,s,s,f277,d278+,d279+,d280+,f281,s,d282+,f283
+s,s,s,f284,d285+,f286,d287+,d288+,f289,s,s,sg5,d290+,s,f291,d292+,s,s,f293,d294+,f295,s,s,f296,f297
+s,s,s,d298+,f299,d300+,f301,s,s,sg4,s,f302,d303+,s,d304+,f305,s,s,f306,d307+,s,f308,d309+,f310,f311
+s,s,s,sg0,f312,d313+,f314,s,s,f315,s,s,f316,s,s,f317,d318+,s,f319,d320+,f321,s,f322,d323+,f324
+s,s,s,s,s,s,s,s,s,sg5,f325,s,s,f326,d327+,s,f328,s,sg0,f329,d330+,s,sg2,s,s
+s,s,s,s,f331,f332,s,s,s,s,f333,d334+,s,s,s,s,s,s,s,s,f335,s,s,s,s
+.
+# CentralEurope
+# created 10/2003
+# by Martin Brotzeller <lorindol at cip.informatik.uni-wuerzburg.de>
+
+# This is a map of europe, cut down a bit at the eastern part because it
+# did not fit with the 0.7/0.8 servers. The only resource available is
+# grain, the only types of ports are grain ports. The reason, obviously,
+# is to conquer a large-enough part of europe.
+
+# Strategy: Grab a harbor from the start of the game, and look out for
+# an area where you can connect fast to build your empire.
Added: trunk/server/main.c
===================================================================
--- trunk/server/main.c (rev 0)
+++ trunk/server/main.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,325 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/* Pioneers Console Server
+ */
+#include "config.h"
+#include "version.h"
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <limits.h>
+#include <glib.h>
+
+#include "driver.h"
+#include "game.h"
+#include "cards.h"
+#include "map.h"
+#include "network.h"
+#include "log.h"
+#include "buildrec.h"
+#include "server.h"
+
+#include "glib-driver.h"
+
+#include "admin.h"
+
+static GMainLoop *event_loop;
+
+static gint num_players = 0;
+static gint num_points = 0;
+static gint sevens_rule = -1;
+static gint terrain = -1;
+static gint timeout = 0;
+static gint num_ai_players = 0;
+static gchar *server_port = NULL;
+static gchar *admin_port = NULL;
+static gchar *game_title = NULL;
+static gchar *game_file = NULL;
+static gboolean disable_game_start = FALSE;
+static gint tournament_time = -1;
+static gboolean quit_when_done = FALSE;
+static gchar *hostname = NULL;
+static gboolean register_server = FALSE;
+static gchar *meta_server_name = NULL;
+static gboolean fixed_seating_order = FALSE;
+static gboolean enable_debug = FALSE;
+static gboolean show_version = FALSE;
+
+static GOptionEntry commandline_game_entries[] = {
+ {"game-title", 'g', 0, G_OPTION_ARG_STRING, &game_title,
+ /* Commandline server-console: game-title */
+ N_("Game title to use"), NULL},
+ {"file", 0, 0, G_OPTION_ARG_STRING, &game_file,
+ /* Commandline server-console: file */
+ N_("Game file to use"), NULL},
+ {"port", 'p', 0, G_OPTION_ARG_STRING, &server_port,
+ /* Commandline server-console: port */
+ N_("Port to listen on"), PIONEERS_DEFAULT_GAME_PORT},
+ {"players", 'P', 0, G_OPTION_ARG_INT, &num_players,
+ /* Commandline server-console: players */
+ N_("Override number of players"), NULL},
+ {"points", 'v', 0, G_OPTION_ARG_INT, &num_points,
+ /* Commandline server-console: points */
+ N_("Override number of points needed to win"), NULL},
+ {"seven-rule", 'R', 0, G_OPTION_ARG_INT, &sevens_rule,
+ /* Commandline server-console: seven-rule */
+ N_("Override seven-rule handling"), "0|1|2"},
+ {"terrain", 'T', 0, G_OPTION_ARG_INT, &terrain,
+ /* Commandline server-console: terrain */
+ N_("Override terrain type, 0=default 1=random"), "0|1"},
+ {"computer-players", 'c', 0, G_OPTION_ARG_INT, &num_ai_players,
+ /* Commandline server-console: computer-players */
+ N_("Add N computer players"), "N"},
+ {"version", '\0', 0, G_OPTION_ARG_NONE, &show_version,
+ /* Commandline option of server-console: version */
+ N_("Show version information"), NULL},
+ {NULL, '\0', 0, 0, NULL, NULL, NULL}
+};
+
+static GOptionEntry commandline_meta_entries[] = {
+ {"register", 'r', 0, G_OPTION_ARG_NONE, ®ister_server,
+ /* Commandline server-console: register */
+ N_("Register server with meta-server"), NULL},
+ {"meta-server", 'm', 0, G_OPTION_ARG_STRING, &meta_server_name,
+ /* Commandline server-console: meta-server */
+ N_("Register at meta-server name (implies -r)"),
+ PIONEERS_DEFAULT_META_SERVER},
+ {"hostname", 'n', 0, G_OPTION_ARG_STRING, &hostname,
+ /* Commandline server-console: hostname */
+ N_("Use this hostname when registering"), NULL},
+ {NULL, '\0', 0, 0, NULL, NULL, NULL}
+};
+
+static GOptionEntry commandline_other_entries[] = {
+ {"auto-quit", 'x', 0, G_OPTION_ARG_NONE, &quit_when_done,
+ /* Commandline server-console: auto-quit */
+ N_("Quit after a player has won"), NULL},
+ {"empty-timeout", 'k', 0, G_OPTION_ARG_INT, &timeout,
+ /* Commandline server-console: empty-timeout */
+ N_("Quit after N seconds with no players"), "N"},
+ {"tournament", 't', 0, G_OPTION_ARG_INT, &tournament_time,
+ /* Commandline server-console: tournament */
+ N_("Tournament mode, computer players added after N minutes"),
+ "N"},
+ {"admin-port", 'a', 0, G_OPTION_ARG_STRING, &admin_port,
+ /* Commandline server-console: admin-port */
+ N_("Admin port to listen on"), PIONEERS_DEFAULT_ADMIN_PORT},
+ {"admin-wait", 's', 0, G_OPTION_ARG_NONE, &disable_game_start,
+ /* Commandline server-console: admin-wait */
+ N_
+ ("Don't start game immediately, wait for a command on admin port"),
+ NULL},
+ {"fixed-seating-order", 0, 0, G_OPTION_ARG_NONE,
+ &fixed_seating_order,
+ /* Commandline server-console: fixed-seating-order */
+ N_
+ ("Give players numbers according to the order they enter the game"),
+ NULL},
+ {"debug", '\0', 0, G_OPTION_ARG_NONE, &enable_debug,
+ /* Commandline option of server: enable debug logging */
+ N_("Enable debug messages"), NULL},
+ {NULL, '\0', 0, 0, NULL, NULL, NULL}
+};
+
+int main(int argc, char *argv[])
+{
+ int i;
+ GOptionContext *context;
+ GOptionGroup *context_group;
+ GError *error = NULL;
+ GameParams *params;
+
+ /* set the UI driver to Glib_Driver, since we're using glib */
+ set_ui_driver(&Glib_Driver);
+ driver->player_added = srv_glib_player_added;
+ driver->player_renamed = srv_glib_player_renamed;
+ driver->player_removed = srv_player_removed;
+
+ driver->player_change = srv_player_change;
+
+ setlocale(LC_ALL, "");
+ bindtextdomain(PACKAGE, LOCALEDIR);
+ textdomain(PACKAGE);
+
+ /* have gettext return strings in UTF-8 */
+ bind_textdomain_codeset(PACKAGE, "UTF-8");
+
+ server_init();
+
+ /* Long description in the commandline for server-console: help */
+ context = g_option_context_new(_("- Host a game of Pioneers"));
+ g_option_context_add_main_entries(context,
+ commandline_game_entries,
+ PACKAGE);
+ context_group = g_option_group_new("meta",
+ /* Commandline server-console: Short description of meta group */
+ _("Meta-server Options"),
+ /* Commandline server-console: Long description of meta group */
+ _
+ ("Options for the meta-server"),
+ NULL, NULL);
+ g_option_group_set_translation_domain(context_group, PACKAGE);
+ g_option_group_add_entries(context_group,
+ commandline_meta_entries);
+ g_option_context_add_group(context, context_group);
+ context_group = g_option_group_new("misc",
+ /* Commandline server-console: Short description of misc group */
+ _("Miscellaneous Options"),
+ /* Commandline server-console: Long description of misc group */
+ _("Miscellaneous options"),
+ NULL, NULL);
+ g_option_group_set_translation_domain(context_group, PACKAGE);
+ g_option_group_add_entries(context_group,
+ commandline_other_entries);
+ g_option_context_add_group(context, context_group);
+ g_option_context_parse(context, &argc, &argv, &error);
+ if (error != NULL) {
+ g_print("%s\n", error->message);
+ g_error_free(error);
+ return 1;
+ }
+ if (show_version) {
+ g_print(_("Pioneers version:"));
+ g_print(" ");
+ g_print(FULL_VERSION);
+ g_print("\n");
+ return 0;
+ }
+
+ set_enable_debug(enable_debug);
+
+ if (server_port == NULL)
+ server_port = g_strdup(PIONEERS_DEFAULT_GAME_PORT);
+ if (disable_game_start)
+ if (admin_port == NULL)
+ admin_port = g_strdup(PIONEERS_DEFAULT_ADMIN_PORT);
+
+ if (game_title && game_file) {
+ g_print
+ ("Cannot set game title and filename at the same time");
+ return 2;
+ }
+ if (game_file == NULL) {
+ load_game_types(get_pioneers_dir());
+ if (game_title == NULL)
+ params = cfg_set_game("Default");
+ else
+ params = cfg_set_game(game_title);
+ } else {
+ params = cfg_set_game_file(game_file);
+ }
+ if (params == NULL) {
+ g_print("Could not set the game");
+ return 3;
+ }
+
+ if (meta_server_name != NULL)
+ register_server = TRUE;
+ if (register_server && meta_server_name == NULL)
+ meta_server_name = get_meta_server_name(TRUE);
+
+ g_assert(server_port != NULL);
+
+ if (num_players)
+ cfg_set_num_players(params, num_players);
+
+ if (sevens_rule != -1)
+ cfg_set_sevens_rule(params, sevens_rule);
+
+ if (num_points)
+ cfg_set_victory_points(params, num_points);
+
+ if (tournament_time != -1)
+ cfg_set_tournament_time(params, tournament_time);
+
+ cfg_set_quit(params, quit_when_done);
+
+ if (terrain != -1)
+ cfg_set_terrain_type(params, terrain ? 1 : 0);
+
+ if (timeout)
+ cfg_set_timeout(timeout);
+
+ net_init();
+
+ if (admin_port != NULL)
+ admin_listen(admin_port);
+
+ if (!disable_game_start) {
+ if (start_server
+ (params, hostname, server_port, register_server,
+ meta_server_name, !fixed_seating_order)) {
+ for (i = 0; i < num_ai_players; ++i)
+ new_computer_player(NULL, server_port,
+ TRUE);
+
+ event_loop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(event_loop);
+ g_main_loop_unref(event_loop);
+ }
+ } else {
+ /* Ugly... But needed to preserve the original functionality
+ if the disable_game_start flag is set... Even if it doesn't
+ really -do- anything. */
+ for (i = 0; i < num_ai_players; ++i)
+ new_computer_player(NULL, server_port, TRUE);
+
+ event_loop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(event_loop);
+ g_main_loop_unref(event_loop);
+ }
+
+ net_finish();
+
+ g_free(hostname);
+ g_free(server_port);
+ g_free(admin_port);
+ g_option_context_free(context);
+ params_free(params);
+ server_cleanup_static_data();
+ return 0;
+}
+
+static gboolean exit_func(G_GNUC_UNUSED gpointer data)
+{
+ g_main_loop_quit(event_loop);
+ return TRUE;
+}
+
+void game_is_over(Game * game)
+{
+ /* quit in ten seconds if configured */
+ if (game->params->quit_when_done) {
+ g_timeout_add(10 * 1000, &exit_func, NULL);
+ }
+}
+
+void request_server_stop(void)
+{
+ server_stop();
+ g_main_loop_quit(event_loop);
+}
Added: trunk/server/meta.c
===================================================================
--- trunk/server/meta.c (rev 0)
+++ trunk/server/meta.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,213 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "server.h"
+
+static Session *ses;
+static enum {
+ MODE_SIGNON,
+ MODE_REDIRECT,
+ MODE_SERVER_LIST
+} meta_mode;
+
+static gint meta_server_version_major;
+static gint meta_server_version_minor;
+static gint num_redirects;
+
+gchar *get_server_name(void)
+{
+ gchar *server_name;
+ server_name = g_strdup(g_getenv("PIONEERS_SERVER_NAME"));
+ if (!server_name)
+ server_name = g_strdup(g_getenv("GNOCATAN_SERVER_NAME"));
+ if (!server_name)
+ server_name = get_my_hostname();
+ return server_name;
+}
+
+void meta_start_game(void)
+{
+#ifdef CLOSE_META_AT_START
+ if (ses != NULL) {
+ net_printf(ses, "begin\n");
+ net_free(&ses);
+ }
+#endif
+}
+
+void meta_report_num_players(gint num_players)
+{
+ if (ses != NULL)
+ net_printf(ses, "curr=%d\n", num_players);
+}
+
+void meta_send_details(Game * game)
+{
+ if (ses == NULL)
+ return;
+
+ net_printf(ses,
+ "server\n"
+ "port=%s\n"
+ "version=%s\n"
+ "max=%d\n"
+ "curr=%d\n",
+ game->server_port, PROTOCOL_VERSION,
+ game->params->num_players, game->num_players);
+ /* Hostname is empty */
+ if (game->hostname && !strlen(game->hostname)) {
+ g_free(game->hostname);
+ game->hostname = NULL;
+ }
+ /* No hostname set, let the metaserver figure out our name */
+ if (game->hostname) {
+ net_printf(ses, "host=%s\n", game->hostname);
+ }
+ if (meta_server_version_major >= 1) {
+ net_printf(ses,
+ "vpoints=%d\n"
+ "sevenrule=%s\n"
+ "terrain=%s\n"
+ "title=%s\n",
+ game->params->victory_points,
+ game->params->sevens_rule == 0 ? "normal" :
+ game->params->sevens_rule ==
+ 1 ? "reroll first 2" : "reroll all",
+ game->params->
+ random_terrain ? "random" : "default",
+ game->params->title);
+ } else {
+ net_printf(ses,
+ "map=%s\n"
+ "comment=%s\n",
+ game->params->
+ random_terrain ? "random" : "default",
+ game->params->title);
+ }
+}
+
+static void meta_event(NetEvent event, Game * game, char *line)
+{
+ switch (event) {
+ case NET_READ:
+ switch (meta_mode) {
+ case MODE_SIGNON:
+ case MODE_REDIRECT:
+ if (strncmp(line, "goto ", 5) == 0) {
+ gchar **split_result;
+ const gchar *port;
+ meta_mode = MODE_REDIRECT;
+ net_free(&ses);
+ if (num_redirects++ == 10) {
+ log_message(MSG_INFO,
+ _
+ ("Too many meta-server redirects\n"));
+ return;
+ }
+ split_result = g_strsplit(line, " ", 0);
+ g_assert(split_result[0] != NULL);
+ g_assert(!strcmp(split_result[0], "goto"));
+ if (split_result[1]) {
+ port = PIONEERS_DEFAULT_META_PORT;
+ if (split_result[2])
+ port = split_result[2];
+ meta_register(split_result[1],
+ port, game);
+ } else {
+ log_message(MSG_ERROR,
+ _
+ ("Bad redirect line: %s\n"),
+ line);
+ };
+ g_strfreev(split_result);
+ }
+
+ meta_server_version_major =
+ meta_server_version_minor = 0;
+ if (strncmp(line, "welcome ", 8) == 0) {
+ char *p = strstr(line, "version ");
+ if (p) {
+ p += 8;
+ meta_server_version_major =
+ atoi(p);
+ p += strspn(p, "0123456789");
+ if (*p == '.')
+ meta_server_version_minor =
+ atoi(p + 1);
+ }
+ }
+ net_printf(ses, "version %s\n",
+ META_PROTOCOL_VERSION);
+ meta_mode = MODE_SERVER_LIST;
+ meta_send_details(game);
+ break;
+ default:
+ log_message(MSG_ERROR,
+ _
+ ("Unknown message from the metaserver: %s\n"),
+ line);
+ break;
+ }
+ break;
+ case NET_CLOSE:
+ log_message(MSG_ERROR, _("Meta-server kicked us off\n"));
+ net_free(&ses);
+ break;
+ case NET_CONNECT:
+ case NET_CONNECT_FAIL:
+ break;
+ }
+}
+
+void meta_register(const gchar * server, const gchar * port, Game * game)
+{
+ if (num_redirects > 0)
+ log_message(MSG_INFO,
+ _
+ ("Redirected to meta-server at %s, port %s\n"),
+ server, port);
+ else
+ log_message(MSG_INFO,
+ _
+ ("Register with meta-server at %s, port %s\n"),
+ server, port);
+
+ if (ses != NULL)
+ net_free(&ses);
+
+ ses = net_new((NetNotifyFunc) meta_event, game);
+ if (net_connect(ses, server, port))
+ meta_mode = MODE_SIGNON;
+ else {
+ net_free(&ses);
+ }
+}
+
+void meta_unregister(void)
+{
+ if (ses != NULL) {
+ log_message(MSG_INFO, _("Unregister from meta-server\n"));
+ net_free(&ses);
+ }
+}
Added: trunk/server/player.c
===================================================================
--- trunk/server/player.c (rev 0)
+++ trunk/server/player.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,1122 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003-2007 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2005,2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "server.h"
+
+/* Local function prototypes */
+static gboolean mode_check_version(Player * player, gint event);
+static gboolean mode_check_status(Player * player, gint event);
+static gboolean mode_bad_version(Player * player, gint event);
+static gboolean mode_global(Player * player, gint event);
+static gboolean mode_unhandled(Player * player, gint event);
+static void player_setup(Player * player, int playernum,
+ const gchar * name, gboolean force_viewer);
+static Player *player_by_name(Game * game, char *name);
+
+
+/** Find a free number for a connecting player.
+ * @param game The game
+ * @param force_viewer The connecting player must be a viewer
+ */
+static gint next_free_player_num(Game * game, gboolean force_viewer)
+{
+ gint idx;
+
+ if (!force_viewer) {
+ GList *list;
+ gboolean player_taken[MAX_PLAYERS];
+ gint available = game->params->num_players;
+
+ memset(player_taken, 0, sizeof(player_taken));
+ playerlist_inc_use_count(game);
+ for (list = game->player_list;
+ list != NULL; list = g_list_next(list)) {
+ Player *player = list->data;
+ if (player->num >= 0
+ && !player_is_viewer(game, player->num)
+ && (!player->disconnected
+ || player->sm->use_cache)) {
+ player_taken[player->num] = TRUE;
+ --available;
+ }
+ }
+ playerlist_dec_use_count(game);
+
+ if (available > 0) {
+ gint skip;
+ if (game->random_order) {
+ skip = get_rand(available);
+ } else {
+ skip = 0;
+ }
+ idx = 0;
+ while (player_taken[idx] || skip-- != 0)
+ ++idx;
+ return idx;
+ }
+ }
+
+ /* No players available/wanted, look for a viewer number */
+ idx = game->params->num_players;
+ while (player_by_num(game, idx) != NULL)
+ ++idx;
+ return idx;
+}
+
+static gboolean mode_global(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ gchar *text;
+
+ switch (event) {
+ case SM_FREE:
+ if (player->name != NULL)
+ g_free(player->name);
+ if (player->style != NULL)
+ g_free(player->style);
+ if (player->location != NULL)
+ g_free(player->location);
+ if (player->devel != NULL)
+ deck_free(player->devel);
+ if (player->num >= 0
+ && !player_is_viewer(game, player->num)) {
+ game->num_players--;
+ meta_report_num_players(game->num_players);
+ }
+ g_list_free(player->build_list);
+ g_list_free(player->special_points);
+ g_free(player);
+ return TRUE;
+ case SM_NET_CLOSE:
+ player_remove(player);
+ if (player->num >= 0) {
+ player_broadcast(player, PB_OTHERS, FIRST_VERSION,
+ LATEST_VERSION, "has quit\n");
+ player_archive(player);
+ } else {
+ player_free(player);
+ }
+ driver->player_change(game);
+ return TRUE;
+ case SM_RECV:
+ if (sm_recv(sm, "chat %S", &text)) {
+ if (strlen(text) > MAX_CHAT)
+ player_send(player, FIRST_VERSION,
+ LATEST_VERSION, "ERR %s\n",
+ _("chat too long"));
+ else
+ player_broadcast(player, PB_ALL,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "chat %s\n", text);
+ g_free(text);
+ return TRUE;
+ }
+ if (sm_recv(sm, "name %S", &text)) {
+ if (text[0] == '\0')
+ player_send(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "ERR invalid-name\n");
+ else if (strlen(text) > MAX_NAME_LENGTH)
+ player_send(player, FIRST_VERSION,
+ LATEST_VERSION, "ERR %s\n",
+ _("name too long"));
+ else
+ player_set_name(player, text);
+ g_free(text);
+ return TRUE;
+ }
+ if (sm_recv(sm, "style %S", &text)) {
+ if (player->style)
+ g_free(player->style);
+ player->style = text;
+ player_broadcast(player, PB_ALL, V0_11,
+ LATEST_VERSION, "style %s\n",
+ text);
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean mode_unhandled(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ gchar *text;
+
+ switch (event) {
+ case SM_RECV:
+ if (sm_recv(sm, "extension %S", &text)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "NOTE %s\n",
+ N_("ignoring unknown extension"));
+ log_message(MSG_INFO,
+ "ignoring unknown extension from %s: %s\n",
+ player->name, text);
+ g_free(text);
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/* Called to start the game (if it hasn't been yet). Add computer
+ * players to fill any empty spots
+ *
+ */
+static gboolean tournament_start_cb(gpointer data)
+{
+ int i;
+ Player *player = (Player *) data;
+ Game *game = player->game;
+
+ /* if game already started */
+ if (game->num_players == game->params->num_players)
+ return FALSE;
+
+ player_broadcast(player, PB_SILENT, FIRST_VERSION, LATEST_VERSION,
+ "NOTE %s\n",
+ N_("Game starts, adding computer players"));
+ /* add computer players to start game */
+ for (i = game->num_players; i < game->params->num_players; i++) {
+ new_computer_player(NULL, game->server_port, TRUE);
+ }
+
+ return FALSE;
+}
+
+/*
+ * Keep players notified about when the tournament game is going to start
+ *
+ */
+static gboolean talk_about_tournament_cb(gpointer data)
+{
+ Player *player = (Player *) data;
+ Game *game = player->game;
+ const gchar *message;
+
+ /* if game already started */
+ if (game->num_players == game->params->num_players)
+ return FALSE;
+
+ /* FIXME: Use ngettext here? */
+ message = game->params->tournament_time != 1 ?
+ N_("The game starts in %s minutes.") :
+ N_("The game starts in %s minute.");
+
+ player_broadcast(player, PB_SILENT, FIRST_VERSION, LATEST_VERSION,
+ "NOTE1 %d|%s\n",
+ game->params->tournament_time, message);
+ game->params->tournament_time--;
+
+ if (game->params->tournament_time > 0)
+ g_timeout_add(1000 * 60,
+ &talk_about_tournament_cb, player);
+
+ return FALSE;
+}
+
+Player *player_new(Game * game, int fd, gchar * location)
+{
+ gchar name[100];
+ gint i;
+ Player *player;
+ StateMachine *sm;
+
+ /* give player a name, some functions need it */
+ strcpy(name, "connecting");
+ for (i = strlen(name); i < G_N_ELEMENTS(name) - 1; ++i) {
+ if (player_by_name(game, name) == NULL)
+ break;
+ name[i] = '_';
+ name[i + 1] = 0;
+ }
+ if (i == G_N_ELEMENTS(name) - 1) {
+ /* there are too many pending connections */
+ write(fd, "ERR Too many connections\n", 25);
+ net_closesocket(fd);
+ return NULL;
+ }
+
+ if (game->is_game_over) {
+ /* The game is over, don't accept new players */
+ Session *ses = net_new(NULL, NULL);
+ gchar *message;
+ net_use_fd(ses, fd, FALSE);
+ /* Message to send to the client when the game is already over
+ * when a connection is made. */
+ message =
+ g_strdup_printf("NOTE %s\n",
+ N_("Sorry, game is over."));
+ net_write(ses, message);
+ log_message(MSG_INFO,
+ _("Player from %s is refused: game is over\n"),
+ location);
+ net_close_when_flushed(ses);
+ g_free(message);
+ return NULL;
+ }
+
+ player = g_malloc0(sizeof(*player));
+ sm = player->sm = sm_new(player);
+
+ sm_global_set(sm, (StateFunc) mode_global);
+ sm_unhandled_set(sm, (StateFunc) mode_unhandled);
+ sm_use_fd(sm, fd, TRUE);
+
+ /* Cache messages of the game in progress until all intial
+ * messages have been sent
+ */
+ sm_set_use_cache(sm, TRUE);
+
+ player->game = game;
+ player->location = g_strdup(location);
+ player->devel = deck_new(game->params);
+ game->player_list = g_list_append(game->player_list, player);
+ player->num = -1;
+ player->chapel_played = 0;
+ player->univ_played = 0;
+ player->gov_played = 0;
+ player->libr_played = 0;
+ player->market_played = 0;
+ player->islands_discovered = 0;
+ player->disconnected = FALSE;
+ player->name = g_strdup(name);
+ player->style = g_strdup("square");
+ player->special_points = NULL;
+ player->special_points_next_id = 0;
+
+ if (game->params->tournament_time > 0) {
+ /* if first player in and this is a tournament start the timer */
+ if (game->num_players == 0) {
+ g_timeout_add(game->params->tournament_time * 60 *
+ 1000 + 500, &tournament_start_cb,
+ player);
+ g_timeout_add(1000, &talk_about_tournament_cb,
+ player);
+ } else {
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION, "NOTE %s\n",
+ N_
+ ("This game will start soon."));
+ }
+ }
+
+ sm_goto(sm, (StateFunc) mode_check_version);
+
+ driver->player_change(game);
+ return player;
+}
+
+/* set the player name. Most of the time, player_set_name is called instead,
+ * which calls this function with public set to TRUE. Only player_setup calls
+ * this with public == FALSE, because it doesn't want the broadcast. */
+static void player_set_name_real(Player * player, gchar * name,
+ gboolean public)
+{
+ Game *game = player->game;
+ Player *player_temp;
+
+ g_assert(name[0] != 0);
+
+ if (((player_temp = player_by_name(game, name)) != NULL) &&
+ (player_temp != player)) {
+ /* make it a note, not an error, so nothing bad happens
+ * (on error the AI would disconnect) */
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "NOTE %s\n",
+ N_
+ ("Name not changed: new name is already in use"));
+ return;
+ }
+
+ if (player->name != name) {
+ g_free(player->name);
+ player->name = g_strdup(name);
+ }
+
+ if (public)
+ player_broadcast(player, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION, "is %s\n", player->name);
+
+ driver->player_renamed(player);
+ driver->player_change(game);
+}
+
+static void player_setup(Player * player, int playernum,
+ const gchar * name, gboolean force_viewer)
+{
+ gchar nm[MAX_NAME_LENGTH + 1];
+ Game *game = player->game;
+ StateMachine *sm = player->sm;
+ Player *other;
+
+ player->num = playernum;
+ if (player->num < 0) {
+ player->num = next_free_player_num(game, force_viewer);
+ }
+
+ if (!player_is_viewer(game, player->num)) {
+ game->num_players++;
+ meta_report_num_players(game->num_players);
+ }
+
+ player->num_roads = 0;
+ player->num_bridges = 0;
+ player->num_ships = 0;
+ player->num_settlements = 0;
+ player->num_cities = 0;
+
+ /* give the player her new name */
+ if (name == NULL) {
+ if (player_is_viewer(game, player->num)) {
+ gint num = 1;
+ do {
+ sprintf(nm, _("Viewer %d"), num++);
+ } while (player_by_name(game, nm) != NULL);
+ } else {
+ sprintf(nm, _("Player %d"), player->num);
+ }
+ } else {
+ strncpy(nm, name, G_N_ELEMENTS(nm));
+ nm[G_N_ELEMENTS(nm) - 1] = '\0';
+ }
+
+ /* if the new name exists, try padding it with underscores */
+ other = player_by_name(game, nm);
+ if (other != player && other != NULL) {
+ gint i;
+ /* add underscores until the name is unique */
+ for (i = strlen(nm); i < G_N_ELEMENTS(nm) - 1; ++i) {
+ if (player_by_name(game, nm) == NULL)
+ break;
+ nm[i] = '_';
+ nm[i + 1] = 0;
+ }
+ /* Adding underscores was not enough to make the name unique.
+ * While staying within the maximum name length,
+ * create numbers at the end of the name.
+ * Repeat until an unique name has been found.
+ */
+ while (player_by_name(game, nm)) {
+ gint digit = 10;
+ i = G_N_ELEMENTS(nm) - 1;
+ while (digit == 10 && i > 0) {
+ /* Digit will be: 0..10 */
+ --i;
+ digit = g_ascii_digit_value(nm[i]) + 1;
+ nm[i] = '0' + digit % 10;
+ }
+ }
+ }
+ /* copy the (possibly new) name to dynamic memory */
+ /* don't broadcast the name. This is done by mode_pre_game, after
+ * telling the user how many players are in the game.
+ * That should keep things easier for the client. */
+ player_set_name_real(player, nm, FALSE);
+
+ /* add the info in the output device */
+ driver->player_added(player);
+ driver->player_change(game);
+ if (playernum < 0)
+ sm_goto(sm, (StateFunc) mode_pre_game);
+}
+
+void player_free(Player * player)
+{
+ Game *game = player->game;
+
+ if (game->player_list_use_count > 0) {
+ game->dead_players =
+ g_list_append(game->dead_players, player);
+ player->disconnected = TRUE;
+ return;
+ }
+
+ game->player_list = g_list_remove(game->player_list, player);
+ driver->player_change(game);
+
+ sm_free(player->sm);
+}
+
+void player_archive(Player * player)
+{
+ StateFunc state;
+ Game *game = player->game;
+
+ /* If this was a viewer, forget about him */
+ if (player_is_viewer(game, player->num)) {
+ player_free(player);
+ return;
+ }
+
+ /* If the player was in the middle of a trade, pop the state
+ machine and inform others as necessary */
+ state = sm_current(player->sm);
+ if (state == (StateFunc) mode_wait_quote_exit) {
+ /* Fake the acknowledgement */
+ sm_pop(player->sm);
+ } else if (state == (StateFunc) mode_domestic_quote) {
+ /* Retract all quotes */
+ for (;;) {
+ QuoteInfo *quote;
+ quote = quotelist_find_domestic(game->quotes,
+ player->num, -1);
+ if (quote == NULL)
+ break;
+ quotelist_delete(game->quotes, quote);
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION,
+ "domestic-quote delete %d\n",
+ quote->var.d.quote_num);
+ }
+ } else if (state == (StateFunc) mode_domestic_initiate) {
+ /* End the trade */
+ trade_finish_domestic(player);
+ }
+
+ /* If the player was robbing something, auto-undo to robber
+ * placement. */
+ if (state == (StateFunc) mode_select_robbed
+ || state == (StateFunc) mode_select_pirated)
+ robber_undo(player);
+
+ /* Mark the player as disconnected */
+ player->disconnected = TRUE;
+ game->num_players--;
+ meta_report_num_players(game->num_players);
+}
+
+/* Try to revive the player
+ newp: Player* attempt to revive this player
+ name: The player wants to have this name, if possible
+*/
+void player_revive(Player * newp, char *name)
+{
+ Game *game = newp->game;
+ GList *current = NULL;
+ Player *p = NULL;
+ gboolean reviving_player_in_setup;
+ gchar *safe_name;
+
+ /* first see if a player with the given name exists */
+ if (name) {
+ playerlist_inc_use_count(game);
+ for (current = game->player_list; current != NULL;
+ current = g_list_next(current)) {
+ p = current->data;
+ if (!strcmp(name, p->name))
+ if (p->disconnected && !p->sm->use_cache
+ && p != newp)
+ break;
+ }
+ playerlist_dec_use_count(game);
+ }
+ /* if not, see if any disconnected player exists */
+ if (current == NULL) {
+ playerlist_inc_use_count(game);
+ for (current = game->player_list; current != NULL;
+ current = g_list_next(current)) {
+ p = current->data;
+ if (p->disconnected && !p->sm->use_cache
+ && p != newp)
+ break;
+ }
+ playerlist_dec_use_count(game);
+ }
+ /* if still no player is found, do a normal setup */
+ if (current == NULL) {
+ player_setup(newp, -1, name, FALSE);
+ return;
+ }
+
+ /* Reviving the player that is currently in the setup phase */
+ reviving_player_in_setup =
+ (game->setup_player && game->setup_player->data == p);
+
+ /* remove the disconnected player from the player list, it's memory will be freed at the end of this routine */
+ game->player_list = g_list_remove(game->player_list, p);
+
+ /* initialize the player */
+ player_setup(newp, p->num, name, FALSE);
+
+ /* mark the player as a reconnect */
+ newp->disconnected = TRUE;
+
+ /* Don't use the old player's name */
+
+ /* copy over all the data from p */
+ g_assert(newp->build_list == NULL);
+ newp->build_list = p->build_list;
+ p->build_list = NULL; /* prevent deletion */
+
+ memcpy(newp->prev_assets, p->prev_assets,
+ sizeof(newp->prev_assets));
+ memcpy(newp->assets, p->assets, sizeof(newp->assets));
+ newp->gold = p->gold;
+ /* take over the development deck */
+ deck_free(newp->devel);
+ newp->devel = p->devel;
+ p->devel = NULL;
+
+ g_assert(newp->special_points == NULL);
+ newp->special_points = p->special_points;
+ p->special_points = NULL; /* prevent deletion */
+
+ newp->discard_num = p->discard_num;
+ newp->num_roads = p->num_roads;
+ newp->num_bridges = p->num_bridges;
+ newp->num_ships = p->num_ships;
+ newp->num_settlements = p->num_settlements;
+ newp->num_cities = p->num_cities;
+ newp->num_soldiers = p->num_soldiers;
+ newp->road_len = p->road_len;
+ newp->develop_points = p->develop_points;
+ newp->chapel_played = p->chapel_played;
+ newp->univ_played = p->univ_played;
+ newp->gov_played = p->gov_played;
+ newp->libr_played = p->libr_played;
+ newp->market_played = p->market_played;
+ /* Not copied: sm, game, location, num, client_version */
+
+ /* copy over the state */
+ memcpy(newp->sm->stack, p->sm->stack, sizeof(newp->sm->stack));
+ memcpy(newp->sm->stack_name, p->sm->stack_name,
+ sizeof(newp->sm->stack_name));
+ newp->sm->stack_ptr = p->sm->stack_ptr;
+ newp->sm->current_state = p->sm->current_state;
+
+ sm_push(newp->sm, (StateFunc) mode_pre_game);
+
+ /* Copy longest road and largest army */
+ if (game->longest_road == p)
+ game->longest_road = newp;
+ if (game->largest_army == p)
+ game->largest_army = newp;
+
+ if (reviving_player_in_setup) {
+ /* Restore the pointer */
+ game->setup_player = game->player_list;
+ while (game->setup_player
+ && game->setup_player->data != newp) {
+ game->setup_player =
+ g_list_next(game->setup_player);
+ }
+ g_assert(game->setup_player != NULL);
+ }
+ p->num = -1; /* prevent the number of players
+ from getting decremented */
+
+ player_free(p);
+
+ /* Make sure the name in the broadcast doesn't contain the separator */
+ safe_name = g_strdup(newp->name);
+ g_strdelimit(safe_name, "|", '_');
+ player_broadcast(newp, PB_SILENT, FIRST_VERSION, LATEST_VERSION,
+ "NOTE1 %s|%s\n", safe_name,
+ /* %s is the name of the reconnecting player */
+ N_("%s has reconnected."));
+ g_free(safe_name);
+ return;
+}
+
+gboolean mode_viewer(Player * player, gint event)
+{
+ gint num;
+ Game *game = player->game;
+ StateMachine *sm = player->sm;
+ Player *other;
+
+ sm_state_name(sm, "mode_viewer");
+ if (event != SM_RECV)
+ return FALSE;
+ /* first see if this is a valid event for this mode */
+ if (sm_recv(sm, "play")) {
+ /* try to be the first available player */
+ num = next_free_player_num(game, FALSE);
+ if (num >= game->params->num_players) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR game-full");
+ return TRUE;
+ }
+ } else if (sm_recv(sm, "play %d", &num)) {
+ /* try to be the specified player number */
+ if (num >= game->params->num_players
+ || !player_by_num(game, num)->disconnected) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR invalid-player");
+ return TRUE;
+ }
+ } else
+ /* input was not what we expected,
+ * see if mode_unhandled likes it */
+ return FALSE;
+
+ other = player_by_num(game, num);
+ if (other == NULL) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION, "Ok\n");
+ player_broadcast(player, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION, "was viewer %d\n",
+ player->num);
+ player_setup(player, player->num, player->name, FALSE);
+ sm_goto(sm, (StateFunc) mode_pre_game);
+ return TRUE;
+ }
+ player_revive(player, player->name);
+ return TRUE;
+}
+
+static gboolean mode_bad_version(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+
+ sm_state_name(sm, "mode_bad_version");
+ switch (event) {
+ case SM_ENTER:
+ player_send_uncached(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR sorry, version conflict\n");
+ player_free(player);
+ break;
+ }
+ return FALSE;
+}
+
+/* Supported version names. Whenever this list changes, the enum in server.h
+ * must also change. */
+static const gchar *client_version_type_to_string(ClientVersionType cvt)
+{
+ switch (cvt) {
+ case V0_10:
+ return "0.10";
+ case V0_11:
+ return "0.11";
+ }
+ g_return_val_if_reached("");
+}
+
+static gboolean check_versions(const gchar * client_version,
+ Player * client)
+{
+ ClientVersionType i;
+ for (i = FIRST_VERSION; i <= LATEST_VERSION; ++i) {
+ if (strcmp
+ (client_version,
+ client_version_type_to_string(i)) == 0) {
+ client->version = i;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static gboolean mode_check_version(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ gchar *version;
+
+ sm_state_name(sm, "mode_check_version");
+ switch (event) {
+ case SM_ENTER:
+ player_send_uncached(player, FIRST_VERSION, LATEST_VERSION,
+ "version report\n");
+ break;
+
+ case SM_RECV:
+ if (sm_recv(sm, "version %S", &version)) {
+ gboolean result = check_versions(version, player);
+ if (result) {
+ sm_goto(sm, (StateFunc) mode_check_status);
+ } else {
+ /* PROTOCOL_VERSION is the current version
+ * of the client when building this server.
+ * Although it's not the only supported
+ * version, it's the best the user can have.
+ */
+ gchar *mismatch =
+ g_strdup_printf("%s <-> %s",
+ PROTOCOL_VERSION,
+ version);
+ /* Make sure the argument does not contain the separator */
+ g_strdelimit(mismatch, "|", '_');
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "NOTE1 %s|%s\n",
+ mismatch,
+ N_
+ ("Version mismatch: %s"));
+ g_free(mismatch);
+ sm_goto(sm, (StateFunc) mode_bad_version);
+ }
+ g_free(version);
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+static gboolean mode_check_status(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ gchar *playername;
+
+ sm_state_name(sm, "mode_check_status");
+ switch (event) {
+ case SM_ENTER:
+ player_send_uncached(player, FIRST_VERSION, LATEST_VERSION,
+ "status report\n");
+ break;
+
+ case SM_RECV:
+ if (sm_recv(sm, "status newplayer")) {
+ player_setup(player, -1, NULL, FALSE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "status reconnect %S", &playername)) {
+ /* if possible, try to revive the player */
+ player_revive(player, playername);
+ g_free(playername);
+ return TRUE;
+ }
+ if (sm_recv(sm, "status newviewer")) {
+ player_setup(player, -1, NULL, TRUE);
+ return TRUE;
+ }
+ if (sm_recv(sm, "status viewer %S", &playername)) {
+ player_setup(player, -1, playername, TRUE);
+ g_free(playername);
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/* Returns a GList* to player 0 */
+GList *player_first_real(Game * game)
+{
+ GList *list;
+ /* search for player 0 */
+ playerlist_inc_use_count(game);
+ for (list = game->player_list;
+ list != NULL; list = g_list_next(list)) {
+ Player *player = list->data;
+ if (player->num == 0)
+ break;
+ }
+ playerlist_dec_use_count(game);
+ return list;
+}
+
+/* Returns a GList * to a player with a number one higher than last */
+GList *player_next_real(GList * last)
+{
+ Player *player;
+ Game *game;
+ gint numplayers;
+ gint nextnum;
+ GList *list;
+
+ if (!last)
+ return NULL;
+
+ player = last->data;
+ game = player->game;
+ numplayers = game->params->num_players;
+ nextnum = player->num + 1;
+
+ if (nextnum >= numplayers)
+ return NULL;
+
+ playerlist_inc_use_count(game);
+ for (list = game->player_list; list != NULL;
+ list = g_list_next(list)) {
+ Player *scan = list->data;
+ if (scan->num == nextnum)
+ break;
+ }
+ playerlist_dec_use_count(game);
+ return list;
+}
+
+static Player *player_by_name(Game * game, char *name)
+{
+ GList *list;
+
+ playerlist_inc_use_count(game);
+ for (list = game->player_list;
+ list != NULL; list = g_list_next(list)) {
+ Player *player = list->data;
+
+ if (player->name != NULL
+ && strcmp(player->name, name) == 0) {
+ playerlist_dec_use_count(game);
+ return player;
+ }
+ }
+ playerlist_dec_use_count(game);
+
+ return NULL;
+}
+
+Player *player_by_num(Game * game, gint num)
+{
+ GList *list;
+
+ playerlist_inc_use_count(game);
+ for (list = game->player_list;
+ list != NULL; list = g_list_next(list)) {
+ Player *player = list->data;
+
+ if (player->num == num) {
+ playerlist_dec_use_count(game);
+ return player;
+ }
+ }
+ playerlist_dec_use_count(game);
+
+ return NULL;
+}
+
+gboolean player_is_viewer(Game * game, gint player_num)
+{
+ return game->params->num_players <= player_num;
+}
+
+/* Returns a player that's not part of the game.
+ */
+Player *player_none(Game * game)
+{
+ static Player player;
+
+ player.game = game;
+ player.num = -1;
+ player.disconnected = TRUE;
+ return &player;
+}
+
+/** Broadcast a message to all players and viewers - prepend "player %d " to
+ * all players except the one generating the message.
+ * Also prepend 'extension' when this message is a protocol extension.
+ *
+ * send to PB_SILENT PB_RESPOND PB_ALL PB_OTHERS
+ * player - - + **
+ * other - + + +
+ * ** = don't send to the player
+ * + = prepend 'player %d' to the message
+ * - = don't alter the message
+ */
+static void player_broadcast_internal(Player * player, BroadcastType type,
+ const gchar * message,
+ gboolean is_extension,
+ ClientVersionType
+ first_supported_version,
+ ClientVersionType
+ last_supported_version)
+{
+ Game *game = player->game;
+ GList *list;
+
+ playerlist_inc_use_count(game);
+ for (list = game->player_list; list != NULL;
+ list = g_list_next(list)) {
+ Player *scan = list->data;
+ if ((scan->disconnected && !scan->sm->use_cache) || scan->num < 0
+ || scan->version < first_supported_version
+ || scan->version > last_supported_version)
+ continue;
+ if (type == PB_SILENT
+ || (scan == player && type == PB_RESPOND)) {
+ if (is_extension) {
+ player_send(scan, first_supported_version,
+ last_supported_version,
+ "extension %s", message);
+ } else {
+ player_send(scan, first_supported_version,
+ last_supported_version, "%s",
+ message);
+ }
+ } else if (scan != player || type == PB_ALL) {
+ if (is_extension) {
+ player_send(scan, first_supported_version,
+ last_supported_version,
+ "extension player %d %s",
+ player->num, message);
+ } else {
+ player_send(scan, first_supported_version,
+ last_supported_version,
+ "player %d %s", player->num,
+ message);
+ }
+
+ }
+ }
+ playerlist_dec_use_count(game);
+}
+
+/** As player_broadcast, but will add the 'extension' keyword */
+void player_broadcast_extension(Player * player, BroadcastType type,
+ ClientVersionType first_supported_version,
+ ClientVersionType last_supported_version,
+ const char *fmt, ...)
+{
+ gchar *buff;
+ va_list ap;
+
+ va_start(ap, fmt);
+ buff = sm_vformat(fmt, ap);
+ va_end(ap);
+
+ player_broadcast_internal(player, type, buff, TRUE,
+ first_supported_version,
+ last_supported_version);
+ g_free(buff);
+}
+
+/** Broadcast a message to all players and viewers */
+void player_broadcast(Player * player, BroadcastType type,
+ ClientVersionType first_supported_version,
+ ClientVersionType last_supported_version,
+ const char *fmt, ...)
+{
+ gchar *buff;
+ va_list ap;
+
+ va_start(ap, fmt);
+ buff = sm_vformat(fmt, ap);
+ va_end(ap);
+
+ player_broadcast_internal(player, type, buff, FALSE,
+ first_supported_version,
+ last_supported_version);
+ g_free(buff);
+}
+
+/** Send a message to one player */
+void player_send(Player * player,
+ ClientVersionType first_supported_version,
+ ClientVersionType last_supported_version, const char *fmt,
+ ...)
+{
+ gchar *buff;
+ va_list ap;
+
+ if (player->version < first_supported_version
+ || player->version > last_supported_version)
+ return;
+
+ va_start(ap, fmt);
+ buff = sm_vformat(fmt, ap);
+ va_end(ap);
+
+ sm_write(player->sm, buff);
+ g_free(buff);
+}
+
+/** Send a message to one player, even when caching is turned on */
+void player_send_uncached(Player * player,
+ ClientVersionType first_supported_version,
+ ClientVersionType last_supported_version,
+ const char *fmt, ...)
+{
+ gchar *buff;
+ va_list ap;
+
+ if (player->version < first_supported_version
+ || player->version > last_supported_version)
+ return;
+
+ va_start(ap, fmt);
+ buff = sm_vformat(fmt, ap);
+ va_end(ap);
+
+ sm_write_uncached(player->sm, buff);
+ g_free(buff);
+}
+
+void player_set_name(Player * player, gchar * name)
+{
+ player_set_name_real(player, name, TRUE);
+}
+
+void player_remove(Player * player)
+{
+ driver->player_removed(player);
+}
+
+GList *list_from_player(Player * player)
+{
+ GList *list;
+ for (list = player_first_real(player->game); list != NULL;
+ list = player_next_real(list))
+ if (list->data == player)
+ break;
+ g_assert(list != NULL);
+ return list;
+}
+
+GList *next_player_loop(GList * current, Player * first)
+{
+ current = player_next_real(current);
+ if (current == NULL)
+ current = player_first_real(first->game);
+ if (current->data == first)
+ return NULL;
+ return current;
+}
+
+void playerlist_inc_use_count(Game * game)
+{
+ game->player_list_use_count++;
+}
+
+void playerlist_dec_use_count(Game * game)
+{
+ game->player_list_use_count--;
+ if (game->player_list_use_count == 0) {
+ GList *current;
+ GList *all_dead_players;
+ current = game->dead_players;
+ all_dead_players = game->dead_players; /* Remember this for g_list_free */
+ game->dead_players = NULL; /* Clear the list */
+ for (; current != NULL; current = g_list_next(current)) {
+ Player *p = current->data;
+ player_free(p);
+ }
+ g_list_free(all_dead_players);
+ }
+}
Added: trunk/server/pond.game
===================================================================
--- trunk/server/pond.game (rev 0)
+++ trunk/server/pond.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,25 @@
+title The Pond
+num-players 2
+victory-points 12
+domestic-trade
+num-roads 20
+num-settlements 10
+num-cities 8
+resource-count 20
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+chits 6, 9, 4, 10, 11, 8, 2, 9, 2, 5, 4, 8, 4, 10, 4, 3, 6, 3, 5, 2, 9, 12, 6, 4, 3, 10, 5, 8
+map
+ -, -, h0, m1, f2, p3, m4, t5
+ m6, p7,sw2, s,s?1, s, p8, f9,p10
+h11,f12,h13, s, s,d28+, s,t14,m15,t16
+ m17,f18,p19, s,s?4, s,sg5,p20,f21
+ -, -,h22,p23,f24,m25,f26,t27
+.
Added: trunk/server/pregame.c
===================================================================
--- trunk/server/pregame.c (rev 0)
+++ trunk/server/pregame.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,943 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003-2005 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include "buildrec.h"
+#include "server.h"
+#include "version.h"
+
+static void build_add(Player * player, BuildType type, gint x, gint y,
+ gint pos)
+{
+ Game *game = player->game;
+ Map *map = game->params->map;
+ gint num;
+ gint num_allowed;
+
+ num_allowed = game->double_setup ? 2 : 1;
+
+ /* Add settlement/road
+ */
+ num = buildrec_count_type(player->build_list, type);
+ if (num == num_allowed) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many\n");
+ return;
+ }
+
+ if (type == BUILD_ROAD) {
+ /* Make sure that there are some roads left to use */
+ if (player->num_roads ==
+ game->params->num_build_type[BUILD_ROAD]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many road\n");
+ return;
+ }
+
+ /* Building a road, make sure it is next to a
+ * settlement/road
+ */
+ if (!buildrec_can_setup_road(player->build_list, map,
+ map_edge(map, x, y, pos),
+ game->double_setup)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+ edge_add(player, BUILD_ROAD, x, y, pos, FALSE);
+ return;
+ }
+
+ if (type == BUILD_BRIDGE) {
+ /* Make sure that there are some bridges left to use */
+ if (player->num_bridges ==
+ game->params->num_build_type[BUILD_BRIDGE]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many bridge\n");
+ return;
+ }
+
+ /* Building a bridge, make sure it is next to a
+ * settlement/road
+ */
+ if (!buildrec_can_setup_bridge(player->build_list, map,
+ map_edge(map, x, y, pos),
+ game->double_setup)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+ edge_add(player, BUILD_BRIDGE, x, y, pos, FALSE);
+ return;
+ }
+
+ if (type == BUILD_SHIP) {
+ /* Make sure that there are some ships left to use */
+ if (player->num_ships ==
+ game->params->num_build_type[BUILD_SHIP]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many ship\n");
+ return;
+ }
+
+ /* Building a ship, make sure it is next to a
+ * settlement/ship
+ */
+ if (!buildrec_can_setup_ship(player->build_list, map,
+ map_edge(map, x, y, pos),
+ game->double_setup)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+ edge_add(player, BUILD_SHIP, x, y, pos, FALSE);
+ return;
+ }
+
+ if (type != BUILD_SETTLEMENT) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR expected-road-or-settlement\n");
+ return;
+ }
+ /* Build the settlement
+ */
+ if (!buildrec_can_setup_settlement(player->build_list, map,
+ map_node(map, x, y, pos),
+ game->double_setup)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+ node_add(player, BUILD_SETTLEMENT, x, y, pos, FALSE, NULL);
+}
+
+static void build_remove(Player * player)
+{
+ /* Remove the settlement/road we just built
+ */
+ if (!perform_undo(player))
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+}
+
+static void start_setup_player(Player * player)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+
+ player->build_list = buildrec_free(player->build_list);
+
+ if (game->double_setup)
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION, "setup-double\n");
+ else
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION, "setup %d\n",
+ game->reverse_setup);
+
+ sm_goto(sm, (StateFunc) mode_setup);
+}
+
+static void allocate_resources(Player * player, BuildRec * rec)
+{
+ Game *game = player->game;
+ Map *map = game->params->map;
+ Node *node;
+ gint idx;
+
+ node = map_node(map, rec->x, rec->y, rec->pos);
+
+ resource_start(game);
+ for (idx = 0; idx < G_N_ELEMENTS(node->hexes); idx++) {
+ Hex *hex = node->hexes[idx];
+ if (hex && hex->roll > 0) {
+ if (hex->terrain == GOLD_TERRAIN)
+ ++player->gold;
+ else
+ ++player->assets[hex->terrain];
+ }
+ }
+ /* give out the gold */
+ distribute_first(list_from_player(player));
+ return;
+}
+
+/* Player tried to finish setup mode */
+static void try_setup_done(Player * player)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ Map *map = game->params->map;
+ gint num_allowed;
+
+ num_allowed = game->double_setup ? 2 : 1;
+
+ /* Make sure we have built the right number of
+ * settlements/roads
+ */
+ if (buildrec_count_edges(player->build_list) != num_allowed
+ || buildrec_count_type(player->build_list,
+ BUILD_SETTLEMENT) != num_allowed) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR expected-build-or-remove\n");
+ return;
+ }
+ /* We have the right number, now make sure that all roads are
+ * connected to buildings and vice-versa
+ */
+ if (!buildrec_is_valid(player->build_list, map, player->num)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR unconnected\n");
+ return;
+ }
+ /* Player has finished setup phase - give resources for second
+ * settlement
+ */
+ player_send(player, FIRST_VERSION, LATEST_VERSION, "OK\n");
+
+ if (game->double_setup)
+ allocate_resources(player,
+ buildrec_get(player->build_list,
+ BUILD_SETTLEMENT, 1));
+ else if (game->reverse_setup)
+ allocate_resources(player,
+ buildrec_get(player->build_list,
+ BUILD_SETTLEMENT, 0));
+ else {
+ sm_goto(sm, (StateFunc) mode_idle);
+ next_setup_player(game);
+ }
+}
+
+/* find next player to do setup. */
+void next_setup_player(Game * game)
+{
+ if (game->reverse_setup) {
+ /* Going back for second setup phase
+ */
+ GList *prev = NULL, *list;
+ for (list = player_first_real(game); list != NULL;
+ list = player_next_real(list)) {
+ if (list == game->setup_player)
+ break;
+ prev = list;
+ }
+ game->setup_player = prev;
+ game->double_setup = FALSE;
+ if (game->setup_player != NULL) {
+ start_setup_player(game->setup_player->data);
+ } else {
+ /* Start the game!!!
+ */
+ turn_next_player(game);
+ }
+ } else {
+ /* First setup phase
+ */
+ Player *player;
+ game->setup_player = player_next_real(game->setup_player);
+ player = game->setup_player->data;
+ /* Last player gets double setup
+ */
+ game->double_setup
+ = player_next_real(game->setup_player) == NULL;
+ /* Prepare to go backwards next time
+ */
+ game->reverse_setup = game->double_setup;
+ start_setup_player(game->setup_player->data);
+ }
+}
+
+/* Player must place exactly one settlement and one road which connect
+ * to each other. If last player, then perform a double setup.
+ */
+gboolean mode_setup(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ BuildType type;
+ gint x, y, pos;
+
+ sm_state_name(sm, "mode_setup");
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (sm_recv(sm, "done")) {
+ try_setup_done(player);
+ return TRUE;
+ }
+ if (sm_recv(sm, "build %B %d %d %d", &type, &x, &y, &pos)) {
+ build_add(player, type, x, y, pos);
+ return TRUE;
+ }
+ if (sm_recv(sm, "undo")) {
+ build_remove(player);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void try_start_game(Game * game)
+{
+ GList *list;
+ int num;
+ int numturn;
+
+ num = 0;
+ numturn = 0;
+ for (list = player_first_real(game);
+ list != NULL; list = player_next_real(list)) {
+ Player *player = list->data;
+
+ if (sm_current(player->sm) == (StateFunc) mode_idle)
+ num++;
+
+ if (sm_current(player->sm) == (StateFunc) mode_turn ||
+ sm_current(player->sm)
+ == (StateFunc) mode_discard_resources ||
+ sm_current(player->sm)
+ == (StateFunc) mode_place_robber ||
+ sm_current(player->sm)
+ == (StateFunc) mode_road_building ||
+ sm_current(player->sm)
+ == (StateFunc) mode_monopoly || sm_current(player->sm)
+ == (StateFunc) mode_plenty_resources) {
+ /* looks like this player got disconnected and
+ now it's his turn. */
+ num++;
+ numturn++;
+ }
+ }
+ if (num != game->params->num_players)
+ return;
+
+ if (numturn > 0) {
+ /* someone got disconnected. Now everyone's back. Let's
+ continue the game... */
+
+ return;
+ }
+
+ /* All players have connected, and are ready to begin
+ */
+ meta_start_game();
+ game->setup_player = player_first_real(game);
+ while (((Player *) game->setup_player->data)->num < 0)
+ game->setup_player = game->setup_player->next;
+ game->double_setup = game->reverse_setup = FALSE;
+
+ start_setup_player(game->setup_player->data);
+}
+
+/* Send the player list to the client
+ */
+static void send_player_list(Player * player)
+{
+ Game *game = player->game;
+ GList *list;
+
+ player_send_uncached(player, FIRST_VERSION, LATEST_VERSION,
+ "players follow\n");
+ for (list = game->player_list; list != NULL;
+ list = g_list_next(list)) {
+ Player *scan = list->data;
+ if (player == scan || scan->num < 0)
+ continue;
+ player_send_uncached(player, FIRST_VERSION, LATEST_VERSION,
+ "player %d is %s\n", scan->num,
+ scan->name);
+ player_send_uncached(player, V0_11, LATEST_VERSION,
+ "player %d style %s\n", scan->num,
+ scan->style);
+ if (scan->disconnected)
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "player %d has quit\n",
+ scan->num);
+ }
+ player_send_uncached(player, FIRST_VERSION, LATEST_VERSION, ".\n");
+}
+
+/* Send the game parameters to the player (uncached)
+ */
+static void send_game_line(gpointer player, const gchar * str)
+{
+ player_send_uncached((Player *) player, FIRST_VERSION,
+ LATEST_VERSION, "%s\n", str);
+}
+
+gboolean send_gameinfo_uncached(Map * map, Hex * hex, void *data)
+{
+ gint i;
+ Player *player = data;
+
+ for (i = 0; i < G_N_ELEMENTS(hex->nodes); i++) {
+ if (!hex->nodes[i] || hex->nodes[i]->x != hex->x
+ || hex->nodes[i]->y != hex->y)
+ continue;
+ if (hex->nodes[i]->owner >= 0) {
+ switch (hex->nodes[i]->type) {
+ case BUILD_SETTLEMENT:
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "S%d,%d,%d,%d\n",
+ hex->x, hex->y, i,
+ hex->nodes[i]->owner);
+ break;
+ case BUILD_CITY:
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "C%d,%d,%d,%d\n",
+ hex->x, hex->y, i,
+ hex->nodes[i]->owner);
+ break;
+ default:
+ ;
+ }
+ if (hex->nodes[i]->city_wall) {
+ /* Older clients see an extension message */
+ player_send_uncached(player, FIRST_VERSION,
+ V0_10,
+ "extension city wall\n");
+ player_send_uncached(player, V0_11,
+ LATEST_VERSION,
+ "W%d,%d,%d,%d\n",
+ hex->x, hex->y, i,
+ hex->nodes[i]->owner);
+ }
+ }
+ }
+
+ for (i = 0; i < G_N_ELEMENTS(hex->edges); i++) {
+ if (!hex->edges[i] || hex->edges[i]->x != hex->x
+ || hex->edges[i]->y != hex->y)
+ continue;
+ if (hex->edges[i]->owner >= 0) {
+ switch (hex->edges[i]->type) {
+ case BUILD_ROAD:
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "R%d,%d,%d,%d\n",
+ hex->x, hex->y, i,
+ hex->edges[i]->owner);
+ break;
+ case BUILD_SHIP:
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "SH%d,%d,%d,%d\n",
+ hex->x, hex->y, i,
+ hex->edges[i]->owner);
+ break;
+ case BUILD_BRIDGE:
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "B%d,%d,%d,%d\n",
+ hex->x, hex->y, i,
+ hex->edges[i]->owner);
+ break;
+ default:
+ ;
+ }
+ }
+ }
+
+ if (hex->robber) {
+ player_send_uncached(player, FIRST_VERSION, LATEST_VERSION,
+ "RO%d,%d\n", hex->x, hex->y);
+ }
+
+ if (hex == map->pirate_hex) {
+ player_send_uncached(player, FIRST_VERSION, LATEST_VERSION,
+ "P%d,%d\n", hex->x, hex->y);
+ }
+
+ return FALSE;
+}
+
+/* Player setup phase
+ */
+gboolean mode_pre_game(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ Map *map = game->params->map;
+ StateFunc state;
+ const gchar *prevstate;
+ gint i;
+ GList *next;
+ gint longestroadpnum = -1;
+ gint largestarmypnum = -1;
+ static gboolean recover_from_plenty = FALSE;
+ guint stack_offset;
+ gchar *player_style;
+
+ if (game->longest_road) {
+ longestroadpnum = game->longest_road->num;
+ }
+ if (game->largest_army) {
+ largestarmypnum = game->largest_army->num;
+ }
+
+ sm_state_name(sm, "mode_pre_game");
+ switch (event) {
+ case SM_ENTER:
+ player_send_uncached(player, FIRST_VERSION, LATEST_VERSION,
+ "player %d of %d, welcome to pioneers server %s\n",
+ player->num,
+ game->params->num_players,
+ FULL_VERSION);
+ /* Tell the player that he exists. This is not done in
+ * player_set_name, because at that point the client doesn't
+ * know how many players are in the game, and therefore if
+ * he is a player or a viewer. */
+ /* Tell the other players about this player */
+ player_broadcast(player, PB_OTHERS, FIRST_VERSION,
+ LATEST_VERSION, "is %s\n", player->name);
+ /* Tell this player his own name */
+ player_send_uncached(player, FIRST_VERSION, LATEST_VERSION,
+ "player %d is %s\n", player->num,
+ player->name);
+ break;
+
+ case SM_RECV:
+ if (sm_recv(sm, "style %S", &player_style)) {
+ if (player->style)
+ g_free(player->style);
+ player->style = player_style;
+ player_broadcast(player, PB_OTHERS, V0_11,
+ LATEST_VERSION, "style %s\n",
+ player_style);
+ player_send_uncached(player, V0_11, LATEST_VERSION,
+ "player %d style %s\n",
+ player->num, player_style);
+ return TRUE;
+ }
+ if (sm_recv(sm, "players")) {
+ send_player_list(player);
+ return TRUE;
+ }
+ if (sm_recv(sm, "game")) {
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION, "game\n");
+ params_write_lines(game->params, FALSE,
+ send_game_line, player);
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION, "end\n");
+ return TRUE;
+ }
+ if (sm_recv(sm, "gameinfo")) {
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION, "gameinfo\n");
+ map_traverse(map, send_gameinfo_uncached, player);
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION, ".\n");
+
+ /* Notify old clients about new features */
+ if (game->params->num_build_type[BUILD_CITY_WALL] >
+ 0) {
+ player_send_uncached(player, FIRST_VERSION,
+ V0_10,
+ "extension city wall\n");
+ }
+
+ /* now, send state info */
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "turn num %d\n",
+ game->curr_turn);
+ if (game->curr_player >= 0) {
+ Player *playerturn
+ =
+ player_by_num(game, game->curr_player);
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "player turn: %d\n",
+ playerturn->num);
+ }
+ if (game->rolled_dice) {
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "dice rolled: %d %d\n",
+ game->die1,
+ game->die2);
+ } else if (game->die1 + game->die2 > 1) {
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "dice value: %d %d\n",
+ game->die1,
+ game->die2);
+ }
+ if (game->played_develop) {
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "played develop\n");
+ }
+ if (game->bought_develop) {
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "bought develop\n");
+ }
+ if (player->disconnected) {
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "player disconnected\n");
+ }
+ stack_offset = 1;
+ state = sm_stack_inspect(sm, stack_offset);
+ while ((state == (StateFunc) mode_choose_gold) ||
+ (state == (StateFunc)
+ mode_wait_for_gold_choosing_players)) {
+ ++stack_offset;
+ state = sm_stack_inspect(sm, stack_offset);
+ }
+
+ if (state == (StateFunc) mode_idle)
+ prevstate = "IDLE";
+ else if (state == (StateFunc) mode_turn)
+ prevstate = "TURN";
+ else if (state ==
+ (StateFunc) mode_discard_resources)
+ prevstate = "DISCARD";
+ else if (state == (StateFunc)
+ mode_wait_for_other_discarding_players)
+ prevstate = "DISCARD";
+ else if (state == (StateFunc) mode_place_robber)
+ prevstate = "YOUAREROBBER";
+ else if (state == (StateFunc) mode_road_building)
+ prevstate = "ROADBUILDING";
+ else if (state == (StateFunc) mode_monopoly)
+ prevstate = "MONOPOLY";
+ else if (state ==
+ (StateFunc) mode_plenty_resources) {
+ recover_from_plenty = TRUE;
+ prevstate = "PLENTY";
+ } else if (state == (StateFunc) mode_setup) {
+ if (game->double_setup)
+ prevstate = "SETUPDOUBLE";
+ else if (game->reverse_setup)
+ prevstate = "RSETUP";
+ else
+ prevstate = "SETUP";
+ /* If player is selecting gold, the state
+ * should be IDLE instead */
+ if (stack_offset != 1)
+ prevstate = "IDLE";
+ } else
+ prevstate = "PREGAME";
+
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION, "state %s\n",
+ prevstate);
+
+ /* Send the bank, so the client can count remaining
+ * resources
+ */
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION, "bank %R\n",
+ game->bank_deck);
+
+ /* Send the number of development cards played, so the
+ * client knows how many are left.
+ */
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "development-bought %d\n",
+ game->develop_next);
+
+ /* send player info about what he has:
+ resources, dev cards, roads, # roads,
+ # bridges, # ships, # settles, # cities,
+ # soldiers, road len, dev points,
+ who has longest road/army */
+ /* Only send this when the player is not a viewer */
+ if (!player_is_viewer(game, player->num)) {
+ GList *list;
+
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "playerinfo: resources: %R\n",
+ player->assets);
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "playerinfo: numdevcards: %d\n",
+ player->devel->
+ num_cards);
+ for (i = 0; i < player->devel->num_cards;
+ i++) {
+ player_send_uncached(player,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "playerinfo: devcard: %d %d\n",
+ (gint)
+ player->
+ devel->
+ cards[i].type,
+ player->
+ devel->
+ cards[i].
+ turn_bought);
+ }
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "playerinfo: %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ player->num_roads,
+ player->num_bridges,
+ player->num_ships,
+ player->
+ num_settlements,
+ player->num_cities,
+ player->num_soldiers,
+ player->road_len,
+ player->chapel_played,
+ player->univ_played,
+ player->gov_played,
+ player->libr_played,
+ player->market_played,
+ (player->num ==
+ longestroadpnum),
+ (player->num ==
+ largestarmypnum));
+
+ /* Send special points */
+ list = player->special_points;
+ while (list) {
+ Points *points = list->data;
+ player_send_uncached(player,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "get-point %d %d %d %s\n",
+ player->num,
+ points->id,
+ points->
+ points,
+ points->name);
+ list = g_list_next(list);
+ }
+ }
+ /* send info about other players */
+ for (next = player_first_real(game); next != NULL;
+ next = player_next_real(next)) {
+ Player *p = (Player *) next->data;
+ GList *list;
+ gint numassets = 0;
+ if (p->num == player->num)
+ continue;
+ for (i = 0; i < NO_RESOURCE; i++) {
+ numassets += p->assets[i];
+ }
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "otherplayerinfo: %d %d %d %d %d %d %d %d %d %d %d\n",
+ p->num, numassets,
+ p->devel->num_cards,
+ p->num_soldiers,
+ p->chapel_played,
+ p->univ_played,
+ p->gov_played,
+ p->libr_played,
+ p->market_played,
+ (p->num ==
+ longestroadpnum),
+ (p->num ==
+ largestarmypnum));
+
+ /* Send special points */
+ list = p->special_points;
+ while (list) {
+ Points *points = list->data;
+ player_send_uncached(player,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "get-point %d %d %d %s\n",
+ p->num,
+ points->id,
+ points->
+ points,
+ points->name);
+ list = g_list_next(list);
+ }
+ }
+
+ /* send build info for the current player
+ - what builds the player was in the process
+ of building when he disconnected */
+ for (next = player->build_list;
+ next != NULL; next = g_list_next(next)) {
+ BuildRec *build = (BuildRec *) next->data;
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "buildinfo: %B %d %d %d\n",
+ build->type, build->x,
+ build->y, build->pos);
+ }
+
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION, "end\n");
+ return TRUE;
+ }
+ if (sm_recv(sm, "start")) {
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION, "OK\n");
+
+ /* Some player was in the setup phase */
+ if (game->setup_player != NULL
+ && (Player *) game->setup_player->data !=
+ player) {
+ gint num =
+ ((Player *) (game->setup_player->
+ data))->num;
+ if (game->double_setup)
+ player_send_uncached(player,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "player %d setup-double\n",
+ num);
+ else
+ player_send_uncached(player,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "player %d setup %d\n",
+ num,
+ game->
+ reverse_setup);
+ }
+
+ if (recover_from_plenty) {
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "plenty %R\n",
+ game->bank_deck);
+ recover_from_plenty = FALSE;
+ }
+
+ /* send discard and gold info for all players */
+ for (next = player_first_real(game); next != NULL;
+ next = player_next_real(next)) {
+ Player *p = (Player *) next->data;
+ if (p->discard_num > 0) {
+ player_send_uncached(player,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "player %d must-discard %d\n",
+ p->num,
+ p->
+ discard_num);
+ }
+ if (p->gold > 0) {
+ player_send_uncached(player,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "player %d prepare-gold %d\n",
+ p->num,
+ p->gold);
+
+ }
+ }
+
+ /* The current player was choosing gold */
+ state = sm_stack_inspect(sm, 1);
+ if (state == (StateFunc) mode_choose_gold) {
+ gint limited_bank[NO_RESOURCE];
+ gold_limited_bank(game, player->gold,
+ limited_bank);
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "choose-gold %d %R\n",
+ player->gold,
+ limited_bank);
+ }
+
+ /* Trade was in progress */
+ if (game->curr_player != -1 &&
+ (StateFunc) mode_domestic_initiate ==
+ sm_stack_inspect(player_by_num
+ (game, game->curr_player)->sm,
+ 0)) {
+ QuoteInfo *quote =
+ quotelist_first(game->quotes);
+
+ player_send_uncached(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "player %d domestic-trade call supply %R receive %R\n",
+ game->curr_player,
+ game->quote_supply,
+ game->quote_receive);
+ while (quote) {
+ if (quote->is_domestic) {
+ player_send_uncached
+ (player, FIRST_VERSION,
+ LATEST_VERSION,
+ "player %d domestic-quote quote %d supply %R receive %R\n",
+ quote->var.d.
+ player_num,
+ quote->var.d.
+ quote_num,
+ quote->var.d.supply,
+ quote->var.d.receive);
+ }
+ quote = quotelist_next(quote);
+ }
+ /* The player already rejected all quotes,
+ * send reject again */
+ if (state !=
+ (StateFunc) mode_domestic_quote) {
+ player_send_uncached(player,
+ FIRST_VERSION,
+ LATEST_VERSION,
+ "player %d domestic-quote finish\n",
+ player->num);
+ /* Restore the stack */
+ sm_goto_noenter(sm, (StateFunc)
+ mode_wait_quote_exit);
+ sm_push_noenter(sm, (StateFunc)
+ mode_pre_game);
+ }
+ }
+ sm_set_use_cache(sm, FALSE);
+
+ if (player->disconnected) {
+ player->disconnected = FALSE;
+ driver->player_change(game);
+ if (!sm_is_connected(sm))
+ /* This happens when the connection is
+ * dropped when the cache is sent */
+ sm_goto(sm,
+ (StateFunc) mode_viewer);
+ else
+ sm_pop(sm);
+ } else {
+ if (!player_is_viewer(game, player->num))
+ sm_goto(sm, (StateFunc) mode_idle);
+ else
+ sm_goto(sm,
+ (StateFunc) mode_viewer);
+ }
+ try_start_game(game);
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
Added: trunk/server/resource.c
===================================================================
--- trunk/server/resource.c (rev 0)
+++ trunk/server/resource.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,117 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include "cost.h"
+#include "server.h"
+
+gboolean resource_available(Player * player, gint * resources,
+ gint * num_in_bank)
+{
+ Game *game = player->game;
+ gint idx;
+
+ if (num_in_bank != NULL)
+ *num_in_bank = 0;
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ if (resources[idx] > game->bank_deck[idx]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR no-cards %r\n", idx);
+ return FALSE;
+ }
+ if (num_in_bank != NULL)
+ *num_in_bank += game->bank_deck[idx];
+ }
+
+ return TRUE;
+}
+
+void resource_start(Game * game)
+{
+ GList *list;
+
+ for (list = player_first_real(game);
+ list != NULL; list = player_next_real(list)) {
+ Player *player = list->data;
+
+ memcpy(player->prev_assets,
+ player->assets, sizeof(player->assets));
+ player->gold = 0;
+ }
+}
+
+void resource_end(Game * game, const gchar * action, gint mult)
+{
+ GList *list;
+
+ for (list = player_first_real(game);
+ list != NULL; list = player_next_real(list)) {
+ Player *player = list->data;
+ gint resource[NO_RESOURCE];
+ int idx;
+ gboolean send_message = FALSE;
+
+ for (idx = 0; idx < G_N_ELEMENTS(player->assets); idx++) {
+ gint num;
+
+ num =
+ player->assets[idx] - player->prev_assets[idx];
+ if (game->bank_deck[idx] - num < 0) {
+ num = game->bank_deck[idx];
+ player->assets[idx]
+ = player->prev_assets[idx] + num;
+ }
+
+ resource[idx] = num;
+ if (num != 0)
+ send_message = TRUE;
+
+ game->bank_deck[idx] -= num;
+ }
+
+ if (send_message) {
+ for (idx = 0; idx < NO_RESOURCE; idx++)
+ resource[idx] *= mult;
+ player_broadcast(player, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION, "%s %R\n", action,
+ resource);
+ }
+ }
+}
+
+void resource_spend(Player * player, const gint * cost)
+{
+ Game *game = player->game;
+
+ resource_start(game);
+ cost_buy(cost, player->assets);
+ resource_end(game, "spent", -1);
+}
+
+void resource_refund(Player * player, const gint * cost)
+{
+ Game *game = player->game;
+
+ resource_start(game);
+ cost_refund(cost, player->assets);
+ resource_end(game, "refund", 1);
+}
Added: trunk/server/robber.c
===================================================================
--- trunk/server/robber.c (rev 0)
+++ trunk/server/robber.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,469 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "server.h"
+
+static Hex *previous_robber_hex;
+
+static void move_pirate(Player * player, Hex * hex, gboolean is_undo)
+{
+ Map *map = hex->map;
+
+ previous_robber_hex = map->pirate_hex;
+ map->pirate_hex = hex;
+ /* 0.10 didn't know about undo for movement, so move happens
+ * only after stealing has been done. */
+ if (is_undo) {
+ player_broadcast(player, PB_ALL, V0_11, LATEST_VERSION,
+ "unmoved-pirate %d %d\n", hex->x, hex->y);
+ } else {
+ player_broadcast(player, PB_ALL, V0_11, LATEST_VERSION,
+ "moved-pirate %d %d\n", hex->x, hex->y);
+ }
+}
+
+static void move_robber(Player * player, Hex * hex, gboolean is_undo)
+{
+ Map *map = hex->map;
+
+ previous_robber_hex = map->robber_hex;
+ if (map->robber_hex)
+ map->robber_hex->robber = FALSE;
+ map->robber_hex = hex;
+ map->robber_hex->robber = TRUE;
+ /* 0.10 didn't know about undo for movement, so move happens
+ * only after stealing has been done. */
+ if (is_undo) {
+ player_broadcast(player, PB_ALL, V0_11, LATEST_VERSION,
+ "unmoved-robber %d %d\n", hex->x, hex->y);
+ } else {
+ player_broadcast(player, PB_ALL, V0_11, LATEST_VERSION,
+ "moved-robber %d %d\n", hex->x, hex->y);
+ }
+}
+
+static void steal_card_from(Player * player, Player * victim)
+{
+ Game *game = player->game;
+ gint idx;
+ gint num;
+ gint steal;
+ GList *list;
+
+ /* Work out how many cards the victim has
+ */
+ num = 0;
+ for (idx = 0; idx < G_N_ELEMENTS(victim->assets); idx++)
+ num += victim->assets[idx];
+ if (num == 0) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR no-resources\n");
+ return;
+ }
+
+ /* Work out which card to steal from the victim
+ */
+ steal = get_rand(num);
+ for (idx = 0; idx < G_N_ELEMENTS(victim->assets); idx++) {
+ steal -= victim->assets[idx];
+ if (steal < 0)
+ break;
+ }
+ /* Now inform the various parties of the theft. All
+ * interested parties find out which card was stolen, the
+ * others just hear about the theft.
+ */
+ for (list = game->player_list; list != NULL;
+ list = g_list_next(list)) {
+ Player *scan = list->data;
+
+ if (scan->num >= 0 && !scan->disconnected) {
+ if (scan == player || scan == victim) {
+ player_send(scan, FIRST_VERSION,
+ LATEST_VERSION,
+ "player %d stole %r from %d\n",
+ player->num, idx, victim->num);
+ } else
+ player_send(scan, FIRST_VERSION,
+ LATEST_VERSION,
+ "player %d stole from %d\n",
+ player->num, victim->num);
+ }
+ }
+ /* Alter the assets of the respective players
+ */
+ player->assets[idx]++;
+ victim->assets[idx]--;
+}
+
+static void done_robbing_pre_steal(Player * player)
+{
+ Game *game = player->game;
+ Map *map = game->params->map;
+ Hex *hex = map_robber_hex(map);
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION, V0_10,
+ "moved-robber %d %d\n", hex->x, hex->y);
+}
+
+static void done_robbing_post_steal(Player * player)
+{
+ sm_pop(player->sm);
+ player_send(player, V0_11, LATEST_VERSION, "robber-done\n");
+}
+
+static void do_select_robbed(Player * player, Hex * hex, gint victim_num)
+{
+ Game *game = player->game;
+ Player *owner;
+ Resource resource;
+ gint idx;
+
+ /* Check if the victim has any resources
+ */
+ owner = player_by_num(game, victim_num);
+ if (!owner) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-player: not found\n");
+ return;
+ }
+ for (resource = 0; resource < NO_RESOURCE; resource++)
+ if (owner->assets[resource] != 0)
+ break;
+ if (resource == NO_RESOURCE) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-player: no resources\n");
+ return;
+ }
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); idx++) {
+ Node *node = hex->nodes[idx];
+
+ if (node->type == BUILD_NONE || node->owner != victim_num)
+ continue;
+
+ /* Victim has resources and has a building there: steal. */
+ done_robbing_pre_steal(player);
+ steal_card_from(player, owner);
+ done_robbing_post_steal(player);
+ return;
+ }
+
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-player: no buildings\n");
+}
+
+/* Wait for the player to select a building to rob
+ */
+gboolean mode_select_robbed(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ Map *map = game->params->map;
+ gint victim_num;
+ Hex *hex;
+
+ sm_state_name(sm, "mode_select_robbed");
+
+ hex = map_robber_hex(map);
+
+ if (event == SM_ENTER) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "rob %d %d\n", hex->x, hex->y);
+ return TRUE;
+ }
+
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (sm_recv(sm, "undo")) {
+ robber_undo(player);
+ return TRUE;
+ }
+
+ if (!sm_recv(sm, "rob %d", &victim_num))
+ return FALSE;
+
+ do_select_robbed(player, hex, victim_num);
+ return TRUE;
+}
+
+
+static void do_select_pirated(Player * player, Hex * hex, gint victim_num)
+{
+ Game *game = player->game;
+ Player *owner;
+ Resource resource;
+ gint idx;
+
+ /* Check if the victim has any resources
+ */
+ owner = player_by_num(game, victim_num);
+ if (!owner) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-player: not found\n");
+ return;
+ }
+ for (resource = 0; resource < NO_RESOURCE; resource++)
+ if (owner->assets[resource] != 0)
+ break;
+ if (resource == NO_RESOURCE) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-player: no resources\n");
+ return;
+ }
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); ++idx) {
+ Edge *edge = hex->edges[idx];
+
+ if (edge->type != BUILD_SHIP || edge->owner != victim_num)
+ continue;
+
+ /* Victim has resources and has a ship there: steal. */
+ done_robbing_pre_steal(player);
+ steal_card_from(player, owner);
+ done_robbing_post_steal(player);
+ return;
+ }
+
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-player: no ships\n");
+}
+
+/* Wait for the player to select a ship to rob
+ */
+gboolean mode_select_pirated(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ Map *map = game->params->map;
+ gint victim_num;
+ Hex *hex;
+
+ sm_state_name(sm, "mode_select_pirated");
+
+ hex = map_pirate_hex(map);
+
+ if (event == SM_ENTER) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "rob %d %d\n", hex->x, hex->y);
+ return TRUE;
+ }
+
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (sm_recv(sm, "undo")) {
+ robber_undo(player);
+ return TRUE;
+ }
+
+ if (!sm_recv(sm, "rob %d", &victim_num))
+ return FALSE;
+
+ do_select_pirated(player, hex, victim_num);
+ return TRUE;
+}
+
+/* Wait for the player to place the robber
+ */
+gboolean mode_place_robber(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ Map *map = game->params->map;
+ gint x, y;
+ Hex *hex;
+ gint idx;
+ gint one_victim;
+ gint victim_num = -1;
+ gboolean old_style;
+
+ sm_state_name(sm, "mode_place_robber");
+
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (sm_recv(sm, "move-robber %d %d %d", &x, &y, &victim_num))
+ old_style = TRUE;
+ else if (sm_recv(sm, "move-robber %d %d", &x, &y))
+ old_style = FALSE;
+ else
+ return FALSE;
+
+ hex = map_hex(map, x, y);
+ if (hex == NULL || !can_robber_or_pirate_be_moved(hex)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return TRUE;
+ }
+
+ /* check if the pirate was moved.
+ */
+ if (hex->terrain == SEA_TERRAIN) {
+ move_pirate(player, hex, FALSE);
+
+ /* If there is no-one to steal from, or the players have no
+ * resources, we cannot steal resources.
+ */
+ one_victim = -1;
+ for (idx = 0; idx < G_N_ELEMENTS(hex->edges); ++idx) {
+ Edge *edge = hex->edges[idx];
+ Player *owner;
+ Resource resource;
+
+ if (edge->type != BUILD_SHIP
+ || edge->owner == player->num)
+ /* Can't steal from myself
+ */
+ continue;
+
+ /* Check if the node owner has any resources
+ */
+ owner = player_by_num(game, edge->owner);
+ for (resource = 0; resource < NO_RESOURCE;
+ resource++)
+ if (owner->assets[resource] != 0)
+ break;
+ if (resource == NO_RESOURCE)
+ continue;
+
+ /* Has resources - we can steal
+ */
+ if (one_victim == owner->num)
+ /* We already knew about this player.
+ */
+ continue;
+ if (one_victim >= 0)
+ /* This is the second victim, which means
+ * there is choice. That's all we need to
+ * know.
+ */
+ break;
+ one_victim = owner->num;
+ }
+ if (idx != G_N_ELEMENTS(hex->edges)) {
+ /* There is choice for stealing. Wait for the
+ * user to choose. */
+ if (old_style) {
+ /* The user already chose. */
+ do_select_pirated(player, hex, victim_num);
+ } else
+ sm_goto(sm,
+ (StateFunc) mode_select_pirated);
+ return TRUE;
+ }
+ if (one_victim < 0) {
+ /* No one to steal from - resume turn
+ */
+ done_robbing_pre_steal(player);
+ done_robbing_post_steal(player);
+ return TRUE;
+ }
+ /* Only one victim: automatically steal. */
+ done_robbing_pre_steal(player);
+ steal_card_from(player, player_by_num(game, one_victim));
+ done_robbing_post_steal(player);
+ return TRUE;
+ }
+
+ /* It wasn't the pirate; it was the robber. */
+
+ move_robber(player, hex, FALSE);
+
+ /* If there is no-one to steal from, or the players have no
+ * resources, we cannot steal resources.
+ */
+ one_victim = -1;
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); idx++) {
+ Node *node = hex->nodes[idx];
+ Player *owner;
+ Resource resource;
+
+ if (node->type == BUILD_NONE || node->owner == player->num)
+ /* Can't steal from myself
+ */
+ continue;
+
+ /* Check if the node owner has any resources
+ */
+ owner = player_by_num(game, node->owner);
+ for (resource = 0; resource < NO_RESOURCE; resource++)
+ if (owner->assets[resource] != 0)
+ break;
+ if (resource == NO_RESOURCE)
+ continue;
+
+ /* Has resources - we can steal
+ */
+ if (one_victim == owner->num)
+ /* We already knew about this player.
+ */
+ continue;
+ if (one_victim >= 0)
+ /* This is the second victim, which means
+ * there is choice. That's all we need to
+ * know.
+ */
+ break;
+ one_victim = owner->num;
+ }
+ if (idx != G_N_ELEMENTS(hex->nodes)) {
+ /* There is choice for stealing. Wait for the user to choose.
+ */
+ if (old_style) {
+ /* The user already chose. */
+ do_select_robbed(player, hex, victim_num);
+ } else
+ sm_goto(sm, (StateFunc) mode_select_robbed);
+ return TRUE;
+ }
+ if (one_victim < 0) {
+ /* No one to steal from - resume turn
+ */
+ done_robbing_pre_steal(player);
+ done_robbing_post_steal(player);
+ return TRUE;
+ }
+ /* Only one victim: automatically steal. */
+ done_robbing_pre_steal(player);
+ steal_card_from(player, player_by_num(game, one_victim));
+ done_robbing_post_steal(player);
+ return TRUE;
+}
+
+void robber_place(Player * player)
+{
+ StateMachine *sm = player->sm;
+ player_broadcast(player, PB_OTHERS, FIRST_VERSION, LATEST_VERSION,
+ "is-robber\n");
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "you-are-robber\n");
+ sm_push(sm, (StateFunc) mode_place_robber);
+}
+
+void robber_undo(Player * player)
+{
+ if (previous_robber_hex->terrain == SEA_TERRAIN)
+ move_pirate(player, previous_robber_hex, TRUE);
+ else
+ move_robber(player, previous_robber_hex, TRUE);
+ sm_goto(player->sm, (StateFunc) mode_place_robber);
+ player_send(player, V0_11, LATEST_VERSION, "undo-robber\n");
+}
Added: trunk/server/seafarers-gold.game
===================================================================
--- trunk/server/seafarers-gold.game (rev 0)
+++ trunk/server/seafarers-gold.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,33 @@
+title Seafarers with gold
+strict-trade
+domestic-trade
+num-players 4
+victory-points 10
+num-roads 15
+num-ships 15
+num-settlements 5
+num-cities 4
+resource-count 19
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+use-pirate
+
+chits 5,2,6,3,8,12,9,12,11,4,8,10,2,4,5,6,3,11,5,2,6,3,8,10,9,12,11,4,8,10,9,4,5,6,3,11,12,6
+map
+s,s,sw5,s,s,sg4,s,s?5,s
+s,g0+,m1,h2,h3,h4,f5,g6+,s
+s,s?0,t7,m8,p9,f10,t11,p12,sw3
+s,f13,s?1,s,s,sg2,s,m14,s
+s,sb1,s,f15,m16,f17,p18,s,so2
+s,m19,t20,t21,f22,p23,m24,h25,s
+s,sb0,t26,p27,d28,h29,f30,f31,s
+s,t32,p33,h34,m35,p36,m37,h38,s?3
+s,s,s,sl1,s,s,s?2,s,s
+.
Added: trunk/server/seafarers.game
===================================================================
--- trunk/server/seafarers.game (rev 0)
+++ trunk/server/seafarers.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,33 @@
+title Seafarers
+strict-trade
+domestic-trade
+num-players 4
+victory-points 10
+num-roads 15
+num-ships 15
+num-settlements 5
+num-cities 4
+resource-count 19
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+use-pirate
+
+chits 5,2,6,3,8,10,9,12,11,4,8,10,9,4,5,6,3,11,5,2,6,3,8,10,9,12,11,4,8,10,9,4,5,6,3,11,12,6
+map
+s,s,sw5,s,s,sg4,s,s?5,s
+s,p0,m1,h2,h3,h4,f5,t6,s
+s,s?0,t7,m8,p9,f10,t11,p12,sw3
+s,f13,s?1,s,s,sg2,s,m14,s
+s,sb1,s,f15,m16,f17,p18,s,so2
+s,m19,t20,t21,f22,p23,m24,h25,s
+s,sb0,t26,p27,d28,h29,f30,f31,s
+s,t32,p33,h34,m35,p36,m37,h38,s?3
+s,s,s,sl1,s,s,s?2,s,s
+.
Added: trunk/server/server.c
===================================================================
--- trunk/server/server.c (rev 0)
+++ trunk/server/server.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,490 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <signal.h>
+
+#include "server.h"
+
+static GameParams *load_game_desc(const gchar * fname);
+
+static Game *curr_game;
+gint no_player_timeout = 0;
+guint no_player_timer = 0;
+
+static GSList *_game_list = NULL; /* The sorted list of game titles */
+
+#define TERRAIN_DEFAULT 0
+#define TERRAIN_RANDOM 1
+
+static gboolean timed_out(G_GNUC_UNUSED gpointer data)
+{
+ log_message(MSG_INFO,
+ _
+ ("Was hanging around for too long without players... bye.\n"));
+ request_server_stop();
+ return FALSE;
+}
+
+void start_timeout(void)
+{
+ if (!no_player_timeout)
+ return;
+ no_player_timer =
+ g_timeout_add(no_player_timeout * 1000, timed_out, NULL);
+}
+
+void stop_timeout(void)
+{
+ if (no_player_timer != 0) {
+ g_source_remove(no_player_timer);
+ no_player_timer = 0;
+ }
+}
+
+gint get_rand(gint range)
+{
+ return g_rand_int_range(g_rand_ctx, 0, range);
+}
+
+Game *game_new(const GameParams * params)
+{
+ Game *game;
+ gint idx;
+
+ game = g_malloc0(sizeof(*game));
+
+ game->is_game_over = FALSE;
+ game->params = params_copy(params);
+ game->curr_player = -1;
+
+ for (idx = 0; idx < G_N_ELEMENTS(game->bank_deck); idx++)
+ game->bank_deck[idx] = game->params->resource_count;
+ develop_shuffle(game);
+ if (params->random_terrain)
+ map_shuffle_terrain(game->params->map);
+
+ return game;
+}
+
+void game_free(Game * game)
+{
+ if (game->accept_tag)
+ driver->input_remove(game->accept_tag);
+ if (game->accept_fd >= 0)
+ close(game->accept_fd);
+
+ g_assert(game->player_list_use_count == 0);
+ while (game->player_list != NULL) {
+ Player *player = game->player_list->data;
+ player_remove(player);
+ player_free(player);
+ }
+ if (game->server_port != NULL)
+ g_free(game->server_port);
+ params_free(game->params);
+ g_free(game);
+}
+
+gint accept_connection(gint in_fd, gchar ** location)
+{
+ int fd;
+ gchar *error_message;
+ gchar *port;
+
+ fd = net_accept(in_fd, &error_message);
+ if (fd < 0) {
+ log_message(MSG_ERROR, "%s\n", error_message);
+ g_free(error_message);
+ return -1;
+ }
+
+ g_assert(location != NULL);
+ if (!net_get_peer_name(fd, location, &port, &error_message)) {
+ log_message(MSG_ERROR, "%s\n", error_message);
+ g_free(error_message);
+ }
+ g_free(port);
+ return fd;
+}
+
+gint new_computer_player(const gchar * server, const gchar * port,
+ gboolean want_chat)
+{
+ gchar *child_argv[8];
+ GError *error = NULL;
+ gint ret = 0;
+ gint n = 0;
+ gint i;
+
+ if (!server)
+ server = PIONEERS_DEFAULT_GAME_HOST;
+
+ child_argv[n++] = g_strdup(PIONEERS_AI_PATH);
+ child_argv[n++] = g_strdup(PIONEERS_AI_PATH);
+ child_argv[n++] = g_strdup("-s");
+ child_argv[n++] = g_strdup(server);
+ child_argv[n++] = g_strdup("-p");
+ child_argv[n++] = g_strdup(port);
+ if (!want_chat)
+ child_argv[n++] = g_strdup("-c");
+ child_argv[n] = NULL;
+ g_assert(n < 8);
+
+ if (!g_spawn_async(NULL, child_argv, NULL, 0, NULL, NULL,
+ NULL, &error)) {
+ log_message(MSG_ERROR,
+ _("Error starting %s: %s"),
+ PIONEERS_AI_PATH, error->message);
+ g_error_free(error);
+ ret = -1;
+ }
+ for (i = 0; child_argv[i] != NULL; i++)
+ g_free(child_argv[i]);
+ return ret;
+}
+
+
+static void player_connect(Game * game)
+{
+ gchar *location;
+ gint fd = accept_connection(game->accept_fd, &location);
+
+ if (fd > 0) {
+ if (player_new(game, fd, location) != NULL)
+ stop_timeout();
+ }
+ g_free(location);
+}
+
+static gboolean game_server_start(Game * game, gboolean register_server,
+ const gchar * meta_server_name)
+{
+ gchar *error_message;
+
+ game->accept_fd =
+ net_open_listening_socket(game->server_port, &error_message);
+ if (game->accept_fd == -1) {
+ log_message(MSG_ERROR, "%s\n", error_message);
+ g_free(error_message);
+ return FALSE;
+ }
+ start_timeout();
+
+ game->accept_tag = driver->input_add_read(game->accept_fd,
+ (InputFunc)
+ player_connect, game);
+
+ if (register_server) {
+ g_assert(meta_server_name != NULL);
+ meta_register(meta_server_name, PIONEERS_DEFAULT_META_PORT,
+ game);
+ }
+ return TRUE;
+}
+
+gboolean server_startup(const GameParams * params, const gchar * hostname,
+ const gchar * port, gboolean register_server,
+ const gchar * meta_server_name,
+ gboolean random_order)
+{
+ guint32 randomseed = time(NULL);
+
+ g_rand_ctx = g_rand_new_with_seed(randomseed);
+ log_message(MSG_INFO, "%s #%" G_GUINT32_FORMAT ".%s.%03d\n",
+ /* Server: preparing game #..... */
+ _("Preparing game"), randomseed, "G", get_rand(1000));
+
+ curr_game = game_new(params);
+ g_assert(curr_game->server_port == NULL);
+ curr_game->server_port = g_strdup(port);
+ curr_game->hostname = g_strdup(hostname);
+ curr_game->random_order = random_order;
+ if (game_server_start
+ (curr_game, register_server, meta_server_name))
+ return TRUE;
+ game_free(curr_game);
+ curr_game = NULL;
+ return FALSE;
+}
+
+gboolean server_stop(void)
+{
+ if (curr_game == NULL)
+ return FALSE;
+ meta_unregister();
+ game_free(curr_game);
+ curr_game = NULL;
+ return TRUE;
+}
+
+/* Return true if a game is running */
+gboolean server_is_running(void)
+{
+ return curr_game != NULL;
+}
+
+static gint sort_function(gconstpointer a, gconstpointer b)
+{
+ return (strcmp(((const GameParams *) a)->title,
+ ((const GameParams *) b)->title));
+}
+
+static gboolean game_list_add_item(GameParams * item)
+{
+ /* check for name collisions */
+ if (item->title && game_list_find_item(item->title)) {
+
+ gchar *nt;
+ gint i;
+
+ /* append a number */
+ for (i = 1; i <= INT_MAX; i++) {
+ nt = g_strdup_printf("%s%d", item->title, i);
+ if (!game_list_find_item(nt)) {
+ g_free(item->title);
+ item->title = nt;
+ break;
+ }
+ g_free(nt);
+ }
+ /* give up and skip this game */
+ if (item->title != nt) {
+ g_free(nt);
+ return FALSE;
+ }
+ }
+
+ _game_list =
+ g_slist_insert_sorted(_game_list, item, sort_function);
+ return TRUE;
+}
+
+/** Returns TRUE if the game list is empty */
+static gboolean game_list_is_empty(void)
+{
+ return _game_list == NULL;
+}
+
+static gint game_list_locate(gconstpointer param, gconstpointer argument)
+{
+ const GameParams *data = param;
+ const gchar *title = argument;
+ return strcmp(data->title, title);
+}
+
+const GameParams *game_list_find_item(const gchar * title)
+{
+ GSList *result;
+ if (!_game_list) {
+ return NULL;
+ }
+
+ result = g_slist_find_custom(_game_list, title, game_list_locate);
+ if (result)
+ return result->data;
+ else
+ return NULL;
+}
+
+void game_list_foreach(GFunc func, gpointer user_data)
+{
+ if (_game_list) {
+ g_slist_foreach(_game_list, func, user_data);
+ }
+}
+
+GameParams *load_game_desc(const gchar * fname)
+{
+ GameParams *params;
+
+ params = params_load_file(fname);
+ if (params == NULL)
+ g_warning("Skipping: %s", fname);
+ return params;
+}
+
+void load_game_types(const gchar * path)
+{
+ GDir *dir;
+ const gchar *fname;
+ gchar *fullname;
+
+ if ((dir = g_dir_open(path, 0, NULL)) == NULL) {
+ log_message(MSG_ERROR, _("Missing game directory\n"));
+ return;
+ }
+
+ while ((fname = g_dir_read_name(dir))) {
+ GameParams *params;
+ gint len = strlen(fname);
+
+ if (len < 6 || strcmp(fname + len - 5, ".game") != 0)
+ continue;
+ fullname = g_build_filename(path, fname, NULL);
+ params = load_game_desc(fullname);
+ g_free(fullname);
+ if (params) {
+ if (!game_list_add_item(params))
+ params_free(params);
+ }
+ }
+ g_dir_close(dir);
+ if (game_list_is_empty())
+ g_error("No games available");
+}
+
+/* game configuration functions / callbacks */
+void cfg_set_num_players(GameParams * params, gint num_players)
+{
+#ifdef PRINT_INFO
+ g_print("cfg_set_num_players: %d\n", num_players);
+#endif
+ g_return_if_fail(params != NULL);
+ params->num_players = CLAMP(num_players, 2, MAX_PLAYERS);
+}
+
+void cfg_set_sevens_rule(GameParams * params, gint sevens_rule)
+{
+#ifdef PRINT_INFO
+ g_print("cfg_set_sevens_rule: %d\n", sevens_rule);
+#endif
+ g_return_if_fail(params != NULL);
+ params->sevens_rule = CLAMP(sevens_rule, 0, 2);
+}
+
+void cfg_set_victory_points(GameParams * params, gint victory_points)
+{
+#ifdef PRINT_INFO
+ g_print("cfg_set_victory_points: %d\n", victory_points);
+#endif
+ g_return_if_fail(params != NULL);
+ params->victory_points = MAX(3, victory_points);
+}
+
+GameParams *cfg_set_game(const gchar * game)
+{
+#ifdef PRINT_INFO
+ g_print("cfg_set_game: %s\n", game);
+#endif
+ return params_copy(game_list_find_item(game));
+}
+
+GameParams *cfg_set_game_file(const gchar * game_filename)
+{
+#ifdef PRINT_INFO
+ g_print("cfg_set_game_file: %s\n", game_filename);
+#endif
+ return params_load_file(game_filename);
+}
+
+void cfg_set_terrain_type(GameParams * params, gint terrain_type)
+{
+#ifdef PRINT_INFO
+ g_print("cfg_set_terrain_type: %d\n", terrain_type);
+#endif
+ g_return_if_fail(params != NULL);
+ params->random_terrain = (terrain_type == TERRAIN_RANDOM) ? 1 : 0;
+}
+
+void cfg_set_tournament_time(GameParams * params, gint tournament_time)
+{
+#ifdef PRINT_INFO
+ g_print("cfg_set_tournament_time: %d\n", tournament_time);
+#endif
+ g_return_if_fail(params != NULL);
+ params->tournament_time = tournament_time;
+}
+
+void cfg_set_quit(GameParams * params, gboolean quitdone)
+{
+#ifdef PRINT_INFO
+ g_print("cfg_set_quit: %d\n", quitdone);
+#endif
+ g_return_if_fail(params != NULL);
+ params->quit_when_done = quitdone;
+}
+
+void cfg_set_timeout(gint to)
+{
+#ifdef PRINT_INFO
+ g_print("cfg_set_timeout: %d\n", to);
+#endif
+ no_player_timeout = to;
+}
+
+void admin_broadcast(const gchar * message)
+{
+ /* The message that is sent must not be translated */
+ player_broadcast(player_none(curr_game), PB_SILENT, FIRST_VERSION,
+ LATEST_VERSION, "NOTE1 %s|%s\n", message, "%s");
+}
+
+gboolean start_server(const GameParams * params, const gchar * hostname,
+ const gchar * port, gboolean register_server,
+ const gchar * meta_server_name,
+ gboolean random_order)
+{
+ g_return_val_if_fail(params != NULL, FALSE);
+#ifdef PRINT_INFO
+ g_print("game type: %s\n", params->title);
+ g_print("num players: %d\n", params->num_players);
+ g_print("victory points: %d\n", params->victory_points);
+ g_print("terrain type: %s\n",
+ (params->random_terrain) ? "random" : "default");
+ g_print("Tournament time: %d\n", params->tournament_time);
+ g_print("Quit when done: %d\n", params->quit_when_done);
+#endif
+
+ return server_startup(params, hostname, port, register_server,
+ meta_server_name, random_order);
+}
+
+/* server initialization */
+void server_init(void)
+{
+ /* Broken pipes can happen when multiple players disconnect
+ * simultaneously. This mostly happens to AI's, which disconnect
+ * when the game is over. */
+ /* SIGPIPE does not exist for G_OS_WIN32 */
+#ifndef G_OS_WIN32
+ struct sigaction sa;
+ sa.sa_flags = 0;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGPIPE, &sa, NULL);
+#endif /* G_OS_WIN32 */
+}
+
+void server_cleanup_static_data(void)
+{
+ GSList *games = _game_list;
+ while (games) {
+ params_free(games->data);
+ games = g_slist_next(games);
+ }
+ g_slist_free(_game_list);
+}
Added: trunk/server/server.h
===================================================================
--- trunk/server/server.h (rev 0)
+++ trunk/server/server.h 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,296 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003-2007 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef __server_h
+#define __server_h
+
+#include "game.h"
+#include "cards.h"
+#include "map.h"
+#include "quoteinfo.h"
+#include "state.h"
+
+/* Supported versions. These are ordered, so that it is possible to see
+ * if versions are greater or smaller than each other. The actual values do
+ * not matter and will change when older versions stop being supported. No
+ * part of the program may depend on their exact value, all comparisons must
+ * always be done with the symbols. */
+/* Names for the versions are defined in server/player.c, and must be
+ * changed when the enum changes. */
+typedef enum {
+ V0_10, /**< Lowest supported version */
+ V0_11, /**< City walls, player style, robber undo */
+ FIRST_VERSION = V0_10,
+ LATEST_VERSION = V0_11
+} ClientVersionType;
+
+#define TERRAIN_DEFAULT 0
+#define TERRAIN_RANDOM 1
+
+typedef struct Game Game;
+typedef struct {
+ StateMachine *sm; /* state machine for this player */
+ Game *game; /* game that player belongs to */
+
+ gchar *location; /* reverse lookup player hostname */
+ gint num; /* number each player */
+ char *name; /* give each player a name */
+ gchar *style; /* description of the player icon */
+ ClientVersionType version; /* version, so adapted messages can be sent */
+
+ GList *build_list; /* list of building that can be undone */
+ gint prev_assets[NO_RESOURCE]; /* remember previous resources */
+ gint assets[NO_RESOURCE]; /* our resources */
+ gint gold; /* how much gold will we recieve? */
+ DevelDeck *devel; /* development cards we own */
+ GList *special_points; /* points from special actions */
+ gint special_points_next_id; /* Next id for the special points */
+ gint discard_num; /* number of resources we must discard */
+
+ gint num_roads; /* number of roads available */
+ gint num_bridges; /* number of bridges available */
+ gint num_ships; /* number of ships available */
+ gint num_settlements; /* settlements available */
+ gint num_cities; /* cities available */
+ gint num_city_walls; /* city walls available */
+
+ gint num_soldiers; /* number of soldiers played */
+ gint road_len; /* last longest road */
+ gint develop_points; /* number of development card victory points */
+ gint chapel_played; /* number of Chapel cards played */
+ gint univ_played; /* number of University cards played */
+ gint gov_played; /* number of Governors cards played */
+ gint libr_played; /* number of Library cards played */
+ gint market_played; /* number of Market cards played */
+ gint islands_discovered; /* number of islands discovered */
+ gboolean disconnected;
+} Player;
+
+struct Game {
+ GameParams *params; /* game parameters */
+ gchar *hostname; /* reported hostname */
+
+ int accept_fd; /* socket for accepting new clients */
+ int accept_tag; /* Gdk event tag for accept socket */
+
+ GList *player_list; /* all players in the game */
+ GList *dead_players; /* all players that should be removed when player_list_use_count == 0 */
+ gint player_list_use_count; /* # functions is in use by */
+ gint num_players; /* current number of players in the game */
+
+ gboolean double_setup;
+ gboolean reverse_setup;
+ GList *setup_player;
+
+ gboolean is_game_over; /* is the game over? */
+ Player *longest_road; /* who holds longest road */
+ Player *largest_army; /* who has largest army */
+
+ QuoteList *quotes; /* domestic trade quotes */
+ gint quote_supply[NO_RESOURCE]; /* only valid when trading */
+ gint quote_receive[NO_RESOURCE]; /* only valid when trading */
+
+ gint curr_player; /* whose turn is it? */
+ gint curr_turn; /* current turn number */
+ gboolean rolled_dice; /* has dice been rolled in turn yet? */
+ gint die1, die2; /* latest dice values */
+ gboolean played_develop; /* has devel. card been played in turn? */
+ gboolean bought_develop; /* has devel. card been bought in turn? */
+
+ gint bank_deck[NO_RESOURCE]; /* resource card bank */
+ gint num_develop; /* number of development cards */
+ gint *develop_deck; /* development cards */
+ gint develop_next; /* next development card to deal */
+
+ gchar *server_port; /* port to run game on */
+ gboolean random_order; /* is turn order randomized? */
+};
+
+/**** global variables ****/
+/* buildutil.c */
+void check_longest_road(Game * game, gboolean can_cut);
+void node_add(Player * player,
+ BuildType type, int x, int y, int pos, gboolean paid_for,
+ Points * special_points);
+void edge_add(Player * player, BuildType type, int x, int y, int pos,
+ gboolean paid_for);
+gboolean perform_undo(Player * player);
+
+/* develop.c */
+void develop_shuffle(Game * game);
+void develop_buy(Player * player);
+void develop_play(Player * player, gint idx);
+gboolean mode_road_building(Player * player, gint event);
+gboolean mode_plenty_resources(Player * player, gint event);
+gboolean mode_monopoly(Player * player, gint event);
+
+/* discard.c */
+void discard_resources(Game * player);
+gboolean mode_discard_resources(Player * player, gint event);
+gboolean mode_wait_others_place_robber(Player * player, gint event);
+gboolean mode_discard_resources_place_robber(Player * player, gint event);
+
+/* meta.c */
+gchar *get_server_name(void);
+void meta_register(const gchar * server, const gchar * port, Game * game);
+void meta_unregister(void);
+void meta_start_game(void);
+void meta_report_num_players(gint num_players);
+void meta_send_details(Game * game);
+
+/* player.c */
+typedef enum {
+ PB_ALL,
+ PB_RESPOND,
+ PB_SILENT,
+ PB_OTHERS
+} BroadcastType;
+Player *player_new(Game * game, int fd, gchar * location);
+Player *player_by_num(Game * game, gint num);
+void player_set_name(Player * player, gchar * name);
+Player *player_none(Game * game);
+void player_broadcast(Player * player, BroadcastType type,
+ ClientVersionType first_supported_version,
+ ClientVersionType last_supported_version,
+ const char *fmt, ...);
+void player_broadcast_extension(Player * player, BroadcastType type,
+ ClientVersionType first_supported_version,
+ ClientVersionType last_supported_version,
+ const char *fmt, ...);
+void player_send(Player * player,
+ ClientVersionType first_supported_version,
+ ClientVersionType last_supported_version, const char *fmt,
+ ...);
+void player_send_uncached(Player * player,
+ ClientVersionType first_supported_version,
+ ClientVersionType last_supported_version,
+ const char *fmt, ...);
+void player_remove(Player * player);
+void player_free(Player * player);
+void player_archive(Player * player);
+void player_revive(Player * newp, char *name);
+GList *player_first_real(Game * game);
+GList *player_next_real(GList * last);
+GList *list_from_player(Player * player);
+GList *next_player_loop(GList * current, Player * first);
+gboolean mode_viewer(Player * player, gint event);
+void playerlist_inc_use_count(Game * game);
+void playerlist_dec_use_count(Game * game);
+gboolean player_is_viewer(Game * game, gint player_num);
+
+/* pregame.c */
+gboolean mode_pre_game(Player * player, gint event);
+gboolean mode_setup(Player * player, gint event);
+gboolean send_gameinfo_uncached(Map * map, Hex * hex, void *player);
+void next_setup_player(Game * game);
+
+/* resource.c */
+gboolean resource_available(Player * player,
+ gint * resources, gint * num_in_bank);
+void resource_maritime_trade(Player * player,
+ Resource supply, Resource receive,
+ gint ratio);
+void resource_start(Game * game);
+void resource_end(Game * game, const gchar * action, gint mult);
+void resource_spend(Player * player, const gint * cost);
+void resource_refund(Player * player, const gint * cost);
+
+/* robber.c */
+void robber_place(Player * player);
+gboolean mode_place_robber(Player * player, gint event);
+gboolean mode_select_pirated(Player * player, gint event);
+gboolean mode_select_robbed(Player * player, gint event);
+void robber_undo(Player * player);
+
+/* server.c */
+void start_timeout(void);
+void stop_timeout(void);
+gint get_rand(gint range);
+Game *game_new(const GameParams * params);
+void game_free(Game * game);
+gint new_computer_player(const gchar * server, const gchar * port,
+ gboolean want_chat);
+gboolean server_startup(const GameParams * params, const gchar * hostname,
+ const gchar * port, gboolean meta_register,
+ const gchar * meta_name_server,
+ gboolean random_order);
+gboolean server_stop(void);
+gboolean server_is_running(void);
+gint accept_connection(gint in_fd, gchar ** location);
+void server_cleanup_static_data(void);
+
+/**** game list control functions ****/
+const GameParams *game_list_find_item(const gchar * title);
+void game_list_foreach(GFunc func, gpointer user_data);
+void load_game_types(const gchar * path);
+
+/**** callbacks to set parameters ****/
+GameParams *cfg_set_game(const gchar * game);
+GameParams *cfg_set_game_file(const gchar * game_filename);
+void cfg_set_num_players(GameParams * params, gint num_players);
+void cfg_set_sevens_rule(GameParams * params, gint sevens_rule);
+void cfg_set_victory_points(GameParams * params, gint victory_points);
+void cfg_set_terrain_type(GameParams * params, gint terrain_type);
+void cfg_set_tournament_time(GameParams * params, gint tournament_time);
+void cfg_set_quit(GameParams * params, gboolean quitdone);
+void cfg_set_timeout(gint to);
+void admin_broadcast(const gchar * message);
+
+/* callbacks related to server starting / stopping */
+gboolean start_server(const GameParams * params, const gchar * hostname,
+ const gchar * port, gboolean register_server,
+ const gchar * meta_server_name,
+ gboolean random_order);
+
+/* initialize the server */
+void server_init(void);
+void game_is_over(Game * game);
+void request_server_stop(void);
+
+/* trade.c */
+void trade_perform_maritime(Player * player,
+ gint ratio, Resource supply, Resource receive);
+gboolean mode_wait_quote_exit(Player * player, gint event);
+gboolean mode_domestic_quote(Player * player, gint event);
+void trade_finish_domestic(Player * player);
+void trade_accept_domestic(Player * player,
+ gint partner_num, gint quote_num,
+ gint * supply, gint * receive);
+gboolean mode_domestic_initiate(Player * player, gint event);
+void trade_begin_domestic(Player * player, gint * supply, gint * receive);
+
+/* turn.c */
+gboolean mode_idle(Player * player, gint event);
+gboolean mode_turn(Player * player, gint event);
+void turn_next_player(Game * game);
+void check_victory(Player * player);
+
+/* gold.c */
+gboolean gold_limited_bank(const Game * game, int limit,
+ gint * limited_bank);
+void distribute_first(GList * list);
+gboolean mode_choose_gold(Player * player, gint event);
+gboolean mode_wait_for_gold_choosing_players(Player * player, gint event);
+
+/* discard.c */
+gboolean mode_wait_for_other_discarding_players(Player * player,
+ gint event);
+#endif
Added: trunk/server/small.game
===================================================================
--- trunk/server/small.game (rev 0)
+++ trunk/server/small.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,26 @@
+title Small
+random-terrain
+strict-trade
+num-players 2
+victory-points 16
+num-roads 15
+num-settlements 5
+num-cities 4
+resource-count 19
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+chits 5,2,6,3,8,10,9,12,11,4
+map
+-, s,s?5, s,so4
+s?0, t6, p5, m4, s
+s, h7, t8, m9, f3,sb3
+sl0, h0, p1, f2, s
+-, s,sw1, s,sg2
+.
Added: trunk/server/square.game
===================================================================
--- trunk/server/square.game (rev 0)
+++ trunk/server/square.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,27 @@
+title Square
+strict-trade
+num-players 2
+victory-points 8
+num-roads 15
+num-settlements 5
+num-cities 4
+resource-count 19
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 13
+chits 6,2,8,12,6,5,3,9,11,5,4,4,10,10,4,3,5,11,9,3,2,6,12,8,2
+map
+s,s,s,s,s,s,s
+s,m0,t1,p2,h3,f4,s
+s,m5,t6,p7,h8,f9,s
+s,m10,t11,p12,h13,f14,s
+s,m15,t16,p17,h18,f19,s
+s,m20,t21,p22,h23,f24,s
+s,s,s,s,s,s,s
+.
Added: trunk/server/star.game
===================================================================
--- trunk/server/star.game (rev 0)
+++ trunk/server/star.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,32 @@
+title Star
+domestic-trade
+num-players 2
+victory-points 8
+num-roads 15
+num-settlements 4
+num-cities 5
+resource-count 24
+develop-road 2
+develop-monopoly 2
+develop-plenty 2
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 10
+chits 2, 12, 3, 11, 4, 10, 5, 9, 6, 8, 12, 11, 10, 9, 8, 6, 5, 4, 3, 2, 8, 9, 10, 11, 12, 2
+map
+-
+ -,-,m1,-,-,-,-,t2,-,-
+-,-,-,f3,-,-,-,p4,-,-
+ -,-,-,h5,-,-,h6,-,-,-
+-,-,-,-, t7,-,m8,-,-,-,-
+ -,-,-,-, p9,f10,-,-,-,-,
+h11,f12,m13,p15,t16,d27+,h17,f18,m19,p20,t21
+ -,-,-,-,-,m22,-,-,-,-
+-,-,-,-,-,-,f23,-,-,-
+ -,-,-,-,-,-,h24,-,-,-
+-,-,-,-,-,-,-,t25,-,-
+ -,-,-,-,-,-,-,p26 -,-
+.
Added: trunk/server/trade.c
===================================================================
--- trunk/server/trade.c (rev 0)
+++ trunk/server/trade.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,448 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <string.h>
+#include "cost.h"
+#include "server.h"
+
+void trade_perform_maritime(Player * player,
+ gint ratio, Resource supply, Resource receive)
+{
+ Game *game = player->game;
+ Map *map = game->params->map;
+ gint check[NO_RESOURCE];
+ MaritimeInfo info;
+
+ if ((!game->rolled_dice) ||
+ ((player->build_list != NULL || game->bought_develop) &&
+ game->params->strict_trade)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR wrong-time\n");
+ return;
+ }
+
+ if (ratio < 2 || ratio > 4) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR trade bad-ratio\n");
+ return;
+ }
+
+ /* Now check that the trade can actually be performed.
+ */
+ map_maritime_info(map, &info, player->num);
+ switch (ratio) {
+ case 4:
+ if (player->assets[supply] < 4) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR maritime trade, not 4 resources\n");
+ return;
+ }
+ break;
+ case 3:
+ if (!info.any_resource || player->assets[supply] < 3) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR maritime trade, not 3 resources\n");
+ return;
+ }
+ break;
+ case 2:
+ if (!info.specific_resource[supply]
+ || player->assets[supply] < 2) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR maritime trade, not 2 resources\n");
+ return;
+ }
+ break;
+ }
+
+ memset(check, 0, sizeof(check));
+ check[receive] = 1;
+ if (!resource_available(player, check, NULL))
+ return;
+
+ game->bank_deck[supply] += ratio;
+ game->bank_deck[receive]--;
+ player->assets[supply] -= ratio;
+ player->assets[receive]++;
+
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION, LATEST_VERSION,
+ "maritime-trade %d supply %r receive %r\n",
+ ratio, supply, receive);
+}
+
+/* Trade initiating player has ended trading, wait for client to
+ * acknowledge.
+ */
+gboolean mode_wait_quote_exit(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+
+ sm_state_name(sm, "mode_wait_quote_exit");
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (sm_recv(sm, "domestic-quote exit")) {
+ sm_pop(sm);
+ return TRUE;
+ }
+ if (sm_recv(sm, "domestic-quote finish")) {
+ /* Trap race condition where initiating player and
+ * quoting player both finish at the same time.
+ */
+ sm_pop(sm);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean mode_domestic_quote(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ gint quote_num;
+ gint supply[NO_RESOURCE];
+ gint receive[NO_RESOURCE];
+
+ sm_state_name(sm, "mode_domestic_quote");
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (sm_recv(sm, "domestic-quote finish")) {
+ /* Player has rejected domestic trade - remove all
+ * quotes from that player
+ */
+ for (;;) {
+ QuoteInfo *quote;
+ quote = quotelist_find_domestic(game->quotes,
+ player->num, -1);
+ if (quote == NULL)
+ break;
+ player_broadcast(player, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION,
+ "domestic-quote delete %d\n",
+ quote->var.d.quote_num);
+ quotelist_delete(game->quotes, quote);
+ }
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION,
+ "domestic-quote finish\n");
+
+ sm_goto(sm, (StateFunc) mode_wait_quote_exit);
+ return TRUE;
+ }
+
+ if (sm_recv(sm, "domestic-quote delete %d", "e_num)) {
+ /* Player wants to retract a quote
+ */
+ QuoteInfo *quote;
+ quote = quotelist_find_domestic(game->quotes,
+ player->num, quote_num);
+ if (quote == NULL) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR quote already deleted\n");
+ return TRUE;
+ }
+ quotelist_delete(game->quotes, quote);
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION,
+ "domestic-quote delete %d\n", quote_num);
+ return TRUE;
+ }
+
+ if (sm_recv(sm, "domestic-quote quote %d supply %R receive %R",
+ "e_num, supply, receive)) {
+ /* Make sure that quoting party can satisfy the trade
+ */
+ if (!cost_can_afford(supply, player->assets)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR quote not enough resources\n");
+ return TRUE;
+ }
+ /* Make sure that the quote does not already exist
+ */
+ if (quotelist_find_domestic
+ (game->quotes, player->num, quote_num) != NULL) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "INFO duplicate quote\n");
+ return TRUE;
+ }
+
+ quotelist_add_domestic(game->quotes, player->num,
+ quote_num, supply, receive);
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION,
+ "domestic-quote quote %d supply %R receive %R\n",
+ quote_num, supply, receive);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Initiating player wants to end domestic trade
+ */
+void trade_finish_domestic(Player * player)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ GList *list;
+
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION, LATEST_VERSION,
+ "domestic-trade finish\n");
+ sm_pop(sm);
+ for (list = player_first_real(game);
+ list != NULL; list = player_next_real(list)) {
+ Player *scan = list->data;
+ if (scan != player && !player_is_viewer(game, scan->num))
+ sm_goto(scan->sm,
+ (StateFunc) mode_wait_quote_exit);
+ }
+ quotelist_free(&game->quotes);
+}
+
+void trade_accept_domestic(Player * player,
+ gint partner_num, gint quote_num,
+ gint * supply, gint * receive)
+{
+ Game *game = player->game;
+ QuoteInfo *quote;
+ Player *partner;
+
+ /* Check for valid trade scenario */
+ if ((!game->rolled_dice) ||
+ (((player->build_list != NULL) || (game->bought_develop)) &&
+ (game->params->strict_trade))) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR wrong-time\n");
+ return;
+ }
+
+ /* Initiating player accepted a quote
+ */
+ quote =
+ quotelist_find_domestic(game->quotes, partner_num, quote_num);
+ if (quote == NULL) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR quote not found\n");
+ return;
+ }
+ /* Make sure that both parties can satisfy the trade
+ */
+ if (!cost_can_afford(quote->var.d.receive, player->assets)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR quote cannot afford\n");
+ return;
+ }
+ partner = player_by_num(game, partner_num);
+ if (!cost_can_afford(quote->var.d.supply, partner->assets)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR quote partner cannot afford\n");
+ return;
+ }
+
+ /* Finally - we do the trade!
+ */
+ cost_refund(quote->var.d.receive, partner->assets);
+ cost_buy(quote->var.d.supply, partner->assets);
+ cost_refund(quote->var.d.supply, player->assets);
+ cost_buy(quote->var.d.receive, player->assets);
+
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION, LATEST_VERSION,
+ "domestic-trade accept player %d quote %d supply %R receive %R\n",
+ partner_num, quote_num, supply, receive);
+
+ /* Remove the quote just processed.
+ * The client should remove the quote too.
+ */
+ quotelist_delete(game->quotes, quote);
+ /* Remove all other quotes from the partner that are no
+ * longer valid
+ */
+ quote = quotelist_find_domestic(game->quotes, partner_num, -1);
+ while (quote != NULL && quote->var.d.player_num == partner_num) {
+ QuoteInfo *tmp = quote;
+
+ quote = quotelist_next(quote);
+ if (!cost_can_afford(tmp->var.d.supply, partner->assets)) {
+ player_broadcast(partner, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION,
+ "domestic-quote delete %d\n",
+ tmp->var.d.quote_num);
+ quotelist_delete(game->quotes, tmp);
+ }
+ }
+}
+
+static void process_call_domestic(Player * player, gint * supply,
+ gint * receive)
+{
+ Game *game = player->game;
+ GList *list;
+ gint i;
+
+ for (i = 0; i < NO_RESOURCE; i++) {
+ game->quote_supply[i] = supply[i];
+ game->quote_receive[i] = receive[i];
+ }
+
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION, LATEST_VERSION,
+ "domestic-trade call supply %R receive %R\n",
+ supply, receive);
+ /* make sure all the others are back in quote mode. They may have
+ * gone to monitor mode (after rejecting), but they should be able
+ * to reply to the new call */
+ for (list = player_first_real(game); list != NULL;
+ list = player_next_real(list)) {
+ Player *scan = list->data;
+ if (!player_is_viewer(game, scan->num) && scan != player) {
+ sm_pop(scan->sm);
+ sm_push(scan->sm, (StateFunc) mode_domestic_quote);
+ }
+ }
+}
+
+static void call_domestic(Player * player, gint * supply, gint * receive)
+{
+ Game *game = player->game;
+ Player *partner;
+ gint num_supply, num_receive;
+ gint idx;
+ QuoteInfo *quote;
+
+ /* Check that the player actually has the specified resources
+ */
+ num_supply = num_receive = 0;
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ if (supply[idx]) {
+ if (player->assets[idx] == 0) {
+ player_send(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "ERR not enough resources for this quote\n");
+ return;
+ }
+ num_supply++;
+ }
+ if (receive[idx] > 0)
+ ++num_receive;
+ }
+ if (num_supply == 0 && num_receive == 0) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR empty quote\n");
+ return;
+ }
+ quote = quotelist_first(game->quotes);
+ while (quote != NULL) {
+ QuoteInfo *curr = quote;
+
+ quote = quotelist_next(quote);
+ if (!curr->is_domestic)
+ continue;
+
+ /* Is the current quote valid?
+ */
+ for (idx = 0; idx < NO_RESOURCE; idx++) {
+ if (!receive[idx] && curr->var.d.supply[idx] != 0)
+ break;
+ if (!supply[idx] && curr->var.d.receive[idx] != 0)
+ break;
+ }
+ if (idx < NO_RESOURCE) {
+ partner =
+ player_by_num(game, curr->var.d.player_num);
+ player_broadcast(partner, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION,
+ "domestic-quote delete %d\n",
+ curr->var.d.quote_num);
+ quotelist_delete(game->quotes, curr);
+ }
+ }
+ process_call_domestic(player, supply, receive);
+}
+
+gboolean mode_domestic_initiate(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ gint partner_num;
+ gint quote_num;
+ gint ratio;
+ Resource supply_type;
+ Resource receive_type;
+ gint supply[NO_RESOURCE];
+ gint receive[NO_RESOURCE];
+
+ sm_state_name(sm, "mode_domestic_initiate");
+ if (event != SM_RECV)
+ return FALSE;
+
+ if (sm_recv(sm, "maritime-trade %d supply %r receive %r",
+ &ratio, &supply_type, &receive_type)) {
+ trade_perform_maritime(player, ratio, supply_type,
+ receive_type);
+ return TRUE;
+ }
+
+ if (sm_recv(sm, "domestic-trade finish")) {
+ trade_finish_domestic(player);
+ return TRUE;
+ }
+
+ if (sm_recv
+ (sm,
+ "domestic-trade accept player %d quote %d supply %R receive %R",
+ &partner_num, "e_num, supply, receive)) {
+ trade_accept_domestic(player, partner_num, quote_num,
+ supply, receive);
+ return TRUE;
+ }
+
+ if (sm_recv(sm, "domestic-trade call supply %R receive %R",
+ supply, receive)) {
+ if (!game->params->domestic_trade)
+ return FALSE;
+ call_domestic(player, supply, receive);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void trade_begin_domestic(Player * player, gint * supply, gint * receive)
+{
+ Game *game = player->game;
+ GList *list;
+
+ sm_push(player->sm, (StateFunc) mode_domestic_initiate);
+ quotelist_new(&game->quotes);
+
+ /* push all others to quote mode. process_call_domestic pops and
+ * repushes them all, so this is needed to keep the state stack
+ * from corrupting. */
+ for (list = player_first_real(game); list != NULL;
+ list = player_next_real(list)) {
+ Player *scan = list->data;
+ if (!player_is_viewer(game, scan->num) && scan != player)
+ sm_push(scan->sm, (StateFunc) mode_domestic_quote);
+ }
+
+ process_call_domestic(player, supply, receive);
+}
Added: trunk/server/turn.c
===================================================================
--- trunk/server/turn.c (rev 0)
+++ trunk/server/turn.c 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,619 @@
+/* Pioneers - Implementation of the excellent Settlers of Catan board game.
+ * Go buy a copy.
+ *
+ * Copyright (C) 1999 Dave Cole
+ * Copyright (C) 2003 Bas Wijnen <shevek at fmf.nl>
+ * Copyright (C) 2006 Roland Clobus <rclobus at bigfoot.com>
+ *
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include "buildrec.h"
+#include "cost.h"
+#include "server.h"
+
+static void build_add(Player * player, BuildType type, gint x, gint y,
+ gint pos)
+{
+ Game *game = player->game;
+ Map *map = game->params->map;
+ Points *special_points;
+
+ if (!game->rolled_dice) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR roll-dice\n");
+ return;
+ }
+
+ /* Add settlement/city/road
+ */
+ if (type == BUILD_ROAD) {
+ /* Building a road, make sure it is next to a
+ * settlement/city/road
+ */
+ if (!map_road_vacant(map, x, y, pos)
+ || !map_road_connect_ok(map, player->num, x, y, pos)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+ /* Make sure the player can afford the road
+ */
+ if (!cost_can_afford(cost_road(), player->assets)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-expensive\n");
+ return;
+ }
+ /* Make sure that there are some roads left to use!
+ */
+ if (player->num_roads ==
+ game->params->num_build_type[BUILD_ROAD]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many road\n");
+ return;
+ }
+ edge_add(player, BUILD_ROAD, x, y, pos, TRUE);
+ return;
+ }
+
+ if (type == BUILD_BRIDGE) {
+ /* Building a bridge, make sure it is next to a
+ * settlement/city/road
+ */
+ if (!map_road_vacant(map, x, y, pos)
+ || !map_bridge_connect_ok(map, player->num, x, y, pos)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+ /* Make sure the player can afford the bridge
+ */
+ if (!cost_can_afford(cost_bridge(), player->assets)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-expensive\n");
+ return;
+ }
+ /* Make sure that there are some roads left to use!
+ */
+ if (player->num_bridges ==
+ game->params->num_build_type[BUILD_BRIDGE]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many bridge\n");
+ return;
+ }
+ edge_add(player, BUILD_BRIDGE, x, y, pos, TRUE);
+ return;
+ }
+
+ if (type == BUILD_SHIP) {
+ /* Building a ship, make sure it is next to a
+ * settlement/city/ship
+ */
+ if (!map_ship_vacant(map, x, y, pos)
+ || !map_ship_connect_ok(map, player->num, x, y, pos)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+ /* Make sure the player can afford the ship
+ */
+ if (!cost_can_afford(cost_ship(), player->assets)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-expensive\n");
+ return;
+ }
+ /* Make sure that there are some roads left to use!
+ */
+ if (player->num_ships ==
+ game->params->num_build_type[BUILD_SHIP]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many ship\n");
+ return;
+ }
+ edge_add(player, BUILD_SHIP, x, y, pos, TRUE);
+ return;
+ }
+
+ if (type == BUILD_CITY_WALL) {
+ if (!can_city_wall_be_built(map_node(map, x, y, pos),
+ player->num)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+ /* Make sure that there are some city walls left to use!
+ */
+ if (player->num_city_walls ==
+ game->params->num_build_type[BUILD_CITY_WALL]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many city wall\n");
+ return;
+ }
+ if (!cost_can_afford(cost_city_wall(), player->assets)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-expensive\n");
+ return;
+ }
+ node_add(player, type, x, y, pos, TRUE, NULL);
+ return;
+ }
+
+ /* Build the settlement/city
+ */
+ if (!map_building_vacant(map, type, x, y, pos)
+ || !map_building_spacing_ok(map, player->num, type, x, y, pos)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+
+ if (type == BUILD_CITY
+ && can_settlement_be_upgraded(map_node(map, x, y, pos),
+ player->num)) {
+ /* Make sure that there are some cities left to use!
+ */
+ if (player->num_cities ==
+ game->params->num_build_type[BUILD_CITY]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many city\n");
+ return;
+ }
+ if (!cost_can_afford(cost_upgrade_settlement(),
+ player->assets)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-expensive\n");
+ return;
+ }
+ } else {
+ /* New building: make sure it connects to a road
+ */
+ if (!map_building_connect_ok
+ (map, player->num, type, x, y, pos)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+ /* Make sure that there are some settlements left to use!
+ * Also when building a city, there must be an intermediate
+ * settlement.
+ */
+ if (player->num_settlements ==
+ game->params->num_build_type[BUILD_SETTLEMENT]) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR too-many settlement\n");
+ return;
+ }
+ /* Make sure the player can afford the building
+ */
+ if (type == BUILD_SETTLEMENT) {
+ if (!cost_can_afford
+ (cost_settlement(), player->assets)) {
+ player_send(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "ERR too-expensive\n");
+ return;
+ }
+ } else {
+ /* Make sure that there are some cities left to use!
+ */
+ if (player->num_cities ==
+ game->params->num_build_type[BUILD_CITY]) {
+ player_send(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "ERR too-many city\n");
+ return;
+ }
+ if (!cost_can_afford(cost_city(), player->assets)) {
+ player_send(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "ERR too-expensive\n");
+ return;
+ }
+ }
+ }
+
+ special_points = NULL;
+ if (game->params->island_discovery_bonus != NULL) {
+ if (!map_is_island_discovered
+ (map, map_node(map, x, y, pos), player->num)) {
+ gboolean first_island;
+ gint points;
+
+ first_island = (player->islands_discovered == 0);
+ /* Use the last entry in island_discovery_bonus,
+ * or the current island
+ */
+ points =
+ g_array_index(game->params->
+ island_discovery_bonus, gint,
+ MIN(game->params->
+ island_discovery_bonus->len -
+ 1,
+ player->islands_discovered));
+
+ if (points != 0)
+ special_points =
+ points_new(player->
+ special_points_next_id++,
+ first_island ?
+ N_("Island Discovery Bonus")
+ :
+ N_
+ ("Additional Island Bonus"),
+ points);
+ player->islands_discovered++;
+ }
+ }
+ node_add(player, type, x, y, pos, TRUE, special_points);
+
+}
+
+static void build_remove(Player * player)
+{
+ /* Remove the settlement/road we just built
+ */
+ if (!perform_undo(player))
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-undo\n");
+}
+
+static void build_move(Player * player, gint sx, gint sy, gint spos,
+ gint dx, gint dy, gint dpos)
+{
+ Game *game = player->game;
+ Map *map = game->params->map;
+ Edge *from = map_edge(map, sx, sy, spos),
+ *to = map_edge(map, dx, dy, dpos);
+ BuildRec *rec;
+
+ /* Allow only one move per turn */
+ if (map->has_moved_ship) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR already-moved\n");
+ return;
+ }
+
+ /* Check if the ship is allowed to move away */
+ if (from->owner != player->num || from->type != BUILD_SHIP
+ || to->owner >= 0
+ || !can_ship_be_moved(map_edge(map, sx, sy, spos),
+ player->num)) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+
+ if (map->pirate_hex != NULL) {
+ gint idx;
+ /* check that the pirate is not on the from hexes */
+ for (idx = 0; idx < G_N_ELEMENTS(from->hexes); ++idx) {
+ if (map->pirate_hex == from->hexes[idx]) {
+ player_send(player, FIRST_VERSION,
+ LATEST_VERSION,
+ "ERR has-pirate\n");
+ return;
+ }
+ }
+ /* checking of destination for pirate is done in
+ * can_ship_be_built */
+ }
+
+ /* Move it away */
+ from->owner = -1;
+ from->type = BUILD_NONE;
+
+ /* Check if it is allowed to move to the other place */
+ if ((sx == dx && sy == dy && spos == dpos)
+ || !can_ship_be_built(to, player->num)) {
+ from->owner = player->num;
+ from->type = BUILD_SHIP;
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR bad-pos\n");
+ return;
+ }
+
+ /* everything is fine, tell everybode the ship has moved */
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION, LATEST_VERSION,
+ "move %d %d %d %d %d %d\n", sx, sy, spos, dx, dy,
+ dpos);
+
+ /* put the move in the undo information */
+ rec = buildrec_new(BUILD_MOVE_SHIP, dx, dy, dpos);
+ rec->cost = NULL;
+ rec->prev_x = sx;
+ rec->prev_y = sy;
+ rec->prev_pos = spos;
+ rec->longest_road =
+ game->longest_road ? game->longest_road->num : -1;
+ player->build_list = g_list_append(player->build_list, rec);
+ map->has_moved_ship = TRUE;
+
+ /* check the longest road while the ship is moving */
+ check_longest_road(game, FALSE);
+
+ /* administrate the arrival of the ship */
+ to->owner = player->num;
+ to->type = BUILD_SHIP;
+
+ /* check the longest road again */
+ check_longest_road(game, FALSE);
+}
+
+typedef struct {
+ Game *game;
+ int roll;
+} GameRoll;
+
+static gboolean distribute_resources(G_GNUC_UNUSED Map * map, Hex * hex,
+ GameRoll * data)
+{
+ int idx;
+
+ if (hex->roll != data->roll || hex->robber)
+ /* return false so the traverse function continues */
+ return FALSE;
+
+ for (idx = 0; idx < G_N_ELEMENTS(hex->nodes); idx++) {
+ Node *node = hex->nodes[idx];
+ Player *player;
+ int num;
+
+ if (node->type == BUILD_NONE)
+ continue;
+ player = player_by_num(data->game, node->owner);
+ if (player != NULL) {
+ num = (node->type == BUILD_CITY) ? 2 : 1;
+ if (hex->terrain == GOLD_TERRAIN)
+ player->gold += num;
+ else
+ player->assets[hex->terrain] += num;
+ } else {
+ /* This should be fixed at some point. */
+ log_message(MSG_ERROR,
+ _
+ ("Tried to assign resources to NULL player.\n"));
+ }
+ }
+
+ /* return false so the traverse function continues */
+ return FALSE;
+}
+
+void check_victory(Player * player)
+{
+ Game *game = player->game;
+ GList *list;
+ gint points;
+
+ points = player->num_settlements
+ + player->num_cities * 2 + player->develop_points;
+
+ if (game->longest_road == player)
+ points += 2;
+ if (game->largest_army == player)
+ points += 2;
+
+ list = player->special_points;
+ while (list) {
+ Points *point = list->data;
+ points += point->points;
+ list = g_list_next(list);
+ }
+
+ if (points >= game->params->victory_points) {
+ GList *list;
+
+ player_broadcast(player, PB_ALL, FIRST_VERSION,
+ LATEST_VERSION, "won with %d\n", points);
+ game->is_game_over = TRUE;
+ /* Set all state machines to idle, to make sure nothing
+ * happens. */
+ for (list = player_first_real(game); list != NULL;
+ list = player_next_real(list)) {
+ Player *scan = list->data;
+ sm_pop_all_and_goto(scan->sm,
+ (StateFunc) mode_idle);
+ }
+ meta_unregister();
+
+ game_is_over(game);
+ }
+}
+
+/* Handle all actions that a player may perform in a turn
+ */
+gboolean mode_turn(Player * player, gint event)
+{
+ StateMachine *sm = player->sm;
+ Game *game = player->game;
+ Map *map = game->params->map;
+ BuildType build_type;
+ DevelType devel_type;
+ gint x, y, pos;
+ gint quote_num, partner_num, idx, ratio;
+ Resource supply_type, receive_type;
+ gint supply[NO_RESOURCE], receive[NO_RESOURCE];
+ gint sx, sy, spos, dx, dy, dpos;
+
+ sm_state_name(sm, "mode_turn");
+ if (event != SM_RECV)
+ return FALSE;
+ if (sm_recv(sm, "roll")) {
+ GameRoll data;
+ gint roll;
+
+ if (game->rolled_dice) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR already-rolled\n");
+ return TRUE;
+ }
+
+ /* roll the dice until we like it */
+ while (TRUE) {
+ game->die1 = get_rand(6) + 1;
+ game->die2 = get_rand(6) + 1;
+ roll = game->die1 + game->die2;
+ game->rolled_dice = TRUE;
+
+ /* sevens_rule == 1: reroll first two turns */
+ if (game->params->sevens_rule == 1)
+ if (roll == 7 && game->curr_turn <= 2)
+ continue;
+ /* sevens_rule == 2: reroll all sevens */
+ if (game->params->sevens_rule == 2)
+ if (roll == 7)
+ continue;
+ /* sevens_rule == 0: don't reroll anything */
+ break;
+ }
+
+ /* let people know what we rolled */
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION,
+ LATEST_VERSION, "rolled %d %d\n",
+ game->die1, game->die2);
+
+ if (roll == 7) {
+ /* Find all players with more than 7 cards -
+ * they must discard half (rounded down)
+ */
+ discard_resources(game);
+ /* there are no resources to distribute on a 7 */
+ return TRUE;
+ }
+ resource_start(game);
+ data.game = game;
+ data.roll = roll;
+ map_traverse(map, (HexFunc) distribute_resources, &data);
+ /* distribute resources and gold (includes resource_end) */
+ distribute_first(list_from_player(player));
+ return TRUE;
+ }
+ /* try to end a turn */
+ if (sm_recv(sm, "done")) {
+ if (!game->rolled_dice) {
+ player_send(player, FIRST_VERSION, LATEST_VERSION,
+ "ERR roll-dice\n");
+ return TRUE;
+ }
+ /* Ok, finish turn */
+ player_send(player, FIRST_VERSION, LATEST_VERSION, "OK\n");
+ /* pop the state machine back to idle */
+ sm_pop(sm);
+ turn_next_player(game);
+ return TRUE;
+ }
+ if (sm_recv(sm, "buy-develop")) {
+ develop_buy(player);
+ return TRUE;
+ }
+ if (sm_recv(sm, "play-develop %d", &idx, &devel_type)) {
+ develop_play(player, idx);
+ check_victory(player);
+ return TRUE;
+ }
+ if (sm_recv(sm, "maritime-trade %d supply %r receive %r",
+ &ratio, &supply_type, &receive_type)) {
+ trade_perform_maritime(player, ratio, supply_type,
+ receive_type);
+ return TRUE;
+ }
+ if (sm_recv(sm, "domestic-trade call supply %R receive %R",
+ supply, receive)) {
+ if (!game->params->domestic_trade)
+ return FALSE;
+ trade_begin_domestic(player, supply, receive);
+ return TRUE;
+ }
+ if (sm_recv
+ (sm,
+ "domestic-trade accept player %d quote %d supply %R receive %R",
+ &partner_num, "e_num, supply, receive)) {
+ trade_accept_domestic(player, partner_num, quote_num,
+ supply, receive);
+ return TRUE;
+ }
+ if (sm_recv(sm, "build %B %d %d %d", &build_type, &x, &y, &pos)) {
+ build_add(player, build_type, x, y, pos);
+ check_victory(player);
+ return TRUE;
+ }
+ if (sm_recv
+ (sm, "move %d %d %d %d %d %d", &sx, &sy, &spos, &dx, &dy,
+ &dpos)) {
+ build_move(player, sx, sy, spos, dx, dy, dpos);
+ check_victory(player);
+ return TRUE;
+ }
+ if (sm_recv(sm, "undo")) {
+ build_remove(player);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Player should be idle - I will tell them when to do something
+ */
+gboolean mode_idle(Player * player, G_GNUC_UNUSED gint event)
+{
+ StateMachine *sm = player->sm;
+ sm_state_name(sm, "mode_idle");
+ return FALSE;
+}
+
+void turn_next_player(Game * game)
+{
+ Player *player = NULL;
+ GList *list = NULL;
+
+ /* the first time this is called there is no curr_player yet */
+ if (game->curr_player >= 0) {
+ player = player_by_num(game, game->curr_player);
+ game->curr_player = -1;
+ g_assert(player != NULL);
+ list = list_from_player(player);
+ }
+
+ do {
+ /* next player */
+ if (list)
+ list = player_next_real(list);
+ /* See if it's the first player's turn again */
+ if (list == NULL) {
+ list = player_first_real(game);
+ game->curr_turn++;
+ }
+ /* sanity check */
+ g_assert(list != NULL && list->data != NULL);
+ player = list->data;
+ /* disconnected players don't take turns */
+ } while (player->disconnected);
+
+ /* reset variables */
+ game->curr_player = player->num;
+ game->rolled_dice = FALSE;
+ game->played_develop = FALSE;
+ game->bought_develop = FALSE;
+ player->build_list = buildrec_free(player->build_list);
+ game->params->map->has_moved_ship = FALSE;
+
+ /* tell everyone what's happening */
+ player_broadcast(player, PB_RESPOND, FIRST_VERSION, LATEST_VERSION,
+ "turn %d\n", game->curr_turn);
+
+ /* put the player in the right state */
+ sm_push(player->sm, (StateFunc) mode_turn);
+}
Added: trunk/server/x.game
===================================================================
--- trunk/server/x.game (rev 0)
+++ trunk/server/x.game 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,33 @@
+title X Marks the Spot
+domestic-trade
+num-players 3
+victory-points 18
+num-roads 30
+num-ships 20
+num-settlements 7
+num-cities 5
+resource-count 24
+develop-road 4
+develop-monopoly 2
+develop-plenty 1
+develop-chapel 1
+develop-university 1
+develop-governor 1
+develop-library 1
+develop-market 1
+develop-soldier 15
+use-pirate
+
+chits 4,9,3,6,6,10,2,5,11,8,9,8,4,12,10,4,9,3,6,6,4,9,3,6,6,10,2,5,11,8,9,8,4,12,10,4,9,3,6,6,8,4,12,10,4,9,3,6,6
+map
+s,s,s,s,s,s,s,s,s,s,s,s
+ s,p0,t1,s,s,h2,t3,s,s,s,s,s
+s,t4,t5,s,s,h6,h7,p8,p9,f10,s,s
+ s,t11,p12,s,s,s,p13,f14,f15,m16,s,s
+s,p17,p18,s,f19,p20,p21,h22,h23,m24,s,s
+ s,m25,m26,s,f27,f28,p29,s,s,f30,m31,s
+s,m49,d32,h33,h34,m35,m36,m37,s,s,s,s
+ s,m38,h39,h40,f41,s,s,f42,t43,t44,s,s
+s,s,s,p45,p46,s,s,t47,t48,s,s,s
+ s,s,s,s,s,s,s,s,s,s,s
+.
Added: trunk/xmldocs.make
===================================================================
--- trunk/xmldocs.make (rev 0)
+++ trunk/xmldocs.make 2007-12-24 20:30:29 UTC (rev 2)
@@ -0,0 +1,95 @@
+#
+# No modifications of this Makefile should be necessary.
+#
+# To use this template:
+# 1) Define: figdir, docname, lang, omffile, and entities in
+# your Makefile.am file for each document directory,
+# although figdir, omffile, and entities may be empty
+# 2) Make sure the Makefile in (1) also includes
+# "include $(top_srcdir)/xmldocs.make" and
+# "dist-hook: app-dist-hook".
+# 3) Optionally define 'entities' to hold xml entities which
+# you would also like installed
+# 4) Figures must go under $(figdir)/ and be in PNG format
+# 5) You should only have one document per directory
+# 6) Note that the figure directory, $(figdir)/, should not have its
+# own Makefile since this Makefile installs those figures.
+#
+# example Makefile.am:
+# figdir = figures
+# docname = scrollkeeper-manual
+# lang = C
+# omffile=scrollkeeper-manual-C.omf
+# entities = fdl.xml
+# include $(top_srcdir)/xmldocs.make
+# dist-hook: app-dist-hook
+#
+# About this file:
+# This file was taken from scrollkeeper_example2, a package illustrating
+# how to install documentation and OMF files for use with ScrollKeeper
+# 0.3.x and 0.4.x. For more information, see:
+# http://scrollkeeper.sourceforge.net/
+# Version: 0.1.2 (last updated: March 20, 2002)
+#
+
+
+# ********** Begin of section some packagers may need to modify **********
+# This variable (docdir) specifies where the documents should be installed.
+# This default value should work for most packages.
+docdir = $(datadir)/gnome/help/$(docname)/$(lang)
+
+# ********** You should not have to edit below this line **********
+xml_files = $(entities) $(docname).xml
+
+EXTRA_DIST = $(xml_files) $(omffile)
+CLEANFILES = omf_timestamp
+
+include $(top_srcdir)/omf.make
+
+all: omf
+
+$(docname).xml: $(entities)
+ -ourdir=`pwd`; \
+ cd $(srcdir); \
+ cp $(entities) $$ourdir
+
+app-dist-hook:
+ if test "$(figdir)"; then \
+ $(mkinstalldirs) $(distdir)/$(figdir); \
+ for file in $(srcdir)/$(figdir)/*.png; do \
+ basefile=`echo $$file | sed -e 's,^.*/,,'`; \
+ $(INSTALL_DATA) $$file $(distdir)/$(figdir)/$$basefile; \
+ done \
+ fi
+
+install-data-local: omf
+ $(mkinstalldirs) $(DESTDIR)$(docdir)
+ for file in $(xml_files); do \
+ cp $(srcdir)/$$file $(DESTDIR)$(docdir); \
+ done
+ if test "$(figdir)"; then \
+ $(mkinstalldirs) $(DESTDIR)$(docdir)/$(figdir); \
+ for file in $(srcdir)/$(figdir)/*.png; do \
+ basefile=`echo $$file | sed -e 's,^.*/,,'`; \
+ $(INSTALL_DATA) $$file $(DESTDIR)$(docdir)/$(figdir)/$$basefile; \
+ done \
+ fi
+
+install-data-hook: install-data-hook-omf
+
+uninstall-local: uninstall-local-doc uninstall-local-omf
+
+uninstall-local-doc:
+ -if test "$(figdir)"; then \
+ for file in $(srcdir)/$(figdir)/*.png; do \
+ basefile=`echo $$file | sed -e 's,^.*/,,'`; \
+ rm -f $(DESTDIR)$(docdir)/$(figdir)/$$basefile; \
+ done; \
+ rmdir $(DESTDIR)$(docdir)/$(figdir); \
+ fi
+ -for file in $(xml_files); do \
+ rm -f $(DESTDIR)$(docdir)/$$file; \
+ done
+ -rmdir $(DESTDIR)$(docdir)
+
+clean-local: clean-local-omf
More information about the Pioneers-commits
mailing list