Files
Akebi-GC/cheat-library/src/user/cheat/world/DialogSkip.cpp

136 lines
5.4 KiB
C++
Raw Normal View History

2022-05-17 03:13:41 +03:00
#include "pch-il2cpp.h"
#include "DialogSkip.h"
#include <helpers.h>
#include <cheat/game/EntityManager.h>
namespace cheat::feature
{
static void InLevelCutScenePageContext_UpdateView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method);
static void InLevelCutScenePageContext_ClearView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method);
DialogSkip::DialogSkip() : Feature(),
NF(f_Enabled, "Auto talk", "AutoTalk", false),
NF(f_AutoSelectDialog, "Auto select dialog", "AutoTalk", true),
NF(f_ExcludeImportant, "Exclude Katheryne/Tubby", "AutoTalk", true),
NF(f_FastDialog, "Fast dialog", "AutoTalk", false),
NF(f_TimeSpeedup, "Time Speed", "AutoTalk", 5.0f)
{
HookManager::install(app::InLevelCutScenePageContext_UpdateView, InLevelCutScenePageContext_UpdateView_Hook);
HookManager::install(app::InLevelCutScenePageContext_ClearView, InLevelCutScenePageContext_ClearView_Hook);
}
const FeatureGUIInfo& DialogSkip::GetGUIInfo() const
{
static const FeatureGUIInfo info{ "Auto Talk", "World", true };
return info;
}
void DialogSkip::DrawMain()
{
ConfigWidget("Enabled", f_Enabled, "Automatically continue the dialog.");
ConfigWidget("Auto-select Dialog", f_AutoSelectDialog, "Automatically select dialog choices.");
if (f_AutoSelectDialog)
{
ImGui::Indent();
ConfigWidget("Exclude Katheryne/Tubby", f_ExcludeImportant, "Exclude Kath/Tubby from auto-select.");
ImGui::Unindent();
}
ConfigWidget("Fast Dialog", f_FastDialog, "Speeds up Time");
if (f_FastDialog)
{
ConfigWidget(f_TimeSpeedup, 0.1f, 2.0f, 50.0f, "Time Speedup Multipler \nHigher Values will lead to sync issues with servers \nand is not recommended for Laggy Internet connections.");
}
}
bool DialogSkip::NeedStatusDraw() const
{
return f_Enabled;
}
void DialogSkip::DrawStatus()
{
ImGui::Text("Dialog [%s%s%s%s%s]",
f_AutoSelectDialog ? "Auto" : "Manual",
f_AutoSelectDialog && (f_ExcludeImportant || f_FastDialog) ? "|" : "",
f_ExcludeImportant ? "Exc" : "",
f_ExcludeImportant && f_FastDialog ? "|" : "",
f_FastDialog ? "Fast" : "Normal");
}
DialogSkip& DialogSkip::GetInstance()
{
static DialogSkip instance;
return instance;
}
// Raised when dialog view updating
// We call free click, if auto talk enabled, that means we just emulate user click
// When appear dialog choose we create notify with dialog select first item.
void DialogSkip::OnCutScenePageUpdate(app::InLevelCutScenePageContext* context)
{
if (!f_Enabled)
return;
auto talkDialog = context->fields._talkDialog;
if (talkDialog == nullptr)
return;
if (f_FastDialog)
app::Time_set_timeScale(nullptr, f_TimeSpeedup, nullptr);
bool isImportant = false;
if (f_ExcludeImportant)
{
// TODO: Add a custom filter in the future where users can
// add their own name substrings of entities to avoid
// speeding up dialog on.
std::vector<std::string> impEntitiesNames = {
"Djinn",
"Katheryne"
};
auto dialogPartnerID = context->fields._inteeID;
auto& manager = game::EntityManager::instance();
auto dialogPartner = manager.entity(dialogPartnerID);
auto dialogPartnerName = dialogPartner->name();
for (auto impEntityName : impEntitiesNames)
{
if (dialogPartnerName.find(impEntityName) != -1) {
LOG_DEBUG("%s %s %d", dialogPartnerName.c_str(), impEntityName, dialogPartnerName.find(impEntityName));
isImportant = true;
break;
}
}
}
if (talkDialog->fields._inSelect && f_AutoSelectDialog && !isImportant)
{
int32_t value = 0;
auto object = il2cpp_value_box((Il2CppClass*)*app::Int32__TypeInfo, &value);
auto notify = app::Notify_CreateNotify_1(nullptr, app::MoleMole_NotifyTypes__Enum::DialogSelectItemNotify, (app::Object*)object, nullptr);
2022-05-17 03:13:41 +03:00
app::TalkDialogContext_OnDialogSelectItem(talkDialog, &notify, nullptr);
}
else if (!talkDialog->fields._inSelect)
app::InLevelCutScenePageContext_OnFreeClick(context, nullptr);
}
static void InLevelCutScenePageContext_UpdateView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method)
{
CALL_ORIGIN(InLevelCutScenePageContext_UpdateView_Hook, __this, method);
DialogSkip& dialogSkip = DialogSkip::GetInstance();
dialogSkip.OnCutScenePageUpdate(__this);
}
// Raised when exiting a dialog. We try to hackishly return to normal value.
// Should be a better way to store the pre-dialog speed using Time_get_timeScale.
static void InLevelCutScenePageContext_ClearView_Hook(app::InLevelCutScenePageContext* __this, MethodInfo* method)
{
float gameSpeed = app::Time_get_timeScale(nullptr, nullptr);
if (gameSpeed > 1.0f)
app::Time_set_timeScale(nullptr, 1.0f, nullptr);
CALL_ORIGIN(InLevelCutScenePageContext_ClearView_Hook, __this, method);
}
}