Merge branch 'master' into develop

This commit is contained in:
Enno Rehling 2016-12-16 17:31:59 +01:00
commit ceacec8115
9 changed files with 97 additions and 28 deletions

View File

@ -128,7 +128,7 @@ bool is_guard(const struct unit * u)
unit *is_guarded(region * r, unit * u) unit *is_guarded(region * r, unit * u)
{ {
unit *u2; unit *u2;
int noguards = 1; bool noguards = true;
if (!fval(r, RF_GUARDED)) { if (!fval(r, RF_GUARDED)) {
return NULL; return NULL;
@ -140,7 +140,7 @@ unit *is_guarded(region * r, unit * u)
for (u2 = r->units; u2; u2 = u2->next) { for (u2 = r->units; u2; u2 = u2->next) {
if (is_guardian_r(u2)) { if (is_guardian_r(u2)) {
noguards = 0; noguards = false;
if (is_guardian_u(u2, u)) { if (is_guardian_u(u2, u)) {
/* u2 is our guard. stop processing (we might have to go further next time) */ /* u2 is our guard. stop processing (we might have to go further next time) */
return u2; return u2;

View File

@ -14,7 +14,7 @@
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
const attrib_type at_lighthouse = { attrib_type at_lighthouse = {
"lighthouse" "lighthouse"
/* Rest ist NULL; tempor<6F>res, nicht alterndes Attribut */ /* Rest ist NULL; tempor<6F>res, nicht alterndes Attribut */
}; };

View File

@ -29,7 +29,7 @@ extern "C" {
struct building; struct building;
struct attrib; struct attrib;
extern const struct attrib_type at_lighthouse; extern struct attrib_type at_lighthouse;
/* leuchtturm */ /* leuchtturm */
bool check_leuchtturm(struct region *r, struct faction *f); bool check_leuchtturm(struct region *r, struct faction *f);
void update_lighthouse(struct building *lh); void update_lighthouse(struct building *lh);

View File

@ -571,7 +571,7 @@ direction_t reldirection(const region * from, const region * to)
return NODIRECTION; return NODIRECTION;
} }
static void leave_trail(ship * sh, region * from, region_list * route) void leave_trail(ship * sh, region * from, region_list * route)
{ {
region *r = from; region *r = from;
@ -595,7 +595,7 @@ static void leave_trail(ship * sh, region * from, region_list * route)
a = a->next; a = a->next;
} }
if (a == NULL) { if (a == NULL || a->type != &at_shiptrail) {
a = a_add(&(r->attribs), a_new(&at_shiptrail)); a = a_add(&(r->attribs), a_new(&at_shiptrail));
td = (traveldir *)a->data.v; td = (traveldir *)a->data.v;
td->no = sh->no; td->no = sh->no;

View File

@ -63,6 +63,8 @@ extern "C" {
int enoughsailors(const struct ship *sh, int sumskill); int enoughsailors(const struct ship *sh, int sumskill);
bool canswim(struct unit *u); bool canswim(struct unit *u);
bool canfly(struct unit *u); bool canfly(struct unit *u);
void leave_trail(struct ship *sh, struct region *from,
struct region_list *route);
struct ship *move_ship(struct ship *sh, struct region *from, struct ship *move_ship(struct ship *sh, struct region *from,
struct region *to, struct region_list *route); struct region *to, struct region_list *route);
int walkingcapacity(const struct unit *u); int walkingcapacity(const struct unit *u);

View File

@ -3,6 +3,7 @@
#include "move.h" #include "move.h"
#include "keyword.h" #include "keyword.h"
#include "lighthouse.h"
#include <kernel/config.h> #include <kernel/config.h>
#include <kernel/ally.h> #include <kernel/ally.h>
@ -478,7 +479,7 @@ static void test_drifting_ships(CuTest *tc) {
region *r1, *r2, *r3; region *r1, *r2, *r3;
terrain_type *t_ocean, *t_plain; terrain_type *t_ocean, *t_plain;
ship_type *st_boat; ship_type *st_boat;
test_cleanup(); test_setup();
t_ocean = test_create_terrain("ocean", SEA_REGION); t_ocean = test_create_terrain("ocean", SEA_REGION);
t_plain = test_create_terrain("plain", LAND_REGION); t_plain = test_create_terrain("plain", LAND_REGION);
r1 = test_create_region(0, 0, t_ocean); r1 = test_create_region(0, 0, t_ocean);
@ -491,11 +492,41 @@ static void test_drifting_ships(CuTest *tc) {
test_cleanup(); test_cleanup();
} }
static void test_ship_leave_trail(CuTest *tc) {
ship *s1, *s2;
region *r1, *r2;
terrain_type *t_ocean;
ship_type *st_boat;
region_list *route = NULL;
test_setup();
t_ocean = test_create_terrain("ocean", SEA_REGION);
r1 = test_create_region(0, 0, t_ocean);
add_regionlist(&route, test_create_region(2, 0, t_ocean));
add_regionlist(&route, r2 = test_create_region(1, 0, t_ocean));
st_boat = test_create_shiptype("boat");
s1 = test_create_ship(r1, st_boat);
s2 = test_create_ship(r1, st_boat);
leave_trail(s1, r1, route);
a_add(&r1->attribs, a_new(&at_lighthouse));
leave_trail(s2, r1, route);
a_add(&r2->attribs, a_new(&at_lighthouse));
CuAssertPtrEquals(tc, &at_shiptrail, (void *)r1->attribs->type);
CuAssertPtrEquals(tc, &at_shiptrail, (void *)r1->attribs->next->type);
CuAssertPtrEquals(tc, &at_lighthouse, (void *)r1->attribs->next->next->type);
CuAssertPtrEquals(tc, &at_shiptrail, (void *)r2->attribs->type);
CuAssertPtrEquals(tc, &at_shiptrail, (void *)r2->attribs->next->type);
CuAssertPtrEquals(tc, &at_lighthouse, (void *)r2->attribs->next->next->type);
free_regionlist(route);
test_cleanup();
}
CuSuite *get_move_suite(void) CuSuite *get_move_suite(void)
{ {
CuSuite *suite = CuSuiteNew(); CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_walkingcapacity); SUITE_ADD_TEST(suite, test_walkingcapacity);
SUITE_ADD_TEST(suite, test_ship_not_allowed_in_coast); SUITE_ADD_TEST(suite, test_ship_not_allowed_in_coast);
SUITE_ADD_TEST(suite, test_ship_leave_trail);
SUITE_ADD_TEST(suite, test_ship_allowed_without_harbormaster); SUITE_ADD_TEST(suite, test_ship_allowed_without_harbormaster);
SUITE_ADD_TEST(suite, test_ship_blocked_by_harbormaster); SUITE_ADD_TEST(suite, test_ship_blocked_by_harbormaster);
SUITE_ADD_TEST(suite, test_ship_has_harbormaster_contact); SUITE_ADD_TEST(suite, test_ship_has_harbormaster_contact);

View File

@ -53,6 +53,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <util/rng.h> #include <util/rng.h>
#include <util/umlaut.h> #include <util/umlaut.h>
#include <quicklist.h>
/* libc includes */ /* libc includes */
#include <assert.h> #include <assert.h>
#include <limits.h> #include <limits.h>
@ -216,24 +218,11 @@ teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
n = _min(n, nteaching); n = _min(n, nteaching);
if (n != 0) { if (n != 0) {
int index = 0;
if (teach == NULL) { if (teach == NULL) {
a = a_add(&student->attribs, a_new(&at_learning)); a = a_add(&student->attribs, a_new(&at_learning));
teach = (teaching_info *)a->data.v; teach = (teaching_info *)a->data.v;
} }
else { ql_push(&teach->teachers, teacher);
while (teach->teachers[index] && index != MAXTEACHERS)
++index;
}
if (index < MAXTEACHERS)
teach->teachers[index++] = teacher;
if (index < MAXTEACHERS) {
teach->teachers[index] = NULL;
}
else {
log_error("MAXTEACHERS=%d is too low for student %s, teacher %s", MAXTEACHERS, unitname(student), unitname(teacher));
}
teach->value += n; teach->value += n;
if (student->building && teacher->building == student->building) { if (student->building && teacher->building == student->building) {
@ -717,7 +706,7 @@ int study_cmd(unit * u, order * ord)
a = a_add(&u->attribs, a_new(&at_learning)); a = a_add(&u->attribs, a_new(&at_learning));
teach = (teaching_info *)a->data.v; teach = (teaching_info *)a->data.v;
assert(teach); assert(teach);
teach->teachers[0] = 0; teach->teachers = NULL;
} }
if (money > 0) { if (money > 0) {
use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, money); use_pooled(u, get_resourcetype(R_SILVER), GET_DEFAULT, money);
@ -766,9 +755,9 @@ int study_cmd(unit * u, order * ord)
learn_skill(u, sk, days); learn_skill(u, sk, days);
if (a != NULL) { if (a != NULL) {
int index = 0; ql_iter qli = qli_init(&teach->teachers);
while (teach->teachers[index] && index != MAXTEACHERS) { while (qli_more(qli)) {
unit *teacher = teach->teachers[index++]; unit *teacher = (unit *)qli_next(&qli);
if (teacher->faction != u->faction) { if (teacher->faction != u->faction) {
bool feedback = alliedunit(u, teacher->faction, HELP_GUARD); bool feedback = alliedunit(u, teacher->faction, HELP_GUARD);
if (feedback) { if (feedback) {

View File

@ -27,6 +27,7 @@ extern "C" {
#endif #endif
struct unit; struct unit;
struct quicklist;
int teach_cmd(struct unit *u, struct order *ord); int teach_cmd(struct unit *u, struct order *ord);
int study_cmd(struct unit *u, struct order *ord); int study_cmd(struct unit *u, struct order *ord);
@ -45,10 +46,9 @@ extern "C" {
void demon_skillchange(struct unit *u); void demon_skillchange(struct unit *u);
#define MAXTEACHERS 32
#define TEACHNUMBER 10 #define TEACHNUMBER 10
typedef struct teaching_info { typedef struct teaching_info {
struct unit *teachers[MAXTEACHERS]; struct quicklist *teachers;
int value; int value;
} teaching_info; } teaching_info;

View File

@ -2,6 +2,7 @@
#include "study.h" #include "study.h"
#include <kernel/ally.h>
#include <kernel/config.h> #include <kernel/config.h>
#include <kernel/building.h> #include <kernel/building.h>
#include <kernel/faction.h> #include <kernel/faction.h>
@ -10,15 +11,18 @@
#include <kernel/race.h> #include <kernel/race.h>
#include <kernel/region.h> #include <kernel/region.h>
#include <kernel/unit.h> #include <kernel/unit.h>
#include <util/attrib.h>
#include <util/rand.h> #include <util/rand.h>
#include <util/message.h> #include <util/message.h>
#include <util/language.h> #include <util/language.h>
#include <util/base36.h> #include <util/base36.h>
#include <tests.h> #include <tests.h>
#include <CuTest.h>
#include <quicklist.h>
#include <assert.h> #include <assert.h>
#include <CuTest.h>
#define MAXLOG 4 #define MAXLOG 4
typedef struct log_entry { typedef struct log_entry {
@ -483,6 +487,7 @@ static void test_teach_one_to_many(CuTest *tc) {
static void test_teach_many_to_one(CuTest *tc) { static void test_teach_many_to_one(CuTest *tc) {
unit *u, *u1, *u2; unit *u, *u1, *u2;
test_setup(); test_setup();
init_resources(); init_resources();
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0)); u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
@ -505,6 +510,47 @@ static void test_teach_many_to_one(CuTest *tc) {
test_cleanup(); test_cleanup();
} }
static void test_teach_message(CuTest *tc) {
unit *u, *u1, *u2;
attrib *a;
ally *al;
teaching_info *teach;
test_setup();
init_resources();
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
scale_number(u, 20);
u->thisorder = create_order(K_STUDY, u->faction->locale, "CROSSBOW");
u1 = test_create_unit(test_create_faction(0), u->region);
set_level(u1, SK_CROSSBOW, TEACHDIFFERENCE);
u1->thisorder = create_order(K_TEACH, u->faction->locale, itoa36(u->no));
u2 = test_create_unit(test_create_faction(0), u->region);
al = ally_add(&u->faction->allies, u2->faction);
al->status = HELP_GUARD;
set_level(u2, SK_CROSSBOW, TEACHDIFFERENCE);
u2->thisorder = create_order(K_TEACH, u->faction->locale, itoa36(u->no));
CuAssertTrue(tc, !alliedunit(u, u1->faction, HELP_GUARD));
CuAssertTrue(tc, alliedunit(u, u2->faction, HELP_GUARD));
teach_cmd(u1, u1->thisorder);
teach_cmd(u2, u2->thisorder);
a = a_find(u->attribs, &at_learning);
CuAssertPtrNotNull(tc, a);
CuAssertPtrNotNull(tc, a->data.v);
teach = (teaching_info *)a->data.v;
CuAssertPtrNotNull(tc, teach->teachers);
CuAssertIntEquals(tc, 600, teach->value);
CuAssertIntEquals(tc, 2, ql_length(teach->teachers));
CuAssertPtrEquals(tc, u1, ql_get(teach->teachers, 0));
CuAssertPtrEquals(tc, u2, ql_get(teach->teachers, 1));
study_cmd(u, u->thisorder);
CuAssertPtrEquals(tc, NULL, test_find_messagetype(u1->faction->msgs, "teach_teacher"));
CuAssertPtrNotNull(tc, test_find_messagetype(u2->faction->msgs, "teach_teacher"));
CuAssertPtrNotNull(tc, test_find_messagetype(u->faction->msgs, "teach_student"));
a = a_find(u->attribs, &at_learning);
CuAssertPtrEquals(tc, NULL, a);
test_cleanup();
}
static void test_teach_many_to_many(CuTest *tc) { static void test_teach_many_to_many(CuTest *tc) {
unit *s1, *s2, *t1, *t2; unit *s1, *s2, *t1, *t2;
region *r; region *r;
@ -554,6 +600,7 @@ CuSuite *get_study_suite(void)
SUITE_ADD_TEST(suite, test_teach_one_to_many); SUITE_ADD_TEST(suite, test_teach_one_to_many);
SUITE_ADD_TEST(suite, test_teach_many_to_one); SUITE_ADD_TEST(suite, test_teach_many_to_one);
SUITE_ADD_TEST(suite, test_teach_many_to_many); SUITE_ADD_TEST(suite, test_teach_many_to_many);
SUITE_ADD_TEST(suite, test_teach_message);
SUITE_ADD_TEST(suite, test_teach_two_skills); SUITE_ADD_TEST(suite, test_teach_two_skills);
SUITE_ADD_TEST(suite, test_learn_skill_single); SUITE_ADD_TEST(suite, test_learn_skill_single);
SUITE_ADD_TEST(suite, test_learn_skill_multi); SUITE_ADD_TEST(suite, test_learn_skill_multi);