* möglichen Exploit beseitigt:

GIB xyz EINHEIT
  GIB 0 ALLES SILBER
  --> ALLE Befehle der übergebenen Einheit werden gelöscht.

* neue Funktion (convenience): ucansee(f, u1, u2)
  liefert u1, wenn cansee(f,u1), sonst u2

* neue mistakes eingefügt uns übersetzt

* message bugfix:
  u->htisorder kann gelöscht werden (z.b. NACH). Daher muss ein pointer auf
  einen befehl in einer message immer auf den u->order Eintrag zeigen, damit er
  zeit der auswertung noch existiert.
  findorder(u, u->thisorder) tut das. Ist an mehreren Stellen nicht benutzt
  worden. assert eingebaut, das das prüft.

* RESERVE_DONATIONS
  Gegenstände, die von einer anderen Partei übergeben wurden, werden nicht
  reserviert.

* TWOPASS_GIVE:
  GIB Befehle werden zuerst an fremde Einheiten, danach in einem zweiten
  Durchlauf an eigene Einheiten, ausgeführt.

* msg_message
  An einigen messages ausprobiert, ob man die gleiche Message mehreren
  Parteien einhängen kann - klappt, spart Speicher.
  Allerdings fehlt dazu ein ordentliches memory-management (refcounter)
This commit is contained in:
Enno Rehling 2001-05-10 05:50:52 +00:00
parent 52aa6bccc2
commit cfdbc32470
21 changed files with 486 additions and 227 deletions

View File

@ -184,5 +184,9 @@ SOURCE=.\reduceproduction.c
SOURCE=.\targetregion.c
# End Source File
# Begin Source File
SOURCE=.\ugroup.c
# End Source File
# End Target
# End Project

View File

@ -8,7 +8,6 @@
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
$Id: ugroup.c,v 1.2 2001/04/29 19:27:41 enno Exp $
*/
#include <config.h>

View File

@ -19,32 +19,36 @@
* permission from the authors.
*/
#define RESERVE_DONATIONS 0 /* shall we reserve objects given to us by other factions? */
#define RESERVE_GIVE 1 /* reserve anything that's given from one unit to another? */
#define TWOPASS_GIVE 1 /* give items in two passes: first to others, than to self */
#include <config.h>
#include "eressea.h"
#include "economy.h"
#include "ship.h"
#include "unit.h"
#include "building.h"
#include "faction.h"
#include "plane.h"
#include "alchemy.h"
#include "item.h"
#include "magic.h"
#include "build.h"
#include "goodies.h"
#include "study.h"
#include "movement.h"
#include "race.h"
#include "spy.h"
#include "build.h"
#include "pool.h"
#include "region.h"
#include "unit.h"
#include "skill.h"
#include "message.h"
#include "reports.h"
#include "karma.h"
#include <ship.h>
#include <unit.h>
#include <building.h>
#include <faction.h>
#include <plane.h>
#include <alchemy.h>
#include <item.h>
#include <magic.h>
#include <build.h>
#include <goodies.h>
#include <study.h>
#include <movement.h>
#include <race.h>
#include <spy.h>
#include <build.h>
#include <pool.h>
#include <region.h>
#include <unit.h>
#include <skill.h>
#include <message.h>
#include <reports.h>
#include <karma.h>
/* gamecode includes */
#include "laws.h"
@ -75,7 +79,6 @@ typedef struct spende {
} spende;
static spende *spenden;
/* ------------------------------------------------------------- */
#define FAST_WORK
static request workers[1024];
static request *nextworker;
@ -315,8 +318,8 @@ expandrecruit(region * r, request * recruitorders)
u->n * level_days(i));
}
if (u->n < u->wants) {
add_message(&u->faction->msgs, new_message(u->faction,
"recruit%u:unit%r:region%i:amount%i:want", u, r, u->n, u->wants));
add_message(&u->faction->msgs,
msg_message("recruit", "unit region amount want", u, r, u->n, u->wants));
}
}
}
@ -371,7 +374,7 @@ recruit(region * r, unit * u, strlist * S,
pl = getplane(r);
if (pl && fval(pl, PFL_NORECRUITS)) {
add_message(&u->faction->msgs,
new_message(u->faction, "error_pflnorecruit%s:command%u:unit%r:region", S->s, u, r));
msg_error(u, S->s, "error_pflnorecruit", ""));
return;
}
@ -436,18 +439,17 @@ void
add_give(unit * u, unit * u2, int n, const resource_type * rtype, const char * cmd, int error)
{
if (error)
cmistake(u, cmd, error, MSG_EVENT);
cmistake(u, cmd, error, MSG_COMMERCE);
else if (!u2 || u2->faction!=u->faction) {
assert(rtype);
add_message(&u->faction->msgs,
new_message(u->faction, "give%u:unit%u:target%X:resource%i:amount",
u,
u2?(cansee(u->faction, u->region, u2, 0)?u2:NULL):&u_peasants,
rtype, n));
if (u2) add_message(&u2->faction->msgs,
new_message(u2->faction, "give%u:unit%u:target%X:resource%i:amount",
u?(cansee(u2->faction, u2->region, u, 0)?u:NULL):&u_peasants,
u2, rtype, n));
msg_message("give", "unit target resource amount",
u, u2?ucansee(u->faction, u2, &u_unknown):&u_peasants, rtype, n));
if (u2) {
add_message(&u2->faction->msgs,
msg_message("give", "unit target resource amount",
ucansee(u2->faction, u, &u_unknown), u2, rtype, n));
}
}
}
@ -479,7 +481,13 @@ give_item(int want, const item_type * itype, unit * src, unit * dest, const char
if (use<n) use += new_use_pooled(src, item2resource(itype), GET_RESERVE|GET_POOLED_SLACK, n-use);
if (dest) {
i_change(&dest->items, itype, n);
#if RESERVE_DONATIONS
new_change_resvalue(dest, item2resource(itype), n);
#elif RESERVE_GIVE
if (src->faction==dest->faction) {
new_change_resvalue(dest, item2resource(itype), n);
}
#endif
handle_event(&src->attribs, "give", dest);
handle_event(&dest->attribs, "receive", src);
#if defined(MUSEUM_PLANE) && defined(TODO)
@ -493,13 +501,6 @@ give_item(int want, const item_type * itype, unit * src, unit * dest, const char
add_give(src, dest, n, item2resource(itype), cmd, error);
}
void
giveitem(int n, item_t it, unit * u, region * r, unit * u2, strlist * S)
{
unused(r);
give_item(n, olditemtype[it], u, u2, S->s);
}
void
givemen(int n, unit * u, unit * u2, strlist * S)
{
@ -720,10 +721,7 @@ giveunit(region * r, unit * u, unit * u2, strlist * S)
cmistake(u, S->s, 156, MSG_COMMERCE);
return;
}
add_message(&u2->faction->msgs,
new_message(u2->faction, "give%u:unit%u:target%X:resource%i:amount",
u?&u_peasants:(cansee(u2->faction, u->region, u, 0)?u:NULL),
u2, r_unit, 1));
add_give(u, u2, 1, r_unit, S->s, 0);
u_setfaction(u, u2->faction);
u2->faction->newbies += n;
@ -732,31 +730,31 @@ giveunit(region * r, unit * u, unit * u2, strlist * S)
* Blödsinn, da Silberpool nicht auf geben wirkt. Aber Rekrutierungen,
* teure Talente lernen und Gegenstände erschaffen! Kritisch sind:
* BIETE, FORSCHEN, KAUFE, LERNE, REKRUTIERE, ZAUBERE,
* HELFE, PASSWORT, STIRB (Katja) */
* HELFE, PASSWORT, STIRB (Katja)
* Natürlich wirkt der Silberpool bei gib!
* Und damit nicht irgendein zukünftiger Befehl vergessen wird,
* löschen wir der Einfachheit halber alle! (Enno).
*/
for (S = u->orders; S; S = S->next) {
switch (igetkeyword(S->s, u->faction->locale)) {
case K_BIETE:
case K_RESEARCH:
case K_BUY:
case K_STUDY:
case K_RECRUIT:
case K_CAST:
case K_ALLY:
case K_PASSWORD:
case K_QUIT:
*S->s = 0;
}
/* freelist(u->orders);
* FEHLER! Das darf nicht, weil es auf orders noch pointer geben kann!
*/
while (u->orders) {
/* dieser code _kennt_ die implementaion von strlists... */
strlist * o = u->orders;
u->orders = o->next;
gc_add(o->s); /* delete it later */
free(o);
}
add_message(&u->faction->msgs,
new_message(u->faction, "give%u:unit%u:target%X:resource%i:amount",
u, u2?&u_peasants:u2,
r_unit, 1));
}
void
dogive(region * r, unit * u, strlist * S, boolean liefere)
static void
dogive(region * r, unit * u, strlist * S, boolean liefere, int mode)
/*
* mode=0: give to any units
* mode=1: give to other units and peasants only
* mode=2: give to own units only
*/
{
unit *u2;
char *s;
@ -768,6 +766,23 @@ dogive(region * r, unit * u, strlist * S, boolean liefere)
u2 = getunit(r, u->faction);
switch (mode) {
case 0:
/* any destination is okay */
break;
case 1:
/* not to myself */
if (u2 && u2->faction==u->faction) return;
break;
#if TWOPASS_GIVE
case 2:
/* not to peasants or others */
if (!u2 || u2->faction!=u->faction) return;
break;
#endif
default:
assert(!"invalid mode for dogive");
}
if (!u2 && !getunitpeasants) {
cmistake(u, S->s, notfound_error, MSG_COMMERCE);
return;
@ -821,16 +836,13 @@ dogive(region * r, unit * u, strlist * S, boolean liefere)
freset(u, FL_OWNER);
fset(u2, FL_OWNER);
add_message(&u2->faction->msgs, new_message(
u2->faction, "givecommand%u:unit%u:receipient",
u,
u2?(cansee(u->faction, u->region, u2, 0)?u2:NULL):&u_peasants));
if (u->faction != u2->faction)
add_message(&u->faction->msgs, new_message(
u->faction, "givecommand%u:unit%u:receipient",
u?(cansee(u2->faction, u2->region, u, 0)?u:NULL):&u_peasants,
u2));
add_message(&u->faction->msgs,
msg_message("givecommand", "unit receipient", u, u2));
if (u->faction != u2->faction) {
add_message(&u2->faction->msgs,
msg_message("givecommand", "unit receipient",
ucansee(u2->faction, u, &u_unknown), u2));
}
return;
}
if (u2 && u2->race == RC_SPELL) {
@ -840,21 +852,21 @@ dogive(region * r, unit * u, strlist * S, boolean liefere)
/* if ((race[u->race].ec_flags & NOGIVE) || fval(u,FL_LOCKED)) {*/
if (race[u->race].ec_flags & NOGIVE) {
sprintf(buf, "%s geben nichts weg", race[u->race].name[1]);
mistake(u, S->s, buf, MSG_COMMERCE);
add_message(&u->faction->msgs,
msg_error(u, S->s, "race_nogive", "race", u->race));
return;
}
if (u2 && !(race[u2->race].ec_flags & GETITEM)) {
sprintf(buf, "%s nehmen nichts an", race[u2->race].name[1]);
mistake(u, S->s, buf, MSG_COMMERCE);
add_message(&u->faction->msgs,
msg_error(u, S->s, "race_notake", "race", u->race));
return;
}
/* Übergabe aller Kräuter */
if (findparam(s, u->faction->locale) == P_HERBS) {
if (!(race[u->race].ec_flags & GIVEITEM)) {
sprintf(buf, "%s geben nichts weg", race[u->race].name[1]);
mistake(u, S->s, buf, MSG_COMMERCE);
add_message(&u->faction->msgs,
msg_error(u, S->s, "race_nogive", "race", u->race));
return;
}
if (!u2) {
@ -910,8 +922,8 @@ dogive(region * r, unit * u, strlist * S, boolean liefere)
if (*s == 0) {
const item_type * itype;
if (!(race[u->race].ec_flags & GIVEITEM)) {
sprintf(buf, "%s geben nichts weg.", race[u->race].name[1]);
mistake(u, S->s, buf, MSG_COMMERCE);
add_message(&u->faction->msgs,
msg_error(u, S->s, "race_nogive", "race", u->race));
return;
}
/* TODO: go through source unit's items only to speed this up */
@ -928,8 +940,8 @@ dogive(region * r, unit * u, strlist * S, boolean liefere)
i = findparam(s, u->faction->locale);
if (i == P_PERSON) {
if (!(race[u->race].ec_flags & GIVEPERSON)) {
sprintf(buf, "%s können nicht neu gruppiert werden.", unitname(u));
mistake(u, S->s, buf, MSG_COMMERCE);
add_message(&u->faction->msgs,
msg_error(u, S->s, "race_noregroup", "race", u->race));
return;
}
n = u->number;
@ -938,8 +950,8 @@ dogive(region * r, unit * u, strlist * S, boolean liefere)
}
if (!(race[u->race].ec_flags & GIVEITEM)) {
sprintf(buf, "%s geben nichts weg.", race[u->race].name[1]);
mistake(u, S->s, buf, MSG_COMMERCE);
add_message(&u->faction->msgs,
msg_error(u, S->s, "race_nogive", "race", u->race));
return;
}
itype = finditemtype(s, u->faction->locale);
@ -972,8 +984,8 @@ dogive(region * r, unit * u, strlist * S, boolean liefere)
i = findparam(s, u->faction->locale);
if (i == P_PERSON) {
if (!(race[u->race].ec_flags & GIVEPERSON)) {
sprintf(buf, "%s können nicht neu gruppiert werden.", unitname(u));
mistake(u, S->s, buf, MSG_COMMERCE);
add_message(&u->faction->msgs,
msg_error(u, S->s, "race_noregroup", "race", u->race));
return;
}
givemen(n, u, u2, S);
@ -981,8 +993,8 @@ dogive(region * r, unit * u, strlist * S, boolean liefere)
}
if (!(race[u->race].ec_flags & GIVEITEM)) {
sprintf(buf, "%s geben nichts weg.", race[u->race].name[1]);
mistake(u, S->s, buf, MSG_COMMERCE);
add_message(&u->faction->msgs,
msg_error(u, S->s, "race_nogive", "race", u->race));
return;
}
itype = finditemtype(s, u->faction->locale);
@ -1145,8 +1157,11 @@ gebaeude_stuerzt_ein(region * r, building * b)
int n, i;
direction_t d;
int opfer = 0;
sprintf(buf, "%s stürzte ein.", buildingname(b));
int road = 0;
struct message * msg;
/*
"$building($crashed) stürzte ein.$if($road," Beim Einsturz wurde die halbe Straße vernichtet.","")$if($victims,"$int($victims) $if($eq($victims,1),"ist","sind"),"") zu beklagen."
*/
/* Falls Karawanserei, Damm oder Tunnel einstürzen, wird die schon
* gebaute Straße zur Hälfte vernichtet */
@ -1156,7 +1171,7 @@ gebaeude_stuerzt_ein(region * r, building * b)
b->type == &bt_tunnel))
{
rsetroad(r, d, rroad(r, d) / 2);
sprintf(buf, " Beim Einsturz wurde die halbe Straße vernichtet.");
road = 1;
}
for (u = r->units; u; u = u->next) {
if (u->building == b) {
@ -1176,24 +1191,13 @@ gebaeude_stuerzt_ein(region * r, building * b)
}
}
if (opfer > 0) {
buf[0]=' ';
strcpy(buf+1, itoa10(opfer));
scat(" Opfer ");
if (opfer == 1) {
scat("ist");
} else {
scat("sind");
}
scat(" zu beklagen.");
} else buf[0] = 0;
addmessage(r, 0, buf, MSG_EVENT, ML_IMPORTANT);
msg = msg_message("buildingcrash", "region building opfer road", r, b, opfer, road);
add_message(&r->msgs, msg);
for (u=r->units; u; u=u->next) {
faction * f = u->faction;
if (fval(f, FL_MARK)) {
freset(u->faction, FL_MARK);
add_message(&f->msgs,
new_message(f, "buildingcrash%r:region%b:building%s:opfer", r, b, buf));
add_message(&f->msgs, msg);
}
}
destroy_building(b);
@ -1213,11 +1217,10 @@ maintain_buildings(boolean crash)
continue;
} else {
unit * u = buildingowner(r, b);
struct message * msg = msg_message("nomaintenance", "building", b);
if (u) {
add_message(&u->faction->msgs,
new_message(u->faction, "nomaintenance%b:building", b));
add_message(&r->msgs,
new_message(u->faction, "nomaintenance%b:building", b));
add_message(&u->faction->msgs, msg);
add_message(&r->msgs, msg);
}
}
}
@ -1249,11 +1252,11 @@ economics(void)
break;
case K_GIVE:
dogive(r, u, S, S->s[0]=='@'?true:false);
dogive(r, u, S, S->s[0]=='@'?true:false, TWOPASS_GIVE);
break;
case K_LIEFERE:
dogive(r, u, S, true);
dogive(r, u, S, true, TWOPASS_GIVE);
break;
case K_FORGET:
@ -1263,7 +1266,20 @@ economics(void)
}
}
}
#if TWOPASS_GIVE
for (u = r->units; u; u = u->next) {
for (S = u->orders; S; S = S->next) {
switch (igetkeyword(S->s, u->faction->locale)) {
case K_GIVE:
dogive(r, u, S, S->s[0]=='@'?true:false, 2);
break;
case K_LIEFERE:
dogive(r, u, S, true, 2);
break;
}
}
}
#endif
/* RECRUIT orders */
for (u = r->units; u; u = u->next) {
@ -1307,11 +1323,11 @@ manufacture(unit * u, const item_type * itype, int want)
switch (n) {
case ENEEDSKILL:
add_message(&u->faction->msgs,
msg_error(u, u->thisorder, "skill_needed", "skill", sk));
msg_error(u, findorder(u, u->thisorder), "skill_needed", "skill", sk));
return;
case ELOWSKILL:
add_message(&u->faction->msgs,
msg_error(u, u->thisorder, "manufacture_skills", "skill minskill product",
msg_error(u, findorder(u, u->thisorder), "manufacture_skills", "skill minskill product",
sk, minskill, itype->rtype, 1));
return;
case ENOMATERIALS:
@ -1330,7 +1346,7 @@ manufacture(unit * u, const item_type * itype, int want)
ch = ch+strlen(ch);
}
strcat(ch,".");
mistake(u, u->thisorder, buf, MSG_PRODUCE);
mistake(u, findorder(u, u->thisorder), buf, MSG_PRODUCE);
return;
}
}
@ -1409,8 +1425,8 @@ allocate_resource(unit * u, const resource_type * rtype, int want)
&& armedmen(u2)
#endif
) {
sprintf(buf, "%s bewacht die Region", unitname(u2));
mistake(u, u->thisorder, buf, MSG_PRODUCE);
add_message(&u->faction->msgs,
msg_error(u, findorder(u, u->thisorder), "region_guarded", "guard", u2));
return;
}
}
@ -1429,8 +1445,8 @@ allocate_resource(unit * u, const resource_type * rtype, int want)
&& !ucontact(u2, u)
&& !allied(u2, u->faction, HELP_GUARD))
{
sprintf(buf, "%s bewacht die Region", unitname(u2));
mistake(u, u->thisorder, buf, MSG_PRODUCE);
add_message(&u->faction->msgs,
msg_error(u, findorder(u, u->thisorder), "region_guarded", "guard", u2));
return;
}
}
@ -1441,13 +1457,13 @@ allocate_resource(unit * u, const resource_type * rtype, int want)
if (skill == 0) {
skill_t sk = itype->construction->skill;
add_message(&u->faction->msgs,
msg_error(u, u->thisorder, "skill_needed", "skill", sk));
msg_error(u, findorder(u, u->thisorder), "skill_needed", "skill", sk));
return;
}
if (skill < itype->construction->minskill) {
skill_t sk = itype->construction->skill;
add_message(&u->faction->msgs,
msg_error(u, u->thisorder, "manufacture_skills", "skill minskill product",
msg_error(u, findorder(u, u->thisorder), "manufacture_skills", "skill minskill product",
sk, itype->construction->minskill, itype->rtype));
return;
} else {
@ -1618,7 +1634,7 @@ create_potion(unit * u, const potion_type * ptype, int want)
ch = ch+strlen(ch);
}
strcat(ch,".");
mistake(u, u->thisorder, buf, MSG_PRODUCE);
mistake(u, findorder(u, u->thisorder), buf, MSG_PRODUCE);
return;
}
break;
@ -1640,7 +1656,7 @@ create_item(unit * u, const item_type * itype, int want)
const potion_type * ptype = resource2potion(itype->rtype);
if (ptype!=NULL) create_potion(u, ptype, want);
else if (itype->construction) manufacture(u, itype, want);
else cmistake(u, u->thisorder, 125, MSG_PRODUCE);
else cmistake(u, findorder(u, u->thisorder), 125, MSG_PRODUCE);
}
}
@ -1692,7 +1708,7 @@ make(region * r, unit * u)
return;
}
build_road(r, u, m, d);
} else cmistake(u, u->thisorder, 71, MSG_PRODUCE);
} else cmistake(u, findorder(u, u->thisorder), 71, MSG_PRODUCE);
return;
} else if (p == P_SHIP) {
if(r->planep && fval(r->planep, PFL_NOBUILD)) {
@ -1915,9 +1931,8 @@ buy(region * r, unit * u, request ** buyorders, const char * cmd)
}
}
if (r_demand(r, ltype)) {
sprintf(buf, "Dieses Luxusgut wird in %s nicht produziert",
regionid(r));
mistake(u, cmd, buf, MSG_COMMERCE);
add_message(&u->faction->msgs,
msg_error(u, cmd, "luxury_notsold", ""));
return;
}
o = (request *) calloc(1, sizeof(request));
@ -2137,8 +2152,8 @@ sell(region * r, unit * u, request ** sellorders, const char * cmd)
/* Belagerte Einheiten können nichts verkaufen. */
if (besieged(u)) {
sprintf(buf, "%s wird belagert.", unitname(u));
mistake(u, cmd, buf, MSG_COMMERCE);
add_message(&u->faction->msgs,
msg_error(u, cmd, "error60", ""));
return;
}
/* In der Region muß es eine Burg geben. */
@ -2293,18 +2308,18 @@ plant(region *r, unit *u)
}
/* Wasser des Lebens prüfen */
if (get_pooled(u, r, R_TREES) == 0) {
sprintf(buf, "Dazu braucht man %s.",
locale_string(u->faction->locale, resourcename(oldresourcetype[R_TREES], GR_PLURAL)));
mistake(u, u->thisorder, buf, MSG_PRODUCE);
add_message(&u->faction->msgs,
msg_error(u, findorder(u, u->thisorder), "resource_missing", "missing",
oldresourcetype[R_TREES]));
return;
}
htype = rherbtype(r);
n = new_get_pooled(u, htype->itype->rtype, GET_DEFAULT);
/* Kräuter prüfen */
if (n==0) {
sprintf(buf, "Dazu braucht man %s.",
locale_string(u->faction->locale, resourcename(htype->itype->rtype, GR_PLURAL)));
mistake(u, u->thisorder, buf, MSG_PRODUCE);
add_message(&u->faction->msgs,
msg_error(u, findorder(u, u->thisorder), "resource_missing", "missing",
htype->itype->rtype));
return;
}
@ -2388,7 +2403,7 @@ research(region *r, unit *u)
if (findparam(s, u->faction->locale) == P_HERBS) {
if (eff_skill(u, SK_HERBALISM, r) < 7) {
cmistake(u, u->thisorder, 227, MSG_EVENT);
cmistake(u, findorder(u, u->thisorder), 227, MSG_EVENT);
return;
}
@ -2464,16 +2479,14 @@ steal(region * r, unit * u, request ** stealorders)
}
if (u2->faction->age < IMMUN_GEGEN_ANGRIFF) {
sprintf(buf, "Eine Partei muß mindestens %d Wochen alt sein, bevor sie "
"bestohlen werden kann.", IMMUN_GEGEN_ANGRIFF);
mistake(u, u->thisorder, buf, MSG_INCOME);
add_message(&u->faction->msgs,
msg_error(u, findorder(u, u->thisorder), "steal_immunity", "age", IMMUN_GEGEN_ANGRIFF));
return;
}
assert(u->region==u2->region);
if (!can_contact(r, u, u2)) {
sprintf(buf, "%s wird belagert.", unitname(u2));
mistake(u, u->thisorder, buf, MSG_INCOME);
add_message(&u->faction->msgs, msg_error(u, findorder(u, u->thisorder), "error60", ""));
return;
}
n = eff_skill(u, SK_STEALTH, r) - wahrnehmung(r, f);
@ -2755,8 +2768,8 @@ tax(region * r, unit * u, request ** taxorders)
u2 = is_guarded(r, u, GUARD_TAX);
if (u2) {
sprintf(buf, "%s bewacht die Region.", unitname(u2));
mistake(u, u->thisorder, buf, MSG_INCOME);
add_message(&u->faction->msgs,
msg_error(u, findorder(u, u->thisorder), "region_guarded", "guard", u2));
return;
}
@ -2861,8 +2874,8 @@ produce(void)
if (!nonplayer(u))
work(r, u);
else if (u->faction->no > 0) {
sprintf(buf, "%s können nicht arbeiten", race[u->race].name[1]);
mistake(u, u->thisorder, buf, MSG_INCOME);
add_message(&u->faction->msgs,
msg_error(u, findorder(u, u->thisorder), "race_cantwork", "race", u->race));
}
break;

View File

@ -1759,8 +1759,8 @@ set_passw(void)
case K_MAGIEGEBIET:
if(u->faction->magiegebiet != 0) {
mistake(u, S->s, "Die Partei hat bereits ein Magiegebiet",
MSG_EVENT);
add_message(&u->faction->msgs,
msg_error(u, S->s, "one_circle_only", ""));
} else {
mtyp = getmagicskill();
if(mtyp == M_NONE) {
@ -1993,7 +1993,8 @@ instant_orders(void)
default:
if (strlen(param)) {
mistake(u, S->s, "unbekannter Kampfstatus", MSG_EVENT);
add_message(&u->faction->msgs,
msg_error(u, S->s, "unknown_status", ""));
} else {
u->status = ST_FIGHT;
}
@ -2138,8 +2139,8 @@ bewache_an(void)
strlist *S;
/* letzte schnellen befehle - bewache */
for (r = regions; r; r = r->next)
for (u = r->units; u; u = u->next)
for (r = regions; r; r = r->next) {
for (u = r->units; u; u = u->next) {
if (!fval(u, FL_MOVED)) {
for (S = u->orders; S; S = S->next) {
if (igetkeyword(S->s, u->faction->locale) == K_GUARD && getparam(u->faction->locale) != P_NOT) {
@ -2147,8 +2148,8 @@ bewache_an(void)
if (!illusionary(u) && u->race != RC_SPELL) {
#ifdef WACH_WAFF
if (!armedmen(u)) {
mistake(u, S->s,
"Die Einheit ist nicht bewaffnet und kampffähig", MSG_EVENT);
add_message(&u->faction->msgs,
msg_error(u, S->s, "unit_unarmed", ""));
continue;
}
#endif
@ -2162,7 +2163,8 @@ bewache_an(void)
}
}
}
}
}
}
void

View File

@ -2605,7 +2605,7 @@ reports(void)
init_intervals();
#endif
remove_empty_units();
log_printf("Report timestamp - %s", pzTime);
log_printf("Report timestamp - %s\n", pzTime);
for (f = factions; f; f = f->next) {
attrib * a = a_find(f->attribs, &at_reportspell);
current_faction = f;

View File

@ -198,10 +198,12 @@ teach_unit(unit * teacher, unit * student, int teaching, skill_t sk, boolean rep
teaching = max(0, teaching - student->number * 30);
if (report || teacher->faction != student->faction) {
add_message(&student->faction->msgs, new_message(student->faction,
"teach%u:teacher%u:student%t:skill", teacher, student, sk));
add_message(&teacher->faction->msgs, new_message(teacher->faction,
"teach%u:teacher%u:student%t:skill", teacher, student, sk));
add_message(&student->faction->msgs, msg_message("teach",
"teacher student skill", teacher, student, sk));
if (teacher->faction != student->faction) {
add_message(&teacher->faction->msgs, msg_message("teach",
"teacher student skill", teacher, student, sk));
}
}
}
return n;
@ -236,8 +238,8 @@ teach(region * r, unit * u)
teaching -= i * 30;
change_effect(u, oldpotiontype[P_FOOL], -i);
j = teaching / 30;
add_message(&u->faction->msgs, new_message(u->faction,
"teachdumb%u:teacher%i:amount", u, j));
add_message(&u->faction->msgs, msg_message("teachdumb",
"teacher amount", u, j));
}
if (teaching == 0)
return;
@ -570,10 +572,8 @@ learn(void)
if (a==NULL) a = a_add(&u->attribs, a_new(&at_learning));
if (money>0) {
use_pooled(u, r, R_SILVER, money);
add_message(&u->faction->msgs,
new_message(u->faction,
"studycost%u:unit%r:region%i:cost%t:skill",
u, u->region, money, i));
add_message(&u->faction->msgs, msg_message("studycost",
"unit region cost skill", u, u->region, money, i));
}
if (get_effect(u, oldpotiontype[P_WISE])) {

View File

@ -1046,7 +1046,6 @@ void * gc_add(void * p);
void gc_done(void);
void mistake(const struct unit * u, const char *cmd, const char *text, int mtype);
void addmessage(struct region * r, struct faction * f, const char *s, msg_t mtype, int level);
void caddmessage(struct region * r, struct faction * f, char *s, msg_t mtype, int level);
void cmistake(const struct unit * u, const char *cmd, int mno, int mtype);
/* grammatik-flags: */

View File

@ -372,6 +372,10 @@ SOURCE=.\plane.c
# End Source File
# Begin Source File
SOURCE=.\player.c
# End Source File
# Begin Source File
SOURCE=.\pool.c
# End Source File
# Begin Source File
@ -416,6 +420,10 @@ SOURCE=.\terrain.c
# End Source File
# Begin Source File
SOURCE=.\ugroup.c
# End Source File
# Begin Source File
SOURCE=.\unit.c
# End Source File
# End Target

View File

@ -264,7 +264,10 @@ msg_error(const struct unit * u, const char * cmd, const char * name, const char
const char *ic = sig;
void * args[16];
memset(args, 0, sizeof(args));
if (cmd==NULL) cmd = u->thisorder;
assert(cmd!=u->thisorder || !"only use entries from u->orders - memory corruption imminent.");
if (cmd==NULL) cmd = findorder(u, u->thisorder);
if (!mtype) {
fprintf(stderr, "trying to create message of unknown type \"%s\"\n", name);
@ -422,73 +425,82 @@ new_message(struct faction * receiver, const char* sig, ...)
return msg_create(mtype, (void**)args);
}
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);
}
void
caddmessage(region * r, faction * f, char *s, msg_t mtype, int level)
static void
caddmessage(region * r, faction * f, const char *s, msg_t mtype, int level)
{
const char * section = NULL;
message * m = NULL;
unused(level);
switch (mtype) {
case MSG_INCOME:
assert(f);
m = add_message(&f->msgs, new_message(f, "msg_economy%s:string", s));
m = add_message(&f->msgs, msg_message("msg_economy", "string", s));
break;
case MSG_BATTLE:
assert(0 || !"battle-meldungen nicht über addmessage machen");
break;
case MSG_MOVE:
assert(f);
m = add_message(&f->msgs, new_message(f, "msg_movement%s:string", s));
m = add_message(&f->msgs, msg_message("msg_movement", "string", s));
break;
case MSG_COMMERCE:
assert(f);
m = add_message(&f->msgs, new_message(f, "msg_economy%s:string", s));
m = add_message(&f->msgs, msg_message("msg_economy", "string", s));
break;
case MSG_PRODUCE:
assert(f);
m = add_message(&f->msgs, new_message(f, "msg_production%s:string", s));
m = add_message(&f->msgs, msg_message("msg_production", "string", s));
break;
case MSG_MAGIC:
case MSG_COMMENT:
case MSG_MESSAGE:
/* Botschaften an REGION oder einzelne PARTEI */
if (!r)
m = add_message(&f->msgs, new_message(f, "msg_event%s:string", s));
if (!r) {
assert(f);
m = add_message(&f->msgs, msg_message("msg_event", "string", s));
}
else
m = add_message(&r->msgs, new_message(f, "msg_event%s:string", s));
m = add_message(&r->msgs, msg_message("msg_event", "string", s));
break;
case MSG_ORCVERMEHRUNG:
case MSG_EVENT:
/* Botschaften an REGION oder einzelne PARTEI */
if (!r)
m = add_message(&f->msgs, new_message(f, "msg_event%s:string", s));
if (!r) {
assert(f);
m = add_message(&f->msgs, msg_message("msg_event", "string", s));
}
else
m = add_message(&r->msgs, new_message(f, "msg_event%s:string", s));
m = add_message(&r->msgs, msg_message("msg_event", "string", s));
break;
default:
assert(!"Ungültige Msg-Klasse!");
}
}
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);
}
void
xmistake(const unit * u, const char *s, const char *comment, int mtype)
{
if (u->faction->no == MONSTER_FACTION) return;
add_message(&u->faction->msgs, new_message(u->faction, "mistake%s:command%s:error%u:unit%r:region", s, comment, u, u->region));
add_message(&u->faction->msgs, msg_message("mistake",
"command error unit region", s, comment, u, u->region));
}
void
cmistake(const unit * u, const char *cmd, int mno, int mtype)
{
static char lbuf[64];
static char ebuf[20];
if (u->faction->no == MONSTER_FACTION) return;
sprintf(lbuf, "error%d", mno);
strcat(lbuf, "%s:command%u:unit%r:region");
add_message(&u->faction->msgs, new_message(u->faction, lbuf, cmd, u, u->region));
sprintf(ebuf, "error%d", mno);
add_message(&u->faction->msgs, msg_message(ebuf,
"command unit region", cmd, u, u->region));
}
void

View File

@ -50,7 +50,7 @@ void read_msglevels(struct warning ** w, FILE * F);
void set_msglevel(struct warning ** warnings, const char * type, int level);
extern struct message * msg_message(const char * name, const char* sig, ...);
extern struct message * msg_error(const struct unit *, const char *,
extern struct message * msg_error(const struct unit *, const char *cmd,
const char * name, const char* sig, ...);
extern struct message * add_message(struct message_list** pm, struct message * m);
extern void free_messages(struct message_list * m);

View File

@ -280,11 +280,11 @@ render_immediate(const message * m, const char * find, localizer * l)
} else {
var = "die Bevölkerung";
}
} else if(m->data[i] == NULL) {
} else if(m->data[i] == NULL || m->data[i] == &u_unknown) {
if (b == rbuf) {
var = "Eine unsichtbare Einheit";
var = "Eine unerkannte Einheit";
} else {
var = "eine unsichtbare Einheit";
var = "eine unerkannte Einheit";
}
} else {
var = unitname((unit*)m->data[i]);

View File

@ -839,3 +839,9 @@ spy_message(int spy, unit *u, unit *target)
}
}
const struct unit *
ucansee(const struct faction *f, const struct unit *u, const struct unit *x)
{
if (cansee(f, u->region, u, 0)) return u;
return x;
}

View File

@ -46,6 +46,8 @@ void reports(void);
char *gamedate(const struct locale *);
char *gamedate2(void);
extern const struct unit *ucansee(const struct faction *f, const struct unit *u, const struct unit *x);
struct summary;
extern void report_summary(struct summary * n, struct summary * o, boolean full);
extern struct summary * make_summary(boolean count_new);

View File

@ -8,7 +8,6 @@
This program may not be used, modified or distributed
without prior permission by the authors of Eressea.
$Id: ugroup.c,v 1.3 2001/04/29 19:27:42 enno Exp $
*/
#include <config.h>

View File

@ -55,7 +55,8 @@
/* ------------------------------------------------------------- */
const unit u_peasants = { NULL, NULL, NULL, NULL, NULL, 2, "Die Bauern" };
const unit u_peasants = { NULL, NULL, NULL, NULL, NULL, 2, "die Bauern" };
const unit u_unknown = { NULL, NULL, NULL, NULL, NULL, 1, "eine unbekannte Einheit" };
#define DMAXHASH 8191
typedef struct dead {

View File

@ -153,6 +153,7 @@ struct unit * findnewunit (const struct region * r, const struct faction *f, int
#define upotions(u) fval(u, FL_POTIONS)
extern const struct unit u_peasants;
extern const struct unit u_unknown;
int change_skill(struct unit * u, skill_t id, int byvalue);
void set_skill(struct unit * u, skill_t id, int value);

View File

@ -28,6 +28,7 @@
/* libc includes */
#include <stdlib.h>
#include <string.h>
extern const char *directions[];

View File

@ -143,6 +143,10 @@ SOURCE=.\base36.h
# End Source File
# Begin Source File
SOURCE=.\command.h
# End Source File
# Begin Source File
SOURCE=.\crmessage.h
# End Source File
# Begin Source File
@ -163,6 +167,10 @@ SOURCE=.\goodies.h
# End Source File
# Begin Source File
SOURCE=.\graph.h
# End Source File
# Begin Source File
SOURCE=.\language.h
# End Source File
# Begin Source File
@ -224,6 +232,10 @@ SOURCE=.\base36.c
# End Source File
# Begin Source File
SOURCE=.\command.c
# End Source File
# Begin Source File
SOURCE=.\crmessage.c
# End Source File
# Begin Source File
@ -248,6 +260,10 @@ SOURCE=.\goodies.c
# End Source File
# Begin Source File
SOURCE=.\graph.c
# End Source File
# Begin Source File
SOURCE=.\language.c
# End Source File
# Begin Source File

View File

@ -644,6 +644,14 @@ SOURCE=..\common\modules\gmcmd.c
# End Source File
# Begin Source File
SOURCE=..\common\modules\infocmd.c
# End Source File
# Begin Source File
SOURCE=..\common\modules\infocmd.h
# End Source File
# Begin Source File
SOURCE=..\common\modules\museum.c
!IF "$(CFG)" == "eressea - Win32 Release"
@ -692,6 +700,10 @@ SOURCE=..\common\modules\oceannames.c
# End Source File
# Begin Source File
SOURCE=..\common\modules\oceannames.h
# End Source File
# Begin Source File
SOURCE=..\common\modules\score.c
!IF "$(CFG)" == "eressea - Win32 Release"
@ -716,6 +728,14 @@ SOURCE=..\common\modules\score.c
# End Source File
# Begin Source File
SOURCE=..\common\modules\weather.c
# End Source File
# Begin Source File
SOURCE=..\common\modules\weather.h
# End Source File
# Begin Source File
SOURCE=..\common\modules\xmas2000.c
!IF "$(CFG)" == "eressea - Win32 Release"
@ -1108,19 +1128,6 @@ SOURCE=..\common\attributes\orcification.c
# Begin Source File
SOURCE=..\common\attributes\otherfaction.c
!IF "$(CFG)" == "eressea - Win32 Release"
!ELSEIF "$(CFG)" == "eressea - Win32 Debug"
# PROP Intermediate_Dir "../common/attributes/Debug"
!ELSEIF "$(CFG)" == "eressea - Win32 Conversion"
!ELSEIF "$(CFG)" == "eressea - Win32 Profile"
!ENDIF
# End Source File
# Begin Source File
@ -1271,6 +1278,10 @@ SOURCE=..\common\attributes\targetregion.h
!ENDIF
# End Source File
# Begin Source File
SOURCE=..\common\attributes\ugroup.c
# End Source File
# End Group
# Begin Group "Triggers"
@ -1535,10 +1546,6 @@ SOURCE=.\main.c
# End Source File
# Begin Source File
SOURCE=..\common\attributes\otherfaction.c
# End Source File
# Begin Source File
SOURCE=.\spells.c
# End Source File
# Begin Source File

View File

@ -2943,6 +2943,60 @@
</locale>
</message>
<message name="one_circle_only">
<type>
<arg name="unit" type="unit"></arg>
<arg name="region" type="region"></arg>
<arg name="command" type="string"></arg>
</type>
<locale name="de">
<nr section="events">
<text>"$unit($unit) in $region($region): '$command' - Die Partei hat bereits ein Magiegebiet."</text>
</nr>
</locale>
<locale name="de">
<nr section="events">
<text>"$unit($unit) in $region($region): '$command' - Your faction can only study one school of magic."</text>
</nr>
</locale>
</message>
<message name="unit_unarmed">
<type>
<arg name="unit" type="unit"></arg>
<arg name="region" type="region"></arg>
<arg name="command" type="string"></arg>
</type>
<locale name="de">
<nr section="errors">
<text>"$unit($unit) in $region($region): '$command' - Die Einheit ist nicht bewaffnet und kampffähig."</text>
</nr>
</locale>
<locale name="de">
<nr section="errors">
<text>"$unit($unit) in $region($region): '$command' - The unit is not armed and trained for combat."</text>
</nr>
</locale>
</message>
<message name="unknown_status">
<type>
<arg name="unit" type="unit"></arg>
<arg name="region" type="region"></arg>
<arg name="command" type="string"></arg>
</type>
<locale name="de">
<nr section="errors">
<text>"$unit($unit) in $region($region): '$command' - unbekannter Kampfstatus."</text>
</nr>
</locale>
<locale name="de">
<nr section="errors">
<text>"$unit($unit) in $region($region): '$command' - unknown status."</text>
</nr>
</locale>
</message>
<message name="error226">
<type>
<arg name="unit" type="unit"></arg>
@ -6529,10 +6583,11 @@
<arg name="region" type="region"></arg>
<arg name="building" type="building"></arg>
<arg name="opfer" type="int"></arg>
<arg name="road" type="int"></arg>
</type>
<locale name="de">
<nr section="events">
<text>"In $region($region) stürzte $building($building) ein.$if($opfer," $int($opfer) Opfer sind zu beklagen.","")"</text>
<text>"In $region($region) stürzte $building($building) ein.$if($road," Beim Einsturz wurde die halbe Straße vernichtet.","")$if($opfer," $int($opfer) Opfer $if($eq($opfer,1),"ist","sind") zu beklagen.","")"</text>
</nr>
</locale>
<locale name="en">
@ -6566,4 +6621,137 @@
</locale>
</message>
<message name="race_nogive">
<type>
<arg name="unit" type="unit"></arg>
<arg name="region" type="region"></arg>
<arg name="command" type="string"></arg>
<arg name="race" type="race"></arg>
</type>
<locale name="de">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - $race($race,0) geben nichts weg."</text>
</nr>
</locale>
<locale name="en">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - $race($race,0) do not give things away."</text>
</nr>
</locale>
</message>
<message name="race_noregroup">
<type>
<arg name="unit" type="unit"></arg>
<arg name="region" type="region"></arg>
<arg name="command" type="string"></arg>
<arg name="race" type="race"></arg>
</type>
<locale name="de">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - $race($race,0) können nicht neu gruppiert werden."</text>
</nr>
</locale>
<locale name="en">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - $race($race,0) cannot be regrouped."</text>
</nr>
</locale>
</message>
<message name="race_notake">
<type>
<arg name="unit" type="unit"></arg>
<arg name="region" type="region"></arg>
<arg name="command" type="string"></arg>
<arg name="race" type="race"></arg>
</type>
<locale name="de">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - $race($race,0) nehmen nichts an."</text>
</nr>
</locale>
<locale name="en">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - $race($race,0) will not accept anything."</text>
</nr>
</locale>
</message>
<message name="resource_missing">
<type>
<arg name="unit" type="unit"></arg>
<arg name="region" type="region"></arg>
<arg name="command" type="string"></arg>
<arg name="missing" type="resource"></arg>
</type>
<locale name="de">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - Dazu benötigt man $resource($missing,0)."</text>
</nr>
</locale>
<locale name="en">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - This requires $resource($missing,0)."</text>
</nr>
</locale>
</message>
<message name="region_guarded">
<type>
<arg name="unit" type="unit"></arg>
<arg name="region" type="region"></arg>
<arg name="command" type="string"></arg>
<arg name="guard" type="unit"></arg>
</type>
<locale name="de">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - $unit($guard) bewacht die Region."</text>
</nr>
</locale>
<locale name="en">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - $unit($guard) is guarding the region."</text>
</nr>
</locale>
</message>
<message name="luxury_notsold">
<type>
<arg name="unit" type="unit"></arg>
<arg name="region" type="region"></arg>
<arg name="command" type="string"></arg>
</type>
<locale name="de">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - Dieses Luxusgut wird hier nicht verkauft."</text>
</nr>
</locale>
<locale name="en">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - These goods are not on sale here."</text>
</nr>
</locale>
</message>
<message name="luxury_notsold">
<type>
<arg name="unit" type="unit"></arg>
<arg name="region" type="region"></arg>
<arg name="command" type="string"></arg>
<arg name="age" type="int"></arg>
</type>
<locale name="de">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - Eine Partei muß mindestens $int($age) Wochen alt sein, bevor sie bestohlen werden kann."</text>
</nr>
</locale>
<locale name="en">
<nr section="production">
<text>"$unit($unit) in $region($region): '$command' - A faction must be at least $int($age) weeks old before you can steal from it."</text>
</nr>
</locale>
</message>
</messages>

View File

@ -564,7 +564,7 @@ nr_size;en;size
nr_spells;en;spells
nr_combatspells;en;combat spells
nr_nospells;en;none
nr_addresslist;en;Addresses
nr_addresses;en;Addresses
## Küsten
Nordwestküste;en;northwest coast
@ -586,3 +586,4 @@ ADRESSEN;en;ADDRESSES
ZIPPED;en;ZIPPED
BZIP2;en;BZIP2
PUNKTE;en;SCORE
INFO;en;INFO