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_mage);
|
||||||
at_register(&at_countdown);
|
at_register(&at_countdown);
|
||||||
at_register(&at_curse);
|
at_register(&at_curse);
|
||||||
|
|
||||||
at_register(&at_seenspell);
|
at_register(&at_seenspell);
|
||||||
|
at_register(&at_seenspells);
|
||||||
|
|
||||||
/* neue REGION-Attribute */
|
/* neue REGION-Attribute */
|
||||||
at_register(&at_moveblock);
|
at_register(&at_moveblock);
|
||||||
|
|
|
@ -34,6 +34,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <storage.h>
|
#include <storage.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Ausgabe der Spruchbeschreibungen
|
/* 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.
|
* 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)
|
static int read_seenspell(variant *var, void *owner, struct gamedata *data)
|
||||||
{
|
{
|
||||||
storage *store = data->store;
|
storage *store = data->store;
|
||||||
|
@ -60,7 +98,7 @@ static int read_seenspell(variant *var, void *owner, struct gamedata *data)
|
||||||
return AT_READ_FAIL;
|
return AT_READ_FAIL;
|
||||||
}
|
}
|
||||||
var->v = sp;
|
var->v = sp;
|
||||||
return AT_READ_OK;
|
return AT_READ_DEPR;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -71,18 +109,53 @@ write_seenspell(const variant *var, const void *owner, struct storage *store)
|
||||||
WRITE_TOK(store, sp->sname);
|
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 = {
|
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)
|
static bool already_seen(const faction * f, const spell * sp)
|
||||||
{
|
{
|
||||||
attrib *a;
|
attrib *a;
|
||||||
|
|
||||||
for (a = a_find(f->attribs, &at_seenspell); a && a->type == &at_seenspell;
|
a = a_find(f->attribs, &at_seenspells);
|
||||||
a = a->next) {
|
if (a) {
|
||||||
if (a->data.v == sp)
|
selist *sl = (selist *)a->data.v;
|
||||||
return true;
|
return selist_set_find(&sl, NULL, sp, cmp_spell);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -94,25 +167,17 @@ attrib_type at_reportspell = {
|
||||||
void show_spell(faction *f, const spellbook_entry *sbe)
|
void show_spell(faction *f, const spellbook_entry *sbe)
|
||||||
{
|
{
|
||||||
if (!already_seen(f, sbe->sp)) {
|
if (!already_seen(f, sbe->sp)) {
|
||||||
attrib * a = a_new(&at_reportspell);
|
/* mark the spell as seen by this faction: */
|
||||||
a->data.v = (void *)sbe;
|
if (set_seen(&f->attribs, sbe->sp)) {
|
||||||
a_add(&f->attribs, a);
|
/* add the spell to the report: */
|
||||||
a_add(&f->attribs, a_new(&at_seenspell))->data.v = sbe->sp;
|
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)
|
void reset_seen_spells(faction *f, const struct spell *sp)
|
||||||
{
|
{
|
||||||
if (sp) {
|
a_removeall(&f->attribs, &at_seenspells);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
void reset_seen_spells(struct faction * f, const struct spell *sp);
|
||||||
|
|
||||||
extern struct attrib_type at_reportspell;
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue