BUG 2367: refactor create_newfamiliar.

add first failing test for bug report.
This commit is contained in:
Enno Rehling 2017-10-06 21:23:58 +02:00
parent 9bfc0139f5
commit 2ce94f2d47
7 changed files with 82 additions and 32 deletions

View File

@ -638,8 +638,14 @@ static int tolua_unit_get_familiar(lua_State * L)
static int tolua_unit_set_familiar(lua_State * L) static int tolua_unit_set_familiar(lua_State * L)
{ {
unit *self = (unit *)tolua_tousertype(L, 1, 0); unit *mag = (unit *)tolua_tousertype(L, 1, NULL);
create_newfamiliar(self, (unit *)tolua_tousertype(L, 2, 0)); unit *fam = (unit *)tolua_tousertype(L, 2, NULL);
if (fam) {
set_familiar(mag, fam);
}
else {
remove_familiar(mag);
}
return 0; return 0;
} }

View File

@ -274,7 +274,7 @@ static void test_skill_familiar(CuTest *tc) {
CuAssertIntEquals(tc, 6, effskill(mag, SK_PERCEPTION, 0)); CuAssertIntEquals(tc, 6, effskill(mag, SK_PERCEPTION, 0));
/* make them mage and familiar to each other */ /* make them mage and familiar to each other */
CuAssertIntEquals(tc, true, create_newfamiliar(mag, fam)); create_newfamiliar(mag, fam);
/* when they are in the same region, the mage gets half their skill as a bonus */ /* when they are in the same region, the mage gets half their skill as a bonus */
CuAssertIntEquals(tc, 6, effskill(fam, SK_PERCEPTION, 0)); CuAssertIntEquals(tc, 6, effskill(fam, SK_PERCEPTION, 0));

View File

@ -42,6 +42,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <kernel/building.h> #include <kernel/building.h>
#include <kernel/callbacks.h> #include <kernel/callbacks.h>
#include <kernel/curse.h> #include <kernel/curse.h>
#include <kernel/equipment.h>
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/messages.h> #include <kernel/messages.h>
@ -2218,23 +2219,35 @@ void remove_familiar(unit * mage)
while (a && a->type == &at_skillmod) { while (a && a->type == &at_skillmod) {
an = a->next; an = a->next;
smd = (skillmod_data *)a->data.v; smd = (skillmod_data *)a->data.v;
if (smd->special == sm_familiar) if (smd->special == sm_familiar) {
a_remove(&mage->attribs, a); a_remove(&mage->attribs, a);
}
a = an; a = an;
} }
} }
bool create_newfamiliar(unit * mage, unit * familiar) void create_newfamiliar(unit * mage, unit * fam)
{ {
set_familiar(mage, familiar); /* skills and spells: */
const struct equipment *eq;
char eqname[64];
const race *rc = u_race(fam);
set_familiar(mage, fam);
snprintf(eqname, sizeof(eqname), "fam_%s", rc->_name);
eq = get_equipment(eqname);
if (eq != NULL) {
equip_items(&fam->items, eq);
}
else {
log_info("could not perform initialization for familiar %s.\n", rc->_name);
}
/* TODO: Diese Attribute beim Tod des Familiars entfernen: */ /* TODO: Diese Attribute beim Tod des Familiars entfernen: */
/* Wenn der Magier stirbt, dann auch der Vertraute */ /* Wenn der Magier stirbt, dann auch der Vertraute */
add_trigger(&mage->attribs, "destroy", trigger_killunit(familiar)); add_trigger(&mage->attribs, "destroy", trigger_killunit(fam));
/* Wenn der Vertraute stirbt, dann bekommt der Magier einen Schock */ /* Wenn der Vertraute stirbt, dann bekommt der Magier einen Schock */
add_trigger(&familiar->attribs, "destroy", trigger_shock(mage)); add_trigger(&fam->attribs, "destroy", trigger_shock(mage));
return true;
} }
static void * resolve_familiar(int id, void *data) { static void * resolve_familiar(int id, void *data) {

View File

@ -329,7 +329,7 @@ extern "C" {
struct unit *get_clone(const struct unit *u); struct unit *get_clone(const struct unit *u);
struct unit *get_clone_mage(const struct unit *u); struct unit *get_clone_mage(const struct unit *u);
void remove_familiar(struct unit *mage); void remove_familiar(struct unit *mage);
bool create_newfamiliar(struct unit *mage, struct unit *familiar); void create_newfamiliar(struct unit *mage, struct unit *familiar);
void create_newclone(struct unit *mage, struct unit *familiar); void create_newclone(struct unit *mage, struct unit *familiar);
struct unit *has_clone(struct unit *mage); struct unit *has_clone(struct unit *mage);

View File

@ -6,6 +6,7 @@
#include <kernel/building.h> #include <kernel/building.h>
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/equipment.h>
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/order.h> #include <kernel/order.h>
#include <kernel/item.h> #include <kernel/item.h>
@ -491,6 +492,9 @@ static void test_familiar_set(CuTest *tc) {
CuAssertPtrEquals(tc, fam, get_familiar(mag)); CuAssertPtrEquals(tc, fam, get_familiar(mag));
CuAssertPtrEquals(tc, mag, get_familiar_mage(fam)); CuAssertPtrEquals(tc, mag, get_familiar_mage(fam));
CuAssertPtrNotNull(tc, a_find(mag->attribs, &at_skillmod)); CuAssertPtrNotNull(tc, a_find(mag->attribs, &at_skillmod));
remove_familiar(mag);
CuAssertPtrEquals(tc, NULL, get_familiar(mag));
CuAssertPtrEquals(tc, NULL, a_find(mag->attribs, &at_skillmod));
test_cleanup(); test_cleanup();
} }
@ -514,10 +518,47 @@ static void test_familiar_age(CuTest *tc) {
test_cleanup(); test_cleanup();
} }
static void test_familiar_equip(CuTest *tc) {
unit *mag, *u;
equipment *eq;
const item_type * itype;
spell *sp;
sc_mage * mage;
test_setup();
itype = test_create_itemtype("horse");
CuAssertPtrNotNull(tc, itype);
sp = create_spell("testspell");
CuAssertPtrNotNull(tc, sp);
eq = get_or_create_equipment("fam_human");
equipment_setitem(eq, itype, "1");
equipment_setskill(eq, SK_ENTERTAINMENT, "5");
equipment_addspell(eq, sp->sname, 1);
mag = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
u = test_create_unit(mag->faction, test_create_region(0, 0, 0));
set_familiar(mag, u);
create_newfamiliar(mag, u);
CuAssertIntEquals(tc, 1, i_get(u->items, itype));
CuAssertIntEquals(tc, 5, get_level(u, SK_ENTERTAINMENT));
CuAssertIntEquals(tc, 0, get_level(u, SK_MAGIC));
mage = get_mage(u);
CuAssertPtrNotNull(tc, mage);
CuAssertPtrNotNull(tc, mage->spellbook);
set_level(u, SK_MAGIC, 1);
CuAssertPtrEquals(tc, mage, get_mage(u));
CuAssertTrue(tc, u_hasspell(u, sp));
test_cleanup();
}
CuSuite *get_familiar_suite(void) CuSuite *get_familiar_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_familiar_equip);
SUITE_ADD_TEST(suite, test_familiar_set); SUITE_ADD_TEST(suite, test_familiar_set);
SUITE_ADD_TEST(suite, test_familiar_age); SUITE_ADD_TEST(suite, test_familiar_age);
return suite; return suite;

View File

@ -39,7 +39,6 @@
#include <kernel/building.h> #include <kernel/building.h>
#include <kernel/curse.h> #include <kernel/curse.h>
#include <kernel/connection.h> #include <kernel/connection.h>
#include <kernel/equipment.h>
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/messages.h> #include <kernel/messages.h>
@ -513,27 +512,22 @@ static const race *select_familiar(const race * magerace, magic_t magiegebiet)
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
/* der Vertraue des Magiers */ /* der Vertraue des Magiers */
static void make_familiar(unit * familiar, unit * mage) static unit * make_familiar(unit * mage, region *r, const race *rc, const char *name)
{ {
/* skills and spells: */ unit *fam;
const struct equipment *eq;
char eqname[64]; fam = create_unit(r, mage->faction, 1, rc, 0, name, mage);
const race * rc = u_race(familiar); setstatus(fam, ST_FLEE);
snprintf(eqname, sizeof(eqname), "fam_%s", rc->_name); fset(fam, UFL_LOCKED);
eq = get_equipment(eqname);
if (eq != NULL) {
equip_items(&familiar->items, eq);
}
else {
log_info("could not perform initialization for familiar %s.\n", rc->_name);
}
/* triggers: */ /* triggers: */
create_newfamiliar(mage, familiar); create_newfamiliar(mage, fam);
/* Hitpoints nach Talenten korrigieren, sonst starten vertraute /* Hitpoints nach Talenten korrigieren, sonst starten vertraute
* mit Ausdauerbonus verwundet */ * mit Ausdauerbonus verwundet */
familiar->hp = unit_max_hp(familiar); fam->hp = unit_max_hp(fam);
return fam;
} }
static int sp_summon_familiar(castorder * co) static int sp_summon_familiar(castorder * co)
@ -586,10 +580,7 @@ static int sp_summon_familiar(castorder * co)
msg = msg_message("familiar_name", "unit", mage); msg = msg_message("familiar_name", "unit", mage);
nr_render(msg, mage->faction->locale, zText, sizeof(zText), mage->faction); nr_render(msg, mage->faction->locale, zText, sizeof(zText), mage->faction);
msg_release(msg); msg_release(msg);
familiar = create_unit(r, mage->faction, 1, rc, 0, zText, mage); familiar = make_familiar(mage, r, rc, zText);
setstatus(familiar, ST_FLEE);
fset(familiar, UFL_LOCKED);
make_familiar(familiar, mage);
dh = 0; dh = 0;
dh1 = 0; dh1 = 0;

View File

@ -396,7 +396,6 @@ int a_age(attrib ** p, void *owner)
static critbit_tree cb_deprecated = { 0 }; static critbit_tree cb_deprecated = { 0 };
typedef struct deprecated_s { typedef struct deprecated_s {
unsigned int hash; unsigned int hash;
int(*reader)(attrib *, void *, struct gamedata *); int(*reader)(attrib *, void *, struct gamedata *);