forked from github/server
- regionid() und die ersetzung von \\r entfernt.
- Neue Funktion für Steinkreise - Bugfix alta Steinkreisfunktion - Geschwindigkeit findfaction - Geschwindigkeit it_find - Einige Messages internationalisiert - Bugfix Startholz
This commit is contained in:
parent
0bd27124b2
commit
13172a28af
|
@ -1,5 +1,5 @@
|
|||
C++ = g++ ;
|
||||
CC = tcc ;
|
||||
CC = gcc ;
|
||||
|
||||
if ! $(HAVE_LUA) {
|
||||
HAVE_LUA = 1 ;
|
||||
|
|
|
@ -71,6 +71,7 @@ createmonsters(void)
|
|||
f->alive = 1;
|
||||
f->options = (char) pow(2, O_REPORT);
|
||||
addlist(&factions, f);
|
||||
fhash(f);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
|
|
@ -161,14 +161,11 @@ reset_translations(void)
|
|||
static void
|
||||
cr_output_str_list(FILE * F, const char *title, const strlist * S, const faction * f)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (!S) return;
|
||||
|
||||
fprintf(F, "%s\n", title);
|
||||
while (S) {
|
||||
s = replace_global_coords(S->s, f);
|
||||
fprintf(F, "\"%s\"\n", s);
|
||||
fprintf(F, "\"%s\"\n", S->s);
|
||||
S = S->next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -743,9 +743,7 @@ maintain(building * b, boolean first)
|
|||
region * r = b->region;
|
||||
boolean paid = true, work = first;
|
||||
unit * u;
|
||||
if (fval(b, BLD_MAINTAINED)) return true;
|
||||
if (b->type==NULL || b->type->maintenance==NULL) return true;
|
||||
if (is_cursed(b->attribs, C_NOCOST, 0)) {
|
||||
if (fval(b, BLD_MAINTAINED) || b->type==NULL || b->type->maintenance==NULL || is_cursed(b->attribs, C_NOCOST, 0)) {
|
||||
fset(b, BLD_MAINTAINED);
|
||||
fset(b, BLD_WORKING);
|
||||
return true;
|
||||
|
@ -1962,8 +1960,9 @@ expandselling(region * r, request * sellorders, int limit)
|
|||
if (taxcollected > 0) {
|
||||
change_money(maxowner, (int) taxcollected);
|
||||
add_income(maxowner, IC_TRADETAX, taxcollected, taxcollected);
|
||||
/* sprintf(buf, "%s verdient %d Silber durch den Handel in %s.",
|
||||
unitname(maxowner), (int) taxcollected, regionid(r)); */
|
||||
/* TODO: Meldung
|
||||
* sprintf(buf, "%s verdient %d Silber durch den Handel in %s.",
|
||||
* unitname(maxowner), (int) taxcollected, regionname(r)); */
|
||||
}
|
||||
}
|
||||
if (hafenowner) {
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include <kernel/ship.h>
|
||||
#include <kernel/skill.h>
|
||||
#include <kernel/spy.h>
|
||||
#include <kernel/teleport.h>
|
||||
#include <kernel/unit.h>
|
||||
#ifdef USE_UGROUPS
|
||||
# include <kernel/ugroup.h>
|
||||
|
@ -2840,7 +2841,9 @@ renumber_factions(void)
|
|||
sql_print(("UPDATE subscriptions set faction='%s' where id=%u;\n",
|
||||
itoa36(rp->want), f->subscription));
|
||||
}
|
||||
funhash(f);
|
||||
f->no = rp->want;
|
||||
fhash(f);
|
||||
register_faction_id(rp->want);
|
||||
fset(f, FF_NEWID);
|
||||
}
|
||||
|
@ -3161,6 +3164,79 @@ renumber(void)
|
|||
renumber_factions();
|
||||
}
|
||||
|
||||
static building *
|
||||
age_building(building * b)
|
||||
{
|
||||
static const building_type * bt_blessed = (const building_type*)0xdeadbeef;
|
||||
static const curse_type * ct_astralblock = NULL;
|
||||
if (bt_blessed==(const building_type*)0xdeadbeef) {
|
||||
bt_blessed = bt_find("blessedstonecircle");
|
||||
ct_astralblock = ct_find("astralblock");
|
||||
}
|
||||
|
||||
/* blesses stone circles create an astral protection in the astral region
|
||||
* above the shield, which prevents chaos suction and other spells.
|
||||
* The shield is created when a magician enters the blessed stone circle,
|
||||
* and lasts for as long as his skill level / 2 is, at no mana cost.
|
||||
*
|
||||
* TODO: this would be nicer in a btype->age function, but we don't have it.
|
||||
*/
|
||||
if (ct_astralblock && bt_blessed && b->type==bt_blessed) {
|
||||
region * r = b->region;
|
||||
region * rt = r_standard_to_astral(r);
|
||||
unit * u, * mage = NULL;
|
||||
|
||||
/* step 1: give unicorns to people in the building,
|
||||
* find out if there's a magician in there. */
|
||||
for (u=r->units;u;u=u->next) {
|
||||
if (b==u->building && inside_building(u)) {
|
||||
if (!(u->race->ec_flags & NOGIVE)) {
|
||||
int n, unicorns = 0;
|
||||
for (n=0; n!=u->number; ++n) {
|
||||
if (chance(0.02)) {
|
||||
change_item(u, I_UNICORN, 1);
|
||||
++unicorns;
|
||||
}
|
||||
if (unicorns) {
|
||||
ADDMSG(&u->faction->msgs, msg_message("scunicorn",
|
||||
"unit amount type", u, unicorns,
|
||||
olditemtype[I_UNICORN]->rtype));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mage==NULL && is_mage(u)) {
|
||||
mage = u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if there's a magician, and a connection to astral space, create the
|
||||
* curse. */
|
||||
if (rt!=NULL && mage!=NULL) {
|
||||
curse * c = get_curse(rt->attribs, ct_astralblock);
|
||||
if (c==NULL) {
|
||||
if (mage!=NULL) {
|
||||
int sk = effskill(mage, SK_MAGIC);
|
||||
/* the mage reactivates the circle */
|
||||
c = create_curse(mage, &rt->attribs, ct_astralblock,
|
||||
sk, sk/2, 100, 0);
|
||||
ADDMSG(&r->msgs, msg_message("astralshield_activate",
|
||||
"region unit", r, mage));
|
||||
}
|
||||
} else if (mage!=NULL) {
|
||||
int sk = effskill(mage, SK_MAGIC);
|
||||
c->duration = max(c->duration, sk/2);
|
||||
c->vigour = max(c->vigour, sk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a_age(&b->attribs);
|
||||
handle_event(&b->attribs, "timer", b);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static void
|
||||
ageing(void)
|
||||
{
|
||||
|
@ -3209,6 +3285,7 @@ ageing(void)
|
|||
|
||||
a_age(&r->attribs);
|
||||
handle_event(&r->attribs, "timer", r);
|
||||
|
||||
/* Einheiten */
|
||||
for (up=&r->units;*up;) {
|
||||
unit * u = *up;
|
||||
|
@ -3216,6 +3293,7 @@ ageing(void)
|
|||
if (u==*up) handle_event(&u->attribs, "timer", u);
|
||||
if (u==*up) up = &(*up)->next;
|
||||
}
|
||||
|
||||
/* Schiffe */
|
||||
for (sp=&r->ships;*sp;) {
|
||||
ship * s = *sp;
|
||||
|
@ -3223,11 +3301,12 @@ ageing(void)
|
|||
if (s==*sp) handle_event(&s->attribs, "timer", s);
|
||||
if (s==*sp) sp = &(*sp)->next;
|
||||
}
|
||||
|
||||
/* Gebäude */
|
||||
for (bp=&r->buildings;*bp;) {
|
||||
building * b = *bp;
|
||||
a_age(&b->attribs);
|
||||
if (b==*bp) handle_event(&b->attribs, "timer", b);
|
||||
b = age_building(b);
|
||||
|
||||
if (b==*bp) bp = &(*bp)->next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -404,7 +404,8 @@ set_new_dragon_target(unit * u, region * r, int range)
|
|||
} else {
|
||||
a->data.v = max_region;
|
||||
}
|
||||
sprintf(buf, "Kommt aus: %s, Will nach: %s", regionid(r), regionid(max_region));
|
||||
sprintf(buf, "Kommt aus: %s, Will nach: %s",
|
||||
regionname(r, u->faction), regionname(max_region, u->faction));
|
||||
usetprivate(u, buf);
|
||||
return a;
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ dissolve_units(void)
|
|||
for (u=r->units;u;u=u->next) {
|
||||
attrib * a = a_find(u->attribs, &at_unitdissolve);
|
||||
if (a) {
|
||||
const char * str = NULL;
|
||||
if (u->age == 0 && a->data.ca[1] < 100) continue;
|
||||
|
||||
/* TODO: Durch einzelne Berechnung ersetzen */
|
||||
|
@ -114,15 +115,13 @@ dissolve_units(void)
|
|||
|
||||
scale_number(u, u->number - n);
|
||||
|
||||
sprintf(buf, "%s in %s: %d %s ", unitname(u), regionid(r),
|
||||
n, LOC(default_locale, rc_name(u->race, n!=1)));
|
||||
switch(a->data.ca[0]) {
|
||||
case 1:
|
||||
rsetpeasants(r, rpeasants(r) + n);
|
||||
if (n == 1) {
|
||||
scat("kehrte auf sein Feld zurück.");
|
||||
str = "kehrte auf sein Feld zurück.";
|
||||
} else {
|
||||
scat("kehrten auf ihre Felder zurück.");
|
||||
str = "kehrten auf ihre Felder zurück.";
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
|
@ -133,35 +132,36 @@ dissolve_units(void)
|
|||
rsettrees(r, rtrees(r) + n);
|
||||
#endif
|
||||
if (n == 1) {
|
||||
scat("wurde zum Baum.");
|
||||
str = "wurde zum Baum.";
|
||||
} else {
|
||||
scat("wurden zu Bäumen.");
|
||||
str = "wurden zu Bäumen.";
|
||||
}
|
||||
} else {
|
||||
if(n == 1) {
|
||||
scat("verfaulte in der feuchten Seeluft.");
|
||||
str = "verfaulte in der feuchten Seeluft.";
|
||||
} else {
|
||||
scat("verfaulten in der feuchten Seeluft.");
|
||||
str = "verfaulten in der feuchten Seeluft.";
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (u->race == new_race[RC_STONEGOLEM] || u->race == new_race[RC_IRONGOLEM]) {
|
||||
if (n == 1) {
|
||||
scat("zerfiel zu Staub.");
|
||||
str = "zerfiel zu Staub.";
|
||||
} else {
|
||||
scat("zerfielen zu Staub.");
|
||||
str = "zerfielen zu Staub.";
|
||||
}
|
||||
}else{
|
||||
if (n == 1) {
|
||||
scat("verschwand über Nacht.");
|
||||
str = "verschwand über Nacht.";
|
||||
}else{
|
||||
scat("verschwanden über Nacht.");
|
||||
str = "verschwanden über Nacht.";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
addmessage(r, u->faction, buf, MSG_EVENT, ML_INFO);
|
||||
ADDMSG(&u->faction->msgs, msg_message("dissolve_units",
|
||||
"unit region number race action", u, r, n, u->race, str));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -606,9 +606,7 @@ chaos(region * r)
|
|||
}
|
||||
u = u2;
|
||||
}
|
||||
sprintf(buf, "Ein gewaltige Flutwelle verschlingt %s und "
|
||||
"alle Bewohner.", regionid(r));
|
||||
addmessage(r, 0, buf, MSG_EVENT, ML_IMPORTANT);
|
||||
ADDMSG(&r->msgs, msg_message("tidalwave", "region", r));
|
||||
|
||||
for (b = rbuildings(r); b;) {
|
||||
b2 = b->next;
|
||||
|
@ -1312,24 +1310,6 @@ randomevents(void)
|
|||
} /* !RACE_ADJUSTMENTS */
|
||||
#endif
|
||||
|
||||
for (u=r->units; u; u=u->next) {
|
||||
if (!(u->race->ec_flags & NOGIVE)) {
|
||||
struct building * b = inside_building(u);
|
||||
const struct building_type * btype = b?b->type:NULL;
|
||||
if (btype == bt_find("blessedstonecircle")) {
|
||||
int n, c = 0;
|
||||
for (n=0; n<u->number; n++) if (rand()%100 < 2) {
|
||||
change_item(u, I_UNICORN, 1);
|
||||
c++;
|
||||
}
|
||||
if (c) {
|
||||
ADDMSG(&u->faction->msgs, new_message(u->faction,
|
||||
"scunicorn%u:unit%i:amount%X:type",u,c,
|
||||
olditemtype[I_UNICORN]->rtype));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Orkifizierte Regionen mutieren und mutieren zurück */
|
||||
|
|
|
@ -290,10 +290,6 @@ rpsnr(FILE * F, const char * s, int offset)
|
|||
char ui=0;
|
||||
size_t indent = 0, len;
|
||||
|
||||
/* Geht nicht: Privatbeschreibungen der Monster enthalten
|
||||
* \\r-Koordinaten ! */
|
||||
/* assert(!strstr(s, "\\r(") || !"error: regionid not translated"); */
|
||||
|
||||
len = strlen(s);
|
||||
while (*x++ == ' ');
|
||||
indent = x - s - 1;
|
||||
|
@ -396,16 +392,7 @@ rnl(FILE * F)
|
|||
static void
|
||||
rps(FILE * F, const char * src)
|
||||
{
|
||||
char * s;
|
||||
|
||||
if (strstr(src, "\\r(")) {
|
||||
s = replace_global_coords(src, current_faction);
|
||||
} else if(src != buf) {
|
||||
s = strcpy(buf, src);
|
||||
} else {
|
||||
s = (char *)src;
|
||||
}
|
||||
rpsnr(F, s, 0);
|
||||
rpsnr(F, src, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -762,20 +749,12 @@ print_curses(FILE *F, const faction *viewer, const void * obj, typ_t typ, int in
|
|||
}
|
||||
}
|
||||
|
||||
char *
|
||||
replace_global_coords(const char *s, const faction * f)
|
||||
{
|
||||
return translate_regions(s, f);
|
||||
}
|
||||
|
||||
static void
|
||||
rps_nowrap(FILE * F, const char *s)
|
||||
{
|
||||
const char *x = s;
|
||||
int indent = 0;
|
||||
|
||||
x = s = replace_global_coords(s, current_faction);
|
||||
|
||||
while (*x++ == ' ');
|
||||
indent = x - s - 1;
|
||||
if (*(x - 1) && indent && *x == ' ')
|
||||
|
|
|
@ -440,11 +440,11 @@ sink_ship(region * r, ship * sh, const char *name, char spy, unit * saboteur)
|
|||
{
|
||||
vset_add(&survivors, u);
|
||||
if (dead > 0) {
|
||||
strcat(strcpy(buffer, unit_lives_msg), regionid(safety));
|
||||
strcat(strcpy(buffer, unit_lives_msg), regionname(safety, u->faction));
|
||||
sprintf(buf, (dead == 1) ? person_lost_msg : persons_lost_msg,
|
||||
dead, unitname(u), buffer);
|
||||
} else
|
||||
sprintf(buf, unit_intact_msg, unitname(u), regionid(safety));
|
||||
sprintf(buf, unit_intact_msg, unitname(u), regionname(safety, u->faction));
|
||||
addmessage(0, u->faction, buf, MSG_EVENT, ML_WARN);
|
||||
set_leftship(u, u->ship);
|
||||
u->ship = 0;
|
||||
|
|
|
@ -40,7 +40,6 @@ use_speedsail(struct unit * u, const struct item_type * itype, int amount, struc
|
|||
unused(itype);
|
||||
if (p!=NULL) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "use_realworld_only", ""));
|
||||
return EUNUSABLE;
|
||||
} else {
|
||||
if (u->ship) {
|
||||
attrib * a = a_find(u->ship->attribs, &at_speedup);
|
||||
|
@ -49,6 +48,8 @@ use_speedsail(struct unit * u, const struct item_type * itype, int amount, struc
|
|||
a->data.sa[0] = 50; /* speed */
|
||||
a->data.sa[1] = 50; /* decay */
|
||||
ADDMSG(&u->faction->msgs, msg_message("use_speedsail", "unit", u));
|
||||
/* Ticket abziehen */
|
||||
i_change(&u->items, itype, -1);
|
||||
return 0;
|
||||
} else {
|
||||
cmistake(u, ord, 211, MSG_EVENT);
|
||||
|
@ -56,8 +57,8 @@ use_speedsail(struct unit * u, const struct item_type * itype, int amount, struc
|
|||
} else {
|
||||
cmistake(u, ord, 144, MSG_EVENT);
|
||||
}
|
||||
return EUNUSABLE;
|
||||
}
|
||||
return EUNUSABLE;
|
||||
}
|
||||
|
||||
static resource_type rt_speedsail = {
|
||||
|
|
|
@ -261,10 +261,11 @@ static void
|
|||
battledebug(const char *s)
|
||||
{
|
||||
#if SHOW_DEBUG
|
||||
printf("%s\n", translate_regions(s, NULL));
|
||||
puts(s);
|
||||
putc('\n');
|
||||
#endif
|
||||
if (bdebug) {
|
||||
dbgprintf((bdebug, "%s\n", translate_regions(s, NULL)));
|
||||
dbgprintf((bdebug, "%s\n", s));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -529,7 +529,7 @@ build_road(region * r, unit * u, int size, direction_t d)
|
|||
|
||||
if (n <= 0) {
|
||||
sprintf(buf, "In %s gibt es keine Brücken und Straßen "
|
||||
"mehr zu bauen", regionid(r));
|
||||
"mehr zu bauen", regionname(r, u->faction));
|
||||
mistake(u, u->thisorder, buf, MSG_PRODUCE);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -151,11 +151,16 @@ int
|
|||
buildingcapacity(const building * b)
|
||||
{
|
||||
if (b->type->capacity>=0) {
|
||||
if (b->type->maxcapacity>=0)
|
||||
if (b->type->maxcapacity>=0) {
|
||||
return min(b->type->maxcapacity, b->size * b->type->capacity);
|
||||
}
|
||||
return b->size * b->type->capacity;
|
||||
}
|
||||
if (b->size>=b->type->maxsize) return b->type->maxcapacity;
|
||||
if (b->size>=b->type->maxsize) {
|
||||
if (b->type->maxcapacity>=0) {
|
||||
return b->type->maxcapacity;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1500,15 +1500,8 @@ boolean enable_fuzzy = false;
|
|||
faction *
|
||||
findfaction (int n)
|
||||
{
|
||||
faction * f;
|
||||
|
||||
f = ffindhash(n);
|
||||
if (f) return f;
|
||||
for (f = factions; f; f = f->next)
|
||||
if (f->no == n) {
|
||||
fhash(f);
|
||||
faction * f = ffindhash(n);
|
||||
return f;
|
||||
}
|
||||
#ifdef FUZZY_BASE36
|
||||
if(enable_fuzzy) {
|
||||
n = atoi(itoa36(n));
|
||||
|
@ -1523,10 +1516,8 @@ findfaction (int n)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif /* FUZZY_BASE36 */
|
||||
/* Gibt komische Seiteneffekte hier! */
|
||||
/* if (n==MONSTER_FACTION) return makemonsters(); */
|
||||
return NULL;
|
||||
#endif /* FUZZY_BASE36 */
|
||||
}
|
||||
|
||||
faction *
|
||||
|
@ -1718,20 +1709,6 @@ cstring(const char *s)
|
|||
return r;
|
||||
}
|
||||
|
||||
const char *
|
||||
regionid(const region * r)
|
||||
{
|
||||
char *buf = idbuf[(++nextbuf) % 8];
|
||||
|
||||
if (!r) {
|
||||
strcpy(buf, "(Chaos)");
|
||||
} else {
|
||||
sprintf(buf, "\\r(%d,%d)", r->x, r->y);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *
|
||||
buildingname (const building * b)
|
||||
{
|
||||
|
@ -1772,14 +1749,6 @@ unitname(const unit * u)
|
|||
return ubuf;
|
||||
}
|
||||
|
||||
char *
|
||||
xunitid(const unit *u)
|
||||
{
|
||||
char *buf = idbuf[(++nextbuf) % 8];
|
||||
sprintf(buf, "%s in %s", unitname(u), regionid(u->region));
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* -- Erschaffung neuer Einheiten ------------------------------ */
|
||||
|
||||
extern faction * dfindhash(int i);
|
||||
|
|
|
@ -351,7 +351,7 @@ extern void plagues(struct region * r, boolean ismagic);
|
|||
#define IDSIZE 15 /* max. Länge einer no (als String), ohne trailing 0 */
|
||||
#define KEYWORDSIZE 15 /* max. Länge eines Keyword, ohne trailing 0 */
|
||||
#define OBJECTIDSIZE (NAMESIZE+5+IDSIZE) /* max. Länge der Strings, die
|
||||
* von struct unitname, regionid, etc. zurückgegeben werden. ohne die 0 */
|
||||
* von struct unitname, etc. zurückgegeben werden. ohne die 0 */
|
||||
#define CMDSIZE (DISPLAYSIZE*2+1)
|
||||
#define STARTMONEY 5000
|
||||
|
||||
|
@ -1007,9 +1007,7 @@ struct region *findunitregion(const struct unit * su);
|
|||
|
||||
char *estring(const char *s);
|
||||
char *cstring(const char *s);
|
||||
const char *regionid(const struct region * r);
|
||||
const char *unitname(const struct unit * u);
|
||||
char *xunitid(const struct unit * u);
|
||||
|
||||
struct building *largestbuilding(const struct region * r, boolean img);
|
||||
|
||||
|
|
|
@ -123,12 +123,12 @@ addfaction(const char *email, const char * password,
|
|||
|
||||
f->no = unused_faction_id();
|
||||
register_faction_id(f->no);
|
||||
addlist(&factions, f);
|
||||
fhash(f);
|
||||
|
||||
sprintf(buf, "%s %s", LOC(loc, "factiondefault"), factionid(f));
|
||||
set_string(&f->name, buf);
|
||||
|
||||
addlist(&factions, f);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,9 +52,11 @@ resource_type * resourcetypes;
|
|||
weapon_type * weapontypes;
|
||||
luxury_type * luxurytypes;
|
||||
potion_type * potiontypes;
|
||||
item_type * itemtypes;
|
||||
herb_type * herbtypes;
|
||||
|
||||
#define IMAXHASH 127
|
||||
static item_type * itemtypes[IMAXHASH];
|
||||
|
||||
#ifdef AT_PTYPE
|
||||
static attrib_type at_ptype = { "potion_type" };
|
||||
#endif
|
||||
|
@ -178,7 +180,9 @@ new_resourcetype(const char ** names, const char ** appearances, int flags)
|
|||
void
|
||||
it_register(item_type * itype)
|
||||
{
|
||||
item_type ** p_itype = &itemtypes;
|
||||
int hash = hashstring(itype->rtype->_name[0]);
|
||||
int key = hash % IMAXHASH;
|
||||
item_type ** p_itype = &itemtypes[key];
|
||||
while (*p_itype && *p_itype != itype) p_itype = &(*p_itype)->next;
|
||||
if (*p_itype==NULL) {
|
||||
#ifdef AT_ITYPE
|
||||
|
@ -452,12 +456,18 @@ it_find(const char * zname)
|
|||
const char * name = it_alias(zname);
|
||||
unsigned int hash = hashstring(name);
|
||||
item_type * itype;
|
||||
unsigned int key = hash % IMAXHASH;
|
||||
|
||||
for (itype=itemtypes; itype; itype=itype->next)
|
||||
if (itype->rtype->hashkey==hash && strcmp(itype->rtype->_name[0], name) == 0) break;
|
||||
if (!itype) for (itype=itemtypes; itype; itype=itype->next)
|
||||
for (itype=itemtypes[key]; itype; itype=itype->next) {
|
||||
if (itype->rtype->hashkey==hash && strcmp(itype->rtype->_name[0], name) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (itype==NULL) {
|
||||
for (itype=itemtypes[key]; itype; itype=itype->next) {
|
||||
if (strcmp(itype->rtype->_name[1], name) == 0) break;
|
||||
|
||||
}
|
||||
}
|
||||
return itype;
|
||||
}
|
||||
|
||||
|
@ -2285,7 +2295,6 @@ init_itemnames(void)
|
|||
int i;
|
||||
for (i=0;localenames[i];++i) {
|
||||
const struct locale * lang = find_locale(localenames[i]);
|
||||
const item_type * itl = itemtypes;
|
||||
boolean exist = false;
|
||||
local_names * in = inames;
|
||||
|
||||
|
@ -2299,14 +2308,20 @@ init_itemnames(void)
|
|||
if (in==NULL) in = calloc(sizeof(local_names), 1);
|
||||
in->next = inames;
|
||||
in->lang = lang;
|
||||
while (itl) {
|
||||
|
||||
if (!exist) {
|
||||
int key;
|
||||
for (key=0;key!=IMAXHASH;++key) {
|
||||
const item_type * itl;
|
||||
for (itl=itemtypes[key];itl;itl=itl->next) {
|
||||
void * result = NULL;
|
||||
const char * iname = locale_string(lang, itl->rtype->_name[0]);
|
||||
if (!exist || findtoken(&in->names, iname, &result)==E_TOK_NOMATCH || result!=itl) {
|
||||
if (findtoken(&in->names, iname, &result)==E_TOK_NOMATCH || result!=itl) {
|
||||
addtoken(&in->names, iname, (void*)itl);
|
||||
addtoken(&in->names, locale_string(lang, itl->rtype->_name[1]), (void*)itl);
|
||||
}
|
||||
itl=itl->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
inames = in;
|
||||
}
|
||||
|
|
|
@ -135,7 +135,6 @@ typedef struct item_type {
|
|||
struct item_type * next;
|
||||
} item_type;
|
||||
|
||||
extern item_type * itemtypes;
|
||||
extern const item_type * finditemtype(const char * name, const struct locale * lang);
|
||||
extern void init_itemnames(void);
|
||||
|
||||
|
|
|
@ -572,7 +572,7 @@ jihad_attacks(void)
|
|||
|
||||
if(doit == false) continue;
|
||||
|
||||
printf("\tPogrom durch %s in %s\n", factionid(f), regionid(r));
|
||||
log_printf("-->> Pogrom durch %s in %s\n", factionid(f), regionname(r, NULL));
|
||||
|
||||
for(u2 = r->units; u; u=u->next) if(u2->faction == f) {
|
||||
for(u=r->units; u; u=u->next) if(jihad(f, u->race)) {
|
||||
|
|
|
@ -952,7 +952,7 @@ cancast(unit * u, spell * sp, int level, int range, struct order * ord)
|
|||
/* Noch fehlte keine Komponente, wir generieren den Anfang der
|
||||
* Fehlermeldung */
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s' Für diesen Zauber fehlen "
|
||||
"noch %d ", unitname(u), regionid(u->region),
|
||||
"noch %d ", unitname(u), regionname(u->region, u->faction),
|
||||
spell_name(sp, u->faction->locale),
|
||||
itemanz);
|
||||
scat(locale_string(u->faction->locale,
|
||||
|
@ -2559,7 +2559,7 @@ magic(void)
|
|||
if (range > 1024) { /* (2^10) weiter als 10 Regionen entfernt */
|
||||
ADDMSG(&u->faction->msgs, msg_message("spellfail::nocontact",
|
||||
"mage region command target", u, u->region, ord,
|
||||
gc_add(strdup(regionid(target_r)))));
|
||||
gc_add(strdup(regionname(target_r, u->faction)))));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,65 +57,6 @@ typedef struct msg_setting {
|
|||
#define MAXSTRLEN (4*DISPLAYSIZE+3)
|
||||
#include "region.h"
|
||||
#include "eressea.h"
|
||||
const char *
|
||||
translate_regions(const char *st, const faction * f)
|
||||
{
|
||||
static char temp[MAXSTRLEN + 1];
|
||||
char *s, *t = temp;
|
||||
const char *p = st;
|
||||
char *c = strstr(p, "\\r(");
|
||||
|
||||
if (!c) return strcpy(temp, st);
|
||||
|
||||
temp[0] = 0;
|
||||
do {
|
||||
static region *r;
|
||||
static int cache_x = -999999, cache_y = -999999;
|
||||
int koor_x, koor_y;
|
||||
int x = MAXSTRLEN - (t - temp);
|
||||
plane *cache_pl = NULL;
|
||||
|
||||
if (c - p < x)
|
||||
x = c - p;
|
||||
|
||||
s = temp;
|
||||
strnzcpy(t, p, x);
|
||||
t += (c - p);
|
||||
p = c + 3;
|
||||
koor_x = atoi(p);
|
||||
p = strchr(p, ',') + 1;
|
||||
koor_y = atoi(p);
|
||||
|
||||
if (koor_x != cache_x || koor_y != cache_y) {
|
||||
r = findregion(koor_x, koor_y);
|
||||
cache_x = koor_x;
|
||||
cache_y = koor_y;
|
||||
cache_pl = getplane(r);
|
||||
}
|
||||
|
||||
if (r!=NULL) {
|
||||
const char *rn;
|
||||
|
||||
if (f!=NULL) {
|
||||
rn = rname(r, f->locale);
|
||||
} else {
|
||||
rn = rname(r, default_locale);
|
||||
}
|
||||
if(rn && *rn) {
|
||||
sprintf(t, "%s (%d,%d)", rn, region_x(r, f), region_y(r, f));
|
||||
} else {
|
||||
sprintf(t, "(%d,%d)", region_x(r, f), region_y(r, f));
|
||||
}
|
||||
} else strcpy(t, "(Chaos)");
|
||||
|
||||
t += strlen(t);
|
||||
p = strchr(p, ')') + 1;
|
||||
c = strstr(p, "\\r(");
|
||||
} while (c!= NULL);
|
||||
if (s == temp)
|
||||
strcat(t, p);
|
||||
return s;
|
||||
}
|
||||
|
||||
messageclass * msgclasses;
|
||||
|
||||
|
@ -382,14 +323,14 @@ caddmessage(region * r, faction * f, const char *s, msg_t mtype, int level)
|
|||
void
|
||||
addmessage(region * r, faction * f, const char *s, msg_t mtype, int level)
|
||||
{
|
||||
caddmessage(r, f, gc_add(strdup(translate_regions(s, f))), mtype, level);
|
||||
caddmessage(r, f, gc_add(strdup(s)), mtype, level);
|
||||
}
|
||||
|
||||
void
|
||||
mistake(const unit * u, struct order * ord, const char *comment, int mtype)
|
||||
{
|
||||
if (u->faction->no != MONSTER_FACTION) {
|
||||
char * cmt = strdup(translate_regions(comment, u->faction));
|
||||
char * cmt = strdup(comment);
|
||||
ADDMSG(&u->faction->msgs, msg_message("mistake",
|
||||
"command error unit region", copy_order(ord), cmt, u, u->region));
|
||||
}
|
||||
|
|
|
@ -1655,9 +1655,9 @@ sail(unit * u, order * ord, boolean move_on_land, region_list **routep)
|
|||
else
|
||||
scat("segelt");
|
||||
scat(" von ");
|
||||
scat(regionid(starting_point));
|
||||
scat(regionname(starting_point, u->faction));
|
||||
scat(" nach ");
|
||||
scat(regionid(current_point));
|
||||
scat(regionname(current_point, u->faction));
|
||||
scat(".");
|
||||
addmessage(0, u->faction, buf, MSG_MOVE, ML_INFO);
|
||||
|
||||
|
|
|
@ -138,35 +138,30 @@ typdata_t typdata[] = {
|
|||
/* TYP_UNIT */ {
|
||||
(ID_fun)unit_ID,
|
||||
(find_fun)unit_find,
|
||||
(desc_fun)unitname,
|
||||
(attrib_fun)unit_attribs,
|
||||
(set_fun)unit_set,
|
||||
},
|
||||
/* TYP_REGION */ {
|
||||
(ID_fun)region_ID,
|
||||
(find_fun)region_find,
|
||||
(desc_fun)regionid,
|
||||
(attrib_fun)region_attribs,
|
||||
(set_fun)region_set,
|
||||
},
|
||||
/* TYP_BUILDING */ {
|
||||
(ID_fun)building_ID,
|
||||
(find_fun)building_find,
|
||||
(desc_fun)buildingname,
|
||||
(attrib_fun)building_attribs,
|
||||
(set_fun)building_set,
|
||||
},
|
||||
/* TYP_SHIP */ {
|
||||
(ID_fun)ship_ID,
|
||||
(find_fun)ship_find,
|
||||
(desc_fun)shipname,
|
||||
(attrib_fun)ship_attribs,
|
||||
(set_fun)ship_set,
|
||||
},
|
||||
/* TYP_FACTION */ {
|
||||
(ID_fun)faction_ID,
|
||||
(find_fun)faction_find,
|
||||
(desc_fun)notimplemented_desc,
|
||||
(attrib_fun)faction_attribs,
|
||||
(set_fun)faction_set,
|
||||
},
|
||||
|
|
|
@ -44,7 +44,6 @@ extern void resolve_IDs(void);
|
|||
|
||||
typedef obj_ID (*ID_fun)(void *obj);
|
||||
typedef void *(*find_fun)(obj_ID id);
|
||||
typedef char *(*desc_fun)(void *obj);
|
||||
typedef attrib **(*attrib_fun)(void *obj);
|
||||
typedef void (*set_fun)(void *ptrptr, void *obj); /* *ptrptr = obj */
|
||||
|
||||
|
@ -52,7 +51,6 @@ typedef void (*set_fun)(void *ptrptr, void *obj); /* *ptrptr = obj */
|
|||
typedef struct {
|
||||
ID_fun getID; /* liefert obj_ID zu struct unit* */
|
||||
find_fun find; /* liefert struct unit* zu obj_ID */
|
||||
desc_fun getname; /* unitname() */
|
||||
attrib_fun getattribs; /* liefert &u->attribs */
|
||||
set_fun ppset; /* setzt *(struct unit **) zu struct unit* */
|
||||
} typdata_t;
|
||||
|
|
|
@ -870,10 +870,12 @@ get_addresses(faction * f)
|
|||
region *r, *last = f->last?f->last:lastregion(f);
|
||||
const faction * lastf = NULL;
|
||||
faction_list * flist = calloc(1, sizeof(faction_list));
|
||||
flist->data = findfaction(f->no);
|
||||
flist->data = f;
|
||||
|
||||
for (r=f->first?f->first:firstregion(f);r!=last;r=r->next) {
|
||||
const unit * u = r->units;
|
||||
const seen_region * sr = find_seen(r);
|
||||
|
||||
if (sr==NULL) continue;
|
||||
while (u!=NULL) {
|
||||
faction * sf = visible_faction(f, u);
|
||||
|
|
|
@ -56,9 +56,6 @@ extern struct summary * make_summary(boolean count_new);
|
|||
|
||||
int hat_in_region(item_t itm, struct region * r, struct faction * f);
|
||||
|
||||
char *translate_regions(const char *st, const struct faction * f);
|
||||
|
||||
char *replace_global_coords(const char *s, const struct faction * f);
|
||||
|
||||
char *f_regionid(const struct region *r, const struct faction *f);
|
||||
|
||||
|
|
|
@ -1029,9 +1029,8 @@ readunit(FILE * F)
|
|||
u_setfaction(u, NULL);
|
||||
}
|
||||
{
|
||||
faction * f;
|
||||
int n = rid(F);
|
||||
f = findfaction(n);
|
||||
faction * f = findfaction(n);
|
||||
if (f!=u->faction) u_setfaction(u, f);
|
||||
}
|
||||
rds(F, &u->name);
|
||||
|
@ -1812,6 +1811,7 @@ readgame(const char * filename, int backup)
|
|||
while (--n >= 0) {
|
||||
faction * f = readfaction(F);
|
||||
addlist2(fp, f);
|
||||
fhash(f);
|
||||
}
|
||||
*fp = 0;
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Umlaute hier drin, weil die in den Report kommen */
|
||||
static const char *skillnames[MAXSKILLS] =
|
||||
{
|
||||
"sk_alchemy",
|
||||
|
|
|
@ -472,7 +472,7 @@ report_effect(region * r, unit * mage, message * seen, message * unseen)
|
|||
* Zauberwirkungen)
|
||||
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': [hier die Fehlermeldung].",
|
||||
unitname(mage), regionid(mage->region), sa->strings[0]);
|
||||
unitname(mage), regionname(mage->region, mage->faction), sa->strings[0]);
|
||||
add_message(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
|
||||
* Allgemein sichtbare Auswirkungen in der Region sollten als
|
||||
|
@ -706,7 +706,7 @@ sp_destroy_magic(castorder *co)
|
|||
{
|
||||
region *tr = pa->param[0]->data.r;
|
||||
ap = &tr->attribs;
|
||||
strcpy(ts, regionid(tr));
|
||||
strcpy(ts, regionname(tr, mage->faction));
|
||||
break;
|
||||
}
|
||||
case SPP_TEMP:
|
||||
|
@ -1746,7 +1746,7 @@ sp_great_drought(castorder *co)
|
|||
fset(u->faction, FL_DH);
|
||||
sprintf(buf, "%s ruft das Feuer der Sonne auf %s hinab.",
|
||||
cansee(u->faction, r, mage, 0)? unitname(mage) : "Jemand",
|
||||
regionid(r));
|
||||
regionname(r, u->faction));
|
||||
if (rterrain(r) != T_OCEAN){
|
||||
if(rterrain(r) == T_SWAMP && terraform){
|
||||
scat(" Eis schmilzt und verwandelt sich in Morast. Reißende "
|
||||
|
@ -2444,7 +2444,7 @@ sp_earthquake(castorder *co)
|
|||
fset(u->faction, FL_DH);
|
||||
sprintf(buf, "%s läßt die Erde in %s erzittern.",
|
||||
cansee(u->faction, r, mage, 0) ? unitname(mage) : "Jemand",
|
||||
regionid(r));
|
||||
regionname(r, u->faction));
|
||||
|
||||
addmessage(r, u->faction, buf, MSG_EVENT, ML_INFO);
|
||||
}
|
||||
|
@ -2603,22 +2603,15 @@ sp_forest_fire(castorder *co)
|
|||
}
|
||||
|
||||
if (destroyed > 0 || vernichtet_schoesslinge > 0) {
|
||||
message * m = msg_message("forestfire_spread", "region next trees",
|
||||
r, nr, destroyed+vernichtet_schoesslinge);
|
||||
|
||||
add_message(&r->msgs, m);
|
||||
add_message(&mage->faction->msgs, m);
|
||||
msg_release(m);
|
||||
|
||||
rsettrees(nr, 2, rtrees(nr,2) - destroyed);
|
||||
rsettrees(nr, 1, rtrees(nr,1) - vernichtet_schoesslinge);
|
||||
sprintf(buf, "Der Waldbrand in %s griff auch auf %s "
|
||||
"über und %d %s.",
|
||||
regionid(r), regionid(nr), destroyed+vernichtet_schoesslinge,
|
||||
destroyed+vernichtet_schoesslinge == 1 ? "Baum verbrannte" : "Bäume verbrannten");
|
||||
for (u = nr->units; u; u = u->next) freset(u->faction, FL_DH);
|
||||
for(u = nr->units; u; u = u->next ) {
|
||||
if(!fval(u->faction, FL_DH) ) {
|
||||
fset(u->faction, FL_DH);
|
||||
addmessage(r, u->faction, buf, MSG_EVENT, ML_INFO);
|
||||
}
|
||||
}
|
||||
if(!fval(mage->faction, FL_DH)){
|
||||
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_INFO);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (rtrees(nr) >= 800) {
|
||||
|
@ -2628,21 +2621,12 @@ sp_forest_fire(castorder *co)
|
|||
}
|
||||
|
||||
if (destroyed > 0 ) {
|
||||
message * m = msg_message("forestfire_spread", "region next trees",
|
||||
r, nr, destroyed);
|
||||
add_message(&r->msgs, m);
|
||||
add_message(&mage->faction->msgs, m);
|
||||
msg_release(m);
|
||||
rsettrees(nr, rtrees(nr) - destroyed);
|
||||
sprintf(buf, "Der Waldbrand in %s griff auch auf %s "
|
||||
"über und %d %s.",
|
||||
regionid(r), regionid(nr), destroyed,
|
||||
destroyed == 1 ? "Baum verbrannte" : "Bäume verbrannten");
|
||||
for (u = nr->units; u; u = u->next) freset(u->faction, FL_DH);
|
||||
for(u = nr->units; u; u = u->next ) {
|
||||
if(!fval(u->faction, FL_DH) ) {
|
||||
fset(u->faction, FL_DH);
|
||||
addmessage(r, u->faction, buf, MSG_EVENT, ML_INFO);
|
||||
}
|
||||
}
|
||||
if(!fval(mage->faction, FL_DH)){
|
||||
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_INFO);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -2801,7 +2785,7 @@ sp_summondragon(castorder *co)
|
|||
} else {
|
||||
a->data.v = co->rt;
|
||||
}
|
||||
sprintf(buf, "Kommt aus: %s, Will nach: %s", regionid(rl2->data), regionid(co->rt));
|
||||
sprintf(buf, "Kommt aus: %s, Will nach: %s", regionname(rl2->data, u->faction), regionname(co->rt, u->faction));
|
||||
usetprivate(u, buf);
|
||||
}
|
||||
}
|
||||
|
@ -3487,9 +3471,8 @@ sp_plague(castorder *co)
|
|||
|
||||
plagues(r, true);
|
||||
|
||||
sprintf(buf, "%s ruft eine Pest in %s hervor.", unitname(mage),
|
||||
regionid(r));
|
||||
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_INFO);
|
||||
ADDMSG(&mage->faction->msgs, msg_message("plague_spell",
|
||||
"region mage", r, mage));
|
||||
return cast_level;
|
||||
}
|
||||
|
||||
|
@ -3788,7 +3771,7 @@ sp_summonundead(castorder *co)
|
|||
|
||||
if (!r->land || deathcount(r) == 0) {
|
||||
sprintf(buf, "%s in %s: In %s sind keine Gräber.", unitname(mage),
|
||||
regionid(mage->region), regionid(r));
|
||||
regionname(mage->region, mage->faction), regionname(r, mage->faction));
|
||||
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -3872,11 +3855,11 @@ sp_auraleak(castorder *co)
|
|||
if (cansee(u->faction, r, mage, 0)) {
|
||||
sprintf(buf, "%s rief in %s einen Riss in dem Gefüge der Magie "
|
||||
"hervor, der alle magische Kraft aus der Region riss.",
|
||||
unitname(mage), regionid(r));
|
||||
unitname(mage), regionname(r, u->faction));
|
||||
} else {
|
||||
sprintf(buf, "In %s entstand ein Riss in dem Gefüge der Magie, "
|
||||
"der alle magische Kraft aus der Region riss.",
|
||||
regionid(r));
|
||||
regionname(r, u->faction));
|
||||
}
|
||||
addmessage(r, u->faction, buf, MSG_EVENT, ML_WARN);
|
||||
}
|
||||
|
@ -4235,18 +4218,18 @@ sp_rallypeasantmob(castorder *co)
|
|||
fset(u->faction, FL_DH);
|
||||
sprintf(buf, "%s besänftigt den Bauernaufstand in %s.",
|
||||
cansee(u->faction, r, mage, 0) ? unitname(mage) : "Jemand",
|
||||
regionid(r));
|
||||
regionname(r, u->faction));
|
||||
addmessage(r, u->faction, buf, MSG_MAGIC, ML_INFO);
|
||||
}
|
||||
}
|
||||
if (!fval(mage->faction, FL_DH)){
|
||||
sprintf(buf, "%s besänftigt den Bauernaufstand in %s.",
|
||||
unitname(mage), regionid(r));
|
||||
unitname(mage), regionname(r, u->faction));
|
||||
addmessage(r, u->faction, buf, MSG_MAGIC, ML_INFO);
|
||||
}
|
||||
} else {
|
||||
sprintf(buf, "Der Bauernaufstand in %s hatte sich bereits verlaufen.",
|
||||
regionid(r));
|
||||
regionname(r, u->faction));
|
||||
addmessage(r, u->faction, buf, MSG_MAGIC, ML_INFO);
|
||||
}
|
||||
return erfolg;
|
||||
|
@ -4383,7 +4366,7 @@ sp_migranten(castorder *co)
|
|||
|| target->number > max_spellpoints(r, mage))
|
||||
{
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': So viele Personen übersteigen "
|
||||
"meine Kräfte.", unitname(mage), regionid(mage->region),
|
||||
"meine Kräfte.", unitname(mage), regionname(mage->region, mage->faction),
|
||||
spell_name(sp, mage->faction->locale));
|
||||
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_WARN);
|
||||
}
|
||||
|
@ -4501,7 +4484,7 @@ sp_generous(castorder *co)
|
|||
if(is_cursed(r->attribs, C_DEPRESSION, 0)){
|
||||
sprintf(buf, "%s in %s: Die Stimmung in %s ist so schlecht, das "
|
||||
"niemand auf den Zauber reagiert.", unitname(mage),
|
||||
regionid(mage->region), regionid(r));
|
||||
regionname(mage->region, mage->faction), regionname(r, mage->faction));
|
||||
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -4677,13 +4660,13 @@ sp_pump(castorder *co)
|
|||
|
||||
if (see == false){
|
||||
sprintf(buf, "%s horcht %s über %s aus, aber %s wusste nichts zu "
|
||||
"berichten.", unitname(mage), unitname(target), regionid(rt),
|
||||
"berichten.", unitname(mage), unitname(target), regionname(rt, mage->faction),
|
||||
unitname(target));
|
||||
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO);
|
||||
return cast_level/2;
|
||||
} else {
|
||||
sprintf(buf, "%s horcht %s über %s aus.", unitname(mage),
|
||||
unitname(target), regionid(rt));
|
||||
unitname(target), regionname(rt, mage->faction));
|
||||
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO);
|
||||
}
|
||||
|
||||
|
@ -5045,7 +5028,7 @@ sp_dragonsong(castorder *co)
|
|||
} else {
|
||||
a->data.v = r;
|
||||
}
|
||||
sprintf(buf, "Kommt aus: %s, Will nach: %s", regionid(rl2->data), regionid(r));
|
||||
sprintf(buf, "Kommt aus: %s, Will nach: %s", regionname(rl2->data, u->faction), regionname(r, u->faction));
|
||||
usetprivate(u, buf);
|
||||
}
|
||||
}
|
||||
|
@ -5509,7 +5492,7 @@ sp_dreamreading(castorder *co)
|
|||
set_level(u2, SK_OBSERVATION, eff_skill(u, SK_OBSERVATION, u2->region));
|
||||
|
||||
sprintf(buf, "%s verliert sich in die Träume von %s und erhält einen "
|
||||
"Eindruck von %s.", unitname(mage), unitname(u), regionid(u->region));
|
||||
"Eindruck von %s.", unitname(mage), unitname(u), regionname(u->region, mage->faction));
|
||||
addmessage(r, mage->faction, buf, MSG_EVENT, ML_INFO);
|
||||
return cast_level;
|
||||
}
|
||||
|
@ -5582,7 +5565,7 @@ sp_disturbingdreams(castorder *co)
|
|||
curse_setflag(c, CURSE_ISNEW);
|
||||
|
||||
sprintf(buf, "%s sorgt für schlechten Schlaf in %s.",
|
||||
unitname(mage), regionid(r));
|
||||
unitname(mage), regionname(r, mage->faction));
|
||||
addmessage(0, mage->faction, buf, MSG_EVENT, ML_INFO);
|
||||
return cast_level;
|
||||
}
|
||||
|
@ -5825,7 +5808,7 @@ sp_enterastral(castorder *co)
|
|||
default:
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': Dieser Zauber funktioniert "
|
||||
"nur in der materiellen Welt.", unitname(mage),
|
||||
regionid(mage->region), spell_name(sp, mage->faction->locale));
|
||||
regionname(mage->region, mage->faction), spell_name(sp, mage->faction->locale));
|
||||
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -5833,7 +5816,7 @@ sp_enterastral(castorder *co)
|
|||
if(!rt) {
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': Es kann hier kein Kontakt zur "
|
||||
"Astralwelt hergestellt werden.", unitname(mage),
|
||||
regionid(mage->region), spell_name(sp, mage->faction->locale));
|
||||
regionname(mage->region, mage->faction), spell_name(sp, mage->faction->locale));
|
||||
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -5842,7 +5825,7 @@ sp_enterastral(castorder *co)
|
|||
is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) {
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': Es kann kein Kontakt zu "
|
||||
"dieser astralen Region hergestellt werden.", unitname(mage),
|
||||
regionid(mage->region), spell_name(sp, mage->faction->locale));
|
||||
regionname(mage->region, mage->faction), spell_name(sp, mage->faction->locale));
|
||||
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -5949,7 +5932,7 @@ sp_pullastral(castorder *co)
|
|||
if(!rl2) {
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': Es kann kein Kontakt zu "
|
||||
"dieser Region hergestellt werden.", unitname(mage),
|
||||
regionid(mage->region), spell_name(sp, mage->faction->locale));
|
||||
regionname(mage->region, mage->faction), spell_name(sp, mage->faction->locale));
|
||||
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
free_regionlist(rl);
|
||||
return 0;
|
||||
|
@ -5959,7 +5942,7 @@ sp_pullastral(castorder *co)
|
|||
default:
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': Dieser Zauber funktioniert "
|
||||
"nur in der astralen Welt.", unitname(mage),
|
||||
regionid(mage->region), spell_name(sp, mage->faction->locale));
|
||||
regionname(mage->region, mage->faction), spell_name(sp, mage->faction->locale));
|
||||
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -5968,7 +5951,7 @@ sp_pullastral(castorder *co)
|
|||
is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) {
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': Es kann kein Kontakt zu "
|
||||
"dieser Region hergestellt werden.", unitname(mage),
|
||||
regionid(mage->region), spell_name(sp, mage->faction->locale));
|
||||
regionname(mage->region, mage->faction), spell_name(sp, mage->faction->locale));
|
||||
addmessage(r, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -6475,7 +6458,7 @@ sp_disruptastral(castorder *co)
|
|||
if(!is_magic_resistant(mage, u, 0) && can_survive(u, tr)) {
|
||||
move_unit(u, tr, NULL);
|
||||
sprintf(buf, "%s wird aus der astralen Ebene nach %s geschleudert.",
|
||||
unitname(u), regionid(tr));
|
||||
unitname(u), regionname(tr, u->faction));
|
||||
addmessage(0, u->faction, buf, MSG_MAGIC, ML_INFO);
|
||||
}
|
||||
}
|
||||
|
@ -6610,7 +6593,7 @@ sp_permtransfer(castorder *co)
|
|||
|
||||
if(!is_mage(tu)) {
|
||||
/* sprintf(buf, "%s in %s: 'ZAUBER %s': Einheit ist kein Magier."
|
||||
, unitname(mage), regionid(mage->region),sa->strings[0]); */
|
||||
, unitname(mage), regionname(mage->region, mage->faction),sa->strings[0]); */
|
||||
cmistake(mage, co->order, 214, MSG_MAGIC);
|
||||
return 0;
|
||||
}
|
||||
|
@ -6656,7 +6639,7 @@ sp_movecastle(castorder *co)
|
|||
|
||||
if(dir == NODIRECTION) {
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': Ungültige Richtung %s.",
|
||||
unitname(mage), regionid(mage->region),
|
||||
unitname(mage), regionname(mage->region, mage->faction),
|
||||
spell_name(sp, mage->faction->locale),
|
||||
pa->param[1]->data.s);
|
||||
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
|
@ -6666,7 +6649,7 @@ sp_movecastle(castorder *co)
|
|||
if(b->size > (cast_level-12) * 250) {
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': Der Elementar ist "
|
||||
"zu klein, um das Gebäude zu tragen.", unitname(mage),
|
||||
regionid(mage->region), spell_name(sp, mage->faction->locale));
|
||||
regionname(mage->region, mage->faction), spell_name(sp, mage->faction->locale));
|
||||
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
return cast_level;
|
||||
}
|
||||
|
@ -6676,7 +6659,7 @@ sp_movecastle(castorder *co)
|
|||
if(!(terrain[target_region->terrain].flags & LAND_REGION)) {
|
||||
sprintf(buf, "%s in %s: 'ZAUBER %s': Der Erdelementar "
|
||||
"weigert sich, nach %s zu gehen.",
|
||||
unitname(mage), regionid(mage->region),
|
||||
unitname(mage), regionname(mage->region, mage->faction),
|
||||
spell_name(sp, mage->faction->locale),
|
||||
locale_string(mage->faction->locale, directions[dir]));
|
||||
addmessage(0, mage->faction, buf, MSG_MAGIC, ML_MISTAKE);
|
||||
|
@ -7079,7 +7062,7 @@ sp_q_antimagie(castorder *co)
|
|||
switch(obj){
|
||||
case SPP_REGION:
|
||||
ap = &r->attribs;
|
||||
set_string(&ts, regionid(r));
|
||||
set_string(&ts, regionname(r, mage->faction));
|
||||
break;
|
||||
|
||||
case SPP_TEMP:
|
||||
|
|
|
@ -116,7 +116,7 @@ static item_type it_gryphonwing = {
|
|||
|
||||
static int
|
||||
enter_fail(unit * u) {
|
||||
sprintf(buf, "In %s erklingt die Stimme des Torwächters: 'Nur wer ohne materielle Güter und noch lernbegierig ist, der darf die Ebene der Herausforderung betreten. Und vergiß nicht mein Trinkgeld.'. %s erhielt keinen Einlaß.", regionid(u->region), unitname(u));
|
||||
sprintf(buf, "In %s erklingt die Stimme des Torwächters: 'Nur wer ohne materielle Güter und noch lernbegierig ist, der darf die Ebene der Herausforderung betreten. Und vergiß nicht mein Trinkgeld.'. %s erhielt keinen Einlaß.", regionname(u->region, u->faction), unitname(u));
|
||||
addmessage(NULL, u->faction, buf, MSG_MESSAGE, ML_IMPORTANT);
|
||||
return 1;
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ enter_arena(unit * u, const item_type * itype, int amount, order * ord)
|
|||
if (u2) change_money(u2, get_money(u) - fee);
|
||||
else if (enter_fail(u)) return -1;
|
||||
}
|
||||
sprintf(buf, "In %s öffnet sich ein Portal. Eine Stimme ertönt, und spricht: 'Willkommen in der Ebene der Herausforderung'. %s durchschreitet das Tor zu einer anderen Welt.", regionid(u->region), unitname(u));
|
||||
sprintf(buf, "In %s öffnet sich ein Portal. Eine Stimme ertönt, und spricht: 'Willkommen in der Ebene der Herausforderung'. %s durchschreitet das Tor zu einer anderen Welt.", regionname(u->region, u->faction), unitname(u));
|
||||
addmessage(NULL, u->faction, buf, MSG_MESSAGE, ML_IMPORTANT);
|
||||
new_use_pooled(u, &rt_gryphonwing, GET_SLACK|GET_RESERVE, 1);
|
||||
use_pooled(u, r, R_SILVER, fee);
|
||||
|
@ -357,6 +357,7 @@ guardian_faction(plane * pl, int id)
|
|||
|
||||
f->no = id;
|
||||
addlist(&factions, f);
|
||||
fhash(f);
|
||||
}
|
||||
if (f->race != new_race[RC_ILLUSION]) {
|
||||
assert(!"guardian id vergeben");
|
||||
|
|
|
@ -648,6 +648,7 @@ gm_addquest(const char * email, const char * name, int radius, unsigned int flag
|
|||
|
||||
f->no = i;
|
||||
addlist(&factions, f);
|
||||
fhash(f);
|
||||
}
|
||||
|
||||
/* GM playfield */
|
||||
|
@ -751,6 +752,7 @@ gm_addfaction(const char * email, plane * p, region * r)
|
|||
|
||||
f->no = i;
|
||||
addlist(&factions, f);
|
||||
fhash(f);
|
||||
}
|
||||
/* generic permissions */
|
||||
a = a_add(&f->attribs, a_new(&at_permissions));
|
||||
|
|
|
@ -324,7 +324,7 @@ use_museumexitticket(unit *u, const struct item_type *itype, int amount, order *
|
|||
/* Exitticket abziehen */
|
||||
i_change(&u->items, itype, -1);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
resource_type rt_museumexitticket = {
|
||||
|
@ -379,7 +379,7 @@ use_museumticket(unit *u, const struct item_type *itype, int amount, order * ord
|
|||
/* Benutzer ein Exitticket geben */
|
||||
i_change(&u->items, &it_museumexitticket, 1);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
resource_type rt_museumticket = {
|
||||
|
|
|
@ -161,13 +161,13 @@ attrib_type at_eventhandler = {
|
|||
};
|
||||
|
||||
struct trigger **
|
||||
get_triggers(struct attrib * ap, const char * event)
|
||||
get_triggers(struct attrib * ap, const char * eventname)
|
||||
{
|
||||
handler_info * td = NULL;
|
||||
attrib * a = a_find(ap, &at_eventhandler);
|
||||
while (a!=NULL) {
|
||||
td = (handler_info *)a->data.v;
|
||||
if (!strcmp(td->event, event)) {
|
||||
if (!strcmp(td->event, eventname)) {
|
||||
break;
|
||||
}
|
||||
a = a->nexttype;
|
||||
|
@ -177,7 +177,7 @@ get_triggers(struct attrib * ap, const char * event)
|
|||
}
|
||||
|
||||
void
|
||||
add_trigger(struct attrib ** ap, const char * event, struct trigger * t)
|
||||
add_trigger(struct attrib ** ap, const char * eventname, struct trigger * t)
|
||||
{
|
||||
trigger ** tp;
|
||||
handler_info * td = NULL;
|
||||
|
@ -185,7 +185,7 @@ add_trigger(struct attrib ** ap, const char * event, struct trigger * t)
|
|||
assert(t->next==NULL);
|
||||
while (a!=NULL) {
|
||||
td = (handler_info *)a->data.v;
|
||||
if (!strcmp(td->event, event)) {
|
||||
if (!strcmp(td->event, eventname)) {
|
||||
break;
|
||||
}
|
||||
a = a->nexttype;
|
||||
|
@ -193,7 +193,7 @@ add_trigger(struct attrib ** ap, const char * event, struct trigger * t)
|
|||
if (!a) {
|
||||
a = a_add(ap, a_new(&at_eventhandler));
|
||||
td = (handler_info *)a->data.v;
|
||||
td->event = strdup(event);
|
||||
td->event = strdup(eventname);
|
||||
}
|
||||
tp = &td->triggers;
|
||||
while (*tp) tp=&(*tp)->next;
|
||||
|
@ -201,7 +201,7 @@ add_trigger(struct attrib ** ap, const char * event, struct trigger * t)
|
|||
}
|
||||
|
||||
void
|
||||
handle_event_va(attrib ** attribs, const char * event, const char * format, ...)
|
||||
handle_event_va(attrib ** attribs, const char * eventname, const char * format, ...)
|
||||
{
|
||||
event_arg args[9];
|
||||
int argc = 0;
|
||||
|
@ -218,12 +218,12 @@ handle_event_va(attrib ** attribs, const char * event, const char * format, ...)
|
|||
}
|
||||
args[argc].type=NULL;
|
||||
va_end(marker);
|
||||
handle_event(attribs, event, args);
|
||||
handle_event(attribs, eventname, args);
|
||||
free (toks);
|
||||
}
|
||||
|
||||
void
|
||||
handle_event(attrib ** attribs, const char * event, void * data)
|
||||
handle_event(attrib ** attribs, const char * eventname, void * data)
|
||||
{
|
||||
while (*attribs) {
|
||||
if ((*attribs)->type==&at_eventhandler) break;
|
||||
|
@ -231,7 +231,7 @@ handle_event(attrib ** attribs, const char * event, void * data)
|
|||
}
|
||||
while (*attribs) {
|
||||
handler_info * tl = (handler_info*)(*attribs)->data.v;
|
||||
if (!strcmp(tl->event, event)) break;
|
||||
if (!strcmp(tl->event, eventname)) break;
|
||||
attribs = &(*attribs)->nexttype;
|
||||
}
|
||||
if (*attribs) {
|
||||
|
@ -265,9 +265,9 @@ tt_find(const char * name)
|
|||
}
|
||||
|
||||
void
|
||||
remove_triggers(struct attrib ** ap, const char * event, const trigger_type * tt)
|
||||
remove_triggers(struct attrib ** ap, const char * eventname, const trigger_type * tt)
|
||||
{
|
||||
trigger ** tp = get_triggers(*ap, event);
|
||||
trigger ** tp = get_triggers(*ap, eventname);
|
||||
if(tp == NULL) return;
|
||||
while (*tp) {
|
||||
/* first, remove all gate-triggers */
|
||||
|
|
|
@ -55,12 +55,12 @@ extern void t_add(trigger ** tlist, trigger * t);
|
|||
/** add and handle triggers **/
|
||||
|
||||
/* add a trigger to a list of attributes */
|
||||
extern void add_trigger(struct attrib ** ap, const char * event, struct trigger * t);
|
||||
extern void remove_triggers(struct attrib ** ap, const char * event, const trigger_type * tt);
|
||||
extern struct trigger ** get_triggers(struct attrib * ap, const char * event);
|
||||
extern void add_trigger(struct attrib ** ap, const char * eventname, struct trigger * t);
|
||||
extern void remove_triggers(struct attrib ** ap, const char * eventname, const trigger_type * tt);
|
||||
extern struct trigger ** get_triggers(struct attrib * ap, const char * eventname);
|
||||
/* calls handle() for each of these. e.g. used in timeout */
|
||||
extern void handle_event(struct attrib ** attribs, const char * event, void * data);
|
||||
extern void handle_event_va(struct attrib ** attribs, const char * event, const char * format, ...);
|
||||
extern void handle_event(struct attrib ** attribs, const char * eventname, void * data);
|
||||
extern void handle_event_va(struct attrib ** attribs, const char * eventname, const char * format, ...);
|
||||
|
||||
/* functions for making complex triggers: */
|
||||
extern void free_triggers(trigger * triggers); /* release all these triggers */
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/MACHINE:I386"
|
||||
AdditionalOptions="/MACHINE:I386 /FIXED:NO"
|
||||
AdditionalDependencies="luabind.lib lua50.lib lualib50.lib libxml2.lib iconv.lib"
|
||||
OutputFile=".\Release/eressea-lua.exe"
|
||||
LinkIncremental="1"
|
||||
|
@ -76,8 +76,8 @@
|
|||
</Configuration>
|
||||
<Configuration
|
||||
Name="Profile|Win32"
|
||||
OutputDirectory=".\Profile"
|
||||
IntermediateDirectory=".\Profile"
|
||||
OutputDirectory=".\Profile-lua"
|
||||
IntermediateDirectory=".\Profile-lua"
|
||||
ConfigurationType="1"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="FALSE"
|
||||
|
|
|
@ -469,7 +469,7 @@ fix_firewalls(void)
|
|||
if (a==NULL || a->data.i <= 0) {
|
||||
erase_border(b);
|
||||
log_warning(("firewall between regions %s and %s was bugged. removed.\n",
|
||||
regionid(r), regionid(r2)));
|
||||
regionname(r, NULL), regionname(r2, NULL)));
|
||||
b = get_borders(r, r2);
|
||||
} else {
|
||||
b = b->next;
|
||||
|
|
|
@ -206,7 +206,9 @@ chg_item(selection * s, void * data) {
|
|||
boolean
|
||||
modify_items(unit * u)
|
||||
{
|
||||
selection *ilist = NULL, **ilast = &ilist;
|
||||
selection *ilist = NULL;
|
||||
#if 0
|
||||
selection **ilast = &ilist;
|
||||
const item_type * itype = itemtypes;
|
||||
|
||||
while (itype!=NULL) {
|
||||
|
@ -222,6 +224,7 @@ modify_items(unit * u)
|
|||
itype=itype->next;
|
||||
while (ilist->prev!=NULL) ilist=ilist->prev;
|
||||
}
|
||||
#endif
|
||||
i_modif = false;
|
||||
do_selection(ilist, "Gegenstände", chg_item, (void*)u);
|
||||
while (ilist) {
|
||||
|
|
|
@ -1544,7 +1544,6 @@ makemonsters(void)
|
|||
f->name=strdup("Monster");
|
||||
f->passw=strdup("abc123");
|
||||
f->override = strdup(itoa36(rand()));
|
||||
fhash(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<building name="genericbuilding" maxsize="1" nobuild="yes" auraregen="1.00"/>
|
||||
<building name="artacademy" maxsize="100" nobuild="yes" nodestroy="yes" unique="yes" auraregen="1.00"/>
|
||||
<building name="artsculpture" maxsize="100" nobuild="yes" nodestroy="yes" unique="yes" auraregen="1.00"/>
|
||||
<building name="blessedstonecircle" maxsize="100" nobuild="yes" magic="yes" magres="60" magresbonus="30" auraregen="1.50">
|
||||
<building name="blessedstonecircle" maxcapacity="3" maxsize="100" nobuild="yes" magic="yes" magres="60" magresbonus="30" auraregen="1.50">
|
||||
<construction skill="sk_building" minskill="2" reqsize="100" maxsize="100">
|
||||
<requirement type="log" recycle="0.5" quantity="500"/>
|
||||
<requirement type="stone" recycle="0.5" quantity="500"/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0"?>
|
||||
<equipment>
|
||||
<item name="conquesttoken" amount="1"/>
|
||||
<item name="wood" amount="30"/>
|
||||
<item name="log" amount="30"/>
|
||||
<item name="stone" amount="30"/>
|
||||
<item name="money" amount="2000"/>
|
||||
</equipment>
|
||||
|
|
|
@ -6069,5 +6069,53 @@
|
|||
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - The unit has $int($have) of $int($cost) silver required."</text>
|
||||
</message>
|
||||
|
||||
<message name="tidalwave" section="events">
|
||||
<type>
|
||||
<arg name="region" type="region"/>
|
||||
</type>
|
||||
<text locale="de">"Eine gewaltige Flutwelle verschlingt $region($region) und alle Bewohner."</text>
|
||||
<text locale="en">"A tidal wave wipes out $region($region) and all who lived there."</text>
|
||||
</message>
|
||||
|
||||
<message name="astralshield_activate" section="events">
|
||||
<type>
|
||||
<arg name="region" type="region"/>
|
||||
<arg name="unit" type="unit"/>
|
||||
</type>
|
||||
<text locale="de">"$unit($unit) reaktiviert den astralen Schutzschild in $region($region)."</text>
|
||||
<text locale="en">"$unit($unit) reactivates the astral protection shield in $region($region)."</text>
|
||||
</message>
|
||||
|
||||
<message name="dissolve_units" section="events">
|
||||
<type>
|
||||
<arg name="region" type="region"/>
|
||||
<arg name="unit" type="unit"/>
|
||||
<arg name="number" type="int"/>
|
||||
<arg name="race" type="race"/>
|
||||
<arg name="action" type="string"/>
|
||||
</type>
|
||||
<text locale="de">"$unit($unit) in $region($region): $int($number) $race($race,$number) $action"</text>
|
||||
<text locale="en">"$unit($unit) in $region($region): $int($number) $race($race,$number) $action"</text>
|
||||
</message>
|
||||
|
||||
<message name="forestfire_spread" section="events">
|
||||
<type>
|
||||
<arg name="region" type="region"/>
|
||||
<arg name="next" type="region"/>
|
||||
<arg name="trees" type="int"/>
|
||||
</type>
|
||||
<text locale="de">"Der Waldbrand in $region($region) griff auch auf $region($next) über, und $int($trees) verbrannten."</text>
|
||||
<text locale="en">"The fire in $region($region) spread to $region($next) and $int($trees) were burnt."</text>
|
||||
</message>
|
||||
|
||||
<message name="plague_spell" section="events">
|
||||
<type>
|
||||
<arg name="region" type="region"/>
|
||||
<arg name="mage" type="unit"/>
|
||||
</type>
|
||||
<text locale="de">"$unit($unit) ruft in $region($region) eine Pest hervor."</text>
|
||||
<text locale="en">"$unit($unit) sends the plague on $region($region)."</text>
|
||||
</message>
|
||||
|
||||
</messages>
|
||||
|
||||
|
|
Loading…
Reference in New Issue