From 21bbbbce86b9f41bb32c4e383f8e8af2732df65f Mon Sep 17 00:00:00 2001
From: KosmX <kosmx.mc@gmail.com>
Date: Thu, 13 May 2021 17:36:05 +0200
Subject: [PATCH] some explosives

---
 2d-game.vcxproj         |  4 ++++
 2d-game.vcxproj.filters | 12 ++++++++++
 CharacterEntity.cpp     |  1 -
 EMGun.cpp               | 16 +++++++++----
 EMGun.h                 |  3 ++-
 ExplosiveProjectile.cpp | 47 +++++++++++++++++++++++++++++++++++++
 ExplosiveProjectile.h   | 23 ++++++++++++++++++
 GlitchGun.cpp           | 52 +++++++++++++++++++++++++++++++++++++++++
 GlitchGun.h             | 33 ++++++++++++++++++++++++++
 PlayerEntity.cpp        |  9 ++++++-
 RangedWeapon.cpp        |  4 ++--
 SimpleSprite.h          |  2 +-
 TestGenerator.cpp       |  9 +++++--
 Weapon.h                |  5 ++++
 WeaponTextures.h        |  3 +++
 mainGame.cpp            |  2 +-
 16 files changed, 211 insertions(+), 14 deletions(-)
 create mode 100644 ExplosiveProjectile.cpp
 create mode 100644 ExplosiveProjectile.h
 create mode 100644 GlitchGun.cpp
 create mode 100644 GlitchGun.h

diff --git a/2d-game.vcxproj b/2d-game.vcxproj
index f262748..36919b5 100644
--- a/2d-game.vcxproj
+++ b/2d-game.vcxproj
@@ -149,8 +149,10 @@
     <ClCompile Include="DungeonGenerator.cpp" />
     <ClCompile Include="EMGun.cpp" />
     <ClCompile Include="Entity.cpp" />
+    <ClCompile Include="ExplosiveProjectile.cpp" />
     <ClCompile Include="game.cpp" />
     <ClCompile Include="GameException.cpp" />
+    <ClCompile Include="GlitchGun.cpp" />
     <ClCompile Include="LazySprite.cpp" />
     <ClCompile Include="LivingEntity.cpp" />
     <ClCompile Include="mainGame.cpp" />
@@ -174,7 +176,9 @@
     <ClInclude Include="DungeonGenerator.h" />
     <ClInclude Include="DynamicArray.hpp" />
     <ClInclude Include="EMGun.h" />
+    <ClInclude Include="ExplosiveProjectile.h" />
     <ClInclude Include="GameException.h" />
+    <ClInclude Include="GlitchGun.h" />
     <ClInclude Include="LivingEntity.h" />
     <ClInclude Include="mainGame.h" />
     <ClInclude Include="MeleeWeapon.h" />
diff --git a/2d-game.vcxproj.filters b/2d-game.vcxproj.filters
index 4b810a8..50b5f91 100644
--- a/2d-game.vcxproj.filters
+++ b/2d-game.vcxproj.filters
@@ -107,6 +107,12 @@
     <ClCompile Include="RangedWeapon.cpp">
       <Filter>Source Files\gameObj\wepons</Filter>
     </ClCompile>
+    <ClCompile Include="GlitchGun.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="ExplosiveProjectile.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="interfaces.h">
@@ -196,6 +202,12 @@
     <ClInclude Include="EMGun.h">
       <Filter>Header Files\gameObj\wepons</Filter>
     </ClInclude>
+    <ClInclude Include="GlitchGun.h">
+      <Filter>Header Files\gameObj\wepons</Filter>
+    </ClInclude>
+    <ClInclude Include="ExplosiveProjectile.h">
+      <Filter>Header Files\gameObj\entities</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="README.md">
diff --git a/CharacterEntity.cpp b/CharacterEntity.cpp
index 08f9e97..842765a 100644
--- a/CharacterEntity.cpp
+++ b/CharacterEntity.cpp
@@ -17,7 +17,6 @@ namespace entities {
 	{
 		LivingEntity::tick(client, deltaT, shared_this);
 		if(this->getWeapon()){
-			this->getWeapon()->update(deltaT);
 			this->getWeapon()->setPos(this->getPos() + (this->speed != olc::vf2d(0, 0) ? this->speed.norm()/2 : olc::vf2d(0, 0)));
 		}
 	}
diff --git a/EMGun.cpp b/EMGun.cpp
index a2f3803..2f7367d 100644
--- a/EMGun.cpp
+++ b/EMGun.cpp
@@ -1,13 +1,19 @@
 #include "EMGun.h"
-
+#include <random>
 
 namespace weapons {
-	weapons::EMGun::EMGun(render::ITexture& texture, float cooldownTime, int damage, float projectileSpeed, const std::string& name, const olc::vf2d& pos)
-		: Pistol(texture, cooldownTime, damage, projectileSpeed, name, pos) {}
+	EMGun::EMGun(render::ITexture& texture, float cooldownTime, int damage, float projectileSpeed, const std::string& name, const olc::vf2d& pos, float energyRegen)
+		: Pistol(texture, cooldownTime, damage, projectileSpeed, name, pos), energyRegenRate(energyRegen) {}
+	
 	bool EMGun::use(std::shared_ptr<Entity> user, const olc::vf2d& direction)
 	{
 		if (energy < 10) return false;
-		if(Pistol::use(user, direction)){
+
+		float r1 = (rand() % 1024 - 512) / 512.0;
+		float r2 = (rand() % 1024 - 512) / 512.0;
+		olc::vf2d randv(r1, r2);
+		randv = randv.norm()*direction.mag();
+		if(Pistol::use(user, direction + randv/8)){
 			energy -= 10;
 			return true;
 		}
@@ -19,7 +25,7 @@ namespace weapons {
 	}
 	bool EMGun::update(float dTick)
 	{
-		energy = std::min(energy + 6 * dTick, 128.f);
+		energy = std::min(energy + energyRegenRate * dTick, 128.f);
 		return Pistol::update(dTick) && energy > 10;
 	}
 }
diff --git a/EMGun.h b/EMGun.h
index fae201d..7321848 100644
--- a/EMGun.h
+++ b/EMGun.h
@@ -9,8 +9,9 @@ namespace weapons
 	{
 	private:
 		float energy = 128;
+		float energyRegenRate;
 	public:
-		EMGun(render::ITexture& texture, float cooldownTime, int damage, float projectileSpeed = 10, const std::string& name = "RangedWeapon", const olc::vf2d& pos = { 0, 0 });
+		EMGun(render::ITexture& texture, float cooldownTime, int damage, float projectileSpeed = 10, const std::string& name = "RangedWeapon", const olc::vf2d& pos = { 0, 0 }, float energyRegen = 12);
 
 		bool use(std::shared_ptr<Entity> user, const olc::vf2d& direction) override;
 
diff --git a/ExplosiveProjectile.cpp b/ExplosiveProjectile.cpp
new file mode 100644
index 0000000..eeb7f2e
--- /dev/null
+++ b/ExplosiveProjectile.cpp
@@ -0,0 +1,47 @@
+#include "ExplosiveProjectile.h"
+
+#include "mainGame.h"
+
+
+const float explosionRadius = 2.5;
+
+namespace entities
+{
+	bool ExplosiveProjectile::onCollide(const olc::vf2d& collisionVector, std::shared_ptr<Entity>& who)
+	{
+		this->state = true;
+		for (auto& entity : GameClient::getInstance().getEntities()) {
+			if (entity != user && (entity->getPos() - this->getPos()).mag() < explosionRadius)
+				entity->damage(this->damageValue, *user);
+		}
+		return true; //it exploded
+	}
+	ExplosiveProjectile::ExplosiveProjectile(std::shared_ptr<Entity>& user, const olc::vf2d& pos0, render::ITexture& texture, int damage)
+		: ProjectileEntity(user, pos0, texture) {}
+	
+	void ExplosiveProjectile::tick(GameClient& client, float deltaT, std::shared_ptr<Entity>& shared_this)
+	{
+		if(state){
+			stateTime += deltaT;
+		}
+		else{
+			ProjectileEntity::tick(client, deltaT, shared_this);
+		}
+	}
+	
+	bool ExplosiveProjectile::canBeRemoved() const
+	{
+		return stateTime > 1;
+	}
+	void ExplosiveProjectile::render(olc::TransformedView& scene)
+	{
+		if(state){
+			explosion.render(scene, *this);
+		}
+		else{
+			ProjectileEntity::render(scene);
+		}
+	}
+
+	render::SimpleSprite ExplosiveProjectile::explosion("Objects/Effect0.png", { 0, 0 }, { 48, 48 });
+}
diff --git a/ExplosiveProjectile.h b/ExplosiveProjectile.h
new file mode 100644
index 0000000..2cc73eb
--- /dev/null
+++ b/ExplosiveProjectile.h
@@ -0,0 +1,23 @@
+#pragma once
+#include "ProjectileEntity.h"
+
+namespace entities {
+	class ExplosiveProjectile :
+		public ProjectileEntity
+	{
+	private:
+		float stateTime = 0;
+		bool state = false;
+		static render::SimpleSprite explosion;
+	protected:
+		bool onCollide(const olc::vf2d& collisionVector, std::shared_ptr<Entity>& who) override;
+	public:
+		ExplosiveProjectile(std::shared_ptr<Entity>& user, const olc::vf2d& pos0, render::ITexture& texture, int damage = 40);
+
+		void tick(GameClient& client, float deltaT, std::shared_ptr<Entity>& shared_this) override;
+
+		bool canBeRemoved() const override;
+
+		void render(olc::TransformedView& scene) override;
+	};
+}
diff --git a/GlitchGun.cpp b/GlitchGun.cpp
new file mode 100644
index 0000000..fe8d3e2
--- /dev/null
+++ b/GlitchGun.cpp
@@ -0,0 +1,52 @@
+#include "GlitchGun.h"
+
+#include "ExplosiveProjectile.h"
+#include "mainGame.h"
+
+using namespace std;
+using namespace entities;
+using namespace olc;
+
+namespace weapons {
+
+	weapons::GlitchGun::GlitchGun(float cooldownTime, int damage, float projectileSpeed, const std::string& name, const olc::vf2d& pos, float energyRegen)
+		: EMGun(GlitchGun::GlitchTexture, cooldownTime, damage, projectileSpeed, name, pos, energyRegen) {}
+
+	void weapons::GlitchGun::spawnProjectile(std::shared_ptr<Entity>& user, const olc::vf2d& pos, const olc::vf2d& v0, int damage)
+	{
+		if (rand() % 8 == 0) {
+			shared_ptr<ExplosiveProjectile> projectile(new ExplosiveProjectile(user, pos, ProjectileEntity::projectile, damage));
+			projectile->setVelocity(v0);
+			GameClient::getInstance() += projectile;
+		}
+		else {
+			EMGun::spawnProjectile(user, pos, v0, damage);
+		}
+	}
+
+	bool weapons::GlitchGun::update(float dTick)
+	{
+		timeState += dTick;
+		if (timeState > 2) {
+			timeState -= 2;
+		}
+		return EMGun::update(dTick);
+	}
+
+	weapons::GlitchTexture::GlitchTexture(const std::string& name)
+		: sprite(name) {}
+
+	void weapons::GlitchTexture::render(olc::TransformedView& scene, Entity& entity)
+	{
+		GlitchGun& gun = dynamic_cast<GlitchGun&>(entity);
+		vi2d pos = { 0, 0 };
+		if (gun.timeState > 1) {
+			pos += {0, 16};
+		}
+		if (gun.timeState > 0.5f && gun.timeState < 1 || gun.timeState > 1.5) {
+			pos += {16, 0};
+		}
+		sprite.renderCentered(scene, gun.getPos(), pos, { 16, 16 });
+	}
+	GlitchTexture GlitchGun::GlitchTexture;
+}
\ No newline at end of file
diff --git a/GlitchGun.h b/GlitchGun.h
new file mode 100644
index 0000000..59d9449
--- /dev/null
+++ b/GlitchGun.h
@@ -0,0 +1,33 @@
+#pragma once
+#include "EMGun.h"
+
+namespace weapons
+{
+	
+	class GlitchTexture : public render::ITexture
+	{
+	private:
+		render::LazySprite sprite;
+	public:
+		GlitchTexture(const std::string& name = "FromMacskusz111/bug.png");
+		void render(olc::TransformedView& scene, Entity& entity) override;
+	};
+
+
+	
+	class GlitchGun :
+		public EMGun
+	{
+		friend GlitchTexture;
+	private:
+		float timeState = 0;
+		static GlitchTexture GlitchTexture;
+		
+	public:
+		GlitchGun(float cooldownTime, int damage, float projectileSpeed = 10, const std::string& name = "RangedWeapon", const olc::vf2d& pos = { 0, 0 }, float energyRegen = 10);
+		void spawnProjectile(std::shared_ptr<Entity>& user, const olc::vf2d& pos, const olc::vf2d& v0, int damage) override;
+		bool update(float dTick) override;
+	};
+
+
+}
diff --git a/PlayerEntity.cpp b/PlayerEntity.cpp
index b2ea294..aadb17a 100644
--- a/PlayerEntity.cpp
+++ b/PlayerEntity.cpp
@@ -5,6 +5,8 @@
 
 using namespace olc;
 
+const float maxWeaponPickupRange = 1;
+
 namespace entities {
 	std::shared_ptr<weapons::Weapon> PlayerEntity::getWeapon()
 	{
@@ -28,9 +30,14 @@ namespace entities {
 		}
 
 		this->weaponToPickUp = nullptr;
+		for(int i = 0; i < maxWeapons; i++){
+			if(weapons[i]){
+				weapons[i]->update(deltaT);
+			}
+		}
 		
 		for(auto& entity : client.getEntities()){
-			if(std::dynamic_pointer_cast<weapons::Weapon>(entity)){
+			if(std::dynamic_pointer_cast<weapons::Weapon>(entity) && (entity->getPos() - getPos()).mag() < maxWeaponPickupRange){
 				weaponToPickUp = std::dynamic_pointer_cast<weapons::Weapon>(entity);
 				break;
 			}
diff --git a/RangedWeapon.cpp b/RangedWeapon.cpp
index c230e9c..d04ec5b 100644
--- a/RangedWeapon.cpp
+++ b/RangedWeapon.cpp
@@ -17,6 +17,6 @@ namespace weapons {
 		return true;
 	}
 
-	const Pistol RangedWeapon::pistol(textures::rifle, .3f, 10, 10, "Pistol");
-	const EMGun RangedWeapon::emgun(textures::rifle, .08f, 14, 10, "Pistol");
+	const Pistol RangedWeapon::pistol(textures::pistol, .3f, 10, 10, "Pistol");
+	const EMGun RangedWeapon::emgun(textures::minigun, .08f, 14, 10, "Pistol");
 }
diff --git a/SimpleSprite.h b/SimpleSprite.h
index 4d50d4e..9cc301a 100644
--- a/SimpleSprite.h
+++ b/SimpleSprite.h
@@ -13,7 +13,7 @@ namespace render {
 		const olc::vf2d uv, size;
 	
 	public:
-		SimpleSprite(const std::string& name, const olc::vi2d& pos, const olc::vf2d& size = {16, 16});
+		SimpleSprite(const std::string& name, const olc::vi2d& pos = { 0, 0 }, const olc::vf2d& size = { 16, 16 });
 
 		void render(olc::TransformedView& scene, entities::Entity& entity) override;
 	};
diff --git a/TestGenerator.cpp b/TestGenerator.cpp
index 6fbbf44..cba1b5d 100644
--- a/TestGenerator.cpp
+++ b/TestGenerator.cpp
@@ -7,6 +7,7 @@
 #include "DummyEntity.h"
 #include "TypicalMeleeWeapon.h"
 #include "EMGun.h"
+#include "GlitchGun.h"
 
 using namespace entities;
 using namespace std;
@@ -22,19 +23,23 @@ shared_ptr<PlayerEntity> TestGenerator::generate(GameClient& client)
 	client += make_shared<WallEntity>(*new WallEntity(olc::vf2d(-1, -1)));
 	client += make_shared<WallEntity>(*asd);
 
-	client += make_shared<CharacterEntity>(*new DummyEntity(olc::vf2d(5, 6), render::CharacterTexture::MageTexture));
+	client += make_shared<DummyEntity>(*new DummyEntity(olc::vf2d(5, 6), render::CharacterTexture::MageTexture));
 
 	auto weapon = make_shared<weapons::TypicalMeleeWeapon>(*new weapons::TypicalMeleeWeapon(weapons::TypicalMeleeWeapon::sword));
 	auto weapon1 = make_shared<weapons::Pistol>(*new weapons::Pistol(weapons::RangedWeapon::pistol));
-	auto weapon2 = make_shared<weapons::Pistol>(*new weapons::EMGun(weapons::RangedWeapon::emgun));
+	auto weapon2 = make_shared<weapons::EMGun>(*new weapons::EMGun(weapons::RangedWeapon::emgun)); //bee careful with make_shared?!
+
+	shared_ptr<weapons::Weapon> gg(new weapons::GlitchGun(0.3f, 40, 10, "GItc|_|Un"));
 
 	weapon->setPos({ -3, -4 });
 	weapon1->setPos({ -4, -4 });
 	weapon2->setPos({ -4, -5 });
+	gg->setPos({ -5, -5 });
 	
 	client += weapon;
 	client += weapon2;
 	client += weapon1;
+	client += gg;
 	shared_ptr<PlayerEntity> player(new PlayerEntity({ 0, -4 }, render::CharacterTexture::EngineerTexture));
 
 
diff --git a/Weapon.h b/Weapon.h
index 32315b8..8b4fee9 100644
--- a/Weapon.h
+++ b/Weapon.h
@@ -30,6 +30,11 @@ namespace weapons {
     	 */
         virtual bool use(std::shared_ptr<Entity> user, const olc::vf2d& direction) = 0;
 
+    	void tick(GameClient& client, float deltaT, std::shared_ptr<Entity>& shared_this) override
+    	{
+            update(deltaT); //weapons on the ground can charge...
+    	}
+    	
         virtual bool update(float dTick);
     	
     	/**
diff --git a/WeaponTextures.h b/WeaponTextures.h
index b0f8c3b..4a03740 100644
--- a/WeaponTextures.h
+++ b/WeaponTextures.h
@@ -16,5 +16,8 @@ namespace weapons
 		inline render::SimpleSprite crystalBow("Items/Ammo.png", { 48, 16 });
 		inline render::SimpleSprite rifle("Items/Ammo.png", { 16, 64 });
 		inline render::SimpleSprite photoMachine("Items/Light.png", { 16 * 6, 0 });//flash
+		inline render::SimpleSprite pistol("FromMacskusz111/pistol.png");
+		inline render::SimpleSprite minigun("FromMacskusz111/gun1.png");
+		inline render::SimpleSprite glitchGun("FromMacskusz111/bug.png");
 	}
 }
diff --git a/mainGame.cpp b/mainGame.cpp
index 7a1985c..4304572 100644
--- a/mainGame.cpp
+++ b/mainGame.cpp
@@ -32,7 +32,7 @@ DynamicArray<std::shared_ptr<Entity>>& GameClient::getEntities()
 
 void GameClient::updateWorldOffset(float dTick)
 {
-	vf2d delta = scene.GetWorldOffset() + scene.GetWorldTL()/4;
+	vf2d delta = scene.GetWorldOffset() + scene.GetWorldVisibleArea()/4;
 	scene.MoveWorldOffset((player->getPos() - delta) * dTick * screenMoveScale);
 }
 
-- 
GitLab