refactor the special fumble functions for spells.

removed from struct spell.
funpointers in structs are bad, mkay.
This commit is contained in:
Enno Rehling 2017-04-30 03:27:28 +02:00
parent 931e705b05
commit e6f8c943fa
7 changed files with 46 additions and 17 deletions

View File

@ -597,9 +597,6 @@ static void json_spells(cJSON *json) {
else if (strcmp(item->string, "cast") == 0) {
sp->cast = (spell_f)get_function(item->valuestring);
}
else if (strcmp(item->string, "fumble") == 0) {
sp->fumble = (fumble_f)get_function(item->valuestring);
}
else if (strcmp(item->string, "syntax") == 0) {
sp->syntax = strdup(item->valuestring);
}

View File

@ -33,6 +33,28 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <stdlib.h>
#include <string.h>
static critbit_tree cb_fumbles;
void add_fumble(const char *sname, fumble_f fun)
{
size_t len;
char data[64];
len = cb_new_kv(sname, strlen(sname), &fun, sizeof(fun), data);
assert(len <= sizeof(data));
cb_insert(&cb_fumbles, data, len);
}
fumble_f get_fumble(const char *sname)
{
void * match;
fumble_f result = NULL;
if (cb_find_prefix(&cb_fumbles, sname, strlen(sname) + 1, &match, 1, 0)) {
cb_get_kv(match, &result, sizeof(result));
}
return result;
}
static critbit_tree cb_spells;
selist * spells;
@ -49,6 +71,7 @@ static void free_spell_cb(void *cbdata) {
}
void free_spells(void) {
cb_clear(&cb_fumbles);
cb_clear(&cb_spells);
selist_foreach(spells, free_spell_cb);
selist_free(spells);

View File

@ -42,7 +42,6 @@ extern "C" {
int rank; /* Reihenfolge der Zauber */
struct spell_component *components;
spell_f cast;
fumble_f fumble;
} spell;
typedef struct spellref {
@ -50,6 +49,9 @@ extern "C" {
struct spell *sp;
} spellref;
void add_fumble(const char *sname, fumble_f fun);
fumble_f get_fumble(const char *sname);
struct spellref *spellref_create(struct spell *sp, const char *name);
void spellref_free(struct spellref *spref);
struct spell *spellref_get(struct spellref *spref);

View File

@ -86,10 +86,25 @@ static void test_spellref(CuTest *tc)
test_cleanup();
}
void my_fumble(const struct castorder *co) {
UNUSED_ARG(co);
}
static void test_fumbles(CuTest *tc)
{
test_setup();
CuAssertTrue(tc, NULL==get_fumble("hodor"));
add_fumble("hodor", my_fumble);
CuAssertTrue(tc, my_fumble==get_fumble("hodor"));
test_cleanup();
CuAssertTrue(tc, NULL==get_fumble("hodor"));
}
CuSuite *get_spell_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_spellref);
SUITE_ADD_TEST(suite, test_fumbles);
SUITE_ADD_TEST(suite, test_create_a_spell);
SUITE_ADD_TEST(suite, test_create_duplicate_spell);
SUITE_ADD_TEST(suite, test_create_spell_with_id);

View File

@ -1312,11 +1312,8 @@ static int parse_spellbooks(xmlDocPtr doc)
static int parse_spells(xmlDocPtr doc)
{
pf_generic cast = 0;
pf_generic fumble = 0;
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
xmlXPathObjectPtr spells;
char zText[32];
strcpy(zText, "fumble_");
/* reading eressea/spells/spell */
spells = xmlXPathEvalExpression(BAD_CAST "/eressea/spells/spell", xpath);
@ -1404,8 +1401,6 @@ static int parse_spells(xmlDocPtr doc)
if (!cast) {
log_error("no spell cast function registered for '%s'\n", sp->sname);
}
strlcpy(zText + 7, sp->sname, sizeof(zText) - 7);
fumble = get_function(zText);
}
else {
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
@ -1422,9 +1417,6 @@ static int parse_spells(xmlDocPtr doc)
log_error("unknown function name '%s' for spell '%s'\n", (const char *)propValue, sp->sname);
}
}
else if (fun && strcmp((const char *)propValue, "fumble") == 0) {
fumble = fun;
}
else {
log_error("unknown function type '%s' for spell '%s'\n", (const char *)propValue, sp->sname);
}
@ -1432,7 +1424,6 @@ static int parse_spells(xmlDocPtr doc)
}
}
sp->cast = (spell_f)cast;
sp->fumble = (fumble_f)fumble;
xmlXPathFreeObject(result);
/* reading eressea/spells/spell/resource */

View File

@ -1370,14 +1370,16 @@ static void do_fumble(castorder * co)
double effect;
static const race *rc_toad;
static int rc_cache;
fumble_f fun;
ADDMSG(&u->faction->msgs,
msg_message("patzer", "unit region spell", u, r, sp));
switch (rng_int() % 10) {
case 0:
/* wenn vorhanden spezieller Patzer, ansonsten nix */
if (sp->fumble) {
sp->fumble(co);
fun = get_fumble(sp->sname);
if (fun) {
fun(co);
}
else {
fumble_default(co);

View File

@ -6622,8 +6622,7 @@ static void register_spelldata(void)
register_function((pf_generic)data->cast, data->sname);
}
if (data->fumble) {
strlcpy(zText + 7, data->sname, sizeof(zText) - 7);
register_function((pf_generic)data->fumble, zText);
add_fumble(data->sname, data->fumble);
}
}
}