Beispiel #1
0
/**
 * \brief Changes the name of an entity.
 * \param index Index of the entity on the map.
 * \param name The new name. An empty string means no name.
 * \return \c true in case of success, \c false if the name was already used.
 */
bool MapData::set_entity_name(const EntityIndex& index, const std::string& name) {

  EntityData& entity = get_entity(index);
  const std::string& old_name = entity.get_name();

  if (name == old_name) {
    // Nothing to do.
    return true;
  }

  if (!name.empty()) {
    if (entity_exists(name)) {
      // This name is already used by another entity.
      return false;
    }
  }

  // Do the change.
  entity.set_name(name);

  if (!old_name.empty()) {
    named_entities.erase(old_name);
  }

  if (!name.empty()) {
    named_entities[name] = index;
  }

  return false;
}
Beispiel #2
0
/**
 * \brief Returns the entity at the given layer and index.
 *
 * Non-const version.
 *
 * \param index Index of the entity to get on the map.
 * \return The entity data.
 * The object remains valid until entities are added or removed.
 */
EntityData& MapData::get_entity(const EntityIndex& index) {

  Debug::check_assertion(entity_exists(index),
      "Entity index out of range"
  );

  return get_entities(index.layer)[index.order];
}
Beispiel #3
0
/**
 * \brief Adds an entity to the map at the specified index.
 *
 * If the new entity has a name, it should be unique on the map.
 *
 * \param entity The information of an entity.
 * \param index The index this entity should have on the map.
 * \return \c false in case of failure, that is,
 * if the name was already in use, if the entity type is illegal
 * or if the index was out of range.
 */
bool MapData::insert_entity(const EntityData& entity, const EntityIndex& index) {

  if (!EntityTypeInfo::can_be_stored_in_map_file(entity.get_type())) {
    // Illegal type of entity in a map file.
    return false;
  }

  const Layer layer = index.layer;
  int order = index.order;
  bool dynamic = entity.is_dynamic();
  int min_order = dynamic ? get_num_tiles(layer) : 0;
  int max_order = dynamic ? get_num_entities(layer) : get_num_tiles(layer);

  if (order < min_order || order > max_order) {
    // Index out of range.
    return false;
  }

  if (entity.has_name()) {
    if (entity_exists(entity.get_name())) {
      // This name is already used by another entity.
      return false;
    }

    named_entities.emplace(entity.get_name(), index);
  }

  if (!dynamic) {
    ++this->entities[layer].num_tiles;
  }

  std::deque<EntityData>& entities = get_entities(layer);
  auto it = entities.begin() + order;
  entities.emplace(it, entity);

  // Indexes after this one get shifted.
  for (it = entities.begin() + order + 1;
      it != entities.end();
      ++it
  ) {
    const EntityData& current_entity = *it;
    const std::string& name = current_entity.get_name();
    if (!name.empty()) {
      EntityIndex& index = named_entities[name];
      ++index.order;
    }
  }

  return true;
}
Beispiel #4
0
entity_t entity_new(uint32_t type)
{
  type = type & TYPE_MASK;
  entity_t entity;
  ue_lock.lock();
  if (unused.size() > 0 && entity_retrieve_by_type(type, &entity))
  {
    ue_lock.unlock();
  }
  else
  {
    ue_lock.unlock();
    ne_lock.lock();
    entity = next_entity;
    entity_t start = next_entity - 1;
    while(entity_exists(entity) && start != next_entity)
    {
      next_entity = (next_entity + 1) & ENTITY_MASK;
      entity = next_entity | type;
    }
    ne_lock.unlock();

    // Invalid entity
    if (start == next_entity)
    {
      entity = entity | ENTITY_MASK;
    }
  }

  // If it was a valid entity, add it to the claimed entities vector
  if ((entity & ENTITY_MASK) != ENTITY_MASK)
  {
    ce_lock.lock();
    claimed.push_back(entity);
    ce_lock.unlock();
  }

  return entity;
}
Beispiel #5
0
/**
 * \brief Removes an entity from the map.
 * \param index Index of the entity on the map.
 * \return \c false in case of failure, that is,
 * if the index is out of range.
 */
bool MapData::remove_entity(const EntityIndex& index) {

  if (!entity_exists(index)) {
    return false;
  }

  Layer layer = index.layer;
  int order = index.order;
  const EntityData& entity = get_entity(index);
  bool dynamic = entity.is_dynamic();

  if (entity.has_name()) {
    named_entities.erase(entity.get_name());
  }

  if (!dynamic) {
    --this->entities[layer].num_tiles;
  }

  std::deque<EntityData>& entities = get_entities(layer);
  auto it = entities.begin() + order;
  entities.erase(it);

  // Indexes after this one get shifted.
  for (it = entities.begin() + order;
      it != entities.end();
      ++it) {
    const EntityData& current_entity = *it;
    const std::string& name = current_entity.get_name();
    if (!name.empty()) {
      EntityIndex& index = named_entities[name];
      --index.order;
    }
  }
  return true;
}