forked from github/server
Merge pull request #731 from ennorehling/develop
BUG 2367, 2368: familiars
This commit is contained in:
commit
0ca0543c6e
2
clibs
2
clibs
|
@ -1 +1 @@
|
||||||
Subproject commit da2c0cc39b27c98ed8d31b0503426788fc236bd8
|
Subproject commit 147584ad70b220abf6a4e97ca76e785729b9ac32
|
|
@ -273,7 +273,7 @@ static int tolua_unit_set_guard(lua_State * L)
|
||||||
|
|
||||||
static const char *unit_getmagic(const unit * u)
|
static const char *unit_getmagic(const unit * u)
|
||||||
{
|
{
|
||||||
sc_mage *mage = get_mage(u);
|
sc_mage *mage = get_mage_depr(u);
|
||||||
return mage ? magic_school[mage->magietyp] : NULL;
|
return mage ? magic_school[mage->magietyp] : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ static int tolua_unit_get_magic(lua_State * L)
|
||||||
|
|
||||||
static void unit_setmagic(unit * u, const char *type)
|
static void unit_setmagic(unit * u, const char *type)
|
||||||
{
|
{
|
||||||
sc_mage *mage = get_mage(u);
|
sc_mage *mage = get_mage_depr(u);
|
||||||
int mtype;
|
int mtype;
|
||||||
for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) {
|
for (mtype = 0; mtype != MAXMAGIETYP; ++mtype) {
|
||||||
if (strcmp(magic_school[mtype], type) == 0)
|
if (strcmp(magic_school[mtype], type) == 0)
|
||||||
|
@ -638,8 +638,14 @@ static int tolua_unit_get_familiar(lua_State * L)
|
||||||
|
|
||||||
static int tolua_unit_set_familiar(lua_State * L)
|
static int tolua_unit_set_familiar(lua_State * L)
|
||||||
{
|
{
|
||||||
unit *self = (unit *)tolua_tousertype(L, 1, 0);
|
unit *mag = (unit *)tolua_tousertype(L, 1, NULL);
|
||||||
create_newfamiliar(self, (unit *)tolua_tousertype(L, 2, 0));
|
unit *fam = (unit *)tolua_tousertype(L, 2, NULL);
|
||||||
|
if (fam) {
|
||||||
|
set_familiar(mag, fam);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
remove_familiar(mag);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,7 +753,7 @@ static int tolua_unit_get_items(lua_State * L)
|
||||||
static int tolua_unit_get_spells(lua_State * L)
|
static int tolua_unit_get_spells(lua_State * L)
|
||||||
{
|
{
|
||||||
unit *self = (unit *) tolua_tousertype(L, 1, 0);
|
unit *self = (unit *) tolua_tousertype(L, 1, 0);
|
||||||
sc_mage *mage = self ? get_mage(self) : 0;
|
sc_mage *mage = self ? get_mage_depr(self) : 0;
|
||||||
spellbook *sb = mage ? mage->spellbook : 0;
|
spellbook *sb = mage ? mage->spellbook : 0;
|
||||||
selist *slist = 0;
|
selist *slist = 0;
|
||||||
if (sb) {
|
if (sb) {
|
||||||
|
|
|
@ -954,7 +954,7 @@ void cr_output_unit(stream *out, const region * r, const faction * f,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* spells that this unit can cast */
|
/* spells that this unit can cast */
|
||||||
mage = get_mage(u);
|
mage = get_mage_depr(u);
|
||||||
if (mage) {
|
if (mage) {
|
||||||
int i, maxlevel = effskill(u, SK_MAGIC, 0);
|
int i, maxlevel = effskill(u, SK_MAGIC, 0);
|
||||||
cr_output_spells(out, u, maxlevel);
|
cr_output_spells(out, u, maxlevel);
|
||||||
|
|
|
@ -591,7 +591,7 @@ void give_unit(unit * u, unit * u2, order * ord)
|
||||||
cmistake(u, ord, 155, MSG_COMMERCE);
|
cmistake(u, ord, 155, MSG_COMMERCE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mage = get_mage(u);
|
mage = get_mage_depr(u);
|
||||||
if (!mage || u2->faction->magiegebiet != mage->magietyp) {
|
if (!mage || u2->faction->magiegebiet != mage->magietyp) {
|
||||||
cmistake(u, ord, 157, MSG_COMMERCE);
|
cmistake(u, ord, 157, MSG_COMMERCE);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -121,7 +121,7 @@ void equip_unit_mask(struct unit *u, const struct equipment *eq, int mask)
|
||||||
if (eq->spells) {
|
if (eq->spells) {
|
||||||
selist * ql = eq->spells;
|
selist * ql = eq->spells;
|
||||||
int qi;
|
int qi;
|
||||||
sc_mage * mage = get_mage(u);
|
sc_mage * mage = get_mage_depr(u);
|
||||||
|
|
||||||
for (qi = 0; ql; selist_advance(&ql, &qi, 1)) {
|
for (qi = 0; ql; selist_advance(&ql, &qi, 1)) {
|
||||||
lazy_spell *sbe = (lazy_spell *)selist_get(ql, qi);
|
lazy_spell *sbe = (lazy_spell *)selist_get(ql, qi);
|
||||||
|
|
|
@ -39,7 +39,7 @@ static void test_equipment(CuTest * tc)
|
||||||
CuAssertIntEquals(tc, 1, i_get(u->items, it_horses));
|
CuAssertIntEquals(tc, 1, i_get(u->items, it_horses));
|
||||||
CuAssertIntEquals(tc, 5, get_level(u, SK_MAGIC));
|
CuAssertIntEquals(tc, 5, get_level(u, SK_MAGIC));
|
||||||
|
|
||||||
mage = get_mage(u);
|
mage = get_mage_depr(u);
|
||||||
CuAssertPtrNotNull(tc, mage);
|
CuAssertPtrNotNull(tc, mage);
|
||||||
CuAssertPtrNotNull(tc, mage->spellbook);
|
CuAssertPtrNotNull(tc, mage->spellbook);
|
||||||
CuAssertTrue(tc, u_hasspell(u, sp));
|
CuAssertTrue(tc, u_hasspell(u, sp));
|
||||||
|
|
|
@ -83,7 +83,7 @@ struct message *msg_feedback(const struct unit *u, struct order *ord,
|
||||||
variant var;
|
variant var;
|
||||||
memset(args, 0, sizeof(args));
|
memset(args, 0, sizeof(args));
|
||||||
|
|
||||||
if (ord && ord->_noerror) {
|
if (ord && is_silent(ord)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,8 +79,8 @@ static void test_noerror(CuTest *tc) {
|
||||||
lang = test_create_locale();
|
lang = test_create_locale();
|
||||||
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
|
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
|
||||||
u->thisorder = parse_order("!@move", lang);
|
u->thisorder = parse_order("!@move", lang);
|
||||||
CuAssertTrue(tc, u->thisorder->_persistent);
|
CuAssertIntEquals(tc, K_MOVE | CMD_QUIET | CMD_PERSIST, u->thisorder->command);
|
||||||
CuAssertTrue(tc, u->thisorder->_noerror);
|
CuAssertTrue(tc, !is_persistent(u->thisorder));
|
||||||
CuAssertPtrEquals(tc, NULL, msg_error(u, u->thisorder, 100));
|
CuAssertPtrEquals(tc, NULL, msg_error(u, u->thisorder, 100));
|
||||||
CuAssertPtrEquals(tc, NULL, msg_feedback(u, u->thisorder, "error_unit_not_found", NULL));
|
CuAssertPtrEquals(tc, NULL, msg_feedback(u, u->thisorder, "error_unit_not_found", NULL));
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
|
|
@ -30,12 +30,12 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
# define ORD_KEYWORD(ord) (ord)->data->_keyword
|
# define ORD_KEYWORD(ord) (keyword_t)((ord)->command & 0xFFFF)
|
||||||
# define ORD_LOCALE(ord) locale_array[(ord)->data->_lindex]->lang
|
# define ORD_LOCALE(ord) locale_array[(ord)->data->_lindex]->lang
|
||||||
# define ORD_STRING(ord) (ord)->data->_str
|
# define ORD_STRING(ord) (ord)->data->_str
|
||||||
|
|
||||||
typedef struct locale_data {
|
typedef struct locale_data {
|
||||||
struct order_data *short_orders[MAXKEYWORDS];
|
struct order_data *short_orders;
|
||||||
struct order_data *study_orders[MAXSKILLS];
|
struct order_data *study_orders[MAXSKILLS];
|
||||||
const struct locale *lang;
|
const struct locale *lang;
|
||||||
} locale_data;
|
} locale_data;
|
||||||
|
@ -46,7 +46,6 @@ typedef struct order_data {
|
||||||
const char *_str;
|
const char *_str;
|
||||||
int _refcount;
|
int _refcount;
|
||||||
int _lindex;
|
int _lindex;
|
||||||
keyword_t _keyword;
|
|
||||||
} order_data;
|
} order_data;
|
||||||
|
|
||||||
static void release_data(order_data * data)
|
static void release_data(order_data * data)
|
||||||
|
@ -94,7 +93,7 @@ char* get_command(const order *ord, char *sbuffer, size_t size) {
|
||||||
keyword_t kwd = ORD_KEYWORD(ord);
|
keyword_t kwd = ORD_KEYWORD(ord);
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
if (ord->_noerror) {
|
if (ord->command & CMD_QUIET) {
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
*bufp++ = '!';
|
*bufp++ = '!';
|
||||||
--size;
|
--size;
|
||||||
|
@ -103,7 +102,7 @@ char* get_command(const order *ord, char *sbuffer, size_t size) {
|
||||||
WARN_STATIC_BUFFER();
|
WARN_STATIC_BUFFER();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ord->_persistent) {
|
if (ord->command & CMD_PERSIST) {
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
*bufp++ = '@';
|
*bufp++ = '@';
|
||||||
--size;
|
--size;
|
||||||
|
@ -162,8 +161,7 @@ order *copy_order(const order * src)
|
||||||
if (src != NULL) {
|
if (src != NULL) {
|
||||||
order *ord = (order *)malloc(sizeof(order));
|
order *ord = (order *)malloc(sizeof(order));
|
||||||
ord->next = NULL;
|
ord->next = NULL;
|
||||||
ord->_persistent = src->_persistent;
|
ord->command = src->command;
|
||||||
ord->_noerror = src->_noerror;
|
|
||||||
ord->data = src->data;
|
ord->data = src->data;
|
||||||
++ord->data->_refcount;
|
++ord->data->_refcount;
|
||||||
return ord;
|
return ord;
|
||||||
|
@ -189,13 +187,12 @@ void free_orders(order ** olist)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *mkdata(order_data **pdata, size_t len, keyword_t kwd, int lindex, const char *str)
|
static char *mkdata(order_data **pdata, size_t len, int lindex, const char *str)
|
||||||
{
|
{
|
||||||
order_data *data;
|
order_data *data;
|
||||||
char *result;
|
char *result;
|
||||||
data = malloc(sizeof(order_data) + len + 1);
|
data = malloc(sizeof(order_data) + len + 1);
|
||||||
result = (char *)(data + 1);
|
result = (char *)(data + 1);
|
||||||
data->_keyword = kwd;
|
|
||||||
data->_lindex = lindex;
|
data->_lindex = lindex;
|
||||||
data->_refcount = 0;
|
data->_refcount = 0;
|
||||||
data->_str = 0;
|
data->_str = 0;
|
||||||
|
@ -229,7 +226,7 @@ static order_data *create_data(keyword_t kwd, const char *sptr, int lindex)
|
||||||
const char *skname = skillname(sk, lang);
|
const char *skname = skillname(sk, lang);
|
||||||
const char *spc = strchr(skname, ' ');
|
const char *spc = strchr(skname, ' ');
|
||||||
size_t len = strlen(skname);
|
size_t len = strlen(skname);
|
||||||
char *dst = mkdata(&data, len + (spc ? 3 : 0), kwd, lindex, spc ? 0 : skname);
|
char *dst = mkdata(&data, len + (spc ? 3 : 0), lindex, spc ? 0 : skname);
|
||||||
locale_array[lindex]->study_orders[sk] = data;
|
locale_array[lindex]->study_orders[sk] = data;
|
||||||
if (spc) {
|
if (spc) {
|
||||||
dst[0] = '\"';
|
dst[0] = '\"';
|
||||||
|
@ -246,26 +243,24 @@ static order_data *create_data(keyword_t kwd, const char *sptr, int lindex)
|
||||||
|
|
||||||
/* orders with no parameter, only one order_data per order required */
|
/* orders with no parameter, only one order_data per order required */
|
||||||
else if (kwd != NOKEYWORD && *sptr == 0) {
|
else if (kwd != NOKEYWORD && *sptr == 0) {
|
||||||
data = locale_array[lindex]->short_orders[kwd];
|
data = locale_array[lindex]->short_orders;
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
mkdata(&data, 0, kwd, lindex, 0);
|
mkdata(&data, 0, lindex, 0);
|
||||||
data->_refcount = 1;
|
data->_refcount = 1;
|
||||||
locale_array[lindex]->short_orders[kwd] = data;
|
locale_array[lindex]->short_orders = data;
|
||||||
}
|
}
|
||||||
++data->_refcount;
|
++data->_refcount;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
mkdata(&data, s ? strlen(s) : 0, kwd, lindex, s);
|
mkdata(&data, s ? strlen(s) : 0, lindex, s);
|
||||||
data->_refcount = 1;
|
data->_refcount = 1;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_localedata(int lindex) {
|
static void clear_localedata(int lindex) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i != MAXKEYWORDS; ++i) {
|
release_data(locale_array[lindex]->short_orders);
|
||||||
release_data(locale_array[lindex]->short_orders[i]);
|
locale_array[lindex]->short_orders = NULL;
|
||||||
locale_array[lindex]->short_orders[i] = 0;
|
|
||||||
}
|
|
||||||
for (i = 0; i != MAXSKILLS; ++i) {
|
for (i = 0; i != MAXSKILLS; ++i) {
|
||||||
release_data(locale_array[lindex]->study_orders[i]);
|
release_data(locale_array[lindex]->study_orders[i]);
|
||||||
locale_array[lindex]->study_orders[i] = 0;
|
locale_array[lindex]->study_orders[i] = 0;
|
||||||
|
@ -284,12 +279,12 @@ void close_orders(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent,
|
static order *create_order_i(order *ord, keyword_t kwd, const char *sptr, bool persistent,
|
||||||
bool noerror, const struct locale *lang)
|
bool noerror, const struct locale *lang)
|
||||||
{
|
{
|
||||||
order *ord = NULL;
|
|
||||||
int lindex;
|
int lindex;
|
||||||
|
|
||||||
|
assert(ord);
|
||||||
if (kwd == NOKEYWORD || keyword_disabled(kwd)) {
|
if (kwd == NOKEYWORD || keyword_disabled(kwd)) {
|
||||||
log_error("trying to create an order for disabled keyword %s.", keyword(kwd));
|
log_error("trying to create an order for disabled keyword %s.", keyword(kwd));
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -316,11 +311,12 @@ static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent,
|
||||||
}
|
}
|
||||||
locale_array[lindex]->lang = lang;
|
locale_array[lindex]->lang = lang;
|
||||||
|
|
||||||
ord = (order *)malloc(sizeof(order));
|
ord->command = (int)kwd;
|
||||||
ord->_persistent = persistent;
|
if (persistent) ord->command |= CMD_PERSIST;
|
||||||
ord->_noerror = noerror;
|
if (noerror) ord->command |= CMD_QUIET;
|
||||||
ord->next = NULL;
|
ord->next = NULL;
|
||||||
|
|
||||||
|
while (isspace(*(unsigned char *)sptr)) ++sptr;
|
||||||
ord->data = create_data(kwd, sptr, lindex);
|
ord->data = create_data(kwd, sptr, lindex);
|
||||||
|
|
||||||
return ord;
|
return ord;
|
||||||
|
@ -329,6 +325,7 @@ static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent,
|
||||||
order *create_order(keyword_t kwd, const struct locale * lang,
|
order *create_order(keyword_t kwd, const struct locale * lang,
|
||||||
const char *params, ...)
|
const char *params, ...)
|
||||||
{
|
{
|
||||||
|
order *ord;
|
||||||
char zBuffer[DISPLAYSIZE];
|
char zBuffer[DISPLAYSIZE];
|
||||||
if (params) {
|
if (params) {
|
||||||
char *bufp = zBuffer;
|
char *bufp = zBuffer;
|
||||||
|
@ -379,42 +376,40 @@ order *create_order(keyword_t kwd, const struct locale * lang,
|
||||||
else {
|
else {
|
||||||
zBuffer[0] = 0;
|
zBuffer[0] = 0;
|
||||||
}
|
}
|
||||||
return create_order_i(kwd, zBuffer, false, false, lang);
|
ord = (order *)malloc(sizeof(order));
|
||||||
|
return create_order_i(ord, kwd, zBuffer, false, false, lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
order *parse_order(const char *s, const struct locale * lang)
|
order *parse_order(const char *s, const struct locale * lang)
|
||||||
{
|
{
|
||||||
assert(lang);
|
assert(lang);
|
||||||
assert(s);
|
assert(s);
|
||||||
while (*s && !isalnum(*(unsigned char *)s) && !ispunct(*(unsigned char *)s)) {
|
|
||||||
++s;
|
|
||||||
}
|
|
||||||
if (*s != 0) {
|
if (*s != 0) {
|
||||||
keyword_t kwd;
|
keyword_t kwd = NOKEYWORD;
|
||||||
const char *sptr;
|
const char *sptr = s;
|
||||||
bool persistent = false, noerror = false;
|
bool persistent = false, noerror = false;
|
||||||
const char * p;
|
const char * p;
|
||||||
|
|
||||||
while (*s == '!' || *s=='@') {
|
|
||||||
if (*s=='!') noerror = true;
|
|
||||||
else if (*s == '@') persistent = true;
|
|
||||||
++s;
|
|
||||||
}
|
|
||||||
sptr = s;
|
|
||||||
p = *sptr ? parse_token_depr(&sptr) : 0;
|
p = *sptr ? parse_token_depr(&sptr) : 0;
|
||||||
kwd = p ? get_keyword(p, lang) : NOKEYWORD;
|
if (p) {
|
||||||
|
while (*p == '!' || *p == '@') {
|
||||||
|
if (*p == '!') noerror = true;
|
||||||
|
else if (*p == '@') persistent = true;
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
kwd = get_keyword(p, lang);
|
||||||
|
}
|
||||||
if (kwd == K_MAKE) {
|
if (kwd == K_MAKE) {
|
||||||
const char *s, *sp = sptr;
|
const char *sp = sptr;
|
||||||
s = parse_token_depr(&sp);
|
p = parse_token_depr(&sp);
|
||||||
if (s && isparam(s, lang, P_TEMP)) {
|
if (p && isparam(p, lang, P_TEMP)) {
|
||||||
kwd = K_MAKETEMP;
|
kwd = K_MAKETEMP;
|
||||||
sptr = sp;
|
sptr = sp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (kwd != NOKEYWORD) {
|
if (kwd != NOKEYWORD) {
|
||||||
while (isspace(*(unsigned char *)sptr)) ++sptr;
|
order *ord = (order *)malloc(sizeof(order));
|
||||||
s = sptr;
|
return create_order_i(ord, kwd, sptr, persistent, noerror, lang);
|
||||||
return create_order_i(kwd, s, persistent, noerror, lang);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -561,10 +556,15 @@ bool is_persistent(const order * ord)
|
||||||
case K_KOMMENTAR:
|
case K_KOMMENTAR:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return ord->_persistent || is_repeated(kwd);
|
return (ord->command & CMD_PERSIST) || is_repeated(kwd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_silent(const order * ord)
|
||||||
|
{
|
||||||
|
return (ord->command & CMD_QUIET) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
char *write_order(const order * ord, char *buffer, size_t size)
|
char *write_order(const order * ord, char *buffer, size_t size)
|
||||||
{
|
{
|
||||||
if (ord == 0) {
|
if (ord == 0) {
|
||||||
|
@ -595,5 +595,5 @@ keyword_t init_order(const struct order *ord)
|
||||||
{
|
{
|
||||||
assert(ord && ord->data);
|
assert(ord && ord->data);
|
||||||
init_tokens_str(ord->data->_str);
|
init_tokens_str(ord->data->_str);
|
||||||
return ord->data->_keyword;
|
return ORD_KEYWORD(ord);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,32 +32,36 @@ extern "C" {
|
||||||
|
|
||||||
struct order_data;
|
struct order_data;
|
||||||
|
|
||||||
|
#define CMD_QUIET 0x010000
|
||||||
|
#define CMD_PERSIST 0x020000
|
||||||
|
#define CMD_DEFAULT 0x040000
|
||||||
|
|
||||||
typedef struct order {
|
typedef struct order {
|
||||||
struct order *next;
|
struct order *next;
|
||||||
/* do not access this data: */
|
/* do not access this data: */
|
||||||
struct order_data *data;
|
struct order_data *data;
|
||||||
bool _persistent;
|
int command;
|
||||||
bool _noerror;
|
|
||||||
} order;
|
} order;
|
||||||
|
|
||||||
/* constructor */
|
/* constructor */
|
||||||
extern order *create_order(keyword_t kwd, const struct locale *lang,
|
order *create_order(keyword_t kwd, const struct locale *lang,
|
||||||
const char *params, ...);
|
const char *params, ...);
|
||||||
extern order *parse_order(const char *s, const struct locale *lang);
|
order *parse_order(const char *s, const struct locale *lang);
|
||||||
extern void replace_order(order ** dst, order * orig, const order * src);
|
void replace_order(order ** dst, order * orig, const order * src);
|
||||||
|
|
||||||
/* reference counted copies of orders: */
|
/* reference counted copies of orders: */
|
||||||
extern order *copy_order(const order * ord);
|
order *copy_order(const order * ord);
|
||||||
extern void free_order(order * ord);
|
void free_order(order * ord);
|
||||||
extern void free_orders(order ** olist);
|
void free_orders(order ** olist);
|
||||||
|
|
||||||
extern void push_order(struct order **olist, struct order *ord);
|
void push_order(struct order **olist, struct order *ord);
|
||||||
|
|
||||||
/* access functions for orders */
|
/* access functions for orders */
|
||||||
keyword_t getkeyword(const order * ord);
|
keyword_t getkeyword(const order * ord);
|
||||||
void set_order(order ** destp, order * src);
|
void set_order(order ** destp, order * src);
|
||||||
char* get_command(const order *ord, char *buffer, size_t size);
|
char* get_command(const order *ord, char *buffer, size_t size);
|
||||||
bool is_persistent(const order * ord);
|
bool is_persistent(const order * ord);
|
||||||
|
bool is_silent(const order * ord);
|
||||||
bool is_exclusive(const order * ord);
|
bool is_exclusive(const order * ord);
|
||||||
bool is_repeated(keyword_t kwd);
|
bool is_repeated(keyword_t kwd);
|
||||||
bool is_long(keyword_t kwd);
|
bool is_long(keyword_t kwd);
|
||||||
|
|
|
@ -38,8 +38,7 @@ static void test_parse_order(CuTest *tc) {
|
||||||
|
|
||||||
ord = parse_order("MOVE NORTH", lang);
|
ord = parse_order("MOVE NORTH", lang);
|
||||||
CuAssertPtrNotNull(tc, ord);
|
CuAssertPtrNotNull(tc, ord);
|
||||||
CuAssertTrue(tc, !ord->_noerror);
|
CuAssertIntEquals(tc, K_MOVE, ord->command);
|
||||||
CuAssertTrue(tc, !ord->_persistent);
|
|
||||||
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
CuAssertStrEquals(tc, "move NORTH", get_command(ord, cmd, sizeof(cmd)));
|
CuAssertStrEquals(tc, "move NORTH", get_command(ord, cmd, sizeof(cmd)));
|
||||||
|
|
||||||
|
@ -49,26 +48,37 @@ static void test_parse_order(CuTest *tc) {
|
||||||
|
|
||||||
ord = parse_order("!MOVE NORTH", lang);
|
ord = parse_order("!MOVE NORTH", lang);
|
||||||
CuAssertPtrNotNull(tc, ord);
|
CuAssertPtrNotNull(tc, ord);
|
||||||
CuAssertTrue(tc, ord->_noerror);
|
CuAssertPtrNotNull(tc, ord->data);
|
||||||
CuAssertTrue(tc, !ord->_persistent);
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
|
CuAssertIntEquals(tc, K_MOVE | CMD_QUIET, ord->command);
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
|
|
||||||
ord = parse_order("@MOVE NORTH", lang);
|
ord = parse_order("@MOVE NORTH", lang);
|
||||||
CuAssertPtrNotNull(tc, ord);
|
CuAssertPtrNotNull(tc, ord);
|
||||||
CuAssertTrue(tc, !ord->_noerror);
|
CuAssertPtrNotNull(tc, ord->data);
|
||||||
CuAssertTrue(tc, ord->_persistent);
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
free_order(ord);
|
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST, ord->command);
|
||||||
|
|
||||||
ord = parse_order("@!MOVE NORTH", lang);
|
|
||||||
CuAssertPtrNotNull(tc, ord);
|
|
||||||
CuAssertTrue(tc, ord->_noerror);
|
|
||||||
CuAssertTrue(tc, ord->_persistent);
|
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
|
|
||||||
ord = parse_order("!@MOVE NORTH", lang);
|
ord = parse_order("!@MOVE NORTH", lang);
|
||||||
CuAssertPtrNotNull(tc, ord);
|
CuAssertPtrNotNull(tc, ord);
|
||||||
CuAssertTrue(tc, ord->_noerror);
|
CuAssertPtrNotNull(tc, ord->data);
|
||||||
CuAssertTrue(tc, ord->_persistent);
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
|
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST | CMD_QUIET, ord->command);
|
||||||
|
free_order(ord);
|
||||||
|
|
||||||
|
ord = parse_order("@!MOVE NORTH", lang);
|
||||||
|
CuAssertPtrNotNull(tc, ord);
|
||||||
|
CuAssertPtrNotNull(tc, ord->data);
|
||||||
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
|
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST | CMD_QUIET, ord->command);
|
||||||
|
free_order(ord);
|
||||||
|
|
||||||
|
ord = parse_order(" !@MOVE NORTH", lang);
|
||||||
|
CuAssertPtrNotNull(tc, ord);
|
||||||
|
CuAssertPtrNotNull(tc, ord->data);
|
||||||
|
CuAssertIntEquals(tc, K_MOVE, getkeyword(ord));
|
||||||
|
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST | CMD_QUIET, ord->command);
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
|
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
@ -204,16 +214,84 @@ static void test_get_command(CuTest *tc) {
|
||||||
lang = test_create_locale();
|
lang = test_create_locale();
|
||||||
ord = create_order(K_MAKE, lang, "iron");
|
ord = create_order(K_MAKE, lang, "iron");
|
||||||
CuAssertStrEquals(tc, "make iron", get_command(ord, buf, sizeof(buf)));
|
CuAssertStrEquals(tc, "make iron", get_command(ord, buf, sizeof(buf)));
|
||||||
ord->_noerror = true;
|
ord->command |= CMD_QUIET;
|
||||||
CuAssertStrEquals(tc, "!make iron", get_command(ord, buf, sizeof(buf)));
|
CuAssertStrEquals(tc, "!make iron", get_command(ord, buf, sizeof(buf)));
|
||||||
ord->_persistent = true;
|
ord->command |= CMD_PERSIST;
|
||||||
CuAssertStrEquals(tc, "!@make iron", get_command(ord, buf, sizeof(buf)));
|
CuAssertStrEquals(tc, "!@make iron", get_command(ord, buf, sizeof(buf)));
|
||||||
ord->_noerror = false;
|
ord->command = K_MAKE | CMD_PERSIST;
|
||||||
CuAssertStrEquals(tc, "@make iron", get_command(ord, buf, sizeof(buf)));
|
CuAssertStrEquals(tc, "@make iron", get_command(ord, buf, sizeof(buf)));
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_is_persistent(CuTest *tc) {
|
||||||
|
order *ord;
|
||||||
|
struct locale *lang;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
lang = test_create_locale();
|
||||||
|
|
||||||
|
ord = parse_order("@invalid", lang);
|
||||||
|
CuAssertPtrEquals(tc, NULL, ord);
|
||||||
|
|
||||||
|
ord = parse_order("give", lang);
|
||||||
|
CuAssertIntEquals(tc, K_GIVE, ord->command);
|
||||||
|
CuAssertTrue(tc, !is_persistent(ord));
|
||||||
|
free_order(ord);
|
||||||
|
|
||||||
|
ord = parse_order("@give", lang);
|
||||||
|
CuAssertTrue(tc, !is_repeated(K_GIVE));
|
||||||
|
CuAssertIntEquals(tc, K_GIVE | CMD_PERSIST, ord->command);
|
||||||
|
CuAssertTrue(tc, is_persistent(ord));
|
||||||
|
free_order(ord);
|
||||||
|
|
||||||
|
ord = parse_order("make", lang);
|
||||||
|
CuAssertTrue(tc, is_repeated(K_MAKE));
|
||||||
|
CuAssertIntEquals(tc, K_MAKE , ord->command);
|
||||||
|
CuAssertTrue(tc, is_persistent(ord));
|
||||||
|
free_order(ord);
|
||||||
|
|
||||||
|
ord = parse_order("@move", lang);
|
||||||
|
CuAssertIntEquals(tc, K_MOVE | CMD_PERSIST, ord->command);
|
||||||
|
CuAssertTrue(tc, !is_persistent(ord));
|
||||||
|
free_order(ord);
|
||||||
|
|
||||||
|
ord = parse_order("// comment", lang);
|
||||||
|
CuAssertTrue(tc, is_persistent(ord));
|
||||||
|
CuAssertIntEquals(tc, K_KOMMENTAR, ord->command);
|
||||||
|
free_order(ord);
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_is_silent(CuTest *tc) {
|
||||||
|
order *ord;
|
||||||
|
struct locale *lang;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
lang = test_create_locale();
|
||||||
|
|
||||||
|
ord = parse_order("make", lang);
|
||||||
|
CuAssertIntEquals(tc, K_MAKE, ord->command);
|
||||||
|
CuAssertTrue(tc, !is_silent(ord));
|
||||||
|
free_order(ord);
|
||||||
|
|
||||||
|
ord = parse_order("!make", lang);
|
||||||
|
CuAssertIntEquals(tc, K_MAKE | CMD_QUIET, ord->command);
|
||||||
|
CuAssertTrue(tc, is_silent(ord));
|
||||||
|
free_order(ord);
|
||||||
|
|
||||||
|
ord = parse_order("@invalid", lang);
|
||||||
|
CuAssertPtrEquals(tc, NULL, ord);
|
||||||
|
|
||||||
|
ord = parse_order("// comment", lang);
|
||||||
|
CuAssertTrue(tc, is_persistent(ord));
|
||||||
|
CuAssertIntEquals(tc, K_KOMMENTAR, ord->command);
|
||||||
|
free_order(ord);
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
CuSuite *get_order_suite(void)
|
CuSuite *get_order_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
@ -227,5 +305,7 @@ CuSuite *get_order_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_skip_token);
|
SUITE_ADD_TEST(suite, test_skip_token);
|
||||||
SUITE_ADD_TEST(suite, test_getstrtoken);
|
SUITE_ADD_TEST(suite, test_getstrtoken);
|
||||||
SUITE_ADD_TEST(suite, test_get_command);
|
SUITE_ADD_TEST(suite, test_get_command);
|
||||||
|
SUITE_ADD_TEST(suite, test_is_persistent);
|
||||||
|
SUITE_ADD_TEST(suite, test_is_silent);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "alchemy.h"
|
#include "alchemy.h"
|
||||||
#include "alliance.h"
|
#include "alliance.h"
|
||||||
#include "ally.h"
|
#include "ally.h"
|
||||||
#include "connection.h"
|
|
||||||
#include "building.h"
|
#include "building.h"
|
||||||
|
#include "connection.h"
|
||||||
|
#include "equipment.h"
|
||||||
#include "faction.h"
|
#include "faction.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
@ -1599,41 +1600,60 @@ static void fix_familiars(void) {
|
||||||
if (u->_race != u->faction->race && (u->_race->flags & RCF_FAMILIAR)) {
|
if (u->_race != u->faction->race && (u->_race->flags & RCF_FAMILIAR)) {
|
||||||
/* unit is potentially a familiar */
|
/* unit is potentially a familiar */
|
||||||
attrib * a = a_find(u->attribs, &at_mage);
|
attrib * a = a_find(u->attribs, &at_mage);
|
||||||
if (a) {
|
attrib * am = a_find(u->attribs, &at_familiarmage);
|
||||||
/* unit is magical */
|
if (am) {
|
||||||
attrib * am = a_find(u->attribs, &at_familiarmage);
|
sc_mage *mage = a ? (sc_mage *)a->data.v : NULL;
|
||||||
if (!am) {
|
/* a familiar */
|
||||||
/* but it is not a familiar? */
|
if (!mage) {
|
||||||
attrib * ae = a_find(u->attribs, &at_eventhandler);
|
log_error("%s seems to be a familiar with no magic.",
|
||||||
if (ae) {
|
unitname(u));
|
||||||
trigger **tlist;
|
mage = create_mage(u, M_GRAY);
|
||||||
tlist = get_triggers(ae, "destroy");
|
}
|
||||||
if (tlist) {
|
if (!mage->spellbook) {
|
||||||
trigger *t;
|
char eqname[32];
|
||||||
unit *um = NULL;
|
equipment *eq;
|
||||||
for (t = *tlist; t; t = t->next) {
|
|
||||||
if (t->type == &tt_shock) {
|
snprintf(eqname, sizeof(eqname), "fam_%s", u->_race->_name);
|
||||||
um = (unit *)t->data.v;
|
eq = get_equipment(eqname);
|
||||||
break;
|
if (eq && eq->spells) {
|
||||||
}
|
log_error("%s seems to be a familiar with no spells.",
|
||||||
|
unitname(u));
|
||||||
|
/* magical familiar, no spells */
|
||||||
|
equip_unit_mask(u, eq, EQUIP_SPELLS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (a) {
|
||||||
|
/* not a familiar, but magical */
|
||||||
|
attrib * ae = a_find(u->attribs, &at_eventhandler);
|
||||||
|
if (ae) {
|
||||||
|
trigger **tlist;
|
||||||
|
tlist = get_triggers(ae, "destroy");
|
||||||
|
if (tlist) {
|
||||||
|
trigger *t;
|
||||||
|
unit *um = NULL;
|
||||||
|
for (t = *tlist; t; t = t->next) {
|
||||||
|
if (t->type == &tt_shock) {
|
||||||
|
um = (unit *)t->data.v;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (um) {
|
}
|
||||||
attrib *af = a_find(um->attribs, &at_familiar);
|
if (um) {
|
||||||
log_error("%s seems to be a broken familiar of %s.",
|
attrib *af = a_find(um->attribs, &at_familiar);
|
||||||
unitname(u), unitname(um));
|
log_error("%s seems to be a broken familiar of %s.",
|
||||||
if (af) {
|
unitname(u), unitname(um));
|
||||||
unit * uf = (unit *)af->data.v;
|
if (af) {
|
||||||
log_error("%s already has a familiar: %s.",
|
unit * uf = (unit *)af->data.v;
|
||||||
unitname(um), unitname(uf));
|
log_error("%s already has a familiar: %s.",
|
||||||
}
|
unitname(um), unitname(uf));
|
||||||
else {
|
|
||||||
set_familiar(um, u);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log_error("%s seems to be a broken familiar with no trigger.", unitname(u));
|
set_familiar(um, u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
log_error("%s seems to be a broken familiar with no trigger.", unitname(u));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1790,7 +1810,7 @@ int read_game(gamedata *data)
|
||||||
else {
|
else {
|
||||||
for (u = f->units; u; u = u->nextF) {
|
for (u = f->units; u; u = u->nextF) {
|
||||||
if (data->version < SPELL_LEVEL_VERSION) {
|
if (data->version < SPELL_LEVEL_VERSION) {
|
||||||
sc_mage *mage = get_mage(u);
|
sc_mage *mage = get_mage_depr(u);
|
||||||
if (mage) {
|
if (mage) {
|
||||||
faction *f = u->faction;
|
faction *f = u->faction;
|
||||||
int skl = effskill(u, SK_MAGIC, 0);
|
int skl = effskill(u, SK_MAGIC, 0);
|
||||||
|
|
|
@ -1492,14 +1492,6 @@ unit *create_unit(region * r, faction * f, int number, const struct race *urace,
|
||||||
if (f) {
|
if (f) {
|
||||||
assert(faction_alive(f));
|
assert(faction_alive(f));
|
||||||
u_setfaction(u, f);
|
u_setfaction(u, f);
|
||||||
|
|
||||||
if (f->locale) {
|
|
||||||
order *deford = default_order(f->locale);
|
|
||||||
if (deford) {
|
|
||||||
set_order(&u->thisorder, NULL);
|
|
||||||
addlist(&u->orders, deford);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set_number(u, number);
|
set_number(u, number);
|
||||||
|
@ -1822,7 +1814,7 @@ void u_setrace(struct unit *u, const struct race *rc)
|
||||||
|
|
||||||
void unit_add_spell(unit * u, sc_mage * m, struct spell * sp, int level)
|
void unit_add_spell(unit * u, sc_mage * m, struct spell * sp, int level)
|
||||||
{
|
{
|
||||||
sc_mage *mage = m ? m : get_mage(u);
|
sc_mage *mage = m ? m : get_mage_depr(u);
|
||||||
|
|
||||||
if (!mage) {
|
if (!mage) {
|
||||||
log_debug("adding new spell %s to a previously non-mage unit %s\n", sp->sname, unitname(u));
|
log_debug("adding new spell %s to a previously non-mage unit %s\n", sp->sname, unitname(u));
|
||||||
|
@ -1836,7 +1828,7 @@ void unit_add_spell(unit * u, sc_mage * m, struct spell * sp, int level)
|
||||||
|
|
||||||
struct spellbook * unit_get_spellbook(const struct unit * u)
|
struct spellbook * unit_get_spellbook(const struct unit * u)
|
||||||
{
|
{
|
||||||
sc_mage * mage = get_mage(u);
|
sc_mage * mage = get_mage_depr(u);
|
||||||
if (mage) {
|
if (mage) {
|
||||||
if (mage->spellbook) {
|
if (mage->spellbook) {
|
||||||
return mage->spellbook;
|
return mage->spellbook;
|
||||||
|
|
|
@ -274,7 +274,7 @@ static void test_skill_familiar(CuTest *tc) {
|
||||||
CuAssertIntEquals(tc, 6, effskill(mag, SK_PERCEPTION, 0));
|
CuAssertIntEquals(tc, 6, effskill(mag, SK_PERCEPTION, 0));
|
||||||
|
|
||||||
/* make them mage and familiar to each other */
|
/* make them mage and familiar to each other */
|
||||||
CuAssertIntEquals(tc, true, create_newfamiliar(mag, fam));
|
create_newfamiliar(mag, fam);
|
||||||
|
|
||||||
/* when they are in the same region, the mage gets half their skill as a bonus */
|
/* when they are in the same region, the mage gets half their skill as a bonus */
|
||||||
CuAssertIntEquals(tc, 6, effskill(fam, SK_PERCEPTION, 0));
|
CuAssertIntEquals(tc, 6, effskill(fam, SK_PERCEPTION, 0));
|
||||||
|
@ -287,33 +287,11 @@ static void test_skill_familiar(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_age_familiar(CuTest *tc) {
|
|
||||||
unit *mag, *fam;
|
|
||||||
|
|
||||||
test_cleanup();
|
|
||||||
|
|
||||||
mag = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
|
||||||
fam = test_create_unit(mag->faction, test_create_region(0, 0, 0));
|
|
||||||
CuAssertPtrEquals(tc, 0, get_familiar(mag));
|
|
||||||
CuAssertPtrEquals(tc, 0, get_familiar_mage(fam));
|
|
||||||
CuAssertIntEquals(tc, true, create_newfamiliar(mag, fam));
|
|
||||||
CuAssertPtrEquals(tc, fam, get_familiar(mag));
|
|
||||||
CuAssertPtrEquals(tc, mag, get_familiar_mage(fam));
|
|
||||||
a_age(&fam->attribs, fam);
|
|
||||||
a_age(&mag->attribs, mag);
|
|
||||||
CuAssertPtrEquals(tc, fam, get_familiar(mag));
|
|
||||||
CuAssertPtrEquals(tc, mag, get_familiar_mage(fam));
|
|
||||||
set_number(fam, 0);
|
|
||||||
a_age(&mag->attribs, mag);
|
|
||||||
CuAssertPtrEquals(tc, 0, get_familiar(mag));
|
|
||||||
test_cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_inside_building(CuTest *tc) {
|
static void test_inside_building(CuTest *tc) {
|
||||||
unit *u;
|
unit *u;
|
||||||
building *b;
|
building *b;
|
||||||
|
|
||||||
test_cleanup();
|
test_setup();
|
||||||
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));
|
||||||
b = test_create_building(u->region, 0);
|
b = test_create_building(u->region, 0);
|
||||||
|
|
||||||
|
@ -631,7 +609,6 @@ CuSuite *get_unit_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_skillmod);
|
SUITE_ADD_TEST(suite, test_skillmod);
|
||||||
SUITE_ADD_TEST(suite, test_skill_hunger);
|
SUITE_ADD_TEST(suite, test_skill_hunger);
|
||||||
SUITE_ADD_TEST(suite, test_skill_familiar);
|
SUITE_ADD_TEST(suite, test_skill_familiar);
|
||||||
SUITE_ADD_TEST(suite, test_age_familiar);
|
|
||||||
SUITE_ADD_TEST(suite, test_inside_building);
|
SUITE_ADD_TEST(suite, test_inside_building);
|
||||||
SUITE_ADD_TEST(suite, test_skills);
|
SUITE_ADD_TEST(suite, test_skills);
|
||||||
SUITE_ADD_TEST(suite, test_limited_skills);
|
SUITE_ADD_TEST(suite, test_limited_skills);
|
||||||
|
|
168
src/laws.c
168
src/laws.c
|
@ -3007,10 +3007,100 @@ int checkunitnumber(const faction * f, int add)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void maketemp_cmd(unit *u, order **olist)
|
||||||
|
{
|
||||||
|
order *makeord;
|
||||||
|
int err = checkunitnumber(u->faction, 1);
|
||||||
|
|
||||||
|
makeord = *olist;
|
||||||
|
if (err) {
|
||||||
|
if (err == 1) {
|
||||||
|
ADDMSG(&u->faction->msgs,
|
||||||
|
msg_feedback(u, makeord,
|
||||||
|
"too_many_units_in_alliance",
|
||||||
|
"allowed", maxunits(u->faction)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ADDMSG(&u->faction->msgs,
|
||||||
|
msg_feedback(u, makeord,
|
||||||
|
"too_many_units_in_faction",
|
||||||
|
"allowed", maxunits(u->faction)));
|
||||||
|
}
|
||||||
|
*olist = makeord->next;
|
||||||
|
makeord->next = NULL;
|
||||||
|
free_order(makeord);
|
||||||
|
while (*olist) {
|
||||||
|
keyword_t kwd;
|
||||||
|
order * ord = *olist;
|
||||||
|
*olist = ord->next;
|
||||||
|
ord->next = NULL;
|
||||||
|
kwd = getkeyword(ord);
|
||||||
|
free_order(ord);
|
||||||
|
if (kwd == K_END) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
char token[128];
|
||||||
|
const char *s;
|
||||||
|
int alias;
|
||||||
|
ship *sh;
|
||||||
|
unit *u2;
|
||||||
|
order **ordp, **oinsert;
|
||||||
|
#ifndef NDEBUG
|
||||||
|
keyword_t kwd = init_order(makeord);
|
||||||
|
assert(kwd == K_MAKETEMP);
|
||||||
|
#endif
|
||||||
|
alias = getid();
|
||||||
|
s = gettoken(token, sizeof(token));
|
||||||
|
if (s && s[0] == '\0') {
|
||||||
|
/* empty name? => generate one */
|
||||||
|
s = NULL;
|
||||||
|
}
|
||||||
|
u2 = create_unit(u->region, u->faction, 0, u->faction->race, alias, s, u);
|
||||||
|
fset(u2, UFL_ISNEW);
|
||||||
|
a_add(&u2->attribs, a_new(&at_alias))->data.i = alias;
|
||||||
|
sh = leftship(u);
|
||||||
|
if (sh) {
|
||||||
|
set_leftship(u2, sh);
|
||||||
|
}
|
||||||
|
setstatus(u2, u->status);
|
||||||
|
|
||||||
|
/* copy orders until K_END from u to u2 */
|
||||||
|
ordp = &makeord->next;
|
||||||
|
oinsert = &u2->orders;
|
||||||
|
|
||||||
|
while (*ordp) {
|
||||||
|
order *ord = *ordp;
|
||||||
|
*ordp = ord->next;
|
||||||
|
if (getkeyword(ord) == K_END) {
|
||||||
|
ord->next = NULL;
|
||||||
|
free_order(ord);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*oinsert = ord;
|
||||||
|
oinsert = &ord->next;
|
||||||
|
*oinsert = NULL;
|
||||||
|
}
|
||||||
|
*olist = *ordp;
|
||||||
|
makeord->next = NULL;
|
||||||
|
free_order(makeord);
|
||||||
|
|
||||||
|
if (!u2->orders) {
|
||||||
|
order *deford = default_order(u2->faction->locale);
|
||||||
|
if (deford) {
|
||||||
|
set_order(&u2->thisorder, NULL);
|
||||||
|
addlist(&u2->orders, deford);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void new_units(void)
|
void new_units(void)
|
||||||
{
|
{
|
||||||
region *r;
|
region *r;
|
||||||
unit *u, *u2;
|
unit *u;
|
||||||
|
|
||||||
/* neue einheiten werden gemacht und ihre befehle (bis zum "ende" zu
|
/* neue einheiten werden gemacht und ihre befehle (bis zum "ende" zu
|
||||||
* ihnen rueberkopiert, damit diese einheiten genauso wie die alten
|
* ihnen rueberkopiert, damit diese einheiten genauso wie die alten
|
||||||
|
@ -3028,73 +3118,13 @@ void new_units(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*ordp) {
|
while (*ordp) {
|
||||||
order *makeord = *ordp;
|
order *ord = *ordp;
|
||||||
if (getkeyword(makeord) == K_MAKETEMP) {
|
if (getkeyword(ord) == K_MAKETEMP) {
|
||||||
char token[128], *name = NULL;
|
maketemp_cmd(u, ordp);
|
||||||
const char *s;
|
}
|
||||||
int alias;
|
else {
|
||||||
ship *sh;
|
ordp = &ord->next;
|
||||||
order **newordersp;
|
|
||||||
int err = checkunitnumber(u->faction, 1);
|
|
||||||
|
|
||||||
if (err) {
|
|
||||||
if (err == 1) {
|
|
||||||
ADDMSG(&u->faction->msgs,
|
|
||||||
msg_feedback(u, makeord,
|
|
||||||
"too_many_units_in_alliance",
|
|
||||||
"allowed", maxunits(u->faction)));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ADDMSG(&u->faction->msgs,
|
|
||||||
msg_feedback(u, makeord,
|
|
||||||
"too_many_units_in_faction",
|
|
||||||
"allowed", maxunits(u->faction)));
|
|
||||||
}
|
|
||||||
ordp = &makeord->next;
|
|
||||||
|
|
||||||
while (*ordp) {
|
|
||||||
order *ord = *ordp;
|
|
||||||
if (getkeyword(ord) == K_END)
|
|
||||||
break;
|
|
||||||
*ordp = ord->next;
|
|
||||||
ord->next = NULL;
|
|
||||||
free_order(ord);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
init_order(makeord);
|
|
||||||
alias = getid();
|
|
||||||
|
|
||||||
s = gettoken(token, sizeof(token));
|
|
||||||
if (s && s[0]) {
|
|
||||||
name = strdup(s);
|
|
||||||
}
|
|
||||||
u2 = create_unit(r, u->faction, 0, u->faction->race, alias, name, u);
|
|
||||||
if (name != NULL)
|
|
||||||
free(name); /* TODO: use a buffer on the stack instead? */
|
|
||||||
fset(u2, UFL_ISNEW);
|
|
||||||
|
|
||||||
a_add(&u2->attribs, a_new(&at_alias))->data.i = alias;
|
|
||||||
sh = leftship(u);
|
|
||||||
if (sh) {
|
|
||||||
set_leftship(u2, sh);
|
|
||||||
}
|
|
||||||
setstatus(u2, u->status);
|
|
||||||
|
|
||||||
ordp = &makeord->next;
|
|
||||||
newordersp = &u2->orders;
|
|
||||||
while (*ordp) {
|
|
||||||
order *ord = *ordp;
|
|
||||||
if (getkeyword(ord) == K_END)
|
|
||||||
break;
|
|
||||||
*ordp = ord->next;
|
|
||||||
ord->next = NULL;
|
|
||||||
*newordersp = ord;
|
|
||||||
newordersp = &ord->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (*ordp == makeord)
|
|
||||||
ordp = &makeord->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3357,7 +3387,7 @@ static int faction_getmages(faction * f, unit ** results, int numresults)
|
||||||
|
|
||||||
for (u = f->units; u; u = u->nextF) {
|
for (u = f->units; u; u = u->nextF) {
|
||||||
if (u->number > 0) {
|
if (u->number > 0) {
|
||||||
sc_mage *mage = get_mage(u);
|
sc_mage *mage = get_mage_depr(u);
|
||||||
if (mage) {
|
if (mage) {
|
||||||
int level = effskill(u, SK_MAGIC, 0);
|
int level = effskill(u, SK_MAGIC, 0);
|
||||||
if (level > maxlevel) {
|
if (level > maxlevel) {
|
||||||
|
@ -3416,7 +3446,7 @@ static void update_spells(void)
|
||||||
show_new_spells(f, maxlevel, faction_get_spellbook(f));
|
show_new_spells(f, maxlevel, faction_get_spellbook(f));
|
||||||
for (i = 0; i != MAXMAGES && mages[i]; ++i) {
|
for (i = 0; i != MAXMAGES && mages[i]; ++i) {
|
||||||
unit * u = mages[i];
|
unit * u = mages[i];
|
||||||
sc_mage *mage = get_mage(u);
|
sc_mage *mage = get_mage_depr(u);
|
||||||
if (mage && mage->spellbook) {
|
if (mage && mage->spellbook) {
|
||||||
int level = effskill(u, SK_MAGIC, 0);
|
int level = effskill(u, SK_MAGIC, 0);
|
||||||
show_new_spells(f, level, mage->spellbook);
|
show_new_spells(f, level, mage->spellbook);
|
||||||
|
|
|
@ -428,6 +428,63 @@ static void test_unit_limit(CuTest * tc)
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_maketemp(CuTest * tc)
|
||||||
|
{
|
||||||
|
faction *f;
|
||||||
|
unit *u, *u2;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
f = test_create_faction(NULL);
|
||||||
|
u = test_create_unit(f, test_create_region(0, 0, NULL));
|
||||||
|
|
||||||
|
u->orders = create_order(K_MAKETEMP, f->locale, "1");
|
||||||
|
u->orders->next = create_order(K_ENTERTAIN, f->locale, NULL);
|
||||||
|
u->orders->next->next = create_order(K_END, f->locale, NULL);
|
||||||
|
u->orders->next->next->next = create_order(K_TAX, f->locale, NULL);
|
||||||
|
|
||||||
|
new_units();
|
||||||
|
CuAssertIntEquals(tc, 2, f->num_units);
|
||||||
|
CuAssertPtrNotNull(tc, u2 = u->next);
|
||||||
|
CuAssertPtrNotNull(tc, u2->orders);
|
||||||
|
CuAssertPtrEquals(tc, NULL, u2->orders->next);
|
||||||
|
CuAssertIntEquals(tc, K_ENTERTAIN, getkeyword(u2->orders));
|
||||||
|
|
||||||
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
CuAssertPtrEquals(tc, NULL, u->orders->next);
|
||||||
|
CuAssertIntEquals(tc, K_TAX, getkeyword(u->orders));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_maketemp_default_order(CuTest * tc)
|
||||||
|
{
|
||||||
|
faction *f;
|
||||||
|
unit *u, *u2;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
config_set("orders.default", "work");
|
||||||
|
f = test_create_faction(NULL);
|
||||||
|
u = test_create_unit(f, test_create_region(0, 0, NULL));
|
||||||
|
|
||||||
|
new_units();
|
||||||
|
CuAssertIntEquals(tc, 1, f->num_units);
|
||||||
|
|
||||||
|
u->orders = create_order(K_MAKETEMP, f->locale, "1");
|
||||||
|
u->orders->next = create_order(K_END, f->locale, NULL);
|
||||||
|
u->orders->next->next = create_order(K_TAX, f->locale, NULL);
|
||||||
|
|
||||||
|
new_units();
|
||||||
|
CuAssertIntEquals(tc, 2, f->num_units);
|
||||||
|
CuAssertPtrNotNull(tc, u2 = u->next);
|
||||||
|
CuAssertPtrNotNull(tc, u2->orders);
|
||||||
|
CuAssertPtrEquals(tc, NULL, u2->orders->next);
|
||||||
|
CuAssertIntEquals(tc, K_WORK, getkeyword(u2->orders));
|
||||||
|
|
||||||
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
CuAssertPtrEquals(tc, NULL, u->orders->next);
|
||||||
|
CuAssertIntEquals(tc, K_TAX, getkeyword(u->orders));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
static void test_limit_new_units(CuTest * tc)
|
static void test_limit_new_units(CuTest * tc)
|
||||||
{
|
{
|
||||||
faction *f;
|
faction *f;
|
||||||
|
@ -449,6 +506,8 @@ static void test_limit_new_units(CuTest * tc)
|
||||||
CuAssertPtrNotNull(tc, u->next);
|
CuAssertPtrNotNull(tc, u->next);
|
||||||
CuAssertIntEquals(tc, 2, f->num_units);
|
CuAssertIntEquals(tc, 2, f->num_units);
|
||||||
|
|
||||||
|
CuAssertPtrEquals(tc, NULL, u->orders);
|
||||||
|
u->orders = create_order(K_MAKETEMP, f->locale, "1");
|
||||||
new_units();
|
new_units();
|
||||||
CuAssertIntEquals(tc, 2, f->num_units);
|
CuAssertIntEquals(tc, 2, f->num_units);
|
||||||
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "too_many_units_in_faction"));
|
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "too_many_units_in_faction"));
|
||||||
|
@ -458,6 +517,8 @@ static void test_limit_new_units(CuTest * tc)
|
||||||
config_set("rules.limit.faction", "3");
|
config_set("rules.limit.faction", "3");
|
||||||
config_set("rules.limit.alliance", "2");
|
config_set("rules.limit.alliance", "2");
|
||||||
|
|
||||||
|
CuAssertPtrEquals(tc, NULL, u->orders);
|
||||||
|
u->orders = create_order(K_MAKETEMP, f->locale, "1");
|
||||||
new_units();
|
new_units();
|
||||||
CuAssertIntEquals(tc, 2, f->num_units);
|
CuAssertIntEquals(tc, 2, f->num_units);
|
||||||
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "too_many_units_in_alliance"));
|
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "too_many_units_in_alliance"));
|
||||||
|
@ -466,6 +527,8 @@ static void test_limit_new_units(CuTest * tc)
|
||||||
u = test_create_unit(test_create_faction(NULL), u->region);
|
u = test_create_unit(test_create_faction(NULL), u->region);
|
||||||
setalliance(u->faction, al);
|
setalliance(u->faction, al);
|
||||||
|
|
||||||
|
CuAssertPtrEquals(tc, NULL, u->orders);
|
||||||
|
u->orders = create_order(K_MAKETEMP, f->locale, "1");
|
||||||
new_units();
|
new_units();
|
||||||
CuAssertIntEquals(tc, 2, f->num_units);
|
CuAssertIntEquals(tc, 2, f->num_units);
|
||||||
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "too_many_units_in_alliance"));
|
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "too_many_units_in_alliance"));
|
||||||
|
@ -1555,6 +1618,8 @@ static void test_armedmen(CuTest *tc) {
|
||||||
CuSuite *get_laws_suite(void)
|
CuSuite *get_laws_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_maketemp_default_order);
|
||||||
|
SUITE_ADD_TEST(suite, test_maketemp);
|
||||||
SUITE_ADD_TEST(suite, test_nmr_warnings);
|
SUITE_ADD_TEST(suite, test_nmr_warnings);
|
||||||
SUITE_ADD_TEST(suite, test_ally_cmd);
|
SUITE_ADD_TEST(suite, test_ally_cmd);
|
||||||
SUITE_ADD_TEST(suite, test_name_cmd);
|
SUITE_ADD_TEST(suite, test_name_cmd);
|
||||||
|
|
99
src/magic.c
99
src/magic.c
|
@ -42,6 +42,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
#include <kernel/callbacks.h>
|
#include <kernel/callbacks.h>
|
||||||
#include <kernel/curse.h>
|
#include <kernel/curse.h>
|
||||||
|
#include <kernel/equipment.h>
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
#include <kernel/item.h>
|
#include <kernel/item.h>
|
||||||
#include <kernel/messages.h>
|
#include <kernel/messages.h>
|
||||||
|
@ -322,10 +323,19 @@ attrib_type at_mage = {
|
||||||
|
|
||||||
bool is_mage(const unit * u)
|
bool is_mage(const unit * u)
|
||||||
{
|
{
|
||||||
return get_mage(u) != NULL;
|
return get_mage_depr(u) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_mage *get_mage(const unit * u)
|
sc_mage *get_mage(const unit * u)
|
||||||
|
{
|
||||||
|
attrib *a = a_find(u->attribs, &at_mage);
|
||||||
|
if (a) {
|
||||||
|
return (sc_mage *)a->data.v;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc_mage *get_mage_depr(const unit * u)
|
||||||
{
|
{
|
||||||
if (has_skill(u, SK_MAGIC)) {
|
if (has_skill(u, SK_MAGIC)) {
|
||||||
attrib *a = a_find(u->attribs, &at_mage);
|
attrib *a = a_find(u->attribs, &at_mage);
|
||||||
|
@ -333,7 +343,7 @@ sc_mage *get_mage(const unit * u)
|
||||||
return (sc_mage *)a->data.v;
|
return (sc_mage *)a->data.v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (sc_mage *)NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
@ -506,7 +516,7 @@ int u_hasspell(const unit *u, const struct spell *sp)
|
||||||
|
|
||||||
int get_combatspelllevel(const unit * u, int nr)
|
int get_combatspelllevel(const unit * u, int nr)
|
||||||
{
|
{
|
||||||
sc_mage *m = get_mage(u);
|
sc_mage *m = get_mage_depr(u);
|
||||||
|
|
||||||
assert(nr < MAXCOMBATSPELLS);
|
assert(nr < MAXCOMBATSPELLS);
|
||||||
if (m) {
|
if (m) {
|
||||||
|
@ -524,7 +534,7 @@ const spell *get_combatspell(const unit * u, int nr)
|
||||||
sc_mage *m;
|
sc_mage *m;
|
||||||
|
|
||||||
assert(nr < MAXCOMBATSPELLS);
|
assert(nr < MAXCOMBATSPELLS);
|
||||||
m = get_mage(u);
|
m = get_mage_depr(u);
|
||||||
if (m) {
|
if (m) {
|
||||||
return m->combatspells[nr].sp;
|
return m->combatspells[nr].sp;
|
||||||
}
|
}
|
||||||
|
@ -533,7 +543,7 @@ const spell *get_combatspell(const unit * u, int nr)
|
||||||
|
|
||||||
void set_combatspell(unit * u, spell * sp, struct order *ord, int level)
|
void set_combatspell(unit * u, spell * sp, struct order *ord, int level)
|
||||||
{
|
{
|
||||||
sc_mage *mage = get_mage(u);
|
sc_mage *mage = get_mage_depr(u);
|
||||||
int i = -1;
|
int i = -1;
|
||||||
|
|
||||||
assert(mage || !"trying to set a combat spell for non-mage");
|
assert(mage || !"trying to set a combat spell for non-mage");
|
||||||
|
@ -573,7 +583,7 @@ void unset_combatspell(unit * u, spell * sp)
|
||||||
int nr = 0;
|
int nr = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
m = get_mage(u);
|
m = get_mage_depr(u);
|
||||||
if (!m)
|
if (!m)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -609,7 +619,7 @@ int get_spellpoints(const unit * u)
|
||||||
{
|
{
|
||||||
sc_mage *m;
|
sc_mage *m;
|
||||||
|
|
||||||
m = get_mage(u);
|
m = get_mage_depr(u);
|
||||||
if (!m)
|
if (!m)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -620,7 +630,7 @@ void set_spellpoints(unit * u, int sp)
|
||||||
{
|
{
|
||||||
sc_mage *m;
|
sc_mage *m;
|
||||||
|
|
||||||
m = get_mage(u);
|
m = get_mage_depr(u);
|
||||||
if (!m)
|
if (!m)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -637,7 +647,7 @@ int change_spellpoints(unit * u, int mp)
|
||||||
sc_mage *m;
|
sc_mage *m;
|
||||||
int sp;
|
int sp;
|
||||||
|
|
||||||
m = get_mage(u);
|
m = get_mage_depr(u);
|
||||||
if (!m) {
|
if (!m) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -656,7 +666,7 @@ static int get_spchange(const unit * u)
|
||||||
{
|
{
|
||||||
sc_mage *m;
|
sc_mage *m;
|
||||||
|
|
||||||
m = get_mage(u);
|
m = get_mage_depr(u);
|
||||||
if (!m)
|
if (!m)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -710,7 +720,7 @@ int change_maxspellpoints(unit * u, int csp)
|
||||||
{
|
{
|
||||||
sc_mage *m;
|
sc_mage *m;
|
||||||
|
|
||||||
m = get_mage(u);
|
m = get_mage_depr(u);
|
||||||
if (!m) {
|
if (!m) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -728,7 +738,7 @@ int countspells(unit * u, int step)
|
||||||
sc_mage *m;
|
sc_mage *m;
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
m = get_mage(u);
|
m = get_mage_depr(u);
|
||||||
if (!m)
|
if (!m)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1312,7 +1322,7 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* CHAOSPATZERCHANCE 10 : +10% Chance zu Patzern */
|
/* CHAOSPATZERCHANCE 10 : +10% Chance zu Patzern */
|
||||||
mage = get_mage(u);
|
mage = get_mage_depr(u);
|
||||||
if (mage->magietyp == M_DRAIG) {
|
if (mage->magietyp == M_DRAIG) {
|
||||||
fumble_chance += CHAOSPATZERCHANCE;
|
fumble_chance += CHAOSPATZERCHANCE;
|
||||||
}
|
}
|
||||||
|
@ -2181,10 +2191,8 @@ void set_familiar(unit * mage, unit * familiar)
|
||||||
a = a->next;
|
a = a->next;
|
||||||
}
|
}
|
||||||
if (a == NULL) {
|
if (a == NULL) {
|
||||||
attrib *an = a_add(&mage->attribs, a_new(&at_skillmod));
|
a = make_skillmod(NOSKILL, sm_familiar, 0.0, 0);
|
||||||
skillmod_data *smd = (skillmod_data *)an->data.v;
|
a_add(&mage->attribs, a);
|
||||||
smd->special = sm_familiar;
|
|
||||||
smd->skill = NOSKILL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a = a_find(mage->attribs, &at_familiar);
|
a = a_find(mage->attribs, &at_familiar);
|
||||||
|
@ -2192,17 +2200,19 @@ void set_familiar(unit * mage, unit * familiar)
|
||||||
a = a_add(&mage->attribs, a_new(&at_familiar));
|
a = a_add(&mage->attribs, a_new(&at_familiar));
|
||||||
a->data.v = familiar;
|
a->data.v = familiar;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
assert(!a->data.v || a->data.v == familiar);
|
assert(!a->data.v || a->data.v == familiar);
|
||||||
/* TODO: Diese Attribute beim Tod des Familiars entfernen: */
|
}
|
||||||
|
|
||||||
|
/* TODO: Diese Attribute beim Tod des Familiars entfernen: */
|
||||||
a = a_find(familiar->attribs, &at_familiarmage);
|
a = a_find(familiar->attribs, &at_familiarmage);
|
||||||
if (a == NULL) {
|
if (a == NULL) {
|
||||||
a = a_add(&familiar->attribs, a_new(&at_familiarmage));
|
a = a_add(&familiar->attribs, a_new(&at_familiarmage));
|
||||||
a->data.v = mage;
|
a->data.v = mage;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
assert(!a->data.v || a->data.v == mage);
|
assert(!a->data.v || a->data.v == mage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_familiar(unit * mage)
|
void remove_familiar(unit * mage)
|
||||||
|
@ -2218,48 +2228,35 @@ void remove_familiar(unit * mage)
|
||||||
while (a && a->type == &at_skillmod) {
|
while (a && a->type == &at_skillmod) {
|
||||||
an = a->next;
|
an = a->next;
|
||||||
smd = (skillmod_data *)a->data.v;
|
smd = (skillmod_data *)a->data.v;
|
||||||
if (smd->special == sm_familiar)
|
if (smd->special == sm_familiar) {
|
||||||
a_remove(&mage->attribs, a);
|
a_remove(&mage->attribs, a);
|
||||||
|
}
|
||||||
a = an;
|
a = an;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool create_newfamiliar(unit * mage, unit * familiar)
|
void create_newfamiliar(unit * mage, unit * fam)
|
||||||
{
|
{
|
||||||
/* if the skill modifier for the mage does not yet exist, add it */
|
/* skills and spells: */
|
||||||
attrib *a;
|
const struct equipment *eq;
|
||||||
attrib *afam = a_find(mage->attribs, &at_familiar);
|
char eqname[64];
|
||||||
attrib *amage = a_find(familiar->attribs, &at_familiarmage);
|
const race *rc = u_race(fam);
|
||||||
|
|
||||||
if (afam == NULL) {
|
set_familiar(mage, fam);
|
||||||
afam = a_add(&mage->attribs, a_new(&at_familiar));
|
|
||||||
}
|
|
||||||
afam->data.v = familiar;
|
|
||||||
if (amage == NULL) {
|
|
||||||
amage = a_add(&familiar->attribs, a_new(&at_familiarmage));
|
|
||||||
}
|
|
||||||
amage->data.v = mage;
|
|
||||||
|
|
||||||
|
snprintf(eqname, sizeof(eqname), "fam_%s", rc->_name);
|
||||||
|
eq = get_equipment(eqname);
|
||||||
|
if (eq != NULL) {
|
||||||
|
equip_unit(fam, eq);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log_info("could not perform initialization for familiar %s.\n", rc->_name);
|
||||||
|
}
|
||||||
/* TODO: Diese Attribute beim Tod des Familiars entfernen: */
|
/* TODO: Diese Attribute beim Tod des Familiars entfernen: */
|
||||||
/* Wenn der Magier stirbt, dann auch der Vertraute */
|
/* Wenn der Magier stirbt, dann auch der Vertraute */
|
||||||
add_trigger(&mage->attribs, "destroy", trigger_killunit(familiar));
|
add_trigger(&mage->attribs, "destroy", trigger_killunit(fam));
|
||||||
/* Wenn der Vertraute stirbt, dann bekommt der Magier einen Schock */
|
/* Wenn der Vertraute stirbt, dann bekommt der Magier einen Schock */
|
||||||
add_trigger(&familiar->attribs, "destroy", trigger_shock(mage));
|
add_trigger(&fam->attribs, "destroy", trigger_shock(mage));
|
||||||
|
|
||||||
a = a_find(mage->attribs, &at_skillmod);
|
|
||||||
while (a && a->type == &at_skillmod) {
|
|
||||||
skillmod_data *smd = (skillmod_data *)a->data.v;
|
|
||||||
if (smd->special == sm_familiar)
|
|
||||||
break;
|
|
||||||
a = a->next;
|
|
||||||
}
|
|
||||||
if (a == NULL) {
|
|
||||||
attrib *an = a_add(&mage->attribs, a_new(&at_skillmod));
|
|
||||||
skillmod_data *smd = (skillmod_data *)an->data.v;
|
|
||||||
smd->special = sm_familiar;
|
|
||||||
smd->skill = NOSKILL;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void * resolve_familiar(int id, void *data) {
|
static void * resolve_familiar(int id, void *data) {
|
||||||
|
|
|
@ -221,6 +221,7 @@ extern "C" {
|
||||||
/* macht die struct unit zu einem neuen Magier: legt die struct u->mage an
|
/* macht die struct unit zu einem neuen Magier: legt die struct u->mage an
|
||||||
* und initialisiert den Magiertypus mit mtyp. */
|
* und initialisiert den Magiertypus mit mtyp. */
|
||||||
sc_mage *get_mage(const struct unit *u);
|
sc_mage *get_mage(const struct unit *u);
|
||||||
|
sc_mage *get_mage_depr(const struct unit *u);
|
||||||
/* gibt u->mage zurück, bei nicht-Magiern *NULL */
|
/* gibt u->mage zurück, bei nicht-Magiern *NULL */
|
||||||
bool is_mage(const struct unit *u);
|
bool is_mage(const struct unit *u);
|
||||||
/* gibt true, wenn u->mage gesetzt. */
|
/* gibt true, wenn u->mage gesetzt. */
|
||||||
|
@ -329,7 +330,7 @@ extern "C" {
|
||||||
struct unit *get_clone(const struct unit *u);
|
struct unit *get_clone(const struct unit *u);
|
||||||
struct unit *get_clone_mage(const struct unit *u);
|
struct unit *get_clone_mage(const struct unit *u);
|
||||||
void remove_familiar(struct unit *mage);
|
void remove_familiar(struct unit *mage);
|
||||||
bool create_newfamiliar(struct unit *mage, struct unit *familiar);
|
void create_newfamiliar(struct unit *mage, struct unit *familiar);
|
||||||
void create_newclone(struct unit *mage, struct unit *familiar);
|
void create_newclone(struct unit *mage, struct unit *familiar);
|
||||||
struct unit *has_clone(struct unit *mage);
|
struct unit *has_clone(struct unit *mage);
|
||||||
|
|
||||||
|
|
123
src/magic.test.c
123
src/magic.test.c
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
#include <kernel/race.h>
|
#include <kernel/race.h>
|
||||||
|
#include <kernel/equipment.h>
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
#include <kernel/order.h>
|
#include <kernel/order.h>
|
||||||
#include <kernel/item.h>
|
#include <kernel/item.h>
|
||||||
|
@ -477,9 +478,131 @@ static void test_illusioncastle(CuTest *tc)
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_is_mage(CuTest *tc) {
|
||||||
|
unit *u;
|
||||||
|
sc_mage *mage;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
CuAssertPtrEquals(tc, NULL, get_mage(u));
|
||||||
|
CuAssertTrue(tc, !is_mage(u));
|
||||||
|
set_level(u, SK_MAGIC, 1);
|
||||||
|
CuAssertTrue(tc, !is_mage(u));
|
||||||
|
CuAssertPtrEquals(tc, NULL, get_mage(u));
|
||||||
|
CuAssertPtrNotNull(tc, mage = create_mage(u, M_CERDDOR));
|
||||||
|
CuAssertPtrEquals(tc, mage, get_mage(u));
|
||||||
|
CuAssertTrue(tc, is_mage(u));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_get_mage(CuTest *tc) {
|
||||||
|
unit *u;
|
||||||
|
sc_mage *mage;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
CuAssertPtrEquals(tc, NULL, get_mage(u));
|
||||||
|
CuAssertPtrEquals(tc, NULL, get_mage_depr(u));
|
||||||
|
CuAssertPtrNotNull(tc, mage = create_mage(u, M_CERDDOR));
|
||||||
|
CuAssertPtrEquals(tc, mage, get_mage(u));
|
||||||
|
CuAssertPtrEquals(tc, NULL, get_mage_depr(u));
|
||||||
|
set_level(u, SK_MAGIC, 1);
|
||||||
|
CuAssertPtrEquals(tc, mage, get_mage(u));
|
||||||
|
CuAssertPtrEquals(tc, mage, get_mage_depr(u));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_familiar_set(CuTest *tc) {
|
||||||
|
unit *mag, *fam;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
|
||||||
|
mag = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
fam = test_create_unit(mag->faction, test_create_region(0, 0, 0));
|
||||||
|
CuAssertPtrEquals(tc, NULL, get_familiar(mag));
|
||||||
|
CuAssertPtrEquals(tc, NULL, get_familiar_mage(fam));
|
||||||
|
CuAssertPtrEquals(tc, NULL, a_find(mag->attribs, &at_skillmod));
|
||||||
|
set_familiar(mag, fam);
|
||||||
|
CuAssertPtrEquals(tc, fam, get_familiar(mag));
|
||||||
|
CuAssertPtrEquals(tc, mag, get_familiar_mage(fam));
|
||||||
|
CuAssertPtrNotNull(tc, a_find(mag->attribs, &at_skillmod));
|
||||||
|
remove_familiar(mag);
|
||||||
|
CuAssertPtrEquals(tc, NULL, get_familiar(mag));
|
||||||
|
CuAssertPtrEquals(tc, NULL, a_find(mag->attribs, &at_skillmod));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_familiar_age(CuTest *tc) {
|
||||||
|
unit *mag, *fam;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
|
||||||
|
mag = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
fam = test_create_unit(mag->faction, test_create_region(0, 0, 0));
|
||||||
|
set_familiar(mag, fam);
|
||||||
|
CuAssertPtrEquals(tc, fam, get_familiar(mag));
|
||||||
|
CuAssertPtrEquals(tc, mag, get_familiar_mage(fam));
|
||||||
|
a_age(&fam->attribs, fam);
|
||||||
|
a_age(&mag->attribs, mag);
|
||||||
|
CuAssertPtrEquals(tc, fam, get_familiar(mag));
|
||||||
|
CuAssertPtrEquals(tc, mag, get_familiar_mage(fam));
|
||||||
|
set_number(fam, 0);
|
||||||
|
a_age(&mag->attribs, mag);
|
||||||
|
CuAssertPtrEquals(tc, NULL, get_familiar(mag));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_familiar_equip(CuTest *tc) {
|
||||||
|
unit *mag, *u;
|
||||||
|
equipment *eq;
|
||||||
|
const item_type * itype;
|
||||||
|
spell *sp;
|
||||||
|
sc_mage * mage;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
|
||||||
|
itype = test_create_itemtype("horse");
|
||||||
|
CuAssertPtrNotNull(tc, itype);
|
||||||
|
sp = create_spell("testspell");
|
||||||
|
CuAssertPtrNotNull(tc, sp);
|
||||||
|
|
||||||
|
eq = get_or_create_equipment("fam_human");
|
||||||
|
equipment_setitem(eq, itype, "1");
|
||||||
|
equipment_setskill(eq, SK_ENTERTAINMENT, "5");
|
||||||
|
equipment_addspell(eq, sp->sname, 1);
|
||||||
|
|
||||||
|
mag = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
u = test_create_unit(mag->faction, test_create_region(0, 0, 0));
|
||||||
|
set_familiar(mag, u);
|
||||||
|
create_newfamiliar(mag, u);
|
||||||
|
CuAssertIntEquals(tc, 1, i_get(u->items, itype));
|
||||||
|
CuAssertIntEquals(tc, 5, get_level(u, SK_ENTERTAINMENT));
|
||||||
|
CuAssertIntEquals(tc, 0, get_level(u, SK_MAGIC));
|
||||||
|
|
||||||
|
mage = get_mage(u);
|
||||||
|
CuAssertPtrNotNull(tc, mage);
|
||||||
|
CuAssertPtrNotNull(tc, mage->spellbook);
|
||||||
|
set_level(u, SK_MAGIC, 1);
|
||||||
|
CuAssertPtrEquals(tc, mage, get_mage_depr(u));
|
||||||
|
CuAssertTrue(tc, u_hasspell(u, sp));
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
CuSuite *get_familiar_suite(void)
|
||||||
|
{
|
||||||
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_familiar_equip);
|
||||||
|
SUITE_ADD_TEST(suite, test_familiar_set);
|
||||||
|
SUITE_ADD_TEST(suite, test_familiar_age);
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_magic_suite(void)
|
CuSuite *get_magic_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_is_mage);
|
||||||
|
SUITE_ADD_TEST(suite, test_get_mage);
|
||||||
SUITE_ADD_TEST(suite, test_multi_cast);
|
SUITE_ADD_TEST(suite, test_multi_cast);
|
||||||
SUITE_ADD_TEST(suite, test_updatespells);
|
SUITE_ADD_TEST(suite, test_updatespells);
|
||||||
SUITE_ADD_TEST(suite, test_spellbooks);
|
SUITE_ADD_TEST(suite, test_spellbooks);
|
||||||
|
|
|
@ -147,8 +147,7 @@ newfaction *read_newfactions(const char *filename)
|
||||||
faction *f;
|
faction *f;
|
||||||
char race[20], email[64], lang[8], password[16];
|
char race[20], email[64], lang[8], password[16];
|
||||||
newfaction *nf, **nfi;
|
newfaction *nf, **nfi;
|
||||||
int bonus = 0, subscription = 0;
|
int alliance = 0, subscription = 0;
|
||||||
int alliance = 0;
|
|
||||||
|
|
||||||
if (fgets(buf, sizeof(buf), F) == NULL)
|
if (fgets(buf, sizeof(buf), F) == NULL)
|
||||||
break;
|
break;
|
||||||
|
@ -156,8 +155,8 @@ newfaction *read_newfactions(const char *filename)
|
||||||
email[0] = '\0';
|
email[0] = '\0';
|
||||||
password[0] = '\0';
|
password[0] = '\0';
|
||||||
|
|
||||||
if (sscanf(buf, "%54s %20s %8s %d %d %16s %d", email, race, lang, &bonus,
|
if (sscanf(buf, "%54s %20s %8s %16s %d %d", email, race, lang,
|
||||||
&subscription, password, &alliance) < 3) {
|
password, &subscription, &alliance) < 3) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (email[0] == '#') {
|
if (email[0] == '#') {
|
||||||
|
@ -228,7 +227,6 @@ newfaction *read_newfactions(const char *filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nf->lang = get_locale(lang);
|
nf->lang = get_locale(lang);
|
||||||
nf->bonus = bonus;
|
|
||||||
assert(nf->race && nf->email && nf->lang);
|
assert(nf->race && nf->email && nf->lang);
|
||||||
nfi = &newfactions;
|
nfi = &newfactions;
|
||||||
while (*nfi) {
|
while (*nfi) {
|
||||||
|
|
|
@ -24,7 +24,6 @@ extern "C" {
|
||||||
char *password;
|
char *password;
|
||||||
const struct locale *lang;
|
const struct locale *lang;
|
||||||
const struct race *race;
|
const struct race *race;
|
||||||
int bonus;
|
|
||||||
int subscription;
|
int subscription;
|
||||||
bool oldregions;
|
bool oldregions;
|
||||||
struct alliance *allies;
|
struct alliance *allies;
|
||||||
|
|
78
src/move.c
78
src/move.c
|
@ -89,14 +89,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
/* Bewegungsweiten: */
|
|
||||||
#define BP_WALKING 4
|
|
||||||
#define BP_RIDING 6
|
|
||||||
#define BP_UNICORN 9
|
|
||||||
#define BP_DRAGON 4
|
|
||||||
#define BP_NORMAL 3
|
|
||||||
#define BP_ROAD 2
|
|
||||||
|
|
||||||
int *storms;
|
int *storms;
|
||||||
|
|
||||||
typedef struct traveldir {
|
typedef struct traveldir {
|
||||||
|
@ -265,7 +257,7 @@ get_transporters(const item * itm, int *p_animals, int *p_acap, int *p_vehicles,
|
||||||
*p_acap = acap;
|
*p_acap = acap;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ridingcapacity(unit * u)
|
static int ridingcapacity(const unit * u)
|
||||||
{
|
{
|
||||||
int vehicles = 0, vcap = 0;
|
int vehicles = 0, vcap = 0;
|
||||||
int animals = 0, acap = 0;
|
int animals = 0, acap = 0;
|
||||||
|
@ -433,7 +425,7 @@ bool canswim(unit * u)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int canride(unit * u)
|
static int canride(const unit * u)
|
||||||
{
|
{
|
||||||
int horses = 0, maxhorses, unicorns = 0, maxunicorns;
|
int horses = 0, maxhorses, unicorns = 0, maxunicorns;
|
||||||
int skill = effskill(u, SK_RIDING, 0);
|
int skill = effskill(u, SK_RIDING, 0);
|
||||||
|
@ -460,17 +452,17 @@ static int canride(unit * u)
|
||||||
if (!(u_race(u)->flags & RCF_HORSE)
|
if (!(u_race(u)->flags & RCF_HORSE)
|
||||||
&& ((horses == 0 && unicorns == 0)
|
&& ((horses == 0 && unicorns == 0)
|
||||||
|| horses > maxhorses || unicorns > maxunicorns)) {
|
|| horses > maxhorses || unicorns > maxunicorns)) {
|
||||||
return 0;
|
return BP_WALKING;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ridingcapacity(u) - eff_weight(u) >= 0) {
|
if (ridingcapacity(u) - eff_weight(u) >= 0) {
|
||||||
if (horses == 0 && unicorns >= u->number && !(u_race(u)->flags & RCF_HORSE)) {
|
if (horses == 0 && unicorns >= u->number && !(u_race(u)->flags & RCF_HORSE)) {
|
||||||
return 2;
|
return BP_UNICORN;
|
||||||
}
|
}
|
||||||
return 1;
|
return BP_RIDING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return BP_WALKING;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool cansail(const region * r, ship * sh)
|
static bool cansail(const region * r, ship * sh)
|
||||||
|
@ -1399,9 +1391,9 @@ static void make_route(unit * u, order * ord, region_list ** routep)
|
||||||
* Normalerweise verliert man 3 BP pro Region, bei Straßen nur 2 BP.
|
* Normalerweise verliert man 3 BP pro Region, bei Straßen nur 2 BP.
|
||||||
* Außerdem: Wenn Einheit transportiert, nur halbe BP
|
* Außerdem: Wenn Einheit transportiert, nur halbe BP
|
||||||
*/
|
*/
|
||||||
static int movement_speed(unit * u)
|
int movement_speed(const unit * u)
|
||||||
{
|
{
|
||||||
int mp = BP_WALKING;
|
int mp = 0;
|
||||||
const race *rc = u_race(u);
|
const race *rc = u_race(u);
|
||||||
double dk = rc->speed;
|
double dk = rc->speed;
|
||||||
assert(u->number);
|
assert(u->number);
|
||||||
|
@ -1415,6 +1407,10 @@ static int movement_speed(unit * u)
|
||||||
mp = BP_DRAGON;
|
mp = BP_DRAGON;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
mp = canride(u);
|
||||||
|
if (mp>=BP_RIDING) {
|
||||||
|
dk = 1.0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1426,38 +1422,22 @@ static int movement_speed(unit * u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (canride(u)) {
|
/* unicorn in inventory */
|
||||||
case 1: /* Pferd */
|
if (u->number <= i_get(u->items, it_find("fairyboot"))) {
|
||||||
mp = BP_RIDING;
|
mp *= 2;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case 2: /* Einhorn */
|
/* Im Astralraum sind Tyb und Ill-Magier doppelt so schnell.
|
||||||
mp = BP_UNICORN;
|
* Nicht kumulativ mit anderen Beschleunigungen! */
|
||||||
break;
|
if (mp * dk <= BP_WALKING * u_race(u)->speed && is_astral(u->region)) {
|
||||||
|
sc_mage *mage = get_mage(u);
|
||||||
default:
|
if (mage && (mage->magietyp == M_TYBIED || mage->magietyp == M_ILLAUN)) {
|
||||||
/* Siebenmeilentee */
|
if (has_skill(u, SK_MAGIC)) {
|
||||||
if (get_effect(u, oldpotiontype[P_FAST]) >= u->number) {
|
|
||||||
mp *= 2;
|
|
||||||
change_effect(u, oldpotiontype[P_FAST], -u->number);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unicorn in inventory */
|
|
||||||
if (u->number <= i_get(u->items, it_find("fairyboot"))) {
|
|
||||||
mp *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Im Astralraum sind Tyb und Ill-Magier doppelt so schnell.
|
|
||||||
* Nicht kumulativ mit anderen Beschleunigungen! */
|
|
||||||
if (mp * dk <= BP_WALKING * u_race(u)->speed && is_astral(u->region)
|
|
||||||
&& is_mage(u)) {
|
|
||||||
sc_mage *mage = get_mage(u);
|
|
||||||
if (mage->magietyp == M_TYBIED || mage->magietyp == M_ILLAUN) {
|
|
||||||
mp *= 2;
|
mp *= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)(dk * mp);
|
return (int)(dk * mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2044,7 +2024,7 @@ static const region_list *travel_i(unit * u, const region_list * route_begin,
|
||||||
const region_list * route_end, order * ord, int mode, follower ** followers)
|
const region_list * route_end, order * ord, int mode, follower ** followers)
|
||||||
{
|
{
|
||||||
region *r = u->region;
|
region *r = u->region;
|
||||||
|
int mp;
|
||||||
if (u->building && !can_leave(u)) {
|
if (u->building && !can_leave(u)) {
|
||||||
cmistake(u, u->thisorder, 150, MSG_MOVE);
|
cmistake(u, u->thisorder, 150, MSG_MOVE);
|
||||||
return route_begin;
|
return route_begin;
|
||||||
|
@ -2060,7 +2040,15 @@ static const region_list *travel_i(unit * u, const region_list * route_begin,
|
||||||
cmistake(u, ord, 42, MSG_MOVE);
|
cmistake(u, ord, 42, MSG_MOVE);
|
||||||
return route_begin;
|
return route_begin;
|
||||||
}
|
}
|
||||||
route_end = cap_route(r, route_begin, route_end, movement_speed(u));
|
|
||||||
|
mp = movement_speed(u);
|
||||||
|
/* Siebenmeilentee */
|
||||||
|
if (get_effect(u, oldpotiontype[P_FAST]) >= u->number) {
|
||||||
|
mp *= 2;
|
||||||
|
change_effect(u, oldpotiontype[P_FAST], -u->number);
|
||||||
|
}
|
||||||
|
|
||||||
|
route_end = cap_route(r, route_begin, route_end, mp);
|
||||||
|
|
||||||
route_end = travel_route(u, route_begin, route_end, ord, mode);
|
route_end = travel_route(u, route_begin, route_end, ord, mode);
|
||||||
if (u->flags&UFL_FOLLOWED) {
|
if (u->flags&UFL_FOLLOWED) {
|
||||||
|
|
|
@ -36,6 +36,14 @@ extern "C" {
|
||||||
extern struct attrib_type at_shiptrail;
|
extern struct attrib_type at_shiptrail;
|
||||||
extern int *storms;
|
extern int *storms;
|
||||||
|
|
||||||
|
/* Bewegungsweiten: */
|
||||||
|
#define BP_WALKING 4
|
||||||
|
#define BP_RIDING 6
|
||||||
|
#define BP_UNICORN 9
|
||||||
|
#define BP_DRAGON 4
|
||||||
|
#define BP_NORMAL 3
|
||||||
|
#define BP_ROAD 2
|
||||||
|
|
||||||
/* die Zahlen sind genau äquivalent zu den race Flags */
|
/* die Zahlen sind genau äquivalent zu den race Flags */
|
||||||
#define MV_CANNOTMOVE (1<<5)
|
#define MV_CANNOTMOVE (1<<5)
|
||||||
#define MV_FLY (1<<7) /* kann fliegen */
|
#define MV_FLY (1<<7) /* kann fliegen */
|
||||||
|
@ -70,6 +78,7 @@ extern "C" {
|
||||||
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);
|
||||||
|
int movement_speed(const struct unit * u);
|
||||||
void follow_unit(struct unit *u);
|
void follow_unit(struct unit *u);
|
||||||
struct unit *owner_buildingtyp(const struct region *r,
|
struct unit *owner_buildingtyp(const struct region *r,
|
||||||
const struct building_type *bt);
|
const struct building_type *bt);
|
||||||
|
|
|
@ -522,9 +522,33 @@ static void test_ship_leave_trail(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_movement_speed(CuTest *tc) {
|
||||||
|
unit * u;
|
||||||
|
race * rc;
|
||||||
|
const struct item_type *it_horse;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
it_horse = test_create_horse();
|
||||||
|
rc = test_create_race(NULL);
|
||||||
|
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, NULL));
|
||||||
|
|
||||||
|
rc->speed = 1.0;
|
||||||
|
CuAssertIntEquals(tc, BP_WALKING, movement_speed(u));
|
||||||
|
|
||||||
|
rc->speed = 2.0;
|
||||||
|
CuAssertIntEquals(tc, 2 * BP_WALKING, movement_speed(u));
|
||||||
|
|
||||||
|
set_level(u, SK_RIDING, 1);
|
||||||
|
i_change(&u->items, it_horse, 1);
|
||||||
|
CuAssertIntEquals(tc, BP_RIDING, movement_speed(u));
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_move_suite(void)
|
CuSuite *get_move_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_movement_speed);
|
||||||
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_leave_trail);
|
||||||
|
|
|
@ -1090,6 +1090,9 @@ void report_region(struct stream *out, const region * r, faction * f)
|
||||||
message *msg;
|
message *msg;
|
||||||
|
|
||||||
if (owner != NULL) {
|
if (owner != NULL) {
|
||||||
|
bytes = (int)strlcpy(bufp, " ", size);
|
||||||
|
if (wrptr(&bufp, &size, bytes) != 0)
|
||||||
|
WARN_STATIC_BUFFER();
|
||||||
msg = msg_message("nr_region_owner", "faction", owner);
|
msg = msg_message("nr_region_owner", "faction", owner);
|
||||||
bytes = (int)nr_render(msg, f->locale, bufp, size, f);
|
bytes = (int)nr_render(msg, f->locale, bufp, size, f);
|
||||||
msg_release(msg);
|
msg_release(msg);
|
||||||
|
|
|
@ -819,8 +819,9 @@ spskill(char *buffer, size_t size, const struct locale * lang,
|
||||||
bufp = STRLCPY(bufp, " ", size);
|
bufp = STRLCPY(bufp, " ", size);
|
||||||
|
|
||||||
if (sv->id == SK_MAGIC) {
|
if (sv->id == SK_MAGIC) {
|
||||||
sc_mage *mage = get_mage(u);
|
sc_mage *mage = get_mage_depr(u);
|
||||||
if (mage && mage->magietyp != M_GRAY) {
|
assert(mage);
|
||||||
|
if (mage->magietyp != M_GRAY) {
|
||||||
bufp = STRLCPY(bufp, LOC(lang, mkname("school",
|
bufp = STRLCPY(bufp, LOC(lang, mkname("school",
|
||||||
magic_school[mage->magietyp])), size);
|
magic_school[mage->magietyp])), size);
|
||||||
bufp = STRLCPY(bufp, " ", size);
|
bufp = STRLCPY(bufp, " ", size);
|
||||||
|
|
46
src/spells.c
46
src/spells.c
|
@ -39,7 +39,6 @@
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
#include <kernel/curse.h>
|
#include <kernel/curse.h>
|
||||||
#include <kernel/connection.h>
|
#include <kernel/connection.h>
|
||||||
#include <kernel/equipment.h>
|
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
#include <kernel/item.h>
|
#include <kernel/item.h>
|
||||||
#include <kernel/messages.h>
|
#include <kernel/messages.h>
|
||||||
|
@ -513,32 +512,26 @@ static const race *select_familiar(const race * magerace, magic_t magiegebiet)
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* der Vertraue des Magiers */
|
/* der Vertraue des Magiers */
|
||||||
|
|
||||||
static void make_familiar(unit * familiar, unit * mage)
|
static unit * make_familiar(unit * mage, region *r, const race *rc, const char *name)
|
||||||
{
|
{
|
||||||
/* skills and spells: */
|
unit *fam;
|
||||||
const struct equipment *eq;
|
|
||||||
char eqname[64];
|
fam = create_unit(r, mage->faction, 1, rc, 0, name, mage);
|
||||||
const race * rc = u_race(familiar);
|
setstatus(fam, ST_FLEE);
|
||||||
snprintf(eqname, sizeof(eqname), "fam_%s", rc->_name);
|
fset(fam, UFL_LOCKED);
|
||||||
eq = get_equipment(eqname);
|
|
||||||
if (eq != NULL) {
|
|
||||||
equip_items(&familiar->items, eq);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log_info("could not perform initialization for familiar %s.\n", rc->_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* triggers: */
|
/* triggers: */
|
||||||
create_newfamiliar(mage, familiar);
|
create_newfamiliar(mage, fam);
|
||||||
|
|
||||||
/* Hitpoints nach Talenten korrigieren, sonst starten vertraute
|
/* Hitpoints nach Talenten korrigieren, sonst starten vertraute
|
||||||
* mit Ausdauerbonus verwundet */
|
* mit Ausdauerbonus verwundet */
|
||||||
familiar->hp = unit_max_hp(familiar);
|
fam->hp = unit_max_hp(fam);
|
||||||
|
|
||||||
|
return fam;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sp_summon_familiar(castorder * co)
|
static int sp_summon_familiar(castorder * co)
|
||||||
{
|
{
|
||||||
unit *familiar;
|
|
||||||
region *r = co_get_region(co);
|
region *r = co_get_region(co);
|
||||||
unit *mage = co->magician.u;
|
unit *mage = co->magician.u;
|
||||||
int cast_level = co->level;
|
int cast_level = co->level;
|
||||||
|
@ -586,10 +579,7 @@ static int sp_summon_familiar(castorder * co)
|
||||||
msg = msg_message("familiar_name", "unit", mage);
|
msg = msg_message("familiar_name", "unit", mage);
|
||||||
nr_render(msg, mage->faction->locale, zText, sizeof(zText), mage->faction);
|
nr_render(msg, mage->faction->locale, zText, sizeof(zText), mage->faction);
|
||||||
msg_release(msg);
|
msg_release(msg);
|
||||||
familiar = create_unit(r, mage->faction, 1, rc, 0, zText, mage);
|
make_familiar(mage, r, rc, zText);
|
||||||
setstatus(familiar, ST_FLEE);
|
|
||||||
fset(familiar, UFL_LOCKED);
|
|
||||||
make_familiar(familiar, mage);
|
|
||||||
|
|
||||||
dh = 0;
|
dh = 0;
|
||||||
dh1 = 0;
|
dh1 = 0;
|
||||||
|
@ -740,7 +730,7 @@ static int sp_transferaura(castorder * co)
|
||||||
int cast_level = co->level;
|
int cast_level = co->level;
|
||||||
spellparameter *pa = co->par;
|
spellparameter *pa = co->par;
|
||||||
unit *u;
|
unit *u;
|
||||||
sc_mage *scm_dst, *scm_src = get_mage(mage);
|
sc_mage *scm_dst, *scm_src = get_mage_depr(mage);
|
||||||
|
|
||||||
/* wenn kein Ziel gefunden, Zauber abbrechen */
|
/* wenn kein Ziel gefunden, Zauber abbrechen */
|
||||||
if (pa->param[0]->flag == TARGET_NOTFOUND)
|
if (pa->param[0]->flag == TARGET_NOTFOUND)
|
||||||
|
@ -754,7 +744,7 @@ static int sp_transferaura(castorder * co)
|
||||||
/* Wieviel Transferieren? */
|
/* Wieviel Transferieren? */
|
||||||
aura = pa->param[1]->data.i;
|
aura = pa->param[1]->data.i;
|
||||||
u = pa->param[0]->data.u;
|
u = pa->param[0]->data.u;
|
||||||
scm_dst = get_mage(u);
|
scm_dst = get_mage_depr(u);
|
||||||
|
|
||||||
if (scm_dst == NULL) {
|
if (scm_dst == NULL) {
|
||||||
/* "Zu dieser Einheit kann ich keine Aura uebertragen." */
|
/* "Zu dieser Einheit kann ich keine Aura uebertragen." */
|
||||||
|
@ -5822,7 +5812,7 @@ int sp_permtransfer(castorder * co)
|
||||||
change_maxspellpoints(mage, -aura);
|
change_maxspellpoints(mage, -aura);
|
||||||
change_spellpoints(mage, -aura);
|
change_spellpoints(mage, -aura);
|
||||||
|
|
||||||
if (get_mage(tu)->magietyp == get_mage(mage)->magietyp) {
|
if (get_mage_depr(tu)->magietyp == get_mage_depr(mage)->magietyp) {
|
||||||
change_maxspellpoints(tu, aura / 2);
|
change_maxspellpoints(tu, aura / 2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -5945,18 +5935,18 @@ int sp_stealaura(castorder * co)
|
||||||
/* Zieleinheit */
|
/* Zieleinheit */
|
||||||
u = pa->param[0]->data.u;
|
u = pa->param[0]->data.u;
|
||||||
|
|
||||||
if (!get_mage(u)) {
|
if (!get_mage_depr(u)) {
|
||||||
ADDMSG(&mage->faction->msgs, msg_message("stealaura_fail", "unit target",
|
ADDMSG(&mage->faction->msgs, msg_message("stealaura_fail", "unit target",
|
||||||
mage, u));
|
mage, u));
|
||||||
ADDMSG(&u->faction->msgs, msg_message("stealaura_fail_detect", "unit", u));
|
ADDMSG(&u->faction->msgs, msg_message("stealaura_fail_detect", "unit", u));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
taura = (get_mage(u)->spellpoints * (rng_int() % (int)(3 * power) + 1)) / 100;
|
taura = (get_mage_depr(u)->spellpoints * (rng_int() % (int)(3 * power) + 1)) / 100;
|
||||||
|
|
||||||
if (taura > 0) {
|
if (taura > 0) {
|
||||||
get_mage(u)->spellpoints -= taura;
|
get_mage_depr(u)->spellpoints -= taura;
|
||||||
get_mage(mage)->spellpoints += taura;
|
get_mage_depr(mage)->spellpoints += taura;
|
||||||
/* sprintf(buf, "%s entzieht %s %d Aura.", unitname(mage), unitname(u),
|
/* sprintf(buf, "%s entzieht %s %d Aura.", unitname(mage), unitname(u),
|
||||||
taura); */
|
taura); */
|
||||||
ADDMSG(&mage->faction->msgs, msg_message("stealaura_success",
|
ADDMSG(&mage->faction->msgs, msg_message("stealaura_success",
|
||||||
|
|
|
@ -68,7 +68,7 @@ void spy_message(int spy, const unit * u, const unit * target)
|
||||||
ADDMSG(&u->faction->msgs, msg_message("spyreport", "spy target status", u,
|
ADDMSG(&u->faction->msgs, msg_message("spyreport", "spy target status", u,
|
||||||
target, status));
|
target, status));
|
||||||
if (spy > 20) {
|
if (spy > 20) {
|
||||||
sc_mage *mage = get_mage(target);
|
sc_mage *mage = get_mage_depr(target);
|
||||||
/* for mages, spells and magic school */
|
/* for mages, spells and magic school */
|
||||||
if (mage) {
|
if (mage) {
|
||||||
ADDMSG(&u->faction->msgs, msg_message("spyreport_mage", "spy target type", u,
|
ADDMSG(&u->faction->msgs, msg_message("spyreport_mage", "spy target type", u,
|
||||||
|
|
|
@ -427,8 +427,8 @@ int teach_cmd(unit * teacher, struct order *ord)
|
||||||
if (sk == SK_MAGIC) {
|
if (sk == SK_MAGIC) {
|
||||||
/* ist der Magier schon spezialisiert, so versteht er nur noch
|
/* ist der Magier schon spezialisiert, so versteht er nur noch
|
||||||
* Lehrer seines Gebietes */
|
* Lehrer seines Gebietes */
|
||||||
sc_mage *mage1 = get_mage(teacher);
|
sc_mage *mage1 = get_mage_depr(teacher);
|
||||||
sc_mage *mage2 = get_mage(student);
|
sc_mage *mage2 = get_mage_depr(student);
|
||||||
if (mage2 && mage1 && mage2->magietyp != M_GRAY
|
if (mage2 && mage1 && mage2->magietyp != M_GRAY
|
||||||
&& mage1->magietyp != mage2->magietyp) {
|
&& mage1->magietyp != mage2->magietyp) {
|
||||||
if (feedback) {
|
if (feedback) {
|
||||||
|
@ -782,7 +782,7 @@ int study_cmd(unit * u, order * ord)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sk == SK_MAGIC) {
|
else if (sk == SK_MAGIC) {
|
||||||
sc_mage *mage = get_mage(u);
|
sc_mage *mage = get_mage_depr(u);
|
||||||
if (!mage) {
|
if (!mage) {
|
||||||
mage = create_mage(u, u->faction->magiegebiet);
|
mage = create_mage(u, u->faction->magiegebiet);
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,11 +409,11 @@ static void test_study_magic(CuTest *tc) {
|
||||||
study_cmd(u, u->thisorder);
|
study_cmd(u, u->thisorder);
|
||||||
CuAssertIntEquals(tc, M_GWYRRD, f->magiegebiet);
|
CuAssertIntEquals(tc, M_GWYRRD, f->magiegebiet);
|
||||||
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
|
CuAssertIntEquals(tc, 0, i_get(u->items, rtype->itype));
|
||||||
CuAssertPtrNotNull(tc, get_mage(u));
|
CuAssertPtrNotNull(tc, get_mage_depr(u));
|
||||||
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error65"));
|
CuAssertPtrEquals(tc, 0, test_find_messagetype(f->msgs, "error65"));
|
||||||
CuAssertIntEquals(tc, M_GWYRRD, get_mage(u)->magietyp);
|
CuAssertIntEquals(tc, M_GWYRRD, get_mage_depr(u)->magietyp);
|
||||||
|
|
||||||
/* the static cost array in study_cost prevents this test:
|
/* TODO: the static cost array in study_cost prevents this test:
|
||||||
test_clear_messages(f);
|
test_clear_messages(f);
|
||||||
config_set("skills.cost.magic", "50");
|
config_set("skills.cost.magic", "50");
|
||||||
i_change(&u->items, rtype->itype, 50);
|
i_change(&u->items, rtype->itype, 50);
|
||||||
|
|
|
@ -101,6 +101,7 @@ int RunAllTests(int argc, char *argv[])
|
||||||
ADD_SUITE(pool);
|
ADD_SUITE(pool);
|
||||||
ADD_SUITE(curse);
|
ADD_SUITE(curse);
|
||||||
ADD_SUITE(equipment);
|
ADD_SUITE(equipment);
|
||||||
|
ADD_SUITE(familiar);
|
||||||
ADD_SUITE(item);
|
ADD_SUITE(item);
|
||||||
ADD_SUITE(magic);
|
ADD_SUITE(magic);
|
||||||
ADD_SUITE(alchemy);
|
ADD_SUITE(alchemy);
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
struct race *test_create_race(const char *name)
|
struct race *test_create_race(const char *name)
|
||||||
{
|
{
|
||||||
race *rc = rc_get_or_create(name);
|
race *rc = rc_get_or_create(name ? name : "smurf");
|
||||||
rc->maintenance = 10;
|
rc->maintenance = 10;
|
||||||
rc->hitpoints = 20;
|
rc->hitpoints = 20;
|
||||||
rc->maxaura = 100;
|
rc->maxaura = 100;
|
||||||
|
|
|
@ -396,7 +396,6 @@ int a_age(attrib ** p, void *owner)
|
||||||
|
|
||||||
static critbit_tree cb_deprecated = { 0 };
|
static critbit_tree cb_deprecated = { 0 };
|
||||||
|
|
||||||
|
|
||||||
typedef struct deprecated_s {
|
typedef struct deprecated_s {
|
||||||
unsigned int hash;
|
unsigned int hash;
|
||||||
int(*reader)(attrib *, void *, struct gamedata *);
|
int(*reader)(attrib *, void *, struct gamedata *);
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
/* unfinished: */
|
/* unfinished: */
|
||||||
#define CRYPT_VERSION 400 /* passwords are encrypted */
|
#define CRYPT_VERSION 400 /* passwords are encrypted */
|
||||||
|
|
||||||
#define RELEASE_VERSION SKILLSORT_VERSION /* current datafile */
|
#define RELEASE_VERSION LANDDISPLAY_VERSION /* current datafile */
|
||||||
#define MIN_VERSION UIDHASH_VERSION /* minimal datafile we support */
|
#define MIN_VERSION UIDHASH_VERSION /* minimal datafile we support */
|
||||||
#define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */
|
#define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ assert_grep_count() {
|
||||||
file=$1
|
file=$1
|
||||||
expr=$2
|
expr=$2
|
||||||
expect=$3
|
expect=$3
|
||||||
count=`grep -cE $expr $file`
|
count=`grep -cE "$expr" $file`
|
||||||
[ $count -eq $expect ] || quit 1 "expected $expect counts of $expr in $file, got $count"
|
[ $count -eq $expect ] || quit 1 "expected $expect counts of $expr in $file, got $count"
|
||||||
echo "PASS: $expr is $expect"
|
echo "PASS: $expr is $expect"
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ setup
|
||||||
cleanup
|
cleanup
|
||||||
VALGRIND=`which valgrind`
|
VALGRIND=`which valgrind`
|
||||||
SERVER=../Debug/eressea/eressea
|
SERVER=../Debug/eressea/eressea
|
||||||
set -e
|
#set -e
|
||||||
if [ -n "$VALGRIND" ]; then
|
if [ -n "$VALGRIND" ]; then
|
||||||
SUPP=../share/ubuntu-12_04.supp
|
SUPP=../share/ubuntu-12_04.supp
|
||||||
SERVER="$VALGRIND --track-origins=yes --gen-suppressions=all --suppressions=$SUPP --error-exitcode=1 --leak-check=no $SERVER"
|
SERVER="$VALGRIND --track-origins=yes --gen-suppressions=all --suppressions=$SUPP --error-exitcode=1 --leak-check=no $SERVER"
|
||||||
|
@ -62,5 +62,6 @@ assert_grep_count reports/185-heg.cr '"lighthouse";visibility' 6
|
||||||
assert_grep_count reports/185-heg.cr '"neighbour";visibility' 11
|
assert_grep_count reports/185-heg.cr '"neighbour";visibility' 11
|
||||||
assert_grep_count reports/185-6rLo.cr '^EINHEIT' 2
|
assert_grep_count reports/185-6rLo.cr '^EINHEIT' 2
|
||||||
assert_grep_count reports/185-6rLo.cr '^REGION' 13
|
assert_grep_count reports/185-6rLo.cr '^REGION' 13
|
||||||
|
assert_grep_count reports/185-6rLo.cr "Befehl ist unbekannt" 0
|
||||||
echo "integration tests: PASS"
|
echo "integration tests: PASS"
|
||||||
cleanup
|
cleanup
|
||||||
|
|
Loading…
Reference in New Issue