// Given two variants, which are maps merge the properties from v2 into v1 that // don't already exist in v1. void variant_map_merge(variant& v1, const variant& v2) { std::map<variant, variant>::const_iterator v2it = v2.as_map().begin(); std::map<variant, variant>::const_iterator v2end = v2.as_map().end(); while(v2it != v2end) { std::map<variant, variant>::const_iterator v1it = v1.as_map().find(v2it->first); if(v1it == v1.as_map().end()) { v1.add_attr(v2it->first, v2it->second); } v2it++; } }
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 formula_variable_storage::read(variant node) { if(node.is_null()) { return; } foreach(const variant_pair& val, node.as_map()) { add(val.first.as_string(), val.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); } }
void load_hex_tiles(variant node) { if(!get_tile_type_map().empty()) { get_tile_type_map().clear(); } for(auto p : node.as_map()) { std::string key_str = p.first.as_string(); get_tile_type_map()[key_str] = tile_type_ptr(new tile_type(key_str, p.second)); } // get list of all tiles have non-empty "editor_info" blocks. if(!get_hex_editor_tiles().empty()) { get_hex_editor_tiles().clear(); } load_editor_tiles(); if(!get_editor_hex_tile_map().empty()) { get_editor_hex_tile_map().clear(); } load_hex_editor_tiles(); }
LayerType read_layer_type(const variant& v) { LayerType result; result.last_edited_variation = v["last_edited_variation"].as_string_default(); result.symmetric = v["symmetric"].as_bool(false); variant layers_node = v["variations"]; if(layers_node.is_null()) { Layer default_layer; default_layer.name = "default"; result.variations["default"] = default_layer; return result; } for(const std::pair<variant,variant>& p : layers_node.as_map()) { Layer layer; layer.name = p.first.as_string(); variant layer_node = p.second; if(layer_node["voxels"].is_list()) { for(variant v : layer_node["voxels"].as_list()) { read_voxels(v, &layer.map); } } result.variations[layer.name] = layer; } const variant pivots_node = v["pivots"]; if(!pivots_node.is_null()) { for(const variant::map_pair& p : pivots_node.as_map()) { std::vector<int> pos = p.second.as_list_int(); ASSERT_LOG(pos.size() == 3, "Invalid pivot position: " << p.second.write_json() << " " << p.second.debug_location()); VoxelPos voxel_pos; std::copy(pos.begin(), pos.end(), &voxel_pos[0]); result.pivots[p.first.as_string()] = voxel_pos; } } return result; }
std::map<std::string, AttachmentPoint> read_attachment_points(const variant& v) { std::map<std::string, AttachmentPoint> result; for(auto p : v.as_map()) { AttachmentPoint point; point.name = p.first.as_string(); point.layer = p.second["layer"].as_string(); point.pivot = p.second["pivot"].as_string(); if(p.second["rotations"].is_list()) { for(auto rotation_node : p.second["rotations"].as_list()) { AttachmentPointRotation rotation; rotation.direction = variant_to_vec3(rotation_node["direction"]); rotation.amount = rotation_node["rotation"].as_decimal().as_float(); point.rotations.push_back(rotation); } } result[point.name] = point; } return result; }