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; }
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 ? }
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()); } }
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); } }
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); } }
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(); } }
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."); } }
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(); } }
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()); } }