예제 #1
0
bool ThrowAbility::use() {
   if (isOnCooldown()) {
      return false;
   }

   SPtr<Scene> scene = gameObject.getScene().lock();
   if (!scene) {
      return false;
   }

   const glm::vec3 &position = gameObject.getCameraComponent().getCameraPosition();
   const glm::vec3 &front = gameObject.getCameraComponent().getFrontVector();
   const glm::vec3 &right = gameObject.getCameraComponent().getRightVector();

   SPtr<GameObject> projectile(std::make_shared<GameObject>());
   projectile->setPosition(position + front + right * 0.25f);
   projectile->setScale(glm::vec3(PROJECTILE_SCALE));

   // Graphics
   SPtr<Model> playerModel = gameObject.getGraphicsComponent().getModel();
   SPtr<Mesh> mesh = Context::getInstance().getAssetManager().loadMesh("meshes/rock_attack.obj");
   glm::vec3 color(1.0f, 0.75f, 0.15f);
   PlayerLogicComponent *playerLogic = dynamic_cast<PlayerLogicComponent*>(&gameObject.getLogicComponent());
   if (playerLogic) {
      color = playerLogic->getColor();
   }
   SPtr<Material> material(std::make_shared<PhongMaterial>(color * 0.2f, color * 0.6f, glm::vec3(0.2f), color * 0.2f, 50.0f));
   SPtr<Model> model(std::make_shared<Model>(playerModel->getShaderProgram(), mesh));
   model->attachMaterial(material);
   projectile->setGraphicsComponent(std::make_shared<GeometricGraphicsComponent>(*projectile));
   projectile->getGraphicsComponent().setModel(model);

   // Physics
   projectile->setPhysicsComponent(std::make_shared<MeshPhysicsComponent>(*projectile, 0.05f, CollisionGroup::Projectiles, CollisionGroup::Everything));
   btRigidBody *projectileRigidBody = dynamic_cast<btRigidBody*>(projectile->getPhysicsComponent().getCollisionObject());
   projectileRigidBody->setFriction(1.0f);
   projectileRigidBody->setRollingFriction(0.25f);
   projectileRigidBody->setRestitution(0.5f);
   projectileRigidBody->applyCentralForce(toBt(front * 100.0f));

   // Logic
   SPtr<ProjectileLogicComponent> logic(std::make_shared<ProjectileLogicComponent>(*projectile));
   WPtr<GameObject> wProjectile(projectile);
   GameObject &creator = gameObject;
   logic->setCollisionCallback([wProjectile, color, &creator](GameObject &gameObject, const btCollisionObject *objectCollidedWidth, const float dt) {
      if (objectCollidedWidth == creator.getPhysicsComponent().getCollisionObject()) {
         return;
      }

      SPtr<Scene> scene = gameObject.getScene().lock();
      if (!scene) {
         return;
      }

      SPtr<GameObject> projectile = wProjectile.lock();
      if (!projectile) {
         return;
      }

      scene->removeObject(projectile);

      SPtr<GameObject> explosion(createExplosion(projectile->getPosition(), 1.0f, color));
      scene->addLight(explosion);
      scene->addObject(explosion);
   });
   projectile->setLogicComponent(logic);

   // Audio
   SPtr<AudioComponent> audioComponent(std::make_shared<AudioComponent>(*projectile));
   audioComponent->registerSoundEvent(Event::SET_SCENE, SoundGroup::THROW);
   projectile->setAudioComponent(audioComponent);

   scene->addObject(projectile);

   resetTimeSinceLastUse();

   return true;
}