From aa12aa8511d93a15a616a4b0b58fdc2431919df1 Mon Sep 17 00:00:00 2001 From: 0O0o0oOoO00 <11174151+0o0o0oooo00@users.noreply.github.com> Date: Mon, 12 Jan 2026 22:24:53 +0800 Subject: [PATCH] add: skip air strike animation --- blcrack/cracker/cracker.cpp | 33 ++++++++++++++++++++++++++ blcrack/cracker/cracker.hpp | 6 +++++ blcrack/cracker/server.cpp | 22 +++++++++++++++++ blcrack/cracker/ui/ui.cpp | 2 ++ config/template.json | 3 ++- module/config/argument/args.json | 4 ++++ module/config/argument/argument.yaml | 1 + module/config/config_generated.py | 1 + module/config/full_config_generated.py | 1 + module/config/i18n/en-US.json | 4 ++++ module/config/i18n/ja-JP.json | 4 ++++ module/config/i18n/zh-CN.json | 4 ++++ module/config/i18n/zh-TW.json | 4 ++++ module/luahook/api.py | 6 +++++ module/luahook/crack.py | 7 ++++++ module/luahook/op.py | 6 +++++ 16 files changed, 107 insertions(+), 1 deletion(-) diff --git a/blcrack/cracker/cracker.cpp b/blcrack/cracker/cracker.cpp index e59fdaec7..e23258a83 100644 --- a/blcrack/cracker/cracker.cpp +++ b/blcrack/cracker/cracker.cpp @@ -321,6 +321,15 @@ void Cracker::disable_all() { disable_chapter_auto_clear(); disable_skip_story(); disable_infinite_battle(); + disable_skip_air_strike_animation(); +} + +void Cracker::enable_skip_air_strike_animation() { + ENABLE(SKIP_AIR_STRIKE_ANIMATION); +} + +void Cracker::disable_skip_air_strike_animation() { + DISABLE(INFINITE_BATTLE); } void Cracker::enable_infinite_battle() { @@ -762,11 +771,28 @@ void Cracker::load_lua_resources() { m_original.Fleet_EnergyCheck = m_state["Fleet"]["EnergyCheck"]; m_original.ContinuousOperationRuntimeData_ConsumeBattleTime = m_state["ContinuousOperationRuntimeData"]["ConsumeBattleTime"]; m_original.ActivityProxy_UseContinuousTime = m_state["ActivityProxy"]["UseContinuousTime"]; + m_original.LevelScene_doPlayAirStrike = m_state["LevelScene"]["doPlayAirStrike"]; } void Cracker::hook_all_lua_functions() { SPDLOG_INFO("Hook lua functions"); + // skip_air_strike_animation + m_state["LevelScene"]["doPlayAirStrike"] = [this](sol::this_state L, Lua::VariadicArgs args) { + CALLED(LevelScene.doPlayAirStrike) + + if (IS_ENABLED(SKIP_AIR_STRIKE_ANIMATION)) { + Lua::Object callback = args[3]; + if (callback.is()) { + callback.as()(L); + } else { + m_original.LevelScene_doPlayAirStrike(L, args); + } + return; + } + m_original.LevelScene_doPlayAirStrike(L, args); + }; + // infinite_battle m_state["ContinuousOperationRuntimeData"]["ConsumeBattleTime"] = [this](sol::this_state L, Lua::VariadicArgs args) { CALLED(ContinuousOperationRuntimeData.ConsumeBattleTime); @@ -1565,6 +1591,7 @@ Cracker::Config Cracker::get_config() { SET_CONFIG_FLAG(CHAPTER_AUTO_CLEAR), SET_CONFIG_FLAG(SKIP_STORY), SET_CONFIG_FLAG(INFINITE_BATTLE), + SET_CONFIG_FLAG(SKIP_AIR_STRIKE_ANIMATION), }, .globle_ship_properties = m_globle_ship_properties, .global_speedup_rate = static_cast(m_global_speedup_rate), @@ -1579,6 +1606,12 @@ Cracker::Config Cracker::get_config() { #define IS_CONFIG_ENABLED(n) config.flag.n void Cracker::apply_config(Config& config) { + if(IS_CONFIG_ENABLED(SKIP_AIR_STRIKE_ANIMATION)) { + enable_skip_air_strike_animation(); + } else { + disable_skip_air_strike_animation(); + } + if(IS_CONFIG_ENABLED(INFINITE_BATTLE)) { enable_infinite_battle(); } else { diff --git a/blcrack/cracker/cracker.hpp b/blcrack/cracker/cracker.hpp index 070eede3d..77f93de52 100644 --- a/blcrack/cracker/cracker.hpp +++ b/blcrack/cracker/cracker.hpp @@ -117,6 +117,7 @@ public: bool CHAPTER_AUTO_CLEAR = false; bool SKIP_STORY = false; bool INFINITE_BATTLE = false; + bool SKIP_AIR_STRIKE_ANIMATION = false; } flag; ShipProperties globle_ship_properties; int global_speedup_rate = 1; @@ -153,6 +154,9 @@ public: void disable_all(); + void enable_skip_air_strike_animation(); + void disable_skip_air_strike_animation(); + void enable_infinite_battle(); void disable_infinite_battle(); @@ -331,6 +335,7 @@ private: std::atomic CHAPTER_AUTO_CLEAR = false; std::atomic SKIP_STORY = false; std::atomic INFINITE_BATTLE = false; + std::atomic SKIP_AIR_STRIKE_ANIMATION = false; } m_flag; struct { @@ -382,6 +387,7 @@ private: Lua::Function Fleet_EnergyCheck; Lua::Function ContinuousOperationRuntimeData_ConsumeBattleTime; Lua::Function ActivityProxy_UseContinuousTime; + Lua::Function LevelScene_doPlayAirStrike; } m_original; struct { Lua::Function Clone; diff --git a/blcrack/cracker/server.cpp b/blcrack/cracker/server.cpp index 44169bf27..916cda85c 100644 --- a/blcrack/cracker/server.cpp +++ b/blcrack/cracker/server.cpp @@ -1212,6 +1212,28 @@ CrackerServer::CrackerServer() { CRACK_OK(); }); + Post("/enable_skip_air_strike_animation", [](const httplib::Request& req, httplib::Response& res) { + try { + Cracker::Instance().enable_skip_air_strike_animation(); + } catch (std::exception& e) { + SPDLOG_ERROR("Enable skip air strike animation failed: {}", e.what()); + res.status = 500; + return; + } + CRACK_OK(); + }); + + Post("/disable_skip_air_strike_animation", [](const httplib::Request& req, httplib::Response& res) { + try { + Cracker::Instance().disable_skip_air_strike_animation(); + } catch (std::exception& e) { + SPDLOG_ERROR("Disable skip air strike animation failed: {}", e.what()); + res.status = 500; + return; + } + CRACK_OK(); + }); + Post("/init", [](const httplib::Request& req, httplib::Response& res) { try { Cracker::Instance(); diff --git a/blcrack/cracker/ui/ui.cpp b/blcrack/cracker/ui/ui.cpp index 4c71a022a..06778aaf7 100644 --- a/blcrack/cracker/ui/ui.cpp +++ b/blcrack/cracker/ui/ui.cpp @@ -114,6 +114,7 @@ void CrackerUI::draw_menu() { PRESET(SKIP_SHIP_GAIN_SHOW); PRESET(CHAPTER_AUTO_NEXT_BATTLE); PRESET(CHAPTER_AUTO_CLEAR); + PRESET(SKIP_AIR_STRIKE_ANIMATION); } ImGui::SameLine(); if (ImGui::Button("加载大世界开荒预设")) { @@ -138,6 +139,7 @@ void CrackerUI::draw_menu() { ImGui::Checkbox("演习锁血", &CONFIG_FLAG(EXERCISE_GOD_MOD)); ImGui::Checkbox("自动规避伏击", &CONFIG_FLAG(CHAPTER_AUTO_AMBUSH)); ImGui::Checkbox("跳过剧情", &CONFIG_FLAG(SKIP_STORY)); + ImGui::Checkbox("跳过空袭动画", &CONFIG_FLAG(SKIP_AIR_STRIKE_ANIMATION)); ImGui::TableNextColumn(); ImGui::Checkbox("移除困难图属性限制", &CONFIG_FLAG(REMOVE_HARD_MODE_SHIP_PROPERTIES_LIMIT)); diff --git a/config/template.json b/config/template.json index 3950b1d2f..d4647476a 100644 --- a/config/template.json +++ b/config/template.json @@ -231,7 +231,8 @@ "ChapterAutoClear": false, "ChapterAutoClearStepInterval": 0.5, "SkipStory": false, - "InfiniteBattle": false + "InfiniteBattle": false, + "SkipAirStrikeAnimation": false }, "ShipProperty": { "Method": "disable", diff --git a/module/config/argument/args.json b/module/config/argument/args.json index edd0d0feb..d7bc1622a 100644 --- a/module/config/argument/args.json +++ b/module/config/argument/args.json @@ -921,6 +921,10 @@ "InfiniteBattle": { "type": "checkbox", "value": false + }, + "SkipAirStrikeAnimation": { + "type": "checkbox", + "value": false } }, "ShipProperty": { diff --git a/module/config/argument/argument.yaml b/module/config/argument/argument.yaml index bb9223c9b..12bd79ec2 100644 --- a/module/config/argument/argument.yaml +++ b/module/config/argument/argument.yaml @@ -897,6 +897,7 @@ Misc: ChapterAutoClearStepInterval: 0.5 SkipStory: false InfiniteBattle: false + SkipAirStrikeAnimation: false # ==================== Cheat ==================== PowerLimit: diff --git a/module/config/config_generated.py b/module/config/config_generated.py index fef41dd31..ea9c5a988 100644 --- a/module/config/config_generated.py +++ b/module/config/config_generated.py @@ -552,6 +552,7 @@ class GeneratedConfig: Misc_ChapterAutoClearStepInterval = 0.5 Misc_SkipStory = False Misc_InfiniteBattle = False + Misc_SkipAirStrikeAnimation = False # Group `PowerLimit` PowerLimit_Enable = True diff --git a/module/config/full_config_generated.py b/module/config/full_config_generated.py index fa47a3c98..fd6827b76 100644 --- a/module/config/full_config_generated.py +++ b/module/config/full_config_generated.py @@ -165,6 +165,7 @@ class FullGeneratedConfig: Hook_Misc_ChapterAutoClearStepInterval = None Hook_Misc_SkipStory = None Hook_Misc_InfiniteBattle = None + Hook_Misc_SkipAirStrikeAnimation = None Hook_ShipProperty_Method = None Hook_ShipProperty_Factor = None Hook_ShipProperty_Armor = None diff --git a/module/config/i18n/en-US.json b/module/config/i18n/en-US.json index 88bc33f10..5adb1ef16 100644 --- a/module/config/i18n/en-US.json +++ b/module/config/i18n/en-US.json @@ -3176,6 +3176,10 @@ "InfiniteBattle": { "name": "Misc.InfiniteBattle.name", "help": "Misc.InfiniteBattle.help" + }, + "SkipAirStrikeAnimation": { + "name": "Misc.SkipAirStrikeAnimation.name", + "help": "Misc.SkipAirStrikeAnimation.help" } }, "PowerLimit": { diff --git a/module/config/i18n/ja-JP.json b/module/config/i18n/ja-JP.json index 61f1253ee..6a7be3f1a 100644 --- a/module/config/i18n/ja-JP.json +++ b/module/config/i18n/ja-JP.json @@ -3176,6 +3176,10 @@ "InfiniteBattle": { "name": "Misc.InfiniteBattle.name", "help": "Misc.InfiniteBattle.help" + }, + "SkipAirStrikeAnimation": { + "name": "Misc.SkipAirStrikeAnimation.name", + "help": "Misc.SkipAirStrikeAnimation.help" } }, "PowerLimit": { diff --git a/module/config/i18n/zh-CN.json b/module/config/i18n/zh-CN.json index 82da60f30..cbad57a10 100644 --- a/module/config/i18n/zh-CN.json +++ b/module/config/i18n/zh-CN.json @@ -3176,6 +3176,10 @@ "InfiniteBattle": { "name": "无限连战", "help": "" + }, + "SkipAirStrikeAnimation": { + "name": "跳过空袭动画", + "help": "" } }, "PowerLimit": { diff --git a/module/config/i18n/zh-TW.json b/module/config/i18n/zh-TW.json index 0d71f715a..8aeb661a7 100644 --- a/module/config/i18n/zh-TW.json +++ b/module/config/i18n/zh-TW.json @@ -3176,6 +3176,10 @@ "InfiniteBattle": { "name": "Misc.InfiniteBattle.name", "help": "Misc.InfiniteBattle.help" + }, + "SkipAirStrikeAnimation": { + "name": "Misc.SkipAirStrikeAnimation.name", + "help": "Misc.SkipAirStrikeAnimation.help" } }, "PowerLimit": { diff --git a/module/luahook/api.py b/module/luahook/api.py index eeef3e1f3..9a1985f76 100644 --- a/module/luahook/api.py +++ b/module/luahook/api.py @@ -404,6 +404,12 @@ class CrackApi: def disable_infinite_battle(self): self.post("disable_infinite_battle") + def enable_skip_air_strike_animation(self): + self.post("enable_skip_air_strike_animation") + + def disable_skip_air_strike_animation(self): + self.post("disable_skip_air_strike_animation") + def init(self): self.post("init") diff --git a/module/luahook/crack.py b/module/luahook/crack.py index 0514c0f30..701d92b1f 100644 --- a/module/luahook/crack.py +++ b/module/luahook/crack.py @@ -46,6 +46,7 @@ ALL_ENABLE_OPS = [ CrackOp.EnableChapterAutoClear, CrackOp.EnableSkipStory, CrackOp.EnableInfiniteBattle, + CrackOp.EnableSkipAirStrikeAnimation, ] REMOTE_PORT = 23897 @@ -337,6 +338,11 @@ def do_crack_op(config: AzurLaneConfig, device: Device, ops: Union[Type[CrackOp. api.enable_infinite_battle() elif op == CrackOp.DisableInfiniteBattle: api.disable_infinite_battle() + elif op == CrackOp.EnableSkipAirStrikeAnimation: + if full_config.Hook_Misc_SkipAirStrikeAnimation: + api.enable_skip_air_strike_animation() + elif op == CrackOp.DisableSkipAirStrikeAnimation: + api.disable_skip_air_strike_animation() else: logger.error(f"Unsupported op: {op}") @@ -396,6 +402,7 @@ CHAPTER_CRACK_OPS = [ CrackOp.EnableChapterAutoClear, CrackOp.EnableSkipStory, CrackOp.EnableInfiniteBattle, + CrackOp.EnableSkipAirStrikeAnimation, ] diff --git a/module/luahook/op.py b/module/luahook/op.py index 01f5bcf69..2aa19826d 100644 --- a/module/luahook/op.py +++ b/module/luahook/op.py @@ -184,3 +184,9 @@ class CrackOp: class DisableInfiniteBattle(Op): ... + + class EnableSkipAirStrikeAnimation(Op): + ... + + class DisableSkipAirStrikeAnimation(Op): + ...