forked from github/server
Merge pull request #728 from ennorehling/develop
bugfixes, sea serpents
This commit is contained in:
commit
1413c2807d
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"))
|
||||||
|
|
100
src/creport.c
100
src/creport.c
|
@ -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;
|
||||||
|
@ -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,7 +817,8 @@ 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);
|
||||||
|
@ -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 */
|
||||||
|
|
|
@ -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,12 +200,39 @@ 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)
|
||||||
|
{
|
||||||
|
const char *match;
|
||||||
|
equipment *eq = NULL;
|
||||||
|
|
||||||
|
match = cb_find_str(&cb_equipments, eqname);
|
||||||
|
if (match) {
|
||||||
|
cb_get_kv(match, &eq, sizeof(eq));
|
||||||
|
}
|
||||||
|
return eq;
|
||||||
|
}
|
||||||
|
|
||||||
|
equipment *get_or_create_equipment(const char *eqname)
|
||||||
|
{
|
||||||
|
equipment *eq = get_equipment(eqname);
|
||||||
|
if (!eq) {
|
||||||
|
size_t len;
|
||||||
|
char data[64];
|
||||||
|
|
||||||
|
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;
|
int i;
|
||||||
equipment *eq = *eqp;
|
|
||||||
*eqp = eq->next;
|
|
||||||
free(eq->name);
|
free(eq->name);
|
||||||
if (eq->spells) {
|
if (eq->spells) {
|
||||||
selist_foreach(eq->spells, free_ls);
|
selist_foreach(eq->spells, free_ls);
|
||||||
|
@ -257,6 +248,17 @@ void equipment_done(void) {
|
||||||
for (i = 0; i != MAXSKILLS; ++i) {
|
for (i = 0; i != MAXSKILLS; ++i) {
|
||||||
free(eq->skills[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);
|
free(eq);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void equipment_done(void) {
|
||||||
|
cb_foreach(&cb_equipments, "", 0, free_equipment_cb, 0);
|
||||||
|
cb_clear(&cb_equipments);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue