Merge branch 'master' of github.com:eressea/server

This commit is contained in:
Enno Rehling 2016-01-01 16:37:31 +01:00
commit c5c0a590a2
11 changed files with 255 additions and 26 deletions

View File

@ -247,8 +247,59 @@
the bearer for one week.</text> the bearer for one week.</text>
</string> </string>
<string name="skillpotion"> <string name="skillpotion">
<text locale="en">The recipe of this potion is a well kept secret. Some even say it couldn't be brewed by mere mortals. One thing is certain though, the drinker receives further insight into any learned skills, which furthers their progress towards the mastery of those skills.</text> <text locale="de">
<text locale="de">Die Herstellung dieses Trunkes ist ein wohlgehütetes Geheimnis. Manche behaupten gar, von Sterblichen könne er gar nicht gebraut werden. Tatsache ist, dass er dem Trinkenden tiefere Einsicht in seine erlernten Talente gewährt, was ihn in der Meisterung dieser Talente voranbringt.</text> Die Herstellung dieses Trunkes ist ein wohlgehütetes Geheimnis. Manche
behaupten gar, von Sterblichen könne er gar nicht gebraut werden.
Tatsache ist, dass er dem Trinkenden tiefere Einsicht in seine erlernten
Talente gewährt, was ihn in der Meisterung dieser Talente voranbringt.
</text>
<text locale="en">
The recipe of this potion is a well kept secret. Some even say it
couldn't be brewed by mere mortals. One thing is certain though, the
drinker receives further insight into any learned skills, which furthers
their progress towards the mastery of those skills.
</text>
</string>
<string name="snowglobe">
<text locale="de">
Eine Kugel aus Kristallglas von circa drei Zoll Durchmesser, welche auf
einem Sockel aus Granit ruht.
Im Inneren tanzen unzählige winzige Schneeflocken munter umher. Auf der
Unterseite des Sockels ist eine goldene Windrose mit den sechs
Himmelsrichtungen abgebildet. Eigentlich ein sehr schöner Anblick, doch
strahlt sie eine namenlose Kälte aus.
Unter Magiern und anderen der arkanen Künste kundigen ist die Funktion
und Wirkungsweise des Artefaktes heftig umstritten. Einig scheint man
sich darüber zu sein, dass in dieser kleinen Kugel so viel Kälte
gefangen ist, dass es dauerhafte Folgen für eine weiträumige Umgebung
hätte wenn man sie zerstört. Größte Brände ließen sich damit wohl
löschen, Vulkane besänftigen und Unmengen von Wasser zum gefrieren
bringen. Doch auch in weniger extremen Umgebungen würden sich bestimmt
dauerhafte Veränderungen ereignen.
Es wäre sicherlich nicht zu empfehlen das Kleinod einfach fallen zu
lassen. Man sollte es anstelle dessen so weit wie möglich von sich
schleudern und dafür sorge tragen, dass sich am Einschlagsort kein
Lebewesen aufhält. So man denn eine Benutzung tatsächlich riskieren
will.
(BENUTZE Schneekugel &lt;HIMMELSRICHTUNG&gt;)
</text>
<text locale="en">
A sphere with a diameter of three inches made of crystal glass, sitting
on a granite base.
On the inside countless tiny snowflakes dance around lively. On the
bottom of the base a golden compass rose is engraved. A beautiful sight
to behold, but it emanates a nameless cold.
Among mages and others knowledgeable in the arcane arts the function and
effect of the artefact are disputed intensely. Although there is
agreement about something: upon release the intensity of the contained
cold would have permanent repercussions for a large area. Gigantic fires
would be extinguished, volcanos quelled and large bodies of water frozen
solid. In less extreme environments permanent changes were also probable.
Therefore it isn't recommended to drop the cold treasure. It should be
thrown far off instead, while making sure there is no living being
within the impact zone, if one is willing to risk the usage.
(USE "snow globe" &lt;DIRECTION&gt;)
</text>
</string> </string>
</namespace> </namespace>

View File

@ -14,7 +14,36 @@
your faction with a $resource($item,1).</text> your faction with a $resource($item,1).</text>
</message> </message>
<message name="target_region_invalid">
<type>
<arg name="unit" type="unit"/>
<arg name="region" type="region"/>
<arg name="command" type="order"/>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - Ungültige Zielregion."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - invalid target region."</text>
</type>
</message>
<message name="missing_direction">
<type>
<arg name="unit" type="unit"/>
<arg name="region" type="region"/>
<arg name="command" type="order"/>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - keine Richtung angegeben."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - no direction was specified."</text>
</type>
</message>
<message name="target_region_not_empty">
<type>
<arg name="unit" type="unit"/>
<arg name="region" type="region"/>
<arg name="command" type="order"/>
<text locale="de">"$unit($unit) in $region($region): '$order($command)' - In der Zielregion befinden sich noch Einheiten."</text>
<text locale="en">"$unit($unit) in $region($region): '$order($command)' - There are units in the target region."</text>
</type>
</message>
<message name="force_leave_ship" section="events"> <message name="force_leave_ship" section="events">
<type> <type>
<arg name="unit" type="unit"/> <arg name="unit" type="unit"/>

View File

@ -6,7 +6,16 @@ local function get_direction(locale, token)
return nil return nil
end 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 = { local transform = {
ocean = "glacier", ocean = "glacier",
firewall = "volcano", firewall = "volcano",
@ -17,8 +26,7 @@ function use_snowglobe(u, amount, token)
if direction then if direction then
local r = u.region:next(direction) local r = u.region:next(direction)
if r.units() then if r.units() then
-- message "target region not empty" return error_message('target_region_not_empty', u, ord)
return -1
end end
if r then if r then
local trans = transform[r.terrain] local trans = transform[r.terrain]
@ -26,15 +34,13 @@ function use_snowglobe(u, amount, token)
r.terrain = trans r.terrain = trans
return 1 return 1
else else
-- message "invalid terrain" return error_message('target_region_invalid', u, ord)
end end
else else
-- message "invalid terrain" return error_message('target_region_invalid', u, ord)
end end
else
-- message "need to specify direction"
end end
return -1 return error_message('missing_direction', u, ord)
end end
function use_snowman(u, amount) function use_snowman(u, amount)

View File

@ -19,6 +19,22 @@ function test_snowglobe_fail()
unit.create(f, r2, 1) -- unit in target region => fail unit.create(f, r2, 1) -- unit in target region => fail
process_orders() process_orders()
assert_equal('ocean', r2.terrain) 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 end
function test_snowglobe() function test_snowglobe()
@ -27,6 +43,7 @@ function test_snowglobe()
local f = faction.create("snowglobe2@eressea.de", "human", "de") local f = faction.create("snowglobe2@eressea.de", "human", "de")
local u = unit.create(f, r1, 1) local u = unit.create(f, r1, 1)
local have = 6 local have = 6
local fail = 0
u:add_item("snowglobe", have) u:add_item("snowglobe", have)
local xform = { ocean = "glacier", glacier = "glacier", firewall = "volcano", volcano = "mountain", desert = "plain", plain = "plain" } local xform = { ocean = "glacier", glacier = "glacier", firewall = "volcano", volcano = "mountain", desert = "plain", plain = "plain" }
u:clear_orders() u:clear_orders()
@ -35,7 +52,12 @@ function test_snowglobe()
r2.terrain = k r2.terrain = k
process_orders() process_orders()
assert_equal(v, r2.terrain) 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")) assert_equal(have, u:get_item("snowglobe"))
end end
end end

View File

@ -139,6 +139,7 @@ set(SERVER_SRC
bind_eressea.c bind_eressea.c
bind_faction.c bind_faction.c
bind_dict.c bind_dict.c
bind_order.c
bindings.c bindings.c
bind_message.c bind_message.c
bind_monsters.c bind_monsters.c

View File

@ -224,6 +224,23 @@ static int tolua_faction_addnotice(lua_State * L)
return 0; 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) static int tolua_faction_get_objects(lua_State * L)
{ {
faction *self = (faction *)tolua_tousertype(L, 1, 0); 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_variable(L, TOLUA_CAST "id", tolua_faction_get_id,
tolua_faction_set_id); tolua_faction_set_id);
tolua_variable(L, TOLUA_CAST "uid", &tolua_faction_get_uid, tolua_variable(L, TOLUA_CAST "uid", tolua_faction_get_uid,
&tolua_faction_set_uid); tolua_faction_set_uid);
tolua_variable(L, TOLUA_CAST "name", &tolua_faction_get_name, tolua_variable(L, TOLUA_CAST "name", tolua_faction_get_name,
&tolua_faction_set_name); tolua_faction_set_name);
tolua_variable(L, TOLUA_CAST "info", &tolua_faction_get_info, tolua_variable(L, TOLUA_CAST "info", tolua_faction_get_info,
&tolua_faction_set_info); tolua_faction_set_info);
tolua_variable(L, TOLUA_CAST "units", tolua_faction_get_units, NULL); 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 "heroes", tolua_faction_get_heroes, NULL);
tolua_variable(L, TOLUA_CAST "maxheroes", tolua_faction_get_maxheroes, 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_variable(L, TOLUA_CAST "alliance", tolua_faction_get_alliance,
tolua_faction_set_alliance); tolua_faction_set_alliance);
tolua_variable(L, TOLUA_CAST "score", tolua_faction_get_score, NULL); 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_faction_set_magic);
tolua_variable(L, TOLUA_CAST "age", tolua_faction_get_age, tolua_variable(L, TOLUA_CAST "age", tolua_faction_get_age,
tolua_faction_set_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_variable(L, TOLUA_CAST "lastturn", tolua_faction_get_lastturn,
tolua_faction_set_lastturn); tolua_faction_set_lastturn);
tolua_function(L, TOLUA_CAST "set_policy", &tolua_faction_set_policy); 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_policy", tolua_faction_get_policy);
tolua_function(L, TOLUA_CAST "get_origin", &tolua_faction_get_origin); 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 "set_origin", tolua_faction_set_origin);
tolua_function(L, TOLUA_CAST "normalize", &tolua_faction_normalize); tolua_function(L, TOLUA_CAST "normalize", tolua_faction_normalize);
tolua_function(L, TOLUA_CAST "add_item", tolua_faction_add_item); tolua_function(L, TOLUA_CAST "add_item", tolua_faction_add_item);
tolua_variable(L, TOLUA_CAST "items", tolua_faction_get_items, NULL); 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 "create", tolua_faction_create);
tolua_function(L, TOLUA_CAST "get", tolua_faction_get); tolua_function(L, TOLUA_CAST "get", tolua_faction_get);
tolua_function(L, TOLUA_CAST "destroy", tolua_faction_destroy); 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, tolua_variable(L, TOLUA_CAST "objects", tolua_faction_get_objects,
NULL); NULL);

View File

@ -81,6 +81,23 @@ static int msg_set_resource(lua_message * msg, const char *param, const char *re
return E_INVALID_MESSAGE; 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) static int msg_set_unit(lua_message * msg, const char *param, const unit * u)
{ {
if (msg->mtype) { if (msg->mtype) {
@ -223,6 +240,16 @@ static int tolua_msg_set_resource(lua_State * L)
return 1; 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) static int tolua_msg_set_unit(lua_State * L)
{ {
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0); 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; 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) static int tolua_msg_render(lua_State * L)
{ {
lua_message *lmsg = (lua_message *)tolua_tousertype(L, 1, 0); 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_beginmodule(L, TOLUA_CAST "message");
{ {
tolua_function(L, TOLUA_CAST "render", tolua_msg_render); 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", tolua_msg_set);
tolua_function(L, TOLUA_CAST "set_unit", tolua_msg_set_unit); 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_region", tolua_msg_set_region);
tolua_function(L, TOLUA_CAST "set_resource", tolua_msg_set_resource); tolua_function(L, TOLUA_CAST "set_resource", tolua_msg_set_resource);
tolua_function(L, TOLUA_CAST "set_int", tolua_msg_set_int); tolua_function(L, TOLUA_CAST "set_int", tolua_msg_set_int);

47
src/bind_order.c Normal file
View File

@ -0,0 +1,47 @@
#include <platform.h>
#include <kernel/config.h>
/* kernel includes */
#include <kernel/order.h>
#include <util/parser.h>
/* lua includes */
#include <tolua.h>
#include <stdlib.h>
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);
}

14
src/bind_order.h Normal file
View File

@ -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

View File

@ -19,6 +19,7 @@ without prior permission by the authors of Eressea.
#include "bind_message.h" #include "bind_message.h"
#include "bind_building.h" #include "bind_building.h"
#include "bind_faction.h" #include "bind_faction.h"
#include "bind_order.h"
#include "bind_ship.h" #include "bind_ship.h"
#include "bind_gmtool.h" #include "bind_gmtool.h"
#include "bind_region.h" #include "bind_region.h"
@ -1157,6 +1158,7 @@ lua_State *lua_init(void) {
tolua_faction_open(L); tolua_faction_open(L);
tolua_unit_open(L); tolua_unit_open(L);
tolua_message_open(L); tolua_message_open(L);
tolua_order_open(L);
tolua_dict_open(L); tolua_dict_open(L);
#ifdef USE_CURSES #ifdef USE_CURSES
tolua_gmtool_open(L); tolua_gmtool_open(L);

View File

@ -511,7 +511,8 @@ struct order *ord)
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit"); tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
lua_pushinteger(L, amount); lua_pushinteger(L, amount);
lua_pushstring(L, getstrtoken()); 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); const char *error = lua_tostring(L, -1);
log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error); log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error);
lua_pop(L, 1); lua_pop(L, 1);