BUG 0001980: Gegener hält Burg obwohl alle geflohen sind!

http://bugs.eressea.de/view.php?id=1980
Der Test unten erzeugt eine Temp-Einheit welche nach dem Kampf die Burg hält, trotz einer vernichtenden Niederlage innerhalb von 2 Kampfrunden. Der Angreifer darf die Burg zwar betreten, bekommt aber nicht das Kommando.
Grund ist das beim Betreten der Burg via u_set_building() nur dann die betretende Einheit zum Burgenbesitzer wird wenn es keinen Burgenbesitzer gibt.
Die eher aufgerufene Funktion building_owner() versucht zwar nach dem Kampf einen neuen Burgenbesitzer zu finden, da sich zu diesem Zeitpunkt aber nur eine Tote Einheit und einen Temp Einheit, beide mit 0 Personen, in der Bug befinden schlägt dies Fehl. Es wird von der Funktion zwar 0 zurückgegeben, aber b->_owner wird nicht zurückgesetzt (Vermutlich da der Server an anderer Stelle sonst annimmt das noch nie jemand in der Burg war). Daher die Überprüfung bei u_set_building ob der Burgenbesitzer tot ist, und wenn ja wird die betretende Einheit neuer Burgenbesitzer.

local r1 = region.create(1, 2, "plain")
local f1 = faction.create("a@b.de", "human", "de")
local f2 = faction.create("c@d.de", "human", "de")
f1.age=20
f2.age=20

local b1 = building.create(r1, "castle")
b1.size = 100

local u0 = unit.create(f1, r1, 10)
u0.building = b1
u0:add_item("money", u0.number * 100)
u0:clear_orders()
u0:add_order("KÄMPFE")
u0:add_order("MACHE TEMP 1")
u0:add_order("ENDE")

local u1 = unit.create(f1, r1, 100)
u1.building = b1
u1:add_item("money", u1.number * 100)
u1:clear_orders()
u1:add_order("KÄMPFE FLIEHE")
u1:add_order("GIB TEMP 1 ALLES PERSONEN")
u1:add_order("GIB TEMP 1 ALLES")
u1:add_order("GIB TEMP 1 Kommando")

local u2 = unit.create(f2, r1, 101)
u2:add_item("sword", u2.number)
u2:add_item("money", u2.number * 100)
u2:set_skill("melee", 16)
u2:clear_orders()
u2:add_order("KÄMPFE")
u2:add_order("ATTACKIEREN " .. itoa36(u1.id))
u2:add_order("BETRETE BURG " .. itoa36(b1.id))

process_orders()


Das sollte für Schiffe eigentlich das gleiche sein, also da die gleiche Änderung.
This commit is contained in:
CTD1 2014-07-15 15:24:21 +02:00
parent 2253296924
commit 38a754844e
1 changed files with 15 additions and 15 deletions

View File

@ -69,7 +69,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
attrib_type at_creator = { attrib_type at_creator = {
"creator" "creator"
/* Rest ist NULL; temporäres, nicht alterndes Attribut */ /* Rest ist NULL; tempor<EFBFBD>res, nicht alterndes Attribut */
}; };
#define UMAXHASH MAXUNITS #define UMAXHASH MAXUNITS
@ -619,7 +619,7 @@ void usetcontact(unit * u, const unit * u2)
} }
bool ucontact(const unit * u, const unit * u2) bool ucontact(const unit * u, const unit * u2)
/* Prüft, ob u den Kontaktiere-Befehl zu u2 gesetzt hat. */ /* Pr<EFBFBD>ft, ob u den Kontaktiere-Befehl zu u2 gesetzt hat. */
{ {
attrib *ru; attrib *ru;
if (u->faction == u2->faction) if (u->faction == u2->faction)
@ -776,7 +776,7 @@ ship *leftship(const unit * u)
{ {
attrib *a = a_find(u->attribs, &at_leftship); attrib *a = a_find(u->attribs, &at_leftship);
/* Achtung: Es ist nicht garantiert, daß der Rückgabewert zu jedem /* Achtung: Es ist nicht garantiert, da<EFBFBD> der R<>ckgabewert zu jedem
* Zeitpunkt noch auf ein existierendes Schiff zeigt! */ * Zeitpunkt noch auf ein existierendes Schiff zeigt! */
if (a) if (a)
@ -789,7 +789,7 @@ void u_set_building(unit * u, building * b)
{ {
assert(!u->building); /* you must leave first */ assert(!u->building); /* you must leave first */
u->building = b; u->building = b;
if (b && !b->_owner) { if (b && (!b->_owner || b->_owner->number <= 0)) {
building_set_owner(u); building_set_owner(u);
} }
} }
@ -798,7 +798,7 @@ void u_set_ship(unit * u, ship * sh)
{ {
assert(!u->ship); /* you must leave_ship */ assert(!u->ship); /* you must leave_ship */
u->ship = sh; u->ship = sh;
if (sh && !sh->_owner) { if (sh && !sh->_owner || sh->_owner->number <= 0) {
ship_set_owner(u); ship_set_owner(u);
} }
} }
@ -930,7 +930,7 @@ void transfermen(unit * u, unit * u2, int n)
if (n == 0) if (n == 0)
return; return;
assert(n > 0); assert(n > 0);
/* "hat attackiert"-status wird übergeben */ /* "hat attackiert"-status wird <EFBFBD>bergeben */
if (u2) { if (u2) {
skill *sv, *sn; skill *sv, *sn;
@ -1016,7 +1016,7 @@ void transfermen(unit * u, unit * u2, int n)
set_number(u2, u2->number + n); set_number(u2, u2->number + n);
hp -= u->hp; hp -= u->hp;
u2->hp += hp; u2->hp += hp;
/* TODO: Das ist schnarchlahm! und gehört nicht hierhin */ /* TODO: Das ist schnarchlahm! und geh<EFBFBD>rt nicht hierhin */
a = a_find(u2->attribs, &at_effect); a = a_find(u2->attribs, &at_effect);
while (a && a->type == &at_effect) { while (a && a->type == &at_effect) {
attrib *an = a->next; attrib *an = a->next;
@ -1050,7 +1050,7 @@ struct building *inside_building(const struct unit *u)
/* Unterhalt nicht bezahlt */ /* Unterhalt nicht bezahlt */
return NULL; return NULL;
} else if (u->building->size < u->building->type->maxsize) { } else if (u->building->size < u->building->type->maxsize) {
/* Gebäude noch nicht fertig */ /* Geb<EFBFBD>ude noch nicht fertig */
return NULL; return NULL;
} else { } else {
int p = 0, cap = buildingcapacity(u->building); int p = 0, cap = buildingcapacity(u->building);
@ -1118,7 +1118,7 @@ void u_setfaction(unit * u, faction * f)
} }
} }
/* vorsicht Sprüche können u->number == RS_FARVISION haben! */ /* vorsicht Spr<EFBFBD>che k<>nnen u->number == RS_FARVISION haben! */
void set_number(unit * u, int count) void set_number(unit * u, int count)
{ {
assert(count >= 0); assert(count >= 0);
@ -1268,8 +1268,8 @@ static int att_modification(const unit * u, skill_t sk)
} }
/* TODO hier kann nicht mit get/iscursed gearbeitet werden, da nur der /* TODO hier kann nicht mit get/iscursed gearbeitet werden, da nur der
* jeweils erste vom Typ C_GBDREAM zurückgegen wird, wir aber alle * jeweils erste vom Typ C_GBDREAM zur<EFBFBD>ckgegen wird, wir aber alle
* durchsuchen und aufaddieren müssen */ * durchsuchen und aufaddieren m<EFBFBD>ssen */
if (u->region) { if (u->region) {
double bonus = 0, malus = 0; double bonus = 0, malus = 0;
attrib *a = a_find(u->region->attribs, &at_curse); attrib *a = a_find(u->region->attribs, &at_curse);
@ -1278,7 +1278,7 @@ static int att_modification(const unit * u, skill_t sk)
if (curse_active(c) && c->type == gbdream_ct) { if (curse_active(c) && c->type == gbdream_ct) {
double mod = curse_geteffect(c); double mod = curse_geteffect(c);
unit *mage = c->magician; unit *mage = c->magician;
/* wir suchen jeweils den größten Bonus und den größten Malus */ /* wir suchen jeweils den gr<EFBFBD><EFBFBD>ten Bonus und den gr<67><72>ten Malus */
if (mod > bonus) { if (mod > bonus) {
if (mage == NULL || mage->number == 0 if (mage == NULL || mage->number == 0
|| alliedunit(mage, u->faction, HELP_GUARD)) { || alliedunit(mage, u->faction, HELP_GUARD)) {
@ -1489,7 +1489,7 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace,
if (r) if (r)
move_unit(u, r, NULL); move_unit(u, r, NULL);
/* u->race muss bereits gesetzt sein, wird für default-hp gebraucht */ /* u->race muss bereits gesetzt sein, wird f<EFBFBD>r default-hp gebraucht */
/* u->region auch */ /* u->region auch */
u->hp = unit_max_hp(u) * number; u->hp = unit_max_hp(u) * number;
@ -1505,7 +1505,7 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace,
/* erbt Kampfstatus */ /* erbt Kampfstatus */
setstatus(u, creator->status); setstatus(u, creator->status);
/* erbt Gebäude/Schiff */ /* erbt Geb<EFBFBD>ude/Schiff */
if (creator->region == r) { if (creator->region == r) {
if (creator->building) { if (creator->building) {
u_set_building(u, creator->building); u_set_building(u, creator->building);
@ -1686,7 +1686,7 @@ int unit_max_hp(const unit * u)
p = pow(effskill(u, SK_STAMINA) / 2.0, 1.5) * 0.2; p = pow(effskill(u, SK_STAMINA) / 2.0, 1.5) * 0.2;
h += (int)(h * p + 0.5); h += (int)(h * p + 0.5);
} }
/* der healing curse verändert die maximalen hp */ /* der healing curse ver<EFBFBD>ndert die maximalen hp */
if (heal_ct) { if (heal_ct) {
curse *c = get_curse(u->region->attribs, heal_ct); curse *c = get_curse(u->region->attribs, heal_ct);
if (c) { if (c) {