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)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
create_newfamiliar(self, (unit *)tolua_tousertype(L, 2, 0));
unit *mag = (unit *)tolua_tousertype(L, 1, NULL);
unit *fam = (unit *)tolua_tousertype(L, 2, NULL);
if (fam) {
set_familiar(mag, fam);
}
else {
remove_familiar(mag);
}
return 0;
}

View File

@ -274,7 +274,7 @@ static void test_skill_familiar(CuTest *tc) {
CuAssertIntEquals(tc, 6, effskill(mag, SK_PERCEPTION, 0));
/* 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 */
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/callbacks.h>
#include <kernel/curse.h>
#include <kernel/equipment.h>
#include <kernel/faction.h>
#include <kernel/item.h>
#include <kernel/messages.h>
@ -2218,23 +2219,35 @@ void remove_familiar(unit * mage)
while (a && a->type == &at_skillmod) {
an = a->next;
smd = (skillmod_data *)a->data.v;
if (smd->special == sm_familiar)
if (smd->special == sm_familiar) {
a_remove(&mage->attribs, a);
}
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: */
/* 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 */
add_trigger(&familiar->attribs, "destroy", trigger_shock(mage));
return true;
add_trigger(&fam->attribs, "destroy", trigger_shock(mage));
}
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_mage(const struct unit *u);
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);
struct unit *has_clone(struct unit *mage);

View File

@ -6,6 +6,7 @@
#include <kernel/building.h>
#include <kernel/race.h>
#include <kernel/equipment.h>
#include <kernel/faction.h>
#include <kernel/order.h>
#include <kernel/item.h>
@ -491,6 +492,9 @@ static void test_familiar_set(CuTest *tc) {
CuAssertPtrEquals(tc, fam, get_familiar(mag));
CuAssertPtrEquals(tc, mag, get_familiar_mage(fam));
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();
}
@ -514,10 +518,47 @@ static void test_familiar_age(CuTest *tc) {
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 *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_familiar_equip);
SUITE_ADD_TEST(suite, test_familiar_set);
SUITE_ADD_TEST(suite, test_familiar_age);
return suite;

View File

@ -39,7 +39,6 @@
#include <kernel/building.h>
#include <kernel/curse.h>
#include <kernel/connection.h>
#include <kernel/equipment.h>
#include <kernel/faction.h>
#include <kernel/item.h>
#include <kernel/messages.h>
@ -513,27 +512,22 @@ static const race *select_familiar(const race * magerace, magic_t magiegebiet)
/* ------------------------------------------------------------- */
/* 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: */
const struct equipment *eq;
char eqname[64];
const race * rc = u_race(familiar);
snprintf(eqname, sizeof(eqname), "fam_%s", rc->_name);
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);
}
unit *fam;
fam = create_unit(r, mage->faction, 1, rc, 0, name, mage);
setstatus(fam, ST_FLEE);
fset(fam, UFL_LOCKED);
/* triggers: */
create_newfamiliar(mage, familiar);
create_newfamiliar(mage, fam);
/* Hitpoints nach Talenten korrigieren, sonst starten vertraute
* mit Ausdauerbonus verwundet */
familiar->hp = unit_max_hp(familiar);
fam->hp = unit_max_hp(fam);
return fam;
}
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);
nr_render(msg, mage->faction->locale, zText, sizeof(zText), mage->faction);
msg_release(msg);
familiar = create_unit(r, mage->faction, 1, rc, 0, zText, mage);
setstatus(familiar, ST_FLEE);
fset(familiar, UFL_LOCKED);
make_familiar(familiar, mage);
familiar = make_familiar(mage, r, rc, zText);
dh = 0;
dh1 = 0;

View File

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