Esempio n. 1
0
corgi::EntityRef PlayerComponent::SpawnProjectile(corgi::EntityRef source) {
  const SushiConfig* current_sushi = static_cast<const SushiConfig*>(
      entity_manager_->GetComponent<ServicesComponent>()
          ->world()
          ->SelectedSushi()
          ->data());
  corgi::EntityRef projectile =
      entity_manager_->GetComponent<ServicesComponent>()
          ->entity_factory()
          ->CreateEntityFromPrototype(current_sushi->prototype()->c_str(),
                                      entity_manager_);
  GraphComponent* graph_component =
      entity_manager_->GetComponent<GraphComponent>();
  graph_component->EntityPostLoadFixup(projectile);

  TransformData* transform_data = Data<TransformData>(projectile);
  PhysicsData* physics_data = Data<PhysicsData>(projectile);
  PlayerProjectileData* projectile_data =
      Data<PlayerProjectileData>(projectile);

  TransformComponent* transform_component = GetComponent<TransformComponent>();
  transform_data->position =
      transform_component->WorldPosition(source) +
      mathfu::kAxisZ3f * config_->projectile_height_offset();
  auto forward = CalculateProjectileDirection(source);
  auto velocity = current_sushi->speed() * forward +
                  current_sushi->upkick() * mathfu::kAxisZ3f;
  transform_data->position +=
      velocity.Normalized() * config_->projectile_forward_offset();

  // Include the raft's current velocity to the thrown sushi.
  auto raft_entity =
      entity_manager_->GetComponent<ServicesComponent>()->raft_entity();
  auto raft_rail = raft_entity ? Data<RailDenizenData>(raft_entity) : nullptr;
  if (raft_rail != nullptr) velocity += raft_rail->Velocity();

  physics_data->SetVelocity(velocity);
  physics_data->SetAngularVelocity(RandomProjectileAngularVelocity());
  auto physics_component = entity_manager_->GetComponent<PhysicsComponent>();
  physics_component->UpdatePhysicsFromTransform(projectile);

  projectile_data->owner = source;

  // TODO: Preferably, this should be a step in the entity creation.
  transform_component->UpdateChildLinks(projectile);

  Data<AttributesData>(source)->attributes[AttributeDef_ProjectilesFired]++;

  return corgi::EntityRef();
}
Esempio n. 2
0
void TransformComponent::AddFromRawData(corgi::EntityRef& entity,
                                        const void* raw_data) {
  auto transform_def = static_cast<const TransformDef*>(raw_data);
  auto pos = transform_def->position();
  auto orientation = transform_def->orientation();
  auto scale = transform_def->scale();
  TransformData* transform_data = AddEntity(entity);
  // TODO: Move vector loading into a function in fplbase.
  if (pos != nullptr) {
    transform_data->position = mathfu::vec3(pos->x(), pos->y(), pos->z());
  }
  if (orientation != nullptr) {
    transform_data->orientation = mathfu::quat::FromEulerAngles(
        mathfu::vec3(orientation->x(), orientation->y(), orientation->z()) *
        kDegreesToRadians);
  }
  if (scale != nullptr) {
    transform_data->scale = mathfu::vec3(scale->x(), scale->y(), scale->z());
  }

  // The physics component is initialized first, so it needs to be updated with
  // the correct initial transform.
  auto physics_component = entity_manager_->GetComponent<PhysicsComponent>();
  if (IsRegisteredWithComponent<PhysicsComponent>(entity)) {
    physics_component->UpdatePhysicsFromTransform(entity);
  }

  if (transform_def->child_ids() != nullptr) {
    for (size_t i = 0; i < transform_def->child_ids()->size(); i++) {
      auto child_id = transform_def->child_ids()->Get(
          static_cast<flatbuffers::uoffset_t>(i));
      // We don't actually add the children until the first update,
      // to give the other entities in our list time to be loaded.
      if (transform_data->child_ids.find(child_id->c_str()) ==
          transform_data->child_ids.end()) {
        transform_data->pending_child_ids.push_back(child_id->c_str());
        transform_data->child_ids.insert(child_id->c_str());
      }
    }
  }
}