From: Aymargeddon Team <benni@aymargeddon.de> Date: Sun, 26 Aug 2012 18:51:52 +0000 (+0200) Subject: Initial Import from the old project. X-Git-Url: http://aymargeddon.de/gitweb/?a=commitdiff_plain;h=8f037c123df00f587fda88e656579bcf17c8e66b;p=aymargeddon%2Fcurrent.git Initial Import from the old project. --- 8f037c123df00f587fda88e656579bcf17c8e66b diff --git a/CREDITS b/CREDITS new file mode 100644 index 0000000..384758a --- /dev/null +++ b/CREDITS @@ -0,0 +1,40 @@ +We have to give credits to the following people! + +Game Design and Main Programming + + Benni Bärmann + Dominikus Scherkl + +Additional Programming + + Jens Kurlanda + Olaf Ohlenmacher + +Graphics + + Christine Bauer + Dominikus Scherkl + +Rule Proofreading + + Frauke Distelrath + +Game Testing + + Benni Bärmann + Christine Bauer + Nicolas Diederichs + Olaf Ohlenmacher + Jens Kleinschmidt + Jens Kurlanda + Dominikus Scherkl + Nicolas Schiller + Andreas Scholz + Ralf Zessin + ... + +Aymargeddon is based on the pbem-game Ragnaroek which was based on the +board game with the same name. Both games where designed by Benni +Bärmann (of course with many help of others - some of them mentioned +here above). + diff --git a/DONTDO b/DONTDO new file mode 100644 index 0000000..6238b82 --- /dev/null +++ b/DONTDO @@ -0,0 +1,113 @@ +Hier stehen Ideen, die bei der Entwicklung von Aymargeddon aufgekommen +sind und gegen die wir uns entschiedne haben, weil sie das Spiel zu +kompliziert machen würden. + +Trotzdem sind einige davon Wert, aufgehoben zu werden, weil sie +vielleicht mal für ein zukünftiges auf Aymargeddon basierendes Spiel +brauchbar sind. + +Propheten +--------- + +Propheten sind Erdlingseinheiten, die: + + - übers Wasser gehen können + - aus einem Priester erzeugt werden, wenn sie einen Bergtempel errichten + und dabei ganz alleine sind im Feld. + => Es gibt nur maximal zwei (drei) Pro Gott pro Spiel. + - Kampfstärke -2 + - MOVE_MNT: Sie können den eigenen Berg mit den meisten Priestern + (ab 3 * FORTUNE) zu sich hin bewegen. Die Priester bleiben zurück. + Der Tempel bleibt erhalten + +Spione +------ + +Spione sind Erdlingseinheiten, die + + - Archen klauen können + - sich unsichtbar auf fremdem Territorium aufhalten können + - keine Kämpfe auslösen + - Schnelligkeit und Kampfkraft wie Krieger + - feindliche Spione mit gewisser Wahrscheinlichkeit aufdecken können + wenn sie ein Feld betreten => löst Kampf aus. + - nur ihr direktes Feld sehen, nicht die Nachbarfelder + - den Widerstand in besetzten Heimatstädten organisieren: + - die produzierten Krieger alle zu Spionen umwandeln bevor sie + kämpfen. + - von Erdlingen aus einem oder mehreren + Helden und/oder Kriegern erzeugt werden + - wenn aus Helden: sterben immer noch für einen Gott + - wenn aus Kriegern: aus mehreren, sonst zu billig + - die DIE_ORDER des Gegners überschreiben mit der eigenen + (Assasinenfertigkeit) + + - Problem: darf niemals send_message_to_field() benutzen + - Problem: Sichtrechte. Spioninfos sollten nicht an Alliierte + weitergegeben werden. + +weitere Ideen: +-------------- + +- Strassen: nur auf Stadt und Land (beschleunigen Bewegung _in_ das +Feld rein), Kosten: sehr lange Bauzeit für einen (oder mehrere) +Krieger. Anzahl Krieger, die bauen beschleunigt die Bauzeit anteilig. + +- ebenso für Burgen: gibt Verteidigungsbonus +2. + +- Artefakte: siehe altes Ragnaroek (erstnochmal da nachlesen) + +- Anführer: Geben Bonus pro Kämpfer wie Avatare aber bis max. +10. +Erdlingseinheit. Kann nur aus einem Held und nur in der Heimatstadt +ausgebildet werden. Ausbildung dauert sehr lange. Max. 1 Anführer pro +Feld wirksam. Anführer haben keine Bindung mehr zu einem Gott und +sterben immer als letztes. Geschwindigkeit ist die eines Kriegers. + +- zwei Sorten Avatare. Die einen blockieren, die anderen helfen. (Idee +von Nicki) oder unterschiedilch starke Avatare die bestimmte +Fähigkeiten erst mit ihrer Stärke kriegen oder auch wieder verlieren. +Implementierung wäre durch Ausnahme in unify_mobiles() (nur noch +Individuen) und Verwendung von COUNT für die Stärke möglich. + +- Hurrican: Zerstört Tempel (auch Bergtempel!), versenkt Archen, +verhindert Bewegung. Bewegt sich selbst zufällig. Wird wie Seuchen +durch Priester "geheilt" ansonsten wütet er ewig weiter. Archen in +Nachbarfeldern eines Hurricans bewegen sich mit 1ZE. + + +zusätzliche Ebenen +------------------ + +Man könnte zusätzlich zu den Ebenen Gott/Erdling noch weitere +einführen, das macht natürlich die Balance enorm schwierig. Eine neue +Ebene muss auf alle anderen angewiesen sein und umgekehrt. Jede Ebene +erhöht die Anzahl der Sieger. + +Beispiel: + +Ebene Volk (Erdling wird umbenannt in Herrscher) + +- hat Bauern, Handwerker und Händler + +- Völker können koexistieren im selben Feld + +- Volksreligiosität verbreitet sich direkt in Reaktion auf +Götteraktionen (positive und negative) und ähnlich wie Seuchen. +Gläubiges Volk gibt Mana, egal wo. + +- Erdlinge brauchen Korn, das Bauern produzieren und Händler +transportieren sowie Dinge, die Handwerker produzieren und Händler +transportieren. + +- Händler bewegen sich so schnell wie Krieger. Bauern gar nicht +(ausser durch Vermehrung). + +- Gewonnen hat, wer am Schluss am meisten Volk hat. + +- Volk vermehrt sich im Frieden und verringert sich bei Krieg und +Seuche. Bei Flut wandern sie in Nachbarfelder. + +- Bauern auf Ebenen produzieren Korn. Bauern in Städten können zu +Händlern werden. Händler auf Landfeldern zu Bauern. + +- ... so oder so ähnlich diff --git a/TODO b/TODO new file mode 100644 index 0000000..610f112 --- /dev/null +++ b/TODO @@ -0,0 +1,3 @@ +Diese Datei wird inzwischen im Wiki gepflegt: + +http://www.aymargeddon.de/wiki/index.php/TODO diff --git a/agrep b/agrep new file mode 100644 index 0000000..768c84a --- /dev/null +++ b/agrep @@ -0,0 +1,3 @@ +#!/bin/sh + +grep $1 src/*.pl src/*.pm src/FROGS/*.pm html/*.epl diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..9d126e1 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,116 @@ +# Makefile for Aymargeddon documentation +# TODO: BUG: macht immer alles (liegt an +* nicht im target) + +LYX2HTML = lyx --export html +LYX2PDF = lyx --export pdf +FICK2DEATH = fig2dev + +INSTALL_SERVER = aymargeddon.de +INSTALL_DIR = /home/benni/aymargeddon_current/doc/ + +DIRS = +FILES_BIN = +FILES_LIB = +FILES_DOC = Regeln.lyx Techdoc.lyx ay_ein_hex.fig +FILES_MISC = +FILES = Makefile $(FILES_IN) $(FILES_DOC) $(FILES_MISC) +FILES_OUT = ay_ein_hex.eps Regeln.pdf \ + Regeln.html Techdoc.pdf Techdoc.html $(FILES_MISC) + + +all: $(FILES_OUT) + +#Regeln.html: Regeln.tex +# $(LATEX2HTML) $(LATEX2HTML_OPT) < Regeln.tex > Regeln.html +# +#Techdoc.html: Techdoc.tex +# $(LATEX2HTML) $(LATEX2HTML_OPT) < Techdoc.tex > Techdoc.html + +clean: + rm -f $(FILES_OUT) + rm -rf Regeln + rm -rf Techdoc + rm -rf auto + rm -f *.aux + rm -f *.log + rm -f *.ps + rm -f *.dvi + rm -f *~ + rm -f *.toc + rm -f *.png + rm -f *.ps.gz + rm -f *.tex + rm -f +* + +realclean: clean + + + +#release: clean have_to_make +# @if [ -z "$(RELDIR)" ] ; then \ +# echo "Sorry, release directory is not set!" 1>&2 ; \ +# exit 1 ; \ +# fi ;\ +# if [ ! -d $(RELDIR) ] ; then mkdir $(RELDIR) ; fi ; \ +# tar cf - $(FILES) | \ +# ( cd $(RELDIR) ; tar xf - ) +# for i in $(DIRS) ; do \ +# ( cd $$i ; \ +# $(MAKE) RELDIR=../$(RELDIR)/$$i $@ ) ; \ +# done + +install: all + +# hier muss dann das angepasste push-script hin + +# @if [ "X$(RELEASE)" = "X" ] ; then \ +# echo "Sorry, this isn't released source" 1>&2 ; \ +# exit 1 ; \ +# fi ;\ +# for i in $(INSTALLDIRS) ; do \ +# if [ ! -d $$i ] ; then mkdir -p $$i ; fi ; \ +# done ;\ +# for i in $(FILES_DOC) ; do \ +# cp $$i $(DOCDIR)/$$i ; \ +# chmod 555 $(DOCDIR)/$$i ; \ +# chown bin:bin $(DOCDIR)/$$i ; \ +# echo "Installed $(DOCDIR)/$$i" ; \ +# done +# for i in $(DIRS) ; do \ +# ( cd $$i ; ${MAKE} RELEASE=$$RELEASE PREFIX=$(PREFIX) install ) ; \ +# done + +# have_to_make: + +.SUFFIXES: +.SUFFIXES: .pdf .lyx .eps .fig .html + +.fig.eps: + $(FICK2DEATH) -L ps $(FICK2DEATH_OPT) $< +$@ + +# TeX to DVI +#.tex.dvi: +# $(LATEX) $< < /dev/null > /dev/null 2>&1 +# $(LATEX) $< < /dev/null > /dev/null 2>&1 + +# DVI to PS +#.dvi.ps: +# $(DVIPS) -o $@ $< + +# PS to PDF +#.ps.pdf: +# $(PS2PDF) $< $@ + +# LyX to TeX +#.lyx.tex: +# $(LYX2LATEX) $< > /dev/null 2>&1 && mv -f $@ +$@ + +# LyX to PDF +.lyx.pdf: + $(LYX2PDF) $< > /dev/null 2>&1 && mv -f $@ +$@ + +# LyX to HTML +.lyx.html: + $(LYX2HTML) $< > /dev/null 2>&1 && mv -f $@ +$@ + + diff --git a/doc/README b/doc/README new file mode 100644 index 0000000..486fcb0 --- /dev/null +++ b/doc/README @@ -0,0 +1,11 @@ +german below! + +There is currently no rules or other documentation in english. use the +sourcecode or ask at the mailinglist, if you want to know something. + +------------------------ + +Die Dateien in diesem Verzeichnis sind nicht auf dem neuesten Stand. +Die Regeln werden inzwischen im Wiki gepflegt: + +http://www.aymargeddon.de/wiki/index.php/Regeln diff --git a/doc/Regeln.lyx b/doc/Regeln.lyx new file mode 100644 index 0000000..d52001d --- /dev/null +++ b/doc/Regeln.lyx @@ -0,0 +1,2397 @@ +#LyX 1.3 created this file. For more info see http://www.lyx.org/ +\lyxformat 221 +\textclass article +\language german +\inputencoding latin1 +\fontscheme default +\graphics default +\paperfontsize 11 +\spacing single +\papersize a4paper +\paperpackage a4 +\use_geometry 0 +\use_amsmath 0 +\use_natbib 0 +\use_numerical_citations 0 +\paperorientation portrait +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip bigskip +\quotes_language polish +\quotes_times 2 +\papercolumns 1 +\papersides 1 +\paperpagestyle default + +\layout Title + +Die letzten Tage von Aymargeddon +\layout Author + +Aymargeddon Development Team +\layout Date + +17. + April 2005 +\layout Standard + + +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +tableofcontents +\backslash +newpage +\end_inset + + +\layout Section + +Einleitung +\layout Quotation + + +\emph on + +\begin_inset Quotes pld +\end_inset + +Es ist nicht leicht, ein Gott zu sein +\begin_inset Quotes prd +\end_inset + + (Titel eines Buches der Brüder Strugatzkij) +\layout Standard + +Während in den himmlischen Sphären der entscheidende Kampf zwischen Gut + und Böse ausgefochten wird, kämpfen auf Erden Elfen gegen Zwerge, Menschen + gegen Halblinge und jeder gegen jeden. + Soweit das Fantasy-Klischee. + Doch jetzt kommen wir zum Spiel: +\layout Standard + + +\series bold +\shape smallcaps +Die letzten Tage von Aymargeddon +\series default +\shape default + wird von mindestens acht Spielern gespielt. + Höchstens ein Drittel der Spieler übernimmt die Aufgabe eines Gottes. + Die restlichen zwei Drittel spielen jeweils ein Volk auf der Erde. + Am Ende gibt es zwei Sieger: den himmlischen Sieger, der zwischen den Göttern + ermittelt wird, und den Sieger der Erdlinge, den die restlichen Spieler + zwischen sich ausmachen. +\layout Standard + + +\series bold +Himmlischer Sieger +\series default +ist der Gott, der am Ende in der +\series bold +letzten Schlacht +\series default + auf der +\series bold +Insel des Schicksals +\series default +, der +\series bold +Aymargeddon, +\series default + am meisten Kräfte auf sich vereinigen kann. + Der Ort der letzten Schlacht wird einer von mehreren +\series bold +Manapolen +\series default + sein - abgelegene Inseln, auf denen die magischen Kraftlinien zusammenlaufen. + In der letzten Schlacht kämpfen die +\series bold +Avatare +\series default + der Götter, aber auch die Geister verstorbener +\series bold +Helden +\series default + der Erdlinge. + +\layout Standard + +Der +\series bold +Sieger der Erdlinge +\series default + ist der Spieler, der am Ende die meisten +\series bold +Städte +\series default + sein eigen nennt. + +\layout Standard + +Zweite Plätze gibt es weder bei den Göttern noch bei den Erdlingen. + Es geht immer um den Kampf ums Ganze, um Alles oder Nichts. +\layout Standard + +Die Interaktion zwischen den beiden Ebenen wird durch +\series bold +Priester +\series default + und +\series bold +Götteraktionen +\series default + möglich. +\layout Standard + +Das +\series bold +Spiel endet, +\series medium + sobald alle +\series bold +heiligen Berge +\series default +und +\series bold + gesegneten Inseln mit Tempeln +\series default + bebaut +\series medium +sind +\series default +. + +\series medium +Die Tempel bauen die Erdlinge, Götter können sie nur zerstören. + +\layout Standard + +Je mehr Priester an einem Tempel +\series bold +beten +\series default +, um so mehr +\series bold +Mana +\series default + erhält der jeweilige Gott und um so mehr Aktionen kann er machen. +\layout Standard + + +\series bold +Beide Ebenen +\series medium +sind aufeinander angewiesen, da Götter ohne den guten Willen der Erdlinge + kein +\series default + Mana und somit keinerlei Macht +\series medium + haben und die Erdlinge die Unterstützung der Götter in ihren irdischen + Dingen dringend brauchen. + Durch diese enge Verzahnung der beiden Spielebenen ist man immer zu +\series bold +Verhandlungen +\series medium + gezwungen. +\layout Standard + +Der +\series bold +Glücksfaktor +\series default + wird von den Spielern selbst bestimmt. + Kämpfe werden durch einen Zufallswert mitbestimmt. + Den Maximalwert des Zufalls (3 - 12) müssen die Götter bestimmen (auch + diese Aktion kostet sie natürlich Mana). + +\layout Standard + +Am +\series bold +Schluss +\series medium + ist es vor allem nötig +\series default +, +\series medium + einen Partner zu haben, der stark genug ist +\series default +, +\series medium + um auch an einem Spielende interessiert zu sein +\series default + oder schwach genug, um sich mit einem hinteren Platz zufrieden zu geben +\series medium +. + So werden treue Verbündete, mit denen man das ganze Spiel gemeinsam bestritten + hat, oft noch einmal kurz vor Schlu +\series default +ss +\series medium + fallengelassen. +\layout Standard + +Die +\series bold +Erdlinge +\series medium +spielen +\series default +mit +\series bold +Kriegern +\series default +, Helden (von Göttern erzeugt) und Priestern. + Üblicherweise werden nur die ersten Priester von Göttern erleuchtet, danach + machen die Tempel diese Arbeit. + Sie können Tempel bauen, Städte erobern und Archen steuern. +\layout Standard + +Die +\series bold +Götter +\series medium +spielen +\series default + mit ihren Avataren, können aber auch Tempel zerstören, Archen erschaffen, + Felder überfluten, Seuchen herbeirufen, Priester und Helden erzeugen und + den Glücks +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +- +\end_inset + +fak +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +- +\end_inset + +tor verändern. + Doch das alles kostet sie Mana. +\layout Standard + +Die Welt ist in viele kleine sechseckige Spielfelder unterteilt. + Die Größe des Spielfeldes wird durch die angestrebte Spieleranzahl bestimmt. + +\layout Standard + +Gespielt wird über einen üblichen Web-Browser. + Es gibt keine Spielrunden, sondern jeder Befehl braucht eine gewisse Zeit, + bis er ausgeführt wird. + Die Spielgeschwindigkeit kann dabei variieren. +\layout Standard + +An dieser Stelle möchten wir einmal ganz laut und deutlich allen Testspielern + des Brettspieles und der Pbem-Version danken, ohne die auch diese Online-Versio +n nicht möglich geworden wäre! +\layout Section* + + +\family sans +\series medium +\size large +\emph on +WARNUNG: +\layout Standard + + +\family sans +\emph on +Sowohl die verschiedenen beteiligten Programme als auch diese Regeln sind + noch in einem Test-Stadium. + Wir bitten also insbesondere alle Testspieler, uns darauf hinzuweisen, + wenn es Unterschiede zwischen diesem Dokument und dem realen Verhalten + des Spiels gibt. + Außerdem bitten wir Euch, Euch in die Ragnarök-Mailingliste einzutragen + ( +\begin_inset Quotes pld +\end_inset + +subscribe ragnaroek +\begin_inset Quotes prd +\end_inset + + nach majordomo@cs.uni-frankfurt.de schicken). + Helft mit, dass Aymargeddon besser wird! Wer will, kann auch gerne selbst + programmieren helfen. + Der Quellcode steht in einem tla-Archiv auf www.aymargeddon.de zur Verfügung. +\layout Section + +Die Welt +\layout Quotation + + +\emph on + +\begin_inset Quotes pld +\end_inset + +Wenn man eine Rolle lange genug spielte, vermischten sich langsam Fiktion + und Realität... + Rache war etwas für Götter. +\begin_inset Quotes prd +\end_inset + + (aus: +\begin_inset Quotes pld +\end_inset + +Ragnarök +\begin_inset Quotes prd +\end_inset + + von D.G.Compton und John Gribbin) +\layout Standard + +Die Welt besteht aus Sechsecken und hat keinen Rand. + Man kann in jede Richtung laufen und kommt wieder zum Ausgangspunkt zurück + (Torus). + Hier ein Screenshot vom Hauptbildschirm, damit Ihr eine Vorstellung davon + bekommt, wie die Welt aussieht. +\layout Standard +\align center +<BILD FEHLT NOCH> +\layout Standard + +In dieser Welt kann man sich in sechs verschiedene Richtungen bewegen, die + man sich folgendermaßen vorstellen kann: +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center +<BILD KAPUTT> +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center + +\begin_inset Graphics + filename +ay_ein_hex.eps + display monochrome + width 50text% + +\end_inset + + +\layout Standard + +Jeder Erdling beginnt bei seiner Heimatstadt. + Diese ist schwerer zu erobern und produziert mehr Krieger als normale Städte. + Jeder Gott hat zwei heilige Berge, an denen nur er angebetet werden kann. +\layout Standard + +Es dürfen immer nur Einheiten von einem Erdling in einem Feld stehen, das + somit einen eindeutigen Eigentümer hat. + Heimatstädte erinnern sich immer an ihre rechtmäßigen Herrscher. + Sie verteidigen sich auch ohne Krieger, und sie gehören einem wieder, sobald + die Besatzungsmacht abgezogen ist. +\layout Standard + +Besondere Felder sind die Manapole, zu ihnen strebt das ganze Denken der + Götter ihrem Wesen nach. + Einer der Manapole ist immer die Insel des Schicksals. + Manapole sind immer komplett von Wasserfeldern ohne gesegnete Inseln umgeben. +\layout Standard + +Außerdem gibt es noch Wasser und Inseln. + Inseln sind immer gesegnet, man kann dort also immer Tempel bauen, außer + es handelt sich um einen Manapol. + Über Wasser darf man sich als Erdling nur bewegen, wenn im Ausgangsfeld + eine Arche ist. + Avatare dürfen sich nur dann über Wasser bewegen, wenn ein Erdling gleichzeitig + die Arche steuert. + Die Archen bewegen sich mit den Erdlingen mit und haben ein unbegrenztes + Fassungsvermögen. + Die Götter sind also auf die Mithilfe der Erdlinge angewiesen, wenn sie + ihre Avatare in die letzte Schlacht, die auf der Insel des Schicksals stattfind +et, schicken wollen. +\layout Standard + +Welcher Manapol Aymargeddon ist, ändert sich im Laufe des Spiels. + Es ist immer der Manapol, der dem neuesten und schönsten Tempel am nächsten + ist. + Avatare bewegen sich leichter in Richtung Aymargeddon als von ihr weg. + Sie dürfen die Insel des Schicksals nicht verlassen, so lange sie Aymargeddon + ist. +\layout Subsection* + +Topologie +\layout Standard + +Felder haben immer zwei Koordinaten. + Das Spielfeld hat keinen Rand, wenn man sich in einer Richtung über den + vermeintlichen Rand bewegt, kommt man auf der gegenüberliegenden Seite + wieder raus. + Die folgende Karte mit den Koordinaten der Felder demonstriert das: +\layout Standard +\align center +<BILD FEHLT NOCH> +\layout Standard + +Eine Welt ist immer doppelt so breit wie hoch. + Nur so kann man in allen Richtungen immer geradeaus laufen und kommt doch + immer wieder am Ausgangspunkt an. +\layout Subsection* + +Produktion +\layout Standard + +Alle Städte erzeugen automatisch in gewissen Zeitabständen Krieger. + Heimatstädte erzeugen doppelt so schnell Krieger, sie tun dies manchmal + auch, wenn sie das Feld von feindlichen Einheiten besetzt wird, dann kommt + es zu Aufständen der heimatlichen Bevölkerung in regelmäßigen Abständen. + Normale Städte erzeugen umso häufiger Krieger, je kürzer der Zeitpunkt + ihres letzten Besitzerwechsels her ist. + +\layout Standard + +Tempel erzeugen in gewissen Zeitabständen Priester. + Es werden keine Priester erzeugt, wenn nicht schon rechtgläubige Priester + dort sind. +\layout Section + +Aktionen +\layout Standard + +Jede Aktion eines Spielers wird sofort in eine Datenbank geschrieben. + Die Aktionen werden jedoch erst zu einem späteren Zeitpunkt ausgeführt. + Wie lange das dauert, hängt von der Aktion ab (siehe Abschnitt Timing). + Einheiten sind wärend dieser Zeit inaktiv. +\layout Subsection* + +Aktionen für alle Spieler +\layout Subsubsection* + +Status ändern +\layout Standard + +Mit dieser Aktion kann man seine generelle Haltung anderen Spielern gegenüber + - seien sie Götter oder Erdlinge - ändern. + Man kann andere Spieler als Freund, als Feind oder neutral ansehen. + Man kann ihnen Sichtrechte gewähren oder sie verweigern. + +\layout Standard + +Das hat an einigen Stellen Auswirkungen, die dort dann näher beschrieben + sind. + Zu Spielbeginn ist man allen anderen Spielern gegenüber neutral eingestellt + und gewährt ihnen keine Sichtrechte. +\layout Subsection* + +Aktionen der Erdlinge +\layout Standard + + +\series bold +Bewegen +\layout Standard + +Dies bedeutet, dass man eine bestimmte Anzahl Krieger, Helden oder Priester + in ein Nachbarfeld bewegen will. + Dies kann zu Kampfhandlungen führen, wenn sich am Ende des Zuges noch Einheiten + anderer Erdlingsspieler auf dem Zielfeld aufhalten. + +\layout Standard + +Erdlinge können die Manapole nicht betreten. + Ihre toten Helden werden automatisch direkt nach einem Kampf zur Aymargeddon + transferiert. +\layout Standard + +Helden bewegen sich doppelt so schnell wie Krieger und kämpfen doppelt so + gut. + +\layout Standard + +Wasser- und Inselfelder können nur betreten werden, wenn im Startfeld eine + Arche steht, die einen dorthin bringen kann. + +\layout Standard + +Archen bewegen sich immer automatisch mit Erdlingen mit außer bei der Bewegung + zwischen Landfeldern. + Wenn Erdlingseinheiten oder Avatare in einem Wasserfeld zurückbleiben, + aus dem sich eine Arche entfernt, ertrinken sie jämmerlich. + Ertrinkende Helden streiten nicht in der letzten Schlacht, ebensowenig + wie ertrinkende Avatare. + Auf Inselfeldern können sie jedoch überleben. +\layout Standard + +Das Bewegen von einem Wasser- oder Inselfeld auf ein benachbartes Landfeld + ist immer möglich auch ohne Arche. + +\layout Standard + +Das Bewegen in das Feld eines Alliierten scheitert +\begin_inset Foot +collapsed true + +\layout Standard + +Böse Zungen nennen das die Olf-Bodo-Regel ;-) +\end_inset + +. + Ebenso scheitert die Bewegung, wenn im Zielfeld bereits ein Kampf stattfindet + an dem ich nicht beteiligt bin. + So wird gewährleistet, dass an einem Erdlingskampf immer nur zwei Spieler + beteiligt sein können. + Das Bewegen scheitert allerdings erst am Schluss der Bewegung. + Sie müssen sich dann wieder zurück bewegen. + +\layout Standard + +Man kann somit fast lückenlos Felder übergeben. + Daraus ergibt sich, dass man Alliierte nicht angreifen kann, so lange sie + Freunde sind. + +\layout Subsubsection* + +Tempel bauen +\layout Standard + +Diese Aktion erzeugt auf einem Feld einen Tempel einer Gottheit. + Es ist nur möglich, Tempel zu erzeugen, wenn der Spieler mindestens einen + Priester der passenden Gottheit dort hat und das Feld ein heiliger Berg + oder eine gesegnete Insel ist. + Wenn es ein heiliger Berg ist, darf nur ein Tempel des Gottes gebaut werden, + dem der Berg gewidmet ist. + Auf jedem Feld kann es immer nur einen Tempel geben. +\layout Standard + +Tempel zu bauen geht am Anfang des Spiels recht schnell, dauert aber um + so länger, je mehr Tempel schon gebaut sind. + Jeder Erdling will schließlich den schönsten Tempel der Welt haben, und + das dauert natürlich seine Zeit. + Wenn alle Tempel gebaut sind, endet das Spiel sofort. + +\layout Standard + +Der Manapol, der dem neuesten Tempel am nächsten ist, wird zur Insel des + Schicksals. + Wenn mehrere Manapole gleich weit entfernt sind, bleibt die aktuelle Aymargeddo +n bestehen. + (noch nicht implementiert) +\layout Subsubsection* + +Schlachtordnung festlegen +\layout Standard + +Erdlinge können angeben in welcher Schlachtordnung ihre Armeen in den Krieg + ziehen. + Es wird eine Reihenfolge angegeben in der die Einheiten aufgestellt werden. + Mit der Reihenfolge kann jeder Erdling angeben, welche eigenen Einheiten + in vorderster Front stehen und somit zuerst sterben sollen. + So kann man zum Beispiel zuerst Krieger sterben lassen, dann Helden und + dann erst die Priester. +\layout Standard + +Die Reihenfolge gilt immer für die ganze Welt. +\layout Standard + +Die voreingestellte Reihenfolge ist: Krieger, Helden, Priester. + +\layout Standard + +Die Reihenfolge ist allerdings nicht absolut, sondern gibt nur die Wahrscheinlic +hkeit des Todes an. +\layout Standard + +Archen befinden sich immer in der letzten Reihe der Schlachtordnung. + Jede Arche, die +\begin_inset Quotes pld +\end_inset + +stirbt +\begin_inset Quotes prd +\end_inset + + wird mit einer gewissen Wahrscheinlichkeit versenkt und mit einer gewissen + Wahrscheinlichkeit vom Gegner erobert. +\layout Subsection* + +Aktionen der Götter +\layout Quotation + + +\emph on + +\begin_inset Quotes pld +\end_inset + +Wenn Dich das nächste Mal jemand fragt, ob Du ein Gott bist, sag ja. +\begin_inset Quotes prd +\end_inset + + (aus: Ghostbusters) +\layout Standard + +Alle folgenden Aktionen kosten Mana. + Neues Mana erhält ein Gott, wenn seine Priester an den richtigen Tempeln + beten. + Alle zehn Zeiteinheiten gibt es pro Priester und Tempel einen Manapunkt + (MP). +\layout Subsubsection* + +Avatar erschaffen +\layout Standard + +Ein Avatare erscheint immer an dem eigenen Tempel an dem am meisten eigene + Priester beten. + Ein Avatar kostet 5 MP. + +\layout Subsubsection* + +Held weihen +\layout Standard + +Ein Krieger kann nur an eigenen Tempeln zum Helden geweiht werden. + Das kostet 1 MP. +\layout Description + +Priester +\series medium + +\series bold +erleuchten +\layout Standard + +Einen Priester kann man nur aus einem Krieger erzeugen, wenn der Gott das + entsprechende Feld einsehen kann (siehe Sicht-Abschnitt). + Diese Aktion kostet 5 MP. + +\layout Subsubsection* + +Avatare bewegen +\layout Standard + +Avatare dürfen sich auch auf die Insel des Schicksals begeben (allerdings + nicht mehr von ihr weg). + Das Bewegen eines Avatars geht deutlich schneller als das Bewegen der Erdlinge + (Eine Zeiteinheit). + Es kostet immer 1 MP pro Feld und Avatar. + Avatare reisen umsonst auf Schiffen mit. +\layout Standard + +Avatare dürfen sich nicht auf Wasser- oder Inselfelder bewegen, ausser mit + einer Arche (von Erdlingen gesteuert). + Von Wasserfeldern aus, dürfen sie sich auch alleine auf Landfelder oder + Manapole bewegen. +\layout Subsubsection* + +Verseuchen +\layout Standard + +Ein Gott kann die Erde mit Seuchen überziehen. + Das hat unterschiedliche Auswirkungen je nach Art der Seuche. + Seuchen verbreiten sich mit einer gewissen Wahrscheinlichkeit auf Nachbarfelder + sowie bei Bewegungen von Erdlingseinheiten. + Die Anwesenheit von Priestern erhöht die Wahrscheinlichkeit, dass die Seuche + aufhört. + Die Kosten für Seuchen hängen von der Art der Seuche ab. + Zum Verseuchen benötigt man einen anwesenden Avatar und in dem Feld darf + gerade kein Götterkampf (s.u.) stattfinden. + +\layout Standard + +Verseucht sind immer ganze Felder, keine einzelnen Einheiten. + Städte stecken sich leichter an als Landfelder, Landfelder leichter als + Berge, Berge leichter als Inseln, Inseln leichter als Wasserfelder. +\layout Standard + +Es gibt zur Zeit drei verschiedene Seuchen: +\layout Standard + + +\begin_inset Tabular +<lyxtabular version="3" rows="4" columns="3"> +<features> +<column alignment="center" valignment="top" leftline="true" width="0"> +<column alignment="center" valignment="top" leftline="true" width="0"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Seuche +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Effekt +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Mana +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Influenza +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Städte und Tempel produzieren nicht mehr +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +10 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Pestilentia +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +50% aller Leute sterben +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +20 +\end_inset +</cell> +</row> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Ebola +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +100% aller Leute sterben +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +40 +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\layout Standard + +Wenn Leute sterben, so geschieht das nach den Regeln bei Erdlingskämpfen + (s.u.). +\layout Standard + +Eine Seuche hat alle 20 Zeiteinheiten erneut ihren in der Tabelle beschriebenen + Effekt. +\layout Subsubsection* + +Sintfluten +\layout Standard + +Avatare können eine Ebene oder einen Berg überfluten, die an ein Wasser- + oder Inselfeld grenzen, wenn sie vor Ort sind und in dem Feld gerade kein + Götterkampf(s.u.) stattfindet. + Eine Sintflut kostet nur 2 MP, dauert aber 40 Zeiteinheiten. + Berge werden durch Überfluten zu Inseln. + Dadurch ändert sich ihre Exklusivität, und von nun an können auch andere + Götter an ihnen angebetet werden. + Städte und Inseln kann man nicht überfluten. +\layout Standard + +Wenn zum Zeitpunkt des Flutens einer Ebene noch Einheiten im Feld sind, + benötigen sie eine Arche, um nicht unterzugehen. +\layout Subsubsection* + +Avatarstatus ändern +\layout Standard + +Jede Gruppe von Avataren eines Spielers in einem Feld hat einen Status. + Dieser kann +\series bold +\shape smallcaps +Helfe +\series default +\shape default +, +\series bold +\shape smallcaps +Block +\series default +\shape default + oder +\series bold +\shape smallcaps +Ignorieren +\series default +\shape default + sein. + Mit +\series bold +\shape smallcaps +Helfe +\series default +\shape default + hilft man befreundeten Erdlingen, wenn es zu Kämpfen kommt. + Mit +\series bold +\shape smallcaps +Block +\series default +\shape default + schlägt man sich mit verfeindeten Avataren, wenn diese ins Feld kommen. + Man kann immer nur eines von beidem gleichzeitig tun. + +\layout Standard + +Sich bewegende Avatare nehmen ihren Status mit. + Wenn zwei Gruppen von Avataren des selben Spielers zusammentreffen, wird + immer automatisch +\series bold +\shape smallcaps +Block +\series default +\shape default + vor +\series bold +\shape smallcaps +Helfe +\series default +\shape default + vor +\series bold +\shape smallcaps +Frieden +\series default +\shape default + für die neue gemeinsame Gruppe gewählt. + +\layout Subsubsection* + +Tempel zerstören +\layout Standard + +Götter können den Tempel eines anderen Gottes auf einer gesegneten Insel + zerstören. + Dort dürfen sich keine Priester eines anderen Gottes befinden, außerdem + braucht man einen eigenen Avatar in dem Feld und es darf dort kein Götterkampf + (s.u.) stattfinden. + Dieser Befehl kostet 5 MP. + Wenn nur noch ein Tempelfeld unbebaut ist, kann man keine Tempel mehr zerstören. + +\layout Standard + +Es gibt im Wesentlichen zwei Anwendungsfälle für diesen Befehl: +\layout Enumerate + +Ein Gott will eine gesegnete Insel übernehmen, damit ein +\begin_inset ERT +status Collapsed + +\layout Standard +ver +\backslash +-bün +\backslash +-de +\backslash +-ter +\end_inset + + Erdling ihm dort einen Tempel errichtet. + Dafür muss der alte Tempel zerstört werden. + +\layout Enumerate + +Ein Gott will das drohende Spielende hinauszögern, weil er für später bessere + Siegchancen sieht. + Danach sollte man Erdlinge dazu überreden, das leere Baufeld auch zu verteidige +n. + Wenn jedoch einmal der Baubefehl für den letzten Tempel gegeben ist, ist + es zu spät, das Ende der Welt noch aufzuhalten. +\layout Subsubsection* + +Glücksfaktor verändern +\layout Standard + +Mit diesem Befehl kann man angeben, ob man den globalen +\begin_inset ERT +status Collapsed + +\layout Standard +Glücks +\backslash +-fak +\backslash +-tor +\end_inset + +, der auf alle Kämpfe mit Ausnahme der letzten Schlacht angewandt wird, + erhöhen oder erniedrigen will. + Man gibt an, wie viele Manapunkte man investieren will. + Pro MP ändert sich der Glücksfaktor um einen Punkt auf einer Skala von + 3 bis 12. +\layout Standard + +Der Glücksfaktor ist immer für alle Spieler gleich hoch, es gibt also nur + einen Glücksfaktor für alle Spieler. +\layout Subsubsection* + +Arche bauen +\layout Standard + +Ein Gott kann auf einem Feld, dass er sieht, eine Arche bauen. + Steuern kann er sie nicht. + Die Arche gehört dem derzeitigen Feldeigentümer. +\layout Standard + +Eine Arche zu bauen kostet 5 MP und dauert 30 Zeiteinheiten. +\layout Section + +Beten +\layout Quotation + + +\emph on + +\begin_inset Quotes pld +\end_inset + +Wer Gott definiert, ist schon Atheist. +\begin_inset Quotes prd +\end_inset + + (Oswald Spengler) +\layout Standard + +Die Götter erhalten alle 10 Zeiteinheiten einen MP pro Tempel und pro rechtgläub +igem Priester an diesem Tempel ebenso ein MP. + Die Anzahl effektiv betender Priester pro Tempel ist allerdings auf den + aktuellen Glücksfaktor begrenzt. + An heiligen Bergen können doppelt so viele Priester effektiv beten. +\layout Section + +Infos +\layout Standard + +Folgende generelle Daten sind für alle Mitspieler jedezeit abrufbar. + Sie beziehen sich auf das ganze Spiel und nicht auf einzelne Felder. + +\layout Itemize + +Der aktuelle Glücksfaktor +\layout Itemize + +Die Anzahl nicht gebauter Tempel +\layout Itemize + +Die Stärke auf der Insel des Schicksals +\layout Itemize + +Die Anzahl der Avatare auf den Manapolen (noch nicht implementiert) +\layout Itemize + +Die Gesamtstärke jeden Erdlings (noch nicht implementiert) +\layout Itemize + +Die Anzahl der lebenden Avatare jedes Gottes (noch nicht implementiert) +\layout Itemize + +Die Anzahl der Priester jedes Gottes (noch nicht implementiert) +\layout Itemize + +Die Anzahl Städte jedes Erdlings +\layout Standard + +Dadurch kann man immer die Stärke eines anderen Spielers ungefähr einordnen + und sieht, wer auf dem Weg zum Sieg ist. +\layout Standard + +Erdlinge sehen außerdem noch die Sterbereihenfolge ihrer Einheiten. + Götter sehen ihren aktuellen Manastand. +\layout Subsection* + +Sichtrechte +\layout Standard + +Sichtrecht hat man für folgende Felder: +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center + +\begin_inset Tabular +<lyxtabular version="3" rows="3" columns="2"> +<features> +<column alignment="center" valignment="top" leftline="true" width="0pt"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0pt"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Götter +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Erdlinge +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +eigene Holys +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Heimatstädte +\end_inset +</cell> +</row> +<row bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +anwesende Priester oder Avatare +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +anwesende Priester, Krieger oder Helden +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\layout Standard + +Von Bergen aus sieht man zwei Felder weit, sonst nur eins. +\layout Standard + +Andere Spieler können einem Sichtrechte gewähren. + Dies tun sie durch den Allianzstatus +\begin_inset Quotes pld +\end_inset + +Alliiert +\begin_inset Quotes prd +\end_inset + + oder +\begin_inset Quotes pld +\end_inset + +Verrat +\begin_inset Quotes prd +\end_inset + +. + +\begin_inset Quotes pld +\end_inset + +Freund +\begin_inset Quotes prd +\end_inset + + gewährt keine Sichtrechte. +\layout Standard + +Als anwesend zählen auch nicht-aktive Einheiten (die sich zum Beispiel gerade + in der Bewegung befinden). +\layout Standard + +Wenn man Sichtrecht für ein Feld hat, kann man jederzeit die Infos zu diesem + Feld abrufen. +\layout Section + +Kampf +\layout Standard + +Götter können Erdlinge nicht direkt attackieren, sie können nur andere Erdlinge + bei diesen Angriffen unterstützen. + +\layout Standard + +Bei jedem Kampf außer der letzten Schlacht werden die Kampfstärken der beteiligt +en Einheiten addiert und zusätzlich ein Zufallswert zwischen eins und dem + Glücksfaktor dazugezählt. + +\layout Standard + +Jeder Kampf dauert eine gewisse Zeitspanne. + Alle in dieser Zeitspanne hinzustoßenden Einheiten nehmen am Kampf teil + oder werden vom Kampf ausgeschlossen. + In letzterem Fall kehren sie einfach wieder um. +\layout Subsection* + +Erdlingskampf +\layout Standard + +Ein Erdlingskampf wird ausgelöst, wenn Einheiten eines neutralen oder verfeindet +en Erdlings - im Folgenden Angreifer genannt - ein Feld betreten, dessen + Eigentümer im Folgenden Verteidiger genannt wird. + Alle Einheiten dieser beiden Parteien, die wärend der Kampfdauer zum Kampf + dazu stoßen, nehmen am Kampf teil. + Einheiten Dritter werden vom Kampf ausgeschlossen. + Eine Möglichkeit, sich aus einem einmal begonnenen Kampf herauszuhalten, + gibt es nicht. +\layout Standard + +Die Kampfstärke beider Seiten ergibt sich aus der Summe der Kampfstärken + der beteiligten Einheiten. + Beide Seiten eines Kampfes addieren einen Zufallswert, der zwischen 1 und + dem aktuellen Glücksfaktor liegt, zu ihrer Kampfstärke. + +\layout Standard + +Dem bisherigen Eigentümer reicht ein Unentschieden zum Sieg. + +\layout Standard + +Eine Partei, die einen Kampf verliert, muss ihre Überlebenden zurückziehen. + Alle Einheiten ziehen sich einzeln zurück. + +\layout Standard + +Dazu wird nach dem Zufallsprinzip eines der Nachbarfelder ausgewählt, das + dem Verlierer gehört oder neutral ist und in dem zum Zeitpunkt des Rückzuges + kein Kampf stattfindet. + Ein Rückzug ist wie eine normale Bewegung und braucht Zeit. + Archen ziehen sich immer zuerst zurück. + Archen auf Küstenfeldern können sich nur auf Wasser oder Inselfelder zurückzieh +en. + Andere Einheiten können sich nur auf Landfelder zurückziehen oder auf solche, + auf die sich bereits Archen zurückgezogen haben. +\layout Standard + +Es kann passieren, dass das Feld bei Ankunft der Flüchtenden auch schon + einem anderen Spieler gehört, dann kommt es dort direkt wieder zum Kampf. + Flüchtende Einheiten können also von Feld zu Feld gejagt und dabei aufgerieben + werden. + Ein gut geplanter Angriff auf breiter Front kann diese Regel bewusst ausnutzen. +\layout Standard + +Natürlich kann man beim Kämpfen auch zu schaden kommen: Der Verlierer verliert + die Hälfte der Kampfstärke des Gewinners (ohne Avatare und Flankierung) + an Leuten. + Der Gewinner verliert ein Viertel der Kampfstärke des Verlierers. + Der Gewinner behält mindestens eine Person (oder Arche), der Verlierer + verliert mindestens eine. + Die Schlachtordnung bestimmt wieviele Leute welcher Art anteilig sterben. +\layout Standard + +Sollte ein Spieler nach einem verlorenen Kampf keinerlei Rückzugsmöglichkeiten + mehr haben, sterben alle seine Einheiten in diesem Feld. + +\layout Standard + +Doch jetzt endlich zu den Kampfstärken: +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center + +\begin_inset Tabular +<lyxtabular version="3" rows="8" columns="2"> +<features> +<column alignment="center" valignment="top" leftline="true" width="0pt"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0pt"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Einheit +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Modifikator +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Priester +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++0 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Krieger +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++1 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Held +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++2 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Avatar +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +bis zu +4 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Heimatstadt +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++2 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Arche +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++3 +\end_inset +</cell> +</row> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +pro Flankierung +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++1 +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\layout Standard + +Dabei ist +0 nicht so sinnlos, wie es auf den ersten Blick aussieht: Sind + nur Prieser anwesend, können sie wenigstens auf ihr Würfelglück hoffen, + wenn sie angegriffen werden und tragen zur Avatarunterstützung bei, wenn + diese vorhanden ist. +\layout Standard + +Avatare kämpfen natürlich nur mit, wenn sie im Status +\begin_inset Quotes pld +\end_inset + +Helfe +\begin_inset Quotes prd +\end_inset + + sind, und Mannapunkte übrig haben (2 MP pro Kampf unabhängig von der Anzahl + Avatare). + Sie geben maximal 4 Punkte Bonus. + Dabei wird pro kämpfendem Erdling ein Punkt verbraucht (egal ob Krieger, + Held oder Priester). + +\layout Standard + +Den Flankierungsbonus erhält man für jedes benachbarte Feld, das folgende + Bedingungen erfüllt: +\layout Itemize + +Es muss einem selbst oder einem Spieler mit dem Status +\begin_inset Quotes pld +\end_inset + +Freund +\begin_inset Quotes prd +\end_inset + + oder +\begin_inset Quotes pld +\end_inset + +alliiert +\begin_inset Quotes prd +\end_inset + + gehören; +\layout Itemize + +der Eigentümer des Feldes muss zum Zeitpunkt des Kampfes noch aktive Einheiten + dort stehen haben; +\layout Itemize + +es darf nicht selbst umkämpft sein. + +\layout Itemize + +Es darf kein Wasserfeld sein. + Inseln flankieren aber ganz normal. +\layout Standard + +Dadurch kann man Gebiete, die aus zusammenhängenden benachbarten Feldern + bestehen, besser verteidigen. +\layout Subsection* + +Avatarkampf +\layout Quotation + + +\emph on + +\begin_inset Quotes pld +\end_inset + +Jetzt hast Du, tapferer Soldat, jetzt hast Du, streitbarer Mann, einen Ort, + wo Du ohne Gefahr kämpfen kannst, wo der Sieg Ruhm und der Tod Gewinn ist. +\begin_inset Quotes prd +\end_inset + + (Bernhard von Clairveaux, 1146 n.u.Z., zum zweiten Kreuzzug aufrufend) +\layout Standard + +Avatare haben immer einen von drei Zuständen. + Mit +\begin_inset Quotes pld +\end_inset + +Helfe +\begin_inset Quotes prd +\end_inset + + helfen sie Erdlingen, wie oben angesprochen. + Mit +\begin_inset Quotes pld +\end_inset + +Block +\begin_inset Quotes prd +\end_inset + + blockieren sie andere Avatare, um gegen sie zu kämpfen. + Ist ihr Zustand +\begin_inset Quotes pld +\end_inset + +Ignoriere +\begin_inset Quotes prd +\end_inset + +, wollen sie mit niemandem Streit. + Die Avatare eines Gottes in einem Feld können nur den gleichen Zustand + haben. + +\layout Standard + +Nur der Status +\begin_inset Quotes pld +\end_inset + +Block +\begin_inset Quotes prd +\end_inset + + kann zu Avatarkämpfen führen. + Dies geschieht, wenn +\layout Itemize + +einer der beiden den anderen als Feind betrachtet und er oder der andere + 'Blockieren' eingestellt hat, oder +\layout Itemize + +wenn zwei Götter aufeinander treffen, die einander beide 'Neutral' gegenübersteh +en aber beide 'Blockiere' eingestellt haben. +\layout Standard + +Zu Kämpfen kann es nur dann kommen, wenn Avatare in ein Feld ziehen oder + wenn der Avatarstatus auf blockieren geändert wird. + Für jeden schon anwesenden Gott wird einzeln ermittelt, ob es zu einem + Kampf mit dem Neuankömmling kommt. + Es kann dabei durchaus zu mehreren parallel verlaufenden Kämpfen kommen, + die auch im Folgenden einzeln abgewickelt werden. + Wenn ein Avatar in ein Feld kommt, in dem er schon vertreten ist, löst + das nie einen Kampf aus. +\layout Standard + +Avatarkämpfe kosten 2 MP unabhängig von der Anzahl der beteiligten Avatare. + Wenn ein Gott nicht mehr genügend MP hat, darf der Gott noch auf sein Würfelglü +ck hofen, aber seine Avatare kämpfen nicht mehr mit. +\layout Standard + +Avatarkämpfe dauern länger als die Kämpfe der Erdlinge; und da Avatare sehr + schnell sein können, kann man eventuell auch noch aus einiger Entfernung + Kräfte hinzuziehen. + Man darf Avatare nicht aus einem umkämpften Feld wegziehen, auch wenn man + an keinem der Kämpfe beteiligt ist. + +\layout Standard + +Sollte im selben Feld bereits ein Erdlingskampf stattfinden, so wird der + Avatarkampf bis nach dem Erdlingskampf verschoben. + +\layout Standard + +Jeder Avatar zählt +4, und es wird ganz normal gewürfelt. + Der Verlierer verliert die Hälfte der Avatare des Gewinners und der Gewinner + verliert ein Viertel der Avatare des Verlierers. + Bei einem unentschieden gelten beide Seiten als Verlierer. + Die Seelen sterbender Avatare fahren in eventuell anwesende Krieger des + Feldeigentümers und machen diese zu Helden. + Alle Avatare des Verlierers die danach noch im Feld sind werden an den + Ort der Avatarerschaffung zurückteleportiert. +\layout Standard + +Avatare, die in einem Götterkampf beschäftigt sind, dürfen keine Erdlinge + bei ihren Kämpfen unterstützen. +\layout Subsection* + +Die letzte Schlacht +\layout Standard + +In der letzten Schlacht wird nicht gewürfelt. + Es zählen nur die Kampfwerte: +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center + +\begin_inset Tabular +<lyxtabular version="3" rows="3" columns="2"> +<features> +<column alignment="center" valignment="top" leftline="true" width="0pt"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0pt"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Einheit +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Kampfwert +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Avatar +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++7 +\end_inset +</cell> +</row> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Geist eines Helden +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++1 +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\layout Standard + +Für die Geister der Helden zählt der angebetete Gott. + Diese Helden kämpfen also immer noch für ihren Gott, auch wenn der Erdling + inzwischen längst vom Glauben abgefallen ist. +\layout Section + +Timing +\layout Standard + +Alle Aktionen dauern unterschiedlich lange. + Dabei gibt es in jedem Spiel eine einstellbare Spielgeschwindigkeit, mit + der die Werte unten multipliziert werden. + Die Zahlen in der Tabelle können also sowohl Minuten als auch Tage meinen, + je nachdem wie schnell man spielt. + Die Spielgeschwindigkeit kann sich auch während eines Spieles ändern. + Es kann zum Beispiel sinnvoll sein, das Spiel am Anfang langsamer laufen + zu lassen, bis eine angemessene Anzahl Mitspieler eingestiegen ist. + Jede Änderung der Spielgeschwindigkeit wird rechtzeitig vorher bekannt + gegeben und sollte nicht zu apprupt erfolgen. +\layout Standard + + +\begin_inset Tabular +<lyxtabular version="3" rows="17" columns="2"> +<features islongtable="true"> +<column alignment="center" valignment="top" leftline="true" width="0pt"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0pt"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Aktion +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Dauer +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Krieger bewegen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +10 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Priester bewegen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +12 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Held bewegen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +6 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Avatar bewegen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +1 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Erdlingskampf +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +6 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Avatarkampf +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +10 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Tempel bauen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +3, 6 , 9, ... +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Überfluten +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +20 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Bewegen mit Arche +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +5 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Krieger produzieren +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +40 + N (20) +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Priester produzieren +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +40 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Glücksfaktor verändern +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +5 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Avatarstatus ändern +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +1 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Arche bauen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +30 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Beten +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +10 +\end_inset +</cell> +</row> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +alle anderen Aktionen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +0 +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\layout Standard + + +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +medskip +\end_inset + + +\layout Section + +Spielanfang +\layout Standard + +Die Götter starten mit 33 Mana. + Sie sollten daher zusehen, dass sie möglichst bald Priester erzeugen, damit + diese Tempel bauen können, die wieder Priester produzieren und damit wieder + Mana. + Dafür ist eine Kooperation mit mindestens einem Erdling nötig. +\layout Standard + +Die Erdlinge stehen am Anfang vor der Entscheidung, wo sie ihre ersten Krieger + hinschicken sollen. + Dies kann zum Beispiel auf ein Tempelfeld sein, weil man davon ausgeht, + dass der Krieger in einen Priester umgewandelt wird. + Außerdem ist es ratsam, sich früh mit seinen Nachbarn abzusprechen, wer + welchen Tempel baut. + Ansonsten kann es zu unliebsamen Überraschungen kommen, die einen gleich + die ersten Krieger verlieren lassen! +\layout Standard + +Der Glücksfaktor ist am Anfang auf seinem Minimalwert von 3. +\layout Standard + +Götter, die nachträglich einsteigen, erhalten etwas Bonusmana pro vergangener + Zeiteinheit. + Erdlinge, die neu einsteigen, profitieren davon, dass ihre Heimatstadt + schon die ganze Zeit Krieger produziert hat. +\layout Section + +Spielende (nur teilweise implementiert) +\layout Standard + +Das Spiel endet, sobald alle Tempel gebaut wurden. + Mit dem Baubefehl des letzten Tempels wird allen Spielern bekanntgegeben, + wie lange das Spiel noch dauert. + Dann gibt es kein Zurück mehr. +\layout Standard + +Es gewinnt der Erdling, der die meisten Städte sein eigen nennt. + Dabei zählen besetzte feindliche Heimatstädte und verseuchte Städte mit. + Bei gleicher Anzahl Städte entscheidet die Gesamtkampfstärke des Erdlings. + Sollte die auch gleich sein, wird gewürfelt. + +\layout Standard + +Der Gott, der in der letzten Schlacht die meisten Kräfte auf sich vereint, + gewinnt. + Dabei muss kein Mana mehr ausgegeben werden und es wird auch nicht mehr + gewürfelt. + Sollte die letzte Schlacht unentschieden ausgehen, zählen die Anzahl lebender + Avatare. + Wenn diese auch gleich sind, die Anzahl der Tempel. + Wenn dann immer noch Gleichstand herrscht, zählt das übrige Mana. + Sollte wider erwarten selbst dieses gleich sein, wird am Ende doch noch + gewürfelt. +\layout Standard + +Alle Spieler erhalten zum Abschluss eine Rangliste und den Ausgang der letzten + Schlacht. +\layout Standard + +Mit jedem Spiel kann man Punkte für die ewige Bestenliste sammeln, allerdings + nur als Sieger. + Zweite Plätze zählen nicht. +\layout Section + +FAQ +\layout Subsection* + +Was bedeutet +\shape italic +Aymargeddon +\shape default +? +\layout Standard + +Der Name des Spiels leitet sich von +\shape italic +Armageddon +\shape default + her. + Das wiederum basiert auf dem hebräischen +\shape italic +Har +\shape default +, was +\shape italic +Berg +\shape default + bedeutet, und der Ortschaft +\shape italic +Megeddon +\shape default +, bei der laut der Sage die letzte Schlacht geschlagen werden wird. + Da in unserem Spiel die letzte Schlacht auf einer Insel stattfindet, haben + wir +\shape italic +Har +\shape default + durch +\shape italic +Ay +\shape default + ersetzt, was +\shape italic +Insel +\shape default + bedeutet. + +\layout Standard + +Das +\begin_inset Quotes pld +\end_inset + +r +\begin_inset Quotes prd +\end_inset + + gehört da nicht wirklich hin, nein. + Aber wir haben das erst entdeckt, als wir die Domain schon bestellt hatten + und es klingt eh besser so, oder? Ausserdem gibt +\begin_inset Quotes pld +\end_inset + +Aymageddon +\begin_inset Quotes prd +\end_inset + + unanständige Suchergebnisse bei Google. +\layout Subsection* + +Heißt es +\shape italic +der +\shape default +, +\shape italic +die +\shape default +, oder +\shape italic +das +\shape default + Aymargeddon? +\layout Standard + +Kommt darauf an. +\layout Standard + +Wenn die Insel des Schicksals gemeint ist, heißt es +\shape italic +die +\shape default +, wenn das Spiel gemeint ist, heißt es +\shape italic +das +\shape default + und wenn der Server gemeint ist, heiß es +\shape italic +der +\shape default + Aymargeddon. +\layout Standard + +Das ist allerdings nur die Erdlingssicht. + Götter geben sich mit solch kleinlichen Geschlechterfragen nicht ab, wenn + es um Schicksalsfragen wie das Ende der Welt geht. +\layout Subsection* + +Gibt es Vorläufer zu Aymargeddon? +\layout Standard + +Das Spiel basiert auf einem - leider noch unveröffentlichten - Brettspiel + namens +\shape italic +Ragnarök +\shape default + beziehungsweise dem zugehörigen Play-by-E-Mail +\shape italic +Ragnarök als Pbem +\shape default +. + Beide Spiele hat Benni Bärmann entwickelt. + Die grundlegenden Konzepte sind erhalten geblieben. + Aber natürlich erforderte der geänderte Zugrhythmus und die höhere Spieleranzah +l einige Anpassungen. +\layout Subsection* + +Wie viel Zeit braucht Aymargeddon? +\layout Standard + +Das hängt von der Spielgeschwindigkeit ab. + +\layout Standard + +Bei niedriger Spielgeschwindigkeit braucht man sich nur gelegentlich einzuloggen +, um zu gucken, was es Neues gibt. + Dafür kann sich ein Spiel dann auch schon mal ein paar Monate hinziehen. + +\layout Standard + +Bei hoher Spielgeschwindigkeit sitzt man mehr oder weniger die ganze Zeit + vorm Rechner, dafür ist es dann aber auch nach ein paar Stunden vorbei. +\layout Standard + +Bei gleicher Spielgeschwindigkeit ist das Spiel als Gott tendenziell aufwendiger + als das als Erdling. + Als Erdling kann man fast sicher sein, nichts wichtiges zu verpassen, wenn + man sich so oft einloggt, wie ein Erdlingskampf dauert. +\layout Subsection* + +Was brauche ich, um mitspielen zu können? +\layout Standard + +Eigentlich nichts, außer einer funktionierenden E-Mail-Adresse und einem + üblichen Web-Browser. +\layout Standard + +Was man natürlich auch noch braucht, sind Spaß am Spiel, Verhandlungsgeschick, + etwas Zeit und ein bisschen Glück. +\layout Subsection* + +Wie sehen sinnvolle erste Züge als Erdling aus? +\layout Standard + +Man sollte sich auf jeden Fall möglichst bald mit den Göttern absprechen, + deren heilige Orte man sieht, beziehungsweise auf die Suche nach solchen + Orten gehen. + Danach sollte man möglichst Tempel bauen für die Götter, damit diese schnell + Mana kriegen, mit dem sie einen dann (hoffentlich) unterstützen. +\layout Standard + +Dabei ist es ratsam, auch die irdischen Nachbarn nicht zu vernachlässigen + und dafür zu sorgen, dass sie nicht in der Zwischenzeit alle strategisch + wichtigen Punkte unter sich aufteilen. +\layout Standard + +Wenn man erste Städte erobert hat, muß man sich überlegen ob man sofort + weiterzieht oder erst abwartet, bis dort ein Krieger erzeugt wird. + Im ersten Fall kommt man schneller voran und kann vieleicht weitere Städte + vor den Nachbarn erreichen, im zweiten Fall produziert man schneller neue + Krieger. +\layout Subsection* + +Wie sehen sinnvolle erste Züge als Gott aus? +\layout Standard + +Ein Gott sollte am Anfang hauptsächlich durch Verhandlungen abklären, welche + Erdlinge ihm möglichst bald Tempel auf seinen exklusiven heiligen Bergen + errichten. + +\layout Standard + +Bald kann man dann schon Avatare und möglicherweise sogar Helden erzeugen + und kriegt neues Mana. + +\layout Standard + +Es kann sinnvoll sein, die wertvollen Tempel mit Avataren zu schützen, damit + nicht kleinliche Streitereien zwischen Erdlingen den wertvollen Manastrom + verringern. +\layout Subsection* + +Können Erdlingsarmeen aneinander vorbeilaufen? +\layout Standard + +Ja. + +\layout Subsection* + +Gibt es nicht zu unausgewogene Startpositionen? +\layout Standard + +Gerade die Unausgewogenheit der Startpositionen zwingt zu Verhandlungen. + Deswegen werden die dafür relevanten Informationen (mit denen die Spieler + abschätzen können, wer führt) ja auch zur Verfügung gestellt. +\layout Subsection* + +Was passiert, wenn jemand aufhört? +\layout Standard + +Seine Einheiten bleiben einfach da stehen, wo sie sind, und rühren sich + nicht. + Krieger und Priester eines ausgestiegenen Erdlings werden aber noch weiterhin + erzeugt. + +\layout Standard + +Bei Göttern ist das lästiger als bei Erdlingen, da das Spielgleichgewicht + stärker beeinträchtigt wird. + Schön ist es natürlich in keinem Fall. + +\layout Standard + +Nichtaktive Spieler können jederzeit übernommen werden von Neueinsteigern. + +\layout Subsection* + +Was passiert, wenn ich eine Weile nicht ziehe? +\layout Standard + +Wenn das lange dauert, geht der Server davon aus, dass Du nicht mehr spielen + willst, und gibt Deine Einheiten zur Übernahme frei. + (noch nicht implementiert) +\layout Subsection* + +Soll ich einen Gott oder einen Erdling spielen? +\layout Standard + +Die Götterrolle ist die anspruchsvollere. + Man muß mehr verhandeln und hat mehr Möglichkeiten. + Das ist Vor- und Nachteil zugleich. + Ganz ohne Verhandlung wird man Aymargeddon nicht gewinnen können, aber + Leute, die nicht allzusehr auf Verhandlungen aus sind, sollten lieber eine + Erdlingsrolle übernehmen. + Man sollte auch nur einen Gott spielen, wenn man häufig online ist, da + Götteraktionen im allgemeinen weniger Zeit brauchen. +\layout Standard + +Beim Spielanfang kann man auch +\begin_inset Quotes pld +\end_inset + +egal +\begin_inset Quotes prd +\end_inset + + als gewünschte Rolle angeben. + Dann gibt einem der Server die Rolle, die dafür sorgt, dass das Zahlenverhältni +s 1:2 von Göttern zu Erdlingen annähernd erreicht wird. + Es kann auch vorkommen, dass in einem Spiel gar keine Erdlinge beziehungsweise + Götter mehr zugelassen sind, weil zu weit vom idealen Verhältnis abgewichen + wurde. +\layout Subsection* + +Gehören Städte, die ich einmal in Besitz genommen habe, mir auch noch, wenn + ich sie wieder verlasse? +\layout Standard + +Nein. + Alle Städte, die keine Heimatstädte sind, werden neutral, sobald kein aktiver + Priester, Krieger oder Held mehr in ihnen steht. + Heimatstädte gehören dem Spieler, dessen Heimat sie sind, jedoch auch, + wenn keine Einheiten dort stehen. + Heimatstädte verteidigen sich auch, ohne dass in ihnen Einheiten stehen + müssen. +\layout Subsection* + +Darf man mehrere Positionen im selben Spiel besetzen? +\layout Standard + +Nein, aber man darf in mehreren Spielen gleichzeitig mitspielen. +\layout Subsection* + +Warum sind Avatare wasserscheu? +\layout Standard + +Ist ja eigentlich schon etwas komisch, wo sie doch ansonsten so mächtig + sind. + Die Erklärung ist ganz einfach: Auf ihrer Reise zur Erde mussten sie entweder + in einem furchtbaren Gewitter auf einer Bergspitze erscheinen oder sich + von einer Insel ans nahe, rettende Ufer quälen. + Nach dieser Erfahrung hat niemand mehr Lust auf Wasser! +\layout Section* + +Copyright +\layout Standard + +(c) 2003, 2004, 2005 Aymargeddon Development Team +\layout Standard + +Permission is granted to copy, distribute and/or modify this document under + the terms of the GNU Free Documentation License, Version 1.1 or any later + version published by the Free Software Foundation; with no Invariant Sections, + with no Front-Cover Texts, and with no Back-Cover Texts. + A copy of the license is available at http://www.aymargeddon.de. +\the_end diff --git a/doc/Techdoc.lyx b/doc/Techdoc.lyx new file mode 100644 index 0000000..7614606 --- /dev/null +++ b/doc/Techdoc.lyx @@ -0,0 +1,823 @@ +#LyX 1.3 created this file. For more info see http://www.lyx.org/ +\lyxformat 221 +\textclass article +\language english +\inputencoding auto +\fontscheme default +\graphics default +\paperfontsize default +\spacing single +\papersize Default +\paperpackage a4 +\use_geometry 0 +\use_amsmath 0 +\use_natbib 0 +\use_numerical_citations 0 +\paperorientation portrait +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip medskip +\quotes_language english +\quotes_times 2 +\papercolumns 1 +\papersides 1 +\paperpagestyle default + +\layout Title + +Technisches zu +\begin_inset Quotes eld +\end_inset + +Die letzten Tage von Aymargeddon +\begin_inset Quotes erd +\end_inset + + +\layout Author + +Aymargeddon Development Team +\layout Date + +9.10.2003 +\layout Standard + + +\emph on +Warnung: Die Information in diesem Dokument ist zu nicht unerheblichen Teilen + veraltet. +\layout Section + +Generelles Design +\layout Standard + +Das Spiel besteht aus folgenden Komponenten: +\layout Enumerate + +Eine Relationale Datenbank +\layout Enumerate + +Ein Dämonprozess im Server +\layout Enumerate + +Serverseitige Scripten zur Benutzerinteraktion +\layout Enumerate + +Ein Weltengenerator +\layout Enumerate + +FROGS +\layout Enumerate + +Ein Programm, dass die Integrität der Datenbank überprüft +\layout Enumerate + +Eine Bibliothek für gemeinsame Funktionalität +\layout Standard + +Die Aufgaben dieser Komponenten stellen sich wie folgt dar: +\layout Section + +Datenbank +\layout Standard + +In dieser Datenbank wird der Zustand aller Spielwelten gespeichert. + Außerdem alle Spielerdaten, alle Spieleraktionen und alle Nachrichten an + Spieler. + Sie sorgt mittels ihrer Transaktionen dafür, dass auch bei konkurierendem + Zugriff die Datenintegrität immer erhalten bleibt. +\layout Standard + +Wir verwenden MySQL zur Implementierung und PhpMyAdmin zur Administrierung + der Datenbank. +\layout Standard + +Felder, die in vielen Tabellen vorkommen und immer wieder das selbe bedeuten: +\layout Description + +GAME Das ist die Id des Spiels. + Dadurch können alle Spiele in der selben Datenbank verwaltet werden. + Es kann maximal max(unsigned smallint) Spiele gleichzeitig geben. +\layout Description + +LOCATION Feldkoordinaten auf dem Hexraster-Torus. + Ein String der Form <x>_<y>. + Die maximale Größe der Welt ist max(unsigned smallint) für die Y-Koordinate + und max(unsingend smallint)*2 für die X-Koordinate. +\layout Description + +PLAYER,OWNER,... + Spieler-Ids. + Die Spieler-Ids bezeichnen den Spieler +\emph on +unabhängig +\emph default +von seiner Rolle. + Sie gilt spielübergreifend. + Die maximale Anzahl Spieler ist auf max(signed smallint) beschränkt. +\layout Subsection + +Bewegung und Kämpfe +\layout Standard + +Einheiten, die sich bewegen, bleiben im Feld stehen, werden aber auf nicht + available gesetzt. + Am Ende des Befehls werden sie in das neue Feld gesetzt. + Sie werden nur wieder aktiv, nachdem alle denkbaren Kämpfe ausgeführt wurden. +\layout Standard + +Kämpfe werden als Quasi-Befehl wieder in die Befehlsqueu geschrieben. + Erst nach Ablauf dieses Quasi-Befehls wird ausgewertet, welche Einheiten + auf welcher Seite am Kampf teilnehmen. +\layout Standard + +Einheiten, die sich zurückziehen, werden ganz normal bewegt. +\layout Subsection + +Tabelle MAP +\layout Standard + +Das ist die zentrale Karte. + Für jedes Feld in jedem Spiel gibt es genau einen Eintrag. +\layout Description + +HOME Eigentümer der Heimatstadt. + Das Feld ist -1, wenn es eine Heimatstadt ist, aber noch niemand spielt. +\layout Description + +OCCUPANT Besitzer des Feldes +\layout Description + +TERRAIN kann sein eins aus: WATER, CITY, MOUNTAIN, ISLE, PLAIN +\layout Description + +PLAGUE ist das Feld verseucht? Kann eine aus einer Liste von Seuchen sein +\layout Description + +ATTACKER Hier steht der leitende Erdling eines Angriffs drinnen so lange + gekämpft wird. + 0 sonst. + Man kann hier also auch ablesen, ob das Feld umkämpft ist. +\layout Description + +LAST_PRODUCE Zu dieser Zeit wurde zu letzt ein Krieger (bei Städten) bzw. + ein Priester (bei Tempeln) produziert. + Der Dämon entscheidet anhand dieser Daten, wann neue Einheiten produziert + werden. +\layout Description + +FLUXLINE Hier stehen die Richtungen, in die sich Avatare momentan kostenlos + bewegen können. + Die benachbarten Richtungen kosten 1 MP, alle anderen 2MP. + Dieses Feld wird bei einer Änderung der IdS für die gesamte Karte neu berechnet. +\layout Description + +TEMPLE Steht auf 'Y', wenn dort ein Tempel gebaut wurde, auf 'N' sonst. +\layout Subsection + +Tabelle MOBILE +\layout Standard + +In dieser Tabelle werden alle beweglichen Objekte abgespeichert. + Das sind also zunächst: Krieger, Helden, Priester, Avatare und Archen. + Dabei gibt es nur einen Eintrag für gleichartige Einheiten im selben Feld + im selben Spiel. +\layout Standard + +Manche Felder werden nur für manche Objekttypen benutzt. + Hier wird also ein bisschen Speicherplatz geopfert um die Struktur möglichst + einfach zu halten. +\layout Description + +ID Eine eindeutige ID. +\layout Description + +TYPE Ist einer aus WARRIOR, HERO, PRIEST, AVATAR, ARK +\layout Description + +OWNER Der Spieler, der die Einheit steuert +\layout Description + +ADORING Der Gott, den der Priester anbetet +\layout Description + +COUNT Anzahl +\layout Description + +AVAILABLE Wird auf 0 gesetzt, wenn die Einheit beschäftigt ist (sich also + z.B. + bewegt) +\layout Description + +STATUS Eines aus HELP, BLOCK, PEACE. + Avatarstatus. +\layout Subsection + +Tabelle COMMAND +\layout Standard + +In diese Tabelle tragen die Scripten die Aktionen der Spieler ein und der + Dämon führt diese dann aus. + Zusätzlich kommen hier auch noch die Quasi-Befehle des Dämons selber rein. + Das ist alles, wo er sich für später dran errinnern will. + Zur Zeit wird dieser Mechanismus nur für Kämpfe benötigt. +\layout Description + +TIME Die Zeit zu der das Kommando eingetragen wurde +\layout Description + +ACK Hier wird vermerkt, dass der Dämon das Kommando zur Kenntnis genommen + hat, aber noch nicht ausgeführt. + Das ist nötig weil bei vielen Kommandos schon am Anfang Nachrichten generiert + werden müssen, lange bevor sie ausgeführt werden. + Z.B. + erhalten die Eigentümer eines Feldes, in das man sich bewegt, eine Nachricht, + schon wenn man sich auf den Weg macht. +\layout Description + +DONE Hier werden abgearbeitete Befehle vermerkt +\layout Standard + +Alle drei Felder sind Timestamps und müssen immer GMT enthalten! +\layout Subsection + +Tabelle MESSAGE +\layout Standard + +In diese Tabelle trägt der Dämon Nachrichten an die Spieler ein und die + Scripten zeigen diese dann an. + Nachrichten an Alle Spieler müssen für jeden Spieler einzeln eingetragen + werden. + Wenn man es anders machen wollte, müsste man wiederum für jeden Spieler + vermerken, welche Nachrichten er nicht mehr sehen will, was fast auf das + selbe rauskommt. + +\layout Description + +TIME Der Zeitpunkt, an dem die Nachricht generiert wurde +\layout Description + +FROM Der Absender. + 0 bedeutet, dass es eine automatisch generierte Nachricht des Dämon ist. +\layout Description + +TO Der Empfänger +\layout Description + +TYPE Message, Error, Warning, ... +\layout Description + +MSG Die eigentliche Meldung. + Bzw. + ein Tag, dass erst noch lokalisiert werden muss (Siehe Tabelle LOCALIZE) +\layout Description + +ARG1...4 Die Argumente für die Lokalisierung. +\layout Subsection + +Tabelle GAME +\layout Standard + +Hier stehen allgemein Infos das Spiel betreffend. + Pro Spiel gibt es nur einen Eintrag. +\layout Description + +SIZE Die Größe des Spiels. + Höhe und halbe Breite des Spielfeldes. + Maximale Anzahl Erdlinge. +\layout Description + +FORTUNE Der Glücksfaktor +\layout Description + +LAST_TEMPLE Die LOCATION des letzten fertig gestellten Tempels. +\layout Description + +TEMPLE_SIZE Größe des nächsten Tempels. +\layout Subsection + +Tabelle PLAYER +\layout Standard + +Hier wird spielunabhängig gespeichert, was es alles über einen Spieler zu + wissen gibt. + Pro Spieler ein Eintrag. +\layout Subsection + +Tabelle ALLIANCE +\layout Standard + +Hier wird beschrieben welche Freunde und Feinde man hat. + Pro Spieler-Spieler-Relation in jedem Spiel höchstens ein Eintrag. + Status kann sein +\begin_inset Quotes eld +\end_inset + +FRIEND +\begin_inset Quotes erd +\end_inset + +, +\begin_inset Quotes eld +\end_inset + +FOE +\begin_inset Quotes erd +\end_inset + + oder +\begin_inset Quotes eld +\end_inset + +NEUTRAL +\begin_inset Quotes erd +\end_inset + +. + Wenn kein Eintrag vorhanden ist, wird neutraler Status angenommen. + +\layout Standard + +Man beachte dass Spieler A, Spieler B als Freund ansehen kann, wärend umgekehrt + Spieler B Spieler A als Feind betrachtet! +\layout Subsection + +Tabelle GOD +\layout Standard + +Hier werden Daten für die Götter gespeichert. + Pro Gott und Spiel ein Eintrag. +\layout Description + +DEATH_AVATAR Die Anzahl der für diesen Gott in diesem Spiel gestorbenen + Avatare +\layout Description + +DEATH_HERO dsgl. + für Helden +\layout Description + +ARRIVAL Hier entstehen neue Avatare. + Dieser Ort wird nach jedem Tempelbau diesen Gottes neu berechnet. +\layout Subsection + +Tabelle LOCALIZE +\layout Standard + +Mit Hilfe dieser Tabelle kann die Darstellung in verschiedenen Sprachen + erfolgen. +\layout Description + +TAG Der Eintrag mit dem man wiederkennt, um welche Message es sich handelt +\layout Description + +LANG Die Sprache des Eintrags. + Zur Zeit werden nur +\begin_inset Quotes eld +\end_inset + +DE +\begin_inset Quotes erd +\end_inset + + und +\begin_inset Quotes eld +\end_inset + +EN +\begin_inset Quotes erd +\end_inset + + unterstützt. +\layout Description + +TEXT Der Text der Nachricht in den einzelnen Sprachen. + Dabei wird mittels +\begin_inset Quotes eld +\end_inset + +%n +\begin_inset Quotes erd +\end_inset + + das n.te Argument eingefügt. + +\begin_inset Quotes eld +\end_inset + +%% +\begin_inset Quotes erd +\end_inset + + gibt ein Prozentzeichen aus. + +\layout Subsection + +Tabelle ROLE +\layout Standard + +Hier wird die Rolle eines Spielers in einem Spiel beschrieben. + Pro Mitspieler in jedem Spiel ein Eintrag. +\layout Section + +Dämon +\layout Standard + +Dieses Programm liest Spieleraktionen aus der Datenbank, berechnet die sich + daraus ergebenden Ereignisse und schreibt Nachrichten an die Spieler zurück + in die Datenbank. +\layout Standard + +Wir verwenden Perl 5.8 zur Implementierung des Servers. +\layout Section + +Scripten +\layout Standard + +Sie lesen den Zustand der Welt und die Nachrichten aus der Datenbank, halten + Session-Informationen vor und bereiten dies alles in HTML zur Darstellung + mittels eines üblichen Web-Browsers auf. + Schließlich schreiben sie die Aktionen des Benutzers in die Datenbank und + verändern den Aktivitätsstatus von beweglichen Einheiten. +\layout Standard + +Wir verwenden EmbPerl auf Apache zur Implementation. + Siehe: http://perl.apache.org/embperl/. + EmbPerl scheint genauso einfach und schnell zu sein wie PHP und hat für + uns den zusätzlichen Vorteil, dass wir gemeinsame Bibliotheken mit den + anderen Komponenten des Servers benutzen können. +\layout Subsection + +Seiten +\layout Standard + +Folgende Seitenlayouts werden benötigt. + Auf allen Seiten findet man ein Hauptmenu. + Auf Login und Home gibt es auch noch ein Aymaegeddon-Banner +\layout Description + +Login Hier gibt es neben News einen kurzen Einleitungstext sowie eine Möglichkei +t sich zu registrieren und mal in einem Fakespiel zu schnuppern. +\layout Description + +Home Liste aller Spiele, pro Spiel: Liste aller Nachrichten, aller Ereignisse, + Statistik +\layout Description + +Karte Aktuelles Feld, Beschreibung, Befehle +\layout Description + +Spieler Beschreibung des Spielers +\layout Description + +Rolle Beschreibung der Rolle +\layout Standard + +Feldnamen/-koordinaten sind überall immer zur Karte mit dem Feld als aktuellem + Feld verlinkt. + Rollennamen sind zu der entsprechenden Rollenseite verlinkt. +\layout Subsection + +Karte +\layout Standard + +Zentrale Komponente der Darstellung ist eine Karte des Hex-Torus. + Dazu werden 3 Tabellenzellen pro Feld verwendet, nämlich so: +\layout Standard +\added_space_bottom 0.3cm +<BILD FEHLT> +\layout Standard + +Diese Karte ist scrollbar. + Ein Feld ist immer als aktuelles Feld umrandet. +\layout Subsection + +Farbdarstellung +\layout Standard + +Wasserfelder blau, Landfelder, Archen und Inseln in Erdfarben. + Dabei gibt es 5 Farbtöne für eigene, befreundete, neutrale, feindliche + sowie unbesiedelte Felder. + Tempel und Avatare werden in 5 verschiedenen Götterfarben (eher grell) + dargestellt, wieder je eine für eigene, befreundete, feindliche sowie neutrale + Götter. + Die +\begin_inset Quotes eld +\end_inset + +eigene +\begin_inset Quotes erd +\end_inset + + Farbe kann auf andere Erdlinge/Götter verändert werden. + +\layout Subsection + +Icons +\layout Standard + +Folgende Icons werden benötigt. +\layout Standard + +Zentriert: +\layout Itemize + +IdS +\layout Itemize + +Eigentum auf Wasser (Schiff) +\layout Itemize + +Städte +\layout Itemize + +Tempel +\layout Itemize + +Heimatstädte +\layout Itemize + +Inseln +\layout Itemize + +Berge +\layout Standard + +Nicht zentriert: +\layout Itemize + +Avatare (oben bis zu vier) +\layout Itemize + +Archen (unten, nur eine) +\layout Itemize + +Kampf (unten) +\layout Itemize + +Avatarkampf (oben) +\layout Section + +Weltengenerator +\layout Standard + +Dieses Programm wird einmal zu Beginn eines neuen Spiels aufgerufen um eine + neue Welt in der Datenbank zu generieren. + Der Generator verteilt die verschiedenen Geländetypen: Wasser, Manapol, + Insel, Berg, Stadt, Heimatstadt, Land. + Er erhält die Anzahl der Erdlinge als Parameter und ermittelt alle anderen + Werte daraus. + +\layout Standard + +Die Game-ID kann automatisch als die erste Freie in der DB ermittelt werden. + Dieses Programm sollte als erstes entwickelt werden, damit man eine sinnvolle + Testumgebung für die anderen Teile des Systems hat. +\layout Standard + +Wir verwenden Perl 5.8 zur Implementation. +\layout Section + +FROGS +\layout Standard + +FROGS steht für +\series bold +F +\series default +ramework for +\series bold +R +\series default +ealtime +\series bold +O +\series default +nline +\series bold +G +\series default +ames of +\series bold +S +\series default +trategy. + Dort werden alle Funktionalitäten versammelt, die nicht nur von Aymargeddon, + sondern auch von anderen Browser-MMOGs verwendet werden können. + Das sind im einzelnen: +\layout Itemize + +Nachrichtenverwaltung +\layout Itemize + +Befehlsverwaltung +\layout Itemize + +Spielerverwaltung +\layout Itemize + +Spielverwaltung +\layout Itemize + +Rollenverwaltung +\layout Itemize + +Verschiedene Standardkarten (hier erstmal nur Hextorus) +\layout Itemize + +Bewegliche Einheiten +\layout Itemize + +Lokalisierung +\layout Itemize + +Sessionhandling +\layout Itemize + +Bestenlisten +\layout Itemize + +Datenbank +\layout Standard + +FROGS basiert dabei auf der Annahme, dass bestimmte Felder in bestimmten + Tabellen vorhanden sein müssen. + Außerdem werden die konkreten Funktionalitäten über Hooks in das Framework + eingehängt. + So wird z.B. + für jeden Befehl ein Name festgelegt mit drei Hooks: +\layout Description + +test Diese Funktion tested, ob der Befehl überhaupt ausführbar ist. +\layout Description + +ack Diese Funktion wird ausgeführt, wenn der Befehl zum ersten mal vom Dämon + zur Kenntnis genommen wird. +\layout Description + +do Diese Funktion führt schließlich den Befehl aus. + Dazu sind am Anfang noch weitere tests nötig. +\layout Standard + +Ziel für Frogs ist, dass man relativ einfach neue Browserspiele bauen kann. + Es wird auch ein Satz von Standardseiten in EmbPerl mitgeliefert mit denen + Funktionen wie Einloggen, Spielverwaltung, Bestenlisten etc. + schon vorhanden sind. +\layout Standard + +Hier noch eine Liste von FROGS-Modulen und was sie tun sollen: +\layout Description + +Map.pm Dies ist eine Basisklasse für alle denkbaren Topologien. + Jedes Modul einer abgeleiteten Klasse sollte auch eine Klasse Location + zur Verfügung stellen. + Außerdem müssen abgeleitete Klassen einige Funktionen mitbringen, damit + die in Map vorhandenen Funktionen funktionieren. +\layout Description + +HexTorus.pm Dies ist die von Aymargeddon verwendete Topologie. + Kann aber auch von anderen Spielen verwendet werden. + Abgeleitet von Map.pm. + Stellt auch die Klasse Location zur Verfügung. +\layout Description + +Checker.pm Hier werden die verallgemeinerbaren Funktionen des Checkers zur + Verfügung gestellt. +\layout Description + +Scheduler.pm Hier wird die Befehlsqueu durchgegangen und die oben definierten + Funktionen werden aufgerufen. +\layout Description + +Localize.pm Hier wird die Lokalisierung ausgeführt. +\layout Description + +DataBase.pm Hier werden Basisdatenbankfunktionalitäten zur Verfügung gestellt +\layout Description + +... + weitere Module noch unklar +\layout Standard + +Auch FROGS wird in Perl 5.8 bzw. + EmbPerl implementiert. +\layout Section + +Checker +\layout Standard + +Dieses Programm überprüft, ob die Daten in der Datenbank noch konsistent + sind. + Dabei werden die Checks zu algorithmisch ähnlichen Gruppen zusammengefasst + und durch allgemein Funktionen ausgeführt. + Bisher sind folgende Funktionen identifiziert worden: +\layout Enumerate + +Jeder Eintrag in Tabelle X muß auch in Tabelle Y existieren. + +\layout Enumerate + +N Einträge in der selben Tabelle müssen eine logische Beziehung erfüllen +\layout Standard + +Diese allgemeinen konfigurierbaren Check-Funktionen sollten auch Teil von + FROGS werden. +\layout Standard + +Der Checker überprüft im einzelnen (Zahlen beziehen sich auf obige Funktionslist +e): +\layout Itemize + +Jede Spielnummer muß in der Tabelle GAME zu finden sein (1). +\layout Itemize + +sämtliche Spieler-IDs müssen in ROLE zum selben Spiel passen (1). +\layout Itemize + +sämtliche Spieler-IDs müssen in PLAYER vorhanden sein (1). +\layout Itemize + +Location muß immer in MAP vorhanden sein. +\layout Itemize + +Location muß immer die kanonische Form haben (2). +\layout Itemize + +HOME nur gesetzt in MAP, wenn TERRAIN = CITY (desgl. + für GOD_HOME und MOUNTAIN) (2). +\layout Itemize + +Keine Zwei Erdlinge im selben Feld, außer es ist Kampf. +\layout Itemize + +Alle Einheiten in COMMANDS müssen inaktiv sein. +\layout Itemize + +Nur Priester ADORING in MOBILE (2). +\layout Itemize + +AVAIABLE immer kleiner oder gleich COUNT in MOBILE (2) +\layout Itemize + +Während eines Kampfes nur aktive Erdlinge eines Spielers im selben Feld. +\layout Itemize + +Keine blockenden Avatare von zwei feindlichen Spielern im selben Feld ohne + Kampf . +\layout Itemize + +Jedes Tag in MESSAGE sollte in LOCALIZE vorhanden sein. + Mindestens in einer Sprache. + Warnung, wenn nicht in jeder Sprache. +\layout Itemize + +Die Anzahl der Argumente in MESSAGES sollte mit den nicht doppelten %-Zeichen + in LOCALIZE übereinstimmen (für jede Sprache). + +\layout Itemize + +CREATE <= EXEC <= ACK <= DONE in COMMAND +\layout Standard + +Dieses Programm sollte möglichst früh entwickelt werden, da es vor allem + im Entwicklungsprozess benötigt wird. +\layout Standard + +Wir verwenden Perl 5.8 zur Implementation. +\layout Section + +Bibliothek +\layout Standard + +Hier werden alle Funktionalitäten versammelt, die von mindestens zwei der + Komponenten (Scripten, Generator, Dämon, Check) verwendet werden. + +\layout Standard + +Dabei bleiben in dieser Bibliothek nur Sachen, die nicht noch allgemeiner + sind und somit in den FROGS-Teil gehören. + Momentan ist noch unklar, ob da überhaupt was übrig bleibt. +\layout Standard + +Wir verwenden Perl 5.8 zur Implementation. +\layout Section + + +\lang german +Copyright +\layout Standard + + +\lang german +(c) 2003 Aymargeddon Development Team +\layout Standard + + +\lang german +Permission is granted to copy, distribute and/or modify this document under + the terms of the GNU Free Documentation License, Version 1.1 or any later + version published by the Free Software Foundation; with no Invariant Sections, + with no Front-Cover Texts, and with no Back-Cover Texts. + A copy of the license is available at http://www.aymargeddon.de. +\the_end diff --git a/doc/ay_ein_hex.fig b/doc/ay_ein_hex.fig new file mode 100644 index 0000000..ea108e2 --- /dev/null +++ b/doc/ay_ein_hex.fig @@ -0,0 +1,36 @@ +#FIG 3.2 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +2 3 0 1 0 7 100 0 -1 0.000 0 0 0 0 0 7 + 4425 4177 5103 5348 6452 5349 7127 4177 6451 3006 5101 3009 + 4425 4177 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 5847 2976 5895 2430 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 4742 3668 4185 3420 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 4752 4771 4050 5175 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 5796 5327 5760 6075 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 6777 4803 7398 5067 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 6823 3599 7408 3262 +4 0 0 100 0 0 12 -0.0000 4 180 1440 3285 3195 Nordwesten (NW)\001 +4 0 0 100 0 0 12 -0.0000 4 180 1410 3105 5625 Suedwesten (SW)\001 +4 0 0 100 0 0 12 -0.0000 4 180 1260 7065 3150 Nordosten (NO)\001 +4 0 0 50 0 0 12 0.0000 4 180 930 5490 2250 Norden (N) \001 +4 0 0 50 0 0 12 0.0000 4 180 765 5355 6390 S\374den (S)\001 +4 0 0 100 0 0 12 -0.0000 4 180 1230 7155 5400 Suedosten (SO)\001 diff --git a/doc/design b/doc/design new file mode 100644 index 0000000..e8f5e51 --- /dev/null +++ b/doc/design @@ -0,0 +1,149 @@ +################# +Datenbankzugriffe +################# + +Alles, was einen SQL-Befehl beinhaltet sollte in +DataBase.pm. zusätzlich vielleicht auch noch sehr eng damit +zusammenhängende Funktionen. Alles abstraktere sollte in extramodule. + +Generelle Frage: +================ + +embperl sollte nur die aktionen überhaupt zur verfügung stellen, die +möglich sind (soweit zu diesem zeitpunkt bekannt). + +soll man darauf vertrauen, dass die embperlseite bestimmte sachen +schon abgetestet hat? oder muss man die alle nochmal auf serverseite +testen? Antwort: wohl ja, da sich zwischen eintragen in die +befehlsqueu und ausführung des befehls der spielstand verändert haben +kann. ausnahmen sind unten eingeklammert. + +Hier jetzt mal eine möglichst vollständige Liste aller +Datenbankzugriffe, als Grundlage für Designüberlegungen. + +Von Serverseite: +================ + +- lies alle aktuellen befehle +- schreibe message + +Alles, was trotz zeitverzögerung schon vorher von embperlseite +abgeklärt hätte werden können ist eingeklammert. + +einzelne befehle: +-------------------- +- passwort ändern (nicht in befehlsqueu sondern sofort?) + - authentifizieren + - schreiben in PLAYER + +- registrieren (nicht in befehlsqueu sondern sofort?) + - schreiben in PLAYER + +- abmelden (nicht in befehlsqueu sondern sofort?) + - authentifizieren + - löschen in PLAYER + +- status ändern + - test ob spieler vorhanden + - schreiben in ALLIANCE + +- anmelden in einzelnen spielen (nicht in befehlsqueu sondern sofort?) + - test ob spieler schon in spiel vorhanden + - schreiben in ROLE + +- abmelden aus spielen (nicht in befehlsqueu sondern sofort?) + - löschen aus ROLE +-------------------- +- erdlingsbewegen: + - (test ob manapol) + - test ob arche auf wasser + - test ob kampf + - test wer kämpft + - schreiben in MOBILE + - schreiben in MAP + - schreiben in COMMAND + +- tempel bauen: + - test ob tempelfeld des gottes (kann sich ändern wg. überschwemmung) + - test ob richtiger priester da + +- sterbereihenfolge: + - (testen ob reihenfolge gültig) + - schreiben in EARTHLING [ACHTUNG: neue Tabelle!] + +- gott für tote helden festlegen: + - testen ob gott gültig + - schreiben in EARTHLING +-------------------- +- bei allen gottbefehlen: testen ob manna reicht + +- avatar erschaffen: + - ort ermitteln aus MAP und MOBILE + - schreiben in MOBILE + +- held weihen + - testen ob held noch vorhanden (und aktiv?) + - schreiben in MOBILE + +- priester erleuchten + - testen ob krieger noch vorhanden (und aktiv?) + - testen ob sichtrecht + - schreiben in MOBILE + +- avatare bewegen + - ähnlich wie erdlingsbewegen nur zusätzliche tests + - avatarstatus beachten (evntl. verändern) + +- verseuchen + - noch unklar, weil seuchen noch unklar + +- sintfluten + - test ob benachbartes wasserfeld + - liest und schreibt aus MAP + +- avatarstatus ändern + - testen ob avatar da. + +- tempel zerstören + - ... + +- glücksfaktor verändern + - ... + +- arche bauen + - ... + +Von Clientseite: +================ + +- authentifizieren +- liste aller spiele +- liste aller spiele mit freien positionen (mit rolle) +- liste aller spieler +- liste aller rollen pro spiel +- infos ueber einen spieler +- infos ueber eine rolle eines spielers in einem spiel + +- karte lesen (sichtregeln beachten!) +- infos ueber ein feld lesen (auch aus MOBILE) (sichtregeln beachten!) + +- liste der möglichen befehle in einem feld ermitteln + (vielfältige tests, viele davon stehen oben bei den serverbefehlen) + +- liste aller nachrichten +- liste aller nachrichten ein feld betreffend + +Von create.pl: +============== + +- lies das erste leere spiel aus GAME +- schreibe in MAP + +Von checker.pl: +=============== + +- sehr spezielle einzelne zugriffe (Check.pm selbst definiert keine +Struktur) + + + diff --git a/doc/pdf-tip b/doc/pdf-tip new file mode 100644 index 0000000..b954654 --- /dev/null +++ b/doc/pdf-tip @@ -0,0 +1,75 @@ +From Martin.Spott@uni-duisburg.de Tue Jul 6 17:06:05 1999 +From: Martin Spott <Martin.Spott@uni-duisburg.de> +Newsgroups: de.comp.os.unix.apps,de.comp.text.tex +Subject: Re: tex -> pdf +Date: 24 Jun 1999 18:59:57 GMT +Organization: home +Lines: 24 +Message-ID: <7ktv7d$p59$1@foehn.quickstep.cologne.de> +References: <7kskei$6hb$1@narses.hrz.tu-chemnitz.de> <3771ECC7.C1F5FDA2@starship.python.net> +NNTP-Posting-Host: foehn.quickstep.cologne.de +X-Trace: foehn.quickstep.cologne.de 930250797 25769 192.168.48.2 (24 Jun 1999 18:59:57 GMT) +X-Complaints-To: usenet@foehn.quickstep.cologne.de +NNTP-Posting-Date: 24 Jun 1999 18:59:57 GMT +X-Newsreader: TIN [UNIX 1.3 unoff BETA 970705; sun4m SunOS 5.5.1] +Path: nntp.server.uni-frankfurt.de!grapool30.rz.uni-frankfurt.de!News.Uni-Marburg.DE!news-fra1.dfn.de!news-kar1.dfn.de!akk.uni-karlsruhe.de!news.cologne.de!quickstep.cologne.de!not-for-mail +Xref: nntp.server.uni-frankfurt.de de.comp.os.unix.apps:2328 de.comp.text.tex:41798 + +In de.comp.os.unix.apps Berthold H?llmann <bhoel@starship.python.net> wrote: + +> 7. latex ; dvipdf ? + +Ist das dasselbe wie das 'dvipdfm', welches ich hier rumfliegen habe ? + +Beim Weg ueber 'dvips' respektive ueber DVI im Allgemeinen ist vor allem +darauf Acht zu geben, dass ausschliesslich Type1-Fonts im TeX-Dokument +verwendet werden. Wie genau das geht, habe ich nicht mehr im Kopf, es gibt +aber wohl irgeneinen Switch im 'dvips' und die dazugehoerigen TeX-Fonts im +Type1-Format. Beruecksichtigt man das nicht, dann sieht das PDF-Dokument vor +allem auf dem Bildschirm ausgesprochen haesslich aus und der Aufbau einer +Seite im Acrobat Reader dauert ungefaehr die fuenffache Zeit vom dem, was es +mit Type1-Fonts gebraucht haette, weil dann Bitmap-Fonts in das Dokument +eingebaut werden. Die eignen sich vielleicht zu allem moeglichen, aber mit +Sicherheit nicht fuer eine skalierbare Darstellung auf verschiedenen +Ausgabemedien. + +Derleit haessliche Dokumente kursieren leider zuhauf .... + +Martin. +-- + Unix _IS_ user friendly - it's just selective about who its friends are ! +-------------------------------------------------------------------------- + + +From Martin.Spott@uni-duisburg.de Tue Jul 6 17:06:14 1999 +From: Martin Spott <Martin.Spott@uni-duisburg.de> +Newsgroups: de.comp.os.unix.apps,de.comp.text.tex +Subject: Re: tex -> pdf +Date: 24 Jun 1999 20:04:25 GMT +Organization: home +Lines: 13 +Message-ID: <7ku309$q35$1@foehn.quickstep.cologne.de> +References: <7kskei$6hb$1@narses.hrz.tu-chemnitz.de> <3771ECC7.C1F5FDA2@starship.python.net> <7ktv7d$p59$1@foehn.quickstep.cologne.de> +NNTP-Posting-Host: foehn.quickstep.cologne.de +X-Trace: foehn.quickstep.cologne.de 930254665 26725 192.168.48.2 (24 Jun 1999 20:04:25 GMT) +X-Complaints-To: usenet@foehn.quickstep.cologne.de +NNTP-Posting-Date: 24 Jun 1999 20:04:25 GMT +X-Newsreader: TIN [UNIX 1.3 unoff BETA 970705; sun4m SunOS 5.5.1] +Path: nntp.server.uni-frankfurt.de!grapool30.rz.uni-frankfurt.de!News.Uni-Marburg.DE!news-fra1.dfn.de!fu-berlin.de!news.cologne.de!quickstep.cologne.de!not-for-mail +Xref: nntp.server.uni-frankfurt.de de.comp.os.unix.apps:2329 de.comp.text.tex:41800 + +In de.comp.os.unix.apps Martin Spott <Martin.Spott@uni-duisburg.de> wrote: + +> darauf Acht zu geben, dass ausschliesslich Type1-Fonts im TeX-Dokument +> verwendet werden. Wie genau das geht, habe ich nicht mehr im Kopf, es gibt +> aber wohl irgeneinen Switch im 'dvips' und die dazugehoerigen TeX-Fonts im +> Type1-Format. [...] + +.... oder jedenfalls die CM-Fonts, + +Martin. +-- + Unix _IS_ user friendly - it's just selective about who its friends are ! +-------------------------------------------------------------------------- + + diff --git a/doc/push_rules b/doc/push_rules new file mode 100644 index 0000000..9ce50ca --- /dev/null +++ b/doc/push_rules @@ -0,0 +1,6 @@ +# tth -t -e2 Regeln.tex +# mv Regeln.tex ./+Regeln.tex +mv Regeln.html ./+Regeln.html +mv Regeln.pdf ./+Regeln.pdf +scp ./+Regeln.html benni@aymargeddon.de:aymargeddon/current/doc/ +scp ./+Regeln.pdf benni@aymargeddon.de:aymargeddon/current/doc/ diff --git a/html/aymargeddon.css b/html/aymargeddon.css new file mode 100644 index 0000000..8148fcc --- /dev/null +++ b/html/aymargeddon.css @@ -0,0 +1,2 @@ +table,body {line-height:13pt;font-size:11pt;} +p {margin-bottom:5pt;margin-top:5pt;} diff --git a/html/command.epl b/html/command.epl new file mode 100644 index 0000000..2eca5e5 --- /dev/null +++ b/html/command.epl @@ -0,0 +1,5 @@ +<html> +<head></head> +<body> +[- Execute('command_frames.epl') -] +</body></html> diff --git a/html/command_frames.epl b/html/command_frames.epl new file mode 100644 index 0000000..cb5b35d --- /dev/null +++ b/html/command_frames.epl @@ -0,0 +1,221 @@ +[# get command and maybe some parameters #] + +[- + use Aymargeddon; + $db = DataBase->new(); + $aym = Aymargeddon->new($udat{-game},$udat{-id},$db); + $db->set_language($udat{-lang}); +-] + +[$ if $fdat{'cmd'} $] [# show form to enter the required parameters #] + +[- +# my ($gname) = $db->read_game($udat{-game},'NAME'); +# my $cname = $aym->charname($udat{-id}); + +# $out = "<strong>$gname</strong> $cname.<p>\n" + $out = '<form method="get" action="command.epl">'; + + my $cmd = $udat{-cmd} = $fdat{'cmd'}; + $udat{-cmd_loc} = $fdat{'loc'} if $fdat{'loc'}; + + if($cmd eq 'SEND_MSG' and exists $fdat{'other'}){ # anybody, always + $udat{-cmd_args} = 'OTHER='.$fdat{'other'}; + my $to = $aym->charname($fdat{'other'}); + $out .= $db->loc('SEND_MESSAGE_TO',$to). + '<textarea name="message" cols="20" rows="20"></textarea>' + }elsif($cmd eq 'CH_STATUS' and exists $fdat{'other'}){ # anybody, always + $udat{-cmd_args} = 'OTHER='.$fdat{'other'}; + $out .= $db->loc('CMD_CH_STATUS_MSG').' '.$aym->charname($fdat{'other'}).":<p>\n" + .'<input type="radio" name="status" value="ALLIED">'.$db->loc('STAT_ALLIED')."<p>\n" + .'<input type="radio" name="status" value="FRIEND">'.$db->loc('STAT_FRIEND')."<p>\n" + .'<input type="radio" name="status" value="NEUTRAL">'.$db->loc('STAT_NEUTRAL')."<p>\n" + .'<input type="radio" name="status" value="FOE">'.$db->loc('STAT_FOE')."<p>\n" + .'<input type="radio" name="status" value="BETRAY">'.$db->loc('STAT_BETRAY')."<p>\n"; + }elsif($cmd eq 'DIE_ORDER'){ # earthling, always + $out .= $db->loc('CMD_DIE_ORDER_MSG').":<p>\n" + .'<input type="radio" name="dying" value="PKH">'.$db->loc('MOBILE_PRIEST_PL').', '.$db->loc('MOBILE_WARRIOR_PL').', '.$db->loc('MOBILE_HERO_PL')."<p>\n" + .'<input type="radio" name="dying" value="PHK">'.$db->loc('MOBILE_PRIEST_PL').', '.$db->loc('MOBILE_HERO_PL').', '.$db->loc('MOBILE_WARRIOR_PL')."<p>\n" + .'<input type="radio" name="dying" value="KPH">'.$db->loc('MOBILE_WARRIOR_PL').', '.$db->loc('MOBILE_PRIEST_PL').', '.$db->loc('MOBILE_HERO_PL')."<p>\n" + .'<input type="radio" name="dying" value="KHP">'.$db->loc('MOBILE_WARRIOR_PL').', '.$db->loc('MOBILE_HERO_PL').', '.$db->loc('MOBILE_PRIEST_PL')."<p>\n" + .'<input type="radio" name="dying" value="HPK">'.$db->loc('MOBILE_HERO_PL').', '.$db->loc('MOBILE_PRIEST_PL').', '.$db->loc('MOBILE_WARRIOR_PL')."<p>\n" + .'<input type="radio" name="dying" value="HKP">'.$db->loc('MOBILE_HERO_PL').', '.$db->loc('MOBILE_WARRIOR_PL').', '.$db->loc('MOBILE_PRIEST_PL')."<p>\n" + }elsif($cmd eq 'CH_LUCK'){ # god, always + $out .= $db->loc('CMD_CH_LUCK_MSG').":<p>\n" + . '<input type="text" name="bonus"><p>'."\n"; + # TODO: inc/dec button + }elsif($cmd eq 'MOVE' and exists $fdat{'mob'} and exists $fdat{'loc'}){ # any mobile + $udat{-cmd_args} = 'MOBILE='.$fdat{'mob'}; + my ($type, $count, $adoring, $movewith) = + $aym->get_mobile_info($fdat{'mob'}, 'TYPE, COUNT, ADORING, MOVE_WITH'); + $out .= $db->loc('CMD_MOVE_MSG',$aym->mobile_extended_string($type,$count,$adoring)).":<p>\n" + .'<input type="text" name="dir">'; + $out .= $db->loc('CMD_COUNT').':<input type="text" name="count">'."max. $count" if $count > 1; + $out .= "<p>\n"; + + # arks cant move with other units + if($type ne 'ARK'){ + # MOVE_WITH + my $mob = $aym->mobiles_available($fdat{'loc'}); + my $mobcount = $#{@$mob}+1; + my $transporters = 0; + if ($mobcount > 1){ + foreach $i (0..$mobcount-1){ + my ($oid,$otype,$oown,$oado,$ocnt,$ostat,$omove) = @{$mob->[$i]}; + next if($oid == $fdat{'mob'} or $otype eq 'AVATAR' ); + next if $omove; + if(! $transporters){ + $out .= $db->loc('MSG_MOVE_WITH').":<p>\n"; + $transporters = 1; + } + if($movewith == $oid){ + $out .= '<input type="radio" name="movewith" value="0">'. + $db->loc('MSG_DONT_MOVE_WITH')."<p>\n"; + }else{ + $out .= '<input type="radio" name="movewith" value="'.$oid.'">'. + $aym->mobile_extended_string($otype, $ocnt, $oado)."<p>\n"; + } + } + } + } + #}elsif($cmd eq 'CH_ADORING' and exists $fdat{'mob'}){ # hero + # $udat{-cmd_args} = 'MOBILE='.$fdat{'mob'}; + # $out .= $db->loc('CMD_CH_ADORING_MSG').":<p>\n"; + # my @gods = $aym->gods(); + # for my $god (@gods){ + # $out .= '<input type="radio" name="god" value="'.$god.'">'.$aym->charname($god)."<p>\n"; + # } + }elsif($cmd eq 'CH_ACTION' and exists $fdat{'mob'}){ # avatar + $udat{-cmd_args} = 'MOBILE='.$fdat{'mob'}; + $out .= $db->loc('CMD_CH_ACTION_MSG').":<p>\n" + . '<input type="radio" name="action" value="BLOCK">'.$db->loc('MOBILE_BLOCK')."<p>\n" + . '<input type="radio" name="action" value="HELP">'.$db->loc('MOBILE_HELP')."<p>\n" + . '<input type="radio" name="action" value="IGNORE">'.$db->loc('MOBILE_IGNORE')."<p>\n"; + }elsif($cmd eq 'BLESS_PRIEST' and exists $fdat{'mob'}){ # warrior + $udat{-cmd_args} = 'MOBILE='.$fdat{'mob'}; + $out .= $db->loc('CMD_BLESS_PRIEST_MSG').".<p>\n"; + }elsif($cmd eq 'BLESS_HERO' and exists $fdat{'mob'}){ # warrior + $udat{-cmd_args} = 'MOBILE='.$fdat{'mob'}; + $out .= $db->loc('CMD_BLESS_HERO_MSG').".<p>\n"; + $out .= ':<input type="text" name="count"><p>'."\n"; + }elsif($cmd eq 'BUILD_TEMPLE' and exists $fdat{'mob'}){ + # priest or prophet at mountain (of the god they adore) or isle without temple + $udat{-cmd_args} = 'MOBILE='.$fdat{'mob'}; # needed to change its type to priest if it was a prophet + $out .= $db->loc('CMD_BUILD_TEMPLE_MSG').' '.$fdat{'loc'}.".<p>\n"; + }elsif($cmd eq 'DESTROY'){ # avatar at mountain or isle with temple + $out .= $db->loc('CMD_DESTROY_MSG').' '.$fdat{'loc'}.".<p>\n"; + }elsif($cmd eq 'MOVE_MTN'){ # earthling at a mountain with more priests of one god than luck+5 + $out .= $db->loc('FIELD_MOUNTAIN')." $loc ".$db->loc('CMD_MOVE_MTN_MSG').":<p>\n"; + # TODO: list target locations (where prophets adoring same god are) + }elsif($cmd eq 'INCARNATE'){ # god at his arrival temple (temple with most priests adoring him) + $out .= $db->loc('CMD_INCARNATE_MSG').":<p>\n" + .':<input type="text" name="count"><p>'."\n"; + }elsif($cmd eq 'BUILD_ARK'){ # god at any coast field + $out .= $db->loc('CMD_BUILD_ARK_MSG').' '.$fdat{'loc'}.".<p>\n"; + }elsif($cmd eq 'PLAGUE'){ # god at any field + $out .= $db->loc('CMD_PLAGUE_MSG').' '.$fdat{'loc'}.":<p>\n"; + for my $plague (@{$::conf->{-PLAGUES}}){ + $out .= '<input type="radio" name="type" value="'.$plague.'">'."$plague<p>\n" + } + }elsif($cmd eq 'FLOOD'){ # god at any coast field (without city) + $out .= $db->loc('CMD_FLOOD_MSG').' '.$fdat{'loc'}.".<p>\n"; + + }else{ + delete $udat{-cmd}; + delete $udat{-cmd_loc}; + $out = $db->loc('CMD_ERROR_MSG')."<p>\n"; # unknown, illegal or incomplete command + } + + if(exists $udat{-cmd}){ + $out .= '<input type="submit" value="'.$db->loc('FORM_OK_BUTTON').'"></form>'; + $udat{-back} = $ENV{'HTTP_REFERER'}; + } + $out .= '<form method="get" action="'.$ENV{'HTTP_REFERER'}.'">' + .'<input type="submit" value="'.$db->loc('FORM_BACK_BUTTON').'"></form><p>'; + + print OUT $out; +-] + +[$ elsif exists $udat{-cmd} $] [# complete the command with the given form-data #] + +[- + my ($cmd) = $udat{-cmd}; delete $udat{-cmd}; + my ($args) = $udat{-cmd_args}; delete $udat{-cmd_args} if exists $udat{-cmd_args}; + my ($loc) = $udat{-cmd_loc}; delete $udat{-cmd_loc} if exists $udat{-cmd_loc}; + my $failure = 0; + + # global + if($cmd eq 'SEND_MSG'){ + my $msg = $db->quote($fdat{'message'}); + + # uggly workaround necessary for Command::parse_args() + $msg =~ s/,/__COMMA__/g; + $msg =~ s/=/__EQUAL__/g; + + $args .= ", MESSAGE=$msg" + }elsif($cmd eq 'CH_STATUS'){ + $failure = 1 if not exists $fdat{'status'}; + $args .= ', STATUS='.$fdat{'status'}; + }elsif($cmd eq 'DIE_ORDER'){ + $failure = 1 if not exists $fdat{'dying'}; + $args = 'DYING='.$fdat{'dying'}; + }elsif($cmd eq 'CH_LUCK'){ + $failure = 1 if not exists $fdat{'bonus'}; + $args = 'BONUS='.$fdat{'bonus'}; + + # mobile + }elsif($cmd eq 'MOVE'){ + $failure = 1 if (not exists $fdat{'dir'} and not exists $fdat{'movewith'}); + my $count = (exists $fdat{'count'}) ? $fdat{'count'} : 1; + if(exists $fdat{'movewith'}){ + $cmd = 'MOVE_WITH'; + $args .= ', COUNT='.$count.', TARGET='.$fdat{'movewith'}; + }else{ + $args .= ', COUNT='.$count.', DIR='.$fdat{'dir'}; + } + #}elsif($cmd eq 'CH_ADORING'){ + #$failure = 1 if not exists $fdat{'god'}; + #$args .= ', GOD='.$fdat{'god'}; + }elsif($cmd eq 'CH_ACTION'){ + $failure = 1 if not exists $fdat{'action'}; + $args .= ', ACTION='.$fdat{'action'}; + }elsif($cmd eq 'BLESS_HERO'){ + my $count = exists $fdat{'count'} ? $fdat{'count'} : 1; + $args .= ", COUNT=$count"; + # local + }elsif($cmd eq 'MOVE_MTN'){ + $failure = 1 if not exists $fdat{'target'}; + $args = 'TARGET='.$fdat{'target'}; + }elsif($cmd eq 'INCARNATE'){ + my $count = (exists $fdat{'count'}) ? $fdat{'count'} : 1; + $args = 'COUNT='.$count; + }elsif($cmd eq 'PLAGUE'){ + $failure = 1 if not exists $fdat{'type'}; + $args = 'TYPE='.$fdat{'type'}; + }# elsif($cmd eq 'DESTROY'){ + + + my $ub = $udat{-back}; + delete $udat{-back}; + + if($failure) + { + $out = $db->loc('CMD_ERROR_MSG')."<p>\n"; # unknown, illegal or incomplete command + $out .= '<form method="get" action="'.$ub.'">' + .'<input type="submit" value="'.$db->loc('FORM_BACK_BUTTON').'"></form><p>'; + print OUT $out; + }else{ + $args = '' if not $args; + $aym->insert_command($cmd,$args,$loc) unless $failure; + $db->commit(); + + # redirect to field + $http_headers_out{'Location'} = $ub; + } +-] + +[$ else $] + + Hey, kein Befehl ?!?! + +[$ endif $] diff --git a/html/doc/Makefile b/html/doc/Makefile new file mode 100644 index 0000000..9d126e1 --- /dev/null +++ b/html/doc/Makefile @@ -0,0 +1,116 @@ +# Makefile for Aymargeddon documentation +# TODO: BUG: macht immer alles (liegt an +* nicht im target) + +LYX2HTML = lyx --export html +LYX2PDF = lyx --export pdf +FICK2DEATH = fig2dev + +INSTALL_SERVER = aymargeddon.de +INSTALL_DIR = /home/benni/aymargeddon_current/doc/ + +DIRS = +FILES_BIN = +FILES_LIB = +FILES_DOC = Regeln.lyx Techdoc.lyx ay_ein_hex.fig +FILES_MISC = +FILES = Makefile $(FILES_IN) $(FILES_DOC) $(FILES_MISC) +FILES_OUT = ay_ein_hex.eps Regeln.pdf \ + Regeln.html Techdoc.pdf Techdoc.html $(FILES_MISC) + + +all: $(FILES_OUT) + +#Regeln.html: Regeln.tex +# $(LATEX2HTML) $(LATEX2HTML_OPT) < Regeln.tex > Regeln.html +# +#Techdoc.html: Techdoc.tex +# $(LATEX2HTML) $(LATEX2HTML_OPT) < Techdoc.tex > Techdoc.html + +clean: + rm -f $(FILES_OUT) + rm -rf Regeln + rm -rf Techdoc + rm -rf auto + rm -f *.aux + rm -f *.log + rm -f *.ps + rm -f *.dvi + rm -f *~ + rm -f *.toc + rm -f *.png + rm -f *.ps.gz + rm -f *.tex + rm -f +* + +realclean: clean + + + +#release: clean have_to_make +# @if [ -z "$(RELDIR)" ] ; then \ +# echo "Sorry, release directory is not set!" 1>&2 ; \ +# exit 1 ; \ +# fi ;\ +# if [ ! -d $(RELDIR) ] ; then mkdir $(RELDIR) ; fi ; \ +# tar cf - $(FILES) | \ +# ( cd $(RELDIR) ; tar xf - ) +# for i in $(DIRS) ; do \ +# ( cd $$i ; \ +# $(MAKE) RELDIR=../$(RELDIR)/$$i $@ ) ; \ +# done + +install: all + +# hier muss dann das angepasste push-script hin + +# @if [ "X$(RELEASE)" = "X" ] ; then \ +# echo "Sorry, this isn't released source" 1>&2 ; \ +# exit 1 ; \ +# fi ;\ +# for i in $(INSTALLDIRS) ; do \ +# if [ ! -d $$i ] ; then mkdir -p $$i ; fi ; \ +# done ;\ +# for i in $(FILES_DOC) ; do \ +# cp $$i $(DOCDIR)/$$i ; \ +# chmod 555 $(DOCDIR)/$$i ; \ +# chown bin:bin $(DOCDIR)/$$i ; \ +# echo "Installed $(DOCDIR)/$$i" ; \ +# done +# for i in $(DIRS) ; do \ +# ( cd $$i ; ${MAKE} RELEASE=$$RELEASE PREFIX=$(PREFIX) install ) ; \ +# done + +# have_to_make: + +.SUFFIXES: +.SUFFIXES: .pdf .lyx .eps .fig .html + +.fig.eps: + $(FICK2DEATH) -L ps $(FICK2DEATH_OPT) $< +$@ + +# TeX to DVI +#.tex.dvi: +# $(LATEX) $< < /dev/null > /dev/null 2>&1 +# $(LATEX) $< < /dev/null > /dev/null 2>&1 + +# DVI to PS +#.dvi.ps: +# $(DVIPS) -o $@ $< + +# PS to PDF +#.ps.pdf: +# $(PS2PDF) $< $@ + +# LyX to TeX +#.lyx.tex: +# $(LYX2LATEX) $< > /dev/null 2>&1 && mv -f $@ +$@ + +# LyX to PDF +.lyx.pdf: + $(LYX2PDF) $< > /dev/null 2>&1 && mv -f $@ +$@ + +# LyX to HTML +.lyx.html: + $(LYX2HTML) $< > /dev/null 2>&1 && mv -f $@ +$@ + + diff --git a/html/doc/README b/html/doc/README new file mode 100644 index 0000000..486fcb0 --- /dev/null +++ b/html/doc/README @@ -0,0 +1,11 @@ +german below! + +There is currently no rules or other documentation in english. use the +sourcecode or ask at the mailinglist, if you want to know something. + +------------------------ + +Die Dateien in diesem Verzeichnis sind nicht auf dem neuesten Stand. +Die Regeln werden inzwischen im Wiki gepflegt: + +http://www.aymargeddon.de/wiki/index.php/Regeln diff --git a/html/doc/Regeln.lyx b/html/doc/Regeln.lyx new file mode 100644 index 0000000..d52001d --- /dev/null +++ b/html/doc/Regeln.lyx @@ -0,0 +1,2397 @@ +#LyX 1.3 created this file. For more info see http://www.lyx.org/ +\lyxformat 221 +\textclass article +\language german +\inputencoding latin1 +\fontscheme default +\graphics default +\paperfontsize 11 +\spacing single +\papersize a4paper +\paperpackage a4 +\use_geometry 0 +\use_amsmath 0 +\use_natbib 0 +\use_numerical_citations 0 +\paperorientation portrait +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip bigskip +\quotes_language polish +\quotes_times 2 +\papercolumns 1 +\papersides 1 +\paperpagestyle default + +\layout Title + +Die letzten Tage von Aymargeddon +\layout Author + +Aymargeddon Development Team +\layout Date + +17. + April 2005 +\layout Standard + + +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +tableofcontents +\backslash +newpage +\end_inset + + +\layout Section + +Einleitung +\layout Quotation + + +\emph on + +\begin_inset Quotes pld +\end_inset + +Es ist nicht leicht, ein Gott zu sein +\begin_inset Quotes prd +\end_inset + + (Titel eines Buches der Brüder Strugatzkij) +\layout Standard + +Während in den himmlischen Sphären der entscheidende Kampf zwischen Gut + und Böse ausgefochten wird, kämpfen auf Erden Elfen gegen Zwerge, Menschen + gegen Halblinge und jeder gegen jeden. + Soweit das Fantasy-Klischee. + Doch jetzt kommen wir zum Spiel: +\layout Standard + + +\series bold +\shape smallcaps +Die letzten Tage von Aymargeddon +\series default +\shape default + wird von mindestens acht Spielern gespielt. + Höchstens ein Drittel der Spieler übernimmt die Aufgabe eines Gottes. + Die restlichen zwei Drittel spielen jeweils ein Volk auf der Erde. + Am Ende gibt es zwei Sieger: den himmlischen Sieger, der zwischen den Göttern + ermittelt wird, und den Sieger der Erdlinge, den die restlichen Spieler + zwischen sich ausmachen. +\layout Standard + + +\series bold +Himmlischer Sieger +\series default +ist der Gott, der am Ende in der +\series bold +letzten Schlacht +\series default + auf der +\series bold +Insel des Schicksals +\series default +, der +\series bold +Aymargeddon, +\series default + am meisten Kräfte auf sich vereinigen kann. + Der Ort der letzten Schlacht wird einer von mehreren +\series bold +Manapolen +\series default + sein - abgelegene Inseln, auf denen die magischen Kraftlinien zusammenlaufen. + In der letzten Schlacht kämpfen die +\series bold +Avatare +\series default + der Götter, aber auch die Geister verstorbener +\series bold +Helden +\series default + der Erdlinge. + +\layout Standard + +Der +\series bold +Sieger der Erdlinge +\series default + ist der Spieler, der am Ende die meisten +\series bold +Städte +\series default + sein eigen nennt. + +\layout Standard + +Zweite Plätze gibt es weder bei den Göttern noch bei den Erdlingen. + Es geht immer um den Kampf ums Ganze, um Alles oder Nichts. +\layout Standard + +Die Interaktion zwischen den beiden Ebenen wird durch +\series bold +Priester +\series default + und +\series bold +Götteraktionen +\series default + möglich. +\layout Standard + +Das +\series bold +Spiel endet, +\series medium + sobald alle +\series bold +heiligen Berge +\series default +und +\series bold + gesegneten Inseln mit Tempeln +\series default + bebaut +\series medium +sind +\series default +. + +\series medium +Die Tempel bauen die Erdlinge, Götter können sie nur zerstören. + +\layout Standard + +Je mehr Priester an einem Tempel +\series bold +beten +\series default +, um so mehr +\series bold +Mana +\series default + erhält der jeweilige Gott und um so mehr Aktionen kann er machen. +\layout Standard + + +\series bold +Beide Ebenen +\series medium +sind aufeinander angewiesen, da Götter ohne den guten Willen der Erdlinge + kein +\series default + Mana und somit keinerlei Macht +\series medium + haben und die Erdlinge die Unterstützung der Götter in ihren irdischen + Dingen dringend brauchen. + Durch diese enge Verzahnung der beiden Spielebenen ist man immer zu +\series bold +Verhandlungen +\series medium + gezwungen. +\layout Standard + +Der +\series bold +Glücksfaktor +\series default + wird von den Spielern selbst bestimmt. + Kämpfe werden durch einen Zufallswert mitbestimmt. + Den Maximalwert des Zufalls (3 - 12) müssen die Götter bestimmen (auch + diese Aktion kostet sie natürlich Mana). + +\layout Standard + +Am +\series bold +Schluss +\series medium + ist es vor allem nötig +\series default +, +\series medium + einen Partner zu haben, der stark genug ist +\series default +, +\series medium + um auch an einem Spielende interessiert zu sein +\series default + oder schwach genug, um sich mit einem hinteren Platz zufrieden zu geben +\series medium +. + So werden treue Verbündete, mit denen man das ganze Spiel gemeinsam bestritten + hat, oft noch einmal kurz vor Schlu +\series default +ss +\series medium + fallengelassen. +\layout Standard + +Die +\series bold +Erdlinge +\series medium +spielen +\series default +mit +\series bold +Kriegern +\series default +, Helden (von Göttern erzeugt) und Priestern. + Üblicherweise werden nur die ersten Priester von Göttern erleuchtet, danach + machen die Tempel diese Arbeit. + Sie können Tempel bauen, Städte erobern und Archen steuern. +\layout Standard + +Die +\series bold +Götter +\series medium +spielen +\series default + mit ihren Avataren, können aber auch Tempel zerstören, Archen erschaffen, + Felder überfluten, Seuchen herbeirufen, Priester und Helden erzeugen und + den Glücks +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +- +\end_inset + +fak +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +- +\end_inset + +tor verändern. + Doch das alles kostet sie Mana. +\layout Standard + +Die Welt ist in viele kleine sechseckige Spielfelder unterteilt. + Die Größe des Spielfeldes wird durch die angestrebte Spieleranzahl bestimmt. + +\layout Standard + +Gespielt wird über einen üblichen Web-Browser. + Es gibt keine Spielrunden, sondern jeder Befehl braucht eine gewisse Zeit, + bis er ausgeführt wird. + Die Spielgeschwindigkeit kann dabei variieren. +\layout Standard + +An dieser Stelle möchten wir einmal ganz laut und deutlich allen Testspielern + des Brettspieles und der Pbem-Version danken, ohne die auch diese Online-Versio +n nicht möglich geworden wäre! +\layout Section* + + +\family sans +\series medium +\size large +\emph on +WARNUNG: +\layout Standard + + +\family sans +\emph on +Sowohl die verschiedenen beteiligten Programme als auch diese Regeln sind + noch in einem Test-Stadium. + Wir bitten also insbesondere alle Testspieler, uns darauf hinzuweisen, + wenn es Unterschiede zwischen diesem Dokument und dem realen Verhalten + des Spiels gibt. + Außerdem bitten wir Euch, Euch in die Ragnarök-Mailingliste einzutragen + ( +\begin_inset Quotes pld +\end_inset + +subscribe ragnaroek +\begin_inset Quotes prd +\end_inset + + nach majordomo@cs.uni-frankfurt.de schicken). + Helft mit, dass Aymargeddon besser wird! Wer will, kann auch gerne selbst + programmieren helfen. + Der Quellcode steht in einem tla-Archiv auf www.aymargeddon.de zur Verfügung. +\layout Section + +Die Welt +\layout Quotation + + +\emph on + +\begin_inset Quotes pld +\end_inset + +Wenn man eine Rolle lange genug spielte, vermischten sich langsam Fiktion + und Realität... + Rache war etwas für Götter. +\begin_inset Quotes prd +\end_inset + + (aus: +\begin_inset Quotes pld +\end_inset + +Ragnarök +\begin_inset Quotes prd +\end_inset + + von D.G.Compton und John Gribbin) +\layout Standard + +Die Welt besteht aus Sechsecken und hat keinen Rand. + Man kann in jede Richtung laufen und kommt wieder zum Ausgangspunkt zurück + (Torus). + Hier ein Screenshot vom Hauptbildschirm, damit Ihr eine Vorstellung davon + bekommt, wie die Welt aussieht. +\layout Standard +\align center +<BILD FEHLT NOCH> +\layout Standard + +In dieser Welt kann man sich in sechs verschiedene Richtungen bewegen, die + man sich folgendermaßen vorstellen kann: +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center +<BILD KAPUTT> +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center + +\begin_inset Graphics + filename +ay_ein_hex.eps + display monochrome + width 50text% + +\end_inset + + +\layout Standard + +Jeder Erdling beginnt bei seiner Heimatstadt. + Diese ist schwerer zu erobern und produziert mehr Krieger als normale Städte. + Jeder Gott hat zwei heilige Berge, an denen nur er angebetet werden kann. +\layout Standard + +Es dürfen immer nur Einheiten von einem Erdling in einem Feld stehen, das + somit einen eindeutigen Eigentümer hat. + Heimatstädte erinnern sich immer an ihre rechtmäßigen Herrscher. + Sie verteidigen sich auch ohne Krieger, und sie gehören einem wieder, sobald + die Besatzungsmacht abgezogen ist. +\layout Standard + +Besondere Felder sind die Manapole, zu ihnen strebt das ganze Denken der + Götter ihrem Wesen nach. + Einer der Manapole ist immer die Insel des Schicksals. + Manapole sind immer komplett von Wasserfeldern ohne gesegnete Inseln umgeben. +\layout Standard + +Außerdem gibt es noch Wasser und Inseln. + Inseln sind immer gesegnet, man kann dort also immer Tempel bauen, außer + es handelt sich um einen Manapol. + Über Wasser darf man sich als Erdling nur bewegen, wenn im Ausgangsfeld + eine Arche ist. + Avatare dürfen sich nur dann über Wasser bewegen, wenn ein Erdling gleichzeitig + die Arche steuert. + Die Archen bewegen sich mit den Erdlingen mit und haben ein unbegrenztes + Fassungsvermögen. + Die Götter sind also auf die Mithilfe der Erdlinge angewiesen, wenn sie + ihre Avatare in die letzte Schlacht, die auf der Insel des Schicksals stattfind +et, schicken wollen. +\layout Standard + +Welcher Manapol Aymargeddon ist, ändert sich im Laufe des Spiels. + Es ist immer der Manapol, der dem neuesten und schönsten Tempel am nächsten + ist. + Avatare bewegen sich leichter in Richtung Aymargeddon als von ihr weg. + Sie dürfen die Insel des Schicksals nicht verlassen, so lange sie Aymargeddon + ist. +\layout Subsection* + +Topologie +\layout Standard + +Felder haben immer zwei Koordinaten. + Das Spielfeld hat keinen Rand, wenn man sich in einer Richtung über den + vermeintlichen Rand bewegt, kommt man auf der gegenüberliegenden Seite + wieder raus. + Die folgende Karte mit den Koordinaten der Felder demonstriert das: +\layout Standard +\align center +<BILD FEHLT NOCH> +\layout Standard + +Eine Welt ist immer doppelt so breit wie hoch. + Nur so kann man in allen Richtungen immer geradeaus laufen und kommt doch + immer wieder am Ausgangspunkt an. +\layout Subsection* + +Produktion +\layout Standard + +Alle Städte erzeugen automatisch in gewissen Zeitabständen Krieger. + Heimatstädte erzeugen doppelt so schnell Krieger, sie tun dies manchmal + auch, wenn sie das Feld von feindlichen Einheiten besetzt wird, dann kommt + es zu Aufständen der heimatlichen Bevölkerung in regelmäßigen Abständen. + Normale Städte erzeugen umso häufiger Krieger, je kürzer der Zeitpunkt + ihres letzten Besitzerwechsels her ist. + +\layout Standard + +Tempel erzeugen in gewissen Zeitabständen Priester. + Es werden keine Priester erzeugt, wenn nicht schon rechtgläubige Priester + dort sind. +\layout Section + +Aktionen +\layout Standard + +Jede Aktion eines Spielers wird sofort in eine Datenbank geschrieben. + Die Aktionen werden jedoch erst zu einem späteren Zeitpunkt ausgeführt. + Wie lange das dauert, hängt von der Aktion ab (siehe Abschnitt Timing). + Einheiten sind wärend dieser Zeit inaktiv. +\layout Subsection* + +Aktionen für alle Spieler +\layout Subsubsection* + +Status ändern +\layout Standard + +Mit dieser Aktion kann man seine generelle Haltung anderen Spielern gegenüber + - seien sie Götter oder Erdlinge - ändern. + Man kann andere Spieler als Freund, als Feind oder neutral ansehen. + Man kann ihnen Sichtrechte gewähren oder sie verweigern. + +\layout Standard + +Das hat an einigen Stellen Auswirkungen, die dort dann näher beschrieben + sind. + Zu Spielbeginn ist man allen anderen Spielern gegenüber neutral eingestellt + und gewährt ihnen keine Sichtrechte. +\layout Subsection* + +Aktionen der Erdlinge +\layout Standard + + +\series bold +Bewegen +\layout Standard + +Dies bedeutet, dass man eine bestimmte Anzahl Krieger, Helden oder Priester + in ein Nachbarfeld bewegen will. + Dies kann zu Kampfhandlungen führen, wenn sich am Ende des Zuges noch Einheiten + anderer Erdlingsspieler auf dem Zielfeld aufhalten. + +\layout Standard + +Erdlinge können die Manapole nicht betreten. + Ihre toten Helden werden automatisch direkt nach einem Kampf zur Aymargeddon + transferiert. +\layout Standard + +Helden bewegen sich doppelt so schnell wie Krieger und kämpfen doppelt so + gut. + +\layout Standard + +Wasser- und Inselfelder können nur betreten werden, wenn im Startfeld eine + Arche steht, die einen dorthin bringen kann. + +\layout Standard + +Archen bewegen sich immer automatisch mit Erdlingen mit außer bei der Bewegung + zwischen Landfeldern. + Wenn Erdlingseinheiten oder Avatare in einem Wasserfeld zurückbleiben, + aus dem sich eine Arche entfernt, ertrinken sie jämmerlich. + Ertrinkende Helden streiten nicht in der letzten Schlacht, ebensowenig + wie ertrinkende Avatare. + Auf Inselfeldern können sie jedoch überleben. +\layout Standard + +Das Bewegen von einem Wasser- oder Inselfeld auf ein benachbartes Landfeld + ist immer möglich auch ohne Arche. + +\layout Standard + +Das Bewegen in das Feld eines Alliierten scheitert +\begin_inset Foot +collapsed true + +\layout Standard + +Böse Zungen nennen das die Olf-Bodo-Regel ;-) +\end_inset + +. + Ebenso scheitert die Bewegung, wenn im Zielfeld bereits ein Kampf stattfindet + an dem ich nicht beteiligt bin. + So wird gewährleistet, dass an einem Erdlingskampf immer nur zwei Spieler + beteiligt sein können. + Das Bewegen scheitert allerdings erst am Schluss der Bewegung. + Sie müssen sich dann wieder zurück bewegen. + +\layout Standard + +Man kann somit fast lückenlos Felder übergeben. + Daraus ergibt sich, dass man Alliierte nicht angreifen kann, so lange sie + Freunde sind. + +\layout Subsubsection* + +Tempel bauen +\layout Standard + +Diese Aktion erzeugt auf einem Feld einen Tempel einer Gottheit. + Es ist nur möglich, Tempel zu erzeugen, wenn der Spieler mindestens einen + Priester der passenden Gottheit dort hat und das Feld ein heiliger Berg + oder eine gesegnete Insel ist. + Wenn es ein heiliger Berg ist, darf nur ein Tempel des Gottes gebaut werden, + dem der Berg gewidmet ist. + Auf jedem Feld kann es immer nur einen Tempel geben. +\layout Standard + +Tempel zu bauen geht am Anfang des Spiels recht schnell, dauert aber um + so länger, je mehr Tempel schon gebaut sind. + Jeder Erdling will schließlich den schönsten Tempel der Welt haben, und + das dauert natürlich seine Zeit. + Wenn alle Tempel gebaut sind, endet das Spiel sofort. + +\layout Standard + +Der Manapol, der dem neuesten Tempel am nächsten ist, wird zur Insel des + Schicksals. + Wenn mehrere Manapole gleich weit entfernt sind, bleibt die aktuelle Aymargeddo +n bestehen. + (noch nicht implementiert) +\layout Subsubsection* + +Schlachtordnung festlegen +\layout Standard + +Erdlinge können angeben in welcher Schlachtordnung ihre Armeen in den Krieg + ziehen. + Es wird eine Reihenfolge angegeben in der die Einheiten aufgestellt werden. + Mit der Reihenfolge kann jeder Erdling angeben, welche eigenen Einheiten + in vorderster Front stehen und somit zuerst sterben sollen. + So kann man zum Beispiel zuerst Krieger sterben lassen, dann Helden und + dann erst die Priester. +\layout Standard + +Die Reihenfolge gilt immer für die ganze Welt. +\layout Standard + +Die voreingestellte Reihenfolge ist: Krieger, Helden, Priester. + +\layout Standard + +Die Reihenfolge ist allerdings nicht absolut, sondern gibt nur die Wahrscheinlic +hkeit des Todes an. +\layout Standard + +Archen befinden sich immer in der letzten Reihe der Schlachtordnung. + Jede Arche, die +\begin_inset Quotes pld +\end_inset + +stirbt +\begin_inset Quotes prd +\end_inset + + wird mit einer gewissen Wahrscheinlichkeit versenkt und mit einer gewissen + Wahrscheinlichkeit vom Gegner erobert. +\layout Subsection* + +Aktionen der Götter +\layout Quotation + + +\emph on + +\begin_inset Quotes pld +\end_inset + +Wenn Dich das nächste Mal jemand fragt, ob Du ein Gott bist, sag ja. +\begin_inset Quotes prd +\end_inset + + (aus: Ghostbusters) +\layout Standard + +Alle folgenden Aktionen kosten Mana. + Neues Mana erhält ein Gott, wenn seine Priester an den richtigen Tempeln + beten. + Alle zehn Zeiteinheiten gibt es pro Priester und Tempel einen Manapunkt + (MP). +\layout Subsubsection* + +Avatar erschaffen +\layout Standard + +Ein Avatare erscheint immer an dem eigenen Tempel an dem am meisten eigene + Priester beten. + Ein Avatar kostet 5 MP. + +\layout Subsubsection* + +Held weihen +\layout Standard + +Ein Krieger kann nur an eigenen Tempeln zum Helden geweiht werden. + Das kostet 1 MP. +\layout Description + +Priester +\series medium + +\series bold +erleuchten +\layout Standard + +Einen Priester kann man nur aus einem Krieger erzeugen, wenn der Gott das + entsprechende Feld einsehen kann (siehe Sicht-Abschnitt). + Diese Aktion kostet 5 MP. + +\layout Subsubsection* + +Avatare bewegen +\layout Standard + +Avatare dürfen sich auch auf die Insel des Schicksals begeben (allerdings + nicht mehr von ihr weg). + Das Bewegen eines Avatars geht deutlich schneller als das Bewegen der Erdlinge + (Eine Zeiteinheit). + Es kostet immer 1 MP pro Feld und Avatar. + Avatare reisen umsonst auf Schiffen mit. +\layout Standard + +Avatare dürfen sich nicht auf Wasser- oder Inselfelder bewegen, ausser mit + einer Arche (von Erdlingen gesteuert). + Von Wasserfeldern aus, dürfen sie sich auch alleine auf Landfelder oder + Manapole bewegen. +\layout Subsubsection* + +Verseuchen +\layout Standard + +Ein Gott kann die Erde mit Seuchen überziehen. + Das hat unterschiedliche Auswirkungen je nach Art der Seuche. + Seuchen verbreiten sich mit einer gewissen Wahrscheinlichkeit auf Nachbarfelder + sowie bei Bewegungen von Erdlingseinheiten. + Die Anwesenheit von Priestern erhöht die Wahrscheinlichkeit, dass die Seuche + aufhört. + Die Kosten für Seuchen hängen von der Art der Seuche ab. + Zum Verseuchen benötigt man einen anwesenden Avatar und in dem Feld darf + gerade kein Götterkampf (s.u.) stattfinden. + +\layout Standard + +Verseucht sind immer ganze Felder, keine einzelnen Einheiten. + Städte stecken sich leichter an als Landfelder, Landfelder leichter als + Berge, Berge leichter als Inseln, Inseln leichter als Wasserfelder. +\layout Standard + +Es gibt zur Zeit drei verschiedene Seuchen: +\layout Standard + + +\begin_inset Tabular +<lyxtabular version="3" rows="4" columns="3"> +<features> +<column alignment="center" valignment="top" leftline="true" width="0"> +<column alignment="center" valignment="top" leftline="true" width="0"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Seuche +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Effekt +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Mana +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Influenza +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Städte und Tempel produzieren nicht mehr +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +10 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Pestilentia +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +50% aller Leute sterben +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +20 +\end_inset +</cell> +</row> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Ebola +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +100% aller Leute sterben +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +40 +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\layout Standard + +Wenn Leute sterben, so geschieht das nach den Regeln bei Erdlingskämpfen + (s.u.). +\layout Standard + +Eine Seuche hat alle 20 Zeiteinheiten erneut ihren in der Tabelle beschriebenen + Effekt. +\layout Subsubsection* + +Sintfluten +\layout Standard + +Avatare können eine Ebene oder einen Berg überfluten, die an ein Wasser- + oder Inselfeld grenzen, wenn sie vor Ort sind und in dem Feld gerade kein + Götterkampf(s.u.) stattfindet. + Eine Sintflut kostet nur 2 MP, dauert aber 40 Zeiteinheiten. + Berge werden durch Überfluten zu Inseln. + Dadurch ändert sich ihre Exklusivität, und von nun an können auch andere + Götter an ihnen angebetet werden. + Städte und Inseln kann man nicht überfluten. +\layout Standard + +Wenn zum Zeitpunkt des Flutens einer Ebene noch Einheiten im Feld sind, + benötigen sie eine Arche, um nicht unterzugehen. +\layout Subsubsection* + +Avatarstatus ändern +\layout Standard + +Jede Gruppe von Avataren eines Spielers in einem Feld hat einen Status. + Dieser kann +\series bold +\shape smallcaps +Helfe +\series default +\shape default +, +\series bold +\shape smallcaps +Block +\series default +\shape default + oder +\series bold +\shape smallcaps +Ignorieren +\series default +\shape default + sein. + Mit +\series bold +\shape smallcaps +Helfe +\series default +\shape default + hilft man befreundeten Erdlingen, wenn es zu Kämpfen kommt. + Mit +\series bold +\shape smallcaps +Block +\series default +\shape default + schlägt man sich mit verfeindeten Avataren, wenn diese ins Feld kommen. + Man kann immer nur eines von beidem gleichzeitig tun. + +\layout Standard + +Sich bewegende Avatare nehmen ihren Status mit. + Wenn zwei Gruppen von Avataren des selben Spielers zusammentreffen, wird + immer automatisch +\series bold +\shape smallcaps +Block +\series default +\shape default + vor +\series bold +\shape smallcaps +Helfe +\series default +\shape default + vor +\series bold +\shape smallcaps +Frieden +\series default +\shape default + für die neue gemeinsame Gruppe gewählt. + +\layout Subsubsection* + +Tempel zerstören +\layout Standard + +Götter können den Tempel eines anderen Gottes auf einer gesegneten Insel + zerstören. + Dort dürfen sich keine Priester eines anderen Gottes befinden, außerdem + braucht man einen eigenen Avatar in dem Feld und es darf dort kein Götterkampf + (s.u.) stattfinden. + Dieser Befehl kostet 5 MP. + Wenn nur noch ein Tempelfeld unbebaut ist, kann man keine Tempel mehr zerstören. + +\layout Standard + +Es gibt im Wesentlichen zwei Anwendungsfälle für diesen Befehl: +\layout Enumerate + +Ein Gott will eine gesegnete Insel übernehmen, damit ein +\begin_inset ERT +status Collapsed + +\layout Standard +ver +\backslash +-bün +\backslash +-de +\backslash +-ter +\end_inset + + Erdling ihm dort einen Tempel errichtet. + Dafür muss der alte Tempel zerstört werden. + +\layout Enumerate + +Ein Gott will das drohende Spielende hinauszögern, weil er für später bessere + Siegchancen sieht. + Danach sollte man Erdlinge dazu überreden, das leere Baufeld auch zu verteidige +n. + Wenn jedoch einmal der Baubefehl für den letzten Tempel gegeben ist, ist + es zu spät, das Ende der Welt noch aufzuhalten. +\layout Subsubsection* + +Glücksfaktor verändern +\layout Standard + +Mit diesem Befehl kann man angeben, ob man den globalen +\begin_inset ERT +status Collapsed + +\layout Standard +Glücks +\backslash +-fak +\backslash +-tor +\end_inset + +, der auf alle Kämpfe mit Ausnahme der letzten Schlacht angewandt wird, + erhöhen oder erniedrigen will. + Man gibt an, wie viele Manapunkte man investieren will. + Pro MP ändert sich der Glücksfaktor um einen Punkt auf einer Skala von + 3 bis 12. +\layout Standard + +Der Glücksfaktor ist immer für alle Spieler gleich hoch, es gibt also nur + einen Glücksfaktor für alle Spieler. +\layout Subsubsection* + +Arche bauen +\layout Standard + +Ein Gott kann auf einem Feld, dass er sieht, eine Arche bauen. + Steuern kann er sie nicht. + Die Arche gehört dem derzeitigen Feldeigentümer. +\layout Standard + +Eine Arche zu bauen kostet 5 MP und dauert 30 Zeiteinheiten. +\layout Section + +Beten +\layout Quotation + + +\emph on + +\begin_inset Quotes pld +\end_inset + +Wer Gott definiert, ist schon Atheist. +\begin_inset Quotes prd +\end_inset + + (Oswald Spengler) +\layout Standard + +Die Götter erhalten alle 10 Zeiteinheiten einen MP pro Tempel und pro rechtgläub +igem Priester an diesem Tempel ebenso ein MP. + Die Anzahl effektiv betender Priester pro Tempel ist allerdings auf den + aktuellen Glücksfaktor begrenzt. + An heiligen Bergen können doppelt so viele Priester effektiv beten. +\layout Section + +Infos +\layout Standard + +Folgende generelle Daten sind für alle Mitspieler jedezeit abrufbar. + Sie beziehen sich auf das ganze Spiel und nicht auf einzelne Felder. + +\layout Itemize + +Der aktuelle Glücksfaktor +\layout Itemize + +Die Anzahl nicht gebauter Tempel +\layout Itemize + +Die Stärke auf der Insel des Schicksals +\layout Itemize + +Die Anzahl der Avatare auf den Manapolen (noch nicht implementiert) +\layout Itemize + +Die Gesamtstärke jeden Erdlings (noch nicht implementiert) +\layout Itemize + +Die Anzahl der lebenden Avatare jedes Gottes (noch nicht implementiert) +\layout Itemize + +Die Anzahl der Priester jedes Gottes (noch nicht implementiert) +\layout Itemize + +Die Anzahl Städte jedes Erdlings +\layout Standard + +Dadurch kann man immer die Stärke eines anderen Spielers ungefähr einordnen + und sieht, wer auf dem Weg zum Sieg ist. +\layout Standard + +Erdlinge sehen außerdem noch die Sterbereihenfolge ihrer Einheiten. + Götter sehen ihren aktuellen Manastand. +\layout Subsection* + +Sichtrechte +\layout Standard + +Sichtrecht hat man für folgende Felder: +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center + +\begin_inset Tabular +<lyxtabular version="3" rows="3" columns="2"> +<features> +<column alignment="center" valignment="top" leftline="true" width="0pt"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0pt"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Götter +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Erdlinge +\end_inset +</cell> +</row> +<row> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +eigene Holys +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Heimatstädte +\end_inset +</cell> +</row> +<row bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +anwesende Priester oder Avatare +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +anwesende Priester, Krieger oder Helden +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\layout Standard + +Von Bergen aus sieht man zwei Felder weit, sonst nur eins. +\layout Standard + +Andere Spieler können einem Sichtrechte gewähren. + Dies tun sie durch den Allianzstatus +\begin_inset Quotes pld +\end_inset + +Alliiert +\begin_inset Quotes prd +\end_inset + + oder +\begin_inset Quotes pld +\end_inset + +Verrat +\begin_inset Quotes prd +\end_inset + +. + +\begin_inset Quotes pld +\end_inset + +Freund +\begin_inset Quotes prd +\end_inset + + gewährt keine Sichtrechte. +\layout Standard + +Als anwesend zählen auch nicht-aktive Einheiten (die sich zum Beispiel gerade + in der Bewegung befinden). +\layout Standard + +Wenn man Sichtrecht für ein Feld hat, kann man jederzeit die Infos zu diesem + Feld abrufen. +\layout Section + +Kampf +\layout Standard + +Götter können Erdlinge nicht direkt attackieren, sie können nur andere Erdlinge + bei diesen Angriffen unterstützen. + +\layout Standard + +Bei jedem Kampf außer der letzten Schlacht werden die Kampfstärken der beteiligt +en Einheiten addiert und zusätzlich ein Zufallswert zwischen eins und dem + Glücksfaktor dazugezählt. + +\layout Standard + +Jeder Kampf dauert eine gewisse Zeitspanne. + Alle in dieser Zeitspanne hinzustoßenden Einheiten nehmen am Kampf teil + oder werden vom Kampf ausgeschlossen. + In letzterem Fall kehren sie einfach wieder um. +\layout Subsection* + +Erdlingskampf +\layout Standard + +Ein Erdlingskampf wird ausgelöst, wenn Einheiten eines neutralen oder verfeindet +en Erdlings - im Folgenden Angreifer genannt - ein Feld betreten, dessen + Eigentümer im Folgenden Verteidiger genannt wird. + Alle Einheiten dieser beiden Parteien, die wärend der Kampfdauer zum Kampf + dazu stoßen, nehmen am Kampf teil. + Einheiten Dritter werden vom Kampf ausgeschlossen. + Eine Möglichkeit, sich aus einem einmal begonnenen Kampf herauszuhalten, + gibt es nicht. +\layout Standard + +Die Kampfstärke beider Seiten ergibt sich aus der Summe der Kampfstärken + der beteiligten Einheiten. + Beide Seiten eines Kampfes addieren einen Zufallswert, der zwischen 1 und + dem aktuellen Glücksfaktor liegt, zu ihrer Kampfstärke. + +\layout Standard + +Dem bisherigen Eigentümer reicht ein Unentschieden zum Sieg. + +\layout Standard + +Eine Partei, die einen Kampf verliert, muss ihre Überlebenden zurückziehen. + Alle Einheiten ziehen sich einzeln zurück. + +\layout Standard + +Dazu wird nach dem Zufallsprinzip eines der Nachbarfelder ausgewählt, das + dem Verlierer gehört oder neutral ist und in dem zum Zeitpunkt des Rückzuges + kein Kampf stattfindet. + Ein Rückzug ist wie eine normale Bewegung und braucht Zeit. + Archen ziehen sich immer zuerst zurück. + Archen auf Küstenfeldern können sich nur auf Wasser oder Inselfelder zurückzieh +en. + Andere Einheiten können sich nur auf Landfelder zurückziehen oder auf solche, + auf die sich bereits Archen zurückgezogen haben. +\layout Standard + +Es kann passieren, dass das Feld bei Ankunft der Flüchtenden auch schon + einem anderen Spieler gehört, dann kommt es dort direkt wieder zum Kampf. + Flüchtende Einheiten können also von Feld zu Feld gejagt und dabei aufgerieben + werden. + Ein gut geplanter Angriff auf breiter Front kann diese Regel bewusst ausnutzen. +\layout Standard + +Natürlich kann man beim Kämpfen auch zu schaden kommen: Der Verlierer verliert + die Hälfte der Kampfstärke des Gewinners (ohne Avatare und Flankierung) + an Leuten. + Der Gewinner verliert ein Viertel der Kampfstärke des Verlierers. + Der Gewinner behält mindestens eine Person (oder Arche), der Verlierer + verliert mindestens eine. + Die Schlachtordnung bestimmt wieviele Leute welcher Art anteilig sterben. +\layout Standard + +Sollte ein Spieler nach einem verlorenen Kampf keinerlei Rückzugsmöglichkeiten + mehr haben, sterben alle seine Einheiten in diesem Feld. + +\layout Standard + +Doch jetzt endlich zu den Kampfstärken: +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center + +\begin_inset Tabular +<lyxtabular version="3" rows="8" columns="2"> +<features> +<column alignment="center" valignment="top" leftline="true" width="0pt"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0pt"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Einheit +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Modifikator +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Priester +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++0 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Krieger +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++1 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Held +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++2 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Avatar +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +bis zu +4 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Heimatstadt +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++2 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Arche +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++3 +\end_inset +</cell> +</row> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +pro Flankierung +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" bottomline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++1 +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\layout Standard + +Dabei ist +0 nicht so sinnlos, wie es auf den ersten Blick aussieht: Sind + nur Prieser anwesend, können sie wenigstens auf ihr Würfelglück hoffen, + wenn sie angegriffen werden und tragen zur Avatarunterstützung bei, wenn + diese vorhanden ist. +\layout Standard + +Avatare kämpfen natürlich nur mit, wenn sie im Status +\begin_inset Quotes pld +\end_inset + +Helfe +\begin_inset Quotes prd +\end_inset + + sind, und Mannapunkte übrig haben (2 MP pro Kampf unabhängig von der Anzahl + Avatare). + Sie geben maximal 4 Punkte Bonus. + Dabei wird pro kämpfendem Erdling ein Punkt verbraucht (egal ob Krieger, + Held oder Priester). + +\layout Standard + +Den Flankierungsbonus erhält man für jedes benachbarte Feld, das folgende + Bedingungen erfüllt: +\layout Itemize + +Es muss einem selbst oder einem Spieler mit dem Status +\begin_inset Quotes pld +\end_inset + +Freund +\begin_inset Quotes prd +\end_inset + + oder +\begin_inset Quotes pld +\end_inset + +alliiert +\begin_inset Quotes prd +\end_inset + + gehören; +\layout Itemize + +der Eigentümer des Feldes muss zum Zeitpunkt des Kampfes noch aktive Einheiten + dort stehen haben; +\layout Itemize + +es darf nicht selbst umkämpft sein. + +\layout Itemize + +Es darf kein Wasserfeld sein. + Inseln flankieren aber ganz normal. +\layout Standard + +Dadurch kann man Gebiete, die aus zusammenhängenden benachbarten Feldern + bestehen, besser verteidigen. +\layout Subsection* + +Avatarkampf +\layout Quotation + + +\emph on + +\begin_inset Quotes pld +\end_inset + +Jetzt hast Du, tapferer Soldat, jetzt hast Du, streitbarer Mann, einen Ort, + wo Du ohne Gefahr kämpfen kannst, wo der Sieg Ruhm und der Tod Gewinn ist. +\begin_inset Quotes prd +\end_inset + + (Bernhard von Clairveaux, 1146 n.u.Z., zum zweiten Kreuzzug aufrufend) +\layout Standard + +Avatare haben immer einen von drei Zuständen. + Mit +\begin_inset Quotes pld +\end_inset + +Helfe +\begin_inset Quotes prd +\end_inset + + helfen sie Erdlingen, wie oben angesprochen. + Mit +\begin_inset Quotes pld +\end_inset + +Block +\begin_inset Quotes prd +\end_inset + + blockieren sie andere Avatare, um gegen sie zu kämpfen. + Ist ihr Zustand +\begin_inset Quotes pld +\end_inset + +Ignoriere +\begin_inset Quotes prd +\end_inset + +, wollen sie mit niemandem Streit. + Die Avatare eines Gottes in einem Feld können nur den gleichen Zustand + haben. + +\layout Standard + +Nur der Status +\begin_inset Quotes pld +\end_inset + +Block +\begin_inset Quotes prd +\end_inset + + kann zu Avatarkämpfen führen. + Dies geschieht, wenn +\layout Itemize + +einer der beiden den anderen als Feind betrachtet und er oder der andere + 'Blockieren' eingestellt hat, oder +\layout Itemize + +wenn zwei Götter aufeinander treffen, die einander beide 'Neutral' gegenübersteh +en aber beide 'Blockiere' eingestellt haben. +\layout Standard + +Zu Kämpfen kann es nur dann kommen, wenn Avatare in ein Feld ziehen oder + wenn der Avatarstatus auf blockieren geändert wird. + Für jeden schon anwesenden Gott wird einzeln ermittelt, ob es zu einem + Kampf mit dem Neuankömmling kommt. + Es kann dabei durchaus zu mehreren parallel verlaufenden Kämpfen kommen, + die auch im Folgenden einzeln abgewickelt werden. + Wenn ein Avatar in ein Feld kommt, in dem er schon vertreten ist, löst + das nie einen Kampf aus. +\layout Standard + +Avatarkämpfe kosten 2 MP unabhängig von der Anzahl der beteiligten Avatare. + Wenn ein Gott nicht mehr genügend MP hat, darf der Gott noch auf sein Würfelglü +ck hofen, aber seine Avatare kämpfen nicht mehr mit. +\layout Standard + +Avatarkämpfe dauern länger als die Kämpfe der Erdlinge; und da Avatare sehr + schnell sein können, kann man eventuell auch noch aus einiger Entfernung + Kräfte hinzuziehen. + Man darf Avatare nicht aus einem umkämpften Feld wegziehen, auch wenn man + an keinem der Kämpfe beteiligt ist. + +\layout Standard + +Sollte im selben Feld bereits ein Erdlingskampf stattfinden, so wird der + Avatarkampf bis nach dem Erdlingskampf verschoben. + +\layout Standard + +Jeder Avatar zählt +4, und es wird ganz normal gewürfelt. + Der Verlierer verliert die Hälfte der Avatare des Gewinners und der Gewinner + verliert ein Viertel der Avatare des Verlierers. + Bei einem unentschieden gelten beide Seiten als Verlierer. + Die Seelen sterbender Avatare fahren in eventuell anwesende Krieger des + Feldeigentümers und machen diese zu Helden. + Alle Avatare des Verlierers die danach noch im Feld sind werden an den + Ort der Avatarerschaffung zurückteleportiert. +\layout Standard + +Avatare, die in einem Götterkampf beschäftigt sind, dürfen keine Erdlinge + bei ihren Kämpfen unterstützen. +\layout Subsection* + +Die letzte Schlacht +\layout Standard + +In der letzten Schlacht wird nicht gewürfelt. + Es zählen nur die Kampfwerte: +\layout Standard +\added_space_top 0.3cm \added_space_bottom 0.3cm \align center + +\begin_inset Tabular +<lyxtabular version="3" rows="3" columns="2"> +<features> +<column alignment="center" valignment="top" leftline="true" width="0pt"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0pt"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Einheit +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Kampfwert +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Avatar +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++7 +\end_inset +</cell> +</row> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Geist eines Helden +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + ++1 +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\layout Standard + +Für die Geister der Helden zählt der angebetete Gott. + Diese Helden kämpfen also immer noch für ihren Gott, auch wenn der Erdling + inzwischen längst vom Glauben abgefallen ist. +\layout Section + +Timing +\layout Standard + +Alle Aktionen dauern unterschiedlich lange. + Dabei gibt es in jedem Spiel eine einstellbare Spielgeschwindigkeit, mit + der die Werte unten multipliziert werden. + Die Zahlen in der Tabelle können also sowohl Minuten als auch Tage meinen, + je nachdem wie schnell man spielt. + Die Spielgeschwindigkeit kann sich auch während eines Spieles ändern. + Es kann zum Beispiel sinnvoll sein, das Spiel am Anfang langsamer laufen + zu lassen, bis eine angemessene Anzahl Mitspieler eingestiegen ist. + Jede Änderung der Spielgeschwindigkeit wird rechtzeitig vorher bekannt + gegeben und sollte nicht zu apprupt erfolgen. +\layout Standard + + +\begin_inset Tabular +<lyxtabular version="3" rows="17" columns="2"> +<features islongtable="true"> +<column alignment="center" valignment="top" leftline="true" width="0pt"> +<column alignment="center" valignment="top" leftline="true" rightline="true" width="0pt"> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Aktion +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Dauer +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Krieger bewegen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +10 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Priester bewegen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +12 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Held bewegen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +6 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Avatar bewegen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +1 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Erdlingskampf +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +6 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Avatarkampf +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +10 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Tempel bauen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +3, 6 , 9, ... +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Überfluten +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +20 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Bewegen mit Arche +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +5 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Krieger produzieren +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +40 + N (20) +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Priester produzieren +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +40 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Glücksfaktor verändern +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +5 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Avatarstatus ändern +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +1 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Arche bauen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +30 +\end_inset +</cell> +</row> +<row topline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +Beten +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +10 +\end_inset +</cell> +</row> +<row topline="true" bottomline="true"> +<cell alignment="center" valignment="top" topline="true" leftline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +alle anderen Aktionen +\end_inset +</cell> +<cell alignment="center" valignment="top" topline="true" leftline="true" rightline="true" usebox="none"> +\begin_inset Text + +\layout Standard + +0 +\end_inset +</cell> +</row> +</lyxtabular> + +\end_inset + + +\layout Standard + + +\begin_inset ERT +status Collapsed + +\layout Standard + +\backslash +medskip +\end_inset + + +\layout Section + +Spielanfang +\layout Standard + +Die Götter starten mit 33 Mana. + Sie sollten daher zusehen, dass sie möglichst bald Priester erzeugen, damit + diese Tempel bauen können, die wieder Priester produzieren und damit wieder + Mana. + Dafür ist eine Kooperation mit mindestens einem Erdling nötig. +\layout Standard + +Die Erdlinge stehen am Anfang vor der Entscheidung, wo sie ihre ersten Krieger + hinschicken sollen. + Dies kann zum Beispiel auf ein Tempelfeld sein, weil man davon ausgeht, + dass der Krieger in einen Priester umgewandelt wird. + Außerdem ist es ratsam, sich früh mit seinen Nachbarn abzusprechen, wer + welchen Tempel baut. + Ansonsten kann es zu unliebsamen Überraschungen kommen, die einen gleich + die ersten Krieger verlieren lassen! +\layout Standard + +Der Glücksfaktor ist am Anfang auf seinem Minimalwert von 3. +\layout Standard + +Götter, die nachträglich einsteigen, erhalten etwas Bonusmana pro vergangener + Zeiteinheit. + Erdlinge, die neu einsteigen, profitieren davon, dass ihre Heimatstadt + schon die ganze Zeit Krieger produziert hat. +\layout Section + +Spielende (nur teilweise implementiert) +\layout Standard + +Das Spiel endet, sobald alle Tempel gebaut wurden. + Mit dem Baubefehl des letzten Tempels wird allen Spielern bekanntgegeben, + wie lange das Spiel noch dauert. + Dann gibt es kein Zurück mehr. +\layout Standard + +Es gewinnt der Erdling, der die meisten Städte sein eigen nennt. + Dabei zählen besetzte feindliche Heimatstädte und verseuchte Städte mit. + Bei gleicher Anzahl Städte entscheidet die Gesamtkampfstärke des Erdlings. + Sollte die auch gleich sein, wird gewürfelt. + +\layout Standard + +Der Gott, der in der letzten Schlacht die meisten Kräfte auf sich vereint, + gewinnt. + Dabei muss kein Mana mehr ausgegeben werden und es wird auch nicht mehr + gewürfelt. + Sollte die letzte Schlacht unentschieden ausgehen, zählen die Anzahl lebender + Avatare. + Wenn diese auch gleich sind, die Anzahl der Tempel. + Wenn dann immer noch Gleichstand herrscht, zählt das übrige Mana. + Sollte wider erwarten selbst dieses gleich sein, wird am Ende doch noch + gewürfelt. +\layout Standard + +Alle Spieler erhalten zum Abschluss eine Rangliste und den Ausgang der letzten + Schlacht. +\layout Standard + +Mit jedem Spiel kann man Punkte für die ewige Bestenliste sammeln, allerdings + nur als Sieger. + Zweite Plätze zählen nicht. +\layout Section + +FAQ +\layout Subsection* + +Was bedeutet +\shape italic +Aymargeddon +\shape default +? +\layout Standard + +Der Name des Spiels leitet sich von +\shape italic +Armageddon +\shape default + her. + Das wiederum basiert auf dem hebräischen +\shape italic +Har +\shape default +, was +\shape italic +Berg +\shape default + bedeutet, und der Ortschaft +\shape italic +Megeddon +\shape default +, bei der laut der Sage die letzte Schlacht geschlagen werden wird. + Da in unserem Spiel die letzte Schlacht auf einer Insel stattfindet, haben + wir +\shape italic +Har +\shape default + durch +\shape italic +Ay +\shape default + ersetzt, was +\shape italic +Insel +\shape default + bedeutet. + +\layout Standard + +Das +\begin_inset Quotes pld +\end_inset + +r +\begin_inset Quotes prd +\end_inset + + gehört da nicht wirklich hin, nein. + Aber wir haben das erst entdeckt, als wir die Domain schon bestellt hatten + und es klingt eh besser so, oder? Ausserdem gibt +\begin_inset Quotes pld +\end_inset + +Aymageddon +\begin_inset Quotes prd +\end_inset + + unanständige Suchergebnisse bei Google. +\layout Subsection* + +Heißt es +\shape italic +der +\shape default +, +\shape italic +die +\shape default +, oder +\shape italic +das +\shape default + Aymargeddon? +\layout Standard + +Kommt darauf an. +\layout Standard + +Wenn die Insel des Schicksals gemeint ist, heißt es +\shape italic +die +\shape default +, wenn das Spiel gemeint ist, heißt es +\shape italic +das +\shape default + und wenn der Server gemeint ist, heiß es +\shape italic +der +\shape default + Aymargeddon. +\layout Standard + +Das ist allerdings nur die Erdlingssicht. + Götter geben sich mit solch kleinlichen Geschlechterfragen nicht ab, wenn + es um Schicksalsfragen wie das Ende der Welt geht. +\layout Subsection* + +Gibt es Vorläufer zu Aymargeddon? +\layout Standard + +Das Spiel basiert auf einem - leider noch unveröffentlichten - Brettspiel + namens +\shape italic +Ragnarök +\shape default + beziehungsweise dem zugehörigen Play-by-E-Mail +\shape italic +Ragnarök als Pbem +\shape default +. + Beide Spiele hat Benni Bärmann entwickelt. + Die grundlegenden Konzepte sind erhalten geblieben. + Aber natürlich erforderte der geänderte Zugrhythmus und die höhere Spieleranzah +l einige Anpassungen. +\layout Subsection* + +Wie viel Zeit braucht Aymargeddon? +\layout Standard + +Das hängt von der Spielgeschwindigkeit ab. + +\layout Standard + +Bei niedriger Spielgeschwindigkeit braucht man sich nur gelegentlich einzuloggen +, um zu gucken, was es Neues gibt. + Dafür kann sich ein Spiel dann auch schon mal ein paar Monate hinziehen. + +\layout Standard + +Bei hoher Spielgeschwindigkeit sitzt man mehr oder weniger die ganze Zeit + vorm Rechner, dafür ist es dann aber auch nach ein paar Stunden vorbei. +\layout Standard + +Bei gleicher Spielgeschwindigkeit ist das Spiel als Gott tendenziell aufwendiger + als das als Erdling. + Als Erdling kann man fast sicher sein, nichts wichtiges zu verpassen, wenn + man sich so oft einloggt, wie ein Erdlingskampf dauert. +\layout Subsection* + +Was brauche ich, um mitspielen zu können? +\layout Standard + +Eigentlich nichts, außer einer funktionierenden E-Mail-Adresse und einem + üblichen Web-Browser. +\layout Standard + +Was man natürlich auch noch braucht, sind Spaß am Spiel, Verhandlungsgeschick, + etwas Zeit und ein bisschen Glück. +\layout Subsection* + +Wie sehen sinnvolle erste Züge als Erdling aus? +\layout Standard + +Man sollte sich auf jeden Fall möglichst bald mit den Göttern absprechen, + deren heilige Orte man sieht, beziehungsweise auf die Suche nach solchen + Orten gehen. + Danach sollte man möglichst Tempel bauen für die Götter, damit diese schnell + Mana kriegen, mit dem sie einen dann (hoffentlich) unterstützen. +\layout Standard + +Dabei ist es ratsam, auch die irdischen Nachbarn nicht zu vernachlässigen + und dafür zu sorgen, dass sie nicht in der Zwischenzeit alle strategisch + wichtigen Punkte unter sich aufteilen. +\layout Standard + +Wenn man erste Städte erobert hat, muß man sich überlegen ob man sofort + weiterzieht oder erst abwartet, bis dort ein Krieger erzeugt wird. + Im ersten Fall kommt man schneller voran und kann vieleicht weitere Städte + vor den Nachbarn erreichen, im zweiten Fall produziert man schneller neue + Krieger. +\layout Subsection* + +Wie sehen sinnvolle erste Züge als Gott aus? +\layout Standard + +Ein Gott sollte am Anfang hauptsächlich durch Verhandlungen abklären, welche + Erdlinge ihm möglichst bald Tempel auf seinen exklusiven heiligen Bergen + errichten. + +\layout Standard + +Bald kann man dann schon Avatare und möglicherweise sogar Helden erzeugen + und kriegt neues Mana. + +\layout Standard + +Es kann sinnvoll sein, die wertvollen Tempel mit Avataren zu schützen, damit + nicht kleinliche Streitereien zwischen Erdlingen den wertvollen Manastrom + verringern. +\layout Subsection* + +Können Erdlingsarmeen aneinander vorbeilaufen? +\layout Standard + +Ja. + +\layout Subsection* + +Gibt es nicht zu unausgewogene Startpositionen? +\layout Standard + +Gerade die Unausgewogenheit der Startpositionen zwingt zu Verhandlungen. + Deswegen werden die dafür relevanten Informationen (mit denen die Spieler + abschätzen können, wer führt) ja auch zur Verfügung gestellt. +\layout Subsection* + +Was passiert, wenn jemand aufhört? +\layout Standard + +Seine Einheiten bleiben einfach da stehen, wo sie sind, und rühren sich + nicht. + Krieger und Priester eines ausgestiegenen Erdlings werden aber noch weiterhin + erzeugt. + +\layout Standard + +Bei Göttern ist das lästiger als bei Erdlingen, da das Spielgleichgewicht + stärker beeinträchtigt wird. + Schön ist es natürlich in keinem Fall. + +\layout Standard + +Nichtaktive Spieler können jederzeit übernommen werden von Neueinsteigern. + +\layout Subsection* + +Was passiert, wenn ich eine Weile nicht ziehe? +\layout Standard + +Wenn das lange dauert, geht der Server davon aus, dass Du nicht mehr spielen + willst, und gibt Deine Einheiten zur Übernahme frei. + (noch nicht implementiert) +\layout Subsection* + +Soll ich einen Gott oder einen Erdling spielen? +\layout Standard + +Die Götterrolle ist die anspruchsvollere. + Man muß mehr verhandeln und hat mehr Möglichkeiten. + Das ist Vor- und Nachteil zugleich. + Ganz ohne Verhandlung wird man Aymargeddon nicht gewinnen können, aber + Leute, die nicht allzusehr auf Verhandlungen aus sind, sollten lieber eine + Erdlingsrolle übernehmen. + Man sollte auch nur einen Gott spielen, wenn man häufig online ist, da + Götteraktionen im allgemeinen weniger Zeit brauchen. +\layout Standard + +Beim Spielanfang kann man auch +\begin_inset Quotes pld +\end_inset + +egal +\begin_inset Quotes prd +\end_inset + + als gewünschte Rolle angeben. + Dann gibt einem der Server die Rolle, die dafür sorgt, dass das Zahlenverhältni +s 1:2 von Göttern zu Erdlingen annähernd erreicht wird. + Es kann auch vorkommen, dass in einem Spiel gar keine Erdlinge beziehungsweise + Götter mehr zugelassen sind, weil zu weit vom idealen Verhältnis abgewichen + wurde. +\layout Subsection* + +Gehören Städte, die ich einmal in Besitz genommen habe, mir auch noch, wenn + ich sie wieder verlasse? +\layout Standard + +Nein. + Alle Städte, die keine Heimatstädte sind, werden neutral, sobald kein aktiver + Priester, Krieger oder Held mehr in ihnen steht. + Heimatstädte gehören dem Spieler, dessen Heimat sie sind, jedoch auch, + wenn keine Einheiten dort stehen. + Heimatstädte verteidigen sich auch, ohne dass in ihnen Einheiten stehen + müssen. +\layout Subsection* + +Darf man mehrere Positionen im selben Spiel besetzen? +\layout Standard + +Nein, aber man darf in mehreren Spielen gleichzeitig mitspielen. +\layout Subsection* + +Warum sind Avatare wasserscheu? +\layout Standard + +Ist ja eigentlich schon etwas komisch, wo sie doch ansonsten so mächtig + sind. + Die Erklärung ist ganz einfach: Auf ihrer Reise zur Erde mussten sie entweder + in einem furchtbaren Gewitter auf einer Bergspitze erscheinen oder sich + von einer Insel ans nahe, rettende Ufer quälen. + Nach dieser Erfahrung hat niemand mehr Lust auf Wasser! +\layout Section* + +Copyright +\layout Standard + +(c) 2003, 2004, 2005 Aymargeddon Development Team +\layout Standard + +Permission is granted to copy, distribute and/or modify this document under + the terms of the GNU Free Documentation License, Version 1.1 or any later + version published by the Free Software Foundation; with no Invariant Sections, + with no Front-Cover Texts, and with no Back-Cover Texts. + A copy of the license is available at http://www.aymargeddon.de. +\the_end diff --git a/html/doc/Techdoc.lyx b/html/doc/Techdoc.lyx new file mode 100644 index 0000000..7614606 --- /dev/null +++ b/html/doc/Techdoc.lyx @@ -0,0 +1,823 @@ +#LyX 1.3 created this file. For more info see http://www.lyx.org/ +\lyxformat 221 +\textclass article +\language english +\inputencoding auto +\fontscheme default +\graphics default +\paperfontsize default +\spacing single +\papersize Default +\paperpackage a4 +\use_geometry 0 +\use_amsmath 0 +\use_natbib 0 +\use_numerical_citations 0 +\paperorientation portrait +\secnumdepth 3 +\tocdepth 3 +\paragraph_separation indent +\defskip medskip +\quotes_language english +\quotes_times 2 +\papercolumns 1 +\papersides 1 +\paperpagestyle default + +\layout Title + +Technisches zu +\begin_inset Quotes eld +\end_inset + +Die letzten Tage von Aymargeddon +\begin_inset Quotes erd +\end_inset + + +\layout Author + +Aymargeddon Development Team +\layout Date + +9.10.2003 +\layout Standard + + +\emph on +Warnung: Die Information in diesem Dokument ist zu nicht unerheblichen Teilen + veraltet. +\layout Section + +Generelles Design +\layout Standard + +Das Spiel besteht aus folgenden Komponenten: +\layout Enumerate + +Eine Relationale Datenbank +\layout Enumerate + +Ein Dämonprozess im Server +\layout Enumerate + +Serverseitige Scripten zur Benutzerinteraktion +\layout Enumerate + +Ein Weltengenerator +\layout Enumerate + +FROGS +\layout Enumerate + +Ein Programm, dass die Integrität der Datenbank überprüft +\layout Enumerate + +Eine Bibliothek für gemeinsame Funktionalität +\layout Standard + +Die Aufgaben dieser Komponenten stellen sich wie folgt dar: +\layout Section + +Datenbank +\layout Standard + +In dieser Datenbank wird der Zustand aller Spielwelten gespeichert. + Außerdem alle Spielerdaten, alle Spieleraktionen und alle Nachrichten an + Spieler. + Sie sorgt mittels ihrer Transaktionen dafür, dass auch bei konkurierendem + Zugriff die Datenintegrität immer erhalten bleibt. +\layout Standard + +Wir verwenden MySQL zur Implementierung und PhpMyAdmin zur Administrierung + der Datenbank. +\layout Standard + +Felder, die in vielen Tabellen vorkommen und immer wieder das selbe bedeuten: +\layout Description + +GAME Das ist die Id des Spiels. + Dadurch können alle Spiele in der selben Datenbank verwaltet werden. + Es kann maximal max(unsigned smallint) Spiele gleichzeitig geben. +\layout Description + +LOCATION Feldkoordinaten auf dem Hexraster-Torus. + Ein String der Form <x>_<y>. + Die maximale Größe der Welt ist max(unsigned smallint) für die Y-Koordinate + und max(unsingend smallint)*2 für die X-Koordinate. +\layout Description + +PLAYER,OWNER,... + Spieler-Ids. + Die Spieler-Ids bezeichnen den Spieler +\emph on +unabhängig +\emph default +von seiner Rolle. + Sie gilt spielübergreifend. + Die maximale Anzahl Spieler ist auf max(signed smallint) beschränkt. +\layout Subsection + +Bewegung und Kämpfe +\layout Standard + +Einheiten, die sich bewegen, bleiben im Feld stehen, werden aber auf nicht + available gesetzt. + Am Ende des Befehls werden sie in das neue Feld gesetzt. + Sie werden nur wieder aktiv, nachdem alle denkbaren Kämpfe ausgeführt wurden. +\layout Standard + +Kämpfe werden als Quasi-Befehl wieder in die Befehlsqueu geschrieben. + Erst nach Ablauf dieses Quasi-Befehls wird ausgewertet, welche Einheiten + auf welcher Seite am Kampf teilnehmen. +\layout Standard + +Einheiten, die sich zurückziehen, werden ganz normal bewegt. +\layout Subsection + +Tabelle MAP +\layout Standard + +Das ist die zentrale Karte. + Für jedes Feld in jedem Spiel gibt es genau einen Eintrag. +\layout Description + +HOME Eigentümer der Heimatstadt. + Das Feld ist -1, wenn es eine Heimatstadt ist, aber noch niemand spielt. +\layout Description + +OCCUPANT Besitzer des Feldes +\layout Description + +TERRAIN kann sein eins aus: WATER, CITY, MOUNTAIN, ISLE, PLAIN +\layout Description + +PLAGUE ist das Feld verseucht? Kann eine aus einer Liste von Seuchen sein +\layout Description + +ATTACKER Hier steht der leitende Erdling eines Angriffs drinnen so lange + gekämpft wird. + 0 sonst. + Man kann hier also auch ablesen, ob das Feld umkämpft ist. +\layout Description + +LAST_PRODUCE Zu dieser Zeit wurde zu letzt ein Krieger (bei Städten) bzw. + ein Priester (bei Tempeln) produziert. + Der Dämon entscheidet anhand dieser Daten, wann neue Einheiten produziert + werden. +\layout Description + +FLUXLINE Hier stehen die Richtungen, in die sich Avatare momentan kostenlos + bewegen können. + Die benachbarten Richtungen kosten 1 MP, alle anderen 2MP. + Dieses Feld wird bei einer Änderung der IdS für die gesamte Karte neu berechnet. +\layout Description + +TEMPLE Steht auf 'Y', wenn dort ein Tempel gebaut wurde, auf 'N' sonst. +\layout Subsection + +Tabelle MOBILE +\layout Standard + +In dieser Tabelle werden alle beweglichen Objekte abgespeichert. + Das sind also zunächst: Krieger, Helden, Priester, Avatare und Archen. + Dabei gibt es nur einen Eintrag für gleichartige Einheiten im selben Feld + im selben Spiel. +\layout Standard + +Manche Felder werden nur für manche Objekttypen benutzt. + Hier wird also ein bisschen Speicherplatz geopfert um die Struktur möglichst + einfach zu halten. +\layout Description + +ID Eine eindeutige ID. +\layout Description + +TYPE Ist einer aus WARRIOR, HERO, PRIEST, AVATAR, ARK +\layout Description + +OWNER Der Spieler, der die Einheit steuert +\layout Description + +ADORING Der Gott, den der Priester anbetet +\layout Description + +COUNT Anzahl +\layout Description + +AVAILABLE Wird auf 0 gesetzt, wenn die Einheit beschäftigt ist (sich also + z.B. + bewegt) +\layout Description + +STATUS Eines aus HELP, BLOCK, PEACE. + Avatarstatus. +\layout Subsection + +Tabelle COMMAND +\layout Standard + +In diese Tabelle tragen die Scripten die Aktionen der Spieler ein und der + Dämon führt diese dann aus. + Zusätzlich kommen hier auch noch die Quasi-Befehle des Dämons selber rein. + Das ist alles, wo er sich für später dran errinnern will. + Zur Zeit wird dieser Mechanismus nur für Kämpfe benötigt. +\layout Description + +TIME Die Zeit zu der das Kommando eingetragen wurde +\layout Description + +ACK Hier wird vermerkt, dass der Dämon das Kommando zur Kenntnis genommen + hat, aber noch nicht ausgeführt. + Das ist nötig weil bei vielen Kommandos schon am Anfang Nachrichten generiert + werden müssen, lange bevor sie ausgeführt werden. + Z.B. + erhalten die Eigentümer eines Feldes, in das man sich bewegt, eine Nachricht, + schon wenn man sich auf den Weg macht. +\layout Description + +DONE Hier werden abgearbeitete Befehle vermerkt +\layout Standard + +Alle drei Felder sind Timestamps und müssen immer GMT enthalten! +\layout Subsection + +Tabelle MESSAGE +\layout Standard + +In diese Tabelle trägt der Dämon Nachrichten an die Spieler ein und die + Scripten zeigen diese dann an. + Nachrichten an Alle Spieler müssen für jeden Spieler einzeln eingetragen + werden. + Wenn man es anders machen wollte, müsste man wiederum für jeden Spieler + vermerken, welche Nachrichten er nicht mehr sehen will, was fast auf das + selbe rauskommt. + +\layout Description + +TIME Der Zeitpunkt, an dem die Nachricht generiert wurde +\layout Description + +FROM Der Absender. + 0 bedeutet, dass es eine automatisch generierte Nachricht des Dämon ist. +\layout Description + +TO Der Empfänger +\layout Description + +TYPE Message, Error, Warning, ... +\layout Description + +MSG Die eigentliche Meldung. + Bzw. + ein Tag, dass erst noch lokalisiert werden muss (Siehe Tabelle LOCALIZE) +\layout Description + +ARG1...4 Die Argumente für die Lokalisierung. +\layout Subsection + +Tabelle GAME +\layout Standard + +Hier stehen allgemein Infos das Spiel betreffend. + Pro Spiel gibt es nur einen Eintrag. +\layout Description + +SIZE Die Größe des Spiels. + Höhe und halbe Breite des Spielfeldes. + Maximale Anzahl Erdlinge. +\layout Description + +FORTUNE Der Glücksfaktor +\layout Description + +LAST_TEMPLE Die LOCATION des letzten fertig gestellten Tempels. +\layout Description + +TEMPLE_SIZE Größe des nächsten Tempels. +\layout Subsection + +Tabelle PLAYER +\layout Standard + +Hier wird spielunabhängig gespeichert, was es alles über einen Spieler zu + wissen gibt. + Pro Spieler ein Eintrag. +\layout Subsection + +Tabelle ALLIANCE +\layout Standard + +Hier wird beschrieben welche Freunde und Feinde man hat. + Pro Spieler-Spieler-Relation in jedem Spiel höchstens ein Eintrag. + Status kann sein +\begin_inset Quotes eld +\end_inset + +FRIEND +\begin_inset Quotes erd +\end_inset + +, +\begin_inset Quotes eld +\end_inset + +FOE +\begin_inset Quotes erd +\end_inset + + oder +\begin_inset Quotes eld +\end_inset + +NEUTRAL +\begin_inset Quotes erd +\end_inset + +. + Wenn kein Eintrag vorhanden ist, wird neutraler Status angenommen. + +\layout Standard + +Man beachte dass Spieler A, Spieler B als Freund ansehen kann, wärend umgekehrt + Spieler B Spieler A als Feind betrachtet! +\layout Subsection + +Tabelle GOD +\layout Standard + +Hier werden Daten für die Götter gespeichert. + Pro Gott und Spiel ein Eintrag. +\layout Description + +DEATH_AVATAR Die Anzahl der für diesen Gott in diesem Spiel gestorbenen + Avatare +\layout Description + +DEATH_HERO dsgl. + für Helden +\layout Description + +ARRIVAL Hier entstehen neue Avatare. + Dieser Ort wird nach jedem Tempelbau diesen Gottes neu berechnet. +\layout Subsection + +Tabelle LOCALIZE +\layout Standard + +Mit Hilfe dieser Tabelle kann die Darstellung in verschiedenen Sprachen + erfolgen. +\layout Description + +TAG Der Eintrag mit dem man wiederkennt, um welche Message es sich handelt +\layout Description + +LANG Die Sprache des Eintrags. + Zur Zeit werden nur +\begin_inset Quotes eld +\end_inset + +DE +\begin_inset Quotes erd +\end_inset + + und +\begin_inset Quotes eld +\end_inset + +EN +\begin_inset Quotes erd +\end_inset + + unterstützt. +\layout Description + +TEXT Der Text der Nachricht in den einzelnen Sprachen. + Dabei wird mittels +\begin_inset Quotes eld +\end_inset + +%n +\begin_inset Quotes erd +\end_inset + + das n.te Argument eingefügt. + +\begin_inset Quotes eld +\end_inset + +%% +\begin_inset Quotes erd +\end_inset + + gibt ein Prozentzeichen aus. + +\layout Subsection + +Tabelle ROLE +\layout Standard + +Hier wird die Rolle eines Spielers in einem Spiel beschrieben. + Pro Mitspieler in jedem Spiel ein Eintrag. +\layout Section + +Dämon +\layout Standard + +Dieses Programm liest Spieleraktionen aus der Datenbank, berechnet die sich + daraus ergebenden Ereignisse und schreibt Nachrichten an die Spieler zurück + in die Datenbank. +\layout Standard + +Wir verwenden Perl 5.8 zur Implementierung des Servers. +\layout Section + +Scripten +\layout Standard + +Sie lesen den Zustand der Welt und die Nachrichten aus der Datenbank, halten + Session-Informationen vor und bereiten dies alles in HTML zur Darstellung + mittels eines üblichen Web-Browsers auf. + Schließlich schreiben sie die Aktionen des Benutzers in die Datenbank und + verändern den Aktivitätsstatus von beweglichen Einheiten. +\layout Standard + +Wir verwenden EmbPerl auf Apache zur Implementation. + Siehe: http://perl.apache.org/embperl/. + EmbPerl scheint genauso einfach und schnell zu sein wie PHP und hat für + uns den zusätzlichen Vorteil, dass wir gemeinsame Bibliotheken mit den + anderen Komponenten des Servers benutzen können. +\layout Subsection + +Seiten +\layout Standard + +Folgende Seitenlayouts werden benötigt. + Auf allen Seiten findet man ein Hauptmenu. + Auf Login und Home gibt es auch noch ein Aymaegeddon-Banner +\layout Description + +Login Hier gibt es neben News einen kurzen Einleitungstext sowie eine Möglichkei +t sich zu registrieren und mal in einem Fakespiel zu schnuppern. +\layout Description + +Home Liste aller Spiele, pro Spiel: Liste aller Nachrichten, aller Ereignisse, + Statistik +\layout Description + +Karte Aktuelles Feld, Beschreibung, Befehle +\layout Description + +Spieler Beschreibung des Spielers +\layout Description + +Rolle Beschreibung der Rolle +\layout Standard + +Feldnamen/-koordinaten sind überall immer zur Karte mit dem Feld als aktuellem + Feld verlinkt. + Rollennamen sind zu der entsprechenden Rollenseite verlinkt. +\layout Subsection + +Karte +\layout Standard + +Zentrale Komponente der Darstellung ist eine Karte des Hex-Torus. + Dazu werden 3 Tabellenzellen pro Feld verwendet, nämlich so: +\layout Standard +\added_space_bottom 0.3cm +<BILD FEHLT> +\layout Standard + +Diese Karte ist scrollbar. + Ein Feld ist immer als aktuelles Feld umrandet. +\layout Subsection + +Farbdarstellung +\layout Standard + +Wasserfelder blau, Landfelder, Archen und Inseln in Erdfarben. + Dabei gibt es 5 Farbtöne für eigene, befreundete, neutrale, feindliche + sowie unbesiedelte Felder. + Tempel und Avatare werden in 5 verschiedenen Götterfarben (eher grell) + dargestellt, wieder je eine für eigene, befreundete, feindliche sowie neutrale + Götter. + Die +\begin_inset Quotes eld +\end_inset + +eigene +\begin_inset Quotes erd +\end_inset + + Farbe kann auf andere Erdlinge/Götter verändert werden. + +\layout Subsection + +Icons +\layout Standard + +Folgende Icons werden benötigt. +\layout Standard + +Zentriert: +\layout Itemize + +IdS +\layout Itemize + +Eigentum auf Wasser (Schiff) +\layout Itemize + +Städte +\layout Itemize + +Tempel +\layout Itemize + +Heimatstädte +\layout Itemize + +Inseln +\layout Itemize + +Berge +\layout Standard + +Nicht zentriert: +\layout Itemize + +Avatare (oben bis zu vier) +\layout Itemize + +Archen (unten, nur eine) +\layout Itemize + +Kampf (unten) +\layout Itemize + +Avatarkampf (oben) +\layout Section + +Weltengenerator +\layout Standard + +Dieses Programm wird einmal zu Beginn eines neuen Spiels aufgerufen um eine + neue Welt in der Datenbank zu generieren. + Der Generator verteilt die verschiedenen Geländetypen: Wasser, Manapol, + Insel, Berg, Stadt, Heimatstadt, Land. + Er erhält die Anzahl der Erdlinge als Parameter und ermittelt alle anderen + Werte daraus. + +\layout Standard + +Die Game-ID kann automatisch als die erste Freie in der DB ermittelt werden. + Dieses Programm sollte als erstes entwickelt werden, damit man eine sinnvolle + Testumgebung für die anderen Teile des Systems hat. +\layout Standard + +Wir verwenden Perl 5.8 zur Implementation. +\layout Section + +FROGS +\layout Standard + +FROGS steht für +\series bold +F +\series default +ramework for +\series bold +R +\series default +ealtime +\series bold +O +\series default +nline +\series bold +G +\series default +ames of +\series bold +S +\series default +trategy. + Dort werden alle Funktionalitäten versammelt, die nicht nur von Aymargeddon, + sondern auch von anderen Browser-MMOGs verwendet werden können. + Das sind im einzelnen: +\layout Itemize + +Nachrichtenverwaltung +\layout Itemize + +Befehlsverwaltung +\layout Itemize + +Spielerverwaltung +\layout Itemize + +Spielverwaltung +\layout Itemize + +Rollenverwaltung +\layout Itemize + +Verschiedene Standardkarten (hier erstmal nur Hextorus) +\layout Itemize + +Bewegliche Einheiten +\layout Itemize + +Lokalisierung +\layout Itemize + +Sessionhandling +\layout Itemize + +Bestenlisten +\layout Itemize + +Datenbank +\layout Standard + +FROGS basiert dabei auf der Annahme, dass bestimmte Felder in bestimmten + Tabellen vorhanden sein müssen. + Außerdem werden die konkreten Funktionalitäten über Hooks in das Framework + eingehängt. + So wird z.B. + für jeden Befehl ein Name festgelegt mit drei Hooks: +\layout Description + +test Diese Funktion tested, ob der Befehl überhaupt ausführbar ist. +\layout Description + +ack Diese Funktion wird ausgeführt, wenn der Befehl zum ersten mal vom Dämon + zur Kenntnis genommen wird. +\layout Description + +do Diese Funktion führt schließlich den Befehl aus. + Dazu sind am Anfang noch weitere tests nötig. +\layout Standard + +Ziel für Frogs ist, dass man relativ einfach neue Browserspiele bauen kann. + Es wird auch ein Satz von Standardseiten in EmbPerl mitgeliefert mit denen + Funktionen wie Einloggen, Spielverwaltung, Bestenlisten etc. + schon vorhanden sind. +\layout Standard + +Hier noch eine Liste von FROGS-Modulen und was sie tun sollen: +\layout Description + +Map.pm Dies ist eine Basisklasse für alle denkbaren Topologien. + Jedes Modul einer abgeleiteten Klasse sollte auch eine Klasse Location + zur Verfügung stellen. + Außerdem müssen abgeleitete Klassen einige Funktionen mitbringen, damit + die in Map vorhandenen Funktionen funktionieren. +\layout Description + +HexTorus.pm Dies ist die von Aymargeddon verwendete Topologie. + Kann aber auch von anderen Spielen verwendet werden. + Abgeleitet von Map.pm. + Stellt auch die Klasse Location zur Verfügung. +\layout Description + +Checker.pm Hier werden die verallgemeinerbaren Funktionen des Checkers zur + Verfügung gestellt. +\layout Description + +Scheduler.pm Hier wird die Befehlsqueu durchgegangen und die oben definierten + Funktionen werden aufgerufen. +\layout Description + +Localize.pm Hier wird die Lokalisierung ausgeführt. +\layout Description + +DataBase.pm Hier werden Basisdatenbankfunktionalitäten zur Verfügung gestellt +\layout Description + +... + weitere Module noch unklar +\layout Standard + +Auch FROGS wird in Perl 5.8 bzw. + EmbPerl implementiert. +\layout Section + +Checker +\layout Standard + +Dieses Programm überprüft, ob die Daten in der Datenbank noch konsistent + sind. + Dabei werden die Checks zu algorithmisch ähnlichen Gruppen zusammengefasst + und durch allgemein Funktionen ausgeführt. + Bisher sind folgende Funktionen identifiziert worden: +\layout Enumerate + +Jeder Eintrag in Tabelle X muß auch in Tabelle Y existieren. + +\layout Enumerate + +N Einträge in der selben Tabelle müssen eine logische Beziehung erfüllen +\layout Standard + +Diese allgemeinen konfigurierbaren Check-Funktionen sollten auch Teil von + FROGS werden. +\layout Standard + +Der Checker überprüft im einzelnen (Zahlen beziehen sich auf obige Funktionslist +e): +\layout Itemize + +Jede Spielnummer muß in der Tabelle GAME zu finden sein (1). +\layout Itemize + +sämtliche Spieler-IDs müssen in ROLE zum selben Spiel passen (1). +\layout Itemize + +sämtliche Spieler-IDs müssen in PLAYER vorhanden sein (1). +\layout Itemize + +Location muß immer in MAP vorhanden sein. +\layout Itemize + +Location muß immer die kanonische Form haben (2). +\layout Itemize + +HOME nur gesetzt in MAP, wenn TERRAIN = CITY (desgl. + für GOD_HOME und MOUNTAIN) (2). +\layout Itemize + +Keine Zwei Erdlinge im selben Feld, außer es ist Kampf. +\layout Itemize + +Alle Einheiten in COMMANDS müssen inaktiv sein. +\layout Itemize + +Nur Priester ADORING in MOBILE (2). +\layout Itemize + +AVAIABLE immer kleiner oder gleich COUNT in MOBILE (2) +\layout Itemize + +Während eines Kampfes nur aktive Erdlinge eines Spielers im selben Feld. +\layout Itemize + +Keine blockenden Avatare von zwei feindlichen Spielern im selben Feld ohne + Kampf . +\layout Itemize + +Jedes Tag in MESSAGE sollte in LOCALIZE vorhanden sein. + Mindestens in einer Sprache. + Warnung, wenn nicht in jeder Sprache. +\layout Itemize + +Die Anzahl der Argumente in MESSAGES sollte mit den nicht doppelten %-Zeichen + in LOCALIZE übereinstimmen (für jede Sprache). + +\layout Itemize + +CREATE <= EXEC <= ACK <= DONE in COMMAND +\layout Standard + +Dieses Programm sollte möglichst früh entwickelt werden, da es vor allem + im Entwicklungsprozess benötigt wird. +\layout Standard + +Wir verwenden Perl 5.8 zur Implementation. +\layout Section + +Bibliothek +\layout Standard + +Hier werden alle Funktionalitäten versammelt, die von mindestens zwei der + Komponenten (Scripten, Generator, Dämon, Check) verwendet werden. + +\layout Standard + +Dabei bleiben in dieser Bibliothek nur Sachen, die nicht noch allgemeiner + sind und somit in den FROGS-Teil gehören. + Momentan ist noch unklar, ob da überhaupt was übrig bleibt. +\layout Standard + +Wir verwenden Perl 5.8 zur Implementation. +\layout Section + + +\lang german +Copyright +\layout Standard + + +\lang german +(c) 2003 Aymargeddon Development Team +\layout Standard + + +\lang german +Permission is granted to copy, distribute and/or modify this document under + the terms of the GNU Free Documentation License, Version 1.1 or any later + version published by the Free Software Foundation; with no Invariant Sections, + with no Front-Cover Texts, and with no Back-Cover Texts. + A copy of the license is available at http://www.aymargeddon.de. +\the_end diff --git a/html/doc/ay_ein_hex.fig b/html/doc/ay_ein_hex.fig new file mode 100644 index 0000000..ea108e2 --- /dev/null +++ b/html/doc/ay_ein_hex.fig @@ -0,0 +1,36 @@ +#FIG 3.2 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +2 3 0 1 0 7 100 0 -1 0.000 0 0 0 0 0 7 + 4425 4177 5103 5348 6452 5349 7127 4177 6451 3006 5101 3009 + 4425 4177 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 5847 2976 5895 2430 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 4742 3668 4185 3420 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 4752 4771 4050 5175 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 5796 5327 5760 6075 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 6777 4803 7398 5067 +2 1 0 1 0 7 100 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 150.00 120.00 + 6823 3599 7408 3262 +4 0 0 100 0 0 12 -0.0000 4 180 1440 3285 3195 Nordwesten (NW)\001 +4 0 0 100 0 0 12 -0.0000 4 180 1410 3105 5625 Suedwesten (SW)\001 +4 0 0 100 0 0 12 -0.0000 4 180 1260 7065 3150 Nordosten (NO)\001 +4 0 0 50 0 0 12 0.0000 4 180 930 5490 2250 Norden (N) \001 +4 0 0 50 0 0 12 0.0000 4 180 765 5355 6390 S\374den (S)\001 +4 0 0 100 0 0 12 -0.0000 4 180 1230 7155 5400 Suedosten (SO)\001 diff --git a/html/doc/design b/html/doc/design new file mode 100644 index 0000000..e8f5e51 --- /dev/null +++ b/html/doc/design @@ -0,0 +1,149 @@ +################# +Datenbankzugriffe +################# + +Alles, was einen SQL-Befehl beinhaltet sollte in +DataBase.pm. zusätzlich vielleicht auch noch sehr eng damit +zusammenhängende Funktionen. Alles abstraktere sollte in extramodule. + +Generelle Frage: +================ + +embperl sollte nur die aktionen überhaupt zur verfügung stellen, die +möglich sind (soweit zu diesem zeitpunkt bekannt). + +soll man darauf vertrauen, dass die embperlseite bestimmte sachen +schon abgetestet hat? oder muss man die alle nochmal auf serverseite +testen? Antwort: wohl ja, da sich zwischen eintragen in die +befehlsqueu und ausführung des befehls der spielstand verändert haben +kann. ausnahmen sind unten eingeklammert. + +Hier jetzt mal eine möglichst vollständige Liste aller +Datenbankzugriffe, als Grundlage für Designüberlegungen. + +Von Serverseite: +================ + +- lies alle aktuellen befehle +- schreibe message + +Alles, was trotz zeitverzögerung schon vorher von embperlseite +abgeklärt hätte werden können ist eingeklammert. + +einzelne befehle: +-------------------- +- passwort ändern (nicht in befehlsqueu sondern sofort?) + - authentifizieren + - schreiben in PLAYER + +- registrieren (nicht in befehlsqueu sondern sofort?) + - schreiben in PLAYER + +- abmelden (nicht in befehlsqueu sondern sofort?) + - authentifizieren + - löschen in PLAYER + +- status ändern + - test ob spieler vorhanden + - schreiben in ALLIANCE + +- anmelden in einzelnen spielen (nicht in befehlsqueu sondern sofort?) + - test ob spieler schon in spiel vorhanden + - schreiben in ROLE + +- abmelden aus spielen (nicht in befehlsqueu sondern sofort?) + - löschen aus ROLE +-------------------- +- erdlingsbewegen: + - (test ob manapol) + - test ob arche auf wasser + - test ob kampf + - test wer kämpft + - schreiben in MOBILE + - schreiben in MAP + - schreiben in COMMAND + +- tempel bauen: + - test ob tempelfeld des gottes (kann sich ändern wg. überschwemmung) + - test ob richtiger priester da + +- sterbereihenfolge: + - (testen ob reihenfolge gültig) + - schreiben in EARTHLING [ACHTUNG: neue Tabelle!] + +- gott für tote helden festlegen: + - testen ob gott gültig + - schreiben in EARTHLING +-------------------- +- bei allen gottbefehlen: testen ob manna reicht + +- avatar erschaffen: + - ort ermitteln aus MAP und MOBILE + - schreiben in MOBILE + +- held weihen + - testen ob held noch vorhanden (und aktiv?) + - schreiben in MOBILE + +- priester erleuchten + - testen ob krieger noch vorhanden (und aktiv?) + - testen ob sichtrecht + - schreiben in MOBILE + +- avatare bewegen + - ähnlich wie erdlingsbewegen nur zusätzliche tests + - avatarstatus beachten (evntl. verändern) + +- verseuchen + - noch unklar, weil seuchen noch unklar + +- sintfluten + - test ob benachbartes wasserfeld + - liest und schreibt aus MAP + +- avatarstatus ändern + - testen ob avatar da. + +- tempel zerstören + - ... + +- glücksfaktor verändern + - ... + +- arche bauen + - ... + +Von Clientseite: +================ + +- authentifizieren +- liste aller spiele +- liste aller spiele mit freien positionen (mit rolle) +- liste aller spieler +- liste aller rollen pro spiel +- infos ueber einen spieler +- infos ueber eine rolle eines spielers in einem spiel + +- karte lesen (sichtregeln beachten!) +- infos ueber ein feld lesen (auch aus MOBILE) (sichtregeln beachten!) + +- liste der möglichen befehle in einem feld ermitteln + (vielfältige tests, viele davon stehen oben bei den serverbefehlen) + +- liste aller nachrichten +- liste aller nachrichten ein feld betreffend + +Von create.pl: +============== + +- lies das erste leere spiel aus GAME +- schreibe in MAP + +Von checker.pl: +=============== + +- sehr spezielle einzelne zugriffe (Check.pm selbst definiert keine +Struktur) + + + diff --git a/html/doc/pdf-tip b/html/doc/pdf-tip new file mode 100644 index 0000000..b954654 --- /dev/null +++ b/html/doc/pdf-tip @@ -0,0 +1,75 @@ +From Martin.Spott@uni-duisburg.de Tue Jul 6 17:06:05 1999 +From: Martin Spott <Martin.Spott@uni-duisburg.de> +Newsgroups: de.comp.os.unix.apps,de.comp.text.tex +Subject: Re: tex -> pdf +Date: 24 Jun 1999 18:59:57 GMT +Organization: home +Lines: 24 +Message-ID: <7ktv7d$p59$1@foehn.quickstep.cologne.de> +References: <7kskei$6hb$1@narses.hrz.tu-chemnitz.de> <3771ECC7.C1F5FDA2@starship.python.net> +NNTP-Posting-Host: foehn.quickstep.cologne.de +X-Trace: foehn.quickstep.cologne.de 930250797 25769 192.168.48.2 (24 Jun 1999 18:59:57 GMT) +X-Complaints-To: usenet@foehn.quickstep.cologne.de +NNTP-Posting-Date: 24 Jun 1999 18:59:57 GMT +X-Newsreader: TIN [UNIX 1.3 unoff BETA 970705; sun4m SunOS 5.5.1] +Path: nntp.server.uni-frankfurt.de!grapool30.rz.uni-frankfurt.de!News.Uni-Marburg.DE!news-fra1.dfn.de!news-kar1.dfn.de!akk.uni-karlsruhe.de!news.cologne.de!quickstep.cologne.de!not-for-mail +Xref: nntp.server.uni-frankfurt.de de.comp.os.unix.apps:2328 de.comp.text.tex:41798 + +In de.comp.os.unix.apps Berthold H?llmann <bhoel@starship.python.net> wrote: + +> 7. latex ; dvipdf ? + +Ist das dasselbe wie das 'dvipdfm', welches ich hier rumfliegen habe ? + +Beim Weg ueber 'dvips' respektive ueber DVI im Allgemeinen ist vor allem +darauf Acht zu geben, dass ausschliesslich Type1-Fonts im TeX-Dokument +verwendet werden. Wie genau das geht, habe ich nicht mehr im Kopf, es gibt +aber wohl irgeneinen Switch im 'dvips' und die dazugehoerigen TeX-Fonts im +Type1-Format. Beruecksichtigt man das nicht, dann sieht das PDF-Dokument vor +allem auf dem Bildschirm ausgesprochen haesslich aus und der Aufbau einer +Seite im Acrobat Reader dauert ungefaehr die fuenffache Zeit vom dem, was es +mit Type1-Fonts gebraucht haette, weil dann Bitmap-Fonts in das Dokument +eingebaut werden. Die eignen sich vielleicht zu allem moeglichen, aber mit +Sicherheit nicht fuer eine skalierbare Darstellung auf verschiedenen +Ausgabemedien. + +Derleit haessliche Dokumente kursieren leider zuhauf .... + +Martin. +-- + Unix _IS_ user friendly - it's just selective about who its friends are ! +-------------------------------------------------------------------------- + + +From Martin.Spott@uni-duisburg.de Tue Jul 6 17:06:14 1999 +From: Martin Spott <Martin.Spott@uni-duisburg.de> +Newsgroups: de.comp.os.unix.apps,de.comp.text.tex +Subject: Re: tex -> pdf +Date: 24 Jun 1999 20:04:25 GMT +Organization: home +Lines: 13 +Message-ID: <7ku309$q35$1@foehn.quickstep.cologne.de> +References: <7kskei$6hb$1@narses.hrz.tu-chemnitz.de> <3771ECC7.C1F5FDA2@starship.python.net> <7ktv7d$p59$1@foehn.quickstep.cologne.de> +NNTP-Posting-Host: foehn.quickstep.cologne.de +X-Trace: foehn.quickstep.cologne.de 930254665 26725 192.168.48.2 (24 Jun 1999 20:04:25 GMT) +X-Complaints-To: usenet@foehn.quickstep.cologne.de +NNTP-Posting-Date: 24 Jun 1999 20:04:25 GMT +X-Newsreader: TIN [UNIX 1.3 unoff BETA 970705; sun4m SunOS 5.5.1] +Path: nntp.server.uni-frankfurt.de!grapool30.rz.uni-frankfurt.de!News.Uni-Marburg.DE!news-fra1.dfn.de!fu-berlin.de!news.cologne.de!quickstep.cologne.de!not-for-mail +Xref: nntp.server.uni-frankfurt.de de.comp.os.unix.apps:2329 de.comp.text.tex:41800 + +In de.comp.os.unix.apps Martin Spott <Martin.Spott@uni-duisburg.de> wrote: + +> darauf Acht zu geben, dass ausschliesslich Type1-Fonts im TeX-Dokument +> verwendet werden. Wie genau das geht, habe ich nicht mehr im Kopf, es gibt +> aber wohl irgeneinen Switch im 'dvips' und die dazugehoerigen TeX-Fonts im +> Type1-Format. [...] + +.... oder jedenfalls die CM-Fonts, + +Martin. +-- + Unix _IS_ user friendly - it's just selective about who its friends are ! +-------------------------------------------------------------------------- + + diff --git a/html/doc/push_rules b/html/doc/push_rules new file mode 100644 index 0000000..9ce50ca --- /dev/null +++ b/html/doc/push_rules @@ -0,0 +1,6 @@ +# tth -t -e2 Regeln.tex +# mv Regeln.tex ./+Regeln.tex +mv Regeln.html ./+Regeln.html +mv Regeln.pdf ./+Regeln.pdf +scp ./+Regeln.html benni@aymargeddon.de:aymargeddon/current/doc/ +scp ./+Regeln.pdf benni@aymargeddon.de:aymargeddon/current/doc/ diff --git a/html/field.epl b/html/field.epl new file mode 100644 index 0000000..05a1478 --- /dev/null +++ b/html/field.epl @@ -0,0 +1,222 @@ +<html> +<head><link rel="stylesheet" type="text/css" href="aymargeddon.css"> +</head> +<body> +[$ if exists $fdat{'x'} and exists $fdat{'y'} $] + [- $udat{-loc} = $fdat{'x'}.'_'.$fdat{'y'}; -] +[$ endif $] + +[$ if exists $udat{-id} and exists $udat{-game} and $udat{-loc} $] + +[- + use FROGS::HexTorus; + use Aymargeddon; + + my $game = $udat{-game}; + my $user = $udat{-id}; + my $loc = $udat{-loc}; + + my $db = DataBase->new(); + my $aym = Aymargeddon->new($game,$user,$db); + $db->set_language($udat{-lang}); + + # maybe you cant see this field (for hackers, which try to look direct + # in the field via url) + unless ($aym->sight_of_field($loc)){ + print OUT "Mogeln gildet nich!\n"; + } else { + + my ($ter,$own,$occ,$temple,$plague) = + $aym->read_field('TERRAIN,HOME,OCCUPANT,TEMPLE,PLAGUE',$loc); + + ##################### + # general field info + ##################### + + $out .= $db->loc('FIELD_'.$ter).' '.Location::pretty($loc).' '. + $db->loc('PREP_IS_SG').' '; + if ($occ) { + $out .= $db->loc('OCCUPIED').' '; + if ($occ==$user) { + # it is our own field + $out .= $db->loc( ($aym->gender($occ) eq 'PLURAL') ? + 'PPRO_DAT3_PL' : 'PPRO_DAT3_SG' ); + } else { + # the field belongs to someone else + $out .= $db->loc('ART_DAT_PL').' ' if $aym->gender($occ) eq 'PLURAL'; + $out .= $aym->charname($occ).' (<a href="command.epl?cmd=CH_STATUS&other='. + $occ.'">'.$aym->relation_string($occ). + '</a>, <a href="command.epl?cmd=SEND_MSG&other='.$occ.'">'. + $db->loc('SEND_MESSAGE').'</a>)'; + } + } else { + $out .= $db->loc('NOT_OCCUPIED'); + } + $out .= ".\n"; + + if ($own > 0) { + # some fields have some specials + if ($ter eq 'CITY') { + $out .= $db->loc('HOMECITY'); + } elsif ($temple eq 'Y') { + $out .= $db->loc('TEMPLE'); + } elsif ($ter eq 'MOUNTAIN') { + $out .= $db->loc('HOMEHOLY'); + } + if($ter ne 'ISLE' or $temple eq 'Y'){ + $out .= ' '.$db->loc('PREP_OWN_SG').' '; + if ($own==$user) { + $out .= $db->loc( ($aym->gender($own) eq 'PLURAL') ? + 'PPRO_DAT3_PL' : 'PPRO_DAT3_SG' ); + } elsif ($occ == $own) { + my $gen = $aym->gender($own); + $out .= $db->loc( ($gen eq 'PLURAL') ? 'PPRO_DAT_PL' : + (($gen eq 'MALE') ? 'PPRO_DAT_M' : 'PPRO_DAT_F') ); + } else { + $out .= $db->loc('ART_DAT_PL').' ' if $aym->gender($own) eq 'PLURAL'; + $out .= $aym->charname($own).' (<a href="command.epl?cmd=CH_STATUS&other='. + $own.'">'.$aym->relation_string($own). + '</a>, <a href="command.epl?cmd=SEND_MSG&other='.$own.'">'. + $db->loc('SEND_MESSAGE').'</a>)'; + } + $out .= '.'; + } + } + $out .= $db->loc('PLAGUE_IN_FIELD',lc($plague)) if $plague; + $out .= "<p>\n"; + + ################### + # show the mobiles + ################### + + $mob = $aym->mobiles_available($loc); + $mobcount = $#{@$mob}+1; + + if ($mobcount) { + $out .= $db->loc('ADJ_HERE').' '; + $out .= $db->loc( ($mobcount == 1 and @{$mob->[0]}[4] == 1) ? + 'PREP_IS_SG' : 'PREP_IS_PL' ); + + $out .= ($mobcount > 1) ? ":\n<p>" : ' '; + foreach $i (0..$mobcount-1) { + my ($oid,$otype,$oown,$oado,$ocnt,$ostat,$omove) = @{$mob->[$i]}; + # check for MOVE_WITH + next if $omove; + $out .= $aym->mobile_to_html( $loc,$own,$occ,$temple,$ter, @{$mob->[$i]}); + + my $transports = 0; + foreach $j (0..$mobcount-1) { + ($xid,$xtype,$xown,$xado,$xcnt,$xstat,$xmove) = @{$mob->[$j]}; + if ($xmove == $oid) { + if (!$transports) { + $out .= ', '.$db->loc('MSG_TRANSPORTS').":<ul>\n"; + $transports = 1; + } + $out .= '<li>'. + $aym->mobile_to_html( $loc,$own,$occ,$temple,$ter, @{$mob->[$j]})."</li>\n"; + } + } + if ($transports) { + $out .= '</ul>'; + } else { + $out .= ($i < $mobcount-1) ? ',' : '.'; + $out .= "\n<p>"; + } + } # end foreach $mobcount + } + + ################################## + # general commands for this field: + ################################## + + if ($aym->is_earthling($user)) { + $out .= "\n<p><a href=\"command.epl?cmd=DIE_ORDER\">". + $db->loc('CMD_DIE_ORDER').'</a>'; + } + if ($aym->is_god($user)) { + if ($aym->is_arrival($loc)) { + $out .= "\n<p><a href=\"command.epl?cmd=INCARNATE&loc=$loc\">". + $db->loc('CMD_INCARNATE').'</a>'; + } + if($aym->is_coast($loc)){ + $out .= "\n<p><a href=\"command.epl?cmd=BUILD_ARK&loc=$loc\">". + $db->loc('CMD_BUILD_ARK').'</a>'; + if($ter ne 'CITY'){ + $out .= "\n<p><a href=\"command.epl?cmd=FLOOD&loc=$loc\">". + $db->loc('CMD_FLOOD').'</a>'; + } + } + $out .= "\n<p><a href=\"command.epl?cmd=PLAGUE&loc=$loc\">". + $db->loc('CMD_PLAGUE').'</a>'; + $out .= "\n<p><a href=\"command.epl?cmd=CH_LUCK\">".$db->loc('CMD_CH_LUCK').'</a>'; + } + + ############################# + # show events for this field + ############################# + + $events = $aym->field_events($loc); + #use Data::Dumper; + #print OUT Dumper $events; + $out .= "\n<p><strong>".$db->loc('PLAYER_EVENTS')."</strong><p>\n" if %$events; + for my $ev ( keys %$events) { + $out .= $aym->show_event($ev, 0) .'<p>'; + } + + ############################ + # show unavailable units + ############################ + + # mobile info: + #$mob = $aym->mobiles_available($loc,-1); + #$mobcount = $#{@$mob}+1; + + #if ($mobcount) { + # $out .= '<p>'; + # $out .= '<strong> '.$db->loc('UNAVAILABLE_UNITS').":</strong><p>"; + # foreach $i (0..$mobcount-1) { + # ($oid,$otype,$oown,$oado,$ocnt,$ostat) = @{$mob->[$i]}; + # $out .= $ocnt.' '; + # if ($oown == $user) { + # $out .= $db->loc('PREP_OWN_PL').' '.$aym->mobile_string($otype,2); + # if ($otype eq 'PRIEST' or $otype eq 'PROPHET') { + # $out .= $db->loc('ADJ_ADORING').' '.$aym->charname($oado); + # } elsif ($otype eq 'HERO') { + # $out .= $db->loc('ADJ_ADORING'); + # $out .= $aym->charname($oado).'</a>'; + # } elsif ($otype eq 'AVATAR') { + # $out .= $aym->mobile_string($ostat,1); + # } + # } else { + # $out .= $aym->mobile_string($otype, $ocnt); + # if ($otype ne 'ARK') { + # $out .= ' '.$db->loc('PREP_OWN_SG').' '; + # $out .= $db->loc('ART_DAT_PL').' ' if $aym->gender($oown) eq 'PLURAL'; + # $out .= $aym->charname($oown); + # } + # if ($otype eq 'PRIEST' or $otype eq 'PROPHET'or $otype eq 'HERO') { + # $out .= $db->loc('ADJ_ADORING').' '; + # if ($oado == $user) { + # $out .= $db->loc( ($aym->gender($user) eq 'PLURAL') ? + # 'PPRO_DAT3_PL' : 'PPRO_DAT3_SG'); + # } else { + # $out .= $aym->charname($oado); + # } + # } + # } + # $out .= ($i < $mobcount-1) ? ',' : '.'; + # $out .= "\n<p>"; + # } # end foreach $mobcount + #} + + print OUT $out; + } # unless sight + -] + +[$ else $] + + To view an Aymargeddon field, you must first <a href="login.epl" target="_top">login</a>, + because we need to know which game to display and for whom. + +[$ endif $] +</body></html> diff --git a/html/games.epl b/html/games.epl new file mode 100644 index 0000000..9f1b367 --- /dev/null +++ b/html/games.epl @@ -0,0 +1,12 @@ +[- use HTML::Embperl::Session; + +-] + +<html><body>Hallo Spieler mit der Nummer +[+ + $udat{-id} + + +] + +hier <a href="mapframe.html">zur Karte </a> +</body></html> \ No newline at end of file diff --git a/html/index.epl b/html/index.epl new file mode 100644 index 0000000..5626b93 --- /dev/null +++ b/html/index.epl @@ -0,0 +1,26 @@ +<html> +<head> + <title>Aymargeddon</title> +</head> +<body> +[- + + use FROGS::Config; + + $udat{-current} = 'index.epl'; + Execute("menu.epl"); + + $udat{-lang} = $::conf->{-DEFAULT_LANGUAGE} unless exists $udat{-lang}; + + if($udat{-lang} eq 'EN'){ + Execute("welcome_english.html"); + }elsif($udat{-lang} eq 'DE'){ + Execute("welcome_german.html"); + }else{ + Execute("welcome_english.html"); + } +-] + +</body> +</html> + diff --git a/html/language.epl b/html/language.epl new file mode 100644 index 0000000..9fe152c --- /dev/null +++ b/html/language.epl @@ -0,0 +1,45 @@ +<html> +<head></head> +<body> +[- + use FROGS::DataBase; + $db = DataBase->new(); +-] + +[$ if exists $fdat{'lang'} $] + +[- + $udat{-lang} = $fdat{'lang'}; + $db->set_language($udat{-lang}); + + #set language in Database in PLAYER.LANGUAGE + my $player = $udat{-id}; + $db->update_hash('PLAYER',"PLAYER=$player",{'LANGUAGE' => $fdat{'lang'}}); + $db->commit(); + + # redirect to original page + $http_headers_out{'Location'} = $udat{-current}; + +-] + +[$ else $] + +[- + $db->set_language($udat{-lang}); + Execute("menu.epl"); +-] + +<hr> +<form method="get" action="language.epl"> + + [+ $db->loc('LANG_WELCOME') +]:<p> + + <input type="radio" name="lang" value="EN">[+ $db->loc('LANG_ENGLISH') +]<p> + <input type="radio" name="lang" value="DE">[+ $db->loc('LANG_GERMAN') +]<p> + <input type="submit" value="[+ $db->loc('FORM_OK_BUTTON') +]"> + +</form> + +[$ endif $] + +</body></html> diff --git a/html/login.epl b/html/login.epl new file mode 100644 index 0000000..64990c3 --- /dev/null +++ b/html/login.epl @@ -0,0 +1,75 @@ +<html> +<head></head> +<body> +[- + $udat{-current} = 'login.epl'; + + use FROGS::DataBase; + $db = DataBase->new(); + $db->set_language($udat{-lang}) if exists $udat{-lang}; + + if(exists $udat{-id}){ # we are logged in, so log out (deleting user-data) + delete $udat{-id}; + delete $udat{-game}; + } + + Execute("menu.epl"); + + $escmode = 0; +-] +<hr> + +[$ if $fdat{'mode'} eq 'register' $] [# register form #] + + [+ $db->loc('LOGIN_REG_FORM_HEAD') +]<p> + <form method="get" action="login.epl"> + [+ $db->loc('LOGIN_USERNAME') +]: <input type="text" name="newlogin" size="20" maxlength="20"><p> + [+ $db->loc('LOGIN_REALNAME') +]: <input type="text" name="realname" size="30" maxlength="30"><p> + [+ $db->loc('LOGIN_EMAIL') +]: <input type="text" name="email" size="40" maxlength="40"><p> + <input type="submit" value="[+ $db->loc('FORM_OK_BUTTON') +]"> + </form> + +[$ elsif defined $fdat{'newlogin'} $] [# validate data from register form #] + + [- $new_passwd = $db->new_account($fdat{'newlogin'}, + $fdat{'realname'}, + $fdat{'email'}, + $udat{-lang}); -] + [$ if $new_passwd $] + + [+ $db->loc('LOGIN_REG_OK_HEAD',$lang) +]<p> + [+ $db->loc('LOGIN_USERNAME') +]: [+ $fdat{'newlogin'} +]<p> + [+ $db->loc('LOGIN_REALNAME') +]: [+ $fdat{'realname'} +]<p> + [+ $db->loc('LOGIN_EMAIL') +]: [+ $fdat{'email'} +]<p> + [+ $db->loc('LOGIN_REG_OK_TAIL') +] + + [$ else $] + + [+ $db->loc('LOGIN_REG_ERROR') +]<p> + + [$ endif $] + + <p><a href="login.epl">[+ $db->loc('LOGIN_REG_RETURN') +]</a> + +[$ else $] [# ask for login-data or register #] + + [+ $db->loc('LOGIN_WELCOME') +]<p> + <form method="get" action="player.epl"> + [+ $db->loc('LOGIN_USERNAME') +]: <input type="text" name="login" + size="20" maxlength="20"> + [+ $db->loc('LOGIN_PASSWORD') +]: <input type="password" name="passwd" + size="20" maxlength="20"> + <p> + [+ $db->loc('CHANGE_PASSWORD') +]: + <input name="passwd2" type="password" size="20" maxlength="20"> + <input name="passwd3" type="password" size="20" maxlength="20"> + <p> + <input type="submit" value="[+ $db->loc('FORM_OK_BUTTON') +]"> + </form> + [+ $db->loc('LOGIN_REG_MSG') +] + <a href="login.epl?mode=register">[+$db->loc('LOGIN_REG_LINK')+]</a>. + +[$ endif $] + +</body> +</html> diff --git a/html/map.epl b/html/map.epl new file mode 100644 index 0000000..b4ccad2 --- /dev/null +++ b/html/map.epl @@ -0,0 +1,249 @@ +<html><head> + <title>Aymargeddon Map</title> +</head><body> + +[$ if exists $udat{-id} and exists $udat{-game} $] + +[- + + # TODO: center relocation + # TODO: bug/feature setting y did not work with local variables + + use FROGS::DataBase; + use Aymargeddon; + use DBI; + my $game = $udat{-game}; + my $user = $udat{-id}; + + # look at MAP + my $db = Aymargeddon->new($game,$user); + my $dat = $db->get_map(); + + # create $map + # map[x][y][0] = background-color + # map[x][y][1] = occupant-color + # map[x][y][2] = type + # map[x][y][3] = owner-color + # map[x][y][4] = avatar-case + # map[x][y][5] = god-fight + # map[x][y][6] = earthling-fight /foreign earthling units approaching /plague + # map[x][y][7] = arc present + + $xmax = 0; $ymax = 0; + for my $row (@$dat){ + my ($loc,$ter,$own,$occ,$temple,$plague) = @$row; + + $loc =~ /^(\d+)_(\d+)$/; + ($x,$y) = ($1,$2); + $xmax = $x if $x > $xmax; + $ymax = $y if $y > $ymax; + + if(!$db->sight($loc)){ + $map[$x][$y][0] = 'B'; + $map[$x][$y][1] = 'B'; + $map[$x][$y][2] = ''; + $map[$x][$y][3] = ''; + $map[$x][$y][4] = 'X'; + next; + } + + if($ter eq 'POLE' or $ter eq 'AYMARGEDDON'){ + $map[$x][$y][1] = 'P'; + }elsif($occ==$user){ + $map[$x][$y][1] = 'O'; + }elsif($db->get_relation($occ) eq 'FRIEND' or $db->get_relation($occ) eq 'ALLIED'){ + $map[$x][$y][1] = 'F'; + }elsif($db->get_relation($occ) eq 'FOE' or $db->get_relation($occ) eq 'BETRAY'){ + $map[$x][$y][1] = 'E'; + }elsif($occ){ + $map[$x][$y][1] = 'N'; + }else{ + $map[$x][$y][1] = 'U'; + } + + $map[$x][$y][0] = ($ter eq 'WATER' or $ter eq 'ISLE') + ? 'W' : $map[$x][$y][1]; + + if($temple eq 'Y'){ + $map[$x][$y][2] = ($ter eq 'ISLE')?'I':'M'; + }elsif($ter eq 'CITY'){ + $map[$x][$y][2] = 'C'; + }elsif($ter eq 'ISLE' or $ter eq 'WATER'){ + $map[$x][$y][2] = 'W'; + }else{ + $map[$x][$y][2] = 'L'; + } + + $map[$x][$y][3] = 'U'; + + if($ter eq 'AYMARGEDDON'){ + $map[$x][$y][3] = 'A'; + }elsif($ter eq 'MOUNTAIN' or $ter eq 'ISLE' or $ter eq 'CITY'){ + if($map[$x][$y][2] eq 'W'){ + $map[$x][$y][3] = 'N'; # Isles without temple are always neutral + }elsif(!$own){ + $map[$x][$y][3] = 'B'; # Cities without owner are non-homecities + }elsif($own eq $user){ + $map[$x][$y][3] = 'O'; + }elsif($db->get_relation($own) eq 'FRIEND' or $db->get_relation($own) eq 'ALLIED'){ + $map[$x][$y][3] = 'F'; + }elsif($db->get_relation($own) eq 'FOE' or $db->get_relation($own) eq 'BETRAY'){ + $map[$x][$y][3] = 'E'; + }elsif($own){ + $map[$x][$y][3] = 'N'; + } + } + + $map[$x][$y][5] = $db->god_fight($loc) ? 'G':'U'; + $map[$x][$y][6] = $db->earthling_fight($loc) ? 'E': 'U'; + $map[$x][$y][7] = (($ter ne 'WATER' or !$occ) and $db->arc_present($loc)) ? 'A':'U'; + my $fea = $db->foreign_earthling_approaching($loc,$occ) ? 'F':'U'; + $map[$x][$y][6] = $map[$x][$y][6] eq 'E' ? 'E' : $fea; + if($map[$x][$y][6] eq 'U' and $plague){ + $map[$x][$y][6] = 'P'; + } + + $avatars = $db->avatar_present($loc); + ($own_avatar,$friend_avatar,$neutral_avatar,$enemy_avatar) = (0,0,0,0); + for my $a (@$avatars){ + $a = $a->[0]; + if($a == $user){ + $own_avatar = 1; + } + elsif($db->get_relation($a) eq 'FOE' or $db->get_relation($a) eq 'BETRAY'){ + $enemy_avatar = 1; + } + elsif($db->get_relation($a) eq 'FRIEND' or $db->get_relation($a) eq 'ALLIED'){ + $friend_avatar = 1; + } + else{ + $neutral_avatar = 1; + } + } + + if($own_avatar){ + if($enemy_avatar){ + $map[$x][$y][4] = '0'; + }elsif($neutral_avatar){ + $map[$x][$y][4] = '1'; + }elsif($friend_avatar){ + $map[$x][$y][4] = '2'; + }else{ + $map[$x][$y][4] = '3'; + } + }elsif($friend_avatar){ + if($enemy_avatar){ + $map[$x][$y][4] = '4'; + }elsif($neutral_avatar){ + $map[$x][$y][4] = '5'; + }else{ + $map[$x][$y][4] = '6'; + } + }elsif($enemy_avatar){ + if($neutral_avatar){ + $map[$x][$y][4] = '7'; + }else{ + $map[$x][$y][4] = '8'; + } + }elsif($neutral_avatar){ + $map[$x][$y][4] = '9'; + }else{ + $map[$x][$y][4] = ($map[$x][$y][5] eq 'U' and $map[$x][$y][6] eq 'U' and $map[$x][$y][7] eq 'U') + ? 'X' : 'U'; # don't use overlay icons if all are empy (to save space) + } + + } + + $xmax++;$ymax++; + + $xoff = $udat{-xoff}; + $yoff = $udat{-yoff}; + +-] + + <table border="0" cellspacing="0" cellpadding="0"> + [$ foreach $yy (0..($ymax-1)) $] + <tr><td><img src="map/SB[+ $map[$xoff][($yy+$yoff)%$ymax][0] +].png"></td> + [$ foreach $xx (0..($xmax-1)) $] + [- $x = ($xx +$xoff) % $xmax; -] + [$ if not $xx % 2 $] + [- $y = ($yy +$yoff -($xx / 2)) % $ymax; -] + [$ if $map[$x][$y][4] eq 'X' $] + [$ if $map[$x][$y][1] eq 'B' $] + <th rowspan="2"><img src="map/CB.png"></th> + [$ else $] + <th rowspan="2"><a href="field.epl?x=[+$x+]&y=[+$y+]" target="field"><img border="0" src="map/C[+ $map[$x][$y][1].$map[$x][$y][2].$map[$x][$y][3] +].png"></a></th> + [$ endif $] + [$ else $] + <th rowspan="2" background="map/C[+ $map[$x][$y][1].$map[$x][$y][2].$map[$x][$y][3] +].png"><table cellpadding="0" cellspacing="0" border="0"> + <tr><td><a href="field.epl?x=[+$x+]&y=[+$y+]" target="field"><img border="0" src="map/I[+ $map[$x][$y][4] +].png"></a></td><td><a href="field.epl?x=[+$x+]&y=[+$y+]" target="field"><img border="0" src="map/I[+ $map[$x][$y][5] +].png"></a></td></tr> + <tr><td><a href="field.epl?x=[+$x+]&y=[+$y+]" target="field"><img border="0" src="map/I[+ $map[$x][$y][6] +].png"></a></td><td><a href="field.epl?x=[+$x+]&y=[+$y+]" target="field"><img border="0" src="map/I[+ $map[$x][$y][7] +].png"></a></td></tr></table></th> + [$ endif $] + [$ if not $yy $] + <td><img src="map/BB[+$map[$x][$y][0]+].png"></td> + [$ else $] + <td><img src="map/B[+$map[($x+1)%$xmax][($y-1)%$ymax][0].$map[$x][$y][0]+].png"></td> + [$ endif $] + [$ else $] + [$ if not $yy $] + <td><img src="map/HB.png"></td> + [$ if $xx==$xmax-1 $] + <td><img src="map/SBB.png"></td> + [$ else $] + <td><img src="map/SB[+$map[($x+1)%$xmax][($y-1)%$ymax][0]+].png"></td> + [$ endif $] + [$ else $] + [$ if $xx==$xmax-1 $] + <td><img src="map/S[+$map[$x][($y-1)%$ymax][0]+]B.png"></td> + [$ else $] + <td><img src="map/S[+$map[$x][($y-1)%$ymax][0].$map[($x+1)%$xmax][($y-1)%$ymax][0]+].png"></td> + [$ endif $] + [$ endif $] + [$ endif $] + [$ endforeach $] + </tr><tr> + <td><img src="map/B[+$map[$xoff][($yy+$yoff)%$ymax][0]+]B.png"></td> + [$ foreach $xx (0..($xmax-1)) $] + [$ if not $xx % 2 $] + [- $x = ($xx +$xoff +1)%$xmax; $y = ($yy +$yoff -($xx/2))%$ymax; -] + <td><img src="map/S[+$map[($x-1)%$xmax][$y][0].$map[$x][$y][0]+].png"></td> + [$ if $map[$x][$y][4] eq 'X' $] + [$ if $map[$x][$y][1] eq 'B' $] + <th rowspan="2"><img src="map/CB.png"></th> + [$ else $] + <th rowspan="2"><a href="field.epl?x=[+$x+]&y=[+$y+]" target="field"><img border="0" src="map/C[+ $map[$x][$y][1].$map[$x][$y][2].$map[$x][$y][3] +].png"></a></th> + [$ endif $] + [$ else $] + <th rowspan="2" background="map/C[+ $map[$x][$y][1].$map[$x][$y][2].$map[$x][$y][3] +].png"><table cellpadding="0" cellspacing="0" border="0"> + <tr><td><a href="field.epl?x=[+$x+]&y=[+$y+]" target="field"><img border="0" src="map/I[+ $map[$x][$y][4] +].png"></a></td><td><a href="field.epl?x=[+$x+]&y=[+$y+]" target="field"><img border="0" src="map/I[+ $map[$x][$y][5] +].png"></a></td></tr> + <tr><td><a href="field.epl?x=[+$x+]&y=[+$y+]" target="field"><img border="0" src="map/I[+ $map[$x][$y][6] +].png"></a></td><td><a href="field.epl?x=[+$x+]&y=[+$y+]" target="field"><img border="0" src="map/I[+ $map[$x][$y][7] +].png"></a></td></tr></table></th> + [$ endif $] + [$ if $xx==$xmax-2 $] + <td><img src="map/BB[+$map[$x][$y][0] +].png"></td> + [$ else $] + <td><img src="map/B[+$map[($x+1)%$xmax][($y-1)%$ymax][0].$map[$x][$y][0] +].png"></td> + [$ endif $] + [$ endif $] + [$ endforeach $] + </tr> + [$ endforeach $] + <tr> + <td><img src="map/SBB.png"></td> + [$ foreach $xx (0..($xmax-1)) $] + [$ if $xx % 2 $] + [- $x = ($xx + $xoff) % $xmax; $y = ($ymax +$yoff -($xx/2))% $ymax; -] + <td><img src="map/HB.png"></td> + <td><img src="map/B[+ $map[$x][$y][0] +]B.png"></td> + <td><img src="map/S[+ $map[$x][$y][0] +]B.png"></td> + [$ endif $] + [$ endforeach $] + </tr></table> + +[$ else $] + + To view an Aymargeddon world-map, you must first <a href="login.epl" target="_top">login</a>, + because we need to know which game to display and for whom. + +[$ endif $] + +</body></html> diff --git a/html/map/Aymargeddon.ACT b/html/map/Aymargeddon.ACT new file mode 100644 index 0000000..df137ca Binary files /dev/null and b/html/map/Aymargeddon.ACT differ diff --git a/html/map/BBB.png b/html/map/BBB.png new file mode 100644 index 0000000..5bfcd29 Binary files /dev/null and b/html/map/BBB.png differ diff --git a/html/map/BBE.png b/html/map/BBE.png new file mode 100644 index 0000000..5ccfc42 Binary files /dev/null and b/html/map/BBE.png differ diff --git a/html/map/BBF.png b/html/map/BBF.png new file mode 100644 index 0000000..d21f9b8 Binary files /dev/null and b/html/map/BBF.png differ diff --git a/html/map/BBN.png b/html/map/BBN.png new file mode 100644 index 0000000..e983887 Binary files /dev/null and b/html/map/BBN.png differ diff --git a/html/map/BBO.png b/html/map/BBO.png new file mode 100644 index 0000000..d3dba3c Binary files /dev/null and b/html/map/BBO.png differ diff --git a/html/map/BBP.png b/html/map/BBP.png new file mode 100644 index 0000000..05c1aa3 Binary files /dev/null and b/html/map/BBP.png differ diff --git a/html/map/BBP2.png b/html/map/BBP2.png new file mode 100644 index 0000000..d17648d Binary files /dev/null and b/html/map/BBP2.png differ diff --git a/html/map/BBU.png b/html/map/BBU.png new file mode 100644 index 0000000..809a570 Binary files /dev/null and b/html/map/BBU.png differ diff --git a/html/map/BBW.png b/html/map/BBW.png new file mode 100644 index 0000000..05c1aa3 Binary files /dev/null and b/html/map/BBW.png differ diff --git a/html/map/BEB.png b/html/map/BEB.png new file mode 100644 index 0000000..0debbd2 Binary files /dev/null and b/html/map/BEB.png differ diff --git a/html/map/BEE.png b/html/map/BEE.png new file mode 100644 index 0000000..bd314ae Binary files /dev/null and b/html/map/BEE.png differ diff --git a/html/map/BEF.png b/html/map/BEF.png new file mode 100644 index 0000000..eae65fd Binary files /dev/null and b/html/map/BEF.png differ diff --git a/html/map/BEN.png b/html/map/BEN.png new file mode 100644 index 0000000..bdbd018 Binary files /dev/null and b/html/map/BEN.png differ diff --git a/html/map/BEO.png b/html/map/BEO.png new file mode 100644 index 0000000..0764d88 Binary files /dev/null and b/html/map/BEO.png differ diff --git a/html/map/BEU.png b/html/map/BEU.png new file mode 100644 index 0000000..b1cca5e Binary files /dev/null and b/html/map/BEU.png differ diff --git a/html/map/BEW.png b/html/map/BEW.png new file mode 100644 index 0000000..a8a9111 Binary files /dev/null and b/html/map/BEW.png differ diff --git a/html/map/BFB.png b/html/map/BFB.png new file mode 100644 index 0000000..9c2218b Binary files /dev/null and b/html/map/BFB.png differ diff --git a/html/map/BFE.png b/html/map/BFE.png new file mode 100644 index 0000000..c33afc9 Binary files /dev/null and b/html/map/BFE.png differ diff --git a/html/map/BFF.png b/html/map/BFF.png new file mode 100644 index 0000000..14c0aaf Binary files /dev/null and b/html/map/BFF.png differ diff --git a/html/map/BFN.png b/html/map/BFN.png new file mode 100644 index 0000000..d3ef082 Binary files /dev/null and b/html/map/BFN.png differ diff --git a/html/map/BFO.png b/html/map/BFO.png new file mode 100644 index 0000000..8761b79 Binary files /dev/null and b/html/map/BFO.png differ diff --git a/html/map/BFU.png b/html/map/BFU.png new file mode 100644 index 0000000..9006f95 Binary files /dev/null and b/html/map/BFU.png differ diff --git a/html/map/BFW.png b/html/map/BFW.png new file mode 100644 index 0000000..c5ebf70 Binary files /dev/null and b/html/map/BFW.png differ diff --git a/html/map/BNB.png b/html/map/BNB.png new file mode 100644 index 0000000..a3d708f Binary files /dev/null and b/html/map/BNB.png differ diff --git a/html/map/BNE.png b/html/map/BNE.png new file mode 100644 index 0000000..485f4cf Binary files /dev/null and b/html/map/BNE.png differ diff --git a/html/map/BNF.png b/html/map/BNF.png new file mode 100644 index 0000000..d57622c Binary files /dev/null and b/html/map/BNF.png differ diff --git a/html/map/BNN.png b/html/map/BNN.png new file mode 100644 index 0000000..f98ca9f Binary files /dev/null and b/html/map/BNN.png differ diff --git a/html/map/BNO.png b/html/map/BNO.png new file mode 100644 index 0000000..38effbe Binary files /dev/null and b/html/map/BNO.png differ diff --git a/html/map/BNU.png b/html/map/BNU.png new file mode 100644 index 0000000..cc823eb Binary files /dev/null and b/html/map/BNU.png differ diff --git a/html/map/BNW.png b/html/map/BNW.png new file mode 100644 index 0000000..076c82a Binary files /dev/null and b/html/map/BNW.png differ diff --git a/html/map/BOB.png b/html/map/BOB.png new file mode 100644 index 0000000..a3235a3 Binary files /dev/null and b/html/map/BOB.png differ diff --git a/html/map/BOE.png b/html/map/BOE.png new file mode 100644 index 0000000..0bafbd8 Binary files /dev/null and b/html/map/BOE.png differ diff --git a/html/map/BOF.png b/html/map/BOF.png new file mode 100644 index 0000000..bab000c Binary files /dev/null and b/html/map/BOF.png differ diff --git a/html/map/BON.png b/html/map/BON.png new file mode 100644 index 0000000..cacedb7 Binary files /dev/null and b/html/map/BON.png differ diff --git a/html/map/BOO.png b/html/map/BOO.png new file mode 100644 index 0000000..55d2521 Binary files /dev/null and b/html/map/BOO.png differ diff --git a/html/map/BOU.png b/html/map/BOU.png new file mode 100644 index 0000000..bf79097 Binary files /dev/null and b/html/map/BOU.png differ diff --git a/html/map/BOW.png b/html/map/BOW.png new file mode 100644 index 0000000..5a987e5 Binary files /dev/null and b/html/map/BOW.png differ diff --git a/html/map/BPB.png b/html/map/BPB.png new file mode 100644 index 0000000..c42879a Binary files /dev/null and b/html/map/BPB.png differ diff --git a/html/map/BPB2.png b/html/map/BPB2.png new file mode 100644 index 0000000..3191893 Binary files /dev/null and b/html/map/BPB2.png differ diff --git a/html/map/BPW.png b/html/map/BPW.png new file mode 100644 index 0000000..96557e9 Binary files /dev/null and b/html/map/BPW.png differ diff --git a/html/map/BPW2.png b/html/map/BPW2.png new file mode 100644 index 0000000..ea77bd0 Binary files /dev/null and b/html/map/BPW2.png differ diff --git a/html/map/BT.gif b/html/map/BT.gif new file mode 100644 index 0000000..fad6d44 Binary files /dev/null and b/html/map/BT.gif differ diff --git a/html/map/BUB.png b/html/map/BUB.png new file mode 100644 index 0000000..80f99dd Binary files /dev/null and b/html/map/BUB.png differ diff --git a/html/map/BUE.png b/html/map/BUE.png new file mode 100644 index 0000000..c0c59f4 Binary files /dev/null and b/html/map/BUE.png differ diff --git a/html/map/BUF.png b/html/map/BUF.png new file mode 100644 index 0000000..36770fd Binary files /dev/null and b/html/map/BUF.png differ diff --git a/html/map/BUN.png b/html/map/BUN.png new file mode 100644 index 0000000..8f201e1 Binary files /dev/null and b/html/map/BUN.png differ diff --git a/html/map/BUO.png b/html/map/BUO.png new file mode 100644 index 0000000..bd192ee Binary files /dev/null and b/html/map/BUO.png differ diff --git a/html/map/BUU.png b/html/map/BUU.png new file mode 100644 index 0000000..4439a99 Binary files /dev/null and b/html/map/BUU.png differ diff --git a/html/map/BUW.png b/html/map/BUW.png new file mode 100644 index 0000000..27bb253 Binary files /dev/null and b/html/map/BUW.png differ diff --git a/html/map/BWB.png b/html/map/BWB.png new file mode 100644 index 0000000..c42879a Binary files /dev/null and b/html/map/BWB.png differ diff --git a/html/map/BWE.png b/html/map/BWE.png new file mode 100644 index 0000000..8ab27ca Binary files /dev/null and b/html/map/BWE.png differ diff --git a/html/map/BWF.png b/html/map/BWF.png new file mode 100644 index 0000000..b2542ba Binary files /dev/null and b/html/map/BWF.png differ diff --git a/html/map/BWN.png b/html/map/BWN.png new file mode 100644 index 0000000..4a92aa6 Binary files /dev/null and b/html/map/BWN.png differ diff --git a/html/map/BWO.png b/html/map/BWO.png new file mode 100644 index 0000000..b5ca713 Binary files /dev/null and b/html/map/BWO.png differ diff --git a/html/map/BWP.png b/html/map/BWP.png new file mode 100644 index 0000000..96557e9 Binary files /dev/null and b/html/map/BWP.png differ diff --git a/html/map/BWP2.png b/html/map/BWP2.png new file mode 100644 index 0000000..16609d0 Binary files /dev/null and b/html/map/BWP2.png differ diff --git a/html/map/BWU.png b/html/map/BWU.png new file mode 100644 index 0000000..e970ff2 Binary files /dev/null and b/html/map/BWU.png differ diff --git a/html/map/BWW.png b/html/map/BWW.png new file mode 100644 index 0000000..96557e9 Binary files /dev/null and b/html/map/BWW.png differ diff --git a/html/map/CB.png b/html/map/CB.png new file mode 100644 index 0000000..41281d6 Binary files /dev/null and b/html/map/CB.png differ diff --git a/html/map/CECB.png b/html/map/CECB.png new file mode 100644 index 0000000..c5d685a Binary files /dev/null and b/html/map/CECB.png differ diff --git a/html/map/CECE.png b/html/map/CECE.png new file mode 100644 index 0000000..0668631 Binary files /dev/null and b/html/map/CECE.png differ diff --git a/html/map/CECF.png b/html/map/CECF.png new file mode 100644 index 0000000..af46161 Binary files /dev/null and b/html/map/CECF.png differ diff --git a/html/map/CECN.png b/html/map/CECN.png new file mode 100644 index 0000000..fb58102 Binary files /dev/null and b/html/map/CECN.png differ diff --git a/html/map/CECO.png b/html/map/CECO.png new file mode 100644 index 0000000..dab9cc0 Binary files /dev/null and b/html/map/CECO.png differ diff --git a/html/map/CECU.png b/html/map/CECU.png new file mode 100644 index 0000000..b14de5e Binary files /dev/null and b/html/map/CECU.png differ diff --git a/html/map/CEIE.png b/html/map/CEIE.png new file mode 100644 index 0000000..7fcd3a8 Binary files /dev/null and b/html/map/CEIE.png differ diff --git a/html/map/CEIF.png b/html/map/CEIF.png new file mode 100644 index 0000000..c15f48d Binary files /dev/null and b/html/map/CEIF.png differ diff --git a/html/map/CEIN.png b/html/map/CEIN.png new file mode 100644 index 0000000..3de6989 Binary files /dev/null and b/html/map/CEIN.png differ diff --git a/html/map/CEIO.png b/html/map/CEIO.png new file mode 100644 index 0000000..f3e7bfa Binary files /dev/null and b/html/map/CEIO.png differ diff --git a/html/map/CELE.png b/html/map/CELE.png new file mode 100644 index 0000000..83cc691 Binary files /dev/null and b/html/map/CELE.png differ diff --git a/html/map/CELF.png b/html/map/CELF.png new file mode 100644 index 0000000..d1a90f9 Binary files /dev/null and b/html/map/CELF.png differ diff --git a/html/map/CELN.png b/html/map/CELN.png new file mode 100644 index 0000000..c40bc34 Binary files /dev/null and b/html/map/CELN.png differ diff --git a/html/map/CELO.png b/html/map/CELO.png new file mode 100644 index 0000000..6d9c504 Binary files /dev/null and b/html/map/CELO.png differ diff --git a/html/map/CELU.png b/html/map/CELU.png new file mode 100644 index 0000000..8f7bf28 Binary files /dev/null and b/html/map/CELU.png differ diff --git a/html/map/CEME.png b/html/map/CEME.png new file mode 100644 index 0000000..7148aba Binary files /dev/null and b/html/map/CEME.png differ diff --git a/html/map/CEMF.png b/html/map/CEMF.png new file mode 100644 index 0000000..bf6109f Binary files /dev/null and b/html/map/CEMF.png differ diff --git a/html/map/CEMN.png b/html/map/CEMN.png new file mode 100644 index 0000000..65b5b1c Binary files /dev/null and b/html/map/CEMN.png differ diff --git a/html/map/CEMO.png b/html/map/CEMO.png new file mode 100644 index 0000000..e0d75c5 Binary files /dev/null and b/html/map/CEMO.png differ diff --git a/html/map/CEWN.png b/html/map/CEWN.png new file mode 100644 index 0000000..4081da3 Binary files /dev/null and b/html/map/CEWN.png differ diff --git a/html/map/CEWU.png b/html/map/CEWU.png new file mode 100644 index 0000000..d012b27 Binary files /dev/null and b/html/map/CEWU.png differ diff --git a/html/map/CFCB.png b/html/map/CFCB.png new file mode 100644 index 0000000..f98349b Binary files /dev/null and b/html/map/CFCB.png differ diff --git a/html/map/CFCE.png b/html/map/CFCE.png new file mode 100644 index 0000000..391718a Binary files /dev/null and b/html/map/CFCE.png differ diff --git a/html/map/CFCF.png b/html/map/CFCF.png new file mode 100644 index 0000000..fa1a312 Binary files /dev/null and b/html/map/CFCF.png differ diff --git a/html/map/CFCN.png b/html/map/CFCN.png new file mode 100644 index 0000000..6a10c3f Binary files /dev/null and b/html/map/CFCN.png differ diff --git a/html/map/CFCO.png b/html/map/CFCO.png new file mode 100644 index 0000000..801b528 Binary files /dev/null and b/html/map/CFCO.png differ diff --git a/html/map/CFCU.png b/html/map/CFCU.png new file mode 100644 index 0000000..00e6914 Binary files /dev/null and b/html/map/CFCU.png differ diff --git a/html/map/CFIE.png b/html/map/CFIE.png new file mode 100644 index 0000000..fc32c1f Binary files /dev/null and b/html/map/CFIE.png differ diff --git a/html/map/CFIF.png b/html/map/CFIF.png new file mode 100644 index 0000000..f1d3708 Binary files /dev/null and b/html/map/CFIF.png differ diff --git a/html/map/CFIN.png b/html/map/CFIN.png new file mode 100644 index 0000000..af375d1 Binary files /dev/null and b/html/map/CFIN.png differ diff --git a/html/map/CFIO.png b/html/map/CFIO.png new file mode 100644 index 0000000..c5aad4b Binary files /dev/null and b/html/map/CFIO.png differ diff --git a/html/map/CFLE.png b/html/map/CFLE.png new file mode 100644 index 0000000..6267bdb Binary files /dev/null and b/html/map/CFLE.png differ diff --git a/html/map/CFLF.png b/html/map/CFLF.png new file mode 100644 index 0000000..5564dae Binary files /dev/null and b/html/map/CFLF.png differ diff --git a/html/map/CFLN.png b/html/map/CFLN.png new file mode 100644 index 0000000..028b020 Binary files /dev/null and b/html/map/CFLN.png differ diff --git a/html/map/CFLO.png b/html/map/CFLO.png new file mode 100644 index 0000000..b0b67de Binary files /dev/null and b/html/map/CFLO.png differ diff --git a/html/map/CFLU.png b/html/map/CFLU.png new file mode 100644 index 0000000..c36d74c Binary files /dev/null and b/html/map/CFLU.png differ diff --git a/html/map/CFME.png b/html/map/CFME.png new file mode 100644 index 0000000..c3eeb1e Binary files /dev/null and b/html/map/CFME.png differ diff --git a/html/map/CFMF.png b/html/map/CFMF.png new file mode 100644 index 0000000..0e51d92 Binary files /dev/null and b/html/map/CFMF.png differ diff --git a/html/map/CFMN.png b/html/map/CFMN.png new file mode 100644 index 0000000..22f0c48 Binary files /dev/null and b/html/map/CFMN.png differ diff --git a/html/map/CFMO.png b/html/map/CFMO.png new file mode 100644 index 0000000..5c17ef1 Binary files /dev/null and b/html/map/CFMO.png differ diff --git a/html/map/CFWN.png b/html/map/CFWN.png new file mode 100644 index 0000000..4082683 Binary files /dev/null and b/html/map/CFWN.png differ diff --git a/html/map/CFWU.png b/html/map/CFWU.png new file mode 100644 index 0000000..9c1847e Binary files /dev/null and b/html/map/CFWU.png differ diff --git a/html/map/CNCB.png b/html/map/CNCB.png new file mode 100644 index 0000000..e1a4e68 Binary files /dev/null and b/html/map/CNCB.png differ diff --git a/html/map/CNCE.png b/html/map/CNCE.png new file mode 100644 index 0000000..133a99b Binary files /dev/null and b/html/map/CNCE.png differ diff --git a/html/map/CNCF.png b/html/map/CNCF.png new file mode 100644 index 0000000..96a2d76 Binary files /dev/null and b/html/map/CNCF.png differ diff --git a/html/map/CNCN.png b/html/map/CNCN.png new file mode 100644 index 0000000..1240c44 Binary files /dev/null and b/html/map/CNCN.png differ diff --git a/html/map/CNCO.png b/html/map/CNCO.png new file mode 100644 index 0000000..e974148 Binary files /dev/null and b/html/map/CNCO.png differ diff --git a/html/map/CNCU.png b/html/map/CNCU.png new file mode 100644 index 0000000..c65ffea Binary files /dev/null and b/html/map/CNCU.png differ diff --git a/html/map/CNIE.png b/html/map/CNIE.png new file mode 100644 index 0000000..e2ff3f0 Binary files /dev/null and b/html/map/CNIE.png differ diff --git a/html/map/CNIF.png b/html/map/CNIF.png new file mode 100644 index 0000000..af48990 Binary files /dev/null and b/html/map/CNIF.png differ diff --git a/html/map/CNIN.png b/html/map/CNIN.png new file mode 100644 index 0000000..ad063a8 Binary files /dev/null and b/html/map/CNIN.png differ diff --git a/html/map/CNIO.png b/html/map/CNIO.png new file mode 100644 index 0000000..bf05537 Binary files /dev/null and b/html/map/CNIO.png differ diff --git a/html/map/CNLE.png b/html/map/CNLE.png new file mode 100644 index 0000000..6372fb4 Binary files /dev/null and b/html/map/CNLE.png differ diff --git a/html/map/CNLF.png b/html/map/CNLF.png new file mode 100644 index 0000000..9c9da8a Binary files /dev/null and b/html/map/CNLF.png differ diff --git a/html/map/CNLN.png b/html/map/CNLN.png new file mode 100644 index 0000000..fd4cc5e Binary files /dev/null and b/html/map/CNLN.png differ diff --git a/html/map/CNLO.png b/html/map/CNLO.png new file mode 100644 index 0000000..6d3cae7 Binary files /dev/null and b/html/map/CNLO.png differ diff --git a/html/map/CNLU.png b/html/map/CNLU.png new file mode 100644 index 0000000..f6b8354 Binary files /dev/null and b/html/map/CNLU.png differ diff --git a/html/map/CNME.png b/html/map/CNME.png new file mode 100644 index 0000000..2795cf2 Binary files /dev/null and b/html/map/CNME.png differ diff --git a/html/map/CNMF.png b/html/map/CNMF.png new file mode 100644 index 0000000..e0908ab Binary files /dev/null and b/html/map/CNMF.png differ diff --git a/html/map/CNMN.png b/html/map/CNMN.png new file mode 100644 index 0000000..bd24032 Binary files /dev/null and b/html/map/CNMN.png differ diff --git a/html/map/CNMO.png b/html/map/CNMO.png new file mode 100644 index 0000000..134d9d0 Binary files /dev/null and b/html/map/CNMO.png differ diff --git a/html/map/CNWN.png b/html/map/CNWN.png new file mode 100644 index 0000000..56e13d3 Binary files /dev/null and b/html/map/CNWN.png differ diff --git a/html/map/CNWU.png b/html/map/CNWU.png new file mode 100644 index 0000000..604c218 Binary files /dev/null and b/html/map/CNWU.png differ diff --git a/html/map/COCB.png b/html/map/COCB.png new file mode 100644 index 0000000..acfa6de Binary files /dev/null and b/html/map/COCB.png differ diff --git a/html/map/COCE.png b/html/map/COCE.png new file mode 100644 index 0000000..63f38c2 Binary files /dev/null and b/html/map/COCE.png differ diff --git a/html/map/COCF.png b/html/map/COCF.png new file mode 100644 index 0000000..d6c8a4a Binary files /dev/null and b/html/map/COCF.png differ diff --git a/html/map/COCN.png b/html/map/COCN.png new file mode 100644 index 0000000..fbbe70a Binary files /dev/null and b/html/map/COCN.png differ diff --git a/html/map/COCO.png b/html/map/COCO.png new file mode 100644 index 0000000..87190f7 Binary files /dev/null and b/html/map/COCO.png differ diff --git a/html/map/COCU.png b/html/map/COCU.png new file mode 100644 index 0000000..3590e0f Binary files /dev/null and b/html/map/COCU.png differ diff --git a/html/map/COIE.png b/html/map/COIE.png new file mode 100644 index 0000000..af13eed Binary files /dev/null and b/html/map/COIE.png differ diff --git a/html/map/COIF.png b/html/map/COIF.png new file mode 100644 index 0000000..038a1fc Binary files /dev/null and b/html/map/COIF.png differ diff --git a/html/map/COIN.png b/html/map/COIN.png new file mode 100644 index 0000000..3931a73 Binary files /dev/null and b/html/map/COIN.png differ diff --git a/html/map/COIO.png b/html/map/COIO.png new file mode 100644 index 0000000..56eb599 Binary files /dev/null and b/html/map/COIO.png differ diff --git a/html/map/COLE.png b/html/map/COLE.png new file mode 100644 index 0000000..05fac69 Binary files /dev/null and b/html/map/COLE.png differ diff --git a/html/map/COLF.png b/html/map/COLF.png new file mode 100644 index 0000000..335b4c6 Binary files /dev/null and b/html/map/COLF.png differ diff --git a/html/map/COLN.png b/html/map/COLN.png new file mode 100644 index 0000000..05cd58a Binary files /dev/null and b/html/map/COLN.png differ diff --git a/html/map/COLO.png b/html/map/COLO.png new file mode 100644 index 0000000..b930bb7 Binary files /dev/null and b/html/map/COLO.png differ diff --git a/html/map/COLU.png b/html/map/COLU.png new file mode 100644 index 0000000..680264c Binary files /dev/null and b/html/map/COLU.png differ diff --git a/html/map/COME.png b/html/map/COME.png new file mode 100644 index 0000000..b28b174 Binary files /dev/null and b/html/map/COME.png differ diff --git a/html/map/COMF.png b/html/map/COMF.png new file mode 100644 index 0000000..3d7db61 Binary files /dev/null and b/html/map/COMF.png differ diff --git a/html/map/COMN.png b/html/map/COMN.png new file mode 100644 index 0000000..4b48a4c Binary files /dev/null and b/html/map/COMN.png differ diff --git a/html/map/COMO.png b/html/map/COMO.png new file mode 100644 index 0000000..db692a6 Binary files /dev/null and b/html/map/COMO.png differ diff --git a/html/map/COWN.png b/html/map/COWN.png new file mode 100644 index 0000000..256fabd Binary files /dev/null and b/html/map/COWN.png differ diff --git a/html/map/COWU.png b/html/map/COWU.png new file mode 100644 index 0000000..9ae99f2 Binary files /dev/null and b/html/map/COWU.png differ diff --git a/html/map/CPLA.png b/html/map/CPLA.png new file mode 100644 index 0000000..5f1383c Binary files /dev/null and b/html/map/CPLA.png differ diff --git a/html/map/CPLA2.png b/html/map/CPLA2.png new file mode 100644 index 0000000..9fc9724 Binary files /dev/null and b/html/map/CPLA2.png differ diff --git a/html/map/CPLU.png b/html/map/CPLU.png new file mode 100644 index 0000000..676d25b Binary files /dev/null and b/html/map/CPLU.png differ diff --git a/html/map/CPLU2.png b/html/map/CPLU2.png new file mode 100644 index 0000000..ee5189c Binary files /dev/null and b/html/map/CPLU2.png differ diff --git a/html/map/CUCB.png b/html/map/CUCB.png new file mode 100644 index 0000000..bf2a45a Binary files /dev/null and b/html/map/CUCB.png differ diff --git a/html/map/CUCE.png b/html/map/CUCE.png new file mode 100644 index 0000000..1221c5f Binary files /dev/null and b/html/map/CUCE.png differ diff --git a/html/map/CUCF.png b/html/map/CUCF.png new file mode 100644 index 0000000..3d9f974 Binary files /dev/null and b/html/map/CUCF.png differ diff --git a/html/map/CUCN.png b/html/map/CUCN.png new file mode 100644 index 0000000..b3ed30d Binary files /dev/null and b/html/map/CUCN.png differ diff --git a/html/map/CUCO.png b/html/map/CUCO.png new file mode 100644 index 0000000..f661f3c Binary files /dev/null and b/html/map/CUCO.png differ diff --git a/html/map/CUCU.png b/html/map/CUCU.png new file mode 100644 index 0000000..57c5ad9 Binary files /dev/null and b/html/map/CUCU.png differ diff --git a/html/map/CUIE.png b/html/map/CUIE.png new file mode 100644 index 0000000..fe99f6f Binary files /dev/null and b/html/map/CUIE.png differ diff --git a/html/map/CUIF.png b/html/map/CUIF.png new file mode 100644 index 0000000..23dceba Binary files /dev/null and b/html/map/CUIF.png differ diff --git a/html/map/CUIN.png b/html/map/CUIN.png new file mode 100644 index 0000000..e0c7899 Binary files /dev/null and b/html/map/CUIN.png differ diff --git a/html/map/CUIO.png b/html/map/CUIO.png new file mode 100644 index 0000000..5068f52 Binary files /dev/null and b/html/map/CUIO.png differ diff --git a/html/map/CULE.png b/html/map/CULE.png new file mode 100644 index 0000000..1ee21dc Binary files /dev/null and b/html/map/CULE.png differ diff --git a/html/map/CULF.png b/html/map/CULF.png new file mode 100644 index 0000000..107f0e5 Binary files /dev/null and b/html/map/CULF.png differ diff --git a/html/map/CULN.png b/html/map/CULN.png new file mode 100644 index 0000000..a5fad23 Binary files /dev/null and b/html/map/CULN.png differ diff --git a/html/map/CULO.png b/html/map/CULO.png new file mode 100644 index 0000000..788a0dc Binary files /dev/null and b/html/map/CULO.png differ diff --git a/html/map/CULU.png b/html/map/CULU.png new file mode 100644 index 0000000..9b50407 Binary files /dev/null and b/html/map/CULU.png differ diff --git a/html/map/CUME.png b/html/map/CUME.png new file mode 100644 index 0000000..03e5f86 Binary files /dev/null and b/html/map/CUME.png differ diff --git a/html/map/CUMF.png b/html/map/CUMF.png new file mode 100644 index 0000000..cc8dac2 Binary files /dev/null and b/html/map/CUMF.png differ diff --git a/html/map/CUMN.png b/html/map/CUMN.png new file mode 100644 index 0000000..c9fd964 Binary files /dev/null and b/html/map/CUMN.png differ diff --git a/html/map/CUMO.png b/html/map/CUMO.png new file mode 100644 index 0000000..b23fa11 Binary files /dev/null and b/html/map/CUMO.png differ diff --git a/html/map/CUWN.png b/html/map/CUWN.png new file mode 100644 index 0000000..1f5abe0 Binary files /dev/null and b/html/map/CUWN.png differ diff --git a/html/map/CUWU.png b/html/map/CUWU.png new file mode 100644 index 0000000..56ee1cd Binary files /dev/null and b/html/map/CUWU.png differ diff --git a/html/map/Center.psd b/html/map/Center.psd new file mode 100644 index 0000000..83e9e79 Binary files /dev/null and b/html/map/Center.psd differ diff --git a/html/map/HB.png b/html/map/HB.png new file mode 100644 index 0000000..bab718c Binary files /dev/null and b/html/map/HB.png differ diff --git a/html/map/I0.gif b/html/map/I0.gif new file mode 100644 index 0000000..17853e4 Binary files /dev/null and b/html/map/I0.gif differ diff --git a/html/map/I0.png b/html/map/I0.png new file mode 100644 index 0000000..1029b78 Binary files /dev/null and b/html/map/I0.png differ diff --git a/html/map/I1.gif b/html/map/I1.gif new file mode 100644 index 0000000..fd607d0 Binary files /dev/null and b/html/map/I1.gif differ diff --git a/html/map/I1.png b/html/map/I1.png new file mode 100644 index 0000000..daa4092 Binary files /dev/null and b/html/map/I1.png differ diff --git a/html/map/I2.gif b/html/map/I2.gif new file mode 100644 index 0000000..2a39408 Binary files /dev/null and b/html/map/I2.gif differ diff --git a/html/map/I2.png b/html/map/I2.png new file mode 100644 index 0000000..0775db0 Binary files /dev/null and b/html/map/I2.png differ diff --git a/html/map/I3.gif b/html/map/I3.gif new file mode 100644 index 0000000..0cb63f0 Binary files /dev/null and b/html/map/I3.gif differ diff --git a/html/map/I3.png b/html/map/I3.png new file mode 100644 index 0000000..29cd74b Binary files /dev/null and b/html/map/I3.png differ diff --git a/html/map/I4.gif b/html/map/I4.gif new file mode 100644 index 0000000..a47427d Binary files /dev/null and b/html/map/I4.gif differ diff --git a/html/map/I4.png b/html/map/I4.png new file mode 100644 index 0000000..0dbde81 Binary files /dev/null and b/html/map/I4.png differ diff --git a/html/map/I5.gif b/html/map/I5.gif new file mode 100644 index 0000000..4028004 Binary files /dev/null and b/html/map/I5.gif differ diff --git a/html/map/I5.png b/html/map/I5.png new file mode 100644 index 0000000..596ec36 Binary files /dev/null and b/html/map/I5.png differ diff --git a/html/map/I6.gif b/html/map/I6.gif new file mode 100644 index 0000000..7d049d3 Binary files /dev/null and b/html/map/I6.gif differ diff --git a/html/map/I6.png b/html/map/I6.png new file mode 100644 index 0000000..a7bbaf1 Binary files /dev/null and b/html/map/I6.png differ diff --git a/html/map/I7.gif b/html/map/I7.gif new file mode 100644 index 0000000..33412e9 Binary files /dev/null and b/html/map/I7.gif differ diff --git a/html/map/I7.png b/html/map/I7.png new file mode 100644 index 0000000..cc1f28c Binary files /dev/null and b/html/map/I7.png differ diff --git a/html/map/I8.gif b/html/map/I8.gif new file mode 100644 index 0000000..4009599 Binary files /dev/null and b/html/map/I8.gif differ diff --git a/html/map/I8.png b/html/map/I8.png new file mode 100644 index 0000000..c8519ef Binary files /dev/null and b/html/map/I8.png differ diff --git a/html/map/I9.gif b/html/map/I9.gif new file mode 100644 index 0000000..4448744 Binary files /dev/null and b/html/map/I9.gif differ diff --git a/html/map/I9.png b/html/map/I9.png new file mode 100644 index 0000000..a11a137 Binary files /dev/null and b/html/map/I9.png differ diff --git a/html/map/IA.gif b/html/map/IA.gif new file mode 100644 index 0000000..e2e3bc9 Binary files /dev/null and b/html/map/IA.gif differ diff --git a/html/map/IA.png b/html/map/IA.png new file mode 100644 index 0000000..1ebd815 Binary files /dev/null and b/html/map/IA.png differ diff --git a/html/map/IE.gif b/html/map/IE.gif new file mode 100644 index 0000000..409f32d Binary files /dev/null and b/html/map/IE.gif differ diff --git a/html/map/IE.png b/html/map/IE.png new file mode 100644 index 0000000..8aaf6ab Binary files /dev/null and b/html/map/IE.png differ diff --git a/html/map/IF.png b/html/map/IF.png new file mode 100644 index 0000000..45b6594 Binary files /dev/null and b/html/map/IF.png differ diff --git a/html/map/IF2.png b/html/map/IF2.png new file mode 100644 index 0000000..b1666a4 Binary files /dev/null and b/html/map/IF2.png differ diff --git a/html/map/IG.gif b/html/map/IG.gif new file mode 100644 index 0000000..ffa57ac Binary files /dev/null and b/html/map/IG.gif differ diff --git a/html/map/IG.png b/html/map/IG.png new file mode 100644 index 0000000..3024b86 Binary files /dev/null and b/html/map/IG.png differ diff --git a/html/map/II.png b/html/map/II.png new file mode 100644 index 0000000..02c286e Binary files /dev/null and b/html/map/II.png differ diff --git a/html/map/IP.png b/html/map/IP.png new file mode 100644 index 0000000..5657239 Binary files /dev/null and b/html/map/IP.png differ diff --git a/html/map/IU.gif b/html/map/IU.gif new file mode 100644 index 0000000..92e757f Binary files /dev/null and b/html/map/IU.gif differ diff --git a/html/map/IU.png b/html/map/IU.png new file mode 100644 index 0000000..4a70973 Binary files /dev/null and b/html/map/IU.png differ diff --git a/html/map/IW.png b/html/map/IW.png new file mode 100644 index 0000000..d19a4a5 Binary files /dev/null and b/html/map/IW.png differ diff --git a/html/map/README b/html/map/README new file mode 100644 index 0000000..e0cff7d --- /dev/null +++ b/html/map/README @@ -0,0 +1,79 @@ +Die Dateinamen sind so Computer-lesbar wie moeglich: + +Alle die mit B anfangen sind "Backslashes", die mit S +"Slashes", die mit C "Center" und die mit I "Icons". +bei den / und \ Bildern stehen die folgenden beiden +Buchstaben fuer + +B Schwarz +P Pol +W Wasser +U Unbesetzt +N Neutral +O Eigene +F Freunde +E Feinde + +(der erste Buchstabe gibt die "obere" der zweite die "untere" Farbe an). + +Bei den Center-Bildern steht der zweite Buchstabe fuer den +Erdling der drin ist (wie oben), der dritte Buchstabe ist +L Land, Manapol oder Berg ohne Tempel +C Stadt bzw. Heimatstadt +W Wasser bzw. Insel ohne Tempel +I Insel mit Tempel +M Berg mit Tempel + +der Letzte Buchstabe ist der Owner (B steht bei Heimatstaedten fuer +NICHT-HEIMATSTADT also Stadt und U steht bei Bergen fuer NICHT-HEILIG +also Plain). Der auserwaehlte Pol hat ein A als letzten Buchstaben. + +Bei den Icons steht das zweite Zeichen fuer + +0 es sind eigene und feindliche Avatare anwesend + (und vielleicht noch befreundete und/oder neutrale) +1 es sind eigene und neutrale Avatare anwesend + (und vielleicht noch befreundete) +2 es sind eigene und befreundete Avatare anwesend +3 es sind nur eigene Avatare anwesend +4 es sind befreundete und feindliche Avatare anwesend + (und vielleicht noch neutrale) +5 es sind befreundete und neutrale Avatare anwesend +6 es sind nur befreundete Avatare anwesend +7 es sind feindliche und neutrale Avatare anwesend +8 es sind nur feindliche Avatare anwesend +9 es sind nur neutrale Avatare anwesend +A es sind Archen im Feld +E es findet gerade ein Erdlingskampf statt +G es findet gerade ein Avatar-Kampf statt +U leeres Icon (wir in allen vier Ecken als Fuellsel benoetigt) + +So, jetzt das komplette Set - ein paar Namen haben sich noch +geaendert, weil mir ein Fehler unterlaufen war. Wirf das alte +Verzeichnis also besser vorher weg. + +Fuer die Karte ohne Spieler werden nur 31 von den 214 Bildchen +gebraucht, naemlich: + +CPLU Manapol +CPLA Aymargeddon +CUWU Wasser +CUWN Insel +CULU Ebene +CULN Berg +CUCU Heimatstadt +CUCB Stadt + +BBP, BPB, SBP, SPB Manapol am Rand +BWP, BPW, SWP, SPW zwischen Manapol und Wasser +BBW, BWB, SBW, SWB Wasser am Rand +BWW, SWW zwischen Wasserfeldern +BWU, BUW, SWU, SWW zwischen Land und Wasser +BBU, BUB, SBU, SUB Land am Rand +BUU, SUU zwischen Landfeldern + +Drei von den Bildchen sollten bei konsistenten Daten eigentlich +nie benoetigt werden, naemlich COLO, COMO und COIO (die selbe +ID kann nie an einen Gott und einen Erdling gleichzeitig vergeben +sein). Zu Testzwecken sind sie dennoch vorhanden. + diff --git a/html/map/Rand2.psd b/html/map/Rand2.psd new file mode 100644 index 0000000..d8280d3 Binary files /dev/null and b/html/map/Rand2.psd differ diff --git a/html/map/SBB.png b/html/map/SBB.png new file mode 100644 index 0000000..5bfcd29 Binary files /dev/null and b/html/map/SBB.png differ diff --git a/html/map/SBE.png b/html/map/SBE.png new file mode 100644 index 0000000..3177f0c Binary files /dev/null and b/html/map/SBE.png differ diff --git a/html/map/SBF.png b/html/map/SBF.png new file mode 100644 index 0000000..76d197a Binary files /dev/null and b/html/map/SBF.png differ diff --git a/html/map/SBN.png b/html/map/SBN.png new file mode 100644 index 0000000..5123729 Binary files /dev/null and b/html/map/SBN.png differ diff --git a/html/map/SBO.png b/html/map/SBO.png new file mode 100644 index 0000000..75cb096 Binary files /dev/null and b/html/map/SBO.png differ diff --git a/html/map/SBP.png b/html/map/SBP.png new file mode 100644 index 0000000..65a93bd Binary files /dev/null and b/html/map/SBP.png differ diff --git a/html/map/SBP2.png b/html/map/SBP2.png new file mode 100644 index 0000000..8243c00 Binary files /dev/null and b/html/map/SBP2.png differ diff --git a/html/map/SBU.png b/html/map/SBU.png new file mode 100644 index 0000000..b295c55 Binary files /dev/null and b/html/map/SBU.png differ diff --git a/html/map/SBW.png b/html/map/SBW.png new file mode 100644 index 0000000..65a93bd Binary files /dev/null and b/html/map/SBW.png differ diff --git a/html/map/SEB.png b/html/map/SEB.png new file mode 100644 index 0000000..b85093a Binary files /dev/null and b/html/map/SEB.png differ diff --git a/html/map/SEE.png b/html/map/SEE.png new file mode 100644 index 0000000..16b35a5 Binary files /dev/null and b/html/map/SEE.png differ diff --git a/html/map/SEF.png b/html/map/SEF.png new file mode 100644 index 0000000..95e73dc Binary files /dev/null and b/html/map/SEF.png differ diff --git a/html/map/SEN.png b/html/map/SEN.png new file mode 100644 index 0000000..7e860c7 Binary files /dev/null and b/html/map/SEN.png differ diff --git a/html/map/SEO.png b/html/map/SEO.png new file mode 100644 index 0000000..63e932c Binary files /dev/null and b/html/map/SEO.png differ diff --git a/html/map/SEU.png b/html/map/SEU.png new file mode 100644 index 0000000..f14a201 Binary files /dev/null and b/html/map/SEU.png differ diff --git a/html/map/SEW.png b/html/map/SEW.png new file mode 100644 index 0000000..e08b411 Binary files /dev/null and b/html/map/SEW.png differ diff --git a/html/map/SFB.png b/html/map/SFB.png new file mode 100644 index 0000000..073616d Binary files /dev/null and b/html/map/SFB.png differ diff --git a/html/map/SFE.png b/html/map/SFE.png new file mode 100644 index 0000000..41b699b Binary files /dev/null and b/html/map/SFE.png differ diff --git a/html/map/SFF.png b/html/map/SFF.png new file mode 100644 index 0000000..ea71c5c Binary files /dev/null and b/html/map/SFF.png differ diff --git a/html/map/SFN.png b/html/map/SFN.png new file mode 100644 index 0000000..5d1f659 Binary files /dev/null and b/html/map/SFN.png differ diff --git a/html/map/SFO.png b/html/map/SFO.png new file mode 100644 index 0000000..495ce2b Binary files /dev/null and b/html/map/SFO.png differ diff --git a/html/map/SFU.png b/html/map/SFU.png new file mode 100644 index 0000000..2dd92d7 Binary files /dev/null and b/html/map/SFU.png differ diff --git a/html/map/SFW.png b/html/map/SFW.png new file mode 100644 index 0000000..a785ba7 Binary files /dev/null and b/html/map/SFW.png differ diff --git a/html/map/SNB.png b/html/map/SNB.png new file mode 100644 index 0000000..0029f78 Binary files /dev/null and b/html/map/SNB.png differ diff --git a/html/map/SNE.png b/html/map/SNE.png new file mode 100644 index 0000000..7db700f Binary files /dev/null and b/html/map/SNE.png differ diff --git a/html/map/SNF.png b/html/map/SNF.png new file mode 100644 index 0000000..4ae88c4 Binary files /dev/null and b/html/map/SNF.png differ diff --git a/html/map/SNN.png b/html/map/SNN.png new file mode 100644 index 0000000..d91b582 Binary files /dev/null and b/html/map/SNN.png differ diff --git a/html/map/SNO.png b/html/map/SNO.png new file mode 100644 index 0000000..2bc9629 Binary files /dev/null and b/html/map/SNO.png differ diff --git a/html/map/SNU.png b/html/map/SNU.png new file mode 100644 index 0000000..5d74110 Binary files /dev/null and b/html/map/SNU.png differ diff --git a/html/map/SNW.png b/html/map/SNW.png new file mode 100644 index 0000000..60e0e1d Binary files /dev/null and b/html/map/SNW.png differ diff --git a/html/map/SOB.png b/html/map/SOB.png new file mode 100644 index 0000000..b787443 Binary files /dev/null and b/html/map/SOB.png differ diff --git a/html/map/SOE.png b/html/map/SOE.png new file mode 100644 index 0000000..d0e4f08 Binary files /dev/null and b/html/map/SOE.png differ diff --git a/html/map/SOF.png b/html/map/SOF.png new file mode 100644 index 0000000..15b1e98 Binary files /dev/null and b/html/map/SOF.png differ diff --git a/html/map/SON.png b/html/map/SON.png new file mode 100644 index 0000000..6d0c02b Binary files /dev/null and b/html/map/SON.png differ diff --git a/html/map/SOO.png b/html/map/SOO.png new file mode 100644 index 0000000..3cc6f0e Binary files /dev/null and b/html/map/SOO.png differ diff --git a/html/map/SOU.png b/html/map/SOU.png new file mode 100644 index 0000000..535d713 Binary files /dev/null and b/html/map/SOU.png differ diff --git a/html/map/SOW.png b/html/map/SOW.png new file mode 100644 index 0000000..7626387 Binary files /dev/null and b/html/map/SOW.png differ diff --git a/html/map/SPB.png b/html/map/SPB.png new file mode 100644 index 0000000..c181623 Binary files /dev/null and b/html/map/SPB.png differ diff --git a/html/map/SPB2.png b/html/map/SPB2.png new file mode 100644 index 0000000..507380e Binary files /dev/null and b/html/map/SPB2.png differ diff --git a/html/map/SPW.png b/html/map/SPW.png new file mode 100644 index 0000000..d06f8e5 Binary files /dev/null and b/html/map/SPW.png differ diff --git a/html/map/SPW2.png b/html/map/SPW2.png new file mode 100644 index 0000000..8be1e55 Binary files /dev/null and b/html/map/SPW2.png differ diff --git a/html/map/ST.gif b/html/map/ST.gif new file mode 100644 index 0000000..61d6437 Binary files /dev/null and b/html/map/ST.gif differ diff --git a/html/map/SUB.png b/html/map/SUB.png new file mode 100644 index 0000000..0ec9249 Binary files /dev/null and b/html/map/SUB.png differ diff --git a/html/map/SUE.png b/html/map/SUE.png new file mode 100644 index 0000000..aaf8168 Binary files /dev/null and b/html/map/SUE.png differ diff --git a/html/map/SUF.png b/html/map/SUF.png new file mode 100644 index 0000000..edafa12 Binary files /dev/null and b/html/map/SUF.png differ diff --git a/html/map/SUN.png b/html/map/SUN.png new file mode 100644 index 0000000..0234cf9 Binary files /dev/null and b/html/map/SUN.png differ diff --git a/html/map/SUO.png b/html/map/SUO.png new file mode 100644 index 0000000..bf06d1c Binary files /dev/null and b/html/map/SUO.png differ diff --git a/html/map/SUU.png b/html/map/SUU.png new file mode 100644 index 0000000..ed68329 Binary files /dev/null and b/html/map/SUU.png differ diff --git a/html/map/SUW.png b/html/map/SUW.png new file mode 100644 index 0000000..2f128a8 Binary files /dev/null and b/html/map/SUW.png differ diff --git a/html/map/SWB.png b/html/map/SWB.png new file mode 100644 index 0000000..c181623 Binary files /dev/null and b/html/map/SWB.png differ diff --git a/html/map/SWE.png b/html/map/SWE.png new file mode 100644 index 0000000..c55dac8 Binary files /dev/null and b/html/map/SWE.png differ diff --git a/html/map/SWF.png b/html/map/SWF.png new file mode 100644 index 0000000..8f4d1c0 Binary files /dev/null and b/html/map/SWF.png differ diff --git a/html/map/SWN.png b/html/map/SWN.png new file mode 100644 index 0000000..6bd1313 Binary files /dev/null and b/html/map/SWN.png differ diff --git a/html/map/SWO.png b/html/map/SWO.png new file mode 100644 index 0000000..4bb8506 Binary files /dev/null and b/html/map/SWO.png differ diff --git a/html/map/SWP.png b/html/map/SWP.png new file mode 100644 index 0000000..d06f8e5 Binary files /dev/null and b/html/map/SWP.png differ diff --git a/html/map/SWP2.png b/html/map/SWP2.png new file mode 100644 index 0000000..4b7f93b Binary files /dev/null and b/html/map/SWP2.png differ diff --git a/html/map/SWU.png b/html/map/SWU.png new file mode 100644 index 0000000..185c9b8 Binary files /dev/null and b/html/map/SWU.png differ diff --git a/html/map/SWW.png b/html/map/SWW.png new file mode 100644 index 0000000..d06f8e5 Binary files /dev/null and b/html/map/SWW.png differ diff --git a/html/map/Testmap.png b/html/map/Testmap.png new file mode 100644 index 0000000..d84b6c4 Binary files /dev/null and b/html/map/Testmap.png differ diff --git a/html/mapframe.epl b/html/mapframe.epl new file mode 100644 index 0000000..d7aa8c3 --- /dev/null +++ b/html/mapframe.epl @@ -0,0 +1,20 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" + "http://www.w3.org/TR/html4/frameset.dtd"> +<html> + <head> + <title>Aymargeddon</title> + </head> + + [- $udat{-current} = 'mapframe.epl'; -] + + <frameset rows="34,*"> + <frame src="menu_frames.epl" name="menu" /> + <frameset cols="*,200"> + <frame src="map.epl" name="map" /> + <frame src="field.epl?x=0,y=0" name="field" /> + </frameset> + <noframes> + keine frames + </noframes> + </frameset> +</html> diff --git a/html/menu.epl b/html/menu.epl new file mode 100644 index 0000000..061bed1 --- /dev/null +++ b/html/menu.epl @@ -0,0 +1,39 @@ +[- + use FROGS::Game; + use Aymargeddon; + use FROGS::DataBase; + + # my ($aym,$gamename); + $db = DataBase->new(); + $db->set_language($udat{-lang}); + if($udat{-game} and $udat{-id}){ + $aym = Aymargeddon->new($udat{-game},$udat{-id},$db); + $game = $aym; + $db->set_language($udat{-lang}); + ($gamename) = $db->read_game($udat{-game},'NAME'); + } + +-] +<table width=100% border=0><tr> +<td align="left"> +<a href="index.epl" target="_top">[+ $db->loc('PAGE_START') +]</a> | +<a href="ruleframe.epl" target="_top">[+ $db->loc('PAGE_RULES') +]</a> | +<a href="reference.epl" target="_top">[+ $db->loc('PAGE_REFERENCE') +]</a> | +[$ if $udat{-id} $] + <a href="player.epl" target="_top">[+ $db->loc('PAGE_PLAYER') +]</a> | + [$ if $udat{-game} and ($udat{-id}==-1 or $game->read_role($udat{-id},'NICKNAME')) $] + <a href="mapframe.epl" target="_top">[+ $db->loc('PAGE_MAP') +]</a> | + [$ endif $] + <a href="login.epl" target="_top">[+ $db->loc('PAGE_LOGOUT') +]</a> | +[$ else $] + <a href="login.epl" target="_top">[+ $db->loc('PAGE_LOGIN') +]</a> | +[$ endif $] +<a href="language.epl" target="_top">[+ $db->loc('PAGE_LANGUAGE') +]</a> +</td><td align="right"> +[$ if(defined $aym) $] +[# TODO: this does not work during character-generation #] + <strong>[+ $gamename +]</strong>, [+ $aym->role_string($udat{-id}) +], + [+ $aym->charname($udat{-id}) +]<p> +[$ endif $] +</td> +</tr></table> diff --git a/html/menu_frames.epl b/html/menu_frames.epl new file mode 100644 index 0000000..82748e1 --- /dev/null +++ b/html/menu_frames.epl @@ -0,0 +1,10 @@ +<html> +<head> +<link rel="stylesheet" type="text/css" href="aymargeddon.css"> +<title> +Aymargeddon - Menubar +</title> +</head> +<body>[- Execute('menu.epl') -] +</body> +</html> diff --git a/html/pic/Screenshot.png b/html/pic/Screenshot.png new file mode 100644 index 0000000..d16a2c5 Binary files /dev/null and b/html/pic/Screenshot.png differ diff --git a/html/pic/map/Aymargeddon.ACT b/html/pic/map/Aymargeddon.ACT new file mode 100644 index 0000000..df137ca Binary files /dev/null and b/html/pic/map/Aymargeddon.ACT differ diff --git a/html/pic/map/BBB.png b/html/pic/map/BBB.png new file mode 100644 index 0000000..5bfcd29 Binary files /dev/null and b/html/pic/map/BBB.png differ diff --git a/html/pic/map/BBE.png b/html/pic/map/BBE.png new file mode 100644 index 0000000..5ccfc42 Binary files /dev/null and b/html/pic/map/BBE.png differ diff --git a/html/pic/map/BBF.png b/html/pic/map/BBF.png new file mode 100644 index 0000000..d21f9b8 Binary files /dev/null and b/html/pic/map/BBF.png differ diff --git a/html/pic/map/BBN.png b/html/pic/map/BBN.png new file mode 100644 index 0000000..e983887 Binary files /dev/null and b/html/pic/map/BBN.png differ diff --git a/html/pic/map/BBO.png b/html/pic/map/BBO.png new file mode 100644 index 0000000..d3dba3c Binary files /dev/null and b/html/pic/map/BBO.png differ diff --git a/html/pic/map/BBP.png b/html/pic/map/BBP.png new file mode 100644 index 0000000..05c1aa3 Binary files /dev/null and b/html/pic/map/BBP.png differ diff --git a/html/pic/map/BBP2.png b/html/pic/map/BBP2.png new file mode 100644 index 0000000..d17648d Binary files /dev/null and b/html/pic/map/BBP2.png differ diff --git a/html/pic/map/BBU.png b/html/pic/map/BBU.png new file mode 100644 index 0000000..809a570 Binary files /dev/null and b/html/pic/map/BBU.png differ diff --git a/html/pic/map/BBW.png b/html/pic/map/BBW.png new file mode 100644 index 0000000..05c1aa3 Binary files /dev/null and b/html/pic/map/BBW.png differ diff --git a/html/pic/map/BEB.png b/html/pic/map/BEB.png new file mode 100644 index 0000000..0debbd2 Binary files /dev/null and b/html/pic/map/BEB.png differ diff --git a/html/pic/map/BEE.png b/html/pic/map/BEE.png new file mode 100644 index 0000000..bd314ae Binary files /dev/null and b/html/pic/map/BEE.png differ diff --git a/html/pic/map/BEF.png b/html/pic/map/BEF.png new file mode 100644 index 0000000..eae65fd Binary files /dev/null and b/html/pic/map/BEF.png differ diff --git a/html/pic/map/BEN.png b/html/pic/map/BEN.png new file mode 100644 index 0000000..bdbd018 Binary files /dev/null and b/html/pic/map/BEN.png differ diff --git a/html/pic/map/BEO.png b/html/pic/map/BEO.png new file mode 100644 index 0000000..0764d88 Binary files /dev/null and b/html/pic/map/BEO.png differ diff --git a/html/pic/map/BEU.png b/html/pic/map/BEU.png new file mode 100644 index 0000000..b1cca5e Binary files /dev/null and b/html/pic/map/BEU.png differ diff --git a/html/pic/map/BEW.png b/html/pic/map/BEW.png new file mode 100644 index 0000000..a8a9111 Binary files /dev/null and b/html/pic/map/BEW.png differ diff --git a/html/pic/map/BFB.png b/html/pic/map/BFB.png new file mode 100644 index 0000000..9c2218b Binary files /dev/null and b/html/pic/map/BFB.png differ diff --git a/html/pic/map/BFE.png b/html/pic/map/BFE.png new file mode 100644 index 0000000..c33afc9 Binary files /dev/null and b/html/pic/map/BFE.png differ diff --git a/html/pic/map/BFF.png b/html/pic/map/BFF.png new file mode 100644 index 0000000..14c0aaf Binary files /dev/null and b/html/pic/map/BFF.png differ diff --git a/html/pic/map/BFN.png b/html/pic/map/BFN.png new file mode 100644 index 0000000..d3ef082 Binary files /dev/null and b/html/pic/map/BFN.png differ diff --git a/html/pic/map/BFO.png b/html/pic/map/BFO.png new file mode 100644 index 0000000..8761b79 Binary files /dev/null and b/html/pic/map/BFO.png differ diff --git a/html/pic/map/BFU.png b/html/pic/map/BFU.png new file mode 100644 index 0000000..9006f95 Binary files /dev/null and b/html/pic/map/BFU.png differ diff --git a/html/pic/map/BFW.png b/html/pic/map/BFW.png new file mode 100644 index 0000000..c5ebf70 Binary files /dev/null and b/html/pic/map/BFW.png differ diff --git a/html/pic/map/BNB.png b/html/pic/map/BNB.png new file mode 100644 index 0000000..a3d708f Binary files /dev/null and b/html/pic/map/BNB.png differ diff --git a/html/pic/map/BNE.png b/html/pic/map/BNE.png new file mode 100644 index 0000000..485f4cf Binary files /dev/null and b/html/pic/map/BNE.png differ diff --git a/html/pic/map/BNF.png b/html/pic/map/BNF.png new file mode 100644 index 0000000..d57622c Binary files /dev/null and b/html/pic/map/BNF.png differ diff --git a/html/pic/map/BNN.png b/html/pic/map/BNN.png new file mode 100644 index 0000000..f98ca9f Binary files /dev/null and b/html/pic/map/BNN.png differ diff --git a/html/pic/map/BNO.png b/html/pic/map/BNO.png new file mode 100644 index 0000000..38effbe Binary files /dev/null and b/html/pic/map/BNO.png differ diff --git a/html/pic/map/BNU.png b/html/pic/map/BNU.png new file mode 100644 index 0000000..cc823eb Binary files /dev/null and b/html/pic/map/BNU.png differ diff --git a/html/pic/map/BNW.png b/html/pic/map/BNW.png new file mode 100644 index 0000000..076c82a Binary files /dev/null and b/html/pic/map/BNW.png differ diff --git a/html/pic/map/BOB.png b/html/pic/map/BOB.png new file mode 100644 index 0000000..a3235a3 Binary files /dev/null and b/html/pic/map/BOB.png differ diff --git a/html/pic/map/BOE.png b/html/pic/map/BOE.png new file mode 100644 index 0000000..0bafbd8 Binary files /dev/null and b/html/pic/map/BOE.png differ diff --git a/html/pic/map/BOF.png b/html/pic/map/BOF.png new file mode 100644 index 0000000..bab000c Binary files /dev/null and b/html/pic/map/BOF.png differ diff --git a/html/pic/map/BON.png b/html/pic/map/BON.png new file mode 100644 index 0000000..cacedb7 Binary files /dev/null and b/html/pic/map/BON.png differ diff --git a/html/pic/map/BOO.png b/html/pic/map/BOO.png new file mode 100644 index 0000000..55d2521 Binary files /dev/null and b/html/pic/map/BOO.png differ diff --git a/html/pic/map/BOU.png b/html/pic/map/BOU.png new file mode 100644 index 0000000..bf79097 Binary files /dev/null and b/html/pic/map/BOU.png differ diff --git a/html/pic/map/BOW.png b/html/pic/map/BOW.png new file mode 100644 index 0000000..5a987e5 Binary files /dev/null and b/html/pic/map/BOW.png differ diff --git a/html/pic/map/BPB.png b/html/pic/map/BPB.png new file mode 100644 index 0000000..c42879a Binary files /dev/null and b/html/pic/map/BPB.png differ diff --git a/html/pic/map/BPB2.png b/html/pic/map/BPB2.png new file mode 100644 index 0000000..3191893 Binary files /dev/null and b/html/pic/map/BPB2.png differ diff --git a/html/pic/map/BPW.png b/html/pic/map/BPW.png new file mode 100644 index 0000000..96557e9 Binary files /dev/null and b/html/pic/map/BPW.png differ diff --git a/html/pic/map/BPW2.png b/html/pic/map/BPW2.png new file mode 100644 index 0000000..ea77bd0 Binary files /dev/null and b/html/pic/map/BPW2.png differ diff --git a/html/pic/map/BT.gif b/html/pic/map/BT.gif new file mode 100644 index 0000000..fad6d44 Binary files /dev/null and b/html/pic/map/BT.gif differ diff --git a/html/pic/map/BUB.png b/html/pic/map/BUB.png new file mode 100644 index 0000000..80f99dd Binary files /dev/null and b/html/pic/map/BUB.png differ diff --git a/html/pic/map/BUE.png b/html/pic/map/BUE.png new file mode 100644 index 0000000..c0c59f4 Binary files /dev/null and b/html/pic/map/BUE.png differ diff --git a/html/pic/map/BUF.png b/html/pic/map/BUF.png new file mode 100644 index 0000000..36770fd Binary files /dev/null and b/html/pic/map/BUF.png differ diff --git a/html/pic/map/BUN.png b/html/pic/map/BUN.png new file mode 100644 index 0000000..8f201e1 Binary files /dev/null and b/html/pic/map/BUN.png differ diff --git a/html/pic/map/BUO.png b/html/pic/map/BUO.png new file mode 100644 index 0000000..bd192ee Binary files /dev/null and b/html/pic/map/BUO.png differ diff --git a/html/pic/map/BUU.png b/html/pic/map/BUU.png new file mode 100644 index 0000000..4439a99 Binary files /dev/null and b/html/pic/map/BUU.png differ diff --git a/html/pic/map/BUW.png b/html/pic/map/BUW.png new file mode 100644 index 0000000..27bb253 Binary files /dev/null and b/html/pic/map/BUW.png differ diff --git a/html/pic/map/BWB.png b/html/pic/map/BWB.png new file mode 100644 index 0000000..c42879a Binary files /dev/null and b/html/pic/map/BWB.png differ diff --git a/html/pic/map/BWE.png b/html/pic/map/BWE.png new file mode 100644 index 0000000..8ab27ca Binary files /dev/null and b/html/pic/map/BWE.png differ diff --git a/html/pic/map/BWF.png b/html/pic/map/BWF.png new file mode 100644 index 0000000..b2542ba Binary files /dev/null and b/html/pic/map/BWF.png differ diff --git a/html/pic/map/BWN.png b/html/pic/map/BWN.png new file mode 100644 index 0000000..4a92aa6 Binary files /dev/null and b/html/pic/map/BWN.png differ diff --git a/html/pic/map/BWO.png b/html/pic/map/BWO.png new file mode 100644 index 0000000..b5ca713 Binary files /dev/null and b/html/pic/map/BWO.png differ diff --git a/html/pic/map/BWP.png b/html/pic/map/BWP.png new file mode 100644 index 0000000..96557e9 Binary files /dev/null and b/html/pic/map/BWP.png differ diff --git a/html/pic/map/BWP2.png b/html/pic/map/BWP2.png new file mode 100644 index 0000000..16609d0 Binary files /dev/null and b/html/pic/map/BWP2.png differ diff --git a/html/pic/map/BWU.png b/html/pic/map/BWU.png new file mode 100644 index 0000000..e970ff2 Binary files /dev/null and b/html/pic/map/BWU.png differ diff --git a/html/pic/map/BWW.png b/html/pic/map/BWW.png new file mode 100644 index 0000000..96557e9 Binary files /dev/null and b/html/pic/map/BWW.png differ diff --git a/html/pic/map/CB.png b/html/pic/map/CB.png new file mode 100644 index 0000000..41281d6 Binary files /dev/null and b/html/pic/map/CB.png differ diff --git a/html/pic/map/CECB.png b/html/pic/map/CECB.png new file mode 100644 index 0000000..c5d685a Binary files /dev/null and b/html/pic/map/CECB.png differ diff --git a/html/pic/map/CECE.png b/html/pic/map/CECE.png new file mode 100644 index 0000000..0668631 Binary files /dev/null and b/html/pic/map/CECE.png differ diff --git a/html/pic/map/CECF.png b/html/pic/map/CECF.png new file mode 100644 index 0000000..af46161 Binary files /dev/null and b/html/pic/map/CECF.png differ diff --git a/html/pic/map/CECN.png b/html/pic/map/CECN.png new file mode 100644 index 0000000..fb58102 Binary files /dev/null and b/html/pic/map/CECN.png differ diff --git a/html/pic/map/CECO.png b/html/pic/map/CECO.png new file mode 100644 index 0000000..dab9cc0 Binary files /dev/null and b/html/pic/map/CECO.png differ diff --git a/html/pic/map/CECU.png b/html/pic/map/CECU.png new file mode 100644 index 0000000..b14de5e Binary files /dev/null and b/html/pic/map/CECU.png differ diff --git a/html/pic/map/CEIE.png b/html/pic/map/CEIE.png new file mode 100644 index 0000000..7fcd3a8 Binary files /dev/null and b/html/pic/map/CEIE.png differ diff --git a/html/pic/map/CEIF.png b/html/pic/map/CEIF.png new file mode 100644 index 0000000..c15f48d Binary files /dev/null and b/html/pic/map/CEIF.png differ diff --git a/html/pic/map/CEIN.png b/html/pic/map/CEIN.png new file mode 100644 index 0000000..3de6989 Binary files /dev/null and b/html/pic/map/CEIN.png differ diff --git a/html/pic/map/CEIO.png b/html/pic/map/CEIO.png new file mode 100644 index 0000000..f3e7bfa Binary files /dev/null and b/html/pic/map/CEIO.png differ diff --git a/html/pic/map/CELE.png b/html/pic/map/CELE.png new file mode 100644 index 0000000..83cc691 Binary files /dev/null and b/html/pic/map/CELE.png differ diff --git a/html/pic/map/CELF.png b/html/pic/map/CELF.png new file mode 100644 index 0000000..d1a90f9 Binary files /dev/null and b/html/pic/map/CELF.png differ diff --git a/html/pic/map/CELN.png b/html/pic/map/CELN.png new file mode 100644 index 0000000..c40bc34 Binary files /dev/null and b/html/pic/map/CELN.png differ diff --git a/html/pic/map/CELO.png b/html/pic/map/CELO.png new file mode 100644 index 0000000..6d9c504 Binary files /dev/null and b/html/pic/map/CELO.png differ diff --git a/html/pic/map/CELU.png b/html/pic/map/CELU.png new file mode 100644 index 0000000..8f7bf28 Binary files /dev/null and b/html/pic/map/CELU.png differ diff --git a/html/pic/map/CEME.png b/html/pic/map/CEME.png new file mode 100644 index 0000000..7148aba Binary files /dev/null and b/html/pic/map/CEME.png differ diff --git a/html/pic/map/CEMF.png b/html/pic/map/CEMF.png new file mode 100644 index 0000000..bf6109f Binary files /dev/null and b/html/pic/map/CEMF.png differ diff --git a/html/pic/map/CEMN.png b/html/pic/map/CEMN.png new file mode 100644 index 0000000..65b5b1c Binary files /dev/null and b/html/pic/map/CEMN.png differ diff --git a/html/pic/map/CEMO.png b/html/pic/map/CEMO.png new file mode 100644 index 0000000..e0d75c5 Binary files /dev/null and b/html/pic/map/CEMO.png differ diff --git a/html/pic/map/CEWN.png b/html/pic/map/CEWN.png new file mode 100644 index 0000000..4081da3 Binary files /dev/null and b/html/pic/map/CEWN.png differ diff --git a/html/pic/map/CEWU.png b/html/pic/map/CEWU.png new file mode 100644 index 0000000..d012b27 Binary files /dev/null and b/html/pic/map/CEWU.png differ diff --git a/html/pic/map/CFCB.png b/html/pic/map/CFCB.png new file mode 100644 index 0000000..f98349b Binary files /dev/null and b/html/pic/map/CFCB.png differ diff --git a/html/pic/map/CFCE.png b/html/pic/map/CFCE.png new file mode 100644 index 0000000..391718a Binary files /dev/null and b/html/pic/map/CFCE.png differ diff --git a/html/pic/map/CFCF.png b/html/pic/map/CFCF.png new file mode 100644 index 0000000..fa1a312 Binary files /dev/null and b/html/pic/map/CFCF.png differ diff --git a/html/pic/map/CFCN.png b/html/pic/map/CFCN.png new file mode 100644 index 0000000..6a10c3f Binary files /dev/null and b/html/pic/map/CFCN.png differ diff --git a/html/pic/map/CFCO.png b/html/pic/map/CFCO.png new file mode 100644 index 0000000..801b528 Binary files /dev/null and b/html/pic/map/CFCO.png differ diff --git a/html/pic/map/CFCU.png b/html/pic/map/CFCU.png new file mode 100644 index 0000000..00e6914 Binary files /dev/null and b/html/pic/map/CFCU.png differ diff --git a/html/pic/map/CFIE.png b/html/pic/map/CFIE.png new file mode 100644 index 0000000..fc32c1f Binary files /dev/null and b/html/pic/map/CFIE.png differ diff --git a/html/pic/map/CFIF.png b/html/pic/map/CFIF.png new file mode 100644 index 0000000..f1d3708 Binary files /dev/null and b/html/pic/map/CFIF.png differ diff --git a/html/pic/map/CFIN.png b/html/pic/map/CFIN.png new file mode 100644 index 0000000..af375d1 Binary files /dev/null and b/html/pic/map/CFIN.png differ diff --git a/html/pic/map/CFIO.png b/html/pic/map/CFIO.png new file mode 100644 index 0000000..c5aad4b Binary files /dev/null and b/html/pic/map/CFIO.png differ diff --git a/html/pic/map/CFLE.png b/html/pic/map/CFLE.png new file mode 100644 index 0000000..6267bdb Binary files /dev/null and b/html/pic/map/CFLE.png differ diff --git a/html/pic/map/CFLF.png b/html/pic/map/CFLF.png new file mode 100644 index 0000000..5564dae Binary files /dev/null and b/html/pic/map/CFLF.png differ diff --git a/html/pic/map/CFLN.png b/html/pic/map/CFLN.png new file mode 100644 index 0000000..028b020 Binary files /dev/null and b/html/pic/map/CFLN.png differ diff --git a/html/pic/map/CFLO.png b/html/pic/map/CFLO.png new file mode 100644 index 0000000..b0b67de Binary files /dev/null and b/html/pic/map/CFLO.png differ diff --git a/html/pic/map/CFLU.png b/html/pic/map/CFLU.png new file mode 100644 index 0000000..c36d74c Binary files /dev/null and b/html/pic/map/CFLU.png differ diff --git a/html/pic/map/CFME.png b/html/pic/map/CFME.png new file mode 100644 index 0000000..c3eeb1e Binary files /dev/null and b/html/pic/map/CFME.png differ diff --git a/html/pic/map/CFMF.png b/html/pic/map/CFMF.png new file mode 100644 index 0000000..0e51d92 Binary files /dev/null and b/html/pic/map/CFMF.png differ diff --git a/html/pic/map/CFMN.png b/html/pic/map/CFMN.png new file mode 100644 index 0000000..22f0c48 Binary files /dev/null and b/html/pic/map/CFMN.png differ diff --git a/html/pic/map/CFMO.png b/html/pic/map/CFMO.png new file mode 100644 index 0000000..5c17ef1 Binary files /dev/null and b/html/pic/map/CFMO.png differ diff --git a/html/pic/map/CFWN.png b/html/pic/map/CFWN.png new file mode 100644 index 0000000..4082683 Binary files /dev/null and b/html/pic/map/CFWN.png differ diff --git a/html/pic/map/CFWU.png b/html/pic/map/CFWU.png new file mode 100644 index 0000000..9c1847e Binary files /dev/null and b/html/pic/map/CFWU.png differ diff --git a/html/pic/map/CNCB.png b/html/pic/map/CNCB.png new file mode 100644 index 0000000..e1a4e68 Binary files /dev/null and b/html/pic/map/CNCB.png differ diff --git a/html/pic/map/CNCE.png b/html/pic/map/CNCE.png new file mode 100644 index 0000000..133a99b Binary files /dev/null and b/html/pic/map/CNCE.png differ diff --git a/html/pic/map/CNCF.png b/html/pic/map/CNCF.png new file mode 100644 index 0000000..96a2d76 Binary files /dev/null and b/html/pic/map/CNCF.png differ diff --git a/html/pic/map/CNCN.png b/html/pic/map/CNCN.png new file mode 100644 index 0000000..1240c44 Binary files /dev/null and b/html/pic/map/CNCN.png differ diff --git a/html/pic/map/CNCO.png b/html/pic/map/CNCO.png new file mode 100644 index 0000000..e974148 Binary files /dev/null and b/html/pic/map/CNCO.png differ diff --git a/html/pic/map/CNCU.png b/html/pic/map/CNCU.png new file mode 100644 index 0000000..c65ffea Binary files /dev/null and b/html/pic/map/CNCU.png differ diff --git a/html/pic/map/CNIE.png b/html/pic/map/CNIE.png new file mode 100644 index 0000000..e2ff3f0 Binary files /dev/null and b/html/pic/map/CNIE.png differ diff --git a/html/pic/map/CNIF.png b/html/pic/map/CNIF.png new file mode 100644 index 0000000..af48990 Binary files /dev/null and b/html/pic/map/CNIF.png differ diff --git a/html/pic/map/CNIN.png b/html/pic/map/CNIN.png new file mode 100644 index 0000000..ad063a8 Binary files /dev/null and b/html/pic/map/CNIN.png differ diff --git a/html/pic/map/CNIO.png b/html/pic/map/CNIO.png new file mode 100644 index 0000000..bf05537 Binary files /dev/null and b/html/pic/map/CNIO.png differ diff --git a/html/pic/map/CNLE.png b/html/pic/map/CNLE.png new file mode 100644 index 0000000..6372fb4 Binary files /dev/null and b/html/pic/map/CNLE.png differ diff --git a/html/pic/map/CNLF.png b/html/pic/map/CNLF.png new file mode 100644 index 0000000..9c9da8a Binary files /dev/null and b/html/pic/map/CNLF.png differ diff --git a/html/pic/map/CNLN.png b/html/pic/map/CNLN.png new file mode 100644 index 0000000..fd4cc5e Binary files /dev/null and b/html/pic/map/CNLN.png differ diff --git a/html/pic/map/CNLO.png b/html/pic/map/CNLO.png new file mode 100644 index 0000000..6d3cae7 Binary files /dev/null and b/html/pic/map/CNLO.png differ diff --git a/html/pic/map/CNLU.png b/html/pic/map/CNLU.png new file mode 100644 index 0000000..f6b8354 Binary files /dev/null and b/html/pic/map/CNLU.png differ diff --git a/html/pic/map/CNME.png b/html/pic/map/CNME.png new file mode 100644 index 0000000..2795cf2 Binary files /dev/null and b/html/pic/map/CNME.png differ diff --git a/html/pic/map/CNMF.png b/html/pic/map/CNMF.png new file mode 100644 index 0000000..e0908ab Binary files /dev/null and b/html/pic/map/CNMF.png differ diff --git a/html/pic/map/CNMN.png b/html/pic/map/CNMN.png new file mode 100644 index 0000000..bd24032 Binary files /dev/null and b/html/pic/map/CNMN.png differ diff --git a/html/pic/map/CNMO.png b/html/pic/map/CNMO.png new file mode 100644 index 0000000..134d9d0 Binary files /dev/null and b/html/pic/map/CNMO.png differ diff --git a/html/pic/map/CNWN.png b/html/pic/map/CNWN.png new file mode 100644 index 0000000..56e13d3 Binary files /dev/null and b/html/pic/map/CNWN.png differ diff --git a/html/pic/map/CNWU.png b/html/pic/map/CNWU.png new file mode 100644 index 0000000..604c218 Binary files /dev/null and b/html/pic/map/CNWU.png differ diff --git a/html/pic/map/COCB.png b/html/pic/map/COCB.png new file mode 100644 index 0000000..acfa6de Binary files /dev/null and b/html/pic/map/COCB.png differ diff --git a/html/pic/map/COCE.png b/html/pic/map/COCE.png new file mode 100644 index 0000000..63f38c2 Binary files /dev/null and b/html/pic/map/COCE.png differ diff --git a/html/pic/map/COCF.png b/html/pic/map/COCF.png new file mode 100644 index 0000000..d6c8a4a Binary files /dev/null and b/html/pic/map/COCF.png differ diff --git a/html/pic/map/COCN.png b/html/pic/map/COCN.png new file mode 100644 index 0000000..fbbe70a Binary files /dev/null and b/html/pic/map/COCN.png differ diff --git a/html/pic/map/COCO.png b/html/pic/map/COCO.png new file mode 100644 index 0000000..87190f7 Binary files /dev/null and b/html/pic/map/COCO.png differ diff --git a/html/pic/map/COCU.png b/html/pic/map/COCU.png new file mode 100644 index 0000000..3590e0f Binary files /dev/null and b/html/pic/map/COCU.png differ diff --git a/html/pic/map/COIE.png b/html/pic/map/COIE.png new file mode 100644 index 0000000..af13eed Binary files /dev/null and b/html/pic/map/COIE.png differ diff --git a/html/pic/map/COIF.png b/html/pic/map/COIF.png new file mode 100644 index 0000000..038a1fc Binary files /dev/null and b/html/pic/map/COIF.png differ diff --git a/html/pic/map/COIN.png b/html/pic/map/COIN.png new file mode 100644 index 0000000..3931a73 Binary files /dev/null and b/html/pic/map/COIN.png differ diff --git a/html/pic/map/COIO.png b/html/pic/map/COIO.png new file mode 100644 index 0000000..56eb599 Binary files /dev/null and b/html/pic/map/COIO.png differ diff --git a/html/pic/map/COLE.png b/html/pic/map/COLE.png new file mode 100644 index 0000000..05fac69 Binary files /dev/null and b/html/pic/map/COLE.png differ diff --git a/html/pic/map/COLF.png b/html/pic/map/COLF.png new file mode 100644 index 0000000..335b4c6 Binary files /dev/null and b/html/pic/map/COLF.png differ diff --git a/html/pic/map/COLN.png b/html/pic/map/COLN.png new file mode 100644 index 0000000..05cd58a Binary files /dev/null and b/html/pic/map/COLN.png differ diff --git a/html/pic/map/COLO.png b/html/pic/map/COLO.png new file mode 100644 index 0000000..b930bb7 Binary files /dev/null and b/html/pic/map/COLO.png differ diff --git a/html/pic/map/COLU.png b/html/pic/map/COLU.png new file mode 100644 index 0000000..680264c Binary files /dev/null and b/html/pic/map/COLU.png differ diff --git a/html/pic/map/COME.png b/html/pic/map/COME.png new file mode 100644 index 0000000..b28b174 Binary files /dev/null and b/html/pic/map/COME.png differ diff --git a/html/pic/map/COMF.png b/html/pic/map/COMF.png new file mode 100644 index 0000000..3d7db61 Binary files /dev/null and b/html/pic/map/COMF.png differ diff --git a/html/pic/map/COMN.png b/html/pic/map/COMN.png new file mode 100644 index 0000000..4b48a4c Binary files /dev/null and b/html/pic/map/COMN.png differ diff --git a/html/pic/map/COMO.png b/html/pic/map/COMO.png new file mode 100644 index 0000000..db692a6 Binary files /dev/null and b/html/pic/map/COMO.png differ diff --git a/html/pic/map/COWN.png b/html/pic/map/COWN.png new file mode 100644 index 0000000..256fabd Binary files /dev/null and b/html/pic/map/COWN.png differ diff --git a/html/pic/map/COWU.png b/html/pic/map/COWU.png new file mode 100644 index 0000000..9ae99f2 Binary files /dev/null and b/html/pic/map/COWU.png differ diff --git a/html/pic/map/CPLA.png b/html/pic/map/CPLA.png new file mode 100644 index 0000000..5f1383c Binary files /dev/null and b/html/pic/map/CPLA.png differ diff --git a/html/pic/map/CPLA2.png b/html/pic/map/CPLA2.png new file mode 100644 index 0000000..9fc9724 Binary files /dev/null and b/html/pic/map/CPLA2.png differ diff --git a/html/pic/map/CPLU.png b/html/pic/map/CPLU.png new file mode 100644 index 0000000..676d25b Binary files /dev/null and b/html/pic/map/CPLU.png differ diff --git a/html/pic/map/CPLU2.png b/html/pic/map/CPLU2.png new file mode 100644 index 0000000..ee5189c Binary files /dev/null and b/html/pic/map/CPLU2.png differ diff --git a/html/pic/map/CUCB.png b/html/pic/map/CUCB.png new file mode 100644 index 0000000..bf2a45a Binary files /dev/null and b/html/pic/map/CUCB.png differ diff --git a/html/pic/map/CUCE.png b/html/pic/map/CUCE.png new file mode 100644 index 0000000..1221c5f Binary files /dev/null and b/html/pic/map/CUCE.png differ diff --git a/html/pic/map/CUCF.png b/html/pic/map/CUCF.png new file mode 100644 index 0000000..3d9f974 Binary files /dev/null and b/html/pic/map/CUCF.png differ diff --git a/html/pic/map/CUCN.png b/html/pic/map/CUCN.png new file mode 100644 index 0000000..b3ed30d Binary files /dev/null and b/html/pic/map/CUCN.png differ diff --git a/html/pic/map/CUCO.png b/html/pic/map/CUCO.png new file mode 100644 index 0000000..f661f3c Binary files /dev/null and b/html/pic/map/CUCO.png differ diff --git a/html/pic/map/CUCU.png b/html/pic/map/CUCU.png new file mode 100644 index 0000000..57c5ad9 Binary files /dev/null and b/html/pic/map/CUCU.png differ diff --git a/html/pic/map/CUIE.png b/html/pic/map/CUIE.png new file mode 100644 index 0000000..fe99f6f Binary files /dev/null and b/html/pic/map/CUIE.png differ diff --git a/html/pic/map/CUIF.png b/html/pic/map/CUIF.png new file mode 100644 index 0000000..23dceba Binary files /dev/null and b/html/pic/map/CUIF.png differ diff --git a/html/pic/map/CUIN.png b/html/pic/map/CUIN.png new file mode 100644 index 0000000..e0c7899 Binary files /dev/null and b/html/pic/map/CUIN.png differ diff --git a/html/pic/map/CUIO.png b/html/pic/map/CUIO.png new file mode 100644 index 0000000..5068f52 Binary files /dev/null and b/html/pic/map/CUIO.png differ diff --git a/html/pic/map/CULE.png b/html/pic/map/CULE.png new file mode 100644 index 0000000..1ee21dc Binary files /dev/null and b/html/pic/map/CULE.png differ diff --git a/html/pic/map/CULF.png b/html/pic/map/CULF.png new file mode 100644 index 0000000..107f0e5 Binary files /dev/null and b/html/pic/map/CULF.png differ diff --git a/html/pic/map/CULN.png b/html/pic/map/CULN.png new file mode 100644 index 0000000..a5fad23 Binary files /dev/null and b/html/pic/map/CULN.png differ diff --git a/html/pic/map/CULO.png b/html/pic/map/CULO.png new file mode 100644 index 0000000..788a0dc Binary files /dev/null and b/html/pic/map/CULO.png differ diff --git a/html/pic/map/CULU.png b/html/pic/map/CULU.png new file mode 100644 index 0000000..9b50407 Binary files /dev/null and b/html/pic/map/CULU.png differ diff --git a/html/pic/map/CUME.png b/html/pic/map/CUME.png new file mode 100644 index 0000000..03e5f86 Binary files /dev/null and b/html/pic/map/CUME.png differ diff --git a/html/pic/map/CUMF.png b/html/pic/map/CUMF.png new file mode 100644 index 0000000..cc8dac2 Binary files /dev/null and b/html/pic/map/CUMF.png differ diff --git a/html/pic/map/CUMN.png b/html/pic/map/CUMN.png new file mode 100644 index 0000000..c9fd964 Binary files /dev/null and b/html/pic/map/CUMN.png differ diff --git a/html/pic/map/CUMO.png b/html/pic/map/CUMO.png new file mode 100644 index 0000000..b23fa11 Binary files /dev/null and b/html/pic/map/CUMO.png differ diff --git a/html/pic/map/CUWN.png b/html/pic/map/CUWN.png new file mode 100644 index 0000000..1f5abe0 Binary files /dev/null and b/html/pic/map/CUWN.png differ diff --git a/html/pic/map/CUWU.png b/html/pic/map/CUWU.png new file mode 100644 index 0000000..56ee1cd Binary files /dev/null and b/html/pic/map/CUWU.png differ diff --git a/html/pic/map/Center.psd b/html/pic/map/Center.psd new file mode 100644 index 0000000..83e9e79 Binary files /dev/null and b/html/pic/map/Center.psd differ diff --git a/html/pic/map/HB.png b/html/pic/map/HB.png new file mode 100644 index 0000000..bab718c Binary files /dev/null and b/html/pic/map/HB.png differ diff --git a/html/pic/map/I0.gif b/html/pic/map/I0.gif new file mode 100644 index 0000000..17853e4 Binary files /dev/null and b/html/pic/map/I0.gif differ diff --git a/html/pic/map/I0.png b/html/pic/map/I0.png new file mode 100644 index 0000000..1029b78 Binary files /dev/null and b/html/pic/map/I0.png differ diff --git a/html/pic/map/I1.gif b/html/pic/map/I1.gif new file mode 100644 index 0000000..fd607d0 Binary files /dev/null and b/html/pic/map/I1.gif differ diff --git a/html/pic/map/I1.png b/html/pic/map/I1.png new file mode 100644 index 0000000..daa4092 Binary files /dev/null and b/html/pic/map/I1.png differ diff --git a/html/pic/map/I2.gif b/html/pic/map/I2.gif new file mode 100644 index 0000000..2a39408 Binary files /dev/null and b/html/pic/map/I2.gif differ diff --git a/html/pic/map/I2.png b/html/pic/map/I2.png new file mode 100644 index 0000000..0775db0 Binary files /dev/null and b/html/pic/map/I2.png differ diff --git a/html/pic/map/I3.gif b/html/pic/map/I3.gif new file mode 100644 index 0000000..0cb63f0 Binary files /dev/null and b/html/pic/map/I3.gif differ diff --git a/html/pic/map/I3.png b/html/pic/map/I3.png new file mode 100644 index 0000000..29cd74b Binary files /dev/null and b/html/pic/map/I3.png differ diff --git a/html/pic/map/I4.gif b/html/pic/map/I4.gif new file mode 100644 index 0000000..a47427d Binary files /dev/null and b/html/pic/map/I4.gif differ diff --git a/html/pic/map/I4.png b/html/pic/map/I4.png new file mode 100644 index 0000000..0dbde81 Binary files /dev/null and b/html/pic/map/I4.png differ diff --git a/html/pic/map/I5.gif b/html/pic/map/I5.gif new file mode 100644 index 0000000..4028004 Binary files /dev/null and b/html/pic/map/I5.gif differ diff --git a/html/pic/map/I5.png b/html/pic/map/I5.png new file mode 100644 index 0000000..596ec36 Binary files /dev/null and b/html/pic/map/I5.png differ diff --git a/html/pic/map/I6.gif b/html/pic/map/I6.gif new file mode 100644 index 0000000..7d049d3 Binary files /dev/null and b/html/pic/map/I6.gif differ diff --git a/html/pic/map/I6.png b/html/pic/map/I6.png new file mode 100644 index 0000000..a7bbaf1 Binary files /dev/null and b/html/pic/map/I6.png differ diff --git a/html/pic/map/I7.gif b/html/pic/map/I7.gif new file mode 100644 index 0000000..33412e9 Binary files /dev/null and b/html/pic/map/I7.gif differ diff --git a/html/pic/map/I7.png b/html/pic/map/I7.png new file mode 100644 index 0000000..cc1f28c Binary files /dev/null and b/html/pic/map/I7.png differ diff --git a/html/pic/map/I8.gif b/html/pic/map/I8.gif new file mode 100644 index 0000000..4009599 Binary files /dev/null and b/html/pic/map/I8.gif differ diff --git a/html/pic/map/I8.png b/html/pic/map/I8.png new file mode 100644 index 0000000..c8519ef Binary files /dev/null and b/html/pic/map/I8.png differ diff --git a/html/pic/map/I9.gif b/html/pic/map/I9.gif new file mode 100644 index 0000000..4448744 Binary files /dev/null and b/html/pic/map/I9.gif differ diff --git a/html/pic/map/I9.png b/html/pic/map/I9.png new file mode 100644 index 0000000..a11a137 Binary files /dev/null and b/html/pic/map/I9.png differ diff --git a/html/pic/map/IA.gif b/html/pic/map/IA.gif new file mode 100644 index 0000000..e2e3bc9 Binary files /dev/null and b/html/pic/map/IA.gif differ diff --git a/html/pic/map/IA.png b/html/pic/map/IA.png new file mode 100644 index 0000000..1ebd815 Binary files /dev/null and b/html/pic/map/IA.png differ diff --git a/html/pic/map/IE.gif b/html/pic/map/IE.gif new file mode 100644 index 0000000..409f32d Binary files /dev/null and b/html/pic/map/IE.gif differ diff --git a/html/pic/map/IE.png b/html/pic/map/IE.png new file mode 100644 index 0000000..8aaf6ab Binary files /dev/null and b/html/pic/map/IE.png differ diff --git a/html/pic/map/IF.png b/html/pic/map/IF.png new file mode 100644 index 0000000..45b6594 Binary files /dev/null and b/html/pic/map/IF.png differ diff --git a/html/pic/map/IF2.png b/html/pic/map/IF2.png new file mode 100644 index 0000000..b1666a4 Binary files /dev/null and b/html/pic/map/IF2.png differ diff --git a/html/pic/map/IG.gif b/html/pic/map/IG.gif new file mode 100644 index 0000000..ffa57ac Binary files /dev/null and b/html/pic/map/IG.gif differ diff --git a/html/pic/map/IG.png b/html/pic/map/IG.png new file mode 100644 index 0000000..3024b86 Binary files /dev/null and b/html/pic/map/IG.png differ diff --git a/html/pic/map/II.png b/html/pic/map/II.png new file mode 100644 index 0000000..02c286e Binary files /dev/null and b/html/pic/map/II.png differ diff --git a/html/pic/map/IP.png b/html/pic/map/IP.png new file mode 100644 index 0000000..5657239 Binary files /dev/null and b/html/pic/map/IP.png differ diff --git a/html/pic/map/IU.gif b/html/pic/map/IU.gif new file mode 100644 index 0000000..92e757f Binary files /dev/null and b/html/pic/map/IU.gif differ diff --git a/html/pic/map/IU.png b/html/pic/map/IU.png new file mode 100644 index 0000000..4a70973 Binary files /dev/null and b/html/pic/map/IU.png differ diff --git a/html/pic/map/IW.png b/html/pic/map/IW.png new file mode 100644 index 0000000..d19a4a5 Binary files /dev/null and b/html/pic/map/IW.png differ diff --git a/html/pic/map/README b/html/pic/map/README new file mode 100644 index 0000000..e0cff7d --- /dev/null +++ b/html/pic/map/README @@ -0,0 +1,79 @@ +Die Dateinamen sind so Computer-lesbar wie moeglich: + +Alle die mit B anfangen sind "Backslashes", die mit S +"Slashes", die mit C "Center" und die mit I "Icons". +bei den / und \ Bildern stehen die folgenden beiden +Buchstaben fuer + +B Schwarz +P Pol +W Wasser +U Unbesetzt +N Neutral +O Eigene +F Freunde +E Feinde + +(der erste Buchstabe gibt die "obere" der zweite die "untere" Farbe an). + +Bei den Center-Bildern steht der zweite Buchstabe fuer den +Erdling der drin ist (wie oben), der dritte Buchstabe ist +L Land, Manapol oder Berg ohne Tempel +C Stadt bzw. Heimatstadt +W Wasser bzw. Insel ohne Tempel +I Insel mit Tempel +M Berg mit Tempel + +der Letzte Buchstabe ist der Owner (B steht bei Heimatstaedten fuer +NICHT-HEIMATSTADT also Stadt und U steht bei Bergen fuer NICHT-HEILIG +also Plain). Der auserwaehlte Pol hat ein A als letzten Buchstaben. + +Bei den Icons steht das zweite Zeichen fuer + +0 es sind eigene und feindliche Avatare anwesend + (und vielleicht noch befreundete und/oder neutrale) +1 es sind eigene und neutrale Avatare anwesend + (und vielleicht noch befreundete) +2 es sind eigene und befreundete Avatare anwesend +3 es sind nur eigene Avatare anwesend +4 es sind befreundete und feindliche Avatare anwesend + (und vielleicht noch neutrale) +5 es sind befreundete und neutrale Avatare anwesend +6 es sind nur befreundete Avatare anwesend +7 es sind feindliche und neutrale Avatare anwesend +8 es sind nur feindliche Avatare anwesend +9 es sind nur neutrale Avatare anwesend +A es sind Archen im Feld +E es findet gerade ein Erdlingskampf statt +G es findet gerade ein Avatar-Kampf statt +U leeres Icon (wir in allen vier Ecken als Fuellsel benoetigt) + +So, jetzt das komplette Set - ein paar Namen haben sich noch +geaendert, weil mir ein Fehler unterlaufen war. Wirf das alte +Verzeichnis also besser vorher weg. + +Fuer die Karte ohne Spieler werden nur 31 von den 214 Bildchen +gebraucht, naemlich: + +CPLU Manapol +CPLA Aymargeddon +CUWU Wasser +CUWN Insel +CULU Ebene +CULN Berg +CUCU Heimatstadt +CUCB Stadt + +BBP, BPB, SBP, SPB Manapol am Rand +BWP, BPW, SWP, SPW zwischen Manapol und Wasser +BBW, BWB, SBW, SWB Wasser am Rand +BWW, SWW zwischen Wasserfeldern +BWU, BUW, SWU, SWW zwischen Land und Wasser +BBU, BUB, SBU, SUB Land am Rand +BUU, SUU zwischen Landfeldern + +Drei von den Bildchen sollten bei konsistenten Daten eigentlich +nie benoetigt werden, naemlich COLO, COMO und COIO (die selbe +ID kann nie an einen Gott und einen Erdling gleichzeitig vergeben +sein). Zu Testzwecken sind sie dennoch vorhanden. + diff --git a/html/pic/map/Rand2.psd b/html/pic/map/Rand2.psd new file mode 100644 index 0000000..d8280d3 Binary files /dev/null and b/html/pic/map/Rand2.psd differ diff --git a/html/pic/map/SBB.png b/html/pic/map/SBB.png new file mode 100644 index 0000000..5bfcd29 Binary files /dev/null and b/html/pic/map/SBB.png differ diff --git a/html/pic/map/SBE.png b/html/pic/map/SBE.png new file mode 100644 index 0000000..3177f0c Binary files /dev/null and b/html/pic/map/SBE.png differ diff --git a/html/pic/map/SBF.png b/html/pic/map/SBF.png new file mode 100644 index 0000000..76d197a Binary files /dev/null and b/html/pic/map/SBF.png differ diff --git a/html/pic/map/SBN.png b/html/pic/map/SBN.png new file mode 100644 index 0000000..5123729 Binary files /dev/null and b/html/pic/map/SBN.png differ diff --git a/html/pic/map/SBO.png b/html/pic/map/SBO.png new file mode 100644 index 0000000..75cb096 Binary files /dev/null and b/html/pic/map/SBO.png differ diff --git a/html/pic/map/SBP.png b/html/pic/map/SBP.png new file mode 100644 index 0000000..65a93bd Binary files /dev/null and b/html/pic/map/SBP.png differ diff --git a/html/pic/map/SBP2.png b/html/pic/map/SBP2.png new file mode 100644 index 0000000..8243c00 Binary files /dev/null and b/html/pic/map/SBP2.png differ diff --git a/html/pic/map/SBU.png b/html/pic/map/SBU.png new file mode 100644 index 0000000..b295c55 Binary files /dev/null and b/html/pic/map/SBU.png differ diff --git a/html/pic/map/SBW.png b/html/pic/map/SBW.png new file mode 100644 index 0000000..65a93bd Binary files /dev/null and b/html/pic/map/SBW.png differ diff --git a/html/pic/map/SEB.png b/html/pic/map/SEB.png new file mode 100644 index 0000000..b85093a Binary files /dev/null and b/html/pic/map/SEB.png differ diff --git a/html/pic/map/SEE.png b/html/pic/map/SEE.png new file mode 100644 index 0000000..16b35a5 Binary files /dev/null and b/html/pic/map/SEE.png differ diff --git a/html/pic/map/SEF.png b/html/pic/map/SEF.png new file mode 100644 index 0000000..95e73dc Binary files /dev/null and b/html/pic/map/SEF.png differ diff --git a/html/pic/map/SEN.png b/html/pic/map/SEN.png new file mode 100644 index 0000000..7e860c7 Binary files /dev/null and b/html/pic/map/SEN.png differ diff --git a/html/pic/map/SEO.png b/html/pic/map/SEO.png new file mode 100644 index 0000000..63e932c Binary files /dev/null and b/html/pic/map/SEO.png differ diff --git a/html/pic/map/SEU.png b/html/pic/map/SEU.png new file mode 100644 index 0000000..f14a201 Binary files /dev/null and b/html/pic/map/SEU.png differ diff --git a/html/pic/map/SEW.png b/html/pic/map/SEW.png new file mode 100644 index 0000000..e08b411 Binary files /dev/null and b/html/pic/map/SEW.png differ diff --git a/html/pic/map/SFB.png b/html/pic/map/SFB.png new file mode 100644 index 0000000..073616d Binary files /dev/null and b/html/pic/map/SFB.png differ diff --git a/html/pic/map/SFE.png b/html/pic/map/SFE.png new file mode 100644 index 0000000..41b699b Binary files /dev/null and b/html/pic/map/SFE.png differ diff --git a/html/pic/map/SFF.png b/html/pic/map/SFF.png new file mode 100644 index 0000000..ea71c5c Binary files /dev/null and b/html/pic/map/SFF.png differ diff --git a/html/pic/map/SFN.png b/html/pic/map/SFN.png new file mode 100644 index 0000000..5d1f659 Binary files /dev/null and b/html/pic/map/SFN.png differ diff --git a/html/pic/map/SFO.png b/html/pic/map/SFO.png new file mode 100644 index 0000000..495ce2b Binary files /dev/null and b/html/pic/map/SFO.png differ diff --git a/html/pic/map/SFU.png b/html/pic/map/SFU.png new file mode 100644 index 0000000..2dd92d7 Binary files /dev/null and b/html/pic/map/SFU.png differ diff --git a/html/pic/map/SFW.png b/html/pic/map/SFW.png new file mode 100644 index 0000000..a785ba7 Binary files /dev/null and b/html/pic/map/SFW.png differ diff --git a/html/pic/map/SNB.png b/html/pic/map/SNB.png new file mode 100644 index 0000000..0029f78 Binary files /dev/null and b/html/pic/map/SNB.png differ diff --git a/html/pic/map/SNE.png b/html/pic/map/SNE.png new file mode 100644 index 0000000..7db700f Binary files /dev/null and b/html/pic/map/SNE.png differ diff --git a/html/pic/map/SNF.png b/html/pic/map/SNF.png new file mode 100644 index 0000000..4ae88c4 Binary files /dev/null and b/html/pic/map/SNF.png differ diff --git a/html/pic/map/SNN.png b/html/pic/map/SNN.png new file mode 100644 index 0000000..d91b582 Binary files /dev/null and b/html/pic/map/SNN.png differ diff --git a/html/pic/map/SNO.png b/html/pic/map/SNO.png new file mode 100644 index 0000000..2bc9629 Binary files /dev/null and b/html/pic/map/SNO.png differ diff --git a/html/pic/map/SNU.png b/html/pic/map/SNU.png new file mode 100644 index 0000000..5d74110 Binary files /dev/null and b/html/pic/map/SNU.png differ diff --git a/html/pic/map/SNW.png b/html/pic/map/SNW.png new file mode 100644 index 0000000..60e0e1d Binary files /dev/null and b/html/pic/map/SNW.png differ diff --git a/html/pic/map/SOB.png b/html/pic/map/SOB.png new file mode 100644 index 0000000..b787443 Binary files /dev/null and b/html/pic/map/SOB.png differ diff --git a/html/pic/map/SOE.png b/html/pic/map/SOE.png new file mode 100644 index 0000000..d0e4f08 Binary files /dev/null and b/html/pic/map/SOE.png differ diff --git a/html/pic/map/SOF.png b/html/pic/map/SOF.png new file mode 100644 index 0000000..15b1e98 Binary files /dev/null and b/html/pic/map/SOF.png differ diff --git a/html/pic/map/SON.png b/html/pic/map/SON.png new file mode 100644 index 0000000..6d0c02b Binary files /dev/null and b/html/pic/map/SON.png differ diff --git a/html/pic/map/SOO.png b/html/pic/map/SOO.png new file mode 100644 index 0000000..3cc6f0e Binary files /dev/null and b/html/pic/map/SOO.png differ diff --git a/html/pic/map/SOU.png b/html/pic/map/SOU.png new file mode 100644 index 0000000..535d713 Binary files /dev/null and b/html/pic/map/SOU.png differ diff --git a/html/pic/map/SOW.png b/html/pic/map/SOW.png new file mode 100644 index 0000000..7626387 Binary files /dev/null and b/html/pic/map/SOW.png differ diff --git a/html/pic/map/SPB.png b/html/pic/map/SPB.png new file mode 100644 index 0000000..c181623 Binary files /dev/null and b/html/pic/map/SPB.png differ diff --git a/html/pic/map/SPB2.png b/html/pic/map/SPB2.png new file mode 100644 index 0000000..507380e Binary files /dev/null and b/html/pic/map/SPB2.png differ diff --git a/html/pic/map/SPW.png b/html/pic/map/SPW.png new file mode 100644 index 0000000..d06f8e5 Binary files /dev/null and b/html/pic/map/SPW.png differ diff --git a/html/pic/map/SPW2.png b/html/pic/map/SPW2.png new file mode 100644 index 0000000..8be1e55 Binary files /dev/null and b/html/pic/map/SPW2.png differ diff --git a/html/pic/map/ST.gif b/html/pic/map/ST.gif new file mode 100644 index 0000000..61d6437 Binary files /dev/null and b/html/pic/map/ST.gif differ diff --git a/html/pic/map/SUB.png b/html/pic/map/SUB.png new file mode 100644 index 0000000..0ec9249 Binary files /dev/null and b/html/pic/map/SUB.png differ diff --git a/html/pic/map/SUE.png b/html/pic/map/SUE.png new file mode 100644 index 0000000..aaf8168 Binary files /dev/null and b/html/pic/map/SUE.png differ diff --git a/html/pic/map/SUF.png b/html/pic/map/SUF.png new file mode 100644 index 0000000..edafa12 Binary files /dev/null and b/html/pic/map/SUF.png differ diff --git a/html/pic/map/SUN.png b/html/pic/map/SUN.png new file mode 100644 index 0000000..0234cf9 Binary files /dev/null and b/html/pic/map/SUN.png differ diff --git a/html/pic/map/SUO.png b/html/pic/map/SUO.png new file mode 100644 index 0000000..bf06d1c Binary files /dev/null and b/html/pic/map/SUO.png differ diff --git a/html/pic/map/SUU.png b/html/pic/map/SUU.png new file mode 100644 index 0000000..ed68329 Binary files /dev/null and b/html/pic/map/SUU.png differ diff --git a/html/pic/map/SUW.png b/html/pic/map/SUW.png new file mode 100644 index 0000000..2f128a8 Binary files /dev/null and b/html/pic/map/SUW.png differ diff --git a/html/pic/map/SWB.png b/html/pic/map/SWB.png new file mode 100644 index 0000000..c181623 Binary files /dev/null and b/html/pic/map/SWB.png differ diff --git a/html/pic/map/SWE.png b/html/pic/map/SWE.png new file mode 100644 index 0000000..c55dac8 Binary files /dev/null and b/html/pic/map/SWE.png differ diff --git a/html/pic/map/SWF.png b/html/pic/map/SWF.png new file mode 100644 index 0000000..8f4d1c0 Binary files /dev/null and b/html/pic/map/SWF.png differ diff --git a/html/pic/map/SWN.png b/html/pic/map/SWN.png new file mode 100644 index 0000000..6bd1313 Binary files /dev/null and b/html/pic/map/SWN.png differ diff --git a/html/pic/map/SWO.png b/html/pic/map/SWO.png new file mode 100644 index 0000000..4bb8506 Binary files /dev/null and b/html/pic/map/SWO.png differ diff --git a/html/pic/map/SWP.png b/html/pic/map/SWP.png new file mode 100644 index 0000000..d06f8e5 Binary files /dev/null and b/html/pic/map/SWP.png differ diff --git a/html/pic/map/SWP2.png b/html/pic/map/SWP2.png new file mode 100644 index 0000000..4b7f93b Binary files /dev/null and b/html/pic/map/SWP2.png differ diff --git a/html/pic/map/SWU.png b/html/pic/map/SWU.png new file mode 100644 index 0000000..185c9b8 Binary files /dev/null and b/html/pic/map/SWU.png differ diff --git a/html/pic/map/SWW.png b/html/pic/map/SWW.png new file mode 100644 index 0000000..d06f8e5 Binary files /dev/null and b/html/pic/map/SWW.png differ diff --git a/html/pic/map/Testmap.png b/html/pic/map/Testmap.png new file mode 100644 index 0000000..d84b6c4 Binary files /dev/null and b/html/pic/map/Testmap.png differ diff --git a/html/player.epl b/html/player.epl new file mode 100644 index 0000000..ccb534e --- /dev/null +++ b/html/player.epl @@ -0,0 +1,182 @@ +[- use FROGS::Config qw($conf); -] +<html> +<head><link rel="stylesheet" type="text/css" href="aymargeddon.css"> +<title>Aymargeddon</title></head> +[- + $| = 1; + $udat{-current} = 'player.epl'; + + use Aymargeddon; + use Data::Dumper; + $db = DataBase->new(); + $id = 0; + if($udat{-id}){ + $id = $udat{-id}; + }else{ + $id = $db->authenticate($fdat{'login'},$fdat{'passwd'}, + $fdat{'passwd2'},$fdat{'passwd3'}); + } + if($udat{-lang}){ + $db->set_language($udat{-lang}); + #set language in Database in PLAYER.LANGUAGE + $db->update_hash('PLAYER',"PLAYER=$id",{'LANGUAGE' => $udat{-lang}}); + $db->commit(); + }else{ + # set language according to PLAYER.LANGUAGE + # read_player() returns the first DB line in ARRAY format + ($udat{-lang}) = $db->read_player($id,'LANGUAGE'); + } + + $escmode = 0; + + # TODO: klappt nich :-( + # $out = '<body style="font-size:10pt" bgcolor="'.$conf->{-COLOR}->{-EMPTY}.'">'; + $out = '<body style="line-height:12pt;font-size:10pt">'; +-] +[+$out+] + +[$ if $id $] [# logged in - show game list, messages, etc. pp. #] + + [- + $udat{-id} = $id; + + # switch game-id + $udat{-game} = $fdat{'game'} if exists $fdat{'game'}; + $aym = Aymargeddon->new($udat{-game},$id,$db) if exists $udat{-game}; + + if(exists $fdat{'game'}){ + $udat{-loc} = $aym->startfield(); + $udat{-loc} =~ /^(\d+)\_(\d+)$/; + my ($x,$y) = ($1, $2); + my $size = $aym->get_size(); + $udat{-xoff} = $x -$size; + $udat{-yoff} = $y; + } + + + + # register for selected role in game + if($fdat{'role'} and $fdat{'charname'}){ + my $return = $aym->new_role($fdat{'role'}, + $fdat{'charname'}, + $fdat{'gender'}); + # $fdat{'description'}); + unless($return){ + print OUT "<strong>Error: cant register role.</strong><p>"; + } + } + + # delete all messages if wanted. + # TODO: write timestamp in link and delete only to this time + if($fdat{delete_all_messages} == 1){ + $aym->delete_all_messages($fdat{time}); + $db->commit(); + } + + Execute("menu.epl"); + + $own_games = $db->games_of_player($id); + $open_games = $db->open_games("HOME=-1"); + + %such = (); + for my $og (@$own_games){ + $such{$og->[0]} = 1; + } + + @real_open_games = (); + for $og (@$open_games){ + push @real_open_games, $og unless exists $such{$og->[0]}; + } + + ($rn) = $db->read_player($id, 'REALNAME') unless exists $udat{-game}; + -] + + [$ if not exists $udat{-game} $] + <hr> + [+ $db->loc('PLAYER_WELCOME').' Aymargeddon '.$rn +]!<p> + [$ endif $] + + <hr> + <table width=100% border=0><colgroup><col width="200"><col></colgroup> + <tr><td valign="top" bgcolor="#b8a266"> + <p>[+ $db->loc('PLAYER_OWN_GAMES') +]<p> + [$ foreach $og (@$own_games) $] + [- $og = $og->[0]; ($og_name) = $db->read_game($og,'NAME'); -] + <a href="player.epl?game=[+$og+]">[+$og_name+]</a><p> + [$ endforeach $] + [$ if $#{@$own_games} < 0 $] + [+ $db->loc('PLAYER_GAMES_NONE') +]<p> + [$ endif $] + <hr> + <p>[+ $db->loc('PLAYER_OPENGAMES') +]:<p> + [$ foreach $og (@real_open_games) $] + [- $og=$og->[0]; ($og_name) = $db->read_game($og,'NAME'); -] + <a href="player.epl?game=[+$og+]">[+$og_name+]</a><p> + [$ endforeach $] + [$ if $#{@real_open_games} < 0 $] + [+ $db->loc('PLAYER_GAMES_NONE') +]<p> + [$ endif $] + <hr></td> + <td valign="top" bgcolor="#fcffd9"> + [$ if not exists $udat{-game} $] + + [+ $db->loc('PLAYER_CHOOSE_GAME') +] + + [$ elsif exists $fdat{'cmd'} $] + [- Execute('command_frames.epl') -] + [$ elsif $such{$udat{-game}} $] + <center> + + [# [- + ($gn) = $db->read_game($udat{-game},'NAME'); + my @list = $aym->charname($udat{-id}); + $cn = $list[0]; + -] + [+ $db->loc('PLAYER_WELCOME') +] <strong>[+ $gn +]</strong>, [+ $cn +].<p> + <hr> #] + + + [- + $messages = $aym->read_messages(); + $now = $db->now(); + -] + <strong>[+ $db->loc('PLAYER_MESSAGES_HEADING') +]</strong><p> + <a href="player.epl?delete_all_messages=1&time=[+$now+]"> + [+ $db->loc('PLAYER_DELETE_MESSAGES')+]</a><p> + [$ foreach $msg (@$messages) $] + [+ $aym->show_message($msg->[0]) +]<br> + [$ endforeach $] + [$ if $#{@$messages} < 0 $] + [+ $db->loc('PLAYER_NO_MESSAGE') +] + [$ endif $] + <p> +[# we dont show events in a global list any more + <strong>[+ $db->loc('PLAYER_EVENTS') +]</strong><p> + [- + $events = $aym->role_events(); + -] + [$ foreach $e (@$events) $] + [+ $aym->show_event($e->{'ID'}) +]<p> + [$ endforeach $] + [$ if $#{@$events} < 0 $] + [+ $db->loc('PLAYER_NO_EVENTS') +]<p> + [$ endif $] +#] + <strong>[+ $db->loc('PLAYER_STATISTIC') +]</strong><p> + [+ $aym->show_statistic() +] + <p><a href="mapframe.epl">[+ $db->loc('PLAYER_TO_MAP') +]</a> + </center> + [$ else $] + [- Execute('role_select.epl'); -] + [$ endif $] + </td></tr></table> +[$ else $] [# wrong login #] + + [- Execute("menu.epl"); -] + <p><p>[+ $db->loc('LOGIN_FAILED') +]<p> + [- print OUT $db->loc('ERROR_NO_LOGIN'); -] + +[$ endif $] +</body></html> + + diff --git a/html/reference.epl b/html/reference.epl new file mode 100644 index 0000000..f1cb02c --- /dev/null +++ b/html/reference.epl @@ -0,0 +1,26 @@ +<html> +<head> + <title>Aymargeddon</title> +</head> + +[- + + use FROGS::Config; + $udat{-current} = 'reference.epl'; + Execute("menu.epl"); +-] +<hr> +[- + $udat{-lang} = $::conf->{-DEFAULT_LANGUAGE} unless exists $udat{-lang}; + + if($udat{-lang} eq 'EN'){ + Execute("table_english.html"); + }elsif($udat{-lang} eq 'DE'){ + Execute("table_german.html"); + } +-] + + +</body> +</html> + diff --git a/html/role_select.epl b/html/role_select.epl new file mode 100644 index 0000000..c40e793 --- /dev/null +++ b/html/role_select.epl @@ -0,0 +1,52 @@ +[$ if exists $udat{-id} and exists $udat{-game} $] + +[- + use Aymargeddon; + $db = DataBase->new(); + $aym = Aymargeddon->new($udat{-game},$udat{-id},$db); + $db->set_language($udat{-lang}); + + # open for earthlings? + $open_earthling = $aym->is_open('CITY'); + # open for gods? + $open_god = $aym->is_open('MOUNTAIN'); + + # open for observers? + ($open_observer) = $db->read_player($udat{-id},'SECURITY'); + $open_observer = 0 if $open_observer eq 'USER'; + + ($gn) = $db->read_game($udat{-game},'NAME'); + +-] + +<form method="get" action="player.epl"> + + [+ $db->loc('PLAYER_CREATE_CHAR').' '.$gn +]:<p> + + [+ $db->loc('NOM_CHARNAME') +]: <input type="text" name="charname" size="20" maxlength="20"><p> + + [+ $db->loc('NOM_ROLE') +]: + [$ if $open_earthling $] + <input type="radio" name="role" value="EARTHLING">[+ $db->loc('ROLE_EARTHLING') +] + [$ endif $] + [$ if $open_god $] + <input type="radio" name="role" value="GOD">[+ $db->loc('ROLE_GOD') +] + [$ endif $] + [$ if $open_observer $] + <input type="radio" name="role" value="OBSERVER">[+ $db->loc('ROLE_OBSERVER') +] + [$ endif $] + <p> + + [+ $db->loc('NOM_GENDER') +]: <input type="radio" name="gender" value="MALE">[+ $db->loc('GEN_MALE') +] + <input type="radio" name="gender" value="FEMALE">[+ $db->loc('GEN_FEMALE') +] + <input type="radio" name="gender" value="PLURAL" checked>[+ $db->loc('GEN_PLURAL') +]<p> +[# [+ $db->loc('NOM_DESCRIPTION') +]: <input type="text" name="description"><p> #] + <input type="submit" value="[+ $db->loc('FORM_OK_BUTTON') +]"> + +</form> + +[$ else $] + + [- print OUT $db->loc('ERROR_NO_LOGIN'); -] + +[$ endif $] diff --git a/html/ruleframe.epl b/html/ruleframe.epl new file mode 100644 index 0000000..dacd896 --- /dev/null +++ b/html/ruleframe.epl @@ -0,0 +1,17 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" + "http://www.w3.org/TR/html4/frameset.dtd"> +<html> + <head> + <title>Frameset for the rules</title> + </head> + + [- $udat{-current} = 'ruleframe.epl'; -] + + <frameset rows="34,*"> + <frame src="menu_frames.epl" name="menu" /> + <frame src="/wiki/index.php/Regeln" name="rules" /> + <noframes> + keine frames + </noframes> + </frameset> +</html> diff --git a/html/table_english.html b/html/table_english.html new file mode 100644 index 0000000..1e6bdc3 --- /dev/null +++ b/html/table_english.html @@ -0,0 +1,359 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> +<html> +<head> + <meta http-equiv="CONTENT-TYPE" + content="text/html; charset=windows-1252"> + <title>Fakten_deu</title> + <meta name="GENERATOR" content="OpenOffice.org 1.0.1 (Win32)"> + <meta name="AUTHOR" content="Christine Bauer"> + <meta name="CREATED" content="20050322;22401092"> + <meta name="CHANGEDBY" content="Christine Bauer"> + <meta name="CHANGED" content="20050323;12460082"> +</head> +<body lang="de-DE"> +<table><tr valign="top"><td><p><span style="font-weight: bold;"></span><font + face="Albany, sans-serif"><font style="font-size: 11pt;" size="2"><b> +campaign<br> +</b></font></font></p> +<table style="page-break-before: always;" border="1" cellpadding="2" + cellspacing="0" width="285"> + <col width="98"> <col width="80"> <col width="93"> <tbody> + <tr> + <th bgcolor="#e6e6e6" width="98"> + <p><br> + </p> + </th> + <th bgcolor="#e6e6e6" width="80"> + <p><font style="font-size: 9pt;" size="2">fighting power</font></p> + </th> + <th bgcolor="#e6e6e6" width="93"> + <p><font style="font-size: 9pt;" size="2">time units movement</font></p> + </th> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">warrior</font> + </p> + </th> + <td sdval="1" sdnum="1031;" width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + <td sdval="10" sdnum="1031;" width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">10</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">hero</font></p> + </th> + <td width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">2</font></p> + </td> + <td sdval="6" sdnum="1031;" width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">6</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">priest</font></p> + </th> + <td sdval="0" sdnum="1031;" width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + <td sdval="12" sdnum="1031;" width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">12</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">avatar</font></p> + </th> + <td width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">up to + +4</font></p> + </td> + <td sdval="1" sdnum="1031;" width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">ark</font></p> + </th> + <td sdval="3" sdnum="1031;" width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">3</font></p> + </td> + <td sdval="5" sdnum="1031;" width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">5</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">home city</font></p> + </th> + <td sdval="2" sdnum="1031;" width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">2</font></p> + </td> + <td width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">--</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">flanking</font></p> + </th> + <td sdval="1" sdnum="1031;" width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + <td width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">--</font></p> + </td> + </tr> + </tbody> +</table></td><td rowspan="2"> +<p style="page-break-after: avoid;"><font + face="Albany, sans-serif"><font style="font-size: 11pt;" size="2"><b>divine actions</b></font></font></p> +<table border="1" cellpadding="4" cellspacing="0" width="291"> + <col width="149"> <col width="48"> <col width="68"> <thead> <tr + valign="top"> + <th bgcolor="#e6e6e6" width="149"> + <p align="center"><br> + </p> + </th> + <th bgcolor="#e6e6e6" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">mana</font></p> + </th> + <th bgcolor="#e6e6e6" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">time units</font></p> + </th> + </tr> + </thead> <tbody> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">bless hero</font></p> + </th> + <td sdval="1" sdnum="1031;" valign="bottom" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + <td sdval="0" sdnum="1031;" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + </tr> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">bless priest</font></p> + </th> + <td sdval="5" sdnum="1031;" valign="bottom" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">5</font></p> + </td> + <td sdval="0" sdnum="1031;" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + </tr> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">build ark</font></p> + </th> + <td sdval="5" sdnum="1031;" valign="bottom" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">5</font></p> + </td> + <td sdval="30" sdnum="1031;" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">30</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffffcc" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">summon avatar</font></p> + </th> + <td sdval="5" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">5</font></p> + </td> + <td sdval="0" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffffcc" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">move avatar</font></p> + </th> + <td sdval="1" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + <td sdval="1" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffffcc" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">avatar fight</font></p> + </th> + <td sdval="1" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">2 per fight</font></p> + </td> + <td sdval="10" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">10</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffffcc" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">avatar help in fight of earthlings</font></p> + </th> + <td bgcolor="#ffffcc" valign="top" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">2 per +fight</font></p> + </td> + <td bgcolor="#ffffcc" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">--</font></p> + </td> + </tr> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">flood</font></p> + </th> + <td sdval="2" sdnum="1031;" valign="bottom" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">2</font></p> + </td> + <td valign="top" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">40</font></p> + </td> + </tr> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">destroy temple</font></p> + </th> + <td sdval="5" sdnum="1031;" valign="bottom" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">5</font></p> + </td> + <td sdval="0" sdnum="1031;" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffcc99" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">plague: +influentia </font> </p> + </th> + <td sdval="10" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">10</font></p> + </td> + <td sdval="10" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">20</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffcc99" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">plague: +pestilenzia</font></p> + </th> + <td sdval="10" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">20</font></p> + </td> + <td sdval="20" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">20</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffcc99" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Plague: +ebola</font></p> + </th> + <td sdval="10" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">40</font></p> + </td> + <td sdval="30" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">20</font></p> + </td> + </tr> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Change luck</font></p> + </th> + <td valign="top" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">1 per point</font></p> + </td> + <td sdval="5" sdnum="1031;" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + </tr> + </tbody> +</table></td></tr><tr><td> +<p><font style="font-size: 11pt;" size="2"><b>miscellanous timing</b></font> +</p> +<table border="1" cellpadding="4" cellspacing="0" width="242"> + <col width="148"> <col width="76"> <thead> <tr valign="top"> + <th bgcolor="#e6e6e6" width="148"> + <p><br> + </p> + </th> + <th bgcolor="#e6e6e6" width="76"> + <p><font style="font-size: 9pt;" size="2">time units</font></p> + </th> + </tr> + </thead> <tbody> + <tr> + <th valign="top" width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">build temple</font></p> + </th> + <td valign="bottom" width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">3, 6, +9....</font></p> + </td> + </tr> + <tr> + <th valign="top" width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">earthlings fight</font></p> + </th> + <td sdval="6" sdnum="1031;" valign="bottom" width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">6</font></p> + </td> + </tr> + <tr valign="top"> + <th width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">warrior production</font></p> + </th> + <td width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">40 + 4 * PEACE</font></p> + </td> + </tr> + <tr valign="top"> + <th width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">warrior production homecity</font></p> + </th> + <td width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">20</font></p> + </td> + </tr> + <tr> + <th valign="top" width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">priest production</font></p> + </th> + <td sdval="40" sdnum="1031;" valign="bottom" width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">40</font></p> + </td> + </tr> + <tr> + <th valign="top" width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">mana +produktion</font></p> + </th> + <td sdval="10" sdnum="1031;" valign="bottom" width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">10</font></p> + </td> + </tr> + </tbody> +</table> +</td></tr></table> +</body> +</html> diff --git a/html/table_german.html b/html/table_german.html new file mode 100644 index 0000000..1710470 --- /dev/null +++ b/html/table_german.html @@ -0,0 +1,370 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"> +<html> +<head> + <meta http-equiv="CONTENT-TYPE" + content="text/html; charset=windows-1252"> + <title>Fakten_deu</title> + <meta name="GENERATOR" content="OpenOffice.org 1.0.1 (Win32)"> + <meta name="AUTHOR" content="Christine Bauer"> + <meta name="CREATED" content="20050322;22401092"> + <meta name="CHANGEDBY" content="Christine Bauer"> + <meta name="CHANGED" content="20050323;12460082"> +</head> +<body lang="de-DE"> +<table><tr valign="top"><td><p><span style="font-weight: bold;"></span><font + face="Albany, sans-serif"><font style="font-size: 11pt;" size="2"><b> +Feldzüge<br> +</b></font></font></p> +<table style="page-break-before: always;" border="1" cellpadding="2" + cellspacing="0" width="285"> + <col width="98"> <col width="80"> <col width="93"> <tbody> + <tr> + <th bgcolor="#e6e6e6" width="98"> + <p><br> + </p> + </th> + <th bgcolor="#e6e6e6" width="80"> + <p><font style="font-size: 9pt;" size="2">Kampfstärke</font></p> + </th> + <th bgcolor="#e6e6e6" width="93"> + <p><font style="font-size: 9pt;" size="2">Zeiteinheiten Bewegung</font></p> + </th> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">Krieger </font> + </p> + </th> + <td sdval="1" sdnum="1031;" width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + <td sdval="10" sdnum="1031;" width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">10</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">Held</font></p> + </th> + <td width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">2</font></p> + </td> + <td sdval="6" sdnum="1031;" width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">6</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">Priester</font></p> + </th> + <td sdval="0" sdnum="1031;" width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + <td sdval="12" sdnum="1031;" width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">12</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">Avatar</font></p> + </th> + <td width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">bis zu + +4</font></p> + </td> + <td sdval="1" sdnum="1031;" width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">Arche</font></p> + </th> + <td sdval="3" sdnum="1031;" width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">3</font></p> + </td> + <td sdval="5" sdnum="1031;" width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">5</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">Heimatstadt</font></p> + </th> + <td sdval="2" sdnum="1031;" width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">2</font></p> + </td> + <td width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">--</font></p> + </td> + </tr> + <tr> + <th width="98"> + <p align="left"><font style="font-size: 9pt;" size="2">Flankierung</font></p> + </th> + <td sdval="1" sdnum="1031;" width="80"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + <td width="93"> + <p align="center"><font style="font-size: 9pt;" size="2">--</font></p> + </td> + </tr> + </tbody> +</table></td><td rowspan="2"> +<p style="page-break-after: avoid;"><font + face="Albany, sans-serif"><font style="font-size: 11pt;" size="2"><b>Götteraktionen</b></font></font></p> +<table border="1" cellpadding="4" cellspacing="0" width="291"> + <col width="149"> <col width="48"> <col width="68"> <thead> <tr + valign="top"> + <th bgcolor="#e6e6e6" width="149"> + <p align="center"><br> + </p> + </th> + <th bgcolor="#e6e6e6" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">Mana</font></p> + </th> + <th bgcolor="#e6e6e6" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">Zeiteinheiten</font></p> + </th> + </tr> + </thead> <tbody> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Helden +weihen</font></p> + </th> + <td sdval="1" sdnum="1031;" valign="bottom" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + <td sdval="0" sdnum="1031;" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + </tr> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Priester +erleuchten</font></p> + </th> + <td sdval="5" sdnum="1031;" valign="bottom" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">5</font></p> + </td> + <td sdval="0" sdnum="1031;" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + </tr> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Arche bauen</font></p> + </th> + <td sdval="5" sdnum="1031;" valign="bottom" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">5</font></p> + </td> + <td sdval="30" sdnum="1031;" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">30</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffffcc" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Avatar +erschaffen</font></p> + </th> + <td sdval="5" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">5</font></p> + </td> + <td sdval="0" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffffcc" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Avatar +bewegen</font></p> + </th> + <td sdval="1" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + <td sdval="1" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">1</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffffcc" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Avatarkampf</font></p> + </th> + <td sdval="1" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">2 pro Kampf</font></p> + </td> + <td sdval="10" sdnum="1031;" bgcolor="#ffffcc" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">10</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffffcc" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Avatar- +Hilfe im Erdlingskampf</font></p> + </th> + <td bgcolor="#ffffcc" valign="top" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">2 pro +Kampf</font></p> + </td> + <td bgcolor="#ffffcc" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">--</font></p> + </td> + </tr> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Sintflut</font></p> + </th> + <td sdval="2" sdnum="1031;" valign="bottom" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">2</font></p> + </td> + <td valign="top" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">40</font></p> + </td> + </tr> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Tempel +zerstören</font></p> + </th> + <td sdval="5" sdnum="1031;" valign="bottom" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">5</font></p> + </td> + <td sdval="0" sdnum="1031;" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffcc99" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Seuche: +Influentia </font> </p> + </th> + <td sdval="10" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">10</font></p> + </td> + <td sdval="10" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">20</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffcc99" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Seuche: +Pestilenzia</font></p> + </th> + <td sdval="10" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">20</font></p> + </td> + <td sdval="20" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">20</font></p> + </td> + </tr> + <tr> + <th bgcolor="#ffcc99" valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Seuche: +Ebola</font></p> + </th> + <td sdval="10" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">40</font></p> + </td> + <td sdval="30" sdnum="1031;" bgcolor="#ffcc99" valign="bottom" + width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">20</font></p> + </td> + </tr> + <tr> + <th valign="top" width="149"> + <p align="left"><font style="font-size: 9pt;" size="2">Glücksfaktor +ändern</font></p> + </th> + <td valign="top" width="48"> + <p align="center"><font style="font-size: 9pt;" size="2">1 pro +Punkt</font></p> + </td> + <td sdval="5" sdnum="1031;" valign="bottom" width="68"> + <p align="center"><font style="font-size: 9pt;" size="2">0</font></p> + </td> + </tr> + </tbody> +</table></td></tr><tr><td> +<p><font style="font-size: 11pt;" size="2"><b>Sonstiges Timing </b></font> +</p> +<table border="1" cellpadding="4" cellspacing="0" width="242"> + <col width="148"> <col width="76"> <thead> <tr valign="top"> + <th bgcolor="#e6e6e6" width="148"> + <p><br> + </p> + </th> + <th bgcolor="#e6e6e6" width="76"> + <p><font style="font-size: 9pt;" size="2">Zeiteinheiten</font></p> + </th> + </tr> + </thead> <tbody> + <tr> + <th valign="top" width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">Tempelbau</font></p> + </th> + <td valign="bottom" width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">3, 6, +9....</font></p> + </td> + </tr> + <tr> + <th valign="top" width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">Erdlingskampf</font></p> + </th> + <td sdval="6" sdnum="1031;" valign="bottom" width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">6</font></p> + </td> + </tr> + <tr valign="top"> + <th width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">Krieger +Produktion</font></p> + </th> + <td width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">40 + 4 * PEACE</font></p> + </td> + </tr> + <tr valign="top"> + <th width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">Krieger +Produktion Heimatstadt</font></p> + </th> + <td width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">20</font></p> + </td> + </tr> + <tr> + <th valign="top" width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">Priester +Produktion</font></p> + </th> + <td sdval="40" sdnum="1031;" valign="bottom" width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">40</font></p> + </td> + </tr> + <tr> + <th valign="top" width="148"> + <p align="left"><font style="font-size: 9pt;" size="2">Mana +Produktion</font></p> + </th> + <td sdval="10" sdnum="1031;" valign="bottom" width="76"> + <p align="center"><font style="font-size: 9pt;" size="2">10</font></p> + </td> + </tr> + </tbody> +</table> +</td></tr></table> +</body> +</html> diff --git a/html/welcome_english.html b/html/welcome_english.html new file mode 100644 index 0000000..a483609 --- /dev/null +++ b/html/welcome_english.html @@ -0,0 +1,61 @@ +<hr> +<h2>The last days of Aymargeddon</h2> + +This is the homepage of the game "The last days of Aymargeddon". The game is still under development. It will be a multi-player-browser-game and it is a successor of the +Pbem <a href="http://ragnaroek.home.pages.de/"> Ragnarök </a>. +<p> +The next Beta-Test will start in the beginning of june. +<p> +You can <a href="login.epl">participate</a> if you are willing to help in the +development with your bug reports. +In this case please subscribe to the mailinglist (see below). +<p> +Unfortunatly the Rules are in german only in the moment, sorry). +<hr> +You have read-access to the sourcecode via +<a href="http://www.gnu.org/software/gnu-arch/">Gnu Arch</a>. + +<p>Archiv +coordinates: +<pre> + archive: benni@obda.de--2003-A + location: http://aymargeddon.de/ARCHIVES/2003-A + project: aymargeddon--main--0.2 +</pre> + +<p> + Aymargeddon is <a href="http://www.gnu.org/philosophy/free-sw.html">free software</a>; +you can redistribute it and/or modify it + under the terms of the <a href="src/COPYING">GNU General Public +License</a>. + +<strong>Warning:</strong> MS-IE-Explorer cant display transparent +png's, therefore this program cant be used to play this game. In the +moment the best browser for playing Aymargeddon is one derived from Mozilla (Netscape, Firefox, ...). + +<hr>If you are interested in the game you should subscribe to the mailinglist. Please send a mail to + +<pre> +majordomo@informatik.uni-frankfurt.de +</pre> + +with the following content: + +<pre> +subscribe ragnaroek +</pre> + +If you want to get rid of the mails you send + +<pre> +unsubscribe ragnaroek +</pre> + +<hr> + A Screenshot of the last game: +<img src="pic/Screenshot.png"> + +<hr> +<a href="http://www.informatik.uni-frankfurt.de/~benni/hello.html"> +Bennis Homepage</a> + diff --git a/html/welcome_german.html b/html/welcome_german.html new file mode 100644 index 0000000..c82184f --- /dev/null +++ b/html/welcome_german.html @@ -0,0 +1,66 @@ +<hr> +<h2>Die letzen Tage von Aymargeddon</h2> +Dies ist die Homepage des Spiels "Die letzten Tage von Aymargeddon". +Das Spiel ist noch in der Entwicklung. Es soll ein +Browser-Multi-Player-Spiel werden und ist eine Weiterentwicklung des +Pbem <a href="http://ragnaroek.home.pages.de/"> Ragnarök </a>. +<p> +Der nächste Beta-Test startet Anfang Juni. +<p> +Du kannst gerne daran <a +href="login.epl">teilnehmen</a>, wenn Du Lust hast uns mit +Fehlerberichten dabei zu helfen, das Spiel zu entwickeln. In diesem +Fall solltest Du Dich auf die Mailingliste eintragen (siehe unten). +<p> +<hr> +Den Quellcode kann man lesend zugreifen über +<a href="http://www.gnu.org/software/gnu-arch/">Gnu Arch</a>. + +<p>Archiv +koordinaten: +<pre> + archive: benni@obda.de--2003-A + location: http://aymargeddon.de/ARCHIVES/2003-A + project: aymargeddon--main--0.2 +</pre> + +<p> + Aymargeddon is <a href="http://www.gnu.org/philosophy/free-sw.html">free software</a>; +you can redistribute it and/or modify it + under the terms of the <a href="src/COPYING">GNU General Public +License</a>. +<hr> + +<strong>Warnung:</strong> Der MS-Internet-Explorer kann transparente +PNGs nicht korrekt anzeigen und ist deswegen unbrauchbar. Momentan +funktioniert am Besten Mozilla und abgeleitete Browser (Netscape oder +Firefox z.B.). Generell soll Aymargeddon aber für alle Browser +spielbar sein. + +<hr>Wer interesse an dem Spiel hat, sollte sich auf die Mailingliste +eintragen. Dazu bitte eine Mail an + +<pre> +majordomo@informatik.uni-frankfurt.de +</pre> + +mit folgendem Inhalt: + +<pre> +subscribe ragnaroek +</pre> + +Solltet ihr wieder von dieser Liste runter wollen, schickt ihr einfach +ein: + +<pre> +unsubscribe ragnaroek +</pre> + +<hr> +Hier ein Screenshot vom letzten Test: +<img src="pic/Screenshot.png"> +<hr> +<a href="http://www.informatik.uni-frankfurt.de/~benni/hello.html"> +Bennis Homepage</a> + diff --git a/linecount b/linecount new file mode 100644 index 0000000..d584d73 --- /dev/null +++ b/linecount @@ -0,0 +1,26 @@ +#!/bin/sh + +echo "Lines of Code:" + +echo "Embedded Perl:" +cat html/*.epl | wc -l + +echo "FROGS:" +cat src/FROGS/*.pm src/FROGS/*.pl | wc -l + +echo "other Perl:" +cat src/*.pl src/*.pm | wc -l + +echo "SQL:" +cat var/RAGNAROEK.sql var/LOCALIZE.sql | wc -l + +echo "scripts:" +cat var/delete_game linecount var/do_sql var/extract_structure_and_localize var/backup var/from_scratch \ + agrep push doc/push_rules src/FROGS/speed_scheduler src/FROGS/start_scheduler | wc -l + +echo "------------------" +echo "total:" +cat var/delete_game html/*.epl src/FROGS/*.pm src/FROGS/*.pl src/*.pl src/*.pm \ + linecount var/do_sql var/extract_structure_and_localize var/backup var/from_scratch \ + agrep push doc/push_rules src/FROGS/speed_scheduler src/FROGS/start_scheduler \ + var/RAGNAROEK.sql var/LOCALIZE.sql | wc -l diff --git a/pic/Screenshot.png b/pic/Screenshot.png new file mode 100644 index 0000000..d16a2c5 Binary files /dev/null and b/pic/Screenshot.png differ diff --git a/pic/map/Aymargeddon.ACT b/pic/map/Aymargeddon.ACT new file mode 100644 index 0000000..df137ca Binary files /dev/null and b/pic/map/Aymargeddon.ACT differ diff --git a/pic/map/BBB.png b/pic/map/BBB.png new file mode 100644 index 0000000..5bfcd29 Binary files /dev/null and b/pic/map/BBB.png differ diff --git a/pic/map/BBE.png b/pic/map/BBE.png new file mode 100644 index 0000000..5ccfc42 Binary files /dev/null and b/pic/map/BBE.png differ diff --git a/pic/map/BBF.png b/pic/map/BBF.png new file mode 100644 index 0000000..d21f9b8 Binary files /dev/null and b/pic/map/BBF.png differ diff --git a/pic/map/BBN.png b/pic/map/BBN.png new file mode 100644 index 0000000..e983887 Binary files /dev/null and b/pic/map/BBN.png differ diff --git a/pic/map/BBO.png b/pic/map/BBO.png new file mode 100644 index 0000000..d3dba3c Binary files /dev/null and b/pic/map/BBO.png differ diff --git a/pic/map/BBP.png b/pic/map/BBP.png new file mode 100644 index 0000000..05c1aa3 Binary files /dev/null and b/pic/map/BBP.png differ diff --git a/pic/map/BBP2.png b/pic/map/BBP2.png new file mode 100644 index 0000000..d17648d Binary files /dev/null and b/pic/map/BBP2.png differ diff --git a/pic/map/BBU.png b/pic/map/BBU.png new file mode 100644 index 0000000..809a570 Binary files /dev/null and b/pic/map/BBU.png differ diff --git a/pic/map/BBW.png b/pic/map/BBW.png new file mode 100644 index 0000000..05c1aa3 Binary files /dev/null and b/pic/map/BBW.png differ diff --git a/pic/map/BEB.png b/pic/map/BEB.png new file mode 100644 index 0000000..0debbd2 Binary files /dev/null and b/pic/map/BEB.png differ diff --git a/pic/map/BEE.png b/pic/map/BEE.png new file mode 100644 index 0000000..bd314ae Binary files /dev/null and b/pic/map/BEE.png differ diff --git a/pic/map/BEF.png b/pic/map/BEF.png new file mode 100644 index 0000000..eae65fd Binary files /dev/null and b/pic/map/BEF.png differ diff --git a/pic/map/BEN.png b/pic/map/BEN.png new file mode 100644 index 0000000..bdbd018 Binary files /dev/null and b/pic/map/BEN.png differ diff --git a/pic/map/BEO.png b/pic/map/BEO.png new file mode 100644 index 0000000..0764d88 Binary files /dev/null and b/pic/map/BEO.png differ diff --git a/pic/map/BEU.png b/pic/map/BEU.png new file mode 100644 index 0000000..b1cca5e Binary files /dev/null and b/pic/map/BEU.png differ diff --git a/pic/map/BEW.png b/pic/map/BEW.png new file mode 100644 index 0000000..a8a9111 Binary files /dev/null and b/pic/map/BEW.png differ diff --git a/pic/map/BFB.png b/pic/map/BFB.png new file mode 100644 index 0000000..9c2218b Binary files /dev/null and b/pic/map/BFB.png differ diff --git a/pic/map/BFE.png b/pic/map/BFE.png new file mode 100644 index 0000000..c33afc9 Binary files /dev/null and b/pic/map/BFE.png differ diff --git a/pic/map/BFF.png b/pic/map/BFF.png new file mode 100644 index 0000000..14c0aaf Binary files /dev/null and b/pic/map/BFF.png differ diff --git a/pic/map/BFN.png b/pic/map/BFN.png new file mode 100644 index 0000000..d3ef082 Binary files /dev/null and b/pic/map/BFN.png differ diff --git a/pic/map/BFO.png b/pic/map/BFO.png new file mode 100644 index 0000000..8761b79 Binary files /dev/null and b/pic/map/BFO.png differ diff --git a/pic/map/BFU.png b/pic/map/BFU.png new file mode 100644 index 0000000..9006f95 Binary files /dev/null and b/pic/map/BFU.png differ diff --git a/pic/map/BFW.png b/pic/map/BFW.png new file mode 100644 index 0000000..c5ebf70 Binary files /dev/null and b/pic/map/BFW.png differ diff --git a/pic/map/BNB.png b/pic/map/BNB.png new file mode 100644 index 0000000..a3d708f Binary files /dev/null and b/pic/map/BNB.png differ diff --git a/pic/map/BNE.png b/pic/map/BNE.png new file mode 100644 index 0000000..485f4cf Binary files /dev/null and b/pic/map/BNE.png differ diff --git a/pic/map/BNF.png b/pic/map/BNF.png new file mode 100644 index 0000000..d57622c Binary files /dev/null and b/pic/map/BNF.png differ diff --git a/pic/map/BNN.png b/pic/map/BNN.png new file mode 100644 index 0000000..f98ca9f Binary files /dev/null and b/pic/map/BNN.png differ diff --git a/pic/map/BNO.png b/pic/map/BNO.png new file mode 100644 index 0000000..38effbe Binary files /dev/null and b/pic/map/BNO.png differ diff --git a/pic/map/BNU.png b/pic/map/BNU.png new file mode 100644 index 0000000..cc823eb Binary files /dev/null and b/pic/map/BNU.png differ diff --git a/pic/map/BNW.png b/pic/map/BNW.png new file mode 100644 index 0000000..076c82a Binary files /dev/null and b/pic/map/BNW.png differ diff --git a/pic/map/BOB.png b/pic/map/BOB.png new file mode 100644 index 0000000..a3235a3 Binary files /dev/null and b/pic/map/BOB.png differ diff --git a/pic/map/BOE.png b/pic/map/BOE.png new file mode 100644 index 0000000..0bafbd8 Binary files /dev/null and b/pic/map/BOE.png differ diff --git a/pic/map/BOF.png b/pic/map/BOF.png new file mode 100644 index 0000000..bab000c Binary files /dev/null and b/pic/map/BOF.png differ diff --git a/pic/map/BON.png b/pic/map/BON.png new file mode 100644 index 0000000..cacedb7 Binary files /dev/null and b/pic/map/BON.png differ diff --git a/pic/map/BOO.png b/pic/map/BOO.png new file mode 100644 index 0000000..55d2521 Binary files /dev/null and b/pic/map/BOO.png differ diff --git a/pic/map/BOU.png b/pic/map/BOU.png new file mode 100644 index 0000000..bf79097 Binary files /dev/null and b/pic/map/BOU.png differ diff --git a/pic/map/BOW.png b/pic/map/BOW.png new file mode 100644 index 0000000..5a987e5 Binary files /dev/null and b/pic/map/BOW.png differ diff --git a/pic/map/BPB.png b/pic/map/BPB.png new file mode 100644 index 0000000..c42879a Binary files /dev/null and b/pic/map/BPB.png differ diff --git a/pic/map/BPB2.png b/pic/map/BPB2.png new file mode 100644 index 0000000..3191893 Binary files /dev/null and b/pic/map/BPB2.png differ diff --git a/pic/map/BPW.png b/pic/map/BPW.png new file mode 100644 index 0000000..96557e9 Binary files /dev/null and b/pic/map/BPW.png differ diff --git a/pic/map/BPW2.png b/pic/map/BPW2.png new file mode 100644 index 0000000..ea77bd0 Binary files /dev/null and b/pic/map/BPW2.png differ diff --git a/pic/map/BT.gif b/pic/map/BT.gif new file mode 100644 index 0000000..fad6d44 Binary files /dev/null and b/pic/map/BT.gif differ diff --git a/pic/map/BUB.png b/pic/map/BUB.png new file mode 100644 index 0000000..80f99dd Binary files /dev/null and b/pic/map/BUB.png differ diff --git a/pic/map/BUE.png b/pic/map/BUE.png new file mode 100644 index 0000000..c0c59f4 Binary files /dev/null and b/pic/map/BUE.png differ diff --git a/pic/map/BUF.png b/pic/map/BUF.png new file mode 100644 index 0000000..36770fd Binary files /dev/null and b/pic/map/BUF.png differ diff --git a/pic/map/BUN.png b/pic/map/BUN.png new file mode 100644 index 0000000..8f201e1 Binary files /dev/null and b/pic/map/BUN.png differ diff --git a/pic/map/BUO.png b/pic/map/BUO.png new file mode 100644 index 0000000..bd192ee Binary files /dev/null and b/pic/map/BUO.png differ diff --git a/pic/map/BUU.png b/pic/map/BUU.png new file mode 100644 index 0000000..4439a99 Binary files /dev/null and b/pic/map/BUU.png differ diff --git a/pic/map/BUW.png b/pic/map/BUW.png new file mode 100644 index 0000000..27bb253 Binary files /dev/null and b/pic/map/BUW.png differ diff --git a/pic/map/BWB.png b/pic/map/BWB.png new file mode 100644 index 0000000..c42879a Binary files /dev/null and b/pic/map/BWB.png differ diff --git a/pic/map/BWE.png b/pic/map/BWE.png new file mode 100644 index 0000000..8ab27ca Binary files /dev/null and b/pic/map/BWE.png differ diff --git a/pic/map/BWF.png b/pic/map/BWF.png new file mode 100644 index 0000000..b2542ba Binary files /dev/null and b/pic/map/BWF.png differ diff --git a/pic/map/BWN.png b/pic/map/BWN.png new file mode 100644 index 0000000..4a92aa6 Binary files /dev/null and b/pic/map/BWN.png differ diff --git a/pic/map/BWO.png b/pic/map/BWO.png new file mode 100644 index 0000000..b5ca713 Binary files /dev/null and b/pic/map/BWO.png differ diff --git a/pic/map/BWP.png b/pic/map/BWP.png new file mode 100644 index 0000000..96557e9 Binary files /dev/null and b/pic/map/BWP.png differ diff --git a/pic/map/BWP2.png b/pic/map/BWP2.png new file mode 100644 index 0000000..16609d0 Binary files /dev/null and b/pic/map/BWP2.png differ diff --git a/pic/map/BWU.png b/pic/map/BWU.png new file mode 100644 index 0000000..e970ff2 Binary files /dev/null and b/pic/map/BWU.png differ diff --git a/pic/map/BWW.png b/pic/map/BWW.png new file mode 100644 index 0000000..96557e9 Binary files /dev/null and b/pic/map/BWW.png differ diff --git a/pic/map/CB.png b/pic/map/CB.png new file mode 100644 index 0000000..41281d6 Binary files /dev/null and b/pic/map/CB.png differ diff --git a/pic/map/CECB.png b/pic/map/CECB.png new file mode 100644 index 0000000..c5d685a Binary files /dev/null and b/pic/map/CECB.png differ diff --git a/pic/map/CECE.png b/pic/map/CECE.png new file mode 100644 index 0000000..0668631 Binary files /dev/null and b/pic/map/CECE.png differ diff --git a/pic/map/CECF.png b/pic/map/CECF.png new file mode 100644 index 0000000..af46161 Binary files /dev/null and b/pic/map/CECF.png differ diff --git a/pic/map/CECN.png b/pic/map/CECN.png new file mode 100644 index 0000000..fb58102 Binary files /dev/null and b/pic/map/CECN.png differ diff --git a/pic/map/CECO.png b/pic/map/CECO.png new file mode 100644 index 0000000..dab9cc0 Binary files /dev/null and b/pic/map/CECO.png differ diff --git a/pic/map/CECU.png b/pic/map/CECU.png new file mode 100644 index 0000000..b14de5e Binary files /dev/null and b/pic/map/CECU.png differ diff --git a/pic/map/CEIE.png b/pic/map/CEIE.png new file mode 100644 index 0000000..7fcd3a8 Binary files /dev/null and b/pic/map/CEIE.png differ diff --git a/pic/map/CEIF.png b/pic/map/CEIF.png new file mode 100644 index 0000000..c15f48d Binary files /dev/null and b/pic/map/CEIF.png differ diff --git a/pic/map/CEIN.png b/pic/map/CEIN.png new file mode 100644 index 0000000..3de6989 Binary files /dev/null and b/pic/map/CEIN.png differ diff --git a/pic/map/CEIO.png b/pic/map/CEIO.png new file mode 100644 index 0000000..f3e7bfa Binary files /dev/null and b/pic/map/CEIO.png differ diff --git a/pic/map/CELE.png b/pic/map/CELE.png new file mode 100644 index 0000000..83cc691 Binary files /dev/null and b/pic/map/CELE.png differ diff --git a/pic/map/CELF.png b/pic/map/CELF.png new file mode 100644 index 0000000..d1a90f9 Binary files /dev/null and b/pic/map/CELF.png differ diff --git a/pic/map/CELN.png b/pic/map/CELN.png new file mode 100644 index 0000000..c40bc34 Binary files /dev/null and b/pic/map/CELN.png differ diff --git a/pic/map/CELO.png b/pic/map/CELO.png new file mode 100644 index 0000000..6d9c504 Binary files /dev/null and b/pic/map/CELO.png differ diff --git a/pic/map/CELU.png b/pic/map/CELU.png new file mode 100644 index 0000000..8f7bf28 Binary files /dev/null and b/pic/map/CELU.png differ diff --git a/pic/map/CEME.png b/pic/map/CEME.png new file mode 100644 index 0000000..7148aba Binary files /dev/null and b/pic/map/CEME.png differ diff --git a/pic/map/CEMF.png b/pic/map/CEMF.png new file mode 100644 index 0000000..bf6109f Binary files /dev/null and b/pic/map/CEMF.png differ diff --git a/pic/map/CEMN.png b/pic/map/CEMN.png new file mode 100644 index 0000000..65b5b1c Binary files /dev/null and b/pic/map/CEMN.png differ diff --git a/pic/map/CEMO.png b/pic/map/CEMO.png new file mode 100644 index 0000000..e0d75c5 Binary files /dev/null and b/pic/map/CEMO.png differ diff --git a/pic/map/CEWN.png b/pic/map/CEWN.png new file mode 100644 index 0000000..4081da3 Binary files /dev/null and b/pic/map/CEWN.png differ diff --git a/pic/map/CEWU.png b/pic/map/CEWU.png new file mode 100644 index 0000000..d012b27 Binary files /dev/null and b/pic/map/CEWU.png differ diff --git a/pic/map/CFCB.png b/pic/map/CFCB.png new file mode 100644 index 0000000..f98349b Binary files /dev/null and b/pic/map/CFCB.png differ diff --git a/pic/map/CFCE.png b/pic/map/CFCE.png new file mode 100644 index 0000000..391718a Binary files /dev/null and b/pic/map/CFCE.png differ diff --git a/pic/map/CFCF.png b/pic/map/CFCF.png new file mode 100644 index 0000000..fa1a312 Binary files /dev/null and b/pic/map/CFCF.png differ diff --git a/pic/map/CFCN.png b/pic/map/CFCN.png new file mode 100644 index 0000000..6a10c3f Binary files /dev/null and b/pic/map/CFCN.png differ diff --git a/pic/map/CFCO.png b/pic/map/CFCO.png new file mode 100644 index 0000000..801b528 Binary files /dev/null and b/pic/map/CFCO.png differ diff --git a/pic/map/CFCU.png b/pic/map/CFCU.png new file mode 100644 index 0000000..00e6914 Binary files /dev/null and b/pic/map/CFCU.png differ diff --git a/pic/map/CFIE.png b/pic/map/CFIE.png new file mode 100644 index 0000000..fc32c1f Binary files /dev/null and b/pic/map/CFIE.png differ diff --git a/pic/map/CFIF.png b/pic/map/CFIF.png new file mode 100644 index 0000000..f1d3708 Binary files /dev/null and b/pic/map/CFIF.png differ diff --git a/pic/map/CFIN.png b/pic/map/CFIN.png new file mode 100644 index 0000000..af375d1 Binary files /dev/null and b/pic/map/CFIN.png differ diff --git a/pic/map/CFIO.png b/pic/map/CFIO.png new file mode 100644 index 0000000..c5aad4b Binary files /dev/null and b/pic/map/CFIO.png differ diff --git a/pic/map/CFLE.png b/pic/map/CFLE.png new file mode 100644 index 0000000..6267bdb Binary files /dev/null and b/pic/map/CFLE.png differ diff --git a/pic/map/CFLF.png b/pic/map/CFLF.png new file mode 100644 index 0000000..5564dae Binary files /dev/null and b/pic/map/CFLF.png differ diff --git a/pic/map/CFLN.png b/pic/map/CFLN.png new file mode 100644 index 0000000..028b020 Binary files /dev/null and b/pic/map/CFLN.png differ diff --git a/pic/map/CFLO.png b/pic/map/CFLO.png new file mode 100644 index 0000000..b0b67de Binary files /dev/null and b/pic/map/CFLO.png differ diff --git a/pic/map/CFLU.png b/pic/map/CFLU.png new file mode 100644 index 0000000..c36d74c Binary files /dev/null and b/pic/map/CFLU.png differ diff --git a/pic/map/CFME.png b/pic/map/CFME.png new file mode 100644 index 0000000..c3eeb1e Binary files /dev/null and b/pic/map/CFME.png differ diff --git a/pic/map/CFMF.png b/pic/map/CFMF.png new file mode 100644 index 0000000..0e51d92 Binary files /dev/null and b/pic/map/CFMF.png differ diff --git a/pic/map/CFMN.png b/pic/map/CFMN.png new file mode 100644 index 0000000..22f0c48 Binary files /dev/null and b/pic/map/CFMN.png differ diff --git a/pic/map/CFMO.png b/pic/map/CFMO.png new file mode 100644 index 0000000..5c17ef1 Binary files /dev/null and b/pic/map/CFMO.png differ diff --git a/pic/map/CFWN.png b/pic/map/CFWN.png new file mode 100644 index 0000000..4082683 Binary files /dev/null and b/pic/map/CFWN.png differ diff --git a/pic/map/CFWU.png b/pic/map/CFWU.png new file mode 100644 index 0000000..9c1847e Binary files /dev/null and b/pic/map/CFWU.png differ diff --git a/pic/map/CNCB.png b/pic/map/CNCB.png new file mode 100644 index 0000000..e1a4e68 Binary files /dev/null and b/pic/map/CNCB.png differ diff --git a/pic/map/CNCE.png b/pic/map/CNCE.png new file mode 100644 index 0000000..133a99b Binary files /dev/null and b/pic/map/CNCE.png differ diff --git a/pic/map/CNCF.png b/pic/map/CNCF.png new file mode 100644 index 0000000..96a2d76 Binary files /dev/null and b/pic/map/CNCF.png differ diff --git a/pic/map/CNCN.png b/pic/map/CNCN.png new file mode 100644 index 0000000..1240c44 Binary files /dev/null and b/pic/map/CNCN.png differ diff --git a/pic/map/CNCO.png b/pic/map/CNCO.png new file mode 100644 index 0000000..e974148 Binary files /dev/null and b/pic/map/CNCO.png differ diff --git a/pic/map/CNCU.png b/pic/map/CNCU.png new file mode 100644 index 0000000..c65ffea Binary files /dev/null and b/pic/map/CNCU.png differ diff --git a/pic/map/CNIE.png b/pic/map/CNIE.png new file mode 100644 index 0000000..e2ff3f0 Binary files /dev/null and b/pic/map/CNIE.png differ diff --git a/pic/map/CNIF.png b/pic/map/CNIF.png new file mode 100644 index 0000000..af48990 Binary files /dev/null and b/pic/map/CNIF.png differ diff --git a/pic/map/CNIN.png b/pic/map/CNIN.png new file mode 100644 index 0000000..ad063a8 Binary files /dev/null and b/pic/map/CNIN.png differ diff --git a/pic/map/CNIO.png b/pic/map/CNIO.png new file mode 100644 index 0000000..bf05537 Binary files /dev/null and b/pic/map/CNIO.png differ diff --git a/pic/map/CNLE.png b/pic/map/CNLE.png new file mode 100644 index 0000000..6372fb4 Binary files /dev/null and b/pic/map/CNLE.png differ diff --git a/pic/map/CNLF.png b/pic/map/CNLF.png new file mode 100644 index 0000000..9c9da8a Binary files /dev/null and b/pic/map/CNLF.png differ diff --git a/pic/map/CNLN.png b/pic/map/CNLN.png new file mode 100644 index 0000000..fd4cc5e Binary files /dev/null and b/pic/map/CNLN.png differ diff --git a/pic/map/CNLO.png b/pic/map/CNLO.png new file mode 100644 index 0000000..6d3cae7 Binary files /dev/null and b/pic/map/CNLO.png differ diff --git a/pic/map/CNLU.png b/pic/map/CNLU.png new file mode 100644 index 0000000..f6b8354 Binary files /dev/null and b/pic/map/CNLU.png differ diff --git a/pic/map/CNME.png b/pic/map/CNME.png new file mode 100644 index 0000000..2795cf2 Binary files /dev/null and b/pic/map/CNME.png differ diff --git a/pic/map/CNMF.png b/pic/map/CNMF.png new file mode 100644 index 0000000..e0908ab Binary files /dev/null and b/pic/map/CNMF.png differ diff --git a/pic/map/CNMN.png b/pic/map/CNMN.png new file mode 100644 index 0000000..bd24032 Binary files /dev/null and b/pic/map/CNMN.png differ diff --git a/pic/map/CNMO.png b/pic/map/CNMO.png new file mode 100644 index 0000000..134d9d0 Binary files /dev/null and b/pic/map/CNMO.png differ diff --git a/pic/map/CNWN.png b/pic/map/CNWN.png new file mode 100644 index 0000000..56e13d3 Binary files /dev/null and b/pic/map/CNWN.png differ diff --git a/pic/map/CNWU.png b/pic/map/CNWU.png new file mode 100644 index 0000000..604c218 Binary files /dev/null and b/pic/map/CNWU.png differ diff --git a/pic/map/COCB.png b/pic/map/COCB.png new file mode 100644 index 0000000..acfa6de Binary files /dev/null and b/pic/map/COCB.png differ diff --git a/pic/map/COCE.png b/pic/map/COCE.png new file mode 100644 index 0000000..63f38c2 Binary files /dev/null and b/pic/map/COCE.png differ diff --git a/pic/map/COCF.png b/pic/map/COCF.png new file mode 100644 index 0000000..d6c8a4a Binary files /dev/null and b/pic/map/COCF.png differ diff --git a/pic/map/COCN.png b/pic/map/COCN.png new file mode 100644 index 0000000..fbbe70a Binary files /dev/null and b/pic/map/COCN.png differ diff --git a/pic/map/COCO.png b/pic/map/COCO.png new file mode 100644 index 0000000..87190f7 Binary files /dev/null and b/pic/map/COCO.png differ diff --git a/pic/map/COCU.png b/pic/map/COCU.png new file mode 100644 index 0000000..3590e0f Binary files /dev/null and b/pic/map/COCU.png differ diff --git a/pic/map/COIE.png b/pic/map/COIE.png new file mode 100644 index 0000000..af13eed Binary files /dev/null and b/pic/map/COIE.png differ diff --git a/pic/map/COIF.png b/pic/map/COIF.png new file mode 100644 index 0000000..038a1fc Binary files /dev/null and b/pic/map/COIF.png differ diff --git a/pic/map/COIN.png b/pic/map/COIN.png new file mode 100644 index 0000000..3931a73 Binary files /dev/null and b/pic/map/COIN.png differ diff --git a/pic/map/COIO.png b/pic/map/COIO.png new file mode 100644 index 0000000..56eb599 Binary files /dev/null and b/pic/map/COIO.png differ diff --git a/pic/map/COLE.png b/pic/map/COLE.png new file mode 100644 index 0000000..05fac69 Binary files /dev/null and b/pic/map/COLE.png differ diff --git a/pic/map/COLF.png b/pic/map/COLF.png new file mode 100644 index 0000000..335b4c6 Binary files /dev/null and b/pic/map/COLF.png differ diff --git a/pic/map/COLN.png b/pic/map/COLN.png new file mode 100644 index 0000000..05cd58a Binary files /dev/null and b/pic/map/COLN.png differ diff --git a/pic/map/COLO.png b/pic/map/COLO.png new file mode 100644 index 0000000..b930bb7 Binary files /dev/null and b/pic/map/COLO.png differ diff --git a/pic/map/COLU.png b/pic/map/COLU.png new file mode 100644 index 0000000..680264c Binary files /dev/null and b/pic/map/COLU.png differ diff --git a/pic/map/COME.png b/pic/map/COME.png new file mode 100644 index 0000000..b28b174 Binary files /dev/null and b/pic/map/COME.png differ diff --git a/pic/map/COMF.png b/pic/map/COMF.png new file mode 100644 index 0000000..3d7db61 Binary files /dev/null and b/pic/map/COMF.png differ diff --git a/pic/map/COMN.png b/pic/map/COMN.png new file mode 100644 index 0000000..4b48a4c Binary files /dev/null and b/pic/map/COMN.png differ diff --git a/pic/map/COMO.png b/pic/map/COMO.png new file mode 100644 index 0000000..db692a6 Binary files /dev/null and b/pic/map/COMO.png differ diff --git a/pic/map/COWN.png b/pic/map/COWN.png new file mode 100644 index 0000000..256fabd Binary files /dev/null and b/pic/map/COWN.png differ diff --git a/pic/map/COWU.png b/pic/map/COWU.png new file mode 100644 index 0000000..9ae99f2 Binary files /dev/null and b/pic/map/COWU.png differ diff --git a/pic/map/CPLA.png b/pic/map/CPLA.png new file mode 100644 index 0000000..5f1383c Binary files /dev/null and b/pic/map/CPLA.png differ diff --git a/pic/map/CPLA2.png b/pic/map/CPLA2.png new file mode 100644 index 0000000..9fc9724 Binary files /dev/null and b/pic/map/CPLA2.png differ diff --git a/pic/map/CPLU.png b/pic/map/CPLU.png new file mode 100644 index 0000000..676d25b Binary files /dev/null and b/pic/map/CPLU.png differ diff --git a/pic/map/CPLU2.png b/pic/map/CPLU2.png new file mode 100644 index 0000000..ee5189c Binary files /dev/null and b/pic/map/CPLU2.png differ diff --git a/pic/map/CUCB.png b/pic/map/CUCB.png new file mode 100644 index 0000000..bf2a45a Binary files /dev/null and b/pic/map/CUCB.png differ diff --git a/pic/map/CUCE.png b/pic/map/CUCE.png new file mode 100644 index 0000000..1221c5f Binary files /dev/null and b/pic/map/CUCE.png differ diff --git a/pic/map/CUCF.png b/pic/map/CUCF.png new file mode 100644 index 0000000..3d9f974 Binary files /dev/null and b/pic/map/CUCF.png differ diff --git a/pic/map/CUCN.png b/pic/map/CUCN.png new file mode 100644 index 0000000..b3ed30d Binary files /dev/null and b/pic/map/CUCN.png differ diff --git a/pic/map/CUCO.png b/pic/map/CUCO.png new file mode 100644 index 0000000..f661f3c Binary files /dev/null and b/pic/map/CUCO.png differ diff --git a/pic/map/CUCU.png b/pic/map/CUCU.png new file mode 100644 index 0000000..57c5ad9 Binary files /dev/null and b/pic/map/CUCU.png differ diff --git a/pic/map/CUIE.png b/pic/map/CUIE.png new file mode 100644 index 0000000..fe99f6f Binary files /dev/null and b/pic/map/CUIE.png differ diff --git a/pic/map/CUIF.png b/pic/map/CUIF.png new file mode 100644 index 0000000..23dceba Binary files /dev/null and b/pic/map/CUIF.png differ diff --git a/pic/map/CUIN.png b/pic/map/CUIN.png new file mode 100644 index 0000000..e0c7899 Binary files /dev/null and b/pic/map/CUIN.png differ diff --git a/pic/map/CUIO.png b/pic/map/CUIO.png new file mode 100644 index 0000000..5068f52 Binary files /dev/null and b/pic/map/CUIO.png differ diff --git a/pic/map/CULE.png b/pic/map/CULE.png new file mode 100644 index 0000000..1ee21dc Binary files /dev/null and b/pic/map/CULE.png differ diff --git a/pic/map/CULF.png b/pic/map/CULF.png new file mode 100644 index 0000000..107f0e5 Binary files /dev/null and b/pic/map/CULF.png differ diff --git a/pic/map/CULN.png b/pic/map/CULN.png new file mode 100644 index 0000000..a5fad23 Binary files /dev/null and b/pic/map/CULN.png differ diff --git a/pic/map/CULO.png b/pic/map/CULO.png new file mode 100644 index 0000000..788a0dc Binary files /dev/null and b/pic/map/CULO.png differ diff --git a/pic/map/CULU.png b/pic/map/CULU.png new file mode 100644 index 0000000..9b50407 Binary files /dev/null and b/pic/map/CULU.png differ diff --git a/pic/map/CUME.png b/pic/map/CUME.png new file mode 100644 index 0000000..03e5f86 Binary files /dev/null and b/pic/map/CUME.png differ diff --git a/pic/map/CUMF.png b/pic/map/CUMF.png new file mode 100644 index 0000000..cc8dac2 Binary files /dev/null and b/pic/map/CUMF.png differ diff --git a/pic/map/CUMN.png b/pic/map/CUMN.png new file mode 100644 index 0000000..c9fd964 Binary files /dev/null and b/pic/map/CUMN.png differ diff --git a/pic/map/CUMO.png b/pic/map/CUMO.png new file mode 100644 index 0000000..b23fa11 Binary files /dev/null and b/pic/map/CUMO.png differ diff --git a/pic/map/CUWN.png b/pic/map/CUWN.png new file mode 100644 index 0000000..1f5abe0 Binary files /dev/null and b/pic/map/CUWN.png differ diff --git a/pic/map/CUWU.png b/pic/map/CUWU.png new file mode 100644 index 0000000..56ee1cd Binary files /dev/null and b/pic/map/CUWU.png differ diff --git a/pic/map/Center.psd b/pic/map/Center.psd new file mode 100644 index 0000000..83e9e79 Binary files /dev/null and b/pic/map/Center.psd differ diff --git a/pic/map/HB.png b/pic/map/HB.png new file mode 100644 index 0000000..bab718c Binary files /dev/null and b/pic/map/HB.png differ diff --git a/pic/map/I0.gif b/pic/map/I0.gif new file mode 100644 index 0000000..17853e4 Binary files /dev/null and b/pic/map/I0.gif differ diff --git a/pic/map/I0.png b/pic/map/I0.png new file mode 100644 index 0000000..1029b78 Binary files /dev/null and b/pic/map/I0.png differ diff --git a/pic/map/I1.gif b/pic/map/I1.gif new file mode 100644 index 0000000..fd607d0 Binary files /dev/null and b/pic/map/I1.gif differ diff --git a/pic/map/I1.png b/pic/map/I1.png new file mode 100644 index 0000000..daa4092 Binary files /dev/null and b/pic/map/I1.png differ diff --git a/pic/map/I2.gif b/pic/map/I2.gif new file mode 100644 index 0000000..2a39408 Binary files /dev/null and b/pic/map/I2.gif differ diff --git a/pic/map/I2.png b/pic/map/I2.png new file mode 100644 index 0000000..0775db0 Binary files /dev/null and b/pic/map/I2.png differ diff --git a/pic/map/I3.gif b/pic/map/I3.gif new file mode 100644 index 0000000..0cb63f0 Binary files /dev/null and b/pic/map/I3.gif differ diff --git a/pic/map/I3.png b/pic/map/I3.png new file mode 100644 index 0000000..29cd74b Binary files /dev/null and b/pic/map/I3.png differ diff --git a/pic/map/I4.gif b/pic/map/I4.gif new file mode 100644 index 0000000..a47427d Binary files /dev/null and b/pic/map/I4.gif differ diff --git a/pic/map/I4.png b/pic/map/I4.png new file mode 100644 index 0000000..0dbde81 Binary files /dev/null and b/pic/map/I4.png differ diff --git a/pic/map/I5.gif b/pic/map/I5.gif new file mode 100644 index 0000000..4028004 Binary files /dev/null and b/pic/map/I5.gif differ diff --git a/pic/map/I5.png b/pic/map/I5.png new file mode 100644 index 0000000..596ec36 Binary files /dev/null and b/pic/map/I5.png differ diff --git a/pic/map/I6.gif b/pic/map/I6.gif new file mode 100644 index 0000000..7d049d3 Binary files /dev/null and b/pic/map/I6.gif differ diff --git a/pic/map/I6.png b/pic/map/I6.png new file mode 100644 index 0000000..a7bbaf1 Binary files /dev/null and b/pic/map/I6.png differ diff --git a/pic/map/I7.gif b/pic/map/I7.gif new file mode 100644 index 0000000..33412e9 Binary files /dev/null and b/pic/map/I7.gif differ diff --git a/pic/map/I7.png b/pic/map/I7.png new file mode 100644 index 0000000..cc1f28c Binary files /dev/null and b/pic/map/I7.png differ diff --git a/pic/map/I8.gif b/pic/map/I8.gif new file mode 100644 index 0000000..4009599 Binary files /dev/null and b/pic/map/I8.gif differ diff --git a/pic/map/I8.png b/pic/map/I8.png new file mode 100644 index 0000000..c8519ef Binary files /dev/null and b/pic/map/I8.png differ diff --git a/pic/map/I9.gif b/pic/map/I9.gif new file mode 100644 index 0000000..4448744 Binary files /dev/null and b/pic/map/I9.gif differ diff --git a/pic/map/I9.png b/pic/map/I9.png new file mode 100644 index 0000000..a11a137 Binary files /dev/null and b/pic/map/I9.png differ diff --git a/pic/map/IA.gif b/pic/map/IA.gif new file mode 100644 index 0000000..e2e3bc9 Binary files /dev/null and b/pic/map/IA.gif differ diff --git a/pic/map/IA.png b/pic/map/IA.png new file mode 100644 index 0000000..1ebd815 Binary files /dev/null and b/pic/map/IA.png differ diff --git a/pic/map/IE.gif b/pic/map/IE.gif new file mode 100644 index 0000000..409f32d Binary files /dev/null and b/pic/map/IE.gif differ diff --git a/pic/map/IE.png b/pic/map/IE.png new file mode 100644 index 0000000..8aaf6ab Binary files /dev/null and b/pic/map/IE.png differ diff --git a/pic/map/IF.png b/pic/map/IF.png new file mode 100644 index 0000000..45b6594 Binary files /dev/null and b/pic/map/IF.png differ diff --git a/pic/map/IF2.png b/pic/map/IF2.png new file mode 100644 index 0000000..b1666a4 Binary files /dev/null and b/pic/map/IF2.png differ diff --git a/pic/map/IG.gif b/pic/map/IG.gif new file mode 100644 index 0000000..ffa57ac Binary files /dev/null and b/pic/map/IG.gif differ diff --git a/pic/map/IG.png b/pic/map/IG.png new file mode 100644 index 0000000..3024b86 Binary files /dev/null and b/pic/map/IG.png differ diff --git a/pic/map/II.png b/pic/map/II.png new file mode 100644 index 0000000..02c286e Binary files /dev/null and b/pic/map/II.png differ diff --git a/pic/map/IP.png b/pic/map/IP.png new file mode 100644 index 0000000..5657239 Binary files /dev/null and b/pic/map/IP.png differ diff --git a/pic/map/IU.gif b/pic/map/IU.gif new file mode 100644 index 0000000..92e757f Binary files /dev/null and b/pic/map/IU.gif differ diff --git a/pic/map/IU.png b/pic/map/IU.png new file mode 100644 index 0000000..4a70973 Binary files /dev/null and b/pic/map/IU.png differ diff --git a/pic/map/IW.png b/pic/map/IW.png new file mode 100644 index 0000000..d19a4a5 Binary files /dev/null and b/pic/map/IW.png differ diff --git a/pic/map/README b/pic/map/README new file mode 100644 index 0000000..e0cff7d --- /dev/null +++ b/pic/map/README @@ -0,0 +1,79 @@ +Die Dateinamen sind so Computer-lesbar wie moeglich: + +Alle die mit B anfangen sind "Backslashes", die mit S +"Slashes", die mit C "Center" und die mit I "Icons". +bei den / und \ Bildern stehen die folgenden beiden +Buchstaben fuer + +B Schwarz +P Pol +W Wasser +U Unbesetzt +N Neutral +O Eigene +F Freunde +E Feinde + +(der erste Buchstabe gibt die "obere" der zweite die "untere" Farbe an). + +Bei den Center-Bildern steht der zweite Buchstabe fuer den +Erdling der drin ist (wie oben), der dritte Buchstabe ist +L Land, Manapol oder Berg ohne Tempel +C Stadt bzw. Heimatstadt +W Wasser bzw. Insel ohne Tempel +I Insel mit Tempel +M Berg mit Tempel + +der Letzte Buchstabe ist der Owner (B steht bei Heimatstaedten fuer +NICHT-HEIMATSTADT also Stadt und U steht bei Bergen fuer NICHT-HEILIG +also Plain). Der auserwaehlte Pol hat ein A als letzten Buchstaben. + +Bei den Icons steht das zweite Zeichen fuer + +0 es sind eigene und feindliche Avatare anwesend + (und vielleicht noch befreundete und/oder neutrale) +1 es sind eigene und neutrale Avatare anwesend + (und vielleicht noch befreundete) +2 es sind eigene und befreundete Avatare anwesend +3 es sind nur eigene Avatare anwesend +4 es sind befreundete und feindliche Avatare anwesend + (und vielleicht noch neutrale) +5 es sind befreundete und neutrale Avatare anwesend +6 es sind nur befreundete Avatare anwesend +7 es sind feindliche und neutrale Avatare anwesend +8 es sind nur feindliche Avatare anwesend +9 es sind nur neutrale Avatare anwesend +A es sind Archen im Feld +E es findet gerade ein Erdlingskampf statt +G es findet gerade ein Avatar-Kampf statt +U leeres Icon (wir in allen vier Ecken als Fuellsel benoetigt) + +So, jetzt das komplette Set - ein paar Namen haben sich noch +geaendert, weil mir ein Fehler unterlaufen war. Wirf das alte +Verzeichnis also besser vorher weg. + +Fuer die Karte ohne Spieler werden nur 31 von den 214 Bildchen +gebraucht, naemlich: + +CPLU Manapol +CPLA Aymargeddon +CUWU Wasser +CUWN Insel +CULU Ebene +CULN Berg +CUCU Heimatstadt +CUCB Stadt + +BBP, BPB, SBP, SPB Manapol am Rand +BWP, BPW, SWP, SPW zwischen Manapol und Wasser +BBW, BWB, SBW, SWB Wasser am Rand +BWW, SWW zwischen Wasserfeldern +BWU, BUW, SWU, SWW zwischen Land und Wasser +BBU, BUB, SBU, SUB Land am Rand +BUU, SUU zwischen Landfeldern + +Drei von den Bildchen sollten bei konsistenten Daten eigentlich +nie benoetigt werden, naemlich COLO, COMO und COIO (die selbe +ID kann nie an einen Gott und einen Erdling gleichzeitig vergeben +sein). Zu Testzwecken sind sie dennoch vorhanden. + diff --git a/pic/map/Rand2.psd b/pic/map/Rand2.psd new file mode 100644 index 0000000..d8280d3 Binary files /dev/null and b/pic/map/Rand2.psd differ diff --git a/pic/map/SBB.png b/pic/map/SBB.png new file mode 100644 index 0000000..5bfcd29 Binary files /dev/null and b/pic/map/SBB.png differ diff --git a/pic/map/SBE.png b/pic/map/SBE.png new file mode 100644 index 0000000..3177f0c Binary files /dev/null and b/pic/map/SBE.png differ diff --git a/pic/map/SBF.png b/pic/map/SBF.png new file mode 100644 index 0000000..76d197a Binary files /dev/null and b/pic/map/SBF.png differ diff --git a/pic/map/SBN.png b/pic/map/SBN.png new file mode 100644 index 0000000..5123729 Binary files /dev/null and b/pic/map/SBN.png differ diff --git a/pic/map/SBO.png b/pic/map/SBO.png new file mode 100644 index 0000000..75cb096 Binary files /dev/null and b/pic/map/SBO.png differ diff --git a/pic/map/SBP.png b/pic/map/SBP.png new file mode 100644 index 0000000..65a93bd Binary files /dev/null and b/pic/map/SBP.png differ diff --git a/pic/map/SBP2.png b/pic/map/SBP2.png new file mode 100644 index 0000000..8243c00 Binary files /dev/null and b/pic/map/SBP2.png differ diff --git a/pic/map/SBU.png b/pic/map/SBU.png new file mode 100644 index 0000000..b295c55 Binary files /dev/null and b/pic/map/SBU.png differ diff --git a/pic/map/SBW.png b/pic/map/SBW.png new file mode 100644 index 0000000..65a93bd Binary files /dev/null and b/pic/map/SBW.png differ diff --git a/pic/map/SEB.png b/pic/map/SEB.png new file mode 100644 index 0000000..b85093a Binary files /dev/null and b/pic/map/SEB.png differ diff --git a/pic/map/SEE.png b/pic/map/SEE.png new file mode 100644 index 0000000..16b35a5 Binary files /dev/null and b/pic/map/SEE.png differ diff --git a/pic/map/SEF.png b/pic/map/SEF.png new file mode 100644 index 0000000..95e73dc Binary files /dev/null and b/pic/map/SEF.png differ diff --git a/pic/map/SEN.png b/pic/map/SEN.png new file mode 100644 index 0000000..7e860c7 Binary files /dev/null and b/pic/map/SEN.png differ diff --git a/pic/map/SEO.png b/pic/map/SEO.png new file mode 100644 index 0000000..63e932c Binary files /dev/null and b/pic/map/SEO.png differ diff --git a/pic/map/SEU.png b/pic/map/SEU.png new file mode 100644 index 0000000..f14a201 Binary files /dev/null and b/pic/map/SEU.png differ diff --git a/pic/map/SEW.png b/pic/map/SEW.png new file mode 100644 index 0000000..e08b411 Binary files /dev/null and b/pic/map/SEW.png differ diff --git a/pic/map/SFB.png b/pic/map/SFB.png new file mode 100644 index 0000000..073616d Binary files /dev/null and b/pic/map/SFB.png differ diff --git a/pic/map/SFE.png b/pic/map/SFE.png new file mode 100644 index 0000000..41b699b Binary files /dev/null and b/pic/map/SFE.png differ diff --git a/pic/map/SFF.png b/pic/map/SFF.png new file mode 100644 index 0000000..ea71c5c Binary files /dev/null and b/pic/map/SFF.png differ diff --git a/pic/map/SFN.png b/pic/map/SFN.png new file mode 100644 index 0000000..5d1f659 Binary files /dev/null and b/pic/map/SFN.png differ diff --git a/pic/map/SFO.png b/pic/map/SFO.png new file mode 100644 index 0000000..495ce2b Binary files /dev/null and b/pic/map/SFO.png differ diff --git a/pic/map/SFU.png b/pic/map/SFU.png new file mode 100644 index 0000000..2dd92d7 Binary files /dev/null and b/pic/map/SFU.png differ diff --git a/pic/map/SFW.png b/pic/map/SFW.png new file mode 100644 index 0000000..a785ba7 Binary files /dev/null and b/pic/map/SFW.png differ diff --git a/pic/map/SNB.png b/pic/map/SNB.png new file mode 100644 index 0000000..0029f78 Binary files /dev/null and b/pic/map/SNB.png differ diff --git a/pic/map/SNE.png b/pic/map/SNE.png new file mode 100644 index 0000000..7db700f Binary files /dev/null and b/pic/map/SNE.png differ diff --git a/pic/map/SNF.png b/pic/map/SNF.png new file mode 100644 index 0000000..4ae88c4 Binary files /dev/null and b/pic/map/SNF.png differ diff --git a/pic/map/SNN.png b/pic/map/SNN.png new file mode 100644 index 0000000..d91b582 Binary files /dev/null and b/pic/map/SNN.png differ diff --git a/pic/map/SNO.png b/pic/map/SNO.png new file mode 100644 index 0000000..2bc9629 Binary files /dev/null and b/pic/map/SNO.png differ diff --git a/pic/map/SNU.png b/pic/map/SNU.png new file mode 100644 index 0000000..5d74110 Binary files /dev/null and b/pic/map/SNU.png differ diff --git a/pic/map/SNW.png b/pic/map/SNW.png new file mode 100644 index 0000000..60e0e1d Binary files /dev/null and b/pic/map/SNW.png differ diff --git a/pic/map/SOB.png b/pic/map/SOB.png new file mode 100644 index 0000000..b787443 Binary files /dev/null and b/pic/map/SOB.png differ diff --git a/pic/map/SOE.png b/pic/map/SOE.png new file mode 100644 index 0000000..d0e4f08 Binary files /dev/null and b/pic/map/SOE.png differ diff --git a/pic/map/SOF.png b/pic/map/SOF.png new file mode 100644 index 0000000..15b1e98 Binary files /dev/null and b/pic/map/SOF.png differ diff --git a/pic/map/SON.png b/pic/map/SON.png new file mode 100644 index 0000000..6d0c02b Binary files /dev/null and b/pic/map/SON.png differ diff --git a/pic/map/SOO.png b/pic/map/SOO.png new file mode 100644 index 0000000..3cc6f0e Binary files /dev/null and b/pic/map/SOO.png differ diff --git a/pic/map/SOU.png b/pic/map/SOU.png new file mode 100644 index 0000000..535d713 Binary files /dev/null and b/pic/map/SOU.png differ diff --git a/pic/map/SOW.png b/pic/map/SOW.png new file mode 100644 index 0000000..7626387 Binary files /dev/null and b/pic/map/SOW.png differ diff --git a/pic/map/SPB.png b/pic/map/SPB.png new file mode 100644 index 0000000..c181623 Binary files /dev/null and b/pic/map/SPB.png differ diff --git a/pic/map/SPB2.png b/pic/map/SPB2.png new file mode 100644 index 0000000..507380e Binary files /dev/null and b/pic/map/SPB2.png differ diff --git a/pic/map/SPW.png b/pic/map/SPW.png new file mode 100644 index 0000000..d06f8e5 Binary files /dev/null and b/pic/map/SPW.png differ diff --git a/pic/map/SPW2.png b/pic/map/SPW2.png new file mode 100644 index 0000000..8be1e55 Binary files /dev/null and b/pic/map/SPW2.png differ diff --git a/pic/map/ST.gif b/pic/map/ST.gif new file mode 100644 index 0000000..61d6437 Binary files /dev/null and b/pic/map/ST.gif differ diff --git a/pic/map/SUB.png b/pic/map/SUB.png new file mode 100644 index 0000000..0ec9249 Binary files /dev/null and b/pic/map/SUB.png differ diff --git a/pic/map/SUE.png b/pic/map/SUE.png new file mode 100644 index 0000000..aaf8168 Binary files /dev/null and b/pic/map/SUE.png differ diff --git a/pic/map/SUF.png b/pic/map/SUF.png new file mode 100644 index 0000000..edafa12 Binary files /dev/null and b/pic/map/SUF.png differ diff --git a/pic/map/SUN.png b/pic/map/SUN.png new file mode 100644 index 0000000..0234cf9 Binary files /dev/null and b/pic/map/SUN.png differ diff --git a/pic/map/SUO.png b/pic/map/SUO.png new file mode 100644 index 0000000..bf06d1c Binary files /dev/null and b/pic/map/SUO.png differ diff --git a/pic/map/SUU.png b/pic/map/SUU.png new file mode 100644 index 0000000..ed68329 Binary files /dev/null and b/pic/map/SUU.png differ diff --git a/pic/map/SUW.png b/pic/map/SUW.png new file mode 100644 index 0000000..2f128a8 Binary files /dev/null and b/pic/map/SUW.png differ diff --git a/pic/map/SWB.png b/pic/map/SWB.png new file mode 100644 index 0000000..c181623 Binary files /dev/null and b/pic/map/SWB.png differ diff --git a/pic/map/SWE.png b/pic/map/SWE.png new file mode 100644 index 0000000..c55dac8 Binary files /dev/null and b/pic/map/SWE.png differ diff --git a/pic/map/SWF.png b/pic/map/SWF.png new file mode 100644 index 0000000..8f4d1c0 Binary files /dev/null and b/pic/map/SWF.png differ diff --git a/pic/map/SWN.png b/pic/map/SWN.png new file mode 100644 index 0000000..6bd1313 Binary files /dev/null and b/pic/map/SWN.png differ diff --git a/pic/map/SWO.png b/pic/map/SWO.png new file mode 100644 index 0000000..4bb8506 Binary files /dev/null and b/pic/map/SWO.png differ diff --git a/pic/map/SWP.png b/pic/map/SWP.png new file mode 100644 index 0000000..d06f8e5 Binary files /dev/null and b/pic/map/SWP.png differ diff --git a/pic/map/SWP2.png b/pic/map/SWP2.png new file mode 100644 index 0000000..4b7f93b Binary files /dev/null and b/pic/map/SWP2.png differ diff --git a/pic/map/SWU.png b/pic/map/SWU.png new file mode 100644 index 0000000..185c9b8 Binary files /dev/null and b/pic/map/SWU.png differ diff --git a/pic/map/SWW.png b/pic/map/SWW.png new file mode 100644 index 0000000..d06f8e5 Binary files /dev/null and b/pic/map/SWW.png differ diff --git a/pic/map/Testmap.png b/pic/map/Testmap.png new file mode 100644 index 0000000..d84b6c4 Binary files /dev/null and b/pic/map/Testmap.png differ diff --git a/push b/push new file mode 100644 index 0000000..c5e7855 --- /dev/null +++ b/push @@ -0,0 +1,5 @@ +#!/bin/sh + +# copy aymargeddon documentation to the webserver. +scp -r doc/*.html doc/*.pdf aymargeddon.de:public_html/aymargeddon/ + diff --git a/src/AymCommand.pm b/src/AymCommand.pm new file mode 100644 index 0000000..0ef4385 --- /dev/null +++ b/src/AymCommand.pm @@ -0,0 +1,3865 @@ + +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of "Last days of Aymargeddon" +# +# Aymargeddon 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. +# +# Aymargeddon 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# +# Aymargeddon specific command clsses used by the scheduler +# generic FROGS-Command is in FROGS/Command.pm +# + +use strict; +use FROGS::Util; +use FROGS::HexTorus; +use Data::Dumper; + +########################################################## +# +# Base Class for Aymargeddon specific commands +# + +package AymCommand; +use Data::Dumper; +@AymCommand::ISA = qw(Command); + +sub end_of_the_game{ + my $self = shift; + + $self->{-context}->send_message_to_all({'MFROM' => 0, + 'MSG_TAG' => 'END_OF_GAME'}); + + Util::log("*****************************\n" . + "*** End of the Game! ***\n" . + "*****************************",0); + + $self->{-db}->update_hash('GAME', + "GAME=$self->{-game}", + {'RUNNING' => 'N'}); + +} + +# just a wrapper +sub avatar_available{ + my ($self,$loc,$god) = @_; + $god = $self->{-player} unless defined $god; + return $self->{-context}->avatar_available($loc,$god,$self->{-class}); +} + +# just another wrapper +sub get_neighbours{ + my ($self,$loc) = @_; + $loc = $self->{-dbhash}->{'LOCATION'} unless defined $loc; + + my $map = HexTorus->new($self->{-context}->get_size()); + my $location = Location->from_string($loc); + my @neighbours = $map->neighbours($location); + return map {$_ = $_->to_string();} @neighbours; +} + +# FIGHT_EARTHLING and Pestilenz +sub casualties{ + my ($self,$victim,$death_count,$no_conquer) = @_; + $self->{-looser} = $victim unless defined $self->{-looser}; + my $other; + unless(defined $no_conquer){ + $other = ($victim != $self->{-winner}) ? $self->{-winner} : $self->{-looser}; + } + + Util::log("death_count for $victim: $death_count",1); + + $self->{-dead}->{$victim} = {'A' => 0, + 'H' => 0, + 'P' => 0, + 'K' => 0, + 'C' => 0}; # conquered arks + + return unless $death_count; + + my $dying = $::conf->{-DEFAULT_DYING}; + unless($self->{-looser} < 0){ + my $earthling = $self->{-db}->single_hash_select('EARTHLING', + "PLAYER=$self->{-looser} AND ". + "GAME=$self->{-game}"); + $dying = $earthling->{'DYING'}; + } + $dying .= 'A'; + my $big_dying = {'P' => 'PRIEST', + 'K' => 'WARRIOR', + 'H' => 'HERO', + 'A' => 'ARK'}; + + # print Dumper $dying; + + # rearrange mobiles in a hash + # TODO PERFORMANCE,DESIGN: we should have read $self->{-mobiles} + # as a hash from database earlier, should be better in all cases. + my %victims_mobiles = (); + for my $mob (@{$self->{-mobiles}}){ + my ($id,$type,$own,$count,$stat) = @$mob; + next unless $own == $victim; + $victims_mobiles{$id} = $mob; + } + + # print Dumper \%victims_mobiles; + + my ($row, $carry, $share, $conquered_arks) = (0,0,0,0); + my $to_kill = $death_count; + my @small_dying = split //,$dying; + while(int($to_kill) > 0 and %victims_mobiles){ + my $small_dying = $small_dying[$row]; + # for my $small_dying (split //,$dying){ + $carry += $death_count * $::conf->{-DEATH_SHARE_ROW}->[$row]; + $share = int($carry); + $carry -= $share; + $share = $to_kill if($share > $to_kill); + + Util::log("type: $small_dying, share: $share, carry: $carry, to_kill: $to_kill",2); + + while( my ($key,$value) = each %victims_mobiles){ + my ($id,$type,$own,$count,$stat) = @$value; + # next unless $own == $victim; + next unless $type eq $big_dying->{$small_dying}; + Util::log("id: $id, count: $count, share: $share, ". + "carry: $carry, to_kill: $to_kill",2); + + my $dead_men = Util::min($count,$share); + $self->{-dead}->{$victim}->{$small_dying} += $dead_men; + if($small_dying eq 'H'){ + # dead heros fights for gods in last battle + my ($god) = $self->{-context}->get_mobile_info($id,'ADORING'); + Util::log("adored god: $god",1); + my ($actual) = $self->{-db}->single_select("SELECT DEATH_HERO FROM GOD WHERE ". + "GAME=$self->{-game} AND ". + "PLAYER=$god"); + Util::log("HERO dying: adds $dead_men heros ". + "to last-battle-strength of $god",1); + $self->{-db}->update_hash('GOD', + "GAME=$self->{-game} AND PLAYER=$god", + {'DEATH_HERO' => $actual + $dead_men}); + }elsif($small_dying eq 'A' and $victim == $self->{-looser} + and not defined $no_conquer){ + # special case ark (can change owner) + my $random_value = rand($dead_men); + Util::log("random value of $dead_men: $random_value",1); + $conquered_arks = int($random_value+0.5); + # $dead_men -= $conquered_arks; + Util::log("ark in battle: $conquered_arks change owner to $other, ". + "$dead_men arks sinking or conquered.",1); + $self->{-dead}->{$victim}->{'C'} += $conquered_arks; + } + + if($count > $dead_men){ + my $new_count = $count - $dead_men; + $self->{-db}->update_hash('MOBILE', + "ID=$id", + {'COUNT' => $new_count}); + $victims_mobiles{$id}->[3] = $new_count; + Util::log("Mobile $id ($small_dying) looses $dead_men people ". + "and have now $new_count.",1); + $to_kill -= $dead_men; + last; + }else{ + $share -= $count; + $to_kill -= $count; + $self->{-db}->delete_from('MOBILE',"ID=$id"); + $self->{-db}->update_hash('MOBILE', + "MOVE_WITH=$id", + {'MOVE_WITH' => 0}); + Util::log("Mobile $id ($small_dying) with $dead_men people is deleted",1); + delete $victims_mobiles{$id}; + } + } + + $carry += $share; + $row = ($row + 1)%4; + } + + unless(defined $no_conquer){ + my $total_conquered_arks = $self->{-dead}->{$victim}->{'C'}; + if($total_conquered_arks){ + # now conquered arks are (re-)created + my $mob = {'ID' => $self->{-db}->find_first_free('MOBILE','ID'), + 'GAME' => $self->{-game}, + 'LOCATION' => $self->{-location}, + 'TYPE' => 'ARK', + 'OWNER' => $self->{-winner}, + 'COUNT' => $self->{-dead}->{$victim}->{'C'}, + 'AVAILABLE' => 'Y', + 'COMMAND_ID' => $self->{-id}, + }; + $self->{-mob} = $mob; + my %mobcopy = (%$mob); + $self->{-db}->insert_hash('MOBILE',\%mobcopy); + $self->unify_mobiles($mob,$self->{-location},$self->{-winner}); + Util::log("$total_conquered_arks conquered arks for $self->{-winner}.",1); + $self->{-dead}->{$victim}->{'A'} -= $total_conquered_arks; + } + } + + $self->change_priest_on_temple($self->{-location}); +} + +sub move_with{ + my ($self,$id,$target,$count) = @_; + + # read mobile + my $mobile = $self->{-db}->single_hash_select('MOBILE',"ID=$id"); + + # split mobile + $self->conditional_split_mobile($mobile,$count, + {'MOVE_WITH' => $target},1); + Util::log("$count mobiles from id $id now moves with mobile $target",1); + + # reread mobile, because split destroys it + $mobile = $self->{-db}->single_hash_select('MOBILE',"ID=$id"); + + # all mobiles which already move with this now move with the target + if($target != 0){ + my $mob = $self->{-context}->mobiles_available($mobile->{'LOCATION'}); + my $mobcount = $#{@$mob}+1; + for my $i (0..$mobcount-1){ + my ($oid,$otype,$oown,$oado,$ocnt,$ostat,$omove) = @{$mob->[$i]}; + next if($omove != $id); + $self->{-db}->update_hash('MOBILE',"ID=$oid", + {'MOVE_WITH' => $target}); + Util::log("therefor all mobiles from id $oid now moves with mobile $target",1); + } + } + + # unify + $self->unify_mobiles($mobile,$mobile->{'LOCATION'}); +} + +# this function is called, if an earthling leave an field and let it possible empty +sub empty_field{ + my ($self,$loc,$player) = @_; + $player = $self->{-player} unless defined $player; + my $db = $self->{-db}; + my $aym = $self->{-context}; + my $oim = $aym->own_in_mobile($loc,$player,1); + + my ($home,$ter,$occ,$temple) = + $aym->read_field('HOME,TERRAIN,OCCUPANT,TEMPLE',$loc); + $home=0 if $ter eq 'MOUNTAIN'; + + unless(@$oim){ + my $keep_owner = 0; + $keep_owner = 1 if $home==$occ and $ter eq 'CITY' and $::conf->{-HOMECITY_KEEP_OWNER}; + $keep_owner = 1 if exists $::conf->{-KEEP_OWNER}->{$ter}; + $keep_owner = 1 if $::conf->{-TEMPLE_KEEP_OWNER} and $temple eq 'Y'; + + if($keep_owner){ + Util::log("leaving occupant $occ in field $loc",1); + }else{ + Util::log("reset old occupant $home in field $loc.",1); + # delete all PRODUCE and PRAY-Commands if any + $self->{-db}->delete_from('COMMAND', + "(COMMAND=PRODUCE OR COMMAND=PRAY) AND ". + "LOCATION=$loc AND GAME=$self->{-game}"); + # delete all PRODUCE-EVENTS + $self->{-db}->delete_from('EVENT', + "(TAG=EVENT_PRODUCE_WARRIOR OR TAG=EVENT_PRODUCE_PRIEST)". + " AND LOCATION=$loc AND GAME=$self->{-game}"); + $db->update_hash('MAP', + "LOCATION=$loc AND GAME=$self->{-game}", + {'OCCUPANT' => $home}); + } + } + $self->change_priest_on_temple($loc); +} + +# this check, if there is still a priest on a temple +# and if there is a new priest on temple +sub change_priest_on_temple{ + my ($self,$loc) = @_; + my $aym = $self->{-context}; + + my ($home,$temple,$occ) = $aym->read_field('HOME,TEMPLE,OCCUPANT',$loc); + return unless $temple eq 'Y'; + + my $produce = $self->{-db}->count('COMMAND', + "LOCATION=$loc AND GAME=$self->{-game} AND ". + "COMMAND=PRODUCE"); + + my $priests = $self->{-db}->count('MOBILE', + "LOCATION=$loc AND GAME=$self->{-game} AND ". + "TYPE=PRIEST AND ADORING=$home AND ". + "AVAILABLE=Y"); + + Util::log("priests: $priests, produce: $produce",1); + + if($priests and not $produce){ + $aym->insert_command('PRODUCE', "ROLE=$occ", $loc); + } + + if(not $priests and $produce){ + Util::log("delete produce-command and event",1); + # delete all PRODUCE -Commands if any + $self->{-db}->delete_from('COMMAND', + "COMMAND=PRODUCE AND ". + "LOCATION=$loc AND GAME=$self->{-game}"); + # delete all PRODUCE-EVENTS + $self->{-db}->delete_from('EVENT', + "(TAG=EVENT_PRODUCE_PRIEST)". + " AND LOCATION=$loc AND GAME=$self->{-game}"); + } +} + +# do we fight? do we conquer? do we join? +# TODO: turn_around if no ark and terrain==water +# TODO: could happen if location is flooded during movement. +sub enter_field{ + my ($self,$loc,$ignore_friend) = @_; + $ignore_friend = 0 unless defined $ignore_friend; + + Util::log("enter_field($loc,$ignore_friend)",2); + + # print "LOC: $loc\n"; + my ($occ,$att,$temple,$home,$terrain) = + $self->{-context}->read_field('OCCUPANT,ATTACKER,TEMPLE,HOME,TERRAIN',$loc); + $self->{-occupant} = $occ; + + my $relation = $self->{-context}->get_relation($occ); + + $relation = 'FOE' if $ignore_friend; + + # if there is allready an ongoing fight + if($att){ + # do nothing if we are allready involved + if($self->{-player} == $occ or $self->{-player} == $att){ + + Util::log("join the ongoing fight in $loc",1); + delete $self->{-multimove}; + return; + }else{ + # turn around otherwise + Util::log("in $loc: There is allready a fight between $occ and $att ". + "... turn around.",1); + $self->turn_around($loc); + delete $self->{-multimove}; + return; + } + } + + if($relation eq 'FRIEND' or $relation eq 'ALLIED'){ + # a friend has allready occupied this place, just turn around. + Util::log("in $loc: $occ is a friend of $self->{-player} ... turn around.",1); + $self->turn_around($loc); + delete $self->{-multimove}; + return; + } + + if($self->is_new_earthling_fight($loc,$relation,$terrain)){ + Util::log("new fight between earthlings in $loc:". + " attacker $self->{-player}, defender $occ",1); + + # we are the attacker + $self->do_earthling_fight($loc); + delete $self->{-multimove}; + return; + } + + if($occ == $self->{-player}){ + # was already our field + Util::log("$loc is allready field of $occ.",2); + $self->unify_mobiles($self->{-mob},$loc) unless defined $self->{-multimove}; + }else{ + # we are the new occupant + $self->conquer($loc,$self->{-player}); + } + + $self->change_priest_on_temple($loc); +} + +# peoples without arks drown +sub drowning{ + my ($self,$loc) = @_; + + # dont drown on islands or land + my ($terrain) = $self->{-context}->read_field('TERRAIN',$loc); + return unless $terrain eq 'WATER'; + + # is there still an active ark? + my $arks = $self->{-context}->read_mobile('TYPE','ARK',$loc,1); + # print Dumper $arks; + my @aa = @$arks; + return if $#aa >= 0; + + # get active mobiles + my $mobs = $self->{-context}->read_mobile('ID,TYPE,COUNT,OWNER','',$loc,1); + + my ($id,$type,$count,$owner); + for my $mob (@$mobs){ + ($id,$type,$count,$owner) = @$mob; + + next if $type eq 'ARK' or $type eq 'PROPHET'; + + # drown mobile + $self->{-db}->delete_from('MOBILE',"ID=$id"); + Util::log("No ark: $count $type from $owner drowned in $loc.",1); + + $self->{-context} + ->send_message_to($owner, + {'MFROM' => 0, + 'MSG_TAG' => 'MSG_MOBILE_DRAWN', + 'ARG1' => $count, + 'ARG2' => $self->{-context}->mobile_string($type,$count), + 'ARG3' => $self->{-context}->charname($owner), + 'ARG4' => $loc}); + } + $self->empty_field($loc,$owner) if $owner; +} + +sub conquer{ + my ($self,$loc,$player) = @_; + + Util::log("$player conquers $loc.",1); + $self->{-db}->update_hash('MAP',"LOCATION=$loc AND GAME=$self->{-game}", + {'OCCUPANT' => $player}); + + # conquer existing arks + $self->{-db}->update_hash('MOBILE',"LOCATION=$loc AND GAME=$self->{-game} AND TYPE=ARK", + {'OWNER' => $player}); + + # insert new PRODUCE-command and delete existent one and PRODUCE-events + my ($terrain,$temple,$home) = $self->{-context}->read_field('TERRAIN,TEMPLE,HOME',$loc); + + if ((not $home and $terrain eq 'CITY')){ + $self->{-db}->delete_from('COMMAND', "COMMAND=PRODUCE AND LOCATION=$loc". + " AND GAME=$self->{-game}"); + $self->{-db}->delete_from('EVENT',"TAG=EVENT_PRODUCE_WARRIOR AND LOCATION=$loc ". + "AND GAME=$self->{-game}"); + $self->{-context}->insert_command('PRODUCE', "ROLE=$player", $loc); + } + + #if ($temple eq 'Y'){ + # PRAY at temples + # $self->{-db}->delete_from('COMMAND', "COMMAND=PRAY AND LOCATION=$loc". + #" AND GAME=$self->{-game}"); + # + # } +} + +sub enter_field_avatar{ + my ($self,$loc,$mob) = @_; + + Util::log("enter_field_avatar() in $loc",1); + # print Dumper $mob; + + # if we are in Aymargeddon, do nothing special + my ($terrain) = $self->{-context}->read_field('TERRAIN',$loc); + if($terrain eq 'AYMARGEDDON'){ + Util::log("enter_field_avatar(AYMARGEDDON): do nothing",1); + delete $self->{-multimove}; + return; + } + + # mob can be ID or hash + $mob = $self->{-db}->read_single_mobile($mob) unless ref($mob); + # print Dumper $mob; + # get all avatars allready here from me and other owners + my $avatars = $self->{-context}->read_mobile_condition('ID,OWNER,STATUS', + "LOCATION=$loc ". + "AND TYPE=AVATAR ". + "AND AVAILABLE=Y"); + # print Dumper $avatars; + + # restructure data + my $own_avatars_here = 0; + my $own_avatar_status = 'IGNORE'; + my %other_avatar_owner = (); + my %other_avatar_status = (); + for my $a (@$avatars){ + my ($id,$own,$stat) = @$a; + next if($id == $mob->{'ID'}); + # print "own: $own\n"; + if($own == $mob->{'OWNER'}){ + $own_avatars_here = $id; + $own_avatar_status = $stat; + }elsif(!defined $other_avatar_owner{$own}){ + $other_avatar_owner{$own} = 1; + $other_avatar_status{$own} = $stat; + Util::log("found other avatar-owner $own in $loc",1); + }else{ + Util::log("other avatar-owner $own allready found in $loc",1); + } + } + + # if we are there allready with other avatars: + if($own_avatars_here){ + # set STATUS of newcomer to the STATUS in the field + if ($own_avatar_status ne $mob->{'STATUS'}){ + $self->{-db}->update_hash('MOBILE', + "ID=$mob->{'ID'}", + {'STATUS' => $own_avatar_status}); + } + Util::log("enter_field_avatar():Avatars (ID:$mob->{'ID'}) ". + "have to join other avatars with status $own_avatar_status in $loc.",1); + $self->unify_mobiles($mob); + }else{ + # for each other avatar-owner + for my $other (keys %other_avatar_owner){ + my $oas = $other_avatar_status{$other}; + # read alliance to each other owner (and vice versa) + my $allianceA = $self->{-context} + ->simplyfied_single_relation($other,$mob->{'OWNER'}); + my $allianceB = $self->{-context} + ->simplyfied_single_relation($mob->{'OWNER'},$other); + # insert FIGHT-command, if necessary + if($self->is_avatar_fight($allianceA,$allianceB,$mob->{'STATUS'},$oas)){ + $self->{-context}->insert_command('FIGHT_GOD', + "A=$other, B=$mob->{'OWNER'}", + $loc); + Util::log("enter_field_avatar():Avatars from $mob->{'OWNER'} ". + "have to fight with $other in $loc.",1); + delete $self->{-multimove}; + } + } + } +} + +sub is_avatar_fight{ + my ($self,$allA,$allB,$statA,$statB) = @_; + + Util::log("is_avatar_fight(): ". + "allA: $allA, allB: $allB, statA: $statA, statB: $statB",1); + + return 0 unless $statA eq 'BLOCK' or $statB eq 'BLOCK'; + my $status = 'NEUTRAL'; + if(($allA eq 'FOE') or ($allB eq 'FOE')){ + $status = 'FOE'; + }elsif(($allA eq 'FRIEND') or ($allB eq 'FRIEND')){ + $status = 'FRIEND'; + } + + return 1 if ($status eq 'FOE'); + return 1 if ($status eq 'NEUTRAL') and $statA eq 'BLOCK' and $statB eq 'BLOCK'; + return 0; +} + +# unify identical mobiles +# $mob still exists after function. all other of same +# TYPE, MOVE_WITH, ADORING will be deleted. +sub unify_mobiles{ + my ($self,$mob,$location,$owner) = @_; + + # mob can be ID or hash + $mob = $self->{-db}->read_single_mobile($mob) unless ref($mob); + + $location = $mob->{'LOCATION'} unless defined $location; + $owner = $self->{-player} unless defined $owner; + + Util::log("unify_mobiles() in $location for mobile $mob->{'ID'} of $owner",1); + + return if $self->{-db}->count('COMMAND', + "MOBILE=$mob->{'ID'} AND ID != $self->{-dbhash}->{'ID'}"); + + my $type = $mob->{'TYPE'}; + + my $mobs = $self->{-context}->read_mobile('ID,COUNT,ADORING,OWNER,MOVE_WITH', + $type, + # $mob->{'LOCATION'}, + $location, + 1 + ); + + my $count = $mob->{'COUNT'}; + for my $m (@$mobs){ + my ($oid,$ocount,$oado,$oown,$omove) = @$m; + + next if $oown ne $owner; # and $type ne 'ARK'; + next if $oid eq $mob->{'ID'}; + if(Util::is_in($type,'PRIEST','PROPHET','HERO')){ + next if $oado ne $mob->{'ADORING'}; + } + + next if(defined $mob->{'MOVE_WITH'} and $mob->{'MOVE_WITH'} ne $omove); + + next if $self->{-db}->count('COMMAND',"MOBILE=$oid"); + + $count += $ocount; + + $self->{-db}->delete_from('MOBILE',"ID=$oid"); + + # set new MOVE_WITH, if deleted unit has some companions + $self->{-db}->update_hash('MOBILE', + "MOVE_WITH=$oid", + {'MOVE_WITH' => $mob->{'ID'}}); + + } + $self->{-db}->update_hash('MOBILE', + "ID=$mob->{'ID'}", + {'COUNT' => $count}) if $count != $mob->{'COUNT'}; + + # rekursion for every companion of $mob + my $companions = $self->{-context}->read_mobile_condition('ID,OWNER', + "LOCATION=$location ". + "AND MOVE_WITH=$mob->{'ID'}"); + for my $m (@$companions){ + my ($mid,$mown) = @$m; + # does it still exist? + my $comp = $self->{-db}->read_single_mobile($mid); + next unless defined $comp; + $self->unify_mobiles($comp,$location,$mown); + } +} + +# the move-command will be set up again in the oposite direction +sub turn_around{ + my ($self,$loc) = @_; + + # first we have to check, if we are here because of an MOVE-COMMAND + # or out of some other reason + if($self->{-dbhash}->{'COMMAND'} eq 'MOVE'){ + my $mob = $self->{-mob}; + my $dir = $self->{-args}->{'DIR'}; + my $rev = {'S' => 'N', + 'N' => 'S', + 'SW' => 'NE', + 'NE' => 'SW', + 'SE' => 'NW', + 'NW' => 'SE',}; + $dir = $rev->{uc($dir)}; + Util::log("we ($mob->{'ID'} in $loc) are friends ". + "and come from $dir. we turn around...",1); + $self->{-context}->insert_command('MOVE', + "DIR=$dir, MOBILE=$mob->{'ID'}, ". + "COUNT=$mob->{'COUNT'}, AUTO=1",$loc); + }else{ + # + } +} + +# do we start a fight here? +sub is_new_earthling_fight{ + my ($self,$location,$relation,$terrain) = @_; + my $mob = $self->{-mob}; + my $attacker = $self->{-player}; + my $occupant = $self->{-occupant}; + + # no fight on some neutral territories + return 0 unless $occupant or exists $::conf->{-FIGHTS_WITHOUT_OWNER}->{$terrain}; + + # no new fight, if allready one started + return 0 if $self->{-context}->earthling_fight($location); + + return 0 if $attacker == $occupant or + $relation eq 'FRIEND' or + $relation eq 'ALLIED'; + + my $qloc = $self->{-db}->quote($location); + $self->{-db}->update_hash('MAP',"GAME=$self->{-game} AND LOCATION=$qloc", + {'ATTACKER' => $attacker}); + +} + +# start a fight! +sub do_earthling_fight{ + my ($self,$loc) = @_; + + # write the fight command + + $self->{-context}->insert_command('FIGHT_EARTHLING', + "ATTACKER=$self->{-player}, ". + "DEFENDER=$self->{-occupant}", + $loc); +} + +# enough mana available? +sub test_mana{ + my ($self,$action,$factor,$god) = @_; + $factor = 1 unless defined $factor; + $god = $self->{-player} unless defined $god; + + my $mana = $self->{-context}->get_mana($god); + my $mana_needed = $::conf->{-MANA}->{"-$action"} * $factor; + + Util::log("$god needs $mana_needed mana from his $mana mana to do $action",1); + + # dirty workaround: we fake our identity. + my $player = $self->{-player}; + $self->{-player} = $god; + unless($self->test(sub{ $mana >= $mana_needed }, + 'MSG_NOT_ENOUGH_MANA', + $action, + $self->{-location} ? $self->{-location} : 'GLOBAL')){ + $self->{-player} = $player; + return 0; + } + $self->{-player} = $player; + + $self->{-mana} = $mana - $mana_needed; + $self->{-mana_paid} = $mana_needed; + return 1; +} + +sub use_mana{ + my ($self,$god) = @_; + $god = $self->{-player} unless defined $god; + $self->{-db}->update_hash('GOD',"PLAYER=$god AND GAME=$self->{-game}", + {'MANA' => $self->{-mana}}); + Util::log("$god pays $self->{-mana_paid} mana ". + "and has still $self->{-mana} left.",1); + #TODO?: Message +} + +# this returns the used mana and did not test before +sub instant_use_mana{ + my ($self,$mana,$god) = @_; + $god = $self->{-player} unless defined $god; + + my $mana_available = $self->{-context}->get_mana($god); + + if ($mana_available < $mana) + { + # not enough mana + $mana = $mana_available; + } + my $newmana = $mana_available - $mana; + + $self->{-db}->update_hash( + 'GOD', + "PLAYER=$god AND GAME=$self->{-game}", + {'MANA' => $newmana} + ); + Util::log("$god pays $mana mana ". + "and has still $newmana left.",1); + return $mana; +} + +# +# End of AymCommand +# +#################################################### + +########################################################## +# +# Use this template to generate new commands +# + +package AymCommandTemplate; +@AymCommandTemplate::ISA = qw(AymCommand); + +# ... arguments in $self->{-args} +# ... player in $self->{-player} +# ... game in $self->{-game} +# ... context object in $self->{-context} +# ... database object in $self->{-db} +# ... basic duration from Config in $self->{-duration} +# ... command from database in $self->{-dbhash} + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + my @required_arguments = (); + return 0 unless $self->Command::is_valid(@required_arguments); + + # ... here your code + + return 1; +} + +# this is called from Scheduler, when he see the command the +# first time, some commands execute here immidiatly. +# AymCommand +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + # ... here your code + + return 1; +} + +# this is called from scheduler when the command will be executed. +# AymCommand +sub second_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + # ... here your code + + return 1; +} + +# +# End of template +# +#################################################### + +# +# CH_STATUS: Change the player alliance status +# + +package CH_STATUS; +@CH_STATUS::ISA = qw(AymCommand); + +sub is_valid{ + my ($self) = @_; + + my @required_arguments = ('OTHER','STATUS'); + return 0 unless $self->Command::is_valid(@required_arguments); + + # exist OTHER still in game? + if($self->{-args}->{'OTHER'} != -1){ + my $role = $self->{-context}->read_role($self->{-args}->{'OTHER'},'PLAYER'); + return 0 unless $self->test(sub{$role}, + 'MSG_NO_SUCH_ROLE'); + } + + # is STATUS valid? + my $status = $self->{-args}->{'STATUS'}; + return 0 unless $self->test(sub{Util::is_in($status, + 'FRIEND', + 'FOE', + 'NEUTRAL', + 'BETRAY', + 'ALLIED')}, + 'MSG_STATUS_INVALID', + $status); + return 1; +} + +# CH_STATUS +sub first_phase{ + my $self = shift; + return 0 unless $self->is_valid(); + + my $tag = 'MSG_CH_STATUS'; + my $other = $self->{-args}->{'OTHER'}; + my $status = $self->{-args}->{'STATUS'}; + # ($status,$tag) = $self->{-db}->quote_all($status,$tag); + $self->{-db}->insert_or_update_hash( + 'ALLIANCE', + "PLAYER=$self->{-player} ". + "AND OTHER=$other ". + "AND GAME=$self->{-game}", + {'GAME' => $self->{-game}, + 'PLAYER' => $self->{-player}, + 'OTHER' => $other, + 'STATUS' => $status} + ); + + #$self->{-context}->send_message_to_me({'MFROM' => 0, + # 'MSG_TAG' => $tag, + # 'ARG1' => $self->{-context}->charname($other), + # 'ARG2' => $status, + # }); + + $self->setDuration(0); + return 0; +}; + +sub second_phase{ + my $self = shift; + Util::log("Warning: We should not reach phase 2 with command CH_STATUS",0); + return 0; +}; + +# +# END of CH_STATUS +# +################################################################ + +################################################################ +# +# MOVE: Move mobiles +# + +package MOVE; +use Data::Dumper; +# use FROGS::HexTorus; +@MOVE::ISA = qw(AymCommand); + +sub is_valid { + my $self = shift; + + my $db = $self->{-db}; + my $args = $self->{-args}; + my $aym = $self->{-context}; + my $phase = $self->{-phase}; + + my @required_arguments = ('MOBILE','COUNT','DIR'); + return 0 unless $self->Command::is_valid(@required_arguments); + + my $mob_id = $args->{'MOBILE'}; + my $count = $args->{'COUNT'}; + + return 0 unless $count =~ /^\s*\d+\s*$/; + + return 0 unless $self->validate_mobile($self->{-args}->{'MOBILE'}); + my $mob = $self->{-mob}; + + my ($owner,$loc_string,$type) = ($mob->{'OWNER'}, + $mob->{'LOCATION'}, + $mob->{'TYPE'}, + ); + # print "LOCATION: $loc_string\n"; + $self->{-loc_string} = $loc_string; + + # enough mobiles avaiable? + if ($phase == 1) { + return 0 unless $self->test(sub {$count <= $mob->{'COUNT'} and + $mob->{'AVAILABLE'} eq 'Y'}, + 'MSG_NOT_ENOUGH_MOBILES', + 'MOVE', + $count, + $loc_string); + } + # get target field + + my ($size) = $db->read_game($self->{-game},'SIZE'); + $self->{-size} = $size; + my $map = HexTorus->new($size); + $self->{-map} = $map; + + my $loc = Location->from_string($loc_string); + $self->{-loc} = $loc; + + # MULTIMOVE: extract first direction and rest of string + my $direction = $args->{'DIR'}; + $direction =~ s/^\s*(\S*)\s*$/$1/; # removing leading/trailing whitespace + $direction =~ /^(\S*)\s+(.*)$/; # split up first direction + my ($first_direction,$other_directions) = ($1,$2); + if($other_directions){ + $self->{-multimove} = $other_directions; + $direction = $first_direction; + Util::log("MULTIMOVE: now $first_direction, later $other_directions",1); + } + + my $target = $map->get_neighbour($loc,$direction); + + # target correct? + return 0 unless $self->test(sub{$target}, + 'MSG_MOVE_NO_TARGET', + $loc_string, + $args->{'DIR'}); + $self->{-target} = $target; + my $target_string = $target->to_string(); + + # get terrain of loc and target + my ($terrain,$attacker,$god_attacker,$plague) = + $aym->read_field('TERRAIN,ATTACKER,GOD_ATTACKER,PLAGUE',$loc_string); + $plague = '' unless defined $plague; + my ($target_terrain,$target_occupant) = + $aym->read_field('TERRAIN,OCCUPANT',$target_string); + $self->{-target_occupant} = $target_occupant; + + # you can only MOVE_WITH on water, except you are an ARK + return 0 unless $self->test(sub{Util::is_in($target_terrain, + 'PLAIN', + 'CITY', + 'MOUNTAIN', + 'AYMARGEDDON', + 'POLE') or $type eq 'ARK'}, + 'MSG_CANT_SWIM', + 'CMD_MOVE', + $loc_string, + "MOBILE_$type\_PL"); + # $self->{-context}->mobile_string($type,2)); + + + + # role specific tests + my $role = $self->{-role}; + + # return 0 unless $self->validate_role('GOD','EARTHLING'); + #if ($mob->{'TYPE'} eq 'ARK') { + # Util::log("Impossible Situation: ARK has got a MOVE-Command",1); + if ($role eq 'GOD') { + # gods can only move avatars + return 0 unless $self->test(sub{$type eq 'AVATAR'}, + 'MSG_GOD_CANT_MOVE_TYPE', + $self->{-context}->mobile_string($type,2)); + + # dont move if $loc is Aymargeddon + return 0 unless $self->test(sub{$terrain ne 'AYMARGEDDON'}, + 'MSG_CANT_LEAVE_AYMARGEDDON', + $loc_string); + + + # dont move, if ongoing FIGHT_GOD + if($phase == 1){ + return 0 unless $self->test(sub{not $god_attacker}, + 'MSG_CANT_MOVE_ATTACKED', + $mob->{'LOCATION'}, + $self->{-context}->mobile_string($type,2)); + } + + # if targetfield water/isle, than dont move directly (only MOVE_WITH) + #if ($phase == 1 and (Util::is_in($target_terrain,'WATER','ISLE') # or + # Util::is_in($terrain,'WATER','ISLE')) + # )) { + + # TODO: Errormessage + + # return 0; + + #} + + # avatars can go on land, if ark available + #if ($phase==1 and Util::is_in($terrain,'ISLE','WATER') and + # not Util::is_in($target_terrain,'ISLE','WATER')) { + # my $arks = $self->{-context}->read_mobile('ID','ARK',$loc_string,1); + # my $ark_count = $#{@$arks}+1; + # return 0 unless $self->test(sub{$ark_count}, + # 'MSG_CANT_SWIM', + # 'MOVE', + # $loc_string, + # $self->{-context}->mobile_string($type,2)); + #} + } elsif ($role eq 'EARTHLING' or $owner == -1) { + # read companions + $self->{-companions} = $self->{-context}-> + read_mobile_condition('TYPE,COUNT,OWNER,ID', + "MOVE_WITH=$self->{-args}->{'MOBILE'}"); + + # do not move if field is attacked or tuberculosis + if ($phase == 1) { + return 0 unless $self->test(sub{not $attacker}, + 'MSG_CANT_MOVE_ATTACKED', + $mob->{'LOCATION'}, + $self->{-context}->mobile_string($type,2)); + return 0 unless $self->test(sub{ $plague !~ /TUBERCULOSIS/ + or exists $self->{-args}->{'AUTO'}}, + 'MSG_CANT_MOVE_PLAGUE', + $mob->{'LOCATION'}, + $self->{-context}->mobile_string($type,2), + 'Tuberculosis'); + } + # eartlings can only move this types + return 0 unless $self->test(sub{Util::is_in($type, + 'WARRIOR', + 'PRIEST', + 'HERO', + 'PROPHET', + 'ARK')}, + 'MSG_EARTHLING_CANT_MOVE_TYPE', + $self->{-context}->mobile_string($type,2)); + + # dont move if target field is Pole + return 0 unless $self->test(sub{$target_terrain ne 'AYMARGEDDON' and + $target_terrain ne 'POLE'}, + 'MSG_CANT_MOVE_TO_POLE', + 'MOVE', $target_string); + + # dont move ark from land to land + if($type eq 'ARK'){ + return 0 unless $self->test(sub{Util::is_in($terrain,'WATER','ISLE') or + Util::is_in($target_terrain,'WATER','ISLE')}, + 'MSG_CANT_MOVE_ARK', + 'MOVE', $target_string); + $self->{-active_ark} = $self->{-args}->{'MOBILE'}; + } + + # automatic ark-moving + # if ($type ne 'ARK' and $phase == 1 and + # (Util::is_in($target_terrain,'WATER','ISLE'))){ + # # or Util::is_in($terrain,'WATER','ISLE'))) { + # my $arks = $aym->read_mobile('ID,COUNT','ARK',$loc_string,1); + # # print Dumper $arks; + # my ($ark,$active); + # if (defined $arks->[0]) { + # ($ark,$active) = (@{$arks->[0]}); + # } else { + # ($ark,$active) = (0,0); + # } + # return 0 unless $self->test(sub {$active or $type eq 'PROPHET'}, + # 'MSG_CANT_SWIM', + # 'MOVE', + # $loc_string, + # $self->{-context}->mobile_string($type,2)); + # $self->{-active_ark} = $ark; + # Util::log("We take ark $ark with us.",1); + # } + + } else { + Util::log("impossible situation. I could not be $role",0); + return 0; + } + + # dont move without mana + if ($phase == 1) { + if ($role eq 'GOD') { + unless($self->test_mana('MOVE_AVATAR',$count)){ + $db->update_hash('MOBILE', + "ID=$mob_id", + { + 'AVAILABLE' => 'Y'}); + return 0; + } + } else { + # for all avatar-companions: pay or stay (if not on ark)! + if ($type ne 'ARK'){ + my $deleted = 0; + for my $comp (@{$self->{-companions}}) { + my ($ctype,$ccount,$cown,$cid) = @$comp; + next unless $ctype eq 'AVATAR'; + unless($self->test_mana('MOVE_AVATAR',$ccount,$cown) and not $god_attacker){ + $db->update_hash('MOBILE', + "ID=$cid", + {'AVAILABLE' => 'Y', + 'MOVE_WITH' => 0}); + $self->unify_mobiles($cid,0,$cown); + $deleted = 1; + } + } + # re-read companions + $self->{-companions} = $self->{-context}-> + read_mobile_condition('TYPE,COUNT,OWNER,ID', + "MOVE_WITH=$self->{-args}->{'MOBILE'}") + if $deleted; + + } + } + } + + return 1; +} + +# MOVE +sub first_phase{ + my ($self) = @_; + + return 0 unless $self->is_valid(); + + my $db = $self->{-db}; + my $type = $self->{-mob}->{'TYPE'}; + my $mob = $self->{-mob}; + my $aym = $self->{-context}; + + # split it, if neccessary + # the moving unit get the old ID! + + my $count = $self->{-args}->{'COUNT'}; + #print "conditional split with $count count and mob=\n"; + #print Dumper $mob; + #print Dumper $self; + return 0 unless + $self->conditional_split_mobile($mob,$count, + {'COMMAND_ID' => $self->{-dbhash}->{'ID'}, + 'MOVE_WITH' => 0},0); + + # if ark needed, move it together with us + #if($type ne 'ARK' and $self->{-active_ark}){ + + # $self->move_with($self->{-active_ark},$self->{-args}->{'MOBILE'},1); + + # set owner of ark + # $self->{-db}->update_hash('MOBILE', + # "ID=$self->{-active_ark}", + # {'OWNER' => $self->{-player}}); + #} + + # collect mobiles with MOVE_WITH in same location + my $companions = $self->{-companions}; + + # calculate duration + my $d = $::conf->{-DURATION}; + my $dur = $d->{"-MOVE_$type"}; + + # if moved with ark use -MOVE_ARK else use slowest + if($self->{-active_ark}){ + $dur = $d->{'-MOVE_ARK'}; + }else{ + for my $m (@$companions){ + my ($mtype) = @$m; + $dur = $d->{"-MOVE_$mtype"} if $d->{"-MOVE_$mtype"} > $dur; + } + } + $self->setDuration($dur); + + # set all companions inactive + $self->{-db}->update_hash('MOBILE', + "LOCATION=$mob->{'LOCATION'} ". + "AND MOVE_WITH=$self->{-args}->{'MOBILE'}", + {'AVAILABLE' => 'N'}); + + # remove OCCUPANT in MAP, if we are an earthling + # and there are no more own active (if it was our field) + # mobiles left and if it is no homecity + if($aym->is_earthling()){ + $self->empty_field($mob->{'LOCATION'}); + # avatar-companions: pay now + if($type ne 'ARK'){ + for my $comp (@$companions){ + my ($ctype,$ccount,$cown,$cid) = @$comp; + next unless $ctype eq 'AVATAR'; + $self->use_mana($cown); + } + } + }elsif($aym->is_god()){ + $self->use_mana(); + } + + # events + if($type eq 'ARK' or $self->{-active_ark}){ + $self->event($self->{-target}->to_string(), + 'EVENT_ARK_APPROACHING', + $mob->{'LOCATION'}, + $mob->{'COUNT'}); + }else{ #elsif($type ne 'ARK'){ + my $player = $self->{-player}; + my $count = $self->{-args}->{'COUNT'}; + my $typetag = $count > 1 ? "MOBILE_$type".'_PL' : "MOBILE_$type"; + $self->event($self->{-target}->to_string(), + 'EVENT_MOBILE_APPROACHING', + $mob->{'LOCATION'}, + $count, + # $self->{-context}->mobile_string($type,$count)); + $typetag); + + # TODO Bug: if avatar moves with hero, the wrong player is in the event-message. + + for my $m2 (@$companions){ + my ($mtype,$c,$mo) = @$m2; + $self->{-player} = $mo; + $typetag = $c > 1 ? "MOBILE_$mtype".'_PL' : "MOBILE_$mtype"; + $self->event($self->{-target}->to_string(), + 'EVENT_MOBILE_APPROACHING', + $mob->{'LOCATION'}, + $c, + # $self->{-context}->mobile_string($mtype,$c)) + $typetag); + } + $self->{-player} = $player; + } + + return $dur; +} + +# MOVE +sub second_phase{ + my ($self) = @_; + + return 0 unless $self->is_valid(); + + my $db = $self->{-db}; + my $mob = $self->{-mob}; + my $count = $self->{-args}->{'COUNT'}; + my $target_location = $self->{-target}->to_string(); + my $old_location = $mob->{'LOCATION'}; + + # move mobile and all moving with it. + $db->update_hash('MOBILE',"ID=$mob->{'ID'} OR MOVE_WITH=$mob->{'ID'}", + {'LOCATION' => $target_location, + 'AVAILABLE' => 'Y', + }); + + # TODO: distribute plagues + + # Bug? + # $self->{-db}->update_hash('MOBILE', + # "TYPE=ARK AND MOVE_WITH=$mob->{'ID'}", + # {'MOVE_WITH' => 0}); + + # should we do a godfight? + my $companions = $self->{-companions}; + if($mob->{'TYPE'} eq 'AVATAR'){ + $self->enter_field_avatar($target_location,$mob); + }else{ + for my $m (@$companions){ + my ($mtype,$mc,$mo,$mid) = @$m; + next unless $mtype eq 'AVATAR'; + $self->enter_field_avatar($target_location,$mid); + } + } + + $self->enter_field($target_location) if $self->{-role} eq 'EARTHLING'; + # $self->enter_field_avatar($target_location,$mob) if $self->{-role} eq 'GOD'; + $self->drowning($old_location); + + # MULTIMOVE + if(defined $self->{-multimove}){ + $self->{-context}->insert_command('MOVE', + "ROLE=$self->{-player}, ". + "DIR=$self->{-multimove}, ". + "MOBILE=$mob->{'ID'}, ". + "COUNT=$mob->{'COUNT'}", + $mob->{'LOCATION'}); + }else{ + $self->unify_mobiles($mob,$target_location); + } + +# TODO: maybe we should give a message only to the player of the unit +# ... but its difficult, because of MOVE_WITH + +# $self->{-context} +# ->send_message_to_field +# ($target_location, +# {'MFROM' => 0, +# 'MSG_TAG' => 'MSG_MOBILE_ARRIVES', +# 'ARG1' => $count, +# 'ARG2' => $self->{-context}->mobile_string($self->{-mob}->{'TYPE'}, +# $self->{-mob}->{'COUNT'}), +# 'ARG3' => $self->{-context}->charname($self->{-player}), +# 'ARG4' => $target_location}); + +# for my $m (@$companions){ +# my ($mtype,$mc,$mo,$mid) = @$m; +# $self->{-context} +# ->send_message_to_field +# ($target_location, +# {'MFROM' => 0, +# 'MSG_TAG' => 'MSG_MOBILE_ARRIVES', +# 'ARG1' => $mc, +# 'ARG2' => $self->{-context}->mobile_string($mtype,$mc), +# 'ARG3' => $self->{-context}->charname($mo), +# 'ARG4' => $target_location}); +# } + + + return 1; +} + +# +# End of MOVE +# +#################################################### + +########################################################## +# +# BLESS_PRIEST +# + +package BLESS_PRIEST; +@BLESS_PRIEST::ISA = qw(AymCommand); + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + my @required_arguments = ('MOBILE'); + return 0 unless $self->Command::is_valid(@required_arguments); + + return 0 unless $self->validate_mobile($self->{-args}->{'MOBILE'}); + + return 0 unless $self->validate_role('GOD'); + + my $mobtype = $self->{-mob}->{'TYPE'}; + my $mobloc = $self->{-mob}->{'LOCATION'}; + + # don't bless unassigned units + return 0 unless $self->test(sub{$self->{-mob}->{'OWNER'} > 0}, + 'MSG_CANT_BLESS_UNASSIGNED', + $mobloc); + + # only bless warriors + return 0 unless $self->test(sub{$self->{-mob}->{'TYPE'} eq 'WARRIOR'}, + 'MSG_WRONG_TYPE', + $self->{-context}->mobile_string($mobtype,1), + $mobloc); + + return 0 unless $self->test_mana('BLESS_PRIEST'); + + return 1; +} + +# this is called from Scheduler, if he see the command the +# first time, some commands execute here immidiatly. +# BLESS_PRIEST +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + my $id = $self->{-mob}->{'ID'}; + my $newid = $self->conditional_split_mobile($self->{-mob}, + 1, + {'ADORING' => $self->{-player}, + 'TYPE' => 'PRIEST', + 'COMMAND_ID' => $self->{-dbhash}->{'ID'}}, + 'beforeafter'); + + # companions move with the remaining warriors, not with the new priest + $self->{-db}->update_hash('MOBILE', + "MOVE_WITH = $id", + {'MOVE_WITH' => $newid}) if $id != $newid; + + # reread mobile, because split destroys it + $self->{-mob} = $self->{-db}->single_hash_select('MOBILE',"ID=$id"); + $self->unify_mobiles($self->{-mob}, + $self->{-mob}->{'LOCATION'}, + $self->{-mob}->{'OWNER'}); + + $self->change_priest_on_temple($self->{-mob}->{'LOCATION'}); + +# $self->{-context} +# ->send_message_to_field +# ($self->{-mob}->{'LOCATION'}, +# {'MFROM' => 0, +# 'MSG_TAG' => 'MSG_BLESS_PRIEST', +# 'ARG1' => $self->{-context}->charname($self->{-player}), +# 'ARG2' => $self->{-context}->charname($self->{-mob}->{'OWNER'}), +# 'ARG3' => $self->{-mob}->{'LOCATION'}}); + + + $self->use_mana(); + $self->setDuration(0); + + return 0; +} + +# this is called from scheduler when the command will be executed +sub second_phase{ + my $self = shift; + Util::log("BLESS_PRIEST should not have a second phase!",0); + return 0; +} + +# +# End of BLESS_PRIEST +# +#################################################### + +########################################################## +# +# BUILD_TEMPLE +# + +package BUILD_TEMPLE; +use Data::Dumper; +@BUILD_TEMPLE::ISA = qw(AymCommand); + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + my @required_arguments = ('MOBILE'); + return 0 unless $self->Command::is_valid(@required_arguments); + + return 0 unless $self->validate_mobile($self->{-args}->{'MOBILE'}); + + my $mobtype = $self->{-mob}->{'TYPE'}; + my $mobloc = $self->{-mob}->{'LOCATION'}; + my $god = $self->{-mob}->{'ADORING'}; + + # only priests can build temples + return 0 unless $self->test(sub{$self->{-mob}->{'TYPE'} eq 'PRIEST'}, + 'MSG_WRONG_TYPE', + $self->{-context}->mobile_string($mobtype,1), + $mobloc); + + # is this a valid building place? + # my($loc,$terrain,$temple) = $self->{-context}->read_map('TERRAIN,TEMPLE'); + my ($terrain,$temple) = + $self->{-context}->read_field('TERRAIN,TEMPLE',$mobloc); + return 0 unless $self->test(sub{$temple ne 'Y' + and Util::is_in($terrain,'MOUNTAIN','ISLE')}, + 'MSG_CANT_BUILD_HERE', + $mobloc); + + # is the priest adoring a fitting god? + #return 0 unless $self->test(sub{($terrain eq 'MOUNTAIN' and + # $self->{-mob}->{'ADORING'} eq $god) or + # $terrain eq 'ISLE'}, + # 'MSG_ADORING_WRONG_GOD', + # $mobloc, + # $self->{-mob}->{'ADORING'}, + # $self->{-context}->charname($god)); + + # is there allready a BUILD_TEMPLE Command + if($self->{-phase} == 1){ + return 0 unless $self->test(sub{! $self->{-context}->search_event('BUILD_TEMPLE', + $mobloc)}, + 'MSG_CANT_BUILD_HERE', + $mobloc); + } + + # dont build more than MAX_MOUNTAIN temples on mountains + if($terrain eq 'MOUNTAIN'){ + my $ret = $self->test(sub{$self->{-db}->count('MAP', + "GAME=$self->{-game} AND ". + "TEMPLE=Y AND ". + "HOME=$god AND ". + "OCCUPANT=$self->{-player} AND ". + "TERRAIN=MOUNTAIN") + < $::conf->{-MAX_MOUNTAINS}}, + 'MSG_CANT_BUILD_HERE', + $mobloc); + if(not $ret and $self->{-phase} == 2){ + # we have to set priest active, if we tryed to build in first phase + $self->{-db}->update_hash('MOBILE', + "ID=$self->{-mob}->{'ID'}", + {'AVAILABLE' => 'Y'}); + } + return 0 unless $ret; + } + + return 1; +} + +# this is called from Scheduler, if he sees the command the +# first time, some commands execute here immidiatly. +# BUILD_TEMPLE +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + $self->conditional_split_mobile($self->{-mob}, + 1, + {'COMMAND_ID' => $self->{-dbhash}->{'ID'}, + 'MOVE_WITH' => 0}, + 0); + + # delete all MOVE_WITH the priest + # BUG?: uninitialized value in this line??? maybe split is wrong in a way? + $self->{-db}->update_hash('MOBILE', + "MOVE_WITH = $self->{-mob}->{'ID'}", + {'MOVE_WITH' => 0}); + + $self->empty_field($self->{-mob}->{'LOCATION'}); + + my ($size) = $self->{-db}->read_game($self->{-game},'TEMPLE_SIZE'); + + # set new temple size + $size++; + $self->{-db}->update_hash('GAME', + "GAME=$self->{-game}", + {'TEMPLE_SIZE' => $size}); + Util::log("New temple size: $size",1); + + # calculate duration + $self->setDuration($size * $::conf->{-DURATION}->{-BUILD_TEMPLE}); + + $self->event($self->{-mob}->{'LOCATION'}, + 'EVENT_BUILD_TEMPLE', + $self->{-context}->charname($self->{-mob}->{'ADORING'}), + $size); + + return $self->{-duration}; +} + +# this is called from scheduler when the command will be executed. +# BUILD_TEMPLE +sub second_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + my $loc = $self->{-mob}->{'LOCATION'}; + $self->{-db}->update_hash('MAP', + "GAME=$self->{-game} AND LOCATION=$loc", + {'TEMPLE' => 'Y', + 'HOME' => $self->{-mob}->{'ADORING'}}); + + $self->{-db}->update_hash('MOBILE', + "ID=$self->{-mob}->{'ID'}", + {'AVAILABLE' => 'Y'}); + + # insert new PRODUCE-command + $self->{-context}->insert_command('PRODUCE', "ROLE=$self->{-player}", + $self->{-mob}->{'LOCATION'}); + + # insert new PRAY-command + $self->{-context}->insert_command('PRAY','',$loc); + + # this deletes and reinsert commands, if we conquer with building + $self->enter_field($loc,1); + + #change aymargeddon to nearest pole + my $poles = $self->{-db}->select_array('MAP', + 'LOCATION,TERRAIN', + "GAME=$self->{-game} AND ". + "(TERRAIN=POLE OR TERRAIN=AYMARGEDDON)"); + my $min_distance = $::conf->{-MANY}; + my $Loc = Location->from_string($loc); + my ($new_aym,$old_aym) = ('',''); + for my $pol (@$poles){ + my ($loc2,$ter) = @$pol; + $old_aym = $loc2 if $ter eq 'AYMARGEDDON'; + my $map = HexTorus->new($self->{-context}->get_size()); + my $Loc2 = Location->from_string($loc2); + my $dist = $map->distance($Loc,$Loc2); + Util::log("distance from $loc to $loc2: $dist",1); + $new_aym = $loc2 if $dist < $min_distance and $ter eq 'POLE'; + } + if($new_aym){ + Util::log("change aymargeddon from $old_aym to $new_aym",1); + $self->{-db}->update_hash('MAP', + "GAME=$self->{-game} AND LOCATION=$new_aym", + {'TERRAIN' => 'AYMARGEDDON'}); + $self->{-db}->update_hash('MAP', + "GAME=$self->{-game} AND LOCATION=$old_aym", + {'TERRAIN' => 'POLE'}); + $self->{-context} + ->send_message_to_all + ({'MFROM' => 0, + 'MSG_TAG' => 'MSG_CHANGE_AYMARGEDDON', + 'ARG1' => $self->{-context}->charname($self->{-player})}); + #'ARG2' => $old_aym, + #'ARG3' => $new_aym}); + } + + # is this the end of the game? + my $unbuild = $self->{-context}->unbuild(); + + $self->end_of_the_game() unless $unbuild; + + return 0; +} + +# +# End of BUILD_TEMPLE +# +#################################################### + +########################################################## +# +# PRODUCE +# + +package PRODUCE; +use Data::Dumper; +@PRODUCE::ISA = qw(AymCommand); + +sub is_valid { + my $self = shift; + + my @required_arguments = ('ROLE'); + # TODO: Open question: is this redundant information? allready + # in PLAYER of COMMAND? + return 0 unless $self->Command::is_valid(@required_arguments); + + return 1; +} + +# PRODUCE +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + my ($ter,$home,$occ,$temple) = + $self->{-context}->read_field('TERRAIN,HOME,OCCUPANT,TEMPLE', + $self->{-dbhash}->{'LOCATION'}); + + my ($type, $duration); + $type = $temple eq 'Y' ? 'PRIEST' : 'WARRIOR'; + + my $d = $::conf->{-DURATION}; + my $peace = $self->{-args}->{'PEACE'}; + $peace = 0 unless defined $peace; + if($type eq 'PRIEST'){ + Util::log("Produce a priest at ",-1); + if ($ter eq 'MOUNTAIN'){ + Util::log("mountain.",1); + $duration = $d->{-PRODUCE_PRIEST_HOME}; + }else{ + Util::log("isle.",1); + $duration = $d->{-PRODUCE_PRIEST}; + } + $self->setDuration($duration); + $self->event($self->{-location}, + 'EVENT_PRODUCE_PRIEST'); + }else{ + Util::log("Produce a warrior at ",-1); + if ($occ == $home){ + Util::log("homecity.",1); + $duration = $d->{-PRODUCE_WARRIOR_HOME}; + }else{ + Util::log("normal city.",1); + $duration = $d->{-PRODUCE_WARRIOR} + $d->{-PRODUCE_WARRIOR_CHANGE} * $peace; + } + $self->setDuration($duration); + $self->event($self->{-location}, + 'EVENT_PRODUCE_WARRIOR'); + } + + return $duration; +} + +# this is called from scheduler when the command will be executed. +# PRODUCE +sub second_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + my $loc = $self->{-dbhash}->{'LOCATION'}; + my ($temple,$home,$occ,$plague) = + $self->{-context}->read_field('TEMPLE,HOME,OCCUPANT,PLAGUE',$loc); + my $type = $temple eq 'Y' ? 'PRIEST' : 'WARRIOR'; + + # fields with influenza do not produce + if(not defined $plague or not $plague =~ 'INFLUENZA'){ + + # dont produce priests at temples, if no other priests are there + if ($type eq 'PRIEST'){ + my $mobiles = $self->{-context} + ->read_mobile_condition('ID', + "TYPE=PRIEST AND AVAILABLE=Y AND ADORING=$home",$loc); + if(!@$mobiles){ + Util::log("No priests, no new priests!",1); + $self->do_it_again(); + return 0; + } + } + + my $mob = {'ID' => $self->{-db}->find_first_free('MOBILE','ID'), + 'TYPE' => $type, + 'LOCATION' => $loc, + 'COUNT' => 1, + 'AVAILABLE' => 'Y', + 'OWNER' => $self->{-args}->{'ROLE'}, + 'GAME' => $self->{-game}, + 'MOVE_WITH' => 0, + }; + + # print Dumper $mob; + + $mob->{'ADORING'} = $home if $type eq 'PRIEST'; + + my %mobcopy = (%$mob); + $self->{-mob} = \%mobcopy; + $self->{-db}->insert_hash('MOBILE', + $mob); + + $self->enter_field($loc,1); + } # endif no influenza + else{ + Util::log("No production in $loc due to INFLUENZA!",1); + } + + # re-insert command + my $new_peace = $self->{-args}->{'PEACE'}; + $new_peace = 0 unless defined $new_peace; + $new_peace++; + $self->do_it_again({'PEACE' => $new_peace}); + + return 1; +} + +# +# End of PRODUCE +# +#################################################### + +########################################################## +# +# PRAY +# + +package PRAY; +use Data::Dumper; +@PRAY::ISA = qw(AymCommand); + +sub is_valid { + my $self = shift; + + my @required_arguments = (); + return 0 unless $self->Command::is_valid(@required_arguments); + + $self->{-loc} = $self->{-dbhash}->{'LOCATION'}; + my ($temple,$home) = $self->{-context}->read_field('TEMPLE,HOME', + $self->{-loc}); + # TODO: use test() instead + return 0 unless $temple eq 'Y'; + + $self->{-god} = $home; + + return 1; +} + +# PRAY +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + return $self->{-duration}; +} + +# PRAY +sub second_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + # count number of active orthodox priests + my $priests = 0; + my $oim = $self->{-context}->own_in_mobile($self->{-loc}, + $self->{-god}, + 'available'); + + for my $om (@$oim){ + my ($id) = @$om; + my $mob = $self->{-db}->read_single_mobile($id); + $priests += $mob->{'COUNT'} if($mob->{'TYPE'} eq 'PRIEST'); + } + + # reduce effective priests if necessary + my $fortune = $self->{-context}->read_fortune(); + my $oldpriests = $priests; + + my ($terrain) = $self->{-context}->read_field('TERRAIN',$self->{-loc}); + if($terrain eq 'MOUNTAIN'){ + if($priests > $::conf->{-FORTUNE_FAKTOR_MOUNTAIN} * $fortune){ + $priests = $::conf->{-FORTUNE_FAKTOR_MOUNTAIN} * $fortune; + } + }elsif($terrain eq 'ISLE'){ + if($priests > $::conf->{-FORTUNE_FAKTOR_ISLAND} * $fortune){ + $priests = $::conf->{-FORTUNE_FAKTOR_ISLAND} * $fortune; + } + }else{ + Util::log("ERROR: PRAY in terrain $terrain",0); + } + + Util::log("reduce praying priests from $oldpriests to". + " $priests in $self->{-loc} ($terrain, fortune: $fortune)",1) + if $oldpriests > $priests; + + # add priests + 1 mana to $self->{-god} + my $mana = $self->{-context}->get_mana($self->{-god}); + my $newmana = $mana + $priests + $::conf->{-MANA_FOR_TEMPLE}; + + $self->{-db}->update_hash('GOD', + "PLAYER=$self->{-god} AND GAME=$self->{-game}", + {'MANA' => $newmana}); + Util::log("$priests priests pray for $self->{-god} ". + "in $self->{-loc} and he got ". ($newmana - $mana) ." mana",1); + + # TODO: Message? + + # re-insert command + $self->do_it_again(); + + return 1; +} + +# +# End of PRAY +# +#################################################### + +########################################################## +# +# BUILD_ARK +# + +package BUILD_ARK; +use Data::Dumper; +@BUILD_ARK::ISA = qw(AymCommand); + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + # my @required_arguments = (''); + return 0 unless $self->Command::is_valid(); + + return 0 unless $self->validate_role('GOD'); + + return 1; +} + +# this is called from Scheduler, if he sees the command the +# first time, some commands execute here immidiatly. +# BUILD_ARK +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + return 0 unless $self->test_mana('BUILD_ARK'); + + # calculate duration + $self->setDuration($::conf->{-DURATION}->{-BUILD_ARK}); + + $self->event($self->{-location}, + 'EVENT_BUILD_ARK'); + + $self->use_mana(); + + return $self->{-duration}; +} + +# this is called from scheduler when the command will be executed. +# BUILD_ARK +sub second_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + # owner should be occupant + my ($occ) = $self->{-context}->read_field('OCCUPANT',$self->{-location}); + $occ = -1 unless $occ; + + my $mob = {'ID' => $self->{-db}->find_first_free('MOBILE','ID'), + 'TYPE' => 'ARK', + 'LOCATION' => $self->{-location}, + 'COUNT' => 1, + 'AVAILABLE' => 'Y', + 'OWNER' => $occ, + 'GAME' => $self->{-game}, + }; + my %mobcopy = (%$mob); + $self->{-db}->insert_hash('MOBILE',$mob); + + # merge multiple ARKs in one mobile, if same owner + $self->unify_mobiles(\%mobcopy,$self->{-location},$occ); + + # $self->{-db}->commit(); + +# $self->{-context} +# ->send_message_to_field +# ($self->{-location}, +# {'MFROM' => 0, +# 'MSG_TAG' => 'MSG_BUILD_ARK', +# 'ARG1' => $self->{-context}->charname($self->{-player}), +# 'ARG2' => $self->{-location}}); + + return 0; +} + +# +# End of BUILD_ARK +# +#################################################### + +#################################################### +# +# INCARNATE: Create an Avatar +# + +package INCARNATE; +@INCARNATE::ISA = qw(AymCommand); + +sub is_valid{ + my ($self) = @_; + + my @required_arguments = ('COUNT'); + return 0 unless $self->Command::is_valid(@required_arguments); + + # you need a temple to create an avatar + $self->{-arrival} = $self->{-context}->incarnation_place(); + return 0 unless $self->test(sub{$self->{-arrival};}, + 'MSG_ERROR_NO_ARRIVAL'); + + # TODO: maybe with variing cost (distance to Aymargeddon) + return 0 unless $self->test_mana('INCARNATE', $self->{-args}->{'COUNT'}); + + return 1; +} + +# INCARNATE +sub first_phase{ + my $self = shift; + return 0 unless $self->is_valid(); + + # create mobile (or join) + my $mob = {'ID' => $self->{-db}->find_first_free('MOBILE','ID'), + 'GAME' => $self->{-game}, + 'LOCATION' => $self->{-location}, + 'TYPE' => 'AVATAR', + 'OWNER' => $self->{-player}, + 'COUNT' => $self->{-args}->{'COUNT'}, + 'AVAILABLE' => 'Y', + 'STATUS' => 'IGNORE', + 'COMMAND_ID' => $self->{-id}, + }; + $self->{-mob} = $mob; + my %mobcopy = (%$mob); + $self->{-db}->insert_hash('MOBILE',\%mobcopy); + + $self->enter_field_avatar($self->{-location},$mob); + $self->unify_mobiles($mob,$self->{-location}); + + $self->use_mana(); + + # TODO: count count +# $self->{-context} +# ->send_message_to_field +# ($self->{-location}, +# {'MFROM' => 0, +# 'MSG_TAG' => 'MSG_INCARNATE', +# 'ARG1' => $self->{-context}->charname($self->{-player}), +# 'ARG2' => $self->{-location}}); + + $self->setDuration(0); + return 1; +}; + +sub second_phase{ + my $self = shift; + Util::log("Warning: We should not reach phase 2 with command INCARNATE",0); + return 0; +}; + +# +# END of INCARNATE +# +################################################################ + +########################################################## +# +# FIGHT_EARTHLING +# + +package FIGHT_EARTHLING; +use Data::Dumper; +use Date::Parse qw(str2time); +use Date::Calc qw(Time_to_Date); +@FIGHT_EARTHLING::ISA = qw(AymCommand); + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + my @required_arguments = ('ATTACKER','DEFENDER'); + return 0 unless $self->Command::is_valid(@required_arguments); + + return 0 unless $self->validate_role('EARTHLING'); + return 0 unless $self->validate_this_role($self->{-args}->{'ATTACKER'},'EARTHLING'); + my $def = $self->{-args}->{'DEFENDER'}; + if($def > 0){ + return 0 unless $self->validate_this_role($self->{-args}->{'DEFENDER'},'EARTHLING'); + } + + return 1; +} + +# this is called from Scheduler, if he sees the command the +# first time, some commands execute here immidiatly. +# FIGHT_EARTHLING +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + # calculate duration + $self->setDuration($::conf->{-DURATION}->{-FIGHT_EARTHLING}); + + $self->event($self->{-location}, + 'FIGHT_EARTHLING'); + + return $self->{-duration}; +} + +# this is called from scheduler when the command will be executed. +# FIGHT_EARTHLING +sub second_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + # read map info + my ($terrain,$home,$occupant) = $self->{-context}-> + read_field('TERRAIN,HOME,OCCUPANT',$self->{-location}); + + my $attacker = $self->{-args}->{'ATTACKER'}; + my $defender = $self->{-args}->{'DEFENDER'}; + + # get all mobiles + my $mobiles = $self->{-context}->read_mobile('ID,TYPE,OWNER,COUNT,STATUS', + 0, $self->{-location}, 1); + $self->{-mobiles} = $mobiles; + # print Dumper $mobiles; + + #my $efoa = {"$attacker" => 0}; # earthling friends of attacker + #my $efod = {"$defender" => 0}; # earthling friends of defender + #$self->{-efoa} = $efoa; + #$self->{-efod} = $efod; + + my ($gfoa, $gfod); # god friends ... + + # calculate strength of both sides + my ($attack_strength, $defend_strength,$attack_avatar,$defend_avatar) = (0,0,0,0); + my ($people_attacker, $people_defender) = (0,0); + for my $mob (@$mobiles){ + my ($id,$type,$own,$count,$stat) = @$mob; + + # next if $own <= 0; + if(exists($gfod->{$own})){ + # could be reached with differen MOVE_WITH + $defend_avatar += $count * $self->strength('AVATAR'); + $gfod->{$own} += $count; + Util::log("(1)mobile $id: $count $type from $own fights for $defender in $self->{-location}",1); + }elsif(exists($gfoa->{$own})){ + # could be reached with differen MOVE_WITH + $attack_avatar += $count * $self->strength('AVATAR'); + $gfoa->{$own} += $count; + Util::log("(2)mobile $id: $count $type from $own fights for $attacker in $self->{-location}",1); + }else{ + # TODO Performance (in the case of earthling this is not necessary) + my ($att_rel,$def_rel,$foa,$fod) = (0,0,0,0); + + # Avatars dont fight sometimes (no mana or no help or no friend) + if($type eq 'AVATAR'){ + # if(not $godfight){ + $att_rel = $self->{-context}->read_single_relation($own,$attacker); + $def_rel = $self->{-context}->read_single_relation($own,$defender); + + $foa = 1 if Util::is_in($att_rel,'FRIEND','ALLIED'); + $fod = 1 if Util::is_in($def_rel,'FRIEND','ALLIED'); + + # defender has support if in doubt + $foa = 0 if $foa and $fod; + $fod = 1 if not $foa and not $fod; + + $gfoa->{$own} += $count if $foa; + $gfod->{$own} += $count if $fod; + + # if you dont have enough mana for all your avatars no one fights! + if($stat eq 'HELP' and $self->test_mana('FIGHT_AVATAR',1,$own)){ + $self->use_mana($own); + }else{ + ($foa, $fod) = (0,0); + $gfod->{$own} = 0; + $gfoa->{$own} = 0; + } + # } + }else{ + # earthlings are simpel: no friends in field + $foa = 1 if $own == $attacker; + $fod = 1 if $own == $defender; + } + + if($foa){ + Util::log("(3)mobile $id: $count $type from $own fights for ". + "$attacker in $self->{-location}",1); + if($type eq 'AVATAR'){ + # count maximum avatarpower + $attack_avatar += $count * $self->strength('AVATAR'); + }else{ + # count earthling_strength + $attack_strength += $count * $self->strength($type); + $people_attacker += $count; + } + }elsif($fod){ # same for defender + Util::log("(4)mobile $id: $count $type from $own fights for ". + "$defender in $self->{-location}",1); + if($type eq 'AVATAR'){ + $defend_avatar += $count * $self->strength('AVATAR'); + }else{ + $defend_strength += $count * $self->strength($type); + $people_defender += $count; + } + }else{ + Util::log("(5)mobile $id: $own dont fight with $count $type ". + "in $self->{-location}",1); + } + } + } + + # terrain-bonus + if($terrain eq 'CITY'){ + # bonus for home city + if($home == $attacker){ + Util::log("homecity fights for $attacker",1); + $attack_strength += $::conf->{-FIGHT}->{-HOME}; + }elsif($home == $defender and $home){ + Util::log("homecity fights for $defender",1); + $defend_strength += $::conf->{-FIGHT}->{-HOME}; + } + }elsif($terrain eq 'ISLE'){ + # bonus for isle + if($occupant == $attacker){ + Util::log("isle fights for $attacker",1); + $attack_strength += $::conf->{-FIGHT}->{-ISLE}; + }elsif($occupant == $defender){ + Util::log("isle fights for $defender",1); + $defend_strength += $::conf->{-FIGHT}->{-ISLE}; + }else{ + Util::log("impossible situation: isle fights for no one!",0); + } + } + + Util::log("earthling strength attacker($attacker): ". + "$attack_strength, defender($defender): $defend_strength" + ,1); + + my $pure_attack_strength = $attack_strength; + my $pure_defend_strength = $defend_strength; + + #my $attacker_death_count = $attack_strength; + #my $defender_death_count = $defend_strength; + + my $attacker_death_count = $people_attacker; + my $defender_death_count = $people_defender; + + Util::log("$people_attacker people fight for attacker $attacker",1); + Util::log("$people_defender people fight for defender $defender",1); + + my $attacker_godpower = Util::min($people_attacker,$attack_avatar); + my $defender_godpower = Util::min($people_defender,$defend_avatar); + + Util::log("Gods supports attacker($attacker) with $attacker_godpower",1); + Util::log("Gods supports defender($defender) with $defender_godpower",1); + + $attack_strength += $attacker_godpower; + $defend_strength += $defender_godpower; + + # FLANKING + # if landbattle: look, for all neighbour fields, + # add flanking power of allies + my ($flanking_attack,$flanking_defend) = (0,0); + # if(not $self->{-see_battle} and not $self->{-island_battle}){ + my @neighbours = $self->get_neighbours($self->{-location}); + # COMMENT IN FOR NEW RULE my ($att_neighbours,$def_neighbours) = (0,0); + # print "neighbours: @neighbours\n"; + for my $n (@neighbours){ + # my $n_string = $n->to_string(); + my ($ter,$occ,$att) = $self->{-context}-> + read_field('TERRAIN,OCCUPANT,ATTACKER',$n); + next if $ter eq 'WATER'; # dont flank from see + next if $att > 0; # dont flank from war + my $attacker_relation = $self->{-context}->read_single_relation($occ,$attacker); + my $defender_relation = $self->{-context}->read_single_relation($occ,$defender); + Util::log("flanking ($n): $attacker_relation, $defender_relation, ". + "$ter, $occ, $att",1); + if($occ != $defender and + ($occ == $attacker or (Util::is_in($attacker_relation,'FRIEND','ALLIED') and not + Util::is_in($defender_relation,'FRIEND','ALLIED')))){ + # COMMENT IN FOR NEW RULE $att_neighbours++; + # COMMENT IN FOR NEW RULE $flanking_attack += $::conf->{-FIGHT}->{-FLANKING} * $att_neighbours; + $flanking_attack += $::conf->{-FIGHT}->{-FLANKING}; + Util::log("$n flanks for attacker($attacker)",1); + }elsif($occ and ($occ != $attacker and + ($occ == $defender or + (not Util::is_in($attacker_relation,'FRIEND','ALLIED') + and Util::is_in($defender_relation,'FRIEND','ALLIED'))))){ + # COMMENT IN FOR NEW RULE $def_neighbours++; + # COMMENT IN FOR NEW RULE $flanking_defend += $::conf->{-FIGHT}->{-FLANKING} * $def_neighbours; + $flanking_defend += $::conf->{-FIGHT}->{-FLANKING}; + Util::log("$n flanks for defender($defender)",1); + } + } + Util::log("sum of flanking: $flanking_attack for attacker($attacker) and ". + "$flanking_defend for defender($defender) and ",1); + $attack_strength += $flanking_attack; + $defend_strength += $flanking_defend; + #} + + Util::log("sum strength without fortune: $attack_strength for attacker($attacker) ". + "and $defend_strength for defender($defender)",1); + + # add random value (1 to GAME.FORTUNE) + my $fortune = $self->{-context}->read_fortune(); + my $asf = int(rand($fortune))+1; + my $dsf = int(rand($fortune))+1; + $attack_strength += $asf; + $defend_strength += $dsf; + Util::log("strength with fortune attacker($attacker): ". + "$attack_strength, defender($defender): $defend_strength",1); + + # my @loosers; + + if($attack_strength > $defend_strength){ + $self->{-winner} = $attacker; + $self->{-looser} = $defender; + $self->{-winner_death_count} = Util::min($people_attacker - 1, + int(0.5 + $defender_death_count / + $::conf->{-WINNER_DEATH_COUNT_FRACTION})); + $self->{-looser_death_count} = Util::max(1,int(0.5 + $attacker_death_count / + $::conf->{-LOOSER_DEATH_COUNT_FRACTION})); + Util::log("Attackers($attacker) won!",1); + $self->conquer($self->{-location},$attacker); + }else{ + $self->{-winner} = $defender; + $self->{-looser} = $attacker; + $self->{-winner_death_count} = Util::min($people_defender - 1, + int(0.5 + $attacker_death_count / + $::conf->{-WINNER_DEATH_COUNT_FRACTION})); + $self->{-looser_death_count} = Util::max(1,int(0.5 + $defender_death_count / + $::conf->{-LOOSER_DEATH_COUNT_FRACTION})); + # $self->{-looser} = $efoa; + # $self->{-master_looser} = $attacker; + Util::log("Defenders($defender) won!",1); + } + + # loosers and helpers run away or die + $self->run_or_die(); + + # erase MAP.ATTACKER + $self->{-db}->update_hash('MAP', + "LOCATION=$self->{-location} AND GAME=$self->{-game}", + {'ATTACKER' => 0}); + + # reread mobiles + # $self->{-mobiles} = $self->{-context}->read_mobile('ID', + # 0, $self->{-location}, 1); + + # unify the mobiles, which are still here + for my $mob_arr (@$mobiles){ + my ($id,$type,$owner,$count,$status) = @$mob_arr; + next if exists $self->{-run_or_die}->{$id}; + my $mob = $self->{-db}->read_single_mobile($id); + $self->unify_mobiles($mob,$self->{-location},$owner) if $mob; + } + + # sometimes the last ark is gone in battle + if($terrain eq 'WATER'){ + $self->drowning($self->{-location}); + } + + # send battle-report + my $name_of_attacker = $self->{-context}->charname($attacker); + my $name_of_defender = $self->{-context}->charname($defender); + my $name_of_winner = $self->{-context}->charname($self->{-winner}); + + my $text = <<END_OF_TEXT; + <strong>BATTLE_REPORT $self->{-location}</strong><br> + <table><tr><th></th><th>$name_of_attacker</th><th>$name_of_defender</th></tr> + <tr><td>PEOPLE</td><td>$people_attacker</td> + <td>$people_defender</td></tr> + <tr><td>FIGHTING_STRENGTH</td><td>$pure_attack_strength</td> + <td>$pure_defend_strength</td></tr> + <tr><td>FLANKING</td><td>$flanking_attack</td><td>$flanking_defend</td></tr> + <tr><td>GODS_HELP</td><td>$attacker_godpower</td><td>$defender_godpower</td></tr> + <tr><td>LUCK</td><td>$asf</td><td>$dsf</td></tr> + <tr><td>SUM_OF_STRENGTH</td><td>$attack_strength</td><td>$defend_strength</td></tr> + <tr><td>DEAD_WARRIORS</td><td>$self->{-dead}->{$attacker}->{'K'}</td> + <td>$self->{-dead}->{$defender}->{'K'}</td></tr> + <tr><td>DEAD_HEROS</td><td>$self->{-dead}->{$attacker}->{'H'}</td> + <td>$self->{-dead}->{$defender}->{'H'}</td></tr> + <tr><td>DEAD_PRIESTS</td><td>$self->{-dead}->{$attacker}->{'P'}</td> + <td>$self->{-dead}->{$defender}->{'P'}</td></tr> + <tr><td>SUNKEN_ARKS</td><td>$self->{-dead}->{$attacker}->{'A'}</td> + <td>$self->{-dead}->{$defender}->{'A'}</td></tr> + <tr><td>CONQUERED_ARKS</td><td>$self->{-dead}->{$defender}->{'C'}</td> + <td>$self->{-dead}->{$attacker}->{'C'}</td></tr> + </table> + <strong>WINNER_IS $name_of_winner</strong>. +END_OF_TEXT + + # TODO: we should make shure, that attacker and defender are receivers. + # could happen, if all dying and no other unit in the neighbourhood + my @gods = (keys %$gfoa, keys %$gfod); + $self->{-context} + ->send_message_to_field + ($self->{-location},{'MFROM' => 0, + 'MSG_TEXT' => $text} + # 'ARG1' => $self->{-context}->charname($attacker), + # 'ARG2' => $self->{-context}->charname($defender), + # 'ARG3' => $self->{-context}->charname($self->{-winner}), + # 'ARG4' => $self->{-location}} + ); + #,$attacker,$defender,@gods); + + return 0; +} + +# FIGHT_EARTHLING +sub run_or_die{ + my($self) = @_; + + # some people have to die + $self->casualties($self->{-winner},$self->{-winner_death_count}); + $self->casualties($self->{-looser},$self->{-looser_death_count}); + + # print Dumper $self->{-dead}; + + # reread mobiles + $self->{-mobiles} = $self->{-context}->read_mobile('ID,TYPE,OWNER,COUNT,STATUS', + 0, $self->{-location}, 1); + + # the survivors run + # TODO: no retreat if no survivors + $self->retreat(); + +} + +sub find_retreat_field{ + my ($self,$retreat_fields) = @_; + + my @retreat_fields = @$retreat_fields; + + # chose one retreat-field + return $retreat_fields[rand($#retreat_fields +1)]; +} + +sub retreat_unit{ + my ($self,$unit,$count,$retreat,$type) = @_; + + my $looser = $self->{-looser}; + + # calculate direction + my $dir = $self->{-context}->is_in_direction_from($retreat, + $self->{-location}); + + # retreat via MOVE_WITH if retreat with ark + if($type ne 'ARK' and exists $self->{-retreat_arks}->{$retreat}){ + my $ark = $self->{-retreat_arks}->{$retreat}; + $self->{-db}->update_hash('MOBILE', + "ID=$unit", + {'MOVE_WITH' => $ark, + 'AVAILABLE' => 'N'}); + Util::log("retreat via $ark (MOVE_WITH)",1); + }else{ + # TODO?: insert event + $self->{-context}->insert_command('MOVE', + "DIR=$dir, MOBILE=$unit, ". + "COUNT=$count, AUTO=1", + $self->{-location}, + $looser); + Util::log("retreat via MOVE_COMMAND",1); + } + Util::log("$looser retreats from $self->{-location} to $retreat ". + "in direction $dir with $count people(or ark). Mobile-ID: $unit",1); + $self->{-run_or_die}->{$unit} = 1; + + $self->{-context} + ->send_message_to_list + ({'MFROM' => 0, + 'MSG_TAG' => 'MSG_FIGHT_RETREAT', + 'ARG1' => $self->{-context}->charname($looser), + 'ARG2' => 'PEOPLE_OR_ARK', + 'ARG3' => $self->{-location}, + 'ARG4' => $count},$looser,$self->{-winner}); + + return $retreat; +} + +sub retreat{ + my ($self) = @_; + + my $looser = $self->{-looser}; + Util::log("checking retreats for looser $looser ...",1); + + # remove MOVE_WITH if any + $self->{-db}->update_hash('MOBILE', + "OWNER=$looser AND LOCATION=$self->{-location} AND ". + "AVAILABLE=Y", + {'MOVE_WITH' => 0}); + + # search for retreat-possibilities + my ($local_terrain) = $self->{-context}->read_field('TERRAIN',$self->{-location}); + my @possible_retreat = $self->{-context}->own_neighbours($self->{-location},$looser); + my @retreat_fields = (); + my @retreat_water_fields = (); + if ($local_terrain eq 'WATER' or $local_terrain eq 'ISLE'){ + @retreat_water_fields = @possible_retreat; + Util::log("retreat from water: @possible_retreat",1); + }else{ + Util::log("check retreat for ...",-1); + for my $field (@possible_retreat){ + Util::log("\n$field ",-1); + my ($terrain) = $self->{-context}->read_field('TERRAIN',$field); + if ($terrain eq 'WATER' or $terrain eq 'ISLE'){ + Util::log("... accepted water retreat to $terrain!",1); + push @retreat_water_fields, $field; + }else{ + Util::log("... accepted land retreat to $terrain!",1); + push @retreat_fields, $field; + } + } + } + # $self->{-retreat_fields} = \@retreat_fields; + # $self->{-retreat_water_fields} = \@retreat_fields; + + # retreat own arks + + my $have_ark = 0; + my %arks = (); + if($#retreat_water_fields >= 0){ + $self->{-retreat_arks} = {}; # TODO Performance: use only hashes, no arrays + for my $m (@{$self->{-mobiles}}){ + my ($id,$type,$own,$count,$stat) = @$m; + next unless $type eq 'ARK' and ($own == $self->{-looser}); + + my $retreat_field = $self->find_retreat_field(\@retreat_water_fields); + Util::log("found ark $id from $own for retreat to $retreat_field",1); + + $self->{-retreat_arks}->{$retreat_field} = $id; + $arks{$id} = $retreat_field; + + if (not Util::is_in($retreat_field,@retreat_fields)){ + push @retreat_fields, $retreat_field; + Util::log("... accepted retreat through ark $id to $retreat_field!",1); + } + } + }else{ + # all arks change owner to winner + $self->{-db}->update_hash('MOBILE', + "GAME=$self->{-game} AND ". + "LOCATION=$self->{-location} AND ". + "TYPE=ARK", + {'OWNER' => $self->{-winner}}); + Util::log("All arks in $self->{-location} change owner to $self->{-winner}",1); + } + + + # for every unit of this looser + for my $mob (@{$self->{-mobiles}}){ + my ($id,$type,$own,$count,$stat) = @$mob; + next unless $own == $looser; + next if $type eq 'ARK'; + + # if there is a way out + if($#retreat_fields >= 0){ + my $field = $self->find_retreat_field(\@retreat_fields); + Util::log("checking retreat for mobile $id ". + "(own: $own, type: $type, count: $count, field: $field)",1); + $self->retreat_unit($id,$count,$field,$type); + }else{ + # die! + $self->{-db}->delete_from('MOBILE',"ID=$id"); + $self->{-run_or_die}->{$id} = 1; + + $self->{-context} + ->send_message_to_field + ($self->{-location}, + {'MFROM' => 0, + 'MSG_TAG' => 'MSG_FIGHT_RETREAT_DIE', + 'ARG1' => $self->{-context}->charname($looser), + 'ARG2' => $type, + 'ARG3' => $self->{-location}, + 'ARG4' => $count});#,$looser,$self->{-winner}); + Util::log("$looser looses $count $type in $self->{-location}". + " because there is no place to retreat.",1); + } + } + # MOVE COMMANDS for arks came last because others move with them + for my $mob (@{$self->{-mobiles}}){ + my ($id,$type,$own,$count,$stat) = @$mob; + next unless $own == $looser; + next unless $type eq 'ARK'; + Util::log("checking retreat for mobile $id ". + "(own: $own, type: $type, count: $count, ". + "via ark $id to field: $arks{$id})",1); + + $self->retreat_unit($id,$count,$arks{$id},$type); + } +} + +sub strength{ + my($self,$type) = @_; + + # return $::conf->{-SEE_FIGHT}->{"-$type"} if $self->{-naval_battle}; + # return $::conf->{-ISLAND_FIGHT}->{"-$type"} if $self->{-island_battle}; + return $::conf->{-FIGHT}->{"-$type"}; +} + +# +# End of FIGHT_EARTHLING +# +#################################################### + +########################################################## +# +# BLESS_HERO +# + +package BLESS_HERO; +@BLESS_HERO::ISA = qw(AymCommand); +use Data::Dumper; + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + my @required_arguments = ('MOBILE','COUNT'); + return 0 unless $self->Command::is_valid(@required_arguments); + + return 0 unless $self->validate_mobile($self->{-args}->{'MOBILE'}); + + return 0 unless $self->validate_role('GOD'); + + my $mobtype = $self->{-mob}->{'TYPE'}; + my $mobloc = $self->{-mob}->{'LOCATION'}; + my $mobcount = $self->{-mob}->{'COUNT'}; + + return 0 unless $self->test(sub{$self->{-mob}->{'TYPE'} eq 'WARRIOR'}, + 'MSG_WRONG_TYPE', + $self->{-context}->mobile_string($mobtype,1), + $mobloc); + + $self->{-count} = $self->{-args}->{'COUNT'} > $mobcount ? + $mobcount : $self->{-args}->{'COUNT'}; + + return 0 unless $self->test_mana('BLESS_HERO',$self->{-count}); + + return 1; +} + +# this is called from Scheduler, if he see the command the +# first time, some commands execute here immidiatly. +# BLESS_HERO +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + + my $id = $self->{-mob}->{'ID'}; + $self->conditional_split_mobile($self->{-mob}, + $self->{-count}, + {'ADORING' => $self->{-player}, + 'TYPE' => 'HERO', + 'COMMAND_ID' => $self->{-dbhash}->{'ID'}}, + 'beforeafter'); + + # reread mobile, because split destroys it + $self->{-mob} = $self->{-db}->single_hash_select('MOBILE',"ID=$id"); + $self->unify_mobiles($self->{-mob}, + $self->{-mob}->{'LOCATION'}, + $self->{-mob}->{'OWNER'}); + +# $self->{-context} +# ->send_message_to_field +# ($self->{-mob}->{'LOCATION'}, +# {'MFROM' => 0, +# 'MSG_TAG' => 'MSG_BLESS_HERO', +# 'ARG1' => $self->{-context}->charname($self->{-player}), +# 'ARG2' => $self->{-context}->charname($self->{-mob}->{'OWNER'}), +# 'ARG3' => $self->{-mob}->{'LOCATION'}}); + + $self->use_mana(); + $self->setDuration(0); + + return 0; +} + +# this is called from scheduler when the command will be executed +sub second_phase{ + my $self = shift; + Util::log("BLESS_HERO should not have a second phase!",0); + return 0; +} + +# +# End of BLESS_HERO +# +#################################################### + +########################################################## +# +# CH_ACTION +# + +package CH_ACTION; +@CH_ACTION::ISA = qw(AymCommand); +use Data::Dumper; + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + my @required_arguments = ('ACTION','MOBILE'); + return 0 unless $self->Command::is_valid(@required_arguments); + + return 0 unless $self->validate_mobile($self->{-args}->{'MOBILE'}); + + return 0 unless $self->validate_role('GOD'); + + my $mobtype = $self->{-mob}->{'TYPE'}; + my $mobloc = $self->{-mob}->{'LOCATION'}; + + return 0 unless $self->test(sub{$mobtype eq 'AVATAR'}, + 'MSG_WRONG_TYPE', + $self->{-context}->mobile_string($mobtype,1), + $mobloc); + + return 1; +} + +# this is called from Scheduler, if he see the command the +# first time, some commands execute here immidiatly. +# CH_ACTION +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + my $mob = $self->{-mob}; + my $loc = $mob->{'LOCATION'}; + my $own = $self->{-player}; + my $action = $self->{-args}->{'ACTION'}; + + # all avatars in the field get the new status + $self->{-db}->update_hash('MOBILE', + "LOCATION=$loc AND TYPE=AVATAR AND OWNER=$own ". + "AND GAME=$self->{-game} AND AVAILABLE=Y", + {'STATUS' => $action}); + + $mob->{'STATUS'} = $action; + $self->enter_field_avatar($loc,$mob) if $action eq 'BLOCK'; + +# $self->{-context} +# ->send_message_to_field +# ($self->{-mob}->{'LOCATION'}, +# {'MFROM' => 0, +# 'MSG_TAG' => 'MSG_CH_ACTION', +# 'ARG1' => $self->{-args}->{'ACTION'}, +# 'ARG2' => $self->{-mob}->{'LOCATION'}}); + + $self->setDuration(0); + return 0; +} + +# this is called from scheduler when the command will be executed +sub second_phase{ + my $self = shift; + Util::log("CH_ACTION should not have a second phase!",0); + return 0; +} + +# +# End of CH_ACTION +# +#################################################### + +#################################################### +# +# DIE_ORDER: Change the order of mobiletypes which dies in battle +# + +package DIE_ORDER; +@DIE_ORDER::ISA = qw(AymCommand); + +sub is_valid{ + my ($self) = @_; + + my @required_arguments = ('DYING'); + return 0 unless $self->Command::is_valid(@required_arguments); + + return 0 unless $self->validate_role('EARTHLING'); + + # TODO: use test with message + return 0 unless Util::is_in($self->{-args}->{'DYING'}, + 'PKH','PHK','KPH','KHP','HKP','HPK'); + + return 1; +} + +# DIE_ORDER +sub first_phase{ + my $self = shift; + return 0 unless $self->is_valid(); + + my $dying = $self->{-args}->{'DYING'}; + + $self->{-db}->update_hash('EARTHLING', + "GAME=$self->{-game} AND ". + "PLAYER=$self->{-player}", + {'DYING' => $dying}); + + $self->{-context}->send_message_to_me({'MFROM' => 0, + 'MSG_TAG' => 'MSG_DIE_ORDER', + 'ARG1' => $dying + }); + Util::log("New die order for player $self->{-player}: $dying",1); + + $self->setDuration(0); + return 1; +}; + +sub second_phase{ + my $self = shift; + Util::log("Warning: We should not reach phase 2 with command DIE_ORDER",0); + return 0; +}; + +# +# END of DIE_ORDER +# +################################################################ + + +########################################################## +# +# CH_LUCK +# + +package CH_LUCK; +@CH_LUCK::ISA = qw(AymCommand); +use Data::Dumper; + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + my @required_arguments = ('BONUS'); + return 0 unless $self->Command::is_valid(@required_arguments); + + return 0 unless $self->validate_role('GOD'); + + return 1 if $self->{-phase} == 2; + + return 0 unless $self->test_mana('CH_LUCK', + abs($self->{-args}->{'BONUS'} * $::conf->{-MANA}->{-CH_LUCK})); + + return 1; +} + +# this is called from Scheduler, if he see the command the +# first time, some commands execute here immidiatly. +# CH_LUCK +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + $self->use_mana(); + + return $self->setDuration($::conf->{-DURATION}->{-CH_LUCK}); +} + +# this is called from scheduler when the command will be executed +sub second_phase{ + my $self = shift; + return 0 unless $self->is_valid(); + my $oldfortune = $self->{-context}->read_fortune(); + + my $change = $self->{-args}->{'BONUS'}; + + my $newfortune = $oldfortune + $change; + if($newfortune > $::conf->{-MAX_LUCK}){ + $newfortune = $::conf->{-MAX_LUCK}; + }elsif($newfortune < $::conf->{-MIN_LUCK}){ + $newfortune = $::conf->{-MIN_LUCK}; + } + + $self->{-db}->update_hash('GAME', + "GAME=$self->{-game}", + {'FORTUNE' => $newfortune}); + + $self->{-context} + ->send_message_to_all + ({'MFROM' => 0, + 'MSG_TAG' => 'MSG_CHANGE_FORTUNE', + 'ARG1' => $self->{-context}->charname($self->{-player}), + 'ARG2' => $oldfortune, + 'ARG3' => $newfortune}); + + + return 0; +} + +# +# End of CH_LUCK +# +#################################################### + +########################################################## +# +# FLOOD +# + +package FLOOD; +@FLOOD::ISA = qw(AymCommand); +use Data::Dumper; + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + my $db = $self->{-db}; + my $context = $self->{-context}; + my $loc = $self->{-location}; + + my @required_arguments = (); + return 0 unless $self->Command::is_valid(@required_arguments); + + return 0 unless $self->validate_role('GOD'); + + # only PLAIN and MOUNTAIN can be flooded + my ($terrain) = $context->read_field('TERRAIN', $loc); + return 0 unless $self->test(sub{Util::is_in($terrain,'PLAIN','MOUNTAIN');}, + 'MSG_CANT_FLOOD_TERRAIN', + $loc, + $terrain); + $self->{-terrain} = $terrain; + + return 1; +} + +# this is called from Scheduler, if he see the command the +# first time, some commands execute here immidiatly. +# FLOOD +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + my $loc = $self->{-location}; + + # need own avatar to flood + return 0 unless $self->avatar_available($loc); + return 0 unless $self->test_mana('FLOOD'); + $self->use_mana(); + + $self->setDuration($::conf->{-DURATION}->{-FLOOD}); + + $self->event($self->{-location}, + 'EVENT_FLOOD', + $self->{-player}); + + return $self->{-duration}; +} + +# this is called from scheduler when the command will be executed. +# FLOOD +sub second_phase{ + my $self = shift; + my $loc = $self->{-location}; + my $db = $self->{-db}; + + return 0 unless $self->is_valid(); + + # mountain -> isle, plain -> water + my $new = $self->{-terrain} eq 'MOUNTAIN' ? 'ISLE' : 'WATER'; + $db->update_hash('MAP',"LOCATION=$loc AND GAME=$self->{-game}", + {'TERRAIN' => $new}); + + # drowning of mobiles if necessary + $self->drowning($loc); + + # Message + $self->{-context} + ->send_message_to_field + ($loc,{'MFROM' => 0, + 'MSG_TAG' => 'MSG_FLOOD', + 'ARG1' => $self->{-context}->charname($self->{-player}), + 'ARG2' => $loc, + 'ARG3' => $self->{-terrain}, + 'ARG4' => $new,}); + + return 0; +} + +# +# End of FLOOD +# +#################################################### + +########################################################## +# +# DESTROY +# + +package DESTROY; +@DESTROY::ISA = qw(AymCommand); +use Data::Dumper; + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + my $db = $self->{-db}; + my $context = $self->{-context}; + my $loc = $self->{-location}; + + my @required_arguments = (); + return 0 unless $self->Command::is_valid(@required_arguments); + + return 0 unless $self->validate_role('GOD'); + + return 0 unless $self->test_mana('DESTROY'); + + # we cant destroy if there is only one temple unbuild + # TODO: wrong. should be cant destroy, if last temple is under construction + my $unbuild = $db->count('MAP', + "(TERRAIN=ISLE OR TERRAIN=MOUNTAIN) ". + "AND TEMPLE=N AND GAME=$self->{-game}"); + return 0 unless $self->test(sub{$unbuild > $::conf->{-MAX_UNBUILD_DESTROY}}, + 'MSG_CANT_RESCUE_WORLD', + $unbuild, + $loc); + + # need own avatar to destroy + return 0 unless $self->avatar_available($loc); + + # there sould be no foreign priests + my $foreign_priests = $db->count('MOBILE', + "GAME=$self->{-game} AND ". + "LOCATION=$loc AND TYPE=PRIEST AND ". + "ADORING!=$self->{-player} AND ". + "AVAILABLE=Y"); + return 0 unless $self->test(sub{$foreign_priests == 0}, + 'MSG_CANT_DESTROY_DEFENDED', + $loc); + + my ($terrain,$temple,$home) = $context->read_field('TERRAIN,TEMPLE,HOME', + $loc); + + # only if temple exists + return 0 unless $self->test(sub{$temple eq 'Y'}, + 'MSG_NO_TEMPLE_TO_DESTROY', + $loc); + + # only destroy foreign temples + return 0 unless $self->test(sub{$home != $self->{-player}}, + 'MSG_CANT_DESTROY_OWN', + $loc); + $self->{-oldgod} = $home; + + # only on islands + return 0 unless $self->test(sub{$terrain eq 'ISLE'}, + 'MSG_CANT_DESTROY_MOUNTAINS', + $loc); + + return 1; +} + +# this is called from Scheduler, if he see the command the +# first time, some commands execute here immidiatly. +# DESTROY +sub first_phase{ + my $self = shift; + my $loc = $self->{-location}; + + return 0 unless $self->is_valid(); + + $self->use_mana(); + + $self->{-db}->update_hash('MAP', + "LOCATION=$loc AND GAME=$self->{-game}", + {'TEMPLE' => 'N', + 'HOME' => 0}); + + # delete PRAY- and PRODUCE-commands and PRODUCE-PRIEST event + $self->{-db}->delete_from('COMMAND', + "(COMMAND=PRODUCE OR COMMAND=PRAY) ". + "AND LOCATION=$loc AND GAME=$self->{-game}"); + $self->{-db}->delete_from('EVENT', + "TAG=EVENT_PRODUCE_PRIEST ". + "AND LOCATION=$loc AND GAME=$self->{-game}"); + + $self->{-context} + ->send_message_to_field + ($loc, + {'MFROM' => 0, + 'MSG_TAG' => 'MSG_TEMPLE_DESTROYD', + 'ARG1' => $loc, + 'ARG2' => $self->{-context}->charname($self->{-oldgod}), + 'ARG3' => $self->{-context}->charname($self->{-player}) + }); + + Util::log("Temple of $self->{-oldgod} destroyed in $self->{-location}",1); + + $self->setDuration(0); + + return 0; +} + +# this is called from scheduler when the command will be executed +sub second_phase{ + my $self = shift; + Util::log("DESTROY should not have a second phase!",0); + return 0; +} + +# +# End of DESTROY +# +#################################################### + +########################################################## +# +# MOVE_WITH +# + +package MOVE_WITH; +@MOVE_WITH::ISA = qw(AymCommand); +use Data::Dumper; + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + my @required_arguments = ('MOBILE','COUNT','TARGET'); + return 0 unless $self->Command::is_valid(@required_arguments); + + my $args = $self->{-args}; + my $count = $args->{'COUNT'}; + + # TODO: more messages + # read mobile + return 0 unless $self->validate_mobile($args->{'MOBILE'}); + my $mob = $self->{-mob}; + + # arks cant move with other units + return 0 if $self->{-mob}->{'TYPE'} eq 'ARK'; + + return 0 unless $self->test(sub {$count <= $mob->{'COUNT'} and + $mob->{'AVAILABLE'} eq 'Y'}, + 'MSG_NOT_ENOUGH_MOBILES', + 'MOVE', + $count, + $mob->{'LOCATION'}); + + return 1; +} + +# this is called from Scheduler, if he see the command the +# first time, some commands execute here immidiatly. +# MOVE_WITH +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + my $args = $self->{-args}; + + $self->move_with($args->{'MOBILE'},$args->{'TARGET'},$args->{'COUNT'}); + + return 0; +} + +# this is called from scheduler when the command will be executed +sub second_phase{ + my $self = shift; + Util::log("MOVE_WITH should not have a second phase!",0); + return 0; +} + +# +# End of MOVE_WITH +# +#################################################### + +########################################################## +# +# SEND_MSG +# + +# TODO: should be in FROGS/Command.pm + +package SEND_MSG; +@SEND_MSG::ISA = qw(AymCommand); +use Data::Dumper; + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + my @required_arguments = ('OTHER','MESSAGE'); + return 0 unless $self->Command::is_valid(@required_arguments); + + return 1; +} + +# this is called from Scheduler, if he see the command the +# first time, some commands execute here immidiatly. +# MOVE_WITH +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + my $args = $self->{-args}; + + Util::log("send message from $self->{-player} to $args->{'OTHER'}.",1); + + my $msg = $args->{'MESSAGE'}; + + # uggly workaround necessary for Command::parse_args() + $msg =~ s/__COMMA__/,/g; + $msg =~ s/__EQUAL__/=/g; + # newline should be in html + $msg =~ s/\\r\\n/<br>/g; + + $self->{-context}->send_message_to($args->{'OTHER'}, + {'MFROM' => $self->{-player}, + 'MSG_TEXT' => $msg}); + + return 0; +} + +# this is called from scheduler when the command will be executed +sub second_phase{ + my $self = shift; + Util::log("SEND_MSG should not have a second phase!",0); + return 0; +} + +# +# End of SEND_MSG +# +#################################################### + +########################################################## +# +# FIGHT_GOD +# + +package FIGHT_GOD; +use Data::Dumper; +@FIGHT_GOD::ISA = qw(AymCommand); + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + my @required_arguments = ('A','B'); + return 0 unless $self->Command::is_valid(@required_arguments); + + my $A = $self->{-args}->{'A'}; + my $B = $self->{-args}->{'B'}; + my $loc = $self->{-dbhash}->{'LOCATION'}; + + # dont accept a new FIGHT_GOD if there is allready a fight between the same gods + my $fights = $self->{-db}->select_array('COMMAND','ARGUMENTS', + "GAME=$self->{-game} AND ". + "COMMAND=FIGHT_GOD AND ". + "ID != $self->{-dbhash}->{'ID'} AND ". + "LOCATION=$loc"); + for my $f (@$fights){ + my $args = $self->parse_args($f->[0]); + + if( $args->{'A'} == $A and $args->{'B'} == $B){ + Util::log("there is allready such a fight between $A and $B in $loc.",1); + return 0; + } + } + + # could not work, command can be inserted from earthling. + # return 0 unless $self->validate_role('GOD'); + + # return 0 unless $self->validate_this_role($self->{-args}->{'A'},'GOD'); + # return 0 unless $self->validate_this_role($self->{-args}->{'B'},'GOD'); + + return 1; +} + +# this is called from Scheduler, if he sees the command the +# first time, some commands execute here immidiatly. +# FIGHT_GOD +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + # calculate duration + $self->setDuration($::conf->{-DURATION}->{-FIGHT_GOD}); + + # set GOD_ATTACKER in MAP to COMMAND.ID + $self->{-db}->update_hash('MAP', + "LOCATION=$self->{-location} AND ". + "GAME=$self->{-game}", + {'GOD_ATTACKER' => $self->{-dbhash}->{'ID'}}); + + $self->event($self->{-location}, + 'EVENT_FIGHT_GOD', + $self->{-context}->charname($self->{-args}->{'A'}), + $self->{-context}->charname($self->{-args}->{'B'}), + ); + + return $self->{-duration}; +} + +# this is called from scheduler when the command will be executed. +# FIGHT_GOD +sub second_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + # read info from map + my ($earthlingfight,$earthling); + ($earthlingfight, $self->{-god_attacker}, $earthling) = + $self->{-context}->read_field( + 'ATTACKER,GOD_ATTACKER,OCCUPANT', $self->{-location} + ); + + # suspend FIGHT until end of FIGHT_GOD if any + # REWRITE: suspend of avatar fight have to be encapsulated + if($earthlingfight){ + ## REWRITE: SQL: sort events up to time, limit output to ONE + # read all earthling-events for this field. + my @events = @{$self->{-db}->select_array('EVENT','ID,TIME', + "GAME=$self->{-game} AND ". + "LOCATION=$self->{-location} AND ". + "TAG=FIGHT_EARTHLING")}; + # which one is the latest? + my ($late_time, $late_id) = (0,0); + for my $ev (@events){ + my ($id, $time) = @$ev; + my $ev_time = &::str2time($time,'GMT'); + Util::log("found FIGHT_EARTHLING with time $time",1); + ($late_time, $late_id) = ($ev_time, $id) if $ev_time > $late_time; + } + + # insert new godfight with one second more. + # TODO: use here the new AFTER-System instead + my ($year,$month,$day, $hour,$min,$sec) = &::Time_to_Date($late_time + 1); + $late_time = sprintf ("%04u-%02u-%02u %02u:%02u:%02u", + $year,$month,$day, $hour,$min,$sec); + Util::log("found earthling fight! suspend godfight until $late_time",1); + $self->{-context}->insert_command('FIGHT_GOD', + "A=$self->{-args}->{'A'}, ". + "B=$self->{-args}->{'B'}", + $self->{-location}, + $self->{-player}, + $late_time); + $self->{-db}->update_hash('EVENT', + "COMMAND_ID=$self->{-dbhash}->{'ID'}", + {'TIME' => $late_time}); + $self->stop_fight(); + return 0; + } + + # get all mobiles here + my $mobiles = $self->{-context}->read_mobile_condition( + 'ID,OWNER,COUNT,TYPE', + "LOCATION=$self->{-location} "."AND AVAILABLE=Y" + ); + $self->{-mobiles} = $mobiles; + + my $A = $self->{-args}->{'A'}; + my $B = $self->{-args}->{'B'}; + my ($avatars_A, $avatars_B) = (0,0); + + # for every avatar-unit in the field + # REWRITE: this block tries to count the opposing avatars: simplify! + for my $a (@$mobiles){ + my ($id,$own,$count,$type) = @$a; + next unless $type eq 'AVATAR'; + + Util::log("found $count avatar(s) from $own with id $id",1); + + # determine side of owner + my $side = $self->which_side($own); + + # calculate strength_of_side + if($side eq 'A'){ + $avatars_A += $count; + }elsif($side eq 'B'){ + $avatars_B += $count; + } + } + + my $mana = $::conf->{-MANA}->{-FIGHT_AVATAR}; + my $mana_A = $self->instant_use_mana($mana,$A); + my $mana_B = $self->instant_use_mana($mana,$B); + my $strength_A = $avatars_A * $::conf->{-FIGHT}->{-AVATAR}; + my $strength_B = $avatars_B * $::conf->{-FIGHT}->{-AVATAR}; + + # TODO?: message in this case + unless($mana_A >= $mana){ + Util::log("$A has not enough mana left to fight",1); + $strength_A = 0; + }; + unless($mana_B >= $mana){ + Util::log("$B has not enough mana left to fight",1); + $strength_B = 0; + }; + + # swl: Strength_Without_Luck strenght_X: Strenght_with_luck + my ($swlA,$swlB) = ($strength_A,$strength_B); + + # add random value (1 to GAME.FORTUNE) + my $fortune = $self->{-context}->read_fortune(); + Util::log("avatarfight in $self->{-location}: strength without fortune player $A: ". + "$strength_A, player $B: $strength_B",1); + $strength_A += int(rand($fortune))+1; + $strength_B += int(rand($fortune))+1; + Util::log("strength with fortune player $A: ". + "$strength_A, player $B: $strength_B",1); + + # how much avatars should die? + my ($dead_A,$dead_B) = (0,0); + my ($winner,$looser) = (0,0); + + if( ($strength_A > $strength_B && $mana_A) or + $mana_A && !$mana_B ) + { + Util::log("$A wins!",1); + $winner = $A; $looser = $B; + ($dead_A, $dead_B) = _calc_dead_avatars($avatars_A, $avatars_B); + } + elsif( ($strength_B > $strength_A && $mana_B) or + $mana_B && !$mana_A ) + { + Util::log("$B wins!",1); + $winner = $B; $looser = $A; + ($dead_B, $dead_A) = _calc_dead_avatars($avatars_B, $avatars_A); + } + else + { + Util::log("Both sides looses!",1); + ($dead_A, $dead_B) = _calc_dead_avatars($avatars_A, $avatars_B, 'drawn'); + } + + my ($new_heros_A, $new_heros_B) = (0,0); + $new_heros_A = $self->die($A, $dead_A, $earthling) if $dead_A; + + # re-read mobiles + $self->{-mobiles} = $self->{-context}-> + read_mobile_condition('ID,OWNER,COUNT,TYPE', + "LOCATION=$self->{-location} ". + "AND AVAILABLE=Y"); + + $new_heros_B = $self->die($B,$dead_B,$earthling) if $dead_B; + + # surviving loosers go home + if($looser){ + $self->teleport($looser); + }else{ + # both sides are looser! + $self->teleport($A); + $self->teleport($B); + } + + $self->stop_fight(); + + my $earthling_name = $self->{-context}->charname($earthling); + my $name_of_A = $self->{-context}->charname($A); + my $name_of_B = $self->{-context}->charname($B); + my $asf = $strength_A - $swlA; + my $dsf = $strength_B - $swlB; + $winner = $winner ? $self->{-context}->charname($winner) : 'NOBODY'; + + my $text = <<END_OF_TEXT; + <strong>BATTLE_REPORT $self->{-location}</strong><br> + <table><tr><th></th><th>$name_of_A</th><th>$name_of_B</th></tr> + <tr><td>MOBILE_AVATAR_PL</td><td>$avatars_A</td><td>$avatars_B</td></tr> + <tr><td>FIGHTING_STRENGTH</td><td>$swlA</td> + <td>$swlB</td></tr> + <tr><td>LUCK</td><td>$asf</td><td>$dsf</td></tr> + <tr><td>SUM_OF_STRENGTH</td><td>$strength_A</td><td>$strength_B</td></tr> + <tr><td>DEAD_AVATARS</td><td>$dead_A</td> + <td>$dead_B</td></tr> + <tr><td>NEW_HEROS $earthling_name</td><td>$new_heros_A</td> + <td>$new_heros_B</td></tr> + </table> + <strong>WINNER_IS $winner</strong>. +END_OF_TEXT + + $self->{-context}->send_message_to_field( + $self->{-location}, + {'MFROM' => 0, 'MSG_TEXT' => $text} + ); +} + +# _calc_dead_avatars +# Calculates number of dead avatars on winner's and looser's side. +# +# Parameters: +# - # winner avatars +# - # looser avatars +# - drawn [OPTIONAL, boolean] +# +# Returns: +# - # dead winner avatars +# - # dead looser avatars +# +sub _calc_dead_avatars +{ + my ($winner, $looser, $drawn) = @_; + my ($dead_winner, $dead_looser) = (0,0); + + # the winner counts as looser if the fight is drawn! + if (defined $drawn && $drawn) + { + $dead_winner = Util::max( + 1, + int(0.5 + $looser / $::conf->{-LOOSER_AVATARS_DYING_FRACTION}) + ); + } + else + { + $dead_winner = Util::min( + $winner - 1, + int(0.5 + $looser / $::conf->{-WINNER_AVATARS_DYING_FRACTION}) + ); + } + + $dead_looser = Util::max( + 1, + int(0.5 + $winner / $::conf->{-LOOSER_AVATARS_DYING_FRACTION}) + ); + + # ensure that there not dying more avatars than existing + $dead_looser = $dead_looser > $looser ? $looser : $dead_looser; + $dead_winner = $dead_winner > $winner ? $winner : $dead_winner; + + return ($dead_winner, $dead_looser); +} + + + +# set MAP.GOD_ATTACKER to 0, if there is our own command-ID +sub stop_fight{ + my($self) = @_; + + my $own_command = $self->{-dbhash}->{'ID'}; + if($own_command == $self->{-god_attacker}){ + $self->{-db}->update_hash('MAP', + "LOCATION=$self->{-location} AND ". + "GAME=$self->{-game}", + {'GOD_ATTACKER' => 0}); + } +} + + +# teleports all of $god from $loc to location of avatar-creation +sub teleport{ + my($self,$god) = @_; + my $loc = $self->{-location}; + + # teleport surviving avatars of looser to home + my $home = $self->{-context}->incarnation_place($god); + Util::log("We teleport all Avatars of $god from $loc to $home.",1); + + $self->{-db}->update_hash('MOBILE', + "TYPE=AVATAR AND OWNER=$god AND AVAILABLE=Y AND ". + "LOCATION=$self->{-location}", + {'LOCATION' => $home}); + + # get all avatar there + my $avatars = $self->{-context}->read_mobile_condition('ID', + "LOCATION=$home ". + "AND OWNER=$god ". + "AND TYPE=AVATAR ". + "AND AVAILABLE=Y"); + # dont call this more than one time! + #for my $avat (@$avatars){ + my ($id) = $avatars->[0]->[0]; + $self->enter_field_avatar($home,$id); + #} +} + + +# kills $to_kill avatars of owner in location and create heros for earthling, +# if possible +sub die{ + my ($self,$owner,$to_kill,$earthling) = @_; + Util::log("$to_kill avatars from $owner dying.",1); + + my $loc = $self->{-location}; + my $mobiles = $self->{-mobiles}; + + my $to_hero = $to_kill; + my $real_to_hero = 0; + for my $a (@$mobiles){ + my ($id,$own,$count,$type) = @$a; + if($own eq $owner and $to_kill){ + if($count <= $to_kill){ + $self->{-db}->delete_from('MOBILE', "ID=$id"); + $to_kill -= $count; + # last unless $to_kill > 0; + }else{ + $self->{-db}->update_hash('MOBILE', "ID=$id", {'COUNT' => ($count - $to_kill)}); + $to_kill = 0; + # last; + } + # add the strength of the death avatar to gods last battle + #my ($actual) = $self->{-db}->single_select("SELECT DEATH_AVATAR FROM GOD WHERE ". + #"GAME=$self->{-game} AND ". + # # "PLAYER=$owner"); + # Util::log("AVATAR dying: adds strength to last-battle-strength of $owner",1); + # $self->{-db}->update_hash('GOD', + # "GAME=$self->{-game} AND PLAYER=$owner", + # {'DEATH_AVATAR' => $actual + 1}); + + # $self->{-context} + # ->send_message_to + # ($loc,$owner, + # {'MFROM' => 0, + # 'MSG_TAG' => 'MSG_AVATAR_DEAD', + # 'ARG1' => $loc, + # 'ARG2' => $self->{-context}->charname($owner)}); + # Util::log("One avatar of $owner died in $loc.",1); + # last; + }elsif($own eq $earthling and $type eq 'WARRIOR' and $to_hero){ + if($count <= $to_hero){ + $self->{-db}->delete_from('MOBILE', "ID=$id"); + $to_hero -= $count; + $real_to_hero += $count; + # last unless $to_hero > 0; + }else{ + $self->{-db}->update_hash('MOBILE', "ID=$id", {'COUNT' => $count-$to_hero}); + $real_to_hero += $to_hero; + $to_hero = 0; + # last; + } + } + last if $to_kill <= 0 and $to_hero <= 0; + } + + if($real_to_hero){ + my $id = $self->{-db}->find_first_free('MOBILE','ID'); + my $mob = {'ID' => $id, + 'GAME' => $self->{-game}, + 'LOCATION' => $self->{-location}, + 'TYPE' => 'HERO', + 'OWNER' => $earthling, + 'COUNT' => $real_to_hero, + 'ADORING' => $owner, + 'AVAILABLE' => 'Y', + 'COMMAND_ID' => $self->{-dbhash}->{'ID'}, + }; + # $self->{-mob} = $mob; + my %mobcopy = (%$mob); + $self->{-db}->insert_hash('MOBILE',\%mobcopy); + $self->unify_mobiles($id,$self->{-location},$earthling); + Util::log("$real_to_hero warriors from $earthling blessed to hero",1); + } + return $real_to_hero; +} + +# this function decides on which side other gods fight +# TODO: do we really need this complicated stuff +sub which_side{ + my($self,$own) = @_; + + my $A = $self->{-args}->{'A'}; + my $B = $self->{-args}->{'B'}; + + my $side = '0'; + $side = 'A' if $own == $A; + $side = 'B' if $own == $B; + + if ($side eq '0') { + my $allA = $self->{-context}->simplyfied_single_relation($own,$A); + my $allB = $self->{-context}->simplyfied_single_relation($own,$B); + if ($allA eq $allB) { + $side = '0'; + } elsif ($allA eq 'FRIEND') { + $side = 'A'; + } elsif ($allB eq 'FRIEND') { + $side = 'B'; + } elsif ($allA eq 'FOE') { + $side = 'B'; + } elsif ($allB eq 'FOE') { + $side = 'A'; + } + } + return $side; +} + +# +# End of FIGHT_GOD +# +#################################################### + +########################################################## +# +# PLAGUE +# + +package PLAGUE; +@PLAGUE::ISA = qw(AymCommand); +use Data::Dumper; + +# this is called to see if the command is executable. +# it should be called from first_phase() and from second_phase(). +# it is not called from the scheduler +sub is_valid { + my $self = shift; + + my @required_arguments = ('TYPE'); + return 0 unless $self->Command::is_valid(@required_arguments); + + # test role god + return 0 unless $self->validate_role('GOD'); + + # test known plagues + unless(Util::is_in($self->{-args}->{'TYPE'},@{$::conf->{-PLAGUES}})){ + Util::log("wrong type of plague: $self->{-args}->{'TYPE'}",0); + return 0; + } + + return 1; +} + +# this is called from Scheduler, if he see the command the +# first time, some commands execute here immidiatly. +# PLAGUE +sub first_phase{ + my $self = shift; + + return 0 unless $self->is_valid(); + + my $args = $self->{-args}; + my $loc = $self->{-dbhash}->{'LOCATION'}; + my $type = $args->{'TYPE'}; + my $spread = $args->{'SPREAD'}; + my $context = $self->{-context}; + + my ($plague,$terrain) = $context->read_field('PLAGUE,TERRAIN', $loc); + $plague = '' unless defined $plague; + + Util::log("old plague: $plague",1); + + # if plagu not allready here + unless($plague =~ /$type/){ + + if(not $spread){ + # need own avatar to plague + return 0 unless $self->avatar_available($loc); + + if($self->test_mana($type,1)){ + $self->use_mana(); + }else{ + return 0; + } + } + Util::log("new plague in $loc: $type",1); + + # set plague in MAP + my $new_plague = $plague ? "$plague,$type" : $type; + $self->{-db}->update_hash('MAP', + "GAME=$self->{-game} AND ". + "LOCATION=$loc", + {'PLAGUE' => $new_plague}); + }else{ + Util::log("plague $type is allready in $loc.",1); + # stop if there is another plague command in location of same type. + # TODO: simplify this with a LIKE-clause, + # but: we have to rewrite quote_condition() first :-( + my $commands = $self->{-db}->select_array('COMMAND', + 'ARGUMENTS,ID', + "COMMAND=PLAGUE AND ". + "GAME=$self->{-game} AND ". + "LOCATION=$loc AND ". + "ID != $self->{-dbhash}->{'ID'}"); + for my $c (@$commands){ + my ($args,$id) = @$c; + # next if $id == $self->{-dbhash}->{'ID'}; + if($args =~ /$type/){ + Util::log("There is allready another PLAGUE-command of $type in $loc",1); + return 0; + } + } + } + + $self->setDuration($::conf->{-DURATION}->{-PLAGUE}); + return $self->{-duration}; +} + +# this is called from scheduler when the command will be executed +# PLAGUE +sub second_phase{ + my $self = shift; + my $loc = $self->{-dbhash}->{'LOCATION'}; + my $type = $self->{-args}->{'TYPE'}; + my $context = $self->{-context}; + + # heal plague with priests + my $priests = $context->count_mobile('PRIEST',$loc); + my $heal_prob = $priests ? 1 - 1/$priests * $::conf->{-HEAL_PLAGUE} : 0; + Util::log("Heal probability: $heal_prob",1); + if($heal_prob > rand(1)){ + Util::log("heal plague of type $type in $loc",1); + my ($plague) = $context->read_field('PLAGUE,TERRAIN', $loc); + if(defined $plague){ + $plague =~ s/$type//; + $self->{-db}->update_hash('MAP', + "GAME=$self->{-game} AND LOCATION=$loc", + {'PLAGUE' => $plague}); + } + }else{ + # spread plague to neighbour-fields + my @neighbours = $self->get_neighbours(); + for my $field (@neighbours){ + my ($terrain,$owner) = $context->read_field('TERRAIN,OCCUPANT',$field); + # $self->{-occ} = $owner; + if(rand(1) < $::conf->{-SPREAD_PLAGUE}->{$terrain}){ + Util::log("spread $type from $loc to $field",1); + $context->insert_command('PLAGUE',"TYPE=$type, SPREAD=1",$field); + } + } + + $self->effect(); + $self->do_it_again({'SPREAD' => 1}); + } + + return 0; +} + +# PLAGUE +sub effect{ + my $self = shift; + my $context = $self->{-context}; + + my $type = $self->{-args}->{'TYPE'}; + Util::log("Do effect of type $type.",1); + + my $loc = $self->{-dbhash}->{'LOCATION'}; + + # effect of INFLUENZA is done in PRODUCE + if($type eq 'PESTILENTIA'){ + my ($vic) = $context->read_field('OCCUPANT',$loc);; + + # count people of owner in field + my $people = $context->count_people($loc,$vic); + $people = 0 unless defined $people; + Util::log("$people people from $vic counted in $loc.",1); + my $victims = int($people * $::conf->{-PESTILENTIA_DEATH_SHARE}); + Util::log("$victims from them have to die.",1); + return unless $victims; + + $self->{-mobiles} = $context->read_mobile('ID,TYPE,OWNER,COUNT,STATUS', + 0, $self->{-location}, 1); + + $self->casualties($vic,$victims,1); + + # send message + my $name_of_victim = $context->charname($vic); + my $text = <<END_OF_TEXT; + <strong>CASUALTIES_OF_PESTILENTIA $self->{-location} $name_of_victim</strong><br> + <table><tr><th></th><th></th></tr> + <tr><td>DEAD_WARRIORS</td><td>$self->{-dead}->{$vic}->{'K'}</td></tr> + <tr><td>DEAD_HEROS</td><td>$self->{-dead}->{$vic}->{'H'}</td></tr> + <tr><td>DEAD_PRIESTS</td><td>$self->{-dead}->{$vic}->{'P'}</td></tr> + <tr><td>SUNKEN_ARKS</td><td>$self->{-dead}->{$vic}->{'A'}</td></tr> + </table> +END_OF_TEXT + + $context->send_message_to_field + ($self->{-location},{'MFROM' => 0, + 'MSG_TEXT' => $text} + # 'ARG1' => $self->{-context}->charname($attacker), + # 'ARG2' => $self->{-context}->charname($defender), + # 'ARG3' => $self->{-context}->charname($self->{-winner}), + # 'ARG4' => $self->{-location}} + ); + #,$attacker,$defender,@gods); + }else{ + Util::log("no effect",1); + } +} + +# +# End of PLAGUE +# +#################################################### +# vim: set ts=4 diff --git a/src/Aymargeddon.pm b/src/Aymargeddon.pm new file mode 100644 index 0000000..7a85977 --- /dev/null +++ b/src/Aymargeddon.pm @@ -0,0 +1,845 @@ +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of "Last days of Aymargeddon" +# +# Aymargeddon 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. +# +# Aymargeddon 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# generell Aymargeddon-specific functions +# + + +# TODO: move color calculation from map.epl in this module + + +use strict; +use FROGS::Game; +use FROGS::HexTorus; + +package Aymargeddon; +use Data::Dumper; +@Aymargeddon::ISA = qw(Game); + +sub new{ + my ($class,$game,$user,$db,$lang) = @_; + + my $self = Game->new($game,$user,$db); + + bless($self,$class); +} + +sub get_map{ + my $self = shift; + + unless (exists $self->{-map}){ + $self->{-map} = $self->read_map("TERRAIN,HOME,OCCUPANT,TEMPLE,PLAGUE,HOME"); + } + return $self->{-map}; +} + +sub get_size{ + my $self = shift; + + unless ($self->{-size}){ + my @size = $self->{-db}->read_game($self->{-game},'SIZE'); + $self->{-size} = $size[0] ? $size[0] : die "could not find size"; + } + return $self->{-size}; +} + +sub get_relation{ + my ($self, $other) = @_; + + unless ($self->{-rel}){ + # print "bindrin\n"; + # $self->{-rel} = $self->read_player_relations($self->{-game}, $self->{-user}); + $self->{-rel} = $self->read_player_relations($self->{-user}); + } + # print Dumper $self->{-rel}; + my $stat = $self->{-rel}->{$other}->{'STATUS'}; + return $stat ? $stat : 'NEUTRAL'; +} + +# FRIEND, ALLIED => FRIEND ; FOE, BETRAY => FOE +sub simplyfied_single_relation{ + my ($self,$me,$you) = @_; + my $rel = $self->read_single_relation($me,$you); + + return 'FRIEND' if Util::is_in($rel,'FRIEND','ALLIED'); + return 'FOE' if Util::is_in($rel,'FOE','BETRAY'); + return 'NEUTRAL'; +} + + +sub god_fight{ + my ($self,$loc_str) = @_; + my @ret = $self->read_field('GOD_ATTACKER',$loc_str); + return $ret[0] ? 1 : 0; +} + +sub earthling_fight{ + my ($self,$loc_str) = @_; + my @ret = $self->read_field('ATTACKER',$loc_str); + return $ret[0] ? 1 : 0; +} + +sub arc_present{ + my ($self,$loc_str) = @_; + my $arks_ref = $self->read_mobile('ID','ARK',$loc_str,1); + my @arks = @$arks_ref; + return $#arks+1; +} + +sub avatar_present{ + my ($self,$loc_str) = @_; + return $self->read_mobile('OWNER','AVATAR',$loc_str,1); +} + +sub mobiles_available{ + my ($self,$loc_str,$avail) = @_; + $avail = 1 unless defined $avail; + my $fields = 'ID, TYPE, OWNER, ADORING, COUNT, STATUS, MOVE_WITH'; + return $self->read_mobile($fields,'',$loc_str, $avail); +} + + +# +# sight stuff +# +# TODO: maybe the generell sight-stuff could go to Game.pm + +# ATTENTION: this function generates the whole sight-matrix, if necessary. +# it could be very time-consuming +sub player_see_field{ + my ($self,$loc) = @_; + + my @players = $self->get_all_roles(); + + my @ret = (); + for my $player (@players){ + # ($player) = @$player; + my $players_aym = new Aymargeddon($self->{-game},$player, + $self->{-db},$self->{-lang}); + if ($players_aym->sight_of_field($loc)){ + push @ret, $player; + # print "$player sees $loc.\n"; + } + } + return @ret; +} + +# this two functions reads sight directly from database +sub sight_of_field{ + my ($self,$loc) = @_; + + return 1 if $self->role($self->{-user}) eq 'OBSERVER'; # admin sees all + + my $player = $self->{-user}; + my $map = HexTorus->new($self->get_size()); + return 1 if $self->sight_of_field_of_player($loc,$player,$map); + + # read all players, which give us informations + my $rel = $self->reverse_player_relations(); + for my $friend (keys %$rel){ + my $status = $rel->{$friend}->{'STATUS'}; + if($status eq 'ALLIED' or $status eq 'BETRAY'){ + if($self->is_earthling($friend) or $::conf->{-GODS_SHOW_EARTHLINGS}){ + return 1 if $self->sight_of_field_of_player($loc,$friend,$map); + } + } + } + return 0; +} + +sub sight_of_field_of_player{ + my ($self,$loc,$player,$map) = @_; + + my ($ter,$own,$occ,$temple) = $self->read_field('TERRAIN,HOME,OCCUPANT,TEMPLE',$loc); + + return 1 if($own == $player or $occ == $player); + return 1 if @{$self->own_in_mobile($loc,$player)}; + + my $location = Location->from_string($loc); + my $dist = 2; + my @neighbours = $map->distant_neighbours($location,$dist); + # Util::log("neighbours: ",-2); + for my $l (@neighbours){ + my $d = $map->distance($location,$l); + my $locstring = $l->to_string(); + # Util::log(" $locstring ($d),",-2); + + my ($neighbour_ter,$neighbour_home) = $self->read_field('TERRAIN,HOME',$locstring); + next if ($d > 1 && $neighbour_ter ne 'MOUNTAIN'); + return 1 if $neighbour_home == $player; + return 1 if $neighbour_ter eq 'MOUNTAIN' and + $neighbour_home <= 0 and $self->is_god($player); + return 1 if @{$self->own_in_mobile($locstring,$player)}; + } + # Util::log("",2); + return 0; +} + +# this function generates the whole sight if called +sub sight{ + my ($self,$loc_str) = @_; + + return 1 if $self->role($self->{-user}) eq 'OBSERVER'; # admin sees all + + $self->generate_sight() unless $self->{-sight_map}; + + return 1 if $self->{-sight_map}->{$loc_str}; +} + +# overloads the function from Game-Class +sub seen_locations{ + my $self = shift; + + # TODO-PERFORMANCE: make map a self-constructing member of class (like size) + my $map = HexTorus->new($self->get_size()); + + my @ret = (); + for my $loc ($map->get_all()){ + my $ls = $loc->to_string(); + push @ret, $ls if $self->sight($ls); + } + return @ret; +} + +sub generate_sight{ + my ($self) = @_; + + delete $self->{-sight_map}; + + my $rel = $self->reverse_player_relations(); + + $self->sight_of_player($self->{-user}); + for my $player (keys %$rel){ + my $status = $rel->{$player}->{'STATUS'}; + if($status eq 'ALLIED' or $status eq 'BETRAY'){ + if($self->is_earthling($player) or $::conf->{-GODS_SHOW_EARTHLINGS}){ + $self->sight_of_player($player); + } + } + } + + # print Dumper $self->{-sight_map}; +} + +sub sight_of_player{ + my ($self,$player) = @_; + + my $map = HexTorus->new($self->get_size()); + + my $selfmap = $self->get_map(); + + for my $row (@$selfmap){ + my ($loc,$ter,$own,$occ,$temple,$plague,$home) = @$row; + + if($own == $player or $occ == $player + or @{$self->own_in_mobile($loc,$player)} + or ($self->is_god($player) and $ter eq 'MOUNTAIN' and $home <= 0)){ + $self->{-sight_map}->{$loc} = 1; + my $location = Location->from_string($loc); + my $dist = 1; + $dist = 2 if $ter eq 'MOUNTAIN'; + my @neighbours = $map->distant_neighbours($location,$dist); + for my $l (@neighbours){ + $self->{-sight_map}->{$l->to_string()} = 1; + } + } + } +} + +sub is_coast{ + my ($self,$loc_str) = @_; + my ($ter) = $self->read_field('TERRAIN',$loc_str); + return 0 if($ter ne 'PLAIN' and $ter ne 'CITY' and $ter ne 'MOUNTAIN'); + + my $map = HexTorus->new($self->get_size()); + my @neighbours = $map->neighbours(Location->from_string($loc_str)); + for my $loc (@neighbours){ + ($ter) = $self->read_field('TERRAIN',$loc->to_string()); + return 1 if($ter eq 'ISLE' or $ter eq 'WATER'); + } + return 0; +} + +sub is_arrival{ + my ($self, $loc_str) = @_; + + return 1 if $loc_str eq $self->incarnation_place(); + + return 0; +} + +sub is_god{ + my ($self,$player) = @_; + $player = $self->{-user} unless defined $player; + return ($self->role($player) eq 'GOD'); +} + +sub is_earthling{ + my ($self,$player) = @_; + $player = $self->{-user} unless defined $player; + return ($self->role($player) eq 'EARTHLING'); +} + +sub gods{ + my ($self) = @_; + return $self->get_all_roles('GOD'); +} + +sub earthlings{ + my ($self) = @_; + return $self->get_all_roles('EARTHLING'); +} + +sub get_mana{ + my ($self,$player) = @_; + $player = $self->{-user} unless defined $player; + return 0 if $player < 1; + + my $stmt = "SELECT MANA from GOD where GAME=$self->{-game} AND PLAYER=$player"; + my ($mana) = $self->{-db}->single_select($stmt); + return $mana ? $mana : 0; +} + +sub gender{ + my ($self,$player) = @_; + return 0 if $player < 1; + my @gen = $self->read_role($player, 'GENDER'); + return $gen[0]; +} + + +sub field_string{ + my ($self, $type) = @_; + return $self->{-db}->loc('FIELD_'.$type); +} + +sub relation_string{ + my ($self, $other) = @_; + my $rel = $self->get_relation($other); + # print Dumper $rel; + $rel = 'NEUTRAL' if not $rel; + return $self->{-db}->loc('STAT_'.$rel); +} + +sub mobile_string{ + my ($self, $type, $num) = @_; + my $tag = 'MOBILE_'.$type; + $tag .= '_PL' if $num != 1; + return $self->{-db}->loc($tag); +} + +sub mobile_extended_string{ + # count + localised type + adored god if any + my ($self, $type, $num, $adoring) = @_; + my $out = $num.' '.$self->mobile_string($type, $num); + if($type eq 'PRIEST' or $type eq 'PROPHET' or $type eq 'HERO'){ + $out .= ' '.$self->{-db}->loc('ADJ_ADORING').' '.$self->charname($adoring); + } + return $out; +} + +sub role_string{ + my ($self, $player) = @_; + my $role = $self->role($player); + $role = 'UNDEFINED' unless defined $role; + my $tag = "ROLE_$role"; + return $self->{-db}->loc($tag); +} + + +sub new_role{ + my($self,$role,$name,$gender,$desc) = @_; + $desc = 'none' unless defined $desc; + my $db = $self->{-db}; + +# my ($qname, $qgender, $qdesc, $qrole) +# = $db->quote_all($name, $gender, $desc, $role); + + my $cond = 'GAME='.$self->{-game}." AND NICKNAME=$name"; + return 0 if @{$db->select_array('ROLE','GAME',$cond)}; # error: dublicate name + + my @homes; # all possible homes for this role + if($role ne 'OBSERVER'){ + @homes = $self->open_homes($role); + return 0 if $#homes<0; # error: no home free + } + + # dont allow names only in uppercase + return 0 if $name =~ /^\s*[A-Z_]{3,}\s*$/; + + # write in ROLE + $db->insert_hash('ROLE',{'GAME' => $self->{-game}, + 'PLAYER' => $self->{-user}, + 'NICKNAME' => $name, + 'ROLE' => $role, + 'GENDER' => $gender, + 'DESCRIPTION' => $desc} + ); + if($role eq 'OBSERVER'){ + $db->commit(); + return 1; + } + + # choose home: + my $home = $homes[rand($#homes + 1)]->[0]; + + if($role eq 'GOD'){ + # read actual default manapool from GAME + my ($mana,$ts) = $db->read_game($self->{-game},'START_MANA,TEMPLE_SIZE'); + $mana += $ts * 2; + + # write GAME, PLAYER, MANA in GOD + $db->insert_hash('GOD',{'GAME' => $self->{-game}, + 'PLAYER' => $self->{-user}, + 'MANA' => $mana}); + + # choose second and third home + # my $home2 = $home; + # my $home3 = $home; + # if($#homes > 0){ + # while($home2 eq $home or $home3 eq $home or $home2 eq $home3){ + # $home2 = $homes[rand($#homes + 1)]->[0]; + # $home3 = $homes[rand($#homes + 1)]->[0]; + # } + # } + + # # change OWNER in MAP where LOCATION=$home or LOCATION=$home2 + # # ($home,$home2) = $db->quote_all($home,$home2); + # $db->update_hash('MAP', + # "GAME=$self->{-game} AND". + # " (LOCATION=$home OR LOCATION=$home2 OR LOCATION=$home3)", + # {'HOME' => $self->{-user}}); + + }else{ # eartling + # write GAME, PLAYER in EARTHLING + $db->insert_hash('EARTHLING',{'GAME' => $self->{-game}, + 'PLAYER' => $self->{-user}}); + + # change OCCUPANT, OWNER in MAP where LOCATION=$home + # ($home) = $db->quote_all($home); + $db->update_hash('MAP', + "GAME=$self->{-game} AND LOCATION=$home", + {'HOME' => $self->{-user}, + 'OCCUPANT' => $self->{-user}}); + + # change PLAYER of WARRIORS OR PRIESTs in MOBILE where LOCATION=$home + $db->update_hash('MOBILE', + "GAME=$self->{-game} AND LOCATION=$home AND OWNER=-1", + {'OWNER' => $self->{-user}}); + + # give additional start-warriors + my $warriors = $db->select_array('MOBILE', + 'ID,COUNT', + "GAME=$self->{-game} AND LOCATION=$home ". + "AND OWNER=$self->{-user} AND TYPE=WARRIOR"); + my @w = @$warriors; + if($#w > -1){ + $db->update_hash('MOBILE', + "ID=$w[0]->[0]", + {'COUNT' => "COUNT + $::conf->{-START_WARRIORS}"}, + 'noquote'); + }else{ + $db->insert_hash('MOBILE', + {'ID' => $db->find_first_free('MOBILE','ID'), + 'GAME' => $self->{-game}, + 'LOCATION' => $home, + 'TYPE' => 'WARRIOR', + 'COUNT' => $::conf->{-START_WARRIORS}, + 'OWNER' => $self->{-user}, + 'AVAILABLE' => 'Y'}); + } + + # modify PRODUCE Command + $db->update_hash('COMMAND', + "GAME=$self->{-game} AND COMMAND=PRODUCE ". + "AND LOCATION=$home", + # TODO: open question: is this redundant information? + {'PLAYER' => $self->{-user}, + 'ARGUMENTS' => "ROLE=$self->{-user}"}); + + } + + # TODO: write MESSAGE to all members of this game: new player with role! + + + $db->commit(); + return 1; +} + +sub startfield{ + my ($self) = @_; + + my $cond = "GAME=$self->{-game} AND "; + if($self->role($self->{-user}) eq 'OBSERVER'){ + $cond .= 'TERRAIN='.$self->{-db}->quote('AYMARGEDDON'); + }else{ + $cond .= "HOME=$self->{-user}"; + } + # TODO: what happens if both mountains are flooded? + return $self->{-db}->select_array('MAP','LOCATION',$cond)->[0]->[0]; +} + + +sub open_homes{ + my ($self,$role) = @_; + my $terrain = ($role eq 'GOD') ? 'MOUNTAIN' : 'CITY'; + # ($terrain) = $self->{-db}->quote_all($terrain); + my $cond = 'GAME='.$self->{-game}." AND HOME=-1 AND TERRAIN=$terrain"; + return @{$self->{-db}->select_array('MAP','LOCATION',$cond)}; +} + +sub is_open{ + my ($self,$terrain) = @_; + + my $cond = "GAME=$self->{-game} AND HOME=-1"; + if($terrain){ + $terrain = $self->{-db}->quote($terrain); + $cond .= "AND TERRAIN=$terrain"; + } + my $unused = $self->{-db}->select_array('MAP','LOCATION','',$cond); + my @arr = @$unused; + + return $#arr+1; +} + +# TODO performance: we can do this whole function in one sophisticated SQL-statement. +sub incarnation_place{ + my ($self,$player) = @_; + $player = $self->{-user} unless defined $player; + + my $temples = $self->{-db}->select_array('MAP','LOCATION', + "TEMPLE='Y' AND HOME=$player"); + + my $place; + my $max_priests = 0; + for my $temple (@$temples){ + my $loc = $temple->[0]; + Util::log("check for $loc...",1); + # my ($qloc,$type,$yes) = $self->{-db}->quote_all($loc,'PRIEST','Y'); + my $priests = $self->{-db}->single_hash_select('MOBILE', + "ADORING=$player AND ". + "LOCATION=$loc AND ". + "TYPE=PRIEST AND ". + "AVAILABLE=Y AND ". + "GAME=$self->{-game}"); + + if(defined $priests and $priests->{'COUNT'} > $max_priests){ + $place = $loc; + $max_priests = $priests->{'COUNT'}; + } + } + return $place; +} + +sub read_fortune{ + my $self = shift; + + my ($fortune) = $self->{-db}->read_game($self->{-game}, + 'FORTUNE'); + return $fortune; +} + +# returns also empty neighbours, but no attacked neighbours +sub own_neighbours{ + my ($self,$loc,$player) = @_; + $player = $self->{player} unless defined $player; + + # print "own_neighbours($loc,$player)\n"; + my $map = HexTorus->new($self->get_size()); + my $location = Location->from_string($loc); + my @neighbours = $map->neighbours($location); + my @own_neighbours; + for my $n (@neighbours){ + my $n_string = $n->to_string(); + my ($occ,$att,$terrain) = $self->read_field('OCCUPANT,ATTACKER,TERRAIN',$n_string); + Util::log("$n_string occupied by $occ, attacked by $att",2); + next if $att; + next if $::conf->{-FIGHTS_WITHOUT_OWNER}->{$terrain} and not $occ; + push @own_neighbours, $n_string if $occ == $player or $occ <= 0; + } + # print Dumper \@own_neighbours; + Util::log("own_neighbours($loc,$player): @own_neighbours",2); + return @own_neighbours; +} + +sub is_in_direction_from{ + my($self,$to,$from) = @_; + + my $map = HexTorus->new($self->get_size()); + my $to_location = Location->from_string($to); + my $from_location = Location->from_string($from); + + return $map->get_direction($from_location,$to_location); +} + +sub show_statistic{ + my($self) = @_; + my $db = $self->{-db}; + + my @earthlings = $self->get_all_roles('EARTHLING'); + my @gods = $self->get_all_roles('GOD'); + + # show for god: own mana, + my $out = ''; + if($self->is_god()){ + # own mana + $out .= $db->loc('OWN_MANA',$self->get_mana()); + } + + # show for all: #priests of god (?), #citys of earthling, #temples to build, + # speed of game, fortune, last battle, fighting strength of earthlings + # #temples of god + + # strength of every god in last battle + $out .= $db->loc('LAST_BATTLE_HEADING') . '<p>'; + for my $god (@gods){ + # my $god = $god->[0]; + + my $strength=$self->strength_in_last_battle($god); + $out .= $db->loc('LAST_BATTLE_LINE',$self->charname($god),$strength) . '<br>'; + + # TODO?: count priests + } + + # count citys + $out .= '<p>' . $db->loc('CITY_HEADING'). '<p>'; + for my $player (@earthlings){ + # $player = $player->[0]; + my $citys = $db->count('MAP', + "GAME=$self->{-game} AND OCCUPANT=$player AND TERRAIN=CITY"); + $out .= $db->loc('STATISTIC_EARTHLING_CITY', + $self->charname($player), + $citys).'<br>'; + } + $out .= '<p>'; + + # count temples to build for the end of the world + $out .= $db->loc('STATISTIC_UNBUILD', $self->unbuild()). " " . + $db->loc('STATISTIC_NEW_TEMPLES', $self->under_construction())."<p>\n"; + + my $game = $db->single_hash_select('GAME', + "GAME=$self->{-game}"); + my $fortune = $game->{'FORTUNE'}; + $out .= $db->loc('STATISTIC_FORTUNE',$fortune); + + my $speed = $game->{'SPEED'}; + $out .= $db->loc('STATISTIC_SPEED',"$speed sec"); + + return $out; +} + +# returns number of places for temples +sub building_places{ + my $self = shift; + return $self->{-db}->count('MAP', + "(TERRAIN=ISLE OR TERRAIN=MOUNTAIN) ". + "AND GAME=$self->{-game}"); +} + +# returns number of unbuild temples +sub unbuild{ + my $self = shift; + return $self->{-db}->count('MAP', + "(TERRAIN=ISLE OR TERRAIN=MOUNTAIN) ". + "AND TEMPLE=N AND GAME=$self->{-game}"); +} + +# returns number of temples or arks which are currently under construction +sub under_construction{ + my ($self,$type) = @_; + $type = 'TEMPLE' unless defined $type; + return $self->{-db}->count('EVENT', + "TAG=EVENT_BUILD_$type"); + +} + +sub strength_in_last_battle{ + my($self,$god) = @_; + $god = $self->{-player} unless defined $god; + my $db = $self->{-db}; + + my $god_hash = + $db->single_hash_select('GOD', + "GAME=$self->{-game} AND PLAYER=$god"); + + my $aymargeddon = + $db->single_hash_select('MAP', + "GAME=$self->{-game} AND". + " TERRAIN=AYMARGEDDON")->{'LOCATION'}; + my $avatars = $self->count_mobile('AVATAR',$aymargeddon,$god); + + my $strength = $::conf->{-LAST_BATTLE}->{-AVATAR} * $avatars + + $::conf->{-LAST_BATTLE}->{-DEATH_AVATAR} * $god_hash->{'DEATH_AVATAR'} + + $::conf->{-LAST_BATTLE}->{-DEATH_HERO} * $god_hash->{'DEATH_HERO'}; + + return $strength; + +} + +sub mobile_to_html{ + my ($self, $loc,$own,$occ,$temple,$ter, + $oid,$otype,$oown,$oado,$ocnt,$ostat,$omove) = @_; +# field infos: +# loc: location of the field +# own: the owner of the field (for cities and temples) (HOME) +# occ: the occupant of the field +# temple: wether there is a temple or not +# ter: terrain of field +# mobile infos: +# oid: id of the mobile +# otype: type of the mobile +# oown: owner of the mobile +# oado: which god the mobile adores +# ocnt: mobile count +# ostat: status of the mobile (BLOCK, IGNORE or HELP) +# omove: the id of the mobile to move with (unused here) + + my $user = $self->{-user}; + my $db = $self->{-db}; + my $aym = $self; + + my $out = $ocnt.' '; + if($oown == $user){ + $out .= $db->loc('PREP_OWN_PL').' '.$aym->mobile_string($otype,2); + if($otype eq 'PRIEST' or $otype eq 'PROPHET'){ + $out .= $db->loc('ADJ_ADORING').' '.$aym->charname($oado); + if($own != $oado){ + $out .= ' (<a href="command.epl?cmd=CH_STATUS&other='.$oado.'">'. + $aym->relation_string($oado). + '</a>, <a href="command.epl?cmd=SEND_MSG&other='.$oado.'">'. + $db->loc('SEND_MESSAGE').'</a>)'; + } + if(($ter eq 'ISLE' or $ter eq 'MOUNTAIN') and $temple eq 'N'){ + $out .=' (<a href="command.epl?cmd=BUILD_TEMPLE&mob='.$oid.'&loc='.$loc.'">'; + $out .= $db->loc('CMD_BUILD_TEMPLE').'</a>)'; + } + }elsif($otype eq 'HERO'){ + $out .= $db->loc('ADJ_ADORING');#.' <a href="command.epl?cmd=CH_ADORING&mob='. + # $oid.'">'; + $out .= ' ' . $aym->charname($oado); #.'</a>'; + if($own != $oado){ + $out .= ' (<a href="command.epl?cmd=CH_STATUS&other='.$oado.'">'. + $aym->relation_string($oado). + '</a>, <a href="command.epl?cmd=SEND_MSG&other='.$oado.'">'. + $db->loc('SEND_MESSAGE').'</a>)'; + } + }elsif($otype eq 'AVATAR'){ + $out .= ' (<a href="command.epl?cmd=CH_ACTION&mob='.$oid.'">'. + $aym->mobile_string($ostat,1).'</a>)'; + if($temple eq 'Y'){ + $out .= " (<a href=\"command.epl?cmd=DESTROY&loc=$loc\">". + $db->loc('CMD_DESTROY').'</a>)'; + } + } + $out .= ' (<a href="command.epl?cmd=MOVE&mob='.$oid.'&loc='.$loc.'">'. + $db->loc('CMD_MOVE').'</a>)'; + + }else{ + $out .= $aym->mobile_string($otype, $ocnt); + + $out .= ' '.$db->loc('PREP_OWN_SG').' '; + $out .= $db->loc('ART_DAT_PL').' ' if $aym->gender($oown) eq 'PLURAL'; + $out .= $aym->charname($oown); + if($own != $oown and $occ != $oown){ + $out .= ' (<a href="command.epl?cmd=CH_STATUS&other='.$oown.'">'. + $aym->relation_string($oown).'</a>,'. + '<a href="command.epl?cmd=SEND_MSG&other='.$oown.'">'. + $db->loc('SEND_MESSAGE').'</a>)'; + } + + if($otype eq 'PRIEST' or $otype eq 'PROPHET'or $otype eq 'HERO'){ + $out .= $db->loc('ADJ_ADORING').' '; + if($oado == $user){ + $out .= $db->loc( ($aym->gender($user) eq 'PLURAL') ? + 'PPRO_DAT3_PL' : 'PPRO_DAT3_SG'); + }else{ + $out .= $aym->charname($oado); + if($own != $oown and $occ != $oown){ + $out .= ' (<a href="command.epl?cmd=CH_STATUS&other='.$oado.'">'. + $aym->relation_string($oado). + '</a>, <a href="command.epl?cmd=SEND_MSG&other='.$oado.'">'. + $db->loc('SEND_MESSAGE').'</a>)'; + } + } + }elsif($otype eq 'WARRIOR' and $aym->is_god($user)){ + $out .= ' (<a href="command.epl?cmd=BLESS_PRIEST&mob='.$oid.'">'. + $db->loc('CMD_BLESS_PRIEST').'</a>)'; + if($own==$user and $temple eq 'Y'){ + $out .= ' (<a href="command.epl?cmd=BLESS_HERO&mob='.$oid.'">'. + $db->loc('CMD_BLESS_HERO').'</a>)'; + } + } + } + return $out; +} + +# this overloads the same function in Game.pm +# we dont look on arks, that is special for Aymargeddon +#sub own_in_mobile{ +# my($self,$loc,$player,$active) = @_; +# my $cond = "GAME=$self->{-game} AND LOCATION=$loc". +# " AND TYPE!=ARK AND (OWNER=$player OR ADORING=$player)"; +# if(defined $active){ +# # my $y = $self->{-db}->quote('Y'); +# $cond .= " AND AVAILABLE='Y'"; +# } +# return $self->{-db}->select_array('MOBILE','ID',$cond); +#} + + +# returns true if foreign eartlings approach to field +sub foreign_earthling_approaching{ + my ($self,$loc,$earthling) = @_; + + # TODO BUG: if $earthling < 1 => different names in different languages... + my $name = $self->charname($earthling); + my $ret = $self->{-db}->count('EVENT', + "LOCATION=$loc AND ". + "(TAG=EVENT_MOBILE_APPROACHING OR ". + "TAG=EVENT_ARK_APPROACHING) AND ". + "ARG1 != $name AND ". + "ARG4 != MOBILE_AVATAR AND ". + "ARG4 != MOBILE_AVATAR_PL"); + + return $ret; +} + +# returns true if own avatar is there and if no god-fight is running +sub avatar_available{ + my ($self,$loc,$god,$command) = @_; + + my $avatars = $self->own_in_mobile($loc,$god,1); + my @avatars = @$avatars; + + my ($godfight) = $self->read_field('GOD_ATTACKER',$loc); + + unless($#avatars >= 0 and not $godfight){ + $self->send_message_to($god, + {'MSG_TAG' => "MSG_$command\_NEED_AVATAR", + 'ARG1' => $loc}) if defined $command; + return 0; + } + + return 1; +} + +1; diff --git a/src/COPYING b/src/COPYING new file mode 100644 index 0000000..eeb586b --- /dev/null +++ b/src/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/src/FROGS/Check.pm b/src/FROGS/Check.pm new file mode 100644 index 0000000..033bcfe --- /dev/null +++ b/src/FROGS/Check.pm @@ -0,0 +1,116 @@ +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of +# "FROGS" = Framework for Realtime Online Games of Strategy +# +# FROGS 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. +# +# FROGS 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +use strict; +use FROGS::DataBase; + +# +# Here some generell functionality to check the integrity of +# the underlying database is checked. + +package Check; +use Data::Dumper; + +sub new{ + my $class = shift; + my $self = {}; + $self->{-db} = DataBase->new(@_); + bless ($self,$class); +} + +# do a check, there can be different TYPE of checks: +# A_IN_B, LOGIC, UNIVERSAL +# +# - A in B checks if corresponding fields in different tables exists +# +# - LOGIC checks with a function for some fields in a table +# +# - UNIVERSAL checks with an arbitrary function +# +# - TODO: LOCATION should check with a function for every location + +sub check_all{ + my $self = shift; + my $checks = shift; + + my $db = $self->{-db}; + + while(my ($k,$v) = each %$checks){ + print "check $k... "; + my $type = $v->[0]; + if($type eq 'A_IN_B'){ + my $table_A = $v->[1]->[0]; + my $field_A = $v->[1]->[1]; + my $table_B = $v->[1]->[2]; + my $field_B = $v->[1]->[3]; + + # TODO BUG: dont use single_select! + my @data = $db->single_select("select distinct $field_A from $table_A"); + my @datb = $db->single_select("select distinct $field_B from $table_B"); + + print Dumper \@datb; + my %schnitt; + for my $d (@datb){ + print "hab $d\n"; + $schnitt{$d} = 1; + } + my $failed = 0; + for my $d (@data){ + if(not exists($schnitt{$d})){ + print "FAILED with $field_A = $d!\n"; + $failed = 1; + last; + } + } + next if $failed; + print "OK.\n"; + }elsif($type eq 'LOGIC'){ + my $table = $v->[1]->[0]; + my $fields = $v->[1]->[1]; + my $function = $v->[1]->[2]; + local $" = ', '; + my $command = "select @$fields from $table"; + # TODO: single_select correct? we need the whole table and + # TODO: there is no condition??? + my @dat = $db->single_select($command); + # print Dumper $dat; + + my $failed = 0; + for my $d (@dat){ + my $ret = &$function($d); + $failed = 1 unless $ret; + } + $failed ? print "FAILED!\n" : print "OK.\n"; + }elsif($type eq 'UNIVERSAL'){ + my $function = $v->[1]; + my $ret = &$function($db); + $ret ? print "FAILED: $ret\n" : print "OK.\n"; + }else{ + print "FAILED (Type of check - $type - not avaiable)\n"; + } + } +} + +1; + + diff --git a/src/FROGS/Command.pm b/src/FROGS/Command.pm new file mode 100644 index 0000000..c10a6c8 --- /dev/null +++ b/src/FROGS/Command.pm @@ -0,0 +1,486 @@ +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of +# "FROGS" = Framework for Realtime Online Games of Strategy +# +# FROGS 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. +# +# FROGS 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# +# basic command object used by the scheduler +use strict; +use Date::Parse qw(str2time); +use Date::Calc qw(Time_to_Date); +use FROGS::DataBase; +use FROGS::Config qw ($conf); +require "$::conf->{-GAME_NAME}.pm"; + +package Command; +use Data::Dumper; + +sub new { + my ($type, $dbhash, $dbobj) = @_; + + Util::log("$type->new()",2); + + my $self = {-dbhash => $dbhash, + -db => $dbobj, + -player => $dbhash->{'PLAYER'}, + -game => $dbhash->{'GAME'}, + -id => $dbhash->{'ID'}, + -location => $dbhash->{'LOCATION'}, + -class => $type, + }; + bless( $self, $type ); + + # create an GAME_NAME context object + $self->{-context} = $::conf->{-GAME_NAME}->new($dbhash->{'GAME'}, + $dbhash->{'PLAYER'}, + $dbobj); + + $self->{-speed} = $self->{-context}->get_speed(); + + # end of the game? + if($self->{-speed} < 0){ + Util::log("Game over, no commands anymore!",1); + $self->done(); + return 0; + } + + # set language according to PLAYER.LANGUAGE + my ($lang) = $dbobj->read_player($self->{-player},'LANGUAGE'); + $dbobj->set_language($lang); + + $self->{-args} = $self->parse_args( $self->{-dbhash}->{'ARGUMENTS'} ); + + if (defined $self->{-dbhash}->{'ACK'} and + $self->{-dbhash}->{'ACK'} ne '0000-00-00 00:00:00'){ + $self->{-phase} = 2; + }else{ + $self->{-phase} = 1; + $self->{-duration} = $::conf->{-DURATION}->{"-$type"} || 0; + } + + if(not $::conf->{-MESSAGE_IN_LOG} and $type eq 'SEND_MSG'){ + Util::log('',1); + }else{ + my $logstring = "\nCommand $type (ID: $self->{-dbhash}->{'ID'}): ". + "Phase $self->{-phase}, ". + "Player $self->{-dbhash}->{'PLAYER'}, ". + "Game $self->{-dbhash}->{'GAME'}, ". + "Arguments $self->{-dbhash}->{'ARGUMENTS'}"; + $logstring .= ", Location $self->{-dbhash}->{'LOCATION'}, " + if defined $self->{-dbhash}->{'LOCATION'}; + Util::log($logstring,1); + } + + return $self; +} + +sub is_valid { + my ($self, @required_args) = @_; + + # all arguments avaiable? + # TODO PERFORMANCE: maybe this check only in phase1? + return 0 unless $self->required_args($self->{-args}, @required_args); + + # does the player still exists? + if($self->{-player} == -1){ + $self->{-role} = $self->{-context}->charname(-1); + }else{ + my ($id,$role) = $self->{-context}->read_role($self->{-player},'PLAYER,ROLE'); + if($id != $self->{-player}){ + Util::log("COMMAND->is_valid: Player $self->{-player} does not exist!\n",0); + return 0; + } + # set role for later use + # print "ROLE(is_valid): $role\n"; + $self->{-role} = $role; + } + return 1; +} + +sub isSecond { + my $self = shift; + return 2 == $self->{-phase}; +} + +sub isFirst { + my $self = shift; + return 1 == $self->{-phase}; +} + +sub execute { + my $self = shift; + my $db=$self->{-db}; + + #if($self->{-speed} < 0){ + # Util::log('*',-1); + # $self->done(); + # return; + #} + # determine phase of command and do it. + if ($self->isFirst() ) { + $db->update_hash("COMMAND","ID = $self->{-dbhash}->{'ID'}",{ 'ACK' => $db->now() }); + my $ret = $self->first_phase(); + + if ($self->getDuration() > 0 and $ret > 0) { + my $exec = $self->getPhase2exec(); + if($self->{-end_of_game}){ + $self->done(); + }else{ + $db->update_hash("COMMAND", + "ID = $self->{-dbhash}->{'ID'}", + { 'EXEC' => $exec }); + } + }elsif ($self->getDuration() == 0 or $ret == 0){ + $self->done(); + } else { + # in this case the command has set its EXEC by itself. we do nothing + $self->done() if $self->{-end_of_game}; + } + } elsif ($self->isSecond() ) { + $self->second_phase(); + $self->done(); + } else { + Util::log("command->execute ($self->{-class}) : Unknown or undefined Command phase",0); + die; + } +} + +sub done { +# a command will use this func to declare it's terminated +# it is called by Scheduler after secondPhase anyway, so a +# command has to use it only explicitley in a member if it wants to +# terminate NOW! (but still have to exit action for itself) + my $self = shift; + my $db=$self->{-db}; + + my $id = $self->{-id}; + + $db->update_hash("COMMAND","ID = $id",{ 'DONE' => $db->now() }); + if ($::conf->{-DEBUG} == 0 or $::conf->{-DELETE_OLD_COMMANDS}) { + $db->delete_from("COMMAND","ID=$id"); + Util::log(ref($self)."-Command $id deleted.",1); + # TODO: dont delete PRODUCE-Command if game not runnning, but waiting + } + # TODO?: send messages +} + +sub setDuration { +# sets the duration of the command in units. Sheduler will schedule +# the Phase 2 then for gametime+units*pace(game). +# this function will have to be called explicitely during phase 1 by the +# implementation of the command +# If it is not called at least once (or set to 0), Scheduler will assume the command has +# no second phase and will call done() after completion of firstPhase(). + my $self = shift; + $self->{-duration} = shift; +} + +sub getDuration { +# get command duration in units + my $self = shift; + return $self->{-duration}; +} + +sub getDurationInSec{ +# get command duration in secs according to the *current* gamespeed + my $self = shift; + + my $ret = $self->getDuration() * $self->{-speed}; + + Util::log("Duration in sec: $ret",1) unless defined $self->{-duration_logged}; + $self->{-duration_logged} = 1; + + $self->{-end_of_game} = 1 unless $ret >= 0; + return $ret; +} + +sub getPhase2exec { + # only valid during phase 1 returns start of phase 2 in game + # time, GMT (YYYY-MM-DD HH:MM:SS). If Duration wasn't set, or + # phase is wrong it returns undef. + my $self = shift; + if ($self->getDuration() == 0 || $self->isSecond() ) { + return undef; + } + my $firstExecTimeUnix = &::str2time($self->{-dbhash}->{'EXEC'},'GMT'); +# my $firstExecTimeUnix = &::str2time($self->{-dbhash}->{'EXEC'}); + $firstExecTimeUnix += $self->getDurationInSec(); + my ($year,$month,$day, $hour,$min,$sec) = &::Time_to_Date($firstExecTimeUnix); + return sprintf ("%04u-%02u-%02u %02u:%02u:%02u",$year,$month,$day, $hour,$min,$sec); +} + + +############################################# +# +# Tools to be used by concrete commands +# + +# TODO: Bug mit messages +sub parse_args { + my ( $self, $arg_string ) = @_; + + my @key_value_pairs = split /,/, $arg_string; # TODO: wrong for messages + + # remove leading/trailing whitespace + @key_value_pairs = map { $_ =~ s/^\s*(\S*)\s*$/$1/; $_ } @key_value_pairs; + + my %hash; + for my $kv (@key_value_pairs) { + my ( $k, $v ) = split /=/, $kv; # TODO: wrong for messages + + # remove leading/trailing whitespace again + ( $k, $v ) = map { $_ =~ s/^\s*(\S*)\s*$/$1/; $_ } ( $k, $v ); + + $hash{$k} = $v; + } + # use Data::Dumper; print Dumper \%hash; + return \%hash; +} + +sub required_args { + my ( $self, $args, @ra ) = @_; + + for my $a (@ra) { + unless ( exists $args->{$a} ) { + Util::log("We need argument $a",1); + return 0; + } + } + return 1; +} + + + +# general testfunction. +# sends error message and return false +# unless &$cond() gives true + +sub test{ + my ($self, $cond, $tag, @args) = @_; + + unless(&$cond()){ + # (@args) = $self->{-db}->quote_all(@args); + + my $sendhash = {'MFROM' => 0, + 'MSG_TAG' => $tag}; + # TODO: localize command-strings! + $sendhash->{'ARG1'} = $self->{-class}; + for my $a (1..($#args+1)){ + $sendhash->{"ARG$a"} = $args[$a-1]; + } + + $self->{-context}->send_message_to($self->{-player},$sendhash); + + Util::log("Test failed: $tag, args @args",1); + + return 0; + } + return 1; +} + +#sub test{ +# my ($self, @all) = @_; +# +# if($self->test_without_done(@all)){ +# return 1; +# }else{ +# # delete me from database +# $self->done(); +# return 0; +# } +#} + +# set a mobilehash if available, sends errormessage otherwise +sub validate_mobile{ + my ($self,$mob_id) = @_; + + my $mob = $self->{-db}->read_single_mobile($mob_id); + + # mobile correct? + if($self->{-phase} == 1){ + return 0 unless $self->test(sub {defined $mob}, + 'MSG_NO_SUCH_MOBILE', + $mob_id); + } + $self->{-mob} = $mob; + return 1; +} + +# errormessage unless one of valid roles +sub validate_role{ + my ($self, @valid_roles) = @_; + + return 1 if $self->{-player} < 0; + + Util::log("validate_role($self->{-role})",2); + + unless(Util::is_in($self->{-role},@valid_roles)){ + return 0 unless $self->test(sub {0}, + 'MSG_ROLE_CANT_DO', + $self->{-role}, + ref($self)); + } + return 1; +} + +sub validate_this_role{ + my($self,$player,@valid_roles) = @_; + + # fake identity + my $role = $self->{-role}; + my ($id,$r) = $self->{-context}->read_role($player,'PLAYER,ROLE'); + $self->{-role} = $r; + my $ret = $self->validate_role(@valid_roles); + $self->{-role} = $role; + return 0 unless $ret; + return 1; +} + +# takes a mobile_hash, a count and a diff_hash. creates another mobile +# with count members in the database with the different fields given +# in diff_hash. if $available, than the new mob is available + +# returns +# ID of newmob (newmob is in some sense really the old mob, because +# diff is apllied to old mob) , returns the new ID (of the old mob). + +sub split_mobile{ + my ($self, $mob, $count, $diff, $available) = @_; + my $db = $self->{-db}; + Util::log(ref($self).": split mobile $mob->{'ID'}",1); + + # create new mobile + my %newmob = %$mob; + my $newmob = \%newmob; + $newmob->{'ID'} = $self->{-db}->find_first_free('MOBILE','ID'); + my $newid = $newmob->{'ID'}; + + %$mob = (%$mob,%$diff); + # print Dumper $mob; exit; + # %$newmob = (%$oldmob, %$newmob); + + # calculate new count and available + $mob->{'COUNT'} = $count; + $mob->{'AVAILABLE'} = $available ? 'Y' : 'N'; + + my $id = $mob->{'ID'}; + delete $mob->{'ID'}; + # print Dumper $mob; + $self->{-db}->update_hash('MOBILE',"ID=$id",$mob); + Util::log("mobile $id updated",1); + + # reduce count of old one + $newmob->{'COUNT'} -= $count; + + # print Dumper $newmob; + $self->{-db}->insert_hash('MOBILE',$newmob); + Util::log("new mobile $newid",1); + + return $newid; +} + +# this function splits a mobile if it necessary, update else. +# usage of parameters: see split_mobile +# returns the new ID of the old mob (see split_mobile) +sub conditional_split_mobile{ + my ($self, $mob, $count, $diff, $available) = @_; + + # print "count: $count\n"; + # print Dumper $mob; + + my $db = $self->{-db}; + + # split it, if neccessary + if($count < $mob->{'COUNT'}){ + + return $self->split_mobile($mob,$count,$diff,$available); + + }elsif($count == $mob->{'COUNT'}){ + $diff->{'AVAILABLE'} = $available ? 'Y' : 'N'; + $db->update_hash('MOBILE', + "ID=$mob->{'ID'}", + $diff); + return $mob->{'ID'}; + }else{ + Util::log("SPLIT MOBILE: Error! impossible case. not enough mobiles. ". + "we need $count and have only $mob->{'COUNT'}",0); + return 0; + } +} + +sub event{ + my ($self, $loc, $tag, @args) = @_; + + # read execution time + my $exec_time = $self->getPhase2exec(); + + unless($exec_time){ + my $cmd = $self->{-db}->single_hash_select('COMMAND', + "ID=$self->{-dbhash}->{'ID'}"); + $exec_time = $cmd->{'EXEC'}; + } + + my $event = {'TAG' => $tag, + 'LOCATION' => $loc, + 'GAME' => $self->{-game}, + 'TIME' => $exec_time, + 'COMMAND_ID' => $self->{-dbhash}->{'ID'}, + }; + $event->{'ARG1'} = $self->{-context}->charname($self->{-player}); + for my $a (0..$#args){ + $event->{'ARG'.($a+2)} = $args[$a]; + } + $self->{-db}->write_event($event); +} + +# this function re-inserts the same command in the queue again +sub do_it_again{ + my ($self,$arguments) = @_; + + my $now = $self->{-db}->now(); + # we need a new ID + delete $self->{-dbhash}->{'ID'}; + # reset timestamps + $self->{-dbhash}->{'SUBMIT'} = $now; + $self->{-dbhash}->{'EXEC'} = $now; + $self->{-dbhash}->{'ACK'} = 'NULL'; # TODO: wrong way to insert NULL? + $self->{-dbhash}->{'DONE'} = 'NULL'; + if (defined $arguments){ + # these arguments are allready there in the database + my $hash = $self->parse_args($self->{-dbhash}->{'ARGUMENTS'}); + # we put some additional ones into hash + for my $k (keys %$arguments){ + $hash->{$k} = $arguments->{$k}; + } + # rearrange hash into string + my $new_string = ''; + my ($key,$value); + while (($key,$value) = each %$hash){ + $new_string .= "$key=$value, "; + } + $new_string =~ s/, $//; + $self->{-dbhash}->{'ARGUMENTS'} = $new_string; + } + # write new command to database + $self->{-db}->insert_hash('COMMAND', $self->{-dbhash}); +} + +1; diff --git a/src/FROGS/Config.pm b/src/FROGS/Config.pm new file mode 100644 index 0000000..860a64f --- /dev/null +++ b/src/FROGS/Config.pm @@ -0,0 +1,206 @@ +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of "Last days of Aymargeddon" +# +# Aymargeddon 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. +# +# Aymargeddon 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# TODO: seperate FROGS-config from Aymargeddon-config in different files + +# change this file to configure your game + +use strict; +package Config; +require Exporter; +@::ISA = qw(Exporter); +@::EXPORT_OK = qw($conf); + +$::conf = { + # FROGS stuff + -DB_SOURCE => 'mysql:RAGNAROEK', + -DB_USER => 'aymargeddon', + -DB_SECRETS => '/home/benni/aymargeddon/current/+secrets', + -COMMANDS => 'AymCommand.pm', + -GAME_NAME => 'Aymargeddon', + -DEFAULT_LANGUAGE => 'EN', + -LOG_TIME_IN_LOOP => 1000, # loops until next time output in log + -DEBUG => 1, + -EPL_DEBUG => 0, + -MESSAGE_IN_LOG => 0, + -FULL_DEBUG_FILE => '/home/benni/aymargeddon/current/src/FROGS/+out', + -SCHEDULER_SLEEP => 2, + -DELETE_OLD_EVENTS => 1, # dont touch this, it will not work! + -DELETE_OLD_COMMANDS => 1, # dont touch this, it will not work! + -SEND_MESSAGE_TO_FIELD => 1, # set to 0 to stop slow messages + -MAX_ARGS => 4, # maximum arguments for localisation tags + # (hardcoded in database-structure) + -MANY => 99999, + + # Aymargeddon stuff... you maybe dont need this for other games + + -START_MANA => 33, + -START_FORTUNE => 3, + -START_WARRIORS => 2, + -MAX_MOUNTAINS => 1, # mountains per god/earthling-combination + -MIN_DISTANCE_HOME => 3, # minimal distance between homecitys + -NEIGHBOUR_CITIES => 2, # number of citys in the neighbourhood of a home + -MIN_DISTANCE_MOUNTAIN => 2, + -WANTED_DISTANCE_MOUNTAIN => 3, + -MIN_DISTANCE_MOUNTAIN_FROM_WATER => 2, + -MIN_LUCK => 3, + -MAX_LUCK => 12, + -MANA_FOR_TEMPLE => 1, + -FORTUNE_FAKTOR_ISLAND => 1, + -FORTUNE_FAKTOR_MOUNTAIN => 2, + -MAX_UNBUILD_DESTROY => 1, + # -ARK_RETREAT_POSSIBILITY => 0.5, (in the moment hardcoded) + -WINNER_DEATH_COUNT_FRACTION => 5, + -LOOSER_DEATH_COUNT_FRACTION => 3, + -WINNER_AVATARS_DYING_FRACTION => 4, + -LOOSER_AVATARS_DYING_FRACTION => 2, + -DEATH_SHARE_ROW => [0.4, 0.3, 0.2, 0.1], # should sum to 1 + -DEFAULT_DYING => 'KHP', + + -PLAGUES => ['INFLUENZA','PESTILENTIA','TUBERCULOSIS'], + -PESTILENTIA_DEATH_SHARE => 0.5, + -SPREAD_PLAGUE => {'CITY' => 0.1, + 'PLAIN' => 0.05, + 'MOUNTAIN' => 0.03, + 'ISLE' => 0.02, + 'WATER' => 0}, + -HEAL_PLAGUE => 0.4, + + # can gods give earthlings right to see? + -GODS_SHOW_EARTHLINGS => 0, + + # which fields keep there owner without units? + -HOMECITY_KEEP_OWNER => 1, + -TEMPLE_KEEP_OWNER => 1, + -KEEP_OWNER => {'CITY' => 1}, + + # which fields fight without owner? + -FIGHTS_WITHOUT_OWNER => {'CITY' => 1}, + + # which fields fights without units? + #-HOMECITY_FIGHTS => 1, + #-FIGHTS_WITHOUT_UNIT => {'CITY' => 1}, + + -DURATION => { + + -MOVE_AVATAR => 1, + -MOVE_HERO => 8, + -MOVE_WARRIOR => 10, + -MOVE_PRIEST => 6, + # -MOVE_PROPHET => 6, # 12 + -MOVE_ARK => 5, + -FIGHT_EARTHLING => 6, + -FIGHT_GOD => 10, #10 + -BUILD_TEMPLE => 3, # 50 + -FLOOD => 40, # 40 + -CH_ADORING => 20, + -CH_LUCK => 5, + -PRODUCE_WARRIOR => 40, # 40 + -PRODUCE_WARRIOR_HOME => 20, # 20 + -PRODUCE_WARRIOR_CHANGE => 0, + -PRODUCE_PRIEST => 40, # 40 + -PRODUCE_PRIEST_HOME => 40, # 40 + -BUILD_ARK => 30, #30 + -PLAGUE => 20, + -PRAY => 10, # 10 + }, + + -FIGHT => { + -PRIEST => 0, + -WARRIOR => 1, + -HERO => 2, + -PROPHET => 0, + -AVATAR => 4, # maximum + -HOME => 2, + -ISLE => 2, + -ARK => 1, + -FLANKING => 1, + }, + #-SEE_FIGHT => { + # -PRIEST => 0, + # -WARRIOR => 0, + # -HERO => 1, + # -PROPHET => 0, + #-AVATAR => 0, + #-HOME => 0, + #-ARK => 3, + #-FLANKING => 0, + #}, + # -ISLAND_FIGHT => { + # -PRIEST => 0, + # -WARRIOR => 1, + # -HERO => 2, + # -PROPHET => 0, + #-AVATAR => 4, # maximum + #-HOME => 2, + #-ARK => 3, + #-FLANKING => 0, + #}, + + -LAST_BATTLE => { + -DEATH_HERO => 1, + -DEATH_AVATAR => 0, + -AVATAR => 7, + }, + -MANA => { + -MOVE_AVATAR => 1, + -FIGHT_AVATAR => 2, + -DESTROY => 7, + -FLOOD => 4, + -CH_LUCK => 1, + -BUILD_ARK => 7, + -BLESS_PRIEST => 7, + -BLESS_HERO => 2, + -INCARNATE => 5, + # plagues: + -INFLUENZA => 10, + -PESTILENTIA => 20, + -TUBERCULOSIS => 40, + }, + + -COLOR => { + -EMPTY => '#fcffd9', + -NEUTRAL => '#b8a266', + }, + }; + +# read password from secrets-file. password should not be included in source! + +my $conf = $::conf->{-DB_SECRETS}; + +# substitute "~" (UNIX only!) from Perl Cookbook 7.3 not really useful +# here, because HOME is different in webserver and in user context +$conf =~ s{ ^ ~ ( [^/]* ) }{ $1 ? (getpwnam($1))[7] : ($ENV{HOME}||$ENV{LOGDIR}|| + (getpwuid($<))[7])}ex; + +open(CONFIG,$conf) or die "could not open config file $conf: $!\n"; + +while(<CONFIG>){ + chop $_; + next if /^\s*$/; + next if /^\s*\#.*$/; + $::conf->{-DB_PASSWD} = $_; +} +close CONFIG or die "could not close config file $conf: $!\n"; + +1; + diff --git a/src/FROGS/DataBase.pm b/src/FROGS/DataBase.pm new file mode 100644 index 0000000..b37458b --- /dev/null +++ b/src/FROGS/DataBase.pm @@ -0,0 +1,592 @@ +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of +# "FROGS" = Framework for Realtime Online Games of Strategy +# +# FROGS 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. +# +# FROGS 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# +# Generell database methods are gathered here. +use strict; +use DBI; +use POSIX qw(floor); +use FROGS::Config qw($conf); +use FROGS::Util; +use Date::Parse qw(str2time); +use Date::Calc qw(Time_to_Date Delta_DHMS); + +package DataBase; + +# the constructor connects to the DB +sub new{ + my ($class,$dbh) = @_; + my $self = {}; + if (defined $dbh){ + $self->{-dbh} = $dbh; + }else{ + $self->{-dbh} = DBI->connect("dbi:$::conf->{-DB_SOURCE}", + $::conf->{-DB_USER}, + $::conf->{-DB_PASSWD}, + {'RaiseError' => 1, 'AutoCommit' => 0} + ); + } + #TODO: should specify iso date and time format explicitly for the session!! + + $self->{-lang} = $self->{-dbh}->quote($::conf->{-DEFAULT_LANGUAGE}); + + bless ($self,$class); +} + +sub commit{ + my $self = shift; + unless(defined $self->{-nowrite}){ + $self->{-dbh}->commit(); + Util::log('committed.',2); + } +} + +sub nowrite{ + my $self = shift; + Util::log("DataBase: nowrite activated!",1); + $self->{-nowrite} = 1; +} + +# automaticly called destructor +sub DESTROY{ + my $self = shift; + $self->{-dbh}->disconnect(); +} + +# wrapper for database functions: + +sub quote{ + my ($self, $text) = @_; + return $self->{-dbh}->quote($text); +} + +sub quote_all{ + my ($self, @plain) = @_; + my @quoted; + for my $s (@plain){ + push @quoted, $self->{-dbh}->quote($s); + } + return @quoted; +} + +# this does not support any possible SQL-conditions +# just a small subset +# TODO: this function is really ugly :-( +# TODO: just use an escape-character in calls to mark, which fields should be +# TODO: quoted +sub quote_condition{ + my ($self, $cond) = @_; + + Util::log("condition: $cond",2); + + my @bracket = ('(',')'); + my @bool = ('AND', 'OR'); + my @ops = ('=', '!='); + my @noops = ('<'); # forbidden substrings of pairs. ugly workaround for "time < now()" + + # split string at boolean operators + my $splitstring = ''; + for my $bool (@bool){ + $splitstring .= '\b'.$bool.'\b|'; + } + $splitstring =~ s/(.*)\|/$1/; + + #Util::log("splitstring: $splitstring\n",2); + + my @pairs = split /\s$splitstring\s/, $cond; + + Util::log("pairs: @pairs",2); + + my $opstring = ''; + for my $o (@ops){ + $opstring .= "$o|"; + } + $opstring =~ s/(.*)\|/$1/; + + my $noopstring = ''; + for my $no (@noops){ + $noopstring .= "$no|"; + } + $noopstring =~ s/(.*)\|/$1/; + + # quote right hand of operator if necessary + for my $pair (@pairs){ + next if $pair =~ /$noopstring/; + my ($left,$right) = split /$opstring/, $pair; + #Util::log("1 left: $left, right: $right",2); + $right =~ s/^\(*-?([\w\s].*)$/$1/; # remove leading brackets + #Util::log("2 left: $left, right: $right",2); + $right =~ s/-?(.*[\w\s])\)*$/$1/; # remove trailing brackets + #Util::log("3 left: $left, right: $right",2); + $right =~ s/^\s*-?(\S.*)/$1/; # remove leading whitespace + #Util::log("4 left: $left, right: $right",2); + $right =~ s/(.*\S)\s*$/$1/; # remove trailing whitespace + #Util::log("5 left: $left, right: $right",2); + + next if $right =~ /^\d+$/; + # this could be misfunctional in some SQL-Dialect. We assume single-quotes + my $qright = ($right =~ /^\'.*\'/) ? $right : $self->quote($right); + + # Util::log("qright: $qright",2); + next if $cond =~ /$qright/; + $cond =~ s/($opstring\s*)$right/$1$qright/; + } + Util::log("new condition: $cond",2); + return $cond; +} + +# assumes that a single row is returned from database +# returns a list of selected columns +sub single_select{ + my ($self,$stmt) = @_; + + Util::log("single_select: $stmt",2); + my $dat = $self->{-dbh}->selectall_arrayref($stmt); + return () if not defined $dat or not defined $dat->[0]; + return @{$dat->[0]}; +} + +sub single_hash_select{ + my ($self,$table,$cond) = @_; + + $cond = $self->quote_condition($cond); + my $stmt = "SELECT * FROM $table where $cond"; + Util::log("single_hash_select: $stmt",2); + return $self->{-dbh}->selectrow_hashref($stmt); +} + +sub select_hash{ + my ($self, $table, $key, $fields, $cond) = @_; + + my $stmt = $fields ? "SELECT $key, $fields FROM $table" + : "SELECT $key FROM $table"; + $stmt .= " WHERE $cond" if $cond; + return $self->{-dbh}->selectall_hashref($stmt, $key); +} + +sub select_array{ + my ($self, $table, $fields, $cond, $order) = @_; + my $stmt = "SELECT $fields FROM $table"; + if( $cond){ + $cond = $self->quote_condition($cond); + $stmt .= " WHERE $cond"; + if(defined $order){ + $stmt .= " ORDER BY $order"; + } + } + + Util::log("select_array: $stmt",2); + return $self->{-dbh}->selectall_arrayref($stmt); +} + +# returns number of fields with given condition +sub count{ + my ($self, $table, $cond) = @_; + my $array = $self->select_array($table,'*',$cond); + my @a = @$array; + my $count = $#a + 1; + Util::log("counted $cond in $table: $count",1); + return $count; +} + +# insert a row in one table of the database +# +# parameterlist: +# table: the database-table we work on +# hash: give here a hash with the new values +# noquote: if hash, than dont quote all keys which are in this hash, +# if no hash but defined, than we dont quote all the new values +# (useful for things simmilar to COUNT = COUNT + 1) +sub insert_hash{ + my ($self, $table, $hash,$noquote) = @_; + my $noquote_type = ref($noquote); + my $noquote_global = 1 if defined $noquote and not $noquote_type eq 'HASH'; + my $noquote_hash = 1 if $noquote_type eq 'HASH'; + + my $insert = "INSERT INTO $table ("; + for my $key (keys %$hash){ + # $key = $self->{-dbh}->quote_identifier($key); + $insert .= "$key,"; + } + chop($insert); + $insert .=") VALUES ("; + while( my ($k,$val) = each %$hash){ + $val = $self->quote($val) if not $noquote_global or + ($noquote_hash and exists $noquote->{$k}); + $insert .= "$val,"; + } + chop($insert); + $insert .= ')'; + + Util::log("INSERT: $insert",2); + my $h = $self->{-dbh}->prepare($insert); + $h->execute(); + $h->finish(); +} + +# parameter: see insert_hash() and update_hash() +sub insert_or_update_hash{ + my ($self, $table, $cond, $hash, $noquote) = @_; + $cond = $self->quote_condition($cond); + my @row = $self->single_select("SELECT * FROM $table WHERE $cond"); + use Data::Dumper; + if($#row >= 0){ + $self->update_hash($table,$cond,$hash,$noquote); + }else{ + $self->insert_hash($table,$hash,$noquote); + } +} + +# update a set of rows in one table of the database +# +# parameterlist: +# table: the database-table we work on +# cond: only rows are effected, which evaluates this condition as true +# hash: give here a hash with the new values +# noquote: if hash, than dont quote all keys which are in this hash, +# if no hash but defined, than we dont quote all the new values +# (useful for things simmilar to COUNT = COUNT + 1) +sub update_hash{ + my ($self, $table, $cond, $hash, $noquote) = @_; + my $noquote_type = ref($noquote); + my $noquote_global = 1 if defined $noquote and not $noquote_type eq 'HASH'; + my $noquote_hash = 1 if $noquote_type eq 'HASH'; + + my $stmt = "UPDATE $table SET "; + while( my ($k,$v) = each %$hash){ + $v = $self->quote($v) if not $noquote_global or + ($noquote_hash and exists $noquote->{$k}); + $stmt .= "$k=$v,"; + } + chop($stmt); + + $stmt .= " WHERE ". $self->quote_condition($cond); + + Util::log("update_hash: $stmt",2); + my $h = $self->{-dbh}->prepare($stmt); + $h->execute(); + $h->finish(); +} + +sub delete_from{ + my ($self,$table,$cond) = @_; + + die "do you really want to delete a complete table?" unless $cond; + + my $sql = "DELETE FROM $table"; + if($cond){ + $cond = $self->quote_condition($cond); + $sql .= " WHERE $cond"; + } + Util::log($sql,2); + my $dbh = $self->{-dbh}; + my $h = $dbh->prepare($sql); + $h->execute(); + $h->finish(); +} + +sub find_first_free{ + my ($self,$table,$field) = @_; + + my $t = $self->select_array($table, $field); + my @ids = sort {$a <=> $b} (map {$_->[0]} @$t); + + my $id = 1; + for my $try (@ids){ + next if $try < 0; # unfortunately some tabels contain the id -1 and id 0 is free :-( + last if $id < $try; + $id = $try + 1; + } + return $id; +} + +sub read_game{ + my ($self,$game,$field) = @_; + my $stmt = "SELECT $field from GAME where GAME=$game"; + return $self->single_select($stmt); +} + +# localisation + +sub set_language{ + my ($self, $lang) = @_; + $self->{-lang} = $self->{-dbh}->quote($lang) if $lang; +} + +# returns the localisation of a tag. +# if the result contains tags again, localize these too. +sub loc{ + my ($self, $tag, @args) = @_; + + Util::log("args: @args",2); + + $tag = $self->{-dbh}->quote($tag); + my $stmt = 'SELECT TEXT FROM LOCALIZE WHERE LANGUAGE='.$self->{-lang}." AND TAG=$tag"; + my ($text) = $self->single_select($stmt); + + # replace %x with arg[x] + while($text =~ /\%(\d+)/){ + my $nr = $1; + Util::log("found $nr in $text",2); + $text =~ s/(\%$nr)/$args[$nr-1]/g; + } + + return $text =~ /^\s*$/ ? "Error: Tag $tag not defined for language $self->{-lang}." + : $self->localize_string($text); +} + +# calls loc() for all uppercase-only-words and returns new string +# TODO: allow arguments in brackets after uppercase-words with length >= 3 +sub localize_string{ + my ($self,$string) = @_; + + $string =~ s/(\b[^\Wa-z0-9]{3,}\b)/$self->loc($1)/ge; + return $string; +} + +# game management: + +sub new_account{ + my ($self,$login,$name,$email,$lang) = @_; + + my ($qlogin,$qname,$qemail) = $self->quote_all($login,$name,$email); + + my $cond = "LOGIN=$qlogin OR REALNAME=$qname OR EMAIL=$qemail"; + my $habschon = $self->select_array('PLAYER','PLAYER',$cond); + my @habschon = @$habschon; + return 0 if @habschon; + + # generate new password + my $pwd = ''; + my $allowed = '2345679ACDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; + for my $i (0..7){ + $pwd .= substr($allowed, POSIX::floor(rand(72)), 1); + } + my $qpwd = $self->{-dbh}->quote($pwd); + + # search first free player ID + my $player = $self->find_first_free('PLAYER','PLAYER'); + + # write new player + $self->insert_hash('PLAYER', {PLAYER => $player, + REALNAME => $name, + LOGIN => $login, + EMAIL => $email, + PASSWORD => $pwd, + LANGUAGE => $lang, + }); + $self->commit(); + + my $mail = "From: registration\@aymargeddon.de\nTo: $name <$email>\n" + . "Subject: ".$self->loc('REGISTER_MAIL_SUBJECT')."\n\n" + . $self->loc('REGISTER_MAIL_TEXT', $name, $login, $pwd)."\n"; + + # print $mail; + + open(SENDMAIL, "|mail $email") or Util::log("Can't fork for sendmail: $!",0); + print SENDMAIL $mail; + close(SENDMAIL) or Util::log("sendmail didn't close nicely",0); + + return $pwd; +} + +sub authenticate{ + my ($self, $user, $pwd, $pwd2, $pwd3 ) = @_; + + my $admin = $self->quote('admin'); + # you can log into any account with adminpassword + my ($adminpwd) = $self->single_select("SELECT PASSWORD FROM PLAYER ". + "WHERE LOGIN=$admin"); + ($user,$pwd,$adminpwd) = $self->quote_all($user,$pwd,$adminpwd); + + + Util::log("Adminpassword: $adminpwd, password: $pwd",2); + + my ($player, $sec); + if($adminpwd eq $pwd){ + my $stmt = "SELECT PLAYER,SECURITY FROM PLAYER WHERE ". + "LOGIN=$user"; + ($player, $sec) = $self->single_select($stmt); + }else{ + my $stmt = "SELECT PLAYER,SECURITY FROM PLAYER WHERE ". + "LOGIN=$user AND PASSWORD=$pwd"; + ($player, $sec) = $self->single_select($stmt); + } + + if($player){ + if($pwd2 and $pwd3 and $pwd2 eq $pwd3){ + # change password! + $self->update_hash('PLAYER', + "LOGIN=$user", + {'PASSWORD' => $pwd2}); + Util::log("password changed!",0); # todo: localize and aufhübschen + } + # TODO: write last_login + return $player; + } + return 0; +} + +sub write_event{ + my ($self, $content) = @_; + + $self->insert_hash('EVENT', $content); +} + +sub read_event{ + my ($self, $id) = @_; + + my $e = $self->single_hash_select('EVENT',"ID=$id"); + my @args; + for my $a (1..($::conf->{-MAX_ARGS})){ + Util::log("search for ARG$a...",2); + push @args, $e->{"ARG$a"}; + } + + Util::log("args in read_event: @args",2); + + my ($loc,$to); + $to = $e->{'LOCATION'} || 'Game'; + + return ($to,$e->{'TIME'},$self->loc($e->{'TAG'},@args)); +} + +sub delete_event{ + my ($self, $id) = @_; + $self->delete_from('EVENT',"ID=$id"); +} + +sub send_message{ + my ($self, $msg_hash) = @_; + + $msg_hash->{'TIME'} = $self->now(); + $self->insert_hash('MESSAGE',$msg_hash); +} + +sub read_message{ + my ($self, $id) = @_; + + my $stmt = "SELECT TIME, MFROM, MSG_TAG, MSG_TEXT, ARG1, ARG2, ARG3, ARG4 ". + "FROM MESSAGE WHERE ID=$id"; + my ($time, $from, $tag, $text, @args) = $self->single_select($stmt); + + # localize it + if($tag){ + # print "tag!"; + $text = $self->loc($tag, @args); + return ($time, $from, $text, @args); + }elsif($text){ + # print "text!"; + $text = $self->localize_string($text) unless $from; + return ($time, $from, $text); + }else{ + return (0, 'unknown message type error in DataBase'); + } +} + +sub delete_message{ + my ($self, $id) = @_; + + $self->delete_from('MESSAGE',"ID=$id"); +} + +sub read_player{ + my ($self,$player,$field) = @_; + my $stmt = "SELECT $field from PLAYER where PLAYER=$player"; + return $self->single_select($stmt); +} + +# returns all games for id -1 (admin) +sub games_of_player{ + my ($self,$player) = @_; + + if($player > 0){ + return $self->select_array('ROLE','GAME',"PLAYER=$player"); + }else{ + return $self->select_array('GAME','GAME'); + } +} + +sub open_games{ + my ($self,$cond) = @_; + my $games = $self->select_array('GAME','GAME'); + # return $games; + + my @log; + for my $game (@$games){ + my $c = "GAME=$game"; + $c .= "AND $cond" if $cond; + + my $unused = $self->select_array('MAP','LOCATION','',$c); + + push @log, $game if $#{@$unused} + 1; + } + return \@log; +} + +sub read_single_mobile{ + my($self,$id) = @_; + + return $self->single_hash_select('MOBILE',"ID=$id"); +} + +sub now{ + my $self = shift; + my ($ret) = $self->single_select("SELECT NOW()"); + return $ret; +} + +# generates a relative time string from an absolute time +sub relative{ + my ($self, $absolute) = @_; + + my $now = $self->now(); + # print "now: $now\nabsolute: $absolute\n"; + + my $now_unix = Date::Parse::str2time($now,'GMT'); + my $absolute_unix = Date::Parse::str2time($absolute,'GMT'); + # print "now_unix: $now_unix\nabsolute_unix: $absolute_unix\n"; + my $diff = $absolute_unix - $now_unix; + + if($diff > 0){ + + my ($days,$hours,$minutes,$seconds) = + Date::Calc::Delta_DHMS(1970,1,1,0,0,0,Date::Calc::Time_to_Date($diff)); + + if($days){ + return $self->loc('TIME_WITH_DAYS',$days,$hours,$minutes,$seconds); + }elsif($hours){ + return $self->loc('TIME_WITH_HOURS',$hours,$minutes,$seconds); + }elsif($minutes){ + return $self->loc('TIME_WITH_MINUTES',$minutes,$seconds); + }else{ + return $self->loc('TIME_WITH_SECONDS',$seconds); + } + }else{ # $diff <= 0 + return ''; + } +} + +1; + + diff --git a/src/FROGS/FROGS.pod b/src/FROGS/FROGS.pod new file mode 100644 index 0000000..a837bcb --- /dev/null +++ b/src/FROGS/FROGS.pod @@ -0,0 +1,134 @@ +=head1 NAME B<FROGS> + + +B<F>ramework for B<R>ealtime B<O>nline B<G>ames of B<S>trategy + +=head1 DESCRIPTION + + +This is a Framework for programming Massive Multiplayer Browsergames +(MMBG). + +The generell idea is to have a SQL-Database, which is accessed over +DBI, some scripts to do the work at the server and some +EmbPerl-Scripts to do the user interaction. The wide area of games is +to different to give the scripts itself, so instead we choose to +provide some modules which includes the generell function of a MMBG +and you will program some scripts to do the game-specific +part. Normally you need: + +=over 4 + +=item create.pl + +A script, which generates a world in the database. + +=item scheduler.pl + +A script which do the commands and deliver the messages. It should run +as a daemon. + +=item check.pl + +A script, which checks the logical integrity of the database of your +game. + +=item *.epl + +A bunch of Templates for the user-interaction. For instance a +login.epl to manage the user-authentification and a map.epl to draw a +graphical map. + +=back + +As a start you can look at the scripts provided by the Aymargeddon +project (www.aymargeddon.de), which is based upon FROGS. You should +maybe use the *.epl-templates from it, because they do much generell +work and some of them will maybe included in later versions of FROGS. + +FROGS consists of the following parts: + +=over 4 + +=item B<FROGS::Map> + +An generell baseclass for maps. Includes a generell baseclass for +locations. + +=item B<FROGS::HexTorus> + +A special Map derived from FROGS::Map. It is a Torus consisting of +Hex-Fields. + +=item B<FROGS::Check> + +This provides generell checking ability for the underlying database. + +=item B<FROGS::DataBase> + +Here the structur of the Database is defined. You should normally not +use direct DBI-access to the Database. Use this module instead +whenever possible. + +=item B<FROGS::Config> + +You have to change this to configure your Game. See the comments in +the file. + +=back + +Look in the perldoc of the parts if you want to know more. + +=head1 DATABASE + +You also need to provide a FROGS-conform database. Your game database +can have more tables and fields than this, but the following +tables/fields are a must have: + +=over 4 + +=item MAP + +Fields: LOCATION, GAME + +=item COMMANDS + +Fields: COMMAND, GAME, PLAYER + +=item MESSAGES + +Fields: GAME, MESSAGE, PLAYER, FROM + +=item LOCALIZE + +=item ROLE + +=item PLAYER + +=back + +Look at the database definition in Aymargeddon to get a clue. For +later versions we will provide a database definition of this minimal +database to simplify things. + +=head1 VERSION + +This is Version 0.1 of the FROGS. + +=head1 LICENSE + +FROGS is Free Software (GPL). + +=head1 AUTHOR + +FROGS was written by the Aymargeddon development team. Most work done by: + + Benni Baermann (benni AT obda DOT de) + + Dominikus Scherkl + + Jens Kurlanda + +Contact us at ragnaroek AT informatik DOT uni-frankfurt DOT de. + +=cut diff --git a/src/FROGS/Game.pm b/src/FROGS/Game.pm new file mode 100644 index 0000000..e07e61d --- /dev/null +++ b/src/FROGS/Game.pm @@ -0,0 +1,391 @@ +#!/usr/bin/perl -w +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of +# "FROGS" = Framework for Realtime Online Games of Strategy +# +# FROGS 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. +# +# FROGS 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# generell Game-specific functions +# + +use strict; +use FROGS::DataBase; +use FROGS::Util; + +package Game; +use Data::Dumper; + +sub new{ + my ($class,$game,$user,$db) = @_; + + my $self = {}; + + # create database-object, if not given with call + if (defined $db) { + $self->{-db} = $db; + } else { + $self->{-db} = DataBase->new(); + } + # $db->set_language($lang); + + $self->{-game} = $game; + $self->{-user} = $user; + + bless($self,$class); +} + +sub insert_command{ + my ($self,$cmd,$args,$loc,$player,$exec) = @_; + $player = $self->{-user} unless defined $player; + my $db = $self->{-db}; + + my ($now) = $db->single_select("SELECT NOW()"); + + # insert MOBILE Argument in the database-field if any + my $mobile = 0; + if($args =~ /MOBILE\s*=\s*(\d+)/){ + $mobile = $1; + } + + my $hash = {'GAME' => $self->{-game}, + 'SUBMIT' => $now, + 'PLAYER' => $player, + 'COMMAND' => $cmd, + 'ARGUMENTS' => $args, + 'MOBILE' => $mobile, + }; + if(defined $exec){ + # insert a phase-2 command + $hash->{'EXEC'} = $exec; + $hash->{'ACK'} = $now; + }else{ + $hash->{'EXEC'} = $now; + } + $hash->{'LOCATION'} = $loc if defined $loc; + $db->insert_hash('COMMAND',$hash); + Util::log("command inserted: $cmd, $args, $loc, $player",1); +} + +sub read_map{ + my ($self, $fields) = @_; + # $fields should NOT be empty + return $self->{-db}->select_array('MAP',"LOCATION,$fields","GAME=$self->{-game}"); +} + +# +# Message handling +# + +sub read_messages{ + my ($self, $fields) = @_; + $fields = ','.$fields if $fields; + $fields = 'ID'.$fields; + my $cond = "GAME=$self->{-game} AND (MTO=0 OR MTO=$self->{-user})"; + return $self->{-db}->select_array('MESSAGE', $fields, $cond, 'TIME desc'); +} + +# sends a raw text, if $hash is not a hash. if it is one, it generates +# a tag with arguments usable by DataBase::long_loc() +sub send_message_to{ + my($self,$user,$hash) = @_; + + $hash->{'MTO'} = $user; + $hash->{'GAME'} = $self->{-game}; + + $self->{-db}->send_message($hash); + +} + +sub send_message_to_me{ + my ($self,$hash) = @_; + + $self->send_message_to($self->{-user},$hash); +} + +sub send_message_to_list{ + my ($self,$msg_hash,@list) = @_; + + Util::log("send_message_to_list(@list)",2); + + for my $user (@list) { + my %copy = (%$msg_hash); + $self->send_message_to($user,\%copy); + } +} + +sub send_message_to_all{ + my ($self,$hash) = @_; + + my @roles = $self->get_all_roles(); + $self->send_message_to_list($hash,@roles); +} + +sub show_message{ + my ($self,$id) = @_; + + my ($time, $from, $text, @args) = $self->{-db}->read_message($id); + + my $other = $from; + # lookup sender + $from = $from == 0 ? "Server" : $self->charname($from); + + my $return = "<strong>$from $time:</strong> $text"; + $return .= ' <a href="player.epl?cmd=SEND_MSG&other='.$other + .'">reply</a>' unless $other == 0; + return $return; +} + +sub delete_all_messages{ + my ($self,$time) = @_; + # $::conf->{-EPL_DEBUG} = 2; + # print "time: $time<p>"; + $self->{-db}->delete_from('MESSAGE',"GAME=$self->{-game} AND MTO=$self->{-user}". + " AND TIME < '$time'"); + # $::conf->{-EPL_DEBUG} = 0; +} + +# send message to all players, who see this field +sub send_message_to_field{ + my($self,$loc,$hash) = @_; + + return unless $::conf->{-SEND_MESSAGE_TO_FIELD}; + + my @players = $self->player_see_field($loc); + $self->send_message_to_list($hash,@players); +} + +# +# events +# + +# returns a ref to a list of Event-IDs for a role +# it includes all game-events and all events on locations seen by the role +# TODO: accept additional parameter N to return the N newest events +sub role_events{ + my $self = shift; + + my $db = $self->{-db}; + my @loc = $self->seen_locations(); + + my $k = $db->select_hash('EVENT','LOCATION','ID',"GAME=$self->{-game}"); + + my @ret = (); + for my $l (@loc) { + push @ret, $k->{$l} if (defined $k->{$l}); + + } + # print "@ret"; + return \@ret; +} +# returns a ref to a list of Event-IDs for a field +# it includes all events on locations +sub field_events{ + my ($self, $loc) = @_; + my $db = $self->{-db}; + my $qloc = $db->quote($loc); + return $db->select_hash('EVENT','ID',0,"GAME=$self->{-game} AND LOCATION=$qloc"); +} + +sub show_event{ + my ($self, $id, $show_field) = @_; + + $show_field = 1 unless defined $show_field and $show_field == 0; + + my ($from, $time, $text, @args) = $self->{-db}->read_event($id); + + # lookup sender + if ($from != 'Game') { + $from = '<a href ="mapframe.epl?field='.$from.'">'."$from</a>"; + } + + + $time = $self->{-db}->relative($time); + $from = "" unless $show_field; + return "<strong>$from $time:</strong> $text"; +} + +sub search_event{ + my ($self,$tag,$location) = @_; + + $tag = 'EVENT_' . $tag; + ($tag,$location) = $self->{-db}->quote_all($tag,$location); + return $self->{-db}->single_hash_select('EVENT',"TAG=$tag and LOCATION=$location"); +} + +# +# +# + +# Should be overloaded by derived class +sub seen_locations{ + my ($self) = @_; + return (); +} + +sub read_field{ + my ($self,$field,$loc) = @_; + $loc = $self->{-db}->quote($loc); + my $stmt = "SELECT $field from MAP where GAME=$self->{-game} AND LOCATION=$loc"; + return $self->{-db}->single_select($stmt); +} + +sub read_player_relations{ + my ($self, $user) = @_; + $user = $self->{-user} unless defined $user; + + # print "user: $user\n"; + my $r = $self->{-db}->select_hash('ALLIANCE', 'OTHER', 'STATUS', + "GAME=$self->{-game} AND PLAYER=$user"); + # print Dumper $r; + return $r; +} + +sub read_single_relation{ + my ($self,$me,$you) = @_; + my $hash = $self->{-db}->single_hash_select('ALLIANCE', + "GAME=$self->{-game} AND ". + "PLAYER=$me AND ". + "OTHER=$you"); + my $ret = $hash->{'STATUS'}; + return $ret ? $ret : 'NEUTRAL'; +} + + +sub reverse_player_relations{ + my ($self) = @_; + return $self->{-db}->select_hash('ALLIANCE', 'PLAYER', 'STATUS', + "GAME=$self->{-game} AND OTHER=$self->{-user}"); +} + +sub read_mobile { + my ($self,$fields,$type,$loc,$only_available) = @_; + $only_available = 0 unless defined $only_available; + # print "read_mobile($fields,$type,$loc,$only_available)\n"; + my $cond = "GAME=$self->{-game} AND LOCATION=$loc"; + if ($only_available > 0) { + $cond .= " AND AVAILABLE=Y"; + } elsif ($only_available < 0) { + $cond .= " AND AVAILABLE=N"; + } + $cond .= " AND TYPE=$type" if $type; + return $self->{-db}->select_array('MOBILE', $fields, $cond); +} + +sub read_mobile_condition{ + my ($self,$fields,$cond,$loc) = @_; + $cond = "GAME=$self->{-game} AND $cond"; + $cond .= " AND LOCATION=$loc" if defined $loc; + $self->{-db}->select_array('MOBILE',$fields,$cond); +} + +# counts available mobiles of TYPE and OWNER (or all owners) in LOCATION +# TODO: we can do this in SQL with "select sum(COUNT) from MOBILE where ..." +sub count_mobile{ + my ($self,$type,$loc,$owner) = @_; + + my $mobs = $self->read_mobile('COUNT,OWNER',$type,$loc,1); + my $count = 0; + for my $mob (@$mobs) { + my $nr = $mob->[0]; + if (defined $owner) { + $count += $nr if $mob->[1] == $owner; + } else { + $count += $nr; + } + } + return $count; +} + +# count all people in $loc from $player +sub count_people{ + my($self,$loc,$player) = @_; + $player = $self->{-user} unless defined $player; + + my $cond = $self->{-db}->quote_condition("GAME=$self->{-game} ". + "AND OWNER=$player ". + "AND AVAILABLE=Y ". + "AND LOCATION=$loc"); + my $stmt = "select sum(COUNT) from MOBILE where $cond"; + my ($ret) = $self->{-db}->single_select($stmt); + return $ret; +} + # stupid, GAME not necessary: ID is unique between different games +sub get_mobile_info { + my ($self, $mob_id, $fields) = @_; + my $stmt = "SELECT $fields from MOBILE where GAME=$self->{-game} AND ID=$mob_id"; + return $self->{-db}->single_select($stmt); +} + +# WARNING: in Aymargeddon, this is overloaded in Aymargeddon.pm +sub own_in_mobile{ + my($self,$loc,$player,$active) = @_; + # $loc = $self->{-db}->quote($loc); + my $cond = "GAME=$self->{-game} AND LOCATION=$loc". + " AND (OWNER=$player OR ADORING=$player)"; + if (defined $active) { + # my $y = $self->{-db}->quote('Y'); + $cond .= " AND AVAILABLE=Y"; + } + return $self->{-db}->select_array('MOBILE','ID',$cond); +} + +sub read_role{ + my ($self,$player,$field) = @_; + my $stmt = "SELECT $field from ROLE where GAME=$self->{-game} AND PLAYER=$player"; + return $self->{-db}->single_select($stmt); +} + +sub get_all_roles{ + my ($self,$role) = @_; + + my $cond = "GAME=$self->{-game}"; + if (defined $role) { + # $role = $self->{-db}->quote($role); + $cond .= " AND ROLE=$role"; + } + my @roles = @{$self->{-db}->select_array('ROLE','PLAYER',$cond)}; + for my $i (0..$#roles) { + $roles[$i] = $roles[$i]->[0]; + } + return @roles; +} + +sub get_speed { + my $self = shift; + my ($ret,$run) = $self->{-db}->single_select("select SPEED, RUNNING from GAME". + " where GAME = $self->{-game} "); + return $run eq 'Y' ? $ret : - $ret; +} + +sub charname{ + my ($self,$player,$do) = @_; + return $self->{-db}->loc('UNASSIGNED') if $player < 1; + my @list = $self->read_role($player, 'NICKNAME'); + return $list[0]; +} + +sub role{ + my ($self,$player) = @_; + return 'OBSERVER' if $player < 1; + my @role = $self->read_role($player, 'ROLE'); + return $role[0]; +} + +1; diff --git a/src/FROGS/HexTorus.pm b/src/FROGS/HexTorus.pm new file mode 100644 index 0000000..6876166 --- /dev/null +++ b/src/FROGS/HexTorus.pm @@ -0,0 +1,352 @@ +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of +# "FROGS" = Framework for Realtime Online Games of Strategy +# +# FROGS 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. +# +# FROGS 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +use strict; +use POSIX qw(ceil floor); + +use FROGS::Config; +use FROGS::Map; + +# We define two classes, which gives an implementation of Maps as a +# HexTorus. + +# TODO: selects to DataBase.pm + +# +# Location. This is a class with two coordinates. +# +package Location; + +sub new{ + my ($class,$x,$y) = @_; + + my $self = { -x => $x, -y => $y }; + bless($self, $class); +} + +sub get{ + my $self = shift; + + return ($self->{-x},$self->{-y}); +} + +sub equal{ + my ($self, $loc) = @_; + my ($x,$y) = $loc->get(); + return ($x == $self->{-x} and $y == $self->{-y}); +} + +sub to_string{ + my $self = shift; + return $self->{-x} . '_' . $self->{-y}; +} + +sub from_string{ + my ($class, $string) = @_; + + # print "CLASS: $class, STRING: $string\n"; + + $string =~ /^(\d+)_(\d+)$/; + my ($x, $y) = ($1,$2); + # print "x: $x, y: $y\n"; + my $self = { -x => $1, + -y => $2,}; + + bless($self, $class); +} + +sub pretty{ + my $loc = shift; + $loc =~ s/^(\d+)_(\d+)$/\($1, $2\)/; + return $loc; +} + +sub is_wellformed{ + my $string = shift; + return 1 if $string =~ /^(\d+)\_(\d+)$/; + return 0; +} + +# +# Map. Hextorus. +# +package HexTorus; +@HexTorus::ISA = qw(Map); + +sub new{ + my $class = shift; + my ($n) = @_; + + my $self = { + -size => $n + }; + + bless($self, $class); +} + + +# returns a list of neighbours of field x,y in +# an hex-torus with size 2n * n +# this function is more effective than the generalised +# distant_neighbours from Map.pm +# TODO BUG: dont return doubbles in turn-around +sub neighbours{ + my $self = shift; + my ($loc) = @_; + + my $n = $self->{-size}; + my ($x,$y) = $loc->get(); + + return (new Location($x,($y-1)%$n), + new Location($x,($y+1)%$n), + new Location(($x-1)%($n*2),$y), + new Location(($x+1)%($n*2),$y), + new Location(($x+1)%($n*2),($y-1)%$n), + new Location(($x-1)%($n*2),($y+1)%$n)); +} + +# returns the neighbour in the given direction. +# direction can be one of qw(NW N NE S SW SE) +sub get_neighbour{ + my ($self, $loc, $dir) = @_; + my ($x,$y) = $loc->get(); + + $dir = uc($dir); + my ($xx,$yy) = ($x,$y); + my $n = $self->{-size}; + if($dir eq 'N'){ + $yy = ($yy - 1) % $n; + }elsif($dir eq 'S'){ + $yy = ($yy + 1) % $n; + }elsif($dir eq 'SW'){ + $xx = ($xx - 1) % ($n * 2); + $yy = ($yy + 1) % $n; + }elsif($dir eq 'SE'){ + $xx = ($xx + 1) % ($n * 2); + }elsif($dir eq 'NW'){ + $xx = ($xx - 1) % ($n * 2); + }elsif($dir eq 'NE'){ + $xx = ($xx + 1) % ($n * 2); + $yy = ($yy - 1) % $n; + }else{ + Util::log("HexTorus::get_neighbour(): unknown direction: $dir\n",0); + return 0; + } + return Location->new($xx,$yy); +} + +# returns the direction from $from to $to (assumes they are neighbours) +sub get_direction{ + my($self,$from,$to) = @_; + + # print "get_direction(".$from->to_string().", ".$to->to_string().")\n"; + + for my $dir (qw(NW N NE S SW SE)){ + my $neighbour = $self->get_neighbour($from,$dir); + # print "test $dir from ".$from->to_string().": ".$neighbour->to_string()."\n"; + return $dir if $to->equal($neighbour); + } + return 0; +} + +# returns the distance between two fields in +# an hex-torus with size 2n * n +sub distance{ + my $self = shift; + my ($loc1,$loc2) = @_; + + my $n = $self->{-size}; + my ($xx,$yy) = $loc1->get(); + my ($x,$y) = $loc2->get(); + + if($xx > $n * 2 or $x > $n * 2 or $yy > $n or $y > $n){ + print "range error in distance ($n,$xx,$x,$yy,$y) !\n"; + return 0; + } + + return 0 if($xx == $x and $yy == $y); + + my $xd = abs($x-$xx); + $xd = 2 * $n - $xd if $xd > $n; + my $sd = abs($x-$xx+$y -$yy) % $n; + $sd = $n - $sd if 2* $sd > $n; + my $yd = abs($y-$yy); + $yd = $n - $yd if 2 * $yd > $n; + + if($xd+$yd+$sd == $n){ + + if(2*$xd == $n) # this occures only for even n + { + # there must be some easier way to distinguish + # fields in se/nw direction from those in sw/ne + # but this works. + my $xp = abs($x-$xx+1); + $xp = 2 * $n - $xp if $xp > $n; + my $sp = abs($x -$xx +$y -$yy +1) % $n; + $sp = $n - $sp if 2* $sp > $n; + return $xd if $xp+$sp != $xd+$sd; + } + $yd = $sd if $sd > $yd; + return $n-$yd; + } + return $xd if 2 * $xd > $n; + return ($xd+$yd+$sd)/2; +} + +# returns a random location +sub random{ + my $self = shift; + my $n = $self->{-size}; + + my $x = POSIX::floor(rand($n*2)); + my $y = POSIX::floor(rand($n)); + + my $loc = new Location($x,$y); + return $loc; +} + +# iterator for all locations +sub next{ + my $self = shift; + my $loc = shift; + my $n = $self->{-size}; + + my ($x, $y) = $loc->get(); + if(++$x > $n * 2) + { + $x = 0; + $y = 0 if(++$y > $n); + } + return new Location($x, $y); +} + +# returns all locations for which $code evals to true +sub grep{ + my $self = shift; + my $code = shift; + + my $n = $self->{-size}; + + my @result; + for my $x (0..($n*2-1)){ + for my $y (0..($n-1)){ + my $loc = new Location($x,$y); + # print $loc->to_string() . "\n"; + if(&$code($loc)){ + push @result, $loc; + } + } + } + return @result; +} + + +sub fill_array{ + my $self = shift; + my @mapping = @_; + + my @array; + for my $terrain (@mapping){ + for my $xy (@{$terrain->[0]}){ + my ($x,$y) = $xy->get(); + $array[$x][$y] = $terrain->[1], + } + } + return \@array; +} + +# TODO: use FROGS::DataBase.pm +sub write_db{ + my ($self, $dbh, $game_id, $game_name, $game_speed, $default, @mapping) = @_; + $default = $dbh->quote($default); + $game_name = $dbh->quote($game_name); + + my $n = $self->{-size}; + + # create game + my $insert_game = "INSERT INTO GAME (GAME,NAME,SIZE,SPEED,FORTUNE,START_MANA) VALUES". + " ($game_id,$game_name,$n,$game_speed,". + "$::conf->{-START_FORTUNE},$::conf->{-START_MANA})"; + print $insert_game ."\n"; + my $h = $dbh->prepare($insert_game); + $h->execute(); + $h->finish(); + + my @db_map = @{$self->fill_array(@mapping)}; + + # fill map + for my $y (0..($n - 1)){ + for my $x ( 0 .. ($n*2-1)){ + my $insert_map; + my $loc = new Location($x,$y); + my $loc_string = $dbh->quote($loc->to_string()); + if(defined $db_map[$x][$y]){ + + $insert_map = "INSERT INTO MAP (GAME,LOCATION,TERRAIN)". + "VALUES ($game_id,$loc_string,". + $dbh->quote($db_map[$x][$y]).")"; + }else{ + + $insert_map = "INSERT INTO MAP (GAME,LOCATION,TERRAIN)". + "VALUES ($game_id,$loc_string,$default)"; + } + # print "$insert_map\n"; + + $dbh->do($insert_map); + } + } +} + +sub write_string{ + my $self = shift; + my $default = shift; + my $default_string = shift; + my @mapping = @_; + + my @ascii_map = @{$self->fill_array(@mapping)}; + + my $n = $self->{-size}; + my $out = "\n"; + for my $y (0..($n - 1)){ + for my $x ( 0 .. ($n*2-1)){ + if(defined $ascii_map[$x][$y]){ + $out .= $ascii_map[$x][$y] ; + }else{ + $out .= $default; + } + $out .= " "; + } + $out .= "\n" . (' ' x ($y +1)); + } + $out .= "\n"; + + $out .= "Legend:\n"; + $out .= "$default_string: \t$default\n"; + for my $terrain (@mapping){ + $out .= $terrain->[2] . ": \t" . + $terrain->[1] . "\n"; + } + return $out; +} + +return 1; diff --git a/src/FROGS/Map.pm b/src/FROGS/Map.pm new file mode 100644 index 0000000..3d72201 --- /dev/null +++ b/src/FROGS/Map.pm @@ -0,0 +1,66 @@ +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of +# "FROGS" = Framework for Realtime Online Games of Strategy +# +# FROGS 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. +# +# FROGS 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# +# This file holds a baseclass for the topology of the game. +# All methods here are independent of a concrete topology. +# but they require, that such dependent functions exists, +# so this base class did not work if there is no derived class. +# +# Derived classes have to implement the following functions +# +# grep() - return a list of all locations with true evaluation of sub +# neighbours() - returns a list of all neigbours of location +# distance() - returns the distance between two locations +# +# have a look at HexTorus.pm to see an example + + +package Map; + +use strict; + +# returns all locations +sub get_all{ + my $self = shift; + + return $self->grep(sub{1;}); +} + +# returns all locations with distance <= dist arround loc +sub distant_neighbours{ + my ($self,$loc,$dist) = @_; + + # for performance reason + # TODO: do this only, if neighbours() is avaiable in the derived class + return $self->neighbours($loc) if $dist == 1; + + return $self->grep(sub{ + my $loc2 = shift; + return $self->distance($loc,$loc2) <= $dist;}); + +} + +1; + + diff --git a/src/FROGS/Util.pm b/src/FROGS/Util.pm new file mode 100644 index 0000000..581e080 --- /dev/null +++ b/src/FROGS/Util.pm @@ -0,0 +1,151 @@ +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of +# "FROGS" = Framework for Realtime Online Games of Strategy +# +# FROGS 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. +# +# FROGS 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# +# Here we gather some utility-functions +# + +use strict; +use FROGS::DataBase; +use FROGS::Config qw ($conf); + +package Util; +use Data::Dumper; + +# parse the command-line (or any other string-array) +# and overwrites $::conf with the new values +# example: ./scheduler.pl -DURATION-PRAY=1000 -MANA-BLESS_PRIEST=10 +sub overwrite_config{ + my @arr = @_; + for my $arg (@arr){ + my ($left,$right) = split /=/,$arg; + my @parts = split /-/, $left; + + # TODO: generalization + if($parts[2]){ + $::conf->{"-$parts[1]"}->{"-$parts[2]"} = $right; + }else{ + $::conf->{"-$parts[1]"} = $right; + } + } +} + +# returns 1 if $scalar is in @list +sub is_in{ + my ($scalar, @list) = @_; + + for my $le (@list) { + return 1 if $le eq $scalar; + } + return 0; +} + +# returns all elements of @$A which are _not_ in @$B +# in an array reference +sub without{ + my ($A, $B) = @_; + + my %h = (); + for my $b (@$B){ + $h{$b} = 1; + } + + my @A_without_B = (); + for my $a (@$A){ + push @A_without_B, $a unless exists $h{$a}; + } + return \@A_without_B; +} + +sub log{ + my ($string,$level) = @_; + + my $abslevel = $level; + my $do = 0; + + # TODO: dirty hack, use caller() instead + if($0 eq '-e'){ + $string .= "<p>"; + $do = 1 if $::conf->{-EPL_DEBUG} >= $abslevel; + }else{ + $do = 1 if $::conf->{-DEBUG} >= $abslevel; + + if($::conf->{-FULL_DEBUG_FILE}){ + # FULL_LOG in file + if($level >= 0){ + print FULL_LOG "$string\n"; + }else{ + print FULL_LOG "$string"; + } + } + } + # negativ values for level prints no newline + if($do){ + if($level >= 0){ + print "$string\n"; + }else{ + print "$string"; + } + } +} + +sub open_log{ + my $file = $::conf->{-FULL_DEBUG_FILE}; + open(FULL_LOG,">$file") or die "can't open $file: $!"; +} + +sub close_log{ + close FULL_LOG; +} + +sub min{ + my @list = @_; + + my $min = 99999999; + for my $elem (@list){ + $min = $elem if $elem < $min; + } + return $min; +} + +sub max{ + my @list = @_; + + my $max = -99999999; + for my $elem (@list){ + $max = $elem if $elem > $max; + } + return $max; +} + +# returns a shuffled list +sub shuffle { + my $array_ref = shift; + + my @shuffled = sort { int(rand(3)) - 1 } @$array_ref; + + return \@shuffled; +} + +1; + diff --git a/src/FROGS/scheduler.pl b/src/FROGS/scheduler.pl new file mode 100644 index 0000000..ea91ff2 --- /dev/null +++ b/src/FROGS/scheduler.pl @@ -0,0 +1,97 @@ +#!/usr/bin/perl -w +######################################################################### +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of +# "FROGS" = Framework for Realtime Online Games of Strategy +# +# FROGS 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. +# +# FROGS 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# +# scheduler daemon +# +# usage: +# ./scheduler.pl [conf-parameter]=[value] ... +# example: +# ./scheduler.pl -DURATION-PRAY=1000 -DURATION-PRODUCE=1000 + +use strict; +use lib qw(..); +use FROGS::DataBase; +use FROGS::Command; +use FROGS::Config qw ($conf); +use Data::Dumper; + +$|=1; + +Util::open_log(); + +# read command line +Util::overwrite_config(@ARGV); + +my $KEYCOL="SUBMIT"; + +my $db= new DataBase; +# $db->nowrite(); +require $::conf->{-COMMANDS}; +my $now = $db->now(); +Util::log("\n$now Scheduler started...",0); +loop(); +exit; + +sub loop { + # read next using our db connection (complicated due to poor SQL + # implemention of MYSQL :-/ + my $nulldate = $db->quote('0000-00-00 00:00:00'); # TODO: ugly and unportable :-( + my $nullcond = "(DONE IS NULL OR DONE=$nulldate)"; + my $count = 0; + while (1) { + $count++; + $db->commit(); # ??? WHY IS THIS NECESSARY TO SEE COMMANDS FROM CLIENTS ??? + my ($minexec) = $db ->single_select("SELECT min( exec ) FROM COMMAND ". + "WHERE $nullcond and EXEC <= NOW()"); + $minexec = $db ->quote($minexec); + my ($id) = $db ->single_select("SELECT min(id) FROM COMMAND ". + "WHERE $nullcond and EXEC = $minexec"); + $id= $db ->quote($id); + my $command_entry = $db ->single_hash_select("COMMAND", + "EXEC = $minexec and ID = $id "); + + # delete outdated events + $db->delete_from('EVENT','TIME < NOW()') if $::conf->{-DELETE_OLD_EVENTS}; + + if (! defined $command_entry ) { + # sleep if no command in db + sleep ($::conf->{-SCHEDULER_SLEEP}); + Util::log('.',-1); + + if($count % $::conf->{-LOG_TIME_IN_LOOP} == 0){ + my $now = $db->now(); + Util::log("\n###\n### $now: counted $count loops\n###\n",1); + } + next; + } + + # create command object + my $command = $command_entry->{"COMMAND"}->new($command_entry,$db); + # execute command + if($command){ + $command->execute(); + $db->commit; + } + } +}; + diff --git a/src/FROGS/speed_scheduler b/src/FROGS/speed_scheduler new file mode 100644 index 0000000..af5c12d --- /dev/null +++ b/src/FROGS/speed_scheduler @@ -0,0 +1,15 @@ + ./scheduler.pl -DURATION-PRAY=1000 -DURATION-PRODUCE_PRIEST=1000 \ + -DURATION-PRODUCE_WARRIOR_HOME=1000 \ +-DURATION-PRODUCE_PRIEST_HOME=1000 \ +-DURATION-MOVE_WARRIOR=1 \ +-DURATION-MOVE_PRIEST=1 \ +-DURATION-MOVE_HERO=1 \ +-DURATION-MOVE_ARK=1 \ +-DURATION-FIGHT_EARTHLING=1 \ +-DURATION-FIGHT_GOD=1000 \ +-DURATION-PLAGUE=1000 \ +-DURATION-PRODUCE_WARRIOR=1000 \ +-DURATION-FLOOD=1 \ +-DURATION-BUILD_TEMPLE=1 \ +-DURATION-BUILD_ARK=1 # -SEND_MESSAGE_TO_FIELD=0 + diff --git a/src/FROGS/start_scheduler b/src/FROGS/start_scheduler new file mode 100644 index 0000000..63ff512 --- /dev/null +++ b/src/FROGS/start_scheduler @@ -0,0 +1,2 @@ +killall scheduler.pl +nohup /home/benni/aymargeddon/current/src/FROGS/scheduler.pl >> /home/benni/aymargeddon/current/src/FROGS/++out 2>&1 & diff --git a/src/check.pl b/src/check.pl new file mode 100755 index 0000000..6959d52 --- /dev/null +++ b/src/check.pl @@ -0,0 +1,152 @@ +#!/usr/bin/perl -w +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of "Last days of Aymargeddon" +# +# Aymargeddon 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. +# +# Aymargeddon 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# +# +# checks the integrity of the database. +# +# usage: ./check.pl [-l] [list of checks] +# no args: do all checks +# -l: lists all avaiable checks +# -h: help +# list of checks: do only this checks + +use strict; +$|=1; +use DBI; +use Data::Dumper; +use POSIX qw(floor ceil); +use Term::ReadLine; + +use FROGS::HexTorus; +use FROGS::Check; +use FROGS::Config; + +$::conf->{-FULL_DEBUG_FILE} = 0; +# Util::open_log(); + +# +# Aymargeddon-specific behaviour +# + +# TODO: should also check, if the location is valid in this map +my $location_wellformed_check = sub { + my $loc = shift; + my $wf = Location::is_wellformed($loc); + print "$loc is in bad form! " unless $wf; + return $wf; +}; + +my $fight_and_occupant = sub { + my $db = shift; + my $dbh = $db->{-dbh}; + + my $stmt = 'SELECT GAME,LOCATION,OCCUPANT,ATTACKER,TERRAIN,HOME FROM MAP WHERE 1'; + my $map = $dbh->selectall_arrayref($stmt); + + # for every field in MAP + for my $field (@$map){ + my ($game,$loc,$occ,$att,$terrain,$home) = @$field; + Util::log("testing field $loc, game $game: occupant $occ, attacker: $att",1); + + # read all earthling mobiles in field + my $cond = "LOCATION='$loc' AND GAME=$game AND AVAILABLE='Y'". + " AND (TYPE='WARRIOR' OR TYPE='PRIEST' OR TYPE='HERO' OR TYPE='PROPHET')"; + # my $qcond = $db->quote_condition($cond); + $stmt = "SELECT OWNER FROM MOBILE WHERE $cond"; + my $mobiles = $dbh->selectall_arrayref($stmt); + + # search for earthlings + my @earthlings = (); + my $earthlings = {}; + for my $mob (@$mobiles){ + my ($own) = @$mob; + next if exists $earthlings->{$own}; + $earthlings->{$own} = 1; + push @earthlings, $own; + } + # print Dumper \@earthlings; + + if($occ){ + return "game $game: no earthlings in field $loc with occupant $occ.\n" + if ($#earthlings == -1 and not ($terrain eq 'CITY' and $home)); + }else{ + return "game $game: earthlings in field $loc without occupant.\n" + if $#earthlings > -1; + } + + if($att){ + return "game $game: only one earthling in field $loc from $occ, ". + "attacked from $att\n" if $#earthlings == 0; + }else{ + return "game $game: more than one earthling in peaceful field $loc." + if $#earthlings > 0; + next if $#earthlings < 0; + return "game $game: occupant $occ is not the only earthling $earthlings[0]". + " in field $loc" + if $occ != $earthlings[0]; + } + } + return 0; +}; + + +# list of checks +# every check consists of ID,behaviour +# behaviour is one of A_IN_B, LOGIK or UNIVERSAL + +my $check = { + -GAME_EXISTS_FOR_MAP => + ['A_IN_B', ['MAP','GAME','GAME','GAME']], + -GAME_EXISTS_FOR_ALLIANCE => + ['A_IN_B', ['ALLIANCE','GAME','GAME','GAME']], + -GAME_EXISTS_FOR_COMMAND => + ['A_IN_B', ['COMMAND','GAME','GAME','GAME']], + -GAME_EXISTS_FOR_GOD => + ['A_IN_B', ['GOD','GAME','GAME','GAME']], + -GAME_EXISTS_FOR_GOD => + ['A_IN_B', ['GOD','GAME','GAME','GAME']], + -GAME_EXISTS_FOR_MESSAGE => + ['A_IN_B', ['MESSAGE','GAME','GAME','GAME']], + -GAME_EXISTS_FOR_ROLE => + ['A_IN_B', ['ROLE','GAME','GAME','GAME']], + -GAME_EXISTS_FOR_MOBILE => + ['A_IN_B', ['MOBILE','GAME','GAME','GAME']], + + -LOCATION_WELLFORMED_IN_MAP => + ['LOGIC',['MAP',['LOCATION'],$location_wellformed_check]], + -LOCATION_WELLFORMED_IN_MOBILE => + ['LOGIC',['MOBILE',['LOCATION'],$location_wellformed_check]], + # TODO?: implement write last_temple + # -LAST_TEMPLE_WELLFORMED_IN_GAME => + # ['LOGIC',['GAME',['LAST_TEMPLE'],$location_wellformed_check]], + + -FIGHT_AND_OCCUPANT => + ['UNIVERSAL', $fight_and_occupant], + + }; + +my $checker = Check->new(); +$checker->check_all($check); + + diff --git a/src/create.pl b/src/create.pl new file mode 100755 index 0000000..69794a7 --- /dev/null +++ b/src/create.pl @@ -0,0 +1,637 @@ +#!/usr/bin/perl -w +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of "Last days of Aymargeddon" +# +# Aymargeddon 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. +# +# Aymargeddon 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# +# +# creates the world to destroy +# +# usage: ./create.pl [number of eartlings] +# +# + +# TODO: use FROGS/DataBase.pm instead of DBI.pm + +use strict; + +$| = 1; + +use DBI; +use Data::Dumper; +use POSIX qw(floor ceil); +use Term::ReadLine; + my $t = Term::ReadLine->new('test'); + +use FROGS::HexTorus; +use FROGS::Config qw($conf); +use FROGS::DataBase; +use FROGS::Game; + +Util::open_log(); + +my $earthlings = $ARGV[0] || 10; # number of earthlings + +my $dont_ask = defined $ARGV[1] ? 1 : 0; + +my $db_source = $::conf->{-DB_SOURCE}; +my $db_user = $::conf->{-DB_USER}; +my $db_passwd = $::conf->{-DB_PASSWD}; + +my $ascii = {-pole => '@', + -city => '+', + -home => '#', + -water => '~', + -island => '°', + -mountain => '^', + -plain => '\''}; + +# set to 0 to not change size of world during generation +# set to positive value to set the number of itterations need to pumpup +my $pump_up_world = 10; + +# TODO: maybe to small? +my $n = ceil(sqrt($earthlings * 7)); # size of world + +my $pole_count = floor(sqrt($n)); +my $min_pole_distance = ceil($n/2); +my $water_count = floor($n*$n/2); +#TODO: number of islands should depend on players, not on size +my $island_count = floor($water_count/3); +my $min_home_distance = $::conf->{-MIN_DISTANCE_HOME}; +my $min_mountain_distance = $::conf->{-MIN_DISTANCE_MOUNTAIN}; +my $wanted_mountain_distance = $::conf->{-WANTED_DISTANCE_MOUNTAIN}; +my $min_water_distance = $::conf->{-MIN_DISTANCE_MOUNTAIN_FROM_WATER}; +my $city_count = $earthlings * 4; +my $mountain_count = floor($earthlings); + +my $nn = 0; +my $map; +while (1) { + if ($pump_up_world and $nn > $pump_up_world) { + $n++; + print "*** World to small! Make it bigger! New size $n.***\n"; + $nn = 0; + } + my $not_enough_room = 0; + $map = new HexTorus($n); + $pole_count = floor(sqrt($n)); + $min_pole_distance = ceil($n/2); + $water_count = floor($n*$n/2); + $island_count = floor($water_count/3); + + # TODO: uggly structure + my $print = 0; + print "generate poles ...\n"; + my @pole = distribute($pole_count,$min_pole_distance, + $min_pole_distance,$min_pole_distance); + $not_enough_room = 1 unless $pole[0]; + my (@water,@islands,@home,@mountains,@not_cities,@cities); + unless ($not_enough_room){ + print "generate water ...\n"; + @water = flood($water_count,@pole); + } + unless ($not_enough_room){ + print "generate islands ...\n"; + @islands = vulcano($island_count, \@water, \@pole); + } + unless ($not_enough_room){ + print "generate mountains ...\n"; + @mountains = distribute($mountain_count,$min_water_distance, + $min_mountain_distance,$wanted_mountain_distance,[],@water); + $not_enough_room = 1 unless $mountains[0]; + } + # print print_list(@mountains); + unless ($not_enough_room){ + print "generate homecitys ...\n"; + + for my $i (1..50){ + @home = homeland(@mountains,@pole,@water,@islands); + # $print = 1 unless $#home<$#mountains; + last unless $#home<$#mountains; + print " RETRY...\n"; + my $mref = Util::shuffle(\@mountains); + @mountains = @$mref; + } + print "\n"; + $not_enough_room = 1 if $#home<$#mountains; + } + + unless ($not_enough_room){ + print "generate citys ...\n"; + @not_cities = (@water,@pole,@mountains,@islands,@home); + @cities = build($city_count,\@home,\@not_cities); + $not_enough_room = 1 unless $cities[0]; + } + + + if (not $not_enough_room or $print) { + #print "Pole: " . print_list(@pole); + #print "Water: " . print_list(@water); + #print "Islands: " . print_list(@islands); + #print "Mountains: " . print_list(@mountains); + #print "Cities: " . print_list(@cities); + #print "Homes: " . print_list(@home); + + print "Earthlings: $earthlings\n". + "Gods: " . ($earthlings/2) . "\n". + "Size of world: $n\n". + "Number of poles: $pole_count\n". + "Minimum pole distance: $min_pole_distance\n". + "Water: $water_count\n". + "Islands: $island_count\n". + "Citys: $city_count\n". + "Plain: " . ( ($n * $n * 2) - ($water_count + $pole_count + + $earthlings + $city_count)) . "\n"; + + print $map->write_string($ascii->{-plain},"Plain", + [\@pole,$ascii->{-pole},"Pole"], + [\@water,$ascii->{-water},"Water"], + [\@islands,$ascii->{-island},"Islands"], + [\@home,$ascii->{-home},"Home"], + [\@mountains,$ascii->{-mountain},"Mountains"], + [\@cities,$ascii->{-city},"Cities"]); + die if $print; + } else { + $nn++; + print "\nNot enough room! Try again ...\n"; + next; + } + + my $r = $dont_ask ? 'y' : + $t->readline('Wrote this world to database? (n/q/[name_of_game])'); + + if ($r =~ /^q$/i) { + exit; + } elsif ($r =~ /^n$/i) { + next; + } else { + my $speed = $dont_ask ? 3600 : + $t->readline('Speed of game in seconds per game step: '); + + my $dbh = DBI->connect("dbi:$db_source",$db_user,$db_passwd, + { + 'RaiseError' => 1,'AutoCommit' => 0}); + + # TODO: use DataBase::find_first_free("GAME","GAME") + + my $table = $dbh->selectall_arrayref("select GAME from GAME"); + my @game_ids = sort {$a <=> $b} (map {$_->[0]} @$table); + + my $game = 1; + for my $try (@game_ids) { + last if $game < $try; + $game = $try + 1; + } + + print "Erste Freie Game ID: $game\n"; + my $db = DataBase->new($dbh); + my $aymgame = Game->new($game,-1,$db); + + $map->write_db($dbh,$game,$r,$speed,'PLAIN', + [\@pole,"POLE"], + [\@water,"WATER"], + [\@islands,"ISLE"], + [\@home,"CITY"], + [\@mountains,"MOUNTAIN"], + [\@cities,"CITY"]); + + # mark home cities and holy mountains + for my $home (@home, @mountains) { + my $lo = $dbh->quote($home->to_string()); + my $cmd = "UPDATE MAP SET HOME=-1 where GAME=$game AND LOCATION=$lo"; + $dbh->do($cmd); + } + + # set home cities occupied + # insert PRODUCE Commands for Homecitys + for my $home (@home) { + my $l = $dbh->quote($home->to_string()); + my $c = "UPDATE MAP SET OCCUPANT=-1 where GAME=$game AND LOCATION=$l"; + $dbh->do($c); + + $aymgame->insert_command('PRODUCE','ROLE=-1',$home->to_string()); + } + + # make one of the poles startup aymargeddon + my $aym = $pole[rand($#pole + 1)]; + my $ter = $dbh->quote('AYMARGEDDON'); + my $loc = $dbh->quote($aym->to_string()); + my $comd = "UPDATE MAP SET TERRAIN=$ter where GAME = $game AND LOCATION=$loc"; + $dbh->do($comd); + + # check some values + $::conf->{-DEBUG} = 0; + print "Check in the database:\n"; + my $m_count = $db->count('MAP', "GAME=$game AND TERRAIN=MOUNTAIN"); + my $h_count = $db->count('MAP', "GAME=$game AND TERRAIN=CITY AND HOME=-1"); + my $o_count = $db->count('MAP', "GAME=$game AND OCCUPANT=-1"); + print "Mountains: " . $m_count; + print "\nCitys: " . $db->count('MAP', + "GAME=$game AND TERRAIN=CITY"); + print "\nHomes: " . $h_count; + print "\nIslands: " . $db->count('MAP', + "GAME=$game AND TERRAIN=ISLE"); + print "\nPoles: " . $db->count('MAP', + "GAME=$game AND TERRAIN=POLE"); + print "\nAymargeddon: " . $db->count('MAP', + "GAME=$game AND TERRAIN=AYMARGEDDON"); + print "\nWater: " . $db->count('MAP', + "GAME=$game AND TERRAIN=WATER"); + print "\nPlain: " . $db->count('MAP', + "GAME=$game AND TERRAIN=PLAIN"); + print "\nOccupied: " . $o_count; + print "\n"; + + if($o_count != $h_count or $h_count != $m_count or $m_count != $o_count){ + print "homes: ". print_list(@home) . "\nmountains: ". + print_list(@mountains) . "\ncities: " . print_list(@cities) . "\n"; + my $boesewichter = $db->select_array('MAP', + 'LOCATION', + "GAME=$game AND HOME=-1 AND ". + "OCCUPANT=0 AND TERRAIN=CITY"); + print "boesewichter: "; print map $_->[0] . ", ", @$boesewichter;print "\n"; + } + + $dbh->commit(); + $dbh->disconnect(); + + + exit; + } +} + +# distributes homecitys near mountains +sub homeland{ + my @mountains = @_; + + my %mountains = (); + for my $m (@mountains){ + $mountains{$m->to_string()} = 1; + } + + my %homes = (); + for my $m (@mountains){ + my @neighbours = $map->neighbours($m); + + my $home; + while($#neighbours >= 0){ + my $rand = rand($#neighbours + 1); + $home = $neighbours[$rand]; + my @home_neighbours = $map->neighbours($home); + my ($m_count,$h_count) = (0,0); + for my $hn (@home_neighbours){ + $h_count++ if exists $homes{$hn->to_string()}; + $m_count++ if exists $mountains{$hn->to_string()}; + } + if($h_count == 0 and $m_count == 1){ + my $valid = 1; + for my $h (keys %homes){ + my $d = $map->distance(Location->from_string($h),$home); + if($d < $::conf->{-MIN_DISTANCE_HOME}){ + $valid = 0; + } + } + if($valid){ + $homes{$home->to_string()} = 1; + print "#"; + last; + } + } + splice @neighbours,$rand,1; + } + last unless $#neighbours >= 0; + } + my @ret = (); + for my $h (keys %homes){ + push @ret, Location->from_string($h); + } + return @ret; +} + +sub build{ + my ($count,$homes,$exclude) = @_; + + my %ex; + if ($exclude) { + for my $f (@$exclude) { + $ex{$f->to_string()} = 1; + } + } + + # build two cities in neihgbourhood of each home + my %cities = (); + for my $home (@$homes){ + # print "build citys for " . $home->to_string() . ": "; + my @neighbours = $map->neighbours($home); + + # exclude non buildable terrain + my $i = 0; + for my $n (@neighbours){ + my $nstr = $n->to_string(); + if($ex{$nstr}){ + splice @neighbours,$i,1; + } + $i++; + } + + # build citys + my $cities = $::conf->{-NEIGHBOUR_CITIES}; + while($cities){ + my $r = rand($#neighbours+1); + my $rstr = $neighbours[$r]->to_string(); + # print " build city in $rstr\n"; + $cities{$rstr} = 1; + $ex{$rstr} = 1; + splice @neighbours,$r,1; + $cities--; + } + + # exclude all remaining neighbours + for my $n (@neighbours){ + $ex{$n->to_string()} = 1; + } + } + + # distribute the remaining cities to fields, which are not neighbours of a home + while($count){ + my $random = $map->random()->to_string(); + unless(exists $ex{$random}){ + $ex{$random} = 1; + $cities{$random} = 1; + $count--; + } + } + + # TODO: clustering check, no more than n in 2distance + + return map Location->from_string($_), keys %cities; +} + +# DEPRECATED, this function is no longer in use! +# returns all fields, which are plain and have +# - 4 or more neighbours ISLAND or WATER +# - no city as neighbour +# - more than 2 citys as neighbour +# - more than 7 citys with distance 2 +sub bad_home{ + my($water,$islands,$pole,$cities,$mountains) = @_; + + print "look for bad home locations ...\n"; + + # my @m = @$mountains; print "mountains: $#m\n"; + + # reorganize data into hashes + my %ex; + for my $f (@$water,@$islands,@$pole){ + $ex{$f->to_string()} = 1; + } + my %cit; + for my $c (@$cities){ + $cit{$c->to_string()} = 1; + } + my %mount; + for my $m (@$mountains){ + $mount{$m->to_string()} = 1; + } + + # for all fields + my %ret; + for my $x (0..($n*2-1)){ + for my $y (0..($n-1)){ + my $lstring = "$x\_$y"; + next if exists $ex{$lstring}; + next if exists $cit{$lstring}; + print "."; + my $loc = new Location($x,$y); + + # look in the neighboorhood + my @neighbours = $map->neighbours($loc); + my ($city,$water,$mount) = (0,0,0); + for my $n (@neighbours){ + $city++ if exists $cit{$n->to_string()}; + $water++ if exists $ex{$n->to_string()}; + # $mount++ if exists $mount{$n->to_string()}; + } + # $ret{$lstring} = 'no mountain in neighbourhood' if $mount == 0; + $ret{$lstring} = 'no city in neighbourhood' if $city == 0; + $ret{$lstring} = 'more than 3 cities in neighbourhood' if $city > 3; + $ret{$lstring} = 'to much water in neighbourhood' if $water > 3; + next if $ret{$lstring}; + + # look in distance 2 + my @dist_neigh = $map->distant_neighbours($loc,2); + $city = 0; $mount = 0; + for my $n (@dist_neigh){ + $city++ if exists $cit{$n->to_string()}; + $mount++ if exists $mount{$n->to_string()}; + } + # print "m: $mount, c: $city\n"; + $ret{$lstring} = 'more than 7 cities in distance 2' if $city > 7; + $ret{$lstring} = 'less than 2 cities in distance 2' if $city < 2; + $ret{$lstring} = 'no mountain in distance 2' unless $mount; + } + } + print "\n"; + my @ret; + my %stat; + for my $r (keys %ret){ + $stat{$ret{$r}}++; + push @ret, Location->from_string($r); + } + print Dumper \%stat; + return @ret; +} + +sub vulcano{ + my ($count, $w,$p) = @_; + my @w = @$w; + my @p = @$p; + + my @islands; + + while ($count) { + my $water_field = floor(rand($#w) + 1); + my $wf = $w[$water_field]; + + my $to_close = 0; + for my $p (@p) { + $to_close = 1 if($map->distance($p,$wf) < 2); + } + next if $to_close; + + splice @w,$water_field,1; + push @islands, $wf; + $count--; + } + return @islands; +} + +sub flood{ + my ($count, @w) = @_; + # print "flood($count,@w)\n"; + + # flood neighbours + my @new_w; + for my $pole (@w) { + push @new_w, $map->neighbours($pole); + } + $count -= $#new_w + 1; + return @new_w unless $count > 0; + + my %w; + for my $w (@w,@new_w) { + $w{$w->to_string()} = 1; + } + @w = @new_w; + + while ($count) { + # print "$count "; + # get a random water field + my $water_field = floor(rand($#w) + 1); + my $wf = $w[$water_field]; + # get neigbours without water + my @nb = $map->neighbours($wf); + my @nb_new; + for my $nb (@nb) { + unless (exists $w{$nb->to_string()}) { + push @nb_new, $nb; + } + } + @nb = @nb_new; + + if ($#nb > 0) { + # get a random neigbour + my $rn = floor(rand($#nb) + 1); + my $rnr = $nb[$rn]; + push @w,$rnr; + $w{$rnr->to_string()} = 1; + $count --; + } + } + return @w; +} + +# distributes $count locations at the map in minimal distance from +# fields not at exclude +# TODO: should be in Map.pm. +# TODO: should incorporate build() and vulcano() +# TODO: make shure there is really no field left. +sub distribute{ + my ($count,$dist,$min_selfdist,$wanted_selfdist,$exclude,@fields) = @_; + my $fields_distance = 2; + my $selfdist = $wanted_selfdist; + + # print "minself: $min_selfdist, wantedself: $wanted_selfdist\n"; + + # print "fields: @fields\n"; + + #print "Exclude: " . print_list(@$exclude); + + my @return_fields; + + my %ex; + if ($exclude) { + for my $f (@$exclude) { + $ex{$f->to_string()} = 1; + } + } + + my $loop = $earthlings * 10; + my $maxloop = $loop; + my $short_allowed = 0; + while ($loop and $count) { + # while($count){ + my $r = $map->random(); + my $valid = 1; + # if ($valid) { + for my $xy (@fields) { + my $d = $map->distance($r,$xy); + my ($x,$y) = $xy->get(); + + if ($d < $dist) { + $valid = 0; + last; + } + } + my $short_count = 0; + for my $xy (@return_fields) { + my $d = $map->distance($r,$xy); + my ($x,$y) = $xy->get(); + + if ($d < $selfdist) { + if($d >= $selfdist - 1 and $short_count < 1 and $short_allowed){ + $short_count++; + print $short_count; + }else{ + $valid = 0; + last; + } + } + } + for my $x (@$exclude){ + if($r->to_string() eq $x->to_string()){ + $valid = 0; + last; + } + } + # } + + if ($valid) { + # push @fields, $r; + push @return_fields, $r; + $count--; + print "+"; + } else { + $loop--; + # print "-"; + if($loop <= 0 and ($selfdist > $min_selfdist)){ + $loop = $maxloop; + # $selfdist--; + # print $selfdist; + $short_allowed = 1; + print "S"; + } + + next; + } + # print "c: $count, l: $loop\n"; + # } + } + + print "\n"; + unless($loop){ + print "need still room for $count locations\n"; + return 0; + } + return @return_fields; +} + +sub print_list{ + my @f = @_; + my $string; + for my $l (@f){ + $string .= $l->to_string() . ', '; + } + $string .= "\n"; + return $string; +} + diff --git a/src/debug.pl b/src/debug.pl new file mode 100755 index 0000000..636b73f --- /dev/null +++ b/src/debug.pl @@ -0,0 +1,59 @@ +#!/usr/local/bin/perl -w +########################################################################## +# +# Copyright (c) 2003 Aymargeddon Development Team +# +# This file is part of "Last days of Aymargeddon" +# +# Aymargeddon 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. +# +# Aymargeddon 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., 675 +# Mass Ave, Cambridge, MA 02139, USA. +# +########################################################################### +# + +# +# +# creates the world to destroy +# +# usage: ./create.pl [number of eartlings] +# +# + +# TODO: use FROGS/DataBase.pm instead of DBI.pm + +use strict; + +use DBI; +use Data::Dumper; +use POSIX qw(floor ceil); +use Term::ReadLine; + +use FROGS::HexTorus; + +my $n = 16; +my $map = new HexTorus($n); +my $out = "\n"; +for my $y (0..($n - 1)){ + for my $x ( 0 .. ($n*2-1)){ + + my $d = + $map->distance(Location->new(5,0), + Location->new($x,$y)); + $d = "0$d" if $d < 10; + $out .= "$d "; + } + $out .= "\n" . (' ' x ($y +1)); +} +$out .= "\n"; + +print $out; diff --git a/src/test.pl b/src/test.pl new file mode 100755 index 0000000..e8c605f --- /dev/null +++ b/src/test.pl @@ -0,0 +1,62 @@ +use FROGS::DataBase; +# use Aymargeddon; +# use DBI; +use strict; +use Data::Dumper; +use Date::Calc qw(Time_to_Date); + +use FROGS::Command; + +use FROGS::Config qw($conf); + +$| = 1; + +my $d = DataBase->new(); +# $d->nowrite(); + +my $dbhash = +# {'LOCATION' => '2_0', +# 'COMMAND' => 'BUILD_TEMPLE', +# 'ARGUMENTS' => 'MOBILE=1', +# 'PLAYER' => 1, +# 'GAME' => 1, +# 'ID' => 1007 +# }; + {'LOCATION' => '11_3', + 'COMMAND' => 'PRODUCE', + 'ARGUMENTS' => 'ROLE=-1', + 'PLAYER' => -1, + 'GAME' => 4, + 'ID' => 1007, + }; + + +# print Dumper $dbhash; + +require "AymCommand.pm"; + +my $c = $dbhash->{'COMMAND'}->new($dbhash,$d); + +# print "is valid\n" if $c->is_valid(); +$c->{-phase} = 1; +my $fp = $c->first_phase(); + +if ($fp){ + print "first phase correct. duration: $c->{-duration}\n"; + $c->{-phase} = 2; + print "second phase correct\n" if $c->second_phase(); +}else{ + print "no second phase\n"; +} + +$d->commit(); + +# $d->{-dbh}->disconnect(); + +# print Dumper $c; + + + + + + diff --git a/src/test2.pl b/src/test2.pl new file mode 100755 index 0000000..9197c44 --- /dev/null +++ b/src/test2.pl @@ -0,0 +1,37 @@ +use strict; +use FROGS::DataBase; +use Data::Dumper; +use Aymargeddon; + +$| = 1; + +use FROGS::Config qw($conf); + +$::conf->{-DEBUG} = 2; + +# $::conf->{-DEBUG} = 2; + +my $db = new DataBase(); + +$db->update_hash('MOBILE', + "LOCATION=0_1", + {'COUNT' => 'COUNT + 1'},'noquote'); + +$db->commit(); + +# print $db->relative("2004-05-13 03:40:37") ."\n"; + +#my $aym = new Aymargeddon(1,3,$db,'DE'); + +#print $aym->show_statistic(); + +# print $aym->read_single_relation(1,2). "\n"; + +#print "place is: $place.\n"; + +# print Dumper $::conf; +# exit; + +#my $d = DataBase->new(); +#$d->nowrite(); + diff --git a/var/LOCALIZE.sql b/var/LOCALIZE.sql new file mode 100644 index 0000000..5ea1bce --- /dev/null +++ b/var/LOCALIZE.sql @@ -0,0 +1,512 @@ +-- MySQL dump 9.09 +-- +-- Host: localhost Database: RAGNAROEK +-- ------------------------------------------------------ +-- Server version 4.0.16-log + +-- +-- Table structure for table `LOCALIZE` +-- + +DROP TABLE IF EXISTS LOCALIZE; +CREATE TABLE LOCALIZE ( + TAG varchar(25) NOT NULL default '', + LANGUAGE enum('DE','EN') NOT NULL default 'DE', + TEXT text NOT NULL, + PRIMARY KEY (TAG,LANGUAGE) +) TYPE=InnoDB; + +-- +-- Dumping data for table `LOCALIZE` +-- + +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ADJ_ADORING','DE',', Anbeter von'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ADJ_ADORING','EN',' adoring'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ADJ_HERE','DE','Hier'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ADJ_HERE','EN','Here'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ART_DAT_PL','DE','den'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ART_DAT_PL','EN','the'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('BATTLE_REPORT','DE','Kampfbericht für'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('BATTLE_REPORT','EN','Battle report for'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('BUILD_ARK','DE','Arche bauen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('BUILD_ARK','EN','build ark'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CASUALTIES_OF_PESTILENTIA','DE','Opfer der Pestilentia'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CASUALTIES_OF_PESTILENTIA','EN','Casualties of pestilentia'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CHANGE_PASSWORD','DE','Wenn Du Dein Passwort ändern willst, gib das neue Passwort bitte hier zweimal ein.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CHANGE_PASSWORD','EN','If you want to change your password, please insert it here two times.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CH_LUCK','DE','Glücksfaktor ändern'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CH_LUCK','EN','change fortune'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CH_STATUS','DE','Status ändern'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CH_STATUS','EN','change status'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CITY_HEADING','DE','Rangfolge der Erdlinge:'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CITY_HEADING','EN','Ranking of earthlings:'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BLESS_HERO','DE','Held weihen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BLESS_HERO','EN','bless hero'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BLESS_HERO_MSG','DE','Anzahl neue Helden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BLESS_HERO_MSG','EN','Number of new heros'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BLESS_PRIEST','DE','Priester weihen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BLESS_PRIEST','EN','bless priest'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BLESS_PRIEST_MSG','DE','Weihe einen neuen Priester'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BLESS_PRIEST_MSG','EN','Bless a new priest'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BUILD_ARK','DE','Arche bauen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BUILD_ARK','EN','build ark'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BUILD_ARK_MSG','DE','Baue Arche in'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BUILD_ARK_MSG','EN','Build ark in'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BUILD_TEMPLE','DE','Tempel bauen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BUILD_TEMPLE','EN','build temple'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BUILD_TEMPLE_MSG','DE','Baue einen Tempel in'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_BUILD_TEMPLE_MSG','EN','build temple in'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_CH_ACTION_MSG','DE','Wähle neue Avatar-Aktion'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_CH_ACTION_MSG','EN','Choose new avatar action'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_CH_ADORING_MSG','DE','Deine Helden beten jetzt zu'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_CH_ADORING_MSG','EN','Your heros now adoring'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_CH_LUCK','DE','Glücksfaktor ändern'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_CH_LUCK','EN','change luck'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_CH_LUCK_MSG','DE','Verändere den Glücksfaktor um'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_CH_LUCK_MSG','EN','Change luck-factor about'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_CH_STATUS_MSG','DE','Setze deine neue Beziehung zu'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_CH_STATUS_MSG','EN','Set your new relation to'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_COUNT','DE','Anzahl'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_COUNT','EN','Number'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_DESTROY','DE','Tempel zerstören'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_DESTROY','EN','destroy temple'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_DESTROY_MSG','DE','Zerstöre den Tempel in'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_DESTROY_MSG','EN','Destroy the temple at'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_DIE_ORDER','DE','Sterbereihenfolge ändern'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_DIE_ORDER','EN','change die-order'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_DIE_ORDER_MSG','DE','Wähle die neue Sterbe-Reihenfolge deiner Einheiten'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_DIE_ORDER_MSG','EN','Choose the new die-order of your units'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_ERROR_MSG','DE','unvollständiger Befehl'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_ERROR_MSG','EN','incomplete command'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_FLOOD','DE','überfluten'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_FLOOD','EN','flood'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_FLOOD_MSG','DE','Überflute'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_FLOOD_MSG','EN','flood'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_INCARNATE','DE','Avatare erschaffen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_INCARNATE','EN','create avatars'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_INCARNATE_MSG','DE','Anzahl der neuen Avatare'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_INCARNATE_MSG','EN','Number of new avatars'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_MOVE','DE','bewegen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_MOVE','EN','move'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_MOVE_MSG','DE','bewege %1 in Richtung <br>Mögliche Richtungen: <br> <table>\r\n<tr><td></td><td>N</td><td></td></tr>\r\n<tr><td>NW</td><td></td><td>NE</td></tr>\r\n<tr><td>SW</td><td></td><td>SE</td></tr>\r\n<tr><td></td><td>S</td><td></td></tr>\r\n</table>\r\n'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_MOVE_MSG','EN','move %1 in direction <br>Possible directions:<br><table>\r\n<tr><td></td><td>N</td><td></td></tr>\r\n<tr><td>NW</td><td></td><td>NE</td></tr>\r\n<tr><td>SW</td><td></td><td>SE</td></tr>\r\n<tr><td></td><td>S</td><td></td></tr>\r\n</table>\r\n'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_MOVE_MTN','DE','Berg versetzten'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_MOVE_MTN','EN','move mountain'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_MOVE_MTN_MSG','DE','soll versetzt werden nach'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_MOVE_MTN_MSG','EN','should be moved to'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_PLAGUE','DE','verseuchen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_PLAGUE','EN','init plague'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_PLAGUE_MSG','DE','Wähle Seuche für'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CMD_PLAGUE_MSG','EN','Choose plague for'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CONQUERED_ARKS','DE','Eroberte Archen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('CONQUERED_ARKS','EN','Conquered arks'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('DEAD_AVATARS','DE','Tote Avatare'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('DEAD_AVATARS','EN','dead avatars'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('DEAD_HEROS','DE','Gefallene Helden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('DEAD_HEROS','EN','Dead heros'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('DEAD_PRIESTS','DE','Gefallene Priester'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('DEAD_PRIESTS','EN','Dead priests'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('DEAD_WARRIORS','DE','Gefallene Krieger'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('DEAD_WARRIORS','EN','Dead warriors'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('END_OF_GAME','DE','Das Spiel ist aus! Die Gewinner entnehmt ihr bitte der Statistik.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('END_OF_GAME','EN','The game is over! For winners look in the statistic section.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ERROR_NO_LOGIN','DE','Um diese Aymargeddon-Seite anzusehen, müssen Sie sich erst <a href=\"login.epl\">einloggen</a>, da der Inhalt für jeden Spieler verschieden ist.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ERROR_NO_LOGIN','EN','To view this aymargeddon page you first need to <a href=\"login.epl\">login</a>, because it\'s content is different for each player.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_ARK_APPROACHING','DE','Von %1 kommt eine Arche.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_ARK_APPROACHING','EN','An ark comes from %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_BUILD_ARK','DE','Spieler %1 baut eine Arche.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_BUILD_ARK','EN','Player %1 builds an ark.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_BUILD_TEMPLE','DE','Ein Tempel für den Gott %2 der Größe %3 wird fertig.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_BUILD_TEMPLE','EN','A temple for god %2 with size %3 will be finished.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_FIGHT_GOD','DE','Hier findet ein Avatarkampf zwischen %2 und %3 statt.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_FIGHT_GOD','EN','Here is an avatar fight between %2 and %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_FLOOD','DE','Der Gott %1 hat die Sintflut herbeigerufen! '); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_FLOOD','EN','The god %1 will flood this aerea!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_MOBILE_APPROACHING','DE','Aus %2 kommen %3 %4 von Spieler %1 hier an.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_MOBILE_APPROACHING','EN','From field %2 will come %3 %4 from player %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_PRODUCE_PRIEST','DE','Ein Priester beendet seine Ausbildung.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_PRODUCE_PRIEST','EN','A priest finish his training.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_PRODUCE_WARRIOR','DE','Ein Krieger beendet seine Ausbildung.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('EVENT_PRODUCE_WARRIOR','EN','A warrior finish his training.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_AYMARGEDDON','DE','Aymargeddon'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_AYMARGEDDON','EN','Aymargeddon'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_CITY','DE','Die Stadt'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_CITY','EN','The city'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_ISLE','DE','Die Insel'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_ISLE','EN','The island'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_MOUNTAIN','DE','Der Berg'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_MOUNTAIN','EN','The mountain'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_PLAIN','DE','Die Ebene'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_PLAIN','EN','The plain'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_POLE','DE','Der Manapol'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_POLE','EN','The mana pole'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_WATER','DE','Das Wasserfeld'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIELD_WATER','EN','The water field'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIGHTING_STRENGTH','DE','Kampfstärke'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIGHTING_STRENGTH','EN','Fighting strength'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIGHT_AVATAR','DE','Avatarkampf'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIGHT_AVATAR','EN','avatar fight'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIGHT_EARTHLING','DE','%1 versucht dieses Feld zu erobern.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FIGHT_EARTHLING','EN','%1 trys to conquer this field.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FLANKING','DE','Flankierungsbonus'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FLANKING','EN','Flanking'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FORM_BACK_BUTTON','DE','zurück'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FORM_BACK_BUTTON','EN','back'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FORM_OK_BUTTON','DE','senden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('FORM_OK_BUTTON','EN','submit'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GEN_FEMALE','DE','Frau'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GEN_FEMALE','EN','Woman'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GEN_MALE','DE','Mann'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GEN_MALE','EN','Man'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GEN_PLURAL','DE','Gruppe'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GEN_PLURAL','EN','Group'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GLOBAL','DE','allen Feldern'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GLOBAL','EN','all places'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GOD','DE','Gott'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GOD','EN','god'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GODS_HELP','DE','Göttlicher Unterstützung'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('GODS_HELP','EN','Help of gods'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('HERO','DE','Held'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('HERO','EN','Hero'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('HKP','DE','Helden - Krieger - Priester'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('HKP','EN','Heros - Warriors - Priests'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('HOMECITY','DE','Es ist die Heimatstadt'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('HOMECITY','EN','It\'s the home town'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('HOMEHOLY','DE','Es ist ein heiliger Berg'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('HOMEHOLY','EN','It\'s a holy mountain'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('HPK','DE','Helden - Priester - Krieger'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('HPK','EN','Heros - Priests - Warriors'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('INCARNATE','DE','Avatar erschaffen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('INCARNATE','EN','create avatar'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ISLE','DE','Insel'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ISLE','EN','Isle'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('KHP','DE','Krierger - Helden - Priester'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('KHP','EN','Warrior - Heros - Priests'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('KPH','DE','Krieger - Priester - Helden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('KPH','EN','Warrior - Priests - Heros'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LANG_ENGLISH','DE','Englisch'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LANG_ENGLISH','EN','English'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LANG_GERMAN','DE','Deutsch'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LANG_GERMAN','EN','German'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LANG_WELCOME','DE','Wählen Sie ihre bevorzugte Sprache'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LANG_WELCOME','EN','Choose your favorite language'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LAST_BATTLE_HEADING','DE','Derzeitige Kampfstärken der Götter in der letzten Schlacht:'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LAST_BATTLE_HEADING','EN','Actual fighting power of gods for the last battle:'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LAST_BATTLE_LINE','DE','%1 kämpft mit Stärke %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LAST_BATTLE_LINE','EN','%1 fights with strength %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_EMAIL','DE','e-Mail Adresse'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_EMAIL','EN','email'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_FAILED','DE','Login fehlgeschlagen. Falsches Passwort oder unbekannter Benutzername.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_FAILED','EN','Login failed. Wrong password or unknown username.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_PASSWORD','DE','Passwort'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_PASSWORD','EN','password'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REALNAME','DE','richtiger Name'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REALNAME','EN','real name'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_ERROR','DE','Die Anmeldung ist fehlgeschlagen. Vielleicht ist der Benutzername schon vergeben. Nicht vergessen: Jeder Benutzer darf nur <strong>einen</strong> Account bei uns haben!!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_ERROR','EN','We couldn\'t register you. Maybe the login name is already in use. Always remember: any user is only allowed <strong>one</strong> account on this server!!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_FORM_HEAD','DE','Suchen sie sich einen Benutzernamen aus:'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_FORM_HEAD','EN','Choose your login name:'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_LINK','DE','anmelden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_LINK','EN','register'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_MSG','DE','Wenn Du noch keinen Aymargeddon-Account hast, solltest Du dich'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_MSG','EN','If you don\'t have an aymargeddon account, you should'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_OK_HEAD','DE','Die Anmeldung hat geklappt.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_OK_HEAD','EN','You are now registered.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_OK_TAIL','DE','Das Passwort für den Account wird an die angegebene Adresse geschickt.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_OK_TAIL','EN','The password for your account will be sent to your email adress.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_RETURN','DE','zurück zum Eingang'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_REG_RETURN','EN','back to the login'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_USERNAME','DE','Benutzername'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_USERNAME','EN','Username'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_WELCOME','DE','Der Eingang zu <strong>Aymargeddon</strong>!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LOGIN_WELCOME','EN','The Entrance to <strong>Aymargeddon</strong>!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LUCK','DE','Gewürfelt'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('LUCK','EN','Dice roll'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_ARK','DE','Arche'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_ARK','EN','ark'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_ARK_PL','DE','Archen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_ARK_PL','EN','arks'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_AVATAR','DE','Avatar'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_AVATAR','EN','avatar'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_AVATAR_PL','DE','Avatare'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_AVATAR_PL','EN','avatars'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_BLOCK','DE','blockieren'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_BLOCK','EN','block'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_HELP','DE','helfen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_HELP','EN','help'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_HERO','DE','Held'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_HERO','EN','hero'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_HERO_PL','DE','Helden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_HERO_PL','EN','heros'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_IGNORE','DE','ignorieren'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_IGNORE','EN','ignore'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_PRIEST','DE','Priester'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_PRIEST','EN','priest'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_PRIEST_PL','DE','Priester'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_PRIEST_PL','EN','priests'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_PROPHET','DE','Prophet'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_PROPHET','EN','prophet'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_PROPHET_PL','DE','Propheten'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_PROPHET_PL','EN','prophets'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_WARRIOR','DE','Krieger'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_WARRIOR','EN','warrior'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_WARRIOR_PL','DE','Krieger'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOBILE_WARRIOR_PL','EN','warriors'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOUNTAIN','DE','Berg'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOUNTAIN','EN','mountain'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOVE','DE','bewegen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MOVE','EN','move'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_AVATAR_DEAD','DE','In %1 starb ein Avatar von %2 im Kampf. Er kämpft jetzt in der letzten Schlacht für seinen Gott.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_AVATAR_DEAD','EN','In %1 died an avatar of %2. He fights now in the last battle for his god.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_BLESS_HERO','DE','Der Gott %1 hat in %3 einen Krieger gesegnet, so daß dieser fortan heroische Kräfte entfalten kann.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_BLESS_HERO','EN','The god %1 has blessed a warrior from %2 in %3. He is from now on called \'HERO\'!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_BLESS_PRIEST','DE','%1 hat einen Krieger von %2 in %3 zum Priester geweiht.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_BLESS_PRIEST','EN','%1 blessed a warrior from %2 in %3. It is now a priest.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_BUILD_ARK','DE','%1 hat in %2 eine Arche gebaut.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_BUILD_ARK','EN','%1 has build an ark in %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_BUILD_TEMPLE','DE','%1 hat in %3 einen Tempel zu Ehren von %2 errichtet. Es ist der größte Tempel weit und breit!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_BUILD_TEMPLE','EN','%1 has build a temple to pray to %3 in %2. It is the largest temple in the world!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_ATTACK_ALLIE','DE','Fehler bei Verarbeitung von Befehl %1: Du kannst Deinen Verbündeten %2 nicht angreifen in Feld %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_ATTACK_ALLIE','EN','Error during process of command %1: You cant yttack your allie %2 in field %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_BUILD_HERE','DE','Fehler bei Verarbeitung von Befehl %1: Das kann man auf Feld %2 nicht bauen.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_BUILD_HERE','EN','Error during process of command %1: You cant build this in field %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_DESTROY_DEFENDED','DE','Du kannst den Tempel in %1 nicht zerstören, weil er von Priestern eines anderen Gottes beschützt wird.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_DESTROY_DEFENDED','EN','You cant destroy the temple in %1. The temple is defended by unorthodox priests.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_DESTROY_MOUNTAIN','DE','Du kannst den Tempel auf dem Berg %1 nicht zerstören.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_DESTROY_MOUNTAIN','EN','You cant destroy the temple on mountain %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_DESTROY_OWN','DE','Du kannst den Tempel in %1 nicht zerstören da er Dir selbst gehört.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_DESTROY_OWN','EN','You cant destroy your very own temple in %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_FLOOD_TERRAIN','DE','Du kannst %1 nicht überfluten: Falsches Terrain %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_FLOOD_TERRAIN','EN','You cant flood %1: Wrong terrain %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_LEAVE_AYMARGEDDO','DE','Fehler bei Verarbeitung von Befehl %1: Du kannst die Aymargeddon in Feld %2 nicht verlassen!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_LEAVE_AYMARGEDDO','EN','Error during process of command %1: You cant leave Aymargeddon in field %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_MOVE_ARK','DE','Du kannst keine Arche nach %1 bewegen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_MOVE_ARK','EN','You cant move an ark to %1'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_MOVE_ATTACKED','DE','Du kannst keine %2 aus %1 bewegen, so lange dort gekämpft wird.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_MOVE_ATTACKED','EN','You cant move %2 from %1 during fight.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_MOVE_PLAGUE','DE','%2 können sich in %1 nicht bewegen, weil sie von der %3 betroffen sind.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_MOVE_PLAGUE','EN','%2 cant move in %1 because of %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_MOVE_TO_POLE','DE','Fehler bei Verarbeitung von Befehl %1: Du kannst Dich nicht auf den Pol %2 bewegen.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_MOVE_TO_POLE','EN','Error during process of command %1: You cant move to pole %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_RESCUE_WORLD','DE','Du kannst den Tempel in %2 nicht mehr zerstören, weil nur noch %1 Tempelbauplätze unbesetzt sind. Das Ende der Welt ist unaufhaltsam!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_RESCUE_WORLD','EN','You cant destroy the temple in %2. There are only %1 unbuild temples left. The end of the world is irresistible.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_SWIM','DE','Fehler bei Verarbeitung von Befehl %1: %3 können nicht schwimmen in %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CANT_SWIM','EN','Error during process of command %1: %3 cant swim in %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CHANGE_AYMARGEDDON','DE','%1 hat die Aymargeddon von %2 nach %3 verschoben'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CHANGE_AYMARGEDDON','EN','%1 has moved Aymargeddon from %2 to %3'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CHANGE_FORTUNE','DE','%1 hat den Glücksfaktor von %2 auf %3 geändert.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CHANGE_FORTUNE','EN','%1 changed the fortune from %2 to %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CH_ACTION','DE','Die Avatare in %2 haben jetzt den Status %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CH_ACTION','EN','The avatars in %2 now have the status %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CH_STATUS','DE','Dein neuer Status gegenüber %1 ist jetzt %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_CH_STATUS','EN','Your new status regarding %1 is now %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_DESTROY_NEED_AVATAR','DE','Du brauchst einen Avatar um den Tempel in %1 zerstören zu können.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_DESTROY_NEED_AVATAR','EN','You need an avatar to destroy the temple in %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_DIE_ORDER','DE','Du hast Deine Sterbereihenfolge geändert. Sie lautet jetzt: %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_DIE_ORDER','EN','You changed your die order to %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_DONT_MOVE_WITH','DE','Nicht mehr mitbewegen.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_DONT_MOVE_WITH','EN','Don\'t move with any mobile.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_EARTHLING_CANT_MOVE_T','DE','Fehler bei Verarbeitung von Befehl %1: Du als Erdling kannst keine %2 bewegen.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_EARTHLING_CANT_MOVE_T','EN','Error during process of command %1: Earthlings cant move %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FIGHT_DIE','DE','Ein %2 von %1 in %3 stirbt.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FIGHT_DIE','EN','A %2 from %1 in %3 dies.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FIGHT_END','DE','Die Horden von %1 griffen %2 in %4 an. %3 gewann.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FIGHT_END','EN','The army of %1 attacked %2 in %4. %3 won the battle.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FIGHT_RETREAT','DE','%4 %2 von %1 ziehen sich aus %3 zurück.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FIGHT_RETREAT','EN','%4 %2 from %1 retreats from %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FIGHT_RETREAT_DIE','DE','%4 %2 von %1 sterben in %3 weil sie keine Rückzugsmöglichkeit haben.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FIGHT_RETREAT_DIE','EN','%4 %2 from %1 die in %3: No way to retreat.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FLOOD','DE','%1 hat das Feld %2 überflutet. Aus %3 wurde %4.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FLOOD','EN','%1 has flooded %2. The old terrain %3 is now %4.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FLOOD_NEED_AVATAR','DE','Zum Überfluten von %1 braucht man einen Avatar.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_FLOOD_NEED_AVATAR','EN','You need an avatar in %1 to flood this field.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_GOD_CANT_MOVE_TYPE','DE','Fehler bei Verarbeitung von Befehl %1: Als Gott kannst Du keine %2 bewegen.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_GOD_CANT_MOVE_TYPE','EN','Error during process of command %1: Gods cant move type %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_INCARNATE','DE','%1 inkarnierte einen Avatar in %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_INCARNATE','EN','%1 incarnates an avatar in %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_MOBILE_ARRIVES','DE','%1 %2 von %3 sind in %4 angekommen.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_MOBILE_ARRIVES','EN','%1 %2 from %3 arrived in %4.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_MOBILE_DRAWN','DE','%1 %2 von %3 sind in %4 jämmerlich ersoffen.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_MOBILE_DRAWN','EN','%1 %2 from %3 drawn in %4.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_MOVE_NO_TARGET','DE','Fehler bei Verarbeitung von Befehl %1: Von Feld %2 gibt es kein Feld in Richtung %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_MOVE_NO_TARGET','EN','Error during process of command %1: There is no field in direction %3 from field %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_MOVE_WITH','DE','Bewegt sich mit'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_MOVE_WITH','EN','Moves with'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_NOT_ENOUGH_MANA','DE','Dir fehlt Mana um den Befehl \"%1\" in %2 auszuführen.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_NOT_ENOUGH_MANA','EN','You lack mana to execute the command \"%1\" in %2.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_NOT_ENOUGH_MOBILES','DE','Fehler bei Verarbeitung von Befehl %1: %2 sind zu wenige in Feld %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_NOT_ENOUGH_MOBILES','EN','Error during process of command %1: %2 is not enough in field %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_NO_SUCH_MOBILE','DE','Fehler: Eine Einheit mit der ID %1 konnte nicht gefunden werden.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_NO_SUCH_MOBILE','EN','Error: Cant find mobile with ID %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_NO_SUCH_ROLE','DE','Fehler bei Verarbeitung des Befehls %1: Du kannst Deinen Status gegenüber jemandem, den es nicht gibt, wohl kaum ändern.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_NO_SUCH_ROLE','EN','Error during process of command %1: You cant change your status to unknown players.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_NO_TEMPLE_TO_DESTROY','DE','Du kannst in %1 keinen Tempel zerstören: Es ist keiner da.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_NO_TEMPLE_TO_DESTROY','EN','You cant destroy an non existent temple in %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_STATUS_INVALID','DE','Fehler bei Verarbeitung von Befehl %1: Unbekannter Status \"%2\"'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_STATUS_INVALID','EN','Error during process of command %1: Unknown status \"%2\"'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_TEMPLE_DESTROYD','DE','%3 hat in %1 einen Tempel, der %2 geweiht war, zerstört.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_TEMPLE_DESTROYD','EN','%3 destroyd the temple of god %2 in %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_TRANSPORTS','DE','reist zusammen mit'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_TRANSPORTS','EN','travels with'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_WRONG_TYPE','DE','Fehler bei Verarbeitung von Befehl %1: Falscher Typ %2 in Feld %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('MSG_WRONG_TYPE','EN','Error during process of command %1: Wrong Type %2 in field %3.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NEW_HEROS','DE','Neue Helden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NEW_HEROS','EN','new heros'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOBODY','DE','niemand'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOBODY','EN','nobody'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOM_CHARNAME','DE','Charaktername'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOM_CHARNAME','EN','Character name'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOM_DESCRIPTION','DE','Beschreibung'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOM_DESCRIPTION','EN','Description'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOM_GENDER','DE','Geschlecht'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOM_GENDER','EN','Gender'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOM_ROLE','DE','Rolle'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOM_ROLE','EN','Role'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOT_OCCUPIED','DE','unbesetzt'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('NOT_OCCUPIED','EN','not occupied'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('OCCUPIED','DE','besetzt von'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('OCCUPIED','EN','occupied by'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('OWN_MANA','DE','Du hast %1 Mana zur Verfügung.<p>'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('OWN_MANA','EN','You have %1 mana.<p>'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_LANGUAGE','DE','Sprache'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_LANGUAGE','EN','Language'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_LOGIN','DE','Einloggen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_LOGIN','EN','Login'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_LOGOUT','DE','Ausloggen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_LOGOUT','EN','Logout'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_MAP','DE','Karte'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_MAP','EN','Map'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_PLAYER','DE','Spieler'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_PLAYER','EN','Player'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_REFERENCE','DE','Kurzreferenz'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_REFERENCE','EN','short reference'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_RULES','DE','Regeln'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_RULES','EN','Rules'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_START','DE','Start'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PAGE_START','EN','Start'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PEOPLE','DE','Leute'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PEOPLE','EN','People'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PEOPLE_OR_ARK','DE','Leute (oder Archen)'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PEOPLE_OR_ARK','EN','people (or arks)'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PHK','DE','Priester - Helden - Krieger'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PHK','EN','Priests - Heros - Warriors'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PKH','DE','Priester - Krieger - Helden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PKH','EN','Priests - Warriors - Heros'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAGUE_IN_FIELD','DE','Hier grassiert die %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAGUE_IN_FIELD','EN','Here rampant %1.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAIN','DE','Ebene'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAIN','EN','plain'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_CHOOSE_GAME','DE','Du musst erst ein Spiel wählen, bevor es mehr zu sehen gibt.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_CHOOSE_GAME','EN','You must choose a game if you want to see more.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_CREATE_CHAR','DE','Erschaffe deinen Charakter für'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_CREATE_CHAR','EN','Create your character for'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_DELETE_MESSAGES','DE','Alle nachrichten löschen.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_DELETE_MESSAGES','EN','Delete all messages.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_EVENTS','DE','Ereignisse'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_EVENTS','EN','Events'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_GAMES_NONE','DE','keine'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_GAMES_NONE','EN','none'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_MESSAGES','DE','Folgende Nachrichten sind für dich eingetroffen:'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_MESSAGES','EN','You got the following new messages:'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_MESSAGES_HEADING','DE','Nachrichten'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_MESSAGES_HEADING','EN','Messages'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_NO_EVENTS','DE','Keine bekannten Ereignisse für Dich.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_NO_EVENTS','EN','No known events'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_NO_MESSAGE','DE','Es gibt keine neuen Nachrichten für dich.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_NO_MESSAGE','EN','There are no new messages for you.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_OPENGAMES','DE','<strong>offene Spiele</strong>'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_OPENGAMES','EN','<strong>open games</strong>'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_OWN_GAMES','DE','<strong>eigene Spiele</strong>'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_OWN_GAMES','EN','<strong>own games</strong>'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_STATISTIC','DE','Statistik'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_STATISTIC','EN','Statistics'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_TO_MAP','DE','Zur Karte'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_TO_MAP','EN','To the map'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_WELCOME','DE','Willkommen bei'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PLAYER_WELCOME','EN','Welcome to'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_DAT3_PL','DE','euch'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_DAT3_PL','EN','you'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_DAT3_SG','DE','dir'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_DAT3_SG','EN','you'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_DAT_F','DE','ihr'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_DAT_F','EN','her'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_DAT_M','DE','ihm'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_DAT_M','EN','him'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_DAT_PL','DE','ihnen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_DAT_PL','EN','them'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_GEN_F','DE','ihr'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_GEN_F','EN','her'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_GEN_M','DE','sein'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_GEN_M','EN','his'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_GEN_PL','DE','ihr'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PPRO_GEN_PL','EN','their'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PREP_IS_PL','DE','sind'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PREP_IS_PL','EN','are'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PREP_IS_SG','DE','ist'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PREP_IS_SG','EN','is'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PREP_OWN_PL','DE','deiner'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PREP_OWN_PL','EN','of your'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PREP_OWN_SG','DE','von'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PREP_OWN_SG','EN','of'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PRIEST','DE','Priester'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('PRIEST','EN','Priest'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('REGISTER_MAIL_SUBJECT','DE','Willkommen bei Aymargeddon!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('REGISTER_MAIL_SUBJECT','EN','Welcome to Aymargeddon!'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('REGISTER_MAIL_TEXT','DE','Hallo %1,\r\n\r\nHerzlich willkommen bei Aymargeddon. Dein Login lautet %2 und Dein Paswort lautet %3.\r\n\r\nBitte trage Dich auch auf die Mailingliste ein. Das geht so: Schicke eine Mail an \r\n\r\nmajordomo@informatik.uni-frankfurt.de\r\n\r\nmit folgendem Inhalt:\r\n\r\nsubscribe ragnaroek\r\n\r\nSolltet ihr wieder von dieser Liste runter wollen, schickt ihr einfach ein:\r\n\r\nunsubscribe ragnaroek\r\n\r\nViel Spaß wünscht das Aymargeddon Development Team'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('REGISTER_MAIL_TEXT','EN','Hello %1,\r\n\r\nWelcome to Aymargeddon. Your login is %2 and your password is %3.\r\n\r\nYou should also subscribe to the mailing list:\r\n\r\nPlease send a mail to\r\n\r\nmajordomo@informatik.uni-frankfurt.de\r\n\r\nwith the following content:\r\n\r\nsubscribe ragnaroek\r\n\r\nIf you want to get rid of the mails you send\r\n\r\nunsubscribe ragnaroek\r\n\r\n\r\nHave fun!\r\n\r\nThe Aymargeddon Development Team'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ROLE_EARTHLING','DE','Erdling'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ROLE_EARTHLING','EN','earthling'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ROLE_GOD','DE','Gott'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ROLE_GOD','EN','god'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ROLE_OBSERVER','DE','Beobachter'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ROLE_OBSERVER','EN','observer'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ROLE_UNDEFINED','DE','noch keine Rolle'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('ROLE_UNDEFINED','EN','no role'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('SEND_MESSAGE','DE','kontaktieren'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('SEND_MESSAGE','EN','contact'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('SEND_MESSAGE_TO','DE','Nachricht an %1:'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('SEND_MESSAGE_TO','EN','Message to %1:'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STATISTIC_EARTHLING_CITY','DE','%1 hat %2 Städte.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STATISTIC_EARTHLING_CITY','EN','%1 has %2 citys.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STATISTIC_FORTUNE','DE','Der Glücksfaktor ist %1.<p>'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STATISTIC_FORTUNE','EN','Fortune is %1.<p>'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STATISTIC_NEW_TEMPLES','DE','Es sind zur Zeit %1 Tempel in Bau'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STATISTIC_NEW_TEMPLES','EN','%1 temples will be build.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STATISTIC_SPEED','DE','Spielgeschwindigkeit: Eine Zeiteinheit dauert %1.<p>'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STATISTIC_SPEED','EN','Game speed: One time intervall is %1.<p>'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STATISTIC_UNBUILD','DE','%1 Tempel sind noch nicht gebaut.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STATISTIC_UNBUILD','EN','%1 temples are unbuild.'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STAT_ALLIED','DE','Alliiert'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STAT_ALLIED','EN','allied'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STAT_BETRAY','DE','Verrat'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STAT_BETRAY','EN','betray'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STAT_FOE','DE','Feind'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STAT_FOE','EN','enemy'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STAT_FRIEND','DE','Freund'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STAT_FRIEND','EN','friend'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STAT_NEUTRAL','DE','Neutral'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('STAT_NEUTRAL','EN','neutral'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('SUM_OF_STRENGTH','DE','Gesamtstärke'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('SUM_OF_STRENGTH','EN','Total strength'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('SUNKEN_ARKS','DE','Gesunkene Archen'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('SUNKEN_ARKS','EN','Sunken arks'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TEMPLE','DE','Hier steht ein Tempel'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TEMPLE','EN','Here is a temple'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TEST_TAG','DE','ich %1, dass %2! Prozent: %% hier nochmal: %2 %1'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TIME_WITH_DAYS','DE','In %1 Tagen, %2 Stunden, %3 Minuten und %4 Sekunden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TIME_WITH_DAYS','EN','In %1 days, %2 hours, %3 minutes and %4 seconds'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TIME_WITH_HOURS','DE','In %1 Stunden, %2 Minuten und %3 Sekunden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TIME_WITH_HOURS','EN','In %1 hours, %2 minutes and %3 seconds'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TIME_WITH_MINUTES','DE','In %1 Minuten und %2 Sekunden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TIME_WITH_MINUTES','EN','In %1 minutes and %2 seconds'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TIME_WITH_SECONDS','DE','In %1 Sekunden'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('TIME_WITH_SECONDS','EN','In %1 seconds'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('UNASSIGNED','DE','nicht vergebene Position'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('UNASSIGNED','EN','unassigned position'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('UNAVAILABLE_UNITS','DE','beschäftigte Einheiten'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('UNAVAILABLE_UNITS','EN','unavailable units'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('WATER','DE','Wasser'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('WATER','EN','water'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('WINNER_IS','DE','Sieger ist'); +INSERT INTO LOCALIZE (TAG, LANGUAGE, TEXT) VALUES ('WINNER_IS','EN','Winner is'); + diff --git a/var/RAGNAROEK.sql b/var/RAGNAROEK.sql new file mode 100644 index 0000000..386332a --- /dev/null +++ b/var/RAGNAROEK.sql @@ -0,0 +1,223 @@ +-- MySQL dump 9.09 +-- +-- Host: localhost Database: RAGNAROEK +-- ------------------------------------------------------ +-- Server version 4.0.16-log + +-- +-- Table structure for table `ALLIANCE` +-- + +DROP TABLE IF EXISTS ALLIANCE; +CREATE TABLE ALLIANCE ( + GAME smallint(5) unsigned NOT NULL default '0', + PLAYER smallint(5) NOT NULL default '0', + OTHER smallint(5) NOT NULL default '0', + STATUS enum('NEUTRAL','ALLIED','FRIEND','FOE','BETRAY') NOT NULL default 'NEUTRAL', + PRIMARY KEY (GAME,PLAYER,OTHER) +) TYPE=InnoDB COMMENT='friend or foe?'; + +-- +-- Table structure for table `COMMAND` +-- + +DROP TABLE IF EXISTS COMMAND; +CREATE TABLE COMMAND ( + ID mediumint(9) NOT NULL auto_increment, + GAME smallint(5) unsigned NOT NULL default '0', + EXEC datetime NOT NULL default '0000-00-00 00:00:00', + SUBMIT datetime NOT NULL default '0000-00-00 00:00:00', + PLAYER smallint(5) NOT NULL default '0', + COMMAND enum('SEND_MSG','MOVE_WITH','PRAY','PRODUCE','FIGHT_EARTHLING','FIGHT_GOD','CH_STATUS','MOVE','BUILD_TEMPLE','CH_ADORING','CH_ACTION','BLESS_PRIEST','BLESS_HERO','DIE_ORDER','MOVE_MTN','INCARNATE','BUILD_ARK','PLAGUE','FLOOD','DESTROY','CH_LUCK') NOT NULL default 'CH_STATUS', + LOCATION varchar(7) default NULL, + MOBILE mediumint(8) unsigned NOT NULL default '0', + ARGUMENTS text NOT NULL, + ACK datetime default NULL, + DONE datetime default NULL, + PRIMARY KEY (ID), + KEY EXEC (EXEC) +) TYPE=InnoDB COMMENT='here the commands of players are stored'; + +-- +-- Table structure for table `EARTHLING` +-- + +DROP TABLE IF EXISTS EARTHLING; +CREATE TABLE EARTHLING ( + GAME smallint(6) NOT NULL default '0', + PLAYER smallint(6) NOT NULL default '0', + DYING enum('PKH','PHK','HPK','HKP','KPH','KHP') NOT NULL default 'KHP', + HERO smallint(6) NOT NULL default '0', + PRIMARY KEY (GAME,PLAYER) +) TYPE=InnoDB COMMENT='info special for each earthling'; + +-- +-- Table structure for table `EVENT` +-- + +DROP TABLE IF EXISTS EVENT; +CREATE TABLE EVENT ( + ID mediumint(9) unsigned NOT NULL auto_increment, + GAME smallint(6) NOT NULL default '0', + LOCATION char(5) NOT NULL default '', + TAG char(30) NOT NULL default '', + ARG1 char(25) NOT NULL default '', + ARG2 char(25) NOT NULL default '', + ARG3 char(25) NOT NULL default '', + ARG4 char(25) NOT NULL default '', + COMMAND_ID mediumint(9) NOT NULL default '0', + TIME datetime NOT NULL default '0000-00-00 00:00:00', + PRIMARY KEY (ID) +) TYPE=InnoDB; + +-- +-- Table structure for table `GAME` +-- + +DROP TABLE IF EXISTS GAME; +CREATE TABLE GAME ( + GAME smallint(5) unsigned NOT NULL default '0', + NAME varchar(20) NOT NULL default '', + SIZE smallint(5) unsigned NOT NULL default '0', + SPEED int(11) NOT NULL default '1800', + FORTUNE tinyint(3) unsigned NOT NULL default '0', + LAST_TEMPLE varchar(7) NOT NULL default '', + TEMPLE_SIZE smallint(3) unsigned NOT NULL default '1', + START_MANA smallint(5) unsigned NOT NULL default '20', + RUNNING enum('Y','N') NOT NULL default 'Y', + PRIMARY KEY (GAME) +) TYPE=InnoDB COMMENT='here some generell global information is stored'; + +-- +-- Table structure for table `GOD` +-- + +DROP TABLE IF EXISTS GOD; +CREATE TABLE GOD ( + GAME smallint(5) unsigned NOT NULL default '0', + PLAYER smallint(5) NOT NULL default '0', + MANA smallint(5) unsigned NOT NULL default '0', + DEATH_HERO smallint(5) unsigned NOT NULL default '0', + DEATH_AVATAR smallint(5) unsigned NOT NULL default '0', + ARRIVAL char(7) NOT NULL default '', + PRIMARY KEY (GAME,PLAYER) +) TYPE=InnoDB COMMENT='here some god-related stuff is stored'; + +-- +-- Table structure for table `LOCALIZE` +-- + +DROP TABLE IF EXISTS LOCALIZE; +CREATE TABLE LOCALIZE ( + TAG varchar(25) NOT NULL default '', + LANGUAGE enum('DE','EN') NOT NULL default 'DE', + TEXT text NOT NULL, + PRIMARY KEY (TAG,LANGUAGE) +) TYPE=InnoDB; + +-- +-- Table structure for table `MAP` +-- + +DROP TABLE IF EXISTS MAP; +CREATE TABLE MAP ( + GAME smallint(6) unsigned NOT NULL default '0', + LOCATION varchar(7) NOT NULL default '', + HOME smallint(6) NOT NULL default '0', + OCCUPANT smallint(6) NOT NULL default '0', + TERRAIN enum('PLAIN','WATER','CITY','MOUNTAIN','ISLE','POLE','AYMARGEDDON') NOT NULL default 'PLAIN', + TEMPLE enum('Y','N') NOT NULL default 'N', + PLAGUE set('PESTILENTIA','INFLUENZA','TUBERCULOSIS') default NULL, + LAST_PRODUCE timestamp(14) NOT NULL, + ATTACKER smallint(5) unsigned default '0', + GOD_ATTACKER smallint(5) unsigned default '0', + NAME varchar(20) NOT NULL default '', + FLUXLINE set('N','S','SW','NW','SE','NE') NOT NULL default '', + PRIMARY KEY (GAME,LOCATION) +) TYPE=InnoDB COMMENT='This is the main map of the world'; + +-- +-- Table structure for table `MESSAGE` +-- + +DROP TABLE IF EXISTS MESSAGE; +CREATE TABLE MESSAGE ( + ID mediumint(8) unsigned NOT NULL auto_increment, + GAME smallint(5) unsigned NOT NULL default '0', + TIME datetime NOT NULL default '0000-00-00 00:00:00', + MFROM smallint(5) NOT NULL default '0', + MTO smallint(5) NOT NULL default '0', + LOCATION varchar(7) NOT NULL default '', + TYPE enum('MESSAGE','ERROR','WARNING') NOT NULL default 'MESSAGE', + MSG_TEXT text NOT NULL, + MSG_TAG varchar(25) NOT NULL default '', + ARG1 varchar(25) NOT NULL default '', + ARG2 varchar(25) NOT NULL default '', + ARG3 varchar(25) NOT NULL default '', + ARG4 varchar(25) NOT NULL default '', + PRIMARY KEY (ID), + KEY TIME (TIME) +) TYPE=InnoDB COMMENT='here messages to the players are stored'; + +-- +-- Table structure for table `MOBILE` +-- + +DROP TABLE IF EXISTS MOBILE; +CREATE TABLE MOBILE ( + ID mediumint(8) unsigned NOT NULL default '0', + GAME smallint(5) unsigned NOT NULL default '0', + LOCATION char(7) NOT NULL default '', + TYPE enum('WARRIOR','HERO','PRIEST','PROPHET','AVATAR','ARK') NOT NULL default 'WARRIOR', + OWNER smallint(5) NOT NULL default '0', + ADORING smallint(5) unsigned NOT NULL default '0', + COUNT smallint(5) unsigned NOT NULL default '0', + AVAILABLE enum('Y','N') NOT NULL default 'Y', + STATUS enum('BLOCK','HELP','IGNORE') NOT NULL default 'BLOCK', + COMMAND_ID mediumint(9) NOT NULL default '0', + MOVE_WITH mediumint(6) unsigned default '0', + PRIMARY KEY (ID) +) TYPE=InnoDB COMMENT='Here all mobile objects are stored'; + +-- +-- Table structure for table `PLAYER` +-- + +DROP TABLE IF EXISTS PLAYER; +CREATE TABLE PLAYER ( + PLAYER smallint(5) NOT NULL default '0', + REALNAME varchar(30) NOT NULL default '', + EMAIL varchar(40) NOT NULL default '', + SECURITY enum('USER','FRIEND','TRUSTED') NOT NULL default 'USER', + DESCRIPTION text NOT NULL, + PICTURE blob NOT NULL, + EARTHLING_SCORE smallint(6) NOT NULL default '0', + GOD_SCORE smallint(6) NOT NULL default '0', + BLOCKED enum('N','Y') NOT NULL default 'N', + LANGUAGE char(2) NOT NULL default '', + LOGIN varchar(20) NOT NULL default '', + PASSWORD varchar(20) NOT NULL default '', + GAMES_PLAYED_EARTHLING smallint(5) unsigned NOT NULL default '0', + GAMES_PLAYED_GOD smallint(5) unsigned NOT NULL default '0', + PRIMARY KEY (PLAYER), + UNIQUE KEY PLAYER (PLAYER), + UNIQUE KEY LOGIN (LOGIN), + UNIQUE KEY EMAIL (EMAIL) +) TYPE=InnoDB COMMENT='information for players, which are not related to a game'; + +-- +-- Table structure for table `ROLE` +-- + +DROP TABLE IF EXISTS ROLE; +CREATE TABLE ROLE ( + GAME smallint(5) unsigned NOT NULL default '0', + PLAYER smallint(5) NOT NULL default '0', + NICKNAME varchar(20) default NULL, + ROLE enum('OBSERVER','EARTHLING','GOD') NOT NULL default 'EARTHLING', + GENDER enum('MALE','FEMALE','PLURAL') NOT NULL default 'PLURAL', + DESCRIPTION text, + PICTURE blob, + PRIMARY KEY (GAME,PLAYER) +) TYPE=InnoDB COMMENT='which player plays which role?'; + diff --git a/var/README b/var/README new file mode 100644 index 0000000..9cb8dac --- /dev/null +++ b/var/README @@ -0,0 +1,18 @@ +In RAGNAROEK.sql, is the export from the testing-database, +generated with the script extract_structure_and_localize + +In LOCALIZE.sql the same but only for table LOCALIZE. + +The script backup generates a backup in ./+RAGNAROEK_BACKUP.sql + +The script from_scratch generates a complete empty database but with +the old PLAYER and LOCALIZE tables. + +The script do_sql executes his first command with mysql + +in my.cnf is my configuration file for mysql to work with +InnoDB tabletype. make shure InnoDB tabletype works for you. mysql +sets default tabletype to MyISAM if it does not work without +complaining! But FROGS and Aymargeddon wont work without the +transaction-capability from InnoDB + diff --git a/var/backup b/var/backup new file mode 100644 index 0000000..10f00c0 --- /dev/null +++ b/var/backup @@ -0,0 +1,3 @@ +mysqldump -u aymargeddon -p`cat ../+secrets` -c --add-drop-table \ + RAGNAROEK > ./+RAGNAROEK_BACKUP.sql + diff --git a/var/delete_game b/var/delete_game new file mode 100644 index 0000000..264cd0c --- /dev/null +++ b/var/delete_game @@ -0,0 +1,13 @@ +# usage: delete_game <game-number> | ./do_sql + +echo "delete from GAME where GAME = $1;" +echo "delete from MOBILE where GAME = $1;" +echo "delete from COMMAND where GAME = $1;" +echo "delete from MAP where GAME = $1;" +echo "delete from ROLE where GAME = $1;" +echo "delete from MESSAGE where GAME = $1;" +echo "delete from EVENT where GAME = $1;" +echo "delete from ALLIANCE where GAME = $1;" +echo "delete from GOD where GAME = $1;" +echo "delete from EARTHLING where GAME = $1;" + diff --git a/var/do_sql b/var/do_sql new file mode 100755 index 0000000..505d49a --- /dev/null +++ b/var/do_sql @@ -0,0 +1,2 @@ +mysql -u aymargeddon -p`cat ../+secrets` RAGNAROEK + diff --git a/var/extract_structure_and_localize b/var/extract_structure_and_localize new file mode 100644 index 0000000..6c0da63 --- /dev/null +++ b/var/extract_structure_and_localize @@ -0,0 +1,4 @@ +mysqldump -u aymargeddon -p`cat ../+secrets` -d --add-drop-table \ + RAGNAROEK > RAGNAROEK.sql +mysqldump -u aymargeddon -p`cat ../+secrets` -c --add-drop-table RAGNAROEK LOCALIZE \ + > LOCALIZE.sql diff --git a/var/from_scratch b/var/from_scratch new file mode 100644 index 0000000..ed14424 --- /dev/null +++ b/var/from_scratch @@ -0,0 +1,8 @@ +mysqldump -u aymargeddon -p`cat ../+secrets` -c --add-drop-table RAGNAROEK LOCALIZE \ + > LOCALIZE.sql +mysqldump -u aymargeddon -p`cat ../+secrets` -c --add-drop-table RAGNAROEK PLAYER \ + > ./+PLAYER.sql + +./do_sql < RAGNAROEK.sql +./do_sql < LOCALIZE.sql +./do_sql < ./+PLAYER.sql diff --git a/var/my.cnf b/var/my.cnf new file mode 100644 index 0000000..47d7b26 --- /dev/null +++ b/var/my.cnf @@ -0,0 +1,98 @@ +# You can copy this to one of: +# /etc/mysql/my.cnf to set global options, +# mysql-data-dir/my.cnf to set server-specific options (in this +# installation this directory is /var/lib/mysql) or +# ~/.my.cnf to set user-specific options. +# +# One can use all long options that the program supports. +# Run the program with --help to get a list of available options + +# This will be passed to all mysql clients +[client] +#password = my_password +port = 3306 +socket = /var/run/mysqld/mysqld.sock + +# Here is entries for some specific programs +# The following values assume you have at least 32M ram + +[safe_mysqld] +err-log = /var/log/mysql/mysql.err + +[mysqld] +user = mysql +pid-file = /var/run/mysqld/mysqld.pid +socket = /var/run/mysqld/mysqld.sock +port = 3306 +# +# You can also put it into /var/log/mysql/mysql.log but I leave it in /var/log +# for backward compatibility. Both location gets rotated by the cronjob. +#log = /var/log/mysql/mysql.log +log = /var/log/mysql.log +basedir = /usr +datadir = /var/lib/mysql +tmpdir = /tmp +language = /usr/share/mysql/english +skip-locking +# +# The skip-networkin option will no longer be set via debconf menu. +# You have to manually change it if you want networking i.e. the server +# listening on port 3306. The default is "disable" - for security reasons. +skip-networking +set-variable = key_buffer=16M +set-variable = max_allowed_packet=1M +set-variable = thread_stack=128K +# +# Here you can see queries with especially long duration +#log-slow-queries = /var/log/mysql/mysql-slow.log +# +# The following can be used as easy to replay backup logs or for replication +#server-id = 1 +#log-bin = /var/log/mysql/mysql-bin.log +#binlog-do-db = include_database_name +#binlog-ignore-db = include_database_name +# + +# +# AB HIER WICHTIGES INNO ZEUGS +# + + +# Read the manual if you want to enable InnoDB! +# skip-innodb +skip-bdb + +# You can write your other MySQL server options here +# ... +# Datafile(s) must be able to +# hold your data and indexes. +# Make sure you have enough +# free disk space. +innodb_data_file_path = ibdata1:10M:autoextend +# Set buffer pool size to +# 50 - 80 % of your computer's +# memory +set-variable = innodb_buffer_pool_size=70M +set-variable = innodb_additional_mem_pool_size=10M +# Set the log file size to about +# 25 % of the buffer pool size +set-variable = innodb_log_file_size=20M +set-variable = innodb_log_buffer_size=8M +# Set ..flush_log_at_trx_commit +# to 0 if you can afford losing +# some last transactions +innodb_flush_log_at_trx_commit=1 + +# +# BIS HIER WICHTIGES INNO-ZEUGS +# + +[mysqldump] +quick +set-variable = max_allowed_packet=1M + +[mysql] +#no-auto-rehash # faster start of mysql but no tab completition + +[isamchk] +set-variable = key_buffer=16M