forked from github/server
Merge pull request #97 from badgerman/bug-2059-force-leave
Bug 2059: force non-allies to leave ships and buildings
This commit is contained in:
commit
9f9043e4dd
|
@ -1,5 +1,23 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<messages>
|
||||
<message name="force_leave_ship" section="events">
|
||||
<type>
|
||||
<arg name="unit" type="unit"/>
|
||||
<arg name="owner" type="unit"/>
|
||||
<arg name="ship" type="ship"/>
|
||||
</type>
|
||||
<text locale="de">$unit($owner) bittet $unit($unit), $ship($ship) zu verlassen.</text>
|
||||
<text locale="en">$unit($owner) asks $unit($unit) to leave $ship($ship).</text>
|
||||
</message>
|
||||
<message name="force_leave_building" section="events">
|
||||
<type>
|
||||
<arg name="unit" type="unit"/>
|
||||
<arg name="owner" type="unit"/>
|
||||
<arg name="building" type="building"/>
|
||||
</type>
|
||||
<text locale="de">$unit($owner) bittet $unit($unit), $building($building) zu verlassen.</text>
|
||||
<text locale="en">$unit($owner) asks $unit($unit) to leave $building($building).</text>
|
||||
</message>
|
||||
<message name="alp_destroyed" section="events">
|
||||
<type>
|
||||
<arg name="region" type="region"/>
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include <config.h>
|
||||
#include <platform.h>
|
||||
#include <kernel/unit.h>
|
||||
#include <kernel/region.h>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <platform.h>
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4100)
|
||||
#include "config.pkg.c"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include <config.h>
|
||||
#include <platform.h>
|
||||
#include "callback.h"
|
||||
#include <stdlib.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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
|
85
src/laws.c
85
src/laws.c
|
@ -4269,6 +4269,36 @@ 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 && r->land) {
|
||||
uo = ship_owner(u->ship);
|
||||
}
|
||||
if (uo && !help_enter(uo, u)) {
|
||||
message *msg = NULL;
|
||||
if (u->building) {
|
||||
msg = msg_message("force_leave_building", "unit owner building", u, uo, u->building);
|
||||
}
|
||||
else {
|
||||
msg = msg_message("force_leave_ship", "unit owner ship", u, uo, u->ship);
|
||||
}
|
||||
if (msg) {
|
||||
ADDMSG(&u->faction->msgs, msg);
|
||||
}
|
||||
leave(u, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void maintain_buildings_1(region * r)
|
||||
{
|
||||
maintain_buildings(r, false);
|
||||
|
@ -4306,71 +4336,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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <util/base36.h>
|
||||
#include <util/language.h>
|
||||
#include <util/message.h>
|
||||
|
||||
#include <CuTest.h>
|
||||
#include <tests.h>
|
||||
|
@ -226,6 +227,74 @@ 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;
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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;
|
||||
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);
|
||||
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);
|
||||
msg = test_get_last_message(u2->faction->msgs);
|
||||
CuAssertStrEquals(tc, "force_leave_ship", test_get_messagetype(msg));
|
||||
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;
|
||||
|
@ -649,5 +718,9 @@ 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);
|
||||
SUITE_ADD_TEST(suite, test_force_leave_ships_on_ocean);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
|
|
@ -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 <windows.h>
|
||||
# include <io.h>
|
||||
#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)
|
||||
/* <name> is not defined as a preprocessor macro, replacing with '0' for '#if/#elif' */
|
||||
# pragma warning(disable: 4668)
|
||||
/* <type>: <num> bytes padding after data member <member> */
|
||||
# pragma warning(disable: 4820)
|
||||
|
||||
/* warning C4100: <name> was declared deprecated */
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
|
@ -113,9 +119,5 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IO_H
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <platform.h>
|
||||
#include <config.h>
|
||||
#include "reports.h"
|
||||
|
||||
|
|
13
src/tests.c
13
src/tests.c
|
@ -14,6 +14,7 @@
|
|||
#include <kernel/spell.h>
|
||||
#include <kernel/spellbook.h>
|
||||
#include <kernel/terrain.h>
|
||||
#include <kernel/messages.h>
|
||||
#include <util/functions.h>
|
||||
#include <util/language.h>
|
||||
#include <util/message.h>
|
||||
|
@ -82,14 +83,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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <platform.h>
|
||||
#include <CuTest.h>
|
||||
#include "unicode.h"
|
||||
#include <stdlib.h>
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include <config.h>
|
||||
#include <platform.h>
|
||||
#include "vortex.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue