POSITIVE-MENTAL-ATTITUDE 8 years ago
parent
commit
4fc6abd992

BIN
data/audio/Ossuary 6 - Air.ogg


BIN
data/background/75pxjitter03.png


BIN
data/background/Foreground_normal.jpg


BIN
data/background/Light_Alt.png


data/light/star.png → data/light/Star.png


BIN
data/light/star.xcf


BIN
data/triangle/Star.png


+ 2 - 2
src/Collidable.hpp

@@ -41,8 +41,8 @@ class Collidable
 		void setPointCount(unsigned pointCount);
 		std::vector<sf::Vector2f> _cmap; /// Current to-be-destroyed points on the edges
 		std::vector<sf::Vector2f> _cbanned; /// Already destroyed points
-		unsigned _pointCount;
-		float _durability; // Normalized value
+		unsigned _pointCount; // Total number of non-transparent points
+		float _durability; // Normalized value how many points the Collidable object can lose before dying
 
 	private:
 		sf::Transform _transform;

+ 56 - 13
src/Foreground.cpp

@@ -19,6 +19,8 @@
 #include <iostream>
 #include <cmath>
 
+Foreground::Foreground(): _wormholePosition(0, 0) {}
+
 Foreground::~Foreground()
 {
 	for(unsigned i = 0; i < _sprites.size(); ++i)
@@ -116,28 +118,48 @@ void Foreground::create(sf::Image& foreground, sf::Image& normal, sf::Image& map
 	}
 	for(unsigned i = 0; i < _tiles.size(); ++i)
 	{
-		// std::get instead of .first and .second because it used to be a tuple
-		// and I did not rewrite this.
-		std::get<0>(_tiles[i]).create(_tileSize, _tileSize, sf::Color::Yellow);
-		std::get<0>(_normalTiles[i]).create(_tileSize, _tileSize, sf::Color::Yellow);
+		_tiles[i].first.create(_tileSize, _tileSize, sf::Color::Yellow);
+		_normalTiles[i].first.create(_tileSize, _tileSize, sf::Color::Yellow);
 	}
 	for(unsigned i = 0; i < _tileCount.x * _tileSize; ++i)
 		for(unsigned j = 0; j < _tileCount.y * _tileSize; ++j)
 		{
 			sf::Color color = foreground.getPixel(i % foreground.getSize().x, j % foreground.getSize().y);
-			std::get<0>(_tiles[j / _tileSize * _tileCount.x + i / _tileSize])
-			.setPixel(i % _tileSize, j % _tileSize, sf::Color(color.r, color.g, color.b, i < map.getSize().x and j < map.getSize().y ? 255 - map.getPixel(i, j).r : 255));
+			
+			_tiles[j / _tileSize * _tileCount.x + i / _tileSize].first
+			.setPixel(i % _tileSize, j % _tileSize, sf::Color(color.r, color.g, color.b, i < map.getSize().x && j < map.getSize().y ? 255 - map.getPixel(i, j).r : 255));
 			color = normal.getPixel(i % normal.getSize().x, j % normal.getSize().y);
-			std::get<0>(_normalTiles[j / _tileSize * _tileCount.x + i / _tileSize])
-			.setPixel(i % _tileSize, j % _tileSize, sf::Color(color.r, color.g, color.b, i < map.getSize().x and j < map.getSize().y ? 255 - map.getPixel(i, j).r : 255));
+			_normalTiles[j / _tileSize * _tileCount.x + i / _tileSize].first
+			.setPixel(i % _tileSize, j % _tileSize, sf::Color(color.r, color.g, color.b, i < map.getSize().x && j < map.getSize().y ? 255 - map.getPixel(i, j).r : 255));
+			
+			if(i >= map.getSize().x - 1 || j >= map.getSize().y - 1)
+				continue;
+			
+			if(i == 0 || j == 0)
+				continue;
+				
+			color = map.getPixel(i, j);
+
+			if((int)color.g > 0 && (int)color.g != 255)
+			{
+				if((int(map.getPixel(i - 1, j).g) == 0 || int(map.getPixel(i - 1, j).g) == 255)
+				&& (int(map.getPixel(i , j - 1).g) == 0 || int(map.getPixel(i, j - 1).g) == 255))
+				{
+					if((int)color.b == 255 && (int)color.g == 100)
+						_wormholePosition = sf::Vector2u(i, j);
+					else if((int)color.b == 0 && (int)color.g == 250)
+						_starPosition.emplace_back(i, j);
+				}
+			}
 		}
+	Echo::info(_starPosition.size());
 	for(unsigned i = 0; i < _tiles.size(); ++i)
 	{
-		std::get<1>(_tiles[i]).loadFromImage(std::get<0>(_tiles[i]));
-		_sprites[i % _tileCount.x][i / _tileCount.x].setTexture(std::get<1>(_tiles[i]));
+		_tiles[i].second.loadFromImage(_tiles[i].first);
+		_sprites[i % _tileCount.x][i / _tileCount.x].setTexture(_tiles[i].second);
 		_sprites[i % _tileCount.x][i / _tileCount.x].setPosition((i % _tileCount.x) * _tileSize, (i / _tileCount.x) * _tileSize);
-		std::get<1>(_normalTiles[i]).loadFromImage(std::get<0>(_normalTiles[i]));
-		_normalSprites[i % _tileCount.x][i / _tileCount.x].setTexture(std::get<1>(_normalTiles[i]));
+		_normalTiles[i].second.loadFromImage(_normalTiles[i].first);
+		_normalSprites[i % _tileCount.x][i / _tileCount.x].setTexture(_normalTiles[i].second);
 		_normalSprites[i % _tileCount.x][i / _tileCount.x].setPosition((i % _tileCount.x) * _tileSize, (i / _tileCount.x) * _tileSize);
 	}
 }
@@ -174,16 +196,21 @@ void Foreground::move(sf::Vector2f movement)
 {
 	for(unsigned i = 0; i < _renderCount.x; ++i)
 		for(unsigned j = 0; j < _renderCount.y; ++j)
+		{
 			_sprites[i][j].move(movement);
+			_normalSprites[i][j].move(movement);
+		}
 }
 
 void Foreground::rotate(float rotation)
 {
 	for(unsigned i = 0; i < _renderCount.x; ++i)
 		for(unsigned j = 0; j < _renderCount.y; ++j)
+		{
 			_sprites[i][j].rotate(rotation);
+			_normalSprites[i][j].rotate(rotation);
+		}
 }
-
 void Foreground::draw(sf::RenderTarget& target, sf::RenderStates states) const
 {
 	unsigned x = _position.x / _tileSize, y = _position.y / _tileSize;
@@ -197,3 +224,19 @@ void Foreground::draw(sf::RenderTarget& target, sf::RenderStates states) const
 						target.draw(_normalSprites[i + x][j + y], states);
 				}
 }
+
+const sf::Vector2f Foreground::getWormholePosition() const
+{
+	return sf::Vector2f(_wormholePosition);
+}
+
+const bool Foreground::getStarPosition(sf::Vector2f& starPosition)
+{
+	if(_starPosition.size() == 0) 
+		return false;
+	
+	starPosition = sf::Vector2f(_starPosition.back());
+	_starPosition.pop_back();
+	Echo::debug(starPosition.x);
+	return true;
+}

+ 8 - 1
src/Foreground.hpp

@@ -19,6 +19,7 @@
 
 #include <vector>
 #include <SFML/Graphics.hpp>
+#include "Utility.hpp"
 
 /**
  * @class Foreground
@@ -30,7 +31,7 @@
 class Foreground: public sf::Drawable
 {
 	public:
-		Foreground() = default;
+		Foreground();
 		~Foreground();
 		void create(sf::Image& foreground, sf::Image& normal, sf::Image& map);
 		void create(std::string foreground, std::string normal, std::string map);
@@ -45,6 +46,9 @@ class Foreground: public sf::Drawable
 		void renderNormals(bool render);
 		void move(sf::Vector2f movement);
 		void rotate(float rotation);
+		const Rect getBounds() const;
+		const sf::Vector2f getWormholePosition() const;
+		const bool getStarPosition(sf::Vector2f& starPosition);
 
 	private:
 		void draw(sf::RenderTarget& target, sf::RenderStates states) const;
@@ -57,5 +61,8 @@ class Foreground: public sf::Drawable
 		unsigned _tileSize;
 		sf::Vector2u _position;
 		bool _renderNormals;
+		
+		sf::Vector2u _wormholePosition;
+		std::vector<sf::Vector2u> _starPosition;
 };
 

+ 62 - 26
src/IngameState.cpp

@@ -21,12 +21,12 @@
 #include "IngameState.hpp"
 #include "Player.hpp"
 
-IngameState::IngameState(): State(), _player(), _paused(false), _blurSize(0.f), _frameAlpha(0.f), _wormhole() {}
+IngameState::IngameState(): State(), _player(), _paused(false), _blurSize(0.f), _frameAlpha(0.f), _wormhole(), _starsCollected(0) {}
 
 IngameState::~IngameState()
 {
 	Echo::debug("Flushing state");
-	_lightSystem.removeLight(_light);
+	_lightSystem.removeLight(_player.light());
 	_lightSystem.removeLight(_wormhole.light());
 }
 
@@ -50,16 +50,14 @@ void IngameState::init()
 	_background.setTexture(_context->assets->loadTexture("data/background/Background.jpg"));
 	_context->assets->loadTexture("data/background/Background.jpg").setRepeated(true);
 
-	_player.setContext(_context);
-	_player.setTexture(_context->assets->loadTexture(rand() % 10 == 0 ? "data/triangle/Illuminati.png" : "data/triangle/Texture.png"));
+	bool illuminati = (rand() % 10 == 0);
+	_player.setIlluminati(illuminati);
+	_player.setContext(_context); 
+	_player.setTexture(_context->assets->loadTexture(illuminati ? "data/triangle/Illuminati.png" : "data/triangle/Texture.png"));
 	_player.setPosition(556.f, 2200.f);
-	
+	 
 	_foreground.create("data/background/Foreground.jpg", "data/background/Foreground_normal.jpg", "data/background/75pxjitter03.png");
 	_context->foreground = &_foreground;
-	_spike.create("data/background/Foreground.jpg", "data/background/Foreground_normal.jpg", "data/background/Spikes16px.png");
-	_spike.setResolution(sf::Vector2u(0, 0));
-	_spike.move(sf::Vector2f(1020, 2310));
-	_spike.rotate(332.f);
 	
 	_background.setTextureRect(sf::IntRect(0, 0, _foreground.getSize().x, _foreground.getSize().y));
 	
@@ -72,13 +70,6 @@ void IngameState::init()
 	_penumbraTexture.loadFromFile("data/light/penumbraTexture.png");
 	_penumbraTexture.setSmooth(true);
 	
-	_light = std::make_shared<ltbl::LightPointEmission>();
-	_light->_emissionSprite.setPosition(0.f, 0.f);
-	_light->_emissionSprite.setTexture(_context->assets->loadTexture("data/background/Light.png"));
-	_light->_emissionSprite.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Light.png").getSize() / 2u));
-	_light->_emissionSprite.setColor(sf::Color::White);
-	_light->_localCastCenter = sf::Vector2f(0.0f, 0.0f); // This is where the shadows emanate from relative to the sprite
-	
 	_blurV.loadFromFile("data/shaders/old_pi_blur/blur.vert", "data/shaders/old_pi_blur/blur-v.frag");
 	_blurH.loadFromFile("data/shaders/old_pi_blur/blur.vert", "data/shaders/old_pi_blur/blur-h.frag");
 	
@@ -86,15 +77,25 @@ void IngameState::init()
 	_dotaSound.setBuffer(_context->assets->loadSound("data/audio/Victory.ogg"));
 	
 	_wormhole.load(_context->assets->loadTexture("data/triangle/Wormhole.png"), _context->assets->loadTexture("data/triangle/Wormhole_light.png"));
-	_wormhole.setPosition(400.f, 400.f);
+	_wormhole.setPosition(_foreground.getWormholePosition());
+	
+	sf::Vector2f starPosition;
+	while(_foreground.getStarPosition(starPosition))
+		_star.emplace_back(_context->assets->loadTexture("data/triangle/Star.png"), _context->assets->loadTexture("data/light/Star.png"), starPosition);
+	_starsCount = _star.size();
 	
 	_statsTime.setFont(_context->assets->loadFont("data/ttf/canonical/Ubuntu-L.ttf"));
 	_statsHull.setFont(_context->assets->loadFont("data/ttf/canonical/Ubuntu-L.ttf"));
+	_statsStars.setFont(_context->assets->loadFont("data/ttf/canonical/Ubuntu-L.ttf"));
 	_statsTime.setCharacterSize(30);
 	_statsHull.setCharacterSize(30);
+	_statsStars.setCharacterSize(30);
 	
 	// Global window is not initialized yet in this method. If you need _context->window->getSize(), go to refresh() instead.
 	
+	_music.openFromFile("data/audio/Ossuary 6 - Air.ogg");
+	_music.setLoop(true);
+	_music.play();
 	_totalTime.restart();
 	_status = State::Ongoing;
 }
@@ -105,6 +106,7 @@ void IngameState::refresh()
 	//_background.setTextureRect(sf::IntRect(0, 0, _context->window->getSize().x, _context->window->getSize().y));
 	_camera.setSize(static_cast<sf::Vector2f>(_context->window->getSize()));
 	_camera.setTwilightViewport(_context->window->getSize().x / 2.f - 240.f/* * (bool) _czyWOgóleTwilightViewportMaByć*/, _context->window->getSize().y / 2.f - 240.f);
+	//_camera.setTwilightViewport(0, 0);
 	_camera.setCenter(_player.getPosition());
 	_foreground.setResolution(res);
 	
@@ -114,14 +116,18 @@ void IngameState::refresh()
 	_wasted.setPosition(_context->window->getSize().x / 2.f, _context->window->getSize().y * 1.5f);
 	_statsTime.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f);
 	_statsHull.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f);
+	_statsStars.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f);
 	
 	_backgroundH.create(_context->window->getSize().x, _context->window->getSize().y);
 	_backgroundV.create(_context->window->getSize().x, _context->window->getSize().y);
 
 	_lightSystem.create(sf::FloatRect{{0.f, 0.f}, {0.f, 0.f}}, {_context->window->getSize().x, _context->window->getSize().y}, _penumbraTexture, _unshadowShader, _lightOverShapeShader, _normalsShader);
 	_lightSystem.normalsEnabled(true);
-	_lightSystem.addLight(_light);
+	_lightSystem.addLight(_player.light());
 	_lightSystem.addLight(_wormhole.light());
+	unsigned k = _star.size();
+	for(unsigned i = 0; i < k; ++i)
+		_lightSystem.addLight(_star[i].light());
 }
 
 void IngameState::coreThink(const sf::Event& event)
@@ -163,11 +169,12 @@ void IngameState::coreUpdate(sf::Time delta)
 		|| (_wasted.getPosition().y < -_context->window->getSize().y / 2.f 
 		&& _marioSound.getStatus() == sf::Sound::Status::Stopped && !_player.hasWon()))
 		{
-			_wasted.move(0.f, -250.f * delta.asSeconds());
+			_wasted.move(0.f, -400.f * delta.asSeconds() * (_context->window->getSize().y / 1080.f));
 			if(_player.hasWon())
 			{
 				_statsTime.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f);
 				_statsHull.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f);
+				_statsStars.setPosition(_wasted.getPosition().x, _wasted.getPosition().y + 100.f);
 			}
 		}
 	}
@@ -181,7 +188,6 @@ void IngameState::coreUpdate(sf::Time delta)
 	const sf::Vector2f pos = _player.getPosition();
 	_player.update(delta);
 	_camera.move(_player.getPosition() - pos);
-	_light->_emissionSprite.setPosition(_player.getPosition());
 	_foreground.setPosition(_camera.getCenter() - _camera.getSize() / 2.f);
 	
 	if(_player.checkCollision(_foreground)) /// True if the target died.
@@ -189,6 +195,7 @@ void IngameState::coreUpdate(sf::Time delta)
 		_paused = true;
 		_wasted.setTexture(_context->assets->loadTexture("data/background/Wasted.png"));
 		_wasted.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Wasted.png").getSize() / 2u));
+		_music.stop();
 		_marioSound.play();
 	}
 	else if(_player.isDead() && _player.hasWon())
@@ -205,8 +212,14 @@ void IngameState::coreUpdate(sf::Time delta)
 		oss.clear();
 		oss << "Hull: " << int(_player.getHullLeft()) << "%";
 		_statsHull.setString(oss.str());
-		_statsTime.setOrigin(_statsTime.getLocalBounds().width / 2.f, _statsTime.getLocalBounds().height / 2.f - 30.f);
-		_statsHull.setOrigin(_statsTime.getLocalBounds().width / 2.f, _statsTime.getLocalBounds().height + _statsHull.getLocalBounds().height / 2.f);
+		oss.str(std::string());
+		oss.clear();
+		oss << "Stars: " << _starsCollected << '/' << _starsCount;
+		_statsStars.setString(oss.str());
+		_statsTime.setOrigin(_statsTime.getLocalBounds().width / 2.f, _statsTime.getLocalBounds().height / 2.f + 60.f);
+		_statsHull.setOrigin(_statsTime.getLocalBounds().width / 2.f, _statsTime.getLocalBounds().height / 2.f - _statsHull.getLocalBounds().height + 30.f);
+		_statsStars.setOrigin(_statsTime.getLocalBounds().width / 2.f, _statsTime.getLocalBounds().height / 2.f - _statsHull.getLocalBounds().height  - _statsStars.getLocalBounds().height);
+		_music.stop();
 		_dotaSound.play();
 	}
 	
@@ -228,6 +241,30 @@ void IngameState::coreUpdate(sf::Time delta)
 		else
 			_player.setScale(1.f, 1.f);
 	}
+	
+	for(unsigned i = 0; i < _star.size(); ++i)
+	{
+		if(_star[i].gravity(_player.getPosition(), delta))
+		{
+			_lightSystem.removeLight(_star[i].light());
+			_star.erase(_star.begin() + i);
+			_starsCollected++;
+		}
+	}
+	
+	{
+		const double degree = 3.14159265358 / 180.;
+		static float offset = 0.f;
+		static bool direction = false;
+		sf::Vector2f movement;
+		movement.x = std::sin((direction ? 152.f : 332.f) * degree) * (direction ? 1500.f : 100.f) * seconds;
+		movement.y = -std::cos((direction ? 152.f : 332.f) * degree) * (direction ? 1500.f : 100.f) * seconds;
+		offset += movement.y;
+		if(offset < -256.f)
+			direction = true;
+		if(offset >= 0.f)
+			direction = false;
+	}
 }
 void IngameState::coreRender(const bool shaders)
 {
@@ -259,6 +296,7 @@ void IngameState::coreRender(const bool shaders)
 		_context->window->draw(_wasted);
 		_context->window->draw(_statsTime);
 		_context->window->draw(_statsHull);
+		_context->window->draw(_statsStars);
 	}
 	else
 	{
@@ -267,19 +305,17 @@ void IngameState::coreRender(const bool shaders)
 		
 		
 		_foreground.renderNormals(true);
-		_spike.renderNormals(true);
 		_lightSystem.normalsTargetSetView(*_camera.getView());
 		_lightSystem.normalsTargetClear();
-		_lightSystem.normalsTargetDraw(_spike);
 		_lightSystem.normalsTargetDraw(_foreground);
 		_lightSystem.normalsTargetDisplay();
 		_lightSystem.render(*_camera.getView(), _unshadowShader, _lightOverShapeShader, _normalsShader);
 		
 		
 		_foreground.renderNormals(false);
-		_spike.renderNormals(false);
-		_context->window->draw(_spike);
 		_context->window->draw(_foreground);
+		for(unsigned i = 0; i < _star.size(); ++i)
+			_context->window->draw(_star[i]);
 		_context->window->draw(_wormhole);
 		_context->window->draw(_player);
 		

+ 7 - 2
src/IngameState.hpp

@@ -22,6 +22,7 @@
 #include "Foreground.hpp"
 #include "Camera.hpp"
 #include "Wormhole.hpp"
+#include "Star.hpp"
 #include "ltbl/lighting/LightSystem.h"
 
 class IngameState: public State
@@ -44,14 +45,12 @@ class IngameState: public State
 		Foreground _foreground;
 		Camera _camera;
 		sf::Sprite _background;
-		Foreground _spike;
 		
 		sf::Shader _unshadowShader;
 		sf::Shader _lightOverShapeShader;
 		sf::Shader _normalsShader;
 		sf::Texture _penumbraTexture;
 		ltbl::LightSystem _lightSystem;
-		std::shared_ptr<ltbl::LightPointEmission> _light;
 		
 		bool _cameraMode;
 		bool _paused;
@@ -60,6 +59,8 @@ class IngameState: public State
 		sf::Shader _blurV;
 		sf::Shader _blurH;
 		
+		sf::Music _music;
+		
 		float _blurSize;
 		float _frameAlpha;
 		
@@ -70,9 +71,13 @@ class IngameState: public State
 		
 		sf::Text _statsTime;
 		sf::Text _statsHull;
+		sf::Text _statsStars;
 		
 		sf::Clock _totalTime;
 		
 		Wormhole _wormhole;
+		std::vector<Star> _star;
+		unsigned _starsCollected;
+		unsigned _starsCount;
 };
 

+ 4 - 0
src/Input.cpp

@@ -21,17 +21,20 @@ Input::Input(const Input& other): _type(other._type), _positive(other._positive)
 {
 	std::memcpy(&_event, &other._event, sizeof(sf::Event));
 }
+
 Input& Input::operator=(const Input& other)
 {
 	std::memcpy(&_event, &other._event, sizeof(sf::Event));
 	_type = other._type;
 	return *this;
 }
+
 Input::Input(const sf::Keyboard::Key& key, int type): _type(type), _positive(true)
 {
 	_event.type = sf::Event::EventType::KeyPressed;
 	_event.key.code = key;
 }
+
 Input::Input(const sf::Mouse::Button& button, int type): _type(type), _positive(true)
 {
 	_event.type = sf::Event::EventType::MouseButtonPressed;
@@ -81,6 +84,7 @@ float Input::test() const
 	}
 	return 0.f;
 }
+
 bool Input::operator==(const sf::Event& event) const
 {
 	switch(event.type)

+ 28 - 0
src/Lantern.cpp

@@ -0,0 +1,28 @@
+/**
+ *  Triangles
+ *  Copyright (C) 2016 POSITIVE MENTAL ATTITUDE
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, version 3 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Lantern.hpp"
+
+Lantern::Lantern(): _light(std::make_shared<ltbl::LightPointEmission>())
+{
+	_light->_localCastCenter = sf::Vector2f(0.0f, 0.0f);
+}
+
+std::shared_ptr<ltbl::LightPointEmission>& Lantern::light()
+{
+	return _light;
+}

+ 33 - 0
src/Lantern.hpp

@@ -0,0 +1,33 @@
+/**
+ *  Triangles
+ *  Copyright (C) 2016 POSITIVE MENTAL ATTITUDE
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, version 3 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include <memory>
+#include "ltbl/lighting/LightPointEmission.h"
+
+class Lantern
+{
+	public:
+		Lantern();
+		std::shared_ptr<ltbl::LightPointEmission>& light();
+
+	private:
+		std::shared_ptr<ltbl::LightPointEmission> _light;
+
+};
+

+ 1 - 0
src/MenuState.cpp

@@ -43,6 +43,7 @@ void MenuState::init()
 	_credits.setColor(sf::Color::Black);
 	
 	_music.openFromFile("data/audio/Past the Edge.ogg");
+	_music.setLoop(true);
 	_music.play();
 	
 	_waterSine.loadFromFile("data/shaders/water.vs", sf::Shader::Fragment);

+ 44 - 9
src/Player.cpp

@@ -23,10 +23,11 @@ Player::Player():
 	Triangle(), 
 	InputTarget(_inputMap), 
 	Collidable(),
+	Lantern(),
 	_movement(0.f), 
-	_movementSpeed(2.f), 
+	_movementSpeed(0.6f), 
 	_movementMomentum(0.f),
-	_movementAcceleration(10.f),
+	_movementAcceleration(7.f),
 	_movementSuppresion(10.f),
 	_rotation(0.f), 
 	_rotationSpeed(0.6f), 
@@ -61,6 +62,7 @@ Player::Player():
 		_inputMap.map(5, Input(sf::Keyboard::Space));
 	 }
 	_inputMap.map(40, Input(sf::Keyboard::F9, Input::Type::Pressed));
+	_inputMap.map(6, Input(sf::Keyboard::LControl, Input::Type::Pressed));
 	
 	/**
 	 *  Input lambdas
@@ -94,12 +96,31 @@ Player::Player():
 								_context->foreground);
 			_bullets.back().setTexture(_innerTexture);
 			_bulletTimer.restart();
-			_movementMomentum -= (rand() % 2000 + 6000) / 1000.f;
+			_movementMomentum -= (rand() % 3000 + 8000) / 1000.f;
 			_life.show();
 			_mana.show();
 		}
 	});
 	
+	bind(6, [this](const sf::Event&, float)
+	{
+		_lightType++;
+		_lightType %= 2;
+		switch(_lightType)
+		{
+			case 0: 
+				light()->_emissionSprite.setTexture(_context->assets->loadTexture("data/background/Light_Alt.png"));
+				light()->_emissionSprite.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Light_Alt.png").getSize().x / 2u, _context->assets->loadTexture("data/background/Light_Alt.png").getSize().y - (_illuminati ? 71 : 0)));
+				break;
+			case 1: 
+				light()->_emissionSprite.setTexture(_context->assets->loadTexture("data/background/Light.png"));
+				light()->_emissionSprite.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Light.png").getSize().x / 2u, _context->assets->loadTexture("data/background/Light.png").getSize().y / 2u - (_illuminati ? 30 : 0)));
+				break;
+			default: 
+				break;
+		}
+	});
+	
 	bind(40, [this](const sf::Event&, float)
 	{
 		_particleSystem.enable(!_particleSystem.isEnabled());
@@ -122,7 +143,9 @@ Player::Player():
 	_bullets.reserve(10);
 	_bulletTimer.restart();
 	 
-	_durability = 0.25f; 
+	_durability = 0.4f;
+
+	light()->_emissionSprite.setColor(sf::Color::White);
 }
 
 void Player::setContext(Context* context)
@@ -133,6 +156,9 @@ void Player::setContext(Context* context)
 	_context->assets->loadTexture("data/triangle/Arc.png").setSmooth(true);
 	_life.setTexture(_context->assets->loadTexture("data/triangle/Arc.png"));
 	_mana.setTexture(_context->assets->loadTexture("data/triangle/Arc.png"));
+	_lightType = 0;
+	light()->_emissionSprite.setTexture(_context->assets->loadTexture("data/background/Light_Alt.png"));
+	light()->_emissionSprite.setOrigin(sf::Vector2f(_context->assets->loadTexture("data/background/Light_Alt.png").getSize().x / 2u, _context->assets->loadTexture("data/background/Light_Alt.png").getSize().y - (_illuminati ? 71 : 0)));
 }
 
 bool Player::isDead()
@@ -161,9 +187,14 @@ void Player::setTexture(sf::Texture& texture)
 	setPointCount(pointCount);
 }
 
-bool Player::checkCollision(Foreground& foreground)
+void Player::setIlluminati(bool illuminati)
 {
-	updateTransform(getTransform());
+	_illuminati = illuminati;
+}
+
+bool Player::checkCollision(Foreground& foreground, bool pixel)
+{
+	Collidable::updateTransform(getTransform());
 	int k = pixelPerfect(foreground);
 	if(k == -1)
 	{
@@ -177,14 +208,14 @@ bool Player::checkCollision(Foreground& foreground)
 	{
 		sf::Vector2f pos = _cmap[k];
 		sf::Vector2f center = sf::Vector2f(_image.getSize().x / 2.f, 100.f);
-		if(center.x + pos.x >= 0 && center.x + pos.x < _image.getSize().x and center.y + pos.y >= 0 && center.y + pos.y < _image.getSize().y)
+		if(center.x + pos.x >= 0 && center.x + pos.x < _image.getSize().x && center.y + pos.y >= 0 && center.y + pos.y < _image.getSize().y)
 			_image.setPixel(center.x + pos.x, center.y + pos.y, sf::Color(0, 0, 0, 0));
 		for(int i = -1; i <= 1; i++)
 			for(int j = -1; j <= 1; j++)
 			{
 				if(i == 0 && j == 0) 
 					continue;
-				if(pos.x + center.x + i < 0 || pos.y + center.y + j < 0 or pos.x + center.x + i > _image.getSize().x || pos.y + center.y + j > _image.getSize().y)
+				if(pos.x + center.x + i < 0 || pos.y + center.y + j < 0 || pos.x + center.x + i > _image.getSize().x || pos.y + center.y + j > _image.getSize().y)
 					continue;
 				if(_image.getPixel(pos.x + center.x + i, pos.y + center.y + j).a > 0)
 				{
@@ -199,7 +230,8 @@ bool Player::checkCollision(Foreground& foreground)
 		_cmap.erase(_cmap.begin() + k);
 		_cbanned.push_back(pos);
 		k = pixelPerfect(foreground);
-		if(i < 100.f) i += 0.1f;
+		if(i < 100.f) 
+			i += 0.1f;
 	}
 	if(i > _glass.getVolume())
 		_glass.setVolume(i);
@@ -408,6 +440,9 @@ void Player::update(sf::Time delta)
 		_dead = true;
 		_won = true;
 	}
+	
+	light()->_emissionSprite.setPosition(getPosition());
+	light()->_emissionSprite.setRotation(getRotation());
 }
 
 float Player::getHullLeft()

+ 7 - 2
src/Player.hpp

@@ -26,6 +26,7 @@
 #include "Context.hpp"
 #include "Particle.hpp"
 #include "Circle.hpp"
+#include "Lantern.hpp"
 
 /**
  * @class Player
@@ -36,7 +37,7 @@
  * This has to be moved to an Entity class or something
  * and leave the camera and input stuff to the Player class.
  */
-class Player: public Triangle, public InputTarget<int>, public Collidable
+class Player: public Triangle, public InputTarget<int>, public Collidable, public Lantern
 {
 	public:
 		Player();
@@ -47,7 +48,8 @@ class Player: public Triangle, public InputTarget<int>, public Collidable
 		 * @param foreground
 		 * @return Returns true if the target died. 
 		 */
-		bool checkCollision(Foreground& foreground);
+		
+		bool checkCollision(Foreground& foreground, bool pixel = true);
 		bool isDead();
 		bool hasWon();
 		Rect getBounds();
@@ -55,6 +57,7 @@ class Player: public Triangle, public InputTarget<int>, public Collidable
 		sf::Texture _innerTexture;
 		void setContext(Context* context);
 		float getHullLeft();
+		void setIlluminati(bool illuminati);
 
 	private:
 		void keyboardControls(sf::Time delta);
@@ -75,6 +78,8 @@ class Player: public Triangle, public InputTarget<int>, public Collidable
 		sf::Sound _deathSound;
 		ParticleSystem _particleSystem;
 		int _ammo;
+		bool _illuminati;
 		Circle _life;
 		Circle _mana;
+		int _lightType;
 };

+ 39 - 0
src/Star.cpp

@@ -0,0 +1,39 @@
+/**
+ *  Triangles
+ *  Copyright (C) 2016 POSITIVE MENTAL ATTITUDE
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, version 3 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cmath>
+#include "Star.hpp"
+
+Star::Star(const sf::Texture& texture, const sf::Texture& lightTexture, sf::Vector2f position): Lantern()
+{
+	light()->_emissionSprite.setPosition(position + sf::Vector2f(32.f, 32.f));
+	light()->_emissionSprite.setTexture(lightTexture);
+	light()->_emissionSprite.setOrigin(sf::Vector2f(lightTexture.getSize() / 2u));
+	setPosition(position + sf::Vector2f(32.f, 32.f));
+	setTexture(texture);
+	setOrigin(sf::Vector2f(texture.getSize() / 2u));
+}
+
+bool Star::gravity(sf::Vector2f position, sf::Time time)
+{
+	light()->_emissionSprite.rotate(time.asSeconds() * 60.f);
+	rotate(time.asSeconds() * 60.f);
+	sf::Vector2f delta = position - light()->_emissionSprite.getPosition();
+	if(delta.x > -1.f && delta.y > -1.f && delta.x < 1.f && delta.y < 1.f)
+		return 1.f;
+	return std::sqrt(delta.x * delta.x + delta.y * delta.y) <= 150;
+}

+ 29 - 0
src/Star.hpp

@@ -0,0 +1,29 @@
+/**
+ *  Triangles
+ *  Copyright (C) 2016 POSITIVE MENTAL ATTITUDE
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, version 3 of the License.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "Lantern.hpp"
+
+class Star: public sf::Sprite, public Lantern
+{
+	public:
+		Star() = delete;
+		Star(const sf::Texture& texture, const sf::Texture& lightTexture, sf::Vector2f position);
+		bool gravity(sf::Vector2f position, sf::Time time);
+};
+

+ 5 - 3
src/Triangles.cpp

@@ -263,11 +263,11 @@ int Triangles::run(unsigned count)
 	
 	if(_context.running)
 	{
-		Echo::out(Echo::Empty, "Triangles version -0.9.7");
+		Echo::out(Echo::Empty, "Triangles version -0.9.5");
 		Echo::out(Echo::Empty, "Copyright (C) 2016 POSITIVE MENTAL ATTITUDE");
 		Echo::out(Echo::Empty, "This program comes with ABSOLUTELY NO WARRANTY;");
 		Echo::out(Echo::Empty, "This is free software, and you are welcome to redistribute it");
-		Echo::out(Echo::Empty, "under certain conditions; see LICENSE.md");
+		Echo::out(Echo::Empty, "under certain conditions; see LICENSE file");
 		Echo::out(Echo::Info, "This is #", count, " Triangles run on this install.", count >= 666 ? " Thanks for being addicted!" : " I like cookies.");
 	}
 	
@@ -374,7 +374,7 @@ void Triangles::coreUpdate(sf::Time delta)
 void Triangles::loadingRender()
 {
 	_window.setActive(true);
-	while(!_current->status() and _context.running)
+	while(!_current->status() && _context.running)
 	{
 		_loadingTriangle.rotate(8.f);
 		coreThink();
@@ -390,7 +390,9 @@ void Triangles::coreRender()
 {
 	_window.clear();
 	_current->coreRender(_variables.shaders);
+	#ifdef DEBUG
 	_window.draw(_fpsRect);
 	_window.draw(_fps);
+	#endif
 	_window.render();
 }

+ 4 - 2
src/TrianglesWindow.cpp

@@ -26,7 +26,7 @@ TrianglesWindow::TrianglesWindow(const std::string& title, sf::Vector2u size):
 {
 	_context = nullptr;
 	_inputMap.map(0, Input(sf::Keyboard::R, Input::Type::Pressed));
-	bind(0, [this](const sf::Event&, float power)
+	bind(0, [this](const sf::Event&, float)
 	{
 		if(_size == sf::Vector2u(640u, 480u))
 			_size = sf::Vector2u(1366u, 768u);
@@ -35,6 +35,8 @@ TrianglesWindow::TrianglesWindow(const std::string& title, sf::Vector2u size):
 		close();
 		open();
 	});
+	
+	_textures.reserve(2000);
 }
 
 TrianglesWindow::~TrianglesWindow()
@@ -159,7 +161,7 @@ void TrianglesWindow::open()
 	if(_context->borderless)
 		_window.setPosition(sf::Vector2i(0, 0));
 	if(_context->vsync)
-		/*_window.setFramerateLimit(60);*/_window.setVerticalSyncEnabled(true);
+		_window.setVerticalSyncEnabled(true);
 	if(_context)
 		_context->needsUpdate = true;
 }

+ 1 - 0
src/TrianglesWindow.hpp

@@ -60,5 +60,6 @@ class TrianglesWindow: public InputTarget<int>
 		sf::Vector2u _size;
 		std::string _title;
 		bool _mouseLocked;
+		std::vector<sf::Texture> _textures;	
 };
 

+ 5 - 1
src/Utility.cpp

@@ -17,8 +17,12 @@
 
 #include <cstdio>
 #include "Utility.hpp"
-
+ 
+#ifdef DEBUG
 int Echo::_loglevel = 4;
+#else
+int Echo::_loglevel = 1;
+#endif
 
 bool Echo::printType(int order)
 {

+ 14 - 13
src/Wormhole.cpp

@@ -19,10 +19,11 @@
 #include "Utility.hpp"
 #include "Wormhole.hpp"
 
-Wormhole::Wormhole(): _light(std::make_shared<ltbl::LightPointEmission>())
+Wormhole::Wormhole(): Lantern()
 {
-	_light->_emissionSprite.setColor(sf::Color::White);
-	_light->_localCastCenter = sf::Vector2f(0.0f, 0.0f);
+	light()->_emissionSprite.setColor(sf::Color::White);
+	light()->_localCastCenter = sf::Vector2f(0.0f, 0.0f);
+	_sprite.setPosition(0, 0);
 }
 
 void Wormhole::load(const sf::Texture& texture1, const sf::Texture& texture2)
@@ -30,8 +31,8 @@ void Wormhole::load(const sf::Texture& texture1, const sf::Texture& texture2)
 	_sprite.setTexture(texture1);
 	_sprite.setOrigin(sf::Vector2f(texture1.getSize() / 2u));
 	
-	_light->_emissionSprite.setTexture(texture2);
-	_light->_emissionSprite.setOrigin(sf::Vector2f(texture2.getSize() / 2u));
+	light()->_emissionSprite.setTexture(texture2);
+	light()->_emissionSprite.setOrigin(sf::Vector2f(texture2.getSize() / 2u));
 }
 
 Wormhole::~Wormhole()
@@ -39,17 +40,22 @@ Wormhole::~Wormhole()
 	Echo::debug("Deleting a wormhole.");
 }
 
+sf::Vector2f Wormhole::getPosition()
+{
+	return _sprite.getPosition();
+}
+
 void Wormhole::update(sf::Time delta)
 {
 	float degree = delta.asSeconds() * 36.f;
 	_sprite.rotate(degree);
-	_light->_emissionSprite.rotate(degree);
+	light()->_emissionSprite.rotate(degree);
 }
 
 void Wormhole::setPosition(sf::Vector2f position)
 {
 	_sprite.setPosition(position);
-	_light->_emissionSprite.setPosition(position);
+	light()->_emissionSprite.setPosition(position);
 }
 
 void Wormhole::setPosition(float x, float y)
@@ -57,15 +63,10 @@ void Wormhole::setPosition(float x, float y)
 	setPosition(sf::Vector2f(x, y));
 }
 
-std::shared_ptr<ltbl::LightPointEmission>& Wormhole::light()
-{
-	return _light;
-}
-
 float Wormhole::gravity(sf::Vector2f position)
 {
 	sf::Vector2f delta = position - _sprite.getPosition();
-	if(delta.x < 1.f && delta.y < 1.f)
+	if(delta.x > -1.f && delta.y > -1.f && delta.x < 1.f && delta.y < 1.f)
 		return 1.f;
 	return std::sqrt(delta.x * delta.x + delta.y * delta.y);
 }

+ 2 - 5
src/Wormhole.hpp

@@ -18,8 +18,7 @@
 #pragma once
 
 #include <SFML/Graphics.hpp>
-#include <memory>
-#include "ltbl/lighting/LightPointEmission.h"
+#include "Lantern.hpp"
 
 /**
  * @class Wormhole
@@ -28,7 +27,7 @@
  * @file Wormhole.hpp
  * @brief A pretty independent class managing that wormhole.
  */
-class Wormhole: public sf::Drawable
+class Wormhole: public sf::Drawable, public Lantern
 {
 	public:
 		Wormhole();
@@ -38,13 +37,11 @@ class Wormhole: public sf::Drawable
 		void setPosition(sf::Vector2f position);
 		void setPosition(float x, float y);
 		sf::Vector2f getPosition();
-		std::shared_ptr<ltbl::LightPointEmission>& light();
 		float gravity(sf::Vector2f position);
 		sf::Vector2f direction(sf::Vector2f position);
 
 	private:
 		virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const;
 		sf::Sprite _sprite;
-		std::shared_ptr<ltbl::LightPointEmission> _light;
 };