Supports cloning battles for AI purposes.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
14016837d9
commit
a88719e2b3
|
@ -14,3 +14,48 @@ void PkmnLib::Battling::Battle::ClearWeather() {
|
|||
_weatherScript = nullptr;
|
||||
_eventHook.Trigger<WeatherChangeEvent>(""_cnc);
|
||||
}
|
||||
PkmnLib::Battling::Battle* PkmnLib::Battling::Battle::Clone() const {
|
||||
auto parties = ArbUt::List<CreatureLib::Battling::BattleParty*>(_parties.Count());
|
||||
for (auto* party : _parties) {
|
||||
parties.Append(party->Clone());
|
||||
}
|
||||
|
||||
auto* battle =
|
||||
new Battle(_library.ForceAs<const BattleLibrary>(), parties, _canFlee, _numberOfSides, _creaturesPerSide);
|
||||
|
||||
for (int i = 0; i < _numberOfSides; ++i) {
|
||||
battle->_sides.Set(i, _sides[i]->CloneWithoutCreatures());
|
||||
// FIXME: This is horrible code to translate the creature from the old battle into the same creature in the
|
||||
// new battle. This needs to be cleaned up, as it's ugly and slow.
|
||||
for (int creatureIndex = 0; creatureIndex < _creaturesPerSide; ++creatureIndex) {
|
||||
auto creature = _sides[i]->GetCreature(creatureIndex);
|
||||
if (!creature.HasValue()) {
|
||||
continue;
|
||||
}
|
||||
for (size_t j = 0; j < _parties.Count(); ++j) {
|
||||
auto party = _parties[j];
|
||||
if (!party->IsResponsibleForIndex(i, creatureIndex)) {
|
||||
continue;
|
||||
}
|
||||
auto partyIndex = party->GetParty()->GetParty().IndexOf(creature.GetValue());
|
||||
if (partyIndex != -1U) {
|
||||
auto c = battle->_parties.At(j)->GetParty()->GetParty()[partyIndex];
|
||||
battle->_sides.At(i)->SetCreature(c, creatureIndex);
|
||||
j = _parties.Count();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
battle->_random = _random;
|
||||
battle->_hasEnded = _hasEnded;
|
||||
battle->_battleResult = _battleResult;
|
||||
_historyHolder.CloneOnto(battle->_historyHolder);
|
||||
battle->_currentTurn = _currentTurn;
|
||||
_volatile.Clone(battle->_volatile);
|
||||
if (_weatherScript != nullptr) {
|
||||
battle->_weatherScript = std::unique_ptr<CreatureLib::Battling::BattleScript>(_weatherScript->Clone());
|
||||
}
|
||||
|
||||
return battle;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ namespace PkmnLib::Battling {
|
|||
scripts.Append(CreatureLib::Battling::ScriptWrapper(
|
||||
CreatureLib::Battling::ScriptWrapper::FromScript(&_weatherScript)));
|
||||
}
|
||||
|
||||
Battle* Clone() const override;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,12 @@ namespace PkmnLib::Battling {
|
|||
const ArbUt::BorrowedPtr<const Library::MoveData> GetMoveData() const {
|
||||
return GetAttack().ForceAs<const Library::MoveData>();
|
||||
}
|
||||
|
||||
LearnedAttack* Clone() const override {
|
||||
auto move = new LearnedMove(GetAttack().ForceAs<const Library::MoveData>(), GetLearnMethod());
|
||||
move->DecreaseUses(GetMaxUses() - GetRemainingUses());
|
||||
return move;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -47,3 +47,46 @@ void PkmnLib::Battling::Pokemon::ClearStatus() {
|
|||
_battle.GetValue()->TriggerEventListener<StatusChangeEvent>(this, ""_cnc);
|
||||
}
|
||||
}
|
||||
|
||||
CreatureLib::Battling::Creature* PkmnLib::Battling::Pokemon::Clone() const {
|
||||
auto moves = std::vector<CreatureLib::Battling::LearnedAttack*>(_attacks.Count());
|
||||
auto i = 0;
|
||||
for (auto* attack : _attacks) {
|
||||
if (attack == nullptr) {
|
||||
moves[i++] = nullptr;
|
||||
} else {
|
||||
moves[i++] = dynamic_cast<LearnedMove*>(attack->Clone());
|
||||
}
|
||||
}
|
||||
|
||||
auto* c = new Pokemon(_library.ForceAs<const BattleLibrary>(), _species.ForceAs<const Library::PokemonSpecies>(),
|
||||
_variant.ForceAs<const Library::PokemonForme>(), _level, _experience, _uniqueIdentifier,
|
||||
_gender, _coloring, _heldItem.ForceAs<const Library::Item>(), _nickname, _talentIndex, moves,
|
||||
_individualValues, _effortValues, _nature, _allowedExperienceGain);
|
||||
c->_displaySpecies = _displaySpecies;
|
||||
c->_displayVariant = _displayVariant;
|
||||
c->_currentHealth = _currentHealth;
|
||||
c->_statBoost = _statBoost;
|
||||
c->_flatStats = _flatStats;
|
||||
c->_boostedStats = _boostedStats;
|
||||
c->_battle = _battle;
|
||||
c->_side = _side;
|
||||
c->_onBattleField = _onBattleField;
|
||||
if (_activeTalent != nullptr) {
|
||||
c->_activeTalent = std::unique_ptr<PkmnScript::BattleScript>(_activeTalent->Clone());
|
||||
}
|
||||
c->_hasOverridenTalent = _hasOverridenTalent;
|
||||
c->_overridenTalentName = _overridenTalentName;
|
||||
if (_status != nullptr) {
|
||||
c->_status = std::unique_ptr<PkmnScript::BattleScript>(_status->Clone());
|
||||
}
|
||||
_volatile.Clone(c->_volatile);
|
||||
c->_types = std::vector<u8>(_types);
|
||||
if (_statusScript != nullptr) {
|
||||
c->_statusScript = std::unique_ptr<PkmnScript::BattleScript>(_statusScript->Clone());
|
||||
}
|
||||
c->_friendship = _friendship;
|
||||
c->RecalculateFlatStats();
|
||||
|
||||
return c;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,8 @@ namespace PkmnLib::Battling {
|
|||
}
|
||||
_friendship = newValue;
|
||||
}
|
||||
|
||||
Creature* Clone() const override;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -10,10 +10,23 @@ namespace PkmnLib::Battling {
|
|||
: CreatureLib::Battling::CreatureParty(std::move(party)) {}
|
||||
PokemonParty(std::initializer_list<CreatureLib::Battling::Creature*> party)
|
||||
: CreatureLib::Battling::CreatureParty(party) {}
|
||||
PokemonParty(size_t size) : CreatureLib::Battling::CreatureParty(size) {}
|
||||
|
||||
ArbUt::OptionalBorrowedPtr<Pokemon> GetAtIndex(int index) const {
|
||||
return CreatureLib::Battling::CreatureParty::GetAtIndex(index).As<Pokemon>();
|
||||
}
|
||||
|
||||
CreatureParty* Clone() const override {
|
||||
auto party = new PokemonParty(GetParty().Count());
|
||||
auto i = 0;
|
||||
for (auto c : GetParty()) {
|
||||
if (c != nullptr) {
|
||||
party->SwapInto(i, c->Clone());
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return party;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -294,9 +294,19 @@ void AngelScriptScript::PreventOpponentSwitch(const CreatureLib::Battling::Switc
|
|||
void AngelScriptScript::OnEndTurn(CreatureLib::Battling::Creature* creature) {
|
||||
CALL_HOOK(OnEndTurn, { ctx->SetArgObject(0, (void*)creature); })
|
||||
}
|
||||
void AngelScriptScript::ModifyNumberOfHits(CreatureLib::Battling::AttackTurnChoice* choice, u8* numberOfHits) {
|
||||
CALL_HOOK(ModifyNumberOfHits, {
|
||||
ctx->SetArgObject(0, (void*)choice);
|
||||
ctx->SetArgAddress(1, numberOfHits);
|
||||
})
|
||||
void AngelScriptScript::ModifyNumberOfHits(CreatureLib::Battling::AttackTurnChoice* choice,
|
||||
u8* numberOfHits){CALL_HOOK(ModifyNumberOfHits,
|
||||
{
|
||||
ctx->SetArgObject(0, (void*)choice);
|
||||
ctx->SetArgAddress(1, numberOfHits);
|
||||
})}
|
||||
|
||||
CreatureLib::Battling::BattleScript* AngelScriptScript::Clone() {
|
||||
auto* ctx = _ctxPool->RequestContext();
|
||||
auto* obj = _type->Instantiate(ctx);
|
||||
if (_obj != nullptr){
|
||||
obj->CopyFrom(_obj);
|
||||
}
|
||||
_ctxPool->ReturnContextToPool(ctx);
|
||||
return new AngelScriptScript(_resolver, _type, obj, _ctxPool);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ public:
|
|||
|
||||
~AngelScriptScript() override { _obj->Release(); }
|
||||
|
||||
BattleScript* Clone() override;
|
||||
|
||||
inline asIScriptObject* GetRawAngelscriptObject() const noexcept { return _obj; }
|
||||
|
||||
[[nodiscard]] const ArbUt::StringView& GetName() const noexcept override { return _type->GetName(); }
|
||||
|
|
Loading…
Reference in New Issue