VERKAUFE ALLES verbessert
- http://eressea.upb.de/mantis/bug_view_page.php?bug_id=0000192
  Keine opponent-Auswahl mehr im Kampf

- LUA:
  unit.weight und unit.capacity (read-only)

- Reporterzeugung:
  Parteiliste nur noch in parteien.full

Stringfix (Fräcke)
This commit is contained in:
Enno Rehling 2004-07-14 07:12:36 +00:00
parent d853ae12a4
commit 8455962a84
8 changed files with 235 additions and 187 deletions

View File

@ -135,7 +135,6 @@ scramble(void *data, int n, size_t width)
static void static void
expandorders(region * r, request * requests) expandorders(region * r, request * requests)
{ {
int i, j;
unit *u; unit *u;
request *o; request *o;
@ -147,32 +146,34 @@ expandorders(region * r, request * requests)
norders = 0; norders = 0;
for (o = requests; o; o = o->next) for (o = requests; o; o = o->next) {
if (o->qty > 0) { if (o->qty > 0) {
norders += o->qty; norders += o->qty;
} }
}
if (norders > 0) { if (norders > 0) {
oa = (request *) calloc(norders, sizeof(request)); int i = 0;
i = 0; oa = (request *) calloc(norders, sizeof(request));
for (o = requests; o; o = o->next) { for (o = requests; o; o = o->next) {
if (o->qty > 0) { if (o->qty > 0) {
for (j = o->qty; j; j--) { int j;
oa[i] = *o; for (j = o->qty; j; j--) {
oa[i].unit->n = 0; oa[i] = *o;
i++; oa[i].unit->n = 0;
} i++;
} }
} }
scramble(oa, norders, sizeof(request));
} else {
oa = NULL;
}
while (requests) {
request * o = requests->next;
free(requests);
requests = o;
} }
scramble(oa, norders, sizeof(request));
} else {
oa = NULL;
}
while (requests) {
request * o = requests->next;
free(requests);
requests = o;
}
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
@ -333,74 +334,75 @@ recruit(unit * u, struct order * ord, request ** recruitorders)
return; return;
} }
if (!(u->faction->race->ec_flags & ECF_REC_HORSES) && fval(r, RF_ORCIFIED)) {
#if RACE_ADJUSTMENTS #if RACE_ADJUSTMENTS
if (fval(r, RF_ORCIFIED) && u->faction->race != new_race[RC_URUK] && if (u->faction->race != new_race[RC_URUK])
#else #else
if (fval(r, RF_ORCIFIED) && u->faction->race != new_race[RC_ORC] && if (u->faction->race != new_race[RC_ORC])
#endif #endif
!(u->faction->race->ec_flags & ECF_REC_HORSES)) { {
cmistake(u, ord, 238, MSG_EVENT); cmistake(u, ord, 238, MSG_EVENT);
return;
}
}
recruitcost = u->faction->race->recruitcost;
if (recruitcost) {
pl = getplane(r);
if (pl && fval(pl, PFL_NORECRUITS)) {
add_message(&u->faction->msgs,
msg_feedback(u, ord, "error_pflnorecruit", ""));
return; return;
} }
if (get_pooled(u, r, R_SILVER) < recruitcost) {
recruitcost = u->faction->race->recruitcost; cmistake(u, ord, 142, MSG_EVENT);
if (recruitcost) { return;
pl = getplane(r);
if (pl && fval(pl, PFL_NORECRUITS)) {
add_message(&u->faction->msgs,
msg_feedback(u, ord, "error_pflnorecruit", ""));
return;
}
if (get_pooled(u, r, R_SILVER) < recruitcost) {
cmistake(u, ord, 142, MSG_EVENT);
return;
}
} }
if (!playerrace(u->race) || idle(u->faction)) { }
if (!playerrace(u->race) || idle(u->faction)) {
cmistake(u, ord, 139, MSG_EVENT);
return;
}
/* snotlinge sollten hiermit bereits abgefangen werden, die
* parteirasse ist uruk oder ork*/
if (u->race != u->faction->race) {
if (u->number != 0) {
cmistake(u, ord, 139, MSG_EVENT); cmistake(u, ord, 139, MSG_EVENT);
return; return;
} }
/* snotlinge sollten hiermit bereits abgefangen werden, die else u->race = u->faction->race;
* parteirasse ist uruk oder ork*/ }
if (u->race != u->faction->race) {
if (u->number != 0) {
cmistake(u, ord, 139, MSG_EVENT);
return;
}
else u->race = u->faction->race;
}
init_tokens(ord); init_tokens(ord);
skip_token(); skip_token();
n = geti(); n = geti();
if (has_skill(u, SK_MAGIC)) { if (has_skill(u, SK_MAGIC)) {
/* error158;de;{unit} in {region}: '{command}' - Magier arbeiten /* error158;de;{unit} in {region}: '{command}' - Magier arbeiten
* grundsätzlich nur alleine! */ * grundsätzlich nur alleine! */
cmistake(u, ord, 158, MSG_EVENT); cmistake(u, ord, 158, MSG_EVENT);
return; return;
} }
if (has_skill(u, SK_ALCHEMY) if (has_skill(u, SK_ALCHEMY)
&& count_skill(u->faction, SK_ALCHEMY) + n > && count_skill(u->faction, SK_ALCHEMY) + n >
max_skill(u->faction, SK_ALCHEMY)) max_skill(u->faction, SK_ALCHEMY))
{ {
cmistake(u, ord, 156, MSG_EVENT); cmistake(u, ord, 156, MSG_EVENT);
return; return;
} }
if (recruitcost) n = min(n, get_pooled(u, r, R_SILVER) / recruitcost); if (recruitcost) n = min(n, get_pooled(u, r, R_SILVER) / recruitcost);
u->wants = n; u->wants = n;
if (!n) { if (!n) {
cmistake(u, ord, 142, MSG_EVENT); cmistake(u, ord, 142, MSG_EVENT);
return; return;
} }
o = (request *) calloc(1, sizeof(request)); o = (request *) calloc(1, sizeof(request));
o->qty = n; o->qty = n;
o->unit = u; o->unit = u;
addlist(recruitorders, o); addlist(recruitorders, o);
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
@ -1792,7 +1794,7 @@ static int tax_per_size[7] =
{0, 6, 12, 18, 24, 30, 36}; {0, 6, 12, 18, 24, 30, 36};
static void static void
expandselling(region * r, request * sellorders) expandselling(region * r, request * sellorders, int limit)
{ {
int money, price, j, max_products; int money, price, j, max_products;
/* int m, n = 0; */ /* int m, n = 0; */
@ -1872,6 +1874,7 @@ expandselling(region * r, request * sellorders)
i=0; i=0;
for (search=luxurytypes;search!=ltype;search=search->next) ++i; for (search=luxurytypes;search!=ltype;search=search->next) ++i;
} }
if (counter[i]>=limit) continue;
if (counter[i]+1 > max_products && multi > 1) --multi; if (counter[i]+1 > max_products && multi > 1) --multi;
price = ltype->price * multi; price = ltype->price * multi;
@ -1955,8 +1958,8 @@ expandselling(region * r, request * sellorders)
if (a==NULL) continue; if (a==NULL) continue;
for (itm=(item*)a->data.v; itm; itm=itm->next) { for (itm=(item*)a->data.v; itm; itm=itm->next) {
if (itm->number) { if (itm->number) {
add_message(&u->faction->msgs, new_message(u->faction, ADDMSG(&u->faction->msgs, msg_message("sellamount",
"sellamount%u:unit%i:amount%X:resource", u, itm->number, itm->type->rtype)); "unit amount resource", u, itm->number, itm->type->rtype));
} }
} }
a_remove(&u->attribs, a); a_remove(&u->attribs, a);
@ -1964,19 +1967,19 @@ expandselling(region * r, request * sellorders)
} }
} }
static void static boolean
sell(unit * u, request ** sellorders, struct order * ord) sell(unit * u, request ** sellorders, struct order * ord)
{ {
boolean unlimited = true;
const item_type * itype; const item_type * itype;
const luxury_type * ltype=NULL; const luxury_type * ltype=NULL;
int n; int n;
request *o;
region * r = u->region; region * r = u->region;
const char *s; const char *s;
if (u->ship && is_guarded(r, u, GUARD_CREWS)) { if (u->ship && is_guarded(r, u, GUARD_CREWS)) {
cmistake(u, ord, 69, MSG_INCOME); cmistake(u, ord, 69, MSG_INCOME);
return; return false;
} }
/* sellorders sind KEIN array, weil für alle items DIE SELBE resource /* sellorders sind KEIN array, weil für alle items DIE SELBE resource
* (das geld der region) aufgebraucht wird. */ * (das geld der region) aufgebraucht wird. */
@ -1986,18 +1989,19 @@ sell(unit * u, request ** sellorders, struct order * ord)
s = getstrtoken(); s = getstrtoken();
if (findparam(s, u->faction->locale) == P_ANY) { if (findparam(s, u->faction->locale) == P_ANY) {
unlimited = false;
n = rpeasants(r) / TRADE_FRACTION; n = rpeasants(r) / TRADE_FRACTION;
if (rterrain(r) == T_DESERT && buildingtype_exists(r, bt_find("caravan"))) if (rterrain(r) == T_DESERT && buildingtype_exists(r, bt_find("caravan")))
n *= 2; n *= 2;
if (n==0) { if (n==0) {
cmistake(u, ord, 303, MSG_COMMERCE); cmistake(u, ord, 303, MSG_COMMERCE);
return; return false;
} }
} else { } else {
n = atoi(s); n = atoi(s);
if (n==0) { if (n==0) {
cmistake(u, ord, 27, MSG_COMMERCE); cmistake(u, ord, 27, MSG_COMMERCE);
return; return false;
} }
} }
/* Belagerte Einheiten können nichts verkaufen. */ /* Belagerte Einheiten können nichts verkaufen. */
@ -2005,19 +2009,19 @@ sell(unit * u, request ** sellorders, struct order * ord)
if (besieged(u)) { if (besieged(u)) {
add_message(&u->faction->msgs, add_message(&u->faction->msgs,
msg_feedback(u, ord, "error60", "")); msg_feedback(u, ord, "error60", ""));
return; return false;
} }
/* In der Region muß es eine Burg geben. */ /* In der Region muß es eine Burg geben. */
if (u->race == new_race[RC_INSECT]) { if (u->race == new_race[RC_INSECT]) {
if (rterrain(r) != T_SWAMP && rterrain(r) != T_DESERT && !rbuildings(r)) { if (rterrain(r) != T_SWAMP && rterrain(r) != T_DESERT && !rbuildings(r)) {
cmistake(u, ord, 119, MSG_COMMERCE); cmistake(u, ord, 119, MSG_COMMERCE);
return; return false;
} }
} else { } else {
if (!rbuildings(r)) { if (!rbuildings(r)) {
cmistake(u, ord, 119, MSG_COMMERCE); cmistake(u, ord, 119, MSG_COMMERCE);
return; return false;
} }
} }
@ -2027,21 +2031,23 @@ sell(unit * u, request ** sellorders, struct order * ord)
if (!n) { if (!n) {
cmistake(u, ord, 54, MSG_COMMERCE); cmistake(u, ord, 54, MSG_COMMERCE);
return; return false;
} }
s=getstrtoken(); s=getstrtoken();
itype = finditemtype(s, u->faction->locale); itype = finditemtype(s, u->faction->locale);
if (itype!=NULL) ltype = resource2luxury(itype->rtype); if (itype!=NULL) ltype = resource2luxury(itype->rtype);
if (ltype==NULL) { if (ltype==NULL) {
cmistake(u, ord, 126, MSG_COMMERCE); cmistake(u, ord, 126, MSG_COMMERCE);
return; return false;
} }
else { else {
attrib * a; attrib * a;
request *o;
int k, available; int k, available;
if (!r_demand(r, ltype)) { if (!r_demand(r, ltype)) {
cmistake(u, ord, 263, MSG_COMMERCE); cmistake(u, ord, 263, MSG_COMMERCE);
return; return false;
} }
available = new_get_pooled(u, itype->rtype, GET_DEFAULT); available = new_get_pooled(u, itype->rtype, GET_DEFAULT);
@ -2058,7 +2064,7 @@ sell(unit * u, request ** sellorders, struct order * ord)
if (n <= 0) { if (n <= 0) {
cmistake(u, ord, 264, MSG_COMMERCE); cmistake(u, ord, 264, MSG_COMMERCE);
return; return false;
} }
/* Hier wird request->type verwendet, weil die obere limit durch /* Hier wird request->type verwendet, weil die obere limit durch
* das silber gegeben wird (region->money), welches für alle * das silber gegeben wird (region->money), welches für alle
@ -2089,6 +2095,7 @@ sell(unit * u, request ** sellorders, struct order * ord)
addlist(sellorders, o); addlist(sellorders, o);
if (n) fset(u, UFL_TRADER); if (n) fset(u, UFL_TRADER);
return unlimited;
} }
} }
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
@ -2897,6 +2904,7 @@ produce(void)
* lehren vor lernen. */ * lehren vor lernen. */
for (r = regions; r; r = r->next) { for (r = regions; r; r = r->next) {
boolean limited = true;
assert(rmoney(r) >= 0); assert(rmoney(r) >= 0);
assert(rpeasants(r) >= 0); assert(rpeasants(r) >= 0);
@ -2931,7 +2939,9 @@ produce(void)
buy(u, &buyorders, ord); buy(u, &buyorders, ord);
break; break;
case K_SELL: case K_SELL:
sell(u, &sellorders, ord); /* sell returns true if the sale is not limited
* by the region limit */
limited = !sell(u, &sellorders, ord) & limited;
break; break;
} }
} }
@ -3014,7 +3024,11 @@ produce(void)
* können. */ * können. */
if (buyorders) expandbuying(r, buyorders); if (buyorders) expandbuying(r, buyorders);
if (sellorders) expandselling(r, sellorders);
if (sellorders) {
int limit = rpeasants(r) / TRADE_FRACTION;
expandselling(r, sellorders, limited?limit:INT_MAX);
}
/* Die Spieler sollen alles Geld verdienen, bevor sie beklaut werden /* Die Spieler sollen alles Geld verdienen, bevor sie beklaut werden
* (expandstealing). */ * (expandstealing). */

View File

@ -3408,31 +3408,33 @@ report_summary(summary * s, summary * o, boolean full)
} }
fprintf(F, "Neue Spieler:\t %d\n", newplayers); fprintf(F, "Neue Spieler:\t %d\n", newplayers);
if (factions) if (full) {
fprintf(F, "\nParteien:\n\n"); if (factions)
fprintf(F, "\nParteien:\n\n");
for (f = factions; f; f = f->next) { for (f = factions; f; f = f->next) {
out_faction(F, f); out_faction(F, f);
} }
if (NMRTimeout() && full) { if (NMRTimeout() && full) {
fprintf(F, "\n\nFactions with NMRs:\n"); fprintf(F, "\n\nFactions with NMRs:\n");
for (i = NMRTimeout(); i > 0; --i) { for (i = NMRTimeout(); i > 0; --i) {
for(f=factions; f; f=f->next) { for(f=factions; f; f=f->next) {
if(i == NMRTimeout()) { if(i == NMRTimeout()) {
if(turn - f->lastorders >= i) { if(turn - f->lastorders >= i) {
out_faction(F, f); out_faction(F, f);
} }
} else { } else {
if(turn - f->lastorders == i) { if(turn - f->lastorders == i) {
out_faction(F, f); out_faction(F, f);
} }
} }
} }
} }
} }
}
fclose(F); fclose(F);
if (full) { if (full) {
printf("Schreibe Liste der Adressen (adressen)...\n"); printf("Schreibe Liste der Adressen (adressen)...\n");

View File

@ -1209,14 +1209,14 @@ terminate(troop dt, troop at, int type, const char *damage, boolean missile)
/* Sieben Leben */ /* Sieben Leben */
if (old_race(du->race) == RC_CAT && (chance(1.0 / 7))) { if (old_race(du->race) == RC_CAT && (chance(1.0 / 7))) {
#ifdef SMALL_BATTLE_MESSAGES #ifdef SMALL_BATTLE_MESSAGES
if (b->small) { if (b->small) {
strcat(smallbuf, ", doch die Katzengöttin ist gnädig"); strcat(smallbuf, ", doch die Katzengöttin ist gnädig");
battlerecord(b, smallbuf); battlerecord(b, smallbuf);
} }
#endif #endif
assert(dt.index>=0 && dt.index<du->number); assert(dt.index>=0 && dt.index<du->number);
df->person[dt.index].hp = unit_max_hp(du); df->person[dt.index].hp = unit_max_hp(du);
return false; return false;
} }
/* Heiltrank schluerfen und hoffen */ /* Heiltrank schluerfen und hoffen */
@ -1235,15 +1235,15 @@ terminate(troop dt, troop at, int type, const char *damage, boolean missile)
battlerecord(b, smallbuf); battlerecord(b, smallbuf);
} else } else
#endif #endif
{ {
message * m = msg_message("battle::potionsave", "unit", du); message * m = msg_message("battle::potionsave", "unit", du);
message_faction(b, du->faction, m); message_faction(b, du->faction, m);
msg_release(m); msg_release(m);
} }
assert(dt.index>=0 && dt.index<du->number); assert(dt.index>=0 && dt.index<du->number);
df->person[dt.index].hp = du->race->hitpoints; df->person[dt.index].hp = du->race->hitpoints;
return false; return false;
} }
strcat(debugbuf, ", tot"); strcat(debugbuf, ", tot");
battledebug(debugbuf); battledebug(debugbuf);
@ -1367,7 +1367,7 @@ static troop
select_opponent(battle * b, troop at, int minrow, int maxrow) select_opponent(battle * b, troop at, int minrow, int maxrow)
{ {
fighter * af = at.fighter; fighter * af = at.fighter;
troop dt = af->person[at.index].opponent; troop dt;
if (af->unit->race->flags & RCF_FLY) { if (af->unit->race->flags & RCF_FLY) {
/* flying races ignore min- and maxrow and can attack anyone fighting /* flying races ignore min- and maxrow and can attack anyone fighting
@ -1377,6 +1377,8 @@ select_opponent(battle * b, troop at, int minrow, int maxrow)
} }
minrow = max(minrow, FIGHT_ROW); minrow = max(minrow, FIGHT_ROW);
#ifdef FIXED_OPPONENTS
dt = af->person[at.index].opponent;
if (dt.fighter!=NULL && dt.index<dt.fighter->alive-dt.fighter->removed) { if (dt.fighter!=NULL && dt.index<dt.fighter->alive-dt.fighter->removed) {
fighter * df = dt.fighter; fighter * df = dt.fighter;
int row = get_unitrow(df); int row = get_unitrow(df);
@ -1388,7 +1390,9 @@ select_opponent(battle * b, troop at, int minrow, int maxrow)
return dt; return dt;
} }
} }
#endif
dt = select_enemy(b, at.fighter, minrow, maxrow); dt = select_enemy(b, at.fighter, minrow, maxrow);
#ifdef FIXED_OPPONENTS
if (dt.fighter!=NULL) { if (dt.fighter!=NULL) {
fighter * df = dt.fighter; fighter * df = dt.fighter;
troop ot = df->person[dt.index].opponent; troop ot = df->person[dt.index].opponent;
@ -1396,6 +1400,7 @@ select_opponent(battle * b, troop at, int minrow, int maxrow)
df->person[dt.index].opponent = at; df->person[dt.index].opponent = at;
} }
} }
#endif
return dt; return dt;
} }

View File

@ -153,19 +153,22 @@ extern "C" {
struct item * loot; struct item * loot;
int catmsg; /* Merkt sich, ob Katapultmessage schon generiert. */ int catmsg; /* Merkt sich, ob Katapultmessage schon generiert. */
struct person { struct person {
int attack : 8; /* (Magie) Attackenbonus der Personen */ int attack : 8; /* (Magie) Attackenbonus der Personen */
int defence : 8; /* (Magie) Paradenbonus der Personen */ int defence : 8; /* (Magie) Paradenbonus der Personen */
int damage : 8; /* (Magie) Schadensbonus der Personen im Nahkampf */ int damage : 8; /* (Magie) Schadensbonus der Personen im Nahkampf */
int damage_rear : 8; /* (Magie) Schadensbonus der Personen im Fernkampf */ int damage_rear : 8; /* (Magie) Schadensbonus der Personen im Fernkampf */
int hp : 16; /* Trefferpunkte der Personen */ int hp : 16; /* Trefferpunkte der Personen */
int flags : 8; /* (Magie) Diverse Flags auf Kämpfern */ int flags : 8; /* (Magie) Diverse Flags auf Kämpfern */
int speed : 8; /* (Magie) Geschwindigkeitsmultiplkator. */ int speed : 8; /* (Magie) Geschwindigkeitsmultiplkator. */
int reload : 4; /* Anzahl Runden, die die Waffe x noch laden muss. int reload : 4; /* Anzahl Runden, die die Waffe x noch laden muss.
* dahinter steckt ein array[RL_MAX] wenn er min. eine hat. */ * dahinter steckt ein array[RL_MAX] wenn er min. eine hat. */
int last_action : 8; /* In welcher Runde haben wir zuletzt etwas getan */ int last_action : 8; /* In welcher Runde haben wir zuletzt etwas getan */
struct weapon * missile; /* missile weapon */ struct weapon * missile; /* missile weapon */
struct weapon * melee; /* melee weapon */ struct weapon * melee; /* melee weapon */
struct troop opponent; /* default opponent */ #undef FIXED_OPPONENTS
#ifdef FIXED_OPPONENTS
struct troop opponent; /* default opponent */
#endif
} * person; } * person;
int flags; int flags;
struct { struct {

View File

@ -2388,7 +2388,7 @@ init_locales(void)
/* TODO: soll hier weg */ /* TODO: soll hier weg */
extern building_type bt_caldera; extern building_type bt_caldera;
extern attrib_type at_traveldir_new; extern attrib_type at_shiptrail;
attrib_type at_germs = { attrib_type at_germs = {
"germs", "germs",
@ -2460,7 +2460,7 @@ remove_empty_factions(boolean writedropouts)
/* monster (0) werden nicht entfernt. alive kann beim readgame /* monster (0) werden nicht entfernt. alive kann beim readgame
* () auf 0 gesetzt werden, wenn monsters keine einheiten mehr * () auf 0 gesetzt werden, wenn monsters keine einheiten mehr
* haben. */ * haben. */
if (f->alive == 0 && f->no != MONSTER_FACTION) { if ((f->units==NULL || f->alive == 0) && f->no != MONSTER_FACTION) {
ursprung * ur = f->ursprung; ursprung * ur = f->ursprung;
while (ur && ur->id!=0) ur=ur->next; while (ur && ur->id!=0) ur=ur->next;
if (!quiet) printf("\t%s\n", factionname(f)); if (!quiet) printf("\t%s\n", factionname(f));
@ -3157,7 +3157,7 @@ attrib_init(void)
{ {
/* Alle speicherbaren Attribute müssen hier registriert werden */ /* Alle speicherbaren Attribute müssen hier registriert werden */
at_register(&at_unitdissolve); at_register(&at_unitdissolve);
at_register(&at_traveldir_new); at_register(&at_shiptrail);
at_register(&at_familiar); at_register(&at_familiar);
at_register(&at_familiarmage); at_register(&at_familiarmage);
at_register(&at_clone); at_register(&at_clone);

View File

@ -62,7 +62,6 @@
/* TODO: boder_type::move() must be able to change target (wisps) */ /* TODO: boder_type::move() must be able to change target (wisps) */
extern border_type bt_wisps; extern border_type bt_wisps;
extern item_type it_demonseye;
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
typedef struct traveldir { typedef struct traveldir {
@ -82,19 +81,19 @@ static attrib_type at_traveldir = {
static void static void
a_traveldir_new_init(attrib *a) shiptrail_init(attrib *a)
{ {
a->data.v = calloc(1, sizeof(traveldir)); a->data.v = calloc(1, sizeof(traveldir));
} }
static void static void
a_traveldir_new_finalize(attrib *a) shiptrail_finalize(attrib *a)
{ {
free(a->data.v); free(a->data.v);
} }
static int static int
a_traveldir_new_age(attrib *a) shiptrail_age(attrib *a)
{ {
traveldir *t = (traveldir *)(a->data.v); traveldir *t = (traveldir *)(a->data.v);
@ -104,7 +103,7 @@ a_traveldir_new_age(attrib *a)
} }
static int static int
a_traveldir_new_read(attrib *a, FILE *f) shiptrail_read(attrib *a, FILE *f)
{ {
traveldir *t = (traveldir *)(a->data.v); traveldir *t = (traveldir *)(a->data.v);
int no, age, dir; int no, age, dir;
@ -117,19 +116,19 @@ a_traveldir_new_read(attrib *a, FILE *f)
} }
static void static void
a_traveldir_new_write(const attrib *a, FILE *f) shiptrail_write(const attrib *a, FILE *f)
{ {
traveldir *t = (traveldir *)(a->data.v); traveldir *t = (traveldir *)(a->data.v);
fprintf(f, "%d %d %d ", t->no, (int)t->dir, t->age); fprintf(f, "%d %d %d ", t->no, (int)t->dir, t->age);
} }
attrib_type at_traveldir_new = { attrib_type at_shiptrail = {
"traveldir_new", "traveldir_new",
a_traveldir_new_init, shiptrail_init,
a_traveldir_new_finalize, shiptrail_finalize,
a_traveldir_new_age, shiptrail_age,
a_traveldir_new_write, shiptrail_write,
a_traveldir_new_read shiptrail_read
}; };
static int static int
@ -473,9 +472,8 @@ travelthru(const unit * u, region * r)
} }
static void static void
leave_trail(unit * u, region * from, region_list *route) leave_trail(ship * sh, region * from, region_list *route)
{ {
ship * sh = u->ship;
region * r = from; region * r = from;
while (route!=NULL) { while (route!=NULL) {
@ -486,7 +484,7 @@ leave_trail(unit * u, region * from, region_list *route)
* if we use this kind of direction-attribute */ * if we use this kind of direction-attribute */
if (dir<MAXDIRECTIONS && dir>=0) { if (dir<MAXDIRECTIONS && dir>=0) {
traveldir * td = NULL; traveldir * td = NULL;
attrib * a = a_find(r->attribs, &at_traveldir_new); attrib * a = a_find(r->attribs, &at_shiptrail);
while (a!=NULL) { while (a!=NULL) {
td = (traveldir *)a->data.v; td = (traveldir *)a->data.v;
@ -495,7 +493,7 @@ leave_trail(unit * u, region * from, region_list *route)
} }
if (a==NULL) { if (a==NULL) {
a = a_add(&(r->attribs), a_new(&at_traveldir_new)); a = a_add(&(r->attribs), a_new(&at_shiptrail));
td = (traveldir *)a->data.v; td = (traveldir *)a->data.v;
td->no = sh->no; td->no = sh->no;
} }
@ -536,7 +534,7 @@ move_ship(ship * sh, region * from, region * to, region_list * route)
if (u->ship == sh) { if (u->ship == sh) {
if (!trail) { if (!trail) {
leave_trail(u, from, route); leave_trail(sh, from, route);
trail = true; trail = true;
} }
if (route!=NULL) travel_route(u, from, route); if (route!=NULL) travel_route(u, from, route);
@ -631,6 +629,7 @@ drifting_ships(region * r)
while (*shp) { while (*shp) {
ship * sh = *shp; ship * sh = *shp;
region * rnext = NULL; region * rnext = NULL;
region_list * route = NULL;
unit * captain; unit * captain;
int d_offset; int d_offset;
@ -679,9 +678,12 @@ drifting_ships(region * r)
/* Das Schiff und alle Einheiten darin werden nun von r /* Das Schiff und alle Einheiten darin werden nun von r
* nach rnext verschoben. Danach eine Meldung. */ * nach rnext verschoben. Danach eine Meldung. */
sh = move_ship(sh, r, rnext, NULL); add_regionlist(&route, rnext);
sh = move_ship(sh, r, rnext, route);
free_regionlist(route);
if (sh!=NULL) { if (sh!=NULL) {
fset(sh, SF_DRIFTED); fset(sh, SF_DRIFTED);
if (rnext->terrain != T_OCEAN && !flying_ship(sh)) { if (rnext->terrain != T_OCEAN && !flying_ship(sh)) {
@ -1814,19 +1816,7 @@ move(unit * u, boolean move_on_land)
followers += travel(u, r2, 0, &route); followers += travel(u, r2, 0, &route);
} }
if (i_get(u->items, &it_demonseye)) { fset(u, UFL_LONGACTION);
direction_t d;
for (d=0;d!=MAXDIRECTIONS;++d) {
region * rc = rconnect(r2,d);
if (rc) {
sprintf(buf, "Im %s ist eine ungeheure magische Präsenz zu verspüren.",
locale_string(u->faction->locale, directions[dir_invert(d)]));
addmessage(rc, NULL, buf, MSG_EVENT, ML_IMPORTANT);
}
}
}
if (u->region!=r) fset(u, UFL_LONGACTION);
set_order(&u->thisorder, NULL); set_order(&u->thisorder, NULL);
if (fval(u, UFL_FOLLOWED) && route!=NULL) { if (fval(u, UFL_FOLLOWED) && route!=NULL) {
@ -2000,7 +1990,7 @@ age_traveldir(region *r)
static direction_t static direction_t
hunted_dir(attrib *at, int id) hunted_dir(attrib *at, int id)
{ {
attrib *a = a_find(at, &at_traveldir_new); attrib *a = a_find(at, &at_shiptrail);
while (a!=NULL) { while (a!=NULL) {
traveldir *t = (traveldir *)(a->data.v); traveldir *t = (traveldir *)(a->data.v);
@ -2234,9 +2224,6 @@ move_pirates(void)
for (r = regions; r; r = r->next) { for (r = regions; r; r = r->next) {
unit ** up = &r->units; unit ** up = &r->units;
/* Abtreiben von beschädigten, unterbemannten, überladenen Schiffen */
drifting_ships(r);
while (*up) { while (*up) {
unit *u = *up; unit *u = *up;
@ -2319,7 +2306,13 @@ movement(void)
} }
/* else *up is already the next unit */ /* else *up is already the next unit */
} }
if (!repeat) r = r->next; if (!repeat) {
if (ships==0) {
/* Abtreiben von beschädigten, unterbemannten, überladenen Schiffen */
drifting_ships(r);
}
r = r->next;
}
} }
} }

View File

@ -12,6 +12,7 @@
#include <kernel/faction.h> #include <kernel/faction.h>
#include <kernel/item.h> #include <kernel/item.h>
#include <kernel/magic.h> #include <kernel/magic.h>
#include <kernel/movement.h>
#include <kernel/order.h> #include <kernel/order.h>
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/region.h> #include <kernel/region.h>
@ -73,6 +74,19 @@ unit_orders(const unit& u) {
return eressea::list<std::string, order *, bind_orders>(u.orders); return eressea::list<std::string, order *, bind_orders>(u.orders);
} }
class bind_items {
public:
static item * next(item * node) { return node->next; }
static std::string value(item * node) {
return std::string(node->type->rtype->_name[0]);
}
};
static eressea::list<std::string, item *, bind_items>
unit_items(const unit& u) {
return eressea::list<std::string, item *, bind_items>(u.items);
}
static unit * static unit *
add_unit(faction * f, region * r) add_unit(faction * f, region * r)
{ {
@ -385,6 +399,17 @@ unit_setscript(struct unit& u, const functor<void>& f)
setscript(&u.attribs, fptr); setscript(&u.attribs, fptr);
} }
static int
unit_weight(const struct unit& u)
{
return weight(&u);
}
static int
unit_capacity(const struct unit& u)
{
return walkingcapacity(&u);
}
void void
bind_unit(lua_State * L) bind_unit(lua_State * L)
@ -402,22 +427,28 @@ bind_unit(lua_State * L)
.property("faction", &unit_getfaction, &unit_setfaction) .property("faction", &unit_getfaction, &unit_setfaction)
.def_readwrite("hp", &unit::hp) .def_readwrite("hp", &unit::hp)
.def_readwrite("status", &unit::status) .def_readwrite("status", &unit::status)
.property("weight", &unit_weight)
.property("capacity", &unit_capacity)
// orders: // orders:
.def("add_order", &unit_addorder) .def("add_order", &unit_addorder)
.def("clear_orders", &unit_clearorders) .def("clear_orders", &unit_clearorders)
.property("orders", &unit_orders, return_stl_iterator) .property("orders", &unit_orders, return_stl_iterator)
// key-attribute: // key-attributes for named flags:
.def("set_flag", &set_flag) .def("set_flag", &set_flag)
.def("get_flag", &get_flag) .def("get_flag", &get_flag)
// items: // items:
.def("get_item", &unit_getitem) .def("get_item", &unit_getitem)
.def("add_item", &unit_additem) .def("add_item", &unit_additem)
.property("items", &unit_items, return_stl_iterator)
// skills:
.def("get_skill", &unit_getskill) .def("get_skill", &unit_getskill)
.def("eff_skill", &unit_effskill) .def("eff_skill", &unit_effskill)
.def("set_skill", &unit_setskill) .def("set_skill", &unit_setskill)
.def("set_brain", &unit_setscript) .def("set_brain", &unit_setscript)
.def("set_racename", &unit_setracename) .def("set_racename", &unit_setracename)
.def("add_spell", &unit_addspell) .def("add_spell", &unit_addspell)

View File

@ -70,7 +70,7 @@
</string> </string>
<string name="wente_dress_p"> <string name="wente_dress_p">
<text locale="de">Frack</text> <text locale="de">Fräcke</text>
<text locale="en">tuxedos</text> <text locale="en">tuxedos</text>
</string> </string>