SIMPLE_ESCAPE: Flucht verhindert BEWACHE.

This commit is contained in:
Enno Rehling 2007-02-12 07:27:04 +00:00
parent d46151998d
commit c61127ab6f
9 changed files with 130 additions and 83 deletions

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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->status<ST_FLEE);
#endif
if (fval(u, UFL_GUARD)) {
a = a_find(u->attribs, &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);

View File

@ -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 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 */
/* !< 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);

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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);

View File

@ -2803,6 +2803,17 @@
<text locale="en">"$unit($unit) drowns when $ship($ship) in $region($region) sinks."</text>
</message>
<message name="error320" section="errors">
<type>
<arg name="unit" type="unit"/>
<arg name="region" type="region"/>
<arg name="command" type="order"/>
</type>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Die Einheit kann nicht bewachen, da sie veruscht zu fliehen."</text>
<text locale="fr">"$unit($unit) in $region($region): '$order($command)' - The unit cannot guard the region because it's trying to flee."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - The unit cannot guard the region because it's trying to flee."</text>
</message>
<message name="error319" section="errors">
<type>
<arg name="unit" type="unit"/>