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);
|
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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue