2001-01-25 10:37:55 +01:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
*
|
2003-07-29 11:48:03 +02:00
|
|
|
|
* Eressea PB(E)M host Copyright (C) 1998-2003
|
2001-01-25 10:37:55 +01:00
|
|
|
|
* 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-pbem.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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* TODO: enum auf fst_ umstellen. Pointer auf Display-Routine */
|
|
|
|
|
#include <config.h>
|
|
|
|
|
#include "eressea.h"
|
|
|
|
|
#include "karma.h"
|
|
|
|
|
|
|
|
|
|
/* kernel includes */
|
|
|
|
|
#include "unit.h"
|
|
|
|
|
#include "race.h"
|
|
|
|
|
#include "region.h"
|
|
|
|
|
#include "item.h"
|
|
|
|
|
#include "group.h"
|
|
|
|
|
#include "pool.h"
|
|
|
|
|
#include "skill.h"
|
|
|
|
|
#include "faction.h"
|
|
|
|
|
#include "magic.h"
|
|
|
|
|
#include "message.h"
|
|
|
|
|
|
|
|
|
|
/* util includes */
|
|
|
|
|
#include <attrib.h>
|
|
|
|
|
#include <base36.h>
|
|
|
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <math.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
|
|
attrib_type at_faction_special = {
|
|
|
|
|
"faction_special", NULL, NULL, NULL, a_writedefault, a_readdefault
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
age_prayer_timeout(attrib *a) {
|
|
|
|
|
return --a->data.sa[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
attrib_type at_prayer_timeout = {
|
|
|
|
|
"prayer_timeout", NULL, NULL, age_prayer_timeout, a_writedefault, a_readdefault
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
attrib_type at_prayer_effect = {
|
|
|
|
|
"prayer_effect", NULL, NULL, NULL, NULL, NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
attrib_type at_wyrm = {
|
|
|
|
|
"wyrm", NULL, NULL, NULL, a_writedefault, a_readdefault
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
attrib_type at_fshidden = {
|
|
|
|
|
"fshidden", NULL, NULL, NULL, a_writedefault, a_readdefault
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
attrib_type at_jihad = {
|
|
|
|
|
"jihad", NULL, NULL, NULL, a_writedefault, a_readdefault
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct fspecialdata fspecials[MAXFACTIONSPECIALS] = {
|
|
|
|
|
{
|
|
|
|
|
"Regeneration",
|
|
|
|
|
"Personen in einer Partei mit dieser Eigenschaft heilen jeden "
|
|
|
|
|
"Schaden innerhalb einer Woche und zus<75>tzlich in jeder Kampfrunde "
|
|
|
|
|
"HP entsprechend ihres Ausdauer-Talents. Sie ben<65>tigen jedoch 11 "
|
2001-12-10 01:13:39 +01:00
|
|
|
|
"Silber Unterhalt pro Woche.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
1
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{ /* TODO: F<>r alte Parteien zu stark */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"St<EFBFBD>dter",
|
|
|
|
|
"Personen einer Partei mit dieser Eigenschaft lieben die St<53>dte und "
|
|
|
|
|
"verabscheuen das Leben in der freien Natur. Ihr Arbeitlohn ver<65>ndert "
|
|
|
|
|
"sich in Abh<62>ngigkeit vom gr<67><72>ten Geb<65>ude in der Region. Ist es eine "
|
|
|
|
|
"Zitadelle so erhalten sie 2 Silber mehr pro Runde, bei einer Festung "
|
|
|
|
|
"1 Silber mehr. Bei einer Burg bekommen sie den normalen Arbeitslohn, "
|
|
|
|
|
"bei einem Turm 1 Silber, bei einer Befestigung 3 Silber weniger. Gibt "
|
|
|
|
|
"es kein entsprechendes Geb<65>ude in der Region, verringert sich ihr "
|
|
|
|
|
"Arbeitslohn um 5 Silber.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
1
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
2001-03-07 16:00:18 +01:00
|
|
|
|
"Barbar",
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"Einheiten dieser Partei erhalten durch Lernen von Waffentalenten "
|
|
|
|
|
"(Taktik und Reiten z<>hlen nicht dazu!) 40 statt 30 Lerntage. Weitere "
|
2001-12-10 01:13:39 +01:00
|
|
|
|
"Stufen erh<72>hen den Bonus um 5 Lerntage. Die Fokussierung auf das "
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"Kriegerdasein f<>hrt jedoch zu Problemen, andere Talente zu erlernen. "
|
|
|
|
|
"In allen nichtkriegerischen Talenten einschlie<69>lich Magie und Taktik "
|
|
|
|
|
"erhalten sie die entsprechende Anzahl von Lerntagen weniger pro "
|
|
|
|
|
"Lernwoche.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
100
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
/* TODO: Noch nicht so implementiert. */
|
|
|
|
|
{
|
|
|
|
|
"Wyrm",
|
|
|
|
|
"Eine Partei mit dieser Eigenschaft kann einen ihrer Magier mit Hilfe "
|
|
|
|
|
"eines speziellen Zaubers permanent in einen Drachen verwandeln. Der "
|
|
|
|
|
"Drache ist zun<75>chst jung, kann sich jedoch durch Lernen des speziellen "
|
|
|
|
|
"Talents 'Drachenwesen' in einen gr<67><72>eren Drachen verwandeln. Um zu "
|
|
|
|
|
"einem ausgewachsenen Drachen zu werden ben<65>tigt der verwandelte Magier "
|
|
|
|
|
"die Talentstufe 6, um zu einem Wyrm zu werden die Talentstufe 12. "
|
|
|
|
|
"Ein junger Drache ben<65>tigt 1000 Silber Unterhalt pro Woche, ein "
|
|
|
|
|
"ausgewachsener Drache 5000 und ein Wyrm 10000 Silber. Bekommt er "
|
|
|
|
|
"dieses Silber nicht, besteht eine Wahrscheinlichkeit, das er desertiert!",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
100
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
/* TODO: Relativ sinnlose Eigenschaft. */
|
|
|
|
|
{
|
|
|
|
|
"Miliz",
|
|
|
|
|
"Alle Personen dieser Partei beginnen mit 30 Talenttagen in allen "
|
|
|
|
|
"Waffentalenten, in denen ihre Rasse keinen Malus hat. Zus<75>tzliche "
|
|
|
|
|
"Stufen bringen jeweils einen zus<75>tzlichen Talentpunkt.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
100
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{ /* Ohne Schiffsunterhaltskosten schwache Eigenschaft. */
|
|
|
|
|
/* Aufpassen: Tragkraft? */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"Feenreich",
|
|
|
|
|
"Alle Personen dieser Partei wiegen nur noch die H<>lfte ihres normalen "
|
|
|
|
|
"Gewichtes. Die N<>he zum Feenreich macht sie jedoch besonders "
|
|
|
|
|
"anf<EFBFBD>llig gegen Waffen aus Eisen, bei einem Treffer durch eine "
|
|
|
|
|
"solche Waffe nehmen sie einen zus<75>tzlichen Schadenspunkt. Zus<75>tzliche "
|
|
|
|
|
"Stufen dieser Eigenschaft verringern das Gewicht auf 1/3, 1/4, ... und "
|
|
|
|
|
"erh<EFBFBD>hen den Schaden durch Eisenwaffen um einen weiteren Punkt.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
100
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"Administrator",
|
|
|
|
|
"Das Einheitenlimit einer Partei mit dieser Eigenschaft erh<72>ht sich um "
|
2001-03-07 16:00:18 +01:00
|
|
|
|
"400 Einheiten. Leider verschlingt der Verwaltungsaufwand viel Silber, "
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"so dass sich der Unterhalt pro Person um 1 Silberst<73>ck erh<72>ht. Weitere "
|
2001-03-07 16:00:18 +01:00
|
|
|
|
"Stufen der Eigenschaft erh<72>hen das Limit um weitere 400 Einheiten und "
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"den Unterhalt um ein weiteres Silberst<73>ck.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
100
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
/* TODO: Noch nicht so implementiert */
|
|
|
|
|
{
|
|
|
|
|
"Telepath",
|
|
|
|
|
"Der Geist fremder Personen bleibt den Magiern einer Partei mit dieser "
|
|
|
|
|
"Eigenschaft nicht verschlossen. Fremde Einheiten erscheinen im Report "
|
|
|
|
|
"wie eigene Einheiten, mit allen Talentwerten und Gegenst<73>nden. Leider "
|
|
|
|
|
"f<EFBFBD>hrt eine so intensive Besch<63>ftigung mit dem Geistigen zur k<>rperlichen "
|
|
|
|
|
"Verk<EFBFBD>mmerung, und die Partei erh<72>lt -1 auf alle Talente au<61>er "
|
2001-04-01 08:58:45 +02:00
|
|
|
|
"Alchemie, Kr<4B>uterkunde, Magie, Spionage, Tarnung und Wahrnehmung. Wird "
|
|
|
|
|
"diese Eigenschaft ein zweites Mal erworben, so bleibt die Wirkung nicht "
|
|
|
|
|
"auf Magier beschr<68>nkt, sondern alle Einheiten einer Partei k<>nnen "
|
|
|
|
|
"die Talente und Gegenst<73>nde aller fremden Einheiten sehen. Allerdings "
|
|
|
|
|
"gibt es in beiden F<>llen eine Einschr<68>nkung: Die Einheit mu<6D> sich einen "
|
|
|
|
|
"Monat lang auf die psychischen Str<74>me einer Region einstellen, bevor "
|
|
|
|
|
"sie in der Lage ist, die Gedanken der anderen zu lesen.",
|
|
|
|
|
2
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"Amphibium",
|
|
|
|
|
"Einheiten dieser Partei k<>nnen durch Ozeanfelder laufen. Allerdings "
|
|
|
|
|
"nehmen sie 10 Schadenspunkte, wenn sie am Ende einer Woche in einem "
|
|
|
|
|
"Ozeanfeld stehen. Pferde weigern sich, in ein Ozeanfeld zu laufen. "
|
|
|
|
|
"Zus<EFBFBD>tzliche Stufen dieser Eigenschaft reduzieren den Schaden um jeweils "
|
|
|
|
|
"5 Punkte. Achtung: Auf dem Ozean wird kein Schaden regeneriert.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
3
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
/* TODO: negative Eigenschaft */
|
|
|
|
|
{
|
|
|
|
|
"Magokrat",
|
|
|
|
|
"Eine Partei mit dieser Eigenschaft hat eine so hohe magische "
|
2001-12-10 01:13:39 +01:00
|
|
|
|
"Affinit<EFBFBD>t, dass sie pro Stufe der Eigenschaft zwei zus<75>tzlich "
|
|
|
|
|
"Magier ausbilden kann.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
100
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
2001-12-10 01:13:39 +01:00
|
|
|
|
/* TODO: negative Eigenschaft, vergleichsweise schwach */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
"Sappeur",
|
|
|
|
|
"Befestigungen wirken gegen Einheiten einer Partei mit dieser "
|
|
|
|
|
"Eigenschaft nur mit ihrer halben Schutzwirkung (aufgerundet).",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
1
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
/* TODO: Noch nicht implementiert */
|
|
|
|
|
{
|
|
|
|
|
"Springer",
|
|
|
|
|
"Einheiten einer Partei mit dieser Eigenschaft k<>nnen sich mit "
|
|
|
|
|
"Hilfe eines speziellen Befehls <20>ber eine Entfernung von zwei "
|
|
|
|
|
"Regionen teleportieren. Einheiten, die sich so teleportieren, "
|
|
|
|
|
"bleiben jedoch f<>r einige Wochen instabil und k<>nnen sich in "
|
|
|
|
|
"seltenen F<>llen selbst<73>ndig in eine zuf<75>llige Nachbarregion "
|
|
|
|
|
"versetzen. Zus<75>tzliche Stufen erh<72>hen die Reichweite um jeweils "
|
|
|
|
|
"eine Region, erh<72>hen jedoch die Wahrscheinlichkeit eines zuf<75>lligen "
|
|
|
|
|
"Versetzens geringf<67>gig.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
100
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
2001-12-10 01:13:39 +01:00
|
|
|
|
/* Evt. zwei Stufen draus machen */
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"Versteckt",
|
|
|
|
|
"Eine Partei mit dieser Eigenschaft hat die F<>higkeit zu Tarnung "
|
2001-03-07 16:00:18 +01:00
|
|
|
|
"zur Perfektion getrieben. Jede Einheit mit mindestens Tarnung 3 "
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"versteckt alle ihre Gegenst<73>nde so, da<64> sie von anderen Parteien "
|
2001-03-07 16:00:18 +01:00
|
|
|
|
"nicht mehr gesehen werden k<>nnen. Jede Einheit mit mindestens Tarnung 6 "
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"schafft es auch, die Zahl der in ihr befindlichen Personen zu verbergen. "
|
|
|
|
|
"Um diese Eigenschaft steuern zu k<>nnen, stehen diesen Parteien die "
|
|
|
|
|
"Befehle TARNE ANZAHL [NICHT] und TARNE GEGENST<53>NDE [NICHT] zur "
|
|
|
|
|
"Verf<EFBFBD>gung.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
1
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
/* TODO: Noch nicht implementiert */
|
|
|
|
|
{
|
|
|
|
|
"Erdelementarist",
|
|
|
|
|
"Alle Geb<65>ude dieser Partei sind von Erdelementaren beseelt und k<>nnen "
|
|
|
|
|
"sich mit Hilfe eines speziellen Befehls jede Woche um eine Region "
|
2002-04-21 09:31:27 +02:00
|
|
|
|
"bewegen. Dies macht es den Bewohnern - welche alle einer Partei mit "
|
|
|
|
|
"dieser Eigenschaft angeh<65>ren m<>ssen - jedoch unm<6E>glich, in dieser "
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"Woche ihren normalen T<>tigkeiten nachzugehen.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
1
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"Magische Immunit<69>t",
|
|
|
|
|
"Eine Partei mit dieser Eigenschaft ist v<>llig immun gegen alle Arten "
|
|
|
|
|
"von Magie. Allerdings verlieren die Magier einer solchen Partei ihre "
|
|
|
|
|
"F<EFBFBD>higkeit, Aura zu regenerieren, v<>llig.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
1
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
/* TODO: Noch nicht implementiert */
|
|
|
|
|
{
|
|
|
|
|
"Vielseitige Magie",
|
|
|
|
|
"Eine Partei mit dieser Eigenschaft kann einen ihrer Magier in einem "
|
|
|
|
|
"anderen als dem Parteimagiegebiet ausbilden. Weitere Stufen erm<72>glichen "
|
|
|
|
|
"jeweils einem weiteren Magier das Lernen eines anderen Gebiets.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
100
|
2001-01-25 10:37:55 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"Jihad",
|
|
|
|
|
"Eine Partei mit dieser Eigenschaft kann eine (Spieler)-Rasse "
|
|
|
|
|
"mit dem speziellen kurzen Befehl JIHAD <RASSE> zum Feind erkl<6B>ren. "
|
|
|
|
|
"Bei einem Kampf gegen einen Angeh<65>rigen dieser Rasse bekommen ihre "
|
2001-12-10 01:13:39 +01:00
|
|
|
|
"K<EFBFBD>mpfer grunds<64>tzlich einen Bonus von +1 auf Angriff und Schaden. "
|
|
|
|
|
"Allerdings kann es zu spontanen Pogromen gegen Angeh<65>rige der mit einem "
|
2001-01-25 10:37:55 +01:00
|
|
|
|
"Jihad belegten Rasse kommen. Wird die Eigenschaft mehrmals erworben "
|
|
|
|
|
"k<EFBFBD>nnen entweder mehrere Rassen mit einem Jihad belegt werden, "
|
|
|
|
|
"oder eine Rasse mehrfach, in diesem Fall addiert sich die Wirkung. "
|
|
|
|
|
"Ein einmal erkl<6B>rter Jihad kann nicht wieder r<>ckg<6B>ngig gemacht "
|
|
|
|
|
"werden.",
|
2001-04-01 08:58:45 +02:00
|
|
|
|
100
|
2001-02-28 19:25:25 +01:00
|
|
|
|
},
|
|
|
|
|
/* TODO: is_undead() und Sonderbehandlungen von Untoten */
|
2001-05-20 09:23:54 +02:00
|
|
|
|
/* in dieser Form ultimative Eigenschaft f<>r Orks */
|
2001-02-28 19:25:25 +01:00
|
|
|
|
{
|
|
|
|
|
"Untot",
|
|
|
|
|
"Personen einer Partei mit dieser Eigenschaft bekommen automatisch doppelt "
|
|
|
|
|
"soviele Trefferpunkte wie normale Angeh<65>rige der entsprechenden Rasse, "
|
|
|
|
|
"verlieren jedoch ihre F<>higkeit zur Regeneration erlittenen Schadens "
|
|
|
|
|
"komplett.",
|
2001-12-10 01:13:39 +01:00
|
|
|
|
1
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
},
|
2001-04-14 14:11:45 +02:00
|
|
|
|
{
|
|
|
|
|
"Windvolk",
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
"Ein solches Volk ist sehr athletisch und die Kinder <20>ben besonders "
|
|
|
|
|
"den Langstreckenlauf von kleinauf. Nach jahrelangem Training sind "
|
|
|
|
|
"sie dann in der Lage, sich zu Fu<46> so schnell zu bewegen als w<>rden "
|
|
|
|
|
"sie reiten. Allerdings hat das jahrelange Konditionstraining ihre "
|
|
|
|
|
"Kr<EFBFBD>fte schwinden lassen, und ihre Tragkraft ist um 2 Gewichtseinheiten "
|
|
|
|
|
"verringert.",
|
|
|
|
|
1
|
2001-12-10 01:13:39 +01:00
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"Gl<EFBFBD>ck",
|
|
|
|
|
"Diese Eigenschaft bewirkt, das der Partei gelegentlich positive "
|
|
|
|
|
"Ereignisse zusto<74>en. Dies k<>nnen spontane Verbesserungen des "
|
|
|
|
|
"Wissensstandes, ein Fund wertvoller Gegenst<73>nde oder <20>hnliches "
|
|
|
|
|
"sein. Je h<>ufiger diese Eigenschaft erworben wird, desto gr<67><72>er die "
|
|
|
|
|
"Wahrscheinlichkeit f<>r solche Ereignisse, und desto postiver ihre "
|
|
|
|
|
"Auswirkungen.",
|
|
|
|
|
100
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
"Lykanthrop",
|
|
|
|
|
"Angeh<EFBFBD>rige einer Partei mit dieser Eigenschaft sind Werwesen. Einheiten "
|
2002-04-12 14:46:16 +02:00
|
|
|
|
"einer solchen Partei k<>nnen sich mit Hilfe der langen Befehle 'WERWESEN' und "
|
2001-12-10 01:13:39 +01:00
|
|
|
|
"'WERWESEN NICHT' in eine andere Form verwandeln. Beide Befehle haben "
|
2002-04-12 14:46:16 +02:00
|
|
|
|
"nur eine gewisse Erfolgswahrscheinlichkeit und funktionieren nicht immer: "
|
|
|
|
|
"Je h<>her die Stufe der Eigenschaft, desto gr<67><72>er die Wahrscheinlichkeit, "
|
|
|
|
|
"dass die Verwandlung gelingt, und je geringer die Chance, sich "
|
|
|
|
|
"zur<EFBFBD>ckzuverwandeln. Zudem besteht eine zunehmende kleine Chance der "
|
|
|
|
|
"spontanen Verwandlung. In Werform erhalten die Einheiten einen Bonus auf "
|
|
|
|
|
"Angriff, Schaden und nat<61>rliche R<>stung in H<>he der Eigenschaft. Sie "
|
|
|
|
|
"benutzen jedoch keine Pferde im Kampf, und verwenden als R<>stungen nur "
|
|
|
|
|
"Schilde. Sie sind eingeschr<68>nkt und k<>nnen in Werform kein Geld verdienen, "
|
|
|
|
|
"nicht Zaubern und nicht Lernen oder Lehren.",
|
|
|
|
|
4
|
2001-12-10 01:13:39 +01:00
|
|
|
|
},
|
|
|
|
|
/* TODO: Noch nicht implementiert */
|
|
|
|
|
{
|
|
|
|
|
"Elite",
|
|
|
|
|
"F<EFBFBD>r eine Partei mit dieser Eigenschaft verdoppeln sich alle Boni- und "
|
|
|
|
|
"Mali ihrer Rasse. Ihre Unterhaltskosten erh<72>hen sich auf 12 Silber pro "
|
2002-04-12 14:46:16 +02:00
|
|
|
|
"Runde, ihr Einheitenlimit reduziert sich auf 25%%. Diese Eigenschaft "
|
|
|
|
|
"kann nicht erworben werden, wenn die Partei nach dem Erwerb zuviele "
|
|
|
|
|
"Einheiten h<>tte.",
|
2001-12-10 01:13:39 +01:00
|
|
|
|
1
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
buy_special(unit *u, strlist *S, fspecial_t special)
|
|
|
|
|
{
|
|
|
|
|
int count = 0;
|
|
|
|
|
int cost;
|
|
|
|
|
attrib *a, *a2 = NULL;
|
|
|
|
|
faction *f = u->faction;
|
|
|
|
|
|
|
|
|
|
/* Kosten berechnen */
|
|
|
|
|
|
|
|
|
|
for(a=a_find(f->attribs, &at_faction_special); a; a=a->nexttype) {
|
|
|
|
|
count += a->data.sa[1];
|
|
|
|
|
if(a->data.sa[0] == special) a2 = a;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cost = (int)(100 * pow(3, count));
|
|
|
|
|
|
|
|
|
|
/* Pr<50>fen, ob genug Karma vorhanden. */
|
|
|
|
|
|
|
|
|
|
if(f->karma < cost) {
|
|
|
|
|
cmistake(u, S->s, 250, MSG_EVENT);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Alles ok, attribut geben */
|
|
|
|
|
|
|
|
|
|
if(a2) {
|
2001-04-01 08:58:45 +02:00
|
|
|
|
if(a2->data.sa[1] < fspecials[special].maxlevel) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
a2->data.sa[1]++;
|
|
|
|
|
add_message(&f->msgs, new_message(f,
|
|
|
|
|
"new_fspecial_level%S:special%d:level", special, a2->data.sa[1]));
|
|
|
|
|
} else {
|
|
|
|
|
cmistake(u, S->s, 251, MSG_EVENT);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
a2 = a_add(&f->attribs, a_new(&at_faction_special));
|
|
|
|
|
a2->data.sa[0] = (short)special;
|
|
|
|
|
a2->data.sa[1] = 1;
|
|
|
|
|
add_message(&f->msgs, new_message(f, "new_fspecial%S:special", special));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
fspecial(const faction *f, fspecial_t special)
|
|
|
|
|
{
|
|
|
|
|
attrib *a;
|
|
|
|
|
|
|
|
|
|
for(a=a_find(f->attribs, &at_faction_special); a; a=a->nexttype) {
|
|
|
|
|
if(a->data.sa[0] == special) return a->data.sa[1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
sacrificings(void)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
unit *u;
|
|
|
|
|
|
|
|
|
|
for(r=regions; r; r=r->next) {
|
|
|
|
|
for(u=r->units; u; u=u->next) {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
if(igetkeyword(u->thisorder, u->faction->locale) == K_SACRIFICE) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
int n = 1, karma;
|
2003-06-22 10:38:55 +02:00
|
|
|
|
const char *s = getstrtoken();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
if(s && *s) n = atoi(s);
|
|
|
|
|
if(n <= 0) {
|
|
|
|
|
cmistake(u, u->thisorder, 252, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
switch(findparam(s, u->faction->locale)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
case P_SILVER:
|
|
|
|
|
n = use_pooled(u, r, R_SILVER, n);
|
|
|
|
|
if(n < 10000) {
|
|
|
|
|
cmistake(u, u->thisorder, 51, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
change_resource(u, R_SILVER, n);
|
|
|
|
|
karma = n/10000;
|
|
|
|
|
u->faction->karma += karma;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case P_AURA:
|
|
|
|
|
if(!is_mage(u)) {
|
|
|
|
|
cmistake(u, u->thisorder, 214, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2002-02-15 17:13:30 +01:00
|
|
|
|
if (get_level(u, SK_MAGIC) < 10) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
cmistake(u, u->thisorder, 253, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
n = min(get_spellpoints(u), min(max_spellpoints(u->region, u), n));
|
|
|
|
|
if(n <= 0) {
|
|
|
|
|
cmistake(u, u->thisorder, 254, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
karma = n;
|
|
|
|
|
u->faction->karma += n;
|
|
|
|
|
change_maxspellpoints(u, -n);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
cmistake(u, u->thisorder, 255, MSG_EVENT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
prayers(void)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
unit *u;
|
|
|
|
|
strlist *S;
|
|
|
|
|
|
|
|
|
|
for(r=regions; r; r=r->next) {
|
|
|
|
|
for(u=r->units; u; u=u->next) {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
for(S = u->orders; S; S = S->next) if(igetkeyword(S->s, u->faction->locale) == K_PRAY) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
attrib *a, *a2;
|
|
|
|
|
unit *u2;
|
|
|
|
|
int karma_cost;
|
|
|
|
|
short mult = 1;
|
|
|
|
|
param_t p;
|
2003-06-22 10:38:55 +02:00
|
|
|
|
const char *s = getstrtoken();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
if(findparam(s, u->faction->locale) == P_FOR) s = getstrtoken();
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
p = findparam(s, u->faction->locale);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
switch(p) {
|
|
|
|
|
case P_AURA:
|
2003-01-12 10:33:20 +01:00
|
|
|
|
if(!is_mage(u)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
cmistake(u, S->s, 214, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
case P_AID:
|
|
|
|
|
case P_MERCY:
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
cmistake(u, S->s, 256, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
a = a_find(u->faction->attribs, &at_prayer_timeout);
|
|
|
|
|
if (a) mult = (short)(2 * a->data.sa[1]);
|
|
|
|
|
karma_cost = 10 * mult;
|
|
|
|
|
|
|
|
|
|
if(u->faction->karma < karma_cost) {
|
|
|
|
|
cmistake(u, S->s, 250, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u->faction->karma -= karma_cost;
|
|
|
|
|
|
|
|
|
|
add_message(&u->faction->msgs, new_message(u->faction,
|
|
|
|
|
"pray_success%u:unit",u));
|
|
|
|
|
|
|
|
|
|
switch(p) {
|
|
|
|
|
case P_AURA:
|
|
|
|
|
set_spellpoints(u, max_spellpoints(u->region, u));
|
|
|
|
|
break;
|
|
|
|
|
case P_AID:
|
|
|
|
|
for(u2 = r->units; u2; u2=u2->next) if(u2->faction == u->faction) {
|
|
|
|
|
a2 = a_add(&u->attribs, a_new(&at_prayer_effect));
|
|
|
|
|
a2->data.sa[0] = PR_AID;
|
|
|
|
|
a2->data.sa[1] = 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case P_MERCY:
|
|
|
|
|
for(u2 = r->units; u2; u2=u2->next) if(u2->faction == u->faction) {
|
|
|
|
|
a2 = a_add(&u->attribs, a_new(&at_prayer_effect));
|
|
|
|
|
a2->data.sa[0] = PR_MERCY;
|
|
|
|
|
a2->data.sa[1] = 80;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!a) a = a_add(&u->faction->attribs, a_new(&at_prayer_timeout));
|
|
|
|
|
a->data.sa[0] = (short)(mult * 14);
|
|
|
|
|
a->data.sa[1] = (short)mult;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
set_jihad(void)
|
|
|
|
|
{
|
|
|
|
|
region *r;
|
|
|
|
|
unit *u;
|
|
|
|
|
strlist *S;
|
|
|
|
|
|
|
|
|
|
for(r=regions; r; r=r->next) {
|
|
|
|
|
for(u=r->units; u; u=u->next) {
|
2001-04-16 16:34:19 +02:00
|
|
|
|
for(S = u->orders; S; S=S->next) if(igetkeyword(S->s, u->faction->locale) == K_SETJIHAD) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
faction *f = u->faction;
|
|
|
|
|
int can = fspecial(f, FS_JIHAD);
|
|
|
|
|
int has = 0;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
const race * jrace;
|
|
|
|
|
race_t jrt;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
attrib *a;
|
2003-06-22 10:38:55 +02:00
|
|
|
|
const char *s;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
for(a = a_find(f->attribs, &at_jihad); a; a = a->nexttype) {
|
|
|
|
|
has += a->data.sa[1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(has >= can) {
|
|
|
|
|
cmistake(u, S->s, 280, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
s = getstrtoken();
|
|
|
|
|
if(!s || !*s) {
|
|
|
|
|
cmistake(u, S->s, 281, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
jrace = rc_find(s);
|
|
|
|
|
jrt = old_race(jrace);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (!playerrace(jrace)) {
|
2001-01-25 10:37:55 +01:00
|
|
|
|
cmistake(u, S->s, 282, MSG_EVENT);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2001-04-16 16:34:19 +02:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for(a = a_find(f->attribs, &at_jihad); a; a = a->nexttype) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if (a->data.sa[0] == jrt) break;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(a) {
|
|
|
|
|
a->data.sa[1]++;
|
|
|
|
|
} else {
|
|
|
|
|
a = a_add(&f->attribs, a_new(&at_jihad));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
a->data.sa[0] = (short)jrt;
|
2001-01-25 10:37:55 +01:00
|
|
|
|
a->data.sa[1] = 1;
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
add_message(&f->msgs, msg_message("setjihad",
|
|
|
|
|
"race", jrace));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
2001-12-10 01:13:39 +01:00
|
|
|
|
jihad(faction *f, const race * rc)
|
2001-01-25 10:37:55 +01:00
|
|
|
|
{
|
|
|
|
|
attrib *a;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
race_t jrt = old_race(rc);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
|
|
|
|
for(a = a_find(f->attribs, &at_jihad); a; a = a->nexttype) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
if(a->data.sa[0] == jrt) return a->data.sa[1];
|
2001-01-25 10:37:55 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
jihad_attacks(void)
|
|
|
|
|
{
|
|
|
|
|
faction *f;
|
|
|
|
|
region *r;
|
|
|
|
|
unit *u, *u2;
|
|
|
|
|
strlist *S;
|
|
|
|
|
attrib *a;
|
|
|
|
|
ally *sf, **sfp;
|
2001-04-16 16:34:19 +02:00
|
|
|
|
|
2001-01-25 10:37:55 +01:00
|
|
|
|
for(f=factions; f; f=f->next) if(fspecial(f, FS_JIHAD)) {
|
|
|
|
|
for(r=f->first; r != f->last; r = r->next) if(rand()%1000 <= 1) {
|
|
|
|
|
boolean doit = false;
|
|
|
|
|
|
|
|
|
|
for(u=r->units; u; u=u->next) if(jihad(f, u->race)) {
|
|
|
|
|
doit = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(doit == false) continue;
|
|
|
|
|
|
|
|
|
|
printf("\tPogrom durch %s in %s\n", factionid(f), regionid(r));
|
|
|
|
|
|
|
|
|
|
for(u2 = r->units; u; u=u->next) if(u2->faction == f) {
|
|
|
|
|
for(u=r->units; u; u=u->next) if(jihad(f, u->race)) {
|
|
|
|
|
/* Allianz aufl<66>sen */
|
|
|
|
|
sfp = &u2->faction->allies;
|
|
|
|
|
a = a_find(u2->attribs, &at_group);
|
|
|
|
|
if (a) sfp = &((group*)a->data.v)->allies;
|
|
|
|
|
|
|
|
|
|
for (sf=*sfp; sf; sf = sf->next) {
|
|
|
|
|
if(sf->faction == u->faction) break;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-02 22:36:12 +02:00
|
|
|
|
if (sf) sf->status = sf->status & (HELP_ALL - HELP_FIGHT);
|
2001-01-25 10:37:55 +01:00
|
|
|
|
|
2001-04-16 16:34:19 +02:00
|
|
|
|
sprintf(buf, "%s %s", locale_string(u->faction->locale, keywords[K_ATTACK]), unitid(u));
|
2001-01-25 10:37:55 +01:00
|
|
|
|
S = makestrlist(buf);
|
|
|
|
|
addlist(&u2->orders, S);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-03-07 16:00:18 +01:00
|
|
|
|
|