Skip to content

Commit ffd4af5

Browse files
committed
feat: filter rocket Pokemon for unconfirmed grunts
New option "fallbackRocketPokemonFiltering" enables maps to have rocket Pokemon filtering even without rocket scanning capabilities. Disable this switch to revert to the old behavior.
1 parent 7be2aea commit ffd4af5

File tree

4 files changed

+106
-21
lines changed

4 files changed

+106
-21
lines changed

config/default.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@
245245
"enableMapJsFilter": true,
246246
"fetchLatestInvasions": true,
247247
"invasionCacheHrs": 1,
248+
"fallbackRocketPokemonFiltering": true,
248249
"masterfileCacheHrs": 6,
249250
"webhookCacheHrs": 1,
250251
"questMessage": "",

server/src/models/Pokestop.js

Lines changed: 93 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -549,27 +549,61 @@ class Pokestop extends Model {
549549
invasion.andWhere('confirmed', onlyConfirmed)
550550
}
551551
invasion.andWhere((subQuery) => {
552-
if (hasConfirmed) {
553-
if (rocketPokemon.length) {
554-
subQuery
555-
.whereIn('slot_1_pokemon_id', rocketPokemon)
556-
.orWhereIn('slot_2_pokemon_id', rocketPokemon)
557-
.orWhereIn('slot_3_pokemon_id', rocketPokemon)
558-
.orWhereIn(
552+
// Case (a): Include if the invasion character/grunt type is checked
553+
subQuery.whereIn(
554+
isMad ? 'character_display' : 'character',
555+
invasions,
556+
)
557+
558+
// Case (b): Include if invasion has potential rewards that are checked
559+
if (rocketPokemon.length) {
560+
// For confirmed invasions, check actual Pokemon slots
561+
if (hasConfirmed)
562+
subQuery.orWhere((confirmedQuery) => {
563+
confirmedQuery
564+
.where('confirmed', 1)
565+
.andWhere((pokemonQuery) => {
566+
pokemonQuery
567+
.whereIn('slot_1_pokemon_id', rocketPokemon)
568+
.orWhereIn('slot_2_pokemon_id', rocketPokemon)
569+
.orWhereIn('slot_3_pokemon_id', rocketPokemon)
570+
})
571+
})
572+
573+
// For unconfirmed invasions, check if their potential rewards match
574+
// Get all grunt types that have potential rewards matching the filter
575+
const gruntTypesWithMatchingRewards = []
576+
Object.entries(state.event.invasions).forEach(
577+
([gruntType, info]) => {
578+
if (!info) return
579+
if (
580+
[
581+
...(info.firstReward ? info.encounters.first : []),
582+
...(info.secondReward ? info.encounters.second : []),
583+
...(info.thirdReward ? info.encounters.third : []),
584+
].some((poke) =>
585+
rocketPokemon.includes(String(poke.id)),
586+
)
587+
) {
588+
gruntTypesWithMatchingRewards.push(gruntType)
589+
}
590+
},
591+
)
592+
593+
if (gruntTypesWithMatchingRewards.length > 0) {
594+
subQuery.orWhere((unconfirmedQuery) => {
595+
unconfirmedQuery.whereIn(
559596
isMad ? 'character_display' : 'character',
560-
invasions,
597+
gruntTypesWithMatchingRewards,
561598
)
562-
} else {
563-
subQuery.whereIn(
564-
isMad ? 'character_display' : 'character',
565-
invasions,
566-
)
599+
if (hasConfirmed)
600+
unconfirmedQuery.andWhere((confirmationQuery) => {
601+
confirmationQuery
602+
.where('confirmed', 0)
603+
.orWhereNull('confirmed')
604+
})
605+
})
567606
}
568-
} else {
569-
subQuery.whereIn(
570-
isMad ? 'character_display' : 'character',
571-
invasions,
572-
)
573607
}
574608
})
575609
if (onlyExcludeGrunts) {
@@ -1530,6 +1564,37 @@ class Pokestop extends Model {
15301564
}
15311565
})
15321566
}
1567+
1568+
if (config.getSafe('map.misc.fallbackRocketPokemonFiltering')) {
1569+
// Always include potential rocket Pokemon from state.event.invasions as backup
1570+
Object.values(state.event.invasions).forEach((invasionInfo) => {
1571+
if (invasionInfo) {
1572+
// Add all potential first slot rewards
1573+
if (invasionInfo.firstReward && invasionInfo.encounters.first) {
1574+
invasionInfo.encounters.first.forEach((poke) => {
1575+
finalList.add(`a${poke.id}-${poke.form}`)
1576+
})
1577+
}
1578+
1579+
// Add all potential second slot rewards
1580+
if (
1581+
invasionInfo.secondReward &&
1582+
invasionInfo.encounters.second
1583+
) {
1584+
invasionInfo.encounters.second.forEach((poke) => {
1585+
finalList.add(`a${poke.id}-${poke.form}`)
1586+
})
1587+
}
1588+
1589+
// Add all potential third slot rewards
1590+
if (invasionInfo.thirdReward && invasionInfo.encounters.third) {
1591+
invasionInfo.encounters.third.forEach((poke) => {
1592+
finalList.add(`a${poke.id}-${poke.form}`)
1593+
})
1594+
}
1595+
}
1596+
})
1597+
}
15331598
break
15341599
case 'showcase':
15351600
if (hasShowcaseData) {
@@ -2004,6 +2069,16 @@ class Pokestop extends Model {
20042069
* @returns {Promise<{ hasConfirmedInvasions: boolean }>}
20052070
*/
20062071
static async getFilterContext({ isMad, hasConfirmed }) {
2072+
// Check if rocket Pokemon filtering should be forced via config
2073+
const fallback = config.getSafe('map.misc.fallbackRocketPokemonFiltering')
2074+
2075+
if (fallback) {
2076+
// Always enable rocket Pokemon filtering regardless of database support
2077+
// This allows filtering by potential rocket Pokemon even without confirmed invasions
2078+
return { hasConfirmedInvasions: true }
2079+
}
2080+
2081+
// Use original behavior when config is disabled
20072082
if (isMad || !hasConfirmed) return { hasConfirmedInvasions: false }
20082083
const result = await this.query()
20092084
.from('incident')

server/src/services/EventManager.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ class EventManager extends Logger {
245245
if (config.getSafe('api.pogoApiEndpoints.invasions')) {
246246
this.intervals.invasions = setInterval(
247247
async () => {
248-
await this.getInvasions()
248+
await this.getInvasions(Db)
249249
await this.chatLog('event', { description: 'Refreshed invasions' })
250250
},
251251
1000 * 60 * 60 * (config.getSafe('map.misc.invasionCacheHrs') || 1),
@@ -355,7 +355,11 @@ class EventManager extends Logger {
355355
this[type] = Object.values(this[`${type}Backup`])
356356
}
357357

358-
async getInvasions() {
358+
/**
359+
*
360+
* @param {import('./DbManager').DbManager} [Db] - Database manager instance
361+
*/
362+
async getInvasions(Db) {
359363
const endpoint = config.getSafe('api.pogoApiEndpoints.invasions')
360364
if (endpoint) {
361365
this.log.info('Fetching Latest Invasions')
@@ -376,6 +380,11 @@ class EventManager extends Logger {
376380
.map(Number)
377381

378382
this.invasions = newInvasions
383+
384+
// Update available rocket Pokemon whenever invasions are refreshed
385+
if (Db) {
386+
await this.setAvailable('pokestops', 'Pokestop', Db)
387+
}
379388
}
380389
} catch (e) {
381390
this.log.warn('Unable to generate latest invasions:\n', e)

server/src/services/state.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ const state = {
127127
promises.push(this.pvp.fetchLatestPokemon())
128128
}
129129
if (!reloadReport || reloadReport.invasions) {
130-
promises.push(this.event.getInvasions())
130+
promises.push(this.event.getInvasions(this.db))
131131
}
132132
if (!reloadReport || reloadReport.webhooks) {
133133
promises.push(this.event.getWebhooks())

0 commit comments

Comments
 (0)