From ac1023b57c8b9eff235cdad6f61024af8e27db7f Mon Sep 17 00:00:00 2001
From: KosmX <kosmx.mc@gmail.com>
Date: Thu, 13 May 2021 15:33:33 +0200
Subject: [PATCH] ranged weapons

---
 2d-game.vcxproj         |   8 +++++
 2d-game.vcxproj.filters |  24 +++++++++++++++
 DawnLike/status.png     | Bin 0 -> 619 bytes
 DawnLike/status.xcf     | Bin 0 -> 813 bytes
 EMGun.cpp               |  27 ++++++++++++++++
 EMGun.h                 |  21 +++++++++++++
 Pistol.cpp              |  21 +++++++++++++
 Pistol.h                |  14 +++++++++
 ProjectileEntity.cpp    |  66 ++++++++++++++++++++++++++++++++++++++++
 ProjectileEntity.h      |  39 ++++++++++++++++++++++++
 RangedWeapon.cpp        |  22 ++++++++++++++
 RangedWeapon.h          |  29 ++++++++++++++++++
 TestGenerator.cpp       |   7 ++++-
 Weapon.cpp              |  10 ++++++
 Weapon.h                |   3 ++
 game.cpp                |   2 +-
 16 files changed, 291 insertions(+), 2 deletions(-)
 create mode 100644 DawnLike/status.png
 create mode 100644 DawnLike/status.xcf
 create mode 100644 EMGun.cpp
 create mode 100644 EMGun.h
 create mode 100644 Pistol.cpp
 create mode 100644 Pistol.h
 create mode 100644 ProjectileEntity.cpp
 create mode 100644 ProjectileEntity.h
 create mode 100644 RangedWeapon.cpp
 create mode 100644 RangedWeapon.h

diff --git a/2d-game.vcxproj b/2d-game.vcxproj
index a7aae7e..f262748 100644
--- a/2d-game.vcxproj
+++ b/2d-game.vcxproj
@@ -147,6 +147,7 @@
     <ClCompile Include="CharacterTexture.cpp" />
     <ClCompile Include="DummyEntity.cpp" />
     <ClCompile Include="DungeonGenerator.cpp" />
+    <ClCompile Include="EMGun.cpp" />
     <ClCompile Include="Entity.cpp" />
     <ClCompile Include="game.cpp" />
     <ClCompile Include="GameException.cpp" />
@@ -154,7 +155,10 @@
     <ClCompile Include="LivingEntity.cpp" />
     <ClCompile Include="mainGame.cpp" />
     <ClCompile Include="MeleeWeapon.cpp" />
+    <ClCompile Include="Pistol.cpp" />
     <ClCompile Include="PlayerEntity.cpp" />
+    <ClCompile Include="ProjectileEntity.cpp" />
+    <ClCompile Include="RangedWeapon.cpp" />
     <ClCompile Include="ResourceManager.cpp" />
     <ClCompile Include="SimpleSprite.cpp" />
     <ClCompile Include="TestGenerator.cpp" />
@@ -169,6 +173,7 @@
     <ClInclude Include="DummyEntity.h" />
     <ClInclude Include="DungeonGenerator.h" />
     <ClInclude Include="DynamicArray.hpp" />
+    <ClInclude Include="EMGun.h" />
     <ClInclude Include="GameException.h" />
     <ClInclude Include="LivingEntity.h" />
     <ClInclude Include="mainGame.h" />
@@ -180,7 +185,10 @@
     <ClInclude Include="LazySprite.h" />
     <ClInclude Include="olcPGEX_TransformedView.h" />
     <ClInclude Include="olcPixelGameEngine.h" />
+    <ClInclude Include="Pistol.h" />
     <ClInclude Include="PlayerEntity.h" />
+    <ClInclude Include="ProjectileEntity.h" />
+    <ClInclude Include="RangedWeapon.h" />
     <ClInclude Include="ResourceManager.h" />
     <ClInclude Include="SimpleSprite.h" />
     <ClInclude Include="TestGenerator.h" />
diff --git a/2d-game.vcxproj.filters b/2d-game.vcxproj.filters
index 7c42959..4b810a8 100644
--- a/2d-game.vcxproj.filters
+++ b/2d-game.vcxproj.filters
@@ -95,6 +95,18 @@
     <ClCompile Include="CharacterEntity.cpp">
       <Filter>Source Files\gameObj\entities</Filter>
     </ClCompile>
+    <ClCompile Include="ProjectileEntity.cpp">
+      <Filter>Source Files\gameObj\entities</Filter>
+    </ClCompile>
+    <ClCompile Include="EMGun.cpp">
+      <Filter>Source Files\gameObj\wepons</Filter>
+    </ClCompile>
+    <ClCompile Include="Pistol.cpp">
+      <Filter>Source Files\gameObj\wepons</Filter>
+    </ClCompile>
+    <ClCompile Include="RangedWeapon.cpp">
+      <Filter>Source Files\gameObj\wepons</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="interfaces.h">
@@ -172,6 +184,18 @@
     <ClInclude Include="CharacterEntity.h">
       <Filter>Header Files\gameObj\entities</Filter>
     </ClInclude>
+    <ClInclude Include="ProjectileEntity.h">
+      <Filter>Header Files\gameObj\entities</Filter>
+    </ClInclude>
+    <ClInclude Include="RangedWeapon.h">
+      <Filter>Header Files\gameObj\wepons</Filter>
+    </ClInclude>
+    <ClInclude Include="Pistol.h">
+      <Filter>Header Files\gameObj\wepons</Filter>
+    </ClInclude>
+    <ClInclude Include="EMGun.h">
+      <Filter>Header Files\gameObj\wepons</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="README.md">
diff --git a/DawnLike/status.png b/DawnLike/status.png
new file mode 100644
index 0000000000000000000000000000000000000000..dfaf106ce45ed31dc11b641ccef13b4bf42588db
GIT binary patch
literal 619
zcmeAS@N?(olHy`uVBq!ia0y~yU}#`qU{K&-V_;yorBtBGz`)p=>FgZf>FlgfP?VpR
znUl)EpfRy_qOHea2Z^@(%cga0v50UyqUc<@NkQw8MyO6x>!q-as|TN4vd_3QVaW~)
zu63;J^<t~}^v><F+QHTIfWKq*?8%F|r~HTw$`E`kd)#)<_r3b%_Zgiwp9<NW&J<vJ
z+C%+OlHPtTws=8@8EFE|LdIWH(hRxJe=OyfzyChT=Jf7&=LN&K)R=3OKFVC??XGC9
zNV|N=^1ZNoL}XCM`Of3KyA(buUr(KW-(tFqSVh{A6U&}=Dj!K&+5J>6E!A0do?4&Q
zDz~3b=Tcigi=}UkN`G7ZNxY5gmRH;BEp8JI2u<>EZ0WJmT5-s!r>s{*IMb@X`bWEL
zeOHXpPOXF|5e~dsD#!W%vG1?W7F(`%cS(Q@$DSMCj%x_qVU6Ow{m*XO+iRQ;>e<$9
z>DzyeCC%P5zhuh`!3+C&V`9opD*1QZVQiaMa&m&qNq=t*vBvMlzn0k;6mWl8yR$ZX
z{^Ku<CxX^b%Wr6QPFUk|^R?XjcW>X_-f#N$-(Lm=yP`I~n&-b67#P@+yxm<GbQu0K
zFgU;RozB3(z**oCS<Jworwqc36-({Q7#JAXOFVsD*`KoV@^T3ui}ST+U|^6eag8W(
z&d<$F%`0JWE=o--Nlj5G&n(GMaQE~L2yf&QXJBA(@^o<wskrs_mZKnpf&i0)N&nw&
zNrvi*-GUNr;;TImM`-WmGT6zmT#Nw@9%TF8zLNPRIhuumfx+My^L{yA$&HU&wt^IR
My85}Sb4q9e0GC|zod5s;

literal 0
HcmV?d00001

diff --git a/DawnLike/status.xcf b/DawnLike/status.xcf
new file mode 100644
index 0000000000000000000000000000000000000000..6331d790696f98191f29737a1a42805b36ecd168
GIT binary patch
literal 813
zcmYe#%q>u;NKR8IGcYt{U|?WqU|?WS05KRC7^X2WFbFa*FfcMQFfa%+Ffed9Ph(&J
zVFm^U5e5bZ76t|eRt5$JF(@0PPLzRx;WGmR124#E-Q@h-+|;}hkbxjcA?Kph#FEq$
zh4Rdj3<Y;j-vE$|09a{eZen_>ZhBE>3P=p3dW}YLNo7u|LUDdhW{M`4Mp}AueolUo
zf(Dq<ElN*HR4@QTLrqOCjU+76h6-Q^lCCH&NKDSmOII*7(B#snMBza>x}|xUB?_5&
z$r-7|np_$c`DtmzsU-?v^+;?86IC(D%}AIr3yA|`!on8hH*TlI<m~jK{L(zIcbTAS
z*q|Z#pMilv5yZ9!X<}gD0I@+)!N9=431x${C?T<Bkl0*EY*2K9VhW_58%dl8iOq||
z<_E<zNHG+%L*+o`t3ufzDHRa=|Ns9Ww<;sCVJQRVCy-hO1_q{5C<8=+e1+sLrkNl?
z1_ox3pCL??q{y@rBFOX|LNhSf|F>tb*Rf})XJ`0t&rr{B;D0?k1A{$-{bvxaXF0~e
o^xuYo>3==rcZe)2I|Ji?TLwn32m#&f3=lo+4j}75gaC*E0C<RoeE<Le

literal 0
HcmV?d00001

diff --git a/EMGun.cpp b/EMGun.cpp
new file mode 100644
index 0000000..1bc55c4
--- /dev/null
+++ b/EMGun.cpp
@@ -0,0 +1,27 @@
+#include "EMGun.h"
+
+
+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) {}
+	bool EMGun::use(std::shared_ptr<Entity> user, const olc::vf2d& direction)
+	{
+		if (cooldown != 0) return false;
+		if (energy < 10) return false;
+		cooldown = cooldownTime;
+		energy -= 10;
+
+		this->spawnProjectile(user, this->pos, direction.norm() * projectileSpeed, this->baseDamage);
+
+		return true;
+	}
+	float EMGun::getSecondaryBar()
+	{
+		return energy / 128;
+	}
+	bool EMGun::update(float dTick)
+	{
+		energy = std::min(energy + 6 * dTick, 128.f);
+		return Pistol::update(dTick) && energy > 10;
+	}
+}
diff --git a/EMGun.h b/EMGun.h
new file mode 100644
index 0000000..fae201d
--- /dev/null
+++ b/EMGun.h
@@ -0,0 +1,21 @@
+#pragma once
+#include "Pistol.h"
+
+namespace weapons
+{
+
+
+	class EMGun : public Pistol
+	{
+	private:
+		float energy = 128;
+	public:
+		EMGun(render::ITexture& texture, float cooldownTime, int damage, float projectileSpeed = 10, const std::string& name = "RangedWeapon", const olc::vf2d& pos = { 0, 0 });
+
+		bool use(std::shared_ptr<Entity> user, const olc::vf2d& direction) override;
+
+		float getSecondaryBar() override;
+
+		bool update(float dTick) override;
+	};
+}
diff --git a/Pistol.cpp b/Pistol.cpp
new file mode 100644
index 0000000..a35667f
--- /dev/null
+++ b/Pistol.cpp
@@ -0,0 +1,21 @@
+#include "Pistol.h"
+
+#include "mainGame.h"
+#include "ProjectileEntity.h"
+
+using namespace std;
+using namespace olc;
+
+namespace weapons {
+
+	Pistol::Pistol(render::ITexture& texture, float cooldownTime, int damage, float projectileSpeed, const std::string& name, const olc::vf2d& pos)
+		: RangedWeapon(texture, cooldownTime, damage, projectileSpeed, name, pos) {}
+
+	
+	void Pistol::spawnProjectile(std::shared_ptr<Entity>& user, const olc::vf2d& pos, const olc::vf2d& v0, int damage)
+	{
+		shared_ptr<ProjectileEntity> projectile(new ProjectileEntity(user, pos, ProjectileEntity::projectile, damage));
+		projectile->setVelocity(v0);
+		GameClient::getInstance() += projectile;
+	}
+}
diff --git a/Pistol.h b/Pistol.h
new file mode 100644
index 0000000..31ad987
--- /dev/null
+++ b/Pistol.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "RangedWeapon.h"
+
+namespace weapons
+{
+	class Pistol :
+		public RangedWeapon
+	{
+	public:
+		void spawnProjectile(std::shared_ptr<Entity>& user, const olc::vf2d& pos, const olc::vf2d& v0, int damage) override;
+		Pistol(render::ITexture& texture, float cooldownTime, int damage, float projectileSpeed = 10, const std::string& name = "RangedWeapon", const olc::vf2d& pos = { 0, 0 });
+	};
+}
diff --git a/ProjectileEntity.cpp b/ProjectileEntity.cpp
new file mode 100644
index 0000000..329a78d
--- /dev/null
+++ b/ProjectileEntity.cpp
@@ -0,0 +1,66 @@
+#include "ProjectileEntity.h"
+
+#include "LivingEntity.h"
+#include "mainGame.h"
+
+namespace entities {
+	render::ITexture& ProjectileEntity::getTexture()
+	{
+		return texture;
+	}
+	int ProjectileEntity::getDamage()
+	{
+		return damageValue;
+	}
+	void ProjectileEntity::bounce(const olc::vf2d& collision)
+	{
+		this->pos += collision; //first resolve the collision
+		if (collision.x) {
+			this->velocity.x *= -1;
+		}
+		if (collision.y) {
+			velocity.y *= -1;
+		}
+	}
+	bool entities::ProjectileEntity::onCollide(const olc::vf2d& collisionVector, std::shared_ptr<Entity>& who)
+	{
+		if (std::dynamic_pointer_cast<ProjectileEntity>(who) == nullptr && who != this->user && collisionVector != olc::vf2d(0, 0)) {
+			who->damage(this->getDamage(), *this->user);
+			this->is_alive = false;
+			return true;
+		}
+		return false;
+	}
+	olc::vf2d ProjectileEntity::getHitBoxSize() const
+	{
+		return olc::vf2d(0.2, 0.2);
+	}
+	ProjectileEntity::ProjectileEntity(std::shared_ptr<Entity>& user, const olc::vf2d& pos0, render::ITexture& texture, int damage)
+		: Entity(pos0), user(user), texture(texture), damageValue(damage) {}
+	
+	void ProjectileEntity::tick(GameClient& client, float deltaT, std::shared_ptr<Entity>& shared_this)
+	{
+		this->pos += this->velocity * deltaT;
+		for(auto& entity : client.getEntities()){
+			if(entity != this->user && std::dynamic_pointer_cast<ProjectileEntity>(entity) == nullptr){ //we ignore the user and other projectiles
+				olc::vf2d collision = getCollision(*entity);
+				if(collision != olc::vf2d(0, 0)){
+					if(this->onCollide(collision, entity)){
+						this->is_alive = false;
+						return;
+					}
+				}
+			}
+		}
+	}
+	void ProjectileEntity::setVelocity(const olc::vf2d& v)
+	{
+		this->velocity = v;
+	}
+	bool ProjectileEntity::damage(int damage, Entity& attacker)
+	{
+		return false;
+	}
+
+	render::SimpleSprite ProjectileEntity::projectile("status.png", { 0, 16 });
+}
diff --git a/ProjectileEntity.h b/ProjectileEntity.h
new file mode 100644
index 0000000..9b6658c
--- /dev/null
+++ b/ProjectileEntity.h
@@ -0,0 +1,39 @@
+#pragma once
+#include "Entity.h"
+#include "SimpleSprite.h"
+
+namespace entities {
+    class ProjectileEntity :
+        public Entity
+    {
+    public:
+        static render::SimpleSprite projectile;
+    private:
+        render::ITexture& texture;
+    protected:
+        olc::vf2d velocity;
+        std::shared_ptr<Entity> user;
+    	render::ITexture& getTexture() override;
+
+        int damageValue;
+        virtual int getDamage();
+        virtual void bounce(const olc::vf2d& collision);
+		/**
+		 * Determines, what will the projectile do, if it hit something.
+		 * @param collisionVector the collision vector
+		 * @param who who is the affected entity
+		 * @return is the projectile destroyed.
+		 */
+        virtual bool onCollide(const olc::vf2d& collisionVector, std::shared_ptr<Entity>& who);
+
+		olc::vf2d getHitBoxSize() const override;
+		
+    public:
+        ProjectileEntity(std::shared_ptr<Entity>& user, const olc::vf2d& pos0, render::ITexture& texture, int damage = 20);
+
+    	void tick(GameClient& client, float deltaT, std::shared_ptr<Entity>& shared_this) override;
+
+        virtual void setVelocity(const olc::vf2d& v);
+    	bool damage(int damage, Entity& attacker) override;
+    };
+}
diff --git a/RangedWeapon.cpp b/RangedWeapon.cpp
new file mode 100644
index 0000000..c230e9c
--- /dev/null
+++ b/RangedWeapon.cpp
@@ -0,0 +1,22 @@
+#include "RangedWeapon.h"
+#include "Pistol.h"
+#include "WeaponTextures.h"
+#include "EMGun.h"
+
+namespace weapons {
+	RangedWeapon::RangedWeapon(render::ITexture& texture, float cooldownTime, int damage, float projectileSpeed, const std::string& name, const olc::vf2d& pos)
+		: Weapon(texture, cooldownTime, damage, name, pos), projectileSpeed(projectileSpeed) {}
+	
+	bool RangedWeapon::use(std::shared_ptr<Entity> user, const olc::vf2d& direction)
+	{
+		if (cooldown != 0) return false;
+		cooldown = cooldownTime;
+
+		this->spawnProjectile(user, this->pos, direction.norm() * projectileSpeed, this->baseDamage);
+
+		return true;
+	}
+
+	const Pistol RangedWeapon::pistol(textures::rifle, .3f, 10, 10, "Pistol");
+	const EMGun RangedWeapon::emgun(textures::rifle, .08f, 14, 10, "Pistol");
+}
diff --git a/RangedWeapon.h b/RangedWeapon.h
new file mode 100644
index 0000000..d9b66f8
--- /dev/null
+++ b/RangedWeapon.h
@@ -0,0 +1,29 @@
+#pragma once
+#include "Weapon.h"
+
+namespace weapons {
+
+    class Pistol;
+    class EMGun;
+	
+    class RangedWeapon :
+        public Weapon
+    {
+    public:
+        const static Pistol pistol;
+        const static EMGun emgun;
+    	
+    protected:
+        float projectileSpeed;
+    	
+        virtual void spawnProjectile(std::shared_ptr<Entity>& user, const olc::vf2d& pos, const olc::vf2d& v0, int damage) = 0;
+
+    public:
+
+        RangedWeapon(render::ITexture& texture, float cooldownTime, int damage, float projectileSpeed = 10, const std::string& name = "RangedWeapon", const olc::vf2d& pos = { 0, 0 });
+    	
+    	bool use(std::shared_ptr<Entity> user, const olc::vf2d& direction) override;
+
+    	
+    };
+}
diff --git a/TestGenerator.cpp b/TestGenerator.cpp
index 0284f9a..c9e4ffd 100644
--- a/TestGenerator.cpp
+++ b/TestGenerator.cpp
@@ -6,6 +6,7 @@
 #include "CharacterTexture.h"
 #include "DummyEntity.h"
 #include "TypicalMeleeWeapon.h"
+#include "EMGun.h"
 
 using namespace entities;
 using namespace std;
@@ -22,10 +23,14 @@ shared_ptr<PlayerEntity> TestGenerator::generate(GameClient& client)
 	client += make_shared<WallEntity>(*asd);
 
 	client += make_shared<CharacterEntity>(*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));
 
 	weapon->setPos({ -3, -4 });
+	weapon1->setPos({ -4, -4 });
+	weapon2->setPos({ -4, -5 });
 	
 	client += weapon;
 	shared_ptr<PlayerEntity> player(new PlayerEntity({ 0, -4 }, render::CharacterTexture::EngineerTexture));
diff --git a/Weapon.cpp b/Weapon.cpp
index fe8f2f9..3507872 100644
--- a/Weapon.cpp
+++ b/Weapon.cpp
@@ -7,6 +7,11 @@ namespace weapons
 		return this->texture;
 	}
 
+	olc::vf2d Weapon::getHitBoxSize() const
+	{
+		return olc::vf2d(0, 0);
+	}
+
 	Weapon::Weapon(render::ITexture& texture, float cooldownTime, int damage, const std::string& name, const olc::vf2d& pos)
 		: Entity(pos), texture(texture), cooldown(0), cooldownTime(cooldownTime), baseDamage(damage), name(name) {}
 
@@ -37,5 +42,10 @@ namespace weapons
 		this->pos = newPos;
 	}
 
+	bool Weapon::damage(int damage, Entity& attacker)
+	{
+		return false;
+	}
+
 	
 }
\ No newline at end of file
diff --git a/Weapon.h b/Weapon.h
index 2ee7241..32315b8 100644
--- a/Weapon.h
+++ b/Weapon.h
@@ -20,6 +20,7 @@ namespace weapons {
         int baseDamage;
         std::string name;
         bool isPickedUp = false;
+		olc::vf2d getHitBoxSize() const override;
     public:
 
         Weapon(render::ITexture& texture, float cooldownTime, int damage = 10, const std::string& name = "Weapon", const olc::vf2d& pos = { 0, 0 });
@@ -46,5 +47,7 @@ namespace weapons {
     	 */
         virtual float getSecondaryBar() { return 0; }
         virtual void setPos(const olc::vf2d& newPos);
+
+    	bool damage(int damage, Entity& attacker) override;
     };
 }
\ No newline at end of file
diff --git a/game.cpp b/game.cpp
index 69ed670..fb643a1 100644
--- a/game.cpp
+++ b/game.cpp
@@ -13,7 +13,7 @@ int main(int argc, char* argv[])
 	cout << argv[0] << endl;
 	
 	bool invalidArg = false;
-	bool debug = true;
+	bool debug = false;
 	for(int i = 0; i < argc; i++){
 		std::string tmp(argv[i]);
 		if(tmp == "-r" || tmp == "--resource"){
-- 
GitLab