BUG 2209: Monster, die attackieren, sollen sich in der selben Runde nicht auch noch bewegen.

This commit is contained in:
Enno Rehling 2018-10-14 11:47:59 +02:00
parent 7b682c6a74
commit 0cc8adeeef
2 changed files with 31 additions and 26 deletions

View file

@ -56,7 +56,6 @@
#include <util/base36.h> #include <util/base36.h>
#include "util/keyword.h" #include "util/keyword.h"
#include "util/language.h" #include "util/language.h"
#include <util/lists.h>
#include <util/log.h> #include <util/log.h>
#include <util/rand.h> #include <util/rand.h>
#include <util/rng.h> #include <util/rng.h>
@ -203,6 +202,7 @@ void monsters_desert(struct faction *monsters)
int monster_attacks(unit * monster, bool rich_only) int monster_attacks(unit * monster, bool rich_only)
{ {
const race *rc_serpent = get_race(RC_SEASERPENT); const race *rc_serpent = get_race(RC_SEASERPENT);
int result = -1;
if (monster->status < ST_AVOID) { if (monster->status < ST_AVOID) {
region *r = monster->region; region *r = monster->region;
unit *u2; unit *u2;
@ -220,15 +220,16 @@ int monster_attacks(unit * monster, bool rich_only)
if (!rich_only || m > 0) { if (!rich_only || m > 0) {
order *ord = monster_attack(monster, u2); order *ord = monster_attack(monster, u2);
if (ord) { if (ord) {
addlist(&monster->orders, ord); result = 0;
unit_addorder(monster, ord);
money += m; money += m;
} }
} }
} }
} }
return money; return money > 0 ? money : result;
} }
return 0; return result;
} }
static order *get_money_for_dragon(region * r, unit * udragon, int wanted) static order *get_money_for_dragon(region * r, unit * udragon, int wanted)
@ -249,7 +250,8 @@ static order *get_money_for_dragon(region * r, unit * udragon, int wanted)
* und holt sich Silber von Einheiten, vorausgesetzt er bewacht bereits */ * und holt sich Silber von Einheiten, vorausgesetzt er bewacht bereits */
money = 0; money = 0;
if (attacks && is_guard(udragon)) { if (attacks && is_guard(udragon)) {
money += monster_attacks(udragon, true); int m = monster_attacks(udragon, true);
if (m > 0) money += m;
} }
/* falls die einnahmen erreicht werden, bleibt das monster noch eine */ /* falls die einnahmen erreicht werden, bleibt das monster noch eine */
@ -737,19 +739,12 @@ void plan_monsters(faction * f)
for (r = regions; r; r = r->next) { for (r = regions; r; r = r->next) {
unit *u; unit *u;
bool attacking = false;
/* Tiny optimization: Monsters on land only attack randomly when
* they are guarding. If nobody is guarding this region (RF_GUARDED),
* there can't be any random attacks.
*/
if (!r->land || r->flags & RF_GUARDED) {
attacking = chance(attack_chance);
}
for (u = r->units; u; u = u->next) { for (u = r->units; u; u = u->next) {
const race *rc = u_race(u); const race *rc = u_race(u);
attrib *ta; attrib *ta;
order *long_order = NULL; order *long_order = NULL;
bool can_move = true;
/* Ab hier nur noch Befehle f<>r NPC-Einheiten. */ /* Ab hier nur noch Befehle f<>r NPC-Einheiten. */
if (u->faction!=f) if (u->faction!=f)
@ -760,16 +755,19 @@ void plan_monsters(faction * f)
u->flags &= ~UFL_ANON_FACTION; u->flags &= ~UFL_ANON_FACTION;
} }
/* Befehle m<>ssen jede Runde neu gegeben werden: */
free_orders(&u->orders);
if (skill_enabled(SK_PERCEPTION)) { if (skill_enabled(SK_PERCEPTION)) {
/* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */ /* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */
produceexp(u, SK_PERCEPTION, u->number); produceexp(u, SK_PERCEPTION, u->number);
} }
if (attacking && (!r->land || is_guard(u))) { /* Befehle m<>ssen jede Runde neu gegeben werden: */
monster_attacks(u, false); free_orders(&u->orders);
/* All monsters guard the region: */
if (u->status < ST_FLEE && !monster_is_waiting(u) && r->land) {
unit_addorder(u, create_order(K_GUARD, u->faction->locale, NULL));
} }
/* units with a plan to kill get ATTACK orders (even if they don't guard): */ /* units with a plan to kill get ATTACK orders (even if they don't guard): */
ta = a_find(u->attribs, &at_hate); ta = a_find(u->attribs, &at_hate);
if (ta && !monster_is_waiting(u)) { if (ta && !monster_is_waiting(u)) {
@ -777,7 +775,8 @@ void plan_monsters(faction * f)
if (tu && tu->region == r) { if (tu && tu->region == r) {
order * ord = monster_attack(u, tu); order * ord = monster_attack(u, tu);
if (ord) { if (ord) {
addlist(&u->orders, ord); unit_addorder(u, ord);
can_move = false;
} }
} }
else if (tu) { else if (tu) {
@ -786,17 +785,22 @@ void plan_monsters(faction * f)
allowed = allowed_fly; allowed = allowed_fly;
} }
long_order = plan_move_to_target(u, tu->region, 2, allowed); long_order = plan_move_to_target(u, tu->region, 2, allowed);
can_move = false;
} }
else else
a_remove(&u->attribs, ta); a_remove(&u->attribs, ta);
} }
/* All monsters guard the region: */ else if (!r->land || is_guard(u)) {
if (u->status < ST_FLEE && !monster_is_waiting(u) && r->land) { if (chance(attack_chance)) {
addlist(&u->orders, create_order(K_GUARD, u->faction->locale, NULL)); int m = monster_attacks(u, false);
if (m >= 0) {
can_move = false;
}
}
} }
/* Einheiten mit Bewegungsplan kriegen ein NACH: */ /* Einheiten mit Bewegungsplan kriegen ein NACH: */
if (long_order == NULL) { if (can_move && long_order == NULL) {
ta = a_find(u->attribs, &at_targetregion); ta = a_find(u->attribs, &at_targetregion);
if (ta) { if (ta) {
if (u->region == (region *)ta->data.v) { if (u->region == (region *)ta->data.v) {
@ -817,7 +821,7 @@ void plan_monsters(faction * f)
long_order = plan_dragon(u); long_order = plan_dragon(u);
} }
else { else {
if (rc == get_race(RC_SEASERPENT)) { if (can_move && rc == get_race(RC_SEASERPENT)) {
long_order = create_order(K_PIRACY, f->locale, NULL); long_order = create_order(K_PIRACY, f->locale, NULL);
} }
else { else {
@ -827,6 +831,7 @@ void plan_monsters(faction * f)
} }
} }
} }
if (long_order == NULL && unit_can_study(u)) { if (long_order == NULL && unit_can_study(u)) {
/* Einheiten, die Waffenlosen Kampf lernen k<>nnten, lernen es um /* Einheiten, die Waffenlosen Kampf lernen k<>nnten, lernen es um
* zu bewachen: */ * zu bewachen: */
@ -840,7 +845,7 @@ void plan_monsters(faction * f)
} }
if (long_order) { if (long_order) {
addlist(&u->orders, long_order); unit_addorder(u, long_order);
} }
} }
} }

View file

@ -123,7 +123,7 @@ static void test_monsters_waiting(CuTest * tc)
setguard(m, true); setguard(m, true);
fset(m, UFL_ISNEW); fset(m, UFL_ISNEW);
monster_attacks(m, false); monster_attacks(m, false);
CuAssertPtrEquals(tc, 0, find_order("attack 1", m)); CuAssertPtrEquals(tc, NULL, find_order("attack 1", m));
test_teardown(); test_teardown();
} }
@ -173,7 +173,7 @@ static void test_monsters_attack_not(CuTest * tc)
plan_monsters(m->faction); plan_monsters(m->faction);
CuAssertPtrEquals(tc, 0, find_order("attack 1", m)); CuAssertPtrEquals(tc, NULL, find_order("attack 1", m));
test_teardown(); test_teardown();
} }