1 #include <GL/glew.h>
2
3 #include "blackHole.h"
4 #include "pathPlanner.h"
5 #include "main.h"
6 #include <SFML/OpenGL.hpp>
7
8 #include "scriptInterface.h"
9 #include "glObjects.h"
10 #include "shaderRegistry.h"
11
12
13 #if FEATURE_3D_RENDERING
14 struct VertexAndTexCoords
15 {
16 sf::Vector3f vertex;
17 sf::Vector2f texcoords;
18 };
19 #endif
20
21 /// A blackhole has a 5km radius where it pulls in all near objects. At the center of the black hole everything gets a lot of damage.
22 /// Which will lead to the eventual destruction of said object.
REGISTER_SCRIPT_SUBCLASS(BlackHole,SpaceObject)23 REGISTER_SCRIPT_SUBCLASS(BlackHole, SpaceObject)
24 {
25 }
26
27 REGISTER_MULTIPLAYER_CLASS(BlackHole, "BlackHole");
BlackHole()28 BlackHole::BlackHole()
29 : SpaceObject(5000, "BlackHole")
30 {
31 update_delta = 0.0;
32 PathPlannerManager::getInstance()->addAvoidObject(this, 7000);
33 setRadarSignatureInfo(0.9, 0, 0);
34 }
35
update(float delta)36 void BlackHole::update(float delta)
37 {
38 update_delta = delta;
39 }
40
41 #if FEATURE_3D_RENDERING
draw3DTransparent()42 void BlackHole::draw3DTransparent()
43 {
44 static std::array<VertexAndTexCoords, 4> quad{
45 sf::Vector3f(), {0.f, 1.f},
46 sf::Vector3f(), {1.f, 1.f},
47 sf::Vector3f(), {1.f, 0.f},
48 sf::Vector3f(), {0.f, 0.f}
49 };
50
51 glBindTexture(GL_TEXTURE_2D, textureManager.getTexture("blackHole3d.png")->getNativeHandle());
52 ShaderRegistry::ScopedShader shader(ShaderRegistry::Shaders::Billboard);
53
54 glUniform4f(shader.get().uniform(ShaderRegistry::Uniforms::Color), 1.f, 1.f, 1.f, 5000.f);
55 gl::ScopedVertexAttribArray positions(shader.get().attribute(ShaderRegistry::Attributes::Position));
56 gl::ScopedVertexAttribArray texcoords(shader.get().attribute(ShaderRegistry::Attributes::Texcoords));
57
58 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
59
60 glVertexAttribPointer(positions.get(), 3, GL_FLOAT, GL_FALSE, sizeof(VertexAndTexCoords), (GLvoid*)quad.data());
61 glVertexAttribPointer(texcoords.get(), 2, GL_FLOAT, GL_FALSE, sizeof(VertexAndTexCoords), (GLvoid*)((char*)quad.data() + sizeof(sf::Vector3f)));
62
63 std::initializer_list<uint8_t> indices = { 0, 2, 1, 0, 3, 2 };
64 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, std::begin(indices));
65 glBlendFunc(GL_ONE, GL_ONE);
66 }
67 #endif
68
drawOnRadar(sf::RenderTarget & window,sf::Vector2f position,float scale,float rotation,bool long_range)69 void BlackHole::drawOnRadar(sf::RenderTarget& window, sf::Vector2f position, float scale, float rotation, bool long_range)
70 {
71 sf::Sprite object_sprite;
72 textureManager.setTexture(object_sprite, "blackHole.png");
73 object_sprite.setRotation(getRotation());
74 object_sprite.setPosition(position);
75 float size = getRadius() * scale / object_sprite.getTextureRect().width * 2;
76 object_sprite.setScale(size, size);
77 object_sprite.setColor(sf::Color(64, 64, 255));
78 window.draw(object_sprite);
79 object_sprite.setColor(sf::Color(0, 0, 0));
80 window.draw(object_sprite);
81 }
82
collide(Collisionable * target,float collision_force)83 void BlackHole::collide(Collisionable* target, float collision_force)
84 {
85 if (update_delta == 0.0)
86 return;
87
88 P<SpaceObject> obj = P<Collisionable>(target);
89 if (!obj) return;
90 if (!obj->hasWeight()) { return; } // the object is not affected by gravitation
91
92 sf::Vector2f diff = getPosition() - target->getPosition();
93 float distance = sf::length(diff);
94 float force = (getRadius() * getRadius() * 50.0f) / (distance * distance);
95 DamageInfo info(NULL, DT_Kinetic, getPosition());
96 if (force > 10000.0)
97 {
98 force = 10000.0;
99 if (isServer())
100 {
101 obj->takeDamage(100000.0, info); //try to destroy the object by inflicting a huge amount of damage
102 if (target)
103 {
104 target->destroy();
105 return;
106 }
107 }
108 }
109 if (force > 100.0 && isServer())
110 {
111 obj->takeDamage(force * update_delta / 10.0f, info);
112 }
113 if (!obj) {return;}
114 obj->setPosition(obj->getPosition() + diff / distance * update_delta * force);
115 }
116