Added a test for expensive skills.

When resetting the game rules, make sure basic resources (money, hp, person) are initialized.
This commit is contained in:
Enno Rehling 2014-06-22 07:55:14 -07:00
parent 43dc69d94a
commit 2c831230a0
15 changed files with 76 additions and 65 deletions

View File

@ -360,7 +360,7 @@ static int do_recruiting(recruitment * recruits, int available)
number = _min(req->qty, (int)(get / multi));
if (rc->recruitcost) {
int afford = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT,
int afford = get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT,
number * rc->recruitcost) / rc->recruitcost;
number = _min(number, afford);
}
@ -371,7 +371,7 @@ static int do_recruiting(recruitment * recruits, int available)
assert(number >= 0);
}
if (rc->recruitcost) {
use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT,
use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT,
rc->recruitcost * number);
}
add_recruits(u, number, req->qty);
@ -578,7 +578,7 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
return;
}
if (get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT,
if (get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT,
recruitcost) < recruitcost) {
cmistake(u, ord, 142, MSG_EVENT);
return;
@ -603,7 +603,7 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
}
if (recruitcost > 0) {
int pooled =
get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, recruitcost * n);
get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, recruitcost * n);
n = _min(n, pooled / recruitcost);
}
@ -1866,7 +1866,7 @@ static void expandbuying(region * r, request * buyorders)
multi = trade->multi;
price = ltype->price * multi;
if (get_pooled(oa[j].unit, oldresourcetype[R_SILVER], GET_DEFAULT,
if (get_pooled(oa[j].unit, get_resourcetype(R_SILVER), GET_DEFAULT,
price) >= price) {
unit *u = oa[j].unit;
item *items;
@ -1883,7 +1883,7 @@ static void expandbuying(region * r, request * buyorders)
i_change(&items, ltype->itype, 1);
a->data.v = items;
i_change(&oa[j].unit->items, ltype->itype, 1);
use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, price);
use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, price);
if (u->n < 0)
u->n = 0;
u->n += price;
@ -2674,7 +2674,7 @@ static void breed_cmd(unit * u, struct order *ord)
if (rtype == rt_mallornseed || rtype == rt_seed) {
breedtrees(r, u, m);
break;
} else if (rtype != oldresourcetype[R_HORSE]) {
} else if (rtype != get_resourcetype(R_HORSE)) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_cannotmake", ""));
break;
}

View File

@ -315,7 +315,7 @@ void build_road(region * r, unit * u, int size, direction_t d)
if (u_race(u) == new_race[RC_STONEGOLEM]) {
n = u->number * GOLEM_STONE;
} else {
n = get_pooled(u, oldresourcetype[R_STONE], GET_DEFAULT, left);
n = get_pooled(u, get_resourcetype(R_STONE), GET_DEFAULT, left);
if (n == 0) {
cmistake(u, u->thisorder, 151, MSG_PRODUCE);
return;
@ -359,7 +359,7 @@ void build_road(region * r, unit * u, int size, direction_t d)
}
scale_number(u, u->number - golemsused);
} else {
use_pooled(u, oldresourcetype[R_STONE], GET_DEFAULT, n);
use_pooled(u, get_resourcetype(R_STONE), GET_DEFAULT, n);
/* Nur soviel PRODUCEEXP wie auch tatsaechlich gemacht wurde */
produceexp(u, SK_ROAD_BUILDING, _min(n, u->number));
}

View File

@ -278,7 +278,7 @@ static int sm_smithy(const unit * u, const region * r, skill_t sk, int value)
static int mm_smithy(const unit * u, const resource_type * rtype, int value)
{ /* material-mod */
if (rtype == oldresourcetype[R_IRON])
if (rtype == get_resourcetype(R_IRON))
return value * 2;
return value;
}

View File

@ -2848,6 +2848,8 @@ void free_gamedata(void)
a_remove(&global.attribs, global.attribs);
}
++global.cookie; /* readgame() already does this, but sjust in case */
init_resources();
}
void load_inifile(dictionary * d)

View File

@ -104,14 +104,14 @@ static int res_changepeasants(unit * u, const resource_type * rtype, int delta)
static int res_changeitem(unit * u, const resource_type * rtype, int delta)
{
int num;
if (rtype == oldresourcetype[R_STONE] && u_race(u) == new_race[RC_STONEGOLEM]
if (rtype == get_resourcetype(R_STONE) && u_race(u) == new_race[RC_STONEGOLEM]
&& delta <= 0) {
int reduce = delta / GOLEM_STONE;
if (delta % GOLEM_STONE != 0)
--reduce;
scale_number(u, u->number + reduce);
num = u->number;
} else if (rtype == oldresourcetype[R_IRON]
} else if (rtype == get_resourcetype(R_IRON)
&& u_race(u) == new_race[RC_IRONGOLEM] && delta <= 0) {
int reduce = delta / GOLEM_IRON;
if (delta % GOLEM_IRON != 0)
@ -598,11 +598,24 @@ give_money(unit * s, unit * d, const item_type * itype, int n,
#define MAXLUXURIES (LASTLUXURY - FIRSTLUXURY)
const item_type *olditemtype[MAXITEMS + 1];
const resource_type *oldresourcetype[MAXRESOURCES + 1];
const potion_type *oldpotiontype[MAXPOTIONS + 1];
/*** alte items ***/
const char *itemnames[MAX_RESOURCES] = {
"iron", "stone", "horse", "ao_healing",
"aots", "roi", "rop", "ao_chastity",
"laen", "fairyboot", "aoc", "pegasus",
"elvenhorse", "dolphin", "roqf", "trollbelt",
"presspass", "aurafocus", "sphereofinv", "magicbag",
"magicherbbag", "dreameye", "money", "aura", "permaura"
};
const resource_type *get_resourcetype(resource_t type) {
const resource_type *rtype = rt_find(itemnames[type]);
return rtype;
}
int get_item(const unit * u, item_t it)
{
const item_type *type = olditemtype[it];
@ -698,15 +711,6 @@ typedef struct t_item {
struct order *);
} t_item;
const char *itemnames[MAXITEMS] = {
"iron", "stone", "horse", "ao_healing",
"aots", "roi", "rop", "ao_chastity",
"laen", "fairyboot", "aoc", "pegasus",
"elvenhorse", "dolphin", "roqf", "trollbelt",
"presspass", "aurafocus", "sphereofinv", "magicbag",
"magicherbbag", "dreameye"
};
#include "move.h"
static int
@ -737,7 +741,6 @@ static void init_olditems(void)
if (itype) {
olditemtype[i] = itype;
oldresourcetype[i] = itype->rtype;
}
}
}
@ -970,26 +973,25 @@ static const char *names[] = {
void init_resources(void)
{
resource_type *rtype;
if (r_hp) {
return;
}
resource_type *rtype;
if (r_hp) {
// we have done this already
return;
}
rtype = new_resourcetype(names + 8, NULL, RTF_NONE);
rtype->uchange = res_changepeasants;
rt_register(rtype);
/* silver was never an item: */
r_silver = new_resourcetype(&names[0], NULL, RTF_ITEM | RTF_POOLED);
i_silver = new_itemtype(r_silver, ITF_NONE, 1 /*weight */ , 0);
r_silver->uchange = res_changeitem;
i_silver->give = give_money;
oldresourcetype[R_SILVER] = r_silver;
rt_register(r_silver);
r_permaura = new_resourcetype(&names[4], NULL, RTF_NONE);
r_permaura->uchange = res_changepermaura;
rt_register(r_permaura);
oldresourcetype[R_PERMAURA] = r_permaura;
r_hp = new_resourcetype(&names[6], NULL, RTF_NONE);
r_hp->uchange = res_changehp;
@ -998,7 +1000,6 @@ void init_resources(void)
r_aura = new_resourcetype(&names[10], NULL, RTF_NONE);
r_aura->uchange = res_changeaura;
rt_register(r_aura);
oldresourcetype[R_AURA] = r_aura;
r_unit = new_resourcetype(&names[12], NULL, RTF_NONE);
r_unit->uchange = res_changeperson;
@ -1211,7 +1212,6 @@ void test_clear_resources(void)
int i;
memset((void *)olditemtype, 0, sizeof(olditemtype));
memset((void *)oldresourcetype, 0, sizeof(oldresourcetype));
memset((void *)oldpotiontype, 0, sizeof(oldpotiontype));
cb_foreach(&cb_items, "", 0, free_itype_cb, 0);

View File

@ -300,7 +300,7 @@ extern "C" {
MAX_ITEMS /* do not use outside item.c ! */
};
enum {
typedef enum {
/* ITEMS: */
R_IRON,
R_STONE,
@ -332,11 +332,11 @@ extern "C" {
MAX_RESOURCES, /* do not use outside item.c ! */
NORESOURCE = -1
};
} resource_t;
extern const struct potion_type *oldpotiontype[];
extern const struct item_type *olditemtype[];
extern const struct resource_type *oldresourcetype[];
const struct resource_type *get_resourcetype(resource_t type);
int get_item(const struct unit *, item_t);
int set_item(struct unit *, item_t, int);

View File

@ -66,9 +66,9 @@ int get_resource(const unit * u, const resource_type * rtype)
return 0;
}
}
if (rtype == oldresourcetype[R_AURA])
if (rtype == get_resourcetype(R_AURA))
return get_spellpoints(u);
if (rtype == oldresourcetype[R_PERMAURA])
if (rtype == get_resourcetype(R_PERMAURA))
return max_spellpoints(u->region, u);
log_error("trying to get unknown resource '%s'.\n", rtype->_name[0]);
return 0;
@ -80,9 +80,9 @@ int change_resource(unit * u, const resource_type * rtype, int change)
if (rtype->uchange)
i = rtype->uchange(u, rtype, change);
else if (rtype == oldresourcetype[R_AURA])
else if (rtype == get_resourcetype(R_AURA))
i = change_spellpoints(u, change);
else if (rtype == oldresourcetype[R_PERMAURA])
else if (rtype == get_resourcetype(R_PERMAURA))
i = change_maxspellpoints(u, change);
else
assert(!"undefined resource detected. rtype->uchange not initialized.");
@ -98,9 +98,9 @@ int get_reservation(const unit * u, const resource_type * rtype)
{
reservation *res = u->reservations;
if (rtype == oldresourcetype[R_STONE] && (u_race(u)->flags & RCF_STONEGOLEM))
if (rtype == get_resourcetype(R_STONE) && (u_race(u)->flags & RCF_STONEGOLEM))
return (u->number * GOLEM_STONE);
if (rtype == oldresourcetype[R_IRON] && (u_race(u)->flags & RCF_IRONGOLEM))
if (rtype == get_resourcetype(R_IRON) && (u_race(u)->flags & RCF_IRONGOLEM))
return (u->number * GOLEM_IRON);
while (res && res->type != rtype)
res = res->next;

View File

@ -133,7 +133,7 @@ enter_arena(unit * u, const item_type * itype, int amount, order * ord)
return -1;
if (u->number != 1 && enter_fail(u))
return -1;
if (get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, fee) < fee
if (get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, fee) < fee
&& enter_fail(u))
return -1;
for (sk = 0; sk != MAXSKILLS; ++sk) {
@ -166,7 +166,7 @@ enter_arena(unit * u, const item_type * itype, int amount, order * ord)
ADDMSG(&u->faction->msgs, msg_message("arena_enter_fail", "region unit",
u->region, u));
use_pooled(u, itype->rtype, GET_SLACK | GET_RESERVE, 1);
use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, fee);
use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, fee);
set_money(u, 109);
fset(u, UFL_ANON_FACTION);
move_unit(u, start_region[rng_int() % 6], NULL);

View File

@ -78,11 +78,11 @@ static void reduce_weight(unit * u)
{
int capacity, weight = 0;
item **itmp = &u->items;
int horses = get_resource(u, oldresourcetype[R_HORSE]);
int horses = get_resource(u, get_resourcetype(R_HORSE));
if (horses > 0) {
horses = _min(horses, (u->number * 2));
change_resource(u, oldresourcetype[R_HORSE], -horses);
change_resource(u, get_resourcetype(R_HORSE), -horses);
}
/* 0. ditch any vehicles */

View File

@ -240,8 +240,10 @@ void find_manual(region * r, unit * u)
slprintf(zBook, sizeof(zLocation), "manual_title_%s", skillnames[skill]);
msg = msg_message("find_manual", "unit location book", u, zLocation, zBook);
r_addmessage(r, u->faction, msg);
msg_release(msg);
if (msg) {
r_addmessage(r, u->faction, msg);
msg_release(msg);
}
if (improve_all(u->faction, skill, 3) == 3) {
int i;

View File

@ -1035,7 +1035,7 @@ static void describe(FILE * F, const seen_region * sr, faction * f)
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
bytes =
(int)strlcpy(bufp, LOC(f->locale, resourcename(oldresourcetype[R_SILVER],
(int)strlcpy(bufp, LOC(f->locale, resourcename(get_resourcetype(R_SILVER),
rmoney(r) != 1)), size);
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
@ -1047,7 +1047,7 @@ static void describe(FILE * F, const seen_region * sr, faction * f)
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();
bytes =
(int)strlcpy(bufp, LOC(f->locale, resourcename(oldresourcetype[R_HORSE],
(int)strlcpy(bufp, LOC(f->locale, resourcename(get_resourcetype(R_HORSE),
(rhorses(r) > 1) ? GR_PLURAL : 0)), size);
if (wrptr(&bufp, &size, bytes) != 0)
WARN_STATIC_BUFFER();

View File

@ -326,7 +326,7 @@ int sp_combatrosthauch(struct castorder * co)
requirement *mat = wp->type->itype->construction->materials;
bool iron = false;
while (mat && mat->number > 0) {
if (mat->rtype == oldresourcetype[R_IRON]) {
if (mat->rtype == get_resourcetype(R_IRON)) {
iron = true;
break;
}
@ -1578,7 +1578,7 @@ int sp_reanimate(struct castorder * co)
if (use_item) {
msg =
msg_message("reanimate_effect_1", "mage amount item", mage, j,
oldresourcetype[R_AMULET_OF_HEALING]);
get_resourcetype(R_AMULET_OF_HEALING));
} else {
msg = msg_message("reanimate_effect_0", "mage amount", mage, j);
}
@ -1682,7 +1682,7 @@ int sp_healing(struct castorder * co)
if (use_item) {
msg =
msg_message("healing_effect_1", "mage amount item", mage, j,
oldresourcetype[R_AMULET_OF_HEALING]);
get_resourcetype(R_AMULET_OF_HEALING));
} else {
msg = msg_message("healing_effect_0", "mage amount", mage, j);
}

View File

@ -225,7 +225,7 @@ teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
int j = study_cost(student, sk);
j = _max(50, j * 2);
/* kann Einheit das zahlen? */
if (get_pooled(student, oldresourcetype[R_SILVER], GET_DEFAULT, j) >= j) {
if (get_pooled(student, get_resourcetype(R_SILVER), GET_DEFAULT, j) >= j) {
/* Jeder Schueler zusaetzlich +10 Tage wenn in Uni. */
teach->value += (n / 30) * 10; /* learning erhoehen */
/* Lehrer zusaetzlich +1 Tag pro Schueler. */
@ -684,7 +684,7 @@ int learn_cmd(unit * u, order * ord)
}
if (studycost) {
int cost = studycost * u->number;
money = get_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, cost);
money = get_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, cost);
money = _min(money, cost);
}
if (money < studycost * u->number) {
@ -702,7 +702,7 @@ int learn_cmd(unit * u, order * ord)
teach->teachers[0] = 0;
}
if (money > 0) {
use_pooled(u, oldresourcetype[R_SILVER], GET_DEFAULT, money);
use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, money);
ADDMSG(&u->faction->msgs, msg_message("studycost",
"unit region cost skill", u, u->region, money, sk));
}

View File

@ -13,16 +13,19 @@ static void test_recreate_world(CuTest * tc)
{
test_cleanup();
CuAssertPtrEquals(tc, 0, get_locale("de"));
CuAssertPtrEquals(tc, 0, it_find("money"));
CuAssertPtrEquals(tc, 0, it_find("horse"));
CuAssertPtrNotNull(tc, rt_find("hp"));
CuAssertPtrNotNull(tc, rt_find("permaura"));
CuAssertPtrNotNull(tc, rt_find("aura"));
CuAssertPtrNotNull(tc, it_find("money"));
test_create_world();
CuAssertPtrEquals(tc, default_locale, get_locale("de"));
CuAssertPtrNotNull(tc, default_locale);
CuAssertPtrNotNull(tc, findregion(0, 0));
CuAssertPtrNotNull(tc, it_find("money"));
CuAssertPtrNotNull(tc, it_find("horse"));
CuAssertPtrNotNull(tc, rt_find("horse"));
CuAssertPtrNotNull(tc, it_find("money"));
CuAssertPtrNotNull(tc, rt_find("hp"));
CuAssertPtrNotNull(tc, rt_find("money"));
CuAssertPtrNotNull(tc, rt_find("aura"));
@ -32,15 +35,15 @@ static void test_recreate_world(CuTest * tc)
test_cleanup();
CuAssertPtrEquals(tc, 0, get_locale("de"));
CuAssertPtrEquals(tc, 0, it_find("money"));
CuAssertPtrEquals(tc, 0, it_find("horse"));
CuAssertPtrEquals(tc, 0, rt_find("horse"));
CuAssertPtrEquals(tc, 0, rt_find("hp"));
CuAssertPtrEquals(tc, 0, rt_find("money"));
CuAssertPtrEquals(tc, 0, rt_find("aura"));
CuAssertPtrEquals(tc, 0, rt_find("permaura"));
CuAssertPtrEquals(tc, 0, rt_find("peasant"));
CuAssertPtrEquals(tc, 0, rt_find("unit"));
CuAssertPtrNotNull(tc, it_find("money"));
CuAssertPtrNotNull(tc, rt_find("hp"));
CuAssertPtrNotNull(tc, rt_find("money"));
CuAssertPtrNotNull(tc, rt_find("aura"));
CuAssertPtrNotNull(tc, rt_find("permaura"));
CuAssertPtrNotNull(tc, rt_find("peasant"));
CuAssertPtrNotNull(tc, rt_find("unit"));
CuAssertPtrEquals(tc, 0, findregion(0, 0));
}

View File

@ -23,11 +23,15 @@ function test_study()
assert_equal(1, u:get_skill("crossbow"))
end
function dsabled_test_study_expensive()
function test_study_expensive()
local r = region.create(0, 0, "plain")
local f = faction.create("test@example.com", "human", "de")
local u = unit.create(f, r, 1)
eressea.settings.set("skills.cost.alchemy", "50")
eressea.settings.set("rules.encounters", "0")
u:add_order("LERNEN Alchemie")
u:add_item("money", 50)
process_orders()
assert_equal(1, u:get_skill("alchemy"))
assert_equal(0, u:get_item("money"))
end