SORTIERE VOR eine pausierte Einheit

Automatische Kommandoübergabe inklusive.
This commit is contained in:
Enno Rehling 2021-06-06 17:52:34 +02:00
parent 062e5ff7ae
commit 4a7580e8eb
2 changed files with 115 additions and 12 deletions

View File

@ -13,6 +13,17 @@
#include "util/param.h" #include "util/param.h"
#include "util/parser.h" #include "util/parser.h"
void sort_before(unit *v, unit **up) {
unit *u = *up;
region *r = u->region;
unit **vp = &r->units;
while (*vp != v)
vp = &(*vp)->next;
*vp = u;
*up = u->next;
u->next = v;
}
void restack_units(void) void restack_units(void)
{ {
region *r; region *r;
@ -37,7 +48,13 @@ void restack_units(void)
id = getid(); id = getid();
v = findunit(id); v = findunit(id);
if (!v || v->faction != u->faction || v->region != r) { if (v == u) {
syntax_error(u, ord);
}
else if (!v || v->region != r) {
cmistake(u, ord, 258, MSG_EVENT);
}
else if (v->faction != u->faction && !is_paused(v->faction)) {
cmistake(u, ord, 258, MSG_EVENT); cmistake(u, ord, 258, MSG_EVENT);
} }
else if (v->building != u->building || v->ship != u->ship) { else if (v->building != u->building || v->ship != u->ship) {
@ -49,9 +66,6 @@ void restack_units(void)
else if (u->ship && ship_owner(u->ship) == u) { else if (u->ship && ship_owner(u->ship) == u) {
cmistake(u, ord, 260, MSG_EVENT); cmistake(u, ord, 260, MSG_EVENT);
} }
else if (v == u) {
syntax_error(u, ord);
}
else { else {
switch (p) { switch (p) {
case P_AFTER: case P_AFTER:
@ -63,18 +77,27 @@ void restack_units(void)
break; break;
case P_BEFORE: case P_BEFORE:
if (v->ship && ship_owner(v->ship) == v) { if (v->ship && ship_owner(v->ship) == v) {
cmistake(v, ord, 261, MSG_EVENT); if (is_paused(v->faction)) {
sort_before(v, up);
ship_set_owner(u);
}
else {
cmistake(v, ord, 261, MSG_EVENT);
break;
}
} }
else if (v->building && building_owner(v->building) == v) { else if (v->building && building_owner(v->building) == v) {
cmistake(v, ord, 261, MSG_EVENT); if (is_paused(v->faction)) {
sort_before(v, up);
building_set_owner(u);
}
else {
cmistake(v, ord, 261, MSG_EVENT);
break;
}
} }
else { else {
unit **vp = &r->units; sort_before(v, up);
while (*vp != v)
vp = &(*vp)->next;
*vp = u;
*up = u->next;
u->next = v;
} }
fset(u, UFL_MARK); fset(u, UFL_MARK);
sorted = true; sorted = true;

View File

@ -123,6 +123,84 @@ static void test_sort_before_owner(CuTest *tc) {
test_teardown(); test_teardown();
} }
static void test_sort_before_paused_building_owner(CuTest *tc) {
unit *u1, *u2;
faction *f;
region *r;
building *b;
test_setup();
u1 = test_create_unit(f = test_create_faction(), r = test_create_plain(0, 0));
f->flags |= FFL_PAUSED;
b = test_create_building(r, NULL);
u2 = test_create_unit(f = test_create_faction(), r);
unit_addorder(u2, create_order(K_SORT, f->locale, "%s %s",
LOC(f->locale, parameters[P_BEFORE]), itoa36(u1->no)));
u1->building = b;
building_update_owner(b);
CuAssertPtrEquals(tc, u1, r->units);
CuAssertPtrEquals(tc, u2, u1->next);
CuAssertPtrEquals(tc, NULL, u2->next);
/* not in building, nothing happend: */
restack_units();
CuAssertPtrEquals(tc, u1, r->units);
CuAssertPtrEquals(tc, u2, u1->next);
CuAssertPtrEquals(tc, NULL, u2->next);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error259"));
test_clear_messagelist(&f->msgs);
/* u1 allows u2 to steal the top spot: */
u2->building = b;
restack_units();
CuAssertPtrEquals(tc, u2, r->units);
CuAssertPtrEquals(tc, u1, u2->next);
CuAssertPtrEquals(tc, NULL, u1->next);
CuAssertPtrEquals(tc, u2, building_owner(b));
CuAssertPtrEquals(tc, NULL, f->msgs);
test_teardown();
}
static void test_sort_before_paused_ship_owner(CuTest *tc) {
unit *u1, *u2;
faction *f;
region *r;
ship *sh;
test_setup();
u1 = test_create_unit(f = test_create_faction(), r = test_create_plain(0, 0));
f->flags |= FFL_PAUSED;
sh = test_create_ship(r, NULL);
u2 = test_create_unit(f = test_create_faction(), r);
unit_addorder(u2, create_order(K_SORT, f->locale, "%s %s",
LOC(f->locale, parameters[P_BEFORE]), itoa36(u1->no)));
u1->ship = sh;
ship_update_owner(sh);
CuAssertPtrEquals(tc, u1, r->units);
CuAssertPtrEquals(tc, u2, u1->next);
CuAssertPtrEquals(tc, NULL, u2->next);
/* not in ship, nothing happend: */
restack_units();
CuAssertPtrEquals(tc, u1, r->units);
CuAssertPtrEquals(tc, u2, u1->next);
CuAssertPtrEquals(tc, NULL, u2->next);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error259"));
test_clear_messagelist(&f->msgs);
/* u1 allows u2 to steal the top spot: */
u2->ship = sh;
restack_units();
CuAssertPtrEquals(tc, u2, r->units);
CuAssertPtrEquals(tc, u1, u2->next);
CuAssertPtrEquals(tc, NULL, u1->next);
CuAssertPtrEquals(tc, u2, ship_owner(sh));
CuAssertPtrEquals(tc, NULL, f->msgs);
test_teardown();
}
static void test_sort_paused(CuTest *tc) { static void test_sort_paused(CuTest *tc) {
unit *u1, *u2; unit *u1, *u2;
faction *f; faction *f;
@ -152,6 +230,8 @@ CuSuite *get_sort_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_sort_before_owner); SUITE_ADD_TEST(suite, test_sort_before_owner);
SUITE_ADD_TEST(suite, test_sort_before_paused_ship_owner);
SUITE_ADD_TEST(suite, test_sort_before_paused_building_owner);
SUITE_ADD_TEST(suite, test_sort_after); SUITE_ADD_TEST(suite, test_sort_after);
SUITE_ADD_TEST(suite, test_sort_before); SUITE_ADD_TEST(suite, test_sort_before);
SUITE_ADD_TEST(suite, test_sort_paused); SUITE_ADD_TEST(suite, test_sort_paused);