AlumKal

【FE】苏生 炸炮情形2

May 11th, 2023 (edited)
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.63 KB | None | 0 0
  1. #include <random>
  2. #include "avz.h"
  3. #include "AvZDSL/AvZDSL.h"
  4. #include "fodder/fodder.h"
  5.  
  6. using namespace std;
  7.  
  8. #define _Concat_(a, b) a ## b
  9. #define _Concat(a, b) _Concat_(a, b)
  10. #define _AddStateHook(func_name, ...) \
  11.     class : AStateHook { \
  12.        void func_name() override { __VA_ARGS__; } \
  13.     } _Concat(_StateHook, __COUNTER__);
  14. #define HookBeforeScript(...) _AddStateHook(_BeforeScript, __VA_ARGS__)
  15. #define HookAfterScript(...) _AddStateHook(_AfterScript, __VA_ARGS__)
  16. #define HookEnterFight(...) _AddStateHook(_EnterFight, __VA_ARGS__)
  17. #define HookExitFight(...) _AddStateHook(_ExitFight, __VA_ARGS__)
  18.  
  19. APvzBase* pb;
  20. AMainObject* mo;
  21. mt19937 rnd;
  22.  
  23. HookBeforeScript(
  24.     pb = AGetPvzBase();
  25.     mo = AGetMainObject();
  26.     random_device rd;
  27.     seed_seq ss{rd(), rd()};
  28.     rnd.seed(ss);
  29.     srand(rd());
  30. );
  31.  
  32. template <typename... Args>
  33. void ACard(const vector<APlantType>& plants, Args... args) {
  34.     for(auto p : plants)
  35.         ACard(p, args...);
  36. }
  37.  
  38. void ACard(const vector<APlantType>& plants, const vector<APosition>& arg) {
  39.     for(auto p : plants)
  40.         ACard(p, arg);
  41. }
  42.  
  43. #define CardR(...) AMkRelOp(ACard(__VA_ARGS__))
  44. #define ShovelR(...) AMkRelOp(AShovel(__VA_ARGS__))
  45.  
  46. RFunc IceDayR() {
  47.     ARelTime t = 298 + rand() % 2;
  48.     return -t[
  49.         AMkRelOp(aIceFiller.Coffee()),
  50.         AMkRelOp(AIce3(t))
  51.     ];
  52. }
  53.  
  54. RFunc IceNightR(int row, int col) {
  55.     return -420_cs[AMkRelOp(
  56.         if(AIsSeedUsable(AM_ICE_SHROOM)) {
  57.             ARelTime t = 419 + rand() % 2;
  58.             ANow(420 - t)[
  59.                 CardR(AM_ICE_SHROOM, row, col),
  60.                 AMkRelOp(AIce3(t))
  61.             ];
  62.         } else
  63.             ANow(320)[CardR(AICE_SHROOM, row, col)];
  64.     )];
  65. }
  66.  
  67. RFunc p(int row, float col, bool wait_until_recover = false) {
  68.     std::vector<int> rows;
  69.     while(row) {
  70.         rows.push_back(row % 10);
  71.         row /= 10;
  72.     }
  73.     std::reverse(rows.begin(), rows.end());
  74.     auto out = AMkRelOp();
  75.     for(int r : rows) {
  76.         int t = ARangeIn(mo->Scene(), {2, 3}) && ARangeIn(r, {3, 4}) ? 378 : 373;
  77.         out += ARelTime(-t)[AMkRelOp(
  78.             aCobManager.SetNext(1);
  79.             if(wait_until_recover)
  80.                 aCobManager.RecoverFire(r, col);
  81.             else
  82.                 aCobManager.Fire(r, col);
  83.         )];
  84.     }
  85.     return out;
  86. }
  87.  
  88. RFunc p(const vector<pair<int, float>>& rcs, bool wait_until_recover = false) {
  89.     auto out = AMkRelOp();
  90.     for(auto [r, c] : rcs)
  91.         out += p(r, c);
  92.     return out;
  93. }
  94.  
  95. RFunc rp(int r1, int c1, int r2, float c2) {
  96.     int t = ARangeIn(mo->Scene(), {2, 3}) && ARangeIn(r2, {3, 4}) ? 378 : 373;
  97.     return ARelTime(-t)[AMkRelOp(aCobManager.RawFire(r1, c1, r2, c2))];
  98. }
  99.  
  100. class AMaidCheatsR {
  101. public:
  102.     RFunc static CallPartner() {
  103.         return AMkRelOp(AMaidCheats::CallPartner());
  104.     }
  105.  
  106.     RFunc static Dancing() {
  107.         return AMkRelOp(AMaidCheats::Dancing());
  108.     }
  109.  
  110.     RFunc static Move() {
  111.         return AMkRelOp(AMaidCheats::Move());
  112.     }
  113.  
  114.     RFunc static Stop() {
  115.         return AMkRelOp(AMaidCheats::Stop());
  116.     }
  117. };
  118.  
  119. template <typename T>
  120. class Logger : public ALogger<T> {
  121. private:
  122.     void _BeforeScript() override {
  123.         this->_level = 0;
  124.         ALogger<T>::_BeforeScript();
  125.         this->_level = 0b1111;
  126.     }
  127.  
  128. public:
  129.     template <typename... Args>
  130.     Logger(Args... args) : ALogger<T>(args...) {}
  131. };
  132.  
  133. Logger<APvzGui> _GUILogger;
  134. AAbstractLogger* logger = &_GUILogger;
  135.  
  136. template <typename... Ts>
  137. RFunc InfoR(Ts... args) {
  138.     return AMkRelOp(logger->Info(args...));
  139. }
  140.  
  141. #define ExportLog(path) \
  142.     Logger<AFile> _ExportLogLogger(path); \
  143.     HookBeforeScript( \
  144.         _ExportLogLogger.Clear(); \
  145.         ASetInternalLogger(_ExportLogLogger); \
  146.         logger = &_ExportLogLogger; \
  147.     );
  148.  
  149. // PropFilter(&AZombie::Hp, greater(), 3000)
  150. template <typename T, typename V>
  151. AAliveFilter<T> PropFilter(V (T::* prop)(), auto&& op, auto value) {
  152.     return AAliveFilter<T>([=](T* x){ return op((x->*prop)(), value); });
  153. }
  154.  
  155. // PropFilter(&AZombie::Type, AGIGA_GARGANTUAR)
  156. template <typename T, typename V>
  157. AAliveFilter<T> PropFilter(V (T::* prop)(), auto value) {
  158.     return PropFilter(prop, equal_to(), value);
  159. }
  160.  
  161. // from crescendo/avz-more
  162. void AverageSpawn(const vector<AZombieType>& types = {}) {
  163.     int scene = AGetMainObject()->Scene();
  164.     if(scene > 5)
  165.         AGetInternalLogger()->Error("AverageSpawn 不支持该场地");
  166.     auto default_rows = ARangeIn(scene, {2, 3}) ? vector<int>{0, 1, 4, 5} : vector<int>{0, 1, 2, 3, 4};
  167.     int height = ARangeIn(scene, {0, 1}) ? 100 : 85;
  168.     for(int wave = 1; wave <= 20; wave++)
  169.         AConnect(ATime(wave, 0), [=]{
  170.             vector<int> rows[33];
  171.             int cur[33];
  172.             for(int i = 0; i < 33; i++) {
  173.                 if(ARangeIn(i, {ADUCKY_TUBE_ZOMBIE, ASNORKEL_ZOMBIE, ADOLPHIN_RIDER_ZOMBIE}))
  174.                     rows[i] = {2, 3};
  175.                 else if(ARangeIn(scene, {0, 1}) && i == ADANCING_ZOMBIE)
  176.                     rows[i] = {1, 2, 3};
  177.                 else if(ARangeIn(scene, {2, 3}) && i == ABALLOON_ZOMBIE && wave > 5)
  178.                     rows[i] = {0, 1, 2, 3, 4, 5};
  179.                 else
  180.                     rows[i] = default_rows;
  181.                 shuffle(rows[i].begin(), rows[i].end(), rnd);
  182.                 cur[i] = 0;
  183.             }
  184.             for(auto& z : PropFilter(&AZombie::ExistTime, 0)) {
  185.                 int type = z.Type();
  186.                 if(type == ABUNGEE_ZOMBIE)
  187.                     continue;
  188.                 if(!types.empty() && find(types.begin(), types.end(), type) == types.end())
  189.                     continue;
  190.                 if(ARangeIn(scene, {2, 3}) && ARangeIn(z.Row(), {2, 3}) &&
  191.                    ARangeIn(type, {AZOMBIE, ACONEHEAD_ZOMBIE, ABUCKETHEAD_ZOMBIE}))
  192.                     type = ADUCKY_TUBE_ZOMBIE;
  193.                 int row = z.Row(), row2 = rows[type][cur[type]];
  194.                 z.Row() = row2;
  195.                 z.Ordinate() += height * (row2 - row);
  196.                 z.MRef<int>(0x20) += 10000 * (row2 - row);
  197.                 cur[type] = (cur[type] + 1) % rows[type].size();
  198.             }
  199.         });
  200. }
  201.  
  202. // ----------------------------------------------------------------
  203.  
  204. FodderR f({ACHOMPER, AFLOWER_POT, AFUME_SHROOM, AKERNEL_PULT});
  205. ACobManager tbs;
  206.  
  207. void set_shovel(int r, int c) {
  208.     vector<AGrid> lst;
  209.     for(auto& p : PropFilter(&APlant::Type, ACOB_CANNON))
  210.         if(p.Col() != 6 && (p.Row() != r - 1 || p.Col() != c - 1))
  211.             lst.push_back({p.Row() + 1, p.Col() + 1});
  212.     sort(lst.begin(), lst.end());
  213.     lst.push_back({r, c});
  214.     for(int r : {1, 2, 5, 6})
  215.         lst.push_back({r, 7});
  216.     aCobManager.SetList(lst);
  217.     tbs.SetList({{r, c}});
  218. }
  219.  
  220. // 炸炮
  221. RFunc SPROING(int row) {
  222.     return -110_cs[AMkRelOp(
  223.         auto z = AAsm::PutZombie(row - 1, 8, AJACK_IN_THE_BOX_ZOMBIE);
  224.         z->Abscissa() = 690;
  225.         z->StateCountdown() = 0;
  226.     )];
  227. }
  228.  
  229. /*
  230. 上F w7-w9、下f w17-w19:
  231. IPP-cccc-PP'DD 1679
  232. PDc/Bdcc
  233. IPP-ccc-PDD/PSD (1510/1300)
  234. */
  235.  
  236. void AScript() {
  237.     // 存档只读
  238.     *(uint8_t*)0x482149 = 0x2e;
  239.     *(uint8_t*)0x54b267 = 0x70;
  240.     ASetReloadMode(AReloadMode::MAIN_UI);
  241.     AConnect(AKey('Q'), []{ throw AException(""); });
  242.     ASetZombies({APOLE_VAULTING_ZOMBIE, ADANCING_ZOMBIE, AZOMBONI, ADOLPHIN_RIDER_ZOMBIE, AJACK_IN_THE_BOX_ZOMBIE, ABALLOON_ZOMBIE, ADIGGER_ZOMBIE, APOGO_ZOMBIE, ABUNGEE_ZOMBIE, ALADDER_ZOMBIE, ACATAPULT_ZOMBIE, AGARGANTUAR, AGIGA_GARGANTUAR});
  243.     ASelectCards({AICE_SHROOM, AM_ICE_SHROOM, ADOOM_SHROOM, ACHERRY_BOMB, ACOB_CANNON, ALILY_PAD, AFLOWER_POT, AFUME_SHROOM, AKERNEL_PULT, ACHOMPER});
  244.     // 无限阳光
  245.     *(uint8_t*)0x41ba72 = 0x70;
  246.     *(uint8_t*)0x41ba74 = 0x3b;
  247.     *(uint8_t*)0x41bac0 = 0x91;
  248.     *(uint8_t*)0x427a92 = 0x80;
  249.     *(uint8_t*)0x427dfd = 0x80;
  250.     *(uint8_t*)0x42487f = 0xeb;
  251.     // 关闭引信延迟
  252.     *(uint16_t*)0x46d672 = 0x9700;
  253.     // 锁定黄油
  254.     "1 10"_wave[AMkRelOp(*(int*)0x45f1e1 = 1)];
  255.     "9 19"_wave + 1000_cs[AMkRelOp(*(int*)0x45f1e1 = 4)];
  256.     AverageSpawn({AGARGANTUAR, AGIGA_GARGANTUAR, ADOLPHIN_RIDER_ZOMBIE});
  257.     set_shovel(6, 1);
  258.  
  259.     1_wave - 599_cs[
  260.         CardR({ALILY_PAD, AFUME_SHROOM}, 3, 1),
  261.         751_cs[CardR({ALILY_PAD, AFUME_SHROOM}, 4, 1)],
  262.         1502_cs[CardR(ALILY_PAD, 3, 7)],
  263.         2253_cs[CardR(ALILY_PAD, 4, 7)]
  264.     ];
  265.     10_wave + 800_cs[CardR(AFUME_SHROOM, 4, 1)];
  266.  
  267.     10_wave[
  268.         -400_cs[AMaidCheatsR::Stop()],
  269.         240_cs[f({1, 2}, 20)],
  270.         225_cs[rp(6, 1, 6, 9)],
  271.         290_cs[rp(5, 7, 5, 9)],
  272.         400_cs - 100_cs[CardR({ALILY_PAD, ADOOM_SHROOM}, 3, 9)],
  273.         399_cs + 255_cs[rp(6, 7, 2, 3)]
  274.     ].AssumeWaveLength(601);
  275.  
  276.     "1 11"_wave[
  277.         245_cs[p(1, 9)],
  278.         359_cs[p(15, 8.75), 107_cs[p(5, 7.8125)]]
  279.     ].AssumeWaveLength(601);
  280.     1_wave + 245_cs[rp(6, 7, 2, 9)];
  281.     11_wave + 245_cs[p(2, 9)];
  282.  
  283.     "2 12"_wave[
  284.         CardR({{AKERNEL_PULT, 1, 9}, {AFLOWER_POT, 2, 9}}),
  285.         121_cs[CardR(ACHOMPER, 2, 9)],
  286.         1_cs - 100_cs[CardR(AICE_SHROOM, 5, 9)],
  287.         104_cs[p(1, 9)],
  288.         433_cs[p(5, 7.4125)],
  289.         871_cs[
  290.             ShovelR(1, 9),
  291.             f({1}, -1),
  292.             f({5, 6}),
  293.             751_cs[CardR({AFLOWER_POT, AFUME_SHROOM}, 6, 9)]
  294.         ],
  295.         1287_cs[ShovelR({{1, 9}, {2, 9}, {2, 9}})],
  296.         1327_cs[p({{256, 9}, {5, 8.4}})],
  297.         1328_cs[CardR(ACHOMPER, 5, 9)]
  298.     ].AssumeWaveLength(1527);
  299.  
  300.     "3 13"_wave[
  301.         11_cs[IceNightR(3, 7)],
  302.         971_cs[
  303.             rp(6, 1, 1, 4),
  304.             -373_cs + 205_cs[
  305.                 ShovelR(6, 1),
  306.                 CardR(AKERNEL_PULT, 6, 1),
  307.                 751_cs[CardR({{AKERNEL_PULT, 6, 2}, {ACOB_CANNON, 6, 1}})]
  308.             ]
  309.         ],
  310.         809_cs[f({1}, 1144 - 809)],
  311.         927_cs[ShovelR(5, 9), f({2}), f({5}, -1)],
  312.         1278_cs[ShovelR({{5, 9}, {6, 9}, {6, 9}})],
  313.         1511_cs + 220_cs[p(1, 7.4125)],
  314.         809_cs + 751_cs[AMkRelOp(
  315.             float min_x = 800;
  316.             int row = 0;
  317.             for(auto& z : PropFilter(&AZombie::Type, AGIGA_GARGANTUAR))
  318.                 if(z.Hp() > 3000 && z.Row() <= 1 && z.Abscissa() < min_x) {
  319.                     min_x = z.Abscissa();
  320.                     row = z.Row();
  321.                 }
  322.             ANow[f({row + 1}, 1)];
  323.         )]
  324.     ].AssumeWaveLength(1711);
  325.     3_wave[
  326.         286_cs[p(5, 9)],
  327.         594_cs[rp(1, 7, 1, 8.625)],
  328.         1511_cs[rp(2, 7, 2, 8.75), rp(5, 7, 5, 8.75)],
  329.         1511_cs + 220_cs[rp(6, 7, 5, 8.4)]
  330.     ];
  331.     13_wave[
  332.         286_cs[rp(1, 7, 5, 9)],
  333.         594_cs[rp(2, 7, 1, 8.625)],
  334.         1511_cs[rp(5, 7, 2, 8.75), rp(6, 7, 5, 8.75)],
  335.         1511_cs + 220_cs[p(5, 8.4)]
  336.     ];
  337.  
  338.     "4 14"_wave[
  339.         240_cs[p(5, 8.75), 110_cs[p(5, 8.15)]],
  340.         362_cs[p(2, 9), 107_cs[p(1, 7.8125)]],
  341.         363_cs[f({1, 2}, 445 + 134 - 363)],
  342.         600_cs[AMkRelOp(
  343.             float min_x[6] = {800, 800, 800, 800, 800, 800};
  344.             for(auto& z : PropFilter(&AZombie::Type, AGIGA_GARGANTUAR))
  345.                 min_x[z.Row()] = min(min_x[z.Row()], z.Abscissa());
  346.             float thres = 671 + 31.103; // 最快巨人走115cs
  347.             if(min_x[0] < thres)
  348.                 ANow(720 - 600)[f({1}, 1)];
  349.             if(min_x[1] < thres)
  350.                 ANow(720 - 600)[f({2}, 1)];
  351.             int cnt = (min_x[0] >= thres) + (min_x[1] >= thres);
  352.             int diff = 0;
  353.             for(auto& z : PropFilter(&AZombie::Type, APOLE_VAULTING_ZOMBIE))
  354.                 if(z.Row() == 4)
  355.                     diff++;
  356.                 else if(z.Row() == 5)
  357.                     diff--;
  358.             int r1 = diff > 0 ? 5 : 6, r2 = 5 ^ 6 ^ r1;
  359.             if(cnt >= 1)
  360.                 ANow[f({r1}, 1)];
  361.             if(cnt >= 2)
  362.                 ANow[f({r2}, 1)];
  363.         )]
  364.     ].AssumeWaveLength(601);
  365.  
  366.     "5 15"_wave[
  367.         240_cs[p(6, 9)],
  368.         241_cs - 100_cs[CardR(ACHERRY_BOMB, 5, 9)],
  369.         360_cs - 100_cs[CardR({ALILY_PAD, ADOOM_SHROOM}, {{3, 8}, {4, 9}})],
  370.         359_cs + 107_cs[p(1, 7.8125)],
  371.         513_cs[f({1, 2}, 134)]
  372.     ].AssumeWaveLength(601);
  373.  
  374.     "6 16"_wave[
  375.         362_cs[p(25, 9), 107_cs[p(15, 7.8125)]],
  376.         445_cs[AMkRelOp(
  377.             float min_x[6] = {800, 800, 0, 0, 800, 800};
  378.             for(auto& z : PropFilter(&AZombie::Type, AGIGA_GARGANTUAR))
  379.                 if(z.Hp() > 3000)
  380.                     min_x[z.Row()] = min(min_x[z.Row()], z.Abscissa());
  381.             int ignored_row = max_element(min_x, min_x + 6) - min_x + 1;
  382.             if(ARangeIn(ignored_row, {1, 2}))
  383.                 AWave(ANowWave())[
  384.                     445_cs[f({5, 6}, 134)],
  385.                     502_cs[CardR(AICE_SHROOM, 1 ^ 2 ^ ignored_row, 9)],
  386.                     601_cs + 293_cs[p(5, 7.85)],
  387.                     601_cs + 555_cs[p(1, 7.4125)]
  388.                 ];
  389.             else
  390.                 AWave(ANowWave())[
  391.                     445_cs[f({1, 2}, 134)],
  392.                     502_cs[CardR(AICE_SHROOM, 5 ^ 6 ^ ignored_row, 9)],
  393.                     601_cs + 293_cs[p(1, 7.85)],
  394.                     601_cs + 555_cs[p(5, 7.4125)]
  395.                 ];
  396.         )]
  397.     ].AssumeWaveLength(601);
  398.  
  399.     "7 17"_wave[
  400.         815_cs[f({1, 2}), f({5, 6})],
  401.         1479_cs[p(25, 9), 220_cs[p({{1, 7.4125}, {5, 8.4}})]]
  402.     ].AssumeWaveLength(1679);
  403.     7_wave + 1400_cs[SPROING(5)];
  404.     17_wave + 1400_cs[SPROING(6)];
  405.  
  406.     "8 18"_wave[
  407.         240_cs[p(5, 8.75), 250_cs[p(5, 4)]],
  408.         359_cs[p(2, 9), 107_cs[p(1, 7.8125)]],
  409.         420_cs[f({2, 5, 6}, 445 + 134 - 420)]
  410.     ].AssumeWaveLength(601);
  411.     8_wave + 436_cs[CardR(AKERNEL_PULT, 5, 7), 751_cs[CardR(AKERNEL_PULT, 5, 8)]];
  412.     18_wave + 436_cs[CardR(AKERNEL_PULT, 6, 7), 751_cs[CardR(AKERNEL_PULT, 6, 8)]];
  413.  
  414.     "9 19"_wave[
  415.         AMaidCheatsR::Move(),
  416.         1_cs[IceNightR(3, 7)],
  417.         466_cs[p(15, 7.4125)],
  418.         847_cs[f({1, 2})],
  419.         1100_cs[p(56, 9), 220_cs[p(5, 8.75)]],
  420.         1310_cs[p(1, 8.4), 225_cs[p(1, 8.4)], 450_cs[p(1, 8.75)]],
  421.         1800_cs[-100_cs[CardR(ACHERRY_BOMB, 2, 9)], AMaidCheatsR::Dancing()],
  422.         1350_cs[f({5, 6}, 700)],
  423.         2250_cs[f({5, 6}, 134)],
  424.         2460_cs[f({5, 6}, 134)],
  425.         2900_cs[p(3, 5)]
  426.     ];
  427.     9_wave[
  428.         761_cs[CardR(ACOB_CANNON, 5, 7)],
  429.         2800_cs[rp(2, 7, 5, 9)]
  430.     ];
  431.     19_wave[
  432.         761_cs[CardR(ACOB_CANNON, 6, 7)],
  433.         2800_cs[p(5, 9)]
  434.     ];
  435.  
  436.     20_wave[
  437.         -400_cs[AMaidCheatsR::Stop()],
  438.         -1_cs[ShovelR({{3, 1}, {4, 1}, {3, 1}, {4, 1}, {3, 7}, {4, 7}})],
  439.         250_cs[p(4, 7.5)],
  440.         341_cs[p(25, 9)],
  441.         441_cs[p(25, 9), 110_cs[p(15, 9)]],
  442.         1000_cs[p(35, 9)],
  443.         3190_cs[p(1, 9)]
  444.     ];
  445.  
  446.     for(int t = 1000; t < 3190 - 134; t += 208)
  447.         20_wave + ARelTime(t)[f({1}, 207)];
  448. }
Advertisement
Add Comment
Please, Sign In to add comment