VERTREIBE Kommando (expel).

Braucht noch Fehlermeldungen.
This commit is contained in:
Enno Rehling 2021-06-10 22:21:15 +02:00
parent d35181b5d6
commit 1711812b0b
11 changed files with 220 additions and 93 deletions

View File

@ -1,11 +1,11 @@
{ {
"keywords": { "keywords": {
"en" : { "en" : {
"plant": "PLANT", "plant": "PLANT",
"grow": [ "GROW", "BREED" ], "grow": [ "GROW", "BREED" ],
"promote": ["PROMOTE", "PROMOTION" ], "promote": ["PROMOTE", "PROMOTION" ],
"locale": ["LANGUAGE", "LOCALE"], "locale": ["LANGUAGE", "LOCALE"],
"combat": [ "COMBAT", "FIGHT" ] "combat": [ "COMBAT", "FIGHT" ]
}, },
"de": { "de": {
"//" : "//", "//" : "//",
@ -36,6 +36,7 @@
"maketemp": ["MACHE TEMP", "MACHETEMP"], "maketemp": ["MACHE TEMP", "MACHETEMP"],
"move" : "NACH", "move" : "NACH",
"password" : "PASSWORT", "password" : "PASSWORT",
"expel" : "VERTREIBE",
"loot" : ["PLÜNDERE", "PLÜNDERN"], "loot" : ["PLÜNDERE", "PLÜNDERN"],
"recruit": ["REKRUTIERE", "REKRUTIEREN"], "recruit": ["REKRUTIERE", "REKRUTIEREN"],
"reserve": ["RESERVIERE", "RESERVIEREN"], "reserve": ["RESERVIERE", "RESERVIEREN"],

View File

@ -2496,6 +2496,10 @@ msgctxt "keyword"
msgid "loot" msgid "loot"
msgstr "PLÜNDERE" msgstr "PLÜNDERE"
msgctxt "keyword"
msgid "expel"
msgstr "VERTREIBE"
msgctxt "calendar" msgctxt "calendar"
msgid "month_1" msgid "month_1"
msgstr "Feldsegen" msgstr "Feldsegen"

View File

@ -2167,6 +2167,10 @@ msgctxt "keyword"
msgid "loot" msgid "loot"
msgstr "loot" msgstr "loot"
msgctxt "keyword"
msgid "expel"
msgstr "EXPEL"
msgctxt "keyword" msgctxt "keyword"
msgid "guard" msgid "guard"
msgstr "GUARD" msgstr "GUARD"

View File

@ -3939,11 +3939,12 @@ void init_processor(void)
add_proc_global(p, defaultorders, "Defaults setzen"); add_proc_global(p, defaultorders, "Defaults setzen");
} }
add_proc_global(p, demographics, "Nahrung, Seuchen, Wachstum, Wanderung"); add_proc_global(p, demographics, "Nahrung, Seuchen, Wachstum, Wanderung");
p += 10;
if (!keyword_disabled(K_SORT)) { if (!keyword_disabled(K_SORT)) {
p += 10; add_proc_region(p, do_sort, "Einheiten sortieren");
add_proc_global(p, restack_units, "Einheiten sortieren");
} }
add_proc_order(p, K_EXPEL, expel_cmd, 0, "Einheiten verjagen");
if (!keyword_disabled(K_NUMBER)) { if (!keyword_disabled(K_NUMBER)) {
add_proc_order(p, K_NUMBER, renumber_cmd, 0, "Neue Nummern (Einheiten)"); add_proc_order(p, K_NUMBER, renumber_cmd, 0, "Neue Nummern (Einheiten)");
p += 10; p += 10;
@ -4187,3 +4188,54 @@ int locale_cmd(unit * u, order * ord)
} }
return 0; return 0;
} }
static void expel_building(unit *u, unit *u2, order *ord) {
building *b = u->building;
if (u != building_owner(b)) {
/* error: must be the owner */
cmistake(u, ord, 5, MSG_EVENT);
}
else {
leave_building(u2);
}
}
static void expel_ship(unit *u, unit *u2, order *ord) {
ship *sh = u->ship;
if (u != ship_owner(sh)) {
/* error: must be the owner */
cmistake(u, ord, 146, MSG_EVENT);
}
else if (!u->region->land) {
/* error: must not be at sea */
ADDMSG(&u->faction->msgs,
msg_feedback(u, ord, "error_onlandonly", NULL));
}
else {
leave_ship(u2);
}
}
int expel_cmd(unit *u, order *ord) {
faction *f = u->faction;
unit *u2;
init_order(ord, f->locale);
getunit(u->region, u->faction, &u2);
if (u2 == NULL) {
/* error: target unit not found */
ADDMSG(&u->faction->msgs,
msg_feedback(u, ord, "feedback_unit_not_found", NULL));
return 0;
}
if (u->building) {
expel_building(u, u2, ord);
}
else if (u->ship) {
expel_ship(u, u2, ord);
}
else {
/* error: unit must be owner of a ship or building */
}
return 0;
}

View File

@ -50,6 +50,7 @@ extern "C" {
bool long_order_allowed(const struct unit *u, bool flags_only); bool long_order_allowed(const struct unit *u, bool flags_only);
bool password_wellformed(const char *password); bool password_wellformed(const char *password);
int expel_cmd(struct unit *u, struct order *ord);
int locale_cmd(struct unit *u, struct order *ord); int locale_cmd(struct unit *u, struct order *ord);
int password_cmd(struct unit *u, struct order *ord); int password_cmd(struct unit *u, struct order *ord);
int banner_cmd(struct unit *u, struct order *ord); int banner_cmd(struct unit *u, struct order *ord);

View File

@ -173,6 +173,59 @@ static void test_enter_ship(CuTest * tc)
test_teardown(); test_teardown();
} }
static void test_expel_building(CuTest *tc) {
unit *u1, *u2;
order *ord;
building *b;
test_setup();
u1 = test_create_unit(test_create_faction(), test_create_plain(0, 0));
u2 = test_create_unit(test_create_faction(), u1->region);
b = u2->building = u1->building = test_create_building(u1->region, NULL);
CuAssertPtrEquals(tc, u1, building_owner(b));
ord = create_order(K_EXPEL, u2->faction->locale, "%s", itoa36(u1->no));
expel_cmd(u2, ord);
/* Nothing happened: */
CuAssertPtrEquals(tc, u1, building_owner(b));
CuAssertPtrEquals(tc, b, u1->building);
CuAssertPtrEquals(tc, b, u2->building);
free_order(ord);
ord = create_order(K_EXPEL, u1->faction->locale, "%s", itoa36(u2->no));
expel_cmd(u1, ord);
/* owner has expelled u2: */
CuAssertPtrEquals(tc, NULL, u2->building);
test_teardown();
}
static void test_expel_ship(CuTest *tc) {
unit *u1, *u2;
order *ord;
ship *sh;
test_setup();
u1 = test_create_unit(test_create_faction(), test_create_plain(0, 0));
u2 = test_create_unit(test_create_faction(), u1->region);
sh = u2->ship = u1->ship = test_create_ship(u1->region, NULL);
CuAssertPtrEquals(tc, u1, ship_owner(sh));
ord = create_order(K_EXPEL, u2->faction->locale, "%s", itoa36(u1->no));
expel_cmd(u2, ord);
/* Nothing happened: */
CuAssertPtrEquals(tc, u1, ship_owner(sh));
CuAssertPtrEquals(tc, sh, u1->ship);
CuAssertPtrEquals(tc, sh, u2->ship);
free_order(ord);
ord = create_order(K_EXPEL, u1->faction->locale, "%s", itoa36(u2->no));
expel_cmd(u1, ord);
/* owner has expelled u2: */
CuAssertPtrEquals(tc, NULL, u2->ship);
CuAssertPtrEquals(tc, sh, leftship(u2));
test_teardown();
}
static void test_display_cmd(CuTest *tc) { static void test_display_cmd(CuTest *tc) {
unit *u; unit *u;
faction *f; faction *f;
@ -2320,6 +2373,8 @@ CuSuite *get_laws_suite(void)
SUITE_ADD_TEST(suite, test_enter_building); SUITE_ADD_TEST(suite, test_enter_building);
SUITE_ADD_TEST(suite, test_enter_ship); SUITE_ADD_TEST(suite, test_enter_ship);
SUITE_ADD_TEST(suite, test_display_cmd); SUITE_ADD_TEST(suite, test_display_cmd);
SUITE_ADD_TEST(suite, test_expel_building);
SUITE_ADD_TEST(suite, test_expel_ship);
SUITE_ADD_TEST(suite, test_rule_force_leave); SUITE_ADD_TEST(suite, test_rule_force_leave);
SUITE_ADD_TEST(suite, test_force_leave_buildings); SUITE_ADD_TEST(suite, test_force_leave_buildings);
SUITE_ADD_TEST(suite, test_force_leave_ships); SUITE_ADD_TEST(suite, test_force_leave_ships);

View File

@ -13,7 +13,7 @@
#include "util/param.h" #include "util/param.h"
#include "util/parser.h" #include "util/parser.h"
void sort_before(unit *v, unit **up) { static void sort_before(unit *v, unit **up) {
unit *u = *up; unit *u = *up;
region *r = u->region; region *r = u->region;
unit **vp = &r->units; unit **vp = &r->units;
@ -24,102 +24,107 @@ void sort_before(unit *v, unit **up) {
u->next = v; u->next = v;
} }
void restack_units(void) void do_sort(region *r)
{ {
region *r; unit **up = &r->units;
for (r = regions; r; r = r->next) { bool sorted = false;
unit **up = &r->units; while (*up) {
bool sorted = false; unit *u = *up;
while (*up) { if (!fval(u, UFL_MARK) && !is_paused(u->faction)) {
unit *u = *up; struct order *ord;
if (!fval(u, UFL_MARK) && !is_paused(u->faction)) { for (ord = u->orders; ord; ord = ord->next) {
struct order *ord; if (getkeyword(ord) == K_SORT) {
for (ord = u->orders; ord; ord = ord->next) { char token[128];
if (getkeyword(ord) == K_SORT) { const char *s;
char token[128]; param_t p;
const char *s; int id;
param_t p; unit *v;
int id;
unit *v;
init_order(ord, NULL); init_order(ord, NULL);
s = gettoken(token, sizeof(token)); s = gettoken(token, sizeof(token));
p = findparam(s, u->faction->locale); p = findparam(s, u->faction->locale);
id = getid(); id = getid();
v = findunit(id); v = findunit(id);
if (v == u) { if (v == u) {
syntax_error(u, ord); syntax_error(u, ord);
} }
else if (!v || v->region != r) { else if (!v || v->region != r) {
cmistake(u, ord, 258, MSG_EVENT); cmistake(u, ord, 258, MSG_EVENT);
} }
else if (v->faction != u->faction && !is_paused(v->faction)) { 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) {
cmistake(u, ord, 259, MSG_EVENT); cmistake(u, ord, 259, MSG_EVENT);
} }
else if (u->building && building_owner(u->building) == u) { else if (u->building && building_owner(u->building) == u) {
cmistake(u, ord, 260, MSG_EVENT); cmistake(u, ord, 260, MSG_EVENT);
} }
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 { else {
switch (p) { switch (p) {
case P_AFTER: case P_AFTER:
*up = u->next; *up = u->next;
u->next = v->next; u->next = v->next;
v->next = u; v->next = u;
fset(u, UFL_MARK); fset(u, UFL_MARK);
sorted = true; sorted = true;
break; break;
case P_BEFORE: case P_BEFORE:
if (v->ship && ship_owner(v->ship) == v) { if (v->ship && ship_owner(v->ship) == v) {
if (is_paused(v->faction)) { if (is_paused(v->faction)) {
sort_before(v, up); sort_before(v, up);
ship_set_owner(u); ship_set_owner(u);
}
else {
cmistake(v, ord, 261, MSG_EVENT);
break;
}
}
else if (v->building && building_owner(v->building) == v) {
if (is_paused(v->faction)) {
sort_before(v, up);
building_set_owner(u);
}
else {
cmistake(v, ord, 261, MSG_EVENT);
break;
}
} }
else { else {
sort_before(v, up); cmistake(v, ord, 261, MSG_EVENT);
break;
} }
fset(u, UFL_MARK);
sorted = true;
break;
default:
/* TODO: syntax error message? */
break;
} }
else if (v->building && building_owner(v->building) == v) {
if (is_paused(v->faction)) {
sort_before(v, up);
building_set_owner(u);
}
else {
cmistake(v, ord, 261, MSG_EVENT);
break;
}
}
else {
sort_before(v, up);
}
fset(u, UFL_MARK);
sorted = true;
break;
default:
/* TODO: syntax error message? */
break;
} }
break;
} }
break;
} }
} }
if (u == *up)
up = &u->next;
} }
if (sorted) { if (u == *up)
unit *u; up = &u->next;
for (u = r->units; u; u = u->next) { }
freset(u, UFL_MARK); if (sorted) {
} unit *u;
for (u = r->units; u; u = u->next) {
freset(u, UFL_MARK);
} }
} }
} }
void restack_units(void)
{
region *r;
for (r = regions; r; r = r->next) {
do_sort(r);
}
}

View File

@ -1,3 +1,6 @@
#pragma once #pragma once
struct region;
void restack_units(void); void restack_units(void);
void do_sort(struct region *r);

View File

@ -119,7 +119,7 @@ int spy_cmd(unit * u, struct order *ord)
if (!target) { if (!target) {
ADDMSG(&u->faction->msgs, ADDMSG(&u->faction->msgs,
msg_feedback(u, u->thisorder, "feedback_unit_not_found", "")); msg_feedback(u, u->thisorder, "feedback_unit_not_found", NULL));
return 0; return 0;
} }
if (effskill(u, SK_SPY, NULL) < 1) { if (effskill(u, SK_SPY, NULL) < 1) {

View File

@ -156,7 +156,8 @@ const char *keywords[MAXKEYWORDS] = {
"promote", "promote",
"pay", "pay",
"loot", "loot",
"expel",
"autostudy", "autostudy",
"locale", "locale"
}; };

View File

@ -71,6 +71,7 @@ extern "C"
K_PROMOTION, K_PROMOTION,
K_PAY, K_PAY,
K_LOOT, K_LOOT,
K_EXPEL,
K_AUTOSTUDY, K_AUTOSTUDY,
K_LOCALE, K_LOCALE,
MAXKEYWORDS, MAXKEYWORDS,