diff --git a/res/core/messages.xml b/res/core/messages.xml
index c79416c25..b89019aa9 100644
--- a/res/core/messages.xml
+++ b/res/core/messages.xml
@@ -14,7 +14,36 @@
your faction with a $resource($item,1).
-
+
+
+
+
+
+ "$unit($unit) in $region($region): '$order($command)' - Ungültige Zielregion."
+ "$unit($unit) in $region($region): '$order($command)' - invalid target region."
+
+
+
+
+
+
+
+
+ "$unit($unit) in $region($region): '$order($command)' - keine Richtung angegeben."
+ "$unit($unit) in $region($region): '$order($command)' - no direction was specified."
+
+
+
+
+
+
+
+
+ "$unit($unit) in $region($region): '$order($command)' - In der Zielregion befinden sich noch Einheiten."
+ "$unit($unit) in $region($region): '$order($command)' - There are units in the target region."
+
+
+
diff --git a/scripts/eressea/xmasitems.lua b/scripts/eressea/xmasitems.lua
index bce82f7e4..4f8a20767 100644
--- a/scripts/eressea/xmasitems.lua
+++ b/scripts/eressea/xmasitems.lua
@@ -6,7 +6,16 @@ local function get_direction(locale, token)
return nil
end
-function use_snowglobe(u, amount, token)
+local function error_message(msg, u, ord)
+ local msg = message.create(msg)
+ msg:set_unit("unit", u)
+ msg:set_region("region", u.region)
+ msg:set_order("command", ord)
+ msg:send_faction(u.faction)
+ return -1
+end
+
+function use_snowglobe(u, amount, token, ord)
local transform = {
ocean = "glacier",
firewall = "volcano",
@@ -17,8 +26,7 @@ function use_snowglobe(u, amount, token)
if direction then
local r = u.region:next(direction)
if r.units() then
- -- message "target region not empty"
- return -1
+ return error_message('target_region_not_empty', u, ord)
end
if r then
local trans = transform[r.terrain]
@@ -26,15 +34,13 @@ function use_snowglobe(u, amount, token)
r.terrain = trans
return 1
else
- -- message "invalid terrain"
+ return error_message('target_region_invalid', u, ord)
end
else
- -- message "invalid terrain"
+ return error_message('target_region_invalid', u, ord)
end
- else
- -- message "need to specify direction"
end
- return -1
+ return error_message('missing_direction', u, ord)
end
function use_snowman(u, amount)
diff --git a/scripts/tests/xmas.lua b/scripts/tests/xmas.lua
index 8c6acb895..7ce416db3 100644
--- a/scripts/tests/xmas.lua
+++ b/scripts/tests/xmas.lua
@@ -19,6 +19,22 @@ function test_snowglobe_fail()
unit.create(f, r2, 1) -- unit in target region => fail
process_orders()
assert_equal('ocean', r2.terrain)
+ assert_equal(1, u:get_item('snowglobe'))
+ assert_equal(1, f:count_msg_type('target_region_not_empty'))
+end
+
+function test_snowglobe_missing_direction()
+ local r1 = region.create(0, 0, "glacier")
+ local r2 = region.create(1, 0, "ocean")
+ local f = faction.create("snowglobe1@eressea.de", "human", "de")
+ local u = unit.create(f, r1, 1)
+ u:add_item("snowglobe", 1)
+ u:clear_orders()
+ u:add_order("BENUTZEN 1 Schneekugel")
+ process_orders()
+ assert_equal('ocean', r2.terrain)
+ assert_equal(1, u:get_item('snowglobe'))
+ assert_equal(1, f:count_msg_type('missing_direction'))
end
function test_snowglobe()
@@ -27,6 +43,7 @@ function test_snowglobe()
local f = faction.create("snowglobe2@eressea.de", "human", "de")
local u = unit.create(f, r1, 1)
local have = 6
+ local fail = 0
u:add_item("snowglobe", have)
local xform = { ocean = "glacier", glacier = "glacier", firewall = "volcano", volcano = "mountain", desert = "plain", plain = "plain" }
u:clear_orders()
@@ -35,7 +52,12 @@ function test_snowglobe()
r2.terrain = k
process_orders()
assert_equal(v, r2.terrain)
- if k~=v then have=have - 1 end
+ if k~=v then
+ have=have - 1
+ else
+ fail = fail + 1
+ assert_equal(fail, f:count_msg_type('target_region_invalid'))
+ end
assert_equal(have, u:get_item("snowglobe"))
end
end
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 36c728d40..eb603bc0b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -139,6 +139,7 @@ set(SERVER_SRC
bind_eressea.c
bind_faction.c
bind_dict.c
+ bind_order.c
bindings.c
bind_message.c
bind_monsters.c
diff --git a/src/bind_faction.c b/src/bind_faction.c
index 8cfc21718..dc06c4057 100644
--- a/src/bind_faction.c
+++ b/src/bind_faction.c
@@ -224,6 +224,23 @@ static int tolua_faction_addnotice(lua_State * L)
return 0;
}
+static int tolua_faction_count_msg_type(lua_State *L) {
+ faction *self = (faction *)tolua_tousertype(L, 1, 0);
+ const char *str = tolua_tostring(L, 2, 0);
+ int n = 0;
+ if (self->msgs) {
+ mlist * ml = self->msgs->begin;
+ while (ml) {
+ if (strcmp(str, ml->msg->type->name) == 0) {
+ ++n;
+ }
+ ml = ml->next;
+ }
+ }
+ lua_pushinteger(L, n);
+ return 1;
+}
+
static int tolua_faction_get_objects(lua_State * L)
{
faction *self = (faction *)tolua_tousertype(L, 1, 0);
@@ -528,12 +545,12 @@ void tolua_faction_open(lua_State * L)
tolua_variable(L, TOLUA_CAST "id", tolua_faction_get_id,
tolua_faction_set_id);
- tolua_variable(L, TOLUA_CAST "uid", &tolua_faction_get_uid,
- &tolua_faction_set_uid);
- tolua_variable(L, TOLUA_CAST "name", &tolua_faction_get_name,
- &tolua_faction_set_name);
- tolua_variable(L, TOLUA_CAST "info", &tolua_faction_get_info,
- &tolua_faction_set_info);
+ tolua_variable(L, TOLUA_CAST "uid", tolua_faction_get_uid,
+ tolua_faction_set_uid);
+ tolua_variable(L, TOLUA_CAST "name", tolua_faction_get_name,
+ tolua_faction_set_name);
+ tolua_variable(L, TOLUA_CAST "info", tolua_faction_get_info,
+ tolua_faction_set_info);
tolua_variable(L, TOLUA_CAST "units", tolua_faction_get_units, NULL);
tolua_variable(L, TOLUA_CAST "heroes", tolua_faction_get_heroes, NULL);
tolua_variable(L, TOLUA_CAST "maxheroes", tolua_faction_get_maxheroes,
@@ -549,7 +566,7 @@ void tolua_faction_open(lua_State * L)
tolua_variable(L, TOLUA_CAST "alliance", tolua_faction_get_alliance,
tolua_faction_set_alliance);
tolua_variable(L, TOLUA_CAST "score", tolua_faction_get_score, NULL);
- tolua_variable(L, TOLUA_CAST "magic", &tolua_faction_get_magic,
+ tolua_variable(L, TOLUA_CAST "magic", tolua_faction_get_magic,
tolua_faction_set_magic);
tolua_variable(L, TOLUA_CAST "age", tolua_faction_get_age,
tolua_faction_set_age);
@@ -559,11 +576,11 @@ void tolua_faction_open(lua_State * L)
tolua_variable(L, TOLUA_CAST "lastturn", tolua_faction_get_lastturn,
tolua_faction_set_lastturn);
- tolua_function(L, TOLUA_CAST "set_policy", &tolua_faction_set_policy);
- tolua_function(L, TOLUA_CAST "get_policy", &tolua_faction_get_policy);
- tolua_function(L, TOLUA_CAST "get_origin", &tolua_faction_get_origin);
- tolua_function(L, TOLUA_CAST "set_origin", &tolua_faction_set_origin);
- tolua_function(L, TOLUA_CAST "normalize", &tolua_faction_normalize);
+ tolua_function(L, TOLUA_CAST "set_policy", tolua_faction_set_policy);
+ tolua_function(L, TOLUA_CAST "get_policy", tolua_faction_get_policy);
+ tolua_function(L, TOLUA_CAST "get_origin", tolua_faction_get_origin);
+ tolua_function(L, TOLUA_CAST "set_origin", tolua_faction_set_origin);
+ tolua_function(L, TOLUA_CAST "normalize", tolua_faction_normalize);
tolua_function(L, TOLUA_CAST "add_item", tolua_faction_add_item);
tolua_variable(L, TOLUA_CAST "items", tolua_faction_get_items, NULL);
@@ -572,7 +589,10 @@ void tolua_faction_open(lua_State * L)
tolua_function(L, TOLUA_CAST "create", tolua_faction_create);
tolua_function(L, TOLUA_CAST "get", tolua_faction_get);
tolua_function(L, TOLUA_CAST "destroy", tolua_faction_destroy);
- tolua_function(L, TOLUA_CAST "add_notice", &tolua_faction_addnotice);
+ tolua_function(L, TOLUA_CAST "add_notice", tolua_faction_addnotice);
+
+ /* tech debt hack, siehe https://paper.dropbox.com/doc/Weihnachten-2015-5tOx5r1xsgGDBpb0gILrv#:h=Probleme-mit-Tests-(Nachtrag-0 */
+ tolua_function(L, TOLUA_CAST "count_msg_type", tolua_faction_count_msg_type);
tolua_variable(L, TOLUA_CAST "objects", tolua_faction_get_objects,
NULL);
diff --git a/src/bind_message.c b/src/bind_message.c
index 34e43301a..15673f4f6 100644
--- a/src/bind_message.c
+++ b/src/bind_message.c
@@ -81,6 +81,23 @@ static int msg_set_resource(lua_message * msg, const char *param, const char *re
return E_INVALID_MESSAGE;
}
+static int msg_set_order(lua_message * msg, const char *param, struct order *ord)
+{
+ if (msg->mtype) {
+ int i = mtype_get_param(msg->mtype, param);
+ if (i == msg->mtype->nparameters) {
+ return E_INVALID_PARAMETER_NAME;
+ }
+ if (strcmp(msg->mtype->types[i]->name, "order") != 0) {
+ return E_INVALID_PARAMETER_TYPE;
+ }
+
+ msg->args[i].v = (void *)ord;
+ return E_OK;
+ }
+ return E_INVALID_MESSAGE;
+}
+
static int msg_set_unit(lua_message * msg, const char *param, const unit * u)
{
if (msg->mtype) {
@@ -223,6 +240,16 @@ static int tolua_msg_set_resource(lua_State * L)
return 1;
}
+static int tolua_msg_set_order(lua_State * L)
+{
+ lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
+ const char *param = tolua_tostring(L, 2, 0);
+ struct order *value = (struct order *)tolua_tousertype(L, 3, 0);
+ int result = msg_set_order(lmsg, param, value);
+ lua_pushinteger(L, result);
+ return 1;
+}
+
static int tolua_msg_set_unit(lua_State * L)
{
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
@@ -294,6 +321,13 @@ static int tolua_msg_send_faction(lua_State * L)
return 0;
}
+static int tolua_msg_get_type(lua_State * L)
+{
+ lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
+ lua_pushstring(L, lmsg->msg->type->name);
+ return 1;
+}
+
static int tolua_msg_render(lua_State * L)
{
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0);
@@ -324,8 +358,10 @@ void tolua_message_open(lua_State * L)
tolua_beginmodule(L, TOLUA_CAST "message");
{
tolua_function(L, TOLUA_CAST "render", tolua_msg_render);
+ tolua_variable(L, TOLUA_CAST "type", tolua_msg_get_type, 0);
tolua_function(L, TOLUA_CAST "set", tolua_msg_set);
tolua_function(L, TOLUA_CAST "set_unit", tolua_msg_set_unit);
+ tolua_function(L, TOLUA_CAST "set_order", tolua_msg_set_order);
tolua_function(L, TOLUA_CAST "set_region", tolua_msg_set_region);
tolua_function(L, TOLUA_CAST "set_resource", tolua_msg_set_resource);
tolua_function(L, TOLUA_CAST "set_int", tolua_msg_set_int);
diff --git a/src/bind_order.c b/src/bind_order.c
new file mode 100644
index 000000000..90fc7d3b0
--- /dev/null
+++ b/src/bind_order.c
@@ -0,0 +1,47 @@
+#include
+#include
+
+/* kernel includes */
+#include
+#include
+
+/* lua includes */
+#include
+
+#include
+
+static int tolua_order_get_token(lua_State *L) {
+ order *ord = (order *)tolua_tousertype(L, 1, 0);
+ int n = (int)tolua_tonumber(L, 2, 0);
+ const char * str = 0;
+ init_order(ord);
+ while (n-->0) {
+ str = getstrtoken();
+ if (!str) {
+ return 0;
+ }
+ }
+
+ tolua_pushstring(L, str);
+ return 1;
+}
+
+void tolua_order_open(lua_State * L)
+{
+ /* register user types */
+ tolua_usertype(L, TOLUA_CAST "order");
+
+ tolua_module(L, NULL, 0);
+ tolua_beginmodule(L, NULL);
+ {
+ tolua_cclass(L, TOLUA_CAST "order", TOLUA_CAST "order", TOLUA_CAST "",
+ NULL);
+ tolua_beginmodule(L, TOLUA_CAST "order");
+ {
+ tolua_function(L, TOLUA_CAST "token", tolua_order_get_token);
+ }
+ tolua_endmodule(L);
+ }
+ tolua_endmodule(L);
+}
+
diff --git a/src/bind_order.h b/src/bind_order.h
new file mode 100644
index 000000000..efe1ef373
--- /dev/null
+++ b/src/bind_order.h
@@ -0,0 +1,14 @@
+#ifndef H_BIND_ORDER_H
+#define H_BIND_ORDER_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ struct lua_State;
+ void tolua_order_open(struct lua_State *L);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/bindings.c b/src/bindings.c
index 20a8192e1..cbbd38072 100755
--- a/src/bindings.c
+++ b/src/bindings.c
@@ -19,6 +19,7 @@ without prior permission by the authors of Eressea.
#include "bind_message.h"
#include "bind_building.h"
#include "bind_faction.h"
+#include "bind_order.h"
#include "bind_ship.h"
#include "bind_gmtool.h"
#include "bind_region.h"
@@ -1157,6 +1158,7 @@ lua_State *lua_init(void) {
tolua_faction_open(L);
tolua_unit_open(L);
tolua_message_open(L);
+ tolua_order_open(L);
tolua_dict_open(L);
#ifdef USE_CURSES
tolua_gmtool_open(L);
diff --git a/src/helpers.c b/src/helpers.c
index c784e9901..55cfffb80 100644
--- a/src/helpers.c
+++ b/src/helpers.c
@@ -511,7 +511,8 @@ struct order *ord)
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
lua_pushinteger(L, amount);
lua_pushstring(L, getstrtoken());
- if (lua_pcall(L, 3, 1, 0) != 0) {
+ tolua_pushusertype(L, (void *)ord, TOLUA_CAST "order");
+ if (lua_pcall(L, 4, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error);
lua_pop(L, 1);