Initial support for item use scripts in angelscript.
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:
@@ -127,7 +127,7 @@ void AngelScriptResolver::MessageCallback(const asSMessageInfo* msg, void*) {
|
||||
}
|
||||
|
||||
CreatureLib::Battling::BattleScript* AngelScriptResolver::LoadScript(ScriptCategory category,
|
||||
const ArbUt::StringView& scriptName) {
|
||||
const ArbUt::StringView& scriptName) {
|
||||
ArbUt::Dictionary<ArbUt::StringView, AngelScriptTypeInfo*> innerDb;
|
||||
auto v = _typeDatabase.TryGet(category);
|
||||
if (!v.has_value()) {
|
||||
@@ -150,6 +150,36 @@ CreatureLib::Battling::BattleScript* AngelScriptResolver::LoadScript(ScriptCateg
|
||||
_contextPool->ReturnContextToPool(ctx);
|
||||
return new AngelScriptScript(this, t.value(), obj, _contextPool);
|
||||
}
|
||||
|
||||
CreatureLib::Battling::ItemUseScript* AngelScriptResolver::LoadItemScript(const CreatureLib::Library::Item* item) {
|
||||
auto v = this->_itemUseScripts.TryGet(item);
|
||||
if (v.has_value()) {
|
||||
return v.value();
|
||||
}
|
||||
if (!item->GetEffect().HasValue()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto typeInfoOption = _itemUseTypes.TryGet(item->GetEffect().GetValue()->GetEffectName());
|
||||
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 AngelScriptItemUseScript(obj, this);
|
||||
_itemUseScripts.Insert(item, scriptObject);
|
||||
_contextPool->ReturnContextToPool(ctx);
|
||||
return scriptObject;
|
||||
}
|
||||
|
||||
void AngelScriptResolver::FinalizeModule() {
|
||||
int r = _builder.BuildModule();
|
||||
if (r < 0)
|
||||
@@ -159,62 +189,85 @@ void AngelScriptResolver::FinalizeModule() {
|
||||
std::regex variableMatcher(R"(\s*(\w+)=(\w+))", std::regex_constants::icase);
|
||||
std::smatch base_match;
|
||||
|
||||
auto pkmnScriptType = _mainModule->GetTypeInfoByName("PkmnScript");
|
||||
auto itemUseScriptType = _mainModule->GetTypeInfoByName("ItemUseScript");
|
||||
for (asUINT n = 0; n < count; n++) {
|
||||
auto typeInfo = _mainModule->GetObjectTypeByIndex(n);
|
||||
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());
|
||||
if (typeInfo->DerivesFrom(pkmnScriptType)) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
RegisterScriptType(typeInfo, metadataKind, effectName);
|
||||
}
|
||||
if (effectName.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
switch (metadataKind) {
|
||||
case "Move"_cnc:
|
||||
_typeDatabase[ScriptCategory::Attack].Insert(effectName,
|
||||
new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Pokemon"_cnc:
|
||||
_typeDatabase[ScriptCategory::Creature].Insert(effectName,
|
||||
new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Ability"_cnc:
|
||||
_typeDatabase[ScriptCategory::Talent].Insert(effectName,
|
||||
new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Status"_cnc:
|
||||
_typeDatabase[ScriptCategory::Status].Insert(effectName,
|
||||
new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Battle"_cnc:
|
||||
_typeDatabase[ScriptCategory::Battle].Insert(effectName,
|
||||
new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Side"_cnc:
|
||||
_typeDatabase[ScriptCategory::Side].Insert(effectName,
|
||||
new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Weather"_cnc:
|
||||
_typeDatabase[static_cast<ScriptCategory>(PkmnScriptCategory::Weather)].Insert(
|
||||
effectName, new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
}
|
||||
} else if (typeInfo->DerivesFrom(itemUseScriptType)) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
_itemUseTypes.Insert(effectName, typeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void AngelScriptResolver::RegisterScriptType(asITypeInfo* typeInfo, const ArbUt::StringView& metadataKind,
|
||||
const ArbUt::StringView& effectName) {
|
||||
if (effectName.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
switch (metadataKind) {
|
||||
case "Move"_cnc:
|
||||
_typeDatabase[ScriptCategory::Attack].Insert(effectName, new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Pokemon"_cnc:
|
||||
_typeDatabase[ScriptCategory::Creature].Insert(effectName, new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Ability"_cnc:
|
||||
_typeDatabase[ScriptCategory::Talent].Insert(effectName, new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Status"_cnc:
|
||||
_typeDatabase[ScriptCategory::Status].Insert(effectName, new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Battle"_cnc:
|
||||
_typeDatabase[ScriptCategory::Battle].Insert(effectName, new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Side"_cnc:
|
||||
_typeDatabase[ScriptCategory::Side].Insert(effectName, new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
case "Weather"_cnc:
|
||||
_typeDatabase[static_cast<ScriptCategory>(PkmnScriptCategory::Weather)].Insert(
|
||||
effectName, new AngelScriptTypeInfo(effectName, typeInfo));
|
||||
break;
|
||||
}
|
||||
}
|
||||
void AngelScriptResolver::CreateScript(const char* name, const char* script) {
|
||||
_builder.AddSectionFromMemory(name, script);
|
||||
}
|
||||
@@ -325,4 +378,4 @@ void AngelScriptResolver::InitializeByteCode(
|
||||
typeDatabase.Set(innerDb.first, newInnerDb);
|
||||
}
|
||||
_typeDatabase = typeDatabase;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user