diff --git a/src/common/kernel/building.c b/src/common/kernel/building.c index 7fe87141b..de59838d5 100644 --- a/src/common/kernel/building.c +++ b/src/common/kernel/building.c @@ -623,3 +623,26 @@ building_addaction(building * b, const char * fname, const char * param) } } +region * +building_getregion(const building * b) +{ + return b->region; +} + +void +building_setregion(building * b, region * r) +{ + building ** blist = &b->region->buildings; + while (*blist && *blist!=b) { + blist = &(*blist)->next; + } + *blist = b->next; + b->next = NULL; + + blist = &r->buildings; + while (*blist && *blist!=b) blist = &(*blist)->next; + *blist = b; + + b->region = r; +} + diff --git a/src/common/kernel/building.h b/src/common/kernel/building.h index 86ffd069e..e9bc53eb0 100644 --- a/src/common/kernel/building.h +++ b/src/common/kernel/building.h @@ -160,6 +160,9 @@ extern const char * buildingname(const struct building * b); extern const char * building_getname(const struct building * b); extern void building_setname(struct building * self, const char * name); +struct region * building_getregion(const struct building * b); +void building_setregion(struct building * bld, struct region * r); + #ifdef __cplusplus } #endif diff --git a/src/common/kernel/region.c b/src/common/kernel/region.c index 8cd656b23..95c83d18e 100644 --- a/src/common/kernel/region.c +++ b/src/common/kernel/region.c @@ -1101,8 +1101,7 @@ terraform_region(region * r, const terrain_type * terrain) terraform_resources(r); if (!fval(terrain, LAND_REGION)) { - free(r->display); - r->display = NULL; + region_setinfo(r, NULL); if (r->land!=NULL) { i_freeall(&r->land->items); freeland(r->land); @@ -1345,6 +1344,18 @@ region_setowner(struct region * r, struct faction * owner) #endif } +void +region_setinfo(struct region * r, const char * info) +{ + free(r->display); + r->display = strdup(info); +} + +const char * +region_getinfo(const region * r) { + return (const char *)r->display; +} + void region_setname(struct region * r, const char * name) { diff --git a/src/common/kernel/region.h b/src/common/kernel/region.h index df97c526f..36de5afbb 100644 --- a/src/common/kernel/region.h +++ b/src/common/kernel/region.h @@ -248,6 +248,8 @@ const char * regionname(const struct region * r, const struct faction * f); const char * region_getname(const struct region * self); void region_setname(struct region * self, const char * name); +const char * region_getinfo(const struct region * self); +void region_setinfo(struct region * self, const char * name); int region_getresource(const struct region * r, const struct resource_type * rtype); void region_setresource(struct region * r, const struct resource_type * rtype, int value); diff --git a/src/common/kernel/save.c b/src/common/kernel/save.c index fffee1c6a..a9e5723a2 100644 --- a/src/common/kernel/save.c +++ b/src/common/kernel/save.c @@ -879,7 +879,9 @@ readregion(struct storage * store, short x, short y) if (lomem) { store->r_str_buf(store, NULL, 0); } else { - r->display = store->r_str(store); + char info[DISPLAYSIZE]; + store->r_str_buf(store, info, sizeof(info)); + region_setinfo(r, info); } if (store->version < TERRAIN_VERSION) { @@ -998,7 +1000,7 @@ void writeregion(struct storage * store, const region * r) { store->w_int(store, r->uid); - store->w_str(store, r->display?(const char *)r->display:""); + store->w_str(store, region_getinfo(r)); store->w_tok(store, r->terrain->_name); store->w_int(store, r->flags & RF_SAVEMASK); store->w_int(store, r->age); diff --git a/src/eressea/lua/building.cpp b/src/eressea/lua/building.cpp index 031fb8cf4..50f961706 100644 --- a/src/eressea/lua/building.cpp +++ b/src/eressea/lua/building.cpp @@ -85,30 +85,6 @@ building_setinfo(building * b, const char * info) b->display = strdup(info); } -static region * -building_getregion(const building * b) -{ - return b->region; -} - -static void -building_setregion(building * bld, region * r) -{ - building * b = bld; - building ** blist = &b->region->buildings; - while (*blist && *blist!=b) { - blist = &(*blist)->next; - } - *blist = b->next; - b->next = NULL; - - blist = &r->buildings; - while (*blist && *blist!=b) blist = &(*blist)->next; - *blist = b; - - b->region = r; -} - static std::ostream& operator<<(std::ostream& stream, const building& b) { diff --git a/src/eressea/lua/region.cpp b/src/eressea/lua/region.cpp index 387f8ecac..a27b376e4 100644 --- a/src/eressea/lua/region.cpp +++ b/src/eressea/lua/region.cpp @@ -86,18 +86,6 @@ region_getherbtype(const region * r) { return itype->rtype->_name[0]; } -static void -region_setinfo(region * r, const char * info) -{ - free(r->display); - r->display = strdup(info); -} - -static const char * -region_getinfo(const region * r) { - return (const char *)r->display; -} - static int region_plane(const region * r) { diff --git a/src/eressea/tolua/bind_building.c b/src/eressea/tolua/bind_building.c index 077fed878..32e32dfb7 100644 --- a/src/eressea/tolua/bind_building.c +++ b/src/eressea/tolua/bind_building.c @@ -21,6 +21,19 @@ without prior permission by the authors of Eressea. #include #include +int tolua_buildinglist_next(lua_State *tolua_S) +{ + building** building_ptr = (building **)lua_touserdata(tolua_S, lua_upvalueindex(1)); + building * u = *building_ptr; + if (u != NULL) { + tolua_pushusertype(tolua_S, (void*)u, "building"); + *building_ptr = u->next; + return 1; + } + else return 0; /* no more values to return */ +} + + static int tolua_building_addaction(lua_State* tolua_S) { @@ -41,6 +54,21 @@ tolua_building_get_objects(lua_State* tolua_S) return 1; } +static int tolua_building_get_region(lua_State* tolua_S) +{ + building* self = (building*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushusertype(tolua_S, building_getregion(self), "region"); + return 1; +} + +static int tolua_building_set_region(lua_State* tolua_S) +{ + building* self = (building*)tolua_tousertype(tolua_S, 1, 0); + building_setregion(self, (region*)tolua_tousertype(tolua_S, 2, 0)); + return 0; +} + + static int tolua_building_get_name(lua_State* tolua_S) { building* self = (building*) tolua_tousertype(tolua_S, 1, 0); @@ -108,6 +136,7 @@ tolua_building_open(lua_State* tolua_S) tolua_variable(tolua_S, "id", tolua_building_get_id, NULL); tolua_variable(tolua_S, "name", tolua_building_get_name, tolua_building_set_name); tolua_variable(tolua_S, "units", tolua_building_get_units, NULL); + tolua_variable(tolua_S, "region", tolua_building_get_region, tolua_building_set_region); tolua_function(tolua_S, "add_action", tolua_building_addaction); tolua_variable(tolua_S, "objects", tolua_building_get_objects, 0); diff --git a/src/eressea/tolua/bind_building.h b/src/eressea/tolua/bind_building.h index 1256dd614..58e20d2a1 100644 --- a/src/eressea/tolua/bind_building.h +++ b/src/eressea/tolua/bind_building.h @@ -15,6 +15,7 @@ extern "C" { #endif struct lua_State; + int tolua_buildinglist_next(struct lua_State *tolua_S); void tolua_building_open(struct lua_State *tolua_S); #ifdef __cplusplus diff --git a/src/eressea/tolua/bind_region.c b/src/eressea/tolua/bind_region.c index a71155a63..0ee515790 100644 --- a/src/eressea/tolua/bind_region.c +++ b/src/eressea/tolua/bind_region.c @@ -13,12 +13,16 @@ without prior permission by the authors of Eressea. #include #include "bind_region.h" #include "bind_unit.h" +#include "bind_ship.h" +#include "bind_building.h" #include #include #include #include #include +#include +#include #include #include @@ -50,6 +54,22 @@ tolua_region_get_id(lua_State* tolua_S) return 1; } +static int +tolua_region_get_x(lua_State* tolua_S) +{ + region * self = (region *)tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->x); + return 1; +} + +static int +tolua_region_get_y(lua_State* tolua_S) +{ + region * self = (region *)tolua_tousertype(tolua_S, 1, 0); + tolua_pushnumber(tolua_S, (lua_Number)self->y); + return 1; +} + static int tolua_region_get_terrain(lua_State* tolua_S) { @@ -58,6 +78,21 @@ tolua_region_get_terrain(lua_State* tolua_S) return 1; } +static int tolua_region_get_info(lua_State* tolua_S) +{ + region* self = (region*) tolua_tousertype(tolua_S, 1, 0); + tolua_pushstring(tolua_S, region_getinfo(self)); + return 1; +} + +static int tolua_region_set_info(lua_State* tolua_S) +{ + region* self = (region*)tolua_tousertype(tolua_S, 1, 0); + region_setinfo(self, tolua_tostring(tolua_S, 2, 0)); + return 0; +} + + static int tolua_region_get_name(lua_State* tolua_S) { region* self = (region*) tolua_tousertype(tolua_S, 1, 0); @@ -65,7 +100,7 @@ static int tolua_region_get_name(lua_State* tolua_S) return 1; } -static int tolua_region_set_units(lua_State* tolua_S) +static int tolua_region_set_name(lua_State* tolua_S) { region* self = (region*)tolua_tousertype(tolua_S, 1, 0); region_setname(self, tolua_tostring(tolua_S, 2, 0)); @@ -195,6 +230,34 @@ static int tolua_region_get_units(lua_State* tolua_S) return 1; } +static int tolua_region_get_buildings(lua_State* tolua_S) +{ + region * self = (region *)tolua_tousertype(tolua_S, 1, 0); + building ** building_ptr = (building**)lua_newuserdata(tolua_S, sizeof(building *)); + + luaL_getmetatable(tolua_S, "building"); + lua_setmetatable(tolua_S, -2); + + *building_ptr = self->buildings; + + lua_pushcclosure(tolua_S, tolua_buildinglist_next, 1); + return 1; +} + +static int tolua_region_get_ships(lua_State* tolua_S) +{ + region * self = (region *)tolua_tousertype(tolua_S, 1, 0); + ship ** ship_ptr = (ship**)lua_newuserdata(tolua_S, sizeof(ship *)); + + luaL_getmetatable(tolua_S, "ship"); + lua_setmetatable(tolua_S, -2); + + *ship_ptr = self->ships; + + lua_pushcclosure(tolua_S, tolua_shiplist_next, 1); + return 1; +} + static int tolua_region_getkey(lua_State* tolua_S) { @@ -237,19 +300,38 @@ tolua_region_open(lua_State* tolua_S) tolua_cclass(tolua_S, "region", "region", "", NULL); tolua_beginmodule(tolua_S, "region"); { + tolua_function(tolua_S, "create", tolua_region_create); + tolua_variable(tolua_S, "id", tolua_region_get_id, NULL); - tolua_variable(tolua_S, "name", tolua_region_get_name, tolua_region_set_units); + tolua_variable(tolua_S, "x", tolua_region_get_x, NULL); + tolua_variable(tolua_S, "y", tolua_region_get_y, NULL); + tolua_variable(tolua_S, "name", tolua_region_get_name, tolua_region_set_name); + tolua_variable(tolua_S, "info", tolua_region_get_info, tolua_region_set_info); tolua_variable(tolua_S, "units", tolua_region_get_units, NULL); + tolua_variable(tolua_S, "ships", tolua_region_get_ships, NULL); + tolua_variable(tolua_S, "buildings", tolua_region_get_buildings, NULL); tolua_variable(tolua_S, "terrain", tolua_region_get_terrain, NULL); tolua_function(tolua_S, "get_resource", tolua_region_get_resource); tolua_function(tolua_S, "set_resource", tolua_region_set_resource); tolua_function(tolua_S, "get_flag", tolua_region_get_flag); tolua_function(tolua_S, "set_flag", tolua_region_set_flag); - tolua_function(tolua_S, "create", tolua_region_create); tolua_function(tolua_S, "get_key", tolua_region_getkey); tolua_function(tolua_S, "set_key", tolua_region_setkey); - +#if 0 + .property("owner", &lua_region_getowner, &lua_region_setowner) + .property("herbtype", ®ion_getherbtype, ®ion_setherbtype) + .def("add_notice", ®ion_addnotice) + .def("add_direction", ®ion_adddirection) + .def("move", ®ion_move) + .def("get_road", ®ion_getroad) + .def("set_road", ®ion_setroad) + .def("next", ®ion_next) + .def_readwrite("age", ®ion::age) + .def("add_item", ®ion_additem) + .property("items", ®ion_items, return_stl_iterator) + .property("plane_id", ®ion_plane) +#endif tolua_variable(tolua_S, "objects", tolua_region_get_objects, 0); } tolua_endmodule(tolua_S); diff --git a/src/eressea/tolua/bind_ship.c b/src/eressea/tolua/bind_ship.c index c975eb63c..5002551ae 100644 --- a/src/eressea/tolua/bind_ship.c +++ b/src/eressea/tolua/bind_ship.c @@ -24,6 +24,18 @@ without prior permission by the authors of Eressea. #include #include +int tolua_shiplist_next(lua_State *tolua_S) +{ + ship** ship_ptr = (ship **)lua_touserdata(tolua_S, lua_upvalueindex(1)); + ship * u = *ship_ptr; + if (u != NULL) { + tolua_pushusertype(tolua_S, (void*)u, "ship"); + *ship_ptr = u->next; + return 1; + } + else return 0; /* no more values to return */ +} + static int tolua_ship_get_id(lua_State* tolua_S) { diff --git a/src/eressea/tolua/bind_ship.h b/src/eressea/tolua/bind_ship.h index a68bdf16e..4461194eb 100644 --- a/src/eressea/tolua/bind_ship.h +++ b/src/eressea/tolua/bind_ship.h @@ -15,6 +15,7 @@ extern "C" { #endif struct lua_State; + int tolua_shiplist_next(struct lua_State *tolua_S); void tolua_ship_open(struct lua_State *tolua_S); #ifdef __cplusplus diff --git a/src/eressea/tolua/bindings.c b/src/eressea/tolua/bindings.c index 2baa29ce1..a91a03b08 100644 --- a/src/eressea/tolua/bindings.c +++ b/src/eressea/tolua/bindings.c @@ -584,6 +584,16 @@ tolua_get_region(lua_State* tolua_S) return 1; } +static int +tolua_get_region_byid(lua_State* tolua_S) +{ + int uid = (int)tolua_tonumber(tolua_S, 1, 0); + region * r = findregionbyid(uid); + + tolua_pushusertype(tolua_S, r, "region"); + return 1; +} + static int tolua_get_building(lua_State* tolua_S) { @@ -726,6 +736,8 @@ tolua_eressea_open(lua_State* tolua_S) } tolua_endmodule(tolua_S); + tolua_function(tolua_S, "get_region_by_id", tolua_get_region_byid); + tolua_function(tolua_S, "get_faction", tolua_get_faction); tolua_function(tolua_S, "get_unit", tolua_get_unit); tolua_function(tolua_S, "get_alliance", tolua_get_alliance); diff --git a/src/scripts/tests.lua b/src/scripts/tests.lua index 1481d9edd..ae014720b 100644 --- a/src/scripts/tests.lua +++ b/src/scripts/tests.lua @@ -130,6 +130,11 @@ local function test_building() units = units + 1 end assert(units==2) + local r2 = region.create(0, 1, "plain") + assert(b.region==r) + b.region = r2 + assert(b.region==r2) + assert(r2.buildings()==b) end local function loadscript(name) @@ -180,11 +185,18 @@ tests = { ["test_gmtool"] = test_gmtool } +fail = 0 for k, v in pairs(tests) do local status, err = pcall(v) if not status then - print("[FAIL] " .. k .. ": " .. err) + fail = fail + 1 + print("[FAIL] " .. k .. ": " .. err) else - print("[OK] " .. k) + print("[OK] " .. k) end end + +if fail > 0 then + print(fail .. " tests failed.") + io.stdin:read() +end