Merge pull request #728 from ennorehling/develop

bugfixes, sea serpents
This commit is contained in:
Enno Rehling 2017-09-09 19:10:43 +02:00 committed by GitHub
commit 1413c2807d
10 changed files with 209 additions and 154 deletions

View File

@ -830,7 +830,7 @@
<attack type="1" damage="1d7"/> <attack type="1" damage="1d7"/>
</race> </race>
<race name="shadowknight" maxaura="0.000000" regaura="0.000000" weight="1000" capacity="540" speed="1.0" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noblock="yes"> <race name="shadowknight" maxaura="0.000000" regaura="0.000000" weight="0" capacity="540" speed="1.0" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noblock="yes">
<ai splitsize="20000" moverandom="yes"/> <ai splitsize="20000" moverandom="yes"/>
<attack type="1" damage="1d1"/> <attack type="1" damage="1d1"/>
</race> </race>

View File

@ -1071,7 +1071,7 @@
<skill name="unarmed" modifier="1"/> <skill name="unarmed" modifier="1"/>
<attack type="1" damage="1d7"/> <attack type="1" damage="1d7"/>
</race> </race>
<race name="shadowknight" maxaura="0.000000" regaura="0.000000" weight="1000" capacity="540" speed="1.000000" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noblock="yes"> <race name="shadowknight" maxaura="0.000000" regaura="0.000000" weight="0" capacity="540" speed="1.000000" hp="1" damage="1d1" unarmedattack="0" unarmeddefense="0" attackmodifier="1" defensemodifier="1" scarepeasants="yes" walk="yes" canlearn="no" teach="no" noblock="yes">
<ai splitsize="20000" moverandom="yes"/> <ai splitsize="20000" moverandom="yes"/>
<attack type="1" damage="1d1"/> <attack type="1" damage="1d1"/>
</race> </race>

View File

@ -19,44 +19,49 @@ local function create_item(mage, level, name, number)
return level return level
end end
local function create_potion(mage, level, name, force)
count = math.floor(force * 2 + 0.5)
return create_item(mage, level, name, count)
end
-- Wasser des Lebens -- Wasser des Lebens
function create_potion_p2(r, mage, level, force) function create_potion_p2(r, mage, level, force)
return create_item(mage, level, "p2", level) return create_potion(mage, level, "p2", force)
end end
-- Siebenmeilentee -- Siebenmeilentee
function create_potion_p0(r, mage, level, force) function create_potion_p0(r, mage, level, force)
return create_item(mage, level, "p0", level) return create_potion(mage, level, "p0", force)
end end
-- Wundsalbe -- Wundsalbe
function create_potion_ointment(r, mage, level, force) function create_potion_ointment(r, mage, level, force)
return create_item(mage, level, "ointment", level) return create_potion(mage, level, "ointment", force)
end end
-- Bauernblut -- Bauernblut
function create_potion_peasantblood(r, mage, level, force) function create_potion_peasantblood(r, mage, level, force)
return create_item(mage, level, "peasantblood", level) return create_potion(mage, level, "peasantblood", force)
end end
-- Pferdeglueck -- Pferdeglueck
function create_potion_p9(r, mage, level, force) function create_potion_p9(r, mage, level, force)
return create_item(mage, level, "p9", level) return create_potion(mage, level, "p9", force)
end end
-- Schaffenstrunk -- Schaffenstrunk
function create_potion_p3(r, mage, level, force) function create_potion_p3(r, mage, level, force)
return create_item(mage, level, "p3", level) return create_potion(mage, level, "p3", force)
end end
-- Heiltrank -- Heiltrank
function create_potion_p14(r, mage, level, force) function create_potion_p14(r, mage, level, force)
return create_item(mage, level, "p14", level) return create_potion(mage, level, "p14", force)
end end
-- Elixier der Macht -- Elixier der Macht
function create_potion_p13(r, mage, level, force) function create_potion_p13(r, mage, level, force)
return create_item(mage, level, "p13", level) return create_potion(mage, level, "p13", force)
end end
-- Erschaffe ein Flammenschwert -- Erschaffe ein Flammenschwert

View File

@ -8,6 +8,7 @@ function setup()
eressea.settings.set("rules.food.flags", "4") eressea.settings.set("rules.food.flags", "4")
eressea.settings.set("rules.ship.storms", "0") eressea.settings.set("rules.ship.storms", "0")
eressea.settings.set("rules.encounters", "0") eressea.settings.set("rules.encounters", "0")
eressea.settings.set("study.produceexp", "0")
end end
function test_calendar() function test_calendar()
@ -57,6 +58,7 @@ function test_dwarf_bonus()
u.building = building.create(r, "mine") u.building = building.create(r, "mine")
u.building.size = 10 u.building.size = 10
u:add_item("money", 500) -- maintenance u:add_item("money", 500) -- maintenance
assert_equal(1, u:get_skill("mining"))
process_orders() process_orders()
assert_equal(70, u:get_item("iron")) assert_equal(70, u:get_item("iron"))
assert_equal(70, r:get_resource("iron")) assert_equal(70, r:get_resource("iron"))

View File

@ -101,7 +101,6 @@ struct locale *crtag_locale(void) {
static const char *crtag(const char *key) static const char *crtag(const char *key)
{ {
/* TODO: those locale lookups are shit, but static kills testing */
const char *result; const char *result;
result = LOC(crtag_locale(), key); result = LOC(crtag_locale(), key);
return result; return result;
@ -382,8 +381,8 @@ static int cr_skill(variant var, char *buffer, const void *userdata)
UNUSED_ARG(userdata); UNUSED_ARG(userdata);
if (sk != NOSKILL) if (sk != NOSKILL)
sprintf(buffer, "\"%s\"", sprintf(buffer, "\"%s\"",
translate(mkname("skill", skillnames[sk]), skillname(sk, translate(mkname("skill", skillnames[sk]), skillname(sk,
report->locale))); report->locale)));
else else
strcpy(buffer, "\"\""); strcpy(buffer, "\"\"");
return 0; return 0;
@ -426,7 +425,7 @@ static int cr_resources(variant var, char *buffer, const void *userdata)
assert(name); assert(name);
wp += wp +=
sprintf(wp, "\"%d %s", rlist->number, translate(name, LOC(f->locale, sprintf(wp, "\"%d %s", rlist->number, translate(name, LOC(f->locale,
name))); name)));
for (;;) { for (;;) {
rlist = rlist->next; rlist = rlist->next;
if (rlist == NULL) if (rlist == NULL)
@ -435,7 +434,7 @@ static int cr_resources(variant var, char *buffer, const void *userdata)
assert(name); assert(name);
wp += wp +=
sprintf(wp, ", %d %s", rlist->number, translate(name, sprintf(wp, ", %d %s", rlist->number, translate(name,
LOC(f->locale, name))); LOC(f->locale, name)));
} }
strcat(wp, "\""); strcat(wp, "\"");
} }
@ -621,86 +620,106 @@ static void cr_output_messages(FILE * F, message_list * msgs, faction * f)
} }
/* prints a building */ /* prints a building */
static void static void cr_output_building(struct stream *out, building *b,
cr_output_building(FILE * F, building * b, const unit * owner, int fno, const unit *owner, int fno, faction *f)
faction * f)
{ {
const char *bname, *billusion; const char *bname, *billusion;
fprintf(F, "BURG %d\n", b->no); stream_printf(out, "BURG %d\n", b->no);
report_building(b, &bname, &billusion); report_building(b, &bname, &billusion);
if (billusion) { if (billusion) {
fprintf(F, "\"%s\";Typ\n", translate(billusion, LOC(f->locale, stream_printf(out, "\"%s\";Typ\n", translate(billusion, LOC(f->locale,
billusion))); billusion)));
if (owner && owner->faction == f) { if (owner && owner->faction == f) {
fprintf(F, "\"%s\";wahrerTyp\n", translate(bname, LOC(f->locale, stream_printf(out, "\"%s\";wahrerTyp\n", translate(bname, LOC(f->locale,
bname))); bname)));
} }
} }
else { else {
fprintf(F, "\"%s\";Typ\n", translate(bname, LOC(f->locale, bname))); stream_printf(out, "\"%s\";Typ\n", translate(bname, LOC(f->locale, bname)));
}
stream_printf(out, "\"%s\";Name\n", b->name);
if (b->display && b->display[0]) {
stream_printf(out, "\"%s\";Beschr\n", b->display);
}
if (b->size) {
stream_printf(out, "%d;Groesse\n", b->size);
} }
fprintf(F, "\"%s\";Name\n", b->name);
if (b->display && b->display[0])
fprintf(F, "\"%s\";Beschr\n", b->display);
if (b->size)
fprintf(F, "%d;Groesse\n", b->size);
if (owner) { if (owner) {
fprintf(F, "%d;Besitzer\n", owner->no); stream_printf(out, "%d;Besitzer\n", owner->no);
} }
if (fno >= 0) if (fno >= 0) {
fprintf(F, "%d;Partei\n", fno); stream_printf(out, "%d;Partei\n", fno);
if (b->besieged) }
fprintf(F, "%d;Belagerer\n", b->besieged); if (b->besieged) {
cr_output_curses_compat(F, f, b, TYP_BUILDING); stream_printf(out, "%d;Belagerer\n", b->besieged);
}
cr_output_curses(out, f, b, TYP_BUILDING);
}
static void cr_output_building_compat(FILE *F, building *b,
const unit *owner, int fno, faction *f)
{
/* TODO: eliminate this function */
stream strm;
fstream_init(&strm, F);
cr_output_building(&strm, b, owner, fno, f);
} }
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ /* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
/* prints a ship */ /* prints a ship */
static void static void cr_output_ship(struct stream *out, const ship *sh, const unit *u,
cr_output_ship(FILE * F, const ship * sh, const unit * u, int fcaptain, int fcaptain, const faction *f, const region *r)
const faction * f, const region * r)
{ {
int w = 0; int w = 0;
assert(sh); assert(sh);
fprintf(F, "SCHIFF %d\n", sh->no); stream_printf(out, "SCHIFF %d\n", sh->no);
fprintf(F, "\"%s\";Name\n", sh->name); stream_printf(out, "\"%s\";Name\n", sh->name);
if (sh->display && sh->display[0]) if (sh->display && sh->display[0])
fprintf(F, "\"%s\";Beschr\n", sh->display); stream_printf(out, "\"%s\";Beschr\n", sh->display);
fprintf(F, "\"%s\";Typ\n", translate(sh->type->_name, stream_printf(out, "\"%s\";Typ\n", translate(sh->type->_name,
LOC(f->locale, sh->type->_name))); LOC(f->locale, sh->type->_name)));
fprintf(F, "%d;Groesse\n", sh->size); stream_printf(out, "%d;Groesse\n", sh->size);
if (sh->damage) { if (sh->damage) {
int percent = int percent =
(sh->damage * 100 + DAMAGE_SCALE - 1) / (sh->size * DAMAGE_SCALE); (sh->damage * 100 + DAMAGE_SCALE - 1) / (sh->size * DAMAGE_SCALE);
fprintf(F, "%d;Schaden\n", percent); stream_printf(out, "%d;Schaden\n", percent);
} }
if (u) { if (u) {
fprintf(F, "%d;Kapitaen\n", u->no); stream_printf(out, "%d;Kapitaen\n", u->no);
}
if (fcaptain >= 0) {
stream_printf(out, "%d;Partei\n", fcaptain);
} }
if (fcaptain >= 0)
fprintf(F, "%d;Partei\n", fcaptain);
/* calculate cargo */ /* calculate cargo */
if (u && (u->faction == f || omniscient(f))) { if (u && (u->faction == f || omniscient(f))) {
int n = 0, p = 0; int n = 0, p = 0;
int mweight = shipcapacity(sh); int mweight = shipcapacity(sh);
getshipweight(sh, &n, &p); getshipweight(sh, &n, &p);
fprintf(F, "%d;capacity\n", mweight); stream_printf(out, "%d;capacity\n", mweight);
fprintf(F, "%d;cargo\n", n); stream_printf(out, "%d;cargo\n", n);
fprintf(F, "%d;speed\n", shipspeed(sh, u)); stream_printf(out, "%d;speed\n", shipspeed(sh, u));
} }
/* shore */ /* shore */
w = NODIRECTION; w = NODIRECTION;
if (!fval(r->terrain, SEA_REGION)) if (!fval(r->terrain, SEA_REGION))
w = sh->coast; w = sh->coast;
if (w != NODIRECTION) if (w != NODIRECTION)
fprintf(F, "%d;Kueste\n", w); stream_printf(out, "%d;Kueste\n", w);
cr_output_curses_compat(F, f, sh, TYP_SHIP); cr_output_curses(out, f, sh, TYP_SHIP);
}
static void cr_output_ship_compat(FILE *F, const ship *sh, const unit *u,
int fcaptain, const faction *f, const region *r)
{
/* TODO: eliminate this function */
stream strm;
fstream_init(&strm, F);
cr_output_ship(&strm, sh, u, fcaptain, f, r);
} }
static int stream_order(stream *out, const struct order *ord) { static int stream_order(stream *out, const struct order *ord) {
@ -798,11 +817,12 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
if (fother) { if (fother) {
stream_printf(out, "%d;Anderepartei\n", fother->no); stream_printf(out, "%d;Anderepartei\n", fother->no);
} }
} else if (!fval(u, UFL_ANON_FACTION)) { }
else if (!fval(u, UFL_ANON_FACTION)) {
/* OBS: anonymity overrides everything */ /* OBS: anonymity overrides everything */
/* we have no alliance, so we get duped */ /* we have no alliance, so we get duped */
stream_printf(out, "%d;Partei\n", (fother ? fother : u->faction)->no); stream_printf(out, "%d;Partei\n", (fother ? fother : u->faction)->no);
if (fother==f) { if (fother == f) {
/* sieht aus wie unsere, ist es aber nicht. */ /* sieht aus wie unsere, ist es aber nicht. */
stream_printf(out, "1;Verraeter\n"); stream_printf(out, "1;Verraeter\n");
} }
@ -929,7 +949,7 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
} }
stream_printf(out, "%d %d;%s\n", u->number * level_days(sv->level), esk, stream_printf(out, "%d %d;%s\n", u->number * level_days(sv->level), esk,
translate(mkname("skill", skillnames[sk]), skillname(sk, translate(mkname("skill", skillnames[sk]), skillname(sk,
f->locale))); f->locale)));
} }
} }
@ -944,7 +964,7 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
if (sp) { if (sp) {
const char *name = const char *name =
translate(mkname("spell", sp->sname), spell_name(sp, translate(mkname("spell", sp->sname), spell_name(sp,
f->locale)); f->locale));
stream_printf(out, "KAMPFZAUBER %d\n", i); stream_printf(out, "KAMPFZAUBER %d\n", i);
stream_printf(out, "\"%s\";name\n", name); stream_printf(out, "\"%s\";name\n", name);
stream_printf(out, "%d;level\n", mage->combatspells[i].level); stream_printf(out, "%d;level\n", mage->combatspells[i].level);
@ -1201,7 +1221,7 @@ void cr_output_resources(stream *out, const faction * f, const region *r, bool s
if (result[n].number >= 0) { if (result[n].number >= 0) {
pos = pos =
cr_output_resource(pos, result[n].rtype, f->locale, result[n].number, cr_output_resource(pos, result[n].rtype, f->locale, result[n].number,
result[n].level); result[n].level);
} }
} }
if (pos != cbuf) { if (pos != cbuf) {
@ -1458,7 +1478,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r)
const faction *sf = visible_faction(f, u); const faction *sf = visible_faction(f, u);
fno = sf->no; fno = sf->no;
} }
cr_output_building(F, b, u, fno, f); cr_output_building_compat(F, b, u, fno, f);
} }
/* ships */ /* ships */
@ -1470,7 +1490,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r)
fno = sf->no; fno = sf->no;
} }
cr_output_ship(F, sh, u, fno, f, r); cr_output_ship_compat(F, sh, u, fno, f, r);
} }
/* visible units */ /* visible units */
@ -1516,7 +1536,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom)
fprintf(F, "VERSION %d\n", C_REPORT_VERSION); fprintf(F, "VERSION %d\n", C_REPORT_VERSION);
fprintf(F, "\"UTF-8\";charset\n\"%s\";locale\n", fprintf(F, "\"UTF-8\";charset\n\"%s\";locale\n",
locale_name(f->locale)); locale_name(f->locale));
fprintf(F, "%d;noskillpoints\n", 1); fprintf(F, "%d;noskillpoints\n", 1);
fprintf(F, "%lld;date\n", (long long)ctx->report_time); fprintf(F, "%lld;date\n", (long long)ctx->report_time);
fprintf(F, "\"%s\";Spiel\n", game_name()); fprintf(F, "\"%s\";Spiel\n", game_name());
@ -1683,7 +1703,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom)
} }
} }
report_crtypes(F, f->locale); report_crtypes(F, f->locale);
if (f->locale!=crtag_locale()) { if (f->locale != crtag_locale()) {
report_translations(F); report_translations(F);
} }
reset_translations(); reset_translations();

View File

@ -29,6 +29,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* util includes */ /* util includes */
#include <selist.h> #include <selist.h>
#include <critbit.h>
#include <util/rand.h> #include <util/rand.h>
#include <util/rng.h> #include <util/rng.h>
@ -37,43 +38,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
static equipment *equipment_sets;
equipment *get_or_create_equipment(const char *eqname)
{
equipment **eqp = &equipment_sets;
for (;;) {
struct equipment *eq = *eqp;
int i = eq ? strcmp(eq->name, eqname) : 1;
if (i > 0) {
eq = (equipment *)calloc(1, sizeof(equipment));
eq->name = strdup(eqname);
eq->next = *eqp;
memset(eq->skills, 0, sizeof(eq->skills));
*eqp = eq;
break;
}
else if (i == 0) {
break;
}
eqp = &eq->next;
}
return *eqp;
}
equipment *get_equipment(const char *eqname)
{
equipment *eq = equipment_sets;
for (; eq; eq = eq->next) {
int i = strcmp(eq->name, eqname);
if (i == 0)
return eq;
else if (i > 0)
break;
}
return NULL;
}
void equipment_setskill(equipment * eq, skill_t sk, const char *value) void equipment_setskill(equipment * eq, skill_t sk, const char *value)
{ {
if (eq != NULL) { if (eq != NULL) {
@ -236,27 +200,65 @@ void free_ls(void *arg) {
free(ls); free(ls);
} }
void equipment_done(void) { static critbit_tree cb_equipments = { 0 };
equipment **eqp = &equipment_sets;
while (*eqp) { equipment *get_equipment(const char *eqname)
int i; {
equipment *eq = *eqp; const char *match;
*eqp = eq->next; equipment *eq = NULL;
free(eq->name);
if (eq->spells) { match = cb_find_str(&cb_equipments, eqname);
selist_foreach(eq->spells, free_ls); if (match) {
selist_free(eq->spells); cb_get_kv(match, &eq, sizeof(eq));
} }
while (eq->items) { return eq;
itemdata *next = eq->items->next; }
free(eq->items->value);
free(eq->items); equipment *get_or_create_equipment(const char *eqname)
eq->items = next; {
} equipment *eq = get_equipment(eqname);
/* TODO: subsets, skills */ if (!eq) {
for (i=0;i!=MAXSKILLS;++i) { size_t len;
free(eq->skills[i]); char data[64];
}
free(eq); eq = (equipment *)calloc(1, sizeof(equipment));
eq->name = strdup(eqname);
len = cb_new_kv(eqname, strlen(eqname), &eq, sizeof(eq), data);
assert(len <= sizeof(data));
cb_insert(&cb_equipments, data, len);
}
return eq;
}
static void free_equipment(equipment *eq) {
int i;
free(eq->name);
if (eq->spells) {
selist_foreach(eq->spells, free_ls);
selist_free(eq->spells);
}
while (eq->items) {
itemdata *next = eq->items->next;
free(eq->items->value);
free(eq->items);
eq->items = next;
}
/* TODO: subsets, skills */
for (i = 0; i != MAXSKILLS; ++i) {
free(eq->skills[i]);
} }
} }
static int free_equipment_cb(const void * match, const void * key, size_t keylen, void *cbdata) {
equipment *eq;
cb_get_kv(match, &eq, sizeof(eq));
free_equipment(eq);
free(eq);
return 0;
}
void equipment_done(void) {
cb_foreach(&cb_equipments, "", 0, free_equipment_cb, 0);
cb_clear(&cb_equipments);
}

View File

@ -50,7 +50,6 @@ extern "C" {
char *skills[MAXSKILLS]; char *skills[MAXSKILLS];
struct selist *spells; struct selist *spells;
struct subset *subsets; struct subset *subsets;
struct equipment *next;
void(*callback) (const struct equipment *, struct unit *); void(*callback) (const struct equipment *, struct unit *);
} equipment; } equipment;

View File

@ -49,6 +49,7 @@
#include <kernel/pool.h> #include <kernel/pool.h>
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/ship.h>
#include <kernel/terrain.h> #include <kernel/terrain.h>
#include <kernel/terrainid.h> #include <kernel/terrainid.h>
#include <kernel/unit.h> #include <kernel/unit.h>
@ -191,6 +192,7 @@ void monsters_desert(struct faction *monsters)
int monster_attacks(unit * monster, bool rich_only) int monster_attacks(unit * monster, bool rich_only)
{ {
const race *rc_serpent = get_race(RC_SEASERPENT);
if (monster->status < ST_AVOID) { if (monster->status < ST_AVOID) {
region *r = monster->region; region *r = monster->region;
unit *u2; unit *u2;
@ -199,6 +201,12 @@ int monster_attacks(unit * monster, bool rich_only)
for (u2 = r->units; u2; u2 = u2->next) { for (u2 = r->units; u2; u2 = u2->next) {
if (u2->faction != monster->faction && cansee(monster->faction, r, u2, 0) && !in_safe_building(u2, monster)) { if (u2->faction != monster->faction && cansee(monster->faction, r, u2, 0) && !in_safe_building(u2, monster)) {
int m = get_money(u2); int m = get_money(u2);
if (u_race(monster) == rc_serpent) {
/* attack bigger ships only */
if (!u2->ship || u2->ship->type->cargo <= 50000) {
continue;
}
}
if (!rich_only || m > 0) { if (!rich_only || m > 0) {
order *ord = monster_attack(monster, u2); order *ord = monster_attack(monster, u2);
if (ord) { if (ord) {

View File

@ -7,6 +7,8 @@
#include <kernel/order.h> #include <kernel/order.h>
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/region.h>
#include <kernel/ship.h>
#include <kernel/terrain.h> #include <kernel/terrain.h>
#include <kernel/unit.h> #include <kernel/unit.h>
@ -41,43 +43,43 @@ static order *find_order(const char *expected, const unit *unit)
return NULL; return NULL;
} }
static void create_monsters(faction **player, faction **monsters, unit **u, unit **m) { static void create_monsters(unit **up, unit **um) {
race* rc; race* rc;
region *r; region *r;
faction *fp, *fm;
test_cleanup(); test_cleanup();
test_create_horse(); test_create_horse();
default_locale = test_create_locale(); default_locale = test_create_locale();
*player = test_create_faction(NULL); fp = test_create_faction(NULL);
*monsters = get_or_create_monsters(); fm = get_or_create_monsters();
assert(rc_find((*monsters)->race->_name)); assert(rc_find(fm->race->_name));
rc = rc_get_or_create((*monsters)->race->_name); rc = rc_get_or_create(fm->race->_name);
fset(rc, RCF_UNARMEDGUARD|RCF_NPC|RCF_DRAGON); fset(rc, RCF_UNARMEDGUARD|RCF_NPC|RCF_DRAGON);
fset(*monsters, FFL_NOIDLEOUT); fset(fm, FFL_NOIDLEOUT);
assert(fval(*monsters, FFL_NPC) && fval((*monsters)->race, RCF_UNARMEDGUARD) && fval((*monsters)->race, RCF_NPC) && fval(*monsters, FFL_NOIDLEOUT)); assert(fval(fm, FFL_NPC) && fval(fm->race, RCF_UNARMEDGUARD) && fval(fm->race, RCF_NPC) && fval(fm, FFL_NOIDLEOUT));
test_create_region(-1, 0, test_create_terrain("ocean", SEA_REGION | SWIM_INTO | FLY_INTO)); test_create_region(-1, 0, test_create_terrain("ocean", SEA_REGION | SWIM_INTO | FLY_INTO));
test_create_region(1, 0, 0); test_create_region(1, 0, 0);
r = test_create_region(0, 0, 0); r = test_create_region(0, 0, 0);
*u = test_create_unit(*player, r); *up = test_create_unit(fp, r);
unit_setid(*u, 1); unit_setid(*up, 1);
*m = test_create_unit(*monsters, r); *um = test_create_unit(fm, r);
unit_setstatus(*m, ST_FIGHT); unit_setstatus(*um, ST_FIGHT);
} }
static void test_monsters_attack(CuTest * tc) static void test_monsters_attack(CuTest * tc)
{ {
faction *f, *f2;
unit *u, *m; unit *u, *m;
create_monsters(&f, &f2, &u, &m); create_monsters(&u, &m);
setguard(m, true); setguard(m, true);
config_set("rules.monsters.attack_chance", "1"); config_set("rules.monsters.attack_chance", "1");
plan_monsters(f2); plan_monsters(m->faction);
CuAssertPtrNotNull(tc, find_order("attack 1", m)); CuAssertPtrNotNull(tc, find_order("attack 1", m));
test_cleanup(); test_cleanup();
@ -85,11 +87,10 @@ static void test_monsters_attack(CuTest * tc)
static void test_monsters_attack_ocean(CuTest * tc) static void test_monsters_attack_ocean(CuTest * tc)
{ {
faction *f, *f2;
region *r; region *r;
unit *u, *m; unit *u, *m;
create_monsters(&f, &f2, &u, &m); create_monsters(&u, &m);
r = findregion(-1, 0); /* ocean */ r = findregion(-1, 0); /* ocean */
u = test_create_unit(u->faction, r); u = test_create_unit(u->faction, r);
unit_setid(u, 2); unit_setid(u, 2);
@ -98,7 +99,7 @@ static void test_monsters_attack_ocean(CuTest * tc)
config_set("rules.monsters.attack_chance", "1"); config_set("rules.monsters.attack_chance", "1");
plan_monsters(f2); plan_monsters(m->faction);
CuAssertPtrNotNull(tc, find_order("attack 2", m)); CuAssertPtrNotNull(tc, find_order("attack 2", m));
test_cleanup(); test_cleanup();
@ -106,10 +107,9 @@ static void test_monsters_attack_ocean(CuTest * tc)
static void test_monsters_waiting(CuTest * tc) static void test_monsters_waiting(CuTest * tc)
{ {
faction *f, *f2;
unit *u, *m; unit *u, *m;
create_monsters(&f, &f2, &u, &m); create_monsters(&u, &m);
setguard(m, true); setguard(m, true);
fset(m, UFL_ISNEW); fset(m, UFL_ISNEW);
monster_attacks(m, false); monster_attacks(m, false);
@ -119,14 +119,16 @@ static void test_monsters_waiting(CuTest * tc)
static void test_seaserpent_piracy(CuTest * tc) static void test_seaserpent_piracy(CuTest * tc)
{ {
faction *f, *f2;
region *r; region *r;
unit *u, *m; unit *u, *m;
race *rc; race *rc;
ship_type * stype;
create_monsters(&f, &f2, &u, &m); create_monsters(&u, &m);
stype = test_create_shiptype("yacht");
r = findregion(-1, 0); /* ocean */ r = findregion(-1, 0); /* ocean */
u = test_create_unit(u->faction, r); u = test_create_unit(u->faction, r);
u->ship = test_create_ship(r, stype);
unit_setid(u, 2); unit_setid(u, 2);
m = test_create_unit(m->faction, r); m = test_create_unit(m->faction, r);
u_setrace(m, rc = test_create_race("seaserpent")); u_setrace(m, rc = test_create_race("seaserpent"));
@ -136,25 +138,28 @@ static void test_seaserpent_piracy(CuTest * tc)
config_set("rules.monsters.attack_chance", "1"); config_set("rules.monsters.attack_chance", "1");
plan_monsters(f2); stype->cargo = 50000;
plan_monsters(m->faction);
CuAssertPtrNotNull(tc, find_order("piracy", m)); CuAssertPtrNotNull(tc, find_order("piracy", m));
CuAssertPtrEquals(tc, NULL, find_order("attack 2", m));
stype->cargo = 50001;
plan_monsters(m->faction);
CuAssertPtrNotNull(tc, find_order("attack 2", m)); CuAssertPtrNotNull(tc, find_order("attack 2", m));
test_cleanup(); test_cleanup();
} }
static void test_monsters_attack_not(CuTest * tc) static void test_monsters_attack_not(CuTest * tc)
{ {
faction *f, *f2;
unit *u, *m; unit *u, *m;
create_monsters(&f, &f2, &u, &m); create_monsters(&u, &m);
setguard(m, true); setguard(m, true);
setguard(u, true); setguard(u, true);
config_set("rules.monsters.attack_chance", "0"); config_set("rules.monsters.attack_chance", "0");
plan_monsters(f2); plan_monsters(m->faction);
CuAssertPtrEquals(tc, 0, find_order("attack 1", m)); CuAssertPtrEquals(tc, 0, find_order("attack 1", m));
test_cleanup(); test_cleanup();
@ -162,11 +167,10 @@ static void test_monsters_attack_not(CuTest * tc)
static void test_dragon_attacks_the_rich(CuTest * tc) static void test_dragon_attacks_the_rich(CuTest * tc)
{ {
faction *f, *f2;
unit *u, *m; unit *u, *m;
const item_type *i_silver; const item_type *i_silver;
create_monsters(&f, &f2, &u, &m); create_monsters(&u, &m);
init_resources(); init_resources();
setguard(m, true); setguard(m, true);
@ -180,8 +184,7 @@ static void test_dragon_attacks_the_rich(CuTest * tc)
config_set("rules.monsters.attack_chance", "0.00001"); config_set("rules.monsters.attack_chance", "0.00001");
plan_monsters(f2); plan_monsters(m->faction);
CuAssertPtrNotNull(tc, find_order("attack 1", m)); CuAssertPtrNotNull(tc, find_order("attack 1", m));
CuAssertPtrNotNull(tc, find_order("loot", m)); CuAssertPtrNotNull(tc, find_order("loot", m));
test_cleanup(); test_cleanup();
@ -191,12 +194,11 @@ extern void random_growl(const unit *u, region *tr, int rand);
static void test_dragon_moves(CuTest * tc) static void test_dragon_moves(CuTest * tc)
{ {
faction *f, *f2;
region *r; region *r;
unit *u, *m; unit *u, *m;
struct message *msg; struct message *msg;
create_monsters(&f, &f2, &u, &m); create_monsters(&u, &m);
rsetmoney(findregion(1, 0), 1000); rsetmoney(findregion(1, 0), 1000);
r = findregion(0, 0); /* plain */ r = findregion(0, 0); /* plain */
rsetpeasants(r, 0); rsetpeasants(r, 0);
@ -204,8 +206,8 @@ static void test_dragon_moves(CuTest * tc)
set_level(m, SK_WEAPONLESS, 10); set_level(m, SK_WEAPONLESS, 10);
config_set("rules.monsters.attack_chance", ".0"); config_set("rules.monsters.attack_chance", ".0");
plan_monsters(f2);
plan_monsters(m->faction);
CuAssertPtrNotNull(tc, find_order("move east", m)); CuAssertPtrNotNull(tc, find_order("move east", m));
mt_register(mt_new_va("dragon_growl", "dragon:unit", "number:int", "target:region", "growl:string", 0)); mt_register(mt_new_va("dragon_growl", "dragon:unit", "number:int", "target:region", "growl:string", 0));
@ -224,11 +226,10 @@ static void test_dragon_moves(CuTest * tc)
static void test_monsters_learn_exp(CuTest * tc) static void test_monsters_learn_exp(CuTest * tc)
{ {
faction *f, *f2;
unit *u, *m; unit *u, *m;
skill* sk; skill* sk;
create_monsters(&f, &f2, &u, &m); create_monsters(&u, &m);
config_set("study.produceexp", "30"); config_set("study.produceexp", "30");
u_setrace(u, u_race(m)); u_setrace(u, u_race(m));

View File

@ -153,6 +153,23 @@ static void test_sparagraph(CuTest *tc) {
freestrlist(sp); freestrlist(sp);
} }
static void test_sparagraph_long(CuTest *tc) {
strlist *sp = 0;
split_paragraph(&sp, "HelloWorld HelloWorld", 0, 16, 0);
CuAssertPtrNotNull(tc, sp);
CuAssertStrEquals(tc, "HelloWorld", sp->s);
CuAssertStrEquals(tc, "HelloWorld", sp->next->s);
CuAssertPtrEquals(tc, NULL, sp->next->next);
freestrlist(sp);
split_paragraph(&sp, "HelloWorldHelloWorld", 0, 16, 0);
CuAssertPtrNotNull(tc, sp);
CuAssertStrEquals(tc, "HelloWorldHelloWorld", sp->s);
CuAssertPtrEquals(tc, NULL, sp->next);
freestrlist(sp);
}
static void test_bufunit_fstealth(CuTest *tc) { static void test_bufunit_fstealth(CuTest *tc) {
faction *f1, *f2; faction *f1, *f2;
region *r; region *r;
@ -767,6 +784,7 @@ CuSuite *get_reports_suite(void)
SUITE_ADD_TEST(suite, test_seen_faction); SUITE_ADD_TEST(suite, test_seen_faction);
SUITE_ADD_TEST(suite, test_regionid); SUITE_ADD_TEST(suite, test_regionid);
SUITE_ADD_TEST(suite, test_sparagraph); SUITE_ADD_TEST(suite, test_sparagraph);
SUITE_ADD_TEST(suite, test_sparagraph_long);
SUITE_ADD_TEST(suite, test_bufunit); SUITE_ADD_TEST(suite, test_bufunit);
SUITE_ADD_TEST(suite, test_bufunit_fstealth); SUITE_ADD_TEST(suite, test_bufunit_fstealth);
SUITE_ADD_TEST(suite, test_arg_resources); SUITE_ADD_TEST(suite, test_arg_resources);