2020-01-11 21:30:23 +00:00
|
|
|
#include "AngelScripResolver.hpp"
|
2020-02-16 15:43:37 +00:00
|
|
|
#include <CreatureLib/Battling/Models/Creature.hpp>
|
|
|
|
#include <cassert>
|
2020-04-10 12:57:20 +00:00
|
|
|
#include <regex>
|
2020-02-02 11:23:50 +00:00
|
|
|
#include "../../../extern/angelscript_addons/scriptarray/scriptarray.h"
|
2020-02-04 18:34:30 +00:00
|
|
|
#include "../../../extern/angelscript_addons/scripthandle/scripthandle.h"
|
2020-02-02 11:23:50 +00:00
|
|
|
#include "../../../extern/angelscript_addons/scripthelper/scripthelper.h"
|
|
|
|
#include "../../../extern/angelscript_addons/scriptstdstring/scriptstdstring.h"
|
2020-02-04 18:34:30 +00:00
|
|
|
#include "TypeRegistry/BasicScriptClass.hpp"
|
2020-02-16 15:43:37 +00:00
|
|
|
#include "TypeRegistry/Battling/RegisterBattleClass.hpp"
|
|
|
|
#include "TypeRegistry/Battling/RegisterBattleLibrary.hpp"
|
2020-01-26 14:18:04 +00:00
|
|
|
#include "TypeRegistry/Battling/RegisterExecutingAttack.hpp"
|
|
|
|
#include "TypeRegistry/Battling/RegisterPokemonClass.hpp"
|
2020-02-16 15:43:37 +00:00
|
|
|
#include "TypeRegistry/Battling/RegisterTurnChoices.hpp"
|
2020-04-06 18:03:44 +00:00
|
|
|
#include "TypeRegistry/ConstString.hpp"
|
2020-01-13 18:52:32 +00:00
|
|
|
#include "TypeRegistry/Library/RegisterGrowthRateTypes.hpp"
|
|
|
|
#include "TypeRegistry/Library/RegisterItemTypes.hpp"
|
|
|
|
#include "TypeRegistry/Library/RegisterMoveTypes.hpp"
|
2020-01-13 19:05:03 +00:00
|
|
|
#include "TypeRegistry/Library/RegisterSpeciesTypes.hpp"
|
2020-01-23 14:10:08 +00:00
|
|
|
#include "TypeRegistry/Library/RegisterStaticLibraryTypes.hpp"
|
2020-01-13 19:16:23 +00:00
|
|
|
#include "TypeRegistry/Library/RegisterTypeLibrary.hpp"
|
2020-01-11 21:30:23 +00:00
|
|
|
|
2020-01-13 18:43:34 +00:00
|
|
|
CreatureLib::Battling::ScriptResolver* PkmnLib::Battling::BattleLibrary::CreateScriptResolver() {
|
2020-01-11 21:30:23 +00:00
|
|
|
return new AngelScripResolver();
|
|
|
|
}
|
2020-01-12 17:20:59 +00:00
|
|
|
|
2020-02-04 18:34:30 +00:00
|
|
|
void AngelScripResolver::Initialize(CreatureLib::Battling::BattleLibrary* arg) {
|
2020-04-10 12:57:20 +00:00
|
|
|
for (auto scriptCategory : ScriptCategoryHelper::GetValues()) {
|
|
|
|
_typeDatabase.Insert(scriptCategory, {});
|
|
|
|
}
|
|
|
|
|
2020-02-04 18:34:30 +00:00
|
|
|
auto library = (PkmnLib::Battling::BattleLibrary*)arg;
|
2020-01-11 21:30:23 +00:00
|
|
|
_engine = asCreateScriptEngine();
|
|
|
|
|
2020-01-26 14:18:04 +00:00
|
|
|
int32_t r = _engine->SetMessageCallback(asFUNCTION(MessageCallback), nullptr, asCALL_CDECL);
|
|
|
|
if (r < 0)
|
|
|
|
throw CreatureException("Registering message callback failed.");
|
|
|
|
|
2020-01-11 21:30:23 +00:00
|
|
|
_engine->SetEngineProperty(asEP_DISALLOW_EMPTY_LIST_ELEMENTS, true);
|
2020-02-04 18:34:30 +00:00
|
|
|
_engine->SetEngineProperty(asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE, false);
|
|
|
|
_engine->SetEngineProperty(asEP_ALLOW_UNSAFE_REFERENCES, true);
|
2020-01-11 21:30:23 +00:00
|
|
|
_engine->SetEngineProperty(asEP_ALWAYS_IMPL_DEFAULT_CONSTRUCT, true);
|
|
|
|
_engine->SetEngineProperty(asEP_AUTO_GARBAGE_COLLECT, false);
|
2020-01-18 12:07:56 +00:00
|
|
|
_engine->SetEngineProperty(asEP_REQUIRE_ENUM_SCOPE, true);
|
2020-02-04 18:34:30 +00:00
|
|
|
_engine->SetEngineProperty(asEP_PROPERTY_ACCESSOR_MODE, 2);
|
2020-02-16 15:43:37 +00:00
|
|
|
_engine->SetEngineProperty(asEP_COMPILER_WARNINGS, 2);
|
2020-01-11 21:30:23 +00:00
|
|
|
|
|
|
|
RegisterStdString(_engine);
|
2020-04-06 18:03:44 +00:00
|
|
|
ConstStringRegister::Register(_engine);
|
2020-01-26 14:18:04 +00:00
|
|
|
|
|
|
|
// Register Script Array type
|
|
|
|
RegisterScriptArray(_engine, true);
|
|
|
|
|
2020-01-11 21:30:23 +00:00
|
|
|
r = _engine->RegisterGlobalFunction("void print(const string &in)", asFUNCTION(Print), asCALL_CDECL);
|
2020-01-13 18:43:34 +00:00
|
|
|
if (r < 0)
|
|
|
|
throw CreatureException("Registering print function failed.");
|
2020-02-04 18:34:30 +00:00
|
|
|
RegisterScriptHandle(_engine);
|
|
|
|
|
2020-02-19 08:07:44 +00:00
|
|
|
_builder.StartNewModule(_engine, "pkmn");
|
|
|
|
_mainModule = _builder.GetModule();
|
2020-01-11 21:30:23 +00:00
|
|
|
|
2020-01-26 14:18:04 +00:00
|
|
|
RegisterTypes();
|
2020-01-11 21:30:23 +00:00
|
|
|
RegisterExceptionRoutines(_engine);
|
|
|
|
|
2020-02-04 18:34:30 +00:00
|
|
|
auto staticLib = library->GetStaticLib();
|
|
|
|
_engine->RegisterGlobalProperty("const StaticLibrary@ StaticLib", &staticLib);
|
2020-01-26 14:18:04 +00:00
|
|
|
|
|
|
|
_contextPool = new ContextPool(_engine);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AngelScripResolver::RegisterTypes() {
|
|
|
|
// Register static library types
|
2020-01-13 19:05:03 +00:00
|
|
|
RegisterSpeciesTypes::Register(_engine);
|
2020-01-13 18:21:41 +00:00
|
|
|
RegisterItemTypes::Register(_engine);
|
2020-01-13 18:43:34 +00:00
|
|
|
RegisterMoveTypes::Register(_engine);
|
2020-01-13 18:52:32 +00:00
|
|
|
RegisterGrowthRateTypes::Register(_engine);
|
2020-01-13 19:16:23 +00:00
|
|
|
RegisterTypeLibrary::Register(_engine);
|
2020-01-23 14:10:08 +00:00
|
|
|
RegisterStaticLibraryTypes::Register(_engine);
|
2020-01-11 21:30:23 +00:00
|
|
|
|
2020-01-26 14:18:04 +00:00
|
|
|
// Register battle types
|
|
|
|
RegisterPokemonClass::Register(_engine);
|
|
|
|
RegisterExecutingAttack::Register(_engine);
|
2020-02-16 15:43:37 +00:00
|
|
|
RegisterTurnChoices::Register(_engine);
|
|
|
|
RegisterBattleLibrary::Register(_engine);
|
|
|
|
RegisterBattleClass::Register(_engine);
|
|
|
|
[[maybe_unused]] int r =
|
|
|
|
_engine->RegisterObjectMethod("Pokemon", "const Battle@ get_Battle() const property",
|
|
|
|
asMETHOD(CreatureLib::Battling::Creature, GetBattle), asCALL_THISCALL);
|
|
|
|
assert(r >= 0);
|
2020-02-04 18:34:30 +00:00
|
|
|
|
|
|
|
// Register base script
|
|
|
|
BasicScriptClass::Register(_engine);
|
2020-01-11 21:30:23 +00:00
|
|
|
}
|
2020-01-26 14:18:04 +00:00
|
|
|
|
2020-01-11 21:30:23 +00:00
|
|
|
void AngelScripResolver::MessageCallback(const asSMessageInfo* msg, void* param) {
|
|
|
|
const char* type = "ERR ";
|
|
|
|
if (msg->type == asMSGTYPE_WARNING)
|
|
|
|
type = "WARN";
|
|
|
|
else if (msg->type == asMSGTYPE_INFORMATION)
|
|
|
|
type = "INFO";
|
|
|
|
printf("%s (%d, %d) : %s : %s\n", msg->section, msg->row, msg->col, type, msg->message);
|
|
|
|
}
|
2020-02-16 13:38:05 +00:00
|
|
|
|
2020-02-28 18:51:50 +00:00
|
|
|
CreatureLib::Battling::Script* AngelScripResolver::LoadScript(ScriptCategory category, const ConstString& scriptName) {
|
2020-04-10 12:57:20 +00:00
|
|
|
Dictionary<uint32_t, AngelScriptTypeInfo*> innerDb;
|
|
|
|
if (!_typeDatabase.TryGet(category, innerDb)) {
|
|
|
|
_typeDatabase.Insert(category, innerDb);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
AngelScriptTypeInfo* t;
|
|
|
|
if (!innerDb.TryGet(scriptName, t)) {
|
|
|
|
innerDb.Insert(scriptName, nullptr);
|
2020-01-13 18:43:34 +00:00
|
|
|
return nullptr;
|
2020-04-10 12:57:20 +00:00
|
|
|
}
|
|
|
|
if (t == nullptr) {
|
|
|
|
return nullptr;
|
|
|
|
}
|
2020-01-11 21:30:23 +00:00
|
|
|
auto ctx = _contextPool->RequestContext();
|
2020-04-10 12:57:20 +00:00
|
|
|
auto obj = t->Instantiate(ctx);
|
2020-01-11 21:30:23 +00:00
|
|
|
_contextPool->ReturnContextToPool(ctx);
|
2020-04-10 12:57:20 +00:00
|
|
|
return new AngelScriptScript(t, obj, _contextPool);
|
2020-01-11 21:30:23 +00:00
|
|
|
}
|
|
|
|
void AngelScripResolver::FinalizeModule() {
|
2020-02-19 08:07:44 +00:00
|
|
|
int r = _builder.BuildModule();
|
2020-01-11 21:30:23 +00:00
|
|
|
if (r < 0)
|
|
|
|
throw CreatureException("Building Script Module failed.");
|
2020-04-10 12:57:20 +00:00
|
|
|
int count = _mainModule->GetObjectTypeCount();
|
|
|
|
std::regex metadataMatcher("^\\s*(\\w+)([\\w\\s=]*)$", std::regex_constants::icase);
|
|
|
|
std::regex variableMatcher("\\s*(\\w+)=(\\w+)", std::regex_constants::icase);
|
|
|
|
std::smatch base_match;
|
|
|
|
|
2020-04-10 13:10:22 +00:00
|
|
|
for (size_t n = 0; n < count; n++) {
|
2020-04-10 12:57:20 +00:00
|
|
|
auto typeInfo = _mainModule->GetObjectTypeByIndex(n);
|
|
|
|
auto metadata = _builder.GetMetadataForType(typeInfo->GetTypeId());
|
2020-04-10 13:10:22 +00:00
|
|
|
for (size_t m = 0; m < metadata.size(); m++) {
|
2020-04-10 12:57:20 +00:00
|
|
|
auto data = metadata[m];
|
|
|
|
if (std::regex_match(data, base_match, metadataMatcher)) {
|
|
|
|
auto metadataKind = base_match[1].str();
|
|
|
|
auto metadataVariables = base_match[2].str();
|
|
|
|
if (!std::regex_match(metadataVariables, base_match, variableMatcher)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ConstString effectName;
|
|
|
|
for (size_t variableIndex = 1; variableIndex < base_match.size(); variableIndex += 2) {
|
|
|
|
if (base_match[variableIndex] == "effect") {
|
|
|
|
auto val = base_match[variableIndex + 1].str();
|
|
|
|
effectName = ConstString(val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (effectName.Empty()) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (metadataKind == "Move") {
|
|
|
|
_typeDatabase[ScriptCategory::Attack].Insert(effectName,
|
|
|
|
new AngelScriptTypeInfo(effectName, typeInfo));
|
|
|
|
} else if (metadataKind == "Pokemon") {
|
|
|
|
_typeDatabase[ScriptCategory::Creature].Insert(effectName,
|
|
|
|
new AngelScriptTypeInfo(effectName, typeInfo));
|
|
|
|
} else if (metadataKind == "Ability") {
|
|
|
|
_typeDatabase[ScriptCategory::Talent].Insert(effectName,
|
|
|
|
new AngelScriptTypeInfo(effectName, typeInfo));
|
|
|
|
} else if (metadataKind == "Status") {
|
|
|
|
_typeDatabase[ScriptCategory::Status].Insert(effectName,
|
|
|
|
new AngelScriptTypeInfo(effectName, typeInfo));
|
|
|
|
} else if (metadataKind == "Battle") {
|
|
|
|
_typeDatabase[ScriptCategory::Battle].Insert(effectName,
|
|
|
|
new AngelScriptTypeInfo(effectName, typeInfo));
|
|
|
|
} else if (metadataKind == "Side") {
|
|
|
|
_typeDatabase[ScriptCategory::Side].Insert(effectName,
|
|
|
|
new AngelScriptTypeInfo(effectName, typeInfo));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-01-11 21:30:23 +00:00
|
|
|
}
|
2020-02-16 12:33:58 +00:00
|
|
|
void AngelScripResolver::CreateScript(const char* name, const char* script) {
|
2020-02-19 08:07:44 +00:00
|
|
|
_builder.AddSectionFromMemory(name, script);
|
2020-01-11 21:30:23 +00:00
|
|
|
}
|