2010-08-08 10:06:34 +02:00
|
|
|
#include <platform.h>
|
|
|
|
#include <kernel/config.h>
|
|
|
|
#include "names.h"
|
|
|
|
|
|
|
|
/* kernel includes */
|
2014-08-27 06:40:18 +02:00
|
|
|
#include <kernel/unit.h>
|
2016-08-28 21:02:45 +02:00
|
|
|
#include <kernel/race.h>
|
2014-08-27 06:40:18 +02:00
|
|
|
#include <kernel/region.h>
|
|
|
|
#include <kernel/faction.h>
|
|
|
|
#include <kernel/race.h>
|
|
|
|
#include <kernel/terrain.h>
|
|
|
|
#include <kernel/terrainid.h>
|
2010-08-08 10:06:34 +02:00
|
|
|
|
|
|
|
/* util includes */
|
|
|
|
#include <util/base36.h>
|
2016-08-28 21:02:45 +02:00
|
|
|
#include <util/functions.h>
|
2017-12-29 06:13:28 +01:00
|
|
|
#include <util/language.h>
|
|
|
|
#include <util/macros.h>
|
2010-08-08 10:06:34 +02:00
|
|
|
#include <util/rng.h>
|
2017-12-30 19:49:21 +01:00
|
|
|
#include <util/strings.h>
|
2010-08-08 10:06:34 +02:00
|
|
|
#include <util/unicode.h>
|
|
|
|
|
|
|
|
/* libc includes */
|
2012-06-04 03:41:07 +02:00
|
|
|
#include <assert.h>
|
2010-08-08 10:06:34 +02:00
|
|
|
#include <ctype.h>
|
|
|
|
#include <wctype.h>
|
|
|
|
#include <stdlib.h>
|
2014-03-15 19:29:11 +01:00
|
|
|
#include <stdio.h>
|
2010-08-08 10:06:34 +02:00
|
|
|
#include <string.h>
|
|
|
|
|
2016-08-28 20:00:04 +02:00
|
|
|
static void count_particles(const char *monster, int *num_prefix, int *num_name, int *num_postfix)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2016-08-28 20:00:04 +02:00
|
|
|
char zText[32];
|
2016-08-28 20:06:14 +02:00
|
|
|
const char *str;
|
2014-08-24 21:49:55 +02:00
|
|
|
|
2016-08-28 20:06:14 +02:00
|
|
|
for (*num_prefix = 0;; ++*num_prefix) {
|
|
|
|
sprintf(zText, "%s_prefix_%d", monster, *num_prefix);
|
|
|
|
str = locale_getstring(default_locale, zText);
|
|
|
|
if (str == NULL)
|
|
|
|
break;
|
|
|
|
}
|
2014-08-24 21:49:55 +02:00
|
|
|
|
2016-08-28 20:06:14 +02:00
|
|
|
for (*num_name = 0;; ++*num_name) {
|
|
|
|
sprintf(zText, "%s_name_%d", monster, *num_name);
|
|
|
|
str = locale_getstring(default_locale, zText);
|
|
|
|
if (str == NULL)
|
|
|
|
break;
|
|
|
|
}
|
2014-08-24 21:49:55 +02:00
|
|
|
|
2016-08-28 20:06:14 +02:00
|
|
|
for (*num_postfix = 0;; ++*num_postfix) {
|
|
|
|
sprintf(zText, "%s_postfix_%d", monster, *num_postfix);
|
|
|
|
str = locale_getstring(default_locale, zText);
|
|
|
|
if (str == NULL)
|
|
|
|
break;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
2016-08-28 20:00:04 +02:00
|
|
|
}
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2016-08-28 21:31:25 +02:00
|
|
|
static void make_name(unit *u, const char *monster, int *num_postfix,
|
2016-08-28 20:00:04 +02:00
|
|
|
int pprefix, int *num_name, int *num_prefix, int ppostfix)
|
|
|
|
{
|
2014-08-24 21:49:55 +02:00
|
|
|
if (*num_name == 0) {
|
2016-08-28 20:00:04 +02:00
|
|
|
count_particles(monster, num_prefix, num_name, num_postfix);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
2016-08-28 20:00:04 +02:00
|
|
|
if (*num_name > 0) {
|
2016-08-30 08:56:40 +02:00
|
|
|
char name[NAMESIZE + 1];
|
2016-08-28 20:00:04 +02:00
|
|
|
char zText[32];
|
2016-08-28 21:27:40 +02:00
|
|
|
int uv = 0, uu = 0, un = 0;
|
2016-08-28 20:00:04 +02:00
|
|
|
const char *str;
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2016-08-28 21:27:40 +02:00
|
|
|
if (*num_prefix > 0) {
|
|
|
|
uv = rng_int() % (*num_prefix * pprefix);
|
|
|
|
}
|
2016-08-28 20:00:04 +02:00
|
|
|
uu = rng_int() % *num_name;
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2016-08-28 20:00:04 +02:00
|
|
|
if (*num_postfix > 0 && uv >= *num_prefix) {
|
|
|
|
un = rng_int() % *num_postfix;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
un = rng_int() % (*num_postfix * ppostfix);
|
2014-08-24 21:49:55 +02:00
|
|
|
}
|
2010-08-08 10:06:34 +02:00
|
|
|
|
2016-08-28 20:00:04 +02:00
|
|
|
name[0] = 0;
|
|
|
|
if (uv < *num_prefix) {
|
|
|
|
sprintf(zText, "%s_prefix_%d", monster, uv);
|
|
|
|
str = locale_getstring(default_locale, zText);
|
|
|
|
if (str) {
|
2017-12-30 19:49:21 +01:00
|
|
|
size_t sz = str_strlcpy(name, (const char *)str, sizeof(name));
|
|
|
|
str_strlcpy(name + sz, " ", sizeof(name) - sz);
|
2016-08-28 20:00:04 +02:00
|
|
|
}
|
|
|
|
}
|
2014-08-24 21:49:55 +02:00
|
|
|
|
2016-08-28 20:00:04 +02:00
|
|
|
sprintf(zText, "%s_name_%d", monster, uu);
|
2014-08-24 21:49:55 +02:00
|
|
|
str = locale_getstring(default_locale, zText);
|
2016-08-28 20:00:04 +02:00
|
|
|
if (str)
|
2017-12-30 19:49:21 +01:00
|
|
|
str_strlcat(name, (const char *)str, sizeof(name));
|
2016-08-28 20:00:04 +02:00
|
|
|
|
|
|
|
if (un < *num_postfix) {
|
|
|
|
sprintf(zText, "%s_postfix_%d", monster, un);
|
|
|
|
str = locale_getstring(default_locale, zText);
|
|
|
|
if (str) {
|
2017-12-30 19:49:21 +01:00
|
|
|
str_strlcat(name, " ", sizeof(name));
|
|
|
|
str_strlcat(name, (const char *)str, sizeof(name));
|
2016-08-28 20:00:04 +02:00
|
|
|
}
|
2014-08-24 21:49:55 +02:00
|
|
|
}
|
2016-08-28 21:31:25 +02:00
|
|
|
unit_setname(u, name);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-28 21:27:40 +02:00
|
|
|
static void undead_name(unit * u)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2014-08-24 21:49:55 +02:00
|
|
|
static int num_postfix, num_name, num_prefix;
|
2016-08-28 21:31:25 +02:00
|
|
|
make_name(u, "undead", &num_postfix, 2, &num_name, &num_prefix, 2);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2016-08-28 21:27:40 +02:00
|
|
|
static void skeleton_name(unit * u)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2014-08-24 21:49:55 +02:00
|
|
|
static int num_postfix, num_name, num_prefix;
|
2016-08-28 21:31:25 +02:00
|
|
|
make_name(u, "skeleton", &num_postfix, 5, &num_name, &num_prefix, 2);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2016-08-28 21:27:40 +02:00
|
|
|
static void zombie_name(unit * u)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2014-08-24 21:49:55 +02:00
|
|
|
static int num_postfix, num_name, num_prefix;
|
2016-08-28 21:31:25 +02:00
|
|
|
make_name(u, "zombie", &num_postfix, 5, &num_name, &num_prefix, 2);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2016-08-28 21:27:40 +02:00
|
|
|
static void ghoul_name(unit * u)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2014-08-24 21:49:55 +02:00
|
|
|
static int num_postfix, num_name, num_prefix;
|
2016-08-28 21:31:25 +02:00
|
|
|
make_name(u, "ghoul", &num_postfix, 5, &num_name, &num_prefix, 4);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Drachen */
|
|
|
|
|
|
|
|
#define SIL1 15
|
|
|
|
|
|
|
|
const char *silbe1[SIL1] = {
|
2014-08-24 21:49:55 +02:00
|
|
|
"Tar",
|
|
|
|
"Ter",
|
|
|
|
"Tor",
|
|
|
|
"Pan",
|
|
|
|
"Par",
|
|
|
|
"Per",
|
|
|
|
"Nim",
|
|
|
|
"Nan",
|
|
|
|
"Nun",
|
|
|
|
"Gor",
|
|
|
|
"For",
|
|
|
|
"Fer",
|
|
|
|
"Kar",
|
|
|
|
"Kur",
|
|
|
|
"Pen",
|
2010-08-08 10:06:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#define SIL2 19
|
|
|
|
|
|
|
|
const char *silbe2[SIL2] = {
|
2014-08-24 21:49:55 +02:00
|
|
|
"da",
|
|
|
|
"do",
|
|
|
|
"dil",
|
|
|
|
"di",
|
|
|
|
"dor",
|
|
|
|
"dar",
|
|
|
|
"ra",
|
|
|
|
"ran",
|
|
|
|
"ras",
|
|
|
|
"ro",
|
|
|
|
"rum",
|
|
|
|
"rin",
|
|
|
|
"ten",
|
|
|
|
"tan",
|
|
|
|
"ta",
|
|
|
|
"tor",
|
|
|
|
"gur",
|
|
|
|
"ga",
|
|
|
|
"gas",
|
2010-08-08 10:06:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#define SIL3 14
|
|
|
|
|
|
|
|
const char *silbe3[SIL3] = {
|
2014-08-24 21:49:55 +02:00
|
|
|
"gul",
|
|
|
|
"gol",
|
|
|
|
"dol",
|
|
|
|
"tan",
|
|
|
|
"tar",
|
|
|
|
"tur",
|
|
|
|
"sur",
|
|
|
|
"sin",
|
|
|
|
"kur",
|
|
|
|
"kor",
|
|
|
|
"kar",
|
|
|
|
"dul",
|
|
|
|
"dol",
|
|
|
|
"bus",
|
2010-08-08 10:06:34 +02:00
|
|
|
};
|
|
|
|
|
2016-08-28 21:27:40 +02:00
|
|
|
static void dragon_name(unit * u)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2016-08-28 21:27:40 +02:00
|
|
|
char name[NAMESIZE + 1];
|
2014-08-24 21:49:55 +02:00
|
|
|
int rnd, ter = 0;
|
|
|
|
static int num_postfix;
|
|
|
|
char zText[32];
|
|
|
|
const char *str;
|
|
|
|
|
2016-09-11 19:09:23 +02:00
|
|
|
assert(u);
|
2014-08-24 21:49:55 +02:00
|
|
|
if (num_postfix == 0) {
|
|
|
|
for (num_postfix = 0;; ++num_postfix) {
|
|
|
|
sprintf(zText, "dragon_postfix_%d", num_postfix);
|
|
|
|
str = locale_getstring(default_locale, zText);
|
|
|
|
if (str == NULL)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (num_postfix == 0)
|
|
|
|
num_postfix = -1;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
2014-08-24 21:49:55 +02:00
|
|
|
|
2016-09-11 19:09:23 +02:00
|
|
|
switch (rterrain(u->region)) {
|
|
|
|
case T_PLAIN:
|
|
|
|
ter = 1;
|
|
|
|
break;
|
|
|
|
case T_MOUNTAIN:
|
|
|
|
ter = 2;
|
|
|
|
break;
|
|
|
|
case T_DESERT:
|
|
|
|
ter = 3;
|
|
|
|
break;
|
|
|
|
case T_SWAMP:
|
|
|
|
ter = 4;
|
|
|
|
break;
|
|
|
|
case T_GLACIER:
|
|
|
|
ter = 5;
|
|
|
|
break;
|
2017-11-05 19:38:42 +01:00
|
|
|
default:
|
|
|
|
ter = 0;
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
2014-08-24 21:49:55 +02:00
|
|
|
|
2015-11-04 12:59:03 +01:00
|
|
|
if (num_postfix <=0) {
|
2016-08-28 21:27:40 +02:00
|
|
|
return;
|
2015-11-04 12:59:03 +01:00
|
|
|
}
|
|
|
|
else if (num_postfix < 6) {
|
|
|
|
rnd = rng_int() % num_postfix;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rnd = num_postfix / 6;
|
|
|
|
rnd = (rng_int() % rnd) + ter * rnd;
|
|
|
|
}
|
2017-12-11 18:35:30 +01:00
|
|
|
snprintf(zText, sizeof(zText), "dragon_postfix_%d", rnd);
|
2014-08-24 21:49:55 +02:00
|
|
|
|
|
|
|
str = locale_getstring(default_locale, zText);
|
|
|
|
assert(str != NULL);
|
|
|
|
|
2017-12-22 11:15:17 +01:00
|
|
|
if (u->region->land && (u->number > 1)) {
|
2014-08-24 21:49:55 +02:00
|
|
|
const char *no_article = strchr((const char *)str, ' ');
|
|
|
|
assert(no_article);
|
2017-02-18 21:15:14 +01:00
|
|
|
/* TODO: localization */
|
2017-12-11 18:35:30 +01:00
|
|
|
snprintf(name, sizeof(name), "Die %sn von %s", no_article + 1, rname(u->region,
|
2014-08-24 21:49:55 +02:00
|
|
|
default_locale));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
char n[32];
|
|
|
|
|
2017-12-12 09:19:35 +01:00
|
|
|
snprintf(n, sizeof(n), "%s%s%s", silbe1[rng_int() % SIL1], silbe2[rng_int() % SIL2], silbe3[rng_int() % SIL3]);
|
2014-08-24 21:49:55 +02:00
|
|
|
if (rng_int() % 5 > 2) {
|
|
|
|
sprintf(name, "%s, %s", n, str); /* "Name, der Titel" */
|
|
|
|
}
|
|
|
|
else {
|
2017-12-22 11:15:17 +01:00
|
|
|
if (u->region->land && (rng_int() % 3 == 0)) {
|
2017-12-11 18:35:30 +01:00
|
|
|
/* TODO: localization */
|
|
|
|
snprintf(name, sizeof(name), "%s %s von %s", n, str, rname(u->region, default_locale));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
snprintf(name, sizeof(name), "%s %s", n, str);
|
|
|
|
}
|
2014-08-24 21:49:55 +02:00
|
|
|
name[0] = (char)toupper(name[0]); /* TODO: UNICODE - should use towupper() */
|
|
|
|
}
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2016-08-28 21:27:40 +02:00
|
|
|
unit_setname(u, name);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Dracoide */
|
|
|
|
|
|
|
|
#define DRAC_PRE 13
|
|
|
|
static const char *drac_pre[DRAC_PRE] = {
|
2014-08-24 21:49:55 +02:00
|
|
|
"Siss",
|
|
|
|
"Xxaa",
|
|
|
|
"Shht",
|
|
|
|
"X'xixi",
|
|
|
|
"Xar",
|
|
|
|
"X'zish",
|
|
|
|
"X",
|
|
|
|
"Sh",
|
|
|
|
"R",
|
|
|
|
"Z",
|
|
|
|
"Y",
|
|
|
|
"L",
|
|
|
|
"Ck",
|
2010-08-08 10:06:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#define DRAC_MID 12
|
|
|
|
static const char *drac_mid[DRAC_MID] = {
|
2014-08-24 21:49:55 +02:00
|
|
|
"siss",
|
|
|
|
"xxaa",
|
|
|
|
"shht",
|
|
|
|
"xxi",
|
|
|
|
"xar",
|
|
|
|
"x'zish",
|
|
|
|
"x",
|
|
|
|
"sh",
|
|
|
|
"r",
|
|
|
|
"z'ck",
|
|
|
|
"y",
|
|
|
|
"rl"
|
2010-08-08 10:06:34 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#define DRAC_SUF 10
|
|
|
|
static const char *drac_suf[DRAC_SUF] = {
|
2014-08-24 21:49:55 +02:00
|
|
|
"xil",
|
|
|
|
"shh",
|
|
|
|
"s",
|
|
|
|
"x",
|
|
|
|
"arr",
|
|
|
|
"lll",
|
|
|
|
"lll",
|
|
|
|
"shack",
|
|
|
|
"ck",
|
|
|
|
"k"
|
2010-08-08 10:06:34 +02:00
|
|
|
};
|
|
|
|
|
2016-08-28 21:27:40 +02:00
|
|
|
static void dracoid_name(unit * u)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2016-08-30 08:56:40 +02:00
|
|
|
static char name[NAMESIZE + 1];
|
2014-08-24 21:49:55 +02:00
|
|
|
int mid_syllabels;
|
|
|
|
|
2015-05-12 18:07:47 +02:00
|
|
|
/* ignore u */
|
2017-01-10 16:31:05 +01:00
|
|
|
UNUSED_ARG(u);
|
2014-08-24 21:49:55 +02:00
|
|
|
/* Wieviele Mittelteile? */
|
|
|
|
|
|
|
|
mid_syllabels = rng_int() % 4;
|
|
|
|
|
2018-02-11 15:57:31 +01:00
|
|
|
str_strlcpy(name, drac_pre[rng_int() % DRAC_PRE], sizeof(name));
|
2014-08-24 21:49:55 +02:00
|
|
|
while (mid_syllabels > 0) {
|
|
|
|
mid_syllabels--;
|
|
|
|
if (rng_int() % 10 < 4)
|
2017-12-30 19:49:21 +01:00
|
|
|
str_strlcat(name, "'", sizeof(name));
|
2018-02-11 15:57:31 +01:00
|
|
|
str_strlcat(name, drac_mid[rng_int() % DRAC_MID], sizeof(name));
|
2014-08-24 21:49:55 +02:00
|
|
|
}
|
2018-02-11 15:57:31 +01:00
|
|
|
str_strlcat(name, drac_suf[rng_int() % DRAC_SUF], sizeof(name));
|
2016-08-28 21:27:40 +02:00
|
|
|
unit_setname(u, name);
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|
|
|
|
|
2011-03-07 08:02:35 +01:00
|
|
|
void register_names(void)
|
2010-08-08 10:06:34 +02:00
|
|
|
{
|
2014-08-24 21:49:55 +02:00
|
|
|
/* function name
|
|
|
|
* generate a name for a nonplayerunit
|
2017-02-20 22:07:36 +01:00
|
|
|
* race->name_unit() */
|
|
|
|
|
|
|
|
register_race_function(undead_name, "name_undead");
|
|
|
|
register_race_function(skeleton_name, "name_skeleton");
|
|
|
|
register_race_function(zombie_name, "name_zombie");
|
|
|
|
register_race_function(ghoul_name, "name_ghoul");
|
|
|
|
register_race_function(dracoid_name, "name_dracoid");
|
|
|
|
register_race_function(dragon_name, "name_dragon");
|
|
|
|
register_race_function(dragon_name, "name_youngdragon");
|
|
|
|
register_race_function(dragon_name, "name_wyrm");
|
2010-08-08 10:06:34 +02:00
|
|
|
}
|