Initial work on capturing of Pokemon
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
b6f539b1f7
commit
cb2f902194
|
@ -0,0 +1,41 @@
|
||||||
|
#include "CaptureLibrary.hpp"
|
||||||
|
#include "../PkmnItemUseScript.hpp"
|
||||||
|
#include "../PkmnScriptHook.hpp"
|
||||||
|
|
||||||
|
namespace PkmnLib::Battling {
|
||||||
|
CaptureLibrary::CaptureResult CaptureLibrary::TryCatch(Pokemon* pokemon, Library::Item* catchItem,
|
||||||
|
ArbUt::Random* random) const {
|
||||||
|
auto hpMax = pokemon->GetMaxHealth();
|
||||||
|
auto hpCurrent = pokemon->GetCurrentHealth();
|
||||||
|
auto rate = pokemon->GetSpecies()->GetCaptureRate();
|
||||||
|
|
||||||
|
u8 bonusBall = 1;
|
||||||
|
auto* itemScript =
|
||||||
|
dynamic_cast<PkmnItemUseScript*>(pokemon->GetLibrary()->GetScriptResolver()->LoadItemScript(catchItem));
|
||||||
|
itemScript->ModifyPokeballCatchBonus(pokemon, &bonusBall);
|
||||||
|
|
||||||
|
u8 bonusStatus = 1;
|
||||||
|
PKMN_HOOK(ModifyCaptureRateBonus, pokemon, pokemon, catchItem, &bonusStatus);
|
||||||
|
|
||||||
|
auto modifiedCatchRate = (((3.0 * hpMax) - (2.0 * hpCurrent)) * rate * bonusBall) / (3.0 * hpMax);
|
||||||
|
modifiedCatchRate *= bonusStatus;
|
||||||
|
|
||||||
|
auto shakeProbability = 65536 / pow((255.0 / modifiedCatchRate), 0.1875);
|
||||||
|
|
||||||
|
u8 shakes = 0;
|
||||||
|
if (modifiedCatchRate >= 255) {
|
||||||
|
shakes = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Implement critical capture
|
||||||
|
|
||||||
|
for (; shakes < 4; shakes++) {
|
||||||
|
auto randomNumber = random->GetUnsigned(65536);
|
||||||
|
if (randomNumber >= shakeProbability) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto success = shakes == 4;
|
||||||
|
return CaptureResult{.WasCaught = success, .Shakes = shakes, .WasCritical = false};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef PKMNLIB_CAPTURELIBRARY_HPP
|
||||||
|
#define PKMNLIB_CAPTURELIBRARY_HPP
|
||||||
|
|
||||||
|
#include <CreatureLib/Defines.hpp>
|
||||||
|
#include "../Pokemon/Pokemon.hpp"
|
||||||
|
namespace PkmnLib::Battling {
|
||||||
|
class CaptureLibrary {
|
||||||
|
public:
|
||||||
|
struct CaptureResult {
|
||||||
|
bool WasCaught;
|
||||||
|
u8 Shakes;
|
||||||
|
bool WasCritical;
|
||||||
|
};
|
||||||
|
|
||||||
|
CaptureResult TryCatch(Pokemon* pokemon, Library::Item* catchItem, ArbUt::Random* random) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PKMNLIB_CAPTURELIBRARY_HPP
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef PKMNLIB_PKMNITEMUSESCRIPT_HPP
|
||||||
|
#define PKMNLIB_PKMNITEMUSESCRIPT_HPP
|
||||||
|
|
||||||
|
#include <CreatureLib/Battling/ScriptHandling/ItemUseScript.hpp>
|
||||||
|
namespace PkmnLib::Battling {
|
||||||
|
class Pokemon;
|
||||||
|
|
||||||
|
class PkmnItemUseScript : public CreatureLib::Battling::ItemUseScript {
|
||||||
|
public:
|
||||||
|
virtual void ModifyPokeballCatchBonus(Pokemon* pokemon, u8* catchBonus) const {
|
||||||
|
(void)pokemon;
|
||||||
|
(void)catchBonus;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // PKMNLIB_PKMNITEMUSESCRIPT_HPP
|
|
@ -36,6 +36,8 @@ namespace PkmnLib::Battling {
|
||||||
CreatureLib::Battling::Creature* target, u8 hitIndex, float* modifier){};
|
CreatureLib::Battling::Creature* target, u8 hitIndex, float* modifier){};
|
||||||
virtual void ModifyDefensiveStatValue(CreatureLib::Battling::ExecutingAttack* attack,
|
virtual void ModifyDefensiveStatValue(CreatureLib::Battling::ExecutingAttack* attack,
|
||||||
CreatureLib::Battling::Creature* target, u8 hitIndex, float* modifier){};
|
CreatureLib::Battling::Creature* target, u8 hitIndex, float* modifier){};
|
||||||
|
virtual void ModifyCaptureRateBonus(CreatureLib::Battling::Creature* pokemon,
|
||||||
|
CreatureLib::Library::Item* catchItem, u8* modifier){};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,9 +71,8 @@ void AngelScriptItemUseScript::OnUse(CreatureLib::Battling::Battle* battle) cons
|
||||||
}
|
}
|
||||||
AngelScriptUtils::AngelscriptFunctionCall(
|
AngelScriptUtils::AngelscriptFunctionCall(
|
||||||
__OnUse.Function, _resolver->GetContextPool(), _scriptObject, _resolver, ""_cnc,
|
__OnUse.Function, _resolver->GetContextPool(), _scriptObject, _resolver, ""_cnc,
|
||||||
[&]([[maybe_unused]] asIScriptContext* ctx) {
|
[&]([[maybe_unused]] asIScriptContext* ctx) { ctx->SetArgObject(0, battle); },
|
||||||
ctx->SetArgObject(0, battle);
|
[&]([[maybe_unused]] asIScriptContext* ctx) {});
|
||||||
}, [&]([[maybe_unused]] asIScriptContext* ctx) {});
|
|
||||||
}
|
}
|
||||||
void AngelScriptItemUseScript::OnCreatureUse(CreatureLib::Battling::Creature* creature, bool isBattle) const {
|
void AngelScriptItemUseScript::OnCreatureUse(CreatureLib::Battling::Creature* creature, bool isBattle) const {
|
||||||
if (!__OnPokemonUse.Exists) {
|
if (!__OnPokemonUse.Exists) {
|
||||||
|
@ -87,3 +86,15 @@ void AngelScriptItemUseScript::OnCreatureUse(CreatureLib::Battling::Creature* cr
|
||||||
},
|
},
|
||||||
[&]([[maybe_unused]] asIScriptContext* ctx) {});
|
[&]([[maybe_unused]] asIScriptContext* ctx) {});
|
||||||
}
|
}
|
||||||
|
void AngelScriptItemUseScript::ModifyPokeballCatchBonus(PkmnLib::Battling::Pokemon* pokemon, u8* catchBonus) const {
|
||||||
|
if (!__ModifyPokeballCatchBonus.Exists) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AngelScriptUtils::AngelscriptFunctionCall(
|
||||||
|
__ModifyPokeballCatchBonus.Function, _resolver->GetContextPool(), _scriptObject, _resolver, ""_cnc,
|
||||||
|
[&]([[maybe_unused]] asIScriptContext* ctx) {
|
||||||
|
ctx->SetArgObject(0, (void*)pokemon);
|
||||||
|
ctx->SetArgAddress(1, catchBonus);
|
||||||
|
},
|
||||||
|
[&]([[maybe_unused]] asIScriptContext* ctx) {});
|
||||||
|
}
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
|
|
||||||
#include <CreatureLib/Battling/ScriptHandling/ItemUseScript.hpp>
|
#include <CreatureLib/Battling/ScriptHandling/ItemUseScript.hpp>
|
||||||
#include <scriptarray/scriptarray.h>
|
#include <scriptarray/scriptarray.h>
|
||||||
|
#include "../../Battling/PkmnItemUseScript.hpp"
|
||||||
#include "TypeRegistry/NativeArray.hpp"
|
#include "TypeRegistry/NativeArray.hpp"
|
||||||
|
|
||||||
class AngelScriptResolver;
|
class AngelScriptResolver;
|
||||||
|
|
||||||
class AngelScriptItemUseScript final : public CreatureLib::Battling::ItemUseScript {
|
class AngelScriptItemUseScript final : public PkmnLib::Battling::PkmnItemUseScript {
|
||||||
public:
|
public:
|
||||||
AngelScriptItemUseScript(asIScriptObject* scriptObject, AngelScriptResolver* resolver)
|
AngelScriptItemUseScript(asIScriptObject* scriptObject, AngelScriptResolver* resolver)
|
||||||
: _scriptObject(scriptObject), _resolver(resolver) {}
|
: _scriptObject(scriptObject), _resolver(resolver) {}
|
||||||
|
@ -27,6 +28,7 @@ public:
|
||||||
|
|
||||||
void OnUse(CreatureLib::Battling::Battle* battle) const override;
|
void OnUse(CreatureLib::Battling::Battle* battle) const override;
|
||||||
void OnCreatureUse(CreatureLib::Battling::Creature* creature, bool isBattle) const override;
|
void OnCreatureUse(CreatureLib::Battling::Creature* creature, bool isBattle) const override;
|
||||||
|
void ModifyPokeballCatchBonus(PkmnLib::Battling::Pokemon* pokemon, u8* catchBonus) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
asIScriptObject* _scriptObject;
|
asIScriptObject* _scriptObject;
|
||||||
|
@ -50,13 +52,16 @@ private:
|
||||||
|
|
||||||
#define ITEM_USE_SCRIPT_HOOK_FUNCTION(name, decl) FunctionInfo __##name = Initialize(decl);
|
#define ITEM_USE_SCRIPT_HOOK_FUNCTION(name, decl) FunctionInfo __##name = Initialize(decl);
|
||||||
|
|
||||||
ITEM_USE_SCRIPT_HOOK_FUNCTION(OnInitialize, "void OnInitialize(const BattleLibrary@ library, const narray<EffectParameter@>@ parameters)");
|
ITEM_USE_SCRIPT_HOOK_FUNCTION(
|
||||||
|
OnInitialize, "void OnInitialize(const BattleLibrary@ library, const narray<EffectParameter@>@ parameters)");
|
||||||
ITEM_USE_SCRIPT_HOOK_FUNCTION(IsItemUsable, "bool IsItemUsable()");
|
ITEM_USE_SCRIPT_HOOK_FUNCTION(IsItemUsable, "bool IsItemUsable()");
|
||||||
ITEM_USE_SCRIPT_HOOK_FUNCTION(IsPokemonUseItem, "bool IsPokemonUseItem()");
|
ITEM_USE_SCRIPT_HOOK_FUNCTION(IsPokemonUseItem, "bool IsPokemonUseItem()");
|
||||||
ITEM_USE_SCRIPT_HOOK_FUNCTION(IsUseValidForPokemon, "bool IsUseValidForPokemon(Pokemon@ target)");
|
ITEM_USE_SCRIPT_HOOK_FUNCTION(IsUseValidForPokemon, "bool IsUseValidForPokemon(Pokemon@ target)");
|
||||||
ITEM_USE_SCRIPT_HOOK_FUNCTION(IsHoldable, "bool IsHoldable()");
|
ITEM_USE_SCRIPT_HOOK_FUNCTION(IsHoldable, "bool IsHoldable()");
|
||||||
ITEM_USE_SCRIPT_HOOK_FUNCTION(OnUse, "void OnUse()");
|
ITEM_USE_SCRIPT_HOOK_FUNCTION(OnUse, "void OnUse()");
|
||||||
ITEM_USE_SCRIPT_HOOK_FUNCTION(OnPokemonUse, "void OnPokemonUse(Pokemon@ target)");
|
ITEM_USE_SCRIPT_HOOK_FUNCTION(OnPokemonUse, "void OnPokemonUse(Pokemon@ target)");
|
||||||
|
ITEM_USE_SCRIPT_HOOK_FUNCTION(ModifyPokeballCatchBonus,
|
||||||
|
"void ModifyPokeballCatchBonus(Pokemon@ target, uint8& catchBonus)");
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PKMNLIB_ANGELSCRIPTITEMUSESCRIPT_HPP
|
#endif // PKMNLIB_ANGELSCRIPTITEMUSESCRIPT_HPP
|
||||||
|
|
|
@ -193,7 +193,7 @@ CreatureLib::Battling::BattleScript* AngelScriptResolver::LoadScript(const ArbUt
|
||||||
return new AngelScriptScript(owner, ownerType, this, t.value(), obj, _contextPool);
|
return new AngelScriptScript(owner, ownerType, this, t.value(), obj, _contextPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
CreatureLib::Battling::ItemUseScript* AngelScriptResolver::LoadItemScript(const CreatureLib::Library::Item* item) {
|
PkmnLib::Battling::PkmnItemUseScript* AngelScriptResolver::LoadItemScript(const CreatureLib::Library::Item* item) {
|
||||||
auto v = this->_itemUseScripts.TryGet(item);
|
auto v = this->_itemUseScripts.TryGet(item);
|
||||||
if (v.has_value()) {
|
if (v.has_value()) {
|
||||||
return v.value();
|
return v.value();
|
||||||
|
|
|
@ -69,7 +69,7 @@ public:
|
||||||
CreatureLib::Battling::BattleScript* LoadScript(const ArbUt::OptionalBorrowedPtr<void>& owner,
|
CreatureLib::Battling::BattleScript* LoadScript(const ArbUt::OptionalBorrowedPtr<void>& owner,
|
||||||
ScriptCategory category,
|
ScriptCategory category,
|
||||||
const ArbUt::StringView& scriptName) override;
|
const ArbUt::StringView& scriptName) override;
|
||||||
CreatureLib::Battling::ItemUseScript* LoadItemScript(const CreatureLib::Library::Item* item) override;
|
PkmnLib::Battling::PkmnItemUseScript* LoadItemScript(const CreatureLib::Library::Item* item) override;
|
||||||
|
|
||||||
ArbUt::OptionalBorrowedPtr<const PkmnLib::Battling::EvolutionScript>
|
ArbUt::OptionalBorrowedPtr<const PkmnLib::Battling::EvolutionScript>
|
||||||
LoadEvolutionScript(const ArbUt::StringView& view) override;
|
LoadEvolutionScript(const ArbUt::StringView& view) override;
|
||||||
|
|
|
@ -463,3 +463,11 @@ void AngelScriptScript::ChangeSpeed(CreatureLib::Battling::BaseTurnChoice* choic
|
||||||
ctx->SetArgAddress(1, (void*)speed);
|
ctx->SetArgAddress(1, (void*)speed);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
void AngelScriptScript::ModifyCaptureRateBonus(CreatureLib::Battling::Creature* pokemon,
|
||||||
|
CreatureLib::Library::Item* catchItem, u8* modifier) {
|
||||||
|
CALL_HOOK(ModifyCaptureRateBonus, {
|
||||||
|
ctx->SetArgObject(0, (void*)pokemon);
|
||||||
|
ctx->SetArgObject(1, (void*)catchItem);
|
||||||
|
ctx->SetArgAddress(2, (void*)modifier);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -163,6 +163,8 @@ public:
|
||||||
CreatureLib::Battling::Creature* target, u8 hitIndex, float* modifier) override;
|
CreatureLib::Battling::Creature* target, u8 hitIndex, float* modifier) override;
|
||||||
void ModifyDefensiveStatValue(CreatureLib::Battling::ExecutingAttack* attack,
|
void ModifyDefensiveStatValue(CreatureLib::Battling::ExecutingAttack* attack,
|
||||||
CreatureLib::Battling::Creature* target, u8 hitIndex, float* modifier) override;
|
CreatureLib::Battling::Creature* target, u8 hitIndex, float* modifier) override;
|
||||||
|
void ModifyCaptureRateBonus(CreatureLib::Battling::Creature* pokemon, CreatureLib::Library::Item* catchItem,
|
||||||
|
u8* modifier) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef CALL_HOOK
|
#undef CALL_HOOK
|
||||||
|
|
|
@ -206,6 +206,8 @@ public:
|
||||||
ModifyDefensiveStatValue,
|
ModifyDefensiveStatValue,
|
||||||
"void ModifyDefensiveStatValue(ExecutingMove@ attack, Pokemon@ target, uint8 hit, float& defensiveStatValue)");
|
"void ModifyDefensiveStatValue(ExecutingMove@ attack, Pokemon@ target, uint8 hit, float& defensiveStatValue)");
|
||||||
SCRIPT_HOOK_FUNCTION(OnAfterHeldItemConsume, "void OnAfterHeldItemConsume(Pokemon@ target, const Item@ item)");
|
SCRIPT_HOOK_FUNCTION(OnAfterHeldItemConsume, "void OnAfterHeldItemConsume(Pokemon@ target, const Item@ item)");
|
||||||
|
SCRIPT_HOOK_FUNCTION(ModifyCaptureRateBonus,
|
||||||
|
"void ModifyCaptureRateBonus(Pokemon@ target, const Item@ item, uint8& bonus)");
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef SCRIPT_HOOK_FUNCTION
|
#undef SCRIPT_HOOK_FUNCTION
|
||||||
|
|
|
@ -89,6 +89,7 @@ shared abstract class ItemUseScript {
|
||||||
|
|
||||||
void OnUse(Battle@ battle) { };
|
void OnUse(Battle@ battle) { };
|
||||||
void OnPokemonUse(Pokemon@ target, bool isBattle) { };
|
void OnPokemonUse(Pokemon@ target, bool isBattle) { };
|
||||||
|
void ModifyPokeballCatchBonus(Pokemon@ target, uint8& catchBonus){};
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
Ensure(r >= 0);
|
Ensure(r >= 0);
|
||||||
|
|
Loading…
Reference in New Issue