bcsfe 3.1.0__tar.gz → 3.2.0b2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {bcsfe-3.1.0/src/bcsfe.egg-info → bcsfe-3.2.0b2}/PKG-INFO +4 -2
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/README.md +3 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/__init__.py +1 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/__main__.py +3 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/color.py +4 -14
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/dialog_creator.py +6 -2
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/basic_items.py +6 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/cat_editor.py +0 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/event_tickets.py +2 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/map.py +5 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/feature_handler.py +10 -2
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/save_management.py +90 -27
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/__init__.py +20 -2
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/__init__.py +2 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/cat.py +2 -30
- bcsfe-3.2.0b2/src/bcsfe/core/game/catbase/gambling.py +111 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/enigma.py +5 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/gauntlets.py +4 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/map_names.py +56 -18
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/outbreaks.py +2 -10
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/story.py +1 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/zero_legends.py +16 -3
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/bc_csv.py +1 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/config.py +5 -6
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/path.py +2 -6
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/save.py +32 -155
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/server/game_data_getter.py +92 -108
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/server/updater.py +1 -2
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/core/main.properties +4 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/core/save.properties +13 -3
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/core/server.properties +4 -0
- bcsfe-3.2.0b2/src/bcsfe/files/locales/en/edits/gambling.properties +3 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/items.properties +3 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/map.properties +3 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/treasures.properties +2 -2
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/core/main.properties +3 -0
- bcsfe-3.2.0b2/src/bcsfe/files/locales/vi/edits/gambling.properties +3 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/items.properties +4 -1
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/map.properties +4 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2/src/bcsfe.egg-info}/PKG-INFO +4 -2
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe.egg-info/SOURCES.txt +3 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/LICENSE +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/MANIFEST.in +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/pyproject.toml +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/setup.cfg +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/setup.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/__init__.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/__init__.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/aku_realm.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/clear_tutorial.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/enemy_editor.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/fixes.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/max_all.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/edits/rare_ticket_trade.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/file_dialog.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/main.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/cli/server_cli.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/country_code.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/crypto.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/__init__.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/battle/__init__.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/battle/battle_items.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/battle/cleared_slots.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/battle/enemy.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/battle/slots.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/beacon_base.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/drop_chara.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/gatya.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/gatya_item.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/item_pack.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/login_bonuses.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/matatabi.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/medals.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/mission.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/my_sale.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/nyanko_club.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/officer_pass.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/playtime.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/powerup.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/scheme_items.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/special_skill.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/stamp.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/talent_orbs.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/unlock_popups.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/upgrade.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/catbase/user_rank_rewards.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/gamoto/__init__.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/gamoto/base_materials.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/gamoto/cat_shrine.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/gamoto/catamins.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/gamoto/gamatoto.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/gamoto/ototo.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/localizable.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/__init__.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/aku.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/challenge.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/chapters.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/dojo.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/event.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/ex_stage.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/item_reward_stage.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/legend_quest.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/map_reset.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/timed_score.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/tower.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game/map/uncanny.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/game_version.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/__init__.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/adb_handler.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/command.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/data.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/git_handler.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/json_file.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/root_handler.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/thread_helper.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/waydroid.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/io/yaml.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/locale_handler.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/log.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/max_value_helper.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/server/__init__.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/server/client_info.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/server/event_data.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/server/headers.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/server/managed_item.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/server/request.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/server/server_handler.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/core/theme_handler.py +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/core/config.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/core/files.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/core/input.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/core/locale.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/core/theme.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/core/updater.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/bannable_items.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/cats.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/enemy.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/fixes.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/gamototo.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/gatya.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/gold_pass.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/medals.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/missions.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/playtime.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/scheme_items.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/special_skills.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/talent_orbs.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/en/edits/user_rank.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/core/config.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/core/files.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/core/input.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/core/locale.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/core/save.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/core/server.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/core/theme.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/core/updater.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/bannable_items.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/cats.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/enemy.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/fixes.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/gamototo.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/gatya.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/gold_pass.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/medals.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/missions.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/playtime.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/scheme_items.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/special_skills.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/talent_orbs.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/treasures.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/edits/user_rank.properties +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/locales/vi/metadata.json +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/max_values.json +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/themes/default.json +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/files/themes/discord.json +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe/py.typed +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe.egg-info/dependency_links.txt +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe.egg-info/entry_points.txt +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe.egg-info/requires.txt +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/src/bcsfe.egg-info/top_level.txt +0 -0
- {bcsfe-3.1.0 → bcsfe-3.2.0b2}/tests/test_parse.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bcsfe
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.2.0b2
|
|
4
4
|
Summary: A save file editor for The Battle Cats
|
|
5
5
|
Author: fieryhenry
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -368,10 +368,12 @@ Alternatively you can use pip directly, although it won't auto-update with the l
|
|
|
368
368
|
git commits.
|
|
369
369
|
|
|
370
370
|
```sh
|
|
371
|
-
py -m pip install git+https://codeberg.org/fieryhenry/BCSFE-Python.git
|
|
371
|
+
py -m pip install -U git+https://codeberg.org/fieryhenry/BCSFE-Python.git
|
|
372
372
|
py -m bcsfe
|
|
373
373
|
```
|
|
374
374
|
|
|
375
|
+
Again, you might need change `py` for `python` or `python3`
|
|
376
|
+
|
|
375
377
|
If you want to use the editor again all you need to do is run the `py -m bcsfe` command
|
|
376
378
|
|
|
377
379
|
## Documentation
|
|
@@ -339,10 +339,12 @@ Alternatively you can use pip directly, although it won't auto-update with the l
|
|
|
339
339
|
git commits.
|
|
340
340
|
|
|
341
341
|
```sh
|
|
342
|
-
py -m pip install git+https://codeberg.org/fieryhenry/BCSFE-Python.git
|
|
342
|
+
py -m pip install -U git+https://codeberg.org/fieryhenry/BCSFE-Python.git
|
|
343
343
|
py -m bcsfe
|
|
344
344
|
```
|
|
345
345
|
|
|
346
|
+
Again, you might need change `py` for `python` or `python3`
|
|
347
|
+
|
|
346
348
|
If you want to use the editor again all you need to do is run the `py -m bcsfe` command
|
|
347
349
|
|
|
348
350
|
## Documentation
|
|
@@ -52,7 +52,9 @@ def main():
|
|
|
52
52
|
cli.main.Main.leave()
|
|
53
53
|
except Exception as e:
|
|
54
54
|
tb = traceback.format_exc()
|
|
55
|
-
cli.color.ColoredText.localize(
|
|
55
|
+
cli.color.ColoredText.localize(
|
|
56
|
+
"error", error=e, version=bcsfe.__version__, traceback=tb
|
|
57
|
+
)
|
|
56
58
|
try:
|
|
57
59
|
cli.main.Main.exit_editor()
|
|
58
60
|
except Exception:
|
|
@@ -113,13 +113,9 @@ class ColoredText:
|
|
|
113
113
|
print(colored.stylize(text, fg), end="") # type: ignore
|
|
114
114
|
|
|
115
115
|
@staticmethod
|
|
116
|
-
def localize(
|
|
117
|
-
string: str, escape: bool = True, **kwargs: Any
|
|
118
|
-
) -> ColoredText:
|
|
116
|
+
def localize(string: str, escape: bool = True, **kwargs: Any) -> ColoredText:
|
|
119
117
|
return ColoredText(
|
|
120
|
-
core.core_data.local_manager.get_key(
|
|
121
|
-
string, escape=escape, **kwargs
|
|
122
|
-
)
|
|
118
|
+
core.core_data.local_manager.get_key(string, escape=escape, **kwargs)
|
|
123
119
|
)
|
|
124
120
|
|
|
125
121
|
def parse(self, txt: str) -> list[tuple[str, str]]:
|
|
@@ -134,11 +130,7 @@ class ColoredText:
|
|
|
134
130
|
special_chars = core.LocalManager.get_special_chars()
|
|
135
131
|
while i < len(txt):
|
|
136
132
|
char = txt[i]
|
|
137
|
-
if (
|
|
138
|
-
char == "\\"
|
|
139
|
-
and i + 1 < len(txt)
|
|
140
|
-
and txt[i + 1] in special_chars
|
|
141
|
-
):
|
|
133
|
+
if char == "\\" and i + 1 < len(txt) and txt[i + 1] in special_chars:
|
|
142
134
|
i += 1
|
|
143
135
|
char = txt[i]
|
|
144
136
|
text += char
|
|
@@ -183,7 +175,5 @@ class ColoredInput:
|
|
|
183
175
|
return input()
|
|
184
176
|
|
|
185
177
|
def localize(self, string: str, escape: bool = True, **kwargs: Any) -> str:
|
|
186
|
-
text = core.core_data.local_manager.get_key(
|
|
187
|
-
string, escape=escape, **kwargs
|
|
188
|
-
)
|
|
178
|
+
text = core.core_data.local_manager.get_key(string, escape=escape, **kwargs)
|
|
189
179
|
return self.get(text)
|
|
@@ -327,7 +327,7 @@ class ChoiceInput:
|
|
|
327
327
|
dialog = core.core_data.local_manager.get_key(key).format(
|
|
328
328
|
min=self.get_min_value(), max=self.get_max_value()
|
|
329
329
|
)
|
|
330
|
-
usr_input = color.ColoredInput().get(dialog).split(" ")
|
|
330
|
+
usr_input = color.ColoredInput().get(dialog).strip().split(" ")
|
|
331
331
|
int_vals: list[int] = []
|
|
332
332
|
for inp in usr_input:
|
|
333
333
|
try:
|
|
@@ -689,7 +689,11 @@ class YesNoInput:
|
|
|
689
689
|
|
|
690
690
|
if usr_input == core.core_data.local_manager.get_key("quit_key"):
|
|
691
691
|
return None
|
|
692
|
-
return
|
|
692
|
+
return (
|
|
693
|
+
usr_input == core.core_data.local_manager.get_key("yes_key")
|
|
694
|
+
or usr_input.lower().strip()
|
|
695
|
+
== core.core_data.local_manager.get_key("yes").lower().strip()
|
|
696
|
+
)
|
|
693
697
|
|
|
694
698
|
|
|
695
699
|
class DialogBuilder:
|
|
@@ -12,6 +12,12 @@ class BasicItems:
|
|
|
12
12
|
return core.core_data.local_manager.get_key(key)
|
|
13
13
|
return name.strip()
|
|
14
14
|
|
|
15
|
+
@staticmethod
|
|
16
|
+
def reset_golden_cat_cpus(save_file: core.SaveFile):
|
|
17
|
+
save_file.golden_cpu_count = 0
|
|
18
|
+
|
|
19
|
+
color.ColoredText.localize("reset_golden_cat_cpus_success")
|
|
20
|
+
|
|
15
21
|
@staticmethod
|
|
16
22
|
def edit_catfood(save_file: core.SaveFile):
|
|
17
23
|
should_exit = not dialog_creator.YesNoInput().get_input_once("catfood_warning")
|
|
@@ -48,7 +48,6 @@ class CatEditor:
|
|
|
48
48
|
if len(current_cats) > 50:
|
|
49
49
|
color.ColoredText.localize("total_selected_cats", total=len(current_cats))
|
|
50
50
|
else:
|
|
51
|
-
self.save_file.cats.bulk_download_names(self.save_file, current_cats)
|
|
52
51
|
for cat in current_cats:
|
|
53
52
|
names = cat.get_names_cls(self.save_file)
|
|
54
53
|
if not names:
|
|
@@ -20,7 +20,8 @@ class EventTickets:
|
|
|
20
20
|
)
|
|
21
21
|
|
|
22
22
|
cli.color.ColoredText.localize("downloading_gatya_data")
|
|
23
|
-
|
|
23
|
+
temp_save_file = core.SaveFile(cc=save_file.cc, gv=save_file.game_version)
|
|
24
|
+
gatya_event_data = core.ServerHandler(temp_save_file).download_gatya_data()
|
|
24
25
|
|
|
25
26
|
if gatya_event_data is None:
|
|
26
27
|
cli.color.ColoredText.localize("download_gatya_data_fail")
|
|
@@ -92,8 +92,12 @@ def edit_chapters(
|
|
|
92
92
|
chapters: ChaptersType,
|
|
93
93
|
letter_code: str,
|
|
94
94
|
type: int | None = None,
|
|
95
|
+
no_r_prefix: bool = False,
|
|
96
|
+
base_index: int | None = None,
|
|
95
97
|
) -> dict[int, bool] | None:
|
|
96
|
-
map_names = core.MapNames(
|
|
98
|
+
map_names = core.MapNames(
|
|
99
|
+
save_file, letter_code, no_r_prefix=no_r_prefix, base_index=base_index
|
|
100
|
+
)
|
|
97
101
|
names = map_names.map_names
|
|
98
102
|
|
|
99
103
|
choice = dialog_creator.ChoiceInput.from_reduced(
|
|
@@ -36,9 +36,11 @@ class FeatureHandler:
|
|
|
36
36
|
"waydroid_push_rerun": save_management.SaveManagement.waydroid_push_rerun,
|
|
37
37
|
"adb_push": save_management.SaveManagement.adb_push,
|
|
38
38
|
"adb_push_rerun": save_management.SaveManagement.adb_push_rerun,
|
|
39
|
+
"root_push": save_management.SaveManagement.root_push,
|
|
40
|
+
"root_push_rerun": save_management.SaveManagement.root_push_rerun,
|
|
39
41
|
"export_save": save_management.SaveManagement.export_save,
|
|
40
42
|
"load_save": save_management.SaveManagement.load_save,
|
|
41
|
-
"init_save": save_management.SaveManagement.init_save,
|
|
43
|
+
# "init_save": save_management.SaveManagement.init_save,
|
|
42
44
|
"convert_region": save_management.SaveManagement.convert_save_cc,
|
|
43
45
|
"convert_version": save_management.SaveManagement.convert_save_gv,
|
|
44
46
|
},
|
|
@@ -63,6 +65,7 @@ class FeatureHandler:
|
|
|
63
65
|
"100_million_tickets": edits.basic_items.BasicItems.edit_100_million_ticket,
|
|
64
66
|
"event_tickets": edits.event_tickets.EventTickets.edit,
|
|
65
67
|
"treasure_chests": edits.basic_items.BasicItems.edit_treasure_chests,
|
|
68
|
+
"reset_golden_cat_cpus": edits.basic_items.BasicItems.reset_golden_cat_cpus,
|
|
66
69
|
},
|
|
67
70
|
"cats_special_skills": cat_features,
|
|
68
71
|
"levels": {
|
|
@@ -70,7 +73,8 @@ class FeatureHandler:
|
|
|
70
73
|
"clear_story": core.game.map.story.StoryChapters.clear_story,
|
|
71
74
|
"challenge_score": core.game.map.challenge.edit_challenge_score,
|
|
72
75
|
"dojo_score": core.game.map.dojo.edit_dojo_score,
|
|
73
|
-
"
|
|
76
|
+
"add_enigma_stages": core.game.map.enigma.edit_enigma,
|
|
77
|
+
"clear_enigma_stages": core.game.map.gauntlets.GauntletChapters.edit_enigma_stages,
|
|
74
78
|
"unlock_aku_realm": edits.aku_realm.unlock_aku_realm,
|
|
75
79
|
"story_treasures": core.game.map.story.StoryChapters.edit_treasures,
|
|
76
80
|
"outbreaks": core.game.map.outbreaks.Outbreaks.edit_outbreaks,
|
|
@@ -88,6 +92,7 @@ class FeatureHandler:
|
|
|
88
92
|
"legend_quest": core.game.map.legend_quest.LegendQuestChapters.edit_legend_quest,
|
|
89
93
|
"towers": core.game.map.tower.TowerChapters.edit_towers,
|
|
90
94
|
"zero_legends": core.game.map.zero_legends.ZeroLegendsChapters.edit_zero_legends,
|
|
95
|
+
"dojo_catclaw_championships": core.game.map.zero_legends.ZeroLegendsChapters.edit_catclaw_championships,
|
|
91
96
|
},
|
|
92
97
|
"gamototo": {
|
|
93
98
|
"engineers": edits.basic_items.BasicItems.edit_engineers,
|
|
@@ -117,6 +122,7 @@ class FeatureHandler:
|
|
|
117
122
|
},
|
|
118
123
|
"other": {
|
|
119
124
|
"unlocked_slots": edits.basic_items.BasicItems.edit_unlocked_slots,
|
|
125
|
+
"reset_gambling_events": core.GamblingEvent.reset_events,
|
|
120
126
|
"restart_pack": edits.basic_items.BasicItems.set_restart_pack,
|
|
121
127
|
"special_skills": edits.basic_items.BasicItems.edit_special_skills,
|
|
122
128
|
"playtime": core.game.catbase.playtime.edit,
|
|
@@ -229,6 +235,8 @@ class FeatureHandler:
|
|
|
229
235
|
|
|
230
236
|
else:
|
|
231
237
|
feats = self.search_features(usr_input)
|
|
238
|
+
if not feats:
|
|
239
|
+
color.ColoredText.localize("no_feature_with_name", name=usr_input)
|
|
232
240
|
kv_map = list(feats.items())
|
|
233
241
|
kv_map.sort(key=lambda v: v[1], reverse=True)
|
|
234
242
|
selected_features = [v[0] for v in kv_map]
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
from bcsfe import core
|
|
3
|
+
import bcsfe
|
|
3
4
|
from bcsfe.core import io
|
|
4
5
|
from bcsfe.cli import main, color, dialog_creator, server_cli
|
|
5
6
|
from bcsfe.core.country_code import CountryCode
|
|
@@ -196,6 +197,43 @@ class SaveManagement:
|
|
|
196
197
|
|
|
197
198
|
return adb_handler
|
|
198
199
|
|
|
200
|
+
@staticmethod
|
|
201
|
+
def root_push(save_file: core.SaveFile) -> core.RootHandler | None:
|
|
202
|
+
"""Push the save file to the device.
|
|
203
|
+
|
|
204
|
+
Args:
|
|
205
|
+
save_file (core.SaveFile): The save file to push.
|
|
206
|
+
|
|
207
|
+
Returns:
|
|
208
|
+
core.AdbHandler: The AdbHandler instance.
|
|
209
|
+
"""
|
|
210
|
+
SaveManagement.save_save(save_file)
|
|
211
|
+
root_handler = core.RootHandler()
|
|
212
|
+
if not root_handler.is_android():
|
|
213
|
+
color.ColoredText.localize("root_push_not_android_error")
|
|
214
|
+
return None
|
|
215
|
+
if not root_handler.is_rooted():
|
|
216
|
+
color.ColoredText.localize("not_rooted_error")
|
|
217
|
+
return None
|
|
218
|
+
if save_file.used_storage and save_file.package_name is not None:
|
|
219
|
+
root_handler.set_package_name(save_file.package_name)
|
|
220
|
+
else:
|
|
221
|
+
packages = root_handler.get_battlecats_packages()
|
|
222
|
+
package_name = SaveManagement.select_package_name(packages)
|
|
223
|
+
if package_name is None:
|
|
224
|
+
color.ColoredText.localize("no_package_name_error")
|
|
225
|
+
return root_handler
|
|
226
|
+
root_handler.set_package_name(package_name)
|
|
227
|
+
if save_file.save_path is None:
|
|
228
|
+
return root_handler
|
|
229
|
+
result = root_handler.load_battlecats_save(save_file.save_path)
|
|
230
|
+
if result.success:
|
|
231
|
+
color.ColoredText.localize("root_push_success")
|
|
232
|
+
else:
|
|
233
|
+
color.ColoredText.localize("root_push_fail", error=result.result)
|
|
234
|
+
|
|
235
|
+
return root_handler
|
|
236
|
+
|
|
199
237
|
@staticmethod
|
|
200
238
|
def adb_push_rerun(save_file: core.SaveFile):
|
|
201
239
|
"""Push the save file to the device and rerun the game.
|
|
@@ -214,6 +252,24 @@ class SaveManagement:
|
|
|
214
252
|
else:
|
|
215
253
|
color.ColoredText.localize("adb_rerun_fail", error=result.result)
|
|
216
254
|
|
|
255
|
+
@staticmethod
|
|
256
|
+
def root_push_rerun(save_file: core.SaveFile):
|
|
257
|
+
"""Push the save file to the device and rerun the game.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
save_file (core.SaveFile): The save file to push.
|
|
261
|
+
"""
|
|
262
|
+
root_handler = SaveManagement.root_push(save_file)
|
|
263
|
+
if not root_handler:
|
|
264
|
+
return
|
|
265
|
+
if root_handler.package_name is None:
|
|
266
|
+
return
|
|
267
|
+
result = root_handler.rerun_game()
|
|
268
|
+
if result.success:
|
|
269
|
+
color.ColoredText.localize("root_rerun_success")
|
|
270
|
+
else:
|
|
271
|
+
color.ColoredText.localize("root_rerun_fail", error=result.result)
|
|
272
|
+
|
|
217
273
|
@staticmethod
|
|
218
274
|
def export_save(save_file: core.SaveFile):
|
|
219
275
|
"""Export the save file to a json file.
|
|
@@ -302,7 +358,7 @@ class SaveManagement:
|
|
|
302
358
|
"load_from_documents",
|
|
303
359
|
"adb_pull_save",
|
|
304
360
|
"load_save_data_json",
|
|
305
|
-
"create_new_save",
|
|
361
|
+
# "create_new_save",
|
|
306
362
|
]
|
|
307
363
|
if starting_options:
|
|
308
364
|
options.append("edit_config")
|
|
@@ -407,32 +463,32 @@ class SaveManagement:
|
|
|
407
463
|
save_path, cc = data
|
|
408
464
|
else:
|
|
409
465
|
save_path = None
|
|
410
|
-
elif choice == 5:
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
elif choice ==
|
|
466
|
+
# elif choice == 5:
|
|
467
|
+
# color.ColoredText.localize("create_new_save_warning")
|
|
468
|
+
# cc = core.CountryCode.select()
|
|
469
|
+
# if cc is None:
|
|
470
|
+
# return None, False
|
|
471
|
+
# try:
|
|
472
|
+
# gv = core.GameVersion.from_string(
|
|
473
|
+
# color.ColoredInput().localize(
|
|
474
|
+
# "game_version_dialog",
|
|
475
|
+
# )
|
|
476
|
+
# )
|
|
477
|
+
# except ValueError:
|
|
478
|
+
# color.ColoredText.localize("invalid_game_version")
|
|
479
|
+
# return None, False
|
|
480
|
+
# save = core.SaveFile(cc=cc, gv=gv, load=False)
|
|
481
|
+
# save_path = main.Main.save_save_dialog(save)
|
|
482
|
+
# if save_path is None:
|
|
483
|
+
# return None, False
|
|
484
|
+
# save.to_file(save_path)
|
|
485
|
+
# color.ColoredText.localize("create_new_save_success")
|
|
486
|
+
|
|
487
|
+
elif choice == 5 and starting_options:
|
|
432
488
|
core.core_data.config.edit_config()
|
|
433
|
-
elif choice ==
|
|
489
|
+
elif choice == 6 and starting_options:
|
|
434
490
|
core.update_external_content()
|
|
435
|
-
elif choice ==
|
|
491
|
+
elif choice == 7 and starting_options:
|
|
436
492
|
main.Main.exit_editor(check_temp=False)
|
|
437
493
|
|
|
438
494
|
if save_path is None or not save_path.exists():
|
|
@@ -465,12 +521,16 @@ class SaveManagement:
|
|
|
465
521
|
save_file = core.SaveFile(save_path.read(), cc)
|
|
466
522
|
except Exception:
|
|
467
523
|
tb = core.core_data.logger.get_traceback()
|
|
468
|
-
color.ColoredText.localize(
|
|
524
|
+
color.ColoredText.localize(
|
|
525
|
+
"parse_save_error", error=tb, version=bcsfe.__version__
|
|
526
|
+
)
|
|
469
527
|
return None
|
|
470
528
|
|
|
471
529
|
except Exception:
|
|
472
530
|
tb = core.core_data.logger.get_traceback()
|
|
473
|
-
color.ColoredText.localize(
|
|
531
|
+
color.ColoredText.localize(
|
|
532
|
+
"parse_save_error", error=tb, version=bcsfe.__version__
|
|
533
|
+
)
|
|
474
534
|
return None
|
|
475
535
|
|
|
476
536
|
save_file.save_path = save_path
|
|
@@ -503,6 +563,7 @@ class SaveManagement:
|
|
|
503
563
|
if new_save_file is None:
|
|
504
564
|
return stop
|
|
505
565
|
save_file.load_save_file(new_save_file)
|
|
566
|
+
core.core_data.init_data()
|
|
506
567
|
color.ColoredText.localize("load_save_success")
|
|
507
568
|
return False
|
|
508
569
|
|
|
@@ -515,6 +576,7 @@ class SaveManagement:
|
|
|
515
576
|
return
|
|
516
577
|
save_file.set_cc(cc)
|
|
517
578
|
core.ServerHandler(save_file).create_new_account()
|
|
579
|
+
core.core_data.init_data()
|
|
518
580
|
color.ColoredText.localize("country_code_set", cc=cc)
|
|
519
581
|
|
|
520
582
|
@staticmethod
|
|
@@ -530,4 +592,5 @@ class SaveManagement:
|
|
|
530
592
|
color.ColoredText.localize("invalid_game_version")
|
|
531
593
|
return
|
|
532
594
|
save_file.set_gv(gv)
|
|
595
|
+
core.core_data.init_data()
|
|
533
596
|
color.ColoredText.localize("game_version_set", version=gv.to_string())
|
|
@@ -4,7 +4,7 @@ from typing import Any
|
|
|
4
4
|
from requests.exceptions import ConnectionError
|
|
5
5
|
from requests import Response
|
|
6
6
|
from json.decoder import JSONDecodeError
|
|
7
|
-
from bcsfe.cli import color
|
|
7
|
+
from bcsfe.cli import color, dialog_creator
|
|
8
8
|
|
|
9
9
|
from bcsfe.core import (
|
|
10
10
|
country_code,
|
|
@@ -30,7 +30,14 @@ from bcsfe.core.game.battle.enemy import (
|
|
|
30
30
|
EnemyDictionary,
|
|
31
31
|
)
|
|
32
32
|
from bcsfe.core.game.catbase.beacon_base import BeaconEventListScene
|
|
33
|
-
from bcsfe.core.game.catbase.cat import
|
|
33
|
+
from bcsfe.core.game.catbase.cat import (
|
|
34
|
+
Cat,
|
|
35
|
+
Cats,
|
|
36
|
+
UnitBuy,
|
|
37
|
+
TalentData,
|
|
38
|
+
NyankoPictureBook,
|
|
39
|
+
)
|
|
40
|
+
from bcsfe.core.game.catbase.gambling import GamblingEvent
|
|
34
41
|
from bcsfe.core.game.catbase.gatya import (
|
|
35
42
|
Gatya,
|
|
36
43
|
GatyaInfos,
|
|
@@ -307,6 +314,14 @@ def update_external_content(_: Any = None):
|
|
|
307
314
|
ExternalLocaleManager.update_all_external_locales()
|
|
308
315
|
core_data.init_data()
|
|
309
316
|
|
|
317
|
+
clear_game_data = dialog_creator.YesNoInput().get_input_once("clear_game_data_q")
|
|
318
|
+
if clear_game_data is None:
|
|
319
|
+
return
|
|
320
|
+
|
|
321
|
+
if clear_game_data:
|
|
322
|
+
GameDataGetter.delete_old_versions(0)
|
|
323
|
+
color.ColoredText.localize("cleared_game_data")
|
|
324
|
+
|
|
310
325
|
|
|
311
326
|
def print_no_internet():
|
|
312
327
|
color.ColoredText.localize("no_internet")
|
|
@@ -368,4 +383,7 @@ __all__ = [
|
|
|
368
383
|
"GatyaDataOptionSet",
|
|
369
384
|
"GatyaDataOption",
|
|
370
385
|
"MaxValueType",
|
|
386
|
+
"GamblingEvent",
|
|
387
|
+
"UnitBuy",
|
|
388
|
+
"NyankoPictureBook",
|
|
371
389
|
]
|
|
@@ -227,7 +227,7 @@ class TalentData:
|
|
|
227
227
|
talent_data_cat = self.get_cat_skill(cat.id)
|
|
228
228
|
if talent_data_cat is None or cat.talents is None:
|
|
229
229
|
return None
|
|
230
|
-
save_talent_data = cat.talents
|
|
230
|
+
# save_talent_data = cat.talents
|
|
231
231
|
talent_names: list[str] = []
|
|
232
232
|
max_levels: list[int] = []
|
|
233
233
|
current_levels: list[int] = []
|
|
@@ -836,7 +836,6 @@ class Cats:
|
|
|
836
836
|
self.unit_limit: UnitLimit | None = None
|
|
837
837
|
self.nyanko_picture_book: NyankoPictureBook | None = None
|
|
838
838
|
self.talent_data: TalentData | None = None
|
|
839
|
-
self.bulk_downloaded = False
|
|
840
839
|
|
|
841
840
|
def get_all_cats(self) -> list[Cat]:
|
|
842
841
|
return self.cats
|
|
@@ -882,7 +881,7 @@ class Cats:
|
|
|
882
881
|
|
|
883
882
|
def get_non_gacha_cats(self, save_file: core.SaveFile) -> list[Cat]:
|
|
884
883
|
unitbuy = self.read_unitbuy(save_file)
|
|
885
|
-
cats = []
|
|
884
|
+
cats: list[Cat] = []
|
|
886
885
|
for cat in self.cats:
|
|
887
886
|
unit_buy_data = unitbuy.get_unit_buy(cat.id)
|
|
888
887
|
if unit_buy_data is None:
|
|
@@ -922,7 +921,6 @@ class Cats:
|
|
|
922
921
|
save_file: core.SaveFile,
|
|
923
922
|
search_name: str,
|
|
924
923
|
) -> list[Cat]:
|
|
925
|
-
self.bulk_download_names(save_file)
|
|
926
924
|
cats: list[Cat] = []
|
|
927
925
|
for cat in self.cats:
|
|
928
926
|
names = cat.get_names_cls(save_file)
|
|
@@ -934,32 +932,6 @@ class Cats:
|
|
|
934
932
|
break
|
|
935
933
|
return cats
|
|
936
934
|
|
|
937
|
-
def bulk_download_names(
|
|
938
|
-
self, save_file: core.SaveFile, current_cats: list[core.Cat] | None = None
|
|
939
|
-
):
|
|
940
|
-
if self.bulk_downloaded and current_cats is None:
|
|
941
|
-
return
|
|
942
|
-
file_names: list[str] = []
|
|
943
|
-
gdg = core.core_data.get_game_data_getter(save_file)
|
|
944
|
-
if current_cats is None:
|
|
945
|
-
cats = self.cats
|
|
946
|
-
else:
|
|
947
|
-
cats = current_cats
|
|
948
|
-
for cat in cats:
|
|
949
|
-
if cat.names is None:
|
|
950
|
-
file_name = f"Unit_Explanation{cat.id + 1}_{core.core_data.get_lang(save_file)}.csv"
|
|
951
|
-
if gdg.is_downloaded("resLocal", file_name):
|
|
952
|
-
continue
|
|
953
|
-
file_names.append(file_name)
|
|
954
|
-
|
|
955
|
-
if len(file_names) > 50:
|
|
956
|
-
gdg.save_all_cat_names_fast()
|
|
957
|
-
|
|
958
|
-
core.core_data.get_game_data_getter(save_file).download_all(
|
|
959
|
-
"resLocal", file_names
|
|
960
|
-
)
|
|
961
|
-
self.bulk_downloaded = current_cats is None
|
|
962
|
-
|
|
963
935
|
def get_cats_obtainable(self, save_file: core.SaveFile) -> list[Cat] | None:
|
|
964
936
|
nyanko_picture_book = self.read_nyanko_picture_book(save_file)
|
|
965
937
|
obtainable_cats = nyanko_picture_book.get_obtainable_cats()
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
from bcsfe import core
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from bcsfe.cli import color
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GamblingEvent:
|
|
9
|
+
def __init__(
|
|
10
|
+
self,
|
|
11
|
+
completed: dict[int, bool],
|
|
12
|
+
values: dict[int, dict[int, int]],
|
|
13
|
+
start_times: dict[int, int | float],
|
|
14
|
+
):
|
|
15
|
+
self.completed = completed
|
|
16
|
+
self.values = values
|
|
17
|
+
self.start_times = start_times
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def init() -> GamblingEvent:
|
|
21
|
+
return GamblingEvent({}, {}, {})
|
|
22
|
+
|
|
23
|
+
@staticmethod
|
|
24
|
+
def read(data: core.Data, game_version: core.GameVersion) -> GamblingEvent:
|
|
25
|
+
total = data.read_short()
|
|
26
|
+
completed: dict[int, bool] = {}
|
|
27
|
+
|
|
28
|
+
for _ in range(total):
|
|
29
|
+
key = data.read_short()
|
|
30
|
+
completed[key] = data.read_bool()
|
|
31
|
+
|
|
32
|
+
total = data.read_short()
|
|
33
|
+
values: dict[int, dict[int, int]] = {}
|
|
34
|
+
|
|
35
|
+
for _ in range(total):
|
|
36
|
+
key = data.read_short()
|
|
37
|
+
if key not in values:
|
|
38
|
+
values[key] = {}
|
|
39
|
+
|
|
40
|
+
total2 = data.read_short()
|
|
41
|
+
for _ in range(total2):
|
|
42
|
+
key2 = data.read_short()
|
|
43
|
+
|
|
44
|
+
values[key][key2] = data.read_short()
|
|
45
|
+
|
|
46
|
+
total = data.read_short()
|
|
47
|
+
start_times: dict[int, int | float] = {}
|
|
48
|
+
|
|
49
|
+
for _ in range(total):
|
|
50
|
+
key = data.read_short()
|
|
51
|
+
|
|
52
|
+
if game_version < 90100:
|
|
53
|
+
value = data.read_double()
|
|
54
|
+
else:
|
|
55
|
+
value = data.read_int()
|
|
56
|
+
|
|
57
|
+
start_times[key] = value
|
|
58
|
+
|
|
59
|
+
return GamblingEvent(completed, values, start_times)
|
|
60
|
+
|
|
61
|
+
def write(self, data: core.Data, game_version: core.GameVersion):
|
|
62
|
+
data.write_short(len(self.completed))
|
|
63
|
+
data.write_short_bool_dict(self.completed, write_length=False)
|
|
64
|
+
|
|
65
|
+
data.write_short(len(self.values))
|
|
66
|
+
|
|
67
|
+
for key, value in self.values.items():
|
|
68
|
+
data.write_short(key)
|
|
69
|
+
data.write_short(len(value))
|
|
70
|
+
|
|
71
|
+
for key2, value2 in value.items():
|
|
72
|
+
data.write_short(key2)
|
|
73
|
+
data.write_short(value2)
|
|
74
|
+
|
|
75
|
+
data.write_short(len(self.start_times))
|
|
76
|
+
for key, value in self.start_times.items():
|
|
77
|
+
data.write_short(key)
|
|
78
|
+
|
|
79
|
+
# this is a bad conversion, since float is timestamp i assume and int as the date as YYYMMDD. FIXME
|
|
80
|
+
if game_version < 90100:
|
|
81
|
+
data.write_double(float(value))
|
|
82
|
+
else:
|
|
83
|
+
data.write_int(int(value))
|
|
84
|
+
|
|
85
|
+
def serialize(self) -> dict[str, Any]:
|
|
86
|
+
return {
|
|
87
|
+
"completed": self.completed,
|
|
88
|
+
"values": self.values,
|
|
89
|
+
"start_times": self.start_times,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def deserialize(data: dict[str, Any]) -> GamblingEvent:
|
|
94
|
+
return GamblingEvent(
|
|
95
|
+
data.get("completed", {}),
|
|
96
|
+
data.get("values", {}),
|
|
97
|
+
data.get("start_times", {}),
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
def reset(self):
|
|
101
|
+
self.completed = {}
|
|
102
|
+
self.values = {}
|
|
103
|
+
# TODO: check start times
|
|
104
|
+
self.start_times = {}
|
|
105
|
+
|
|
106
|
+
@staticmethod
|
|
107
|
+
def reset_events(save_file: core.SaveFile):
|
|
108
|
+
save_file.wildcat_slots.reset()
|
|
109
|
+
color.ColoredText.localize("reset_wildcat_slots")
|
|
110
|
+
save_file.cat_scratcher.reset()
|
|
111
|
+
color.ColoredText.localize("reset_cat_scratcher")
|
|
@@ -195,6 +195,9 @@ class Enigma:
|
|
|
195
195
|
if wipe is None:
|
|
196
196
|
return
|
|
197
197
|
if wipe:
|
|
198
|
+
for stage in self.stages:
|
|
199
|
+
id = stage.stage_id
|
|
200
|
+
save_file.event_stages.chapter_completion_count[id] = 0
|
|
198
201
|
self.stages = []
|
|
199
202
|
|
|
200
203
|
ids, _ = dialog_creator.ChoiceInput(
|
|
@@ -209,6 +212,8 @@ class Enigma:
|
|
|
209
212
|
|
|
210
213
|
for enigma_id in ids:
|
|
211
214
|
abs_id = enigma_id + base_level
|
|
215
|
+
save_file.event_stages.chapter_completion_count[abs_id] = 0
|
|
216
|
+
# TODO: level? they can go much higher than 3... not sure it really matters though
|
|
212
217
|
stage = Stage(3, abs_id, 2, int(time.time()))
|
|
213
218
|
self.stages.append(stage)
|
|
214
219
|
|
|
@@ -334,6 +334,10 @@ class GauntletChapters:
|
|
|
334
334
|
gauntlets = save_file.behemoth_culling
|
|
335
335
|
gauntlets.edit_chapters(save_file, "Q")
|
|
336
336
|
|
|
337
|
+
@staticmethod
|
|
338
|
+
def edit_enigma_stages(save_file: core.SaveFile):
|
|
339
|
+
save_file.enigma_clears.edit_chapters(save_file, "H")
|
|
340
|
+
|
|
337
341
|
def edit_chapters(self, save_file: core.SaveFile, letter_code: str):
|
|
338
342
|
edits.map.edit_chapters(save_file, self, letter_code)
|
|
339
343
|
|