forked from github/server
1. spell_list was pretty much used everywhere in the code, and is now also a quicklist.
2. Cleaned up the bindings for quicklist to Lua.
This commit is contained in:
parent
b28fa19d01
commit
b2d6203cec
20 changed files with 254 additions and 222 deletions
|
@ -15,6 +15,7 @@ without prior permission by the authors of Eressea.
|
|||
#include <kernel/config.h>
|
||||
|
||||
#include <kernel/unit.h>
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/ship.h>
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/region.h>
|
||||
|
|
|
@ -471,19 +471,7 @@ tolua_faction_tostring(lua_State *L)
|
|||
static int tolua_faction_get_spells(lua_State* L)
|
||||
{
|
||||
faction* self = (faction*)tolua_tousertype(L, 1, 0);
|
||||
spell_list * slist = self->spellbook;
|
||||
if (slist) {
|
||||
spell_list ** spell_ptr = (spell_list **)lua_newuserdata(L, sizeof(spell_list *));
|
||||
luaL_getmetatable(L, TOLUA_CAST "spell_list");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*spell_ptr = slist;
|
||||
lua_pushcclosure(L, tolua_spelllist_next, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
return tolua_quicklist_push(L, "spell_list", "spell", self->spellbook);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -43,6 +43,7 @@ without prior permission by the authors of Eressea.
|
|||
#include <util/event.h>
|
||||
#include <util/lists.h>
|
||||
#include <util/log.h>
|
||||
#include <util/quicklist.h>
|
||||
|
||||
#include <lua.h>
|
||||
#include <tolua.h>
|
||||
|
@ -468,9 +469,11 @@ tolua_unit_addnotice(lua_State* L)
|
|||
static void
|
||||
unit_castspell(unit * u, const char * name)
|
||||
{
|
||||
spell_list * slist = spells;
|
||||
while (slist!=NULL) {
|
||||
spell * sp = slist->data;
|
||||
quicklist * ql = spells;
|
||||
int qi;
|
||||
|
||||
for (ql=spells,qi=0;ql;ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
if (strcmp(name, sp->sname)==0) {
|
||||
castorder * co = (castorder*)malloc(sizeof(castorder));
|
||||
co->distance = 0;
|
||||
|
@ -490,7 +493,6 @@ unit_castspell(unit * u, const char * name)
|
|||
}
|
||||
free(co);
|
||||
}
|
||||
slist=slist->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -506,23 +508,12 @@ tolua_unit_castspell(lua_State* L)
|
|||
static void
|
||||
unit_addspell(unit * u, const char * name)
|
||||
{
|
||||
int add = 0;
|
||||
sc_mage * m = get_mage(u);
|
||||
spell_list * slist = spells;
|
||||
spell_list ** starget = NULL;
|
||||
spell * spadd = NULL;
|
||||
while (slist!=NULL) {
|
||||
spell * sp = slist->data;
|
||||
if (strcmp(name, sp->sname)==0) {
|
||||
starget = get_spelllist(m, u->faction);
|
||||
if (m->magietyp==sp->magietyp) spadd = sp;
|
||||
else if (!spadd) spadd = sp;
|
||||
add = 1;
|
||||
}
|
||||
slist=slist->next;
|
||||
}
|
||||
spell * spadd = find_spell(M_NONE, name);
|
||||
|
||||
if (!spadd) log_error(("spell %s could not be found\n", name));
|
||||
else {
|
||||
quicklist ** starget = get_spelllist(m, u->faction);
|
||||
add_spell(starget, spadd);
|
||||
}
|
||||
}
|
||||
|
@ -537,19 +528,12 @@ tolua_unit_addspell(lua_State* L)
|
|||
}
|
||||
|
||||
static void
|
||||
unit_removespell(unit * u, const spell * sp)
|
||||
unit_removespell(unit * u, spell * sp)
|
||||
{
|
||||
spell_list ** isptr;
|
||||
isptr = get_spelllist(get_mage(u), u->faction);
|
||||
quicklist ** isptr;
|
||||
|
||||
while (*isptr && (*isptr)->data != sp) {
|
||||
isptr = &(*isptr)->next;
|
||||
}
|
||||
if (*isptr) {
|
||||
spell_list * sptr = *isptr;
|
||||
*isptr = sptr->next;
|
||||
free(sptr);
|
||||
}
|
||||
isptr = get_spelllist(get_mage(u), u->faction);
|
||||
ql_set_remove(isptr, sp);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -760,23 +744,16 @@ static int tolua_unit_get_spells(lua_State* L)
|
|||
{
|
||||
unit* self = (unit*)tolua_tousertype(L, 1, 0);
|
||||
sc_mage * mage = get_mage(self);
|
||||
quicklist * slist = 0;
|
||||
|
||||
if (mage) {
|
||||
spell_list ** slist = get_spelllist(mage, self->faction);
|
||||
assert(slist);
|
||||
if (slist) {
|
||||
spell_list ** spell_ptr = (spell_list **)lua_newuserdata(L, sizeof(spell_list *));
|
||||
luaL_getmetatable(L, TOLUA_CAST "spell_list");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*spell_ptr = *slist;
|
||||
lua_pushcclosure(L, tolua_spelllist_next, 1);
|
||||
return 1;
|
||||
quicklist ** slist_ptr = get_spelllist(mage, self->faction);
|
||||
if (slist_ptr) {
|
||||
slist = *slist_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
return tolua_quicklist_push(L, "spell_list", "spell", slist);
|
||||
}
|
||||
|
||||
static int tolua_unit_get_orders(lua_State* L)
|
||||
|
|
|
@ -92,7 +92,7 @@ int tolua_orderlist_next(lua_State *L)
|
|||
else return 0; /* no more values to return */
|
||||
}
|
||||
|
||||
int tolua_quicklist_iter(lua_State *L)
|
||||
static int tolua_quicklist_iter(lua_State *L)
|
||||
{
|
||||
quicklist** qlp = (quicklist **)lua_touserdata(L, lua_upvalueindex(1));
|
||||
quicklist* ql = *qlp;
|
||||
|
@ -110,16 +110,21 @@ int tolua_quicklist_iter(lua_State *L)
|
|||
else return 0; /* no more values to return */
|
||||
}
|
||||
|
||||
int tolua_spelllist_next(lua_State *L)
|
||||
int tolua_quicklist_push(struct lua_State *L, const char * list_type, const char * elem_type, struct quicklist * list)
|
||||
{
|
||||
spell_list** spell_ptr = (spell_list **)lua_touserdata(L, lua_upvalueindex(1));
|
||||
spell_list* slist = *spell_ptr;
|
||||
if (slist != NULL) {
|
||||
tolua_pushusertype(L, slist->data, TOLUA_CAST "spell");
|
||||
*spell_ptr = slist->next;
|
||||
return 1;
|
||||
if (list) {
|
||||
quicklist ** qlist_ptr = (quicklist**)lua_newuserdata(L, sizeof(quicklist *));
|
||||
*qlist_ptr = list;
|
||||
|
||||
luaL_getmetatable(L, list_type);
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushnumber(L, 0);
|
||||
lua_pushstring(L, elem_type);
|
||||
lua_pushcclosure(L, tolua_quicklist_iter, 3); /* OBS: this closure has multiple upvalues (list, index, type_name) */
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else return 0; /* no more values to return */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int tolua_itemlist_next(lua_State *L)
|
||||
|
@ -747,18 +752,7 @@ static int
|
|||
tolua_get_alliance_factions(lua_State* L)
|
||||
{
|
||||
alliance * self = (alliance *)tolua_tousertype(L, 1, 0);
|
||||
quicklist ** faction_ptr = (quicklist**)lua_newuserdata(L, sizeof(quicklist *));
|
||||
|
||||
luaL_getmetatable(L, "faction_list");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
lua_pushnumber(L, 0);
|
||||
|
||||
*faction_ptr = self->members;
|
||||
|
||||
lua_pushstring(L, "faction");
|
||||
lua_pushcclosure(L, tolua_quicklist_iter, 3); /* OBS: this closure has multiple upvalues (list, index, type_name) */
|
||||
return 1;
|
||||
return tolua_quicklist_push(L, "faction_list", "faction", self->members);
|
||||
}
|
||||
|
||||
static int tolua_get_alliance_id(lua_State* L)
|
||||
|
@ -794,10 +788,11 @@ tolua_write_spells(lua_State* L)
|
|||
const char * filename = "magic.xml";
|
||||
xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
|
||||
xmlNodePtr root = xmlNewNode(NULL, BAD_CAST "spells");
|
||||
spell_list * splist;
|
||||
quicklist * ql;
|
||||
int qi;
|
||||
|
||||
for (splist=spells; splist; splist=splist->next) {
|
||||
spell * sp = splist->data;
|
||||
for (ql=spells,qi=0;ql;ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
if (sp->sp_function!=fun) {
|
||||
int combat = 0;
|
||||
xmlNodePtr node = xmlNewNode(NULL, BAD_CAST "spell");
|
||||
|
@ -904,19 +899,7 @@ tolua_get_spell_name(lua_State *L)
|
|||
|
||||
static int tolua_get_spells(lua_State* L)
|
||||
{
|
||||
spell_list * slist = spells;
|
||||
if (slist) {
|
||||
spell_list ** spell_ptr = (spell_list **)lua_newuserdata(L, sizeof(spell_list *));
|
||||
luaL_getmetatable(L, "spell_list");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
*spell_ptr = slist;
|
||||
lua_pushcclosure(L, tolua_spelllist_next, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
return tolua_quicklist_push(L, "spell_list", "spell", spells);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -20,6 +20,7 @@ extern "C" {
|
|||
int tolua_spelllist_next(struct lua_State *L);
|
||||
int tolua_itemlist_next(struct lua_State *L);
|
||||
int tolua_orderlist_next(struct lua_State *L);
|
||||
int tolua_quicklist_push(struct lua_State *L, const char * list_type, const char * elem_type, struct quicklist * list);
|
||||
|
||||
int log_lua_error(struct lua_State * L);
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
<ClCompile Include="gamecode\economy.c" />
|
||||
<ClCompile Include="eressea.c" />
|
||||
<ClCompile Include="gamecode\give.c" />
|
||||
<ClCompile Include="gamecode\xmlreport.c" />
|
||||
<ClCompile Include="gmtool.c" />
|
||||
<ClCompile Include="gamecode\items.c" />
|
||||
<ClCompile Include="gamecode\laws.c" />
|
||||
|
@ -119,6 +120,7 @@
|
|||
<ClInclude Include="gamecode\economy.h" />
|
||||
<ClInclude Include="eressea.h" />
|
||||
<ClInclude Include="gamecode\give.h" />
|
||||
<ClInclude Include="gamecode\xmlreport.h" />
|
||||
<ClInclude Include="gmtool.h" />
|
||||
<ClInclude Include="gmtool_structs.h" />
|
||||
<ClInclude Include="gamecode\items.h" />
|
||||
|
|
|
@ -65,6 +65,9 @@
|
|||
<ClCompile Include="gamecode\summary.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gamecode\xmlreport.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="gamecode\archetype.h">
|
||||
|
@ -121,5 +124,8 @@
|
|||
<ClInclude Include="gamecode\summary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gamecode\xmlreport.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -641,12 +641,15 @@ fwriteorder(FILE * F, const struct order * ord, const struct locale * lang, bool
|
|||
fputc('"', F);
|
||||
}
|
||||
|
||||
static void cr_output_spells(FILE * F, spell_list * slist, const faction * f, int maxlevel)
|
||||
static void cr_output_spells(FILE * F, quicklist * slist, const faction * f, int maxlevel)
|
||||
{
|
||||
if (slist) {
|
||||
quicklist * ql;
|
||||
int qi;
|
||||
fprintf(F, "SPRUECHE\n");
|
||||
for (;slist; slist = slist->next) {
|
||||
spell * sp = slist->data;
|
||||
|
||||
for (ql=slist,qi=0;ql;ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
if (sp->level <= maxlevel) {
|
||||
const char * name = add_translation(mkname("spell", sp->sname), spell_name(sp, f->locale));
|
||||
fprintf(F, "\"%s\"\n", name);
|
||||
|
@ -868,7 +871,7 @@ cr_output_unit(FILE * F, const region * r,
|
|||
/* spells */
|
||||
if (is_mage(u)) {
|
||||
sc_mage * mage = get_mage(u);
|
||||
spell_list ** slistp = get_spelllist(mage, u->faction);
|
||||
quicklist ** slistp = get_spelllist(mage, u->faction);
|
||||
int i, maxlevel = effskill(u, SK_MAGIC);
|
||||
|
||||
cr_output_spells(F, *slistp, f, maxlevel);
|
||||
|
|
|
@ -58,6 +58,7 @@ without prior permission by the authors of Eressea.
|
|||
#include <util/goodies.h>
|
||||
#include <util/language.h>
|
||||
#include <util/message.h>
|
||||
#include <util/quicklist.h>
|
||||
#include <util/unicode.h>
|
||||
#include <util/xml.h>
|
||||
|
||||
|
@ -173,13 +174,15 @@ xml_inventory(report_context * ctx, item * items, unit * u)
|
|||
}
|
||||
|
||||
static xmlNodePtr
|
||||
xml_spells(report_context * ctx, spell_list * slist, int maxlevel)
|
||||
xml_spells(report_context * ctx, quicklist * slist, int maxlevel)
|
||||
{
|
||||
xml_context* xct = (xml_context*)ctx->userdata;
|
||||
xmlNodePtr child, node = xmlNewNode(xct->ns_atl, BAD_CAST "spells");
|
||||
quicklist * ql;
|
||||
int qi;
|
||||
|
||||
for (;slist; slist = slist->next) {
|
||||
spell * sp = slist->data;
|
||||
for (ql=slist,qi=0;ql;ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
|
||||
if (sp->level <= maxlevel) {
|
||||
child = xmlAddChild(node, xmlNewNode(xct->ns_atl, BAD_CAST "spell"));
|
||||
|
@ -338,7 +341,7 @@ xml_unit(report_context * ctx, unit * u, int mode)
|
|||
/* spells */
|
||||
if (is_mage(u)) {
|
||||
sc_mage * mage = get_mage(u);
|
||||
spell_list * slist = mage->spells;
|
||||
quicklist * slist = mage->spells;
|
||||
if (slist) {
|
||||
xmlAddChild(node, xml_spells(ctx, slist, effskill(u, SK_MAGIC)));
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <util/lists.h>
|
||||
#include <util/language.h>
|
||||
#include <util/log.h>
|
||||
#include <util/quicklist.h>
|
||||
#include <util/resolve.h>
|
||||
#include <util/rng.h>
|
||||
#include <util/storage.h>
|
||||
|
@ -287,7 +288,7 @@ destroyfaction(faction * f)
|
|||
if (!f->alive) return;
|
||||
fset(f, FFL_QUIT);
|
||||
|
||||
freelist(f->spellbook);
|
||||
ql_free(f->spellbook);
|
||||
f->spellbook = NULL;
|
||||
|
||||
while (f->battles) {
|
||||
|
|
|
@ -73,7 +73,7 @@ typedef struct faction {
|
|||
char *passw;
|
||||
char *override;
|
||||
int max_spelllevel;
|
||||
struct spell_list * spellbook;
|
||||
struct quicklist * spellbook;
|
||||
const struct locale * locale;
|
||||
int lastorders;
|
||||
int age;
|
||||
|
|
|
@ -53,6 +53,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <util/lists.h>
|
||||
#include <util/log.h>
|
||||
#include <util/parser.h>
|
||||
#include <util/quicklist.h>
|
||||
#include <util/resolve.h>
|
||||
#include <util/rand.h>
|
||||
#include <util/rng.h>
|
||||
|
@ -208,7 +209,7 @@ int FactionSpells(void)
|
|||
return rules_factionspells;
|
||||
}
|
||||
|
||||
void read_spellist(struct spell_list ** slistp, magic_t mtype, struct storage * store)
|
||||
void read_spells(struct quicklist ** slistp, magic_t mtype, struct storage * store)
|
||||
{
|
||||
for (;;) {
|
||||
spell * sp;
|
||||
|
@ -269,16 +270,18 @@ read_mage(attrib * a, void * owner, struct storage * store)
|
|||
}
|
||||
}
|
||||
}
|
||||
read_spellist(&mage->spells, mage->magietyp, store);
|
||||
read_spells(&mage->spells, mage->magietyp, store);
|
||||
return AT_READ_OK;
|
||||
}
|
||||
|
||||
void write_spelllist(const spell_list * slist, struct storage * store)
|
||||
void write_spells(struct quicklist * slist, struct storage * store)
|
||||
{
|
||||
while (slist!=NULL) {
|
||||
spell * sp = slist->data;
|
||||
quicklist * ql;
|
||||
int qi;
|
||||
|
||||
for (ql=slist,qi=0;ql;ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
store->w_tok(store, sp->sname);
|
||||
slist = slist->next;
|
||||
}
|
||||
store->w_tok(store, "end");
|
||||
}
|
||||
|
@ -296,7 +299,7 @@ write_mage(const attrib * a, const void * owner, struct storage * store)
|
|||
store->w_tok(store, mage->combatspells[i].sp?mage->combatspells[i].sp->sname:"none");
|
||||
store->w_int(store, mage->combatspells[i].level);
|
||||
}
|
||||
write_spelllist(mage->spells, store);
|
||||
write_spells(mage->spells, store);
|
||||
}
|
||||
|
||||
attrib_type at_mage = {
|
||||
|
@ -404,6 +407,13 @@ static boolean know_school(const faction * f, magic_t school)
|
|||
#define COMMONSPELLS 1 /* number of new common spells per level */
|
||||
#define MAXSPELLS 256
|
||||
|
||||
static boolean
|
||||
has_spell(quicklist * ql, const spell * sp)
|
||||
{
|
||||
int qi;
|
||||
return ql_set_find(&ql, &qi, sp)!=0;
|
||||
}
|
||||
|
||||
/** update the spellbook with a new level
|
||||
* Written for Eressea 1.1
|
||||
*/
|
||||
|
@ -411,18 +421,16 @@ void
|
|||
update_spellbook(faction * f, int level)
|
||||
{
|
||||
spell * commonspells[MAXSPELLS];
|
||||
int numspells = 0;
|
||||
spell_list * slist;
|
||||
int qi, numspells = 0;
|
||||
quicklist * ql;
|
||||
|
||||
for (slist=spells;slist!=NULL;slist=slist->next) {
|
||||
spell * sp = slist->data;
|
||||
for (qi=0,ql=spells;ql;ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
if (sp->magietyp == M_COMMON && level>f->max_spelllevel && sp->level<=level) {
|
||||
commonspells[numspells++] = sp;
|
||||
} else {
|
||||
if (know_school(f, sp->magietyp) && sp->level <= level) {
|
||||
if (!has_spell(f->spellbook, sp)) {
|
||||
add_spell(&f->spellbook, sp);
|
||||
}
|
||||
add_spell(&f->spellbook, sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -442,7 +450,7 @@ update_spellbook(faction * f, int level)
|
|||
while (maxspell>0 && sp && sp->level<=f->max_spelllevel && !has_spell(f->spellbook, sp));
|
||||
|
||||
if (sp) {
|
||||
add_spell(&f->spellbook, sp);
|
||||
ql_set_insert(&f->spellbook, sp);
|
||||
commonspells[spellno] = 0;
|
||||
}
|
||||
}
|
||||
|
@ -454,9 +462,11 @@ void
|
|||
updatespelllist(unit * u)
|
||||
{
|
||||
int sk = eff_skill(u, SK_MAGIC, u->region);
|
||||
spell_list * slist = spells;
|
||||
quicklist * ql = spells;
|
||||
int qi;
|
||||
struct sc_mage * mage = get_mage(u);
|
||||
boolean ismonster = is_monsters(u->faction);
|
||||
quicklist ** dst;
|
||||
|
||||
if (mage->magietyp==M_GRAY) {
|
||||
/* Magier mit M_GRAY bekommen weder Sprüche angezeigt noch
|
||||
|
@ -466,18 +476,19 @@ updatespelllist(unit * u)
|
|||
}
|
||||
|
||||
if (FactionSpells()) {
|
||||
slist = u->faction->spellbook;
|
||||
ql = u->faction->spellbook;
|
||||
}
|
||||
dst = get_spelllist(mage, u->faction);
|
||||
|
||||
for (;slist!=NULL;slist=slist->next) {
|
||||
spell * sp = slist->data;
|
||||
for (qi=0;ql;ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
if (sp->level<=sk) {
|
||||
boolean know = u_hasspell(u, sp);
|
||||
|
||||
if (know || sp->magietyp==M_COMMON || know_school(u->faction, sp->magietyp)) {
|
||||
faction * f = u->faction;
|
||||
|
||||
if (!know) add_spell(get_spelllist(mage, u->faction), sp);
|
||||
if (!know) add_spell(dst, sp);
|
||||
if (!ismonster && !already_seen(u->faction, sp)) {
|
||||
a_add(&f->attribs, a_new(&at_reportspell))->data.v = sp;
|
||||
a_add(&f->attribs, a_new(&at_seenspell))->data.v = sp;
|
||||
|
@ -511,39 +522,24 @@ create_mage(unit * u, magic_t mtyp)
|
|||
/* Funktionen für die Bearbeitung der List-of-known-spells */
|
||||
|
||||
void
|
||||
add_spell(spell_list ** slistp, spell * sp)
|
||||
add_spell(struct quicklist ** slistp, spell * sp)
|
||||
{
|
||||
if (slistp==NULL) {
|
||||
log_error(("add_spell: unit is not a mage.\n"));
|
||||
} else {
|
||||
spell_list ** slist = spelllist_find(slistp, sp);
|
||||
if (*slist) {
|
||||
spell * psp = (*slist)->data;
|
||||
if (psp==sp) {
|
||||
log_error(("add_spell: unit already has spell '%s'.\n", sp->sname));
|
||||
return;
|
||||
}
|
||||
}
|
||||
spelllist_add(slist, sp);
|
||||
}
|
||||
}
|
||||
quicklist * ql = *slistp;
|
||||
int qi;
|
||||
|
||||
boolean
|
||||
has_spell(spell_list * slist, const spell * sp)
|
||||
{
|
||||
if (slist!=NULL) {
|
||||
spell_list * sfind = *spelllist_find(&slist, sp);
|
||||
return sfind!=NULL && sfind->data==sp;
|
||||
if (ql_set_find(&ql, &qi, sp)) {
|
||||
log_error(("add_spell: the list already contains the spell '%s'.\n", sp->sname));
|
||||
} else {
|
||||
ql_set_insert(slistp, sp);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean
|
||||
u_hasspell(const struct unit *u, const struct spell * sp)
|
||||
{
|
||||
sc_mage * mage = get_mage(u);
|
||||
if (mage) return has_spell(mage->spells, sp);
|
||||
return false;
|
||||
|
||||
return (mage)?has_spell(mage->spells, sp):false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
@ -2881,40 +2877,7 @@ curse_name(const curse_type * ctype, const struct locale * lang)
|
|||
return LOC(lang, mkname("spell", ctype->cname));
|
||||
}
|
||||
|
||||
void
|
||||
spelllist_add(spell_list ** lspells, spell * sp)
|
||||
{
|
||||
spell_list * entry;
|
||||
|
||||
while (*lspells) {
|
||||
spell_list * slist = *lspells;
|
||||
if (slist->data->id==sp->id) {
|
||||
if (slist->data==sp) {
|
||||
log_error(("trying to add spell '%s' to a list twice.\n", sp->sname));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (slist->data->id>sp->id) break;
|
||||
lspells = &slist->next;
|
||||
}
|
||||
entry = malloc(sizeof(spell_list));
|
||||
entry->data = sp;
|
||||
entry->next = *lspells;
|
||||
*lspells = entry;
|
||||
}
|
||||
|
||||
spell_list **
|
||||
spelllist_find(spell_list ** lspells, const spell * sp)
|
||||
{
|
||||
while (*lspells) {
|
||||
spell_list * slist = *lspells;
|
||||
if (slist->data->id>=sp->id) break;
|
||||
lspells = &slist->next;
|
||||
}
|
||||
return lspells;
|
||||
}
|
||||
|
||||
extern struct spell_list ** get_spelllist(struct sc_mage * mage, struct faction * f)
|
||||
struct quicklist ** get_spelllist(struct sc_mage * mage, struct faction * f)
|
||||
{
|
||||
if (mage) {
|
||||
return &mage->spells;
|
||||
|
|
|
@ -25,6 +25,7 @@ extern "C" {
|
|||
#include "curse.h"
|
||||
struct fighter;
|
||||
struct building;
|
||||
struct quicklist;
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
|
@ -123,7 +124,7 @@ typedef struct sc_mage {
|
|||
int spchange;
|
||||
int spellcount;
|
||||
combatspell combatspells[MAXCOMBATSPELLS];
|
||||
struct spell_list * spells;
|
||||
struct quicklist * spells;
|
||||
} sc_mage;
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
@ -175,13 +176,6 @@ typedef struct spell {
|
|||
void (*patzer) (castorder*);
|
||||
} spell;
|
||||
|
||||
typedef struct spell_list {
|
||||
struct spell_list * next;
|
||||
spell * data; /* TODO: should be const */
|
||||
} spell_list;
|
||||
|
||||
extern void spelllist_add(spell_list ** lspells, struct spell * sp);
|
||||
extern spell_list ** spelllist_find(spell_list ** lspells, const struct spell * sp);
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
/* besondere Spruchtypen */
|
||||
|
@ -282,10 +276,8 @@ void set_combatspell(struct unit *u, spell *sp, struct order * ord, int level);
|
|||
/* setzt Kampfzauber */
|
||||
void unset_combatspell(struct unit *u, spell *sp);
|
||||
/* löscht Kampfzauber */
|
||||
void add_spell(spell_list ** slistp, spell *sp);
|
||||
void add_spell(struct quicklist ** slistp, spell *sp);
|
||||
/* fügt den Spruch mit der Id spellid der Spruchliste der Einheit hinzu. */
|
||||
boolean has_spell(struct spell_list *slist, const struct spell * sp);
|
||||
/* prüft, ob der Spruch in der Spruchliste der Einheit steht. */
|
||||
boolean u_hasspell(const struct unit * u, const struct spell * sp);
|
||||
/* prüft, ob der Spruch in der Spruchliste der Einheit steht. */
|
||||
void update_spellbook(struct faction * f, int level);
|
||||
|
@ -383,10 +375,10 @@ extern const char * curse_name(const struct curse_type * ctype, const struct loc
|
|||
|
||||
extern struct message * msg_unitnotfound(const struct unit * mage, struct order * ord, const struct spllprm * spobj);
|
||||
extern int FactionSpells(void);
|
||||
extern struct spell_list ** get_spelllist(struct sc_mage * mage, struct faction * f);
|
||||
extern struct quicklist ** get_spelllist(struct sc_mage * mage, struct faction * f);
|
||||
|
||||
extern void write_spelllist(const struct spell_list * slist, struct storage * store);
|
||||
extern void read_spellist(struct spell_list ** slistp, magic_t mtype, struct storage * store);
|
||||
extern void write_spells(struct quicklist * slist, struct storage * store);
|
||||
extern void read_spells(struct quicklist ** slistp, magic_t mtype, struct storage * store);
|
||||
extern double MagicPower(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -622,13 +622,13 @@ bufunit(const faction * f, const unit * u, int indent, int mode, char * buf, siz
|
|||
sc_mage * m = get_mage(u);
|
||||
|
||||
if (m!=NULL) {
|
||||
spell_list *slist = m->spells;
|
||||
int t = effskill(u, SK_MAGIC);
|
||||
quicklist * ql = m->spells;
|
||||
int qi, t = effskill(u, SK_MAGIC);
|
||||
int bytes = snprintf(bufp, size, ". Aura %d/%d", get_spellpoints(u), max_spellpoints(u->region,u));
|
||||
if (bytes<0 || wrptr(&bufp, &size, bytes)!=0) WARN_STATIC_BUFFER();
|
||||
|
||||
for (dh=0; slist; slist=slist->next) {
|
||||
spell * sp = slist->data;
|
||||
for (dh=0,qi=0; ql; ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
if (sp->level > t) continue;
|
||||
if (!dh) {
|
||||
bytes = snprintf(bufp, size, ", %s: ", LOC(f->locale, "nr_spells"));
|
||||
|
|
|
@ -1288,7 +1288,7 @@ readfaction(struct storage * store)
|
|||
read_groups(store, f);
|
||||
f->spellbook = NULL;
|
||||
if (store->version>=REGIONOWNER_VERSION) {
|
||||
read_spellist(&f->spellbook, f->magiegebiet, store);
|
||||
read_spells(&f->spellbook, f->magiegebiet, store);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
@ -1352,7 +1352,7 @@ writefaction(struct storage * store, const faction * f)
|
|||
store->w_id(store, 0);
|
||||
store->w_brk(store);
|
||||
write_groups(store, f->groups);
|
||||
write_spelllist(f->spellbook, store);
|
||||
write_spells(f->spellbook, store);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -33,12 +33,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <util/language.h>
|
||||
#include <util/log.h>
|
||||
#include <util/umlaut.h>
|
||||
#include <util/quicklist.h>
|
||||
|
||||
/* Bitte die Sprüche nach Gebieten und Stufe ordnen, denn in derselben
|
||||
* Reihenfolge wie in Spelldaten tauchen sie auch im Report auf
|
||||
*/
|
||||
|
||||
spell_list * spells = NULL;
|
||||
quicklist * spells = NULL;
|
||||
|
||||
void
|
||||
register_spell(spell * sp)
|
||||
|
@ -46,7 +47,7 @@ register_spell(spell * sp)
|
|||
if (sp->id==0) {
|
||||
sp->id = hashstring(sp->sname);
|
||||
}
|
||||
spelllist_add(&spells, sp);
|
||||
add_spell(&spells, sp);
|
||||
}
|
||||
|
||||
/** versucht einen Spruch über gebiet + name zu identifizieren.
|
||||
|
@ -54,15 +55,16 @@ register_spell(spell * sp)
|
|||
spell *
|
||||
find_spell(magic_t mtype, const char * name)
|
||||
{
|
||||
spell_list * slist = spells;
|
||||
quicklist * ql = spells;
|
||||
int qi;
|
||||
spell * spx = NULL;
|
||||
while (slist) {
|
||||
spell * sp = slist->data;
|
||||
|
||||
for (qi=0;ql;ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
if (strcmp(name, sp->sname)==0) {
|
||||
if (mtype==M_NONE || sp->magietyp==mtype) return sp;
|
||||
spx = sp;
|
||||
}
|
||||
slist = slist->next;
|
||||
}
|
||||
if (spx==NULL) {
|
||||
log_error(("cannot find spell by name: %s\n", name));
|
||||
|
@ -86,13 +88,14 @@ static spell_names * spellnames;
|
|||
static spell_names *
|
||||
init_spellnames(const struct locale * lang, magic_t mtype)
|
||||
{
|
||||
spell_list * slist;
|
||||
spell_names * sn = calloc(sizeof(spell_names), 1);
|
||||
quicklist * ql;
|
||||
int qi;
|
||||
spell_names * sn = (spell_names *)calloc(sizeof(spell_names), 1);
|
||||
sn->next = spellnames;
|
||||
sn->lang = lang;
|
||||
sn->mtype = mtype;
|
||||
for (slist=spells;slist!=NULL;slist=slist->next) {
|
||||
spell * sp = slist->data;
|
||||
for (qi=0,ql=spells;ql;ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
if (sp->magietyp==mtype) {
|
||||
const char * n = spell_name(sp, lang);
|
||||
variant token;
|
||||
|
@ -147,11 +150,11 @@ get_spellfromtoken(unit *u, const char *name, const struct locale * lang)
|
|||
if (m==NULL) return NULL;
|
||||
sp = get_spellfromtoken_i(name, lang, m->magietyp);
|
||||
if (sp!=NULL) {
|
||||
spell_list * slist = m->spells;
|
||||
quicklist * ql = m->spells;
|
||||
int qi;
|
||||
|
||||
while (slist && slist->data->id<=sp->id) {
|
||||
if (sp==slist->data) return sp;
|
||||
slist = slist->next;
|
||||
if (ql_set_find(&ql, &qi, sp)) {
|
||||
return sp;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
@ -160,16 +163,19 @@ get_spellfromtoken(unit *u, const char *name, const struct locale * lang)
|
|||
spell *
|
||||
find_spellbyid(magic_t mtype, spellid_t id)
|
||||
{
|
||||
spell_list * slist;
|
||||
quicklist * ql;
|
||||
int qi;
|
||||
|
||||
assert(id>=0);
|
||||
if (id==0) return NULL;
|
||||
for (slist=spells;slist!=NULL;slist=slist->next) {
|
||||
spell* sp = slist->data;
|
||||
if (sp->id == id) return sp;
|
||||
for (qi=0, ql=spells; ql; ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
if (sp->id == id) {
|
||||
return sp;
|
||||
}
|
||||
}
|
||||
for (slist=spells;slist!=NULL;slist=slist->next) {
|
||||
spell* sp = slist->data;
|
||||
for (qi=0, ql=spells; ql; ql_advance(&ql, &qi, 1)) {
|
||||
spell * sp = (spell *)ql_get(ql, qi);
|
||||
unsigned int hashid = hashstring(sp->sname);
|
||||
if (hashid==id) {
|
||||
if (sp->magietyp==mtype || mtype==M_NONE) {
|
||||
|
|
|
@ -42,7 +42,7 @@ extern "C" {
|
|||
extern struct attrib_type at_unitdissolve;
|
||||
extern struct attrib_type at_wdwpyramid;
|
||||
|
||||
extern struct spell_list * spells;
|
||||
extern struct quicklist * spells;
|
||||
extern void register_spell(struct spell * sp);
|
||||
extern struct spell * find_spell(magic_t mtype, const char * name);
|
||||
extern struct spell * find_spellbyid(magic_t mtype, spellid_t i);
|
||||
|
|
|
@ -147,6 +147,22 @@ void ql_free(struct quicklist * ql)
|
|||
free(ql);
|
||||
}
|
||||
|
||||
int ql_set_remove(struct quicklist ** qlp, void * data)
|
||||
{
|
||||
int qi;
|
||||
quicklist * ql = *qlp;
|
||||
|
||||
if (!ql) return 0;
|
||||
|
||||
for (qi=0;qi!=ql->num_elements;++qi) {
|
||||
void * qd = ql_get(ql, qi);
|
||||
if (qd==data) {
|
||||
return ql_delete(qlp, qi)==0;
|
||||
}
|
||||
}
|
||||
return ql_set_remove(&ql->next, data);
|
||||
}
|
||||
|
||||
int ql_set_insert(struct quicklist ** qlp, void * data)
|
||||
{
|
||||
if (*qlp) {
|
||||
|
@ -174,4 +190,31 @@ int ql_set_insert(struct quicklist ** qlp, void * data)
|
|||
}
|
||||
ql_push(qlp, data);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ql_set_find(struct quicklist ** qlp, int * qip, const void * data)
|
||||
{
|
||||
quicklist * ql = *qlp;
|
||||
int qi;
|
||||
|
||||
while (ql && ql->elements[ql->num_elements-1]<data) {
|
||||
ql=ql->next;
|
||||
}
|
||||
|
||||
if (!ql) return 0;
|
||||
|
||||
/* TODO: OPT | binary search */
|
||||
for (qi=0;qi!=ql->num_elements;++qi) {
|
||||
if (ql->elements[qi]>data) {
|
||||
return 0;
|
||||
}
|
||||
if (ql->elements[qi]==data) {
|
||||
if (qip) {
|
||||
*qip = qi;
|
||||
*qlp = ql;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@ void ql_free(struct quicklist * ql);
|
|||
|
||||
/* you can use it as a set (sorted pointers)*/
|
||||
int ql_set_insert(struct quicklist ** qlp, void * data);
|
||||
int ql_set_find(struct quicklist ** qlp, int * qip, const void * data);
|
||||
int ql_set_remove(struct quicklist ** qlp, void * data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,7 +26,7 @@ static void test_insert_delete_gives_null(CuTest * tc) {
|
|||
|
||||
static void test_set_insert(CuTest * tc) {
|
||||
struct quicklist * ql = NULL;
|
||||
int a;
|
||||
int a, qi;
|
||||
a = ql_set_insert(&ql, (void*)42);
|
||||
CuAssertIntEquals(tc, 1, ql_length(ql));
|
||||
CuAssertIntEquals(tc, 0, a);
|
||||
|
@ -42,6 +42,64 @@ static void test_set_insert(CuTest * tc) {
|
|||
CuAssertIntEquals(tc, 41, (int)ql_get(ql, 0));
|
||||
CuAssertIntEquals(tc, 42, (int)ql_get(ql, 1));
|
||||
CuAssertIntEquals(tc, 43, (int)ql_get(ql, 2));
|
||||
|
||||
a = ql_set_find(&ql, &qi, (void *)49);
|
||||
CuAssertIntEquals(tc, 0, a);
|
||||
a = ql_set_find(&ql, &qi, (void *)42);
|
||||
CuAssertIntEquals(tc, 1, a);
|
||||
CuAssertIntEquals(tc, 42, (int)ql_get(ql, qi));
|
||||
}
|
||||
|
||||
static void test_set_remove(CuTest * tc) {
|
||||
struct quicklist * ql = NULL, * q2;
|
||||
int a;
|
||||
|
||||
ql_set_insert(&ql, (void*)41);
|
||||
ql_set_insert(&ql, (void*)42);
|
||||
ql_set_insert(&ql, (void*)43);
|
||||
|
||||
q2 = ql;
|
||||
|
||||
a = ql_set_remove(&ql, (void*)42);
|
||||
CuAssertPtrEquals(tc, q2, ql);
|
||||
CuAssertIntEquals(tc, 1, a);
|
||||
CuAssertIntEquals(tc, 41, (int)ql_get(ql, 0));
|
||||
CuAssertIntEquals(tc, 43, (int)ql_get(ql, 1));
|
||||
CuAssertIntEquals(tc, 2, ql_length(ql));
|
||||
|
||||
a = ql_set_remove(&ql, (void*)42);
|
||||
CuAssertPtrEquals(tc, q2, ql);
|
||||
CuAssertIntEquals(tc, 0, a);
|
||||
|
||||
ql_set_remove(&ql, (void*)41);
|
||||
ql_set_remove(&ql, (void*)43);
|
||||
CuAssertPtrEquals(tc, 0, ql);
|
||||
}
|
||||
|
||||
static void test_set_find(CuTest * tc) {
|
||||
struct quicklist * ql = NULL, * q2;
|
||||
int a, qi;
|
||||
|
||||
for (a=0;a!=32;++a) {
|
||||
ql_set_insert(&ql, (void *)a);
|
||||
}
|
||||
|
||||
q2 = ql;
|
||||
a = ql_set_find(&q2, 0, (void *)31);
|
||||
CuAssertIntEquals(tc, 1, a);
|
||||
CuAssertPtrEquals(tc, ql, q2);
|
||||
|
||||
q2 = ql;
|
||||
a = ql_set_find(&ql, &qi, (void *)0);
|
||||
CuAssertIntEquals(tc, 1, a);
|
||||
CuAssertIntEquals(tc, 0, qi);
|
||||
CuAssertPtrEquals(tc, ql, q2);
|
||||
|
||||
q2 = ql;
|
||||
a = ql_set_find(&ql, &qi, (void *)31);
|
||||
CuAssertIntEquals(tc, 1, a);
|
||||
CuAssertIntEquals(tc, 31, (int)ql_get(ql, qi));
|
||||
CuAssertTrue(tc, ql!=q2);
|
||||
}
|
||||
|
||||
static void test_advance(CuTest * tc) {
|
||||
|
@ -111,6 +169,8 @@ CuSuite* get_quicklist_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_advance);
|
||||
SUITE_ADD_TEST(suite, test_push);
|
||||
SUITE_ADD_TEST(suite, test_insert);
|
||||
SUITE_ADD_TEST(suite, test_set_remove);
|
||||
SUITE_ADD_TEST(suite, test_set_find);
|
||||
SUITE_ADD_TEST(suite, test_insert_delete_gives_null);
|
||||
SUITE_ADD_TEST(suite, test_insert_many);
|
||||
SUITE_ADD_TEST(suite, test_delete_rand);
|
||||
|
|
Loading…
Reference in a new issue