Implement skeleton for Enchant Confirm Window. Make original ability functions static for player class ability retrieval. Add private static access internal functions. Remove check for non-existing animations for player (would just not change the animation if it doesn't exist). Release Build 11598.
This commit is contained in:
parent
0d7759b230
commit
1e7345d7b5
@ -118,13 +118,13 @@ namespace EnchantTests
|
||||
std::weak_ptr<Item>nullRing{Game::GiveAndEquipEnchantedRing("Aura of the Beast")};
|
||||
std::unordered_map<int,uint32_t>statDistribution;
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing.lock()->EnchantItem("Health Boost");
|
||||
nullRing.lock()->_EnchantItem("Health Boost");
|
||||
statDistribution[player->GetMaxHealth()]++;
|
||||
}
|
||||
Assert::AreEqual(size_t(3),statDistribution.size(),L"There should be three entries generated. If not, then the RNG picking is likely not working!");
|
||||
std::weak_ptr<Item>nullRing2{Game::GiveAndEquipEnchantedRing("Aura of the Beast",EquipSlot::RING2)};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing2.lock()->EnchantItem("Health Boost");
|
||||
nullRing2.lock()->_EnchantItem("Health Boost");
|
||||
Test::InRange(player->GetMaxHealth(),{106,110},L"Max Health not in expected range with two rings equipped.");
|
||||
}
|
||||
}
|
||||
@ -133,12 +133,12 @@ namespace EnchantTests
|
||||
Assert::AreEqual(100,player->GetAttack(),L"Player starts with 100 attack.");
|
||||
std::weak_ptr<Item>nullRing{Game::GiveAndEquipEnchantedRing("Attack Boost")};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing.lock()->EnchantItem("Attack Boost");
|
||||
nullRing.lock()->_EnchantItem("Attack Boost");
|
||||
Test::InRange(player->GetAttack(),{103,105},L"Attack not in expected range.");
|
||||
}
|
||||
std::weak_ptr<Item>nullRing2{Game::GiveAndEquipEnchantedRing("Attack Boost",EquipSlot::RING2)};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing2.lock()->EnchantItem("Attack Boost");
|
||||
nullRing2.lock()->_EnchantItem("Attack Boost");
|
||||
Test::InRange(player->GetAttack(),{106,110},L"Attack not in expected range with two rings equipped.");
|
||||
}
|
||||
}
|
||||
@ -146,12 +146,12 @@ namespace EnchantTests
|
||||
Assert::AreEqual(100.0_Pct,player->GetMoveSpdMult(),L"Player starts with 100% Movespd.");
|
||||
std::weak_ptr<Item>nullRing{Game::GiveAndEquipEnchantedRing("Movement Boost")};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing.lock()->EnchantItem("Movement Boost");
|
||||
nullRing.lock()->_EnchantItem("Movement Boost");
|
||||
Test::InRange(player->GetMoveSpdMult(),{103.0_Pct,105.0_Pct},L"Move Speed not in expected range.");
|
||||
}
|
||||
std::weak_ptr<Item>nullRing2{Game::GiveAndEquipEnchantedRing("Movement Boost",EquipSlot::RING2)};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing2.lock()->EnchantItem("Movement Boost");
|
||||
nullRing2.lock()->_EnchantItem("Movement Boost");
|
||||
Test::InRange(player->GetMoveSpdMult(),{106.0_Pct,110.0_Pct},L"Move Speed not in expected range with two rings equipped.");
|
||||
}
|
||||
}
|
||||
@ -159,12 +159,12 @@ namespace EnchantTests
|
||||
Assert::AreEqual(0.0_Pct,player->GetCooldownReductionPct(),L"Player starts with 0% CDR.");
|
||||
std::weak_ptr<Item>nullRing{Game::GiveAndEquipEnchantedRing("Ability Haste")};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing.lock()->EnchantItem("Ability Haste");
|
||||
nullRing.lock()->_EnchantItem("Ability Haste");
|
||||
Test::InRange(player->GetCooldownReductionPct(),{3.0_Pct,5.0_Pct},L"CDR not in expected range.");
|
||||
}
|
||||
std::weak_ptr<Item>nullRing2{Game::GiveAndEquipEnchantedRing("Ability Haste",EquipSlot::RING2)};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing2.lock()->EnchantItem("Ability Haste");
|
||||
nullRing2.lock()->_EnchantItem("Ability Haste");
|
||||
Test::InRange(player->GetCooldownReductionPct(),{6.0_Pct,10.0_Pct},L"CDR not in expected range with two rings.");
|
||||
}
|
||||
}
|
||||
@ -172,12 +172,12 @@ namespace EnchantTests
|
||||
Assert::AreEqual(0.0_Pct,player->GetCritRatePct(),L"Player starts with 0% Crit Rate.");
|
||||
std::weak_ptr<Item>nullRing{Game::GiveAndEquipEnchantedRing("Crit Rate")};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing.lock()->EnchantItem("Crit Rate");
|
||||
nullRing.lock()->_EnchantItem("Crit Rate");
|
||||
Test::InRange(player->GetCritRatePct(),{3.0_Pct,5.0_Pct},L"Crit Rate not in expected range.");
|
||||
}
|
||||
std::weak_ptr<Item>nullRing2{Game::GiveAndEquipEnchantedRing("Crit Rate",EquipSlot::RING2)};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing2.lock()->EnchantItem("Crit Rate");
|
||||
nullRing2.lock()->_EnchantItem("Crit Rate");
|
||||
Test::InRange(player->GetCritRatePct(),{6.0_Pct,10.0_Pct},L"Crit Rate not in expected range with two rings.");
|
||||
}
|
||||
}
|
||||
@ -185,12 +185,12 @@ namespace EnchantTests
|
||||
Assert::AreEqual(50.0_Pct,player->GetCritDmgPct(),L"Player starts with 50% Crit Damage.");
|
||||
std::weak_ptr<Item>nullRing{Game::GiveAndEquipEnchantedRing("Crit Damage")};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing.lock()->EnchantItem("Crit Damage");
|
||||
nullRing.lock()->_EnchantItem("Crit Damage");
|
||||
Test::InRange(player->GetCritDmgPct(),{57.0_Pct,60.0_Pct},L"Crit Damage not in expected range.");
|
||||
}
|
||||
std::weak_ptr<Item>nullRing2{Game::GiveAndEquipEnchantedRing("Crit Damage",EquipSlot::RING2)};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing2.lock()->EnchantItem("Crit Damage");
|
||||
nullRing2.lock()->_EnchantItem("Crit Damage");
|
||||
Test::InRange(player->GetCritDmgPct(),{64.0_Pct,70.0_Pct},L"Crit Damage not in expected range with two rings.");
|
||||
}
|
||||
}
|
||||
@ -198,12 +198,12 @@ namespace EnchantTests
|
||||
Assert::AreEqual(0.0_Pct,player->GetDamageReductionFromBuffs(),L"Player starts with 0% Damage Reduction.");
|
||||
std::weak_ptr<Item>nullRing{Game::GiveAndEquipEnchantedRing("Stoneskin")};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing.lock()->EnchantItem("Stoneskin");
|
||||
nullRing.lock()->_EnchantItem("Stoneskin");
|
||||
Test::InRange(player->GetDamageReductionFromBuffs(),{3.0_Pct,5.0_Pct},L"Damage Reduction not in expected range.");
|
||||
}
|
||||
std::weak_ptr<Item>nullRing2{Game::GiveAndEquipEnchantedRing("Stoneskin",EquipSlot::RING2)};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing2.lock()->EnchantItem("Stoneskin");
|
||||
nullRing2.lock()->_EnchantItem("Stoneskin");
|
||||
Test::InRange(player->GetDamageReductionFromBuffs(),{6.0_Pct,10.0_Pct},L"Damage Reduction not in expected range with two rings.");
|
||||
}
|
||||
}
|
||||
@ -211,12 +211,12 @@ namespace EnchantTests
|
||||
Assert::AreEqual(100,player->GetMaxMana(),L"Player starts with 100 mana.");
|
||||
std::weak_ptr<Item>nullRing{Game::GiveAndEquipEnchantedRing("Mana Pool")};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing.lock()->EnchantItem("Mana Pool");
|
||||
nullRing.lock()->_EnchantItem("Mana Pool");
|
||||
Test::InRange(player->GetMaxMana(),{107,112},L"Mana Pool not in expected range.");
|
||||
}
|
||||
std::weak_ptr<Item>nullRing2{Game::GiveAndEquipEnchantedRing("Mana Pool",EquipSlot::RING2)};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing2.lock()->EnchantItem("Mana Pool");
|
||||
nullRing2.lock()->_EnchantItem("Mana Pool");
|
||||
Test::InRange(player->GetMaxMana(),{114,124},L"Mana Pool not in expected range with two rings.");
|
||||
}
|
||||
}
|
||||
@ -227,7 +227,7 @@ namespace EnchantTests
|
||||
Assert::AreEqual(0.0_Pct,player->GetHP6RecoveryPct(),L"Player starts with 0% HP/6 recovery.");
|
||||
std::weak_ptr<Item>nullRing{Game::GiveAndEquipEnchantedRing("Magical Protection")};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing.lock()->EnchantItem("Magical Protection");
|
||||
nullRing.lock()->_EnchantItem("Magical Protection");
|
||||
Test::InRange(player->GetMaxHealth(),{102,103},L"Max Health not in expected range.");
|
||||
Test::InRange(player->GetDamageReductionFromBuffs(),{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.");
|
||||
@ -235,7 +235,7 @@ namespace EnchantTests
|
||||
}
|
||||
std::weak_ptr<Item>nullRing2{Game::GiveAndEquipEnchantedRing("Magical Protection",EquipSlot::RING2)};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing2.lock()->EnchantItem("Magical Protection");
|
||||
nullRing2.lock()->_EnchantItem("Magical Protection");
|
||||
Test::InRange(player->GetMaxHealth(),{102,103},L"Max Health not in expected range with two rings.");
|
||||
Test::InRange(player->GetDamageReductionFromBuffs(),{2.0_Pct,3.0_Pct},L"Damage Reduction not in expected range with two rings.");
|
||||
Test::InRange(player->GetMoveSpdMult(),{102.0_Pct,103.0_Pct},L"Move Speed % not in expected range with two rings.");
|
||||
@ -250,7 +250,7 @@ namespace EnchantTests
|
||||
Assert::AreEqual(50.0_Pct,player->GetCritDmgPct(),L"Player starts with 50% crit rate.");
|
||||
std::weak_ptr<Item>nullRing{Game::GiveAndEquipEnchantedRing("Aura of the Beast")};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing.lock()->EnchantItem("Aura of the Beast");
|
||||
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.");
|
||||
@ -258,7 +258,7 @@ namespace EnchantTests
|
||||
}
|
||||
std::weak_ptr<Item>nullRing2{Game::GiveAndEquipEnchantedRing("Aura of the Beast",EquipSlot::RING2)};
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
nullRing2.lock()->EnchantItem("Aura of the Beast");
|
||||
nullRing2.lock()->_EnchantItem("Aura of the Beast");
|
||||
Test::InRange(player->GetAttack(),{102,103},L"Attack not in expected range with two rings.");
|
||||
Test::InRange(player->GetCritRatePct(),{2.0_Pct,3.0_Pct},L"Crit Rate not in expected range with two rings.");
|
||||
Test::InRange(player->GetCooldownReductionPct(),{2.0_Pct,3.0_Pct},L"Cooldown Reduction % not in expected range with two rings.");
|
||||
|
@ -66,7 +66,7 @@ namespace Game{
|
||||
inline std::weak_ptr<Item>GiveAndEquipEnchantedRing(const std::string_view enchantName,const EquipSlot slot=EquipSlot::RING1){
|
||||
std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)};
|
||||
Inventory::EquipItem(nullRing,slot);
|
||||
nullRing.lock()->EnchantItem(enchantName);
|
||||
nullRing.lock()->_EnchantItem(enchantName);
|
||||
return nullRing;
|
||||
}
|
||||
}
|
||||
|
@ -251,14 +251,14 @@ namespace ItemTests
|
||||
std::weak_ptr<Item>slimeKingRing{Inventory::AddItem("Ring of the Slime King"s)};
|
||||
Assert::IsFalse(slimeKingRing.lock()->HasEnchant());
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
slimeKingRing.lock()->EnchantItem(ItemEnchant::RollRandomEnchant());
|
||||
slimeKingRing.lock()->_EnchantItem(ItemEnchant::RollRandomEnchant());
|
||||
Assert::IsTrue(slimeKingRing.lock()->HasEnchant());
|
||||
if(ItemEnchantInfo::ENCHANT_LIST.at(slimeKingRing.lock()->GetEnchant().value().Name()).GetClass().has_value())Assert::AreEqual(int(player->GetClass()),int(ItemEnchantInfo::ENCHANT_LIST.at(slimeKingRing.lock()->GetEnchant().value().Name()).GetClass().value())); //Validate enchant is only for this class if it's a class-based ability.
|
||||
}
|
||||
testGame->ChangePlayerClass(WIZARD);
|
||||
player=testGame->GetPlayer(); //The player pointer has been reassigned...
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
slimeKingRing.lock()->EnchantItem(ItemEnchant::RollRandomEnchant());
|
||||
slimeKingRing.lock()->_EnchantItem(ItemEnchant::RollRandomEnchant());
|
||||
Assert::IsTrue(slimeKingRing.lock()->HasEnchant());
|
||||
if(ItemEnchantInfo::ENCHANT_LIST.at(slimeKingRing.lock()->GetEnchant().value().Name()).GetClass().has_value())Assert::AreEqual(int(player->GetClass()),int(ItemEnchantInfo::ENCHANT_LIST.at(slimeKingRing.lock()->GetEnchant().value().Name()).GetClass().value())); //Validate enchant is only for this class if it's a class-based ability.
|
||||
}
|
||||
@ -277,6 +277,8 @@ namespace ItemTests
|
||||
std::weak_ptr<Item>extraRing{Inventory::AddItem("Ring of the Slime King"s)};
|
||||
std::unordered_map<ItemEnchantInfo::ItemEnchantCategory,uint32_t>enchantCounts;
|
||||
for(int i:std::ranges::iota_view(0,1000)){
|
||||
Inventory::AddItem(extraRing.lock()->FragmentName(),"Fragment Enchant Cost"_i[0]);
|
||||
player->AddMoney("Fragment Enchant Cost"_i[1]);
|
||||
ItemEnchantInfo resultEnchant{extraRing.lock()->ApplyRandomEnchant()};
|
||||
if(resultEnchant.GetClass().has_value())Assert::AreEqual(int(resultEnchant.GetClass().value()),int(player->GetClass()),L"Player's class matches the class of the enchant.");
|
||||
enchantCounts[resultEnchant.Category()]++;
|
||||
@ -296,5 +298,23 @@ namespace ItemTests
|
||||
Assert::AreEqual("Item Enchants.Class Enchants.Enchant Display Color"_Pixel.n,ItemEnchantInfo::GetEnchant("Quickdraw").DisplayCol().n,L"Expecting a class enchant to have the class enchant pixel display color.");
|
||||
Assert::AreEqual("Item Enchants.Unique Enchants.Enchant Display Color"_Pixel.n,ItemEnchantInfo::GetEnchant("Magical Protection").DisplayCol().n,L"Expecting a unique enchant to have the unique enchant pixel display color.");
|
||||
}
|
||||
TEST_METHOD(CanBeEnchantedTest){
|
||||
std::weak_ptr<Item>extraRing{Inventory::AddItem("Ring of the Slime King"s)};
|
||||
std::weak_ptr<Item>testArmor{Inventory::AddItem("Test Armor"s)};
|
||||
Assert::AreEqual(false,extraRing.lock()->CanBeEnchanted(),L"We don't have the money nor required fragments to enchant this item.");
|
||||
Assert::AreEqual(false,testArmor.lock()->CanBeEnchanted(),L"We can't enchant armor.");
|
||||
player->SetMoney(2000U);
|
||||
Assert::AreEqual(false,extraRing.lock()->CanBeEnchanted(),L"We don't have the required fragments to enchant this item.");
|
||||
player->SetMoney(0U);
|
||||
Inventory::AddItem(extraRing.lock()->FragmentName(),"Fragment Enchant Cost"_i[0]);
|
||||
Assert::AreEqual(false,extraRing.lock()->CanBeEnchanted(),L"We don't have the required money to enchant this item.");
|
||||
player->SetMoney(2000U);
|
||||
Assert::AreEqual(true,extraRing.lock()->CanBeEnchanted(),L"We don't have the required money to enchant this item.");
|
||||
extraRing.lock()->ApplyRandomEnchant();
|
||||
Assert::AreEqual(false,extraRing.lock()->CanBeEnchanted(),L"Ring cannot be enchanted again due to consumption of fragments.");
|
||||
Inventory::AddItem(extraRing.lock()->FragmentName(),"Fragment Enchant Cost"_i[0]);
|
||||
Assert::AreEqual(true,extraRing.lock()->CanBeEnchanted(),L"Ring can be enchanted again with the right amount of fragments.");
|
||||
Assert::AreEqual(uint32_t(2000-"Fragment Enchant Cost"_i[1]),player->GetMoney(),util::wformat("Lost {} money due to enchanting ring.","Fragment Enchant Cost"_i[1]).c_str());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -629,17 +629,17 @@ namespace PlayerTests
|
||||
TEST_METHOD(HasEnchantCheck){
|
||||
std::weak_ptr<Item>slimeKingRing{Inventory::AddItem("Ring of the Slime King"s)};
|
||||
Inventory::EquipItem(slimeKingRing,EquipSlot::RING1);
|
||||
slimeKingRing.lock()->EnchantItem("Emergency Recovery");
|
||||
slimeKingRing.lock()->_EnchantItem("Emergency Recovery");
|
||||
Assert::IsTrue(player->HasEnchant("Emergency Recovery"));
|
||||
Inventory::EquipItem(slimeKingRing,EquipSlot::RING2);
|
||||
Assert::IsTrue(player->HasEnchant("Emergency Recovery"));
|
||||
Inventory::EquipItem(slimeKingRing,EquipSlot::RING1);
|
||||
slimeKingRing.lock()->EnchantItem("Reaper of Souls");
|
||||
slimeKingRing.lock()->_EnchantItem("Reaper of Souls");
|
||||
Assert::IsTrue(player->HasEnchant("Reaper of Souls"));
|
||||
Inventory::EquipItem(slimeKingRing,EquipSlot::RING2);
|
||||
Assert::IsTrue(player->HasEnchant("Reaper of Souls"));
|
||||
Inventory::EquipItem(slimeKingRing,EquipSlot::RING1);
|
||||
slimeKingRing.lock()->EnchantItem("Attack Boost");
|
||||
slimeKingRing.lock()->_EnchantItem("Attack Boost");
|
||||
Assert::IsTrue(player->HasEnchant("Attack Boost"));
|
||||
Inventory::EquipItem(slimeKingRing,EquipSlot::RING2);
|
||||
Assert::IsTrue(player->HasEnchant("Attack Boost"));
|
||||
@ -658,18 +658,18 @@ namespace PlayerTests
|
||||
Inventory::EquipItem(leatherShoes,EquipSlot::SHOES);
|
||||
Inventory::EquipItem(woodenSword,EquipSlot::WEAPON);
|
||||
|
||||
leatherHelmet.lock()->EnchantItem("Wizard's Soul");
|
||||
leatherHelmet.lock()->_EnchantItem("Wizard's Soul");
|
||||
Assert::IsTrue(player->HasEnchant("Wizard's Soul"));
|
||||
leatherArmor.lock()->EnchantItem("Ability Haste");
|
||||
leatherArmor.lock()->_EnchantItem("Ability Haste");
|
||||
Assert::IsTrue(player->HasEnchant("Ability Haste"));
|
||||
leatherPants.lock()->EnchantItem("Improved Ground Slam");
|
||||
leatherPants.lock()->_EnchantItem("Improved Ground Slam");
|
||||
Assert::IsTrue(player->HasEnchant("Improved Ground Slam"));
|
||||
leatherGloves.lock()->EnchantItem("Battle Shout");
|
||||
leatherGloves.lock()->_EnchantItem("Battle Shout");
|
||||
Assert::IsTrue(player->HasEnchant("Battle Shout"));
|
||||
leatherShoes.lock()->EnchantItem("Attack Boost");
|
||||
leatherShoes.lock()->_EnchantItem("Attack Boost");
|
||||
Inventory::UnequipItem(EquipSlot::RING2);
|
||||
Assert::IsTrue(player->HasEnchant("Attack Boost"));
|
||||
woodenSword.lock()->EnchantItem("Mana Pool");
|
||||
woodenSword.lock()->_EnchantItem("Mana Pool");
|
||||
Assert::IsTrue(player->HasEnchant("Mana Pool"));
|
||||
|
||||
Inventory::UnequipItem(EquipSlot::HELMET);
|
||||
@ -744,7 +744,7 @@ namespace PlayerTests
|
||||
player->GetAbility3().cooldown=player->GetAbility3().GetCooldownTime();
|
||||
std::weak_ptr<Item>nullRing{Inventory::AddItem("Null Ring"s)};
|
||||
Inventory::EquipItem(nullRing,EquipSlot::RING1);
|
||||
nullRing.lock()->EnchantItem("Multi-Multishot");
|
||||
nullRing.lock()->_EnchantItem("Multi-Multishot");
|
||||
testKey->bHeld=true; //Force the key to be held down for testing purposes.
|
||||
Assert::AreEqual(player->GetAbility3().GetCooldownTime(),oldCooldownTime-oldCooldownTime*"Multi-Multishot"_ENC["COOLDOWN REDUCTION PCT"]/100.f,L"Old cooldown time with multishot cooldown reduction pct matches.");
|
||||
testGame->SetElapsedTime(0.f);
|
||||
|
@ -436,7 +436,7 @@ bool AiL::OnConsoleCommand(const std::string& sCommand){
|
||||
if(args[0]=="/accessory"){
|
||||
if(args.size()<2)ConsoleOut()<<"Usage: /accessory <Accessory Name> [Enchant Name]"<<std::endl;
|
||||
std::weak_ptr<Item>accessory{Inventory::AddItem(args[1])};
|
||||
if(args.size()>=3)accessory.lock()->EnchantItem(args[2]);
|
||||
if(args.size()>=3)accessory.lock()->_EnchantItem(args[2]);
|
||||
ConsoleOut()<<"Added "<<args[1]<<" to player's inventory."<<std::endl;
|
||||
}else{
|
||||
ConsoleOut()<<"Invalid command! Use /help to see available commands."<<std::endl;
|
||||
@ -2988,6 +2988,7 @@ void AiL::ChangePlayerClass(Class cl){
|
||||
player->OnLevelStart();
|
||||
player->timers=oldTimers;
|
||||
player->shield=previousShield;
|
||||
player->SetAbility4(Thief::GetOriginalAbility2());
|
||||
}
|
||||
|
||||
void AiL::InitializeClasses(){
|
||||
|
@ -38,11 +38,41 @@ All rights reserved.
|
||||
|
||||
#include "Menu.h"
|
||||
#include "AdventuresInLestoria.h"
|
||||
#include "MenuLabel.h"
|
||||
#include "MenuIconButton.h"
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
void Menu::InitializeArtificerEnchantConfirmWindow(){
|
||||
Menu*artificerEnchantConfirmWindow=CreateMenu(ARTIFICER_ENCHANT_CONFIRM,CENTERED,vi2d{144,144});
|
||||
Menu*artificerEnchantConfirmWindow=CreateMenu(ARTIFICER_ENCHANT_CONFIRM,CENTERED,vi2d{240,144});
|
||||
|
||||
auto enchantSuccessLabel{artificerEnchantConfirmWindow->ADD("Enchant Success Label",MenuLabel)(geom2d::rect<float>{{0.f,-14.f},vf2d{artificerEnchantConfirmWindow->size.x,12.f}},"Enchantment Success!",1.f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END};
|
||||
|
||||
auto chooseResultLabel{artificerEnchantConfirmWindow->ADD("Choose Result Label",MenuLabel)(geom2d::rect<float>{vf2d{0.f,0.f},vf2d{artificerEnchantConfirmWindow->size.x,12.f}},"Choose a Result",1.f,ComponentAttr::SHADOW)END};
|
||||
|
||||
const float oldLabelTextWidth{game->GetTextSize("OLD").x*2.f};
|
||||
auto oldLabel{artificerEnchantConfirmWindow->ADD("Old Item Label",MenuLabel)(geom2d::rect<float>{{artificerEnchantConfirmWindow->size.x/4.f-oldLabelTextWidth/2-4.f,14.f},vf2d{oldLabelTextWidth+8.f,24.f}},"OLD",2.f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END};
|
||||
|
||||
const float newLabelTextWidth{game->GetTextSize("NEW").x*2.f};
|
||||
auto newLabel{artificerEnchantConfirmWindow->ADD("New Item Label",MenuLabel)(geom2d::rect<float>{{artificerEnchantConfirmWindow->size.x/2.f+artificerEnchantConfirmWindow->size.x/4.f-oldLabelTextWidth/2+2.f,14.f},vf2d{oldLabelTextWidth+8.f,24.f}},"NEW",2.f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END};
|
||||
|
||||
auto oldIcon{artificerEnchantConfirmWindow->ADD("Old Item Icon",MenuIconButton)(geom2d::rect<float>{{artificerEnchantConfirmWindow->size.x/4.f-12.f,42.f},{24,24}},nullptr,DO_NOTHING,IconButtonAttr::NOT_SELECTABLE)END};
|
||||
auto newIcon{artificerEnchantConfirmWindow->ADD("New Item Icon",MenuIconButton)(geom2d::rect<float>{{artificerEnchantConfirmWindow->size.x/2.f+artificerEnchantConfirmWindow->size.x/4.f-12.f+4.f,42.f},{24,24}},nullptr,DO_NOTHING,IconButtonAttr::NOT_SELECTABLE)END};
|
||||
|
||||
auto oldItemDescription{artificerEnchantConfirmWindow->ADD("Old Item Description",MenuLabel)(geom2d::rect<float>{{0.f,74.f},{artificerEnchantConfirmWindow->size.x/2.f-8.f,60.f}},"",0.5f,ComponentAttr::SHADOW|ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)END};
|
||||
auto newItemDescription{artificerEnchantConfirmWindow->ADD("New Item Description",MenuLabel)(geom2d::rect<float>{{artificerEnchantConfirmWindow->size.x/2.f+8.f,74.f},{artificerEnchantConfirmWindow->size.x/2.f-8.f,60.f}},"",0.5f,ComponentAttr::SHADOW|ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)END};
|
||||
|
||||
const float takeOldTextWidth{float(game->GetTextSize("Take Old").x)*2.f};
|
||||
auto takeOldButton{artificerEnchantConfirmWindow->ADD("Take Old Button",MenuComponent)(geom2d::rect<float>{{artificerEnchantConfirmWindow->size.x/4.f-takeOldTextWidth/2.f,138.f},{takeOldTextWidth,20.f}},"Take Old",[](MenuFuncData data){
|
||||
onClick:
|
||||
return true;
|
||||
},vf2d{2.f,2.f})END};
|
||||
|
||||
const float takeNewTextWidth{float(game->GetTextSize("Take New").x)*2.f};
|
||||
auto takeNewButton{artificerEnchantConfirmWindow->ADD("Take New Button",MenuComponent)(geom2d::rect<float>{vf2d{artificerEnchantConfirmWindow->size.x/2.f+8.f+artificerEnchantConfirmWindow->size.x/4.f-takeNewTextWidth/2.f,138.f},{takeNewTextWidth,20.f}},"Take New",[](MenuFuncData data){
|
||||
onClick:
|
||||
return true;
|
||||
},vf2d{2.f,2.f})END};
|
||||
|
||||
artificerEnchantConfirmWindow->SetupKeyboardNavigation(
|
||||
[](MenuType type,Data&returnData){ //On Open
|
||||
@ -51,7 +81,7 @@ void Menu::InitializeArtificerEnchantConfirmWindow(){
|
||||
{ //Button Key
|
||||
{game->KEY_SCROLL,{"Navigate",[](MenuType type){}}},
|
||||
{game->KEY_BACK,{"Stay",[](MenuType type){
|
||||
Menu::CloseMenu();
|
||||
|
||||
}}},
|
||||
{game->KEY_CONFIRM,{"Select",[](MenuType type){}}},
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ All rights reserved.
|
||||
#include "MenuLabel.h"
|
||||
#include "MenuDecal.h"
|
||||
#include "PlayerMoneyLabel.h"
|
||||
#include "SoundEffect.h"
|
||||
|
||||
INCLUDE_game
|
||||
|
||||
@ -59,18 +60,43 @@ void Menu::InitializeArtificerEnchantWindow(){
|
||||
|
||||
auto accessoryDescription{artificerEnchantWindow->ADD("Item Description",MenuLabel)(geom2d::rect<float>{{artificerEnchantWindow->size.x/2+56.f,16.f},{artificerEnchantWindow->size.x/2-40.f,72.f}},"",0.5f,ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE|ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END};
|
||||
|
||||
const auto ResetRefineDisplay{[artificerEnchantWindow](){
|
||||
const auto ResetEnchantDisplay{[artificerEnchantWindow](){
|
||||
MenuType menuType{artificerEnchantWindow->GetType()};
|
||||
Component<MenuItemItemButton>(menuType,"Item Icon")->SetItem(Item::BLANK);
|
||||
Component<ScrollableWindowComponent>(menuType,"Enchant Container")->Disable();
|
||||
Component<MenuLabel>(menuType,"Enchant List Header")->Disable();
|
||||
Component<MenuLabel>(menuType,"Enchant Cost Label")->Disable();
|
||||
Component<MenuDecal>(menuType,"Fragment Cost Icon")->Disable();
|
||||
Component<MenuLabel>(menuType,"Fragment Label")->Disable();
|
||||
Component<MenuLabel>(menuType,"Fragment Money Cost Label")->Disable();
|
||||
Component<MenuComponent>(menuType,"Fragment Enchant Button")->Disable();
|
||||
}};
|
||||
const auto EnableRefineDisplay{[artificerEnchantWindow](){
|
||||
const auto EnableEnchantDisplay{[artificerEnchantWindow](){
|
||||
MenuType menuType{artificerEnchantWindow->GetType()};
|
||||
const std::weak_ptr<Item>&selectedItem{Component<MenuItemItemButton>(menuType,"Item Icon")->GetItem()};
|
||||
std::vector<ItemEnchantInfo>availableEnchants{ItemEnchant::GetAvailableEnchants()};
|
||||
std::sort(availableEnchants.begin(),availableEnchants.end(),[](const ItemEnchantInfo&enchant1,const ItemEnchantInfo&enchant2){
|
||||
return enchant1.Category()!=enchant2.Category()?int(enchant1.Category())<int(enchant2.Category()):enchant1.Name()<enchant2.Name();
|
||||
});
|
||||
std::string enchantList{std::accumulate(availableEnchants.begin(),availableEnchants.end(),""s,[](const std::string&acc,const ItemEnchantInfo&enchant){
|
||||
return std::format("{}{}{}#FFFFFF\n",acc,enchant.DisplayCol().toHTMLColorCode(),enchant.Name());
|
||||
})};
|
||||
Component<ScrollableWindowComponent>(menuType,"Enchant Container")->Enable();
|
||||
Component<MenuLabel>(menuType,"Enchant List")->SetLabel(enchantList);
|
||||
Component<MenuLabel>(menuType,"Enchant List Header")->Enable();
|
||||
Component<MenuLabel>(menuType,"Enchant Cost Label")->Enable();
|
||||
Component<MenuDecal>(menuType,"Fragment Cost Icon")->Enable();
|
||||
Component<MenuDecal>(menuType,"Fragment Cost Icon")->SetImage(GFX.at(selectedItem.lock()->FragmentIcon().value()));
|
||||
Component<MenuLabel>(menuType,"Fragment Label")->Enable();
|
||||
Component<MenuLabel>(menuType,"Fragment Money Cost Label")->Enable();
|
||||
Component<MenuComponent>(menuType,"Fragment Enchant Button")->Enable();
|
||||
Component<MenuComponent>(menuType,"Fragment Enchant Button")->SetGrayedOut(!selectedItem.lock()->CanBeEnchanted());
|
||||
|
||||
const std::string_view fragmentName{selectedItem.lock()->FragmentName()};
|
||||
const Pixel fragmentItemDisplayCol{Inventory::GetItemCount(fragmentName)>="Fragment Enchant Cost"_i[0]?WHITE:RED};
|
||||
const Pixel moneyCostDisplayCol{game->GetPlayer()->GetMoney()>="Fragment Enchant Cost"_i[1]?WHITE:RED};
|
||||
Component<MenuLabel>(menuType,"Fragment Label")->SetLabel(std::format("{}{} x{} ({})",fragmentItemDisplayCol.toHTMLColorCode(),fragmentName,"Fragment Enchant Cost"_i[0],Inventory::GetItemCount(fragmentName)));
|
||||
Component<MenuLabel>(menuType,"Fragment Money Cost Label")->SetLabel(std::format("{}{} gold",moneyCostDisplayCol.toHTMLColorCode(),"Fragment Enchant Cost"_i[1]));
|
||||
}};
|
||||
|
||||
auto inventoryDisplay{artificerEnchantWindow->ADD("Accessory List",RowInventoryScrollableWindowComponent)(geom2d::rect<float>{{0.f,28.f},{artificerEnchantWindow->size.x/2-4.f,artificerEnchantWindow->size.y-44}},"","",[](MenuFuncData data){
|
||||
@ -78,18 +104,18 @@ void Menu::InitializeArtificerEnchantWindow(){
|
||||
RowItemDisplay&item{*DYNAMIC_POINTER_CAST<RowItemDisplay>(data.component)};
|
||||
DYNAMIC_POINTER_CAST<RowInventoryScrollableWindowComponent>(data.parentComponent.lock())->SelectChild(DYNAMIC_POINTER_CAST<RowItemDisplay>(data.component));
|
||||
return true;
|
||||
},[EnableRefineDisplay](MenuFuncData data){OnHover:
|
||||
},[EnableEnchantDisplay](MenuFuncData data){OnHover:
|
||||
RowItemDisplay&item{*DYNAMIC_POINTER_CAST<RowItemDisplay>(data.component)};
|
||||
Component<MenuItemItemButton>(data.menu.type,"Item Icon")->SetItem(item.GetItem());
|
||||
EnableRefineDisplay();
|
||||
EnableEnchantDisplay();
|
||||
return true;
|
||||
},[ResetRefineDisplay,EnableRefineDisplay](MenuFuncData data){OnMouseOut:
|
||||
ResetRefineDisplay();
|
||||
},[ResetEnchantDisplay,EnableEnchantDisplay](MenuFuncData data){OnMouseOut:
|
||||
ResetEnchantDisplay();
|
||||
auto childComponent{DYNAMIC_POINTER_CAST<RowInventoryScrollableWindowComponent>(data.parentComponent.lock())->GetSelectedChild()};
|
||||
if(childComponent){
|
||||
RowItemDisplay&item{childComponent.value().get()};
|
||||
Component<MenuItemItemButton>(data.menu.type,"Item Icon")->SetItem(item.GetItem());
|
||||
EnableRefineDisplay();
|
||||
EnableEnchantDisplay();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@ -107,9 +133,15 @@ void Menu::InitializeArtificerEnchantWindow(){
|
||||
auto fragmentDisplayLabel{artificerEnchantWindow->ADD("Fragment Label",MenuLabel)(geom2d::rect<float>{{artificerEnchantWindow->size.x/2+80.f,152.f},{artificerEnchantWindow->size.x/2-60.f,12.f}},"",1.f,ComponentAttr::SHADOW|ComponentAttr::FIT_TO_LABEL|ComponentAttr::LEFT_ALIGN)END};
|
||||
auto fragmentMoneyCostLabel{artificerEnchantWindow->ADD("Fragment Money Cost Label",MenuLabel)(geom2d::rect<float>{{artificerEnchantWindow->size.x/2+80.f,164.f},{artificerEnchantWindow->size.x/2-60.f,12.f}},"",1.f,ComponentAttr::SHADOW|ComponentAttr::LEFT_ALIGN)END};
|
||||
|
||||
auto fragmentEnchantButton{artificerEnchantWindow->ADD("Fragment Enchant Button",MenuComponent)(geom2d::rect<float>{{artificerEnchantWindow->size.x/2+96.f,180.f},{artificerEnchantWindow->size.x/2-80.f,12.f}},"Enchant",[EnableRefineDisplay](MenuFuncData data){
|
||||
auto fragmentEnchantButton{artificerEnchantWindow->ADD("Fragment Enchant Button",MenuComponent)(geom2d::rect<float>{{artificerEnchantWindow->size.x/2+96.f,180.f},{artificerEnchantWindow->size.x/2-80.f,12.f}},"Enchant",[EnableEnchantDisplay](MenuFuncData data){
|
||||
onClick:
|
||||
EnableRefineDisplay(); //Refresh the current display contents.
|
||||
EnableEnchantDisplay(); //Refresh the current display contents.
|
||||
SoundEffect::PlaySFX("Enchant Item",SoundEffect::CENTERED);
|
||||
std::weak_ptr<Item>item{Component<MenuItemItemButton>(data.menu.type,"Item Icon")->GetItem()};
|
||||
std::optional<ItemEnchant>previousEnchant{item.lock()->GetEnchant()};
|
||||
item.lock()->ApplyRandomEnchant();
|
||||
const ItemEnchant&newEnchant{item.lock()->GetEnchant().value()};
|
||||
//TODO: Do stuff with this info.
|
||||
Menu::OpenMenu(ARTIFICER_ENCHANT_CONFIRM,true);
|
||||
return true;
|
||||
})END};
|
||||
|
@ -124,7 +124,7 @@ void Menu::InitializeArtificerRefineWindow(){
|
||||
|
||||
auto fragmentRefineButton{artificerRefineWindow->ADD("Fragment Refine Button",MenuComponent)(geom2d::rect<float>{{artificerRefineWindow->size.x/2+96.f,180.f},{artificerRefineWindow->size.x/2-80.f,12.f}},"Refine",[EnableRefineDisplay](MenuFuncData data){
|
||||
onClick:
|
||||
SoundEffect::PlaySFX("Sprint",SoundEffect::CENTERED);
|
||||
SoundEffect::PlaySFX("Refine Item",SoundEffect::CENTERED);
|
||||
std::weak_ptr<Item>item{Component<MenuItemItemButton>(data.menu.type,"Item Icon")->GetItem()};
|
||||
RefineResult result{item.lock()->Refine()};
|
||||
Component<MenuItemItemButton>(ARTIFICER_REFINE_RESULT,"Item Icon")->SetItem(item);
|
||||
|
@ -62,6 +62,7 @@ void Menu::InitializeArtificerWindow(){
|
||||
},vf2d{2.f,2.f},ButtonAttr::FIT_TO_LABEL)END;
|
||||
artificerWindow->ADD("Enchant Button",MenuComponent)(geom2d::rect<float>{{0.f,60.f},{144.f,24.f}},"Enchant",[](MenuFuncData data){
|
||||
Menu::OpenMenu(MenuType::ARTIFICER_ENCHANT);
|
||||
Component<RowInventoryScrollableWindowComponent>(MenuType::ARTIFICER_ENCHANT,"Accessory List")->ClearSelectedChild();
|
||||
return true;
|
||||
},vf2d{2.f,2.f},ButtonAttr::FIT_TO_LABEL)END;
|
||||
artificerWindow->ADD("Help Button",MenuComponent)(geom2d::rect<float>{{0.f,88.f},{144.f,24.f}},"Help",[](MenuFuncData data){
|
||||
|
@ -70,7 +70,7 @@ void Menu::InitializeCraftItemWindow(){
|
||||
for(const auto&[name,amt]:consumedResources.GetItems()){
|
||||
Inventory::RemoveItem(Inventory::GetItem(name)[0],amt);
|
||||
}
|
||||
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-consumedResources.GetCost());
|
||||
game->GetPlayer()->RemoveMoney(consumedResources.GetCost());
|
||||
|
||||
Inventory::UpdateBlacksmithInventoryLists();
|
||||
SoundEffect::PlaySFX("Craft Equip",SoundEffect::CENTERED);
|
||||
|
@ -121,6 +121,10 @@ Ability&class::GetAbility1(){return ability1;}; \
|
||||
Ability&class::GetAbility2(){return ability2;}; \
|
||||
Ability&class::GetAbility3(){return ability3;}; \
|
||||
Ability&class::GetAbility4(){return ability4;}; \
|
||||
Ability&class::_GetOriginalAbility1(){return GetOriginalAbility1();}; \
|
||||
Ability&class::_GetOriginalAbility2(){return GetOriginalAbility2();}; \
|
||||
Ability&class::_GetOriginalAbility3(){return GetOriginalAbility2();}; \
|
||||
Ability&class::_GetOriginalRightClickAbility(){return GetOriginalRightClickAbility();}; \
|
||||
Ability&class::GetOriginalAbility1(){return original_ability1;}; \
|
||||
Ability&class::GetOriginalAbility2(){return original_ability2;}; \
|
||||
Ability&class::GetOriginalAbility3(){return original_ability3;}; \
|
||||
|
@ -1034,7 +1034,7 @@ void Item::EnhanceItem(uint8_t qty){
|
||||
for(const auto&[name,amt]:consumedResources.GetItems()){
|
||||
Inventory::RemoveItem(Inventory::GetItem(name)[0],amt);
|
||||
}
|
||||
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-consumedResources.GetCost());
|
||||
game->GetPlayer()->RemoveMoney(consumedResources.GetCost());
|
||||
|
||||
SoundEffect::PlaySFX("Enhance Item",SoundEffect::CENTERED);
|
||||
|
||||
@ -1047,7 +1047,7 @@ void Item::EnhanceItem(uint8_t qty){
|
||||
for(const auto&[name,amt]:consumedResources.GetItems()){
|
||||
Inventory::RemoveItem(Inventory::GetItem(name)[0],amt);
|
||||
}
|
||||
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-consumedResources.GetCost());
|
||||
game->GetPlayer()->RemoveMoney(consumedResources.GetCost());
|
||||
}
|
||||
}
|
||||
SoundEffect::PlaySFX("Craft Item",SoundEffect::CENTERED);
|
||||
@ -1441,10 +1441,14 @@ const bool Item::CanBeRefined()const{
|
||||
return false; //Maxed out, so cannot be refined.
|
||||
}
|
||||
|
||||
const bool Item::CanBeEnchanted()const{
|
||||
return IsAccessory()&&Inventory::GetItemCount(FragmentName())>="Fragment Enchant Cost"_i[0]&&game->GetPlayer()->GetMoney()>="Fragment Enchant Cost"_i[1];
|
||||
}
|
||||
|
||||
RefineResult Item::Refine(){
|
||||
if(!CanBeRefined())ERR("WARNING! Trying to refine an item that cannot be refined! Make sure you are checking with CanBeRefined() before calling this function!");
|
||||
Inventory::RemoveItem(FragmentName(),"Fragment Refine Cost"_i[0]);
|
||||
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-"Fragment Refine Cost"_i[1]);
|
||||
game->GetPlayer()->RemoveMoney("Fragment Refine Cost"_i[1]);
|
||||
std::vector<ItemAttribute>statsAvailableForRefining;
|
||||
for(const auto&[attr,val]:randomizedStats){
|
||||
float maxVal{ITEM_DATA[ActualName()].GetMaxStats().A_Read(attr)};
|
||||
@ -1461,13 +1465,13 @@ RefineResult Item::Refine(){
|
||||
return RefineResult{chosenAttr,newAmt-oldAmt};
|
||||
}
|
||||
|
||||
void Item::EnchantItem(const std::string_view enchantName){
|
||||
void Item::_EnchantItem(const std::string_view enchantName){
|
||||
enchant=ItemEnchant{enchantName};
|
||||
|
||||
game->GetPlayer()->RecalculateEquipStats();
|
||||
}
|
||||
|
||||
std::optional<ItemEnchant>Item::GetEnchant()const{
|
||||
const std::optional<ItemEnchant>&Item::GetEnchant()const{
|
||||
return enchant;
|
||||
}
|
||||
const bool Item::HasEnchant()const{
|
||||
@ -1524,7 +1528,10 @@ const std::optional<std::string>&Item::FragmentIcon()const{
|
||||
}
|
||||
|
||||
const ItemEnchantInfo Item::ApplyRandomEnchant(){
|
||||
if(!CanBeEnchanted())ERR("WARNING! Trying to enchant an item that cannot be enchanted! Make sure you are checking with CanBeEnchanted() before calling this function!");
|
||||
EnchantName randomEnchantName{ItemEnchant::RollRandomEnchant()};
|
||||
EnchantItem(randomEnchantName);
|
||||
_EnchantItem(randomEnchantName);
|
||||
Inventory::RemoveItem(FragmentName(),"Fragment Enchant Cost"_i[0]);
|
||||
game->GetPlayer()->RemoveMoney("Fragment Enchant Cost"_i[1]);
|
||||
return ItemEnchantInfo::GetEnchant(randomEnchantName);
|
||||
}
|
@ -254,11 +254,15 @@ public:
|
||||
//Assumes an item can be refined. CHECK WITH CanBeRefined() First!!!
|
||||
//Refines a random stat by the parameters defined in the Accessories.txt configuration file. Also takes away the costs required to refine the item.
|
||||
RefineResult Refine();
|
||||
const bool CanBeEnchanted()const;
|
||||
void Lock();
|
||||
void Unlock();
|
||||
void EnchantItem(const std::string_view enchantName);
|
||||
void _EnchantItem(const std::string_view enchantName);
|
||||
//Applies a random valid enchant to an item and consumes the materials in the process.
|
||||
//Assumes an item can be enchanted. CHECK WITH CanBeEnchanted() First!!!
|
||||
//Enchants the item based on its class parameters defined in the ItemEnchants.txt configuration file. Also takes away the costs required to refine the item (Located in Accessories.txt).
|
||||
const ItemEnchantInfo ApplyRandomEnchant();
|
||||
std::optional<ItemEnchant>GetEnchant()const;
|
||||
const std::optional<ItemEnchant>&GetEnchant()const;
|
||||
const bool HasEnchant()const;
|
||||
friend const bool operator==(std::shared_ptr<Item>lhs,std::shared_ptr<Item>rhs){return lhs->it==rhs->it&&lhs->randomizedStats==rhs->randomizedStats;};
|
||||
friend const bool operator==(std::shared_ptr<Item>lhs,const IT&rhs){return lhs->ActualName()==const_cast<IT&>(rhs);};
|
||||
|
@ -184,7 +184,7 @@ void Merchant::PurchaseItem(IT item,uint32_t amt){
|
||||
}
|
||||
|
||||
Inventory::AddItem(item,amt);
|
||||
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()-totalCost);
|
||||
game->GetPlayer()->RemoveMoney(totalCost);
|
||||
}
|
||||
void Merchant::SellItem(std::weak_ptr<Item>item,uint32_t amt){
|
||||
sellFunctionPrimed.Validate(item.lock()->ActualName(),amt);
|
||||
@ -222,7 +222,7 @@ void Merchant::SellItem(std::weak_ptr<Item>item,uint32_t amt){
|
||||
std::string itemName=item.lock()->ActualName(); //We need the item name since our reference to the item is about to be deleted.
|
||||
|
||||
Inventory::RemoveItem(item,amt);
|
||||
game->GetPlayer()->SetMoney(game->GetPlayer()->GetMoney()+totalCost);
|
||||
game->GetPlayer()->AddMoney(totalCost);
|
||||
|
||||
//If we still have some in our inventory, we'll add them back in.
|
||||
if(foundLoadoutSlot!=-1&&Inventory::GetItemCount(itemName)>0){
|
||||
|
@ -1288,7 +1288,6 @@ void Player::SetAnimationBasedOnTargetingDirection(const std::string_view animat
|
||||
std::string newAnimState{std::format("{}_{}_{}",Capitalize(GetClassName()),animation_name,facingChar)};
|
||||
|
||||
if(animation.HasState(newAnimState))UpdateAnimation(newAnimState);
|
||||
else ERR(std::format("WARNING! Animation {} does not exist on the player! THIS SHOULD NOT BE HAPPENING!",newAnimState));
|
||||
}
|
||||
|
||||
void Player::ApplyIframes(float duration){
|
||||
@ -1539,12 +1538,12 @@ void Player::RecalculateEquipStats(){
|
||||
if(GetClass()&WIZARD){
|
||||
if(HasEnchant("Blink Portal"))GetRightClickAbility().COOLDOWN_TIME="Blink Portal"_ENC["COOLDOWN"];
|
||||
if(HasEnchant("Summon Comet")){
|
||||
float castTimeDiff{GetOriginalAbility3().precastInfo.castTime-"Summon Comet"_ENC["METEOR CAST TIME"]};
|
||||
float castTimeDiff{_GetOriginalAbility3().precastInfo.castTime-"Summon Comet"_ENC["METEOR CAST TIME"]};
|
||||
GetAbility3().precastInfo.castTime-=castTimeDiff;
|
||||
GetAbility3().COOLDOWN_TIME+="Summon Comet"_ENC["COOLDOWN REDUCTION"]; //This is not a typo, we add because the cooldown reduction in the config is NEGATIVE!
|
||||
}
|
||||
if(HasEnchant("Solar Flare")){
|
||||
float castTimeDiff{GetOriginalAbility3().precastInfo.castTime-"Solar Flare"_ENC["METEOR CAST TIME"]};
|
||||
float castTimeDiff{_GetOriginalAbility3().precastInfo.castTime-"Solar Flare"_ENC["METEOR CAST TIME"]};
|
||||
GetAbility3().precastInfo.castTime-=castTimeDiff;
|
||||
GetAbility3().COOLDOWN_TIME+="Solar Flare"_ENC["COOLDOWN INCREASE"];
|
||||
}
|
||||
@ -2291,3 +2290,12 @@ void Player::SetTestScreenAimingLocation(vf2d forcedAimingLoc){
|
||||
void Player::SetAbility4(const Ability&ability){
|
||||
|
||||
}
|
||||
|
||||
void Player::RemoveMoney(const uint32_t moneyCost){
|
||||
if(moneyCost>GetMoney())ERR(std::format("WARNING! Trying to spend more money than we actually have! THIS SHOULD NOT BE HAPPENING! Current Money: {} Trying to spend: {}",GetMoney(),moneyCost));
|
||||
SetMoney(GetMoney()-moneyCost);
|
||||
}
|
||||
|
||||
void Player::AddMoney(const uint32_t moneyCost){
|
||||
SetMoney(GetMoney()+moneyCost);
|
||||
}
|
@ -231,10 +231,6 @@ public:
|
||||
virtual Ability&GetAbility3()=0;
|
||||
virtual Ability&GetAbility4()=0;
|
||||
virtual void SetAbility4(const Ability&originalAbility)=0; //NOTE: Make sure to provide the original ability and not a current ability!
|
||||
virtual Ability&GetOriginalAbility1()=0;
|
||||
virtual Ability&GetOriginalAbility2()=0;
|
||||
virtual Ability&GetOriginalAbility3()=0;
|
||||
virtual Ability&GetOriginalRightClickAbility()=0;
|
||||
virtual std::string&GetWalkNAnimation()=0;
|
||||
virtual std::string&GetWalkEAnimation()=0;
|
||||
virtual std::string&GetWalkSAnimation()=0;
|
||||
@ -268,6 +264,8 @@ public:
|
||||
static void AddMoneyListener(std::weak_ptr<MenuComponent>component);
|
||||
uint32_t GetMoney()const;
|
||||
void SetMoney(uint32_t newMoney);
|
||||
void AddMoney(const uint32_t moneyCost);
|
||||
void RemoveMoney(const uint32_t moneyCost);
|
||||
void AddXP(const uint64_t xpGain);
|
||||
void OnLevelUp();
|
||||
const uint8_t LevelCap()const;
|
||||
@ -485,6 +483,10 @@ protected:
|
||||
vf2d leapStartingPos{};
|
||||
float poisonArrowReadyTimer{};
|
||||
void ActivateCatForm();
|
||||
virtual Ability&_GetOriginalAbility1()=0;
|
||||
virtual Ability&_GetOriginalAbility2()=0;
|
||||
virtual Ability&_GetOriginalAbility3()=0;
|
||||
virtual Ability&_GetOriginalRightClickAbility()=0;
|
||||
};
|
||||
|
||||
#pragma region Warrior
|
||||
@ -507,10 +509,14 @@ struct Warrior:Player{
|
||||
Ability&GetAbility2()override;
|
||||
Ability&GetAbility3()override;
|
||||
Ability&GetAbility4()override;
|
||||
Ability&GetOriginalAbility1()override;
|
||||
Ability&GetOriginalAbility2()override;
|
||||
Ability&GetOriginalAbility3()override;
|
||||
Ability&GetOriginalRightClickAbility()override;
|
||||
virtual Ability&_GetOriginalAbility1()override;
|
||||
virtual Ability&_GetOriginalAbility2()override;
|
||||
virtual Ability&_GetOriginalAbility3()override;
|
||||
virtual Ability&_GetOriginalRightClickAbility()override;
|
||||
static Ability&GetOriginalAbility1();
|
||||
static Ability&GetOriginalAbility2();
|
||||
static Ability&GetOriginalAbility3();
|
||||
static Ability&GetOriginalRightClickAbility();
|
||||
void SetAbility4(const Ability&originalAbility)override; //NOTE: Make sure to provide the original ability and not a current ability!
|
||||
std::string&GetWalkNAnimation()override;
|
||||
std::string&GetWalkEAnimation()override;
|
||||
@ -547,10 +553,14 @@ struct Thief:Player{
|
||||
Ability&GetAbility2()override;
|
||||
Ability&GetAbility3()override;
|
||||
Ability&GetAbility4()override;
|
||||
Ability&GetOriginalAbility1()override;
|
||||
Ability&GetOriginalAbility2()override;
|
||||
Ability&GetOriginalAbility3()override;
|
||||
Ability&GetOriginalRightClickAbility()override;
|
||||
virtual Ability&_GetOriginalAbility1()override;
|
||||
virtual Ability&_GetOriginalAbility2()override;
|
||||
virtual Ability&_GetOriginalAbility3()override;
|
||||
virtual Ability&_GetOriginalRightClickAbility()override;
|
||||
static Ability&GetOriginalAbility1();
|
||||
static Ability&GetOriginalAbility2();
|
||||
static Ability&GetOriginalAbility3();
|
||||
static Ability&GetOriginalRightClickAbility();
|
||||
void SetAbility4(const Ability&originalAbility)override; //NOTE: Make sure to provide the original ability and not a current ability!
|
||||
std::string&GetWalkNAnimation()override;
|
||||
std::string&GetWalkEAnimation()override;
|
||||
@ -587,10 +597,14 @@ struct Ranger:Player{
|
||||
Ability&GetAbility2()override;
|
||||
Ability&GetAbility3()override;
|
||||
Ability&GetAbility4()override;
|
||||
Ability&GetOriginalAbility1()override;
|
||||
Ability&GetOriginalAbility2()override;
|
||||
Ability&GetOriginalAbility3()override;
|
||||
Ability&GetOriginalRightClickAbility()override;
|
||||
virtual Ability&_GetOriginalAbility1()override;
|
||||
virtual Ability&_GetOriginalAbility2()override;
|
||||
virtual Ability&_GetOriginalAbility3()override;
|
||||
virtual Ability&_GetOriginalRightClickAbility()override;
|
||||
static Ability&GetOriginalAbility1();
|
||||
static Ability&GetOriginalAbility2();
|
||||
static Ability&GetOriginalAbility3();
|
||||
static Ability&GetOriginalRightClickAbility();
|
||||
void SetAbility4(const Ability&originalAbility)override; //NOTE: Make sure to provide the original ability and not a current ability!
|
||||
std::string&GetWalkNAnimation()override;
|
||||
std::string&GetWalkEAnimation()override;
|
||||
@ -627,10 +641,14 @@ struct Trapper:Player{
|
||||
Ability&GetAbility2()override;
|
||||
Ability&GetAbility3()override;
|
||||
Ability&GetAbility4()override;
|
||||
Ability&GetOriginalAbility1()override;
|
||||
Ability&GetOriginalAbility2()override;
|
||||
Ability&GetOriginalAbility3()override;
|
||||
Ability&GetOriginalRightClickAbility()override;
|
||||
virtual Ability&_GetOriginalAbility1()override;
|
||||
virtual Ability&_GetOriginalAbility2()override;
|
||||
virtual Ability&_GetOriginalAbility3()override;
|
||||
virtual Ability&_GetOriginalRightClickAbility()override;
|
||||
static Ability&GetOriginalAbility1();
|
||||
static Ability&GetOriginalAbility2();
|
||||
static Ability&GetOriginalAbility3();
|
||||
static Ability&GetOriginalRightClickAbility();
|
||||
void SetAbility4(const Ability&originalAbility)override; //NOTE: Make sure to provide the original ability and not a current ability!
|
||||
std::string&GetWalkNAnimation()override;
|
||||
std::string&GetWalkEAnimation()override;
|
||||
@ -663,14 +681,18 @@ struct Wizard:Player{
|
||||
static void InitializeClassAbilities();
|
||||
const std::string&GetClassName()override;
|
||||
Ability&GetRightClickAbility()override;
|
||||
Ability&GetAbility1()override;
|
||||
Ability&GetAbility2()override;
|
||||
Ability&GetAbility3()override;
|
||||
Ability&GetAbility4()override;
|
||||
Ability&GetOriginalAbility1()override;
|
||||
Ability&GetOriginalAbility2()override;
|
||||
Ability&GetOriginalAbility3()override;
|
||||
Ability&GetOriginalRightClickAbility()override;
|
||||
Ability&GetAbility1();
|
||||
Ability&GetAbility2();
|
||||
Ability&GetAbility3();
|
||||
Ability&GetAbility4();
|
||||
virtual Ability&_GetOriginalAbility1()override;
|
||||
virtual Ability&_GetOriginalAbility2()override;
|
||||
virtual Ability&_GetOriginalAbility3()override;
|
||||
virtual Ability&_GetOriginalRightClickAbility()override;
|
||||
static Ability&GetOriginalAbility1();
|
||||
static Ability&GetOriginalAbility2();
|
||||
static Ability&GetOriginalAbility3();
|
||||
static Ability&GetOriginalRightClickAbility();
|
||||
void SetAbility4(const Ability&originalAbility)override; //NOTE: Make sure to provide the original ability and not a current ability!
|
||||
std::string&GetWalkNAnimation()override;
|
||||
std::string&GetWalkEAnimation()override;
|
||||
@ -707,10 +729,14 @@ struct Witch:Player{
|
||||
Ability&GetAbility2()override;
|
||||
Ability&GetAbility3()override;
|
||||
Ability&GetAbility4()override;
|
||||
Ability&GetOriginalAbility1()override;
|
||||
Ability&GetOriginalAbility2()override;
|
||||
Ability&GetOriginalAbility3()override;
|
||||
Ability&GetOriginalRightClickAbility()override;
|
||||
virtual Ability&_GetOriginalAbility1()override;
|
||||
virtual Ability&_GetOriginalAbility2()override;
|
||||
virtual Ability&_GetOriginalAbility3()override;
|
||||
virtual Ability&_GetOriginalRightClickAbility()override;
|
||||
static Ability&GetOriginalAbility1();
|
||||
static Ability&GetOriginalAbility2();
|
||||
static Ability&GetOriginalAbility3();
|
||||
static Ability&GetOriginalRightClickAbility();
|
||||
void SetAbility4(const Ability&originalAbility)override; //NOTE: Make sure to provide the original ability and not a current ability!
|
||||
std::string&GetWalkNAnimation()override;
|
||||
std::string&GetWalkEAnimation()override;
|
||||
|
@ -39,7 +39,7 @@ All rights reserved.
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 3
|
||||
#define VERSION_PATCH 0
|
||||
#define VERSION_BUILD 11564
|
||||
#define VERSION_BUILD 11598
|
||||
|
||||
#define stringify(a) stringify_(a)
|
||||
#define stringify_(a) #a
|
||||
|
@ -137,6 +137,12 @@ Events
|
||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||
File[0] = disassemble.ogg, 70%
|
||||
}
|
||||
Enchant Item
|
||||
{
|
||||
CombatSound = True
|
||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||
File[0] = enchant_item.ogg, 100%
|
||||
}
|
||||
Equip Armor
|
||||
{
|
||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||
@ -323,6 +329,12 @@ Events
|
||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||
File[0] = ranger_charged_shot.ogg, 70%
|
||||
}
|
||||
Refine Item
|
||||
{
|
||||
CombatSound = True
|
||||
# Specify file names, followed by volume %. Optional min and max pitch adjustment (Defaults are 90%,110%)
|
||||
File[0] = refine_item.ogg, 60%, 110%, 130%
|
||||
}
|
||||
Rise
|
||||
{
|
||||
CombatSound = True
|
||||
|
BIN
Adventures in Lestoria/assets/sounds/enchant_item.ogg
Normal file
BIN
Adventures in Lestoria/assets/sounds/enchant_item.ogg
Normal file
Binary file not shown.
BIN
Adventures in Lestoria/assets/sounds/refine_item.ogg
Normal file
BIN
Adventures in Lestoria/assets/sounds/refine_item.ogg
Normal file
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user