forked from github/server
Merge pull request #2 from ennorehling/feature/bug-2080-destroy-and-thisorder
merge bug 2080: destroy and thisorder
This commit is contained in:
commit
91efc30afd
|
@ -2830,17 +2830,6 @@
|
||||||
<text locale="de">"$unit($unit) in $region($region) produziert $int($amount)$if($eq($wanted,$amount),""," von $int($wanted)") $resource($resource,$wanted)."</text>
|
<text locale="de">"$unit($unit) in $region($region) produziert $int($amount)$if($eq($wanted,$amount),""," von $int($wanted)") $resource($resource,$wanted)."</text>
|
||||||
<text locale="en">"$unit($unit) in $region($region) produces $int($amount)$if($eq($wanted,$amount),""," of $int($wanted)") $resource($resource,$amount)."</text>
|
<text locale="en">"$unit($unit) in $region($region) produces $int($amount)$if($eq($wanted,$amount),""," of $int($wanted)") $resource($resource,$amount)."</text>
|
||||||
</message>
|
</message>
|
||||||
<message name="manufacture" section="production">
|
|
||||||
<type>
|
|
||||||
<arg name="unit" type="unit"/>
|
|
||||||
<arg name="region" type="region"/>
|
|
||||||
<arg name="amount" type="int"/>
|
|
||||||
<arg name="wanted" type="int"/>
|
|
||||||
<arg name="resource" type="resource"/>
|
|
||||||
</type>
|
|
||||||
<text locale="de">"$unit($unit) in $region($region) produziert $int($amount)$if($eq($wanted,$amount),""," von $int($wanted)") $resource($resource,$wanted)."</text>
|
|
||||||
<text locale="en">"$unit($unit) in $region($region) produces $int($amount)$if($eq($wanted,$amount),""," of $int($wanted)") $resource($resource,$amount)."</text>
|
|
||||||
</message>
|
|
||||||
<message name="buildbuilding" section="production">
|
<message name="buildbuilding" section="production">
|
||||||
<type>
|
<type>
|
||||||
<arg name="unit" type="unit"/>
|
<arg name="unit" type="unit"/>
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
local pkg = {}
|
local pkg = {}
|
||||||
|
|
||||||
print("loading jsreport module")
|
|
||||||
|
|
||||||
function pkg.init()
|
function pkg.init()
|
||||||
eressea.settings.set("feature.jsreport.enable", "1")
|
eressea.settings.set("feature.jsreport.enable", "1")
|
||||||
end
|
end
|
||||||
|
|
|
@ -460,7 +460,6 @@ function test_canoe_passes_through_land()
|
||||||
u1:add_order("NACH O O O")
|
u1:add_order("NACH O O O")
|
||||||
process_orders()
|
process_orders()
|
||||||
assert_equal(land, u2.region, "canoe did not stop at coast")
|
assert_equal(land, u2.region, "canoe did not stop at coast")
|
||||||
u1:add_order("NACH O O O")
|
|
||||||
process_orders()
|
process_orders()
|
||||||
assert_equal(dst, sh.region, "canoe could not leave coast")
|
assert_equal(dst, sh.region, "canoe could not leave coast")
|
||||||
assert_equal(dst, u1.region, "canoe could not leave coast")
|
assert_equal(dst, u1.region, "canoe could not leave coast")
|
||||||
|
|
|
@ -58,7 +58,6 @@ function test_magic()
|
||||||
u:add_spell("protective_runes")
|
u:add_spell("protective_runes")
|
||||||
u:add_spell("analyze_magic")
|
u:add_spell("analyze_magic")
|
||||||
u:clear_orders()
|
u:clear_orders()
|
||||||
u:add_order("ZAUBERE \"Runen des Schutzes\" BURG " .. itoa36(b.id));
|
|
||||||
u.building = b
|
u.building = b
|
||||||
u:add_order("ZAUBERE \"Magie analysieren\" BURG " .. itoa36(b.id));
|
u:add_order("ZAUBERE \"Magie analysieren\" BURG " .. itoa36(b.id));
|
||||||
process_orders()
|
process_orders()
|
||||||
|
|
|
@ -3232,7 +3232,7 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Illusionen und Zauber kaempfen nicht */
|
/* Illusionen und Zauber kaempfen nicht */
|
||||||
if (fval(u_race(u), RCF_ILLUSIONARY) || idle(u->faction) || u->number == 0) {
|
if (fval(u_race(u), RCF_ILLUSIONARY) || u->number == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (s1 == NULL) {
|
if (s1 == NULL) {
|
||||||
|
|
|
@ -929,7 +929,8 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
for (ord = u->orders; ord; ord = ord->next) {
|
||||||
if (u->old_orders && is_repeated(ord))
|
keyword_t kwd = getkeyword(ord);
|
||||||
|
if (u->old_orders && is_repeated(kwd))
|
||||||
continue; /* unit has defaults */
|
continue; /* unit has defaults */
|
||||||
if (is_persistent(ord)) {
|
if (is_persistent(ord)) {
|
||||||
fwriteorder(F, ord, f->locale, true);
|
fwriteorder(F, ord, f->locale, true);
|
||||||
|
|
|
@ -563,7 +563,7 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!playerrace(rc) || idle(u->faction)) {
|
if (!playerrace(rc)) {
|
||||||
cmistake(u, ord, 139, MSG_EVENT);
|
cmistake(u, ord, 139, MSG_EVENT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -979,26 +979,13 @@ void economics(region * r)
|
||||||
remove_empty_units_in_region(r);
|
remove_empty_units_in_region(r);
|
||||||
|
|
||||||
for (u = r->units; u; u = u->next) {
|
for (u = r->units; u; u = u->next) {
|
||||||
order *ord;
|
order *ord = u->thisorder;
|
||||||
bool destroyed = false;
|
keyword_t kwd = getkeyword(ord);
|
||||||
if (u->number > 0) {
|
if (kwd == K_DESTROY) {
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
if (destroy_cmd(u, ord) == 0) {
|
||||||
keyword_t kwd = getkeyword(ord);
|
fset(u, UFL_LONGACTION | UFL_NOTMOVING);
|
||||||
if (kwd == K_DESTROY) {
|
|
||||||
if (!destroyed) {
|
|
||||||
if (destroy_cmd(u, ord) != 0)
|
|
||||||
ord = NULL;
|
|
||||||
destroyed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (u->orders == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (destroyed) {
|
|
||||||
fset(u, UFL_LONGACTION | UFL_NOTMOVING);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1051,7 +1038,7 @@ static void manufacture(unit * u, const item_type * itype, int want)
|
||||||
i_change(&u->items, itype, n);
|
i_change(&u->items, itype, n);
|
||||||
if (want == INT_MAX)
|
if (want == INT_MAX)
|
||||||
want = n;
|
want = n;
|
||||||
ADDMSG(&u->faction->msgs, msg_message("manufacture",
|
ADDMSG(&u->faction->msgs, msg_message("produce",
|
||||||
"unit region amount wanted resource", u, u->region, n, want,
|
"unit region amount wanted resource", u, u->region, n, want,
|
||||||
itype->rtype));
|
itype->rtype));
|
||||||
}
|
}
|
||||||
|
@ -1466,7 +1453,7 @@ static void create_potion(unit * u, const potion_type * ptype, int want)
|
||||||
i_change(&u->items, ptype->itype, built);
|
i_change(&u->items, ptype->itype, built);
|
||||||
if (want == INT_MAX)
|
if (want == INT_MAX)
|
||||||
want = built;
|
want = built;
|
||||||
ADDMSG(&u->faction->msgs, msg_message("manufacture",
|
ADDMSG(&u->faction->msgs, msg_message("produce",
|
||||||
"unit region amount wanted resource", u, u->region, built, want,
|
"unit region amount wanted resource", u, u->region, built, want,
|
||||||
ptype->itype->rtype));
|
ptype->itype->rtype));
|
||||||
break;
|
break;
|
||||||
|
@ -3216,7 +3203,7 @@ void produce(struct region *r)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (fval(u, UFL_LONGACTION) && u->thisorder == NULL) {
|
if (fval(u, UFL_LONGACTION) && u->thisorder == NULL) {
|
||||||
/* this message was already given in laws.setdefaults
|
/* this message was already given in laws.c:update_long_order
|
||||||
cmistake(u, u->thisorder, 52, MSG_PRODUCE);
|
cmistake(u, u->thisorder, 52, MSG_PRODUCE);
|
||||||
*/
|
*/
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -151,11 +151,11 @@ int destroy_cmd(unit * u, struct order *ord)
|
||||||
int n = INT_MAX;
|
int n = INT_MAX;
|
||||||
|
|
||||||
if (u->number < 1)
|
if (u->number < 1)
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
if (fval(u, UFL_LONGACTION)) {
|
if (fval(u, UFL_LONGACTION)) {
|
||||||
cmistake(u, ord, 52, MSG_PRODUCE);
|
cmistake(u, ord, 52, MSG_PRODUCE);
|
||||||
return 0;
|
return 52;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_order(ord);
|
init_order(ord);
|
||||||
|
@ -183,11 +183,11 @@ int destroy_cmd(unit * u, struct order *ord)
|
||||||
|
|
||||||
if (u != building_owner(b)) {
|
if (u != building_owner(b)) {
|
||||||
cmistake(u, ord, 138, MSG_PRODUCE);
|
cmistake(u, ord, 138, MSG_PRODUCE);
|
||||||
return 0;
|
return 138;
|
||||||
}
|
}
|
||||||
if (fval(b->type, BTF_INDESTRUCTIBLE)) {
|
if (fval(b->type, BTF_INDESTRUCTIBLE)) {
|
||||||
cmistake(u, ord, 138, MSG_PRODUCE);
|
cmistake(u, ord, 138, MSG_PRODUCE);
|
||||||
return 0;
|
return 138;
|
||||||
}
|
}
|
||||||
if (n >= b->size) {
|
if (n >= b->size) {
|
||||||
/* destroy completly */
|
/* destroy completly */
|
||||||
|
@ -213,11 +213,11 @@ int destroy_cmd(unit * u, struct order *ord)
|
||||||
|
|
||||||
if (u != ship_owner(sh)) {
|
if (u != ship_owner(sh)) {
|
||||||
cmistake(u, ord, 138, MSG_PRODUCE);
|
cmistake(u, ord, 138, MSG_PRODUCE);
|
||||||
return 0;
|
return 138;
|
||||||
}
|
}
|
||||||
if (fval(r->terrain, SEA_REGION)) {
|
if (fval(r->terrain, SEA_REGION)) {
|
||||||
cmistake(u, ord, 14, MSG_EVENT);
|
cmistake(u, ord, 14, MSG_EVENT);
|
||||||
return 0;
|
return 14;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n >= (sh->size * 100) / sh->type->construction->maxsize) {
|
if (n >= (sh->size * 100) / sh->type->construction->maxsize) {
|
||||||
|
@ -242,11 +242,11 @@ int destroy_cmd(unit * u, struct order *ord)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cmistake(u, ord, 138, MSG_PRODUCE);
|
cmistake(u, ord, 138, MSG_PRODUCE);
|
||||||
return 0;
|
return 138;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (con) {
|
if (con) {
|
||||||
/* TODO: Nicht an ZERSTÖRE mit Punktangabe angepaßt! */
|
/* TODO: Nicht an ZERSTÖRE mit Punktangabe angepasst! */
|
||||||
int c;
|
int c;
|
||||||
for (c = 0; con->materials[c].number; ++c) {
|
for (c = 0; con->materials[c].number; ++c) {
|
||||||
const requirement *rq = con->materials + c;
|
const requirement *rq = con->materials + c;
|
||||||
|
|
|
@ -906,11 +906,6 @@ int newcontainerid(void)
|
||||||
return random_no;
|
return random_no;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool idle(faction * f)
|
|
||||||
{
|
|
||||||
return (bool)(f ? false : true);
|
|
||||||
}
|
|
||||||
|
|
||||||
int maxworkingpeasants(const struct region *r)
|
int maxworkingpeasants(const struct region *r)
|
||||||
{
|
{
|
||||||
int size = production(r);
|
int size = production(r);
|
||||||
|
@ -1686,6 +1681,11 @@ void kernel_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static order * defaults[MAXLOCALES];
|
static order * defaults[MAXLOCALES];
|
||||||
|
keyword_t default_keyword = NOKEYWORD;
|
||||||
|
|
||||||
|
void set_default_order(int kwd) {
|
||||||
|
default_keyword = (keyword_t)kwd;
|
||||||
|
}
|
||||||
|
|
||||||
order *default_order(const struct locale *lang)
|
order *default_order(const struct locale *lang)
|
||||||
{
|
{
|
||||||
|
@ -1693,6 +1693,11 @@ order *default_order(const struct locale *lang)
|
||||||
int i = locale_index(lang);
|
int i = locale_index(lang);
|
||||||
order *result = 0;
|
order *result = 0;
|
||||||
assert(i < MAXLOCALES);
|
assert(i < MAXLOCALES);
|
||||||
|
|
||||||
|
if (default_keyword!=NOKEYWORD) {
|
||||||
|
return create_order(default_keyword, lang, 0);
|
||||||
|
}
|
||||||
|
|
||||||
result = defaults[i];
|
result = defaults[i];
|
||||||
if (!result && usedefault) {
|
if (!result && usedefault) {
|
||||||
const char * str = LOC(lang, "defaultorder");
|
const char * str = LOC(lang, "defaultorder");
|
||||||
|
|
|
@ -179,7 +179,6 @@ extern "C" {
|
||||||
bool has_limited_skills(const struct unit *u);
|
bool has_limited_skills(const struct unit *u);
|
||||||
const struct race *findrace(const char *, const struct locale *);
|
const struct race *findrace(const char *, const struct locale *);
|
||||||
|
|
||||||
bool idle(struct faction *f);
|
|
||||||
bool unit_has_cursed_item(const struct unit *u);
|
bool unit_has_cursed_item(const struct unit *u);
|
||||||
|
|
||||||
/* grammatik-flags: */
|
/* grammatik-flags: */
|
||||||
|
@ -287,7 +286,10 @@ extern "C" {
|
||||||
int AllianceAuto(void); /* flags that allied factions get automatically */
|
int AllianceAuto(void); /* flags that allied factions get automatically */
|
||||||
int AllianceRestricted(void); /* flags restricted to allied factions */
|
int AllianceRestricted(void); /* flags restricted to allied factions */
|
||||||
int HelpMask(void); /* flags restricted to allied factions */
|
int HelpMask(void); /* flags restricted to allied factions */
|
||||||
|
|
||||||
struct order *default_order(const struct locale *lang);
|
struct order *default_order(const struct locale *lang);
|
||||||
|
void set_default_order(int kwd);
|
||||||
|
|
||||||
int entertainmoney(const struct region *r);
|
int entertainmoney(const struct region *r);
|
||||||
|
|
||||||
void free_gamedata(void);
|
void free_gamedata(void);
|
||||||
|
|
|
@ -252,6 +252,19 @@ static order_data *create_data(keyword_t kwd, const char *sptr, int lindex)
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void free_localedata(int lindex) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i != MAXKEYWORDS; ++i) {
|
||||||
|
release_data(locale_array[lindex]->short_orders[i]);
|
||||||
|
locale_array[lindex]->short_orders[i] = 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i != MAXSKILLS; ++i) {
|
||||||
|
release_data(locale_array[lindex]->study_orders[i]);
|
||||||
|
locale_array[lindex]->study_orders[i] = 0;
|
||||||
|
}
|
||||||
|
locale_array[lindex]->lang = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent,
|
static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent,
|
||||||
const struct locale *lang)
|
const struct locale *lang)
|
||||||
{
|
{
|
||||||
|
@ -276,7 +289,12 @@ static order *create_order_i(keyword_t kwd, const char *sptr, bool persistent,
|
||||||
|
|
||||||
lindex = locale_index(lang);
|
lindex = locale_index(lang);
|
||||||
assert(lindex < MAXLOCALES);
|
assert(lindex < MAXLOCALES);
|
||||||
locale_array[lindex] = (locale_data *)calloc(1, sizeof(locale_data));
|
if (!locale_array[lindex]) {
|
||||||
|
locale_array[lindex] = (locale_data *)calloc(1, sizeof(locale_data));
|
||||||
|
}
|
||||||
|
else if (locale_array[lindex]->lang != lang) {
|
||||||
|
free_localedata(lindex);
|
||||||
|
}
|
||||||
locale_array[lindex]->lang = lang;
|
locale_array[lindex]->lang = lang;
|
||||||
|
|
||||||
ord = (order *)malloc(sizeof(order));
|
ord = (order *)malloc(sizeof(order));
|
||||||
|
@ -292,13 +310,13 @@ order *create_order(keyword_t kwd, const struct locale * lang,
|
||||||
const char *params, ...)
|
const char *params, ...)
|
||||||
{
|
{
|
||||||
char zBuffer[DISPLAYSIZE];
|
char zBuffer[DISPLAYSIZE];
|
||||||
assert(lang);
|
|
||||||
if (params) {
|
if (params) {
|
||||||
char *bufp = zBuffer;
|
char *bufp = zBuffer;
|
||||||
int bytes;
|
int bytes;
|
||||||
size_t size = sizeof(zBuffer) - 1;
|
size_t size = sizeof(zBuffer) - 1;
|
||||||
va_list marker;
|
va_list marker;
|
||||||
|
|
||||||
|
assert(lang);
|
||||||
va_start(marker, params);
|
va_start(marker, params);
|
||||||
while (*params) {
|
while (*params) {
|
||||||
if (*params == '%') {
|
if (*params == '%') {
|
||||||
|
@ -389,9 +407,8 @@ order *parse_order(const char *s, const struct locale * lang)
|
||||||
* \return true if the order is long
|
* \return true if the order is long
|
||||||
* \sa is_exclusive(), is_repeated(), is_persistent()
|
* \sa is_exclusive(), is_repeated(), is_persistent()
|
||||||
*/
|
*/
|
||||||
bool is_repeated(const order * ord)
|
bool is_repeated(keyword_t kwd)
|
||||||
{
|
{
|
||||||
keyword_t kwd = ORD_KEYWORD(ord);
|
|
||||||
switch (kwd) {
|
switch (kwd) {
|
||||||
case K_CAST:
|
case K_CAST:
|
||||||
case K_BUY:
|
case K_BUY:
|
||||||
|
@ -468,10 +485,8 @@ bool is_exclusive(const order * ord)
|
||||||
* \return true if the order is long
|
* \return true if the order is long
|
||||||
* \sa is_exclusive(), is_repeated(), is_persistent()
|
* \sa is_exclusive(), is_repeated(), is_persistent()
|
||||||
*/
|
*/
|
||||||
bool is_long(const order * ord)
|
bool is_long(keyword_t kwd)
|
||||||
{
|
{
|
||||||
keyword_t kwd = ORD_KEYWORD(ord);
|
|
||||||
|
|
||||||
switch (kwd) {
|
switch (kwd) {
|
||||||
case K_CAST:
|
case K_CAST:
|
||||||
case K_BUY:
|
case K_BUY:
|
||||||
|
@ -522,7 +537,7 @@ bool is_persistent(const order * ord)
|
||||||
case K_KOMMENTAR:
|
case K_KOMMENTAR:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return ord->_persistent || is_repeated(ord);
|
return ord->_persistent || is_repeated(kwd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,8 @@ extern "C" {
|
||||||
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_exclusive(const order * ord);
|
bool is_exclusive(const order * ord);
|
||||||
bool is_repeated(const order * ord);
|
bool is_repeated(keyword_t kwd);
|
||||||
bool is_long(const order * ord);
|
bool is_long(keyword_t kwd);
|
||||||
|
|
||||||
char *write_order(const order * ord, char *buffer, size_t size);
|
char *write_order(const order * ord, char *buffer, size_t size);
|
||||||
keyword_t init_order(const struct order *ord);
|
keyword_t init_order(const struct order *ord);
|
||||||
|
|
|
@ -139,7 +139,8 @@ static unit *unitorders(FILE * F, int enc, struct faction *f)
|
||||||
ordp = &u->old_orders;
|
ordp = &u->old_orders;
|
||||||
while (*ordp) {
|
while (*ordp) {
|
||||||
order *ord = *ordp;
|
order *ord = *ordp;
|
||||||
if (!is_repeated(ord)) {
|
keyword_t kwd = getkeyword(ord);
|
||||||
|
if (!is_repeated(kwd)) {
|
||||||
*ordp = ord->next;
|
*ordp = ord->next;
|
||||||
ord->next = NULL;
|
ord->next = NULL;
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
|
@ -777,7 +778,8 @@ void write_unit(struct gamedata *data, const unit * u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
for (ord = u->orders; ord; ord = ord->next) {
|
||||||
if (u->old_orders && is_repeated(ord))
|
keyword_t kwd = getkeyword(ord);
|
||||||
|
if (u->old_orders && is_repeated(kwd))
|
||||||
continue; /* has new defaults */
|
continue; /* has new defaults */
|
||||||
if (is_persistent(ord)) {
|
if (is_persistent(ord)) {
|
||||||
if (++p < MAXPERSISTENT) {
|
if (++p < MAXPERSISTENT) {
|
||||||
|
|
174
src/laws.c
174
src/laws.c
|
@ -3407,126 +3407,101 @@ void new_units(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks for two long orders and issues a warning if necessary.
|
void update_long_order(unit * u)
|
||||||
*/
|
|
||||||
void check_long_orders(unit * u)
|
|
||||||
{
|
{
|
||||||
order *ord;
|
order *ord;
|
||||||
keyword_t otherorder = MAXKEYWORDS;
|
bool exclusive = true;
|
||||||
|
keyword_t thiskwd = NOKEYWORD;
|
||||||
|
bool hunger = LongHunger(u);
|
||||||
|
|
||||||
|
freset(u, UFL_MOVED);
|
||||||
|
freset(u, UFL_LONGACTION);
|
||||||
|
|
||||||
|
/* check all orders for a potential new long order this round: */
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
for (ord = u->orders; ord; ord = ord->next) {
|
||||||
if (getkeyword(ord) == NOKEYWORD) {
|
keyword_t kwd = getkeyword(ord);
|
||||||
cmistake(u, ord, 22, MSG_EVENT);
|
if (kwd == NOKEYWORD) continue;
|
||||||
|
|
||||||
|
if (u->old_orders && is_repeated(kwd)) {
|
||||||
|
/* this new order will replace the old defaults */
|
||||||
|
free_orders(&u->old_orders);
|
||||||
}
|
}
|
||||||
else if (is_long(ord)) {
|
|
||||||
keyword_t longorder = getkeyword(ord);
|
// hungry units do not get long orders:
|
||||||
if (otherorder != MAXKEYWORDS) {
|
if (hunger) {
|
||||||
switch (longorder) {
|
if (u->old_orders) {
|
||||||
|
// keep looking for repeated orders that might clear the old_orders
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_long(kwd)) {
|
||||||
|
if (thiskwd == NOKEYWORD) {
|
||||||
|
// we have found the (first) long order
|
||||||
|
// some long orders can have multiple instances:
|
||||||
|
switch (kwd) {
|
||||||
|
/* Wenn gehandelt wird, darf kein langer Befehl ausgeführt
|
||||||
|
* werden. Da Handel erst nach anderen langen Befehlen kommt,
|
||||||
|
* muss das vorher abgefangen werden. Wir merken uns also
|
||||||
|
* hier, ob die Einheit handelt. */
|
||||||
|
case K_BUY:
|
||||||
|
case K_SELL:
|
||||||
case K_CAST:
|
case K_CAST:
|
||||||
if (otherorder != longorder) {
|
// non-exclusive orders can be used with others. BUY can be paired with SELL,
|
||||||
|
// CAST with other CAST orders. compatibility is checked once the second
|
||||||
|
// long order is analyzed (below).
|
||||||
|
exclusive = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
set_order(&u->thisorder, copy_order(ord));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
thiskwd = kwd;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// we have found a second long order. this is okay for some, but not all commands.
|
||||||
|
// u->thisorder is already set, and should not have to be updated.
|
||||||
|
switch (kwd) {
|
||||||
|
case K_CAST:
|
||||||
|
if (thiskwd != K_CAST) {
|
||||||
|
cmistake(u, ord, 52, MSG_EVENT);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case K_SELL:
|
||||||
|
if (thiskwd != K_SELL && thiskwd != K_BUY) {
|
||||||
cmistake(u, ord, 52, MSG_EVENT);
|
cmistake(u, ord, 52, MSG_EVENT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case K_BUY:
|
case K_BUY:
|
||||||
if (otherorder == K_SELL) {
|
if (thiskwd != K_SELL) {
|
||||||
otherorder = K_BUY;
|
cmistake(u, ord, 52, MSG_EVENT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
thiskwd = K_BUY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// TODO: decide https://bugs.eressea.de/view.php?id=2080#c6011
|
||||||
|
if (kwd > thiskwd) {
|
||||||
|
// swap out thisorder for the new one
|
||||||
|
cmistake(u, u->thisorder, 52, MSG_EVENT);
|
||||||
|
set_order(&u->thisorder, copy_order(ord));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cmistake(u, ord, 52, MSG_EVENT);
|
cmistake(u, ord, 52, MSG_EVENT);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case K_SELL:
|
|
||||||
if (otherorder != K_SELL && otherorder != K_BUY) {
|
|
||||||
cmistake(u, ord, 52, MSG_EVENT);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
cmistake(u, ord, 52, MSG_EVENT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
otherorder = longorder;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void update_long_order(unit * u)
|
|
||||||
{
|
|
||||||
order *ord;
|
|
||||||
bool trade = false;
|
|
||||||
bool hunger = LongHunger(u);
|
|
||||||
|
|
||||||
freset(u, UFL_MOVED);
|
|
||||||
freset(u, UFL_LONGACTION);
|
|
||||||
if (hunger) {
|
if (hunger) {
|
||||||
/* Hungernde Einheiten führen NUR den default-Befehl aus */
|
// Hungernde Einheiten führen NUR den default-Befehl aus
|
||||||
set_order(&u->thisorder, default_order(u->faction->locale));
|
set_order(&u->thisorder, default_order(u->faction->locale));
|
||||||
}
|
} else if (!exclusive) {
|
||||||
else {
|
// Wenn die Einheit handelt oder zaubert, muss der Default-Befehl gelöscht werden.
|
||||||
check_long_orders(u);
|
|
||||||
}
|
|
||||||
/* check all orders for a potential new long order this round: */
|
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
|
||||||
if (getkeyword(ord) == NOKEYWORD)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (u->old_orders && is_repeated(ord)) {
|
|
||||||
/* this new order will replace the old defaults */
|
|
||||||
free_orders(&u->old_orders);
|
|
||||||
if (hunger)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (hunger)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (is_exclusive(ord)) {
|
|
||||||
/* Über dieser Zeile nur Befehle, die auch eine idle Faction machen darf */
|
|
||||||
if (idle(u->faction)) {
|
|
||||||
set_order(&u->thisorder, default_order(u->faction->locale));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
set_order(&u->thisorder, copy_order(ord));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
keyword_t keyword = getkeyword(ord);
|
|
||||||
switch (keyword) {
|
|
||||||
/* Wenn gehandelt wird, darf kein langer Befehl ausgeführt
|
|
||||||
* werden. Da Handel erst nach anderen langen Befehlen kommt,
|
|
||||||
* muss das vorher abgefangen werden. Wir merken uns also
|
|
||||||
* hier, ob die Einheit handelt. */
|
|
||||||
case K_BUY:
|
|
||||||
case K_SELL:
|
|
||||||
/* Wenn die Einheit handelt, muss der Default-Befehl gelöscht
|
|
||||||
* werden.
|
|
||||||
* Wird je diese Ausschliesslichkeit aufgehoben, muss man aufpassen
|
|
||||||
* mit der Reihenfolge von Kaufen, Verkaufen etc., damit es Spielern
|
|
||||||
* nicht moeglich ist, Schulden zu machen. */
|
|
||||||
trade = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case K_CAST:
|
|
||||||
/* dient dazu, das neben Zaubern kein weiterer Befehl
|
|
||||||
* ausgeführt werden kann, Zaubern ist ein kurzer Befehl */
|
|
||||||
set_order(&u->thisorder, copy_order(ord));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hunger) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Wenn die Einheit handelt, muss der Default-Befehl gelöscht
|
|
||||||
* werden. */
|
|
||||||
|
|
||||||
if (trade) {
|
|
||||||
/* fset(u, UFL_LONGACTION|UFL_NOTMOVING); */
|
|
||||||
set_order(&u->thisorder, NULL);
|
set_order(&u->thisorder, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3696,6 +3671,7 @@ void defaultorders(void)
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
if (!neworders) {
|
if (!neworders) {
|
||||||
/* lange Befehle aus orders und old_orders löschen zu gunsten des neuen */
|
/* lange Befehle aus orders und old_orders löschen zu gunsten des neuen */
|
||||||
|
// TODO: why only is_exclusive, not is_long? what about CAST, BUY, SELL?
|
||||||
remove_exclusive(&u->orders);
|
remove_exclusive(&u->orders);
|
||||||
remove_exclusive(&u->old_orders);
|
remove_exclusive(&u->old_orders);
|
||||||
neworders = true;
|
neworders = true;
|
||||||
|
|
154
src/laws.test.c
154
src/laws.test.c
|
@ -768,9 +768,163 @@ static void test_luck_message(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_long_order_normal(CuTest *tc) {
|
||||||
|
// TODO: write more tests
|
||||||
|
unit *u;
|
||||||
|
order *ord;
|
||||||
|
test_cleanup();
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
fset(u, UFL_MOVED);
|
||||||
|
fset(u, UFL_LONGACTION);
|
||||||
|
u->faction->locale = get_or_create_locale("de");
|
||||||
|
ord = create_order(K_MOVE, u->faction->locale, 0);
|
||||||
|
unit_addorder(u, ord);
|
||||||
|
update_long_order(u);
|
||||||
|
CuAssertPtrEquals(tc, ord->data, u->thisorder->data);
|
||||||
|
CuAssertIntEquals(tc, 0, fval(u, UFL_MOVED));
|
||||||
|
CuAssertIntEquals(tc, 0, fval(u, UFL_LONGACTION));
|
||||||
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->faction->msgs);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->old_orders);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_long_order_none(CuTest *tc) {
|
||||||
|
// TODO: write more tests
|
||||||
|
unit *u;
|
||||||
|
test_cleanup();
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
u->faction->locale = get_or_create_locale("de");
|
||||||
|
update_long_order(u);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->thisorder);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->orders);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->faction->msgs);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_long_order_cast(CuTest *tc) {
|
||||||
|
// TODO: write more tests
|
||||||
|
unit *u;
|
||||||
|
test_cleanup();
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
u->faction->locale = get_or_create_locale("de");
|
||||||
|
unit_addorder(u, create_order(K_CAST, u->faction->locale, 0));
|
||||||
|
unit_addorder(u, create_order(K_CAST, u->faction->locale, 0));
|
||||||
|
update_long_order(u);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->thisorder);
|
||||||
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->faction->msgs);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_long_order_buy_sell(CuTest *tc) {
|
||||||
|
// TODO: write more tests
|
||||||
|
unit *u;
|
||||||
|
test_cleanup();
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
u->faction->locale = get_or_create_locale("de");
|
||||||
|
unit_addorder(u, create_order(K_BUY, u->faction->locale, 0));
|
||||||
|
unit_addorder(u, create_order(K_SELL, u->faction->locale, 0));
|
||||||
|
unit_addorder(u, create_order(K_SELL, u->faction->locale, 0));
|
||||||
|
update_long_order(u);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->thisorder);
|
||||||
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->faction->msgs);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_long_order_multi_long(CuTest *tc) {
|
||||||
|
// TODO: write more tests
|
||||||
|
unit *u;
|
||||||
|
test_cleanup();
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
u->faction->locale = get_or_create_locale("de");
|
||||||
|
unit_addorder(u, create_order(K_MOVE, u->faction->locale, 0));
|
||||||
|
unit_addorder(u, create_order(K_DESTROY, u->faction->locale, 0));
|
||||||
|
update_long_order(u);
|
||||||
|
CuAssertPtrNotNull(tc, u->thisorder);
|
||||||
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
CuAssertStrEquals(tc, "error52", test_get_messagetype(u->faction->msgs->begin->msg));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_long_order_multi_buy(CuTest *tc) {
|
||||||
|
// TODO: write more tests
|
||||||
|
unit *u;
|
||||||
|
test_cleanup();
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
u->faction->locale = get_or_create_locale("de");
|
||||||
|
unit_addorder(u, create_order(K_BUY, u->faction->locale, 0));
|
||||||
|
unit_addorder(u, create_order(K_BUY, u->faction->locale, 0));
|
||||||
|
update_long_order(u);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->thisorder);
|
||||||
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
CuAssertStrEquals(tc, "error52", test_get_messagetype(u->faction->msgs->begin->msg));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_long_order_multi_sell(CuTest *tc) {
|
||||||
|
// TODO: write more tests
|
||||||
|
unit *u;
|
||||||
|
test_cleanup();
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
u->faction->locale = get_or_create_locale("de");
|
||||||
|
unit_addorder(u, create_order(K_SELL, u->faction->locale, 0));
|
||||||
|
unit_addorder(u, create_order(K_BUY, u->faction->locale, 0));
|
||||||
|
unit_addorder(u, create_order(K_SELL, u->faction->locale, 0));
|
||||||
|
update_long_order(u);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->thisorder);
|
||||||
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->faction->msgs);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_long_order_buy_cast(CuTest *tc) {
|
||||||
|
// TODO: write more tests
|
||||||
|
unit *u;
|
||||||
|
test_cleanup();
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
u->faction->locale = get_or_create_locale("de");
|
||||||
|
unit_addorder(u, create_order(K_BUY, u->faction->locale, 0));
|
||||||
|
unit_addorder(u, create_order(K_CAST, u->faction->locale, 0));
|
||||||
|
update_long_order(u);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->thisorder);
|
||||||
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
CuAssertStrEquals(tc, "error52", test_get_messagetype(u->faction->msgs->begin->msg));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_long_order_hungry(CuTest *tc) {
|
||||||
|
// TODO: write more tests
|
||||||
|
unit *u;
|
||||||
|
test_cleanup();
|
||||||
|
set_param(&global.parameters, "hunger.long", "1");
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
fset(u, UFL_HUNGER);
|
||||||
|
u->faction->locale = get_or_create_locale("de");
|
||||||
|
unit_addorder(u, create_order(K_MOVE, u->faction->locale, 0));
|
||||||
|
unit_addorder(u, create_order(K_DESTROY, u->faction->locale, 0));
|
||||||
|
set_default_order(K_WORK);
|
||||||
|
update_long_order(u);
|
||||||
|
CuAssertIntEquals(tc, K_WORK, getkeyword(u->thisorder));
|
||||||
|
CuAssertPtrNotNull(tc, u->orders);
|
||||||
|
CuAssertPtrEquals(tc, 0, u->faction->msgs);
|
||||||
|
set_default_order(NOKEYWORD);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_laws_suite(void)
|
CuSuite *get_laws_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
SUITE_ADD_TEST(suite, test_long_order_normal);
|
||||||
|
SUITE_ADD_TEST(suite, test_long_order_none);
|
||||||
|
SUITE_ADD_TEST(suite, test_long_order_cast);
|
||||||
|
SUITE_ADD_TEST(suite, test_long_order_buy_sell);
|
||||||
|
SUITE_ADD_TEST(suite, test_long_order_multi_long);
|
||||||
|
SUITE_ADD_TEST(suite, test_long_order_multi_buy);
|
||||||
|
SUITE_ADD_TEST(suite, test_long_order_multi_sell);
|
||||||
|
SUITE_ADD_TEST(suite, test_long_order_buy_cast);
|
||||||
|
SUITE_ADD_TEST(suite, test_long_order_hungry);
|
||||||
SUITE_ADD_TEST(suite, test_new_building_can_be_renamed);
|
SUITE_ADD_TEST(suite, test_new_building_can_be_renamed);
|
||||||
SUITE_ADD_TEST(suite, test_rename_building);
|
SUITE_ADD_TEST(suite, test_rename_building);
|
||||||
SUITE_ADD_TEST(suite, test_rename_building_twice);
|
SUITE_ADD_TEST(suite, test_rename_building_twice);
|
||||||
|
|
26
src/magic.c
26
src/magic.c
|
@ -777,7 +777,7 @@ int spellcost(unit * u, const spell * sp)
|
||||||
int count = countspells(u, 0);
|
int count = countspells(u, 0);
|
||||||
const resource_type *r_aura = get_resourcetype(R_AURA);
|
const resource_type *r_aura = get_resourcetype(R_AURA);
|
||||||
|
|
||||||
for (k = 0; sp->components[k].type; k++) {
|
for (k = 0; sp->components && sp->components[k].type; k++) {
|
||||||
if (sp->components[k].type == r_aura) {
|
if (sp->components[k].type == r_aura) {
|
||||||
aura = sp->components[k].amount;
|
aura = sp->components[k].amount;
|
||||||
}
|
}
|
||||||
|
@ -798,7 +798,7 @@ static int spl_costtyp(const spell * sp)
|
||||||
int k;
|
int k;
|
||||||
int costtyp = SPC_FIX;
|
int costtyp = SPC_FIX;
|
||||||
|
|
||||||
for (k = 0; sp->components[k].type; k++) {
|
for (k = 0; sp->components && sp->components[k].type; k++) {
|
||||||
if (costtyp == SPC_LINEAR)
|
if (costtyp == SPC_LINEAR)
|
||||||
return SPC_LINEAR;
|
return SPC_LINEAR;
|
||||||
|
|
||||||
|
@ -827,7 +827,7 @@ int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range)
|
||||||
int k, maxlevel, needplevel;
|
int k, maxlevel, needplevel;
|
||||||
int costtyp = SPC_FIX;
|
int costtyp = SPC_FIX;
|
||||||
|
|
||||||
for (k = 0; sp->components[k].type; k++) {
|
for (k = 0; sp->components && sp->components[k].type; k++) {
|
||||||
if (cast_level == 0)
|
if (cast_level == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -894,7 +894,7 @@ void pay_spell(unit * u, const spell * sp, int cast_level, int range)
|
||||||
int resuse;
|
int resuse;
|
||||||
|
|
||||||
assert(cast_level > 0);
|
assert(cast_level > 0);
|
||||||
for (k = 0; sp->components[k].type; k++) {
|
for (k = 0; sp->components && sp->components[k].type; k++) {
|
||||||
if (sp->components[k].type == r_aura) {
|
if (sp->components[k].type == r_aura) {
|
||||||
resuse = spellcost(u, sp) * range;
|
resuse = spellcost(u, sp) * range;
|
||||||
}
|
}
|
||||||
|
@ -954,7 +954,7 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k = 0; sp->components[k].type; ++k) {
|
for (k = 0; sp->components && sp->components[k].type; ++k) {
|
||||||
if (sp->components[k].amount > 0) {
|
if (sp->components[k].amount > 0) {
|
||||||
const resource_type *rtype = sp->components[k].type;
|
const resource_type *rtype = sp->components[k].type;
|
||||||
int itemhave;
|
int itemhave;
|
||||||
|
@ -2768,15 +2768,13 @@ void magic(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u->thisorder != NULL) {
|
for (ord = u->orders; ord; ord = ord->next) {
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
if (getkeyword(ord) == K_CAST) {
|
||||||
if (getkeyword(ord) == K_CAST) {
|
castorder *co = cast_cmd(u, ord);
|
||||||
castorder *co = cast_cmd(u, ord);
|
fset(u, UFL_LONGACTION | UFL_NOTMOVING);
|
||||||
fset(u, UFL_LONGACTION | UFL_NOTMOVING);
|
if (co) {
|
||||||
if (co) {
|
const spell *sp = co->sp;
|
||||||
const spell *sp = co->sp;
|
add_castorder(&spellranks[sp->rank], co);
|
||||||
add_castorder(&spellranks[sp->rank], co);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "magic.h"
|
#include "magic.h"
|
||||||
|
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
|
#include <kernel/order.h>
|
||||||
#include <kernel/item.h>
|
#include <kernel/item.h>
|
||||||
#include <kernel/region.h>
|
#include <kernel/region.h>
|
||||||
#include <kernel/spell.h>
|
#include <kernel/spell.h>
|
||||||
|
@ -382,9 +383,45 @@ void test_hasspell(CuTest * tc)
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static quicklist * casts;
|
||||||
|
|
||||||
|
static int cast_fireball(struct castorder * co) {
|
||||||
|
ql_push(&casts, co);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_multi_cast(CuTest *tc) {
|
||||||
|
unit *u;
|
||||||
|
spell *sp;
|
||||||
|
struct locale * lang;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
sp = create_spell("fireball", 0);
|
||||||
|
sp->cast = cast_fireball;
|
||||||
|
CuAssertPtrEquals(tc, sp, find_spell("fireball"));
|
||||||
|
|
||||||
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
|
u->faction->locale = lang = get_or_create_locale("de");
|
||||||
|
locale_setstring(lang, mkname("spell", sp->sname), "Feuerball");
|
||||||
|
CuAssertStrEquals(tc, "Feuerball", spell_name(sp, lang));
|
||||||
|
set_level(u, SK_MAGIC, 10);
|
||||||
|
unit_add_spell(u, 0, sp, 1);
|
||||||
|
CuAssertPtrEquals(tc, sp, unit_getspell(u, "Feuerball", lang));
|
||||||
|
|
||||||
|
unit_addorder(u, create_order(K_CAST, u->faction->locale, "Feuerball"));
|
||||||
|
unit_addorder(u, create_order(K_CAST, u->faction->locale, "Feuerball"));
|
||||||
|
CuAssertPtrEquals(tc, casts, 0);
|
||||||
|
magic();
|
||||||
|
CuAssertPtrNotNull(tc, casts);
|
||||||
|
CuAssertIntEquals(tc, 2, ql_length(casts));
|
||||||
|
ql_free(casts);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_magic_suite(void)
|
CuSuite *get_magic_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
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);
|
||||||
SUITE_ADD_TEST(suite, test_pay_spell);
|
SUITE_ADD_TEST(suite, test_pay_spell);
|
||||||
|
|
|
@ -1471,14 +1471,12 @@ report_template(const char *filename, report_context * ctx, const char *charset)
|
||||||
newline(out);
|
newline(out);
|
||||||
newline(out);
|
newline(out);
|
||||||
|
|
||||||
sprintf(buf, "%s %s \"%s\"", LOC(f->locale, "ERESSEA"), factionid(f),
|
sprintf(buf, "%s %s \"%s\"", LOC(f->locale, "ERESSEA"), factionid(f), f->passw);
|
||||||
LOC(f->locale, "enterpasswd"));
|
|
||||||
rps_nowrap(out, buf);
|
rps_nowrap(out, buf);
|
||||||
newline(out);
|
newline(out);
|
||||||
newline(out);
|
newline(out);
|
||||||
sprintf(buf, "; ECHECK -l -w4 -r%d -v%s", f->race->recruitcost,
|
sprintf(buf, "; ECHECK -l -w4 -r%d -v%s", f->race->recruitcost,
|
||||||
ECHECK_VERSION);
|
ECHECK_VERSION);
|
||||||
/* -v3.4: ECheck Version 3.4.x */
|
|
||||||
rps_nowrap(out, buf);
|
rps_nowrap(out, buf);
|
||||||
newline(out);
|
newline(out);
|
||||||
|
|
||||||
|
@ -1575,7 +1573,8 @@ report_template(const char *filename, report_context * ctx, const char *charset)
|
||||||
newline(out);
|
newline(out);
|
||||||
}
|
}
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
for (ord = u->orders; ord; ord = ord->next) {
|
||||||
if (u->old_orders && is_repeated(ord))
|
keyword_t kwd = getkeyword(ord);
|
||||||
|
if (u->old_orders && is_repeated(kwd))
|
||||||
continue; /* unit has defaults */
|
continue; /* unit has defaults */
|
||||||
if (is_persistent(ord)) {
|
if (is_persistent(ord)) {
|
||||||
strcpy(buf, " ");
|
strcpy(buf, " ");
|
||||||
|
|
|
@ -793,7 +793,8 @@ size_t size)
|
||||||
bool printed = 0;
|
bool printed = 0;
|
||||||
order *ord;;
|
order *ord;;
|
||||||
for (ord = u->old_orders; ord; ord = ord->next) {
|
for (ord = u->old_orders; ord; ord = ord->next) {
|
||||||
if (is_repeated(ord)) {
|
keyword_t kwd = getkeyword(ord);
|
||||||
|
if (is_repeated(kwd)) {
|
||||||
if (printed < ORDERS_IN_NR) {
|
if (printed < ORDERS_IN_NR) {
|
||||||
bytes = buforder(bufp, size, ord, printed++);
|
bytes = buforder(bufp, size, ord, printed++);
|
||||||
if (wrptr(&bufp, &size, bytes) != 0)
|
if (wrptr(&bufp, &size, bytes) != 0)
|
||||||
|
@ -805,7 +806,8 @@ size_t size)
|
||||||
}
|
}
|
||||||
if (printed < ORDERS_IN_NR)
|
if (printed < ORDERS_IN_NR)
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
for (ord = u->orders; ord; ord = ord->next) {
|
||||||
if (is_repeated(ord)) {
|
keyword_t kwd = getkeyword(ord);
|
||||||
|
if (is_repeated(kwd)) {
|
||||||
if (printed < ORDERS_IN_NR) {
|
if (printed < ORDERS_IN_NR) {
|
||||||
bytes = buforder(bufp, size, ord, printed++);
|
bytes = buforder(bufp, size, ord, printed++);
|
||||||
if (wrptr(&bufp, &size, bytes) != 0)
|
if (wrptr(&bufp, &size, bytes) != 0)
|
||||||
|
|
|
@ -43,6 +43,7 @@ char *set_string(char **s, const char *neu)
|
||||||
unsigned int hashstring(const char *s)
|
unsigned int hashstring(const char *s)
|
||||||
{
|
{
|
||||||
unsigned int key = 0;
|
unsigned int key = 0;
|
||||||
|
assert(s);
|
||||||
while (*s) {
|
while (*s) {
|
||||||
key = key * 37 + *s++;
|
key = key * 37 + *s++;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue