forked from github/server
Merge pull request #688 from ennorehling/develop
fix a crash, refactor fumbles
This commit is contained in:
commit
33aa46674f
|
@ -244,7 +244,6 @@ struct order *ord)
|
|||
warden_add_give(src, dest, itype, delta);
|
||||
}
|
||||
#endif
|
||||
handle_event(dest->attribs, "receive", src);
|
||||
}
|
||||
else {
|
||||
/* return horses to the region */
|
||||
|
@ -257,7 +256,6 @@ struct order *ord)
|
|||
give_money(src, itype, n);
|
||||
}
|
||||
}
|
||||
handle_event(src->attribs, "give", dest);
|
||||
}
|
||||
add_give(src, dest, n, delta, item2resource(itype), ord, error);
|
||||
if (error)
|
||||
|
|
|
@ -190,7 +190,7 @@ const char *buildingtype(const building_type * btype, const building * b, int bs
|
|||
if (btype->name) {
|
||||
return btype->name(btype, b, bsize);
|
||||
}
|
||||
if (btype->construction->extra.name) {
|
||||
if (btype->construction && btype->construction->extra.name) {
|
||||
if (b) {
|
||||
assert(b->type == btype);
|
||||
bsize = adjust_size(b, bsize);
|
||||
|
|
|
@ -558,9 +558,24 @@ static void test_largestbuilding(CuTest *tc) {
|
|||
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 *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_buildingtype);
|
||||
SUITE_ADD_TEST(suite, test_largestbuilding);
|
||||
SUITE_ADD_TEST(suite, test_cmp_castle_size);
|
||||
SUITE_ADD_TEST(suite, test_cmp_taxes);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -799,10 +799,6 @@ void plan_monsters(faction * f)
|
|||
if (long_order == NULL) {
|
||||
/* Ab hier noch nicht generalisierte Spezialbehandlungen. */
|
||||
|
||||
if (!u->orders) {
|
||||
handle_event(u->attribs, "ai_move", u);
|
||||
}
|
||||
|
||||
if (fval(rc, RCF_DRAGON)) {
|
||||
long_order = plan_dragon(u);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue