Skip to content

Commit

Permalink
feat(skymp5-server): add playable race filter for espm characters (sk…
Browse files Browse the repository at this point in the history
  • Loading branch information
Pospelove authored Apr 8, 2024
1 parent 0040a96 commit f62cf1b
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
33 changes: 33 additions & 0 deletions skymp5-server/cpp/server_guest_lib/WorldState.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "WorldState.h"
#include "EvaluateTemplate.h"
#include "FormCallbacks.h"
#include "LeveledListUtils.h"
#include "LocationalDataUtils.h"
#include "MpActor.h"
#include "MpChangeForms.h"
Expand Down Expand Up @@ -409,6 +411,37 @@ bool WorldState::AttachEspmRecord(const espm::CombineBrowser& br,
return false;
}
}

const int kPcLevel = 0; // Shouldn't mean much to races

// May be not exact the same template chain as it would be in MpActor
// but it's ok for this check
std::vector<uint32_t> evaluateChainResult =
LeveledListUtils::EvaluateTemplateChain(br, base, kPcLevel);
std::vector<FormDesc> templateChain(evaluateChainResult.size());
std::transform(evaluateChainResult.begin(), evaluateChainResult.end(),
templateChain.begin(), [&](uint32_t formId) {
return FormDesc::FromFormId(formId, this->espmFiles);
});

uint32_t race = EvaluateTemplate<espm::NPC_::UseTraits>(
this, baseId, templateChain,
[&](const auto& npcLookupResult, const auto& npcData) {
return npcLookupResult.ToGlobalId(npcData.race);
});

bool isBanned = std::find(bannedEspmCharacterRaceIds.begin(),
bannedEspmCharacterRaceIds.end(),
race) != bannedEspmCharacterRaceIds.end();
if (isBanned) {
logger->info("Skipping actor {:#x} because it has banned race {:#x}",
record->GetId(), race);
if (optionalOutTrace) {
*optionalOutTrace << fmt::format("Skip NPC due to banned race")
<< std::endl;
}
return false;
}
}

auto locationalData = data.loc;
Expand Down
10 changes: 10 additions & 0 deletions skymp5-server/cpp/server_guest_lib/WorldState.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,16 @@ class WorldState

bool disableVanillaScriptsInExterior = true;

std::vector<uint32_t> bannedEspmCharacterRaceIds = {
0x000e7713, 0x00012e82, 0x001052a3, 0x00088884, 0x0008883a, 0x00088846,
0x00108272, 0x000a82b9, 0x0008883c, 0x00088794, 0x00088845, 0x0008883d,
0x00088844, 0x00088840, 0x000a82ba,

/* Playable races from ArgonianRace to WoodElfRace */
0x00013740, 0x00013741, 0x00013742, 0x00013743, 0x00013744, 0x00013745,
0x00013746, 0x00013747, 0x00013748, 0x00013749
};

private:
bool AttachEspmRecord(const espm::CombineBrowser& br,
const espm::RecordHeader* record,
Expand Down
2 changes: 2 additions & 0 deletions unit/PartOne_ActivateTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ PartOne& GetPartOne()
std::make_shared<DirectoryScriptStorage>(TEST_PEX_DIR));
instance->AttachEspm(&l);

instance->worldState.bannedEspmCharacterRaceIds.clear();

static std::vector<std::shared_ptr<PartOne>> g_partOneInstances;
g_partOneInstances.push_back(instance);
return *g_partOneInstances.back();
Expand Down

0 comments on commit f62cf1b

Please sign in to comment.