forked from github/server
convert multiple seenspell attributes to single seenspells list. faster? maybe.
This commit is contained in:
parent
c3fce574fb
commit
fe29f2433a
3 changed files with 90 additions and 24 deletions
|
@ -179,8 +179,8 @@ void register_attributes(void)
|
|||
at_register(&at_mage);
|
||||
at_register(&at_countdown);
|
||||
at_register(&at_curse);
|
||||
|
||||
at_register(&at_seenspell);
|
||||
at_register(&at_seenspells);
|
||||
|
||||
/* neue REGION-Attribute */
|
||||
at_register(&at_moveblock);
|
||||
|
|
|
@ -34,6 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <storage.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/* Ausgabe der Spruchbeschreibungen
|
||||
|
@ -43,6 +44,43 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
* Spruch zu seiner List-of-known-spells hinzugefügt werden.
|
||||
*/
|
||||
|
||||
static int read_seenspells(variant *var, void *owner, struct gamedata *data)
|
||||
{
|
||||
selist *ql;
|
||||
storage *store = data->store;
|
||||
spell *sp = 0;
|
||||
char token[32];
|
||||
|
||||
UNUSED_ARG(owner);
|
||||
READ_TOK(store, token, sizeof(token));
|
||||
while (token[0]) {
|
||||
sp = find_spell(token);
|
||||
if (!sp) {
|
||||
log_info("read_seenspells: could not find spell '%s'\n", token);
|
||||
return AT_READ_FAIL;
|
||||
}
|
||||
selist_push(&ql, sp);
|
||||
READ_TOK(store, token, sizeof(token));
|
||||
}
|
||||
var->v = ql;
|
||||
return AT_READ_OK;
|
||||
}
|
||||
|
||||
static bool cb_write_spell(const void *data, void *more) {
|
||||
const spell *sp = (const spell *)data;
|
||||
storage *store = (storage *)more;
|
||||
WRITE_TOK(store, sp->sname);
|
||||
return true;
|
||||
|
||||
}
|
||||
static void
|
||||
write_seenspells(const variant *var, const void *owner, struct storage *store)
|
||||
{
|
||||
UNUSED_ARG(owner);
|
||||
selist_foreach_ex((selist *)var->v, cb_write_spell, store);
|
||||
WRITE_TOK(store, "");
|
||||
}
|
||||
|
||||
static int read_seenspell(variant *var, void *owner, struct gamedata *data)
|
||||
{
|
||||
storage *store = data->store;
|
||||
|
@ -60,7 +98,7 @@ static int read_seenspell(variant *var, void *owner, struct gamedata *data)
|
|||
return AT_READ_FAIL;
|
||||
}
|
||||
var->v = sp;
|
||||
return AT_READ_OK;
|
||||
return AT_READ_DEPR;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -71,18 +109,53 @@ write_seenspell(const variant *var, const void *owner, struct storage *store)
|
|||
WRITE_TOK(store, sp->sname);
|
||||
}
|
||||
|
||||
static int cmp_spell(const void *a, const void *b) {
|
||||
const spell *spa = (const spell *)a;
|
||||
const spell *spb = (const spell *)b;
|
||||
return strcmp(spa->sname, spb->sname);
|
||||
}
|
||||
|
||||
static bool set_seen(attrib **alist, struct spell *sp) {
|
||||
attrib *a = a_find(*alist, &at_seenspells);
|
||||
selist *sl;
|
||||
if (!a) {
|
||||
a = a_add(alist, a_new(&at_seenspells));
|
||||
}
|
||||
sl = (selist *)a->data.v;
|
||||
return selist_set_insert(&sl, sp, cmp_spell);
|
||||
}
|
||||
|
||||
static void upgrade_seenspell(attrib **alist, attrib *abegin) {
|
||||
attrib *a, *ak;
|
||||
|
||||
ak = a_find(*alist, &at_seenspells);
|
||||
if (ak) alist = &ak;
|
||||
for (a = abegin; a && a->type == abegin->type; a = a->next) {
|
||||
set_seen(alist, (struct spell *)a->data.v);
|
||||
}
|
||||
}
|
||||
|
||||
static void free_seenspells(variant *var) {
|
||||
selist *sl = (selist *)var->v;
|
||||
selist_free(sl);
|
||||
}
|
||||
|
||||
attrib_type at_seenspells = {
|
||||
"seenspells", NULL, free_seenspells, NULL, write_seenspells, read_seenspells
|
||||
};
|
||||
|
||||
attrib_type at_seenspell = {
|
||||
"seenspell", NULL, NULL, NULL, write_seenspell, read_seenspell
|
||||
"seenspell", NULL, NULL, NULL, NULL, read_seenspell, upgrade_seenspell
|
||||
};
|
||||
|
||||
static bool already_seen(const faction * f, const spell * sp)
|
||||
{
|
||||
attrib *a;
|
||||
|
||||
for (a = a_find(f->attribs, &at_seenspell); a && a->type == &at_seenspell;
|
||||
a = a->next) {
|
||||
if (a->data.v == sp)
|
||||
return true;
|
||||
a = a_find(f->attribs, &at_seenspells);
|
||||
if (a) {
|
||||
selist *sl = (selist *)a->data.v;
|
||||
return selist_set_find(&sl, NULL, sp, cmp_spell);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -94,25 +167,17 @@ attrib_type at_reportspell = {
|
|||
void show_spell(faction *f, const spellbook_entry *sbe)
|
||||
{
|
||||
if (!already_seen(f, sbe->sp)) {
|
||||
attrib * a = a_new(&at_reportspell);
|
||||
a->data.v = (void *)sbe;
|
||||
a_add(&f->attribs, a);
|
||||
a_add(&f->attribs, a_new(&at_seenspell))->data.v = sbe->sp;
|
||||
/* mark the spell as seen by this faction: */
|
||||
if (set_seen(&f->attribs, sbe->sp)) {
|
||||
/* add the spell to the report: */
|
||||
attrib * a = a_new(&at_reportspell);
|
||||
a->data.v = (void *)sbe;
|
||||
a_add(&f->attribs, a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reset_seen_spells(faction *f, const struct spell *sp)
|
||||
{
|
||||
if (sp) {
|
||||
attrib *a = a_find(f->attribs, &at_seenspell);
|
||||
while (a && a->type == &at_seenspell && a->data.v != sp) {
|
||||
a = a->next;
|
||||
}
|
||||
if (a) {
|
||||
a_remove(&f->attribs, a);
|
||||
}
|
||||
}
|
||||
else {
|
||||
a_removeall(&f->attribs, &at_seenspell);
|
||||
}
|
||||
a_removeall(&f->attribs, &at_seenspells);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ void show_spell(struct faction * f, const struct spellbook_entry *sbe);
|
|||
void reset_seen_spells(struct faction * f, const struct spell *sp);
|
||||
|
||||
extern struct attrib_type at_reportspell;
|
||||
extern struct attrib_type at_seenspell;
|
||||
extern struct attrib_type at_seenspells;
|
||||
extern struct attrib_type at_seenspell; /* upgraded */
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue