Adds a bunch of helpers for evolution, as well as custom script evolution methods.
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
@@ -107,13 +107,13 @@ void AngelScriptResolver::Initialize(CreatureLib::Battling::BattleLibrary* arg,
|
||||
|
||||
void AngelScriptResolver::RegisterTypes() {
|
||||
// Register static library types
|
||||
RegisterEffectParameter::Register(_engine);
|
||||
RegisterSpeciesTypes::Register(_engine);
|
||||
RegisterItemTypes::Register(_engine);
|
||||
RegisterMoveTypes::Register(_engine);
|
||||
RegisterGrowthRateTypes::Register(_engine);
|
||||
RegisterTypeLibrary::Register(_engine);
|
||||
RegisterStaticLibraryTypes::Register(_engine);
|
||||
RegisterEffectParameter::Register(_engine);
|
||||
|
||||
// Register battle types
|
||||
// Predeclare these two types, and declare their implementation later.
|
||||
@@ -197,6 +197,31 @@ CreatureLib::Battling::ItemUseScript* AngelScriptResolver::LoadItemScript(const
|
||||
return scriptObject;
|
||||
}
|
||||
|
||||
ArbUt::OptionalBorrowedPtr<const PkmnLib::Battling::EvolutionScript>
|
||||
AngelScriptResolver::LoadEvolutionScript(const ArbUt::StringView& view) {
|
||||
auto v = this->_evolutionScripts.TryGet(view);
|
||||
if (v.has_value()) {
|
||||
return v.value().get();
|
||||
}
|
||||
auto typeInfoOption = _evolutionTypes.TryGet(view);
|
||||
if (!typeInfoOption.has_value()) {
|
||||
return nullptr;
|
||||
}
|
||||
auto* ctx = _contextPool->RequestContext();
|
||||
auto* factory = typeInfoOption.value().get()->GetFactoryByIndex(0);
|
||||
ctx->Prepare(factory);
|
||||
auto result = ctx->Execute();
|
||||
if (result != asEXECUTION_FINISHED) {
|
||||
throw ArbUt::Exception("Instantiation failed.");
|
||||
}
|
||||
asIScriptObject* obj = *(asIScriptObject**)ctx->GetAddressOfReturnValue();
|
||||
obj->AddRef();
|
||||
auto* scriptObject = new AngelScriptEvolutionScript(obj, this);
|
||||
_evolutionScripts.Insert(view, scriptObject);
|
||||
_contextPool->ReturnContextToPool(ctx);
|
||||
return scriptObject;
|
||||
}
|
||||
|
||||
void AngelScriptResolver::FinalizeModule() {
|
||||
int r = _builder.BuildModule();
|
||||
if (r < 0)
|
||||
@@ -208,6 +233,7 @@ void AngelScriptResolver::FinalizeModule() {
|
||||
|
||||
auto pkmnScriptType = _mainModule->GetTypeInfoByName("PkmnScript");
|
||||
auto itemUseScriptType = _mainModule->GetTypeInfoByName("ItemUseScript");
|
||||
auto evolutionScriptType = _mainModule->GetTypeInfoByName("EvolutionScript");
|
||||
for (asUINT n = 0; n < count; n++) {
|
||||
auto typeInfo = _mainModule->GetObjectTypeByIndex(n);
|
||||
if (typeInfo->DerivesFrom(pkmnScriptType)) {
|
||||
@@ -252,6 +278,27 @@ void AngelScriptResolver::FinalizeModule() {
|
||||
_itemUseTypes.Insert(effectName, typeInfo);
|
||||
}
|
||||
}
|
||||
} else if (typeInfo->DerivesFrom(evolutionScriptType)) {
|
||||
auto metadata = _builder.GetMetadataForType(typeInfo->GetTypeId());
|
||||
for (size_t m = 0; m < metadata.size(); m++) {
|
||||
auto data = metadata[m];
|
||||
if (std::regex_match(data, base_match, metadataMatcher)) {
|
||||
auto mt = base_match[1].str();
|
||||
auto metadataKind = ArbUt::StringView(mt.c_str(), mt.length());
|
||||
auto metadataVariables = base_match[2].str();
|
||||
if (!std::regex_match(metadataVariables, base_match, variableMatcher)) {
|
||||
continue;
|
||||
}
|
||||
ArbUt::StringView effectName;
|
||||
for (size_t variableIndex = 1; variableIndex < base_match.size(); variableIndex += 2) {
|
||||
if (ArbUt::StringView::CalculateHash(base_match[variableIndex].str().c_str()) == "effect"_cnc) {
|
||||
auto val = base_match[variableIndex + 1].str();
|
||||
effectName = ArbUt::StringView(val.c_str(), val.length());
|
||||
}
|
||||
}
|
||||
_evolutionTypes.Insert(effectName, typeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,7 +356,7 @@ void AngelScriptResolver::WriteByteCodeToFile(const char* file, bool stripDebugI
|
||||
// We grab the current position of the written file. This is the position the types will be written on. So we need
|
||||
// to know this.
|
||||
uint64_t bytecodeSize = (uint64_t)ftell(wFile);
|
||||
stream->WriteTypes(_typeDatabase, _itemUseTypes);
|
||||
stream->WriteTypes(_typeDatabase, _itemUseTypes, _evolutionTypes);
|
||||
|
||||
// Go back to the start of the file
|
||||
fsetpos(wFile, &startPos);
|
||||
@@ -351,7 +398,7 @@ uint8_t* AngelScriptResolver::WriteByteCodeToMemory(size_t& size, bool stripDebu
|
||||
auto result = _mainModule->SaveByteCode(stream, stripDebugInfo);
|
||||
Ensure(result == asSUCCESS);
|
||||
byteCodeSize[0] = (uint64_t)stream->GetWrittenSize();
|
||||
stream->WriteTypes(_typeDatabase, _itemUseTypes);
|
||||
stream->WriteTypes(_typeDatabase, _itemUseTypes, _evolutionTypes);
|
||||
stream->WriteToPosition(byteCodeSize, sizeof(uint64_t), 0);
|
||||
auto arr = stream->GetOut();
|
||||
size = stream->GetWrittenSize();
|
||||
@@ -376,7 +423,7 @@ void AngelScriptResolver::LoadByteCodeFromMemory(uint8_t* byte, size_t size) {
|
||||
delete stream;
|
||||
}
|
||||
void AngelScriptResolver::InitializeByteCode(
|
||||
const ArbUt::Dictionary<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, uint32_t>>& types) {
|
||||
const ArbUt::Dictionary<i16, ArbUt::Dictionary<ArbUt::StringView, uint32_t>>& types) {
|
||||
|
||||
auto typeCount = _mainModule->GetObjectTypeCount();
|
||||
ArbUt::Dictionary<uint32_t, asITypeInfo*> objectTypes;
|
||||
@@ -386,19 +433,29 @@ void AngelScriptResolver::InitializeByteCode(
|
||||
}
|
||||
ArbUt::Dictionary<ScriptCategory, ArbUt::Dictionary<ArbUt::StringView, AngelScriptTypeInfo*>> typeDatabase;
|
||||
for (const auto& innerDb : types) {
|
||||
if (innerDb.first != (ScriptCategory)-1) {
|
||||
if (innerDb.first >= 0 && innerDb.first <= 255) {
|
||||
ArbUt::Dictionary<ArbUt::StringView, AngelScriptTypeInfo*> newInnerDb;
|
||||
for (const auto& val : innerDb.second) {
|
||||
auto decl = val.second;
|
||||
auto type = objectTypes[decl];
|
||||
newInnerDb.Set(val.first, new AngelScriptTypeInfo(val.first, type));
|
||||
}
|
||||
typeDatabase.Set(innerDb.first, newInnerDb);
|
||||
typeDatabase.Set((ScriptCategory)innerDb.first, newInnerDb);
|
||||
} else {
|
||||
for (const auto& val : innerDb.second) {
|
||||
auto decl = val.second;
|
||||
auto type = objectTypes[decl];
|
||||
_itemUseTypes.Set(val.first, type);
|
||||
if (innerDb.first == -1) {
|
||||
for (const auto& val : innerDb.second) {
|
||||
auto decl = val.second;
|
||||
auto type = objectTypes[decl];
|
||||
_itemUseTypes.Set(val.first, type);
|
||||
}
|
||||
} else if (innerDb.first == -2) {
|
||||
for (const auto& val : innerDb.second) {
|
||||
auto decl = val.second;
|
||||
auto type = objectTypes[decl];
|
||||
_evolutionTypes.Set(val.first, type);
|
||||
}
|
||||
} else {
|
||||
THROW("Resolving unknown script category value: " << innerDb.first);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,4 +483,4 @@ i32 AngelScriptResolver::IncludeCallback(const char* include, const char*, CScri
|
||||
return -102;
|
||||
}
|
||||
return builder->AddSectionFromFile((const char*)path.c_str());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user