added an option to have certain races supply a description without a need to

set u->display everywhere. This was costing 24 MB of memory just for the
braineaters alone, a terrible waste.
This commit is contained in:
Enno Rehling 2007-06-25 01:50:34 +00:00
parent 2610986a5a
commit 25cd0e4b66
17 changed files with 75 additions and 24 deletions

View File

@ -604,6 +604,7 @@ cr_output_unit(FILE * F, const region * r,
{ {
/* Race attributes are always plural and item attributes always /* Race attributes are always plural and item attributes always
* singular */ * singular */
const char * str;
const item_type * lasttype; const item_type * lasttype;
int pr; int pr;
item *itm, *show; item *itm, *show;
@ -632,9 +633,10 @@ cr_output_unit(FILE * F, const region * r,
fprintf(F, "EINHEIT %d\n", u->no); fprintf(F, "EINHEIT %d\n", u->no);
fprintf(F, "\"%s\";Name\n", u->name); fprintf(F, "\"%s\";Name\n", u->name);
if (u->display && strlen(u->display)) str = u_description(u, f->locale);
fprintf(F, "\"%s\";Beschr\n", u->display); if (str) {
fprintf(F, "\"%s\";Beschr\n", str);
}
{ {
/* print faction information */ /* print faction information */
const faction * sf = visible_faction(f, u); const faction * sf = visible_faction(f, u);

View File

@ -40,6 +40,7 @@
/* util includes */ /* util includes */
#include <util/base36.h> #include <util/base36.h>
#include <util/bsdstring.h> #include <util/bsdstring.h>
#include <util/functions.h>
#include <util/rng.h> #include <util/rng.h>
/* Untote */ /* Untote */
@ -112,6 +113,12 @@ static const char *untot_nach[UNTOT_NACH] =
" aus der Unterwelt" " aus der Unterwelt"
}; };
static const char *
describe_braineater(unit * u, const struct locale * lang)
{
return LOC(lang, "describe_braineater");
}
const char * const char *
untoten_name(const unit * u) untoten_name(const unit * u)
{ {
@ -707,3 +714,21 @@ abkz(const char *s, size_t max)
return buf; return buf;
} }
void
register_names(void)
{
register_function((pf_generic)describe_braineater, "describe_braineater");
/* function name
* generate a name for a nonplayerunit
* race->generate_name() */
register_function((pf_generic)untoten_name, "nameundead");
register_function((pf_generic)skeleton_name, "nameskeleton");
register_function((pf_generic)zombie_name, "namezombie");
register_function((pf_generic)ghoul_name, "nameghoul");
register_function((pf_generic)drachen_name, "namedragon");
register_function((pf_generic)dracoid_name, "namedracoid");
register_function((pf_generic)shadow_name, "nameshadow");
}

View File

@ -18,7 +18,7 @@
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern void register_names(void);
const char *untoten_name(const struct unit * u); const char *untoten_name(const struct unit * u);
const char *skeleton_name(const struct unit * u); const char *skeleton_name(const struct unit * u);
const char *zombie_name(const struct unit * u); const char *zombie_name(const struct unit * u);

View File

@ -410,17 +410,6 @@ register_races(void)
register_function((pf_generic)allowed_fly, "moveflying"); register_function((pf_generic)allowed_fly, "moveflying");
register_function((pf_generic)allowed_dragon, "movedragon"); register_function((pf_generic)allowed_dragon, "movedragon");
/* function name
* generate a name for a nonplayerunit
* race->generate_name() */
register_function((pf_generic)untoten_name, "nameundead");
register_function((pf_generic)skeleton_name, "nameskeleton");
register_function((pf_generic)zombie_name, "namezombie");
register_function((pf_generic)ghoul_name, "nameghoul");
register_function((pf_generic)drachen_name, "namedragon");
register_function((pf_generic)dracoid_name, "namedracoid");
register_function((pf_generic)shadow_name, "nameshadow");
/* function age /* function age
* race->age() */ * race->age() */
register_function((pf_generic)age_undead, "ageundead"); register_function((pf_generic)age_undead, "ageundead");

View File

@ -79,6 +79,7 @@ typedef struct race {
race_t oldfamiliars[MAXMAGIETYP]; race_t oldfamiliars[MAXMAGIETYP];
const char *(*generate_name) (const struct unit *); const char *(*generate_name) (const struct unit *);
const char *(*describe) (const struct unit *, const struct locale *);
void (*age)(struct unit *u); void (*age)(struct unit *u);
boolean (*move_allowed)(const struct region *, const struct region *); boolean (*move_allowed)(const struct region *, const struct region *);
struct item * (*itemdrop)(const struct race *, int size); struct item * (*itemdrop)(const struct race *, int size);

View File

@ -235,7 +235,7 @@ bufunit(const faction * f, const unit * u, int indent, int mode)
{ {
int i, dh; int i, dh;
int getarnt = fval(u, UFL_PARTEITARNUNG); int getarnt = fval(u, UFL_PARTEITARNUNG);
const char *pzTmp; const char *pzTmp, *str;
building * b; building * b;
boolean isbattle = (boolean)(mode == see_battle); boolean isbattle = (boolean)(mode == see_battle);
int telepath_see = 0; int telepath_see = 0;
@ -630,18 +630,19 @@ bufunit(const faction * f, const unit * u, int indent, int mode)
} }
i = 0; i = 0;
if (u->display && u->display[0]) { str = u_description(u, f->locale);
if (str) {
rsize = strlcpy(bufp, "; ", size); rsize = strlcpy(bufp, "; ", size);
if (rsize>size) rsize = size-1; if (rsize>size) rsize = size-1;
size -= rsize; size -= rsize;
bufp += rsize; bufp += rsize;
rsize = strlcpy(bufp, u->display, size); rsize = strlcpy(bufp, str, size);
if (rsize>size) rsize = size-1; if (rsize>size) rsize = size-1;
size -= rsize; size -= rsize;
bufp += rsize; bufp += rsize;
i = u->display[strlen(u->display) - 1]; i = str[strlen(str) - 1];
} }
if (i != '!' && i != '?' && i != '.') { if (i != '!' && i != '?' && i != '.') {
if (size>1) { if (size>1) {

View File

@ -976,7 +976,9 @@ readunit(FILE * F)
} }
rds(F, &u->name); rds(F, &u->name);
if (lomem) rds(F, 0); if (lomem) rds(F, 0);
else rds(F, &u->display); else {
rds(F, &u->display);
}
#ifndef NDEBUG #ifndef NDEBUG
if (strlen(u->name)>=NAMESIZE) u->name[NAMESIZE] = 0; if (strlen(u->name)>=NAMESIZE) u->name[NAMESIZE] = 0;
if (u->display && strlen(u->display)>=DISPLAYSIZE) u->display[DISPLAYSIZE] = 0; if (u->display && strlen(u->display)>=DISPLAYSIZE) u->display[DISPLAYSIZE] = 0;
@ -1009,6 +1011,15 @@ readunit(FILE * F)
if (strlen(buf)) u->irace = rc_find(buf); if (strlen(buf)) u->irace = rc_find(buf);
else u->irace = u->race; else u->irace = u->race;
} }
if (u->race->describe) {
const char * rcdisp = u->race->describe(u, u->faction->locale);
if (u->display && rcdisp) {
/* see if the data file contains old descriptions */
if (strcmp(rcdisp, u->display)==0) {
set_string(&u->display, NULL);
}
}
}
if (u->faction == NULL) { if (u->faction == NULL) {
log_error(("unit %s has faction == NULL\n", unitname(u))); log_error(("unit %s has faction == NULL\n", unitname(u)));
u_setfaction(u, findfaction(MONSTER_FACTION)); u_setfaction(u, findfaction(MONSTER_FACTION));

View File

@ -154,7 +154,6 @@ spawn_braineaters(float chance)
unit *u = createunit(r, f0, 1+rng_int()%10+rng_int()%10, new_race[RC_HIRNTOETER]); unit *u = createunit(r, f0, 1+rng_int()%10+rng_int()%10, new_race[RC_HIRNTOETER]);
set_string(&u->name, "Hirntöter"); set_string(&u->name, "Hirntöter");
set_string(&u->display, "Wabernde grüne Schwaden treiben durch den Nebel und verdichten sich zu einer unheimlichen Kreatur, die nur aus einem langen Ruderschwanz und einem riesigen runden Maul zu bestehen scheint.");
set_level(u, SK_STEALTH, 1); set_level(u, SK_STEALTH, 1);
set_level(u, SK_OBSERVATION, 1); set_level(u, SK_OBSERVATION, 1);
next = rng_int() % (int)(chance*100); next = rng_int() % (int)(chance*100);

View File

@ -346,6 +346,17 @@ attrib_type at_private = {
a_readstring a_readstring
}; };
const char *
u_description(const unit * u, const struct locale * lang)
{
if (u->display && u->display[0]) {
return u->display;
} else if (u->race->describe) {
return u->race->describe(u, lang);
}
return NULL;
}
const char * const char *
uprivate(const unit * u) { uprivate(const unit * u) {
attrib * a = a_find(u->attribs, &at_private); attrib * a = a_find(u->attribs, &at_private);

View File

@ -171,7 +171,7 @@ extern const struct unit * u_peasants(void);
extern const struct unit * u_unknown(void); extern const struct unit * u_unknown(void);
extern struct unit * udestroy; extern struct unit * udestroy;
extern const char * u_description(const unit * u, const struct locale * lang);
extern struct skill * add_skill(struct unit * u, skill_t id); extern struct skill * add_skill(struct unit * u, skill_t id);
extern void remove_skill(struct unit *u, skill_t sk); extern void remove_skill(struct unit *u, skill_t sk);
extern struct skill * get_skill(const struct unit * u, skill_t id); extern struct skill * get_skill(const struct unit * u, skill_t id);

View File

@ -1532,6 +1532,8 @@ parse_races(xmlDocPtr doc)
assert(property!=NULL); assert(property!=NULL);
if (strcmp((const char*)property, "name")==0) { if (strcmp((const char*)property, "name")==0) {
rc->generate_name = (const char* (*)(const struct unit*))fun; rc->generate_name = (const char* (*)(const struct unit*))fun;
} else if (strcmp((const char*)property, "describe")==0) {
rc->describe = (const char* (*)(const struct unit*, const struct locale *))fun;
} else if (strcmp((const char*)property, "age")==0) { } else if (strcmp((const char*)property, "age")==0) {
rc->age = (void(*)(struct unit*))fun; rc->age = (void(*)(struct unit*))fun;
} else if (strcmp((const char*)property, "move")==0) { } else if (strcmp((const char*)property, "move")==0) {

View File

@ -22,7 +22,7 @@ init_tokens_str(const char * initstr, char * cmd)
if (state==NULL) { if (state==NULL) {
state = malloc(sizeof(parser_state)); state = malloc(sizeof(parser_state));
} }
if (state->current_cmd) free(state->current_cmd); else if (state->current_cmd) free(state->current_cmd);
state->current_cmd = cmd; state->current_cmd = cmd;
state->current_token = (const unsigned char *)initstr; state->current_token = (const unsigned char *)initstr;
} }

View File

@ -41,6 +41,7 @@
#include <kernel/plane.h> #include <kernel/plane.h>
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/names.h>
#include <kernel/teleport.h> #include <kernel/teleport.h>
#include <kernel/terrainid.h> #include <kernel/terrainid.h>
#include <kernel/unit.h> #include <kernel/unit.h>
@ -213,6 +214,7 @@ game_init(void)
init_xmas(); init_xmas();
register_races(); register_races();
register_names();
register_resources(); register_resources();
register_buildings(); register_buildings();
register_ships(); register_ships();

View File

@ -158,6 +158,7 @@ game_init(void)
debug_language("locales.log"); debug_language("locales.log");
register_races(); register_races();
register_names();
register_resources(); register_resources();
register_buildings(); register_buildings();
register_ships(); register_ships();

View File

@ -69,6 +69,7 @@
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/message.h> #include <kernel/message.h>
#include <kernel/names.h>
#include <kernel/plane.h> #include <kernel/plane.h>
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/region.h> #include <kernel/region.h>
@ -219,6 +220,7 @@ game_init(void)
debug_language("locales.log"); debug_language("locales.log");
register_races(); register_races();
register_names();
register_resources(); register_resources();
register_buildings(); register_buildings();
register_ships(); register_ships();

View File

@ -6,7 +6,11 @@
_x: preposition (15 /Troll/schwerter) _x: preposition (15 /Troll/schwerter)
_a: including article (ein Troll, a troll) _a: including article (ein Troll, a troll)
--> -->
<string name="describe_braineater">
<text locale="de">"Wabernde grüne Schwaden treiben durch den Nebel und
verdichten sich zu einer unheimlichen Kreatur, die nur aus einem langen
Ruderschwanz und einem riesigen runden Maul zu bestehen scheint."</text>
</string>
<namespace name="raceinfo"> <namespace name="raceinfo">
<string name="no_info"> <string name="no_info">
<text locale="de">Keine Informationen über diese Rasse verfügbar.</text> <text locale="de">Keine Informationen über diese Rasse verfügbar.</text>

View File

@ -572,6 +572,7 @@
</race> </race>
<race name="braineater" magres="0.900000" maxaura="1.000000" regaura="1.000000" recruitcost="50000" weight="100" capacity="540" speed="1.000000" hp="20" ac="1" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes"> <race name="braineater" magres="0.900000" maxaura="1.000000" regaura="1.000000" recruitcost="50000" weight="100" capacity="540" speed="1.000000" hp="20" ac="1" damage="0d0" unarmedattack="0" unarmeddefense="0" attackmodifier="6" defensemodifier="10" scarepeasants="yes" fly="yes" walk="yes" teach="no" invinciblenonmagic="yes">
<ai splitsize="500" killpeasants="yes" moverandom="yes" learn="yes"/> <ai splitsize="500" killpeasants="yes" moverandom="yes" learn="yes"/>
<function name="describe" value="describe_braineater"/>
<attack type="2" damage="3d15"/> <attack type="2" damage="3d15"/>
<attack type="3" damage="1d1"/> <attack type="3" damage="1d1"/>
<attack type="4" damage="1d1"/> <attack type="4" damage="1d1"/>