#ifndef POKEMONSCRIPTTESTER_BATTLEFUNCTIONS_HPP #define POKEMONSCRIPTTESTER_BATTLEFUNCTIONS_HPP #include #include #include #include #include #include #include "../TestEnvironment.hpp" class BattleFunctions { static CreatureLib::Battling::CreatureParty* CreateSimpleParty(CScriptArray* species, u8 level) { auto* ctx = asGetActiveContext(); TestEnvironment* env = static_cast(ctx->GetUserData(684)); auto lib = Globals::Library.GetValue(); auto p1 = new PkmnLib::Battling::PokemonParty(species->GetSize()); for (u32 i = 0; i < species->GetSize(); ++i) { auto s = reinterpret_cast(species->At(i)); auto mon1 = PkmnLib::Battling::CreatePokemon(lib, *s, level) .WithEffortValues(0, 0, 0, 0, 0, 0) .WithIndividualValues(31, 31, 31, 31, 31, 31) .WithNature("hardy"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .IsAllowedExperienceGain(false) .Build(); p1->SwapInto(i, mon1); } env->AddGarbage(p1); return p1; } static CreatureLib::Battling::CreatureParty* CreateParty(CScriptArray* mons) { auto* ctx = asGetActiveContext(); TestEnvironment* env = static_cast(ctx->GetUserData(684)); auto p1 = new PkmnLib::Battling::PokemonParty(mons->GetSize()); for (u32 i = 0; i < mons->GetSize(); ++i) { auto s = *reinterpret_cast(mons->At(i)); p1->SwapInto(i, s); // Party becomes owner of mon, so take it from GC. env->TakeOwnershipOfGarbage(s); } env->AddGarbage(p1); return p1; } static PkmnLib::Battling::Battle* CreateSimpleBattle(u32 seed, const ArbUt::StringView& species1, const ArbUt::StringView& species2, u8 level) { auto* ctx = asGetActiveContext(); TestEnvironment* env = static_cast(ctx->GetUserData(684)); auto lib = Globals::Library.GetValue(); auto mon1 = PkmnLib::Battling::CreatePokemon(lib, species1, level) .WithEffortValues(0, 0, 0, 0, 0, 0) .WithIndividualValues(31, 31, 31, 31, 31, 31) .WithNature("hardy"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .IsAllowedExperienceGain(false) .Build(); auto p1 = new PkmnLib::Battling::PokemonParty(1); p1->SwapInto(0, mon1); auto mon2 = PkmnLib::Battling::CreatePokemon(lib, species2, level) .WithEffortValues(0, 0, 0, 0, 0, 0) .WithIndividualValues(31, 31, 31, 31, 31, 31) .WithNature("hardy"_cnc) .WithGender(CreatureLib::Library::Gender::Male) .IsAllowedExperienceGain(false) .Build(); auto p2 = new PkmnLib::Battling::PokemonParty(1); p2->SwapInto(0, mon2); auto battle = new PkmnLib::Battling::Battle( lib, {new CreatureLib::Battling::BattleParty(p1, {CreatureLib::Battling::CreatureIndex(0, 0)}), new CreatureLib::Battling::BattleParty(p2, {CreatureLib::Battling::CreatureIndex(1, 0)})}, true, // can flee 2, // 2 sides 1, // 1 mon per side seed // with seed ); battle->SwitchCreature(0, 0, mon1); battle->SwitchCreature(1, 0, mon2); env->AddGarbage(battle); env->AddGarbage(p1); env->AddGarbage(p2); return battle; } static PkmnLib::Battling::Battle* CreateSimpleBattleFromParties(u32 seed, PkmnLib::Battling::PokemonParty* p1, PkmnLib::Battling::PokemonParty* p2) { auto* ctx = asGetActiveContext(); TestEnvironment* env = static_cast(ctx->GetUserData(684)); auto lib = Globals::Library.GetValue(); auto battle = new PkmnLib::Battling::Battle( lib, {new CreatureLib::Battling::BattleParty(p1, {CreatureLib::Battling::CreatureIndex(0, 0)}), new CreatureLib::Battling::BattleParty(p2, {CreatureLib::Battling::CreatureIndex(1, 0)})}, true, // can flee 2, // 2 sides 1, // 1 mon per side seed // with seed ); battle->SwitchCreature(0, 0, p1->GetAtIndex(0)); battle->SwitchCreature(1, 0, p2->GetAtIndex(0)); env->AddGarbage(battle); return battle; } static bool UseMove(PkmnLib::Battling::Pokemon* user, const ArbUt::StringView& moveName, u8 sideTarget, u8 target) { auto battle = user->GetBattle(); if (!battle.HasValue()) { return false; } auto move = Globals::Library.GetValue()->GetMoveLibrary()->TryGet(moveName); if (!move.has_value()) { return false; } auto* ctx = asGetActiveContext(); TestEnvironment* env = static_cast(ctx->GetUserData(684)); auto learnedMove = new PkmnLib::Battling::LearnedMove(move.value(), CreatureLib::Battling::AttackLearnMethod::Unknown); env->AddGarbage(learnedMove); auto choice = new CreatureLib::Battling::AttackTurnChoice( user, learnedMove, CreatureLib::Battling::CreatureIndex(sideTarget, target)); auto b = battle.GetValue()->TrySetChoice(choice); if (!b) { delete choice; } return b; } static bool PassTurn(PkmnLib::Battling::Pokemon* user) { auto battle = user->GetBattle(); if (!battle.HasValue()) { return false; } auto choice = new CreatureLib::Battling::PassTurnChoice(user); auto b = battle.GetValue()->TrySetChoice(choice); if (!b) { delete choice; } return b; } static void LearnMove(PkmnLib::Battling::Pokemon* user, const ArbUt::StringView& moveName) { auto move = Globals::Library.GetValue()->GetMoveLibrary()->TryGet(moveName); if (!move.has_value()) { THROW("Unknown move: ", moveName); } user->AddAttack( new PkmnLib::Battling::LearnedMove(move.value(), CreatureLib::Battling::AttackLearnMethod::Unknown)); } public: static void Register(AngelScriptResolver* scriptResolver) { auto engine = scriptResolver->GetBuilder().GetEngine(); Ensure( engine->RegisterGlobalFunction("Party@ CreateSimpleParty(const array&in species, uint8 level)", asFUNCTION(CreateSimpleParty), asCALL_CDECL) >= 0); Ensure(engine->RegisterGlobalFunction("Party@ CreateParty(const array&in mons)", asFUNCTION(CreateParty), asCALL_CDECL) >= 0); Ensure(engine->RegisterGlobalFunction("Battle@ CreateSimpleBattle(uint seed, const constString&in species1, " "const constString&in species2, uint8 level)", asFUNCTION(CreateSimpleBattle), asCALL_CDECL) >= 0); Ensure(engine->RegisterGlobalFunction("Battle@ CreateSimpleBattle(uint seed, Party@ p1, Party@ p2)", asFUNCTION(CreateSimpleBattleFromParties), asCALL_CDECL) >= 0); Ensure(engine->RegisterObjectMethod("Pokemon", "bool UseMove(const constString&in move, uint8 side, uint8 index)", asFUNCTION(UseMove), asCALL_CDECL_OBJFIRST) >= 0); Ensure(engine->RegisterObjectMethod("Pokemon", "bool PassTurn()", asFUNCTION(PassTurn), asCALL_CDECL_OBJFIRST) >= 0); Ensure(engine->RegisterObjectMethod("Pokemon", "bool LearnMove(const constString&in move)", asFUNCTION(LearnMove), asCALL_CDECL_OBJFIRST) >= 0); } }; #endif // POKEMONSCRIPTTESTER_BATTLEFUNCTIONS_HPP