From c61127ab6fbfb00a775f6b9c4094838ac11e2b60 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 12 Feb 2007 07:27:04 +0000 Subject: [PATCH] SIMPLE_ESCAPE: Flucht verhindert BEWACHE. --- src/common/gamecode/laws.c | 27 ++++++++------ src/common/gamecode/monster.c | 11 ++++-- src/common/kernel/eressea.c | 20 +++++++++-- src/common/kernel/eressea.h | 6 ++-- src/common/kernel/save.c | 62 ++++++++++++++++++-------------- src/common/spells/alp.c | 62 ++++++++++++++++---------------- src/common/spells/combatspells.c | 8 ++--- src/common/spells/spells.c | 6 ++-- src/res/messages.xml | 11 ++++++ 9 files changed, 130 insertions(+), 83 deletions(-) diff --git a/src/common/gamecode/laws.c b/src/common/gamecode/laws.c index c1f9ba2d3..28b73938c 100644 --- a/src/common/gamecode/laws.c +++ b/src/common/gamecode/laws.c @@ -2461,22 +2461,22 @@ status_cmd(unit * u, struct order * ord) param = getstrtoken(); switch (findparam(param, u->faction->locale)) { case P_NOT: - u->status = ST_AVOID; + setstatus(u, ST_AVOID); break; case P_BEHIND: - u->status = ST_BEHIND; + setstatus(u, ST_BEHIND); break; case P_FLEE: - u->status = ST_FLEE; + setstatus(u, ST_FLEE); break; case P_CHICKEN: - u->status = ST_CHICKEN; + setstatus(u, ST_CHICKEN); break; case P_AGGRO: - u->status = ST_AGGRO; + setstatus(u, ST_AGGRO); break; case P_VORNE: - u->status = ST_FIGHT; + setstatus(u, ST_FIGHT); break; case P_HELP: if (getparam(u->faction->locale) == P_NOT) { @@ -2490,7 +2490,7 @@ status_cmd(unit * u, struct order * ord) add_message(&u->faction->msgs, msg_feedback(u, ord, "unknown_status", "")); } else { - u->status = ST_FIGHT; + setstatus(u, ST_FIGHT); } } return 0; @@ -2548,11 +2548,14 @@ combatspell_cmd(unit * u, struct order * ord) /* Beachten: einige Monster sollen auch unbewaffent die Region bewachen * können */ -enum { E_GUARD_OK, E_GUARD_UNARMED, E_GUARD_NEWBIE }; +enum { E_GUARD_OK, E_GUARD_UNARMED, E_GUARD_NEWBIE, E_GUARD_FLEEING }; static int can_start_guarding(const unit * u) { +#ifdef SIMPLE_ESCAPE + if (u->status>=ST_FLEE) return E_GUARD_FLEEING; +#endif if (fval(u->race, RCF_UNARMEDGUARD)) return E_GUARD_OK; if (!armedmen(u)) return E_GUARD_UNARMED; if (u->faction->age < NewbieImmunity()) return E_GUARD_NEWBIE; @@ -2598,12 +2601,14 @@ guard_on_cmd(unit * u, struct order * ord) guard(u, GUARD_ALL); } else { int err = can_start_guarding(u); - if (err==E_GUARD_UNARMED) { + if (err==E_GUARD_OK) { + guard(u, GUARD_ALL); + } else if (err==E_GUARD_UNARMED) { ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unit_unarmed", "")); + } else if (err==E_GUARD_FLEEING) { + cmistake(u, ord, 320, MSG_EVENT); } else if (err==E_GUARD_NEWBIE) { cmistake(u, ord, 304, MSG_EVENT); - } else { - guard(u, GUARD_ALL); } } } diff --git a/src/common/gamecode/monster.c b/src/common/gamecode/monster.c index b3ffba282..ab17af82a 100644 --- a/src/common/gamecode/monster.c +++ b/src/common/gamecode/monster.c @@ -805,10 +805,12 @@ recruit_dracoids(unit * dragon, int size) change_money(dragon, -un->number * 50); equip_unit(un, get_equipment("recruited_dracoid")); - un->status = ST_FIGHT; + setstatus(un, ST_FIGHT); for (weapon=un->items;weapon;weapon=weapon->next) { const weapon_type * wtype = weapon->type->rtype->wtype; - if (wtype && (wtype->flags & WTF_MISSILE)) un->status = ST_BEHIND; + if (wtype && (wtype->flags & WTF_MISSILE)) { + setstatus(un, ST_BEHIND); + } sprintf(buf, "%s \"%s\"", keywords[K_STUDY], skillname(weapon->type->rtype->wtype->skill, f->locale)); new_order = parse_order(buf, default_locale); @@ -941,7 +943,10 @@ plan_monsters(void) attack_chance = 0.0; } - if (u->status>ST_BEHIND) u->status = ST_FIGHT; /* all monsters fight */ + if (u->status>ST_BEHIND) { + setstatus(u, ST_FIGHT); + /* all monsters fight */ + } /* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */ produceexp(u, SK_OBSERVATION, u->number); diff --git a/src/common/kernel/eressea.c b/src/common/kernel/eressea.c index 60bddac71..724d7ceb8 100644 --- a/src/common/kernel/eressea.c +++ b/src/common/kernel/eressea.c @@ -1960,7 +1960,7 @@ create_unit(region * r, faction * f, int number, const struct race *urace, int i attrib * a; /* erbt Kampfstatus */ - u->status = creator->status; + setstatus(u, creator->status); /* erbt Gebäude/Schiff*/ if (creator->region==r) { @@ -2427,12 +2427,29 @@ attrib_type at_guard = { ATF_UNIQUE }; +void +setstatus(struct unit * u, int status) +{ + assert(status>=ST_AGGRO && status<=ST_FLEE); + if (u->status!=status) { + u->status = status; +#ifdef SIMPLE_ESCAPE + if (u->status==ST_FLEE) { + setguard(u, GUARD_NONE); + } +#endif + } +} + void setguard(unit * u, unsigned int flags) { /* setzt die guard-flags der Einheit */ attrib * a = NULL; assert(flags==0 || !fval(u, UFL_MOVED)); +#ifdef SIMPLE_ESCAPE + assert(flags==0 || u->statusattribs, &at_guard); } @@ -2449,7 +2466,6 @@ setguard(unit * u, unsigned int flags) unsigned int getguard(const unit * u) { - if (!fval(u->region->terrain, LAND_REGION)) return GUARD_NONE; if (fval(u, UFL_GUARD)) { attrib * a = a_find(u->attribs, &at_guard); diff --git a/src/common/kernel/eressea.h b/src/common/kernel/eressea.h index 15a71862e..c4b9aed30 100644 --- a/src/common/kernel/eressea.h +++ b/src/common/kernel/eressea.h @@ -1035,8 +1035,10 @@ void addmessage(struct region * r, struct faction * f, const char *s, msg_t mtyp /* Verhindert Abbau von Resourcen mit RTF_LIMITED */ #define GUARD_ALL 0xFFFF -extern void setguard(struct unit * u, unsigned int flags); - /* setzt die guard-flags der Einheit */ +extern void setstatus(struct unit * u, int status); +/* !< sets combatstatus of a unit */ +extern void setguard(struct unit * u, unsigned int flags); +/* !< setzt die guard-flags der Einheit */ extern unsigned int getguard(const struct unit * u); /* liest die guard-flags der Einheit */ extern void guard(struct unit * u, unsigned int mask); diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index a71ef9c8c..7fadd94e1 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -1015,34 +1015,42 @@ readunit(FILE * F) if (count_unit(u)) u->faction->no_units++; set_number(u, number); - u->building = findbuilding(rid(F)); - u->ship = findship(rid(F)); + u->building = findbuilding(rid(F)); + u->ship = findship(rid(F)); - if (global.data_version <= 73) { - if (ri(F)) { - fset(u, UFL_OWNER); - } else { - freset(u, UFL_OWNER); - } - } - u->status = (status_t) ri(F); - if (global.data_version < NEWSTATUS_VERSION) { - switch (u->status) { - case 0: u->status = ST_FIGHT; break; - case 1: u->status = ST_BEHIND; break; - case 2: u->status = ST_AVOID; break; - case 3: u->status = ST_FLEE; break; - default: assert(0); - } - } - if (global.data_version <= 73) { - if (ri(F)) { - guard(u, GUARD_ALL); - } else { - guard(u, GUARD_NONE); - } - } else { - u->flags = ri(F) & ~UFL_DEBUG; + if (global.data_version <= 73) { + if (ri(F)) { + fset(u, UFL_OWNER); + } else { + freset(u, UFL_OWNER); + } + } + setstatus(u, ri(F)); + if (global.data_version < NEWSTATUS_VERSION) { + switch (u->status) { + case 0: + setstatus(u, ST_FIGHT); + break; + case 1: + setstatus(u, ST_BEHIND); + break; + case 2: + setstatus(u, ST_AVOID); + break; + case 3: + setstatus(u, ST_FLEE); + default: + assert(!"unknown status in data"); + } + } + if (global.data_version <= 73) { + if (ri(F)) { + guard(u, GUARD_ALL); + } else { + guard(u, GUARD_NONE); + } + } else { + u->flags = ri(F) & ~UFL_DEBUG; u->flags &= UFL_SAVEMASK; } /* Persistente Befehle einlesen */ diff --git a/src/common/spells/alp.c b/src/common/spells/alp.c index 80944c499..d33da68db 100644 --- a/src/common/spells/alp.c +++ b/src/common/spells/alp.c @@ -89,43 +89,43 @@ static attrib_type at_alp = { int sp_summon_alp(struct castorder *co) { - unit *alp, *opfer; - region *r = co->rt; - unit *mage = co->magician.u; - int cast_level = co->level; - spellparameter *pa = co->par; + unit *alp, *opfer; + region *r = co->rt; + unit *mage = co->magician.u; + int cast_level = co->level; + spellparameter *pa = co->par; - opfer = pa->param[0]->data.u; + opfer = pa->param[0]->data.u; - /* Der Alp gehört den Monstern, darum erhält der Magier auch keine - * Regionsberichte von ihm. Er erhält aber später eine Mitteilung, - * sobald der Alp sein Opfer erreicht hat. - */ - alp = createunit(r, findfaction(MONSTER_FACTION), 1, new_race[RC_ALP]); - set_level(alp, SK_STEALTH, 7); - set_string(&alp->name, "Alp"); - alp->status = ST_FLEE; /* flieht */ + /* Der Alp gehört den Monstern, darum erhält der Magier auch keine + * Regionsberichte von ihm. Er erhält aber später eine Mitteilung, + * sobald der Alp sein Opfer erreicht hat. + */ + alp = createunit(r, findfaction(MONSTER_FACTION), 1, new_race[RC_ALP]); + set_level(alp, SK_STEALTH, 7); + set_string(&alp->name, "Alp"); + setstatus(alp, ST_FLEE); /* flieht */ - { - attrib * a = a_add(&alp->attribs, a_new(&at_alp)); - alp_data * ad = (alp_data*) a->data.v; - ad->mage = mage; - ad->target = opfer; - } + { + attrib * a = a_add(&alp->attribs, a_new(&at_alp)); + alp_data * ad = (alp_data*) a->data.v; + ad->mage = mage; + ad->target = opfer; + } - { - /* Wenn der Alp stirbt, den Magier nachrichtigen */ - add_trigger(&alp->attribs, "destroy", trigger_unitmessage(mage, + { + /* Wenn der Alp stirbt, den Magier nachrichtigen */ + add_trigger(&alp->attribs, "destroy", trigger_unitmessage(mage, "Ein Alp starb, ohne sein Ziel zu erreichen.", MSG_EVENT, ML_INFO)); - /* Wenn Opfer oder Magier nicht mehr existieren, dann stirbt der Alp */ - add_trigger(&mage->attribs, "destroy", trigger_killunit(alp)); - add_trigger(&opfer->attribs, "destroy", trigger_killunit(alp)); - } - sprintf(buf, "%s beschwört den Alp %s für %s.", unitname(mage), - unitname(alp), unitname(opfer)); - addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO); + /* Wenn Opfer oder Magier nicht mehr existieren, dann stirbt der Alp */ + add_trigger(&mage->attribs, "destroy", trigger_killunit(alp)); + add_trigger(&opfer->attribs, "destroy", trigger_killunit(alp)); + } + sprintf(buf, "%s beschwört den Alp %s für %s.", unitname(mage), + unitname(alp), unitname(opfer)); + addmessage(r, mage->faction, buf, MSG_MAGIC, ML_INFO); - return cast_level; + return cast_level; } diff --git a/src/common/spells/combatspells.c b/src/common/spells/combatspells.c index ac2115b64..7ee7ab0eb 100644 --- a/src/common/spells/combatspells.c +++ b/src/common/spells/combatspells.c @@ -737,7 +737,7 @@ sp_shadowcall(fighter * fi, int level, double power, spell * sp) unused(sp); u = create_unit(r, mage->faction, force, rc, 0, NULL, mage); - u->status = ST_FIGHT; + setstatus(u, ST_FIGHT); set_string(&u->name, racename(mage->faction->locale, u, u->race)); set_level(u, SK_WEAPONLESS, (int)(power/2)); @@ -767,7 +767,7 @@ sp_wolfhowl(fighter * fi, int level, double power, spell * sp) unit *u = create_unit(r, mage->faction, force, new_race[RC_WOLF], 0, NULL, mage); unused(sp); - u->status = ST_FIGHT; + setstatus(u, ST_FIGHT); set_string(&u->name, racename(mage->faction->locale, u, u->race)); set_level(u, SK_WEAPONLESS, (int)(power/3)); @@ -802,7 +802,7 @@ sp_shadowknights(fighter * fi, int level, double power, spell * sp) unused(sp); u = create_unit(r, mage->faction, force, new_race[RC_SHADOWKNIGHT], 0, NULL, mage); - u->status = ST_FIGHT; + setstatus(u, ST_FIGHT); set_string(&u->name, "Schattenritter"); u->hp = u->number * unit_max_hp(u); @@ -1683,7 +1683,7 @@ sp_undeadhero(fighter * fi, int level, double power, spell * sp) /* new units gets some stats from old unit */ set_string(&u->name, du->name); set_string(&u->display, du->display); - u->status = du->status; + setstatus(u, du->status); setguard(u, GUARD_NONE); /* inherit stealth from magician */ diff --git a/src/common/spells/spells.c b/src/common/spells/spells.c index 433776d12..575ef9d9d 100644 --- a/src/common/spells/spells.c +++ b/src/common/spells/spells.c @@ -575,7 +575,7 @@ sp_summon_familiar(castorder *co) familiar->building = mage->building; familiar->ship = mage->ship; } - familiar->status = ST_FLEE; /* flieht */ + setstatus(familiar, ST_FLEE); sprintf(buf, "Vertrauter von %s", unitname(mage)); set_string(&familiar->name, buf); if (fval(mage, UFL_PARTEITARNUNG)) fset(familiar, UFL_PARTEITARNUNG); @@ -2222,7 +2222,7 @@ sp_ironkeeper(castorder *co) /*keeper->age = cast_level + 2;*/ guard(keeper, GUARD_MINING); fset(keeper, UFL_ISNEW); - keeper->status = ST_AVOID; /* kaempft nicht */ + setstatus(keeper, ST_AVOID); /* kaempft nicht */ /* Parteitarnen, damit man nicht sofort weiß, wer dahinter steckt */ fset(keeper, UFL_PARTEITARNUNG); { @@ -5291,7 +5291,7 @@ sp_clonecopy(castorder *co) sprintf(buf, "Klon von %s", unitname(mage)); clone = create_unit(target_region, mage->faction, 1, new_race[RC_CLONE], 0, buf, mage); - clone->status = ST_FLEE; + setstatus(clone, ST_FLEE); fset(clone, UFL_LOCKED); create_newclone(mage, clone); diff --git a/src/res/messages.xml b/src/res/messages.xml index 8415ef8fa..3e8e493db 100644 --- a/src/res/messages.xml +++ b/src/res/messages.xml @@ -2803,6 +2803,17 @@ "$unit($unit) drowns when $ship($ship) in $region($region) sinks." + + + + + + + "$unit($unit) in $region($region): '$order($command)' - Die Einheit kann nicht bewachen, da sie veruscht zu fliehen." + "$unit($unit) in $region($region): '$order($command)' - The unit cannot guard the region because it's trying to flee." + "$unit($unit) in $region($region): '$order($command)' - The unit cannot guard the region because it's trying to flee." + +