forked from github/server
bug 2387: create a ghost to hold on to magical notlost items.
This commit is contained in:
parent
01c808da66
commit
6927eed52e
7 changed files with 130 additions and 35 deletions
|
@ -35,6 +35,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include <spells/unitcurse.h>
|
||||
#include <attributes/otherfaction.h>
|
||||
#include <attributes/racename.h>
|
||||
|
||||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
|
@ -361,6 +362,71 @@ void free_flist(faction **fp) {
|
|||
|
||||
static faction *dead_factions;
|
||||
|
||||
static void give_special_items(unit *u, item **items) {
|
||||
item **iter = items;
|
||||
while (*iter) {
|
||||
item *itm = *iter;
|
||||
if (itm->number > 0 && itm->type->flags & ITF_NOTLOST) {
|
||||
i_change(&u->items, itm->type, itm->number);
|
||||
*iter = itm->next;
|
||||
if (iter == items) {
|
||||
*items = *iter;
|
||||
}
|
||||
i_free(itm);
|
||||
}
|
||||
else {
|
||||
iter = &itm->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
faction *get_or_create_monsters(void)
|
||||
{
|
||||
faction *f = findfaction(MONSTER_ID);
|
||||
if (!f) {
|
||||
const race *rc = rc_get_or_create("dragon");
|
||||
const char *email = config_get("monster.email");
|
||||
f = addfaction(email, NULL, rc, default_locale, 0);
|
||||
renumber_faction(f, MONSTER_ID);
|
||||
faction_setname(f, "Monster");
|
||||
fset(f, FFL_NPC | FFL_NOIDLEOUT);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
faction *get_monsters(void) {
|
||||
return get_or_create_monsters();
|
||||
}
|
||||
|
||||
void save_special_items(unit *usrc)
|
||||
{
|
||||
unit *u;
|
||||
region *r = usrc->region;
|
||||
faction *fm = get_monsters();
|
||||
static const race *rc_ghost;
|
||||
static int cache;
|
||||
static const char *name = NULL;
|
||||
if (rc_changed(&cache)) {
|
||||
rc_ghost = rc_find("ghost");
|
||||
if (!rc_ghost) {
|
||||
rc_ghost = get_race(RC_TEMPLATE);
|
||||
name = "ghost";
|
||||
}
|
||||
assert(rc_ghost);
|
||||
}
|
||||
for (u = r->units; u; u = u->next) {
|
||||
if (u->faction == fm) {
|
||||
give_special_items(u, &usrc->items);
|
||||
return;
|
||||
}
|
||||
}
|
||||
u = create_unit(r, fm, 1, rc_ghost, 0, NULL, NULL);
|
||||
if (name) {
|
||||
set_racename(&u->attribs, name);
|
||||
}
|
||||
give_special_items(u, &usrc->items);
|
||||
}
|
||||
|
||||
void destroyfaction(faction ** fp)
|
||||
{
|
||||
faction * f = *fp;
|
||||
|
@ -385,22 +451,19 @@ void destroyfaction(faction ** fp)
|
|||
}
|
||||
|
||||
while (u) {
|
||||
/* give away your stuff, make zombies if you cannot (quest items) */
|
||||
int result = gift_items(u, GIFT_FRIENDS | GIFT_PEASANTS);
|
||||
if (result != 0) {
|
||||
unit *zombie = u;
|
||||
u = u->nextF;
|
||||
make_zombie(zombie);
|
||||
}
|
||||
else {
|
||||
/* give away your stuff, to ghosts if you cannot (quest items) */
|
||||
if (u->items) {
|
||||
region *r = u->region;
|
||||
|
||||
int result = gift_items(u, GIFT_FRIENDS | GIFT_PEASANTS);
|
||||
if (result != 0) {
|
||||
save_special_items(u);
|
||||
}
|
||||
if (r->land && !!playerrace(u_race(u))) {
|
||||
const race *rc = u_race(u);
|
||||
int m = rmoney(r);
|
||||
|
||||
/* Personen gehen nur an die Bauern, wenn sie auch von dort
|
||||
* stammen */
|
||||
* stammen */
|
||||
if ((rc->ec_flags & ECF_REC_ETHEREAL) == 0) {
|
||||
int p = rpeasants(u->region);
|
||||
int h = rhorses(u->region);
|
||||
|
@ -418,9 +481,9 @@ void destroyfaction(faction ** fp)
|
|||
m += get_money(u);
|
||||
rsetmoney(r, m);
|
||||
}
|
||||
set_number(u, 0);
|
||||
u = u->nextF;
|
||||
}
|
||||
set_number(u, 0);
|
||||
u = u->nextF;
|
||||
}
|
||||
|
||||
handle_event(f->attribs, "destroy", f);
|
||||
|
|
|
@ -168,7 +168,13 @@ extern "C" {
|
|||
int count_maxmigrants(const struct faction * f);
|
||||
int max_magicians(const struct faction * f);
|
||||
|
||||
#define MONSTER_ID 666
|
||||
struct faction *getfaction(void);
|
||||
struct faction *get_monsters(void);
|
||||
struct faction *get_or_create_monsters(void);
|
||||
void save_special_items(struct unit *u);
|
||||
|
||||
#define is_monsters(f) (f->no==MONSTER_ID)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <kernel/ally.h>
|
||||
#include <kernel/alliance.h>
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/item.h>
|
||||
#include <kernel/plane.h>
|
||||
#include <kernel/race.h>
|
||||
#include <kernel/region.h>
|
||||
|
@ -12,6 +13,8 @@
|
|||
#include <util/language.h>
|
||||
#include <util/password.h>
|
||||
|
||||
#include <attributes/racename.h>
|
||||
|
||||
#include "monsters.h"
|
||||
#include <CuTest.h>
|
||||
#include <tests.h>
|
||||
|
@ -250,6 +253,44 @@ static void test_set_email(CuTest *tc) {
|
|||
test_cleanup();
|
||||
}
|
||||
|
||||
static void test_items_notlost(CuTest *tc) {
|
||||
unit *u, *ug;
|
||||
race * rc;
|
||||
struct item_type *itype, *it_silver, *it_horse;
|
||||
|
||||
test_setup();
|
||||
it_horse = test_create_horse();
|
||||
it_silver = test_create_silver();
|
||||
itype = test_create_itemtype("banana");
|
||||
itype->flags |= ITF_NOTLOST;
|
||||
rc = test_create_race("template");
|
||||
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
|
||||
i_change(&u->items, itype, 1);
|
||||
save_special_items(u);
|
||||
CuAssertPtrNotNull(tc, u->next);
|
||||
ug = u->next;
|
||||
CuAssertPtrEquals(tc, NULL, ug->next);
|
||||
CuAssertPtrEquals(tc, rc, (void *)ug->_race);
|
||||
CuAssertIntEquals(tc, 0, i_get(u->items, itype));
|
||||
CuAssertIntEquals(tc, 1, i_get(ug->items, itype));
|
||||
CuAssertStrEquals(tc, "ghost", get_racename(ug->attribs));
|
||||
|
||||
i_change(&u->items, itype, 1);
|
||||
save_special_items(u);
|
||||
CuAssertPtrEquals(tc, NULL, ug->next);
|
||||
CuAssertIntEquals(tc, 2, i_get(ug->items, itype));
|
||||
CuAssertPtrEquals(tc, NULL, u->items);
|
||||
|
||||
i_change(&u->items, itype, 1);
|
||||
i_change(&u->items, it_horse, 5);
|
||||
i_change(&u->items, it_silver, 10);
|
||||
save_special_items(u);
|
||||
CuAssertIntEquals(tc, 3, i_get(ug->items, itype));
|
||||
CuAssertIntEquals(tc, 5, i_get(u->items, it_horse));
|
||||
CuAssertIntEquals(tc, 10, i_get(u->items, it_silver));
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
CuSuite *get_faction_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
@ -265,5 +306,6 @@ CuSuite *get_faction_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_check_passwd);
|
||||
SUITE_ADD_TEST(suite, test_valid_race);
|
||||
SUITE_ADD_TEST(suite, test_set_email);
|
||||
SUITE_ADD_TEST(suite, test_items_notlost);
|
||||
return suite;
|
||||
}
|
||||
|
|
|
@ -1128,24 +1128,6 @@ void monster_kills_peasants(unit * u)
|
|||
}
|
||||
}
|
||||
|
||||
faction *get_or_create_monsters(void)
|
||||
{
|
||||
faction *f = findfaction(MONSTER_ID);
|
||||
if (!f) {
|
||||
const race *rc = rc_get_or_create("dragon");
|
||||
const char *email = config_get("monster.email");
|
||||
f = addfaction(email, NULL, rc, default_locale, 0);
|
||||
renumber_faction(f, MONSTER_ID);
|
||||
faction_setname(f, "Monster");
|
||||
fset(f, FFL_NPC | FFL_NOIDLEOUT);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
faction *get_monsters(void) {
|
||||
return get_or_create_monsters();
|
||||
}
|
||||
|
||||
void make_zombie(unit * u)
|
||||
{
|
||||
u_setfaction(u, get_monsters());
|
||||
|
|
|
@ -35,13 +35,8 @@ extern "C" {
|
|||
|
||||
void monster_kills_peasants(struct unit *u);
|
||||
bool monster_is_waiting(const struct unit *u);
|
||||
struct faction *get_monsters(void);
|
||||
struct faction *get_or_create_monsters(void);
|
||||
void make_zombie(struct unit * u);
|
||||
|
||||
#define MONSTER_ID 666
|
||||
#define is_monsters(f) ((f->flags & FFL_NPC) && f==get_monsters())
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -390,6 +390,12 @@ void test_translate_param(const struct locale *lang, param_t param, const char *
|
|||
add_translation(cb, text, param);
|
||||
}
|
||||
|
||||
item_type *test_create_silver(void) {
|
||||
item_type * itype;
|
||||
itype = test_create_itemtype("money");
|
||||
itype->weight = 1;
|
||||
return itype;
|
||||
}
|
||||
|
||||
item_type *test_create_horse(void) {
|
||||
item_type * itype;
|
||||
|
|
|
@ -50,6 +50,7 @@ extern "C" {
|
|||
struct unit *test_create_unit(struct faction *f, struct region *r);
|
||||
void test_create_world(void);
|
||||
struct item_type * test_create_horse(void);
|
||||
struct item_type * test_create_silver(void);
|
||||
struct building * test_create_building(struct region * r, const struct building_type * btype);
|
||||
struct ship * test_create_ship(struct region * r, const struct ship_type * stype);
|
||||
struct item_type * test_create_itemtype(const char * name);
|
||||
|
|
Loading…
Reference in a new issue