Fix demon stealth in English reports.

This commit is contained in:
Enno Rehling 2020-05-10 17:50:56 +02:00
parent 1a63e41929
commit 08b9f03afc
9 changed files with 151 additions and 62 deletions

View File

@ -6,10 +6,6 @@ local function equip_first(u)
equip_unit(u, name, 255)
end
local function equip_demon(u)
u.race_name = 'human'
end
local mysets = {
['first_unit'] = {
['items'] = {
@ -82,7 +78,6 @@ local mysets = {
['skills'] = {
['stamina'] = 15
},
['callback'] = equip_demon
},
['seed_insect'] = {
['items'] = {

View File

@ -300,15 +300,16 @@ fighter *select_corpse(battle * b, fighter * af)
/* Geflohene haben auch 0 hp, duerfen hier aber nicht ausgewaehlt
* werden! */
int dead = dead_fighters(df);
if (!playerrace(u_race(df->unit)))
continue;
if (af && !helping(af->side, df->side))
continue;
if (di < dead) {
return df;
const race *rc = u_race(df->unit);
/* Untote sinc für immer tot */
if (!undeadrace(rc)) {
if (af && !helping(af->side, df->side))
continue;
if (di < dead) {
return df;
}
di -= dead;
}
di -= dead;
}
}
}
@ -2076,9 +2077,6 @@ static void make_heroes(battle * b)
unit *u = fig->unit;
if (fval(u, UFL_HERO)) {
int i;
if (!playerrace(u_race(u))) {
log_error("Hero %s is a %s.\n", unitname(u), u_race(u)->_name);
}
for (i = 0; i != u->number; ++i) {
fig->person[i].speed += (rule_hero_speed - 1);
}
@ -2609,11 +2607,12 @@ static void aftermath(battle * b)
for (df = s->fighters; df; df = df->next) {
unit *du = df->unit;
int dead = dead_fighters(df);
const race *rc = u_race(du);
/* tote insgesamt: */
s->dead += dead;
/* Tote, die wiederbelebt werde koennen: */
if (playerrace(u_race(df->unit))) {
if (!undeadrace(rc)) {
s->casualties += dead;
}
if (df->hits + df->kills) {
@ -2640,6 +2639,7 @@ static void aftermath(battle * b)
for (df = s->fighters; df; df = df->next) {
unit *du = df->unit;
const race *rc = u_race(du);
int dead = dead_fighters(df);
int sum_hp = 0;
int n;
@ -2732,7 +2732,7 @@ static void aftermath(battle * b)
}
s->flee += df->run.number;
if (playerrace(u_race(du))) {
if (!undeadrace(rc)) {
/* tote im kampf werden zu regionsuntoten:
* for each of them, a peasant will die as well */
dead_players += dead;
@ -3102,7 +3102,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
}
else {
building *bld = u->building;
if (bld && bld->sizeleft >= u->number && playerrace(u_race(u))) {
if (bld && bld->sizeleft >= u->number && humanoidrace(u_race(u))) {
fig->building = bld;
fig->building->sizeleft -= u->number;
}

View File

@ -83,7 +83,7 @@ static void chaos(region * r)
case 0: /* Untote */
if (!(r->terrain->flags & SEA_REGION)) {
unit *u = random_unit(r);
if (u && playerrace(u_race(u))) {
if (u && !undeadrace(u_race(u))) {
ADDMSG(&u->faction->msgs, msg_message("chaos_disease", "unit", u));
u_setfaction(u, get_monsters());
u_freeorders(u);

View File

@ -769,6 +769,7 @@ static void cr_output_spells(stream *out, const unit * u, int maxlevel)
void cr_output_unit(stream *out, const faction * f,
const unit * u, seen_mode mode)
{
const struct locale *lang = crtag_locale();
/* Race attributes are always plural and item attributes always
* singular */
const char *str;
@ -781,7 +782,6 @@ void cr_output_unit(stream *out, const faction * f,
const faction *fother;
const char *prefix;
bool allied;
const struct locale *lang = f->locale;
assert(u && u->number);
@ -841,17 +841,16 @@ void cr_output_unit(stream *out, const faction * f,
pzTmp = get_racename(u->attribs);
if (pzTmp) {
const char *pzRace = locale_string(lang, mkname("race", pzTmp), false);
if (pzRace) {
pzTmp = pzRace;
const char *pzRace = pzTmp;
const struct race *rc = rc_find(pzTmp);
if (rc) {
pzRace = rc_name_s(rc, NAME_PLURAL);
}
pzRace = translate(pzTmp, locale_string(lang, pzTmp, false));
if (!pzRace) {
pzRace = pzTmp;
}
stream_printf(out, "\"%s\";Typ\n", pzRace);
if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) {
pzRace = rc_name_s(u_race(u), NAME_PLURAL);
pzTmp = translate(pzRace, locale_string(lang, pzRace, false));
stream_printf(out, "\"%s\";Typ\n", pzTmp);
rc = u_race(u);
if (u->faction == f && fval(rc, RCF_SHAPESHIFTANY)) {
pzRace = rc_name_s(rc, NAME_PLURAL);
stream_printf(out, "\"%s\";wahrerTyp\n", pzRace);
}
}
@ -1559,7 +1558,7 @@ static void report_itemtype(FILE *F, faction *f, const item_type *itype) {
static int
report_computer(const char *filename, report_context * ctx, const char *bom)
{
static int era = -1;
const struct locale *lang = crtag_locale();
int i;
faction *f = ctx->f;
const char *prefix, *str;
@ -1569,6 +1568,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom)
FILE *F = fopen(filename, "w");
static const race *rc_human;
static int rc_cache;
static int era = -1;
if (era < 0) {
era = config_get_int("game.era", 1);
@ -1623,13 +1623,13 @@ report_computer(const char *filename, report_context * ctx, const char *bom)
}
{
const char *zRace = rc_name_s(f->race, NAME_PLURAL);
fprintf(F, "\"%s\";Typ\n", translate(zRace, LOC(f->locale, zRace)));
fprintf(F, "\"%s\";Typ\n", translate(zRace, LOC(lang, zRace)));
}
prefix = get_prefix(f->attribs);
if (prefix != NULL) {
prefix = mkname("prefix", prefix);
fprintf(F, "\"%s\";typprefix\n",
translate(prefix, LOC(f->locale, prefix)));
translate(prefix, LOC(lang, prefix)));
}
fprintf(F, "%d;Rekrutierungskosten\n", f->race->recruitcost);
fprintf(F, "%d;Anzahl Personen\n", f->num_people);
@ -1682,7 +1682,7 @@ report_computer(const char *filename, report_context * ctx, const char *bom)
if (prefix != NULL) {
prefix = mkname("prefix", prefix);
fprintf(F, "\"%s\";typprefix\n",
translate(prefix, LOC(f->locale, prefix)));
translate(prefix, LOC(lang, prefix)));
}
show_allies_cr(F, f, g);
}

View File

@ -4,6 +4,13 @@
#include "spy.h"
#include "travelthru.h"
#include "attributes/racename.h"
#include "util/keyword.h"
#include <util/language.h>
#include <util/lists.h>
#include <util/message.h>
#include <kernel/ally.h>
#include <kernel/building.h>
#include <kernel/faction.h>
@ -16,11 +23,6 @@
#include <kernel/spell.h>
#include <kernel/spellbook.h>
#include "util/keyword.h"
#include <util/language.h>
#include <util/lists.h>
#include <util/message.h>
#include <stream.h>
#include <memstream.h>
@ -222,6 +224,96 @@ static int cr_get_int(stream *strm, const char *match, int def)
return def;
}
static bool cr_find_string(stream *strm, const char *match, const char *value)
{
char line[1024];
size_t len = strlen(match);
strm->api->rewind(strm->handle);
while (strm->api->readln(strm->handle, line, sizeof(line))==0) {
if (line[0] == '\"') {
const char * pos = strstr(line + 1, match);
if (pos && pos[len] == '\0') {
size_t vlen = strlen(value);
if (value != NULL && strncmp(line + 1, value, vlen) == 0) {
return (line[vlen + 1] == '\"');
}
return false;
}
}
}
return value == NULL;
}
static void test_cr_hiderace(CuTest *tc) {
stream strm;
faction *f1, *f2;
region *r;
unit *u;
struct locale * lang;
test_setup();
default_locale = test_create_locale();
locale_setstring(default_locale, "race::elf_p", "Elfen");
locale_setstring(default_locale, "race::elf", "elf");
locale_setstring(default_locale, "race::human_p", "Menschen");
locale_setstring(default_locale, "race::human", "Mensch");
lang = get_or_create_locale("en");
locale_setstring(lang, "race::human_p", "humans");
locale_setstring(lang, "race::human", "human");
locale_setstring(lang, "race::elf_p", "elves");
locale_setstring(lang, "race::elf", "elf");
f1 = test_create_faction(NULL);
f2 = test_create_faction(NULL);
r = test_create_region(0, 0, NULL);
u = test_create_unit(f1, r);
mstream_init(&strm);
CuAssertPtrEquals(tc, default_locale, (struct locale *)f1->locale);
CuAssertPtrEquals(tc, default_locale, (struct locale *)f2->locale);
cr_output_unit(&strm, f1, u, seen_unit);
CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Menschen"));
CuAssertTrue(tc, cr_find_string(&strm, ";wahrerTyp", NULL));
mstream_done(&strm);
mstream_init(&strm);
CuAssertPtrEquals(tc, default_locale, (struct locale *)f1->locale);
CuAssertPtrEquals(tc, default_locale, (struct locale *)f2->locale);
cr_output_unit(&strm, f2, u, seen_unit);
CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Menschen"));
CuAssertTrue(tc, cr_find_string(&strm, ";wahrerTyp", NULL));
mstream_done(&strm);
/* when we use irace, the owner can see the true race */
f1->locale = lang;
u->irace = test_create_race("elf");
mstream_init(&strm);
cr_output_unit(&strm, f1, u, seen_unit);
CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Elfen"));
CuAssertTrue(tc, cr_find_string(&strm, ";wahrerTyp", "Menschen"));
mstream_done(&strm);
mstream_init(&strm);
cr_output_unit(&strm, f2, u, seen_unit);
CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Elfen"));
CuAssertTrue(tc, cr_find_string(&strm, ";wahrerTyp", NULL));
mstream_done(&strm);
/* when we use racename, nobody can tell it's not the real deal */
u->irace = NULL;
set_racename(&u->attribs, "Zwerge");
mstream_init(&strm);
cr_output_unit(&strm, f1, u, seen_unit);
CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Zwerge"));
CuAssertTrue(tc, cr_find_string(&strm, ";wahrerTyp", NULL));
mstream_done(&strm);
mstream_init(&strm);
cr_output_unit(&strm, f2, u, seen_unit);
CuAssertTrue(tc, cr_find_string(&strm, ";Typ", "Zwerge"));
CuAssertTrue(tc, cr_find_string(&strm, ";wahrerTyp", NULL));
mstream_done(&strm);
test_teardown();
}
static void test_cr_factionstealth(CuTest *tc) {
stream strm;
faction *f1, *f2;
@ -326,6 +418,7 @@ CuSuite *get_creport_suite(void)
SUITE_ADD_TEST(suite, test_cr_unit);
SUITE_ADD_TEST(suite, test_cr_resources);
SUITE_ADD_TEST(suite, test_cr_mallorn);
SUITE_ADD_TEST(suite, test_cr_hiderace);
SUITE_ADD_TEST(suite, test_cr_factionstealth);
return suite;
}

View File

@ -279,12 +279,10 @@ unit *addplayer(region * r, faction * f)
u->hp = unit_max_hp(u) * u->number;
fset(u, UFL_ISNEW);
if (f->race == get_race(RC_DAEMON)) {
race_t urc;
const race *rc;
do {
urc = (race_t)(rng_int() % MAXRACES);
rc = get_race(urc);
} while (rc == NULL || urc == RC_DAEMON || !playerrace(rc));
int urc = (race_t)(rng_int() % MAX_START_RACE);
if (urc >= RC_DAEMON) ++urc;
rc = get_race(urc);
u->irace = rc;
}
f->lastorders = turn;

View File

@ -48,16 +48,14 @@ int num_races = 0;
static int rc_changes = 1;
const char *racenames[MAXRACES] = {
"dwarf", "elf", NULL, "goblin", "human", "troll", "demon", "insect",
"halfling", "cat", "aquarian", "orc", "snotling", "undead", NULL,
"dwarf", "elf", "goblin", "human", "troll", "demon", "insect",
"halfling", "cat", "aquarian", "orc", "snotling", "undead",
"youngdragon", "dragon", "wyrm", "ent", "catdragon", "dracoid",
NULL, NULL, "irongolem", "stonegolem", "shadowdemon",
"irongolem", "stonegolem", "shadowdemon",
"shadowmaster", "mountainguard", "alp", "toad", "braineater", "peasant",
"wolf", NULL, NULL, NULL, NULL, "songdragon", NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, "seaserpent",
"shadowknight", NULL, "skeleton", "skeletonlord", "zombie",
"juju", "ghoul", "ghast", NULL, NULL, "template",
"wolf", "songdragon", "seaserpent",
"shadowknight", "skeleton", "skeletonlord", "zombie",
"juju", "ghoul", "ghast", "template",
"clone"
};

View File

@ -35,7 +35,7 @@ extern "C" {
typedef enum {
RC_DWARF, /* 0 - Zwerg */
RC_ELF,
RC_GOBLIN = 3,
RC_GOBLIN,
RC_HUMAN,
RC_TROLL,
RC_DAEMON,
@ -44,17 +44,19 @@ extern "C" {
RC_CAT,
RC_AQUARIAN,
RC_ORC,
/* last of the addplayer races */
RC_SNOTLING,
RC_UNDEAD,
RC_FIREDRAGON = 15,
RC_FIREDRAGON,
RC_DRAGON,
RC_WYRM,
RC_TREEMAN,
RC_BIRTHDAYDRAGON,
RC_DRACOID,
RC_IRONGOLEM = 23,
RC_IRONGOLEM,
RC_STONEGOLEM,
RC_SHADOW,
RC_SHADOWLORD,
@ -63,25 +65,27 @@ extern "C" {
RC_TOAD,
RC_HIRNTOETER,
RC_PEASANT,
RC_WOLF = 32,
RC_WOLF,
RC_SONGDRAGON = 37,
RC_SONGDRAGON,
RC_SEASERPENT = 51,
RC_SEASERPENT,
RC_SHADOWKNIGHT,
RC_SKELETON = 54,
RC_SKELETON,
RC_SKELETON_LORD,
RC_ZOMBIE,
RC_ZOMBIE_LORD,
RC_GHOUL,
RC_GHOUL_LORD,
RC_TEMPLATE = 62,
RC_TEMPLATE,
RC_CLONE,
MAXRACES,
NORACE = -1
} race_t;
#define MAX_START_RACE RC_ORC
extern int num_races;
extern const char *racenames[MAXRACES];
@ -241,6 +245,7 @@ extern "C" {
#define playerrace(rc) ((rc)->flags & RCF_PLAYABLE)
#define dragonrace(rc) ((rc)->flags & RCF_DRAGON)
#define humanoidrace(rc) (((rc)->flags & RCF_UNDEAD) || (rc)==get_race(RC_DRACOID) || playerrace(rc))
#define undeadrace(rc) (((rc)->flags & RCF_UNDEAD) || (rc)==get_race(RC_DRACOID))
#define illusionaryrace(rc) ((rc)->flags & RCF_ILLUSIONARY)
bool allowed_dragon(const struct region *src,

View File

@ -1399,7 +1399,7 @@ static int heal_fighters(selist * fgs, int *power, bool heal_monsters)
continue;
/* wir heilen erstmal keine Monster */
if (heal_monsters || playerrace(u_race(df->unit))) {
if (heal_monsters || !undeadrace(u_race(df->unit))) {
int n, hp = df->unit->hp / df->unit->number;
int rest = df->unit->hp % df->unit->number;