예제 #1
0
	std::vector<CastlePart> parse_dir(const variant& node)
	{
		std::vector<CastlePart> res;
		const std::vector<std::string> keys = { "bl", "br", "l", "r", "tl", "tr" };
		ASSERT_LOG(node.is_map(), "must be a map type.");
		for(auto key : keys) {
			ASSERT_LOG(node.has_key(key), "Must have attribute '" << key << "' in definition.");
			const variant& dir = node[key];
			ASSERT_LOG(dir.has_key("rect"), "Attribute '" << key << "' must have 'rect' definition.");
			CastlePart cp;
			cp.r_ = rect(dir["rect"]);
			if(dir.has_key("border")) {
				ASSERT_LOG(dir["border"].num_elements() == 4, "'border' attribute must be list of 4 integers.");
				for(int n = 0; n != 4; ++n) {
					cp.border_[n] = dir["border"][n].as_int32();
				}
			} else {
				for(int n = 0; n != 4; ++n) {
					cp.border_[n] = 0;
				}
			}
			if(dir.has_key("offset")) {
				cp.offs_ = point(dir["offset"]);
			} else {
				cp.offs_.x = cp.offs_.y = 0;
			}
			res.emplace_back(cp);
		}
		return res;
	}
예제 #2
0
	RenderTarget::RenderTarget(const variant& node)
		: width_(0),
		  height_(0),
		  color_attachments_(1),
		  depth_attachment_(false),
		  stencil_attachment_(false),
		  multi_sampling_(false),
		  multi_samples_(0),
		  clear_color_(0.0f, 0.0f, 0.0f, 1.0f)
	{
		ASSERT_LOG(node.is_map(), "RenderTarget definitions must be maps: " << node.to_debug_string());
		ASSERT_LOG(node.has_key("width"), "Render target must have a 'width' attribute.");
		ASSERT_LOG(node.has_key("height"), "Render target must have a 'height' attribute.");
		width_ = node["width"].as_int32();
		height_ = node["height"].as_int32();
		if(node.has_key("color_planes")) {
			color_attachments_ = node["color_planes"].as_int32();
			ASSERT_LOG(color_attachments_ >= 0, "Number of 'color_planes' must be zero or greater: " << color_attachments_);
		}
		if(node.has_key("depth_buffer")) {
			depth_attachment_ = node["depth_buffer"].as_bool();
		}
		if(node.has_key("stencil_buffer")) {
			stencil_attachment_ = node["stencil_buffer"].as_bool();
		}
		if(node.has_key("use_multisampling")) {
			multi_sampling_ = node["use_multisampling"].as_bool();
			if(node.has_key("samples")) {
				multi_samples_ = node["samples"].as_int32();
			}
		}
		// XXX Maybe we need to add some extra filtering from min to max values based on order ?
	}
예제 #3
0
	BlendEquation::BlendEquation(const variant& node)
		: rgb_(BlendEquationConstants::BE_ADD),
		  alpha_(BlendEquationConstants::BE_ADD)
	{
		if(node.is_map()) {
			if(node.has_key("rgba")) {
				rgb_ = alpha_ = convert_string_to_equation(node["rgba"].as_string());
			} 
			if(node.has_key("rgb")) {
				rgb_ = convert_string_to_equation(node["rgb"].as_string());
			}
			if(node.has_key("alpha")) {
				alpha_ = convert_string_to_equation(node["alpha"].as_string());
			}
			if(node.has_key("a")) {
				alpha_ = convert_string_to_equation(node["a"].as_string());
			}
		} else if(node.is_list()) {
			ASSERT_LOG(node.num_elements() > 0, "When using a list for blend equation must give at least one element");
			if(node.num_elements() == 1) {
				rgb_ = alpha_ = convert_string_to_equation(node[0].as_string());
			} else {
				rgb_   = convert_string_to_equation(node[0].as_string());
				alpha_ = convert_string_to_equation(node[1].as_string());
			}
		} else if(node.is_string()) {
			// simply setting the rgb/alpha values that same, from string
			rgb_ = alpha_ = convert_string_to_equation(node.as_string());
		} else {
			ASSERT_LOG(false, "Unrecognised type for blend equation: " << node.to_debug_string());
		}
	}
예제 #4
0
void load_castle_definitions(const variant& castle_def)
{
	ASSERT_LOG(castle_def.is_map(), "Castle definitions must be a map.");
	for(const auto& def : castle_def.as_map()) {
		const std::string name = def.first.as_string();
		get_castle_def()[name] = std::make_shared<CastleDef>(name, def.second);
	}
}
예제 #5
0
void luaW_pushfaivariant(lua_State* L, variant val) {
	if(val.is_int()) {
		lua_pushinteger(L, val.as_int());
	} else if(val.is_decimal()) {
		lua_pushnumber(L, val.as_decimal() / 1000.0);
	} else if(val.is_string()) {
		const std::string result_string = val.as_string();
		lua_pushlstring(L, result_string.c_str(), result_string.size());
	} else if(val.is_list()) {
		lua_newtable(L);
		for(const variant& v : val.as_list()) {
			lua_pushinteger(L, lua_rawlen(L, -1) + 1);
			luaW_pushfaivariant(L, v);
			lua_settable(L, -3);
		}
	} else if(val.is_map()) {
		typedef std::map<variant,variant>::value_type kv_type;
		lua_newtable(L);
		for(const kv_type& v : val.as_map()) {
			luaW_pushfaivariant(L, v.first);
			luaW_pushfaivariant(L, v.second);
			lua_settable(L, -3);
		}
	} else if(val.is_callable()) {
		// First try a few special cases
		if(unit_callable* u_ref = val.try_convert<unit_callable>()) {
			const unit& u = u_ref->get_unit();
			unit_map::iterator un_it = resources::gameboard->units().find(u.get_location());
			if(&*un_it == &u) {
				luaW_pushunit(L, u.underlying_id());
			} else {
				luaW_pushunit(L, u.side(), u.underlying_id());
			}
		} else if(location_callable* loc_ref = val.try_convert<location_callable>()) {
			luaW_pushlocation(L, loc_ref->loc());
		} else {
			// If those fail, convert generically to a map
			const formula_callable* obj = val.as_callable();
			std::vector<formula_input> inputs;
			obj->get_inputs(&inputs);
			lua_newtable(L);
			for(const formula_input& attr : inputs) {
				if(attr.access == FORMULA_WRITE_ONLY) {
					continue;
				}
				lua_pushstring(L, attr.name.c_str());
				luaW_pushfaivariant(L, obj->query_value(attr.name));
				lua_settable(L, -3);
			}
		}
	} else if(val.is_null()) {
		lua_pushnil(L);
	}
}
예제 #6
0
widget_ptr create(const variant& v, game_logic::formula_callable* e)
{
	ASSERT_LOG(v.is_map(), "TYPE ERROR: widget must be specified by a map");	
	std::string wtype = v["type"].as_string();
	std::cerr << "Widget Factory creating widget of type: " << wtype << std::endl;
	if(wtype == "animation_preview") {
		return widget_ptr(new gui::animation_preview_widget(v,e));
	} else if(wtype == "animation_widget") {
		return widget_ptr(new gui::animation_widget(v,e));
	} else if(wtype == "border_widget") {
		return widget_ptr(new gui::border_widget(v,e));
	} else if(wtype == "button") {
		return widget_ptr(new gui::button(v,e));
	} else if(wtype == "checkbox") {
		return widget_ptr(new gui::checkbox(v,e));
	} else if(wtype == "dialog") {
		return widget_ptr(new gui::dialog(v,e));
	} else if(wtype == "drag_widget") {
		return widget_ptr(new gui::drag_widget(v,e));
	} else if(wtype == "graphical_font_label") {
		return widget_ptr(new gui::graphical_font_label(v,e));
	} else if(wtype == "grid") {
		return widget_ptr(new gui::grid(v,e));
	} else if(wtype == "image") {
		return widget_ptr(new gui::image_widget(v,e));
	} else if(wtype == "section") {
		return widget_ptr(new gui::gui_section_widget(v,e));
	} else if(wtype == "key_button") {
		return widget_ptr(new gui::key_button(v,e));
	} else if(wtype == "label") {
		return widget_ptr(new gui::label(v,e));
	} else if(wtype == "poly_line_widget") {
		return widget_ptr(new gui::poly_line_widget(v,e));
	} else if(wtype == "tileset_preview") {
		return widget_ptr(new gui::preview_tileset_widget(v,e));
	} else if(wtype == "scrollbar") {
		return widget_ptr(new gui::scrollbar_widget(v,e));
	} else if(wtype == "slider") {
		return widget_ptr(new gui::slider(v,e));
	} else if(wtype == "text_editor") {
		return widget_ptr(new gui::text_editor_widget(v,e));
	//} else if(wtype == "scrollable") {
	//} else if(wtype == "widget") {
	} else {
		ASSERT_LOG(true, "Unable to create a widget of type " << wtype);
		return widget_ptr();
	}
}
예제 #7
0
	void Material::init(const variant& node)
	{
		blend_.set(BlendModeConstants::BM_SRC_ALPHA, BlendModeConstants::BM_ONE_MINUS_SRC_ALPHA);

		if(node.is_string()) {
			name_ = node.as_string();
			tex_.emplace_back(DisplayDevice::createTexture(name_));
		} else if(node.is_map()) {
			name_ = node["name"].as_string();
		
			// XXX: technically a material could have multiple technique's and passes -- ignoring for now.
			ASSERT_LOG(node.has_key("technique"), "PSYSTEM2: 'material' must have 'technique' attribute.");
			ASSERT_LOG(node["technique"].has_key("pass"), "PSYSTEM2: 'material' must have 'pass' attribute.");
			const variant& pass = node["technique"]["pass"];
			use_lighting_ = pass["lighting"].as_bool(false);
			use_fog_ = pass["fog_override"].as_bool(false);
			do_depth_write_ = pass["depth_write"].as_bool(true);
			do_depth_check_ = pass["depth_check"].as_bool(true);
			if(pass.has_key("scene_blend")) {
				blend_.set(pass["scene_blend"]);
			}
			if(pass.has_key("texture_unit")) {
				if(pass["texture_unit"].is_map()) {
					tex_.emplace_back(createTexture(pass["texture_unit"]));
				} else if(pass["texture_unit"].is_list()) {
					for(size_t n = 0; n != pass["texture_unit"].num_elements(); ++n) {
						tex_.emplace_back(createTexture(pass["texture_unit"][n]));
					}
				} else {
					ASSERT_LOG(false, "'texture_unit' attribute must be map or list ");
				}
			}
			if(pass.has_key("rect")) {
				draw_rect_ = rectf(pass["rect"]);
			}
		} else {
			ASSERT_LOG(false, "Materials(Textures) must be either a single string filename or a map.");
		}
	}
예제 #8
0
widget_ptr create(const variant& v, game_logic::formula_callable* e)
{
	if(v.is_callable()) {
		widget_ptr w = v.try_convert<gui::widget>();
		ASSERT_LOG(w != NULL, "Error converting widget from callable.");
		return w;
	}
	ASSERT_LOG(v.is_map(), "TYPE ERROR: widget must be specified by a map, found: " << v.to_debug_string());
	std::string wtype = v["type"].as_string();
	if(wtype == "animation_widget") {
		return widget_ptr(new gui::animation_widget(v,e));
#ifndef NO_EDITOR
	} else if(wtype == "animation_preview") {
		return widget_ptr(new gui::animation_preview_widget(v,e));
#endif
	} else if(wtype == "border_widget") {
		return widget_ptr(new gui::border_widget(v,e));
	} else if(wtype == "button") {
		return widget_ptr(new gui::button(v,e));
	} else if(wtype == "checkbox") {
		return widget_ptr(new gui::checkbox(v,e));
	} else if(wtype == "dialog") {
		return widget_ptr(new gui::dialog(v,e));
#ifndef NO_EDITOR
	} else if(wtype == "drag_widget") {
		return widget_ptr(new gui::drag_widget(v,e));
#endif
	} else if(wtype == "graphical_font_label") {
		return widget_ptr(new gui::graphical_font_label(v,e));
	} else if(wtype == "grid") {
		return widget_ptr(new gui::grid(v,e));
	} else if(wtype == "image") {
		return widget_ptr(new gui::image_widget(v,e));
	} else if(wtype == "section") {
		return widget_ptr(new gui::gui_section_widget(v,e));
	} else if(wtype == "key_button") {
		return widget_ptr(new gui::key_button(v,e));
	} else if(wtype == "label") {
		return widget_ptr(new gui::label(v,e));
	} else if(wtype == "poly_line_widget") {
		return widget_ptr(new gui::poly_line_widget(v,e));
	} else if(wtype == "rich_text_label") {
		return widget_ptr(new gui::rich_text_label(v,e));
	} else if(wtype == "tileset_preview") {
		return widget_ptr(new gui::preview_tileset_widget(v,e));
	} else if(wtype == "scrollbar") {
		return widget_ptr(new gui::scrollbar_widget(v,e));
	} else if(wtype == "slider") {
		return widget_ptr(new gui::slider(v,e));
	} else if(wtype == "text_editor") {
		return widget_ptr(new gui::text_editor_widget(v,e));
	} else if(wtype == "progress") {
		return widget_ptr(new gui::progress_bar(v, e));
	} else if(wtype == "selector") {
		return widget_ptr(new gui::selector_widget(v, e));
	} else if(wtype == "object") {
		return widget_ptr(new gui::custom_object_widget(v, e));
	} else if(wtype == "bar") {
		return widget_ptr(new gui::bar_widget(v, e));
	} else if(wtype == "color_picker") {
		return widget_ptr(new gui::color_picker(v, e));
	} else if(wtype == "layout") {
		return widget_ptr(new gui::layout_widget(v, e));
	} else if(wtype == "file_chooser") {
		return widget_ptr(new gui::file_chooser_dialog(v, e));
#if defined(USE_ISOMAP)
	} else if(wtype == "view3d") {
		return widget_ptr(new gui::view3d_widget(v, e));
#endif
	//} else if(wtype == "scrollable") {
	//} else if(wtype == "widget") {
	} else {
		ASSERT_LOG(true, "Unable to create a widget of type " << wtype);
		return widget_ptr();
	}
}
예제 #9
0
	Renderable::Renderable(const variant& node)
		: order_(0),
		  position_(0.0f),
		  rotation_(1.0f, 0.0f, 0.0f, 0.0f),
		  scale_(1.0f),
		  shader_(ShaderProgram::getSystemDefault()),
		  enabled_(true),
		  ignore_global_model_(false),
		  derived_position_(0.0f),
		  derived_rotation_(),
		  derived_scale_(1.0f)
	{
		if(!node.is_map()) {
			return;
		}

		if(node.has_key("ignore_global_model")) {
			ignore_global_model_ = node["ignore_global_model"].as_bool(false);
		}
		if(node.has_key("order")) {
			order_ = node["order"].as_int32();
		}
		// XXX set other stuff here, tbd
		if(node.has_key("blend")) {
			setBlendMode(KRE::BlendMode(node["blend"]));
		}
		if(node.has_key("blend_equation")) {
			setBlendEquation(KRE::BlendEquation(node["blend_equation"]));
		} else if(node.has_key("blend_eq")) {
			setBlendEquation(KRE::BlendEquation(node["blend_eq"]));
		}
		if(node.has_key("rotation")) {
			const variant& rot = node["rotation"];
			if(rot.is_numeric()) {
				// Assume it's a simple rotation around z-axis
				setRotation(rot.as_float(), glm::vec3(0.f,0.f,1.f));
			} else if(rot.is_list()) {
				// Either a single rotation formatted as [angle,[x,y,z]] or a list of three euler angles
				if(rot.num_elements() == 2) {
					ASSERT_LOG(rot[1].is_list() && rot[1].num_elements() == 3,
						"Format for a single rotation is [angle, [x,y,z]]");
					setRotation(rot[0].as_float(), variant_to_vec3(rot[1]));
				} else if(rot.num_elements() == 3) {
					setRotation(rot[0].as_float(), glm::vec3(1.,0.,0.));
					setRotation(rot[1].as_float(), glm::vec3(0.,1.,0.));
					setRotation(rot[2].as_float(), glm::vec3(0.,0.,1.));
				} else {
					ASSERT_LOG(false, "Need a list of three (x/y/z rotations) or 2 elements (angle, [axis])");
				}
			}
		}
		if(node.has_key("translation") || node.has_key("position")) {
			const variant& pos = node.has_key("translation") ? node["translation"] : node["position"];
			ASSERT_LOG(pos.is_list() && (pos.num_elements() == 2 || pos.num_elements() == 3),
				"'translation'/'position' attribute should have 2 [x,y] or 3 [x,y,z] elements.");
			if(pos.num_elements() == 3) {
				setPosition(variant_to_vec3(pos));
			} else {
				setPosition(pos[0].as_float(), pos[1].as_float());
			}
		}
		if(node.has_key("scale")) {
			const variant& sc = node["scale"];
			if(sc.is_numeric()) {
				const float scale = sc.as_float();
				setScale(scale, scale, scale);
			} else if(sc.is_list()) {
				float xs = 1.0f;
				float ys = 1.0f;
				float zs = 1.0f;
				if(sc.num_elements() == 1) {
					xs = sc[0].as_float();
				} else if(sc.num_elements() == 2) {
					xs = sc[0].as_float();
					ys = sc[1].as_float();
				} else if(sc.num_elements() == 3) {
					xs = sc[0].as_float();
					ys = sc[1].as_float();
					zs = sc[2].as_float();
				}
				setScale(xs, ys, zs);
			} else {
				ASSERT_LOG(false, "Scale should be a number of a list of up to three elements.");
			}
		}
		if(node.has_key("color")) {
			setColor(KRE::Color(node["color"]));
		}
		if(node.has_key("texture")) {
			texture_ = Texture::createTexture(node["texture"]);
		} else if(node.has_key("image")) {
			texture_ = Texture::createTexture(node["image"]);			
		}
		if(node.has_key("depth_check")) {
			setDepthEnable(node["depth_check"].as_bool());
		}
		if(node.has_key("depth_write")) {
			setDepthWrite(node["depth_write"].as_bool());
		}
		// XXX add depth function.
		if(node.has_key("use_lighting")) {
			enableLighting(node["use_lighting"].as_bool());
		}
	}