forked from github/server
Merge branch 'master' into hotfix/3_10_5
This commit is contained in:
commit
6eded43ce9
|
@ -128,7 +128,7 @@ bool is_guard(const struct unit * u)
|
|||
unit *is_guarded(region * r, unit * u)
|
||||
{
|
||||
unit *u2;
|
||||
int noguards = 1;
|
||||
bool noguards = true;
|
||||
|
||||
if (!fval(r, RF_GUARDED)) {
|
||||
return NULL;
|
||||
|
@ -140,7 +140,7 @@ unit *is_guarded(region * r, unit * u)
|
|||
|
||||
for (u2 = r->units; u2; u2 = u2->next) {
|
||||
if (is_guardian_r(u2)) {
|
||||
noguards = 0;
|
||||
noguards = false;
|
||||
if (is_guardian_u(u2, u)) {
|
||||
/* u2 is our guard. stop processing (we might have to go further next time) */
|
||||
return u2;
|
||||
|
|
|
@ -369,10 +369,3 @@ void register_race_description_function(race_desc_func func, const char *name) {
|
|||
void register_race_name_function(race_name_func func, const char *name) {
|
||||
register_function((pf_generic)func, name);
|
||||
}
|
||||
|
||||
char * race_namegen(const struct race *rc, struct unit *u) {
|
||||
if (rc->generate_name) {
|
||||
rc->generate_name(u);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -252,7 +252,6 @@ extern "C" {
|
|||
const char *raceprefix(const struct unit *u);
|
||||
void register_race_name_function(race_name_func, const char *);
|
||||
void register_race_description_function(race_desc_func, const char *);
|
||||
char * race_namegen(const struct race *rc, struct unit *u);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1480,15 +1480,9 @@ void default_name(const unit *u, char name[], int len) {
|
|||
|
||||
void name_unit(unit * u)
|
||||
{
|
||||
if (u_race(u)->generate_name) {
|
||||
char *gen_name = race_namegen(u_race(u), u);
|
||||
if (gen_name) {
|
||||
free(u->_name);
|
||||
u->_name = gen_name;
|
||||
}
|
||||
else {
|
||||
unit_setname(u, racename(u->faction->locale, u, u_race(u)));
|
||||
}
|
||||
const race *rc = u_race(u);
|
||||
if (rc->generate_name) {
|
||||
rc->generate_name(u);
|
||||
}
|
||||
else {
|
||||
char name[32];
|
||||
|
|
|
@ -468,6 +468,24 @@ static void test_renumber_unit(CuTest *tc) {
|
|||
test_cleanup();
|
||||
}
|
||||
|
||||
static void gen_name(unit *u)
|
||||
{
|
||||
unit_setname(u, "Hodor");
|
||||
}
|
||||
|
||||
static void test_name_unit(CuTest *tc) {
|
||||
race *rc;
|
||||
unit * u;
|
||||
|
||||
test_setup();
|
||||
rc = test_create_race("skeleton");
|
||||
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
|
||||
rc->generate_name = gen_name;
|
||||
name_unit(u);
|
||||
CuAssertStrEquals(tc, "Hodor", unit_getname(u));
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
CuSuite *get_unit_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
@ -491,5 +509,6 @@ CuSuite *get_unit_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_inside_building);
|
||||
SUITE_ADD_TEST(suite, test_limited_skills);
|
||||
SUITE_ADD_TEST(suite, test_renumber_unit);
|
||||
SUITE_ADD_TEST(suite, test_name_unit);
|
||||
return suite;
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
const attrib_type at_lighthouse = {
|
||||
attrib_type at_lighthouse = {
|
||||
"lighthouse"
|
||||
/* Rest ist NULL; tempor<6F>res, nicht alterndes Attribut */
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
struct building;
|
||||
struct attrib;
|
||||
|
||||
extern const struct attrib_type at_lighthouse;
|
||||
extern struct attrib_type at_lighthouse;
|
||||
/* leuchtturm */
|
||||
bool check_leuchtturm(struct region *r, struct faction *f);
|
||||
void update_lighthouse(struct building *lh);
|
||||
|
|
|
@ -571,7 +571,7 @@ direction_t reldirection(const region * from, const region * to)
|
|||
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;
|
||||
|
||||
|
@ -595,7 +595,7 @@ static void leave_trail(ship * sh, region * from, region_list * route)
|
|||
a = a->next;
|
||||
}
|
||||
|
||||
if (a == NULL) {
|
||||
if (a == NULL || a->type != &at_shiptrail) {
|
||||
a = a_add(&(r->attribs), a_new(&at_shiptrail));
|
||||
td = (traveldir *)a->data.v;
|
||||
td->no = sh->no;
|
||||
|
|
|
@ -63,6 +63,8 @@ extern "C" {
|
|||
int enoughsailors(const struct ship *sh, int sumskill);
|
||||
bool canswim(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 region *to, struct region_list *route);
|
||||
int walkingcapacity(const struct unit *u);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "move.h"
|
||||
|
||||
#include "keyword.h"
|
||||
#include "lighthouse.h"
|
||||
|
||||
#include <kernel/config.h>
|
||||
#include <kernel/ally.h>
|
||||
|
@ -478,7 +479,7 @@ static void test_drifting_ships(CuTest *tc) {
|
|||
region *r1, *r2, *r3;
|
||||
terrain_type *t_ocean, *t_plain;
|
||||
ship_type *st_boat;
|
||||
test_cleanup();
|
||||
test_setup();
|
||||
t_ocean = test_create_terrain("ocean", SEA_REGION);
|
||||
t_plain = test_create_terrain("plain", LAND_REGION);
|
||||
r1 = test_create_region(0, 0, t_ocean);
|
||||
|
@ -491,11 +492,41 @@ static void test_drifting_ships(CuTest *tc) {
|
|||
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 *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_walkingcapacity);
|
||||
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_blocked_by_harbormaster);
|
||||
SUITE_ADD_TEST(suite, test_ship_has_harbormaster_contact);
|
||||
|
|
|
@ -221,11 +221,7 @@ const char *silbe3[SIL3] = {
|
|||
|
||||
static void generic_name(unit * u)
|
||||
{
|
||||
const char * name = rc_name_s(u_race(u), (u->number == 1) ? NAME_SINGULAR : NAME_PLURAL);
|
||||
name = LOC(u->faction->locale, name);
|
||||
if (name) {
|
||||
unit_setname(u, name);
|
||||
}
|
||||
unit_setname(u, NULL);
|
||||
}
|
||||
|
||||
static void dragon_name(unit * u)
|
||||
|
|
|
@ -24,7 +24,7 @@ static void test_names(CuTest * tc)
|
|||
locale_setstring(default_locale, "undead_postfix_0", "Kobolde");
|
||||
CuAssertPtrNotNull(tc, foo = (race_name_func)get_function("nameundead"));
|
||||
rc->generate_name = foo;
|
||||
race_namegen(rc, u);
|
||||
rc->generate_name(u);
|
||||
CuAssertStrEquals(tc, "Graue Kobolde", u->_name);
|
||||
CuAssertPtrNotNull(tc, get_function("nameskeleton"));
|
||||
CuAssertPtrNotNull(tc, get_function("namezombie"));
|
||||
|
@ -36,9 +36,31 @@ static void test_names(CuTest * tc)
|
|||
test_cleanup();
|
||||
}
|
||||
|
||||
static void test_monster_names(CuTest *tc) {
|
||||
unit *u;
|
||||
race *rc;
|
||||
|
||||
test_setup();
|
||||
register_names();
|
||||
default_locale = test_create_locale();
|
||||
locale_setstring(default_locale, "race::irongolem", "Eisengolem");
|
||||
locale_setstring(default_locale, "race::irongolem_p", "Eisengolems");
|
||||
rc = test_create_race("irongolem");
|
||||
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
|
||||
CuAssertPtrNotNull(tc, u->_name);
|
||||
rc->generate_name = (race_name_func)get_function("namegeneric");
|
||||
rc->generate_name(u);
|
||||
CuAssertPtrEquals(tc, 0, u->_name);
|
||||
CuAssertStrEquals(tc, "Eisengolem", unit_getname(u));
|
||||
u->number = 2;
|
||||
CuAssertStrEquals(tc, "Eisengolems", unit_getname(u));
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
CuSuite *get_names_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_names);
|
||||
SUITE_ADD_TEST(suite, test_monster_names);
|
||||
return suite;
|
||||
}
|
||||
|
|
25
src/study.c
25
src/study.c
|
@ -53,6 +53,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <util/rng.h>
|
||||
#include <util/umlaut.h>
|
||||
|
||||
#include <quicklist.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
@ -216,24 +218,11 @@ teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
|
|||
n = _min(n, nteaching);
|
||||
|
||||
if (n != 0) {
|
||||
int index = 0;
|
||||
|
||||
if (teach == NULL) {
|
||||
a = a_add(&student->attribs, a_new(&at_learning));
|
||||
teach = (teaching_info *)a->data.v;
|
||||
}
|
||||
else {
|
||||
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));
|
||||
}
|
||||
ql_push(&teach->teachers, teacher);
|
||||
teach->value += n;
|
||||
|
||||
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));
|
||||
teach = (teaching_info *)a->data.v;
|
||||
assert(teach);
|
||||
teach->teachers[0] = 0;
|
||||
teach->teachers = NULL;
|
||||
}
|
||||
if (money > 0) {
|
||||
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);
|
||||
if (a != NULL) {
|
||||
int index = 0;
|
||||
while (teach->teachers[index] && index != MAXTEACHERS) {
|
||||
unit *teacher = teach->teachers[index++];
|
||||
ql_iter qli = qli_init(&teach->teachers);
|
||||
while (qli_more(qli)) {
|
||||
unit *teacher = (unit *)qli_next(&qli);
|
||||
if (teacher->faction != u->faction) {
|
||||
bool feedback = alliedunit(u, teacher->faction, HELP_GUARD);
|
||||
if (feedback) {
|
||||
|
|
|
@ -27,6 +27,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct unit;
|
||||
struct quicklist;
|
||||
|
||||
int teach_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);
|
||||
|
||||
#define MAXTEACHERS 64
|
||||
#define TEACHNUMBER 10
|
||||
typedef struct teaching_info {
|
||||
struct unit *teachers[MAXTEACHERS];
|
||||
struct quicklist *teachers;
|
||||
int value;
|
||||
} teaching_info;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "study.h"
|
||||
|
||||
#include <kernel/ally.h>
|
||||
#include <kernel/config.h>
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/faction.h>
|
||||
|
@ -10,15 +11,18 @@
|
|||
#include <kernel/race.h>
|
||||
#include <kernel/region.h>
|
||||
#include <kernel/unit.h>
|
||||
#include <util/attrib.h>
|
||||
#include <util/rand.h>
|
||||
#include <util/message.h>
|
||||
#include <util/language.h>
|
||||
#include <util/base36.h>
|
||||
#include <tests.h>
|
||||
|
||||
#include <CuTest.h>
|
||||
#include <quicklist.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <CuTest.h>
|
||||
|
||||
#define MAXLOG 4
|
||||
typedef struct log_entry {
|
||||
|
@ -511,6 +515,7 @@ static void test_teach_one_to_many(CuTest *tc) {
|
|||
|
||||
static void test_teach_many_to_one(CuTest *tc) {
|
||||
unit *u, *u1, *u2;
|
||||
|
||||
test_setup();
|
||||
init_resources();
|
||||
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||
|
@ -533,6 +538,47 @@ static void test_teach_many_to_one(CuTest *tc) {
|
|||
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) {
|
||||
unit *s1, *s2, *t1, *t2;
|
||||
region *r;
|
||||
|
@ -583,6 +629,7 @@ CuSuite *get_study_suite(void)
|
|||
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_many);
|
||||
SUITE_ADD_TEST(suite, test_teach_message);
|
||||
SUITE_ADD_TEST(suite, test_teach_two_skills);
|
||||
SUITE_ADD_TEST(suite, test_learn_skill_single);
|
||||
SUITE_ADD_TEST(suite, test_learn_skill_multi);
|
||||
|
|
Loading…
Reference in New Issue