Updates to new PkmnLib, many many changes.

This commit is contained in:
Deukhoofd 2020-04-11 00:22:34 +02:00
parent 525c748b91
commit 292ca78b47
Signed by: Deukhoofd
GPG Key ID: ADF2E9256009EDCE
17 changed files with 125 additions and 78 deletions

View File

@ -39,7 +39,7 @@ SET(FILE_SOURCE
file(GLOB_RECURSE CORE_SRC_FILES ${FILE_SOURCE})
add_executable(Gen7Tests ${CORE_SRC_FILES})
SET(_LINKS CreatureLibCore CreatureLibLibrary CreatureLibBattling pkmnLib)
SET(_LINKS CreatureLibLibrary CreatureLibBattling pkmnLib)
target_link_libraries(Gen7Tests PUBLIC ${_LINKS})

View File

@ -53,9 +53,9 @@ PkmnLib::Library::ItemLibrary* BuildItems::Build(const std::string& path) {
if (static_cast<int>(itemType) == 255)
return nullptr;
auto flags = std::unordered_set<Arbutils::CaseInsensitiveConstString>();
auto flags = std::unordered_set<uint>();
for (auto flagIndex : _flags.items()) {
flags.insert(Arbutils::CaseInsensitiveConstString(flagIndex.value().get<std::string>()));
flags.insert(Arbutils::CaseInsensitiveConstString::GetHash(flagIndex.value().get<std::string>()));
}
auto item = new PkmnLib::Library::Item(Arbutils::CaseInsensitiveConstString(_name.get<std::string>()), itemType,

View File

@ -46,7 +46,7 @@ PkmnLib::Library::MoveLibrary* BuildMoves::Build(const std::string& path,
GET(val, flags, i);
if (_pp.get<uint8_t>() == 0)
continue;
auto type = types->GetTypeId(_type.get<std::string>());
auto type = types->GetTypeId(Arbutils::CaseInsensitiveConstString::GetHash(_type.get<std::string>()));
auto category = ParseCategory(_category.get<std::string>());
if (static_cast<int>(category) == 255)
return nullptr;
@ -56,14 +56,53 @@ PkmnLib::Library::MoveLibrary* BuildMoves::Build(const std::string& path,
<< _name.get<std::string>() << "'\n";
return nullptr;
}
auto flags = std::unordered_set<Arbutils::CaseInsensitiveConstString>();
auto flags = std::unordered_set<uint32_t>();
for (auto flagIndex : _flags.items()) {
flags.insert(Arbutils::CaseInsensitiveConstString(flagIndex.value().get<std::string>()));
flags.insert(Arbutils::CaseInsensitiveConstString::GetHash(flagIndex.value().get<std::string>()));
}
CreatureLib::Library::SecondaryEffect* effect = nullptr;
auto jsonEffect = val["effect"];
if (jsonEffect != nullptr) {
auto name = jsonEffect["name"];
auto chanceJson = jsonEffect["chance"];
auto parametersJson = jsonEffect["parameters"];
if (name != nullptr) {
List<CreatureLib::Library::EffectParameter*> parameters;
auto chance = -1.0f;
if (chanceJson != nullptr) {
chance = chanceJson.get<float>();
}
if (parametersJson != nullptr) {
for (auto& kv : parametersJson.items()) {
auto& p = kv.value();
auto t = p.type();
switch (t) {
case json::value_t::boolean:
parameters.Append(new CreatureLib::Library::EffectParameter(p.get<bool>()));
break;
case json::value_t::number_integer:
case json::value_t::number_unsigned:
parameters.Append(new CreatureLib::Library::EffectParameter(p.get<int64_t>()));
break;
case json::value_t::number_float:
parameters.Append(new CreatureLib::Library::EffectParameter(p.get<float>()));
break;
default: continue;
}
}
}
effect = new CreatureLib::Library::SecondaryEffect(
chance, Arbutils::CaseInsensitiveConstString(name.get<std::string>()), parameters);
}
}
if (effect == nullptr) {
effect = new CreatureLib::Library::SecondaryEffect();
}
auto move = new PkmnLib::Library::MoveData(
_name.get<std::string>(), type, category, _power.get<uint8_t>(), _accuracy.get<uint8_t>(),
_pp.get<uint8_t>(), target, _priority.get<int8_t>(), flags);
auto move = new PkmnLib::Library::MoveData(Arbutils::CaseInsensitiveConstString(_name.get<std::string>()), type,
category, _power.get<uint8_t>(), _accuracy.get<uint8_t>(),
_pp.get<uint8_t>(), target, _priority.get<int8_t>(), effect, flags);
lib->Insert(Arbutils::CaseInsensitiveConstString(move->GetName()), move);
}

View File

@ -3,21 +3,21 @@
#include <fstream>
#include <iostream>
static CreatureLib::Core::Statistic ParseStatistic(const std::string& stat) {
static CreatureLib::Library::Statistic ParseStatistic(const std::string& stat) {
if (stat.empty())
return static_cast<CreatureLib::Core::Statistic>(255);
return static_cast<CreatureLib::Library::Statistic>(255);
if (stat == "Attack")
return CreatureLib::Core::Statistic::PhysicalAttack;
return CreatureLib::Library::Statistic::PhysicalAttack;
if (stat == "Defense")
return CreatureLib::Core::Statistic::PhysicalDefense;
return CreatureLib::Library::Statistic::PhysicalDefense;
if (stat == "SpecialAttack")
return CreatureLib::Core::Statistic::MagicalAttack;
return CreatureLib::Library::Statistic::MagicalAttack;
if (stat == "SpecialDefense")
return CreatureLib::Core::Statistic::MagicalDefense;
return CreatureLib::Library::Statistic::MagicalDefense;
if (stat == "Speed")
return CreatureLib::Core::Statistic::Speed;
return CreatureLib::Library::Statistic::Speed;
std::cout << "Invalid stat was given: '" << stat << "'.\n";
return static_cast<CreatureLib::Core::Statistic>(254);
return static_cast<CreatureLib::Library::Statistic>(254);
}
PkmnLib::Library::NatureLibrary* BuildNatures::Build(const std::string& path) {

View File

@ -80,8 +80,8 @@ PkmnLib::Library::SpeciesLibrary* BuildSpecies::BuildLibrary(const std::string&
return lib;
}
static CreatureLib::Core::StatisticSet<uint16_t> ParseStatistics(json& json) {
return CreatureLib::Core::StatisticSet<uint16_t>(
static CreatureLib::Library::StatisticSet<uint16_t> ParseStatistics(json& json) {
return CreatureLib::Library::StatisticSet<uint16_t>(
json["hp"].get<uint16_t>(), json["attack"].get<uint16_t>(), json["defense"].get<uint16_t>(),
json["specialAttack"].get<uint16_t>(), json["specialDefense"].get<uint16_t>(), json["speed"].get<uint16_t>());
}
@ -100,15 +100,26 @@ const PkmnLib::Library::PokemonForme* BuildSpecies::BuildForme(const std::string
GET(forme, moves, baseKeyName << " -> " << name);
auto typeStrings = _types.get<std::vector<std::string>>();
auto types = std::vector<uint8_t>(typeStrings.size());
auto types = List<uint8_t>(typeStrings.size());
for (auto i = 0; i < typeStrings.size(); i++) {
types[i] = typeLibrary->GetTypeId(typeStrings[i]);
types[i] = typeLibrary->GetTypeId(Arbutils::CaseInsensitiveConstString::GetHash(typeStrings[i]));
}
auto stats = ParseStatistics(_baseStats);
return new PkmnLib::Library::PokemonForme(
name, _height.get<float>(), _weight.get<float>(), _baseExp.get<uint32_t>(), types, stats,
_abilities.get<std::vector<std::string>>(), _hiddenAbilities.get<std::vector<std::string>>(), nullptr);
auto abilityStrings = _abilities.get<std::vector<std::string>>();
auto abilities = List<Arbutils::CaseInsensitiveConstString>(abilityStrings.size());
for (auto i = 0; i < abilityStrings.size(); i++) {
abilities[i] = Arbutils::CaseInsensitiveConstString(abilityStrings[i]);
}
auto hiddenAbilityStrings = _abilities.get<std::vector<std::string>>();
auto hiddenAbilities = List<Arbutils::CaseInsensitiveConstString>(hiddenAbilityStrings.size());
for (auto i = 0; i < hiddenAbilityStrings.size(); i++) {
hiddenAbilities[i] = Arbutils::CaseInsensitiveConstString(abilityStrings[i]);
}
return new PkmnLib::Library::PokemonForme(Arbutils::CaseInsensitiveConstString(name), _height.get<float>(),
_weight.get<float>(), _baseExp.get<uint32_t>(), types, stats, abilities,
hiddenAbilities, nullptr);
}
#undef GET

View File

@ -20,14 +20,14 @@ CreatureLib::Library::TypeLibrary* BuildTypes::Build(const std::string& path) {
bool hasSkippedFirst = false;
size_t lastStart = 0;
std::vector<uint8_t > types;
std::vector<uint8_t> types;
for (size_t i = 0; i < line.length(); i++) {
if (line[i] == divider) {
auto substr = line.substr(lastStart, i - lastStart);
lastStart = i + 1;
if (hasSkippedFirst) {
std::cout << "Registered type: " << substr << "\n";
auto val = library->RegisterType(substr);
auto val = library->RegisterType(Arbutils::CaseInsensitiveConstString::GetHash(substr));
types.push_back(val);
} else {
hasSkippedFirst = true;
@ -37,10 +37,9 @@ CreatureLib::Library::TypeLibrary* BuildTypes::Build(const std::string& path) {
}
auto substr = line.substr(lastStart, line.length() - lastStart);
std::cout << "Registered type: " << substr << "\n";
auto val = library->RegisterType(substr);
auto val = library->RegisterType(Arbutils::CaseInsensitiveConstString::GetHash(substr));
types.push_back(val);
while (std::getline(file, line)) {
uint8_t attackingType = 0;
bool gotType = false;
@ -56,7 +55,7 @@ CreatureLib::Library::TypeLibrary* BuildTypes::Build(const std::string& path) {
current++;
} else {
gotType = true;
attackingType = library->GetTypeId(substr);
attackingType = library->GetTypeId(Arbutils::CaseInsensitiveConstString::GetHash(substr));
}
i++;
}

View File

@ -21,8 +21,8 @@ TEST_CASE("Species - Ensure each species has a default forme", "[species]") {
auto iterator = library->GetSpeciesLibrary()->GetIterator();
size_t i = 0;
for (const auto& v: iterator){
REQUIRE(v.second->HasVariant("default"_cnc));
CHECK(v.second->GetVariant("default"_cnc)->GetName() == "default");
REQUIRE(v.second->HasVariant("default"_cnc.GetHash()));
CHECK(v.second->GetVariant("default"_cnc.GetHash())->GetName() == "default");
i++;
}
REQUIRE(i == 802);
@ -35,7 +35,7 @@ TEST_CASE("Species - Ensure each forme has abilities", "[species]") {
for (const auto& v: iterator){
for (const auto& forme: v.second->GetVariantsIterator()){
auto abilities = forme.second->GetTalents();
CHECK(!abilities.empty());
CHECK(abilities.Count() != 0);
}
i++;
}

View File

@ -2,7 +2,9 @@
#include "../Library.hpp"
#define CHECK_EFFECTIVENESS(attack, defense, expected) \
CHECK(typeLib->GetSingleEffectiveness(typeLib->GetTypeId(#attack), typeLib->GetTypeId(#defense)) == expected);
CHECK(typeLib->GetSingleEffectiveness( \
typeLib->GetTypeId(Arbutils::CaseInsensitiveConstString::GetHash(#attack)), \
typeLib->GetTypeId(Arbutils::CaseInsensitiveConstString::GetHash(#defense))) == expected);
TEST_CASE("Type Effectiveness - Normal Attacking", "[type]") {
auto typeLib = Library::GetStaticLib()->GetTypeLibrary();
@ -400,8 +402,4 @@ TEST_CASE("Type Effectiveness - Fairy Attacking", "[type]") {
CHECK_EFFECTIVENESS(Fairy, Fairy, 1);
}
#undef CHECK_EFFECTIVENESS

View File

@ -17,16 +17,21 @@
auto userParty = new CreatureLib::Battling::CreatureParty({userMon}); \
auto targetParty = new CreatureLib::Battling::CreatureParty({targetMon}); \
auto battle = new PkmnLib::Battling::Battle( \
library, { \
CreatureLib::Battling::BattleParty(userParty, {CreatureLib::Battling::CreatureIndex(0, 0)}), \
CreatureLib::Battling::BattleParty(targetParty, {CreatureLib::Battling::CreatureIndex(1, 0)}), \
}); \
library, \
{ \
new CreatureLib::Battling::BattleParty(userParty, {CreatureLib::Battling::CreatureIndex(0, 0)}), \
new CreatureLib::Battling::BattleParty(targetParty, {CreatureLib::Battling::CreatureIndex(1, 0)}), \
}); \
\
userMon->SetBattleData(battle, battle->GetSides()[0]); \
targetMon->SetBattleData(battle, battle->GetSides()[1]); \
\
auto script = library->LoadScript(ScriptCategory::Attack, #move); \
auto moveData = library->GetMoveLibrary()->Get(Arbutils::CaseInsensitiveConstString(#move)); \
REQUIRE(moveData->HasSecondaryEffect()); \
auto effect = moveData->GetSecondaryEffect(); \
auto script = library->LoadScript(ScriptCategory::Attack, effect->GetEffectName()); \
REQUIRE(script != nullptr); \
script->OnInitialize(effect->GetParameters()); \
\
auto executingMove = \
new CreatureLib::Battling::ExecutingAttack({targetMon}, 1, userMon, userMon->GetMoves()[0], script);
@ -41,7 +46,7 @@
TEST_CASE(#move " - On Effect Trigger", "[moves]") { \
SETUP_MOVE_TEST(move) \
\
battle->AddVolatileScript("TriggerEffectChance"); \
battle->AddVolatileScript("TriggerEffectChance"_cnc); \
script->OnSecondaryEffect(executingMove, targetMon, 0); \
onAfterCheck; \
\
@ -52,7 +57,7 @@
TEST_CASE(#move " - On Effect No Trigger", "[moves]") { \
SETUP_MOVE_TEST(move) \
\
battle->AddVolatileScript("BlockEffectChance"); \
battle->AddVolatileScript("BlockEffectChance"_cnc); \
script->OnSecondaryEffect(executingMove, targetMon, 0); \
onAfterCheck; \
\
@ -61,26 +66,14 @@
#define MOVE_EFFECT_CHANCE(move, chance) \
TEST_CASE(#move " - Effect Chance = " #chance, "[moves]") { \
SETUP_MOVE_TEST(move) \
\
battle->AddVolatileScript("SaveEffectChance"); \
script->OnSecondaryEffect(executingMove, targetMon, 0); \
\
auto saveScript = dynamic_cast<AngelScriptScript*>(battle->GetVolatileScript("SaveEffectChance")); \
\
auto ctx = saveScript->GetContextPool()->RequestContext(); \
saveScript->PrepareMethod("GetChance", ctx); \
ctx->Execute(); \
auto result = ctx->GetReturnFloat(); \
CHECK(result == Approx(chance)); \
saveScript->GetContextPool()->ReturnContextToPool(ctx); \
\
CLEANUP_MOVE_TEST \
auto library = Library::GetLibrary(); \
auto move = library->GetMoveLibrary()->Get(Arbutils::CaseInsensitiveConstString(#move)); \
REQUIRE(move->HasSecondaryEffect()); \
CHECK(move->GetSecondaryEffect()->GetChance() == chance); \
}
#define CHANCE_BASED_MOVE(moveName, chance, onEffectCheck, onNoEffectCheck) \
#define CHANCE_BASED_MOVE(moveName, chance, onEffectCheck) \
ON_MOVE_EFFECT_TRIGGER(moveName, onEffectCheck) \
ON_MOVE_EFFECT_NO_TRIGGER(moveName, onNoEffectCheck) \
MOVE_EFFECT_CHANCE(moveName, chance)
#define INCREASED_CRITICAL_RATE(moveName, expectedStage) \

View File

@ -20,7 +20,7 @@ TEST_CASE("Absorb - Heals more with big root", "[moves]") {
userMon->Damage(50, CreatureLib::Battling::DamageSource::AttackDamage);
executingMove->GetAttackDataForTarget(targetMon)->GetHit(0)->SetDamage(50);
userMon->SetHeldItem("big_root"_cnc);
userMon->SetHeldItem("big_root"_cnc.GetHash());
script->OnSecondaryEffect(executingMove, targetMon, 0);
CHECK(userMon->GetCurrentHealth() == userMon->GetMaxHealth() - 18);

View File

@ -2,8 +2,4 @@
using Stats = PkmnLib::Library::Statistic;
CHANCE_BASED_MOVE(
Acid, 10,
{ CHECK(targetMon->GetStatBoost(Stats::SpecialDefense) == -1); },
{ CHECK(targetMon->GetStatBoost(Stats::SpecialDefense) == 0); }
);
CHANCE_BASED_MOVE(Acid, 10, { CHECK(targetMon->GetStatBoost(Stats::SpecialDefense) == -1); });

View File

@ -1,3 +1,3 @@
#include "../../Macros/MoveMacros.hpp"
CHANGE_USER_STAT_MOVE(Acid_Armor, PhysicalDefense, 2, OnStatusMove);
CHANGE_USER_STAT_MOVE(Acid_Armor, PhysicalDefense, 2, OnSecondaryEffect);

View File

@ -21,11 +21,10 @@ TEST_CASE("Acrobatics - doesn't overflow", "[moves]") {
CLEANUP_MOVE_TEST
}
TEST_CASE("Acrobatics - doesn't double base power when no held item", "[moves]") {
SETUP_MOVE_TEST(Acrobatics)
userMon->SetHeldItem("poke_ball"_cnc);
userMon->SetHeldItem("poke_ball"_cnc.GetHash());
uint8_t basePower = 40;
script->OverrideBasePower(executingMove, userMon, 0, &basePower);
REQUIRE(basePower == 40);

View File

@ -7,9 +7,9 @@
TEST_CASE("Acupressure - increases random stat by 2", "[moves]") {
SETUP_MOVE_TEST(Acupressure)
script->OnStatusMove(executingMove, targetMon, 0);
script->OnSecondaryEffect(executingMove, targetMon, 0);
bool hasDoubleIncreasedStat = false;
for (auto stat: CreatureLib::Core::StatisticHelper::GetValues()){
for (auto stat: CreatureLib::Library::StatisticHelper::GetValues()){
auto statBoost = targetMon->GetStatBoost(stat);
if (statBoost == 0)
@ -32,9 +32,9 @@ TEST_CASE("Acupressure - increases random stat by 2", "[moves]") {
TEST_CASE("Acupressure - fails if user is target", "[moves]") {
SETUP_MOVE_TEST(Acupressure)
script->OnStatusMove(executingMove, userMon, 0);
script->OnSecondaryEffect(executingMove, userMon, 0);
bool hasDoubleIncreasedStat = false;
for (auto stat: CreatureLib::Core::StatisticHelper::GetValues()){
for (auto stat: CreatureLib::Library::StatisticHelper::GetValues()){
auto statBoost = userMon->GetStatBoost(stat);
if (statBoost == 0)

View File

@ -1,3 +1,3 @@
#include "../../Macros/MoveMacros.hpp"
CHANGE_USER_STAT_MOVE(Agility, Speed, 2, OnStatusMove);
CHANGE_USER_STAT_MOVE(Agility, Speed, 2, OnSecondaryEffect);

View File

@ -0,0 +1,6 @@
#include "../../Macros/MoveMacros.hpp"
CHANCE_BASED_MOVE(
Air_Slash, 30,
{ CHECK(targetMon->HasVolatileScript("flinch"_cnc)); }
);

View File

@ -106,15 +106,21 @@ int main(int argc, char* argv[]) {
}
asScriptResolver->CreateScript("TriggerEffectChance", R"(
namespace Battle{ class TriggerEffectChance : PkmnScript {
namespace Battle{
[Battle effect=TriggerEffectChance]
class TriggerEffectChance : PkmnScript {
void ModifyEffectChance(ExecutingMove@ attack, Pokemon@ target, float& chance) override{chance = 10000;} }
})");
asScriptResolver->CreateScript("BlockEffectChance", R"(
namespace Battle{ class BlockEffectChance : PkmnScript {
namespace Battle{
[Battle effect=BlockEffectChance]
class BlockEffectChance : PkmnScript {
void ModifyEffectChance(ExecutingMove@ attack, Pokemon@ target, float& chance) override{chance = -10000;} }
})");
asScriptResolver->CreateScript("SaveEffectChance", R"(
namespace Battle{ class SaveEffectChance : PkmnScript {
namespace Battle{
[Battle effect=SaveEffectChance]
class SaveEffectChance : PkmnScript {
float _chance = 0;
void ModifyEffectChance(ExecutingMove@ attack, Pokemon@ target, float& chance) override{_chance = chance;}
float GetChance() { return _chance; }