From f8094f77dcfbdf5a34c9320f5c725e2042d8a582 Mon Sep 17 00:00:00 2001 From: Enno Rehling <enno.rehling@gmail.com> Date: Sat, 7 Aug 2010 22:53:41 -0700 Subject: [PATCH] use libraries from the external folder, don't depend on any additional installations (VS 2010) --- .gitignore | 10 +- doc/bugs.txt | 1846 ++-- doc/changes.txt | 98 +- doc/coding.txt | 180 +- doc/directories.txt | 56 +- doc/spells_uebersicht.txt | 370 +- doc/synonyme-rassen | 168 +- doc/todo.txt | 478 +- doc/triggers.txt | 222 +- game-e2/eressea.ini | 34 +- game-e2/setup.lua | 30 +- game-e3/eressea.ini | 34 +- game-e3/setup.lua | 30 +- res/buildings/castle-2.xml | 48 +- res/buildings/castle.xml | 52 +- res/catalog-e3a.xml | 20 +- res/catalog-eressea.xml | 20 +- res/config-e3a.xml | 386 +- res/config-eressea.xml | 242 +- res/directions.xml | 8 +- res/e3a/armor.xml | 24 +- res/e3a/armor/chainmail.xml | 18 +- res/e3a/armor/laenmail.xml | 18 +- res/e3a/armor/laenshield.xml | 18 +- res/e3a/armor/plate.xml | 20 +- res/e3a/armor/rustychainmail.xml | 18 +- res/e3a/armor/rustyshield.xml | 18 +- res/e3a/armor/scale.xml | 22 +- res/e3a/armor/shield.xml | 18 +- res/e3a/armor/towershield.xml | 26 +- res/e3a/buildings.xml | 60 +- res/e3a/equipment.xml | 156 +- res/e3a/items.xml | 178 +- res/e3a/luxuries.xml | 46 +- res/e3a/messages.xml | 20 +- res/e3a/races.xml | 1854 ++-- res/e3a/resources.xml | 32 +- res/e3a/resources/iron.xml | 22 +- res/e3a/resources/mallornseed.xml | 8 +- res/e3a/resources/seed.xml | 8 +- res/e3a/resources/stone.xml | 20 +- res/e3a/shipnames.xml | 216 +- res/e3a/ships.xml | 308 +- res/e3a/spells.xml | 1380 +-- res/e3a/strings.xml | 670 +- res/e3a/terrains.xml | 146 +- res/e3a/weapons.xml | 48 +- res/e3a/weapons/crossbow.xml | 26 +- res/e3a/weapons/greatbow.xml | 44 +- res/e3a/weapons/greatsword.xml | 30 +- res/e3a/weapons/halberd.xml | 36 +- res/e3a/weapons/laensword.xml | 30 +- res/e3a/weapons/mallorncrossbow.xml | 26 +- res/e3a/weapons/mallornlance.xml | 26 +- res/e3a/weapons/rustygreatsword.xml | 30 +- res/e3a/weapons/rustyhalberd.xml | 34 +- res/eressea/artrewards.xml | 64 +- res/eressea/buildings.xml | 14 +- res/eressea/equipment.xml | 38 +- res/eressea/items.xml | 398 +- res/eressea/races.xml | 2746 ++--- res/eressea/spellinfo.xml | 226 +- res/eressea/spells.xml | 1408 +-- res/eressea/strings.xml | 784 +- res/eressea/terrains.xml | 20 +- res/names-dragons.xml | 190 +- res/names-ghouls.xml | 230 +- res/names-skeletons.xml | 242 +- res/names-undead.xml | 312 +- res/names-zombies.xml | 216 +- res/races/dragon.xml | 28 +- res/races/goblin-2.xml | 44 +- res/races/goblin-3.xml | 44 +- res/races/wyrm.xml | 22 +- res/races/youngdragon.xml | 26 +- scripts/e3a/build.lua | 388 +- scripts/e3a/main.lua | 126 +- scripts/e3a/markets.lua | 178 +- scripts/e3a/modules.lua | 24 +- scripts/e3a/rules.lua | 154 +- scripts/e3a/xmas2009.lua | 52 +- scripts/eressea/adamant.lua | 156 +- scripts/eressea/alp.lua | 74 +- scripts/eressea/embassy.lua | 60 +- scripts/eressea/ents.lua | 64 +- scripts/eressea/eternath.lua | 36 +- scripts/eressea/igjaruk.lua | 118 +- scripts/eressea/items.lua | 38 +- scripts/eressea/main.lua | 126 +- scripts/eressea/modules.lua | 42 +- scripts/eressea/ponnuki.lua | 84 +- scripts/eressea/rules.lua | 16 +- scripts/eressea/tunnels.lua | 124 +- scripts/eressea/wedding-jadee.lua | 94 +- scripts/eressea/xmas2004.lua | 50 +- scripts/eressea/xmas2005.lua | 62 +- scripts/eressea/xmas2006.lua | 108 +- scripts/tests/castles.lua | 54 +- scripts/tests/e3a.lua | 1190 +-- scripts/tests/eressea.lua | 288 +- scripts/tests/morale.lua | 352 +- src/bindings.c | 198 +- src/curses.c | 656 +- src/curses.h | 54 +- src/eressea.vcproj | 1272 +-- src/eressea.vcxproj | 17 +- src/main.c | 584 +- src/monsters.c | 2006 ++-- src/races/Jamfile | 40 +- src/races/dragons.c | 104 +- src/races/illusion.c | 82 +- src/races/races.c | 286 +- src/races/races.h | 50 +- src/races/zombies.c | 194 +- src/server.c | 42 +- src/spells/Jamfile | 46 +- src/spells/alp.c | 410 +- src/spells/alp.h | 108 +- src/spells/buildingcurse.c | 198 +- src/spells/buildingcurse.h | 56 +- src/spells/combatspells.c | 3320 +++--- src/spells/combatspells.h | 114 +- src/spells/regioncurse.c | 592 +- src/spells/regioncurse.h | 56 +- src/spells/shipcurse.c | 312 +- src/spells/shipcurse.h | 60 +- src/spells/spells.c | 14502 +++++++++++++------------- src/spells/spells.h | 64 +- src/spells/unitcurse.c | 726 +- src/spells/unitcurse.h | 58 +- 130 files changed, 23651 insertions(+), 23652 deletions(-) diff --git a/.gitignore b/.gitignore index 5e8112bb4..af88a9746 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ -bin/ - -*.ncb -*.suo -*.ncb +bin/ + +*.ncb +*.suo +*.ncb *.suo \ No newline at end of file diff --git a/doc/bugs.txt b/doc/bugs.txt index f2b5a0a0a..bf025b147 100644 --- a/doc/bugs.txt +++ b/doc/bugs.txt @@ -1,923 +1,923 @@ -BUGS - -? > nicht untersucht, fraglich -- > best�tigt, aber unerledigt -+ > erledigt -(!) kritische Bugs, die unbedingt vor der n�chsten Auswertung repariert werden m�ssen - -+ F�r alle nur den kurzen Report. War Fehler in einem logischen Ausdruck - in creport.c - -+ URSPRUNG hat eine kranke Semantik - (enno) repariert. Nach der alten Routine konnte man seine Koordinaten durch Neusetzen ermitteln! - -+ Die neuen Kampfmeldungen k�nnten Kosmetik brauchen, � la: Einheit(en) - (corwin) Das Gr�bste verbessert. K�nnte aber noch mehr Arbeit brauchen. - -+ im CR fehlen die Botschaften - (enno) Hatte S�ren nicht gemacht. ist im standard-cr jetzt drin. - -+ Orks k�nnen die Vermehrungsmeldungen nicht separat abschalten - (Henning) MSG_ORKVERMEHRUNG eingebaut, ist ML_INFO, kann also mit REPORT ORK WARN - abgestellt werden - -+ Talenttage gibt's f�r jedermann, der k�mpft - (enno) Nur noch f�r die, die min. 2 Runden lang k�mpfen. - -+ "Einheiten vor der x. Runde" wird einmal zuviel angezeigt. - (enno) War ein Fehler in der Berechnung von side::alive - -+ Karawansereien wirken sich nicht auf die Anzeige der Luxusg�ter aus. - -+ FL_LEFTSHIP wurde f�lschlicherweise gespeichert. - -+ Fehler im Handel, von Thorsten beobachtet. Einheiten verkaufen, ohne etwas zu haben. - Vermutung: Zwei gleichzeitig verkaufende Einheiten bedienne sich beide aus dem Pool. - (enno) Das auch, aber au�erdem wurden die G�ter dem falschen abgezogen. - -+ Kapit�ne ohne Wahrnehmung durchbrechen Nebelwand - (katja) Auch Kapit�ne m�ssen nun Wahrnehmung haben - -+ Mantel der Unverwundbarkeit wirkt nicht. - (corwin) survival_chance() gab einen Prozentwert zur�ck, gebraucht - wurde aber ein Wert von 0-1. Funktioniert die R�stungsfunktion? - -+ Absturz in set_resource() bei Kr�uterreservierung. - (corwin) Hektischer Bugfix (|| resource == NORESOURCE). - -+ Bug in hp_status (Cast/Klammerung) - -+ Ausdauerlernen und HP richtig verwurstet. - -+ Luftschiff - (enno) Eine Alraune wurde statt des Windbeutel verwendet. Auch, wenn man keine hatte. - -+ Fehler in den expandxxx routinen! - (enno) statt addlist(xxxorders) wurde addlist(&xxxorders) gemacht. - -+ Angabe 'erschoepft' bei Personen, die Ausdauer lernen. - (corwin) HP-Gewinn beim Ausdauer lernen war inkorrekt. - (corwin) Fehler gefunden, ich war blind. - -+ SCHWERER BUG: Orks bekommen falsche Lerntage - (enno) u->n statt u->no benutzt. - (enno) change_skill statt set_skill benutzt. - -+ SCHWERER BUG: Im Kampf gehen Talentwerte kaputt - (enno) set_number statt scale_unit - -+ SCHWERER BUG: Fliehende Einheiten ohne Talente - (enno) schlicht und einfach vergessen - -+ Trankbeschreibungen stimmen nicht mit Kr�utern �berein - (corwin) Beschreibungen waren schon bei den alten Tr�nken falsch. - -+ Ostfriesische Burgen konnten nicht gebaut werden - (enno) Fehler, soweit im Server, behoben: - wenn eine einheit MACHE X 123 sagt, und es gibt ein Geb�ude 123, - egal welchen Typs, dann baut sie Geb�ude 123 weiter. Auch wenn - sie selbst in einem anderen steht. - -+ in den Kampfbeschreibungen ist ein Umbruch zuviel. CR klappt nicht. - (enno) repariert. in addmessage() niemals \n benutzen! - -+ im Handel (sell) werden die Steuern nicht vom Verdienst abgezogen. - (martin+enno) repariert. Der spieler bezahlt. - -+ Einheiten leben nach dem Kampf noch weiter - (enno) u->number auf 0 setzen. - -+ herbs-pool hatte eine macke - (enno) use_pooled klappte nicht, weil NULL �bergeben wird. - Das k�nte den Thorsten-Bug erkl�ren. - -+ Einheiten von angegriffenen klagen �ber kampfersch�pfte Personen - (enno) flag setzen. - -+ �bergabe von 4. Magier an Elfenpartei klappt nicht. (Partei 10) - (corwin) u statt u2 in givemen() - (enno) in giveunit() auch. und daran ist es auch gescheitert. - -+ Antimagiezone sollte erst in der darauffolgenden Runde wirken. - (NEW-Flag setzen.) - (corwin) NEW-Flag wird gesetzt und in spell_active() abgefragt. - -+ move_monster() - warning - (enno) Variable d wurde nicht initialisiert. - -+ Rundungsfehler in scale_number, wenn Einheiten-Anzahl zu gro�. - (enno) repariert, noch undurchsichtiger geworden. - -+ Schiffe aus Mallorn bauen zieht keine Ressourcen aus der Region ab - (enno) repariert. Es wurde an use_pooled keine Region gegeben, - Test auf Mallorn fehlte v�llig. - -+ Zauber brauchen Holz als Komponenten. - (enno) Mallorn kann das Holz notfalls ersetzen. - -+ Elfenparteien konnten keinen 4. Magier �bergeben bekommen. - (enno) Es wurde bei der Quellpartei das Magiermax gefragt. - -+ Aji - die Drachent�ter (29206) hat -1 Gefallene zu beklagen. - Katzeneinheit. Evt. Kollision von Heilung und 14%-Chance. - (enno) gefunden. index�berschreitung, msvc macht's m�glich. - -+ random_neighbour() - warnings - (enno) implizite typecasts von int nach direction_t - -+ fliehende k�nnen von Schiffen herunterfliehen. - (enno) �nderung in fleeregion(), sollte das reparieren. - -+ Fliehende Magier verlieren evt. ihre Spr�che. - (enno) stimmt! dicker bug, wer war davon betroffen? - -+ Hitpointberechnung bei Einheitensplitting fehlerhaft. - (corwin) Gefunden. change_skill in transfermen macht Probleme, dort - ersetzt durch change_skill_transfermen. - -+ dazzle und demoralize klappten nicht. - (enno) neu implementiert. - -+ Stringzuweisungen in Mapper falsch. - -+ angegriffene einheiten k�nnen nichts tun - (enno) tritt in allen getesteten k�mpfen nicht mehr auf. - -+ fliehende einheiten attackieren in seltenen F�llen ein zweites mal. - (enno) gefixt. passierte bei einheiten, die komplett (ohne fluechttlings-einheit) wegrannten. - -+ HELFE GIB verhindert Einsatz von Dumpfbackbrot - (corwin) Ge�ndert, relevant ist jetzt nur noch der HELFE-Status des - Gebers. - -+ Meldung �ber fehlenden Zug irritiert Neueinsteiger - (corwin) Ge�ndert, Neueinsteiger bekommen die Meldung nicht mehr - -+ Meldungen zum Abtreiben fehlen. - (corwin) f->dh in drifting_ships wird nie gesetzt. - -+ Formatierungsfehler im Spionagebericht. - -+ Ents entstehen nicht. - -+ Vogelfreund als Einheit sichtbar (NR) - (corwin) Alle U_SPELL-Einheiten werden angezeigt? Wer hat da wieder - gefummelt, ohne zu testen... Auch Befehle kann man ihnen geben, - klasse Sache, bei ner Antimagiezone. - (enno) hihi. w�re ein cooles feature f�rs neue magsystem - (corwin) Brachialfix in readorders() und rpunit(). - -+ Verteidigung mit halbem Waffentalent gegen Fernwaffen funktioniert - nicht. - (corwin) Fehler lokalisiert, switch/case in hits(). Wie soll es sein? - -+ Es wurde vergessen, die Kampfwirkung der Antimagiezone an die - ver�nderte St�rke anzupassen. - (corwin) Gefixt, Durchbruchschance jetzt wieder normal. - -+ Katapulte ohne Talent Katapultbedienung benutzt. - (enno) Waffenauswahl war verhunzt. - -+ �berlange Zeilen werden in der Zugvorlage umgebrochen. - (corwin) In der Zugvorlage wird nicht mehr umgebrochen. - -+ Heilung funktioniert nicht. (Wyrm vollst�ndig geheilt.) - (corwin) Nicht reproduzierbar. Ursache unbekannt. - (corwin) Fehler in battle.c, Hitpointberechnung fehlerhaft, - wenn keine Toten in Einheit. - -? HP-Berechnung bei neu hinzurekrutierten scheint fehlerhaft. - (corwin) In Testspiel nicht reproduzierbar, scheint ok. - -+ Taktik funktioniert nicht korrekt, Werte werden nirgends verglichen. - (corwin) Taktikvergleich war nirgends implementiert. - -+ Drachen heilen nicht. - -+ Kampfmessages sind verwirrend. - (corwin) Kampfmeldungen aussagekr�ftiger gemacht. - -+ Sch�ler m�ssen Lehrer kontaktieren. - (corwin) Abfrage rausgenommen. Kein Sinn erkennbar. - -+ Handeln-Talent wurde negativ. - (corwin) Gefunden. Fehler in der Poolbehandlung in sell(). - -? Deadlock bei Kampf in Carwin. - (enno) war evtl. ein Problem mit der Alliiertenmatrix? - -+ Aus einem Kampf geflohene Einheiten bekommen keinerlei Kampferfahrung, - auch wenn sie vorher aktiv gek�mpft haben. - (katja) Kampferfahrung ist eh abgeschafft - -? Probleme beim �bergeben von Personen mit unterschiedlichem - Ausdauer-Talent. - ! was f�r ein problem? ! - -- Einige Kampftexte grammatisch falsch. (Plural einsetzen... andere - F�lle.) - -+ die Tavernen tun nichts - (enno) Neue Regeln fuer Tavernen, alte Tavernen konvertiert zu neuen. - -+ Semikolon in Strings f�hren zu �rger. - [BESCHREIBE EINHEIT "Schlaue Leute; Sie sind nicht dumm"]. - Generell kann man das Parsen noch verbessern. - (enno) komplett neuer parser - -+ Umlaute an einigen Stellen noch fehlend. (Bla lst sich auf.) - (enno) repariert - -+ Adresslisten sind nicht in Ordnung, es erscheinen Parteien, - die man nur parteigetarnt sieht. - (Faroul) sollte schon einige Zeit gefixt sein in spunit - -? Fernk�mpfer bekommen keine Kriegsbeute. - (enno) das ist doch sicher nicht mehr so. - -+ BEWACHE geht nicht (Marco Zielinski) - (enno) fehler gefunden, es fehlte ein ! - -+ Parteien bekommen Meldungen, die nichts mit ihnen zu tun haben. - (corwin) Fehler in givesilver, alter buf verwendet. - -- Fehler mit Pferden in plan_monsters. Ich wei� aber nicht, - wozu der Code gut sein soll, habe es markiert. (enno) - -? magres wird nicht beachtet. - (katja) wo? - -? Immer noch ersch�pfte Einheiten. - (enno) lag vielleicht an der kampf-hp-aufteilung, die wir aber im juli 00 gefixt haben? - -? Heilung funktioniert nicht. - -? Negative Handelsvolumina f�hren zu Absturz in expandselling. - (corwin) Quickfix f�ngt negative Mengen dort ab. Ursache f�r die - negativen Mengen noch nicht gefunden. Zusammenhang mit - VERKAUFE ALLES vermutet. - ! (enno) ! hatten wir das nicht repariert? - -+ Fehlende Anf�hrungszeichnen bei BENENNE f�hren zu String�berlauf. - (enno) gefixt, mit komplett neuem parser. - -- r->demand f�llt auf 0. assertion in readgame springt an. - (corwin) Brachialfix beim Einlesen. Ursache nicht gefunden. - -- flutwellen l�schen bauern, silber und sonstige regionswerte nicht. - -- flutwellen vernichten schiffe, aber nicht die besatzung - -- �bergaben k�nnen an Einheiten erfolgen, die man nicht sieht. - Auf diese Weise k�nnen Tarner identifiziert werden. (In dogive() - fixen!?) auf kontaktiere pr�fen, dann erlauben - -+ Betrete Schiff sollte vor Attackiere kommen, um att,betrete,nach - zu verhindern. - (corwin) Reihenfolge unver�ndert, aber trotzdem gefixt in - building/shipowner. - -+ Formatierungsproblem: Zentrierte lange Strings beginnen manchmal - schon in Spalte 0. Vermutlich Rundungsproblem. - (enno) in zukunft sollen eh alle bei spalte 0 anfangen. - -+ addmessage( ,"", ) erzeugt eine Zeile mit einem Space "^ $" - (enno) addmessage fliegt eh raus - -+ Magieresistenz funktioniert nicht. - (corwin) Wieder eingebaut. - -+ Drachen greifen trotz WARTEN an. - (corwin) Hoffentlich gefixt, Verwechslung thisorder, lastorder - -+ Ablegen in Nachbarregionen funktioniert nicht. - (corwin) Gefixt. - -+ Kapit�ne und Burgherren stehen in der Zugvorlage nicht an der - richtigen Stelle. - (enno) eingebaut. - -+ Im Gletscher ist zuviel Eisen. Menge begrenzen. - (corwin) Max 80 Eisen pro Gletscherregion. - -+ Nebelw�lle? - (corwin) Nebelwall-Anzeige in describe() war Unfug, ebenso - is_fogwalled(). - -+ Absturz bei destroy_ship durch zuviel Schaden. - -+ reale Koordinaten in den Fehlermeldungen in sail() - (katja) durch regionid() ersetzt - -+ Beschriftung der Meriankarten falsch (Beschriftung oben verschoben) - (enno) sollte gefixt sein. - -+ Man sieht Botschaften in Regionen, die nur vom Leuchtturm gesehen - werden. - (corwin) Abfrage in die Reportgenerierung eingebaut. - -+ CR bei vorigem �bersehen. - (enno) gefixt. - -+ Fl�chtende Drachen hinterlassen Drachenkopf und -blut. - (corwin) Hoffentlich gefixt. - -? Eine Partei in einer Kampfregion erhielt keinen Kampfbericht. - -+ Fl�chtende Einheiten verlassen Burgen und Geb�ude evt. nicht. - (corwin) Fliehende Einheiten verlassen auf jeden Fall Geb�ude und - Schiffe. - -+ von Turmregionen erh�lt man keine Durchreiseereignisse - (katja) gefixt - -+ Im CR ist erkennbar, ob eine Region Mallornregion ist. - (corwin) Mallorn nur noch = 1, wenn auch B�ume da sind. - -+ Magieresistenz f�r Drachen falsch. - (corwin) magicresistance() mu� nat�rlich auf alles wirken. - -+ "Maentel" ohne Umlaut wird nicht erkannt. - (corwin) In Tabelle eingef�gt. - -+ Illusionen werden als Migranten gez�hlt. - (corwin) count_migrants pr�fte nur auf nonplayer(), nicht auf - Illusionen. - -+ Werden K�mpfer auf Schiffen in einen Kampf gezogen bleiben - die Schiffe unbesch�digt. - (corwin) Damage-Routine ber�cksichtigte nur Kapit�ne. - -+ Adressen von Parteien, die man nur in einer Turmregion oder - Durchreiseregion sieht, stehen im NR aber nicht im CR - -+ Von Migranten und Untoten erzeugte TEMP-Einheiten haben den falschen - Typ/Rasse. - (corwin) u->race statt u->faction->race - -+ material- und silberpool in den cr mit aufnehmen - (corwin) Neues Tag ;Optionen mit f->options - -+ Fl�chtende Einheiten werden evt in mehrere K�mpfe verwickelt, wenn die - Region, in die sie fl�chten, sp�ter ausgewertet wird. - (enno) sollte l�ngst gefixt sein. - -+ Schiffe, die in der selben Region an- wie ablegen, haben die kueste - falsch gesetzt.und kriegen keine durchreiseinfos. - (corwin) Zumindest die K�stengeschichte ist gefixt. (Auch das hatte - ich �brigens schonmal gemacht.) - -? Schiffe, die in der selben Region an- wie ablegen, haben die kueste - falsch gesetzt.und kriegen keine durchreiseinfos. - (corwin) K�ste gefixt. Durchreiseinfos m��ten imho kommen. - -+ bugreport isilpetz, teleport funktioniert nicht, obwohl kontaktiert wurde. - (corwin) Gefixt. Isilpetz'Partei mu� in TELEPORT_HACK extra - ber�cksichtigt werden. - -+ Ein Kampf, der 1+1 Kampfrunden dauert, gibt keine Kampferfahrung. - (corwin) Ge�ndert. - -+ Mapper - Einheit ins Clip nehmen geht nicht. (Es wird eine scheinbar - ausgew�rfelte Einheit genommen.) - (corwin) atoi36-Umstellung vergessen. Gefixt. - -+ von Migranten rekrutierte Temp-Einheiten erscheinen als eine andere Rasse als sie sind. - (enno) gefixt. - -+ mehrere Ponnukis - (enno) gefixt. - -? artefakte werden auf der flucht nicht mitgenommen - bugreport 26.oct.99 stefan reich - (corwin) Alte Flucht rausgenommen. - (enno) stefan sagt, es sei schon wieder passiert. - (corwin) War nur in der alten Flucht �berhaupt ber�cksichtigt. - 0 Gewicht-Items werden jetzt wie Pferde behandelt. (Ein - Exemplar pro Person wird bei Flucht mitgenommen.) - - Dies bedeutet, da� Fl�chtlinge immer z.B. einen MdU - mitnehmen, wenn in der Einheit vorhanden. Das ist eigentlich - nicht gut, aber nicht ohne gro�en Aufwand anders zu l�sen. - -+ Merian-X-Koordinaten sind manchmal verschoben. - (corwin) Rundungsfehler bei der Kartenerstellung. Bitte nochmal - im Spiel nachgucken, ob Fix ok. - (enno) Merian ist rausgeflogen - -+ Diebstahl kann durch TEMP-Machen verhindert werden - (enno) Reihenfolge des shash in destroy_unit falsch. - -- Durch den selben trick (TEMP-�bergabe) kann man sich vor - spionage sch�tzen - -+ Parteien aus Leuchtturmregionen ersheinne nicht in der Adressliste. - (enno) ich glaub, ich hab's. oder doch nicht? - -+ Bauernblut hilft auch fremden D�moneneinheiten, - (enno) Auswirkungen kann man vernachl�ssigen. niemand hat - >100 D�monen aus zwei parteien in einer region mit <100 bauern. - -+ potion-effects werden in scale_number nicht ber�cksichtigt - (enno) repariert, skalieren jetzt genau wie skills. - -- assert in battle.c:4958 wird getriggert. Schlecht reproduzierbar. - (enno) ein paar asserts zus�tzlich eingebaut, falls es nochmal passiert. - -+ ; terminiert einlesen der Befehlsdatei. - (enno) repariert. 'comment' wurde nie wieder false. - -+ fix_irace ignoriert d�monen - (enno) repariert. - -+ strassen gingen verloren - (enno) read/write reparatur-routine. - -+ doppeltes ;; im CR - (enno) doppelt gemacht, in sprintf und im fprintf. - -+ Trollst�rke-G�rtel - (enno) wurde nicht um SCALEWEIGHT skaliert, brachte nur 5 GE. - -+ kampfresultat in Sun Lake City. funktioniert Magieschutz nicht? - -- komische leerzeilen in kampfabrechnungen: -> Schauspieler (pg2d) verlor 9 Personen, 0 �berlebten und 1 flohen nach Heredon -> (-3,5). -> H�ndler (uk53) verlor 1 Personen, 0 �berlebten und 0 flohen nach Lykubet -> (-1,3). -> -> Schattenluchse (umnb) verlor 18 Personen, 0 �berlebten und 0 flohen nach -> Sturmhafen (-2,5). -> Baumeister (f0o7) verlor 1 Personen, 0 �berlebten und 0 flohen nach Heredon -> (-3,5). - -? insekten, geht der handel in w�sten und s�mpfen? - -+ Meer-Vertraute k�nnen in Nichtk�stenl�ndern erscheinen. (wegen 3% in - select_famaliar()) - (corwin) Gefixt. - -+ Magielernen bei Vertrauten allgemein machen, da Goblin-Vertraute sonst - keine Magie lernen k�nnen. - -? kostenlose Talente lernen in Akademie geht nciht, wenn akademie nicht - finanziert und zwar nichtmal 30 tage - (corwin) Ist das wirklich so? Ich finde im Source keine Stelle, - die das bewirken k�nnte. - -+ Handelsg�terpreis wurde beim kauf zu sp�t erh�ht - -- astraler nebel taucht in messages mit koordinaten auf. - -? Mein Alchemist (gxd) hatte letzte Woche noch 2 Bauernlieb. EIn BENUTZE - Bauernlieb brachte mir die Fehlermeldung "Gouldie Horrn (gxd) in - Wywipozos (-1,0): 'benutze bauernlieb' - Die Einheit besitzt den Trank - nicht." ein und diese Woche hat er gar keine dieser Tr�nke mehr. - (Seine anderen Tr�nke waren davon nicht betroffen). - (corwin) Wann soll das passiert sein? Diese Runde hatte er kein - BENUTZE. - (enno) das mu�t du den fragen, der den bugreport gemacht hat. - -+ Leuchturm funktioniert nicht f�r Regionen, die in der - Regionsreihenfolge vor dem Leuchturm kommen - kein Report - (enno) repariert. - -? Probleme bei sp_charmingsong: Aufl�sung scheint nicht zu - funktionieren, wenn in der gleichen Runde die alte Partei gel�scht - wird. - -+ Jeder Verkauf reduzierte die Verkaufspreise. - (enno) Fehler beseitigt. - -+ Bauern wandern in und aus orkifierte Regionen. - (corwin) Unterbunden. - -+ Falsche Rundung beim Verhungern. - (corwin) Gefixt. - -+ HP von Eisengolems werden bei Mache nicht runterskaliert. - (corwin) gefixt - -? fl�chtlinge verdoppeln sich - (enno) da fehlte ein scale_number in der routine. - -+ luftschiff-landungen (edelmayer, 13.6.00) - (corwin) Gelandete Luftschiffe k�nnen in Zukunft beliebig ablegen, - ebenso startende. - -+ schiffe aus mallorn (stanka, 13.6.00) - (corwin) Gefixt, fehlende Abfrage in continue_ship() - -+ bei handel wird ein gut zuviel bezahlt (ashdurbuk, 13.6.00) - (enno) gefixt - -? Adressliste sollte gescramblet werden - (corwin) Implementiert - (enno) sortiern w�re besser - -+ Statistik: Lohn auf Ozean f�r Nichtmeermenschen weglassen - (corwin) Implementiert - -+ Karavelle in Sumpf - (corwin) Hoffentlich gefixt. - -+ Mehrfachnennungen in Kampfausl�sung - (corwin) Gefixt - -+ eisengolems ziehen ihr verbrauchtes eisen aus dem pool ab - (enno) repariert - -+ schiffbau mit mallorn geht nicht - (enno) es gab garkiene sonderbehandlung. ist drin, aber ohne poolnutzung - -? HELFE xyz NICHT funktioniert nicht. - (enno) Es mu� doch HELFE xyz ALLES NICHT hei�en. - -? HELFE GIB reicht scheinbar, um eine Burg betreten zu k�nnen. - -- Eisengolems �bergeben nichts an andere (Bugreport Thomas Stankats, 3.7.) - -- bug bei goblinklau (Jens Meirose, 9.7.00) - -- fehlende zaubersyntax im cr (stefan g�tz, e-client, 9.7.00) - -+ trank der wahrheit - beschreibung passt nicht zu zutatenliste (ashdurbuk, 3.7.00) - (corwin) Beschreibung ge�ndert. - -? bug bei beklauen (ilia, 40.6.00) - (enno) diebstahl aus dem pool ging bei reservierungen schief. neu: use_all(), get_all() - -- "Keine Gr�ber" (Hjalmar Bruns, 27.6.00) - trotz schlacht keine gr�ber gefunden - -+ "Burgenbau" (christian decomain, 26.6.00) - nicht neue gr��e, sondern alte z�hlt f�r das talent - (corwin) Gefixt. - -- "Antimagiekristalle" (stefan schubert, 26.6.00) - trotz antimagie finden zauber statt - -+ Im Astralraum kann man arbeiten - (corwin) maxworkingspeasants gab minimal 1 zur�ck. Das ausgebaut. Ich - hoffe ich habe alle DivByZero-M�glichkeiten, die dadurch entstehen - gefunden. - -+ W�lfe verschwinden nach der Schlacht nicht. - (corwin) Fehler in at_unitdissolve, gefixt. - -+ Sortierung der Adressliste nach Parteinummer funktioniert nicht. - (enno) war ein falscher cast, sch�tze ich. - -- Vertraute nehmen keine Gegenst�nde an. - -+ Mallorn f�r Schiffsreparatur geht nicht (Thomas Stanka, 14/8/00) - (enno) copy&paste bug - -- Mallorn f�r Schiffbau geht noicht (Zemsauer 9/8/00 - -+ Drachen bewachen Ozeane (10/8/00) - (corwin) ge�ndert - -- Doku zu Reserviere sollte auf GIB ALLES angepasst werden - -+ zauber auf temp-einheiten (Sven Howard, 13.8.00) - (corwin) F�r die Tyb-Zauber gefixt. Gibt es noch mehr? - -+ BE's Taktiker half den NK nicht im Kampf. - (enno) Es wurde HELFE BEWACHE statt HELFE KAEMPFE �berpr�ft. - -- Gabe des Chaos, Negativwirkung h�rt nicht mehr auf (Kollakowski, 24.8.00 ; Emmler, 19.8.00) - -- Meldung, Runen des Schutzes, ist buggy (Weinzinger, 23.8.00) - -- FOLGE EINHEIT geht nicht (Dagmar M�ller, 23.8.00) - -- FAHRE mit Reiter hat nicht funktioniert (Enno, 20.8.00) - -- S�gewerk funktioniert nicht (Andreas Beer, 15.8.00) - -- Mallorn f�r Leuchtt�rme verbauen? (Florian Lang, 15.8.00) - -+ Silberspenden an die eigene Partei? (Stean Reich, 20.8.00) - (corwin) Fehlendes spender->faction != bed�rftiger->faction in - get_food(). - -? Xandril vermutet, man k�nne mit Nahkampfwaffen aus der 2. Reihe k�mpfen. Vage Behauptung. - -+ GIB 0 EINHEIT geht nicht (Alke Rehling, 21.8.00; Alex Mielke, 21.8.00) - (corwin) Das war �berhaupt nicht implementiert. Quickhack eingebaut. - -+ Neue Katapultregel funktionert nicht! Datenfile 201, Kampf in Rudkepaso (-8,24). - (enno) nachladen war kaputt. - -- Tempeinheiten profitieren nicht von Uni - -- Sinkende Schiffe erzeugen keine Globalmeldung, damit sieht man die - nicht! - -== Aus PLAN �bertragen: == - -- Alp funktioniert nicht, Suchroutine wird nirgends aufgerufen und - enth�lt TODOs. - -- teil-verhungern: - "0;live" kommt im Template nicht vor. - -- Monsterauseinanderlaufen klappt nicht. - -- cansee() fehlt in vielen Zaubern. - -- Schiffeversenken gibt kaputte Meldung - Cef'az (c142) in D�r'Aglar (18,-16) versenkt die X~Lc^H~@~[c^H^X~Gc^Hm - (17). - (Das Schiff war die Cir'mor (1142), Langboot) - -- Botschaft an Einheit <nr> gibt als Meldung nur - 'Eine Botschaft von xyz: "<nr>"' - -- Durch �bergeben kann man Silber vor Beklaue sch�tzen - -- Aufgel�ste Zauber (z.B. Magischer Pfad) sollten eine Meldung in der - Region geben. ('Die Stra�e ist verschwunden') - -- Meldungen zuhauf unvollst�ndig, Regionsangabe oder Einheitenkennung - fehlt. Sehr uneinheitlich. - -+ Zauberliste f�r D�monen wird nicht aktualisiert - (enno) gefixt. Erst nach randomevents() berechnen. - -- NUMMER PARTEI �ndert auch die Nummer der befehlenden Einheit - -+ Eigene Einheiten halfen nicht, wenn man attackiert hatte und gleichzeitig wurde. - (enno) Test in join_allies auf eigene Partei fehlte. - -- Einheit auf Schiff flieht, kommt aber nicht in Nachbarregion an (Marc Korevar, 14.09.00, Runde 207->208) - -? K�MPFE HELFE NICHT geht nicht. - (corwin) gefixt? - -+ Mehrere Kr�uterbeutel im CR - (enno) 2 wurde ausgegeben, wenn mehr als ein Kraut vorhanden. - -? Benennen fremder Schiffe ging nicht (Enno) - (corwin) gefixt? - -+ Anzeige von Zitadellen als "Burg" - -+ Bau von Geb�uden klappt nicht. "Baut f�r 0 an ..." - (enno) Bei want=0 wurde nix gebaut. Ich dooof. - -+ Traumschl��chen sind erkennbar. - (enno) gefixt. - -- Einheiten k�nnen nach Kampf noch lange Befele ausf�hren. (Wenninger, 30.09.) - -? Karawanserei funktioniert nicht, Gr��e stimmt nicht - (enno) Max. Gr��enpunkte der Karawanserei waren 50 statt 10 - -+ NUMMER PARTEI �ndert die Einhietennummer (G. Grundh�fer, 5.10.) - (enno) ein break im switch fehlte - -? Boot mit 4% Schaden hat 40 Kapazit�t? (M.Bank, 5.10.) - (enno) ist ein Rundungsfehler in shipcapacity(). �nderung noch nicht getestet. - -- Sturmmeldungen fehlen (M. Bank, 5.10.) - -- Durch Sturm unterwegs stark besch�digte Schiffe melden, das sie nicht ablegen k�nnen. (M. Bank, 5.10.) - -- Silberspende mri->bierbrauer falschrum? (S. Reich, 5.10.) - -+ FUZZY wirkt nicht auf PARTEI-Befehl (Mangar, 5.10.) - (enno) Ich denke, da habe ich jetzt eine wirklich gute L�sung gefunden. - -? Steinverbrauch beim Burgenbau falsch (Kirche des Morgenstern, 5.10.) - (stefan) lag wohl an - -+ Hohe Patzerchance Draig-Magier (Knoche, 5.10.) - (enno) Er hat auf maximaler Stufe, T 13, gezaubert. - -+ BENENNE FREMDES geht nicht mit base36 (wuzel, 5.10.) - (enno) Repariert, nicht schwer. - -+ Hafenbau > 25 (Kl�stenhof, 5.10.) - (stefan, enno) falscher eintrag im buildingtype - -? Zombies gehen trotz massiver Katapultangriffe nicht kaputt (Meirose, Reich, et al, 5.10.) - (enno) In normalen K�mpfen mit Skeletten sieht das okay aus. - -? Boot wird mehr als 100% repariert (Wachtendorf, 5.10.) - (stefan) fehler in build - -+ geb�ude werden doppelt bezahlt (Mueller, Rehling, et al, 5.10.) - (enno) heftiger bug, f�hrt zu neuauswertung. flag wurde nicht getestet - -+ einst�rzendes geb�ude f�hrt zu einheiten mit 0 personen (o. eckstein, 5.10.) - (enno) remove_empty_units() einfach noch einmal vor der reportgenerierung machen. - -? Vermishcung zweier Z�ge? (Necron, 16.10.) - -+ chaosregionen auf Insel der Partei o8 (Kirche des morgenstern, 16.10.) - -+ �berfl�ssige Gruppen l�schen (Sassmanshausen 16.10.) - (Stefan) g->members werden jetzt wieder runtergez�hlt. - -? Steingolems vermehren sich, statt zu verschwinden (Emmler, 16.10.) - (enno) sollte sich mit der neuen production erledigt haben. - -- feuerwand bug, nicht erschienen (wolfgang haupt 16.10.) - -+ mallorn beim neuen geb�udeschiffs-bau (Stanka, 16.10.) - (enno) ja, das klappt nicht mehr - -+ keine Meldungen im CR (diverse, 16.10.) - (enno) corwin hat das beim abschaltender messagelevel verbockt. - -- messagelevel kaputt, warnings-pointer ist verhunzt (auswertung) - -- bekannte Zauber werden erneut angezeigt. - -+ Steinbruch hat verbraucht 5 Steine statt 5 Holz (ullrich, 30.10.) - (stefan) gefixed - -- Luxusgut-Preise fallen (diverse, 30.10.) - (corwin) Auswirkungen gefixt, aber Bug vermutlich noch da. - -+ Gewichtsberechnung geht nicht (diverse, 30.10.) - (corwin) Eine wichtige Zeile in weight() ist vergessen worden. - -+ Lokalisierung in Kampf und Produktion falsch (diverse, 30.10.) - (enno) repariert - -+ Luxusgut-Preise im CR falsch (diverse, 30.10.) - (stefan) Verkaufte G�ter wurden mit Preis=0 statt negativem - Grundpreis angegeben. - -+ Materialpool funktioniert nicht bei Tr�nken (Katja, 30.10.) - (enno) in welchem kontext? GIB, BENUTZE, MACHE? - (katja) BENUTZE - (enno) gefixed. - -+ Alchemisten ohne Produktion (Katja, 30.10.) - (stefan) i_change fehlte in create_potion() - -+ Schrottige Meldungen bei MACHE Trank (diverse, 30.10.) - (stefan) create_potion wurde mit zuwenig Parametern aufgerufen - -+ Zuviele Kr�uterbeutel (Katja, 30.10.) - (enno) repariert, fehler in report_item. - -+ Schmiede funktioniert nicht (diverse, 30.10.) - (enno) Schmiede funktioniert wieder. Aufruf von init_buildings() fehlte. - -+ Zauber verbrauchen keine Aura (diverse, 30.10.) - (enno) res_changeaura, res_changepremaura, res_changehp u.a. - waren not implemented. erledigt. - -+ Zauber erzeugen keine Gegenst�nde (diverse, 30.10.) - -? Wald/Ebenen-Kr�uter wechseln nicht, wenn sich das Terrain �ndert - (wuzel, 30.10) - -+ Waldkr�uter nicht korrekt initialisiert, in W�ldern sind jetzt - Ebenenkr�uter (wuzel, 30.10.) - (enno) rterrain() statt mainterrain() benutzt. - (enno) gefixt, korrektur() erledigt das n�chste woche. - -+ Verkaufte Luxusg�ter werden nicht abgezogen, sondern dazugez�hlt - (mbank, 30.10) - (enno) gefixt, das i_change war falsch. (copy&paste) - -- Gew�rze wurde nicht erkannt (stanka, 30.10.) - (enno) Mehrzahl von Gew�rz ist Gew�rz. - Ich habe einen String f�r spices eingebaut, aber der wird noch nicht verwendet, - da au�er den korrekten Namen der Items noch keine aliase verarbeitet werden. - (enno) am besten w�ren standardisierte abk�rzungen. ich hab da was im kopf. - -+ doppelte Silberbeutel (diverse, 30.10.) - (enno) die alte routine war noch drin, gefixt. - -+ Abzug von Luxusg�tern immer noch falsch: G�ter aus dem Pool - werden bei Verkauf von der Einheit gezogen, assert in - i_change triggert. - (enno) Umstellung auf new_use_pooled() und kleiner speedup. - -- Silberspenden werden gemacht, obwohl eigentlich unn�tig gewesen. - (katja) warscheinlich am Anfang der Runde nicht genug Geld f�r die - Geb�udeversorgung, dann helfen die aliierten aus - -+ Gespenster aus der Unterwelt (w9kL) erzielte 1026 Treffer und t�tete 0 Gegner. - (enno) scheisse. waffenloser kampf. fixed. - -+ 42 K�mpfer aus Rukh-R (1ftp) feuern ihr Katapult ab: - (enno) ...und sie haben nur 42 katapulte. alle in der gleichen runde ist zuviel. - (enno) war nur kosmetisch - -- Parteien aus Durchreiseregionen erschienen nicht in den ADressen - -- Transporteure (2jws) arbeitet in Twerken (-7,8) f�r einen Lohn von 70 - statt 65 Silber. - -+ Illaun-Zauber Schoene/Schlechte Tr�ume wirkt zu kurz: beginnt erst in der - darauffolgenden runde, endet aber evtl. schon in der aktuellen. - (katja) irgendwer hatte bei Sch�ne Tr�ume die Dauer total verhuzt. - -+ Schattend�monen k�nnen reservieren (P. Horner, 15.09.00) - (katja) repariert - -+ Tunnelw�rmer k�nnen Stra�enbau statt Steinbau (H. Steinbei�er, 16.09.00) - -+ Vertraute nehmen nichts an (O. Eckstein, 17.09.00) - (katja) ist gefixt - -- FAHRE funktioniert nicht (G. Gro�berger, 19.09.00) - (enno) ist bei uns auch schonmal schiefgegangen, kann was dran sein. - -? Bei "Verw�nschung" sieht das Opfer der Verw�nschung den Zaubernden. - (enno) ich glaub, das hatte ich gefixt. - -? "Schl�gerzwerg (id84) in Kitpad (-1,2): 'KAEMPFE HELFE NICHT' - unbekannter - Kampfstatus." - (corwin) Kann nicht sein. Ist das noch aktuell? - -- Einheit auf Schiff flieht nicht in benachbarte Region (M. Korevaar, 24.09.00) - -- Astraler Ausgang funktioniert nicth (Synes Elischka, 29.09.2000) - -- Leuchtturmeinsturz macht Einheiten mit 0 Personen (O. Eckstein, 05.10.2000) - * Krath (hqk), 0 Elfen, "lerne wahrnehmung"; In eine dunkle Robe geh�llter - Elf - er vertritt hier seinen Herrn und Meister. - -? Bergwerk st�rzt trotz genug Silber ein (M. M�ller, 05.10.2000) - (enno) Die Routine ist seit dem �berarbeitet worden. - -+ Zauber "Runen des Schutzes" nicht base36 (F. Wolkwitz, 04.11.2000) - Maehrlin (39x) in Amandor (0,23): 'zaubere Runen~des~Schutzes Schiff 1bq' - - Schiff 1 wurde nicht gefunden. - (katja) #define FULL_BASE36 war vergessen worden - -+ Schmieden funktioiniern nicht (O. Eckstein, 05.11.2000) - (enno) Beispiel �berpr�ft, er muss sich verrechnet haben. - -- �bergabe klappte mit Pferd, aber nicht mit Silber? I. Schr�der, 05.11.2000) - -- einheit waru mcht zu wenig Kettenhemden (A. Neumann, 05.11.2000) - (enno) evtl. nicht oben in der schmiede gestanden? trotzdem zu wenig - -- einhiet buf erzeugt 5 statt 6 schwertern (dwalin, 6.09.2000) - (enno) die hat sich bestimmt verechnet. - -+ kostenlose kostenpflichtige talente mit lehrer (A. Klauer, 06.11.2000) - (stefan) Anteiliges Lernen betrifft jetzt alle Effekte mit. - -- hegg hat genug Material, kann aber nicht produzieren (P. Burkert, 06.11.00) - -+ Kein Anlegen in neuen Regionstypen m�glich (Joern Stampehl, 09.11.00) - (corwin) Neue Terraintypen fehlten in coast_allowed komplett. - -o Leuchtt�rme schauen mindestens eine Region zu weit. (Gr��e 10 - Leuchtturm 3 Regionen.) - (stefan) Bei mir nicht. Zu beachten ist, da� man halt 2 Regionen weit sieht, - und DANN noch die Nachbarregionen drangeh�ngt werden. - -+ 'cannot resolve action' vereinzelt - (enno) die alten actios sind weg, damit erledigt sich das wohl. - -+ timeout auf eine Vertrautenl�schung - (enno) Das ist dank neuer events wohl auch repariert? - -+ Museums'geb�ude' k�nnen umbenannt werden - (corwin) Generische Geb�ude (bt_generic) k�nnen bis zur Implementation - eines besseren Mechanismus nicht mehr umbenannt werden. - -+ Benennen fremder Burgen klappt nicht. - (corwin) Bei der Umstrukturierung der Geb�ude vergessen worden. - -+ Benennen fremder Schiffe und Geb�ude ist nicht an Locales angepa�t. - (corwin) Wird nicht mehr nahnd des Namens, sondern mit einem Flag gepr�ft. - -+ Bauernfressen und Vertreiben trotz Vernichtung der Untoten - (corwin) In der Reihenfolge vor die Zufallsereignisse gelegt. - -+ Stra�en �ber 100% fertig - (corwin) Fehler in build_road() - -+ Verfolgendes Schiff f�hrt in falsche Richtung - (corwin) u->wants bei Verfolgungen nicht mit 0 initialisiert. - -+ (katja) diverse Zauberfehlschl�ge, obwohl Aura �bertragen wurde (u.a. - Segne Steinkreis) weil VOR allen Zaubern, also auch vor dem - Auratransver, eine cancast �berpr�fung war, die zu dem Zeitpunkt - nat�rlich fehlschlug. - -- memoryleak in curseid? - -+ Fliehende Einheiten nehmen kein Silber mehr mit (Katja, 28.12.2000) - -+ Magiebegabte Vertraute haben keine Zauber mehr - -- lmsreward funktioiniert nicht (curse wird nicht gesetzt) - -- benutze item funktioniert nicht. itype->use ist �berall 0x0 - -- auch nichtpoolbare Resourcen wie Aura, HP, perm Aura sind im pool - -- lernen in akademie bringt 80 statt 70 Tage, ausser bei Magie, da - funktionierts? - (Zhardamon, irq 20.2.01) +BUGS + +? > nicht untersucht, fraglich +- > best�tigt, aber unerledigt ++ > erledigt +(!) kritische Bugs, die unbedingt vor der n�chsten Auswertung repariert werden m�ssen + ++ F�r alle nur den kurzen Report. War Fehler in einem logischen Ausdruck + in creport.c + ++ URSPRUNG hat eine kranke Semantik + (enno) repariert. Nach der alten Routine konnte man seine Koordinaten durch Neusetzen ermitteln! + ++ Die neuen Kampfmeldungen k�nnten Kosmetik brauchen, � la: Einheit(en) + (corwin) Das Gr�bste verbessert. K�nnte aber noch mehr Arbeit brauchen. + ++ im CR fehlen die Botschaften + (enno) Hatte S�ren nicht gemacht. ist im standard-cr jetzt drin. + ++ Orks k�nnen die Vermehrungsmeldungen nicht separat abschalten + (Henning) MSG_ORKVERMEHRUNG eingebaut, ist ML_INFO, kann also mit REPORT ORK WARN + abgestellt werden + ++ Talenttage gibt's f�r jedermann, der k�mpft + (enno) Nur noch f�r die, die min. 2 Runden lang k�mpfen. + ++ "Einheiten vor der x. Runde" wird einmal zuviel angezeigt. + (enno) War ein Fehler in der Berechnung von side::alive + ++ Karawansereien wirken sich nicht auf die Anzeige der Luxusg�ter aus. + ++ FL_LEFTSHIP wurde f�lschlicherweise gespeichert. + ++ Fehler im Handel, von Thorsten beobachtet. Einheiten verkaufen, ohne etwas zu haben. + Vermutung: Zwei gleichzeitig verkaufende Einheiten bedienne sich beide aus dem Pool. + (enno) Das auch, aber au�erdem wurden die G�ter dem falschen abgezogen. + ++ Kapit�ne ohne Wahrnehmung durchbrechen Nebelwand + (katja) Auch Kapit�ne m�ssen nun Wahrnehmung haben + ++ Mantel der Unverwundbarkeit wirkt nicht. + (corwin) survival_chance() gab einen Prozentwert zur�ck, gebraucht + wurde aber ein Wert von 0-1. Funktioniert die R�stungsfunktion? + ++ Absturz in set_resource() bei Kr�uterreservierung. + (corwin) Hektischer Bugfix (|| resource == NORESOURCE). + ++ Bug in hp_status (Cast/Klammerung) + ++ Ausdauerlernen und HP richtig verwurstet. + ++ Luftschiff + (enno) Eine Alraune wurde statt des Windbeutel verwendet. Auch, wenn man keine hatte. + ++ Fehler in den expandxxx routinen! + (enno) statt addlist(xxxorders) wurde addlist(&xxxorders) gemacht. + ++ Angabe 'erschoepft' bei Personen, die Ausdauer lernen. + (corwin) HP-Gewinn beim Ausdauer lernen war inkorrekt. + (corwin) Fehler gefunden, ich war blind. + ++ SCHWERER BUG: Orks bekommen falsche Lerntage + (enno) u->n statt u->no benutzt. + (enno) change_skill statt set_skill benutzt. + ++ SCHWERER BUG: Im Kampf gehen Talentwerte kaputt + (enno) set_number statt scale_unit + ++ SCHWERER BUG: Fliehende Einheiten ohne Talente + (enno) schlicht und einfach vergessen + ++ Trankbeschreibungen stimmen nicht mit Kr�utern �berein + (corwin) Beschreibungen waren schon bei den alten Tr�nken falsch. + ++ Ostfriesische Burgen konnten nicht gebaut werden + (enno) Fehler, soweit im Server, behoben: + wenn eine einheit MACHE X 123 sagt, und es gibt ein Geb�ude 123, + egal welchen Typs, dann baut sie Geb�ude 123 weiter. Auch wenn + sie selbst in einem anderen steht. + ++ in den Kampfbeschreibungen ist ein Umbruch zuviel. CR klappt nicht. + (enno) repariert. in addmessage() niemals \n benutzen! + ++ im Handel (sell) werden die Steuern nicht vom Verdienst abgezogen. + (martin+enno) repariert. Der spieler bezahlt. + ++ Einheiten leben nach dem Kampf noch weiter + (enno) u->number auf 0 setzen. + ++ herbs-pool hatte eine macke + (enno) use_pooled klappte nicht, weil NULL �bergeben wird. + Das k�nte den Thorsten-Bug erkl�ren. + ++ Einheiten von angegriffenen klagen �ber kampfersch�pfte Personen + (enno) flag setzen. + ++ �bergabe von 4. Magier an Elfenpartei klappt nicht. (Partei 10) + (corwin) u statt u2 in givemen() + (enno) in giveunit() auch. und daran ist es auch gescheitert. + ++ Antimagiezone sollte erst in der darauffolgenden Runde wirken. + (NEW-Flag setzen.) + (corwin) NEW-Flag wird gesetzt und in spell_active() abgefragt. + ++ move_monster() - warning + (enno) Variable d wurde nicht initialisiert. + ++ Rundungsfehler in scale_number, wenn Einheiten-Anzahl zu gro�. + (enno) repariert, noch undurchsichtiger geworden. + ++ Schiffe aus Mallorn bauen zieht keine Ressourcen aus der Region ab + (enno) repariert. Es wurde an use_pooled keine Region gegeben, + Test auf Mallorn fehlte v�llig. + ++ Zauber brauchen Holz als Komponenten. + (enno) Mallorn kann das Holz notfalls ersetzen. + ++ Elfenparteien konnten keinen 4. Magier �bergeben bekommen. + (enno) Es wurde bei der Quellpartei das Magiermax gefragt. + ++ Aji - die Drachent�ter (29206) hat -1 Gefallene zu beklagen. + Katzeneinheit. Evt. Kollision von Heilung und 14%-Chance. + (enno) gefunden. index�berschreitung, msvc macht's m�glich. + ++ random_neighbour() - warnings + (enno) implizite typecasts von int nach direction_t + ++ fliehende k�nnen von Schiffen herunterfliehen. + (enno) �nderung in fleeregion(), sollte das reparieren. + ++ Fliehende Magier verlieren evt. ihre Spr�che. + (enno) stimmt! dicker bug, wer war davon betroffen? + ++ Hitpointberechnung bei Einheitensplitting fehlerhaft. + (corwin) Gefunden. change_skill in transfermen macht Probleme, dort + ersetzt durch change_skill_transfermen. + ++ dazzle und demoralize klappten nicht. + (enno) neu implementiert. + ++ Stringzuweisungen in Mapper falsch. + ++ angegriffene einheiten k�nnen nichts tun + (enno) tritt in allen getesteten k�mpfen nicht mehr auf. + ++ fliehende einheiten attackieren in seltenen F�llen ein zweites mal. + (enno) gefixt. passierte bei einheiten, die komplett (ohne fluechttlings-einheit) wegrannten. + ++ HELFE GIB verhindert Einsatz von Dumpfbackbrot + (corwin) Ge�ndert, relevant ist jetzt nur noch der HELFE-Status des + Gebers. + ++ Meldung �ber fehlenden Zug irritiert Neueinsteiger + (corwin) Ge�ndert, Neueinsteiger bekommen die Meldung nicht mehr + ++ Meldungen zum Abtreiben fehlen. + (corwin) f->dh in drifting_ships wird nie gesetzt. + ++ Formatierungsfehler im Spionagebericht. + ++ Ents entstehen nicht. + ++ Vogelfreund als Einheit sichtbar (NR) + (corwin) Alle U_SPELL-Einheiten werden angezeigt? Wer hat da wieder + gefummelt, ohne zu testen... Auch Befehle kann man ihnen geben, + klasse Sache, bei ner Antimagiezone. + (enno) hihi. w�re ein cooles feature f�rs neue magsystem + (corwin) Brachialfix in readorders() und rpunit(). + ++ Verteidigung mit halbem Waffentalent gegen Fernwaffen funktioniert + nicht. + (corwin) Fehler lokalisiert, switch/case in hits(). Wie soll es sein? + ++ Es wurde vergessen, die Kampfwirkung der Antimagiezone an die + ver�nderte St�rke anzupassen. + (corwin) Gefixt, Durchbruchschance jetzt wieder normal. + ++ Katapulte ohne Talent Katapultbedienung benutzt. + (enno) Waffenauswahl war verhunzt. + ++ �berlange Zeilen werden in der Zugvorlage umgebrochen. + (corwin) In der Zugvorlage wird nicht mehr umgebrochen. + ++ Heilung funktioniert nicht. (Wyrm vollst�ndig geheilt.) + (corwin) Nicht reproduzierbar. Ursache unbekannt. + (corwin) Fehler in battle.c, Hitpointberechnung fehlerhaft, + wenn keine Toten in Einheit. + +? HP-Berechnung bei neu hinzurekrutierten scheint fehlerhaft. + (corwin) In Testspiel nicht reproduzierbar, scheint ok. + ++ Taktik funktioniert nicht korrekt, Werte werden nirgends verglichen. + (corwin) Taktikvergleich war nirgends implementiert. + ++ Drachen heilen nicht. + ++ Kampfmessages sind verwirrend. + (corwin) Kampfmeldungen aussagekr�ftiger gemacht. + ++ Sch�ler m�ssen Lehrer kontaktieren. + (corwin) Abfrage rausgenommen. Kein Sinn erkennbar. + ++ Handeln-Talent wurde negativ. + (corwin) Gefunden. Fehler in der Poolbehandlung in sell(). + +? Deadlock bei Kampf in Carwin. + (enno) war evtl. ein Problem mit der Alliiertenmatrix? + ++ Aus einem Kampf geflohene Einheiten bekommen keinerlei Kampferfahrung, + auch wenn sie vorher aktiv gek�mpft haben. + (katja) Kampferfahrung ist eh abgeschafft + +? Probleme beim �bergeben von Personen mit unterschiedlichem + Ausdauer-Talent. + ! was f�r ein problem? ! + +- Einige Kampftexte grammatisch falsch. (Plural einsetzen... andere + F�lle.) + ++ die Tavernen tun nichts + (enno) Neue Regeln fuer Tavernen, alte Tavernen konvertiert zu neuen. + ++ Semikolon in Strings f�hren zu �rger. + [BESCHREIBE EINHEIT "Schlaue Leute; Sie sind nicht dumm"]. + Generell kann man das Parsen noch verbessern. + (enno) komplett neuer parser + ++ Umlaute an einigen Stellen noch fehlend. (Bla lst sich auf.) + (enno) repariert + ++ Adresslisten sind nicht in Ordnung, es erscheinen Parteien, + die man nur parteigetarnt sieht. + (Faroul) sollte schon einige Zeit gefixt sein in spunit + +? Fernk�mpfer bekommen keine Kriegsbeute. + (enno) das ist doch sicher nicht mehr so. + ++ BEWACHE geht nicht (Marco Zielinski) + (enno) fehler gefunden, es fehlte ein ! + ++ Parteien bekommen Meldungen, die nichts mit ihnen zu tun haben. + (corwin) Fehler in givesilver, alter buf verwendet. + +- Fehler mit Pferden in plan_monsters. Ich wei� aber nicht, + wozu der Code gut sein soll, habe es markiert. (enno) + +? magres wird nicht beachtet. + (katja) wo? + +? Immer noch ersch�pfte Einheiten. + (enno) lag vielleicht an der kampf-hp-aufteilung, die wir aber im juli 00 gefixt haben? + +? Heilung funktioniert nicht. + +? Negative Handelsvolumina f�hren zu Absturz in expandselling. + (corwin) Quickfix f�ngt negative Mengen dort ab. Ursache f�r die + negativen Mengen noch nicht gefunden. Zusammenhang mit + VERKAUFE ALLES vermutet. + ! (enno) ! hatten wir das nicht repariert? + ++ Fehlende Anf�hrungszeichnen bei BENENNE f�hren zu String�berlauf. + (enno) gefixt, mit komplett neuem parser. + +- r->demand f�llt auf 0. assertion in readgame springt an. + (corwin) Brachialfix beim Einlesen. Ursache nicht gefunden. + +- flutwellen l�schen bauern, silber und sonstige regionswerte nicht. + +- flutwellen vernichten schiffe, aber nicht die besatzung + +- �bergaben k�nnen an Einheiten erfolgen, die man nicht sieht. + Auf diese Weise k�nnen Tarner identifiziert werden. (In dogive() + fixen!?) auf kontaktiere pr�fen, dann erlauben + ++ Betrete Schiff sollte vor Attackiere kommen, um att,betrete,nach + zu verhindern. + (corwin) Reihenfolge unver�ndert, aber trotzdem gefixt in + building/shipowner. + ++ Formatierungsproblem: Zentrierte lange Strings beginnen manchmal + schon in Spalte 0. Vermutlich Rundungsproblem. + (enno) in zukunft sollen eh alle bei spalte 0 anfangen. + ++ addmessage( ,"", ) erzeugt eine Zeile mit einem Space "^ $" + (enno) addmessage fliegt eh raus + ++ Magieresistenz funktioniert nicht. + (corwin) Wieder eingebaut. + ++ Drachen greifen trotz WARTEN an. + (corwin) Hoffentlich gefixt, Verwechslung thisorder, lastorder + ++ Ablegen in Nachbarregionen funktioniert nicht. + (corwin) Gefixt. + ++ Kapit�ne und Burgherren stehen in der Zugvorlage nicht an der + richtigen Stelle. + (enno) eingebaut. + ++ Im Gletscher ist zuviel Eisen. Menge begrenzen. + (corwin) Max 80 Eisen pro Gletscherregion. + ++ Nebelw�lle? + (corwin) Nebelwall-Anzeige in describe() war Unfug, ebenso + is_fogwalled(). + ++ Absturz bei destroy_ship durch zuviel Schaden. + ++ reale Koordinaten in den Fehlermeldungen in sail() + (katja) durch regionid() ersetzt + ++ Beschriftung der Meriankarten falsch (Beschriftung oben verschoben) + (enno) sollte gefixt sein. + ++ Man sieht Botschaften in Regionen, die nur vom Leuchtturm gesehen + werden. + (corwin) Abfrage in die Reportgenerierung eingebaut. + ++ CR bei vorigem �bersehen. + (enno) gefixt. + ++ Fl�chtende Drachen hinterlassen Drachenkopf und -blut. + (corwin) Hoffentlich gefixt. + +? Eine Partei in einer Kampfregion erhielt keinen Kampfbericht. + ++ Fl�chtende Einheiten verlassen Burgen und Geb�ude evt. nicht. + (corwin) Fliehende Einheiten verlassen auf jeden Fall Geb�ude und + Schiffe. + ++ von Turmregionen erh�lt man keine Durchreiseereignisse + (katja) gefixt + ++ Im CR ist erkennbar, ob eine Region Mallornregion ist. + (corwin) Mallorn nur noch = 1, wenn auch B�ume da sind. + ++ Magieresistenz f�r Drachen falsch. + (corwin) magicresistance() mu� nat�rlich auf alles wirken. + ++ "Maentel" ohne Umlaut wird nicht erkannt. + (corwin) In Tabelle eingef�gt. + ++ Illusionen werden als Migranten gez�hlt. + (corwin) count_migrants pr�fte nur auf nonplayer(), nicht auf + Illusionen. + ++ Werden K�mpfer auf Schiffen in einen Kampf gezogen bleiben + die Schiffe unbesch�digt. + (corwin) Damage-Routine ber�cksichtigte nur Kapit�ne. + ++ Adressen von Parteien, die man nur in einer Turmregion oder + Durchreiseregion sieht, stehen im NR aber nicht im CR + ++ Von Migranten und Untoten erzeugte TEMP-Einheiten haben den falschen + Typ/Rasse. + (corwin) u->race statt u->faction->race + ++ material- und silberpool in den cr mit aufnehmen + (corwin) Neues Tag ;Optionen mit f->options + ++ Fl�chtende Einheiten werden evt in mehrere K�mpfe verwickelt, wenn die + Region, in die sie fl�chten, sp�ter ausgewertet wird. + (enno) sollte l�ngst gefixt sein. + ++ Schiffe, die in der selben Region an- wie ablegen, haben die kueste + falsch gesetzt.und kriegen keine durchreiseinfos. + (corwin) Zumindest die K�stengeschichte ist gefixt. (Auch das hatte + ich �brigens schonmal gemacht.) + +? Schiffe, die in der selben Region an- wie ablegen, haben die kueste + falsch gesetzt.und kriegen keine durchreiseinfos. + (corwin) K�ste gefixt. Durchreiseinfos m��ten imho kommen. + ++ bugreport isilpetz, teleport funktioniert nicht, obwohl kontaktiert wurde. + (corwin) Gefixt. Isilpetz'Partei mu� in TELEPORT_HACK extra + ber�cksichtigt werden. + ++ Ein Kampf, der 1+1 Kampfrunden dauert, gibt keine Kampferfahrung. + (corwin) Ge�ndert. + ++ Mapper - Einheit ins Clip nehmen geht nicht. (Es wird eine scheinbar + ausgew�rfelte Einheit genommen.) + (corwin) atoi36-Umstellung vergessen. Gefixt. + ++ von Migranten rekrutierte Temp-Einheiten erscheinen als eine andere Rasse als sie sind. + (enno) gefixt. + ++ mehrere Ponnukis + (enno) gefixt. + +? artefakte werden auf der flucht nicht mitgenommen - bugreport 26.oct.99 stefan reich + (corwin) Alte Flucht rausgenommen. + (enno) stefan sagt, es sei schon wieder passiert. + (corwin) War nur in der alten Flucht �berhaupt ber�cksichtigt. + 0 Gewicht-Items werden jetzt wie Pferde behandelt. (Ein + Exemplar pro Person wird bei Flucht mitgenommen.) + + Dies bedeutet, da� Fl�chtlinge immer z.B. einen MdU + mitnehmen, wenn in der Einheit vorhanden. Das ist eigentlich + nicht gut, aber nicht ohne gro�en Aufwand anders zu l�sen. + ++ Merian-X-Koordinaten sind manchmal verschoben. + (corwin) Rundungsfehler bei der Kartenerstellung. Bitte nochmal + im Spiel nachgucken, ob Fix ok. + (enno) Merian ist rausgeflogen + ++ Diebstahl kann durch TEMP-Machen verhindert werden + (enno) Reihenfolge des shash in destroy_unit falsch. + +- Durch den selben trick (TEMP-�bergabe) kann man sich vor + spionage sch�tzen + ++ Parteien aus Leuchtturmregionen ersheinne nicht in der Adressliste. + (enno) ich glaub, ich hab's. oder doch nicht? + ++ Bauernblut hilft auch fremden D�moneneinheiten, + (enno) Auswirkungen kann man vernachl�ssigen. niemand hat + >100 D�monen aus zwei parteien in einer region mit <100 bauern. + ++ potion-effects werden in scale_number nicht ber�cksichtigt + (enno) repariert, skalieren jetzt genau wie skills. + +- assert in battle.c:4958 wird getriggert. Schlecht reproduzierbar. + (enno) ein paar asserts zus�tzlich eingebaut, falls es nochmal passiert. + ++ ; terminiert einlesen der Befehlsdatei. + (enno) repariert. 'comment' wurde nie wieder false. + ++ fix_irace ignoriert d�monen + (enno) repariert. + ++ strassen gingen verloren + (enno) read/write reparatur-routine. + ++ doppeltes ;; im CR + (enno) doppelt gemacht, in sprintf und im fprintf. + ++ Trollst�rke-G�rtel + (enno) wurde nicht um SCALEWEIGHT skaliert, brachte nur 5 GE. + ++ kampfresultat in Sun Lake City. funktioniert Magieschutz nicht? + +- komische leerzeilen in kampfabrechnungen: +> Schauspieler (pg2d) verlor 9 Personen, 0 �berlebten und 1 flohen nach Heredon +> (-3,5). +> H�ndler (uk53) verlor 1 Personen, 0 �berlebten und 0 flohen nach Lykubet +> (-1,3). +> +> Schattenluchse (umnb) verlor 18 Personen, 0 �berlebten und 0 flohen nach +> Sturmhafen (-2,5). +> Baumeister (f0o7) verlor 1 Personen, 0 �berlebten und 0 flohen nach Heredon +> (-3,5). + +? insekten, geht der handel in w�sten und s�mpfen? + ++ Meer-Vertraute k�nnen in Nichtk�stenl�ndern erscheinen. (wegen 3% in + select_famaliar()) + (corwin) Gefixt. + ++ Magielernen bei Vertrauten allgemein machen, da Goblin-Vertraute sonst + keine Magie lernen k�nnen. + +? kostenlose Talente lernen in Akademie geht nciht, wenn akademie nicht + finanziert und zwar nichtmal 30 tage + (corwin) Ist das wirklich so? Ich finde im Source keine Stelle, + die das bewirken k�nnte. + ++ Handelsg�terpreis wurde beim kauf zu sp�t erh�ht + +- astraler nebel taucht in messages mit koordinaten auf. + +? Mein Alchemist (gxd) hatte letzte Woche noch 2 Bauernlieb. EIn BENUTZE + Bauernlieb brachte mir die Fehlermeldung "Gouldie Horrn (gxd) in + Wywipozos (-1,0): 'benutze bauernlieb' - Die Einheit besitzt den Trank + nicht." ein und diese Woche hat er gar keine dieser Tr�nke mehr. + (Seine anderen Tr�nke waren davon nicht betroffen). + (corwin) Wann soll das passiert sein? Diese Runde hatte er kein + BENUTZE. + (enno) das mu�t du den fragen, der den bugreport gemacht hat. + ++ Leuchturm funktioniert nicht f�r Regionen, die in der + Regionsreihenfolge vor dem Leuchturm kommen - kein Report + (enno) repariert. + +? Probleme bei sp_charmingsong: Aufl�sung scheint nicht zu + funktionieren, wenn in der gleichen Runde die alte Partei gel�scht + wird. + ++ Jeder Verkauf reduzierte die Verkaufspreise. + (enno) Fehler beseitigt. + ++ Bauern wandern in und aus orkifierte Regionen. + (corwin) Unterbunden. + ++ Falsche Rundung beim Verhungern. + (corwin) Gefixt. + ++ HP von Eisengolems werden bei Mache nicht runterskaliert. + (corwin) gefixt + +? fl�chtlinge verdoppeln sich + (enno) da fehlte ein scale_number in der routine. + ++ luftschiff-landungen (edelmayer, 13.6.00) + (corwin) Gelandete Luftschiffe k�nnen in Zukunft beliebig ablegen, + ebenso startende. + ++ schiffe aus mallorn (stanka, 13.6.00) + (corwin) Gefixt, fehlende Abfrage in continue_ship() + ++ bei handel wird ein gut zuviel bezahlt (ashdurbuk, 13.6.00) + (enno) gefixt + +? Adressliste sollte gescramblet werden + (corwin) Implementiert + (enno) sortiern w�re besser + ++ Statistik: Lohn auf Ozean f�r Nichtmeermenschen weglassen + (corwin) Implementiert + ++ Karavelle in Sumpf + (corwin) Hoffentlich gefixt. + ++ Mehrfachnennungen in Kampfausl�sung + (corwin) Gefixt + ++ eisengolems ziehen ihr verbrauchtes eisen aus dem pool ab + (enno) repariert + ++ schiffbau mit mallorn geht nicht + (enno) es gab garkiene sonderbehandlung. ist drin, aber ohne poolnutzung + +? HELFE xyz NICHT funktioniert nicht. + (enno) Es mu� doch HELFE xyz ALLES NICHT hei�en. + +? HELFE GIB reicht scheinbar, um eine Burg betreten zu k�nnen. + +- Eisengolems �bergeben nichts an andere (Bugreport Thomas Stankats, 3.7.) + +- bug bei goblinklau (Jens Meirose, 9.7.00) + +- fehlende zaubersyntax im cr (stefan g�tz, e-client, 9.7.00) + ++ trank der wahrheit - beschreibung passt nicht zu zutatenliste (ashdurbuk, 3.7.00) + (corwin) Beschreibung ge�ndert. + +? bug bei beklauen (ilia, 40.6.00) + (enno) diebstahl aus dem pool ging bei reservierungen schief. neu: use_all(), get_all() + +- "Keine Gr�ber" (Hjalmar Bruns, 27.6.00) - trotz schlacht keine gr�ber gefunden + ++ "Burgenbau" (christian decomain, 26.6.00) - nicht neue gr��e, sondern alte z�hlt f�r das talent + (corwin) Gefixt. + +- "Antimagiekristalle" (stefan schubert, 26.6.00) - trotz antimagie finden zauber statt + ++ Im Astralraum kann man arbeiten + (corwin) maxworkingspeasants gab minimal 1 zur�ck. Das ausgebaut. Ich + hoffe ich habe alle DivByZero-M�glichkeiten, die dadurch entstehen + gefunden. + ++ W�lfe verschwinden nach der Schlacht nicht. + (corwin) Fehler in at_unitdissolve, gefixt. + ++ Sortierung der Adressliste nach Parteinummer funktioniert nicht. + (enno) war ein falscher cast, sch�tze ich. + +- Vertraute nehmen keine Gegenst�nde an. + ++ Mallorn f�r Schiffsreparatur geht nicht (Thomas Stanka, 14/8/00) + (enno) copy&paste bug + +- Mallorn f�r Schiffbau geht noicht (Zemsauer 9/8/00 + ++ Drachen bewachen Ozeane (10/8/00) + (corwin) ge�ndert + +- Doku zu Reserviere sollte auf GIB ALLES angepasst werden + ++ zauber auf temp-einheiten (Sven Howard, 13.8.00) + (corwin) F�r die Tyb-Zauber gefixt. Gibt es noch mehr? + ++ BE's Taktiker half den NK nicht im Kampf. + (enno) Es wurde HELFE BEWACHE statt HELFE KAEMPFE �berpr�ft. + +- Gabe des Chaos, Negativwirkung h�rt nicht mehr auf (Kollakowski, 24.8.00 ; Emmler, 19.8.00) + +- Meldung, Runen des Schutzes, ist buggy (Weinzinger, 23.8.00) + +- FOLGE EINHEIT geht nicht (Dagmar M�ller, 23.8.00) + +- FAHRE mit Reiter hat nicht funktioniert (Enno, 20.8.00) + +- S�gewerk funktioniert nicht (Andreas Beer, 15.8.00) + +- Mallorn f�r Leuchtt�rme verbauen? (Florian Lang, 15.8.00) + ++ Silberspenden an die eigene Partei? (Stean Reich, 20.8.00) + (corwin) Fehlendes spender->faction != bed�rftiger->faction in + get_food(). + +? Xandril vermutet, man k�nne mit Nahkampfwaffen aus der 2. Reihe k�mpfen. Vage Behauptung. + ++ GIB 0 EINHEIT geht nicht (Alke Rehling, 21.8.00; Alex Mielke, 21.8.00) + (corwin) Das war �berhaupt nicht implementiert. Quickhack eingebaut. + ++ Neue Katapultregel funktionert nicht! Datenfile 201, Kampf in Rudkepaso (-8,24). + (enno) nachladen war kaputt. + +- Tempeinheiten profitieren nicht von Uni + +- Sinkende Schiffe erzeugen keine Globalmeldung, damit sieht man die + nicht! + +== Aus PLAN �bertragen: == + +- Alp funktioniert nicht, Suchroutine wird nirgends aufgerufen und + enth�lt TODOs. + +- teil-verhungern: + "0;live" kommt im Template nicht vor. + +- Monsterauseinanderlaufen klappt nicht. + +- cansee() fehlt in vielen Zaubern. + +- Schiffeversenken gibt kaputte Meldung + Cef'az (c142) in D�r'Aglar (18,-16) versenkt die X~Lc^H~@~[c^H^X~Gc^Hm + (17). + (Das Schiff war die Cir'mor (1142), Langboot) + +- Botschaft an Einheit <nr> gibt als Meldung nur + 'Eine Botschaft von xyz: "<nr>"' + +- Durch �bergeben kann man Silber vor Beklaue sch�tzen + +- Aufgel�ste Zauber (z.B. Magischer Pfad) sollten eine Meldung in der + Region geben. ('Die Stra�e ist verschwunden') + +- Meldungen zuhauf unvollst�ndig, Regionsangabe oder Einheitenkennung + fehlt. Sehr uneinheitlich. + ++ Zauberliste f�r D�monen wird nicht aktualisiert + (enno) gefixt. Erst nach randomevents() berechnen. + +- NUMMER PARTEI �ndert auch die Nummer der befehlenden Einheit + ++ Eigene Einheiten halfen nicht, wenn man attackiert hatte und gleichzeitig wurde. + (enno) Test in join_allies auf eigene Partei fehlte. + +- Einheit auf Schiff flieht, kommt aber nicht in Nachbarregion an (Marc Korevar, 14.09.00, Runde 207->208) + +? K�MPFE HELFE NICHT geht nicht. + (corwin) gefixt? + ++ Mehrere Kr�uterbeutel im CR + (enno) 2 wurde ausgegeben, wenn mehr als ein Kraut vorhanden. + +? Benennen fremder Schiffe ging nicht (Enno) + (corwin) gefixt? + ++ Anzeige von Zitadellen als "Burg" + ++ Bau von Geb�uden klappt nicht. "Baut f�r 0 an ..." + (enno) Bei want=0 wurde nix gebaut. Ich dooof. + ++ Traumschl��chen sind erkennbar. + (enno) gefixt. + +- Einheiten k�nnen nach Kampf noch lange Befele ausf�hren. (Wenninger, 30.09.) + +? Karawanserei funktioniert nicht, Gr��e stimmt nicht + (enno) Max. Gr��enpunkte der Karawanserei waren 50 statt 10 + ++ NUMMER PARTEI �ndert die Einhietennummer (G. Grundh�fer, 5.10.) + (enno) ein break im switch fehlte + +? Boot mit 4% Schaden hat 40 Kapazit�t? (M.Bank, 5.10.) + (enno) ist ein Rundungsfehler in shipcapacity(). �nderung noch nicht getestet. + +- Sturmmeldungen fehlen (M. Bank, 5.10.) + +- Durch Sturm unterwegs stark besch�digte Schiffe melden, das sie nicht ablegen k�nnen. (M. Bank, 5.10.) + +- Silberspende mri->bierbrauer falschrum? (S. Reich, 5.10.) + ++ FUZZY wirkt nicht auf PARTEI-Befehl (Mangar, 5.10.) + (enno) Ich denke, da habe ich jetzt eine wirklich gute L�sung gefunden. + +? Steinverbrauch beim Burgenbau falsch (Kirche des Morgenstern, 5.10.) + (stefan) lag wohl an + ++ Hohe Patzerchance Draig-Magier (Knoche, 5.10.) + (enno) Er hat auf maximaler Stufe, T 13, gezaubert. + ++ BENENNE FREMDES geht nicht mit base36 (wuzel, 5.10.) + (enno) Repariert, nicht schwer. + ++ Hafenbau > 25 (Kl�stenhof, 5.10.) + (stefan, enno) falscher eintrag im buildingtype + +? Zombies gehen trotz massiver Katapultangriffe nicht kaputt (Meirose, Reich, et al, 5.10.) + (enno) In normalen K�mpfen mit Skeletten sieht das okay aus. + +? Boot wird mehr als 100% repariert (Wachtendorf, 5.10.) + (stefan) fehler in build + ++ geb�ude werden doppelt bezahlt (Mueller, Rehling, et al, 5.10.) + (enno) heftiger bug, f�hrt zu neuauswertung. flag wurde nicht getestet + ++ einst�rzendes geb�ude f�hrt zu einheiten mit 0 personen (o. eckstein, 5.10.) + (enno) remove_empty_units() einfach noch einmal vor der reportgenerierung machen. + +? Vermishcung zweier Z�ge? (Necron, 16.10.) + ++ chaosregionen auf Insel der Partei o8 (Kirche des morgenstern, 16.10.) + ++ �berfl�ssige Gruppen l�schen (Sassmanshausen 16.10.) + (Stefan) g->members werden jetzt wieder runtergez�hlt. + +? Steingolems vermehren sich, statt zu verschwinden (Emmler, 16.10.) + (enno) sollte sich mit der neuen production erledigt haben. + +- feuerwand bug, nicht erschienen (wolfgang haupt 16.10.) + ++ mallorn beim neuen geb�udeschiffs-bau (Stanka, 16.10.) + (enno) ja, das klappt nicht mehr + ++ keine Meldungen im CR (diverse, 16.10.) + (enno) corwin hat das beim abschaltender messagelevel verbockt. + +- messagelevel kaputt, warnings-pointer ist verhunzt (auswertung) + +- bekannte Zauber werden erneut angezeigt. + ++ Steinbruch hat verbraucht 5 Steine statt 5 Holz (ullrich, 30.10.) + (stefan) gefixed + +- Luxusgut-Preise fallen (diverse, 30.10.) + (corwin) Auswirkungen gefixt, aber Bug vermutlich noch da. + ++ Gewichtsberechnung geht nicht (diverse, 30.10.) + (corwin) Eine wichtige Zeile in weight() ist vergessen worden. + ++ Lokalisierung in Kampf und Produktion falsch (diverse, 30.10.) + (enno) repariert + ++ Luxusgut-Preise im CR falsch (diverse, 30.10.) + (stefan) Verkaufte G�ter wurden mit Preis=0 statt negativem + Grundpreis angegeben. + ++ Materialpool funktioniert nicht bei Tr�nken (Katja, 30.10.) + (enno) in welchem kontext? GIB, BENUTZE, MACHE? + (katja) BENUTZE + (enno) gefixed. + ++ Alchemisten ohne Produktion (Katja, 30.10.) + (stefan) i_change fehlte in create_potion() + ++ Schrottige Meldungen bei MACHE Trank (diverse, 30.10.) + (stefan) create_potion wurde mit zuwenig Parametern aufgerufen + ++ Zuviele Kr�uterbeutel (Katja, 30.10.) + (enno) repariert, fehler in report_item. + ++ Schmiede funktioniert nicht (diverse, 30.10.) + (enno) Schmiede funktioniert wieder. Aufruf von init_buildings() fehlte. + ++ Zauber verbrauchen keine Aura (diverse, 30.10.) + (enno) res_changeaura, res_changepremaura, res_changehp u.a. + waren not implemented. erledigt. + ++ Zauber erzeugen keine Gegenst�nde (diverse, 30.10.) + +? Wald/Ebenen-Kr�uter wechseln nicht, wenn sich das Terrain �ndert + (wuzel, 30.10) + ++ Waldkr�uter nicht korrekt initialisiert, in W�ldern sind jetzt + Ebenenkr�uter (wuzel, 30.10.) + (enno) rterrain() statt mainterrain() benutzt. + (enno) gefixt, korrektur() erledigt das n�chste woche. + ++ Verkaufte Luxusg�ter werden nicht abgezogen, sondern dazugez�hlt + (mbank, 30.10) + (enno) gefixt, das i_change war falsch. (copy&paste) + +- Gew�rze wurde nicht erkannt (stanka, 30.10.) + (enno) Mehrzahl von Gew�rz ist Gew�rz. + Ich habe einen String f�r spices eingebaut, aber der wird noch nicht verwendet, + da au�er den korrekten Namen der Items noch keine aliase verarbeitet werden. + (enno) am besten w�ren standardisierte abk�rzungen. ich hab da was im kopf. + ++ doppelte Silberbeutel (diverse, 30.10.) + (enno) die alte routine war noch drin, gefixt. + ++ Abzug von Luxusg�tern immer noch falsch: G�ter aus dem Pool + werden bei Verkauf von der Einheit gezogen, assert in + i_change triggert. + (enno) Umstellung auf new_use_pooled() und kleiner speedup. + +- Silberspenden werden gemacht, obwohl eigentlich unn�tig gewesen. + (katja) warscheinlich am Anfang der Runde nicht genug Geld f�r die + Geb�udeversorgung, dann helfen die aliierten aus + ++ Gespenster aus der Unterwelt (w9kL) erzielte 1026 Treffer und t�tete 0 Gegner. + (enno) scheisse. waffenloser kampf. fixed. + ++ 42 K�mpfer aus Rukh-R (1ftp) feuern ihr Katapult ab: + (enno) ...und sie haben nur 42 katapulte. alle in der gleichen runde ist zuviel. + (enno) war nur kosmetisch + +- Parteien aus Durchreiseregionen erschienen nicht in den ADressen + +- Transporteure (2jws) arbeitet in Twerken (-7,8) f�r einen Lohn von 70 + statt 65 Silber. + ++ Illaun-Zauber Schoene/Schlechte Tr�ume wirkt zu kurz: beginnt erst in der + darauffolgenden runde, endet aber evtl. schon in der aktuellen. + (katja) irgendwer hatte bei Sch�ne Tr�ume die Dauer total verhuzt. + ++ Schattend�monen k�nnen reservieren (P. Horner, 15.09.00) + (katja) repariert + ++ Tunnelw�rmer k�nnen Stra�enbau statt Steinbau (H. Steinbei�er, 16.09.00) + ++ Vertraute nehmen nichts an (O. Eckstein, 17.09.00) + (katja) ist gefixt + +- FAHRE funktioniert nicht (G. Gro�berger, 19.09.00) + (enno) ist bei uns auch schonmal schiefgegangen, kann was dran sein. + +? Bei "Verw�nschung" sieht das Opfer der Verw�nschung den Zaubernden. + (enno) ich glaub, das hatte ich gefixt. + +? "Schl�gerzwerg (id84) in Kitpad (-1,2): 'KAEMPFE HELFE NICHT' - unbekannter + Kampfstatus." + (corwin) Kann nicht sein. Ist das noch aktuell? + +- Einheit auf Schiff flieht nicht in benachbarte Region (M. Korevaar, 24.09.00) + +- Astraler Ausgang funktioniert nicth (Synes Elischka, 29.09.2000) + +- Leuchtturmeinsturz macht Einheiten mit 0 Personen (O. Eckstein, 05.10.2000) + * Krath (hqk), 0 Elfen, "lerne wahrnehmung"; In eine dunkle Robe geh�llter + Elf - er vertritt hier seinen Herrn und Meister. + +? Bergwerk st�rzt trotz genug Silber ein (M. M�ller, 05.10.2000) + (enno) Die Routine ist seit dem �berarbeitet worden. + ++ Zauber "Runen des Schutzes" nicht base36 (F. Wolkwitz, 04.11.2000) + Maehrlin (39x) in Amandor (0,23): 'zaubere Runen~des~Schutzes Schiff 1bq' - + Schiff 1 wurde nicht gefunden. + (katja) #define FULL_BASE36 war vergessen worden + ++ Schmieden funktioiniern nicht (O. Eckstein, 05.11.2000) + (enno) Beispiel �berpr�ft, er muss sich verrechnet haben. + +- �bergabe klappte mit Pferd, aber nicht mit Silber? I. Schr�der, 05.11.2000) + +- einheit waru mcht zu wenig Kettenhemden (A. Neumann, 05.11.2000) + (enno) evtl. nicht oben in der schmiede gestanden? trotzdem zu wenig + +- einhiet buf erzeugt 5 statt 6 schwertern (dwalin, 6.09.2000) + (enno) die hat sich bestimmt verechnet. + ++ kostenlose kostenpflichtige talente mit lehrer (A. Klauer, 06.11.2000) + (stefan) Anteiliges Lernen betrifft jetzt alle Effekte mit. + +- hegg hat genug Material, kann aber nicht produzieren (P. Burkert, 06.11.00) + ++ Kein Anlegen in neuen Regionstypen m�glich (Joern Stampehl, 09.11.00) + (corwin) Neue Terraintypen fehlten in coast_allowed komplett. + +o Leuchtt�rme schauen mindestens eine Region zu weit. (Gr��e 10 + Leuchtturm 3 Regionen.) + (stefan) Bei mir nicht. Zu beachten ist, da� man halt 2 Regionen weit sieht, + und DANN noch die Nachbarregionen drangeh�ngt werden. + ++ 'cannot resolve action' vereinzelt + (enno) die alten actios sind weg, damit erledigt sich das wohl. + ++ timeout auf eine Vertrautenl�schung + (enno) Das ist dank neuer events wohl auch repariert? + ++ Museums'geb�ude' k�nnen umbenannt werden + (corwin) Generische Geb�ude (bt_generic) k�nnen bis zur Implementation + eines besseren Mechanismus nicht mehr umbenannt werden. + ++ Benennen fremder Burgen klappt nicht. + (corwin) Bei der Umstrukturierung der Geb�ude vergessen worden. + ++ Benennen fremder Schiffe und Geb�ude ist nicht an Locales angepa�t. + (corwin) Wird nicht mehr nahnd des Namens, sondern mit einem Flag gepr�ft. + ++ Bauernfressen und Vertreiben trotz Vernichtung der Untoten + (corwin) In der Reihenfolge vor die Zufallsereignisse gelegt. + ++ Stra�en �ber 100% fertig + (corwin) Fehler in build_road() + ++ Verfolgendes Schiff f�hrt in falsche Richtung + (corwin) u->wants bei Verfolgungen nicht mit 0 initialisiert. + ++ (katja) diverse Zauberfehlschl�ge, obwohl Aura �bertragen wurde (u.a. + Segne Steinkreis) weil VOR allen Zaubern, also auch vor dem + Auratransver, eine cancast �berpr�fung war, die zu dem Zeitpunkt + nat�rlich fehlschlug. + +- memoryleak in curseid? + ++ Fliehende Einheiten nehmen kein Silber mehr mit (Katja, 28.12.2000) + ++ Magiebegabte Vertraute haben keine Zauber mehr + +- lmsreward funktioiniert nicht (curse wird nicht gesetzt) + +- benutze item funktioniert nicht. itype->use ist �berall 0x0 + +- auch nichtpoolbare Resourcen wie Aura, HP, perm Aura sind im pool + +- lernen in akademie bringt 80 statt 70 Tage, ausser bei Magie, da + funktionierts? + (Zhardamon, irq 20.2.01) diff --git a/doc/changes.txt b/doc/changes.txt index c04460958..409483333 100644 --- a/doc/changes.txt +++ b/doc/changes.txt @@ -1,49 +1,49 @@ -Konzepte: -- Astralraum abschaffen - = done (modules.astralspace). - = done (Zauber entfernt). -- Regionsbesitz und Moral -- Allianzen -- GIB abstellen - = done - -Talente: -- Talentlimit 10 + Rassenbonus - = done -- Ausdauer wirkt sich nicht auf Trefferpunkte aus - = done (rules.stamina) -- Wahrnehmung und Tarnung abschalten - = done - -Kampf: -- Regionen belagern -- Allianz ersetzt HELFE KAEMPFE -- Reduktion auf 1 Kampfrunde - = done (rules.combat_turns) -- neue Trefferchanceberechnung -- neue Beuteregelung -- Gegnerlimits - -Gegenstände: -- Waffen mit höherem Schaden. -- RdU und AdwS überarbeiten - -Diverse: -- neue Terraintypen (weniger Bauern, knappere Ressourcen) -- limitiertes Rekrutieren von Migranten erlauben -- Parteitarnung fällt weg - = done (disable TARNEN) -- Monster entfernen - -Ökonomie: -- UNTERHALTEN abstellen - = done (Befehl & Skill) -- TREIBEN abstellen - = done (Befehl & Skill) -- ARBEITEN abstellen - = done (Befehl) -- LEHREN abstellen - = done (Befehl) -- VERKAUFEN abstellen. - = done (Befehl) -- Steuern für den Regionsbesitzer +Konzepte: +- Astralraum abschaffen + = done (modules.astralspace). + = done (Zauber entfernt). +- Regionsbesitz und Moral +- Allianzen +- GIB abstellen + = done + +Talente: +- Talentlimit 10 + Rassenbonus + = done +- Ausdauer wirkt sich nicht auf Trefferpunkte aus + = done (rules.stamina) +- Wahrnehmung und Tarnung abschalten + = done + +Kampf: +- Regionen belagern +- Allianz ersetzt HELFE KAEMPFE +- Reduktion auf 1 Kampfrunde + = done (rules.combat_turns) +- neue Trefferchanceberechnung +- neue Beuteregelung +- Gegnerlimits + +Gegenstände: +- Waffen mit höherem Schaden. +- RdU und AdwS überarbeiten + +Diverse: +- neue Terraintypen (weniger Bauern, knappere Ressourcen) +- limitiertes Rekrutieren von Migranten erlauben +- Parteitarnung fällt weg + = done (disable TARNEN) +- Monster entfernen + +Ökonomie: +- UNTERHALTEN abstellen + = done (Befehl & Skill) +- TREIBEN abstellen + = done (Befehl & Skill) +- ARBEITEN abstellen + = done (Befehl) +- LEHREN abstellen + = done (Befehl) +- VERKAUFEN abstellen. + = done (Befehl) +- Steuern für den Regionsbesitzer diff --git a/doc/coding.txt b/doc/coding.txt index 95952bc96..fe896a8b7 100644 --- a/doc/coding.txt +++ b/doc/coding.txt @@ -1,90 +1,90 @@ -Was ist das hier? -Dieses File ist eine Sammlung von kleinen Artikeln zum Code - -Designgedanken, haupts�chlich, keine Anleitungen. - -- Die Variable buf -wird an zu vielen Stellen im Source benutzt. K�nnen wir zumindest in -Zukunft versuchen, auf sie zu verzichten? Mir ist nie sehr wohl, wen ich -die irgendwo sehe. - -- Bibliotheken, module -Jedes Verzeichnis in common/ erzeugt eine Bibliothek. Je nach Bedarf -muss aber nicht jeder Server die ganze Bibliothek linken (die ist eher -was f�r den mapper), sondern kann die Files auch einzeln linken. Jedes -modul, item, attribut, usw. sollte eine Funktion zur Verf�gung stellen, -die seine typen initialisiert, also it_register respektive at_register -o.�. aufruft. Jede Biliothek hat ein File, das ihren Namen tr�gt (z.b. -items.txt) mit einer eigenen init_-Funktion, die alle init_funktionen -der enthaltenen objekte enth�lt. (init_items, init_attributes, usw). -Neue Files hinzuf�gen hei�t also bitte, die Registrierung in den -"bibliotheks-file" zu machen. - -- KI -Beim Anblick des enums mit Rassen-Flags sieht man schnell, das die in -mehrere Kategorien fallen. Eine davon ist die KI-Steuerung, und k�nnte -man die vielleicht getrennt von den anderen speichern? - -- Wor�ber man nachdenken sollte, ehe man etwas neues hinzuf�gt -90% aller Erweiterungen sind eigentlich optional. Ein Eressea ist z.B. -auch ohne die Rasse Troll denkbar. Leider ist die rasse Troll an derart -viele Stellen hartgecodet, das man Eressea ohne Trolle nie �bersetzen -k�nnte (Im Kampfsystem bekommen z.B. Trolle -1 beim Reitenbonus). Immer -dr�ber nachdenken, ob man hartcoden mu�, oder ob es auch einen anderen -Weg gibt (in diesem Fall z.B. ein at_skillmod attribut an der Rasse -Troll). - -- RC_SPELL -Es gibt einen Zauber (Ferne Vision) der Einheiten vom Typ RC_SPELL -erzeugt, aber 36 Stellen, an denen auf diesen Typ abgetestet werden mu� -(vielleicht sogar mehr?). K�nnen wir das mal auf einen curse umstellen? -Am besten in Kombination mit einem allgemeinen "diese Einheit/Region -soll in den Report der PArtei x", das man dann auch f�r Spionage usw. -benutzen kann, und das im Fall von Antimagie oder Zauberende durch einen -Trigger am entsprechenden curse mit zerlegt wird? - -- Wie komplex macht man einen Curse? -siehe vorangegangener Absatz. Generell gilt hier: Lieber zwei -vielseitige Dinge machen, als ein unflexibles - der curse sollte -lediglich der container seiin, der die wirkung aufrechterh�lt (das -attribut an der region �berwacht, und per trigger-funktion bei ende des -curse oder antimagie entfernt). die eigentliche wirkung kann man in ein -separates attribut stecken, dann ist sie auch in anderen kontexten als -zauberei verwendbar (geba�de oder items mit der gleichen wirkung, z.b.). -Tests sollten so wenig wie m�glich auf einen curse gehen (in fact, -eigentlich nur bei der antimagie) sondern immer auf die wirkung (das -attribut). - -- wie benenne ich Sourcedateien? -lang dr�ber nachgedacht, bin ich zum schluss gekommen: kleinbuchstaben, -keien unterstriche. Es kann sich nie jemand merken, ob testplayer oder -test_player jetzt richtig ist, und wir kommen sicher selten in die -situation, das wir zwischen opium_bringen.c und opi_umbringen.c -unterscheiden m�ssen. - -- wie benenne ich variablen? -da gilt das gleiceh wie bei den files, mit einer ausnahme: -typspezifikation, also zum beispiel at_ f�r attributstypen, mit einem -unterstrich. dann ist auch klar, was at_work ist: ein attribut, das was -mit arbeit zu tun hat, keine boolean-variable die sagt ob man auf der -arbeit ist. - -- faction::units -Die Variable funktioniert und kann benutzt werden. folgendes: -for (r=regions;r;r=r->next) for (u=r->units;u;u=u->next) if (u->faction==f) {} -schreibt sich viel einfacher so: -for (u=f->units;u;u=u->nextF) {} -und ja, es wird garantiert, das das funktioiniert, und regionsreihenfolge -einhalten tut es auch. weshalb wahlloses erzeugen von einheiten per calloc und -ohne createunit() aufruf schon seit l�ngerem ein NoNo ist. - -- buffer length -Namen von attributen, hashcodes f�r items, usw. sollten kurz sein. -schliesslich landen sie im Datenfile. Eine Funktion, die sie einl�dt, -sollte mit 32 byte speicherbedarf rechnen. - -- FL_MARK und FL_DH: -Der unterschied zwischen diesen beiden Flags ist: -FL_DH sollte man vor der Benutzung auf einen Wert setzen, den man coraussetzt -(man kriegt keinen wert garanteirt). -FL_MARK ist immer 0. jede routine die es setzt, muss es am ende wieder auf 0 -zur�cksetzen. code-beispiel ist z.b. die SORTIERE-funktion. +Was ist das hier? +Dieses File ist eine Sammlung von kleinen Artikeln zum Code - +Designgedanken, haupts�chlich, keine Anleitungen. + +- Die Variable buf +wird an zu vielen Stellen im Source benutzt. K�nnen wir zumindest in +Zukunft versuchen, auf sie zu verzichten? Mir ist nie sehr wohl, wen ich +die irgendwo sehe. + +- Bibliotheken, module +Jedes Verzeichnis in common/ erzeugt eine Bibliothek. Je nach Bedarf +muss aber nicht jeder Server die ganze Bibliothek linken (die ist eher +was f�r den mapper), sondern kann die Files auch einzeln linken. Jedes +modul, item, attribut, usw. sollte eine Funktion zur Verf�gung stellen, +die seine typen initialisiert, also it_register respektive at_register +o.�. aufruft. Jede Biliothek hat ein File, das ihren Namen tr�gt (z.b. +items.txt) mit einer eigenen init_-Funktion, die alle init_funktionen +der enthaltenen objekte enth�lt. (init_items, init_attributes, usw). +Neue Files hinzuf�gen hei�t also bitte, die Registrierung in den +"bibliotheks-file" zu machen. + +- KI +Beim Anblick des enums mit Rassen-Flags sieht man schnell, das die in +mehrere Kategorien fallen. Eine davon ist die KI-Steuerung, und k�nnte +man die vielleicht getrennt von den anderen speichern? + +- Wor�ber man nachdenken sollte, ehe man etwas neues hinzuf�gt +90% aller Erweiterungen sind eigentlich optional. Ein Eressea ist z.B. +auch ohne die Rasse Troll denkbar. Leider ist die rasse Troll an derart +viele Stellen hartgecodet, das man Eressea ohne Trolle nie �bersetzen +k�nnte (Im Kampfsystem bekommen z.B. Trolle -1 beim Reitenbonus). Immer +dr�ber nachdenken, ob man hartcoden mu�, oder ob es auch einen anderen +Weg gibt (in diesem Fall z.B. ein at_skillmod attribut an der Rasse +Troll). + +- RC_SPELL +Es gibt einen Zauber (Ferne Vision) der Einheiten vom Typ RC_SPELL +erzeugt, aber 36 Stellen, an denen auf diesen Typ abgetestet werden mu� +(vielleicht sogar mehr?). K�nnen wir das mal auf einen curse umstellen? +Am besten in Kombination mit einem allgemeinen "diese Einheit/Region +soll in den Report der PArtei x", das man dann auch f�r Spionage usw. +benutzen kann, und das im Fall von Antimagie oder Zauberende durch einen +Trigger am entsprechenden curse mit zerlegt wird? + +- Wie komplex macht man einen Curse? +siehe vorangegangener Absatz. Generell gilt hier: Lieber zwei +vielseitige Dinge machen, als ein unflexibles - der curse sollte +lediglich der container seiin, der die wirkung aufrechterh�lt (das +attribut an der region �berwacht, und per trigger-funktion bei ende des +curse oder antimagie entfernt). die eigentliche wirkung kann man in ein +separates attribut stecken, dann ist sie auch in anderen kontexten als +zauberei verwendbar (geba�de oder items mit der gleichen wirkung, z.b.). +Tests sollten so wenig wie m�glich auf einen curse gehen (in fact, +eigentlich nur bei der antimagie) sondern immer auf die wirkung (das +attribut). + +- wie benenne ich Sourcedateien? +lang dr�ber nachgedacht, bin ich zum schluss gekommen: kleinbuchstaben, +keien unterstriche. Es kann sich nie jemand merken, ob testplayer oder +test_player jetzt richtig ist, und wir kommen sicher selten in die +situation, das wir zwischen opium_bringen.c und opi_umbringen.c +unterscheiden m�ssen. + +- wie benenne ich variablen? +da gilt das gleiceh wie bei den files, mit einer ausnahme: +typspezifikation, also zum beispiel at_ f�r attributstypen, mit einem +unterstrich. dann ist auch klar, was at_work ist: ein attribut, das was +mit arbeit zu tun hat, keine boolean-variable die sagt ob man auf der +arbeit ist. + +- faction::units +Die Variable funktioniert und kann benutzt werden. folgendes: +for (r=regions;r;r=r->next) for (u=r->units;u;u=u->next) if (u->faction==f) {} +schreibt sich viel einfacher so: +for (u=f->units;u;u=u->nextF) {} +und ja, es wird garantiert, das das funktioiniert, und regionsreihenfolge +einhalten tut es auch. weshalb wahlloses erzeugen von einheiten per calloc und +ohne createunit() aufruf schon seit l�ngerem ein NoNo ist. + +- buffer length +Namen von attributen, hashcodes f�r items, usw. sollten kurz sein. +schliesslich landen sie im Datenfile. Eine Funktion, die sie einl�dt, +sollte mit 32 byte speicherbedarf rechnen. + +- FL_MARK und FL_DH: +Der unterschied zwischen diesen beiden Flags ist: +FL_DH sollte man vor der Benutzung auf einen Wert setzen, den man coraussetzt +(man kriegt keinen wert garanteirt). +FL_MARK ist immer 0. jede routine die es setzt, muss es am ende wieder auf 0 +zur�cksetzen. code-beispiel ist z.b. die SORTIERE-funktion. diff --git a/doc/directories.txt b/doc/directories.txt index 1f9d3c1fe..70ef479e3 100644 --- a/doc/directories.txt +++ b/doc/directories.txt @@ -1,28 +1,28 @@ -src/util - 1. Was ist hier drin? - Hier drin steckt Code, der nicht nur f�r Eressea zu gebrauchen ist. Wann immer m�glich, sollte man versuchen, Code hier unterzubringen. Code in diesem Verzeichnis verwendet config.h, aber unter keinen Umst�nden eressea.h oder anderen code aus src/common. - 2. Beispiele: - attrib, event, base36, rand -src/common - 1. Was ist hier drin? - Der Kern des Spiels. Funktionen, ohne die ein Eressea-Spiel nicht existieren kann. Zum Beispiel Kampfsystem, Magiesystem, item-typen (aber m�glichst wenige items). Je allgemeiner gehalten der Code ist, desto weniger mu� in common, desto mehr kann in "pluggable" Modulen untergebracht werden. - Bei Code im Kern des Spiels sollte man beachten, das eine Abfrage auf einen konkreten item-typ immer zu einer Abh�ngigkeit mit Code f�hrt, der eigentlich nicht dem Kern zuzurechnen ist. Wenn im Kampf z.B. eine Spezialwaffe erfragt wird, dann kann man kein Eressea-Spiel erzeugen, ohne diese Waffe mit zu linken, selbst wenn man sie nicht benutzt. Besser ist es in diesem Fall, wiederverwendbare attribute oder itemtype-flags zu benutzen. Analog gilt das f�r alle anderen typen: rassen, geb�ude, schiffe, Regionstypen, Zauber. - 2. Beispiele: - battle, economy, magic (vormals newmagic), item (allerdings ohne konkret items zu enthalten), build, building, ship -src/common/gamecode - 1. Was ist hier drin? - Code, der nur die Auswertung und den Ablauf betrifft, aber keine statischen Tools wie z.B. den Mapper. - 2. Beispiele: - Hier ist die �konomie drin, Zufallsereignisse, Reportgenerierung. -src/common/modules - 1. Was ist hier drin? - "Pluggable" Module, wie Questen, Spezial-Planes, Events. Alles, was dem Spiel Leben einhaucht, ohne im Kern verankert zu sein. - 2. Beispiele: - arena, xmas2000, museum, score (?). - 3. Style - Ein Modul sollte aus main.c heraus initialisiert werden k�nnen. Ideal ist, wenn ein Aufruf von init_<module>() gen�gt, um es zu aktivieren. Das sorgt z.B. beim Weihnachtsmann-Modul f�r die Erzeugung der Plane und der Units, der Registrierung der n�tigen Items und Attribute, und mehr mu� nicht getan werden. - Darf keine Funktionen aus gamecode() benutzen, oder sollte selber im gamecode landen. -src/triggers -src/items -src/spells - +src/util + 1. Was ist hier drin? + Hier drin steckt Code, der nicht nur f�r Eressea zu gebrauchen ist. Wann immer m�glich, sollte man versuchen, Code hier unterzubringen. Code in diesem Verzeichnis verwendet config.h, aber unter keinen Umst�nden eressea.h oder anderen code aus src/common. + 2. Beispiele: + attrib, event, base36, rand +src/common + 1. Was ist hier drin? + Der Kern des Spiels. Funktionen, ohne die ein Eressea-Spiel nicht existieren kann. Zum Beispiel Kampfsystem, Magiesystem, item-typen (aber m�glichst wenige items). Je allgemeiner gehalten der Code ist, desto weniger mu� in common, desto mehr kann in "pluggable" Modulen untergebracht werden. + Bei Code im Kern des Spiels sollte man beachten, das eine Abfrage auf einen konkreten item-typ immer zu einer Abh�ngigkeit mit Code f�hrt, der eigentlich nicht dem Kern zuzurechnen ist. Wenn im Kampf z.B. eine Spezialwaffe erfragt wird, dann kann man kein Eressea-Spiel erzeugen, ohne diese Waffe mit zu linken, selbst wenn man sie nicht benutzt. Besser ist es in diesem Fall, wiederverwendbare attribute oder itemtype-flags zu benutzen. Analog gilt das f�r alle anderen typen: rassen, geb�ude, schiffe, Regionstypen, Zauber. + 2. Beispiele: + battle, economy, magic (vormals newmagic), item (allerdings ohne konkret items zu enthalten), build, building, ship +src/common/gamecode + 1. Was ist hier drin? + Code, der nur die Auswertung und den Ablauf betrifft, aber keine statischen Tools wie z.B. den Mapper. + 2. Beispiele: + Hier ist die �konomie drin, Zufallsereignisse, Reportgenerierung. +src/common/modules + 1. Was ist hier drin? + "Pluggable" Module, wie Questen, Spezial-Planes, Events. Alles, was dem Spiel Leben einhaucht, ohne im Kern verankert zu sein. + 2. Beispiele: + arena, xmas2000, museum, score (?). + 3. Style + Ein Modul sollte aus main.c heraus initialisiert werden k�nnen. Ideal ist, wenn ein Aufruf von init_<module>() gen�gt, um es zu aktivieren. Das sorgt z.B. beim Weihnachtsmann-Modul f�r die Erzeugung der Plane und der Units, der Registrierung der n�tigen Items und Attribute, und mehr mu� nicht getan werden. + Darf keine Funktionen aus gamecode() benutzen, oder sollte selber im gamecode landen. +src/triggers +src/items +src/spells + diff --git a/doc/spells_uebersicht.txt b/doc/spells_uebersicht.txt index d8e1bcd25..e0b210f80 100644 --- a/doc/spells_uebersicht.txt +++ b/doc/spells_uebersicht.txt @@ -1,185 +1,185 @@ -Stufe, Name, Kosten, Auswirkung -Kosten: *L = pro Level, P = Permanente Aura, M = Materialien (zB Holz), - B = Bauern, $ = Silber, H = Hitpoints -(K) = Kampfzauber, (+K) = Prekampfzauber, (K+) = Postkampfzauber - - -Druide/Gwyrrd (38 Spr�che): ---------------------------- - 1 Segen der Erde 1*L Bauern verdienen 1 Silber mehr - 1 Viehheilung 1*L Magier verdient 50$*L - 1 Erschaffe Steingolems 2*L,M Magische Strassen/Burgenbauer - 2 Erschaffe Eisengolems 2*L,M Magische R�stungsbauer - 2 Hainzauber 2*L,$ Erschafft B�ume - 3 Rostregen 2*L Vernichtet Eisenwaffen - 3 Firuns Fell 2*L Insekten k�nnen auf Gletscher - 3 Hagel (K) 1*L verursacht leichten Schaden - 3 Bergw�chter 3*L Verhindert Eisenabbau - 4 Magischer Pfad 1*L,M Magische Strasse - 4 Windschild (+K) 2*L behindert Sch�tzen - 4 B... Wasserelementar 1*L Schiffe +1 Bewegung und keine Abdrift - 5 Heilung (K+) 1*L heilt bis zu 11 Personen pro Stufe - 5 Wirbelwind (+K) 15 behindert alle Sch�tzen zu 50% - 5 Astralschutzgeister (+K) 5*L behindert Kampfzauber - 5 E... magischen Kr�uterb. 30,1P,M Artefakt - 6 Meditation 2 �bertr�gt Aura - 6 B... einen Erdelementar 25,M Besch�digt alle Geb�ude einer Region - 6 B... Sturmelementar 6*L verdoppelt Schiffsbewegung - 6 E... des wahren Sehens 50,$ Artefakt - 6 E... der Unsichtbarkeit 50,$ Artefakt - 7 Heimstein 50,1P verbessert Burg dauerhaft - 7 Wolfsgeheul (+K) 2*L ruft W�lfe f�r den Kampf - 8 Blick des Basilisken (K) 1*L entfernt Gegner aus Kampf - 8 Starkes Tor und ... (+K) 2*L verbessert Schutz der Burg - 8 Geister bannen 6*L Antimagie - 9 Weg der B�ume 3*L Stufe*5 GE aus Wald in Astralebene - 9 Sog des Lebens 2*L Stufe*5 GE aus Astralebene in Wald - 9 Heiliger Boden 80,3P -10 Erwecke Ents 6*L Erschafft Einheit -10 Vertrauten binden 100,5P Vertrauter -11 Segne Steinkreis 350,5P Wandelt Steinkreis zum gesegneten St. -12 Rindenhaut (+K) 4*L Verbessert R�stung -13 B... Hitzeelementar 600 halbiert Fruchtbarkeit der Region -14 Nebel der Verwirrung 8*L Bewegung wird zuf�llig (nur Wald+Ozean) -15 Mahlstrom 200,M Ozeanfeld besch�digt Schiffe schwer -16 Wurzeln der Magie 250,10P,M Wald wird permanent Mallornwald -17 T... die Ebene der Hitze 800 st�rker als L13, kann Region wandeln - - -Chaos/Draig (27 Spr�che): -------------------------- - 1 Verw�nschung 1*L nur Showeffekt - 1 Kleine Fl�che 1*L Magier verdient 50$*L - 2 Feuerball (K) 1*L Schaden - 3 Gabe des Chaos 2*L Magicboost - 4 M�chte des Todes 5*L Erschafft Untote - 5 Blutrausch (+K) 5*L,B Verbessert Kampfkraft - 5 Chaosfluch 4*L behindert Zauberer - 6 Rosthauch (K) 2*L zerst�rt Eisenwaffen - 6 E... des wahren Sehens 50,$ Artefakt - 6 E... der Unsichtbarkeit 50,$ Artefakt - 7 Macht�bertragung 2 �bertr�gt Aura - 7 Feuerwand 6*L Wall, macht Schaden - 7 Fluch der Pestilenz 30,B erzeugt Pest - 8 Wahnsinn des Krieges (+K) 3*L,B verwirbelt gegnerische Reihen - 8 Beschw�re Schattend�monen 3*L erzeugt Einheit - 9 E... der Trollst�rke 20,1P Artefakt - 9 Astraler Riss 35,M Magier der Region verlieren Aura - 9 Astrales Chaos (+K) 6*L behindert Kampfzauber -10 Feuerteufel 50,M vernichtet W�lder -10 Pentagramm 10*L Antimagie -10 Unheilige Kraft 8*L,M Transformiert Untote -11 Todeswolke 40,H alle Personen der Region verlieren HP -11 Drachenruf 80,M lockt Drachen an -12 Beschw�re Schattenmeister 7*L erzeugt Einheit -12 E... ein Flammenschwert 150,M Artefakt -13 Vertrauten rufen 100,5P Vertrauter -14 Chaossog 150,B n�chste Runde Tor zur Astralebene - - -Traum/Illaun (27 Spr�che): --------------------------- - 1 Traumsenden 1*L nur Showeffekt - 1 Wahrsagen 1*L Magier verdient 50$*L - 1 Schattenritter (+K) 1*L Illusionen, fangen Angriffe ab - 2 Grauen der Schlacht (+K) 1*L verleitet Gegner zur Flucht - 2 Seelenfrieden 3*L,M reduziert deathcount der Region - 3 Traumschl��chen 1*L Illusion einer Burg - 3 Traum der Magie 2 Auratransfer - 3 Gestaltwandlung 1*L Einheit erscheint als andere Rasse - 4 Traumlesen 8 Magier erh�lt Regionsbericht - 4 Schwere Glieder (+K) 4*L -2 Def, 50% Chance dass keine Att - 5 Wiederbelebung (K+) 1*L holt Tote zur�ck - 5 Traumbilder analysieren 5*L analysiert Spr�che auf Einheiten - 6 Schlechter Schlaf 18 vermindert Lernrate in einer Region - 6 E... des wahren Sehens 50,$ Artefakt - 6 E... der Unsichtbarkeit 50,$ Artefakt - 7 Schlaf (K) 1*L -2 Def, kein Att, solange bis getroffen - 7 Irrlichter 2*L Bewegung wird zuf�llig? - 7 Traumdeuten 20 spioniert Einheit aus - 8 Sch�ne Tr�ume 8*L zeitweilig Bonus auf alle Talente - 8 Traumbilder entwirren 6*L Antimagie - 9 Vertrauten rufen 100,5P Vertrauter - 9 Seelenkopie 100,20P+ Reserveklon -10 Schlechte Tr�ume 9*L zeitweilig -L/4 Talentstufen -11 Tod des Geistes (K) 2*L vermindert Talente, t�ten bei 0 Tagen -12 S��e Tr�ume 30 Vermehrung wie bei Orks -14 Erschaffe ein Traumauge 10P,M Artefakt -15 Alp 350,5P,M Monster, sucht Opfer => -2 auf Talente -16 Schleier der Verwirrung 7*L mehrere Regionen: Bewegung wird zuf�llig - - -Barde/Cerddor (33 Spr�che): ---------------------------- - 1 Friedenslied (+K) 2 Magier kann vor Angriff fliehen - 1 Gaukelleien 1*L Magier verdient 50$*L - 2 Lied der Heilung (K+) 1*L heilt Verwundete - 2 Hohes Lied der Gaukelei 2*L Unterhaltungsmaximum zeitweilig doppelt - 3 Regentanz 1*L Bauern verdienen 1 Silber mehr - 3 Gesang der Furcht (K) 1*L Gegner versuchen zu fliehen - 4 Gesang des Werbens 2*L rekrutiert Bauern - 4 Gesang der Verwirrung (+K) 2*L verwirbelt gegnerische Reihen - 4 Plappermaul 10 spioniert Einheit aus - 5 Heldengesang (+K) 2*L Krieger widerstehen einigen Effekten - 5 Gesang des Auratransfers 2 �bertr�gt Aura - 5 G... Lebens analysieren 10 analysiert Zauber auf Einheit - 5 Bannlied (+K) 5*L behindert Kampfzauber - 6 Monster friedlich stimmen 15 verhindert Monsterangriffe - 6 Lied der Verf�hrung 12 Einheit schenkt Magier 50% Besitz - 6 E... des wahren Sehens 50,$ Artefakt - 6 E... der Unsichtbarkeit 50,$ Artefakt - 7 Schaler Wein 4*L,M,$ Opfer vergi�t bis 60 Talenttage - 7 Aushorchen 4,$ Magier erh�lt Regionsbericht - 7 Kriegsgesang (+K) 5*L verbessert Kampfkraft - 8 Gesang der Angst 5*L Malus auf Att und Def - 8 L... Ortes analysieren 3*L analysiert Zauber auf Objekten/Regionen - 8 Lebenslied festigen 5*L Antimagie - 9 Ritual der Aufnahme 3*L,1P*L L Personen k�nnen Partei wechseln - 9 Vertrauten rufen 100,5P Vertrauter -10 Mob aufwiegeln 4*L Erzeugt Einheit -10 Gesang des wachen Geistes 2*L verbessert Magieresistenz in Region -11 Gesang der Melancholie 40 kein Unterhaltunssilber verf�gbar -11 Miriams flinke Finger 20,1P,$ Artefakt -12 G... schwachen Geistes 2*L vermindert Magieresistenz in Region -12 G... der Friedfertigkeit 20*L verhindert K�mpfe -13 Gesang der Versklavung 40 Opfer wechselt zeitweilig Partei -15 Aufruhr beschwichtigen 30 L�st Mob (L10) auf - - -Astral/Tybied (32 Spr�che): ---------------------------- - 1 Magie analysieren 1*L analysiert Zauber - 1 Schleieraura 1*L verbirgt Ausr�stung einer Einheit - 1 Wunderdoktor 1*L Magier verdient 50$*L - 2 Schutz vor Magie (+K) 3*L behindert Kampfzauber - 2 Astraler Blick 1*L sieht Einheiten in Astralebene - 3 Schutzzauber 5*L verbessert Magieresistenz einer Einheit - 3 Beute bewahren (K+) 1*L vermindert Zerst�rung von Gegenst�nden - 4 Astraler Weg 2*L schiebt (L-3)*15 GE in Astralebene - 4 Astraler Ausgang 2*L schiebt (L-3)*15 GE in Realit�t - 5 Auratransfer 1 transferiert Aura, auch andere Gebiete - 5 Schockwelle (K) 1*L verhindert n�chste Attacke - 5 Astrale Schw�chezone 3*L Antimagiezone - 5 E... des wahren Sehens 50,$ Artefakt - 6 Astraler Ruf 2*L zieht (L-3)*15 GE in Astralebene - 6 Ruf der Realit�t 2*L zieht (L-3)*15 GE in Realit�t - 6 Stehle Aura 2*L entzieht anderem Magier Aura - 6 Luftschiff 10,M l��t Boot/Langboot fliegen - 6 E... der Unsichtbarkeit 50,$ Artefakt - 7 E... Antimagiekristall 50,$ Item, das Antimagiezone erzeugt - 7 Magiefresser 3*L Antimagie - 8 Runen des Schutzes 20 +20% Magieresistenz bei Burgen/Schiffen - 8 Schild des Fisches (+K) 4*L vermindert Schaden - 9 Beschleunigung (+K) 5*L verdoppelt Attacken - 9 E... einen Ring der Macht 100,$ Artefakt -10 Blick in die Realit�t 40 sieht Region aus Astralebene -10 E... Negativen Gewichts 30,1P,$ Artefakt -11 Zeitdehnung 5*L Doppelte Bewegung und Angriffe -12 R�stschild (+K) 4*L verbessert R�stung -12 Vertrauten rufen 100,5P Vertrauter -13 Belebtes Gestein 10,5P,M Versetzt Burg samt Besatzung -14 St�re Astrale Integrit�t 140 -15 Opfere Kraft 100 transferiert permanente Aura - - - +Stufe, Name, Kosten, Auswirkung +Kosten: *L = pro Level, P = Permanente Aura, M = Materialien (zB Holz), + B = Bauern, $ = Silber, H = Hitpoints +(K) = Kampfzauber, (+K) = Prekampfzauber, (K+) = Postkampfzauber + + +Druide/Gwyrrd (38 Spr�che): +--------------------------- + 1 Segen der Erde 1*L Bauern verdienen 1 Silber mehr + 1 Viehheilung 1*L Magier verdient 50$*L + 1 Erschaffe Steingolems 2*L,M Magische Strassen/Burgenbauer + 2 Erschaffe Eisengolems 2*L,M Magische R�stungsbauer + 2 Hainzauber 2*L,$ Erschafft B�ume + 3 Rostregen 2*L Vernichtet Eisenwaffen + 3 Firuns Fell 2*L Insekten k�nnen auf Gletscher + 3 Hagel (K) 1*L verursacht leichten Schaden + 3 Bergw�chter 3*L Verhindert Eisenabbau + 4 Magischer Pfad 1*L,M Magische Strasse + 4 Windschild (+K) 2*L behindert Sch�tzen + 4 B... Wasserelementar 1*L Schiffe +1 Bewegung und keine Abdrift + 5 Heilung (K+) 1*L heilt bis zu 11 Personen pro Stufe + 5 Wirbelwind (+K) 15 behindert alle Sch�tzen zu 50% + 5 Astralschutzgeister (+K) 5*L behindert Kampfzauber + 5 E... magischen Kr�uterb. 30,1P,M Artefakt + 6 Meditation 2 �bertr�gt Aura + 6 B... einen Erdelementar 25,M Besch�digt alle Geb�ude einer Region + 6 B... Sturmelementar 6*L verdoppelt Schiffsbewegung + 6 E... des wahren Sehens 50,$ Artefakt + 6 E... der Unsichtbarkeit 50,$ Artefakt + 7 Heimstein 50,1P verbessert Burg dauerhaft + 7 Wolfsgeheul (+K) 2*L ruft W�lfe f�r den Kampf + 8 Blick des Basilisken (K) 1*L entfernt Gegner aus Kampf + 8 Starkes Tor und ... (+K) 2*L verbessert Schutz der Burg + 8 Geister bannen 6*L Antimagie + 9 Weg der B�ume 3*L Stufe*5 GE aus Wald in Astralebene + 9 Sog des Lebens 2*L Stufe*5 GE aus Astralebene in Wald + 9 Heiliger Boden 80,3P +10 Erwecke Ents 6*L Erschafft Einheit +10 Vertrauten binden 100,5P Vertrauter +11 Segne Steinkreis 350,5P Wandelt Steinkreis zum gesegneten St. +12 Rindenhaut (+K) 4*L Verbessert R�stung +13 B... Hitzeelementar 600 halbiert Fruchtbarkeit der Region +14 Nebel der Verwirrung 8*L Bewegung wird zuf�llig (nur Wald+Ozean) +15 Mahlstrom 200,M Ozeanfeld besch�digt Schiffe schwer +16 Wurzeln der Magie 250,10P,M Wald wird permanent Mallornwald +17 T... die Ebene der Hitze 800 st�rker als L13, kann Region wandeln + + +Chaos/Draig (27 Spr�che): +------------------------- + 1 Verw�nschung 1*L nur Showeffekt + 1 Kleine Fl�che 1*L Magier verdient 50$*L + 2 Feuerball (K) 1*L Schaden + 3 Gabe des Chaos 2*L Magicboost + 4 M�chte des Todes 5*L Erschafft Untote + 5 Blutrausch (+K) 5*L,B Verbessert Kampfkraft + 5 Chaosfluch 4*L behindert Zauberer + 6 Rosthauch (K) 2*L zerst�rt Eisenwaffen + 6 E... des wahren Sehens 50,$ Artefakt + 6 E... der Unsichtbarkeit 50,$ Artefakt + 7 Macht�bertragung 2 �bertr�gt Aura + 7 Feuerwand 6*L Wall, macht Schaden + 7 Fluch der Pestilenz 30,B erzeugt Pest + 8 Wahnsinn des Krieges (+K) 3*L,B verwirbelt gegnerische Reihen + 8 Beschw�re Schattend�monen 3*L erzeugt Einheit + 9 E... der Trollst�rke 20,1P Artefakt + 9 Astraler Riss 35,M Magier der Region verlieren Aura + 9 Astrales Chaos (+K) 6*L behindert Kampfzauber +10 Feuerteufel 50,M vernichtet W�lder +10 Pentagramm 10*L Antimagie +10 Unheilige Kraft 8*L,M Transformiert Untote +11 Todeswolke 40,H alle Personen der Region verlieren HP +11 Drachenruf 80,M lockt Drachen an +12 Beschw�re Schattenmeister 7*L erzeugt Einheit +12 E... ein Flammenschwert 150,M Artefakt +13 Vertrauten rufen 100,5P Vertrauter +14 Chaossog 150,B n�chste Runde Tor zur Astralebene + + +Traum/Illaun (27 Spr�che): +-------------------------- + 1 Traumsenden 1*L nur Showeffekt + 1 Wahrsagen 1*L Magier verdient 50$*L + 1 Schattenritter (+K) 1*L Illusionen, fangen Angriffe ab + 2 Grauen der Schlacht (+K) 1*L verleitet Gegner zur Flucht + 2 Seelenfrieden 3*L,M reduziert deathcount der Region + 3 Traumschl��chen 1*L Illusion einer Burg + 3 Traum der Magie 2 Auratransfer + 3 Gestaltwandlung 1*L Einheit erscheint als andere Rasse + 4 Traumlesen 8 Magier erh�lt Regionsbericht + 4 Schwere Glieder (+K) 4*L -2 Def, 50% Chance dass keine Att + 5 Wiederbelebung (K+) 1*L holt Tote zur�ck + 5 Traumbilder analysieren 5*L analysiert Spr�che auf Einheiten + 6 Schlechter Schlaf 18 vermindert Lernrate in einer Region + 6 E... des wahren Sehens 50,$ Artefakt + 6 E... der Unsichtbarkeit 50,$ Artefakt + 7 Schlaf (K) 1*L -2 Def, kein Att, solange bis getroffen + 7 Irrlichter 2*L Bewegung wird zuf�llig? + 7 Traumdeuten 20 spioniert Einheit aus + 8 Sch�ne Tr�ume 8*L zeitweilig Bonus auf alle Talente + 8 Traumbilder entwirren 6*L Antimagie + 9 Vertrauten rufen 100,5P Vertrauter + 9 Seelenkopie 100,20P+ Reserveklon +10 Schlechte Tr�ume 9*L zeitweilig -L/4 Talentstufen +11 Tod des Geistes (K) 2*L vermindert Talente, t�ten bei 0 Tagen +12 S��e Tr�ume 30 Vermehrung wie bei Orks +14 Erschaffe ein Traumauge 10P,M Artefakt +15 Alp 350,5P,M Monster, sucht Opfer => -2 auf Talente +16 Schleier der Verwirrung 7*L mehrere Regionen: Bewegung wird zuf�llig + + +Barde/Cerddor (33 Spr�che): +--------------------------- + 1 Friedenslied (+K) 2 Magier kann vor Angriff fliehen + 1 Gaukelleien 1*L Magier verdient 50$*L + 2 Lied der Heilung (K+) 1*L heilt Verwundete + 2 Hohes Lied der Gaukelei 2*L Unterhaltungsmaximum zeitweilig doppelt + 3 Regentanz 1*L Bauern verdienen 1 Silber mehr + 3 Gesang der Furcht (K) 1*L Gegner versuchen zu fliehen + 4 Gesang des Werbens 2*L rekrutiert Bauern + 4 Gesang der Verwirrung (+K) 2*L verwirbelt gegnerische Reihen + 4 Plappermaul 10 spioniert Einheit aus + 5 Heldengesang (+K) 2*L Krieger widerstehen einigen Effekten + 5 Gesang des Auratransfers 2 �bertr�gt Aura + 5 G... Lebens analysieren 10 analysiert Zauber auf Einheit + 5 Bannlied (+K) 5*L behindert Kampfzauber + 6 Monster friedlich stimmen 15 verhindert Monsterangriffe + 6 Lied der Verf�hrung 12 Einheit schenkt Magier 50% Besitz + 6 E... des wahren Sehens 50,$ Artefakt + 6 E... der Unsichtbarkeit 50,$ Artefakt + 7 Schaler Wein 4*L,M,$ Opfer vergi�t bis 60 Talenttage + 7 Aushorchen 4,$ Magier erh�lt Regionsbericht + 7 Kriegsgesang (+K) 5*L verbessert Kampfkraft + 8 Gesang der Angst 5*L Malus auf Att und Def + 8 L... Ortes analysieren 3*L analysiert Zauber auf Objekten/Regionen + 8 Lebenslied festigen 5*L Antimagie + 9 Ritual der Aufnahme 3*L,1P*L L Personen k�nnen Partei wechseln + 9 Vertrauten rufen 100,5P Vertrauter +10 Mob aufwiegeln 4*L Erzeugt Einheit +10 Gesang des wachen Geistes 2*L verbessert Magieresistenz in Region +11 Gesang der Melancholie 40 kein Unterhaltunssilber verf�gbar +11 Miriams flinke Finger 20,1P,$ Artefakt +12 G... schwachen Geistes 2*L vermindert Magieresistenz in Region +12 G... der Friedfertigkeit 20*L verhindert K�mpfe +13 Gesang der Versklavung 40 Opfer wechselt zeitweilig Partei +15 Aufruhr beschwichtigen 30 L�st Mob (L10) auf + + +Astral/Tybied (32 Spr�che): +--------------------------- + 1 Magie analysieren 1*L analysiert Zauber + 1 Schleieraura 1*L verbirgt Ausr�stung einer Einheit + 1 Wunderdoktor 1*L Magier verdient 50$*L + 2 Schutz vor Magie (+K) 3*L behindert Kampfzauber + 2 Astraler Blick 1*L sieht Einheiten in Astralebene + 3 Schutzzauber 5*L verbessert Magieresistenz einer Einheit + 3 Beute bewahren (K+) 1*L vermindert Zerst�rung von Gegenst�nden + 4 Astraler Weg 2*L schiebt (L-3)*15 GE in Astralebene + 4 Astraler Ausgang 2*L schiebt (L-3)*15 GE in Realit�t + 5 Auratransfer 1 transferiert Aura, auch andere Gebiete + 5 Schockwelle (K) 1*L verhindert n�chste Attacke + 5 Astrale Schw�chezone 3*L Antimagiezone + 5 E... des wahren Sehens 50,$ Artefakt + 6 Astraler Ruf 2*L zieht (L-3)*15 GE in Astralebene + 6 Ruf der Realit�t 2*L zieht (L-3)*15 GE in Realit�t + 6 Stehle Aura 2*L entzieht anderem Magier Aura + 6 Luftschiff 10,M l��t Boot/Langboot fliegen + 6 E... der Unsichtbarkeit 50,$ Artefakt + 7 E... Antimagiekristall 50,$ Item, das Antimagiezone erzeugt + 7 Magiefresser 3*L Antimagie + 8 Runen des Schutzes 20 +20% Magieresistenz bei Burgen/Schiffen + 8 Schild des Fisches (+K) 4*L vermindert Schaden + 9 Beschleunigung (+K) 5*L verdoppelt Attacken + 9 E... einen Ring der Macht 100,$ Artefakt +10 Blick in die Realit�t 40 sieht Region aus Astralebene +10 E... Negativen Gewichts 30,1P,$ Artefakt +11 Zeitdehnung 5*L Doppelte Bewegung und Angriffe +12 R�stschild (+K) 4*L verbessert R�stung +12 Vertrauten rufen 100,5P Vertrauter +13 Belebtes Gestein 10,5P,M Versetzt Burg samt Besatzung +14 St�re Astrale Integrit�t 140 +15 Opfere Kraft 100 transferiert permanente Aura + + + diff --git a/doc/synonyme-rassen b/doc/synonyme-rassen index 47a216ba3..ba5c2804c 100644 --- a/doc/synonyme-rassen +++ b/doc/synonyme-rassen @@ -1,84 +1,84 @@ - -Elfen ------ - -Waldelfen -Hochelfen -Grauelfen -Meerelfen -Auelfen -Dunkelelfen -Sylphen - - -Halblinge ---------- - -Kender - - -Meermenschen ------------- - -Nymphen -Meervolk -Echsen - - -Zentauren ---------- - -Satyre - - -Zwerge ------- - -Duergar - - -Katzen ------- - -Tiger -L�wen -Panter -Wolf -Rakshasa - - - -Trolle ------- - -Olog-Hai -Riesen -Oger - -Orks ----- - -Uruks -Gnolle -Hobgoblin -Troglodyte - - -Insekten --------- - - -D�monen -------- - -Teufel - - - -Goblins -------- - -Kobolde -Gnome -Wichtel - + +Elfen +----- + +Waldelfen +Hochelfen +Grauelfen +Meerelfen +Auelfen +Dunkelelfen +Sylphen + + +Halblinge +--------- + +Kender + + +Meermenschen +------------ + +Nymphen +Meervolk +Echsen + + +Zentauren +--------- + +Satyre + + +Zwerge +------ + +Duergar + + +Katzen +------ + +Tiger +L�wen +Panter +Wolf +Rakshasa + + + +Trolle +------ + +Olog-Hai +Riesen +Oger + +Orks +---- + +Uruks +Gnolle +Hobgoblin +Troglodyte + + +Insekten +-------- + + +D�monen +------- + +Teufel + + + +Goblins +------- + +Kobolde +Gnome +Wichtel + diff --git a/doc/todo.txt b/doc/todo.txt index b573a08c2..d131a3253 100644 --- a/doc/todo.txt +++ b/doc/todo.txt @@ -1,239 +1,239 @@ -TODO, FEATURES, usw: - -- alte Artefakte sollten auch permanente Aura kosten - -- Traumauge auf 5 PA senken. - -- news.silly: - - Statistik der Regionen mit den meisten Gr�bern - - Wahl zur unbeliebtesten Region der Welt (Wo Bauern am wenigsten gern sein - wollen). - -- NEW_ITEMS: - - SILVERWEIGHT, silber nicth doppelt berechnen. - - -- Monster sollten die Runde nach dem Auftauchen nicht angreifen k�nnen. - -- Alchemie: Mehr als einen Trank/Runde brauen - Tr�nke aufwerte/billiger machen - -- items, die man selber benennen kann. - namen werden reserviert f�r eine partei, jede partei nur endlich viele. - derartige items wiegen nichts, k�nnen frei gehandelt werden - spezielle option, um solche items an beliebige einheiten zu �bergeben - (amulett des treffens, u.�.) - -- Tr�nke aufwerten, - -- Geb�ude f�r D�monen? - -- Parteiwissen - -- Mails "von Einheiten an Einheiten". - -- Neue Schiffstypen - -- Meditation / Trance? - langer Befehl, bringt doppelte Regeneration, braucht Heiligen Hain - oder Magierturm? - -- Linear Stufenabh�ngige Zauber ausbauen, ist wohl zu verwirrend, das - ein Zauber Stufenabh�ngig ist aber nicht in der Stufe variiert werden - kann. - -- parteigetarnte alliierte angreifbar machen. siehe mail an e-kom, enno, 29.8.00 - -- Anmeldungen direkt in den mapper integrieren - -+ HELFE-Gruppen - - -- Wiederanmeldungen im Wochenbericht von Erstanmeldungen trennen - -- Nichtmeermenschen Piraterie einfacher machen. (20 Lerntage auf See? - Geringer Arbeitslohn?) - -- battle.c: evtl. kann man sich b->fighters sparen? - -- struct building: ein paar der variablen k�nnen auch attribute sein, siehe header - -+ battle.c: b->see_matrix = calloc((max_fac_no+1), sizeof(boolean *)); - (enno) die see_matrix ist als speichermethode ziemlich ineffizient, - da es eine sparse matrix ist. besser so machen wie in cansee() - -- battle.c: Dr�ber nachdenken, ob struct battle wirklich dynamisch angelegt werden sollte. - (enno) nein, eigentlich sollte sie das nicht... - -- mehr Gel�ndeunterschiede. Vorschl�ge: - - Sumpf: bewegung -1 - -+ potion effects werden bei transfermen nicht skaliert. - sp�testens im item-source wird das gefixt. - -- Durch �bergeben kann man Silber vor Beklaue sch�tzen - -- Botschaft an Einheit <nr> gibt als Meldung nur - 'Eine Botschaft von xyz: "<nr>"' - -- Schiffeversenken gibt kaputte Meldung - Cef'az (c142) in D�r'Aglar (18,-16) versenkt die X~Lc^H~@~[c^H^X~Gc^Hm - (17). - (Das Schiff war die Cir'mor (1142), Langboot) - -- Monsterauseinanderlaufen klappt nicht. - -+ cansee() fehlt in vielen Zaubern. - -+ parser hat neuerdings ein umlautproblem (unter windows) (�l->l) - -+ gr�ber verwittern - -- kampfzauber im cr anzeigen. - -- umlautfix fixen. - -+ Frubilaszat (Lhmc) findet 0 Blasenmorcheln. - -+ schiffsfix fixen. - -+ handel vereinfachen. - -? Durch Fahre/Transportiere k�nnen Nichtschwimmer/Nichtflieger �ber - Meerengen, wenn ein Schwimmer/Flieger sie transportiert. Rast auf - dem Meer ist f�r sie aber nicht m�glich. Evt. kann man da tricksen, - mu� �berpr�ft werden. - -- Transportkapazit�t sollte in race[]. - -+ Lehre-Meldungen: - skill-Nummern werden nirgends definiert. - (enno) da mu� eine liste her, in einem rules.cr - (enno) oder besser, wir geben die namen aus. - -- Fehler-beschreibungen sind inkonsistent: - > "Dusei-Endlager (cawk) ist mindestens gleich gut wie wir.";error - aber - > 65;errno - (statt "Die Lernkosten k�nnen nicht bezahlt werden") - -- Unterhalt-Zahlungen: - Es fehlt Unterscheidung zwischen Bezahlung und nicht-bezahlung, - sowie der Betrag. - (enno) ja, ist schwer, wegen der komplexen message. - -+ Luxusgut-Ein-/Verkauf: - Warum auf 2 Messages aufspalten ? - (enno) warum nicht. - (corwin) Weil nur noch ne uninteressante Message mehr? - -? casualties-Messages nicht definiert. (Was soll die machen?) - (enno) - - Die sollen in render.c eine Spezialbehandlung bekommen. - + Quickfix: Eine einfache Ausgabe f�r den NR. - -+ hilfen f�r ehmv/vorlage im CR (NUMMER, TEMP) - -- Werte mit 0 wieder in den CR aufnehmen (angefangen) - -+ lerntage -> lernpunkte (doku) - - -- Eine Konstruktion der Form - - new_message(...,"%s:bla",buf) funktioniert nicht. Es werden - Nonsens-Strings ausgegeben: - - Nummer 5r94 (5r94) in Syvanrylfed (4,4) produziert 85 Schwerter aus - Optionen: AUSWERTUNG ZUGVORLAGE SILBERPOOL STATISTIK MERIAN ADRESSEN - - Wird da evt. nur der Zeiger auf Buf gespeichert? Oha, dann haben - wir bei vielen Messages ein Problem. - - -> (enno) stimmt. Der �bergebene String darf nicht mehr ver�ndert werden, - strdup() ist dein freund. Um das anders zu machen, k�nnte man in - new_message() einstrdup() machen, wenn der typ %s gefuden wird. - - -> strings sollten allerdings eh selten sein, da ja meist locale-dependent. - ausnahmen sind eigentlich nur namen. - - -> passiert bei allen Zauberfehlermeldungen - -- Einordnung der Messages klappt scheinbar nicht, es stehen auch - Produktionsmessages unter Meldungen und Fehler. - - -> Die Einordnung ist erst sp�ter dazugekommen, und wird noch kaum - irgendwo benutzt - -+ Unterscheidung unitid(mage), "Jemand" in der Ausgabe ist z.B. - beim Zauber Erwecke Ents fehlerhaft. (Die zaubernde Partei bekommt - ein 'Jemand ...' in den Regionsmessages.) Fehler wohl erst beim - Rendering: v_mage_de bekommt i=0 obwohl bei allen Erzeugern ein - mage angegeben wird. - (katja) scheint zu funktionieren - -Implementationsl�cken: - -Es fehlen noch Spr�che f�r - -- Tybied (20): - Stufe 13 - Artefakte zerst�ren (ist noch unsinnig, da es keine Artefakte mit - mehr als 1 Aura gibt) - - zus�tzlich w�re sch�n: - niedrigstufiger Combatspell - Stufe 11 Non-Combat - Stufe 12 Non-Combat - - -- Illaun(15): - Stufe 1 - Stufe 13 - Stufe 14 - - F�r diese Zauber fehlen noch Ideen - - zus�tzlich w�re sch�n: - Stufe 2 Non-Combat - Stufe 7 Non-Combat - - -- Gwyrrd(27): - Stufe 11 - Stufe 12 - - Hier sind noch einige nicht weiter ausgearbeitete Zauberideen - vorhanden - -- Cerddor(26): - Stufe 14 - - Hier sind noch einige nicht weiter ausgearbeitete Zauberideen - vorhanden, aber alles eher niedrigstufige - - -- Draig(18): - Stufe 1 - Stufe 13 - Wahnsinn (Einheit, negativ) - - Hier fehlt nur die Implementation - - zus�tzlich w�re sch�n: - Stufe 2 Non-Combat - -Dann gibt es f�r jedes Gebiet zu jeder Stufe kleiner 15 mindestens einen -normalen Spruch. - - - Kristall des Schutzes - Der Kristall erh�ht im Kampf die f�r die Berechnung der - Magieresistenz angesetzte Stufe von 500 Personen (wenn - Besitzer ein Magier) oder 200 Personen (wenn Besitzer kein - Magier) der eigenen Partei (oder, wenn alle Personen der eigenen - gesch�tzt sind, von Alliierten) um 25%. Der Besitzer mu� kein - Magier sein. Implementation �ber ein Flag, welches vor dem Kampf - gesetzt wird. Sollte teuer sein, da Wirkung ziemlich heftig. - - +TODO, FEATURES, usw: + +- alte Artefakte sollten auch permanente Aura kosten + +- Traumauge auf 5 PA senken. + +- news.silly: + - Statistik der Regionen mit den meisten Gr�bern + - Wahl zur unbeliebtesten Region der Welt (Wo Bauern am wenigsten gern sein + wollen). + +- NEW_ITEMS: + - SILVERWEIGHT, silber nicth doppelt berechnen. + + +- Monster sollten die Runde nach dem Auftauchen nicht angreifen k�nnen. + +- Alchemie: Mehr als einen Trank/Runde brauen + Tr�nke aufwerte/billiger machen + +- items, die man selber benennen kann. + namen werden reserviert f�r eine partei, jede partei nur endlich viele. + derartige items wiegen nichts, k�nnen frei gehandelt werden + spezielle option, um solche items an beliebige einheiten zu �bergeben + (amulett des treffens, u.�.) + +- Tr�nke aufwerten, + +- Geb�ude f�r D�monen? + +- Parteiwissen + +- Mails "von Einheiten an Einheiten". + +- Neue Schiffstypen + +- Meditation / Trance? + langer Befehl, bringt doppelte Regeneration, braucht Heiligen Hain + oder Magierturm? + +- Linear Stufenabh�ngige Zauber ausbauen, ist wohl zu verwirrend, das + ein Zauber Stufenabh�ngig ist aber nicht in der Stufe variiert werden + kann. + +- parteigetarnte alliierte angreifbar machen. siehe mail an e-kom, enno, 29.8.00 + +- Anmeldungen direkt in den mapper integrieren + ++ HELFE-Gruppen + + +- Wiederanmeldungen im Wochenbericht von Erstanmeldungen trennen + +- Nichtmeermenschen Piraterie einfacher machen. (20 Lerntage auf See? + Geringer Arbeitslohn?) + +- battle.c: evtl. kann man sich b->fighters sparen? + +- struct building: ein paar der variablen k�nnen auch attribute sein, siehe header + ++ battle.c: b->see_matrix = calloc((max_fac_no+1), sizeof(boolean *)); + (enno) die see_matrix ist als speichermethode ziemlich ineffizient, + da es eine sparse matrix ist. besser so machen wie in cansee() + +- battle.c: Dr�ber nachdenken, ob struct battle wirklich dynamisch angelegt werden sollte. + (enno) nein, eigentlich sollte sie das nicht... + +- mehr Gel�ndeunterschiede. Vorschl�ge: + - Sumpf: bewegung -1 + ++ potion effects werden bei transfermen nicht skaliert. + sp�testens im item-source wird das gefixt. + +- Durch �bergeben kann man Silber vor Beklaue sch�tzen + +- Botschaft an Einheit <nr> gibt als Meldung nur + 'Eine Botschaft von xyz: "<nr>"' + +- Schiffeversenken gibt kaputte Meldung + Cef'az (c142) in D�r'Aglar (18,-16) versenkt die X~Lc^H~@~[c^H^X~Gc^Hm + (17). + (Das Schiff war die Cir'mor (1142), Langboot) + +- Monsterauseinanderlaufen klappt nicht. + ++ cansee() fehlt in vielen Zaubern. + ++ parser hat neuerdings ein umlautproblem (unter windows) (�l->l) + ++ gr�ber verwittern + +- kampfzauber im cr anzeigen. + +- umlautfix fixen. + ++ Frubilaszat (Lhmc) findet 0 Blasenmorcheln. + ++ schiffsfix fixen. + ++ handel vereinfachen. + +? Durch Fahre/Transportiere k�nnen Nichtschwimmer/Nichtflieger �ber + Meerengen, wenn ein Schwimmer/Flieger sie transportiert. Rast auf + dem Meer ist f�r sie aber nicht m�glich. Evt. kann man da tricksen, + mu� �berpr�ft werden. + +- Transportkapazit�t sollte in race[]. + ++ Lehre-Meldungen: + skill-Nummern werden nirgends definiert. + (enno) da mu� eine liste her, in einem rules.cr + (enno) oder besser, wir geben die namen aus. + +- Fehler-beschreibungen sind inkonsistent: + > "Dusei-Endlager (cawk) ist mindestens gleich gut wie wir.";error + aber + > 65;errno + (statt "Die Lernkosten k�nnen nicht bezahlt werden") + +- Unterhalt-Zahlungen: + Es fehlt Unterscheidung zwischen Bezahlung und nicht-bezahlung, + sowie der Betrag. + (enno) ja, ist schwer, wegen der komplexen message. + ++ Luxusgut-Ein-/Verkauf: + Warum auf 2 Messages aufspalten ? + (enno) warum nicht. + (corwin) Weil nur noch ne uninteressante Message mehr? + +? casualties-Messages nicht definiert. (Was soll die machen?) + (enno) + - Die sollen in render.c eine Spezialbehandlung bekommen. + + Quickfix: Eine einfache Ausgabe f�r den NR. + ++ hilfen f�r ehmv/vorlage im CR (NUMMER, TEMP) + +- Werte mit 0 wieder in den CR aufnehmen (angefangen) + ++ lerntage -> lernpunkte (doku) + + +- Eine Konstruktion der Form + + new_message(...,"%s:bla",buf) funktioniert nicht. Es werden + Nonsens-Strings ausgegeben: + + Nummer 5r94 (5r94) in Syvanrylfed (4,4) produziert 85 Schwerter aus + Optionen: AUSWERTUNG ZUGVORLAGE SILBERPOOL STATISTIK MERIAN ADRESSEN + + Wird da evt. nur der Zeiger auf Buf gespeichert? Oha, dann haben + wir bei vielen Messages ein Problem. + + -> (enno) stimmt. Der �bergebene String darf nicht mehr ver�ndert werden, + strdup() ist dein freund. Um das anders zu machen, k�nnte man in + new_message() einstrdup() machen, wenn der typ %s gefuden wird. + + -> strings sollten allerdings eh selten sein, da ja meist locale-dependent. + ausnahmen sind eigentlich nur namen. + + -> passiert bei allen Zauberfehlermeldungen + +- Einordnung der Messages klappt scheinbar nicht, es stehen auch + Produktionsmessages unter Meldungen und Fehler. + + -> Die Einordnung ist erst sp�ter dazugekommen, und wird noch kaum + irgendwo benutzt + ++ Unterscheidung unitid(mage), "Jemand" in der Ausgabe ist z.B. + beim Zauber Erwecke Ents fehlerhaft. (Die zaubernde Partei bekommt + ein 'Jemand ...' in den Regionsmessages.) Fehler wohl erst beim + Rendering: v_mage_de bekommt i=0 obwohl bei allen Erzeugern ein + mage angegeben wird. + (katja) scheint zu funktionieren + +Implementationsl�cken: + +Es fehlen noch Spr�che f�r + +- Tybied (20): + Stufe 13 + Artefakte zerst�ren (ist noch unsinnig, da es keine Artefakte mit + mehr als 1 Aura gibt) + + zus�tzlich w�re sch�n: + niedrigstufiger Combatspell + Stufe 11 Non-Combat + Stufe 12 Non-Combat + + +- Illaun(15): + Stufe 1 + Stufe 13 + Stufe 14 + + F�r diese Zauber fehlen noch Ideen + + zus�tzlich w�re sch�n: + Stufe 2 Non-Combat + Stufe 7 Non-Combat + + +- Gwyrrd(27): + Stufe 11 + Stufe 12 + + Hier sind noch einige nicht weiter ausgearbeitete Zauberideen + vorhanden + +- Cerddor(26): + Stufe 14 + + Hier sind noch einige nicht weiter ausgearbeitete Zauberideen + vorhanden, aber alles eher niedrigstufige + + +- Draig(18): + Stufe 1 + Stufe 13 + Wahnsinn (Einheit, negativ) + + Hier fehlt nur die Implementation + + zus�tzlich w�re sch�n: + Stufe 2 Non-Combat + +Dann gibt es f�r jedes Gebiet zu jeder Stufe kleiner 15 mindestens einen +normalen Spruch. + + + Kristall des Schutzes + Der Kristall erh�ht im Kampf die f�r die Berechnung der + Magieresistenz angesetzte Stufe von 500 Personen (wenn + Besitzer ein Magier) oder 200 Personen (wenn Besitzer kein + Magier) der eigenen Partei (oder, wenn alle Personen der eigenen + gesch�tzt sind, von Alliierten) um 25%. Der Besitzer mu� kein + Magier sein. Implementation �ber ein Flag, welches vor dem Kampf + gesetzt wird. Sollte teuer sein, da Wirkung ziemlich heftig. + + diff --git a/doc/triggers.txt b/doc/triggers.txt index 5470a5d5e..fc1ee0b20 100644 --- a/doc/triggers.txt +++ b/doc/triggers.txt @@ -1,111 +1,111 @@ -==-------------------== -New Style Eventhandling -==-------------------== - - Zweck des ganzen ist es, m�glichst frei Reaktionen auf Ereignisse zu - implementieren. Dazu mu� nat�rlich defineirt sein, was so ein Ereignis - ist. Sowohl die Eriegnisse als auch das, was daraufhin geschieht, mu� - m�glichst flexibel erweiterbar sein. au�erdem sollen solche - Ereigniss-Behandlungen zur Laufzeit defineirt werden k�nnen. Die m�glichen - Events kann man nur zur Compilezeit definieren, und auch die Klassen von - Behandlungsroutinen, aber festzulegen wer wann auf was reagiert sollte - durch einen Spruch, das auftauchen eines Drachen, einen Event oder den Tod - einer Einheit ausgel�st werden k�nnen, und beliebiges anderes. - -Wie's geht: - - Wenn durch den Code ein Event "event" ausgel�st wird, dann wird f�r das - betroffene Objekt X die Funktion handle_event(X->attribs, "event") - aufgerufen. Ja, der Event ist ein String. - - handle_event(a, e) sucht in der Liste der attribute nach einem - at_eventhandler Objekt. So ein at_eventhandler verwaltet eine Liste von - Trigger-Objekten trigger_list mit Daten und handle() Funktion, die im Fall - des Events aufgerufen wird. F�r jeden event-typ (string) gibt es ein - solches at_eventhandler Attribut in der Attributliste, das mehrere - Trigger-Funktionen beinhalten kann. Ich glaube, die hat Ingo in seinem - Ansatz "action" getauft. - - Wurde ein Passendes gefunden, dann wird der Reihe nach jeder Trigger - ausgef�hrt. - - Das ganze wird im Datenfile sogar ziemlich lesbar, wie man hier an diesem - Magier sieht: - eventhandler destroy killunit LeL end - Hier ist ein eventhandler, der im falle eines "destroy" Events auch die - Einheit LeL killt (LeL ist der Vertraute des Magiers). - -Neue Trigger-Typen machen: - - Neue Trigger zu definieren ist ziemlich leicht, und ich habe schonmal ein - paar flexible vordefiniert. Sie sollten m�glichst im Verzeichnis triggers/ - landen. Dran denken, das jeder in Eressea verwendete trigger-typ mit - tt_register() angemeldet werden mu�. Das passiert in der Datei - eressea/triggers.c - - Dabei lohnt es sich, die trigger etwas genereller zu mchen. F�r viele von - ihnen sollte man resolve.[hc] verstanden haben, da man das zum Speichern - von Referenzen auf Parteien, Einheiten, usw. ben�tigt. - -Trigger aktivieren: - - Der Trigger sollte jeweils in der Attributliste des Objektes landen, - dessen Existnez f�r die Ausf�hrung n�tig ist. z.B. der Trigger zum T�ten - des Familiars beim Magier, der zum �bergeben eines item an eine person die - ein geb�ude betritt, in das Geb�ude. - - Beispiel: Wenn die verzauberte Burg b zerst�rt wird, soll der zaubernde - Magier einen Schock erleiden: - add_trigger(&b->attribs, "destroy", trigger_shock(mage)); - Steht die Burg jedoch nach 10 Runden noch an ihrem Fleck, bekommt er einen - Schatz von 100 Silber: - trigger * ttreasure = trigger_giveitem(mage, &i_silver, 100); - trigger * ttimer = trigger_timetrigger(10, ttreasure); - add_trigger(&b-attribs, "timer", ttimer); - Wie man sieht, kann ein trigger einen anderen ausl�sen, und mit etwas - Geschick kann man ganze Ketten von Ereignissen hinbekommen, die wieder - neue Trigger setzen, usw. - -Bisher definierte Events: (NI=Not Implemented) - - {building|faction|unit|ship}:"destroy" - Das Objekt verschwindet. - {building|faction|unit|ship|region}:"timer" - einmal pro Runde in - eressea.c::ageing() - {building}"enter" - Geb�ude oder Schiff wird betreten (NI) - -Bisher definierte trigger: - - - timeout: meta-trigger, aktiviert eine liste von triggern nach einer - zeitspanne. - - changerace: �ndert race/irace f�r eine einheit - - giveitem: gibt items eines typs an eine einheit. - - killunit: t�tet die angegebene einhiet. - - shock: schockt einen magier. - - changefaction - - removecurse - -adaptierte alte trigger: - - - famililars: - familiar: on "destroy" shock(mage) - mage: on "destroy" killunit(familiar) - - toad: - mage: on "timer" timeout([changerace(), giveitem(toadslime)]) - - summondragon: - region: on "timer" timeout([createunit()]) - - magicboost: - mage: on "timer" timeout(createcurse()) - - charm: - target: on "timer" changefaction(target) - new faction: on "destroy" destroy(target) - -problems to be solved: - - - propagation of triggers/attributes in general - - was, wenn ein removecurse(c) ausgefuehrt werden soll, aber der curse - sich propagiert hat? daf�r waere wohl ein forwarding-graph ganz geeignet. - (spells:5066, alp) - -TODO: - - - fprintf/fscanf nochmal checken. +==-------------------== +New Style Eventhandling +==-------------------== + + Zweck des ganzen ist es, m�glichst frei Reaktionen auf Ereignisse zu + implementieren. Dazu mu� nat�rlich defineirt sein, was so ein Ereignis + ist. Sowohl die Eriegnisse als auch das, was daraufhin geschieht, mu� + m�glichst flexibel erweiterbar sein. au�erdem sollen solche + Ereigniss-Behandlungen zur Laufzeit defineirt werden k�nnen. Die m�glichen + Events kann man nur zur Compilezeit definieren, und auch die Klassen von + Behandlungsroutinen, aber festzulegen wer wann auf was reagiert sollte + durch einen Spruch, das auftauchen eines Drachen, einen Event oder den Tod + einer Einheit ausgel�st werden k�nnen, und beliebiges anderes. + +Wie's geht: + + Wenn durch den Code ein Event "event" ausgel�st wird, dann wird f�r das + betroffene Objekt X die Funktion handle_event(X->attribs, "event") + aufgerufen. Ja, der Event ist ein String. + + handle_event(a, e) sucht in der Liste der attribute nach einem + at_eventhandler Objekt. So ein at_eventhandler verwaltet eine Liste von + Trigger-Objekten trigger_list mit Daten und handle() Funktion, die im Fall + des Events aufgerufen wird. F�r jeden event-typ (string) gibt es ein + solches at_eventhandler Attribut in der Attributliste, das mehrere + Trigger-Funktionen beinhalten kann. Ich glaube, die hat Ingo in seinem + Ansatz "action" getauft. + + Wurde ein Passendes gefunden, dann wird der Reihe nach jeder Trigger + ausgef�hrt. + + Das ganze wird im Datenfile sogar ziemlich lesbar, wie man hier an diesem + Magier sieht: + eventhandler destroy killunit LeL end + Hier ist ein eventhandler, der im falle eines "destroy" Events auch die + Einheit LeL killt (LeL ist der Vertraute des Magiers). + +Neue Trigger-Typen machen: + + Neue Trigger zu definieren ist ziemlich leicht, und ich habe schonmal ein + paar flexible vordefiniert. Sie sollten m�glichst im Verzeichnis triggers/ + landen. Dran denken, das jeder in Eressea verwendete trigger-typ mit + tt_register() angemeldet werden mu�. Das passiert in der Datei + eressea/triggers.c + + Dabei lohnt es sich, die trigger etwas genereller zu mchen. F�r viele von + ihnen sollte man resolve.[hc] verstanden haben, da man das zum Speichern + von Referenzen auf Parteien, Einheiten, usw. ben�tigt. + +Trigger aktivieren: + + Der Trigger sollte jeweils in der Attributliste des Objektes landen, + dessen Existnez f�r die Ausf�hrung n�tig ist. z.B. der Trigger zum T�ten + des Familiars beim Magier, der zum �bergeben eines item an eine person die + ein geb�ude betritt, in das Geb�ude. + + Beispiel: Wenn die verzauberte Burg b zerst�rt wird, soll der zaubernde + Magier einen Schock erleiden: + add_trigger(&b->attribs, "destroy", trigger_shock(mage)); + Steht die Burg jedoch nach 10 Runden noch an ihrem Fleck, bekommt er einen + Schatz von 100 Silber: + trigger * ttreasure = trigger_giveitem(mage, &i_silver, 100); + trigger * ttimer = trigger_timetrigger(10, ttreasure); + add_trigger(&b-attribs, "timer", ttimer); + Wie man sieht, kann ein trigger einen anderen ausl�sen, und mit etwas + Geschick kann man ganze Ketten von Ereignissen hinbekommen, die wieder + neue Trigger setzen, usw. + +Bisher definierte Events: (NI=Not Implemented) + + {building|faction|unit|ship}:"destroy" - Das Objekt verschwindet. + {building|faction|unit|ship|region}:"timer" - einmal pro Runde in + eressea.c::ageing() + {building}"enter" - Geb�ude oder Schiff wird betreten (NI) + +Bisher definierte trigger: + + - timeout: meta-trigger, aktiviert eine liste von triggern nach einer + zeitspanne. + - changerace: �ndert race/irace f�r eine einheit + - giveitem: gibt items eines typs an eine einheit. + - killunit: t�tet die angegebene einhiet. + - shock: schockt einen magier. + - changefaction + - removecurse + +adaptierte alte trigger: + + - famililars: + familiar: on "destroy" shock(mage) + mage: on "destroy" killunit(familiar) + - toad: + mage: on "timer" timeout([changerace(), giveitem(toadslime)]) + - summondragon: + region: on "timer" timeout([createunit()]) + - magicboost: + mage: on "timer" timeout(createcurse()) + - charm: + target: on "timer" changefaction(target) + new faction: on "destroy" destroy(target) + +problems to be solved: + + - propagation of triggers/attributes in general + - was, wenn ein removecurse(c) ausgefuehrt werden soll, aber der curse + sich propagiert hat? daf�r waere wohl ein forwarding-graph ganz geeignet. + (spells:5066, alp) + +TODO: + + - fprintf/fscanf nochmal checken. diff --git a/game-e2/eressea.ini b/game-e2/eressea.ini index 15eb20b5e..eba302cc3 100644 --- a/game-e2/eressea.ini +++ b/game-e2/eressea.ini @@ -1,17 +1,17 @@ -[eressea] -base = . -load = setup.lua -report = reports -verbose = 0 -lomem = 0 -debug = 0 -memcheck = 0 -locales = de,en - -[config] -game = eressea -source_dir = ../.. -maxnmrs = 10 - -[editor] -color = 1 +[eressea] +base = . +load = setup.lua +report = reports +verbose = 0 +lomem = 0 +debug = 0 +memcheck = 0 +locales = de,en + +[config] +game = eressea +source_dir = ../.. +maxnmrs = 10 + +[editor] +color = 1 diff --git a/game-e2/setup.lua b/game-e2/setup.lua index ffbb81987..d9d885859 100644 --- a/game-e2/setup.lua +++ b/game-e2/setup.lua @@ -1,15 +1,15 @@ -local srcpath = config.source_dir -local respath = srcpath .. '/eressea/res' -local paths = { - 'eressea/scripts/?.lua', - 'server/scripts/?.lua', - 'external/lunit/?.lua' -} - -for idx, path in pairs(paths) do - package.path = srcpath .. '/' .. path .. ';' .. package.path -end - -read_xml(respath..'/config-eressea.xml', respath..'/catalog-eressea.xml') - -require "init" +local srcpath = config.source_dir +local respath = srcpath .. '/eressea/res' +local paths = { + 'eressea/scripts/?.lua', + 'server/scripts/?.lua', + 'external/lunit/?.lua' +} + +for idx, path in pairs(paths) do + package.path = srcpath .. '/' .. path .. ';' .. package.path +end + +read_xml(respath..'/config-eressea.xml', respath..'/catalog-eressea.xml') + +require "init" diff --git a/game-e3/eressea.ini b/game-e3/eressea.ini index 4adfd84f6..3d2a4898e 100644 --- a/game-e3/eressea.ini +++ b/game-e3/eressea.ini @@ -1,17 +1,17 @@ -[eressea] -base = . -load = setup.lua -report = reports -verbose = 0 -lomem = 0 -debug = 0 -memcheck = 0 -locales = de,en - -[config] -game = e3a -source_dir = ../.. -maxnmrs = 10 - -[editor] -color = 1 +[eressea] +base = . +load = setup.lua +report = reports +verbose = 0 +lomem = 0 +debug = 0 +memcheck = 0 +locales = de,en + +[config] +game = e3a +source_dir = ../.. +maxnmrs = 10 + +[editor] +color = 1 diff --git a/game-e3/setup.lua b/game-e3/setup.lua index 9c263b4ee..0c989c9d4 100644 --- a/game-e3/setup.lua +++ b/game-e3/setup.lua @@ -1,15 +1,15 @@ -local srcpath = config.source_dir -local respath = srcpath .. '/eressea/res' -local paths = { - 'eressea/scripts/?.lua', - 'server/scripts/?.lua', - 'external/lunit/?.lua' -} - -for idx, path in pairs(paths) do - package.path = srcpath .. '/' .. path .. ';' .. package.path -end - -read_xml(respath..'/config-e3a.xml', respath..'/catalog-e3a.xml') - -require "init" +local srcpath = config.source_dir +local respath = srcpath .. '/eressea/res' +local paths = { + 'eressea/scripts/?.lua', + 'server/scripts/?.lua', + 'external/lunit/?.lua' +} + +for idx, path in pairs(paths) do + package.path = srcpath .. '/' .. path .. ';' .. package.path +end + +read_xml(respath..'/config-e3a.xml', respath..'/catalog-e3a.xml') + +require "init" diff --git a/res/buildings/castle-2.xml b/res/buildings/castle-2.xml index 5f48e73ee..7b04102fd 100644 --- a/res/buildings/castle-2.xml +++ b/res/buildings/castle-2.xml @@ -1,24 +1,24 @@ -<?xml version="1.0"?> -<building name="castle" capacity="1"> - <function name="name" value="castle_name_2"/> - <function name="protection" value="lua_building_protection"/> - <function name="taxes" value="lua_building_taxes"/> - <construction skill="building" minskill="1" maxsize="10" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="2" maxsize="40" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="3" maxsize="200" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="4" maxsize="1000" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="5" maxsize="5000" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="6" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> -</building> +<?xml version="1.0"?> +<building name="castle" capacity="1"> + <function name="name" value="castle_name_2"/> + <function name="protection" value="lua_building_protection"/> + <function name="taxes" value="lua_building_taxes"/> + <construction skill="building" minskill="1" maxsize="10" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="2" maxsize="40" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="3" maxsize="200" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="4" maxsize="1000" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="5" maxsize="5000" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="6" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> +</building> diff --git a/res/buildings/castle.xml b/res/buildings/castle.xml index 296d1f716..071fb13fc 100644 --- a/res/buildings/castle.xml +++ b/res/buildings/castle.xml @@ -1,26 +1,26 @@ -<?xml version="1.0"?> -<building name="castle" capacity="1"> - <function name="name" value="castle_name"/> - <function name="protection" value="eressea_building_protection"/> - <construction skill="building" minskill="1" maxsize="2" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="1" maxsize="8" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="2" maxsize="40" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="3" maxsize="200" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="4" maxsize="1000" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="5" maxsize="5000" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> - <construction skill="building" minskill="6" reqsize="1"> - <requirement type="stone" quantity="1"/> - </construction> -</building> +<?xml version="1.0"?> +<building name="castle" capacity="1"> + <function name="name" value="castle_name"/> + <function name="protection" value="eressea_building_protection"/> + <construction skill="building" minskill="1" maxsize="2" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="1" maxsize="8" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="2" maxsize="40" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="3" maxsize="200" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="4" maxsize="1000" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="5" maxsize="5000" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> + <construction skill="building" minskill="6" reqsize="1"> + <requirement type="stone" quantity="1"/> + </construction> +</building> diff --git a/res/catalog-e3a.xml b/res/catalog-e3a.xml index 661a6cedb..2b16bf737 100644 --- a/res/catalog-e3a.xml +++ b/res/catalog-e3a.xml @@ -1,10 +1,10 @@ -<?xml version="1.0"?> -<!DOCTYPE catalog - PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN" - "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"> - -<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> - <rewriteURI - uriStartString="eressea:///core/" - rewritePrefix="../../server/res/" /> -</catalog> +<?xml version="1.0"?> +<!DOCTYPE catalog + PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN" + "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"> + +<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> + <rewriteURI + uriStartString="eressea:///core/" + rewritePrefix="../../server/res/" /> +</catalog> diff --git a/res/catalog-eressea.xml b/res/catalog-eressea.xml index 661a6cedb..2b16bf737 100644 --- a/res/catalog-eressea.xml +++ b/res/catalog-eressea.xml @@ -1,10 +1,10 @@ -<?xml version="1.0"?> -<!DOCTYPE catalog - PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN" - "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"> - -<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> - <rewriteURI - uriStartString="eressea:///core/" - rewritePrefix="../../server/res/" /> -</catalog> +<?xml version="1.0"?> +<!DOCTYPE catalog + PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN" + "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd"> + +<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> + <rewriteURI + uriStartString="eressea:///core/" + rewritePrefix="../../server/res/" /> +</catalog> diff --git a/res/config-e3a.xml b/res/config-e3a.xml index a42b5ffdb..4409a4143 100644 --- a/res/config-e3a.xml +++ b/res/config-e3a.xml @@ -1,193 +1,193 @@ -<?xml version="1.0"?> -<eressea xmlns:xi="http://www.w3.org/2001/XInclude"> - <xi:include href="eressea:///core/messages.xml"/> - - <!-- Localization --> - <xi:include href="eressea:///core/de/strings.xml"/> - <xi:include href="eressea:///core/en/strings.xml"/> - - <xi:include href="eressea:///core/common/items.xml"/> - <xi:include href="eressea:///core/common/herbs.xml" /> - <xi:include href="eressea:///core/spoils.xml"/> - <xi:include href="eressea:///core/prefixes.xml"/> - <xi:include href="eressea:///core/common/buildings.xml"/> - <xi:include href="eressea:///core/equipment.xml"/> - <xi:include href="directions.xml"/> - - <xi:include href="e3a/ships.xml"/> - <xi:include href="e3a/shipnames.xml"/> - <xi:include href="e3a/terrains.xml"/> - <xi:include href="eressea:///core/calendar.xml"/> - <calendar name="thirdage" newyear="month_1" start="1"/> - <xi:include href="e3a/items.xml" /> - <xi:include href="e3a/strings.xml"/> - <xi:include href="e3a/messages.xml"/> - <xi:include href="e3a/races.xml"/> - <xi:include href="e3a/buildings.xml"/> - <xi:include href="e3a/equipment.xml"/> - <xi:include href="e3a/spells.xml"/> - <xi:include href="e3a/luxuries.xml" /> - <xi:include href="e3a/weapons.xml" /> - <xi:include href="e3a/armor.xml" /> - <xi:include href="e3a/resources.xml" /> - - <equipment> - <set name="first_unit"> - <item name="conquesttoken" amount="1"/> - <item name="log" amount="10"/> - <item name="stone" amount="10"/> - <item name="money" amount="5000"/> - </set> - </equipment> - - <xi:include href="names-undead.xml"/> - <xi:include href="names-skeletons.xml"/> - <xi:include href="names-zombies.xml"/> - <xi:include href="names-ghouls.xml"/> - <xi:include href="names-dragons.xml"/> - - <game name="E3"> - <!-- Game specific settings --> - <param name="database.gameid" value="7"></param> - - <!--order name="ARBEITEN" disable="yes"/--> - <order name="BETEN" disable="yes"/> - <order name="BELAGERE" disable="yes"/> - <order name="BEKLAUEN" disable="yes"/> - <order name="FRIEDEN" disable="yes"/> - <order name="GM" disable="yes"/> - <order name="JIHAD" disable="yes"/> - <order name="KRIEG" disable="yes"/> - <order name="KAUFEN" disable="yes"/> - <order name="LEHREN" disable="yes"/> - <order name="LIEFERE" disable="yes"/> - <order name="OPFERE" disable="yes"/> - <order name="SABOTIEREN" disable="yes"/> - <order name="SPIONIEREN" disable="yes"/> - <order name="TARNEN" disable="yes"/> - <order name="TREIBEN" disable="yes"/> - <order name="UNTERHALTEN" disable="yes"/> - <order name="VERKAUFEN" disable="yes"/> - <order name="WERWESEN" disable="yes"/> - <order name="XONTORMIA" disable="yes"/> - - <skill name="armorer" enable="true"/> - <skill name="bow" enable="true"/> - <skill name="building" enable="true"/> - <skill name="cartmaking" enable="true"/> - <skill name="catapult" enable="true"/> - <skill name="crossbow" enable="true"/> - <skill name="forestry" enable="true"/> - <skill name="magic" enable="true"/> - <skill name="melee" enable="true"/> - <skill name="mining" enable="true"/> - <skill name="polearm" enable="true"/> - <skill name="quarrying" enable="true"/> - <skill name="riding" enable="true"/> - <skill name="roadwork" enable="true"/> - <skill name="sailing" enable="true"/> - <skill name="shipcraft" enable="true"/> - <skill name="stamina" enable="true"/> - <skill name="tactics" enable="true"/> - <skill name="training" enable="true"/> - <skill name="unarmed" enable="true"/> - <skill name="weaponsmithing" enable="true"/> - - <skill name="herbalism" enable="false"/> - - <skill name="alchemy" enable="false"/> - <skill name="entertainment" enable="false"/> - <skill name="espionage" enable="false"/> - <skill name="perception" enable="false"/> - <skill name="stealth" enable="false"/> - <skill name="taxation" enable="false"/> - <skill name="trade" enable="false"/> - - <param name="NewbieImmunity" value="9"/> <!-- ends after turn 9 --> - - <param name="modules.astralspace" value="0"/> - <param name="modules.wormholes" value="0"/> - <param name="modules.markets" value="1"/> - - <!-- resource limitations --> - <param name="magic.regeneration" value="0.75"/> - <param name="magic.power" value="0.5"/> - <param name="resource.factor" value="0.25"/> - - <param name="skills.cost.tactics" value="500"/> - <param name="entertain.base" value="0"/> - <param name="entertain.perlevel" value="20"/> - <param name="nmr.timeout" value="5"/> - <param name="nmr.removenewbie" value="0"/> - <param name="GiveRestriction" value="3"/> - <param name="hunger.long" value="0"/> - <param name="hunger.demon.skill" value="1"/> - <param name="hunger.damage" value="1d9+9"/> - <param name="hunger.demons" value="1"/> - <param name="init_spells" value="0"/> - <param name="recruit.allow_merge" value="1"/> - <param name="study.expensivemigrants" value="1"/> - <param name="study.speedup" value="0"/> - <param name="world.era" value="3"/> - <param name="rules.migrants" value="0"/> - <param name="rules.transfermen" value="0"/> - <param name="rules.stealth.faction" value="0"/> - <param name="rules.check_overload" value="0"/> - <param name="rules.combat.goblinbonus" value="3"/> - <param name="rules.ship.damage_drift" value="0.00"/> <!-- percent damage from drifting--> - <param name="rules.alliances" value="1"/> - <param name="rules.combat.herospeed" value="3"/> - <param name="rules.combat.demon_vampire" value="5"/> <!-- regen 1 hp per X points of damage done --> - <param name="rules.combat.skill_bonus" value="0"/> - <!--param name="rules.combat.loot" value="5"/--> <!-- only self + others - keeploot --> - <param name="rules.items.loot_divisor" value="2"/> <!-- damage skims off 1/2 of goods transfers --> - <param name="rules.items.give_divisor" value="2"/> <!-- corruption skims off 1/2 of goods transfers --> - <param name="rules.move.owner_leave" value="1"/> <!-- owner must leave before moving --> - <param name="rules.region_owners" value="1"/> - <param name="rules.cavalry.skill" value="2"/> - <param name="rules.cavalry.mode" value="1"/> - <param name="rules.magic.multipotion" value="1"/> - <param name="rules.magic.wol_effect" value="5"/> - <param name="rules.magic.factionlist" value="1"/> - <param name="rules.magic.wol_type" value="2"/> - <param name="rules.magic.blessed_harvest" value="1"/> - <param name="rules.magic.common" value="tybied"/> <!-- tybied spells can be cast by anyone --> - <param name="rules.magic.elfpower" value="1"/> <!-- elves get ring-of-power bonus in a forest --> - <param name="rules.magic.playerschools" value="gwyrrd illaun draig cerddor"/> - <param name="rules.build.other_buildings" value="1"/> - <param name="rules.economy.taxation" value="1"/> - <param name="rules.economy.food" value="2"/> - <param name="rules.economy.wages" value="1"/> - <param name="rules.economy.roqf" value="5"/> - <param name="rules.economy.herbrot" value="0"/> - <param name="rules.dwarf_castles" value="1"/> - <!-- param name="rules.nmr.destroy" value="1"/ --> - <param name="rules.limit.faction" value="250"/> - <!--param name="rules.give" value="15"/ --> <!-- self + peasants + herbs + lux - goods --> - <param name="rules.economy.grow" value="1"/> - <param name="rules.tactics.formula" value="1"/> <!-- 10% per skilldiff --> - <param name="rules.help.mask" value="fight guard money give"/> - <param name="movement.shipspeed.skillbonus" value="6"/> - <param name="alliance.auto" value="fight"/> - <param name="alliance.restricted" value="fight"/> - </game> - <rules> - <function name="wage" value="minimum_wage"/> - </rules> - <strings> - <string name="mailto"> - <text locale="de">eressea-server@eressea.de</text> - <text locale="en">eressea-server@eressea.de</text> - </string> - <string name="newbie_info_1"> - <text locale="de">Bitte denke daran, deine Befehle mit dem Betreff - E3 BEFEHLE an eressea-server@eressea.de zu senden.</text> - <text locale="en">Remember to send your orders to - eressea-server@eressea.de with the subject E3 ORDERS.</text> - </string> - <string name="mailcmd"> - <text locale="de">E3 BEFEHLE</text> - <text locale="en">E3 ORDERS</text> - </string> - </strings> -</eressea> +<?xml version="1.0"?> +<eressea xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="eressea:///core/messages.xml"/> + + <!-- Localization --> + <xi:include href="eressea:///core/de/strings.xml"/> + <xi:include href="eressea:///core/en/strings.xml"/> + + <xi:include href="eressea:///core/common/items.xml"/> + <xi:include href="eressea:///core/common/herbs.xml" /> + <xi:include href="eressea:///core/spoils.xml"/> + <xi:include href="eressea:///core/prefixes.xml"/> + <xi:include href="eressea:///core/common/buildings.xml"/> + <xi:include href="eressea:///core/equipment.xml"/> + <xi:include href="directions.xml"/> + + <xi:include href="e3a/ships.xml"/> + <xi:include href="e3a/shipnames.xml"/> + <xi:include href="e3a/terrains.xml"/> + <xi:include href="eressea:///core/calendar.xml"/> + <calendar name="thirdage" newyear="month_1" start="1"/> + <xi:include href="e3a/items.xml" /> + <xi:include href="e3a/strings.xml"/> + <xi:include href="e3a/messages.xml"/> + <xi:include href="e3a/races.xml"/> + <xi:include href="e3a/buildings.xml"/> + <xi:include href="e3a/equipment.xml"/> + <xi:include href="e3a/spells.xml"/> + <xi:include href="e3a/luxuries.xml" /> + <xi:include href="e3a/weapons.xml" /> + <xi:include href="e3a/armor.xml" /> + <xi:include href="e3a/resources.xml" /> + + <equipment> + <set name="first_unit"> + <item name="conquesttoken" amount="1"/> + <item name="log" amount="10"/> + <item name="stone" amount="10"/> + <item name="money" amount="5000"/> + </set> + </equipment> + + <xi:include href="names-undead.xml"/> + <xi:include href="names-skeletons.xml"/> + <xi:include href="names-zombies.xml"/> + <xi:include href="names-ghouls.xml"/> + <xi:include href="names-dragons.xml"/> + + <game name="E3"> + <!-- Game specific settings --> + <param name="database.gameid" value="7"></param> + + <!--order name="ARBEITEN" disable="yes"/--> + <order name="BETEN" disable="yes"/> + <order name="BELAGERE" disable="yes"/> + <order name="BEKLAUEN" disable="yes"/> + <order name="FRIEDEN" disable="yes"/> + <order name="GM" disable="yes"/> + <order name="JIHAD" disable="yes"/> + <order name="KRIEG" disable="yes"/> + <order name="KAUFEN" disable="yes"/> + <order name="LEHREN" disable="yes"/> + <order name="LIEFERE" disable="yes"/> + <order name="OPFERE" disable="yes"/> + <order name="SABOTIEREN" disable="yes"/> + <order name="SPIONIEREN" disable="yes"/> + <order name="TARNEN" disable="yes"/> + <order name="TREIBEN" disable="yes"/> + <order name="UNTERHALTEN" disable="yes"/> + <order name="VERKAUFEN" disable="yes"/> + <order name="WERWESEN" disable="yes"/> + <order name="XONTORMIA" disable="yes"/> + + <skill name="armorer" enable="true"/> + <skill name="bow" enable="true"/> + <skill name="building" enable="true"/> + <skill name="cartmaking" enable="true"/> + <skill name="catapult" enable="true"/> + <skill name="crossbow" enable="true"/> + <skill name="forestry" enable="true"/> + <skill name="magic" enable="true"/> + <skill name="melee" enable="true"/> + <skill name="mining" enable="true"/> + <skill name="polearm" enable="true"/> + <skill name="quarrying" enable="true"/> + <skill name="riding" enable="true"/> + <skill name="roadwork" enable="true"/> + <skill name="sailing" enable="true"/> + <skill name="shipcraft" enable="true"/> + <skill name="stamina" enable="true"/> + <skill name="tactics" enable="true"/> + <skill name="training" enable="true"/> + <skill name="unarmed" enable="true"/> + <skill name="weaponsmithing" enable="true"/> + + <skill name="herbalism" enable="false"/> + + <skill name="alchemy" enable="false"/> + <skill name="entertainment" enable="false"/> + <skill name="espionage" enable="false"/> + <skill name="perception" enable="false"/> + <skill name="stealth" enable="false"/> + <skill name="taxation" enable="false"/> + <skill name="trade" enable="false"/> + + <param name="NewbieImmunity" value="9"/> <!-- ends after turn 9 --> + + <param name="modules.astralspace" value="0"/> + <param name="modules.wormholes" value="0"/> + <param name="modules.markets" value="1"/> + + <!-- resource limitations --> + <param name="magic.regeneration" value="0.75"/> + <param name="magic.power" value="0.5"/> + <param name="resource.factor" value="0.25"/> + + <param name="skills.cost.tactics" value="500"/> + <param name="entertain.base" value="0"/> + <param name="entertain.perlevel" value="20"/> + <param name="nmr.timeout" value="5"/> + <param name="nmr.removenewbie" value="0"/> + <param name="GiveRestriction" value="3"/> + <param name="hunger.long" value="0"/> + <param name="hunger.demon.skill" value="1"/> + <param name="hunger.damage" value="1d9+9"/> + <param name="hunger.demons" value="1"/> + <param name="init_spells" value="0"/> + <param name="recruit.allow_merge" value="1"/> + <param name="study.expensivemigrants" value="1"/> + <param name="study.speedup" value="0"/> + <param name="world.era" value="3"/> + <param name="rules.migrants" value="0"/> + <param name="rules.transfermen" value="0"/> + <param name="rules.stealth.faction" value="0"/> + <param name="rules.check_overload" value="0"/> + <param name="rules.combat.goblinbonus" value="3"/> + <param name="rules.ship.damage_drift" value="0.00"/> <!-- percent damage from drifting--> + <param name="rules.alliances" value="1"/> + <param name="rules.combat.herospeed" value="3"/> + <param name="rules.combat.demon_vampire" value="5"/> <!-- regen 1 hp per X points of damage done --> + <param name="rules.combat.skill_bonus" value="0"/> + <!--param name="rules.combat.loot" value="5"/--> <!-- only self + others - keeploot --> + <param name="rules.items.loot_divisor" value="2"/> <!-- damage skims off 1/2 of goods transfers --> + <param name="rules.items.give_divisor" value="2"/> <!-- corruption skims off 1/2 of goods transfers --> + <param name="rules.move.owner_leave" value="1"/> <!-- owner must leave before moving --> + <param name="rules.region_owners" value="1"/> + <param name="rules.cavalry.skill" value="2"/> + <param name="rules.cavalry.mode" value="1"/> + <param name="rules.magic.multipotion" value="1"/> + <param name="rules.magic.wol_effect" value="5"/> + <param name="rules.magic.factionlist" value="1"/> + <param name="rules.magic.wol_type" value="2"/> + <param name="rules.magic.blessed_harvest" value="1"/> + <param name="rules.magic.common" value="tybied"/> <!-- tybied spells can be cast by anyone --> + <param name="rules.magic.elfpower" value="1"/> <!-- elves get ring-of-power bonus in a forest --> + <param name="rules.magic.playerschools" value="gwyrrd illaun draig cerddor"/> + <param name="rules.build.other_buildings" value="1"/> + <param name="rules.economy.taxation" value="1"/> + <param name="rules.economy.food" value="2"/> + <param name="rules.economy.wages" value="1"/> + <param name="rules.economy.roqf" value="5"/> + <param name="rules.economy.herbrot" value="0"/> + <param name="rules.dwarf_castles" value="1"/> + <!-- param name="rules.nmr.destroy" value="1"/ --> + <param name="rules.limit.faction" value="250"/> + <!--param name="rules.give" value="15"/ --> <!-- self + peasants + herbs + lux - goods --> + <param name="rules.economy.grow" value="1"/> + <param name="rules.tactics.formula" value="1"/> <!-- 10% per skilldiff --> + <param name="rules.help.mask" value="fight guard money give"/> + <param name="movement.shipspeed.skillbonus" value="6"/> + <param name="alliance.auto" value="fight"/> + <param name="alliance.restricted" value="fight"/> + </game> + <rules> + <function name="wage" value="minimum_wage"/> + </rules> + <strings> + <string name="mailto"> + <text locale="de">eressea-server@eressea.de</text> + <text locale="en">eressea-server@eressea.de</text> + </string> + <string name="newbie_info_1"> + <text locale="de">Bitte denke daran, deine Befehle mit dem Betreff + E3 BEFEHLE an eressea-server@eressea.de zu senden.</text> + <text locale="en">Remember to send your orders to + eressea-server@eressea.de with the subject E3 ORDERS.</text> + </string> + <string name="mailcmd"> + <text locale="de">E3 BEFEHLE</text> + <text locale="en">E3 ORDERS</text> + </string> + </strings> +</eressea> diff --git a/res/config-eressea.xml b/res/config-eressea.xml index 291277c6f..1ce464728 100644 --- a/res/config-eressea.xml +++ b/res/config-eressea.xml @@ -1,121 +1,121 @@ -<?xml version="1.0"?> -<eressea xmlns:xi="http://www.w3.org/2001/XInclude"> - <xi:include href="eressea:///core/messages.xml"/> - - <!-- Localization --> - <xi:include href="eressea:///core/de/strings.xml"/> - <xi:include href="eressea:///core/en/strings.xml"/> - <xi:include href="eressea/spellinfo.xml" /> - - <xi:include href="eressea:///core/common/items.xml" /> - <xi:include href="eressea:///core/common/armor.xml" /> - <xi:include href="eressea:///core/common/weapons.xml" /> - <xi:include href="eressea:///core/common/resources.xml" /> - <xi:include href="eressea:///core/common/luxuries.xml" /> - <xi:include href="eressea:///core/common/herbs.xml" /> - <xi:include href="eressea:///core/common/potions.xml" /> - <xi:include href="eressea:///core/spoils.xml"/> - <xi:include href="eressea/races.xml"/> - <xi:include href="eressea:///core/prefixes.xml"/> - <xi:include href="eressea:///core/ships.xml"/> - <xi:include href="eressea:///core/common/buildings.xml"/> - <xi:include href="eressea:///core/equipment.xml"/> - <xi:include href="eressea:///core/terrains.xml"/> - <xi:include href="eressea/terrains.xml"/> - <xi:include href="directions.xml"/> - <xi:include href="eressea/artrewards.xml"/> - <xi:include href="eressea/buildings.xml"/> - <xi:include href="eressea:///core/calendar.xml"/> - <calendar name="secondage" newyear="month_1" start="184"/> - <xi:include href="eressea/equipment.xml"/> - <xi:include href="eressea/items.xml"/> - <xi:include href="eressea/spells.xml"/> - <xi:include href="eressea/strings.xml"/> - <equipment> - <set name="first_unit"> - <item name="conquesttoken" amount="1"/> - <item name="log" amount="30"/> - <item name="stone" amount="30"/> - <item name="money" amount="4200"/> - </set> - <set name="new_faction"> - <item name="adamantium" amount="1"/> - </set> - </equipment> - - <xi:include href="names-undead.xml"/> - <xi:include href="names-skeletons.xml"/> - <xi:include href="names-zombies.xml"/> - <xi:include href="names-ghouls.xml"/> - <xi:include href="names-dragons.xml"/> - - <game name="Eressea"> - <!-- Game specific settings --> - - <order name="BEZAHLEN" disable="yes"/> - <order name="FRIEDEN" disable="yes"/> - <order name="GM" disable="yes"/> - <order name="JIHAD" disable="yes"/> - <order name="KRIEG" disable="yes"/> - <order name="WERWESEN" disable="yes"/> - <order name="XONTORMIA" disable="yes"/> - - <skill name="alchemy" enable="true"/> - <skill name="crossbow" enable="true"/> - <skill name="mining" enable="true"/> - <skill name="bow" enable="true"/> - <skill name="building" enable="true"/> - <skill name="trade" enable="true"/> - <skill name="forestry" enable="true"/> - <skill name="catapult" enable="true"/> - <skill name="herbalism" enable="true"/> - <skill name="magic" enable="true"/> - <skill name="training" enable="true"/> - <skill name="riding" enable="true"/> - <skill name="armorer" enable="true"/> - <skill name="shipcraft" enable="true"/> - <skill name="melee" enable="true"/> - <skill name="sailing" enable="true"/> - <skill name="polearm" enable="true"/> - <skill name="espionage" enable="true"/> - <skill name="quarrying" enable="true"/> - <skill name="roadwork" enable="true"/> - <skill name="tactics" enable="true"/> - <skill name="stealth" enable="true"/> - <skill name="entertainment" enable="true"/> - <skill name="weaponsmithing" enable="true"/> - <skill name="cartmaking" enable="true"/> - <skill name="perception" enable="true"/> - <skill name="taxation" enable="true"/> - <skill name="stamina" enable="true"/> - <skill name="unarmed" enable="true"/> - - <param name="NewbieImmunity" value="8"/> - <param name="modules.wormholes" value="1"/> - <param name="entertain.base" value="0"/> - <param name="entertain.perlevel" value="20"/> - <param name="nmr.timeout" value="5"/> - <param name="nmr.removenewbie" value="10"/> - <param name="GiveRestriction" value="3"/> - <param name="hunger.long" value="1"/> - <param name="init_spells" value="0"/> - <param name="rules.check_overload" value="0"/> - <param name="rules.limit.faction" value="1500"/> - </game> - <strings> - <string name="mailto"> - <text locale="de">eressea-server@eressea.de</text> - <text locale="en">eressea-server@eressea.de</text> - </string> - <string name="newbie_info_1"> - <text locale="de">Bitte denke daran, deine Befehle mit dem Betreff - ERESSEA BEFEHLE an eressea-server@eressea.de zu senden.</text> - <text locale="en">Remember to send your orders to - eressea-server@eressea.de with the subject ERESSEA ORDERS.</text> - </string> - <string name="mailcmd"> - <text locale="de">ERESSEA BEFEHLE</text> - <text locale="en">ERESSEA ORDERS</text> - </string> - </strings> -</eressea> +<?xml version="1.0"?> +<eressea xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="eressea:///core/messages.xml"/> + + <!-- Localization --> + <xi:include href="eressea:///core/de/strings.xml"/> + <xi:include href="eressea:///core/en/strings.xml"/> + <xi:include href="eressea/spellinfo.xml" /> + + <xi:include href="eressea:///core/common/items.xml" /> + <xi:include href="eressea:///core/common/armor.xml" /> + <xi:include href="eressea:///core/common/weapons.xml" /> + <xi:include href="eressea:///core/common/resources.xml" /> + <xi:include href="eressea:///core/common/luxuries.xml" /> + <xi:include href="eressea:///core/common/herbs.xml" /> + <xi:include href="eressea:///core/common/potions.xml" /> + <xi:include href="eressea:///core/spoils.xml"/> + <xi:include href="eressea/races.xml"/> + <xi:include href="eressea:///core/prefixes.xml"/> + <xi:include href="eressea:///core/ships.xml"/> + <xi:include href="eressea:///core/common/buildings.xml"/> + <xi:include href="eressea:///core/equipment.xml"/> + <xi:include href="eressea:///core/terrains.xml"/> + <xi:include href="eressea/terrains.xml"/> + <xi:include href="directions.xml"/> + <xi:include href="eressea/artrewards.xml"/> + <xi:include href="eressea/buildings.xml"/> + <xi:include href="eressea:///core/calendar.xml"/> + <calendar name="secondage" newyear="month_1" start="184"/> + <xi:include href="eressea/equipment.xml"/> + <xi:include href="eressea/items.xml"/> + <xi:include href="eressea/spells.xml"/> + <xi:include href="eressea/strings.xml"/> + <equipment> + <set name="first_unit"> + <item name="conquesttoken" amount="1"/> + <item name="log" amount="30"/> + <item name="stone" amount="30"/> + <item name="money" amount="4200"/> + </set> + <set name="new_faction"> + <item name="adamantium" amount="1"/> + </set> + </equipment> + + <xi:include href="names-undead.xml"/> + <xi:include href="names-skeletons.xml"/> + <xi:include href="names-zombies.xml"/> + <xi:include href="names-ghouls.xml"/> + <xi:include href="names-dragons.xml"/> + + <game name="Eressea"> + <!-- Game specific settings --> + + <order name="BEZAHLEN" disable="yes"/> + <order name="FRIEDEN" disable="yes"/> + <order name="GM" disable="yes"/> + <order name="JIHAD" disable="yes"/> + <order name="KRIEG" disable="yes"/> + <order name="WERWESEN" disable="yes"/> + <order name="XONTORMIA" disable="yes"/> + + <skill name="alchemy" enable="true"/> + <skill name="crossbow" enable="true"/> + <skill name="mining" enable="true"/> + <skill name="bow" enable="true"/> + <skill name="building" enable="true"/> + <skill name="trade" enable="true"/> + <skill name="forestry" enable="true"/> + <skill name="catapult" enable="true"/> + <skill name="herbalism" enable="true"/> + <skill name="magic" enable="true"/> + <skill name="training" enable="true"/> + <skill name="riding" enable="true"/> + <skill name="armorer" enable="true"/> + <skill name="shipcraft" enable="true"/> + <skill name="melee" enable="true"/> + <skill name="sailing" enable="true"/> + <skill name="polearm" enable="true"/> + <skill name="espionage" enable="true"/> + <skill name="quarrying" enable="true"/> + <skill name="roadwork" enable="true"/> + <skill name="tactics" enable="true"/> + <skill name="stealth" enable="true"/> + <skill name="entertainment" enable="true"/> + <skill name="weaponsmithing" enable="true"/> + <skill name="cartmaking" enable="true"/> + <skill name="perception" enable="true"/> + <skill name="taxation" enable="true"/> + <skill name="stamina" enable="true"/> + <skill name="unarmed" enable="true"/> + + <param name="NewbieImmunity" value="8"/> + <param name="modules.wormholes" value="1"/> + <param name="entertain.base" value="0"/> + <param name="entertain.perlevel" value="20"/> + <param name="nmr.timeout" value="5"/> + <param name="nmr.removenewbie" value="10"/> + <param name="GiveRestriction" value="3"/> + <param name="hunger.long" value="1"/> + <param name="init_spells" value="0"/> + <param name="rules.check_overload" value="0"/> + <param name="rules.limit.faction" value="1500"/> + </game> + <strings> + <string name="mailto"> + <text locale="de">eressea-server@eressea.de</text> + <text locale="en">eressea-server@eressea.de</text> + </string> + <string name="newbie_info_1"> + <text locale="de">Bitte denke daran, deine Befehle mit dem Betreff + ERESSEA BEFEHLE an eressea-server@eressea.de zu senden.</text> + <text locale="en">Remember to send your orders to + eressea-server@eressea.de with the subject ERESSEA ORDERS.</text> + </string> + <string name="mailcmd"> + <text locale="de">ERESSEA BEFEHLE</text> + <text locale="en">ERESSEA ORDERS</text> + </string> + </strings> +</eressea> diff --git a/res/directions.xml b/res/directions.xml index 0e2e0b5fe..f70e7ec6d 100644 --- a/res/directions.xml +++ b/res/directions.xml @@ -1,4 +1,4 @@ -<?xml version="1.0"?> -<directions> - <dir name="vortex" desc="vortex_desc"/> -</directions> +<?xml version="1.0"?> +<directions> + <dir name="vortex" desc="vortex_desc"/> +</directions> diff --git a/res/e3a/armor.xml b/res/e3a/armor.xml index fe1d7fb45..b0cf14d54 100644 --- a/res/e3a/armor.xml +++ b/res/e3a/armor.xml @@ -1,12 +1,12 @@ -<?xml version="1.0"?> -<resources xmlns:xi="http://www.w3.org/2001/XInclude"> - <xi:include href="armor/chainmail.xml"/> - <xi:include href="armor/laenmail.xml"/> - <xi:include href="armor/laenshield.xml"/> - <xi:include href="armor/plate.xml"/> - <xi:include href="armor/rustychainmail.xml"/> - <xi:include href="armor/rustyshield.xml"/> - <xi:include href="armor/scale.xml"/> - <xi:include href="armor/shield.xml"/> - <xi:include href="armor/towershield.xml"/> -</resources> +<?xml version="1.0"?> +<resources xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="armor/chainmail.xml"/> + <xi:include href="armor/laenmail.xml"/> + <xi:include href="armor/laenshield.xml"/> + <xi:include href="armor/plate.xml"/> + <xi:include href="armor/rustychainmail.xml"/> + <xi:include href="armor/rustyshield.xml"/> + <xi:include href="armor/scale.xml"/> + <xi:include href="armor/shield.xml"/> + <xi:include href="armor/towershield.xml"/> +</resources> diff --git a/res/e3a/armor/chainmail.xml b/res/e3a/armor/chainmail.xml index 39743d754..4c3b6647f 100644 --- a/res/e3a/armor/chainmail.xml +++ b/res/e3a/armor/chainmail.xml @@ -1,9 +1,9 @@ -<?xml version="1.0"?> -<resource name="chainmail"> - <item weight="200" score="90"> - <construction skill="armorer" minskill="3" reqsize="1"> - <requirement type="iron" quantity="2"/> - </construction> - <armor ac="2" penalty="0.10" projectile="0.0" magres="0.0"/> - </item> -</resource> +<?xml version="1.0"?> +<resource name="chainmail"> + <item weight="200" score="90"> + <construction skill="armorer" minskill="3" reqsize="1"> + <requirement type="iron" quantity="2"/> + </construction> + <armor ac="2" penalty="0.10" projectile="0.0" magres="0.0"/> + </item> +</resource> diff --git a/res/e3a/armor/laenmail.xml b/res/e3a/armor/laenmail.xml index d3b1dd533..b8bc7343a 100644 --- a/res/e3a/armor/laenmail.xml +++ b/res/e3a/armor/laenmail.xml @@ -1,9 +1,9 @@ -<?xml version="1.0"?> -<resource name="laenmail"> - <item weight="100" score="1000"> - <construction skill="armorer" minskill="9" reqsize="1"> - <requirement type="laen" quantity="2"/> - </construction> - <armor ac="3" penalty="0.0" projectile="0.10" magres="0.3" laen="yes" /> - </item> -</resource> +<?xml version="1.0"?> +<resource name="laenmail"> + <item weight="100" score="1000"> + <construction skill="armorer" minskill="9" reqsize="1"> + <requirement type="laen" quantity="2"/> + </construction> + <armor ac="3" penalty="0.0" projectile="0.10" magres="0.3" laen="yes" /> + </item> +</resource> diff --git a/res/e3a/armor/laenshield.xml b/res/e3a/armor/laenshield.xml index 1ce6216b2..f9c808876 100644 --- a/res/e3a/armor/laenshield.xml +++ b/res/e3a/armor/laenshield.xml @@ -1,9 +1,9 @@ -<?xml version="1.0"?> -<resource name="laenshield"> - <item weight="0" score="1000"> - <construction skill="armorer" minskill="7" reqsize="1"> - <requirement type="laen" quantity="1"/> - </construction> - <armor ac="1" penalty="-0.10" magres="0.3" laen="yes" shield="yes" /> - </item> -</resource> +<?xml version="1.0"?> +<resource name="laenshield"> + <item weight="0" score="1000"> + <construction skill="armorer" minskill="7" reqsize="1"> + <requirement type="laen" quantity="1"/> + </construction> + <armor ac="1" penalty="-0.10" magres="0.3" laen="yes" shield="yes" /> + </item> +</resource> diff --git a/res/e3a/armor/plate.xml b/res/e3a/armor/plate.xml index 550e83173..a9aabfc04 100644 --- a/res/e3a/armor/plate.xml +++ b/res/e3a/armor/plate.xml @@ -1,10 +1,10 @@ -<?xml version="1.0"?> -<resource name="plate"> - <item weight="400" score="150"> - <function name="canuse" value="lua_canuse_item"/> - <construction skill="armorer" minskill="4" reqsize="1"> - <requirement type="iron" quantity="4"/> - </construction> - <armor ac="3" penalty="0.15" projectile="0.10" magres="0.0"/> - </item> -</resource> +<?xml version="1.0"?> +<resource name="plate"> + <item weight="400" score="150"> + <function name="canuse" value="lua_canuse_item"/> + <construction skill="armorer" minskill="4" reqsize="1"> + <requirement type="iron" quantity="4"/> + </construction> + <armor ac="3" penalty="0.15" projectile="0.10" magres="0.0"/> + </item> +</resource> diff --git a/res/e3a/armor/rustychainmail.xml b/res/e3a/armor/rustychainmail.xml index ac2628c62..56c314042 100644 --- a/res/e3a/armor/rustychainmail.xml +++ b/res/e3a/armor/rustychainmail.xml @@ -1,9 +1,9 @@ -<?xml version="1.0"?> -<resource name="rustychainmail"> - <item weight="200" score="30"> - <construction skill="armorer" minskill="3" reqsize="1"> - <requirement type="iron" quantity="3"/> - </construction> - <armor ac="1" penalty="0.20" magres="0.0"/> - </item> -</resource> +<?xml version="1.0"?> +<resource name="rustychainmail"> + <item weight="200" score="30"> + <construction skill="armorer" minskill="3" reqsize="1"> + <requirement type="iron" quantity="3"/> + </construction> + <armor ac="1" penalty="0.20" magres="0.0"/> + </item> +</resource> diff --git a/res/e3a/armor/rustyshield.xml b/res/e3a/armor/rustyshield.xml index 2becae180..53f9ea04a 100644 --- a/res/e3a/armor/rustyshield.xml +++ b/res/e3a/armor/rustyshield.xml @@ -1,9 +1,9 @@ -<?xml version="1.0"?> -<resource name="rustyshield"> - <item weight="100" score="10"> - <construction skill="armorer" minskill="2" reqsize="1"> - <requirement type="iron" quantity="1"/> - </construction> - <armor ac="0" penalty="-0.05" magres="0.0" shield="yes"/> - </item> -</resource> +<?xml version="1.0"?> +<resource name="rustyshield"> + <item weight="100" score="10"> + <construction skill="armorer" minskill="2" reqsize="1"> + <requirement type="iron" quantity="1"/> + </construction> + <armor ac="0" penalty="-0.05" magres="0.0" shield="yes"/> + </item> +</resource> diff --git a/res/e3a/armor/scale.xml b/res/e3a/armor/scale.xml index 809d08bca..0d01e4658 100644 --- a/res/e3a/armor/scale.xml +++ b/res/e3a/armor/scale.xml @@ -1,11 +1,11 @@ -<?xml version="1.0"?> -<resource name="scale"> - <item weight="300" score="150"> - <function name="canuse" value="lua_canuse_item"/> - <construction skill="armorer" minskill="5" reqsize="1"> - <modifier function="mod_dwarves_only"/> - <requirement type="iron" quantity="2"/> - </construction> - <armor ac="3" penalty="0.10" projectile="0.05" magres="0.0"/> - </item> -</resource> +<?xml version="1.0"?> +<resource name="scale"> + <item weight="300" score="150"> + <function name="canuse" value="lua_canuse_item"/> + <construction skill="armorer" minskill="5" reqsize="1"> + <modifier function="mod_dwarves_only"/> + <requirement type="iron" quantity="2"/> + </construction> + <armor ac="3" penalty="0.10" projectile="0.05" magres="0.0"/> + </item> +</resource> diff --git a/res/e3a/armor/shield.xml b/res/e3a/armor/shield.xml index 9b4ad9174..8e137026a 100644 --- a/res/e3a/armor/shield.xml +++ b/res/e3a/armor/shield.xml @@ -1,9 +1,9 @@ -<?xml version="1.0"?> -<resource name="shield"> - <item weight="100" score="30"> - <construction skill="armorer" minskill="2" reqsize="1"> - <requirement type="iron" quantity="1"/> - </construction> - <armor ac="0" penalty="-0.10" magres="0.0" shield="yes"/> - </item> -</resource> +<?xml version="1.0"?> +<resource name="shield"> + <item weight="100" score="30"> + <construction skill="armorer" minskill="2" reqsize="1"> + <requirement type="iron" quantity="1"/> + </construction> + <armor ac="0" penalty="-0.10" magres="0.0" shield="yes"/> + </item> +</resource> diff --git a/res/e3a/armor/towershield.xml b/res/e3a/armor/towershield.xml index 5a7edcabe..a0c0cce96 100644 --- a/res/e3a/armor/towershield.xml +++ b/res/e3a/armor/towershield.xml @@ -1,13 +1,13 @@ -<?xml version="1.0"?> -<resource name="towershield"> - <item weight="200" score="60"> - <function name="canuse" value="lua_canuse_item"/> - <construction skill="armorer" minskill="4" reqsize="1"> - <modifier function="mod_dwarves_only"/> - <requirement type="iron" quantity="1"/> - </construction> - <armor ac="0" penalty="-0.15" projectile="0.25" magres="0.0" shield="yes"> - <modifier type="canuse" function="mod_dwarves_only"/> - </armor> - </item> -</resource> +<?xml version="1.0"?> +<resource name="towershield"> + <item weight="200" score="60"> + <function name="canuse" value="lua_canuse_item"/> + <construction skill="armorer" minskill="4" reqsize="1"> + <modifier function="mod_dwarves_only"/> + <requirement type="iron" quantity="1"/> + </construction> + <armor ac="0" penalty="-0.15" projectile="0.25" magres="0.0" shield="yes"> + <modifier type="canuse" function="mod_dwarves_only"/> + </armor> + </item> +</resource> diff --git a/res/e3a/buildings.xml b/res/e3a/buildings.xml index f87987ac1..1521b1743 100644 --- a/res/e3a/buildings.xml +++ b/res/e3a/buildings.xml @@ -1,30 +1,30 @@ -<?xml version="1.0"?> -<buildings xmlns:xi="http://www.w3.org/2001/XInclude"> - - <xi:include href="../buildings/castle-2.xml" /> - - <building name="watch" capacity="1" maxsize="10"> - <function name="name" value="fort_name"/> - <function name="protection" value="lua_building_protection"/> - <function name="taxes" value="lua_building_taxes"/> - <construction skill="building" minskill="1" maxsize="5" reqsize="1"> - <requirement type="log" quantity="1"/> - </construction> - <construction skill="building" minskill="2" maxsize="5" reqsize="1"> - <requirement type="log" quantity="1"/> - </construction> - <construction skill="building" minskill="2" reqsize="1"> - <requirement type="log" quantity="1"/> - </construction> - </building> - - <building name="market" capacity="1" maxsize="10"> - <maintenance type="money" amount="200" vital="yes"/> - <construction skill="building" minskill="3" reqsize="1"> - <requirement type="log" quantity="1"/> - <requirement type="stone" quantity="1"/> - </construction> - </building> - -</buildings> - +<?xml version="1.0"?> +<buildings xmlns:xi="http://www.w3.org/2001/XInclude"> + + <xi:include href="../buildings/castle-2.xml" /> + + <building name="watch" capacity="1" maxsize="10"> + <function name="name" value="fort_name"/> + <function name="protection" value="lua_building_protection"/> + <function name="taxes" value="lua_building_taxes"/> + <construction skill="building" minskill="1" maxsize="5" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + <construction skill="building" minskill="2" maxsize="5" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + <construction skill="building" minskill="2" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + </building> + + <building name="market" capacity="1" maxsize="10"> + <maintenance type="money" amount="200" vital="yes"/> + <construction skill="building" minskill="3" reqsize="1"> + <requirement type="log" quantity="1"/> + <requirement type="stone" quantity="1"/> + </construction> + </building> + +</buildings> + diff --git a/res/e3a/equipment.xml b/res/e3a/equipment.xml index bbd2ac5b7..6e634eecf 100644 --- a/res/e3a/equipment.xml +++ b/res/e3a/equipment.xml @@ -1,78 +1,78 @@ -<?xml version="1.0"?> -<equipment> - - <!-- equipment given to new units --> - <set name="new_demon_unit"> - <!--skill name="stamina" level="6"/--> - </set> - - <set name="new_troll_unit"> - <!--skill name="stamina" level="2"/--> - </set> - - <set name="seaserpent_spoils"> - <item name="dragonblood" amount="2"/> - <item name="seaserpenthead" amount="1"/> - </set> - - <set name="goblin_1"> - <skill name="melee" level="7"/> - <skill name="stamina" level="3"/> - <item name="sword" amount="1"/> - <item name="shield" amount="1"/> - <item name="chainmail" amount="1"/> - </set> - - <set name="troll_1"> - <skill name="melee" level="7"/> - <skill name="stamina" level="3"/> - <item name="sword" amount="1"/> - <item name="shield" amount="1"/> - <item name="plate" amount="1"/> - </set> - - <set name="front_1"> - <skill name="melee" level="7"/> - <skill name="stamina" level="3"/> - <item name="sword" amount="1"/> - <item name="shield" amount="1"/> - <item name="plate" amount="1"/> - </set> - - <set name="front_2"> - <skill name="melee" level="7"/> - <skill name="stamina" level="3"/> - <item name="sword" amount="1"/> - <item name="towershield" amount="1"/> - <item name="plate" amount="1"/> - </set> - - <set name="rear_1"> - <skill name="crossbow" level="7"/> - <skill name="stamina" level="3"/> - <item name="crossbow" amount="1"/> - <item name="shield" amount="1"/> - </set> - - <set name="rear_2"> - <skill name="crossbow" level="7"/> - <skill name="stamina" level="3"/> - <item name="crossbow" amount="1"/> - <item name="shield" amount="1"/> - </set> - - <set name="dwarf_2"> - <skill name="melee" level="7"/> - <skill name="stamina" level="3"/> - <item name="sword" amount="1"/> - <item name="shield" amount="1"/> - <item name="plate" amount="1"/> - </set> - - <set name="halfling_2"> - <skill name="crossbow" level="7"/> - <skill name="stamina" level="3"/> - <item name="rep_crossbow" amount="1"/> - </set> - -</equipment> +<?xml version="1.0"?> +<equipment> + + <!-- equipment given to new units --> + <set name="new_demon_unit"> + <!--skill name="stamina" level="6"/--> + </set> + + <set name="new_troll_unit"> + <!--skill name="stamina" level="2"/--> + </set> + + <set name="seaserpent_spoils"> + <item name="dragonblood" amount="2"/> + <item name="seaserpenthead" amount="1"/> + </set> + + <set name="goblin_1"> + <skill name="melee" level="7"/> + <skill name="stamina" level="3"/> + <item name="sword" amount="1"/> + <item name="shield" amount="1"/> + <item name="chainmail" amount="1"/> + </set> + + <set name="troll_1"> + <skill name="melee" level="7"/> + <skill name="stamina" level="3"/> + <item name="sword" amount="1"/> + <item name="shield" amount="1"/> + <item name="plate" amount="1"/> + </set> + + <set name="front_1"> + <skill name="melee" level="7"/> + <skill name="stamina" level="3"/> + <item name="sword" amount="1"/> + <item name="shield" amount="1"/> + <item name="plate" amount="1"/> + </set> + + <set name="front_2"> + <skill name="melee" level="7"/> + <skill name="stamina" level="3"/> + <item name="sword" amount="1"/> + <item name="towershield" amount="1"/> + <item name="plate" amount="1"/> + </set> + + <set name="rear_1"> + <skill name="crossbow" level="7"/> + <skill name="stamina" level="3"/> + <item name="crossbow" amount="1"/> + <item name="shield" amount="1"/> + </set> + + <set name="rear_2"> + <skill name="crossbow" level="7"/> + <skill name="stamina" level="3"/> + <item name="crossbow" amount="1"/> + <item name="shield" amount="1"/> + </set> + + <set name="dwarf_2"> + <skill name="melee" level="7"/> + <skill name="stamina" level="3"/> + <item name="sword" amount="1"/> + <item name="shield" amount="1"/> + <item name="plate" amount="1"/> + </set> + + <set name="halfling_2"> + <skill name="crossbow" level="7"/> + <skill name="stamina" level="3"/> + <item name="rep_crossbow" amount="1"/> + </set> + +</equipment> diff --git a/res/e3a/items.xml b/res/e3a/items.xml index 706bd0d67..db0b4e562 100644 --- a/res/e3a/items.xml +++ b/res/e3a/items.xml @@ -1,89 +1,89 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<resources> - - <resource name="rpg_item_1"><item weight="10"/></resource> - <resource name="rpg_item_2"><item weight="1"/></resource> - <resource name="rpg_item_3"><item weight="100"/></resource> - - <resource name="ointment" appearance="vial"> - <!-- Wundsalbe --> - <item weight="0" score="60"> - <function name="use" value="usehealingpotion"/> - <potion level="2"/> - </item> - </resource> - - <resource name="p13" appearance="vial"> - <!-- Elixier der Macht --> - <item weight="0" score="120"> - <function name="use" value="usepotion"/> - <potion level="4"/> - </item> - </resource> - - <resource name="p3" appearance="vial"> - <!-- Schaffenstrunk --> - <item weight="0" score="60"> - <function name="use" value="usepotion"/> - <potion level="2"/> - </item> - </resource> - - <resource name="p14" appearance="vial"> - <!-- Heiltrank --> - <item weight="0" score="120"> - <function name="use" value="usepotion"/> - <potion level="4"/> - </item> - </resource> - - <resource name="p0" appearance="vial"> - <!-- Siebenmeilentee --> - <item weight="0" score="30"> - <function name="use" value="usepotion"/> - <potion level="1"/> - </item> - </resource> - - <resource name="p2" appearance="vial"> - <!-- Wasser des Lebens --> - <item weight="0" score="30"> - <function name="use" value="usepotion_delayed"/> - <potion level="1"/> - </item> - </resource> - - <resource name="peasantblood" appearance="vial"> - <!-- Bauernblut --> - <item weight="0" score="60"> - <function name="use" value="usebloodpotion"/> - <potion level="2"/> - </item> - </resource> - - <resource name="p9" appearance="vial"> - <!-- Pferdeglück --> - <item weight="0" score="90"> - <function name="use" value="usepotion"/> - <potion level="3"/> - </item> - </resource> - - <resource name="charger"> - <item big="yes" weight="5000" score="10" capacity="7000" animal="yes"> - <construction skill="training" minskill="4" reqsize="1"> - <requirement type="money" quantity="200"/> - <requirement type="iron" quantity="1"/> - <requirement type="horse" quantity="1"/> - </construction> - <function name="give" value="givehorses"/> - </item> - </resource> - - <resource name="xmastree"> - <item weight="0"> - <function name="use" value="lua_useitem"/> - </item> - </resource> - -</resources> +<?xml version="1.0" encoding="UTF-8" ?> +<resources> + + <resource name="rpg_item_1"><item weight="10"/></resource> + <resource name="rpg_item_2"><item weight="1"/></resource> + <resource name="rpg_item_3"><item weight="100"/></resource> + + <resource name="ointment" appearance="vial"> + <!-- Wundsalbe --> + <item weight="0" score="60"> + <function name="use" value="usehealingpotion"/> + <potion level="2"/> + </item> + </resource> + + <resource name="p13" appearance="vial"> + <!-- Elixier der Macht --> + <item weight="0" score="120"> + <function name="use" value="usepotion"/> + <potion level="4"/> + </item> + </resource> + + <resource name="p3" appearance="vial"> + <!-- Schaffenstrunk --> + <item weight="0" score="60"> + <function name="use" value="usepotion"/> + <potion level="2"/> + </item> + </resource> + + <resource name="p14" appearance="vial"> + <!-- Heiltrank --> + <item weight="0" score="120"> + <function name="use" value="usepotion"/> + <potion level="4"/> + </item> + </resource> + + <resource name="p0" appearance="vial"> + <!-- Siebenmeilentee --> + <item weight="0" score="30"> + <function name="use" value="usepotion"/> + <potion level="1"/> + </item> + </resource> + + <resource name="p2" appearance="vial"> + <!-- Wasser des Lebens --> + <item weight="0" score="30"> + <function name="use" value="usepotion_delayed"/> + <potion level="1"/> + </item> + </resource> + + <resource name="peasantblood" appearance="vial"> + <!-- Bauernblut --> + <item weight="0" score="60"> + <function name="use" value="usebloodpotion"/> + <potion level="2"/> + </item> + </resource> + + <resource name="p9" appearance="vial"> + <!-- Pferdeglück --> + <item weight="0" score="90"> + <function name="use" value="usepotion"/> + <potion level="3"/> + </item> + </resource> + + <resource name="charger"> + <item big="yes" weight="5000" score="10" capacity="7000" animal="yes"> + <construction skill="training" minskill="4" reqsize="1"> + <requirement type="money" quantity="200"/> + <requirement type="iron" quantity="1"/> + <requirement type="horse" quantity="1"/> + </construction> + <function name="give" value="givehorses"/> + </item> + </resource> + + <resource name="xmastree"> + <item weight="0"> + <function name="use" value="lua_useitem"/> + </item> + </resource> + +</resources> diff --git a/res/e3a/luxuries.xml b/res/e3a/luxuries.xml index 6c5094a19..4bb1e9879 100644 --- a/res/e3a/luxuries.xml +++ b/res/e3a/luxuries.xml @@ -1,23 +1,23 @@ -<?xml version="1.0"?> -<resources> - <!-- this file contains luxury items that are part of the trade system --> - <resource name="balm"> - <item weight="200"><luxury price="4"/></item> - </resource> - <resource name="jewel"> - <item weight="100"><luxury price="7"/></item> - </resource> - <resource name="myrrh"> - <item weight="200"><luxury price="5"/></item> - </resource> - <resource name="oil"> - <item weight="300"><luxury price="3"/></item> - </resource> - <resource name="silk"> - <item weight="300"><luxury price="6"/></item> - </resource> - <resource name="incense"> - <item weight="200"><luxury price="4"/></item> - </resource> - -</resources> +<?xml version="1.0"?> +<resources> + <!-- this file contains luxury items that are part of the trade system --> + <resource name="balm"> + <item weight="200"><luxury price="4"/></item> + </resource> + <resource name="jewel"> + <item weight="100"><luxury price="7"/></item> + </resource> + <resource name="myrrh"> + <item weight="200"><luxury price="5"/></item> + </resource> + <resource name="oil"> + <item weight="300"><luxury price="3"/></item> + </resource> + <resource name="silk"> + <item weight="300"><luxury price="6"/></item> + </resource> + <resource name="incense"> + <item weight="200"><luxury price="4"/></item> + </resource> + +</resources> diff --git a/res/e3a/messages.xml b/res/e3a/messages.xml index af781cfa5..b02313fe6 100644 --- a/res/e3a/messages.xml +++ b/res/e3a/messages.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<messages> - <message name="raindance_effect" section="magic"> - <type> - <arg name="mage" type="unit"/> - </type> - <text locale="de">"$if($isnull($mage),"Ein unentdeckter Magier",$unit($mage)) f�hrt einen sonderbaren Tanz auf. Kurz darauf beginnt es zu regnen."</text> - <text locale="en">"$if($isnull($mage),"an unseen magician",$unit($mage)) dances a strange dance. Shortly after, rain begins to fall on the fields."</text> - </message> -</messages> +<?xml version="1.0" encoding="ISO-8859-1"?> +<messages> + <message name="raindance_effect" section="magic"> + <type> + <arg name="mage" type="unit"/> + </type> + <text locale="de">"$if($isnull($mage),"Ein unentdeckter Magier",$unit($mage)) f�hrt einen sonderbaren Tanz auf. Kurz darauf beginnt es zu regnen."</text> + <text locale="en">"$if($isnull($mage),"an unseen magician",$unit($mage)) dances a strange dance. Shortly after, rain begins to fall on the fields."</text> + </message> +</messages> diff --git a/res/e3a/races.xml b/res/e3a/races.xml index 1bf6cccbc..50570cf3c 100644 --- a/res/e3a/races.xml +++ b/res/e3a/races.xml @@ -1,927 +1,927 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<races xmlns:xi="http://www.w3.org/2001/XInclude"> - - <!-- begin main races --> - - <xi:include href="../races/goblin-3.xml"/> - <xi:include href="../races/wyrm.xml"/> - <xi:include href="../races/dragon.xml"/> - <xi:include href="../races/youngdragon.xml"/> - - <race name="human" magres="0.000000" maxaura="1.0" regaura="1.0" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <param name="other_race" value="elf"/> - <param name="other_cost" value="500"/> - <skill name="riding" modifier="+1"/> - <skill name="shipcraft" modifier="2"/> - <skill name="sailing" modifier="2"/> - <skill name="magic" modifier="-99"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="dolphin" default="yes"/> - <familiar race="giantturtle"/> - </race> - - <race name="orc" studyspeed="-5" magres="-0.05" maxaura="1.0" regaura="1.0" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <param name="other_race" value="troll"/> - <param name="other_cost" value="500"/> - - <skill name="bow" speed="+5"/> - <skill name="building" modifier="1"/> - <skill name="cartmaking" modifier="-1"/> - <skill name="catapult" speed="+5"/> - <skill name="crossbow" speed="+5"/> - <skill name="forestry" modifier="1"/> - <skill name="melee" speed="+5"/> - <skill name="mining" modifier="1"/> - <skill name="polearm" speed="+5"/> - <skill name="quarrying" modifier="1"/> - <skill name="sailing" modifier="-1"/> - <skill name="stamina" speed="0"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="tactics" modifier="1"/> - <skill name="training" modifier="-1"/> - <skill name="magic" modifier="-99"/> - <skill name="unarmed" modifier="-99"/> - <skill name="weaponsmithing" modifier="2"/> - <attack type="1" damage="1d5"/> - <familiar race="wolf" default="yes"/> - <familiar race="ghost"/> - </race> - - <race name="halfling" defensemodifier="1" magres="0.05" maxaura="1.0" regaura="1.0" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <param name="other_race" value="dwarf"/> - <param name="other_cost" value="500"/> - <param name="luxury_trade" value="600"/> - <skill name="bow" modifier="-1"/> - <skill name="building" modifier="1"/> - <skill name="cartmaking" modifier="2"/> - <skill name="catapult" modifier="-1"/> - <skill name="crossbow" modifier="2"/> - <skill name="melee" modifier="-1"/> - <skill name="mining" modifier="1"/> - <skill name="polearm" modifier="-1"/> - <skill name="riding" modifier="-1"/> - <skill name="roadwork" modifier="1"/> - <skill name="sailing" modifier="-2"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="training" modifier="-1"/> - <skill name="magic" modifier="-99"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="eagle" default="yes"/> - <familiar race="imp"/> - </race> - - <!-- begin secondary races --> - - <race name="demon" magres="0.150000" maxaura="1.0" regaura="1.1" recruitcost="360" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="30" ac="2" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" shapeshift="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="cartmaking" modifier="-2"/> - <skill name="forestry" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="riding" modifier="-1"/> - <skill name="sailing" modifier="-1"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="tactics" modifier="-1"/> - <skill name="training" modifier="-3"/> - <skill name="unarmed" modifier="-99"/> - <skill name="weaponsmithing" modifier="1"/> - <attack type="1" damage="1d5"/> - <attack type="5"/> - <familiar race="imp" default="yes"/> - <familiar race="ghost"/> - </race> - - <race name="elf" magres="0.100000" maxaura="1.0" regaura="1.1" recruitcost="200" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <param name="regen.forest" value="2.0"/> - <skill name="armorer" modifier="-1"/> - <skill name="bow" modifier="2"/> - <skill name="building" modifier="-1"/> - <skill name="catapult" modifier="-2"/> - <skill name="mining" modifier="-2"/> - <skill name="quarrying" modifier="-1"/> - <skill name="roadwork" modifier="-1"/> - <skill name="sailing" modifier="-1"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="training" modifier="2"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="nymph" default="yes"/> - <familiar race="unicorn"/> - </race> - - <race name="troll" magres="0.100000" maxaura="1.0" regaura="1.0" recruitcost="260" maintenance="10" weight="2000" capacity="1080" speed="1.0" hp="20" ac="1" damage="1d5+3" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <param name="armor.stamina" value="4"/> <!-- +1 natural armor per X levels stamina --> - <skill name="armorer" modifier="2"/> - <skill name="bow" modifier="-2"/> - <skill name="building" modifier="2"/> - <skill name="catapult" modifier="2"/> - <skill name="melee" modifier="1"/> - <skill name="mining" modifier="1"/> - <skill name="quarrying" modifier="2"/> - <skill name="riding" modifier="-99"/> - <skill name="roadwork" modifier="2"/> - <skill name="sailing" modifier="-1"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="tactics" modifier="-1"/> - <skill name="training" modifier="-1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5+3"/> - <familiar race="tunnelworm" default="yes"/> - <familiar race="rat"/> - </race> - - <race name="dwarf" magres="0.05" maxaura="1.0" regaura="0.9" recruitcost="240" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="armorer" modifier="2"/> - <skill name="bow" modifier="-1"/> - <skill name="building" modifier="2"/> - <skill name="catapult" modifier="2"/> - <skill name="forestry" modifier="-1"/> - <skill name="melee" modifier="1"/> - <skill name="mining" modifier="2"/> - <skill name="quarrying" modifier="2"/> - <skill name="riding" modifier="-2"/> - <skill name="roadwork" modifier="2"/> - <skill name="sailing" modifier="-2"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="training" modifier="-2"/> - <skill name="weaponsmithing" modifier="2"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="lynx" default="yes"/> - <familiar race="songdragon"/> - </race> - - <!-- end player races --> - - <race name="kraken" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="2.000000" hp="300" damage="2d10" unarmedattack="0" unarmeddefense="0" attackmodifier="7" defensemodifier="7" coastal="yes" swim="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="2d10"/> - <attack type="4" damage="1d10"/> - <attack type="4" damage="1d10"/> - <attack type="4" damage="1d10"/> - <attack type="4" damage="1d10"/> - <attack type="4" damage="1d10"/> - </race> - <race name="giantturtle" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="1600" capacity="600" speed="1.0" hp="900" ac="7" damage="2d50" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="5" coastal="yes" swim="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="2d50"/> - </race> - <race name="dolphin" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="2.000000" hp="24" damage="1d6" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="5" coastal="yes" swim="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="1d6"/> - </race> - <race name="tiger" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="30" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="3" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="2d6"/> - <attack type="4" damage="1d6"/> - <attack type="4" damage="1d6"/> - </race> - <race name="hellcat" magres="0.500000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="40" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="4" walk="yes" teach="no" giveitem="yes" getitem="yes" resistpierce="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="2d6"/> - <attack type="4" damage="1d6"/> - <attack type="4" damage="1d6"/> - </race> - <race name="owl" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="9" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="2" defensemodifier="4" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="1d4"/> - </race> - <race name="fairy" magres="0.800000" maxaura="1.0" regaura="1.500000" weight="200" capacity="540" speed="1.0" hp="6" damage="1d3" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="14" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="magic" modifier="1"/> - <skill name="riding" modifier="-1"/> - <skill name="melee" modifier="-1"/> - <skill name="polearm" modifier="-1"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="1d3"/> - <attack type="4" damage="1d3"/> - <attack type="4" damage="1d3"/> - <attack type="4" damage="1d3"/> - </race> - <race name="dreamcat" magres="0.500000" maxaura="1.0" regaura="1.0" weight="500" capacity="540" speed="1.0" hp="10" damage="1d5" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="6" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" invinciblenonmagic="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="magic" modifier="1"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="1d5"/> - <attack type="4" damage="1d5"/> - </race> - <race name="imp" magres="0.500000" maxaura="1.0" regaura="1.0" weight="500" capacity="540" speed="1.0" hp="10" ac="1" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="4" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="magic" modifier="1"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-1"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="1d4"/> - <attack type="4" damage="1d4"/> - <attack type="1" damage="1d4"/> - <attack type="6" spell="fiery_dragonbreath"/> - </race> - <race name="ghost" magres="0.800000" maxaura="0.500000" regaura="0.100000" weight="500" capacity="540" speed="1.0" hp="30" ac="5" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="8" scarepeasants="yes" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes" invinciblenonmagic="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="magic" modifier="1"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-2"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="1d5"/> - <attack type="4" damage="1d5"/> - <attack type="1" damage="2d6"/> - <attack type="2" damage="2d30"/> - <attack type="3" damage="1d1"/> - </race> - <race name="wolf" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="25" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="3" scarepeasants="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="name" value="namegeneric"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="2d6"/> - <attack type="4" damage="1d4"/> - <attack type="4" damage="1d4"/> - </race> - <race name="unicorn" magres="0.900000" maxaura="1.500000" regaura="1.500000" weight="5000" capacity="2000" speed="2.000000" hp="40" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="4" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="9999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="magic" modifier="2"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="3d12"/> - <attack type="4" damage="2d4"/> - </race> - <race name="nymph" magres="0.900000" maxaura="1.0" regaura="1.500000" weight="1000" capacity="540" speed="1.0" hp="15" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> - <ai splitsize="9999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="2"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="magic" modifier="1"/> - <skill name="training" modifier="5"/> - <skill name="riding" modifier="5"/> - <skill name="armorer" modifier="-2"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="sailing" modifier="-2"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-2"/> - <skill name="weaponsmithing" modifier="-2"/> - <skill name="cartmaking" modifier="-2"/> - <skill name="stamina" modifier="-1"/> - <attack type="1" damage="1d4"/> - <attack type="2" damage="2d20"/> - </race> - <race name="songdragon" magres="0.990000" maxaura="1.0" regaura="1.0" weight="1000" capacity="600" speed="1.500000" hp="40" ac="1" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="9999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="magic" modifier="1"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="2d4"/> - <attack type="4" damage="2d4"/> - <attack type="4" damage="2d4"/> - <attack type="6" spell="fiery_dragonbreath"/> - </race> - - <race name="rat" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="100" capacity="540" speed="1.0" hp="10" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="9999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="1d4"/> - <attack type="4" damage="1d4"/> - </race> - <race name="eagle" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.500000" hp="15" damage="2d3" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="2" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="9999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="2d3"/> - </race> - <race name="tunnelworm" magres="0.800000" maxaura="0.000000" regaura="0.000000" weight="30000" capacity="10000" speed="1.0" hp="300" ac="6" damage="3d20" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="1" scarepeasants="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="99999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="10"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="10"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="10"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="stamina" modifier="2"/> - <attack type="4" damage="3d20"/> - <attack type="8" damage="1d10"/> - </race> - <race name="lynx" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="20" damage="2d3" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="5" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="99999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="training" modifier="1"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="2d3"/> - </race> - <race name="direwolf" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="20" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" walk="yes" teach="no" giveperson="yes"> - <function name="initfamiliar" value="oldfamiliars"/> - <ai splitsize="5000"/> - <attack type="4" damage="2d4"/> - </race> - <race name="peasant" magres="0.000000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d6" unarmedattack="0" unarmeddefense="0" cannotmove="yes" teach="no"> - <ai splitsize="10000"/> - <attack type="1" damage="1d6"/> - </race> - <race name="braineater" magres="0.900000" maxaura="1.0" regaura="1.0" weight="100" capacity="540" speed="1.0" hp="20" ac="1" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes"> - <ai splitsize="500" killpeasants="yes" moverandom="yes" learn="yes"/> - <function name="name" value="namegeneric"/> - <function name="describe" value="describe_braineater"/> - <attack type="2" damage="3d15"/> - <attack type="3" damage="1d1"/> - <attack type="4" damage="1d1"/> - </race> - <race name="toad" magres="0.200000" maxaura="1.0" regaura="1.0" maintenance="10" weight="100" capacity="540" speed="1.0" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes"> - <ai splitsize="1" learn="yes"/> - <skill name="crossbow" modifier="-10"/> - <skill name="mining" modifier="-10"/> - <skill name="bow" modifier="-10"/> - <skill name="building" modifier="-10"/> - <skill name="forestry" modifier="-10"/> - <skill name="catapult" modifier="-10"/> - <skill name="magic" modifier="-10"/> - <skill name="training" modifier="-10"/> - <skill name="riding" modifier="-10"/> - <skill name="armorer" modifier="-10"/> - <skill name="shipcraft" modifier="-10"/> - <skill name="melee" modifier="-10"/> - <skill name="sailing" modifier="-10"/> - <skill name="polearm" modifier="-10"/> - <skill name="quarrying" modifier="-10"/> - <skill name="roadwork" modifier="-10"/> - <skill name="tactics" modifier="-10"/> - <skill name="weaponsmithing" modifier="-10"/> - <skill name="cartmaking" modifier="-10"/> - <skill name="stamina" modifier="-10"/> - <attack type="4" damage="1d2"/> - </race> - <race name="smurf" weight="1000" capacity="540" speed="1.0" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes"> - <ai splitsize="1" learn="yes"/> - <skill name="crossbow" modifier="-10"/> - <skill name="mining" modifier="-10"/> - <skill name="bow" modifier="-10"/> - <skill name="building" modifier="-10"/> - <skill name="forestry" modifier="-10"/> - <skill name="catapult" modifier="-10"/> - <skill name="magic" modifier="-10"/> - <skill name="training" modifier="-10"/> - <skill name="riding" modifier="-10"/> - <skill name="armorer" modifier="-10"/> - <skill name="shipcraft" modifier="-10"/> - <skill name="melee" modifier="-10"/> - <skill name="sailing" modifier="-10"/> - <skill name="polearm" modifier="-10"/> - <skill name="quarrying" modifier="-10"/> - <skill name="roadwork" modifier="-10"/> - <skill name="tactics" modifier="-10"/> - <skill name="weaponsmithing" modifier="-10"/> - <skill name="cartmaking" modifier="-10"/> - <skill name="stamina" modifier="-10"/> - <attack type="4" damage="1d2"/> - </race> - <race name="alp" magres="0.950000" maxaura="1.0" regaura="1.0" weight="0" capacity="0" speed="1.500000" hp="20" ac="2" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="2" defensemodifier="20" fly="yes" walk="yes" canlearn="no" canteach="no"> - <ai splitsize="1"/> - <function name="name" value="namegeneric"/> - <attack type="1" damage="1d4"/> - </race> - <race name="mountainguard" unarmedguard="yes" magres="0.500000" maxaura="1.0" regaura="0.500000" weight="10000" capacity="2000" speed="0.000000" hp="1000" ac="12" damage="2d40" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="8" cannotmove="yes" canlearn="no" teach="no" noweapons="yes" giveitem="yes"> - <ai splitsize="1"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="2d40"/> - </race> - <race name="shadowmaster" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.0" regaura="2.000000" weight="500" capacity="540" speed="1.0" hp="150" ac="4" damage="2d5" unarmedattack="0" unarmeddefense="0" attackmodifier="11" defensemodifier="13" scarepeasants="yes" walk="yes" teach="no" desert="yes"> - <ai splitsize="50" killpeasants="yes" moverandom="yes" learn="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="2d4"/> - <attack type="2" damage="2d30"/> - <attack type="3" damage="1d2"/> - </race> - <race name="shadowdemon" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.0" regaura="1.0" weight="500" capacity="540" speed="1.0" hp="50" ac="3" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="8" defensemodifier="11" scarepeasants="yes" walk="yes" teach="no" desert="yes" recruitethereal="yes"> - <ai splitsize="1000" killpeasants="yes" moverandom="yes" learn="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="2d3"/> - <attack type="3" damage="1d1"/> - </race> - <race name="stonegolem" stonegolem="true" magres="0.250000" maxaura="1.0" regaura="0.100000" weight="10000" capacity="2000" speed="1.0" hp="60" ac="4" damage="2d12+6" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="2" walk="yes" canlearn="no" teach="no" giveitem="yes"> - <ai splitsize="50"/> - <skill name="building" modifier="14"/> - <skill name="roadwork" modifier="14"/> - <attack type="4" damage="2d10+4"/> - </race> - <race name="irongolem" irongolem="true" magres="0.250000" maxaura="1.0" regaura="0.100000" weight="10000" capacity="2000" speed="1.0" hp="50" ac="2" damage="2d10+4" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="2" walk="yes" canlearn="no" teach="no" giveitem="yes"> - <ai splitsize="50"/> - <function name="name" value="namegeneric"/> - <skill name="armorer" modifier="14"/> - <skill name="weaponsmithing" modifier="14"/> - <attack type="4" damage="2d8+4"/> - </race> - <race name="spell" magres="0.000000" maxaura="1.0" regaura="0.100000" weight="0" capacity="0" speed="0.000000" hp="1" damage="1d4" unarmedattack="-2" unarmeddefense="-2" canlearn="no" noheal="yes" noweapons="yes" illusionary="yes" invisible="yes" fly="yes" swim="yes" walk="yes"> - <ai splitsize="1"/> - <attack type="1" damage="1d4"/> - </race> - <race name="special" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="0" capacity="0" speed="0.000000" hp="1" damage="1d4" unarmedattack="-2" unarmeddefense="-2"> - <ai splitsize="1"/> - <attack type="1" damage="1d4"/> - </race> - - <race name="dracoid" magres="0.000000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" walk="yes" teach="no" giveitem="yes" giveperson="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="name" value="namedracoid"/> - <attack type="4" damage="1d6"/> - <attack type="4" damage="1d6"/> - <attack type="1" damage="1d5"/> - </race> - - <race name="ent" magres="0.250000" maxaura="1.0" regaura="0.500000" weight="5000" capacity="2500" speed="1.0" hp="50" ac="4" damage="2d4+12" unarmedattack="0" unarmeddefense="0" attackmodifier="9" defensemodifier="7" scarepeasants="yes" walk="yes" teach="no"> - <ai splitsize="1000" moverandom="yes" learn="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="2d12"/> - <attack type="4" damage="2d12"/> - </race> - - <race name="illusion" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="0" capacity="0" speed="1.0" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" walk="yes" canlearn="no" teach="no" noweapons="yes" illusionary="yes"> - <ai splitsize="999999"/> - <function name="age" value="ageillusion"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d1"/> - </race> - - <race name="undead" magres="0.000000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d7" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes"> - <ai splitsize="20000" moverandom="yes"/> - <function name="name" value="nameundead"/> - <function name="age" value="ageundead"/> - <attack type="4" damage="1d7"/> - <attack type="5"/> - </race> - - <race name="clone" magres="0.900000" maxaura="0.000000" regaura="0.000000" weight="1000" capacity="540" speed="1.0" hp="40" damage="0d0" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" canlearn="no" teach="no" noheal="yes"> - <ai splitsize="10000"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="magic" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="stamina" modifier="-99"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="0d0"/> - </race> - - <race name="ghast" magres="0.600000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="60" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes"> - <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> - <function name="name" value="nameghoul"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="4" damage="2d8"/> - <attack type="3" damage="1d5"/> - <attack type="3" damage="1d5"/> - <attack type="2" damage="1d30"/> - <attack type="2" damage="1d30"/> - </race> - - <race name="ghoul" magres="0.300000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="30" ac="1" damage="1d7" unarmedattack="3" unarmeddefense="3" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes"> - <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> - <function name="name" value="nameghoul"/> - <function name="age" value="ageghoul"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="4" damage="2d6"/> - <attack type="3" damage="1d2"/> - <attack type="3" damage="1d2"/> - <attack type="2" damage="1d30"/> - </race> - - <race name="juju-zombie" magres="0.500000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="80" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistbash="yes" resistcut="yes" resistpierce="yes"> - <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> - <function name="name" value="namezombie"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="1" damage="1d7"/> - <attack type="3" damage="1d1"/> - <attack type="3" damage="1d1"/> - </race> - - <race name="zombie" magres="0.200000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="40" ac="1" damage="1d7" unarmedattack="2" unarmeddefense="2" attackmodifier="5" defensemodifier="5" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> - <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> - <function name="name" value="namezombie"/> - <function name="age" value="agezombie"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="1" damage="1d7"/> - </race> - - <race name="skeletonlord" magres="0.300000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="60" ac="4" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> - <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> - <function name="name" value="nameskeleton"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="1" damage="1d7"/> - <attack type="1" damage="1d7"/> - </race> - - <race name="skeleton" magres="0.100000" maxaura="1.0" regaura="1.0" weight="500" capacity="540" speed="1.0" hp="20" ac="1" damage="1d7" unarmedattack="1" unarmeddefense="1" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> - <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> - <function name="name" value="nameskeleton"/> - <function name="age" value="ageskeleton"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="1" damage="1d7"/> - </race> - - <race name="shadowknight" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="1000" capacity="540" speed="1.0" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noblock="yes"> - <ai splitsize="20000" moverandom="yes"/> - <function name="name" value="namegeneric"/> - <attack type="1" damage="1d1"/> - </race> - - <race name="seaserpent" magres="0.500000" maxaura="1.0" regaura="1.0" weight="20000" capacity="5000" speed="1.0" hp="600" ac="3" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" scarepeasants="yes" swim="yes" teach="no" getitem="yes" resistbash="yes"> - <ai splitsize="6" killpeasants="yes" moverandom="yes" learn="yes"/> - <function name="name" value="namegeneric"/> - <function name="move" value="moveswimming"/> - <skill name="tactics" modifier="4"/> - <attack type="4" damage="1d30"/> - <attack type="4" damage="1d30"/> - <attack type="4" damage="1d30"/> - <attack type="6" spell="fiery_dragonbreath"/> - <attack type="8" damage="1d10"/> - </race> - - <!-- for the shadowcall spell --> - <race name="shadowbat" magres="0.800000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="500" capacity="540" speed="1.0" hp="1" ac="4" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes"> - <ai splitsize="5000" killpeasants="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="1d6"/> - <attack type="3" damage="1d1"/> - </race> - - <!-- for the shadowcall spell --> - <race name="nightmare" magres="0.500000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="100" capacity="540" speed="1.0" hp="80" ac="10" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" invinciblenonmagic="yes"> - <ai splitsize="500" killpeasants="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="1d4"/> - <attack type="4" damage="1d4"/> - <attack type="4" damage="1d4"/> - <attack type="3" damage="1d4"/> - <attack type="2" damage="1d10"/> - </race> - - <!-- for the shadowcall spell --> - <race name="vampunicorn" magres="1.0" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="5000" capacity="2000" speed="1.0" hp="30" ac="4" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" teach="no" getitem="yes"> - <ai splitsize="5000" killpeasants="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="2d10"/> - <attack type="3" damage="1d4"/> - <attack type="3" damage="1d4"/> - <attack type="3" damage="1d4"/> - <attack type="3" damage="1d4"/> - <attack type="2" damage="2d60"/> - </race> - -</races> +<?xml version="1.0" encoding="iso-8859-1" ?> +<races xmlns:xi="http://www.w3.org/2001/XInclude"> + + <!-- begin main races --> + + <xi:include href="../races/goblin-3.xml"/> + <xi:include href="../races/wyrm.xml"/> + <xi:include href="../races/dragon.xml"/> + <xi:include href="../races/youngdragon.xml"/> + + <race name="human" magres="0.000000" maxaura="1.0" regaura="1.0" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <param name="other_race" value="elf"/> + <param name="other_cost" value="500"/> + <skill name="riding" modifier="+1"/> + <skill name="shipcraft" modifier="2"/> + <skill name="sailing" modifier="2"/> + <skill name="magic" modifier="-99"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="dolphin" default="yes"/> + <familiar race="giantturtle"/> + </race> + + <race name="orc" studyspeed="-5" magres="-0.05" maxaura="1.0" regaura="1.0" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <param name="other_race" value="troll"/> + <param name="other_cost" value="500"/> + + <skill name="bow" speed="+5"/> + <skill name="building" modifier="1"/> + <skill name="cartmaking" modifier="-1"/> + <skill name="catapult" speed="+5"/> + <skill name="crossbow" speed="+5"/> + <skill name="forestry" modifier="1"/> + <skill name="melee" speed="+5"/> + <skill name="mining" modifier="1"/> + <skill name="polearm" speed="+5"/> + <skill name="quarrying" modifier="1"/> + <skill name="sailing" modifier="-1"/> + <skill name="stamina" speed="0"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="tactics" modifier="1"/> + <skill name="training" modifier="-1"/> + <skill name="magic" modifier="-99"/> + <skill name="unarmed" modifier="-99"/> + <skill name="weaponsmithing" modifier="2"/> + <attack type="1" damage="1d5"/> + <familiar race="wolf" default="yes"/> + <familiar race="ghost"/> + </race> + + <race name="halfling" defensemodifier="1" magres="0.05" maxaura="1.0" regaura="1.0" recruitcost="100" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <param name="other_race" value="dwarf"/> + <param name="other_cost" value="500"/> + <param name="luxury_trade" value="600"/> + <skill name="bow" modifier="-1"/> + <skill name="building" modifier="1"/> + <skill name="cartmaking" modifier="2"/> + <skill name="catapult" modifier="-1"/> + <skill name="crossbow" modifier="2"/> + <skill name="melee" modifier="-1"/> + <skill name="mining" modifier="1"/> + <skill name="polearm" modifier="-1"/> + <skill name="riding" modifier="-1"/> + <skill name="roadwork" modifier="1"/> + <skill name="sailing" modifier="-2"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="training" modifier="-1"/> + <skill name="magic" modifier="-99"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="eagle" default="yes"/> + <familiar race="imp"/> + </race> + + <!-- begin secondary races --> + + <race name="demon" magres="0.150000" maxaura="1.0" regaura="1.1" recruitcost="360" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="30" ac="2" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" shapeshift="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="cartmaking" modifier="-2"/> + <skill name="forestry" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="riding" modifier="-1"/> + <skill name="sailing" modifier="-1"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="tactics" modifier="-1"/> + <skill name="training" modifier="-3"/> + <skill name="unarmed" modifier="-99"/> + <skill name="weaponsmithing" modifier="1"/> + <attack type="1" damage="1d5"/> + <attack type="5"/> + <familiar race="imp" default="yes"/> + <familiar race="ghost"/> + </race> + + <race name="elf" magres="0.100000" maxaura="1.0" regaura="1.1" recruitcost="200" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <param name="regen.forest" value="2.0"/> + <skill name="armorer" modifier="-1"/> + <skill name="bow" modifier="2"/> + <skill name="building" modifier="-1"/> + <skill name="catapult" modifier="-2"/> + <skill name="mining" modifier="-2"/> + <skill name="quarrying" modifier="-1"/> + <skill name="roadwork" modifier="-1"/> + <skill name="sailing" modifier="-1"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="training" modifier="2"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="nymph" default="yes"/> + <familiar race="unicorn"/> + </race> + + <race name="troll" magres="0.100000" maxaura="1.0" regaura="1.0" recruitcost="260" maintenance="10" weight="2000" capacity="1080" speed="1.0" hp="20" ac="1" damage="1d5+3" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <param name="armor.stamina" value="4"/> <!-- +1 natural armor per X levels stamina --> + <skill name="armorer" modifier="2"/> + <skill name="bow" modifier="-2"/> + <skill name="building" modifier="2"/> + <skill name="catapult" modifier="2"/> + <skill name="melee" modifier="1"/> + <skill name="mining" modifier="1"/> + <skill name="quarrying" modifier="2"/> + <skill name="riding" modifier="-99"/> + <skill name="roadwork" modifier="2"/> + <skill name="sailing" modifier="-1"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="tactics" modifier="-1"/> + <skill name="training" modifier="-1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5+3"/> + <familiar race="tunnelworm" default="yes"/> + <familiar race="rat"/> + </race> + + <race name="dwarf" magres="0.05" maxaura="1.0" regaura="0.9" recruitcost="240" maintenance="10" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="armorer" modifier="2"/> + <skill name="bow" modifier="-1"/> + <skill name="building" modifier="2"/> + <skill name="catapult" modifier="2"/> + <skill name="forestry" modifier="-1"/> + <skill name="melee" modifier="1"/> + <skill name="mining" modifier="2"/> + <skill name="quarrying" modifier="2"/> + <skill name="riding" modifier="-2"/> + <skill name="roadwork" modifier="2"/> + <skill name="sailing" modifier="-2"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="training" modifier="-2"/> + <skill name="weaponsmithing" modifier="2"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="lynx" default="yes"/> + <familiar race="songdragon"/> + </race> + + <!-- end player races --> + + <race name="kraken" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="2.000000" hp="300" damage="2d10" unarmedattack="0" unarmeddefense="0" attackmodifier="7" defensemodifier="7" coastal="yes" swim="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="2d10"/> + <attack type="4" damage="1d10"/> + <attack type="4" damage="1d10"/> + <attack type="4" damage="1d10"/> + <attack type="4" damage="1d10"/> + <attack type="4" damage="1d10"/> + </race> + <race name="giantturtle" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="1600" capacity="600" speed="1.0" hp="900" ac="7" damage="2d50" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="5" coastal="yes" swim="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="2d50"/> + </race> + <race name="dolphin" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="2.000000" hp="24" damage="1d6" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="5" coastal="yes" swim="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="1d6"/> + </race> + <race name="tiger" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="30" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="3" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="2d6"/> + <attack type="4" damage="1d6"/> + <attack type="4" damage="1d6"/> + </race> + <race name="hellcat" magres="0.500000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="40" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="4" walk="yes" teach="no" giveitem="yes" getitem="yes" resistpierce="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="2d6"/> + <attack type="4" damage="1d6"/> + <attack type="4" damage="1d6"/> + </race> + <race name="owl" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="9" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="2" defensemodifier="4" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="1d4"/> + </race> + <race name="fairy" magres="0.800000" maxaura="1.0" regaura="1.500000" weight="200" capacity="540" speed="1.0" hp="6" damage="1d3" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="14" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="magic" modifier="1"/> + <skill name="riding" modifier="-1"/> + <skill name="melee" modifier="-1"/> + <skill name="polearm" modifier="-1"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="1d3"/> + <attack type="4" damage="1d3"/> + <attack type="4" damage="1d3"/> + <attack type="4" damage="1d3"/> + </race> + <race name="dreamcat" magres="0.500000" maxaura="1.0" regaura="1.0" weight="500" capacity="540" speed="1.0" hp="10" damage="1d5" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="6" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" invinciblenonmagic="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="magic" modifier="1"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="1d5"/> + <attack type="4" damage="1d5"/> + </race> + <race name="imp" magres="0.500000" maxaura="1.0" regaura="1.0" weight="500" capacity="540" speed="1.0" hp="10" ac="1" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="4" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="magic" modifier="1"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-1"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="1d4"/> + <attack type="4" damage="1d4"/> + <attack type="1" damage="1d4"/> + <attack type="6" spell="fiery_dragonbreath"/> + </race> + <race name="ghost" magres="0.800000" maxaura="0.500000" regaura="0.100000" weight="500" capacity="540" speed="1.0" hp="30" ac="5" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="8" scarepeasants="yes" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes" invinciblenonmagic="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="magic" modifier="1"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-2"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="1d5"/> + <attack type="4" damage="1d5"/> + <attack type="1" damage="2d6"/> + <attack type="2" damage="2d30"/> + <attack type="3" damage="1d1"/> + </race> + <race name="wolf" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="25" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="3" scarepeasants="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="name" value="namegeneric"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="2d6"/> + <attack type="4" damage="1d4"/> + <attack type="4" damage="1d4"/> + </race> + <race name="unicorn" magres="0.900000" maxaura="1.500000" regaura="1.500000" weight="5000" capacity="2000" speed="2.000000" hp="40" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="4" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="9999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="magic" modifier="2"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="3d12"/> + <attack type="4" damage="2d4"/> + </race> + <race name="nymph" magres="0.900000" maxaura="1.0" regaura="1.500000" weight="1000" capacity="540" speed="1.0" hp="15" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> + <ai splitsize="9999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="2"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="magic" modifier="1"/> + <skill name="training" modifier="5"/> + <skill name="riding" modifier="5"/> + <skill name="armorer" modifier="-2"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="sailing" modifier="-2"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-2"/> + <skill name="weaponsmithing" modifier="-2"/> + <skill name="cartmaking" modifier="-2"/> + <skill name="stamina" modifier="-1"/> + <attack type="1" damage="1d4"/> + <attack type="2" damage="2d20"/> + </race> + <race name="songdragon" magres="0.990000" maxaura="1.0" regaura="1.0" weight="1000" capacity="600" speed="1.500000" hp="40" ac="1" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="9999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="magic" modifier="1"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="2d4"/> + <attack type="4" damage="2d4"/> + <attack type="4" damage="2d4"/> + <attack type="6" spell="fiery_dragonbreath"/> + </race> + + <race name="rat" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="100" capacity="540" speed="1.0" hp="10" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="9999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="1d4"/> + <attack type="4" damage="1d4"/> + </race> + <race name="eagle" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.500000" hp="15" damage="2d3" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="2" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="9999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="2d3"/> + </race> + <race name="tunnelworm" magres="0.800000" maxaura="0.000000" regaura="0.000000" weight="30000" capacity="10000" speed="1.0" hp="300" ac="6" damage="3d20" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="1" scarepeasants="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="99999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="10"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="10"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="10"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="stamina" modifier="2"/> + <attack type="4" damage="3d20"/> + <attack type="8" damage="1d10"/> + </race> + <race name="lynx" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="20" damage="2d3" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="5" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="99999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="training" modifier="1"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="2d3"/> + </race> + <race name="direwolf" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="500" capacity="540" speed="1.0" hp="20" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" walk="yes" teach="no" giveperson="yes"> + <function name="initfamiliar" value="oldfamiliars"/> + <ai splitsize="5000"/> + <attack type="4" damage="2d4"/> + </race> + <race name="peasant" magres="0.000000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d6" unarmedattack="0" unarmeddefense="0" cannotmove="yes" teach="no"> + <ai splitsize="10000"/> + <attack type="1" damage="1d6"/> + </race> + <race name="braineater" magres="0.900000" maxaura="1.0" regaura="1.0" weight="100" capacity="540" speed="1.0" hp="20" ac="1" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes"> + <ai splitsize="500" killpeasants="yes" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> + <function name="describe" value="describe_braineater"/> + <attack type="2" damage="3d15"/> + <attack type="3" damage="1d1"/> + <attack type="4" damage="1d1"/> + </race> + <race name="toad" magres="0.200000" maxaura="1.0" regaura="1.0" maintenance="10" weight="100" capacity="540" speed="1.0" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes"> + <ai splitsize="1" learn="yes"/> + <skill name="crossbow" modifier="-10"/> + <skill name="mining" modifier="-10"/> + <skill name="bow" modifier="-10"/> + <skill name="building" modifier="-10"/> + <skill name="forestry" modifier="-10"/> + <skill name="catapult" modifier="-10"/> + <skill name="magic" modifier="-10"/> + <skill name="training" modifier="-10"/> + <skill name="riding" modifier="-10"/> + <skill name="armorer" modifier="-10"/> + <skill name="shipcraft" modifier="-10"/> + <skill name="melee" modifier="-10"/> + <skill name="sailing" modifier="-10"/> + <skill name="polearm" modifier="-10"/> + <skill name="quarrying" modifier="-10"/> + <skill name="roadwork" modifier="-10"/> + <skill name="tactics" modifier="-10"/> + <skill name="weaponsmithing" modifier="-10"/> + <skill name="cartmaking" modifier="-10"/> + <skill name="stamina" modifier="-10"/> + <attack type="4" damage="1d2"/> + </race> + <race name="smurf" weight="1000" capacity="540" speed="1.0" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes"> + <ai splitsize="1" learn="yes"/> + <skill name="crossbow" modifier="-10"/> + <skill name="mining" modifier="-10"/> + <skill name="bow" modifier="-10"/> + <skill name="building" modifier="-10"/> + <skill name="forestry" modifier="-10"/> + <skill name="catapult" modifier="-10"/> + <skill name="magic" modifier="-10"/> + <skill name="training" modifier="-10"/> + <skill name="riding" modifier="-10"/> + <skill name="armorer" modifier="-10"/> + <skill name="shipcraft" modifier="-10"/> + <skill name="melee" modifier="-10"/> + <skill name="sailing" modifier="-10"/> + <skill name="polearm" modifier="-10"/> + <skill name="quarrying" modifier="-10"/> + <skill name="roadwork" modifier="-10"/> + <skill name="tactics" modifier="-10"/> + <skill name="weaponsmithing" modifier="-10"/> + <skill name="cartmaking" modifier="-10"/> + <skill name="stamina" modifier="-10"/> + <attack type="4" damage="1d2"/> + </race> + <race name="alp" magres="0.950000" maxaura="1.0" regaura="1.0" weight="0" capacity="0" speed="1.500000" hp="20" ac="2" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="2" defensemodifier="20" fly="yes" walk="yes" canlearn="no" canteach="no"> + <ai splitsize="1"/> + <function name="name" value="namegeneric"/> + <attack type="1" damage="1d4"/> + </race> + <race name="mountainguard" unarmedguard="yes" magres="0.500000" maxaura="1.0" regaura="0.500000" weight="10000" capacity="2000" speed="0.000000" hp="1000" ac="12" damage="2d40" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="8" cannotmove="yes" canlearn="no" teach="no" noweapons="yes" giveitem="yes"> + <ai splitsize="1"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="2d40"/> + </race> + <race name="shadowmaster" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.0" regaura="2.000000" weight="500" capacity="540" speed="1.0" hp="150" ac="4" damage="2d5" unarmedattack="0" unarmeddefense="0" attackmodifier="11" defensemodifier="13" scarepeasants="yes" walk="yes" teach="no" desert="yes"> + <ai splitsize="50" killpeasants="yes" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="2d4"/> + <attack type="2" damage="2d30"/> + <attack type="3" damage="1d2"/> + </race> + <race name="shadowdemon" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.0" regaura="1.0" weight="500" capacity="540" speed="1.0" hp="50" ac="3" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="8" defensemodifier="11" scarepeasants="yes" walk="yes" teach="no" desert="yes" recruitethereal="yes"> + <ai splitsize="1000" killpeasants="yes" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="2d3"/> + <attack type="3" damage="1d1"/> + </race> + <race name="stonegolem" stonegolem="true" magres="0.250000" maxaura="1.0" regaura="0.100000" weight="10000" capacity="2000" speed="1.0" hp="60" ac="4" damage="2d12+6" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="2" walk="yes" canlearn="no" teach="no" giveitem="yes"> + <ai splitsize="50"/> + <skill name="building" modifier="14"/> + <skill name="roadwork" modifier="14"/> + <attack type="4" damage="2d10+4"/> + </race> + <race name="irongolem" irongolem="true" magres="0.250000" maxaura="1.0" regaura="0.100000" weight="10000" capacity="2000" speed="1.0" hp="50" ac="2" damage="2d10+4" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="2" walk="yes" canlearn="no" teach="no" giveitem="yes"> + <ai splitsize="50"/> + <function name="name" value="namegeneric"/> + <skill name="armorer" modifier="14"/> + <skill name="weaponsmithing" modifier="14"/> + <attack type="4" damage="2d8+4"/> + </race> + <race name="spell" magres="0.000000" maxaura="1.0" regaura="0.100000" weight="0" capacity="0" speed="0.000000" hp="1" damage="1d4" unarmedattack="-2" unarmeddefense="-2" canlearn="no" noheal="yes" noweapons="yes" illusionary="yes" invisible="yes" fly="yes" swim="yes" walk="yes"> + <ai splitsize="1"/> + <attack type="1" damage="1d4"/> + </race> + <race name="special" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="0" capacity="0" speed="0.000000" hp="1" damage="1d4" unarmedattack="-2" unarmeddefense="-2"> + <ai splitsize="1"/> + <attack type="1" damage="1d4"/> + </race> + + <race name="dracoid" magres="0.000000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" walk="yes" teach="no" giveitem="yes" giveperson="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="name" value="namedracoid"/> + <attack type="4" damage="1d6"/> + <attack type="4" damage="1d6"/> + <attack type="1" damage="1d5"/> + </race> + + <race name="ent" magres="0.250000" maxaura="1.0" regaura="0.500000" weight="5000" capacity="2500" speed="1.0" hp="50" ac="4" damage="2d4+12" unarmedattack="0" unarmeddefense="0" attackmodifier="9" defensemodifier="7" scarepeasants="yes" walk="yes" teach="no"> + <ai splitsize="1000" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="2d12"/> + <attack type="4" damage="2d12"/> + </race> + + <race name="illusion" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="0" capacity="0" speed="1.0" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" walk="yes" canlearn="no" teach="no" noweapons="yes" illusionary="yes"> + <ai splitsize="999999"/> + <function name="age" value="ageillusion"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d1"/> + </race> + + <race name="undead" magres="0.000000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="20" damage="1d7" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes"> + <ai splitsize="20000" moverandom="yes"/> + <function name="name" value="nameundead"/> + <function name="age" value="ageundead"/> + <attack type="4" damage="1d7"/> + <attack type="5"/> + </race> + + <race name="clone" magres="0.900000" maxaura="0.000000" regaura="0.000000" weight="1000" capacity="540" speed="1.0" hp="40" damage="0d0" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" canlearn="no" teach="no" noheal="yes"> + <ai splitsize="10000"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="magic" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="stamina" modifier="-99"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="0d0"/> + </race> + + <race name="ghast" magres="0.600000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="60" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes"> + <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> + <function name="name" value="nameghoul"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="4" damage="2d8"/> + <attack type="3" damage="1d5"/> + <attack type="3" damage="1d5"/> + <attack type="2" damage="1d30"/> + <attack type="2" damage="1d30"/> + </race> + + <race name="ghoul" magres="0.300000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="30" ac="1" damage="1d7" unarmedattack="3" unarmeddefense="3" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes"> + <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> + <function name="name" value="nameghoul"/> + <function name="age" value="ageghoul"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="4" damage="2d6"/> + <attack type="3" damage="1d2"/> + <attack type="3" damage="1d2"/> + <attack type="2" damage="1d30"/> + </race> + + <race name="juju-zombie" magres="0.500000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="80" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistbash="yes" resistcut="yes" resistpierce="yes"> + <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> + <function name="name" value="namezombie"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="1" damage="1d7"/> + <attack type="3" damage="1d1"/> + <attack type="3" damage="1d1"/> + </race> + + <race name="zombie" magres="0.200000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="40" ac="1" damage="1d7" unarmedattack="2" unarmeddefense="2" attackmodifier="5" defensemodifier="5" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> + <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> + <function name="name" value="namezombie"/> + <function name="age" value="agezombie"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="1" damage="1d7"/> + </race> + + <race name="skeletonlord" magres="0.300000" maxaura="1.0" regaura="1.0" weight="1000" capacity="540" speed="1.0" hp="60" ac="4" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> + <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> + <function name="name" value="nameskeleton"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="1" damage="1d7"/> + <attack type="1" damage="1d7"/> + </race> + + <race name="skeleton" magres="0.100000" maxaura="1.0" regaura="1.0" weight="500" capacity="540" speed="1.0" hp="20" ac="1" damage="1d7" unarmedattack="1" unarmeddefense="1" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> + <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> + <function name="name" value="nameskeleton"/> + <function name="age" value="ageskeleton"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="1" damage="1d7"/> + </race> + + <race name="shadowknight" magres="0.000000" maxaura="0.000000" regaura="0.000000" weight="1000" capacity="540" speed="1.0" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noblock="yes"> + <ai splitsize="20000" moverandom="yes"/> + <function name="name" value="namegeneric"/> + <attack type="1" damage="1d1"/> + </race> + + <race name="seaserpent" magres="0.500000" maxaura="1.0" regaura="1.0" weight="20000" capacity="5000" speed="1.0" hp="600" ac="3" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" scarepeasants="yes" swim="yes" teach="no" getitem="yes" resistbash="yes"> + <ai splitsize="6" killpeasants="yes" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> + <function name="move" value="moveswimming"/> + <skill name="tactics" modifier="4"/> + <attack type="4" damage="1d30"/> + <attack type="4" damage="1d30"/> + <attack type="4" damage="1d30"/> + <attack type="6" spell="fiery_dragonbreath"/> + <attack type="8" damage="1d10"/> + </race> + + <!-- for the shadowcall spell --> + <race name="shadowbat" magres="0.800000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="500" capacity="540" speed="1.0" hp="1" ac="4" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes"> + <ai splitsize="5000" killpeasants="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="1d6"/> + <attack type="3" damage="1d1"/> + </race> + + <!-- for the shadowcall spell --> + <race name="nightmare" magres="0.500000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="100" capacity="540" speed="1.0" hp="80" ac="10" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" invinciblenonmagic="yes"> + <ai splitsize="500" killpeasants="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="1d4"/> + <attack type="4" damage="1d4"/> + <attack type="4" damage="1d4"/> + <attack type="3" damage="1d4"/> + <attack type="2" damage="1d10"/> + </race> + + <!-- for the shadowcall spell --> + <race name="vampunicorn" magres="1.0" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="5000" capacity="2000" speed="1.0" hp="30" ac="4" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" teach="no" getitem="yes"> + <ai splitsize="5000" killpeasants="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="2d10"/> + <attack type="3" damage="1d4"/> + <attack type="3" damage="1d4"/> + <attack type="3" damage="1d4"/> + <attack type="3" damage="1d4"/> + <attack type="2" damage="2d60"/> + </race> + +</races> diff --git a/res/e3a/resources.xml b/res/e3a/resources.xml index b9f14c32c..3bc43eb69 100644 --- a/res/e3a/resources.xml +++ b/res/e3a/resources.xml @@ -1,16 +1,16 @@ -<?xml version="1.0"?> -<resources xmlns:xi="http://www.w3.org/2001/XInclude"> - <!-- this file contains resources that can be mined in some way (anything with a resourcelimit) --> - - <xi:include href="eressea:///core/resources/horse.xml"/> - <xi:include href="eressea:///core/resources/hp.xml"/> - <xi:include href="eressea:///core/resources/laen.xml"/> - <xi:include href="eressea:///core/resources/log.xml"/> - <xi:include href="eressea:///core/resources/mallorn.xml"/> - <xi:include href="eressea:///core/resources/peasant.xml"/> - <xi:include href="resources/iron.xml"/> - <xi:include href="resources/mallornseed.xml"/> - <xi:include href="resources/seed.xml"/> - <xi:include href="resources/stone.xml"/> - -</resources> +<?xml version="1.0"?> +<resources xmlns:xi="http://www.w3.org/2001/XInclude"> + <!-- this file contains resources that can be mined in some way (anything with a resourcelimit) --> + + <xi:include href="eressea:///core/resources/horse.xml"/> + <xi:include href="eressea:///core/resources/hp.xml"/> + <xi:include href="eressea:///core/resources/laen.xml"/> + <xi:include href="eressea:///core/resources/log.xml"/> + <xi:include href="eressea:///core/resources/mallorn.xml"/> + <xi:include href="eressea:///core/resources/peasant.xml"/> + <xi:include href="resources/iron.xml"/> + <xi:include href="resources/mallornseed.xml"/> + <xi:include href="resources/seed.xml"/> + <xi:include href="resources/stone.xml"/> + +</resources> diff --git a/res/e3a/resources/iron.xml b/res/e3a/resources/iron.xml index 3856c045d..669a41168 100644 --- a/res/e3a/resources/iron.xml +++ b/res/e3a/resources/iron.xml @@ -1,11 +1,11 @@ -<?xml version="1.0"?> -<resource name="iron" limited="yes" material="rm_iron"> - <item weight="500" score="10"> - <construction skill="mining" minskill="1" reqsize="1"/> - </item> - <resourcelimit> - <modifier building="mine" type="skill" value="1"/> - <modifier building="mine" type="material" value="0.5"/> - <guard flag="mining"/> - </resourcelimit> -</resource> +<?xml version="1.0"?> +<resource name="iron" limited="yes" material="rm_iron"> + <item weight="500" score="10"> + <construction skill="mining" minskill="1" reqsize="1"/> + </item> + <resourcelimit> + <modifier building="mine" type="skill" value="1"/> + <modifier building="mine" type="material" value="0.5"/> + <guard flag="mining"/> + </resourcelimit> +</resource> diff --git a/res/e3a/resources/mallornseed.xml b/res/e3a/resources/mallornseed.xml index 4a348c212..97a2692a3 100644 --- a/res/e3a/resources/mallornseed.xml +++ b/res/e3a/resources/mallornseed.xml @@ -1,4 +1,4 @@ -<?xml version="1.0"?> -<resource name="mallornseed" limited="yes"> - <item weight="10" score="100"/> -</resource> +<?xml version="1.0"?> +<resource name="mallornseed" limited="yes"> + <item weight="10" score="100"/> +</resource> diff --git a/res/e3a/resources/seed.xml b/res/e3a/resources/seed.xml index 21652f364..aa3faf2dc 100644 --- a/res/e3a/resources/seed.xml +++ b/res/e3a/resources/seed.xml @@ -1,4 +1,4 @@ -<?xml version="1.0"?> -<resource name="seed" limited="yes"> - <item weight="10" score="50"/> -</resource> +<?xml version="1.0"?> +<resource name="seed" limited="yes"> + <item weight="10" score="50"/> +</resource> diff --git a/res/e3a/resources/stone.xml b/res/e3a/resources/stone.xml index 854003c86..78956f9e1 100644 --- a/res/e3a/resources/stone.xml +++ b/res/e3a/resources/stone.xml @@ -1,10 +1,10 @@ -<?xml version="1.0"?> -<resource name="stone" limited="yes" material="rm_stone"> - <item weight="6000" score="10" big="yes"> - <construction skill="quarrying" minskill="1" reqsize="1"/> - </item> - <resourcelimit> - <modifier building="quarry" type="skill" value="1"/> - <modifier building="quarry" type="material" value="0.5"/> - </resourcelimit> -</resource> +<?xml version="1.0"?> +<resource name="stone" limited="yes" material="rm_stone"> + <item weight="6000" score="10" big="yes"> + <construction skill="quarrying" minskill="1" reqsize="1"/> + </item> + <resourcelimit> + <modifier building="quarry" type="skill" value="1"/> + <modifier building="quarry" type="material" value="0.5"/> + </resourcelimit> +</resource> diff --git a/res/e3a/shipnames.xml b/res/e3a/shipnames.xml index 15e261ef0..4a008ef3d 100644 --- a/res/e3a/shipnames.xml +++ b/res/e3a/shipnames.xml @@ -1,108 +1,108 @@ -<?xml version="1.0" encoding="UTF-8"?> -<strings> - <string name="canoe_a"> - <text locale="de">ein Einbaum</text> - <text locale="en">a canoe</text> - </string> - <string name="raft_a"> - <text locale="de">ein Floß</text> - <text locale="en">a raft</text> - </string> - <string name="cutter_a"> - <text locale="de">ein Kutter</text> - <text locale="en">a cutter</text> - </string> - <string name="barge_a"> - <text locale="de">eine Barke</text> - <text locale="en">a barge</text> - </string> - - <string name="royalbarge_a"> - <text locale="de">eine Königsbarke</text> - <text locale="en">a royal barge</text> - </string> - <string name="catamaran_a"> - <text locale="de">ein Katamaran</text> - <text locale="en">a catamaran</text> - </string> - - <string name="cog_a"> - <text locale="de">eine Kogge</text> - <text locale="en">a cog</text> - </string> - <string name="caravel_a"> - <text locale="de">eine Karavelle</text> - <text locale="en">a caravel</text> - </string> - - <string name="frigate_a"> - <text locale="de">eine Fregatte</text> - <text locale="en">a frigate</text> - </string> - <string name="galleon_a"> - <text locale="de">eine Galeone</text> - <text locale="en">a galleon</text> - </string> - - <string name="dragonship_a"> - <text locale="de">ein Drachenschiff</text> - <text locale="en">a dragonship</text> - </string> - <string name="trireme_a"> - <text locale="de">eine Trireme</text> - <text locale="en">a trireme</text> - </string> - - <string name="canoe"> - <text locale="de">Einbaum</text> - <text locale="en">canoe</text> - </string> - <string name="raft"> - <text locale="de">Floß</text> - <text locale="en">raft</text> - </string> - <string name="cutter"> - <text locale="de">Kutter</text> - <text locale="en">cutter</text> - </string> - <string name="barge"> - <text locale="de">Barke</text> - <text locale="en">barge</text> - </string> - - <string name="royalbarge"> - <text locale="de">Königsbarke</text> - <text locale="en">royal barge</text> - </string> - <string name="catamaran"> - <text locale="de">Katamaran</text> - <text locale="en">catamaran</text> - </string> - - <string name="cog"> - <text locale="de">Kogge</text> - <text locale="en">cog</text> - </string> - <string name="caravel"> - <text locale="de">Karavelle</text> - <text locale="en">caravel</text> - </string> - - <string name="frigate"> - <text locale="de">Fregatte</text> - <text locale="en">frigate</text> - </string> - <string name="galleon"> - <text locale="de">Galeone</text> - <text locale="en">galleon</text> - </string> - - <string name="dragonship"> - <text locale="de">Drachenschiff</text> - <text locale="en">dragonship</text> - </string> - <string name="trireme"> - <text locale="de">Trireme</text> - <text locale="en">trireme</text> - </string> -</strings> +<?xml version="1.0" encoding="UTF-8"?> +<strings> + <string name="canoe_a"> + <text locale="de">ein Einbaum</text> + <text locale="en">a canoe</text> + </string> + <string name="raft_a"> + <text locale="de">ein Floß</text> + <text locale="en">a raft</text> + </string> + <string name="cutter_a"> + <text locale="de">ein Kutter</text> + <text locale="en">a cutter</text> + </string> + <string name="barge_a"> + <text locale="de">eine Barke</text> + <text locale="en">a barge</text> + </string> + + <string name="royalbarge_a"> + <text locale="de">eine Königsbarke</text> + <text locale="en">a royal barge</text> + </string> + <string name="catamaran_a"> + <text locale="de">ein Katamaran</text> + <text locale="en">a catamaran</text> + </string> + + <string name="cog_a"> + <text locale="de">eine Kogge</text> + <text locale="en">a cog</text> + </string> + <string name="caravel_a"> + <text locale="de">eine Karavelle</text> + <text locale="en">a caravel</text> + </string> + + <string name="frigate_a"> + <text locale="de">eine Fregatte</text> + <text locale="en">a frigate</text> + </string> + <string name="galleon_a"> + <text locale="de">eine Galeone</text> + <text locale="en">a galleon</text> + </string> + + <string name="dragonship_a"> + <text locale="de">ein Drachenschiff</text> + <text locale="en">a dragonship</text> + </string> + <string name="trireme_a"> + <text locale="de">eine Trireme</text> + <text locale="en">a trireme</text> + </string> + + <string name="canoe"> + <text locale="de">Einbaum</text> + <text locale="en">canoe</text> + </string> + <string name="raft"> + <text locale="de">Floß</text> + <text locale="en">raft</text> + </string> + <string name="cutter"> + <text locale="de">Kutter</text> + <text locale="en">cutter</text> + </string> + <string name="barge"> + <text locale="de">Barke</text> + <text locale="en">barge</text> + </string> + + <string name="royalbarge"> + <text locale="de">Königsbarke</text> + <text locale="en">royal barge</text> + </string> + <string name="catamaran"> + <text locale="de">Katamaran</text> + <text locale="en">catamaran</text> + </string> + + <string name="cog"> + <text locale="de">Kogge</text> + <text locale="en">cog</text> + </string> + <string name="caravel"> + <text locale="de">Karavelle</text> + <text locale="en">caravel</text> + </string> + + <string name="frigate"> + <text locale="de">Fregatte</text> + <text locale="en">frigate</text> + </string> + <string name="galleon"> + <text locale="de">Galeone</text> + <text locale="en">galleon</text> + </string> + + <string name="dragonship"> + <text locale="de">Drachenschiff</text> + <text locale="en">dragonship</text> + </string> + <string name="trireme"> + <text locale="de">Trireme</text> + <text locale="en">trireme</text> + </string> +</strings> diff --git a/res/e3a/ships.xml b/res/e3a/ships.xml index 0c8c184e0..f1afff2c5 100644 --- a/res/e3a/ships.xml +++ b/res/e3a/ships.xml @@ -1,154 +1,154 @@ -<?xml version="1.0"?> -<ships> - <ship name="canoe" nocoast="true" range="3" fishing="20" storm="1.00" damage="1.00" cabins="2" cargo="2000" cptskill="1" minskill="1" sumskill="2" opensea="no"> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <coast terrain="swamp"/> - <coast terrain="desert"/> - <coast terrain="highland"/> - <coast terrain="mountain"/> - <coast terrain="glacier"/> - <coast terrain="volcano"/> - <coast terrain="activevolcano"/> - <coast terrain="iceberg_sleep"/> - <coast terrain="iceberg"/> - <construction skill="shipcraft" minskill="1" maxsize="3" reqsize="1"> - <requirement type="log" quantity="1"/> - </construction> - </ship> - - <ship name="raft" range="1" fishing="20" storm="1.00" damage="1.00" cabins="5" cargo="50000" cptskill="1" minskill="1" sumskill="5" opensea="no"> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <coast terrain="swamp"/> - <coast terrain="desert"/> - <construction skill="shipcraft" minskill="1" maxsize="10" reqsize="1"> - <requirement type="log" quantity="1"/> - </construction> - </ship> - - <ship name="cutter" range="2" fishing="20" storm="1.00" damage="1.00" cabins="5" cargo="5500" cptskill="2" minskill="1" sumskill="5" opensea="yes"> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <coast terrain="swamp"/> - <coast terrain="desert"/> - <coast terrain="highland"/> - <coast terrain="mountain"/> - <coast terrain="glacier"/> - <coast terrain="volcano"/> - <coast terrain="activevolcano"/> - <coast terrain="iceberg_sleep"/> - <coast terrain="iceberg"/> - <construction skill="shipcraft" minskill="2" maxsize="10" reqsize="1"> - <requirement type="log" quantity="1"/> - </construction> - </ship> - - <ship name="barge" range="3" fishing="20" storm="1.00" damage="1.00" cabins="11" cargo="5000" cptskill="2" minskill="1" sumskill="5" opensea="no"> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <coast terrain="swamp"/> - <coast terrain="desert"/> - <coast terrain="highland"/> - <coast terrain="mountain"/> - <coast terrain="glacier"/> - <coast terrain="volcano"/> - <coast terrain="activevolcano"/> - <coast terrain="iceberg_sleep"/> - <coast terrain="iceberg"/> - <construction skill="shipcraft" minskill="2" maxsize="10" reqsize="1"> - <requirement type="log" quantity="1"/> - </construction> - </ship> - - - <ship name="royalbarge" range="5" storm="0.25" damage="1.00" cabins="11" cargo="5000" cptskill="5" minskill="1" sumskill="10" opensea="no"> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <coast terrain="swamp"/> - <coast terrain="desert"/> - <coast terrain="highland"/> - <coast terrain="mountain"/> - <coast terrain="glacier"/> - <coast terrain="volcano"/> - <coast terrain="activevolcano"/> - <coast terrain="iceberg_sleep"/> - <coast terrain="iceberg"/> - <construction skill="shipcraft" minskill="6" maxsize="10" reqsize="1"> - <requirement type="mallorn" quantity="1"/> - <requirement type="money" quantity="100"/> - </construction> - </ship> - - <ship name="catamaran" range="7" storm="0.25" damage="1.00" cabins="22" cargo="10000" cptskill="7" minskill="1" sumskill="20" opensea="yes"> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <construction skill="shipcraft" minskill="8" maxsize="30" reqsize="1"> - <requirement type="mallorn" quantity="1"/> - <requirement type="money" quantity="100"/> - </construction> - </ship> - - - <ship name="cog" range="4" storm="0.50" damage="1.00" cabins="50" cargo="200000" cptskill="4" minskill="1" sumskill="20" opensea="yes"> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <construction skill="shipcraft" minskill="4" maxsize="100" reqsize="1"> - <requirement type="log" quantity="1"/> - </construction> - </ship> - - <ship name="caravel" range="4" storm="0.50" damage="1.00" cabins="150" cargo="600000" cptskill="6" minskill="1" sumskill="30" opensea="yes"> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <construction skill="shipcraft" minskill="6" maxsize="300" reqsize="1"> - <requirement type="log" quantity="1"/> - </construction> - </ship> - - - <ship name="frigate" range="4" storm="1.00" damage="1.00" cabins="110" cargo="100000" cptskill="5" minskill="1" sumskill="40" opensea="yes"> - <modifier type="defense" value="+2"/> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <construction skill="shipcraft" minskill="5" maxsize="100" reqsize="1"> - <requirement type="log" quantity="1"/> - <requirement type="money" quantity="10"/> - </construction> - </ship> - - <ship name="galleon" range="4" storm="1.00" damage="1.00" cabins="310" cargo="300000" cptskill="7" minskill="1" sumskill="60" opensea="yes"> - <modifier type="defense" value="+2"/> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <construction skill="shipcraft" minskill="7" maxsize="300" reqsize="1"> - <requirement type="log" quantity="1"/> - <requirement type="money" quantity="10"/> - </construction> - </ship> - - - <ship name="dragonship" range="6" storm="1.00" damage="1.00" cabins="110" cargo="50000" cptskill="5" minskill="1" sumskill="60" opensea="yes"> - <modifier type="attack" value="+1"/> - <modifier type="tactics" factor="2.00"/> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <construction skill="shipcraft" minskill="5" maxsize="100" reqsize="1"> - <requirement type="log" quantity="1"/> - <requirement type="money" quantity="10"/> - </construction> - </ship> - - <ship name="trireme" range="6" storm="1.00" damage="1.00" cabins="310" cargo="150000" cptskill="7" minskill="1" sumskill="90" opensea="yes"> - <modifier type="attack" value="+1"/> - <modifier type="tactics" factor="2.00"/> - <coast terrain="ocean"/> - <coast terrain="plain"/> - <construction skill="shipcraft" minskill="7" maxsize="300" reqsize="1"> - <requirement type="log" quantity="1"/> - <requirement type="money" quantity="10"/> - </construction> - </ship> - -</ships> - +<?xml version="1.0"?> +<ships> + <ship name="canoe" nocoast="true" range="3" fishing="20" storm="1.00" damage="1.00" cabins="2" cargo="2000" cptskill="1" minskill="1" sumskill="2" opensea="no"> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <coast terrain="swamp"/> + <coast terrain="desert"/> + <coast terrain="highland"/> + <coast terrain="mountain"/> + <coast terrain="glacier"/> + <coast terrain="volcano"/> + <coast terrain="activevolcano"/> + <coast terrain="iceberg_sleep"/> + <coast terrain="iceberg"/> + <construction skill="shipcraft" minskill="1" maxsize="3" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + </ship> + + <ship name="raft" range="1" fishing="20" storm="1.00" damage="1.00" cabins="5" cargo="50000" cptskill="1" minskill="1" sumskill="5" opensea="no"> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <coast terrain="swamp"/> + <coast terrain="desert"/> + <construction skill="shipcraft" minskill="1" maxsize="10" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + </ship> + + <ship name="cutter" range="2" fishing="20" storm="1.00" damage="1.00" cabins="5" cargo="5500" cptskill="2" minskill="1" sumskill="5" opensea="yes"> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <coast terrain="swamp"/> + <coast terrain="desert"/> + <coast terrain="highland"/> + <coast terrain="mountain"/> + <coast terrain="glacier"/> + <coast terrain="volcano"/> + <coast terrain="activevolcano"/> + <coast terrain="iceberg_sleep"/> + <coast terrain="iceberg"/> + <construction skill="shipcraft" minskill="2" maxsize="10" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + </ship> + + <ship name="barge" range="3" fishing="20" storm="1.00" damage="1.00" cabins="11" cargo="5000" cptskill="2" minskill="1" sumskill="5" opensea="no"> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <coast terrain="swamp"/> + <coast terrain="desert"/> + <coast terrain="highland"/> + <coast terrain="mountain"/> + <coast terrain="glacier"/> + <coast terrain="volcano"/> + <coast terrain="activevolcano"/> + <coast terrain="iceberg_sleep"/> + <coast terrain="iceberg"/> + <construction skill="shipcraft" minskill="2" maxsize="10" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + </ship> + + + <ship name="royalbarge" range="5" storm="0.25" damage="1.00" cabins="11" cargo="5000" cptskill="5" minskill="1" sumskill="10" opensea="no"> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <coast terrain="swamp"/> + <coast terrain="desert"/> + <coast terrain="highland"/> + <coast terrain="mountain"/> + <coast terrain="glacier"/> + <coast terrain="volcano"/> + <coast terrain="activevolcano"/> + <coast terrain="iceberg_sleep"/> + <coast terrain="iceberg"/> + <construction skill="shipcraft" minskill="6" maxsize="10" reqsize="1"> + <requirement type="mallorn" quantity="1"/> + <requirement type="money" quantity="100"/> + </construction> + </ship> + + <ship name="catamaran" range="7" storm="0.25" damage="1.00" cabins="22" cargo="10000" cptskill="7" minskill="1" sumskill="20" opensea="yes"> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <construction skill="shipcraft" minskill="8" maxsize="30" reqsize="1"> + <requirement type="mallorn" quantity="1"/> + <requirement type="money" quantity="100"/> + </construction> + </ship> + + + <ship name="cog" range="4" storm="0.50" damage="1.00" cabins="50" cargo="200000" cptskill="4" minskill="1" sumskill="20" opensea="yes"> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <construction skill="shipcraft" minskill="4" maxsize="100" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + </ship> + + <ship name="caravel" range="4" storm="0.50" damage="1.00" cabins="150" cargo="600000" cptskill="6" minskill="1" sumskill="30" opensea="yes"> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <construction skill="shipcraft" minskill="6" maxsize="300" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + </ship> + + + <ship name="frigate" range="4" storm="1.00" damage="1.00" cabins="110" cargo="100000" cptskill="5" minskill="1" sumskill="40" opensea="yes"> + <modifier type="defense" value="+2"/> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <construction skill="shipcraft" minskill="5" maxsize="100" reqsize="1"> + <requirement type="log" quantity="1"/> + <requirement type="money" quantity="10"/> + </construction> + </ship> + + <ship name="galleon" range="4" storm="1.00" damage="1.00" cabins="310" cargo="300000" cptskill="7" minskill="1" sumskill="60" opensea="yes"> + <modifier type="defense" value="+2"/> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <construction skill="shipcraft" minskill="7" maxsize="300" reqsize="1"> + <requirement type="log" quantity="1"/> + <requirement type="money" quantity="10"/> + </construction> + </ship> + + + <ship name="dragonship" range="6" storm="1.00" damage="1.00" cabins="110" cargo="50000" cptskill="5" minskill="1" sumskill="60" opensea="yes"> + <modifier type="attack" value="+1"/> + <modifier type="tactics" factor="2.00"/> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <construction skill="shipcraft" minskill="5" maxsize="100" reqsize="1"> + <requirement type="log" quantity="1"/> + <requirement type="money" quantity="10"/> + </construction> + </ship> + + <ship name="trireme" range="6" storm="1.00" damage="1.00" cabins="310" cargo="150000" cptskill="7" minskill="1" sumskill="90" opensea="yes"> + <modifier type="attack" value="+1"/> + <modifier type="tactics" factor="2.00"/> + <coast terrain="ocean"/> + <coast terrain="plain"/> + <construction skill="shipcraft" minskill="7" maxsize="300" reqsize="1"> + <requirement type="log" quantity="1"/> + <requirement type="money" quantity="10"/> + </construction> + </ship> + +</ships> + diff --git a/res/e3a/spells.xml b/res/e3a/spells.xml index 57185c3f7..2e563cbe8 100644 --- a/res/e3a/spells.xml +++ b/res/e3a/spells.xml @@ -1,690 +1,690 @@ -<?xml version="1.0" encoding="iso-8859-1"?> -<spells> -<!-- new illaun --> - <spell name="shadowknights" type="illaun" rank="4" level="1" index="147" variable="true" combat="1"> - <!-- Schattenritter --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="sparkledream" type="illaun" rank="5" level="1" index="154" parameters="u" los="true" ship="true" variable="true"> - <!-- Traumsenden --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="earn_silver#illaun" type="illaun" ship="true" variable="true" rank="5" level="1" index="159"> - <!-- Wahrsagen --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="flee" type="illaun" rank="5" level="2" index="20" variable="true" combat="1"> - <!-- Grauen der Schlacht --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="puttorest" type="illaun" rank="5" level="2" index="168" variable="true"> - <!-- Seelenfrieden --> - <resource name="aura" amount="3" cost="level"/> - <resource name="balm" amount="10" cost="fixed"/> - </spell> - <spell name="shapeshift" type="illaun" rank="5" level="3" index="93" syntax="race" parameters="uc" variable="true"> - <!-- Gestaltwandlung --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="icastle" type="illaun" rank="5" level="3" index="137" syntax="buildingtype" parameters="c"> - <!-- Traumschl��chen --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="dreamreading" type="illaun" rank="5" level="4" index="13" parameters="u" far="true"> - <!-- Traumlesen --> - <resource name="aura" amount="8" cost="fixed"/> - </spell> - <spell name="tiredsoldiers" type="illaun" rank="5" level="4" index="15" variable="true" combat="1"> - <!-- Schwere Glieder --> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="reanimate" type="illaun" rank="4" level="5" index="85" variable="true" combat="3"> - <!-- Wiederbelebung --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="disturbingdreams" type="illaun" rank="5" level="6" index="50" far="true"> - <!-- Schlechter Schlaf --> - <resource name="aura" amount="18" cost="fixed"/> - </spell> - <spell name="sleep" type="illaun" rank="5" level="7" index="52" variable="true" combat="2"> - <!-- Schlaf --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="readmind" parameters="u" type="illaun" rank="5" level="7" index="114"> - <!-- Traumdeuten --> - <function name="cast" value="cast_readmind"/> - <resource name="aura" amount="20" cost="fixed"/> - <!-- missing syntactical info: ONETARGET | UNITSPELL --> - </spell> - <spell name="gooddreams" type="illaun" rank="5" level="8" index="12" far="true"> - <!-- Sch�ne Tr�ume --> - <resource name="aura" amount="80" cost="fixed"/> - </spell> - <spell name="illaundestroymagic" type="illaun" rank="2" level="8" index="140" parameters="kc+" los="true" ship="true" far="true" variable="true"> - <!-- Traumbilder entwirren --> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="clone" type="illaun" rank="5" level="9" index="173"> - <!-- Seelenkopie --> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="20" cost="fixed"/> - <resource name="dragonblood" amount="5" cost="fixed"/> - <resource name="silk" amount="20" cost="fixed"/> - </spell> - <spell name="bad_dreams" type="illaun" rank="5" level="10" index="11" far="true"> - <!-- Schlechte Tr�ume --> - <resource name="aura" amount="90" cost="fixed"/> - </spell> - <spell name="mindblast" type="illaun" rank="5" level="11" index="78" variable="true" combat="1"> - <!-- Tod des Geistes --> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="create_dreameye" type="illaun" ship="true" rank="5" level="14" index="149"> - <!-- Erschaffe ein Traumauge --> - <function name="cast" value="lua_castspell"/> - <resource name="dragonhead" amount="1" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <!-- end illaun --> - - <!-- new draig --> - <spell name="sparklechaos" type="draig" rank="5" level="1" index="153" parameters="u" los="true" variable="true"> - <!-- Verw�nschung --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="earn_silver#draig" type="draig" ship="true" variable="true" rank="5" level="1" index="159"> - <!-- Kleine Fl�che --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="fireball" type="draig" rank="5" level="2" index="4" variable="true" combat="2"> - <!-- Feuerball --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="magicboost" type="draig" rank="3" level="3" index="17" ship="true"> - <!-- Gabe des Chaos --> - <resource name="aura" amount="2" cost="linear"/> - </spell> - <spell name="bloodsacrifice" type="draig" rank="1" level="4" index="171" ship="true"> - <!-- Kleines Blutopfer --> - <resource name="hp" amount="4" cost="level"/> - </spell> - <spell name="berserk" type="draig" rank="4" level="5" index="22" variable="true" combat="1"> - <!-- Blutrausch --> - <resource name="aura" amount="5" cost="level"/> - <resource name="peasant" amount="1" cost="fixed"/> - </spell> - <spell name="fumblecurse" type="draig" rank="4" level="5" index="136" parameters="u" los="true" variable="true"> - <!-- Chaosfluch --> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="combatrust" type="draig" rank="5" level="6" index="7" variable="true" combat="2"> - <!-- Rosthauch --> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="summonundead" type="draig" rank="5" level="6" index="41" ship="true" far="true" variable="true"> - <!-- M�chte des Todes --> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="firewall" type="draig" rank="4" level="7" index="151" syntax="direction" parameters="c" variable="true"> - <!-- Feuerwand --> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="chaosrow" type="draig" rank="5" level="8" index="18" variable="true" combat="1"> - <!-- Wahnsinn des Krieges --> - <resource name="aura" amount="3" cost="level"/> - <resource name="peasant" amount="10" cost="fixed"/> - </spell> - <spell name="summonshadow" type="draig" rank="5" level="8" index="34" variable="true"> - <!-- Beschw�re Schattend�monen --> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="undeadhero" type="draig" rank="5" level="9" index="164" variable="true" combat="3"> - <!-- Untote Helden --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="draigdestroymagic" type="draig" rank="2" level="10" index="139" parameters="kc+" los="true" ship="true" far="true" variable="true"> - <!-- Pentagramm --> - <resource name="aura" amount="10" cost="level"/> - </spell> - <spell name="deathcloud" type="draig" rank="5" level="11" index="111" far="true"> - <!-- Todeswolke --> - <resource name="aura" amount="40" cost="fixed"/> - <resource name="hp" amount="15" cost="fixed"/> - </spell> - <spell name="summondragon" type="draig" rank="5" level="11" index="113" far="true"> - <!-- Drachenruf --> - <resource name="aura" amount="80" cost="fixed"/> - <resource name="dragonhead" amount="1" cost="fixed"/> - </spell> - <spell name="summonshadowlords" type="draig" rank="5" level="12" index="35" variable="true"> - <!-- Beschw�re Schattenmeister --> - <resource name="aura" amount="7" cost="level"/> - </spell> - <spell name="create_firesword" type="draig" ship="true" rank="5" level="12" index="148"> - <!-- Erschaffe ein Flammenschwert --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="oil" amount="10" cost="fixed"/> - <resource name="sword" amount="1" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - <spell name="unholypower" type="draig" rank="5" level="14" index="169" parameters="u+" los="true" variable="true"> - <!-- Unheilige Kraft --> - <resource name="aura" amount="10" cost="level"/> - <resource name="peasant" amount="5" cost="level"/> - </spell> - <!-- end draig --> - - <!-- new cerddor --> - <spell name="earn_silver#cerddor" type="cerddor" ship="true" variable="true" rank="5" level="1" index="159"> - <!-- Gaukeleien --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="song_of_healing" type="cerddor" rank="5" level="2" index="10" variable="true" combat="3"> - <!-- Lied der Heilung --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="generous" type="cerddor" rank="5" level="2" index="87" ship="true" far="true" variable="true"> - <!-- Hohes Lied der Gaukelei --> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="song_of_fear" type="cerddor" rank="5" level="3" index="21" variable="true" combat="2"> - <!-- Gesang der Furcht --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="song_of_confusion" type="cerddor" rank="5" level="4" index="19" variable="true" combat="1"> - <!-- Gesang der Verwirrung --> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="blabbermouth" parameters="u" type="cerddor" los="true" rank="5" level="4" index="115"> - <!-- Plappermaul --> - <function name="cast" value="cast_babbler"/> - <resource name="aura" amount="10" cost="fixed"/> - <!-- missing syntactical info: ONETARGET | UNITSPELL --> - </spell> - <spell name="heroic_song" type="cerddor" rank="4" level="5" index="76" variable="true" combat="1"> - <!-- Heldengesang --> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="seduction" type="cerddor" rank="5" level="6" index="73" parameters="u" los="true"> - <!-- Lied der Verf�hrung --> - <resource name="aura" amount="12" cost="fixed"/> - </spell> - <spell name="calm_monster" type="cerddor" rank="5" level="6" index="75" parameters="u" los="true" ship="true"> - <!-- Monster friedlich stimmen --> - <resource name="aura" amount="15" cost="fixed"/> - </spell> - <spell name="bloodthirst" type="cerddor" rank="4" level="7" index="23" variable="true" combat="1"> - <!-- Kriegsgesang --> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="frighten" type="cerddor" rank="5" level="8" index="77" variable="true" combat="1"> - <!-- Gesang der Angst --> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="cerddor_destroymagic" type="cerddor" rank="2" level="8" index="141" parameters="kc+" los="true" ship="true" far="true" variable="true"> - <!-- Lebenslied festigen --> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="migration" type="cerddor" rank="5" level="9" index="90" parameters="u" los="true" variable="true"> - <!-- Ritual der Aufnahme --> - <resource name="aura" amount="3" cost="level"/> - <resource name="permaura" amount="1" cost="level"/> - </spell> - <spell name="raise_mob" type="cerddor" rank="5" level="10" index="60" variable="true"> - <!-- Mob aufwiegeln --> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="song_resist_magic" type="cerddor" rank="2" level="10" index="100" far="true" variable="true"> - <!-- Gesang des wachen Geistes --> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="create_roqf" type="cerddor" ship="true" rank="5" level="11" index="63"> - <!-- Miriams flinke Finger --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="20" cost="fixed"/> - <resource name="money" amount="1000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - <spell name="song_of_peace" type="cerddor" rank="5" level="12" index="89" variable="true"> - <!-- Gesang der Friedfertigkeit --> - <resource name="aura" amount="20" cost="level"/> - </spell> - <spell name="song_suscept_magic" type="cerddor" rank="2" level="12" index="101" far="true" variable="true"> - <!-- Gesang des schwachen Geistes --> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="song_of_slavery" type="cerddor" rank="5" level="13" index="123" parameters="u" los="true"> - <!-- Gesang der Versklavung --> - <resource name="aura" amount="40" cost="fixed"/> - </spell> -<!-- TODO: exploitable (transfers items) --> - <spell name="big_recruit" type="cerddor" rank="5" level="14" index="179" variable="true"> - <!-- Hohe Kunst der �berzeugung --> - <resource name="aura" amount="20" cost="level"/> - </spell> - <spell name="calm_riot" type="cerddor" rank="5" level="14" index="91" far="true"> - <!-- Aufruhr beschwichtigen --> - <resource name="aura" amount="30" cost="fixed"/> - </spell> - <spell name="incite_riot" type="cerddor" rank="5" level="15" index="92" far="true"> - <!-- Aufruhr verursachen --> - <resource name="aura" amount="40" cost="fixed"/> - </spell> - <!-- end cerddor --> - - <!-- new gwyrrd --> - <spell name="blessedharvest" type="gwyrrd" rank="5" level="3" index="25" ship="true" far="true" variable="true"> - <!-- Segen der Erde --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="earn_silver#gwyrrd" type="gwyrrd" ship="true" variable="true" rank="5" level="1" index="159"> - <!-- Viehheilung --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="stonegolem" type="gwyrrd" rank="4" level="20" index="32" variable="true"> - <!-- Erschaffe Steingolems --> - <resource name="aura" amount="2" cost="level"/> - <resource name="stone" amount="1" cost="level"/> - <resource name="jewel" amount="10" cost="fixed"/> - </spell> - <spell name="treegrow" type="gwyrrd" rank="5" level="2" index="8" far="true" variable="true"> - <!-- Hainzauber --> - <resource name="aura" amount="4" cost="level"/> - <resource name="log" amount="1" cost="level"/> - <resource name="myrrh" amount="10" cost="fixed"/> - </spell> - <spell name="hail" type="gwyrrd" rank="5" level="3" index="5" variable="true" combat="2"> - <!-- Hagel --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="goodwinds" type="common" rank="5" level="4" index="56" parameters="s" ship="true" variable="true"> - <!-- Beschw�rung eines Wasserelementares --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="windshield" type="gwyrrd" rank="5" level="4" index="59" variable="true" combat="1"> - <!-- Windschild --> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="healing" type="gwyrrd" rank="5" level="5" index="9" variable="true" combat="3"> - <!-- Heilung --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="earthquake" type="gwyrrd" rank="5" level="6" index="53" far="true"> - <!-- Beschw�re einen Erdelementar --> - <resource name="aura" amount="25" cost="fixed"/> - <resource name="laen" amount="2" cost="fixed"/> - </spell> - <spell name="stormwinds" type="gwyrrd" rank="5" level="6" index="55" parameters="s+" ship="true" ocean="true" variable="true"> - <!-- Beschw�re einen Sturmelementar --> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="wolfhowl" type="gwyrrd" rank="5" level="7" index="94" variable="true" combat="1"> - <!-- Wolfsgeheul --> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="versteinern" type="gwyrrd" rank="5" level="8" index="67" variable="true" combat="2"> - <!-- Blick des Basilisken --> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="gwyrrddestroymagic" type="gwyrrd" rank="2" level="8" index="138" parameters="kc+" los="true" ship="true" far="true" variable="true"> - <!-- Geister bannen --> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="holyground" type="gwyrrd" rank="5" level="9" index="170"> - <!-- Heiliger Boden --> - <resource name="aura" amount="80" cost="fixed"/> - <resource name="permaura" amount="3" cost="fixed"/> - </spell> - <spell name="summonent" type="gwyrrd" rank="5" level="10" index="49" variable="true"> - <!-- Erwecke Ents --> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="blessstonecircle" type="gwyrrd" rank="5" level="11" index="117" parameters="b"> - <!-- Segne Steinkreis --> - <resource name="aura" amount="350" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="barkskin" type="gwyrrd" rank="2" level="12" index="142" variable="true" combat="1"> - <!-- Rindenhaut --> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="summonfireelemental" type="gwyrrd" rank="5" level="13" index="46" far="true"> - <!-- Beschw�rung eines Hitzeelementar --> - <resource name="aura" amount="600" cost="fixed"/> - </spell> - <spell name="maelstrom" type="gwyrrd" rank="5" level="15" index="24" ship="true" ocean="true"> - <!-- Mahlstrom --> - <resource name="aura" amount="200" cost="fixed"/> - <resource name="seaserpenthead" amount="1" cost="fixed"/> - </spell> - <!-- end gwyrrd --> - - <!-- new tybied - spells known to all schools --> - <spell name="create_potion_p2" type="tybied" ship="true" rank="5" level="2" variable="true"> - <!-- Wasser des Lebens --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="2" cost="linear"/> - <resource name="h4" amount="1" cost="linear"/><!-- Baumringel --> - <resource name="h6" amount="1" cost="linear"/><!-- Gurgelkraut --> - </spell> - <spell name="create_potion_p0" type="tybied" ship="true" rank="5" level="3" variable="true"> - <!-- Siebenmeilentee --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="2" cost="linear"/> - <resource name="h12" amount="1" cost="linear"/><!-- Windbeutel --> - <resource name="h17" amount="1" cost="linear"/><!-- H�hlenglimm --> - </spell> - <spell name="create_potion_p9" type="tybied" ship="true" rank="5" level="4" variable="true"> - <!-- Pferdegl�ck --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="3" cost="linear"/> - <resource name="h0" amount="1" cost="linear"/><!-- Flachwurz --> - <resource name="h8" amount="1" cost="linear"/><!-- Blasenmorchel --> - <resource name="h15" amount="1" cost="linear"/><!-- Steinbei�er --> - </spell> - <spell name="create_potion_peasantblood" type="tybied" ship="true" rank="5" level="5" variable="true"> - <!-- Bauernblut --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="3" cost="linear"/> - <resource name="h14" amount="1" cost="linear"/><!-- Alraune --> - <resource name="h6" amount="1" cost="linear"/><!-- Gurgelkraut --> - <resource name="h17" amount="1" cost="linear"/><!-- H�hlenglimm --> - <resource name="peasant" amount="1" cost="fixed"/><!-- Bauer --> - </spell> - - <spell name="create_potion_ointment" type="tybied" ship="true" rank="5" level="6" variable="true"> - <!-- Wundsalbe --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="4" cost="linear"/> - <resource name="h4" amount="1" cost="linear"/><!-- Baumringel --> - <resource name="h15" amount="1" cost="linear"/><!-- Steinbei�er --> - <resource name="h18" amount="1" cost="linear"/><!-- Eisblume --> - <resource name="h11" amount="1" cost="linear"/><!-- Sandf�ule --> - </spell> - <spell name="create_potion_p3" type="tybied" ship="true" rank="5" level="7" variable="true"> - <!-- Schaffenstrunk --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="4" cost="linear"/> - <resource name="h12" amount="1" cost="linear"/><!-- Windbeutel --> - <resource name="h6" amount="1" cost="linear"/><!-- Gurgelkraut --> - <resource name="h20" amount="1" cost="linear"/><!-- Schneekristall --> - <resource name="h9" amount="1" cost="linear"/><!-- Wasserfinder --> - </spell> - <spell name="create_potion_p14" type="tybied" ship="true" rank="5" level="8" variable="true"> - <!-- Heiltrank --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="5" cost="linear"/> - <resource name="h0" amount="1" cost="linear"/><!-- Flachwurz --> - <resource name="h8" amount="1" cost="linear"/><!-- Blasenmorchel --> - <resource name="h15" amount="1" cost="linear"/><!-- Steinbei�er --> - <resource name="h18" amount="1" cost="linear"/><!-- Eisblume --> - <resource name="h9" amount="1" cost="linear"/><!-- Wasserfinder --> - </spell> - <spell name="create_potion_p13" type="tybied" ship="true" rank="5" level="9" variable="true"> - <!-- Elixier der Macht --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="5" cost="linear"/> - <resource name="h14" amount="1" cost="linear"/><!-- Alraune --> - <resource name="h8" amount="1" cost="linear"/><!-- Blasenmorchel --> - <resource name="h17" amount="1" cost="linear"/><!-- H�hlenglimm --> - <resource name="h20" amount="1" cost="linear"/><!-- Schneekristall --> - <resource name="h11" amount="1" cost="linear"/><!-- Sandf�ule --> - <resource name="dragonblood" amount="1" cost="fixed"/><!-- Drachenblut --> - </spell> - - <spell name="create_roi" type="tybied" ship="true" rank="5" level="7" index="130"> - <!-- Erschaffe einen Ring der Unsichtbarkeit --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - <spell name="create_aots" type="tybied" ship="true" rank="5" level="6" index="125"> - <!-- Erschaffe ein Amulett des wahren Sehens --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - <spell name="auratransfer" type="tybied" rank="1" level="5" index="31" syntax="aura" parameters="ui" ship="true"> - <!-- Auratransfer --> - <resource name="aura" amount="1" cost="fixed"/> - </spell> - <!-- end tybied --> - - <!-- common spells: randomly given, one per level --> - <spell name="create_trollbelt" type="common" ship="true" rank="5" level="9" index="48"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="20" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="create_antimagic" type="common" ship="true" rank="5" level="7" index="38"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - </spell> - - <spell name="create_rop" type="common" ship="true" rank="5" level="9" index="1"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - <resource name="money" amount="4000" cost="fixed"/> - </spell> - - <spell name="create_bagofholding" type="common" ship="true" rank="5" level="10" index="155"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="30" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - <resource name="money" amount="5000" cost="fixed"/> - </spell> - - <spell name="create_focus" type="common" ship="true" rank="5" level="9" index="2"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="create_ror" type="common" ship="true" rank="5" level="9" index="3"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="rustweapon" type="gwyrrd" rank="5" level="3" index="6" parameters="u+" los="true" far="true" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="plague" type="common" rank="5" level="7" index="16" far="true"> - <resource name="aura" amount="30" cost="fixed"/> - <resource name="peasant" amount="50" cost="fixed"/> - </spell> - <spell name="raindance" type="common" rank="5" level="2" index="26" ship="true" far="true" variable="true"> - <!-- Regentanz --> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="irongolem" type="common" rank="4" level="2" index="33" variable="true"> - <!-- Eisengolem --> - <resource name="aura" amount="2" cost="level"/> - <resource name="iron" amount="1" cost="level"/> - <resource name="incense" amount="1" cost="fixed"/> - </spell> - <spell name="reelingarrows" type="common" rank="5" level="5" index="36" variable="true" combat="1"> - <!-- Wirbelwind --> - <resource name="aura" amount="15" cost="fixed"/> - </spell> - <spell name="antimagiczone" type="common" rank="2" level="5" index="37" far="true" variable="true"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="steal_aura" type="common" rank="3" level="6" index="40" parameters="u" los="true" far="true" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="auraleak" type="common" rank="3" level="9" index="42"> - <resource name="aura" amount="35" cost="fixed"/> - <resource name="dragonblood" amount="1" cost="fixed"/> - </spell> - <spell name="strongwall" type="common" rank="5" level="8" index="44" variable="true" combat="1"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="homestone" type="common" rank="5" level="7" index="45"> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - <spell name="forestfire" type="common" rank="5" level="10" index="47" far="true"> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="oil" amount="5" cost="fixed"/> - </spell> - <spell name="disturbingdreams" type="common" rank="5" level="6" index="50" far="true"> - <resource name="aura" amount="18" cost="fixed"/> - </spell> - <spell name="appeasement" type="common" rank="5" level="1" index="51" variable="true" combat="1"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="ironkeeper" type="common" rank="5" level="3" index="54" far="true" variable="true"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="airship" type="common" rank="5" level="6" index="57" parameters="s" ship="true"> - <resource name="aura" amount="10" cost="fixed"/> - <resource name="h12" amount="1" cost="fixed"/> - <resource name="h20" amount="1" cost="fixed"/> - </spell> - <spell name="sound_out" type="common" rank="5" level="7" index="74" parameters="ur" los="true"> - <resource name="aura" amount="4" cost="fixed"/> - <resource name="money" amount="100" cost="fixed"/> - </spell> - <spell name="combat_speed" type="common" rank="5" level="9" index="79" variable="true" combat="1"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="double_time" type="common" rank="5" level="11" index="80" parameters="u+" los="true" ship="true" variable="true"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="magicstreet" type="common" rank="5" level="4" index="84" ship="true" far="true" variable="true"> - <resource name="aura" amount="1" cost="level"/> - <resource name="stone" amount="1" cost="fixed"/> - <resource name="log" amount="1" cost="fixed"/> - </spell> - <spell name="sacrifice_strength" type="common" rank="1" level="15" index="88" syntax="aura" parameters="ui"> - <resource name="aura" amount="100" cost="fixed"/> - </spell> - <spell name="resist_magic" type="common" rank="2" level="3" index="97" parameters="u+" los="true" ship="true" variable="true"> - <!-- Schutzzauber --> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="protective_runes" type="common" rank="2" level="8" index="99" parameters="kc" ship="true"> - <resource name="aura" amount="20" cost="fixed"/> - </spell> - <spell name="analyze_magic" type="common" rank="5" level="1" index="102" parameters="kc?" los="true" ship="true" variable="true"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="destroy_magic" type="common" rank="2" level="5" index="106" parameters="kc+" los="true" ship="true" far="true" variable="true"> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="break_curse" type="common" rank="3" level="7" index="107" syntax="spellid" parameters="kcc?" los="true" ship="true" far="true" variable="true"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="fish_shield" type="common" rank="2" level="8" index="109" variable="true" combat="1"> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="armor_shield" type="common" rank="2" level="12" index="110" variable="true" combat="1"> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="living_rock" type="common" rank="5" level="13" index="116" syntax="direction" parameters="bc" variable="true"> - <resource name="aura" amount="10" cost="level"/> - <resource name="permaura" amount="1" cost="fixed"/> - <resource name="laen" amount="5" cost="fixed"/> - </spell> - <spell name="commonfamiliar" type="common" rank="5" level="9" index="118"> - <function name="cast" value="cast_familiar"/> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="gwyrrdfamiliar" type="common" rank="5" level="10" index="119"> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="draigfamiliar" type="common" rank="5" level="13" index="120"> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="summon_familiar" type="cerddor" rank="5" level="9" index="121"> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="summon_familiar" type="common" rank="5" level="12" index="122"> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="draigfumbleshield" type="common" rank="2" level="9" index="143" variable="true" combat="1"> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="gwyrrdfumbleshield" type="common" rank="2" level="5" index="144" variable="true" combat="1"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="cerrdorfumbleshield" type="common" rank="2" level="5" index="145" variable="true" combat="1"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="tybiedfumbleshield" type="common" rank="2" level="2" index="146" variable="true" combat="1"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="concealing_aura" type="common" rank="5" level="1" index="150" parameters="u" ship="true" variable="true"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="shockwave" type="common" rank="5" level="5" index="163" variable="true" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="eternal_walls" type="common" rank="5" level="7" index="167" parameters="b" ship="true" variable="true"> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - <!-- end common spells --> - - <!-- gray spells: given to individuals or monsters --> - <spell name="fiery_dragonbreath" type="gray" rank="5" level="3" index="81" combat="2"> - <resource name="aura" amount="1" cost="fixed"/> - </spell> - <spell name="icy_dragonbreath" type="gray" rank="5" level="6" index="82" combat="2"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="powerful_dragonbreath" type="gray" rank="5" level="12" index="83" combat="2"> - <resource name="aura" amount="3" cost="fixed"/> - </spell> - <spell name="meteor_rain" type="gray" rank="5" level="3" index="108" variable="true" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="wyrm_transformation" type="gray" rank="5" level="1" index="166"> - <resource name="aura" amount="1" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - <spell name="transferauratraum" type="gray" rank="1" level="3" index="30" syntax="aura" parameters="ui" ship="true"> - <!-- Traum der Magie --> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="drain_skills" type="gray" rank="5" level="12" index="174" combat="2"> - <resource name="aura" amount="4" cost="fixed"/> - </spell> - <spell name="aura_of_fear" type="gray" rank="5" level="12" index="175" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="shadowcall" type="gray" rank="5" level="12" index="176" combat="1"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="immolation" type="gray" rank="5" level="12" index="180" combat="2"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="firestorm" type="gray" rank="5" level="8" index="181" combat="2"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="coldfront" type="gray" rank="5" level="8" index="182" combat="2"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="acidrain" type="gray" rank="5" level="8" index="183" combat="2"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <!-- end gray spells --> -</spells> +<?xml version="1.0" encoding="iso-8859-1"?> +<spells> +<!-- new illaun --> + <spell name="shadowknights" type="illaun" rank="4" level="1" index="147" variable="true" combat="1"> + <!-- Schattenritter --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="sparkledream" type="illaun" rank="5" level="1" index="154" parameters="u" los="true" ship="true" variable="true"> + <!-- Traumsenden --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="earn_silver#illaun" type="illaun" ship="true" variable="true" rank="5" level="1" index="159"> + <!-- Wahrsagen --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="flee" type="illaun" rank="5" level="2" index="20" variable="true" combat="1"> + <!-- Grauen der Schlacht --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="puttorest" type="illaun" rank="5" level="2" index="168" variable="true"> + <!-- Seelenfrieden --> + <resource name="aura" amount="3" cost="level"/> + <resource name="balm" amount="10" cost="fixed"/> + </spell> + <spell name="shapeshift" type="illaun" rank="5" level="3" index="93" syntax="race" parameters="uc" variable="true"> + <!-- Gestaltwandlung --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="icastle" type="illaun" rank="5" level="3" index="137" syntax="buildingtype" parameters="c"> + <!-- Traumschl��chen --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="dreamreading" type="illaun" rank="5" level="4" index="13" parameters="u" far="true"> + <!-- Traumlesen --> + <resource name="aura" amount="8" cost="fixed"/> + </spell> + <spell name="tiredsoldiers" type="illaun" rank="5" level="4" index="15" variable="true" combat="1"> + <!-- Schwere Glieder --> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="reanimate" type="illaun" rank="4" level="5" index="85" variable="true" combat="3"> + <!-- Wiederbelebung --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="disturbingdreams" type="illaun" rank="5" level="6" index="50" far="true"> + <!-- Schlechter Schlaf --> + <resource name="aura" amount="18" cost="fixed"/> + </spell> + <spell name="sleep" type="illaun" rank="5" level="7" index="52" variable="true" combat="2"> + <!-- Schlaf --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="readmind" parameters="u" type="illaun" rank="5" level="7" index="114"> + <!-- Traumdeuten --> + <function name="cast" value="cast_readmind"/> + <resource name="aura" amount="20" cost="fixed"/> + <!-- missing syntactical info: ONETARGET | UNITSPELL --> + </spell> + <spell name="gooddreams" type="illaun" rank="5" level="8" index="12" far="true"> + <!-- Sch�ne Tr�ume --> + <resource name="aura" amount="80" cost="fixed"/> + </spell> + <spell name="illaundestroymagic" type="illaun" rank="2" level="8" index="140" parameters="kc+" los="true" ship="true" far="true" variable="true"> + <!-- Traumbilder entwirren --> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="clone" type="illaun" rank="5" level="9" index="173"> + <!-- Seelenkopie --> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="20" cost="fixed"/> + <resource name="dragonblood" amount="5" cost="fixed"/> + <resource name="silk" amount="20" cost="fixed"/> + </spell> + <spell name="bad_dreams" type="illaun" rank="5" level="10" index="11" far="true"> + <!-- Schlechte Tr�ume --> + <resource name="aura" amount="90" cost="fixed"/> + </spell> + <spell name="mindblast" type="illaun" rank="5" level="11" index="78" variable="true" combat="1"> + <!-- Tod des Geistes --> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="create_dreameye" type="illaun" ship="true" rank="5" level="14" index="149"> + <!-- Erschaffe ein Traumauge --> + <function name="cast" value="lua_castspell"/> + <resource name="dragonhead" amount="1" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <!-- end illaun --> + + <!-- new draig --> + <spell name="sparklechaos" type="draig" rank="5" level="1" index="153" parameters="u" los="true" variable="true"> + <!-- Verw�nschung --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="earn_silver#draig" type="draig" ship="true" variable="true" rank="5" level="1" index="159"> + <!-- Kleine Fl�che --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="fireball" type="draig" rank="5" level="2" index="4" variable="true" combat="2"> + <!-- Feuerball --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="magicboost" type="draig" rank="3" level="3" index="17" ship="true"> + <!-- Gabe des Chaos --> + <resource name="aura" amount="2" cost="linear"/> + </spell> + <spell name="bloodsacrifice" type="draig" rank="1" level="4" index="171" ship="true"> + <!-- Kleines Blutopfer --> + <resource name="hp" amount="4" cost="level"/> + </spell> + <spell name="berserk" type="draig" rank="4" level="5" index="22" variable="true" combat="1"> + <!-- Blutrausch --> + <resource name="aura" amount="5" cost="level"/> + <resource name="peasant" amount="1" cost="fixed"/> + </spell> + <spell name="fumblecurse" type="draig" rank="4" level="5" index="136" parameters="u" los="true" variable="true"> + <!-- Chaosfluch --> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="combatrust" type="draig" rank="5" level="6" index="7" variable="true" combat="2"> + <!-- Rosthauch --> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="summonundead" type="draig" rank="5" level="6" index="41" ship="true" far="true" variable="true"> + <!-- M�chte des Todes --> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="firewall" type="draig" rank="4" level="7" index="151" syntax="direction" parameters="c" variable="true"> + <!-- Feuerwand --> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="chaosrow" type="draig" rank="5" level="8" index="18" variable="true" combat="1"> + <!-- Wahnsinn des Krieges --> + <resource name="aura" amount="3" cost="level"/> + <resource name="peasant" amount="10" cost="fixed"/> + </spell> + <spell name="summonshadow" type="draig" rank="5" level="8" index="34" variable="true"> + <!-- Beschw�re Schattend�monen --> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="undeadhero" type="draig" rank="5" level="9" index="164" variable="true" combat="3"> + <!-- Untote Helden --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="draigdestroymagic" type="draig" rank="2" level="10" index="139" parameters="kc+" los="true" ship="true" far="true" variable="true"> + <!-- Pentagramm --> + <resource name="aura" amount="10" cost="level"/> + </spell> + <spell name="deathcloud" type="draig" rank="5" level="11" index="111" far="true"> + <!-- Todeswolke --> + <resource name="aura" amount="40" cost="fixed"/> + <resource name="hp" amount="15" cost="fixed"/> + </spell> + <spell name="summondragon" type="draig" rank="5" level="11" index="113" far="true"> + <!-- Drachenruf --> + <resource name="aura" amount="80" cost="fixed"/> + <resource name="dragonhead" amount="1" cost="fixed"/> + </spell> + <spell name="summonshadowlords" type="draig" rank="5" level="12" index="35" variable="true"> + <!-- Beschw�re Schattenmeister --> + <resource name="aura" amount="7" cost="level"/> + </spell> + <spell name="create_firesword" type="draig" ship="true" rank="5" level="12" index="148"> + <!-- Erschaffe ein Flammenschwert --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="oil" amount="10" cost="fixed"/> + <resource name="sword" amount="1" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + <spell name="unholypower" type="draig" rank="5" level="14" index="169" parameters="u+" los="true" variable="true"> + <!-- Unheilige Kraft --> + <resource name="aura" amount="10" cost="level"/> + <resource name="peasant" amount="5" cost="level"/> + </spell> + <!-- end draig --> + + <!-- new cerddor --> + <spell name="earn_silver#cerddor" type="cerddor" ship="true" variable="true" rank="5" level="1" index="159"> + <!-- Gaukeleien --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="song_of_healing" type="cerddor" rank="5" level="2" index="10" variable="true" combat="3"> + <!-- Lied der Heilung --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="generous" type="cerddor" rank="5" level="2" index="87" ship="true" far="true" variable="true"> + <!-- Hohes Lied der Gaukelei --> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="song_of_fear" type="cerddor" rank="5" level="3" index="21" variable="true" combat="2"> + <!-- Gesang der Furcht --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="song_of_confusion" type="cerddor" rank="5" level="4" index="19" variable="true" combat="1"> + <!-- Gesang der Verwirrung --> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="blabbermouth" parameters="u" type="cerddor" los="true" rank="5" level="4" index="115"> + <!-- Plappermaul --> + <function name="cast" value="cast_babbler"/> + <resource name="aura" amount="10" cost="fixed"/> + <!-- missing syntactical info: ONETARGET | UNITSPELL --> + </spell> + <spell name="heroic_song" type="cerddor" rank="4" level="5" index="76" variable="true" combat="1"> + <!-- Heldengesang --> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="seduction" type="cerddor" rank="5" level="6" index="73" parameters="u" los="true"> + <!-- Lied der Verf�hrung --> + <resource name="aura" amount="12" cost="fixed"/> + </spell> + <spell name="calm_monster" type="cerddor" rank="5" level="6" index="75" parameters="u" los="true" ship="true"> + <!-- Monster friedlich stimmen --> + <resource name="aura" amount="15" cost="fixed"/> + </spell> + <spell name="bloodthirst" type="cerddor" rank="4" level="7" index="23" variable="true" combat="1"> + <!-- Kriegsgesang --> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="frighten" type="cerddor" rank="5" level="8" index="77" variable="true" combat="1"> + <!-- Gesang der Angst --> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="cerddor_destroymagic" type="cerddor" rank="2" level="8" index="141" parameters="kc+" los="true" ship="true" far="true" variable="true"> + <!-- Lebenslied festigen --> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="migration" type="cerddor" rank="5" level="9" index="90" parameters="u" los="true" variable="true"> + <!-- Ritual der Aufnahme --> + <resource name="aura" amount="3" cost="level"/> + <resource name="permaura" amount="1" cost="level"/> + </spell> + <spell name="raise_mob" type="cerddor" rank="5" level="10" index="60" variable="true"> + <!-- Mob aufwiegeln --> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="song_resist_magic" type="cerddor" rank="2" level="10" index="100" far="true" variable="true"> + <!-- Gesang des wachen Geistes --> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="create_roqf" type="cerddor" ship="true" rank="5" level="11" index="63"> + <!-- Miriams flinke Finger --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="20" cost="fixed"/> + <resource name="money" amount="1000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + <spell name="song_of_peace" type="cerddor" rank="5" level="12" index="89" variable="true"> + <!-- Gesang der Friedfertigkeit --> + <resource name="aura" amount="20" cost="level"/> + </spell> + <spell name="song_suscept_magic" type="cerddor" rank="2" level="12" index="101" far="true" variable="true"> + <!-- Gesang des schwachen Geistes --> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="song_of_slavery" type="cerddor" rank="5" level="13" index="123" parameters="u" los="true"> + <!-- Gesang der Versklavung --> + <resource name="aura" amount="40" cost="fixed"/> + </spell> +<!-- TODO: exploitable (transfers items) --> + <spell name="big_recruit" type="cerddor" rank="5" level="14" index="179" variable="true"> + <!-- Hohe Kunst der �berzeugung --> + <resource name="aura" amount="20" cost="level"/> + </spell> + <spell name="calm_riot" type="cerddor" rank="5" level="14" index="91" far="true"> + <!-- Aufruhr beschwichtigen --> + <resource name="aura" amount="30" cost="fixed"/> + </spell> + <spell name="incite_riot" type="cerddor" rank="5" level="15" index="92" far="true"> + <!-- Aufruhr verursachen --> + <resource name="aura" amount="40" cost="fixed"/> + </spell> + <!-- end cerddor --> + + <!-- new gwyrrd --> + <spell name="blessedharvest" type="gwyrrd" rank="5" level="3" index="25" ship="true" far="true" variable="true"> + <!-- Segen der Erde --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="earn_silver#gwyrrd" type="gwyrrd" ship="true" variable="true" rank="5" level="1" index="159"> + <!-- Viehheilung --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="stonegolem" type="gwyrrd" rank="4" level="20" index="32" variable="true"> + <!-- Erschaffe Steingolems --> + <resource name="aura" amount="2" cost="level"/> + <resource name="stone" amount="1" cost="level"/> + <resource name="jewel" amount="10" cost="fixed"/> + </spell> + <spell name="treegrow" type="gwyrrd" rank="5" level="2" index="8" far="true" variable="true"> + <!-- Hainzauber --> + <resource name="aura" amount="4" cost="level"/> + <resource name="log" amount="1" cost="level"/> + <resource name="myrrh" amount="10" cost="fixed"/> + </spell> + <spell name="hail" type="gwyrrd" rank="5" level="3" index="5" variable="true" combat="2"> + <!-- Hagel --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="goodwinds" type="common" rank="5" level="4" index="56" parameters="s" ship="true" variable="true"> + <!-- Beschw�rung eines Wasserelementares --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="windshield" type="gwyrrd" rank="5" level="4" index="59" variable="true" combat="1"> + <!-- Windschild --> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="healing" type="gwyrrd" rank="5" level="5" index="9" variable="true" combat="3"> + <!-- Heilung --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="earthquake" type="gwyrrd" rank="5" level="6" index="53" far="true"> + <!-- Beschw�re einen Erdelementar --> + <resource name="aura" amount="25" cost="fixed"/> + <resource name="laen" amount="2" cost="fixed"/> + </spell> + <spell name="stormwinds" type="gwyrrd" rank="5" level="6" index="55" parameters="s+" ship="true" ocean="true" variable="true"> + <!-- Beschw�re einen Sturmelementar --> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="wolfhowl" type="gwyrrd" rank="5" level="7" index="94" variable="true" combat="1"> + <!-- Wolfsgeheul --> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="versteinern" type="gwyrrd" rank="5" level="8" index="67" variable="true" combat="2"> + <!-- Blick des Basilisken --> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="gwyrrddestroymagic" type="gwyrrd" rank="2" level="8" index="138" parameters="kc+" los="true" ship="true" far="true" variable="true"> + <!-- Geister bannen --> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="holyground" type="gwyrrd" rank="5" level="9" index="170"> + <!-- Heiliger Boden --> + <resource name="aura" amount="80" cost="fixed"/> + <resource name="permaura" amount="3" cost="fixed"/> + </spell> + <spell name="summonent" type="gwyrrd" rank="5" level="10" index="49" variable="true"> + <!-- Erwecke Ents --> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="blessstonecircle" type="gwyrrd" rank="5" level="11" index="117" parameters="b"> + <!-- Segne Steinkreis --> + <resource name="aura" amount="350" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="barkskin" type="gwyrrd" rank="2" level="12" index="142" variable="true" combat="1"> + <!-- Rindenhaut --> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="summonfireelemental" type="gwyrrd" rank="5" level="13" index="46" far="true"> + <!-- Beschw�rung eines Hitzeelementar --> + <resource name="aura" amount="600" cost="fixed"/> + </spell> + <spell name="maelstrom" type="gwyrrd" rank="5" level="15" index="24" ship="true" ocean="true"> + <!-- Mahlstrom --> + <resource name="aura" amount="200" cost="fixed"/> + <resource name="seaserpenthead" amount="1" cost="fixed"/> + </spell> + <!-- end gwyrrd --> + + <!-- new tybied - spells known to all schools --> + <spell name="create_potion_p2" type="tybied" ship="true" rank="5" level="2" variable="true"> + <!-- Wasser des Lebens --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="2" cost="linear"/> + <resource name="h4" amount="1" cost="linear"/><!-- Baumringel --> + <resource name="h6" amount="1" cost="linear"/><!-- Gurgelkraut --> + </spell> + <spell name="create_potion_p0" type="tybied" ship="true" rank="5" level="3" variable="true"> + <!-- Siebenmeilentee --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="2" cost="linear"/> + <resource name="h12" amount="1" cost="linear"/><!-- Windbeutel --> + <resource name="h17" amount="1" cost="linear"/><!-- H�hlenglimm --> + </spell> + <spell name="create_potion_p9" type="tybied" ship="true" rank="5" level="4" variable="true"> + <!-- Pferdegl�ck --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="3" cost="linear"/> + <resource name="h0" amount="1" cost="linear"/><!-- Flachwurz --> + <resource name="h8" amount="1" cost="linear"/><!-- Blasenmorchel --> + <resource name="h15" amount="1" cost="linear"/><!-- Steinbei�er --> + </spell> + <spell name="create_potion_peasantblood" type="tybied" ship="true" rank="5" level="5" variable="true"> + <!-- Bauernblut --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="3" cost="linear"/> + <resource name="h14" amount="1" cost="linear"/><!-- Alraune --> + <resource name="h6" amount="1" cost="linear"/><!-- Gurgelkraut --> + <resource name="h17" amount="1" cost="linear"/><!-- H�hlenglimm --> + <resource name="peasant" amount="1" cost="fixed"/><!-- Bauer --> + </spell> + + <spell name="create_potion_ointment" type="tybied" ship="true" rank="5" level="6" variable="true"> + <!-- Wundsalbe --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="4" cost="linear"/> + <resource name="h4" amount="1" cost="linear"/><!-- Baumringel --> + <resource name="h15" amount="1" cost="linear"/><!-- Steinbei�er --> + <resource name="h18" amount="1" cost="linear"/><!-- Eisblume --> + <resource name="h11" amount="1" cost="linear"/><!-- Sandf�ule --> + </spell> + <spell name="create_potion_p3" type="tybied" ship="true" rank="5" level="7" variable="true"> + <!-- Schaffenstrunk --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="4" cost="linear"/> + <resource name="h12" amount="1" cost="linear"/><!-- Windbeutel --> + <resource name="h6" amount="1" cost="linear"/><!-- Gurgelkraut --> + <resource name="h20" amount="1" cost="linear"/><!-- Schneekristall --> + <resource name="h9" amount="1" cost="linear"/><!-- Wasserfinder --> + </spell> + <spell name="create_potion_p14" type="tybied" ship="true" rank="5" level="8" variable="true"> + <!-- Heiltrank --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="5" cost="linear"/> + <resource name="h0" amount="1" cost="linear"/><!-- Flachwurz --> + <resource name="h8" amount="1" cost="linear"/><!-- Blasenmorchel --> + <resource name="h15" amount="1" cost="linear"/><!-- Steinbei�er --> + <resource name="h18" amount="1" cost="linear"/><!-- Eisblume --> + <resource name="h9" amount="1" cost="linear"/><!-- Wasserfinder --> + </spell> + <spell name="create_potion_p13" type="tybied" ship="true" rank="5" level="9" variable="true"> + <!-- Elixier der Macht --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="5" cost="linear"/> + <resource name="h14" amount="1" cost="linear"/><!-- Alraune --> + <resource name="h8" amount="1" cost="linear"/><!-- Blasenmorchel --> + <resource name="h17" amount="1" cost="linear"/><!-- H�hlenglimm --> + <resource name="h20" amount="1" cost="linear"/><!-- Schneekristall --> + <resource name="h11" amount="1" cost="linear"/><!-- Sandf�ule --> + <resource name="dragonblood" amount="1" cost="fixed"/><!-- Drachenblut --> + </spell> + + <spell name="create_roi" type="tybied" ship="true" rank="5" level="7" index="130"> + <!-- Erschaffe einen Ring der Unsichtbarkeit --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + <spell name="create_aots" type="tybied" ship="true" rank="5" level="6" index="125"> + <!-- Erschaffe ein Amulett des wahren Sehens --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + <spell name="auratransfer" type="tybied" rank="1" level="5" index="31" syntax="aura" parameters="ui" ship="true"> + <!-- Auratransfer --> + <resource name="aura" amount="1" cost="fixed"/> + </spell> + <!-- end tybied --> + + <!-- common spells: randomly given, one per level --> + <spell name="create_trollbelt" type="common" ship="true" rank="5" level="9" index="48"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="20" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="create_antimagic" type="common" ship="true" rank="5" level="7" index="38"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + </spell> + + <spell name="create_rop" type="common" ship="true" rank="5" level="9" index="1"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + <resource name="money" amount="4000" cost="fixed"/> + </spell> + + <spell name="create_bagofholding" type="common" ship="true" rank="5" level="10" index="155"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="30" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + <resource name="money" amount="5000" cost="fixed"/> + </spell> + + <spell name="create_focus" type="common" ship="true" rank="5" level="9" index="2"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="create_ror" type="common" ship="true" rank="5" level="9" index="3"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="rustweapon" type="gwyrrd" rank="5" level="3" index="6" parameters="u+" los="true" far="true" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="plague" type="common" rank="5" level="7" index="16" far="true"> + <resource name="aura" amount="30" cost="fixed"/> + <resource name="peasant" amount="50" cost="fixed"/> + </spell> + <spell name="raindance" type="common" rank="5" level="2" index="26" ship="true" far="true" variable="true"> + <!-- Regentanz --> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="irongolem" type="common" rank="4" level="2" index="33" variable="true"> + <!-- Eisengolem --> + <resource name="aura" amount="2" cost="level"/> + <resource name="iron" amount="1" cost="level"/> + <resource name="incense" amount="1" cost="fixed"/> + </spell> + <spell name="reelingarrows" type="common" rank="5" level="5" index="36" variable="true" combat="1"> + <!-- Wirbelwind --> + <resource name="aura" amount="15" cost="fixed"/> + </spell> + <spell name="antimagiczone" type="common" rank="2" level="5" index="37" far="true" variable="true"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="steal_aura" type="common" rank="3" level="6" index="40" parameters="u" los="true" far="true" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="auraleak" type="common" rank="3" level="9" index="42"> + <resource name="aura" amount="35" cost="fixed"/> + <resource name="dragonblood" amount="1" cost="fixed"/> + </spell> + <spell name="strongwall" type="common" rank="5" level="8" index="44" variable="true" combat="1"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="homestone" type="common" rank="5" level="7" index="45"> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + <spell name="forestfire" type="common" rank="5" level="10" index="47" far="true"> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="oil" amount="5" cost="fixed"/> + </spell> + <spell name="disturbingdreams" type="common" rank="5" level="6" index="50" far="true"> + <resource name="aura" amount="18" cost="fixed"/> + </spell> + <spell name="appeasement" type="common" rank="5" level="1" index="51" variable="true" combat="1"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="ironkeeper" type="common" rank="5" level="3" index="54" far="true" variable="true"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="airship" type="common" rank="5" level="6" index="57" parameters="s" ship="true"> + <resource name="aura" amount="10" cost="fixed"/> + <resource name="h12" amount="1" cost="fixed"/> + <resource name="h20" amount="1" cost="fixed"/> + </spell> + <spell name="sound_out" type="common" rank="5" level="7" index="74" parameters="ur" los="true"> + <resource name="aura" amount="4" cost="fixed"/> + <resource name="money" amount="100" cost="fixed"/> + </spell> + <spell name="combat_speed" type="common" rank="5" level="9" index="79" variable="true" combat="1"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="double_time" type="common" rank="5" level="11" index="80" parameters="u+" los="true" ship="true" variable="true"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="magicstreet" type="common" rank="5" level="4" index="84" ship="true" far="true" variable="true"> + <resource name="aura" amount="1" cost="level"/> + <resource name="stone" amount="1" cost="fixed"/> + <resource name="log" amount="1" cost="fixed"/> + </spell> + <spell name="sacrifice_strength" type="common" rank="1" level="15" index="88" syntax="aura" parameters="ui"> + <resource name="aura" amount="100" cost="fixed"/> + </spell> + <spell name="resist_magic" type="common" rank="2" level="3" index="97" parameters="u+" los="true" ship="true" variable="true"> + <!-- Schutzzauber --> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="protective_runes" type="common" rank="2" level="8" index="99" parameters="kc" ship="true"> + <resource name="aura" amount="20" cost="fixed"/> + </spell> + <spell name="analyze_magic" type="common" rank="5" level="1" index="102" parameters="kc?" los="true" ship="true" variable="true"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="destroy_magic" type="common" rank="2" level="5" index="106" parameters="kc+" los="true" ship="true" far="true" variable="true"> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="break_curse" type="common" rank="3" level="7" index="107" syntax="spellid" parameters="kcc?" los="true" ship="true" far="true" variable="true"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="fish_shield" type="common" rank="2" level="8" index="109" variable="true" combat="1"> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="armor_shield" type="common" rank="2" level="12" index="110" variable="true" combat="1"> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="living_rock" type="common" rank="5" level="13" index="116" syntax="direction" parameters="bc" variable="true"> + <resource name="aura" amount="10" cost="level"/> + <resource name="permaura" amount="1" cost="fixed"/> + <resource name="laen" amount="5" cost="fixed"/> + </spell> + <spell name="commonfamiliar" type="common" rank="5" level="9" index="118"> + <function name="cast" value="cast_familiar"/> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="gwyrrdfamiliar" type="common" rank="5" level="10" index="119"> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="draigfamiliar" type="common" rank="5" level="13" index="120"> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="summon_familiar" type="cerddor" rank="5" level="9" index="121"> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="summon_familiar" type="common" rank="5" level="12" index="122"> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="draigfumbleshield" type="common" rank="2" level="9" index="143" variable="true" combat="1"> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="gwyrrdfumbleshield" type="common" rank="2" level="5" index="144" variable="true" combat="1"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="cerrdorfumbleshield" type="common" rank="2" level="5" index="145" variable="true" combat="1"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="tybiedfumbleshield" type="common" rank="2" level="2" index="146" variable="true" combat="1"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="concealing_aura" type="common" rank="5" level="1" index="150" parameters="u" ship="true" variable="true"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="shockwave" type="common" rank="5" level="5" index="163" variable="true" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="eternal_walls" type="common" rank="5" level="7" index="167" parameters="b" ship="true" variable="true"> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + <!-- end common spells --> + + <!-- gray spells: given to individuals or monsters --> + <spell name="fiery_dragonbreath" type="gray" rank="5" level="3" index="81" combat="2"> + <resource name="aura" amount="1" cost="fixed"/> + </spell> + <spell name="icy_dragonbreath" type="gray" rank="5" level="6" index="82" combat="2"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="powerful_dragonbreath" type="gray" rank="5" level="12" index="83" combat="2"> + <resource name="aura" amount="3" cost="fixed"/> + </spell> + <spell name="meteor_rain" type="gray" rank="5" level="3" index="108" variable="true" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="wyrm_transformation" type="gray" rank="5" level="1" index="166"> + <resource name="aura" amount="1" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + <spell name="transferauratraum" type="gray" rank="1" level="3" index="30" syntax="aura" parameters="ui" ship="true"> + <!-- Traum der Magie --> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="drain_skills" type="gray" rank="5" level="12" index="174" combat="2"> + <resource name="aura" amount="4" cost="fixed"/> + </spell> + <spell name="aura_of_fear" type="gray" rank="5" level="12" index="175" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="shadowcall" type="gray" rank="5" level="12" index="176" combat="1"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="immolation" type="gray" rank="5" level="12" index="180" combat="2"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="firestorm" type="gray" rank="5" level="8" index="181" combat="2"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="coldfront" type="gray" rank="5" level="8" index="182" combat="2"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="acidrain" type="gray" rank="5" level="8" index="183" combat="2"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <!-- end gray spells --> +</spells> diff --git a/res/e3a/strings.xml b/res/e3a/strings.xml index 3e4c3e9d1..c59f183f7 100644 --- a/res/e3a/strings.xml +++ b/res/e3a/strings.xml @@ -1,335 +1,335 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<strings> - <!-- - _d: dativ (wir erkl�ren allen /Trollen/ den Krieg) - _p: plural (13 /Trolle/) - _x: preposition (15 /Troll/schwerter) - _a: including article (ein Troll, a troll) - --> - - <!--Fort-Ausbaustufen --> - <string name="calendar::thirdage"> - <text locale="de">des dritten Zeitalters</text> - <text locale="en">the third age</text> - </string> - - <string name="rpg_item_1_p"> - <text locale="de">Urkunden</text> - <text locale="en">Certificates</text> - </string> - <string name="rpg_item_2_p"> - <text locale="de">Nu�h�lften</text> - <text locale="en">nut halves</text> - </string> - <string name="rpg_item_3_p"> - <text locale="de">Flaschengeister</text> - <text locale="en">bottle demons</text> - </string> - <string name="rpg_item_1"> - <text locale="de">Pandoras Urkunde f�r Halbling ehrenhalber, weiblich</text> - <text locale="en">Pandora's Certificate</text> - </string> - <string name="rpg_item_2"> - <text locale="de">Heilige Nu�h�lfte</text> - <text locale="en">piece of a holy nut</text> - </string> - <string name="rpg_item_3"> - <text locale="de">Flaschengeist Zhardamon</text> - <text locale="en">bottle demon Zhardamon</text> - </string> - - <string name="rep_crossbow"> - <text locale="de">Repetierarmbrust</text> - <text locale="en">repeating crossbow</text> - </string> - <string name="rep_crossbow_p"> - <text locale="de">Repetierarmbr�ste</text> - <text locale="en">repeating crossbows</text> - </string> - - <string name="scaffolding"> - <text locale="de">Ger�st</text> - <text locale="en">scaffolding</text> - </string> - <string name="guardhouse"> - <text locale="de">Wachstube</text> - <text locale="en">guard house</text> - </string> - <string name="guardtower"> - <text locale="de">Wachturm</text> - <text locale="en">guard tower</text> - </string> - <string name="watch"> - <text locale="de">Wache</text> - <text locale="en">watch</text> - </string> - <string name="market"> - <text locale="de">Marktplatz</text> - <text locale="en">marketplace</text> - </string> - - <namespace name="morale"> - <string name="0"> - <text locale="de">aufst�ndische</text> - <text locale="en">rebellious</text> - </string> - <string name="1"> - <text locale="de">w�tende</text> - <text locale="en">mad</text> - </string> - <string name="2"> - <text locale="de">zornige</text> - <text locale="en">angry</text> - </string> - <string name="3"> - <text locale="de">unruhige</text> - <text locale="en">agitated</text> - </string> - <string name="4"> - <text locale="de">gleichg�ltige</text> - <text locale="en">indifferent</text> - </string> - <string name="5"> - <text locale="de">entspannte</text> - <text locale="en">relaxed</text> - </string> - <string name="6"> - <text locale="de">zufriedene</text> - <text locale="en">content</text> - </string> - <string name="7"> - <text locale="de">gl�ckliche</text> - <text locale="en">happy</text> - </string> - <string name="8"> - <text locale="de">treue</text> - <text locale="en">loyal</text> - </string> - <string name="9"> - <text locale="de">ergebene</text> - <text locale="en">devoted</text> - </string> - <string name="10"> - <text locale="de">unterw�rfige</text> - <text locale="en">subservient</text> - </string> - </namespace> - <string name="charger"> - <text locale="de">Streitross</text> - <text locale="en">charger</text> - </string> - <string name="charger_p"> - <text locale="de">Streitr�sser</text> - <text locale="en">chargers</text> - </string> - <string name="towershield"> - <text locale="de">Turmschild</text> - <text locale="en">tower shield</text> - </string> - <string name="towershield_p"> - <text locale="de">Turmschilde</text> - <text locale="en">tower shields</text> - </string> - - <namespace name="spell"> - <string name="create_potion_p0"> - <text locale="de">Braue Siebenmeilentee</text> - <text locale="en">brew seven mile tea</text> - </string> - <string name="create_potion_p2"> - <text locale="de">Braue Wasser des Lebens</text> - <text locale="en">brew water of life</text> - </string> - <string name="create_potion_p3"> - <text locale="de">Braue Schaffenstrunk</text> - <text locale="en">brew busy beer</text> - </string> - <string name="create_potion_ointment"> - <text locale="de">Braue Wundsalbe</text> - <text locale="en">brew ointment</text> - </string> - <string name="create_potion_peasantblood"> - <text locale="de">Braue Bauernblut</text> - <text locale="en">brew peasant blood</text> - </string> - <string name="create_potion_p9"> - <text locale="de">Braue Pferdegl�ck</text> - <text locale="en">brew horsepower potion</text> - </string> - <string name="create_potion_p13"> - <text locale="de">Braue Elixier der Macht</text> - <text locale="en">brew elixir of power</text> - </string> - <string name="create_potion_p14"> - <text locale="de">Braue Heiltrank</text> - <text locale="en">brew healing potion</text> - </string> - </namespace> - - <namespace name="spellinfo"> - <string name="raindance"> - <text locale="de">Durch dieses uralte Tanzritual ruft der Zauberkundige - die Kr�fte des Lebens und der Fruchtbarkeit an. Die darauf folgenden - Regenf�lle beg�nstigen das Wachstum und erh�hen die Ernteertr�ge - einiger Bauern der Region bis der Regen wieder nachl�sst.</text> - <text locale="en">This ancient rite calls upon the - forces of life and fertility. For the next few weeks, - the peasant's harvest will be extraordinary good. - (OBS: this spell has been changed and needs a new translation).</text> - </string> - <string name="blessedharvest"> - <text locale="de">F�r dieses Ernteritual sendet der Druide seine arkane Energie entlang - der astralen Kraftlinien der gesamten Umgebung, um selbst weit entfernte - Naturgeister zu erreichen. Die Beschw�rung dieser Naturgeister ist eine - hohe Kunst, die h�chste Konzentration und vor allem viel Erfahrung - erfordert. Die Bauern werden nach und nach von den besseren Ernten - profitieren und ihre Ersparnisse steigern k�nnen.</text> - <text locale="en">This ritual increases the output of the local farms. - Peasants in the region produce an extra silverpiece. The stronger the - druid's spell is, the longer the effect will last. - (OBS: this spell has been changed and needs a new translation).</text> - </string> - <string name="earn_silver#draig"> - <text locale="de">In den dunkleren Gassen gibt es sie, - die Fl�che und Verhexungen auf Bestellung. Aber - auch Gegenzauber hat der J�nger des Draigs - nat�rlich im Angebot. Ob nun der Sohn des - Nachbarn in einen Liebesbann gezogen werden soll - oder die Nebenbuhlerin Pickel und Warzen - bekommen soll, niemand gibt gerne zu, zu solchen - Mitteln gegriffen zu haben. F�r diese - Dienstleistung streicht der Magier 25 Silber pro - Stufe ein.</text> - <text locale="en">In the dark alleys you can find those - who sell curses and hexes on demand - but you - can buy the apropriate counterspells from the - followers of Draig as well. May it be a love - spell for the son of a neighbour or a wart in - the face of a rival. For offering these - services, the sorcerer charges 25 silver pieces. - per level.</text> - </string> - <string name="earn_silver#illaun"> - <text locale="fr">Personne n'interpr�te aussi bien les - r�ves que les mages d'Illaun. Ils sont �galement - vers�s dans l'utilisation des objets utilis�s - pour pr�dire le futur comme les boules de - cristal, les cartes de tarot ou les lignes de la - main. Un mentaliste peut gagner 25 �cus par - niveau et par semaine en proposant ses services - aux paysans.</text> - <text locale="de">Niemand kann so gut die Tr�ume deuten - wie ein Magier des Illaun. Auch die Kunst der - Wahrsagerei, des Kartenlegens und des Handlesens - sind ihm gel�ufig. Daf�r zahlen ihm die Bauern - 25 Silber pro Stufe.</text> - <text locale="en">No one can read dreams as well as the - mages of Illaun. Furthermore, they are also - familiar with all other common means of - foretelling the future like crystal balls, tarot - cards or palms. A mentalist can earn 25 silver - pieces per level and week for offering these - services to peasants.</text> - </string> - <string name="earn_silver#tybied"> - <text locale="de">Wenn einem der Alchemist nicht weiterhelfen kann, geht man zu dem - gelehrten Tybiedmagier. Seine Tr�nke und Tinkturen helfen gegen - alles, was man sonst nicht bekommen kann. Ob nun die kryptische - Formel unter dem Holzschuh des untreuen Ehemannes wirklich geholfen - hat - nun, der des Lesens nicht m�chtige Bauer wird es nie wissen. - Dem Magier hilft es auf jeden Fall... beim F�llen seines - Geldbeutels. 25 Silber pro Stufe lassen sich so in einer Woche - verdienen.</text> - <text locale="en">If the local alchemist could not help you, you should visit a - scholar of Tybied. His potions and tinctures may help when nothing - else does. If the cryptic formula under the wooden shoes of the - unfaithful husband really helped? - well, the peasant, who isn't - capable of reading, will never know. At least it helped the magician... - to fill his purse. In one week he can earn 25 silver per level that - way.</text> - </string> - <string name="earn_silver#cerddor"> - <text locale="de">Cerddormagier sind _die_ Gaukler unter - den Magiern, sie lieben es das Volk zu unterhalten und - im Mittelpunkt zu stehen. Schon Anf�nger lernen die - kleinen Kunstst�cke und magischen Tricks, mit denen man - das Volk locken und verf�hren kann, den Geldbeutel ganz - weit zu �ffnen, und am Ende der Woche wird der Gaukler - 25 Silber pro Stufe verdient haben.</text> - <text locale="en">The mages of Cerddor truly are the - bards of the wizards; they love to use their sorcery to - entertain the crowds and to be the center of attention. - Even the apprentices study those little magic tricks, - which attract and fascinate the people and thus ensnare - them into leaving a few coins or more for the artist. By - the end of the week, the bard will have earned 25 silver - per level. </text> - </string> - <string name="earn_silver#gwyrrd"> - <text locale="de">Die F�higkeiten der Gwyrrd-Magier in - der Viehzucht und Heilung sind bei den Bauern sehr - begehrt. Gerade auf M�rkten sind ihre Dienste h�ufig sehr - gefragt. Manch einer mag auch sein Talent dazu nutzen, - ein Tier f�r einen besseren Preis zu verkaufen. Pro - Stufe kann der Magier so 25 Silber verdienen.</text> - <text locale="en">The abilities of the mages of Gwyrrd - concerning the breeding and healing of cattle are highly - appreciated among the peasants. Especially at the - markets, their services are demanded frequently. Some of - them also use their talents to sell an animal at a - higher price. A magician can earn 25 silver pieces per level - in this way.</text> - </string> - <string name="create_potion_p0"> - <text locale="en">Time is one of the first mysteries every magician tries to solve. If he succeeds, he can focus all his energies on his magical studies as the ways between dormatory, library and magician tower now pass much faster. To keep his heart in tune the magician uses a special self made tey. Some mages even share it with up to 10 people</text> - <text locale="de">Die Zeit ist eines der ersten Geheimnisse, die jeder Magier zu erkunden versucht. Gelingt ihm dies, kann er alle seine Energie auf das Studium der Magie verwenden, die Wege zwischen Dormitorium, Bibliothek und Magierturm schafft er nun viel schneller. Um sein Herz im Takt zu halten verwendet er einen speziellen selbstgemachten Tee. Manche Magier teilen diesen Tee mit bis zu 10 Personen. </text> - </string> - <string name="create_potion_p2"> - <text locale="en">One of the most strange spells enables the magician to withdraw a little life energy from his surroundings to produce the so called water of life. The juice of some selected herbs is used to conserve the energies of life. As the magician is protected by his magical abilities, he is the only one who can touch the juice without taking damage. This is necessary because the juice must be carried around from place to place to avoid damaging one region by taking too much energy at once.</text> - <text locale="de">In einem der seltsamsten Zauber kann der Magier seiner Umgebung ein klein wenig der Lebensenergie entziehen um das sogenannte Wasser des Lebens herstellen. Als Basis dient ihm hierbei der Saft aus einigen ausgesuchten Kr�utern, welcher die Lebensenergie speichern kann. Da der Magier aufgrund seiner magischen F�higkeiten immun ist, ist er der einzige, der den Saft ber�hren kann, ohne Schaden zu nehmen. Sodenn mu� er diesen eine Woche lang von Ort zu Ort tragen, damit er sich mit Lebensenergie vollsaugt, ohne einem einzelnen Ort soviel zu entfernen, da� er Schaden nimmt. </text> - </string> - <string name="create_potion_p3"> - <text locale="en">Busybeer is another application for the knowledge about time a magician accumulates. Even though manual labour is only seldom done by mages, they still show interest in increasing the efficiency of their minions that do this work for them. Mornac the wise was the first to discover how to produce a potion that would enable 10 minions to do the work of 20, thus freeing the other 10 for different experiments.</text> - <text locale="de">Ein weiteres Anwendungsgebiet des Wissens �ber die Zeit welches ein Magier ansammelt stellt der Schaffenstrunk dar. Auch wenn k�rperliche Arbeiten eher selten von Magiern ausgef�hrt werden, so haben diese doch ein Interesse daran, die Effizienz ihrer Untergebenen bei solchen Arbeiten zu steigern. Mornac der Weise war der erste, der entdeckte, da� man einen Trunk herstellen kann, durch den 10 Untergebene die arbeit von 20 erledigen k�nnen, wodurch 10 f�r andere Experimente weiterverwendet werden konnten. </text> - </string> - <string name="create_potion_ointment"> - <text locale="en">In the aftermath of battle it is vital to heal your own troops. This can be done by a healer as well as by a magician. In contrast to a healer, the magician can fullfill his treatment already before the battle by binding his magical powers into a potent salve. This salve can be stored and only needs to be applied to the wounds after the battle. </text> - <text locale="de">Nach einem harten Kampf sollte man sich heilen lassen. Diese M�glichkeit bietet der Magier ebenso wie der Heiler. Im Gegensatz zum Heiler ist der Magier jedoch in der Lage, seine Behandlung bereits vor dem Kampf durchzuf�hren, indem er seine Heilkr�fte in eine magische Salbe bindet, welche gelagert werden kann und nach dem Kampf nur aufgetragen werden mu�.</text> - </string> - <string name="create_potion_peasantblood"> - <text locale="en">One of the most dangerous and best guarded secrets of all mages is the knowledge about the power of death. Even though most of them would not openly admit it, and it is at least partially forbidden in most countries, each of them studies death sooner or later. When they do, they quickly find out that there is another plane of existance, the home of the demons. Only blood can quelch the thirst of those, when they switch from their home to our world. But experienced mages will find out that the demons bloodwine can be deluted when apropiate herbs are included, making it enough for 100 instead of 10 demons. As the demons may not know about that, the magician has to secretly sacrifice one of his freed minions.</text> - <text locale="de">Zu den gef�hrlichsten und geheimsten Wissen der Magier z�hlt das Wissen �ber die Macht des Todes. Auch wenn die meisten es nicht zugeben, so fasziniert dieses Thema jeden Magier. Fr�her oder sp�ter besch�ftigen sich alle mit diesem, teiweise verbotenen, Gebiet. Sodann werden sie feststellen, das es noch eine weitere Ebene der Existenz gibt, in der die D�monen beheimatet sind. Nur Blut allein vermag den Hunger dieser Wesen zu befriedigen, wenn sie ihre Ebene verlassen und unsere betreten. Erfahrene Magier werden jedoch feststellen, dass man den Blutwein, den die D�monen zu sich nehmen strecken kann, so da� davon 100 anstatt nur 10 D�monen satt werden. Da die D�monen davon jedoch nichts wissen d�rfen, mu� der Magier selbst klammheimlich einen seiner urpl�tzlich verf�gbar gewordenen Untergebenen opfern. </text> - </string> - <string name="create_potion_p9"> - <text locale="en">Even though mages live in strict cellibate they know a lot about creating certain longings. Peasants keep asking them for this love potion or that. But the penality for bewitching a peasant is death, so the mages offer their services only to farmers for their breeding stock. In an elaborate ritual, which only serves to hide the simplicity of the procedure, the magician draws the fluids from certains plants. while doing so, he calls upon the spirits of fertility which of course only listen when he talkes to them. Now the farmer knows that any attempt to draw the fluids himself will only result in a useless waste of resorces. Finally, the magician hands the vial with the fluids to the farmer, who pours it into his horses drinking water.</text> - <text locale="de">Obwohl f�r Magier das Gebiet der Liebe Tabu ist und sie im strengen Z�libat leben, haben sie ein gro�es Wissen dar�ber, wie man gewisse Bed�rfnisse weckt, weshalb sie immer wieder von Dorfbewohnerinnen und Dorfbewohnern nach entsprechenden Zaubern gefragt werden. Da die Verzauberung eines Bewohners jedoch streng verboten ist, bieten sie ihre Dienste nur f�r die Z�chter an. In einem Aufwendigen Ritual, welches jedoch nur dazu dient zu verschleiern, wie einfach dies eigentlich ist, vermischt der Magier vor den Augen des Z�chters einige Pflanzens�fte. Dabei ruft er die Geister an die dem Pferdez�chter das Gl�ck bescheren sollen, um klarzumachen, das diese nur mit ihm sprechen und jeglicher Versuch des Z�chters, selbst die Kr�uter zu mischen nur eine unbrauchbare Pampe produzieren w�rde. Anschlie�end �berreicht der Magier dem Z�chter eine Phiole, die dieser in die Tr�nke seiner Pferde entleeren mu�.</text> - </string> - <string name="create_potion_p13"> - <text locale="en">Just like with the knowledge about death, the peasants feel uncomfortable with the knowledge about monsters. A few warriors though, who have already faced these creatures in combat, foud that the monsters blood had en invigourating effect on them. There is talk about some warriors, who bathed in the blood of the slain monsters to take up their strenght. But this effect ends soon, and only occurs with fresh blood. As no one has time to quickly slay a wyrm before attacking his neighbors, a way had to be found to make the effect last longer. After lots of experiments that cost the life of lots of good warriors who had to constantly bring in fresh dragon blood, Manasouf the black finally found a way. Originally a closely guarded secret, the recipe is now knows in all lands. First, the hardened dragon blood needs to be melted in hot tin. After that, the magician binds the spirit of the dragon to its blood once again. It can not fnd eternal rest until the last bit of blood has been used. </text> - <text locale="de">Ebenso wie das Wissen �ber den Tod ist das Wissen �ber gewisse Monster bei der abergl�ubigen Bev�lkerung nicht gerne gesehen. Einige wenige Krieger jedoch, die diesen Kreaturen schon mal im Kampf gegen�berstanden haben entdeckt, da� deren Blut eine belebende Wirkung auf sie hatte. So solle es schon Kriger gegeben haben, die im Blut der erschlagenen Monster badeten, um deren St�rke in sich aufzunehmen. Diese Wirkung verfliegt jedoch rasch, und wirkt nur bei frischen Blut. Da niemand vor dem Kampf gegen seinen Nachbarn die Zeit hat, schnell noch einen Wyrm zu erschlagen musste ein Weg gefunden werden, die Wirkung haltbar zu machen. Manasouf dem schwarzen gelang dies nach zahlreichen Experimenten, die das Leben vieler guter M�nner kosteten, welche st�ndig neues Drachenblut f�r seine Versuche beschaffen mussten. Urspr�nglich ein streng geh�tetes Geheimnis, ist das Rezept inzwischen im ganzen Land bekannt. Zun�chst mu� geronnene Drachenblut mu� in einem Tiegel wieder verfl�ssigt werden. Anschlie�end wird der Geist des erschlagenen Drachen in der Geisterebene wieder an sein Blut gebunden, und kann solange nicht in frieden ruhen, bis das letzte bisschen seines Blutes verbraucht wurde.</text> - </string> - <string name="create_potion_p14"> - <text locale="en">Some mages research deth's secrets until they can bring the dead back to life. But those who are brought back are often only shadows of ther former self and turn against their erstwhile friends. But those mages that study life and its iteraction with death find a possibility, to bring the deceased back as their original selves. A drawback is that this is only possible in the very first minutes after the death. As even mages can not be everywhere at the same time, a way had to be found to give this ability to helpers. All healers who tried to learn this from the mages failed, though, until one of those healers was backstabbingly killed. In the moment of his death he used the knowledge gained and was able to have his murderer executed the following day. The potion he designed has to be blessed by a magician before usage at any given time. This potion gives 4 people (or 1 person 4 times) a 50% chance to survive an otherwise deadly wound. It is used automatically by the victom.</text> - <text locale="de">Manche Magier erforschen den Tod, bis sie verstorbene wieder ins Leben zur�ck bringen k�nnen. Diese sind jedoch meist b�sartig und nur noch Schatten ihres fr�heren selbst. Diejenigen jedoch, die sich intensiv mit dem Leben und seiner Kombination mit dem Tod besch�ftigen finden eine M�glichkeit, verstorbene in ihrer wahren Gestallt zur�ck zu rufen. Dies ist allerdings nur wenige Minuten nach dem Tod m�glich. Da selbst Magier nicht �berall gleichzeitig sein k�nnen, musste ein Weg gefunden werden, diese F�higkeit auf andere zu �bertragen. Alle Versuche, dies feldschern beizubringen scheiterten jedoch, bis einer dieser Felschner von einem Widersacher hinterr�cks ermordet wurde. Im Moment seines Todes wandte er sein erworbenes Wissen an und konnte tags darauf den �belt�ter wegen Mordes hinrichten lassen. Der von ihm entwickelte magische Trank mu� jedoch von einem der Magie des Lebens kundigen gesegnet werden, um seine volle Wirkung zu entfalten. Ein solcher Trank gibt vier M�nnern (oder einem Mann vier mal) im Kampf eine Chance von 50%, sonst t�dliche Wunden zu �berleben. Der Trank wird von ihnen automatisch bei Verletzung angewandt.</text> - </string> - </namespace> - - <namespace name="spell"> - <string name="commonfamiliar"> - <text locale="de">Vertrauten binden</text> - <text locale="en">Bind Familiar</text> - </string> - </namespace> - <namespace name="spellinfo"> - <string name="commonfamiliar"> - <text locale="de">Einem erfahrenen Magier wird - irgendwann auf seinen Wanderungen ein - ungew�hnliches Exemplar einer Gattung begegnen, - welches sich dem Magier anschlie�en wird.</text> - <text locale="en">During their travel, seasoned - magicians will occasionally befriend an extraordinary - creature of an unusual species that will join them.</text> - </string> - </namespace> - -</strings> +<?xml version="1.0" encoding="iso-8859-1" ?> +<strings> + <!-- + _d: dativ (wir erkl�ren allen /Trollen/ den Krieg) + _p: plural (13 /Trolle/) + _x: preposition (15 /Troll/schwerter) + _a: including article (ein Troll, a troll) + --> + + <!--Fort-Ausbaustufen --> + <string name="calendar::thirdage"> + <text locale="de">des dritten Zeitalters</text> + <text locale="en">the third age</text> + </string> + + <string name="rpg_item_1_p"> + <text locale="de">Urkunden</text> + <text locale="en">Certificates</text> + </string> + <string name="rpg_item_2_p"> + <text locale="de">Nu�h�lften</text> + <text locale="en">nut halves</text> + </string> + <string name="rpg_item_3_p"> + <text locale="de">Flaschengeister</text> + <text locale="en">bottle demons</text> + </string> + <string name="rpg_item_1"> + <text locale="de">Pandoras Urkunde f�r Halbling ehrenhalber, weiblich</text> + <text locale="en">Pandora's Certificate</text> + </string> + <string name="rpg_item_2"> + <text locale="de">Heilige Nu�h�lfte</text> + <text locale="en">piece of a holy nut</text> + </string> + <string name="rpg_item_3"> + <text locale="de">Flaschengeist Zhardamon</text> + <text locale="en">bottle demon Zhardamon</text> + </string> + + <string name="rep_crossbow"> + <text locale="de">Repetierarmbrust</text> + <text locale="en">repeating crossbow</text> + </string> + <string name="rep_crossbow_p"> + <text locale="de">Repetierarmbr�ste</text> + <text locale="en">repeating crossbows</text> + </string> + + <string name="scaffolding"> + <text locale="de">Ger�st</text> + <text locale="en">scaffolding</text> + </string> + <string name="guardhouse"> + <text locale="de">Wachstube</text> + <text locale="en">guard house</text> + </string> + <string name="guardtower"> + <text locale="de">Wachturm</text> + <text locale="en">guard tower</text> + </string> + <string name="watch"> + <text locale="de">Wache</text> + <text locale="en">watch</text> + </string> + <string name="market"> + <text locale="de">Marktplatz</text> + <text locale="en">marketplace</text> + </string> + + <namespace name="morale"> + <string name="0"> + <text locale="de">aufst�ndische</text> + <text locale="en">rebellious</text> + </string> + <string name="1"> + <text locale="de">w�tende</text> + <text locale="en">mad</text> + </string> + <string name="2"> + <text locale="de">zornige</text> + <text locale="en">angry</text> + </string> + <string name="3"> + <text locale="de">unruhige</text> + <text locale="en">agitated</text> + </string> + <string name="4"> + <text locale="de">gleichg�ltige</text> + <text locale="en">indifferent</text> + </string> + <string name="5"> + <text locale="de">entspannte</text> + <text locale="en">relaxed</text> + </string> + <string name="6"> + <text locale="de">zufriedene</text> + <text locale="en">content</text> + </string> + <string name="7"> + <text locale="de">gl�ckliche</text> + <text locale="en">happy</text> + </string> + <string name="8"> + <text locale="de">treue</text> + <text locale="en">loyal</text> + </string> + <string name="9"> + <text locale="de">ergebene</text> + <text locale="en">devoted</text> + </string> + <string name="10"> + <text locale="de">unterw�rfige</text> + <text locale="en">subservient</text> + </string> + </namespace> + <string name="charger"> + <text locale="de">Streitross</text> + <text locale="en">charger</text> + </string> + <string name="charger_p"> + <text locale="de">Streitr�sser</text> + <text locale="en">chargers</text> + </string> + <string name="towershield"> + <text locale="de">Turmschild</text> + <text locale="en">tower shield</text> + </string> + <string name="towershield_p"> + <text locale="de">Turmschilde</text> + <text locale="en">tower shields</text> + </string> + + <namespace name="spell"> + <string name="create_potion_p0"> + <text locale="de">Braue Siebenmeilentee</text> + <text locale="en">brew seven mile tea</text> + </string> + <string name="create_potion_p2"> + <text locale="de">Braue Wasser des Lebens</text> + <text locale="en">brew water of life</text> + </string> + <string name="create_potion_p3"> + <text locale="de">Braue Schaffenstrunk</text> + <text locale="en">brew busy beer</text> + </string> + <string name="create_potion_ointment"> + <text locale="de">Braue Wundsalbe</text> + <text locale="en">brew ointment</text> + </string> + <string name="create_potion_peasantblood"> + <text locale="de">Braue Bauernblut</text> + <text locale="en">brew peasant blood</text> + </string> + <string name="create_potion_p9"> + <text locale="de">Braue Pferdegl�ck</text> + <text locale="en">brew horsepower potion</text> + </string> + <string name="create_potion_p13"> + <text locale="de">Braue Elixier der Macht</text> + <text locale="en">brew elixir of power</text> + </string> + <string name="create_potion_p14"> + <text locale="de">Braue Heiltrank</text> + <text locale="en">brew healing potion</text> + </string> + </namespace> + + <namespace name="spellinfo"> + <string name="raindance"> + <text locale="de">Durch dieses uralte Tanzritual ruft der Zauberkundige + die Kr�fte des Lebens und der Fruchtbarkeit an. Die darauf folgenden + Regenf�lle beg�nstigen das Wachstum und erh�hen die Ernteertr�ge + einiger Bauern der Region bis der Regen wieder nachl�sst.</text> + <text locale="en">This ancient rite calls upon the + forces of life and fertility. For the next few weeks, + the peasant's harvest will be extraordinary good. + (OBS: this spell has been changed and needs a new translation).</text> + </string> + <string name="blessedharvest"> + <text locale="de">F�r dieses Ernteritual sendet der Druide seine arkane Energie entlang + der astralen Kraftlinien der gesamten Umgebung, um selbst weit entfernte + Naturgeister zu erreichen. Die Beschw�rung dieser Naturgeister ist eine + hohe Kunst, die h�chste Konzentration und vor allem viel Erfahrung + erfordert. Die Bauern werden nach und nach von den besseren Ernten + profitieren und ihre Ersparnisse steigern k�nnen.</text> + <text locale="en">This ritual increases the output of the local farms. + Peasants in the region produce an extra silverpiece. The stronger the + druid's spell is, the longer the effect will last. + (OBS: this spell has been changed and needs a new translation).</text> + </string> + <string name="earn_silver#draig"> + <text locale="de">In den dunkleren Gassen gibt es sie, + die Fl�che und Verhexungen auf Bestellung. Aber + auch Gegenzauber hat der J�nger des Draigs + nat�rlich im Angebot. Ob nun der Sohn des + Nachbarn in einen Liebesbann gezogen werden soll + oder die Nebenbuhlerin Pickel und Warzen + bekommen soll, niemand gibt gerne zu, zu solchen + Mitteln gegriffen zu haben. F�r diese + Dienstleistung streicht der Magier 25 Silber pro + Stufe ein.</text> + <text locale="en">In the dark alleys you can find those + who sell curses and hexes on demand - but you + can buy the apropriate counterspells from the + followers of Draig as well. May it be a love + spell for the son of a neighbour or a wart in + the face of a rival. For offering these + services, the sorcerer charges 25 silver pieces. + per level.</text> + </string> + <string name="earn_silver#illaun"> + <text locale="fr">Personne n'interpr�te aussi bien les + r�ves que les mages d'Illaun. Ils sont �galement + vers�s dans l'utilisation des objets utilis�s + pour pr�dire le futur comme les boules de + cristal, les cartes de tarot ou les lignes de la + main. Un mentaliste peut gagner 25 �cus par + niveau et par semaine en proposant ses services + aux paysans.</text> + <text locale="de">Niemand kann so gut die Tr�ume deuten + wie ein Magier des Illaun. Auch die Kunst der + Wahrsagerei, des Kartenlegens und des Handlesens + sind ihm gel�ufig. Daf�r zahlen ihm die Bauern + 25 Silber pro Stufe.</text> + <text locale="en">No one can read dreams as well as the + mages of Illaun. Furthermore, they are also + familiar with all other common means of + foretelling the future like crystal balls, tarot + cards or palms. A mentalist can earn 25 silver + pieces per level and week for offering these + services to peasants.</text> + </string> + <string name="earn_silver#tybied"> + <text locale="de">Wenn einem der Alchemist nicht weiterhelfen kann, geht man zu dem + gelehrten Tybiedmagier. Seine Tr�nke und Tinkturen helfen gegen + alles, was man sonst nicht bekommen kann. Ob nun die kryptische + Formel unter dem Holzschuh des untreuen Ehemannes wirklich geholfen + hat - nun, der des Lesens nicht m�chtige Bauer wird es nie wissen. + Dem Magier hilft es auf jeden Fall... beim F�llen seines + Geldbeutels. 25 Silber pro Stufe lassen sich so in einer Woche + verdienen.</text> + <text locale="en">If the local alchemist could not help you, you should visit a + scholar of Tybied. His potions and tinctures may help when nothing + else does. If the cryptic formula under the wooden shoes of the + unfaithful husband really helped? - well, the peasant, who isn't + capable of reading, will never know. At least it helped the magician... + to fill his purse. In one week he can earn 25 silver per level that + way.</text> + </string> + <string name="earn_silver#cerddor"> + <text locale="de">Cerddormagier sind _die_ Gaukler unter + den Magiern, sie lieben es das Volk zu unterhalten und + im Mittelpunkt zu stehen. Schon Anf�nger lernen die + kleinen Kunstst�cke und magischen Tricks, mit denen man + das Volk locken und verf�hren kann, den Geldbeutel ganz + weit zu �ffnen, und am Ende der Woche wird der Gaukler + 25 Silber pro Stufe verdient haben.</text> + <text locale="en">The mages of Cerddor truly are the + bards of the wizards; they love to use their sorcery to + entertain the crowds and to be the center of attention. + Even the apprentices study those little magic tricks, + which attract and fascinate the people and thus ensnare + them into leaving a few coins or more for the artist. By + the end of the week, the bard will have earned 25 silver + per level. </text> + </string> + <string name="earn_silver#gwyrrd"> + <text locale="de">Die F�higkeiten der Gwyrrd-Magier in + der Viehzucht und Heilung sind bei den Bauern sehr + begehrt. Gerade auf M�rkten sind ihre Dienste h�ufig sehr + gefragt. Manch einer mag auch sein Talent dazu nutzen, + ein Tier f�r einen besseren Preis zu verkaufen. Pro + Stufe kann der Magier so 25 Silber verdienen.</text> + <text locale="en">The abilities of the mages of Gwyrrd + concerning the breeding and healing of cattle are highly + appreciated among the peasants. Especially at the + markets, their services are demanded frequently. Some of + them also use their talents to sell an animal at a + higher price. A magician can earn 25 silver pieces per level + in this way.</text> + </string> + <string name="create_potion_p0"> + <text locale="en">Time is one of the first mysteries every magician tries to solve. If he succeeds, he can focus all his energies on his magical studies as the ways between dormatory, library and magician tower now pass much faster. To keep his heart in tune the magician uses a special self made tey. Some mages even share it with up to 10 people</text> + <text locale="de">Die Zeit ist eines der ersten Geheimnisse, die jeder Magier zu erkunden versucht. Gelingt ihm dies, kann er alle seine Energie auf das Studium der Magie verwenden, die Wege zwischen Dormitorium, Bibliothek und Magierturm schafft er nun viel schneller. Um sein Herz im Takt zu halten verwendet er einen speziellen selbstgemachten Tee. Manche Magier teilen diesen Tee mit bis zu 10 Personen. </text> + </string> + <string name="create_potion_p2"> + <text locale="en">One of the most strange spells enables the magician to withdraw a little life energy from his surroundings to produce the so called water of life. The juice of some selected herbs is used to conserve the energies of life. As the magician is protected by his magical abilities, he is the only one who can touch the juice without taking damage. This is necessary because the juice must be carried around from place to place to avoid damaging one region by taking too much energy at once.</text> + <text locale="de">In einem der seltsamsten Zauber kann der Magier seiner Umgebung ein klein wenig der Lebensenergie entziehen um das sogenannte Wasser des Lebens herstellen. Als Basis dient ihm hierbei der Saft aus einigen ausgesuchten Kr�utern, welcher die Lebensenergie speichern kann. Da der Magier aufgrund seiner magischen F�higkeiten immun ist, ist er der einzige, der den Saft ber�hren kann, ohne Schaden zu nehmen. Sodenn mu� er diesen eine Woche lang von Ort zu Ort tragen, damit er sich mit Lebensenergie vollsaugt, ohne einem einzelnen Ort soviel zu entfernen, da� er Schaden nimmt. </text> + </string> + <string name="create_potion_p3"> + <text locale="en">Busybeer is another application for the knowledge about time a magician accumulates. Even though manual labour is only seldom done by mages, they still show interest in increasing the efficiency of their minions that do this work for them. Mornac the wise was the first to discover how to produce a potion that would enable 10 minions to do the work of 20, thus freeing the other 10 for different experiments.</text> + <text locale="de">Ein weiteres Anwendungsgebiet des Wissens �ber die Zeit welches ein Magier ansammelt stellt der Schaffenstrunk dar. Auch wenn k�rperliche Arbeiten eher selten von Magiern ausgef�hrt werden, so haben diese doch ein Interesse daran, die Effizienz ihrer Untergebenen bei solchen Arbeiten zu steigern. Mornac der Weise war der erste, der entdeckte, da� man einen Trunk herstellen kann, durch den 10 Untergebene die arbeit von 20 erledigen k�nnen, wodurch 10 f�r andere Experimente weiterverwendet werden konnten. </text> + </string> + <string name="create_potion_ointment"> + <text locale="en">In the aftermath of battle it is vital to heal your own troops. This can be done by a healer as well as by a magician. In contrast to a healer, the magician can fullfill his treatment already before the battle by binding his magical powers into a potent salve. This salve can be stored and only needs to be applied to the wounds after the battle. </text> + <text locale="de">Nach einem harten Kampf sollte man sich heilen lassen. Diese M�glichkeit bietet der Magier ebenso wie der Heiler. Im Gegensatz zum Heiler ist der Magier jedoch in der Lage, seine Behandlung bereits vor dem Kampf durchzuf�hren, indem er seine Heilkr�fte in eine magische Salbe bindet, welche gelagert werden kann und nach dem Kampf nur aufgetragen werden mu�.</text> + </string> + <string name="create_potion_peasantblood"> + <text locale="en">One of the most dangerous and best guarded secrets of all mages is the knowledge about the power of death. Even though most of them would not openly admit it, and it is at least partially forbidden in most countries, each of them studies death sooner or later. When they do, they quickly find out that there is another plane of existance, the home of the demons. Only blood can quelch the thirst of those, when they switch from their home to our world. But experienced mages will find out that the demons bloodwine can be deluted when apropiate herbs are included, making it enough for 100 instead of 10 demons. As the demons may not know about that, the magician has to secretly sacrifice one of his freed minions.</text> + <text locale="de">Zu den gef�hrlichsten und geheimsten Wissen der Magier z�hlt das Wissen �ber die Macht des Todes. Auch wenn die meisten es nicht zugeben, so fasziniert dieses Thema jeden Magier. Fr�her oder sp�ter besch�ftigen sich alle mit diesem, teiweise verbotenen, Gebiet. Sodann werden sie feststellen, das es noch eine weitere Ebene der Existenz gibt, in der die D�monen beheimatet sind. Nur Blut allein vermag den Hunger dieser Wesen zu befriedigen, wenn sie ihre Ebene verlassen und unsere betreten. Erfahrene Magier werden jedoch feststellen, dass man den Blutwein, den die D�monen zu sich nehmen strecken kann, so da� davon 100 anstatt nur 10 D�monen satt werden. Da die D�monen davon jedoch nichts wissen d�rfen, mu� der Magier selbst klammheimlich einen seiner urpl�tzlich verf�gbar gewordenen Untergebenen opfern. </text> + </string> + <string name="create_potion_p9"> + <text locale="en">Even though mages live in strict cellibate they know a lot about creating certain longings. Peasants keep asking them for this love potion or that. But the penality for bewitching a peasant is death, so the mages offer their services only to farmers for their breeding stock. In an elaborate ritual, which only serves to hide the simplicity of the procedure, the magician draws the fluids from certains plants. while doing so, he calls upon the spirits of fertility which of course only listen when he talkes to them. Now the farmer knows that any attempt to draw the fluids himself will only result in a useless waste of resorces. Finally, the magician hands the vial with the fluids to the farmer, who pours it into his horses drinking water.</text> + <text locale="de">Obwohl f�r Magier das Gebiet der Liebe Tabu ist und sie im strengen Z�libat leben, haben sie ein gro�es Wissen dar�ber, wie man gewisse Bed�rfnisse weckt, weshalb sie immer wieder von Dorfbewohnerinnen und Dorfbewohnern nach entsprechenden Zaubern gefragt werden. Da die Verzauberung eines Bewohners jedoch streng verboten ist, bieten sie ihre Dienste nur f�r die Z�chter an. In einem Aufwendigen Ritual, welches jedoch nur dazu dient zu verschleiern, wie einfach dies eigentlich ist, vermischt der Magier vor den Augen des Z�chters einige Pflanzens�fte. Dabei ruft er die Geister an die dem Pferdez�chter das Gl�ck bescheren sollen, um klarzumachen, das diese nur mit ihm sprechen und jeglicher Versuch des Z�chters, selbst die Kr�uter zu mischen nur eine unbrauchbare Pampe produzieren w�rde. Anschlie�end �berreicht der Magier dem Z�chter eine Phiole, die dieser in die Tr�nke seiner Pferde entleeren mu�.</text> + </string> + <string name="create_potion_p13"> + <text locale="en">Just like with the knowledge about death, the peasants feel uncomfortable with the knowledge about monsters. A few warriors though, who have already faced these creatures in combat, foud that the monsters blood had en invigourating effect on them. There is talk about some warriors, who bathed in the blood of the slain monsters to take up their strenght. But this effect ends soon, and only occurs with fresh blood. As no one has time to quickly slay a wyrm before attacking his neighbors, a way had to be found to make the effect last longer. After lots of experiments that cost the life of lots of good warriors who had to constantly bring in fresh dragon blood, Manasouf the black finally found a way. Originally a closely guarded secret, the recipe is now knows in all lands. First, the hardened dragon blood needs to be melted in hot tin. After that, the magician binds the spirit of the dragon to its blood once again. It can not fnd eternal rest until the last bit of blood has been used. </text> + <text locale="de">Ebenso wie das Wissen �ber den Tod ist das Wissen �ber gewisse Monster bei der abergl�ubigen Bev�lkerung nicht gerne gesehen. Einige wenige Krieger jedoch, die diesen Kreaturen schon mal im Kampf gegen�berstanden haben entdeckt, da� deren Blut eine belebende Wirkung auf sie hatte. So solle es schon Kriger gegeben haben, die im Blut der erschlagenen Monster badeten, um deren St�rke in sich aufzunehmen. Diese Wirkung verfliegt jedoch rasch, und wirkt nur bei frischen Blut. Da niemand vor dem Kampf gegen seinen Nachbarn die Zeit hat, schnell noch einen Wyrm zu erschlagen musste ein Weg gefunden werden, die Wirkung haltbar zu machen. Manasouf dem schwarzen gelang dies nach zahlreichen Experimenten, die das Leben vieler guter M�nner kosteten, welche st�ndig neues Drachenblut f�r seine Versuche beschaffen mussten. Urspr�nglich ein streng geh�tetes Geheimnis, ist das Rezept inzwischen im ganzen Land bekannt. Zun�chst mu� geronnene Drachenblut mu� in einem Tiegel wieder verfl�ssigt werden. Anschlie�end wird der Geist des erschlagenen Drachen in der Geisterebene wieder an sein Blut gebunden, und kann solange nicht in frieden ruhen, bis das letzte bisschen seines Blutes verbraucht wurde.</text> + </string> + <string name="create_potion_p14"> + <text locale="en">Some mages research deth's secrets until they can bring the dead back to life. But those who are brought back are often only shadows of ther former self and turn against their erstwhile friends. But those mages that study life and its iteraction with death find a possibility, to bring the deceased back as their original selves. A drawback is that this is only possible in the very first minutes after the death. As even mages can not be everywhere at the same time, a way had to be found to give this ability to helpers. All healers who tried to learn this from the mages failed, though, until one of those healers was backstabbingly killed. In the moment of his death he used the knowledge gained and was able to have his murderer executed the following day. The potion he designed has to be blessed by a magician before usage at any given time. This potion gives 4 people (or 1 person 4 times) a 50% chance to survive an otherwise deadly wound. It is used automatically by the victom.</text> + <text locale="de">Manche Magier erforschen den Tod, bis sie verstorbene wieder ins Leben zur�ck bringen k�nnen. Diese sind jedoch meist b�sartig und nur noch Schatten ihres fr�heren selbst. Diejenigen jedoch, die sich intensiv mit dem Leben und seiner Kombination mit dem Tod besch�ftigen finden eine M�glichkeit, verstorbene in ihrer wahren Gestallt zur�ck zu rufen. Dies ist allerdings nur wenige Minuten nach dem Tod m�glich. Da selbst Magier nicht �berall gleichzeitig sein k�nnen, musste ein Weg gefunden werden, diese F�higkeit auf andere zu �bertragen. Alle Versuche, dies feldschern beizubringen scheiterten jedoch, bis einer dieser Felschner von einem Widersacher hinterr�cks ermordet wurde. Im Moment seines Todes wandte er sein erworbenes Wissen an und konnte tags darauf den �belt�ter wegen Mordes hinrichten lassen. Der von ihm entwickelte magische Trank mu� jedoch von einem der Magie des Lebens kundigen gesegnet werden, um seine volle Wirkung zu entfalten. Ein solcher Trank gibt vier M�nnern (oder einem Mann vier mal) im Kampf eine Chance von 50%, sonst t�dliche Wunden zu �berleben. Der Trank wird von ihnen automatisch bei Verletzung angewandt.</text> + </string> + </namespace> + + <namespace name="spell"> + <string name="commonfamiliar"> + <text locale="de">Vertrauten binden</text> + <text locale="en">Bind Familiar</text> + </string> + </namespace> + <namespace name="spellinfo"> + <string name="commonfamiliar"> + <text locale="de">Einem erfahrenen Magier wird + irgendwann auf seinen Wanderungen ein + ungew�hnliches Exemplar einer Gattung begegnen, + welches sich dem Magier anschlie�en wird.</text> + <text locale="en">During their travel, seasoned + magicians will occasionally befriend an extraordinary + creature of an unusual species that will join them.</text> + </string> + </namespace> + +</strings> diff --git a/res/e3a/terrains.xml b/res/e3a/terrains.xml index 512536c38..b61f03966 100644 --- a/res/e3a/terrains.xml +++ b/res/e3a/terrains.xml @@ -1,73 +1,73 @@ -<?xml version="1.0" encoding="ISO-8859-1"?> -<terrains> - <!-- defaults: walk="yes" sail="yes" fly="yes" shallow="yes" swim="no" forest="no" sea="no" land="yes" forbidden="no" arctic="no" cavalry="no" size="0" --> - <terrain name="ocean" size="100" shallow="no" walk="no" swim="yes" land="no" sea="yes" /> - <terrain name="plain" size="4000" road="50" shallow="no" forest="yes" cavalry="yes" seed="3"> - <herb name="h0" /> - <herb name="h4" /> - <resource name="iron" chance="0.1" level="2d4-1" base="5d8" div="2d20+10" /> - <resource name="stone" chance="0.15" level="1d4" base="5d8" div="2d30+20" /> - <resource name="laen" chance="0.01" level="1d4" base="1d4" div="2d20+50" /> - </terrain> - <terrain name="swamp" size="1200" road="75" seed="2"> - <herb name="h6" /> - <herb name="h8" /> - <resource name="iron" chance="0.02" level="2d4-1" base="5d8" div="2d20+10" /> - <resource name="stone" chance="0.02" level="1d4" base="5d8" div="2d30+20" /> - <resource name="laen" chance="0.02" level="1d4" base="1d4" div="2d20+50" /> - </terrain> - <terrain name="desert" size="400" road="100" cavalry="yes" seed="2"> - <herb name="h9" /> - <herb name="h11" /> - <resource name="iron" chance="0.15" level="2d4-1" base="5d8" div="2d20+10" /> - <resource name="stone" chance="0.25" level="1d4" base="5d8" div="2d30+20" /> - <resource name="laen" chance="0.025" level="1d4" base="1d4" div="2d20+50" /> - </terrain> - <terrain name="highland" size="2300" road="100" cavalry="yes" seed="2"> - <herb name="h12" /> - <herb name="h14" /> - <resource name="iron" chance="0.15" level="2d4-1" base="5d8" div="2d20+10" /> - <resource name="stone" chance="0.25" level="1d4" base="5d8" div="2d30+20" /> - <resource name="laen" chance="0.025" level="1d4" base="1d4" div="2d20+50" /> - </terrain> - <terrain name="mountain" size="600" road="250" seed="2"> - <herb name="h15" /> - <herb name="h17" /> - <resource name="iron" chance="1.0" level="1" base="50" div="50" /> - <resource name="stone" chance="1.0" level="1" base="100" div="100" /> - <resource name="laen" chance="0.05" level="1" base="4" div="100" /> - </terrain> - <terrain name="glacier" size="150" road="250" arctic="yes" seed="2"> - <herb name="h18" /> - <herb name="h20" /> - <resource name="iron" chance="1.0" level="1" base="3" div="50" /> - <resource name="stone" chance="1.0" level="1" base="2" div="100" /> - <resource name="laen" chance="0.05" level="1" base="4" div="100" /> - </terrain> - <terrain name="iceberg_sleep" size="150" road="250" arctic="yes"> - <herb name="h18" /> - <herb name="h20" /> - <resource name="iron" chance="0.9" level="1" base="3" div="50" /> - <resource name="stone" chance="0.9" level="1" base="2" div="100" /> - <resource name="laen" chance="0.05" level="1" base="4" div="100" /> - </terrain> - <terrain name="iceberg" size="150" arctic="yes"> - <herb name="h18" /> - <herb name="h20" /> - <resource name="iron" chance="0.9" level="1" base="3" div="50" /> - <resource name="stone" chance="0.9" level="1" base="2" div="100" /> - </terrain> - <terrain name="firewall" road="250" land="no" walk="no" sail="no" fly="no" forbidden="yes" /> - <terrain name="fog" sail="no" land="no" /> - <terrain name="thickfog" forbidden="yes" sail="no" walk="no" fly="no" land="no" /> - <terrain name="volcano" size="400" road="250" seed="1"> - <resource name="iron" chance="0.5" level="1" base="50" div="50" /> - <resource name="stone" chance="0.5" level="1" base="100" div="100" /> - <resource name="laen" chance="0.075" level="1" base="4" div="100" /> - </terrain> - <terrain name="activevolcano" size="400" road="250"> - <resource name="iron" chance="0.5" level="1" base="50" div="50" /> - <resource name="stone" chance="0.5" level="1" base="100" div="100" /> - <resource name="laen" chance="0.075" level="1" base="4" div="100" /> - </terrain> -</terrains> +<?xml version="1.0" encoding="ISO-8859-1"?> +<terrains> + <!-- defaults: walk="yes" sail="yes" fly="yes" shallow="yes" swim="no" forest="no" sea="no" land="yes" forbidden="no" arctic="no" cavalry="no" size="0" --> + <terrain name="ocean" size="100" shallow="no" walk="no" swim="yes" land="no" sea="yes" /> + <terrain name="plain" size="4000" road="50" shallow="no" forest="yes" cavalry="yes" seed="3"> + <herb name="h0" /> + <herb name="h4" /> + <resource name="iron" chance="0.1" level="2d4-1" base="5d8" div="2d20+10" /> + <resource name="stone" chance="0.15" level="1d4" base="5d8" div="2d30+20" /> + <resource name="laen" chance="0.01" level="1d4" base="1d4" div="2d20+50" /> + </terrain> + <terrain name="swamp" size="1200" road="75" seed="2"> + <herb name="h6" /> + <herb name="h8" /> + <resource name="iron" chance="0.02" level="2d4-1" base="5d8" div="2d20+10" /> + <resource name="stone" chance="0.02" level="1d4" base="5d8" div="2d30+20" /> + <resource name="laen" chance="0.02" level="1d4" base="1d4" div="2d20+50" /> + </terrain> + <terrain name="desert" size="400" road="100" cavalry="yes" seed="2"> + <herb name="h9" /> + <herb name="h11" /> + <resource name="iron" chance="0.15" level="2d4-1" base="5d8" div="2d20+10" /> + <resource name="stone" chance="0.25" level="1d4" base="5d8" div="2d30+20" /> + <resource name="laen" chance="0.025" level="1d4" base="1d4" div="2d20+50" /> + </terrain> + <terrain name="highland" size="2300" road="100" cavalry="yes" seed="2"> + <herb name="h12" /> + <herb name="h14" /> + <resource name="iron" chance="0.15" level="2d4-1" base="5d8" div="2d20+10" /> + <resource name="stone" chance="0.25" level="1d4" base="5d8" div="2d30+20" /> + <resource name="laen" chance="0.025" level="1d4" base="1d4" div="2d20+50" /> + </terrain> + <terrain name="mountain" size="600" road="250" seed="2"> + <herb name="h15" /> + <herb name="h17" /> + <resource name="iron" chance="1.0" level="1" base="50" div="50" /> + <resource name="stone" chance="1.0" level="1" base="100" div="100" /> + <resource name="laen" chance="0.05" level="1" base="4" div="100" /> + </terrain> + <terrain name="glacier" size="150" road="250" arctic="yes" seed="2"> + <herb name="h18" /> + <herb name="h20" /> + <resource name="iron" chance="1.0" level="1" base="3" div="50" /> + <resource name="stone" chance="1.0" level="1" base="2" div="100" /> + <resource name="laen" chance="0.05" level="1" base="4" div="100" /> + </terrain> + <terrain name="iceberg_sleep" size="150" road="250" arctic="yes"> + <herb name="h18" /> + <herb name="h20" /> + <resource name="iron" chance="0.9" level="1" base="3" div="50" /> + <resource name="stone" chance="0.9" level="1" base="2" div="100" /> + <resource name="laen" chance="0.05" level="1" base="4" div="100" /> + </terrain> + <terrain name="iceberg" size="150" arctic="yes"> + <herb name="h18" /> + <herb name="h20" /> + <resource name="iron" chance="0.9" level="1" base="3" div="50" /> + <resource name="stone" chance="0.9" level="1" base="2" div="100" /> + </terrain> + <terrain name="firewall" road="250" land="no" walk="no" sail="no" fly="no" forbidden="yes" /> + <terrain name="fog" sail="no" land="no" /> + <terrain name="thickfog" forbidden="yes" sail="no" walk="no" fly="no" land="no" /> + <terrain name="volcano" size="400" road="250" seed="1"> + <resource name="iron" chance="0.5" level="1" base="50" div="50" /> + <resource name="stone" chance="0.5" level="1" base="100" div="100" /> + <resource name="laen" chance="0.075" level="1" base="4" div="100" /> + </terrain> + <terrain name="activevolcano" size="400" road="250"> + <resource name="iron" chance="0.5" level="1" base="50" div="50" /> + <resource name="stone" chance="0.5" level="1" base="100" div="100" /> + <resource name="laen" chance="0.075" level="1" base="4" div="100" /> + </terrain> +</terrains> diff --git a/res/e3a/weapons.xml b/res/e3a/weapons.xml index 421c60305..c0e608bfd 100644 --- a/res/e3a/weapons.xml +++ b/res/e3a/weapons.xml @@ -1,24 +1,24 @@ -<?xml version="1.0"?> -<resources xmlns:xi="http://www.w3.org/2001/XInclude"> - <xi:include href="eressea:///core/weapons/axe.xml"/> - <xi:include href="eressea:///core/weapons/bow.xml"/> - <xi:include href="eressea:///core/weapons/catapult.xml"/> - <xi:include href="eressea:///core/weapons/lance.xml"/> - <xi:include href="eressea:///core/weapons/mallornbow.xml"/> - <xi:include href="eressea:///core/weapons/mallornspear.xml"/> - <xi:include href="eressea:///core/weapons/rep_crossbow.xml"/> - <xi:include href="eressea:///core/weapons/runesword.xml"/> - <xi:include href="eressea:///core/weapons/rustyaxe.xml"/> - <xi:include href="eressea:///core/weapons/rustysword.xml"/> - <xi:include href="eressea:///core/weapons/spear.xml"/> - <xi:include href="eressea:///core/weapons/sword.xml"/> - <xi:include href="weapons/crossbow.xml"/> - <xi:include href="weapons/greatbow.xml"/> - <xi:include href="weapons/greatsword.xml"/> - <xi:include href="weapons/halberd.xml"/> - <xi:include href="weapons/laensword.xml"/> - <xi:include href="weapons/mallorncrossbow.xml"/> - <xi:include href="weapons/mallornlance.xml"/> - <xi:include href="weapons/rustygreatsword.xml"/> - <xi:include href="weapons/rustyhalberd.xml"/> -</resources> +<?xml version="1.0"?> +<resources xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="eressea:///core/weapons/axe.xml"/> + <xi:include href="eressea:///core/weapons/bow.xml"/> + <xi:include href="eressea:///core/weapons/catapult.xml"/> + <xi:include href="eressea:///core/weapons/lance.xml"/> + <xi:include href="eressea:///core/weapons/mallornbow.xml"/> + <xi:include href="eressea:///core/weapons/mallornspear.xml"/> + <xi:include href="eressea:///core/weapons/rep_crossbow.xml"/> + <xi:include href="eressea:///core/weapons/runesword.xml"/> + <xi:include href="eressea:///core/weapons/rustyaxe.xml"/> + <xi:include href="eressea:///core/weapons/rustysword.xml"/> + <xi:include href="eressea:///core/weapons/spear.xml"/> + <xi:include href="eressea:///core/weapons/sword.xml"/> + <xi:include href="weapons/crossbow.xml"/> + <xi:include href="weapons/greatbow.xml"/> + <xi:include href="weapons/greatsword.xml"/> + <xi:include href="weapons/halberd.xml"/> + <xi:include href="weapons/laensword.xml"/> + <xi:include href="weapons/mallorncrossbow.xml"/> + <xi:include href="weapons/mallornlance.xml"/> + <xi:include href="weapons/rustygreatsword.xml"/> + <xi:include href="weapons/rustyhalberd.xml"/> +</resources> diff --git a/res/e3a/weapons/crossbow.xml b/res/e3a/weapons/crossbow.xml index 57535a070..8416d7e93 100644 --- a/res/e3a/weapons/crossbow.xml +++ b/res/e3a/weapons/crossbow.xml @@ -1,13 +1,13 @@ -<?xml version="1.0"?> -<resource name="crossbow"> - <item weight="100"> - <construction skill="weaponsmithing" minskill="3" reqsize="1"> - <requirement type="log" quantity="1"/> - </construction> - <weapon armorpiercing="true" pierce="true" missile="true" skill="crossbow" offmod="0" defmod="0" reload="2"> - <damage type="rider" value="3d4+5"/> - <damage type="footman" value="3d4+5"/> - <modifier type="missile_target" value="0"/> - </weapon> - </item> -</resource> +<?xml version="1.0"?> +<resource name="crossbow"> + <item weight="100"> + <construction skill="weaponsmithing" minskill="3" reqsize="1"> + <requirement type="log" quantity="1"/> + </construction> + <weapon armorpiercing="true" pierce="true" missile="true" skill="crossbow" offmod="0" defmod="0" reload="2"> + <damage type="rider" value="3d4+5"/> + <damage type="footman" value="3d4+5"/> + <modifier type="missile_target" value="0"/> + </weapon> + </item> +</resource> diff --git a/res/e3a/weapons/greatbow.xml b/res/e3a/weapons/greatbow.xml index ba91f54de..6e3c08cf0 100644 --- a/res/e3a/weapons/greatbow.xml +++ b/res/e3a/weapons/greatbow.xml @@ -1,22 +1,22 @@ -<?xml version="1.0"?> -<!-- changes: - * has a lua canuse function - * has lower damage ---> -<resource name="greatbow"> - <item weight="100"> - <function name="canuse" value="lua_canuse_item"/> - <construction skill="weaponsmithing" minskill="5" reqsize="1"> - <modifier function="mod_elves_only"/> - <requirement type="mallorn" quantity="2"/> - </construction> - <weapon pierce="true" missile="true" skill="bow" offmod="0" defmod="0" reload="0" magres="0.0"> - <damage type="rider" value="2d4+5"/> - <damage type="footman" value="2d4+5"/> - <modifier type="missile_target" value="2"/> - <modifier type="damage" value="1"> - <race name="elf"/> - </modifier> - </weapon> - </item> -</resource> +<?xml version="1.0"?> +<!-- changes: + * has a lua canuse function + * has lower damage +--> +<resource name="greatbow"> + <item weight="100"> + <function name="canuse" value="lua_canuse_item"/> + <construction skill="weaponsmithing" minskill="5" reqsize="1"> + <modifier function="mod_elves_only"/> + <requirement type="mallorn" quantity="2"/> + </construction> + <weapon pierce="true" missile="true" skill="bow" offmod="0" defmod="0" reload="0" magres="0.0"> + <damage type="rider" value="2d4+5"/> + <damage type="footman" value="2d4+5"/> + <modifier type="missile_target" value="2"/> + <modifier type="damage" value="1"> + <race name="elf"/> + </modifier> + </weapon> + </item> +</resource> diff --git a/res/e3a/weapons/greatsword.xml b/res/e3a/weapons/greatsword.xml index 5fc1c9042..7956cee65 100644 --- a/res/e3a/weapons/greatsword.xml +++ b/res/e3a/weapons/greatsword.xml @@ -1,15 +1,15 @@ -<?xml version="1.0"?> -<!-- changes to the regular weapon: - 1. you cannt use this with cavalry ---> -<resource name="greatsword"> - <item weight="200" score="30"> - <construction skill="weaponsmithing" minskill="4" reqsize="1"> - <requirement type="iron" quantity="2"/> - </construction> - <weapon useshield="false" cut="true" skill="melee" offmod="-1" defmod="-2" horse="false"> - <damage type="rider" value="2d8+3"/> - <damage type="footman" value="2d8+3"/> - </weapon> - </item> -</resource> +<?xml version="1.0"?> +<!-- changes to the regular weapon: + 1. you cannt use this with cavalry +--> +<resource name="greatsword"> + <item weight="200" score="30"> + <construction skill="weaponsmithing" minskill="4" reqsize="1"> + <requirement type="iron" quantity="2"/> + </construction> + <weapon useshield="false" cut="true" skill="melee" offmod="-1" defmod="-2" horse="false"> + <damage type="rider" value="2d8+3"/> + <damage type="footman" value="2d8+3"/> + </weapon> + </item> +</resource> diff --git a/res/e3a/weapons/halberd.xml b/res/e3a/weapons/halberd.xml index edb933701..cf6f46647 100644 --- a/res/e3a/weapons/halberd.xml +++ b/res/e3a/weapons/halberd.xml @@ -1,18 +1,18 @@ -<?xml version="1.0"?> -<!-- changes to the regular weapon: - 1. you cannt use this with cavalry ---> -<resource name="halberd"> - <item weight="200"> - <function name="canuse" value="lua_canuse_item"/> - <construction skill="weaponsmithing" minskill="3" reqsize="1"> - <requirement type="log" quantity="2"/> - <requirement type="iron" quantity="1"/> - </construction> - <weapon useshield="false" cut="true" skill="polearm" offmod="-1" defmod="2" magres="0.0" horse="false"> - <damage type="rider" value="2d6+3"/> - <damage type="footman" value="2d6+3"/> - <modifier type="skill" value="1" walking="true" against_riding="true" defensive="true"/> - </weapon> - </item> -</resource> +<?xml version="1.0"?> +<!-- changes to the regular weapon: + 1. you cannt use this with cavalry +--> +<resource name="halberd"> + <item weight="200"> + <function name="canuse" value="lua_canuse_item"/> + <construction skill="weaponsmithing" minskill="3" reqsize="1"> + <requirement type="log" quantity="2"/> + <requirement type="iron" quantity="1"/> + </construction> + <weapon useshield="false" cut="true" skill="polearm" offmod="-1" defmod="2" magres="0.0" horse="false"> + <damage type="rider" value="2d6+3"/> + <damage type="footman" value="2d6+3"/> + <modifier type="skill" value="1" walking="true" against_riding="true" defensive="true"/> + </weapon> + </item> +</resource> diff --git a/res/e3a/weapons/laensword.xml b/res/e3a/weapons/laensword.xml index 13ebbf03e..ab65e23c8 100644 --- a/res/e3a/weapons/laensword.xml +++ b/res/e3a/weapons/laensword.xml @@ -1,15 +1,15 @@ -<?xml version="1.0"?> -<!-- changes: - * has lower damage ---> -<resource name="laensword"> - <item weight="100" score="400"> - <construction skill="weaponsmithing" minskill="8" reqsize="1"> - <requirement type="laen" quantity="1"/> - </construction> - <weapon cut="true" skill="melee" offmod="1" defmod="1" magres="0.30"> - <damage type="rider" value="2d9+4"/> - <damage type="footman" value="2d9+4"/> - </weapon> - </item> -</resource> +<?xml version="1.0"?> +<!-- changes: + * has lower damage +--> +<resource name="laensword"> + <item weight="100" score="400"> + <construction skill="weaponsmithing" minskill="8" reqsize="1"> + <requirement type="laen" quantity="1"/> + </construction> + <weapon cut="true" skill="melee" offmod="1" defmod="1" magres="0.30"> + <damage type="rider" value="2d9+4"/> + <damage type="footman" value="2d9+4"/> + </weapon> + </item> +</resource> diff --git a/res/e3a/weapons/mallorncrossbow.xml b/res/e3a/weapons/mallorncrossbow.xml index 920ae553f..4210135fd 100644 --- a/res/e3a/weapons/mallorncrossbow.xml +++ b/res/e3a/weapons/mallorncrossbow.xml @@ -1,13 +1,13 @@ -<?xml version="1.0"?> -<resource name="mallorncrossbow"> - <item weight="100"> - <construction skill="weaponsmithing" minskill="5" reqsize="1"> - <requirement type="mallorn" quantity="1"/> - </construction> - <weapon armorpiercing="true" pierce="true" missile="true" skill="crossbow" offmod="0" defmod="0" reload="2" magres="0.15"> - <damage type="rider" value="3d4+6"/> - <damage type="footman" value="3d4+6"/> - <modifier type="missile_target" value="0"/> - </weapon> - </item> -</resource> +<?xml version="1.0"?> +<resource name="mallorncrossbow"> + <item weight="100"> + <construction skill="weaponsmithing" minskill="5" reqsize="1"> + <requirement type="mallorn" quantity="1"/> + </construction> + <weapon armorpiercing="true" pierce="true" missile="true" skill="crossbow" offmod="0" defmod="0" reload="2" magres="0.15"> + <damage type="rider" value="3d4+6"/> + <damage type="footman" value="3d4+6"/> + <modifier type="missile_target" value="0"/> + </weapon> + </item> +</resource> diff --git a/res/e3a/weapons/mallornlance.xml b/res/e3a/weapons/mallornlance.xml index 6355f5780..78df993cb 100644 --- a/res/e3a/weapons/mallornlance.xml +++ b/res/e3a/weapons/mallornlance.xml @@ -1,13 +1,13 @@ -<?xml version="1.0"?> -<resource name="mallornlance"> - <item weight="100"> - <function name="canuse" value="lua_canuse_item"/> - <construction skill="weaponsmithing" minskill="5" reqsize="1"> - <requirement type="mallorn" quantity="2"/> - </construction> - <weapon pierce="true" skill="polearm" minskill="5" offmod="0" defmod="0" magres="0.15"> - <damage type="footman" value="1d5+2"/> - <damage type="rider" value="2d6+7"/> - </weapon> - </item> -</resource> +<?xml version="1.0"?> +<resource name="mallornlance"> + <item weight="100"> + <function name="canuse" value="lua_canuse_item"/> + <construction skill="weaponsmithing" minskill="5" reqsize="1"> + <requirement type="mallorn" quantity="2"/> + </construction> + <weapon pierce="true" skill="polearm" minskill="5" offmod="0" defmod="0" magres="0.15"> + <damage type="footman" value="1d5+2"/> + <damage type="rider" value="2d6+7"/> + </weapon> + </item> +</resource> diff --git a/res/e3a/weapons/rustygreatsword.xml b/res/e3a/weapons/rustygreatsword.xml index 818fac553..6ca1ed30a 100644 --- a/res/e3a/weapons/rustygreatsword.xml +++ b/res/e3a/weapons/rustygreatsword.xml @@ -1,15 +1,15 @@ -<?xml version="1.0"?> -<!-- changes to the regular weapon: - 1. you cannt use this with cavalry ---> -<resource name="rustygreatsword"> - <item weight="200" score="20"> - <construction skill="weaponsmithing" minskill="4" reqsize="1"> - <requirement type="iron" quantity="2"/> - </construction> - <weapon useshield="false" cut="true" skill="melee" offmod="-2" defmod="-3" horse="false"> - <damage type="rider" value="2d8"/> - <damage type="footman" value="2d8"/> - </weapon> - </item> -</resource> +<?xml version="1.0"?> +<!-- changes to the regular weapon: + 1. you cannt use this with cavalry +--> +<resource name="rustygreatsword"> + <item weight="200" score="20"> + <construction skill="weaponsmithing" minskill="4" reqsize="1"> + <requirement type="iron" quantity="2"/> + </construction> + <weapon useshield="false" cut="true" skill="melee" offmod="-2" defmod="-3" horse="false"> + <damage type="rider" value="2d8"/> + <damage type="footman" value="2d8"/> + </weapon> + </item> +</resource> diff --git a/res/e3a/weapons/rustyhalberd.xml b/res/e3a/weapons/rustyhalberd.xml index bab849b49..3f9909059 100644 --- a/res/e3a/weapons/rustyhalberd.xml +++ b/res/e3a/weapons/rustyhalberd.xml @@ -1,17 +1,17 @@ -<?xml version="1.0"?> -<!-- changes to the regular weapon: - 1. you cannot use this with cavalry ---> -<resource name="rustyhalberd"> - <item weight="200" score="20"> - <function name="canuse" value="lua_canuse_item"/> - <construction skill="weaponsmithing" minskill="3" reqsize="1"> - <requirement type="iron" quantity="1"/> - <requirement type="log" quantity="1"/> - </construction> - <weapon useshield="false" cut="true" skill="polearm" offmod="-2" defmod="-1" horse="false"> - <damage type="rider" value="2d6"/> - <damage type="footman" value="2d6"/> - </weapon> - </item> -</resource> +<?xml version="1.0"?> +<!-- changes to the regular weapon: + 1. you cannot use this with cavalry +--> +<resource name="rustyhalberd"> + <item weight="200" score="20"> + <function name="canuse" value="lua_canuse_item"/> + <construction skill="weaponsmithing" minskill="3" reqsize="1"> + <requirement type="iron" quantity="1"/> + <requirement type="log" quantity="1"/> + </construction> + <weapon useshield="false" cut="true" skill="polearm" offmod="-2" defmod="-1" horse="false"> + <damage type="rider" value="2d6"/> + <damage type="footman" value="2d6"/> + </weapon> + </item> +</resource> diff --git a/res/eressea/artrewards.xml b/res/eressea/artrewards.xml index 6cb836c52..c62c23a1b 100644 --- a/res/eressea/artrewards.xml +++ b/res/eressea/artrewards.xml @@ -1,32 +1,32 @@ -<?xml version="1.0"?> -<resources> - - <resource name="instantartsculpture"> - <function name="change" value="changeitem"/> - <item weight="0"> - <function name="use" value="use_instantartsculpture"/> - </item> - </resource> - - <resource name="instantartacademy"> - <function name="change" value="changeitem"/> - <item weight="0"> - <function name="use" value="use_instantartacademy"/> - </item> - </resource> - - <resource name="aurapotion50"> - <function name="change" value="changeitem"/> - <item weight="0"> - <function name="use" value="use_aurapotion50"/> - </item> - </resource> - - <resource name="bagpipeoffear"> - <function name="change" value="changeitem"/> - <item weight="0"> - <function name="use" value="use_bagpipeoffear"/> - </item> - </resource> - -</resources> +<?xml version="1.0"?> +<resources> + + <resource name="instantartsculpture"> + <function name="change" value="changeitem"/> + <item weight="0"> + <function name="use" value="use_instantartsculpture"/> + </item> + </resource> + + <resource name="instantartacademy"> + <function name="change" value="changeitem"/> + <item weight="0"> + <function name="use" value="use_instantartacademy"/> + </item> + </resource> + + <resource name="aurapotion50"> + <function name="change" value="changeitem"/> + <item weight="0"> + <function name="use" value="use_aurapotion50"/> + </item> + </resource> + + <resource name="bagpipeoffear"> + <function name="change" value="changeitem"/> + <item weight="0"> + <function name="use" value="use_bagpipeoffear"/> + </item> + </resource> + +</resources> diff --git a/res/eressea/buildings.xml b/res/eressea/buildings.xml index 64d65cff0..9d8d28da7 100644 --- a/res/eressea/buildings.xml +++ b/res/eressea/buildings.xml @@ -1,7 +1,7 @@ -<?xml version="1.0"?> -<buildings xmlns:xi="http://www.w3.org/2001/XInclude"> - <xi:include href="../buildings/castle.xml"/> - <building name="temple" maxsize="50" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" auraregen="1.00" /> - <building name="portal" maxsize="2" capacity="1" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" /> - <building name="pavilion" maxsize="2" capacity="1" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" /> -</buildings> +<?xml version="1.0"?> +<buildings xmlns:xi="http://www.w3.org/2001/XInclude"> + <xi:include href="../buildings/castle.xml"/> + <building name="temple" maxsize="50" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" auraregen="1.00" /> + <building name="portal" maxsize="2" capacity="1" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" /> + <building name="pavilion" maxsize="2" capacity="1" maxcapacity="2" nobuild="yes" nodestroy="yes" unique="yes" /> +</buildings> diff --git a/res/eressea/equipment.xml b/res/eressea/equipment.xml index 6e2f25b95..22fd4dd0f 100644 --- a/res/eressea/equipment.xml +++ b/res/eressea/equipment.xml @@ -1,19 +1,19 @@ -<?xml version="1.0"?> -<equipment> - - <set name="new_orc_unit"> - <skill name="polearm" level="1"/> - <skill name="melee" level="1"/> - </set> - - <set name="new_centaur_unit"> - <skill name="polearm" level="1"/> - <skill name="melee" level="1"/> - </set> - - <set name="seaserpent_spoils"> - <item name="dragonblood" amount="6"/> - <item name="seaserpenthead" amount="1"/> - </set> - -</equipment> +<?xml version="1.0"?> +<equipment> + + <set name="new_orc_unit"> + <skill name="polearm" level="1"/> + <skill name="melee" level="1"/> + </set> + + <set name="new_centaur_unit"> + <skill name="polearm" level="1"/> + <skill name="melee" level="1"/> + </set> + + <set name="seaserpent_spoils"> + <item name="dragonblood" amount="6"/> + <item name="seaserpenthead" amount="1"/> + </set> + +</equipment> diff --git a/res/eressea/items.xml b/res/eressea/items.xml index a1efc9620..7bc7d3aa6 100644 --- a/res/eressea/items.xml +++ b/res/eressea/items.xml @@ -1,199 +1,199 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<resources> - -<!-- xmas gimmicks --> - <resource name="snowball"> - <item notlost="yes" weight="0"> - <weapon bash="true" missile="true" skill="unarmed" offmod="0" defmod="0" reload="0" magres="0.0"> - <damage type="rider" value="3d8+8"/> - <damage type="footman" value="3d8+8"/> - <modifier type="missile_target" value="2"/> - <modifier type="skill" value="-90"/> - <modifier type="skill" value="100"> - <race name="snowman"/> - </modifier> - </weapon> - </item> - </resource> - - <resource name="snowman"> - <item notlost="yes" weight="1"> - <function name="use" value="lua_useitem"/> - </item> - </resource> - - <resource name="ring_of_levitation" appearance="ring"> - <item notlost="yes" weight="0" cursed="true"> - <function name="use" value="lua_useitem"/> - </item> - </resource> - - <resource name="birthdaycake"> - <item notlost="yes" weight="0"/> - </resource> - - <resource name="lebkuchenherz"> - <item notlost="yes" weight="0"/> - </resource> - -<!-- ambassador rewards --> - <resource name="seashell"> - <item cursed="true" weight="0"> - <function name="use" value="lua_useitem"/> - </item> - </resource> - -<!-- xmas 2005 --> - <resource name="stardust" appearance="vial"> - <item weight="0"> - <function name="use" value="lua_useitem"/> - </item> - </resource> - -<!-- xmas 2006 --> - <resource name="xmastree"> - <item weight="0"> - <function name="use" value="lua_useitem"/> - </item> - </resource> - -<!-- art rewards --> - <resource name="trappedairelemental"> - <item weight="0"> - <function name="use" value="use_trappedairelemental"/> - </item> - </resource> - - <resource name="hornofdancing"> - <item weight="0"> - <function name="use" value="use_hornofdancing"/> - </item> - </resource> - -<!-- museum items --> - <resource name="museumexitticket"> - <!-- you get your stuff back when leaving the museum --> - <item notlost="yes" weight="0"> - <function name="use" value="use_museumexitticket"/> - </item> - </resource> - - <resource name="museumticket"> - <!-- you get your stuff back when leaving the museum --> - <item weight="0"> - <function name="use" value="use_museumticket"/> - </item> - </resource> - -<!-- gimmicks, etc. --> - <resource name="aog"> - <!-- Amulett des Treffens --> - <item notlost="yes" cursed="true" weight="0"/> - </resource> - - <resource name="ao_daemon"> - <!-- summons igjarjuk --> - <item weight="0" score="6000" notlost="true" cursed="true"> - <function name="use" value="useigjarjuk"/> - <function name="give" value="giveigjarjuk"/> - </item> - </resource> - - <resource name="griphonwing"> - <!-- this lets you leave the arena --> - <item weight="0" score="6000" notlost="true" cursed="true"> - <function name="use" value="leave_arena"/> - <function name="give" value="giveigjarjuk"/> - </item> - </resource> - - <resource name="eyeofdragon"> - <!-- the arena gate, for one-time entry --> - <item weight="0" score="0"> - <function name="use" value="enter_arena"/> - </item> - </resource> - - <resource name="questkey1" appearance="key"> - <!-- Key for an old quest. placeholder item --> - <item notlost="yes" weight="0" /> - </resource> - - <resource name="questkey2" appearance="key"> - <!-- Key for an old quest. placeholder item --> - <item notlost="yes" weight="0" /> - </resource> - - <resource name="jadee_ring" appearance="ring"> - <!-- Wedding ring for Jadee --> - <item cursed="yes" notlost="yes" weight="0" /> - </resource> - - <resource name="wente_ring" appearance="ring"> - <!-- Wedding ring for Wildente --> - <item cursed="yes" notlost="yes" weight="0" /> - </resource> - - <resource name="jadee_dress"> - <!-- Wedding dress for Jadee --> - <item cursed="yes" notlost="yes" weight="0" /> - </resource> - - <resource name="wente_dress"> - <!-- Wedding dress for Wildente --> - <item cursed="yes" notlost="yes" weight="0" /> - </resource> - - <resource name="lmsreward"> - <!-- LMS reward --> - <item cursed="yes" notlost="yes" weight="0" /> - </resource> - - <!-- christmas items: start --> - <resource name="almond"> - <item weight="0"/> - </resource> - <resource name="apple"> - <item weight="0"/> - </resource> - <resource name="nut"> - <item weight="0"/> - </resource> - <resource name="cookie"> - <item weight="0"/> - </resource> - <!-- christmas items: end --> - - <resource name="adamantium" limited="yes" material="rm_adamantium"> - <item weight="200" score="200"> - <construction skill="mining" minskill="8" reqsize="1"/> - </item> - <resourcelimit> - <modifier type="require" building="mine"/> - <guard flag="mining"/> - </resourcelimit> - </resource> - - <resource name="adamantiumaxe"> - <item weight="100" score="500"> - <construction skill="weaponsmithing" minskill="8" reqsize="1"> - <requirement type="adamantium" quantity="1"/> - <requirement type="log" quantity="1"/> - </construction> - <weapon cut="true" skill="melee" offmod="2" defmod="-2" magres="0.30"> - <damage type="rider" value="3d4+15"/> - <damage type="footman" value="3d4+15"/> - </weapon> - </item> - </resource> - - <resource name="adamantiumplate"> - <item weight="100" score="2000"> - <construction skill="armorer" minskill="10" reqsize="1"> - <requirement type="adamantium" quantity="3"/> - </construction> - <armor ac="7" penalty="0.1"/> - </item> - </resource> - -</resources> +<?xml version="1.0" encoding="iso-8859-1" ?> +<resources> + +<!-- xmas gimmicks --> + <resource name="snowball"> + <item notlost="yes" weight="0"> + <weapon bash="true" missile="true" skill="unarmed" offmod="0" defmod="0" reload="0" magres="0.0"> + <damage type="rider" value="3d8+8"/> + <damage type="footman" value="3d8+8"/> + <modifier type="missile_target" value="2"/> + <modifier type="skill" value="-90"/> + <modifier type="skill" value="100"> + <race name="snowman"/> + </modifier> + </weapon> + </item> + </resource> + + <resource name="snowman"> + <item notlost="yes" weight="1"> + <function name="use" value="lua_useitem"/> + </item> + </resource> + + <resource name="ring_of_levitation" appearance="ring"> + <item notlost="yes" weight="0" cursed="true"> + <function name="use" value="lua_useitem"/> + </item> + </resource> + + <resource name="birthdaycake"> + <item notlost="yes" weight="0"/> + </resource> + + <resource name="lebkuchenherz"> + <item notlost="yes" weight="0"/> + </resource> + +<!-- ambassador rewards --> + <resource name="seashell"> + <item cursed="true" weight="0"> + <function name="use" value="lua_useitem"/> + </item> + </resource> + +<!-- xmas 2005 --> + <resource name="stardust" appearance="vial"> + <item weight="0"> + <function name="use" value="lua_useitem"/> + </item> + </resource> + +<!-- xmas 2006 --> + <resource name="xmastree"> + <item weight="0"> + <function name="use" value="lua_useitem"/> + </item> + </resource> + +<!-- art rewards --> + <resource name="trappedairelemental"> + <item weight="0"> + <function name="use" value="use_trappedairelemental"/> + </item> + </resource> + + <resource name="hornofdancing"> + <item weight="0"> + <function name="use" value="use_hornofdancing"/> + </item> + </resource> + +<!-- museum items --> + <resource name="museumexitticket"> + <!-- you get your stuff back when leaving the museum --> + <item notlost="yes" weight="0"> + <function name="use" value="use_museumexitticket"/> + </item> + </resource> + + <resource name="museumticket"> + <!-- you get your stuff back when leaving the museum --> + <item weight="0"> + <function name="use" value="use_museumticket"/> + </item> + </resource> + +<!-- gimmicks, etc. --> + <resource name="aog"> + <!-- Amulett des Treffens --> + <item notlost="yes" cursed="true" weight="0"/> + </resource> + + <resource name="ao_daemon"> + <!-- summons igjarjuk --> + <item weight="0" score="6000" notlost="true" cursed="true"> + <function name="use" value="useigjarjuk"/> + <function name="give" value="giveigjarjuk"/> + </item> + </resource> + + <resource name="griphonwing"> + <!-- this lets you leave the arena --> + <item weight="0" score="6000" notlost="true" cursed="true"> + <function name="use" value="leave_arena"/> + <function name="give" value="giveigjarjuk"/> + </item> + </resource> + + <resource name="eyeofdragon"> + <!-- the arena gate, for one-time entry --> + <item weight="0" score="0"> + <function name="use" value="enter_arena"/> + </item> + </resource> + + <resource name="questkey1" appearance="key"> + <!-- Key for an old quest. placeholder item --> + <item notlost="yes" weight="0" /> + </resource> + + <resource name="questkey2" appearance="key"> + <!-- Key for an old quest. placeholder item --> + <item notlost="yes" weight="0" /> + </resource> + + <resource name="jadee_ring" appearance="ring"> + <!-- Wedding ring for Jadee --> + <item cursed="yes" notlost="yes" weight="0" /> + </resource> + + <resource name="wente_ring" appearance="ring"> + <!-- Wedding ring for Wildente --> + <item cursed="yes" notlost="yes" weight="0" /> + </resource> + + <resource name="jadee_dress"> + <!-- Wedding dress for Jadee --> + <item cursed="yes" notlost="yes" weight="0" /> + </resource> + + <resource name="wente_dress"> + <!-- Wedding dress for Wildente --> + <item cursed="yes" notlost="yes" weight="0" /> + </resource> + + <resource name="lmsreward"> + <!-- LMS reward --> + <item cursed="yes" notlost="yes" weight="0" /> + </resource> + + <!-- christmas items: start --> + <resource name="almond"> + <item weight="0"/> + </resource> + <resource name="apple"> + <item weight="0"/> + </resource> + <resource name="nut"> + <item weight="0"/> + </resource> + <resource name="cookie"> + <item weight="0"/> + </resource> + <!-- christmas items: end --> + + <resource name="adamantium" limited="yes" material="rm_adamantium"> + <item weight="200" score="200"> + <construction skill="mining" minskill="8" reqsize="1"/> + </item> + <resourcelimit> + <modifier type="require" building="mine"/> + <guard flag="mining"/> + </resourcelimit> + </resource> + + <resource name="adamantiumaxe"> + <item weight="100" score="500"> + <construction skill="weaponsmithing" minskill="8" reqsize="1"> + <requirement type="adamantium" quantity="1"/> + <requirement type="log" quantity="1"/> + </construction> + <weapon cut="true" skill="melee" offmod="2" defmod="-2" magres="0.30"> + <damage type="rider" value="3d4+15"/> + <damage type="footman" value="3d4+15"/> + </weapon> + </item> + </resource> + + <resource name="adamantiumplate"> + <item weight="100" score="2000"> + <construction skill="armorer" minskill="10" reqsize="1"> + <requirement type="adamantium" quantity="3"/> + </construction> + <armor ac="7" penalty="0.1"/> + </item> + </resource> + +</resources> diff --git a/res/eressea/races.xml b/res/eressea/races.xml index cf529821d..1de3898b7 100644 --- a/res/eressea/races.xml +++ b/res/eressea/races.xml @@ -1,1373 +1,1373 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<races xmlns:xi="http://www.w3.org/2001/XInclude"> - - <race name="snowman" magres="0.800000" maxaura="0.000000" - regaura="0.000000" weight="500" capacity="200" equipment="no" - speed="1.000000" hp="1000" ac="4" damage="2d4" unarmedattack="10" - unarmeddefense="10" attackmodifier="8" defensemodifier="8" - fly="no" walk="no" canteach="no" getitem="yes"> - <attack type="4" damage="2d6+2"/> - <attack type="3" damage="2d6+2"/> - </race> - - <race name="human" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="75" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="trade" modifier="1"/> - <skill name="herbalism" modifier="-1"/> - <skill name="shipcraft" modifier="1"/> - <skill name="sailing" modifier="1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="wolf" default="yes"/> - <familiar race="dreamcat"/> - <familiar race="owl"/> - <familiar race="owl"/> - <familiar race="eagle"/> - <familiar race="imp"/> - </race> - <race name="kraken" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="2.000000" hp="300" damage="2d10" unarmedattack="0" unarmeddefense="0" attackmodifier="7" defensemodifier="7" coastal="yes" swim="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="perception" modifier="1"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="stealth" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="2d10"/> - <attack type="4" damage="1d10"/> - <attack type="4" damage="1d10"/> - <attack type="4" damage="1d10"/> - <attack type="4" damage="1d10"/> - <attack type="4" damage="1d10"/> - </race> - <race name="giantturtle" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="1600" capacity="600" speed="1.000000" hp="900" ac="7" damage="2d50" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="5" coastal="yes" swim="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="perception" modifier="1"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="stealth" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="2d50"/> - </race> - <race name="dolphin" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="2.000000" hp="24" damage="1d6" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="5" coastal="yes" swim="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="perception" modifier="1"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="1d6"/> - </race> - <race name="tiger" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="30" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="3" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="perception" modifier="1"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="2d6"/> - <attack type="4" damage="1d6"/> - <attack type="4" damage="1d6"/> - </race> - <race name="hellcat" magres="0.500000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="40" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="4" walk="yes" teach="no" giveitem="yes" getitem="yes" resistpierce="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="perception" modifier="1"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="2d6"/> - <attack type="4" damage="1d6"/> - <attack type="4" damage="1d6"/> - </race> - <race name="owl" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="9" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="2" defensemodifier="4" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="espionage" modifier="1"/> - <skill name="stealth" modifier="1"/> - <skill name="perception" modifier="5"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="1d4"/> - </race> - <race name="fairy" magres="0.800000" maxaura="1.000000" regaura="1.500000" recruitcost="50" weight="200" capacity="540" speed="1.000000" hp="6" damage="1d3" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="14" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="stealth" modifier="5"/> - <skill name="espionage" modifier="2"/> - <skill name="perception" modifier="2"/> - <skill name="magic" modifier="1"/> - <skill name="riding" modifier="-1"/> - <skill name="melee" modifier="-1"/> - <skill name="polearm" modifier="-1"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="1d3"/> - <attack type="4" damage="1d3"/> - <attack type="4" damage="1d3"/> - <attack type="4" damage="1d3"/> - </race> - <race name="dreamcat" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="10" damage="1d5" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="6" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" invinciblenonmagic="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="magic" modifier="1"/> - <skill name="espionage" modifier="1"/> - <skill name="stealth" modifier="1"/> - <skill name="perception" modifier="1"/> - <skill name="taxation" modifier="1"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <attack type="4" damage="1d5"/> - <attack type="4" damage="1d5"/> - </race> - <race name="imp" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="10" ac="1" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="4" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="magic" modifier="1"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-1"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="espionage" modifier="1"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="stealth" modifier="1"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="perception" modifier="1"/> - <skill name="taxation" modifier="1"/> - <attack type="4" damage="1d4"/> - <attack type="4" damage="1d4"/> - <attack type="1" damage="1d4"/> - <attack type="6" spell="fiery_dragonbreath"/> - </race> - <race name="ghost" magres="0.800000" maxaura="0.500000" regaura="0.100000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="30" ac="5" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="8" scarepeasants="yes" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes" invinciblenonmagic="yes"> - <ai splitsize="5000"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="magic" modifier="1"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-2"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="1d5"/> - <attack type="4" damage="1d5"/> - <attack type="1" damage="2d6"/> - <attack type="2" damage="2d30"/> - <attack type="3" damage="1d1"/> - </race> - <race name="wolf" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="25" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="3" scarepeasants="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="5000"/> - <function name="name" value="namegeneric"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="perception" modifier="2"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="2d6"/> - <attack type="4" damage="1d4"/> - <attack type="4" damage="1d4"/> - </race> - <race name="unicorn" magres="0.900000" maxaura="1.500000" regaura="1.500000" recruitcost="50" weight="5000" capacity="2000" speed="2.000000" hp="40" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="4" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="9999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="magic" modifier="2"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="stealth" modifier="4"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="perception" modifier="5"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="3d12"/> - <attack type="4" damage="2d4"/> - </race> - <race name="nymph" magres="0.900000" maxaura="1.000000" regaura="1.500000" recruitcost="50" weight="1000" capacity="540" speed="1.000000" hp="15" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> - <ai splitsize="9999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="2"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-2"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="4"/> - <skill name="magic" modifier="1"/> - <skill name="training" modifier="5"/> - <skill name="riding" modifier="5"/> - <skill name="armorer" modifier="-2"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="sailing" modifier="-2"/> - <skill name="espionage" modifier="2"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-2"/> - <skill name="stealth" modifier="3"/> - <skill name="entertainment" modifier="10"/> - <skill name="weaponsmithing" modifier="-2"/> - <skill name="cartmaking" modifier="-2"/> - <skill name="perception" modifier="2"/> - <skill name="taxation" modifier="-2"/> - <skill name="stamina" modifier="-1"/> - <attack type="1" damage="1d4"/> - <attack type="2" damage="2d20"/> - </race> - <race name="songdragon" magres="0.990000" maxaura="1.000000" regaura="1.000000" recruitcost="50" weight="1000" capacity="600" speed="1.500000" hp="40" ac="1" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="9999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="magic" modifier="1"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="2d4"/> - <attack type="4" damage="2d4"/> - <attack type="4" damage="2d4"/> - <attack type="6" spell="fiery_dragonbreath"/> - </race> - <race name="rat" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="100" capacity="540" speed="1.000000" hp="10" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="9999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="espionage" modifier="5"/> - <skill name="stealth" modifier="4"/> - <skill name="perception" modifier="2"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="1d4"/> - <attack type="4" damage="1d4"/> - </race> - <race name="eagle" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.500000" hp="15" damage="2d3" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="2" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="9999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="stealth" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="perception" modifier="2"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="2d3"/> - </race> - <race name="tunnelworm" magres="0.800000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="30000" capacity="10000" speed="1.000000" hp="300" ac="6" damage="3d20" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="1" scarepeasants="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="99999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="10"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="10"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="espionage" modifier="-99"/> - <skill name="quarrying" modifier="10"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="stealth" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="perception" modifier="-99"/> - <skill name="taxation" modifier="-99"/> - <skill name="stamina" modifier="2"/> - <attack type="4" damage="3d20"/> - <attack type="8" damage="1d10"/> - </race> - <race name="lynx" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="20" damage="2d3" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="5" walk="yes" teach="no" giveitem="yes" getitem="yes"> - <ai splitsize="99999"/> - <function name="initfamiliar" value="oldfamiliars"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="1"/> - <skill name="training" modifier="1"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="espionage" modifier="3"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="stealth" modifier="3"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="perception" modifier="4"/> - <skill name="taxation" modifier="-99"/> - <attack type="4" damage="2d3"/> - </race> - <race name="direwolf" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="20" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" walk="yes" teach="no" giveperson="yes"> - <function name="initfamiliar" value="oldfamiliars"/> - <ai splitsize="5000"/> - <attack type="4" damage="2d4"/> - </race> - <race name="peasant" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="50" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d6" unarmedattack="0" unarmeddefense="0" cannotmove="yes" teach="no"> - <ai splitsize="10000"/> - <attack type="1" damage="1d6"/> - </race> - <race name="braineater" magres="0.900000" maxaura="1.000000" regaura="1.000000" recruitcost="50000" weight="100" capacity="540" speed="1.000000" hp="20" ac="1" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes"> - <ai splitsize="500" killpeasants="yes" moverandom="yes" learn="yes"/> - <function name="name" value="namegeneric"/> - <function name="describe" value="describe_braineater"/> - <attack type="2" damage="3d15"/> - <attack type="3" damage="1d1"/> - <attack type="4" damage="1d1"/> - </race> - <race name="toad" magres="0.200000" maxaura="1.000000" regaura="1.000000" recruitcost="50" maintenance="10" weight="100" capacity="540" speed="1.000000" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes"> - <ai splitsize="1" learn="yes"/> - <skill name="alchemy" modifier="-10"/> - <skill name="crossbow" modifier="-10"/> - <skill name="mining" modifier="-10"/> - <skill name="bow" modifier="-10"/> - <skill name="building" modifier="-10"/> - <skill name="trade" modifier="-10"/> - <skill name="forestry" modifier="-10"/> - <skill name="catapult" modifier="-10"/> - <skill name="herbalism" modifier="-10"/> - <skill name="magic" modifier="-10"/> - <skill name="training" modifier="-10"/> - <skill name="riding" modifier="-10"/> - <skill name="armorer" modifier="-10"/> - <skill name="shipcraft" modifier="-10"/> - <skill name="melee" modifier="-10"/> - <skill name="sailing" modifier="-10"/> - <skill name="polearm" modifier="-10"/> - <skill name="espionage" modifier="-10"/> - <skill name="quarrying" modifier="-10"/> - <skill name="roadwork" modifier="-10"/> - <skill name="tactics" modifier="-10"/> - <skill name="stealth" modifier="2"/> - <skill name="entertainment" modifier="-10"/> - <skill name="weaponsmithing" modifier="-10"/> - <skill name="cartmaking" modifier="-10"/> - <skill name="perception" modifier="-10"/> - <skill name="taxation" modifier="-10"/> - <skill name="stamina" modifier="-10"/> - <attack type="4" damage="1d2"/> - </race> - <race name="smurf" weight="1000" capacity="540" speed="1.000000" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes"> - <ai splitsize="1" learn="yes"/> - <skill name="alchemy" modifier="-10"/> - <skill name="crossbow" modifier="-10"/> - <skill name="mining" modifier="-10"/> - <skill name="bow" modifier="-10"/> - <skill name="building" modifier="-10"/> - <skill name="trade" modifier="-10"/> - <skill name="forestry" modifier="-10"/> - <skill name="catapult" modifier="-10"/> - <skill name="herbalism" modifier="-10"/> - <skill name="magic" modifier="-10"/> - <skill name="training" modifier="-10"/> - <skill name="riding" modifier="-10"/> - <skill name="armorer" modifier="-10"/> - <skill name="shipcraft" modifier="-10"/> - <skill name="melee" modifier="-10"/> - <skill name="sailing" modifier="-10"/> - <skill name="polearm" modifier="-10"/> - <skill name="espionage" modifier="-10"/> - <skill name="quarrying" modifier="-10"/> - <skill name="roadwork" modifier="-10"/> - <skill name="tactics" modifier="-10"/> - <skill name="stealth" modifier="2"/> - <skill name="entertainment" modifier="-10"/> - <skill name="weaponsmithing" modifier="-10"/> - <skill name="cartmaking" modifier="-10"/> - <skill name="perception" modifier="-10"/> - <skill name="taxation" modifier="-10"/> - <skill name="stamina" modifier="-10"/> - <attack type="4" damage="1d2"/> - </race> - <race name="alp" magres="0.950000" maxaura="1.000000" regaura="1.000000" recruitcost="50000" weight="0" capacity="0" speed="1.500000" hp="20" ac="2" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="2" defensemodifier="20" fly="yes" walk="yes" canlearn="no" canteach="no"> - <ai splitsize="1"/> - <function name="name" value="namegeneric"/> - <attack type="1" damage="1d4"/> - </race> - <race name="mountainguard" unarmedguard="yes" magres="0.500000" maxaura="1.000000" regaura="0.500000" recruitcost="50000" weight="10000" capacity="2000" speed="0.000000" hp="1000" ac="12" damage="2d40" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="8" cannotmove="yes" canlearn="no" teach="no" noweapons="yes" giveitem="yes"> - <ai splitsize="1"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="2d40"/> - </race> - <race name="shadowmaster" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.000000" regaura="2.000000" recruitcost="50000" weight="500" capacity="540" speed="1.000000" hp="150" ac="4" damage="2d5" unarmedattack="0" unarmeddefense="0" attackmodifier="11" defensemodifier="13" scarepeasants="yes" walk="yes" teach="no" desert="yes"> - <ai splitsize="50" killpeasants="yes" moverandom="yes" learn="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="2d4"/> - <attack type="2" damage="2d30"/> - <attack type="3" damage="1d2"/> - </race> - <race name="shadowdemon" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.000000" regaura="1.000000" recruitcost="5000" weight="500" capacity="540" speed="1.000000" hp="50" ac="3" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="8" defensemodifier="11" scarepeasants="yes" walk="yes" teach="no" desert="yes" recruitethereal="yes"> - <ai splitsize="1000" killpeasants="yes" moverandom="yes" learn="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="2d3"/> - <attack type="3" damage="1d1"/> - </race> - <race name="stonegolem" stonegolem="true" magres="0.250000" maxaura="1.000000" regaura="0.100000" recruitcost="5000" weight="10000" capacity="2000" speed="1.000000" hp="60" ac="4" damage="2d12+6" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="2" walk="yes" canlearn="no" teach="no" giveitem="yes"> - <ai splitsize="50"/> - <skill name="building" modifier="14"/> - <skill name="roadwork" modifier="14"/> - <attack type="4" damage="2d10+4"/> - </race> - <race name="irongolem" irongolem="true" magres="0.250000" maxaura="1.000000" regaura="0.100000" recruitcost="5000" weight="10000" capacity="2000" speed="1.000000" hp="50" ac="2" damage="2d10+4" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="2" walk="yes" canlearn="no" teach="no" giveitem="yes"> - <ai splitsize="50"/> - <function name="name" value="namegeneric"/> - <skill name="armorer" modifier="14"/> - <skill name="weaponsmithing" modifier="14"/> - <attack type="4" damage="2d8+4"/> - </race> - <race name="spell" magres="0.000000" maxaura="1.000000" regaura="0.100000" recruitcost="0" weight="0" capacity="0" speed="0.000000" hp="1" damage="1d4" unarmedattack="-2" unarmeddefense="-2" canlearn="no" noheal="yes" noweapons="yes" illusionary="yes" invisible="yes" fly="yes" swim="yes" walk="yes"> - <ai splitsize="1"/> - <attack type="1" damage="1d4"/> - </race> - <race name="special" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="0" weight="0" capacity="0" speed="0.000000" hp="1" damage="1d4" unarmedattack="-2" unarmeddefense="-2"> - <ai splitsize="1"/> - <attack type="1" damage="1d4"/> - </race> - <race name="dracoid" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="50" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" walk="yes" teach="no" giveitem="yes" giveperson="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="name" value="namedracoid"/> - <attack type="4" damage="1d6"/> - <attack type="4" damage="1d6"/> - <attack type="1" damage="1d5"/> - </race> - <race name="catdragon" magres="0.900000" maxaura="1.000000" regaura="1.000000" recruitcost="500000" weight="20000" capacity="10000" speed="1.000000" hp="20" damage="2d40" unarmedattack="0" unarmeddefense="0" defensemodifier="50" fly="yes" walk="yes" teach="no" shapeshift="yes" giveitem="yes" giveperson="yes" getitem="yes"> - <ai splitsize="1"/> - <attack type="4" damage="2d40"/> - <attack type="4" damage="2d40"/> - <attack type="4" damage="2d40"/> - <attack type="4" damage="2d40"/> - </race> - <race name="ent" magres="0.250000" maxaura="1.000000" regaura="0.500000" recruitcost="5000" weight="5000" capacity="2500" speed="1.000000" hp="50" ac="4" damage="2d4+12" unarmedattack="0" unarmeddefense="0" attackmodifier="9" defensemodifier="7" scarepeasants="yes" walk="yes" teach="no"> - <ai splitsize="1000" moverandom="yes" learn="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="2d12"/> - <attack type="4" damage="2d12"/> - </race> - <race name="wyrm" magres="0.900000" maxaura="1.000000" regaura="3.000000" recruitcost="250000" weight="18000" capacity="1000000" speed="1.000000" hp="2700" ac="8" damage="2d60" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes"> - <ai splitsize="1" killpeasants="yes" learn="yes"/> - <function name="name" value="namedragon"/> - <function name="move" value="movedragon"/> - <skill name="magic" modifier="12"/> - <skill name="tactics" modifier="12"/> - <skill name="perception" modifier="10"/> - <attack type="4" damage="3d20"/> - <attack type="4" damage="3d20"/> - <attack type="4" damage="5d30"/> - <attack type="6" spell="powerful_dragonbreath"/> - </race> - <race name="dragon" magres="0.700000" maxaura="1.000000" regaura="2.000000" recruitcost="50000" weight="10000" capacity="1000000" speed="1.500000" hp="900" ac="6" damage="2d30" unarmedattack="0" unarmeddefense="0" attackmodifier="7" defensemodifier="7" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" giveitem="yes" resistbash="yes"> - <ai splitsize="2" killpeasants="yes" learn="yes"/> - <function name="name" value="namedragon"/> - <function name="age" value="agedragon"/> - <function name="move" value="movedragon"/> - <skill name="magic" modifier="8"/> - <skill name="tactics" modifier="8"/> - <skill name="perception" modifier="5"/> - <attack type="4" damage="2d20"/> - <attack type="4" damage="2d20"/> - <attack type="4" damage="3d30"/> - <attack type="6" spell="icy_dragonbreath"/> - </race> - <race name="youngdragon" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="10000" weight="20000" capacity="10000" speed="1.000000" hp="300" ac="4" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes"> - <ai splitsize="6" killpeasants="yes" learn="yes"/> - <function name="name" value="namedragon"/> - <function name="age" value="agefiredragon"/> - <function name="move" value="movedragon"/> - <skill name="magic" modifier="4"/> - <skill name="tactics" modifier="4"/> - <skill name="stealth" modifier="2"/> - <skill name="perception" modifier="2"/> - <attack type="4" damage="1d30"/> - <attack type="4" damage="1d30"/> - <attack type="4" damage="1d30"/> - <attack type="6" spell="fiery_dragonbreath"/> - </race> - <race name="illusion" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="0" capacity="0" speed="1.000000" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" walk="yes" canlearn="no" teach="no" noweapons="yes" illusionary="yes"> - <ai splitsize="999999"/> - <function name="age" value="ageillusion"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d1"/> - </race> - <race name="undead" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="2" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d7" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes"> - <ai splitsize="20000" moverandom="yes"/> - <function name="name" value="nameundead"/> - <function name="age" value="ageundead"/> - <attack type="4" damage="1d7"/> - <attack type="5"/> - </race> - <race name="aquarian" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" shipspeed="yes" playerrace="yes" coastal="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="mining" modifier="-2"/> - <skill name="building" modifier="-1"/> - <skill name="trade" modifier="2"/> - <skill name="armorer" modifier="-1"/> - <skill name="shipcraft" modifier="3"/> - <skill name="sailing" modifier="3"/> - <skill name="roadwork" modifier="-1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="giantturtle" default="yes"/> - <familiar race="dolphin"/> - <familiar race="giantturtle"/> - <familiar race="dolphin"/> - <familiar race="dolphin"/> - <familiar race="kraken"/> - </race> - <race name="cat" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="90" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" defensemodifier="1" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="alchemy" modifier="-1"/> - <skill name="mining" modifier="-2"/> - <skill name="building" modifier="-1"/> - <skill name="catapult" modifier="-1"/> - <skill name="herbalism" modifier="1"/> - <skill name="armorer" modifier="-1"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="sailing" modifier="-2"/> - <skill name="espionage" modifier="2"/> - <skill name="quarrying" modifier="-1"/> - <skill name="roadwork" modifier="-1"/> - <skill name="stealth" modifier="1"/> - <skill name="perception" modifier="2"/> - <skill name="taxation" modifier="1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="lynx" default="yes"/> - <familiar race="dreamcat"/> - <familiar race="lynx"/> - <familiar race="songdragon"/> - <familiar race="tiger"/> - <familiar race="hellcat"/> - </race> - <race name="halfling" magres="0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="18" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <param name="hunger.damage" value="1d14+14"/> - <skill name="crossbow" modifier="1"/> - <skill name="mining" modifier="1"/> - <skill name="bow" modifier="-1"/> - <skill name="building" modifier="1"/> - <skill name="trade" modifier="2"/> - <skill name="catapult" modifier="-1"/> - <skill name="herbalism" modifier="2"/> - <skill name="training" modifier="-1"/> - <skill name="riding" modifier="-1"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="melee" modifier="-1"/> - <skill name="sailing" modifier="-2"/> - <skill name="polearm" modifier="-1"/> - <skill name="espionage" modifier="1"/> - <skill name="roadwork" modifier="1"/> - <skill name="stealth" modifier="1"/> - <skill name="entertainment" modifier="1"/> - <skill name="cartmaking" modifier="2"/> - <skill name="perception" modifier="1"/> - <skill name="taxation" modifier="-1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="owl" default="yes"/> - <familiar race="rat"/> - <familiar race="eagle"/> - <familiar race="songdragon"/> - <familiar race="eagle"/> - <familiar race="rat"/> - </race> - <race name="insect" magres="0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" ac="2" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="crossbow" modifier="1"/> - <skill name="mining" modifier="1"/> - <skill name="bow" modifier="-2"/> - <skill name="building" modifier="2"/> - <skill name="trade" modifier="-1"/> - <skill name="forestry" modifier="1"/> - <skill name="herbalism" modifier="1"/> - <skill name="training" modifier="-3"/> - <skill name="riding" modifier="-3"/> - <skill name="armorer" modifier="2"/> - <skill name="melee" modifier="-1"/> - <skill name="polearm" modifier="1"/> - <skill name="roadwork" modifier="-1"/> - <skill name="tactics" modifier="-1"/> - <skill name="stealth" modifier="-1"/> - <skill name="entertainment" modifier="-2"/> - <skill name="perception" modifier="1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="ghost" default="yes"/> - <familiar race="rat"/> - <familiar race="owl"/> - <familiar race="rat"/> - <familiar race="tunnelworm"/> - <familiar race="imp"/> - </race> - <race name="demon" magres="0.150000" maxaura="1.000000" regaura="1.250000" recruitcost="150" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="50" ac="2" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" shapeshift="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="initfamiliar" value="oldfamiliars"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="alchemy" modifier="2"/> - <skill name="trade" modifier="-3"/> - <skill name="forestry" modifier="1"/> - <skill name="herbalism" modifier="-3"/> - <skill name="magic" modifier="1"/> - <skill name="training" modifier="-3"/> - <skill name="riding" modifier="-1"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="melee" modifier="1"/> - <skill name="sailing" modifier="-1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="-1"/> - <skill name="stealth" modifier="1"/> - <skill name="entertainment" modifier="-3"/> - <skill name="weaponsmithing" modifier="1"/> - <skill name="cartmaking" modifier="-2"/> - <skill name="perception" modifier="1"/> - <skill name="taxation" modifier="1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <attack type="5"/> - <familiar race="imp" default="yes"/> - <familiar race="imp"/> - <familiar race="ghost"/> - <familiar race="rat"/> - <familiar race="wolf"/> - <familiar race="imp"/> - </race> - <race name="troll" magres="0.100000" maxaura="1.000000" regaura="1.000000" recruitcost="90" maintenance="10" weight="2000" capacity="1080" speed="1.000000" hp="30" ac="1" damage="1d5+3" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="mining" modifier="2"/> - <skill name="bow" modifier="-2"/> - <skill name="building" modifier="2"/> - <skill name="catapult" modifier="2"/> - <skill name="herbalism" modifier="-1"/> - <skill name="training" modifier="-1"/> - <skill name="riding" modifier="-2"/> - <skill name="armorer" modifier="2"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="melee" modifier="1"/> - <skill name="sailing" modifier="-1"/> - <skill name="espionage" modifier="-3"/> - <skill name="quarrying" modifier="2"/> - <skill name="roadwork" modifier="2"/> - <skill name="tactics" modifier="-1"/> - <skill name="stealth" modifier="-3"/> - <skill name="entertainment" modifier="-1"/> - <skill name="perception" modifier="-1"/> - <skill name="taxation" modifier="1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5+3"/> - <familiar race="tunnelworm" default="yes"/> - <familiar race="rat"/> - <familiar race="rat"/> - <familiar race="eagle"/> - <familiar race="tunnelworm"/> - <familiar race="wolf"/> - </race> - <race name="goblin" magres="-0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="40" maintenance="10" weight="600" capacity="440" speed="1.000000" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="initfamiliar" value="oldfamiliars"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="alchemy" modifier="1"/> - <skill name="mining" modifier="1"/> - <skill name="building" modifier="1"/> - <skill name="trade" modifier="-1"/> - <skill name="catapult" modifier="1"/> - <skill name="magic" modifier="-1"/> - <skill name="shipcraft" modifier="-2"/> - <skill name="sailing" modifier="-2"/> - <skill name="roadwork" modifier="-2"/> - <skill name="tactics" modifier="-2"/> - <skill name="stealth" modifier="1"/> - <skill name="entertainment" modifier="-1"/> - <skill name="cartmaking" modifier="-1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="rat" default="yes"/> - <familiar race="songdragon"/> - <familiar race="imp"/> - <familiar race="rat"/> - <familiar race="rat"/> - <familiar race="imp"/> - </race> - <race name="clone" magres="0.900000" maxaura="0.000000" regaura="0.000000" recruitcost="0" weight="1000" capacity="540" speed="1.000000" hp="40" damage="0d0" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" canlearn="no" teach="no" noheal="yes"> - <ai splitsize="10000"/> - <skill name="alchemy" modifier="-99"/> - <skill name="crossbow" modifier="-99"/> - <skill name="mining" modifier="-99"/> - <skill name="bow" modifier="-99"/> - <skill name="building" modifier="-99"/> - <skill name="trade" modifier="-99"/> - <skill name="forestry" modifier="-99"/> - <skill name="catapult" modifier="-99"/> - <skill name="herbalism" modifier="-99"/> - <skill name="magic" modifier="-99"/> - <skill name="training" modifier="-99"/> - <skill name="riding" modifier="-99"/> - <skill name="armorer" modifier="-99"/> - <skill name="shipcraft" modifier="-99"/> - <skill name="melee" modifier="-99"/> - <skill name="sailing" modifier="-99"/> - <skill name="polearm" modifier="-99"/> - <skill name="espionage" modifier="-99"/> - <skill name="quarrying" modifier="-99"/> - <skill name="roadwork" modifier="-99"/> - <skill name="tactics" modifier="-99"/> - <skill name="stealth" modifier="-99"/> - <skill name="entertainment" modifier="-99"/> - <skill name="weaponsmithing" modifier="-99"/> - <skill name="cartmaking" modifier="-99"/> - <skill name="perception" modifier="-99"/> - <skill name="taxation" modifier="-99"/> - <skill name="stamina" modifier="-99"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="0d0"/> - </race> - <race name="template" magres="1.000000" maxaura="0.000000" regaura="0.000000" recruitcost="0" weight="0" capacity="1000" speed="10.000000" hp="10" damage="1d4" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" fly="yes" swim="yes" walk="yes" shapeshift="yes" shapeshiftany="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" recruitunlimited="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <attack type="1" damage="1d4"/> - </race> - <race name="gnome" magres="1.000000" maxaura="0.000000" regaura="0.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="50" damage="1d4" unarmedattack="10" unarmeddefense="10" attackmodifier="10" defensemodifier="10" walk="yes" teach="no"> - <ai splitsize="10000"/> - <skill name="tactics" modifier="1"/> - <skill name="perception" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="1" damage="1d4"/> - </race> - <race name="museumghost" magres="1.000000" maxaura="0.000000" regaura="0.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="50" damage="1d4" unarmedattack="10" unarmeddefense="10" attackmodifier="10" defensemodifier="10" walk="yes" teach="no"> - <ai splitsize="10000"/> - <skill name="tactics" modifier="1"/> - <skill name="perception" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="2" damage="5d600"/> - <attack type="3" damage="5d5"/> - <attack type="2" damage="5d600"/> - <attack type="2" damage="5d600"/> - <attack type="3" damage="5d5"/> - <attack type="2" damage="5d600"/> - <attack type="1" damage="1d4"/> - </race> - <race name="ghast" magres="0.600000" maxaura="1.000000" regaura="1.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="60" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes"> - <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> - <function name="name" value="nameghoul"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="4" damage="2d8"/> - <attack type="3" damage="1d5"/> - <attack type="3" damage="1d5"/> - <attack type="2" damage="1d30"/> - <attack type="2" damage="1d30"/> - </race> - <race name="ghoul" magres="0.300000" maxaura="1.000000" regaura="1.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="30" ac="1" damage="1d7" unarmedattack="3" unarmeddefense="3" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes"> - <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> - <function name="name" value="nameghoul"/> - <function name="age" value="ageghoul"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="4" damage="2d6"/> - <attack type="3" damage="1d2"/> - <attack type="3" damage="1d2"/> - <attack type="2" damage="1d30"/> - </race> - <race name="juju-zombie" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="8" weight="1000" capacity="540" speed="1.000000" hp="80" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistbash="yes" resistcut="yes" resistpierce="yes"> - <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> - <function name="name" value="namezombie"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="1" damage="1d7"/> - <attack type="3" damage="1d1"/> - <attack type="3" damage="1d1"/> - </race> - <race name="zombie" magres="0.200000" maxaura="1.000000" regaura="1.000000" recruitcost="4" weight="1000" capacity="540" speed="1.000000" hp="40" ac="1" damage="1d7" unarmedattack="2" unarmeddefense="2" attackmodifier="5" defensemodifier="5" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> - <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> - <function name="name" value="namezombie"/> - <function name="age" value="agezombie"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="1" damage="1d7"/> - </race> - <race name="skeletonlord" magres="0.300000" maxaura="1.000000" regaura="1.000000" recruitcost="2" weight="1000" capacity="540" speed="1.000000" hp="60" ac="4" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> - <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> - <function name="name" value="nameskeleton"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="1" damage="1d7"/> - <attack type="1" damage="1d7"/> - </race> - <race name="skeleton" magres="0.100000" maxaura="1.000000" regaura="1.000000" recruitcost="0" weight="500" capacity="540" speed="1.000000" hp="20" ac="1" damage="1d7" unarmedattack="1" unarmeddefense="1" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> - <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> - <function name="name" value="nameskeleton"/> - <function name="age" value="ageskeleton"/> - <skill name="crossbow" modifier="1"/> - <skill name="bow" modifier="1"/> - <skill name="catapult" modifier="1"/> - <skill name="riding" modifier="1"/> - <skill name="melee" modifier="1"/> - <skill name="polearm" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="stamina" modifier="1"/> - <skill name="unarmed" modifier="1"/> - <attack type="1" damage="1d7"/> - </race> - <race name="centaur" magres="0.000000" maxaura="0.750000" regaura="0.750000" recruitcost="100" maintenance="10" weight="5000" capacity="2040" speed="1.000000" hp="30" damage="2d5" unarmedattack="0" unarmeddefense="0" playerrace="yes" walk="yes" horse="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" recruithorses="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <skill name="crossbow" modifier="1"/> - <skill name="mining" modifier="-3"/> - <skill name="bow" modifier="1"/> - <skill name="building" modifier="-2"/> - <skill name="trade" modifier="1"/> - <skill name="catapult" modifier="-2"/> - <skill name="herbalism" modifier="1"/> - <skill name="training" modifier="4"/> - <skill name="armorer" modifier="-1"/> - <skill name="shipcraft" modifier="-4"/> - <skill name="sailing" modifier="-4"/> - <skill name="polearm" modifier="1"/> - <skill name="espionage" modifier="-1"/> - <skill name="quarrying" modifier="-1"/> - <skill name="stealth" modifier="-1"/> - <skill name="weaponsmithing" modifier="1"/> - <skill name="cartmaking" modifier="1"/> - <skill name="taxation" modifier="1"/> - <attack type="1" damage="2d5"/> - <familiar race="eagle" default="yes"/> - <familiar race="fairy"/> - <familiar race="owl"/> - <familiar race="unicorn"/> - <familiar race="nymph"/> - <familiar race="imp"/> - </race> - <race name="shadowknight" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noblock="yes"> - <ai splitsize="20000" moverandom="yes"/> - <function name="name" value="namegeneric"/> - <attack type="1" damage="1d1"/> - </race> - <race name="seaserpent" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="5000" weight="20000" capacity="5000" speed="1.000000" hp="600" ac="3" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" scarepeasants="yes" swim="yes" teach="no" getitem="yes" resistbash="yes"> - <ai splitsize="6" killpeasants="yes" moverandom="yes" learn="yes"/> - <function name="name" value="namegeneric"/> - <function name="move" value="moveswimming"/> - <skill name="tactics" modifier="4"/> - <attack type="4" damage="1d30"/> - <attack type="4" damage="1d30"/> - <attack type="4" damage="1d30"/> - <attack type="6" spell="fiery_dragonbreath"/> - <attack type="8" damage="1d10"/> - </race> - <race name="snotling" magres="-0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="50" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="alchemy" modifier="1"/> - <skill name="mining" modifier="1"/> - <skill name="building" modifier="1"/> - <skill name="trade" modifier="-3"/> - <skill name="forestry" modifier="1"/> - <skill name="herbalism" modifier="-2"/> - <skill name="magic" modifier="-1"/> - <skill name="training" modifier="-1"/> - <skill name="armorer" modifier="1"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="sailing" modifier="-1"/> - <skill name="espionage" modifier="-1"/> - <skill name="quarrying" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="entertainment" modifier="-2"/> - <skill name="weaponsmithing" modifier="2"/> - <skill name="cartmaking" modifier="-1"/> - <skill name="taxation" modifier="1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="goblin" default="yes"/> - <familiar race="ghost"/> - <familiar race="imp"/> - <familiar race="rat"/> - <familiar race="wolf"/> - <familiar race="demon"/> - </race> - - <!-- race name="old_orc" magres="-0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="50" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="alchemy" modifier="1"/> - <skill name="mining" modifier="1"/> - <skill name="building" modifier="1"/> - <skill name="trade" modifier="-3"/> - <skill name="forestry" modifier="1"/> - <skill name="herbalism" modifier="-2"/> - <skill name="magic" modifier="-1"/> - <skill name="training" modifier="-1"/> - <skill name="armorer" modifier="1"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="sailing" modifier="-1"/> - <skill name="espionage" modifier="-1"/> - <skill name="quarrying" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="entertainment" modifier="-2"/> - <skill name="weaponsmithing" modifier="2"/> - <skill name="cartmaking" modifier="-1"/> - <skill name="taxation" modifier="1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="goblin" default="yes"/> - <familiar race="ghost"/> - <familiar race="imp"/> - <familiar race="rat"/> - <familiar race="wolf"/> - <familiar race="demon"/> - </race --> - <race name="elf" magres="0.100000" maxaura="1.000000" regaura="1.250000" recruitcost="130" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="18" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="alchemy" modifier="-1"/> - <skill name="mining" modifier="-2"/> - <skill name="bow" modifier="2"/> - <skill name="building" modifier="-1"/> - <skill name="catapult" modifier="-2"/> - <skill name="herbalism" modifier="2"/> - <skill name="magic" modifier="1"/> - <skill name="training" modifier="1"/> - <skill name="armorer" modifier="-1"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="sailing" modifier="-1"/> - <skill name="quarrying" modifier="-1"/> - <skill name="roadwork" modifier="-1"/> - <skill name="stealth" modifier="1"/> - <skill name="perception" modifier="1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="lynx" default="yes"/> - <familiar race="fairy"/> - <familiar race="owl"/> - <familiar race="nymph"/> - <familiar race="unicorn"/> - <familiar race="imp"/> - </race> - <race name="dwarf" magres="0.050000" maxaura="1.000000" regaura="0.500000" recruitcost="110" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <skill name="mining" modifier="2"/> - <skill name="bow" modifier="-1"/> - <skill name="building" modifier="2"/> - <skill name="trade" modifier="1"/> - <skill name="forestry" modifier="-1"/> - <skill name="catapult" modifier="2"/> - <skill name="herbalism" modifier="-2"/> - <skill name="magic" modifier="-2"/> - <skill name="training" modifier="-2"/> - <skill name="riding" modifier="-2"/> - <skill name="armorer" modifier="2"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="melee" modifier="1"/> - <skill name="sailing" modifier="-2"/> - <skill name="quarrying" modifier="2"/> - <skill name="roadwork" modifier="2"/> - <skill name="stealth" modifier="-1"/> - <skill name="entertainment" modifier="-1"/> - <skill name="weaponsmithing" modifier="2"/> - <skill name="taxation" modifier="1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="tunnelworm" default="yes"/> - <familiar race="eagle"/> - <familiar race="owl"/> - <familiar race="lynx"/> - <familiar race="wolf"/> - <familiar race="rat"/> - </race> - <race name="orc" magres="-0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="70" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <param name="recruit_multi" value="0.5"/> - <skill name="alchemy" modifier="1"/> - <skill name="mining" modifier="1"/> - <skill name="building" modifier="1"/> - <skill name="trade" modifier="-3"/> - <skill name="forestry" modifier="1"/> - <skill name="herbalism" modifier="-2"/> - <skill name="magic" modifier="-1"/> - <skill name="training" modifier="-1"/> - <skill name="armorer" modifier="1"/> - <skill name="shipcraft" modifier="-1"/> - <skill name="sailing" modifier="-1"/> - <skill name="espionage" modifier="-1"/> - <skill name="quarrying" modifier="1"/> - <skill name="tactics" modifier="1"/> - <skill name="entertainment" modifier="-2"/> - <skill name="weaponsmithing" modifier="2"/> - <skill name="cartmaking" modifier="-1"/> - <skill name="taxation" modifier="1"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="goblin" default="yes"/> - <familiar race="ghost"/> - <familiar race="imp"/> - <familiar race="rat"/> - <familiar race="wolf"/> - <familiar race="demon"/> - </race> - <race name="shadowdragon" magres="0.950000" maxaura="1.000000" regaura="3.000000" recruitcost="2500000" weight="100" capacity="100000" speed="1.000000" hp="2700" ac="10" damage="2d60" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="12" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes"> - <ai splitsize="1" killpeasants="yes" learn="yes"/> - <function name="name" value="namedragon"/> - <function name="move" value="movedragon"/> - <skill name="tactics" modifier="20"/> - <skill name="perception" modifier="20"/> - <attack type="4" damage="5d30"/> - <attack type="4" damage="3d20"/> - <attack type="4" damage="3d20"/> - <attack type="4" damage="5d30"/> - <attack type="6" spell="drain_skills"/> - <attack type="6" spell="aura_of_fear"/> - <precombatspell spell="shadowcall"/> - </race> - <race name="shadowbat" magres="0.800000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="500" capacity="540" speed="1.000000" hp="1" ac="4" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes"> - <ai splitsize="5000" killpeasants="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="1d6"/> - <attack type="3" damage="1d1"/> - </race> - <race name="nightmare" magres="0.500000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="100" capacity="540" speed="1.000000" hp="80" ac="10" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" invinciblenonmagic="yes"> - <ai splitsize="500" killpeasants="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="1d4"/> - <attack type="4" damage="1d4"/> - <attack type="4" damage="1d4"/> - <attack type="3" damage="1d4"/> - <attack type="2" damage="1d10"/> - </race> - <race name="vampunicorn" magres="1.000000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="5000" capacity="2000" speed="1.000000" hp="30" ac="4" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" teach="no" getitem="yes"> - <ai splitsize="5000" killpeasants="yes"/> - <function name="name" value="namegeneric"/> - <attack type="4" damage="2d10"/> - <attack type="3" damage="1d4"/> - <attack type="3" damage="1d4"/> - <attack type="3" damage="1d4"/> - <attack type="3" damage="1d4"/> - <attack type="2" damage="2d60"/> - </race> -</races> +<?xml version="1.0" encoding="iso-8859-1" ?> +<races xmlns:xi="http://www.w3.org/2001/XInclude"> + + <race name="snowman" magres="0.800000" maxaura="0.000000" + regaura="0.000000" weight="500" capacity="200" equipment="no" + speed="1.000000" hp="1000" ac="4" damage="2d4" unarmedattack="10" + unarmeddefense="10" attackmodifier="8" defensemodifier="8" + fly="no" walk="no" canteach="no" getitem="yes"> + <attack type="4" damage="2d6+2"/> + <attack type="3" damage="2d6+2"/> + </race> + + <race name="human" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="75" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="trade" modifier="1"/> + <skill name="herbalism" modifier="-1"/> + <skill name="shipcraft" modifier="1"/> + <skill name="sailing" modifier="1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="wolf" default="yes"/> + <familiar race="dreamcat"/> + <familiar race="owl"/> + <familiar race="owl"/> + <familiar race="eagle"/> + <familiar race="imp"/> + </race> + <race name="kraken" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="2.000000" hp="300" damage="2d10" unarmedattack="0" unarmeddefense="0" attackmodifier="7" defensemodifier="7" coastal="yes" swim="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="perception" modifier="1"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="stealth" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="2d10"/> + <attack type="4" damage="1d10"/> + <attack type="4" damage="1d10"/> + <attack type="4" damage="1d10"/> + <attack type="4" damage="1d10"/> + <attack type="4" damage="1d10"/> + </race> + <race name="giantturtle" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="1600" capacity="600" speed="1.000000" hp="900" ac="7" damage="2d50" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="5" coastal="yes" swim="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="perception" modifier="1"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="stealth" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="2d50"/> + </race> + <race name="dolphin" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="2.000000" hp="24" damage="1d6" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="5" coastal="yes" swim="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="perception" modifier="1"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="1d6"/> + </race> + <race name="tiger" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="30" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="3" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="perception" modifier="1"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="2d6"/> + <attack type="4" damage="1d6"/> + <attack type="4" damage="1d6"/> + </race> + <race name="hellcat" magres="0.500000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="40" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="4" walk="yes" teach="no" giveitem="yes" getitem="yes" resistpierce="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="perception" modifier="1"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="2d6"/> + <attack type="4" damage="1d6"/> + <attack type="4" damage="1d6"/> + </race> + <race name="owl" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="9" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="2" defensemodifier="4" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="espionage" modifier="1"/> + <skill name="stealth" modifier="1"/> + <skill name="perception" modifier="5"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="1d4"/> + </race> + <race name="fairy" magres="0.800000" maxaura="1.000000" regaura="1.500000" recruitcost="50" weight="200" capacity="540" speed="1.000000" hp="6" damage="1d3" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="14" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="stealth" modifier="5"/> + <skill name="espionage" modifier="2"/> + <skill name="perception" modifier="2"/> + <skill name="magic" modifier="1"/> + <skill name="riding" modifier="-1"/> + <skill name="melee" modifier="-1"/> + <skill name="polearm" modifier="-1"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="1d3"/> + <attack type="4" damage="1d3"/> + <attack type="4" damage="1d3"/> + <attack type="4" damage="1d3"/> + </race> + <race name="dreamcat" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="10" damage="1d5" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="6" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" invinciblenonmagic="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="magic" modifier="1"/> + <skill name="espionage" modifier="1"/> + <skill name="stealth" modifier="1"/> + <skill name="perception" modifier="1"/> + <skill name="taxation" modifier="1"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <attack type="4" damage="1d5"/> + <attack type="4" damage="1d5"/> + </race> + <race name="imp" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="10" ac="1" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="4" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="magic" modifier="1"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-1"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="espionage" modifier="1"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="stealth" modifier="1"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="perception" modifier="1"/> + <skill name="taxation" modifier="1"/> + <attack type="4" damage="1d4"/> + <attack type="4" damage="1d4"/> + <attack type="1" damage="1d4"/> + <attack type="6" spell="fiery_dragonbreath"/> + </race> + <race name="ghost" magres="0.800000" maxaura="0.500000" regaura="0.100000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="30" ac="5" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="5" defensemodifier="8" scarepeasants="yes" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes" invinciblenonmagic="yes"> + <ai splitsize="5000"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="magic" modifier="1"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-2"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="1d5"/> + <attack type="4" damage="1d5"/> + <attack type="1" damage="2d6"/> + <attack type="2" damage="2d30"/> + <attack type="3" damage="1d1"/> + </race> + <race name="wolf" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="25" damage="2d6" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="3" scarepeasants="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="5000"/> + <function name="name" value="namegeneric"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="perception" modifier="2"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="2d6"/> + <attack type="4" damage="1d4"/> + <attack type="4" damage="1d4"/> + </race> + <race name="unicorn" magres="0.900000" maxaura="1.500000" regaura="1.500000" recruitcost="50" weight="5000" capacity="2000" speed="2.000000" hp="40" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="4" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="9999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="magic" modifier="2"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="stealth" modifier="4"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="perception" modifier="5"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="3d12"/> + <attack type="4" damage="2d4"/> + </race> + <race name="nymph" magres="0.900000" maxaura="1.000000" regaura="1.500000" recruitcost="50" weight="1000" capacity="540" speed="1.000000" hp="15" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" walk="yes" teach="no" giveitem="yes" getitem="yes" equipment="yes"> + <ai splitsize="9999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="2"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-2"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="4"/> + <skill name="magic" modifier="1"/> + <skill name="training" modifier="5"/> + <skill name="riding" modifier="5"/> + <skill name="armorer" modifier="-2"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="sailing" modifier="-2"/> + <skill name="espionage" modifier="2"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-2"/> + <skill name="stealth" modifier="3"/> + <skill name="entertainment" modifier="10"/> + <skill name="weaponsmithing" modifier="-2"/> + <skill name="cartmaking" modifier="-2"/> + <skill name="perception" modifier="2"/> + <skill name="taxation" modifier="-2"/> + <skill name="stamina" modifier="-1"/> + <attack type="1" damage="1d4"/> + <attack type="2" damage="2d20"/> + </race> + <race name="songdragon" magres="0.990000" maxaura="1.000000" regaura="1.000000" recruitcost="50" weight="1000" capacity="600" speed="1.500000" hp="40" ac="1" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="9999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="magic" modifier="1"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="2d4"/> + <attack type="4" damage="2d4"/> + <attack type="4" damage="2d4"/> + <attack type="6" spell="fiery_dragonbreath"/> + </race> + <race name="rat" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="100" capacity="540" speed="1.000000" hp="10" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="9999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="espionage" modifier="5"/> + <skill name="stealth" modifier="4"/> + <skill name="perception" modifier="2"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="1d4"/> + <attack type="4" damage="1d4"/> + </race> + <race name="eagle" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.500000" hp="15" damage="2d3" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="2" fly="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="9999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="stealth" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="perception" modifier="2"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="2d3"/> + </race> + <race name="tunnelworm" magres="0.800000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="30000" capacity="10000" speed="1.000000" hp="300" ac="6" damage="3d20" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="1" scarepeasants="yes" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="99999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="10"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="10"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="espionage" modifier="-99"/> + <skill name="quarrying" modifier="10"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="stealth" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="perception" modifier="-99"/> + <skill name="taxation" modifier="-99"/> + <skill name="stamina" modifier="2"/> + <attack type="4" damage="3d20"/> + <attack type="8" damage="1d10"/> + </race> + <race name="lynx" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="20" damage="2d3" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="5" walk="yes" teach="no" giveitem="yes" getitem="yes"> + <ai splitsize="99999"/> + <function name="initfamiliar" value="oldfamiliars"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="1"/> + <skill name="training" modifier="1"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="espionage" modifier="3"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="stealth" modifier="3"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="perception" modifier="4"/> + <skill name="taxation" modifier="-99"/> + <attack type="4" damage="2d3"/> + </race> + <race name="direwolf" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="500" capacity="540" speed="1.000000" hp="20" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="1" walk="yes" teach="no" giveperson="yes"> + <function name="initfamiliar" value="oldfamiliars"/> + <ai splitsize="5000"/> + <attack type="4" damage="2d4"/> + </race> + <race name="peasant" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="50" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d6" unarmedattack="0" unarmeddefense="0" cannotmove="yes" teach="no"> + <ai splitsize="10000"/> + <attack type="1" damage="1d6"/> + </race> + <race name="braineater" magres="0.900000" maxaura="1.000000" regaura="1.000000" recruitcost="50000" weight="100" capacity="540" speed="1.000000" hp="20" ac="1" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes"> + <ai splitsize="500" killpeasants="yes" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> + <function name="describe" value="describe_braineater"/> + <attack type="2" damage="3d15"/> + <attack type="3" damage="1d1"/> + <attack type="4" damage="1d1"/> + </race> + <race name="toad" magres="0.200000" maxaura="1.000000" regaura="1.000000" recruitcost="50" maintenance="10" weight="100" capacity="540" speed="1.000000" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes"> + <ai splitsize="1" learn="yes"/> + <skill name="alchemy" modifier="-10"/> + <skill name="crossbow" modifier="-10"/> + <skill name="mining" modifier="-10"/> + <skill name="bow" modifier="-10"/> + <skill name="building" modifier="-10"/> + <skill name="trade" modifier="-10"/> + <skill name="forestry" modifier="-10"/> + <skill name="catapult" modifier="-10"/> + <skill name="herbalism" modifier="-10"/> + <skill name="magic" modifier="-10"/> + <skill name="training" modifier="-10"/> + <skill name="riding" modifier="-10"/> + <skill name="armorer" modifier="-10"/> + <skill name="shipcraft" modifier="-10"/> + <skill name="melee" modifier="-10"/> + <skill name="sailing" modifier="-10"/> + <skill name="polearm" modifier="-10"/> + <skill name="espionage" modifier="-10"/> + <skill name="quarrying" modifier="-10"/> + <skill name="roadwork" modifier="-10"/> + <skill name="tactics" modifier="-10"/> + <skill name="stealth" modifier="2"/> + <skill name="entertainment" modifier="-10"/> + <skill name="weaponsmithing" modifier="-10"/> + <skill name="cartmaking" modifier="-10"/> + <skill name="perception" modifier="-10"/> + <skill name="taxation" modifier="-10"/> + <skill name="stamina" modifier="-10"/> + <attack type="4" damage="1d2"/> + </race> + <race name="smurf" weight="1000" capacity="540" speed="1.000000" hp="10" damage="1d2" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" giveperson="yes" giveunit="yes" getitem="yes" walk="yes"> + <ai splitsize="1" learn="yes"/> + <skill name="alchemy" modifier="-10"/> + <skill name="crossbow" modifier="-10"/> + <skill name="mining" modifier="-10"/> + <skill name="bow" modifier="-10"/> + <skill name="building" modifier="-10"/> + <skill name="trade" modifier="-10"/> + <skill name="forestry" modifier="-10"/> + <skill name="catapult" modifier="-10"/> + <skill name="herbalism" modifier="-10"/> + <skill name="magic" modifier="-10"/> + <skill name="training" modifier="-10"/> + <skill name="riding" modifier="-10"/> + <skill name="armorer" modifier="-10"/> + <skill name="shipcraft" modifier="-10"/> + <skill name="melee" modifier="-10"/> + <skill name="sailing" modifier="-10"/> + <skill name="polearm" modifier="-10"/> + <skill name="espionage" modifier="-10"/> + <skill name="quarrying" modifier="-10"/> + <skill name="roadwork" modifier="-10"/> + <skill name="tactics" modifier="-10"/> + <skill name="stealth" modifier="2"/> + <skill name="entertainment" modifier="-10"/> + <skill name="weaponsmithing" modifier="-10"/> + <skill name="cartmaking" modifier="-10"/> + <skill name="perception" modifier="-10"/> + <skill name="taxation" modifier="-10"/> + <skill name="stamina" modifier="-10"/> + <attack type="4" damage="1d2"/> + </race> + <race name="alp" magres="0.950000" maxaura="1.000000" regaura="1.000000" recruitcost="50000" weight="0" capacity="0" speed="1.500000" hp="20" ac="2" damage="1d4" unarmedattack="0" unarmeddefense="0" attackmodifier="2" defensemodifier="20" fly="yes" walk="yes" canlearn="no" canteach="no"> + <ai splitsize="1"/> + <function name="name" value="namegeneric"/> + <attack type="1" damage="1d4"/> + </race> + <race name="mountainguard" unarmedguard="yes" magres="0.500000" maxaura="1.000000" regaura="0.500000" recruitcost="50000" weight="10000" capacity="2000" speed="0.000000" hp="1000" ac="12" damage="2d40" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="8" cannotmove="yes" canlearn="no" teach="no" noweapons="yes" giveitem="yes"> + <ai splitsize="1"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="2d40"/> + </race> + <race name="shadowmaster" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.000000" regaura="2.000000" recruitcost="50000" weight="500" capacity="540" speed="1.000000" hp="150" ac="4" damage="2d5" unarmedattack="0" unarmeddefense="0" attackmodifier="11" defensemodifier="13" scarepeasants="yes" walk="yes" teach="no" desert="yes"> + <ai splitsize="50" killpeasants="yes" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="2d4"/> + <attack type="2" damage="2d30"/> + <attack type="3" damage="1d2"/> + </race> + <race name="shadowdemon" cansail="no" cansteal="no" canlearn="no" magres="0.750000" maxaura="1.000000" regaura="1.000000" recruitcost="5000" weight="500" capacity="540" speed="1.000000" hp="50" ac="3" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="8" defensemodifier="11" scarepeasants="yes" walk="yes" teach="no" desert="yes" recruitethereal="yes"> + <ai splitsize="1000" killpeasants="yes" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="2d3"/> + <attack type="3" damage="1d1"/> + </race> + <race name="stonegolem" stonegolem="true" magres="0.250000" maxaura="1.000000" regaura="0.100000" recruitcost="5000" weight="10000" capacity="2000" speed="1.000000" hp="60" ac="4" damage="2d12+6" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="2" walk="yes" canlearn="no" teach="no" giveitem="yes"> + <ai splitsize="50"/> + <skill name="building" modifier="14"/> + <skill name="roadwork" modifier="14"/> + <attack type="4" damage="2d10+4"/> + </race> + <race name="irongolem" irongolem="true" magres="0.250000" maxaura="1.000000" regaura="0.100000" recruitcost="5000" weight="10000" capacity="2000" speed="1.000000" hp="50" ac="2" damage="2d10+4" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="2" walk="yes" canlearn="no" teach="no" giveitem="yes"> + <ai splitsize="50"/> + <function name="name" value="namegeneric"/> + <skill name="armorer" modifier="14"/> + <skill name="weaponsmithing" modifier="14"/> + <attack type="4" damage="2d8+4"/> + </race> + <race name="spell" magres="0.000000" maxaura="1.000000" regaura="0.100000" recruitcost="0" weight="0" capacity="0" speed="0.000000" hp="1" damage="1d4" unarmedattack="-2" unarmeddefense="-2" canlearn="no" noheal="yes" noweapons="yes" illusionary="yes" invisible="yes" fly="yes" swim="yes" walk="yes"> + <ai splitsize="1"/> + <attack type="1" damage="1d4"/> + </race> + <race name="special" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="0" weight="0" capacity="0" speed="0.000000" hp="1" damage="1d4" unarmedattack="-2" unarmeddefense="-2"> + <ai splitsize="1"/> + <attack type="1" damage="1d4"/> + </race> + <race name="dracoid" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="50" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" walk="yes" teach="no" giveitem="yes" giveperson="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="name" value="namedracoid"/> + <attack type="4" damage="1d6"/> + <attack type="4" damage="1d6"/> + <attack type="1" damage="1d5"/> + </race> + <race name="catdragon" magres="0.900000" maxaura="1.000000" regaura="1.000000" recruitcost="500000" weight="20000" capacity="10000" speed="1.000000" hp="20" damage="2d40" unarmedattack="0" unarmeddefense="0" defensemodifier="50" fly="yes" walk="yes" teach="no" shapeshift="yes" giveitem="yes" giveperson="yes" getitem="yes"> + <ai splitsize="1"/> + <attack type="4" damage="2d40"/> + <attack type="4" damage="2d40"/> + <attack type="4" damage="2d40"/> + <attack type="4" damage="2d40"/> + </race> + <race name="ent" magres="0.250000" maxaura="1.000000" regaura="0.500000" recruitcost="5000" weight="5000" capacity="2500" speed="1.000000" hp="50" ac="4" damage="2d4+12" unarmedattack="0" unarmeddefense="0" attackmodifier="9" defensemodifier="7" scarepeasants="yes" walk="yes" teach="no"> + <ai splitsize="1000" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="2d12"/> + <attack type="4" damage="2d12"/> + </race> + <race name="wyrm" magres="0.900000" maxaura="1.000000" regaura="3.000000" recruitcost="250000" weight="18000" capacity="1000000" speed="1.000000" hp="2700" ac="8" damage="2d60" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes"> + <ai splitsize="1" killpeasants="yes" learn="yes"/> + <function name="name" value="namedragon"/> + <function name="move" value="movedragon"/> + <skill name="magic" modifier="12"/> + <skill name="tactics" modifier="12"/> + <skill name="perception" modifier="10"/> + <attack type="4" damage="3d20"/> + <attack type="4" damage="3d20"/> + <attack type="4" damage="5d30"/> + <attack type="6" spell="powerful_dragonbreath"/> + </race> + <race name="dragon" magres="0.700000" maxaura="1.000000" regaura="2.000000" recruitcost="50000" weight="10000" capacity="1000000" speed="1.500000" hp="900" ac="6" damage="2d30" unarmedattack="0" unarmeddefense="0" attackmodifier="7" defensemodifier="7" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" giveitem="yes" resistbash="yes"> + <ai splitsize="2" killpeasants="yes" learn="yes"/> + <function name="name" value="namedragon"/> + <function name="age" value="agedragon"/> + <function name="move" value="movedragon"/> + <skill name="magic" modifier="8"/> + <skill name="tactics" modifier="8"/> + <skill name="perception" modifier="5"/> + <attack type="4" damage="2d20"/> + <attack type="4" damage="2d20"/> + <attack type="4" damage="3d30"/> + <attack type="6" spell="icy_dragonbreath"/> + </race> + <race name="youngdragon" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="10000" weight="20000" capacity="10000" speed="1.000000" hp="300" ac="4" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes"> + <ai splitsize="6" killpeasants="yes" learn="yes"/> + <function name="name" value="namedragon"/> + <function name="age" value="agefiredragon"/> + <function name="move" value="movedragon"/> + <skill name="magic" modifier="4"/> + <skill name="tactics" modifier="4"/> + <skill name="stealth" modifier="2"/> + <skill name="perception" modifier="2"/> + <attack type="4" damage="1d30"/> + <attack type="4" damage="1d30"/> + <attack type="4" damage="1d30"/> + <attack type="6" spell="fiery_dragonbreath"/> + </race> + <race name="illusion" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="50" weight="0" capacity="0" speed="1.000000" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" walk="yes" canlearn="no" teach="no" noweapons="yes" illusionary="yes"> + <ai splitsize="999999"/> + <function name="age" value="ageillusion"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d1"/> + </race> + <race name="undead" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="2" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d7" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes"> + <ai splitsize="20000" moverandom="yes"/> + <function name="name" value="nameundead"/> + <function name="age" value="ageundead"/> + <attack type="4" damage="1d7"/> + <attack type="5"/> + </race> + <race name="aquarian" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" shipspeed="yes" playerrace="yes" coastal="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="mining" modifier="-2"/> + <skill name="building" modifier="-1"/> + <skill name="trade" modifier="2"/> + <skill name="armorer" modifier="-1"/> + <skill name="shipcraft" modifier="3"/> + <skill name="sailing" modifier="3"/> + <skill name="roadwork" modifier="-1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="giantturtle" default="yes"/> + <familiar race="dolphin"/> + <familiar race="giantturtle"/> + <familiar race="dolphin"/> + <familiar race="dolphin"/> + <familiar race="kraken"/> + </race> + <race name="cat" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="90" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" defensemodifier="1" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="alchemy" modifier="-1"/> + <skill name="mining" modifier="-2"/> + <skill name="building" modifier="-1"/> + <skill name="catapult" modifier="-1"/> + <skill name="herbalism" modifier="1"/> + <skill name="armorer" modifier="-1"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="sailing" modifier="-2"/> + <skill name="espionage" modifier="2"/> + <skill name="quarrying" modifier="-1"/> + <skill name="roadwork" modifier="-1"/> + <skill name="stealth" modifier="1"/> + <skill name="perception" modifier="2"/> + <skill name="taxation" modifier="1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="lynx" default="yes"/> + <familiar race="dreamcat"/> + <familiar race="lynx"/> + <familiar race="songdragon"/> + <familiar race="tiger"/> + <familiar race="hellcat"/> + </race> + <race name="halfling" magres="0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="18" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <param name="hunger.damage" value="1d14+14"/> + <skill name="crossbow" modifier="1"/> + <skill name="mining" modifier="1"/> + <skill name="bow" modifier="-1"/> + <skill name="building" modifier="1"/> + <skill name="trade" modifier="2"/> + <skill name="catapult" modifier="-1"/> + <skill name="herbalism" modifier="2"/> + <skill name="training" modifier="-1"/> + <skill name="riding" modifier="-1"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="melee" modifier="-1"/> + <skill name="sailing" modifier="-2"/> + <skill name="polearm" modifier="-1"/> + <skill name="espionage" modifier="1"/> + <skill name="roadwork" modifier="1"/> + <skill name="stealth" modifier="1"/> + <skill name="entertainment" modifier="1"/> + <skill name="cartmaking" modifier="2"/> + <skill name="perception" modifier="1"/> + <skill name="taxation" modifier="-1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="owl" default="yes"/> + <familiar race="rat"/> + <familiar race="eagle"/> + <familiar race="songdragon"/> + <familiar race="eagle"/> + <familiar race="rat"/> + </race> + <race name="insect" magres="0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="80" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" ac="2" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="crossbow" modifier="1"/> + <skill name="mining" modifier="1"/> + <skill name="bow" modifier="-2"/> + <skill name="building" modifier="2"/> + <skill name="trade" modifier="-1"/> + <skill name="forestry" modifier="1"/> + <skill name="herbalism" modifier="1"/> + <skill name="training" modifier="-3"/> + <skill name="riding" modifier="-3"/> + <skill name="armorer" modifier="2"/> + <skill name="melee" modifier="-1"/> + <skill name="polearm" modifier="1"/> + <skill name="roadwork" modifier="-1"/> + <skill name="tactics" modifier="-1"/> + <skill name="stealth" modifier="-1"/> + <skill name="entertainment" modifier="-2"/> + <skill name="perception" modifier="1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="ghost" default="yes"/> + <familiar race="rat"/> + <familiar race="owl"/> + <familiar race="rat"/> + <familiar race="tunnelworm"/> + <familiar race="imp"/> + </race> + <race name="demon" magres="0.150000" maxaura="1.000000" regaura="1.250000" recruitcost="150" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="50" ac="2" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" shapeshift="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="initfamiliar" value="oldfamiliars"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="alchemy" modifier="2"/> + <skill name="trade" modifier="-3"/> + <skill name="forestry" modifier="1"/> + <skill name="herbalism" modifier="-3"/> + <skill name="magic" modifier="1"/> + <skill name="training" modifier="-3"/> + <skill name="riding" modifier="-1"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="melee" modifier="1"/> + <skill name="sailing" modifier="-1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="-1"/> + <skill name="stealth" modifier="1"/> + <skill name="entertainment" modifier="-3"/> + <skill name="weaponsmithing" modifier="1"/> + <skill name="cartmaking" modifier="-2"/> + <skill name="perception" modifier="1"/> + <skill name="taxation" modifier="1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <attack type="5"/> + <familiar race="imp" default="yes"/> + <familiar race="imp"/> + <familiar race="ghost"/> + <familiar race="rat"/> + <familiar race="wolf"/> + <familiar race="imp"/> + </race> + <race name="troll" magres="0.100000" maxaura="1.000000" regaura="1.000000" recruitcost="90" maintenance="10" weight="2000" capacity="1080" speed="1.000000" hp="30" ac="1" damage="1d5+3" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="mining" modifier="2"/> + <skill name="bow" modifier="-2"/> + <skill name="building" modifier="2"/> + <skill name="catapult" modifier="2"/> + <skill name="herbalism" modifier="-1"/> + <skill name="training" modifier="-1"/> + <skill name="riding" modifier="-2"/> + <skill name="armorer" modifier="2"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="melee" modifier="1"/> + <skill name="sailing" modifier="-1"/> + <skill name="espionage" modifier="-3"/> + <skill name="quarrying" modifier="2"/> + <skill name="roadwork" modifier="2"/> + <skill name="tactics" modifier="-1"/> + <skill name="stealth" modifier="-3"/> + <skill name="entertainment" modifier="-1"/> + <skill name="perception" modifier="-1"/> + <skill name="taxation" modifier="1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5+3"/> + <familiar race="tunnelworm" default="yes"/> + <familiar race="rat"/> + <familiar race="rat"/> + <familiar race="eagle"/> + <familiar race="tunnelworm"/> + <familiar race="wolf"/> + </race> + <race name="goblin" magres="-0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="40" maintenance="10" weight="600" capacity="440" speed="1.000000" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="initfamiliar" value="oldfamiliars"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="alchemy" modifier="1"/> + <skill name="mining" modifier="1"/> + <skill name="building" modifier="1"/> + <skill name="trade" modifier="-1"/> + <skill name="catapult" modifier="1"/> + <skill name="magic" modifier="-1"/> + <skill name="shipcraft" modifier="-2"/> + <skill name="sailing" modifier="-2"/> + <skill name="roadwork" modifier="-2"/> + <skill name="tactics" modifier="-2"/> + <skill name="stealth" modifier="1"/> + <skill name="entertainment" modifier="-1"/> + <skill name="cartmaking" modifier="-1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="rat" default="yes"/> + <familiar race="songdragon"/> + <familiar race="imp"/> + <familiar race="rat"/> + <familiar race="rat"/> + <familiar race="imp"/> + </race> + <race name="clone" magres="0.900000" maxaura="0.000000" regaura="0.000000" recruitcost="0" weight="1000" capacity="540" speed="1.000000" hp="40" damage="0d0" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" canlearn="no" teach="no" noheal="yes"> + <ai splitsize="10000"/> + <skill name="alchemy" modifier="-99"/> + <skill name="crossbow" modifier="-99"/> + <skill name="mining" modifier="-99"/> + <skill name="bow" modifier="-99"/> + <skill name="building" modifier="-99"/> + <skill name="trade" modifier="-99"/> + <skill name="forestry" modifier="-99"/> + <skill name="catapult" modifier="-99"/> + <skill name="herbalism" modifier="-99"/> + <skill name="magic" modifier="-99"/> + <skill name="training" modifier="-99"/> + <skill name="riding" modifier="-99"/> + <skill name="armorer" modifier="-99"/> + <skill name="shipcraft" modifier="-99"/> + <skill name="melee" modifier="-99"/> + <skill name="sailing" modifier="-99"/> + <skill name="polearm" modifier="-99"/> + <skill name="espionage" modifier="-99"/> + <skill name="quarrying" modifier="-99"/> + <skill name="roadwork" modifier="-99"/> + <skill name="tactics" modifier="-99"/> + <skill name="stealth" modifier="-99"/> + <skill name="entertainment" modifier="-99"/> + <skill name="weaponsmithing" modifier="-99"/> + <skill name="cartmaking" modifier="-99"/> + <skill name="perception" modifier="-99"/> + <skill name="taxation" modifier="-99"/> + <skill name="stamina" modifier="-99"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="0d0"/> + </race> + <race name="template" magres="1.000000" maxaura="0.000000" regaura="0.000000" recruitcost="0" weight="0" capacity="1000" speed="10.000000" hp="10" damage="1d4" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" fly="yes" swim="yes" walk="yes" shapeshift="yes" shapeshiftany="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" recruitethereal="yes" recruitunlimited="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <attack type="1" damage="1d4"/> + </race> + <race name="gnome" magres="1.000000" maxaura="0.000000" regaura="0.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="50" damage="1d4" unarmedattack="10" unarmeddefense="10" attackmodifier="10" defensemodifier="10" walk="yes" teach="no"> + <ai splitsize="10000"/> + <skill name="tactics" modifier="1"/> + <skill name="perception" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="1" damage="1d4"/> + </race> + <race name="museumghost" magres="1.000000" maxaura="0.000000" regaura="0.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="50" damage="1d4" unarmedattack="10" unarmeddefense="10" attackmodifier="10" defensemodifier="10" walk="yes" teach="no"> + <ai splitsize="10000"/> + <skill name="tactics" modifier="1"/> + <skill name="perception" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="2" damage="5d600"/> + <attack type="3" damage="5d5"/> + <attack type="2" damage="5d600"/> + <attack type="2" damage="5d600"/> + <attack type="3" damage="5d5"/> + <attack type="2" damage="5d600"/> + <attack type="1" damage="1d4"/> + </race> + <race name="ghast" magres="0.600000" maxaura="1.000000" regaura="1.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="60" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes"> + <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> + <function name="name" value="nameghoul"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="4" damage="2d8"/> + <attack type="3" damage="1d5"/> + <attack type="3" damage="1d5"/> + <attack type="2" damage="1d30"/> + <attack type="2" damage="1d30"/> + </race> + <race name="ghoul" magres="0.300000" maxaura="1.000000" regaura="1.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="30" ac="1" damage="1d7" unarmedattack="3" unarmeddefense="3" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes"> + <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> + <function name="name" value="nameghoul"/> + <function name="age" value="ageghoul"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="4" damage="2d6"/> + <attack type="3" damage="1d2"/> + <attack type="3" damage="1d2"/> + <attack type="2" damage="1d30"/> + </race> + <race name="juju-zombie" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="8" weight="1000" capacity="540" speed="1.000000" hp="80" ac="2" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistbash="yes" resistcut="yes" resistpierce="yes"> + <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> + <function name="name" value="namezombie"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="1" damage="1d7"/> + <attack type="3" damage="1d1"/> + <attack type="3" damage="1d1"/> + </race> + <race name="zombie" magres="0.200000" maxaura="1.000000" regaura="1.000000" recruitcost="4" weight="1000" capacity="540" speed="1.000000" hp="40" ac="1" damage="1d7" unarmedattack="2" unarmeddefense="2" attackmodifier="5" defensemodifier="5" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> + <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> + <function name="name" value="namezombie"/> + <function name="age" value="agezombie"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="1" damage="1d7"/> + </race> + <race name="skeletonlord" magres="0.300000" maxaura="1.000000" regaura="1.000000" recruitcost="2" weight="1000" capacity="540" speed="1.000000" hp="60" ac="4" damage="1d7" unarmedattack="6" unarmeddefense="6" attackmodifier="8" defensemodifier="8" scarepeasants="yes" walk="yes" canlearn="no" teach="no" absorbpeasants="yes" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> + <ai splitsize="2000" aggression="0.02" killpeasants="yes" moverandom="yes"/> + <function name="name" value="nameskeleton"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="1" damage="1d7"/> + <attack type="1" damage="1d7"/> + </race> + <race name="skeleton" magres="0.100000" maxaura="1.000000" regaura="1.000000" recruitcost="0" weight="500" capacity="540" speed="1.000000" hp="20" ac="1" damage="1d7" unarmedattack="1" unarmeddefense="1" attackmodifier="6" defensemodifier="6" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noheal="yes" undead="yes" equipment="yes" resistcut="yes" resistpierce="yes"> + <ai splitsize="10000" killpeasants="yes" moverandom="yes"/> + <function name="name" value="nameskeleton"/> + <function name="age" value="ageskeleton"/> + <skill name="crossbow" modifier="1"/> + <skill name="bow" modifier="1"/> + <skill name="catapult" modifier="1"/> + <skill name="riding" modifier="1"/> + <skill name="melee" modifier="1"/> + <skill name="polearm" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="stamina" modifier="1"/> + <skill name="unarmed" modifier="1"/> + <attack type="1" damage="1d7"/> + </race> + <race name="centaur" magres="0.000000" maxaura="0.750000" regaura="0.750000" recruitcost="100" maintenance="10" weight="5000" capacity="2040" speed="1.000000" hp="30" damage="2d5" unarmedattack="0" unarmeddefense="0" playerrace="yes" walk="yes" horse="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" recruithorses="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <skill name="crossbow" modifier="1"/> + <skill name="mining" modifier="-3"/> + <skill name="bow" modifier="1"/> + <skill name="building" modifier="-2"/> + <skill name="trade" modifier="1"/> + <skill name="catapult" modifier="-2"/> + <skill name="herbalism" modifier="1"/> + <skill name="training" modifier="4"/> + <skill name="armorer" modifier="-1"/> + <skill name="shipcraft" modifier="-4"/> + <skill name="sailing" modifier="-4"/> + <skill name="polearm" modifier="1"/> + <skill name="espionage" modifier="-1"/> + <skill name="quarrying" modifier="-1"/> + <skill name="stealth" modifier="-1"/> + <skill name="weaponsmithing" modifier="1"/> + <skill name="cartmaking" modifier="1"/> + <skill name="taxation" modifier="1"/> + <attack type="1" damage="2d5"/> + <familiar race="eagle" default="yes"/> + <familiar race="fairy"/> + <familiar race="owl"/> + <familiar race="unicorn"/> + <familiar race="nymph"/> + <familiar race="imp"/> + </race> + <race name="shadowknight" magres="0.000000" maxaura="0.000000" regaura="0.000000" recruitcost="5" weight="1000" capacity="540" speed="1.000000" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noblock="yes"> + <ai splitsize="20000" moverandom="yes"/> + <function name="name" value="namegeneric"/> + <attack type="1" damage="1d1"/> + </race> + <race name="seaserpent" magres="0.500000" maxaura="1.000000" regaura="1.000000" recruitcost="5000" weight="20000" capacity="5000" speed="1.000000" hp="600" ac="3" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" scarepeasants="yes" swim="yes" teach="no" getitem="yes" resistbash="yes"> + <ai splitsize="6" killpeasants="yes" moverandom="yes" learn="yes"/> + <function name="name" value="namegeneric"/> + <function name="move" value="moveswimming"/> + <skill name="tactics" modifier="4"/> + <attack type="4" damage="1d30"/> + <attack type="4" damage="1d30"/> + <attack type="4" damage="1d30"/> + <attack type="6" spell="fiery_dragonbreath"/> + <attack type="8" damage="1d10"/> + </race> + <race name="snotling" magres="-0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="50" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="alchemy" modifier="1"/> + <skill name="mining" modifier="1"/> + <skill name="building" modifier="1"/> + <skill name="trade" modifier="-3"/> + <skill name="forestry" modifier="1"/> + <skill name="herbalism" modifier="-2"/> + <skill name="magic" modifier="-1"/> + <skill name="training" modifier="-1"/> + <skill name="armorer" modifier="1"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="sailing" modifier="-1"/> + <skill name="espionage" modifier="-1"/> + <skill name="quarrying" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="entertainment" modifier="-2"/> + <skill name="weaponsmithing" modifier="2"/> + <skill name="cartmaking" modifier="-1"/> + <skill name="taxation" modifier="1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="goblin" default="yes"/> + <familiar race="ghost"/> + <familiar race="imp"/> + <familiar race="rat"/> + <familiar race="wolf"/> + <familiar race="demon"/> + </race> + + <!-- race name="old_orc" magres="-0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="50" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="alchemy" modifier="1"/> + <skill name="mining" modifier="1"/> + <skill name="building" modifier="1"/> + <skill name="trade" modifier="-3"/> + <skill name="forestry" modifier="1"/> + <skill name="herbalism" modifier="-2"/> + <skill name="magic" modifier="-1"/> + <skill name="training" modifier="-1"/> + <skill name="armorer" modifier="1"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="sailing" modifier="-1"/> + <skill name="espionage" modifier="-1"/> + <skill name="quarrying" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="entertainment" modifier="-2"/> + <skill name="weaponsmithing" modifier="2"/> + <skill name="cartmaking" modifier="-1"/> + <skill name="taxation" modifier="1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="goblin" default="yes"/> + <familiar race="ghost"/> + <familiar race="imp"/> + <familiar race="rat"/> + <familiar race="wolf"/> + <familiar race="demon"/> + </race --> + <race name="elf" magres="0.100000" maxaura="1.000000" regaura="1.250000" recruitcost="130" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="18" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="alchemy" modifier="-1"/> + <skill name="mining" modifier="-2"/> + <skill name="bow" modifier="2"/> + <skill name="building" modifier="-1"/> + <skill name="catapult" modifier="-2"/> + <skill name="herbalism" modifier="2"/> + <skill name="magic" modifier="1"/> + <skill name="training" modifier="1"/> + <skill name="armorer" modifier="-1"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="sailing" modifier="-1"/> + <skill name="quarrying" modifier="-1"/> + <skill name="roadwork" modifier="-1"/> + <skill name="stealth" modifier="1"/> + <skill name="perception" modifier="1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="lynx" default="yes"/> + <familiar race="fairy"/> + <familiar race="owl"/> + <familiar race="nymph"/> + <familiar race="unicorn"/> + <familiar race="imp"/> + </race> + <race name="dwarf" magres="0.050000" maxaura="1.000000" regaura="0.500000" recruitcost="110" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <skill name="mining" modifier="2"/> + <skill name="bow" modifier="-1"/> + <skill name="building" modifier="2"/> + <skill name="trade" modifier="1"/> + <skill name="forestry" modifier="-1"/> + <skill name="catapult" modifier="2"/> + <skill name="herbalism" modifier="-2"/> + <skill name="magic" modifier="-2"/> + <skill name="training" modifier="-2"/> + <skill name="riding" modifier="-2"/> + <skill name="armorer" modifier="2"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="melee" modifier="1"/> + <skill name="sailing" modifier="-2"/> + <skill name="quarrying" modifier="2"/> + <skill name="roadwork" modifier="2"/> + <skill name="stealth" modifier="-1"/> + <skill name="entertainment" modifier="-1"/> + <skill name="weaponsmithing" modifier="2"/> + <skill name="taxation" modifier="1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="tunnelworm" default="yes"/> + <familiar race="eagle"/> + <familiar race="owl"/> + <familiar race="lynx"/> + <familiar race="wolf"/> + <familiar race="rat"/> + </race> + <race name="orc" magres="-0.050000" maxaura="1.000000" regaura="1.000000" recruitcost="70" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="24" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <param name="recruit_multi" value="0.5"/> + <skill name="alchemy" modifier="1"/> + <skill name="mining" modifier="1"/> + <skill name="building" modifier="1"/> + <skill name="trade" modifier="-3"/> + <skill name="forestry" modifier="1"/> + <skill name="herbalism" modifier="-2"/> + <skill name="magic" modifier="-1"/> + <skill name="training" modifier="-1"/> + <skill name="armorer" modifier="1"/> + <skill name="shipcraft" modifier="-1"/> + <skill name="sailing" modifier="-1"/> + <skill name="espionage" modifier="-1"/> + <skill name="quarrying" modifier="1"/> + <skill name="tactics" modifier="1"/> + <skill name="entertainment" modifier="-2"/> + <skill name="weaponsmithing" modifier="2"/> + <skill name="cartmaking" modifier="-1"/> + <skill name="taxation" modifier="1"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="goblin" default="yes"/> + <familiar race="ghost"/> + <familiar race="imp"/> + <familiar race="rat"/> + <familiar race="wolf"/> + <familiar race="demon"/> + </race> + <race name="shadowdragon" magres="0.950000" maxaura="1.000000" regaura="3.000000" recruitcost="2500000" weight="100" capacity="100000" speed="1.000000" hp="2700" ac="10" damage="2d60" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="12" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes"> + <ai splitsize="1" killpeasants="yes" learn="yes"/> + <function name="name" value="namedragon"/> + <function name="move" value="movedragon"/> + <skill name="tactics" modifier="20"/> + <skill name="perception" modifier="20"/> + <attack type="4" damage="5d30"/> + <attack type="4" damage="3d20"/> + <attack type="4" damage="3d20"/> + <attack type="4" damage="5d30"/> + <attack type="6" spell="drain_skills"/> + <attack type="6" spell="aura_of_fear"/> + <precombatspell spell="shadowcall"/> + </race> + <race name="shadowbat" magres="0.800000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="500" capacity="540" speed="1.000000" hp="1" ac="4" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes"> + <ai splitsize="5000" killpeasants="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="1d6"/> + <attack type="3" damage="1d1"/> + </race> + <race name="nightmare" magres="0.500000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="100" capacity="540" speed="1.000000" hp="80" ac="10" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" invinciblenonmagic="yes"> + <ai splitsize="500" killpeasants="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="1d4"/> + <attack type="4" damage="1d4"/> + <attack type="4" damage="1d4"/> + <attack type="3" damage="1d4"/> + <attack type="2" damage="1d10"/> + </race> + <race name="vampunicorn" magres="1.000000" maxaura="0.000000" regaura="0.000000" recruitcost="500" weight="5000" capacity="2000" speed="1.000000" hp="30" ac="4" damage="2d4" unarmedattack="0" unarmeddefense="0" attackmodifier="3" defensemodifier="3" scarepeasants="yes" walk="yes" teach="no" getitem="yes"> + <ai splitsize="5000" killpeasants="yes"/> + <function name="name" value="namegeneric"/> + <attack type="4" damage="2d10"/> + <attack type="3" damage="1d4"/> + <attack type="3" damage="1d4"/> + <attack type="3" damage="1d4"/> + <attack type="3" damage="1d4"/> + <attack type="2" damage="2d60"/> + </race> +</races> diff --git a/res/eressea/spellinfo.xml b/res/eressea/spellinfo.xml index ce2e82635..85e3fb352 100644 --- a/res/eressea/spellinfo.xml +++ b/res/eressea/spellinfo.xml @@ -1,113 +1,113 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<strings> - <namespace name="spellinfo"> - <string name="raindance"> - <text locale="de">Dieses uralte Tanzritual ruft die - Kr�fte des Lebens und der Fruchtbarkeit. Die Ertr�ge der - Bauern werden f�r einige Wochen deutlich besser - ausfallen.</text> - <text locale="en">This ancient rite calls upon the - forces of life and fertility. For the next few weeks, - the peasant's harvest will be extraordinary good.</text> - </string> - <string name="blessedharvest"> - <text locale="de">Dieses Ernteritual verbessert die Ertr�ge der - arbeitenden Bauern in der Region um ein Silberst�ck. Je mehr Kraft der - Druide investiert, desto l�nger wirkt der Zauber.</text> - <text locale="en">This ritual increases the output of the local farms. - Peasants in the region produce an extra silverpiece. The stronger the - druid's spell is, the longer the effect will last.</text> - </string> - <string name="earn_silver#tybied"> - <text locale="de">Wenn einem der Alchemist nicht weiterhelfen kann, geht man zu dem - gelehrten Tybiedmagier. Seine Tr�nke und Tinkturen helfen gegen - alles, was man sonst nicht bekommen kann. Ob nun die kryptische - Formel unter dem Holzschuh des untreuen Ehemannes wirklich geholfen - hat - nun, der des Lesens nicht m�chtige Bauer wird es nie wissen. - Dem Magier hilft es auf jeden Fall... beim F�llen seines - Geldbeutels. 50 Silber pro Stufe lassen sich so in einer Woche - verdienen.</text> - <text locale="en">If the local alchemist could not help you, you should visit a - scholar of Tybied. His potions and tinctures may help when nothing - else does. If the cryptic formula under the wooden shoes of the - unfaithful husband really helped? - well, the peasant, who isn't - capable of reading, will never know. At least it helped the magician... - to fill his purse. In one week he can earn 50 silver per level that - way.</text> - </string> - <string name="earn_silver#cerddor"> - <text locale="de">Cerddormagier sind _die_ Gaukler unter - den Magiern, sie lieben es das Volk zu unterhalten und - im Mittelpunkt zu stehen. Schon Anf�nger lernen die - kleinen Kunstst�cke und magischen Tricks, mit denen man - das Volk locken und verf�hren kann, den Geldbeutel ganz - weit zu �ffnen, und am Ende der Woche wird der Gaukler - 50 Silber pro Stufe verdient haben.</text> - <text locale="en">The mages of Cerddor truly are the - bards of the wizards; they love to use their sorcery to - entertain the crowds and to be the center of attention. - Even the apprentices study those little magic tricks, - which attract and fascinate the people and thus ensnare - them into leaving a few coins or more for the artist. By - the end of the week, the bard will have earned 50 silver - per level. </text> - </string> - <string name="earn_silver#gwyrrd"> - <text locale="de">Die F�higkeiten der Gwyrrd-Magier in - der Viehzucht und Heilung sind bei den Bauern sehr - begehrt. Gerade auf M�rkten sind ihre Dienste h�ufig sehr - gefragt. Manch einer mag auch sein Talent dazu nutzen, - ein Tier f�r einen besseren Preis zu verkaufen. Pro - Stufe kann der Magier so 50 Silber verdienen.</text> - <text locale="en">The abilities of the mages of Gwyrrd - concerning the breeding and healing of cattle are highly - appreciated among the peasants. Especially at the - markets, their services are demanded frequently. Some of - them also use their talents to sell an animal at a - higher price. A magician can earn 50 silver pieces per level - in this way.</text> - </string> - <string name="earn_silver#draig"> - <text locale="de">In den dunkleren Gassen gibt es sie, - die Fl�che und Verhexungen auf Bestellung. Aber - auch Gegenzauber hat der J�nger des Draigs - nat�rlich im Angebot. Ob nun der Sohn des - Nachbarn in einen Liebesbann gezogen werden soll - oder die Nebenbuhlerin Pickel und Warzen - bekommen soll, niemand gibt gerne zu, zu solchen - Mitteln gegriffen zu haben. F�r diese - Dienstleistung streicht der Magier 50 Silber pro - Stufe ein.</text> - <text locale="en">In the dark alleys you can find those - who sell curses and hexes on demand - but you - can buy the apropriate counterspells from the - followers of Draig as well. May it be a love - spell for the son of a neighbour or a wart in - the face of a rival. For offering these - services, the sorcerer charges 50 silver pieces - per level.</text> - </string> - <string name="earn_silver#illaun"> - <text locale="fr">Personne n'interpr�te aussi bien les - r�ves que les mages d'Illaun. Ils sont �galement - vers�s dans l'utilisation des objets utilis�s - pour pr�dire le futur comme les boules de - cristal, les cartes de tarot ou les lignes de la - main. Un mentaliste peut gagner 50 �cus par - niveau et par semaine en proposant ses services - aux paysans.</text> - <text locale="de">Niemand kann so gut die Tr�ume deuten - wie ein Magier des Illaun. Auch die Kunst der - Wahrsagerei, des Kartenlegens und des Handlesens - sind ihm gel�ufig. Daf�r zahlen ihm die Bauern - 50 Silber pro Stufe.</text> - <text locale="en">No one can read dreams as well as the - mages of Illaun. Furthermore, they are also - familiar with all other common means of - foretelling the future like crystal balls, tarot - cards or palms. A mentalist can earn 50 silver - pieces per level and week for offering these - services to peasants.</text> - </string> - </namespace> -</strings> +<?xml version="1.0" encoding="iso-8859-1" ?> +<strings> + <namespace name="spellinfo"> + <string name="raindance"> + <text locale="de">Dieses uralte Tanzritual ruft die + Kr�fte des Lebens und der Fruchtbarkeit. Die Ertr�ge der + Bauern werden f�r einige Wochen deutlich besser + ausfallen.</text> + <text locale="en">This ancient rite calls upon the + forces of life and fertility. For the next few weeks, + the peasant's harvest will be extraordinary good.</text> + </string> + <string name="blessedharvest"> + <text locale="de">Dieses Ernteritual verbessert die Ertr�ge der + arbeitenden Bauern in der Region um ein Silberst�ck. Je mehr Kraft der + Druide investiert, desto l�nger wirkt der Zauber.</text> + <text locale="en">This ritual increases the output of the local farms. + Peasants in the region produce an extra silverpiece. The stronger the + druid's spell is, the longer the effect will last.</text> + </string> + <string name="earn_silver#tybied"> + <text locale="de">Wenn einem der Alchemist nicht weiterhelfen kann, geht man zu dem + gelehrten Tybiedmagier. Seine Tr�nke und Tinkturen helfen gegen + alles, was man sonst nicht bekommen kann. Ob nun die kryptische + Formel unter dem Holzschuh des untreuen Ehemannes wirklich geholfen + hat - nun, der des Lesens nicht m�chtige Bauer wird es nie wissen. + Dem Magier hilft es auf jeden Fall... beim F�llen seines + Geldbeutels. 50 Silber pro Stufe lassen sich so in einer Woche + verdienen.</text> + <text locale="en">If the local alchemist could not help you, you should visit a + scholar of Tybied. His potions and tinctures may help when nothing + else does. If the cryptic formula under the wooden shoes of the + unfaithful husband really helped? - well, the peasant, who isn't + capable of reading, will never know. At least it helped the magician... + to fill his purse. In one week he can earn 50 silver per level that + way.</text> + </string> + <string name="earn_silver#cerddor"> + <text locale="de">Cerddormagier sind _die_ Gaukler unter + den Magiern, sie lieben es das Volk zu unterhalten und + im Mittelpunkt zu stehen. Schon Anf�nger lernen die + kleinen Kunstst�cke und magischen Tricks, mit denen man + das Volk locken und verf�hren kann, den Geldbeutel ganz + weit zu �ffnen, und am Ende der Woche wird der Gaukler + 50 Silber pro Stufe verdient haben.</text> + <text locale="en">The mages of Cerddor truly are the + bards of the wizards; they love to use their sorcery to + entertain the crowds and to be the center of attention. + Even the apprentices study those little magic tricks, + which attract and fascinate the people and thus ensnare + them into leaving a few coins or more for the artist. By + the end of the week, the bard will have earned 50 silver + per level. </text> + </string> + <string name="earn_silver#gwyrrd"> + <text locale="de">Die F�higkeiten der Gwyrrd-Magier in + der Viehzucht und Heilung sind bei den Bauern sehr + begehrt. Gerade auf M�rkten sind ihre Dienste h�ufig sehr + gefragt. Manch einer mag auch sein Talent dazu nutzen, + ein Tier f�r einen besseren Preis zu verkaufen. Pro + Stufe kann der Magier so 50 Silber verdienen.</text> + <text locale="en">The abilities of the mages of Gwyrrd + concerning the breeding and healing of cattle are highly + appreciated among the peasants. Especially at the + markets, their services are demanded frequently. Some of + them also use their talents to sell an animal at a + higher price. A magician can earn 50 silver pieces per level + in this way.</text> + </string> + <string name="earn_silver#draig"> + <text locale="de">In den dunkleren Gassen gibt es sie, + die Fl�che und Verhexungen auf Bestellung. Aber + auch Gegenzauber hat der J�nger des Draigs + nat�rlich im Angebot. Ob nun der Sohn des + Nachbarn in einen Liebesbann gezogen werden soll + oder die Nebenbuhlerin Pickel und Warzen + bekommen soll, niemand gibt gerne zu, zu solchen + Mitteln gegriffen zu haben. F�r diese + Dienstleistung streicht der Magier 50 Silber pro + Stufe ein.</text> + <text locale="en">In the dark alleys you can find those + who sell curses and hexes on demand - but you + can buy the apropriate counterspells from the + followers of Draig as well. May it be a love + spell for the son of a neighbour or a wart in + the face of a rival. For offering these + services, the sorcerer charges 50 silver pieces + per level.</text> + </string> + <string name="earn_silver#illaun"> + <text locale="fr">Personne n'interpr�te aussi bien les + r�ves que les mages d'Illaun. Ils sont �galement + vers�s dans l'utilisation des objets utilis�s + pour pr�dire le futur comme les boules de + cristal, les cartes de tarot ou les lignes de la + main. Un mentaliste peut gagner 50 �cus par + niveau et par semaine en proposant ses services + aux paysans.</text> + <text locale="de">Niemand kann so gut die Tr�ume deuten + wie ein Magier des Illaun. Auch die Kunst der + Wahrsagerei, des Kartenlegens und des Handlesens + sind ihm gel�ufig. Daf�r zahlen ihm die Bauern + 50 Silber pro Stufe.</text> + <text locale="en">No one can read dreams as well as the + mages of Illaun. Furthermore, they are also + familiar with all other common means of + foretelling the future like crystal balls, tarot + cards or palms. A mentalist can earn 50 silver + pieces per level and week for offering these + services to peasants.</text> + </string> + </namespace> +</strings> diff --git a/res/eressea/spells.xml b/res/eressea/spells.xml index 08f43a0ac..36940ccd0 100644 --- a/res/eressea/spells.xml +++ b/res/eressea/spells.xml @@ -1,704 +1,704 @@ -<?xml version="1.0"?> -<spells> - <spell name="fireball" type="draig" rank="5" level="2" index="4" variable="true" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="hail" type="gwyrrd" rank="5" level="3" index="5" variable="true" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="rustweapon" type="gwyrrd" rank="5" level="3" index="6" parameters="u+" los="true" far="true" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="combatrust" type="draig" rank="5" level="6" index="7" variable="true" combat="2"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="treegrow" type="gwyrrd" rank="5" level="2" index="8" far="true" variable="true"> - <resource name="aura" amount="4" cost="level"/> - <resource name="log" amount="1" cost="level"/> - <resource name="p2" amount="1" cost="fixed"/> - </spell> - <spell name="healing" type="gwyrrd" rank="5" level="5" index="9" variable="true" combat="3"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="song_of_healing" type="cerddor" rank="5" level="2" index="10" variable="true" combat="3"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="bad_dreams" type="illaun" rank="5" level="10" index="11" far="true"> - <resource name="aura" amount="90" cost="fixed"/> - </spell> - <spell name="gooddreams" type="illaun" rank="5" level="8" index="12" far="true"> - <resource name="aura" amount="80" cost="fixed"/> - </spell> - <spell name="dreamreading" type="illaun" rank="5" level="4" index="13" parameters="u" far="true"> - <resource name="aura" amount="8" cost="fixed"/> - </spell> - <spell name="tiredsoldiers" type="illaun" rank="5" level="4" index="15" variable="true" combat="1"> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="plague" type="draig" rank="5" level="7" index="16" far="true"> - <resource name="aura" amount="30" cost="fixed"/> - <resource name="peasant" amount="50" cost="fixed"/> - </spell> - <spell name="magicboost" type="draig" rank="3" level="3" index="17" ship="true"> - <resource name="aura" amount="2" cost="linear"/> - </spell> - <spell name="chaosrow" type="draig" rank="5" level="8" index="18" variable="true" combat="1"> - <resource name="aura" amount="3" cost="level"/> - <resource name="peasant" amount="10" cost="fixed"/> - </spell> - <spell name="song_of_confusion" type="cerddor" rank="5" level="4" index="19" variable="true" combat="1"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="flee" type="illaun" rank="5" level="2" index="20" variable="true" combat="1"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="song_of_fear" type="cerddor" rank="5" level="3" index="21" variable="true" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="berserk" type="draig" rank="4" level="5" index="22" variable="true" combat="1"> - <resource name="aura" amount="5" cost="level"/> - <resource name="peasant" amount="1" cost="fixed"/> - </spell> - <spell name="bloodthirst" type="cerddor" rank="4" level="7" index="23" variable="true" combat="1"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="maelstrom" type="gwyrrd" rank="5" level="15" index="24" ship="true" ocean="true"> - <resource name="aura" amount="200" cost="fixed"/> - <resource name="seaserpenthead" amount="1" cost="fixed"/> - </spell> - <spell name="transferauradruide" type="gwyrrd" rank="1" level="6" index="27" syntax="aura" parameters="ui" ship="true"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="transfer_aura_song" type="cerddor" rank="1" level="5" index="28" syntax="aura" parameters="ui" ship="true"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="transferaurachaos" type="draig" rank="1" level="7" index="29" syntax="aura" parameters="ui" ship="true"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="transferauratraum" type="illaun" rank="1" level="3" index="30" syntax="aura" parameters="ui" ship="true"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="auratransfer" type="tybied" rank="1" level="5" index="31" syntax="aura" parameters="ui" ship="true"> - <resource name="aura" amount="1" cost="fixed"/> - </spell> - <spell name="stonegolem" type="gwyrrd" rank="4" level="1" index="32" variable="true"> - <resource name="aura" amount="2" cost="level"/> - <resource name="stone" amount="1" cost="level"/> - <resource name="p2" amount="1" cost="fixed"/> - </spell> - <spell name="irongolem" type="gwyrrd" rank="4" level="2" index="33" variable="true"> - <resource name="aura" amount="2" cost="level"/> - <resource name="iron" amount="1" cost="level"/> - <resource name="p2" amount="1" cost="fixed"/> - </spell> - <spell name="summonshadow" type="draig" rank="5" level="8" index="34" variable="true"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="summonshadowlords" type="draig" rank="5" level="12" index="35" variable="true"> - <resource name="aura" amount="7" cost="level"/> - </spell> - <spell name="reelingarrows" type="gwyrrd" rank="5" level="5" index="36" variable="true" combat="1"> - <resource name="aura" amount="15" cost="fixed"/> - </spell> - <spell name="antimagiczone" type="tybied" rank="2" level="5" index="37" far="true" variable="true"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="cold_protection" type="gwyrrd" rank="5" level="3" index="39" parameters="u+" los="true" ship="true" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="steal_aura" type="tybied" rank="3" level="6" index="40" parameters="u" los="true" far="true" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="summonundead" type="draig" rank="5" level="6" index="41" ship="true" far="true" variable="true"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="auraleak" type="draig" rank="3" level="9" index="42"> - <resource name="aura" amount="35" cost="fixed"/> - <resource name="dragonblood" amount="1" cost="fixed"/> - </spell> - <spell name="great_drought" type="gwyrrd" rank="5" level="17" index="43" far="true"> - <resource name="aura" amount="800" cost="fixed"/> - </spell> - <spell name="strongwall" type="gwyrrd" rank="5" level="8" index="44" variable="true" combat="1"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="homestone" type="gwyrrd" rank="5" level="7" index="45"> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - <spell name="summonfireelemental" type="gwyrrd" rank="5" level="13" index="46" far="true"> - <resource name="aura" amount="600" cost="fixed"/> - </spell> - <spell name="forestfire" type="draig" rank="5" level="10" index="47" far="true"> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="oil" amount="1" cost="fixed"/> - </spell> - <spell name="summonent" type="gwyrrd" rank="5" level="10" index="49" variable="true"> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="disturbingdreams" type="illaun" rank="5" level="6" index="50" far="true"> - <resource name="aura" amount="18" cost="fixed"/> - </spell> - <spell name="appeasement" type="cerddor" rank="5" level="1" index="51" variable="true" combat="1"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="sleep" type="illaun" rank="5" level="7" index="52" variable="true" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="earthquake" type="gwyrrd" rank="5" level="6" index="53" far="true"> - <resource name="aura" amount="25" cost="fixed"/> - <resource name="laen" amount="2" cost="fixed"/> - </spell> - <spell name="ironkeeper" type="gwyrrd" rank="5" level="3" index="54" far="true" variable="true"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="stormwinds" type="gwyrrd" rank="5" level="6" index="55" parameters="s+" ship="true" ocean="true" variable="true"> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="goodwinds" type="gwyrrd" rank="5" level="4" index="56" parameters="s" ship="true" variable="true"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="airship" type="tybied" rank="5" level="6" index="57" parameters="s" ship="true"> - <resource name="aura" amount="10" cost="fixed"/> - <resource name="h12" amount="1" cost="fixed"/> - <resource name="h20" amount="1" cost="fixed"/> - </spell> - <spell name="summon_alp" type="illaun" rank="5" level="15" index="58" parameters="u" target_global="true"> - <resource name="aura" amount="350" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - <resource name="h8" amount="1" cost="fixed"/> - </spell> - <spell name="windshield" type="gwyrrd" rank="5" level="4" index="59" variable="true" combat="1"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="raise_mob" type="cerddor" rank="5" level="10" index="60" variable="true"> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="melancholy" type="cerddor" rank="5" level="11" index="61" far="true"> - <resource name="aura" amount="40" cost="fixed"/> - </spell> - <spell name="headache" type="cerddor" rank="5" level="7" index="62" parameters="u" los="true"> - <resource name="aura" amount="4" cost="linear"/> - <resource name="h7" amount="3" cost="fixed"/> - <resource name="money" amount="50" cost="fixed"/> - </spell> - <spell name="enterastral" type="tybied" rank="7" level="4" index="64" parameters="u+" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="leaveastral" type="tybied" rank="7" level="4" index="65" parameters="ru+" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="versteinern" type="gwyrrd" rank="5" level="8" index="67" variable="true" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="treewalkenter" type="gwyrrd" rank="7" level="9" index="68" parameters="u+" los="true" variable="true"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="treewalkexit" type="gwyrrd" rank="7" level="9" index="69" parameters="ru+" los="true" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="chaossuction" type="draig" rank="5" level="14" index="70"> - <resource name="aura" amount="150" cost="fixed"/> - <resource name="peasant" amount="200" cost="fixed"/> - </spell> - <spell name="view_reality" type="tybied" rank="5" level="10" index="71"> - <resource name="aura" amount="40" cost="fixed"/> - </spell> - <spell name="astral_disruption" type="tybied" rank="4" level="14" index="72" variable="true"> - <resource name="aura" amount="140" cost="fixed"/> - </spell> - <spell name="seduction" type="cerddor" rank="5" level="6" index="73" parameters="u" los="true"> - <resource name="aura" amount="12" cost="fixed"/> - </spell> - <spell name="sound_out" type="cerddor" rank="5" level="7" index="74" parameters="ur" los="true"> - <resource name="aura" amount="4" cost="fixed"/> - <resource name="money" amount="100" cost="fixed"/> - </spell> - <spell name="calm_monster" type="cerddor" rank="5" level="6" index="75" parameters="u" los="true" ship="true"> - <resource name="aura" amount="15" cost="fixed"/> - </spell> - <spell name="heroic_song" type="cerddor" rank="4" level="5" index="76" variable="true" combat="1"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="frighten" type="cerddor" rank="5" level="8" index="77" variable="true" combat="1"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="mindblast" type="illaun" rank="5" level="11" index="78" variable="true" combat="1"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="combat_speed" type="tybied" rank="5" level="9" index="79" variable="true" combat="1"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="double_time" type="tybied" rank="5" level="11" index="80" parameters="u+" los="true" ship="true" variable="true"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="fiery_dragonbreath" type="gray" rank="5" level="3" index="81" combat="2"> - <resource name="aura" amount="1" cost="fixed"/> - </spell> - <spell name="icy_dragonbreath" type="gray" rank="5" level="6" index="82" combat="2"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="powerful_dragonbreath" type="gray" rank="5" level="12" index="83" combat="2"> - <resource name="aura" amount="3" cost="fixed"/> - </spell> - <spell name="magicstreet" type="gwyrrd" rank="5" level="4" index="84" ship="true" far="true" variable="true"> - <resource name="aura" amount="1" cost="level"/> - <resource name="stone" amount="1" cost="fixed"/> - <resource name="log" amount="1" cost="fixed"/> - </spell> - <spell name="reanimate" type="illaun" rank="4" level="5" index="85" variable="true" combat="3"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="courting" type="cerddor" rank="5" level="4" index="86" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="generous" type="cerddor" rank="5" level="2" index="87" ship="true" far="true" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="sacrifice_strength" type="tybied" rank="1" level="15" index="88" syntax="aura" parameters="ui"> - <resource name="aura" amount="100" cost="fixed"/> - </spell> - <spell name="song_of_peace" type="cerddor" rank="5" level="12" index="89" variable="true"> - <resource name="aura" amount="20" cost="level"/> - </spell> - <spell name="migration" type="cerddor" rank="5" level="9" index="90" parameters="u" los="true" variable="true"> - <resource name="aura" amount="3" cost="level"/> - <resource name="permaura" amount="1" cost="level"/> - </spell> - <spell name="calm_riot" type="cerddor" rank="5" level="15" index="91" far="true"> - <resource name="aura" amount="30" cost="fixed"/> - </spell> - <spell name="incite_riot" type="cerddor" rank="5" level="16" index="92" far="true"> - <resource name="aura" amount="40" cost="fixed"/> - </spell> - <spell name="shapeshift" type="illaun" rank="5" level="3" index="93" syntax="race" parameters="uc" variable="true"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="wolfhowl" type="gwyrrd" rank="5" level="7" index="94" variable="true" combat="1"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="resist_magic" type="tybied" rank="2" level="3" index="97" parameters="u+" los="true" ship="true" variable="true"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="keeploot" type="tybied" rank="5" level="3" index="98" variable="true" combat="3"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="protective_runes" type="tybied" rank="2" level="8" index="99" parameters="kc" ship="true"> - <resource name="aura" amount="20" cost="fixed"/> - </spell> - <spell name="song_resist_magic" type="cerddor" rank="2" level="10" index="100" far="true" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="song_suscept_magic" type="cerddor" rank="2" level="12" index="101" far="true" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="analyze_magic" type="tybied" rank="5" level="1" index="102" parameters="kc?" los="true" ship="true" variable="true"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="analysedream" type="illaun" rank="5" level="5" index="103" parameters="u" los="true" ship="true"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="analysesong_unit" type="cerddor" rank="5" level="5" index="104" parameters="u" los="true" ship="true"> - <resource name="aura" amount="10" cost="fixed"/> - </spell> - <spell name="analyse_object" type="cerddor" rank="5" level="8" index="105" parameters="kc?" ship="true" variable="true"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="destroy_magic" type="tybied" rank="2" level="5" index="106" parameters="kc?" los="true" ship="true" far="true" variable="true"> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="break_curse" type="tybied" rank="3" level="7" index="107" syntax="spellid" parameters="kcc?" los="true" ship="true" far="true" variable="true"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="meteor_rain" type="gray" rank="5" level="3" index="108" variable="true" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="fish_shield" type="tybied" rank="2" level="8" index="109" variable="true" combat="1"> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="armor_shield" type="tybied" rank="2" level="12" index="110" variable="true" combat="1"> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="deathcloud" type="draig" rank="5" level="11" index="111" far="true"> - <resource name="aura" amount="40" cost="fixed"/> - <resource name="hp" amount="15" cost="fixed"/> - </spell> - <spell name="orkdream" type="illaun" rank="5" level="12" index="112" parameters="u+" los="true" variable="true"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="summondragon" type="draig" rank="5" level="11" index="113" far="true"> - <resource name="aura" amount="80" cost="fixed"/> - <resource name="dragonhead" amount="1" cost="fixed"/> - </spell> - <spell name="living_rock" type="tybied" rank="5" level="13" index="116" syntax="direction" parameters="bc" variable="true"> - <resource name="aura" amount="10" cost="level"/> - <resource name="permaura" amount="1" cost="fixed"/> - <resource name="laen" amount="5" cost="fixed"/> - </spell> - <spell name="blessstonecircle" type="gwyrrd" rank="5" level="11" index="117" parameters="b"> - <resource name="aura" amount="350" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="illaunfamiliar" type="illaun" rank="5" level="9" index="118"> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="gwyrrdfamiliar" type="gwyrrd" rank="5" level="10" index="119"> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="draigfamiliar" type="draig" rank="5" level="13" index="120"> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="summon_familiar" type="cerddor" rank="5" level="9" index="121"> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="summon_familiar" type="tybied" rank="5" level="12" index="122"> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - <spell name="song_of_slavery" type="cerddor" rank="5" level="13" index="123" parameters="u" los="true"> - <resource name="aura" amount="40" cost="fixed"/> - </spell> - <spell name="fumblecurse" type="draig" rank="4" level="5" index="136" parameters="u" los="true" variable="true"> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="icastle" type="illaun" rank="5" level="3" index="137" syntax="buildingtype" parameters="c"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="gwyrrddestroymagic" type="gwyrrd" rank="2" level="8" index="138" parameters="kc?" los="true" ship="true" far="true" variable="true"> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="draigdestroymagic" type="draig" rank="2" level="10" index="139" parameters="kc?" los="true" ship="true" far="true" variable="true"> - <resource name="aura" amount="10" cost="level"/> - </spell> - <spell name="illaundestroymagic" type="illaun" rank="2" level="8" index="140" parameters="kc?" los="true" ship="true" far="true" variable="true"> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="cerddor_destroymagic" type="cerddor" rank="2" level="8" index="141" parameters="kc?" los="true" ship="true" far="true" variable="true"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="barkskin" type="gwyrrd" rank="2" level="12" index="142" variable="true" combat="1"> - <resource name="aura" amount="4" cost="level"/> - </spell> - <spell name="draigfumbleshield" type="draig" rank="2" level="9" index="143" variable="true" combat="1"> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="gwyrrdfumbleshield" type="gwyrrd" rank="2" level="5" index="144" variable="true" combat="1"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="cerrdorfumbleshield" type="cerddor" rank="2" level="5" index="145" variable="true" combat="1"> - <resource name="aura" amount="5" cost="level"/> - </spell> - <spell name="tybiedfumbleshield" type="tybied" rank="2" level="2" index="146" variable="true" combat="1"> - <resource name="aura" amount="3" cost="level"/> - </spell> - <spell name="shadowknights" type="illaun" rank="4" level="1" index="147" variable="true" combat="1"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="concealing_aura" type="tybied" rank="5" level="1" index="150" parameters="u" ship="true" variable="true"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="firewall" type="draig" rank="4" level="7" index="151" syntax="direction" parameters="c" variable="true"> - <resource name="aura" amount="6" cost="level"/> - </spell> - <spell name="wisps" type="illaun" rank="5" level="7" index="152" syntax="direction" parameters="c" far="true" variable="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="sparklechaos" type="draig" rank="5" level="1" index="153" parameters="u" los="true" variable="true"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="sparkledream" type="illaun" rank="5" level="1" index="154" parameters="u" los="true" ship="true" variable="true"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="pull_astral" type="tybied" rank="7" level="6" index="156" parameters="ru+" variable="true" target_global="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="fetch_astral" type="tybied" rank="7" level="6" index="157" parameters="u+" variable="true" target_global="true"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="shockwave" type="tybied" rank="5" level="5" index="163" variable="true" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="undeadhero" type="draig" rank="5" level="9" index="164" variable="true" combat="3"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="wyrm_transformation" type="gray" rank="5" level="1" index="166"> - <resource name="aura" amount="1" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - <spell name="eternal_walls" type="tybied" rank="5" level="7" index="167" parameters="b" ship="true" variable="true"> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - <spell name="puttorest" type="illaun" rank="5" level="2" index="168" variable="true"> - <resource name="aura" amount="3" cost="level"/> - <resource name="p2" amount="1" cost="fixed"/> - </spell> - <spell name="unholypower" type="draig" rank="5" level="14" index="169" parameters="u+" los="true" variable="true"> - <resource name="aura" amount="10" cost="level"/> - <resource name="peasant" amount="5" cost="level"/> - </spell> - <spell name="holyground" type="gwyrrd" rank="5" level="9" index="170"> - <resource name="aura" amount="80" cost="fixed"/> - <resource name="permaura" amount="3" cost="fixed"/> - </spell> - <spell name="bloodsacrifice" type="draig" rank="1" level="4" index="171" ship="true"> - <resource name="hp" amount="4" cost="level"/> - </spell> - <spell name="magic_roots" type="gwyrrd" rank="5" level="16" index="172" far="true"> - <resource name="aura" amount="250" cost="fixed"/> - <resource name="permaura" amount="10" cost="fixed"/> - <resource name="toadslime" amount="1" cost="fixed"/> - </spell> - <spell name="clone" type="illaun" rank="5" level="9" index="173"> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="20" cost="fixed"/> - <resource name="dragonblood" amount="5" cost="fixed"/> - <resource name="p2" amount="5" cost="fixed"/> - </spell> - <spell name="drain_skills" type="gray" rank="5" level="12" index="174" combat="2"> - <resource name="aura" amount="4" cost="fixed"/> - </spell> - <spell name="aura_of_fear" type="gray" rank="5" level="12" index="175" combat="2"> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="shadowcall" type="gray" rank="5" level="12" index="176" combat="1"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="mallorntreegrow" type="gwyrrd" rank="5" level="4" index="177" far="true" variable="true"> - <resource name="aura" amount="6" cost="level"/> - <resource name="mallorn" amount="1" cost="level"/> - <resource name="p2" amount="1" cost="fixed"/> - </spell> - <spell name="big_recruit" type="cerddor" rank="5" level="14" index="179" variable="true"> - <resource name="aura" amount="20" cost="level"/> - </spell> - <spell name="immolation" type="gray" rank="5" level="12" index="180" combat="2"> - <resource name="aura" amount="2" cost="level"/> - </spell> - <spell name="firestorm" type="gray" rank="5" level="8" index="181" combat="2"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="coldfront" type="gray" rank="5" level="8" index="182" combat="2"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - <spell name="acidrain" type="gray" rank="5" level="8" index="183" combat="2"> - <resource name="aura" amount="2" cost="fixed"/> - </spell> - - <!-- draig spells --> - <spell name="create_roi" type="draig" ship="true" rank="5" level="6" index="130"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="earn_silver#draig" type="draig" ship="true" variable="true" rank="5" level="1" index="159"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - - <spell name="create_aots" type="draig" ship="true" rank="5" level="6" index="125"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="create_firesword" type="draig" ship="true" rank="5" level="12" index="148"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="p10" amount="1" cost="fixed"/> - <resource name="sword" amount="1" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="create_trollbelt" type="draig" ship="true" rank="5" level="9" index="48"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="20" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <!-- gwyrrd spells --> - <spell name="blessedharvest" type="gwyrrd" rank="5" level="1" index="25" ship="true" far="true" variable="true"> - <!-- Segen der Erde --> - <function name="cast" value="cast_blessedharvest"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - - <spell name="create_roi" type="gwyrrd" ship="true" rank="5" level="6" index="129"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="earn_silver#gwyrrd" type="gwyrrd" ship="true" variable="true" rank="5" level="1" index="159"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - - <spell name="create_aots" type="gwyrrd" ship="true" rank="5" level="6" index="124"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="create_magicherbbag" type="gwyrrd" ship="true" rank="5" level="5" index="165"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="30" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - <resource name="p2" amount="1" cost="fixed"/> - </spell> - - <!-- illaun spells --> - <spell name="create_roi" type="illaun" ship="true" rank="5" level="6" index="131"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="earn_silver#illaun" type="illaun" ship="true" variable="true" rank="5" level="1" index="159"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - - <spell name="create_aots" type="illaun" ship="true" rank="5" level="6" index="126"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="create_dreameye" type="illaun" ship="true" rank="5" level="14" index="149"> - <function name="cast" value="lua_castspell"/> - <resource name="dragonhead" amount="1" cost="fixed"/> - <resource name="permaura" amount="5" cost="fixed"/> - </spell> - - <spell name="create_invisibility_sphere" type="illaun" ship="true" rank="5" level="13" index="178"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="150" cost="fixed"/> - <resource name="money" amount="30000" cost="fixed"/> - <resource name="permaura" amount="3" cost="fixed"/> - </spell> - - <!-- cerddor spells --> - <spell name="raindance" type="cerddor" rank="5" level="3" index="26" ship="true" far="true" variable="true"> - <!-- Segen der Erde --> - <function name="cast" value="cast_blessedharvest"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - <spell name="create_roi" type="cerddor" ship="true" rank="5" level="6" index="132"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="earn_silver#cerddor" type="cerddor" ship="true" variable="true" rank="5" level="1" index="159"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - - <spell name="create_aots" type="cerddor" ship="true" rank="5" level="6" index="127"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="create_roqf" type="cerddor" ship="true" rank="5" level="11" index="63"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="20" cost="fixed"/> - <resource name="money" amount="1000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="blabbermouth" parameters="u" type="cerddor" los="true" rank="5" level="4" index="115"> - <function name="cast" value="cast_babbler"/> - <resource name="aura" amount="10" cost="fixed"/> - <!-- missing syntactical info: ONETARGET | UNITSPELL --> - </spell> - - <spell name="readmind" parameters="u" type="illaun" rank="5" level="7" index="114"> - <function name="cast" value="cast_readmind"/> - <resource name="aura" amount="20" cost="fixed"/> - <!-- missing syntactical info: ONETARGET | UNITSPELL --> - </spell> - - <!-- tybied spells --> - <spell name="create_roi" type="tybied" ship="true" rank="5" level="6" index="133"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="earn_silver#tybied" type="tybied" ship="true" variable="true" rank="5" level="1" index="159"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="1" cost="level"/> - </spell> - - <spell name="create_aots" type="tybied" ship="true" rank="5" level="6" index="128"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="create_antimagic" type="tybied" ship="true" rank="5" level="7" index="38"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - </spell> - - <spell name="create_rop" type="tybied" ship="true" rank="5" level="9" index="1"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - <resource name="money" amount="4000" cost="fixed"/> - </spell> - - <spell name="create_bagofholding" type="tybied" ship="true" rank="5" level="10" index="155"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="30" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - <resource name="money" amount="5000" cost="fixed"/> - </spell> - - <!-- gray magic --> - <spell name="create_runesword" type="gray" ship="true" rank="5" level="6" index="135"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - <resource name="money" amount="1000" cost="fixed"/> - <resource name="laensword" amount="1" cost="fixed"/> - </spell> - - <spell name="create_chastitybelt" type="gray" ship="true" rank="5" level="7" index="134"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="50" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - <resource name="money" amount="3000" cost="fixed"/> - </spell> - - <spell name="create_focus" type="gray" ship="true" rank="5" level="9" index="2"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - - <spell name="create_ror" type="gray" ship="true" rank="5" level="9" index="3"> - <function name="cast" value="lua_castspell"/> - <resource name="aura" amount="100" cost="fixed"/> - <resource name="permaura" amount="1" cost="fixed"/> - </spell> - -</spells> +<?xml version="1.0"?> +<spells> + <spell name="fireball" type="draig" rank="5" level="2" index="4" variable="true" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="hail" type="gwyrrd" rank="5" level="3" index="5" variable="true" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="rustweapon" type="gwyrrd" rank="5" level="3" index="6" parameters="u+" los="true" far="true" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="combatrust" type="draig" rank="5" level="6" index="7" variable="true" combat="2"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="treegrow" type="gwyrrd" rank="5" level="2" index="8" far="true" variable="true"> + <resource name="aura" amount="4" cost="level"/> + <resource name="log" amount="1" cost="level"/> + <resource name="p2" amount="1" cost="fixed"/> + </spell> + <spell name="healing" type="gwyrrd" rank="5" level="5" index="9" variable="true" combat="3"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="song_of_healing" type="cerddor" rank="5" level="2" index="10" variable="true" combat="3"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="bad_dreams" type="illaun" rank="5" level="10" index="11" far="true"> + <resource name="aura" amount="90" cost="fixed"/> + </spell> + <spell name="gooddreams" type="illaun" rank="5" level="8" index="12" far="true"> + <resource name="aura" amount="80" cost="fixed"/> + </spell> + <spell name="dreamreading" type="illaun" rank="5" level="4" index="13" parameters="u" far="true"> + <resource name="aura" amount="8" cost="fixed"/> + </spell> + <spell name="tiredsoldiers" type="illaun" rank="5" level="4" index="15" variable="true" combat="1"> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="plague" type="draig" rank="5" level="7" index="16" far="true"> + <resource name="aura" amount="30" cost="fixed"/> + <resource name="peasant" amount="50" cost="fixed"/> + </spell> + <spell name="magicboost" type="draig" rank="3" level="3" index="17" ship="true"> + <resource name="aura" amount="2" cost="linear"/> + </spell> + <spell name="chaosrow" type="draig" rank="5" level="8" index="18" variable="true" combat="1"> + <resource name="aura" amount="3" cost="level"/> + <resource name="peasant" amount="10" cost="fixed"/> + </spell> + <spell name="song_of_confusion" type="cerddor" rank="5" level="4" index="19" variable="true" combat="1"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="flee" type="illaun" rank="5" level="2" index="20" variable="true" combat="1"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="song_of_fear" type="cerddor" rank="5" level="3" index="21" variable="true" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="berserk" type="draig" rank="4" level="5" index="22" variable="true" combat="1"> + <resource name="aura" amount="5" cost="level"/> + <resource name="peasant" amount="1" cost="fixed"/> + </spell> + <spell name="bloodthirst" type="cerddor" rank="4" level="7" index="23" variable="true" combat="1"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="maelstrom" type="gwyrrd" rank="5" level="15" index="24" ship="true" ocean="true"> + <resource name="aura" amount="200" cost="fixed"/> + <resource name="seaserpenthead" amount="1" cost="fixed"/> + </spell> + <spell name="transferauradruide" type="gwyrrd" rank="1" level="6" index="27" syntax="aura" parameters="ui" ship="true"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="transfer_aura_song" type="cerddor" rank="1" level="5" index="28" syntax="aura" parameters="ui" ship="true"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="transferaurachaos" type="draig" rank="1" level="7" index="29" syntax="aura" parameters="ui" ship="true"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="transferauratraum" type="illaun" rank="1" level="3" index="30" syntax="aura" parameters="ui" ship="true"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="auratransfer" type="tybied" rank="1" level="5" index="31" syntax="aura" parameters="ui" ship="true"> + <resource name="aura" amount="1" cost="fixed"/> + </spell> + <spell name="stonegolem" type="gwyrrd" rank="4" level="1" index="32" variable="true"> + <resource name="aura" amount="2" cost="level"/> + <resource name="stone" amount="1" cost="level"/> + <resource name="p2" amount="1" cost="fixed"/> + </spell> + <spell name="irongolem" type="gwyrrd" rank="4" level="2" index="33" variable="true"> + <resource name="aura" amount="2" cost="level"/> + <resource name="iron" amount="1" cost="level"/> + <resource name="p2" amount="1" cost="fixed"/> + </spell> + <spell name="summonshadow" type="draig" rank="5" level="8" index="34" variable="true"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="summonshadowlords" type="draig" rank="5" level="12" index="35" variable="true"> + <resource name="aura" amount="7" cost="level"/> + </spell> + <spell name="reelingarrows" type="gwyrrd" rank="5" level="5" index="36" variable="true" combat="1"> + <resource name="aura" amount="15" cost="fixed"/> + </spell> + <spell name="antimagiczone" type="tybied" rank="2" level="5" index="37" far="true" variable="true"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="cold_protection" type="gwyrrd" rank="5" level="3" index="39" parameters="u+" los="true" ship="true" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="steal_aura" type="tybied" rank="3" level="6" index="40" parameters="u" los="true" far="true" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="summonundead" type="draig" rank="5" level="6" index="41" ship="true" far="true" variable="true"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="auraleak" type="draig" rank="3" level="9" index="42"> + <resource name="aura" amount="35" cost="fixed"/> + <resource name="dragonblood" amount="1" cost="fixed"/> + </spell> + <spell name="great_drought" type="gwyrrd" rank="5" level="17" index="43" far="true"> + <resource name="aura" amount="800" cost="fixed"/> + </spell> + <spell name="strongwall" type="gwyrrd" rank="5" level="8" index="44" variable="true" combat="1"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="homestone" type="gwyrrd" rank="5" level="7" index="45"> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + <spell name="summonfireelemental" type="gwyrrd" rank="5" level="13" index="46" far="true"> + <resource name="aura" amount="600" cost="fixed"/> + </spell> + <spell name="forestfire" type="draig" rank="5" level="10" index="47" far="true"> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="oil" amount="1" cost="fixed"/> + </spell> + <spell name="summonent" type="gwyrrd" rank="5" level="10" index="49" variable="true"> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="disturbingdreams" type="illaun" rank="5" level="6" index="50" far="true"> + <resource name="aura" amount="18" cost="fixed"/> + </spell> + <spell name="appeasement" type="cerddor" rank="5" level="1" index="51" variable="true" combat="1"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="sleep" type="illaun" rank="5" level="7" index="52" variable="true" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="earthquake" type="gwyrrd" rank="5" level="6" index="53" far="true"> + <resource name="aura" amount="25" cost="fixed"/> + <resource name="laen" amount="2" cost="fixed"/> + </spell> + <spell name="ironkeeper" type="gwyrrd" rank="5" level="3" index="54" far="true" variable="true"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="stormwinds" type="gwyrrd" rank="5" level="6" index="55" parameters="s+" ship="true" ocean="true" variable="true"> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="goodwinds" type="gwyrrd" rank="5" level="4" index="56" parameters="s" ship="true" variable="true"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="airship" type="tybied" rank="5" level="6" index="57" parameters="s" ship="true"> + <resource name="aura" amount="10" cost="fixed"/> + <resource name="h12" amount="1" cost="fixed"/> + <resource name="h20" amount="1" cost="fixed"/> + </spell> + <spell name="summon_alp" type="illaun" rank="5" level="15" index="58" parameters="u" target_global="true"> + <resource name="aura" amount="350" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + <resource name="h8" amount="1" cost="fixed"/> + </spell> + <spell name="windshield" type="gwyrrd" rank="5" level="4" index="59" variable="true" combat="1"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="raise_mob" type="cerddor" rank="5" level="10" index="60" variable="true"> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="melancholy" type="cerddor" rank="5" level="11" index="61" far="true"> + <resource name="aura" amount="40" cost="fixed"/> + </spell> + <spell name="headache" type="cerddor" rank="5" level="7" index="62" parameters="u" los="true"> + <resource name="aura" amount="4" cost="linear"/> + <resource name="h7" amount="3" cost="fixed"/> + <resource name="money" amount="50" cost="fixed"/> + </spell> + <spell name="enterastral" type="tybied" rank="7" level="4" index="64" parameters="u+" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="leaveastral" type="tybied" rank="7" level="4" index="65" parameters="ru+" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="versteinern" type="gwyrrd" rank="5" level="8" index="67" variable="true" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="treewalkenter" type="gwyrrd" rank="7" level="9" index="68" parameters="u+" los="true" variable="true"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="treewalkexit" type="gwyrrd" rank="7" level="9" index="69" parameters="ru+" los="true" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="chaossuction" type="draig" rank="5" level="14" index="70"> + <resource name="aura" amount="150" cost="fixed"/> + <resource name="peasant" amount="200" cost="fixed"/> + </spell> + <spell name="view_reality" type="tybied" rank="5" level="10" index="71"> + <resource name="aura" amount="40" cost="fixed"/> + </spell> + <spell name="astral_disruption" type="tybied" rank="4" level="14" index="72" variable="true"> + <resource name="aura" amount="140" cost="fixed"/> + </spell> + <spell name="seduction" type="cerddor" rank="5" level="6" index="73" parameters="u" los="true"> + <resource name="aura" amount="12" cost="fixed"/> + </spell> + <spell name="sound_out" type="cerddor" rank="5" level="7" index="74" parameters="ur" los="true"> + <resource name="aura" amount="4" cost="fixed"/> + <resource name="money" amount="100" cost="fixed"/> + </spell> + <spell name="calm_monster" type="cerddor" rank="5" level="6" index="75" parameters="u" los="true" ship="true"> + <resource name="aura" amount="15" cost="fixed"/> + </spell> + <spell name="heroic_song" type="cerddor" rank="4" level="5" index="76" variable="true" combat="1"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="frighten" type="cerddor" rank="5" level="8" index="77" variable="true" combat="1"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="mindblast" type="illaun" rank="5" level="11" index="78" variable="true" combat="1"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="combat_speed" type="tybied" rank="5" level="9" index="79" variable="true" combat="1"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="double_time" type="tybied" rank="5" level="11" index="80" parameters="u+" los="true" ship="true" variable="true"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="fiery_dragonbreath" type="gray" rank="5" level="3" index="81" combat="2"> + <resource name="aura" amount="1" cost="fixed"/> + </spell> + <spell name="icy_dragonbreath" type="gray" rank="5" level="6" index="82" combat="2"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="powerful_dragonbreath" type="gray" rank="5" level="12" index="83" combat="2"> + <resource name="aura" amount="3" cost="fixed"/> + </spell> + <spell name="magicstreet" type="gwyrrd" rank="5" level="4" index="84" ship="true" far="true" variable="true"> + <resource name="aura" amount="1" cost="level"/> + <resource name="stone" amount="1" cost="fixed"/> + <resource name="log" amount="1" cost="fixed"/> + </spell> + <spell name="reanimate" type="illaun" rank="4" level="5" index="85" variable="true" combat="3"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="courting" type="cerddor" rank="5" level="4" index="86" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="generous" type="cerddor" rank="5" level="2" index="87" ship="true" far="true" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="sacrifice_strength" type="tybied" rank="1" level="15" index="88" syntax="aura" parameters="ui"> + <resource name="aura" amount="100" cost="fixed"/> + </spell> + <spell name="song_of_peace" type="cerddor" rank="5" level="12" index="89" variable="true"> + <resource name="aura" amount="20" cost="level"/> + </spell> + <spell name="migration" type="cerddor" rank="5" level="9" index="90" parameters="u" los="true" variable="true"> + <resource name="aura" amount="3" cost="level"/> + <resource name="permaura" amount="1" cost="level"/> + </spell> + <spell name="calm_riot" type="cerddor" rank="5" level="15" index="91" far="true"> + <resource name="aura" amount="30" cost="fixed"/> + </spell> + <spell name="incite_riot" type="cerddor" rank="5" level="16" index="92" far="true"> + <resource name="aura" amount="40" cost="fixed"/> + </spell> + <spell name="shapeshift" type="illaun" rank="5" level="3" index="93" syntax="race" parameters="uc" variable="true"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="wolfhowl" type="gwyrrd" rank="5" level="7" index="94" variable="true" combat="1"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="resist_magic" type="tybied" rank="2" level="3" index="97" parameters="u+" los="true" ship="true" variable="true"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="keeploot" type="tybied" rank="5" level="3" index="98" variable="true" combat="3"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="protective_runes" type="tybied" rank="2" level="8" index="99" parameters="kc" ship="true"> + <resource name="aura" amount="20" cost="fixed"/> + </spell> + <spell name="song_resist_magic" type="cerddor" rank="2" level="10" index="100" far="true" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="song_suscept_magic" type="cerddor" rank="2" level="12" index="101" far="true" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="analyze_magic" type="tybied" rank="5" level="1" index="102" parameters="kc?" los="true" ship="true" variable="true"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="analysedream" type="illaun" rank="5" level="5" index="103" parameters="u" los="true" ship="true"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="analysesong_unit" type="cerddor" rank="5" level="5" index="104" parameters="u" los="true" ship="true"> + <resource name="aura" amount="10" cost="fixed"/> + </spell> + <spell name="analyse_object" type="cerddor" rank="5" level="8" index="105" parameters="kc?" ship="true" variable="true"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="destroy_magic" type="tybied" rank="2" level="5" index="106" parameters="kc?" los="true" ship="true" far="true" variable="true"> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="break_curse" type="tybied" rank="3" level="7" index="107" syntax="spellid" parameters="kcc?" los="true" ship="true" far="true" variable="true"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="meteor_rain" type="gray" rank="5" level="3" index="108" variable="true" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="fish_shield" type="tybied" rank="2" level="8" index="109" variable="true" combat="1"> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="armor_shield" type="tybied" rank="2" level="12" index="110" variable="true" combat="1"> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="deathcloud" type="draig" rank="5" level="11" index="111" far="true"> + <resource name="aura" amount="40" cost="fixed"/> + <resource name="hp" amount="15" cost="fixed"/> + </spell> + <spell name="orkdream" type="illaun" rank="5" level="12" index="112" parameters="u+" los="true" variable="true"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="summondragon" type="draig" rank="5" level="11" index="113" far="true"> + <resource name="aura" amount="80" cost="fixed"/> + <resource name="dragonhead" amount="1" cost="fixed"/> + </spell> + <spell name="living_rock" type="tybied" rank="5" level="13" index="116" syntax="direction" parameters="bc" variable="true"> + <resource name="aura" amount="10" cost="level"/> + <resource name="permaura" amount="1" cost="fixed"/> + <resource name="laen" amount="5" cost="fixed"/> + </spell> + <spell name="blessstonecircle" type="gwyrrd" rank="5" level="11" index="117" parameters="b"> + <resource name="aura" amount="350" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="illaunfamiliar" type="illaun" rank="5" level="9" index="118"> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="gwyrrdfamiliar" type="gwyrrd" rank="5" level="10" index="119"> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="draigfamiliar" type="draig" rank="5" level="13" index="120"> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="summon_familiar" type="cerddor" rank="5" level="9" index="121"> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="summon_familiar" type="tybied" rank="5" level="12" index="122"> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + <spell name="song_of_slavery" type="cerddor" rank="5" level="13" index="123" parameters="u" los="true"> + <resource name="aura" amount="40" cost="fixed"/> + </spell> + <spell name="fumblecurse" type="draig" rank="4" level="5" index="136" parameters="u" los="true" variable="true"> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="icastle" type="illaun" rank="5" level="3" index="137" syntax="buildingtype" parameters="c"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="gwyrrddestroymagic" type="gwyrrd" rank="2" level="8" index="138" parameters="kc?" los="true" ship="true" far="true" variable="true"> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="draigdestroymagic" type="draig" rank="2" level="10" index="139" parameters="kc?" los="true" ship="true" far="true" variable="true"> + <resource name="aura" amount="10" cost="level"/> + </spell> + <spell name="illaundestroymagic" type="illaun" rank="2" level="8" index="140" parameters="kc?" los="true" ship="true" far="true" variable="true"> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="cerddor_destroymagic" type="cerddor" rank="2" level="8" index="141" parameters="kc?" los="true" ship="true" far="true" variable="true"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="barkskin" type="gwyrrd" rank="2" level="12" index="142" variable="true" combat="1"> + <resource name="aura" amount="4" cost="level"/> + </spell> + <spell name="draigfumbleshield" type="draig" rank="2" level="9" index="143" variable="true" combat="1"> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="gwyrrdfumbleshield" type="gwyrrd" rank="2" level="5" index="144" variable="true" combat="1"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="cerrdorfumbleshield" type="cerddor" rank="2" level="5" index="145" variable="true" combat="1"> + <resource name="aura" amount="5" cost="level"/> + </spell> + <spell name="tybiedfumbleshield" type="tybied" rank="2" level="2" index="146" variable="true" combat="1"> + <resource name="aura" amount="3" cost="level"/> + </spell> + <spell name="shadowknights" type="illaun" rank="4" level="1" index="147" variable="true" combat="1"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="concealing_aura" type="tybied" rank="5" level="1" index="150" parameters="u" ship="true" variable="true"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="firewall" type="draig" rank="4" level="7" index="151" syntax="direction" parameters="c" variable="true"> + <resource name="aura" amount="6" cost="level"/> + </spell> + <spell name="wisps" type="illaun" rank="5" level="7" index="152" syntax="direction" parameters="c" far="true" variable="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="sparklechaos" type="draig" rank="5" level="1" index="153" parameters="u" los="true" variable="true"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="sparkledream" type="illaun" rank="5" level="1" index="154" parameters="u" los="true" ship="true" variable="true"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="pull_astral" type="tybied" rank="7" level="6" index="156" parameters="ru+" variable="true" target_global="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="fetch_astral" type="tybied" rank="7" level="6" index="157" parameters="u+" variable="true" target_global="true"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="shockwave" type="tybied" rank="5" level="5" index="163" variable="true" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="undeadhero" type="draig" rank="5" level="9" index="164" variable="true" combat="3"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="wyrm_transformation" type="gray" rank="5" level="1" index="166"> + <resource name="aura" amount="1" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + <spell name="eternal_walls" type="tybied" rank="5" level="7" index="167" parameters="b" ship="true" variable="true"> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + <spell name="puttorest" type="illaun" rank="5" level="2" index="168" variable="true"> + <resource name="aura" amount="3" cost="level"/> + <resource name="p2" amount="1" cost="fixed"/> + </spell> + <spell name="unholypower" type="draig" rank="5" level="14" index="169" parameters="u+" los="true" variable="true"> + <resource name="aura" amount="10" cost="level"/> + <resource name="peasant" amount="5" cost="level"/> + </spell> + <spell name="holyground" type="gwyrrd" rank="5" level="9" index="170"> + <resource name="aura" amount="80" cost="fixed"/> + <resource name="permaura" amount="3" cost="fixed"/> + </spell> + <spell name="bloodsacrifice" type="draig" rank="1" level="4" index="171" ship="true"> + <resource name="hp" amount="4" cost="level"/> + </spell> + <spell name="magic_roots" type="gwyrrd" rank="5" level="16" index="172" far="true"> + <resource name="aura" amount="250" cost="fixed"/> + <resource name="permaura" amount="10" cost="fixed"/> + <resource name="toadslime" amount="1" cost="fixed"/> + </spell> + <spell name="clone" type="illaun" rank="5" level="9" index="173"> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="20" cost="fixed"/> + <resource name="dragonblood" amount="5" cost="fixed"/> + <resource name="p2" amount="5" cost="fixed"/> + </spell> + <spell name="drain_skills" type="gray" rank="5" level="12" index="174" combat="2"> + <resource name="aura" amount="4" cost="fixed"/> + </spell> + <spell name="aura_of_fear" type="gray" rank="5" level="12" index="175" combat="2"> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="shadowcall" type="gray" rank="5" level="12" index="176" combat="1"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="mallorntreegrow" type="gwyrrd" rank="5" level="4" index="177" far="true" variable="true"> + <resource name="aura" amount="6" cost="level"/> + <resource name="mallorn" amount="1" cost="level"/> + <resource name="p2" amount="1" cost="fixed"/> + </spell> + <spell name="big_recruit" type="cerddor" rank="5" level="14" index="179" variable="true"> + <resource name="aura" amount="20" cost="level"/> + </spell> + <spell name="immolation" type="gray" rank="5" level="12" index="180" combat="2"> + <resource name="aura" amount="2" cost="level"/> + </spell> + <spell name="firestorm" type="gray" rank="5" level="8" index="181" combat="2"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="coldfront" type="gray" rank="5" level="8" index="182" combat="2"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + <spell name="acidrain" type="gray" rank="5" level="8" index="183" combat="2"> + <resource name="aura" amount="2" cost="fixed"/> + </spell> + + <!-- draig spells --> + <spell name="create_roi" type="draig" ship="true" rank="5" level="6" index="130"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="earn_silver#draig" type="draig" ship="true" variable="true" rank="5" level="1" index="159"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + + <spell name="create_aots" type="draig" ship="true" rank="5" level="6" index="125"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="create_firesword" type="draig" ship="true" rank="5" level="12" index="148"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="p10" amount="1" cost="fixed"/> + <resource name="sword" amount="1" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="create_trollbelt" type="draig" ship="true" rank="5" level="9" index="48"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="20" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <!-- gwyrrd spells --> + <spell name="blessedharvest" type="gwyrrd" rank="5" level="1" index="25" ship="true" far="true" variable="true"> + <!-- Segen der Erde --> + <function name="cast" value="cast_blessedharvest"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + + <spell name="create_roi" type="gwyrrd" ship="true" rank="5" level="6" index="129"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="earn_silver#gwyrrd" type="gwyrrd" ship="true" variable="true" rank="5" level="1" index="159"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + + <spell name="create_aots" type="gwyrrd" ship="true" rank="5" level="6" index="124"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="create_magicherbbag" type="gwyrrd" ship="true" rank="5" level="5" index="165"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="30" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + <resource name="p2" amount="1" cost="fixed"/> + </spell> + + <!-- illaun spells --> + <spell name="create_roi" type="illaun" ship="true" rank="5" level="6" index="131"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="earn_silver#illaun" type="illaun" ship="true" variable="true" rank="5" level="1" index="159"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + + <spell name="create_aots" type="illaun" ship="true" rank="5" level="6" index="126"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="create_dreameye" type="illaun" ship="true" rank="5" level="14" index="149"> + <function name="cast" value="lua_castspell"/> + <resource name="dragonhead" amount="1" cost="fixed"/> + <resource name="permaura" amount="5" cost="fixed"/> + </spell> + + <spell name="create_invisibility_sphere" type="illaun" ship="true" rank="5" level="13" index="178"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="150" cost="fixed"/> + <resource name="money" amount="30000" cost="fixed"/> + <resource name="permaura" amount="3" cost="fixed"/> + </spell> + + <!-- cerddor spells --> + <spell name="raindance" type="cerddor" rank="5" level="3" index="26" ship="true" far="true" variable="true"> + <!-- Segen der Erde --> + <function name="cast" value="cast_blessedharvest"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + <spell name="create_roi" type="cerddor" ship="true" rank="5" level="6" index="132"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="earn_silver#cerddor" type="cerddor" ship="true" variable="true" rank="5" level="1" index="159"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + + <spell name="create_aots" type="cerddor" ship="true" rank="5" level="6" index="127"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="create_roqf" type="cerddor" ship="true" rank="5" level="11" index="63"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="20" cost="fixed"/> + <resource name="money" amount="1000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="blabbermouth" parameters="u" type="cerddor" los="true" rank="5" level="4" index="115"> + <function name="cast" value="cast_babbler"/> + <resource name="aura" amount="10" cost="fixed"/> + <!-- missing syntactical info: ONETARGET | UNITSPELL --> + </spell> + + <spell name="readmind" parameters="u" type="illaun" rank="5" level="7" index="114"> + <function name="cast" value="cast_readmind"/> + <resource name="aura" amount="20" cost="fixed"/> + <!-- missing syntactical info: ONETARGET | UNITSPELL --> + </spell> + + <!-- tybied spells --> + <spell name="create_roi" type="tybied" ship="true" rank="5" level="6" index="133"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="earn_silver#tybied" type="tybied" ship="true" variable="true" rank="5" level="1" index="159"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="1" cost="level"/> + </spell> + + <spell name="create_aots" type="tybied" ship="true" rank="5" level="6" index="128"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="create_antimagic" type="tybied" ship="true" rank="5" level="7" index="38"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + </spell> + + <spell name="create_rop" type="tybied" ship="true" rank="5" level="9" index="1"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + <resource name="money" amount="4000" cost="fixed"/> + </spell> + + <spell name="create_bagofholding" type="tybied" ship="true" rank="5" level="10" index="155"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="30" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + <resource name="money" amount="5000" cost="fixed"/> + </spell> + + <!-- gray magic --> + <spell name="create_runesword" type="gray" ship="true" rank="5" level="6" index="135"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + <resource name="money" amount="1000" cost="fixed"/> + <resource name="laensword" amount="1" cost="fixed"/> + </spell> + + <spell name="create_chastitybelt" type="gray" ship="true" rank="5" level="7" index="134"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="50" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + <resource name="money" amount="3000" cost="fixed"/> + </spell> + + <spell name="create_focus" type="gray" ship="true" rank="5" level="9" index="2"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + + <spell name="create_ror" type="gray" ship="true" rank="5" level="9" index="3"> + <function name="cast" value="lua_castspell"/> + <resource name="aura" amount="100" cost="fixed"/> + <resource name="permaura" amount="1" cost="fixed"/> + </spell> + +</spells> diff --git a/res/eressea/strings.xml b/res/eressea/strings.xml index 435e53f61..16fdf946c 100644 --- a/res/eressea/strings.xml +++ b/res/eressea/strings.xml @@ -1,392 +1,392 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<strings> - <namespace name="race"> - <string name="snowman"> - <text locale="de">Schneemann</text> - <text locale="en">snowman</text> - </string> - <string name="snowman_p"> - <text locale="de">Schneem�nner</text> - <text locale="en">snowmen</text> - </string> - </namespace> - <namespace name="shipinfo"> - <!-- ship info is not implemented! --> - <string name="no_info"> - <text locale="de">Keine Informationen �ber diesen Schiffstyp verf�gbar.</text> - <text locale="en">No Information available for this type of ship.</text> - </string> - <string name="balloon"> - <text locale="de">Der Sumpfgasballon besteht aus einem gro�en - Weidenkorb, welcher Platz - f�r maximal 5 Personen oder 500 Gewichtseinheiten bietet, und einer - gro�en, mit Sumpfgas gef�llten Wyrmblase. Bei guten Winden kann sich - der Ballon zwei Regionen pro Woche fortbewegen. Das F�hren eines - Ballons ist nicht einfach, und der Kapit�n muss mindestens ein - Segeltalent von 6 besitzen. Diese neue Entwicklung auf Eressea wird - ausschlie�lich f�r den Xontormia-Expre� hergestellt und die Baupl�ne - sind streng geheim. So ist es auch bisher noch niemandem gelungen, ein - Exemplar nachzubauen.</text> - </string> - </namespace> - <namespace name="iteminfo"> - <string name="ring_of_levitation"> - <text locale="de">Benutzt der Kapit�n des Schiffes diesen Talisman, so wird allen an Bord befindlichen Mallornsamen ihre magisch Energie entzogen, und das Schiff kann mit dieser Energie bis zu zwei Wochen lang fliegen.</text> - </string> - <string name="birthdaycake"> - <text locale="de">Eine Geburtstagstorte mit 10 Kerzen. Herzlichen Gl�ckwunsch, Eressea!</text> - <text locale="en">A birthday cake with 10 candles. Happy Birthday, Eressea!</text> - </string> - <string name="no_info"> - <text locale="de">Keine Informationen.</text> - <text locale="en">No Information available.</text> - </string> - <string name="griphonwing"> - <text locale="de">Dieses Flugger�t aus der Schmiede der Zwerge von Celeband galt wie die - 'Ebene der Herausforderung' seit Urzeiten als verschollen, ja man - zweifelte seine Existenz an. Die Sage �berliefert, das derjenige, der - sie auf der Spitze des Turmes seiner Gesinnung benutzt, als einziger - die 'Ebene der Herausforderungen' verlassen kann.</text> - </string> - <string name="ao_daemon"> - <text locale="de">Gl�ckwunsch, mein Kind. Du bist im Besitz des m�chtigsten - Artefaktes Eresseas. Ein Fluch, sagt man, liege auf ihm, denn - niemand hat es bisher lange sein Eigen genannt...</text> - </string> - <string name="cookie"> - <text locale="de">Kleines trockenes Dauergeb�ck, m od. s; - u. -es, - u. -e</text> - </string> - <string name="eyeofdragon"> - <text locale="de">So wisse denn, dass das Auge des Drachen den Weg zur Herausforderung - aufzeigt. Doch die �berlieferung sagt, das nur der Unschuldige und - Ungewappnete es benutzen kann. Sie sagt auch, da� er einen Beutel mit - einem Betrag von bis zu zweitausend Silber mit sich f�hren soll, - jedoch nicht mehr als einem F�nftel der St�rke seines Volkes - entsprechend - dem Torw�chter zum Geschenke als Beweis seiner - asketischen Gesinnung. Die 5 scheidet ganz aus.</text> - </string> - <string name="almond"> - <text locale="de">(Prunus dulcis) [...] Die N�sse existieren in zwei Varianten, s�� und - bitter. S��e Mandeln sind der bekannte e�bare Typ, der in Form von - N�ssen gegessen, beim Kochen verwandt oder zu Mandel�l und Mandelmehl - verarbeitet wird.</text> - </string> - <string name="apple"> - <text locale="en">A tasty fruit.</text> - <text locale="de">Frucht aus der Gattung Malus (ca. 25 Arten), geh�rt - zur Familie der - Rosengew�chse. Die am h�ufigsten kultivierte Baumfrucht. Der Apfel - geh�rt zu den fleischigen Fr�chten, in dem der gereifte Fruchtknoten - und - das umgebende Gewebe fleischig und e�bar werden. Die Apfelbl�te der - meisten Varianten erfordert Kreuzbest�ubung zur Befruchtung. Form und - Gr��e des Apfels bei der Ernte variieren abh�ngig von kulturellen und - umweltbedingten Einfl�ssen in Gr��e, Form, Farbe und Geschmack, sind - jedoch nichtsdestotrotz �blicherweise rund, zwischen 50 und 100mm im - Durchmesser und weisen r�t- oder gelbliche Farbt�ne auf.</text> - </string> - <string name="nut"> - <text locale="de">Nu�, im umgangssprachlichen Sinne alle trockenen, - hartschaligen - Fr�chte oder Samen, die eine Schale besitzen, die sich leicht - vom inneren, e�baren Kern entfernen l��t. In der botanischen - Terminologie beschr�nkt sich die Bezeichnung Nu� auf eine - einsamige Frucht, die aus einem Fruchtknoten (Ovarium) - entstanden ist, dessen �u�ere W�nde sich verholzt haben und der - sich nicht �ffnet, um seinen Samen zu entlassen. Solche echten - N�sse k�nnen e�bar, aber auch ungenie�bar sein. Bekannte - Beispiele sind Eicheln, Bucheckern, Kastanien und Haseln�sse. - Beispiele f�r Fr�chte oder Samen, die vom Volksmund f�lschlich - als N�sse bezeichnet werden, sind Mandeln und Waln�sse: Im - botanischen Sinne sind dies Steinfr�chte, denen die fleischige - �u�ere Schale entfernt wurde. Andere Beispiele f�r unechte - N�sse sind Erdn�sse - in H�lsen eingeschlossene Samen - sowie - Ro�kastanien und Paran�sse, bei denen es sich um von Kapseln - umh�llte Samen handelt.</text> - </string> - <string name="jadee_ring"> - <text locale="de">Zwerge schufen diesen wundersch�nen Ring aus Weissgold und Platin. Die - Oberfl�che ist so glatt, dass man nur bei genauem Hinsehen entdeckt, - dass hier eigentlich zwei Metalle ineinander verarbeitet worden sind. - In der Innenseite des Rings ist eine Gravur zu lesen: "Wildente, 3. - Woche Eiswind Jahr 8".</text> - </string> - <string name="jadee_dress"> - <text locale="de">Dieses Brautkleid ist mit Abstand das sch�nste, was je jemand - irgendwie irgendwo gesehen hat. Auch wenn nur Wildente und Jadee das - finden m�ssten, wird jeder Bewohner Eresseas dies neidlos best�tigen. - Das sehr stilvolle Kleid l�sst die zarten Schultern seiner Tr�gerin - frei und liegt am Oberk�rper eng an. Dies betont atemberaubend die - zarten Kurven der Braut. Der Rock f�llt leicht ausgestellt den ganzen - langen Weg an den Beinen herunter Richtung Boden, wo er sich in einer - sehr stilvollen Schleppe ergiesst.</text> - </string> - <string name="wente_ring"> - <text locale="de">Dieser Ring ist ein wahres Meisterwerk. Obwohl er sehr gross ist - (weil auch sein Tr�ger sehr gross ist), wirkt er filigran. Weissgold - und Platin verschmelzen in diesem Ring zu einer Einheit, die die - Sch�nheit der einzelnen Elemente nur noch unterstreich. In der - Innenseite des Rings ist eine Gravur zu lesen: 'Jadee, 3. Woche - Eiswind Jahr 8'.</text> - </string> - <string name="wente_dress"> - <text locale="de">Hach! Sieht der Mann beeindruckend aus in diesem Frack! Und so - ordentlich! Und so ernst! Und so beeindruckend! Es f�llt ein - wenig schwer, sich auf den Br�utigam zu konzentrieren, weil das - Brautkleid noch daneben strahlt, aber der Anzug des Br�utigams ist - auf jeden Fall so, wie er sein soll und sieht toll aus und sehr - geschmackvoll.</text> - </string> - <string name="snowman"> - <text locale="en">Orange nose, black hat, frosty character. A snowman. - He'll make a fine guard if you use him in a cold place. (USE 1 - snowman)</text> - <text locale="de">R�bennase, schwarzer Hut, kaltes Herz. Ein Schneemann. Er gibt - einen prima Wachmann ab, wenn er in einem Gletscher belebt wird - (BENUTZE 1 Schneemann).</text> - </string> - <string name="snowball"> - <text locale="en">These items stay frozen all year round. There seem to be bits of - ice in them - in the right hands, these might put an eye out!</text> - <text locale="de">Ein Schneeball. Es scheinen kleine Eissplitter darin zu sein. In - den richtigen H�nden k�nnen sie sicher weh tun.</text> - </string> - <string name="seashell"> - <text locale="en">This badge pronounces its wearer an official visitor to the - region of Muschelplateau.</text> - <text locale="de">Dieses Abzeichen identifiziert die Partei seines Tr�gers offiziell - als einen Besucher der Botschafterregion 'Muschelplateau'.</text> - </string> - <string name="xmastree"> - <text locale="de">Dieser wunderschoen geschmueckte Baum entfaltet in den Wintermonaten eine magische Wirkung auf den ganzen Wald.</text> - <text locale="en">In the winter months, this beautifully decorated tree has a magical effect on the entire forest.</text> - </string> - <string name="stardust"> - <text locale="de">Dieser magische Staub ist aus einem im Winter vom Himmel gefallenen - Stern gewonnen worden, und ihm werden aphrodisiakische Eigenschaften - nachgesagt.</text> - <text locale="en">This vial of dust, made from the remains of a star that fell from - the sky one cold winter night, is said to have aphrodisiacal powers.</text> - </string> - </namespace> - <string name="ring_of_levitation"> - <text locale="de">Ring der Levitation</text> - <text locale="en">ring of levitation</text> - </string> - <string name="ring_of_levitation_p"> - <text locale="de">Ringe der Levitation</text> - <text locale="en">rings of levitation</text> - </string> - <string name="birthdaycake"> - <text locale="de">Geburtstagstorte</text> - <text locale="en">birthday cake</text> - </string> - <string name="birthdaycake_p"> - <text locale="de">Geburtstagstorten</text> - <text locale="en">birthday cakes</text> - </string> - <string name="seashell"> - <text locale="de">Muschel</text> - <text locale="en">seashell</text> - </string> - <string name="seashell_p"> - <text locale="de">Muscheln</text> - <text locale="en">seashells</text> - </string> - - <string name="newbie_info_2"> - <text locale="de">Die ersten beiden Z�ge mu�t du abgeben, sonst wird deine - Partei sofort wieder gel�scht, um Karteileichen zu vermeiden.</text> - <text locale="en">If you fail to send in orders for one of the first two turns, your faction will be erased from the game to reduce the number of inactive players in Eressea.</text> - </string> - <string name="newbie_info_3"> - <text locale="de">Mit der ersten Auswertung bekommst du einen - Computerreport, den du mit vielen der Tools auf - http://eressea-pbem.de/download.html benutzen kannst. Wenn du ihn - weiterhin bekommen willst, gib einer deiner Einheiten den Befehl OPTION - COMPUTER.</text> - <text locale="en">With the first two turns, you will get a computer report (CR). It can be used with many of the tools on http://eressea-pbem.de/download.html. If you want to continue getting it after the second turn, please make one of your units give the order OPTION COMPUTER.</text> - </string> - <string name="defaultorder"> - <text locale="de">ARBEITEN</text> - <text locale="en">WORK</text> - </string> - <string name="temple"> - <text locale="de">Tempel</text> - <text locale="en">temple</text> - </string> - <string name="seaserpenthead"> - <text locale="de">Seeschlangenkopf</text> - </string> - <string name="seaserpenthead_p"> - <text locale="de">Seeschlangenk�pfe</text> - </string> - - <!-- starting here: Wildente and Jadee's wedding --> - <string name="pavilion"> - <text locale="de">Pavillion</text> - <text locale="en">pavilion</text> - </string> - - <string name="portal"> - <text locale="de">Portal</text> - <text locale="en">portal</text> - </string> - - <string name="jadee_ring"> - <text locale="de">Jadees Hochzeitsring</text> - <text locale="en">Jadee's wedding ring</text> - </string> - - <string name="jadee_ring_p"> - <text locale="de">Jadees Hochzeitsringe</text> - <text locale="en">Jadee's wedding rings</text> - </string> - - <string name="wente_ring"> - <text locale="de">Wildentes Hochzeitsring</text> - <text locale="en">Wildente's wedding ring</text> - </string> - - <string name="wente_ring_p"> - <text locale="de">Wildentes Hochzeitsringe</text> - <text locale="en">Wildente's wedding rings</text> - </string> - - <string name="jadee_dress"> - <text locale="de">Hochzeitskleid</text> - <text locale="en">wedding dress</text> - </string> - - <string name="jadee_dress_p"> - <text locale="de">Hochzeitskleider</text> - <text locale="en">wedding dresses</text> - </string> - - <string name="wente_dress"> - <text locale="de">Frack</text> - <text locale="en">tuxedo</text> - </string> - - <string name="wente_dress_p"> - <text locale="de">Fr�cke</text> - <text locale="en">tuxedos</text> - </string> - - <string name="ring"> - <text locale="de">Ring</text> - <text locale="en">ring</text> - </string> - - <string name="ring_p"> - <text locale="de">Ringe</text> - <text locale="en">rings</text> - </string> - <!-- ending here: Wildente and Jadee's wedding --> - - <!-- art rewards begin --> - <string name="hornofdancing"> - <text locale="de">Horn des Tanzes</text> - <text locale="en">horn of dancing</text> - </string> - <string name="hornofdancing_p"> - <text locale="de">H�rner des Tanzes</text> - <text locale="en">horns of dancing</text> - </string> - <string name="instantartacademy"> - <text locale="de">Miniatur einer Akademie der K�nste</text> - <text locale="en">academy of arts in a box</text> - </string> - <string name="instantartacademy_p"> - <text locale="de">Miniaturen einer Akademie der K�nste</text> - <text locale="en">academies of arts in a box</text> - </string> - <string name="instantartsculpture"> - <text locale="de">Miniatur einer Skulptur</text> - <text locale="en">art sculpture in a box</text> - </string> - <string name="instantartsculpture_p"> - <text locale="de">Miniaturen einer Skulptur</text> - <text locale="en">art sculptures in a box</text> - </string> - <string name="trappedairelemental"> - <text locale="de">Gefangener Windgeist</text> - <text locale="en">trapped air elemental</text> - </string> - <string name="trappedairelemental_p"> - <text locale="de">Gefangene Windgeister</text> - <text locale="en">trapped air elementals</text> - </string> - <string name="aurapotion50"> - <text locale="de">Auratrank</text> - <text locale="en">aura potion</text> - </string> - <string name="aurapotion50_p"> - <text locale="de">Auratr�nke</text> - <text locale="en">aura potions</text> - </string> - <string name="bagpipeoffear"> - <text locale="de">Dudelsack der Furcht</text> - <text locale="en">bagpipe of fear</text> - </string> - <string name="bagpipeoffear_p"> - <text locale="de">Dudels�cke der Furcht</text> - <text locale="en">bagpipes of fear</text> - </string> - <!-- art rewards end --> - - <!-- igjarjuk queste begin --> - <string name="ao_daemon"> - <text locale="de">Auge des D�mon</text> - <text locale="en">eye of the demon</text> - <text locale="fr">oeil du d�mon</text> - </string> - <string name="ao_daemon_p"> - <text locale="de">Augen des D�mon</text> - <text locale="en">eyes of the demon</text> - <text locale="fr">oeil du d�mon</text> - </string> - <string name="griphonwing"> - <text locale="de">Schwinge des Greifen</text> - <text locale="en">wing of the gryphon</text> - <text locale="fr">aile du griffon</text> - </string> - <string name="griphonwing_p"> - <text locale="de">Schwingen des Greifen</text> - <text locale="en">wings of the gryphon</text> - <text locale="fr">ailes du griffon</text> - </string> - <!-- igjarjuk queste end --> - - <string name="rm_adamantium"> - <text locale="de">Adamantium</text> - <text locale="en">adamantium</text> - </string> - <string name="adamantium"> - <text locale="de">Adamantium</text> - <text locale="en">adamantium</text> - </string> - <string name="adamantium_p"> - <text locale="de">Adamantium</text> - <text locale="en">adamantium</text> - </string> - - <string name="adamantiumaxe"> - <text locale="de">Adamantiumaxt</text> - <text locale="en">adamantium axe</text> - </string> - <string name="adamantiumaxe_p"> - <text locale="de">Adamantium�xte</text> - <text locale="en">adamantium axes</text> - </string> - - <string name="adamantiumplate"> - <text locale="de">Adamantiumr�stung</text> - <text locale="en">adamantium plate</text> - </string> - <string name="adamantiumplate_p"> - <text locale="de">Adamantiumr�stungen</text> - <text locale="en">adamantium plates</text> - </string> - -</strings> +<?xml version="1.0" encoding="iso-8859-1" ?> +<strings> + <namespace name="race"> + <string name="snowman"> + <text locale="de">Schneemann</text> + <text locale="en">snowman</text> + </string> + <string name="snowman_p"> + <text locale="de">Schneem�nner</text> + <text locale="en">snowmen</text> + </string> + </namespace> + <namespace name="shipinfo"> + <!-- ship info is not implemented! --> + <string name="no_info"> + <text locale="de">Keine Informationen �ber diesen Schiffstyp verf�gbar.</text> + <text locale="en">No Information available for this type of ship.</text> + </string> + <string name="balloon"> + <text locale="de">Der Sumpfgasballon besteht aus einem gro�en + Weidenkorb, welcher Platz + f�r maximal 5 Personen oder 500 Gewichtseinheiten bietet, und einer + gro�en, mit Sumpfgas gef�llten Wyrmblase. Bei guten Winden kann sich + der Ballon zwei Regionen pro Woche fortbewegen. Das F�hren eines + Ballons ist nicht einfach, und der Kapit�n muss mindestens ein + Segeltalent von 6 besitzen. Diese neue Entwicklung auf Eressea wird + ausschlie�lich f�r den Xontormia-Expre� hergestellt und die Baupl�ne + sind streng geheim. So ist es auch bisher noch niemandem gelungen, ein + Exemplar nachzubauen.</text> + </string> + </namespace> + <namespace name="iteminfo"> + <string name="ring_of_levitation"> + <text locale="de">Benutzt der Kapit�n des Schiffes diesen Talisman, so wird allen an Bord befindlichen Mallornsamen ihre magisch Energie entzogen, und das Schiff kann mit dieser Energie bis zu zwei Wochen lang fliegen.</text> + </string> + <string name="birthdaycake"> + <text locale="de">Eine Geburtstagstorte mit 10 Kerzen. Herzlichen Gl�ckwunsch, Eressea!</text> + <text locale="en">A birthday cake with 10 candles. Happy Birthday, Eressea!</text> + </string> + <string name="no_info"> + <text locale="de">Keine Informationen.</text> + <text locale="en">No Information available.</text> + </string> + <string name="griphonwing"> + <text locale="de">Dieses Flugger�t aus der Schmiede der Zwerge von Celeband galt wie die + 'Ebene der Herausforderung' seit Urzeiten als verschollen, ja man + zweifelte seine Existenz an. Die Sage �berliefert, das derjenige, der + sie auf der Spitze des Turmes seiner Gesinnung benutzt, als einziger + die 'Ebene der Herausforderungen' verlassen kann.</text> + </string> + <string name="ao_daemon"> + <text locale="de">Gl�ckwunsch, mein Kind. Du bist im Besitz des m�chtigsten + Artefaktes Eresseas. Ein Fluch, sagt man, liege auf ihm, denn + niemand hat es bisher lange sein Eigen genannt...</text> + </string> + <string name="cookie"> + <text locale="de">Kleines trockenes Dauergeb�ck, m od. s; - u. -es, - u. -e</text> + </string> + <string name="eyeofdragon"> + <text locale="de">So wisse denn, dass das Auge des Drachen den Weg zur Herausforderung + aufzeigt. Doch die �berlieferung sagt, das nur der Unschuldige und + Ungewappnete es benutzen kann. Sie sagt auch, da� er einen Beutel mit + einem Betrag von bis zu zweitausend Silber mit sich f�hren soll, + jedoch nicht mehr als einem F�nftel der St�rke seines Volkes + entsprechend - dem Torw�chter zum Geschenke als Beweis seiner + asketischen Gesinnung. Die 5 scheidet ganz aus.</text> + </string> + <string name="almond"> + <text locale="de">(Prunus dulcis) [...] Die N�sse existieren in zwei Varianten, s�� und + bitter. S��e Mandeln sind der bekannte e�bare Typ, der in Form von + N�ssen gegessen, beim Kochen verwandt oder zu Mandel�l und Mandelmehl + verarbeitet wird.</text> + </string> + <string name="apple"> + <text locale="en">A tasty fruit.</text> + <text locale="de">Frucht aus der Gattung Malus (ca. 25 Arten), geh�rt + zur Familie der + Rosengew�chse. Die am h�ufigsten kultivierte Baumfrucht. Der Apfel + geh�rt zu den fleischigen Fr�chten, in dem der gereifte Fruchtknoten + und + das umgebende Gewebe fleischig und e�bar werden. Die Apfelbl�te der + meisten Varianten erfordert Kreuzbest�ubung zur Befruchtung. Form und + Gr��e des Apfels bei der Ernte variieren abh�ngig von kulturellen und + umweltbedingten Einfl�ssen in Gr��e, Form, Farbe und Geschmack, sind + jedoch nichtsdestotrotz �blicherweise rund, zwischen 50 und 100mm im + Durchmesser und weisen r�t- oder gelbliche Farbt�ne auf.</text> + </string> + <string name="nut"> + <text locale="de">Nu�, im umgangssprachlichen Sinne alle trockenen, + hartschaligen + Fr�chte oder Samen, die eine Schale besitzen, die sich leicht + vom inneren, e�baren Kern entfernen l��t. In der botanischen + Terminologie beschr�nkt sich die Bezeichnung Nu� auf eine + einsamige Frucht, die aus einem Fruchtknoten (Ovarium) + entstanden ist, dessen �u�ere W�nde sich verholzt haben und der + sich nicht �ffnet, um seinen Samen zu entlassen. Solche echten + N�sse k�nnen e�bar, aber auch ungenie�bar sein. Bekannte + Beispiele sind Eicheln, Bucheckern, Kastanien und Haseln�sse. + Beispiele f�r Fr�chte oder Samen, die vom Volksmund f�lschlich + als N�sse bezeichnet werden, sind Mandeln und Waln�sse: Im + botanischen Sinne sind dies Steinfr�chte, denen die fleischige + �u�ere Schale entfernt wurde. Andere Beispiele f�r unechte + N�sse sind Erdn�sse - in H�lsen eingeschlossene Samen - sowie + Ro�kastanien und Paran�sse, bei denen es sich um von Kapseln + umh�llte Samen handelt.</text> + </string> + <string name="jadee_ring"> + <text locale="de">Zwerge schufen diesen wundersch�nen Ring aus Weissgold und Platin. Die + Oberfl�che ist so glatt, dass man nur bei genauem Hinsehen entdeckt, + dass hier eigentlich zwei Metalle ineinander verarbeitet worden sind. + In der Innenseite des Rings ist eine Gravur zu lesen: "Wildente, 3. + Woche Eiswind Jahr 8".</text> + </string> + <string name="jadee_dress"> + <text locale="de">Dieses Brautkleid ist mit Abstand das sch�nste, was je jemand + irgendwie irgendwo gesehen hat. Auch wenn nur Wildente und Jadee das + finden m�ssten, wird jeder Bewohner Eresseas dies neidlos best�tigen. + Das sehr stilvolle Kleid l�sst die zarten Schultern seiner Tr�gerin + frei und liegt am Oberk�rper eng an. Dies betont atemberaubend die + zarten Kurven der Braut. Der Rock f�llt leicht ausgestellt den ganzen + langen Weg an den Beinen herunter Richtung Boden, wo er sich in einer + sehr stilvollen Schleppe ergiesst.</text> + </string> + <string name="wente_ring"> + <text locale="de">Dieser Ring ist ein wahres Meisterwerk. Obwohl er sehr gross ist + (weil auch sein Tr�ger sehr gross ist), wirkt er filigran. Weissgold + und Platin verschmelzen in diesem Ring zu einer Einheit, die die + Sch�nheit der einzelnen Elemente nur noch unterstreich. In der + Innenseite des Rings ist eine Gravur zu lesen: 'Jadee, 3. Woche + Eiswind Jahr 8'.</text> + </string> + <string name="wente_dress"> + <text locale="de">Hach! Sieht der Mann beeindruckend aus in diesem Frack! Und so + ordentlich! Und so ernst! Und so beeindruckend! Es f�llt ein + wenig schwer, sich auf den Br�utigam zu konzentrieren, weil das + Brautkleid noch daneben strahlt, aber der Anzug des Br�utigams ist + auf jeden Fall so, wie er sein soll und sieht toll aus und sehr + geschmackvoll.</text> + </string> + <string name="snowman"> + <text locale="en">Orange nose, black hat, frosty character. A snowman. + He'll make a fine guard if you use him in a cold place. (USE 1 + snowman)</text> + <text locale="de">R�bennase, schwarzer Hut, kaltes Herz. Ein Schneemann. Er gibt + einen prima Wachmann ab, wenn er in einem Gletscher belebt wird + (BENUTZE 1 Schneemann).</text> + </string> + <string name="snowball"> + <text locale="en">These items stay frozen all year round. There seem to be bits of + ice in them - in the right hands, these might put an eye out!</text> + <text locale="de">Ein Schneeball. Es scheinen kleine Eissplitter darin zu sein. In + den richtigen H�nden k�nnen sie sicher weh tun.</text> + </string> + <string name="seashell"> + <text locale="en">This badge pronounces its wearer an official visitor to the + region of Muschelplateau.</text> + <text locale="de">Dieses Abzeichen identifiziert die Partei seines Tr�gers offiziell + als einen Besucher der Botschafterregion 'Muschelplateau'.</text> + </string> + <string name="xmastree"> + <text locale="de">Dieser wunderschoen geschmueckte Baum entfaltet in den Wintermonaten eine magische Wirkung auf den ganzen Wald.</text> + <text locale="en">In the winter months, this beautifully decorated tree has a magical effect on the entire forest.</text> + </string> + <string name="stardust"> + <text locale="de">Dieser magische Staub ist aus einem im Winter vom Himmel gefallenen + Stern gewonnen worden, und ihm werden aphrodisiakische Eigenschaften + nachgesagt.</text> + <text locale="en">This vial of dust, made from the remains of a star that fell from + the sky one cold winter night, is said to have aphrodisiacal powers.</text> + </string> + </namespace> + <string name="ring_of_levitation"> + <text locale="de">Ring der Levitation</text> + <text locale="en">ring of levitation</text> + </string> + <string name="ring_of_levitation_p"> + <text locale="de">Ringe der Levitation</text> + <text locale="en">rings of levitation</text> + </string> + <string name="birthdaycake"> + <text locale="de">Geburtstagstorte</text> + <text locale="en">birthday cake</text> + </string> + <string name="birthdaycake_p"> + <text locale="de">Geburtstagstorten</text> + <text locale="en">birthday cakes</text> + </string> + <string name="seashell"> + <text locale="de">Muschel</text> + <text locale="en">seashell</text> + </string> + <string name="seashell_p"> + <text locale="de">Muscheln</text> + <text locale="en">seashells</text> + </string> + + <string name="newbie_info_2"> + <text locale="de">Die ersten beiden Z�ge mu�t du abgeben, sonst wird deine + Partei sofort wieder gel�scht, um Karteileichen zu vermeiden.</text> + <text locale="en">If you fail to send in orders for one of the first two turns, your faction will be erased from the game to reduce the number of inactive players in Eressea.</text> + </string> + <string name="newbie_info_3"> + <text locale="de">Mit der ersten Auswertung bekommst du einen + Computerreport, den du mit vielen der Tools auf + http://eressea-pbem.de/download.html benutzen kannst. Wenn du ihn + weiterhin bekommen willst, gib einer deiner Einheiten den Befehl OPTION + COMPUTER.</text> + <text locale="en">With the first two turns, you will get a computer report (CR). It can be used with many of the tools on http://eressea-pbem.de/download.html. If you want to continue getting it after the second turn, please make one of your units give the order OPTION COMPUTER.</text> + </string> + <string name="defaultorder"> + <text locale="de">ARBEITEN</text> + <text locale="en">WORK</text> + </string> + <string name="temple"> + <text locale="de">Tempel</text> + <text locale="en">temple</text> + </string> + <string name="seaserpenthead"> + <text locale="de">Seeschlangenkopf</text> + </string> + <string name="seaserpenthead_p"> + <text locale="de">Seeschlangenk�pfe</text> + </string> + + <!-- starting here: Wildente and Jadee's wedding --> + <string name="pavilion"> + <text locale="de">Pavillion</text> + <text locale="en">pavilion</text> + </string> + + <string name="portal"> + <text locale="de">Portal</text> + <text locale="en">portal</text> + </string> + + <string name="jadee_ring"> + <text locale="de">Jadees Hochzeitsring</text> + <text locale="en">Jadee's wedding ring</text> + </string> + + <string name="jadee_ring_p"> + <text locale="de">Jadees Hochzeitsringe</text> + <text locale="en">Jadee's wedding rings</text> + </string> + + <string name="wente_ring"> + <text locale="de">Wildentes Hochzeitsring</text> + <text locale="en">Wildente's wedding ring</text> + </string> + + <string name="wente_ring_p"> + <text locale="de">Wildentes Hochzeitsringe</text> + <text locale="en">Wildente's wedding rings</text> + </string> + + <string name="jadee_dress"> + <text locale="de">Hochzeitskleid</text> + <text locale="en">wedding dress</text> + </string> + + <string name="jadee_dress_p"> + <text locale="de">Hochzeitskleider</text> + <text locale="en">wedding dresses</text> + </string> + + <string name="wente_dress"> + <text locale="de">Frack</text> + <text locale="en">tuxedo</text> + </string> + + <string name="wente_dress_p"> + <text locale="de">Fr�cke</text> + <text locale="en">tuxedos</text> + </string> + + <string name="ring"> + <text locale="de">Ring</text> + <text locale="en">ring</text> + </string> + + <string name="ring_p"> + <text locale="de">Ringe</text> + <text locale="en">rings</text> + </string> + <!-- ending here: Wildente and Jadee's wedding --> + + <!-- art rewards begin --> + <string name="hornofdancing"> + <text locale="de">Horn des Tanzes</text> + <text locale="en">horn of dancing</text> + </string> + <string name="hornofdancing_p"> + <text locale="de">H�rner des Tanzes</text> + <text locale="en">horns of dancing</text> + </string> + <string name="instantartacademy"> + <text locale="de">Miniatur einer Akademie der K�nste</text> + <text locale="en">academy of arts in a box</text> + </string> + <string name="instantartacademy_p"> + <text locale="de">Miniaturen einer Akademie der K�nste</text> + <text locale="en">academies of arts in a box</text> + </string> + <string name="instantartsculpture"> + <text locale="de">Miniatur einer Skulptur</text> + <text locale="en">art sculpture in a box</text> + </string> + <string name="instantartsculpture_p"> + <text locale="de">Miniaturen einer Skulptur</text> + <text locale="en">art sculptures in a box</text> + </string> + <string name="trappedairelemental"> + <text locale="de">Gefangener Windgeist</text> + <text locale="en">trapped air elemental</text> + </string> + <string name="trappedairelemental_p"> + <text locale="de">Gefangene Windgeister</text> + <text locale="en">trapped air elementals</text> + </string> + <string name="aurapotion50"> + <text locale="de">Auratrank</text> + <text locale="en">aura potion</text> + </string> + <string name="aurapotion50_p"> + <text locale="de">Auratr�nke</text> + <text locale="en">aura potions</text> + </string> + <string name="bagpipeoffear"> + <text locale="de">Dudelsack der Furcht</text> + <text locale="en">bagpipe of fear</text> + </string> + <string name="bagpipeoffear_p"> + <text locale="de">Dudels�cke der Furcht</text> + <text locale="en">bagpipes of fear</text> + </string> + <!-- art rewards end --> + + <!-- igjarjuk queste begin --> + <string name="ao_daemon"> + <text locale="de">Auge des D�mon</text> + <text locale="en">eye of the demon</text> + <text locale="fr">oeil du d�mon</text> + </string> + <string name="ao_daemon_p"> + <text locale="de">Augen des D�mon</text> + <text locale="en">eyes of the demon</text> + <text locale="fr">oeil du d�mon</text> + </string> + <string name="griphonwing"> + <text locale="de">Schwinge des Greifen</text> + <text locale="en">wing of the gryphon</text> + <text locale="fr">aile du griffon</text> + </string> + <string name="griphonwing_p"> + <text locale="de">Schwingen des Greifen</text> + <text locale="en">wings of the gryphon</text> + <text locale="fr">ailes du griffon</text> + </string> + <!-- igjarjuk queste end --> + + <string name="rm_adamantium"> + <text locale="de">Adamantium</text> + <text locale="en">adamantium</text> + </string> + <string name="adamantium"> + <text locale="de">Adamantium</text> + <text locale="en">adamantium</text> + </string> + <string name="adamantium_p"> + <text locale="de">Adamantium</text> + <text locale="en">adamantium</text> + </string> + + <string name="adamantiumaxe"> + <text locale="de">Adamantiumaxt</text> + <text locale="en">adamantium axe</text> + </string> + <string name="adamantiumaxe_p"> + <text locale="de">Adamantium�xte</text> + <text locale="en">adamantium axes</text> + </string> + + <string name="adamantiumplate"> + <text locale="de">Adamantiumr�stung</text> + <text locale="en">adamantium plate</text> + </string> + <string name="adamantiumplate_p"> + <text locale="de">Adamantiumr�stungen</text> + <text locale="en">adamantium plates</text> + </string> + +</strings> diff --git a/res/eressea/terrains.xml b/res/eressea/terrains.xml index 8b2ce7b1c..539d57246 100644 --- a/res/eressea/terrains.xml +++ b/res/eressea/terrains.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<terrains> - <!-- used by the experimental dungeon --> - <terrain name="hell" fly="no" sail="no" size="0" land="no"/> - - <!-- used for the museum only --> - <terrain name="hall1" fly="no" size="0" /> - <terrain name="corridor1" fly="no" size="0" /> - <terrain name="wall1" sail="no" walk="no" fly="no" forbidden="yes" size="0" /> -</terrains> +<?xml version="1.0" encoding="iso-8859-1" ?> +<terrains> + <!-- used by the experimental dungeon --> + <terrain name="hell" fly="no" sail="no" size="0" land="no"/> + + <!-- used for the museum only --> + <terrain name="hall1" fly="no" size="0" /> + <terrain name="corridor1" fly="no" size="0" /> + <terrain name="wall1" sail="no" walk="no" fly="no" forbidden="yes" size="0" /> +</terrains> diff --git a/res/names-dragons.xml b/res/names-dragons.xml index 1b0abf4c1..ef403863d 100644 --- a/res/names-dragons.xml +++ b/res/names-dragons.xml @@ -1,95 +1,95 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<strings> - - <string name="dragon_postfix_0"> - <text locale="de">der Weise</text> - </string> - <string name="dragon_postfix_1"> - <text locale="de">der Allwissende</text> - </string> - <string name="dragon_postfix_2"> - <text locale="de">der M�chtige</text> - </string> - <string name="dragon_postfix_3"> - <text locale="de">die Ehrw�rdige</text> - </string> - <string name="dragon_postfix_4"> - <text locale="de">die Listige</text> - </string> - <string name="dragon_postfix_5"> - <text locale="de">der Gr�ne</text> - </string> - <string name="dragon_postfix_6"> - <text locale="de">die Strafende</text> - </string> - <string name="dragon_postfix_7"> - <text locale="de">der Sehende</text> - </string> - <string name="dragon_postfix_8"> - <text locale="de">der Reisende</text> - </string> - <string name="dragon_postfix_9"> - <text locale="de">die Wissende</text> - </string> - <string name="dragon_postfix_10"> - <text locale="de">der Goldene</text> - </string> - <string name="dragon_postfix_11"> - <text locale="de">der Graue</text> - </string> - <string name="dragon_postfix_12"> - <text locale="de">der Steinerne</text> - </string> - <string name="dragon_postfix_13"> - <text locale="de">die Alte</text> - </string> - <string name="dragon_postfix_14"> - <text locale="de">die M�chtige</text> - </string> - <string name="dragon_postfix_15"> - <text locale="de">die Goldene</text> - </string> - <string name="dragon_postfix_16"> - <text locale="de">der Grausame</text> - </string> - <string name="dragon_postfix_17"> - <text locale="de">der Sanddrache</text> - </string> - <string name="dragon_postfix_18"> - <text locale="de">der Durstige</text> - </string> - <string name="dragon_postfix_19"> - <text locale="de">die Verzehrende</text> - </string> - <string name="dragon_postfix_20"> - <text locale="de">die Gr�ne</text> - </string> - <string name="dragon_postfix_21"> - <text locale="de">die Rote</text> - </string> - <string name="dragon_postfix_22"> - <text locale="de">der Furchtlose</text> - </string> - <string name="dragon_postfix_23"> - <text locale="de">der Allm�chtige</text> - </string> - <string name="dragon_postfix_24"> - <text locale="de">der Weitblickende</text> - </string> - <string name="dragon_postfix_25"> - <text locale="de">der Wei�e</text> - </string> - <string name="dragon_postfix_26"> - <text locale="de">die Gl�nzende</text> - </string> - <string name="dragon_postfix_27"> - <text locale="de">der Wissende</text> - </string> - <string name="dragon_postfix_28"> - <text locale="de">die Unbarmherzige</text> - </string> - <string name="dragon_postfix_29"> - <text locale="de">die Sch�ne</text> - </string> - -</strings> +<?xml version="1.0" encoding="iso-8859-1" ?> +<strings> + + <string name="dragon_postfix_0"> + <text locale="de">der Weise</text> + </string> + <string name="dragon_postfix_1"> + <text locale="de">der Allwissende</text> + </string> + <string name="dragon_postfix_2"> + <text locale="de">der M�chtige</text> + </string> + <string name="dragon_postfix_3"> + <text locale="de">die Ehrw�rdige</text> + </string> + <string name="dragon_postfix_4"> + <text locale="de">die Listige</text> + </string> + <string name="dragon_postfix_5"> + <text locale="de">der Gr�ne</text> + </string> + <string name="dragon_postfix_6"> + <text locale="de">die Strafende</text> + </string> + <string name="dragon_postfix_7"> + <text locale="de">der Sehende</text> + </string> + <string name="dragon_postfix_8"> + <text locale="de">der Reisende</text> + </string> + <string name="dragon_postfix_9"> + <text locale="de">die Wissende</text> + </string> + <string name="dragon_postfix_10"> + <text locale="de">der Goldene</text> + </string> + <string name="dragon_postfix_11"> + <text locale="de">der Graue</text> + </string> + <string name="dragon_postfix_12"> + <text locale="de">der Steinerne</text> + </string> + <string name="dragon_postfix_13"> + <text locale="de">die Alte</text> + </string> + <string name="dragon_postfix_14"> + <text locale="de">die M�chtige</text> + </string> + <string name="dragon_postfix_15"> + <text locale="de">die Goldene</text> + </string> + <string name="dragon_postfix_16"> + <text locale="de">der Grausame</text> + </string> + <string name="dragon_postfix_17"> + <text locale="de">der Sanddrache</text> + </string> + <string name="dragon_postfix_18"> + <text locale="de">der Durstige</text> + </string> + <string name="dragon_postfix_19"> + <text locale="de">die Verzehrende</text> + </string> + <string name="dragon_postfix_20"> + <text locale="de">die Gr�ne</text> + </string> + <string name="dragon_postfix_21"> + <text locale="de">die Rote</text> + </string> + <string name="dragon_postfix_22"> + <text locale="de">der Furchtlose</text> + </string> + <string name="dragon_postfix_23"> + <text locale="de">der Allm�chtige</text> + </string> + <string name="dragon_postfix_24"> + <text locale="de">der Weitblickende</text> + </string> + <string name="dragon_postfix_25"> + <text locale="de">der Wei�e</text> + </string> + <string name="dragon_postfix_26"> + <text locale="de">die Gl�nzende</text> + </string> + <string name="dragon_postfix_27"> + <text locale="de">der Wissende</text> + </string> + <string name="dragon_postfix_28"> + <text locale="de">die Unbarmherzige</text> + </string> + <string name="dragon_postfix_29"> + <text locale="de">die Sch�ne</text> + </string> + +</strings> diff --git a/res/names-ghouls.xml b/res/names-ghouls.xml index 474156c55..64d17ff1e 100644 --- a/res/names-ghouls.xml +++ b/res/names-ghouls.xml @@ -1,115 +1,115 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<strings> - - <string name="ghoul_prefix_0"> - <text locale="de">Faulende</text> - </string> - <string name="ghoul_prefix_1"> - <text locale="de">Angsteinfl��ende</text> - </string> - <string name="ghoul_prefix_2"> - <text locale="de">Leise</text> - </string> - <string name="ghoul_prefix_3"> - <text locale="de">Kinderfressende</text> - </string> - <string name="ghoul_prefix_4"> - <text locale="de">Menschenfressende</text> - </string> - <string name="ghoul_prefix_5"> - <text locale="de">Wahnsinnige</text> - </string> - <string name="ghoul_prefix_6"> - <text locale="de">Brutale</text> - </string> - <string name="ghoul_prefix_7"> - <text locale="de">Schwarze</text> - </string> - <string name="ghoul_prefix_8"> - <text locale="de">Dunkle</text> - </string> - <string name="ghoul_prefix_9"> - <text locale="de">F�rchterliche</text> - </string> - <string name="ghoul_prefix_10"> - <text locale="de">Grauenhafte</text> - </string> - <string name="ghoul_prefix_11"> - <text locale="de">Furchtbare</text> - </string> - <string name="ghoul_prefix_12"> - <text locale="de">Entsetzliche</text> - </string> - <string name="ghoul_prefix_13"> - <text locale="de">Schauderhafte</text> - </string> - <string name="ghoul_prefix_14"> - <text locale="de">Schreckliche</text> - </string> - <string name="ghoul_prefix_15"> - <text locale="de">D�stere</text> - </string> - <string name="ghoul_prefix_16"> - <text locale="de">Schaurige</text> - </string> - - <string name="ghoul_name_0"> - <text locale="de">Ghoule</text> - </string> - <string name="ghoul_name_1"> - <text locale="de">Kreaturen</text> - </string> - <string name="ghoul_name_2"> - <text locale="de">Verlorene</text> - </string> - <string name="ghoul_name_3"> - <text locale="de">Erschlagene</text> - </string> - <string name="ghoul_name_4"> - <text locale="de">Verdammte</text> - </string> - <string name="ghoul_name_5"> - <text locale="de">Schlurfende Ghoule</text> - </string> - - <string name="ghoul_postfix_0"> - <text locale="de">der Nacht</text> - </string> - <string name="ghoul_postfix_1"> - <text locale="de">der Schatten</text> - </string> - <string name="ghoul_postfix_2"> - <text locale="de">der Finsternis</text> - </string> - <string name="ghoul_postfix_3"> - <text locale="de">des B�sen</text> - </string> - <string name="ghoul_postfix_4"> - <text locale="de">der Erschlagenen</text> - </string> - <string name="ghoul_postfix_5"> - <text locale="de">der Verfluchten</text> - </string> - <string name="ghoul_postfix_6"> - <text locale="de">der Ruhelosen</text> - </string> - <string name="ghoul_postfix_7"> - <text locale="de">aus dem Nebel</text> - </string> - <string name="ghoul_postfix_8"> - <text locale="de">aus dem Dunkel</text> - </string> - <string name="ghoul_postfix_9"> - <text locale="de">der Tiefe</text> - </string> - <string name="ghoul_postfix_10"> - <text locale="de">in Ketten</text> - </string> - <string name="ghoul_postfix_11"> - <text locale="de">aus dem Totenreich</text> - </string> - <string name="ghoul_postfix_12"> - <text locale="de">aus der Unterwelt</text> - </string> - -</strings> +<?xml version="1.0" encoding="iso-8859-1" ?> +<strings> + + <string name="ghoul_prefix_0"> + <text locale="de">Faulende</text> + </string> + <string name="ghoul_prefix_1"> + <text locale="de">Angsteinfl��ende</text> + </string> + <string name="ghoul_prefix_2"> + <text locale="de">Leise</text> + </string> + <string name="ghoul_prefix_3"> + <text locale="de">Kinderfressende</text> + </string> + <string name="ghoul_prefix_4"> + <text locale="de">Menschenfressende</text> + </string> + <string name="ghoul_prefix_5"> + <text locale="de">Wahnsinnige</text> + </string> + <string name="ghoul_prefix_6"> + <text locale="de">Brutale</text> + </string> + <string name="ghoul_prefix_7"> + <text locale="de">Schwarze</text> + </string> + <string name="ghoul_prefix_8"> + <text locale="de">Dunkle</text> + </string> + <string name="ghoul_prefix_9"> + <text locale="de">F�rchterliche</text> + </string> + <string name="ghoul_prefix_10"> + <text locale="de">Grauenhafte</text> + </string> + <string name="ghoul_prefix_11"> + <text locale="de">Furchtbare</text> + </string> + <string name="ghoul_prefix_12"> + <text locale="de">Entsetzliche</text> + </string> + <string name="ghoul_prefix_13"> + <text locale="de">Schauderhafte</text> + </string> + <string name="ghoul_prefix_14"> + <text locale="de">Schreckliche</text> + </string> + <string name="ghoul_prefix_15"> + <text locale="de">D�stere</text> + </string> + <string name="ghoul_prefix_16"> + <text locale="de">Schaurige</text> + </string> + + <string name="ghoul_name_0"> + <text locale="de">Ghoule</text> + </string> + <string name="ghoul_name_1"> + <text locale="de">Kreaturen</text> + </string> + <string name="ghoul_name_2"> + <text locale="de">Verlorene</text> + </string> + <string name="ghoul_name_3"> + <text locale="de">Erschlagene</text> + </string> + <string name="ghoul_name_4"> + <text locale="de">Verdammte</text> + </string> + <string name="ghoul_name_5"> + <text locale="de">Schlurfende Ghoule</text> + </string> + + <string name="ghoul_postfix_0"> + <text locale="de">der Nacht</text> + </string> + <string name="ghoul_postfix_1"> + <text locale="de">der Schatten</text> + </string> + <string name="ghoul_postfix_2"> + <text locale="de">der Finsternis</text> + </string> + <string name="ghoul_postfix_3"> + <text locale="de">des B�sen</text> + </string> + <string name="ghoul_postfix_4"> + <text locale="de">der Erschlagenen</text> + </string> + <string name="ghoul_postfix_5"> + <text locale="de">der Verfluchten</text> + </string> + <string name="ghoul_postfix_6"> + <text locale="de">der Ruhelosen</text> + </string> + <string name="ghoul_postfix_7"> + <text locale="de">aus dem Nebel</text> + </string> + <string name="ghoul_postfix_8"> + <text locale="de">aus dem Dunkel</text> + </string> + <string name="ghoul_postfix_9"> + <text locale="de">der Tiefe</text> + </string> + <string name="ghoul_postfix_10"> + <text locale="de">in Ketten</text> + </string> + <string name="ghoul_postfix_11"> + <text locale="de">aus dem Totenreich</text> + </string> + <string name="ghoul_postfix_12"> + <text locale="de">aus der Unterwelt</text> + </string> + +</strings> diff --git a/res/names-skeletons.xml b/res/names-skeletons.xml index 47554d6ae..475a94d97 100644 --- a/res/names-skeletons.xml +++ b/res/names-skeletons.xml @@ -1,121 +1,121 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<strings> - - <string name="skeleton_prefix_0"> - <text locale="de">Klapperige</text> - </string> - <string name="skeleton_prefix_1"> - <text locale="de">St�hnende</text> - </string> - <string name="skeleton_prefix_2"> - <text locale="de">Schwarzknochige</text> - </string> - <string name="skeleton_prefix_3"> - <text locale="de">Schwarzgewandete</text> - </string> - <string name="skeleton_prefix_4"> - <text locale="de">Angsteinfl��ende</text> - </string> - <string name="skeleton_prefix_5"> - <text locale="de">Heulende</text> - </string> - <string name="skeleton_prefix_6"> - <text locale="de">Wartende</text> - </string> - <string name="skeleton_prefix_7"> - <text locale="de">Grauenvolle</text> - </string> - <string name="skeleton_prefix_8"> - <text locale="de">Schwarze</text> - </string> - <string name="skeleton_prefix_9"> - <text locale="de">Dunkle</text> - </string> - <string name="skeleton_prefix_10"> - <text locale="de">F�rchterliche</text> - </string> - <string name="skeleton_prefix_11"> - <text locale="de">Grauenhafte</text> - </string> - <string name="skeleton_prefix_12"> - <text locale="de">Furchtbare</text> - </string> - <string name="skeleton_prefix_13"> - <text locale="de">Entsetzliche</text> - </string> - <string name="skeleton_prefix_14"> - <text locale="de">Schauderhafte</text> - </string> - <string name="skeleton_prefix_15"> - <text locale="de">Schreckliche</text> - </string> - <string name="skeleton_prefix_16"> - <text locale="de">D�stere</text> - </string> - <string name="skeleton_prefix_17"> - <text locale="de">Schaurige</text> - </string> - <string name="skeleton_prefix_18"> - <text locale="de">Erbarmungslose</text> - </string> - - <string name="skeleton_name_0"> - <text locale="de">Skelette</text> - </string> - <string name="skeleton_name_1"> - <text locale="de">Kreaturen</text> - </string> - <string name="skeleton_name_2"> - <text locale="de">Krieger</text> - </string> - <string name="skeleton_name_3"> - <text locale="de">K�mpfer</text> - </string> - <string name="skeleton_name_4"> - <text locale="de">R�cher</text> - </string> - - <string name="skeleton_postfix_0"> - <text locale="de">der Nacht</text> - </string> - <string name="skeleton_postfix_1"> - <text locale="de">der Schatten</text> - </string> - <string name="skeleton_postfix_2"> - <text locale="de">der Finsternis</text> - </string> - <string name="skeleton_postfix_3"> - <text locale="de">des B�sen</text> - </string> - <string name="skeleton_postfix_4"> - <text locale="de">der Erschlagenen</text> - </string> - <string name="skeleton_postfix_5"> - <text locale="de">der Verfluchten</text> - </string> - <string name="skeleton_postfix_6"> - <text locale="de">der Gefolterten</text> - </string> - <string name="skeleton_postfix_7"> - <text locale="de">der Ruhelosen</text> - </string> - <string name="skeleton_postfix_8"> - <text locale="de">aus dem Nebel</text> - </string> - <string name="skeleton_postfix_9"> - <text locale="de">aus dem Dunkel</text> - </string> - <string name="skeleton_postfix_10"> - <text locale="de">der Tiefe</text> - </string> - <string name="skeleton_postfix_11"> - <text locale="de">in Ketten</text> - </string> - <string name="skeleton_postfix_12"> - <text locale="de">aus dem Totenreich</text> - </string> - <string name="skeleton_postfix_13"> - <text locale="de">aus der Unterwelt</text> - </string> - -</strings> +<?xml version="1.0" encoding="iso-8859-1" ?> +<strings> + + <string name="skeleton_prefix_0"> + <text locale="de">Klapperige</text> + </string> + <string name="skeleton_prefix_1"> + <text locale="de">St�hnende</text> + </string> + <string name="skeleton_prefix_2"> + <text locale="de">Schwarzknochige</text> + </string> + <string name="skeleton_prefix_3"> + <text locale="de">Schwarzgewandete</text> + </string> + <string name="skeleton_prefix_4"> + <text locale="de">Angsteinfl��ende</text> + </string> + <string name="skeleton_prefix_5"> + <text locale="de">Heulende</text> + </string> + <string name="skeleton_prefix_6"> + <text locale="de">Wartende</text> + </string> + <string name="skeleton_prefix_7"> + <text locale="de">Grauenvolle</text> + </string> + <string name="skeleton_prefix_8"> + <text locale="de">Schwarze</text> + </string> + <string name="skeleton_prefix_9"> + <text locale="de">Dunkle</text> + </string> + <string name="skeleton_prefix_10"> + <text locale="de">F�rchterliche</text> + </string> + <string name="skeleton_prefix_11"> + <text locale="de">Grauenhafte</text> + </string> + <string name="skeleton_prefix_12"> + <text locale="de">Furchtbare</text> + </string> + <string name="skeleton_prefix_13"> + <text locale="de">Entsetzliche</text> + </string> + <string name="skeleton_prefix_14"> + <text locale="de">Schauderhafte</text> + </string> + <string name="skeleton_prefix_15"> + <text locale="de">Schreckliche</text> + </string> + <string name="skeleton_prefix_16"> + <text locale="de">D�stere</text> + </string> + <string name="skeleton_prefix_17"> + <text locale="de">Schaurige</text> + </string> + <string name="skeleton_prefix_18"> + <text locale="de">Erbarmungslose</text> + </string> + + <string name="skeleton_name_0"> + <text locale="de">Skelette</text> + </string> + <string name="skeleton_name_1"> + <text locale="de">Kreaturen</text> + </string> + <string name="skeleton_name_2"> + <text locale="de">Krieger</text> + </string> + <string name="skeleton_name_3"> + <text locale="de">K�mpfer</text> + </string> + <string name="skeleton_name_4"> + <text locale="de">R�cher</text> + </string> + + <string name="skeleton_postfix_0"> + <text locale="de">der Nacht</text> + </string> + <string name="skeleton_postfix_1"> + <text locale="de">der Schatten</text> + </string> + <string name="skeleton_postfix_2"> + <text locale="de">der Finsternis</text> + </string> + <string name="skeleton_postfix_3"> + <text locale="de">des B�sen</text> + </string> + <string name="skeleton_postfix_4"> + <text locale="de">der Erschlagenen</text> + </string> + <string name="skeleton_postfix_5"> + <text locale="de">der Verfluchten</text> + </string> + <string name="skeleton_postfix_6"> + <text locale="de">der Gefolterten</text> + </string> + <string name="skeleton_postfix_7"> + <text locale="de">der Ruhelosen</text> + </string> + <string name="skeleton_postfix_8"> + <text locale="de">aus dem Nebel</text> + </string> + <string name="skeleton_postfix_9"> + <text locale="de">aus dem Dunkel</text> + </string> + <string name="skeleton_postfix_10"> + <text locale="de">der Tiefe</text> + </string> + <string name="skeleton_postfix_11"> + <text locale="de">in Ketten</text> + </string> + <string name="skeleton_postfix_12"> + <text locale="de">aus dem Totenreich</text> + </string> + <string name="skeleton_postfix_13"> + <text locale="de">aus der Unterwelt</text> + </string> + +</strings> diff --git a/res/names-undead.xml b/res/names-undead.xml index 4623b9710..5bc93da08 100644 --- a/res/names-undead.xml +++ b/res/names-undead.xml @@ -1,156 +1,156 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<strings> - <string name="undead_prefix_0"> - <text locale="de">Grausige</text> - </string> - <string name="undead_prefix_1"> - <text locale="de">St�hnende</text> - </string> - <string name="undead_prefix_2"> - <text locale="de">Schlurfende</text> - </string> - <string name="undead_prefix_3"> - <text locale="de">Schwarzgewandete</text> - </string> - <string name="undead_prefix_4"> - <text locale="de">Faulende</text> - </string> - <string name="undead_prefix_5"> - <text locale="de">Angsteinfl��ende</text> - </string> - <string name="undead_prefix_6"> - <text locale="de">Heulende</text> - </string> - <string name="undead_prefix_7"> - <text locale="de">Wartende</text> - </string> - <string name="undead_prefix_8"> - <text locale="de">Grauenvolle</text> - </string> - <string name="undead_prefix_9"> - <text locale="de">Schwarze</text> - </string> - <string name="undead_prefix_10"> - <text locale="de">Dunkle</text> - </string> - <string name="undead_prefix_11"> - <text locale="de">F�rchterliche</text> - </string> - <string name="undead_prefix_12"> - <text locale="de">Grauenhafte</text> - </string> - <string name="undead_prefix_13"> - <text locale="de">Furchtbare</text> - </string> - <string name="undead_prefix_14"> - <text locale="de">Entsetzliche</text> - </string> - <string name="undead_prefix_15"> - <text locale="de">Schauderhafte</text> - </string> - <string name="undead_prefix_16"> - <text locale="de">Schreckliche</text> - </string> - <string name="undead_prefix_17"> - <text locale="de">Gespenstische</text> - </string> - <string name="undead_prefix_18"> - <text locale="de">Ekelhafte</text> - </string> - <string name="undead_prefix_19"> - <text locale="de">D�stere</text> - </string> - <string name="undead_prefix_20"> - <text locale="de">Schaurige</text> - </string> - <string name="undead_prefix_21"> - <text locale="de">Erbarmungslose</text> - </string> - <string name="undead_prefix_22"> - <text locale="de">Hungrige</text> - </string> - - <string name="undead_name_0"> - <text locale="de">Geister</text> - </string> - <string name="undead_name_1"> - <text locale="de">Phantome</text> - </string> - <string name="undead_name_2"> - <text locale="de">Vampire</text> - </string> - <string name="undead_name_3"> - <text locale="de">Zombies</text> - </string> - <string name="undead_name_4"> - <text locale="de">Gespenster</text> - </string> - <string name="undead_name_5"> - <text locale="de">Kreaturen</text> - </string> - <string name="undead_name_6"> - <text locale="de">Gestalten</text> - </string> - <string name="undead_name_7"> - <text locale="de">Schemen</text> - </string> - <string name="undead_name_8"> - <text locale="de">Monster</text> - </string> - <string name="undead_name_9"> - <text locale="de">Krieger</text> - </string> - <string name="undead_name_10"> - <text locale="de">Ghule</text> - </string> - <string name="undead_name_11"> - <text locale="de">Kopflose</text> - </string> - <string name="undead_name_12"> - <text locale="de">Irrlichter</text> - </string> - - <string name="undead_postfix_0"> - <text locale="de">der Nacht</text> - </string> - <string name="undead_postfix_1"> - <text locale="de">der Schatten</text> - </string> - <string name="undead_postfix_2"> - <text locale="de">der Finsternis</text> - </string> - <string name="undead_postfix_3"> - <text locale="de">des B�sen</text> - </string> - <string name="undead_postfix_4"> - <text locale="de">der Erschlagenen</text> - </string> - <string name="undead_postfix_5"> - <text locale="de">der Verfluchten</text> - </string> - <string name="undead_postfix_6"> - <text locale="de">der Gefolterten</text> - </string> - <string name="undead_postfix_7"> - <text locale="de">der Ruhelosen</text> - </string> - <string name="undead_postfix_8"> - <text locale="de">aus dem Nebel</text> - </string> - <string name="undead_postfix_9"> - <text locale="de">aus dem Dunkel</text> - </string> - <string name="undead_postfix_10"> - <text locale="de">der Tiefe</text> - </string> - <string name="undead_postfix_11"> - <text locale="de">in Ketten</text> - </string> - <string name="undead_postfix_12"> - <text locale="de">aus dem Totenreich</text> - </string> - <string name="undead_postfix_13"> - <text locale="de">aus der Unterwelt</text> - </string> - -</strings> +<?xml version="1.0" encoding="iso-8859-1" ?> +<strings> + <string name="undead_prefix_0"> + <text locale="de">Grausige</text> + </string> + <string name="undead_prefix_1"> + <text locale="de">St�hnende</text> + </string> + <string name="undead_prefix_2"> + <text locale="de">Schlurfende</text> + </string> + <string name="undead_prefix_3"> + <text locale="de">Schwarzgewandete</text> + </string> + <string name="undead_prefix_4"> + <text locale="de">Faulende</text> + </string> + <string name="undead_prefix_5"> + <text locale="de">Angsteinfl��ende</text> + </string> + <string name="undead_prefix_6"> + <text locale="de">Heulende</text> + </string> + <string name="undead_prefix_7"> + <text locale="de">Wartende</text> + </string> + <string name="undead_prefix_8"> + <text locale="de">Grauenvolle</text> + </string> + <string name="undead_prefix_9"> + <text locale="de">Schwarze</text> + </string> + <string name="undead_prefix_10"> + <text locale="de">Dunkle</text> + </string> + <string name="undead_prefix_11"> + <text locale="de">F�rchterliche</text> + </string> + <string name="undead_prefix_12"> + <text locale="de">Grauenhafte</text> + </string> + <string name="undead_prefix_13"> + <text locale="de">Furchtbare</text> + </string> + <string name="undead_prefix_14"> + <text locale="de">Entsetzliche</text> + </string> + <string name="undead_prefix_15"> + <text locale="de">Schauderhafte</text> + </string> + <string name="undead_prefix_16"> + <text locale="de">Schreckliche</text> + </string> + <string name="undead_prefix_17"> + <text locale="de">Gespenstische</text> + </string> + <string name="undead_prefix_18"> + <text locale="de">Ekelhafte</text> + </string> + <string name="undead_prefix_19"> + <text locale="de">D�stere</text> + </string> + <string name="undead_prefix_20"> + <text locale="de">Schaurige</text> + </string> + <string name="undead_prefix_21"> + <text locale="de">Erbarmungslose</text> + </string> + <string name="undead_prefix_22"> + <text locale="de">Hungrige</text> + </string> + + <string name="undead_name_0"> + <text locale="de">Geister</text> + </string> + <string name="undead_name_1"> + <text locale="de">Phantome</text> + </string> + <string name="undead_name_2"> + <text locale="de">Vampire</text> + </string> + <string name="undead_name_3"> + <text locale="de">Zombies</text> + </string> + <string name="undead_name_4"> + <text locale="de">Gespenster</text> + </string> + <string name="undead_name_5"> + <text locale="de">Kreaturen</text> + </string> + <string name="undead_name_6"> + <text locale="de">Gestalten</text> + </string> + <string name="undead_name_7"> + <text locale="de">Schemen</text> + </string> + <string name="undead_name_8"> + <text locale="de">Monster</text> + </string> + <string name="undead_name_9"> + <text locale="de">Krieger</text> + </string> + <string name="undead_name_10"> + <text locale="de">Ghule</text> + </string> + <string name="undead_name_11"> + <text locale="de">Kopflose</text> + </string> + <string name="undead_name_12"> + <text locale="de">Irrlichter</text> + </string> + + <string name="undead_postfix_0"> + <text locale="de">der Nacht</text> + </string> + <string name="undead_postfix_1"> + <text locale="de">der Schatten</text> + </string> + <string name="undead_postfix_2"> + <text locale="de">der Finsternis</text> + </string> + <string name="undead_postfix_3"> + <text locale="de">des B�sen</text> + </string> + <string name="undead_postfix_4"> + <text locale="de">der Erschlagenen</text> + </string> + <string name="undead_postfix_5"> + <text locale="de">der Verfluchten</text> + </string> + <string name="undead_postfix_6"> + <text locale="de">der Gefolterten</text> + </string> + <string name="undead_postfix_7"> + <text locale="de">der Ruhelosen</text> + </string> + <string name="undead_postfix_8"> + <text locale="de">aus dem Nebel</text> + </string> + <string name="undead_postfix_9"> + <text locale="de">aus dem Dunkel</text> + </string> + <string name="undead_postfix_10"> + <text locale="de">der Tiefe</text> + </string> + <string name="undead_postfix_11"> + <text locale="de">in Ketten</text> + </string> + <string name="undead_postfix_12"> + <text locale="de">aus dem Totenreich</text> + </string> + <string name="undead_postfix_13"> + <text locale="de">aus der Unterwelt</text> + </string> + +</strings> diff --git a/res/names-zombies.xml b/res/names-zombies.xml index d494b9380..3d34affe1 100644 --- a/res/names-zombies.xml +++ b/res/names-zombies.xml @@ -1,108 +1,108 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<strings> - <string name="zombie_prefix_0"> - <text locale="de">Faulende</text> - </string> - <string name="zombie_prefix_1"> - <text locale="de">Zerschlagene</text> - </string> - <string name="zombie_prefix_2"> - <text locale="de">Gefolterte</text> - </string> - <string name="zombie_prefix_3"> - <text locale="de">Angsteinfl��ende</text> - </string> - <string name="zombie_prefix_4"> - <text locale="de">Leise Schlurfende</text> - </string> - <string name="zombie_prefix_5"> - <text locale="de">Kinderfressende</text> - </string> - <string name="zombie_prefix_6"> - <text locale="de">Schwarze</text> - </string> - <string name="zombie_prefix_7"> - <text locale="de">Dunkle</text> - </string> - <string name="zombie_prefix_8"> - <text locale="de">F�rchterliche</text> - </string> - <string name="zombie_prefix_9"> - <text locale="de">Grauenhafte</text> - </string> - <string name="zombie_prefix_10"> - <text locale="de">Furchtbare</text> - </string> - <string name="zombie_prefix_11"> - <text locale="de">Entsetzliche</text> - </string> - <string name="zombie_prefix_12"> - <text locale="de">Schauderhafte</text> - </string> - <string name="zombie_prefix_13"> - <text locale="de">Schreckliche</text> - </string> - <string name="zombie_prefix_14"> - <text locale="de">D�stere</text> - </string> - <string name="zombie_prefix_15"> - <text locale="de">Schaurige</text> - </string> - - <string name="zombie_name_0"> - <text locale="de">Zombies</text> - </string> - <string name="zombie_name_1"> - <text locale="de">Kreaturen</text> - </string> - <string name="zombie_name_2"> - <text locale="de">Verlorene</text> - </string> - <string name="zombie_name_3"> - <text locale="de">Erschlagene</text> - </string> - <string name="zombie_name_4"> - <text locale="de">Verdammte</text> - </string> - - <string name="zombie_postfix_0"> - <text locale="de">der Nacht</text> - </string> - <string name="zombie_postfix_1"> - <text locale="de">der Schatten</text> - </string> - <string name="zombie_postfix_2"> - <text locale="de">der Finsternis</text> - </string> - <string name="zombie_postfix_3"> - <text locale="de">des B�sen</text> - </string> - <string name="zombie_postfix_4"> - <text locale="de">der Erschlagenen</text> - </string> - <string name="zombie_postfix_5"> - <text locale="de">der Verfluchten</text> - </string> - <string name="zombie_postfix_6"> - <text locale="de">der Ruhelosen</text> - </string> - <string name="zombie_postfix_7"> - <text locale="de">aus dem Nebel</text> - </string> - <string name="zombie_postfix_8"> - <text locale="de">aus dem Dunkel</text> - </string> - <string name="zombie_postfix_9"> - <text locale="de">der Tiefe</text> - </string> - <string name="zombie_postfix_10"> - <text locale="de">in Ketten</text> - </string> - <string name="zombie_postfix_11"> - <text locale="de">aus dem Totenreich</text> - </string> - <string name="zombie_postfix_12"> - <text locale="de">aus der Unterwelt</text> - </string> - -</strings> +<?xml version="1.0" encoding="iso-8859-1" ?> +<strings> + <string name="zombie_prefix_0"> + <text locale="de">Faulende</text> + </string> + <string name="zombie_prefix_1"> + <text locale="de">Zerschlagene</text> + </string> + <string name="zombie_prefix_2"> + <text locale="de">Gefolterte</text> + </string> + <string name="zombie_prefix_3"> + <text locale="de">Angsteinfl��ende</text> + </string> + <string name="zombie_prefix_4"> + <text locale="de">Leise Schlurfende</text> + </string> + <string name="zombie_prefix_5"> + <text locale="de">Kinderfressende</text> + </string> + <string name="zombie_prefix_6"> + <text locale="de">Schwarze</text> + </string> + <string name="zombie_prefix_7"> + <text locale="de">Dunkle</text> + </string> + <string name="zombie_prefix_8"> + <text locale="de">F�rchterliche</text> + </string> + <string name="zombie_prefix_9"> + <text locale="de">Grauenhafte</text> + </string> + <string name="zombie_prefix_10"> + <text locale="de">Furchtbare</text> + </string> + <string name="zombie_prefix_11"> + <text locale="de">Entsetzliche</text> + </string> + <string name="zombie_prefix_12"> + <text locale="de">Schauderhafte</text> + </string> + <string name="zombie_prefix_13"> + <text locale="de">Schreckliche</text> + </string> + <string name="zombie_prefix_14"> + <text locale="de">D�stere</text> + </string> + <string name="zombie_prefix_15"> + <text locale="de">Schaurige</text> + </string> + + <string name="zombie_name_0"> + <text locale="de">Zombies</text> + </string> + <string name="zombie_name_1"> + <text locale="de">Kreaturen</text> + </string> + <string name="zombie_name_2"> + <text locale="de">Verlorene</text> + </string> + <string name="zombie_name_3"> + <text locale="de">Erschlagene</text> + </string> + <string name="zombie_name_4"> + <text locale="de">Verdammte</text> + </string> + + <string name="zombie_postfix_0"> + <text locale="de">der Nacht</text> + </string> + <string name="zombie_postfix_1"> + <text locale="de">der Schatten</text> + </string> + <string name="zombie_postfix_2"> + <text locale="de">der Finsternis</text> + </string> + <string name="zombie_postfix_3"> + <text locale="de">des B�sen</text> + </string> + <string name="zombie_postfix_4"> + <text locale="de">der Erschlagenen</text> + </string> + <string name="zombie_postfix_5"> + <text locale="de">der Verfluchten</text> + </string> + <string name="zombie_postfix_6"> + <text locale="de">der Ruhelosen</text> + </string> + <string name="zombie_postfix_7"> + <text locale="de">aus dem Nebel</text> + </string> + <string name="zombie_postfix_8"> + <text locale="de">aus dem Dunkel</text> + </string> + <string name="zombie_postfix_9"> + <text locale="de">der Tiefe</text> + </string> + <string name="zombie_postfix_10"> + <text locale="de">in Ketten</text> + </string> + <string name="zombie_postfix_11"> + <text locale="de">aus dem Totenreich</text> + </string> + <string name="zombie_postfix_12"> + <text locale="de">aus der Unterwelt</text> + </string> + +</strings> diff --git a/res/races/dragon.xml b/res/races/dragon.xml index 1e508db89..6bbbb5e4b 100644 --- a/res/races/dragon.xml +++ b/res/races/dragon.xml @@ -1,14 +1,14 @@ -<race name="dragon" magres="0.700000" maxaura="1.0" regaura="2.000000" weight="10000" capacity="1000000" speed="1.500000" hp="900" ac= -"6" damage="2d30" unarmedattack="0" unarmeddefense="0" attackmodifier="7" defensemodifier="7" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" giveitem="yes" resistbash="yes"> - <ai splitsize="2" killpeasants="yes" learn="yes"/> - <function name="name" value="namedragon"/> - <function name="age" value="agedragon"/> - <function name="move" value="movedragon"/> - <skill name="magic" modifier="8"/> - <skill name="tactics" modifier="8"/> - <attack type="4" damage="2d20"/> - <attack type="4" damage="2d20"/> - <attack type="4" damage="3d30"/> - <attack type="6" spell="icy_dragonbreath"/> -</race> - +<race name="dragon" magres="0.700000" maxaura="1.0" regaura="2.000000" weight="10000" capacity="1000000" speed="1.500000" hp="900" ac= +"6" damage="2d30" unarmedattack="0" unarmeddefense="0" attackmodifier="7" defensemodifier="7" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" giveitem="yes" resistbash="yes"> + <ai splitsize="2" killpeasants="yes" learn="yes"/> + <function name="name" value="namedragon"/> + <function name="age" value="agedragon"/> + <function name="move" value="movedragon"/> + <skill name="magic" modifier="8"/> + <skill name="tactics" modifier="8"/> + <attack type="4" damage="2d20"/> + <attack type="4" damage="2d20"/> + <attack type="4" damage="3d30"/> + <attack type="6" spell="icy_dragonbreath"/> +</race> + diff --git a/res/races/goblin-2.xml b/res/races/goblin-2.xml index 7e23e28cf..4bfdff162 100644 --- a/res/races/goblin-2.xml +++ b/res/races/goblin-2.xml @@ -1,22 +1,22 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<race name="goblin" magres="-0.05" maxaura="1.0" regaura="1.0" recruitcost="60" maintenance="6" weight="600" capacity="440" speed="1.0" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <param name="hunger.damage" value="1d8+7"/> - <param name="other_race" value="demon"/> - <param name="other_cost" value="500"/> - <param name="recruit_multi" value="0.5"/> - <skill name="building" modifier="1"/> - <skill name="cartmaking" modifier="-1"/> - <skill name="catapult" modifier="1"/> - <skill name="magic" modifier="-99"/> - <skill name="mining" modifier="1"/> - <skill name="roadwork" modifier="-2"/> - <skill name="sailing" modifier="-2"/> - <skill name="shipcraft" modifier="-2"/> - <skill name="tactics" modifier="-2"/> - <skill name="unarmed" modifier="-99"/> - <attack type="1" damage="1d5"/> - <familiar race="rat" default="yes"/> - <familiar race="imp"/> -</race> +<?xml version="1.0" encoding="iso-8859-1" ?> +<race name="goblin" magres="-0.05" maxaura="1.0" regaura="1.0" recruitcost="60" maintenance="6" weight="600" capacity="440" speed="1.0" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <param name="hunger.damage" value="1d8+7"/> + <param name="other_race" value="demon"/> + <param name="other_cost" value="500"/> + <param name="recruit_multi" value="0.5"/> + <skill name="building" modifier="1"/> + <skill name="cartmaking" modifier="-1"/> + <skill name="catapult" modifier="1"/> + <skill name="magic" modifier="-99"/> + <skill name="mining" modifier="1"/> + <skill name="roadwork" modifier="-2"/> + <skill name="sailing" modifier="-2"/> + <skill name="shipcraft" modifier="-2"/> + <skill name="tactics" modifier="-2"/> + <skill name="unarmed" modifier="-99"/> + <attack type="1" damage="1d5"/> + <familiar race="rat" default="yes"/> + <familiar race="imp"/> +</race> diff --git a/res/races/goblin-3.xml b/res/races/goblin-3.xml index 845b69c20..263fc4762 100644 --- a/res/races/goblin-3.xml +++ b/res/races/goblin-3.xml @@ -1,22 +1,22 @@ -<?xml version="1.0" encoding="iso-8859-1" ?> -<race name="goblin" magres="-0.05" maxaura="1.0" regaura="1.0" recruitcost="60" maintenance="6" weight="600" capacity="440" speed="1.0" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> - <ai splitsize="10000" moverandom="yes" learn="yes"/> - <function name="itemdrop" value="defaultdrops"/> - <param name="hunger.damage" value="1d8+7"/> - <param name="other_race" value="demon"/> - <param name="other_cost" value="500"/> - <param name="recruit_multi" value="0.5"/> - <skill name="cartmaking" modifier="-1"/> - <skill name="catapult" modifier="1"/> - <skill name="magic" modifier="-99"/> - <skill name="mining" modifier="1"/> - <skill name="roadwork" modifier="-2"/> - <skill name="sailing" modifier="-2"/> - <skill name="shipcraft" modifier="-2"/> - <skill name="tactics" modifier="-2"/> - <skill name="unarmed" modifier="-99"/> - <skill name="weaponsmithing" modifier="-1"/> - <attack type="1" damage="1d5"/> - <familiar race="rat" default="yes"/> - <familiar race="imp"/> -</race> +<?xml version="1.0" encoding="iso-8859-1" ?> +<race name="goblin" magres="-0.05" maxaura="1.0" regaura="1.0" recruitcost="60" maintenance="6" weight="600" capacity="440" speed="1.0" hp="16" damage="1d5" unarmedattack="-2" unarmeddefense="0" playerrace="yes" walk="yes" giveitem="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes"> + <ai splitsize="10000" moverandom="yes" learn="yes"/> + <function name="itemdrop" value="defaultdrops"/> + <param name="hunger.damage" value="1d8+7"/> + <param name="other_race" value="demon"/> + <param name="other_cost" value="500"/> + <param name="recruit_multi" value="0.5"/> + <skill name="cartmaking" modifier="-1"/> + <skill name="catapult" modifier="1"/> + <skill name="magic" modifier="-99"/> + <skill name="mining" modifier="1"/> + <skill name="roadwork" modifier="-2"/> + <skill name="sailing" modifier="-2"/> + <skill name="shipcraft" modifier="-2"/> + <skill name="tactics" modifier="-2"/> + <skill name="unarmed" modifier="-99"/> + <skill name="weaponsmithing" modifier="-1"/> + <attack type="1" damage="1d5"/> + <familiar race="rat" default="yes"/> + <familiar race="imp"/> +</race> diff --git a/res/races/wyrm.xml b/res/races/wyrm.xml index 924178c25..3f648ea3c 100644 --- a/res/races/wyrm.xml +++ b/res/races/wyrm.xml @@ -1,11 +1,11 @@ -<race name="wyrm" magres="0.900000" maxaura="1.0" regaura="3.000000" weight="18000" capacity="1000000" speed="1.0" hp="2700" ac="8" damage="2d60" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes"> - <ai splitsize="1" killpeasants="yes" learn="yes"/> - <function name="name" value="namedragon"/> - <function name="move" value="movedragon"/> - <skill name="magic" modifier="12"/> - <skill name="tactics" modifier="12"/> - <attack type="4" damage="3d20"/> - <attack type="4" damage="3d20"/> - <attack type="4" damage="5d30"/> - <attack type="6" spell="powerful_dragonbreath"/> -</race> +<race name="wyrm" magres="0.900000" maxaura="1.0" regaura="3.000000" weight="18000" capacity="1000000" speed="1.0" hp="2700" ac="8" damage="2d60" unarmedattack="0" unarmeddefense="0" attackmodifier="10" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes"> + <ai splitsize="1" killpeasants="yes" learn="yes"/> + <function name="name" value="namedragon"/> + <function name="move" value="movedragon"/> + <skill name="magic" modifier="12"/> + <skill name="tactics" modifier="12"/> + <attack type="4" damage="3d20"/> + <attack type="4" damage="3d20"/> + <attack type="4" damage="5d30"/> + <attack type="6" spell="powerful_dragonbreath"/> +</race> diff --git a/res/races/youngdragon.xml b/res/races/youngdragon.xml index 18af1f46a..86c249be1 100644 --- a/res/races/youngdragon.xml +++ b/res/races/youngdragon.xml @@ -1,13 +1,13 @@ -<race name="youngdragon" magres="0.500000" maxaura="1.0" regaura="1.0" weight="20000" capacity="10000" speed="1.0" hp="300" ac="4" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes"> - <ai splitsize="6" killpeasants="yes" learn="yes"/> - <function name="name" value="namedragon"/> - <function name="age" value="agefiredragon"/> - <function name="move" value="movedragon"/> - <skill name="magic" modifier="4"/> - <skill name="tactics" modifier="4"/> - <attack type="4" damage="1d30"/> - <attack type="4" damage="1d30"/> - <attack type="4" damage="1d30"/> - <attack type="6" spell="fiery_dragonbreath"/> -</race> - +<race name="youngdragon" magres="0.500000" maxaura="1.0" regaura="1.0" weight="20000" capacity="10000" speed="1.0" hp="300" ac="4" damage="2d15" unarmedattack="0" unarmeddefense="0" attackmodifier="4" defensemodifier="4" scarepeasants="yes" fly="yes" walk="yes" teach="no" getitem="yes" resistbash="yes"> + <ai splitsize="6" killpeasants="yes" learn="yes"/> + <function name="name" value="namedragon"/> + <function name="age" value="agefiredragon"/> + <function name="move" value="movedragon"/> + <skill name="magic" modifier="4"/> + <skill name="tactics" modifier="4"/> + <attack type="4" damage="1d30"/> + <attack type="4" damage="1d30"/> + <attack type="4" damage="1d30"/> + <attack type="6" spell="fiery_dragonbreath"/> +</race> + diff --git a/scripts/e3a/build.lua b/scripts/e3a/build.lua index 8ea2693b8..a11b6068f 100644 --- a/scripts/e3a/build.lua +++ b/scripts/e3a/build.lua @@ -1,194 +1,194 @@ -function size() - return 16 -end - -function make_island(pl, x, y, a, b) - if b==nil then b = a/3 end - local nx, ny = plane.normalize(pl, x, y) - gmtool.make_island(nx, ny, a, b) -end - -function make_block(pl, x, y, r) - local nx, ny = plane.normalize(pl, x, y) - gmtool.make_block(nx, ny, r) -end - -function find(email) - for f in factions() do if f.email==email then return f end end - return nil -end - -function give_item(email, id, uname, iname) - f = find(email) - for u in f.units do - u.id=atoi36(id) - u.name=uname - u:add_item(iname, 1) - break - end -end - -function give_items() - give_item("hongeldongel@web.de", "boss", "Drollitz", "rpg_item_1") - give_item("zangerl.helmut@chello.at", "holb", "Holbard", "rpg_item_2") - give_item("r.lang@chello.at", "brtL", "Bertl", "rpg_item_2") - give_item("schlaustauch@gmx.de", "bert", "Bertram", "rpg_item_3") -end - -function island(pl, x, y, r) - make_block(pl, x, y, r) - make_island(pl, x+r/2+2, y+r/2, size() * 3) - make_island(pl, x-r-2, y+r/2, size() * 3) - make_island(pl, x-r/2-2, y-r/2, size() * 3) - make_island(pl, x+r+2, y-r/2, size() * 3) - make_island(pl, x+r/2+2, y-r-2, size() * 3) - make_island(pl, x-r/2-2, y+r+2, size() * 3) -end - -function cross(pl, x, y, r) - make_block(pl, x-r, y+r*2, r) - make_block(pl, x+r*4/3, y, r) - make_block(pl, x-r*4/3, y, r) - make_block(pl, x+r, y-r*2, r) - - make_island(pl, x, y, size() * 3) - make_island(pl, x, y-r*4/3, size() * 3) - make_island(pl, x, y+r*4/3, size() * 3) - make_island(pl, x+r*4/3, y-r*4/3, size() * 3) - make_island(pl, x-r*4/3, y+r*4/3, size() * 3) -end - -function clean() - for r in regions() do - if r.terrain=="ocean" then - -- print(r) - region.destroy(r) - end - end -end - -function count() - local i = 0 - for f in factions() do i = i + 1 end - print(i) -end - -function line(pl) - local m = 0 - local i = 0 - local x, y = plane.normalize(pl, 0, i) - local r = get_region(x, y) - while true do - if r==nil then - if m==0 and (i>=0 or i<-10) then - local s = size() - gmtool.make_island(x, y, s*3, s) - else - gmtool.make_block(x, y, 6) - end - r = get_region(x, y) - if r==nil then - r = region.create(x, y, "ocean") - end - m = 1 - m - end - i = r.y + 1 - x, y = plane.normalize(pl, 0, i) - r = get_region(x, y) - if r~=nil and r.y==0 then break end - end -end - -function build(pl) - local d = 28 - local h = 20 - line(pl) - island(pl, d+15, -6, 11) - island(pl, -d, -h-10, 11) - cross(pl, -d, h-10, 6) - island(pl, d, 2*h, 11) -end - -function fill(pl, w, h) - local x, y - for x=0,w do - for y=0,h do - local nx, ny = plane.normalize(pl, x, y) - local r = get_region(nx, ny) - if r==nil then - r = region.create(nx, ny, "ocean") - end - end - end -end - -function seed() - local input = io.open(config.basepath .. "/parteien.txt") - for f in factions() do - if f.race=="vampunicorn" then - local str = input:read("*line") - if str==nil then break end - local race, lang, email = str:match("([^ ]*) ([^ ]*) ([^ ]*)") - f.race = race:lower() - f.options = f.options + 4096 - f.email = email - f.locale = lang - for u in f.units do - u.race = race:lower() - u.hp = u.hp_max - local b = building.create(u.region, "castle") - if lang=="de" then - u.name = "Entdecker" - b.name = "Heimat" - else - u.name = "Explorer" - b.name = "Home" - end - b.size = 10 - u.building = b - end - end - end - for r in regions() do - r:set_resource("sapling", r:get_resource("tree")/4) - r:set_resource("seed", 0) - end - update_owners() -end - -function select() - for f in factions() do - if f.email=="enno@eressea.de" then - for u in f.units do - gmtool.select(u.region, true) - u.number = 0 - end - end - end -end - -function justWords(str) - local t = {} - local function helper(word) table.insert(t, word) return "" end - if not str:gsub("%w+", helper):find"%S" then return t end -end - -function rebuild() - free_game() - local w = 110 - local h = 80 - local pl = plane.create(0, -w/2, -h/2, w+1, h+1) - build(pl) - fill(pl, w, h) - write_map("export.cr") -end - -function testwelt() - free_game() - local w = 10 - local h = 10 - local pl = plane.create(0, -w/2, -h/2, w+1, h+1) - gmtool.make_island(0, 0, 30, 3) - fill(pl, w, h) - write_map("export.cr") -end +function size() + return 16 +end + +function make_island(pl, x, y, a, b) + if b==nil then b = a/3 end + local nx, ny = plane.normalize(pl, x, y) + gmtool.make_island(nx, ny, a, b) +end + +function make_block(pl, x, y, r) + local nx, ny = plane.normalize(pl, x, y) + gmtool.make_block(nx, ny, r) +end + +function find(email) + for f in factions() do if f.email==email then return f end end + return nil +end + +function give_item(email, id, uname, iname) + f = find(email) + for u in f.units do + u.id=atoi36(id) + u.name=uname + u:add_item(iname, 1) + break + end +end + +function give_items() + give_item("hongeldongel@web.de", "boss", "Drollitz", "rpg_item_1") + give_item("zangerl.helmut@chello.at", "holb", "Holbard", "rpg_item_2") + give_item("r.lang@chello.at", "brtL", "Bertl", "rpg_item_2") + give_item("schlaustauch@gmx.de", "bert", "Bertram", "rpg_item_3") +end + +function island(pl, x, y, r) + make_block(pl, x, y, r) + make_island(pl, x+r/2+2, y+r/2, size() * 3) + make_island(pl, x-r-2, y+r/2, size() * 3) + make_island(pl, x-r/2-2, y-r/2, size() * 3) + make_island(pl, x+r+2, y-r/2, size() * 3) + make_island(pl, x+r/2+2, y-r-2, size() * 3) + make_island(pl, x-r/2-2, y+r+2, size() * 3) +end + +function cross(pl, x, y, r) + make_block(pl, x-r, y+r*2, r) + make_block(pl, x+r*4/3, y, r) + make_block(pl, x-r*4/3, y, r) + make_block(pl, x+r, y-r*2, r) + + make_island(pl, x, y, size() * 3) + make_island(pl, x, y-r*4/3, size() * 3) + make_island(pl, x, y+r*4/3, size() * 3) + make_island(pl, x+r*4/3, y-r*4/3, size() * 3) + make_island(pl, x-r*4/3, y+r*4/3, size() * 3) +end + +function clean() + for r in regions() do + if r.terrain=="ocean" then + -- print(r) + region.destroy(r) + end + end +end + +function count() + local i = 0 + for f in factions() do i = i + 1 end + print(i) +end + +function line(pl) + local m = 0 + local i = 0 + local x, y = plane.normalize(pl, 0, i) + local r = get_region(x, y) + while true do + if r==nil then + if m==0 and (i>=0 or i<-10) then + local s = size() + gmtool.make_island(x, y, s*3, s) + else + gmtool.make_block(x, y, 6) + end + r = get_region(x, y) + if r==nil then + r = region.create(x, y, "ocean") + end + m = 1 - m + end + i = r.y + 1 + x, y = plane.normalize(pl, 0, i) + r = get_region(x, y) + if r~=nil and r.y==0 then break end + end +end + +function build(pl) + local d = 28 + local h = 20 + line(pl) + island(pl, d+15, -6, 11) + island(pl, -d, -h-10, 11) + cross(pl, -d, h-10, 6) + island(pl, d, 2*h, 11) +end + +function fill(pl, w, h) + local x, y + for x=0,w do + for y=0,h do + local nx, ny = plane.normalize(pl, x, y) + local r = get_region(nx, ny) + if r==nil then + r = region.create(nx, ny, "ocean") + end + end + end +end + +function seed() + local input = io.open(config.basepath .. "/parteien.txt") + for f in factions() do + if f.race=="vampunicorn" then + local str = input:read("*line") + if str==nil then break end + local race, lang, email = str:match("([^ ]*) ([^ ]*) ([^ ]*)") + f.race = race:lower() + f.options = f.options + 4096 + f.email = email + f.locale = lang + for u in f.units do + u.race = race:lower() + u.hp = u.hp_max + local b = building.create(u.region, "castle") + if lang=="de" then + u.name = "Entdecker" + b.name = "Heimat" + else + u.name = "Explorer" + b.name = "Home" + end + b.size = 10 + u.building = b + end + end + end + for r in regions() do + r:set_resource("sapling", r:get_resource("tree")/4) + r:set_resource("seed", 0) + end + update_owners() +end + +function select() + for f in factions() do + if f.email=="enno@eressea.de" then + for u in f.units do + gmtool.select(u.region, true) + u.number = 0 + end + end + end +end + +function justWords(str) + local t = {} + local function helper(word) table.insert(t, word) return "" end + if not str:gsub("%w+", helper):find"%S" then return t end +end + +function rebuild() + free_game() + local w = 110 + local h = 80 + local pl = plane.create(0, -w/2, -h/2, w+1, h+1) + build(pl) + fill(pl, w, h) + write_map("export.cr") +end + +function testwelt() + free_game() + local w = 10 + local h = 10 + local pl = plane.create(0, -w/2, -h/2, w+1, h+1) + gmtool.make_island(0, 0, 30, 3) + fill(pl, w, h) + write_map("export.cr") +end diff --git a/scripts/e3a/main.lua b/scripts/e3a/main.lua index 0548ce513..e7553521f 100644 --- a/scripts/e3a/main.lua +++ b/scripts/e3a/main.lua @@ -1,63 +1,63 @@ -require "multis" - -function process(orders) - local confirmed_multis = { } - local suspected_multis = { } - - if open_game(get_turn())~=0 then - print("could not read game") - return -1 - end - init_summary() - - -- kill multi-players (external script) - kill_multis(confirmed_multis, false) - mark_multis(suspected_multis, false) - - -- run the turn: - if read_orders(orders) ~= 0 then - print("could not read " .. orders) - return -1 - end - - -- plan_monsters() - local mon = get_faction(666) - if mon ~= nil then - mon.lastturn = get_turn() - end - - if nmr_check(config.maxnmrs or 30)~=0 then - return -1 - end - - process_orders() - if xmas2009~=nil then - xmas2009() - end - - -- create new monsters: - spawn_dragons() - spawn_undead() - -- spawn_braineaters(0.25) - -- spawn_ents() - - kill_nonstarters() - -- post-turn updates: - update_guards() - update_scores() - - local localechange = { de = { "ii" } } - change_locales(localechange) - - -- use newfactions file to place out new players - -- autoseed(config.basepath .. "/newfactions", false) - - write_files(config.locales) - - file = "" .. get_turn() .. ".dat" - if write_game(file, "binary")~=0 then - print("could not write game") - return -1 - end - return 0 -end +require "multis" + +function process(orders) + local confirmed_multis = { } + local suspected_multis = { } + + if open_game(get_turn())~=0 then + print("could not read game") + return -1 + end + init_summary() + + -- kill multi-players (external script) + kill_multis(confirmed_multis, false) + mark_multis(suspected_multis, false) + + -- run the turn: + if read_orders(orders) ~= 0 then + print("could not read " .. orders) + return -1 + end + + -- plan_monsters() + local mon = get_faction(666) + if mon ~= nil then + mon.lastturn = get_turn() + end + + if nmr_check(config.maxnmrs or 30)~=0 then + return -1 + end + + process_orders() + if xmas2009~=nil then + xmas2009() + end + + -- create new monsters: + spawn_dragons() + spawn_undead() + -- spawn_braineaters(0.25) + -- spawn_ents() + + kill_nonstarters() + -- post-turn updates: + update_guards() + update_scores() + + local localechange = { de = { "ii" } } + change_locales(localechange) + + -- use newfactions file to place out new players + -- autoseed(config.basepath .. "/newfactions", false) + + write_files(config.locales) + + file = "" .. get_turn() .. ".dat" + if write_game(file, "binary")~=0 then + print("could not write game") + return -1 + end + return 0 +end diff --git a/scripts/e3a/markets.lua b/scripts/e3a/markets.lua index 0fc24da28..b6bfb23c0 100644 --- a/scripts/e3a/markets.lua +++ b/scripts/e3a/markets.lua @@ -1,89 +1,89 @@ -function get_markets(r, result) - local n = 0 - result = result or {} - - for b in r.buildings do - if b.type=="market" then - u = b.owner - if u~=nil then - table.insert(result, u) - n = n + 1 - end - end - end - return n, result -end - -function collect_markets(r, result) - local result = result or {} - local n = 0 - n, result = get_markets(r, result) - for i, r in ipairs(r.adj) do - if r then - local x, result = get_markets(r, result) - n = n + x - end - end - return n, result -end - -function market_action(r) - local f = r.owner - local trade = 1000 - if f~=nil and f.race=="halfling" then - trade = 600 - end - - local p = r:get_resource("peasant") - if p > 500 then - local n, markets = collect_markets(r) - - if n>0 then - local give - if r.luxury~=nil then - give = {} - local numlux = p / trade - for x = 1, numlux do - local m = 1+math.mod(rng_int(), n) - u = markets[m] - if give[u] then - give[u] = give[u] + 1 - else - give[u] = 1 - end - end - - for u, v in pairs(give) do - u:add_item(r.luxury, v) - end - end - - if r.herb~=nil then - give = {} - local numherb = p / 500 - for x = 1, numherb do - local m = 1+math.mod(rng_int(), n) - u = markets[m] - if give[u] then - give[u] = give[u] + 1 - else - give[u] = 1 - end - end - - for u, v in pairs(give) do - u:add_item(r.herb, v) - end - end - end - end -end - -local function markets() - local r - for r in regions() do - market_action(r) - end -end - --- add_proc(markets, "Markets", "Bauernwanderung") +function get_markets(r, result) + local n = 0 + result = result or {} + + for b in r.buildings do + if b.type=="market" then + u = b.owner + if u~=nil then + table.insert(result, u) + n = n + 1 + end + end + end + return n, result +end + +function collect_markets(r, result) + local result = result or {} + local n = 0 + n, result = get_markets(r, result) + for i, r in ipairs(r.adj) do + if r then + local x, result = get_markets(r, result) + n = n + x + end + end + return n, result +end + +function market_action(r) + local f = r.owner + local trade = 1000 + if f~=nil and f.race=="halfling" then + trade = 600 + end + + local p = r:get_resource("peasant") + if p > 500 then + local n, markets = collect_markets(r) + + if n>0 then + local give + if r.luxury~=nil then + give = {} + local numlux = p / trade + for x = 1, numlux do + local m = 1+math.mod(rng_int(), n) + u = markets[m] + if give[u] then + give[u] = give[u] + 1 + else + give[u] = 1 + end + end + + for u, v in pairs(give) do + u:add_item(r.luxury, v) + end + end + + if r.herb~=nil then + give = {} + local numherb = p / 500 + for x = 1, numherb do + local m = 1+math.mod(rng_int(), n) + u = markets[m] + if give[u] then + give[u] = give[u] + 1 + else + give[u] = 1 + end + end + + for u, v in pairs(give) do + u:add_item(r.herb, v) + end + end + end + end +end + +local function markets() + local r + for r in regions() do + market_action(r) + end +end + +-- add_proc(markets, "Markets", "Bauernwanderung") diff --git a/scripts/e3a/modules.lua b/scripts/e3a/modules.lua index aac9e864a..9f93570b5 100644 --- a/scripts/e3a/modules.lua +++ b/scripts/e3a/modules.lua @@ -1,12 +1,12 @@ -require "spells" -require "e3a.xmas2009" -require "e3a.rules" -require "e3a.markets" - -local srcpath = config.source_dir -tests = { - srcpath .. '/eressea/scripts/tests/castles.lua', - srcpath .. '/eressea/scripts/tests/morale.lua', - srcpath .. '/server/scripts/tests/common.lua', - srcpath .. '/eressea/scripts/tests/e3a.lua', -} +require "spells" +require "e3a.xmas2009" +require "e3a.rules" +require "e3a.markets" + +local srcpath = config.source_dir +tests = { + srcpath .. '/eressea/scripts/tests/castles.lua', + srcpath .. '/eressea/scripts/tests/morale.lua', + srcpath .. '/server/scripts/tests/common.lua', + srcpath .. '/eressea/scripts/tests/e3a.lua', +} diff --git a/scripts/e3a/rules.lua b/scripts/e3a/rules.lua index 2d137d2d0..2e20e8595 100644 --- a/scripts/e3a/rules.lua +++ b/scripts/e3a/rules.lua @@ -1,77 +1,77 @@ --- when appending to this, make sure the item has a canuse-function! -local goblin_denied = " plate lance mallornlance greatbow axe greatsword halberd rustyaxe rustyhalberd towershield scale " -function item_canuse(u, iname) - local race = u.race - if race=="goblin" then - if string.find(goblin_denied, " " .. iname .. " ") then - return false - end - end - if iname=="rep_crossbow" then - -- only dwarves and halflings allowed to use towershield - return race=="dwarf" or race=="halfling" - end - if iname=="scale" then - -- only dwarves and halflings can use scale - return race=="dwarf" or race=="halfling" - end - if iname=="towershield" then - -- only dwarves allowed to use towershield - return race=="dwarf" - end - if iname=="greatbow" then - -- only elves use greatbow - return race=="elf" - end - return true -end - -function building_protection(b, u) - return 1 -end - -function building_taxes(b, blevel) - btype = b.type - if btype=="castle" then - return blevel * 0.01 - elseif btype=="watch" then - return blevel * 0.005 - end - return 0.0 -end - --- the "raindance" spell -function raindance(r, mage, level, force) - if (create_curse(mage, r, "blessedharvest", force, 1+force*2, 100 * force)) then - -- slightly crooked way of reporting an action to everyone in the region - local msg = message.create("raindance_effect") - msg:set_unit("mage", mage) - if (msg:report_action(r, mage, 3)) then - local msg2 = message.create("raindance_effect") - msg2:set_unit("mage", nil) - msg2:report_action(r, mage, 4) - end - end - return level -end - --- the "blessed harvest" spell -function blessedharvest(r, mage, level, force) - if create_curse(mage, r, "blessedharvest", force, 1+force*2, 50 * force) then - -- slightly crooked way of reporting an action to everyone in the region - local msg = message.create("harvest_effect") - msg:set_unit("mage", mage) - if (msg:report_action(r, mage, 3)) then - local msg2 = message.create("harvest_effect") - msg2:set_unit("mage", nil) - msg2:report_action(r, mage, 4) - end - for idx, rn in ipairs(r.adj) do - -- nur landregionen haben moral>=0 - if r.morale>=0 then - create_curse(mage, r, "blessedharvest", force, force*2, 50 * force) - end - end - end - return level -end +-- when appending to this, make sure the item has a canuse-function! +local goblin_denied = " plate lance mallornlance greatbow axe greatsword halberd rustyaxe rustyhalberd towershield scale " +function item_canuse(u, iname) + local race = u.race + if race=="goblin" then + if string.find(goblin_denied, " " .. iname .. " ") then + return false + end + end + if iname=="rep_crossbow" then + -- only dwarves and halflings allowed to use towershield + return race=="dwarf" or race=="halfling" + end + if iname=="scale" then + -- only dwarves and halflings can use scale + return race=="dwarf" or race=="halfling" + end + if iname=="towershield" then + -- only dwarves allowed to use towershield + return race=="dwarf" + end + if iname=="greatbow" then + -- only elves use greatbow + return race=="elf" + end + return true +end + +function building_protection(b, u) + return 1 +end + +function building_taxes(b, blevel) + btype = b.type + if btype=="castle" then + return blevel * 0.01 + elseif btype=="watch" then + return blevel * 0.005 + end + return 0.0 +end + +-- the "raindance" spell +function raindance(r, mage, level, force) + if (create_curse(mage, r, "blessedharvest", force, 1+force*2, 100 * force)) then + -- slightly crooked way of reporting an action to everyone in the region + local msg = message.create("raindance_effect") + msg:set_unit("mage", mage) + if (msg:report_action(r, mage, 3)) then + local msg2 = message.create("raindance_effect") + msg2:set_unit("mage", nil) + msg2:report_action(r, mage, 4) + end + end + return level +end + +-- the "blessed harvest" spell +function blessedharvest(r, mage, level, force) + if create_curse(mage, r, "blessedharvest", force, 1+force*2, 50 * force) then + -- slightly crooked way of reporting an action to everyone in the region + local msg = message.create("harvest_effect") + msg:set_unit("mage", mage) + if (msg:report_action(r, mage, 3)) then + local msg2 = message.create("harvest_effect") + msg2:set_unit("mage", nil) + msg2:report_action(r, mage, 4) + end + for idx, rn in ipairs(r.adj) do + -- nur landregionen haben moral>=0 + if r.morale>=0 then + create_curse(mage, r, "blessedharvest", force, force*2, 50 * force) + end + end + end + return level +end diff --git a/scripts/e3a/xmas2009.lua b/scripts/e3a/xmas2009.lua index 7e634d918..708893fb6 100644 --- a/scripts/e3a/xmas2009.lua +++ b/scripts/e3a/xmas2009.lua @@ -1,26 +1,26 @@ -function xmas2009() - if not get_key("xm09") then --- print("Es weihnachtet sehr (2009)") - set_key("xm09", true) - for f in factions() do - f:add_item("xmastree", 1) - local msg = message.create("msg_event") - msg:set_string("string", translate("santa2006")) - msg:send_faction(f) - end - end - return 0 -end - -function use_xmastree(u, amount) - if u.region.herb~=nil then - local trees = u.region:get_resource("tree") - u.region:set_resource("tree", 10+trees) - u:use_pooled("xmastree", amount) - local msg = message.create("usepotion") - msg:set_unit("unit", u) - msg:set_resource("potion", "xmastree") - msg:send_region(u.region) - return 0 - end -end +function xmas2009() + if not get_key("xm09") then +-- print("Es weihnachtet sehr (2009)") + set_key("xm09", true) + for f in factions() do + f:add_item("xmastree", 1) + local msg = message.create("msg_event") + msg:set_string("string", translate("santa2006")) + msg:send_faction(f) + end + end + return 0 +end + +function use_xmastree(u, amount) + if u.region.herb~=nil then + local trees = u.region:get_resource("tree") + u.region:set_resource("tree", 10+trees) + u:use_pooled("xmastree", amount) + local msg = message.create("usepotion") + msg:set_unit("unit", u) + msg:set_resource("potion", "xmastree") + msg:send_region(u.region) + return 0 + end +end diff --git a/scripts/eressea/adamant.lua b/scripts/eressea/adamant.lua index 66c260bdf..73315f4bd 100644 --- a/scripts/eressea/adamant.lua +++ b/scripts/eressea/adamant.lua @@ -1,78 +1,78 @@ --- adamant gifts and setup for tunnels - --- use only once to hand out some items to existing factions -function adamant_gifts() - for f in factions() do - local i = math.mod(test.rng_int(), 2) - if i==0 then - f:add_item("adamantium", 1) - f:add_item("adamantiumplate", 1) - else - f:add_item("adamantium", 3) - f:add_item("adamantiumaxe", 1) - end - end -end - -function adamant_seeds() - for r in regions() do - if r:get_key("tnnL") then - print("1 ", r:get_resource("adamantium"), r) - test.adamantium_island(r) - print("2 ", r:get_resource("adamantium")) - end - end -end - --- create a fixed path to a specific region -local function create_path(from, to) - local param = tostring(to.uid) - local b = add_building(from, "portal") - b.name = "Weltentor" - b.size = 1 - b:add_action("tunnel_action", param) -end - --- create a wonky tunnel wth more than one exit -local function create_tunnel(from, param) - local b = add_building(from, "portal") - b.name = "Weltentor" - b.size = 1 - b:add_action("tunnel_action", param) -end - --- make a tunnel from the cursor to the first selected region -function mktunnel() - local from = gmtool.get_cursor() - local to = gmtool.get_selection()() - if to~=nil then - region.create(from.x, from.y, "glacier") - create_tunnel(from, to) - gmtool.select(to, 0) - gmtool.highlight(to, 1) - end -end - --- turn all selected regions into targets for a wonky tunnel ("tnnL") -function mkanchors() - for r in gmtool.get_selection() do - if not r:get_key("tnnL") then - r:set_key("tnnL", true) - if r:get_flag(0) then - -- RF_CHAOTIC - r:set_flag(0, true) - end - r:set_resource("peasant", r:get_resource("peasant") + 1) - end - end -end - --- region.create and prepare all hell-regions to become wonky gates -function mkgates() - for r in regions() do - if r.plane_id==0 and r.terrain=="hell" then - create_tunnel(r, "tnnL") - region.create(r.x, r.y, "glacier") - end - end -end +-- adamant gifts and setup for tunnels + +-- use only once to hand out some items to existing factions +function adamant_gifts() + for f in factions() do + local i = math.mod(test.rng_int(), 2) + if i==0 then + f:add_item("adamantium", 1) + f:add_item("adamantiumplate", 1) + else + f:add_item("adamantium", 3) + f:add_item("adamantiumaxe", 1) + end + end +end + +function adamant_seeds() + for r in regions() do + if r:get_key("tnnL") then + print("1 ", r:get_resource("adamantium"), r) + test.adamantium_island(r) + print("2 ", r:get_resource("adamantium")) + end + end +end + +-- create a fixed path to a specific region +local function create_path(from, to) + local param = tostring(to.uid) + local b = add_building(from, "portal") + b.name = "Weltentor" + b.size = 1 + b:add_action("tunnel_action", param) +end + +-- create a wonky tunnel wth more than one exit +local function create_tunnel(from, param) + local b = add_building(from, "portal") + b.name = "Weltentor" + b.size = 1 + b:add_action("tunnel_action", param) +end + +-- make a tunnel from the cursor to the first selected region +function mktunnel() + local from = gmtool.get_cursor() + local to = gmtool.get_selection()() + if to~=nil then + region.create(from.x, from.y, "glacier") + create_tunnel(from, to) + gmtool.select(to, 0) + gmtool.highlight(to, 1) + end +end + +-- turn all selected regions into targets for a wonky tunnel ("tnnL") +function mkanchors() + for r in gmtool.get_selection() do + if not r:get_key("tnnL") then + r:set_key("tnnL", true) + if r:get_flag(0) then + -- RF_CHAOTIC + r:set_flag(0, true) + end + r:set_resource("peasant", r:get_resource("peasant") + 1) + end + end +end + +-- region.create and prepare all hell-regions to become wonky gates +function mkgates() + for r in regions() do + if r.plane_id==0 and r.terrain=="hell" then + create_tunnel(r, "tnnL") + region.create(r.x, r.y, "glacier") + end + end +end diff --git a/scripts/eressea/alp.lua b/scripts/eressea/alp.lua index 1f33c8681..c167784db 100644 --- a/scripts/eressea/alp.lua +++ b/scripts/eressea/alp.lua @@ -1,37 +1,37 @@ -require "callbacks" -require "dumptable" - -local function trigger_alp_destroyed(alp, event) - m = message.create("alp_destroyed") - m:set_region("region", alp.region) - m:send_faction(alp.faction) -end - -local function trigger_alp_dissolve(u, event, attr) - local alp = attr.alp - attr.alp.number = 0 -- kills the alp -end - -local function init_alp(attr) - -- dumptable(attr) - eventbus.register(attr.alp, "destroy", trigger_alp_destroyed) - eventbus.register(attr.mage, "destroy", trigger_alp_dissolve, attr) - eventbus.register(attr.target, "destroy", trigger_alp_dissolve, attr) -end - -callbacks["init_alp"] = init_alp - --- Spell: summon alp -function summon_alp(r, mage, level, force, params) - local alp = unit.create(mage.faction, r, 1, "alp") - local target = params[1] - alp:set_skill("stealth", 7) - alp.status = 5 -- FLEE - attr = attrib.create(alp, { ['name'] = 'alp', ['target'] = target, ['alp'] = alp, ['mage'] = mage }) - init_alp(attr) - msg = message.create("summon_alp_effect") - m:set_unit("mage", mage) - m:set_unit("alp", alp) - m:set_unit("target", target) - m:send_faction(mage.faction) -end +require "callbacks" +require "dumptable" + +local function trigger_alp_destroyed(alp, event) + m = message.create("alp_destroyed") + m:set_region("region", alp.region) + m:send_faction(alp.faction) +end + +local function trigger_alp_dissolve(u, event, attr) + local alp = attr.alp + attr.alp.number = 0 -- kills the alp +end + +local function init_alp(attr) + -- dumptable(attr) + eventbus.register(attr.alp, "destroy", trigger_alp_destroyed) + eventbus.register(attr.mage, "destroy", trigger_alp_dissolve, attr) + eventbus.register(attr.target, "destroy", trigger_alp_dissolve, attr) +end + +callbacks["init_alp"] = init_alp + +-- Spell: summon alp +function summon_alp(r, mage, level, force, params) + local alp = unit.create(mage.faction, r, 1, "alp") + local target = params[1] + alp:set_skill("stealth", 7) + alp.status = 5 -- FLEE + attr = attrib.create(alp, { ['name'] = 'alp', ['target'] = target, ['alp'] = alp, ['mage'] = mage }) + init_alp(attr) + msg = message.create("summon_alp_effect") + m:set_unit("mage", mage) + m:set_unit("alp", alp) + m:set_unit("target", target) + m:send_faction(mage.faction) +end diff --git a/scripts/eressea/embassy.lua b/scripts/eressea/embassy.lua index 8648d600e..d427676e1 100644 --- a/scripts/eressea/embassy.lua +++ b/scripts/eressea/embassy.lua @@ -1,30 +1,30 @@ -function use_seashell(u, amount) --- Muschelplateau... - local r = get_region(165,30) - local visit = u.faction.objects:get("embassy_muschel") - if visit~=nil and u.region~= r then - local turns = get_turn() - visit - local msg = message.create("msg_event") - msg:set_string("string", u.name .. "(" .. itoa36(u.id) .. ") erz�hlt den Bewohnern von " .. u.region.name .. " von Muschelplateau, das die Partei " .. u.faction.name .. " vor " .. turns .. " Wochen besucht hat." ) - msg:send_region(u.region) - return 0 - end - return -4 -end - -function update_embassies() --- Muschelplateau - local r = get_region(165,30) - if r~=nil then - local u - for u in r.units do - if u.faction.objects:get("embassy_muschel")==nil then - if (u.faction:add_item("seashell", 1)>0) then - print(u.faction) - u.faction.objects:set("embassy_muschel", get_turn()) - end - end - end - end -end - +function use_seashell(u, amount) +-- Muschelplateau... + local r = get_region(165,30) + local visit = u.faction.objects:get("embassy_muschel") + if visit~=nil and u.region~= r then + local turns = get_turn() - visit + local msg = message.create("msg_event") + msg:set_string("string", u.name .. "(" .. itoa36(u.id) .. ") erz�hlt den Bewohnern von " .. u.region.name .. " von Muschelplateau, das die Partei " .. u.faction.name .. " vor " .. turns .. " Wochen besucht hat." ) + msg:send_region(u.region) + return 0 + end + return -4 +end + +function update_embassies() +-- Muschelplateau + local r = get_region(165,30) + if r~=nil then + local u + for u in r.units do + if u.faction.objects:get("embassy_muschel")==nil then + if (u.faction:add_item("seashell", 1)>0) then + print(u.faction) + u.faction.objects:set("embassy_muschel", get_turn()) + end + end + end + end +end + diff --git a/scripts/eressea/ents.lua b/scripts/eressea/ents.lua index 60532442d..fe07a94fc 100644 --- a/scripts/eressea/ents.lua +++ b/scripts/eressea/ents.lua @@ -1,32 +1,32 @@ - -local function create_ents(r, number) - local f = get_faction(0) - if f~=nil and number>0 then - u = add_unit(f, r) - u.number = number - u.name = "W�tende Ents" - u:set_skill("perception", 2) - - msg = message.create("entrise") - msg:set_region("region", r) - msg:send_region(r) - return u - end - return nil -end - -function spawn_ents() - local r - for r in regions() do - if r:get_flag(0) then -- RF_CHAOTIC - if r.terrain == "plain" and r:get_resource("tree")==0 then - if math.random(3)==1 then - u = create_ents(r, math.random(30)) - if u ~= nil then - r:set_resource("tree", u.number) - end - end - end - end - end -end + +local function create_ents(r, number) + local f = get_faction(0) + if f~=nil and number>0 then + u = add_unit(f, r) + u.number = number + u.name = "W�tende Ents" + u:set_skill("perception", 2) + + msg = message.create("entrise") + msg:set_region("region", r) + msg:send_region(r) + return u + end + return nil +end + +function spawn_ents() + local r + for r in regions() do + if r:get_flag(0) then -- RF_CHAOTIC + if r.terrain == "plain" and r:get_resource("tree")==0 then + if math.random(3)==1 then + u = create_ents(r, math.random(30)) + if u ~= nil then + r:set_resource("tree", u.number) + end + end + end + end + end +end diff --git a/scripts/eressea/eternath.lua b/scripts/eressea/eternath.lua index c421d3cce..0134127ab 100644 --- a/scripts/eressea/eternath.lua +++ b/scripts/eressea/eternath.lua @@ -1,18 +1,18 @@ -require "gates" - -local function eternath_exchange(b1, b2, size) - local units1 = gate_units(b1, size) - local units2 = gate_units(b2, size) - - gate_travel(b2, units1) - gate_travel(b1, units2) -end - -function eternathgate_action(b) - if eternathgate == nil then - eternathgate = b - else - eternath_exchange(eternathgate, b, 10) - end - return 1 -end +require "gates" + +local function eternath_exchange(b1, b2, size) + local units1 = gate_units(b1, size) + local units2 = gate_units(b2, size) + + gate_travel(b2, units1) + gate_travel(b1, units2) +end + +function eternathgate_action(b) + if eternathgate == nil then + eternathgate = b + else + eternath_exchange(eternathgate, b, 10) + end + return 1 +end diff --git a/scripts/eressea/igjaruk.lua b/scripts/eressea/igjaruk.lua index 24a095742..09b96328f 100644 --- a/scripts/eressea/igjaruk.lua +++ b/scripts/eressea/igjaruk.lua @@ -1,59 +1,59 @@ -function teleport_all(map, grave) - print("- teleporting all quest members to the grave") - local index - local r - for index, r in pairs(map) do - local u - for u in r.units do - u.region = grave - print (" .teleported " .. u.name) - grave:add_notice("Ein Portal �ffnet sich, und " .. u.name .. " erscheint in " .. grave.name) - end - end -end - -function wyrm() - print("- running the wyrm quest") - local grave = get_region(-9995,4) - local plane = get_plane_id("arena") - local map = {} - local mapsize = 0 - local r - - for r in regions() do - if r.plane_id==plane then - mapsize=mapsize+1 - map[mapsize] = r - end - end - - local u - for u in grave.units do - if u.faction.id~=atoi36("rr") then - teleport_all(map, grave) - break - end - end - - local index - local r - for index, r in pairs(map) do - if r~=grave then - if (math.mod(r.x,2)==math.mod(get_turn(),2)) then - r:add_notice("Eine Botschaft von Igjarjuk, Herr der Wyrme: 'Die Zeit des Wartens ist beinahe vorr�ber. Euer F�rst kehrt aus dem Grabe zur�ck.'") - else - r:add_notice("Eine Botschaft von Gwaewar, Herr der Greife: 'Das Ende naht. Igjarjuk ist aus seinem Grab auferstanden. Eilt, noch ist die Welt zu retten!'") - end - end - end - - local gryph=get_unit(atoi36("gfd4")) - local igjar=get_unit(atoi36("igjr")) - if grave~=nil and gryph~=nil and igjar~=nil then - gryph.region=grave - igjar.region=grave - grave:add_notice("Eine Botschaft von Gwaewar, Herr der Greife: 'Ihr, die Ihr die Strapazen der letzten Jahre �berstanden habt: Lasst nicht zu, dass Igjarjuk wieder in die Welt der Lebenden zur�ckkehrt. Vernichtet das Auge - jetzt und hier!'") - grave:add_notice("Eine Botschaft von Igjarjuk, Herr der Wyrme: 'Gwaewar, Du wirst dereinst an Deinem Glauben an das Gute in den Sterblichen verrecken... So wie ich es einst tat. Der Krieg ist die einzige Sprache die sie verstehen, und derjenige, der mir hilft, wird ihn gewinnen.'") - end - -end +function teleport_all(map, grave) + print("- teleporting all quest members to the grave") + local index + local r + for index, r in pairs(map) do + local u + for u in r.units do + u.region = grave + print (" .teleported " .. u.name) + grave:add_notice("Ein Portal �ffnet sich, und " .. u.name .. " erscheint in " .. grave.name) + end + end +end + +function wyrm() + print("- running the wyrm quest") + local grave = get_region(-9995,4) + local plane = get_plane_id("arena") + local map = {} + local mapsize = 0 + local r + + for r in regions() do + if r.plane_id==plane then + mapsize=mapsize+1 + map[mapsize] = r + end + end + + local u + for u in grave.units do + if u.faction.id~=atoi36("rr") then + teleport_all(map, grave) + break + end + end + + local index + local r + for index, r in pairs(map) do + if r~=grave then + if (math.mod(r.x,2)==math.mod(get_turn(),2)) then + r:add_notice("Eine Botschaft von Igjarjuk, Herr der Wyrme: 'Die Zeit des Wartens ist beinahe vorr�ber. Euer F�rst kehrt aus dem Grabe zur�ck.'") + else + r:add_notice("Eine Botschaft von Gwaewar, Herr der Greife: 'Das Ende naht. Igjarjuk ist aus seinem Grab auferstanden. Eilt, noch ist die Welt zu retten!'") + end + end + end + + local gryph=get_unit(atoi36("gfd4")) + local igjar=get_unit(atoi36("igjr")) + if grave~=nil and gryph~=nil and igjar~=nil then + gryph.region=grave + igjar.region=grave + grave:add_notice("Eine Botschaft von Gwaewar, Herr der Greife: 'Ihr, die Ihr die Strapazen der letzten Jahre �berstanden habt: Lasst nicht zu, dass Igjarjuk wieder in die Welt der Lebenden zur�ckkehrt. Vernichtet das Auge - jetzt und hier!'") + grave:add_notice("Eine Botschaft von Igjarjuk, Herr der Wyrme: 'Gwaewar, Du wirst dereinst an Deinem Glauben an das Gute in den Sterblichen verrecken... So wie ich es einst tat. Der Krieg ist die einzige Sprache die sie verstehen, und derjenige, der mir hilft, wird ihn gewinnen.'") + end + +end diff --git a/scripts/eressea/items.lua b/scripts/eressea/items.lua index 8f6ca2f8a..4a0a1d1a7 100644 --- a/scripts/eressea/items.lua +++ b/scripts/eressea/items.lua @@ -1,19 +1,19 @@ -function use_ring_of_levitation(u, amount) - if u.ship~=nil and amount>0 then - local mallorn = 0 - for u2 in u.region.units do - if u2.ship==u.ship then - local i = u2:get_item("mallornseed") - if i>0 then - u2:use_pooled("mallornseed", i) - u2:use_pooled("seed", i) - mallorn = mallorn + i - end - end - end - if mallorn>0 then - levitate_ship(u.ship, u, mallorn, 2) - end - end - return 0 -end +function use_ring_of_levitation(u, amount) + if u.ship~=nil and amount>0 then + local mallorn = 0 + for u2 in u.region.units do + if u2.ship==u.ship then + local i = u2:get_item("mallornseed") + if i>0 then + u2:use_pooled("mallornseed", i) + u2:use_pooled("seed", i) + mallorn = mallorn + i + end + end + end + if mallorn>0 then + levitate_ship(u.ship, u, mallorn, 2) + end + end + return 0 +end diff --git a/scripts/eressea/main.lua b/scripts/eressea/main.lua index 060fdbf8c..5545d9a14 100644 --- a/scripts/eressea/main.lua +++ b/scripts/eressea/main.lua @@ -1,63 +1,63 @@ -require "multis" - -function apply_fixes() - local turn = get_turn() - if config.game=="eressea" and turn>654 and turn<662 then - print("Fixing familiars") - fix_familiars() - end -end - -function process(orders) - local confirmed_multis = { } - local suspected_multis = { } - - if open_game(get_turn())~=0 then - print("could not read game") - return -1 - end - apply_fixes() - init_summary() - - -- kill multi-players (external script) - kill_multis(confirmed_multis, false) - mark_multis(suspected_multis, false) - - -- run the turn: - if read_orders(orders) ~= 0 then - print("could not read " .. orders) - return -1 - end - - plan_monsters() - - if nmr_check(config.maxnmrs or 80)~=0 then - return -1 - end - - process_orders() - - -- create new monsters: - spawn_dragons() - spawn_undead() - spawn_braineaters(0.25) - spawn_ents() - - -- post-turn updates: - update_xmas2006() - update_embassies() - update_guards() - update_scores() - - local localechange = { de = { "ii" } } - change_locales(localechange) - - write_files(config.locales) - - file = "" .. get_turn() .. ".dat" - if write_game(file, "binary")~=0 then - print("could not write game") - return -1 - end - return 0 -end +require "multis" + +function apply_fixes() + local turn = get_turn() + if config.game=="eressea" and turn>654 and turn<662 then + print("Fixing familiars") + fix_familiars() + end +end + +function process(orders) + local confirmed_multis = { } + local suspected_multis = { } + + if open_game(get_turn())~=0 then + print("could not read game") + return -1 + end + apply_fixes() + init_summary() + + -- kill multi-players (external script) + kill_multis(confirmed_multis, false) + mark_multis(suspected_multis, false) + + -- run the turn: + if read_orders(orders) ~= 0 then + print("could not read " .. orders) + return -1 + end + + plan_monsters() + + if nmr_check(config.maxnmrs or 80)~=0 then + return -1 + end + + process_orders() + + -- create new monsters: + spawn_dragons() + spawn_undead() + spawn_braineaters(0.25) + spawn_ents() + + -- post-turn updates: + update_xmas2006() + update_embassies() + update_guards() + update_scores() + + local localechange = { de = { "ii" } } + change_locales(localechange) + + write_files(config.locales) + + file = "" .. get_turn() .. ".dat" + if write_game(file, "binary")~=0 then + print("could not write game") + return -1 + end + return 0 +end diff --git a/scripts/eressea/modules.lua b/scripts/eressea/modules.lua index aa6c14114..719dcbd20 100644 --- a/scripts/eressea/modules.lua +++ b/scripts/eressea/modules.lua @@ -1,21 +1,21 @@ -require "spells" -require "gates" -require "eressea.alp" -require "eressea.eternath" -require "eressea.wedding-jadee" -require "eressea.ponnuki" -require "eressea.items" -require "eressea.rules" --- require "eressea.10years" -require "eressea.xmas2004" -require "eressea.xmas2005" -require "eressea.xmas2006" -require "eressea.embassy" -require "eressea.tunnels" -require "eressea.ents" - -local srcpath = config.source_dir -tests = { - srcpath .. '/server/scripts/tests/common.lua', - srcpath .. '/eressea/scripts/tests/eressea.lua', -} +require "spells" +require "gates" +require "eressea.alp" +require "eressea.eternath" +require "eressea.wedding-jadee" +require "eressea.ponnuki" +require "eressea.items" +require "eressea.rules" +-- require "eressea.10years" +require "eressea.xmas2004" +require "eressea.xmas2005" +require "eressea.xmas2006" +require "eressea.embassy" +require "eressea.tunnels" +require "eressea.ents" + +local srcpath = config.source_dir +tests = { + srcpath .. '/server/scripts/tests/common.lua', + srcpath .. '/eressea/scripts/tests/eressea.lua', +} diff --git a/scripts/eressea/ponnuki.lua b/scripts/eressea/ponnuki.lua index 95d121cc5..348549c33 100644 --- a/scripts/eressea/ponnuki.lua +++ b/scripts/eressea/ponnuki.lua @@ -1,42 +1,42 @@ -function ponnuki_brain(u) - jokes = { - "Ein Bummerang ist, wenn man ihn wegwirft und er kommt nicht wieder, dann war's keiner.", - - "Merke: Mit Schwabenwitzen soll man ganz sparsam sein.", - - "Was bekommt man, wenn man Katzen und Elfen kreuzt? Elfen ohne Rheuma.", - - "Was bekommt man, wenn man Insekten und Katzen kreuzt? Tiger, die Crisan benutzen." - } - local i = math.random(table.getn(jokes)) - u.region:add_notice(jokes[i]) - local d = math.random(6) - r = u.region:next(d-1) - u:clear_orders() - directions = { "NW", "NO", "O", "SO", "SW", "W" } - u:add_order("NACH " .. directions[d]) -end - -local function init_ponnuki(home) - local f = get_faction(0) - local u = get_unit(atoi36("ponn")) - if u == nil then - u = add_unit(f, home) - u.id = atoi36("ponn") - u.name = "Ponnuki" - u.info = "Go, Ponnuki, Go!" - u.race = "illusion" - u:set_racename("Ritter von Go") - end - if u.faction==f then - set_unit_brain(u, ponnuki_brain) - end -end - --- initialize other scripts -local magrathea = get_region(-67, -5) -if magrathea~=nil and init_ponnuki~=nil then - init_ponnuki(magrathea) - return -end - +function ponnuki_brain(u) + jokes = { + "Ein Bummerang ist, wenn man ihn wegwirft und er kommt nicht wieder, dann war's keiner.", + + "Merke: Mit Schwabenwitzen soll man ganz sparsam sein.", + + "Was bekommt man, wenn man Katzen und Elfen kreuzt? Elfen ohne Rheuma.", + + "Was bekommt man, wenn man Insekten und Katzen kreuzt? Tiger, die Crisan benutzen." + } + local i = math.random(table.getn(jokes)) + u.region:add_notice(jokes[i]) + local d = math.random(6) + r = u.region:next(d-1) + u:clear_orders() + directions = { "NW", "NO", "O", "SO", "SW", "W" } + u:add_order("NACH " .. directions[d]) +end + +local function init_ponnuki(home) + local f = get_faction(0) + local u = get_unit(atoi36("ponn")) + if u == nil then + u = add_unit(f, home) + u.id = atoi36("ponn") + u.name = "Ponnuki" + u.info = "Go, Ponnuki, Go!" + u.race = "illusion" + u:set_racename("Ritter von Go") + end + if u.faction==f then + set_unit_brain(u, ponnuki_brain) + end +end + +-- initialize other scripts +local magrathea = get_region(-67, -5) +if magrathea~=nil and init_ponnuki~=nil then + init_ponnuki(magrathea) + return +end + diff --git a/scripts/eressea/rules.lua b/scripts/eressea/rules.lua index 5866a8ffc..9b3706a55 100644 --- a/scripts/eressea/rules.lua +++ b/scripts/eressea/rules.lua @@ -1,8 +1,8 @@ -function item_canuse(u, iname) - local race = u.race - if iname=="greatbow" then - -- only elves use greatbow - return race=="elf" - end - return true -end +function item_canuse(u, iname) + local race = u.race + if iname=="greatbow" then + -- only elves use greatbow + return race=="elf" + end + return true +end diff --git a/scripts/eressea/tunnels.lua b/scripts/eressea/tunnels.lua index 283cbab5b..623f8e951 100644 --- a/scripts/eressea/tunnels.lua +++ b/scripts/eressea/tunnels.lua @@ -1,62 +1,62 @@ -local function tunnel_travelers(b) - local units = nil - for u in b.units do - if units==nil then - units = {} - end - units[u] = u - end - return units -end - -targets = nil -ntargets = 0 - -local function get_target(param) - -- print("finding targets: " .. param) - if targets == nil then - targets = {} - local r - for r in regions() do - if r:get_key(param) then - if (r:get_flag(0)) then - r:set_flag(0, false) - end - if (r.terrain=="ocean") then - r = region.create(r.x, r.y, "plain") - end - targets[ntargets] = r - ntargets = ntargets + 1 - -- print("target: " .. tostring(r)) - end - end - end - if ntargets==0 then - return nil - end - local rn = math.mod(rng_int(), ntargets) - return targets[rn] -end - --- export, will be called from lc_age() -function tunnel_action(b, param) - local r = nil - if tonumber(param)~=nil then - r = get_region_by_id(tonumber(param)) - end - local units = tunnel_travelers(b) - if units~=nil then - print("Tunnel from " .. tostring(b) .. " [" .. param .. "]") - for key, u in pairs(units) do - local rto = r - if r==nil then - rto = get_target(param) - end - if rto~=nil then - u.region = rto - print(" - teleported " .. tostring(u) .. " to " .. tostring(rto)) - end - end - end - return 1 -- return 0 to destroy -end +local function tunnel_travelers(b) + local units = nil + for u in b.units do + if units==nil then + units = {} + end + units[u] = u + end + return units +end + +targets = nil +ntargets = 0 + +local function get_target(param) + -- print("finding targets: " .. param) + if targets == nil then + targets = {} + local r + for r in regions() do + if r:get_key(param) then + if (r:get_flag(0)) then + r:set_flag(0, false) + end + if (r.terrain=="ocean") then + r = region.create(r.x, r.y, "plain") + end + targets[ntargets] = r + ntargets = ntargets + 1 + -- print("target: " .. tostring(r)) + end + end + end + if ntargets==0 then + return nil + end + local rn = math.mod(rng_int(), ntargets) + return targets[rn] +end + +-- export, will be called from lc_age() +function tunnel_action(b, param) + local r = nil + if tonumber(param)~=nil then + r = get_region_by_id(tonumber(param)) + end + local units = tunnel_travelers(b) + if units~=nil then + print("Tunnel from " .. tostring(b) .. " [" .. param .. "]") + for key, u in pairs(units) do + local rto = r + if r==nil then + rto = get_target(param) + end + if rto~=nil then + u.region = rto + print(" - teleported " .. tostring(u) .. " to " .. tostring(rto)) + end + end + end + return 1 -- return 0 to destroy +end diff --git a/scripts/eressea/wedding-jadee.lua b/scripts/eressea/wedding-jadee.lua index f7a671c7a..761d4d2df 100644 --- a/scripts/eressea/wedding-jadee.lua +++ b/scripts/eressea/wedding-jadee.lua @@ -1,47 +1,47 @@ --- this script contains the action functions for the two portals --- used on the jadee/wildente wedding island. the two _action functions --- are used as age() functions for a building_action with b:addaction("name") - -if gate_travel==nil then - loadscript("gates.lua") -end - -hellgate = nil -peacegate = nil - -local function wedding_travellers(b) - local units = {} - - for u in b.units do - if u:get_flag("wdgt") then - units[u] = u - end - end - return units -end - -local function wedding_exchange(b1, b2) - local units1 = wedding_travellers(b1) - local units2 = wedding_travellers(b2) - - gate_travel(b2, units1) - gate_travel(b1, units2) -end - -function hellgate_action(b) - if hellgate == nil then - hellgate = b - else - wedding_exchange(hellgate, b) - end - return 1 -end - -function peacegate_action(b) - if peacegate == nil then - peacegate = b - else - wedding_exchange(peacegate, b) - end - return 1 -end +-- this script contains the action functions for the two portals +-- used on the jadee/wildente wedding island. the two _action functions +-- are used as age() functions for a building_action with b:addaction("name") + +if gate_travel==nil then + loadscript("gates.lua") +end + +hellgate = nil +peacegate = nil + +local function wedding_travellers(b) + local units = {} + + for u in b.units do + if u:get_flag("wdgt") then + units[u] = u + end + end + return units +end + +local function wedding_exchange(b1, b2) + local units1 = wedding_travellers(b1) + local units2 = wedding_travellers(b2) + + gate_travel(b2, units1) + gate_travel(b1, units2) +end + +function hellgate_action(b) + if hellgate == nil then + hellgate = b + else + wedding_exchange(hellgate, b) + end + return 1 +end + +function peacegate_action(b) + if peacegate == nil then + peacegate = b + else + wedding_exchange(peacegate, b) + end + return 1 +end diff --git a/scripts/eressea/xmas2004.lua b/scripts/eressea/xmas2004.lua index 6a6bcfa63..e6fb9776b 100644 --- a/scripts/eressea/xmas2004.lua +++ b/scripts/eressea/xmas2004.lua @@ -1,25 +1,25 @@ -function use_snowman(u, amount) - if u.region.terrain == "glacier" then - local man = add_unit(u.faction, u.region) - man.race = "snowman" - man.number = amount - u:add_item("snowman", -amount) - return 0 - end - return -4 -end - -function xmas2004() - if get_gamename() == "Eressea" then - if not get_key("xm04") then - print("Es weihnachtet sehr (2004)") - set_key("xm04", true) - for f in factions() do - f:add_item("speedsail", 1) - f:add_notice("santa2004") - end - end - end -end - --- xmas2004() +function use_snowman(u, amount) + if u.region.terrain == "glacier" then + local man = add_unit(u.faction, u.region) + man.race = "snowman" + man.number = amount + u:add_item("snowman", -amount) + return 0 + end + return -4 +end + +function xmas2004() + if get_gamename() == "Eressea" then + if not get_key("xm04") then + print("Es weihnachtet sehr (2004)") + set_key("xm04", true) + for f in factions() do + f:add_item("speedsail", 1) + f:add_notice("santa2004") + end + end + end +end + +-- xmas2004() diff --git a/scripts/eressea/xmas2005.lua b/scripts/eressea/xmas2005.lua index cde00f65b..937e1ecbf 100644 --- a/scripts/eressea/xmas2005.lua +++ b/scripts/eressea/xmas2005.lua @@ -1,31 +1,31 @@ -function usepotion_message(u, potion) - msg = message.create("usepotion") - msg:set_unit("unit", u) - msg:set_resource("potion", potion) - return msg -end - -function use_stardust(u, amount) - local p = u.region:get_resource("peasant") - p = math.ceil(1.5 * p) - u.region:set_resource("peasant", p) - local msg = usepotion_message(u, "stardust") - msg:send_region(u.region) - u:use_pooled("stardust", amount) - return 0 -end - -function xmas2005() - if get_gamename() == "Eressea" then - if not get_flag("xm05") then - print("Es weihnachtet sehr (2005)") - set_flag("xm05", true) - for f in factions() do - f:add_item("stardust", 1) - f:add_notice("santa2005") - end - end - end -end - --- xmas2005() +function usepotion_message(u, potion) + msg = message.create("usepotion") + msg:set_unit("unit", u) + msg:set_resource("potion", potion) + return msg +end + +function use_stardust(u, amount) + local p = u.region:get_resource("peasant") + p = math.ceil(1.5 * p) + u.region:set_resource("peasant", p) + local msg = usepotion_message(u, "stardust") + msg:send_region(u.region) + u:use_pooled("stardust", amount) + return 0 +end + +function xmas2005() + if get_gamename() == "Eressea" then + if not get_flag("xm05") then + print("Es weihnachtet sehr (2005)") + set_flag("xm05", true) + for f in factions() do + f:add_item("stardust", 1) + f:add_notice("santa2005") + end + end + end +end + +-- xmas2005() diff --git a/scripts/eressea/xmas2006.lua b/scripts/eressea/xmas2006.lua index fa3ec251b..e76d0c7a0 100644 --- a/scripts/eressea/xmas2006.lua +++ b/scripts/eressea/xmas2006.lua @@ -1,54 +1,54 @@ -function use_xmastree(u, amount) - u.region:set_key("xm06", true) - u:use_pooled("xmastree", amount) - local msg = message.create("usepotion") - msg:set_unit("unit", u) - msg:set_resource("potion", "xmastree") - msg:send_region(u.region) - return 0 -end - -function update_xmas2006() - local turn = get_turn() - local season = get_season(turn) - if season == "calendar::winter" then - print("it is " .. season .. ", the christmas trees do their magic") - local msg = message.create("xmastree_effect") - for r in regions() do - if r:get_key("xm06") then - trees = r:get_resource("tree") - if trees*0.1>=1 then - r:set_resource("tree", trees * 1.1) - msg:send_region(r) - end - if clear then - end - end - end - else - local prevseason = get_season(turn-1) - if prevseason == "calendar::winter" then - -- we celebrate knut and kick out the trees. - for r in regions() do - if r:get_key("xm06") then - r:set_key("xm06", false) - end - end - end - end -end - -function xmas2006() - if get_gamename() == "Eressea" then - if not get_key("xm06") then - print("Es weihnachtet sehr (2006)") - set_key("xm06", true) - for f in factions() do - f:add_item("xmastree", 1) - f:add_notice("santa2006") - end - end - end -end - --- xmas2006() +function use_xmastree(u, amount) + u.region:set_key("xm06", true) + u:use_pooled("xmastree", amount) + local msg = message.create("usepotion") + msg:set_unit("unit", u) + msg:set_resource("potion", "xmastree") + msg:send_region(u.region) + return 0 +end + +function update_xmas2006() + local turn = get_turn() + local season = get_season(turn) + if season == "calendar::winter" then + print("it is " .. season .. ", the christmas trees do their magic") + local msg = message.create("xmastree_effect") + for r in regions() do + if r:get_key("xm06") then + trees = r:get_resource("tree") + if trees*0.1>=1 then + r:set_resource("tree", trees * 1.1) + msg:send_region(r) + end + if clear then + end + end + end + else + local prevseason = get_season(turn-1) + if prevseason == "calendar::winter" then + -- we celebrate knut and kick out the trees. + for r in regions() do + if r:get_key("xm06") then + r:set_key("xm06", false) + end + end + end + end +end + +function xmas2006() + if get_gamename() == "Eressea" then + if not get_key("xm06") then + print("Es weihnachtet sehr (2006)") + set_key("xm06", true) + for f in factions() do + f:add_item("xmastree", 1) + f:add_notice("santa2006") + end + end + end +end + +-- xmas2006() diff --git a/scripts/tests/castles.lua b/scripts/tests/castles.lua index f37955d98..79ad619d6 100644 --- a/scripts/tests/castles.lua +++ b/scripts/tests/castles.lua @@ -1,27 +1,27 @@ -require "lunit" - -module( "castles", package.seeall, lunit.testcase ) - -function setup() - free_game() -end - -function test_small_castles() - local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f1, r, 1) - local f2 = faction.create("noreply@eressea.de", "halfling", "de") - local u2 = unit.create(f2, r, 1) - u1:add_item("money", 10000) - - local b = building.create(r, "castle") - u2.building = b - u1.building = b - - b.owner = u2 - assert_equal("site", b:get_typename(7)) - assert_equal("fortification", b:get_typename(8)) - b.owner = u1 - assert_equal("site", b:get_typename(9)) - assert_equal("fortification", b:get_typename(10)) -end +require "lunit" + +module( "castles", package.seeall, lunit.testcase ) + +function setup() + free_game() +end + +function test_small_castles() + local r = region.create(0, 0, "plain") + local f1 = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f1, r, 1) + local f2 = faction.create("noreply@eressea.de", "halfling", "de") + local u2 = unit.create(f2, r, 1) + u1:add_item("money", 10000) + + local b = building.create(r, "castle") + u2.building = b + u1.building = b + + b.owner = u2 + assert_equal("site", b:get_typename(7)) + assert_equal("fortification", b:get_typename(8)) + b.owner = u1 + assert_equal("site", b:get_typename(9)) + assert_equal("fortification", b:get_typename(10)) +end diff --git a/scripts/tests/e3a.lua b/scripts/tests/e3a.lua index 17b4d08b8..4486ed9df 100644 --- a/scripts/tests/e3a.lua +++ b/scripts/tests/e3a.lua @@ -1,595 +1,595 @@ -require "lunit" - -module( "e3", package.seeall, lunit.testcase ) - -function setup() - free_game() -end - -function has_attrib(u, value) - for a in u.attribs do - if (a.data==value) then return true end - end - return false -end - -function test_attrib() - local r = region.create(0,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - local u2 = unit.create(f, r, 1) - data = { arr = { 'a', 'b', 'c' }, name = 'familiar', events = { die = 'familiar_died' }, data = { mage = u2 } } - a = { 'a' } - b = { 'a' } - uno = u.id - u2no = u2.id - a = attrib.create(u, 12) - a = attrib.create(u, "enno") - a = attrib.create(u, u2) - a = attrib.create(u, data) - write_game("attrib.dat") - free_game() - read_game("attrib.dat") - u = get_unit(uno) - u2 = get_unit(u2no) - assert_false(has_attrib(u, 42)) - assert_true(has_attrib(u, "enno")) - assert_true(has_attrib(u, 12)) - - for a in u.attribs do - x = a.data - if (type(x)=="table") then - assert_equal('a', x.arr[1]) - assert_equal('familiar', x.name) - assert_equal('familiar_died', x.events.die) - assert_equal(u2, x.data.mage) - break - end - end -end - -function test_seecast() - local r = region.create(0,0, "plain") - for i = 1,10 do - -- this prevents storms (only high seas have storms) - region.create(i, 1, "plain") - end - for i = 1,10 do - region.create(i, 0, "ocean") - end - local f = faction.create("noreply@eressea.de", "human", "de") - local s1 = ship.create(r, "cutter") - local u1 = unit.create(f, r, 2) - u1:set_skill("sailing", 3) - u1:add_item("money", 1000) - u1.ship = s1 - local u2 = unit.create(f, r, 1) - u2.race = "elf" - u2:set_skill("magic", 6) - u2.magic = "gwyrrd" - u2.aura = 60 - u2.ship = s1 - u2:add_spell("stormwinds") - update_owners() - u2:clear_orders() - u2:add_order("Zaubere stufe 2 'Beschwoere einen Sturmelementar' " .. itoa36(s1.id)) - u1:clear_orders() - u1:add_order("NACH O O O O") - process_orders() - assert_equal(4, u2.region.x) - - u2:clear_orders() - u2:add_spell("stormwinds") - u2:add_order("Zaubere stufe 2 'Beschwoere einen Sturmelementar' " .. itoa36(s1.id)) - u1:clear_orders() - u1:add_order("NACH O O O O") - process_orders() - write_reports() - assert_equal(8, u2.region.x) -end - -local function use_tree(terrain) - local r = region.create(0,0, terrain) - local f = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f, r, 5) - r:set_resource("tree", 0) - u1:add_item("xmastree", 1) - u1:clear_orders() - u1:add_order("BENUTZEN 1 Weihnachtsbaum") - process_orders() - return r -end - -function test_xmas2009() - local r = region.create(0,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f, r, 1) - process_orders() - xmas2009() - assert_equal("xmastree", f.items()) -end - -function test_xmastree() - local r - r = use_tree("ocean") - assert_equal(0, r:get_resource("tree")) - free_game() - r = use_tree("plain") - assert_equal(10, r:get_resource("tree")) -end - -function test_fishing() - local r = region.create(0,0, "ocean") - local r2 = region.create(1,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local s1 = ship.create(r, "cutter") - local u1 = unit.create(f, r, 3) - u1.ship = s1 - u1:set_skill("sailing", 10) - u1:add_item("money", 100) - u1:clear_orders() - u1:add_order("NACH O") - update_owners() - - process_orders() - assert_equal(r2.id, u1.region.id) - assert_equal(90, u1:get_item("money")) - - u1:clear_orders() - u1:add_order("NACH W") - - process_orders() - assert_equal(60, u1:get_item("money")) -end - -function test_ship_capacity() - local r = region.create(0,0, "ocean") - region.create(1,0, "ocean") - local r2 = region.create(2,0, "ocean") - local f = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "goblin", "de") - - -- u1 is at the limit and moves - local s1 = ship.create(r, "cutter") - local u1 = unit.create(f, r, 5) - u1.ship = s1 - u1:set_skill("sailing", 10) - u1:add_item("sword", 55) - u1:clear_orders() - u1:add_order("NACH O O") - - -- u2 has too many people - local s2 = ship.create(r, "cutter") - local u2 = unit.create(f, r, 6) - u2.ship = s2 - u2:set_skill("sailing", 10) - u2:clear_orders() - u2:add_order("NACH O O") - - -- u3 has goblins, they weigh 40% less - local s3 = ship.create(r, "cutter") - local u3 = unit.create(f2, r, 8) - u3.ship = s3 - u3:set_skill("sailing", 10) - u3:add_item("sword", 55) - u3:clear_orders() - u3:add_order("NACH O O") - - -- u4 has too much stuff - local s4 = ship.create(r, "cutter") - local u4 = unit.create(f, r, 5) - u4.ship = s4 - u4:set_skill("sailing", 10) - u4:add_item("sword", 56) - u4:clear_orders() - u4:add_order("NACH O O") - - update_owners() - process_orders() - assert_equal(r2.id, u1.region.id) - assert_not_equal(r2.id, u2.region.id) - assert_equal(r2.id, u3.region.id) - assert_not_equal(r2.id, u4.region.id) -end - -function test_owners() - local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f1, r, 1) - local f2 = faction.create("noreply@eressea.de", "human", "de") - local u2 = unit.create(f2, r, 1) - local u3 = unit.create(f2, r, 1) - - local b3 = building.create(r, "castle") - b3.size = 2 - u3.building = b3 - local b1 = building.create(r, "castle") - b1.size = 1 - u1.building = b1 - local b2 = building.create(r, "castle") - b2.size = 2 - u2.building = b2 - - update_owners() - assert(r.owner==u3.faction) - b1.size=3 - b2.size=3 - update_owners() - assert(r.owner==u2.faction) - b1.size=4 - update_owners() - assert(r.owner==u1.faction) -end - -function test_taxes() - local r = region.create(0, 0, "plain") - r:set_resource("peasant", 1000) - r:set_resource("money", 5000) - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u:add_item("money", u.number * 10) - u:clear_orders() - u:add_order("LERNE Holzfaellen") -- do not work - local b = building.create(r, "watch") - b.size = 10 - u.building = b - update_owners() - assert_equal(1, r.morale) - process_orders() - assert_equal(1, r.morale) - assert_equal(25, u:get_item("money")) -end - -function test_leave() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - f.id = 42 - local b1 = building.create(r, "castle") - b1.size = 10 - local b2 = building.create(r, "lighthouse") - b2.size = 10 - local u = unit.create(f, r, 1) - u.building = b1 - assert_not_equal(nil, u.building) - u:add_item("money", u.number * 100) - u:clear_orders() - u:add_order("BETRETE BURG " .. itoa36(b2.id)) - update_owners() - process_orders() - assert_equal(u.building.id, b1.id, "region owner has left the building") -- region owners may not leave -end - -function test_market() - -- if i am the only trader around, i should be getting all the herbs from all 7 regions - local herb_multi = 500 -- from rc_herb_trade() - local r, idx - local herbnames = { 'h0', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8' } - idx = 1 - for x = -1, 1 do for y = -1, 1 do - r = region.create(x, y, "plain") - r:set_resource("peasant", herb_multi * 9 + 50) -- 10 herbs per region - r.herb = herbnames[idx] - idx = idx+1 - end end - r = get_region(0, 0) - local b = building.create(r, "market") - b.size = 10 - local f = faction.create("noreply@eressea.de", "human", "de") - f.id = 42 - local u = unit.create(f, r, 1) - u.building = b - u:add_item("money", u.number * 10000) - for i = 0, 5 do - local rn = r:next(i) - end - process.markets() - u:add_item("money", -u:get_item("money")) -- now we only have herbs - local len = 0 - for i in u.items do - len = len + 1 - end - assert_not_equal(0, len, "trader did not get any herbs") - for idx, name in pairs(herbnames) do - local n = u:get_item(name) - if n>0 then - assert_equal(10, n, 'trader did not get exaxtly 10 herbs') - end - end -end - -function test_market_gives_items() - local r - for x = -1, 1 do for y = -1, 1 do - r = region.create(x, y, "plain") - r:set_resource("peasant", 5000) - end end - r = get_region(0, 0) - local b = building.create(r, "market") - b.size = 10 - local f = faction.create("noreply@eressea.de", "human", "de") - f.id = 42 - local u = unit.create(f, r, 1) - u.building = b - u:add_item("money", u.number * 10000) - for i = 0, 5 do - local rn = r:next(i) - end - process_orders() - local len = 0 - for i in u.items do - len = len + 1 - end - assert(len>1) -end - -function test_spells() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - u.race = "elf" - u:clear_orders() - u:add_item("money", 10000) - u:set_skill("magic", 5) - u:add_order("LERNE MAGIE Illaun") - process_orders() - local sp - local nums = 0 - if f.spells~=nil then - for sp in f.spells do - nums = nums + 1 - end - assert(nums>0) - for sp in u.spells do - nums = nums - 1 - end - assert(nums==0) - else - for sp in u.spells do - nums = nums + 1 - end - assert(nums>0) - end -end - -function test_alliance() - local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f1, r, 1) - u1:add_item("money", u1.number * 100) - local f2 = faction.create("info@eressea.de", "human", "de") - local u2 = unit.create(f2, r, 1) - u2:add_item("money", u2.number * 100) - assert(f1.alliance==nil) - assert(f2.alliance==nil) - u1:clear_orders() - u2:clear_orders() - u1:add_order("ALLIANZ NEU pink") - u1:add_order("ALLIANZ EINLADEN " .. itoa36(f2.id)) - u2:add_order("ALLIANZ BEITRETEN pink") - process_orders() - assert(f1.alliance~=nil) - assert(f2.alliance~=nil) - assert(f2.alliance==f1.alliance) - u1:clear_orders() - u2:clear_orders() - u1:add_order("ALLIANZ KOMMANDO " .. itoa36(f2.id)) - process_orders() - assert(f1.alliance~=nil) - assert(f2.alliance~=nil) - assert(f2.alliance==f1.alliance) - u1:clear_orders() - u2:clear_orders() - u2:add_order("ALLIANZ AUSSTOSSEN " .. itoa36(f1.id)) - process_orders() - assert(f1.alliance==nil) - assert(f2.alliance~=nil) - u1:clear_orders() - u2:clear_orders() - u2:add_order("ALLIANZ NEU zing") - u1:add_order("ALLIANZ BEITRETEN zing") -- no invite! - process_orders() - assert(f1.alliance==nil) - assert(f2.alliance~=nil) - u1:clear_orders() - u2:clear_orders() - u1:add_order("ALLIANZ NEU zack") - u1:add_order("ALLIANZ EINLADEN " .. itoa36(f2.id)) - u2:add_order("ALLIANZ BEITRETEN zack") - process_orders() - assert(f1.alliance==f2.alliance) - assert(f2.alliance~=nil) -end - -function test_canoe_passes_through_land() - local f = faction.create("noreply@eressea.de", "human", "de") - local src = region.create(0, 0, "ocean") - local land = region.create(1, 0, "plain") - region.create(2, 0, "ocean") - local dst = region.create(3, 0, "ocean") - local sh = ship.create(src, "canoe") - local u1, u2 = two_units(src, f, f) - u1.ship = sh - u2.ship = sh - u1:set_skill("sailing", 10) - u1:clear_orders() - u1:add_order("NACH O O O") - process_orders() - assert_equal(u2.region.id, land.id, "canoe did not stop at coast") - u1:add_order("NACH O O O") - process_orders() - assert_equal(u2.region.id, dst.id, "canoe could not leave coast") -end - -function test_give_50_percent_of_money() - local u1, u2 = two_units(region.create(0, 0, "plain"), two_factions()) - local r = u2.region - u1.faction.age = 10 - u2.faction.age = 10 - u1:add_item("money", 500) - local m1, m2 = u1:get_item("money"), u2:get_item("money") - u1:clear_orders() - u1:add_order("GIB " .. itoa36(u2.id) .. " 221 Silber") - u2:clear_orders() - u2:add_order("LERNEN Hiebwaffen") - process_orders() - assert(u1:get_item("money")==m1-10*u1.number) - assert(u2:get_item("money")==m2-10*u2.number) - - m1, m2 = u1:get_item("money"), u2:get_item("money") - u1:clear_orders() - u1:add_order("GIB " .. itoa36(u2.id) .. " 221 Silber") - u2:clear_orders() - u2:add_order("HELFEN " .. itoa36(u1.faction.id) .. " GIB") - u2:add_item("horse", 100) - u2:add_order("GIB 0 ALLES PFERD") - local h = r:get_resource("horse") - process_orders() - assert(r:get_resource("horse")>=h+100) - assert_equal(m1-221-10*u1.number, u1:get_item("money")) - assert_equal(m2+110-10*u2.number, u2:get_item("money")) -end - -function test_give_100_percent_of_items() - local u1, u2 = two_units(region.create(0, 0, "plain"), two_factions()) - local r = u2.region - u1.faction.age = 10 - u2.faction.age = 10 - u1:add_item("money", 500) - u1:add_item("log", 500) - local m1, m2 = u1:get_item("log"), u2:get_item("log") - u1:clear_orders() - u1:add_order("GIB " .. itoa36(u2.id) .. " 332 Holz") - u2:clear_orders() - u2:add_order("LERNEN Hiebwaffen") - u2:add_order("HELFEN " .. itoa36(u1.faction.id) .. " GIB") - process_orders() - assert_equal(m1-332, u1:get_item("log")) - assert_equal(m2+332, u2:get_item("log")) -end - -function test_cannot_give_person() - local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f1, r, 10) - local u2 = unit.create(f2, r, 10) - u1.faction.age = 10 - u2.faction.age = 10 - u1:add_item("money", 500) - u2:add_item("money", 500) - u2:clear_orders() - u2:add_order("GIB ".. itoa36(u1.id) .. " 1 PERSON") - u2:add_order("HELFE ".. itoa36(f1.id) .. " GIB") - u1:add_order("HELFE ".. itoa36(f2.id) .. " GIB") - process_orders() - assert_equal(10, u2.number) - assert_equal(10, u1.number) -end - -function test_cannot_give_unit() - local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f1, r, 10) - local u2 = unit.create(f2, r, 10) - u1.faction.age = 10 - u2.faction.age = 10 - u1:add_item("money", 500) - u2:add_item("money", 500) - u2:clear_orders() - u2:add_order("GIB ".. itoa36(u1.id) .. " EINHEIT") - u2:add_order("HELFE ".. itoa36(f1.id) .. " GIB") - u1:add_order("HELFE ".. itoa36(f2.id) .. " GIB") - process_orders() - assert_not_equal(u2.faction.id, u1.faction.id) -end - -function test_guard_by_owners() - -- http://bugs.eressea.de/view.php?id=1756 - local r = region.create(0,0, "mountain") - local f1 = faction.create("noreply@eressea.de", "human", "de") - f1.age=20 - local f2 = faction.create("noreply@eressea.de", "human", "de") - f2.age=20 - local u1 = unit.create(f1, r, 1) - local b = building.create(r, "castle") - b.size = 10 - u1.building = b - u1:add_item("money", 100) - - local u2 = unit.create(f2, r, 1) - u2:add_item("money", 100) - u2:set_skill("mining", 3) - u2:clear_orders() - u2:add_order("MACHEN EISEN") - - process_orders() - local iron = u2:get_item("iron") - process_orders() - assert_equal(iron, u2:get_item("iron")) -end - -function test_market_action() - local f = faction.create("noreply@eressea.de", "human", "de") - local x, y, r - for x=0,2 do - for y=0,2 do - r = region.create(x, y, "plain") - r.luxury = "balm" - r.herb = "h2" - r:set_resource("peasant", 5000) - end - end - r = get_region(1, 1) - local u = unit.create(f, r, 1) - b = building.create(r, "market") - b.size = 10 - u.building = b - update_owners() - for r in regions() do - market_action(r) - end - assert_equal(35, u:get_item("balm")) - assert_equal(70, u:get_item("h2")) -end - --- function test_process_execute() - -- local i = 0 - -- local f = faction.create("noreply@eressea.de", "human", "de") - -- local r = region.create(0, 0, "plain") - -- local u = unit.create(f, r, 1) - -- local r1, u1 - - -- function a() i = 2 end - -- function b() i = i * 2 end - -- function c(r) r1 = r i = i + 1 end - -- function d(u) u1 = u i = i * 3 end - -- process.execute({a, b}, {c}, {d}) - -- assert_equal(15, i) - -- assert_equal(r, r1) - -- assert_equal(u, u1) --- end - --- function test_new_orders() - -- local i = 0 - -- local f = faction.create("noreply@eressea.de", "human", "de") - -- local r = region.create(0, 0, "plain") - -- local u = unit.create(f, r, 1) - -- local r1, u1 - - -- function a() i = 2 end - -- function b() i = i * 2 end - -- function c(r) r1 = r i = i + 1 end - -- function d(u) u1 = u i = i * 3 end - - -- process.setup() - -- process.push(a) - -- process.push(b) - -- process.push(c, "region") - -- process.push(d, "unit") - -- process.start() - - -- assert_equal(15, i) - -- assert_equal(r, r1) - -- assert_equal(u, u1) --- end +require "lunit" + +module( "e3", package.seeall, lunit.testcase ) + +function setup() + free_game() +end + +function has_attrib(u, value) + for a in u.attribs do + if (a.data==value) then return true end + end + return false +end + +function test_attrib() + local r = region.create(0,0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + local u2 = unit.create(f, r, 1) + data = { arr = { 'a', 'b', 'c' }, name = 'familiar', events = { die = 'familiar_died' }, data = { mage = u2 } } + a = { 'a' } + b = { 'a' } + uno = u.id + u2no = u2.id + a = attrib.create(u, 12) + a = attrib.create(u, "enno") + a = attrib.create(u, u2) + a = attrib.create(u, data) + write_game("attrib.dat") + free_game() + read_game("attrib.dat") + u = get_unit(uno) + u2 = get_unit(u2no) + assert_false(has_attrib(u, 42)) + assert_true(has_attrib(u, "enno")) + assert_true(has_attrib(u, 12)) + + for a in u.attribs do + x = a.data + if (type(x)=="table") then + assert_equal('a', x.arr[1]) + assert_equal('familiar', x.name) + assert_equal('familiar_died', x.events.die) + assert_equal(u2, x.data.mage) + break + end + end +end + +function test_seecast() + local r = region.create(0,0, "plain") + for i = 1,10 do + -- this prevents storms (only high seas have storms) + region.create(i, 1, "plain") + end + for i = 1,10 do + region.create(i, 0, "ocean") + end + local f = faction.create("noreply@eressea.de", "human", "de") + local s1 = ship.create(r, "cutter") + local u1 = unit.create(f, r, 2) + u1:set_skill("sailing", 3) + u1:add_item("money", 1000) + u1.ship = s1 + local u2 = unit.create(f, r, 1) + u2.race = "elf" + u2:set_skill("magic", 6) + u2.magic = "gwyrrd" + u2.aura = 60 + u2.ship = s1 + u2:add_spell("stormwinds") + update_owners() + u2:clear_orders() + u2:add_order("Zaubere stufe 2 'Beschwoere einen Sturmelementar' " .. itoa36(s1.id)) + u1:clear_orders() + u1:add_order("NACH O O O O") + process_orders() + assert_equal(4, u2.region.x) + + u2:clear_orders() + u2:add_spell("stormwinds") + u2:add_order("Zaubere stufe 2 'Beschwoere einen Sturmelementar' " .. itoa36(s1.id)) + u1:clear_orders() + u1:add_order("NACH O O O O") + process_orders() + write_reports() + assert_equal(8, u2.region.x) +end + +local function use_tree(terrain) + local r = region.create(0,0, terrain) + local f = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f, r, 5) + r:set_resource("tree", 0) + u1:add_item("xmastree", 1) + u1:clear_orders() + u1:add_order("BENUTZEN 1 Weihnachtsbaum") + process_orders() + return r +end + +function test_xmas2009() + local r = region.create(0,0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f, r, 1) + process_orders() + xmas2009() + assert_equal("xmastree", f.items()) +end + +function test_xmastree() + local r + r = use_tree("ocean") + assert_equal(0, r:get_resource("tree")) + free_game() + r = use_tree("plain") + assert_equal(10, r:get_resource("tree")) +end + +function test_fishing() + local r = region.create(0,0, "ocean") + local r2 = region.create(1,0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local s1 = ship.create(r, "cutter") + local u1 = unit.create(f, r, 3) + u1.ship = s1 + u1:set_skill("sailing", 10) + u1:add_item("money", 100) + u1:clear_orders() + u1:add_order("NACH O") + update_owners() + + process_orders() + assert_equal(r2.id, u1.region.id) + assert_equal(90, u1:get_item("money")) + + u1:clear_orders() + u1:add_order("NACH W") + + process_orders() + assert_equal(60, u1:get_item("money")) +end + +function test_ship_capacity() + local r = region.create(0,0, "ocean") + region.create(1,0, "ocean") + local r2 = region.create(2,0, "ocean") + local f = faction.create("noreply@eressea.de", "human", "de") + local f2 = faction.create("noreply@eressea.de", "goblin", "de") + + -- u1 is at the limit and moves + local s1 = ship.create(r, "cutter") + local u1 = unit.create(f, r, 5) + u1.ship = s1 + u1:set_skill("sailing", 10) + u1:add_item("sword", 55) + u1:clear_orders() + u1:add_order("NACH O O") + + -- u2 has too many people + local s2 = ship.create(r, "cutter") + local u2 = unit.create(f, r, 6) + u2.ship = s2 + u2:set_skill("sailing", 10) + u2:clear_orders() + u2:add_order("NACH O O") + + -- u3 has goblins, they weigh 40% less + local s3 = ship.create(r, "cutter") + local u3 = unit.create(f2, r, 8) + u3.ship = s3 + u3:set_skill("sailing", 10) + u3:add_item("sword", 55) + u3:clear_orders() + u3:add_order("NACH O O") + + -- u4 has too much stuff + local s4 = ship.create(r, "cutter") + local u4 = unit.create(f, r, 5) + u4.ship = s4 + u4:set_skill("sailing", 10) + u4:add_item("sword", 56) + u4:clear_orders() + u4:add_order("NACH O O") + + update_owners() + process_orders() + assert_equal(r2.id, u1.region.id) + assert_not_equal(r2.id, u2.region.id) + assert_equal(r2.id, u3.region.id) + assert_not_equal(r2.id, u4.region.id) +end + +function test_owners() + local r = region.create(0, 0, "plain") + local f1 = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f1, r, 1) + local f2 = faction.create("noreply@eressea.de", "human", "de") + local u2 = unit.create(f2, r, 1) + local u3 = unit.create(f2, r, 1) + + local b3 = building.create(r, "castle") + b3.size = 2 + u3.building = b3 + local b1 = building.create(r, "castle") + b1.size = 1 + u1.building = b1 + local b2 = building.create(r, "castle") + b2.size = 2 + u2.building = b2 + + update_owners() + assert(r.owner==u3.faction) + b1.size=3 + b2.size=3 + update_owners() + assert(r.owner==u2.faction) + b1.size=4 + update_owners() + assert(r.owner==u1.faction) +end + +function test_taxes() + local r = region.create(0, 0, "plain") + r:set_resource("peasant", 1000) + r:set_resource("money", 5000) + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u:add_item("money", u.number * 10) + u:clear_orders() + u:add_order("LERNE Holzfaellen") -- do not work + local b = building.create(r, "watch") + b.size = 10 + u.building = b + update_owners() + assert_equal(1, r.morale) + process_orders() + assert_equal(1, r.morale) + assert_equal(25, u:get_item("money")) +end + +function test_leave() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + f.id = 42 + local b1 = building.create(r, "castle") + b1.size = 10 + local b2 = building.create(r, "lighthouse") + b2.size = 10 + local u = unit.create(f, r, 1) + u.building = b1 + assert_not_equal(nil, u.building) + u:add_item("money", u.number * 100) + u:clear_orders() + u:add_order("BETRETE BURG " .. itoa36(b2.id)) + update_owners() + process_orders() + assert_equal(u.building.id, b1.id, "region owner has left the building") -- region owners may not leave +end + +function test_market() + -- if i am the only trader around, i should be getting all the herbs from all 7 regions + local herb_multi = 500 -- from rc_herb_trade() + local r, idx + local herbnames = { 'h0', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8' } + idx = 1 + for x = -1, 1 do for y = -1, 1 do + r = region.create(x, y, "plain") + r:set_resource("peasant", herb_multi * 9 + 50) -- 10 herbs per region + r.herb = herbnames[idx] + idx = idx+1 + end end + r = get_region(0, 0) + local b = building.create(r, "market") + b.size = 10 + local f = faction.create("noreply@eressea.de", "human", "de") + f.id = 42 + local u = unit.create(f, r, 1) + u.building = b + u:add_item("money", u.number * 10000) + for i = 0, 5 do + local rn = r:next(i) + end + process.markets() + u:add_item("money", -u:get_item("money")) -- now we only have herbs + local len = 0 + for i in u.items do + len = len + 1 + end + assert_not_equal(0, len, "trader did not get any herbs") + for idx, name in pairs(herbnames) do + local n = u:get_item(name) + if n>0 then + assert_equal(10, n, 'trader did not get exaxtly 10 herbs') + end + end +end + +function test_market_gives_items() + local r + for x = -1, 1 do for y = -1, 1 do + r = region.create(x, y, "plain") + r:set_resource("peasant", 5000) + end end + r = get_region(0, 0) + local b = building.create(r, "market") + b.size = 10 + local f = faction.create("noreply@eressea.de", "human", "de") + f.id = 42 + local u = unit.create(f, r, 1) + u.building = b + u:add_item("money", u.number * 10000) + for i = 0, 5 do + local rn = r:next(i) + end + process_orders() + local len = 0 + for i in u.items do + len = len + 1 + end + assert(len>1) +end + +function test_spells() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + u.race = "elf" + u:clear_orders() + u:add_item("money", 10000) + u:set_skill("magic", 5) + u:add_order("LERNE MAGIE Illaun") + process_orders() + local sp + local nums = 0 + if f.spells~=nil then + for sp in f.spells do + nums = nums + 1 + end + assert(nums>0) + for sp in u.spells do + nums = nums - 1 + end + assert(nums==0) + else + for sp in u.spells do + nums = nums + 1 + end + assert(nums>0) + end +end + +function test_alliance() + local r = region.create(0, 0, "plain") + local f1 = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f1, r, 1) + u1:add_item("money", u1.number * 100) + local f2 = faction.create("info@eressea.de", "human", "de") + local u2 = unit.create(f2, r, 1) + u2:add_item("money", u2.number * 100) + assert(f1.alliance==nil) + assert(f2.alliance==nil) + u1:clear_orders() + u2:clear_orders() + u1:add_order("ALLIANZ NEU pink") + u1:add_order("ALLIANZ EINLADEN " .. itoa36(f2.id)) + u2:add_order("ALLIANZ BEITRETEN pink") + process_orders() + assert(f1.alliance~=nil) + assert(f2.alliance~=nil) + assert(f2.alliance==f1.alliance) + u1:clear_orders() + u2:clear_orders() + u1:add_order("ALLIANZ KOMMANDO " .. itoa36(f2.id)) + process_orders() + assert(f1.alliance~=nil) + assert(f2.alliance~=nil) + assert(f2.alliance==f1.alliance) + u1:clear_orders() + u2:clear_orders() + u2:add_order("ALLIANZ AUSSTOSSEN " .. itoa36(f1.id)) + process_orders() + assert(f1.alliance==nil) + assert(f2.alliance~=nil) + u1:clear_orders() + u2:clear_orders() + u2:add_order("ALLIANZ NEU zing") + u1:add_order("ALLIANZ BEITRETEN zing") -- no invite! + process_orders() + assert(f1.alliance==nil) + assert(f2.alliance~=nil) + u1:clear_orders() + u2:clear_orders() + u1:add_order("ALLIANZ NEU zack") + u1:add_order("ALLIANZ EINLADEN " .. itoa36(f2.id)) + u2:add_order("ALLIANZ BEITRETEN zack") + process_orders() + assert(f1.alliance==f2.alliance) + assert(f2.alliance~=nil) +end + +function test_canoe_passes_through_land() + local f = faction.create("noreply@eressea.de", "human", "de") + local src = region.create(0, 0, "ocean") + local land = region.create(1, 0, "plain") + region.create(2, 0, "ocean") + local dst = region.create(3, 0, "ocean") + local sh = ship.create(src, "canoe") + local u1, u2 = two_units(src, f, f) + u1.ship = sh + u2.ship = sh + u1:set_skill("sailing", 10) + u1:clear_orders() + u1:add_order("NACH O O O") + process_orders() + assert_equal(u2.region.id, land.id, "canoe did not stop at coast") + u1:add_order("NACH O O O") + process_orders() + assert_equal(u2.region.id, dst.id, "canoe could not leave coast") +end + +function test_give_50_percent_of_money() + local u1, u2 = two_units(region.create(0, 0, "plain"), two_factions()) + local r = u2.region + u1.faction.age = 10 + u2.faction.age = 10 + u1:add_item("money", 500) + local m1, m2 = u1:get_item("money"), u2:get_item("money") + u1:clear_orders() + u1:add_order("GIB " .. itoa36(u2.id) .. " 221 Silber") + u2:clear_orders() + u2:add_order("LERNEN Hiebwaffen") + process_orders() + assert(u1:get_item("money")==m1-10*u1.number) + assert(u2:get_item("money")==m2-10*u2.number) + + m1, m2 = u1:get_item("money"), u2:get_item("money") + u1:clear_orders() + u1:add_order("GIB " .. itoa36(u2.id) .. " 221 Silber") + u2:clear_orders() + u2:add_order("HELFEN " .. itoa36(u1.faction.id) .. " GIB") + u2:add_item("horse", 100) + u2:add_order("GIB 0 ALLES PFERD") + local h = r:get_resource("horse") + process_orders() + assert(r:get_resource("horse")>=h+100) + assert_equal(m1-221-10*u1.number, u1:get_item("money")) + assert_equal(m2+110-10*u2.number, u2:get_item("money")) +end + +function test_give_100_percent_of_items() + local u1, u2 = two_units(region.create(0, 0, "plain"), two_factions()) + local r = u2.region + u1.faction.age = 10 + u2.faction.age = 10 + u1:add_item("money", 500) + u1:add_item("log", 500) + local m1, m2 = u1:get_item("log"), u2:get_item("log") + u1:clear_orders() + u1:add_order("GIB " .. itoa36(u2.id) .. " 332 Holz") + u2:clear_orders() + u2:add_order("LERNEN Hiebwaffen") + u2:add_order("HELFEN " .. itoa36(u1.faction.id) .. " GIB") + process_orders() + assert_equal(m1-332, u1:get_item("log")) + assert_equal(m2+332, u2:get_item("log")) +end + +function test_cannot_give_person() + local r = region.create(0, 0, "plain") + local f1 = faction.create("noreply@eressea.de", "human", "de") + local f2 = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f1, r, 10) + local u2 = unit.create(f2, r, 10) + u1.faction.age = 10 + u2.faction.age = 10 + u1:add_item("money", 500) + u2:add_item("money", 500) + u2:clear_orders() + u2:add_order("GIB ".. itoa36(u1.id) .. " 1 PERSON") + u2:add_order("HELFE ".. itoa36(f1.id) .. " GIB") + u1:add_order("HELFE ".. itoa36(f2.id) .. " GIB") + process_orders() + assert_equal(10, u2.number) + assert_equal(10, u1.number) +end + +function test_cannot_give_unit() + local r = region.create(0, 0, "plain") + local f1 = faction.create("noreply@eressea.de", "human", "de") + local f2 = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f1, r, 10) + local u2 = unit.create(f2, r, 10) + u1.faction.age = 10 + u2.faction.age = 10 + u1:add_item("money", 500) + u2:add_item("money", 500) + u2:clear_orders() + u2:add_order("GIB ".. itoa36(u1.id) .. " EINHEIT") + u2:add_order("HELFE ".. itoa36(f1.id) .. " GIB") + u1:add_order("HELFE ".. itoa36(f2.id) .. " GIB") + process_orders() + assert_not_equal(u2.faction.id, u1.faction.id) +end + +function test_guard_by_owners() + -- http://bugs.eressea.de/view.php?id=1756 + local r = region.create(0,0, "mountain") + local f1 = faction.create("noreply@eressea.de", "human", "de") + f1.age=20 + local f2 = faction.create("noreply@eressea.de", "human", "de") + f2.age=20 + local u1 = unit.create(f1, r, 1) + local b = building.create(r, "castle") + b.size = 10 + u1.building = b + u1:add_item("money", 100) + + local u2 = unit.create(f2, r, 1) + u2:add_item("money", 100) + u2:set_skill("mining", 3) + u2:clear_orders() + u2:add_order("MACHEN EISEN") + + process_orders() + local iron = u2:get_item("iron") + process_orders() + assert_equal(iron, u2:get_item("iron")) +end + +function test_market_action() + local f = faction.create("noreply@eressea.de", "human", "de") + local x, y, r + for x=0,2 do + for y=0,2 do + r = region.create(x, y, "plain") + r.luxury = "balm" + r.herb = "h2" + r:set_resource("peasant", 5000) + end + end + r = get_region(1, 1) + local u = unit.create(f, r, 1) + b = building.create(r, "market") + b.size = 10 + u.building = b + update_owners() + for r in regions() do + market_action(r) + end + assert_equal(35, u:get_item("balm")) + assert_equal(70, u:get_item("h2")) +end + +-- function test_process_execute() + -- local i = 0 + -- local f = faction.create("noreply@eressea.de", "human", "de") + -- local r = region.create(0, 0, "plain") + -- local u = unit.create(f, r, 1) + -- local r1, u1 + + -- function a() i = 2 end + -- function b() i = i * 2 end + -- function c(r) r1 = r i = i + 1 end + -- function d(u) u1 = u i = i * 3 end + -- process.execute({a, b}, {c}, {d}) + -- assert_equal(15, i) + -- assert_equal(r, r1) + -- assert_equal(u, u1) +-- end + +-- function test_new_orders() + -- local i = 0 + -- local f = faction.create("noreply@eressea.de", "human", "de") + -- local r = region.create(0, 0, "plain") + -- local u = unit.create(f, r, 1) + -- local r1, u1 + + -- function a() i = 2 end + -- function b() i = i * 2 end + -- function c(r) r1 = r i = i + 1 end + -- function d(u) u1 = u i = i * 3 end + + -- process.setup() + -- process.push(a) + -- process.push(b) + -- process.push(c, "region") + -- process.push(d, "unit") + -- process.start() + + -- assert_equal(15, i) + -- assert_equal(r, r1) + -- assert_equal(u, u1) +-- end diff --git a/scripts/tests/eressea.lua b/scripts/tests/eressea.lua index 06e1fd701..57efd36fa 100644 --- a/scripts/tests/eressea.lua +++ b/scripts/tests/eressea.lua @@ -1,144 +1,144 @@ -require "lunit" - -module( "e2", package.seeall, lunit.testcase ) - -function setup() - free_game() -end - -function test_rename() - local r = region.create(0, 0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r) - u:add_item("aoh", 1) - assert_equal(u:get_item("ao_healing"), 1) -end - -function DISABLE_test_alp() - local r = region.create(0,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 1) - local u2 = unit.create(f, r, 1) - u.race = "elf" - u:set_skill("magic", 10) - u:add_item("money", 3010) - u.magic = "illaun" - u.aura = 200 - u.ship = s1 - u:add_spell("summon_alp") - u:clear_orders() - u:add_order("ZAUBERE 'Alp' " .. itoa36(u2.id)) - process_orders() - print(get_turn(), f) - write_reports() -end - -function test_unit_limit_is_1500() - local r = region.create(0,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - for i = 1,1500 do - unit.create(f, r, 1) - end - local u = unit.create(f, r, 0) - u:add_item("money", 20000) - u:clear_orders() - u:add_order("REKRUTIEREN 1") - process_orders() - assert_equal(1, u.number) -end - -function test_ship_capacity() - local r = region.create(0,0, "ocean") - region.create(1,0, "ocean") - local r2 = region.create(2,0, "ocean") - local f = faction.create("noreply@eressea.de", "human", "de") - - -- u1 is at the limit and moves - local s1 = ship.create(r, "boat") - local u1 = unit.create(f, r, 5) - u1.ship = s1 - u1:set_skill("sailing", 10) - u1:clear_orders() - u1:add_order("NACH O O") - - -- u2 has too many people - local s2 = ship.create(r, "boat") - local u2 = unit.create(f, r, 6) - u2.ship = s2 - u2:set_skill("sailing", 10) - u2:clear_orders() - u2:add_order("NACH O O") - - -- u4 has too much stuff - local s4 = ship.create(r, "boat") - local u4 = unit.create(f, r, 5) - u4.ship = s4 - u4:set_skill("sailing", 10) - u4:add_item("sword", 1) - u4:clear_orders() - u4:add_order("NACH O O") - - process_orders() --- print(s.region, u.region, r2) - assert_equal(r2.id, u1.region.id, "boat with 5 humans did not move") - assert_not_equal(r2.id, u2.region.id, "boat with too many people has moved") - assert_not_equal(r2.id, u4.region.id, "boat with too much cargo has moved") -end - -function test_levitate() - local r = region.create(0,0, "plain") - local f = faction.create("noreply@eressea.de", "human", "de") - local u = unit.create(f, r, 2) - local s = ship.create(r, "boat") - u.ship = s - u.age = 20 - u:set_skill("sailing", 5) - u:add_item("money", 100) - u:clear_orders() - u:add_order("ARBEITE") - levitate_ship(u.ship, u, 2, 1) - assert_equal(32, u.ship.flags) - process_orders() - assert_equal(0, u.ship.flags) -end - -function test_terrains() - local terrains = { "hell", "wall1", "corridor1" } - for k,v in ipairs(terrains) do - local r = region.create(k, k, v) - assert_not_equal(nil, r) - end -end - -function test_races() - local races = { "wolf", "orc", "human", "demon" } - for k,v in ipairs(races) do - local f = faction.create("noreply@eressea.de", "human", "de") - assert_not_equal(nil, f) - end -end - -function test_can_give_person() - local r = region.create(0, 0, "plain") - local f1 = faction.create("noreply@eressea.de", "human", "de") - local f2 = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f1, r, 10) - local u2 = unit.create(f2, r, 10) - u1.faction.age = 10 - u2.faction.age = 10 - u1:add_item("money", 500) - u2:add_item("money", 500) - u2:clear_orders() - u2:add_order("GIB ".. itoa36(u1.id) .. " 1 PERSON") - u2:add_order("HELFE ".. itoa36(f1.id) .. " GIB") - u1:add_order("HELFE ".. itoa36(f2.id) .. " GIB") - u1:add_order("KONTAKTIERE ".. itoa36(u2.id)) - process_orders() - assert_equal(9, u2.number) - assert_equal(11, u1.number) -end - -function test_no_uruk() - local f1 = faction.create("noreply@eressea.de", "uruk", "de") - assert_equal(f1.race, "orc") -end +require "lunit" + +module( "e2", package.seeall, lunit.testcase ) + +function setup() + free_game() +end + +function test_rename() + local r = region.create(0, 0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r) + u:add_item("aoh", 1) + assert_equal(u:get_item("ao_healing"), 1) +end + +function DISABLE_test_alp() + local r = region.create(0,0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 1) + local u2 = unit.create(f, r, 1) + u.race = "elf" + u:set_skill("magic", 10) + u:add_item("money", 3010) + u.magic = "illaun" + u.aura = 200 + u.ship = s1 + u:add_spell("summon_alp") + u:clear_orders() + u:add_order("ZAUBERE 'Alp' " .. itoa36(u2.id)) + process_orders() + print(get_turn(), f) + write_reports() +end + +function test_unit_limit_is_1500() + local r = region.create(0,0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + for i = 1,1500 do + unit.create(f, r, 1) + end + local u = unit.create(f, r, 0) + u:add_item("money", 20000) + u:clear_orders() + u:add_order("REKRUTIEREN 1") + process_orders() + assert_equal(1, u.number) +end + +function test_ship_capacity() + local r = region.create(0,0, "ocean") + region.create(1,0, "ocean") + local r2 = region.create(2,0, "ocean") + local f = faction.create("noreply@eressea.de", "human", "de") + + -- u1 is at the limit and moves + local s1 = ship.create(r, "boat") + local u1 = unit.create(f, r, 5) + u1.ship = s1 + u1:set_skill("sailing", 10) + u1:clear_orders() + u1:add_order("NACH O O") + + -- u2 has too many people + local s2 = ship.create(r, "boat") + local u2 = unit.create(f, r, 6) + u2.ship = s2 + u2:set_skill("sailing", 10) + u2:clear_orders() + u2:add_order("NACH O O") + + -- u4 has too much stuff + local s4 = ship.create(r, "boat") + local u4 = unit.create(f, r, 5) + u4.ship = s4 + u4:set_skill("sailing", 10) + u4:add_item("sword", 1) + u4:clear_orders() + u4:add_order("NACH O O") + + process_orders() +-- print(s.region, u.region, r2) + assert_equal(r2.id, u1.region.id, "boat with 5 humans did not move") + assert_not_equal(r2.id, u2.region.id, "boat with too many people has moved") + assert_not_equal(r2.id, u4.region.id, "boat with too much cargo has moved") +end + +function test_levitate() + local r = region.create(0,0, "plain") + local f = faction.create("noreply@eressea.de", "human", "de") + local u = unit.create(f, r, 2) + local s = ship.create(r, "boat") + u.ship = s + u.age = 20 + u:set_skill("sailing", 5) + u:add_item("money", 100) + u:clear_orders() + u:add_order("ARBEITE") + levitate_ship(u.ship, u, 2, 1) + assert_equal(32, u.ship.flags) + process_orders() + assert_equal(0, u.ship.flags) +end + +function test_terrains() + local terrains = { "hell", "wall1", "corridor1" } + for k,v in ipairs(terrains) do + local r = region.create(k, k, v) + assert_not_equal(nil, r) + end +end + +function test_races() + local races = { "wolf", "orc", "human", "demon" } + for k,v in ipairs(races) do + local f = faction.create("noreply@eressea.de", "human", "de") + assert_not_equal(nil, f) + end +end + +function test_can_give_person() + local r = region.create(0, 0, "plain") + local f1 = faction.create("noreply@eressea.de", "human", "de") + local f2 = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f1, r, 10) + local u2 = unit.create(f2, r, 10) + u1.faction.age = 10 + u2.faction.age = 10 + u1:add_item("money", 500) + u2:add_item("money", 500) + u2:clear_orders() + u2:add_order("GIB ".. itoa36(u1.id) .. " 1 PERSON") + u2:add_order("HELFE ".. itoa36(f1.id) .. " GIB") + u1:add_order("HELFE ".. itoa36(f2.id) .. " GIB") + u1:add_order("KONTAKTIERE ".. itoa36(u2.id)) + process_orders() + assert_equal(9, u2.number) + assert_equal(11, u1.number) +end + +function test_no_uruk() + local f1 = faction.create("noreply@eressea.de", "uruk", "de") + assert_equal(f1.race, "orc") +end diff --git a/scripts/tests/morale.lua b/scripts/tests/morale.lua index 6dbc8f679..90ac4cd32 100644 --- a/scripts/tests/morale.lua +++ b/scripts/tests/morale.lua @@ -1,176 +1,176 @@ -require "lunit" - -module( "morale", package.seeall, lunit.testcase ) - -function setup() - free_game() -end - -function test_when_owner_returns_morale_drops_only_2() - local r = region.create(0, 0, "plain") - assert_equal(1, r.morale) - local f1 = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f1, r, 1) - u1:add_item("money", 10000) - local b = building.create(r, "castle") - b.size = 50 - - set_turn(get_turn()+10) - f1.lastturn=get_turn() - u1.building = b - update_owners() - r.morale = 6 - u1.building = nil - process_orders() - assert_equal(5, r.morale) -- no owner, fall by 1 - u1.building = b - update_owners() - set_key("test", 42) - process_orders() - assert_equal(3, r.morale) -- new owner, fall by 2 -end - -function test_morale_alliance() - local r = region.create(0, 0, "plain") - assert_equal(1, r.morale) - local f1 = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f1, r, 1) - u1:add_item("money", 10000) - local f2 = faction.create("noreply@eressea.de", "human", "de") - local u2 = unit.create(f2, r, 1) - u2:add_item("money", 10000) - local f3 = faction.create("noreply@eressea.de", "human", "de") - local u3 = unit.create(f3, r, 1) - u3:add_item("money", 10000) - - local al = alliance.create(42, "Die Antwoord") - f1.alliance = al; - f2.alliance = al; - - local b = building.create(r, "castle") - b.size = 50 - u1.building = b - u2.building = b - u3.building = b - update_owners() - r.morale = 6 - - local function run_a_turn() - process_orders() - f1.lastturn=get_turn() - f2.lastturn=get_turn() - f3.lastturn=get_turn() - end - - -- just checking everything's okay after setup. - run_a_turn() - assert_equal(6, r.morale) - - -- change owner, new owner is in the same alliance - u1.building = nil - run_a_turn() - assert_equal(4, r.morale) - - -- change owner, new owner is not in the same alliance - u2.building = nil - run_a_turn() - assert_equal(0, r.morale) -end - -function test_morale_change() - local r = region.create(0, 0, "plain") - assert_equal(1, r.morale) - local f1 = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f1, r, 1) - u1:add_item("money", 10000) - local f2 = faction.create("noreply@eressea.de", "human", "de") - local u2 = unit.create(f2, r, 1) - u2:add_item("money", 10000) - - local AVG_STEP = 6 - local b = building.create(r, "castle") - b.size = 10 - u1.building = b - - local function run_a_turn() - process_orders() - f1.lastturn=get_turn() - f2.lastturn=get_turn() - end - - -- reinhardt-regel: nach 2*AVG_STEP ist moral mindestens einmal gestiegen. - for i=1,AVG_STEP*2 do - run_a_turn() - assert_not_equal(r.owner, nil) - end - assert_not_equal(1, r.morale) - - -- regel: moral ist nie hoeher als 2 punkte ueber burgen-max. - for i=1,AVG_STEP*4 do - run_a_turn() - end - assert_equal(4, r.morale) - - -- auch mit herrscher faellt moral um 1 pro woche, wenn moral > burgstufe - r.morale = 6 - run_a_turn() - assert_equal(5, r.morale) - run_a_turn() - assert_equal(4, r.morale) - run_a_turn() - assert_equal(4, r.morale) - - -- regel: ohne herrscher f�llt die moral jede woche um 1 punkt, bis sie 1 erreicht - u1.building = nil - update_owners() - run_a_turn() - assert_equal(3, r.morale) - run_a_turn() - assert_equal(2, r.morale) - run_a_turn() - assert_equal(1, r.morale) - run_a_turn() - assert_equal(1, r.morale) - - -- ohne herrscher �ndert sich auch beschissene Moral nicht: - r.morale = 0 - run_a_turn() - assert_equal(0, r.morale) -end - -function test_morale_old() - local r = region.create(0, 0, "plain") - assert_equal(1, r.morale) - local f1 = faction.create("noreply@eressea.de", "human", "de") - local u1 = unit.create(f1, r, 1) - local f2 = faction.create("noreply@eressea.de", "human", "de") - local u2 = unit.create(f2, r, 1) - - local b = building.create(r, "castle") - b.size = 10 - u1.building = b - u2.building = b - update_owners() - assert_equal(1, r.morale) - r.morale = 5 - assert_equal(r.owner, u1.faction) - u1:clear_orders() - u1:add_order("GIB " .. itoa36(u2.id) .. " KOMMANDO") - process_orders() - u1:clear_orders() - assert_equal(u2.faction, r.owner) - assert_equal(3, r.morale) -- 5-MORALE_TRANSFER - for u in r.units do - if u.faction.id==u2.faction.id then - u.building = nil - end - end - update_owners() - assert_equal(r.owner, u1.faction) - assert_equal(0, r.morale) -end - -function test_no_uruk() - local f1 = faction.create("noreply@eressea.de", "uruk", "de") - assert_equal(f1.race, "orc") -end +require "lunit" + +module( "morale", package.seeall, lunit.testcase ) + +function setup() + free_game() +end + +function test_when_owner_returns_morale_drops_only_2() + local r = region.create(0, 0, "plain") + assert_equal(1, r.morale) + local f1 = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f1, r, 1) + u1:add_item("money", 10000) + local b = building.create(r, "castle") + b.size = 50 + + set_turn(get_turn()+10) + f1.lastturn=get_turn() + u1.building = b + update_owners() + r.morale = 6 + u1.building = nil + process_orders() + assert_equal(5, r.morale) -- no owner, fall by 1 + u1.building = b + update_owners() + set_key("test", 42) + process_orders() + assert_equal(3, r.morale) -- new owner, fall by 2 +end + +function test_morale_alliance() + local r = region.create(0, 0, "plain") + assert_equal(1, r.morale) + local f1 = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f1, r, 1) + u1:add_item("money", 10000) + local f2 = faction.create("noreply@eressea.de", "human", "de") + local u2 = unit.create(f2, r, 1) + u2:add_item("money", 10000) + local f3 = faction.create("noreply@eressea.de", "human", "de") + local u3 = unit.create(f3, r, 1) + u3:add_item("money", 10000) + + local al = alliance.create(42, "Die Antwoord") + f1.alliance = al; + f2.alliance = al; + + local b = building.create(r, "castle") + b.size = 50 + u1.building = b + u2.building = b + u3.building = b + update_owners() + r.morale = 6 + + local function run_a_turn() + process_orders() + f1.lastturn=get_turn() + f2.lastturn=get_turn() + f3.lastturn=get_turn() + end + + -- just checking everything's okay after setup. + run_a_turn() + assert_equal(6, r.morale) + + -- change owner, new owner is in the same alliance + u1.building = nil + run_a_turn() + assert_equal(4, r.morale) + + -- change owner, new owner is not in the same alliance + u2.building = nil + run_a_turn() + assert_equal(0, r.morale) +end + +function test_morale_change() + local r = region.create(0, 0, "plain") + assert_equal(1, r.morale) + local f1 = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f1, r, 1) + u1:add_item("money", 10000) + local f2 = faction.create("noreply@eressea.de", "human", "de") + local u2 = unit.create(f2, r, 1) + u2:add_item("money", 10000) + + local AVG_STEP = 6 + local b = building.create(r, "castle") + b.size = 10 + u1.building = b + + local function run_a_turn() + process_orders() + f1.lastturn=get_turn() + f2.lastturn=get_turn() + end + + -- reinhardt-regel: nach 2*AVG_STEP ist moral mindestens einmal gestiegen. + for i=1,AVG_STEP*2 do + run_a_turn() + assert_not_equal(r.owner, nil) + end + assert_not_equal(1, r.morale) + + -- regel: moral ist nie hoeher als 2 punkte ueber burgen-max. + for i=1,AVG_STEP*4 do + run_a_turn() + end + assert_equal(4, r.morale) + + -- auch mit herrscher faellt moral um 1 pro woche, wenn moral > burgstufe + r.morale = 6 + run_a_turn() + assert_equal(5, r.morale) + run_a_turn() + assert_equal(4, r.morale) + run_a_turn() + assert_equal(4, r.morale) + + -- regel: ohne herrscher f�llt die moral jede woche um 1 punkt, bis sie 1 erreicht + u1.building = nil + update_owners() + run_a_turn() + assert_equal(3, r.morale) + run_a_turn() + assert_equal(2, r.morale) + run_a_turn() + assert_equal(1, r.morale) + run_a_turn() + assert_equal(1, r.morale) + + -- ohne herrscher �ndert sich auch beschissene Moral nicht: + r.morale = 0 + run_a_turn() + assert_equal(0, r.morale) +end + +function test_morale_old() + local r = region.create(0, 0, "plain") + assert_equal(1, r.morale) + local f1 = faction.create("noreply@eressea.de", "human", "de") + local u1 = unit.create(f1, r, 1) + local f2 = faction.create("noreply@eressea.de", "human", "de") + local u2 = unit.create(f2, r, 1) + + local b = building.create(r, "castle") + b.size = 10 + u1.building = b + u2.building = b + update_owners() + assert_equal(1, r.morale) + r.morale = 5 + assert_equal(r.owner, u1.faction) + u1:clear_orders() + u1:add_order("GIB " .. itoa36(u2.id) .. " KOMMANDO") + process_orders() + u1:clear_orders() + assert_equal(u2.faction, r.owner) + assert_equal(3, r.morale) -- 5-MORALE_TRANSFER + for u in r.units do + if u.faction.id==u2.faction.id then + u.building = nil + end + end + update_owners() + assert_equal(r.owner, u1.faction) + assert_equal(0, r.morale) +end + +function test_no_uruk() + local f1 = faction.create("noreply@eressea.de", "uruk", "de") + assert_equal(f1.race, "orc") +end diff --git a/src/bindings.c b/src/bindings.c index 3dfafcc56..62cce1992 100644 --- a/src/bindings.c +++ b/src/bindings.c @@ -1,99 +1,99 @@ -#include <platform.h> -#include <kernel/types.h> -#include "spells/shipcurse.h" - -#include <kernel/ship.h> -#include <kernel/unit.h> -#include <kernel/faction.h> - -#include <tolua.h> - -static int -tolua_levitate_ship(lua_State * L) -{ - ship * sh = (ship *)tolua_tousertype(L, 1, 0); - unit * mage = (unit *)tolua_tousertype(L, 2, 0); - double power = (double)tolua_tonumber(L, 3, 0); - int duration = (int)tolua_tonumber(L, 4, 0); - int cno = levitate_ship(sh, mage, power, duration); - tolua_pushnumber(L, (lua_Number)cno); - return 1; -} - - -extern void spawn_undead(void); -extern void spawn_dragons(void); -extern void plan_monsters(struct faction * f); - - -static int -tolua_planmonsters(lua_State * L) -{ - faction * f = (faction *)tolua_tousertype(L, 1, get_monsters()); - if (f) { - plan_monsters(f); - } - - return 0; -} - -static int -tolua_spawn_dragons(lua_State * L) -{ - spawn_dragons(); - return 0; -} - -static int -tolua_spawn_undead(lua_State * L) -{ - spawn_undead(); - return 0; -} - -static int -fix_familiars(struct lua_State * L) -{ - faction * f; - for (f=factions;f;f=f->next) { - unit * u; - for (u=f->units;u;u=u->nextF) { - struct sc_mage * mage = get_mage(u); - if (mage && is_familiar(u)) { - if (mage->spells && mage->magietyp==M_GRAY) { - equipment * eq; - char buffer[64]; - - while (mage->spells) { - spell_list * slist = mage->spells; - mage->spells = mage->spells->next; - free(slist); - } - - snprintf(buffer, sizeof(buffer), "%s_familiar", u->race->_name[0]); - eq = get_equipment(buffer); - if (eq) { - equip_unit_mask(u, eq, EQUIP_SPELLS); - } - } - } - } - } - return 0; -} - -void -bind_eressea(struct lua_State * L) -{ - tolua_module(L, NULL, 0); - tolua_beginmodule(L, NULL); - { - tolua_function(L, TOLUA_CAST "levitate_ship", tolua_levitate_ship); - tolua_function(L, TOLUA_CAST "plan_monsters", tolua_planmonsters); - tolua_function(L, TOLUA_CAST "spawn_undead", tolua_spawn_undead); - tolua_function(L, TOLUA_CAST "spawn_dragons", tolua_spawn_dragons); - tolua_function(L, TOLUA_CAST "fix_familiars", &fix_familiars); - } - tolua_endmodule(L); -} - +#include <platform.h> +#include <kernel/types.h> +#include "spells/shipcurse.h" + +#include <kernel/ship.h> +#include <kernel/unit.h> +#include <kernel/faction.h> + +#include <tolua.h> + +static int +tolua_levitate_ship(lua_State * L) +{ + ship * sh = (ship *)tolua_tousertype(L, 1, 0); + unit * mage = (unit *)tolua_tousertype(L, 2, 0); + double power = (double)tolua_tonumber(L, 3, 0); + int duration = (int)tolua_tonumber(L, 4, 0); + int cno = levitate_ship(sh, mage, power, duration); + tolua_pushnumber(L, (lua_Number)cno); + return 1; +} + + +extern void spawn_undead(void); +extern void spawn_dragons(void); +extern void plan_monsters(struct faction * f); + + +static int +tolua_planmonsters(lua_State * L) +{ + faction * f = (faction *)tolua_tousertype(L, 1, get_monsters()); + if (f) { + plan_monsters(f); + } + + return 0; +} + +static int +tolua_spawn_dragons(lua_State * L) +{ + spawn_dragons(); + return 0; +} + +static int +tolua_spawn_undead(lua_State * L) +{ + spawn_undead(); + return 0; +} + +static int +fix_familiars(struct lua_State * L) +{ + faction * f; + for (f=factions;f;f=f->next) { + unit * u; + for (u=f->units;u;u=u->nextF) { + struct sc_mage * mage = get_mage(u); + if (mage && is_familiar(u)) { + if (mage->spells && mage->magietyp==M_GRAY) { + equipment * eq; + char buffer[64]; + + while (mage->spells) { + spell_list * slist = mage->spells; + mage->spells = mage->spells->next; + free(slist); + } + + snprintf(buffer, sizeof(buffer), "%s_familiar", u->race->_name[0]); + eq = get_equipment(buffer); + if (eq) { + equip_unit_mask(u, eq, EQUIP_SPELLS); + } + } + } + } + } + return 0; +} + +void +bind_eressea(struct lua_State * L) +{ + tolua_module(L, NULL, 0); + tolua_beginmodule(L, NULL); + { + tolua_function(L, TOLUA_CAST "levitate_ship", tolua_levitate_ship); + tolua_function(L, TOLUA_CAST "plan_monsters", tolua_planmonsters); + tolua_function(L, TOLUA_CAST "spawn_undead", tolua_spawn_undead); + tolua_function(L, TOLUA_CAST "spawn_dragons", tolua_spawn_dragons); + tolua_function(L, TOLUA_CAST "fix_familiars", &fix_familiars); + } + tolua_endmodule(L); +} + diff --git a/src/curses.c b/src/curses.c index 5fc33e9eb..c2b0e8631 100644 --- a/src/curses.c +++ b/src/curses.c @@ -1,328 +1,328 @@ -#include <platform.h> -#include <kernel/types.h> - -#include "curses.h" - -#include <kernel/connection.h> -#include <kernel/curse.h> -#include <kernel/config.h> -#include <kernel/faction.h> -#include <kernel/message.h> -#include <kernel/region.h> -#include <kernel/save.h> -#include <kernel/terrain.h> -#include <kernel/unit.h> -#include <kernel/version.h> - -#include "spells/regioncurse.h" -#include "spells/unitcurse.h" -#include "spells/shipcurse.h" -#include "spells/buildingcurse.h" - -#include <util/attrib.h> -#include <util/language.h> -#include <util/rand.h> -#include <util/rng.h> -#include <util/resolve.h> -#include <util/storage.h> - -#include <assert.h> - -typedef struct wallcurse { - curse * buddy; - connection * wall; -} wallcurse; - -void -cw_init(attrib * a) { - curse * c; - curse_init(a); - c = (curse*)a->data.v; - c->data.v = calloc(sizeof(wallcurse), 1); -} - -void -cw_write(const attrib * a, const void * target, storage * store) { - connection * b = ((wallcurse*)((curse*)a->data.v)->data.v)->wall; - curse_write(a, target, store); - store->w_int(store, b->id); -} - -typedef struct bresvole { - unsigned int id; - curse * self; -} bresolve; - -static int resolve_buddy(variant data, void * addr); - -static int -cw_read(attrib * a, void * target, storage * store) -{ - bresolve * br = calloc(sizeof(bresolve), 1); - curse * c = (curse*)a->data.v; - wallcurse * wc = (wallcurse*)c->data.v; - variant var; - - curse_read(a, store, target); - br->self = c; - br->id = store->r_int(store); - - var.i = br->id; - ur_add(var, &wc->wall, resolve_borderid); - - var.v = br; - ur_add(var, &wc->buddy, resolve_buddy); - return AT_READ_OK; -} - -attrib_type at_cursewall = -{ - "cursewall", - cw_init, - curse_done, - curse_age, - cw_write, - cw_read, - ATF_CURSE -}; - - -static int -resolve_buddy(variant data, void * addr) -{ - curse * result = NULL; - bresolve * br = (bresolve*)data.v; - - if (br->id>=0) { - connection * b = find_border(br->id); - - if (b && b->from && b->to) { - attrib * a = a_find(b->from->attribs, &at_cursewall); - while (a && a->data.v!=br->self) { - curse * c = (curse*)a->data.v; - wallcurse * wc = (wallcurse*)c->data.v; - if (wc->wall->id==br->id) break; - a = a->next; - } - if (!a || a->type!=&at_cursewall) { - a = a_find(b->to->attribs, &at_cursewall); - while (a && a->type==&at_cursewall && a->data.v!=br->self) { - curse * c = (curse*)a->data.v; - wallcurse * wc = (wallcurse*)c->data.v; - if (wc->wall->id==br->id) break; - a = a->next; - } - } - if (a && a->type==&at_cursewall) { - curse * c = (curse*)a->data.v; - free(br); - result = c; - } - } else { - /* fail, object does not exist (but if you're still loading then - * you may want to try again later) */ - *(curse**)addr = NULL; - return -1; - } - } - *(curse**)addr = result; - return 0; -} - -static void -wall_init(connection * b) -{ - wall_data * fd = (wall_data*)calloc(sizeof(wall_data), 1); - fd->countdown = -1; /* infinite */ - b->data.v = fd; -} - -static void -wall_destroy(connection * b) -{ - free(b->data.v); -} - -static void -wall_read(connection * b, storage * store) -{ - wall_data * fd = (wall_data*)b->data.v; - variant mno; - assert(fd); - if (store->version<STORAGE_VERSION) { - mno.i = store->r_int(store); - fd->mage = findunit(mno.i); - if (!fd->mage) { - ur_add(mno, &fd->mage, resolve_unit); - } - } else { - read_reference(&fd->mage, store, read_unit_reference, resolve_unit); - } - fd->force = store->r_int(store); - if (store->version>=NOBORDERATTRIBS_VERSION) { - fd->countdown = store->r_int(store); - } - fd->active = true; -} - -static void -wall_write(const connection * b, storage * store) -{ - wall_data * fd = (wall_data*)b->data.v; - write_unit_reference(fd->mage, store); - store->w_int(store, fd->force); - store->w_int(store, fd->countdown); -} - -static int -wall_age(connection * b) -{ - wall_data * fd = (wall_data*)b->data.v; - --fd->countdown; - return (fd->countdown>0)?AT_AGE_KEEP:AT_AGE_REMOVE; -} - -static region * -wall_move(const connection * b, struct unit * u, struct region * from, struct region * to, boolean routing) -{ - wall_data * fd = (wall_data*)b->data.v; - if (!routing && fd->active) { - int hp = dice(3, fd->force) * u->number; - hp = MIN(u->hp, hp); - u->hp -= hp; - if (u->hp) { - ADDMSG(&u->faction->msgs, msg_message("firewall_damage", - "region unit", from, u)); - } - else ADDMSG(&u->faction->msgs, msg_message("firewall_death", "region unit", from, u)); - if (u->number>u->hp) { - scale_number(u, u->hp); - u->hp = u->number; - } - } - return to; -} - -static const char * -b_namefirewall(const connection * b, const region * r, const faction * f, int gflags) -{ - const char * bname; - unused(f); - unused(r); - unused(b); - if (gflags & GF_ARTICLE) bname = "a_firewall"; - else bname = "firewall"; - - if (gflags & GF_PURE) return bname; - return LOC(f->locale, mkname("border", bname)); -} - -border_type bt_firewall = { - "firewall", VAR_VOIDPTR, - b_transparent, /* transparent */ - wall_init, /* init */ - wall_destroy, /* destroy */ - wall_read, /* read */ - wall_write, /* write */ - b_blocknone, /* block */ - b_namefirewall, /* name */ - b_rvisible, /* rvisible */ - b_finvisible, /* fvisible */ - b_uinvisible, /* uvisible */ - NULL, - wall_move, - wall_age -}; - -void convert_firewall_timeouts(connection * b, attrib * a) -{ - while (a) { - if (b->type==&bt_firewall && a->type==&at_countdown) { - wall_data * fd = (wall_data *)b->data.v; - fd->countdown = a->data.i; - } - } -} - -static const char * -wisps_name(const connection * b, const region * r, const faction * f, int gflags) -{ - const char * bname; - unused(f); - unused(r); - unused(b); - if (gflags & GF_ARTICLE) { - bname = "a_wisps"; - } else { - bname = "wisps"; - } - if (gflags & GF_PURE) return bname; - return LOC(f->locale, mkname("border", bname)); -} - -typedef struct wisps_data { - wall_data wall; - int rnd; -} wisps_data; - -static region * -wisps_move(const connection * b, struct unit * u, struct region * from, struct region * next, boolean routing) -{ - direction_t reldir = reldirection(from, next); - wisps_data * wd = (wisps_data*)b->data.v; - assert(reldir!=D_SPECIAL); - - if (routing && wd->wall.active) { - region * rl = rconnect(from, (direction_t)((reldir+MAXDIRECTIONS-1)%MAXDIRECTIONS)); - region * rr = rconnect(from, (direction_t)((reldir+1)%MAXDIRECTIONS)); - /* pick left and right region: */ - if (wd->rnd<0) { - wd->rnd = rng_int() % 3; - } - - if (wd->rnd == 1 && rl && fval(rl->terrain, LAND_REGION)==fval(next, LAND_REGION)) return rl; - if (wd->rnd == 2 && rr && fval(rr->terrain, LAND_REGION)==fval(next, LAND_REGION)) return rr; - } - return next; -} - -static void -wisps_init(connection * b) -{ - wisps_data * wd = (wisps_data*)calloc(sizeof(wisps_data), 1); - - b->data.v = wd; - wd->rnd = -1; -} - -border_type bt_wisps = { - "wisps", VAR_VOIDPTR, - b_transparent, /* transparent */ - wisps_init, /* init */ - wall_destroy, /* destroy */ - wall_read, /* read */ - wall_write, /* write */ - b_blocknone, /* block */ - wisps_name, /* name */ - b_rvisible, /* rvisible */ - b_fvisible, /* fvisible */ - b_uvisible, /* uvisible */ - NULL, /* visible */ - wisps_move -}; - -void -register_curses(void) -{ - border_convert_cb = &convert_firewall_timeouts; - at_register(&at_cursewall); - - register_bordertype(&bt_firewall); - register_bordertype(&bt_wisps); - register_bordertype(&bt_chaosgate); - - register_unitcurse(); - register_regioncurse(); - register_shipcurse(); - register_buildingcurse(); -} +#include <platform.h> +#include <kernel/types.h> + +#include "curses.h" + +#include <kernel/connection.h> +#include <kernel/curse.h> +#include <kernel/config.h> +#include <kernel/faction.h> +#include <kernel/message.h> +#include <kernel/region.h> +#include <kernel/save.h> +#include <kernel/terrain.h> +#include <kernel/unit.h> +#include <kernel/version.h> + +#include "spells/regioncurse.h" +#include "spells/unitcurse.h" +#include "spells/shipcurse.h" +#include "spells/buildingcurse.h" + +#include <util/attrib.h> +#include <util/language.h> +#include <util/rand.h> +#include <util/rng.h> +#include <util/resolve.h> +#include <util/storage.h> + +#include <assert.h> + +typedef struct wallcurse { + curse * buddy; + connection * wall; +} wallcurse; + +void +cw_init(attrib * a) { + curse * c; + curse_init(a); + c = (curse*)a->data.v; + c->data.v = calloc(sizeof(wallcurse), 1); +} + +void +cw_write(const attrib * a, const void * target, storage * store) { + connection * b = ((wallcurse*)((curse*)a->data.v)->data.v)->wall; + curse_write(a, target, store); + store->w_int(store, b->id); +} + +typedef struct bresvole { + unsigned int id; + curse * self; +} bresolve; + +static int resolve_buddy(variant data, void * addr); + +static int +cw_read(attrib * a, void * target, storage * store) +{ + bresolve * br = calloc(sizeof(bresolve), 1); + curse * c = (curse*)a->data.v; + wallcurse * wc = (wallcurse*)c->data.v; + variant var; + + curse_read(a, store, target); + br->self = c; + br->id = store->r_int(store); + + var.i = br->id; + ur_add(var, &wc->wall, resolve_borderid); + + var.v = br; + ur_add(var, &wc->buddy, resolve_buddy); + return AT_READ_OK; +} + +attrib_type at_cursewall = +{ + "cursewall", + cw_init, + curse_done, + curse_age, + cw_write, + cw_read, + ATF_CURSE +}; + + +static int +resolve_buddy(variant data, void * addr) +{ + curse * result = NULL; + bresolve * br = (bresolve*)data.v; + + if (br->id>=0) { + connection * b = find_border(br->id); + + if (b && b->from && b->to) { + attrib * a = a_find(b->from->attribs, &at_cursewall); + while (a && a->data.v!=br->self) { + curse * c = (curse*)a->data.v; + wallcurse * wc = (wallcurse*)c->data.v; + if (wc->wall->id==br->id) break; + a = a->next; + } + if (!a || a->type!=&at_cursewall) { + a = a_find(b->to->attribs, &at_cursewall); + while (a && a->type==&at_cursewall && a->data.v!=br->self) { + curse * c = (curse*)a->data.v; + wallcurse * wc = (wallcurse*)c->data.v; + if (wc->wall->id==br->id) break; + a = a->next; + } + } + if (a && a->type==&at_cursewall) { + curse * c = (curse*)a->data.v; + free(br); + result = c; + } + } else { + /* fail, object does not exist (but if you're still loading then + * you may want to try again later) */ + *(curse**)addr = NULL; + return -1; + } + } + *(curse**)addr = result; + return 0; +} + +static void +wall_init(connection * b) +{ + wall_data * fd = (wall_data*)calloc(sizeof(wall_data), 1); + fd->countdown = -1; /* infinite */ + b->data.v = fd; +} + +static void +wall_destroy(connection * b) +{ + free(b->data.v); +} + +static void +wall_read(connection * b, storage * store) +{ + wall_data * fd = (wall_data*)b->data.v; + variant mno; + assert(fd); + if (store->version<STORAGE_VERSION) { + mno.i = store->r_int(store); + fd->mage = findunit(mno.i); + if (!fd->mage) { + ur_add(mno, &fd->mage, resolve_unit); + } + } else { + read_reference(&fd->mage, store, read_unit_reference, resolve_unit); + } + fd->force = store->r_int(store); + if (store->version>=NOBORDERATTRIBS_VERSION) { + fd->countdown = store->r_int(store); + } + fd->active = true; +} + +static void +wall_write(const connection * b, storage * store) +{ + wall_data * fd = (wall_data*)b->data.v; + write_unit_reference(fd->mage, store); + store->w_int(store, fd->force); + store->w_int(store, fd->countdown); +} + +static int +wall_age(connection * b) +{ + wall_data * fd = (wall_data*)b->data.v; + --fd->countdown; + return (fd->countdown>0)?AT_AGE_KEEP:AT_AGE_REMOVE; +} + +static region * +wall_move(const connection * b, struct unit * u, struct region * from, struct region * to, boolean routing) +{ + wall_data * fd = (wall_data*)b->data.v; + if (!routing && fd->active) { + int hp = dice(3, fd->force) * u->number; + hp = MIN(u->hp, hp); + u->hp -= hp; + if (u->hp) { + ADDMSG(&u->faction->msgs, msg_message("firewall_damage", + "region unit", from, u)); + } + else ADDMSG(&u->faction->msgs, msg_message("firewall_death", "region unit", from, u)); + if (u->number>u->hp) { + scale_number(u, u->hp); + u->hp = u->number; + } + } + return to; +} + +static const char * +b_namefirewall(const connection * b, const region * r, const faction * f, int gflags) +{ + const char * bname; + unused(f); + unused(r); + unused(b); + if (gflags & GF_ARTICLE) bname = "a_firewall"; + else bname = "firewall"; + + if (gflags & GF_PURE) return bname; + return LOC(f->locale, mkname("border", bname)); +} + +border_type bt_firewall = { + "firewall", VAR_VOIDPTR, + b_transparent, /* transparent */ + wall_init, /* init */ + wall_destroy, /* destroy */ + wall_read, /* read */ + wall_write, /* write */ + b_blocknone, /* block */ + b_namefirewall, /* name */ + b_rvisible, /* rvisible */ + b_finvisible, /* fvisible */ + b_uinvisible, /* uvisible */ + NULL, + wall_move, + wall_age +}; + +void convert_firewall_timeouts(connection * b, attrib * a) +{ + while (a) { + if (b->type==&bt_firewall && a->type==&at_countdown) { + wall_data * fd = (wall_data *)b->data.v; + fd->countdown = a->data.i; + } + } +} + +static const char * +wisps_name(const connection * b, const region * r, const faction * f, int gflags) +{ + const char * bname; + unused(f); + unused(r); + unused(b); + if (gflags & GF_ARTICLE) { + bname = "a_wisps"; + } else { + bname = "wisps"; + } + if (gflags & GF_PURE) return bname; + return LOC(f->locale, mkname("border", bname)); +} + +typedef struct wisps_data { + wall_data wall; + int rnd; +} wisps_data; + +static region * +wisps_move(const connection * b, struct unit * u, struct region * from, struct region * next, boolean routing) +{ + direction_t reldir = reldirection(from, next); + wisps_data * wd = (wisps_data*)b->data.v; + assert(reldir!=D_SPECIAL); + + if (routing && wd->wall.active) { + region * rl = rconnect(from, (direction_t)((reldir+MAXDIRECTIONS-1)%MAXDIRECTIONS)); + region * rr = rconnect(from, (direction_t)((reldir+1)%MAXDIRECTIONS)); + /* pick left and right region: */ + if (wd->rnd<0) { + wd->rnd = rng_int() % 3; + } + + if (wd->rnd == 1 && rl && fval(rl->terrain, LAND_REGION)==fval(next, LAND_REGION)) return rl; + if (wd->rnd == 2 && rr && fval(rr->terrain, LAND_REGION)==fval(next, LAND_REGION)) return rr; + } + return next; +} + +static void +wisps_init(connection * b) +{ + wisps_data * wd = (wisps_data*)calloc(sizeof(wisps_data), 1); + + b->data.v = wd; + wd->rnd = -1; +} + +border_type bt_wisps = { + "wisps", VAR_VOIDPTR, + b_transparent, /* transparent */ + wisps_init, /* init */ + wall_destroy, /* destroy */ + wall_read, /* read */ + wall_write, /* write */ + b_blocknone, /* block */ + wisps_name, /* name */ + b_rvisible, /* rvisible */ + b_fvisible, /* fvisible */ + b_uvisible, /* uvisible */ + NULL, /* visible */ + wisps_move +}; + +void +register_curses(void) +{ + border_convert_cb = &convert_firewall_timeouts; + at_register(&at_cursewall); + + register_bordertype(&bt_firewall); + register_bordertype(&bt_wisps); + register_bordertype(&bt_chaosgate); + + register_unitcurse(); + register_regioncurse(); + register_shipcurse(); + register_buildingcurse(); +} diff --git a/src/curses.h b/src/curses.h index 9eeba298c..0905e016d 100644 --- a/src/curses.h +++ b/src/curses.h @@ -1,27 +1,27 @@ -#ifndef H_KRNL_CURSES -#define H_KRNL_CURSES -#ifdef __cplusplus -extern "C" { -#endif - - extern void register_curses(void); - - /* f�r Feuerw�nde: in movement mu� das noch explizit getestet werden. - ** besser w�re eine blcok_type::move() routine, die den effekt - ** der Bewegung auf eine struct unit anwendet. - **/ - extern struct border_type bt_chaosgate; - extern struct border_type bt_firewall; - - typedef struct wall_data { - struct unit * mage; - int force; - boolean active; - int countdown; - } wall_data; - - -#ifdef __cplusplus -} -#endif -#endif +#ifndef H_KRNL_CURSES +#define H_KRNL_CURSES +#ifdef __cplusplus +extern "C" { +#endif + + extern void register_curses(void); + + /* f�r Feuerw�nde: in movement mu� das noch explizit getestet werden. + ** besser w�re eine blcok_type::move() routine, die den effekt + ** der Bewegung auf eine struct unit anwendet. + **/ + extern struct border_type bt_chaosgate; + extern struct border_type bt_firewall; + + typedef struct wall_data { + struct unit * mage; + int force; + boolean active; + int countdown; + } wall_data; + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/eressea.vcproj b/src/eressea.vcproj index 777ec9943..ff6831b27 100644 --- a/src/eressea.vcproj +++ b/src/eressea.vcproj @@ -1,636 +1,636 @@ -<?xml version="1.0" encoding="Windows-1252"?> -<VisualStudioProject - ProjectType="Visual C++" - Version="8.00" - Name="amalgamation-eressea" - ProjectGUID="{AD80EB0B-7CB4-42F2-9C95-8CCEF68DB387}" - RootNamespace="build" - Keyword="Win32Proj" - > - <Platforms> - <Platform - Name="Win32" - /> - </Platforms> - <ToolFiles> - </ToolFiles> - <Configurations> - <Configuration - Name="Debug|Win32" - OutputDirectory="$(ProjectDir)$(ConfigurationName)" - IntermediateDirectory="$(ProjectDir)$(ConfigurationName)" - ConfigurationType="1" - CharacterSet="1" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - AdditionalOptions="/MP" - Optimization="0" - AdditionalIncludeDirectories="../../server/src;../../external" - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" - MinimalRebuild="true" - BasicRuntimeChecks="3" - RuntimeLibrary="3" - UsePrecompiledHeader="2" - PrecompiledHeaderThrough="stdafx.h" - WarningLevel="4" - Detect64BitPortabilityProblems="true" - DebugInformationFormat="4" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="libxml2.lib pdcurses.lib lua5.1_d.lib tolua.lib" - OutputFile="$(OutDir)\eressea.exe" - LinkIncremental="2" - GenerateDebugInformation="true" - SubSystem="1" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - <Configuration - Name="Release|Win32" - OutputDirectory="$(ProjectDir)$(ConfigurationName)" - IntermediateDirectory="$(ProjectDir)$(ConfigurationName)" - ConfigurationType="1" - CharacterSet="1" - WholeProgramOptimization="1" - > - <Tool - Name="VCPreBuildEventTool" - /> - <Tool - Name="VCCustomBuildTool" - /> - <Tool - Name="VCXMLDataGeneratorTool" - /> - <Tool - Name="VCWebServiceProxyGeneratorTool" - /> - <Tool - Name="VCMIDLTool" - /> - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="../../server/src;../../external" - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" - RuntimeLibrary="2" - UsePrecompiledHeader="2" - WarningLevel="3" - Detect64BitPortabilityProblems="true" - DebugInformationFormat="3" - /> - <Tool - Name="VCManagedResourceCompilerTool" - /> - <Tool - Name="VCResourceCompilerTool" - /> - <Tool - Name="VCPreLinkEventTool" - /> - <Tool - Name="VCLinkerTool" - AdditionalDependencies="libxml2.lib pdcurses.lib lua5.1.lib tolua.lib" - OutputFile="$(OutDir)\eressea.exe" - LinkIncremental="1" - GenerateDebugInformation="true" - SubSystem="1" - OptimizeReferences="2" - EnableCOMDATFolding="2" - TargetMachine="1" - /> - <Tool - Name="VCALinkTool" - /> - <Tool - Name="VCManifestTool" - /> - <Tool - Name="VCXDCMakeTool" - /> - <Tool - Name="VCBscMakeTool" - /> - <Tool - Name="VCFxCopTool" - /> - <Tool - Name="VCAppVerifierTool" - /> - <Tool - Name="VCWebDeploymentTool" - /> - <Tool - Name="VCPostBuildEventTool" - /> - </Configuration> - </Configurations> - <References> - </References> - <Files> - <Filter - Name="Source Files" - Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" - > - <File - RelativePath=".\spells\alp.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\bindings.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\spells\buildingcurse.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\spells\combatspells.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\curses.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\races\dragons.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\races\illusion.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\main.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\monsters.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\races\races.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\races\races.h" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCustomBuildTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\spells\regioncurse.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\spells\shipcurse.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\spells\spells.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\..\server\src\tests.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\spells\unitcurse.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - <File - RelativePath=".\races\zombies.c" - > - <FileConfiguration - Name="Debug|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - ExcludedFromBuild="true" - > - <Tool - Name="VCCLCompilerTool" - /> - </FileConfiguration> - </File> - </Filter> - <Filter - Name="Header Files" - Filter="h;hpp;hxx;hm;inl;inc;xsd" - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" - > - <File - RelativePath=".\spells\alp.h" - > - </File> - <File - RelativePath=".\spells\buildingcurse.h" - > - </File> - <File - RelativePath=".\spells\combatspells.h" - > - </File> - <File - RelativePath=".\curses.h" - > - </File> - <File - RelativePath=".\spells\regioncurse.h" - > - </File> - <File - RelativePath=".\spells\shipcurse.h" - > - </File> - <File - RelativePath=".\spells\spells.h" - > - </File> - <File - RelativePath="..\..\server\src\build\stdafx.h" - > - </File> - <File - RelativePath="..\..\server\src\tests.h" - > - </File> - <File - RelativePath=".\spells\unitcurse.h" - > - </File> - </Filter> - <Filter - Name="Unity Build" - > - <File - RelativePath="..\..\server\src\build\external.c" - > - </File> - <File - RelativePath="..\..\server\src\build\gamecode.c" - > - </File> - <File - RelativePath="..\..\server\src\build\kernel.c" - > - </File> - <File - RelativePath="..\..\server\src\build\lib.c" - > - </File> - <File - RelativePath=".\server.c" - > - </File> - <File - RelativePath="..\..\server\src\build\stdafx.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="1" - PrecompiledHeaderThrough="stdafx.h" - /> - </FileConfiguration> - <FileConfiguration - Name="Release|Win32" - > - <Tool - Name="VCCLCompilerTool" - UsePrecompiledHeader="1" - /> - </FileConfiguration> - </File> - <File - RelativePath="..\..\server\src\build\util.c" - > - <FileConfiguration - Name="Debug|Win32" - > - <Tool - Name="VCCLCompilerTool" - AdditionalIncludeDirectories="src/util" - /> - </FileConfiguration> - </File> - </Filter> - <File - RelativePath=".\spells\Jamfile" - > - </File> - </Files> - <Globals> - </Globals> -</VisualStudioProject> +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="8.00" + Name="amalgamation-eressea" + ProjectGUID="{AD80EB0B-7CB4-42F2-9C95-8CCEF68DB387}" + RootNamespace="build" + Keyword="Win32Proj" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(ProjectDir)$(ConfigurationName)" + IntermediateDirectory="$(ProjectDir)$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/MP" + Optimization="0" + AdditionalIncludeDirectories="../../server/src;../../external" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + UsePrecompiledHeader="2" + PrecompiledHeaderThrough="stdafx.h" + WarningLevel="4" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="4" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libxml2.lib pdcurses.lib lua5.1_d.lib tolua.lib" + OutputFile="$(OutDir)\eressea.exe" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(ProjectDir)$(ConfigurationName)" + IntermediateDirectory="$(ProjectDir)$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="1" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="../../server/src;../../external" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + RuntimeLibrary="2" + UsePrecompiledHeader="2" + WarningLevel="3" + Detect64BitPortabilityProblems="true" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalDependencies="libxml2.lib pdcurses.lib lua5.1.lib tolua.lib" + OutputFile="$(OutDir)\eressea.exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\spells\alp.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\bindings.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\spells\buildingcurse.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\spells\combatspells.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\curses.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\races\dragons.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\races\illusion.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\main.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\monsters.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\races\races.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\races\races.h" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\spells\regioncurse.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\spells\shipcurse.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\spells\spells.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\..\server\src\tests.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\spells\unitcurse.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\races\zombies.c" + > + <FileConfiguration + Name="Debug|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + </Filter> + <Filter + Name="Header Files" + Filter="h;hpp;hxx;hm;inl;inc;xsd" + UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" + > + <File + RelativePath=".\spells\alp.h" + > + </File> + <File + RelativePath=".\spells\buildingcurse.h" + > + </File> + <File + RelativePath=".\spells\combatspells.h" + > + </File> + <File + RelativePath=".\curses.h" + > + </File> + <File + RelativePath=".\spells\regioncurse.h" + > + </File> + <File + RelativePath=".\spells\shipcurse.h" + > + </File> + <File + RelativePath=".\spells\spells.h" + > + </File> + <File + RelativePath="..\..\server\src\build\stdafx.h" + > + </File> + <File + RelativePath="..\..\server\src\tests.h" + > + </File> + <File + RelativePath=".\spells\unitcurse.h" + > + </File> + </Filter> + <Filter + Name="Unity Build" + > + <File + RelativePath="..\..\server\src\build\external.c" + > + </File> + <File + RelativePath="..\..\server\src\build\gamecode.c" + > + </File> + <File + RelativePath="..\..\server\src\build\kernel.c" + > + </File> + <File + RelativePath="..\..\server\src\build\lib.c" + > + </File> + <File + RelativePath=".\server.c" + > + </File> + <File + RelativePath="..\..\server\src\build\stdafx.c" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + PrecompiledHeaderThrough="stdafx.h" + /> + </FileConfiguration> + <FileConfiguration + Name="Release|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + </File> + <File + RelativePath="..\..\server\src\build\util.c" + > + <FileConfiguration + Name="Debug|Win32" + > + <Tool + Name="VCCLCompilerTool" + AdditionalIncludeDirectories="src/util" + /> + </FileConfiguration> + </File> + </Filter> + <File + RelativePath=".\spells\Jamfile" + > + </File> + </Files> + <Globals> + </Globals> +</VisualStudioProject> diff --git a/src/eressea.vcxproj b/src/eressea.vcxproj index ef4a306bb..e8e663c7a 100644 --- a/src/eressea.vcxproj +++ b/src/eressea.vcxproj @@ -49,9 +49,8 @@ <ClCompile> <AdditionalOptions>/MP %(AdditionalOptions)</AdditionalOptions> <Optimization>Disabled</Optimization> - <AdditionalIncludeDirectories>../../server/src;../../external;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MinimalRebuild>true</MinimalRebuild> + <AdditionalIncludeDirectories>../../server/src;../../external;../../external/lua/src;../../external/tolua/include;../../external/pdcurses;..\..\external\libxml2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>LIBXML_STATIC;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <PrecompiledHeader>Use</PrecompiledHeader> @@ -60,30 +59,30 @@ <DebugInformationFormat>EditAndContinue</DebugInformationFormat> </ClCompile> <Link> - <AdditionalDependencies>libxml2.lib;pdcurses.lib;lua5.1_d.lib;tolua.lib;%(AdditionalDependencies)</AdditionalDependencies> - <OutputFile>$(OutDir)eressea.exe</OutputFile> + <AdditionalDependencies>libxml2.lib;pdcurses.lib;lua.lib;tolua.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Console</SubSystem> <TargetMachine>MachineX86</TargetMachine> + <AdditionalLibraryDirectories>..\..\external\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <AdditionalIncludeDirectories>../../server/src;../../external;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>../../server/src;../../external;../../external/lua/src;../../external/tolua/include;../../external/pdcurses;..\..\external\libxml2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>LIBXML_STATIC;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <PrecompiledHeader>Use</PrecompiledHeader> <WarningLevel>Level3</WarningLevel> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> </ClCompile> <Link> - <AdditionalDependencies>libxml2.lib;pdcurses.lib;lua5.1.lib;tolua.lib;%(AdditionalDependencies)</AdditionalDependencies> - <OutputFile>$(OutDir)eressea.exe</OutputFile> + <AdditionalDependencies>libxml2.lib;pdcurses.lib;lua.lib;tolua.lib;%(AdditionalDependencies)</AdditionalDependencies> <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Console</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> <TargetMachine>MachineX86</TargetMachine> + <AdditionalLibraryDirectories>..\..\external\$(Configuration)\;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemGroup> diff --git a/src/main.c b/src/main.c index 32538bfa7..e090ce1ff 100644 --- a/src/main.c +++ b/src/main.c @@ -1,292 +1,292 @@ -#include <platform.h> -#include <util/log.h> - -#include <eressea.h> -#include <gmtool.h> -#include <kernel/config.h> -#include <kernel/save.h> -#include <iniparser/iniparser.h> -#include "races/races.h" - -#include <assert.h> -#include <locale.h> -#include <wctype.h> - -#include <tests.h> - -static const char * luafile = "setup.lua"; -static const char * entry_point = NULL; -static const char * inifile = "eressea.ini"; -static int memdebug = 0; - -static void parse_config(const char * filename) -{ - dictionary * d = iniparser_new(filename); - if (d) { - load_inifile(d); - - memdebug = iniparser_getint(d, "eressea:memcheck", memdebug); - entry_point = iniparser_getstring(d, "eressea:run", entry_point); - luafile = iniparser_getstring(d, "eressea:load", luafile); - - /* only one value in the [editor] section */ - force_color = iniparser_getint(d, "editor:color", force_color); - - /* excerpt from [config] (the rest is used in bindings.c) */ - game_name = iniparser_getstring(d, "config:game", game_name); - } - global.inifile = d; -} - -static int -usage(const char * prog, const char * arg) -{ - if (arg) { - fprintf(stderr, "unknown argument: %s\n\n", arg); - } - fprintf(stderr, "Usage: %s [options]\n" - "-t <turn> : read this datafile, not the most current one\n" - "-q : be quite (same as -v 0)\n" - "-v <level> : verbosity level\n" - "-C : run in interactive mode\n" - "--color : force curses to use colors even when not detected\n" - "--tests : run testsuite\n" - "--help : help\n", prog); - return -1; -} - -static int -parse_args(int argc, char **argv, int *exitcode) -{ - int i; - int run_tests = 0; - - for (i=1;i!=argc;++i) { - if (argv[i][0]!='-') { - return usage(argv[0], argv[i]); - } else if (argv[i][1]=='-') { /* long format */ - if (strcmp(argv[i]+2, "version")==0) { - printf("\n%s PBEM host\n" - "Copyright (C) 1996-2005 C. Schlittchen, K. Zedel, E. Rehling, H. Peters.\n\n" - "Compilation: " __DATE__ " at " __TIME__ "\nVersion: %f\n\n", global.gamename, version()); - } - else if (strcmp(argv[i]+2, "color")==0) { - /* force the editor to have colors */ - force_color = 1; - } - else if (strcmp(argv[i]+2, "tests")==0) { - /* force the editor to have colors */ - run_tests = 1; - } - else if (strcmp(argv[i]+2, "help")==0) { - return usage(argv[0], NULL); - } - else { - return usage(argv[0], argv[i]); - } - } else switch(argv[i][1]) { - case 'C': - entry_point = NULL; - break; - case 'e': - entry_point = argv[++i]; - break; - case 't': - turn = atoi(argv[++i]); - break; - case 'q': - verbosity = 0; - break; - case 'v': - verbosity = atoi(argv[++i]); - break; - case 'h': - usage(argv[0], NULL); - return 1; - default: - *exitcode = -1; - usage(argv[0], argv[i]); - return 1; - } - } - - if (run_tests) { - *exitcode = RunAllTests(); - return 1; - } - - return 0; -} - -#if defined(HAVE_SIGACTION) && defined(HAVE_EXECINFO) -#include <execinfo.h> -#include <signal.h> - -static void -report_segfault(int signo, siginfo_t * sinf, void * arg) -{ - void * btrace[50]; - size_t size; - int fd = fileno(stderr); - - fflush(stdout); - fputs("\n\nProgram received SIGSEGV, backtrace follows.\n", stderr); - size = backtrace(btrace, 50); - backtrace_symbols_fd(btrace, size, fd); - abort(); -} - -static int -setup_signal_handler(void) -{ - struct sigaction act; - - act.sa_flags = SA_ONESHOT | SA_SIGINFO; - act.sa_sigaction = report_segfault; - sigfillset(&act.sa_mask); - return sigaction(SIGSEGV, &act, NULL); -} -#else -static int -setup_signal_handler(void) -{ - return 0; -} -#endif - -#undef CRTDBG -#ifdef CRTDBG -#include <crtdbg.h> -void -init_crtdbg(void) -{ -#if (defined(_MSC_VER)) - int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); - if (memdebug==1) { - flags |= _CRTDBG_CHECK_ALWAYS_DF; /* expensive */ - } else if (memdebug==2) { - flags = (flags&0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF; - } else if (memdebug==3) { - flags = (flags&0x0000FFFF) | _CRTDBG_CHECK_EVERY_128_DF; - } else if (memdebug==4) { - flags = (flags&0x0000FFFF) | _CRTDBG_CHECK_EVERY_1024_DF; - } - _CrtSetDbgFlag(flags); -#endif -} -#endif - - -static void -write_spells(void) -{ - struct locale * loc = find_locale("de"); - FILE * F = fopen("spells.csv", "w"); - spell_list * spl = spells; - for (;spl;spl=spl->next) { - const spell * sp = spl->data; - spell_component * spc = sp->components; - char components[128]; - components[0]=0; - for (;spc->type;++spc) { - strcat(components, LOC(loc, spc->type->_name[0])); - strcat(components, ","); - } - fprintf(F, "%s;%d;%s;%s\n", LOC(loc, mkname("spell", sp->sname)), sp->level, LOC(loc, mkname("school", magic_school[sp->magietyp])), components); - } - fclose(F); -} - -static void -write_skills(void) -{ - struct locale * loc = find_locale("de"); - FILE * F = fopen("skills.csv", "w"); - race * rc; - skill_t sk; - fputs("\"Rasse\",", F); - for (rc=races;rc;rc = rc->next) { - if (playerrace(rc)) { - fprintf(F, "\"%s\",", LOC(loc, mkname("race", rc->_name[0]))); - } - } - fputc('\n', F); - - for (sk=0;sk!=MAXSKILLS;++sk) { - const char * str = skillname(sk, loc); - if (str) { - fprintf(F, "\"%s\",", str); - for (rc=races;rc;rc = rc->next) { - if (playerrace(rc)) { - if (rc->bonus[sk]) fprintf(F, "%d,", rc->bonus[sk]); - else fputc(',', F); - } - } - fputc('\n', F); - } - } - fclose(F); -} - -void locale_init(void) -{ - setlocale(LC_CTYPE, ""); - setlocale(LC_NUMERIC, "C"); - if (towlower(0xC4)!=0xE4) { /* Ä => ä */ - log_error(("Umlaut conversion is not working properly. Wrong locale? LANG=%s\n", getenv("LANG"))); - } -} - -extern void bind_eressea(struct lua_State * L); - -int main(int argc, char ** argv) -{ - static int write_csv = 0; - int err, result = 0; - - setup_signal_handler(); - - parse_config(inifile); - - err = parse_args(argc, argv, &result); - if (err) { - return result; - } - - log_open("eressea.log"); - locale_init(); - -#ifdef CRTDBG - init_crtdbg(); -#endif - - err = eressea_init(); - if (err) { - log_error(("initialization failed with code %d\n", err)); - return err; - } - register_races(); - register_curses(); - register_spells(); - bind_eressea((struct lua_State *)global.vm_state); - - if (write_csv) { - write_skills(); - write_spells(); - } - - err = eressea_run(luafile, entry_point); - if (err) { - log_error(("server execution failed with code %d\n", err)); - return err; - } - -#ifdef MSPACES - malloc_stats(); -#endif - - eressea_done(); - log_close(); - if (global.inifile) iniparser_free(global.inifile); - return 0; -} +#include <platform.h> +#include <util/log.h> + +#include <eressea.h> +#include <gmtool.h> +#include <kernel/config.h> +#include <kernel/save.h> +#include <iniparser/iniparser.h> +#include "races/races.h" + +#include <assert.h> +#include <locale.h> +#include <wctype.h> + +#include <tests.h> + +static const char * luafile = "setup.lua"; +static const char * entry_point = NULL; +static const char * inifile = "eressea.ini"; +static int memdebug = 0; + +static void parse_config(const char * filename) +{ + dictionary * d = iniparser_new(filename); + if (d) { + load_inifile(d); + + memdebug = iniparser_getint(d, "eressea:memcheck", memdebug); + entry_point = iniparser_getstring(d, "eressea:run", entry_point); + luafile = iniparser_getstring(d, "eressea:load", luafile); + + /* only one value in the [editor] section */ + force_color = iniparser_getint(d, "editor:color", force_color); + + /* excerpt from [config] (the rest is used in bindings.c) */ + game_name = iniparser_getstring(d, "config:game", game_name); + } + global.inifile = d; +} + +static int +usage(const char * prog, const char * arg) +{ + if (arg) { + fprintf(stderr, "unknown argument: %s\n\n", arg); + } + fprintf(stderr, "Usage: %s [options]\n" + "-t <turn> : read this datafile, not the most current one\n" + "-q : be quite (same as -v 0)\n" + "-v <level> : verbosity level\n" + "-C : run in interactive mode\n" + "--color : force curses to use colors even when not detected\n" + "--tests : run testsuite\n" + "--help : help\n", prog); + return -1; +} + +static int +parse_args(int argc, char **argv, int *exitcode) +{ + int i; + int run_tests = 0; + + for (i=1;i!=argc;++i) { + if (argv[i][0]!='-') { + return usage(argv[0], argv[i]); + } else if (argv[i][1]=='-') { /* long format */ + if (strcmp(argv[i]+2, "version")==0) { + printf("\n%s PBEM host\n" + "Copyright (C) 1996-2005 C. Schlittchen, K. Zedel, E. Rehling, H. Peters.\n\n" + "Compilation: " __DATE__ " at " __TIME__ "\nVersion: %f\n\n", global.gamename, version()); + } + else if (strcmp(argv[i]+2, "color")==0) { + /* force the editor to have colors */ + force_color = 1; + } + else if (strcmp(argv[i]+2, "tests")==0) { + /* force the editor to have colors */ + run_tests = 1; + } + else if (strcmp(argv[i]+2, "help")==0) { + return usage(argv[0], NULL); + } + else { + return usage(argv[0], argv[i]); + } + } else switch(argv[i][1]) { + case 'C': + entry_point = NULL; + break; + case 'e': + entry_point = argv[++i]; + break; + case 't': + turn = atoi(argv[++i]); + break; + case 'q': + verbosity = 0; + break; + case 'v': + verbosity = atoi(argv[++i]); + break; + case 'h': + usage(argv[0], NULL); + return 1; + default: + *exitcode = -1; + usage(argv[0], argv[i]); + return 1; + } + } + + if (run_tests) { + *exitcode = RunAllTests(); + return 1; + } + + return 0; +} + +#if defined(HAVE_SIGACTION) && defined(HAVE_EXECINFO) +#include <execinfo.h> +#include <signal.h> + +static void +report_segfault(int signo, siginfo_t * sinf, void * arg) +{ + void * btrace[50]; + size_t size; + int fd = fileno(stderr); + + fflush(stdout); + fputs("\n\nProgram received SIGSEGV, backtrace follows.\n", stderr); + size = backtrace(btrace, 50); + backtrace_symbols_fd(btrace, size, fd); + abort(); +} + +static int +setup_signal_handler(void) +{ + struct sigaction act; + + act.sa_flags = SA_ONESHOT | SA_SIGINFO; + act.sa_sigaction = report_segfault; + sigfillset(&act.sa_mask); + return sigaction(SIGSEGV, &act, NULL); +} +#else +static int +setup_signal_handler(void) +{ + return 0; +} +#endif + +#undef CRTDBG +#ifdef CRTDBG +#include <crtdbg.h> +void +init_crtdbg(void) +{ +#if (defined(_MSC_VER)) + int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + if (memdebug==1) { + flags |= _CRTDBG_CHECK_ALWAYS_DF; /* expensive */ + } else if (memdebug==2) { + flags = (flags&0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF; + } else if (memdebug==3) { + flags = (flags&0x0000FFFF) | _CRTDBG_CHECK_EVERY_128_DF; + } else if (memdebug==4) { + flags = (flags&0x0000FFFF) | _CRTDBG_CHECK_EVERY_1024_DF; + } + _CrtSetDbgFlag(flags); +#endif +} +#endif + + +static void +write_spells(void) +{ + struct locale * loc = find_locale("de"); + FILE * F = fopen("spells.csv", "w"); + spell_list * spl = spells; + for (;spl;spl=spl->next) { + const spell * sp = spl->data; + spell_component * spc = sp->components; + char components[128]; + components[0]=0; + for (;spc->type;++spc) { + strcat(components, LOC(loc, spc->type->_name[0])); + strcat(components, ","); + } + fprintf(F, "%s;%d;%s;%s\n", LOC(loc, mkname("spell", sp->sname)), sp->level, LOC(loc, mkname("school", magic_school[sp->magietyp])), components); + } + fclose(F); +} + +static void +write_skills(void) +{ + struct locale * loc = find_locale("de"); + FILE * F = fopen("skills.csv", "w"); + race * rc; + skill_t sk; + fputs("\"Rasse\",", F); + for (rc=races;rc;rc = rc->next) { + if (playerrace(rc)) { + fprintf(F, "\"%s\",", LOC(loc, mkname("race", rc->_name[0]))); + } + } + fputc('\n', F); + + for (sk=0;sk!=MAXSKILLS;++sk) { + const char * str = skillname(sk, loc); + if (str) { + fprintf(F, "\"%s\",", str); + for (rc=races;rc;rc = rc->next) { + if (playerrace(rc)) { + if (rc->bonus[sk]) fprintf(F, "%d,", rc->bonus[sk]); + else fputc(',', F); + } + } + fputc('\n', F); + } + } + fclose(F); +} + +void locale_init(void) +{ + setlocale(LC_CTYPE, ""); + setlocale(LC_NUMERIC, "C"); + if (towlower(0xC4)!=0xE4) { /* Ä => ä */ + log_error(("Umlaut conversion is not working properly. Wrong locale? LANG=%s\n", getenv("LANG"))); + } +} + +extern void bind_eressea(struct lua_State * L); + +int main(int argc, char ** argv) +{ + static int write_csv = 0; + int err, result = 0; + + setup_signal_handler(); + + parse_config(inifile); + + err = parse_args(argc, argv, &result); + if (err) { + return result; + } + + log_open("eressea.log"); + locale_init(); + +#ifdef CRTDBG + init_crtdbg(); +#endif + + err = eressea_init(); + if (err) { + log_error(("initialization failed with code %d\n", err)); + return err; + } + register_races(); + register_curses(); + register_spells(); + bind_eressea((struct lua_State *)global.vm_state); + + if (write_csv) { + write_skills(); + write_spells(); + } + + err = eressea_run(luafile, entry_point); + if (err) { + log_error(("server execution failed with code %d\n", err)); + return err; + } + +#ifdef MSPACES + malloc_stats(); +#endif + + eressea_done(); + log_close(); + if (global.inifile) iniparser_free(global.inifile); + return 0; +} diff --git a/src/monsters.c b/src/monsters.c index c80915ee7..e9418e7f6 100644 --- a/src/monsters.c +++ b/src/monsters.c @@ -1,1003 +1,1003 @@ -/* vi: set ts=2: - * - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * based on: - * - * Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace - * Atlantis v1.7 Copyright 1996 by Alex Schr�der - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - * This program may not be sold or used commercially without prior written - * permission from the authors. - */ - -#include <platform.h> -#include <kernel/config.h> - -/* triggers includes */ -#include <triggers/removecurse.h> - -/* attributes includes */ -#include <attributes/targetregion.h> -#include <attributes/hate.h> - -/* kernel includes */ -#include <kernel/build.h> -#include <kernel/equipment.h> -#include <kernel/faction.h> -#include <kernel/item.h> -#include <kernel/message.h> -#include <kernel/move.h> -#include <kernel/names.h> -#include <kernel/order.h> -#include <kernel/pathfinder.h> -#include <kernel/pool.h> -#include <kernel/race.h> -#include <kernel/region.h> -#include <kernel/reports.h> -#include <kernel/skill.h> -#include <kernel/terrain.h> -#include <kernel/terrainid.h> -#include <kernel/unit.h> - -#include <gamecode/economy.h> -#include <gamecode/give.h> -#include <gamecode/monster.h> - -/* util includes */ -#include <util/attrib.h> -#include <util/base36.h> -#include <util/bsdstring.h> -#include <util/event.h> -#include <util/language.h> -#include <util/lists.h> -#include <util/log.h> -#include <util/rand.h> -#include <util/rng.h> - -/* libc includes */ -#include <stdio.h> -#include <string.h> -#include <assert.h> - -#define MOVECHANCE 25 /* chance fuer bewegung */ -#define DRAGON_RANGE 20 /* Max. Distanz zum n�chsten Drachenziel */ -#define MAXILLUSION_TEXTS 3 - -static void -reduce_weight(unit * u) -{ - int capacity, weight = 0; - item ** itmp = &u->items; - int horses = get_resource(u, oldresourcetype[R_HORSE]); - - if (horses > 0) { - horses = MIN(horses, (u->number*2)); - change_resource(u, oldresourcetype[R_HORSE], - horses); - } - - /* 0. ditch any vehicles */ - while (*itmp!=NULL) { - item * itm = *itmp; - const item_type * itype = itm->type; - weight += itm->number*itype->weight; - if (itype->flags & ITF_VEHICLE) { - give_item(itm->number, itm->type, u, NULL, NULL); - } - if (*itmp==itm) itmp=&itm->next; - } - - capacity = walkingcapacity(u); - - /* 1. get rid of anything that isn't silver or really lightweight or helpful in combat */ - for (itmp = &u->items;*itmp && capacity>0;) { - item * itm = *itmp; - const item_type * itype = itm->type; - weight += itm->number*itype->weight; - if (weight>capacity) { - if (itype->weight>=10 && itype->rtype->wtype==0 && itype->rtype->atype==0) { - if (itype->capacity < itype->weight) { - int reduce = MIN(itm->number, -((capacity-weight)/itype->weight)); - give_item(reduce, itm->type, u, NULL, NULL); - weight -= reduce * itype->weight; - } - } - } - if (*itmp==itm) itmp=&itm->next; - } - - for (itmp = &u->items;*itmp && weight>capacity;) { - item * itm = *itmp; - const item_type * itype = itm->type; - weight += itm->number*itype->weight; - if (itype->capacity < itype->weight) { - int reduce = MIN(itm->number, -((capacity-weight)/itype->weight)); - give_item(reduce, itm->type, u, NULL, NULL); - weight -= reduce * itype->weight; - } - if (*itmp==itm) itmp=&itm->next; - } -} - -static order * -monster_attack(unit * u, const unit * target) -{ - if (u->region!=target->region) return NULL; - if (u->faction==target->faction) return NULL; - if (!cansee(u->faction, u->region, target, 0)) return NULL; - if (monster_is_waiting(u)) return NULL; - - return create_order(K_ATTACK, u->faction->locale, "%i", target->no); -} - - -static order * -get_money_for_dragon(region * r, unit * u, int wanted) -{ - unit *u2; - int n; - - /* attackiere bewachende einheiten */ - for (u2 = r->units; u2; u2 = u2->next) { - if (u2 != u && is_guard(u2, GUARD_TAX)) { - order * ord = monster_attack(u, u2); - if (ord) addlist(&u->orders, ord); - } - } - - /* falls genug geld in der region ist, treiben wir steuern ein. */ - if (rmoney(r) >= wanted) { - /* 5% chance, dass der drache aus einer laune raus attackiert */ - if (chance(1.0-u->race->aggression)) { - return create_order(K_TAX, default_locale, NULL); - } - } - - /* falls der drache launisch ist, oder das regionssilber knapp, greift er alle an */ - n = 0; - for (u2 = r->units; u2; u2 = u2->next) { - if (u2->faction != u->faction && cansee(u->faction, r, u2, 0)) { - int m = get_money(u2); - if (m==0 || is_guard(u2, GUARD_TAX)) continue; - else { - order * ord = monster_attack(u, u2); - if (ord) { - addlist(&u->orders, ord); - n += m; - } - } - } - } - - /* falls die einnahmen erreicht werden, bleibt das monster noch eine - * runde hier. */ - if (n + rmoney(r) >= wanted) { - return create_order(K_TAX, default_locale, NULL); - } - - /* wenn wir NULL zur�ckliefern, macht der drache was anderes, z.b. weggehen */ - return NULL; -} - -static int -all_money(region * r, faction * f) -{ - unit *u; - int m; - - m = rmoney(r); - for (u = r->units; u; u = u->next) { - if (f!=u->faction) { - m += get_money(u); - } - } - return m; -} - -static direction_t -richest_neighbour(region * r, faction * f, int absolut) -{ - - /* m - maximum an Geld, d - Richtung, i - index, t = Geld hier */ - - double m; - double t; - direction_t d = NODIRECTION, i; - - if (absolut == 1 || rpeasants(r) == 0) { - m = (double) all_money(r, f); - } else { - m = (double) all_money(r, f) / (double) rpeasants(r); - } - - /* finde die region mit dem meisten geld */ - - for (i = 0; i != MAXDIRECTIONS; i++) { - region * rn = rconnect(r, i); - if (rn!=NULL && fval(rn->terrain, LAND_REGION)) { - if (absolut == 1 || rpeasants(rn) == 0) { - t = (double) all_money(rn, f); - } else { - t = (double) all_money(rn, f) / (double) rpeasants(rn); - } - - if (t > m) { - m = t; - d = i; - } - } - } - return d; -} - -static boolean -room_for_race_in_region(region *r, const race * rc) -{ - unit *u; - int c = 0; - - for(u=r->units;u;u=u->next) { - if(u->race == rc) c += u->number; - } - - if(c > (rc->splitsize*2)) - return false; - - return true; -} - -static direction_t -random_neighbour(region * r, unit *u) -{ - direction_t i; - region *rc; - int rr, c = 0, c2 = 0; - - /* Nachsehen, wieviele Regionen in Frage kommen */ - - for (i = 0; i != MAXDIRECTIONS; i++) { - rc = rconnect(r, i); - if (rc && can_survive(u, rc)) { - if(room_for_race_in_region(rc, u->race)) { - c++; - } - c2++; - } - } - - if (c == 0) { - if(c2 == 0) { - return NODIRECTION; - } else { - c = c2; - c2 = 0; /* c2 == 0 -> room_for_race nicht beachten */ - } - } - - /* Zuf�llig eine ausw�hlen */ - - rr = rng_int() % c; - - /* Durchz�hlen */ - - c = -1; - for (i = 0; i != MAXDIRECTIONS; i++) { - rc = rconnect(r, i); - if (rc && can_survive(u, rc)) { - if(c2 == 0) { - c++; - } else if(room_for_race_in_region(rc, u->race)) { - c++; - } - if (c == rr) return i; - } - } - - assert(1 == 0); /* Bis hierhin sollte er niemals kommen. */ - return NODIRECTION; -} - -static direction_t -treeman_neighbour(region * r) -{ - direction_t i; - int rr; - int c = 0; - - /* Nachsehen, wieviele Regionen in Frage kommen */ - - for (i = 0; i != MAXDIRECTIONS; i++) { - if (rconnect(r, i) - && rterrain(rconnect(r, i)) != T_OCEAN - && rterrain(rconnect(r, i)) != T_GLACIER - && rterrain(rconnect(r, i)) != T_DESERT) { - c++; - } - } - - if (c == 0) { - return NODIRECTION; - } - /* Zuf�llig eine ausw�hlen */ - - rr = rng_int() % c; - - /* Durchz�hlen */ - - c = -1; - for (i = 0; i != MAXDIRECTIONS; i++) { - if (rconnect(r, i) - && rterrain(rconnect(r, i)) != T_OCEAN - && rterrain(rconnect(r, i)) != T_GLACIER - && rterrain(rconnect(r, i)) != T_DESERT) { - c++; - if (c == rr) { - return i; - } - } - } - - assert(1 == 0); /* Bis hierhin sollte er niemals kommen. */ - return NODIRECTION; -} - -static order * -monster_move(region * r, unit * u) -{ - direction_t d = NODIRECTION; - - if (monster_is_waiting(u)) return NULL; - switch(old_race(u->race)) { - case RC_FIREDRAGON: - case RC_DRAGON: - case RC_WYRM: - d = richest_neighbour(r, u->faction, 1); - break; - case RC_TREEMAN: - d = treeman_neighbour(r); - break; - default: - d = random_neighbour(r,u); - break; - } - - /* falls kein geld gefunden wird, zufaellig verreisen, aber nicht in - * den ozean */ - - if (d == NODIRECTION) - return NULL; - - reduce_weight(u); - return create_order(K_MOVE, u->faction->locale, "%s", LOC(u->faction->locale, directions[d])); -} - -static int -dragon_affinity_value(region *r, unit *u) -{ - int m = all_money(r, u->faction); - - if(u->race == new_race[RC_FIREDRAGON]) { - return (int)(normalvariate(m,m/2)); - } else { - return (int)(normalvariate(m,m/4)); - } -} - -static attrib * -set_new_dragon_target(unit * u, region * r, int range) -{ - int max_affinity = 0; - region *max_region = NULL; - -#if 1 - region_list * rptr, * rlist = regions_in_range(r, range, allowed_dragon); - for (rptr=rlist;rptr;rptr=rptr->next) { - region * r2 = rptr->data; - int affinity = dragon_affinity_value(r2, u); - if (affinity > max_affinity) { - max_affinity = affinity; - max_region = r2; - } - } - - free_regionlist(rlist); -#else - int tx, ty; - for (tx = r->x - range; tx < r->x + range; tx++) { - for (ty = r->y - range; ty < r->y + range; ty++) { - region * r2; - int x = tx, y = ty; - pnormalize(&x, &y, r->planep); - r2 = findregion(x, y); - if (r2!=NULL) { - int affinity = dragon_affinity_value(r2, u); - if (affinity > max_affinity) { - if (koor_distance (r->x, r->y, x, y) <= range && path_exists(r, r2, range, allowed_dragon)) - { - max_affinity = affinity; - max_region = r2; - } - } - } - } - } -#endif - if (max_region && max_region != r) { - attrib * a = a_find(u->attribs, &at_targetregion); - if (!a) { - a = a_add(&u->attribs, make_targetregion(max_region)); - } else { - a->data.v = max_region; - } - return a; - } - return NULL; -} - -static order * -make_movement_order(unit * u, const region * target, int moves, boolean (*allowed)(const region *, const region *)) -{ - region * r = u->region; - region ** plan; - int bytes, position = 0; - char zOrder[128], * bufp = zOrder; - size_t size = sizeof(zOrder) - 1; - - if (monster_is_waiting(u)) return NULL; - - plan = path_find(r, target, DRAGON_RANGE*5, allowed); - if (plan==NULL) return NULL; - - bytes = (int)strlcpy(bufp, (const char *)LOC(u->faction->locale, keywords[K_MOVE]), size); - if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER(); - - while (position!=moves && plan[position+1]) { - region * prev = plan[position]; - region * next = plan[++position]; - direction_t dir = reldirection(prev, next); - assert(dir!=NODIRECTION && dir!=D_SPECIAL); - if (size>1) { - *bufp++ = ' '; - --size; - } - bytes = (int)strlcpy(bufp, (const char *)LOC(u->faction->locale, directions[dir]), size); - if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER(); - } - - *bufp = 0; - return parse_order(zOrder, u->faction->locale); -} - -#ifdef TODO_ALP -static order * -monster_seeks_target(region *r, unit *u) -{ - direction_t d; - unit *target = NULL; - int dist, dist2; - direction_t i; - region *nr; - - /* Das Monster sucht ein bestimmtes Opfer. Welches, steht - * in einer Referenz/attribut - * derzeit gibt es nur den alp - */ - - switch( old_race(u->race) ) { - case RC_ALP: - target = alp_target(u); - break; - default: - assert(!"Seeker-Monster gibt kein Ziel an"); - } - - /* TODO: pr�fen, ob target �berhaupt noch existiert... */ - if (!target) { - log_error(("Monster '%s' hat kein Ziel!\n", unitname(u))); - return NULL; /* this is a bug workaround! remove!! */ - } - - if(r == target->region ) { /* Wir haben ihn! */ - if (u->race == new_race[RC_ALP]) { - alp_findet_opfer(u, r); - } - else { - assert(!"Seeker-Monster hat keine Aktion fuer Ziel"); - } - return NULL; - } - - /* Simpler Ansatz: Nachbarregion mit gerinster Distanz suchen. - * Sinnvoll momentan nur bei Monstern, die sich nicht um das - * Terrain k�mmern. Nebelw�nde & Co machen derzeit auch nix... - */ - dist2 = distance(r, target->region); - d = NODIRECTION; - for( i = 0; i < MAXDIRECTIONS; i++ ) { - nr = rconnect(r, i); - assert(nr); - dist = distance(nr, target->region); - if( dist < dist2 ) { - dist2 = dist; - d = i; - } - } - assert(d != NODIRECTION ); - - return create_order(K_MOVE, u->faction->locale, "%s", LOC(u->faction->locale, directions[d])); -} -#endif - -static void -monster_attacks(unit * u) -{ - region * r = u->region; - unit * u2; - - for (u2=r->units;u2;u2=u2->next) { - if (u2->faction!=u->faction && chance(0.75)) { - order * ord = monster_attack(u, u2); - if (ord) addlist(&u->orders, ord); - } - } -} - -static const char * -random_growl(void) -{ - switch(rng_int()%5) { - case 0: - return "Groammm"; - case 1: - return "Roaaarrrr"; - case 2: - return "Chhhhhhhhhh"; - case 3: - return "Tschrrrkk"; - case 4: - return "Schhhh"; - } - return ""; -} - -extern struct attrib_type at_direction; - -static order * -monster_learn(unit *u) -{ - int c = 0; - int n; - skill * sv; - const struct locale * lang = u->faction->locale; - - /* Monster lernt ein zuf�lliges Talent aus allen, in denen es schon - * Lerntage hat. */ - - for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { - if (sv->level>0) ++c; - } - - if(c == 0) return NULL; - - n = rng_int()%c + 1; - c = 0; - - for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { - if (sv->level>0) { - if (++c == n) { - return create_order(K_STUDY, lang, "'%s'", skillname(sv->id, lang)); - } - } - } - return NULL; -} - -static boolean -check_overpopulated(unit *u) -{ - unit *u2; - int c = 0; - - for(u2 = u->region->units; u2; u2 = u2->next) { - if(u2->race == u->race && u != u2) c += u2->number; - } - - if(c > u->race->splitsize * 2) return true; - - return false; -} - -static void -recruit_dracoids(unit * dragon, int size) -{ - faction * f = dragon->faction; - region * r = dragon->region; - const struct item * weapon = NULL; - order * new_order = NULL; - unit *un = createunit(r, f, size, new_race[RC_DRACOID]); - - fset(un, UFL_ISNEW|UFL_MOVED); - - name_unit(un); - change_money(dragon, -un->number * 50); - equip_unit(un, get_equipment("recruited_dracoid")); - - setstatus(un, ST_FIGHT); - for (weapon=un->items;weapon;weapon=weapon->next) { - const weapon_type * wtype = weapon->type->rtype->wtype; - if (wtype && (wtype->flags & WTF_MISSILE)) { - setstatus(un, ST_BEHIND); - } - new_order = create_order(K_STUDY, f->locale, "'%s'", - skillname(weapon->type->rtype->wtype->skill, f->locale)); - } - - if (new_order!=NULL) { - addlist(&un->orders, new_order); - } -} - -static order * -plan_dragon(unit * u) -{ - attrib * ta = a_find(u->attribs, &at_targetregion); - region * r = u->region; - region * tr = NULL; - boolean move = false; - order * long_order = NULL; - - reduce_weight(u); - - if (ta==NULL) { - move |= (r->land==0 || r->land->peasants==0); /* when no peasants, move */ - move |= (r->land==0 || r->land->money==0); /* when no money, move */ - } - move |= chance(0.04); /* 4% chance to change your mind */ - - if (u->race==new_race[RC_WYRM] && !move) { - unit * u2; - for (u2=r->units;u2;u2=u2->next) { - /* wyrme sind einzelg�nger */ - if (u2==u) { - /* we do not make room for newcomers, so we don't need to look at them */ - break; - } - if (u2!=u && u2->race==u->race && chance(0.5)) { - move = true; - break; - } - } - } - - if (move) { - /* dragon gets bored and looks for a different place to go */ - ta = set_new_dragon_target(u, u->region, DRAGON_RANGE); - } - else ta = a_find(u->attribs, &at_targetregion); - if (ta!=NULL) { - tr = (region *) ta->data.v; - if (tr==NULL || !path_exists(u->region, tr, DRAGON_RANGE, allowed_dragon)) { - ta = set_new_dragon_target(u, u->region, DRAGON_RANGE); - if (ta) tr = findregion(ta->data.sa[0], ta->data.sa[1]); - } - } - if (tr!=NULL) { - assert(long_order==NULL); - switch(old_race(u->race)) { - case RC_FIREDRAGON: - long_order = make_movement_order(u, tr, 4, allowed_dragon); - break; - case RC_DRAGON: - long_order = make_movement_order(u, tr, 3, allowed_dragon); - break; - case RC_WYRM: - long_order = make_movement_order(u, tr, 1, allowed_dragon); - break; - } - if (rng_int()%100 < 15) { - const struct locale * lang = u->faction->locale; - /* do a growl */ - if (rname(tr, lang)) { - addlist(&u->orders, create_order(K_MAIL, lang, "%s '%s... %s %s %s'", - LOC(lang, parameters[P_REGION]), random_growl(), - u->number==1?"Ich rieche":"Wir riechen", - "etwas in", rname(tr, u->faction->locale))); - } - } - } else { - /* we have no target. do we like it here, then? */ - long_order = get_money_for_dragon(u->region, u, income(u)); - if (long_order==NULL) { - /* money is gone, need a new target */ - set_new_dragon_target(u, u->region, DRAGON_RANGE); - } - else if (u->race != new_race[RC_FIREDRAGON]) { - /* neue dracoiden! */ - if (r->land && !fval(r->terrain, FORBIDDEN_REGION)) { - int ra = 20 + rng_int() % 100; - if (get_money(u) > ra * 50 + 100 && rng_int() % 100 < 50) { - recruit_dracoids(u, ra); - } - } - } - } - if (long_order==NULL) { - skill_t sk = SK_PERCEPTION; - /* study perception (or a random useful skill) */ - while (!skill_enabled[sk] || u->race->bonus[sk]<-5) { - sk = (skill_t)(rng_int() % MAXSKILLS); - } - long_order = create_order(K_STUDY, u->faction->locale, "'%s'", - skillname(sk, u->faction->locale)); - } - return long_order; -} - -void -plan_monsters(faction * f) -{ - region *r; - - assert(f); - f->lastorders = turn; - - for (r = regions; r; r = r->next) { - unit *u; - double attack_chance = MONSTERATTACK; - boolean attacking = false; - - for (u = r->units; u; u = u->next) { - attrib * ta; - order * long_order = NULL; - - /* Ab hier nur noch Befehle f�r NPC-Einheiten. */ - if (!is_monsters(u->faction)) continue; - - if (attack_chance>0.0) { - if (chance(attack_chance)) attacking = true; - attack_chance = 0.0; - } - - if (u->status>ST_BEHIND) { - setstatus(u, ST_FIGHT); - /* all monsters fight */ - } - if (skill_enabled[SK_PERCEPTION]) { - /* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */ - /* TODO: this only works for playerrace */ - produceexp(u, SK_PERCEPTION, u->number); - } - - /* Befehle m�ssen jede Runde neu gegeben werden: */ - free_orders(&u->orders); - - if (attacking) { - monster_attacks(u); - } - /* units with a plan to kill get ATTACK orders: */ - ta = a_find(u->attribs, &at_hate); - if (ta && !monster_is_waiting(u)) { - unit * tu = (unit *)ta->data.v; - if (tu && tu->region==r) { - addlist(&u->orders, create_order(K_ATTACK, u->faction->locale, "%i", tu->no)); - } else if (tu) { - tu = findunitg(ta->data.i, NULL); - if (tu!=NULL) { - long_order = make_movement_order(u, tu->region, 2, allowed_walk); - } - } - else a_remove(&u->attribs, ta); - } - - /* All monsters guard the region: */ - if (!monster_is_waiting(u) && r->land) { - addlist(&u->orders, create_order(K_GUARD, u->faction->locale, NULL)); - } - - /* Einheiten mit Bewegungsplan kriegen ein NACH: */ - if (long_order==NULL) { - attrib * ta = a_find(u->attribs, &at_targetregion); - if (ta) { - if (u->region == (region*)ta->data.v) { - a_remove(&u->attribs, ta); - } - } else if (u->race->flags & RCF_MOVERANDOM) { - if (rng_int()%100<MOVECHANCE || check_overpopulated(u)) { - long_order = monster_move(r, u); - } - } - } - - if (long_order==NULL) { - /* Einheiten, die Waffenlosen Kampf lernen k�nnten, lernen es um - * zu bewachen: */ - if (u->race->bonus[SK_WEAPONLESS] != -99) { - if (eff_skill(u, SK_WEAPONLESS, u->region) < 1) { - long_order = create_order(K_STUDY, f->locale, "'%s'", skillname(SK_WEAPONLESS, f->locale)); - } - } - } - - if (long_order==NULL) { - /* Ab hier noch nicht generalisierte Spezialbehandlungen. */ - - if (!u->orders) { - handle_event(u->attribs, "ai_move", u); - } - - switch (old_race(u->race)) { - case RC_SEASERPENT: - long_order = create_order(K_PIRACY, f->locale, NULL); - break; -#ifdef TODO_ALP - case RC_ALP: - long_order = monster_seeks_target(r, u); - break; -#endif - case RC_FIREDRAGON: - case RC_DRAGON: - case RC_WYRM: - long_order = plan_dragon(u); - break; - default: - if (u->race->flags & RCF_LEARN) { - long_order = monster_learn(u); - } - break; - } - } - if (long_order) { - addlist(&u->orders, long_order); - } - } - } - pathfinder_cleanup(); -} - -static double -chaosfactor(region * r) -{ - attrib * a = a_find(r->attribs, &at_chaoscount); - if (!a) return 0; - return ((double) a->data.i / 1000.0); -} - -static int -nrand(int start, int sub) -{ - int res = 0; - - do { - if (rng_int() % 100 < start) - res++; - start -= sub; - } while (start > 0); - - return res; -} - -/** Drachen und Seeschlangen k�nnen entstehen */ -void -spawn_dragons(void) -{ - region * r; - faction * monsters = get_monsters(); - - for (r = regions; r; r = r->next) { - unit * u; - - if (fval(r->terrain, SEA_REGION) && rng_int()%10000 < 1) { - u = createunit(r, monsters, 1, new_race[RC_SEASERPENT]); - fset(u, UFL_ISNEW|UFL_MOVED); - equip_unit(u, get_equipment("monster_seaserpent")); - } - - if ((r->terrain == newterrain(T_GLACIER) || r->terrain == newterrain(T_SWAMP) || r->terrain == newterrain(T_DESERT)) && rng_int() % 10000 < (5 + 100 * chaosfactor(r))) - { - if (chance(0.80)) { - u = createunit(r, monsters, nrand(60, 20) + 1, new_race[RC_FIREDRAGON]); - } else { - u = createunit(r, monsters, nrand(30, 20) + 1, new_race[RC_DRAGON]); - } - fset(u, UFL_ISNEW|UFL_MOVED); - equip_unit(u, get_equipment("monster_dragon")); - - if (verbosity>=2) { - log_printf("%d %s in %s.\n", u->number, - LOC(default_locale, rc_name(u->race, u->number!=1)), regionname(r, NULL)); - } - - name_unit(u); - - /* add message to the region */ - ADDMSG(&r->msgs, - msg_message("sighting", "region race number", r, u->race, u->number)); - } - } -} - -/** Untote k�nnen entstehen */ -void -spawn_undead(void) -{ - region * r; - faction * monsters = get_monsters(); - - for (r = regions; r; r = r->next) { - int unburied = deathcount(r); - static const curse_type * ctype = NULL; - - if (!ctype) ctype = ct_find("holyground"); - if (ctype && curse_active(get_curse(r->attribs, ctype))) continue; - - /* Chance 0.1% * chaosfactor */ - if (r->land && unburied > r->land->peasants / 20 && rng_int() % 10000 < (100 + 100 * chaosfactor(r))) { - unit * u; - /* es ist sinnfrei, wenn irgendwo im Wald 3er-Einheiten Untote entstehen. - * Lieber sammeln lassen, bis sie mindestens 5% der Bev�lkerung sind, und - * dann erst auferstehen. */ - int undead = unburied / (rng_int() % 2 + 1); - const race * rc = NULL; - int i; - if (r->age<100) undead = undead * r->age / 100; /* newbie-regionen kriegen weniger ab */ - - if (!undead || r->age < 20) continue; - - switch(rng_int()%3) { - case 0: - rc = new_race[RC_SKELETON]; break; - case 1: - rc = new_race[RC_ZOMBIE]; break; - default: - rc = new_race[RC_GHOUL]; break; - } - - u = createunit(r, monsters, undead, rc); - fset(u, UFL_ISNEW|UFL_MOVED); - if ((rc == new_race[RC_SKELETON] || rc == new_race[RC_ZOMBIE]) && rng_int()%10 < 4) { - equip_unit(u, get_equipment("rising_undead")); - } - - for (i=0;i < MAXSKILLS;i++) { - if (rc->bonus[i] >= 1) { - set_level(u, (skill_t)i, 1); - } - } - u->hp = unit_max_hp(u) * u->number; - - deathcounts(r, -undead); - name_unit(u); - - if (verbosity>=2) { - log_printf("%d %s in %s.\n", u->number, - LOC(default_locale, rc_name(u->race, u->number!=1)), regionname(r, NULL)); - } - - { - message * msg = msg_message("undeadrise", "region", r); - add_message(&r->msgs, msg); - for (u=r->units;u;u=u->next) freset(u->faction, FFL_SELECT); - for (u=r->units;u;u=u->next) { - if (fval(u->faction, FFL_SELECT)) continue; - fset(u->faction, FFL_SELECT); - add_message(&u->faction->msgs, msg); - } - msg_release(msg); - } - } else { - int i = deathcount(r); - if (i) { - /* Gr�ber verwittern, 3% der Untoten finden die ewige Ruhe */ - deathcounts(r, (int)(-i*0.03)); - } - } - } -} +/* vi: set ts=2: + * + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * based on: + * + * Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace + * Atlantis v1.7 Copyright 1996 by Alex Schr�der + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + * This program may not be sold or used commercially without prior written + * permission from the authors. + */ + +#include <platform.h> +#include <kernel/config.h> + +/* triggers includes */ +#include <triggers/removecurse.h> + +/* attributes includes */ +#include <attributes/targetregion.h> +#include <attributes/hate.h> + +/* kernel includes */ +#include <kernel/build.h> +#include <kernel/equipment.h> +#include <kernel/faction.h> +#include <kernel/item.h> +#include <kernel/message.h> +#include <kernel/move.h> +#include <kernel/names.h> +#include <kernel/order.h> +#include <kernel/pathfinder.h> +#include <kernel/pool.h> +#include <kernel/race.h> +#include <kernel/region.h> +#include <kernel/reports.h> +#include <kernel/skill.h> +#include <kernel/terrain.h> +#include <kernel/terrainid.h> +#include <kernel/unit.h> + +#include <gamecode/economy.h> +#include <gamecode/give.h> +#include <gamecode/monster.h> + +/* util includes */ +#include <util/attrib.h> +#include <util/base36.h> +#include <util/bsdstring.h> +#include <util/event.h> +#include <util/language.h> +#include <util/lists.h> +#include <util/log.h> +#include <util/rand.h> +#include <util/rng.h> + +/* libc includes */ +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#define MOVECHANCE 25 /* chance fuer bewegung */ +#define DRAGON_RANGE 20 /* Max. Distanz zum n�chsten Drachenziel */ +#define MAXILLUSION_TEXTS 3 + +static void +reduce_weight(unit * u) +{ + int capacity, weight = 0; + item ** itmp = &u->items; + int horses = get_resource(u, oldresourcetype[R_HORSE]); + + if (horses > 0) { + horses = MIN(horses, (u->number*2)); + change_resource(u, oldresourcetype[R_HORSE], - horses); + } + + /* 0. ditch any vehicles */ + while (*itmp!=NULL) { + item * itm = *itmp; + const item_type * itype = itm->type; + weight += itm->number*itype->weight; + if (itype->flags & ITF_VEHICLE) { + give_item(itm->number, itm->type, u, NULL, NULL); + } + if (*itmp==itm) itmp=&itm->next; + } + + capacity = walkingcapacity(u); + + /* 1. get rid of anything that isn't silver or really lightweight or helpful in combat */ + for (itmp = &u->items;*itmp && capacity>0;) { + item * itm = *itmp; + const item_type * itype = itm->type; + weight += itm->number*itype->weight; + if (weight>capacity) { + if (itype->weight>=10 && itype->rtype->wtype==0 && itype->rtype->atype==0) { + if (itype->capacity < itype->weight) { + int reduce = MIN(itm->number, -((capacity-weight)/itype->weight)); + give_item(reduce, itm->type, u, NULL, NULL); + weight -= reduce * itype->weight; + } + } + } + if (*itmp==itm) itmp=&itm->next; + } + + for (itmp = &u->items;*itmp && weight>capacity;) { + item * itm = *itmp; + const item_type * itype = itm->type; + weight += itm->number*itype->weight; + if (itype->capacity < itype->weight) { + int reduce = MIN(itm->number, -((capacity-weight)/itype->weight)); + give_item(reduce, itm->type, u, NULL, NULL); + weight -= reduce * itype->weight; + } + if (*itmp==itm) itmp=&itm->next; + } +} + +static order * +monster_attack(unit * u, const unit * target) +{ + if (u->region!=target->region) return NULL; + if (u->faction==target->faction) return NULL; + if (!cansee(u->faction, u->region, target, 0)) return NULL; + if (monster_is_waiting(u)) return NULL; + + return create_order(K_ATTACK, u->faction->locale, "%i", target->no); +} + + +static order * +get_money_for_dragon(region * r, unit * u, int wanted) +{ + unit *u2; + int n; + + /* attackiere bewachende einheiten */ + for (u2 = r->units; u2; u2 = u2->next) { + if (u2 != u && is_guard(u2, GUARD_TAX)) { + order * ord = monster_attack(u, u2); + if (ord) addlist(&u->orders, ord); + } + } + + /* falls genug geld in der region ist, treiben wir steuern ein. */ + if (rmoney(r) >= wanted) { + /* 5% chance, dass der drache aus einer laune raus attackiert */ + if (chance(1.0-u->race->aggression)) { + return create_order(K_TAX, default_locale, NULL); + } + } + + /* falls der drache launisch ist, oder das regionssilber knapp, greift er alle an */ + n = 0; + for (u2 = r->units; u2; u2 = u2->next) { + if (u2->faction != u->faction && cansee(u->faction, r, u2, 0)) { + int m = get_money(u2); + if (m==0 || is_guard(u2, GUARD_TAX)) continue; + else { + order * ord = monster_attack(u, u2); + if (ord) { + addlist(&u->orders, ord); + n += m; + } + } + } + } + + /* falls die einnahmen erreicht werden, bleibt das monster noch eine + * runde hier. */ + if (n + rmoney(r) >= wanted) { + return create_order(K_TAX, default_locale, NULL); + } + + /* wenn wir NULL zur�ckliefern, macht der drache was anderes, z.b. weggehen */ + return NULL; +} + +static int +all_money(region * r, faction * f) +{ + unit *u; + int m; + + m = rmoney(r); + for (u = r->units; u; u = u->next) { + if (f!=u->faction) { + m += get_money(u); + } + } + return m; +} + +static direction_t +richest_neighbour(region * r, faction * f, int absolut) +{ + + /* m - maximum an Geld, d - Richtung, i - index, t = Geld hier */ + + double m; + double t; + direction_t d = NODIRECTION, i; + + if (absolut == 1 || rpeasants(r) == 0) { + m = (double) all_money(r, f); + } else { + m = (double) all_money(r, f) / (double) rpeasants(r); + } + + /* finde die region mit dem meisten geld */ + + for (i = 0; i != MAXDIRECTIONS; i++) { + region * rn = rconnect(r, i); + if (rn!=NULL && fval(rn->terrain, LAND_REGION)) { + if (absolut == 1 || rpeasants(rn) == 0) { + t = (double) all_money(rn, f); + } else { + t = (double) all_money(rn, f) / (double) rpeasants(rn); + } + + if (t > m) { + m = t; + d = i; + } + } + } + return d; +} + +static boolean +room_for_race_in_region(region *r, const race * rc) +{ + unit *u; + int c = 0; + + for(u=r->units;u;u=u->next) { + if(u->race == rc) c += u->number; + } + + if(c > (rc->splitsize*2)) + return false; + + return true; +} + +static direction_t +random_neighbour(region * r, unit *u) +{ + direction_t i; + region *rc; + int rr, c = 0, c2 = 0; + + /* Nachsehen, wieviele Regionen in Frage kommen */ + + for (i = 0; i != MAXDIRECTIONS; i++) { + rc = rconnect(r, i); + if (rc && can_survive(u, rc)) { + if(room_for_race_in_region(rc, u->race)) { + c++; + } + c2++; + } + } + + if (c == 0) { + if(c2 == 0) { + return NODIRECTION; + } else { + c = c2; + c2 = 0; /* c2 == 0 -> room_for_race nicht beachten */ + } + } + + /* Zuf�llig eine ausw�hlen */ + + rr = rng_int() % c; + + /* Durchz�hlen */ + + c = -1; + for (i = 0; i != MAXDIRECTIONS; i++) { + rc = rconnect(r, i); + if (rc && can_survive(u, rc)) { + if(c2 == 0) { + c++; + } else if(room_for_race_in_region(rc, u->race)) { + c++; + } + if (c == rr) return i; + } + } + + assert(1 == 0); /* Bis hierhin sollte er niemals kommen. */ + return NODIRECTION; +} + +static direction_t +treeman_neighbour(region * r) +{ + direction_t i; + int rr; + int c = 0; + + /* Nachsehen, wieviele Regionen in Frage kommen */ + + for (i = 0; i != MAXDIRECTIONS; i++) { + if (rconnect(r, i) + && rterrain(rconnect(r, i)) != T_OCEAN + && rterrain(rconnect(r, i)) != T_GLACIER + && rterrain(rconnect(r, i)) != T_DESERT) { + c++; + } + } + + if (c == 0) { + return NODIRECTION; + } + /* Zuf�llig eine ausw�hlen */ + + rr = rng_int() % c; + + /* Durchz�hlen */ + + c = -1; + for (i = 0; i != MAXDIRECTIONS; i++) { + if (rconnect(r, i) + && rterrain(rconnect(r, i)) != T_OCEAN + && rterrain(rconnect(r, i)) != T_GLACIER + && rterrain(rconnect(r, i)) != T_DESERT) { + c++; + if (c == rr) { + return i; + } + } + } + + assert(1 == 0); /* Bis hierhin sollte er niemals kommen. */ + return NODIRECTION; +} + +static order * +monster_move(region * r, unit * u) +{ + direction_t d = NODIRECTION; + + if (monster_is_waiting(u)) return NULL; + switch(old_race(u->race)) { + case RC_FIREDRAGON: + case RC_DRAGON: + case RC_WYRM: + d = richest_neighbour(r, u->faction, 1); + break; + case RC_TREEMAN: + d = treeman_neighbour(r); + break; + default: + d = random_neighbour(r,u); + break; + } + + /* falls kein geld gefunden wird, zufaellig verreisen, aber nicht in + * den ozean */ + + if (d == NODIRECTION) + return NULL; + + reduce_weight(u); + return create_order(K_MOVE, u->faction->locale, "%s", LOC(u->faction->locale, directions[d])); +} + +static int +dragon_affinity_value(region *r, unit *u) +{ + int m = all_money(r, u->faction); + + if(u->race == new_race[RC_FIREDRAGON]) { + return (int)(normalvariate(m,m/2)); + } else { + return (int)(normalvariate(m,m/4)); + } +} + +static attrib * +set_new_dragon_target(unit * u, region * r, int range) +{ + int max_affinity = 0; + region *max_region = NULL; + +#if 1 + region_list * rptr, * rlist = regions_in_range(r, range, allowed_dragon); + for (rptr=rlist;rptr;rptr=rptr->next) { + region * r2 = rptr->data; + int affinity = dragon_affinity_value(r2, u); + if (affinity > max_affinity) { + max_affinity = affinity; + max_region = r2; + } + } + + free_regionlist(rlist); +#else + int tx, ty; + for (tx = r->x - range; tx < r->x + range; tx++) { + for (ty = r->y - range; ty < r->y + range; ty++) { + region * r2; + int x = tx, y = ty; + pnormalize(&x, &y, r->planep); + r2 = findregion(x, y); + if (r2!=NULL) { + int affinity = dragon_affinity_value(r2, u); + if (affinity > max_affinity) { + if (koor_distance (r->x, r->y, x, y) <= range && path_exists(r, r2, range, allowed_dragon)) + { + max_affinity = affinity; + max_region = r2; + } + } + } + } + } +#endif + if (max_region && max_region != r) { + attrib * a = a_find(u->attribs, &at_targetregion); + if (!a) { + a = a_add(&u->attribs, make_targetregion(max_region)); + } else { + a->data.v = max_region; + } + return a; + } + return NULL; +} + +static order * +make_movement_order(unit * u, const region * target, int moves, boolean (*allowed)(const region *, const region *)) +{ + region * r = u->region; + region ** plan; + int bytes, position = 0; + char zOrder[128], * bufp = zOrder; + size_t size = sizeof(zOrder) - 1; + + if (monster_is_waiting(u)) return NULL; + + plan = path_find(r, target, DRAGON_RANGE*5, allowed); + if (plan==NULL) return NULL; + + bytes = (int)strlcpy(bufp, (const char *)LOC(u->faction->locale, keywords[K_MOVE]), size); + if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER(); + + while (position!=moves && plan[position+1]) { + region * prev = plan[position]; + region * next = plan[++position]; + direction_t dir = reldirection(prev, next); + assert(dir!=NODIRECTION && dir!=D_SPECIAL); + if (size>1) { + *bufp++ = ' '; + --size; + } + bytes = (int)strlcpy(bufp, (const char *)LOC(u->faction->locale, directions[dir]), size); + if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER(); + } + + *bufp = 0; + return parse_order(zOrder, u->faction->locale); +} + +#ifdef TODO_ALP +static order * +monster_seeks_target(region *r, unit *u) +{ + direction_t d; + unit *target = NULL; + int dist, dist2; + direction_t i; + region *nr; + + /* Das Monster sucht ein bestimmtes Opfer. Welches, steht + * in einer Referenz/attribut + * derzeit gibt es nur den alp + */ + + switch( old_race(u->race) ) { + case RC_ALP: + target = alp_target(u); + break; + default: + assert(!"Seeker-Monster gibt kein Ziel an"); + } + + /* TODO: pr�fen, ob target �berhaupt noch existiert... */ + if (!target) { + log_error(("Monster '%s' hat kein Ziel!\n", unitname(u))); + return NULL; /* this is a bug workaround! remove!! */ + } + + if(r == target->region ) { /* Wir haben ihn! */ + if (u->race == new_race[RC_ALP]) { + alp_findet_opfer(u, r); + } + else { + assert(!"Seeker-Monster hat keine Aktion fuer Ziel"); + } + return NULL; + } + + /* Simpler Ansatz: Nachbarregion mit gerinster Distanz suchen. + * Sinnvoll momentan nur bei Monstern, die sich nicht um das + * Terrain k�mmern. Nebelw�nde & Co machen derzeit auch nix... + */ + dist2 = distance(r, target->region); + d = NODIRECTION; + for( i = 0; i < MAXDIRECTIONS; i++ ) { + nr = rconnect(r, i); + assert(nr); + dist = distance(nr, target->region); + if( dist < dist2 ) { + dist2 = dist; + d = i; + } + } + assert(d != NODIRECTION ); + + return create_order(K_MOVE, u->faction->locale, "%s", LOC(u->faction->locale, directions[d])); +} +#endif + +static void +monster_attacks(unit * u) +{ + region * r = u->region; + unit * u2; + + for (u2=r->units;u2;u2=u2->next) { + if (u2->faction!=u->faction && chance(0.75)) { + order * ord = monster_attack(u, u2); + if (ord) addlist(&u->orders, ord); + } + } +} + +static const char * +random_growl(void) +{ + switch(rng_int()%5) { + case 0: + return "Groammm"; + case 1: + return "Roaaarrrr"; + case 2: + return "Chhhhhhhhhh"; + case 3: + return "Tschrrrkk"; + case 4: + return "Schhhh"; + } + return ""; +} + +extern struct attrib_type at_direction; + +static order * +monster_learn(unit *u) +{ + int c = 0; + int n; + skill * sv; + const struct locale * lang = u->faction->locale; + + /* Monster lernt ein zuf�lliges Talent aus allen, in denen es schon + * Lerntage hat. */ + + for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { + if (sv->level>0) ++c; + } + + if(c == 0) return NULL; + + n = rng_int()%c + 1; + c = 0; + + for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { + if (sv->level>0) { + if (++c == n) { + return create_order(K_STUDY, lang, "'%s'", skillname(sv->id, lang)); + } + } + } + return NULL; +} + +static boolean +check_overpopulated(unit *u) +{ + unit *u2; + int c = 0; + + for(u2 = u->region->units; u2; u2 = u2->next) { + if(u2->race == u->race && u != u2) c += u2->number; + } + + if(c > u->race->splitsize * 2) return true; + + return false; +} + +static void +recruit_dracoids(unit * dragon, int size) +{ + faction * f = dragon->faction; + region * r = dragon->region; + const struct item * weapon = NULL; + order * new_order = NULL; + unit *un = createunit(r, f, size, new_race[RC_DRACOID]); + + fset(un, UFL_ISNEW|UFL_MOVED); + + name_unit(un); + change_money(dragon, -un->number * 50); + equip_unit(un, get_equipment("recruited_dracoid")); + + setstatus(un, ST_FIGHT); + for (weapon=un->items;weapon;weapon=weapon->next) { + const weapon_type * wtype = weapon->type->rtype->wtype; + if (wtype && (wtype->flags & WTF_MISSILE)) { + setstatus(un, ST_BEHIND); + } + new_order = create_order(K_STUDY, f->locale, "'%s'", + skillname(weapon->type->rtype->wtype->skill, f->locale)); + } + + if (new_order!=NULL) { + addlist(&un->orders, new_order); + } +} + +static order * +plan_dragon(unit * u) +{ + attrib * ta = a_find(u->attribs, &at_targetregion); + region * r = u->region; + region * tr = NULL; + boolean move = false; + order * long_order = NULL; + + reduce_weight(u); + + if (ta==NULL) { + move |= (r->land==0 || r->land->peasants==0); /* when no peasants, move */ + move |= (r->land==0 || r->land->money==0); /* when no money, move */ + } + move |= chance(0.04); /* 4% chance to change your mind */ + + if (u->race==new_race[RC_WYRM] && !move) { + unit * u2; + for (u2=r->units;u2;u2=u2->next) { + /* wyrme sind einzelg�nger */ + if (u2==u) { + /* we do not make room for newcomers, so we don't need to look at them */ + break; + } + if (u2!=u && u2->race==u->race && chance(0.5)) { + move = true; + break; + } + } + } + + if (move) { + /* dragon gets bored and looks for a different place to go */ + ta = set_new_dragon_target(u, u->region, DRAGON_RANGE); + } + else ta = a_find(u->attribs, &at_targetregion); + if (ta!=NULL) { + tr = (region *) ta->data.v; + if (tr==NULL || !path_exists(u->region, tr, DRAGON_RANGE, allowed_dragon)) { + ta = set_new_dragon_target(u, u->region, DRAGON_RANGE); + if (ta) tr = findregion(ta->data.sa[0], ta->data.sa[1]); + } + } + if (tr!=NULL) { + assert(long_order==NULL); + switch(old_race(u->race)) { + case RC_FIREDRAGON: + long_order = make_movement_order(u, tr, 4, allowed_dragon); + break; + case RC_DRAGON: + long_order = make_movement_order(u, tr, 3, allowed_dragon); + break; + case RC_WYRM: + long_order = make_movement_order(u, tr, 1, allowed_dragon); + break; + } + if (rng_int()%100 < 15) { + const struct locale * lang = u->faction->locale; + /* do a growl */ + if (rname(tr, lang)) { + addlist(&u->orders, create_order(K_MAIL, lang, "%s '%s... %s %s %s'", + LOC(lang, parameters[P_REGION]), random_growl(), + u->number==1?"Ich rieche":"Wir riechen", + "etwas in", rname(tr, u->faction->locale))); + } + } + } else { + /* we have no target. do we like it here, then? */ + long_order = get_money_for_dragon(u->region, u, income(u)); + if (long_order==NULL) { + /* money is gone, need a new target */ + set_new_dragon_target(u, u->region, DRAGON_RANGE); + } + else if (u->race != new_race[RC_FIREDRAGON]) { + /* neue dracoiden! */ + if (r->land && !fval(r->terrain, FORBIDDEN_REGION)) { + int ra = 20 + rng_int() % 100; + if (get_money(u) > ra * 50 + 100 && rng_int() % 100 < 50) { + recruit_dracoids(u, ra); + } + } + } + } + if (long_order==NULL) { + skill_t sk = SK_PERCEPTION; + /* study perception (or a random useful skill) */ + while (!skill_enabled[sk] || u->race->bonus[sk]<-5) { + sk = (skill_t)(rng_int() % MAXSKILLS); + } + long_order = create_order(K_STUDY, u->faction->locale, "'%s'", + skillname(sk, u->faction->locale)); + } + return long_order; +} + +void +plan_monsters(faction * f) +{ + region *r; + + assert(f); + f->lastorders = turn; + + for (r = regions; r; r = r->next) { + unit *u; + double attack_chance = MONSTERATTACK; + boolean attacking = false; + + for (u = r->units; u; u = u->next) { + attrib * ta; + order * long_order = NULL; + + /* Ab hier nur noch Befehle f�r NPC-Einheiten. */ + if (!is_monsters(u->faction)) continue; + + if (attack_chance>0.0) { + if (chance(attack_chance)) attacking = true; + attack_chance = 0.0; + } + + if (u->status>ST_BEHIND) { + setstatus(u, ST_FIGHT); + /* all monsters fight */ + } + if (skill_enabled[SK_PERCEPTION]) { + /* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */ + /* TODO: this only works for playerrace */ + produceexp(u, SK_PERCEPTION, u->number); + } + + /* Befehle m�ssen jede Runde neu gegeben werden: */ + free_orders(&u->orders); + + if (attacking) { + monster_attacks(u); + } + /* units with a plan to kill get ATTACK orders: */ + ta = a_find(u->attribs, &at_hate); + if (ta && !monster_is_waiting(u)) { + unit * tu = (unit *)ta->data.v; + if (tu && tu->region==r) { + addlist(&u->orders, create_order(K_ATTACK, u->faction->locale, "%i", tu->no)); + } else if (tu) { + tu = findunitg(ta->data.i, NULL); + if (tu!=NULL) { + long_order = make_movement_order(u, tu->region, 2, allowed_walk); + } + } + else a_remove(&u->attribs, ta); + } + + /* All monsters guard the region: */ + if (!monster_is_waiting(u) && r->land) { + addlist(&u->orders, create_order(K_GUARD, u->faction->locale, NULL)); + } + + /* Einheiten mit Bewegungsplan kriegen ein NACH: */ + if (long_order==NULL) { + attrib * ta = a_find(u->attribs, &at_targetregion); + if (ta) { + if (u->region == (region*)ta->data.v) { + a_remove(&u->attribs, ta); + } + } else if (u->race->flags & RCF_MOVERANDOM) { + if (rng_int()%100<MOVECHANCE || check_overpopulated(u)) { + long_order = monster_move(r, u); + } + } + } + + if (long_order==NULL) { + /* Einheiten, die Waffenlosen Kampf lernen k�nnten, lernen es um + * zu bewachen: */ + if (u->race->bonus[SK_WEAPONLESS] != -99) { + if (eff_skill(u, SK_WEAPONLESS, u->region) < 1) { + long_order = create_order(K_STUDY, f->locale, "'%s'", skillname(SK_WEAPONLESS, f->locale)); + } + } + } + + if (long_order==NULL) { + /* Ab hier noch nicht generalisierte Spezialbehandlungen. */ + + if (!u->orders) { + handle_event(u->attribs, "ai_move", u); + } + + switch (old_race(u->race)) { + case RC_SEASERPENT: + long_order = create_order(K_PIRACY, f->locale, NULL); + break; +#ifdef TODO_ALP + case RC_ALP: + long_order = monster_seeks_target(r, u); + break; +#endif + case RC_FIREDRAGON: + case RC_DRAGON: + case RC_WYRM: + long_order = plan_dragon(u); + break; + default: + if (u->race->flags & RCF_LEARN) { + long_order = monster_learn(u); + } + break; + } + } + if (long_order) { + addlist(&u->orders, long_order); + } + } + } + pathfinder_cleanup(); +} + +static double +chaosfactor(region * r) +{ + attrib * a = a_find(r->attribs, &at_chaoscount); + if (!a) return 0; + return ((double) a->data.i / 1000.0); +} + +static int +nrand(int start, int sub) +{ + int res = 0; + + do { + if (rng_int() % 100 < start) + res++; + start -= sub; + } while (start > 0); + + return res; +} + +/** Drachen und Seeschlangen k�nnen entstehen */ +void +spawn_dragons(void) +{ + region * r; + faction * monsters = get_monsters(); + + for (r = regions; r; r = r->next) { + unit * u; + + if (fval(r->terrain, SEA_REGION) && rng_int()%10000 < 1) { + u = createunit(r, monsters, 1, new_race[RC_SEASERPENT]); + fset(u, UFL_ISNEW|UFL_MOVED); + equip_unit(u, get_equipment("monster_seaserpent")); + } + + if ((r->terrain == newterrain(T_GLACIER) || r->terrain == newterrain(T_SWAMP) || r->terrain == newterrain(T_DESERT)) && rng_int() % 10000 < (5 + 100 * chaosfactor(r))) + { + if (chance(0.80)) { + u = createunit(r, monsters, nrand(60, 20) + 1, new_race[RC_FIREDRAGON]); + } else { + u = createunit(r, monsters, nrand(30, 20) + 1, new_race[RC_DRAGON]); + } + fset(u, UFL_ISNEW|UFL_MOVED); + equip_unit(u, get_equipment("monster_dragon")); + + if (verbosity>=2) { + log_printf("%d %s in %s.\n", u->number, + LOC(default_locale, rc_name(u->race, u->number!=1)), regionname(r, NULL)); + } + + name_unit(u); + + /* add message to the region */ + ADDMSG(&r->msgs, + msg_message("sighting", "region race number", r, u->race, u->number)); + } + } +} + +/** Untote k�nnen entstehen */ +void +spawn_undead(void) +{ + region * r; + faction * monsters = get_monsters(); + + for (r = regions; r; r = r->next) { + int unburied = deathcount(r); + static const curse_type * ctype = NULL; + + if (!ctype) ctype = ct_find("holyground"); + if (ctype && curse_active(get_curse(r->attribs, ctype))) continue; + + /* Chance 0.1% * chaosfactor */ + if (r->land && unburied > r->land->peasants / 20 && rng_int() % 10000 < (100 + 100 * chaosfactor(r))) { + unit * u; + /* es ist sinnfrei, wenn irgendwo im Wald 3er-Einheiten Untote entstehen. + * Lieber sammeln lassen, bis sie mindestens 5% der Bev�lkerung sind, und + * dann erst auferstehen. */ + int undead = unburied / (rng_int() % 2 + 1); + const race * rc = NULL; + int i; + if (r->age<100) undead = undead * r->age / 100; /* newbie-regionen kriegen weniger ab */ + + if (!undead || r->age < 20) continue; + + switch(rng_int()%3) { + case 0: + rc = new_race[RC_SKELETON]; break; + case 1: + rc = new_race[RC_ZOMBIE]; break; + default: + rc = new_race[RC_GHOUL]; break; + } + + u = createunit(r, monsters, undead, rc); + fset(u, UFL_ISNEW|UFL_MOVED); + if ((rc == new_race[RC_SKELETON] || rc == new_race[RC_ZOMBIE]) && rng_int()%10 < 4) { + equip_unit(u, get_equipment("rising_undead")); + } + + for (i=0;i < MAXSKILLS;i++) { + if (rc->bonus[i] >= 1) { + set_level(u, (skill_t)i, 1); + } + } + u->hp = unit_max_hp(u) * u->number; + + deathcounts(r, -undead); + name_unit(u); + + if (verbosity>=2) { + log_printf("%d %s in %s.\n", u->number, + LOC(default_locale, rc_name(u->race, u->number!=1)), regionname(r, NULL)); + } + + { + message * msg = msg_message("undeadrise", "region", r); + add_message(&r->msgs, msg); + for (u=r->units;u;u=u->next) freset(u->faction, FFL_SELECT); + for (u=r->units;u;u=u->next) { + if (fval(u->faction, FFL_SELECT)) continue; + fset(u->faction, FFL_SELECT); + add_message(&u->faction->msgs, msg); + } + msg_release(msg); + } + } else { + int i = deathcount(r); + if (i) { + /* Gr�ber verwittern, 3% der Untoten finden die ewige Ruhe */ + deathcounts(r, (int)(-i*0.03)); + } + } + } +} diff --git a/src/races/Jamfile b/src/races/Jamfile index 6272f8708..c8a07e9ed 100644 --- a/src/races/Jamfile +++ b/src/races/Jamfile @@ -1,20 +1,20 @@ -SubDir TOP src races ; - -TargetDirectory ; -SubDirHdrs $(SUBDIR)/../gamecode ; -SubDirHdrs $(SUBDIR)/../kernel ; -SubDirHdrs $(SUBDIR)/../util ; -SubDirHdrs $(SUBDIR)/.. ; -SubDirHdrs $(SUBDIR)/../.. ; -SubDirHdrs $(XMLHDRS) ; - -SOURCES = - dragons.c - illusion.c - races.c - zombies.c - ; - -if $(BUILDTYPE) = REGULAR { -Library races : $(SOURCES) ; -} +SubDir TOP src races ; + +TargetDirectory ; +SubDirHdrs $(SUBDIR)/../gamecode ; +SubDirHdrs $(SUBDIR)/../kernel ; +SubDirHdrs $(SUBDIR)/../util ; +SubDirHdrs $(SUBDIR)/.. ; +SubDirHdrs $(SUBDIR)/../.. ; +SubDirHdrs $(XMLHDRS) ; + +SOURCES = + dragons.c + illusion.c + races.c + zombies.c + ; + +if $(BUILDTYPE) = REGULAR { +Library races : $(SOURCES) ; +} diff --git a/src/races/dragons.c b/src/races/dragons.c index f02e4617d..f2bed885b 100644 --- a/src/races/dragons.c +++ b/src/races/dragons.c @@ -1,52 +1,52 @@ -/* vi: set ts=2: - * - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#include <platform.h> -#include <kernel/config.h> - -/* kernel includes */ -#include <kernel/region.h> -#include <kernel/unit.h> - -/* util includes */ -#include <util/rng.h> - -#define age_chance(a,b,p) (MAX(0,a-b)*p) - -#define DRAGONAGE 27 -#define WYRMAGE 68 - -void -age_firedragon(unit *u) -{ - if (u->number>0 && rng_int()%100 < age_chance(u->age, DRAGONAGE, 1)) { - double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); - u->race = new_race[RC_DRAGON]; - u->irace = NULL; - scale_number(u,1); - u->hp = (int) (unit_max_hp(u) * u->number * q); - } -} - -void -age_dragon(unit *u) -{ - if (u->number>0 && rng_int()%100 < age_chance(u->age, WYRMAGE, 1)) { - double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); - u->race = new_race[RC_WYRM]; - u->irace = NULL; - u->hp = (int) (unit_max_hp(u) * u->number * q); - } -} - +/* vi: set ts=2: + * + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#include <platform.h> +#include <kernel/config.h> + +/* kernel includes */ +#include <kernel/region.h> +#include <kernel/unit.h> + +/* util includes */ +#include <util/rng.h> + +#define age_chance(a,b,p) (MAX(0,a-b)*p) + +#define DRAGONAGE 27 +#define WYRMAGE 68 + +void +age_firedragon(unit *u) +{ + if (u->number>0 && rng_int()%100 < age_chance(u->age, DRAGONAGE, 1)) { + double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); + u->race = new_race[RC_DRAGON]; + u->irace = NULL; + scale_number(u,1); + u->hp = (int) (unit_max_hp(u) * u->number * q); + } +} + +void +age_dragon(unit *u) +{ + if (u->number>0 && rng_int()%100 < age_chance(u->age, WYRMAGE, 1)) { + double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); + u->race = new_race[RC_WYRM]; + u->irace = NULL; + u->hp = (int) (unit_max_hp(u) * u->number * q); + } +} + diff --git a/src/races/illusion.c b/src/races/illusion.c index b2b20fb63..ddb8eb6fc 100644 --- a/src/races/illusion.c +++ b/src/races/illusion.c @@ -1,41 +1,41 @@ -/* vi: set ts=2: - * - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#include <platform.h> -#include <kernel/config.h> - -/* kernel includes */ -#include <kernel/unit.h> -#include <kernel/faction.h> -#include <kernel/message.h> - -/* libc includes */ -#include <stdlib.h> -#include <assert.h> - -#define ILLUSIONMAX 6 - -void -age_illusion(unit *u) -{ - if (u->faction->race!=new_race[RC_ILLUSION]) { - if (u->age == ILLUSIONMAX) { - ADDMSG(&u->faction->msgs, msg_message("warnillusiondissolve", - "unit", u)); - } else if (u->age > ILLUSIONMAX) { - set_number(u, 0); - ADDMSG(&u->faction->msgs, msg_message("illusiondissolve", "unit", u)); - } - } -} +/* vi: set ts=2: + * + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#include <platform.h> +#include <kernel/config.h> + +/* kernel includes */ +#include <kernel/unit.h> +#include <kernel/faction.h> +#include <kernel/message.h> + +/* libc includes */ +#include <stdlib.h> +#include <assert.h> + +#define ILLUSIONMAX 6 + +void +age_illusion(unit *u) +{ + if (u->faction->race!=new_race[RC_ILLUSION]) { + if (u->age == ILLUSIONMAX) { + ADDMSG(&u->faction->msgs, msg_message("warnillusiondissolve", + "unit", u)); + } else if (u->age > ILLUSIONMAX) { + set_number(u, 0); + ADDMSG(&u->faction->msgs, msg_message("illusiondissolve", "unit", u)); + } + } +} diff --git a/src/races/races.c b/src/races/races.c index abf9f5a4b..de615f1df 100644 --- a/src/races/races.c +++ b/src/races/races.c @@ -1,143 +1,143 @@ -/* vi: set ts=2: - * +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de> - * | | Enno Rehling <enno@eressea.de> - * | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de> - * | (c) 1998 - 2007 | - * | | This program may not be used, modified or distributed - * +-------------------+ without prior permission by the authors of Eressea. - * - */ - -#include <platform.h> -#include <kernel/config.h> -#include "races.h" - -#include <kernel/building.h> -#include <kernel/equipment.h> -#include <kernel/faction.h> -#include <kernel/item.h> -#include <kernel/pathfinder.h> -#include <kernel/race.h> -#include <kernel/region.h> -#include <kernel/ship.h> -#include <kernel/terrain.h> -#include <kernel/unit.h> - -#include <util/attrib.h> -#include <util/functions.h> -#include <util/rng.h> - -void age_firedragon(struct unit *u); -void age_dragon(struct unit *u); -void age_illusion(struct unit *u); -void age_undead(struct unit *u); -void age_skeleton(struct unit *u); -void age_zombie(struct unit *u); -void age_ghoul(struct unit *u); - -static void -oldfamiliars(unit * u) -{ - char fname[64]; - /* these familiars have no special skills. - */ - snprintf(fname, sizeof(fname), "%s_familiar", u->race->_name[0]); - create_mage(u, M_GRAY); - equip_unit(u, get_equipment(fname)); -} - -static void -set_show_item(faction *f, item_t i) -{ - attrib *a = a_add(&f->attribs, a_new(&at_showitem)); - a->data.v = (void*)olditemtype[i]; -} - -static void -equip_newunits(const struct equipment * eq, struct unit *u) -{ - struct region *r = u->region; - - switch (old_race(u->race)) { - case RC_ELF: - set_show_item(u->faction, I_FEENSTIEFEL); - break; - case RC_GOBLIN: - set_show_item(u->faction, I_RING_OF_INVISIBILITY); - set_number(u, 10); - break; - case RC_HUMAN: - if (u->building==NULL) { - const building_type * btype = bt_find("castle"); - if (btype!=NULL) { - building *b = new_building(btype, r, u->faction->locale); - b->size = 10; - u->building = b; - fset(u, UFL_OWNER); - } - } - break; - case RC_CAT: - set_show_item(u->faction, I_RING_OF_INVISIBILITY); - break; - case RC_AQUARIAN: - { - ship *sh = new_ship(st_find("boat"), u->faction->locale, r); - sh->size = sh->type->construction->maxsize; - u->ship = sh; - fset(u, UFL_OWNER); - } - break; - case RC_CENTAUR: - rsethorses(r, 250+rng_int()%51+rng_int()%51); - break; - } -} - -static item * -default_spoil(const struct race * rc, int size) -{ - item * itm = NULL; - - if (rng_int()%100 < RACESPOILCHANCE) { - char spoilname[32]; - const item_type * itype; - - sprintf(spoilname, "%sspoil", rc->_name[0]); - itype = it_find(spoilname); - if (itype!=NULL) { - i_add(&itm, i_new(itype, size)); - } - } - return itm; -} - -/* Die Funktionen werden �ber den hier registrierten Namen in races.xml - * in die jeweilige Rassendefiniton eingebunden */ -void -register_races(void) -{ - /* function initfamiliar */ - register_function((pf_generic)oldfamiliars, "oldfamiliars"); - - register_function((pf_generic)allowed_dragon, "movedragon"); - - register_function((pf_generic)allowed_swim, "moveswimming"); - register_function((pf_generic)allowed_fly, "moveflying"); - register_function((pf_generic)allowed_walk, "movewalking"); - - /* function age for race->age() */ - register_function((pf_generic)age_undead, "ageundead"); - register_function((pf_generic)age_illusion, "ageillusion"); - register_function((pf_generic)age_skeleton, "ageskeleton"); - register_function((pf_generic)age_zombie, "agezombie"); - register_function((pf_generic)age_ghoul, "ageghoul"); - register_function((pf_generic)age_dragon, "agedragon"); - register_function((pf_generic)age_firedragon, "agefiredragon"); - - /* function itemdrop - * to generate battle spoils - * race->itemdrop() */ - register_function((pf_generic)default_spoil, "defaultdrops"); - register_function((pf_generic)equip_newunits, "equip_newunits"); -} +/* vi: set ts=2: + * +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de> + * | | Enno Rehling <enno@eressea.de> + * | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de> + * | (c) 1998 - 2007 | + * | | This program may not be used, modified or distributed + * +-------------------+ without prior permission by the authors of Eressea. + * + */ + +#include <platform.h> +#include <kernel/config.h> +#include "races.h" + +#include <kernel/building.h> +#include <kernel/equipment.h> +#include <kernel/faction.h> +#include <kernel/item.h> +#include <kernel/pathfinder.h> +#include <kernel/race.h> +#include <kernel/region.h> +#include <kernel/ship.h> +#include <kernel/terrain.h> +#include <kernel/unit.h> + +#include <util/attrib.h> +#include <util/functions.h> +#include <util/rng.h> + +void age_firedragon(struct unit *u); +void age_dragon(struct unit *u); +void age_illusion(struct unit *u); +void age_undead(struct unit *u); +void age_skeleton(struct unit *u); +void age_zombie(struct unit *u); +void age_ghoul(struct unit *u); + +static void +oldfamiliars(unit * u) +{ + char fname[64]; + /* these familiars have no special skills. + */ + snprintf(fname, sizeof(fname), "%s_familiar", u->race->_name[0]); + create_mage(u, M_GRAY); + equip_unit(u, get_equipment(fname)); +} + +static void +set_show_item(faction *f, item_t i) +{ + attrib *a = a_add(&f->attribs, a_new(&at_showitem)); + a->data.v = (void*)olditemtype[i]; +} + +static void +equip_newunits(const struct equipment * eq, struct unit *u) +{ + struct region *r = u->region; + + switch (old_race(u->race)) { + case RC_ELF: + set_show_item(u->faction, I_FEENSTIEFEL); + break; + case RC_GOBLIN: + set_show_item(u->faction, I_RING_OF_INVISIBILITY); + set_number(u, 10); + break; + case RC_HUMAN: + if (u->building==NULL) { + const building_type * btype = bt_find("castle"); + if (btype!=NULL) { + building *b = new_building(btype, r, u->faction->locale); + b->size = 10; + u->building = b; + fset(u, UFL_OWNER); + } + } + break; + case RC_CAT: + set_show_item(u->faction, I_RING_OF_INVISIBILITY); + break; + case RC_AQUARIAN: + { + ship *sh = new_ship(st_find("boat"), u->faction->locale, r); + sh->size = sh->type->construction->maxsize; + u->ship = sh; + fset(u, UFL_OWNER); + } + break; + case RC_CENTAUR: + rsethorses(r, 250+rng_int()%51+rng_int()%51); + break; + } +} + +static item * +default_spoil(const struct race * rc, int size) +{ + item * itm = NULL; + + if (rng_int()%100 < RACESPOILCHANCE) { + char spoilname[32]; + const item_type * itype; + + sprintf(spoilname, "%sspoil", rc->_name[0]); + itype = it_find(spoilname); + if (itype!=NULL) { + i_add(&itm, i_new(itype, size)); + } + } + return itm; +} + +/* Die Funktionen werden �ber den hier registrierten Namen in races.xml + * in die jeweilige Rassendefiniton eingebunden */ +void +register_races(void) +{ + /* function initfamiliar */ + register_function((pf_generic)oldfamiliars, "oldfamiliars"); + + register_function((pf_generic)allowed_dragon, "movedragon"); + + register_function((pf_generic)allowed_swim, "moveswimming"); + register_function((pf_generic)allowed_fly, "moveflying"); + register_function((pf_generic)allowed_walk, "movewalking"); + + /* function age for race->age() */ + register_function((pf_generic)age_undead, "ageundead"); + register_function((pf_generic)age_illusion, "ageillusion"); + register_function((pf_generic)age_skeleton, "ageskeleton"); + register_function((pf_generic)age_zombie, "agezombie"); + register_function((pf_generic)age_ghoul, "ageghoul"); + register_function((pf_generic)age_dragon, "agedragon"); + register_function((pf_generic)age_firedragon, "agefiredragon"); + + /* function itemdrop + * to generate battle spoils + * race->itemdrop() */ + register_function((pf_generic)default_spoil, "defaultdrops"); + register_function((pf_generic)equip_newunits, "equip_newunits"); +} diff --git a/src/races/races.h b/src/races/races.h index 90c9f78f6..25752da56 100644 --- a/src/races/races.h +++ b/src/races/races.h @@ -1,25 +1,25 @@ -/* vi: set ts=2: - * +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de> - * | | Enno Rehling <enno@eressea.de> - * | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de> - * | (c) 1998 - 2007 | - * | | This program may not be used, modified or distributed - * +-------------------+ without prior permission by the authors of Eressea. - * - */ - -#ifndef H_RACES -#define H_RACES - -#ifdef __cplusplus -extern "C" { -#endif - - extern void register_races(void); - -#ifdef __cplusplus -} -#endif - -#endif - +/* vi: set ts=2: + * +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de> + * | | Enno Rehling <enno@eressea.de> + * | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de> + * | (c) 1998 - 2007 | + * | | This program may not be used, modified or distributed + * +-------------------+ without prior permission by the authors of Eressea. + * + */ + +#ifndef H_RACES +#define H_RACES + +#ifdef __cplusplus +extern "C" { +#endif + + extern void register_races(void); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/src/races/zombies.c b/src/races/zombies.c index c908963a0..7ce2459e6 100644 --- a/src/races/zombies.c +++ b/src/races/zombies.c @@ -1,97 +1,97 @@ -/* vi: set ts=2: - * - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#include <platform.h> -#include <kernel/config.h> - -/* kernel includes */ -#include <kernel/unit.h> -#include <kernel/faction.h> -#include <kernel/region.h> - -/* util iclude */ -#include <util/rng.h> - -/* libc includes */ -#include <stdlib.h> - -#define UNDEAD_MIN 90 /* mind. zahl vor weg gehen */ -#define UNDEAD_BREAKUP 25 /* chance dafuer */ -#define UNDEAD_BREAKUP_FRACTION (25+rng_int()%70) /* anteil der weg geht */ - -#define age_chance(a,b,p) (MAX(0,a-b)*p) - -void -age_undead(unit *u) -{ - region *r = u->region; - int n = 0; - - /* untote, die einer partei angehoeren, koennen sich - * absplitten, anstatt sich zu vermehren. monster - * untote vermehren sich nur noch */ - - if (u->number > UNDEAD_MIN && !is_monsters(u->faction) && rng_int() % 100 < UNDEAD_BREAKUP) { - int m; - unit *u2; - - n = 0; - for (m = u->number; m; m--) { - if (rng_int() % 100 < UNDEAD_BREAKUP_FRACTION) ++n; - } - u2 = create_unit(r, get_monsters(), 0, new_race[RC_UNDEAD], 0, NULL, u); - make_undead_unit(u2); - transfermen(u, u2, u->number - n); - } -} - -void -age_skeleton(unit *u) -{ - if (is_monsters(u->faction) && rng_int()%100 < age_chance(u->age, 27, 1)) { - int n = MAX(1,u->number/2); - double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); - u->race = new_race[RC_SKELETON_LORD]; - u->irace = NULL; - scale_number(u,n); - u->hp = (int) (unit_max_hp(u) * u->number * q); - } -} - -void -age_zombie(unit *u) -{ - if (is_monsters(u->faction) && rng_int()%100 < age_chance(u->age, 27, 1)) { - int n = MAX(1,u->number/2); - double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); - u->race = new_race[RC_ZOMBIE_LORD]; - u->irace = NULL; - scale_number(u,n); - u->hp = (int) (unit_max_hp(u) * u->number * q); - } -} - -void -age_ghoul(unit *u) -{ - if (is_monsters(u->faction) && rng_int()%100 < age_chance(u->age, 27, 1)) { - int n = MAX(1,u->number/2); - double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); - u->race = new_race[RC_GHOUL_LORD]; - u->irace = NULL; - scale_number(u,n); - u->hp = (int) (unit_max_hp(u) * u->number * q); - } -} - +/* vi: set ts=2: + * + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#include <platform.h> +#include <kernel/config.h> + +/* kernel includes */ +#include <kernel/unit.h> +#include <kernel/faction.h> +#include <kernel/region.h> + +/* util iclude */ +#include <util/rng.h> + +/* libc includes */ +#include <stdlib.h> + +#define UNDEAD_MIN 90 /* mind. zahl vor weg gehen */ +#define UNDEAD_BREAKUP 25 /* chance dafuer */ +#define UNDEAD_BREAKUP_FRACTION (25+rng_int()%70) /* anteil der weg geht */ + +#define age_chance(a,b,p) (MAX(0,a-b)*p) + +void +age_undead(unit *u) +{ + region *r = u->region; + int n = 0; + + /* untote, die einer partei angehoeren, koennen sich + * absplitten, anstatt sich zu vermehren. monster + * untote vermehren sich nur noch */ + + if (u->number > UNDEAD_MIN && !is_monsters(u->faction) && rng_int() % 100 < UNDEAD_BREAKUP) { + int m; + unit *u2; + + n = 0; + for (m = u->number; m; m--) { + if (rng_int() % 100 < UNDEAD_BREAKUP_FRACTION) ++n; + } + u2 = create_unit(r, get_monsters(), 0, new_race[RC_UNDEAD], 0, NULL, u); + make_undead_unit(u2); + transfermen(u, u2, u->number - n); + } +} + +void +age_skeleton(unit *u) +{ + if (is_monsters(u->faction) && rng_int()%100 < age_chance(u->age, 27, 1)) { + int n = MAX(1,u->number/2); + double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); + u->race = new_race[RC_SKELETON_LORD]; + u->irace = NULL; + scale_number(u,n); + u->hp = (int) (unit_max_hp(u) * u->number * q); + } +} + +void +age_zombie(unit *u) +{ + if (is_monsters(u->faction) && rng_int()%100 < age_chance(u->age, 27, 1)) { + int n = MAX(1,u->number/2); + double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); + u->race = new_race[RC_ZOMBIE_LORD]; + u->irace = NULL; + scale_number(u,n); + u->hp = (int) (unit_max_hp(u) * u->number * q); + } +} + +void +age_ghoul(unit *u) +{ + if (is_monsters(u->faction) && rng_int()%100 < age_chance(u->age, 27, 1)) { + int n = MAX(1,u->number/2); + double q = (double) u->hp / (double) (unit_max_hp(u) * u->number); + u->race = new_race[RC_GHOUL_LORD]; + u->irace = NULL; + scale_number(u,n); + u->hp = (int) (unit_max_hp(u) * u->number * q); + } +} + diff --git a/src/server.c b/src/server.c index 04e8faba2..f3d4c1d29 100644 --- a/src/server.c +++ b/src/server.c @@ -1,21 +1,21 @@ -#include <platform.h> -#include "stdafx.h" - -#include "curses.c" -#include "spells/alp.c" -#include "spells/buildingcurse.c" -#include "spells/combatspells.c" -#include "spells/regioncurse.c" -#include "spells/shipcurse.c" -#include "spells/spells.c" -#include "spells/unitcurse.c" - -#include "races/dragons.c" -#include "races/illusion.c" -#include "races/races.c" -#include "races/zombies.c" - -#include "bindings.c" -#include "monsters.c" -#include "main.c" -#include "tests.c" +#include <platform.h> +#include "stdafx.h" + +#include "curses.c" +#include "spells/alp.c" +#include "spells/buildingcurse.c" +#include "spells/combatspells.c" +#include "spells/regioncurse.c" +#include "spells/shipcurse.c" +#include "spells/spells.c" +#include "spells/unitcurse.c" + +#include "races/dragons.c" +#include "races/illusion.c" +#include "races/races.c" +#include "races/zombies.c" + +#include "bindings.c" +#include "monsters.c" +#include "main.c" +#include "tests.c" diff --git a/src/spells/Jamfile b/src/spells/Jamfile index a0aaaf7d4..8ef4a06ec 100644 --- a/src/spells/Jamfile +++ b/src/spells/Jamfile @@ -1,23 +1,23 @@ -SubDir TOP src spells ; - -TargetDirectory ; -SubDirHdrs $(SUBDIR)/../gamecode ; -SubDirHdrs $(SUBDIR)/../kernel ; -SubDirHdrs $(SUBDIR)/../util ; -SubDirHdrs $(SUBDIR)/.. ; -SubDirHdrs $(SUBDIR)/../.. ; -SubDirHdrs $(XMLHDRS) ; - -SOURCES = - alp.c - buildingcurse.c - combatspells.c - regioncurse.c - shipcurse.c - spells.c - unitcurse.c - ; - -if $(BUILDTYPE) = REGULAR { -Library spells : $(SOURCES) ; -} +SubDir TOP src spells ; + +TargetDirectory ; +SubDirHdrs $(SUBDIR)/../gamecode ; +SubDirHdrs $(SUBDIR)/../kernel ; +SubDirHdrs $(SUBDIR)/../util ; +SubDirHdrs $(SUBDIR)/.. ; +SubDirHdrs $(SUBDIR)/../.. ; +SubDirHdrs $(XMLHDRS) ; + +SOURCES = + alp.c + buildingcurse.c + combatspells.c + regioncurse.c + shipcurse.c + spells.c + unitcurse.c + ; + +if $(BUILDTYPE) = REGULAR { +Library spells : $(SOURCES) ; +} diff --git a/src/spells/alp.c b/src/spells/alp.c index a95a292e1..8887a72b9 100644 --- a/src/spells/alp.c +++ b/src/spells/alp.c @@ -1,205 +1,205 @@ -/* vi: set ts=2: - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#include <platform.h> -#include <kernel/config.h> -#include "alp.h" - -#include <kernel/config.h> -#include <kernel/faction.h> -#include <kernel/magic.h> -#include <kernel/message.h> -#include <kernel/race.h> -#include <kernel/region.h> -#include <kernel/skill.h> -#include <kernel/unit.h> - -/* util includes */ -#include <util/attrib.h> -#include <util/event.h> -#include <util/resolve.h> -#include <util/umlaut.h> -#include <util/storage.h> - -#include <triggers/createcurse.h> -#include <triggers/killunit.h> -#include <triggers/removecurse.h> -#include <triggers/unitmessage.h> - -/* libc includes */ -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -extern const char *directions[]; - -typedef struct alp_data { - unit * mage; - unit * target; -} alp_data; - -static void -alp_init(attrib * a) -{ - a->data.v = calloc(sizeof(alp_data), 1); -} - -static void -alp_done(attrib * a) -{ - free(a->data.v); -} - -static int -alp_verify(attrib * a) -{ - alp_data * ad = (alp_data*)a->data.v; - if (ad->mage && ad->target) return 1; - return 0; /* remove the attribute */ -} - -static void -alp_write(const attrib * a, const void * owner, struct storage * store) -{ - alp_data * ad = (alp_data*)a->data.v; - write_unit_reference(ad->mage, store); - write_unit_reference(ad->target, store); -} - -static int -alp_read(attrib * a, void * owner, struct storage * store) -{ - alp_data * ad = (alp_data*)a->data.v; - int rm = read_reference(&ad->mage, store, read_unit_reference, resolve_unit); - int rt = read_reference(&ad->target, store, read_unit_reference, resolve_unit); - if (rt==0 && rm==0 && (!ad->target || !ad->mage)) { - /* the target or mage disappeared. */ - return AT_READ_FAIL; - } - return AT_READ_OK; -} - -static attrib_type at_alp = { - "alp", - alp_init, - alp_done, - alp_verify, - alp_write, - alp_read, - ATF_UNIQUE -}; - -int -sp_summon_alp(struct castorder *co) -{ - unit *alp, *opfer; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - const struct race * rc = new_race[RC_ALP]; - struct faction * f = get_monsters(); - struct message * msg; - - opfer = pa->param[0]->data.u; - - /* Der Alp geh�rt den Monstern, darum erh�lt der Magier auch keine - * Regionsberichte von ihm. Er erh�lt aber sp�ter eine Mitteilung, - * sobald der Alp sein Opfer erreicht hat. - */ - alp = create_unit(r, f, 1, rc, 0, NULL, NULL); - set_level(alp, SK_STEALTH, 7); - setstatus(alp, ST_FLEE); /* flieht */ - - { - attrib * a = a_add(&alp->attribs, a_new(&at_alp)); - alp_data * ad = (alp_data*) a->data.v; - ad->mage = mage; - ad->target = opfer; - } - - { - /* Wenn der Alp stirbt, den Magier nachrichtigen */ - add_trigger(&alp->attribs, "destroy", trigger_unitmessage(mage, - "trigger_alp_destroy", MSG_EVENT, ML_INFO)); - /* Wenn Opfer oder Magier nicht mehr existieren, dann stirbt der Alp */ - add_trigger(&mage->attribs, "destroy", trigger_killunit(alp)); - add_trigger(&opfer->attribs, "destroy", trigger_killunit(alp)); - } - msg = msg_message("summon_alp_effect", "mage alp target", mage, alp, opfer); - r_addmessage(r, mage->faction, msg); - msg_release(msg); - - return cast_level; -} - - -void -alp_findet_opfer(unit *alp, region *r) -{ - curse * c; - attrib * a = a_find(alp->attribs, &at_alp); - alp_data * ad = (alp_data*)a->data.v; - unit *mage = ad->mage; - unit *opfer = ad->target; - double effect; - message * msg; - - assert(opfer); - assert(mage); - - /* Magier und Opfer Bescheid geben */ - msg = msg_message("alp_success", "target", opfer); - add_message(&mage->faction->msgs, msg); - r_addmessage(opfer->region, opfer->faction, msg); - msg_release(msg); - - /* Relations werden in destroy_unit(alp) automatisch gel�scht. - * Die Aktionen, die beim Tod des Alps ausgel�st werden sollen, - * m�ssen jetzt aber deaktiviert werden, sonst werden sie gleich - * beim destroy_unit(alp) ausgel�st. - */ - a_removeall(&alp->attribs, &at_eventhandler); - - /* Alp umwandeln in Curse */ - effect = -2; - c = create_curse(mage, &opfer->attribs, ct_find("worse"), 2, 2, effect, opfer->number); - /* solange es noch keine spezielle alp-Antimagie gibt, reagiert der - * auch auf normale */ - set_number(alp, 0); - - /* wenn der Magier stirbt, wird der Curse wieder vom Opfer genommen */ - add_trigger(&mage->attribs, "destroy", trigger_removecurse(c, opfer)); -} - -void -register_alp(void) -{ - at_register(&at_alp); -} - -unit * -alp_target(unit *alp) -{ - alp_data* ad; - unit * target = NULL; - - attrib * a = a_find(alp->attribs, &at_alp); - - if (a) { - ad = (alp_data*) a->data.v; - target = ad->target; - } - return target; - -} +/* vi: set ts=2: + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#include <platform.h> +#include <kernel/config.h> +#include "alp.h" + +#include <kernel/config.h> +#include <kernel/faction.h> +#include <kernel/magic.h> +#include <kernel/message.h> +#include <kernel/race.h> +#include <kernel/region.h> +#include <kernel/skill.h> +#include <kernel/unit.h> + +/* util includes */ +#include <util/attrib.h> +#include <util/event.h> +#include <util/resolve.h> +#include <util/umlaut.h> +#include <util/storage.h> + +#include <triggers/createcurse.h> +#include <triggers/killunit.h> +#include <triggers/removecurse.h> +#include <triggers/unitmessage.h> + +/* libc includes */ +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +extern const char *directions[]; + +typedef struct alp_data { + unit * mage; + unit * target; +} alp_data; + +static void +alp_init(attrib * a) +{ + a->data.v = calloc(sizeof(alp_data), 1); +} + +static void +alp_done(attrib * a) +{ + free(a->data.v); +} + +static int +alp_verify(attrib * a) +{ + alp_data * ad = (alp_data*)a->data.v; + if (ad->mage && ad->target) return 1; + return 0; /* remove the attribute */ +} + +static void +alp_write(const attrib * a, const void * owner, struct storage * store) +{ + alp_data * ad = (alp_data*)a->data.v; + write_unit_reference(ad->mage, store); + write_unit_reference(ad->target, store); +} + +static int +alp_read(attrib * a, void * owner, struct storage * store) +{ + alp_data * ad = (alp_data*)a->data.v; + int rm = read_reference(&ad->mage, store, read_unit_reference, resolve_unit); + int rt = read_reference(&ad->target, store, read_unit_reference, resolve_unit); + if (rt==0 && rm==0 && (!ad->target || !ad->mage)) { + /* the target or mage disappeared. */ + return AT_READ_FAIL; + } + return AT_READ_OK; +} + +static attrib_type at_alp = { + "alp", + alp_init, + alp_done, + alp_verify, + alp_write, + alp_read, + ATF_UNIQUE +}; + +int +sp_summon_alp(struct castorder *co) +{ + unit *alp, *opfer; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + const struct race * rc = new_race[RC_ALP]; + struct faction * f = get_monsters(); + struct message * msg; + + opfer = pa->param[0]->data.u; + + /* Der Alp geh�rt den Monstern, darum erh�lt der Magier auch keine + * Regionsberichte von ihm. Er erh�lt aber sp�ter eine Mitteilung, + * sobald der Alp sein Opfer erreicht hat. + */ + alp = create_unit(r, f, 1, rc, 0, NULL, NULL); + set_level(alp, SK_STEALTH, 7); + setstatus(alp, ST_FLEE); /* flieht */ + + { + attrib * a = a_add(&alp->attribs, a_new(&at_alp)); + alp_data * ad = (alp_data*) a->data.v; + ad->mage = mage; + ad->target = opfer; + } + + { + /* Wenn der Alp stirbt, den Magier nachrichtigen */ + add_trigger(&alp->attribs, "destroy", trigger_unitmessage(mage, + "trigger_alp_destroy", MSG_EVENT, ML_INFO)); + /* Wenn Opfer oder Magier nicht mehr existieren, dann stirbt der Alp */ + add_trigger(&mage->attribs, "destroy", trigger_killunit(alp)); + add_trigger(&opfer->attribs, "destroy", trigger_killunit(alp)); + } + msg = msg_message("summon_alp_effect", "mage alp target", mage, alp, opfer); + r_addmessage(r, mage->faction, msg); + msg_release(msg); + + return cast_level; +} + + +void +alp_findet_opfer(unit *alp, region *r) +{ + curse * c; + attrib * a = a_find(alp->attribs, &at_alp); + alp_data * ad = (alp_data*)a->data.v; + unit *mage = ad->mage; + unit *opfer = ad->target; + double effect; + message * msg; + + assert(opfer); + assert(mage); + + /* Magier und Opfer Bescheid geben */ + msg = msg_message("alp_success", "target", opfer); + add_message(&mage->faction->msgs, msg); + r_addmessage(opfer->region, opfer->faction, msg); + msg_release(msg); + + /* Relations werden in destroy_unit(alp) automatisch gel�scht. + * Die Aktionen, die beim Tod des Alps ausgel�st werden sollen, + * m�ssen jetzt aber deaktiviert werden, sonst werden sie gleich + * beim destroy_unit(alp) ausgel�st. + */ + a_removeall(&alp->attribs, &at_eventhandler); + + /* Alp umwandeln in Curse */ + effect = -2; + c = create_curse(mage, &opfer->attribs, ct_find("worse"), 2, 2, effect, opfer->number); + /* solange es noch keine spezielle alp-Antimagie gibt, reagiert der + * auch auf normale */ + set_number(alp, 0); + + /* wenn der Magier stirbt, wird der Curse wieder vom Opfer genommen */ + add_trigger(&mage->attribs, "destroy", trigger_removecurse(c, opfer)); +} + +void +register_alp(void) +{ + at_register(&at_alp); +} + +unit * +alp_target(unit *alp) +{ + alp_data* ad; + unit * target = NULL; + + attrib * a = a_find(alp->attribs, &at_alp); + + if (a) { + ad = (alp_data*) a->data.v; + target = ad->target; + } + return target; + +} diff --git a/src/spells/alp.h b/src/spells/alp.h index 4ffd7604e..fc691b17b 100644 --- a/src/spells/alp.h +++ b/src/spells/alp.h @@ -1,54 +1,54 @@ -/* vi: set ts=2: - * - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#ifndef ALP_H -#define ALP_H -#ifdef __cplusplus -extern "C" { -#endif - -struct castorder; -struct region; -struct unit; -/* ------------------------------------------------------------- */ -/* Name: Alp - * Stufe: 15 - * Gebiet: Illaun - * Wirkung: - * Erschafft ein kleines Monster (den Alp). Dieser bewegt sich jede - * zweite Runde auf eine Zieleinheit zu. Sobald das Ziel erreicht ist, - * verwandelt es sich in einen Curse auf die Einheit, welches -2 auf - * alle Talente bewirkt. - * - * F�higkeiten (factypes.c): - * Der Alp hat mittlere Tarnung (T7) und exzellente Verteidigung - * (+20, 99% Magieresistenz, siehe factypes.c) - * - * TODO: Der Alp-Curse sollte sich durch besondere Antimagie (Tybied) - * entfernen lassen. - * - * (UNITSPELL | SEARCHGLOBAL | TESTRESISTANCE) - */ - -extern int sp_summon_alp(struct castorder *co); -extern void register_alp(void); - -struct unit* alp_target(struct unit *alp); -void alp_findet_opfer(struct unit *alp, struct region *r); - - -#ifdef __cplusplus -} -#endif -#endif +/* vi: set ts=2: + * + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#ifndef ALP_H +#define ALP_H +#ifdef __cplusplus +extern "C" { +#endif + +struct castorder; +struct region; +struct unit; +/* ------------------------------------------------------------- */ +/* Name: Alp + * Stufe: 15 + * Gebiet: Illaun + * Wirkung: + * Erschafft ein kleines Monster (den Alp). Dieser bewegt sich jede + * zweite Runde auf eine Zieleinheit zu. Sobald das Ziel erreicht ist, + * verwandelt es sich in einen Curse auf die Einheit, welches -2 auf + * alle Talente bewirkt. + * + * F�higkeiten (factypes.c): + * Der Alp hat mittlere Tarnung (T7) und exzellente Verteidigung + * (+20, 99% Magieresistenz, siehe factypes.c) + * + * TODO: Der Alp-Curse sollte sich durch besondere Antimagie (Tybied) + * entfernen lassen. + * + * (UNITSPELL | SEARCHGLOBAL | TESTRESISTANCE) + */ + +extern int sp_summon_alp(struct castorder *co); +extern void register_alp(void); + +struct unit* alp_target(struct unit *alp); +void alp_findet_opfer(struct unit *alp, struct region *r); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/spells/buildingcurse.c b/src/spells/buildingcurse.c index 22e6871d0..465b726e4 100644 --- a/src/spells/buildingcurse.c +++ b/src/spells/buildingcurse.c @@ -1,99 +1,99 @@ -/* vi: set ts=2: - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#include <platform.h> -#include <kernel/config.h> -#include "buildingcurse.h" - -/* kernel includes */ -#include <kernel/message.h> -#include <kernel/objtypes.h> -#include <kernel/building.h> -#include <kernel/ship.h> -#include <kernel/curse.h> - -/* util includes */ -#include <util/nrmessage.h> -#include <util/base36.h> -#include <util/functions.h> -#include <util/language.h> - -/* libc includes */ -#include <string.h> -#include <stdlib.h> -#include <assert.h> - - -static message * -cinfo_building(const void * obj, typ_t typ, const curse *c, int self) -{ - unused(typ); - assert(typ == TYP_BUILDING); - - if (self != 0){ /* owner or inside */ - return msg_message(mkname("curseinfo", c->type->cname), "id", c->no); - } - return msg_message(mkname("curseinfo", "buildingunknown"), "id", c->no); -} - -/* CurseInfo mit Spezialabfragen */ - -/* C_MAGICWALLS*/ -static message * -cinfo_magicrunes(const void * obj, typ_t typ, const curse *c, int self) -{ - message * msg = NULL; - if (typ == TYP_BUILDING){ - building * b; - b = (building*)obj; - if (self != 0) { - msg = msg_message("curseinfo::magicrunes_building", "building id", b, c->no); - } - } else if (typ == TYP_SHIP) { - ship *sh; - sh = (ship*)obj; - if (self != 0){ - msg = msg_message("curseinfo::magicrunes_ship", "ship id", sh, c->no); - } - } - - return msg; -} -static struct curse_type ct_magicrunes = { "magicrunes", - CURSETYP_NORM, 0, M_SUMEFFECT, cinfo_magicrunes -}; - -/* Heimstein-Zauber */ -static struct curse_type ct_magicwalls = { "magicwalls", - CURSETYP_NORM, 0, NO_MERGE, cinfo_building -}; - -/* Feste Mauer - Pr�kampfzauber, wirkt nur 1 Runde */ -static struct curse_type ct_strongwall = { "strongwall", - CURSETYP_NORM, 0, NO_MERGE, NULL -}; - -/* Ewige Mauern-Zauber */ -static struct curse_type ct_nocostbuilding = { "nocostbuilding", - CURSETYP_NORM, CURSE_NOAGE|CURSE_ONLYONE, NO_MERGE, cinfo_building -}; - - -void -register_buildingcurse(void) -{ - ct_register(&ct_magicwalls); - ct_register(&ct_strongwall); - ct_register(&ct_magicrunes); - ct_register(&ct_nocostbuilding); -} +/* vi: set ts=2: + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#include <platform.h> +#include <kernel/config.h> +#include "buildingcurse.h" + +/* kernel includes */ +#include <kernel/message.h> +#include <kernel/objtypes.h> +#include <kernel/building.h> +#include <kernel/ship.h> +#include <kernel/curse.h> + +/* util includes */ +#include <util/nrmessage.h> +#include <util/base36.h> +#include <util/functions.h> +#include <util/language.h> + +/* libc includes */ +#include <string.h> +#include <stdlib.h> +#include <assert.h> + + +static message * +cinfo_building(const void * obj, typ_t typ, const curse *c, int self) +{ + unused(typ); + assert(typ == TYP_BUILDING); + + if (self != 0){ /* owner or inside */ + return msg_message(mkname("curseinfo", c->type->cname), "id", c->no); + } + return msg_message(mkname("curseinfo", "buildingunknown"), "id", c->no); +} + +/* CurseInfo mit Spezialabfragen */ + +/* C_MAGICWALLS*/ +static message * +cinfo_magicrunes(const void * obj, typ_t typ, const curse *c, int self) +{ + message * msg = NULL; + if (typ == TYP_BUILDING){ + building * b; + b = (building*)obj; + if (self != 0) { + msg = msg_message("curseinfo::magicrunes_building", "building id", b, c->no); + } + } else if (typ == TYP_SHIP) { + ship *sh; + sh = (ship*)obj; + if (self != 0){ + msg = msg_message("curseinfo::magicrunes_ship", "ship id", sh, c->no); + } + } + + return msg; +} +static struct curse_type ct_magicrunes = { "magicrunes", + CURSETYP_NORM, 0, M_SUMEFFECT, cinfo_magicrunes +}; + +/* Heimstein-Zauber */ +static struct curse_type ct_magicwalls = { "magicwalls", + CURSETYP_NORM, 0, NO_MERGE, cinfo_building +}; + +/* Feste Mauer - Pr�kampfzauber, wirkt nur 1 Runde */ +static struct curse_type ct_strongwall = { "strongwall", + CURSETYP_NORM, 0, NO_MERGE, NULL +}; + +/* Ewige Mauern-Zauber */ +static struct curse_type ct_nocostbuilding = { "nocostbuilding", + CURSETYP_NORM, CURSE_NOAGE|CURSE_ONLYONE, NO_MERGE, cinfo_building +}; + + +void +register_buildingcurse(void) +{ + ct_register(&ct_magicwalls); + ct_register(&ct_strongwall); + ct_register(&ct_magicrunes); + ct_register(&ct_nocostbuilding); +} diff --git a/src/spells/buildingcurse.h b/src/spells/buildingcurse.h index 8389879b3..64502dcfb 100644 --- a/src/spells/buildingcurse.h +++ b/src/spells/buildingcurse.h @@ -1,28 +1,28 @@ -/* vi: set ts=2: - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#ifndef _BCURSE_H -#define _BCURSE_H -#ifdef __cplusplus -extern "C" { -#endif - -struct locale; -struct curse; - -extern void register_buildingcurse(void); - -#ifdef __cplusplus -} -#endif -#endif /* _BCURSE_H */ +/* vi: set ts=2: + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#ifndef _BCURSE_H +#define _BCURSE_H +#ifdef __cplusplus +extern "C" { +#endif + +struct locale; +struct curse; + +extern void register_buildingcurse(void); + +#ifdef __cplusplus +} +#endif +#endif /* _BCURSE_H */ diff --git a/src/spells/combatspells.c b/src/spells/combatspells.c index 9d64d23de..c48c164c6 100644 --- a/src/spells/combatspells.c +++ b/src/spells/combatspells.c @@ -1,1660 +1,1660 @@ -/* vi: set ts=2: - +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de> - | | Enno Rehling <enno@eressea.de> - | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de> - | (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de> - | | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de> - +-------------------+ Stefan Reich <reich@halbling.de> - - This program may not be used, modified or distributed - without prior permission by the authors of Eressea. -*/ -#include <platform.h> -#include <kernel/config.h> -#include "combatspells.h" - -/* kernel includes */ -#include <kernel/battle.h> -#include <kernel/build.h> -#include <kernel/building.h> -#include <kernel/faction.h> -#include <kernel/item.h> -#include <kernel/magic.h> -#include <kernel/message.h> -#include <kernel/order.h> -#include <kernel/region.h> -#include <kernel/unit.h> -#include <kernel/move.h> -#include <kernel/spell.h> -#include <kernel/spellid.h> -#include <kernel/race.h> -#include <kernel/skill.h> -#include <kernel/terrain.h> - -/* util includes */ -#include <util/attrib.h> -#include <util/base36.h> -#include <util/rand.h> -#include <util/rng.h> - -/* libc includes */ -#include <assert.h> -#include <string.h> - -#define EFFECT_HEALING_SPELL 5 - -/* ------------------------------------------------------------------ */ -/* Kampfzauberfunktionen */ - -/* COMBAT */ - -static const char * -spell_damage(int sp) -{ - switch (sp) { - case 0: - /* meist t�dlich 20-65 HP */ - return "5d10+15"; - case 1: - /* sehr variabel 4-48 HP */ - return "4d12"; - case 2: - /* leicht verwundet 4-18 HP */ - return "2d8+2"; - case 3: - /* fast immer t�dlich 30-50 HP */ - return "5d5+25"; - case 4: - /* verwundet 11-26 HP */ - return "3d6+8"; - case 5: - /* leichter Schaden */ - return "2d4"; - default: - /* schwer verwundet 14-34 HP */ - return "4d6+10"; - } -} - -static double -get_force(double power, int formel) -{ - switch (formel) { - case 0: - /* (4,8,12,16,20,24,28,32,36,40,44,..)*/ - return (power * 4); - case 1: - /* (15,30,45,60,75,90,105,120,135,150,165,..) */ - return (power*15); - case 2: - /* (40,80,120,160,200,240,280,320,360,400,440,..)*/ - return (power*40); - case 3: - /* (2,8,18,32,50,72,98,128,162,200,242,..)*/ - return (power*power*2); - case 4: - /* (4,16,36,64,100,144,196,256,324,400,484,..)*/ - return (power*power*4); - case 5: - /* (10,40,90,160,250,360,490,640,810,1000,1210,1440,..)*/ - return (power*power*10); - case 6: - /* (6,24,54,96,150,216,294,384,486,600,726,864)*/ - return (power*power*6); - default: - return power; - } -} - -/* Generischer Kampfzauber */ -int -sp_kampfzauber(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - troop at, dt; - message * m; - /* Immer aus der ersten Reihe nehmen */ - int force, enemies; - int killed = 0; - const char *damage; - - if (power <= 0) return 0; - at.fighter = fi; - at.index = 0; - - switch(sp->id) { - /* lovar halbiert im Schnitt! */ - case SPL_FIREBALL: - damage = spell_damage(0); - force = lovar(get_force(power,0)); - break; - case SPL_HAGEL: - damage = spell_damage(2); - force = lovar(get_force(power,4)); - break; - case SPL_METEORRAIN: - damage = spell_damage(1); - force = lovar(get_force(power,1)); - break; - default: - damage = spell_damage(10); - force = lovar(get_force(power,10)); - } - - enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); - if (enemies==0) { - message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - while (force>0 && killed < enemies) { - dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); - assert(dt.fighter); - --force; - killed += terminate(dt, at, AT_COMBATSPELL, damage, false); - } - - m = msg_message("battle::combatspell", "mage spell dead", - fi->unit, sp, killed); - message_all(b, m); - msg_release(m); - - return level; -} - -/* Versteinern */ -int -sp_petrify(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - /* Wirkt auf erste und zweite Reihe */ - int force, enemies; - int stoned = 0; - message * m; - - force = lovar(get_force(power, 0)); - - enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - if (!enemies) { - message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - while (force && stoned < enemies) { - troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - unit * du = dt.fighter->unit; - if (is_magic_resistant(mage, du, 0) == false) { - /* person ans ende hinter die lebenden schieben */ - remove_troop(dt); - ++stoned; - } - --force; - } - - m = msg_message("cast_petrify_effect", "mage spell amount", fi->unit, sp, stoned); - message_all(b, m); - msg_release(m); - return level; -} - -/* Benommenheit: eine Runde kein Angriff */ -int -sp_stun(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - message * m; - troop at; - /* Aus beiden Reihen nehmen */ - int force=0, enemies; - int stunned; - - if (power <= 0) return 0; - at.fighter = fi; - at.index = 0; - - switch(sp->id) { - case SPL_SHOCKWAVE: - force = lovar(get_force(power,1)); - break; - default: - assert(0); - } - - enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - if (!enemies) { - message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - stunned = 0; - while (force && stunned < enemies) { - troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - fighter * df = dt.fighter; - unit * du = df->unit; - - --force; - if (is_magic_resistant(mage, du, 0) == false) { - df->person[dt.index].flags |= FL_STUNNED; - ++stunned; - } - } - - m = msg_message("cast_stun_effect", "mage spell amount", fi->unit, sp, stunned); - message_all(b, m); - msg_release(m); - return level; -} - -/* ------------------------------------------------------------- */ -/* F�r Spr�che 'get_scrambled_list_of_enemys_in_row', so da� man diese - * Liste nur noch einmal durchlaufen muss, um Fl�chenzauberwirkungen - * abzuarbeiten */ - -/* Rosthauch */ -int -sp_combatrosthauch(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - cvector *fgs; - void **fig; - int force = lovar(power * 15); - int k = 0; - - /* Immer aus der ersten Reihe nehmen */ - unused(sp); - - if (!count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE|SELECT_FIND)) { - message * msg = msg_message("rust_effect_0", "mage", fi->unit); - message_all(b, msg); - msg_release(msg); - return 0; - } - - fgs = fighters(b, fi->side, FIGHT_ROW, BEHIND_ROW-1, FS_ENEMY); - v_scramble(fgs->begin, fgs->end); - - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; - - if (df->alive==0) continue; - if (force<=0) break; - - /* da n MIN(force, x), sollte force maximal auf 0 sinken */ - assert(force >= 0); - - if (df->weapons) { - int w; - for (w=0;df->weapons[w].type!=NULL;++w) { - weapon * wp = df->weapons; - int n = MIN(force, wp->used); - if (n) { - requirement * mat = wp->type->itype->construction->materials; - boolean iron = false; - while (mat && mat->number>0) { - if (mat->rtype==oldresourcetype[R_IRON]) { - iron = true; - break; - } - mat++; - } - if (iron) { - int p; - force -=n; - wp->used -= n; - k +=n; - i_change(&df->unit->items, wp->type->itype, -n); - for (p=0;n && p!=df->unit->number;++p) { - if (df->person[p].missile==wp) { - df->person[p].missile = NULL; - --n; - } - } - for (p=0;n && p!=df->unit->number;++p) { - if (df->person[p].melee==wp) { - df->person[p].melee = NULL; - --n; - } - } - } - } - } - } - } - cv_kill(fgs); - free(fgs); - - if (k == 0) { - /* keine Waffen mehr da, die zerst�rt werden k�nnten */ - message * msg = msg_message("rust_effect_1", "mage", fi->unit); - message_all(b, msg); - msg_release(msg); - fi->magic = 0; /* k�mpft nichtmagisch weiter */ - level = 0; - } else { - message * msg = msg_message("rust_effect_2", "mage", fi->unit); - message_all(b, msg); - msg_release(msg); - } - return level; -} - -int -sp_sleep(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - unit *du; - troop dt; - int force, enemies; - int k = 0; - message * m; - /* Immer aus der ersten Reihe nehmen */ - - force = lovar(power * 25); - enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - - if (!enemies) { - m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - while (force && enemies) { - dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - assert(dt.fighter); - du = dt.fighter->unit; - if (!is_magic_resistant(mage, du, 0)) { - dt.fighter->person[dt.index].flags |= FL_SLEEPING; - ++k; - --enemies; - } - --force; - } - - m = msg_message("cast_sleep_effect", "mage spell amount", fi->unit, sp, k); - message_all(b, m); - msg_release(m); - return level; -} - - -int -sp_speed(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - int force; - int allies; - int targets = 0; - message * m; - - force = lovar(power * power * 5); - - allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE, ALLY_ANY); - /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde - * die Gefahr eine Endlosschleife*/ - allies *= 2; - - while (force && allies) { - troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW, ALLY_ANY); - fighter *df = dt.fighter; - --allies; - - if (df) { - if (df->person[dt.index].speed == 1) { - df->person[dt.index].speed++; - targets++; - --force; - } - } - } - - m = msg_message("cast_speed_effect", "mage spell amount", fi->unit, sp, targets); - message_all(b, m); - msg_release(m); - return 1; -} - -static skill_t -random_skill(unit *u, boolean weighted) -{ - int n = 0; - skill * sv; - - for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { - if (sv->level>0) { - if (weighted) n+= sv->level; - else ++n; - } - } - - if (n == 0) - return NOSKILL; - - n = rng_int()%n; - - for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { - if (sv->level>0) { - if (weighted) { - if (n<(int)sv->level) return sv->id; - n-=sv->level; - } else { - if (n == 0) return sv->id; - --n; - } - } - } - - assert(0==1); /* Hier sollte er niemals ankommen. */ - return NOSKILL; -} - -/** The mind blast spell for regular folks. -* This spell temporarily reduces the skill of the victims -*/ -int -sp_mindblast_temp(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - int k = 0, reset = 0, maxloss = (level+2)/3; - message * m; - int force = lovar(power * 25); - int enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - - if (!enemies) { - m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - while (force>0 && enemies>0) { - unit *du; - troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - - assert(dt.fighter); - du = dt.fighter->unit; - if (fval(du, UFL_MARK)) { - /* not this one again */ - continue; - } - - if (humanoidrace(du->race) && force>=du->number) { - if (!is_magic_resistant(mage, du, 0)) { - skill_t sk = random_skill(du, true); - if (sk != NOSKILL) { - int n = 1 + rng_int() % maxloss; - attrib * a = make_skillmod(sk, SMF_ALWAYS, NULL, 0.0, n); - /* neat: you can add a whole lot of these to a unit, they stack */ - a_add(&du->attribs, a); - } - k += du->number; - } - force -= du->number; - } - fset(du, UFL_MARK); - reset = 1; - enemies -= du->number; - } - - if (reset) { - unit * u; - for (u=b->region->units;u;u=u->next) { - freset(u, UFL_MARK); - } - } - - m = msg_message("sp_mindblast_temp_effect", "mage spell amount", mage, sp, k); - message_all(b, m); - msg_release(m); - return level; -} - -/** A mind blast spell for monsters. - * This spell PERMANENTLY reduces the skill of the victims or kills them - * when they have no skills left. Not currently in use. - */ -int -sp_mindblast(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - int killed = 0, k = 0, reset = 0; - message * m; - int force = lovar(power * 25); - int enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - - if (!enemies) { - m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - while (enemies>0 && force>0) { - unit *du; - troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - - assert(dt.fighter); - du = dt.fighter->unit; - if (fval(du, UFL_MARK)) { - /* not this one again */ - continue; - } - - if (humanoidrace(du->race) && force>=du->number) { - if (!is_magic_resistant(mage, du, 0)) { - skill_t sk = random_skill(du, false); - if (sk != NOSKILL) { - skill * sv = get_skill(du, sk); - int n = 1 + rng_int() % 3; - - reduce_skill(du, sv, n); - k+=du->number; - } else { - /* unit has no skill. kill it. */ - kill_troop(dt); - ++killed; - } - } - force -= du->number; - } else { - /* only works against humanoids, don't try others. but do remove them - * from 'force' once or we may never terminate. */ - fset(du, UFL_MARK); - reset = 1; - } - enemies -= du->number; - } - - if (reset) { - unit * u; - for (u=b->region->units;u;u=u->next) { - freset(u, UFL_MARK); - } - } - - m = msg_message("sp_mindblast_effect", "mage spell amount dead", mage, sp, k, killed); - message_all(b, m); - msg_release(m); - return level; -} - -int -sp_dragonodem(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - troop dt; - troop at; - int force, enemies; - int killed = 0; - const char *damage; - - /* 11-26 HP */ - damage = spell_damage(4); - /* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */ - force = lovar(get_force(power, 6)); - - enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); - - if (!enemies) { - struct message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } else { - struct message * m; - - at.fighter = fi; - at.index = 0; - - while (force && killed < enemies) { - dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); - assert(dt.fighter); - --force; - killed += terminate(dt, at, AT_COMBATSPELL, damage, false); - } - - m = msg_message("battle::combatspell", "mage spell dead", fi->unit, sp, killed); - message_all(b, m); - msg_release(m); - } - return level; -} - -/* Feuersturm: Betrifft sehr viele Gegner (in der Regel alle), - * macht nur vergleichsweise geringen Schaden */ -int -sp_immolation(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - troop at; - int force; - int killed = 0; - const char *damage; - cvector *fgs; - void **fig; - message * m; - - /* 2d4 HP */ - damage = spell_damage(5); - /* Betrifft alle Gegner */ - force = 99999; - - if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE|SELECT_FIND)) { - message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - at.fighter = fi; - at.index = 0; - - fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY); - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; - int n = df->alive-df->removed; - troop dt; - - dt.fighter = df; - while (n!=0) { - dt.index = --n; - killed += terminate(dt, at, AT_COMBATSPELL, damage, false); - if (--force==0) break; - } - if (force==0) break; - } - cv_kill(fgs); - free(fgs); - - m = msg_message("battle::combatspell", "mage spell killed", fi->unit, sp, killed); - message_all(b, m); - msg_release(m); - return level; -} - -int -sp_drainodem(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - troop dt; - troop at; - int force, enemies; - int drained = 0; - int killed = 0; - const char *damage; - message * m; - - /* 11-26 HP */ - damage = spell_damage(4); - /* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */ - force = lovar(get_force(power, 6)); - - enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); - - if (!enemies) { - m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - at.fighter = fi; - at.index = 0; - - while (force && drained < enemies) { - dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); - assert(dt.fighter); - if (hits(at, dt, NULL)) { - drain_exp(dt.fighter->unit, 90); - ++drained; - killed += terminate(dt, at, AT_COMBATSPELL, damage, false); - } - --force; - } - - m = msg_message("cast_drainlife_effect", "mage spell amount", fi->unit, sp, drained); - message_all(b, m); - msg_release(m); - return level; -} - -/* ------------------------------------------------------------- */ -/* PRECOMBAT */ - -int -sp_shadowcall(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - region *r = b->region; - unit *mage = fi->unit; - attrib *a; - int force = (int)(get_force(power, 3)/2); - unit *u; - const char * races[3] = { "shadowbat", "nightmare", "vampunicorn" }; - const race *rc = rc_find(races[rng_int()%3]); - message * msg; - - unused(sp); - - u = create_unit(r, mage->faction, force, rc, 0, NULL, mage); - setstatus(u, ST_FIGHT); - - set_level(u, SK_WEAPONLESS, (int)(power/2)); - set_level(u, SK_STAMINA, (int)(power/2)); - u->hp = u->number * unit_max_hp(u); - - a = a_new(&at_unitdissolve); - a->data.ca[0] = 0; - a->data.ca[1] = 100; - a_add(&u->attribs, a); - - make_fighter(b, u, fi->side, is_attacker(fi)); - msg = msg_message("sp_shadowcall_effect", "mage amount race", mage, u->number, u->race); - message_all(b, msg); - msg_release(msg); - return level; -} - -int -sp_wolfhowl(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - region *r = b->region; - unit *mage = fi->unit; - attrib *a; - message * msg; - int force = (int)(get_force(power, 3)/2); - unit * u = create_unit(r, mage->faction, force, new_race[RC_WOLF], 0, NULL, mage); - unused(sp); - - leave(u, true); - setstatus(u, ST_FIGHT); - - set_level(u, SK_WEAPONLESS, (int)(power/3)); - set_level(u, SK_STAMINA, (int)(power/3)); - u->hp = u->number * unit_max_hp(u); - - if (fval(mage, UFL_ANON_FACTION)) { - fset(u, UFL_ANON_FACTION); - } - - a = a_new(&at_unitdissolve); - a->data.ca[0] = 0; - a->data.ca[1] = 100; - a_add(&u->attribs, a); - - make_fighter(b, u, fi->side, is_attacker(fi)); - msg = msg_message("sp_wolfhowl_effect", "mage amount race", mage, u->number, u->race); - message_all(b, msg); - msg_release(msg); - - return level; -} - -int -sp_shadowknights(fighter * fi, int level, double power, spell * sp) -{ - unit *u; - battle *b = fi->side->battle; - region *r = b->region; - unit *mage = fi->unit; - attrib *a; - int force = MAX(1, (int)get_force(power, 3)); - message * msg; - - unused(sp); - - - u = create_unit(r, mage->faction, force, new_race[RC_SHADOWKNIGHT], 0, NULL, mage); - setstatus(u, ST_FIGHT); - - u->hp = u->number * unit_max_hp(u); - - if (fval(mage, UFL_ANON_FACTION)) { - fset(u, UFL_ANON_FACTION); - } - - a = a_new(&at_unitdissolve); - a->data.ca[0] = 0; - a->data.ca[1] = 100; - a_add(&u->attribs, a); - - make_fighter(b, u, fi->side, is_attacker(fi)); - - msg = msg_message("sp_shadowknights_effect", "mage", mage); - message_all(b, msg); - msg_release(msg); - - return level; -} - -int -sp_strong_wall(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - building *burg; - double effect; - static boolean init = false; - message * msg; - static const curse_type * strongwall_ct; - if (!init) { init = true; strongwall_ct = ct_find("strongwall"); } - - unused(sp); - - if (!mage->building) { - return 0; - } - burg = mage->building; - - effect = power*0.25; - create_curse(mage, &burg->attribs, strongwall_ct, power, 1, effect, 0); - - msg = msg_message("sp_strongwalls_effect", "mage building", mage, mage->building); - message_all(b, msg); - msg_release(msg); - - return level; -} - -/** Spells: chaosrow / song of confusion. - * German Title: 'Gesang der Verwirrung' - */ -int -sp_chaosrow(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - cvector *fgs; - void **fig; - message * m; - const char * mtype; - int k = 0; - - if (!count_enemies(b, fi, FIGHT_ROW, NUMROWS, SELECT_ADVANCE|SELECT_FIND)) { - m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - if (sp->id==SPL_CHAOSROW) power *=40; - else power = get_force(power, 5); - - fgs = fighters(b, fi->side, FIGHT_ROW, NUMROWS, FS_ENEMY); - v_scramble(fgs->begin, fgs->end); - - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; - int n = df->unit->number; - - if (df->alive==0) continue; - if (power<=0.0) break; - /* force sollte wegen des MAX(0,x) nicht unter 0 fallen k�nnen */ - - if (is_magic_resistant(mage, df->unit, 0)) continue; - - if (chance(power/n)) { - int row = statusrow(df->status); - df->side->size[row] -= df->alive; - if (df->unit->race->battle_flags & BF_NOBLOCK) { - df->side->nonblockers[row] -= df->alive; - } - row = FIRST_ROW + (rng_int()%(LAST_ROW-FIRST_ROW)); - switch (row) { - case FIGHT_ROW: - df->status = ST_FIGHT; - break; - case BEHIND_ROW: - df->status = ST_CHICKEN; - break; - case AVOID_ROW: - df->status = ST_AVOID; - break; - case FLEE_ROW: - df->status = ST_FLEE; - break; - default: - assert(!"unknown combatrow"); - } - assert(statusrow(df->status)==row); - df->side->size[row] += df->alive; - if (df->unit->race->battle_flags & BF_NOBLOCK) { - df->side->nonblockers[row] += df->alive; - } - k+=df->alive; - } - power = MAX(0, power-n); - } - cv_kill(fgs); - free(fgs); - - if (sp->id==SPL_CHAOSROW) { - mtype = (k>0) ? "sp_chaosrow_effect_1" : "sp_chaosrow_effect_0"; - } else { - mtype = (k>0) ? "sp_confusion_effect_1" : "sp_confusion_effect_0"; - } - m = msg_message(mtype, "mage", mage); - message_all(b, m); - msg_release(m); - return level; -} - -/* Gesang der Furcht (Kampfzauber) */ -/* Panik (Pr�kampfzauber) */ - -int -sp_flee(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - cvector *fgs; - void **fig; - int force, n; - int panik = 0; - message * msg; - - switch(sp->id) { - case SPL_FLEE: - force = (int)get_force(power,4); - break; - case SPL_SONG_OF_FEAR: - force = (int)get_force(power,3); - break; - case SPL_AURA_OF_FEAR: - force = (int)get_force(power,5); - break; - default: - force = (int)get_force(power,10); - } - - if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE|SELECT_FIND)) { - msg = msg_message("sp_flee_effect_0", "mage spell", mage, sp); - message_all(b, msg); - msg_release(msg); - return 0; - } - - fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY); - v_scramble(fgs->begin, fgs->end); - - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; - for (n=0; n!=df->alive; ++n) { - if (force < 0) - break; - - if (df->person[n].flags & FL_PANICED) { /* bei SPL_SONG_OF_FEAR m�glich */ - df->person[n].attack -= 1; - --force; - ++panik; - } else if (!(df->person[n].flags & FL_COURAGE) - || !fval(df->unit->race, RCF_UNDEAD)) - { - if (is_magic_resistant(mage, df->unit, 0) == false) { - df->person[n].flags |= FL_PANICED; - ++panik; - } - --force; - } - } - } - cv_kill(fgs); - free(fgs); - - msg = msg_message("sp_flee_effect_1", "mage spell amount", mage, sp, panik); - message_all(b, msg); - msg_release(msg); - - return level; -} - -/* Heldenmut */ -int -sp_hero(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - int df_bonus = 0; - int force = 0; - int allies; - int targets = 0; - message * m; - - switch(sp->id) { - case SPL_HERO: - df_bonus = (int)(power/5); - force = MAX(1, lovar(get_force(power, 4))); - break; - - default: - df_bonus = 1; - force = MAX(1, (int)power); - } - - allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE, ALLY_ANY); - /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde - * die Gefahr eine Endlosschleife*/ - allies *= 2; - - while (force && allies) { - troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW, ALLY_ANY); - fighter *df = dt.fighter; - --allies; - - if (df) { - if (!(df->person[dt.index].flags & FL_COURAGE)) { - df->person[dt.index].defence += df_bonus; - df->person[dt.index].flags = df->person[dt.index].flags | FL_COURAGE; - targets++; - --force; - } - } - } - - m = msg_message("cast_hero_effect", "mage spell amount", fi->unit, sp, targets); - message_all(b, m); - msg_release(m); - - return level; -} - -int -sp_berserk(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - int at_bonus = 0; - int df_malus = 0; - int force = 0; - int allies = 0; - int targets = 0; - message * m; - - switch(sp->id) { - case SPL_BERSERK: - case SPL_BLOODTHIRST: - at_bonus = MAX(1,level/3); - df_malus = 2; - force = (int)get_force(power,2); - break; - - default: - at_bonus = 1; - df_malus = 0; - force = (int)power; - } - - allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE, ALLY_ANY); - /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde - * die Gefahr eine Endlosschleife*/ - allies *= 2; - - while (force && allies) { - troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW-1, ALLY_ANY); - fighter *df = dt.fighter; - --allies; - - if (df) { - if (!(df->person[dt.index].flags & FL_COURAGE)) { - df->person[dt.index].attack += at_bonus; - df->person[dt.index].defence -= df_malus; - df->person[dt.index].flags = df->person[dt.index].flags | FL_COURAGE; - targets++; - --force; - } - } - } - - m = msg_message("cast_berserk_effect", "mage spell amount", fi->unit, sp, targets); - message_all(b, m); - msg_release(m); - return level; -} - -int -sp_frighten(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - int at_malus = 0; - int df_malus = 0; - int force = 0; - int enemies = 0; - int targets = 0; - message * m; - - at_malus = MAX(1,level - 4); - df_malus = 2; - force = (int)get_force(power, 2); - - enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); - if (!enemies) { - message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - while (force && enemies) { - troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); - fighter *df = dt.fighter; - --enemies; - - if (!df) - break; - - assert(!helping(fi->side, df->side)); - - if (df->person[dt.index].flags & FL_COURAGE) { - df->person[dt.index].flags &= ~(FL_COURAGE); - } - if (is_magic_resistant(mage, df->unit, 0) == false) { - df->person[dt.index].attack -= at_malus; - df->person[dt.index].defence -= df_malus; - targets++; - } - --force; - } - - m = msg_message("cast_frighten_effect", "mage spell amount", fi->unit, sp, targets); - message_all(b, m); - msg_release(m); - return level; -} - - -int -sp_tiredsoldiers(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - int n = 0; - int force = (int)(power * power * 4); - message * m; - - if (!count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE|SELECT_FIND)) { - message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - while (force) { - troop t = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); - fighter *df = t.fighter; - - if (!df) - break; - - assert(!helping(fi->side, df->side)); - if (!(df->person[t.index].flags & FL_TIRED)) { - if (is_magic_resistant(mage, df->unit, 0) == false) { - df->person[t.index].flags = df->person[t.index].flags | FL_TIRED; - df->person[t.index].defence -= 2; - ++n; - } - } - --force; - } - - m = msg_message("cast_tired_effect", "mage spell amount", fi->unit, sp, n); - message_all(b, m); - msg_release(m); - return level; -} - -int -sp_windshield(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - int force, at_malus; - int enemies; - message * m; - - switch(sp->id) { - case SPL_WINDSHIELD: - force = (int)get_force(power,4); - at_malus = level/4; - break; - - default: - force = (int)power; - at_malus = 2; - } - enemies = count_enemies(b, fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE); - if (!enemies) { - m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return 0; - } - - while (force && enemies) { - troop dt = select_enemy(fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE); - fighter *df = dt.fighter; - --enemies; - - if (!df) - break; - assert(!helping(fi->side, df->side)); - - if (df->person[dt.index].missile) { - /* this suxx... affects your melee weapon as well. */ - df->person[dt.index].attack -= at_malus; - --force; - } - } - - m = msg_message("cast_storm_effect", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return level; -} - -int -sp_reeling_arrows(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - message * m; - - unused(power); - - b->reelarrow = true; - m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - return level; -} - -int -sp_denyattack(fighter * fi, int level, double power, spell * sp) -{ -/* Magier weicht dem Kampf aus. Wenn er sich bewegen kann, zieht er in - * eine Nachbarregion, wobei ein NACH ber�cksichtigt wird. Ansonsten - * bleibt er stehen und nimmt nicht weiter am Kampf teil. */ - battle *b = fi->side->battle; - unit *mage = fi->unit; - region *r = b->region; - message * m; - - unused(power); - - /* Fliehende Einheiten verlassen auf jeden Fall Geb�ude und Schiffe. */ - if (!fval(r->terrain, SEA_REGION)) { - leave(mage, false); - } - /* und bewachen nicht */ - setguard(mage, GUARD_NONE); - /* irgendwie den langen befehl sperren */ - /* fset(fi, FIG_ATTACKED); */ - - /* wir tun so, als w�re die Person geflohen */ - fset(fi, FIG_NOLOOT); - fi->run.hp = mage->hp; - fi->run.number = mage->number; - /* fighter leeren */ - rmfighter(fi, mage->number); - - m = msg_message("cast_escape_effect", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - - return level; -} - -static void -do_meffect(fighter * af, int typ, int effect, int duration) -{ - battle *b = af->side->battle; - meffect *meffect = calloc(1, sizeof(struct meffect)); - cv_pushback(&b->meffects, meffect); - meffect->magician = af; - meffect->typ = typ; - meffect->effect = effect; - meffect->duration = duration; -} - -int -sp_armorshield(fighter * fi, int level, double power, spell * sp) -{ - int effect; - int duration; - battle *b = fi->side->battle; - message * m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp); - - message_all(b, m); - msg_release(m); - - /* gibt R�stung +effect f�r duration Treffer */ - - switch(sp->id) { - case SPL_ARMORSHIELD: - effect = level/3; - duration = (int)(20*power*power); - break; - - default: - effect = level/4; - duration = (int)(power*power); - } - do_meffect(fi, SHIELD_ARMOR, effect, duration); - return level; -} - -int -sp_reduceshield(fighter * fi, int level, double power, spell * sp) -{ - int effect; - int duration; - battle *b = fi->side->battle; - message * m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp); - message_all(b, m); - msg_release(m); - - /* jeder Schaden wird um effect% reduziert bis der Schild duration - * Trefferpunkte aufgefangen hat */ - - switch(sp->id) { - case SPL_REDUCESHIELD: - effect = 50; - duration = (int)(50*power*power); - break; - - default: - effect = level*3; - duration = (int)get_force(power,5); - } - do_meffect(fi, SHIELD_REDUCE, effect, duration); - return level; -} - -int -sp_fumbleshield(fighter * fi, int level, double power, spell * sp) -{ - int effect; - int duration; - battle *b = fi->side->battle; - message * m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp); - - message_all(b, m); - msg_release(m); - - /* der erste Zauber schl�gt mit 100% fehl */ - - switch(sp->id) { - case SPL_DRAIG_FUMBLESHIELD: - case SPL_GWYRRD_FUMBLESHIELD: - case SPL_CERRDOR_FUMBLESHIELD: - case SPL_TYBIED_FUMBLESHIELD: - duration = 100; - effect = MAX(1, 25-level); - break; - - default: - duration = 100; - effect = 10; - } - do_meffect(fi, SHIELD_BLOCK, effect, duration); - return level; -} - -/* ------------------------------------------------------------- */ -/* POSTCOMBAT */ - -static int -count_healable(battle *b, fighter *df) -{ - side *s; - int healable = 0; - - for (s=b->sides;s!=b->sides+b->nsides;++s) { - if (helping(df->side, s)) { - healable += s->casualties; - } - } - return healable; -} - -/* wiederbeleben */ -int -sp_reanimate(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - int healable, j=0; - double c = 0.50 + 0.02 * power; - double k = EFFECT_HEALING_SPELL * power; - boolean use_item = get_item(mage, I_AMULET_OF_HEALING) > 0; - message * msg; - - if (use_item) { - k *= 2; - c += 0.10; - } - - healable = count_healable(b, fi); - healable = (int)MIN(k, healable); - while (healable--) { - fighter * tf = select_corpse(b, fi); - if (tf!=NULL && tf->side->casualties > 0 - && tf->unit->race != new_race[RC_DAEMON] - && (chance(c))) - { - assert(tf->alive < tf->unit->number); - /* t.fighter->person[].hp beginnt mit t.index = 0 zu z�hlen, - * t.fighter->alive ist jedoch die Anzahl lebender in der Einheit, - * also sind die hp von t.fighter->alive - * t.fighter->hitpoints[t.fighter->alive-1] und der erste Tote - * oder weggelaufene ist t.fighter->hitpoints[tf->alive] */ - tf->person[tf->alive].hp = 2; - ++tf->alive; - ++tf->side->size[SUM_ROW]; - ++tf->side->size[tf->unit->status + 1]; - ++tf->side->healed; - --tf->side->casualties; - assert(tf->side->casualties>=0); - --tf->side->dead; - assert(tf->side->dead>=0); - ++j; - } - } - if (j <= 0) { - level = j; - } - if (use_item) { - msg = msg_message("reanimate_effect_1", "mage amount item", mage, j, oldresourcetype[R_AMULET_OF_HEALING]); - } else { - msg = msg_message("reanimate_effect_0", "mage amount", mage, j); - } - message_all(b, msg); - msg_release(msg); - - return level; -} - -int -sp_keeploot(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - message * m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp); - - message_all(b, m); - msg_release(m); - - b->keeploot = (int)MAX(25, b->keeploot + 5*power); - - return level; -} - -static int -heal_fighters(cvector *fgs, int * power, boolean heal_monsters) -{ - int healhp = *power; - int healed = 0; - void **fig; - - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; - - if (healhp<=0) break; - - /* Untote kann man nicht heilen */ - if (df->unit->number==0 || fval(df->unit->race, RCF_NOHEAL)) continue; - - /* wir heilen erstmal keine Monster */ - if (heal_monsters || playerrace(df->unit->race)) { - int n, hp = df->unit->hp / df->unit->number; - int rest = df->unit->hp % df->unit->number; - - for (n = 0; n < df->unit->number; n++) { - int wound = hp - df->person[n].hp; - if (rest>n) ++wound; - - if (wound > 0 && wound < hp) { - int heal = MIN(healhp, wound); - assert(heal>=0); - df->person[n].hp += heal; - healhp = MAX(0, healhp - heal); - ++healed; - if (healhp<=0) break; - } - } - } - } - - *power = healhp; - return healed; -} - -int -sp_healing(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - int j = 0; - int healhp = (int)power * 200; - cvector *fgs; - message * msg; - boolean use_item = get_item(mage, I_AMULET_OF_HEALING) > 0; - - /* bis zu 11 Personen pro Stufe (einen HP m�ssen sie ja noch - * haben, sonst w�ren sie tot) k�nnen geheilt werden */ - - if (use_item) { - healhp *= 2; - } - - /* gehe alle denen wir helfen der reihe nach durch, heile verwundete, - * bis zu verteilende HP aufgebraucht sind */ - - fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_HELP); - v_scramble(fgs->begin, fgs->end); - j += heal_fighters(fgs, &healhp, false); - j += heal_fighters(fgs, &healhp, true); - cv_kill(fgs); - free(fgs); - - if (j <= 0) { - level = j; - } - if (use_item) { - msg = msg_message("healing_effect_1", "mage amount item", mage, j, oldresourcetype[R_AMULET_OF_HEALING]); - } else { - msg = msg_message("healing_effect_0", "mage amount", mage, j); - } - message_all(b, msg); - msg_release(msg); - - return level; -} - -int -sp_undeadhero(fighter * fi, int level, double power, spell * sp) -{ - battle *b = fi->side->battle; - unit *mage = fi->unit; - region *r = b->region; - cvector *fgs; - void **fig; - int n, undead = 0; - message * msg; - int force = (int)get_force(power,0); - double c = 0.50 + 0.02 * power; - - /* Liste aus allen K�mpfern */ - fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY | FS_HELP ); - v_scramble(fgs->begin, fgs->end); - - for (fig = fgs->begin; fig != fgs->end; ++fig) { - fighter *df = *fig; - unit *du = df->unit; - - if (force<=0) break; - - /* keine Monster */ - if (!playerrace(du->race)) continue; - - if (df->alive + df->run.number < du->number) { - int j = 0; - - /* Wieviele Untote k�nnen wir aus dieser Einheit wecken? */ - for (n = df->alive + df->run.number; n != du->number; n++) { - if (chance(c)) { - ++j; - if (--force<=0) break; - } - } - - if (j > 0) { - unit * u = create_unit(r, mage->faction, 0, new_race[RC_UNDEAD], 0, du->name, du); - - /* new units gets some stats from old unit */ - - if (du->display) { - unit_setinfo(u, du->display); - } else { - unit_setinfo(u, NULL); - } - setstatus(u, du->status); - setguard(u, GUARD_NONE); - - /* inherit stealth from magician */ - if (fval(mage, UFL_ANON_FACTION)) { - fset(u, UFL_ANON_FACTION); - } - - /* transfer dead people to new unit, set hitpoints to those of old unit */ - transfermen(du, u, j); - u->hp = u->number * unit_max_hp(du); - assert(j<=df->side->casualties); - df->side->casualties -= j; - df->side->dead -= j; - - /* counting total number of undead */ - undead += j; - } - } - } - cv_kill(fgs); - free(fgs); - - level = MIN(level, undead); - if (undead == 0) { - msg = msg_message("summonundead_effect_0", "mage region", mage, mage->region); - } else { - msg = msg_message("summonundead_effect_1", "mage region amount", mage, mage->region, undead); - } - - message_all(b, msg); - msg_release(msg); - return level; -} +/* vi: set ts=2: + +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de> + | | Enno Rehling <enno@eressea.de> + | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de> + | (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de> + | | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de> + +-------------------+ Stefan Reich <reich@halbling.de> + + This program may not be used, modified or distributed + without prior permission by the authors of Eressea. +*/ +#include <platform.h> +#include <kernel/config.h> +#include "combatspells.h" + +/* kernel includes */ +#include <kernel/battle.h> +#include <kernel/build.h> +#include <kernel/building.h> +#include <kernel/faction.h> +#include <kernel/item.h> +#include <kernel/magic.h> +#include <kernel/message.h> +#include <kernel/order.h> +#include <kernel/region.h> +#include <kernel/unit.h> +#include <kernel/move.h> +#include <kernel/spell.h> +#include <kernel/spellid.h> +#include <kernel/race.h> +#include <kernel/skill.h> +#include <kernel/terrain.h> + +/* util includes */ +#include <util/attrib.h> +#include <util/base36.h> +#include <util/rand.h> +#include <util/rng.h> + +/* libc includes */ +#include <assert.h> +#include <string.h> + +#define EFFECT_HEALING_SPELL 5 + +/* ------------------------------------------------------------------ */ +/* Kampfzauberfunktionen */ + +/* COMBAT */ + +static const char * +spell_damage(int sp) +{ + switch (sp) { + case 0: + /* meist t�dlich 20-65 HP */ + return "5d10+15"; + case 1: + /* sehr variabel 4-48 HP */ + return "4d12"; + case 2: + /* leicht verwundet 4-18 HP */ + return "2d8+2"; + case 3: + /* fast immer t�dlich 30-50 HP */ + return "5d5+25"; + case 4: + /* verwundet 11-26 HP */ + return "3d6+8"; + case 5: + /* leichter Schaden */ + return "2d4"; + default: + /* schwer verwundet 14-34 HP */ + return "4d6+10"; + } +} + +static double +get_force(double power, int formel) +{ + switch (formel) { + case 0: + /* (4,8,12,16,20,24,28,32,36,40,44,..)*/ + return (power * 4); + case 1: + /* (15,30,45,60,75,90,105,120,135,150,165,..) */ + return (power*15); + case 2: + /* (40,80,120,160,200,240,280,320,360,400,440,..)*/ + return (power*40); + case 3: + /* (2,8,18,32,50,72,98,128,162,200,242,..)*/ + return (power*power*2); + case 4: + /* (4,16,36,64,100,144,196,256,324,400,484,..)*/ + return (power*power*4); + case 5: + /* (10,40,90,160,250,360,490,640,810,1000,1210,1440,..)*/ + return (power*power*10); + case 6: + /* (6,24,54,96,150,216,294,384,486,600,726,864)*/ + return (power*power*6); + default: + return power; + } +} + +/* Generischer Kampfzauber */ +int +sp_kampfzauber(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + troop at, dt; + message * m; + /* Immer aus der ersten Reihe nehmen */ + int force, enemies; + int killed = 0; + const char *damage; + + if (power <= 0) return 0; + at.fighter = fi; + at.index = 0; + + switch(sp->id) { + /* lovar halbiert im Schnitt! */ + case SPL_FIREBALL: + damage = spell_damage(0); + force = lovar(get_force(power,0)); + break; + case SPL_HAGEL: + damage = spell_damage(2); + force = lovar(get_force(power,4)); + break; + case SPL_METEORRAIN: + damage = spell_damage(1); + force = lovar(get_force(power,1)); + break; + default: + damage = spell_damage(10); + force = lovar(get_force(power,10)); + } + + enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); + if (enemies==0) { + message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + while (force>0 && killed < enemies) { + dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); + assert(dt.fighter); + --force; + killed += terminate(dt, at, AT_COMBATSPELL, damage, false); + } + + m = msg_message("battle::combatspell", "mage spell dead", + fi->unit, sp, killed); + message_all(b, m); + msg_release(m); + + return level; +} + +/* Versteinern */ +int +sp_petrify(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + /* Wirkt auf erste und zweite Reihe */ + int force, enemies; + int stoned = 0; + message * m; + + force = lovar(get_force(power, 0)); + + enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + if (!enemies) { + message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + while (force && stoned < enemies) { + troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + unit * du = dt.fighter->unit; + if (is_magic_resistant(mage, du, 0) == false) { + /* person ans ende hinter die lebenden schieben */ + remove_troop(dt); + ++stoned; + } + --force; + } + + m = msg_message("cast_petrify_effect", "mage spell amount", fi->unit, sp, stoned); + message_all(b, m); + msg_release(m); + return level; +} + +/* Benommenheit: eine Runde kein Angriff */ +int +sp_stun(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + message * m; + troop at; + /* Aus beiden Reihen nehmen */ + int force=0, enemies; + int stunned; + + if (power <= 0) return 0; + at.fighter = fi; + at.index = 0; + + switch(sp->id) { + case SPL_SHOCKWAVE: + force = lovar(get_force(power,1)); + break; + default: + assert(0); + } + + enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + if (!enemies) { + message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + stunned = 0; + while (force && stunned < enemies) { + troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + fighter * df = dt.fighter; + unit * du = df->unit; + + --force; + if (is_magic_resistant(mage, du, 0) == false) { + df->person[dt.index].flags |= FL_STUNNED; + ++stunned; + } + } + + m = msg_message("cast_stun_effect", "mage spell amount", fi->unit, sp, stunned); + message_all(b, m); + msg_release(m); + return level; +} + +/* ------------------------------------------------------------- */ +/* F�r Spr�che 'get_scrambled_list_of_enemys_in_row', so da� man diese + * Liste nur noch einmal durchlaufen muss, um Fl�chenzauberwirkungen + * abzuarbeiten */ + +/* Rosthauch */ +int +sp_combatrosthauch(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + cvector *fgs; + void **fig; + int force = lovar(power * 15); + int k = 0; + + /* Immer aus der ersten Reihe nehmen */ + unused(sp); + + if (!count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE|SELECT_FIND)) { + message * msg = msg_message("rust_effect_0", "mage", fi->unit); + message_all(b, msg); + msg_release(msg); + return 0; + } + + fgs = fighters(b, fi->side, FIGHT_ROW, BEHIND_ROW-1, FS_ENEMY); + v_scramble(fgs->begin, fgs->end); + + for (fig = fgs->begin; fig != fgs->end; ++fig) { + fighter *df = *fig; + + if (df->alive==0) continue; + if (force<=0) break; + + /* da n MIN(force, x), sollte force maximal auf 0 sinken */ + assert(force >= 0); + + if (df->weapons) { + int w; + for (w=0;df->weapons[w].type!=NULL;++w) { + weapon * wp = df->weapons; + int n = MIN(force, wp->used); + if (n) { + requirement * mat = wp->type->itype->construction->materials; + boolean iron = false; + while (mat && mat->number>0) { + if (mat->rtype==oldresourcetype[R_IRON]) { + iron = true; + break; + } + mat++; + } + if (iron) { + int p; + force -=n; + wp->used -= n; + k +=n; + i_change(&df->unit->items, wp->type->itype, -n); + for (p=0;n && p!=df->unit->number;++p) { + if (df->person[p].missile==wp) { + df->person[p].missile = NULL; + --n; + } + } + for (p=0;n && p!=df->unit->number;++p) { + if (df->person[p].melee==wp) { + df->person[p].melee = NULL; + --n; + } + } + } + } + } + } + } + cv_kill(fgs); + free(fgs); + + if (k == 0) { + /* keine Waffen mehr da, die zerst�rt werden k�nnten */ + message * msg = msg_message("rust_effect_1", "mage", fi->unit); + message_all(b, msg); + msg_release(msg); + fi->magic = 0; /* k�mpft nichtmagisch weiter */ + level = 0; + } else { + message * msg = msg_message("rust_effect_2", "mage", fi->unit); + message_all(b, msg); + msg_release(msg); + } + return level; +} + +int +sp_sleep(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + unit *du; + troop dt; + int force, enemies; + int k = 0; + message * m; + /* Immer aus der ersten Reihe nehmen */ + + force = lovar(power * 25); + enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + + if (!enemies) { + m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + while (force && enemies) { + dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + assert(dt.fighter); + du = dt.fighter->unit; + if (!is_magic_resistant(mage, du, 0)) { + dt.fighter->person[dt.index].flags |= FL_SLEEPING; + ++k; + --enemies; + } + --force; + } + + m = msg_message("cast_sleep_effect", "mage spell amount", fi->unit, sp, k); + message_all(b, m); + msg_release(m); + return level; +} + + +int +sp_speed(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + int force; + int allies; + int targets = 0; + message * m; + + force = lovar(power * power * 5); + + allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE, ALLY_ANY); + /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde + * die Gefahr eine Endlosschleife*/ + allies *= 2; + + while (force && allies) { + troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW, ALLY_ANY); + fighter *df = dt.fighter; + --allies; + + if (df) { + if (df->person[dt.index].speed == 1) { + df->person[dt.index].speed++; + targets++; + --force; + } + } + } + + m = msg_message("cast_speed_effect", "mage spell amount", fi->unit, sp, targets); + message_all(b, m); + msg_release(m); + return 1; +} + +static skill_t +random_skill(unit *u, boolean weighted) +{ + int n = 0; + skill * sv; + + for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { + if (sv->level>0) { + if (weighted) n+= sv->level; + else ++n; + } + } + + if (n == 0) + return NOSKILL; + + n = rng_int()%n; + + for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) { + if (sv->level>0) { + if (weighted) { + if (n<(int)sv->level) return sv->id; + n-=sv->level; + } else { + if (n == 0) return sv->id; + --n; + } + } + } + + assert(0==1); /* Hier sollte er niemals ankommen. */ + return NOSKILL; +} + +/** The mind blast spell for regular folks. +* This spell temporarily reduces the skill of the victims +*/ +int +sp_mindblast_temp(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + int k = 0, reset = 0, maxloss = (level+2)/3; + message * m; + int force = lovar(power * 25); + int enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + + if (!enemies) { + m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + while (force>0 && enemies>0) { + unit *du; + troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + + assert(dt.fighter); + du = dt.fighter->unit; + if (fval(du, UFL_MARK)) { + /* not this one again */ + continue; + } + + if (humanoidrace(du->race) && force>=du->number) { + if (!is_magic_resistant(mage, du, 0)) { + skill_t sk = random_skill(du, true); + if (sk != NOSKILL) { + int n = 1 + rng_int() % maxloss; + attrib * a = make_skillmod(sk, SMF_ALWAYS, NULL, 0.0, n); + /* neat: you can add a whole lot of these to a unit, they stack */ + a_add(&du->attribs, a); + } + k += du->number; + } + force -= du->number; + } + fset(du, UFL_MARK); + reset = 1; + enemies -= du->number; + } + + if (reset) { + unit * u; + for (u=b->region->units;u;u=u->next) { + freset(u, UFL_MARK); + } + } + + m = msg_message("sp_mindblast_temp_effect", "mage spell amount", mage, sp, k); + message_all(b, m); + msg_release(m); + return level; +} + +/** A mind blast spell for monsters. + * This spell PERMANENTLY reduces the skill of the victims or kills them + * when they have no skills left. Not currently in use. + */ +int +sp_mindblast(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + int killed = 0, k = 0, reset = 0; + message * m; + int force = lovar(power * 25); + int enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + + if (!enemies) { + m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + while (enemies>0 && force>0) { + unit *du; + troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + + assert(dt.fighter); + du = dt.fighter->unit; + if (fval(du, UFL_MARK)) { + /* not this one again */ + continue; + } + + if (humanoidrace(du->race) && force>=du->number) { + if (!is_magic_resistant(mage, du, 0)) { + skill_t sk = random_skill(du, false); + if (sk != NOSKILL) { + skill * sv = get_skill(du, sk); + int n = 1 + rng_int() % 3; + + reduce_skill(du, sv, n); + k+=du->number; + } else { + /* unit has no skill. kill it. */ + kill_troop(dt); + ++killed; + } + } + force -= du->number; + } else { + /* only works against humanoids, don't try others. but do remove them + * from 'force' once or we may never terminate. */ + fset(du, UFL_MARK); + reset = 1; + } + enemies -= du->number; + } + + if (reset) { + unit * u; + for (u=b->region->units;u;u=u->next) { + freset(u, UFL_MARK); + } + } + + m = msg_message("sp_mindblast_effect", "mage spell amount dead", mage, sp, k, killed); + message_all(b, m); + msg_release(m); + return level; +} + +int +sp_dragonodem(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + troop dt; + troop at; + int force, enemies; + int killed = 0; + const char *damage; + + /* 11-26 HP */ + damage = spell_damage(4); + /* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */ + force = lovar(get_force(power, 6)); + + enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); + + if (!enemies) { + struct message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } else { + struct message * m; + + at.fighter = fi; + at.index = 0; + + while (force && killed < enemies) { + dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); + assert(dt.fighter); + --force; + killed += terminate(dt, at, AT_COMBATSPELL, damage, false); + } + + m = msg_message("battle::combatspell", "mage spell dead", fi->unit, sp, killed); + message_all(b, m); + msg_release(m); + } + return level; +} + +/* Feuersturm: Betrifft sehr viele Gegner (in der Regel alle), + * macht nur vergleichsweise geringen Schaden */ +int +sp_immolation(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + troop at; + int force; + int killed = 0; + const char *damage; + cvector *fgs; + void **fig; + message * m; + + /* 2d4 HP */ + damage = spell_damage(5); + /* Betrifft alle Gegner */ + force = 99999; + + if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE|SELECT_FIND)) { + message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + at.fighter = fi; + at.index = 0; + + fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY); + for (fig = fgs->begin; fig != fgs->end; ++fig) { + fighter *df = *fig; + int n = df->alive-df->removed; + troop dt; + + dt.fighter = df; + while (n!=0) { + dt.index = --n; + killed += terminate(dt, at, AT_COMBATSPELL, damage, false); + if (--force==0) break; + } + if (force==0) break; + } + cv_kill(fgs); + free(fgs); + + m = msg_message("battle::combatspell", "mage spell killed", fi->unit, sp, killed); + message_all(b, m); + msg_release(m); + return level; +} + +int +sp_drainodem(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + troop dt; + troop at; + int force, enemies; + int drained = 0; + int killed = 0; + const char *damage; + message * m; + + /* 11-26 HP */ + damage = spell_damage(4); + /* Jungdrache 3->54, Drache 6->216, Wyrm 12->864 Treffer */ + force = lovar(get_force(power, 6)); + + enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); + + if (!enemies) { + m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + at.fighter = fi; + at.index = 0; + + while (force && drained < enemies) { + dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); + assert(dt.fighter); + if (hits(at, dt, NULL)) { + drain_exp(dt.fighter->unit, 90); + ++drained; + killed += terminate(dt, at, AT_COMBATSPELL, damage, false); + } + --force; + } + + m = msg_message("cast_drainlife_effect", "mage spell amount", fi->unit, sp, drained); + message_all(b, m); + msg_release(m); + return level; +} + +/* ------------------------------------------------------------- */ +/* PRECOMBAT */ + +int +sp_shadowcall(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + region *r = b->region; + unit *mage = fi->unit; + attrib *a; + int force = (int)(get_force(power, 3)/2); + unit *u; + const char * races[3] = { "shadowbat", "nightmare", "vampunicorn" }; + const race *rc = rc_find(races[rng_int()%3]); + message * msg; + + unused(sp); + + u = create_unit(r, mage->faction, force, rc, 0, NULL, mage); + setstatus(u, ST_FIGHT); + + set_level(u, SK_WEAPONLESS, (int)(power/2)); + set_level(u, SK_STAMINA, (int)(power/2)); + u->hp = u->number * unit_max_hp(u); + + a = a_new(&at_unitdissolve); + a->data.ca[0] = 0; + a->data.ca[1] = 100; + a_add(&u->attribs, a); + + make_fighter(b, u, fi->side, is_attacker(fi)); + msg = msg_message("sp_shadowcall_effect", "mage amount race", mage, u->number, u->race); + message_all(b, msg); + msg_release(msg); + return level; +} + +int +sp_wolfhowl(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + region *r = b->region; + unit *mage = fi->unit; + attrib *a; + message * msg; + int force = (int)(get_force(power, 3)/2); + unit * u = create_unit(r, mage->faction, force, new_race[RC_WOLF], 0, NULL, mage); + unused(sp); + + leave(u, true); + setstatus(u, ST_FIGHT); + + set_level(u, SK_WEAPONLESS, (int)(power/3)); + set_level(u, SK_STAMINA, (int)(power/3)); + u->hp = u->number * unit_max_hp(u); + + if (fval(mage, UFL_ANON_FACTION)) { + fset(u, UFL_ANON_FACTION); + } + + a = a_new(&at_unitdissolve); + a->data.ca[0] = 0; + a->data.ca[1] = 100; + a_add(&u->attribs, a); + + make_fighter(b, u, fi->side, is_attacker(fi)); + msg = msg_message("sp_wolfhowl_effect", "mage amount race", mage, u->number, u->race); + message_all(b, msg); + msg_release(msg); + + return level; +} + +int +sp_shadowknights(fighter * fi, int level, double power, spell * sp) +{ + unit *u; + battle *b = fi->side->battle; + region *r = b->region; + unit *mage = fi->unit; + attrib *a; + int force = MAX(1, (int)get_force(power, 3)); + message * msg; + + unused(sp); + + + u = create_unit(r, mage->faction, force, new_race[RC_SHADOWKNIGHT], 0, NULL, mage); + setstatus(u, ST_FIGHT); + + u->hp = u->number * unit_max_hp(u); + + if (fval(mage, UFL_ANON_FACTION)) { + fset(u, UFL_ANON_FACTION); + } + + a = a_new(&at_unitdissolve); + a->data.ca[0] = 0; + a->data.ca[1] = 100; + a_add(&u->attribs, a); + + make_fighter(b, u, fi->side, is_attacker(fi)); + + msg = msg_message("sp_shadowknights_effect", "mage", mage); + message_all(b, msg); + msg_release(msg); + + return level; +} + +int +sp_strong_wall(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + building *burg; + double effect; + static boolean init = false; + message * msg; + static const curse_type * strongwall_ct; + if (!init) { init = true; strongwall_ct = ct_find("strongwall"); } + + unused(sp); + + if (!mage->building) { + return 0; + } + burg = mage->building; + + effect = power*0.25; + create_curse(mage, &burg->attribs, strongwall_ct, power, 1, effect, 0); + + msg = msg_message("sp_strongwalls_effect", "mage building", mage, mage->building); + message_all(b, msg); + msg_release(msg); + + return level; +} + +/** Spells: chaosrow / song of confusion. + * German Title: 'Gesang der Verwirrung' + */ +int +sp_chaosrow(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + cvector *fgs; + void **fig; + message * m; + const char * mtype; + int k = 0; + + if (!count_enemies(b, fi, FIGHT_ROW, NUMROWS, SELECT_ADVANCE|SELECT_FIND)) { + m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + if (sp->id==SPL_CHAOSROW) power *=40; + else power = get_force(power, 5); + + fgs = fighters(b, fi->side, FIGHT_ROW, NUMROWS, FS_ENEMY); + v_scramble(fgs->begin, fgs->end); + + for (fig = fgs->begin; fig != fgs->end; ++fig) { + fighter *df = *fig; + int n = df->unit->number; + + if (df->alive==0) continue; + if (power<=0.0) break; + /* force sollte wegen des MAX(0,x) nicht unter 0 fallen k�nnen */ + + if (is_magic_resistant(mage, df->unit, 0)) continue; + + if (chance(power/n)) { + int row = statusrow(df->status); + df->side->size[row] -= df->alive; + if (df->unit->race->battle_flags & BF_NOBLOCK) { + df->side->nonblockers[row] -= df->alive; + } + row = FIRST_ROW + (rng_int()%(LAST_ROW-FIRST_ROW)); + switch (row) { + case FIGHT_ROW: + df->status = ST_FIGHT; + break; + case BEHIND_ROW: + df->status = ST_CHICKEN; + break; + case AVOID_ROW: + df->status = ST_AVOID; + break; + case FLEE_ROW: + df->status = ST_FLEE; + break; + default: + assert(!"unknown combatrow"); + } + assert(statusrow(df->status)==row); + df->side->size[row] += df->alive; + if (df->unit->race->battle_flags & BF_NOBLOCK) { + df->side->nonblockers[row] += df->alive; + } + k+=df->alive; + } + power = MAX(0, power-n); + } + cv_kill(fgs); + free(fgs); + + if (sp->id==SPL_CHAOSROW) { + mtype = (k>0) ? "sp_chaosrow_effect_1" : "sp_chaosrow_effect_0"; + } else { + mtype = (k>0) ? "sp_confusion_effect_1" : "sp_confusion_effect_0"; + } + m = msg_message(mtype, "mage", mage); + message_all(b, m); + msg_release(m); + return level; +} + +/* Gesang der Furcht (Kampfzauber) */ +/* Panik (Pr�kampfzauber) */ + +int +sp_flee(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + cvector *fgs; + void **fig; + int force, n; + int panik = 0; + message * msg; + + switch(sp->id) { + case SPL_FLEE: + force = (int)get_force(power,4); + break; + case SPL_SONG_OF_FEAR: + force = (int)get_force(power,3); + break; + case SPL_AURA_OF_FEAR: + force = (int)get_force(power,5); + break; + default: + force = (int)get_force(power,10); + } + + if (!count_enemies(b, fi, FIGHT_ROW, AVOID_ROW, SELECT_ADVANCE|SELECT_FIND)) { + msg = msg_message("sp_flee_effect_0", "mage spell", mage, sp); + message_all(b, msg); + msg_release(msg); + return 0; + } + + fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY); + v_scramble(fgs->begin, fgs->end); + + for (fig = fgs->begin; fig != fgs->end; ++fig) { + fighter *df = *fig; + for (n=0; n!=df->alive; ++n) { + if (force < 0) + break; + + if (df->person[n].flags & FL_PANICED) { /* bei SPL_SONG_OF_FEAR m�glich */ + df->person[n].attack -= 1; + --force; + ++panik; + } else if (!(df->person[n].flags & FL_COURAGE) + || !fval(df->unit->race, RCF_UNDEAD)) + { + if (is_magic_resistant(mage, df->unit, 0) == false) { + df->person[n].flags |= FL_PANICED; + ++panik; + } + --force; + } + } + } + cv_kill(fgs); + free(fgs); + + msg = msg_message("sp_flee_effect_1", "mage spell amount", mage, sp, panik); + message_all(b, msg); + msg_release(msg); + + return level; +} + +/* Heldenmut */ +int +sp_hero(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + int df_bonus = 0; + int force = 0; + int allies; + int targets = 0; + message * m; + + switch(sp->id) { + case SPL_HERO: + df_bonus = (int)(power/5); + force = MAX(1, lovar(get_force(power, 4))); + break; + + default: + df_bonus = 1; + force = MAX(1, (int)power); + } + + allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE, ALLY_ANY); + /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde + * die Gefahr eine Endlosschleife*/ + allies *= 2; + + while (force && allies) { + troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW, ALLY_ANY); + fighter *df = dt.fighter; + --allies; + + if (df) { + if (!(df->person[dt.index].flags & FL_COURAGE)) { + df->person[dt.index].defence += df_bonus; + df->person[dt.index].flags = df->person[dt.index].flags | FL_COURAGE; + targets++; + --force; + } + } + } + + m = msg_message("cast_hero_effect", "mage spell amount", fi->unit, sp, targets); + message_all(b, m); + msg_release(m); + + return level; +} + +int +sp_berserk(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + int at_bonus = 0; + int df_malus = 0; + int force = 0; + int allies = 0; + int targets = 0; + message * m; + + switch(sp->id) { + case SPL_BERSERK: + case SPL_BLOODTHIRST: + at_bonus = MAX(1,level/3); + df_malus = 2; + force = (int)get_force(power,2); + break; + + default: + at_bonus = 1; + df_malus = 0; + force = (int)power; + } + + allies = count_allies(fi->side, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE, ALLY_ANY); + /* maximal 2*allies Versuche ein Opfer zu finden, ansonsten best�nde + * die Gefahr eine Endlosschleife*/ + allies *= 2; + + while (force && allies) { + troop dt = select_ally(fi, FIGHT_ROW, BEHIND_ROW-1, ALLY_ANY); + fighter *df = dt.fighter; + --allies; + + if (df) { + if (!(df->person[dt.index].flags & FL_COURAGE)) { + df->person[dt.index].attack += at_bonus; + df->person[dt.index].defence -= df_malus; + df->person[dt.index].flags = df->person[dt.index].flags | FL_COURAGE; + targets++; + --force; + } + } + } + + m = msg_message("cast_berserk_effect", "mage spell amount", fi->unit, sp, targets); + message_all(b, m); + msg_release(m); + return level; +} + +int +sp_frighten(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + int at_malus = 0; + int df_malus = 0; + int force = 0; + int enemies = 0; + int targets = 0; + message * m; + + at_malus = MAX(1,level - 4); + df_malus = 2; + force = (int)get_force(power, 2); + + enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); + if (!enemies) { + message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + while (force && enemies) { + troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW-1, SELECT_ADVANCE); + fighter *df = dt.fighter; + --enemies; + + if (!df) + break; + + assert(!helping(fi->side, df->side)); + + if (df->person[dt.index].flags & FL_COURAGE) { + df->person[dt.index].flags &= ~(FL_COURAGE); + } + if (is_magic_resistant(mage, df->unit, 0) == false) { + df->person[dt.index].attack -= at_malus; + df->person[dt.index].defence -= df_malus; + targets++; + } + --force; + } + + m = msg_message("cast_frighten_effect", "mage spell amount", fi->unit, sp, targets); + message_all(b, m); + msg_release(m); + return level; +} + + +int +sp_tiredsoldiers(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + int n = 0; + int force = (int)(power * power * 4); + message * m; + + if (!count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE|SELECT_FIND)) { + message * m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + while (force) { + troop t = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE); + fighter *df = t.fighter; + + if (!df) + break; + + assert(!helping(fi->side, df->side)); + if (!(df->person[t.index].flags & FL_TIRED)) { + if (is_magic_resistant(mage, df->unit, 0) == false) { + df->person[t.index].flags = df->person[t.index].flags | FL_TIRED; + df->person[t.index].defence -= 2; + ++n; + } + } + --force; + } + + m = msg_message("cast_tired_effect", "mage spell amount", fi->unit, sp, n); + message_all(b, m); + msg_release(m); + return level; +} + +int +sp_windshield(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + int force, at_malus; + int enemies; + message * m; + + switch(sp->id) { + case SPL_WINDSHIELD: + force = (int)get_force(power,4); + at_malus = level/4; + break; + + default: + force = (int)power; + at_malus = 2; + } + enemies = count_enemies(b, fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE); + if (!enemies) { + m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return 0; + } + + while (force && enemies) { + troop dt = select_enemy(fi, BEHIND_ROW, BEHIND_ROW, SELECT_ADVANCE); + fighter *df = dt.fighter; + --enemies; + + if (!df) + break; + assert(!helping(fi->side, df->side)); + + if (df->person[dt.index].missile) { + /* this suxx... affects your melee weapon as well. */ + df->person[dt.index].attack -= at_malus; + --force; + } + } + + m = msg_message("cast_storm_effect", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return level; +} + +int +sp_reeling_arrows(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + message * m; + + unused(power); + + b->reelarrow = true; + m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + return level; +} + +int +sp_denyattack(fighter * fi, int level, double power, spell * sp) +{ +/* Magier weicht dem Kampf aus. Wenn er sich bewegen kann, zieht er in + * eine Nachbarregion, wobei ein NACH ber�cksichtigt wird. Ansonsten + * bleibt er stehen und nimmt nicht weiter am Kampf teil. */ + battle *b = fi->side->battle; + unit *mage = fi->unit; + region *r = b->region; + message * m; + + unused(power); + + /* Fliehende Einheiten verlassen auf jeden Fall Geb�ude und Schiffe. */ + if (!fval(r->terrain, SEA_REGION)) { + leave(mage, false); + } + /* und bewachen nicht */ + setguard(mage, GUARD_NONE); + /* irgendwie den langen befehl sperren */ + /* fset(fi, FIG_ATTACKED); */ + + /* wir tun so, als w�re die Person geflohen */ + fset(fi, FIG_NOLOOT); + fi->run.hp = mage->hp; + fi->run.number = mage->number; + /* fighter leeren */ + rmfighter(fi, mage->number); + + m = msg_message("cast_escape_effect", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + + return level; +} + +static void +do_meffect(fighter * af, int typ, int effect, int duration) +{ + battle *b = af->side->battle; + meffect *meffect = calloc(1, sizeof(struct meffect)); + cv_pushback(&b->meffects, meffect); + meffect->magician = af; + meffect->typ = typ; + meffect->effect = effect; + meffect->duration = duration; +} + +int +sp_armorshield(fighter * fi, int level, double power, spell * sp) +{ + int effect; + int duration; + battle *b = fi->side->battle; + message * m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp); + + message_all(b, m); + msg_release(m); + + /* gibt R�stung +effect f�r duration Treffer */ + + switch(sp->id) { + case SPL_ARMORSHIELD: + effect = level/3; + duration = (int)(20*power*power); + break; + + default: + effect = level/4; + duration = (int)(power*power); + } + do_meffect(fi, SHIELD_ARMOR, effect, duration); + return level; +} + +int +sp_reduceshield(fighter * fi, int level, double power, spell * sp) +{ + int effect; + int duration; + battle *b = fi->side->battle; + message * m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp); + message_all(b, m); + msg_release(m); + + /* jeder Schaden wird um effect% reduziert bis der Schild duration + * Trefferpunkte aufgefangen hat */ + + switch(sp->id) { + case SPL_REDUCESHIELD: + effect = 50; + duration = (int)(50*power*power); + break; + + default: + effect = level*3; + duration = (int)get_force(power,5); + } + do_meffect(fi, SHIELD_REDUCE, effect, duration); + return level; +} + +int +sp_fumbleshield(fighter * fi, int level, double power, spell * sp) +{ + int effect; + int duration; + battle *b = fi->side->battle; + message * m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp); + + message_all(b, m); + msg_release(m); + + /* der erste Zauber schl�gt mit 100% fehl */ + + switch(sp->id) { + case SPL_DRAIG_FUMBLESHIELD: + case SPL_GWYRRD_FUMBLESHIELD: + case SPL_CERRDOR_FUMBLESHIELD: + case SPL_TYBIED_FUMBLESHIELD: + duration = 100; + effect = MAX(1, 25-level); + break; + + default: + duration = 100; + effect = 10; + } + do_meffect(fi, SHIELD_BLOCK, effect, duration); + return level; +} + +/* ------------------------------------------------------------- */ +/* POSTCOMBAT */ + +static int +count_healable(battle *b, fighter *df) +{ + side *s; + int healable = 0; + + for (s=b->sides;s!=b->sides+b->nsides;++s) { + if (helping(df->side, s)) { + healable += s->casualties; + } + } + return healable; +} + +/* wiederbeleben */ +int +sp_reanimate(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + int healable, j=0; + double c = 0.50 + 0.02 * power; + double k = EFFECT_HEALING_SPELL * power; + boolean use_item = get_item(mage, I_AMULET_OF_HEALING) > 0; + message * msg; + + if (use_item) { + k *= 2; + c += 0.10; + } + + healable = count_healable(b, fi); + healable = (int)MIN(k, healable); + while (healable--) { + fighter * tf = select_corpse(b, fi); + if (tf!=NULL && tf->side->casualties > 0 + && tf->unit->race != new_race[RC_DAEMON] + && (chance(c))) + { + assert(tf->alive < tf->unit->number); + /* t.fighter->person[].hp beginnt mit t.index = 0 zu z�hlen, + * t.fighter->alive ist jedoch die Anzahl lebender in der Einheit, + * also sind die hp von t.fighter->alive + * t.fighter->hitpoints[t.fighter->alive-1] und der erste Tote + * oder weggelaufene ist t.fighter->hitpoints[tf->alive] */ + tf->person[tf->alive].hp = 2; + ++tf->alive; + ++tf->side->size[SUM_ROW]; + ++tf->side->size[tf->unit->status + 1]; + ++tf->side->healed; + --tf->side->casualties; + assert(tf->side->casualties>=0); + --tf->side->dead; + assert(tf->side->dead>=0); + ++j; + } + } + if (j <= 0) { + level = j; + } + if (use_item) { + msg = msg_message("reanimate_effect_1", "mage amount item", mage, j, oldresourcetype[R_AMULET_OF_HEALING]); + } else { + msg = msg_message("reanimate_effect_0", "mage amount", mage, j); + } + message_all(b, msg); + msg_release(msg); + + return level; +} + +int +sp_keeploot(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + message * m = msg_message("cast_spell_effect", "mage spell", fi->unit, sp); + + message_all(b, m); + msg_release(m); + + b->keeploot = (int)MAX(25, b->keeploot + 5*power); + + return level; +} + +static int +heal_fighters(cvector *fgs, int * power, boolean heal_monsters) +{ + int healhp = *power; + int healed = 0; + void **fig; + + for (fig = fgs->begin; fig != fgs->end; ++fig) { + fighter *df = *fig; + + if (healhp<=0) break; + + /* Untote kann man nicht heilen */ + if (df->unit->number==0 || fval(df->unit->race, RCF_NOHEAL)) continue; + + /* wir heilen erstmal keine Monster */ + if (heal_monsters || playerrace(df->unit->race)) { + int n, hp = df->unit->hp / df->unit->number; + int rest = df->unit->hp % df->unit->number; + + for (n = 0; n < df->unit->number; n++) { + int wound = hp - df->person[n].hp; + if (rest>n) ++wound; + + if (wound > 0 && wound < hp) { + int heal = MIN(healhp, wound); + assert(heal>=0); + df->person[n].hp += heal; + healhp = MAX(0, healhp - heal); + ++healed; + if (healhp<=0) break; + } + } + } + } + + *power = healhp; + return healed; +} + +int +sp_healing(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + int j = 0; + int healhp = (int)power * 200; + cvector *fgs; + message * msg; + boolean use_item = get_item(mage, I_AMULET_OF_HEALING) > 0; + + /* bis zu 11 Personen pro Stufe (einen HP m�ssen sie ja noch + * haben, sonst w�ren sie tot) k�nnen geheilt werden */ + + if (use_item) { + healhp *= 2; + } + + /* gehe alle denen wir helfen der reihe nach durch, heile verwundete, + * bis zu verteilende HP aufgebraucht sind */ + + fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_HELP); + v_scramble(fgs->begin, fgs->end); + j += heal_fighters(fgs, &healhp, false); + j += heal_fighters(fgs, &healhp, true); + cv_kill(fgs); + free(fgs); + + if (j <= 0) { + level = j; + } + if (use_item) { + msg = msg_message("healing_effect_1", "mage amount item", mage, j, oldresourcetype[R_AMULET_OF_HEALING]); + } else { + msg = msg_message("healing_effect_0", "mage amount", mage, j); + } + message_all(b, msg); + msg_release(msg); + + return level; +} + +int +sp_undeadhero(fighter * fi, int level, double power, spell * sp) +{ + battle *b = fi->side->battle; + unit *mage = fi->unit; + region *r = b->region; + cvector *fgs; + void **fig; + int n, undead = 0; + message * msg; + int force = (int)get_force(power,0); + double c = 0.50 + 0.02 * power; + + /* Liste aus allen K�mpfern */ + fgs = fighters(b, fi->side, FIGHT_ROW, AVOID_ROW, FS_ENEMY | FS_HELP ); + v_scramble(fgs->begin, fgs->end); + + for (fig = fgs->begin; fig != fgs->end; ++fig) { + fighter *df = *fig; + unit *du = df->unit; + + if (force<=0) break; + + /* keine Monster */ + if (!playerrace(du->race)) continue; + + if (df->alive + df->run.number < du->number) { + int j = 0; + + /* Wieviele Untote k�nnen wir aus dieser Einheit wecken? */ + for (n = df->alive + df->run.number; n != du->number; n++) { + if (chance(c)) { + ++j; + if (--force<=0) break; + } + } + + if (j > 0) { + unit * u = create_unit(r, mage->faction, 0, new_race[RC_UNDEAD], 0, du->name, du); + + /* new units gets some stats from old unit */ + + if (du->display) { + unit_setinfo(u, du->display); + } else { + unit_setinfo(u, NULL); + } + setstatus(u, du->status); + setguard(u, GUARD_NONE); + + /* inherit stealth from magician */ + if (fval(mage, UFL_ANON_FACTION)) { + fset(u, UFL_ANON_FACTION); + } + + /* transfer dead people to new unit, set hitpoints to those of old unit */ + transfermen(du, u, j); + u->hp = u->number * unit_max_hp(du); + assert(j<=df->side->casualties); + df->side->casualties -= j; + df->side->dead -= j; + + /* counting total number of undead */ + undead += j; + } + } + } + cv_kill(fgs); + free(fgs); + + level = MIN(level, undead); + if (undead == 0) { + msg = msg_message("summonundead_effect_0", "mage region", mage, mage->region); + } else { + msg = msg_message("summonundead_effect_1", "mage region amount", mage, mage->region, undead); + } + + message_all(b, msg); + msg_release(msg); + return level; +} diff --git a/src/spells/combatspells.h b/src/spells/combatspells.h index cfda537bb..75f9e3554 100644 --- a/src/spells/combatspells.h +++ b/src/spells/combatspells.h @@ -1,57 +1,57 @@ -/* vi: set ts=2: - +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de> - | | Enno Rehling <enno@eressea.de> - | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de> - | (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de> - | | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de> - +-------------------+ Stefan Reich <reich@halbling.de> - - This program may not be used, modified or distributed - without prior permission by the authors of Eressea. -*/ - -#ifndef H_GC_COMBATSPELLS -#define H_GC_COMBATSPELLS - -#ifdef __cplusplus -extern "C" { -#endif - - struct fighter; - - /* Kampfzauber */ - extern int sp_fumbleshield(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_shadowknights(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_combatrosthauch(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_kampfzauber(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_healing(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_keeploot(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_reanimate(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_chaosrow(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_flee(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_berserk(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_tiredsoldiers(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_reeling_arrows(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_denyattack(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_sleep(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_windshield(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_strong_wall(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_petrify(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_hero(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_frighten(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_mindblast(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_mindblast_temp(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_speed(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_wolfhowl(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_dragonodem(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_reduceshield(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_armorshield(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_stun(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_undeadhero(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_shadowcall(struct fighter * fi, int level, double power, struct spell * sp); - extern int sp_immolation(struct fighter * fi, int level, double power, struct spell * sp); - -#ifdef __cplusplus -} -#endif -#endif +/* vi: set ts=2: + +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de> + | | Enno Rehling <enno@eressea.de> + | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de> + | (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de> + | | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de> + +-------------------+ Stefan Reich <reich@halbling.de> + + This program may not be used, modified or distributed + without prior permission by the authors of Eressea. +*/ + +#ifndef H_GC_COMBATSPELLS +#define H_GC_COMBATSPELLS + +#ifdef __cplusplus +extern "C" { +#endif + + struct fighter; + + /* Kampfzauber */ + extern int sp_fumbleshield(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_shadowknights(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_combatrosthauch(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_kampfzauber(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_healing(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_keeploot(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_reanimate(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_chaosrow(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_flee(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_berserk(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_tiredsoldiers(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_reeling_arrows(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_denyattack(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_sleep(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_windshield(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_strong_wall(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_petrify(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_hero(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_frighten(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_mindblast(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_mindblast_temp(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_speed(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_wolfhowl(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_dragonodem(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_reduceshield(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_armorshield(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_stun(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_undeadhero(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_shadowcall(struct fighter * fi, int level, double power, struct spell * sp); + extern int sp_immolation(struct fighter * fi, int level, double power, struct spell * sp); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/spells/regioncurse.c b/src/spells/regioncurse.c index 93d082580..4fe2dc2a9 100644 --- a/src/spells/regioncurse.c +++ b/src/spells/regioncurse.c @@ -1,296 +1,296 @@ -/* vi: set ts=2: - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#include <platform.h> -#include <kernel/config.h> -#include "regioncurse.h" - -/* kernel includes */ -#include <kernel/curse.h> -#include <kernel/magic.h> -#include <kernel/message.h> -#include <kernel/objtypes.h> -#include <kernel/region.h> -#include <kernel/terrain.h> -#include <kernel/unit.h> - -/* util includes */ -#include <util/nrmessage.h> -#include <util/message.h> -#include <util/functions.h> - -/* libc includes */ -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -/* --------------------------------------------------------------------- */ -/* CurseInfo mit Spezialabfragen - */ - -/* - * godcursezone - */ -static message * -cinfo_cursed_by_the_gods(const void * obj, typ_t typ, const curse *c, int self) -{ - region *r = (region *)obj; - - unused(typ); - unused(self); - assert(typ == TYP_REGION); - - if (fval(r->terrain, SEA_REGION)) { - return msg_message("curseinfo::godcurseocean", "id", c->no); - } - return msg_message("curseinfo::godcurse", "id", c->no); -} - -static struct curse_type ct_godcursezone = { - "godcursezone", - CURSETYP_NORM, CURSE_IMMUNE|CURSE_ISNEW, (NO_MERGE), cinfo_cursed_by_the_gods, -}; - - -/* --------------------------------------------------------------------- */ -/* - * C_GBDREAM - */ -static message * -cinfo_dreamcurse(const void * obj, typ_t typ, const curse *c, int self) -{ - unused(self); - unused(typ); - unused(obj); - assert(typ == TYP_REGION); - - if (curse_geteffect(c) > 0) { - return msg_message("curseinfo::gooddream", "id", c->no); - } - return msg_message("curseinfo::baddream", "id", c->no); -} - -static struct curse_type ct_gbdream = { - "gbdream", - CURSETYP_NORM, CURSE_ISNEW, (NO_MERGE), cinfo_dreamcurse -}; - -/* --------------------------------------------------------------------- */ -/* - * C_MAGICSTREET - * erzeugt Stra�ennetz - */ -static message * -cinfo_magicstreet(const void * obj, typ_t typ, const curse *c, int self) -{ - unused(typ); - unused(self); - unused(obj); - assert(typ == TYP_REGION); - - /* Warnung vor Aufl�sung */ - if (c->duration <= 2) { - return msg_message("curseinfo::magicstreet", "id", c->no); - } - return msg_message("curseinfo::magicstreetwarn", "id", c->no); -} - -static struct curse_type ct_magicstreet = { - "magicstreet", - CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), - cinfo_magicstreet -}; - -/* --------------------------------------------------------------------- */ - -static message * -cinfo_antimagiczone(const void * obj, typ_t typ, const curse *c, int self) -{ - unused(typ); - unused(self); - unused(obj); - assert(typ == TYP_REGION); - - /* Magier sp�ren eine Antimagiezone */ - if (self != 0) { - return msg_message("curseinfo::antimagiczone", "id", c->no); - } - - return NULL; -} - -/* alle Magier k�nnen eine Antimagiezone wahrnehmen */ -static int -cansee_antimagiczone(const struct faction *viewer, const void * obj, typ_t typ, const curse *c, int self) -{ - region *r; - unit *u = NULL; - unit *mage = c->magician; - - unused(typ); - - assert(typ == TYP_REGION); - r = (region *)obj; - for (u = r->units; u; u = u->next) { - if (u->faction==viewer) { - if (u==mage) { - self = 2; - break; - } - if (is_mage(u)) { - self = 1; - } - } - } - return self; -} -static struct curse_type ct_antimagiczone = { - "antimagiczone", - CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), - cinfo_antimagiczone, NULL, NULL, NULL, cansee_antimagiczone -}; - -/* --------------------------------------------------------------------- */ -static message * -cinfo_farvision(const void * obj, typ_t typ, const curse *c, int self) -{ - unused(typ); - unused(obj); - - assert(typ == TYP_REGION); - - /* Magier sp�ren eine farvision */ - if (self != 0) { - return msg_message("curseinfo::farvision", "id", c->no); - } - - return 0; -} - -static struct curse_type ct_farvision = { - "farvision", - CURSETYP_NORM, 0, (NO_MERGE), - cinfo_farvision -}; - - -/* --------------------------------------------------------------------- */ - -static struct curse_type ct_fogtrap = { - "fogtrap", - CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), - cinfo_simple -}; -static struct curse_type ct_maelstrom = { - "maelstrom", - CURSETYP_NORM, CURSE_ISNEW, (M_DURATION | M_VIGOUR), - cinfo_simple -}; - -static struct curse_type ct_blessedharvest = { - "blessedharvest", - CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), - cinfo_simple -}; - -static struct curse_type ct_drought = { - "drought", - CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), - cinfo_simple -}; -static struct curse_type ct_badlearn = { - "badlearn", - CURSETYP_NORM, CURSE_ISNEW, ( M_DURATION | M_VIGOUR ), - cinfo_simple -}; -/* Tr�bsal-Zauber */ -static struct curse_type ct_depression = { - "depression", - CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), - cinfo_simple -}; - -/* Astralblock, auf Astralregion */ -static struct curse_type ct_astralblock = { - "astralblock", - CURSETYP_NORM, 0, NO_MERGE, - cinfo_simple -}; -/* Unterhaltungsanteil vermehren */ -static struct curse_type ct_generous = { - "generous", - CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR | M_MAXEFFECT ), - cinfo_simple -}; -/* verhindert Attackiere regional */ -static struct curse_type ct_peacezone = { - "peacezone", - CURSETYP_NORM, 0, NO_MERGE, - cinfo_simple -}; -/* erniedigt Magieresistenz von nicht-aliierten Einheiten, wirkt nur 1x -* pro Einheit */ -static struct curse_type ct_badmagicresistancezone = { - "badmagicresistancezone", - CURSETYP_NORM, 0, NO_MERGE, - cinfo_simple -}; -/* erh�ht Magieresistenz von aliierten Einheiten, wirkt nur 1x pro -* Einheit */ -static struct curse_type ct_goodmagicresistancezone = { - "goodmagicresistancezone", - CURSETYP_NORM, 0, NO_MERGE, - cinfo_simple -}; -static struct curse_type ct_riotzone = { - "riotzone", - CURSETYP_NORM, 0, (M_DURATION), - cinfo_simple -}; -static struct curse_type ct_holyground = { - "holyground", - CURSETYP_NORM, CURSE_NOAGE, (M_VIGOUR_ADD), - cinfo_simple -}; -static struct curse_type ct_healing = { - "healingzone", - CURSETYP_NORM, 0, (M_VIGOUR | M_DURATION), - cinfo_simple -}; - - -void -register_regioncurse(void) -{ - ct_register(&ct_fogtrap); - ct_register(&ct_antimagiczone); - ct_register(&ct_farvision); - ct_register(&ct_gbdream); - ct_register(&ct_maelstrom); - ct_register(&ct_blessedharvest); - ct_register(&ct_drought); - ct_register(&ct_badlearn); - ct_register(&ct_depression); - ct_register(&ct_astralblock); - ct_register(&ct_generous); - ct_register(&ct_peacezone); - ct_register(&ct_magicstreet); - ct_register(&ct_badmagicresistancezone); - ct_register(&ct_goodmagicresistancezone); - ct_register(&ct_riotzone); - ct_register(&ct_godcursezone); - ct_register(&ct_holyground); - ct_register(&ct_healing); -} - - +/* vi: set ts=2: + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#include <platform.h> +#include <kernel/config.h> +#include "regioncurse.h" + +/* kernel includes */ +#include <kernel/curse.h> +#include <kernel/magic.h> +#include <kernel/message.h> +#include <kernel/objtypes.h> +#include <kernel/region.h> +#include <kernel/terrain.h> +#include <kernel/unit.h> + +/* util includes */ +#include <util/nrmessage.h> +#include <util/message.h> +#include <util/functions.h> + +/* libc includes */ +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +/* --------------------------------------------------------------------- */ +/* CurseInfo mit Spezialabfragen + */ + +/* + * godcursezone + */ +static message * +cinfo_cursed_by_the_gods(const void * obj, typ_t typ, const curse *c, int self) +{ + region *r = (region *)obj; + + unused(typ); + unused(self); + assert(typ == TYP_REGION); + + if (fval(r->terrain, SEA_REGION)) { + return msg_message("curseinfo::godcurseocean", "id", c->no); + } + return msg_message("curseinfo::godcurse", "id", c->no); +} + +static struct curse_type ct_godcursezone = { + "godcursezone", + CURSETYP_NORM, CURSE_IMMUNE|CURSE_ISNEW, (NO_MERGE), cinfo_cursed_by_the_gods, +}; + + +/* --------------------------------------------------------------------- */ +/* + * C_GBDREAM + */ +static message * +cinfo_dreamcurse(const void * obj, typ_t typ, const curse *c, int self) +{ + unused(self); + unused(typ); + unused(obj); + assert(typ == TYP_REGION); + + if (curse_geteffect(c) > 0) { + return msg_message("curseinfo::gooddream", "id", c->no); + } + return msg_message("curseinfo::baddream", "id", c->no); +} + +static struct curse_type ct_gbdream = { + "gbdream", + CURSETYP_NORM, CURSE_ISNEW, (NO_MERGE), cinfo_dreamcurse +}; + +/* --------------------------------------------------------------------- */ +/* + * C_MAGICSTREET + * erzeugt Stra�ennetz + */ +static message * +cinfo_magicstreet(const void * obj, typ_t typ, const curse *c, int self) +{ + unused(typ); + unused(self); + unused(obj); + assert(typ == TYP_REGION); + + /* Warnung vor Aufl�sung */ + if (c->duration <= 2) { + return msg_message("curseinfo::magicstreet", "id", c->no); + } + return msg_message("curseinfo::magicstreetwarn", "id", c->no); +} + +static struct curse_type ct_magicstreet = { + "magicstreet", + CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), + cinfo_magicstreet +}; + +/* --------------------------------------------------------------------- */ + +static message * +cinfo_antimagiczone(const void * obj, typ_t typ, const curse *c, int self) +{ + unused(typ); + unused(self); + unused(obj); + assert(typ == TYP_REGION); + + /* Magier sp�ren eine Antimagiezone */ + if (self != 0) { + return msg_message("curseinfo::antimagiczone", "id", c->no); + } + + return NULL; +} + +/* alle Magier k�nnen eine Antimagiezone wahrnehmen */ +static int +cansee_antimagiczone(const struct faction *viewer, const void * obj, typ_t typ, const curse *c, int self) +{ + region *r; + unit *u = NULL; + unit *mage = c->magician; + + unused(typ); + + assert(typ == TYP_REGION); + r = (region *)obj; + for (u = r->units; u; u = u->next) { + if (u->faction==viewer) { + if (u==mage) { + self = 2; + break; + } + if (is_mage(u)) { + self = 1; + } + } + } + return self; +} +static struct curse_type ct_antimagiczone = { + "antimagiczone", + CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), + cinfo_antimagiczone, NULL, NULL, NULL, cansee_antimagiczone +}; + +/* --------------------------------------------------------------------- */ +static message * +cinfo_farvision(const void * obj, typ_t typ, const curse *c, int self) +{ + unused(typ); + unused(obj); + + assert(typ == TYP_REGION); + + /* Magier sp�ren eine farvision */ + if (self != 0) { + return msg_message("curseinfo::farvision", "id", c->no); + } + + return 0; +} + +static struct curse_type ct_farvision = { + "farvision", + CURSETYP_NORM, 0, (NO_MERGE), + cinfo_farvision +}; + + +/* --------------------------------------------------------------------- */ + +static struct curse_type ct_fogtrap = { + "fogtrap", + CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), + cinfo_simple +}; +static struct curse_type ct_maelstrom = { + "maelstrom", + CURSETYP_NORM, CURSE_ISNEW, (M_DURATION | M_VIGOUR), + cinfo_simple +}; + +static struct curse_type ct_blessedharvest = { + "blessedharvest", + CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), + cinfo_simple +}; + +static struct curse_type ct_drought = { + "drought", + CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), + cinfo_simple +}; +static struct curse_type ct_badlearn = { + "badlearn", + CURSETYP_NORM, CURSE_ISNEW, ( M_DURATION | M_VIGOUR ), + cinfo_simple +}; +/* Tr�bsal-Zauber */ +static struct curse_type ct_depression = { + "depression", + CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), + cinfo_simple +}; + +/* Astralblock, auf Astralregion */ +static struct curse_type ct_astralblock = { + "astralblock", + CURSETYP_NORM, 0, NO_MERGE, + cinfo_simple +}; +/* Unterhaltungsanteil vermehren */ +static struct curse_type ct_generous = { + "generous", + CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR | M_MAXEFFECT ), + cinfo_simple +}; +/* verhindert Attackiere regional */ +static struct curse_type ct_peacezone = { + "peacezone", + CURSETYP_NORM, 0, NO_MERGE, + cinfo_simple +}; +/* erniedigt Magieresistenz von nicht-aliierten Einheiten, wirkt nur 1x +* pro Einheit */ +static struct curse_type ct_badmagicresistancezone = { + "badmagicresistancezone", + CURSETYP_NORM, 0, NO_MERGE, + cinfo_simple +}; +/* erh�ht Magieresistenz von aliierten Einheiten, wirkt nur 1x pro +* Einheit */ +static struct curse_type ct_goodmagicresistancezone = { + "goodmagicresistancezone", + CURSETYP_NORM, 0, NO_MERGE, + cinfo_simple +}; +static struct curse_type ct_riotzone = { + "riotzone", + CURSETYP_NORM, 0, (M_DURATION), + cinfo_simple +}; +static struct curse_type ct_holyground = { + "holyground", + CURSETYP_NORM, CURSE_NOAGE, (M_VIGOUR_ADD), + cinfo_simple +}; +static struct curse_type ct_healing = { + "healingzone", + CURSETYP_NORM, 0, (M_VIGOUR | M_DURATION), + cinfo_simple +}; + + +void +register_regioncurse(void) +{ + ct_register(&ct_fogtrap); + ct_register(&ct_antimagiczone); + ct_register(&ct_farvision); + ct_register(&ct_gbdream); + ct_register(&ct_maelstrom); + ct_register(&ct_blessedharvest); + ct_register(&ct_drought); + ct_register(&ct_badlearn); + ct_register(&ct_depression); + ct_register(&ct_astralblock); + ct_register(&ct_generous); + ct_register(&ct_peacezone); + ct_register(&ct_magicstreet); + ct_register(&ct_badmagicresistancezone); + ct_register(&ct_goodmagicresistancezone); + ct_register(&ct_riotzone); + ct_register(&ct_godcursezone); + ct_register(&ct_holyground); + ct_register(&ct_healing); +} + + diff --git a/src/spells/regioncurse.h b/src/spells/regioncurse.h index 16d4a4adc..25e3c1de8 100644 --- a/src/spells/regioncurse.h +++ b/src/spells/regioncurse.h @@ -1,28 +1,28 @@ -/* vi: set ts=2: - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#ifndef _RCURSE_H -#define _RCURSE_H -#ifdef __cplusplus -extern "C" { -#endif - -struct curse; -struct locale; - -extern void register_regioncurse(void); - -#ifdef __cplusplus -} -#endif -#endif /* _RCURSE_H */ +/* vi: set ts=2: + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#ifndef _RCURSE_H +#define _RCURSE_H +#ifdef __cplusplus +extern "C" { +#endif + +struct curse; +struct locale; + +extern void register_regioncurse(void); + +#ifdef __cplusplus +} +#endif +#endif /* _RCURSE_H */ diff --git a/src/spells/shipcurse.c b/src/spells/shipcurse.c index 1b6385d3a..0a4376cc1 100644 --- a/src/spells/shipcurse.c +++ b/src/spells/shipcurse.c @@ -1,156 +1,156 @@ -/* vi: set ts=2: - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#include <platform.h> -#include <kernel/config.h> -#include <kernel/version.h> -#include "shipcurse.h" - -/* kernel includes */ -#include <kernel/message.h> -#include <kernel/objtypes.h> -#include <kernel/ship.h> -#include <kernel/unit.h> -#include <kernel/curse.h> - -/* util includes */ -#include <util/base36.h> -#include <util/functions.h> -#include <util/language.h> -#include <util/log.h> - -/* libc includes */ -#include <string.h> -#include <stdlib.h> -#include <assert.h> - - -message * -cinfo_ship(const void * obj, typ_t typ, const curse *c, int self) -{ - message * msg; - - unused(typ); - unused(obj); - assert(typ == TYP_SHIP); - - if (self != 0) { /* owner or inside */ - msg = msg_message(mkname("curseinfo", c->type->cname), "id", c->no); - } else { - msg = msg_message("curseinfo::ship_unknown", "id", c->no); - } - if (msg==NULL) { - log_error(("There is no curseinfo for %s.\n", c->type->cname)); - } - return msg; -} - -/* CurseInfo mit Spezialabfragen */ - -/* C_SHIP_NODRIFT */ -static message * -cinfo_shipnodrift(const void * obj, typ_t typ, const curse *c, int self) -{ - ship * sh = (ship *)obj; - - unused(typ); - assert(typ == TYP_SHIP); - - if (self != 0) { - return msg_message("curseinfo::shipnodrift_1", "ship duration id", sh, c->duration, c->no); - } - return msg_message("curseinfo::shipnodrift_0", "ship id", sh, c->no); -} - -static struct curse_type ct_stormwind = { "stormwind", - CURSETYP_NORM, 0, NO_MERGE, cinfo_ship -}; - -static int flyingship_read(storage * store, curse * c, void * target) { - ship * sh = (ship *)target; - c->data.v = sh; - if (store->version<FOSS_VERSION) { - sh->flags |= SF_FLYING; - return 0; - } - assert(sh->flags&SF_FLYING); - return 0; -} - -static int flyingship_write(storage * store, const curse * c, const void * target) { - const ship * sh = (const ship *)target; - assert(sh->flags&SF_FLYING); - return 0; -} - -static int flyingship_age(curse * c) { - ship * sh = (ship *)c->data.v; - if (sh && c->duration==1) { - freset(sh, SF_FLYING); - return 1; - } - return 0; -} - -static struct curse_type ct_flyingship = { "flyingship", - CURSETYP_NORM, 0, NO_MERGE, cinfo_ship, NULL, flyingship_read, flyingship_write, NULL, flyingship_age -}; -static struct curse_type ct_nodrift = { "nodrift", - CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), cinfo_shipnodrift -}; -static struct curse_type ct_shipspeedup = { "shipspeedup", - CURSETYP_NORM, 0, 0, cinfo_ship -}; - -curse * -shipcurse_flyingship(ship* sh, unit * mage, double power, int duration) -{ - static const curse_type * ct_flyingship = NULL; - if (!ct_flyingship) { - ct_flyingship = ct_find("flyingship"); - assert(ct_flyingship); - } - if (curse_active(get_curse(sh->attribs, ct_flyingship))) { - return NULL; - } else if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0)) { - return NULL; - } else { - /* mit C_SHIP_NODRIFT haben wir kein Problem */ - curse * c = create_curse(mage, &sh->attribs, ct_flyingship, power, duration, 0.0, 0); - c->data.v = sh; - if (c && c->duration>0) { - sh->flags |= SF_FLYING; - } - return c; - } -} - -int -levitate_ship(ship * sh, unit * mage, double power, int duration) -{ - curse * c = shipcurse_flyingship(sh, mage, power, duration); - if (c) { - return c->no; - } - return 0; -} - -void -register_shipcurse(void) -{ - ct_register(&ct_stormwind); - ct_register(&ct_flyingship); - ct_register(&ct_nodrift); - ct_register(&ct_shipspeedup); -} - +/* vi: set ts=2: + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#include <platform.h> +#include <kernel/config.h> +#include <kernel/version.h> +#include "shipcurse.h" + +/* kernel includes */ +#include <kernel/message.h> +#include <kernel/objtypes.h> +#include <kernel/ship.h> +#include <kernel/unit.h> +#include <kernel/curse.h> + +/* util includes */ +#include <util/base36.h> +#include <util/functions.h> +#include <util/language.h> +#include <util/log.h> + +/* libc includes */ +#include <string.h> +#include <stdlib.h> +#include <assert.h> + + +message * +cinfo_ship(const void * obj, typ_t typ, const curse *c, int self) +{ + message * msg; + + unused(typ); + unused(obj); + assert(typ == TYP_SHIP); + + if (self != 0) { /* owner or inside */ + msg = msg_message(mkname("curseinfo", c->type->cname), "id", c->no); + } else { + msg = msg_message("curseinfo::ship_unknown", "id", c->no); + } + if (msg==NULL) { + log_error(("There is no curseinfo for %s.\n", c->type->cname)); + } + return msg; +} + +/* CurseInfo mit Spezialabfragen */ + +/* C_SHIP_NODRIFT */ +static message * +cinfo_shipnodrift(const void * obj, typ_t typ, const curse *c, int self) +{ + ship * sh = (ship *)obj; + + unused(typ); + assert(typ == TYP_SHIP); + + if (self != 0) { + return msg_message("curseinfo::shipnodrift_1", "ship duration id", sh, c->duration, c->no); + } + return msg_message("curseinfo::shipnodrift_0", "ship id", sh, c->no); +} + +static struct curse_type ct_stormwind = { "stormwind", + CURSETYP_NORM, 0, NO_MERGE, cinfo_ship +}; + +static int flyingship_read(storage * store, curse * c, void * target) { + ship * sh = (ship *)target; + c->data.v = sh; + if (store->version<FOSS_VERSION) { + sh->flags |= SF_FLYING; + return 0; + } + assert(sh->flags&SF_FLYING); + return 0; +} + +static int flyingship_write(storage * store, const curse * c, const void * target) { + const ship * sh = (const ship *)target; + assert(sh->flags&SF_FLYING); + return 0; +} + +static int flyingship_age(curse * c) { + ship * sh = (ship *)c->data.v; + if (sh && c->duration==1) { + freset(sh, SF_FLYING); + return 1; + } + return 0; +} + +static struct curse_type ct_flyingship = { "flyingship", + CURSETYP_NORM, 0, NO_MERGE, cinfo_ship, NULL, flyingship_read, flyingship_write, NULL, flyingship_age +}; +static struct curse_type ct_nodrift = { "nodrift", + CURSETYP_NORM, 0, ( M_DURATION | M_VIGOUR ), cinfo_shipnodrift +}; +static struct curse_type ct_shipspeedup = { "shipspeedup", + CURSETYP_NORM, 0, 0, cinfo_ship +}; + +curse * +shipcurse_flyingship(ship* sh, unit * mage, double power, int duration) +{ + static const curse_type * ct_flyingship = NULL; + if (!ct_flyingship) { + ct_flyingship = ct_find("flyingship"); + assert(ct_flyingship); + } + if (curse_active(get_curse(sh->attribs, ct_flyingship))) { + return NULL; + } else if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0)) { + return NULL; + } else { + /* mit C_SHIP_NODRIFT haben wir kein Problem */ + curse * c = create_curse(mage, &sh->attribs, ct_flyingship, power, duration, 0.0, 0); + c->data.v = sh; + if (c && c->duration>0) { + sh->flags |= SF_FLYING; + } + return c; + } +} + +int +levitate_ship(ship * sh, unit * mage, double power, int duration) +{ + curse * c = shipcurse_flyingship(sh, mage, power, duration); + if (c) { + return c->no; + } + return 0; +} + +void +register_shipcurse(void) +{ + ct_register(&ct_stormwind); + ct_register(&ct_flyingship); + ct_register(&ct_nodrift); + ct_register(&ct_shipspeedup); +} + diff --git a/src/spells/shipcurse.h b/src/spells/shipcurse.h index d074dad4e..3df41bb5d 100644 --- a/src/spells/shipcurse.h +++ b/src/spells/shipcurse.h @@ -1,30 +1,30 @@ -/* vi: set ts=2: - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#ifndef _SCURSE_H -#define _SCURSE_H -#ifdef __cplusplus -extern "C" { -#endif - -struct locale; -struct message; -extern struct message * cinfo_ship(const void * obj, typ_t typ, const struct curse *c, int self); -extern void register_shipcurse(void); -extern struct curse * shipcurse_flyingship(struct ship* sh, struct unit * mage, double power, int duration); -int levitate_ship(struct ship * sh, struct unit * mage, double power, int duration); - -#ifdef __cplusplus -} -#endif -#endif /* _SCURSE_H */ +/* vi: set ts=2: + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#ifndef _SCURSE_H +#define _SCURSE_H +#ifdef __cplusplus +extern "C" { +#endif + +struct locale; +struct message; +extern struct message * cinfo_ship(const void * obj, typ_t typ, const struct curse *c, int self); +extern void register_shipcurse(void); +extern struct curse * shipcurse_flyingship(struct ship* sh, struct unit * mage, double power, int duration); +int levitate_ship(struct ship * sh, struct unit * mage, double power, int duration); + +#ifdef __cplusplus +} +#endif +#endif /* _SCURSE_H */ diff --git a/src/spells/spells.c b/src/spells/spells.c index 783ab9c1c..6e6522355 100644 --- a/src/spells/spells.c +++ b/src/spells/spells.c @@ -1,7251 +1,7251 @@ -/* vi: set ts=2: - * - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#include <platform.h> -#include <kernel/config.h> -#include "spells.h" - -#include "buildingcurse.h" -#include "regioncurse.h" -#include "unitcurse.h" -#include "shipcurse.h" - -/* kernel includes */ -#include <kernel/curse.h> -#include <kernel/battle.h> /* f�r lovar */ -#include <kernel/connection.h> -#include <kernel/building.h> -#include <kernel/curse.h> -#include <kernel/spellid.h> -#include <kernel/faction.h> -#include <kernel/reports.h> -#include <kernel/item.h> -#include <kernel/magic.h> -#include <kernel/message.h> -#include <kernel/objtypes.h> -#include <kernel/order.h> -#include <kernel/plane.h> -#include <kernel/pool.h> -#include <kernel/race.h> -#include <kernel/region.h> -#include <kernel/save.h> -#include <kernel/ship.h> -#include <kernel/skill.h> -#include <kernel/spell.h> -#include <kernel/teleport.h> -#include <kernel/terrain.h> -#include <kernel/terrainid.h> -#include <kernel/unit.h> -#include <kernel/xmlreader.h> -#include <kernel/version.h> - -#include <gamecode/spy.h> - -/* spells includes */ -#include "alp.h" - -/* util includes */ -#include <util/attrib.h> -#include <util/base36.h> -#include <util/event.h> -#include <util/language.h> -#include <util/message.h> -#include <util/parser.h> -#include <util/umlaut.h> -#include <util/functions.h> -#include <util/lists.h> -#include <util/rand.h> -#include <util/log.h> -#include <util/nrmessage.h> -#include <util/bsdstring.h> -#include <util/variant.h> -#include <util/goodies.h> -#include <util/resolve.h> -#include <util/rng.h> -#include <util/storage.h> - -/* libc includes */ -#include <assert.h> -#include <ctype.h> -#include <math.h> -#include <stdio.h> -#include <string.h> -#include <limits.h> - -/* triggers includes */ -#include <triggers/changefaction.h> -#include <triggers/changerace.h> -#include <triggers/createcurse.h> -#include <triggers/createunit.h> -#include <triggers/killunit.h> -#include <triggers/timeout.h> -#include <triggers/unitmessage.h> - -/* attributes includes */ -#include <attributes/targetregion.h> -#include <attributes/hate.h> -/* ----------------------------------------------------------------------- */ - -static double zero_effect = 0.0; - -attrib_type at_wdwpyramid = { - "wdwpyramid", NULL, NULL, NULL, a_writevoid, a_readvoid -}; - -/* ----------------------------------------------------------------------- */ - -static void -report_spell(unit * mage, region * r, message * msg) -{ - r_addmessage(r, NULL, msg); - if (mage && mage->region!=r) { - add_message(&mage->faction->msgs, msg); - } -} - -static void -report_failure(unit * mage, struct order * ord) { - /* Fehler: "Der Zauber schl�gt fehl" */ - cmistake(mage, ord, 180, MSG_MAGIC); -} - -/* ------------------------------------------------------------- */ -/* Spruchanalyse - Ausgabe von curse->info und curse->name */ -/* ------------------------------------------------------------- */ - -static double -curse_chance(const struct curse * c, double force) -{ - return 1.0 + (force - c->vigour) * 0.1; -} - -static void -magicanalyse_region(region *r, unit *mage, double force) -{ - attrib *a; - boolean found = false; - - for (a=r->attribs;a;a=a->next) { - curse * c = (curse*)a->data.v; - double probability; - int mon; - - if (!fval(a->type, ATF_CURSE)) continue; - - /* ist der curse schw�cher als der Analysezauber, so ergibt sich - * mehr als 100% probability und damit immer ein Erfolg. */ - probability = curse_chance(c, force); - mon = c->duration + (rng_int()%10) - 5; - mon = MAX(1, mon); - found = true; - - if (chance(probability)) { /* Analyse gegl�ckt */ - if (c_flags(c) & CURSE_NOAGE) { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_region_noage", "mage region curse", - mage, r, c->type)); - } else { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_region_age", "mage region curse months", - mage, r, c->type, mon)); - } - } else { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_region_fail", "mage region", mage, r)); - } - } - if (!found) { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_region_nospell", "mage region", mage, r)); - } -} - -static void -magicanalyse_unit(unit *u, unit *mage, double force) -{ - attrib *a; - boolean found = false; - - for (a=u->attribs;a;a=a->next) { - curse * c; - double probability; - int mon; - if (!fval(a->type, ATF_CURSE)) continue; - - c = (curse*)a->data.v; - /* ist der curse schw�cher als der Analysezauber, so ergibt sich - * mehr als 100% probability und damit immer ein Erfolg. */ - probability = curse_chance(c, force); - mon = c->duration + (rng_int()%10) - 5; - mon = MAX(1,mon); - - if (chance(probability)) { /* Analyse gegl�ckt */ - if (c_flags(c) & CURSE_NOAGE) { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_unit_noage", "mage unit curse", - mage, u, c->type)); - }else{ - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_unit_age", "mage unit curse months", - mage, u, c->type, mon)); - } - } else { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_unit_fail", "mage unit", mage, u)); - } - } - if (!found) { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_unit_nospell", "mage target", mage, u)); - } -} - -static void -magicanalyse_building(building *b, unit *mage, double force) -{ - attrib *a; - boolean found = false; - - for (a=b->attribs;a;a=a->next) { - curse * c; - double probability; - int mon; - - if (!fval(a->type, ATF_CURSE)) continue; - - c = (curse*)a->data.v; - /* ist der curse schw�cher als der Analysezauber, so ergibt sich - * mehr als 100% probability und damit immer ein Erfolg. */ - probability = curse_chance(c, force); - mon = c->duration + (rng_int()%10) - 5; - mon = MAX(1,mon); - - if (chance(probability)) { /* Analyse gegl�ckt */ - if (c_flags(c) & CURSE_NOAGE) { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_building_age", "mage building curse", - mage, b, c->type)); - }else{ - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_building_age", "mage building curse months", - mage, b, c->type, mon)); - } - } else { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_building_fail", "mage building", mage, b)); - } - } - if (!found) { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_building_nospell", "mage building", mage, b)); - } - -} - -static void -magicanalyse_ship(ship *sh, unit *mage, double force) -{ - attrib *a; - boolean found = false; - - for (a=sh->attribs;a;a=a->next) { - curse * c; - double probability; - int mon; - if (!fval(a->type, ATF_CURSE)) continue; - - c = (curse*)a->data.v; - /* ist der curse schw�cher als der Analysezauber, so ergibt sich - * mehr als 100% probability und damit immer ein Erfolg. */ - probability = curse_chance(c, force); - mon = c->duration + (rng_int()%10) - 5; - mon = MAX(1,mon); - - if (chance(probability)) { /* Analyse gegl�ckt */ - if (c_flags(c) & CURSE_NOAGE) { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_ship_noage", "mage ship curse", - mage, sh, c->type)); - }else{ - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_ship_age", "mage ship curse months", - mage, sh, c->type, mon)); - } - } else { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_ship_fail", "mage ship", mage, sh)); - - } - } - if (!found) { - ADDMSG(&mage->faction->msgs, msg_message( - "analyse_ship_nospell", "mage ship", mage, sh)); - } - -} - -int -break_curse(attrib **alist, int cast_level, double force, curse * c) -{ - int succ = 0; -/* attrib **a = a_find(*ap, &at_curse); */ - attrib ** ap = alist; - - while (*ap && force > 0) { - curse * c1; - attrib * a = *ap; - if (!fval(a->type, ATF_CURSE)) { - do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type); - continue; - } - c1 = (curse*)a->data.v; - - /* Immunit�t pr�fen */ - if (c_flags(c1) & CURSE_IMMUNE) { - do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type); - continue; - } - - /* Wenn kein spezieller cursetyp angegeben ist, soll die Antimagie - * auf alle Verzauberungen wirken. Ansonsten pr�fe, ob der Curse vom - * richtigen Typ ist. */ - if (!c || c==c1) { - double remain = destr_curse(c1, cast_level, force); - if (remain < force) { - succ = cast_level; - force = remain; - } - if (c1->vigour <= 0) { - a_remove(alist, a); - } - } - if (*ap==a) ap = &a->next; - } - return succ; -} - -/* ------------------------------------------------------------- */ -/* Report a spell's effect to the units in the region. -*/ - -static void -report_effect(region * r, unit * mage, message * seen, message * unseen) -{ -#if 0 - unit * u; - - /* melden, 1x pro Partei */ - freset(mage->faction, FFL_SELECT); - for (u = r->units; u; u = u->next ) freset(u->faction, FFL_SELECT); - for (u = r->units; u; u = u->next ) { - if (!fval(u->faction, FFL_SELECT) ) { - fset(u->faction, FFL_SELECT); - - /* Bei Fernzaubern sieht nur die eigene Partei den Magier */ - if (u->faction != mage->faction) { - if (r == mage->region) { - /* kein Fernzauber, pr�fe, ob der Magier �berhaupt gesehen - * wird */ - if (cansee(u->faction, r, mage, 0)) { - r_addmessage(r, u->faction, seen); - } else { - r_addmessage(r, u->faction, unseen); - } - } else { /* Fernzauber, fremde Partei sieht den Magier niemals */ - r_addmessage(r, u->faction, unseen); - } - } else { /* Partei des Magiers, sieht diesen immer */ - r_addmessage(r, u->faction, seen); - } - } - } - /* Ist niemand von der Partei des Magiers in der Region, dem Magier - * nochmal gesondert melden */ - if (!fval(mage->faction, FFL_SELECT)) { - add_message(&mage->faction->msgs, seen); - } -#else - int err = report_action(r, mage, seen, ACTION_RESET|ACTION_CANSEE); - if (err) { - report_action(r, mage, seen, ACTION_CANNOTSEE); - } -#endif -} - -/* ------------------------------------------------------------- */ -/* Die Spruchfunktionen */ -/* ------------------------------------------------------------- */ -/* Meldungen: - * - * Fehlermeldungen sollten als MSG_MAGIC, level ML_MISTAKE oder - * ML_WARN ausgegeben werden. (stehen im Kopf der Auswertung unter - * Zauberwirkungen) - - sprintf(buf, "%s in %s: 'ZAUBER %s': [hier die Fehlermeldung].", - unitname(mage), regionname(mage->region, mage->faction), sa->strings[0]); - add_message(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE); - - * Allgemein sichtbare Auswirkungen in der Region sollten als - * Regionsereignisse auch dort auftauchen. - - { - message * seen = msg_message("harvest_effect", "mage", mage); - message * unseen = msg_message("harvest_effect", "mage", NULL); - report_effect(r, mage, seen, unseen); - } - - * Meldungen an den Magier �ber Erfolg sollten, wenn sie nicht als - * Regionsereigniss auftauchen, als MSG_MAGIC level ML_INFO unter - * Zauberwirkungen gemeldet werden. Direkt dem Magier zuordnen (wie - * Botschaft an Einheit) ist derzeit nicht m�glich. - * ACHTUNG! r muss nicht die Region des Magier sein! (FARCASTING) - * - * Parameter: - * die Struct castorder *co ist in magic.h deklariert - * die Parameterliste spellparameter *pa = co->par steht dort auch. - * - */ - -/* ------------------------------------------------------------- */ -/* Name: Vertrauter - * Stufe: 10 - * - * Wirkung: - * Der Magier beschw�rt einen Vertrauten, ein kleines Tier, welches - * dem Magier zu Diensten ist. Der Magier kann durch die Augen des - * Vertrauten sehen, und durch den Vertrauten zaubern, allerdings nur - * mit seiner halben Stufe. Je nach Vertrautem erh�lt der Magier - * evtl diverse Skillmodifikationen. Der Typ des Vertrauten ist - * zuf�llig bestimmt, wird aber durch Magiegebiet und Rasse beeinflu�t. - * "Tierische" Vertraute brauchen keinen Unterhalt. - * - * Ein paar M�glichkeiten: - * Magieg. Rasse Besonderheiten - * Eule Tybied -/- fliegt, Auraregeneration - * Rabe Ilaun -/- fliegt - * Imp Draig -/- Magieresistenz? - * Fuchs Gwyrrd -/- Wahrnehmung - * ???? Cerddor -/- ???? (Singvogel?, Papagei?) - * Adler -/- -/- fliegt, +Wahrnehmung, =^=Adlerauge-Spruch? - * Kr�he -/- -/- fliegt, +Tarnung (weil unauff�llig) - * Delphin -/- Meerm. schwimmt - * Wolf -/- Ork - * Hund -/- Mensch kann evtl BEWACHE ausf�hren - * Ratte -/- Goblin - * Albatros -/- -/- fliegt, kann auf Ozean "landen" - * Affe -/- -/- kann evtl BEKLAUE ausf�hren - * Goblin -/- !Goblin normale Einheit - * Katze -/- !Katze normale Einheit - * D�mon -/- !D�mon normale Einheit - * - * Spezielle V. f�r Katzen, Trolle, Elfen, D�monen, Insekten, Zwerge? - */ - -static const race * -select_familiar(const race * magerace, magic_t magiegebiet) -{ - const race * retval = NULL; - int rnd = rng_int()%100; - - assert(magerace->familiars[0]); - if (rnd < 3) { - race_list * familiarraces = get_familiarraces(); - unsigned int maxlen = listlen(familiarraces); - if (maxlen>0) { - race_list * rclist = familiarraces; - int index = rng_int()%maxlen; - while (index-->0) { - rclist = rclist->next; - } - retval = rclist->data; - } - } else if (rnd < 70) { - retval = magerace->familiars[0]; - } else { - retval = magerace->familiars[magiegebiet]; - } - - return retval; -} - -/* ------------------------------------------------------------- */ -/* der Vertraue des Magiers */ - -static void -make_familiar(unit *familiar, unit *mage) -{ - /* skills and spells: */ - if (familiar->race->init_familiar!=NULL) { - familiar->race->init_familiar(familiar); - } else { - log_error(("could not perform initialization for familiar %s.\n", - familiar->faction->race->_name[0])); - } - - /* triggers: */ - create_newfamiliar(mage, familiar); - - /* Hitpoints nach Talenten korrigieren, sonst starten vertraute - * mit Ausdauerbonus verwundet */ - familiar->hp = unit_max_hp(familiar); -} - -static int -sp_summon_familiar(castorder *co) -{ - unit *familiar; - region *r = co->rt; - region *target_region = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - const race * rc; - skill_t sk; - int dh, dh1, bytes; - direction_t d; - message * msg; - char zText[2048], * bufp = zText; - size_t size = sizeof(zText) - 1; - - if (get_familiar(mage) != NULL ) { - cmistake(mage, co->order, 199, MSG_MAGIC); - return 0; - } - rc = select_familiar(mage->faction->race, mage->faction->magiegebiet); - if (rc==NULL) { - log_error(("could not find suitable familiar for %s.\n", - mage->faction->race->_name[0])); - return 0; - } - - if (fval(rc, RCF_SWIM) && !fval(rc, RCF_WALK)) { - int coasts = is_coastregion(r); - - if (coasts == 0) { - cmistake(mage, co->order, 229, MSG_MAGIC); - return 0; - } - - /* In welcher benachbarten Ozeanregion soll der Familiar erscheinen? */ - coasts = rng_int()%coasts; - dh = -1; - for(d=0; d<MAXDIRECTIONS; d++) { - region * rn = rconnect(r,d); - if (rn && fval(rn->terrain, SEA_REGION)) { - dh++; - if (dh == coasts) break; - } - } - target_region = rconnect(r,d); - } - - msg = msg_message("familiar_name", "unit", mage); - nr_render(msg, mage->faction->locale, zText, sizeof(zText), mage->faction); - msg_release(msg); - familiar = create_unit(target_region, mage->faction, 1, rc, 0, zText, mage); - setstatus(familiar, ST_FLEE); - fset(familiar, UFL_LOCKED); - make_familiar(familiar, mage); - - dh = 0; - dh1 = 0; - for (sk=0;sk<MAXSKILLS;sk++) { - if (rc->bonus[sk] > -5) dh++; - } - - for (sk=0;sk<MAXSKILLS;sk++) { - if (rc->bonus[sk] > -5) { - dh--; - if (dh1 == 0) { - dh1 = 1; - } else { - if (dh == 0) { - bytes = (int)strlcpy(bufp, (const char*)LOC(mage->faction->locale, "list_and"), size); - } else { - bytes = (int)strlcpy(bufp, (const char*)", ", size); - } - if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER(); - } - bytes = (int)strlcpy(bufp, (const char*)skillname(sk, mage->faction->locale), size); - if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER(); - } - } - ADDMSG(&mage->faction->msgs, msg_message("familiar_describe", - "mage race skills", mage, rc, zText)); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Zerst�re Magie - * Wirkung: - * Zerst�rt alle Zauberwirkungen auf dem Objekt. Jeder gebrochene - * Zauber verbraucht c->vigour an Zauberkraft. Wird der Spruch auf - * einer geringeren Stufe gezaubert, als der Zielzauber an c->vigour - * hat, so schl�gt die Aufl�sung mit einer von der Differenz abh�ngigen - * Chance fehl. Auch dann wird force verbraucht, der Zauber jedoch nur - * abgeschw�cht. - * - * Flag: - * (FARCASTING|SPELLLEVEL|ONSHIPCAST|TESTCANSEE) - * */ -static int -sp_destroy_magic(castorder *co) -{ - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - spellparameter *pa = co->par; - curse * c = NULL; - char ts[80]; - attrib **ap; - int obj; - int succ; - - /* da jeder Zauber force verbraucht und der Zauber auf alles und nicht - * nur einen Spruch wirken soll, wird die Wirkung hier verst�rkt */ - force *= 4; - - /* Objekt ermitteln */ - obj = pa->param[0]->typ; - - switch(obj) { - case SPP_REGION: - { - /* region *tr = pa->param[0]->data.r; -- farcasting! */ - region *tr = co->rt; - ap = &tr->attribs; - write_regionname(tr, mage->faction, ts, sizeof(ts)); - break; - } - case SPP_TEMP: - case SPP_UNIT: - { - unit *u; - u = pa->param[0]->data.u; - ap = &u->attribs; - write_unitname(u, ts, sizeof(ts)); - break; - } - case SPP_BUILDING: - { - building *b; - b = pa->param[0]->data.b; - ap = &b->attribs; - write_buildingname(b, ts, sizeof(ts)); - break; - } - case SPP_SHIP: - { - ship *sh; - sh = pa->param[0]->data.sh; - ap = &sh->attribs; - write_shipname(sh, ts, sizeof(ts)); - break; - } - default: - return 0; - } - - succ = break_curse(ap, cast_level, force, c); - - if (succ) { - ADDMSG(&mage->faction->msgs, msg_message( - "destroy_magic_effect", "unit region command succ target", - mage, mage->region, co->order, succ, ts)); - } else { - ADDMSG(&mage->faction->msgs, msg_message( - "destroy_magic_noeffect", "unit region command", - mage, mage->region, co->order)); - } - - return MAX(succ, 1); -} - -/* ------------------------------------------------------------- */ -/* Name: Transferiere Aura - * Stufe: variabel - * Gebiet: alle - * Kategorie: Einheit, positiv - * Wirkung: - * Mit Hilfe dieses Zauber kann der Magier eigene Aura im Verh�ltnis - * 2:1 auf einen anderen Magier des gleichen Magiegebietes oder (nur - * bei Tybied) im Verh�ltnis 3:1 auf einen Magier eines anderen - * Magiegebietes �bertragen. - * - * Syntax: - * "ZAUBERE <spruchname> <Einheit-Nr> <investierte Aura>" - * "ui" - * Flags: - * (UNITSPELL|ONSHIPCAST) - * */ - -static int -sp_transferaura(castorder *co) -{ - int aura, gain, multi = 2; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - unit * u; - sc_mage * scm_dst, * scm_src = get_mage(mage); - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber - * abbrechen aber kosten lassen */ - if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; - - /* Wieviel Transferieren? */ - aura = pa->param[1]->data.i; - u = pa->param[0]->data.u; - scm_dst = get_mage(u); - - if (scm_dst==NULL) { - /* "Zu dieser Einheit kann ich keine Aura �bertragen." */ - cmistake(mage, co->order, 207, MSG_MAGIC); - return 0; - } else if (scm_src->magietyp==M_TYBIED) { - if (scm_src->magietyp != scm_dst->magietyp) multi = 3; - } else if (scm_src->magietyp==M_GRAY) { - if (scm_src->magietyp != scm_dst->magietyp) multi = 4; - } else if (scm_dst->magietyp!=scm_src->magietyp) { - /* "Zu dieser Einheit kann ich keine Aura �bertragen." */ - cmistake(mage, co->order, 207, MSG_MAGIC); - return 0; - } - - if (aura < multi) { - /* "Auraangabe fehlerhaft." */ - cmistake(mage, co->order, 208, MSG_MAGIC); - return 0; - } - - gain = MIN(aura, scm_src->spellpoints) / multi; - scm_src->spellpoints -= gain*multi; - scm_dst->spellpoints += gain; - -/* sprintf(buf, "%s transferiert %d Aura auf %s", unitname(mage), - gain, unitname(u)); */ - ADDMSG(&mage->faction->msgs, msg_message( - "auratransfer_success", "unit target aura", mage, u, gain)); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* DRUIDE */ -/* ------------------------------------------------------------- */ -/* Name: G�nstige Winde - * Stufe: 4 - * Gebiet: Gwyrrd - * Wirkung: - * Schiffsbewegung +1, kein Abtreiben. H�lt (Stufe) Runden an. - * Kombinierbar mit "Sturmwind" (das +1 wird dadurch aber nicht - * verdoppelt), und "Luftschiff". - * - * Flags: - * (SHIPSPELL|ONSHIPCAST|SPELLLEVEL|TESTRESISTANCE) - */ - -static int -sp_goodwinds(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - int duration = cast_level+1; - spellparameter *pa = co->par; - message * m; - ship *sh; - unit *u; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - sh = pa->param[0]->data.sh; - - /* keine Probleme mit C_SHIP_SPEEDUP und C_SHIP_FLYING */ - /* NODRIFT bewirkt auch +1 Geschwindigkeit */ - create_curse(mage, &sh->attribs, ct_find("nodrift"), power, duration, zero_effect, 0); - - /* melden, 1x pro Partei */ - freset(mage->faction, FFL_SELECT); - for(u = r->units; u; u = u->next ) freset(u->faction, FFL_SELECT); - m = msg_message("wind_effect", "mage ship", mage, sh); - for(u = r->units; u; u = u->next ) { - if (u->ship != sh ) /* nur den Schiffsbesatzungen! */ - continue; - if (!fval(u->faction, FFL_SELECT) ) { - r_addmessage(r, u->faction, m); - fset(u->faction, FFL_SELECT); - } - } - if (!fval(mage->faction, FFL_SELECT)) { - r_addmessage(r, mage->faction, m); - } - msg_release(m); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Magischer Pfad - * Stufe: 4 - * Gebiet: Gwyrrd - * Wirkung: - * f�r Stufe Runden wird eine (magische) Strasse erzeugt, die wie eine - * normale Strasse wirkt. - * Im Ozean schl�gt der Spruch fehl - * - * Flags: - * (FARCASTING|SPELLLEVEL|REGIONSPELL|ONSHIPCAST|TESTRESISTANCE) - */ -static int -sp_magicstreet(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - - if (!fval(r->terrain, LAND_REGION)) { - cmistake(mage, co->order, 186, MSG_MAGIC); - return 0; - } - - /* wirkt schon in der Zauberrunde! */ - create_curse(mage, &r->attribs, ct_find("magicstreet"), co->force, co->level+1, zero_effect, 0); - - /* melden, 1x pro Partei */ - { - message * seen = msg_message("path_effect", "mage region", mage, r); - message * unseen = msg_message("path_effect", "mage region", NULL, r); - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); - } - - return co->level; -} - -/* ------------------------------------------------------------- */ -/* Name: Erwecke Ents - * Stufe: 10 - * Kategorie: Beschw�rung, positiv - * Gebiet: Gwyrrd - * Wirkung: - * Verwandelt (Stufe) B�ume in eine Gruppe von Ents, die sich f�r Stufe - * Runden der Partei des Druiden anschliessen und danach wieder zu - * B�umen werden - * Patzer: - * Monster-Ents entstehen - * - * Flags: - * (SPELLLEVEL) - */ -static int -sp_summonent(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - unit *u; - attrib *a; - int ents; - - if (rtrees(r,2) == 0) { - cmistake(mage, co->order, 204, MSG_EVENT); - /* nicht ohne b�ume */ - return 0; - } - - ents = (int)MIN(power*power, rtrees(r,2)); - - u = create_unit(r, mage->faction, ents, new_race[RC_TREEMAN], 0, NULL, mage); - - a = a_new(&at_unitdissolve); - a->data.ca[0] = 2; /* An r->trees. */ - a->data.ca[1] = 5; /* 5% */ - a_add(&u->attribs, a); - fset(u, UFL_LOCKED); - - rsettrees(r, 2, rtrees(r,2) - ents); - - /* melden, 1x pro Partei */ - { - message * seen = msg_message("ent_effect", "mage amount", mage, ents); - message * unseen = msg_message("ent_effect", "mage amount", NULL, ents); - report_effect(r, mage, seen, unseen); - msg_release(unseen); - msg_release(seen); - } - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Segne Steinkreis - * Stufe: 11 - * Kategorie: Artefakt - * Gebiet: Gwyrrd - * Wirkung: - * Es werden zwei neue Geb�ude eingef�hrt: Steinkreis und Steinkreis - * (gesegnet). Ersteres kann man bauen, letzteres wird aus einem - * fertigen Steinkreis mittels des Zaubers erschaffen. - * - * Flags: - * (BUILDINGSPELL) - * - */ -static int -sp_blessstonecircle(castorder *co) -{ - building *b; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *p = co->par; - message * msg; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (p->param[0]->flag == TARGET_NOTFOUND) return 0; - - b = p->param[0]->data.b; - - if (b->type != bt_find("stonecircle")) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_notstonecircle", "building", b)); - return 0; - } - - if (b->size < b->type->maxsize) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_notcomplete", "building", b)); - return 0; - } - - b->type = bt_find("blessedstonecircle"); - - msg = msg_message("blessedstonecircle_effect", "mage building", mage, b); - add_message(&r->msgs, msg); - msg_release(msg); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Mahlstrom - * Stufe: 15 - * Kategorie: Region, negativ - * Gebiet: Gwyrrd - * Wirkung: - * Erzeugt auf See einen Mahlstrom f�r Stufe-Wochen. Jedes Schiff, das - * durch den Mahlstrom segelt, nimmt 0-150% Schaden. (D.h. es hat auch - * eine 1/3-Chance, ohne Federlesens zu sinken. Der Mahlstrom sollte - * aus den Nachbarregionen sichtbar sein. - * - * Flags: - * (OCEANCASTABLE | ONSHIPCAST | REGIONSPELL | TESTRESISTANCE) - */ -static int -sp_maelstrom(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - curse * c; - double power = co->force; - double effect = co->force; - int duration = (int)power+1; - - if (!fval(r->terrain, SEA_REGION)) { - cmistake(mage, co->order, 205, MSG_MAGIC); - /* nur auf ozean */ - return 0; - } - - /* Attribut auf Region. - * Existiert schon ein curse, so wird dieser verst�rkt - * (Max(Dauer), Max(St�rke))*/ - c = create_curse(mage, &r->attribs, ct_find("maelstrom"), power, duration, effect, 0); - - /* melden, 1x pro Partei */ - { - message * seen = msg_message("maelstrom_effect", "mage", mage); - message * unseen = msg_message("maelstrom_effect", "mage", NULL); - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); - } - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Wurzeln der Magie - * Stufe: 16 - * Kategorie: Region, neutral - * Gebiet: Gwyrrd - * Wirkung: - * Wandelt einen Wald permanent in eine Mallornregion - * - * Flags: - * (FARCASTING | REGIONSPELL | TESTRESISTANCE) - */ -static int -sp_mallorn(castorder *co) -{ - region *r = co->rt; - int cast_level = co->level; - unit *mage = co->magician.u; - - if (!fval(r->terrain, LAND_REGION)) { - cmistake(mage, co->order, 290, MSG_MAGIC); - return 0; - } - if (fval(r, RF_MALLORN)) { - cmistake(mage, co->order, 291, MSG_MAGIC); - return 0; - } - - /* half the trees will die */ - rsettrees(r, 2, rtrees(r,2)/2); - rsettrees(r, 1, rtrees(r,1)/2); - rsettrees(r, 0, rtrees(r,0)/2); - fset(r, RF_MALLORN); - - /* melden, 1x pro Partei */ - { - message * seen = msg_message("mallorn_effect", "mage", mage); - message * unseen = msg_message("mallorn_effect", "mage", NULL); - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); - } - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Segen der Erde / Regentanz - * Stufe: 1 - * Kategorie: Region, positiv - * Gebiet: Gwyrrd - * - * Wirkung: - * Alle Bauern verdienen Stufe-Wochen 1 Silber mehr. - * - * Flags: - * (FARCASTING | SPELLLEVEL | ONSHIPCAST | REGIONSPELL) - */ -static int -sp_blessedharvest(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - int duration = (int)power+1; - /* Attribut auf Region. - * Existiert schon ein curse, so wird dieser verst�rkt - * (Max(Dauer), Max(St�rke))*/ - - if (create_curse(mage, &r->attribs, ct_find("blessedharvest"), power, duration, 1.0, 0)) { - message * seen = msg_message("harvest_effect", "mage", mage); - message * unseen = msg_message("harvest_effect", "mage", NULL); - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); - } - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Hainzauber - * Stufe: 2 - * Kategorie: Region, positiv - * Gebiet: Gwyrrd - * Syntax: ZAUBER [REGION x y] [STUFE 2] "Hain" - * Wirkung: - * Erschafft Stufe-10*Stufe Jungb�ume - * - * Flag: - * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) - */ - -static int -sp_hain(castorder *co) -{ - int trees; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - - if (!r->land) { - cmistake(mage, co->order, 296, MSG_MAGIC); - return 0; - } - if (fval(r, RF_MALLORN)) { - cmistake(mage, co->order, 92, MSG_MAGIC); - return 0; - } - - trees = lovar((int)(force * 10 * RESOURCE_QUANTITY)) + (int)force; - rsettrees(r, 1, rtrees(r,1) + trees); - - /* melden, 1x pro Partei */ - { - message * seen = msg_message("growtree_effect", "mage amount", mage, trees); - message * unseen = msg_message("growtree_effect", "mage amount", NULL, trees); - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); - } - - return cast_level; -} -/* ------------------------------------------------------------- */ -/* Name: Segne Mallornstecken - Mallorn Hainzauber - * Stufe: 4 - * Kategorie: Region, positiv - * Gebiet: Gwyrrd - * Syntax: ZAUBER [REGION x y] [STUFE 4] "Segne Mallornstecken" - * Wirkung: - * Erschafft Stufe-10*Stufe Jungb�ume - * - * Flag: - * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) - */ - -static int -sp_mallornhain(castorder *co) -{ - int trees; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - - if (!r->land) { - cmistake(mage, co->order, 296, MSG_MAGIC); - return 0; - } - if (!fval(r, RF_MALLORN)) { - cmistake(mage, co->order, 91, MSG_MAGIC); - return 0; - } - - trees = lovar((int)(force * 10 * RESOURCE_QUANTITY)) + (int)force; - rsettrees(r, 1, rtrees(r,1) + trees); - - /* melden, 1x pro Partei */ - { - message * seen = msg_message("growtree_effect", "mage amount", mage, trees); - message * unseen = msg_message("growtree_effect", "mage amount", NULL, trees); - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); - } - - return cast_level; -} - -void -patzer_ents(castorder *co) -{ - int ents; - unit *u; - region *r = co->rt; - unit *mage = co->magician.u; - /* int cast_level = co->level; */ - double force = co->force; - - if (!r->land) { - cmistake(mage, co->order, 296, MSG_MAGIC); - return; - } - - ents = (int)(force*10); - u = create_unit(r, get_monsters(), ents, new_race[RC_TREEMAN], 0, NULL, NULL); - - /* 'Erfolg' melden */ - ADDMSG(&mage->faction->msgs, msg_message( - "regionmagic_patzer", "unit region command", mage, - mage->region, co->order)); - - /* melden, 1x pro Partei */ - { - message * unseen = msg_message("entrise", "region", r); - report_effect(r, mage, unseen, unseen); - msg_release(unseen); - } -} - -/* ------------------------------------------------------------- */ -/* Name: Rosthauch - * Stufe: 3 - * Kategorie: Einheit, negativ - * Gebiet: Gwyrrd - * Wirkung: - * Zerst�rt zwischen Stufe und Stufe*10 Eisenwaffen - * - * Flag: - * (FARCASTING | SPELLLEVEL | UNITSPELL | TESTCANSEE | TESTRESISTANCE) - */ -/* Syntax: ZAUBER [REGION x y] [STUFE 2] "Rosthauch" 1111 2222 3333 */ - -typedef struct iron_weapon { - const struct item_type * type; - const struct item_type * rusty; - float chance; - struct iron_weapon * next; -} iron_weapon; - -static iron_weapon * ironweapons = NULL; - -void -add_ironweapon(const struct item_type * type, const struct item_type * rusty, float chance) -{ - iron_weapon * iweapon = malloc(sizeof(iron_weapon)); - iweapon->type = type; - iweapon->rusty = rusty; - iweapon->chance = chance; - iweapon->next = ironweapons; - ironweapons = iweapon; -} - -static int -sp_rosthauch(castorder *co) -{ - int n; - int success = 0; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - int force = (int)co->force; - spellparameter *pa = co->par; - - if (ironweapons==NULL) { - add_ironweapon(it_find("sword"), it_find("rustysword"), 1.0); - add_ironweapon(it_find("axe"), it_find("rustyaxe"), 1.0); - add_ironweapon(it_find("greatsword"), it_find("rustygreatsword"), 1.0); - add_ironweapon(it_find("halberd"), it_find("rustyhalberd"), 0.5f); -#ifndef NO_RUSTY_ARMOR - add_ironweapon(it_find("shield"), it_find("rustyshield"), 0.5f); - add_ironweapon(it_find("chainmail"), it_find("rustychainmail"), 0.2f); -#endif - } - - if (force>0) { - force = rng_int()%((int)(force * 10)) + force; - } - /* fuer jede Einheit */ - for (n = 0; n < pa->length; n++) { - unit *u = pa->param[n]->data.u; - int ironweapon = 0; - iron_weapon * iweapon = ironweapons; - - if (force<=0) break; - if (pa->param[n]->flag & (TARGET_RESISTS|TARGET_NOTFOUND)) continue; - - for (;iweapon!=NULL;iweapon=iweapon->next) { - item ** ip = i_find(&u->items, iweapon->type); - if (*ip) { - int i = MIN((*ip)->number, force); - if (iweapon->chance<1.0) { - i = (int)(i*iweapon->chance); - } - if (i>0) { - force -= i; - ironweapon += i; - i_change(ip, iweapon->type, -i); - if (iweapon->rusty) { - i_change(&u->items, iweapon->rusty, i); - } - } - } - if (force<=0) break; - } - - if (ironweapon>0) { - /* {$mage mage} legt einen Rosthauch auf {target}. {amount} Waffen - * wurden vom Rost zerfressen */ - ADDMSG(&mage->faction->msgs, msg_message("rust_effect", - "mage target amount", mage, u, ironweapon)); - ADDMSG(&u->faction->msgs, msg_message("rust_effect", - "mage target amount", - cansee(u->faction, r, mage, 0) ? mage:NULL, u, ironweapon)); - success += ironweapon; - } else { - /* {$mage mage} legt einen Rosthauch auf {target}, doch der - * Rosthauch fand keine Nahrung */ - ADDMSG(&mage->faction->msgs, msg_message( - "rust_fail", "mage target", mage, u)); - } - } - /* in success stehen nun die insgesamt zerst�rten Waffen. Im - * ung�nstigsten Fall kann pro Stufe nur eine Waffe verzaubert werden, - * darum wird hier nur f�r alle F�lle in denen noch weniger Waffen - * betroffen wurden ein Kostennachlass gegeben */ - return MIN(success, cast_level); -} - - -/* ------------------------------------------------------------- */ -/* Name: K�lteschutz - * Stufe: 3 - * Kategorie: Einheit, positiv - * Gebiet: Gwyrrd - * - * Wirkung: - * sch�tzt ein bis mehrere Einheiten mit bis zu Stufe*10 Insekten vor - * den Auswirkungen der K�lte. Sie k�nnen Gletscher betreten und dort - * ganz normal alles machen. Die Wirkung h�lt Stufe Wochen an - * Insekten haben in Gletschern den selben Malus wie in Bergen. Zu - * lange drin, nicht mehr �ndern - * - * Flag: - * (UNITSPELL | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) - */ -/* Syntax: ZAUBER [STUFE n] "K�lteschutz" eh1 [eh2 [eh3 [...]]] */ - -static int -sp_kaelteschutz(castorder *co) -{ - unit *u; - int n, i = 0; - int men; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int duration = MAX(cast_level, (int)force) + 1; - spellparameter *pa = co->par; - double effect; - - force*=10; /* 10 Personen pro Force-Punkt */ - - /* f�r jede Einheit in der Kommandozeile */ - for (n = 0; n < pa->length; n++) { - if (force < 1) - break; - - if (pa->param[n]->flag == TARGET_RESISTS - || pa->param[n]->flag == TARGET_NOTFOUND) - continue; - - u = pa->param[n]->data.u; - - if (force < u->number) { - men = (int)force; - } else { - men = u->number; - } - - effect = 1; - create_curse(mage, &u->attribs, ct_find("insectfur"), cast_level, - duration, effect, men); - - force -= u->number; - ADDMSG(&mage->faction->msgs, msg_message( - "heat_effect", "mage target", mage, u)); - if (u->faction!=mage->faction) ADDMSG(&u->faction->msgs, msg_message( - "heat_effect", "mage target", - cansee(u->faction, r, mage, 0) ? mage:NULL, u)); - i = cast_level; - } - /* Erstattung? */ - return i; -} - -/* ------------------------------------------------------------- */ -/* Name: Verw�nschung, Funkenregen, Naturfreund, ... - * Stufe: 1 - * Kategorie: Einheit, rein visuell - * Gebiet: Alle - * - * Wirkung: - * Die Einheit wird von einem magischen Effekt heimgesucht, der in ihrer - * Beschreibung auftaucht, aber nur visuellen Effekt hat. - * - * Flag: - * (UNITSPELL | TESTCANSEE | SPELLLEVEL) - */ -/* Syntax: ZAUBER "Funkenregen" eh1 */ - -static int -sp_sparkle(castorder *co) -{ - unit *u; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - int duration = cast_level+1; - double effect; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber - * abbrechen aber kosten lassen */ - if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; - - u = pa->param[0]->data.u; - effect = rng_int() % 0xffffff; - create_curse(mage, &u->attribs, ct_find("sparkle"), cast_level, - duration, effect, u->number); - - ADDMSG(&mage->faction->msgs, msg_message( - "sparkle_effect", "mage target", mage, u)); - if (u->faction!=mage->faction) { - ADDMSG(&u->faction->msgs, msg_message( - "sparkle_effect", "mage target", mage, u)); - } - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Eisengolem - * Stufe: 2 - * Kategorie: Beschw�rung, positiv - * Gebiet: Gwyrrd - * Wirkung: - * Erschafft eine Einheit Eisengolems mit Stufe*8 Golems. Jeder Golem - * hat jede Runde eine Chance von 15% zu Staub zu zerfallen. Gibt man - * den Golems den Befehl 'mache Schwert/Bih�nder' oder 'mache - * Schild/Kettenhemd/Plattenpanzer', so werden pro Golem 5 Eisenbarren - * verbaut und der Golem l�st sich auf. - * - * Golems sind zu langsam um wirklich im Kampf von Nutzen zu sein. - * Jedoch fangen sie eine Menge Schaden auf und sollten sie zuf�llig - * treffen, so ist der Schaden fast immer t�dlich. (Eisengolem: HP - * 50, AT 4, PA 2, R�stung 2(KH), 2d10+4 TP, Magieresistenz 0.25) - * - * Golems nehmen nix an und geben nix. Sie bewegen sich immer nur 1 - * Region weit und ziehen aus Strassen keinen Nutzen. Ein Golem wiegt - * soviel wie ein Stein. Kann nicht im Sumpf gezaubert werden - * - * Flag: - * (SPELLLEVEL) - * - * #define GOLEM_IRON 4 - */ - -static int -sp_create_irongolem(castorder *co) -{ - unit *u2; - attrib *a; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int number = lovar(force*8*RESOURCE_QUANTITY); - if (number<1) number = 1; - - if (r->terrain == newterrain(T_SWAMP)) { - cmistake(mage, co->order, 188, MSG_MAGIC); - return 0; - } - - u2 = create_unit(r, mage->faction, number, rc_find("irongolem"), 0, NULL, mage); - - set_level(u2, SK_ARMORER, 1); - set_level(u2, SK_WEAPONSMITH, 1); - - a = a_new(&at_unitdissolve); - a->data.ca[0] = 0; - a->data.ca[1] = IRONGOLEM_CRUMBLE; - a_add(&u2->attribs, a); - - ADDMSG(&mage->faction->msgs, - msg_message("magiccreate_effect", "region command unit amount object", - mage->region, co->order, mage, number, - LOC(mage->faction->locale, rc_name(rc_find("irongolem"), 1)))); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Steingolem - * Stufe: 1 - * Kategorie: Beschw�rung, positiv - * Gebiet: Gwyrrd - * Wirkung: - * Erschafft eine Einheit Steingolems mit Stufe*5 Golems. Jeder Golem - * hat jede Runde eine Chance von 10% zu Staub zu zerfallen. Gibt man - * den Golems den Befehl 'mache Burg' oder 'mache Strasse', so werden - * pro Golem 10 Steine verbaut und der Golem l�st sich auf. - * - * Golems sind zu langsam um wirklich im Kampf von Nutzen zu sein. - * Jedoch fangen sie eine Menge Schaden auf und sollten sie zuf�llig - * treffen, so ist der Schaden fast immer t�dlich. (Steingolem: HP 60, - * AT 4, PA 2, R�stung 4(PP), 2d12+6 TP) - * - * Golems nehmen nix an und geben nix. Sie bewegen sich immer nur 1 - * Region weit und ziehen aus Strassen keinen Nutzen. Ein Golem wiegt - * soviel wie ein Stein. - * - * Kann nicht im Sumpf gezaubert werden - * - * Flag: - * (SPELLLEVEL) - * - * #define GOLEM_STONE 4 - */ -static int -sp_create_stonegolem(castorder *co) -{ - unit *u2; - attrib *a; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - int number = lovar(co->force*5*RESOURCE_QUANTITY); - if (number<1) number = 1; - - if (r->terrain == newterrain(T_SWAMP)) { - cmistake(mage, co->order, 188, MSG_MAGIC); - return 0; - } - - u2 = create_unit(r, mage->faction, number, rc_find("stonegolem"), 0, NULL, mage); - set_level(u2, SK_ROAD_BUILDING, 1); - set_level(u2, SK_BUILDING, 1); - - a = a_new(&at_unitdissolve); - a->data.ca[0] = 0; - a->data.ca[1] = STONEGOLEM_CRUMBLE; - a_add(&u2->attribs, a); - - ADDMSG(&mage->faction->msgs, - msg_message("magiccreate_effect", "region command unit amount object", - mage->region, co->order, mage, number, - LOC(mage->faction->locale, rc_name(rc_find("stonegolem"), 1)))); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Gro�e D�rre - * Stufe: 17 - * Kategorie: Region, negativ - * Gebiet: Gwyrrd - * - * Wirkung: - * 50% alle Bauern, Pferde, B�ume sterben. - * Zu 25% terraform: Gletscher wird mit 50% zu Sumpf, sonst Ozean, - * Sumpf wird zu Steppe, Ebene zur Steppe, Steppe zur W�ste. - * Besonderheiten: - * neuer Terraintyp Steppe: - * 5000 Felder, 500 B�ume, Strasse: 250 Steine. Anlegen wie in Ebene - * m�glich - * - * Flags: - * (FARCASTING | REGIONSPELL | TESTRESISTANCE) - */ - -static void -destroy_all_roads(region *r) -{ - int i; - - for(i = 0; i < MAXDIRECTIONS; i++) { - rsetroad(r,(direction_t)i, 0); - } -} - -static int -sp_great_drought(castorder *co) -{ - unit *u; - boolean terraform = false; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int duration = 2; - double effect; - - if (fval(r->terrain, SEA_REGION) ) { - cmistake(mage, co->order, 189, MSG_MAGIC); - /* TODO: vielleicht einen netten Patzer hier? */ - return 0; - } - - /* sterben */ - rsetpeasants(r, rpeasants(r)/2); /* evtl wuerfeln */ - rsettrees(r, 2, rtrees(r,2)/2); - rsettrees(r, 1, rtrees(r,1)/2); - rsettrees(r, 0, rtrees(r,0)/2); - rsethorses(r, rhorses(r)/2); - - /* Arbeitslohn = 1/4 */ - effect = 4.0; /* curses: higher is stronger */ - create_curse(mage, &r->attribs, ct_find("drought"), force, duration, effect, 0); - - /* terraforming */ - if (rng_int() % 100 < 25) { - terraform = true; - - switch(rterrain(r)) { - case T_PLAIN: - /* rsetterrain(r, T_GRASSLAND); */ - destroy_all_roads(r); - break; - - case T_SWAMP: - /* rsetterrain(r, T_GRASSLAND); */ - destroy_all_roads(r); - break; -/* - case T_GRASSLAND: - rsetterrain(r, T_DESERT); - destroy_all_roads(r); - break; -*/ - case T_GLACIER: - if (rng_int() % 100 < 50) { - rsetterrain(r, T_SWAMP); - destroy_all_roads(r); - } else { /* Ozean */ - destroy_all_roads(r); - rsetterrain(r, T_OCEAN); - /* Einheiten d�rfen hier auf keinen Fall gel�scht werden! */ - for (u = r->units; u; u = u->next) { - if (u->race != new_race[RC_SPELL] && u->ship == 0) { - set_number(u, 0); - } - } - while (r->buildings) { - remove_building(&r->buildings, r->buildings); - } - } - break; - - default: - terraform = false; - break; - } - } - - if (!fval(r->terrain, SEA_REGION)) { - /* not destroying the region, so it should be safe to make this a local - * message */ - message * msg; - const char * mtype; - if (r->terrain == newterrain(T_SWAMP) && terraform) { - mtype = "drought_effect_1"; - } else if (!terraform) { - mtype = "drought_effect_2"; - } else { - mtype = "drought_effect_3"; - } - msg = msg_message(mtype, "mage region", mage, r); - add_message(&r->msgs, msg); - msg_release(msg); - } else { - /* possible that all units here get killed so better to inform with a global - * message */ - message * msg = msg_message("drought_effect_4", "mage region", mage, r); - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - for (u = r->units; u; u = u->next) { - if (!fval(u->faction, FFL_SELECT)) { - fset(u->faction, FFL_SELECT); - add_message(&u->faction->msgs, msg); - } - } - if (!fval(mage->faction, FFL_SELECT)) { - add_message(&mage->faction->msgs, msg); - } - msg_release(msg); - } - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: 'Weg der B�ume' - * Stufe: 9 - * Kategorie: Teleport - * Gebiet: Gwyrrd - * Wirkung: - * Der Druide kann 5*Stufe GE in die astrale Ebene schicken. - * Der Druide wird nicht mitteleportiert, es sei denn, er gibt sich - * selbst mit an. - * Der Zauber funktioniert nur in W�ldern. - * - * Syntax: Zauber "Weg der B�ume" <Einheit> ... - * - * Flags: - * (UNITSPELL | SPELLLEVEL | TESTCANSEE) - */ -static int -sp_treewalkenter(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - spellparameter *pa = co->par; - double power = co->force; - int cast_level = co->level; - region *rt; - int remaining_cap; - int n; - int erfolg = 0; - - if (getplane(r) != 0) { - cmistake(mage, co->order, 190, MSG_MAGIC); - return 0; - } - - if (!r_isforest(r)) { - cmistake(mage, co->order, 191, MSG_MAGIC); - return 0; - } - - rt = r_standard_to_astral(r); - if (rt==NULL || is_cursed(rt->attribs, C_ASTRALBLOCK, 0) || fval(rt->terrain, FORBIDDEN_REGION)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); - return 0; - } - - remaining_cap = (int)(power * 500); - - /* fuer jede Einheit */ - for (n = 0; n < pa->length; n++) { - unit * u = pa->param[n]->data.u; - spllprm * param = pa->param[n]; - - if (param->flag & (TARGET_RESISTS|TARGET_NOTFOUND)) { - continue; - } - - if (!ucontact(u, mage)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact", "target", u)); - } else { - int w; - message * m; - unit * u2; - - if (!can_survive(u, rt)) { - cmistake(mage, co->order, 231, MSG_MAGIC); - continue; - } - - w = weight(u); - if (remaining_cap - w < 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "fail_tooheavy", - "target", u)); - continue; - } - remaining_cap = remaining_cap - w; - move_unit(u, rt, NULL); - erfolg = cast_level; - - /* Meldungen in der Ausgangsregion */ - for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = r->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, r, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_disappear", "unit", u); - r_addmessage(r, u2->faction, m); - } - } - } - if (m) msg_release(m); - - /* Meldungen in der Zielregion */ - for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = rt->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_appear", "unit", u); - r_addmessage(rt, u2->faction, m); - } - } - } - if (m) msg_release(m); - } - } - return erfolg; -} - -/* ------------------------------------------------------------- */ -/* Name: 'Sog des Lebens' - * Stufe: 9 - * Kategorie: Teleport - * Gebiet: Gwyrrd - * Wirkung: - * Der Druide kann 5*Stufe GE aus die astrale Ebene schicken. Der - * Druide wird nicht mitteleportiert, es sei denn, er gibt sich selbst - * mit an. - * Der Zauber funktioniert nur, wenn die Zielregion ein Wald ist. - * - * Syntax: Zauber "Sog des Lebens" <Ziel-X> <Ziel-Y> <Einheit> ... - * - * Flags: - * (UNITSPELL|SPELLLEVEL) - */ -static int -sp_treewalkexit(castorder *co) -{ - region *rt; - region_list *rl, *rl2; - int tax, tay; - unit *u, *u2; - int remaining_cap; - int n; - int erfolg = 0; - region *r = co->rt; - unit *mage = co->magician.u; - double power = co->force; - spellparameter *pa = co->par; - int cast_level = co->level; - - if (!is_astral(r)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralonly", "")); - return 0; - } - if (is_cursed(r->attribs, C_ASTRALBLOCK, 0)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); - return 0; - } - - remaining_cap = (int)(power * 500); - - if (pa->param[0]->typ != SPP_REGION) { - report_failure(mage, co->order); - return 0; - } - - /* Koordinaten setzen und Region l�schen f�r �berpr�fung auf - * G�ltigkeit */ - rt = pa->param[0]->data.r; - tax = rt->x; - tay = rt->y; - rt = NULL; - - rl = astralregions(r, inhabitable); - rt = 0; - - rl2 = rl; - while(rl2) { - if (rl2->data->x == tax && rl2->data->y == tay) { - rt = rl2->data; - break; - } - rl2 = rl2->next; - } - free_regionlist(rl); - - if (!rt) { - cmistake(mage, co->order, 195, MSG_MAGIC); - return 0; - } - - if (!r_isforest(rt)) { - cmistake(mage, co->order, 196, MSG_MAGIC); - return 0; - } - - /* f�r jede Einheit in der Kommandozeile */ - for (n = 1; n < pa->length; n++) { - if (pa->param[n]->flag == TARGET_RESISTS - || pa->param[n]->flag == TARGET_NOTFOUND) - continue; - - u = pa->param[n]->data.u; - - if (!ucontact(u, mage)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact", "target", u)); - } else { - int w = weight(u); - if (!can_survive(u, rt)) { - cmistake(mage, co->order, 231, MSG_MAGIC); - } else if (remaining_cap - w < 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "fail_tooheavy", "target", u)); - } else { - message * m; - - remaining_cap = remaining_cap - w; - move_unit(u, rt, NULL); - erfolg = cast_level; - - /* Meldungen in der Ausgangsregion */ - - for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for(u2 = r->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, r, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_disappear", "unit", u); - r_addmessage(r, u2->faction, m); - } - } - } - if (m) msg_release(m); - - /* Meldungen in der Zielregion */ - - for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = rt->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_appear", "unit", u); - r_addmessage(rt, u2->faction, m); - } - } - } - if (m) msg_release(m); - } - } - } - return erfolg; -} - -/* ------------------------------------------------------------- */ -/* Name: Heiliger Boden - * Stufe: 9 - * Kategorie: perm. Regionszauber - * Gebiet: Gwyrrd - * Wirkung: - * Es entstehen keine Untoten mehr, Untote betreten die Region - * nicht mehr. - * - * ZAUBER "Heiliger Boden" - * Flags: (0) - */ -static int -sp_holyground(castorder *co) -{ - static const curse_type * ctype = NULL; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - curse * c; - message * msg = msg_message("sp_holyground_effect", "mage region", mage, r); - report_spell(mage, r, msg); - msg_release(msg); - - if (!ctype) ctype = ct_find("holyground"); - c = create_curse(mage, &r->attribs, ctype, power*power, 1, zero_effect, 0); - - a_removeall(&r->attribs, &at_deathcount); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Heimstein - * Stufe: 7 - * Kategorie: Artefakt - * Gebiet: Gwyrrd - * Wirkung: - * Die Burg kann nicht mehr durch Donnerbeben oder andere - * Geb�udezerst�renden Spr�che kaputt gemacht werden. Auch - * sch�tzt der Zauber vor Belagerungskatapulten. - * - * ZAUBER Heimstein - * Flags: (0) - */ -static int -sp_homestone(castorder *co) -{ - unit *u; - curse * c; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - double effect; - message * msg; - if (!mage->building || mage->building->type != bt_find("castle")) { - cmistake(mage, co->order, 197, MSG_MAGIC); - return 0; - } - - c = create_curse(mage, &mage->building->attribs, ct_find("magicwalls"), - force*force, 1, zero_effect, 0); - - if (c==NULL) { - cmistake(mage, co->order, 206, MSG_MAGIC); - return 0; - } - c_setflag(c, CURSE_NOAGE|CURSE_ONLYONE); - - /* Magieresistenz der Burg erh�ht sich um 50% */ - effect = 50; - c = create_curse(mage, &mage->building->attribs, - ct_find("magicresistance"), force*force, 1, effect, 0); - c_setflag(c, CURSE_NOAGE); - - /* melden, 1x pro Partei in der Burg */ - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - msg = msg_message("homestone_effect", "mage building", mage, mage->building); - for (u = r->units; u; u = u->next) { - if (!fval(u->faction, FFL_SELECT)) { - fset(u->faction, FFL_SELECT); - if (u->building == mage->building) { - r_addmessage(r, u->faction, msg); - } - } - } - msg_release(msg); - return cast_level; -} - - - -/* ------------------------------------------------------------- */ -/* Name: D�rre - * Stufe: 13 - * Kategorie: Region, negativ - * Gebiet: Gwyrrd - * Wirkung: - * tempor�r ver�ndert sich das Baummaximum und die maximalen Felder in - * einer Region auf die H�lfte des normalen. - * Die H�lfte der B�ume verdorren und Pferde verdursten. - * Arbeiten bringt nur noch 1/4 des normalen Verdienstes - * - * Flags: - * (FARCASTING|REGIONSPELL|TESTRESISTANCE), - */ -static int -sp_drought(castorder *co) -{ - curse *c; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - int duration = (int)power+1; - message * msg; - - if (fval(r->terrain, SEA_REGION) ) { - cmistake(mage, co->order, 189, MSG_MAGIC); - /* TODO: vielleicht einen netten Patzer hier? */ - return 0; - } - - /* melden, 1x pro Partei */ - msg = msg_message("sp_drought_effect", "mage region", mage, r); - report_spell(mage, r, msg); - msg_release(msg); - - /* Wenn schon Duerre herrscht, dann setzen wir nur den Power-Level - * hoch (evtl dauert dann die Duerre laenger). Ansonsten volle - * Auswirkungen. - */ - c = get_curse(r->attribs, ct_find("drought")); - if (c) { - c->vigour = MAX(c->vigour, power); - c->duration = MAX(c->duration, (int)power); - } else { - double effect; - /* Baeume und Pferde sterben */ - rsettrees(r, 2, rtrees(r,2)/2); - rsettrees(r, 1, rtrees(r,1)/2); - rsettrees(r, 0, rtrees(r,0)/2); - rsethorses(r, rhorses(r)/2); - - effect = 4.0; - create_curse(mage, &r->attribs, ct_find("drought"), power, duration, effect, 0); - } - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Bergw�chter - * Stufe: 9 - * Gebiet: Gwyrrd - * Kategorie: Beschw�rung, negativ - * - * Wirkung: - * Erschafft in Bergen oder Gletschern einen W�chter, der durch bewachen - * den Eisen/Laen-Abbau f�r nicht-Allierte verhindert. Bergw�chter - * verhindern auch Abbau durch getarnte/unsichtbare Einheiten und lassen - * sich auch durch Belagerungen nicht aufhalten. - * - * (Ansonsten in economic.c:manufacture() entsprechend anpassen). - * - * F�higkeiten (factypes.c): 50% Magieresistenz, 25 HP, 4d4 Schaden, - * 4 R�stung (=PP) - * Flags: - * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) - */ -static int -sp_ironkeeper(castorder *co) -{ - unit *keeper; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - message * msg; - - if (r->terrain != newterrain(T_MOUNTAIN) && r->terrain != newterrain(T_GLACIER)) { - report_failure(mage, co->order); - return 0; - } - - keeper = create_unit(r, mage->faction, 1, new_race[RC_IRONKEEPER], 0, NULL, mage); - - /*keeper->age = cast_level + 2;*/ - setstatus(keeper, ST_AVOID); /* kaempft nicht */ - guard(keeper, GUARD_MINING); - fset(keeper, UFL_ISNEW); - /* Parteitarnen, damit man nicht sofort wei�, wer dahinter steckt */ - if (rule_stealth_faction()) { - fset(keeper, UFL_ANON_FACTION); - } - - { - trigger * tkill = trigger_killunit(keeper); - add_trigger(&keeper->attribs, "timer", trigger_timeout(cast_level+2, tkill)); - } - - msg = msg_message("summon_effect", "mage amount race", mage, 1, keeper->race); - r_addmessage(r, NULL, msg); - msg_release(msg); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Sturmwind - Beschw�re einen Sturmelementar - * Stufe: 6 - * Gebiet: Gwyrrd - * - * Wirkung: - * Verdoppelt Geschwindigkeit aller angegebener Schiffe fuer diese - * Runde. Kombinierbar mit "G�nstige Winde", aber nicht mit - * "Luftschiff". - * - * Anstelle des alten ship->enchanted benutzen wir einen kurzfristigen - * Curse. Das ist zwar ein wenig aufwendiger, aber weitaus flexibler - * und erlaubt es zB, die Dauer sp�ter problemlos zu ver�ndern. - * - * Flags: - * (SHIPSPELL|ONSHIPCAST|OCEANCASTABLE|TESTRESISTANCE) - */ - -static int -sp_stormwinds(castorder *co) -{ - ship *sh; - unit *u; - int erfolg = 0; - region *r = co->rt; - unit *mage = co->magician.u; - double power = co->force; - spellparameter *pa = co->par; - int n, force = (int)power; - message * m = NULL; - - /* melden vorbereiten */ - freset(mage->faction, FFL_SELECT); - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - - for (n = 0; n < pa->length; n++) { - if (force<=0) break; - - if (pa->param[n]->flag == TARGET_RESISTS - || pa->param[n]->flag == TARGET_NOTFOUND) - continue; - - sh = pa->param[n]->data.sh; - - /* mit C_SHIP_NODRIFT haben wir kein Problem */ - if (is_cursed(sh->attribs, C_SHIP_FLYING, 0) ) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_spell_on_flying_ship", "ship", sh)) - continue; - } - if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0) ) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_spell_on_ship_already", "ship", sh)) - continue; - } - - /* Duration = 1, nur diese Runde */ - create_curse(mage, &sh->attribs, ct_find("stormwind"), power, 1, zero_effect, 0); - /* Da der Spruch nur diese Runde wirkt wird er nie im Report - * erscheinen */ - erfolg++; - force--; - - /* melden vorbereiten: */ - for(u = r->units; u; u = u->next ) { - if (u->ship == sh ) { - /* nur den Schiffsbesatzungen! */ - fset(u->faction, FFL_SELECT); - } - } - } - if (erfolg<pa->length) { - ADDMSG(&mage->faction->msgs, msg_message("stormwinds_reduced", - "unit ships maxships", mage, erfolg, pa->length)); - } - /* melden, 1x pro Partei auf Schiff und f�r den Magier */ - fset(mage->faction, FFL_SELECT); - for (u = r->units; u; u = u->next ) { - if (fval(u->faction, FFL_SELECT)) { - freset(u->faction, FFL_SELECT); - if (erfolg > 0) { - if (!m) { - m = msg_message("stormwinds_effect", "unit", mage); - } - r_addmessage(r, u->faction, m); - } - } - } - if (m) msg_release(m); - return erfolg; -} - - -/* ------------------------------------------------------------- */ -/* Name: Donnerbeben - * Stufe: 6 - * Gebiet: Gwyrrd - * - * Wirkung: - * Zerst�rt Stufe*10 "Steineinheiten" aller Geb�ude der Region, aber nie - * mehr als 25% des gesamten Geb�udes (aber nat�rlich mindestens ein - * Stein). - * - * Flags: - * (FARCASTING|REGIONSPELL|TESTRESISTANCE) - */ -static int -sp_earthquake(castorder *co) -{ - int kaputt; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - message * msg; - building **blist = &r->buildings; - - while (*blist) { - building * burg = *blist; - - if (burg->size != 0 && !is_cursed(burg->attribs, C_MAGICWALLS, 0)) { - /* Magieresistenz */ - if (!target_resists_magic(mage, burg, TYP_BUILDING, 0)) { - kaputt = MIN(10 * cast_level, burg->size / 4); - kaputt = MAX(kaputt, 1); - burg->size -= kaputt; - if (burg->size == 0) { - /* TODO: sollten die Insassen nicht Schaden nehmen? */ - remove_building(blist, burg); - } - } - } - if (*blist==burg) blist=&burg->next; - } - - /* melden, 1x pro Partei */ - msg = msg_message("earthquake_effect", "mage region", mage, r); - r_addmessage(r, NULL, msg); - msg_release(msg); - return cast_level; -} - - -/* ------------------------------------------------------------- */ -/* CHAOS / M_DRAIG / Draig */ -/* ------------------------------------------------------------- */ -void -patzer_peasantmob(castorder *co) -{ - int anteil = 6, n; - unit *u; - attrib *a; - region *r; - unit *mage = co->magician.u; - - if (mage->region->land) { - r = mage->region; - } else { - r = co->rt; - } - - if (r->land) { - faction * f = get_monsters(); - const struct locale * lang = f->locale; - message * msg; - - anteil += rng_int() % 4; - n = rpeasants(r) * anteil / 10; - rsetpeasants(r, rpeasants(r) - n); - assert(rpeasants(r) >= 0); - - u = create_unit(r, f, n, new_race[RC_PEASANT], 0, LOC(f->locale, "angry_mob"), NULL); - fset(u, UFL_ISNEW); - /* guard(u, GUARD_ALL); hier zu fr�h! Befehl BEWACHE setzten */ - addlist(&u->orders, create_order(K_GUARD, lang, NULL)); - set_order(&u->thisorder, default_order(lang)); - a = a_new(&at_unitdissolve); - a->data.ca[0] = 1; /* An rpeasants(r). */ - a->data.ca[1] = 10; /* 10% */ - a_add(&u->attribs, a); - a_add(&u->attribs, make_hate(mage)); - - msg = msg_message("mob_warning", ""); - r_addmessage(r, NULL, msg); - msg_release(msg); - } - return; -} - - -/* ------------------------------------------------------------- */ -/* Name: Waldbrand - * Stufe: 10 - * Kategorie: Region, negativ - * Gebiet: Draig - * Wirkung: - * Vernichtet 10-80% aller Baeume in der Region. Kann sich auf benachbarte - * Regionen ausbreiten, wenn diese (stark) bewaldet sind. F�r jeweils - * 10 verbrannte Baeume in der Startregion gibts es eine 1%-Chance, dass - * sich das Feuer auf stark bewaldete Nachbarregionen ausdehnt, auf - * bewaldeten mit halb so hoher Wahrscheinlichkeit. Dort verbrennen - * dann prozentual halbsoviele bzw ein viertel soviele Baeume wie in der - * Startregion. - * - * Im Extremfall: 1250 Baeume in Region, 80% davon verbrennen (1000). - * Dann breitet es sich mit 100% Chance in stark bewaldete Regionen - * aus, mit 50% in bewaldete. Dort verbrennen dann 40% bzw 20% der Baeume. - * Weiter als eine Nachbarregion breitet sich dass Feuer nicht aus. - * - * Sinn: Ein Feuer in einer "stark bewaldeten" Wueste hat so trotzdem kaum - * eine Chance, sich weiter auszubreiten, waehrend ein Brand in einem Wald - * sich fast mit Sicherheit weiter ausbreitet. - * - * Flags: - * (FARCASTING | REGIONSPELL | TESTRESISTANCE) - */ -static int -sp_forest_fire(castorder *co) -{ - unit *u; - region *nr; - direction_t i; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double probability; - double percentage = (rng_int() % 8 + 1) * 0.1; /* 10 - 80% */ - message * msg; - - int vernichtet_schoesslinge = (int)(rtrees(r, 1) * percentage); - int destroyed = (int)(rtrees(r, 2) * percentage); - - if (destroyed<1) { - cmistake(mage, co->order, 198, MSG_MAGIC); - return 0; - } - - rsettrees(r, 2, rtrees(r,2) - destroyed); - rsettrees(r, 1, rtrees(r,1) - vernichtet_schoesslinge); - probability = destroyed * 0.001; /* Chance, dass es sich ausbreitet */ - - /* melden, 1x pro Partei */ - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - msg = msg_message("forestfire_effect", "mage region amount", mage, r, destroyed+vernichtet_schoesslinge); - r_addmessage(r, NULL, msg); - add_message(&mage->faction->msgs, msg); - msg_release(msg); - - for (i = 0; i < MAXDIRECTIONS; i++ ) { - nr = rconnect(r, i); - assert(nr); - destroyed = 0; - vernichtet_schoesslinge = 0; - - if (rtrees(nr,2) + rtrees(nr,1) >= 800) { - if (chance(probability)) { - destroyed = (int)(rtrees(nr,2) * percentage/2); - vernichtet_schoesslinge = (int)(rtrees(nr,1) * percentage/2); - } - } else if (rtrees(nr,2) + rtrees(nr,1) >= 600) { - if (chance(probability/2)) { - destroyed = (int)(rtrees(nr,2) * percentage/4); - vernichtet_schoesslinge = (int)(rtrees(nr,1) * percentage/4); - } - } - - if (destroyed > 0 || vernichtet_schoesslinge > 0) { - message * m = msg_message("forestfire_spread", "region next trees", - r, nr, destroyed+vernichtet_schoesslinge); - - add_message(&r->msgs, m); - add_message(&mage->faction->msgs, m); - msg_release(m); - - rsettrees(nr, 2, rtrees(nr,2) - destroyed); - rsettrees(nr, 1, rtrees(nr,1) - vernichtet_schoesslinge); - } - } - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Chaosfluch - * Stufe: 5 - * Gebiet: Draig - * Kategorie: (Antimagie) Kraftreduzierer, Einheit, negativ - * Wirkung: - * Auf einen Magier gezaubert verhindert/erschwert dieser Chaosfluch - * das Zaubern. Patzer werden warscheinlicher. - * Jeder Zauber muss erst gegen den Wiederstand des Fluchs gezaubert - * werden und schw�cht dessen Antimagiewiederstand um 1. - * Wirkt MAX(Stufe(Magier) - Stufe(Ziel), rand(3)) Wochen - * Patzer: - * Magier wird selbst betroffen - * - * Flags: - * (UNITSPELL | SPELLLEVEL | TESTCANSEE | TESTRESISTANCE) - * - */ -static int -sp_fumblecurse(castorder *co) -{ - unit *target; - int rx, sx; - int duration; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - double effect; - curse * c; - spellparameter *pa = co->par; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - target = pa->param[0]->data.u; - - rx = rng_int()%3; - sx = cast_level - effskill(target, SK_MAGIC); - duration = MAX(sx, rx) + 1; - - effect = force*0.5; - c = create_curse(mage, &target->attribs, ct_find("fumble"), - force, duration, effect, 0); - if (c == NULL) { - report_failure(mage, co->order); - return 0; - } - - ADDMSG(&target->faction->msgs, msg_message( - "fumblecurse", "unit region", target, target->region)); - - return cast_level; -} - -void -patzer_fumblecurse(castorder *co) -{ - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int duration = (cast_level/2)+1; - double effect; - curse * c; - - effect = force*0.5; - c = create_curse(mage, &mage->attribs, ct_find("fumble"), force, - duration, effect, 0); - if (c!=NULL) { - ADDMSG(&mage->faction->msgs, msg_message( - "magic_fumble", "unit region command", - mage, mage->region, co->order)); - } - return; -} - -/* ------------------------------------------------------------- */ -/* Name: Drachenruf - * Stufe: 11 - * Gebiet: Draig - * Kategorie: Monster, Beschw�rung, negativ - * - * Wirkung: - * In einer W�ste, Sumpf oder Gletscher gezaubert kann innerhalb der - * n�chsten 6 Runden ein bis 6 Dracheneinheiten bis Gr��e Wyrm - * entstehen. - * - * Mit Stufe 12-15 erscheinen Jung- oder normaler Drachen, mit Stufe - * 16+ erscheinen normale Drachen oder Wyrme. - * - * Flag: - * (FARCASTING | REGIONSPELL | TESTRESISTANCE) - */ - -static int -sp_summondragon(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - unit *u; - int cast_level = co->level; - double power = co->force; - region_list *rl,*rl2; - faction *f; - int time; - int number; - const race * race; - - f = get_monsters(); - - if (r->terrain != newterrain(T_SWAMP) && r->terrain != newterrain(T_DESERT) - && r->terrain != newterrain(T_GLACIER)) { - report_failure(mage, co->order); - return 0; - } - - for(time = 1; time < 7; time++) { - if (rng_int()%100 < 25) { - switch(rng_int()%3) { - case 0: - race = new_race[RC_WYRM]; - number = 1; - break; - - case 1: - race = new_race[RC_DRAGON]; - number = 2; - break; - - case 2: - default: - race = new_race[RC_FIREDRAGON]; - number = 6; - break; - } - { - trigger * tsummon = trigger_createunit(r, f, race, number); - add_trigger(&r->attribs, "timer", trigger_timeout(time, tsummon)); - } - } - } - - rl = all_in_range(r, (short)power, NULL); - - for(rl2 = rl; rl2; rl2 = rl2->next) { - region * r2 = rl2->data; - for(u = r2->units; u; u = u->next) { - if (u->race == new_race[RC_WYRM] || u->race == new_race[RC_DRAGON]) { - attrib * a = a_find(u->attribs, &at_targetregion); - if (!a) { - a = a_add(&u->attribs, make_targetregion(co->rt)); - } else { - a->data.v = co->rt; - } - } - } - } - - ADDMSG(&mage->faction->msgs, msg_message( - "summondragon", "unit region command target", - mage, mage->region, co->order, co->rt)); - - free_regionlist(rl); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Feuerwand - * Stufe: - * Gebiet: Draig - * Kategorie: Region, negativ - * Flag: - * Kosten: SPC_LINEAR - * Aura: - * Komponenten: - * - * Wirkung: - * eine Wand aus Feuer entsteht in der angegebenen Richtung - * - * Was f�r eine Wirkung hat die? - */ - -void -wall_vigour(curse* c, double delta) -{ - wallcurse * wc = (wallcurse*)c->data.v; - assert(wc->buddy->vigour==c->vigour); - wc->buddy->vigour += delta; - if (wc->buddy->vigour<=0) { - erase_border(wc->wall); - wc->wall = NULL; - ((wallcurse*)wc->buddy->data.v)->wall = NULL; - } -} - -const curse_type ct_firewall = { - "Feuerwand", - CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR | NO_MERGE), - NULL, /* curseinfo */ - wall_vigour /* change_vigour */ -}; - -static int -sp_firewall(castorder *co) -{ - connection * b; - wall_data * fd; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - spellparameter *pa = co->par; - direction_t dir; - region * r2; - - dir = finddirection(pa->param[0]->data.xs, mage->faction->locale); - if (dir<MAXDIRECTIONS && dir!=NODIRECTION) { - r2 = rconnect(r, dir); - } else { - report_failure(mage, co->order); - return 0; - } - - if (!r2 || r2==r) { - report_failure(mage, co->order); - return 0; - } - - b = get_borders(r, r2); - while (b!=NULL) { - if (b->type == &bt_firewall) break; - b = b->next; - } - if (b==NULL) { - b = new_border(&bt_firewall, r, r2); - fd = (wall_data*)b->data.v; - fd->force = (int)(force/2+0.5); - fd->mage = mage; - fd->active = false; - fd->countdown = cast_level+1; - } else { - fd = (wall_data*)b->data.v; - fd->force = (int)MAX(fd->force, force/2+0.5); - fd->countdown = MAX(fd->countdown, cast_level+1); - } - - /* melden, 1x pro Partei */ - { - message * seen = msg_message("firewall_effect", "mage region", mage, r); - message * unseen = msg_message("firewall_effect", "mage region", NULL, r); - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); - } - - return cast_level; -} - -/* ------------------------------------------------------------- */ - -static int -sp_wisps(castorder *co) -{ - connection * b; - wall_data * fd; - region * r2; - direction_t dir; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - spellparameter *pa = co->par; - - dir = finddirection(pa->param[0]->data.xs, mage->faction->locale); - r2 = rconnect(r, dir); - - if (!r2) { - report_failure(mage, co->order); - return 0; - } - - b = new_border(&bt_wisps, r, r2); - fd = (wall_data*)b->data.v; - fd->force = (int)(force/2+0.5); - fd->mage = mage; - fd->active = false; - fd->countdown = cast_level+1; - - /* melden, 1x pro Partei */ - { - message * seen = msg_message("wisps_effect", "mage region", mage, r); - message * unseen = msg_message("wisps_effect", "mage region", NULL, r); - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); - } - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Unheilige Kraft - * Stufe: 10 - * Gebiet: Draig - * Kategorie: Untote Einheit, positiv - * - * Wirkung: - * transformiert (Stufe)W10 Untote in ihre st�rkere Form - * - * - * Flag: - * (SPELLLEVEL | TESTCANSEE) - */ - -static int -sp_unholypower(castorder *co) -{ - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - int i; - int n; - int wounds; - - n = dice((int)co->force, 10); - - for (i = 0; i < pa->length && n > 0; i++) { - const race * target_race; - unit *u; - - if (pa->param[i]->flag == TARGET_RESISTS - || pa->param[i]->flag == TARGET_NOTFOUND) - continue; - - u = pa->param[i]->data.u; - - switch (old_race(u->race)) { - case RC_SKELETON: - target_race = new_race[RC_SKELETON_LORD]; - break; - case RC_ZOMBIE: - target_race = new_race[RC_ZOMBIE_LORD]; - break; - case RC_GHOUL: - target_race = new_race[RC_GHOUL_LORD]; - break; - default: - cmistake(mage, co->order, 284, MSG_MAGIC); - continue; - } - /* Untote heilen nicht, darum den neuen Untoten maximale hp geben - * und vorhandene Wunden abziehen */ - wounds = unit_max_hp(u)*u->number - u->hp; - - if (u->number <= n) { - n -= u->number; - u->irace = NULL; - u->race = target_race; - u->hp = unit_max_hp(u)*u->number - wounds; - ADDMSG(&co->rt->msgs, msg_message("unholypower_effect", - "mage target race", mage, u, target_race)); - } else { - unit *un; - - /* Wird hoffentlich niemals vorkommen. Es gibt im Source - * vermutlich eine ganze Reihe von Stellen, wo das nicht - * korrekt abgefangen wird. Besser (aber nicht gerade einfach) - * w�re es, eine solche Konstruktion irgendwie zu kapseln. */ - if (fval(u, UFL_LOCKED) || fval(u, UFL_HUNGER) - || is_cursed(u->attribs, C_SLAVE, 0)) { - cmistake(mage, co->order, 74, MSG_MAGIC); - continue; - } - /* Verletzungsanteil der transferierten Personen berechnen */ - wounds = wounds*n/u->number; - - un = create_unit(co->rt, u->faction, 0, target_race, 0, NULL, u); - transfermen(u, un, n); - un->hp = unit_max_hp(un)*n - wounds; - ADDMSG(&co->rt->msgs, msg_message("unholypower_limitedeffect", - "mage target race amount", - mage, u, target_race, n)); - n = 0; - } - } - - return cast_level; -} - -static int -dc_age(struct curse * c) -/* age returns 0 if the attribute needs to be removed, !=0 otherwise */ -{ - region * r = (region*)c->data.v; - unit **up; - unit * mage = c->magician; - - if (r==NULL || mage==NULL || mage->number==0) { - /* if the mage disappears, so does the spell. */ - return AT_AGE_REMOVE; - } - - up = &r->units; - if (curse_active(c)) while (*up!=NULL) { - unit * u = *up; - double damage = c->effect * u->number; - - freset(u->faction, FFL_SELECT); - if (u->number<=0 || target_resists_magic(mage, u, TYP_UNIT, 0)) { - up=&u->next; - continue; - } - - /* Reduziert durch Magieresistenz */ - damage *= (1.0 - magic_resistance(u)); - change_hitpoints(u, -(int)damage); - - if (*up==u) up=&u->next; - } - - return AT_AGE_KEEP; -} - -static struct curse_type ct_deathcloud = { - "deathcloud", CURSETYP_REGION, 0, NO_MERGE, cinfo_simple, NULL, NULL, NULL, NULL, dc_age -}; - -static curse * -mk_deathcloud(unit * mage, region * r, double force, int duration) -{ - double effect; - curse * c; - - effect = force * 0.5; - c = create_curse(mage, &r->attribs, &ct_deathcloud, force, duration, effect, 0); - c->data.v = r; - return c; -} - -#define COMPAT_DEATHCLOUD -#ifdef COMPAT_DEATHCLOUD -static int -dc_read_compat(struct attrib * a, void * target, storage * store) -/* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */ -{ - region * r = NULL; - unit * u; - variant var; - int duration = store->r_int(store); - double strength = store->r_flt(store); - short rx, ry; - - var.i = store->r_id(store); - u = findunit(var.i); - - /* this only affects really old data. no need to change: */ - rx = (short)store->r_int(store); - ry = (short)store->r_int(store); - r = findregion(rx, ry); - - if (r!=NULL) { - double effect; - curse * c; - - effect = strength; - c = create_curse(u, &r->attribs, &ct_deathcloud, strength * 2, duration, effect, 0); - c->data.v = r; - if (u==NULL) { - ur_add(var, &c->magician, resolve_unit); - } - } - return AT_READ_FAIL; /* we don't care for the attribute. */ -} - - -attrib_type at_deathcloud_compat = { - "zauber_todeswolke", NULL, NULL, NULL, NULL, dc_read_compat -}; -#endif - -/* ------------------------------------------------------------- */ -/* Name: Todeswolke -* Stufe: 11 -* Gebiet: Draig -* Kategorie: Region, negativ -* -* Wirkung: -* Personen in der Region verlieren stufe/2 Trefferpunkte pro Runde. -* Dauer force/2 -* Wirkt gegen MR -* R�stung wirkt nicht -* Patzer: -* Magier ger�t in den Staub und verliert zuf�llige Zahl von HP bis -* auf MAX(hp,2) -* Besonderheiten: -* Nicht als curse implementiert, was schlecht ist - man kann dadurch -* kein dispell machen. Wegen fix unter Zeitdruck erstmal nicht zu -* �ndern... -* Missbrauchsm�glichkeit: -* Hat der Magier mehr HP als Rasse des Feindes (extrem: D�mon/Goblin) -* so kann er per Farcasting durch mehrmaliges Zaubern eine -* Nachbarregion ausl�schen. Darum sollte dieser Spruch nur einmal auf -* eine Region gelegt werden k�nnen. -* -* Flag: -* (FARCASTING | REGIONSPELL | TESTRESISTANCE) -*/ - -static int -sp_deathcloud(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - attrib *a = r->attribs; - unit * u; - - while (a) { - if ((a->type->flags & ATF_CURSE)) { - curse * c = a->data.v; - if (c->type==&ct_deathcloud) { - report_failure(mage, co->order); - return 0; - } - a = a->next; - } - else a = a->nexttype; - } - - mk_deathcloud(mage, r, co->force, co->level); - - /* melden, 1x pro Partei */ - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - for (u = r->units; u; u = u->next ) { - if (!fval(u->faction, FFL_SELECT) ) { - fset(u->faction, FFL_SELECT); - ADDMSG(&u->faction->msgs, msg_message("deathcloud_effect", - "mage region", cansee(u->faction, r, mage, 0) ? mage : NULL, r)); - } - } - - if (!fval(mage->faction, FFL_SELECT)) { - ADDMSG(&mage->faction->msgs, msg_message("deathcloud_effect", - "mage region", mage, r)); - } - - return co->level; -} - -void -patzer_deathcloud(castorder *co) -{ - unit *mage = co->magician.u; - int hp = (mage->hp - 2); - - change_hitpoints(mage, -rng_int()%hp); - - ADDMSG(&mage->faction->msgs, msg_message( - "magic_fumble", "unit region command", - mage, mage->region, co->order)); - - return; -} - -/* ------------------------------------------------------------- */ -/* Name: Pest - * Stufe: 7 - * Gebiet: Draig - * Wirkung: - * ruft eine Pest in der Region hervor. - * Flags: - * (FARCASTING | REGIONSPELL | TESTRESISTANCE) - * Syntax: ZAUBER [REGION x y] "Pest" - */ -static int -sp_plague(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - - plagues(r, true); - - ADDMSG(&mage->faction->msgs, msg_message("plague_spell", - "region mage", r, mage)); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Beschw�re Schattend�mon - * Stufe: 8 - * Gebiet: Draig - * Kategorie: Beschw�rung, positiv - * Wirkung: - * Der Magier beschw�rt Stufe^2 Schattend�monen. - * Schattend�monen haben Tarnung = (Magie_Magier+ Tarnung_Magier)/2 und - * Wahrnehmung 1. Sie haben einen Attacke-Bonus von 8, einen - * Verteidigungsbonus von 11 und machen 2d3 Schaden. Sie entziehen bei - * einem Treffer dem Getroffenen einen Attacke- oder - * Verteidigungspunkt. (50% Chance.) Sie haben 25 Hitpoints und - * R�stungsschutz 3. - * Flag: - * (SPELLLEVEL) - */ -static int -sp_summonshadow(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - unit *u; - int val, number = (int)(force*force); - - u = create_unit(r, mage->faction, number, new_race[RC_SHADOW], 0, NULL, mage); - - /* Bekommen Tarnung = (Magie+Tarnung)/2 und Wahrnehmung 1. */ - val = get_level(mage, SK_MAGIC) + get_level(mage, SK_STEALTH); - - set_level(u, SK_STEALTH, val); - set_level(u, SK_PERCEPTION, 1); - - ADDMSG(&mage->faction->msgs, msg_message("summonshadow_effect", - "mage number", mage, number)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Beschw�re Schattenmeister - * Stufe: 12 - * Gebiet: Draig - * Kategorie: Beschw�rung, positiv - * Wirkung: - * Diese h�heren Schattend�monen sind erheblich gef�hrlicher als die - * einfachen Schattend�monen. Sie haben Tarnung entsprechend dem - * Magietalent des Beschw�rer-1 und Wahrnehmung 5, 75 HP, - * R�stungsschutz 4, Attacke-Bonus 11 und Verteidigungsbonus 13, machen - * bei einem Treffer 2d4 Schaden, entziehen einen St�rkepunkt und - * entziehen 5 Talenttage in einem zuf�lligen Talent. - * Stufe^2 D�monen. - * - * Flag: - * (SPELLLEVEL) - * */ -static int -sp_summonshadowlords(castorder *co) -{ - unit *u; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int amount = (int)(force*force); - - u = create_unit(r, mage->faction, amount, new_race[RC_SHADOWLORD], 0, NULL, mage); - - /* Bekommen Tarnung = Magie und Wahrnehmung 5. */ - set_level(u, SK_STEALTH, get_level(mage, SK_MAGIC)); - set_level(u, SK_PERCEPTION, 5); - - ADDMSG(&mage->faction->msgs, msg_message("summon_effect", "mage amount race", mage, amount, u->race)); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Chaossog - * Stufe: 14 - * Gebiet: Draig - * Kategorie: Teleport - * Wirkung: - * Durch das Opfern von 200 Bauern kann der Chaosmagier ein Tor zur - * astralen Welt �ffnen. Das Tor kann im Folgemonat verwendet werden, - * es l�st sich am Ende des Folgemonats auf. - * - * Flag: (0) - */ -static int -sp_chaossuction(castorder *co) -{ - region *rt; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - - if (getplane(r)!=get_normalplane()) { - /* Der Zauber funktioniert nur in der materiellen Welt. */ - cmistake(mage, co->order, 190, MSG_MAGIC); - return 0; - } - - rt = r_standard_to_astral(r); - - if (rt==NULL || fval(rt->terrain, FORBIDDEN_REGION)) { - /* Hier gibt es keine Verbindung zur astralen Welt.*/ - cmistake(mage, co->order, 216, MSG_MAGIC); - return 0; - } else if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); - return 0; - } - - /* TODO: implement with a building */ - create_special_direction(r, rt, 2, "vortex_desc", "vortex"); - create_special_direction(rt, r, 2, "vortex_desc", "vortex"); - new_border(&bt_chaosgate, r, rt); - - add_message(&r->msgs, msg_message("chaosgate_effect_1", "mage", mage)); - add_message(&rt->msgs, msg_message("chaosgate_effect_2", "")); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Magic Boost - Gabe des Chaos - * Stufe: 3 - * Gebiet: Draig - * Kategorie: Einheit, positiv - * - * Wirkung: - * Erh�ht die maximalen Magiepunkte und die monatliche Regeneration auf - * das doppelte. Dauer: 4 Wochen Danach sinkt beides auf die H�lfte des - * normalen ab. - * Dauer: 6 Wochen - * Patzer: - * permanenter Stufen- (Talenttage), Regenerations- oder maxMP-Verlust - * Besonderheiten: - * Patzer k�nnen w�hrend der Zauberdauer h�ufiger auftreten derzeit - * +10% - * - * Flag: - * (ONSHIPCAST) - */ - -static int -sp_magicboost(castorder *co) -{ - curse * c; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - double effect; - trigger * tsummon; - static const curse_type * ct_auraboost; - static const curse_type * ct_magicboost; - - if (!ct_auraboost) { - ct_auraboost = ct_find("auraboost"); - ct_magicboost = ct_find("magicboost"); - assert(ct_auraboost!=NULL); - assert(ct_magicboost!=NULL); - } - /* fehler, wenn schon ein boost */ - if (is_cursed(mage->attribs, C_MBOOST, 0) == true) { - report_failure(mage, co->order); - return 0; - } - - effect = 6; - c = create_curse(mage, &mage->attribs, ct_magicboost, power, 10, effect, 1); - - /* one aura boost with 200% aura now: */ - effect = 200; - c = create_curse(mage, &mage->attribs, ct_auraboost, power, 4, effect, 1); - - /* and one aura boost with 50% aura in 5 weeks: */ - tsummon = trigger_createcurse(mage, mage, ct_auraboost, power, 6, 50, 1); - add_trigger(&mage->attribs, "timer", trigger_timeout(5, tsummon)); - - ADDMSG(&mage->faction->msgs, msg_message("magicboost_effect", - "unit region command", mage, mage->region, co->order)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: kleines Blutopfer - * Stufe: 4 - * Gebiet: Draig - * Kategorie: Einheit, positiv - * - * Wirkung: - * Hitpoints to Aura: - * skill < 8 = 4:1 - * skill < 12 = 3:1 - * skill < 15 = 2:1 - * skill < 18 = 1:2 - * skill > = 2:1 - * Patzer: - * permanenter HP verlust - * - * Flag: - * (ONSHIPCAST) - */ -static int -sp_bloodsacrifice(castorder *co) -{ - unit *mage = co->magician.u; - int cast_level = co->level; - int aura; - int skill = eff_skill(mage, SK_MAGIC, mage->region); - int hp = (int)(co->force*8); - - if (hp <= 0) { - report_failure(mage, co->order); - return 0; - } - - aura = lovar(hp); - - if (skill < 8) { - aura /= 4; - } else if (skill < 12) { - aura /= 3; - } else if (skill < 15) { - aura /= 2; - /* von 15 bis 17 ist hp = aura */ - } else if (skill > 17) { - aura *= 2; - } - - if (aura <= 0) { - report_failure(mage, co->order); - return 0; - } - - /* sicherheitshalber gibs hier einen HP gratis. sonst schaffen es - * garantiert ne ganze reihe von leuten ihren Magier damit umzubringen */ - mage->hp++; - change_spellpoints(mage, aura); - ADDMSG(&mage->faction->msgs, - msg_message("sp_bloodsacrifice_effect", - "unit region command amount", - mage, mage->region, co->order, aura)); - return cast_level; -} - -/** gives a summoned undead unit some base skills. - */ -static void -skill_summoned(unit * u, int level) -{ - if (level>0) { - const race * rc = u->race; - skill_t sk; - for (sk=0;sk!=MAXSKILLS;++sk) { - if (rc->bonus[sk]>0) { - set_level(u, sk, level); - } - } - } -} - -/* ------------------------------------------------------------- */ -/* Name: Totenruf - M�chte des Todes - * Stufe: 6 - * Gebiet: Draig - * Kategorie: Beschw�rung, positiv - * Flag: FARCASTING - * Wirkung: - * Untote aus deathcounther ziehen, bis Stufe*10 St�ck - * - * Patzer: - * Erzeugt Monsteruntote - */ -static int -sp_summonundead(castorder *co) -{ - int undead; - unit *u; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - int force = (int)(co->force*10); - const race * race = new_race[RC_SKELETON]; - - if (!r->land || deathcount(r) == 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_nograves", "target", r)); - return 0; - } - - undead = MIN(deathcount(r), 2 + lovar(force)); - - if (cast_level <= 8) { - race = new_race[RC_SKELETON]; - } else if (cast_level <= 12) { - race = new_race[RC_ZOMBIE]; - } else { - race = new_race[RC_GHOUL]; - } - - u = create_unit(r, mage->faction, undead, race, 0, NULL, mage); - make_undead_unit(u); - skill_summoned(u, cast_level/2); - - ADDMSG(&mage->faction->msgs, msg_message("summonundead_effect_1", "mage region amount", mage, r, undead)); - ADDMSG(&r->msgs, msg_message("summonundead_effect_2", "mage region", mage, r)); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Astraler Sog - * Stufe: 9 - * Gebiet: Draig - * Kategorie: Region, negativ - * Wirkung: - * Allen Magier in der betroffenen Region wird eine Teil ihrer - * Magischen Kraft in die Gefilde des Chaos entzogen Jeder Magier im - * Einflussbereich verliert Stufe(Zaubernden)*5% seiner Magiepunkte. - * Keine Regeneration in der Woche (fehlt noch) - * - * Flag: - * (REGIONSPELL | TESTRESISTANCE) - */ - -static int -sp_auraleak(castorder *co) -{ - int lost_aura; - double lost; - unit *u; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - message * msg; - - lost = MIN(0.95, cast_level * 0.05); - - for (u = r->units; u; u = u->next) { - if (is_mage(u)) { - /* Magieresistenz Einheit? Bei gegenerischen Magiern nur sehr - * geringe Chance auf Erfolg wg erh�hter MR, w�rde Spruch sinnlos - * machen */ - lost_aura = (int)(get_spellpoints(u)*lost); - change_spellpoints(u, -lost_aura); - } - } - msg = msg_message("cast_auraleak_effect", "mage region", mage, r); - r_addmessage(r, NULL, msg); - msg_release(msg); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* BARDE - CERDDOR*/ -/* ------------------------------------------------------------- */ -/* ------------------------------------------------------------- */ -/* Name: Magie analysieren - Geb�ude, Schiffe, Region - * Name: Lied des Ortes analysieren - * Stufe: 8 - * Gebiet: Cerddor - * - * Wirkung: - * Zeigt die Verzauberungen eines Objekts an (curse->name, - * curse::info). Aus der Differenz Spruchst�rke und Curse->vigour - * ergibt sich die Chance den Spruch zu identifizieren ((force - - * c->vigour)*10 + 100 %). - * - * Flag: - * (SPELLLEVEL|ONSHIPCAST) - */ -static int -sp_analysesong_obj(castorder *co) -{ - int obj; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - spellparameter *pa = co->par; - - obj = pa->param[0]->typ; - - switch(obj) { - case SPP_REGION: - magicanalyse_region(r, mage, force); - break; - - case SPP_BUILDING: - { - building *b = pa->param[0]->data.b; - magicanalyse_building(b, mage, force); - break; - } - case SPP_SHIP: - { - ship * sh = pa->param[0]->data.sh; - magicanalyse_ship(sh, mage, force); - break; - } - default: - /* Syntax fehlerhaft */ - return 0; - } - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Gesang des Lebens analysieren - * Name: Magie analysieren - Unit - * Stufe: 5 - * Gebiet: Cerddor - * Wirkung: - * Zeigt die Verzauberungen eines Objekts an (curse->name, - * curse::info). Aus der Differenz Spruchst�rke und Curse->vigour - * ergibt sich die Chance den Spruch zu identifizieren ((force - - * c->vigour)*10 + 100 %). - * - * Flag: - * (UNITSPELL|ONSHIPCAST|TESTCANSEE) - */ -static int -sp_analysesong_unit(castorder *co) -{ - unit *u; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - spellparameter *pa = co->par; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber - * abbrechen aber kosten lassen */ - if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; - - u = pa->param[0]->data.u; - - magicanalyse_unit(u, mage, force); - - return cast_level; -} - -static boolean -can_charm(const unit * u, int maxlevel) -{ - const skill_t expskills[] = { SK_ALCHEMY, SK_HERBALISM, SK_MAGIC, SK_SPY, SK_TACTICS, NOSKILL }; - skill * sv = u->skills; - - if (fval(u, UFL_HERO)) return false; - - for (;sv!=u->skills+u->skill_size;++sv) { - int l = 0, h = 5; - skill_t sk = sv->id; - assert(expskills[h]==NOSKILL); - while (l<h) { - int m = (l+h)/2; - if (sk==expskills[m]) { - if (skill_limit(u->faction, sk)!=INT_MAX) { - return false; - } else if ((int)sv->level>maxlevel) { - return false; - } - break; - } - else if (sk>expskills[m]) l=m+1; - else h=m; - } - } - return true; -} -/* ------------------------------------------------------------- */ -/* Name: Charming - * Stufe: 13 - * Gebiet: Cerddor - * Flag: UNITSPELL - * Wirkung: - * bezauberte Einheit wechselt 'virtuell' die Partei und f�hrt fremde - * Befehle aus. - * Dauer: 3 - force+2 Wochen - * Wirkt gegen Magieresistenz - * - * wirkt auf eine Einheit mit maximal Talent Personen normal. F�r jede - * zus�tzliche Person gibt es einen Bonus auf Magieresistenz, also auf - * nichtgelingen, von 10%. - * - * Das h�chste Talent der Einheit darf maximal so hoch sein wie das - * Magietalent des Magiers. F�r jeden Talentpunkt mehr gibt es einen - * Bonus auf Magieresistenz von 15%, was dazu f�hrt, das bei +2 Stufen - * die Magiersistenz bei 90% liegt. - * - * Migrantenz�hlung muss Einheit �berspringen - * - * Attackiere verbieten - * Flags: - * (UNITSPELL | TESTCANSEE) - */ -static int -sp_charmingsong(castorder *co) -{ - unit *target; - int duration; - skill_t i; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - spellparameter *pa = co->par; - int resist_bonus = 0; - int tb = 0; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - target = pa->param[0]->data.u; - - /* Auf eigene Einheiten versucht zu zaubern? Garantiert Tippfehler */ - if (target->faction == mage->faction) { - /* Die Einheit ist eine der unsrigen */ - cmistake(mage, co->order, 45, MSG_MAGIC); - } - /* niemand mit teurem Talent */ - if (!can_charm(target, cast_level/2)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, - "spellfail_noexpensives", "target", target)); - return 0; - } - - /* Magieresistensbonus f�r mehr als Stufe Personen */ - if (target->number > force) { - resist_bonus += (int)((target->number - force) * 10); - } - /* Magieresistensbonus f�r h�here Talentwerte */ - for(i = 0; i < MAXSKILLS; i++) { - int sk = effskill(target, i); - if (tb < sk) tb = sk; - } - tb -= effskill(mage, SK_MAGIC); - if (tb > 0) { - resist_bonus += tb * 15; - } - /* Magieresistenz */ - if (target_resists_magic(mage, target, TYP_UNIT, resist_bonus)) { - report_failure(mage, co->order); -#if 0 - sprintf(buf, "%s f�hlt sich einen Moment lang benommen und desorientiert.", - unitname(target)); - addmessage(target->region, target->faction, buf, MSG_EVENT, ML_WARN); -#endif - return 0; - } - - duration = 3 + rng_int()%(int)force; - { - trigger * trestore = trigger_changefaction(target, target->faction); - /* l�uft die Dauer ab, setze Partei zur�ck */ - add_trigger(&target->attribs, "timer", trigger_timeout(duration, trestore)); - /* wird die alte Partei von Target aufgel�st, dann auch diese Einheit */ - add_trigger(&target->faction->attribs, "destroy", trigger_killunit(target)); - /* wird die neue Partei von Target aufgel�st, dann auch diese Einheit */ - add_trigger(&mage->faction->attribs, "destroy", trigger_killunit(target)); - } - /* sperre ATTACKIERE, GIB PERSON und �berspringe Migranten */ - create_curse(mage, &target->attribs, ct_find("slavery"), force, duration, zero_effect, 0); - - /* setze Partei um und l�sche langen Befehl aus Sicherheitsgr�nden */ - u_setfaction(target, mage->faction); - set_order(&target->thisorder, NULL); - - /* setze Parteitarnung, damit nicht sofort klar ist, wer dahinter - * steckt */ - if (rule_stealth_faction()) { - fset(target, UFL_ANON_FACTION); - } - - ADDMSG(&mage->faction->msgs, msg_message("charming_effect", "mage unit duration", mage, target, duration)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Gesang des wachen Geistes - * Stufe: 10 - * Gebiet: Cerddor - * Kosten: SPC_LEVEL - * Wirkung: - * Bringt einmaligen Bonus von +15% auf Magieresistenz. Wirkt auf alle - * Aliierten (HELFE BEWACHE) in der Region. - * Dauert Stufe Wochen an, ist nicht kumulativ. - * Flag: - * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) - */ -static int -sp_song_resistmagic(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int duration = (int)force+1; - - create_curse(mage, &r->attribs, ct_find("goodmagicresistancezone"), - force, duration, 15, 0); - - /* Erfolg melden */ - ADDMSG(&mage->faction->msgs, msg_message( - "regionmagic_effect", "unit region command", mage, - mage->region, co->order)); - - return cast_level; -} -/* ------------------------------------------------------------- */ -/* Name: Gesang des schwachen Geistes - * Stufe: 12 - * Gebiet: Cerddor - * Wirkung: - * Bringt einmaligen Malus von -15% auf Magieresistenz. - * Wirkt auf alle Nicht-Aliierten (HELFE BEWACHE) in der Region. - * Dauert Stufe Wochen an, ist nicht kumulativ. - * Flag: - * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) - */ -static int -sp_song_susceptmagic(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int duration = (int)force+1; - - create_curse(mage, &r->attribs, ct_find("badmagicresistancezone"), - force, duration, 15, 0); - - ADDMSG(&mage->faction->msgs, msg_message( - "regionmagic_effect", "unit region command", mage, - mage->region, co->order)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Aufruhr beschwichtigen - * Stufe: 15 - * Gebiet: Cerddor - * Flag: FARCASTING - * Wirkung: - * zerstreut einen Monsterbauernmob, Antimagie zu 'Aufruhr - * verursachen' - */ - -static int -sp_rallypeasantmob(castorder *co) -{ - unit *u, *un; - int erfolg = 0; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - message * msg; - curse * c; - - for (u = r->units; u; u = un) { - un = u->next; - if (is_monsters(u->faction) && u->race == new_race[RC_PEASANT]) { - rsetpeasants(r, rpeasants(r) + u->number); - rsetmoney(r, rmoney(r) + get_money(u)); - set_money(u, 0); - setguard(u, GUARD_NONE); - set_number(u, 0); - erfolg = cast_level; - } - } - - c = get_curse(r->attribs, ct_find(oldcursename(C_RIOT))); - if (c!=NULL) { - remove_curse(&r->attribs, c); - } - - msg = msg_message("cast_rally_effect", "mage region", mage, r); - r_addmessage(r, NULL, msg); - msg_release(msg); - return erfolg; -} - -/* ------------------------------------------------------------- */ -/* Name: Aufruhr verursachen - * Stufe: 16 - * Gebiet: Cerddor - * Wirkung: - * Wiegelt 60% bis 90% der Bauern einer Region auf. Bauern werden ein - * gro�er Mob, der zur Monsterpartei geh�rt und die Region bewacht. - * Regionssilber sollte auch nicht durch Unterhaltung gewonnen werden - * k�nnen. - * - * Fehlt: Triggeraktion: l�ste Bauernmob auf und gib alles an Region, - * dann k�nnen die Bauernmobs ihr Silber mitnehmen und bleiben x - * Wochen bestehen - * - * alternativ: L�sen sich langsam wieder auf - * Flag: - * (FARCASTING | REGIONSPELL | TESTRESISTANCE) - */ -static int -sp_raisepeasantmob(castorder *co) -{ - unit *u; - attrib *a; - int n; - int anteil; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int duration = (int)force+1; - faction * monsters = get_monsters(); - message * msg; - - anteil = 6 + (rng_int()%4); - - n = rpeasants(r) * anteil / 10; - n = MAX(0, n); - n = MIN(n, rpeasants(r)); - - if (n <= 0) { - report_failure(mage, co->order); - return 0; - } - - rsetpeasants(r, rpeasants(r) - n); - assert(rpeasants(r) >= 0); - - u = create_unit(r, monsters, n, new_race[RC_PEASANT], 0, LOC(monsters->locale, "furious_mob"), NULL); - fset(u, UFL_ISNEW); - guard(u, GUARD_ALL); - a = a_new(&at_unitdissolve); - a->data.ca[0] = 1; /* An rpeasants(r). */ - a->data.ca[1] = 15; /* 15% */ - a_add(&u->attribs, a); - - create_curse(mage, &r->attribs, ct_find("riotzone"), cast_level, duration, (double)anteil, 0); - - msg = msg_message("sp_raisepeasantmob_effect", "mage region", mage, r); - report_spell(mage, r, msg); - msg_release(msg); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Ritual der Aufnahme / Migrantenwerben - * Stufe: 9 - * Gebiet: Cerddor - * Wirkung: - * Bis zu Stufe Personen fremder Rasse k�nnen angeworben werden. Die - * angeworbene Einheit muss kontaktieren. Keine teuren Talente - * - * Flag: - * (UNITSPELL | SPELLLEVEL | TESTCANSEE) - */ -static int -sp_migranten(castorder *co) -{ - unit *target; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - target = pa->param[0]->data.u; /* Zieleinheit */ - - /* Personen unserer Rasse k�nnen problemlos normal �bergeben werden */ - if (target->race == mage->faction->race) { - /* u ist von unserer Art, das Ritual w�re verschwendete Aura. */ - ADDMSG(&mage->faction->msgs, msg_message( - "sp_migranten_fail1", "unit region command target", mage, - mage->region, co->order, target)); - } - /* Auf eigene Einheiten versucht zu zaubern? Garantiert Tippfehler */ - if (target->faction == mage->faction) { - cmistake(mage, co->order, 45, MSG_MAGIC); - } - - /* Keine Monstereinheiten */ - if (!playerrace(target->race)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, - "spellfail_nomonsters", "")); - return 0; - } - /* niemand mit teurem Talent */ - if (has_limited_skills(target)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, - "spellfail_noexpensives", "target", target)); - return 0; - } - /* maximal Stufe Personen */ - if (target->number > cast_level - || target->number > max_spellpoints(r, mage)) - { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, - "spellfail_toomanytargets", "")); - return 0; - } - - /* Kontakt pr�fen (aus alter Teleportroutine �bernommen) */ - if (!ucontact(target, mage)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, - "spellfail::contact", "target", target)); - return 0; - } - u_setfaction(target,mage->faction); - set_order(&target->thisorder, NULL); - - /* Erfolg melden */ - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "sp_migranten", - "target", target)); - - return target->number; -} - -/* ------------------------------------------------------------- */ -/* Name: Gesang der Friedfertigkeit - * Stufe: 12 - * Gebiet: Cerddor - * Wirkung: - * verhindert jede Attacke f�r lovar(Stufe/2) Runden - */ - -static int -sp_song_of_peace(castorder *co) -{ - unit *u; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int duration = 2 + lovar(force/2); - message * msg[2] = { NULL, NULL }; - - create_curse(mage, &r->attribs, ct_find("peacezone"), force, duration, zero_effect, 0); - - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - for (u = r->units; u; u = u->next ) { - if (!fval(u->faction, FFL_SELECT) ) { - message * m = NULL; - fset(u->faction, FFL_SELECT); - if (cansee(u->faction, r, mage, 0)) { - if (msg[0]==NULL) msg[0] = msg_message("song_of_peace_effect_0", "mage", mage); - m = msg[0]; - } else { - if (msg[1]==NULL) msg[1] = msg_message("song_of_peace_effect_1", ""); - m = msg[1]; - } - r_addmessage(r, u->faction, m); - } - } - if (msg[0]) msg_release(msg[0]); - if (msg[1]) msg_release(msg[1]); - return cast_level; - -} - -/* ------------------------------------------------------------- */ -/* Name: Hohes Lied der Gaukelei - * Stufe: 2 - * Gebiet: Cerddor - * Wirkung: - * Das Unterhaltungsmaximum steigt von 20% auf 40% des - * Regionsverm�gens. Der Spruch h�lt Stufe Wochen an - */ - -static int -sp_generous(castorder *co) -{ - unit *u; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int duration = (int)force+1; - double effect; - message * msg[2] = { NULL, NULL }; - - if (is_cursed(r->attribs, C_DEPRESSION, 0)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_generous", "")); - return 0; - } - - effect = 2; - create_curse(mage,&r->attribs, ct_find("generous"), force, duration, effect, 0); - - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - for (u = r->units; u; u = u->next ) { - if (!fval(u->faction, FFL_SELECT) ) { - message * m = NULL; - fset(u->faction, FFL_SELECT); - if (cansee(u->faction, r, mage, 0)) { - if (msg[0]==NULL) msg[0] = msg_message("generous_effect_0", "mage", mage); - m = msg[0]; - } else { - if (msg[1]==NULL) msg[1] = msg_message("generous_effect_1", ""); - m = msg[1]; - } - r_addmessage(r, u->faction, m); - } - } - if (msg[0]) msg_release(msg[0]); - if (msg[1]) msg_release(msg[1]); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Anwerbung - * Stufe: 4 - * Gebiet: Cerddor - * Wirkung: - * Bauern schliessen sich der eigenen Partei an - * ist zus�tzlich zur Rekrutierungsmenge in der Region - * */ - -static int -sp_recruit(castorder *co) -{ - unit *u; - region *r = co->rt; - int num, maxp = rpeasants(r); - double n; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - faction *f = mage->faction; - const struct race * rc = f->race; - - if (maxp == 0) { - report_failure(mage, co->order); - return 0; - } - /* Immer noch zuviel auf niedrigen Stufen. Deshalb die Rekrutierungskosten - * mit einfliessen lassen und daf�r den Exponenten etwas gr��er. - * Wenn die Rekrutierungskosten deutlich h�her sind als der Faktor, - * ist das Verh�ltniss von ausgegebene Aura pro Bauer bei Stufe 2 - * ein mehrfaches von Stufe 1, denn in beiden F�llen gibt es nur 1 - * Bauer, nur die Kosten steigen. */ - n = (pow(force, 1.6) * 100)/f->race->recruitcost; - if (rc->recruit_multi!=0) { - double multp = maxp/rc->recruit_multi; - n = MIN(multp, n); - n = MAX(n, 1); - rsetpeasants(r, maxp - (int)(n * rc->recruit_multi)); - } else { - n = MIN(maxp, n); - n = MAX(n, 1); - rsetpeasants(r, maxp - (int)n); - } - - num = (int)n; - u = create_unit(r, f, num, f->race, 0, LOC(f->locale,(num == 1 ? "peasant" : "peasant_p")), mage); - set_order(&u->thisorder, default_order(f->locale)); - - ADDMSG(&mage->faction->msgs, msg_message("recruit_effect", "mage amount", mage, num)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Wanderprediger - Gro�e Anwerbung - * Stufe: 14 - * Gebiet: Cerddor - * Wirkung: - * Bauern schliessen sich der eigenen Partei an - * ist zus�tzlich zur Rekrutierungsmenge in der Region - * */ - -static int -sp_bigrecruit(castorder *co) -{ - unit *u; - region *r = co->rt; - int n, maxp = rpeasants(r); - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - faction *f = mage->faction; - message * msg; - - if (maxp <= 0) { - report_failure(mage, co->order); - return 0; - } - /* F�r vergleichbare Erfolge bei unterschiedlichen Rassen die - * Rekrutierungskosten mit einfliessen lassen. */ - - n = (int)force + lovar((force * force * 1000)/f->race->recruitcost); - if (f->race==new_race[RC_ORC]) { - n = MIN(2*maxp, n); - n = MAX(n, 1); - rsetpeasants(r, maxp - (n+1) / 2); - } else { - n = MIN(maxp, n); - n = MAX(n, 1); - rsetpeasants(r, maxp - n); - } - - u = create_unit(r, f, n, f->race, 0, LOC(f->locale,(n == 1 ? "peasant" : "peasant_p")), mage); - set_order(&u->thisorder, default_order(f->locale)); - - msg = msg_message("recruit_effect", "mage amount", mage, n); - r_addmessage(r, mage->faction, msg); - msg_release(msg); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Aushorchen - * Stufe: 7 - * Gebiet: Cerddor - * Wirkung: - * Erliegt die Einheit dem Zauber, so wird sie dem Magier alles - * erz�hlen, was sie �ber die gefragte Region wei�. Ist in der Region - * niemand ihrer Partei, so wei� sie nichts zu berichten. Auch kann - * sie nur das erz�hlen, was sie selber sehen k�nnte. - * Flags: - * (UNITSPELL | TESTCANSEE) - */ - -/* restistenz der einheit pr�fen */ -static int -sp_pump(castorder *co) -{ - unit *u, *target; - region *rt; - boolean see = false; - unit *mage = co->magician.u; - spellparameter *pa = co->par; - int cast_level = co->level; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - target = pa->param[0]->data.u; /* Zieleinheit */ - - if (fval(target->race, RCF_UNDEAD)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_not_on_undead", "")); - return 0; - } - if (is_magic_resistant(mage, target, 0) || is_monsters(target->faction)) { - report_failure(mage, co->order); - return 0; - } - - rt = pa->param[1]->data.r; - - for (u = rt->units; u; u = u->next) { - if (u->faction == target->faction) - see = true; - } - - if (see == false) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_pump", "target tregion", target, rt)); - return cast_level/2; - } else { - ADDMSG(&mage->faction->msgs, msg_message("pump_effect", "mage unit tregion", mage, target, rt)); - } - - u = create_unit(rt, mage->faction, RS_FARVISION, new_race[RC_SPELL], 0, "spell/pump", NULL); - u->age = 2; - set_level(u, SK_PERCEPTION, eff_skill(target, SK_PERCEPTION, u->region)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Verf�hrung - * Stufe: 6 - * Gebiet: Cerddor - * Wirkung: - * Bet�rt eine Einheit, so das sie ihm den gr��ten Teil ihres Bargelds - * und 50% ihres Besitzes schenkt. Sie beh�lt jedoch immer soviel, wie - * sie zum �berleben braucht. Wirkt gegen Magieresistenz. - * MIN(Stufe*1000$, u->money - maintenace) - * Von jedem Item wird 50% abgerundet ermittelt und �bergeben. Dazu - * kommt Itemzahl%2 mit 50% chance - * - * Flags: - * (UNITSPELL | TESTRESISTANCE | TESTCANSEE) - */ -static int -sp_seduce(castorder *co) -{ - item *items = NULL; - unit *target; - item **itmp; - unit *mage = co->magician.u; - spellparameter *pa = co->par; - int cast_level = co->level; - double force = co->force; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - target = pa->param[0]->data.u; /* Zieleinheit */ - - if (fval(target->race, RCF_UNDEAD)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, - "spellfail_noundead", "")); - return 0; - } - - /* Erfolgsmeldung */ - - itmp=&target->items; - while (*itmp) { - item * itm = *itmp; - int loot; - if (itm->type==i_silver) { - loot = MIN(cast_level * 1000, get_money(target) - (maintenance_cost(target))); - loot = MAX(loot, 0); - } else { - loot = itm->number/2; - if (itm->number % 2) { - loot += rng_int() % 2; - } - if (loot > 0) { - loot = (int)MIN(loot, force * 5); - } - } - if (loot>0) { - i_change(&mage->items, itm->type, loot); - i_change(&items, itm->type, loot); - i_change(itmp, itm->type, -loot); - } - if (*itmp==itm) itmp=&itm->next; - } - - ADDMSG(&mage->faction->msgs, msg_message("seduce_effect_0", "mage unit items", mage, target, items)); - i_freeall(&items); - ADDMSG(&target->faction->msgs, msg_message("seduce_effect_1", "unit", target)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Monster friedlich stimmen - * Stufe: 6 - * Gebiet: Cerddor - * Wirkung: - * verhindert Angriffe des bezauberten Monsters auf die Partei des - * Barden f�r Stufe Wochen. Nicht �bertragbar, dh Verb�ndete werden vom - * Monster nat�rlich noch angegriffen. Wirkt nicht gegen Untote - * Jede Einheit kann maximal unter einem Beherrschungszauber dieser Art - * stehen, dh wird auf die selbe Einheit dieser Zauber von einem - * anderen Magier nochmal gezaubert, schl�gt der Zauber fehl. - * - * Flags: - * (UNITSPELL | ONSHIPCAST | TESTRESISTANCE | TESTCANSEE) - */ - -static int -sp_calm_monster(castorder *co) -{ - curse * c; - unit *target; - unit *mage = co->magician.u; - spellparameter *pa = co->par; - int cast_level = co->level; - double force = co->force; - double effect; - message * msg; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - target = pa->param[0]->data.u; /* Zieleinheit */ - - if (fval(target->race, RCF_UNDEAD)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, - "spellfail_noundead", "")); - return 0; - } - - effect = mage->faction->subscription; - c = create_curse(mage, &target->attribs, ct_find("calmmonster"), force, - (int)force, effect, 0); - if (c==NULL) { - report_failure(mage, co->order); - return 0; - } - - msg = msg_message("calm_effect", "mage unit", mage, target); - r_addmessage(mage->region, mage->faction, msg); - msg_release(msg); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: schaler Wein - * Stufe: 7 - * Gebiet: Cerddor - * Wirkung: - * wird gegen Magieresistenz gezaubert Das Opfer vergisst bis zu - * Talenttage seines h�chsten Talentes und tut die Woche nix. - * Nachfolgende Zauber sind erschwert. - * Wirkt auf bis zu 10 Personen in der Einheit - * - * Flags: - * (UNITSPELL | TESTRESISTANCE | TESTCANSEE) - */ - -static int -sp_headache(castorder *co) -{ - skill * smax = NULL; - int i; - unit *target; - unit *mage = co->magician.u; - spellparameter *pa = co->par; - int cast_level = co->level; - message * msg; - - /* Macht alle nachfolgenden Zauber doppelt so teuer */ - countspells(mage, 1); - - target = pa->param[0]->data.u; /* Zieleinheit */ - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (target->number==0 || pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - /* finde das gr��te Talent: */ - for (i=0;i!=target->skill_size;++i) { - skill * sv = target->skills+i; - if (smax==NULL || skill_compare(sv, smax)>0) { - smax = sv; - } - } - if (smax!=NULL) { - /* wirkt auf maximal 10 Personen */ - int change = MIN(10, target->number) * (rng_int()%2+1) / target->number; - reduce_skill(target, smax, change); - } - set_order(&target->thisorder, NULL); - - msg = msg_message("hangover_effect_0", "mage unit", mage, target); - r_addmessage(mage->region, mage->faction, msg); - msg_release(msg); - - msg = msg_message("hangover_effect_1", "unit", target); - r_addmessage(target->region, target->faction, msg); - msg_release(msg); - - return cast_level; -} - - -/* ------------------------------------------------------------- */ -/* Name: Mob - * Stufe: 10 - * Gebiet: Cerddor - * Wirkung: - * Wiegelt Stufe*250 Bauern zu einem Mob auf, der sich der Partei des - * Magier anschliesst Pro Woche beruhigen sich etwa 15% wieder und - * kehren auf ihre Felder zur�ck - * - * Flags: - * (SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) - */ -static int -sp_raisepeasants(castorder *co) -{ - int bauern; - unit *u2; - attrib *a; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - message * msg; - - if (rpeasants(r) == 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_nopeasants", "")); - return 0; - } - bauern = (int)MIN(rpeasants(r), power*250); - rsetpeasants(r, rpeasants(r) - bauern); - - u2 = create_unit(r, mage->faction, bauern, new_race[RC_PEASANT], 0, LOC(mage->faction->locale, "furious_mob"), mage); - - fset(u2, UFL_LOCKED); - if (rule_stealth_faction()) { - fset(u2, UFL_ANON_FACTION); - } - - a = a_new(&at_unitdissolve); - a->data.ca[0] = 1; /* An rpeasants(r). */ - a->data.ca[1] = 15; /* 15% */ - a_add(&u2->attribs, a); - - msg = msg_message("sp_raisepeasants_effect", "mage region amount", mage, r, u2->number); - r_addmessage(r, NULL, msg); - if (mage->region!=r) { - add_message(&mage->faction->msgs, msg); - } - msg_release(msg); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Tr�bsal - * Stufe: 11 - * Kategorie: Region, negativ - * Wirkung: - * in der Region kann f�r einige Wochen durch Unterhaltung kein Geld - * mehr verdient werden - * - * Flag: - * (FARCASTING | REGIONSPELL | TESTRESISTANCE) - */ -static int -sp_depression(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int duration = (int)force+1; - message * msg; - - create_curse(mage, &r->attribs, ct_find("depression"), force, duration, zero_effect, 0); - - msg = msg_message("sp_depression_effect", "mage region", mage, r); - r_addmessage(r, NULL, msg); - if (mage->region!=r) { - add_message(&mage->faction->msgs, msg); - } - msg_release(msg); - return cast_level; -} - -#if 0 -/* ------------------------------------------------------------- */ -/* Name: Hoher Gesang der Drachen - * Stufe: 14 - * Gebiet: Cerddor - * Kategorie: Monster, Beschw�rung, positiv - * - * Wirkung: - * Erh�ht HP-Regeneration in der Region und lockt drachenartige (Wyrm, - * Drache, Jungdrache, Seeschlange, ...) aus der Umgebung an - * - * Flag: - * (FARCASTING | REGIONSPELL | TESTRESISTANCE) - */ -/* TODO zur Aktivierung in Zauberliste aufnehmen*/ -static int -sp_dragonsong(castorder *co) -{ - region *r = co->rt; /* Zauberregion */ - unit *mage = co->magician.u; - unit *u; - int cast_level = co->level; - double power = co->force; - region_list *rl,*rl2; - faction *f; - - /* TODO HP-Effekt */ - - f = get_monsters(); - - rl = all_in_range(r, (int)power); - - for(rl2 = rl; rl2; rl2 = rl2->next) { - region * r2 = rl2->data; - for(u = r2->units; u; u = u->next) { - if (u->race->flags & RCF_DRAGON) { - attrib * a = a_find(u->attribs, &at_targetregion); - if (!a) { - a = a_add(&u->attribs, make_targetregion(r)); - } else { - a->data.v = r; - } - } - } - } - - ADDMSG(&mage->faction->msgs, msg_message( - "summondragon", "unit region command target", - mage, mage->region, co->order, co->rt)); - - free_regionlist(rl); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Hoher Gesang der Verlockung - * Stufe: 17 - * Gebiet: Cerddor - * Kategorie: Monster, Beschw�rung, positiv - * - * Wirkung: - * Lockt Bauern aus den umliegenden Regionen her - * - * Flag: - * (FARCASTING | REGIONSPELL | TESTRESISTANCE) - */ -/* TODO zur Aktivierung in Zauberliste aufnehmen*/ - -static int -sp_songofAttraction(castorder *co) -{ - region *r = co->rt; /* Zauberregion */ - unit *mage = co->magician.u; - int cast_level = co->level; - /* double power = co->force; */ - - /* TODO Wander Effekt */ - - ADDMSG(&mage->faction->msgs, msg_message( - "summon", "unit region command region", - mage, mage->region, co->order, r)); - - return cast_level; -} - -#endif - -/* ------------------------------------------------------------- */ -/* TRAUM - Illaun */ -/* ------------------------------------------------------------- */ - -/* Name: Seelenfrieden - * Stufe: 2 - * Kategorie: Region, positiv - * Gebiet: Illaun - * Wirkung: - * Reduziert Untotencounter - * Flag: (0) - */ - -int -sp_puttorest(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int dead = deathcount(r); - int laid_to_rest = dice((int)(co->force * 2), 100); - message * seen = msg_message("puttorest", "mage", mage); - message * unseen = msg_message("puttorest", "mage", NULL); - - laid_to_rest = MAX(laid_to_rest, dead); - - deathcounts(r, -laid_to_rest); - - report_effect(r, mage, seen, unseen); - msg_release(seen); - msg_release(unseen); - return co->level; -} - -/* Name: Traumschl��chen - * Stufe: 3 - * Kategorie: Region, Geb�ude, positiv - * Gebiet: Illaun - * Wirkung: - * Mit Hilfe dieses Zaubers kann der Traumweber die Illusion eines - * beliebigen Geb�udes erzeugen. Die Illusion kann betreten werden, ist - * aber ansonsten funktionslos und ben�tigt auch keinen Unterhalt - * Flag: (0) - */ - -int -sp_icastle(castorder *co) -{ - building *b; - const building_type * type; - attrib *a; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - spellparameter *pa = co->par; - icastle_data * data; - const char * bname; - message * msg; - static const building_type * bt_illusion; - - if (bt_illusion==NULL) bt_illusion = bt_find("illusioncastle"); - if (bt_illusion==NULL) { - return 0; - } - - if ((type=findbuildingtype(pa->param[0]->data.xs, mage->faction->locale)) == NULL) { - type = bt_find("castle"); - } - - b = new_building(bt_illusion, r, mage->faction->locale); - - /* Gr��e festlegen. */ - if (type == bt_illusion) { - b->size = (rng_int()%(int)((power*power)+1)*10); - } else if (type->maxsize == -1) { - b->size = ((rng_int()%(int)(power))+1)*5; - } else { - b->size = type->maxsize; - } - - if (type->name==NULL) { - bname = LOC(mage->faction->locale, type->_name); - } else { - bname = LOC(mage->faction->locale, buildingtype(type, b, 0)); - } - building_setname(b, bname); - - /* TODO: Auf timeout und action_destroy umstellen */ - a = a_add(&b->attribs, a_new(&at_icastle)); - data = (icastle_data*)a->data.v; - data->type = type; - data->building = b; - data->time = 2+(rng_int()%(int)(power)+1)*(rng_int()%(int)(power)+1); - - if (mage->region == r) { - if (leave(mage, false)) { - mage->building = b; - } - } - - ADDMSG(&mage->faction->msgs, msg_message( - "icastle_create", "unit region command", mage, mage->region, - co->order)); - - msg = msg_message("sp_icastle_effect", "region", r); - report_spell(mage, r, msg); - msg_release(msg); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Gestaltwandlung - * Stufe: 3 - * Gebiet: Illaun - * Wirkung: - * Zieleinheit erscheint f�r (Stufe) Wochen als eine andere Gestalt - * (wie bei d�monischer Rassetarnung). - * Syntax: ZAUBERE "Gestaltwandlung" <einheit> <rasse> - * Flags: - * (UNITSPELL | SPELLLEVEL) - */ - -int -sp_illusionary_shapeshift(castorder *co) -{ - unit *u; - const race * rc; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - spellparameter *pa = co->par; - const race * irace; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber - * abbrechen aber kosten lassen */ - if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; - - u = pa->param[0]->data.u; - - rc = findrace(pa->param[1]->data.xs, mage->faction->locale); - if (rc == NULL) { - cmistake(mage, co->order, 202, MSG_MAGIC); - return 0; - } - - /* �hnlich wie in laws.c:setealth() */ - if (!playerrace(rc)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "sp_shapeshift_fail", "target race", u, rc)); - return 0; - } - irace = u_irace(u); - if (irace == u->race) { - trigger * trestore = trigger_changerace(u, NULL, irace); - add_trigger(&u->attribs, "timer", trigger_timeout((int)power+2, trestore)); - u->irace = rc; - } - - ADDMSG(&mage->faction->msgs, msg_message("shapeshift_effect", "mage target race", mage, u, rc)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Regionstraum analysieren - * Stufe: 9 - * Aura: 18 - * Kosten: SPC_FIX - * Wirkung: - * Zeigt die Verzauberungen eines Objekts an (curse->name, - * curse::info). Aus der Differenz Spruchst�rke und Curse->vigour - * ergibt sich die Chance den Spruch zu identifizieren ((force - - * c->vigour)*10 + 100 %). - */ -int -sp_analyseregionsdream(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - - magicanalyse_region(r, mage, cast_level); - - return cast_level; -} - - -/* ------------------------------------------------------------- */ -/* Name: Traumbilder erkennen - * Stufe: 5 - * Aura: 12 - * Kosten: SPC_FIX - * Wirkung: - * Zeigt die Verzauberungen eines Objekts an (curse->name, - * curse::info). Aus der Differenz Spruchst�rke und Curse->vigour - * ergibt sich die Chance den Spruch zu identifizieren ((force - - * c->vigour)*10 + 100 %). - */ -int -sp_analysedream(castorder *co) -{ - unit *u; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber - * abbrechen aber kosten lassen */ - if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; - - u = pa->param[0]->data.u; - magicanalyse_unit(u, mage, cast_level); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Schlechte Tr�ume - * Stufe: 10 - * Kategorie: Region, negativ - * Wirkung: - * Dieser Zauber erm�glicht es dem Tr�umer, den Schlaf aller - * nichtaliierten Einheiten (HELFE BEWACHE) in der Region so starkzu - * st�ren, das sie 1 Talentstufe in allen Talenten - * vor�bergehend verlieren. Der Zauber wirkt erst im Folgemonat. - * - * Flags: - * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) - * */ -int -sp_baddreams(castorder *co) -{ - int duration; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - region *r = co->rt; - curse * c; - double effect; - - /* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken, - * also duration+2 */ - duration = (int)MAX(1, power/2); /* Stufe 1 macht sonst mist */ - duration = 2 + rng_int()%duration; - - /* Nichts machen als ein entsprechendes Attribut in die Region legen. */ - effect = -1; - c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, effect, 0); - - /* Erfolg melden*/ - ADDMSG(&mage->faction->msgs, msg_message( - "regionmagic_effect", "unit region command", mage, - mage->region, co->order)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Sch�ne Tr�ume - * Stufe: 8 - * Kategorie: - * Wirkung: - * Dieser Zauber erm�glicht es dem Tr�umer, den Schlaf aller aliierten - * Einheiten in der Region so zu beeinflussen, da� sie f�r einige Zeit - * einen Bonus von 1 Talentstufe in allen Talenten - * bekommen. Der Zauber wirkt erst im Folgemonat. - * Flags: - * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) - */ -int -sp_gooddreams(castorder *co) -{ - int duration; - curse * c; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - double effect; - - /* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken, - * also duration+2 */ - duration = (int)MAX(1, power/2); /* Stufe 1 macht sonst mist */ - duration = 2 + rng_int()%duration; - effect = 1; - c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, effect, 0); - - /* Erfolg melden*/ - ADDMSG(&mage->faction->msgs, msg_message( - "regionmagic_effect", "unit region command", mage, - mage->region, co->order)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: - * Stufe: 9 - * Kategorie: - * Wirkung: - * Es wird eine Kloneinheit erzeugt, die nichts kann. Stirbt der - * Magier, wird er mit einer Wahrscheinlichkeit von 90% in den Klon - * transferiert. - * Flags: - * (NOTFAMILARCAST) - */ -int -sp_clonecopy(castorder *co) -{ - unit *clone; - region *r = co->rt; - region *target_region = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - message * msg; - char name[NAMESIZE]; - - if (get_clone(mage) != NULL ) { - cmistake(mage, co->order, 298, MSG_MAGIC); - return 0; - } - - snprintf(name, sizeof(name), (const char*)LOC(mage->faction->locale, "clone_of"), unitname(mage)); - clone = create_unit(target_region, mage->faction, 1, new_race[RC_CLONE], 0, name, mage); - setstatus(clone, ST_FLEE); - fset(clone, UFL_LOCKED); - - create_newclone(mage, clone); - - msg = msg_message("sp_clone_effet", "mage", mage); - r_addmessage(r, mage->faction, msg); - msg_release(msg); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -int -sp_dreamreading(castorder *co) -{ - unit *u,*u2; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - double power = co->force; - message * msg; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber - * abbrechen aber kosten lassen */ - if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; - - u = pa->param[0]->data.u; - - /* Illusionen und Untote abfangen. */ - if (fval(u->race, RCF_UNDEAD|RCF_ILLUSIONARY)) { - ADDMSG(&mage->faction->msgs, msg_unitnotfound(mage, co->order, pa->param[0])); - return 0; - } - - /* Entfernung */ - if (distance(mage->region, u->region) > power) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_distance", "")); - return 0; - } - - u2 = create_unit(u->region,mage->faction, RS_FARVISION, new_race[RC_SPELL], 0, "spell/dreamreading", NULL); - set_number(u2, 1); - u2->age = 2; /* Nur f�r diese Runde. */ - set_level(u2, SK_PERCEPTION, eff_skill(u, SK_PERCEPTION, u2->region)); - - msg = msg_message("sp_dreamreading_effect", "mage unit region", mage, u, u->region); - r_addmessage(r, mage->faction, msg); - msg_release(msg); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Wirkt power/2 Runden auf bis zu power^2 Personen - * mit einer Chance von 5% vermehren sie sich */ -int -sp_sweetdreams(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - spellparameter *pa = co->par; - int men, n; - int duration = (int)(power/2)+1; - int opfer = (int)(power*power); - - /* Schleife �ber alle angegebenen Einheiten */ - for (n = 0; n < pa->length; n++) { - curse * c; - unit *u; - double effect; - message * msg; - /* sollte nie negativ werden */ - if (opfer < 1) break; - - if (pa->param[n]->flag == TARGET_RESISTS || - pa->param[n]->flag == TARGET_NOTFOUND) - continue; - - /* Zieleinheit */ - u = pa->param[n]->data.u; - - if (!ucontact(u, mage)) { - cmistake(mage, co->order, 40, MSG_EVENT); - continue; - } - men = MIN(opfer, u->number); - opfer -= men; - - /* Nichts machen als ein entsprechendes Attribut an die Einheit legen. */ - effect = 0.05; - c = create_curse(mage,&u->attribs, ct_find("orcish"), power, duration, effect, men); - - msg = msg_message("sp_sweetdreams_effect", "mage unit region", mage, u, r); - r_addmessage(r, mage->faction, msg); - if (u->faction!=mage->faction) { - r_addmessage(r, u->faction, msg); - } - msg_release(msg); - } - return cast_level; -} - -/* ------------------------------------------------------------- */ -int -sp_disturbingdreams(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - int duration = 1 + (int)(power/6); - double effect; - curse * c; - - effect = 10; - c = create_curse(mage, &r->attribs, ct_find("badlearn"), power, duration, effect, 0); - - ADDMSG(&mage->faction->msgs, msg_message("sp_disturbingdreams_effect", "mage region", mage, r)); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* ASTRAL / THEORIE / M_TYBIED */ -/* ------------------------------------------------------------- */ -/* Name: Magie analysieren - * Stufe: 1 - * Aura: 1 - * Kosten: SPC_LINEAR - * Komponenten: - * - * Wirkung: - * Zeigt die Verzauberungen eines Objekts an (curse->name, - * curse::info). Aus der Differenz Spruchst�rke und Curse->vigour - * ergibt sich die Chance den Spruch zu identifizieren ((force - - * c->vigour)*10 + 100 %). - * - * Flags: - * UNITSPELL, SHIPSPELL, BUILDINGSPELL - */ - -int -sp_analysemagic(castorder *co) -{ - int obj; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - - if (!pa->param) { - return 0; - } - /* Objekt ermitteln */ - obj = pa->param[0]->typ; - - switch(obj) { - case SPP_REGION: - { - region *tr = pa->param[0]->data.r; - magicanalyse_region(tr, mage, cast_level); - break; - } - case SPP_TEMP: - case SPP_UNIT: - { - unit *u; - u = pa->param[0]->data.u; - magicanalyse_unit(u, mage, cast_level); - break; - } - case SPP_BUILDING: - { - building *b; - b = pa->param[0]->data.b; - magicanalyse_building(b, mage, cast_level); - break; - } - case SPP_SHIP: - { - ship *sh; - sh = pa->param[0]->data.sh; - magicanalyse_ship(sh, mage, cast_level); - break; - } - default: - /* Fehlerhafter Parameter */ - return 0; - } - - return cast_level; -} - -/* ------------------------------------------------------------- */ - -int -sp_itemcloak(castorder *co) -{ - unit *target; - unit *mage = co->magician.u; - spellparameter *pa = co->par; - int cast_level = co->level; - double power = co->force; - int duration = (int)MAX(2.0, power+1); /* works in the report, and ageing this round would kill it if it's <=1 */ - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - /* Zieleinheit */ - target = pa->param[0]->data.u; - - create_curse(mage,&target->attribs, ct_find("itemcloak"), power, duration, zero_effect, 0); - ADDMSG(&mage->faction->msgs, msg_message( - "itemcloak", "mage target", mage, target)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Magieresistenz erh�hen - * Stufe: 3 - * Aura: 5 MP - * Kosten: SPC_LEVEL - * Komponenten: - * - * Wirkung: - * erh�ht die Magierestistenz der Personen um 20 Punkte f�r 6 Wochen - * Wirkt auf Stufe*5 Personen kann auf mehrere Einheiten gezaubert - * werden, bis die Zahl der m�glichen Personen ersch�pft ist - * - * Flags: - * UNITSPELL - */ -int -sp_resist_magic_bonus(castorder *co) -{ - unit *u; - int n, m; - int duration = 6; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - spellparameter *pa = co->par; - /* Pro Stufe k�nnen bis zu 5 Personen verzaubert werden */ - double maxvictims = 5; - int victims = (int)maxvictims; - - /* Schleife �ber alle angegebenen Einheiten */ - for (n = 0; n < pa->length; n++) { - message * msg; - /* sollte nie negativ werden */ - if (victims < 1) - break; - - if (pa->param[n]->flag == TARGET_RESISTS - || pa->param[n]->flag == TARGET_NOTFOUND) - continue; - - u = pa->param[n]->data.u; - - /* Ist die Einheit schon verzaubert, wirkt sich dies nur auf die - * Menge der Verzauberten Personen aus. - if (is_cursed(u->attribs, C_MAGICRESISTANCE, 0)) - continue; - */ - - m = MIN(u->number,victims); - victims -= m; - - create_curse(mage, &u->attribs, ct_find("magicresistance"), - power, duration, 20, m); - - msg = msg_message("magicresistance_effect", "unit", u); - add_message(&u->faction->msgs, msg); - - /* und noch einmal dem Magier melden */ - if (u->faction != mage->faction) { - add_message(&mage->faction->msgs, msg); - } - msg_release(msg); - } - - cast_level = MIN(cast_level, (int)(cast_level*(victims+4)/maxvictims)); - return MAX(cast_level, 1); -} - -/** spell 'Astraler Weg'. - * Syntax "ZAUBERE [STUFE n] 'Astraler Weg' <Einheit-Nr> [<Einheit-Nr> ...]", - * - * Parameter: - * pa->param[0]->data.xs -*/ -int -sp_enterastral(castorder *co) -{ - region *rt, *ro; - unit *u, *u2; - int remaining_cap; - int n, w; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - spellparameter *pa = co->par; - - switch(getplaneid(r)) { - case 0: - rt = r_standard_to_astral(r); - ro = r; - break; - default: - cmistake(mage, co->order, 190, MSG_MAGIC); - return 0; - } - - if (!rt || fval(rt->terrain, FORBIDDEN_REGION)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_astralregion", "")); - return 0; - } - - if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0) || is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); - return 0; - } - - remaining_cap = (int)((power-3) * 1500); - - /* f�r jede Einheit in der Kommandozeile */ - for (n = 0; n < pa->length; n++) { - if (pa->param[n]->flag == TARGET_NOTFOUND) continue; - u = pa->param[n]->data.u; - - if (!ucontact(u, mage)) { - if (power > 10 && !is_magic_resistant(mage, u, 0) && can_survive(u, rt)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_no_resist", "target", u)); - ADDMSG(&u->faction->msgs, msg_message("send_astral", "unit target", mage, u)); - } else { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_resist", "target", u)); - ADDMSG(&u->faction->msgs, msg_message("try_astral", "unit target", mage, u)); - continue; - } - } - - w = weight(u); - if (!can_survive(u, rt)) { - cmistake(mage, co->order, 231, MSG_MAGIC); - } else if (remaining_cap - w < 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "fail_tooheavy", "target", u)); - } else { - message * m; - remaining_cap = remaining_cap - w; - move_unit(u, rt, NULL); - - /* Meldungen in der Ausgangsregion */ - - for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = r->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, r, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_disappear", "unit", u); - r_addmessage(r, u2->faction, m); - } - } - } - if (m) msg_release(m); - - /* Meldungen in der Zielregion */ - - for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = rt->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_appear", "unit", u); - r_addmessage(rt, u2->faction, m); - } - } - } - if (m) msg_release(m); - } - } - return cast_level; -} - -/** Spell 'Astraler Ruf' / 'Astral Call'. - */ -int -sp_pullastral(castorder *co) -{ - region *rt, *ro; - unit *u, *u2; - region_list *rl, *rl2; - int remaining_cap; - int n, w; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - spellparameter *pa = co->par; - - switch (getplaneid(r)) { - case 1: - rt = r; - ro = pa->param[0]->data.r; - rl = astralregions(r, NULL); - rl2 = rl; - while (rl2!=NULL) { - region * r2 = rl2->data; - if (r2->x == ro->x && r2->y == ro->y) { - ro = r2; - break; - } - rl2 = rl2->next; - } - if (!rl2) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail::nocontact", - "target", rt)); - free_regionlist(rl); - return 0; - } - free_regionlist(rl); - break; - default: - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralonly", "")); - return 0; - } - - if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0) || is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); - return 0; - } - - remaining_cap = (int)((power-3) * 1500); - - /* f�r jede Einheit in der Kommandozeile */ - for (n = 1; n < pa->length; n++) { - spllprm * spobj = pa->param[n]; - if (spobj->flag == TARGET_NOTFOUND) continue; - - u = spobj->data.u; - - if (u->region!=ro) { - /* Report this as unit not found */ - if (spobj->typ == SPP_UNIT) { - spobj->data.i = u->no; - } else { - spobj->data.i = ualias(u); - } - spobj->flag = TARGET_NOTFOUND; - ADDMSG(&mage->faction->msgs, msg_unitnotfound(mage, co->order, spobj)); - return false; - } - - if (!ucontact(u, mage)) { - if (power > 12 && spobj->flag != TARGET_RESISTS && can_survive(u, rt)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_no_resist", "target", u)); - } else { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_resist", "target", u)); - ADDMSG(&u->faction->msgs, msg_message("try_astral", "unit target", mage, u)); - continue; - } - } - - w = weight(u); - - if (!can_survive(u, rt)) { - cmistake(mage, co->order, 231, MSG_MAGIC); - } else if (remaining_cap - w < 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "fail_tooheavy", "target", u)); - } else { - message * m; - - ADDMSG(&u->faction->msgs, msg_message("send_astral", "unit target", mage, u)); - remaining_cap = remaining_cap - w; - move_unit(u, rt, NULL); - - /* Meldungen in der Ausgangsregion */ - - for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = r->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, r, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_disappear", "unit", u); - r_addmessage(r, u2->faction, m); - } - } - } - if (m) msg_release(m); - - /* Meldungen in der Zielregion */ - - for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = rt->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_appear", "unit", u); - r_addmessage(rt, u2->faction, m); - } - } - } - if (m) msg_release(m); - } - } - return cast_level; -} - -int -sp_leaveastral(castorder *co) -{ - region *rt, *ro; - region_list *rl, *rl2; - unit *u, *u2; - int remaining_cap; - int n, w; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - spellparameter *pa = co->par; - - switch(getplaneid(r)) { - case 1: - ro = r; - rt = pa->param[0]->data.r; - if (!rt) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail::noway", "")); - return 0; - } - rl = astralregions(r, inhabitable); - rl2 = rl; - while (rl2!=NULL) { - if (rl2->data == rt) break; - rl2 = rl2->next; - } - if (rl2==NULL) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail::noway", "")); - free_regionlist(rl); - return 0; - } - free_regionlist(rl); - break; - default: - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spell_astral_only", "")); - return 0; - } - - if (ro==NULL || is_cursed(ro->attribs, C_ASTRALBLOCK, 0) || is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); - return 0; - } - - remaining_cap = (int)((power-3) * 1500); - - /* f�r jede Einheit in der Kommandozeile */ - for (n = 1; n < pa->length; n++) { - if (pa->param[n]->flag == TARGET_NOTFOUND) continue; - - u = pa->param[n]->data.u; - - if (!ucontact(u, mage)) { - if (power > 10 && !pa->param[n]->flag == TARGET_RESISTS && can_survive(u, rt)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_no_resist", "target", u)); - ADDMSG(&u->faction->msgs, msg_message("send_astral", "unit target", mage, u)); - } else { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_resist", "target", u)); - ADDMSG(&u->faction->msgs, msg_message("try_astral", "unit target", mage, u)); - continue; - } - } - - w = weight(u); - - if (!can_survive(u, rt)) { - cmistake(mage, co->order, 231, MSG_MAGIC); - } else if (remaining_cap - w < 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "fail_tooheavy", "target", u)); - } else { - message * m; - - remaining_cap = remaining_cap - w; - move_unit(u, rt, NULL); - - /* Meldungen in der Ausgangsregion */ - - for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = r->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, r, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_disappear", "unit", u); - r_addmessage(r, u2->faction, m); - } - } - } - if (m) msg_release(m); - - /* Meldungen in der Zielregion */ - - for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = rt->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_appear", "unit", u); - r_addmessage(rt, u2->faction, m); - } - } - } - if (m) msg_release(m); - } - } - return cast_level; -} - -int -sp_fetchastral(castorder *co) -{ - int n; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - double power = co->force; - int remaining_cap = (int)((power-3) * 1500); - region_list * rtl = NULL; - region * rt = co->rt; /* region to which we are fetching */ - region * ro = NULL; /* region in which the target is */ - - if (rplane(rt)!=get_normalplane()) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error190", "")); - return 0; - } - - /* f�r jede Einheit in der Kommandozeile */ - for (n=0; n!=pa->length; ++n) { - unit * u2, * u = pa->param[n]->data.u; - int w; - message * m; - - if (pa->param[n]->flag & TARGET_NOTFOUND) continue; - - if (u->region!=ro) { - /* this can happen several times if the units are from different astral - * regions. Only possible on the intersections of schemes */ - region_list * rfind; - if (!is_astral(u->region)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralonly", "")); - continue; - } - if (rtl!=NULL) free_regionlist(rtl); - rtl = astralregions(u->region, NULL); - for (rfind=rtl;rfind!=NULL;rfind=rfind->next) { - if (rfind->data==mage->region) break; - } - if (rfind==NULL) { - /* the region r is not in the schemes of rt */ - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, - "spellfail_distance", "target", u)); - continue; - } - ro = u->region; - } - - if (is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, - "spellfail_astralblock", "")); - continue; - } - - if (!can_survive(u, rt)) { - cmistake(mage, co->order, 231, MSG_MAGIC); - continue; - } - - w = weight(u); - if (remaining_cap - w < 0) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, - "fail_tooheavy", "target", u)); - continue; - } - - if (!ucontact(u, mage)) { - if (power>12 && !(pa->param[n]->flag & TARGET_RESISTS)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_no_resist", "target", u)); - ADDMSG(&u->faction->msgs, msg_message("send_astral", "unit target", mage, u)); - } else { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_resist", "target", u)); - ADDMSG(&u->faction->msgs, msg_message("try_astral", "unit target", mage, u)); - continue; - } - } - - remaining_cap -= w; - move_unit(u, rt, NULL); - - /* Meldungen in der Ausgangsregion */ - for (u2 = ro->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = ro->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, ro, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_disappear", "unit", u); - r_addmessage(ro, u2->faction, m); - } - } - } - if (m) msg_release(m); - - /* Meldungen in der Zielregion */ - for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); - m = NULL; - for (u2 = rt->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FFL_SELECT)) { - if (cansee(u2->faction, rt, u, 0)) { - fset(u2->faction, FFL_SELECT); - if (!m) m = msg_message("astral_appear", "unit", u); - r_addmessage(rt, u2->faction, m); - } - } - } - if (m) msg_release(m); - } - if (rtl!=NULL) free_regionlist(rtl); - return cast_level; -} - -#ifdef SHOWASTRAL_NOT_BORKED -int -sp_showastral(castorder *co) -{ - unit *u; - region *rt; - int n = 0; - int c = 0; - region_list *rl, *rl2; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - - switch(getplaneid(r)) { - case 0: - rt = r_standard_to_astral(r); - if (!rt || fval(rt->terrain, FORBIDDEN_REGION)) { - /* Hier gibt es keine Verbindung zur astralen Welt */ - cmistake(mage, co->order, 216, MSG_MAGIC); - return 0; - } - break; - case 1: - rt = r; - break; - default: - /* Hier gibt es keine Verbindung zur astralen Welt */ - cmistake(mage, co->order, 216, MSG_MAGIC); - return 0; - } - - rl = all_in_range(rt,power/5); - - /* Erst Einheiten z�hlen, f�r die Grammatik. */ - - for (rl2=rl; rl2; rl2=rl2->next) { - region * r2 = rl2->data; - if (!is_cursed(r2->attribs, C_ASTRALBLOCK, 0)) { - for(u = r2->units; u; u=u->next) { - if (u->race != new_race[RC_SPECIAL] && u->race != new_race[RC_SPELL]) n++; - } - } - } - - if (n == 0) { - /* sprintf(buf, "%s kann niemanden im astralen Nebel entdecken.", - unitname(mage)); */ - cmistake(mage, co->order, 220, MSG_MAGIC); - } else { - - /* Ausgeben */ - - sprintf(buf, "%s hat eine Vision der astralen Ebene. Im astralen " - "Nebel zu erkennen sind ", unitname(mage)); - - for(rl2=rl; rl2; rl2=rl2->next) { - if (!is_cursed(rl2->data->attribs, C_ASTRALBLOCK, 0)) { - for(u = rl2->data->units; u; u=u->next) { - if (u->race != new_race[RC_SPECIAL] && u->race != new_race[RC_SPELL]) { - c++; - scat(unitname(u)); - scat(" ("); - if (!fval(u, UFL_ANON_FACTION)) { - scat(factionname(u->faction)); - scat(", "); - } - icat(u->number); - scat(" "); - scat(LOC(mage->faction->locale, rc_name(u->race, u->number!=1))); - scat(", Entfernung "); - icat(distance(rl2->data, rt)); - scat(")"); - if (c == n-1) { - scat(" und "); - } else if (c < n-1) { - scat(", "); - } - } - } - } - } - scat("."); - addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO); - } - - free_regionlist(rl); - return cast_level; - unused(co); - return 0; -} -#endif - -/* ------------------------------------------------------------- */ -int -sp_viewreality(castorder *co) -{ - region_list *rl, *rl2; - unit *u; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - message * m; - - if (getplaneid(r) != 1) { - /* sprintf(buf, "Dieser Zauber kann nur im Astralraum gezaubert werden."); */ - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spell_astral_only", "")); - return 0; - } - - rl = astralregions(r, NULL); - - /* Irgendwann mal auf Curses u/o Attribut umstellen. */ - for (rl2=rl; rl2; rl2=rl2->next) { - region * rt = rl2->data; - if (!is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { - u = create_unit(rt, mage->faction, RS_FARVISION, new_race[RC_SPELL], 0, "spell/viewreality", NULL); - set_level(u, SK_PERCEPTION, co->level/2); - u->age = 2; - } - } - - free_regionlist(rl); - - m = msg_message("viewreality_effect", "unit", mage); - r_addmessage(r, mage->faction, m); - msg_release(m); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -int -sp_disruptastral(castorder *co) -{ - region_list *rl, *rl2; - region *rt; - unit *u; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - int duration = (int)(power/3)+1; - - switch(getplaneid(r)) { - case 0: - rt = r_standard_to_astral(r); - if (!rt || fval(rt->terrain, FORBIDDEN_REGION)) { - /* "Hier gibt es keine Verbindung zur astralen Welt." */ - cmistake(mage, co->order, 216, MSG_MAGIC); - return 0; - } - break; - case 1: - rt = r; - break; - default: - /* "Von hier aus kann man die astrale Ebene nicht erreichen." */ - cmistake(mage, co->order, 215, MSG_MAGIC); - return 0; - } - - rl = all_in_range(rt, (short)(power/5), NULL); - - for (rl2=rl; rl2!=NULL; rl2=rl2->next) { - attrib *a; - double effect; - region * r2 = rl2->data; - spec_direction *sd; - int inhab_regions = 0; - region_list * trl = NULL; - - if (is_cursed(r2->attribs, C_ASTRALBLOCK, 0)) continue; - - if (r2->units!=NULL) { - region_list * trl2; - - trl = astralregions(rl2->data, inhabitable); - for (trl2 = trl; trl2; trl2 = trl2->next) ++inhab_regions; - } - - /* Nicht-Permanente Tore zerst�ren */ - a = a_find(r->attribs, &at_direction); - - while (a!=NULL && a->type==&at_direction) { - attrib * a2 = a->next; - sd = (spec_direction *)(a->data.v); - if (sd->duration != -1) a_remove(&r->attribs, a); - a = a2; - } - - /* Einheiten auswerfen */ - - if (trl!=NULL) { - for (u=r2->units;u;u=u->next) { - if (u->race != new_race[RC_SPELL]) { - region_list *trl2 = trl; - region *tr; - int c = rng_int() % inhab_regions; - - /* Zuf�llige Zielregion suchen */ - while (c--!=0) trl2 = trl2->next; - tr = trl2->data; - - if (!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) { - message * msg = msg_message("disrupt_astral", "unit region", u, tr); - add_message(&u->faction->msgs, msg); - add_message(&tr->msgs, msg); - msg_release(msg); - - move_unit(u, tr, NULL); - } - } - } - free_regionlist(trl); - } - - /* Kontakt unterbinden */ - effect = 100; - create_curse(mage, &rl2->data->attribs, ct_find("astralblock"), - power, duration, effect, 0); - } - - free_regionlist(rl); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Mauern der Ewigkeit - * Stufe: 7 - * Kategorie: Artefakt - * Gebiet: Tybied - * Wirkung: - * Das Geb�ude kostet keinen Unterhalt mehr - * - * ZAUBER "Mauern der Ewigkeit" <geb�ude-nummer> - * Flags: (0) - */ -static int -sp_eternizewall(castorder *co) -{ - unit *u; - curse * c; - building *b; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - spellparameter *pa = co->par; - message * msg; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - b = pa->param[0]->data.b; - c = create_curse(mage, &b->attribs, ct_find("nocostbuilding"), - power*power, 1, zero_effect, 0); - - if (c==NULL) { /* ist bereits verzaubert */ - cmistake(mage, co->order, 206, MSG_MAGIC); - return 0; - } - - /* melden, 1x pro Partei in der Burg */ - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - msg = msg_message("sp_eternizewall_effect", "mage building region", mage, b, r); - for (u = r->units; u; u = u->next) { - if (!fval(u->faction, FFL_SELECT)) { - fset(u->faction, FFL_SELECT); - if (u->building == b) { - r_addmessage(r, u->faction, msg); - } - } - } - if (r!=mage->region) { - add_message(&mage->faction->msgs, msg); - } else if (mage->building!=b) { - r_addmessage(r, mage->faction, msg); - } - msg_release(msg); - - return cast_level; -} - - -/* ------------------------------------------------------------- */ -/* Name: Opfere Kraft - * Stufe: 15 - * Gebiet: Tybied - * Kategorie: Einheit, positiv - * Wirkung: - * Mit Hilfe dieses Zaubers kann der Magier einen Teil seiner - * magischen Kraft permanent auf einen anderen Magier �bertragen. Auf - * einen Tybied-Magier kann er die H�lfte der eingesetzten Kraft - * �bertragen, auf einen Magier eines anderen Gebietes ein Drittel. - * - * Flags: - * (UNITSPELL) - * - * Syntax: - * ZAUBERE \"Opfere Kraft\" <Einheit-Nr> <Aura> - * "ui" - */ -int -sp_permtransfer(castorder *co) -{ - int aura; - unit *tu; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - const spell *sp = co->sp; - message * msg; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber - * abbrechen aber kosten lassen */ - if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; - - tu = pa->param[0]->data.u; - aura = pa->param[1]->data.i; - - if (!is_mage(tu)) { -/* sprintf(buf, "%s in %s: 'ZAUBER %s': Einheit ist kein Magier." - , unitname(mage), regionname(mage->region, mage->faction),sa->strings[0]); */ - cmistake(mage, co->order, 214, MSG_MAGIC); - return 0; - } - - aura = MIN(get_spellpoints(mage)-spellcost(mage, sp), aura); - - change_maxspellpoints(mage,-aura); - change_spellpoints(mage,-aura); - - if (get_mage(tu)->magietyp == get_mage(mage)->magietyp) { - change_maxspellpoints(tu, aura/2); - } else { - change_maxspellpoints(tu, aura/3); - } - - msg = msg_message("sp_permtransfer_effect", "mage target amount", mage, tu, aura); - add_message(&mage->faction->msgs, msg); - if (tu->faction!=mage->faction) { - add_message(&tu->faction->msgs, msg); - } - msg_release(msg); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* TODO: specialdirections? */ - -int -sp_movecastle(castorder *co) -{ - building *b; - direction_t dir; - region *target_region; - unit *u, *unext; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - message* msg; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - b = pa->param[0]->data.b; - dir = finddirection(pa->param[1]->data.xs, mage->faction->locale); - - if (dir == NODIRECTION) { - /* Die Richtung wurde nicht erkannt */ - cmistake(mage, co->order, 71, MSG_PRODUCE); - return 0; - } - - if (b->size > (cast_level-12) * 250) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "sp_movecastle_fail_0", "")); - return cast_level; - } - - target_region = rconnect(r,dir); - - if (!(target_region->terrain->flags & LAND_REGION)) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "sp_movecastle_fail_1", "direction", dir)); - return cast_level; - } - - bunhash(b); - translist(&r->buildings, &target_region->buildings, b); - b->region = target_region; - b->size -= b->size/(10-rng_int()%6); - bhash(b); - - for(u=r->units;u;) { - unext = u->next; - if (u->building == b) { - uunhash(u); - translist(&r->units, &target_region->units, u); - uhash(u); - } - u = unext; - } - - if ((b->type==bt_find("caravan") || b->type==bt_find("dam") || b->type==bt_find("tunnel"))) { - boolean damage = false; - direction_t d; - for (d=0;d!=MAXDIRECTIONS;++d) { - if (rroad(r, d)) { - rsetroad(r, d, rroad(r, d)/2); - damage = true; - } - } -/* if (damage) strcat(buf, " Die Stra�en der Region wurden besch�digt."); */ - } - - msg = msg_message("sp_movecastle_effect", "building direction", b, dir); - r_addmessage(r, NULL, msg); - msg_release(msg); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Luftschiff - * Stufe: 6 - * - * Wirkung: - * L��t ein Schiff eine Runde lang fliegen. Wirkt nur auf Boote und - * Langboote. - * Kombinierbar mit "G�nstige Winde", aber nicht mit "Sturmwind". - * - * Flag: - * (ONSHIPCAST | SHIPSPELL | TESTRESISTANCE) - */ -int -sp_flying_ship(castorder *co) -{ - ship *sh; - unit *u; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - spellparameter *pa = co->par; - message * m = NULL; - int cno; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - sh = pa->param[0]->data.sh; - if (sh->type->construction->maxsize>50) { - ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_flying_ship_too_big", "ship", sh)); - return 0; - } - - /* Duration = 1, nur diese Runde */ - - cno = levitate_ship(sh, mage, power, 1); - if (cno==0) { - if (is_cursed(sh->attribs, C_SHIP_FLYING, 0) ) { - /* Auf dem Schiff befindet liegt bereits so ein Zauber. */ - cmistake(mage, co->order, 211, MSG_MAGIC); - } else if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0) ) { - /* Es ist zu gef�hrlich, ein sturmgepeitschtes Schiff fliegen zu lassen. */ - cmistake(mage, co->order, 210, MSG_MAGIC); - } - return 0; - } - sh->coast = NODIRECTION; - - /* melden, 1x pro Partei */ - for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); - for(u = r->units; u; u = u->next ) { - /* das sehen nat�rlich auch die Leute an Land */ - if (!fval(u->faction, FFL_SELECT) ) { - fset(u->faction, FFL_SELECT); - if (!m) m = msg_message("flying_ship_result", "mage ship", mage, sh); - add_message(&u->faction->msgs, m); - } - } - if (m) msg_release(m); - return cast_level; -} - - -/* ------------------------------------------------------------- */ -/* Name: Stehle Aura - * Stufe: 6 - * Kategorie: Einheit, negativ - * Wirkung: - * Mit Hilfe dieses Zaubers kann der Magier einem anderen Magier - * seine Aura gegen dessen Willen entziehen und sich selber - * zuf�hren. - * - * Flags: - * (FARCASTING | SPELLLEVEL | UNITSPELL | TESTRESISTANCE | - * TESTCANSEE) - * */ -int -sp_stealaura(castorder *co) -{ - int taura; - unit *u; - unit *mage = co->magician.u; - int cast_level = co->level; - double power = co->force; - spellparameter *pa = co->par; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - /* Zieleinheit */ - u = pa->param[0]->data.u; - - if (!get_mage(u)) { - ADDMSG(&mage->faction->msgs, msg_message( - "stealaura_fail", "unit target", mage, u)); - ADDMSG(&u->faction->msgs, msg_message( - "stealaura_fail_detect", "unit", u)); - return 0; - } - - taura = (get_mage(u)->spellpoints*(rng_int()%(int)(3*power)+1))/100; - - if (taura > 0) { - get_mage(u)->spellpoints -= taura; - get_mage(mage)->spellpoints += taura; -/* sprintf(buf, "%s entzieht %s %d Aura.", unitname(mage), unitname(u), - taura); */ - ADDMSG(&mage->faction->msgs, msg_message( - "stealaura_success", "mage target aura", mage, u, taura)); -/* sprintf(buf, "%s f�hlt seine magischen Kr�fte schwinden und verliert %d " - "Aura.", unitname(u), taura); */ - ADDMSG(&u->faction->msgs, msg_message( - "stealaura_detect", "unit aura", u, taura)); - } else { - ADDMSG(&mage->faction->msgs, msg_message( - "stealaura_fail", "unit target", mage, u)); - ADDMSG(&u->faction->msgs, msg_message( - "stealaura_fail_detect", "unit", u)); - } - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Astrale Schw�chezone - * Stufe: 5 - * Kategorie: - * Wirkung: - * Reduziert die St�rke jedes Spruch in der Region um Level H�lt - * Spr�che bis zu einem Gesammtlevel von St�rke*10 aus, danach ist - * sie verbraucht. - * leibt bis zu St�rke Wochen aktiv. - * Ein Ring der Macht erh�ht die St�rke um 1, in einem Magierturm - * gezaubert gibt nochmal +1 auf St�rke. (force) - * - * Beispiel: - * Eine Antimagiezone Stufe 7 h�lt bis zu 7 Wochen an oder Spr�che mit - * einem Gesammtlevel bis zu 70 auf. Also zB 7 Stufe 10 Spr�che, 10 - * Stufe 7 Spr�che oder 35 Stufe 2 Spr�che. Sie reduziert die St�rke - * (level+boni) jedes Spruchs, der in der Region gezaubert wird, um - * 7. Alle Spr�che mit einer St�rke kleiner als 7 schlagen fehl - * (power = 0). - * - * Flags: - * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) - * - */ -int -sp_antimagiczone(castorder *co) -{ - double power; - double effect; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - int duration = (int)force+1; - - /* H�lt Spr�che bis zu einem summierten Gesamtlevel von power aus. - * Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone - * um seine Stufe */ - power = force * 10; - - /* Reduziert die St�rke jedes Spruchs um effect */ - effect = cast_level; - - create_curse(mage, &r->attribs, ct_find("antimagiczone"), power, duration, - effect, 0); - - /* Erfolg melden*/ - ADDMSG(&mage->faction->msgs, msg_message( - "regionmagic_effect", "unit region command", mage, - mage->region, co->order)); - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Schutzrunen - * Stufe: 8 - * Kosten: SPC_FIX - * - * Wirkung: - * Gibt Geb�uden einen Bonus auf Magieresistenz von +20%. Der Zauber - * dauert 3+rng_int()%Level Wochen an, also im Extremfall bis zu 2 Jahre - * bei Stufe 20 - * - * Es k�nnen mehrere Zauber �bereinander gelegt werden, der Effekt - * summiert sich, jedoch wird die Dauer dadurch nicht verl�ngert. - * - * oder: - * - * Gibt Schiffen einen Bonus auf Magieresistenz von +20%. Der Zauber - * dauert 3+rng_int()%Level Wochen an, also im Extremfall bis zu 2 Jahre - * bei Stufe 20 - * - * Es k�nnen mehrere Zauber �bereinander gelegt werden, der Effekt - * summiert sich, jedoch wird die Dauer dadurch nicht verl�ngert. - * - * Flags: - * (ONSHIPCAST | TESTRESISTANCE) - * - * Syntax: - * ZAUBERE \"Runen des Schutzes\" GEBAEUDE <Gebaeude-Nr> - * ZAUBERE \"Runen des Schutzes\" SCHIFF <Schiff-Nr> - * "kc" - */ - -static int -sp_magicrunes(castorder *co) -{ - int duration; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - spellparameter *pa = co->par; - double effect; - - duration = 3 + rng_int()%cast_level; - effect = 20; - - switch(pa->param[0]->typ) { - case SPP_BUILDING: - { - building *b; - b = pa->param[0]->data.b; - - /* Magieresistenz der Burg erh�ht sich um 20% */ - create_curse(mage, &b->attribs, ct_find("magicrunes"), force, - duration, effect, 0); - - /* Erfolg melden */ - ADDMSG(&mage->faction->msgs, msg_message( - "objmagic_effect", "unit region command target", mage, - mage->region, co->order, buildingname(b))); - break; - } - case SPP_SHIP: - { - ship *sh; - sh = pa->param[0]->data.sh; - /* Magieresistenz des Schiffs erh�ht sich um 20% */ - create_curse(mage, &sh->attribs, ct_find("magicrunes"), force, - duration, effect, 0); - - /* Erfolg melden */ - ADDMSG(&mage->faction->msgs, msg_message( - "objmagic_effect", "unit region command target", mage, - mage->region, co->order, shipname(sh))); - break; - } - default: - /* fehlerhafter Parameter */ - return 0; - } - - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Zeitdehnung - * - * Flags: - * (UNITSPELL | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) - * Syntax: - * "u+" - */ - -int -sp_speed2(castorder *co) -{ - int n, maxmen, used = 0, dur, men; - unit *u; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - spellparameter *pa = co->par; - - maxmen = 2 * cast_level * cast_level; - dur = MAX(1, cast_level/2); - - for (n = 0; n < pa->length; n++) { - double effect; - /* sollte nie negativ werden */ - if (maxmen < 1) - break; - - if (pa->param[n]->flag == TARGET_RESISTS - || pa->param[n]->flag == TARGET_NOTFOUND) - continue; - - u = pa->param[n]->data.u; - - men = MIN(maxmen,u->number); - effect = 2; - create_curse(mage, &u->attribs, ct_find("speed"), force, dur, effect, men); - maxmen -= men; - used += men; - } - - ADDMSG(&mage->faction->msgs, msg_message("speed_time_effect", "unit region amount", mage, mage->region, used)); - /* Effektiv ben�tigten cast_level (mindestens 1) zur�ckgeben */ - used = (int)sqrt(used/2); - return MAX(1, used); -} - -/* ------------------------------------------------------------- */ -/* Name: Magiefresser - * Stufe: 7 - * Kosten: SPC_LEVEL - * - * Wirkung: - * Kann eine bestimmte Verzauberung angreifen und aufl�sen. Die St�rke - * des Zaubers muss st�rker sein als die der Verzauberung. - * Syntax: - * ZAUBERE \"Magiefresser\" REGION - * ZAUBERE \"Magiefresser\" EINHEIT <Einheit-Nr> - * ZAUBERE \"Magiefresser\" GEBAEUDE <Gebaeude-Nr> - * ZAUBERE \"Magiefresser\" SCHIFF <Schiff-Nr> - * - * "kc?c" - * Flags: - * (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) - */ -/* Jeder gebrochene Zauber verbraucht c->vigour an Zauberkraft - * (force) */ -int -sp_q_antimagie(castorder *co) -{ - attrib **ap; - int obj; - curse * c = NULL; - int succ; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - spellparameter *pa = co->par; - const char *ts = NULL; - - obj = pa->param[0]->typ; - - switch(obj) { - case SPP_REGION: - ap = &r->attribs; - ts = regionname(r, mage->faction); - break; - - case SPP_TEMP: - case SPP_UNIT: - { - unit *u = pa->param[0]->data.u; - ap = &u->attribs; - ts = unitid(u); - break; - } - case SPP_BUILDING: - { - building *b = pa->param[0]->data.b; - ap = &b->attribs; - ts = buildingid(b); - break; - } - case SPP_SHIP: - { - ship *sh = pa->param[0]->data.sh; - ap = &sh->attribs; - ts = shipid(sh); - break; - } - default: - /* Das Zielobjekt wurde vergessen */ - cmistake(mage, co->order, 203, MSG_MAGIC); - return 0; - } - - succ = break_curse(ap, cast_level, force, c); - - if (succ) { - ADDMSG(&mage->faction->msgs, msg_message( - "destroy_magic_effect", "unit region command succ target", - mage, mage->region, co->order, succ, ts)); - } else { - ADDMSG(&mage->faction->msgs, msg_message( - "destroy_magic_noeffect", "unit region command", - mage, mage->region, co->order)); - } - return MAX(succ, 1); -} - -/* ------------------------------------------------------------- */ -/* Name: Fluch brechen - * Stufe: 7 - * Kosten: SPC_LEVEL - * - * Wirkung: - * Kann eine bestimmte Verzauberung angreifen und aufl�sen. Die St�rke - * des Zaubers muss st�rker sein als die der Verzauberung. - * Syntax: - * ZAUBERE \"Fluch brechen\" REGION <Zauber-id> - * ZAUBERE \"Fluch brechen\" EINHEIT <Einheit-Nr> <Zauber-id> - * ZAUBERE \"Fluch brechen\" GEBAEUDE <Gebaeude-Nr> <Zauber-id> - * ZAUBERE \"Fluch brechen\" SCHIFF <Schiff-Nr> <Zauber-id> - * - * "kcc" - * Flags: - * (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) - */ -int -sp_break_curse(castorder *co) -{ - attrib **ap; - int obj; - curse * c; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - double force = co->force; - spellparameter *pa = co->par; - const char *ts = NULL; - - if (pa->length < 2) { - /* Das Zielobjekt wurde vergessen */ - cmistake(mage, co->order, 203, MSG_MAGIC); - } - - obj = pa->param[0]->typ; - - c = findcurse(atoi36(pa->param[1]->data.s)); - if (!c) { - /* Es wurde kein Ziel gefunden */ - ADDMSG(&mage->faction->msgs, msg_message( - "spelltargetnotfound", "unit region command", - mage, mage->region, co->order)); - } else { - switch(obj) { - case SPP_REGION: - ap = &r->attribs; - ts = regionname(r, mage->faction); - break; - - case SPP_TEMP: - case SPP_UNIT: - { - unit *u = pa->param[0]->data.u; - ap = &u->attribs; - ts = unitid(u); - break; - } - case SPP_BUILDING: - { - building *b = pa->param[0]->data.b; - ap = &b->attribs; - ts = buildingid(b); - break; - } - case SPP_SHIP: - { - ship *sh = pa->param[0]->data.sh; - ap = &sh->attribs; - ts = shipid(sh); - break; - } - default: - /* Das Zielobjekt wurde vergessen */ - cmistake(mage, co->order, 203, MSG_MAGIC); - return 0; - } - - /* �berpr�fung, ob curse zu diesem objekt geh�rt */ - if (!is_cursed_with(*ap, c)) { - /* Es wurde kein Ziel gefunden */ - ADDMSG(&mage->faction->msgs, - msg_message( - "spelltargetnotfound", "unit region command", - mage, mage->region, co->order)); - } - - /* curse aufl�sen, wenn zauber st�rker (force > vigour)*/ - c->vigour -= force; - - if (c->vigour <= 0.0) { - remove_curse(ap, c); - - ADDMSG(&mage->faction->msgs, msg_message( - "destroy_curse_effect", "unit region command id target", - mage, mage->region, co->order, pa->param[1]->data.xs, ts)); - } else { - ADDMSG(&mage->faction->msgs, msg_message( - "destroy_curse_noeffect", "unit region command id target", - mage, mage->region, co->order, pa->param[1]->data.xs, ts)); - } - } - - return cast_level; -} - - -/* ------------------------------------------------------------- */ -int -sp_becomewyrm(castorder *co) -{ - return 0; -} - -/* ------------------------------------------------------------- */ -/* Name: WDW-Pyramidenfindezauber - * Stufe: unterschiedlich - * Gebiet: alle - * Wirkung: - * gibt die ungefaehre Entfernung zur naechstgelegenen Pyramiden- - * region an. - * - * Flags: - */ -static int -sp_wdwpyramid(castorder *co) -{ - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - - if (a_find(r->attribs, &at_wdwpyramid) != NULL) { - ADDMSG(&mage->faction->msgs, msg_message("wdw_pyramidspell_found", - "unit region command", mage, r, co->order)); - } else { - region *r2; - int mindist = INT_MAX; - int minshowdist; - int maxshowdist; - - for(r2 = regions; r2; r2 = r2->next) { - if (a_find(r2->attribs, &at_wdwpyramid) != NULL) { - int dist = distance(mage->region, r2); - if (dist < mindist) { - mindist = dist; - } - } - } - - assert(mindist >= 1); - - minshowdist = mindist - rng_int()%5; - maxshowdist = minshowdist + 4; - - ADDMSG(&mage->faction->msgs, msg_message("wdw_pyramidspell_notfound", - "unit region command mindist maxdist", mage, r, co->order, - MAX(1, minshowdist), maxshowdist)); - } - - return cast_level; -} - -typedef struct spelldata { - spellid_t id; - const char *sname; - spell_f sp_function; - void (*patzer) (castorder*); -} spelldata; - -static spelldata spelldaten[] = -{ - /* M_GWYRRD */ - { - SPL_STONEGOLEM, "stonegolem", - (spell_f)sp_create_stonegolem, NULL - }, - { - SPL_IRONGOLEM, "irongolem", - (spell_f)sp_create_irongolem, NULL - }, - { - SPL_TREEGROW, "treegrow", - (spell_f)sp_hain, patzer_ents - }, - { - SPL_RUSTWEAPON, "rustweapon", - (spell_f)sp_rosthauch, NULL - }, - { - SPL_KAELTESCHUTZ, "cold_protection", - (spell_f)sp_kaelteschutz, NULL - }, - { - SPL_HAGEL, "hail", - (spell_f)sp_kampfzauber, NULL - }, - { - SPL_IRONKEEPER, "ironkeeper", - (spell_f)sp_ironkeeper, NULL - }, - { - SPL_MAGICSTREET, "magicstreet", - (spell_f)sp_magicstreet, NULL - }, - { - SPL_WINDSHIELD, "windshield", - (spell_f)sp_windshield, NULL - }, - { - SPL_MALLORNTREEGROW, "mallorntreegrow", - (spell_f)sp_mallornhain, patzer_ents - }, - { SPL_GOODWINDS, "goodwinds", - (spell_f)sp_goodwinds, NULL - }, - { - SPL_HEALING, "healing", - (spell_f)sp_healing, NULL - }, - { - SPL_REELING_ARROWS, "reelingarrows", - (spell_f)sp_reeling_arrows, NULL - }, - { - SPL_GWYRRD_FUMBLESHIELD, "gwyrrdfumbleshield", - (spell_f)sp_fumbleshield, NULL - }, - { - SPL_TRANSFERAURA_DRUIDE, "transferauradruide", - (spell_f)sp_transferaura, NULL - }, - { - SPL_EARTHQUAKE, "earthquake", - (spell_f)sp_earthquake, NULL - }, - { - SPL_STORMWINDS, "stormwinds", - (spell_f)sp_stormwinds, NULL - }, - { - SPL_HOMESTONE, "homestone", - (spell_f)sp_homestone, NULL - }, - { - SPL_WOLFHOWL, "wolfhowl", - (spell_f)sp_wolfhowl, NULL - }, - { - SPL_VERSTEINERN, "versteinern", - (spell_f)sp_petrify, NULL - }, - { - SPL_STRONG_WALL, "strongwall", - (spell_f)sp_strong_wall, NULL - }, - { - SPL_GWYRRD_DESTROY_MAGIC, "gwyrrddestroymagic", - (spell_f)sp_destroy_magic, NULL - }, - { - SPL_TREEWALKENTER, "treewalkenter", - (spell_f)sp_treewalkenter, NULL - }, - { - SPL_TREEWALKEXIT, "treewalkexit", - (spell_f)sp_treewalkexit, NULL - }, - { - SPL_HOLYGROUND, "holyground", - (spell_f)sp_holyground, NULL - }, - { - SPL_SUMMONENT, "summonent", - (spell_f)sp_summonent, NULL - }, - { - SPL_GWYRRD_FAMILIAR, "gwyrrdfamiliar", - (spell_f)sp_summon_familiar, NULL - }, - { - SPL_BLESSSTONECIRCLE, "blessstonecircle", - (spell_f)sp_blessstonecircle, NULL - }, - { - SPL_GWYRRD_ARMORSHIELD, "barkskin", - (spell_f)sp_armorshield, NULL - }, - { - SPL_DROUGHT, "summonfireelemental", - (spell_f)sp_drought, NULL - }, - { - SPL_MAELSTROM, "maelstrom", - (spell_f)sp_maelstrom, NULL - }, - { - SPL_MALLORN, "magic_roots", - (spell_f)sp_mallorn, NULL - }, - { - SPL_GREAT_DROUGHT, "great_drought", - (spell_f)sp_great_drought, NULL - }, - /* M_DRAIG */ - { - SPL_SPARKLE_CHAOS, "sparklechaos", - (spell_f)sp_sparkle, NULL - }, - { - SPL_FIREBALL, "fireball", - (spell_f)sp_kampfzauber, NULL - }, - { - SPL_MAGICBOOST, "magicboost", - (spell_f)sp_magicboost, NULL - }, - { - SPL_BLOODSACRIFICE, "bloodsacrifice", - (spell_f)sp_bloodsacrifice, NULL - }, - { - SPL_BERSERK, "berserk", - (spell_f)sp_berserk, NULL - }, - { - SPL_FUMBLECURSE, "fumblecurse", - (spell_f)sp_fumblecurse, patzer_fumblecurse - }, - { - SPL_SUMMONUNDEAD, "summonundead", - (spell_f)sp_summonundead, patzer_peasantmob - }, - { - SPL_COMBATRUST, "combatrust", - (spell_f)sp_combatrosthauch, NULL - }, - { - SPL_TRANSFERAURA_CHAOS, "transferaurachaos", - (spell_f)sp_transferaura, NULL - }, - { - SPL_FIREWALL, "firewall", - (spell_f)sp_firewall, patzer_peasantmob - }, - { - SPL_PLAGUE, "plague", - (spell_f)sp_plague, patzer_peasantmob - }, - { - SPL_CHAOSROW, "chaosrow", - (spell_f)sp_chaosrow, NULL - }, - { - SPL_SUMMONSHADOW, "summonshadow", - (spell_f)sp_summonshadow, patzer_peasantmob - }, - { - SPL_UNDEADHERO, "undeadhero", - (spell_f)sp_undeadhero, NULL - }, - { - SPL_AURALEAK, "auraleak", - (spell_f)sp_auraleak, NULL - }, - { - SPL_DRAIG_FUMBLESHIELD, "draigfumbleshield", - (spell_f)sp_fumbleshield, NULL - }, - { - SPL_FOREST_FIRE, "forestfire", - (spell_f)sp_forest_fire, patzer_peasantmob - }, - { - SPL_DRAIG_DESTROY_MAGIC, "draigdestroymagic", - (spell_f)sp_destroy_magic, NULL - }, - { - SPL_UNHOLYPOWER, "unholypower", - (spell_f)sp_unholypower, NULL - }, - { - SPL_DEATHCLOUD, "deathcloud", - (spell_f)sp_deathcloud, patzer_peasantmob - }, - { - SPL_SUMMONDRAGON, "summondragon", - (spell_f)sp_summondragon, patzer_peasantmob - }, - { - SPL_SUMMONSHADOWLORDS, "summonshadowlords", - (spell_f)sp_summonshadowlords, patzer_peasantmob - }, - { - SPL_DRAIG_FAMILIAR, "draigfamiliar", - (spell_f)sp_summon_familiar, NULL - }, - { - SPL_CHAOSSUCTION, "chaossuction", - (spell_f)sp_chaossuction, patzer_peasantmob - }, - /* M_ILLAUN */ - { - SPL_SPARKLE_DREAM, "sparkledream", - (spell_f)sp_sparkle, NULL - }, - { - SPL_SHADOWKNIGHTS, "shadowknights", - (spell_f)sp_shadowknights, NULL - }, - { - SPL_FLEE, "flee", - (spell_f)sp_flee, NULL - }, - { - SPL_PUTTOREST, "puttorest", - (spell_f)sp_puttorest, NULL - }, - { - SPL_ICASTLE, "icastle", - (spell_f)sp_icastle, NULL - }, - { - SPL_TRANSFERAURA_TRAUM, "transferauratraum", - (spell_f)sp_transferaura, NULL - }, - { - SPL_ILL_SHAPESHIFT, "shapeshift", - (spell_f)sp_illusionary_shapeshift, NULL - }, - { - SPL_DREAMREADING, "dreamreading", - (spell_f)sp_dreamreading, NULL - }, - { - SPL_TIREDSOLDIERS, "tiredsoldiers", - (spell_f)sp_tiredsoldiers, NULL - }, - { - SPL_REANIMATE, "reanimate", - (spell_f)sp_reanimate, NULL - }, - { - SPL_ANALYSEDREAM, "analysedream", - (spell_f)sp_analysedream, NULL - }, - { - SPL_DISTURBINGDREAMS, "disturbingdreams", - (spell_f)sp_disturbingdreams, NULL - }, - { - SPL_SLEEP, "sleep", - (spell_f)sp_sleep, NULL - }, - { - SPL_WISPS, "wisps", - (spell_f)sp_wisps, NULL - }, - { - SPL_GOODDREAMS, "gooddreams", - (spell_f)sp_gooddreams, NULL - }, - { - SPL_ILLAUN_DESTROY_MAGIC, "illaundestroymagic", - (spell_f)sp_destroy_magic, NULL - }, - { - SPL_ILLAUN_FAMILIAR, "illaunfamiliar", - (spell_f)sp_summon_familiar, NULL - }, - { - SPL_CLONECOPY, "clone", - (spell_f)sp_clonecopy, NULL - }, - { - SPL_BADDREAMS, "bad_dreams", - (spell_f)sp_baddreams, NULL - }, - { - SPL_MINDBLAST, "mindblast", - (spell_f)sp_mindblast_temp, NULL - }, - { - SPL_ORKDREAM, "orkdream", - (spell_f)sp_sweetdreams, NULL - }, - { - SPL_SUMMON_ALP, "summon_alp", - (spell_f)sp_summon_alp, NULL - }, - /* M_CERDDOR */ - { - SPL_DENYATTACK, "appeasement", - (spell_f)sp_denyattack, NULL - }, - { - SPL_HEALINGSONG, "song_of_healing", - (spell_f)sp_healing, NULL - }, - { - SPL_GENEROUS, "generous", - (spell_f)sp_generous, NULL - }, - { - SPL_SONG_OF_FEAR, "song_of_fear", - (spell_f)sp_flee, NULL - }, - { - SPL_RECRUIT, "courting", - (spell_f)sp_recruit, NULL - }, - { - SPL_SONG_OF_CONFUSION, "song_of_confusion", - (spell_f)sp_chaosrow, NULL - }, - { - SPL_HERO, "heroic_song", - (spell_f)sp_hero, NULL - }, - { - SPL_TRANSFERAURA_BARDE, "transfer_aura_song", - (spell_f)sp_transferaura, NULL - }, - { - SPL_UNIT_ANALYSESONG, "analysesong_unit", - (spell_f)sp_analysesong_unit, NULL - }, - { - SPL_CERRDOR_FUMBLESHIELD, "cerrdorfumbleshield", - (spell_f)sp_fumbleshield, NULL - }, - { SPL_CALM_MONSTER, "calm_monster", - (spell_f)sp_calm_monster, NULL - }, - { SPL_SEDUCE, "seduction", - (spell_f)sp_seduce, NULL - }, - { - SPL_HEADACHE, "headache", - (spell_f)sp_headache, NULL - }, - { SPL_PUMP, "sound_out", - (spell_f)sp_pump, NULL - }, - { - SPL_BLOODTHIRST, "bloodthirst", - (spell_f)sp_berserk, NULL - }, - { - SPL_FRIGHTEN, "frighten", - (spell_f)sp_frighten, NULL - }, - { - SPL_OBJ_ANALYSESONG, "analyse_object", - (spell_f)sp_analysesong_obj, NULL - }, - { - SPL_CERDDOR_DESTROY_MAGIC, "cerddor_destroymagic", - (spell_f)sp_destroy_magic, NULL - }, - { - SPL_MIGRANT, "migration", - (spell_f)sp_migranten, NULL - }, - { - SPL_CERDDOR_FAMILIAR, "summon_familiar", - (spell_f)sp_summon_familiar, NULL - }, - { - SPL_RAISEPEASANTS, "raise_mob", - (spell_f)sp_raisepeasants, NULL - }, - { - SPL_SONG_RESISTMAGIC, "song_resist_magic", - (spell_f)sp_song_resistmagic, NULL - }, - { - SPL_DEPRESSION, "melancholy", - (spell_f)sp_depression, NULL - }, - { - SPL_SONG_SUSCEPTMAGIC, "song_suscept_magic", - (spell_f)sp_song_susceptmagic, NULL - }, - { - SPL_SONG_OF_PEACE, "song_of_peace", - (spell_f)sp_song_of_peace, NULL - }, - { - SPL_SONG_OF_ENSLAVE, "song_of_slavery", - (spell_f)sp_charmingsong, NULL - }, - { - SPL_BIGRECRUIT, "big_recruit", - (spell_f)sp_bigrecruit, NULL - }, - { - SPL_RALLYPEASANTMOB, "calm_riot", - (spell_f)sp_rallypeasantmob, NULL - }, - { - SPL_RAISEPEASANTMOB, "incite_riot", - (spell_f)sp_raisepeasantmob, NULL - }, - /* M_TYBIED */ - { - SPL_ANALYSEMAGIC, "analyze_magic", - (spell_f)sp_analysemagic, NULL - }, - { - SPL_ITEMCLOAK, "concealing_aura", - (spell_f)sp_itemcloak, NULL - }, - { - SPL_TYBIED_FUMBLESHIELD, "tybiedfumbleshield", - (spell_f)sp_fumbleshield, NULL - }, -#ifdef SHOWASTRAL_NOT_BORKED - { - SPL_SHOWASTRAL, "show_astral", - (spell_f)sp_showastral, NULL - }, -#endif - { - SPL_RESISTMAGICBONUS, "resist_magic", - (spell_f)sp_resist_magic_bonus, NULL - }, - { - SPL_KEEPLOOT, "keeploot", - (spell_f)sp_keeploot, NULL - }, - { - SPL_ENTERASTRAL, "enterastral", - (spell_f)sp_enterastral, NULL - }, - { - SPL_LEAVEASTRAL, "leaveastral", - (spell_f)sp_leaveastral, NULL - }, - { - SPL_TRANSFERAURA_ASTRAL, "auratransfer", - (spell_f)sp_transferaura, NULL - }, - { - SPL_SHOCKWAVE, "shockwave", - (spell_f)sp_stun, NULL - }, - { - SPL_ANTIMAGICZONE, "antimagiczone", - (spell_f)sp_antimagiczone, NULL - }, - { - SPL_TYBIED_DESTROY_MAGIC, "destroy_magic", - (spell_f)sp_destroy_magic, NULL - }, - { - SPL_PULLASTRAL, "pull_astral", - (spell_f)sp_pullastral, NULL - }, - - { - SPL_FETCHASTRAL, "fetch_astral", - (spell_f)sp_fetchastral, NULL - }, - { - SPL_STEALAURA, "steal_aura", - (spell_f)sp_stealaura, NULL - }, - { - SPL_FLYING_SHIP, "airship", - (spell_f)sp_flying_ship, NULL - }, - { - SPL_DESTROY_MAGIC, "break_curse", - (spell_f)sp_break_curse, NULL - }, - { - SPL_ETERNIZEWALL, "eternal_walls", - (spell_f)sp_eternizewall, NULL - }, - { - SPL_SCHILDRUNEN, "protective_runes", - (spell_f)sp_magicrunes, NULL - }, - - { - SPL_REDUCESHIELD, "fish_shield", - (spell_f)sp_reduceshield, NULL - }, - { - SPL_SPEED, "combat_speed", - (spell_f)sp_speed, NULL - }, - { - SPL_VIEWREALITY, "view_reality", - (spell_f)sp_viewreality, NULL - }, - { - SPL_SPEED2, "double_time", - (spell_f)sp_speed2, NULL - }, - { - SPL_ARMORSHIELD, "armor_shield", - (spell_f)sp_armorshield, NULL - }, - { - SPL_TYBIED_FAMILIAR, "summon_familiar", - (spell_f)sp_summon_familiar, NULL - }, - { - SPL_MOVECASTLE, "living_rock", - (spell_f)sp_movecastle, NULL - }, - { - SPL_DISRUPTASTRAL, "astral_disruption", - (spell_f)sp_disruptastral, NULL - }, - { - SPL_PERMTRANSFER, "sacrifice_strength", - (spell_f)sp_permtransfer, NULL - }, - /* M_GRAY */ - /* Definitionen von Create_Artefaktspr�chen */ - { - SPL_METEORRAIN, "meteor_rain", - (spell_f)sp_kampfzauber, NULL - }, - { - SPL_BECOMEWYRM, "wyrm_transformation", - (spell_f)sp_becomewyrm, NULL - }, - /* Monsterspr�che */ - { SPL_FIREDRAGONODEM, "fiery_dragonbreath", - (spell_f)sp_dragonodem, NULL - }, - { SPL_DRAGONODEM, "icy_dragonbreath", - (spell_f)sp_dragonodem, NULL - }, - { SPL_WYRMODEM, "powerful_dragonbreath", - (spell_f)sp_dragonodem, NULL - }, - { SPL_DRAINODEM, "drain_skills", - (spell_f)sp_dragonodem, NULL - }, - { - SPL_AURA_OF_FEAR, "aura_of_fear", - (spell_f)sp_flee, NULL - }, - { - SPL_SHADOWCALL, "shadowcall", - (spell_f)sp_shadowcall, NULL - }, - { - SPL_IMMOLATION, "immolation", - (spell_f)sp_immolation, NULL - }, - { SPL_FIREODEM, "firestorm", - (spell_f)sp_immolation, NULL - }, - { SPL_ICEODEM, "coldfront", - (spell_f)sp_immolation, NULL - }, - { SPL_ACIDODEM, "acidrain", - (spell_f)sp_immolation, NULL - }, - /* SPL_NOSPELL MUSS der letzte Spruch der Liste sein*/ - { - SPL_NOSPELL, "no spell", - NULL, NULL - } -}; - -static boolean -chaosgate_valid(const connection * b) -{ - const attrib * a = a_findc(b->from->attribs, &at_direction); - if (!a) a = a_findc(b->to->attribs, &at_direction); - if (!a) return false; - return true; -} - -struct region * -chaosgate_move(const connection * b, struct unit * u, struct region * from, struct region * to, boolean routing) -{ - if (!routing) { - int maxhp = u->hp / 4; - if (maxhp<u->number) maxhp = u->number; - u->hp = maxhp; - } - return to; -} - -border_type bt_chaosgate = { - "chaosgate", VAR_NONE, - b_transparent, /* transparent */ - NULL, /* init */ - NULL, /* destroy */ - NULL, /* read */ - NULL, /* write */ - b_blocknone, /* block */ - NULL, /* name */ - b_rinvisible, /* rvisible */ - b_finvisible, /* fvisible */ - b_uinvisible, /* uvisible */ - chaosgate_valid, - chaosgate_move -}; - -static void -set_spelldata_i(spell * sp, spelldata * data) -{ - sp->sp_function = data->sp_function; - sp->patzer = data->patzer; -} - -void -set_spelldata(spell * sp) -{ - int i; - for (i=0;spelldaten[i].id!=SPL_NOSPELL;++i) { - spelldata * data = spelldaten+i; - if (strcmp(data->sname, sp->sname)==0) { - set_spelldata_i(sp, data); - return; - } - } - log_error(("unknown spell %s.\n", sp->sname)); - assert(!"there is no spell by that name"); -} - -/* ------------------------------------------------------------- */ -/* Name: Plappermaul -* Stufe: 4 -* Gebiet: Cerddor -* Kategorie: Einheit -* -* Wirkung: -* Einheit ausspionieren. Gibt auch Zauber und Kampfstatus aus. Wirkt -* gegen Magieresistenz. Ist diese zu hoch, so wird der Zauber entdeckt -* (Meldung) und der Zauberer erh�lt nur die Talente, nicht die Werte -* der Einheit und auch keine Zauber. -* -* Flag: -* (UNITSPELL | TESTCANSEE) -*/ -static int -sp_babbler(castorder *co) -{ - unit *target; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - message * msg; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - target = pa->param[0]->data.u; - - if (target->faction == mage->faction) { - /* Die Einheit ist eine der unsrigen */ - cmistake(mage, co->order, 45, MSG_MAGIC); - } - - /* Magieresistenz Unit */ - if (target_resists_magic(mage, target, TYP_UNIT, 0)) { - spy_message(5, mage, target); - msg = msg_message("babbler_resist", "unit mage", target, mage); - } else { - spy_message(100, mage, target); - msg = msg_message("babbler_effect", "unit", target); - } - r_addmessage(r, target->faction, msg); - msg_release(msg); - return cast_level; -} - -/* ------------------------------------------------------------- */ -/* Name: Traumdeuten -* Stufe: 7 -* Kategorie: Einheit -* -* Wirkung: -* Wirkt gegen Magieresistenz. Spioniert die Einheit aus. Gibt alle -* Gegenst�nde, Talente mit Stufe, Zauber und Kampfstatus an. -* -* Magieresistenz hier pr�fen, wegen Fehlermeldung -* -* Flag: -* (UNITSPELL) -*/ -static int -sp_readmind(castorder *co) -{ - unit *target; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; - - /* wenn kein Ziel gefunden, Zauber abbrechen */ - if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; - - target = pa->param[0]->data.u; - - if (target->faction == mage->faction) { - /* Die Einheit ist eine der unsrigen */ - cmistake(mage, co->order, 45, MSG_MAGIC); - } - - /* Magieresistenz Unit */ - if (target_resists_magic(mage, target, TYP_UNIT, 0)) { - cmistake(mage, co->order, 180, MSG_MAGIC); - /* "F�hlt sich beobachtet"*/ - ADDMSG(&target->faction->msgs, msg_message("stealdetect", "unit", target)); - return 0; - } - spy_message(2, mage, target); - - return cast_level; -} - -void -register_spells(void) -{ - set_spelldata_cb = &set_spelldata; - at_register(&at_wdwpyramid); - at_register(&at_deathcloud_compat); - - /* sp_summon_alp */ - register_alp(); - - /* init_firewall(); */ - ct_register(&ct_firewall); - ct_register(&ct_deathcloud); - - register_function((pf_generic)&sp_blessedharvest, "cast_blessedharvest"); - register_function((pf_generic)&sp_wdwpyramid, "wdwpyramid"); - register_function((pf_generic)&sp_summon_familiar, "cast_familiar"); - register_function((pf_generic)&sp_babbler, "cast_babbler"); - register_function((pf_generic)&sp_readmind, "cast_readmind"); -} +/* vi: set ts=2: + * + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#include <platform.h> +#include <kernel/config.h> +#include "spells.h" + +#include "buildingcurse.h" +#include "regioncurse.h" +#include "unitcurse.h" +#include "shipcurse.h" + +/* kernel includes */ +#include <kernel/curse.h> +#include <kernel/battle.h> /* f�r lovar */ +#include <kernel/connection.h> +#include <kernel/building.h> +#include <kernel/curse.h> +#include <kernel/spellid.h> +#include <kernel/faction.h> +#include <kernel/reports.h> +#include <kernel/item.h> +#include <kernel/magic.h> +#include <kernel/message.h> +#include <kernel/objtypes.h> +#include <kernel/order.h> +#include <kernel/plane.h> +#include <kernel/pool.h> +#include <kernel/race.h> +#include <kernel/region.h> +#include <kernel/save.h> +#include <kernel/ship.h> +#include <kernel/skill.h> +#include <kernel/spell.h> +#include <kernel/teleport.h> +#include <kernel/terrain.h> +#include <kernel/terrainid.h> +#include <kernel/unit.h> +#include <kernel/xmlreader.h> +#include <kernel/version.h> + +#include <gamecode/spy.h> + +/* spells includes */ +#include "alp.h" + +/* util includes */ +#include <util/attrib.h> +#include <util/base36.h> +#include <util/event.h> +#include <util/language.h> +#include <util/message.h> +#include <util/parser.h> +#include <util/umlaut.h> +#include <util/functions.h> +#include <util/lists.h> +#include <util/rand.h> +#include <util/log.h> +#include <util/nrmessage.h> +#include <util/bsdstring.h> +#include <util/variant.h> +#include <util/goodies.h> +#include <util/resolve.h> +#include <util/rng.h> +#include <util/storage.h> + +/* libc includes */ +#include <assert.h> +#include <ctype.h> +#include <math.h> +#include <stdio.h> +#include <string.h> +#include <limits.h> + +/* triggers includes */ +#include <triggers/changefaction.h> +#include <triggers/changerace.h> +#include <triggers/createcurse.h> +#include <triggers/createunit.h> +#include <triggers/killunit.h> +#include <triggers/timeout.h> +#include <triggers/unitmessage.h> + +/* attributes includes */ +#include <attributes/targetregion.h> +#include <attributes/hate.h> +/* ----------------------------------------------------------------------- */ + +static double zero_effect = 0.0; + +attrib_type at_wdwpyramid = { + "wdwpyramid", NULL, NULL, NULL, a_writevoid, a_readvoid +}; + +/* ----------------------------------------------------------------------- */ + +static void +report_spell(unit * mage, region * r, message * msg) +{ + r_addmessage(r, NULL, msg); + if (mage && mage->region!=r) { + add_message(&mage->faction->msgs, msg); + } +} + +static void +report_failure(unit * mage, struct order * ord) { + /* Fehler: "Der Zauber schl�gt fehl" */ + cmistake(mage, ord, 180, MSG_MAGIC); +} + +/* ------------------------------------------------------------- */ +/* Spruchanalyse - Ausgabe von curse->info und curse->name */ +/* ------------------------------------------------------------- */ + +static double +curse_chance(const struct curse * c, double force) +{ + return 1.0 + (force - c->vigour) * 0.1; +} + +static void +magicanalyse_region(region *r, unit *mage, double force) +{ + attrib *a; + boolean found = false; + + for (a=r->attribs;a;a=a->next) { + curse * c = (curse*)a->data.v; + double probability; + int mon; + + if (!fval(a->type, ATF_CURSE)) continue; + + /* ist der curse schw�cher als der Analysezauber, so ergibt sich + * mehr als 100% probability und damit immer ein Erfolg. */ + probability = curse_chance(c, force); + mon = c->duration + (rng_int()%10) - 5; + mon = MAX(1, mon); + found = true; + + if (chance(probability)) { /* Analyse gegl�ckt */ + if (c_flags(c) & CURSE_NOAGE) { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_region_noage", "mage region curse", + mage, r, c->type)); + } else { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_region_age", "mage region curse months", + mage, r, c->type, mon)); + } + } else { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_region_fail", "mage region", mage, r)); + } + } + if (!found) { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_region_nospell", "mage region", mage, r)); + } +} + +static void +magicanalyse_unit(unit *u, unit *mage, double force) +{ + attrib *a; + boolean found = false; + + for (a=u->attribs;a;a=a->next) { + curse * c; + double probability; + int mon; + if (!fval(a->type, ATF_CURSE)) continue; + + c = (curse*)a->data.v; + /* ist der curse schw�cher als der Analysezauber, so ergibt sich + * mehr als 100% probability und damit immer ein Erfolg. */ + probability = curse_chance(c, force); + mon = c->duration + (rng_int()%10) - 5; + mon = MAX(1,mon); + + if (chance(probability)) { /* Analyse gegl�ckt */ + if (c_flags(c) & CURSE_NOAGE) { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_unit_noage", "mage unit curse", + mage, u, c->type)); + }else{ + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_unit_age", "mage unit curse months", + mage, u, c->type, mon)); + } + } else { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_unit_fail", "mage unit", mage, u)); + } + } + if (!found) { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_unit_nospell", "mage target", mage, u)); + } +} + +static void +magicanalyse_building(building *b, unit *mage, double force) +{ + attrib *a; + boolean found = false; + + for (a=b->attribs;a;a=a->next) { + curse * c; + double probability; + int mon; + + if (!fval(a->type, ATF_CURSE)) continue; + + c = (curse*)a->data.v; + /* ist der curse schw�cher als der Analysezauber, so ergibt sich + * mehr als 100% probability und damit immer ein Erfolg. */ + probability = curse_chance(c, force); + mon = c->duration + (rng_int()%10) - 5; + mon = MAX(1,mon); + + if (chance(probability)) { /* Analyse gegl�ckt */ + if (c_flags(c) & CURSE_NOAGE) { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_building_age", "mage building curse", + mage, b, c->type)); + }else{ + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_building_age", "mage building curse months", + mage, b, c->type, mon)); + } + } else { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_building_fail", "mage building", mage, b)); + } + } + if (!found) { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_building_nospell", "mage building", mage, b)); + } + +} + +static void +magicanalyse_ship(ship *sh, unit *mage, double force) +{ + attrib *a; + boolean found = false; + + for (a=sh->attribs;a;a=a->next) { + curse * c; + double probability; + int mon; + if (!fval(a->type, ATF_CURSE)) continue; + + c = (curse*)a->data.v; + /* ist der curse schw�cher als der Analysezauber, so ergibt sich + * mehr als 100% probability und damit immer ein Erfolg. */ + probability = curse_chance(c, force); + mon = c->duration + (rng_int()%10) - 5; + mon = MAX(1,mon); + + if (chance(probability)) { /* Analyse gegl�ckt */ + if (c_flags(c) & CURSE_NOAGE) { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_ship_noage", "mage ship curse", + mage, sh, c->type)); + }else{ + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_ship_age", "mage ship curse months", + mage, sh, c->type, mon)); + } + } else { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_ship_fail", "mage ship", mage, sh)); + + } + } + if (!found) { + ADDMSG(&mage->faction->msgs, msg_message( + "analyse_ship_nospell", "mage ship", mage, sh)); + } + +} + +int +break_curse(attrib **alist, int cast_level, double force, curse * c) +{ + int succ = 0; +/* attrib **a = a_find(*ap, &at_curse); */ + attrib ** ap = alist; + + while (*ap && force > 0) { + curse * c1; + attrib * a = *ap; + if (!fval(a->type, ATF_CURSE)) { + do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type); + continue; + } + c1 = (curse*)a->data.v; + + /* Immunit�t pr�fen */ + if (c_flags(c1) & CURSE_IMMUNE) { + do { ap = &(*ap)->next; } while (*ap && a->type==(*ap)->type); + continue; + } + + /* Wenn kein spezieller cursetyp angegeben ist, soll die Antimagie + * auf alle Verzauberungen wirken. Ansonsten pr�fe, ob der Curse vom + * richtigen Typ ist. */ + if (!c || c==c1) { + double remain = destr_curse(c1, cast_level, force); + if (remain < force) { + succ = cast_level; + force = remain; + } + if (c1->vigour <= 0) { + a_remove(alist, a); + } + } + if (*ap==a) ap = &a->next; + } + return succ; +} + +/* ------------------------------------------------------------- */ +/* Report a spell's effect to the units in the region. +*/ + +static void +report_effect(region * r, unit * mage, message * seen, message * unseen) +{ +#if 0 + unit * u; + + /* melden, 1x pro Partei */ + freset(mage->faction, FFL_SELECT); + for (u = r->units; u; u = u->next ) freset(u->faction, FFL_SELECT); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FFL_SELECT) ) { + fset(u->faction, FFL_SELECT); + + /* Bei Fernzaubern sieht nur die eigene Partei den Magier */ + if (u->faction != mage->faction) { + if (r == mage->region) { + /* kein Fernzauber, pr�fe, ob der Magier �berhaupt gesehen + * wird */ + if (cansee(u->faction, r, mage, 0)) { + r_addmessage(r, u->faction, seen); + } else { + r_addmessage(r, u->faction, unseen); + } + } else { /* Fernzauber, fremde Partei sieht den Magier niemals */ + r_addmessage(r, u->faction, unseen); + } + } else { /* Partei des Magiers, sieht diesen immer */ + r_addmessage(r, u->faction, seen); + } + } + } + /* Ist niemand von der Partei des Magiers in der Region, dem Magier + * nochmal gesondert melden */ + if (!fval(mage->faction, FFL_SELECT)) { + add_message(&mage->faction->msgs, seen); + } +#else + int err = report_action(r, mage, seen, ACTION_RESET|ACTION_CANSEE); + if (err) { + report_action(r, mage, seen, ACTION_CANNOTSEE); + } +#endif +} + +/* ------------------------------------------------------------- */ +/* Die Spruchfunktionen */ +/* ------------------------------------------------------------- */ +/* Meldungen: + * + * Fehlermeldungen sollten als MSG_MAGIC, level ML_MISTAKE oder + * ML_WARN ausgegeben werden. (stehen im Kopf der Auswertung unter + * Zauberwirkungen) + + sprintf(buf, "%s in %s: 'ZAUBER %s': [hier die Fehlermeldung].", + unitname(mage), regionname(mage->region, mage->faction), sa->strings[0]); + add_message(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE); + + * Allgemein sichtbare Auswirkungen in der Region sollten als + * Regionsereignisse auch dort auftauchen. + + { + message * seen = msg_message("harvest_effect", "mage", mage); + message * unseen = msg_message("harvest_effect", "mage", NULL); + report_effect(r, mage, seen, unseen); + } + + * Meldungen an den Magier �ber Erfolg sollten, wenn sie nicht als + * Regionsereigniss auftauchen, als MSG_MAGIC level ML_INFO unter + * Zauberwirkungen gemeldet werden. Direkt dem Magier zuordnen (wie + * Botschaft an Einheit) ist derzeit nicht m�glich. + * ACHTUNG! r muss nicht die Region des Magier sein! (FARCASTING) + * + * Parameter: + * die Struct castorder *co ist in magic.h deklariert + * die Parameterliste spellparameter *pa = co->par steht dort auch. + * + */ + +/* ------------------------------------------------------------- */ +/* Name: Vertrauter + * Stufe: 10 + * + * Wirkung: + * Der Magier beschw�rt einen Vertrauten, ein kleines Tier, welches + * dem Magier zu Diensten ist. Der Magier kann durch die Augen des + * Vertrauten sehen, und durch den Vertrauten zaubern, allerdings nur + * mit seiner halben Stufe. Je nach Vertrautem erh�lt der Magier + * evtl diverse Skillmodifikationen. Der Typ des Vertrauten ist + * zuf�llig bestimmt, wird aber durch Magiegebiet und Rasse beeinflu�t. + * "Tierische" Vertraute brauchen keinen Unterhalt. + * + * Ein paar M�glichkeiten: + * Magieg. Rasse Besonderheiten + * Eule Tybied -/- fliegt, Auraregeneration + * Rabe Ilaun -/- fliegt + * Imp Draig -/- Magieresistenz? + * Fuchs Gwyrrd -/- Wahrnehmung + * ???? Cerddor -/- ???? (Singvogel?, Papagei?) + * Adler -/- -/- fliegt, +Wahrnehmung, =^=Adlerauge-Spruch? + * Kr�he -/- -/- fliegt, +Tarnung (weil unauff�llig) + * Delphin -/- Meerm. schwimmt + * Wolf -/- Ork + * Hund -/- Mensch kann evtl BEWACHE ausf�hren + * Ratte -/- Goblin + * Albatros -/- -/- fliegt, kann auf Ozean "landen" + * Affe -/- -/- kann evtl BEKLAUE ausf�hren + * Goblin -/- !Goblin normale Einheit + * Katze -/- !Katze normale Einheit + * D�mon -/- !D�mon normale Einheit + * + * Spezielle V. f�r Katzen, Trolle, Elfen, D�monen, Insekten, Zwerge? + */ + +static const race * +select_familiar(const race * magerace, magic_t magiegebiet) +{ + const race * retval = NULL; + int rnd = rng_int()%100; + + assert(magerace->familiars[0]); + if (rnd < 3) { + race_list * familiarraces = get_familiarraces(); + unsigned int maxlen = listlen(familiarraces); + if (maxlen>0) { + race_list * rclist = familiarraces; + int index = rng_int()%maxlen; + while (index-->0) { + rclist = rclist->next; + } + retval = rclist->data; + } + } else if (rnd < 70) { + retval = magerace->familiars[0]; + } else { + retval = magerace->familiars[magiegebiet]; + } + + return retval; +} + +/* ------------------------------------------------------------- */ +/* der Vertraue des Magiers */ + +static void +make_familiar(unit *familiar, unit *mage) +{ + /* skills and spells: */ + if (familiar->race->init_familiar!=NULL) { + familiar->race->init_familiar(familiar); + } else { + log_error(("could not perform initialization for familiar %s.\n", + familiar->faction->race->_name[0])); + } + + /* triggers: */ + create_newfamiliar(mage, familiar); + + /* Hitpoints nach Talenten korrigieren, sonst starten vertraute + * mit Ausdauerbonus verwundet */ + familiar->hp = unit_max_hp(familiar); +} + +static int +sp_summon_familiar(castorder *co) +{ + unit *familiar; + region *r = co->rt; + region *target_region = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + const race * rc; + skill_t sk; + int dh, dh1, bytes; + direction_t d; + message * msg; + char zText[2048], * bufp = zText; + size_t size = sizeof(zText) - 1; + + if (get_familiar(mage) != NULL ) { + cmistake(mage, co->order, 199, MSG_MAGIC); + return 0; + } + rc = select_familiar(mage->faction->race, mage->faction->magiegebiet); + if (rc==NULL) { + log_error(("could not find suitable familiar for %s.\n", + mage->faction->race->_name[0])); + return 0; + } + + if (fval(rc, RCF_SWIM) && !fval(rc, RCF_WALK)) { + int coasts = is_coastregion(r); + + if (coasts == 0) { + cmistake(mage, co->order, 229, MSG_MAGIC); + return 0; + } + + /* In welcher benachbarten Ozeanregion soll der Familiar erscheinen? */ + coasts = rng_int()%coasts; + dh = -1; + for(d=0; d<MAXDIRECTIONS; d++) { + region * rn = rconnect(r,d); + if (rn && fval(rn->terrain, SEA_REGION)) { + dh++; + if (dh == coasts) break; + } + } + target_region = rconnect(r,d); + } + + msg = msg_message("familiar_name", "unit", mage); + nr_render(msg, mage->faction->locale, zText, sizeof(zText), mage->faction); + msg_release(msg); + familiar = create_unit(target_region, mage->faction, 1, rc, 0, zText, mage); + setstatus(familiar, ST_FLEE); + fset(familiar, UFL_LOCKED); + make_familiar(familiar, mage); + + dh = 0; + dh1 = 0; + for (sk=0;sk<MAXSKILLS;sk++) { + if (rc->bonus[sk] > -5) dh++; + } + + for (sk=0;sk<MAXSKILLS;sk++) { + if (rc->bonus[sk] > -5) { + dh--; + if (dh1 == 0) { + dh1 = 1; + } else { + if (dh == 0) { + bytes = (int)strlcpy(bufp, (const char*)LOC(mage->faction->locale, "list_and"), size); + } else { + bytes = (int)strlcpy(bufp, (const char*)", ", size); + } + if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER(); + } + bytes = (int)strlcpy(bufp, (const char*)skillname(sk, mage->faction->locale), size); + if (wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER(); + } + } + ADDMSG(&mage->faction->msgs, msg_message("familiar_describe", + "mage race skills", mage, rc, zText)); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Zerst�re Magie + * Wirkung: + * Zerst�rt alle Zauberwirkungen auf dem Objekt. Jeder gebrochene + * Zauber verbraucht c->vigour an Zauberkraft. Wird der Spruch auf + * einer geringeren Stufe gezaubert, als der Zielzauber an c->vigour + * hat, so schl�gt die Aufl�sung mit einer von der Differenz abh�ngigen + * Chance fehl. Auch dann wird force verbraucht, der Zauber jedoch nur + * abgeschw�cht. + * + * Flag: + * (FARCASTING|SPELLLEVEL|ONSHIPCAST|TESTCANSEE) + * */ +static int +sp_destroy_magic(castorder *co) +{ + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + spellparameter *pa = co->par; + curse * c = NULL; + char ts[80]; + attrib **ap; + int obj; + int succ; + + /* da jeder Zauber force verbraucht und der Zauber auf alles und nicht + * nur einen Spruch wirken soll, wird die Wirkung hier verst�rkt */ + force *= 4; + + /* Objekt ermitteln */ + obj = pa->param[0]->typ; + + switch(obj) { + case SPP_REGION: + { + /* region *tr = pa->param[0]->data.r; -- farcasting! */ + region *tr = co->rt; + ap = &tr->attribs; + write_regionname(tr, mage->faction, ts, sizeof(ts)); + break; + } + case SPP_TEMP: + case SPP_UNIT: + { + unit *u; + u = pa->param[0]->data.u; + ap = &u->attribs; + write_unitname(u, ts, sizeof(ts)); + break; + } + case SPP_BUILDING: + { + building *b; + b = pa->param[0]->data.b; + ap = &b->attribs; + write_buildingname(b, ts, sizeof(ts)); + break; + } + case SPP_SHIP: + { + ship *sh; + sh = pa->param[0]->data.sh; + ap = &sh->attribs; + write_shipname(sh, ts, sizeof(ts)); + break; + } + default: + return 0; + } + + succ = break_curse(ap, cast_level, force, c); + + if (succ) { + ADDMSG(&mage->faction->msgs, msg_message( + "destroy_magic_effect", "unit region command succ target", + mage, mage->region, co->order, succ, ts)); + } else { + ADDMSG(&mage->faction->msgs, msg_message( + "destroy_magic_noeffect", "unit region command", + mage, mage->region, co->order)); + } + + return MAX(succ, 1); +} + +/* ------------------------------------------------------------- */ +/* Name: Transferiere Aura + * Stufe: variabel + * Gebiet: alle + * Kategorie: Einheit, positiv + * Wirkung: + * Mit Hilfe dieses Zauber kann der Magier eigene Aura im Verh�ltnis + * 2:1 auf einen anderen Magier des gleichen Magiegebietes oder (nur + * bei Tybied) im Verh�ltnis 3:1 auf einen Magier eines anderen + * Magiegebietes �bertragen. + * + * Syntax: + * "ZAUBERE <spruchname> <Einheit-Nr> <investierte Aura>" + * "ui" + * Flags: + * (UNITSPELL|ONSHIPCAST) + * */ + +static int +sp_transferaura(castorder *co) +{ + int aura, gain, multi = 2; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + unit * u; + sc_mage * scm_dst, * scm_src = get_mage(mage); + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber + * abbrechen aber kosten lassen */ + if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; + + /* Wieviel Transferieren? */ + aura = pa->param[1]->data.i; + u = pa->param[0]->data.u; + scm_dst = get_mage(u); + + if (scm_dst==NULL) { + /* "Zu dieser Einheit kann ich keine Aura �bertragen." */ + cmistake(mage, co->order, 207, MSG_MAGIC); + return 0; + } else if (scm_src->magietyp==M_TYBIED) { + if (scm_src->magietyp != scm_dst->magietyp) multi = 3; + } else if (scm_src->magietyp==M_GRAY) { + if (scm_src->magietyp != scm_dst->magietyp) multi = 4; + } else if (scm_dst->magietyp!=scm_src->magietyp) { + /* "Zu dieser Einheit kann ich keine Aura �bertragen." */ + cmistake(mage, co->order, 207, MSG_MAGIC); + return 0; + } + + if (aura < multi) { + /* "Auraangabe fehlerhaft." */ + cmistake(mage, co->order, 208, MSG_MAGIC); + return 0; + } + + gain = MIN(aura, scm_src->spellpoints) / multi; + scm_src->spellpoints -= gain*multi; + scm_dst->spellpoints += gain; + +/* sprintf(buf, "%s transferiert %d Aura auf %s", unitname(mage), + gain, unitname(u)); */ + ADDMSG(&mage->faction->msgs, msg_message( + "auratransfer_success", "unit target aura", mage, u, gain)); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* DRUIDE */ +/* ------------------------------------------------------------- */ +/* Name: G�nstige Winde + * Stufe: 4 + * Gebiet: Gwyrrd + * Wirkung: + * Schiffsbewegung +1, kein Abtreiben. H�lt (Stufe) Runden an. + * Kombinierbar mit "Sturmwind" (das +1 wird dadurch aber nicht + * verdoppelt), und "Luftschiff". + * + * Flags: + * (SHIPSPELL|ONSHIPCAST|SPELLLEVEL|TESTRESISTANCE) + */ + +static int +sp_goodwinds(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + int duration = cast_level+1; + spellparameter *pa = co->par; + message * m; + ship *sh; + unit *u; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + sh = pa->param[0]->data.sh; + + /* keine Probleme mit C_SHIP_SPEEDUP und C_SHIP_FLYING */ + /* NODRIFT bewirkt auch +1 Geschwindigkeit */ + create_curse(mage, &sh->attribs, ct_find("nodrift"), power, duration, zero_effect, 0); + + /* melden, 1x pro Partei */ + freset(mage->faction, FFL_SELECT); + for(u = r->units; u; u = u->next ) freset(u->faction, FFL_SELECT); + m = msg_message("wind_effect", "mage ship", mage, sh); + for(u = r->units; u; u = u->next ) { + if (u->ship != sh ) /* nur den Schiffsbesatzungen! */ + continue; + if (!fval(u->faction, FFL_SELECT) ) { + r_addmessage(r, u->faction, m); + fset(u->faction, FFL_SELECT); + } + } + if (!fval(mage->faction, FFL_SELECT)) { + r_addmessage(r, mage->faction, m); + } + msg_release(m); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Magischer Pfad + * Stufe: 4 + * Gebiet: Gwyrrd + * Wirkung: + * f�r Stufe Runden wird eine (magische) Strasse erzeugt, die wie eine + * normale Strasse wirkt. + * Im Ozean schl�gt der Spruch fehl + * + * Flags: + * (FARCASTING|SPELLLEVEL|REGIONSPELL|ONSHIPCAST|TESTRESISTANCE) + */ +static int +sp_magicstreet(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + + if (!fval(r->terrain, LAND_REGION)) { + cmistake(mage, co->order, 186, MSG_MAGIC); + return 0; + } + + /* wirkt schon in der Zauberrunde! */ + create_curse(mage, &r->attribs, ct_find("magicstreet"), co->force, co->level+1, zero_effect, 0); + + /* melden, 1x pro Partei */ + { + message * seen = msg_message("path_effect", "mage region", mage, r); + message * unseen = msg_message("path_effect", "mage region", NULL, r); + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); + } + + return co->level; +} + +/* ------------------------------------------------------------- */ +/* Name: Erwecke Ents + * Stufe: 10 + * Kategorie: Beschw�rung, positiv + * Gebiet: Gwyrrd + * Wirkung: + * Verwandelt (Stufe) B�ume in eine Gruppe von Ents, die sich f�r Stufe + * Runden der Partei des Druiden anschliessen und danach wieder zu + * B�umen werden + * Patzer: + * Monster-Ents entstehen + * + * Flags: + * (SPELLLEVEL) + */ +static int +sp_summonent(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + unit *u; + attrib *a; + int ents; + + if (rtrees(r,2) == 0) { + cmistake(mage, co->order, 204, MSG_EVENT); + /* nicht ohne b�ume */ + return 0; + } + + ents = (int)MIN(power*power, rtrees(r,2)); + + u = create_unit(r, mage->faction, ents, new_race[RC_TREEMAN], 0, NULL, mage); + + a = a_new(&at_unitdissolve); + a->data.ca[0] = 2; /* An r->trees. */ + a->data.ca[1] = 5; /* 5% */ + a_add(&u->attribs, a); + fset(u, UFL_LOCKED); + + rsettrees(r, 2, rtrees(r,2) - ents); + + /* melden, 1x pro Partei */ + { + message * seen = msg_message("ent_effect", "mage amount", mage, ents); + message * unseen = msg_message("ent_effect", "mage amount", NULL, ents); + report_effect(r, mage, seen, unseen); + msg_release(unseen); + msg_release(seen); + } + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Segne Steinkreis + * Stufe: 11 + * Kategorie: Artefakt + * Gebiet: Gwyrrd + * Wirkung: + * Es werden zwei neue Geb�ude eingef�hrt: Steinkreis und Steinkreis + * (gesegnet). Ersteres kann man bauen, letzteres wird aus einem + * fertigen Steinkreis mittels des Zaubers erschaffen. + * + * Flags: + * (BUILDINGSPELL) + * + */ +static int +sp_blessstonecircle(castorder *co) +{ + building *b; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *p = co->par; + message * msg; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (p->param[0]->flag == TARGET_NOTFOUND) return 0; + + b = p->param[0]->data.b; + + if (b->type != bt_find("stonecircle")) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_notstonecircle", "building", b)); + return 0; + } + + if (b->size < b->type->maxsize) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_notcomplete", "building", b)); + return 0; + } + + b->type = bt_find("blessedstonecircle"); + + msg = msg_message("blessedstonecircle_effect", "mage building", mage, b); + add_message(&r->msgs, msg); + msg_release(msg); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Mahlstrom + * Stufe: 15 + * Kategorie: Region, negativ + * Gebiet: Gwyrrd + * Wirkung: + * Erzeugt auf See einen Mahlstrom f�r Stufe-Wochen. Jedes Schiff, das + * durch den Mahlstrom segelt, nimmt 0-150% Schaden. (D.h. es hat auch + * eine 1/3-Chance, ohne Federlesens zu sinken. Der Mahlstrom sollte + * aus den Nachbarregionen sichtbar sein. + * + * Flags: + * (OCEANCASTABLE | ONSHIPCAST | REGIONSPELL | TESTRESISTANCE) + */ +static int +sp_maelstrom(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + curse * c; + double power = co->force; + double effect = co->force; + int duration = (int)power+1; + + if (!fval(r->terrain, SEA_REGION)) { + cmistake(mage, co->order, 205, MSG_MAGIC); + /* nur auf ozean */ + return 0; + } + + /* Attribut auf Region. + * Existiert schon ein curse, so wird dieser verst�rkt + * (Max(Dauer), Max(St�rke))*/ + c = create_curse(mage, &r->attribs, ct_find("maelstrom"), power, duration, effect, 0); + + /* melden, 1x pro Partei */ + { + message * seen = msg_message("maelstrom_effect", "mage", mage); + message * unseen = msg_message("maelstrom_effect", "mage", NULL); + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); + } + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Wurzeln der Magie + * Stufe: 16 + * Kategorie: Region, neutral + * Gebiet: Gwyrrd + * Wirkung: + * Wandelt einen Wald permanent in eine Mallornregion + * + * Flags: + * (FARCASTING | REGIONSPELL | TESTRESISTANCE) + */ +static int +sp_mallorn(castorder *co) +{ + region *r = co->rt; + int cast_level = co->level; + unit *mage = co->magician.u; + + if (!fval(r->terrain, LAND_REGION)) { + cmistake(mage, co->order, 290, MSG_MAGIC); + return 0; + } + if (fval(r, RF_MALLORN)) { + cmistake(mage, co->order, 291, MSG_MAGIC); + return 0; + } + + /* half the trees will die */ + rsettrees(r, 2, rtrees(r,2)/2); + rsettrees(r, 1, rtrees(r,1)/2); + rsettrees(r, 0, rtrees(r,0)/2); + fset(r, RF_MALLORN); + + /* melden, 1x pro Partei */ + { + message * seen = msg_message("mallorn_effect", "mage", mage); + message * unseen = msg_message("mallorn_effect", "mage", NULL); + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); + } + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Segen der Erde / Regentanz + * Stufe: 1 + * Kategorie: Region, positiv + * Gebiet: Gwyrrd + * + * Wirkung: + * Alle Bauern verdienen Stufe-Wochen 1 Silber mehr. + * + * Flags: + * (FARCASTING | SPELLLEVEL | ONSHIPCAST | REGIONSPELL) + */ +static int +sp_blessedharvest(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + int duration = (int)power+1; + /* Attribut auf Region. + * Existiert schon ein curse, so wird dieser verst�rkt + * (Max(Dauer), Max(St�rke))*/ + + if (create_curse(mage, &r->attribs, ct_find("blessedharvest"), power, duration, 1.0, 0)) { + message * seen = msg_message("harvest_effect", "mage", mage); + message * unseen = msg_message("harvest_effect", "mage", NULL); + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); + } + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Hainzauber + * Stufe: 2 + * Kategorie: Region, positiv + * Gebiet: Gwyrrd + * Syntax: ZAUBER [REGION x y] [STUFE 2] "Hain" + * Wirkung: + * Erschafft Stufe-10*Stufe Jungb�ume + * + * Flag: + * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) + */ + +static int +sp_hain(castorder *co) +{ + int trees; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + + if (!r->land) { + cmistake(mage, co->order, 296, MSG_MAGIC); + return 0; + } + if (fval(r, RF_MALLORN)) { + cmistake(mage, co->order, 92, MSG_MAGIC); + return 0; + } + + trees = lovar((int)(force * 10 * RESOURCE_QUANTITY)) + (int)force; + rsettrees(r, 1, rtrees(r,1) + trees); + + /* melden, 1x pro Partei */ + { + message * seen = msg_message("growtree_effect", "mage amount", mage, trees); + message * unseen = msg_message("growtree_effect", "mage amount", NULL, trees); + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); + } + + return cast_level; +} +/* ------------------------------------------------------------- */ +/* Name: Segne Mallornstecken - Mallorn Hainzauber + * Stufe: 4 + * Kategorie: Region, positiv + * Gebiet: Gwyrrd + * Syntax: ZAUBER [REGION x y] [STUFE 4] "Segne Mallornstecken" + * Wirkung: + * Erschafft Stufe-10*Stufe Jungb�ume + * + * Flag: + * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) + */ + +static int +sp_mallornhain(castorder *co) +{ + int trees; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + + if (!r->land) { + cmistake(mage, co->order, 296, MSG_MAGIC); + return 0; + } + if (!fval(r, RF_MALLORN)) { + cmistake(mage, co->order, 91, MSG_MAGIC); + return 0; + } + + trees = lovar((int)(force * 10 * RESOURCE_QUANTITY)) + (int)force; + rsettrees(r, 1, rtrees(r,1) + trees); + + /* melden, 1x pro Partei */ + { + message * seen = msg_message("growtree_effect", "mage amount", mage, trees); + message * unseen = msg_message("growtree_effect", "mage amount", NULL, trees); + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); + } + + return cast_level; +} + +void +patzer_ents(castorder *co) +{ + int ents; + unit *u; + region *r = co->rt; + unit *mage = co->magician.u; + /* int cast_level = co->level; */ + double force = co->force; + + if (!r->land) { + cmistake(mage, co->order, 296, MSG_MAGIC); + return; + } + + ents = (int)(force*10); + u = create_unit(r, get_monsters(), ents, new_race[RC_TREEMAN], 0, NULL, NULL); + + /* 'Erfolg' melden */ + ADDMSG(&mage->faction->msgs, msg_message( + "regionmagic_patzer", "unit region command", mage, + mage->region, co->order)); + + /* melden, 1x pro Partei */ + { + message * unseen = msg_message("entrise", "region", r); + report_effect(r, mage, unseen, unseen); + msg_release(unseen); + } +} + +/* ------------------------------------------------------------- */ +/* Name: Rosthauch + * Stufe: 3 + * Kategorie: Einheit, negativ + * Gebiet: Gwyrrd + * Wirkung: + * Zerst�rt zwischen Stufe und Stufe*10 Eisenwaffen + * + * Flag: + * (FARCASTING | SPELLLEVEL | UNITSPELL | TESTCANSEE | TESTRESISTANCE) + */ +/* Syntax: ZAUBER [REGION x y] [STUFE 2] "Rosthauch" 1111 2222 3333 */ + +typedef struct iron_weapon { + const struct item_type * type; + const struct item_type * rusty; + float chance; + struct iron_weapon * next; +} iron_weapon; + +static iron_weapon * ironweapons = NULL; + +void +add_ironweapon(const struct item_type * type, const struct item_type * rusty, float chance) +{ + iron_weapon * iweapon = malloc(sizeof(iron_weapon)); + iweapon->type = type; + iweapon->rusty = rusty; + iweapon->chance = chance; + iweapon->next = ironweapons; + ironweapons = iweapon; +} + +static int +sp_rosthauch(castorder *co) +{ + int n; + int success = 0; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + int force = (int)co->force; + spellparameter *pa = co->par; + + if (ironweapons==NULL) { + add_ironweapon(it_find("sword"), it_find("rustysword"), 1.0); + add_ironweapon(it_find("axe"), it_find("rustyaxe"), 1.0); + add_ironweapon(it_find("greatsword"), it_find("rustygreatsword"), 1.0); + add_ironweapon(it_find("halberd"), it_find("rustyhalberd"), 0.5f); +#ifndef NO_RUSTY_ARMOR + add_ironweapon(it_find("shield"), it_find("rustyshield"), 0.5f); + add_ironweapon(it_find("chainmail"), it_find("rustychainmail"), 0.2f); +#endif + } + + if (force>0) { + force = rng_int()%((int)(force * 10)) + force; + } + /* fuer jede Einheit */ + for (n = 0; n < pa->length; n++) { + unit *u = pa->param[n]->data.u; + int ironweapon = 0; + iron_weapon * iweapon = ironweapons; + + if (force<=0) break; + if (pa->param[n]->flag & (TARGET_RESISTS|TARGET_NOTFOUND)) continue; + + for (;iweapon!=NULL;iweapon=iweapon->next) { + item ** ip = i_find(&u->items, iweapon->type); + if (*ip) { + int i = MIN((*ip)->number, force); + if (iweapon->chance<1.0) { + i = (int)(i*iweapon->chance); + } + if (i>0) { + force -= i; + ironweapon += i; + i_change(ip, iweapon->type, -i); + if (iweapon->rusty) { + i_change(&u->items, iweapon->rusty, i); + } + } + } + if (force<=0) break; + } + + if (ironweapon>0) { + /* {$mage mage} legt einen Rosthauch auf {target}. {amount} Waffen + * wurden vom Rost zerfressen */ + ADDMSG(&mage->faction->msgs, msg_message("rust_effect", + "mage target amount", mage, u, ironweapon)); + ADDMSG(&u->faction->msgs, msg_message("rust_effect", + "mage target amount", + cansee(u->faction, r, mage, 0) ? mage:NULL, u, ironweapon)); + success += ironweapon; + } else { + /* {$mage mage} legt einen Rosthauch auf {target}, doch der + * Rosthauch fand keine Nahrung */ + ADDMSG(&mage->faction->msgs, msg_message( + "rust_fail", "mage target", mage, u)); + } + } + /* in success stehen nun die insgesamt zerst�rten Waffen. Im + * ung�nstigsten Fall kann pro Stufe nur eine Waffe verzaubert werden, + * darum wird hier nur f�r alle F�lle in denen noch weniger Waffen + * betroffen wurden ein Kostennachlass gegeben */ + return MIN(success, cast_level); +} + + +/* ------------------------------------------------------------- */ +/* Name: K�lteschutz + * Stufe: 3 + * Kategorie: Einheit, positiv + * Gebiet: Gwyrrd + * + * Wirkung: + * sch�tzt ein bis mehrere Einheiten mit bis zu Stufe*10 Insekten vor + * den Auswirkungen der K�lte. Sie k�nnen Gletscher betreten und dort + * ganz normal alles machen. Die Wirkung h�lt Stufe Wochen an + * Insekten haben in Gletschern den selben Malus wie in Bergen. Zu + * lange drin, nicht mehr �ndern + * + * Flag: + * (UNITSPELL | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) + */ +/* Syntax: ZAUBER [STUFE n] "K�lteschutz" eh1 [eh2 [eh3 [...]]] */ + +static int +sp_kaelteschutz(castorder *co) +{ + unit *u; + int n, i = 0; + int men; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int duration = MAX(cast_level, (int)force) + 1; + spellparameter *pa = co->par; + double effect; + + force*=10; /* 10 Personen pro Force-Punkt */ + + /* f�r jede Einheit in der Kommandozeile */ + for (n = 0; n < pa->length; n++) { + if (force < 1) + break; + + if (pa->param[n]->flag == TARGET_RESISTS + || pa->param[n]->flag == TARGET_NOTFOUND) + continue; + + u = pa->param[n]->data.u; + + if (force < u->number) { + men = (int)force; + } else { + men = u->number; + } + + effect = 1; + create_curse(mage, &u->attribs, ct_find("insectfur"), cast_level, + duration, effect, men); + + force -= u->number; + ADDMSG(&mage->faction->msgs, msg_message( + "heat_effect", "mage target", mage, u)); + if (u->faction!=mage->faction) ADDMSG(&u->faction->msgs, msg_message( + "heat_effect", "mage target", + cansee(u->faction, r, mage, 0) ? mage:NULL, u)); + i = cast_level; + } + /* Erstattung? */ + return i; +} + +/* ------------------------------------------------------------- */ +/* Name: Verw�nschung, Funkenregen, Naturfreund, ... + * Stufe: 1 + * Kategorie: Einheit, rein visuell + * Gebiet: Alle + * + * Wirkung: + * Die Einheit wird von einem magischen Effekt heimgesucht, der in ihrer + * Beschreibung auftaucht, aber nur visuellen Effekt hat. + * + * Flag: + * (UNITSPELL | TESTCANSEE | SPELLLEVEL) + */ +/* Syntax: ZAUBER "Funkenregen" eh1 */ + +static int +sp_sparkle(castorder *co) +{ + unit *u; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + int duration = cast_level+1; + double effect; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber + * abbrechen aber kosten lassen */ + if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; + + u = pa->param[0]->data.u; + effect = rng_int() % 0xffffff; + create_curse(mage, &u->attribs, ct_find("sparkle"), cast_level, + duration, effect, u->number); + + ADDMSG(&mage->faction->msgs, msg_message( + "sparkle_effect", "mage target", mage, u)); + if (u->faction!=mage->faction) { + ADDMSG(&u->faction->msgs, msg_message( + "sparkle_effect", "mage target", mage, u)); + } + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Eisengolem + * Stufe: 2 + * Kategorie: Beschw�rung, positiv + * Gebiet: Gwyrrd + * Wirkung: + * Erschafft eine Einheit Eisengolems mit Stufe*8 Golems. Jeder Golem + * hat jede Runde eine Chance von 15% zu Staub zu zerfallen. Gibt man + * den Golems den Befehl 'mache Schwert/Bih�nder' oder 'mache + * Schild/Kettenhemd/Plattenpanzer', so werden pro Golem 5 Eisenbarren + * verbaut und der Golem l�st sich auf. + * + * Golems sind zu langsam um wirklich im Kampf von Nutzen zu sein. + * Jedoch fangen sie eine Menge Schaden auf und sollten sie zuf�llig + * treffen, so ist der Schaden fast immer t�dlich. (Eisengolem: HP + * 50, AT 4, PA 2, R�stung 2(KH), 2d10+4 TP, Magieresistenz 0.25) + * + * Golems nehmen nix an und geben nix. Sie bewegen sich immer nur 1 + * Region weit und ziehen aus Strassen keinen Nutzen. Ein Golem wiegt + * soviel wie ein Stein. Kann nicht im Sumpf gezaubert werden + * + * Flag: + * (SPELLLEVEL) + * + * #define GOLEM_IRON 4 + */ + +static int +sp_create_irongolem(castorder *co) +{ + unit *u2; + attrib *a; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int number = lovar(force*8*RESOURCE_QUANTITY); + if (number<1) number = 1; + + if (r->terrain == newterrain(T_SWAMP)) { + cmistake(mage, co->order, 188, MSG_MAGIC); + return 0; + } + + u2 = create_unit(r, mage->faction, number, rc_find("irongolem"), 0, NULL, mage); + + set_level(u2, SK_ARMORER, 1); + set_level(u2, SK_WEAPONSMITH, 1); + + a = a_new(&at_unitdissolve); + a->data.ca[0] = 0; + a->data.ca[1] = IRONGOLEM_CRUMBLE; + a_add(&u2->attribs, a); + + ADDMSG(&mage->faction->msgs, + msg_message("magiccreate_effect", "region command unit amount object", + mage->region, co->order, mage, number, + LOC(mage->faction->locale, rc_name(rc_find("irongolem"), 1)))); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Steingolem + * Stufe: 1 + * Kategorie: Beschw�rung, positiv + * Gebiet: Gwyrrd + * Wirkung: + * Erschafft eine Einheit Steingolems mit Stufe*5 Golems. Jeder Golem + * hat jede Runde eine Chance von 10% zu Staub zu zerfallen. Gibt man + * den Golems den Befehl 'mache Burg' oder 'mache Strasse', so werden + * pro Golem 10 Steine verbaut und der Golem l�st sich auf. + * + * Golems sind zu langsam um wirklich im Kampf von Nutzen zu sein. + * Jedoch fangen sie eine Menge Schaden auf und sollten sie zuf�llig + * treffen, so ist der Schaden fast immer t�dlich. (Steingolem: HP 60, + * AT 4, PA 2, R�stung 4(PP), 2d12+6 TP) + * + * Golems nehmen nix an und geben nix. Sie bewegen sich immer nur 1 + * Region weit und ziehen aus Strassen keinen Nutzen. Ein Golem wiegt + * soviel wie ein Stein. + * + * Kann nicht im Sumpf gezaubert werden + * + * Flag: + * (SPELLLEVEL) + * + * #define GOLEM_STONE 4 + */ +static int +sp_create_stonegolem(castorder *co) +{ + unit *u2; + attrib *a; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + int number = lovar(co->force*5*RESOURCE_QUANTITY); + if (number<1) number = 1; + + if (r->terrain == newterrain(T_SWAMP)) { + cmistake(mage, co->order, 188, MSG_MAGIC); + return 0; + } + + u2 = create_unit(r, mage->faction, number, rc_find("stonegolem"), 0, NULL, mage); + set_level(u2, SK_ROAD_BUILDING, 1); + set_level(u2, SK_BUILDING, 1); + + a = a_new(&at_unitdissolve); + a->data.ca[0] = 0; + a->data.ca[1] = STONEGOLEM_CRUMBLE; + a_add(&u2->attribs, a); + + ADDMSG(&mage->faction->msgs, + msg_message("magiccreate_effect", "region command unit amount object", + mage->region, co->order, mage, number, + LOC(mage->faction->locale, rc_name(rc_find("stonegolem"), 1)))); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Gro�e D�rre + * Stufe: 17 + * Kategorie: Region, negativ + * Gebiet: Gwyrrd + * + * Wirkung: + * 50% alle Bauern, Pferde, B�ume sterben. + * Zu 25% terraform: Gletscher wird mit 50% zu Sumpf, sonst Ozean, + * Sumpf wird zu Steppe, Ebene zur Steppe, Steppe zur W�ste. + * Besonderheiten: + * neuer Terraintyp Steppe: + * 5000 Felder, 500 B�ume, Strasse: 250 Steine. Anlegen wie in Ebene + * m�glich + * + * Flags: + * (FARCASTING | REGIONSPELL | TESTRESISTANCE) + */ + +static void +destroy_all_roads(region *r) +{ + int i; + + for(i = 0; i < MAXDIRECTIONS; i++) { + rsetroad(r,(direction_t)i, 0); + } +} + +static int +sp_great_drought(castorder *co) +{ + unit *u; + boolean terraform = false; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int duration = 2; + double effect; + + if (fval(r->terrain, SEA_REGION) ) { + cmistake(mage, co->order, 189, MSG_MAGIC); + /* TODO: vielleicht einen netten Patzer hier? */ + return 0; + } + + /* sterben */ + rsetpeasants(r, rpeasants(r)/2); /* evtl wuerfeln */ + rsettrees(r, 2, rtrees(r,2)/2); + rsettrees(r, 1, rtrees(r,1)/2); + rsettrees(r, 0, rtrees(r,0)/2); + rsethorses(r, rhorses(r)/2); + + /* Arbeitslohn = 1/4 */ + effect = 4.0; /* curses: higher is stronger */ + create_curse(mage, &r->attribs, ct_find("drought"), force, duration, effect, 0); + + /* terraforming */ + if (rng_int() % 100 < 25) { + terraform = true; + + switch(rterrain(r)) { + case T_PLAIN: + /* rsetterrain(r, T_GRASSLAND); */ + destroy_all_roads(r); + break; + + case T_SWAMP: + /* rsetterrain(r, T_GRASSLAND); */ + destroy_all_roads(r); + break; +/* + case T_GRASSLAND: + rsetterrain(r, T_DESERT); + destroy_all_roads(r); + break; +*/ + case T_GLACIER: + if (rng_int() % 100 < 50) { + rsetterrain(r, T_SWAMP); + destroy_all_roads(r); + } else { /* Ozean */ + destroy_all_roads(r); + rsetterrain(r, T_OCEAN); + /* Einheiten d�rfen hier auf keinen Fall gel�scht werden! */ + for (u = r->units; u; u = u->next) { + if (u->race != new_race[RC_SPELL] && u->ship == 0) { + set_number(u, 0); + } + } + while (r->buildings) { + remove_building(&r->buildings, r->buildings); + } + } + break; + + default: + terraform = false; + break; + } + } + + if (!fval(r->terrain, SEA_REGION)) { + /* not destroying the region, so it should be safe to make this a local + * message */ + message * msg; + const char * mtype; + if (r->terrain == newterrain(T_SWAMP) && terraform) { + mtype = "drought_effect_1"; + } else if (!terraform) { + mtype = "drought_effect_2"; + } else { + mtype = "drought_effect_3"; + } + msg = msg_message(mtype, "mage region", mage, r); + add_message(&r->msgs, msg); + msg_release(msg); + } else { + /* possible that all units here get killed so better to inform with a global + * message */ + message * msg = msg_message("drought_effect_4", "mage region", mage, r); + for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + for (u = r->units; u; u = u->next) { + if (!fval(u->faction, FFL_SELECT)) { + fset(u->faction, FFL_SELECT); + add_message(&u->faction->msgs, msg); + } + } + if (!fval(mage->faction, FFL_SELECT)) { + add_message(&mage->faction->msgs, msg); + } + msg_release(msg); + } + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: 'Weg der B�ume' + * Stufe: 9 + * Kategorie: Teleport + * Gebiet: Gwyrrd + * Wirkung: + * Der Druide kann 5*Stufe GE in die astrale Ebene schicken. + * Der Druide wird nicht mitteleportiert, es sei denn, er gibt sich + * selbst mit an. + * Der Zauber funktioniert nur in W�ldern. + * + * Syntax: Zauber "Weg der B�ume" <Einheit> ... + * + * Flags: + * (UNITSPELL | SPELLLEVEL | TESTCANSEE) + */ +static int +sp_treewalkenter(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + spellparameter *pa = co->par; + double power = co->force; + int cast_level = co->level; + region *rt; + int remaining_cap; + int n; + int erfolg = 0; + + if (getplane(r) != 0) { + cmistake(mage, co->order, 190, MSG_MAGIC); + return 0; + } + + if (!r_isforest(r)) { + cmistake(mage, co->order, 191, MSG_MAGIC); + return 0; + } + + rt = r_standard_to_astral(r); + if (rt==NULL || is_cursed(rt->attribs, C_ASTRALBLOCK, 0) || fval(rt->terrain, FORBIDDEN_REGION)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); + return 0; + } + + remaining_cap = (int)(power * 500); + + /* fuer jede Einheit */ + for (n = 0; n < pa->length; n++) { + unit * u = pa->param[n]->data.u; + spllprm * param = pa->param[n]; + + if (param->flag & (TARGET_RESISTS|TARGET_NOTFOUND)) { + continue; + } + + if (!ucontact(u, mage)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact", "target", u)); + } else { + int w; + message * m; + unit * u2; + + if (!can_survive(u, rt)) { + cmistake(mage, co->order, 231, MSG_MAGIC); + continue; + } + + w = weight(u); + if (remaining_cap - w < 0) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "fail_tooheavy", + "target", u)); + continue; + } + remaining_cap = remaining_cap - w; + move_unit(u, rt, NULL); + erfolg = cast_level; + + /* Meldungen in der Ausgangsregion */ + for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = r->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, r, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_disappear", "unit", u); + r_addmessage(r, u2->faction, m); + } + } + } + if (m) msg_release(m); + + /* Meldungen in der Zielregion */ + for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = rt->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, rt, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_appear", "unit", u); + r_addmessage(rt, u2->faction, m); + } + } + } + if (m) msg_release(m); + } + } + return erfolg; +} + +/* ------------------------------------------------------------- */ +/* Name: 'Sog des Lebens' + * Stufe: 9 + * Kategorie: Teleport + * Gebiet: Gwyrrd + * Wirkung: + * Der Druide kann 5*Stufe GE aus die astrale Ebene schicken. Der + * Druide wird nicht mitteleportiert, es sei denn, er gibt sich selbst + * mit an. + * Der Zauber funktioniert nur, wenn die Zielregion ein Wald ist. + * + * Syntax: Zauber "Sog des Lebens" <Ziel-X> <Ziel-Y> <Einheit> ... + * + * Flags: + * (UNITSPELL|SPELLLEVEL) + */ +static int +sp_treewalkexit(castorder *co) +{ + region *rt; + region_list *rl, *rl2; + int tax, tay; + unit *u, *u2; + int remaining_cap; + int n; + int erfolg = 0; + region *r = co->rt; + unit *mage = co->magician.u; + double power = co->force; + spellparameter *pa = co->par; + int cast_level = co->level; + + if (!is_astral(r)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralonly", "")); + return 0; + } + if (is_cursed(r->attribs, C_ASTRALBLOCK, 0)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); + return 0; + } + + remaining_cap = (int)(power * 500); + + if (pa->param[0]->typ != SPP_REGION) { + report_failure(mage, co->order); + return 0; + } + + /* Koordinaten setzen und Region l�schen f�r �berpr�fung auf + * G�ltigkeit */ + rt = pa->param[0]->data.r; + tax = rt->x; + tay = rt->y; + rt = NULL; + + rl = astralregions(r, inhabitable); + rt = 0; + + rl2 = rl; + while(rl2) { + if (rl2->data->x == tax && rl2->data->y == tay) { + rt = rl2->data; + break; + } + rl2 = rl2->next; + } + free_regionlist(rl); + + if (!rt) { + cmistake(mage, co->order, 195, MSG_MAGIC); + return 0; + } + + if (!r_isforest(rt)) { + cmistake(mage, co->order, 196, MSG_MAGIC); + return 0; + } + + /* f�r jede Einheit in der Kommandozeile */ + for (n = 1; n < pa->length; n++) { + if (pa->param[n]->flag == TARGET_RESISTS + || pa->param[n]->flag == TARGET_NOTFOUND) + continue; + + u = pa->param[n]->data.u; + + if (!ucontact(u, mage)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact", "target", u)); + } else { + int w = weight(u); + if (!can_survive(u, rt)) { + cmistake(mage, co->order, 231, MSG_MAGIC); + } else if (remaining_cap - w < 0) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "fail_tooheavy", "target", u)); + } else { + message * m; + + remaining_cap = remaining_cap - w; + move_unit(u, rt, NULL); + erfolg = cast_level; + + /* Meldungen in der Ausgangsregion */ + + for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for(u2 = r->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, r, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_disappear", "unit", u); + r_addmessage(r, u2->faction, m); + } + } + } + if (m) msg_release(m); + + /* Meldungen in der Zielregion */ + + for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = rt->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, rt, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_appear", "unit", u); + r_addmessage(rt, u2->faction, m); + } + } + } + if (m) msg_release(m); + } + } + } + return erfolg; +} + +/* ------------------------------------------------------------- */ +/* Name: Heiliger Boden + * Stufe: 9 + * Kategorie: perm. Regionszauber + * Gebiet: Gwyrrd + * Wirkung: + * Es entstehen keine Untoten mehr, Untote betreten die Region + * nicht mehr. + * + * ZAUBER "Heiliger Boden" + * Flags: (0) + */ +static int +sp_holyground(castorder *co) +{ + static const curse_type * ctype = NULL; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + curse * c; + message * msg = msg_message("sp_holyground_effect", "mage region", mage, r); + report_spell(mage, r, msg); + msg_release(msg); + + if (!ctype) ctype = ct_find("holyground"); + c = create_curse(mage, &r->attribs, ctype, power*power, 1, zero_effect, 0); + + a_removeall(&r->attribs, &at_deathcount); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Heimstein + * Stufe: 7 + * Kategorie: Artefakt + * Gebiet: Gwyrrd + * Wirkung: + * Die Burg kann nicht mehr durch Donnerbeben oder andere + * Geb�udezerst�renden Spr�che kaputt gemacht werden. Auch + * sch�tzt der Zauber vor Belagerungskatapulten. + * + * ZAUBER Heimstein + * Flags: (0) + */ +static int +sp_homestone(castorder *co) +{ + unit *u; + curse * c; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + double effect; + message * msg; + if (!mage->building || mage->building->type != bt_find("castle")) { + cmistake(mage, co->order, 197, MSG_MAGIC); + return 0; + } + + c = create_curse(mage, &mage->building->attribs, ct_find("magicwalls"), + force*force, 1, zero_effect, 0); + + if (c==NULL) { + cmistake(mage, co->order, 206, MSG_MAGIC); + return 0; + } + c_setflag(c, CURSE_NOAGE|CURSE_ONLYONE); + + /* Magieresistenz der Burg erh�ht sich um 50% */ + effect = 50; + c = create_curse(mage, &mage->building->attribs, + ct_find("magicresistance"), force*force, 1, effect, 0); + c_setflag(c, CURSE_NOAGE); + + /* melden, 1x pro Partei in der Burg */ + for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + msg = msg_message("homestone_effect", "mage building", mage, mage->building); + for (u = r->units; u; u = u->next) { + if (!fval(u->faction, FFL_SELECT)) { + fset(u->faction, FFL_SELECT); + if (u->building == mage->building) { + r_addmessage(r, u->faction, msg); + } + } + } + msg_release(msg); + return cast_level; +} + + + +/* ------------------------------------------------------------- */ +/* Name: D�rre + * Stufe: 13 + * Kategorie: Region, negativ + * Gebiet: Gwyrrd + * Wirkung: + * tempor�r ver�ndert sich das Baummaximum und die maximalen Felder in + * einer Region auf die H�lfte des normalen. + * Die H�lfte der B�ume verdorren und Pferde verdursten. + * Arbeiten bringt nur noch 1/4 des normalen Verdienstes + * + * Flags: + * (FARCASTING|REGIONSPELL|TESTRESISTANCE), + */ +static int +sp_drought(castorder *co) +{ + curse *c; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + int duration = (int)power+1; + message * msg; + + if (fval(r->terrain, SEA_REGION) ) { + cmistake(mage, co->order, 189, MSG_MAGIC); + /* TODO: vielleicht einen netten Patzer hier? */ + return 0; + } + + /* melden, 1x pro Partei */ + msg = msg_message("sp_drought_effect", "mage region", mage, r); + report_spell(mage, r, msg); + msg_release(msg); + + /* Wenn schon Duerre herrscht, dann setzen wir nur den Power-Level + * hoch (evtl dauert dann die Duerre laenger). Ansonsten volle + * Auswirkungen. + */ + c = get_curse(r->attribs, ct_find("drought")); + if (c) { + c->vigour = MAX(c->vigour, power); + c->duration = MAX(c->duration, (int)power); + } else { + double effect; + /* Baeume und Pferde sterben */ + rsettrees(r, 2, rtrees(r,2)/2); + rsettrees(r, 1, rtrees(r,1)/2); + rsettrees(r, 0, rtrees(r,0)/2); + rsethorses(r, rhorses(r)/2); + + effect = 4.0; + create_curse(mage, &r->attribs, ct_find("drought"), power, duration, effect, 0); + } + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Bergw�chter + * Stufe: 9 + * Gebiet: Gwyrrd + * Kategorie: Beschw�rung, negativ + * + * Wirkung: + * Erschafft in Bergen oder Gletschern einen W�chter, der durch bewachen + * den Eisen/Laen-Abbau f�r nicht-Allierte verhindert. Bergw�chter + * verhindern auch Abbau durch getarnte/unsichtbare Einheiten und lassen + * sich auch durch Belagerungen nicht aufhalten. + * + * (Ansonsten in economic.c:manufacture() entsprechend anpassen). + * + * F�higkeiten (factypes.c): 50% Magieresistenz, 25 HP, 4d4 Schaden, + * 4 R�stung (=PP) + * Flags: + * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) + */ +static int +sp_ironkeeper(castorder *co) +{ + unit *keeper; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + message * msg; + + if (r->terrain != newterrain(T_MOUNTAIN) && r->terrain != newterrain(T_GLACIER)) { + report_failure(mage, co->order); + return 0; + } + + keeper = create_unit(r, mage->faction, 1, new_race[RC_IRONKEEPER], 0, NULL, mage); + + /*keeper->age = cast_level + 2;*/ + setstatus(keeper, ST_AVOID); /* kaempft nicht */ + guard(keeper, GUARD_MINING); + fset(keeper, UFL_ISNEW); + /* Parteitarnen, damit man nicht sofort wei�, wer dahinter steckt */ + if (rule_stealth_faction()) { + fset(keeper, UFL_ANON_FACTION); + } + + { + trigger * tkill = trigger_killunit(keeper); + add_trigger(&keeper->attribs, "timer", trigger_timeout(cast_level+2, tkill)); + } + + msg = msg_message("summon_effect", "mage amount race", mage, 1, keeper->race); + r_addmessage(r, NULL, msg); + msg_release(msg); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Sturmwind - Beschw�re einen Sturmelementar + * Stufe: 6 + * Gebiet: Gwyrrd + * + * Wirkung: + * Verdoppelt Geschwindigkeit aller angegebener Schiffe fuer diese + * Runde. Kombinierbar mit "G�nstige Winde", aber nicht mit + * "Luftschiff". + * + * Anstelle des alten ship->enchanted benutzen wir einen kurzfristigen + * Curse. Das ist zwar ein wenig aufwendiger, aber weitaus flexibler + * und erlaubt es zB, die Dauer sp�ter problemlos zu ver�ndern. + * + * Flags: + * (SHIPSPELL|ONSHIPCAST|OCEANCASTABLE|TESTRESISTANCE) + */ + +static int +sp_stormwinds(castorder *co) +{ + ship *sh; + unit *u; + int erfolg = 0; + region *r = co->rt; + unit *mage = co->magician.u; + double power = co->force; + spellparameter *pa = co->par; + int n, force = (int)power; + message * m = NULL; + + /* melden vorbereiten */ + freset(mage->faction, FFL_SELECT); + for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + + for (n = 0; n < pa->length; n++) { + if (force<=0) break; + + if (pa->param[n]->flag == TARGET_RESISTS + || pa->param[n]->flag == TARGET_NOTFOUND) + continue; + + sh = pa->param[n]->data.sh; + + /* mit C_SHIP_NODRIFT haben wir kein Problem */ + if (is_cursed(sh->attribs, C_SHIP_FLYING, 0) ) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_spell_on_flying_ship", "ship", sh)) + continue; + } + if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0) ) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_spell_on_ship_already", "ship", sh)) + continue; + } + + /* Duration = 1, nur diese Runde */ + create_curse(mage, &sh->attribs, ct_find("stormwind"), power, 1, zero_effect, 0); + /* Da der Spruch nur diese Runde wirkt wird er nie im Report + * erscheinen */ + erfolg++; + force--; + + /* melden vorbereiten: */ + for(u = r->units; u; u = u->next ) { + if (u->ship == sh ) { + /* nur den Schiffsbesatzungen! */ + fset(u->faction, FFL_SELECT); + } + } + } + if (erfolg<pa->length) { + ADDMSG(&mage->faction->msgs, msg_message("stormwinds_reduced", + "unit ships maxships", mage, erfolg, pa->length)); + } + /* melden, 1x pro Partei auf Schiff und f�r den Magier */ + fset(mage->faction, FFL_SELECT); + for (u = r->units; u; u = u->next ) { + if (fval(u->faction, FFL_SELECT)) { + freset(u->faction, FFL_SELECT); + if (erfolg > 0) { + if (!m) { + m = msg_message("stormwinds_effect", "unit", mage); + } + r_addmessage(r, u->faction, m); + } + } + } + if (m) msg_release(m); + return erfolg; +} + + +/* ------------------------------------------------------------- */ +/* Name: Donnerbeben + * Stufe: 6 + * Gebiet: Gwyrrd + * + * Wirkung: + * Zerst�rt Stufe*10 "Steineinheiten" aller Geb�ude der Region, aber nie + * mehr als 25% des gesamten Geb�udes (aber nat�rlich mindestens ein + * Stein). + * + * Flags: + * (FARCASTING|REGIONSPELL|TESTRESISTANCE) + */ +static int +sp_earthquake(castorder *co) +{ + int kaputt; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + message * msg; + building **blist = &r->buildings; + + while (*blist) { + building * burg = *blist; + + if (burg->size != 0 && !is_cursed(burg->attribs, C_MAGICWALLS, 0)) { + /* Magieresistenz */ + if (!target_resists_magic(mage, burg, TYP_BUILDING, 0)) { + kaputt = MIN(10 * cast_level, burg->size / 4); + kaputt = MAX(kaputt, 1); + burg->size -= kaputt; + if (burg->size == 0) { + /* TODO: sollten die Insassen nicht Schaden nehmen? */ + remove_building(blist, burg); + } + } + } + if (*blist==burg) blist=&burg->next; + } + + /* melden, 1x pro Partei */ + msg = msg_message("earthquake_effect", "mage region", mage, r); + r_addmessage(r, NULL, msg); + msg_release(msg); + return cast_level; +} + + +/* ------------------------------------------------------------- */ +/* CHAOS / M_DRAIG / Draig */ +/* ------------------------------------------------------------- */ +void +patzer_peasantmob(castorder *co) +{ + int anteil = 6, n; + unit *u; + attrib *a; + region *r; + unit *mage = co->magician.u; + + if (mage->region->land) { + r = mage->region; + } else { + r = co->rt; + } + + if (r->land) { + faction * f = get_monsters(); + const struct locale * lang = f->locale; + message * msg; + + anteil += rng_int() % 4; + n = rpeasants(r) * anteil / 10; + rsetpeasants(r, rpeasants(r) - n); + assert(rpeasants(r) >= 0); + + u = create_unit(r, f, n, new_race[RC_PEASANT], 0, LOC(f->locale, "angry_mob"), NULL); + fset(u, UFL_ISNEW); + /* guard(u, GUARD_ALL); hier zu fr�h! Befehl BEWACHE setzten */ + addlist(&u->orders, create_order(K_GUARD, lang, NULL)); + set_order(&u->thisorder, default_order(lang)); + a = a_new(&at_unitdissolve); + a->data.ca[0] = 1; /* An rpeasants(r). */ + a->data.ca[1] = 10; /* 10% */ + a_add(&u->attribs, a); + a_add(&u->attribs, make_hate(mage)); + + msg = msg_message("mob_warning", ""); + r_addmessage(r, NULL, msg); + msg_release(msg); + } + return; +} + + +/* ------------------------------------------------------------- */ +/* Name: Waldbrand + * Stufe: 10 + * Kategorie: Region, negativ + * Gebiet: Draig + * Wirkung: + * Vernichtet 10-80% aller Baeume in der Region. Kann sich auf benachbarte + * Regionen ausbreiten, wenn diese (stark) bewaldet sind. F�r jeweils + * 10 verbrannte Baeume in der Startregion gibts es eine 1%-Chance, dass + * sich das Feuer auf stark bewaldete Nachbarregionen ausdehnt, auf + * bewaldeten mit halb so hoher Wahrscheinlichkeit. Dort verbrennen + * dann prozentual halbsoviele bzw ein viertel soviele Baeume wie in der + * Startregion. + * + * Im Extremfall: 1250 Baeume in Region, 80% davon verbrennen (1000). + * Dann breitet es sich mit 100% Chance in stark bewaldete Regionen + * aus, mit 50% in bewaldete. Dort verbrennen dann 40% bzw 20% der Baeume. + * Weiter als eine Nachbarregion breitet sich dass Feuer nicht aus. + * + * Sinn: Ein Feuer in einer "stark bewaldeten" Wueste hat so trotzdem kaum + * eine Chance, sich weiter auszubreiten, waehrend ein Brand in einem Wald + * sich fast mit Sicherheit weiter ausbreitet. + * + * Flags: + * (FARCASTING | REGIONSPELL | TESTRESISTANCE) + */ +static int +sp_forest_fire(castorder *co) +{ + unit *u; + region *nr; + direction_t i; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double probability; + double percentage = (rng_int() % 8 + 1) * 0.1; /* 10 - 80% */ + message * msg; + + int vernichtet_schoesslinge = (int)(rtrees(r, 1) * percentage); + int destroyed = (int)(rtrees(r, 2) * percentage); + + if (destroyed<1) { + cmistake(mage, co->order, 198, MSG_MAGIC); + return 0; + } + + rsettrees(r, 2, rtrees(r,2) - destroyed); + rsettrees(r, 1, rtrees(r,1) - vernichtet_schoesslinge); + probability = destroyed * 0.001; /* Chance, dass es sich ausbreitet */ + + /* melden, 1x pro Partei */ + for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + msg = msg_message("forestfire_effect", "mage region amount", mage, r, destroyed+vernichtet_schoesslinge); + r_addmessage(r, NULL, msg); + add_message(&mage->faction->msgs, msg); + msg_release(msg); + + for (i = 0; i < MAXDIRECTIONS; i++ ) { + nr = rconnect(r, i); + assert(nr); + destroyed = 0; + vernichtet_schoesslinge = 0; + + if (rtrees(nr,2) + rtrees(nr,1) >= 800) { + if (chance(probability)) { + destroyed = (int)(rtrees(nr,2) * percentage/2); + vernichtet_schoesslinge = (int)(rtrees(nr,1) * percentage/2); + } + } else if (rtrees(nr,2) + rtrees(nr,1) >= 600) { + if (chance(probability/2)) { + destroyed = (int)(rtrees(nr,2) * percentage/4); + vernichtet_schoesslinge = (int)(rtrees(nr,1) * percentage/4); + } + } + + if (destroyed > 0 || vernichtet_schoesslinge > 0) { + message * m = msg_message("forestfire_spread", "region next trees", + r, nr, destroyed+vernichtet_schoesslinge); + + add_message(&r->msgs, m); + add_message(&mage->faction->msgs, m); + msg_release(m); + + rsettrees(nr, 2, rtrees(nr,2) - destroyed); + rsettrees(nr, 1, rtrees(nr,1) - vernichtet_schoesslinge); + } + } + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Chaosfluch + * Stufe: 5 + * Gebiet: Draig + * Kategorie: (Antimagie) Kraftreduzierer, Einheit, negativ + * Wirkung: + * Auf einen Magier gezaubert verhindert/erschwert dieser Chaosfluch + * das Zaubern. Patzer werden warscheinlicher. + * Jeder Zauber muss erst gegen den Wiederstand des Fluchs gezaubert + * werden und schw�cht dessen Antimagiewiederstand um 1. + * Wirkt MAX(Stufe(Magier) - Stufe(Ziel), rand(3)) Wochen + * Patzer: + * Magier wird selbst betroffen + * + * Flags: + * (UNITSPELL | SPELLLEVEL | TESTCANSEE | TESTRESISTANCE) + * + */ +static int +sp_fumblecurse(castorder *co) +{ + unit *target; + int rx, sx; + int duration; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + double effect; + curse * c; + spellparameter *pa = co->par; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + target = pa->param[0]->data.u; + + rx = rng_int()%3; + sx = cast_level - effskill(target, SK_MAGIC); + duration = MAX(sx, rx) + 1; + + effect = force*0.5; + c = create_curse(mage, &target->attribs, ct_find("fumble"), + force, duration, effect, 0); + if (c == NULL) { + report_failure(mage, co->order); + return 0; + } + + ADDMSG(&target->faction->msgs, msg_message( + "fumblecurse", "unit region", target, target->region)); + + return cast_level; +} + +void +patzer_fumblecurse(castorder *co) +{ + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int duration = (cast_level/2)+1; + double effect; + curse * c; + + effect = force*0.5; + c = create_curse(mage, &mage->attribs, ct_find("fumble"), force, + duration, effect, 0); + if (c!=NULL) { + ADDMSG(&mage->faction->msgs, msg_message( + "magic_fumble", "unit region command", + mage, mage->region, co->order)); + } + return; +} + +/* ------------------------------------------------------------- */ +/* Name: Drachenruf + * Stufe: 11 + * Gebiet: Draig + * Kategorie: Monster, Beschw�rung, negativ + * + * Wirkung: + * In einer W�ste, Sumpf oder Gletscher gezaubert kann innerhalb der + * n�chsten 6 Runden ein bis 6 Dracheneinheiten bis Gr��e Wyrm + * entstehen. + * + * Mit Stufe 12-15 erscheinen Jung- oder normaler Drachen, mit Stufe + * 16+ erscheinen normale Drachen oder Wyrme. + * + * Flag: + * (FARCASTING | REGIONSPELL | TESTRESISTANCE) + */ + +static int +sp_summondragon(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + unit *u; + int cast_level = co->level; + double power = co->force; + region_list *rl,*rl2; + faction *f; + int time; + int number; + const race * race; + + f = get_monsters(); + + if (r->terrain != newterrain(T_SWAMP) && r->terrain != newterrain(T_DESERT) + && r->terrain != newterrain(T_GLACIER)) { + report_failure(mage, co->order); + return 0; + } + + for(time = 1; time < 7; time++) { + if (rng_int()%100 < 25) { + switch(rng_int()%3) { + case 0: + race = new_race[RC_WYRM]; + number = 1; + break; + + case 1: + race = new_race[RC_DRAGON]; + number = 2; + break; + + case 2: + default: + race = new_race[RC_FIREDRAGON]; + number = 6; + break; + } + { + trigger * tsummon = trigger_createunit(r, f, race, number); + add_trigger(&r->attribs, "timer", trigger_timeout(time, tsummon)); + } + } + } + + rl = all_in_range(r, (short)power, NULL); + + for(rl2 = rl; rl2; rl2 = rl2->next) { + region * r2 = rl2->data; + for(u = r2->units; u; u = u->next) { + if (u->race == new_race[RC_WYRM] || u->race == new_race[RC_DRAGON]) { + attrib * a = a_find(u->attribs, &at_targetregion); + if (!a) { + a = a_add(&u->attribs, make_targetregion(co->rt)); + } else { + a->data.v = co->rt; + } + } + } + } + + ADDMSG(&mage->faction->msgs, msg_message( + "summondragon", "unit region command target", + mage, mage->region, co->order, co->rt)); + + free_regionlist(rl); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Feuerwand + * Stufe: + * Gebiet: Draig + * Kategorie: Region, negativ + * Flag: + * Kosten: SPC_LINEAR + * Aura: + * Komponenten: + * + * Wirkung: + * eine Wand aus Feuer entsteht in der angegebenen Richtung + * + * Was f�r eine Wirkung hat die? + */ + +void +wall_vigour(curse* c, double delta) +{ + wallcurse * wc = (wallcurse*)c->data.v; + assert(wc->buddy->vigour==c->vigour); + wc->buddy->vigour += delta; + if (wc->buddy->vigour<=0) { + erase_border(wc->wall); + wc->wall = NULL; + ((wallcurse*)wc->buddy->data.v)->wall = NULL; + } +} + +const curse_type ct_firewall = { + "Feuerwand", + CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR | NO_MERGE), + NULL, /* curseinfo */ + wall_vigour /* change_vigour */ +}; + +static int +sp_firewall(castorder *co) +{ + connection * b; + wall_data * fd; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + spellparameter *pa = co->par; + direction_t dir; + region * r2; + + dir = finddirection(pa->param[0]->data.xs, mage->faction->locale); + if (dir<MAXDIRECTIONS && dir!=NODIRECTION) { + r2 = rconnect(r, dir); + } else { + report_failure(mage, co->order); + return 0; + } + + if (!r2 || r2==r) { + report_failure(mage, co->order); + return 0; + } + + b = get_borders(r, r2); + while (b!=NULL) { + if (b->type == &bt_firewall) break; + b = b->next; + } + if (b==NULL) { + b = new_border(&bt_firewall, r, r2); + fd = (wall_data*)b->data.v; + fd->force = (int)(force/2+0.5); + fd->mage = mage; + fd->active = false; + fd->countdown = cast_level+1; + } else { + fd = (wall_data*)b->data.v; + fd->force = (int)MAX(fd->force, force/2+0.5); + fd->countdown = MAX(fd->countdown, cast_level+1); + } + + /* melden, 1x pro Partei */ + { + message * seen = msg_message("firewall_effect", "mage region", mage, r); + message * unseen = msg_message("firewall_effect", "mage region", NULL, r); + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); + } + + return cast_level; +} + +/* ------------------------------------------------------------- */ + +static int +sp_wisps(castorder *co) +{ + connection * b; + wall_data * fd; + region * r2; + direction_t dir; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + spellparameter *pa = co->par; + + dir = finddirection(pa->param[0]->data.xs, mage->faction->locale); + r2 = rconnect(r, dir); + + if (!r2) { + report_failure(mage, co->order); + return 0; + } + + b = new_border(&bt_wisps, r, r2); + fd = (wall_data*)b->data.v; + fd->force = (int)(force/2+0.5); + fd->mage = mage; + fd->active = false; + fd->countdown = cast_level+1; + + /* melden, 1x pro Partei */ + { + message * seen = msg_message("wisps_effect", "mage region", mage, r); + message * unseen = msg_message("wisps_effect", "mage region", NULL, r); + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); + } + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Unheilige Kraft + * Stufe: 10 + * Gebiet: Draig + * Kategorie: Untote Einheit, positiv + * + * Wirkung: + * transformiert (Stufe)W10 Untote in ihre st�rkere Form + * + * + * Flag: + * (SPELLLEVEL | TESTCANSEE) + */ + +static int +sp_unholypower(castorder *co) +{ + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + int i; + int n; + int wounds; + + n = dice((int)co->force, 10); + + for (i = 0; i < pa->length && n > 0; i++) { + const race * target_race; + unit *u; + + if (pa->param[i]->flag == TARGET_RESISTS + || pa->param[i]->flag == TARGET_NOTFOUND) + continue; + + u = pa->param[i]->data.u; + + switch (old_race(u->race)) { + case RC_SKELETON: + target_race = new_race[RC_SKELETON_LORD]; + break; + case RC_ZOMBIE: + target_race = new_race[RC_ZOMBIE_LORD]; + break; + case RC_GHOUL: + target_race = new_race[RC_GHOUL_LORD]; + break; + default: + cmistake(mage, co->order, 284, MSG_MAGIC); + continue; + } + /* Untote heilen nicht, darum den neuen Untoten maximale hp geben + * und vorhandene Wunden abziehen */ + wounds = unit_max_hp(u)*u->number - u->hp; + + if (u->number <= n) { + n -= u->number; + u->irace = NULL; + u->race = target_race; + u->hp = unit_max_hp(u)*u->number - wounds; + ADDMSG(&co->rt->msgs, msg_message("unholypower_effect", + "mage target race", mage, u, target_race)); + } else { + unit *un; + + /* Wird hoffentlich niemals vorkommen. Es gibt im Source + * vermutlich eine ganze Reihe von Stellen, wo das nicht + * korrekt abgefangen wird. Besser (aber nicht gerade einfach) + * w�re es, eine solche Konstruktion irgendwie zu kapseln. */ + if (fval(u, UFL_LOCKED) || fval(u, UFL_HUNGER) + || is_cursed(u->attribs, C_SLAVE, 0)) { + cmistake(mage, co->order, 74, MSG_MAGIC); + continue; + } + /* Verletzungsanteil der transferierten Personen berechnen */ + wounds = wounds*n/u->number; + + un = create_unit(co->rt, u->faction, 0, target_race, 0, NULL, u); + transfermen(u, un, n); + un->hp = unit_max_hp(un)*n - wounds; + ADDMSG(&co->rt->msgs, msg_message("unholypower_limitedeffect", + "mage target race amount", + mage, u, target_race, n)); + n = 0; + } + } + + return cast_level; +} + +static int +dc_age(struct curse * c) +/* age returns 0 if the attribute needs to be removed, !=0 otherwise */ +{ + region * r = (region*)c->data.v; + unit **up; + unit * mage = c->magician; + + if (r==NULL || mage==NULL || mage->number==0) { + /* if the mage disappears, so does the spell. */ + return AT_AGE_REMOVE; + } + + up = &r->units; + if (curse_active(c)) while (*up!=NULL) { + unit * u = *up; + double damage = c->effect * u->number; + + freset(u->faction, FFL_SELECT); + if (u->number<=0 || target_resists_magic(mage, u, TYP_UNIT, 0)) { + up=&u->next; + continue; + } + + /* Reduziert durch Magieresistenz */ + damage *= (1.0 - magic_resistance(u)); + change_hitpoints(u, -(int)damage); + + if (*up==u) up=&u->next; + } + + return AT_AGE_KEEP; +} + +static struct curse_type ct_deathcloud = { + "deathcloud", CURSETYP_REGION, 0, NO_MERGE, cinfo_simple, NULL, NULL, NULL, NULL, dc_age +}; + +static curse * +mk_deathcloud(unit * mage, region * r, double force, int duration) +{ + double effect; + curse * c; + + effect = force * 0.5; + c = create_curse(mage, &r->attribs, &ct_deathcloud, force, duration, effect, 0); + c->data.v = r; + return c; +} + +#define COMPAT_DEATHCLOUD +#ifdef COMPAT_DEATHCLOUD +static int +dc_read_compat(struct attrib * a, void * target, storage * store) +/* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */ +{ + region * r = NULL; + unit * u; + variant var; + int duration = store->r_int(store); + double strength = store->r_flt(store); + short rx, ry; + + var.i = store->r_id(store); + u = findunit(var.i); + + /* this only affects really old data. no need to change: */ + rx = (short)store->r_int(store); + ry = (short)store->r_int(store); + r = findregion(rx, ry); + + if (r!=NULL) { + double effect; + curse * c; + + effect = strength; + c = create_curse(u, &r->attribs, &ct_deathcloud, strength * 2, duration, effect, 0); + c->data.v = r; + if (u==NULL) { + ur_add(var, &c->magician, resolve_unit); + } + } + return AT_READ_FAIL; /* we don't care for the attribute. */ +} + + +attrib_type at_deathcloud_compat = { + "zauber_todeswolke", NULL, NULL, NULL, NULL, dc_read_compat +}; +#endif + +/* ------------------------------------------------------------- */ +/* Name: Todeswolke +* Stufe: 11 +* Gebiet: Draig +* Kategorie: Region, negativ +* +* Wirkung: +* Personen in der Region verlieren stufe/2 Trefferpunkte pro Runde. +* Dauer force/2 +* Wirkt gegen MR +* R�stung wirkt nicht +* Patzer: +* Magier ger�t in den Staub und verliert zuf�llige Zahl von HP bis +* auf MAX(hp,2) +* Besonderheiten: +* Nicht als curse implementiert, was schlecht ist - man kann dadurch +* kein dispell machen. Wegen fix unter Zeitdruck erstmal nicht zu +* �ndern... +* Missbrauchsm�glichkeit: +* Hat der Magier mehr HP als Rasse des Feindes (extrem: D�mon/Goblin) +* so kann er per Farcasting durch mehrmaliges Zaubern eine +* Nachbarregion ausl�schen. Darum sollte dieser Spruch nur einmal auf +* eine Region gelegt werden k�nnen. +* +* Flag: +* (FARCASTING | REGIONSPELL | TESTRESISTANCE) +*/ + +static int +sp_deathcloud(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + attrib *a = r->attribs; + unit * u; + + while (a) { + if ((a->type->flags & ATF_CURSE)) { + curse * c = a->data.v; + if (c->type==&ct_deathcloud) { + report_failure(mage, co->order); + return 0; + } + a = a->next; + } + else a = a->nexttype; + } + + mk_deathcloud(mage, r, co->force, co->level); + + /* melden, 1x pro Partei */ + for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FFL_SELECT) ) { + fset(u->faction, FFL_SELECT); + ADDMSG(&u->faction->msgs, msg_message("deathcloud_effect", + "mage region", cansee(u->faction, r, mage, 0) ? mage : NULL, r)); + } + } + + if (!fval(mage->faction, FFL_SELECT)) { + ADDMSG(&mage->faction->msgs, msg_message("deathcloud_effect", + "mage region", mage, r)); + } + + return co->level; +} + +void +patzer_deathcloud(castorder *co) +{ + unit *mage = co->magician.u; + int hp = (mage->hp - 2); + + change_hitpoints(mage, -rng_int()%hp); + + ADDMSG(&mage->faction->msgs, msg_message( + "magic_fumble", "unit region command", + mage, mage->region, co->order)); + + return; +} + +/* ------------------------------------------------------------- */ +/* Name: Pest + * Stufe: 7 + * Gebiet: Draig + * Wirkung: + * ruft eine Pest in der Region hervor. + * Flags: + * (FARCASTING | REGIONSPELL | TESTRESISTANCE) + * Syntax: ZAUBER [REGION x y] "Pest" + */ +static int +sp_plague(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + + plagues(r, true); + + ADDMSG(&mage->faction->msgs, msg_message("plague_spell", + "region mage", r, mage)); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Beschw�re Schattend�mon + * Stufe: 8 + * Gebiet: Draig + * Kategorie: Beschw�rung, positiv + * Wirkung: + * Der Magier beschw�rt Stufe^2 Schattend�monen. + * Schattend�monen haben Tarnung = (Magie_Magier+ Tarnung_Magier)/2 und + * Wahrnehmung 1. Sie haben einen Attacke-Bonus von 8, einen + * Verteidigungsbonus von 11 und machen 2d3 Schaden. Sie entziehen bei + * einem Treffer dem Getroffenen einen Attacke- oder + * Verteidigungspunkt. (50% Chance.) Sie haben 25 Hitpoints und + * R�stungsschutz 3. + * Flag: + * (SPELLLEVEL) + */ +static int +sp_summonshadow(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + unit *u; + int val, number = (int)(force*force); + + u = create_unit(r, mage->faction, number, new_race[RC_SHADOW], 0, NULL, mage); + + /* Bekommen Tarnung = (Magie+Tarnung)/2 und Wahrnehmung 1. */ + val = get_level(mage, SK_MAGIC) + get_level(mage, SK_STEALTH); + + set_level(u, SK_STEALTH, val); + set_level(u, SK_PERCEPTION, 1); + + ADDMSG(&mage->faction->msgs, msg_message("summonshadow_effect", + "mage number", mage, number)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Beschw�re Schattenmeister + * Stufe: 12 + * Gebiet: Draig + * Kategorie: Beschw�rung, positiv + * Wirkung: + * Diese h�heren Schattend�monen sind erheblich gef�hrlicher als die + * einfachen Schattend�monen. Sie haben Tarnung entsprechend dem + * Magietalent des Beschw�rer-1 und Wahrnehmung 5, 75 HP, + * R�stungsschutz 4, Attacke-Bonus 11 und Verteidigungsbonus 13, machen + * bei einem Treffer 2d4 Schaden, entziehen einen St�rkepunkt und + * entziehen 5 Talenttage in einem zuf�lligen Talent. + * Stufe^2 D�monen. + * + * Flag: + * (SPELLLEVEL) + * */ +static int +sp_summonshadowlords(castorder *co) +{ + unit *u; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int amount = (int)(force*force); + + u = create_unit(r, mage->faction, amount, new_race[RC_SHADOWLORD], 0, NULL, mage); + + /* Bekommen Tarnung = Magie und Wahrnehmung 5. */ + set_level(u, SK_STEALTH, get_level(mage, SK_MAGIC)); + set_level(u, SK_PERCEPTION, 5); + + ADDMSG(&mage->faction->msgs, msg_message("summon_effect", "mage amount race", mage, amount, u->race)); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Chaossog + * Stufe: 14 + * Gebiet: Draig + * Kategorie: Teleport + * Wirkung: + * Durch das Opfern von 200 Bauern kann der Chaosmagier ein Tor zur + * astralen Welt �ffnen. Das Tor kann im Folgemonat verwendet werden, + * es l�st sich am Ende des Folgemonats auf. + * + * Flag: (0) + */ +static int +sp_chaossuction(castorder *co) +{ + region *rt; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + + if (getplane(r)!=get_normalplane()) { + /* Der Zauber funktioniert nur in der materiellen Welt. */ + cmistake(mage, co->order, 190, MSG_MAGIC); + return 0; + } + + rt = r_standard_to_astral(r); + + if (rt==NULL || fval(rt->terrain, FORBIDDEN_REGION)) { + /* Hier gibt es keine Verbindung zur astralen Welt.*/ + cmistake(mage, co->order, 216, MSG_MAGIC); + return 0; + } else if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); + return 0; + } + + /* TODO: implement with a building */ + create_special_direction(r, rt, 2, "vortex_desc", "vortex"); + create_special_direction(rt, r, 2, "vortex_desc", "vortex"); + new_border(&bt_chaosgate, r, rt); + + add_message(&r->msgs, msg_message("chaosgate_effect_1", "mage", mage)); + add_message(&rt->msgs, msg_message("chaosgate_effect_2", "")); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Magic Boost - Gabe des Chaos + * Stufe: 3 + * Gebiet: Draig + * Kategorie: Einheit, positiv + * + * Wirkung: + * Erh�ht die maximalen Magiepunkte und die monatliche Regeneration auf + * das doppelte. Dauer: 4 Wochen Danach sinkt beides auf die H�lfte des + * normalen ab. + * Dauer: 6 Wochen + * Patzer: + * permanenter Stufen- (Talenttage), Regenerations- oder maxMP-Verlust + * Besonderheiten: + * Patzer k�nnen w�hrend der Zauberdauer h�ufiger auftreten derzeit + * +10% + * + * Flag: + * (ONSHIPCAST) + */ + +static int +sp_magicboost(castorder *co) +{ + curse * c; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + double effect; + trigger * tsummon; + static const curse_type * ct_auraboost; + static const curse_type * ct_magicboost; + + if (!ct_auraboost) { + ct_auraboost = ct_find("auraboost"); + ct_magicboost = ct_find("magicboost"); + assert(ct_auraboost!=NULL); + assert(ct_magicboost!=NULL); + } + /* fehler, wenn schon ein boost */ + if (is_cursed(mage->attribs, C_MBOOST, 0) == true) { + report_failure(mage, co->order); + return 0; + } + + effect = 6; + c = create_curse(mage, &mage->attribs, ct_magicboost, power, 10, effect, 1); + + /* one aura boost with 200% aura now: */ + effect = 200; + c = create_curse(mage, &mage->attribs, ct_auraboost, power, 4, effect, 1); + + /* and one aura boost with 50% aura in 5 weeks: */ + tsummon = trigger_createcurse(mage, mage, ct_auraboost, power, 6, 50, 1); + add_trigger(&mage->attribs, "timer", trigger_timeout(5, tsummon)); + + ADDMSG(&mage->faction->msgs, msg_message("magicboost_effect", + "unit region command", mage, mage->region, co->order)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: kleines Blutopfer + * Stufe: 4 + * Gebiet: Draig + * Kategorie: Einheit, positiv + * + * Wirkung: + * Hitpoints to Aura: + * skill < 8 = 4:1 + * skill < 12 = 3:1 + * skill < 15 = 2:1 + * skill < 18 = 1:2 + * skill > = 2:1 + * Patzer: + * permanenter HP verlust + * + * Flag: + * (ONSHIPCAST) + */ +static int +sp_bloodsacrifice(castorder *co) +{ + unit *mage = co->magician.u; + int cast_level = co->level; + int aura; + int skill = eff_skill(mage, SK_MAGIC, mage->region); + int hp = (int)(co->force*8); + + if (hp <= 0) { + report_failure(mage, co->order); + return 0; + } + + aura = lovar(hp); + + if (skill < 8) { + aura /= 4; + } else if (skill < 12) { + aura /= 3; + } else if (skill < 15) { + aura /= 2; + /* von 15 bis 17 ist hp = aura */ + } else if (skill > 17) { + aura *= 2; + } + + if (aura <= 0) { + report_failure(mage, co->order); + return 0; + } + + /* sicherheitshalber gibs hier einen HP gratis. sonst schaffen es + * garantiert ne ganze reihe von leuten ihren Magier damit umzubringen */ + mage->hp++; + change_spellpoints(mage, aura); + ADDMSG(&mage->faction->msgs, + msg_message("sp_bloodsacrifice_effect", + "unit region command amount", + mage, mage->region, co->order, aura)); + return cast_level; +} + +/** gives a summoned undead unit some base skills. + */ +static void +skill_summoned(unit * u, int level) +{ + if (level>0) { + const race * rc = u->race; + skill_t sk; + for (sk=0;sk!=MAXSKILLS;++sk) { + if (rc->bonus[sk]>0) { + set_level(u, sk, level); + } + } + } +} + +/* ------------------------------------------------------------- */ +/* Name: Totenruf - M�chte des Todes + * Stufe: 6 + * Gebiet: Draig + * Kategorie: Beschw�rung, positiv + * Flag: FARCASTING + * Wirkung: + * Untote aus deathcounther ziehen, bis Stufe*10 St�ck + * + * Patzer: + * Erzeugt Monsteruntote + */ +static int +sp_summonundead(castorder *co) +{ + int undead; + unit *u; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + int force = (int)(co->force*10); + const race * race = new_race[RC_SKELETON]; + + if (!r->land || deathcount(r) == 0) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_nograves", "target", r)); + return 0; + } + + undead = MIN(deathcount(r), 2 + lovar(force)); + + if (cast_level <= 8) { + race = new_race[RC_SKELETON]; + } else if (cast_level <= 12) { + race = new_race[RC_ZOMBIE]; + } else { + race = new_race[RC_GHOUL]; + } + + u = create_unit(r, mage->faction, undead, race, 0, NULL, mage); + make_undead_unit(u); + skill_summoned(u, cast_level/2); + + ADDMSG(&mage->faction->msgs, msg_message("summonundead_effect_1", "mage region amount", mage, r, undead)); + ADDMSG(&r->msgs, msg_message("summonundead_effect_2", "mage region", mage, r)); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Astraler Sog + * Stufe: 9 + * Gebiet: Draig + * Kategorie: Region, negativ + * Wirkung: + * Allen Magier in der betroffenen Region wird eine Teil ihrer + * Magischen Kraft in die Gefilde des Chaos entzogen Jeder Magier im + * Einflussbereich verliert Stufe(Zaubernden)*5% seiner Magiepunkte. + * Keine Regeneration in der Woche (fehlt noch) + * + * Flag: + * (REGIONSPELL | TESTRESISTANCE) + */ + +static int +sp_auraleak(castorder *co) +{ + int lost_aura; + double lost; + unit *u; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + message * msg; + + lost = MIN(0.95, cast_level * 0.05); + + for (u = r->units; u; u = u->next) { + if (is_mage(u)) { + /* Magieresistenz Einheit? Bei gegenerischen Magiern nur sehr + * geringe Chance auf Erfolg wg erh�hter MR, w�rde Spruch sinnlos + * machen */ + lost_aura = (int)(get_spellpoints(u)*lost); + change_spellpoints(u, -lost_aura); + } + } + msg = msg_message("cast_auraleak_effect", "mage region", mage, r); + r_addmessage(r, NULL, msg); + msg_release(msg); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* BARDE - CERDDOR*/ +/* ------------------------------------------------------------- */ +/* ------------------------------------------------------------- */ +/* Name: Magie analysieren - Geb�ude, Schiffe, Region + * Name: Lied des Ortes analysieren + * Stufe: 8 + * Gebiet: Cerddor + * + * Wirkung: + * Zeigt die Verzauberungen eines Objekts an (curse->name, + * curse::info). Aus der Differenz Spruchst�rke und Curse->vigour + * ergibt sich die Chance den Spruch zu identifizieren ((force - + * c->vigour)*10 + 100 %). + * + * Flag: + * (SPELLLEVEL|ONSHIPCAST) + */ +static int +sp_analysesong_obj(castorder *co) +{ + int obj; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + spellparameter *pa = co->par; + + obj = pa->param[0]->typ; + + switch(obj) { + case SPP_REGION: + magicanalyse_region(r, mage, force); + break; + + case SPP_BUILDING: + { + building *b = pa->param[0]->data.b; + magicanalyse_building(b, mage, force); + break; + } + case SPP_SHIP: + { + ship * sh = pa->param[0]->data.sh; + magicanalyse_ship(sh, mage, force); + break; + } + default: + /* Syntax fehlerhaft */ + return 0; + } + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Gesang des Lebens analysieren + * Name: Magie analysieren - Unit + * Stufe: 5 + * Gebiet: Cerddor + * Wirkung: + * Zeigt die Verzauberungen eines Objekts an (curse->name, + * curse::info). Aus der Differenz Spruchst�rke und Curse->vigour + * ergibt sich die Chance den Spruch zu identifizieren ((force - + * c->vigour)*10 + 100 %). + * + * Flag: + * (UNITSPELL|ONSHIPCAST|TESTCANSEE) + */ +static int +sp_analysesong_unit(castorder *co) +{ + unit *u; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + spellparameter *pa = co->par; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber + * abbrechen aber kosten lassen */ + if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; + + u = pa->param[0]->data.u; + + magicanalyse_unit(u, mage, force); + + return cast_level; +} + +static boolean +can_charm(const unit * u, int maxlevel) +{ + const skill_t expskills[] = { SK_ALCHEMY, SK_HERBALISM, SK_MAGIC, SK_SPY, SK_TACTICS, NOSKILL }; + skill * sv = u->skills; + + if (fval(u, UFL_HERO)) return false; + + for (;sv!=u->skills+u->skill_size;++sv) { + int l = 0, h = 5; + skill_t sk = sv->id; + assert(expskills[h]==NOSKILL); + while (l<h) { + int m = (l+h)/2; + if (sk==expskills[m]) { + if (skill_limit(u->faction, sk)!=INT_MAX) { + return false; + } else if ((int)sv->level>maxlevel) { + return false; + } + break; + } + else if (sk>expskills[m]) l=m+1; + else h=m; + } + } + return true; +} +/* ------------------------------------------------------------- */ +/* Name: Charming + * Stufe: 13 + * Gebiet: Cerddor + * Flag: UNITSPELL + * Wirkung: + * bezauberte Einheit wechselt 'virtuell' die Partei und f�hrt fremde + * Befehle aus. + * Dauer: 3 - force+2 Wochen + * Wirkt gegen Magieresistenz + * + * wirkt auf eine Einheit mit maximal Talent Personen normal. F�r jede + * zus�tzliche Person gibt es einen Bonus auf Magieresistenz, also auf + * nichtgelingen, von 10%. + * + * Das h�chste Talent der Einheit darf maximal so hoch sein wie das + * Magietalent des Magiers. F�r jeden Talentpunkt mehr gibt es einen + * Bonus auf Magieresistenz von 15%, was dazu f�hrt, das bei +2 Stufen + * die Magiersistenz bei 90% liegt. + * + * Migrantenz�hlung muss Einheit �berspringen + * + * Attackiere verbieten + * Flags: + * (UNITSPELL | TESTCANSEE) + */ +static int +sp_charmingsong(castorder *co) +{ + unit *target; + int duration; + skill_t i; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + spellparameter *pa = co->par; + int resist_bonus = 0; + int tb = 0; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + target = pa->param[0]->data.u; + + /* Auf eigene Einheiten versucht zu zaubern? Garantiert Tippfehler */ + if (target->faction == mage->faction) { + /* Die Einheit ist eine der unsrigen */ + cmistake(mage, co->order, 45, MSG_MAGIC); + } + /* niemand mit teurem Talent */ + if (!can_charm(target, cast_level/2)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + "spellfail_noexpensives", "target", target)); + return 0; + } + + /* Magieresistensbonus f�r mehr als Stufe Personen */ + if (target->number > force) { + resist_bonus += (int)((target->number - force) * 10); + } + /* Magieresistensbonus f�r h�here Talentwerte */ + for(i = 0; i < MAXSKILLS; i++) { + int sk = effskill(target, i); + if (tb < sk) tb = sk; + } + tb -= effskill(mage, SK_MAGIC); + if (tb > 0) { + resist_bonus += tb * 15; + } + /* Magieresistenz */ + if (target_resists_magic(mage, target, TYP_UNIT, resist_bonus)) { + report_failure(mage, co->order); +#if 0 + sprintf(buf, "%s f�hlt sich einen Moment lang benommen und desorientiert.", + unitname(target)); + addmessage(target->region, target->faction, buf, MSG_EVENT, ML_WARN); +#endif + return 0; + } + + duration = 3 + rng_int()%(int)force; + { + trigger * trestore = trigger_changefaction(target, target->faction); + /* l�uft die Dauer ab, setze Partei zur�ck */ + add_trigger(&target->attribs, "timer", trigger_timeout(duration, trestore)); + /* wird die alte Partei von Target aufgel�st, dann auch diese Einheit */ + add_trigger(&target->faction->attribs, "destroy", trigger_killunit(target)); + /* wird die neue Partei von Target aufgel�st, dann auch diese Einheit */ + add_trigger(&mage->faction->attribs, "destroy", trigger_killunit(target)); + } + /* sperre ATTACKIERE, GIB PERSON und �berspringe Migranten */ + create_curse(mage, &target->attribs, ct_find("slavery"), force, duration, zero_effect, 0); + + /* setze Partei um und l�sche langen Befehl aus Sicherheitsgr�nden */ + u_setfaction(target, mage->faction); + set_order(&target->thisorder, NULL); + + /* setze Parteitarnung, damit nicht sofort klar ist, wer dahinter + * steckt */ + if (rule_stealth_faction()) { + fset(target, UFL_ANON_FACTION); + } + + ADDMSG(&mage->faction->msgs, msg_message("charming_effect", "mage unit duration", mage, target, duration)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Gesang des wachen Geistes + * Stufe: 10 + * Gebiet: Cerddor + * Kosten: SPC_LEVEL + * Wirkung: + * Bringt einmaligen Bonus von +15% auf Magieresistenz. Wirkt auf alle + * Aliierten (HELFE BEWACHE) in der Region. + * Dauert Stufe Wochen an, ist nicht kumulativ. + * Flag: + * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) + */ +static int +sp_song_resistmagic(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int duration = (int)force+1; + + create_curse(mage, &r->attribs, ct_find("goodmagicresistancezone"), + force, duration, 15, 0); + + /* Erfolg melden */ + ADDMSG(&mage->faction->msgs, msg_message( + "regionmagic_effect", "unit region command", mage, + mage->region, co->order)); + + return cast_level; +} +/* ------------------------------------------------------------- */ +/* Name: Gesang des schwachen Geistes + * Stufe: 12 + * Gebiet: Cerddor + * Wirkung: + * Bringt einmaligen Malus von -15% auf Magieresistenz. + * Wirkt auf alle Nicht-Aliierten (HELFE BEWACHE) in der Region. + * Dauert Stufe Wochen an, ist nicht kumulativ. + * Flag: + * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) + */ +static int +sp_song_susceptmagic(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int duration = (int)force+1; + + create_curse(mage, &r->attribs, ct_find("badmagicresistancezone"), + force, duration, 15, 0); + + ADDMSG(&mage->faction->msgs, msg_message( + "regionmagic_effect", "unit region command", mage, + mage->region, co->order)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Aufruhr beschwichtigen + * Stufe: 15 + * Gebiet: Cerddor + * Flag: FARCASTING + * Wirkung: + * zerstreut einen Monsterbauernmob, Antimagie zu 'Aufruhr + * verursachen' + */ + +static int +sp_rallypeasantmob(castorder *co) +{ + unit *u, *un; + int erfolg = 0; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + message * msg; + curse * c; + + for (u = r->units; u; u = un) { + un = u->next; + if (is_monsters(u->faction) && u->race == new_race[RC_PEASANT]) { + rsetpeasants(r, rpeasants(r) + u->number); + rsetmoney(r, rmoney(r) + get_money(u)); + set_money(u, 0); + setguard(u, GUARD_NONE); + set_number(u, 0); + erfolg = cast_level; + } + } + + c = get_curse(r->attribs, ct_find(oldcursename(C_RIOT))); + if (c!=NULL) { + remove_curse(&r->attribs, c); + } + + msg = msg_message("cast_rally_effect", "mage region", mage, r); + r_addmessage(r, NULL, msg); + msg_release(msg); + return erfolg; +} + +/* ------------------------------------------------------------- */ +/* Name: Aufruhr verursachen + * Stufe: 16 + * Gebiet: Cerddor + * Wirkung: + * Wiegelt 60% bis 90% der Bauern einer Region auf. Bauern werden ein + * gro�er Mob, der zur Monsterpartei geh�rt und die Region bewacht. + * Regionssilber sollte auch nicht durch Unterhaltung gewonnen werden + * k�nnen. + * + * Fehlt: Triggeraktion: l�ste Bauernmob auf und gib alles an Region, + * dann k�nnen die Bauernmobs ihr Silber mitnehmen und bleiben x + * Wochen bestehen + * + * alternativ: L�sen sich langsam wieder auf + * Flag: + * (FARCASTING | REGIONSPELL | TESTRESISTANCE) + */ +static int +sp_raisepeasantmob(castorder *co) +{ + unit *u; + attrib *a; + int n; + int anteil; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int duration = (int)force+1; + faction * monsters = get_monsters(); + message * msg; + + anteil = 6 + (rng_int()%4); + + n = rpeasants(r) * anteil / 10; + n = MAX(0, n); + n = MIN(n, rpeasants(r)); + + if (n <= 0) { + report_failure(mage, co->order); + return 0; + } + + rsetpeasants(r, rpeasants(r) - n); + assert(rpeasants(r) >= 0); + + u = create_unit(r, monsters, n, new_race[RC_PEASANT], 0, LOC(monsters->locale, "furious_mob"), NULL); + fset(u, UFL_ISNEW); + guard(u, GUARD_ALL); + a = a_new(&at_unitdissolve); + a->data.ca[0] = 1; /* An rpeasants(r). */ + a->data.ca[1] = 15; /* 15% */ + a_add(&u->attribs, a); + + create_curse(mage, &r->attribs, ct_find("riotzone"), cast_level, duration, (double)anteil, 0); + + msg = msg_message("sp_raisepeasantmob_effect", "mage region", mage, r); + report_spell(mage, r, msg); + msg_release(msg); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Ritual der Aufnahme / Migrantenwerben + * Stufe: 9 + * Gebiet: Cerddor + * Wirkung: + * Bis zu Stufe Personen fremder Rasse k�nnen angeworben werden. Die + * angeworbene Einheit muss kontaktieren. Keine teuren Talente + * + * Flag: + * (UNITSPELL | SPELLLEVEL | TESTCANSEE) + */ +static int +sp_migranten(castorder *co) +{ + unit *target; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + target = pa->param[0]->data.u; /* Zieleinheit */ + + /* Personen unserer Rasse k�nnen problemlos normal �bergeben werden */ + if (target->race == mage->faction->race) { + /* u ist von unserer Art, das Ritual w�re verschwendete Aura. */ + ADDMSG(&mage->faction->msgs, msg_message( + "sp_migranten_fail1", "unit region command target", mage, + mage->region, co->order, target)); + } + /* Auf eigene Einheiten versucht zu zaubern? Garantiert Tippfehler */ + if (target->faction == mage->faction) { + cmistake(mage, co->order, 45, MSG_MAGIC); + } + + /* Keine Monstereinheiten */ + if (!playerrace(target->race)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + "spellfail_nomonsters", "")); + return 0; + } + /* niemand mit teurem Talent */ + if (has_limited_skills(target)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + "spellfail_noexpensives", "target", target)); + return 0; + } + /* maximal Stufe Personen */ + if (target->number > cast_level + || target->number > max_spellpoints(r, mage)) + { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + "spellfail_toomanytargets", "")); + return 0; + } + + /* Kontakt pr�fen (aus alter Teleportroutine �bernommen) */ + if (!ucontact(target, mage)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + "spellfail::contact", "target", target)); + return 0; + } + u_setfaction(target,mage->faction); + set_order(&target->thisorder, NULL); + + /* Erfolg melden */ + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "sp_migranten", + "target", target)); + + return target->number; +} + +/* ------------------------------------------------------------- */ +/* Name: Gesang der Friedfertigkeit + * Stufe: 12 + * Gebiet: Cerddor + * Wirkung: + * verhindert jede Attacke f�r lovar(Stufe/2) Runden + */ + +static int +sp_song_of_peace(castorder *co) +{ + unit *u; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int duration = 2 + lovar(force/2); + message * msg[2] = { NULL, NULL }; + + create_curse(mage, &r->attribs, ct_find("peacezone"), force, duration, zero_effect, 0); + + for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FFL_SELECT) ) { + message * m = NULL; + fset(u->faction, FFL_SELECT); + if (cansee(u->faction, r, mage, 0)) { + if (msg[0]==NULL) msg[0] = msg_message("song_of_peace_effect_0", "mage", mage); + m = msg[0]; + } else { + if (msg[1]==NULL) msg[1] = msg_message("song_of_peace_effect_1", ""); + m = msg[1]; + } + r_addmessage(r, u->faction, m); + } + } + if (msg[0]) msg_release(msg[0]); + if (msg[1]) msg_release(msg[1]); + return cast_level; + +} + +/* ------------------------------------------------------------- */ +/* Name: Hohes Lied der Gaukelei + * Stufe: 2 + * Gebiet: Cerddor + * Wirkung: + * Das Unterhaltungsmaximum steigt von 20% auf 40% des + * Regionsverm�gens. Der Spruch h�lt Stufe Wochen an + */ + +static int +sp_generous(castorder *co) +{ + unit *u; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int duration = (int)force+1; + double effect; + message * msg[2] = { NULL, NULL }; + + if (is_cursed(r->attribs, C_DEPRESSION, 0)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_generous", "")); + return 0; + } + + effect = 2; + create_curse(mage,&r->attribs, ct_find("generous"), force, duration, effect, 0); + + for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FFL_SELECT) ) { + message * m = NULL; + fset(u->faction, FFL_SELECT); + if (cansee(u->faction, r, mage, 0)) { + if (msg[0]==NULL) msg[0] = msg_message("generous_effect_0", "mage", mage); + m = msg[0]; + } else { + if (msg[1]==NULL) msg[1] = msg_message("generous_effect_1", ""); + m = msg[1]; + } + r_addmessage(r, u->faction, m); + } + } + if (msg[0]) msg_release(msg[0]); + if (msg[1]) msg_release(msg[1]); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Anwerbung + * Stufe: 4 + * Gebiet: Cerddor + * Wirkung: + * Bauern schliessen sich der eigenen Partei an + * ist zus�tzlich zur Rekrutierungsmenge in der Region + * */ + +static int +sp_recruit(castorder *co) +{ + unit *u; + region *r = co->rt; + int num, maxp = rpeasants(r); + double n; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + faction *f = mage->faction; + const struct race * rc = f->race; + + if (maxp == 0) { + report_failure(mage, co->order); + return 0; + } + /* Immer noch zuviel auf niedrigen Stufen. Deshalb die Rekrutierungskosten + * mit einfliessen lassen und daf�r den Exponenten etwas gr��er. + * Wenn die Rekrutierungskosten deutlich h�her sind als der Faktor, + * ist das Verh�ltniss von ausgegebene Aura pro Bauer bei Stufe 2 + * ein mehrfaches von Stufe 1, denn in beiden F�llen gibt es nur 1 + * Bauer, nur die Kosten steigen. */ + n = (pow(force, 1.6) * 100)/f->race->recruitcost; + if (rc->recruit_multi!=0) { + double multp = maxp/rc->recruit_multi; + n = MIN(multp, n); + n = MAX(n, 1); + rsetpeasants(r, maxp - (int)(n * rc->recruit_multi)); + } else { + n = MIN(maxp, n); + n = MAX(n, 1); + rsetpeasants(r, maxp - (int)n); + } + + num = (int)n; + u = create_unit(r, f, num, f->race, 0, LOC(f->locale,(num == 1 ? "peasant" : "peasant_p")), mage); + set_order(&u->thisorder, default_order(f->locale)); + + ADDMSG(&mage->faction->msgs, msg_message("recruit_effect", "mage amount", mage, num)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Wanderprediger - Gro�e Anwerbung + * Stufe: 14 + * Gebiet: Cerddor + * Wirkung: + * Bauern schliessen sich der eigenen Partei an + * ist zus�tzlich zur Rekrutierungsmenge in der Region + * */ + +static int +sp_bigrecruit(castorder *co) +{ + unit *u; + region *r = co->rt; + int n, maxp = rpeasants(r); + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + faction *f = mage->faction; + message * msg; + + if (maxp <= 0) { + report_failure(mage, co->order); + return 0; + } + /* F�r vergleichbare Erfolge bei unterschiedlichen Rassen die + * Rekrutierungskosten mit einfliessen lassen. */ + + n = (int)force + lovar((force * force * 1000)/f->race->recruitcost); + if (f->race==new_race[RC_ORC]) { + n = MIN(2*maxp, n); + n = MAX(n, 1); + rsetpeasants(r, maxp - (n+1) / 2); + } else { + n = MIN(maxp, n); + n = MAX(n, 1); + rsetpeasants(r, maxp - n); + } + + u = create_unit(r, f, n, f->race, 0, LOC(f->locale,(n == 1 ? "peasant" : "peasant_p")), mage); + set_order(&u->thisorder, default_order(f->locale)); + + msg = msg_message("recruit_effect", "mage amount", mage, n); + r_addmessage(r, mage->faction, msg); + msg_release(msg); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Aushorchen + * Stufe: 7 + * Gebiet: Cerddor + * Wirkung: + * Erliegt die Einheit dem Zauber, so wird sie dem Magier alles + * erz�hlen, was sie �ber die gefragte Region wei�. Ist in der Region + * niemand ihrer Partei, so wei� sie nichts zu berichten. Auch kann + * sie nur das erz�hlen, was sie selber sehen k�nnte. + * Flags: + * (UNITSPELL | TESTCANSEE) + */ + +/* restistenz der einheit pr�fen */ +static int +sp_pump(castorder *co) +{ + unit *u, *target; + region *rt; + boolean see = false; + unit *mage = co->magician.u; + spellparameter *pa = co->par; + int cast_level = co->level; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + target = pa->param[0]->data.u; /* Zieleinheit */ + + if (fval(target->race, RCF_UNDEAD)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_not_on_undead", "")); + return 0; + } + if (is_magic_resistant(mage, target, 0) || is_monsters(target->faction)) { + report_failure(mage, co->order); + return 0; + } + + rt = pa->param[1]->data.r; + + for (u = rt->units; u; u = u->next) { + if (u->faction == target->faction) + see = true; + } + + if (see == false) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_pump", "target tregion", target, rt)); + return cast_level/2; + } else { + ADDMSG(&mage->faction->msgs, msg_message("pump_effect", "mage unit tregion", mage, target, rt)); + } + + u = create_unit(rt, mage->faction, RS_FARVISION, new_race[RC_SPELL], 0, "spell/pump", NULL); + u->age = 2; + set_level(u, SK_PERCEPTION, eff_skill(target, SK_PERCEPTION, u->region)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Verf�hrung + * Stufe: 6 + * Gebiet: Cerddor + * Wirkung: + * Bet�rt eine Einheit, so das sie ihm den gr��ten Teil ihres Bargelds + * und 50% ihres Besitzes schenkt. Sie beh�lt jedoch immer soviel, wie + * sie zum �berleben braucht. Wirkt gegen Magieresistenz. + * MIN(Stufe*1000$, u->money - maintenace) + * Von jedem Item wird 50% abgerundet ermittelt und �bergeben. Dazu + * kommt Itemzahl%2 mit 50% chance + * + * Flags: + * (UNITSPELL | TESTRESISTANCE | TESTCANSEE) + */ +static int +sp_seduce(castorder *co) +{ + item *items = NULL; + unit *target; + item **itmp; + unit *mage = co->magician.u; + spellparameter *pa = co->par; + int cast_level = co->level; + double force = co->force; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + target = pa->param[0]->data.u; /* Zieleinheit */ + + if (fval(target->race, RCF_UNDEAD)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + "spellfail_noundead", "")); + return 0; + } + + /* Erfolgsmeldung */ + + itmp=&target->items; + while (*itmp) { + item * itm = *itmp; + int loot; + if (itm->type==i_silver) { + loot = MIN(cast_level * 1000, get_money(target) - (maintenance_cost(target))); + loot = MAX(loot, 0); + } else { + loot = itm->number/2; + if (itm->number % 2) { + loot += rng_int() % 2; + } + if (loot > 0) { + loot = (int)MIN(loot, force * 5); + } + } + if (loot>0) { + i_change(&mage->items, itm->type, loot); + i_change(&items, itm->type, loot); + i_change(itmp, itm->type, -loot); + } + if (*itmp==itm) itmp=&itm->next; + } + + ADDMSG(&mage->faction->msgs, msg_message("seduce_effect_0", "mage unit items", mage, target, items)); + i_freeall(&items); + ADDMSG(&target->faction->msgs, msg_message("seduce_effect_1", "unit", target)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Monster friedlich stimmen + * Stufe: 6 + * Gebiet: Cerddor + * Wirkung: + * verhindert Angriffe des bezauberten Monsters auf die Partei des + * Barden f�r Stufe Wochen. Nicht �bertragbar, dh Verb�ndete werden vom + * Monster nat�rlich noch angegriffen. Wirkt nicht gegen Untote + * Jede Einheit kann maximal unter einem Beherrschungszauber dieser Art + * stehen, dh wird auf die selbe Einheit dieser Zauber von einem + * anderen Magier nochmal gezaubert, schl�gt der Zauber fehl. + * + * Flags: + * (UNITSPELL | ONSHIPCAST | TESTRESISTANCE | TESTCANSEE) + */ + +static int +sp_calm_monster(castorder *co) +{ + curse * c; + unit *target; + unit *mage = co->magician.u; + spellparameter *pa = co->par; + int cast_level = co->level; + double force = co->force; + double effect; + message * msg; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + target = pa->param[0]->data.u; /* Zieleinheit */ + + if (fval(target->race, RCF_UNDEAD)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + "spellfail_noundead", "")); + return 0; + } + + effect = mage->faction->subscription; + c = create_curse(mage, &target->attribs, ct_find("calmmonster"), force, + (int)force, effect, 0); + if (c==NULL) { + report_failure(mage, co->order); + return 0; + } + + msg = msg_message("calm_effect", "mage unit", mage, target); + r_addmessage(mage->region, mage->faction, msg); + msg_release(msg); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: schaler Wein + * Stufe: 7 + * Gebiet: Cerddor + * Wirkung: + * wird gegen Magieresistenz gezaubert Das Opfer vergisst bis zu + * Talenttage seines h�chsten Talentes und tut die Woche nix. + * Nachfolgende Zauber sind erschwert. + * Wirkt auf bis zu 10 Personen in der Einheit + * + * Flags: + * (UNITSPELL | TESTRESISTANCE | TESTCANSEE) + */ + +static int +sp_headache(castorder *co) +{ + skill * smax = NULL; + int i; + unit *target; + unit *mage = co->magician.u; + spellparameter *pa = co->par; + int cast_level = co->level; + message * msg; + + /* Macht alle nachfolgenden Zauber doppelt so teuer */ + countspells(mage, 1); + + target = pa->param[0]->data.u; /* Zieleinheit */ + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (target->number==0 || pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + /* finde das gr��te Talent: */ + for (i=0;i!=target->skill_size;++i) { + skill * sv = target->skills+i; + if (smax==NULL || skill_compare(sv, smax)>0) { + smax = sv; + } + } + if (smax!=NULL) { + /* wirkt auf maximal 10 Personen */ + int change = MIN(10, target->number) * (rng_int()%2+1) / target->number; + reduce_skill(target, smax, change); + } + set_order(&target->thisorder, NULL); + + msg = msg_message("hangover_effect_0", "mage unit", mage, target); + r_addmessage(mage->region, mage->faction, msg); + msg_release(msg); + + msg = msg_message("hangover_effect_1", "unit", target); + r_addmessage(target->region, target->faction, msg); + msg_release(msg); + + return cast_level; +} + + +/* ------------------------------------------------------------- */ +/* Name: Mob + * Stufe: 10 + * Gebiet: Cerddor + * Wirkung: + * Wiegelt Stufe*250 Bauern zu einem Mob auf, der sich der Partei des + * Magier anschliesst Pro Woche beruhigen sich etwa 15% wieder und + * kehren auf ihre Felder zur�ck + * + * Flags: + * (SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) + */ +static int +sp_raisepeasants(castorder *co) +{ + int bauern; + unit *u2; + attrib *a; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + message * msg; + + if (rpeasants(r) == 0) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_nopeasants", "")); + return 0; + } + bauern = (int)MIN(rpeasants(r), power*250); + rsetpeasants(r, rpeasants(r) - bauern); + + u2 = create_unit(r, mage->faction, bauern, new_race[RC_PEASANT], 0, LOC(mage->faction->locale, "furious_mob"), mage); + + fset(u2, UFL_LOCKED); + if (rule_stealth_faction()) { + fset(u2, UFL_ANON_FACTION); + } + + a = a_new(&at_unitdissolve); + a->data.ca[0] = 1; /* An rpeasants(r). */ + a->data.ca[1] = 15; /* 15% */ + a_add(&u2->attribs, a); + + msg = msg_message("sp_raisepeasants_effect", "mage region amount", mage, r, u2->number); + r_addmessage(r, NULL, msg); + if (mage->region!=r) { + add_message(&mage->faction->msgs, msg); + } + msg_release(msg); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Tr�bsal + * Stufe: 11 + * Kategorie: Region, negativ + * Wirkung: + * in der Region kann f�r einige Wochen durch Unterhaltung kein Geld + * mehr verdient werden + * + * Flag: + * (FARCASTING | REGIONSPELL | TESTRESISTANCE) + */ +static int +sp_depression(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int duration = (int)force+1; + message * msg; + + create_curse(mage, &r->attribs, ct_find("depression"), force, duration, zero_effect, 0); + + msg = msg_message("sp_depression_effect", "mage region", mage, r); + r_addmessage(r, NULL, msg); + if (mage->region!=r) { + add_message(&mage->faction->msgs, msg); + } + msg_release(msg); + return cast_level; +} + +#if 0 +/* ------------------------------------------------------------- */ +/* Name: Hoher Gesang der Drachen + * Stufe: 14 + * Gebiet: Cerddor + * Kategorie: Monster, Beschw�rung, positiv + * + * Wirkung: + * Erh�ht HP-Regeneration in der Region und lockt drachenartige (Wyrm, + * Drache, Jungdrache, Seeschlange, ...) aus der Umgebung an + * + * Flag: + * (FARCASTING | REGIONSPELL | TESTRESISTANCE) + */ +/* TODO zur Aktivierung in Zauberliste aufnehmen*/ +static int +sp_dragonsong(castorder *co) +{ + region *r = co->rt; /* Zauberregion */ + unit *mage = co->magician.u; + unit *u; + int cast_level = co->level; + double power = co->force; + region_list *rl,*rl2; + faction *f; + + /* TODO HP-Effekt */ + + f = get_monsters(); + + rl = all_in_range(r, (int)power); + + for(rl2 = rl; rl2; rl2 = rl2->next) { + region * r2 = rl2->data; + for(u = r2->units; u; u = u->next) { + if (u->race->flags & RCF_DRAGON) { + attrib * a = a_find(u->attribs, &at_targetregion); + if (!a) { + a = a_add(&u->attribs, make_targetregion(r)); + } else { + a->data.v = r; + } + } + } + } + + ADDMSG(&mage->faction->msgs, msg_message( + "summondragon", "unit region command target", + mage, mage->region, co->order, co->rt)); + + free_regionlist(rl); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Hoher Gesang der Verlockung + * Stufe: 17 + * Gebiet: Cerddor + * Kategorie: Monster, Beschw�rung, positiv + * + * Wirkung: + * Lockt Bauern aus den umliegenden Regionen her + * + * Flag: + * (FARCASTING | REGIONSPELL | TESTRESISTANCE) + */ +/* TODO zur Aktivierung in Zauberliste aufnehmen*/ + +static int +sp_songofAttraction(castorder *co) +{ + region *r = co->rt; /* Zauberregion */ + unit *mage = co->magician.u; + int cast_level = co->level; + /* double power = co->force; */ + + /* TODO Wander Effekt */ + + ADDMSG(&mage->faction->msgs, msg_message( + "summon", "unit region command region", + mage, mage->region, co->order, r)); + + return cast_level; +} + +#endif + +/* ------------------------------------------------------------- */ +/* TRAUM - Illaun */ +/* ------------------------------------------------------------- */ + +/* Name: Seelenfrieden + * Stufe: 2 + * Kategorie: Region, positiv + * Gebiet: Illaun + * Wirkung: + * Reduziert Untotencounter + * Flag: (0) + */ + +int +sp_puttorest(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int dead = deathcount(r); + int laid_to_rest = dice((int)(co->force * 2), 100); + message * seen = msg_message("puttorest", "mage", mage); + message * unseen = msg_message("puttorest", "mage", NULL); + + laid_to_rest = MAX(laid_to_rest, dead); + + deathcounts(r, -laid_to_rest); + + report_effect(r, mage, seen, unseen); + msg_release(seen); + msg_release(unseen); + return co->level; +} + +/* Name: Traumschl��chen + * Stufe: 3 + * Kategorie: Region, Geb�ude, positiv + * Gebiet: Illaun + * Wirkung: + * Mit Hilfe dieses Zaubers kann der Traumweber die Illusion eines + * beliebigen Geb�udes erzeugen. Die Illusion kann betreten werden, ist + * aber ansonsten funktionslos und ben�tigt auch keinen Unterhalt + * Flag: (0) + */ + +int +sp_icastle(castorder *co) +{ + building *b; + const building_type * type; + attrib *a; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + spellparameter *pa = co->par; + icastle_data * data; + const char * bname; + message * msg; + static const building_type * bt_illusion; + + if (bt_illusion==NULL) bt_illusion = bt_find("illusioncastle"); + if (bt_illusion==NULL) { + return 0; + } + + if ((type=findbuildingtype(pa->param[0]->data.xs, mage->faction->locale)) == NULL) { + type = bt_find("castle"); + } + + b = new_building(bt_illusion, r, mage->faction->locale); + + /* Gr��e festlegen. */ + if (type == bt_illusion) { + b->size = (rng_int()%(int)((power*power)+1)*10); + } else if (type->maxsize == -1) { + b->size = ((rng_int()%(int)(power))+1)*5; + } else { + b->size = type->maxsize; + } + + if (type->name==NULL) { + bname = LOC(mage->faction->locale, type->_name); + } else { + bname = LOC(mage->faction->locale, buildingtype(type, b, 0)); + } + building_setname(b, bname); + + /* TODO: Auf timeout und action_destroy umstellen */ + a = a_add(&b->attribs, a_new(&at_icastle)); + data = (icastle_data*)a->data.v; + data->type = type; + data->building = b; + data->time = 2+(rng_int()%(int)(power)+1)*(rng_int()%(int)(power)+1); + + if (mage->region == r) { + if (leave(mage, false)) { + mage->building = b; + } + } + + ADDMSG(&mage->faction->msgs, msg_message( + "icastle_create", "unit region command", mage, mage->region, + co->order)); + + msg = msg_message("sp_icastle_effect", "region", r); + report_spell(mage, r, msg); + msg_release(msg); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Gestaltwandlung + * Stufe: 3 + * Gebiet: Illaun + * Wirkung: + * Zieleinheit erscheint f�r (Stufe) Wochen als eine andere Gestalt + * (wie bei d�monischer Rassetarnung). + * Syntax: ZAUBERE "Gestaltwandlung" <einheit> <rasse> + * Flags: + * (UNITSPELL | SPELLLEVEL) + */ + +int +sp_illusionary_shapeshift(castorder *co) +{ + unit *u; + const race * rc; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + spellparameter *pa = co->par; + const race * irace; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber + * abbrechen aber kosten lassen */ + if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; + + u = pa->param[0]->data.u; + + rc = findrace(pa->param[1]->data.xs, mage->faction->locale); + if (rc == NULL) { + cmistake(mage, co->order, 202, MSG_MAGIC); + return 0; + } + + /* �hnlich wie in laws.c:setealth() */ + if (!playerrace(rc)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "sp_shapeshift_fail", "target race", u, rc)); + return 0; + } + irace = u_irace(u); + if (irace == u->race) { + trigger * trestore = trigger_changerace(u, NULL, irace); + add_trigger(&u->attribs, "timer", trigger_timeout((int)power+2, trestore)); + u->irace = rc; + } + + ADDMSG(&mage->faction->msgs, msg_message("shapeshift_effect", "mage target race", mage, u, rc)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Regionstraum analysieren + * Stufe: 9 + * Aura: 18 + * Kosten: SPC_FIX + * Wirkung: + * Zeigt die Verzauberungen eines Objekts an (curse->name, + * curse::info). Aus der Differenz Spruchst�rke und Curse->vigour + * ergibt sich die Chance den Spruch zu identifizieren ((force - + * c->vigour)*10 + 100 %). + */ +int +sp_analyseregionsdream(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + + magicanalyse_region(r, mage, cast_level); + + return cast_level; +} + + +/* ------------------------------------------------------------- */ +/* Name: Traumbilder erkennen + * Stufe: 5 + * Aura: 12 + * Kosten: SPC_FIX + * Wirkung: + * Zeigt die Verzauberungen eines Objekts an (curse->name, + * curse::info). Aus der Differenz Spruchst�rke und Curse->vigour + * ergibt sich die Chance den Spruch zu identifizieren ((force - + * c->vigour)*10 + 100 %). + */ +int +sp_analysedream(castorder *co) +{ + unit *u; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber + * abbrechen aber kosten lassen */ + if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; + + u = pa->param[0]->data.u; + magicanalyse_unit(u, mage, cast_level); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Schlechte Tr�ume + * Stufe: 10 + * Kategorie: Region, negativ + * Wirkung: + * Dieser Zauber erm�glicht es dem Tr�umer, den Schlaf aller + * nichtaliierten Einheiten (HELFE BEWACHE) in der Region so starkzu + * st�ren, das sie 1 Talentstufe in allen Talenten + * vor�bergehend verlieren. Der Zauber wirkt erst im Folgemonat. + * + * Flags: + * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) + * */ +int +sp_baddreams(castorder *co) +{ + int duration; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + region *r = co->rt; + curse * c; + double effect; + + /* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken, + * also duration+2 */ + duration = (int)MAX(1, power/2); /* Stufe 1 macht sonst mist */ + duration = 2 + rng_int()%duration; + + /* Nichts machen als ein entsprechendes Attribut in die Region legen. */ + effect = -1; + c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, effect, 0); + + /* Erfolg melden*/ + ADDMSG(&mage->faction->msgs, msg_message( + "regionmagic_effect", "unit region command", mage, + mage->region, co->order)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Sch�ne Tr�ume + * Stufe: 8 + * Kategorie: + * Wirkung: + * Dieser Zauber erm�glicht es dem Tr�umer, den Schlaf aller aliierten + * Einheiten in der Region so zu beeinflussen, da� sie f�r einige Zeit + * einen Bonus von 1 Talentstufe in allen Talenten + * bekommen. Der Zauber wirkt erst im Folgemonat. + * Flags: + * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) + */ +int +sp_gooddreams(castorder *co) +{ + int duration; + curse * c; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + double effect; + + /* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken, + * also duration+2 */ + duration = (int)MAX(1, power/2); /* Stufe 1 macht sonst mist */ + duration = 2 + rng_int()%duration; + effect = 1; + c = create_curse(mage, &r->attribs, ct_find("gbdream"), power, duration, effect, 0); + + /* Erfolg melden*/ + ADDMSG(&mage->faction->msgs, msg_message( + "regionmagic_effect", "unit region command", mage, + mage->region, co->order)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: + * Stufe: 9 + * Kategorie: + * Wirkung: + * Es wird eine Kloneinheit erzeugt, die nichts kann. Stirbt der + * Magier, wird er mit einer Wahrscheinlichkeit von 90% in den Klon + * transferiert. + * Flags: + * (NOTFAMILARCAST) + */ +int +sp_clonecopy(castorder *co) +{ + unit *clone; + region *r = co->rt; + region *target_region = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + message * msg; + char name[NAMESIZE]; + + if (get_clone(mage) != NULL ) { + cmistake(mage, co->order, 298, MSG_MAGIC); + return 0; + } + + snprintf(name, sizeof(name), (const char*)LOC(mage->faction->locale, "clone_of"), unitname(mage)); + clone = create_unit(target_region, mage->faction, 1, new_race[RC_CLONE], 0, name, mage); + setstatus(clone, ST_FLEE); + fset(clone, UFL_LOCKED); + + create_newclone(mage, clone); + + msg = msg_message("sp_clone_effet", "mage", mage); + r_addmessage(r, mage->faction, msg); + msg_release(msg); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +int +sp_dreamreading(castorder *co) +{ + unit *u,*u2; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + double power = co->force; + message * msg; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber + * abbrechen aber kosten lassen */ + if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; + + u = pa->param[0]->data.u; + + /* Illusionen und Untote abfangen. */ + if (fval(u->race, RCF_UNDEAD|RCF_ILLUSIONARY)) { + ADDMSG(&mage->faction->msgs, msg_unitnotfound(mage, co->order, pa->param[0])); + return 0; + } + + /* Entfernung */ + if (distance(mage->region, u->region) > power) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_distance", "")); + return 0; + } + + u2 = create_unit(u->region,mage->faction, RS_FARVISION, new_race[RC_SPELL], 0, "spell/dreamreading", NULL); + set_number(u2, 1); + u2->age = 2; /* Nur f�r diese Runde. */ + set_level(u2, SK_PERCEPTION, eff_skill(u, SK_PERCEPTION, u2->region)); + + msg = msg_message("sp_dreamreading_effect", "mage unit region", mage, u, u->region); + r_addmessage(r, mage->faction, msg); + msg_release(msg); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Wirkt power/2 Runden auf bis zu power^2 Personen + * mit einer Chance von 5% vermehren sie sich */ +int +sp_sweetdreams(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + spellparameter *pa = co->par; + int men, n; + int duration = (int)(power/2)+1; + int opfer = (int)(power*power); + + /* Schleife �ber alle angegebenen Einheiten */ + for (n = 0; n < pa->length; n++) { + curse * c; + unit *u; + double effect; + message * msg; + /* sollte nie negativ werden */ + if (opfer < 1) break; + + if (pa->param[n]->flag == TARGET_RESISTS || + pa->param[n]->flag == TARGET_NOTFOUND) + continue; + + /* Zieleinheit */ + u = pa->param[n]->data.u; + + if (!ucontact(u, mage)) { + cmistake(mage, co->order, 40, MSG_EVENT); + continue; + } + men = MIN(opfer, u->number); + opfer -= men; + + /* Nichts machen als ein entsprechendes Attribut an die Einheit legen. */ + effect = 0.05; + c = create_curse(mage,&u->attribs, ct_find("orcish"), power, duration, effect, men); + + msg = msg_message("sp_sweetdreams_effect", "mage unit region", mage, u, r); + r_addmessage(r, mage->faction, msg); + if (u->faction!=mage->faction) { + r_addmessage(r, u->faction, msg); + } + msg_release(msg); + } + return cast_level; +} + +/* ------------------------------------------------------------- */ +int +sp_disturbingdreams(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + int duration = 1 + (int)(power/6); + double effect; + curse * c; + + effect = 10; + c = create_curse(mage, &r->attribs, ct_find("badlearn"), power, duration, effect, 0); + + ADDMSG(&mage->faction->msgs, msg_message("sp_disturbingdreams_effect", "mage region", mage, r)); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* ASTRAL / THEORIE / M_TYBIED */ +/* ------------------------------------------------------------- */ +/* Name: Magie analysieren + * Stufe: 1 + * Aura: 1 + * Kosten: SPC_LINEAR + * Komponenten: + * + * Wirkung: + * Zeigt die Verzauberungen eines Objekts an (curse->name, + * curse::info). Aus der Differenz Spruchst�rke und Curse->vigour + * ergibt sich die Chance den Spruch zu identifizieren ((force - + * c->vigour)*10 + 100 %). + * + * Flags: + * UNITSPELL, SHIPSPELL, BUILDINGSPELL + */ + +int +sp_analysemagic(castorder *co) +{ + int obj; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + + if (!pa->param) { + return 0; + } + /* Objekt ermitteln */ + obj = pa->param[0]->typ; + + switch(obj) { + case SPP_REGION: + { + region *tr = pa->param[0]->data.r; + magicanalyse_region(tr, mage, cast_level); + break; + } + case SPP_TEMP: + case SPP_UNIT: + { + unit *u; + u = pa->param[0]->data.u; + magicanalyse_unit(u, mage, cast_level); + break; + } + case SPP_BUILDING: + { + building *b; + b = pa->param[0]->data.b; + magicanalyse_building(b, mage, cast_level); + break; + } + case SPP_SHIP: + { + ship *sh; + sh = pa->param[0]->data.sh; + magicanalyse_ship(sh, mage, cast_level); + break; + } + default: + /* Fehlerhafter Parameter */ + return 0; + } + + return cast_level; +} + +/* ------------------------------------------------------------- */ + +int +sp_itemcloak(castorder *co) +{ + unit *target; + unit *mage = co->magician.u; + spellparameter *pa = co->par; + int cast_level = co->level; + double power = co->force; + int duration = (int)MAX(2.0, power+1); /* works in the report, and ageing this round would kill it if it's <=1 */ + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + /* Zieleinheit */ + target = pa->param[0]->data.u; + + create_curse(mage,&target->attribs, ct_find("itemcloak"), power, duration, zero_effect, 0); + ADDMSG(&mage->faction->msgs, msg_message( + "itemcloak", "mage target", mage, target)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Magieresistenz erh�hen + * Stufe: 3 + * Aura: 5 MP + * Kosten: SPC_LEVEL + * Komponenten: + * + * Wirkung: + * erh�ht die Magierestistenz der Personen um 20 Punkte f�r 6 Wochen + * Wirkt auf Stufe*5 Personen kann auf mehrere Einheiten gezaubert + * werden, bis die Zahl der m�glichen Personen ersch�pft ist + * + * Flags: + * UNITSPELL + */ +int +sp_resist_magic_bonus(castorder *co) +{ + unit *u; + int n, m; + int duration = 6; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + spellparameter *pa = co->par; + /* Pro Stufe k�nnen bis zu 5 Personen verzaubert werden */ + double maxvictims = 5; + int victims = (int)maxvictims; + + /* Schleife �ber alle angegebenen Einheiten */ + for (n = 0; n < pa->length; n++) { + message * msg; + /* sollte nie negativ werden */ + if (victims < 1) + break; + + if (pa->param[n]->flag == TARGET_RESISTS + || pa->param[n]->flag == TARGET_NOTFOUND) + continue; + + u = pa->param[n]->data.u; + + /* Ist die Einheit schon verzaubert, wirkt sich dies nur auf die + * Menge der Verzauberten Personen aus. + if (is_cursed(u->attribs, C_MAGICRESISTANCE, 0)) + continue; + */ + + m = MIN(u->number,victims); + victims -= m; + + create_curse(mage, &u->attribs, ct_find("magicresistance"), + power, duration, 20, m); + + msg = msg_message("magicresistance_effect", "unit", u); + add_message(&u->faction->msgs, msg); + + /* und noch einmal dem Magier melden */ + if (u->faction != mage->faction) { + add_message(&mage->faction->msgs, msg); + } + msg_release(msg); + } + + cast_level = MIN(cast_level, (int)(cast_level*(victims+4)/maxvictims)); + return MAX(cast_level, 1); +} + +/** spell 'Astraler Weg'. + * Syntax "ZAUBERE [STUFE n] 'Astraler Weg' <Einheit-Nr> [<Einheit-Nr> ...]", + * + * Parameter: + * pa->param[0]->data.xs +*/ +int +sp_enterastral(castorder *co) +{ + region *rt, *ro; + unit *u, *u2; + int remaining_cap; + int n, w; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + spellparameter *pa = co->par; + + switch(getplaneid(r)) { + case 0: + rt = r_standard_to_astral(r); + ro = r; + break; + default: + cmistake(mage, co->order, 190, MSG_MAGIC); + return 0; + } + + if (!rt || fval(rt->terrain, FORBIDDEN_REGION)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_astralregion", "")); + return 0; + } + + if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0) || is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); + return 0; + } + + remaining_cap = (int)((power-3) * 1500); + + /* f�r jede Einheit in der Kommandozeile */ + for (n = 0; n < pa->length; n++) { + if (pa->param[n]->flag == TARGET_NOTFOUND) continue; + u = pa->param[n]->data.u; + + if (!ucontact(u, mage)) { + if (power > 10 && !is_magic_resistant(mage, u, 0) && can_survive(u, rt)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_no_resist", "target", u)); + ADDMSG(&u->faction->msgs, msg_message("send_astral", "unit target", mage, u)); + } else { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_resist", "target", u)); + ADDMSG(&u->faction->msgs, msg_message("try_astral", "unit target", mage, u)); + continue; + } + } + + w = weight(u); + if (!can_survive(u, rt)) { + cmistake(mage, co->order, 231, MSG_MAGIC); + } else if (remaining_cap - w < 0) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "fail_tooheavy", "target", u)); + } else { + message * m; + remaining_cap = remaining_cap - w; + move_unit(u, rt, NULL); + + /* Meldungen in der Ausgangsregion */ + + for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = r->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, r, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_disappear", "unit", u); + r_addmessage(r, u2->faction, m); + } + } + } + if (m) msg_release(m); + + /* Meldungen in der Zielregion */ + + for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = rt->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, rt, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_appear", "unit", u); + r_addmessage(rt, u2->faction, m); + } + } + } + if (m) msg_release(m); + } + } + return cast_level; +} + +/** Spell 'Astraler Ruf' / 'Astral Call'. + */ +int +sp_pullastral(castorder *co) +{ + region *rt, *ro; + unit *u, *u2; + region_list *rl, *rl2; + int remaining_cap; + int n, w; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + spellparameter *pa = co->par; + + switch (getplaneid(r)) { + case 1: + rt = r; + ro = pa->param[0]->data.r; + rl = astralregions(r, NULL); + rl2 = rl; + while (rl2!=NULL) { + region * r2 = rl2->data; + if (r2->x == ro->x && r2->y == ro->y) { + ro = r2; + break; + } + rl2 = rl2->next; + } + if (!rl2) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail::nocontact", + "target", rt)); + free_regionlist(rl); + return 0; + } + free_regionlist(rl); + break; + default: + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralonly", "")); + return 0; + } + + if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0) || is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); + return 0; + } + + remaining_cap = (int)((power-3) * 1500); + + /* f�r jede Einheit in der Kommandozeile */ + for (n = 1; n < pa->length; n++) { + spllprm * spobj = pa->param[n]; + if (spobj->flag == TARGET_NOTFOUND) continue; + + u = spobj->data.u; + + if (u->region!=ro) { + /* Report this as unit not found */ + if (spobj->typ == SPP_UNIT) { + spobj->data.i = u->no; + } else { + spobj->data.i = ualias(u); + } + spobj->flag = TARGET_NOTFOUND; + ADDMSG(&mage->faction->msgs, msg_unitnotfound(mage, co->order, spobj)); + return false; + } + + if (!ucontact(u, mage)) { + if (power > 12 && spobj->flag != TARGET_RESISTS && can_survive(u, rt)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_no_resist", "target", u)); + } else { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_resist", "target", u)); + ADDMSG(&u->faction->msgs, msg_message("try_astral", "unit target", mage, u)); + continue; + } + } + + w = weight(u); + + if (!can_survive(u, rt)) { + cmistake(mage, co->order, 231, MSG_MAGIC); + } else if (remaining_cap - w < 0) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "fail_tooheavy", "target", u)); + } else { + message * m; + + ADDMSG(&u->faction->msgs, msg_message("send_astral", "unit target", mage, u)); + remaining_cap = remaining_cap - w; + move_unit(u, rt, NULL); + + /* Meldungen in der Ausgangsregion */ + + for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = r->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, r, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_disappear", "unit", u); + r_addmessage(r, u2->faction, m); + } + } + } + if (m) msg_release(m); + + /* Meldungen in der Zielregion */ + + for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = rt->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, rt, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_appear", "unit", u); + r_addmessage(rt, u2->faction, m); + } + } + } + if (m) msg_release(m); + } + } + return cast_level; +} + +int +sp_leaveastral(castorder *co) +{ + region *rt, *ro; + region_list *rl, *rl2; + unit *u, *u2; + int remaining_cap; + int n, w; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + spellparameter *pa = co->par; + + switch(getplaneid(r)) { + case 1: + ro = r; + rt = pa->param[0]->data.r; + if (!rt) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail::noway", "")); + return 0; + } + rl = astralregions(r, inhabitable); + rl2 = rl; + while (rl2!=NULL) { + if (rl2->data == rt) break; + rl2 = rl2->next; + } + if (rl2==NULL) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail::noway", "")); + free_regionlist(rl); + return 0; + } + free_regionlist(rl); + break; + default: + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spell_astral_only", "")); + return 0; + } + + if (ro==NULL || is_cursed(ro->attribs, C_ASTRALBLOCK, 0) || is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralblock", "")); + return 0; + } + + remaining_cap = (int)((power-3) * 1500); + + /* f�r jede Einheit in der Kommandozeile */ + for (n = 1; n < pa->length; n++) { + if (pa->param[n]->flag == TARGET_NOTFOUND) continue; + + u = pa->param[n]->data.u; + + if (!ucontact(u, mage)) { + if (power > 10 && !pa->param[n]->flag == TARGET_RESISTS && can_survive(u, rt)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_no_resist", "target", u)); + ADDMSG(&u->faction->msgs, msg_message("send_astral", "unit target", mage, u)); + } else { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_resist", "target", u)); + ADDMSG(&u->faction->msgs, msg_message("try_astral", "unit target", mage, u)); + continue; + } + } + + w = weight(u); + + if (!can_survive(u, rt)) { + cmistake(mage, co->order, 231, MSG_MAGIC); + } else if (remaining_cap - w < 0) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "fail_tooheavy", "target", u)); + } else { + message * m; + + remaining_cap = remaining_cap - w; + move_unit(u, rt, NULL); + + /* Meldungen in der Ausgangsregion */ + + for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = r->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, r, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_disappear", "unit", u); + r_addmessage(r, u2->faction, m); + } + } + } + if (m) msg_release(m); + + /* Meldungen in der Zielregion */ + + for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = rt->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, rt, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_appear", "unit", u); + r_addmessage(rt, u2->faction, m); + } + } + } + if (m) msg_release(m); + } + } + return cast_level; +} + +int +sp_fetchastral(castorder *co) +{ + int n; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + double power = co->force; + int remaining_cap = (int)((power-3) * 1500); + region_list * rtl = NULL; + region * rt = co->rt; /* region to which we are fetching */ + region * ro = NULL; /* region in which the target is */ + + if (rplane(rt)!=get_normalplane()) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error190", "")); + return 0; + } + + /* f�r jede Einheit in der Kommandozeile */ + for (n=0; n!=pa->length; ++n) { + unit * u2, * u = pa->param[n]->data.u; + int w; + message * m; + + if (pa->param[n]->flag & TARGET_NOTFOUND) continue; + + if (u->region!=ro) { + /* this can happen several times if the units are from different astral + * regions. Only possible on the intersections of schemes */ + region_list * rfind; + if (!is_astral(u->region)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spellfail_astralonly", "")); + continue; + } + if (rtl!=NULL) free_regionlist(rtl); + rtl = astralregions(u->region, NULL); + for (rfind=rtl;rfind!=NULL;rfind=rfind->next) { + if (rfind->data==mage->region) break; + } + if (rfind==NULL) { + /* the region r is not in the schemes of rt */ + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + "spellfail_distance", "target", u)); + continue; + } + ro = u->region; + } + + if (is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + "spellfail_astralblock", "")); + continue; + } + + if (!can_survive(u, rt)) { + cmistake(mage, co->order, 231, MSG_MAGIC); + continue; + } + + w = weight(u); + if (remaining_cap - w < 0) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, + "fail_tooheavy", "target", u)); + continue; + } + + if (!ucontact(u, mage)) { + if (power>12 && !(pa->param[n]->flag & TARGET_RESISTS)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_no_resist", "target", u)); + ADDMSG(&u->faction->msgs, msg_message("send_astral", "unit target", mage, u)); + } else { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "feedback_no_contact_resist", "target", u)); + ADDMSG(&u->faction->msgs, msg_message("try_astral", "unit target", mage, u)); + continue; + } + } + + remaining_cap -= w; + move_unit(u, rt, NULL); + + /* Meldungen in der Ausgangsregion */ + for (u2 = ro->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = ro->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, ro, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_disappear", "unit", u); + r_addmessage(ro, u2->faction, m); + } + } + } + if (m) msg_release(m); + + /* Meldungen in der Zielregion */ + for (u2 = rt->units; u2; u2 = u2->next) freset(u2->faction, FFL_SELECT); + m = NULL; + for (u2 = rt->units; u2; u2 = u2->next ) { + if (!fval(u2->faction, FFL_SELECT)) { + if (cansee(u2->faction, rt, u, 0)) { + fset(u2->faction, FFL_SELECT); + if (!m) m = msg_message("astral_appear", "unit", u); + r_addmessage(rt, u2->faction, m); + } + } + } + if (m) msg_release(m); + } + if (rtl!=NULL) free_regionlist(rtl); + return cast_level; +} + +#ifdef SHOWASTRAL_NOT_BORKED +int +sp_showastral(castorder *co) +{ + unit *u; + region *rt; + int n = 0; + int c = 0; + region_list *rl, *rl2; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + + switch(getplaneid(r)) { + case 0: + rt = r_standard_to_astral(r); + if (!rt || fval(rt->terrain, FORBIDDEN_REGION)) { + /* Hier gibt es keine Verbindung zur astralen Welt */ + cmistake(mage, co->order, 216, MSG_MAGIC); + return 0; + } + break; + case 1: + rt = r; + break; + default: + /* Hier gibt es keine Verbindung zur astralen Welt */ + cmistake(mage, co->order, 216, MSG_MAGIC); + return 0; + } + + rl = all_in_range(rt,power/5); + + /* Erst Einheiten z�hlen, f�r die Grammatik. */ + + for (rl2=rl; rl2; rl2=rl2->next) { + region * r2 = rl2->data; + if (!is_cursed(r2->attribs, C_ASTRALBLOCK, 0)) { + for(u = r2->units; u; u=u->next) { + if (u->race != new_race[RC_SPECIAL] && u->race != new_race[RC_SPELL]) n++; + } + } + } + + if (n == 0) { + /* sprintf(buf, "%s kann niemanden im astralen Nebel entdecken.", + unitname(mage)); */ + cmistake(mage, co->order, 220, MSG_MAGIC); + } else { + + /* Ausgeben */ + + sprintf(buf, "%s hat eine Vision der astralen Ebene. Im astralen " + "Nebel zu erkennen sind ", unitname(mage)); + + for(rl2=rl; rl2; rl2=rl2->next) { + if (!is_cursed(rl2->data->attribs, C_ASTRALBLOCK, 0)) { + for(u = rl2->data->units; u; u=u->next) { + if (u->race != new_race[RC_SPECIAL] && u->race != new_race[RC_SPELL]) { + c++; + scat(unitname(u)); + scat(" ("); + if (!fval(u, UFL_ANON_FACTION)) { + scat(factionname(u->faction)); + scat(", "); + } + icat(u->number); + scat(" "); + scat(LOC(mage->faction->locale, rc_name(u->race, u->number!=1))); + scat(", Entfernung "); + icat(distance(rl2->data, rt)); + scat(")"); + if (c == n-1) { + scat(" und "); + } else if (c < n-1) { + scat(", "); + } + } + } + } + } + scat("."); + addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO); + } + + free_regionlist(rl); + return cast_level; + unused(co); + return 0; +} +#endif + +/* ------------------------------------------------------------- */ +int +sp_viewreality(castorder *co) +{ + region_list *rl, *rl2; + unit *u; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + message * m; + + if (getplaneid(r) != 1) { + /* sprintf(buf, "Dieser Zauber kann nur im Astralraum gezaubert werden."); */ + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "spell_astral_only", "")); + return 0; + } + + rl = astralregions(r, NULL); + + /* Irgendwann mal auf Curses u/o Attribut umstellen. */ + for (rl2=rl; rl2; rl2=rl2->next) { + region * rt = rl2->data; + if (!is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) { + u = create_unit(rt, mage->faction, RS_FARVISION, new_race[RC_SPELL], 0, "spell/viewreality", NULL); + set_level(u, SK_PERCEPTION, co->level/2); + u->age = 2; + } + } + + free_regionlist(rl); + + m = msg_message("viewreality_effect", "unit", mage); + r_addmessage(r, mage->faction, m); + msg_release(m); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +int +sp_disruptastral(castorder *co) +{ + region_list *rl, *rl2; + region *rt; + unit *u; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + int duration = (int)(power/3)+1; + + switch(getplaneid(r)) { + case 0: + rt = r_standard_to_astral(r); + if (!rt || fval(rt->terrain, FORBIDDEN_REGION)) { + /* "Hier gibt es keine Verbindung zur astralen Welt." */ + cmistake(mage, co->order, 216, MSG_MAGIC); + return 0; + } + break; + case 1: + rt = r; + break; + default: + /* "Von hier aus kann man die astrale Ebene nicht erreichen." */ + cmistake(mage, co->order, 215, MSG_MAGIC); + return 0; + } + + rl = all_in_range(rt, (short)(power/5), NULL); + + for (rl2=rl; rl2!=NULL; rl2=rl2->next) { + attrib *a; + double effect; + region * r2 = rl2->data; + spec_direction *sd; + int inhab_regions = 0; + region_list * trl = NULL; + + if (is_cursed(r2->attribs, C_ASTRALBLOCK, 0)) continue; + + if (r2->units!=NULL) { + region_list * trl2; + + trl = astralregions(rl2->data, inhabitable); + for (trl2 = trl; trl2; trl2 = trl2->next) ++inhab_regions; + } + + /* Nicht-Permanente Tore zerst�ren */ + a = a_find(r->attribs, &at_direction); + + while (a!=NULL && a->type==&at_direction) { + attrib * a2 = a->next; + sd = (spec_direction *)(a->data.v); + if (sd->duration != -1) a_remove(&r->attribs, a); + a = a2; + } + + /* Einheiten auswerfen */ + + if (trl!=NULL) { + for (u=r2->units;u;u=u->next) { + if (u->race != new_race[RC_SPELL]) { + region_list *trl2 = trl; + region *tr; + int c = rng_int() % inhab_regions; + + /* Zuf�llige Zielregion suchen */ + while (c--!=0) trl2 = trl2->next; + tr = trl2->data; + + if (!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) { + message * msg = msg_message("disrupt_astral", "unit region", u, tr); + add_message(&u->faction->msgs, msg); + add_message(&tr->msgs, msg); + msg_release(msg); + + move_unit(u, tr, NULL); + } + } + } + free_regionlist(trl); + } + + /* Kontakt unterbinden */ + effect = 100; + create_curse(mage, &rl2->data->attribs, ct_find("astralblock"), + power, duration, effect, 0); + } + + free_regionlist(rl); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Mauern der Ewigkeit + * Stufe: 7 + * Kategorie: Artefakt + * Gebiet: Tybied + * Wirkung: + * Das Geb�ude kostet keinen Unterhalt mehr + * + * ZAUBER "Mauern der Ewigkeit" <geb�ude-nummer> + * Flags: (0) + */ +static int +sp_eternizewall(castorder *co) +{ + unit *u; + curse * c; + building *b; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + spellparameter *pa = co->par; + message * msg; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + b = pa->param[0]->data.b; + c = create_curse(mage, &b->attribs, ct_find("nocostbuilding"), + power*power, 1, zero_effect, 0); + + if (c==NULL) { /* ist bereits verzaubert */ + cmistake(mage, co->order, 206, MSG_MAGIC); + return 0; + } + + /* melden, 1x pro Partei in der Burg */ + for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + msg = msg_message("sp_eternizewall_effect", "mage building region", mage, b, r); + for (u = r->units; u; u = u->next) { + if (!fval(u->faction, FFL_SELECT)) { + fset(u->faction, FFL_SELECT); + if (u->building == b) { + r_addmessage(r, u->faction, msg); + } + } + } + if (r!=mage->region) { + add_message(&mage->faction->msgs, msg); + } else if (mage->building!=b) { + r_addmessage(r, mage->faction, msg); + } + msg_release(msg); + + return cast_level; +} + + +/* ------------------------------------------------------------- */ +/* Name: Opfere Kraft + * Stufe: 15 + * Gebiet: Tybied + * Kategorie: Einheit, positiv + * Wirkung: + * Mit Hilfe dieses Zaubers kann der Magier einen Teil seiner + * magischen Kraft permanent auf einen anderen Magier �bertragen. Auf + * einen Tybied-Magier kann er die H�lfte der eingesetzten Kraft + * �bertragen, auf einen Magier eines anderen Gebietes ein Drittel. + * + * Flags: + * (UNITSPELL) + * + * Syntax: + * ZAUBERE \"Opfere Kraft\" <Einheit-Nr> <Aura> + * "ui" + */ +int +sp_permtransfer(castorder *co) +{ + int aura; + unit *tu; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + const spell *sp = co->sp; + message * msg; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + /* wenn Ziel gefunden, dieses aber Magieresistent war, Zauber + * abbrechen aber kosten lassen */ + if (pa->param[0]->flag == TARGET_RESISTS) return cast_level; + + tu = pa->param[0]->data.u; + aura = pa->param[1]->data.i; + + if (!is_mage(tu)) { +/* sprintf(buf, "%s in %s: 'ZAUBER %s': Einheit ist kein Magier." + , unitname(mage), regionname(mage->region, mage->faction),sa->strings[0]); */ + cmistake(mage, co->order, 214, MSG_MAGIC); + return 0; + } + + aura = MIN(get_spellpoints(mage)-spellcost(mage, sp), aura); + + change_maxspellpoints(mage,-aura); + change_spellpoints(mage,-aura); + + if (get_mage(tu)->magietyp == get_mage(mage)->magietyp) { + change_maxspellpoints(tu, aura/2); + } else { + change_maxspellpoints(tu, aura/3); + } + + msg = msg_message("sp_permtransfer_effect", "mage target amount", mage, tu, aura); + add_message(&mage->faction->msgs, msg); + if (tu->faction!=mage->faction) { + add_message(&tu->faction->msgs, msg); + } + msg_release(msg); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* TODO: specialdirections? */ + +int +sp_movecastle(castorder *co) +{ + building *b; + direction_t dir; + region *target_region; + unit *u, *unext; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + message* msg; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + b = pa->param[0]->data.b; + dir = finddirection(pa->param[1]->data.xs, mage->faction->locale); + + if (dir == NODIRECTION) { + /* Die Richtung wurde nicht erkannt */ + cmistake(mage, co->order, 71, MSG_PRODUCE); + return 0; + } + + if (b->size > (cast_level-12) * 250) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "sp_movecastle_fail_0", "")); + return cast_level; + } + + target_region = rconnect(r,dir); + + if (!(target_region->terrain->flags & LAND_REGION)) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "sp_movecastle_fail_1", "direction", dir)); + return cast_level; + } + + bunhash(b); + translist(&r->buildings, &target_region->buildings, b); + b->region = target_region; + b->size -= b->size/(10-rng_int()%6); + bhash(b); + + for(u=r->units;u;) { + unext = u->next; + if (u->building == b) { + uunhash(u); + translist(&r->units, &target_region->units, u); + uhash(u); + } + u = unext; + } + + if ((b->type==bt_find("caravan") || b->type==bt_find("dam") || b->type==bt_find("tunnel"))) { + boolean damage = false; + direction_t d; + for (d=0;d!=MAXDIRECTIONS;++d) { + if (rroad(r, d)) { + rsetroad(r, d, rroad(r, d)/2); + damage = true; + } + } +/* if (damage) strcat(buf, " Die Stra�en der Region wurden besch�digt."); */ + } + + msg = msg_message("sp_movecastle_effect", "building direction", b, dir); + r_addmessage(r, NULL, msg); + msg_release(msg); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Luftschiff + * Stufe: 6 + * + * Wirkung: + * L��t ein Schiff eine Runde lang fliegen. Wirkt nur auf Boote und + * Langboote. + * Kombinierbar mit "G�nstige Winde", aber nicht mit "Sturmwind". + * + * Flag: + * (ONSHIPCAST | SHIPSPELL | TESTRESISTANCE) + */ +int +sp_flying_ship(castorder *co) +{ + ship *sh; + unit *u; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + spellparameter *pa = co->par; + message * m = NULL; + int cno; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + sh = pa->param[0]->data.sh; + if (sh->type->construction->maxsize>50) { + ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order, "error_flying_ship_too_big", "ship", sh)); + return 0; + } + + /* Duration = 1, nur diese Runde */ + + cno = levitate_ship(sh, mage, power, 1); + if (cno==0) { + if (is_cursed(sh->attribs, C_SHIP_FLYING, 0) ) { + /* Auf dem Schiff befindet liegt bereits so ein Zauber. */ + cmistake(mage, co->order, 211, MSG_MAGIC); + } else if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0) ) { + /* Es ist zu gef�hrlich, ein sturmgepeitschtes Schiff fliegen zu lassen. */ + cmistake(mage, co->order, 210, MSG_MAGIC); + } + return 0; + } + sh->coast = NODIRECTION; + + /* melden, 1x pro Partei */ + for (u = r->units; u; u = u->next) freset(u->faction, FFL_SELECT); + for(u = r->units; u; u = u->next ) { + /* das sehen nat�rlich auch die Leute an Land */ + if (!fval(u->faction, FFL_SELECT) ) { + fset(u->faction, FFL_SELECT); + if (!m) m = msg_message("flying_ship_result", "mage ship", mage, sh); + add_message(&u->faction->msgs, m); + } + } + if (m) msg_release(m); + return cast_level; +} + + +/* ------------------------------------------------------------- */ +/* Name: Stehle Aura + * Stufe: 6 + * Kategorie: Einheit, negativ + * Wirkung: + * Mit Hilfe dieses Zaubers kann der Magier einem anderen Magier + * seine Aura gegen dessen Willen entziehen und sich selber + * zuf�hren. + * + * Flags: + * (FARCASTING | SPELLLEVEL | UNITSPELL | TESTRESISTANCE | + * TESTCANSEE) + * */ +int +sp_stealaura(castorder *co) +{ + int taura; + unit *u; + unit *mage = co->magician.u; + int cast_level = co->level; + double power = co->force; + spellparameter *pa = co->par; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + /* Zieleinheit */ + u = pa->param[0]->data.u; + + if (!get_mage(u)) { + ADDMSG(&mage->faction->msgs, msg_message( + "stealaura_fail", "unit target", mage, u)); + ADDMSG(&u->faction->msgs, msg_message( + "stealaura_fail_detect", "unit", u)); + return 0; + } + + taura = (get_mage(u)->spellpoints*(rng_int()%(int)(3*power)+1))/100; + + if (taura > 0) { + get_mage(u)->spellpoints -= taura; + get_mage(mage)->spellpoints += taura; +/* sprintf(buf, "%s entzieht %s %d Aura.", unitname(mage), unitname(u), + taura); */ + ADDMSG(&mage->faction->msgs, msg_message( + "stealaura_success", "mage target aura", mage, u, taura)); +/* sprintf(buf, "%s f�hlt seine magischen Kr�fte schwinden und verliert %d " + "Aura.", unitname(u), taura); */ + ADDMSG(&u->faction->msgs, msg_message( + "stealaura_detect", "unit aura", u, taura)); + } else { + ADDMSG(&mage->faction->msgs, msg_message( + "stealaura_fail", "unit target", mage, u)); + ADDMSG(&u->faction->msgs, msg_message( + "stealaura_fail_detect", "unit", u)); + } + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Astrale Schw�chezone + * Stufe: 5 + * Kategorie: + * Wirkung: + * Reduziert die St�rke jedes Spruch in der Region um Level H�lt + * Spr�che bis zu einem Gesammtlevel von St�rke*10 aus, danach ist + * sie verbraucht. + * leibt bis zu St�rke Wochen aktiv. + * Ein Ring der Macht erh�ht die St�rke um 1, in einem Magierturm + * gezaubert gibt nochmal +1 auf St�rke. (force) + * + * Beispiel: + * Eine Antimagiezone Stufe 7 h�lt bis zu 7 Wochen an oder Spr�che mit + * einem Gesammtlevel bis zu 70 auf. Also zB 7 Stufe 10 Spr�che, 10 + * Stufe 7 Spr�che oder 35 Stufe 2 Spr�che. Sie reduziert die St�rke + * (level+boni) jedes Spruchs, der in der Region gezaubert wird, um + * 7. Alle Spr�che mit einer St�rke kleiner als 7 schlagen fehl + * (power = 0). + * + * Flags: + * (FARCASTING | SPELLLEVEL | REGIONSPELL | TESTRESISTANCE) + * + */ +int +sp_antimagiczone(castorder *co) +{ + double power; + double effect; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + int duration = (int)force+1; + + /* H�lt Spr�che bis zu einem summierten Gesamtlevel von power aus. + * Jeder Zauber reduziert die 'Lebenskraft' (vigour) der Antimagiezone + * um seine Stufe */ + power = force * 10; + + /* Reduziert die St�rke jedes Spruchs um effect */ + effect = cast_level; + + create_curse(mage, &r->attribs, ct_find("antimagiczone"), power, duration, + effect, 0); + + /* Erfolg melden*/ + ADDMSG(&mage->faction->msgs, msg_message( + "regionmagic_effect", "unit region command", mage, + mage->region, co->order)); + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Schutzrunen + * Stufe: 8 + * Kosten: SPC_FIX + * + * Wirkung: + * Gibt Geb�uden einen Bonus auf Magieresistenz von +20%. Der Zauber + * dauert 3+rng_int()%Level Wochen an, also im Extremfall bis zu 2 Jahre + * bei Stufe 20 + * + * Es k�nnen mehrere Zauber �bereinander gelegt werden, der Effekt + * summiert sich, jedoch wird die Dauer dadurch nicht verl�ngert. + * + * oder: + * + * Gibt Schiffen einen Bonus auf Magieresistenz von +20%. Der Zauber + * dauert 3+rng_int()%Level Wochen an, also im Extremfall bis zu 2 Jahre + * bei Stufe 20 + * + * Es k�nnen mehrere Zauber �bereinander gelegt werden, der Effekt + * summiert sich, jedoch wird die Dauer dadurch nicht verl�ngert. + * + * Flags: + * (ONSHIPCAST | TESTRESISTANCE) + * + * Syntax: + * ZAUBERE \"Runen des Schutzes\" GEBAEUDE <Gebaeude-Nr> + * ZAUBERE \"Runen des Schutzes\" SCHIFF <Schiff-Nr> + * "kc" + */ + +static int +sp_magicrunes(castorder *co) +{ + int duration; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + spellparameter *pa = co->par; + double effect; + + duration = 3 + rng_int()%cast_level; + effect = 20; + + switch(pa->param[0]->typ) { + case SPP_BUILDING: + { + building *b; + b = pa->param[0]->data.b; + + /* Magieresistenz der Burg erh�ht sich um 20% */ + create_curse(mage, &b->attribs, ct_find("magicrunes"), force, + duration, effect, 0); + + /* Erfolg melden */ + ADDMSG(&mage->faction->msgs, msg_message( + "objmagic_effect", "unit region command target", mage, + mage->region, co->order, buildingname(b))); + break; + } + case SPP_SHIP: + { + ship *sh; + sh = pa->param[0]->data.sh; + /* Magieresistenz des Schiffs erh�ht sich um 20% */ + create_curse(mage, &sh->attribs, ct_find("magicrunes"), force, + duration, effect, 0); + + /* Erfolg melden */ + ADDMSG(&mage->faction->msgs, msg_message( + "objmagic_effect", "unit region command target", mage, + mage->region, co->order, shipname(sh))); + break; + } + default: + /* fehlerhafter Parameter */ + return 0; + } + + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Zeitdehnung + * + * Flags: + * (UNITSPELL | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) + * Syntax: + * "u+" + */ + +int +sp_speed2(castorder *co) +{ + int n, maxmen, used = 0, dur, men; + unit *u; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + spellparameter *pa = co->par; + + maxmen = 2 * cast_level * cast_level; + dur = MAX(1, cast_level/2); + + for (n = 0; n < pa->length; n++) { + double effect; + /* sollte nie negativ werden */ + if (maxmen < 1) + break; + + if (pa->param[n]->flag == TARGET_RESISTS + || pa->param[n]->flag == TARGET_NOTFOUND) + continue; + + u = pa->param[n]->data.u; + + men = MIN(maxmen,u->number); + effect = 2; + create_curse(mage, &u->attribs, ct_find("speed"), force, dur, effect, men); + maxmen -= men; + used += men; + } + + ADDMSG(&mage->faction->msgs, msg_message("speed_time_effect", "unit region amount", mage, mage->region, used)); + /* Effektiv ben�tigten cast_level (mindestens 1) zur�ckgeben */ + used = (int)sqrt(used/2); + return MAX(1, used); +} + +/* ------------------------------------------------------------- */ +/* Name: Magiefresser + * Stufe: 7 + * Kosten: SPC_LEVEL + * + * Wirkung: + * Kann eine bestimmte Verzauberung angreifen und aufl�sen. Die St�rke + * des Zaubers muss st�rker sein als die der Verzauberung. + * Syntax: + * ZAUBERE \"Magiefresser\" REGION + * ZAUBERE \"Magiefresser\" EINHEIT <Einheit-Nr> + * ZAUBERE \"Magiefresser\" GEBAEUDE <Gebaeude-Nr> + * ZAUBERE \"Magiefresser\" SCHIFF <Schiff-Nr> + * + * "kc?c" + * Flags: + * (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) + */ +/* Jeder gebrochene Zauber verbraucht c->vigour an Zauberkraft + * (force) */ +int +sp_q_antimagie(castorder *co) +{ + attrib **ap; + int obj; + curse * c = NULL; + int succ; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + spellparameter *pa = co->par; + const char *ts = NULL; + + obj = pa->param[0]->typ; + + switch(obj) { + case SPP_REGION: + ap = &r->attribs; + ts = regionname(r, mage->faction); + break; + + case SPP_TEMP: + case SPP_UNIT: + { + unit *u = pa->param[0]->data.u; + ap = &u->attribs; + ts = unitid(u); + break; + } + case SPP_BUILDING: + { + building *b = pa->param[0]->data.b; + ap = &b->attribs; + ts = buildingid(b); + break; + } + case SPP_SHIP: + { + ship *sh = pa->param[0]->data.sh; + ap = &sh->attribs; + ts = shipid(sh); + break; + } + default: + /* Das Zielobjekt wurde vergessen */ + cmistake(mage, co->order, 203, MSG_MAGIC); + return 0; + } + + succ = break_curse(ap, cast_level, force, c); + + if (succ) { + ADDMSG(&mage->faction->msgs, msg_message( + "destroy_magic_effect", "unit region command succ target", + mage, mage->region, co->order, succ, ts)); + } else { + ADDMSG(&mage->faction->msgs, msg_message( + "destroy_magic_noeffect", "unit region command", + mage, mage->region, co->order)); + } + return MAX(succ, 1); +} + +/* ------------------------------------------------------------- */ +/* Name: Fluch brechen + * Stufe: 7 + * Kosten: SPC_LEVEL + * + * Wirkung: + * Kann eine bestimmte Verzauberung angreifen und aufl�sen. Die St�rke + * des Zaubers muss st�rker sein als die der Verzauberung. + * Syntax: + * ZAUBERE \"Fluch brechen\" REGION <Zauber-id> + * ZAUBERE \"Fluch brechen\" EINHEIT <Einheit-Nr> <Zauber-id> + * ZAUBERE \"Fluch brechen\" GEBAEUDE <Gebaeude-Nr> <Zauber-id> + * ZAUBERE \"Fluch brechen\" SCHIFF <Schiff-Nr> <Zauber-id> + * + * "kcc" + * Flags: + * (FARCASTING | SPELLLEVEL | ONSHIPCAST | TESTCANSEE) + */ +int +sp_break_curse(castorder *co) +{ + attrib **ap; + int obj; + curse * c; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + double force = co->force; + spellparameter *pa = co->par; + const char *ts = NULL; + + if (pa->length < 2) { + /* Das Zielobjekt wurde vergessen */ + cmistake(mage, co->order, 203, MSG_MAGIC); + } + + obj = pa->param[0]->typ; + + c = findcurse(atoi36(pa->param[1]->data.s)); + if (!c) { + /* Es wurde kein Ziel gefunden */ + ADDMSG(&mage->faction->msgs, msg_message( + "spelltargetnotfound", "unit region command", + mage, mage->region, co->order)); + } else { + switch(obj) { + case SPP_REGION: + ap = &r->attribs; + ts = regionname(r, mage->faction); + break; + + case SPP_TEMP: + case SPP_UNIT: + { + unit *u = pa->param[0]->data.u; + ap = &u->attribs; + ts = unitid(u); + break; + } + case SPP_BUILDING: + { + building *b = pa->param[0]->data.b; + ap = &b->attribs; + ts = buildingid(b); + break; + } + case SPP_SHIP: + { + ship *sh = pa->param[0]->data.sh; + ap = &sh->attribs; + ts = shipid(sh); + break; + } + default: + /* Das Zielobjekt wurde vergessen */ + cmistake(mage, co->order, 203, MSG_MAGIC); + return 0; + } + + /* �berpr�fung, ob curse zu diesem objekt geh�rt */ + if (!is_cursed_with(*ap, c)) { + /* Es wurde kein Ziel gefunden */ + ADDMSG(&mage->faction->msgs, + msg_message( + "spelltargetnotfound", "unit region command", + mage, mage->region, co->order)); + } + + /* curse aufl�sen, wenn zauber st�rker (force > vigour)*/ + c->vigour -= force; + + if (c->vigour <= 0.0) { + remove_curse(ap, c); + + ADDMSG(&mage->faction->msgs, msg_message( + "destroy_curse_effect", "unit region command id target", + mage, mage->region, co->order, pa->param[1]->data.xs, ts)); + } else { + ADDMSG(&mage->faction->msgs, msg_message( + "destroy_curse_noeffect", "unit region command id target", + mage, mage->region, co->order, pa->param[1]->data.xs, ts)); + } + } + + return cast_level; +} + + +/* ------------------------------------------------------------- */ +int +sp_becomewyrm(castorder *co) +{ + return 0; +} + +/* ------------------------------------------------------------- */ +/* Name: WDW-Pyramidenfindezauber + * Stufe: unterschiedlich + * Gebiet: alle + * Wirkung: + * gibt die ungefaehre Entfernung zur naechstgelegenen Pyramiden- + * region an. + * + * Flags: + */ +static int +sp_wdwpyramid(castorder *co) +{ + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + + if (a_find(r->attribs, &at_wdwpyramid) != NULL) { + ADDMSG(&mage->faction->msgs, msg_message("wdw_pyramidspell_found", + "unit region command", mage, r, co->order)); + } else { + region *r2; + int mindist = INT_MAX; + int minshowdist; + int maxshowdist; + + for(r2 = regions; r2; r2 = r2->next) { + if (a_find(r2->attribs, &at_wdwpyramid) != NULL) { + int dist = distance(mage->region, r2); + if (dist < mindist) { + mindist = dist; + } + } + } + + assert(mindist >= 1); + + minshowdist = mindist - rng_int()%5; + maxshowdist = minshowdist + 4; + + ADDMSG(&mage->faction->msgs, msg_message("wdw_pyramidspell_notfound", + "unit region command mindist maxdist", mage, r, co->order, + MAX(1, minshowdist), maxshowdist)); + } + + return cast_level; +} + +typedef struct spelldata { + spellid_t id; + const char *sname; + spell_f sp_function; + void (*patzer) (castorder*); +} spelldata; + +static spelldata spelldaten[] = +{ + /* M_GWYRRD */ + { + SPL_STONEGOLEM, "stonegolem", + (spell_f)sp_create_stonegolem, NULL + }, + { + SPL_IRONGOLEM, "irongolem", + (spell_f)sp_create_irongolem, NULL + }, + { + SPL_TREEGROW, "treegrow", + (spell_f)sp_hain, patzer_ents + }, + { + SPL_RUSTWEAPON, "rustweapon", + (spell_f)sp_rosthauch, NULL + }, + { + SPL_KAELTESCHUTZ, "cold_protection", + (spell_f)sp_kaelteschutz, NULL + }, + { + SPL_HAGEL, "hail", + (spell_f)sp_kampfzauber, NULL + }, + { + SPL_IRONKEEPER, "ironkeeper", + (spell_f)sp_ironkeeper, NULL + }, + { + SPL_MAGICSTREET, "magicstreet", + (spell_f)sp_magicstreet, NULL + }, + { + SPL_WINDSHIELD, "windshield", + (spell_f)sp_windshield, NULL + }, + { + SPL_MALLORNTREEGROW, "mallorntreegrow", + (spell_f)sp_mallornhain, patzer_ents + }, + { SPL_GOODWINDS, "goodwinds", + (spell_f)sp_goodwinds, NULL + }, + { + SPL_HEALING, "healing", + (spell_f)sp_healing, NULL + }, + { + SPL_REELING_ARROWS, "reelingarrows", + (spell_f)sp_reeling_arrows, NULL + }, + { + SPL_GWYRRD_FUMBLESHIELD, "gwyrrdfumbleshield", + (spell_f)sp_fumbleshield, NULL + }, + { + SPL_TRANSFERAURA_DRUIDE, "transferauradruide", + (spell_f)sp_transferaura, NULL + }, + { + SPL_EARTHQUAKE, "earthquake", + (spell_f)sp_earthquake, NULL + }, + { + SPL_STORMWINDS, "stormwinds", + (spell_f)sp_stormwinds, NULL + }, + { + SPL_HOMESTONE, "homestone", + (spell_f)sp_homestone, NULL + }, + { + SPL_WOLFHOWL, "wolfhowl", + (spell_f)sp_wolfhowl, NULL + }, + { + SPL_VERSTEINERN, "versteinern", + (spell_f)sp_petrify, NULL + }, + { + SPL_STRONG_WALL, "strongwall", + (spell_f)sp_strong_wall, NULL + }, + { + SPL_GWYRRD_DESTROY_MAGIC, "gwyrrddestroymagic", + (spell_f)sp_destroy_magic, NULL + }, + { + SPL_TREEWALKENTER, "treewalkenter", + (spell_f)sp_treewalkenter, NULL + }, + { + SPL_TREEWALKEXIT, "treewalkexit", + (spell_f)sp_treewalkexit, NULL + }, + { + SPL_HOLYGROUND, "holyground", + (spell_f)sp_holyground, NULL + }, + { + SPL_SUMMONENT, "summonent", + (spell_f)sp_summonent, NULL + }, + { + SPL_GWYRRD_FAMILIAR, "gwyrrdfamiliar", + (spell_f)sp_summon_familiar, NULL + }, + { + SPL_BLESSSTONECIRCLE, "blessstonecircle", + (spell_f)sp_blessstonecircle, NULL + }, + { + SPL_GWYRRD_ARMORSHIELD, "barkskin", + (spell_f)sp_armorshield, NULL + }, + { + SPL_DROUGHT, "summonfireelemental", + (spell_f)sp_drought, NULL + }, + { + SPL_MAELSTROM, "maelstrom", + (spell_f)sp_maelstrom, NULL + }, + { + SPL_MALLORN, "magic_roots", + (spell_f)sp_mallorn, NULL + }, + { + SPL_GREAT_DROUGHT, "great_drought", + (spell_f)sp_great_drought, NULL + }, + /* M_DRAIG */ + { + SPL_SPARKLE_CHAOS, "sparklechaos", + (spell_f)sp_sparkle, NULL + }, + { + SPL_FIREBALL, "fireball", + (spell_f)sp_kampfzauber, NULL + }, + { + SPL_MAGICBOOST, "magicboost", + (spell_f)sp_magicboost, NULL + }, + { + SPL_BLOODSACRIFICE, "bloodsacrifice", + (spell_f)sp_bloodsacrifice, NULL + }, + { + SPL_BERSERK, "berserk", + (spell_f)sp_berserk, NULL + }, + { + SPL_FUMBLECURSE, "fumblecurse", + (spell_f)sp_fumblecurse, patzer_fumblecurse + }, + { + SPL_SUMMONUNDEAD, "summonundead", + (spell_f)sp_summonundead, patzer_peasantmob + }, + { + SPL_COMBATRUST, "combatrust", + (spell_f)sp_combatrosthauch, NULL + }, + { + SPL_TRANSFERAURA_CHAOS, "transferaurachaos", + (spell_f)sp_transferaura, NULL + }, + { + SPL_FIREWALL, "firewall", + (spell_f)sp_firewall, patzer_peasantmob + }, + { + SPL_PLAGUE, "plague", + (spell_f)sp_plague, patzer_peasantmob + }, + { + SPL_CHAOSROW, "chaosrow", + (spell_f)sp_chaosrow, NULL + }, + { + SPL_SUMMONSHADOW, "summonshadow", + (spell_f)sp_summonshadow, patzer_peasantmob + }, + { + SPL_UNDEADHERO, "undeadhero", + (spell_f)sp_undeadhero, NULL + }, + { + SPL_AURALEAK, "auraleak", + (spell_f)sp_auraleak, NULL + }, + { + SPL_DRAIG_FUMBLESHIELD, "draigfumbleshield", + (spell_f)sp_fumbleshield, NULL + }, + { + SPL_FOREST_FIRE, "forestfire", + (spell_f)sp_forest_fire, patzer_peasantmob + }, + { + SPL_DRAIG_DESTROY_MAGIC, "draigdestroymagic", + (spell_f)sp_destroy_magic, NULL + }, + { + SPL_UNHOLYPOWER, "unholypower", + (spell_f)sp_unholypower, NULL + }, + { + SPL_DEATHCLOUD, "deathcloud", + (spell_f)sp_deathcloud, patzer_peasantmob + }, + { + SPL_SUMMONDRAGON, "summondragon", + (spell_f)sp_summondragon, patzer_peasantmob + }, + { + SPL_SUMMONSHADOWLORDS, "summonshadowlords", + (spell_f)sp_summonshadowlords, patzer_peasantmob + }, + { + SPL_DRAIG_FAMILIAR, "draigfamiliar", + (spell_f)sp_summon_familiar, NULL + }, + { + SPL_CHAOSSUCTION, "chaossuction", + (spell_f)sp_chaossuction, patzer_peasantmob + }, + /* M_ILLAUN */ + { + SPL_SPARKLE_DREAM, "sparkledream", + (spell_f)sp_sparkle, NULL + }, + { + SPL_SHADOWKNIGHTS, "shadowknights", + (spell_f)sp_shadowknights, NULL + }, + { + SPL_FLEE, "flee", + (spell_f)sp_flee, NULL + }, + { + SPL_PUTTOREST, "puttorest", + (spell_f)sp_puttorest, NULL + }, + { + SPL_ICASTLE, "icastle", + (spell_f)sp_icastle, NULL + }, + { + SPL_TRANSFERAURA_TRAUM, "transferauratraum", + (spell_f)sp_transferaura, NULL + }, + { + SPL_ILL_SHAPESHIFT, "shapeshift", + (spell_f)sp_illusionary_shapeshift, NULL + }, + { + SPL_DREAMREADING, "dreamreading", + (spell_f)sp_dreamreading, NULL + }, + { + SPL_TIREDSOLDIERS, "tiredsoldiers", + (spell_f)sp_tiredsoldiers, NULL + }, + { + SPL_REANIMATE, "reanimate", + (spell_f)sp_reanimate, NULL + }, + { + SPL_ANALYSEDREAM, "analysedream", + (spell_f)sp_analysedream, NULL + }, + { + SPL_DISTURBINGDREAMS, "disturbingdreams", + (spell_f)sp_disturbingdreams, NULL + }, + { + SPL_SLEEP, "sleep", + (spell_f)sp_sleep, NULL + }, + { + SPL_WISPS, "wisps", + (spell_f)sp_wisps, NULL + }, + { + SPL_GOODDREAMS, "gooddreams", + (spell_f)sp_gooddreams, NULL + }, + { + SPL_ILLAUN_DESTROY_MAGIC, "illaundestroymagic", + (spell_f)sp_destroy_magic, NULL + }, + { + SPL_ILLAUN_FAMILIAR, "illaunfamiliar", + (spell_f)sp_summon_familiar, NULL + }, + { + SPL_CLONECOPY, "clone", + (spell_f)sp_clonecopy, NULL + }, + { + SPL_BADDREAMS, "bad_dreams", + (spell_f)sp_baddreams, NULL + }, + { + SPL_MINDBLAST, "mindblast", + (spell_f)sp_mindblast_temp, NULL + }, + { + SPL_ORKDREAM, "orkdream", + (spell_f)sp_sweetdreams, NULL + }, + { + SPL_SUMMON_ALP, "summon_alp", + (spell_f)sp_summon_alp, NULL + }, + /* M_CERDDOR */ + { + SPL_DENYATTACK, "appeasement", + (spell_f)sp_denyattack, NULL + }, + { + SPL_HEALINGSONG, "song_of_healing", + (spell_f)sp_healing, NULL + }, + { + SPL_GENEROUS, "generous", + (spell_f)sp_generous, NULL + }, + { + SPL_SONG_OF_FEAR, "song_of_fear", + (spell_f)sp_flee, NULL + }, + { + SPL_RECRUIT, "courting", + (spell_f)sp_recruit, NULL + }, + { + SPL_SONG_OF_CONFUSION, "song_of_confusion", + (spell_f)sp_chaosrow, NULL + }, + { + SPL_HERO, "heroic_song", + (spell_f)sp_hero, NULL + }, + { + SPL_TRANSFERAURA_BARDE, "transfer_aura_song", + (spell_f)sp_transferaura, NULL + }, + { + SPL_UNIT_ANALYSESONG, "analysesong_unit", + (spell_f)sp_analysesong_unit, NULL + }, + { + SPL_CERRDOR_FUMBLESHIELD, "cerrdorfumbleshield", + (spell_f)sp_fumbleshield, NULL + }, + { SPL_CALM_MONSTER, "calm_monster", + (spell_f)sp_calm_monster, NULL + }, + { SPL_SEDUCE, "seduction", + (spell_f)sp_seduce, NULL + }, + { + SPL_HEADACHE, "headache", + (spell_f)sp_headache, NULL + }, + { SPL_PUMP, "sound_out", + (spell_f)sp_pump, NULL + }, + { + SPL_BLOODTHIRST, "bloodthirst", + (spell_f)sp_berserk, NULL + }, + { + SPL_FRIGHTEN, "frighten", + (spell_f)sp_frighten, NULL + }, + { + SPL_OBJ_ANALYSESONG, "analyse_object", + (spell_f)sp_analysesong_obj, NULL + }, + { + SPL_CERDDOR_DESTROY_MAGIC, "cerddor_destroymagic", + (spell_f)sp_destroy_magic, NULL + }, + { + SPL_MIGRANT, "migration", + (spell_f)sp_migranten, NULL + }, + { + SPL_CERDDOR_FAMILIAR, "summon_familiar", + (spell_f)sp_summon_familiar, NULL + }, + { + SPL_RAISEPEASANTS, "raise_mob", + (spell_f)sp_raisepeasants, NULL + }, + { + SPL_SONG_RESISTMAGIC, "song_resist_magic", + (spell_f)sp_song_resistmagic, NULL + }, + { + SPL_DEPRESSION, "melancholy", + (spell_f)sp_depression, NULL + }, + { + SPL_SONG_SUSCEPTMAGIC, "song_suscept_magic", + (spell_f)sp_song_susceptmagic, NULL + }, + { + SPL_SONG_OF_PEACE, "song_of_peace", + (spell_f)sp_song_of_peace, NULL + }, + { + SPL_SONG_OF_ENSLAVE, "song_of_slavery", + (spell_f)sp_charmingsong, NULL + }, + { + SPL_BIGRECRUIT, "big_recruit", + (spell_f)sp_bigrecruit, NULL + }, + { + SPL_RALLYPEASANTMOB, "calm_riot", + (spell_f)sp_rallypeasantmob, NULL + }, + { + SPL_RAISEPEASANTMOB, "incite_riot", + (spell_f)sp_raisepeasantmob, NULL + }, + /* M_TYBIED */ + { + SPL_ANALYSEMAGIC, "analyze_magic", + (spell_f)sp_analysemagic, NULL + }, + { + SPL_ITEMCLOAK, "concealing_aura", + (spell_f)sp_itemcloak, NULL + }, + { + SPL_TYBIED_FUMBLESHIELD, "tybiedfumbleshield", + (spell_f)sp_fumbleshield, NULL + }, +#ifdef SHOWASTRAL_NOT_BORKED + { + SPL_SHOWASTRAL, "show_astral", + (spell_f)sp_showastral, NULL + }, +#endif + { + SPL_RESISTMAGICBONUS, "resist_magic", + (spell_f)sp_resist_magic_bonus, NULL + }, + { + SPL_KEEPLOOT, "keeploot", + (spell_f)sp_keeploot, NULL + }, + { + SPL_ENTERASTRAL, "enterastral", + (spell_f)sp_enterastral, NULL + }, + { + SPL_LEAVEASTRAL, "leaveastral", + (spell_f)sp_leaveastral, NULL + }, + { + SPL_TRANSFERAURA_ASTRAL, "auratransfer", + (spell_f)sp_transferaura, NULL + }, + { + SPL_SHOCKWAVE, "shockwave", + (spell_f)sp_stun, NULL + }, + { + SPL_ANTIMAGICZONE, "antimagiczone", + (spell_f)sp_antimagiczone, NULL + }, + { + SPL_TYBIED_DESTROY_MAGIC, "destroy_magic", + (spell_f)sp_destroy_magic, NULL + }, + { + SPL_PULLASTRAL, "pull_astral", + (spell_f)sp_pullastral, NULL + }, + + { + SPL_FETCHASTRAL, "fetch_astral", + (spell_f)sp_fetchastral, NULL + }, + { + SPL_STEALAURA, "steal_aura", + (spell_f)sp_stealaura, NULL + }, + { + SPL_FLYING_SHIP, "airship", + (spell_f)sp_flying_ship, NULL + }, + { + SPL_DESTROY_MAGIC, "break_curse", + (spell_f)sp_break_curse, NULL + }, + { + SPL_ETERNIZEWALL, "eternal_walls", + (spell_f)sp_eternizewall, NULL + }, + { + SPL_SCHILDRUNEN, "protective_runes", + (spell_f)sp_magicrunes, NULL + }, + + { + SPL_REDUCESHIELD, "fish_shield", + (spell_f)sp_reduceshield, NULL + }, + { + SPL_SPEED, "combat_speed", + (spell_f)sp_speed, NULL + }, + { + SPL_VIEWREALITY, "view_reality", + (spell_f)sp_viewreality, NULL + }, + { + SPL_SPEED2, "double_time", + (spell_f)sp_speed2, NULL + }, + { + SPL_ARMORSHIELD, "armor_shield", + (spell_f)sp_armorshield, NULL + }, + { + SPL_TYBIED_FAMILIAR, "summon_familiar", + (spell_f)sp_summon_familiar, NULL + }, + { + SPL_MOVECASTLE, "living_rock", + (spell_f)sp_movecastle, NULL + }, + { + SPL_DISRUPTASTRAL, "astral_disruption", + (spell_f)sp_disruptastral, NULL + }, + { + SPL_PERMTRANSFER, "sacrifice_strength", + (spell_f)sp_permtransfer, NULL + }, + /* M_GRAY */ + /* Definitionen von Create_Artefaktspr�chen */ + { + SPL_METEORRAIN, "meteor_rain", + (spell_f)sp_kampfzauber, NULL + }, + { + SPL_BECOMEWYRM, "wyrm_transformation", + (spell_f)sp_becomewyrm, NULL + }, + /* Monsterspr�che */ + { SPL_FIREDRAGONODEM, "fiery_dragonbreath", + (spell_f)sp_dragonodem, NULL + }, + { SPL_DRAGONODEM, "icy_dragonbreath", + (spell_f)sp_dragonodem, NULL + }, + { SPL_WYRMODEM, "powerful_dragonbreath", + (spell_f)sp_dragonodem, NULL + }, + { SPL_DRAINODEM, "drain_skills", + (spell_f)sp_dragonodem, NULL + }, + { + SPL_AURA_OF_FEAR, "aura_of_fear", + (spell_f)sp_flee, NULL + }, + { + SPL_SHADOWCALL, "shadowcall", + (spell_f)sp_shadowcall, NULL + }, + { + SPL_IMMOLATION, "immolation", + (spell_f)sp_immolation, NULL + }, + { SPL_FIREODEM, "firestorm", + (spell_f)sp_immolation, NULL + }, + { SPL_ICEODEM, "coldfront", + (spell_f)sp_immolation, NULL + }, + { SPL_ACIDODEM, "acidrain", + (spell_f)sp_immolation, NULL + }, + /* SPL_NOSPELL MUSS der letzte Spruch der Liste sein*/ + { + SPL_NOSPELL, "no spell", + NULL, NULL + } +}; + +static boolean +chaosgate_valid(const connection * b) +{ + const attrib * a = a_findc(b->from->attribs, &at_direction); + if (!a) a = a_findc(b->to->attribs, &at_direction); + if (!a) return false; + return true; +} + +struct region * +chaosgate_move(const connection * b, struct unit * u, struct region * from, struct region * to, boolean routing) +{ + if (!routing) { + int maxhp = u->hp / 4; + if (maxhp<u->number) maxhp = u->number; + u->hp = maxhp; + } + return to; +} + +border_type bt_chaosgate = { + "chaosgate", VAR_NONE, + b_transparent, /* transparent */ + NULL, /* init */ + NULL, /* destroy */ + NULL, /* read */ + NULL, /* write */ + b_blocknone, /* block */ + NULL, /* name */ + b_rinvisible, /* rvisible */ + b_finvisible, /* fvisible */ + b_uinvisible, /* uvisible */ + chaosgate_valid, + chaosgate_move +}; + +static void +set_spelldata_i(spell * sp, spelldata * data) +{ + sp->sp_function = data->sp_function; + sp->patzer = data->patzer; +} + +void +set_spelldata(spell * sp) +{ + int i; + for (i=0;spelldaten[i].id!=SPL_NOSPELL;++i) { + spelldata * data = spelldaten+i; + if (strcmp(data->sname, sp->sname)==0) { + set_spelldata_i(sp, data); + return; + } + } + log_error(("unknown spell %s.\n", sp->sname)); + assert(!"there is no spell by that name"); +} + +/* ------------------------------------------------------------- */ +/* Name: Plappermaul +* Stufe: 4 +* Gebiet: Cerddor +* Kategorie: Einheit +* +* Wirkung: +* Einheit ausspionieren. Gibt auch Zauber und Kampfstatus aus. Wirkt +* gegen Magieresistenz. Ist diese zu hoch, so wird der Zauber entdeckt +* (Meldung) und der Zauberer erh�lt nur die Talente, nicht die Werte +* der Einheit und auch keine Zauber. +* +* Flag: +* (UNITSPELL | TESTCANSEE) +*/ +static int +sp_babbler(castorder *co) +{ + unit *target; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + message * msg; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + target = pa->param[0]->data.u; + + if (target->faction == mage->faction) { + /* Die Einheit ist eine der unsrigen */ + cmistake(mage, co->order, 45, MSG_MAGIC); + } + + /* Magieresistenz Unit */ + if (target_resists_magic(mage, target, TYP_UNIT, 0)) { + spy_message(5, mage, target); + msg = msg_message("babbler_resist", "unit mage", target, mage); + } else { + spy_message(100, mage, target); + msg = msg_message("babbler_effect", "unit", target); + } + r_addmessage(r, target->faction, msg); + msg_release(msg); + return cast_level; +} + +/* ------------------------------------------------------------- */ +/* Name: Traumdeuten +* Stufe: 7 +* Kategorie: Einheit +* +* Wirkung: +* Wirkt gegen Magieresistenz. Spioniert die Einheit aus. Gibt alle +* Gegenst�nde, Talente mit Stufe, Zauber und Kampfstatus an. +* +* Magieresistenz hier pr�fen, wegen Fehlermeldung +* +* Flag: +* (UNITSPELL) +*/ +static int +sp_readmind(castorder *co) +{ + unit *target; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; + + /* wenn kein Ziel gefunden, Zauber abbrechen */ + if (pa->param[0]->flag == TARGET_NOTFOUND) return 0; + + target = pa->param[0]->data.u; + + if (target->faction == mage->faction) { + /* Die Einheit ist eine der unsrigen */ + cmistake(mage, co->order, 45, MSG_MAGIC); + } + + /* Magieresistenz Unit */ + if (target_resists_magic(mage, target, TYP_UNIT, 0)) { + cmistake(mage, co->order, 180, MSG_MAGIC); + /* "F�hlt sich beobachtet"*/ + ADDMSG(&target->faction->msgs, msg_message("stealdetect", "unit", target)); + return 0; + } + spy_message(2, mage, target); + + return cast_level; +} + +void +register_spells(void) +{ + set_spelldata_cb = &set_spelldata; + at_register(&at_wdwpyramid); + at_register(&at_deathcloud_compat); + + /* sp_summon_alp */ + register_alp(); + + /* init_firewall(); */ + ct_register(&ct_firewall); + ct_register(&ct_deathcloud); + + register_function((pf_generic)&sp_blessedharvest, "cast_blessedharvest"); + register_function((pf_generic)&sp_wdwpyramid, "wdwpyramid"); + register_function((pf_generic)&sp_summon_familiar, "cast_familiar"); + register_function((pf_generic)&sp_babbler, "cast_babbler"); + register_function((pf_generic)&sp_readmind, "cast_readmind"); +} diff --git a/src/spells/spells.h b/src/spells/spells.h index 07a603e73..1ab4471b2 100644 --- a/src/spells/spells.h +++ b/src/spells/spells.h @@ -1,32 +1,32 @@ -/* vi: set ts=2: - * - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#ifndef H_SPL_SPELLS -#define H_SPL_SPELLS -#ifdef __cplusplus -extern "C" { -#endif - - struct ship; - struct curse; - struct unit; - - extern void register_spells(void); - - void set_spelldata(struct spell * sp); - -#ifdef __cplusplus -} -#endif -#endif +/* vi: set ts=2: + * + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#ifndef H_SPL_SPELLS +#define H_SPL_SPELLS +#ifdef __cplusplus +extern "C" { +#endif + + struct ship; + struct curse; + struct unit; + + extern void register_spells(void); + + void set_spelldata(struct spell * sp); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/spells/unitcurse.c b/src/spells/unitcurse.c index b3b5fc4fc..240afd61d 100644 --- a/src/spells/unitcurse.c +++ b/src/spells/unitcurse.c @@ -1,363 +1,363 @@ -/* vi: set ts=2: - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#include <platform.h> -#include <kernel/config.h> -#include "unitcurse.h" - -/* kernel includes */ -#include <kernel/curse.h> -#include <kernel/message.h> -#include <kernel/race.h> -#include <kernel/skill.h> -#include <kernel/unit.h> -#include <kernel/faction.h> -#include <kernel/objtypes.h> -#include <kernel/version.h> - -/* util includes */ -#include <util/language.h> -#include <util/nrmessage.h> -#include <util/message.h> -#include <util/base36.h> -#include <util/functions.h> -#include <util/storage.h> - -/* libc includes */ -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -/* ------------------------------------------------------------- */ -/* - * C_AURA - */ -/* erh�ht/senkt regeneration und maxaura um effect% */ -static message * -cinfo_auraboost(const void * obj, typ_t typ, const curse *c, int self) -{ - struct unit *u = (struct unit *)obj; - unused(typ); - assert(typ == TYP_UNIT); - - if (self != 0){ - if (curse_geteffect(c) > 100){ - return msg_message("curseinfo::auraboost_0", "unit id", u, c->no); - } else { - return msg_message("curseinfo::auraboost_1", "unit id", u, c->no); - } - } - return NULL; -} -static struct curse_type ct_auraboost = { - "auraboost", - CURSETYP_NORM, CURSE_SPREADMODULO, (NO_MERGE), - cinfo_auraboost -}; - -/* Magic Boost - Gabe des Chaos */ -static struct curse_type ct_magicboost = { - "magicboost", - CURSETYP_UNIT, CURSE_SPREADMODULO|CURSE_IMMUNE, M_MEN, cinfo_simple -}; - -/* ------------------------------------------------------------- */ -/* - * C_SLAVE - */ -static message * -cinfo_slave(const void * obj, typ_t typ, const curse *c, int self) -{ - unit *u; - unused(typ); - - assert(typ == TYP_UNIT); - u = (unit *)obj; - - if (self != 0){ - return msg_message("curseinfo::slave_1", "unit duration id", u, c->duration, c->no); - } - return NULL; -} -static struct curse_type ct_slavery = { "slavery", - CURSETYP_NORM, 0, NO_MERGE, - cinfo_slave -}; - -/* ------------------------------------------------------------- */ -/* - * C_CALM - */ -static message * -cinfo_calm(const void * obj, typ_t typ, const curse *c, int self) -{ - unused(typ); - assert(typ == TYP_UNIT); - - if (c->magician && c->magician->faction) { - faction *f = c->magician->faction; - unit *u = (unit *)obj; - - if (f==NULL || self == 0) { - const struct race * rc = u_irace(c->magician); - return msg_message("curseinfo::calm_0", "unit race id", u, rc, c->no); - } - return msg_message("curseinfo::calm_1", "unit faction id", u, f, c->no); - } - return NULL; -} - -static struct curse_type ct_calmmonster = { - "calmmonster", - CURSETYP_NORM, CURSE_SPREADNEVER|CURSE_ONLYONE, NO_MERGE, - cinfo_calm -}; - -/* ------------------------------------------------------------- */ -/* - * C_SPEED - */ -static message * -cinfo_speed(const void * obj, typ_t typ, const curse *c, int self) -{ - unused(typ); - assert(typ == TYP_UNIT); - - if (self != 0){ - unit *u = (unit *)obj; - return msg_message("curseinfo::speed_1", "unit number duration id", u, c->data.i, c->duration, c->no); - } - return NULL; -} -static struct curse_type ct_speed = { - "speed", - CURSETYP_UNIT, CURSE_SPREADNEVER, M_MEN, - cinfo_speed -}; - -/* ------------------------------------------------------------- */ -/* - * C_ORC - */ -message * -cinfo_unit(const void * obj, typ_t typ, const curse *c, int self) -{ - unused(typ); - assert(typ == TYP_UNIT); - - if (self != 0){ - unit * u = (unit *)obj; - return msg_message(mkname("curseinfo", c->type->cname), "unit id", u, c->no); - } - return NULL; -} - -static struct curse_type ct_orcish = { - "orcish", - CURSETYP_UNIT, CURSE_SPREADMODULO|CURSE_ISNEW, M_MEN, - cinfo_unit -}; - -/* ------------------------------------------------------------- */ -/* - * C_KAELTESCHUTZ - */ -static message * -cinfo_kaelteschutz(const void * obj, typ_t typ, const curse *c, int self) -{ - unused(typ); - assert(typ == TYP_UNIT); - - if (self != 0) { - unit * u = (unit *)obj; - return msg_message("curseinfo::warmth_1", "unit number id", u, get_cursedmen(u, c), c->no); - } - return NULL; -} -static struct curse_type ct_insectfur = { - "insectfur", - CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ), - cinfo_kaelteschutz -}; - -/* ------------------------------------------------------------- */ -/* - * C_SPARKLE - */ -static message * -cinfo_sparkle(const void * obj, typ_t typ, const curse *c, int self) -{ - const char * effects[] = { - NULL, /* end grau*/ - "sparkle_1", - "sparkle_2", - NULL, /* end traum */ - "sparkle_3", - "sparkle_4", - NULL, /* end tybied */ - "sparkle_5", - "sparkle_6", - "sparkle_7", - "sparkle_8", - NULL, /* end cerrdor */ - "sparkle_9", - "sparkle_10", - "sparkle_11", - "sparkle_12", - NULL, /* end gwyrrd */ - "sparkle_13", - "sparkle_14", - "sparkle_15", - "sparkle_16", - "sparkle_17", - "sparkle_18", - NULL, /* end draig */ - }; - int m, begin=0, end=0; - unit *u; - unused(typ); - - assert(typ == TYP_UNIT); - u = (unit *)obj; - - if (!c->magician || !c->magician->faction) return NULL; - - for (m=0;m!=c->magician->faction->magiegebiet;++m) { - while (effects[end]!=NULL) ++end; - begin = end+1; - end = begin; - } - - while (effects[end]!=NULL) ++end; - if (end==begin) return NULL; - else { - int index = begin + curse_geteffect_int(c) % (end-begin); - return msg_message(mkname("curseinfo", effects[index]), "unit id", u, c->no); - } -} - -static struct curse_type ct_sparkle = { "sparkle", - CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ), cinfo_sparkle -}; - -/* ------------------------------------------------------------- */ -/* - * C_STRENGTH - */ -static struct curse_type ct_strength = { "strength", - CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_simple -}; - -/* ------------------------------------------------------------- */ -/* - * C_ALLSKILLS (Alp) - */ -static struct curse_type ct_worse = { - "worse", CURSETYP_UNIT, CURSE_SPREADMODULO|CURSE_NOAGE, M_MEN, cinfo_unit -}; - -/* ------------------------------------------------------------- */ - -/* - * C_ITEMCLOAK - */ -static struct curse_type ct_itemcloak = { - "itemcloak", CURSETYP_UNIT, CURSE_SPREADNEVER, M_DURATION, cinfo_unit -}; -/* ------------------------------------------------------------- */ - -static struct curse_type ct_fumble = { - "fumble", CURSETYP_NORM, CURSE_SPREADNEVER|CURSE_ONLYONE, NO_MERGE, cinfo_unit -}; -/* ------------------------------------------------------------- */ - - -static struct curse_type ct_oldrace = { - "oldrace", CURSETYP_NORM, CURSE_SPREADALWAYS, NO_MERGE, NULL -}; - -static struct curse_type ct_magicresistance = { - "magicresistance", CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_simple -}; - - -/* ------------------------------------------------------------- */ -/* - * C_SKILL - */ - -static int -read_skill(struct storage * store, curse * c, void * target) -{ - int skill; - if (store->version<CURSETYPE_VERSION) { - int men; - skill = store->r_int(store); - men = store->r_int(store); - } else { - skill = store->r_int(store); - } - c->data.i = skill; - return 0; -} - -static int -write_skill(struct storage * store, const curse * c, const void * target) -{ - store->w_int(store, c->data.i); - return 0; -} - -static message * -cinfo_skillmod(const void * obj, typ_t typ, const curse *c, int self) -{ - unused(typ); - - if (self != 0) { - unit *u = (unit *)obj; - int sk = c->data.i; - if (c->effect>0) { - return msg_message("curseinfo::skill_1", "unit skill id", u, sk, c->no); - } else if (c->effect<0) { - return msg_message("curseinfo::skill_2", "unit skill id", u, sk, c->no); - } - } - return NULL; -} - -static struct curse_type ct_skillmod = { - "skillmod", CURSETYP_NORM, CURSE_SPREADMODULO, M_MEN, cinfo_skillmod, - NULL, read_skill, write_skill -}; - -/* ------------------------------------------------------------- */ -void -register_unitcurse(void) -{ - ct_register(&ct_auraboost); - ct_register(&ct_magicboost); - ct_register(&ct_slavery); - ct_register(&ct_calmmonster); - ct_register(&ct_speed); - ct_register(&ct_orcish); - ct_register(&ct_insectfur); - ct_register(&ct_sparkle); - ct_register(&ct_strength); - ct_register(&ct_worse); - ct_register(&ct_skillmod); - ct_register(&ct_itemcloak); - ct_register(&ct_fumble); - ct_register(&ct_oldrace); - ct_register(&ct_magicresistance); -} - +/* vi: set ts=2: + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#include <platform.h> +#include <kernel/config.h> +#include "unitcurse.h" + +/* kernel includes */ +#include <kernel/curse.h> +#include <kernel/message.h> +#include <kernel/race.h> +#include <kernel/skill.h> +#include <kernel/unit.h> +#include <kernel/faction.h> +#include <kernel/objtypes.h> +#include <kernel/version.h> + +/* util includes */ +#include <util/language.h> +#include <util/nrmessage.h> +#include <util/message.h> +#include <util/base36.h> +#include <util/functions.h> +#include <util/storage.h> + +/* libc includes */ +#include <string.h> +#include <stdlib.h> +#include <assert.h> + +/* ------------------------------------------------------------- */ +/* + * C_AURA + */ +/* erh�ht/senkt regeneration und maxaura um effect% */ +static message * +cinfo_auraboost(const void * obj, typ_t typ, const curse *c, int self) +{ + struct unit *u = (struct unit *)obj; + unused(typ); + assert(typ == TYP_UNIT); + + if (self != 0){ + if (curse_geteffect(c) > 100){ + return msg_message("curseinfo::auraboost_0", "unit id", u, c->no); + } else { + return msg_message("curseinfo::auraboost_1", "unit id", u, c->no); + } + } + return NULL; +} +static struct curse_type ct_auraboost = { + "auraboost", + CURSETYP_NORM, CURSE_SPREADMODULO, (NO_MERGE), + cinfo_auraboost +}; + +/* Magic Boost - Gabe des Chaos */ +static struct curse_type ct_magicboost = { + "magicboost", + CURSETYP_UNIT, CURSE_SPREADMODULO|CURSE_IMMUNE, M_MEN, cinfo_simple +}; + +/* ------------------------------------------------------------- */ +/* + * C_SLAVE + */ +static message * +cinfo_slave(const void * obj, typ_t typ, const curse *c, int self) +{ + unit *u; + unused(typ); + + assert(typ == TYP_UNIT); + u = (unit *)obj; + + if (self != 0){ + return msg_message("curseinfo::slave_1", "unit duration id", u, c->duration, c->no); + } + return NULL; +} +static struct curse_type ct_slavery = { "slavery", + CURSETYP_NORM, 0, NO_MERGE, + cinfo_slave +}; + +/* ------------------------------------------------------------- */ +/* + * C_CALM + */ +static message * +cinfo_calm(const void * obj, typ_t typ, const curse *c, int self) +{ + unused(typ); + assert(typ == TYP_UNIT); + + if (c->magician && c->magician->faction) { + faction *f = c->magician->faction; + unit *u = (unit *)obj; + + if (f==NULL || self == 0) { + const struct race * rc = u_irace(c->magician); + return msg_message("curseinfo::calm_0", "unit race id", u, rc, c->no); + } + return msg_message("curseinfo::calm_1", "unit faction id", u, f, c->no); + } + return NULL; +} + +static struct curse_type ct_calmmonster = { + "calmmonster", + CURSETYP_NORM, CURSE_SPREADNEVER|CURSE_ONLYONE, NO_MERGE, + cinfo_calm +}; + +/* ------------------------------------------------------------- */ +/* + * C_SPEED + */ +static message * +cinfo_speed(const void * obj, typ_t typ, const curse *c, int self) +{ + unused(typ); + assert(typ == TYP_UNIT); + + if (self != 0){ + unit *u = (unit *)obj; + return msg_message("curseinfo::speed_1", "unit number duration id", u, c->data.i, c->duration, c->no); + } + return NULL; +} +static struct curse_type ct_speed = { + "speed", + CURSETYP_UNIT, CURSE_SPREADNEVER, M_MEN, + cinfo_speed +}; + +/* ------------------------------------------------------------- */ +/* + * C_ORC + */ +message * +cinfo_unit(const void * obj, typ_t typ, const curse *c, int self) +{ + unused(typ); + assert(typ == TYP_UNIT); + + if (self != 0){ + unit * u = (unit *)obj; + return msg_message(mkname("curseinfo", c->type->cname), "unit id", u, c->no); + } + return NULL; +} + +static struct curse_type ct_orcish = { + "orcish", + CURSETYP_UNIT, CURSE_SPREADMODULO|CURSE_ISNEW, M_MEN, + cinfo_unit +}; + +/* ------------------------------------------------------------- */ +/* + * C_KAELTESCHUTZ + */ +static message * +cinfo_kaelteschutz(const void * obj, typ_t typ, const curse *c, int self) +{ + unused(typ); + assert(typ == TYP_UNIT); + + if (self != 0) { + unit * u = (unit *)obj; + return msg_message("curseinfo::warmth_1", "unit number id", u, get_cursedmen(u, c), c->no); + } + return NULL; +} +static struct curse_type ct_insectfur = { + "insectfur", + CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ), + cinfo_kaelteschutz +}; + +/* ------------------------------------------------------------- */ +/* + * C_SPARKLE + */ +static message * +cinfo_sparkle(const void * obj, typ_t typ, const curse *c, int self) +{ + const char * effects[] = { + NULL, /* end grau*/ + "sparkle_1", + "sparkle_2", + NULL, /* end traum */ + "sparkle_3", + "sparkle_4", + NULL, /* end tybied */ + "sparkle_5", + "sparkle_6", + "sparkle_7", + "sparkle_8", + NULL, /* end cerrdor */ + "sparkle_9", + "sparkle_10", + "sparkle_11", + "sparkle_12", + NULL, /* end gwyrrd */ + "sparkle_13", + "sparkle_14", + "sparkle_15", + "sparkle_16", + "sparkle_17", + "sparkle_18", + NULL, /* end draig */ + }; + int m, begin=0, end=0; + unit *u; + unused(typ); + + assert(typ == TYP_UNIT); + u = (unit *)obj; + + if (!c->magician || !c->magician->faction) return NULL; + + for (m=0;m!=c->magician->faction->magiegebiet;++m) { + while (effects[end]!=NULL) ++end; + begin = end+1; + end = begin; + } + + while (effects[end]!=NULL) ++end; + if (end==begin) return NULL; + else { + int index = begin + curse_geteffect_int(c) % (end-begin); + return msg_message(mkname("curseinfo", effects[index]), "unit id", u, c->no); + } +} + +static struct curse_type ct_sparkle = { "sparkle", + CURSETYP_UNIT, CURSE_SPREADMODULO, ( M_MEN | M_DURATION ), cinfo_sparkle +}; + +/* ------------------------------------------------------------- */ +/* + * C_STRENGTH + */ +static struct curse_type ct_strength = { "strength", + CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_simple +}; + +/* ------------------------------------------------------------- */ +/* + * C_ALLSKILLS (Alp) + */ +static struct curse_type ct_worse = { + "worse", CURSETYP_UNIT, CURSE_SPREADMODULO|CURSE_NOAGE, M_MEN, cinfo_unit +}; + +/* ------------------------------------------------------------- */ + +/* + * C_ITEMCLOAK + */ +static struct curse_type ct_itemcloak = { + "itemcloak", CURSETYP_UNIT, CURSE_SPREADNEVER, M_DURATION, cinfo_unit +}; +/* ------------------------------------------------------------- */ + +static struct curse_type ct_fumble = { + "fumble", CURSETYP_NORM, CURSE_SPREADNEVER|CURSE_ONLYONE, NO_MERGE, cinfo_unit +}; +/* ------------------------------------------------------------- */ + + +static struct curse_type ct_oldrace = { + "oldrace", CURSETYP_NORM, CURSE_SPREADALWAYS, NO_MERGE, NULL +}; + +static struct curse_type ct_magicresistance = { + "magicresistance", CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_simple +}; + + +/* ------------------------------------------------------------- */ +/* + * C_SKILL + */ + +static int +read_skill(struct storage * store, curse * c, void * target) +{ + int skill; + if (store->version<CURSETYPE_VERSION) { + int men; + skill = store->r_int(store); + men = store->r_int(store); + } else { + skill = store->r_int(store); + } + c->data.i = skill; + return 0; +} + +static int +write_skill(struct storage * store, const curse * c, const void * target) +{ + store->w_int(store, c->data.i); + return 0; +} + +static message * +cinfo_skillmod(const void * obj, typ_t typ, const curse *c, int self) +{ + unused(typ); + + if (self != 0) { + unit *u = (unit *)obj; + int sk = c->data.i; + if (c->effect>0) { + return msg_message("curseinfo::skill_1", "unit skill id", u, sk, c->no); + } else if (c->effect<0) { + return msg_message("curseinfo::skill_2", "unit skill id", u, sk, c->no); + } + } + return NULL; +} + +static struct curse_type ct_skillmod = { + "skillmod", CURSETYP_NORM, CURSE_SPREADMODULO, M_MEN, cinfo_skillmod, + NULL, read_skill, write_skill +}; + +/* ------------------------------------------------------------- */ +void +register_unitcurse(void) +{ + ct_register(&ct_auraboost); + ct_register(&ct_magicboost); + ct_register(&ct_slavery); + ct_register(&ct_calmmonster); + ct_register(&ct_speed); + ct_register(&ct_orcish); + ct_register(&ct_insectfur); + ct_register(&ct_sparkle); + ct_register(&ct_strength); + ct_register(&ct_worse); + ct_register(&ct_skillmod); + ct_register(&ct_itemcloak); + ct_register(&ct_fumble); + ct_register(&ct_oldrace); + ct_register(&ct_magicresistance); +} + diff --git a/src/spells/unitcurse.h b/src/spells/unitcurse.h index 4ea5b7682..63d1f4da5 100644 --- a/src/spells/unitcurse.h +++ b/src/spells/unitcurse.h @@ -1,29 +1,29 @@ -/* vi: set ts=2: - * - * Eressea PB(E)M host Copyright (C) 1998-2003 - * Christian Schlittchen (corwin@amber.kn-bremen.de) - * Katja Zedel (katze@felidae.kn-bremen.de) - * Henning Peters (faroul@beyond.kn-bremen.de) - * Enno Rehling (enno@eressea.de) - * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) - * - * This program may not be used, modified or distributed without - * prior permission by the authors of Eressea. - */ - -#ifndef _UCURSE_H -#define _UCURSE_H -#ifdef __cplusplus -extern "C" { -#endif - -struct curse; -struct message; -extern struct message * cinfo_unit(const void * obj, typ_t typ, const struct curse *c, int self); - -extern void register_unitcurse(void); - -#ifdef __cplusplus -} -#endif -#endif /* _UCURSE_H */ +/* vi: set ts=2: + * + * Eressea PB(E)M host Copyright (C) 1998-2003 + * Christian Schlittchen (corwin@amber.kn-bremen.de) + * Katja Zedel (katze@felidae.kn-bremen.de) + * Henning Peters (faroul@beyond.kn-bremen.de) + * Enno Rehling (enno@eressea.de) + * Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * This program may not be used, modified or distributed without + * prior permission by the authors of Eressea. + */ + +#ifndef _UCURSE_H +#define _UCURSE_H +#ifdef __cplusplus +extern "C" { +#endif + +struct curse; +struct message; +extern struct message * cinfo_unit(const void * obj, typ_t typ, const struct curse *c, int self); + +extern void register_unitcurse(void); + +#ifdef __cplusplus +} +#endif +#endif /* _UCURSE_H */