Merge pull request #688 from ennorehling/develop

fix a crash, refactor fumbles
This commit is contained in:
Enno Rehling 2017-04-30 03:51:49 +02:00 committed by GitHub
commit 33aa46674f
11 changed files with 62 additions and 24 deletions

View File

@ -244,7 +244,6 @@ struct order *ord)
warden_add_give(src, dest, itype, delta); warden_add_give(src, dest, itype, delta);
} }
#endif #endif
handle_event(dest->attribs, "receive", src);
} }
else { else {
/* return horses to the region */ /* return horses to the region */
@ -257,7 +256,6 @@ struct order *ord)
give_money(src, itype, n); give_money(src, itype, n);
} }
} }
handle_event(src->attribs, "give", dest);
} }
add_give(src, dest, n, delta, item2resource(itype), ord, error); add_give(src, dest, n, delta, item2resource(itype), ord, error);
if (error) if (error)

View File

@ -190,7 +190,7 @@ const char *buildingtype(const building_type * btype, const building * b, int bs
if (btype->name) { if (btype->name) {
return btype->name(btype, b, bsize); return btype->name(btype, b, bsize);
} }
if (btype->construction->extra.name) { if (btype->construction && btype->construction->extra.name) {
if (b) { if (b) {
assert(b->type == btype); assert(b->type == btype);
bsize = adjust_size(b, bsize); bsize = adjust_size(b, bsize);

View File

@ -558,9 +558,24 @@ static void test_largestbuilding(CuTest *tc) {
test_cleanup(); test_cleanup();
} }
static void test_buildingtype(CuTest *tc) {
building_type *btype;
test_setup();
btype = test_create_buildingtype("hodor");
CuAssertPtrNotNull(tc, btype->construction);
CuAssertStrEquals(tc, "hodor", buildingtype(btype, NULL, 1));
btype->construction->extra.name = strdup("castle");
CuAssertStrEquals(tc, "castle", buildingtype(btype, NULL, 1));
btype = bt_get_or_create("portal");
CuAssertPtrEquals(tc, NULL, btype->construction);
CuAssertStrEquals(tc, "portal", buildingtype(btype, NULL, 1));
test_cleanup();
}
CuSuite *get_building_suite(void) CuSuite *get_building_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_buildingtype);
SUITE_ADD_TEST(suite, test_largestbuilding); SUITE_ADD_TEST(suite, test_largestbuilding);
SUITE_ADD_TEST(suite, test_cmp_castle_size); SUITE_ADD_TEST(suite, test_cmp_castle_size);
SUITE_ADD_TEST(suite, test_cmp_taxes); SUITE_ADD_TEST(suite, test_cmp_taxes);

View File

@ -597,9 +597,6 @@ static void json_spells(cJSON *json) {
else if (strcmp(item->string, "cast") == 0) { else if (strcmp(item->string, "cast") == 0) {
sp->cast = (spell_f)get_function(item->valuestring); 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) { else if (strcmp(item->string, "syntax") == 0) {
sp->syntax = strdup(item->valuestring); 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 <stdlib.h>
#include <string.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; static critbit_tree cb_spells;
selist * spells; selist * spells;
@ -49,6 +71,7 @@ static void free_spell_cb(void *cbdata) {
} }
void free_spells(void) { void free_spells(void) {
cb_clear(&cb_fumbles);
cb_clear(&cb_spells); cb_clear(&cb_spells);
selist_foreach(spells, free_spell_cb); selist_foreach(spells, free_spell_cb);
selist_free(spells); selist_free(spells);

View File

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

View File

@ -86,10 +86,25 @@ static void test_spellref(CuTest *tc)
test_cleanup(); 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 *get_spell_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_spellref); 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_a_spell);
SUITE_ADD_TEST(suite, test_create_duplicate_spell); SUITE_ADD_TEST(suite, test_create_duplicate_spell);
SUITE_ADD_TEST(suite, test_create_spell_with_id); 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) static int parse_spells(xmlDocPtr doc)
{ {
pf_generic cast = 0; pf_generic cast = 0;
pf_generic fumble = 0;
xmlXPathContextPtr xpath = xmlXPathNewContext(doc); xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
xmlXPathObjectPtr spells; xmlXPathObjectPtr spells;
char zText[32];
strcpy(zText, "fumble_");
/* reading eressea/spells/spell */ /* reading eressea/spells/spell */
spells = xmlXPathEvalExpression(BAD_CAST "/eressea/spells/spell", xpath); spells = xmlXPathEvalExpression(BAD_CAST "/eressea/spells/spell", xpath);
@ -1404,8 +1401,6 @@ static int parse_spells(xmlDocPtr doc)
if (!cast) { if (!cast) {
log_error("no spell cast function registered for '%s'\n", sp->sname); 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 { else {
for (k = 0; k != result->nodesetval->nodeNr; ++k) { 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); 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 { else {
log_error("unknown function type '%s' for spell '%s'\n", (const char *)propValue, sp->sname); 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->cast = (spell_f)cast;
sp->fumble = (fumble_f)fumble;
xmlXPathFreeObject(result); xmlXPathFreeObject(result);
/* reading eressea/spells/spell/resource */ /* reading eressea/spells/spell/resource */

View File

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

View File

@ -799,10 +799,6 @@ void plan_monsters(faction * f)
if (long_order == NULL) { if (long_order == NULL) {
/* Ab hier noch nicht generalisierte Spezialbehandlungen. */ /* Ab hier noch nicht generalisierte Spezialbehandlungen. */
if (!u->orders) {
handle_event(u->attribs, "ai_move", u);
}
if (fval(rc, RCF_DRAGON)) { if (fval(rc, RCF_DRAGON)) {
long_order = plan_dragon(u); long_order = plan_dragon(u);
} }

View File

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