add lua map generator type

This commit is contained in:
Chris Beck 2014-11-04 15:52:29 -05:00
parent ab821fcfeb
commit 2da4c9157a
6 changed files with 165 additions and 4 deletions

View File

@ -1006,6 +1006,7 @@ set(libwesnoth-game_STAT_SRC
generators/map_create.cpp
generators/map_generator.cpp
generators/default_map_generator.cpp
generators/lua_map_generator.cpp
generators/yamg/ya_mapgen.cpp
generators/yamg/yamg_hex.cpp
generators/yamg/yamg_hexheap.cpp

View File

@ -93,6 +93,7 @@ libwesnoth_sources = Split("""
generators/map_create.cpp
generators/map_generator.cpp
generators/default_map_generator.cpp
generators/lua_map_generator.cpp
generators/yamg/ya_mapgen.cpp
generators/yamg/yamg_hex.cpp
generators/yamg/yamg_hexheap.cpp

View File

@ -0,0 +1,98 @@
/*
Copyright (C) 2014 by Chris Beck <render787@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "lua_map_generator.hpp"
#include "config.hpp"
#include "lua/lauxlib.h"
#include "lua/lua.h"
#include "lua/lualib.h"
#ifdef DEBUG_LUA
#include "scripting/debug_lua.hpp"
#endif
#include "scripting/lua_api.hpp"
#include <string>
#include <boost/foreach.hpp>
lua_map_generator::lua_map_generator(const config & cfg)
: id_(cfg["id"])
, config_name_(cfg["config_name"])
, create_map_(cfg["create_map"])
, mState_(luaL_newstate())
{
const char* required[] = {"id", "config_name", "create_map"};
BOOST_FOREACH(std::string req, required) {
if (!cfg.has_attribute(req)) {
std::string msg = "Error when constructing a lua map generator -- missing a required attribute '";
msg += req + "'\n";
msg += "Config was '" + cfg.debug() + "'";
throw mapgen_exception(msg);
}
}
}
lua_map_generator::~lua_map_generator()
{
lua_close(mState_);
}
std::string lua_map_generator::create_map()
{
{
int errcode = luaL_loadstring(mState_, create_map_.c_str());
if (errcode != LUA_OK) {
std::string msg = "Error when running lua_map_generator create_map.\n";
msg += "The generator was: " + config_name_ + "\n";
msg += "Error when parsing create_map function. ";
if (errcode == LUA_ERRSYNTAX) {
msg += "There was a syntax error:\n";
} else {
msg += "There was a memory error:\n";
}
msg += lua_tostring(mState_, -1);
throw mapgen_exception(msg);
}
}
{
int errcode = lua_pcall(mState_, 0, 1, 0);
if (errcode != LUA_OK) {
std::string msg = "Error when running lua_map_generator create_map.\n";
msg += "The generator was: " + config_name_ + "\n";
msg += "Error when running create_map function. ";
if (errcode == LUA_ERRRUN) {
msg += "There was a runtime error:\n";
} else if (errcode == LUA_ERRERR) {
msg += "There was an error with the attached debugger:\n";
} else {
msg += "There was a memory or garbage collection error:\n";
}
msg += lua_tostring(mState_, -1);
throw mapgen_exception(msg);
}
}
if (!lua_isstring(mState_,-1)) {
std::string msg = "Error when running lua_map_generator create_map.\n";
msg += "The generator was: " + config_name_ + "\n";
msg += "create_map did not return a string, instead it returned '";
msg += lua_typename(mState_, lua_type(mState_, -1));
msg += "'";
throw mapgen_exception(msg);
}
return lua_tostring(mState_, -1);
}

View File

@ -0,0 +1,53 @@
/*
Copyright (C) 2014 by Chris Beck <render787@gmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef LUA_MAP_GENERATOR_DEFINED
#define LUA_MAP_GENERATOR_DEFINED
#include "map_generator.hpp"
#include <string>
class config;
struct lua_State;
// TODO: Add support for user configurability (via defining a gui2 dialog in lua)
// What's missing is that you need access to the 'wesnoth' object to call show dialog
// at the moment.
class lua_map_generator : public map_generator {
public:
lua_map_generator(const config & cfg);
~lua_map_generator();
bool allow_user_config() const { return false; }
std::string name() const { return "lua"; }
std::string id() const { return id_; }
std::string config_name() const { return config_name_; }
virtual std::string create_map();
private:
std::string id_, config_name_;
std::string create_map_;
lua_State * mState_;
};
#endif

View File

@ -18,11 +18,13 @@
#include "generators/cave_map_generator.hpp"
#include "generators/yamg/ya_mapgen.hpp"
#include "generators/default_map_generator.hpp"
#include "generators/lua_map_generator.hpp"
#include "log.hpp"
#include "scoped_resource.hpp"
#include "serialization/string_utils.hpp"
#include <cassert>
#include <sstream>
static lg::log_domain log_config("config");
#define ERR_CF LOG_STREAM(err, log_config)
@ -35,6 +37,8 @@ map_generator* create_map_generator(const std::string& name, const config &cfg)
return new cave_map_generator(cfg);
} else if(name == "yamg") {
return new ya_mapgen(cfg);
} else if(name == "lua") {
return new lua_map_generator(cfg);
} else {
return NULL;
}
@ -50,8 +54,9 @@ std::string random_generate_map(const std::string& parms, const config &cfg)
assert(!parameters.empty()); //we use parameters.front() in the next line.
util::scoped_ptr<map_generator> generator(create_map_generator(parameters.front(),cfg));
if(generator == NULL) {
ERR_CF << "could not find map generator '" << parameters.front() << "'" << std::endl;
return std::string();
std::stringstream ss;
ss << "could not find map generator '" << parameters.front() << "'";
throw mapgen_exception(ss.str());
}
parameters.erase(parameters.begin());
@ -66,8 +71,9 @@ config random_generate_scenario(const std::string& parms, const config &cfg)
assert(!parameters.empty()); //we use parameters.front() in the next line.
util::scoped_ptr<map_generator> generator(create_map_generator(parameters.front(),cfg));
if(generator == NULL) {
ERR_CF << "could not find map generator '" << parameters.front() << "'" << std::endl;
return config();
std::stringstream ss;
ss << "could not find map generator '" << parameters.front() << "'";
throw mapgen_exception(ss.str());
}
parameters.erase(parameters.begin());

View File

@ -86,6 +86,8 @@
#include "SDL_stdinc.h" // for SDL_putenv, Uint32
#include "SDL_timer.h" // for SDL_GetTicks
//#define NO_CATCH_AT_GAME_END
#ifdef _WIN32
#include <windows.h>
#endif