From 9331f7e2739c40c641d6addeb83bfc6e20fd7700 Mon Sep 17 00:00:00 2001
From: KosmX <kosmx.mc@gmail.com>
Date: Wed, 12 May 2021 18:51:57 +0200
Subject: [PATCH] Use dynamic cast instead of stupid static cast

---
 2d-game.vcxproj         |  8 +++++-
 2d-game.vcxproj.filters | 37 +++++++++++++++++--------
 2d-game1.rc             | 60 +++++++++++++++++++++++++++++++++++++++++
 CharacterEntity.cpp     | 14 ++++++++++
 CharacterEntity.h       | 24 +++++++++++++++++
 CharacterTexture.cpp    |  4 +--
 DummyEntity.cpp         |  7 +++++
 DummyEntity.h           | 16 +++++++++++
 Entity.h                | 11 +++-----
 LivingEntity.cpp        |  5 ----
 LivingEntity.h          |  2 --
 MeleeWeapon.cpp         |  6 ++---
 MeleeWeapon.h           |  6 ++---
 PlayerEntity.cpp        | 25 ++++++++++++-----
 PlayerEntity.h          |  7 +++--
 WallEntity.cpp          |  4 +--
 WallEntity.h            |  4 ---
 WallTexture.cpp         |  4 +--
 Weapon.h                |  2 +-
 mainGame.cpp            |  5 ++++
 mainGame.h              |  2 ++
 resource1.h             | 14 ++++++++++
 22 files changed, 212 insertions(+), 55 deletions(-)
 create mode 100644 2d-game1.rc
 create mode 100644 CharacterEntity.cpp
 create mode 100644 CharacterEntity.h
 create mode 100644 DummyEntity.cpp
 create mode 100644 DummyEntity.h
 create mode 100644 resource1.h

diff --git a/2d-game.vcxproj b/2d-game.vcxproj
index 160c507..a7aae7e 100644
--- a/2d-game.vcxproj
+++ b/2d-game.vcxproj
@@ -143,7 +143,9 @@
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="CharacterEntity.cpp" />
     <ClCompile Include="CharacterTexture.cpp" />
+    <ClCompile Include="DummyEntity.cpp" />
     <ClCompile Include="DungeonGenerator.cpp" />
     <ClCompile Include="Entity.cpp" />
     <ClCompile Include="game.cpp" />
@@ -162,7 +164,9 @@
     <ClCompile Include="Weapon.cpp" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="CharacterEntity.h" />
     <ClInclude Include="CharacterTexture.h" />
+    <ClInclude Include="DummyEntity.h" />
     <ClInclude Include="DungeonGenerator.h" />
     <ClInclude Include="DynamicArray.hpp" />
     <ClInclude Include="GameException.h" />
@@ -177,7 +181,6 @@
     <ClInclude Include="olcPGEX_TransformedView.h" />
     <ClInclude Include="olcPixelGameEngine.h" />
     <ClInclude Include="PlayerEntity.h" />
-    <ClInclude Include="resource.h" />
     <ClInclude Include="ResourceManager.h" />
     <ClInclude Include="SimpleSprite.h" />
     <ClInclude Include="TestGenerator.h" />
@@ -194,6 +197,9 @@
   <ItemGroup>
     <Text Include="Text.md" />
   </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="2d-game1.rc" />
+  </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
diff --git a/2d-game.vcxproj.filters b/2d-game.vcxproj.filters
index 4399b23..7c42959 100644
--- a/2d-game.vcxproj.filters
+++ b/2d-game.vcxproj.filters
@@ -33,6 +33,9 @@
     <Filter Include="Header Files\gameObj\wepons">
       <UniqueIdentifier>{de0faaa5-c9ef-49fa-881f-2e075bcfb99a}</UniqueIdentifier>
     </Filter>
+    <Filter Include="Source Files\gameObj\wepons">
+      <UniqueIdentifier>{dd621142-8159-4833-89b9-1326e01d8640}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="game.cpp">
@@ -77,14 +80,20 @@
     <ClCompile Include="PlayerEntity.cpp">
       <Filter>Source Files\gameObj\entities</Filter>
     </ClCompile>
-    <ClCompile Include="Weapon.cpp">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="MeleeWeapon.cpp">
-      <Filter>Source Files</Filter>
+      <Filter>Source Files\gameObj\wepons</Filter>
     </ClCompile>
     <ClCompile Include="TypicalMeleeWeapon.cpp">
-      <Filter>Source Files</Filter>
+      <Filter>Source Files\gameObj\wepons</Filter>
+    </ClCompile>
+    <ClCompile Include="Weapon.cpp">
+      <Filter>Source Files\gameObj\wepons</Filter>
+    </ClCompile>
+    <ClCompile Include="DummyEntity.cpp">
+      <Filter>Source Files\gameObj\entities</Filter>
+    </ClCompile>
+    <ClCompile Include="CharacterEntity.cpp">
+      <Filter>Source Files\gameObj\entities</Filter>
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
@@ -115,9 +124,6 @@
     <ClInclude Include="mainGame.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="resource.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="DynamicArray.hpp">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -148,9 +154,6 @@
     <ClInclude Include="PlayerEntity.h">
       <Filter>Header Files\gameObj\entities</Filter>
     </ClInclude>
-    <ClInclude Include="Weapon.h">
-      <Filter>Header Files\gameObj\entities</Filter>
-    </ClInclude>
     <ClInclude Include="WeaponTextures.h">
       <Filter>Header Files\gameObj\render</Filter>
     </ClInclude>
@@ -160,6 +163,15 @@
     <ClInclude Include="MeleeWeapon.h">
       <Filter>Header Files\gameObj\wepons</Filter>
     </ClInclude>
+    <ClInclude Include="Weapon.h">
+      <Filter>Header Files\gameObj\wepons</Filter>
+    </ClInclude>
+    <ClInclude Include="DummyEntity.h">
+      <Filter>Header Files\gameObj\entities</Filter>
+    </ClInclude>
+    <ClInclude Include="CharacterEntity.h">
+      <Filter>Header Files\gameObj\entities</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <None Include="README.md">
@@ -172,4 +184,7 @@
       <Filter>Header Files\gameObj\wepons</Filter>
     </Text>
   </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="2d-game1.rc" />
+  </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/2d-game1.rc b/2d-game1.rc
new file mode 100644
index 0000000..80eb26a
--- /dev/null
+++ b/2d-game1.rc
@@ -0,0 +1,60 @@
+// Microsoft Visual C++ generated resource script.
+//
+
+#include "resource1.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (United States) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+LANGUAGE 9, 1
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+    "resource1.h\0"
+END
+
+2 TEXTINCLUDE  
+BEGIN
+    "#include ""winres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE  
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (United States) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
diff --git a/CharacterEntity.cpp b/CharacterEntity.cpp
new file mode 100644
index 0000000..c144eca
--- /dev/null
+++ b/CharacterEntity.cpp
@@ -0,0 +1,14 @@
+#include "CharacterEntity.h"
+
+namespace entities {
+	std::shared_ptr<weapons::Weapon> CharacterEntity::getWeapon()
+	{
+		return std::shared_ptr<weapons::Weapon>();
+	}
+	render::ITexture& CharacterEntity::getTexture()
+	{
+		return texture;
+	}
+	CharacterEntity::CharacterEntity(render::ITexture& tex, const olc::vf2d& pos)
+		: LivingEntity(pos), texture(tex) {}
+}
diff --git a/CharacterEntity.h b/CharacterEntity.h
new file mode 100644
index 0000000..6ffd8b2
--- /dev/null
+++ b/CharacterEntity.h
@@ -0,0 +1,24 @@
+#pragma once
+#include "LivingEntity.h"
+
+namespace weapons
+{
+    class Weapon;
+}
+
+namespace entities {
+    class CharacterEntity :
+        public LivingEntity
+    {
+    protected:
+    	/**
+    	 * Return null if not available
+    	 */
+        std::shared_ptr<weapons::Weapon> getWeapon();
+
+        render::ITexture& texture;
+		render::ITexture& getTexture() override;
+    public:
+        CharacterEntity(render::ITexture& skin, const olc::vf2d& pos);
+    };
+}
diff --git a/CharacterTexture.cpp b/CharacterTexture.cpp
index 6c724ba..4b179c2 100644
--- a/CharacterTexture.cpp
+++ b/CharacterTexture.cpp
@@ -13,10 +13,10 @@ namespace render {
 
 	void CharacterTexture::render(TransformedView& scene, entities::Entity& entity)
 	{
-		if (entity.getAsLivingEntity() == nullptr) {
+		if (dynamic_cast<entities::LivingEntity*>(&entity) == nullptr) {
 			throw GameException("Can't render character texture for a not-living entity...", entity);
 		}
-		entities::LivingEntity& livingEntity = *entity.getAsLivingEntity();
+		auto& livingEntity = dynamic_cast<entities::LivingEntity&>(entity);
 		vf2d pos = this->uv + vf2d(livingEntity.getAnimPhase() * this->size.x, livingEntity.getDirection() * size.y);
 		this->sprite.renderCentered(scene, entity.getPos(), pos, size, entity.getSize());
 	}
diff --git a/DummyEntity.cpp b/DummyEntity.cpp
new file mode 100644
index 0000000..dcbb9ce
--- /dev/null
+++ b/DummyEntity.cpp
@@ -0,0 +1,7 @@
+#include "DummyEntity.h"
+
+namespace entities
+{
+    DummyEntity::DummyEntity(olc::vf2d pos, render::ITexture& skin, const std::string& name)
+	    : CharacterEntity(skin, pos), name(name) {}
+}
diff --git a/DummyEntity.h b/DummyEntity.h
new file mode 100644
index 0000000..144b821
--- /dev/null
+++ b/DummyEntity.h
@@ -0,0 +1,16 @@
+#pragma once
+#include "CharacterEntity.h"
+
+namespace entities {
+    class DummyEntity :
+        public CharacterEntity
+    {
+    private:
+        std::string name;
+        std::shared_ptr<weapons::Weapon> weaponToPickUp;
+    public:
+
+        DummyEntity(olc::vf2d pos, render::ITexture& skin, const std::string& name = "DummyEntity");
+    };
+    ;
+}
diff --git a/Entity.h b/Entity.h
index fb76b98..bf0c20f 100644
--- a/Entity.h
+++ b/Entity.h
@@ -48,15 +48,10 @@ namespace entities {
 		
 		virtual ~Entity() = default;
 
-		//TODO getAs*** stuff, all virtual
-		//same purpose to dynamic_cast, but without using language server
-		virtual WallEntity* getAsWallEntity()
-		{
-			return nullptr;
-		}
 
-		virtual LivingEntity* getAsLivingEntity()
-		{
+		
+
+		virtual operator WallEntity* (){
 			return nullptr;
 		}
 	};
diff --git a/LivingEntity.cpp b/LivingEntity.cpp
index 7d1425c..f6a1d95 100644
--- a/LivingEntity.cpp
+++ b/LivingEntity.cpp
@@ -90,10 +90,5 @@ namespace entities {
 		pos += offset;
 	}
 
-	LivingEntity* LivingEntity::getAsLivingEntity()
-	{
-		return this;
-	}
-
 	const float LivingEntity::phaseLength = 1;
 }
\ No newline at end of file
diff --git a/LivingEntity.h b/LivingEntity.h
index fd9434b..39e1a9c 100644
--- a/LivingEntity.h
+++ b/LivingEntity.h
@@ -23,7 +23,5 @@ namespace entities {
 
 
 		void tick(GameClient& client, float deltaT, std::shared_ptr<Entity>& shared_this) override; //TODO
-
-		LivingEntity* getAsLivingEntity() override;
 	};
 }
diff --git a/MeleeWeapon.cpp b/MeleeWeapon.cpp
index 41d323f..5737f9c 100644
--- a/MeleeWeapon.cpp
+++ b/MeleeWeapon.cpp
@@ -6,11 +6,11 @@ namespace weapons {
     {
         return this->baseDamage;
     }
-    bool MeleeWeapon::damageEntity(std::shared_ptr<LivingEntity> user, std::shared_ptr<Entity>& victim)
+    bool MeleeWeapon::damageEntity(std::shared_ptr<Entity> user, std::shared_ptr<Entity>& victim)
     {
         return victim->damage(this->getDamage(), *victim);
     }
-    bool MeleeWeapon::damageIf(std::shared_ptr<LivingEntity>& user, std::function<bool(std::shared_ptr<Entity>, std::shared_ptr<Entity>)> predicate)
+    bool MeleeWeapon::damageIf(std::shared_ptr<Entity>& user, std::function<bool(std::shared_ptr<Entity>, std::shared_ptr<Entity>)> predicate)
     {
         bool bl = false;
         for(auto& entity : GameClient::getInstance().getEntities()){
@@ -24,7 +24,7 @@ namespace weapons {
     MeleeWeapon::MeleeWeapon(render::ITexture& texture, const std::string& name, float cooldownTime, int damage, const olc::vf2d& pos)
 	    : Weapon(texture, cooldownTime, damage, name, pos) {}
 
-    bool MeleeWeapon::use(std::shared_ptr<LivingEntity> user, const olc::vf2d& direction)
+    bool MeleeWeapon::use(std::shared_ptr<Entity> user, const olc::vf2d& direction)
     {
         if (this->cooldown != 0) return false;
         this->cooldown = this->cooldownTime;
diff --git a/MeleeWeapon.h b/MeleeWeapon.h
index 97cfaaa..853011b 100644
--- a/MeleeWeapon.h
+++ b/MeleeWeapon.h
@@ -8,8 +8,8 @@ namespace weapons {
     {
     protected:
         virtual int getDamage() const;
-        virtual bool damageEntity(std::shared_ptr<LivingEntity> user, std::shared_ptr<Entity>& victim);
-        virtual bool damageIf(std::shared_ptr<LivingEntity>& user, std::function<bool(std::shared_ptr<Entity> self, std::shared_ptr<Entity> other)> predicate);
+        virtual bool damageEntity(std::shared_ptr<Entity> user, std::shared_ptr<Entity>& victim);
+        virtual bool damageIf(std::shared_ptr<Entity>& user, std::function<bool(std::shared_ptr<Entity> self, std::shared_ptr<Entity> other)> predicate);
         //virtual bool(*getPredicator())(std::shared_ptr<Entity>, std::shared_ptr<Entity>) = 0;
         virtual std::function<bool(std::shared_ptr<Entity>, std::shared_ptr<Entity>)> getPredicator(const olc::vf2d& direction) = 0;
 
@@ -29,7 +29,7 @@ namespace weapons {
     public:
         MeleeWeapon(render::ITexture& texture, const std::string& name, float cooldownTime, int damage = 10, const olc::vf2d& pos = { 0, 0 });
     	
-        bool use(std::shared_ptr<LivingEntity> user, const olc::vf2d& direction) override;
+        bool use(std::shared_ptr<Entity> user, const olc::vf2d& direction) override;
         virtual void setPos(const olc::vf2d& newPos);
     };
 }
diff --git a/PlayerEntity.cpp b/PlayerEntity.cpp
index 2d6e826..7aa4d61 100644
--- a/PlayerEntity.cpp
+++ b/PlayerEntity.cpp
@@ -1,16 +1,12 @@
 #include "PlayerEntity.h"
 
 #include "mainGame.h"
+#include "Weapon.h"
 
 using namespace olc;
 
 namespace entities {
-
-	render::ITexture& PlayerEntity::getTexture()
-	{
-		return this->texture;
-	}
-
+	
 	void PlayerEntity::tick(GameClient& client, float deltaT, std::shared_ptr<Entity>& shared_this)
 	{
 		vf2d newSpeed = { 0, 0 };
@@ -19,11 +15,26 @@ namespace entities {
 		if (client.GetKey(olc::Key::D).bHeld) newSpeed += {1, 0};
 		if (client.GetKey(olc::Key::W).bHeld) newSpeed += {0, -1};
 		this->speed = newSpeed == vf2d(0, 0) ? newSpeed : newSpeed.norm() * 6;
+
+		if(client.GetKey(SPACE).bHeld && this->getWeapon()) // TODO mouse button ?!
+		{
+			vf2d mouse = client.getScene().ScreenToWorld(client.GetMousePos());
+			mouse -= this->getPos();
+			mouse = mouse.norm();
+			this->getWeapon()->use(shared_this, mouse);
+		}
+
+		for(auto& entity : client.getEntities()){
+			if(std::dynamic_pointer_cast<weapons::Weapon>(entity)){
+				
+			}
+		}
+		
 		LivingEntity::tick(client, deltaT, shared_this);
 	}
 
 	PlayerEntity::PlayerEntity(olc::vf2d pos, render::ITexture& skin, const std::string& name)
-		: LivingEntity(pos), name(name), texture(skin)
+		: CharacterEntity(skin, pos), name(name)
 	{
 
 	}
diff --git a/PlayerEntity.h b/PlayerEntity.h
index 5d84c71..8a8e670 100644
--- a/PlayerEntity.h
+++ b/PlayerEntity.h
@@ -1,15 +1,14 @@
 #pragma once
-#include "LivingEntity.h"
+#include "CharacterEntity.h"
 
 namespace entities {
 
     class PlayerEntity :
-        public LivingEntity
+        public CharacterEntity
     {
     private:
         std::string name;
-        render::ITexture& texture;
-		render::ITexture& getTexture() override;
+        std::shared_ptr<weapons::Weapon> weaponToPickUp;
     public:
         void tick(GameClient& client, float deltaT, std::shared_ptr<Entity>& shared_this) override;
         PlayerEntity(olc::vf2d pos, render::ITexture& skin, const std::string& name = "Player");
diff --git a/WallEntity.cpp b/WallEntity.cpp
index 6853077..6200e29 100644
--- a/WallEntity.cpp
+++ b/WallEntity.cpp
@@ -9,8 +9,8 @@ namespace entities {
 	{
 		this->neighbourID = 0;
 		for (auto& entity : client.getEntities()) {
-			if (entity->getAsWallEntity() != nullptr) {
-				WallEntity& wallEntity = *entity->getAsWallEntity();
+			if (std::dynamic_pointer_cast<WallEntity>(entity) != nullptr) {
+				auto& wallEntity = dynamic_cast<WallEntity&>(*entity);
 				vi2d distance = entity->getPos() - this->getPos();
 				if (abs(distance.x) == 1 && abs(distance.y) == 0) {
 					neighbourID |= distance.x != 1 ? 0b0100 : 0b1000;
diff --git a/WallEntity.h b/WallEntity.h
index a9a7e40..b941f11 100644
--- a/WallEntity.h
+++ b/WallEntity.h
@@ -30,9 +30,5 @@ namespace entities {
 		virtual byte getNeighbourID() const;
 
 		//This is a wall entity after all.
-		WallEntity* getAsWallEntity() override
-		{
-			return this;
-		}
 	};
 }
diff --git a/WallTexture.cpp b/WallTexture.cpp
index d13f370..d0bd85e 100644
--- a/WallTexture.cpp
+++ b/WallTexture.cpp
@@ -13,10 +13,10 @@ namespace render
 		: sprite(resName), baseOffset(baseOffset * size), size(size) {}
 	void WallTexture::render(olc::TransformedView& scene, Entity& entity)
 	{
-		if(entity.getAsWallEntity() == nullptr){
+		if(dynamic_cast<WallEntity*>(&entity) == nullptr){
 			throw GameException("Wall texture needs a wall entity", entity);
 		}
-		WallEntity& wallEntity = *entity.getAsWallEntity();
+		auto& wallEntity = dynamic_cast<WallEntity&>(entity);
 		vf2d offset = this->baseOffset;
 
 		//I can't use index[] because that is not const function... WHY???
diff --git a/Weapon.h b/Weapon.h
index 0f03c39..061f9b3 100644
--- a/Weapon.h
+++ b/Weapon.h
@@ -26,7 +26,7 @@ namespace weapons {
     	/**
     	 * @return true, if can use
     	 */
-        virtual bool use(std::shared_ptr<LivingEntity> user, const olc::vf2d& direction) = 0;
+        virtual bool use(std::shared_ptr<Entity> user, const olc::vf2d& direction) = 0;
 
         virtual bool update(float dTick);
     	
diff --git a/mainGame.cpp b/mainGame.cpp
index 87c9dcc..0526e1c 100644
--- a/mainGame.cpp
+++ b/mainGame.cpp
@@ -108,6 +108,11 @@ void GameClient::addEntity(std::shared_ptr<entities::Entity>& entity)
 	this->entities.operator+=(entity);
 }
 
+const olc::TransformedView& GameClient::getScene()
+{
+	return scene;
+}
+
 GameClient& GameClient::operator+=(std::shared_ptr<entities::Entity> entity)
 {
 	this->addEntity(entity);
diff --git a/mainGame.h b/mainGame.h
index aa0dd5d..fa72dd3 100644
--- a/mainGame.h
+++ b/mainGame.h
@@ -41,6 +41,8 @@ public:
 	
 	void addEntity(std::shared_ptr<entities::Entity>& entity);
 
+	const olc::TransformedView& getScene(); //for some reason
+
 	GameClient& operator+=(std::shared_ptr<entities::Entity> entity);
  
 	//for some reason, probably I won't need it
diff --git a/resource1.h b/resource1.h
new file mode 100644
index 0000000..4642976
--- /dev/null
+++ b/resource1.h
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by 2d-game1.rc
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        101
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1001
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif
-- 
GitLab