Skip to content

Commit 7fde935

Browse files
authored
Overlay: Display catch/escape odds during a shiny Safari encounter (#794)
* Overlay: Display catch/escape odds during a shiny Safari encounter * Update code formatting to satisfy newer black version * Overlay: Hard-code Gloom and Wobbuffet as completed
1 parent ce92c5a commit 7fde935

File tree

14 files changed

+131
-80
lines changed

14 files changed

+131
-80
lines changed

modules/battle_state.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
get_opponent,
2626
get_type_by_name,
2727
HIDDEN_POWER_MAP,
28+
get_move_by_name,
2829
)
2930
from modules.state_cache import state_cache
3031
from modules.tasks import get_global_script_context
@@ -531,7 +532,7 @@ def moves(self) -> list[LearnedMove | None]:
531532
result.append(LearnedMove(move, total_pp, current_pp, total_pp - move.pp))
532533
return result
533534

534-
def knows_move(self, move: str | Move, with_pp_remaining: bool = False):
535+
def knows_move(self, move: str | Move, with_pp_remaining: bool = False) -> bool:
535536
if isinstance(move, Move):
536537
move = move.name
537538
for learned_move in self.moves:
@@ -543,6 +544,20 @@ def knows_move(self, move: str | Move, with_pp_remaining: bool = False):
543544
return True
544545
return False
545546

547+
def can_use_move(self, move: str | Move) -> bool:
548+
if isinstance(move, str):
549+
move = get_move_by_name(move)
550+
for learned_move in self.moves:
551+
if (
552+
learned_move is not None
553+
and learned_move.move is move
554+
and learned_move.pp > 0
555+
and (self.disabled_move is not move or self.disabled_turns_remaining <= 0)
556+
and (self.encored_move is move or self.encore_turns_remaining <= 0)
557+
):
558+
return True
559+
return False
560+
546561
@property
547562
def is_egg(self) -> bool:
548563
return bool(self._data[0x17] & 0b0100_0000)

modules/data/get_pret_maps.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,19 @@ def _might_be_map_coordinates(value) -> bool:
5555
out.write(f"class MapGroup{game_code}(Enum):\n")
5656
for map_group in map_group_names:
5757
out.write(f" {map_group_names[map_group]} = {map_group}\n")
58-
out.write(
59-
f""" def __contains__(self, item):
58+
out.write(f""" def __contains__(self, item):
6059
if _might_be_map_coordinates(item):
6160
return self.value == item[0]
6261
elif isinstance(item, Map{game_code}):
6362
return self.value == item.value[0]
6463
else:
65-
return NotImplemented"""
66-
)
64+
return NotImplemented""")
6765

6866
out.write("\n\n\n")
6967

7068
out.write(f"class Map{game_code}(Enum):\n")
7169
out.write(" " + "\n".join(output).strip() + "\n")
72-
out.write(
73-
f"""
70+
out.write(f"""
7471
def __eq__(self, other):
7572
if _might_be_map_coordinates(other):
7673
return self.value == other
@@ -92,5 +89,4 @@ def __contains__(self, item):
9289
elif isinstance(item, MapLocation):
9390
return item.map_group == self.value[0] and item.map_number == self.value[1]
9491
else:
95-
return NotImplemented\n"""
96-
)
92+
return NotImplemented\n""")

modules/gui/emulator_controls.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -320,9 +320,7 @@ def _update_stats(self):
320320
self.stats_label.config(text=" | ".join(stats))
321321

322322
def _reset_shiny_phase_stats(self):
323-
is_the_user_sure = ask_for_confirmation(
324-
dedent(
325-
"""
323+
is_the_user_sure = ask_for_confirmation(dedent("""
326324
This will reset all stats from your current shiny phase -- such
327325
as encounters, IV/SV records, fishing attempts etc. -- to zero.
328326
@@ -334,9 +332,7 @@ def _reset_shiny_phase_stats(self):
334332
Total encounter numbers will not be affected.
335333
336334
This cannot be undone! Are you sure you want to proceed?
337-
"""
338-
)
339-
)
335+
"""))
340336

341337
if is_the_user_sure:
342338
context.stats.clear_current_shiny_phase()

modules/gui/emulator_screen.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
from modules.sprites import generate_placeholder_image
1818
from modules.version import pokebot_name, pokebot_version
1919

20-
2120
# Defines how many frames can be reverted at the most in stepping mode.
2221
stepping_mode_frame_history_size = 128
2322
stepping_mode_forward_key = "<space>"

modules/modes/util/map.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def find_closest_pokemon_center(
108108
pass
109109

110110
if pokemon_center is None:
111-
raise BotModeError("Could not find a suitable oath from here to a Pokemon Center nearby.")
111+
raise BotModeError("Could not find a suitable path from here to a Pokemon Center nearby.")
112112

113113
return pokemon_center
114114

modules/stats.py

Lines changed: 22 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -708,16 +708,14 @@ def clear_current_shiny_phase(self):
708708
(self.current_shiny_phase.start_time, self.current_shiny_phase.shiny_phase_id),
709709
)
710710

711-
self._execute_write(
712-
"""
711+
self._execute_write("""
713712
UPDATE encounter_summaries
714713
SET phase_encounters = 0,
715714
phase_highest_iv_sum = NULL,
716715
phase_lowest_iv_sum = NULL,
717716
phase_highest_sv = NULL,
718717
phase_lowest_sv = NULL
719-
"""
720-
)
718+
""")
721719

722720
for index in self._encounter_summaries:
723721
summary = self._encounter_summaries[index]
@@ -991,8 +989,7 @@ def _get_next_shiny_phase_id(self) -> int:
991989
return int(result[0]) + 1
992990

993991
def _get_encounter_summaries(self) -> dict[int, EncounterSummary]:
994-
result = self._cursor.execute(
995-
"""
992+
result = self._cursor.execute("""
996993
SELECT
997994
species_id,
998995
species_name,
@@ -1011,8 +1008,7 @@ def _get_encounter_summaries(self) -> dict[int, EncounterSummary]:
10111008
last_encounter_time
10121009
FROM encounter_summaries
10131010
ORDER BY species_id
1014-
"""
1015-
)
1011+
""")
10161012

10171013
encounter_summaries = {}
10181014
for row in result:
@@ -1165,16 +1161,14 @@ def _reset_phase_in_database(self, encounter: Encounter) -> None:
11651161
(encounter.encounter_time, encounter.encounter_id, self.current_shiny_phase.shiny_phase_id),
11661162
)
11671163

1168-
self._execute_write(
1169-
"""
1164+
self._execute_write("""
11701165
UPDATE encounter_summaries
11711166
SET phase_encounters = 0,
11721167
phase_highest_iv_sum = NULL,
11731168
phase_lowest_iv_sum = NULL,
11741169
phase_highest_sv = NULL,
11751170
phase_lowest_sv = NULL
1176-
"""
1177-
)
1171+
""")
11781172

11791173
def _insert_or_update_encounter_summary(self, encounter_summary: EncounterSummary) -> None:
11801174
if encounter_summary.species is None:
@@ -1314,20 +1308,14 @@ def _update_schema(self, from_schema_version: int) -> None:
13141308
if from_schema_version <= 0:
13151309
self._execute_write("CREATE TABLE schema_version (version INT UNSIGNED)")
13161310

1317-
self._execute_write(
1318-
dedent(
1319-
"""
1311+
self._execute_write(dedent("""
13201312
CREATE TABLE base_data (
13211313
data_key INT UNSIGNED PRIMARY KEY,
13221314
value TEXT DEFAULT NULL
13231315
)
1324-
"""
1325-
)
1326-
)
1316+
"""))
13271317

1328-
self._execute_write(
1329-
dedent(
1330-
"""
1318+
self._execute_write(dedent("""
13311319
CREATE TABLE encounter_summaries (
13321320
species_id INT UNSIGNED PRIMARY KEY,
13331321
species_name TEXT NOT NULL,
@@ -1345,13 +1333,9 @@ def _update_schema(self, from_schema_version: int) -> None:
13451333
phase_lowest_sv INT UNSIGNED DEFAULT NULL,
13461334
last_encounter_time DATETIME
13471335
)
1348-
"""
1349-
)
1350-
)
1336+
"""))
13511337

1352-
self._execute_write(
1353-
dedent(
1354-
"""
1338+
self._execute_write(dedent("""
13551339
CREATE TABLE shiny_phases (
13561340
shiny_phase_id INT UNSIGNED PRIMARY KEY,
13571341
start_time DATETIME NOT NULL,
@@ -1379,13 +1363,9 @@ def _update_schema(self, from_schema_version: int) -> None:
13791363
snapshot_species_encounters INT UNSIGNED DEFAULT NULL,
13801364
snapshot_species_shiny_encounters INT UNSIGNED DEFAULT NULL
13811365
)
1382-
"""
1383-
)
1384-
)
1366+
"""))
13851367

1386-
self._execute_write(
1387-
dedent(
1388-
"""
1368+
self._execute_write(dedent("""
13891369
CREATE TABLE encounters (
13901370
encounter_id INT UNSIGNED PRIMARY KEY,
13911371
species_id INT UNSIGNED NOT NULL,
@@ -1402,50 +1382,32 @@ def _update_schema(self, from_schema_version: int) -> None:
14021382
outcome INT UNSIGNED DEFAULT NULL,
14031383
data BLOB NOT NULL
14041384
)
1405-
"""
1406-
)
1407-
)
1385+
"""))
14081386

1409-
self._execute_write(
1410-
dedent(
1411-
"""
1387+
self._execute_write(dedent("""
14121388
CREATE TABLE pickup_items (
14131389
item_id INT UNSIGNED PRIMARY KEY,
14141390
item_name TEXT NOT NULL,
14151391
times_picked_up INT NOT NULL DEFAULT 0
14161392
)
1417-
"""
1418-
)
1419-
)
1393+
"""))
14201394

14211395
if from_schema_version <= 1:
1422-
self._execute_write(
1423-
dedent(
1424-
"""
1396+
self._execute_write(dedent("""
14251397
ALTER TABLE shiny_phases
14261398
ADD pokenav_calls INT UNSIGNED DEFAULT 0
1427-
"""
1428-
)
1429-
)
1399+
"""))
14301400

1431-
self._execute_write(
1432-
dedent(
1433-
"""
1401+
self._execute_write(dedent("""
14341402
DROP TABLE base_data
1435-
"""
1436-
)
1437-
)
1403+
"""))
14381404

1439-
self._execute_write(
1440-
dedent(
1441-
"""
1405+
self._execute_write(dedent("""
14421406
CREATE TABLE base_data (
14431407
data_key TEXT PRIMARY KEY,
14441408
value TEXT DEFAULT NULL
14451409
)
1446-
"""
1447-
)
1448-
)
1410+
"""))
14491411

14501412
self._execute_write("DELETE FROM schema_version")
14511413
self._execute_write("INSERT INTO schema_version VALUES (?)", (current_schema_version,))

modules/web/http.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
from modules.version import pokebot_version, pokebot_name
4444
from modules.web.http_stream import add_subscriber
4545

46-
4746
custom_state: dict = {}
4847

4948

modules/web/static/stream-overlay/content/route-encounters.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ const updateRouteEncountersList = (encounters, stats, encounterType, checklistCo
167167
catches.push(missedShiniesLabel);
168168
}
169169

170-
if (goal && species.catches >= goal) {
170+
if (goal && (species.catches >= goal || species.species_name === "Gloom" || species.species_name === "Wobbuffet")) {
171171
const tick = document.createElement("img")
172172
tick.src = "/static/sprites/stream-overlay/tick.png";
173173
tick.classList.add("tick");
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/** @type {HTMLDivElement} */
2+
const safariRatesBox = document.getElementById("safari-rates");
3+
4+
const sectionChecklistBox = document.getElementById("section-checklist");
5+
6+
/** @type {HTMLSpanElement} */
7+
const safariCatchRateLabel = document.getElementById("safari_catch_rate");
8+
/** @type {HTMLSpanElement} */
9+
const safariEscapeRateLabel = document.getElementById("safari_escape_rate");
10+
11+
/**
12+
* @param {number|null} catchRate
13+
* @param {number|null} escapeRate
14+
*/
15+
const showSafariRates = (catchRate, escapeRate) => {
16+
if (catchRate === null || escapeRate === null) {
17+
hideSafariRates();
18+
return;
19+
}
20+
21+
safariCatchRateLabel.innerText = (catchRate * 100).toFixed(1) + "%";
22+
safariEscapeRateLabel.innerText = (100 * escapeRate).toFixed(0) + "%";
23+
24+
safariRatesBox.style.display = "block";
25+
sectionChecklistBox.style.display = "none";
26+
}
27+
28+
const hideSafariRates = () => {
29+
safariRatesBox.style.display = "none";
30+
sectionChecklistBox.style.display = "block";
31+
}
32+
33+
34+
export {showSafariRates};

modules/web/static/stream-overlay/index.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,16 @@ <h2>
197197
</h2>
198198
<ul></ul>
199199
</div>
200+
<div class="content-box" id="safari-rates">
201+
<h2>
202+
<img src="../sprites/items/Safari%20Ball.png" style="transform: scale(1.44)">Safari Zone Encounter
203+
</h2>
204+
<div>
205+
<p><small>Odds of being caught each turn:</small> <strong id="safari_catch_rate">?</strong></p>
206+
<p><small>Odds of running away each turn:</small> <strong id="safari_escape_rate">?</strong></p>
207+
<small>!safaristrat</small>
208+
</div>
209+
</div>
200210
<div class="content-box" id="section-checklist">
201211
<h2>
202212
<img src="../sprites/stream-overlay/target.png">Shiny Pokemon needed before the next gym

0 commit comments

Comments
 (0)