From 73da2564614b012971aa979210bb69ff1094d403 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 5 Jan 2015 18:14:55 +0100 Subject: [PATCH 1/6] Bug 2059: building owners kick out anyone they don't HELP GUARD. --- src/laws.c | 75 +++++++++++++++++++++++++++++++------------------ src/laws.h | 1 + src/laws.test.c | 47 +++++++++++++++++++++++++++++++ src/tests.c | 4 +-- 4 files changed, 98 insertions(+), 29 deletions(-) diff --git a/src/laws.c b/src/laws.c index 0c01f0471..8a29db9c0 100755 --- a/src/laws.c +++ b/src/laws.c @@ -4269,6 +4269,26 @@ static void enter_2(region * r) do_enter(r, 1); } +static bool help_enter(unit *uo, unit *u) { + return uo->faction == u->faction || alliedunit(uo, u->faction, HELP_GUARD); +} + +void force_leave(region *r) { + unit *u; + for (u = r->units; u; u = u->next) { + unit *uo = NULL; + if (u->building) { + uo = building_owner(u->building); + } + if (u->ship) { + uo = ship_owner(u->ship); + } + if (uo && !help_enter(uo, u)) { + leave(u, false); + } + } +} + static void maintain_buildings_1(region * r) { maintain_buildings(r, false); @@ -4306,71 +4326,72 @@ void init_processor(void) int p; p = 10; - add_proc_global(p, &new_units, "Neue Einheiten erschaffen"); + add_proc_global(p, new_units, "Neue Einheiten erschaffen"); p += 10; add_proc_unit(p, update_long_order, "Langen Befehl aktualisieren"); add_proc_order(p, K_BANNER, banner_cmd, 0, NULL); - add_proc_order(p, K_EMAIL, &email_cmd, 0, NULL); - add_proc_order(p, K_PASSWORD, &password_cmd, 0, NULL); - add_proc_order(p, K_SEND, &send_cmd, 0, NULL); - add_proc_order(p, K_GROUP, &group_cmd, 0, NULL); + add_proc_order(p, K_EMAIL, email_cmd, 0, NULL); + add_proc_order(p, K_PASSWORD, password_cmd, 0, NULL); + add_proc_order(p, K_SEND, send_cmd, 0, NULL); + add_proc_order(p, K_GROUP, group_cmd, 0, NULL); p += 10; - add_proc_order(p, K_QUIT, &quit_cmd, 0, NULL); - add_proc_order(p, K_URSPRUNG, &origin_cmd, 0, NULL); - add_proc_order(p, K_ALLY, &ally_cmd, 0, NULL); - add_proc_order(p, K_PREFIX, &prefix_cmd, 0, NULL); - add_proc_order(p, K_SETSTEALTH, &setstealth_cmd, 0, NULL); - add_proc_order(p, K_STATUS, &status_cmd, 0, NULL); - add_proc_order(p, K_COMBATSPELL, &combatspell_cmd, 0, NULL); - add_proc_order(p, K_DISPLAY, &display_cmd, 0, NULL); - add_proc_order(p, K_NAME, &name_cmd, 0, NULL); - add_proc_order(p, K_GUARD, &guard_off_cmd, 0, NULL); - add_proc_order(p, K_RESHOW, &reshow_cmd, 0, NULL); + add_proc_order(p, K_QUIT, quit_cmd, 0, NULL); + add_proc_order(p, K_URSPRUNG, origin_cmd, 0, NULL); + add_proc_order(p, K_ALLY, ally_cmd, 0, NULL); + add_proc_order(p, K_PREFIX, prefix_cmd, 0, NULL); + add_proc_order(p, K_SETSTEALTH, setstealth_cmd, 0, NULL); + add_proc_order(p, K_STATUS, status_cmd, 0, NULL); + add_proc_order(p, K_COMBATSPELL, combatspell_cmd, 0, NULL); + add_proc_order(p, K_DISPLAY, display_cmd, 0, NULL); + add_proc_order(p, K_NAME, name_cmd, 0, NULL); + add_proc_order(p, K_GUARD, guard_off_cmd, 0, NULL); + add_proc_order(p, K_RESHOW, reshow_cmd, 0, NULL); if (get_param_int(global.parameters, "rules.alliances", 0) == 1) { p += 10; - add_proc_global(p, &alliance_cmd, NULL); + add_proc_global(p, alliance_cmd, NULL); } p += 10; add_proc_region(p, do_contact, "Kontaktieren"); - add_proc_order(p, K_MAIL, &mail_cmd, 0, "Botschaften"); + add_proc_order(p, K_MAIL, mail_cmd, 0, "Botschaften"); p += 10; /* all claims must be done before we can USE */ add_proc_region(p, &enter_1, "Betreten (1. Versuch)"); /* for GIVE CONTROL */ - add_proc_order(p, K_USE, &use_cmd, 0, "Benutzen"); + add_proc_order(p, K_USE, use_cmd, 0, "Benutzen"); p += 10; /* in case it has any effects on alliance victories */ - add_proc_order(p, K_GIVE, &give_control_cmd, 0, "GIB KOMMANDO"); + add_proc_order(p, K_GIVE, give_control_cmd, 0, "GIB KOMMANDO"); p += 10; /* in case it has any effects on alliance victories */ - add_proc_order(p, K_LEAVE, &leave_cmd, 0, "Verlassen"); + add_proc_order(p, K_LEAVE, leave_cmd, 0, "Verlassen"); p += 10; - add_proc_region(p, &enter_1, "Betreten (2. Versuch)"); /* to allow a buildingowner to enter the castle pre combat */ + add_proc_region(p, enter_1, "Betreten (2. Versuch)"); /* to allow a buildingowner to enter the castle pre combat */ p += 10; - add_proc_region(p, &do_battle, "Attackieren"); + add_proc_region(p, do_battle, "Attackieren"); if (!keyword_disabled(K_BESIEGE)) { p += 10; - add_proc_region(p, &do_siege, "Belagern"); + add_proc_region(p, do_siege, "Belagern"); } p += 10; /* can't allow reserve before siege (weapons) */ - add_proc_region(p, &enter_1, "Betreten (3. Versuch)"); /* to claim a castle after a victory and to be able to DESTROY it in the same turn */ + add_proc_region(p, enter_1, "Betreten (3. Versuch)"); /* to claim a castle after a victory and to be able to DESTROY it in the same turn */ if (get_param_int(global.parameters, "rules.reserve.twophase", 0)) { add_proc_order(p, K_RESERVE, &reserve_self, 0, "RESERVE (self)"); p += 10; } add_proc_order(p, K_RESERVE, &reserve_cmd, 0, "RESERVE (all)"); add_proc_order(p, K_CLAIM, &claim_cmd, 0, NULL); - add_proc_unit(p, &follow_unit, "Folge auf Einheiten setzen"); + add_proc_unit(p, follow_unit, "Folge auf Einheiten setzen"); p += 10; /* rest rng again before economics */ - add_proc_region(p, &economics, "Zerstoeren, Geben, Rekrutieren, Vergessen"); + add_proc_region(p, force_leave, "kick non-allies out of buildings/ships"); + add_proc_region(p, economics, "Zerstoeren, Geben, Rekrutieren, Vergessen"); add_proc_order(p, K_PROMOTION, &promotion_cmd, 0, "Heldenbefoerderung"); p += 10; diff --git a/src/laws.h b/src/laws.h index f5209ac3f..27232982b 100755 --- a/src/laws.h +++ b/src/laws.h @@ -105,6 +105,7 @@ extern "C" { bool seefaction(const struct faction *f, const struct region *r, const struct unit *u, int modifier); int armedmen(const struct unit *u, bool siege_weapons); + void force_leave(struct region *r); #ifdef __cplusplus diff --git a/src/laws.test.c b/src/laws.test.c index 9f91ffc77..ec1174a17 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -226,6 +226,51 @@ static void test_display_cmd(CuTest *tc) { test_cleanup(); } +static void test_force_leave_buildings(CuTest *tc) { + ally *al; + region *r; + unit *u1, *u2, *u3; + building * b; + test_cleanup(); + r = test_create_region(0, 0, test_create_terrain("plain", LAND_REGION)); + u1 = test_create_unit(test_create_faction(NULL), r); + u2 = test_create_unit(u1->faction, r); + u3 = test_create_unit(test_create_faction(NULL), r); + b = test_create_building(r, NULL); + u_set_building(u1, b); + building_set_owner(u1); + u_set_building(u2, b); + u_set_building(u3, b); + force_leave(r); + CuAssertPtrEquals_Msg(tc, "owner should not be forecd to leave", b, u1->building); + CuAssertPtrEquals_Msg(tc, "same faction should not be forced to leave", b, u2->building); + CuAssertPtrEquals_Msg(tc, "non-allies should be forced to leave", NULL, u3->building); + + u_set_building(u3, b); + al = ally_add(&u1->faction->allies, u3->faction); + al->status = HELP_GUARD; + force_leave(r); + CuAssertPtrEquals_Msg(tc, "allies should not be forced to leave", b, u3->building); + test_cleanup(); +} + +static void test_force_leave_ships(CuTest *tc) { + region *r; + unit *u1, *u2; + ship *sh; + test_cleanup(); + r = test_create_region(0, 0, test_create_terrain("plain", LAND_REGION)); + u1 = test_create_unit(test_create_faction(NULL), r); + u2 = test_create_unit(test_create_faction(NULL), r); + sh = test_create_ship(r, NULL); + u_set_ship(u1, sh); + u_set_ship(u2, sh); + ship_set_owner(u1); + force_leave(r); + CuAssertPtrEquals_Msg(tc, "non-allies should be forced to leave", NULL, u2->ship); + test_cleanup(); +} + static void test_fishing_feeds_2_people(CuTest * tc) { const resource_type *rtype; @@ -649,5 +694,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_enter_building); SUITE_ADD_TEST(suite, test_enter_ship); SUITE_ADD_TEST(suite, test_display_cmd); + SUITE_ADD_TEST(suite, test_force_leave_buildings); + SUITE_ADD_TEST(suite, test_force_leave_ships); return suite; } diff --git a/src/tests.c b/src/tests.c index 79ff5ad38..bf2aa4ef3 100644 --- a/src/tests.c +++ b/src/tests.c @@ -81,14 +81,14 @@ test_create_terrain(const char * name, unsigned int flags) building * test_create_building(region * r, const building_type * btype) { - building * b = new_building(btype?btype:bt_find("castle"), r, default_locale); + building * b = new_building(btype?btype:bt_get_or_create("castle"), r, default_locale); b->size = b->type->maxsize>0?b->type->maxsize:1; return b; } ship * test_create_ship(region * r, const ship_type * stype) { - ship * s = new_ship(stype?stype:st_find("boat"), r, default_locale); + ship * s = new_ship(stype?stype:st_get_or_create("boat"), r, default_locale); s->size = s->type->construction?s->type->construction->maxsize:1; return s; } From d968aa2ed52ea322f411207a82b310bdae81da6d Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 5 Jan 2015 22:09:08 +0100 Subject: [PATCH 2/6] do not eject units from a ship when on the ocean. --- src/laws.c | 2 +- src/laws.test.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/laws.c b/src/laws.c index 8a29db9c0..66884aa71 100755 --- a/src/laws.c +++ b/src/laws.c @@ -4280,7 +4280,7 @@ void force_leave(region *r) { if (u->building) { uo = building_owner(u->building); } - if (u->ship) { + if (u->ship && r->land) { uo = ship_owner(u->ship); } if (uo && !help_enter(uo, u)) { diff --git a/src/laws.test.c b/src/laws.test.c index ec1174a17..14e6bb6c7 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -271,6 +271,23 @@ static void test_force_leave_ships(CuTest *tc) { test_cleanup(); } +static void test_force_leave_ships_on_ocean(CuTest *tc) { + region *r; + unit *u1, *u2; + ship *sh; + test_cleanup(); + r = test_create_region(0, 0, test_create_terrain("ocean", SEA_REGION)); + u1 = test_create_unit(test_create_faction(NULL), r); + u2 = test_create_unit(test_create_faction(NULL), r); + sh = test_create_ship(r, NULL); + u_set_ship(u1, sh); + u_set_ship(u2, sh); + ship_set_owner(u1); + force_leave(r); + CuAssertPtrEquals_Msg(tc, "no forcing out of ships on oceans", sh, u2->ship); + test_cleanup(); +} + static void test_fishing_feeds_2_people(CuTest * tc) { const resource_type *rtype; @@ -696,5 +713,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_display_cmd); SUITE_ADD_TEST(suite, test_force_leave_buildings); SUITE_ADD_TEST(suite, test_force_leave_ships); + SUITE_ADD_TEST(suite, test_force_leave_ships_on_ocean); + return suite; } From 838cf3d938a91efc840bd844406793de5ad33328 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 12 Jan 2015 22:53:21 +0100 Subject: [PATCH 3/6] try to allow visual studio to build with all warnings (/WAll) enabled. --- src/attributes/stealth.c | 1 - src/bind_tolua.c | 1 + src/callback.c | 1 - src/kernel/faction.h | 2 +- src/kernel/item.h | 4 ++-- src/kernel/race.h | 5 ++--- src/platform.h | 10 ++++++---- src/reports.test.c | 1 + src/util/unicode.test.c | 9 +++++---- src/vortex.c | 1 - 10 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/attributes/stealth.c b/src/attributes/stealth.c index 129802c09..9d76ffb29 100644 --- a/src/attributes/stealth.c +++ b/src/attributes/stealth.c @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/src/bind_tolua.c b/src/bind_tolua.c index 26e536f9c..c6df54a10 100644 --- a/src/bind_tolua.c +++ b/src/bind_tolua.c @@ -1,3 +1,4 @@ +#include #pragma warning(push) #pragma warning(disable: 4100) #include "config.pkg.c" diff --git a/src/callback.c b/src/callback.c index c2d178819..9d76f30c8 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1,4 +1,3 @@ -#include #include #include "callback.h" #include diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 20c6f9785..31705860f 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -82,7 +82,6 @@ typedef struct faction { int no_units; struct ally *allies; struct group *groups; - bool alive; /* enno: sollte ein flag werden */ int nregions; int money; #if SCORE_MODULE @@ -104,6 +103,7 @@ typedef struct faction { struct item *items; /* items this faction can claim */ struct seen_region **seen; struct quicklist *seen_factions; + bool alive; /* enno: sollte ein flag werden */ } faction; extern struct faction *factions; diff --git a/src/kernel/item.h b/src/kernel/item.h index d40e2d90c..9f2513134 100644 --- a/src/kernel/item.h +++ b/src/kernel/item.h @@ -193,11 +193,11 @@ extern "C" { typedef struct armor_type { const item_type *itype; + unsigned int flags; double penalty; double magres; int prot; float projectile; /* chance, dass ein projektil abprallt */ - unsigned int flags; } armor_type; #define WTF_NONE 0x00 @@ -223,7 +223,7 @@ extern "C" { int reload; /* time to reload this weapon */ weapon_mod *modifiers; /* --- functions --- */ - bool(*attack) (const struct troop *, const struct weapon_type *, + bool(*attack) (const struct troop *, const struct weapon_type *, int *deaths); } weapon_type; diff --git a/src/kernel/race.h b/src/kernel/race.h index 6882af222..fa61e4cec 100644 --- a/src/kernel/race.h +++ b/src/kernel/race.h @@ -140,14 +140,13 @@ extern "C" { int at_bonus; /* Verändert den Angriffsskill (default: 0) */ int df_bonus; /* Verändert den Verteidigungskill (default: 0) */ const struct spell *precombatspell; - struct att attack[10]; - signed char bonus[MAXSKILLS]; signed char *study_speed; /* study-speed-bonus in points/turn (0=30 Tage) */ - bool __remove_me_nonplayer; int flags; int battle_flags; int ec_flags; race_t oldfamiliars[MAXMAGIETYP]; + struct att attack[10]; + signed char bonus[MAXSKILLS]; const char *(*generate_name) (const struct unit *); const char *(*describe) (const struct unit *, const struct locale *); diff --git a/src/platform.h b/src/platform.h index e83600fa2..64c369c0a 100644 --- a/src/platform.h +++ b/src/platform.h @@ -26,7 +26,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifdef _MSC_VER # define VC_EXTRALEAN # define WIN32_LEAN_AND_MEAN +#pragma warning(push) +#pragma warning(disable:4820 4255 4668) # include +# include +#pragma warning(pop) # undef MOUSE_MOVED # define STDIO_CP 1252 /* log.c, convert to console character set */ # pragma warning (disable: 4201 4214 4514 4115 4711) @@ -41,6 +45,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # pragma warning(disable: 4996) /* is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' */ # pragma warning(disable: 4668) +/* : bytes padding after data member */ +# pragma warning(disable: 4820) /* warning C4100: was declared deprecated */ #ifndef _CRT_SECURE_NO_DEPRECATE @@ -113,9 +119,5 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #endif -#ifdef HAVE_IO_H -#include -#endif - #endif diff --git a/src/reports.test.c b/src/reports.test.c index 5f9ce5ae0..060934ddb 100644 --- a/src/reports.test.c +++ b/src/reports.test.c @@ -1,3 +1,4 @@ +#include #include #include "reports.h" diff --git a/src/util/unicode.test.c b/src/util/unicode.test.c index 52392fda4..958b695e2 100644 --- a/src/util/unicode.test.c +++ b/src/util/unicode.test.c @@ -1,3 +1,4 @@ +#include #include #include "unicode.h" #include @@ -10,14 +11,14 @@ static void test_unicode_tolower(CuTest * tc) CuAssertIntEquals(tc, 0, unicode_utf8_tolower(buffer, sizeof(buffer), "HeLlO W0Rld")); CuAssertStrEquals(tc, "hello w0rld", buffer); memset(buffer, 0, sizeof(buffer)); - buffer[5]='X'; + buffer[5] = 'X'; CuAssertIntEquals(tc, ENOMEM, unicode_utf8_tolower(buffer, 5, "HeLlO W0Rld")); CuAssertStrEquals(tc, "helloX", buffer); } CuSuite *get_unicode_suite(void) { - CuSuite *suite = CuSuiteNew(); - SUITE_ADD_TEST(suite, test_unicode_tolower); - return suite; + CuSuite *suite = CuSuiteNew(); + SUITE_ADD_TEST(suite, test_unicode_tolower); + return suite; } diff --git a/src/vortex.c b/src/vortex.c index a4aee3181..79b37fb8a 100644 --- a/src/vortex.c +++ b/src/vortex.c @@ -1,4 +1,3 @@ -#include #include #include "vortex.h" From 698aa5e99af592d111d3917aeb89ffbd3eee1a59 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 5 Jan 2015 18:14:55 +0100 Subject: [PATCH 4/6] Bug 2059: building owners kick out anyone they don't HELP GUARD. --- src/laws.c | 75 +++++++++++++++++++++++++++++++------------------ src/laws.h | 1 + src/laws.test.c | 47 +++++++++++++++++++++++++++++++ src/tests.c | 4 +-- 4 files changed, 98 insertions(+), 29 deletions(-) diff --git a/src/laws.c b/src/laws.c index 1715bede1..46f765b41 100755 --- a/src/laws.c +++ b/src/laws.c @@ -4269,6 +4269,26 @@ static void enter_2(region * r) do_enter(r, 1); } +static bool help_enter(unit *uo, unit *u) { + return uo->faction == u->faction || alliedunit(uo, u->faction, HELP_GUARD); +} + +void force_leave(region *r) { + unit *u; + for (u = r->units; u; u = u->next) { + unit *uo = NULL; + if (u->building) { + uo = building_owner(u->building); + } + if (u->ship) { + uo = ship_owner(u->ship); + } + if (uo && !help_enter(uo, u)) { + leave(u, false); + } + } +} + static void maintain_buildings_1(region * r) { maintain_buildings(r, false); @@ -4306,71 +4326,72 @@ void init_processor(void) int p; p = 10; - add_proc_global(p, &new_units, "Neue Einheiten erschaffen"); + add_proc_global(p, new_units, "Neue Einheiten erschaffen"); p += 10; add_proc_unit(p, update_long_order, "Langen Befehl aktualisieren"); add_proc_order(p, K_BANNER, banner_cmd, 0, NULL); - add_proc_order(p, K_EMAIL, &email_cmd, 0, NULL); - add_proc_order(p, K_PASSWORD, &password_cmd, 0, NULL); - add_proc_order(p, K_SEND, &send_cmd, 0, NULL); - add_proc_order(p, K_GROUP, &group_cmd, 0, NULL); + add_proc_order(p, K_EMAIL, email_cmd, 0, NULL); + add_proc_order(p, K_PASSWORD, password_cmd, 0, NULL); + add_proc_order(p, K_SEND, send_cmd, 0, NULL); + add_proc_order(p, K_GROUP, group_cmd, 0, NULL); p += 10; - add_proc_order(p, K_QUIT, &quit_cmd, 0, NULL); - add_proc_order(p, K_URSPRUNG, &origin_cmd, 0, NULL); - add_proc_order(p, K_ALLY, &ally_cmd, 0, NULL); - add_proc_order(p, K_PREFIX, &prefix_cmd, 0, NULL); - add_proc_order(p, K_SETSTEALTH, &setstealth_cmd, 0, NULL); - add_proc_order(p, K_STATUS, &status_cmd, 0, NULL); - add_proc_order(p, K_COMBATSPELL, &combatspell_cmd, 0, NULL); - add_proc_order(p, K_DISPLAY, &display_cmd, 0, NULL); - add_proc_order(p, K_NAME, &name_cmd, 0, NULL); - add_proc_order(p, K_GUARD, &guard_off_cmd, 0, NULL); - add_proc_order(p, K_RESHOW, &reshow_cmd, 0, NULL); + add_proc_order(p, K_QUIT, quit_cmd, 0, NULL); + add_proc_order(p, K_URSPRUNG, origin_cmd, 0, NULL); + add_proc_order(p, K_ALLY, ally_cmd, 0, NULL); + add_proc_order(p, K_PREFIX, prefix_cmd, 0, NULL); + add_proc_order(p, K_SETSTEALTH, setstealth_cmd, 0, NULL); + add_proc_order(p, K_STATUS, status_cmd, 0, NULL); + add_proc_order(p, K_COMBATSPELL, combatspell_cmd, 0, NULL); + add_proc_order(p, K_DISPLAY, display_cmd, 0, NULL); + add_proc_order(p, K_NAME, name_cmd, 0, NULL); + add_proc_order(p, K_GUARD, guard_off_cmd, 0, NULL); + add_proc_order(p, K_RESHOW, reshow_cmd, 0, NULL); if (get_param_int(global.parameters, "rules.alliances", 0) == 1) { p += 10; - add_proc_global(p, &alliance_cmd, NULL); + add_proc_global(p, alliance_cmd, NULL); } p += 10; add_proc_region(p, do_contact, "Kontaktieren"); - add_proc_order(p, K_MAIL, &mail_cmd, 0, "Botschaften"); + add_proc_order(p, K_MAIL, mail_cmd, 0, "Botschaften"); p += 10; /* all claims must be done before we can USE */ add_proc_region(p, &enter_1, "Betreten (1. Versuch)"); /* for GIVE CONTROL */ - add_proc_order(p, K_USE, &use_cmd, 0, "Benutzen"); + add_proc_order(p, K_USE, use_cmd, 0, "Benutzen"); p += 10; /* in case it has any effects on alliance victories */ - add_proc_order(p, K_GIVE, &give_control_cmd, 0, "GIB KOMMANDO"); + add_proc_order(p, K_GIVE, give_control_cmd, 0, "GIB KOMMANDO"); p += 10; /* in case it has any effects on alliance victories */ - add_proc_order(p, K_LEAVE, &leave_cmd, 0, "Verlassen"); + add_proc_order(p, K_LEAVE, leave_cmd, 0, "Verlassen"); p += 10; - add_proc_region(p, &enter_1, "Betreten (2. Versuch)"); /* to allow a buildingowner to enter the castle pre combat */ + add_proc_region(p, enter_1, "Betreten (2. Versuch)"); /* to allow a buildingowner to enter the castle pre combat */ p += 10; - add_proc_region(p, &do_battle, "Attackieren"); + add_proc_region(p, do_battle, "Attackieren"); if (!keyword_disabled(K_BESIEGE)) { p += 10; - add_proc_region(p, &do_siege, "Belagern"); + add_proc_region(p, do_siege, "Belagern"); } p += 10; /* can't allow reserve before siege (weapons) */ - add_proc_region(p, &enter_1, "Betreten (3. Versuch)"); /* to claim a castle after a victory and to be able to DESTROY it in the same turn */ + add_proc_region(p, enter_1, "Betreten (3. Versuch)"); /* to claim a castle after a victory and to be able to DESTROY it in the same turn */ if (get_param_int(global.parameters, "rules.reserve.twophase", 0)) { add_proc_order(p, K_RESERVE, &reserve_self, 0, "RESERVE (self)"); p += 10; } add_proc_order(p, K_RESERVE, &reserve_cmd, 0, "RESERVE (all)"); add_proc_order(p, K_CLAIM, &claim_cmd, 0, NULL); - add_proc_unit(p, &follow_unit, "Folge auf Einheiten setzen"); + add_proc_unit(p, follow_unit, "Folge auf Einheiten setzen"); p += 10; /* rest rng again before economics */ - add_proc_region(p, &economics, "Zerstoeren, Geben, Rekrutieren, Vergessen"); + add_proc_region(p, force_leave, "kick non-allies out of buildings/ships"); + add_proc_region(p, economics, "Zerstoeren, Geben, Rekrutieren, Vergessen"); add_proc_order(p, K_PROMOTION, &promotion_cmd, 0, "Heldenbefoerderung"); p += 10; diff --git a/src/laws.h b/src/laws.h index f5209ac3f..27232982b 100755 --- a/src/laws.h +++ b/src/laws.h @@ -105,6 +105,7 @@ extern "C" { bool seefaction(const struct faction *f, const struct region *r, const struct unit *u, int modifier); int armedmen(const struct unit *u, bool siege_weapons); + void force_leave(struct region *r); #ifdef __cplusplus diff --git a/src/laws.test.c b/src/laws.test.c index 9f91ffc77..ec1174a17 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -226,6 +226,51 @@ static void test_display_cmd(CuTest *tc) { test_cleanup(); } +static void test_force_leave_buildings(CuTest *tc) { + ally *al; + region *r; + unit *u1, *u2, *u3; + building * b; + test_cleanup(); + r = test_create_region(0, 0, test_create_terrain("plain", LAND_REGION)); + u1 = test_create_unit(test_create_faction(NULL), r); + u2 = test_create_unit(u1->faction, r); + u3 = test_create_unit(test_create_faction(NULL), r); + b = test_create_building(r, NULL); + u_set_building(u1, b); + building_set_owner(u1); + u_set_building(u2, b); + u_set_building(u3, b); + force_leave(r); + CuAssertPtrEquals_Msg(tc, "owner should not be forecd to leave", b, u1->building); + CuAssertPtrEquals_Msg(tc, "same faction should not be forced to leave", b, u2->building); + CuAssertPtrEquals_Msg(tc, "non-allies should be forced to leave", NULL, u3->building); + + u_set_building(u3, b); + al = ally_add(&u1->faction->allies, u3->faction); + al->status = HELP_GUARD; + force_leave(r); + CuAssertPtrEquals_Msg(tc, "allies should not be forced to leave", b, u3->building); + test_cleanup(); +} + +static void test_force_leave_ships(CuTest *tc) { + region *r; + unit *u1, *u2; + ship *sh; + test_cleanup(); + r = test_create_region(0, 0, test_create_terrain("plain", LAND_REGION)); + u1 = test_create_unit(test_create_faction(NULL), r); + u2 = test_create_unit(test_create_faction(NULL), r); + sh = test_create_ship(r, NULL); + u_set_ship(u1, sh); + u_set_ship(u2, sh); + ship_set_owner(u1); + force_leave(r); + CuAssertPtrEquals_Msg(tc, "non-allies should be forced to leave", NULL, u2->ship); + test_cleanup(); +} + static void test_fishing_feeds_2_people(CuTest * tc) { const resource_type *rtype; @@ -649,5 +694,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_enter_building); SUITE_ADD_TEST(suite, test_enter_ship); SUITE_ADD_TEST(suite, test_display_cmd); + SUITE_ADD_TEST(suite, test_force_leave_buildings); + SUITE_ADD_TEST(suite, test_force_leave_ships); return suite; } diff --git a/src/tests.c b/src/tests.c index 499e9883d..4e5c41255 100644 --- a/src/tests.c +++ b/src/tests.c @@ -82,14 +82,14 @@ test_create_terrain(const char * name, unsigned int flags) building * test_create_building(region * r, const building_type * btype) { - building * b = new_building(btype?btype:bt_find("castle"), r, default_locale); + building * b = new_building(btype?btype:bt_get_or_create("castle"), r, default_locale); b->size = b->type->maxsize>0?b->type->maxsize:1; return b; } ship * test_create_ship(region * r, const ship_type * stype) { - ship * s = new_ship(stype?stype:st_find("boat"), r, default_locale); + ship * s = new_ship(stype?stype:st_get_or_create("boat"), r, default_locale); s->size = s->type->construction?s->type->construction->maxsize:1; return s; } From f52e00d574f043e3254f2c1ffc1d8fe3e9544ec4 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Mon, 5 Jan 2015 22:09:08 +0100 Subject: [PATCH 5/6] do not eject units from a ship when on the ocean. --- src/laws.c | 2 +- src/laws.test.c | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/laws.c b/src/laws.c index 46f765b41..5d51eeba4 100755 --- a/src/laws.c +++ b/src/laws.c @@ -4280,7 +4280,7 @@ void force_leave(region *r) { if (u->building) { uo = building_owner(u->building); } - if (u->ship) { + if (u->ship && r->land) { uo = ship_owner(u->ship); } if (uo && !help_enter(uo, u)) { diff --git a/src/laws.test.c b/src/laws.test.c index ec1174a17..14e6bb6c7 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -271,6 +271,23 @@ static void test_force_leave_ships(CuTest *tc) { test_cleanup(); } +static void test_force_leave_ships_on_ocean(CuTest *tc) { + region *r; + unit *u1, *u2; + ship *sh; + test_cleanup(); + r = test_create_region(0, 0, test_create_terrain("ocean", SEA_REGION)); + u1 = test_create_unit(test_create_faction(NULL), r); + u2 = test_create_unit(test_create_faction(NULL), r); + sh = test_create_ship(r, NULL); + u_set_ship(u1, sh); + u_set_ship(u2, sh); + ship_set_owner(u1); + force_leave(r); + CuAssertPtrEquals_Msg(tc, "no forcing out of ships on oceans", sh, u2->ship); + test_cleanup(); +} + static void test_fishing_feeds_2_people(CuTest * tc) { const resource_type *rtype; @@ -696,5 +713,7 @@ CuSuite *get_laws_suite(void) SUITE_ADD_TEST(suite, test_display_cmd); SUITE_ADD_TEST(suite, test_force_leave_buildings); SUITE_ADD_TEST(suite, test_force_leave_ships); + SUITE_ADD_TEST(suite, test_force_leave_ships_on_ocean); + return suite; } From 4f2d9260d16aefe839ddee7a138a7bc90c992d62 Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Tue, 13 Jan 2015 07:43:30 +0100 Subject: [PATCH 6/6] add a message to the unit that gets kicked, with tests --- res/core/messages.xml | 18 ++++++++++++++++++ src/laws.c | 6 ++++++ src/laws.test.c | 7 +++++++ src/tests.c | 9 +++++++++ src/tests.h | 2 ++ 5 files changed, 42 insertions(+) diff --git a/res/core/messages.xml b/res/core/messages.xml index 52b132220..cbc5dd780 100644 --- a/res/core/messages.xml +++ b/res/core/messages.xml @@ -1,5 +1,23 @@ + + + + + + + $unit($owner) bittet $unit($unit), $ship($ship) zu verlassen. + $unit($owner) asks $unit($unit) to leave $ship($ship). + + + + + + + + $unit($owner) bittet $unit($unit), $building($building) zu verlassen. + $unit($owner) asks $unit($unit) to leave $building($building). + diff --git a/src/laws.c b/src/laws.c index 5d51eeba4..ca80a9fb4 100755 --- a/src/laws.c +++ b/src/laws.c @@ -4277,14 +4277,20 @@ void force_leave(region *r) { unit *u; for (u = r->units; u; u = u->next) { unit *uo = NULL; + message *msg = NULL; if (u->building) { uo = building_owner(u->building); + msg = msg_message("force_leave_building", "unit owner building", u, uo, u->building); } if (u->ship && r->land) { uo = ship_owner(u->ship); + msg = msg_message("force_leave_ship", "unit owner ship", u, uo, u->ship); } if (uo && !help_enter(uo, u)) { leave(u, false); + if (msg) { + ADDMSG(&u->faction->msgs, msg); + } } } } diff --git a/src/laws.test.c b/src/laws.test.c index 14e6bb6c7..2b2f0bb9f 100644 --- a/src/laws.test.c +++ b/src/laws.test.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -231,6 +232,7 @@ static void test_force_leave_buildings(CuTest *tc) { region *r; unit *u1, *u2, *u3; building * b; + message *msg; test_cleanup(); r = test_create_region(0, 0, test_create_terrain("plain", LAND_REGION)); u1 = test_create_unit(test_create_faction(NULL), r); @@ -245,6 +247,8 @@ static void test_force_leave_buildings(CuTest *tc) { CuAssertPtrEquals_Msg(tc, "owner should not be forecd to leave", b, u1->building); CuAssertPtrEquals_Msg(tc, "same faction should not be forced to leave", b, u2->building); CuAssertPtrEquals_Msg(tc, "non-allies should be forced to leave", NULL, u3->building); + msg = test_get_last_message(u3->faction->msgs); + CuAssertStrEquals(tc, "force_leave_building", test_get_messagetype(msg)); u_set_building(u3, b); al = ally_add(&u1->faction->allies, u3->faction); @@ -258,6 +262,7 @@ static void test_force_leave_ships(CuTest *tc) { region *r; unit *u1, *u2; ship *sh; + message *msg; test_cleanup(); r = test_create_region(0, 0, test_create_terrain("plain", LAND_REGION)); u1 = test_create_unit(test_create_faction(NULL), r); @@ -268,6 +273,8 @@ static void test_force_leave_ships(CuTest *tc) { ship_set_owner(u1); force_leave(r); CuAssertPtrEquals_Msg(tc, "non-allies should be forced to leave", NULL, u2->ship); + msg = test_get_last_message(u2->faction->msgs); + CuAssertStrEquals(tc, "force_leave_ship", test_get_messagetype(msg)); test_cleanup(); } diff --git a/src/tests.c b/src/tests.c index 4e5c41255..83c6fe6fa 100644 --- a/src/tests.c +++ b/src/tests.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -193,6 +194,14 @@ void test_create_world(void) test_create_shiptype("boat"); } +message * test_get_last_message(message_list *msgs) { + struct mlist *iter = msgs->begin; + while (iter->next) { + iter = iter->next; + } + return iter->msg; +} + const char * test_get_messagetype(const message *msg) { const char * name = msg->type->name; if (strcmp(name, "missing_message") == 0) { diff --git a/src/tests.h b/src/tests.h index 1780e4e74..b83beab40 100644 --- a/src/tests.h +++ b/src/tests.h @@ -14,6 +14,7 @@ extern "C" { struct building; struct ship; struct message; + struct message_list; struct item_type; struct building_type; struct ship_type; @@ -37,6 +38,7 @@ extern "C" { int RunAllTests(void); void test_translate_param(const struct locale *lang, param_t param, const char *text); const char * test_get_messagetype(const struct message *msg); + struct message * test_get_last_message(struct message_list *mlist); #ifdef __cplusplus }