diff --git a/src/eressea/eressea.vcproj b/src/eressea/eressea.vcproj
index c1a5099dc..554b2ed58 100644
--- a/src/eressea/eressea.vcproj
+++ b/src/eressea/eressea.vcproj
@@ -286,6 +286,46 @@
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -326,6 +366,46 @@
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -406,6 +486,26 @@
/>
+
+
+
+
+
+
+
+
#include
#include
+#include "races/races.h"
#include
#include
@@ -243,6 +244,7 @@ int main(int argc, char ** argv)
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);
diff --git a/src/eressea/src/races/Jamfile b/src/eressea/src/races/Jamfile
new file mode 100644
index 000000000..99eeff83e
--- /dev/null
+++ b/src/eressea/src/races/Jamfile
@@ -0,0 +1,20 @@
+SubDir TOP common 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/eressea/src/races/dragons.c b/src/eressea/src/races/dragons.c
new file mode 100644
index 000000000..f02e4617d
--- /dev/null
+++ b/src/eressea/src/races/dragons.c
@@ -0,0 +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
+#include
+
+/* kernel includes */
+#include
+#include
+
+/* util includes */
+#include
+
+#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/eressea/src/races/illusion.c b/src/eressea/src/races/illusion.c
new file mode 100644
index 000000000..b2b20fb63
--- /dev/null
+++ b/src/eressea/src/races/illusion.c
@@ -0,0 +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
+#include
+
+/* kernel includes */
+#include
+#include
+#include
+
+/* libc includes */
+#include
+#include
+
+#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/eressea/src/races/races.c b/src/eressea/src/races/races.c
new file mode 100644
index 000000000..abf9f5a4b
--- /dev/null
+++ b/src/eressea/src/races/races.c
@@ -0,0 +1,143 @@
+/* vi: set ts=2:
+ * +-------------------+ Christian Schlittchen
+ * | | Enno Rehling
+ * | Eressea PBEM host | Katja Zedel
+ * | (c) 1998 - 2007 |
+ * | | This program may not be used, modified or distributed
+ * +-------------------+ without prior permission by the authors of Eressea.
+ *
+ */
+
+#include
+#include
+#include "races.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+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/eressea/src/races/races.h b/src/eressea/src/races/races.h
new file mode 100644
index 000000000..90c9f78f6
--- /dev/null
+++ b/src/eressea/src/races/races.h
@@ -0,0 +1,25 @@
+/* vi: set ts=2:
+ * +-------------------+ Christian Schlittchen
+ * | | Enno Rehling
+ * | Eressea PBEM host | Katja Zedel
+ * | (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/eressea/src/races/zombies.c b/src/eressea/src/races/zombies.c
new file mode 100644
index 000000000..c908963a0
--- /dev/null
+++ b/src/eressea/src/races/zombies.c
@@ -0,0 +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
+#include
+
+/* kernel includes */
+#include
+#include
+#include
+
+/* util iclude */
+#include
+
+/* libc includes */
+#include
+
+#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/eressea/src/server.c b/src/eressea/src/server.c
index 04103e18b..990687e29 100644
--- a/src/eressea/src/server.c
+++ b/src/eressea/src/server.c
@@ -10,6 +10,12 @@
#include "spells/spells.c"
#include "spells/unitcurse.c"
-#include "main.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"
+