diff --git a/src/common/kernel/magic.c b/src/common/kernel/magic.c index f54f5e177..2a39127a4 100644 --- a/src/common/kernel/magic.c +++ b/src/common/kernel/magic.c @@ -365,43 +365,17 @@ void updatespelllist(unit * u) { int max = eff_skill(u, SK_MAGIC, u->region); - int i, sk = max; + int sk = max; + spell * sp; magic_t gebiet = find_magetype(u); + boolean ismonster = u->faction->no==MONSTER_FACTION; - if (u->faction->no==MONSTER_FACTION) return; - - - /* Magier mit keinem bzw M_GRAU bekommen weder Sprüche angezeigt noch - * neue Sprüche in ihre List-of-known-spells. Das sind zb alle alten - * Drachen, die noch den Skill Magie haben */ - /* if (gebiet == M_GRAU) return; */ - - for (i = 0; spelldaten[i].id != SPL_NOSPELL; i++) { - boolean know = getspell(u, spelldaten[i].id); - if (know || (spelldaten[i].magietyp == gebiet && spelldaten[i].level <= sk)) { - if (!know) addspell(u, spelldaten[i].id); - - if (!already_seen(u->faction, spelldaten[i].id)) { - a_add(&u->faction->attribs, - a_new(&at_reportspell))->data.i = spelldaten[i].id; - a_add(&u->faction->attribs, - a_new(&at_seenspell))->data.i = spelldaten[i].id; - } - } - } - /* Nur Orkmagier bekommen den Keuschheitsamulettzauber */ + /* Nur Orkmagier bekommen den Keuschheitsamulettzauber */ if (old_race(u->race) == RC_ORC && !getspell(u, SPL_ARTEFAKT_CHASTITYBELT) && find_spellbyid(SPL_ARTEFAKT_CHASTITYBELT)->level <= max) { - addspell(u,SPL_ARTEFAKT_CHASTITYBELT); - - if (!already_seen(u->faction, spelldaten[i].id)) { - a_add(&u->faction->attribs, - a_new(&at_reportspell))->data.i = SPL_ARTEFAKT_CHASTITYBELT; - a_add(&u->faction->attribs, - a_new(&at_seenspell))->data.i = SPL_ARTEFAKT_CHASTITYBELT; - } + addspell(u, SPL_ARTEFAKT_CHASTITYBELT); } /* Nur Wyrm-Magier bekommen den Wyrmtransformationszauber */ @@ -410,12 +384,6 @@ updatespelllist(unit * u) && find_spellbyid(SPL_BECOMEWYRM)->level <= max) { addspell(u, SPL_BECOMEWYRM); - if (!already_seen(u->faction, spelldaten[i].id)) { - a_add(&u->faction->attribs, - a_new(&at_reportspell))->data.i = SPL_BECOMEWYRM; - a_add(&u->faction->attribs, - a_new(&at_seenspell))->data.i = SPL_BECOMEWYRM; - } } /* Transformierte Wyrm-Magier bekommen Drachenodem */ @@ -424,51 +392,41 @@ updatespelllist(unit * u) switch (urc) { /* keine breaks! Wyrme sollen alle drei Zauber können.*/ case RC_WYRM: - { - if(!getspell(u, SPL_WYRMODEM) && - find_spellbyid(SPL_WYRMODEM)->level <= max) { - - addspell(u, SPL_WYRMODEM); - if (!already_seen(u->faction, spelldaten[i].id)) { - a_add(&u->faction->attribs, - a_new(&at_reportspell))->data.i = SPL_WYRMODEM; - a_add(&u->faction->attribs, - a_new(&at_seenspell))->data.i = SPL_WYRMODEM; - } - } - } + sp = find_spellbyid(SPL_WYRMODEM); + if (sp!=NULL && !getspell(u, sp->id) && sp->level<=max) { + addspell(u, sp->id); + } case RC_DRAGON: - { - if(!getspell(u, SPL_DRAGONODEM) && - find_spellbyid(SPL_DRAGONODEM)->level <= max) { - - addspell(u, SPL_DRAGONODEM); - if (!already_seen(u->faction, spelldaten[i].id)) { - a_add(&u->faction->attribs, - a_new(&at_reportspell))->data.i = SPL_DRAGONODEM; - a_add(&u->faction->attribs, - a_new(&at_seenspell))->data.i = SPL_DRAGONODEM; - } - } - } + sp = find_spellbyid(SPL_DRAGONODEM); + if (sp!=NULL && !getspell(u, sp->id) && sp->level<=max) { + addspell(u, sp->id); + } case RC_FIREDRAGON: - { - if(!getspell(u, SPL_FIREDRAGONODEM) && - find_spellbyid(SPL_FIREDRAGONODEM)->level <= max) { - - addspell(u, SPL_FIREDRAGONODEM); - if (!already_seen(u->faction, spelldaten[i].id)) { - a_add(&u->faction->attribs, - a_new(&at_reportspell))->data.i = SPL_FIREDRAGONODEM; - a_add(&u->faction->attribs, - a_new(&at_seenspell))->data.i = SPL_FIREDRAGONODEM; - } - } - } + sp = find_spellbyid(SPL_FIREDRAGONODEM); + if (sp!=NULL && getspell(u, sp->id) && sp->level<=max) { + addspell(u, sp->id); + } + break; } } - return; + /* Magier mit keinem bzw M_GRAU bekommen weder Sprüche angezeigt noch + * neue Sprüche in ihre List-of-known-spells. Das sind zb alle alten + * Drachen, die noch den Skill Magie haben */ + + for (sp = spelldaten; sp->id != SPL_NOSPELL; ++sp) { + boolean know = getspell(u, sp->id); + + if (know || (gebiet!=M_GRAU && sp->magietyp == gebiet && sp->level <= sk)) { + faction * f = u->faction; + + if (!know) addspell(u, sp->id); + if (!ismonster && !already_seen(u->faction, sp->id)) { + a_add(&f->attribs, a_new(&at_reportspell))->data.i = sp->id; + a_add(&f->attribs, a_new(&at_seenspell))->data.i = sp->id; + } + } + } } /* ------------------------------------------------------------- */ @@ -3173,3 +3131,12 @@ spell_name(const struct spell * sp, const struct locale * lang) } return sp->sname; } + +void +add_spelllist(spell_list ** lspells, spell * sp) +{ + spell_list * entry = malloc(sizeof(spell_list)); + entry->data = sp; + entry->next = *lspells; + *lspells = entry; +} \ No newline at end of file diff --git a/src/common/kernel/magic.h b/src/common/kernel/magic.h index 9d398b05d..65af7ad95 100644 --- a/src/common/kernel/magic.h +++ b/src/common/kernel/magic.h @@ -34,10 +34,6 @@ struct building; #define IRONGOLEM_CRUMBLE 15 /* monatlich Chance zu zerfallen */ #define STONEGOLEM_CRUMBLE 10 /* monatlich Chance zu zerfallen */ -/* ------------------------------------------------------------- */ -typedef struct spell_ptr spell_ptr; -typedef struct castorder castorder; - /* ------------------------------------------------------------- */ /* Spruchparameter * Wir suchen beim Parsen des Befehls erstmal nach lokalen Objekten, @@ -112,6 +108,11 @@ extern const char *magietypen[MAXMAGIETYP]; * - Spruchliste */ +typedef struct spell_ptr { + struct spell_ptr *next; + spellid_t spellid; +} spell_ptr; + typedef struct sc_mage { magic_t magietyp; int spellpoints; @@ -121,14 +122,9 @@ typedef struct sc_mage { int combatspelllevel[MAXCOMBATSPELLS]; int precombataura; /* Merker, wieviel Aura in den Präcombatzauber gegangen ist. Nicht speichern. */ - spell_ptr *spellptr; + struct spell_ptr *spellptr; } sc_mage; -struct spell_ptr { - spell_ptr *next; - spellid_t spellid; -}; - /* ------------------------------------------------------------- */ /* Spruchstukturdefinition: * id: @@ -144,7 +140,23 @@ struct spell_ptr { * */ -/* typedef struct fighter fighter; */ +/* ------------------------------------------------------------- */ +/* Zauberliste */ + + +typedef struct castorder { + struct castorder *next; + void *magician; /* Magier (kann vom Typ struct unit oder fighter sein) */ + struct unit *familiar; /* Vertrauter, gesetzt, wenn der Spruch durch + den Vertrauten gezaubert wird */ + struct spell *sp; /* Spruch */ + int level; /* gewünschte Stufe oder Stufe des Magiers */ + double force; /* Stärke des Zaubers */ + struct region *rt; /* Zielregion des Spruchs */ + int distance; /* Entfernung zur Zielregion */ + char *order; /* Befehl */ + struct spellparameter *par; /* für weitere Parameter */ +} castorder; /* irgendwelche zauber: */ typedef void (*spell_f) (void*); @@ -170,25 +182,12 @@ typedef struct spell { void (*patzer) (castorder*); } spell; +typedef struct spell_list { + struct spell_list * next; + spell * data; +} spell_list; -/* ------------------------------------------------------------- */ -/* Zauberliste */ - - -struct castorder { - castorder *next; - void *magician; /* Magier (kann vom Typ struct unit oder fighter sein) */ - struct unit *familiar; /* Vertrauter, gesetzt, wenn der Spruch durch - den Vertrauten gezaubert wird */ - struct spell *sp; /* Spruch */ - int level; /* gewünschte Stufe oder Stufe des Magiers */ - double force; /* Stärke des Zaubers */ - struct region *rt; /* Zielregion des Spruchs */ - int distance; /* Entfernung zur Zielregion */ - char *order; /* Befehl */ - struct spellparameter *par; /* für weitere Parameter */ -}; - +extern void add_spelllist(spell_list ** lspells, spell * sp); /* ------------------------------------------------------------- */ /* besondere Spruchtypen */ diff --git a/src/common/kernel/race.c b/src/common/kernel/race.c index 3fe7159fb..4f731141d 100644 --- a/src/common/kernel/race.c +++ b/src/common/kernel/race.c @@ -391,7 +391,7 @@ racename(const struct locale *loc, const unit *u, const race * rc) static void oldfamiliars(unit * familiar) { - sc_mage * m; + sc_mage * m = NULL; race_t frt = old_race(familiar->race); switch(frt) { @@ -432,9 +432,6 @@ oldfamiliars(unit * familiar) /* Magie+1, Spionage, Tarnung, Wahrnehmung, Ausdauer */ m = create_mage(familiar, M_GRAU); set_level(familiar, SK_MAGIC, 1); - addspell(familiar, SPL_FLEE); - addspell(familiar, SPL_SLEEP); - addspell(familiar, SPL_FRIGHTEN); m->combatspell[0] = SPL_FLEE; m->combatspell[1] = SPL_SLEEP; break; @@ -452,10 +449,6 @@ oldfamiliars(unit * familiar) set_level(familiar, SK_ENTERTAINMENT, 1); set_level(familiar, SK_OBSERVATION, 1); m = create_mage(familiar, M_GRAU); - addspell(familiar, SPL_SEDUCE); - addspell(familiar, SPL_CALM_MONSTER); - addspell(familiar, SPL_SONG_OF_CONFUSION); - addspell(familiar, SPL_DENYATTACK); m->combatspell[0] = SPL_SONG_OF_CONFUSION; break; case RC_UNICORN: @@ -464,12 +457,6 @@ oldfamiliars(unit * familiar) set_level(familiar, SK_STEALTH, 1); set_level(familiar, SK_OBSERVATION, 1); m = create_mage(familiar, M_GRAU); - addspell(familiar, SPL_RESISTMAGICBONUS); - addspell(familiar, SPL_SONG_OF_PEACE); - addspell(familiar, SPL_CALM_MONSTER); - addspell(familiar, SPL_HERO); - addspell(familiar, SPL_HEALINGSONG); - addspell(familiar, SPL_DENYATTACK); break; case RC_WARG: /* Spi, Tak, Tar, Wahri+2, Aus */ @@ -481,9 +468,6 @@ oldfamiliars(unit * familiar) /* Mag+1, Rei-2, Hie, Sta, Spi, Tar, Wahr, Aus */ set_level(familiar, SK_MAGIC, 1); m = create_mage(familiar, M_GRAU); - addspell(familiar, SPL_STEALAURA); - addspell(familiar, SPL_FRIGHTEN); - addspell(familiar, SPL_SUMMONUNDEAD); break; case RC_IMP: /* Mag+1,Rei-1,Hie,Sta,Spi+1,Tar+1,Wahr+1,Steu+1,Aus*/ @@ -493,7 +477,6 @@ oldfamiliars(unit * familiar) set_level(familiar, SK_OBSERVATION, 1); set_level(familiar, SK_TAXING, 1); m = create_mage(familiar, M_GRAU); - addspell(familiar, SPL_STEALAURA); break; case RC_DREAMCAT: /* Mag+1,Hie,Sta,Spi+1,Tar+1,Wahr+1,Steu+1,Aus*/ @@ -503,16 +486,11 @@ oldfamiliars(unit * familiar) set_level(familiar, SK_OBSERVATION, 1); set_level(familiar, SK_TAXING, 1); m = create_mage(familiar, M_GRAU); - addspell(familiar, SPL_ILL_SHAPESHIFT); - addspell(familiar, SPL_TRANSFERAURA_TRAUM); break; case RC_FEY: /* Mag+1,Rei-1,Hie-1,Sta-1,Spi+2,Tar+5,Wahr+2,Aus */ set_level(familiar, SK_MAGIC, 1); m = create_mage(familiar,M_GRAU); - addspell(familiar, SPL_DENYATTACK); - addspell(familiar, SPL_CALM_MONSTER); - addspell(familiar, SPL_SEDUCE); break; case RC_OWL: /* Spi+1,Tar+1,Wahr+5,Aus */ @@ -535,6 +513,13 @@ oldfamiliars(unit * familiar) m = create_mage(familiar,M_GRAU); break; } + if (m!=NULL) { + spell_list * fspells = familiarspells(familiar->race); + while (fspells!=NULL) { + addspell(familiar, fspells->data->id); + fspells=fspells->next; + } + } } static item * @@ -578,6 +563,7 @@ elf_spoil(const struct race * rc, int size) } return itm; } + static item * demon_spoil(const struct race * rc, int size) { @@ -587,6 +573,7 @@ demon_spoil(const struct race * rc, int size) } return itm; } + static item * goblin_spoil(const struct race * rc, int size) { @@ -988,3 +975,90 @@ register_races(void) sprintf(zBuffer, "%s/races.xml", resourcepath()); xml_register(&xml_races, "eressea races", 0); } + +/** familiars **/ +typedef struct familiar_spells { + struct familiar_spells * next; + spell_list * spells; + const race * familiar_race; +} familiar_spells; + +static familiar_spells * racespells; + +spell_list * +familiarspells(const race * rc) +{ + familiar_spells * fspells = racespells; + while (fspells && rc!=fspells->familiar_race) { + fspells = fspells->next; + } + if (fspells!=NULL) return fspells->spells; + return NULL; +} + +familiar_spells * +mkspells(const race * rc) +{ + familiar_spells * fspells; + + fspells = malloc(sizeof(familiar_spells)); + fspells->next = racespells; + racespells = fspells; + fspells->familiar_race = rc; + fspells->spells = NULL; + return fspells; +} + +void +init_familiarspells(void) +{ + familiar_spells * fspells; + + fspells = mkspells(new_race[RC_PSEUDODRAGON]); + add_spelllist(&fspells->spells, find_spellbyid(SPL_FLEE)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_SLEEP)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_FRIGHTEN)); + + fspells = mkspells(new_race[RC_NYMPH]); + add_spelllist(&fspells->spells, find_spellbyid(SPL_SEDUCE)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_SONG_OF_CONFUSION)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); + + fspells = mkspells(new_race[RC_NYMPH]); + add_spelllist(&fspells->spells, find_spellbyid(SPL_SEDUCE)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_SONG_OF_CONFUSION)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); + + fspells = mkspells(new_race[RC_UNICORN]); + add_spelllist(&fspells->spells, find_spellbyid(SPL_RESISTMAGICBONUS)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_SONG_OF_PEACE)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_HERO)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_HEALINGSONG)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); + + fspells = mkspells(new_race[RC_WRAITH]); + add_spelllist(&fspells->spells, find_spellbyid(SPL_STEALAURA)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_FRIGHTEN)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_SUMMONUNDEAD)); + + fspells = mkspells(new_race[RC_IMP]); + add_spelllist(&fspells->spells, find_spellbyid(SPL_STEALAURA)); + + fspells = mkspells(new_race[RC_DREAMCAT]); + add_spelllist(&fspells->spells, find_spellbyid(SPL_ILL_SHAPESHIFT)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_TRANSFERAURA_TRAUM)); + + fspells = mkspells(new_race[RC_FEY]); + add_spelllist(&fspells->spells, find_spellbyid(SPL_DENYATTACK)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_CALM_MONSTER)); + add_spelllist(&fspells->spells, find_spellbyid(SPL_SEDUCE)); +} + +void +init_races(void) +{ + init_familiarspells(); +} \ No newline at end of file diff --git a/src/common/kernel/race.h b/src/common/kernel/race.h index 0ea6a10db..c0e0f0e05 100644 --- a/src/common/kernel/race.h +++ b/src/common/kernel/race.h @@ -156,7 +156,9 @@ extern const char * racename(const struct locale *lang, const struct unit *u, co extern boolean allowed_dragon(const struct region * src, const struct region * target); extern void register_races(void); +extern void init_races(void); extern boolean r_insectstalled(const struct region *r); +extern spell_list * familiarspells(const struct race * rc); extern const char *race_prefixes[]; diff --git a/src/eressea/eressea-lua.vcproj b/src/eressea/eressea-lua.vcproj index 75300891e..1909ca225 100644 --- a/src/eressea/eressea-lua.vcproj +++ b/src/eressea/eressea-lua.vcproj @@ -314,6 +314,9 @@ DisableLanguageExtensions="FALSE"/> + + +#include +#include "list.h" + +// Atributes includes +#include + +// kernel includes +#include + +// lua includes +#include +#include +#include + +using namespace luabind; + +static const char * +spell_getschool(const spell& sp) +{ + return magietypen[sp.magietyp]; +} + +void +bind_spell(lua_State * L) +{ + module(L)[ + class_("spell") + .def_readonly("name", &spell::sname) + .def_readonly("level", &spell::level) + .def("school", &spell_getschool) + ]; +} diff --git a/src/eressea/lua/unit.cpp b/src/eressea/lua/unit.cpp index 0a34483b0..042ef605e 100644 --- a/src/eressea/lua/unit.cpp +++ b/src/eressea/lua/unit.cpp @@ -1,5 +1,6 @@ #include #include +#include "list.h" // Atributes includes #include @@ -11,6 +12,7 @@ #include #include #include +#include // lua includes #include @@ -19,6 +21,32 @@ using namespace luabind; +class bind_spell_ptr { +public: + static spell_ptr * next(spell_ptr * node) { return node->next; } + static spell * value(spell_ptr * node) { return find_spellbyid(node->spellid); } +}; + +static eressea::list +unit_spells(const unit& u) { + sc_mage * mage = get_mage(&u); + if (mage==NULL) return eressea::list(NULL); + spell_ptr * splist = mage->spellptr; + return eressea::list(splist); +} + +class bind_spell_list { +public: + static spell_list * next(spell_list * node) { return node->next; } + static spell * value(spell_list * node) { return node->data; } +}; + +static eressea::list +unit_familiarspells(const unit& u) { + spell_list * spells = familiarspells(u.race); + return eressea::list(spells); +} + static unit * add_unit(faction * f, region * r) { @@ -135,6 +163,8 @@ bind_unit(lua_State * L) .def("eff_skill", &unit_effskill) .def("set_skill", &unit_setskill) .def("set_racename", &unit_setracename) + .property("spells", &unit_spells, return_stl_iterator) + .property("familiarspells", &unit_familiarspells, return_stl_iterator) .property("number", &unit_getnumber, &unit_setnumber) .property("race", &unit_getrace, &unit_setrace) ]; diff --git a/src/eressea/main.c b/src/eressea/main.c index 1e0509378..b136de4d8 100644 --- a/src/eressea/main.c +++ b/src/eressea/main.c @@ -173,6 +173,7 @@ game_init(void) init_attributes(); init_resources(); init_items(); + init_races(); init_economy(); #if NEW_RESOURCEGROWTH init_rawmaterials(); diff --git a/src/eressea/server.cpp b/src/eressea/server.cpp index 8e6b81842..c13972bf3 100644 --- a/src/eressea/server.cpp +++ b/src/eressea/server.cpp @@ -186,6 +186,7 @@ game_init(void) init_attributes(); init_resources(); + init_races(); init_items(); init_economy(); #if NEW_RESOURCEGROWTH