forked from github/server
8823db9702
- Bugfix to P_BERSERK
720 lines
11 KiB
C
720 lines
11 KiB
C
/* vi: set ts=2:
|
|
*
|
|
*
|
|
* Eressea PB(E)M host Copyright (C) 1998-2003
|
|
* Christian Schlittchen (corwin@amber.kn-bremen.de)
|
|
* Katja Zedel (katze@felidae.kn-bremen.de)
|
|
* Henning Peters (faroul@beyond.kn-bremen.de)
|
|
* Enno Rehling (enno@eressea-pbem.de)
|
|
* Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de)
|
|
*
|
|
* based on:
|
|
*
|
|
* Atlantis v1.0 13 September 1993 Copyright 1993 by Russell Wallace
|
|
* Atlantis v1.7 Copyright 1996 by Alex Schröder
|
|
*
|
|
* This program may not be used, modified or distributed without
|
|
* prior permission by the authors of Eressea.
|
|
* This program may not be sold or used commercially without prior written
|
|
* permission from the authors.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include "eressea.h"
|
|
#include "names.h"
|
|
|
|
/* kernel includes */
|
|
#include "unit.h"
|
|
#include "region.h"
|
|
#include "faction.h"
|
|
#include "magic.h"
|
|
#include "race.h"
|
|
|
|
/* libc includes */
|
|
#include <ctype.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/* util includes */
|
|
#include <base36.h>
|
|
|
|
/* Untote */
|
|
|
|
#define UNTOT_VOR 23
|
|
|
|
static const char *untot_vor[UNTOT_VOR] =
|
|
{
|
|
"Grausige ",
|
|
"Stöhnende ",
|
|
"Schlurfende ",
|
|
"Schwarzgewandete ",
|
|
"Faulende ",
|
|
"Angsteinflößende ",
|
|
"Heulende ",
|
|
"Wartende ",
|
|
"Grauenvolle ",
|
|
"Schwarze ",
|
|
"Dunkle ",
|
|
"Fürchterliche ",
|
|
"Grauenhafte ",
|
|
"Furchtbare ",
|
|
"Entsetzliche ",
|
|
"Schauderhafte ",
|
|
"Schreckliche ",
|
|
"Gespenstische ",
|
|
"Ekelhafte ",
|
|
"Düstere ",
|
|
"Schaurige ",
|
|
"Erbarmungslose ",
|
|
"Hungrige "
|
|
};
|
|
|
|
#define UNTOT 13
|
|
|
|
static const char *untot[UNTOT] =
|
|
{
|
|
"Geister",
|
|
"Phantome",
|
|
"Vampire",
|
|
"Zombies",
|
|
"Gespenster",
|
|
"Kreaturen",
|
|
"Gestalten",
|
|
"Schemen",
|
|
"Monster",
|
|
"Krieger",
|
|
"Ghule",
|
|
"Kopflose",
|
|
"Irrlichter"
|
|
};
|
|
|
|
#define UNTOT_NACH 14
|
|
|
|
static const char *untot_nach[UNTOT_NACH] =
|
|
{
|
|
" der Nacht",
|
|
" der Schatten",
|
|
" der Finsternis",
|
|
" des Bösen",
|
|
" der Erschlagenen",
|
|
" der Verfluchten",
|
|
" der Gefolterten",
|
|
" der Ruhelosen",
|
|
" aus dem Nebel",
|
|
" aus dem Dunkel",
|
|
" der Tiefe",
|
|
" in Ketten",
|
|
" aus dem Totenreich",
|
|
" aus der Unterwelt"
|
|
};
|
|
|
|
const char *
|
|
untoten_name(const unit * u)
|
|
{
|
|
int uv, uu, un;
|
|
static char name[NAMESIZE + 1];
|
|
|
|
/* nur 50% aller Namen haben "Vor-Teil" */
|
|
u=u;
|
|
uv = rand() % (UNTOT_VOR * 2);
|
|
|
|
uu = rand() % UNTOT;
|
|
un = rand() % (UNTOT_NACH * (uv >= UNTOT_VOR ? 1 : 2));
|
|
/* nur 50% aller Namen haben "Nach-Teil", wenn kein Vor-Teil */
|
|
|
|
if (uv < UNTOT_VOR) {
|
|
strcpy(name, untot_vor[uv]);
|
|
} else {
|
|
name[0] = 0;
|
|
}
|
|
|
|
strcat(name, untot[uu]);
|
|
|
|
if (un < UNTOT_NACH)
|
|
strcat(name, untot_nach[un]);
|
|
|
|
return name;
|
|
}
|
|
|
|
/* Skelette */
|
|
|
|
#define SKEL_VOR 19
|
|
|
|
static const char *skel_vor[SKEL_VOR] =
|
|
{
|
|
"Klapperige ",
|
|
"Stöhnende ",
|
|
"Schwarzknochige ",
|
|
"Schwarzgewandete ",
|
|
"Angsteinflößende ",
|
|
"Heulende ",
|
|
"Wartende ",
|
|
"Grauenvolle ",
|
|
"Schwarze ",
|
|
"Dunkle ",
|
|
"Fürchterliche ",
|
|
"Grauenhafte ",
|
|
"Furchtbare ",
|
|
"Entsetzliche ",
|
|
"Schauderhafte ",
|
|
"Schreckliche ",
|
|
"Düstere ",
|
|
"Schaurige ",
|
|
"Erbarmungslose "
|
|
};
|
|
|
|
#define SKEL 5
|
|
|
|
static const char *skel[SKEL] =
|
|
{
|
|
"Skelette",
|
|
"Kreaturen",
|
|
"Krieger",
|
|
"Kämpfer",
|
|
"Rächer"
|
|
};
|
|
|
|
#define SKEL_NACH 14
|
|
|
|
static const char *skel_nach[SKEL_NACH] =
|
|
{
|
|
" der Nacht",
|
|
" der Schatten",
|
|
" der Finsternis",
|
|
" des Bösen",
|
|
" der Erschlagenen",
|
|
" der Verfluchten",
|
|
" der Gefolterten",
|
|
" der Ruhelosen",
|
|
" aus dem Nebel",
|
|
" aus dem Dunkel",
|
|
" der Tiefe",
|
|
" in Ketten",
|
|
" aus dem Totenreich",
|
|
" aus der Unterwelt"
|
|
};
|
|
|
|
const char *
|
|
skeleton_name(const unit * u)
|
|
{
|
|
int uv, uu, un;
|
|
static char name[NAMESIZE + 1];
|
|
|
|
u=u;
|
|
|
|
/* nur 20% aller Namen haben "Vor-Teil" */
|
|
uv = rand() % (SKEL_VOR * 5);
|
|
uu = rand() % SKEL;
|
|
un = rand() % (SKEL_NACH * (uv >= SKEL_VOR ? 1 : 2));
|
|
|
|
/* nur 50% aller Namen haben "Nach-Teil", wenn kein Vor-Teil */
|
|
|
|
if (uv < SKEL_VOR) {
|
|
strcpy(name, skel_vor[uv]);
|
|
} else {
|
|
name[0] = 0;
|
|
}
|
|
|
|
strcat(name, skel[uu]);
|
|
|
|
if (un < SKEL_NACH)
|
|
strcat(name, skel_nach[un]);
|
|
|
|
return name;
|
|
}
|
|
|
|
/* Zombies */
|
|
|
|
#define ZOM_VOR 16
|
|
|
|
static const char *zombie_vor[ZOM_VOR] =
|
|
{
|
|
"Faulende ",
|
|
"Zerschlagene ",
|
|
"Gefolterte ",
|
|
"Angsteinflößende ",
|
|
"Leise Schlurfende ",
|
|
"Kinderfressende ",
|
|
"Schwarze ",
|
|
"Dunkle ",
|
|
"Fürchterliche ",
|
|
"Grauenhafte ",
|
|
"Furchtbare ",
|
|
"Entsetzliche ",
|
|
"Schauderhafte ",
|
|
"Schreckliche ",
|
|
"Düstere ",
|
|
"Schaurige "
|
|
};
|
|
|
|
#define ZOM 5
|
|
|
|
static const char *zombie[ZOM] =
|
|
{
|
|
"Zombies",
|
|
"Kreaturen",
|
|
"Verlorene",
|
|
"Erschlagene",
|
|
"Verdammte"
|
|
};
|
|
|
|
#define ZOM_NACH 13
|
|
|
|
static const char *zombie_nach[ZOM_NACH] =
|
|
{
|
|
" der Nacht",
|
|
" der Schatten",
|
|
" der Finsternis",
|
|
" des Bösen",
|
|
" der Erschlagenen",
|
|
" der Verfluchten",
|
|
" der Ruhelosen",
|
|
" aus dem Nebel",
|
|
" aus dem Dunkel",
|
|
" der Tiefe",
|
|
" in Ketten",
|
|
" aus dem Totenreich",
|
|
" aus der Unterwelt"
|
|
};
|
|
|
|
const char *
|
|
zombie_name(const unit * u)
|
|
{
|
|
int uv, uu, un;
|
|
static char name[NAMESIZE + 1];
|
|
|
|
u=u;
|
|
|
|
/* nur 20% aller Namen haben "Vor-Teil" */
|
|
uv = rand() % (ZOM_VOR * 5);
|
|
uu = rand() % ZOM;
|
|
un = rand() % (ZOM_NACH * (uv >= ZOM_VOR ? 1 : 2));
|
|
|
|
/* nur 50% aller Namen haben "Nach-Teil", wenn kein Vor-Teil */
|
|
|
|
if (uv < ZOM_VOR) {
|
|
strcpy(name, zombie_vor[uv]);
|
|
} else {
|
|
name[0] = 0;
|
|
}
|
|
|
|
strcat(name, zombie[uu]);
|
|
|
|
if (un < ZOM_NACH)
|
|
strcat(name, zombie_nach[un]);
|
|
|
|
return name;
|
|
}
|
|
|
|
/* Ghoule */
|
|
|
|
#define GHOUL_VOR 17
|
|
|
|
static const char *ghoul_vor[GHOUL_VOR] =
|
|
{
|
|
"Faulende ",
|
|
"Angsteinflößende ",
|
|
"Leise ",
|
|
"Kinderfressende ",
|
|
"Menschenfressende ",
|
|
"Wahnsinnige ",
|
|
"Brutale ",
|
|
"Schwarze ",
|
|
"Dunkle ",
|
|
"Fürchterliche ",
|
|
"Grauenhafte ",
|
|
"Furchtbare ",
|
|
"Entsetzliche ",
|
|
"Schauderhafte ",
|
|
"Schreckliche ",
|
|
"Düstere ",
|
|
"Schaurige "
|
|
};
|
|
|
|
#define GHOUL 6
|
|
|
|
static const char *ghoul[GHOUL] =
|
|
{
|
|
"Ghoule",
|
|
"Kreaturen",
|
|
"Verlorene",
|
|
"Erschlagene",
|
|
"Verdammte",
|
|
"Schlurfende Ghoule",
|
|
};
|
|
|
|
#define GHOUL_NACH 13
|
|
|
|
static const char *ghoul_nach[GHOUL_NACH] =
|
|
{
|
|
" der Nacht",
|
|
" der Schatten",
|
|
" der Finsternis",
|
|
" des Bösen",
|
|
" der Erschlagenen",
|
|
" der Verfluchten",
|
|
" der Ruhelosen",
|
|
" aus dem Nebel",
|
|
" aus dem Dunkel",
|
|
" der Tiefe",
|
|
" in Ketten",
|
|
" aus dem Totenreich",
|
|
" aus der Unterwelt"
|
|
};
|
|
|
|
const char *
|
|
ghoul_name(const unit * u)
|
|
{
|
|
int uv, uu, un;
|
|
static char name[NAMESIZE + 1];
|
|
|
|
u=u;
|
|
|
|
/* nur 20% aller Namen haben "Vor-Teil" */
|
|
uv = rand() % (GHOUL_VOR * 5);
|
|
uu = rand() % GHOUL;
|
|
un = rand() % (GHOUL_NACH * (uv >= GHOUL_VOR ? 1 : 4));
|
|
|
|
/* nur 25% aller Namen haben "Nach-Teil", wenn kein Vor-Teil */
|
|
|
|
if (uv < GHOUL_VOR) {
|
|
strcpy(name, ghoul_vor[uv]);
|
|
} else {
|
|
name[0] = 0;
|
|
}
|
|
|
|
strcat(name, ghoul[uu]);
|
|
|
|
if (un < GHOUL_NACH)
|
|
strcat(name, ghoul_nach[un]);
|
|
|
|
return name;
|
|
}
|
|
|
|
|
|
/* Drachen */
|
|
|
|
#define SIL1 15
|
|
|
|
const char *silbe1[SIL1] = {
|
|
"Tar",
|
|
"Ter",
|
|
"Tor",
|
|
"Pan",
|
|
"Par",
|
|
"Per",
|
|
"Nim",
|
|
"Nan",
|
|
"Nun",
|
|
"Gor",
|
|
"For",
|
|
"Fer",
|
|
"Kar",
|
|
"Kur",
|
|
"Pen",
|
|
};
|
|
|
|
#define SIL2 19
|
|
|
|
const char *silbe2[SIL2] = {
|
|
"da",
|
|
"do",
|
|
"dil",
|
|
"di",
|
|
"dor",
|
|
"dar",
|
|
"ra",
|
|
"ran",
|
|
"ras",
|
|
"ro",
|
|
"rum",
|
|
"rin",
|
|
"ten",
|
|
"tan",
|
|
"ta",
|
|
"tor",
|
|
"gur",
|
|
"ga",
|
|
"gas",
|
|
};
|
|
|
|
#define SIL3 14
|
|
|
|
const char *silbe3[SIL3] = {
|
|
"gul",
|
|
"gol",
|
|
"dol",
|
|
"tan",
|
|
"tar",
|
|
"tur",
|
|
"sur",
|
|
"sin",
|
|
"kur",
|
|
"kor",
|
|
"kar",
|
|
"dul",
|
|
"dol",
|
|
"bus",
|
|
};
|
|
|
|
#define DTITEL 5
|
|
|
|
const char *dtitel[6][DTITEL] =
|
|
{
|
|
{ /* Ebene, Hochland */
|
|
"der Weise",
|
|
"der Allwissende",
|
|
"der Mächtige",
|
|
"die Ehrwürdige",
|
|
"die Listige"
|
|
},
|
|
{ /* Wald */
|
|
"der Grüne",
|
|
"die Strafende",
|
|
"der Sehende",
|
|
"der Reisende",
|
|
"die Wissende"
|
|
},
|
|
{ /* Berge */
|
|
"der Goldene",
|
|
"der Graue",
|
|
"der Steinerne",
|
|
"die Alte",
|
|
"die Mächtige"
|
|
},
|
|
{ /* Wüste */
|
|
"die Goldene",
|
|
"der Grausame",
|
|
"der Sanddrache",
|
|
"der Durstige",
|
|
"die Verzehrende"
|
|
},
|
|
{ /* Sumpf */
|
|
"die Grüne",
|
|
"die Rote",
|
|
"der Furchtlose",
|
|
"der Allmächtige",
|
|
"der Weitblickende"
|
|
},
|
|
{ /* Gletscher */
|
|
"der Weiße",
|
|
"die Glänzende",
|
|
"der Wissende",
|
|
"die Unbarmherzige",
|
|
"die Schöne"
|
|
}
|
|
};
|
|
|
|
const char *
|
|
shadow_name(const unit *u)
|
|
{
|
|
if(u->no == 1) {
|
|
return "Schattendämon";
|
|
}
|
|
return "Schattendämonen";
|
|
}
|
|
|
|
const char *
|
|
drachen_name(const unit *u)
|
|
{
|
|
static char name[NAMESIZE + 1];
|
|
int rnd = rand() % DTITEL;
|
|
const char *t = dtitel[0][rnd];
|
|
int anzahl = 1;
|
|
|
|
if (u) {
|
|
region *r = u->region;
|
|
anzahl = u->number;
|
|
switch (rterrain(r)) {
|
|
case T_PLAIN:
|
|
t = dtitel[1][rnd];
|
|
break;
|
|
case T_MOUNTAIN:
|
|
t = dtitel[2][rnd];
|
|
break;
|
|
case T_DESERT:
|
|
t = dtitel[3][rnd];
|
|
break;
|
|
case T_SWAMP:
|
|
t = dtitel[4][rnd];
|
|
break;
|
|
case T_GLACIER:
|
|
t = dtitel[5][rnd];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (anzahl > 1) {
|
|
sprintf(name, "Die %sn von %s", t+4, rname(u->region, NULL));
|
|
} else {
|
|
char *n = malloc(32*sizeof(char));
|
|
|
|
strcpy(n, silbe1[rand() % SIL1]);
|
|
strcat(n, silbe2[rand() % SIL2]);
|
|
strcat(n, silbe3[rand() % SIL3]);
|
|
if (rand() % 5 > 2) {
|
|
sprintf(name, "%s, %s", n, t); /* "Name, der Titel" */
|
|
} else {
|
|
strcpy(name, t); /* "Der Titel Name" */
|
|
name[0] = (char) toupper(name[0]);
|
|
strcat(name, " ");
|
|
strcat(name, n);
|
|
}
|
|
if (u && (rand() % 3 == 0)) {
|
|
strcat(name, " von ");
|
|
strcat(name, rname(u->region, NULL));
|
|
}
|
|
}
|
|
|
|
return name;
|
|
}
|
|
|
|
/* Dracoide */
|
|
|
|
#define DRAC_PRE 13
|
|
static const char *drac_pre[DRAC_PRE] = {
|
|
"Siss",
|
|
"Xxaa",
|
|
"Shht",
|
|
"X'xixi",
|
|
"Xar",
|
|
"X'zish",
|
|
"X",
|
|
"Sh",
|
|
"R",
|
|
"Z",
|
|
"Y",
|
|
"L",
|
|
"Ck",
|
|
};
|
|
|
|
#define DRAC_MID 12
|
|
static const char *drac_mid[DRAC_MID] = {
|
|
"siss",
|
|
"xxaa",
|
|
"shht",
|
|
"xxi",
|
|
"xar",
|
|
"x'zish",
|
|
"x",
|
|
"sh",
|
|
"r",
|
|
"z'ck",
|
|
"y",
|
|
"rl"
|
|
};
|
|
|
|
#define DRAC_SUF 10
|
|
static const char *drac_suf[DRAC_SUF] = {
|
|
"xil",
|
|
"shh",
|
|
"s",
|
|
"x",
|
|
"arr",
|
|
"lll",
|
|
"lll",
|
|
"shack",
|
|
"ck",
|
|
"k"
|
|
};
|
|
|
|
const char *
|
|
dracoid_name(const unit *u)
|
|
{
|
|
static char name[NAMESIZE + 1];
|
|
int mid_syllabels;
|
|
|
|
u=u;
|
|
/* Wieviele Mittelteile? */
|
|
|
|
mid_syllabels = rand()%4;
|
|
|
|
strcpy(name, drac_pre[rand()%DRAC_PRE]);
|
|
while(mid_syllabels > 0) {
|
|
mid_syllabels--;
|
|
if(rand()%10 < 4) strcat(name,"'");
|
|
strcat(name, drac_mid[rand()%DRAC_MID]);
|
|
}
|
|
strcat(name, drac_suf[rand()%DRAC_SUF]);
|
|
return name;
|
|
}
|
|
|
|
const char *
|
|
abkz(const char *s, size_t max)
|
|
{
|
|
static char buf[32];
|
|
const char *p = s;
|
|
unsigned int c = 0;
|
|
int bpt;
|
|
int i;
|
|
|
|
max = min(max, 79);
|
|
|
|
/* Prüfen, ob Kurz genug */
|
|
|
|
if (strlen(s) <= max) {
|
|
return s;
|
|
}
|
|
/* Anzahl der Wörter feststellen */
|
|
|
|
while (*p != 0) {
|
|
/* Leerzeichen überspringen */
|
|
while (*p != 0 && !isalnum(*(unsigned char*)p))
|
|
p++;
|
|
|
|
/* Counter erhöhen */
|
|
if (*p != 0)
|
|
c++;
|
|
|
|
/* alnums überspringen */
|
|
while(*p != 0 && isalnum(*(unsigned char*)p))
|
|
p++;
|
|
}
|
|
|
|
/* Buchstaben pro Teilkürzel = max(1,max/AnzWort) */
|
|
|
|
bpt = max(1, max / c);
|
|
|
|
/* Einzelne Wörter anspringen und jeweils die ersten BpT kopieren */
|
|
|
|
p = s;
|
|
c = 0;
|
|
|
|
while (*p != 0 && c < max) {
|
|
/* Leerzeichen überspringen */
|
|
|
|
while (*p != 0 && !isalnum(*(unsigned char*)p))
|
|
p++;
|
|
|
|
/* alnums übertragen */
|
|
|
|
for (i = 0; i < bpt && *p != 0 && isalnum(*(unsigned char*)p); i++) {
|
|
buf[c] = *p;
|
|
c++;
|
|
p++;
|
|
}
|
|
|
|
/* Bis zum nächsten Leerzeichen */
|
|
|
|
while (c < max && *p != 0 && isalnum(*(unsigned char*)p))
|
|
p++;
|
|
}
|
|
|
|
buf[c] = 0;
|
|
|
|
return buf;
|
|
}
|
|
|
|
void
|
|
name_unit(unit *u)
|
|
{
|
|
char name[16];
|
|
|
|
if (u->race->generate_name) {
|
|
set_string(&u->name, (u->race->generate_name(u)));
|
|
} else {
|
|
sprintf(name, "%s %s", LOC(u->faction->locale, "unitdefault"), itoa36(u->no));
|
|
set_string(&u->name, name);
|
|
fset(u, FL_UNNAMED);
|
|
}
|
|
}
|