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