// Sets all undefined properties in the dictionary to their defaults.
void PropertySpecification::SetPropertyDefaults(PropertyDictionary& dictionary) const
{
	for (PropertyMap::const_iterator i = properties.begin(); i != properties.end(); ++i)
	{
		if (dictionary.GetProperty((*i).first) == NULL)
			dictionary.SetProperty((*i).first, *(*i).second->GetDefaultValue());
	}
}
Exemplo n.º 2
0
		GradientDecorator( const PropertyDictionary& properties )
		{
			// fetch the properties from the dict
			String prop_dir = properties.GetProperty( "dir" )->Get<String>();
			start = properties.GetProperty( "start" )->Get<Colourb>();
			end = properties.GetProperty( "end" )->Get<Colourb>();

			// enumerate direction property
			dir = ( prop_dir == "horizontal" ? HORIZONTAL : VERTICAL );
		}
// Retrieves all the properties for a tile from the property dictionary.
void DecoratorTiledInstancer::GetTileProperties(DecoratorTiled::Tile& tile, String& texture_name, String& rcss_path, const PropertyDictionary& properties, const String& name)
{
	LoadTexCoord(properties, String(32, "%s-s-begin", name.CString()), tile.texcoords[0].x, tile.texcoords_absolute[0][0]);
	LoadTexCoord(properties, String(32, "%s-t-begin", name.CString()), tile.texcoords[0].y, tile.texcoords_absolute[0][1]);
	LoadTexCoord(properties, String(32, "%s-s-end", name.CString()), tile.texcoords[1].x, tile.texcoords_absolute[1][0]);
	LoadTexCoord(properties, String(32, "%s-t-end", name.CString()), tile.texcoords[1].y, tile.texcoords_absolute[1][1]);

	const Property* repeat_property = properties.GetProperty(String(32, "%s-repeat", name.CString()));
	if (repeat_property != NULL)
		tile.repeat_mode = (DecoratorTiled::TileRepeatMode) repeat_property->value.Get< int >();

	const Property* texture_property = properties.GetProperty(String(32, "%s-src", name.CString()));
	texture_name = texture_property->Get< String >();
	rcss_path = texture_property->source;
}
Exemplo n.º 4
0
// Get decorator-id property from properties or "" if not id is given.
String DecoratorInstancer::GetDecoratorIdProperty(const PropertyDictionary& properties)
{
	const Property* id_property = properties.GetProperty("decorator-id");
	if (id_property) {
	  String decorator_id = id_property->Get< String >();
	  return decorator_id;
	}
	return "";
}
Exemplo n.º 5
0
// Updates a property dictionary of all properties for a single group.
int ElementDefinition::BuildPropertyGroupDictionary(PropertyDictionary& group_properties, const String& ROCKET_UNUSED(group_type), const String& group_name, const PropertyDictionary& element_properties)
{
	int num_properties = 0;

	PropertyMap::const_iterator property_iterator;
	for (property_iterator = element_properties.GetProperties().begin(); property_iterator != element_properties.GetProperties().end(); ++property_iterator)
	{
		const String& full_property_name = (*property_iterator).first;
		if (full_property_name.Length() > group_name.Length() + 1 &&
			strncasecmp(full_property_name.CString(), group_name.CString(), group_name.Length()) == 0 &&
			full_property_name[group_name.Length()] == '-')
		{
			String property_name = full_property_name.Substring(group_name.Length() + 1);
//			if (property_name == group_type)
//				continue;

			group_properties.SetProperty(property_name, (*property_iterator).second);
			num_properties++;
		}
	}

	return num_properties;
}
// Loads a single texture coordinate value from the properties.
void DecoratorTiledInstancer::LoadTexCoord(const PropertyDictionary& properties, const String& name, float& tex_coord, bool& tex_coord_absolute)
{
	const Property* property = properties.GetProperty(name);
	if (property == NULL)
		return;

	tex_coord = property->value.Get< float >();
	if (property->unit == Property::PX)
		tex_coord_absolute = true;
	else
	{
		tex_coord_absolute = false;
		if (property->unit == Property::PERCENT)
			tex_coord *= 0.01f;
	}
}
Exemplo n.º 7
0
// Returns the floating-point value of a numerical property from a dictionary of properties.
float Decorator::ResolveProperty(const PropertyDictionary& properties, const String& name, float base_value) const
{
	const Property* property = properties.GetProperty(name);
	if (property == NULL)
	{
		ROCKET_ERROR;
		return 0;
	}

	// Need to include em!
	if (property->unit & Property::RELATIVE_UNIT)
		return base_value * property->value.Get< float >() * 0.01f;

	if (property->unit & Property::NUMBER || property->unit & Property::PX)
		return property->value.Get< float >();

	if (property->unit & Property::GSP)
		return property->value.Get< float >() * Rocket::Core::GetRenderInterface()->GetPixelScale();
    
    // Values based on pixels-per-inch.
	if (property->unit & Property::PPI_UNIT)
	{
		float inch = property->value.Get< float >() * GetRenderInterface()->GetPixelsPerInch();

		if (property->unit & Property::INCH) // inch
			return inch;
		if (property->unit & Property::CM) // centimeter
			return inch / 2.54f;
		if (property->unit & Property::MM) // millimeter
			return inch / 25.4f;
		if (property->unit & Property::PT) // point
			return inch / 72.0f;
		if (property->unit & Property::PC) // pica
			return inch / 6.0f;
	}

	ROCKET_ERROR;
	return 0;
}
Exemplo n.º 8
0
MapDonutRoom::MapDonutRoom(Map& m, PropertyDictionary const& s, GeoVector vec)
  :
  MapFeature{ m, s, vec }
{
  unsigned int num_tries = 0;

  unsigned int minWidth = s.get("min_width", 7);
  unsigned int maxWidth = s.get("max_width", 20);
  unsigned int minHeight = s.get("min_height", 7);
  unsigned int maxHeight = s.get("max_height", 20);
  unsigned int min_hole_size = s.get("min_hole_size", 5);
  unsigned int max_retries = s.get("max_retries", 500);
  std::string floorMaterial = s.get("floor_type", "Dirt");
  std::string wallMaterial = s.get("wall_type", "Stone");


  IntVec2& starting_coords = vec.start_point;
  Direction& direction = vec.direction;

  while (num_tries < max_retries)
  {
    sf::IntRect rect;

    rect.width = the_RNG.pick_uniform(minWidth, maxWidth);
    rect.height = the_RNG.pick_uniform(minHeight, maxHeight);

    if (direction == Direction::North)
    {
      int offset = the_RNG.pick_uniform(0, rect.width - 1);

      rect.top = starting_coords.y - rect.height;
      rect.left = starting_coords.x - offset;
    }
    else if (direction == Direction::South)
    {
      int offset = the_RNG.pick_uniform(0, rect.width - 1);

      rect.top = starting_coords.y + 1;
      rect.left = starting_coords.x - offset;
    }
    else if (direction == Direction::West)
    {
      int offset = the_RNG.pick_uniform(0, rect.height - 1);

      rect.top = starting_coords.y - offset;
      rect.left = starting_coords.x - rect.width;
    }
    else if (direction == Direction::East)
    {
      int offset = the_RNG.pick_uniform(0, rect.height - 1);

      rect.top = starting_coords.y - offset;
      rect.left = starting_coords.x + 1;
    }
    else
    {
      throw MapFeatureException("Invalid direction passed to MapDonutRoom constructor");
    }

    if ((getMap().isInBounds({ rect.left - 1, rect.top - 1 })) &&
      (getMap().isInBounds({ rect.left + rect.width, rect.top + rect.height })))
    {
      bool okay = true;

      okay = doesBoxPassCriterion({ rect.left - 1, rect.top - 1 },
      { rect.left + rect.width, rect.top + rect.height },
                                     [&](MapTile& tile) { return !tile.isPassable(); });

      // Create the hole location.
      sf::IntRect hole;

      int x_hole_left = the_RNG.pick_uniform(rect.left + 1, rect.left + rect.width - 2);
      int x_hole_right = the_RNG.pick_uniform(rect.left + 1, rect.left + rect.width - 2);
      int y_hole_top = the_RNG.pick_uniform(rect.top + 1, rect.top + rect.height - 2);
      int y_hole_bottom = the_RNG.pick_uniform(rect.top + 1, rect.top + rect.height - 2);

      // Make sure the hole isn't TOO small.
      // GSL GRUMBLE: WHY does abs() return a signed value?!?
      if ((static_cast<unsigned int>(abs(x_hole_right - x_hole_left)) < min_hole_size - 1) ||
        (static_cast<unsigned int>(abs(y_hole_bottom - y_hole_top)) < min_hole_size - 1))
      {
        okay = false;
      }

      if (x_hole_right < x_hole_left) std::swap(x_hole_left, x_hole_right);
      if (y_hole_bottom < y_hole_top) std::swap(y_hole_top, y_hole_bottom);

      if (okay)
      {
        // Clear out the box EXCEPT FOR the hole.
        for (int x_coord = rect.left;
             x_coord <= rect.left + rect.width - 1;
             ++x_coord)
        {
          for (int y_coord = rect.top;
               y_coord <= rect.top + rect.height - 1;
               ++y_coord)
          {
            if (!((x_coord >= x_hole_left) && (x_coord <= x_hole_right) &&
              (y_coord >= y_hole_top) && (y_coord <= y_hole_bottom)))
            {
              auto& tile = getMap().getTile({ x_coord, y_coord });
              tile.setTileType({ "Floor", floorMaterial }, { "OpenSpace" });
            }
          }
        }

        setCoords(rect);

        // Add the surrounding walls as potential connection points.

        // Horizontal walls...
        for (int x_coord = rect.left + 1;
             x_coord <= rect.left + rect.width - 1;
             ++x_coord)
        {
          addGrowthVector(GeoVector(x_coord, rect.top - 1, Direction::North));
          addGrowthVector(GeoVector(x_coord, rect.top + rect.height, Direction::South));
        }
        // Vertical walls...
        for (int y_coord = rect.top + 1;
             y_coord <= rect.top + rect.height - 1;
             ++y_coord)
        {
          addGrowthVector(GeoVector(rect.left - 1, y_coord, Direction::West));
          addGrowthVector(GeoVector(rect.left + rect.width, y_coord, Direction::East));
        }

        // Do the same for the hole walls.
        // Horizontal walls...
        for (int x_coord = x_hole_left + 1; x_coord < x_hole_right; ++x_coord)
        {
          addGrowthVector(GeoVector(x_coord, y_hole_bottom, Direction::North));
          addGrowthVector(GeoVector(x_coord, y_hole_top, Direction::South));
        }
        // Vertical walls...
        for (int y_coord = y_hole_top + 1; y_coord < y_hole_bottom; ++y_coord)
        {
          addGrowthVector(GeoVector(x_hole_right, y_coord, Direction::West));
          addGrowthVector(GeoVector(x_hole_left, y_coord, Direction::East));
        }

        /// @todo Put either a door or an open area at the starting coords.
        ///       Right now we just make it an open area.
        auto& startTile = getMap().getTile(starting_coords);
        startTile.setTileType({ "Floor", floorMaterial }, { "OpenSpace" });

        return;
      }
    }

    ++num_tries;
  }

  throw MapFeatureException("Out of tries attempting to make MapDonutRoom");
}
Exemplo n.º 9
0
// Finds all propery declarations for a group.
void ElementDefinition::BuildPropertyGroup(PropertyGroupMap& groups, const String& group_type, const PropertyDictionary& element_properties, const PropertyGroupMap* default_properties)
{
	String property_suffix = "-" + group_type;

	PropertyMap::const_iterator property_iterator;
	for (property_iterator = element_properties.GetProperties().begin(); property_iterator != element_properties.GetProperties().end(); ++property_iterator)
	{
		const String& property_name = (*property_iterator).first;
		if (property_name.Length() > property_suffix.Length() &&
			strcasecmp(property_name.CString() + (property_name.Length() - property_suffix.Length()), property_suffix.CString()) == 0)
		{
			// We've found a group declaration!
			String group_name = property_name.Substring(0, property_name.Length() - (group_type.Length() + 1));
			String group_class = (*property_iterator).second.value.Get< String >();
			PropertyDictionary* group_properties = NULL;		

			// Check if we have an existing definition by this name; if so, we're only overriding the type.
			PropertyGroupMap::iterator existing_definition = groups.find(group_name);
			if (existing_definition != groups.end())
			{
				(*existing_definition).second.first = group_class;
				group_properties = &(*existing_definition).second.second;
			}
			else
			{
				// Check if we have any default decorator definitions, and if the new decorator has a default. If so,
				// we make a copy of the default properties for the new decorator.
				if (default_properties != NULL)
				{
					PropertyGroupMap::const_iterator default_definition = default_properties->find(group_name);
					if (default_definition != default_properties->end())
						group_properties = &(*groups.insert(PropertyGroupMap::value_type(group_name, PropertyGroup(group_class, (*default_definition).second.second))).first).second.second;
				}

				// If we still haven't got somewhere to put the properties for the new decorator, make a new
				// definition.
				if (group_properties == NULL)
					group_properties = &(*groups.insert(PropertyGroupMap::value_type(group_name, PropertyGroup(group_class, PropertyDictionary()))).first).second.second;
			}

			// Now find all of this decorator's properties.
			BuildPropertyGroupDictionary(*group_properties, group_type, group_name, element_properties);
		}
	}

	// Now go through all the default decorator definitions and see if the new property list redefines any properties
	// used by them.
	if (default_properties != NULL)
	{
		for (PropertyGroupMap::const_iterator default_definition_iterator = default_properties->begin(); default_definition_iterator != default_properties->end(); ++default_definition_iterator)
		{
			const String& default_definition_name = (*default_definition_iterator).first;

			// Check the list of new definitions hasn't defined this decorator already; if so, it overrode the
			// decorator type and so has inherited all the properties anyway.
			if (groups.find(default_definition_name) == groups.end())
			{
				// Nope! Make a copy of the decorator's properties and see if the new dictionary overrides any of the
				// properties.
				PropertyDictionary decorator_properties = (*default_definition_iterator).second.second;
				if (BuildPropertyGroupDictionary(decorator_properties, group_type, default_definition_name, element_properties) > 0)
					groups[default_definition_name] = PropertyGroup((*default_definition_iterator).second.first, decorator_properties);
			}
		}
	}
}
// Parses a property declaration, setting any parsed and validated properties on the given dictionary.
bool PropertySpecification::ParsePropertyDeclaration(PropertyDictionary& dictionary, const String& property_name, const String& property_value, const String& source_file, int source_line_number) const
{
	String lower_case_name = property_name.ToLower();

	// Attempt to parse as a single property.
	const PropertyDefinition* property_definition = GetProperty(lower_case_name);

	StringList property_values;
	if (!ParsePropertyValues(property_values, property_value, property_definition == NULL) || property_values.size() == 0)
		return false;

	if (property_definition != NULL)
	{
		Property new_property;
		new_property.source = source_file;
		new_property.source_line_number = source_line_number;
		if (property_definition->ParseValue(new_property, property_values[0]))
		{
			dictionary.SetProperty(lower_case_name, new_property);
			return true;
		}

		return false;
	}

	// Try as a shorthand.
	const PropertyShorthandDefinition* shorthand_definition = GetShorthand(lower_case_name);
	if (shorthand_definition != NULL)
	{
		// If this definition is a 'box'-style shorthand (x-top, x-right, x-bottom, x-left, etc) and there are fewer
		// than four values
		if (shorthand_definition->type == BOX &&
			property_values.size() < 4)
		{
			switch (property_values.size())
			{
				// Only one value is defined, so it is parsed onto all four sides.
				case 1:
				{
					for (int i = 0; i < 4; i++)
					{
						Property new_property;
						if (!shorthand_definition->properties[i].second->ParseValue(new_property, property_values[0]))
							return false;

						new_property.source = source_file;
						new_property.source_line_number = source_line_number;
						dictionary.SetProperty(shorthand_definition->properties[i].first, new_property);
					}
				}
				break;

				// Two values are defined, so the first one is parsed onto the top and bottom value, the second onto
				// the left and right.
				case 2:
				{
					// Parse the first value into the top and bottom properties.
					Property new_property;
					new_property.source = source_file;
					new_property.source_line_number = source_line_number;

					if (!shorthand_definition->properties[0].second->ParseValue(new_property, property_values[0]))
						return false;
					dictionary.SetProperty(shorthand_definition->properties[0].first, new_property);

					if (!shorthand_definition->properties[2].second->ParseValue(new_property, property_values[0]))
						return false;
					dictionary.SetProperty(shorthand_definition->properties[2].first, new_property);

					// Parse the second value into the left and right properties.
					if (!shorthand_definition->properties[1].second->ParseValue(new_property, property_values[1]))
						return false;
					dictionary.SetProperty(shorthand_definition->properties[1].first, new_property);

					if (!shorthand_definition->properties[3].second->ParseValue(new_property, property_values[1]))
						return false;
					dictionary.SetProperty(shorthand_definition->properties[3].first, new_property);
				}
				break;

				// Three values are defined, so the first is parsed into the top value, the second onto the left and
				// right, and the third onto the bottom.
				case 3:
				{
					// Parse the first value into the top property.
					Property new_property;
					new_property.source = source_file;
					new_property.source_line_number = source_line_number;

					if (!shorthand_definition->properties[0].second->ParseValue(new_property, property_values[0]))
						return false;
					dictionary.SetProperty(shorthand_definition->properties[0].first, new_property);

					// Parse the second value into the left and right properties.
					if (!shorthand_definition->properties[1].second->ParseValue(new_property, property_values[1]))
						return false;
					dictionary.SetProperty(shorthand_definition->properties[1].first, new_property);

					if (!shorthand_definition->properties[3].second->ParseValue(new_property, property_values[1]))
						return false;
					dictionary.SetProperty(shorthand_definition->properties[3].first, new_property);

					// Parse the third value into the bottom property.
					if (!shorthand_definition->properties[2].second->ParseValue(new_property, property_values[2]))
						return false;
					dictionary.SetProperty(shorthand_definition->properties[2].first, new_property);
				}
				break;

				default:	break;
			}
		}
		else
		{
			size_t value_index = 0;
			size_t property_index = 0;

			for (; value_index < property_values.size() && property_index < shorthand_definition->properties.size(); property_index++)
			{
				Property new_property;
				new_property.source = source_file;
				new_property.source_line_number = source_line_number;

				if (!shorthand_definition->properties[property_index].second->ParseValue(new_property, property_values[value_index]))
				{
					// This definition failed to parse; if we're falling through, try the next property. If there is no
					// next property, then abort!
					if (shorthand_definition->type == FALL_THROUGH)
					{
						if (property_index + 1 < shorthand_definition->properties.size())
							continue;
					}
					return false;
				}

				dictionary.SetProperty(shorthand_definition->properties[property_index].first, new_property);

				// Increment the value index, unless we're replicating the last value and we're up to the last value.
				if (shorthand_definition->type != REPLICATE ||
					value_index < property_values.size() - 1)
					value_index++;
			}
		}

		return true;
	}

	// Can't find it! Store as an unknown string value.
	Property new_property(property_value, Property::UNKNOWN);
	new_property.source = source_file;
	new_property.source_line_number = source_line_number;
	dictionary.SetProperty(lower_case_name, new_property);

	return true;
}