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