Support for experience sharing.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
d6792635f9
commit
0d111739f4
|
@ -1,7 +1,19 @@
|
||||||
#include "ExperienceLibrary.hpp"
|
#include "ExperienceLibrary.hpp"
|
||||||
|
#include <CreatureLib/Battling/Models/Battle.hpp>
|
||||||
#include "../PkmnScriptHook.hpp"
|
#include "../PkmnScriptHook.hpp"
|
||||||
#include "../Pokemon/Pokemon.hpp"
|
#include "../Pokemon/Pokemon.hpp"
|
||||||
|
|
||||||
|
static inline uint32_t CalculateDynamicExperience(uint8_t level, float v1, CreatureLib::Battling::Creature* op,
|
||||||
|
CreatureLib::Battling::Creature* faintedMon) {
|
||||||
|
float a = 2 * level + 10;
|
||||||
|
float b = level + op->GetLevel() + 10;
|
||||||
|
float v2 = (a * a * sqrt(a)) / (b * b * sqrt(b));
|
||||||
|
uint32_t experienceGain = v1 * v2 + 1;
|
||||||
|
// TODO: Check owner and international
|
||||||
|
PKMN_HOOK(ModifyExperienceGain, op, faintedMon, op, &experienceGain);
|
||||||
|
return experienceGain;
|
||||||
|
}
|
||||||
|
|
||||||
void PkmnLib::Battling::ExperienceLibrary::HandleExperienceGain(
|
void PkmnLib::Battling::ExperienceLibrary::HandleExperienceGain(
|
||||||
CreatureLib::Battling::Creature* faintedMon,
|
CreatureLib::Battling::Creature* faintedMon,
|
||||||
const std::unordered_set<CreatureLib::Battling::Creature*>& opponents) const {
|
const std::unordered_set<CreatureLib::Battling::Creature*>& opponents) const {
|
||||||
|
@ -9,17 +21,45 @@ void PkmnLib::Battling::ExperienceLibrary::HandleExperienceGain(
|
||||||
auto fainted = dynamic_cast<Pokemon*>(faintedMon);
|
auto fainted = dynamic_cast<Pokemon*>(faintedMon);
|
||||||
auto expGain = fainted->GetForme()->GetBaseExperience();
|
auto expGain = fainted->GetForme()->GetBaseExperience();
|
||||||
auto level = fainted->GetLevel();
|
auto level = fainted->GetLevel();
|
||||||
// TODO exp share
|
|
||||||
|
|
||||||
auto v1 = (expGain * level) / 5;
|
float v1 = (expGain * level) / 5;
|
||||||
|
|
||||||
for (auto op : opponents) {
|
for (auto op : opponents) {
|
||||||
if (!op->AllowedExperienceGain())
|
if (!op->AllowedExperienceGain())
|
||||||
continue;
|
continue;
|
||||||
auto v2 = pow(2 * level + 10, 2.5) / pow(level + op->GetLevel() + 10, 2.5);
|
auto experienceGain = CalculateDynamicExperience(level, v1, op, fainted);
|
||||||
uint32_t experienceGain = v1 * v2 + 1;
|
op->AddExperience(experienceGain);
|
||||||
// TODO: Check owner and international
|
}
|
||||||
PKMN_HOOK(ModifyExperienceGain, op, faintedMon, op, experienceGain);
|
|
||||||
|
auto battle = fainted->GetBattle();
|
||||||
|
if (battle == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_set<CreatureLib::Battling::Creature*> shareExperience;
|
||||||
|
for (const auto& party : battle->GetParties()) {
|
||||||
|
for (const auto& mon : party->GetParty()->GetParty()) {
|
||||||
|
if (mon == nullptr)
|
||||||
|
continue;
|
||||||
|
// If the mon is not allowed to gain experience, or is fainted, don't check for experience sharing.
|
||||||
|
if (!mon->AllowedExperienceGain() || mon->IsFainted())
|
||||||
|
continue;
|
||||||
|
// If the mon is already in the opponents set, don't check for experience sharing.
|
||||||
|
if (opponents.find(mon) != opponents.end())
|
||||||
|
continue;
|
||||||
|
bool sharedExp = false;
|
||||||
|
PKMN_HOOK(DoesShareExperience, mon, faintedMon, mon, &sharedExp);
|
||||||
|
if (sharedExp) {
|
||||||
|
shareExperience.insert(mon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shareExperience.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
v1 /= 2;
|
||||||
|
for (auto op : shareExperience) {
|
||||||
|
auto experienceGain = CalculateDynamicExperience(level, v1, op, faintedMon);
|
||||||
op->AddExperience(experienceGain);
|
op->AddExperience(experienceGain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,9 @@ namespace PkmnLib::Battling {
|
||||||
virtual void ModifyCriticalStage(CreatureLib::Battling::ExecutingAttack* attack,
|
virtual void ModifyCriticalStage(CreatureLib::Battling::ExecutingAttack* attack,
|
||||||
CreatureLib::Battling::Creature* target, uint8_t hit, uint8_t* critStage){};
|
CreatureLib::Battling::Creature* target, uint8_t hit, uint8_t* critStage){};
|
||||||
virtual void ModifyExperienceGain(CreatureLib::Battling::Creature* faintedMon,
|
virtual void ModifyExperienceGain(CreatureLib::Battling::Creature* faintedMon,
|
||||||
CreatureLib::Battling::Creature* winningMon, uint32_t experienceGain){};
|
CreatureLib::Battling::Creature* winningMon, uint32_t* experienceGain){};
|
||||||
|
virtual void DoesShareExperience(CreatureLib::Battling::Creature* faintedMon,
|
||||||
|
CreatureLib::Battling::Creature* winningMon, bool* shareExperience){};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -258,3 +258,19 @@ void AngelScriptScript::ModifyCriticalStage(CreatureLib::Battling::ExecutingAtta
|
||||||
ctx->SetArgAddress(3, critStage);
|
ctx->SetArgAddress(3, critStage);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
void AngelScriptScript::ModifyExperienceGain(CreatureLib::Battling::Creature* faintedMon,
|
||||||
|
CreatureLib::Battling::Creature* winningMon, uint32_t* experienceGain) {
|
||||||
|
CALL_HOOK(ModifyExperienceGain, {
|
||||||
|
ctx->SetArgObject(0, (void*)faintedMon);
|
||||||
|
ctx->SetArgObject(1, (void*)winningMon);
|
||||||
|
ctx->SetArgAddress(2, experienceGain);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
void AngelScriptScript::DoesShareExperience(CreatureLib::Battling::Creature* faintedMon,
|
||||||
|
CreatureLib::Battling::Creature* winningMon, bool* shareExperience) {
|
||||||
|
CALL_HOOK(DoesShareExperience, {
|
||||||
|
ctx->SetArgObject(0, (void*)faintedMon);
|
||||||
|
ctx->SetArgObject(1, (void*)winningMon);
|
||||||
|
ctx->SetArgAddress(2, shareExperience);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -104,6 +104,11 @@ public:
|
||||||
|
|
||||||
void ModifyCriticalStage(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
|
void ModifyCriticalStage(CreatureLib::Battling::ExecutingAttack* attack, CreatureLib::Battling::Creature* target,
|
||||||
uint8_t hit, uint8_t* critStage) override;
|
uint8_t hit, uint8_t* critStage) override;
|
||||||
|
|
||||||
|
void ModifyExperienceGain(CreatureLib::Battling::Creature* faintedMon, CreatureLib::Battling::Creature* winningMon,
|
||||||
|
uint32_t* experienceGain) override;
|
||||||
|
void DoesShareExperience(CreatureLib::Battling::Creature* faintedMon, CreatureLib::Battling::Creature* winningMon,
|
||||||
|
bool* shareExperience) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef CALL_HOOK
|
#undef CALL_HOOK
|
||||||
|
|
|
@ -131,6 +131,10 @@ public:
|
||||||
SCRIPT_HOOK_FUNCTION(
|
SCRIPT_HOOK_FUNCTION(
|
||||||
ModifyCriticalStage,
|
ModifyCriticalStage,
|
||||||
"void ModifyCriticalStage(ExecutingMove@ attack, Pokemon@ target, uint8 hit, uint8& critStage)");
|
"void ModifyCriticalStage(ExecutingMove@ attack, Pokemon@ target, uint8 hit, uint8& critStage)");
|
||||||
|
SCRIPT_HOOK_FUNCTION(ModifyExperienceGain,
|
||||||
|
"void ModifyExperienceGain(Pokemon@ faintedMon, Pokemon@ winningMon, uint32& critStage)");
|
||||||
|
SCRIPT_HOOK_FUNCTION(DoesShareExperience,
|
||||||
|
"void DoesShareExperience(Pokemon@ faintedMon, Pokemon@ winningMon, bool& shareExperience)");
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef SCRIPT_HOOK_FUNCTION
|
#undef SCRIPT_HOOK_FUNCTION
|
||||||
|
|
|
@ -39,6 +39,8 @@ shared abstract class PkmnScript {
|
||||||
|
|
||||||
// PkmnLib methods
|
// PkmnLib methods
|
||||||
void ModifyCriticalStage(ExecutingMove@ attack, Pokemon@ target, uint8 hit, uint8& critStage){};
|
void ModifyCriticalStage(ExecutingMove@ attack, Pokemon@ target, uint8 hit, uint8& critStage){};
|
||||||
|
void ModifyExperienceGain(Pokemon@ faintedMon, Pokemon@ winningMon, uint32& critStage){};
|
||||||
|
void DoesShareExperience(Pokemon@ faintedMon, Pokemon@ winningMon, bool& shareExperience){};
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
|
|
Loading…
Reference in New Issue