widelands-dev team mailing list archive
-
widelands-dev team
-
Mailing list archive
-
Message #09927
[Merge] lp:~widelands-dev/widelands/bug-1675179-lua-economy into lp:widelands
GunChleoc has proposed merging lp:~widelands-dev/widelands/bug-1675179-lua-economy into lp:widelands.
Commit message:
Added a new object LuaEconomy to LuaMap.
Requested reviews:
Widelands Developers (widelands-dev)
Related bugs:
Bug #1675179 in widelands: "Implement lua functions needed for Empire scenario 3"
https://bugs.launchpad.net/widelands/+bug/1675179
For more details, see:
https://code.launchpad.net/~widelands-dev/widelands/bug-1675179-lua-economy/+merge/321008
This is for the Empire scenario scripting. The new functions aren't used anywhere in the game yet, so the unit test will have to cover the testing for now.
--
Your team Widelands Developers is requested to review the proposed merge of lp:~widelands-dev/widelands/bug-1675179-lua-economy into lp:widelands.
=== modified file 'src/scripting/lua_map.cc'
--- src/scripting/lua_map.cc 2017-01-30 14:40:12 +0000
+++ src/scripting/lua_map.cc 2017-03-26 10:55:25 +0000
@@ -3342,6 +3342,128 @@
*/
/* RST
+Economy
+-------
+.. class:: LuaEconomy
+
+ Provides access to an economy. A player can have multiple economies;
+ you can get an economy from a :class:`Flag`.
+*/
+const char LuaEconomy::className[] = "Economy";
+const MethodType<LuaEconomy> LuaEconomy::Methods[] = {
+ METHOD(LuaEconomy, ware_target_quantity),
+ METHOD(LuaEconomy, worker_target_quantity),
+ METHOD(LuaEconomy, set_ware_target_quantity),
+ METHOD(LuaEconomy, set_worker_target_quantity),
+ {nullptr, nullptr},
+};
+const PropertyType<LuaEconomy> LuaEconomy::Properties[] = {
+ {nullptr, nullptr, nullptr},
+};
+
+void LuaEconomy::__persist(lua_State* L) {
+ const Widelands::Economy* economy = get();
+ const Widelands::Player& player = economy->owner();
+ PERS_UINT32("player", player.player_number());
+ PERS_UINT32("economy", player.get_economy_number(economy));
+}
+
+void LuaEconomy::__unpersist(lua_State* L) {
+ Widelands::PlayerNumber player_number;
+ size_t economy_number;
+ UNPERS_UINT32("player", player_number);
+ UNPERS_UINT32("economy", economy_number);
+ const Widelands::Player& player = get_egbase(L).player(player_number);
+ set_economy_pointer(player.get_economy_by_number(economy_number));
+}
+
+/* RST
+ .. method:: ware_target_quantity(warename)
+
+ Returns the amount of the given ware that should be kept in stock for this economy.
+
+ :arg warename: the name of the ware.
+ :type warename: :class:`string`
+*/
+int LuaEconomy::ware_target_quantity(lua_State* L) {
+ const std::string warename = luaL_checkstring(L, 2);
+ const Widelands::DescriptionIndex index = get_egbase(L).tribes().ware_index(warename);
+ if (get_egbase(L).tribes().ware_exists(index)) {
+ const Widelands::Economy::TargetQuantity& quantity = get()->ware_target_quantity(index);
+ lua_pushinteger(L, quantity.permanent);
+ } else {
+ report_error(L, "There is no ware '%s'.", warename.c_str());
+ }
+ return 1;
+}
+
+/* RST
+ .. method:: worker_target_quantity(workername)
+
+ Returns the amount of the given worker that should be kept in stock for this economy.
+
+ :arg workername: the name of the worker.
+ :type workername: :class:`string`
+*/
+int LuaEconomy::worker_target_quantity(lua_State* L) {
+ const std::string workername = luaL_checkstring(L, 2);
+ const Widelands::DescriptionIndex index = get_egbase(L).tribes().worker_index(workername);
+ if (get_egbase(L).tribes().worker_exists(index)) {
+ const Widelands::Economy::TargetQuantity& quantity = get()->worker_target_quantity(index);
+ lua_pushinteger(L, quantity.permanent);
+ } else {
+ report_error(L, "There is no worker '%s'.", workername.c_str());
+ }
+ return 1;
+}
+
+/* RST
+ .. method:: set_ware_target_quantity(warename)
+
+ Sets the amount of the given ware type that should be kept in stock for this economy.
+
+ :arg warename: the name of the ware type.
+ :type warename: :class:`string`
+
+ :arg amount: the new target amount for the ware.
+ :type amount: :class:`integer`
+*/
+int LuaEconomy::set_ware_target_quantity(lua_State* L) {
+ const std::string warename = luaL_checkstring(L, 2);
+ const Widelands::DescriptionIndex index = get_egbase(L).tribes().ware_index(warename);
+ if (get_egbase(L).tribes().ware_exists(index)) {
+ const int quantity = luaL_checkinteger(L, 3);
+ get()->set_ware_target_quantity(index, quantity, get_egbase(L).get_gametime());
+ } else {
+ report_error(L, "There is no ware '%s'.", warename.c_str());
+ }
+ return 1;
+}
+
+/* RST
+ .. method:: set_worker_target_quantity(workername)
+
+ Sets the amount of the given worker type that should be kept in stock for this economy.
+
+ :arg workername: the name of the worker type.
+ :type workername: :class:`string`
+
+ :arg amount: the new target amount for the worker.
+ :type amount: :class:`integer`
+*/
+int LuaEconomy::set_worker_target_quantity(lua_State* L) {
+ const std::string workername = luaL_checkstring(L, 2);
+ const Widelands::DescriptionIndex index = get_egbase(L).tribes().worker_index(workername);
+ if (get_egbase(L).tribes().worker_exists(index)) {
+ const int quantity = luaL_checkinteger(L, 3);
+ get()->set_worker_target_quantity(index, quantity, get_egbase(L).get_gametime());
+ } else {
+ report_error(L, "There is no worker '%s'.", workername.c_str());
+ }
+ return 1;
+}
+
+/* RST
MapObject
---------
@@ -3682,7 +3804,10 @@
METHOD(LuaFlag, set_wares), METHOD(LuaFlag, get_wares), {nullptr, nullptr},
};
const PropertyType<LuaFlag> LuaFlag::Properties[] = {
- PROP_RO(LuaFlag, roads), PROP_RO(LuaFlag, building), {nullptr, nullptr, nullptr},
+ PROP_RO(LuaFlag, economy),
+ PROP_RO(LuaFlag, roads),
+ PROP_RO(LuaFlag, building),
+ {nullptr, nullptr, nullptr},
};
/*
@@ -3691,6 +3816,18 @@
==========================================================
*/
/* RST
+ .. attribute:: economy
+
+ (RO) Returns the economy that this flag belongs to.
+
+ :returns: The :class:`Economy` associated with the flag.
+*/
+int LuaFlag::get_economy(lua_State* L) {
+ const Flag* f = get(L, get_egbase(L));
+ return to_lua<LuaEconomy>(L, new LuaEconomy(f->get_economy()));
+}
+
+/* RST
.. attribute:: roads
(RO) Array of roads leading to the flag. Directions
@@ -6075,6 +6212,7 @@
register_class<LuaField>(L, "map");
register_class<LuaPlayerSlot>(L, "map");
+ register_class<LuaEconomy>(L, "map");
register_class<LuaMapObject>(L, "map");
register_class<LuaBob>(L, "map", true);
=== modified file 'src/scripting/lua_map.h'
--- src/scripting/lua_map.h 2017-01-25 18:55:59 +0000
+++ src/scripting/lua_map.h 2017-03-26 10:55:25 +0000
@@ -22,6 +22,7 @@
#include <set>
+#include "economy/economy.h"
#include "economy/flag.h"
#include "economy/portdock.h"
#include "economy/road.h"
@@ -728,6 +729,54 @@
const Widelands::TerrainDescription* terraindescr_;
};
+class LuaEconomy : public LuaMapModuleClass {
+public:
+ LUNA_CLASS_HEAD(LuaEconomy);
+
+ virtual ~LuaEconomy() {
+ }
+
+ LuaEconomy() : economy_(nullptr) {
+ }
+ LuaEconomy(Widelands::Economy* economy) : economy_(economy) {
+ }
+ LuaEconomy(lua_State* L) : economy_(nullptr) {
+ report_error(L, "Cannot instantiate a 'LuaEconomy' directly!");
+ }
+
+ void __persist(lua_State* L) override;
+ void __unpersist(lua_State* L) override;
+
+ /*
+ * Properties
+ */
+
+ /*
+ * Lua methods
+ */
+ int ware_target_quantity(lua_State*);
+ int worker_target_quantity(lua_State*);
+ int set_ware_target_quantity(lua_State*);
+ int set_worker_target_quantity(lua_State*);
+
+ /*
+ * C methods
+ */
+
+protected:
+ Widelands::Economy* get() const {
+ assert(economy_ != nullptr);
+ return economy_;
+ }
+ // For persistence.
+ void set_economy_pointer(Widelands::Economy* pointer) {
+ economy_ = pointer;
+ }
+
+private:
+ Widelands::Economy* economy_;
+};
+
#define CASTED_GET(klass) \
Widelands::klass* get(lua_State* L, Widelands::EditorGameBase& egbase) { \
return static_cast<Widelands::klass*>(LuaMapObject::get(L, egbase, #klass)); \
@@ -904,6 +953,7 @@
/*
* Properties
*/
+ int get_economy(lua_State* L);
int get_roads(lua_State* L);
int get_building(lua_State* L);
/*
=== added file 'test/maps/lua_testsuite.wmf/scripting/geconomy.lua'
--- test/maps/lua_testsuite.wmf/scripting/geconomy.lua 1970-01-01 00:00:00 +0000
+++ test/maps/lua_testsuite.wmf/scripting/geconomy.lua 2017-03-26 10:55:25 +0000
@@ -0,0 +1,47 @@
+-- ==================================================
+-- Tests for Economy that are only useful in the Game
+-- ==================================================
+
+economy_tests = lunit.TestCase("Economy test")
+function test_descr:test_instantiation_forbidden()
+ assert_error("Cannot instantiate", function()
+ wl.map.Economy()
+ end)
+end
+
+function economy_tests:test_ware_target_quantity()
+
+ -- Get the economy off a flag
+ local sf = map:get_field(10, 10)
+ local hq = player1:place_building("barbarians_headquarters", sf, false, true)
+ local hq_flag = hq.flag
+ local eco = hq_flag.economy
+
+ -- Nonexisting ware should fail
+ assert_error("Nonexisting ware",function() eco:ware_target_quantity("foobar") end)
+
+ -- Now set and confirm ware quantity
+ quantity = eco:ware_target_quantity("log")
+ quantity = quantity + 1
+ eco:set_ware_target_quantity("log", quantity)
+ assert_equal(quantity, eco:ware_target_quantity("log"))
+ hq_flag:remove()
+end
+
+function economy_tests:test_worker_target_quantity()
+ -- Get the economy off a flag
+ local sf = map:get_field(10, 10)
+ local hq = player1:place_building("barbarians_headquarters", sf, false, true)
+ local hq_flag = hq.flag
+ local eco = hq_flag.economy
+
+ -- Nonexisting worker should fail
+ assert_error("Nonexisting worker",function() eco:worker_target_quantity("foobar") end)
+
+ -- Now set and confirm worker quantity
+ quantity = eco:worker_target_quantity("barbarians_soldier")
+ quantity = quantity + 1
+ eco:set_worker_target_quantity("barbarians_soldier", quantity)
+ assert_equal(quantity, eco:worker_target_quantity("barbarians_soldier"))
+ hq_flag:remove()
+end
=== modified file 'test/maps/lua_testsuite.wmf/scripting/init.lua'
--- test/maps/lua_testsuite.wmf/scripting/init.lua 2016-04-12 07:35:33 +0000
+++ test/maps/lua_testsuite.wmf/scripting/init.lua 2017-03-26 10:55:25 +0000
@@ -40,6 +40,7 @@
if not wl.editor then
include "map:scripting/game.lua"
+ include "map:scripting/geconomy.lua"
include "map:scripting/gplayer.lua"
include "map:scripting/gfield.lua"
include "map:scripting/gplr_access.lua"
Follow ups