-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.lua
More file actions
244 lines (224 loc) · 11.3 KB
/
Copy pathmain.lua
File metadata and controls
244 lines (224 loc) · 11.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
-- Mew Glitch Mod (mewmod) for gen1recomp
-- Replicates the classic Trainer Fly / Teleport Mew Glitch natively.
local INDEX_TO_SPECIES = {
[1] = "RHYDON", [2] = "KANGASKHAN", [3] = "NIDORAN_M", [4] = "CLEFAIRY", [5] = "SPEAROW",
[6] = "VOLTORB", [7] = "NIDOKING", [8] = "SLOWBRO", [9] = "IVYSAUR", [10] = "EXEGGUTOR",
[11] = "LICKITUNG", [12] = "EXEGGCUTE", [13] = "GRIMER", [14] = "GENGAR", [15] = "NIDORAN_F",
[16] = "NIDOQUEEN", [17] = "CUBONE", [18] = "RHYHORN", [19] = "LAPRAS", [20] = "ARCANINE",
[21] = "MEW", [22] = "GYARADOS", [23] = "SHELLDER", [24] = "TENTACOOL", [25] = "GASTLY",
[26] = "SCYTHER", [27] = "STARYU", [28] = "BLASTOISE", [29] = "PINSIR", [30] = "TENTACRUEL",
[31] = "GOLDEEN", [32] = "SEAKING", [33] = "PIDGEOTTO", [34] = "PIDGEOT", [35] = "STARMIE",
[36] = "BULBASAUR", [37] = "VENUSAUR", [38] = "TENTACRUEL", [39] = "GOLDUCK", [40] = "HYPNO",
[41] = "GOLBAT", [42] = "MEWTWO", [43] = "SNORLAX", [44] = "MAGIKARP", [45] = "MUK",
[46] = "KINGLER", [47] = "CLOYSTER", [48] = "ELECTRODE", [49] = "CLEFABLE", [50] = "WEEZING",
[51] = "PERSIAN", [52] = "MAROWAK", [53] = "HAUNTER", [54] = "ABRA", [55] = "KADABRA",
[56] = "ALAKAZAM", [57] = "PIDGEOTTO", [58] = "PIDGEOT", [59] = "STARMIE", [60] = "BULBASAUR",
[61] = "VENUSAUR", [62] = "TENTACRUEL", [63] = "GOLDUCK", [64] = "HYPNO", [65] = "GOLBAT",
[66] = "MEWTWO", [67] = "SNORLAX", [68] = "MAGIKARP", [69] = "MUK", [70] = "KINGLER",
[71] = "CLOYSTER", [72] = "ELECTRODE", [73] = "CLEFABLE", [74] = "WEEZING", [75] = "PERSIAN",
[76] = "MAROWAK", [77] = "HAUNTER", [78] = "ABRA", [79] = "KADABRA", [80] = "ALAKAZAM",
[81] = "PIDGEOT", [82] = "SLOWPOKE", [83] = "KADABRA", [84] = "GRAVELER", [85] = "CHANSEY",
[86] = "MACHOKE", [87] = "MR_MIME", [88] = "HITMONLEE", [89] = "HITMONCHAN", [90] = "ARBOK",
[91] = "PARASECT", [92] = "PSYDUCK", [93] = "DROWZEE", [94] = "GOLEM", [95] = "MAGMAR",
[96] = "ELECTABUZZ", [97] = "MAGNETON", [98] = "KOFFING", [99] = "MANKEY", [100] = "SEEL",
[101] = "DIGLETT", [102] = "TAUROS", [103] = "FARFETCHD", [104] = "VENONAT", [105] = "DRAGONITE",
[106] = "DODUO", [107] = "POLIWAG", [108] = "JYNX", [109] = "MOLTRES", [110] = "ARTICUNO",
[111] = "ZAPDUS", [112] = "DITTO", [113] = "MEOWTH", [114] = "KRABBY", [115] = "VULPIX",
[116] = "NINETALES", [117] = "PIKACHU", [118] = "RAICHU", [119] = "DRATINI", [120] = "DRAGONAIR",
[121] = "KABUTO", [122] = "KABUTOPS", [123] = "SEADRA", [124] = "HORSEA", [125] = "SHELLDER",
[126] = "TENTACOOL", [127] = "GASTLY", [128] = "SCYTHER", [129] = "STARYU", [130] = "BLASTOISE",
[131] = "PINSIR", [132] = "TENTACRUEL", [133] = "GOLDEEN", [134] = "SEAKING", [135] = "PIDGEOTTO",
[136] = "PIDGEOT", [137] = "STARMIE", [138] = "BULBASAUR", [139] = "VENUSAUR", [140] = "TENTACRUEL",
[141] = "GOLDUCK", [142] = "HYPNO", [143] = "GOLBAT", [144] = "MEWTWO", [145] = "SNORLAX",
[146] = "MAGIKARP", [147] = "MUK", [148] = "KINGLER", [149] = "CLOYSTER", [150] = "MEWTWO",
[151] = "MEW", [152] = "CATERPIE", [153] = "METAPOD", [154] = "BUTTERFREE", [155] = "MACHOP",
[156] = "ZUBAT", [157] = "EKANS", [158] = "PARAS", [159] = "POLIWHIRL", [160] = "POLIWRATH",
[161] = "WEEDLE", [162] = "KAKUNA", [163] = "BEEDRILL", [164] = "DODRIO", [165] = "PRIMEAPE",
[166] = "DUGTRIO", [167] = "VENOMOTH", [168] = "DEGWONG", [169] = "CATERPIE", [170] = "METAPOD",
[171] = "BUTTERFREE", [172] = "MACHOP", [173] = "ZUBAT", [174] = "EKANS", [175] = "PARAS",
[176] = "POLIWHIRL", [177] = "POLIWRATH", [178] = "WEEDLE", [179] = "KAKUNA", [180] = "BEEDRILL",
[181] = "DODRIO", [182] = "PRIMEAPE", [183] = "DUGTRIO", [184] = "VENOMOTH", [185] = "DEGWONG",
[186] = "CHARMANDER", [187] = "SQUIRTLE", [188] = "CHARMELEON", [189] = "WARTORTLE", [190] = "CHARIZARD"
}
return function(mod)
local DEBUG = true
local function debugLog(fmt, ...)
if DEBUG then
mod.log:info(fmt, ...)
end
end
local glitchArmedFromSight = false
local pendingGlitchMap = nil
local waitingGlitchMenuClose = false
-- Helper to get species string from Special stat value
local function speciesForSpecial(val)
if not val or val <= 0 then return "MEW" end
return INDEX_TO_SPECIES[val] or "MEW"
end
-- 1. DETECCIÓN: Intercept Start menu on the exact frame a trainer spots the player ("!" emote)
mod.hooks:wrap("input.step", function(next, game, dt)
next(game, dt)
local active = mod.save:get("glitchActive", false)
local origin = mod.save:get("originMap", nil)
local state = game and game.stack and game.stack:top()
-- Check if trainer sight exclamation bubble is active and player presses Start
if state and state.engaging and state.emote then
local npc = state.emote.npc
local player = state.player
local dist = 0
if npc and player then
dist = math.abs(npc.cellX - player.cellX) + math.abs(npc.cellY - player.cellY)
end
local input = game.input
if input and input:wasPressed("start") then
-- Glitch only arms if trainer is at distance >= 3 tiles
if dist >= 3 then
glitchArmedFromSight = true
pendingGlitchMap = state.map and state.map.id
-- Neutralize background trainer approach callback so fight() doesn't freeze the player after teleport
if state.emote then
state.emote.onDone = nil
state.emote = nil
end
state.engaging = false
local Sound = require("src.core.Sound")
local Screens = require("src.ui.Screens")
Sound.play(game.data, "Start_Menu")
Screens.push(game, "StartMenu")
debugLog("[mewmod] Intercepted Start menu on trainer sight line exclamation bubble (distance: %d tiles, map: %s).", dist, tostring(pendingGlitchMap))
return
else
debugLog("[mewmod] Trainer sight line too close (distance: %d < 3 tiles); glitch activation bypassed.", dist)
end
end
end
-- Lock Start and A button interactions on other maps while glitch is active
if active and state and state.map and origin and state.map.id ~= origin then
local input = game.input
if input then
local blockedA = false
local blockedStart = false
if input.pressQueue then
for i = #input.pressQueue, 1, -1 do
local btn = input.pressQueue[i]
if btn == "a" then
table.remove(input.pressQueue, i)
blockedA = true
elseif btn == "start" then
table.remove(input.pressQueue, i)
blockedStart = true
end
end
end
if input.pressed then
if input.pressed["a"] then
input.pressed["a"] = nil
blockedA = true
end
if input.pressed["start"] then
input.pressed["start"] = nil
blockedStart = true
end
end
if blockedA then
debugLog("[mewmod] Blocked A-button interaction outside origin map.")
end
if blockedStart then
debugLog("[mewmod] Blocked Start menu invocation outside origin map.")
end
end
end
-- Auto-open Start Menu when returning to origin map while glitch is active
if active and state and state.map and origin and state.map.id == origin then
if not waitingGlitchMenuClose and not state.engaging and not state.teleportOut and not state.flyAnim then
local sid = state.screenId or state.id
if sid ~= "StartMenu" then
waitingGlitchMenuClose = true
local Sound = require("src.core.Sound")
local Screens = require("src.ui.Screens")
Sound.play(game.data, "Start_Menu")
Screens.push(game, "StartMenu")
debugLog("[mewmod] Re-entered origin map '%s': auto-opening Start menu.", tostring(origin))
end
end
end
-- Check if player activates Teleport (beginTeleportOut) while glitchArmedFromSight is true
if glitchArmedFromSight and state and state.teleportOut then
mod.save:set("glitchActive", true)
if pendingGlitchMap then
mod.save:set("originMap", pendingGlitchMap)
end
glitchArmedFromSight = false
debugLog("[mewmod] Mew glitch armed via Teleport departure (origin map: %s).", tostring(pendingGlitchMap))
end
end)
-- Intercept Fly (TownMap) activation while glitchArmedFromSight is true
mod.events:on("screen.pushed", function(ev)
if glitchArmedFromSight and ev and ev.state then
local sid = ev.state.screenId or ev.state.id
-- Flying opens TownMap
if sid == "TownMap" then
mod.save:set("glitchActive", true)
if pendingGlitchMap then
mod.save:set("originMap", pendingGlitchMap)
end
glitchArmedFromSight = false
debugLog("[mewmod] Mew glitch armed via Fly selection (origin map: %s).", tostring(pendingGlitchMap))
end
end
end)
-- Handle closing the StartMenu on the origin map to trigger the encounter
mod.events:on("screen.popped", function(ev)
if waitingGlitchMenuClose and ev and ev.state then
local sid = ev.state.screenId or ev.state.id
if sid == "StartMenu" then
waitingGlitchMenuClose = false
local game = ev.state.game
local state = game and game.stack and game.stack:top()
if state and state.pushBattle then
local spec = mod.save:get("savedSpecialStat", 21)
local speciesName = speciesForSpecial(spec)
mod.save:set("glitchActive", false) -- Clear glitch state after triggering
local BattleState = require("src.battle.BattleState")
local battle = BattleState.newWild(game, speciesName, 7)
battle.onFinish = function(result) state:afterBattle(result, battle) end
state:pushBattle(battle)
debugLog("[mewmod] Start menu closed on origin map: initiating wild encounter with %s (Level 7).", speciesName)
end
end
end
end)
-- Reset pending glitch attempt when entering a normal battle
mod.events:on("battle.started", function()
glitchArmedFromSight = false
end)
-- 2. MEMORIA DEL SPECIAL STAT: Save enemy's Special attribute value on battle end
mod.events:on("battle.ended", function(ev)
if ev and ev.battle and ev.battle.enemy then
local enemy = ev.battle.enemy
local specialVal = nil
if enemy.curStats and enemy.curStats.special then
specialVal = enemy.curStats.special
elseif enemy.mon and enemy.mon.stats and enemy.mon.stats.special then
specialVal = enemy.mon.stats.special
end
if specialVal and specialVal > 0 then
mod.save:set("savedSpecialStat", specialVal)
debugLog("[mewmod] Saved opponent Special stat: %d -> target species: %s.", specialVal, speciesForSpecial(specialVal))
end
end
end)
-- 3. DESENCADENANTE: Force wild encounter fallback if encounter.roll checks
mod.hooks:wrap("encounter.roll", function(next, encDef, ctx)
local active = mod.save:get("glitchActive", false)
local origin = mod.save:get("originMap", nil)
if active and ctx and origin and ctx.mapId == origin then
local spec = mod.save:get("savedSpecialStat", 21)
local speciesName = speciesForSpecial(spec)
mod.save:set("glitchActive", false) -- Clear glitch state after triggering
debugLog("[mewmod] Mew glitch triggered on step: forcing wild encounter with %s (Level 7) on map %s.", speciesName, tostring(ctx.mapId))
return { species = speciesName, level = 7 }
end
return next(encDef, ctx)
end)
end