diff --git a/src/common/gamecode/economy.c b/src/common/gamecode/economy.c index 592fa6cb0..c382105a0 100644 --- a/src/common/gamecode/economy.c +++ b/src/common/gamecode/economy.c @@ -57,6 +57,7 @@ #include #include #include +#include /* libs includes */ #include @@ -1014,10 +1015,10 @@ forgetskill(unit * u) s = getstrtoken(); if ((talent = findskill(s, u->faction->locale)) != NOSKILL) { + struct message * m = add_message(&u->faction->msgs, + msg_message("forget", "unit skill", u, talent)); + msg_release(m); set_skill(u, talent, 0); -/* sprintf(buf, "%s vergißt das Talent %s.", u, talent); */ - add_message(&u->faction->msgs, new_message(u->faction, - "forget%u:unit%t:skill", u, talent)); } } @@ -1030,10 +1031,11 @@ report_donations(void) for (sp = spenden; sp; sp = sp->next) { region * r = sp->region; if (sp->betrag > 0) { - add_message(&r->msgs, new_message(sp->f1, - "donation%f:from%f:to%i:amount", sp->f1, sp->f2, sp->betrag)); - add_message(&r->msgs, new_message(sp->f2, - "donation%f:from%f:to%i:amount", sp->f1, sp->f2, sp->betrag)); + struct message * msg = msg_message("donation", + "from to amount", sp->f1, sp->f2, sp->betrag); + r_addmessage(r, sp->f1, msg); + r_addmessage(r, sp->f2, msg); + msg_release(msg); } } } @@ -1112,8 +1114,9 @@ maintain(building * b, boolean full) } if (paid && c>0) { /* TODO: wieviel von was wurde bezahlt */ - add_message(&u->faction->msgs, new_message(u->faction, - "maintenance%u:unit%b:building", u, b)); + message * msg = add_message(&u->faction->msgs, + msg_message("maintenance", "unit building", u, b)); + msg_release(msg); fset(b, BLD_MAINTAINED); if (work) fset(b, BLD_WORKING); for (c=0;b->type->maintenance[c].number;++c) { @@ -1143,8 +1146,9 @@ maintain(building * b, boolean full) assert(cost==0); } } else { - add_message(&u->faction->msgs, new_message(u->faction, - "maintenancefail%u:unit%b:building", u, b)); + message * msg = add_message(&u->faction->msgs, + msg_message("maintenancefail", "unit building", u, b)); + msg_release(msg); return false; } return true; @@ -1200,6 +1204,7 @@ gebaeude_stuerzt_ein(region * r, building * b) add_message(&f->msgs, msg); } } + msg_release(msg); destroy_building(b); } @@ -1220,7 +1225,7 @@ maintain_buildings(boolean crash) struct message * msg = msg_message("nomaintenance", "building", b); if (u) { add_message(&u->faction->msgs, msg); - add_message(&r->msgs, msg); + r_addmessage(r, u->faction, msg); } } } diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index c01f67c7a..3a32afbcf 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -69,6 +69,7 @@ #include #include #include +#include #ifdef AT_OPTION /* attributes includes */ @@ -521,8 +522,9 @@ peasants(region * r) dead++; if(dead > 0) { + message * msg = add_message(&r->msgs, msg_message("phunger", "dead", dead)); + msg_release(msg); peasants -= dead; - add_message(&r->msgs, new_message(NULL, "phunger%i:dead", dead)); } rsetpeasants(r, peasants); } @@ -1398,7 +1400,6 @@ deliverMail(faction * f, region * r, unit * u, const char *s, unit * receiver) { char message[DISPLAYSIZE + 1]; - strcpy(message, strcheck(s, DISPLAYSIZE)); if (!receiver) { /* BOTSCHAFT an PARTEI */ diff --git a/src/common/gamecode/randenc.c b/src/common/gamecode/randenc.c index 068cf2d71..74d6508c8 100644 --- a/src/common/gamecode/randenc.c +++ b/src/common/gamecode/randenc.c @@ -50,6 +50,7 @@ /* util includes */ #include +#include /* libc includes */ #include @@ -959,7 +960,7 @@ randomevents(void) { region *r; building *b, *b2; - unit *u, *u2; + unit *u; int n; int unfed; @@ -1158,15 +1159,9 @@ randomevents(void) if (rc && rpeasants(rc) > 0 && !fval(rc, RF_ORCIFIED)) chance += 2; } if (rand()%100 < chance) { + message * msg = add_message(&r->msgs, msg_message("deorcified", "region", r)); + msg_release(msg); freset(r, RF_ORCIFIED); - for (u2 = r->units; u2; u2 = u2->next ) freset(u2->faction, FL_DH); - for (u2 = r->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FL_DH)) { - add_message(&r->msgs, new_message(u2->faction, - "deorcified%r:region", r)); - fset(u2->faction, FL_DH); - } - } } } else { attrib *a = a_find(r->attribs, &at_orcification); @@ -1177,14 +1172,7 @@ randomevents(void) if (rand()%100 < chance) { fset(r, RF_ORCIFIED); a_remove(&r->attribs, a); - for (u2 = r->units; u2; u2 = u2->next) freset(u2->faction, FL_DH); - for (u2 = r->units; u2; u2 = u2->next) { - if (!fval(u2->faction, FL_DH)) { - add_message(&r->msgs, new_message(u2->faction, - "orcified%r:region", r)); - fset(u2->faction, FL_DH); - } - } + add_message(&r->msgs, msg_message("orcified", "region", r)); } else { a->data.i -= max(10,a->data.i/10); if (a->data.i <= 0) a_remove(&r->attribs, a); @@ -1199,30 +1187,16 @@ randomevents(void) switch(rterrain(r)) { case T_VOLCANO: if (rand()%100 < 5) { + message * msg = add_message(&r->msgs, msg_message("volcanostartsmoke", "region", r)); + msg_release(msg); rsetterrain(r, T_VOLCANO_SMOKING); - /* Meldungen generieren */ - for (u = r->units; u; u = u->next ) freset(u->faction, FL_DH); - for (u = r->units; u; u = u->next ) { - if (!fval(u->faction, FL_DH)) { - add_message(&r->msgs, new_message(u->faction, - "volcanostartsmoke%r:region", r)); - fset(u->faction, FL_DH); - } - } } break; case T_VOLCANO_SMOKING: if (rand()%100 < 10) { + message * msg = add_message(&r->msgs, msg_message("volcanostopsmoke", "region", r)); + msg_release(msg); rsetterrain(r, T_VOLCANO); - /* Meldungen generieren */ - for (u = r->units; u; u = u->next ) freset(u->faction, FL_DH); - for (u = r->units; u; u = u->next ) { - if (!fval(u->faction, FL_DH)) { - add_message(&r->msgs, new_message(u->faction, - "volcanostopsmoke%r:region", r)); - fset(u->faction, FL_DH); - } - } } else if (rand()%100 < 8) { volcano_outbreak(r); } @@ -1368,20 +1342,22 @@ randomevents(void) log_printf("%d %s in %s.\n", u->number, race[u->race].name[1], regionname(r, NULL)); - add_message(&r->msgs, new_message(NULL, - "undeadrise%r:region", r)); - for (u=r->units;u;u=u->next) freset(u->faction, FL_DH); - for (u=r->units;u;u=u->next) { - if (fval(u->faction, FL_DH)) continue; - fset(u->faction, FL_DH); - add_message(&u->faction->msgs, new_message(NULL, - "undeadrise%r:region", r)); + { + message * msg = msg_message("undeadrise", "region amount", r, undead); + add_message(&r->msgs, msg); + for (u=r->units;u;u=u->next) freset(u->faction, FL_DH); + for (u=r->units;u;u=u->next) { + if (fval(u->faction, FL_DH)) continue; + fset(u->faction, FL_DH); + add_message(&u->faction->msgs, msg); + } + msg_release(msg); } } else { int i = deathcount(r); if (i) { /* Gräber verwittern, 3% der Untoten finden die ewige Ruhe */ - deathcounts(r, (int)(1+i*0.03)); + deathcounts(r, (int)(-i*0.03)); } } } @@ -1405,6 +1381,8 @@ randomevents(void) if (woodcount(r) >= 40 && rand()%100 < 33) { int trees = rtrees(r); int treemen = rand()%(max(50,trees)/3); + struct message * msg; + treemen = max(25, treemen); woodcounts(r, -40); trees = max(0, trees-treemen); @@ -1420,15 +1398,15 @@ randomevents(void) log_printf("%d Ents in %s.\n", u->number, regionname(r, NULL)); - add_message(&r->msgs, new_message(NULL, - "entrise%r:region", r)); + msg = msg_message("entrise", "region amount", r, u->number); + add_message(&r->msgs, msg); for (u=r->units;u;u=u->next) freset(u->faction, FL_DH); for (u=r->units;u;u=u->next) { if (fval(u->faction, FL_DH)) continue; fset(u->faction, FL_DH); - add_message(&u->faction->msgs, new_message(NULL, - "entrise%r:region", r)); + add_message(&u->faction->msgs, msg); } + msg_release(msg); } } } @@ -1511,6 +1489,7 @@ void growlaen(void) { } else { attrib *a=a_new(&at_laen); + struct message * msg = NULL; a_add(&rl->region->attribs, a); rsetlaen(rl->region, add_laen[z]); @@ -1519,11 +1498,12 @@ void growlaen(void) { for (u = r->units; u; u = u->next ) { if (!fval(u->faction, FL_DH) && eff_skill(u, SK_MINING, rl->region) >= olditemtype[I_EOG]->minskill) { - add_message(&rl->region->msgs, new_message(u->faction, - "unveileog%u:unit%r:region", u, rl->region)); + if (!msg) msg = msg_message("unveileog", "unit region", u, rl->region); + r_addmessage(rl->region, u->faction, msg); fset(u->faction, FL_DH); } } + if (msg) msg_release(msg); } } free(add_laen); diff --git a/src/common/gamecode/spy.c b/src/common/gamecode/spy.c index 94cf0e56a..10b8ee9dc 100644 --- a/src/common/gamecode/spy.c +++ b/src/common/gamecode/spy.c @@ -443,34 +443,6 @@ sabotage(region * r, unit * u) sink_ship(r, sh, buffer, 1, u); } break; -#if 0 - case P_BUILDING: - if(u->building) { - /* TODO: Gebäude zerstören */ - } else { - building *b = getbuilding(r); - unit *owner; - - if(!b) { - cmistake(u, findorder(u, u->thisorder), 6, MSG_EVENT); - return; - } - owner = buildingowner(r, b); - - if(owner == NULL || eff_skill(u, SK_STEALTH, r) > wahrnehmung(r,owner->faction) { - /* Besser Curse benutzen, einfacher */ - a = a_add(b->attribs, a_new(&at_sabotaged)); - a->data.i = 1+rand()%(eff_skll(u, SK_SPY, r)); - } else if(owner) { /* Ertappt */ - add_message(&u->faction->msgs, - new_message(u->faction, "sabot_building_fail%u:unit", u); - add_message(&r->msgs, - new_message(owner->faction, "sabot_building_detect%u:unit", u); - } else { - } - } - break; -#endif default: cmistake(u, findorder(u, u->thisorder), 9, MSG_EVENT); return; diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index f161d4101..99d25505b 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -59,6 +59,7 @@ /* libc includes */ #include #include +#include #include #include #include @@ -2544,8 +2545,8 @@ plagues(region * r, boolean ismagic) gestorben = rpeasants(r) - peasants; if (gestorben > 0) { - add_message(&r->msgs, new_message(NULL, - "pest%i:dead", gestorben)); + message * msg = add_message(&r->msgs, msg_message("pest", "dead", gestorben)); + msg_release(msg); } rsetpeasants(r, peasants); } diff --git a/src/common/kernel/message.c b/src/common/kernel/message.c index ac588644f..4e533172f 100644 --- a/src/common/kernel/message.c +++ b/src/common/kernel/message.c @@ -435,22 +435,22 @@ caddmessage(region * r, faction * f, const char *s, msg_t mtype, int level) switch (mtype) { case MSG_INCOME: assert(f); - add_message(&f->msgs, msg_message("msg_economy", "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); - add_message(&f->msgs, msg_message("msg_movement", "string", s)); + m = add_message(&f->msgs, msg_message("msg_movement", "string", s)); break; case MSG_COMMERCE: assert(f); - add_message(&f->msgs, msg_message("msg_economy", "string", s)); + m = add_message(&f->msgs, msg_message("msg_economy", "string", s)); break; case MSG_PRODUCE: assert(f); - add_message(&f->msgs, msg_message("msg_production", "string", s)); + m = add_message(&f->msgs, msg_message("msg_production", "string", s)); break; case MSG_MAGIC: case MSG_COMMENT: @@ -470,6 +470,7 @@ caddmessage(region * r, faction * f, const char *s, msg_t mtype, int level) default: assert(!"Ungültige Msg-Klasse!"); } + if (m) msg_release(m); } void @@ -549,7 +550,7 @@ add_message(message_list** pm, message * m) *pm = malloc(sizeof(message_list)); (*pm)->end=&(*pm)->begin; } - mnew->msg = m; + mnew->msg = msg_addref(m); mnew->next = NULL; *((*pm)->end) = mnew; (*pm)->end=&mnew->next; @@ -563,8 +564,7 @@ free_messages(message_list * m) struct mlist * x = m->begin; while (x) { m->begin = x->next; - msg_free(x->msg); - free(x); + msg_release(x->msg); } } diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 6cb4d52f7..2da1e2211 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -922,7 +922,7 @@ r_getmessages(struct region * r, const struct faction * viewer) return NULL; } -void +struct message * r_addmessage(struct region * r, const struct faction * viewer, struct message * msg) { struct individual_message * imsg; @@ -936,5 +936,5 @@ r_addmessage(struct region * r, const struct faction * viewer, struct message * r->individual_messages = imsg; imsg->viewer = viewer; } - add_message(&imsg->msgs, msg); + return add_message(&imsg->msgs, msg); } \ No newline at end of file diff --git a/src/common/kernel/region.h b/src/common/kernel/region.h index 3bcb93302..d9049b3d7 100644 --- a/src/common/kernel/region.h +++ b/src/common/kernel/region.h @@ -86,7 +86,7 @@ typedef struct region { } region; extern struct message_list * r_getmessages(struct region * r, const struct faction * viewer); -extern void r_addmessage(struct region * r, const struct faction * viewer, struct message * msg); +extern struct message * r_addmessage(struct region * r, const struct faction * viewer, struct message * msg); typedef struct { int x; diff --git a/src/common/kernel/spell.c b/src/common/kernel/spell.c index 4f350737c..6509df155 100644 --- a/src/common/kernel/spell.c +++ b/src/common/kernel/spell.c @@ -53,6 +53,7 @@ /* util includes */ #include +#include #include #include @@ -945,14 +946,16 @@ sp_goodwinds(castorder *co) if(u->ship != sh ) /* nur den Schiffsbesatzungen! */ continue; if(!fval(u->faction, FL_DH) ) { + message * m = msg_message("wind_effect", "mage ship", cansee(u->faction, r, mage, 0) ? mage:NULL, sh); + r_addmessage(r, u->faction, m); + msg_release(m); fset(u->faction, FL_DH); - add_message(&r->msgs, new_message(u->faction, - "wind_effect%u:mage%h:ship", cansee(u->faction, r, mage, 0) ? mage:NULL, sh)); } } - if(!fval(mage->faction, FL_DH)){ - add_message(&mage->faction->msgs, new_message(mage->faction, - "wind_effect%u:mage%h:ship", mage, sh)); + if (!fval(mage->faction, FL_DH)) { + message * m = msg_message("wind_effect", "mage ship", mage, sh); + r_addmessage(r, mage->faction, m); + msg_release(m); } return cast_level; @@ -997,17 +1000,26 @@ sp_magicstreet(castorder *co) /* melden, 1x pro Partei */ freset(mage->faction, FL_DH); - for(u = r->units; u; u = u->next ) freset(u->faction, FL_DH); - for(u = r->units; u; u = u->next ) { - if(!fval(u->faction, FL_DH) ) { - fset(u->faction, FL_DH); - add_message(&r->msgs, new_message(u->faction, - "path_effect%u:mage%r:region", cansee(u->faction, r, mage, 0) ? mage:NULL, r)); + { + message * seen = msg_message("path_effect", "mage region", mage, r); + message * unseen = NULL; + for (u = r->units; u; u = u->next ) freset(u->faction, FL_DH); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FL_DH) ) { + fset(u->faction, FL_DH); + if (cansee(u->faction, r, mage, 0)) { + r_addmessage(r, u->faction, seen); + } else { + if (!unseen) unseen = msg_message("path_effect", "mage region", NULL, r); + r_addmessage(r, u->faction, unseen); + } + } } - } - if(!fval(mage->faction, FL_DH)){ - add_message(&mage->faction->msgs, new_message(mage->faction, - "path_effect%u:mage%r:region", mage, r)); + if(!fval(mage->faction, FL_DH)){ + add_message(&mage->faction->msgs, seen); + } + msg_release(seen); + if (unseen) msg_release(unseen); } return cast_level; @@ -1036,7 +1048,6 @@ sp_summonent(castorder *co) int cast_level = co->level; int power = co->force; unit *u; - unit *u2; attrib *a; int ents; @@ -1065,21 +1076,26 @@ sp_summonent(castorder *co) rsettrees(r, rtrees(r) - ents); - /* melden, 1x pro partei */ - freset(mage->faction, FL_DH); - for(u2 = r->units; u2; u2 = u2->next ) freset(u2->faction, FL_DH); - for(u2 = r->units; u2; u2 = u2->next ) { - if (!fval(u2->faction, FL_DH) ) { - fset(u2->faction, FL_DH); - add_message(&r->msgs, new_message(u2->faction, - "ent_effect%u:mage%i:amount", cansee(u2->faction, r, mage, 0)?mage:NULL, u->number)); + { + message * seen = msg_message("ent_effect", "mage amount", mage, ents); + message * unseen = NULL; + for (u = r->units; u; u = u->next ) freset(u->faction, FL_DH); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FL_DH) ) { + fset(u->faction, FL_DH); + if (cansee(u->faction, r, mage, 0)) { + r_addmessage(r, u->faction, seen); + } else { + if (!unseen) unseen = msg_message("ent_effect", "mage amount", NULL, ents); + r_addmessage(r, u->faction, unseen); + } + } } - } - if(!fval(mage->faction, FL_DH)){ - /* dann steht niemand von der Magierpartei in der Region, sieht also - * auch keine Regionsmeldung. ergo: global anzeigen */ - add_message(&mage->faction->msgs, new_message(mage->faction, - "ent_effect%u:mage%i:amount", mage, u->number)); + if(!fval(mage->faction, FL_DH)){ + add_message(&mage->faction->msgs, seen); + } + msg_release(seen); + if (unseen) msg_release(unseen); } return cast_level; @@ -1168,21 +1184,26 @@ sp_maelstrom(castorder *co) create_curse(mage,&mage->attribs,C_MAELSTROM,0,power,power,power,0); set_curseflag(r->attribs, C_MAELSTROM, 0, CURSE_ISNEW); - /* melden, 1x pro partei */ - freset(mage->faction, FL_DH); - for (u = r->units; u; u = u->next) freset(u->faction, FL_DH); - for (u = r->units; u; u = u->next) { - if (!fval(u->faction, FL_DH)) { - fset(u->faction, FL_DH); - add_message(&r->msgs, new_message(u->faction, - "maelstrom_effect%u:mage", cansee(u->faction, r, mage, 0) ? mage:NULL)); + { + message * seen = msg_message("maelstrom_effect", "mage", mage); + message * unseen = NULL; + for (u = r->units; u; u = u->next ) freset(u->faction, FL_DH); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FL_DH) ) { + fset(u->faction, FL_DH); + if (cansee(u->faction, r, mage, 0)) { + r_addmessage(r, u->faction, seen); + } else { + if (!unseen) unseen = msg_message("maelstrom_effect", "mage", NULL); + r_addmessage(r, u->faction, unseen); + } + } } - } - if(!fval(mage->faction, FL_DH)){ - /* dann steht niemand von der Magierpartei in der Region, sieht also - * auch keine Regionsmeldung. ergo: global anzeigen */ - add_message(&mage->faction->msgs, new_message(mage->faction, - "maelstrom_effect%u:mage", mage)); + if(!fval(mage->faction, FL_DH)){ + add_message(&mage->faction->msgs, seen); + } + msg_release(seen); + if (unseen) msg_release(unseen); } return cast_level; @@ -1220,21 +1241,26 @@ sp_mallorn(castorder *co) rsettrees(r, rtrees(r)/2); fset(r, RF_MALLORN); - /* melden, 1x pro partei */ - freset(mage->faction, FL_DH); - for (u = r->units; u; u = u->next) freset(u->faction, FL_DH); - for (u = r->units; u; u = u->next) { - if (!fval(u->faction, FL_DH)) { - fset(u->faction, FL_DH); - add_message(&r->msgs, new_message(u->faction, - "mallorn_effect%u:mage", cansee(u->faction, r, mage, 0) ? mage:NULL)); + { + message * seen = msg_message("mallorn_effect", "mage", mage); + message * unseen = NULL; + for (u = r->units; u; u = u->next ) freset(u->faction, FL_DH); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FL_DH) ) { + fset(u->faction, FL_DH); + if (cansee(u->faction, r, mage, 0)) { + r_addmessage(r, u->faction, seen); + } else { + if (!unseen) unseen = msg_message("mallorn_effect", "mage", NULL); + r_addmessage(r, u->faction, unseen); + } + } } - } - if(!fval(mage->faction, FL_DH)){ - /* dann steht niemand von der Magierpartei in der Region, sieht also - * auch keine Regionsmeldung. ergo: global anzeigen */ - add_message(&mage->faction->msgs, new_message(mage->faction, - "mallorn_effect%u:mage", mage)); + if(!fval(mage->faction, FL_DH)){ + add_message(&mage->faction->msgs, seen); + } + msg_release(seen); + if (unseen) msg_release(unseen); } return cast_level; @@ -1266,22 +1292,26 @@ sp_blessedharvest(castorder *co) * (Max(Dauer), Max(Stärke))*/ create_curse(mage,&r->attribs,C_BLESSEDHARVEST,0,power,power,1,0); - /* melden, 1x pro partei */ - freset(mage->faction, FL_DH); - for (u = r->units; u; u = u->next) freset(u->faction, FL_DH); - - for (u = r->units; u; u = u->next) { - if (!fval(u->faction, FL_DH)) { - fset(u->faction, FL_DH); - add_message(&r->msgs, new_message(u->faction, - "harvest_effect%u:mage", cansee(u->faction, r, mage, 0) ? mage:NULL)); + { + message * seen = msg_message("harvest_effect", "mage", mage); + message * unseen = NULL; + for (u = r->units; u; u = u->next ) freset(u->faction, FL_DH); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FL_DH) ) { + fset(u->faction, FL_DH); + if (cansee(u->faction, r, mage, 0)) { + r_addmessage(r, u->faction, seen); + } else { + if (!unseen) unseen = msg_message("harvest_effect", "mage", NULL); + r_addmessage(r, u->faction, unseen); + } + } } - } - if (!fval(mage->faction, FL_DH)){ - /* dann steht niemand von der Magierpartei in der Region, sieht also - * auch keine Regionsmeldung. ergo: global anzeigen */ - add_message(&mage->faction->msgs, new_message(mage->faction, - "harvest_effect%u:mage", mage)); + if(!fval(mage->faction, FL_DH)) { + add_message(&mage->faction->msgs, seen); + } + msg_release(seen); + if (unseen) msg_release(unseen); } return cast_level; } @@ -1312,22 +1342,26 @@ sp_hain(castorder *co) trees = lovar(force * 10) + force; rsettrees(r, rtrees(r) + trees); - /* melden, 1x pro partei */ - freset(mage->faction, FL_DH); - for (u = r->units; u; u = u->next) freset(u->faction, FL_DH); - for (u = r->units; u; u = u->next) { - if (!fval(u->faction, FL_DH)) { - fset(u->faction, FL_DH); - add_message(&r->msgs, new_message(u->faction, - "growtree_effect%u:mage%i:amount", - cansee(u->faction, r, mage, 0) ? mage:NULL, trees)); + { + message * seen = msg_message("growtree_effect", "mage amount", mage, trees); + message * unseen = NULL; + for (u = r->units; u; u = u->next ) freset(u->faction, FL_DH); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FL_DH) ) { + fset(u->faction, FL_DH); + if (cansee(u->faction, r, mage, 0)) { + r_addmessage(r, u->faction, seen); + } else { + if (!unseen) unseen = msg_message("growtree_effect", "mage amount", NULL, trees); + r_addmessage(r, u->faction, unseen); + } + } } - } - if (!fval(mage->faction, FL_DH)){ - /* dann steht niemand von der Magierpartei in der Region, sieht also - * auch keine Regionsmeldung. ergo: global anzeigen */ - add_message(&mage->faction->msgs, new_message(mage->faction, - "growtree_effect%u:mage%i:amount", mage, trees)); + if(!fval(mage->faction, FL_DH)) { + add_message(&mage->faction->msgs, seen); + } + msg_release(seen); + if (unseen) msg_release(unseen); } return cast_level; @@ -1403,7 +1437,7 @@ sp_rosthauch(castorder *co) } } - if (ironweapon){ + if (ironweapon) { /* {$mage mage} legt einen Rosthauch auf {target}. {amount} Waffen * wurden vom Rost zerfressen */ add_message(&mage->faction->msgs, new_message(mage->faction, @@ -1426,6 +1460,30 @@ sp_rosthauch(castorder *co) return min(success, cast_level); } +/* Report a spell's effect to the units in the region. +*/ +static void +report_effect(region * r, unit * mage, message * seen, message * unseen) +{ + unit * u; + for (u = r->units; u; u = u->next ) freset(u->faction, FL_DH); + for (u = r->units; u; u = u->next ) { + if (!fval(u->faction, FL_DH) ) { + fset(u->faction, FL_DH); + if (cansee(u->faction, r, mage, 0)) { + r_addmessage(r, u->faction, seen); + } else if (unseen) { + r_addmessage(r, u->faction, unseen); + } + } + } + if(!fval(mage->faction, FL_DH)) { + add_message(&mage->faction->msgs, seen); + } + msg_release(seen); + if (unseen) msg_release(unseen); +} + /* ------------------------------------------------------------- */ /* Name: Kälteschutz * Stufe: 3 @@ -2084,14 +2142,14 @@ sp_holyground(castorder *co) unit *mage = (unit *)co->magician; int cast_level = co->level; int power = co->force; + message * msg = r_addmessage(r, mage->faction, msg_message("holyground", "mage", mage)); + msg_release(msg); create_curse(mage, &r->attribs, C_HOLYGROUND, 0, power*power, 1, 0, 0); set_curseflag(mage->building->attribs, C_HOLYGROUND, 0, CURSE_NOAGE); - add_message(&r->msgs, new_message(mage->faction, "holyground%u:mage", mage)); - a_removeall(&r->attribs, &at_deathcount); return cast_level; @@ -4880,28 +4938,14 @@ sp_puttorest(castorder *co) region *r = co->rt; unit *mage = (unit *)co->magician; int laid_to_rest = 0; - unit *u; - laid_to_rest = dice(co->force * 2, 100); laid_to_rest = max(laid_to_rest, deathcount(r)); deathcounts(r, -laid_to_rest); - /* melden, 1x pro partei */ - for (u = r->units; u; u = u->next) freset(u->faction, FL_DH); - - for (u = r->units; u; u = u->next) { - if (!fval(u->faction, FL_DH)) { - fset(u->faction, FL_DH); - add_message(&r->msgs, new_message(u->faction, - "puttorest%u:mage", cansee(u->faction, r, mage, 0) ? mage:NULL)); - } - } - - if (!fval(mage->faction, FL_DH)){ - add_message(&mage->faction->msgs, new_message(mage->faction, - "puttorest%u:mage", mage)); - } + report_effect(r, mage, + msg_message("puttorest", "mage", mage), + msg_message("puttorest", "mage", NULL)); return co->level; } diff --git a/src/common/util/message.c b/src/common/util/message.c index c70bf4958..9a892ae6c 100644 --- a/src/common/util/message.c +++ b/src/common/util/message.c @@ -14,7 +14,8 @@ #include #include "message.h" -#include +/* libc includes */ +#include #include #include #include @@ -79,6 +80,7 @@ msg_create(const struct message_type * type, void * args[]) message * msg = (message *)malloc(sizeof(message)); msg->type = type; msg->parameters = calloc(sizeof(void*), type->nparameters); + msg->refcount=1; for (i=0;i!=type->nparameters;++i) { msg->parameters[i] = args[i]; } @@ -130,8 +132,24 @@ mt_find(const char * name) } void -msg_free(message *m) +msg_free(message *msg) { - free((void*)m->parameters); - free(m); + assert(msg->refcount==0); + free((void*)msg->parameters); + free(msg); } + +void +msg_release(struct message * msg) +{ + if (--msg->refcount) return; + msg_free(msg); +} + +struct message * +msg_addref(struct message * msg) +{ + ++msg->refcount; + return msg; +} + diff --git a/src/common/util/message.h b/src/common/util/message.h index 5802d9597..407726e37 100644 --- a/src/common/util/message.h +++ b/src/common/util/message.h @@ -22,6 +22,7 @@ typedef struct message_type { typedef struct message { const struct message_type * type; const void ** parameters; + int refcount; } message; extern struct message_type * mt_new(const char * name, const char ** args); @@ -33,8 +34,9 @@ extern struct message * msg_create(const struct message_type * type, void * args extern struct message * msg_create_va(const struct message_type * type, ...); /* msg_create(&mt_simplesentence, "enno", "eats", "chocolate", &locale_de); * parameters must be in the same order as they were for mt_new! */ -extern void msg_free(struct message *m); - /* remove message and associated data from memory */ + +extern void msg_release(struct message * msg); +extern struct message * msg_addref(struct message * msg); extern const char * mt_name(const struct message_type* mtype); diff --git a/src/eressea/korrektur.c b/src/eressea/korrektur.c index 9cbe1271a..6c4a91446 100644 --- a/src/eressea/korrektur.c +++ b/src/eressea/korrektur.c @@ -1880,6 +1880,17 @@ undo_deadpeasants(void) } #endif +static void +fix_undead3percent(void) +{ + region * r = regions; + while (r) { + int dead = deathcount(r); + deathcounts(r, -(dead/2)); + r = r->next; + } +} + #if 0 static void fix_targetregion_resolve(void) @@ -2235,6 +2246,7 @@ korrektur(void) #endif fix_migrants(); fix_allies(); + do_once(atoi36("ud3p"), fix_undead3percent()); do_once(atoi36("fhrb"), fix_herbs()); do_once(atoi36("ftos"), fix_timeouts()); do_once(atoi36("fixsl"), fix_prices());