Added stat-based item enchant checks. Remove friend class dependencies from unit tests and added appropriate publicly exposed functions. Release Build 10538.
This commit is contained in:
		
							parent
							
								
									d4d325503e
								
							
						
					
					
						commit
						2f244e21ff
					
				| @ -101,6 +101,10 @@ | |||||||
|     <ClCompile Include="..\Adventures in Lestoria\discord-files\store_manager.cpp" /> |     <ClCompile Include="..\Adventures in Lestoria\discord-files\store_manager.cpp" /> | ||||||
|     <ClCompile Include="..\Adventures in Lestoria\discord-files\user_manager.cpp" /> |     <ClCompile Include="..\Adventures in Lestoria\discord-files\user_manager.cpp" /> | ||||||
|     <ClCompile Include="..\Adventures in Lestoria\discord-files\voice_manager.cpp" /> |     <ClCompile Include="..\Adventures in Lestoria\discord-files\voice_manager.cpp" /> | ||||||
|  |     <ClCompile Include="EnchantTests.cpp"> | ||||||
|  |       <SubType> | ||||||
|  |       </SubType> | ||||||
|  |     </ClCompile> | ||||||
|     <ClCompile Include="GeometryTests.cpp" /> |     <ClCompile Include="GeometryTests.cpp" /> | ||||||
|     <ClCompile Include="ItemTests.cpp"> |     <ClCompile Include="ItemTests.cpp"> | ||||||
|       <SubType> |       <SubType> | ||||||
|  | |||||||
| @ -69,5 +69,8 @@ | |||||||
|     <ClCompile Include="ItemTests.cpp"> |     <ClCompile Include="ItemTests.cpp"> | ||||||
|       <Filter>Source Files</Filter> |       <Filter>Source Files</Filter> | ||||||
|     </ClCompile> |     </ClCompile> | ||||||
|  |     <ClCompile Include="EnchantTests.cpp"> | ||||||
|  |       <Filter>Source Files</Filter> | ||||||
|  |     </ClCompile> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| </Project> | </Project> | ||||||
							
								
								
									
										213
									
								
								Adventures in Lestoria Tests/EnchantTests.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								Adventures in Lestoria Tests/EnchantTests.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,213 @@ | |||||||
|  | #pragma region License | ||||||
|  | /*
 | ||||||
|  | License (OLC-3) | ||||||
|  | ~~~~~~~~~~~~~~~ | ||||||
|  | 
 | ||||||
|  | Copyright 2024 Joshua Sigona <sigonasr2@gmail.com> | ||||||
|  | 
 | ||||||
|  | Redistribution and use in source and binary forms, with or without modification, | ||||||
|  | are permitted provided that the following conditions are met: | ||||||
|  | 
 | ||||||
|  | 1. Redistributions or derivations of source code must retain the above copyright | ||||||
|  | notice, this list of conditions and the following disclaimer. | ||||||
|  | 
 | ||||||
|  | 2. Redistributions or derivative works in binary form must reproduce the above | ||||||
|  | copyright notice. This list of conditions and the following	disclaimer must be | ||||||
|  | reproduced in the documentation and/or other materials provided with the distribution. | ||||||
|  | 
 | ||||||
|  | 3. Neither the name of the copyright holder nor the names of its contributors may | ||||||
|  | be used to endorse or promote products derived from this software without specific | ||||||
|  | prior written permission. | ||||||
|  | 
 | ||||||
|  | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS	"AS IS" AND ANY | ||||||
|  | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||||
|  | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT | ||||||
|  | SHALL THE COPYRIGHT	HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  | INCIDENTAL,	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED | ||||||
|  | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||||||
|  | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||||
|  | CONTRACT, STRICT LIABILITY, OR TORT	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | ||||||
|  | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||||
|  | SUCH DAMAGE. | ||||||
|  | 
 | ||||||
|  | Portions of this software are copyright © 2024 The FreeType | ||||||
|  | Project (www.freetype.org). Please see LICENSE_FT.txt for more information. | ||||||
|  | All rights reserved. | ||||||
|  | */ | ||||||
|  | #pragma endregion | ||||||
|  | #include "CppUnitTest.h" | ||||||
|  | #include "AdventuresInLestoria.h" | ||||||
|  | #include "Tutorial.h" | ||||||
|  | #include <random> | ||||||
|  | #include <format> | ||||||
|  | #include "ItemDrop.h" | ||||||
|  | #include "DamageNumber.h" | ||||||
|  | #include <ranges> | ||||||
|  | 
 | ||||||
|  | using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||||
|  | using namespace olc::utils; | ||||||
|  | 
 | ||||||
|  | INCLUDE_GFX | ||||||
|  | INCLUDE_ITEM_DATA | ||||||
|  | INCLUDE_DAMAGENUMBER_LIST | ||||||
|  | 
 | ||||||
|  | extern std::mt19937 rng; | ||||||
|  | 
 | ||||||
|  | namespace Test | ||||||
|  | { | ||||||
|  | 	template<class T> | ||||||
|  | 	inline static void InRange(T initialVal,std::pair<T,T>range,std::wstring_view assertMessage){ | ||||||
|  | 		Assert::IsTrue(initialVal>=range.first&&initialVal<=range.second,std::format(L"Expected: {}~{}   Actual: {} - {}",range.first,range.second,initialVal,assertMessage).c_str()); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | namespace EnchantTests | ||||||
|  | { | ||||||
|  | 	TEST_CLASS(EnchantTest) | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		std::unique_ptr<AiL>testGame; | ||||||
|  | 		InputGroup testKeyboardInput; | ||||||
|  | 		Player*player; | ||||||
|  | 		const HWButton*testKey; | ||||||
|  | 		TEST_METHOD_INITIALIZE(PlayerInitialize){ | ||||||
|  | 			rng=std::mt19937{57189U};//Establish a fixed random seed on setup so the exact same results are generated every test run.
 | ||||||
|  | 			testGame.reset(new AiL(true)); | ||||||
|  | 			ItemAttribute::Initialize(); | ||||||
|  | 			ItemInfo::InitializeItems(); | ||||||
|  | 			testGame->InitializeGraphics(); | ||||||
|  | 			testGame->InitializeClasses(); | ||||||
|  | 			sig::Animation::InitializeAnimations(); | ||||||
|  | 			testGame->InitializeDefaultKeybinds(); | ||||||
|  | 			testGame->InitializePlayer(); | ||||||
|  | 			sig::Animation::SetupPlayerAnimations(); | ||||||
|  | 			Menu::InitializeMenus(); | ||||||
|  | 			Tutorial::Initialize(); | ||||||
|  | 			Stats::InitializeDamageReductionTable(); | ||||||
|  | 
 | ||||||
|  | 			GameState::Initialize(); | ||||||
|  | 			GameState::STATE=GameState::states.at(States::State::GAME_RUN); | ||||||
|  | 			 | ||||||
|  | 			#pragma region Setup a fake test map and test monster | ||||||
|  | 				game->MAP_DATA["CAMPAIGN_1_1"]; | ||||||
|  | 				ItemDrop::ClearDrops(); | ||||||
|  | 				MonsterData testMonsterData{"TestName","Test Monster",1000,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f}; | ||||||
|  | 				MONSTER_DATA["TestName"]=testMonsterData; | ||||||
|  | 			#pragma endregion | ||||||
|  | 
 | ||||||
|  | 			player=testGame->GetPlayer(); | ||||||
|  | 			//Setup key "0" as a test input
 | ||||||
|  | 			testKeyboardInput.AddKeybind(Input{InputType::KEY,0}); | ||||||
|  | 			testKey=testGame->GetKeyboardState(0); | ||||||
|  | 			testGame->olc_UpdateKeyFocus(true); //Force the game to be "focused" for tests. Required if we want keyboard inputs to work.
 | ||||||
|  | 			Menu::themes.SetInitialized(); | ||||||
|  | 			GFX.SetInitialized(); | ||||||
|  | 
 | ||||||
|  | 			DAMAGENUMBER_LIST.clear(); | ||||||
|  | 		} | ||||||
|  | 		TEST_METHOD(HealthBoostCheck){ | ||||||
|  | 			std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)}; | ||||||
|  | 			Assert::AreEqual(100,player->GetMaxHealth(),L"Player starts with 100 health."); | ||||||
|  | 			Inventory::EquipItem(nullRing,EquipSlot::RING1); | ||||||
|  | 			for(int i:std::ranges::iota_view(0,1000)){ | ||||||
|  | 				nullRing.lock()->EnchantItem("Health Boost"); | ||||||
|  | 				Test::InRange(player->GetMaxHealth(),{103,105},L"Max Health not in expected range."); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		TEST_METHOD(AttackBoostCheck){ | ||||||
|  | 			player->SetBaseStat("Attack",100.f); | ||||||
|  | 			std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)}; | ||||||
|  | 			Assert::AreEqual(100,player->GetAttack(),L"Player starts with 100 attack."); | ||||||
|  | 			Inventory::EquipItem(nullRing,EquipSlot::RING1); | ||||||
|  | 			for(int i:std::ranges::iota_view(0,1000)){ | ||||||
|  | 				nullRing.lock()->EnchantItem("Attack Boost"); | ||||||
|  | 				Test::InRange(player->GetAttack(),{103,105},L"Attack not in expected range."); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		TEST_METHOD(MovementBoostCheck){ | ||||||
|  | 			std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)}; | ||||||
|  | 			Assert::AreEqual(100.0_Pct,player->GetMoveSpdMult(),L"Player starts with 100% Movespd."); | ||||||
|  | 			Inventory::EquipItem(nullRing,EquipSlot::RING1); | ||||||
|  | 			for(int i:std::ranges::iota_view(0,1000)){ | ||||||
|  | 				nullRing.lock()->EnchantItem("Movement Boost"); | ||||||
|  | 				Test::InRange(player->GetMoveSpdMult(),{103.0_Pct,105.0_Pct},L"Move Speed not in expected range."); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		TEST_METHOD(AbilityHasteCheck){ | ||||||
|  | 			std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)}; | ||||||
|  | 			Assert::AreEqual(0.0_Pct,player->GetCooldownReductionPct(),L"Player starts with 0% CDR."); | ||||||
|  | 			Inventory::EquipItem(nullRing,EquipSlot::RING1); | ||||||
|  | 			for(int i:std::ranges::iota_view(0,1000)){ | ||||||
|  | 				nullRing.lock()->EnchantItem("Ability Haste"); | ||||||
|  | 				Test::InRange(player->GetCooldownReductionPct(),{3.0_Pct,5.0_Pct},L"CDR not in expected range."); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		TEST_METHOD(CritRateCheck){ | ||||||
|  | 			std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)}; | ||||||
|  | 			Assert::AreEqual(0.0_Pct,player->GetCritRatePct(),L"Player starts with 0% Crit Rate."); | ||||||
|  | 			Inventory::EquipItem(nullRing,EquipSlot::RING1); | ||||||
|  | 			for(int i:std::ranges::iota_view(0,1000)){ | ||||||
|  | 				nullRing.lock()->EnchantItem("Crit Rate"); | ||||||
|  | 				Test::InRange(player->GetCritRatePct(),{3.0_Pct,5.0_Pct},L"Crit Rate not in expected range."); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		TEST_METHOD(CritDamageCheck){ | ||||||
|  | 			std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)}; | ||||||
|  | 			Assert::AreEqual(50.0_Pct,player->GetCritDmgPct(),L"Player starts with 50% Crit Damage."); | ||||||
|  | 			Inventory::EquipItem(nullRing,EquipSlot::RING1); | ||||||
|  | 			for(int i:std::ranges::iota_view(0,1000)){ | ||||||
|  | 				nullRing.lock()->EnchantItem("Crit Damage"); | ||||||
|  | 				Test::InRange(player->GetCritDmgPct(),{57.0_Pct,60.0_Pct},L"Crit Damage not in expected range."); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		TEST_METHOD(StoneskinCheck){ | ||||||
|  | 			std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)}; | ||||||
|  | 			Assert::AreEqual(0.0_Pct,player->GetDamageReductionPct(),L"Player starts with 0% Damage Reduction."); | ||||||
|  | 			Inventory::EquipItem(nullRing,EquipSlot::RING1); | ||||||
|  | 			for(int i:std::ranges::iota_view(0,1000)){ | ||||||
|  | 				nullRing.lock()->EnchantItem("Stoneskin"); | ||||||
|  | 				Test::InRange(player->GetDamageReductionPct(),{3.0_Pct,5.0_Pct},L"Damage Reduction not in expected range."); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		TEST_METHOD(ManaPoolCheck){ | ||||||
|  | 			std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)}; | ||||||
|  | 			Assert::AreEqual(100,player->GetMaxMana(),L"Player starts with 100 mana."); | ||||||
|  | 			Inventory::EquipItem(nullRing,EquipSlot::RING1); | ||||||
|  | 			for(int i:std::ranges::iota_view(0,1000)){ | ||||||
|  | 				nullRing.lock()->EnchantItem("Mana Pool"); | ||||||
|  | 				Test::InRange(player->GetMaxMana(),{107,112},L"Mana Pool not in expected range."); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		TEST_METHOD(MagicalProtectionCheck){ | ||||||
|  | 			std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)}; | ||||||
|  | 			Assert::AreEqual(100,player->GetMaxHealth(),L"Player starts with 100 health."); | ||||||
|  | 			Assert::AreEqual(0.0_Pct,player->GetDamageReductionPct(),L"Player starts with 0% damage reduction."); | ||||||
|  | 			Assert::AreEqual(100.0_Pct,player->GetMoveSpdMult(),L"Player starts with 100% move speed."); | ||||||
|  | 			Assert::AreEqual(0.0_Pct,player->GetHP6RecoveryPct(),L"Player starts with 0% HP/6 recovery."); | ||||||
|  | 			Inventory::EquipItem(nullRing,EquipSlot::RING1); | ||||||
|  | 			for(int i:std::ranges::iota_view(0,1000)){ | ||||||
|  | 				nullRing.lock()->EnchantItem("Magical Protection"); | ||||||
|  | 				Test::InRange(player->GetMaxHealth(),{102,103},L"Max Health not in expected range."); | ||||||
|  | 				Test::InRange(player->GetDamageReductionPct(),{2.0_Pct,3.0_Pct},L"Damage Reduction not in expected range."); | ||||||
|  | 				Test::InRange(player->GetMoveSpdMult(),{102.0_Pct,103.0_Pct},L"Move Speed % not in expected range."); | ||||||
|  | 				Test::InRange(player->GetHP6RecoveryPct(),{1.0_Pct,1.0_Pct},L"HP/6 Recovery not in expected range."); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		TEST_METHOD(AuraOfTheBeastCheck){ | ||||||
|  | 			player->SetBaseStat("Attack",100.f); | ||||||
|  | 			std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)}; | ||||||
|  | 			Assert::AreEqual(100,player->GetAttack(),L"Player starts with 100 attack."); | ||||||
|  | 			Assert::AreEqual(0.0_Pct,player->GetCritRatePct(),L"Player starts with 0% crit rate."); | ||||||
|  | 			Assert::AreEqual(0.0_Pct,player->GetCooldownReductionPct(),L"Player starts with 0% cooldown reduction."); | ||||||
|  | 			Assert::AreEqual(50.0_Pct,player->GetCritDmgPct(),L"Player starts with 50% crit rate."); | ||||||
|  | 			Inventory::EquipItem(nullRing,EquipSlot::RING1); | ||||||
|  | 			for(int i:std::ranges::iota_view(0,1000)){ | ||||||
|  | 				nullRing.lock()->EnchantItem("Aura of the Beast"); | ||||||
|  | 				Test::InRange(player->GetAttack(),{102,103},L"Attack not in expected range."); | ||||||
|  | 				Test::InRange(player->GetCritRatePct(),{2.0_Pct,3.0_Pct},L"Crit Rate not in expected range."); | ||||||
|  | 				Test::InRange(player->GetCooldownReductionPct(),{2.0_Pct,3.0_Pct},L"Cooldown Reduction % not in expected range."); | ||||||
|  | 				Test::InRange(player->GetCritDmgPct(),{53.0_Pct,57.0_Pct},L"Crit Damage not in expected range."); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | } | ||||||
| @ -74,13 +74,12 @@ namespace ItemTests | |||||||
| 			Menu::InitializeMenus(); | 			Menu::InitializeMenus(); | ||||||
| 			Tutorial::Initialize(); | 			Tutorial::Initialize(); | ||||||
| 			Stats::InitializeDamageReductionTable(); | 			Stats::InitializeDamageReductionTable(); | ||||||
| 
 |  | ||||||
| 			GameState::Initialize(); | 			GameState::Initialize(); | ||||||
| 			GameState::STATE=GameState::states.at(States::State::GAME_RUN); | 			GameState::STATE=GameState::states.at(States::State::GAME_RUN); | ||||||
| 			 | 			 | ||||||
| 			#pragma region Setup a fake test map and test monster | 			#pragma region Setup a fake test map and test monster | ||||||
| 				game->MAP_DATA["CAMPAIGN_1_1"]; | 				game->MAP_DATA["CAMPAIGN_1_1"]; | ||||||
| 			ItemDrop::drops.clear(); | 				ItemDrop::ClearDrops(); | ||||||
| 				MonsterData testMonsterData{"TestName","Test Monster",1000,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f}; | 				MonsterData testMonsterData{"TestName","Test Monster",1000,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f}; | ||||||
| 				MONSTER_DATA["TestName"]=testMonsterData; | 				MONSTER_DATA["TestName"]=testMonsterData; | ||||||
| 			#pragma endregion | 			#pragma endregion | ||||||
| @ -88,7 +87,7 @@ namespace ItemTests | |||||||
| 			player=testGame->GetPlayer(); | 			player=testGame->GetPlayer(); | ||||||
| 			//Setup key "0" as a test input
 | 			//Setup key "0" as a test input
 | ||||||
| 			testKeyboardInput.AddKeybind(Input{InputType::KEY,0}); | 			testKeyboardInput.AddKeybind(Input{InputType::KEY,0}); | ||||||
| 			testKey=&testGame->pKeyboardState[0]; | 			testKey=testGame->GetKeyboardState(0); | ||||||
| 			testGame->olc_UpdateKeyFocus(true); //Force the game to be "focused" for tests. Required if we want keyboard inputs to work.
 | 			testGame->olc_UpdateKeyFocus(true); //Force the game to be "focused" for tests. Required if we want keyboard inputs to work.
 | ||||||
| 			Menu::themes.SetInitialized(); | 			Menu::themes.SetInitialized(); | ||||||
| 			GFX.SetInitialized(); | 			GFX.SetInitialized(); | ||||||
|  | |||||||
| @ -85,8 +85,8 @@ namespace MonsterTests | |||||||
| 				game->MAP_DATA["CAMPAIGN_1_1"]; | 				game->MAP_DATA["CAMPAIGN_1_1"]; | ||||||
| 				game->MAP_DATA["CAMPAIGN_1_1"].ZoneData["UpperZone"]; | 				game->MAP_DATA["CAMPAIGN_1_1"].ZoneData["UpperZone"]; | ||||||
| 				game->MAP_DATA["CAMPAIGN_1_1"].ZoneData["LowerZone"]; | 				game->MAP_DATA["CAMPAIGN_1_1"].ZoneData["LowerZone"]; | ||||||
| 				game->currentLevel="CAMPAIGN_1_1"; | 				game->_SetCurrentLevel("CAMPAIGN_1_1"); | ||||||
| 				ItemDrop::drops.clear(); | 				ItemDrop::ClearDrops(); | ||||||
| 			#pragma endregion | 			#pragma endregion | ||||||
| 
 | 
 | ||||||
| 			MonsterData testMonsterData{"TestName","Test Monster",30,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f}; | 			MonsterData testMonsterData{"TestName","Test Monster",30,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f}; | ||||||
| @ -98,7 +98,7 @@ namespace MonsterTests | |||||||
| 		} | 		} | ||||||
| 		void SetupMockMap(){ | 		void SetupMockMap(){ | ||||||
| 			game->MAP_DATA["CAMPAIGN_1_1"]; | 			game->MAP_DATA["CAMPAIGN_1_1"]; | ||||||
| 			ItemDrop::drops.clear(); | 			ItemDrop::ClearDrops(); | ||||||
| 		} | 		} | ||||||
| 		#pragma endregion | 		#pragma endregion | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -81,7 +81,7 @@ namespace PlayerTests | |||||||
| 			 | 			 | ||||||
| 			#pragma region Setup a fake test map and test monster | 			#pragma region Setup a fake test map and test monster | ||||||
| 				game->MAP_DATA["CAMPAIGN_1_1"]; | 				game->MAP_DATA["CAMPAIGN_1_1"]; | ||||||
| 				ItemDrop::drops.clear(); | 				ItemDrop::ClearDrops(); | ||||||
| 				MonsterData testMonsterData{"TestName","Test Monster",1000,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f}; | 				MonsterData testMonsterData{"TestName","Test Monster",1000,10,5,{MonsterDropData{"Health Potion",100.f,1,1}},200.f}; | ||||||
| 				MONSTER_DATA["TestName"]=testMonsterData; | 				MONSTER_DATA["TestName"]=testMonsterData; | ||||||
| 			#pragma endregion | 			#pragma endregion | ||||||
| @ -89,7 +89,7 @@ namespace PlayerTests | |||||||
| 			player=testGame->GetPlayer(); | 			player=testGame->GetPlayer(); | ||||||
| 			//Setup key "0" as a test input
 | 			//Setup key "0" as a test input
 | ||||||
| 			testKeyboardInput.AddKeybind(Input{InputType::KEY,0}); | 			testKeyboardInput.AddKeybind(Input{InputType::KEY,0}); | ||||||
| 			testKey=&testGame->pKeyboardState[0]; | 			testKey=testGame->GetKeyboardState(0); | ||||||
| 			testGame->olc_UpdateKeyFocus(true); //Force the game to be "focused" for tests. Required if we want keyboard inputs to work.
 | 			testGame->olc_UpdateKeyFocus(true); //Force the game to be "focused" for tests. Required if we want keyboard inputs to work.
 | ||||||
| 			Menu::themes.SetInitialized(); | 			Menu::themes.SetInitialized(); | ||||||
| 			GFX.SetInitialized(); | 			GFX.SetInitialized(); | ||||||
|  | |||||||
| @ -4448,3 +4448,7 @@ const std::map<std::string,TilesetData>&AiL::GetTilesets()const{ | |||||||
| void AiL::AddToMarkedTargetList(std::tuple<std::weak_ptr<Monster>,StackCount,MarkTime>markData){ | void AiL::AddToMarkedTargetList(std::tuple<std::weak_ptr<Monster>,StackCount,MarkTime>markData){ | ||||||
| 	lockOnTargets.emplace_back(markData); | 	lockOnTargets.emplace_back(markData); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void AiL::_SetCurrentLevel(const MapName map){ | ||||||
|  | 	currentLevel=map; | ||||||
|  | } | ||||||
| @ -95,9 +95,6 @@ class AiL : public olc::PixelGameEngine | |||||||
| 	friend class sig::Animation; | 	friend class sig::Animation; | ||||||
| 	friend class Audio; | 	friend class Audio; | ||||||
| 	friend class Minimap; | 	friend class Minimap; | ||||||
| 	friend class MonsterTests::MonsterTest; |  | ||||||
| 	friend class PlayerTests::PlayerTest; |  | ||||||
| 	friend class ItemTests::ItemTest; |  | ||||||
| 	std::unique_ptr<Player>player; | 	std::unique_ptr<Player>player; | ||||||
| 	SplashScreen splash; | 	SplashScreen splash; | ||||||
| public: | public: | ||||||
| @ -170,7 +167,6 @@ private: | |||||||
| 	std::vector<TileGroup>upperForegroundTileGroups; | 	std::vector<TileGroup>upperForegroundTileGroups; | ||||||
| 	int bridgeLayerIndex=-1; | 	int bridgeLayerIndex=-1; | ||||||
| 	float bridgeFadeFactor=0.f; | 	float bridgeFadeFactor=0.f; | ||||||
| 	void InitializeClasses(); |  | ||||||
| 	int DEBUG_PATHFINDING=0; | 	int DEBUG_PATHFINDING=0; | ||||||
| 	std::vector<Monster*>monstersBeforeLower,monstersAfterLower,monstersBeforeUpper,monstersAfterUpper; | 	std::vector<Monster*>monstersBeforeLower,monstersAfterLower,monstersBeforeUpper,monstersAfterUpper; | ||||||
| 	std::vector<IBullet*>bulletsLower,bulletsUpper; | 	std::vector<IBullet*>bulletsLower,bulletsUpper; | ||||||
| @ -386,6 +382,8 @@ public: | |||||||
| 	void PlayFootstepSound(); | 	void PlayFootstepSound(); | ||||||
| 	const std::map<std::string,TilesetData>&GetTilesets()const; | 	const std::map<std::string,TilesetData>&GetTilesets()const; | ||||||
| 	void AddToMarkedTargetList(std::tuple<std::weak_ptr<Monster>,StackCount,MarkTime>markData); | 	void AddToMarkedTargetList(std::tuple<std::weak_ptr<Monster>,StackCount,MarkTime>markData); | ||||||
|  | 	void InitializeClasses(); | ||||||
|  | 	void _SetCurrentLevel(const MapName map); //NOTE: This will modify the currentLevel variable without triggering anything else in-game, this will normally mess up the state in the game. Ideally this is only used when initializing a test level.
 | ||||||
| 
 | 
 | ||||||
| 	struct TileGroupData{ | 	struct TileGroupData{ | ||||||
| 		vi2d tilePos; | 		vi2d tilePos; | ||||||
|  | |||||||
| @ -167,3 +167,7 @@ const ItemInfo*ItemDrop::GetItem()const{ | |||||||
| const std::vector<ItemDrop>&ItemDrop::GetDrops(){ | const std::vector<ItemDrop>&ItemDrop::GetDrops(){ | ||||||
| 	return ItemDrop::drops; | 	return ItemDrop::drops; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | void ItemDrop::ClearDrops(){ | ||||||
|  | 	ItemDrop::drops.clear(); | ||||||
|  | } | ||||||
| @ -45,9 +45,6 @@ namespace MonsterTests{ | |||||||
| 
 | 
 | ||||||
| class ItemDrop{ | class ItemDrop{ | ||||||
| 	friend class AiL; | 	friend class AiL; | ||||||
| 	friend class MonsterTests::MonsterTest; |  | ||||||
| 	friend class PlayerTests::PlayerTest; |  | ||||||
| 	friend class ItemTests::ItemTest; |  | ||||||
| 	vf2d pos; | 	vf2d pos; | ||||||
| 	vf2d speed{}; | 	vf2d speed{}; | ||||||
| 	float zSpeed=0; | 	float zSpeed=0; | ||||||
| @ -66,6 +63,7 @@ public: | |||||||
| 	void Draw()const; | 	void Draw()const; | ||||||
| 	static void UpdateDrops(float fElapsedTime); | 	static void UpdateDrops(float fElapsedTime); | ||||||
| 	static const std::vector<ItemDrop>&GetDrops(); | 	static const std::vector<ItemDrop>&GetDrops(); | ||||||
|  | 	static void ClearDrops(); | ||||||
| 	float GetZ()const; | 	float GetZ()const; | ||||||
| 	static void SpawnItem(const ItemInfo*item,vf2d pos,bool isUpper); | 	static void SpawnItem(const ItemInfo*item,vf2d pos,bool isUpper); | ||||||
| 	const ItemInfo*GetItem()const; | 	const ItemInfo*GetItem()const; | ||||||
|  | |||||||
| @ -155,7 +155,17 @@ void ItemEnchantInfo::Initialize(){ | |||||||
| } | } | ||||||
| 	 | 	 | ||||||
| ItemEnchant::ItemEnchant(const std::string_view enchantName) | ItemEnchant::ItemEnchant(const std::string_view enchantName) | ||||||
| :enchantName(std::string(enchantName)){} | :enchantName(std::string(enchantName)){ | ||||||
|  | 	for(const auto&[attr,val]:ItemEnchantInfo::ENCHANT_LIST.at(this->enchantName).minStatModifiers){ | ||||||
|  | 		float minVal=ItemEnchantInfo::ENCHANT_LIST.at(this->enchantName).minStatModifiers.A_Read(attr); | ||||||
|  | 		float maxVal=ItemEnchantInfo::ENCHANT_LIST.at(this->enchantName).maxStatModifiers.A_Read(attr); | ||||||
|  | 		if(minVal==maxVal)A(attr)=minVal; | ||||||
|  | 		else{ | ||||||
|  | 			const auto&randRange{std::ranges::iota_view(int(minVal),int(maxVal))}; | ||||||
|  | 			A(attr)=randRange[util::random()%randRange.size()]; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| const ItemEnchantInfo&ItemEnchantInfo::GetEnchant(const std::string_view enchantName){ | const ItemEnchantInfo&ItemEnchantInfo::GetEnchant(const std::string_view enchantName){ | ||||||
| 	return ENCHANT_LIST.at(std::string(enchantName)); | 	return ENCHANT_LIST.at(std::string(enchantName)); | ||||||
|  | |||||||
| @ -1300,6 +1300,7 @@ void EntityStats::RecalculateEquipStats(){ | |||||||
| 		for(auto&[key,size]:ItemAttribute::attributes){ | 		for(auto&[key,size]:ItemAttribute::attributes){ | ||||||
| 			equipStats.A(key)+=equip.lock()->GetStats().A_Read(key); | 			equipStats.A(key)+=equip.lock()->GetStats().A_Read(key); | ||||||
| 			equipStats.A(key)+=equip.lock()->RandomStats().A_Read(key); | 			equipStats.A(key)+=equip.lock()->RandomStats().A_Read(key); | ||||||
|  | 			if(equip.lock()->HasEnchant())equipStats.A(key)+=equip.lock()->GetEnchant().value().A_Read(key); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -39,7 +39,7 @@ All rights reserved. | |||||||
| #define VERSION_MAJOR 1 | #define VERSION_MAJOR 1 | ||||||
| #define VERSION_MINOR 2 | #define VERSION_MINOR 2 | ||||||
| #define VERSION_PATCH 3 | #define VERSION_PATCH 3 | ||||||
| #define VERSION_BUILD 10532 | #define VERSION_BUILD 10538 | ||||||
| 
 | 
 | ||||||
| #define stringify(a) stringify_(a) | #define stringify(a) stringify_(a) | ||||||
| #define stringify_(a) #a | #define stringify_(a) #a | ||||||
|  | |||||||
| @ -937,8 +937,6 @@ namespace olc | |||||||
| 	class PixelGameEngine | 	class PixelGameEngine | ||||||
| 	{ | 	{ | ||||||
| 		friend class ViewPort; | 		friend class ViewPort; | ||||||
| 		friend class PlayerTests::PlayerTest; |  | ||||||
| 		friend class ItemTests::ItemTest; |  | ||||||
| 		struct StringDecalData{ | 		struct StringDecalData{ | ||||||
| 			char c; | 			char c; | ||||||
| 			vf2d sourcePos; | 			vf2d sourcePos; | ||||||
| @ -1205,6 +1203,8 @@ namespace olc | |||||||
| 		const uint8_t GetMosaicEffect()const; | 		const uint8_t GetMosaicEffect()const; | ||||||
| 		void SetMosaicEffect(uint8_t effectLevel); | 		void SetMosaicEffect(uint8_t effectLevel); | ||||||
| 
 | 
 | ||||||
|  | 		HWButton*const GetKeyboardState(uint8_t key); | ||||||
|  | 
 | ||||||
| 	public: | 	public: | ||||||
| 		static std::map<char,Pixel> charToColor; | 		static std::map<char,Pixel> charToColor; | ||||||
| 		static std::string Grey; | 		static std::string Grey; | ||||||
| @ -4396,6 +4396,9 @@ namespace olc | |||||||
| 	void PixelGameEngine::SetMosaicEffect(uint8_t effectLevel){ | 	void PixelGameEngine::SetMosaicEffect(uint8_t effectLevel){ | ||||||
| 		mosaic=std::max(uint8_t(1),effectLevel); | 		mosaic=std::max(uint8_t(1),effectLevel); | ||||||
| 	} | 	} | ||||||
|  | 	HWButton*const PixelGameEngine::GetKeyboardState(uint8_t key){ | ||||||
|  | 		return &pKeyboardState[key]; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	void PixelGameEngine::UpdateTextEntry() | 	void PixelGameEngine::UpdateTextEntry() | ||||||
| 	{ | 	{ | ||||||
|  | |||||||
										
											Binary file not shown.
										
									
								
							| @ -6,7 +6,7 @@ ItemConfiguration | |||||||
| 	Item Categories = ItemCategory.txt | 	Item Categories = ItemCategory.txt | ||||||
| 	Equipment = Equipment-test.txt | 	Equipment = Equipment-test.txt | ||||||
| 	Weapons = Weapons.txt | 	Weapons = Weapons.txt | ||||||
| 	Accessories = Accessories.txt | 	Accessories = Accessories-test.txt | ||||||
| } | } | ||||||
| Item | Item | ||||||
| { | { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user