forked from github/server
mages have spellbooks now
This commit is contained in:
parent
409328a9c2
commit
998549e687
8 changed files with 134 additions and 111 deletions
|
@ -502,22 +502,6 @@ static int tolua_unit_addspell(lua_State * L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void unit_removespell(unit * u, spell * sp)
|
||||
{
|
||||
quicklist **isptr;
|
||||
|
||||
isptr = get_spelllist(get_mage(u), u->faction);
|
||||
ql_set_remove(isptr, sp);
|
||||
}
|
||||
|
||||
static int tolua_unit_removespell(lua_State * L)
|
||||
{
|
||||
unit *self = (unit *) tolua_tousertype(L, 1, 0);
|
||||
spell *sp = (spell *) tolua_tousertype(L, 2, 0);
|
||||
unit_removespell(self, sp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_unit_set_racename(lua_State * L)
|
||||
{
|
||||
unit *self = (unit *) tolua_tousertype(L, 1, 0);
|
||||
|
@ -704,6 +688,7 @@ static int tolua_unit_get_items(lua_State * L)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#ifdef TODO /* spellbooks */
|
||||
static int tolua_unit_get_spells(lua_State * L)
|
||||
{
|
||||
unit *self = (unit *) tolua_tousertype(L, 1, 0);
|
||||
|
@ -720,6 +705,24 @@ static int tolua_unit_get_spells(lua_State * L)
|
|||
return tolua_quicklist_push(L, "spell_list", "spell", slist);
|
||||
}
|
||||
|
||||
static void unit_removespell(unit * u, spell * sp)
|
||||
{
|
||||
quicklist **isptr;
|
||||
|
||||
isptr = get_spelllist(get_mage(u), u->faction);
|
||||
ql_set_remove(isptr, sp);
|
||||
}
|
||||
|
||||
static int tolua_unit_removespell(lua_State * L)
|
||||
{
|
||||
unit *self = (unit *) tolua_tousertype(L, 1, 0);
|
||||
spell *sp = (spell *) tolua_tousertype(L, 2, 0);
|
||||
unit_removespell(self, sp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int tolua_unit_get_orders(lua_State * L)
|
||||
{
|
||||
unit *self = (unit *) tolua_tousertype(L, 1, 0);
|
||||
|
@ -953,7 +956,10 @@ void tolua_unit_open(lua_State * L)
|
|||
tolua_variable(L, TOLUA_CAST "race_name", &tolua_unit_get_racename,
|
||||
&tolua_unit_set_racename);
|
||||
tolua_function(L, TOLUA_CAST "add_spell", &tolua_unit_addspell);
|
||||
#ifdef TODO /* spellbooks */
|
||||
tolua_function(L, TOLUA_CAST "remove_spell", &tolua_unit_removespell);
|
||||
tolua_variable(L, TOLUA_CAST "spells", &tolua_unit_get_spells, 0);
|
||||
#endif
|
||||
tolua_function(L, TOLUA_CAST "cast_spell", &tolua_unit_castspell);
|
||||
|
||||
tolua_variable(L, TOLUA_CAST "magic", &tolua_unit_get_magic,
|
||||
|
@ -966,7 +972,6 @@ void tolua_unit_open(lua_State * L)
|
|||
tolua_unit_set_ship);
|
||||
tolua_variable(L, TOLUA_CAST "region", &tolua_unit_get_region,
|
||||
tolua_unit_set_region);
|
||||
tolua_variable(L, TOLUA_CAST "spells", &tolua_unit_get_spells, 0);
|
||||
tolua_variable(L, TOLUA_CAST "number", &tolua_unit_get_number,
|
||||
tolua_unit_set_number);
|
||||
tolua_variable(L, TOLUA_CAST "race", &tolua_unit_get_race,
|
||||
|
|
|
@ -3737,12 +3737,11 @@ static void update_spells(void)
|
|||
}
|
||||
show_new_spells(f, maxlevel, faction_get_spellbook(f));
|
||||
for (i=0; i!=MAXMAGES && mages[i]; ++i) {
|
||||
sc_mage *mage = get_mage(mages[i]);
|
||||
if (mage && mage->spells) {
|
||||
#ifdef TODO
|
||||
int level = effskill(mages[i], SK_MAGIC);
|
||||
unit * u = mages[i];
|
||||
sc_mage *mage = get_mage(u);
|
||||
if (mage && mage->spellbook) {
|
||||
int level = effskill(u, SK_MAGIC);
|
||||
show_new_spells(f, level, mage->spellbook);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@ void test_equipment(CuTest * tc)
|
|||
|
||||
mage = get_mage(u);
|
||||
CuAssertPtrNotNull(tc, mage);
|
||||
CuAssertPtrNotNull(tc, mage->spells);
|
||||
CuAssertTrue(tc, u_hasspell(mage, sp));
|
||||
CuAssertPtrNotNull(tc, mage->spellbook);
|
||||
CuAssertTrue(tc, u_hasspell(u, sp));
|
||||
}
|
||||
|
||||
CuSuite *get_equipment_suite(void)
|
||||
|
|
|
@ -33,6 +33,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "pool.h"
|
||||
#include "race.h"
|
||||
#include "region.h"
|
||||
#include "save.h"
|
||||
#include "ship.h"
|
||||
#include "skill.h"
|
||||
#include "spell.h"
|
||||
|
@ -200,7 +201,10 @@ static void init_mage(attrib * a)
|
|||
static void free_mage(attrib * a)
|
||||
{
|
||||
sc_mage *mage = (sc_mage *) a->data.v;
|
||||
freelist(mage->spells);
|
||||
if (mage->spellbook) {
|
||||
spellbook_clear(mage->spellbook);
|
||||
free(mage->spellbook);
|
||||
}
|
||||
free(mage);
|
||||
}
|
||||
|
||||
|
@ -286,7 +290,7 @@ static int read_mage(attrib * a, void *owner, struct storage *store)
|
|||
}
|
||||
}
|
||||
}
|
||||
read_spells(&mage->spells, mage->magietyp, store);
|
||||
mage->spellbook = read_spellbook(store);
|
||||
return AT_READ_OK;
|
||||
}
|
||||
|
||||
|
@ -316,7 +320,7 @@ write_mage(const attrib * a, const void *owner, struct storage *store)
|
|||
mage->combatspells[i].sp ? mage->combatspells[i].sp->sname : "none");
|
||||
store->w_int(store, mage->combatspells[i].level);
|
||||
}
|
||||
write_spells(mage->spells, store);
|
||||
write_spellbook(mage->spellbook, store);
|
||||
}
|
||||
|
||||
attrib_type at_mage = {
|
||||
|
@ -391,12 +395,6 @@ attrib_type at_seenspell = {
|
|||
|
||||
#define MAXSPELLS 256
|
||||
|
||||
static boolean has_spell(quicklist * ql, const spell * sp)
|
||||
{
|
||||
int qi;
|
||||
return ql_set_find(&ql, &qi, sp) != 0;
|
||||
}
|
||||
|
||||
static boolean already_seen(const faction * f, const spell * sp)
|
||||
{
|
||||
attrib *a;
|
||||
|
@ -521,9 +519,14 @@ void add_spellname(sc_mage * mage, const spell * sp)
|
|||
}
|
||||
}
|
||||
|
||||
int u_hasspell(const sc_mage *mage, const struct spell *sp)
|
||||
int u_hasspell(const unit *u, const struct spell *sp)
|
||||
{
|
||||
return mage ? has_spell(mage->spells, sp) : 0;
|
||||
spellbook * book = unit_get_spellbook(u);
|
||||
spellbook_entry * sbe = book ? spellbook_get(book, sp) : 0;
|
||||
if (sbe) {
|
||||
return sbe->level<=effskill(u, SK_MAGIC);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
@ -572,7 +575,7 @@ void set_combatspell(unit * u, spell * sp, struct order *ord, int level)
|
|||
cmistake(u, ord, 173, MSG_MAGIC);
|
||||
return;
|
||||
}
|
||||
if (!u_hasspell(mage, sp)) {
|
||||
if (!u_hasspell(u, sp)) {
|
||||
/* Diesen Zauber kennt die Einheit nicht */
|
||||
cmistake(u, ord, 169, MSG_MAGIC);
|
||||
return;
|
||||
|
@ -911,19 +914,12 @@ void pay_spell(unit * u, const spell * sp, int cast_level, int range)
|
|||
*/
|
||||
boolean knowsspell(const region * r, const unit * u, const spell * sp)
|
||||
{
|
||||
sc_mage *mage;
|
||||
/* Ist überhaupt ein gültiger Spruch angegeben? */
|
||||
if (!sp || sp->id == 0) {
|
||||
return false;
|
||||
}
|
||||
/* Magier? */
|
||||
mage = get_mage(u);
|
||||
if (!mage) {
|
||||
log_warning("%s ist kein Magier, versucht aber zu zaubern.\n", unitname(u));
|
||||
return false;
|
||||
}
|
||||
/* steht der Spruch in der Spruchliste? */
|
||||
return u_hasspell(mage, sp)!=0;
|
||||
return u_hasspell(u, sp)!=0;
|
||||
}
|
||||
|
||||
/* Um einen Spruch zu beherrschen, muss der Magier die Stufe des
|
||||
|
@ -2876,8 +2872,7 @@ const char *curse_name(const curse_type * ctype, const struct locale *lang)
|
|||
return LOC(lang, mkname("spell", ctype->cname));
|
||||
}
|
||||
|
||||
spell *unit_getspell(struct unit *u, const char *name,
|
||||
const struct locale * lang)
|
||||
spell *unit_getspell(struct unit *u, const char *name, const struct locale * lang)
|
||||
{
|
||||
sc_mage * mage = get_mage(u);
|
||||
if (mage) {
|
||||
|
@ -2887,40 +2882,37 @@ spell *unit_getspell(struct unit *u, const char *name,
|
|||
if (names->lang==lang) break;
|
||||
}
|
||||
if (!names) {
|
||||
quicklist *ql = mage->spells;
|
||||
int qi;
|
||||
names = (spell_names *)calloc(1, sizeof(spell_names));
|
||||
names->next = mage->spellnames;
|
||||
names->lang = lang;
|
||||
names->tokens = 0;
|
||||
for (qi = 0, ql = mage->spells; ql; ql_advance(&ql, &qi, 1)) {
|
||||
spell *sp = (spell *) ql_get(ql, qi);
|
||||
const char *n = spell_name(sp, lang);
|
||||
if (!n) {
|
||||
log_error("no translation in locae %s for spell $s\n", locale_name(lang), sp->sname);
|
||||
} else {
|
||||
token.v = sp;
|
||||
addtoken(&names->tokens, n, token);
|
||||
spellbook *sb = unit_get_spellbook(u);
|
||||
if (sb) {
|
||||
quicklist * ql;
|
||||
int qi;
|
||||
names = (spell_names *)calloc(1, sizeof(spell_names));
|
||||
names->next = mage->spellnames;
|
||||
names->lang = lang;
|
||||
names->tokens = 0;
|
||||
|
||||
for (qi = 0, ql = sb->spells; ql; ql_advance(&ql, &qi, 1)) {
|
||||
spellbook_entry *sbe = (spellbook_entry *)ql_get(ql, qi);
|
||||
spell *sp = sbe->sp;
|
||||
const char *n = spell_name(sp, lang);
|
||||
if (!n) {
|
||||
log_error("no translation in locale %s for spell %s\n", locale_name(lang), sp->sname);
|
||||
} else {
|
||||
token.v = sp;
|
||||
addtoken(&names->tokens, n, token);
|
||||
}
|
||||
}
|
||||
mage->spellnames = names;
|
||||
}
|
||||
mage->spellnames = names;
|
||||
}
|
||||
|
||||
if (findtoken(names->tokens, name, &token) != E_TOK_NOMATCH) {
|
||||
if (names && findtoken(names->tokens, name, &token) != E_TOK_NOMATCH) {
|
||||
return (spell *) token.v;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct quicklist **get_spelllist(struct sc_mage *mage, struct faction *f)
|
||||
{
|
||||
if (mage) {
|
||||
return &mage->spells;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static critbit_tree cb_spellbooks;
|
||||
|
||||
spellbook * get_spellbook(const char * name)
|
||||
|
|
|
@ -117,7 +117,7 @@ typedef struct sc_mage {
|
|||
int spchange;
|
||||
int spellcount;
|
||||
combatspell combatspells[MAXCOMBATSPELLS];
|
||||
struct quicklist *spells;
|
||||
struct spellbook *spellbook;
|
||||
struct spell_names * spellnames;
|
||||
} sc_mage;
|
||||
|
||||
|
@ -252,7 +252,7 @@ typedef struct sc_mage {
|
|||
/* löscht Kampfzauber */
|
||||
void add_spellname(sc_mage * mage, const struct spell * sp);
|
||||
/* fügt den Spruch mit der Id spellid der Spruchliste der Einheit hinzu. */
|
||||
int u_hasspell(const sc_mage *mage, const struct spell *sp);
|
||||
int u_hasspell(const struct unit *u, const struct spell *sp);
|
||||
/* prüft, ob der Spruch in der Spruchliste der Einheit steht. */
|
||||
void pick_random_spells(struct faction *f, int level, struct spellbook * book, int num_spells);
|
||||
void show_new_spells(struct faction * f, int level, const struct spellbook *book);
|
||||
|
@ -360,8 +360,6 @@ typedef struct sc_mage {
|
|||
extern struct message *msg_unitnotfound(const struct unit *mage,
|
||||
struct order *ord, const struct spllprm *spobj);
|
||||
extern int FactionSpells(void);
|
||||
extern struct quicklist **get_spelllist(struct sc_mage *mage,
|
||||
struct faction *f);
|
||||
|
||||
extern void write_spells(struct quicklist *slist, struct storage *store);
|
||||
extern void read_spells(struct quicklist **slistp, magic_t mtype,
|
||||
|
|
|
@ -348,6 +348,35 @@ void test_set_post_combatspell(CuTest * tc)
|
|||
CuAssertPtrEquals(tc, 0, (spell *)get_combatspell(u, index));
|
||||
}
|
||||
|
||||
void test_hasspell(CuTest * tc)
|
||||
{
|
||||
spell *sp;
|
||||
struct unit * u;
|
||||
struct faction * f;
|
||||
struct region * r;
|
||||
|
||||
test_cleanup();
|
||||
test_create_world();
|
||||
r = findregion(0, 0);
|
||||
f = test_create_faction(0);
|
||||
f->magiegebiet = M_TYBIED;
|
||||
u = test_create_unit(f, r);
|
||||
skill_enabled[SK_MAGIC] = 1;
|
||||
sp = create_spell("testspell", 0);
|
||||
sp->sptyp |= POSTCOMBATSPELL;
|
||||
|
||||
unit_add_spell(u, 0, sp, 2);
|
||||
|
||||
set_level(u, SK_MAGIC, 1);
|
||||
CuAssertTrue(tc, !u_hasspell(u, sp));
|
||||
|
||||
set_level(u, SK_MAGIC, 2);
|
||||
CuAssertTrue(tc, u_hasspell(u, sp));
|
||||
|
||||
set_level(u, SK_MAGIC, 1);
|
||||
CuAssertTrue(tc, !u_hasspell(u, sp));
|
||||
}
|
||||
|
||||
CuSuite *get_magic_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
@ -361,5 +390,6 @@ CuSuite *get_magic_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_set_pre_combatspell);
|
||||
SUITE_ADD_TEST(suite, test_set_main_combatspell);
|
||||
SUITE_ADD_TEST(suite, test_set_post_combatspell);
|
||||
SUITE_ADD_TEST(suite, test_hasspell);
|
||||
return suite;
|
||||
}
|
||||
|
|
|
@ -221,7 +221,7 @@ static struct skillmods *init_skills(const race * rc)
|
|||
|
||||
int rc_skillmod(const struct race *rc, const region * r, skill_t sk)
|
||||
{
|
||||
int mods;
|
||||
int mods = 0;
|
||||
|
||||
if (!skill_enabled[sk]) {
|
||||
return 0;
|
||||
|
@ -237,19 +237,15 @@ int rc_skillmod(const struct race *rc, const region * r, skill_t sk)
|
|||
}
|
||||
mods = (*imods)->mod[rterrain(r)].value[sk];
|
||||
#else
|
||||
mods = skill_mod(rc, sk, r->terrain);
|
||||
if (r) {
|
||||
mods = skill_mod(rc, sk, r->terrain);
|
||||
}
|
||||
#endif
|
||||
if (rc == new_race[RC_ELF] && r_isforest(r)) {
|
||||
if (sk == SK_PERCEPTION) {
|
||||
if (rc == new_race[RC_ELF] && r && r_isforest(r)) {
|
||||
if (sk == SK_PERCEPTION || sk == SK_STEALTH) {
|
||||
++mods;
|
||||
} else if (sk == SK_STEALTH) {
|
||||
if (r_isforest(r)) {
|
||||
++mods;
|
||||
}
|
||||
} else if (sk == SK_TACTICS) {
|
||||
if (r_isforest(r)) {
|
||||
mods += 2;
|
||||
}
|
||||
mods += 2;
|
||||
}
|
||||
}
|
||||
return mods;
|
||||
|
|
|
@ -31,6 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "race.h"
|
||||
#include "region.h"
|
||||
#include "spell.h"
|
||||
#include "spellbook.h"
|
||||
#include "save.h"
|
||||
#include "ship.h"
|
||||
#include "skill.h"
|
||||
|
@ -1219,8 +1220,6 @@ static int item_modification(const unit * u, skill_t sk, int val)
|
|||
|
||||
static int att_modification(const unit * u, skill_t sk)
|
||||
{
|
||||
double bonus = 0, malus = 0;
|
||||
attrib *a;
|
||||
double result = 0;
|
||||
static boolean init = false;
|
||||
static const curse_type *skillmod_ct, *gbdream_ct, *worse_ct;
|
||||
|
@ -1251,27 +1250,30 @@ static int att_modification(const unit * u, skill_t sk)
|
|||
/* TODO hier kann nicht mit get/iscursed gearbeitet werden, da nur der
|
||||
* jeweils erste vom Typ C_GBDREAM zurückgegen wird, wir aber alle
|
||||
* durchsuchen und aufaddieren müssen */
|
||||
a = a_find(u->region->attribs, &at_curse);
|
||||
while (a && a->type == &at_curse) {
|
||||
curse *c = (curse *) a->data.v;
|
||||
if (curse_active(c) && c->type == gbdream_ct) {
|
||||
double mod = curse_geteffect(c);
|
||||
unit *mage = c->magician;
|
||||
/* wir suchen jeweils den größten Bonus und den größten Malus */
|
||||
if (mod > bonus) {
|
||||
if (mage == NULL || mage->number == 0
|
||||
|| alliedunit(mage, u->faction, HELP_GUARD)) {
|
||||
bonus = mod;
|
||||
}
|
||||
} else if (mod < malus) {
|
||||
if (mage == NULL || !alliedunit(mage, u->faction, HELP_GUARD)) {
|
||||
malus = mod;
|
||||
if (u->region) {
|
||||
double bonus = 0, malus = 0;
|
||||
attrib *a = a_find(u->region->attribs, &at_curse);
|
||||
while (a && a->type == &at_curse) {
|
||||
curse *c = (curse *) a->data.v;
|
||||
if (curse_active(c) && c->type == gbdream_ct) {
|
||||
double mod = curse_geteffect(c);
|
||||
unit *mage = c->magician;
|
||||
/* wir suchen jeweils den größten Bonus und den größten Malus */
|
||||
if (mod > bonus) {
|
||||
if (mage == NULL || mage->number == 0
|
||||
|| alliedunit(mage, u->faction, HELP_GUARD)) {
|
||||
bonus = mod;
|
||||
}
|
||||
} else if (mod < malus) {
|
||||
if (mage == NULL || !alliedunit(mage, u->faction, HELP_GUARD)) {
|
||||
malus = mod;
|
||||
}
|
||||
}
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
a = a->next;
|
||||
result = result + bonus + malus;
|
||||
}
|
||||
result = result + bonus + malus;
|
||||
|
||||
return (int)result;
|
||||
}
|
||||
|
@ -1283,11 +1285,11 @@ get_modifier(const unit * u, skill_t sk, int level, const region * r,
|
|||
int bskill = level;
|
||||
int skill = bskill;
|
||||
|
||||
assert(r);
|
||||
if (sk == SK_STEALTH) {
|
||||
if (r && sk == SK_STEALTH) {
|
||||
plane *pl = rplane(r);
|
||||
if (pl && fval(pl, PFL_NOSTEALTH))
|
||||
if (pl && fval(pl, PFL_NOSTEALTH)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
skill += rc_skillmod(u->race, r, sk);
|
||||
|
@ -1734,7 +1736,10 @@ void unit_add_spell(unit * u, sc_mage * m, struct spell * sp, int level)
|
|||
log_debug("adding new spell %s to a previously non-mage unit %s\n", sp->sname, unitname(u));
|
||||
mage = create_mage(u, u->faction?u->faction->magiegebiet:M_GRAY);
|
||||
}
|
||||
add_spell(&mage->spells, sp);
|
||||
if (!mage->spellbook) {
|
||||
mage->spellbook = create_spellbook(0);
|
||||
}
|
||||
spellbook_add(mage->spellbook, sp, level);
|
||||
add_spellname(mage, sp);
|
||||
}
|
||||
|
||||
|
@ -1742,10 +1747,8 @@ struct spellbook * unit_get_spellbook(const struct unit * u)
|
|||
{
|
||||
sc_mage * mage = get_mage(u);
|
||||
if (mage) {
|
||||
if (mage->spells) {
|
||||
#ifdef TODO
|
||||
if (mage->spellbook) {
|
||||
return mage->spellbook;
|
||||
#endif
|
||||
}
|
||||
return faction_get_spellbook(u->faction);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue