tuipet 0.5.330__tar.gz → 0.5.332__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.
- {tuipet-0.5.330/src/tuipet.egg-info → tuipet-0.5.332}/PKG-INFO +1 -1
- {tuipet-0.5.330 → tuipet-0.5.332}/pyproject.toml +1 -1
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/app.py +1 -1
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/petbase.py +11 -2
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/petbody.py +39 -19
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/petcare.py +7 -4
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/shop.py +4 -2
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/statusbox.py +22 -0
- {tuipet-0.5.330 → tuipet-0.5.332/src/tuipet.egg-info}/PKG-INFO +1 -1
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_canon_discipline.py +15 -11
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_filth_system.py +89 -6
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_shop_dossier_audit.py +6 -1
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_status_box.py +38 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/LICENSE +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/README.md +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/setup.cfg +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/__init__.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/__main__.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/accountscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/adventure.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/adventurescreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/albumscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/anim.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/appactions.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/appboot.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/arena.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/arenafx.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/assistscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/backgrounds.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/backgroundscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/battle.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/battlescreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/bugscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/cloudsync.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/attr_icons.json +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/backgrounds.json.gz +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/battle_fx.json.gz +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/battle_overlays.json +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/careEffect.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/deviceAttacks.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/digicoreMenuConfig.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/digimon.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/dropRate.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/effects.json.gz +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/eggUnlock.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/eggs.json.gz +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/elementAffinity.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/enemies.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/evolutions.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/fieldAffinity.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/foods.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/hp_dummies.json +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/icons.json.gz +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/items.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/jogress_overlays.json +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/lines.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/lootTable.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/maps.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/orbs.json.gz +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/shopConsumable.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/alarm.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/angry.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/attack.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/attackHit.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/battle.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/boot.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/cancel.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/champion.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/click.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/compatible.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/confirm.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/death.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/eat.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/error.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/evolve.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/happy.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/hatch.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/jogress.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/largePoop.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/lastBite.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/lose.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/menu.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/mischief.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/poop.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/refuse.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/reward.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/scroll.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/select.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/smallPoop.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/startBattle.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/strongAttack.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/strongHit.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/trainhit.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/wash.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sounds/win.wav +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/sprites.json.gz +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/titles.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/tournies.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/towns.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/train_wall.json +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/vitems.json +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data/zones.csv +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data_core.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data_meta.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data_shop.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/data_world.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/deathscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/digicore.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/digicorescreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/disciplinescreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/dnascreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/egg.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/eggguidescreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/eggmigrate.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/eggselectscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/evolution.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/feedscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/grid.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/hallscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/helpscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/hostinfo.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/itemfx.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/jogress.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/jogressscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/lines.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/lobbybout.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/lobbychat.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/lobbyscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/menu.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/net.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/optionsscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/persistence.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/persistio.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/pet.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/petbattle.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/petdna.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/placeholder.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/raidscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/render.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/rival.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/shopscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/sound.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/strikefx.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/theme.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/themescreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/titlescreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/tournament.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/tournamentscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/towneggscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/townscreen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/training.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet/update.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet.egg-info/SOURCES.txt +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet.egg-info/dependency_links.txt +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet.egg-info/entry_points.txt +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet.egg-info/requires.txt +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/src/tuipet.egg-info/top_level.txt +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_boss.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_conditions.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_drain.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_encounters.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_finds.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_foundation.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_geography.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_hazards.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_holiday.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_march.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_placement.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_progression.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_replay.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_rewards.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_score.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_shop.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_streak.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_summary.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_towns.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_adventure_transport.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_album_completable.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_album_dex.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_album_screen.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_anim_canon.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_anim_hardening.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_anim_timing.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_announce.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_armor_canon.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_audit_fixes.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_auto_care.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_auto_update.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_away_flag.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_background_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_backgrounds.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_battle_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_battle_race.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_bedtime.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_birthday.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_body_math.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_body_tells.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_bugreport.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_call_cadence.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_canon_injury.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_card_runoffs.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_care_asleep.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_care_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_care_bonus.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_catalog_categories.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_catalog_record.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_catalog_touches.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_clock_units.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_completeness_sweep.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_constant_shadowing.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_cup_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_cup_cadence.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_cup_festival_eggs.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_cup_theater.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_dark_room_fx.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_data.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_data_facade.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_dead_gate.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_death.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_device_lines.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_digicore.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_digimemory.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_digimental_gates.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_distribution.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_divergence.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_dmx_level.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_dna_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_dna_charge.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_dna_slim.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_effects_integrity.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_egg_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_egg_dominance.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_egg_economy.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_egg_guide.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_egg_guide_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_egg_unlock.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_egg_unlock_math.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_encoding.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_energy_system.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_evolution.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_evolution_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_evolution_math.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_evolution_system.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_feed.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_feeding_math.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_festival_gifts.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_filth_sick_rate.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_food_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_fusion_mode_canon.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_fx.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_gift_birthday_math.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_hall.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_hardening_0712.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_help.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_hint_strips.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_holiday_decor.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_home_battle.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_honors.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_hud.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_humulos_eggs.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_hunger.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_ios_support.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_item_expansion.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_item_heal.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_itemfx.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_items_p5.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_items_p6.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_items_sweep.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_jogress.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_jogress_canon.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_jogress_math.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_jogress_wire.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_ko6_gate.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_ko6_reachable.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_line_anchoring.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_line_curation.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_lines.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_liveplay_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_lobby.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_lobby_admin.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_lobby_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_lobby_chat_polish.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_lobby_screens.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_menu_bounds.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_menu_runoffs.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_messages.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_mortality_math.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_msg_strip.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_nav_quit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_night_palette.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_note_marquee.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_options.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_orb_integrity.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_panel_smoke.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_performance.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_persistence.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_persistence_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_pet_effect.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_poop_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_poop_model.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_poop_placement.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_poop_report.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_pvp_duel.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_qol_polish.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_raid.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_rank_system.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_render_budgets.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_rival.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_road_presents.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_robustness.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_rooms.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_save_integrity.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_scene_actors.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_scene_picker.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_screen_sweep.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_sfx_scroll.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_shop_clone.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_shops_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_sickness_clone.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_silent_failures.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_sleep.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_sleep_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_sleep_system.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_sound.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_sound_ios.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_special_idles.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_stage_arrival.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_status_box_sweep.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_status_icons.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_sync.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_theme.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_theme_contrast.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_tier1_robustness.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_tier2_onboarding.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_tier3_moments.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_timing_honesty.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_tournament.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_town_cup.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_town_egg_market.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_town_shop_economy.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_training_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_training_clone.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_training_hp.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_training_system.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_ui_stats.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_update.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_update_install.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_verx.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_visual_audit.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_visual_polish.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_weight_system.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_whats_new.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_wild_memory.py +0 -0
- {tuipet-0.5.330 → tuipet-0.5.332}/tests/test_win_eggs.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tuipet
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.332
|
|
4
4
|
Summary: A terminal virtual pet (Digimon V-Pet style) rendered with halfblock sprites, built on data from the real devices.
|
|
5
5
|
Author-email: Joel Taylor <joeltaylor734@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -150,7 +150,7 @@ class TuiPetApp(ActionsMixin, App):
|
|
|
150
150
|
"""
|
|
151
151
|
# the release-news line (title-screen msg box, first launch per build) --
|
|
152
152
|
# UPDATE THIS WITH EVERY RELEASE that ships something player-visible
|
|
153
|
-
WHATS_NEW = ("
|
|
153
|
+
WHATS_NEW = ("THAT LITTLE SPRITE IN THE CORNER IS A FESTIVAL, NOT A STUCK PIXEL: on four days a year a decoration appears in your arena — the Crest of Courage on Odaiba Memorial Day, a present at Christmas, candy at Halloween, cake at New Year — and until now nothing on the home screen said so. The card names the day above your vitals whenever one is on, on the egg screen too. It was only ever labelled on the adventure card before.")
|
|
154
154
|
|
|
155
155
|
BINDINGS = [
|
|
156
156
|
# jogress is LOBBY-ONLY (fusion needs a real partner from the
|
|
@@ -679,8 +679,17 @@ LIGHTS_MISTAKE_POSTPONE = -60.0 # AfterMistakeMinutesPostponed: the NEXT
|
|
|
679
679
|
LIGHTS_MISTAKE_OBED = -1 # LightsOnMistakeObedienceChange (once per night)
|
|
680
680
|
HUNGER_MISTAKE_OBED = 1 # HungerMistakeObedienceChange (canon: +1!)
|
|
681
681
|
HUNGER_MISTAKE_OBED_GLUTTON = -1 # ...ChangeGlutton
|
|
682
|
-
LIGHTS_MISTAKE_SEC = 60.0 # MinutesToMistakeLights(60)
|
|
683
|
-
#
|
|
682
|
+
LIGHTS_MISTAKE_SEC = 60.0 # MinutesToMistakeLights(60): the FIRST lit mistake
|
|
683
|
+
# lands 60 game-min into the sleep, then every 120
|
|
684
|
+
# (LIGHTS_MISTAKE_POSTPONE). ⚠ THE OLD TAIL HERE
|
|
685
|
+
# CLAIMED "~6-min night -- one mistake/night" AND IT
|
|
686
|
+
# WAS WRONG BOTH WAYS: measured on a live Mega the
|
|
687
|
+
# night runs ~600 game-min, so a fully lit one books
|
|
688
|
+
# FIVE (canon's own ~8h night gives 4 -- _tick_asleep
|
|
689
|
+
# has always said so). The number is canon and stays;
|
|
690
|
+
# only this comment lied. Diagnosed 2026-07-31 when
|
|
691
|
+
# Joel asked what was eating his care mistakes: it was
|
|
692
|
+
# this, 5 of his 6 a day.
|
|
684
693
|
MORNING_MOOD_CHANCE = 5 # MorningMoodChance: 1/5 bad, 1/5 terrible-if-happy, 1/5 good
|
|
685
694
|
BAD_MORNING_MOOD = {"Happy": -150, "Neutral": -100, "Unhappy": -10, "Depressed": -10}
|
|
686
695
|
GOOD_MORNING_MOOD = {"Happy": 50, "Neutral": 100, "Unhappy": 150, "Depressed": 150}
|
|
@@ -128,15 +128,30 @@ class BodyMixin:
|
|
|
128
128
|
anyone else loses 50 -- then the counters tick (care-mistake audit
|
|
129
129
|
2026-07-05: the counters ticked silently).
|
|
130
130
|
|
|
131
|
+
⭐⭐THE THREE CALLS, AND ONLY THE THREE (2026-08-01, Joel: "canonize
|
|
132
|
+
all care mistakes"). ⛔DO NOT ADD A FOURTH CALLER TO THIS METHOD.
|
|
133
|
+
THE BANDAI DEVICE RECORD IS THE AUTHORITY on what a care mistake IS:
|
|
134
|
+
a MISSED CALL, and the device makes exactly three calls --
|
|
135
|
+
1. hunger empty (petbody, the hunger call)
|
|
136
|
+
2. strength empty (petbody, the effort call)
|
|
137
|
+
3. tired / wants sleep (petbody, the lights call)
|
|
138
|
+
The manual also names things that are explicitly NOT care mistakes:
|
|
139
|
+
overfeeding, injury, and waking a sleeper. Two impostors were cut on
|
|
140
|
+
that ruling -- the ignored TANTRUM (`_tick_mortality`; the device has
|
|
141
|
+
no scold mechanic at all, so ignoring one cannot cost a mistake) and
|
|
142
|
+
the CHEESEBURGER (`petcare._junk`; that is overfeeding, named in the
|
|
143
|
+
manual as not-a-mistake). Both keep their own penalties in tuipet's
|
|
144
|
+
own currencies -- obedience and weight.
|
|
145
|
+
FILTH books nothing either, and never did: `_open_scold` raises only
|
|
146
|
+
`scold_window`, never `discipline_call`, so the timeout cannot reach
|
|
147
|
+
it. Measured 2026-07-31: 4.2 game-days pegged at poop 4 with the
|
|
148
|
+
calls answered books ZERO.
|
|
149
|
+
|
|
131
150
|
⭐`reason` NAMES THE SLIP (bug report 2026-07-31, Joel: "mon is getting
|
|
132
|
-
a care mistake after 4 poops, not 1... correct?").
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
care mistake was SILENT: the counter moved on the card and nothing ever
|
|
137
|
-
said which of the four calls went unanswered -- for a Mega, where five
|
|
138
|
-
of them turn lethal. The app reads this on the tick edge and flashes
|
|
139
|
-
it (an unheard verdict is a silent failure)."""
|
|
151
|
+
a care mistake after 4 poops, not 1... correct?"). A care mistake was
|
|
152
|
+
SILENT: the counter moved on the card and nothing ever said which call
|
|
153
|
+
went unanswered -- on a Mega, where five turn lethal. The app reads
|
|
154
|
+
this on the tick edge and flashes it."""
|
|
140
155
|
self.care_mistakes += 1
|
|
141
156
|
self.mistake_reason = reason
|
|
142
157
|
self.mistake_day += 1 # MistakeIncMissedDayChange
|
|
@@ -676,23 +691,28 @@ class BodyMixin:
|
|
|
676
691
|
self._obed_t -= _lapse
|
|
677
692
|
self._set_obedience(self.obedience + OBEDIENCE_LAPSE_DEC * -1 # noqa: F405
|
|
678
693
|
+ OBEDIENCE_FILTH_SCALE * self.poop) # noqa: F405
|
|
679
|
-
# THE TANTRUM
|
|
680
|
-
#
|
|
681
|
-
#
|
|
682
|
-
#
|
|
683
|
-
#
|
|
684
|
-
#
|
|
685
|
-
#
|
|
694
|
+
# THE TANTRUM: an awake pet AT HOME acts up about once per 5400
|
|
695
|
+
# game-min (~90 REAL minutes of play); SCOLD inside the window pays
|
|
696
|
+
# obedience +25, IGNORING it past the window costs obedience -5.
|
|
697
|
+
# Never on the road, never asleep.
|
|
698
|
+
#
|
|
699
|
+
# ⭐IT IS NOT A CARE MISTAKE (2026-08-01, Joel: "not scolding an acting
|
|
700
|
+
# out mon is canonically a care mistake?" -> "canon is bandai"). THE
|
|
701
|
+
# BANDAI DEVICE RECORD IS THE AUTHORITY, and it is unambiguous: a care
|
|
702
|
+
# mistake is a MISSED CALL, and the device has exactly three calls --
|
|
703
|
+
# hunger empty, strength empty, and tired/wants-sleep (the lights).
|
|
704
|
+
# The manual carries no praise, no scold, no acting-up mechanic at all,
|
|
705
|
+
# so ignoring one cannot cost a mistake there. The line that stood
|
|
706
|
+
# here booked one anyway under a citation it never had.
|
|
707
|
+
# The TANTRUM ITSELF stays: it is tuipet's own system, so it pays in
|
|
708
|
+
# tuipet's own currency (obedience), and it no longer touches the
|
|
709
|
+
# Bandai-defined counter that gates evolution and kills at 20.
|
|
686
710
|
if (not self.asleep and not getattr(self, "away", False)
|
|
687
711
|
and self.stage not in ("Egg", "Fresh")):
|
|
688
712
|
if self.discipline_call:
|
|
689
713
|
if self.world_seconds > getattr(self, "scold_window", 0.0):
|
|
690
714
|
self.discipline_call = False
|
|
691
715
|
self.scold_window = 0.0
|
|
692
|
-
# through the front door: the bare += here skipped the
|
|
693
|
-
# mood sting + the birthday mistake_day tally every
|
|
694
|
-
# other mistake pays (incMistake; audit 2026-07-25)
|
|
695
|
-
self._inc_mistake("acting up, not scolded")
|
|
696
716
|
self._set_obedience(self.obedience - 5)
|
|
697
717
|
else:
|
|
698
718
|
# canon checkDisciplineCall: a check every DisciplineCallMin
|
|
@@ -798,12 +798,15 @@ class CareMixin:
|
|
|
798
798
|
return "...it was DELICIOUS. And fatal."
|
|
799
799
|
|
|
800
800
|
def _junk(self):
|
|
801
|
+
# ⭐NOT A CARE MISTAKE (2026-08-01, Joel: "canonize all care mistakes").
|
|
802
|
+
# THE BANDAI DEVICE RECORD IS THE AUTHORITY and it is explicit on this
|
|
803
|
+
# one: a care mistake is a MISSED CALL, and OVERFEEDING is called out
|
|
804
|
+
# by name as something that is NOT one. The burger is junk food -- it
|
|
805
|
+
# fills the belly and it makes the pet fat, which is the whole penalty.
|
|
806
|
+
# It has no business touching the counter that gates evolution and
|
|
807
|
+
# kills at 20.
|
|
801
808
|
self.hunger = FULL_HUNGER
|
|
802
809
|
self._set_weight(self.weight + 4)
|
|
803
|
-
# the real mistake pipeline: the bare counter bumped care_mistakes
|
|
804
|
-
# without the mood sting or mistake_day, so the burger slip was
|
|
805
|
-
# invisible to the birthday judgment
|
|
806
|
-
self._inc_mistake("that cheeseburger")
|
|
807
810
|
return "Delicious. Regrettable."
|
|
808
811
|
|
|
809
812
|
def _premium_meat(self):
|
|
@@ -75,7 +75,7 @@ _AUTHORED = {
|
|
|
75
75
|
"vegetable": ("Vegetable", "f:3", 150, "Feed", "hunger +1 · weight -1", "crunchy diet fare"),
|
|
76
76
|
"tuna": ("Tuna", "f:14", 400, "Feed", "hunger +2 · energy +1", "a hearty catch"),
|
|
77
77
|
"cake": ("Cake", "f:6", 300, "Feed", "hunger +1 · energy +2 · weight +2", "a celebration slice"),
|
|
78
|
-
"cheese_burger": ("Cheese burger", "f:57", 50, "Feed", "fills belly · weight +4
|
|
78
|
+
"cheese_burger": ("Cheese burger", "f:57", 50, "Feed", "fills the belly · weight +4", "greasy, regrettable"),
|
|
79
79
|
"giga_meal": ("Giga Meal", "f:28", 800, "Feed", "fills belly · energy +4 · weight +6", "a feast fit for a Mega"),
|
|
80
80
|
"steak": ("Steak", "f:8", 2000, "Feed", "fills belly · 12h satiety", "the premium table"),
|
|
81
81
|
"poison_mushroom": ("Poison Mushroom", "f:13", 200, "Feed", "DO NOT FEED", "it does look delicious"),
|
|
@@ -249,7 +249,9 @@ _TOUCHES = {
|
|
|
249
249
|
"cupcake": ("hunger", "energy"),
|
|
250
250
|
"cookie": ("hunger", "energy"),
|
|
251
251
|
"candy": ("hunger", "energy"),
|
|
252
|
-
|
|
252
|
+
# (care_mistakes dropped 2026-08-01, "canonize all care mistakes": the
|
|
253
|
+
# Bandai record names OVERFEEDING as explicitly NOT a care mistake)
|
|
254
|
+
"cheese_burger": ("hunger", "weight"),
|
|
253
255
|
"giga_meal": ("hunger", "energy", "weight"),
|
|
254
256
|
"steak": ("hunger", "full_until"),
|
|
255
257
|
"poison_mushroom": ("dead",), # _die(): the one lethal entry
|
|
@@ -198,6 +198,21 @@ def adventure_line(pet):
|
|
|
198
198
|
return f"Quest {count}[dim]▸ {_frontier_name(pet, 16 - len(count))}[/]"
|
|
199
199
|
|
|
200
200
|
|
|
201
|
+
def festival_line():
|
|
202
|
+
"""TODAY's festival, named -- or None on an ordinary day.
|
|
203
|
+
|
|
204
|
+
⭐Bug report 2026-08-01 (Joel): "whyyyy is there a sun pixel sprite stuck
|
|
205
|
+
on the lcd screen?" It was the Crest of Courage, the Odaiba Memorial Day
|
|
206
|
+
decoration (arenafx.HOLIDAY_DECOR) -- a prop that quietly appears in the
|
|
207
|
+
arena's corner on four dates a year. The festival was named NOWHERE on
|
|
208
|
+
the home screen, so the only thing a player could conclude was that a
|
|
209
|
+
pixel had got stuck. A prop with no label is a glitch; a prop with a
|
|
210
|
+
label is a holiday. (The road card has always named it -- statusbox.road
|
|
211
|
+
-- and that is the only place it was ever said.)"""
|
|
212
|
+
from . import tournament
|
|
213
|
+
return tournament.holiday()
|
|
214
|
+
|
|
215
|
+
|
|
201
216
|
def home_lines(pet):
|
|
202
217
|
from . import lines as _lines # DMX level: exp vs canon thresholds
|
|
203
218
|
T = theme
|
|
@@ -206,9 +221,11 @@ def home_lines(pet):
|
|
|
206
221
|
age = age_compact(pet.age_seconds)
|
|
207
222
|
xm = f" [b {T.ACCENT}]X[/]" if pet.x_antibody != "None" else ""
|
|
208
223
|
lvl = _lines._pet_level(pet)
|
|
224
|
+
fest = festival_line()
|
|
209
225
|
return [
|
|
210
226
|
f"[b]{pet.name[:22]}[/]{xm}",
|
|
211
227
|
f"[dim]{pet.stage}{(' · ' + pet.attribute) if pet.attribute else ''}[/]",
|
|
228
|
+
] + ([f"[{T.COIN}]★ {fest[:24]}[/]"] if fest else []) + [
|
|
212
229
|
DIV,
|
|
213
230
|
f"Hunger {hearts(pet.hunger)}",
|
|
214
231
|
f"Effort {hearts(pet.strength)}",
|
|
@@ -252,9 +269,14 @@ def home_lines(pet):
|
|
|
252
269
|
|
|
253
270
|
def egg_lines(pet):
|
|
254
271
|
mins, secs = divmod(int(pet.age_seconds), 60)
|
|
272
|
+
# the festival prop draws over an EGG's arena too (arenafx._effect_overlay
|
|
273
|
+
# blits it before the `pet.num == -1` return), so the egg card names the
|
|
274
|
+
# day for the same reason the home card does -- 12 rows, room to spare
|
|
275
|
+
fest = festival_line()
|
|
255
276
|
return [
|
|
256
277
|
"[b]Digitama[/] [dim]· egg[/]",
|
|
257
278
|
DIV,
|
|
279
|
+
] + ([f"[{theme.COIN}]★ {fest[:24]}[/]", ""] if fest else []) + [
|
|
258
280
|
"[dim]a new life is warming[/]",
|
|
259
281
|
"",
|
|
260
282
|
"Destined to hatch",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tuipet
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.332
|
|
4
4
|
Summary: A terminal virtual pet (Digimon V-Pet style) rendered with halfblock sprites, built on data from the real devices.
|
|
5
5
|
Author-email: Joel Taylor <joeltaylor734@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -48,15 +48,20 @@ def test_the_tantrum_never_fires_on_the_road_or_asleep(monkeypatch):
|
|
|
48
48
|
assert not road.discipline_call
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
def
|
|
51
|
+
def test_an_ignored_tantrum_costs_manners_not_a_care_mistake(monkeypatch):
|
|
52
|
+
"""⭐2026-08-01, Joel: "canonize all care mistakes". The BANDAI device
|
|
53
|
+
record defines a care mistake as a MISSED CALL and the device makes three
|
|
54
|
+
-- hunger, strength, tired/sleep. It has no scold mechanic at all, so
|
|
55
|
+
ignoring a tantrum cannot be one. The tantrum is TUIPET'S OWN system, so
|
|
56
|
+
it keeps paying in tuipet's own currency: obedience."""
|
|
52
57
|
p = _pet(discipline_call=True)
|
|
53
58
|
p.scold_window = p.world_seconds - 1.0 # the window has passed
|
|
54
59
|
monkeypatch.setattr(petbody.random, "random", lambda: 0.99)
|
|
55
60
|
m0, o0 = p.care_mistakes, p.obedience
|
|
56
61
|
p.tick(1.0)
|
|
57
|
-
assert not p.discipline_call
|
|
58
|
-
assert p.
|
|
59
|
-
assert p.
|
|
62
|
+
assert not p.discipline_call # the window closed
|
|
63
|
+
assert p.obedience == o0 - 5 # manners, yes
|
|
64
|
+
assert p.care_mistakes == m0 # the counter, NO
|
|
60
65
|
|
|
61
66
|
|
|
62
67
|
def test_scold_answers_the_call_and_wrong_scold_lands_nothing():
|
|
@@ -359,15 +364,14 @@ def test_a_new_pet_is_not_born_disobedient():
|
|
|
359
364
|
assert p.manners_refusal("feed") is False
|
|
360
365
|
|
|
361
366
|
|
|
362
|
-
def
|
|
363
|
-
"""
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
pays the tally; this one didn't (claims audit 2026-07-25)."""
|
|
367
|
+
def test_an_ignored_tantrum_touches_neither_counter(monkeypatch):
|
|
368
|
+
"""It used to route through incMistake, which pays BOTH the care-mistake
|
|
369
|
+
counter and the birthday mistake_day tally. Canonized 2026-08-01: the
|
|
370
|
+
device has no scold mechanic, so an ignored tantrum feeds neither."""
|
|
367
371
|
p = _pet(discipline_call=True)
|
|
368
372
|
p.scold_window = p.world_seconds - 1.0
|
|
369
373
|
monkeypatch.setattr(petbody.random, "random", lambda: 0.99)
|
|
370
374
|
d0, m0 = p.mistake_day, p.care_mistakes
|
|
371
375
|
p.tick(1.0)
|
|
372
|
-
assert p.care_mistakes == m0
|
|
373
|
-
assert p.mistake_day == d0
|
|
376
|
+
assert p.care_mistakes == m0
|
|
377
|
+
assert p.mistake_day == d0 # nor the birthday tally
|
|
@@ -147,11 +147,16 @@ def test_filth_never_books_a_care_mistake():
|
|
|
147
147
|
f"filth booked {p.care_mistakes} care mistakes -- it must book none")
|
|
148
148
|
|
|
149
149
|
|
|
150
|
-
def
|
|
151
|
-
"""
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
def test_a_care_mistake_is_a_missed_call_and_nothing_else():
|
|
151
|
+
"""⭐THE THREE CALLS (2026-08-01, Joel: "canonize all care mistakes").
|
|
152
|
+
The BANDAI device record defines a care mistake as a MISSED CALL, and the
|
|
153
|
+
device makes exactly three: hunger empty, strength empty, tired/wants
|
|
154
|
+
sleep. It also names what is NOT one -- overfeeding, injury, waking a
|
|
155
|
+
sleeper. Two impostors were cut on that ruling: the ignored TANTRUM (the
|
|
156
|
+
device has no scold mechanic at all) and the CHEESEBURGER (overfeeding).
|
|
157
|
+
⛔THIS PIN IS A FENCE: a fourth `_inc_mistake` caller fails it.
|
|
158
|
+
|
|
159
|
+
Each source also NAMES itself, and each fits the 40-cell HUD line."""
|
|
155
160
|
import inspect
|
|
156
161
|
import os
|
|
157
162
|
import re
|
|
@@ -164,7 +169,10 @@ def test_every_care_mistake_names_itself():
|
|
|
164
169
|
from tuipet.pet import Pet
|
|
165
170
|
src = inspect.getsource(petbody) + inspect.getsource(petcare)
|
|
166
171
|
calls = re.findall(r"_inc_mistake\((.*?)\)", src)
|
|
167
|
-
|
|
172
|
+
reasons = [a.strip('"') for a in calls if not a.startswith("self")]
|
|
173
|
+
assert sorted(reasons) == sorted([
|
|
174
|
+
"left hungry too long", "empty effort gauge", "the lights left on",
|
|
175
|
+
]), f"the three calls, and only the three -- got {reasons}"
|
|
168
176
|
for arg in calls:
|
|
169
177
|
if arg.startswith("self"): # the definition's own signature
|
|
170
178
|
continue
|
|
@@ -194,3 +202,78 @@ def test_the_first_slip_of_a_session_still_flashes():
|
|
|
194
202
|
assert src.index("cm0 = self.pet.care_mistakes") < src.index("self.pet.tick(1.0)")
|
|
195
203
|
assert src.index("self.pet.tick(1.0)") < src.index("if p.care_mistakes > cm0")
|
|
196
204
|
assert not re.search(r"_cm_seen\s*=", src) # no lazy latch, ever again
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def test_a_lit_night_is_the_dominant_mistake_source():
|
|
208
|
+
"""Diagnosed 2026-07-31 (Joel: "ok so what's actually causing my care
|
|
209
|
+
mistakes then"). His cloud save carried lights=True; measured on his own
|
|
210
|
+
numbers, one game-day costs FIVE lights mistakes and one ignored tantrum,
|
|
211
|
+
against ONE with the lights off. Canon: the first lit mistake lands 60
|
|
212
|
+
game-min in, then every 120 (LIGHTS_MISTAKE_POSTPONE = -60). The number
|
|
213
|
+
is canon and stays -- this pins the SHAPE so the constants block's old
|
|
214
|
+
"one mistake/night" claim can never quietly come back."""
|
|
215
|
+
import os
|
|
216
|
+
import random
|
|
217
|
+
import tempfile
|
|
218
|
+
os.environ.setdefault("TUIPET_SAVE_DIR", tempfile.mkdtemp())
|
|
219
|
+
from tuipet.pet import Pet
|
|
220
|
+
|
|
221
|
+
def day(lights):
|
|
222
|
+
random.seed(12)
|
|
223
|
+
p = Pet(num=399, name="Omni", stage="Mega", attribute="Vaccine",
|
|
224
|
+
obedience=111)
|
|
225
|
+
p.hunger, p.strength = 4, 4
|
|
226
|
+
p.sleep_limit, p.world_seconds = 840.0, 12607.0
|
|
227
|
+
p.max_energy = 38
|
|
228
|
+
p._set_energy(26)
|
|
229
|
+
p.lights = lights
|
|
230
|
+
seen = []
|
|
231
|
+
real = type(p)._inc_mistake
|
|
232
|
+
type(p)._inc_mistake = lambda s, reason="": (seen.append(reason),
|
|
233
|
+
real(s, reason))[1]
|
|
234
|
+
try:
|
|
235
|
+
for _ in range(1440):
|
|
236
|
+
p.tick(1.0)
|
|
237
|
+
finally:
|
|
238
|
+
type(p)._inc_mistake = real
|
|
239
|
+
return seen
|
|
240
|
+
|
|
241
|
+
lit = day(True)
|
|
242
|
+
dark = day(False)
|
|
243
|
+
assert lit.count("the lights left on") >= 4, lit
|
|
244
|
+
assert "the lights left on" not in dark, dark
|
|
245
|
+
assert len(lit) > len(dark), (lit, dark)
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def test_the_two_cut_impostors_keep_their_own_penalties():
|
|
249
|
+
"""Canonizing the counter must not quietly delete the SYSTEMS. An ignored
|
|
250
|
+
tantrum still costs obedience (tuipet's own currency), and the burger
|
|
251
|
+
still packs on weight -- they just no longer touch the Bandai-defined
|
|
252
|
+
counter that gates evolution and kills at 20."""
|
|
253
|
+
import os
|
|
254
|
+
import tempfile
|
|
255
|
+
os.environ.setdefault("TUIPET_SAVE_DIR", tempfile.mkdtemp())
|
|
256
|
+
from tuipet.pet import Pet
|
|
257
|
+
|
|
258
|
+
# the ignored tantrum: obedience yes, care mistake no
|
|
259
|
+
p = Pet(num=399, name="Omni", stage="Mega", attribute="Vaccine",
|
|
260
|
+
obedience=111)
|
|
261
|
+
p.hunger, p.strength = 4, 4
|
|
262
|
+
p.world_seconds = 12607.0
|
|
263
|
+
p.discipline_call = True
|
|
264
|
+
p.scold_window = p.world_seconds - 1.0 # already expired
|
|
265
|
+
obed0, cm0 = p.obedience, p.care_mistakes
|
|
266
|
+
p._tick_mortality(1.0)
|
|
267
|
+
assert p.discipline_call is False # the window closed
|
|
268
|
+
assert p.obedience == obed0 - 5 # it still stings manners
|
|
269
|
+
assert p.care_mistakes == cm0 # ...and NOT the counter
|
|
270
|
+
|
|
271
|
+
# the cheeseburger: weight yes, care mistake no
|
|
272
|
+
q = Pet(num=399, name="Omni", stage="Mega", attribute="Vaccine")
|
|
273
|
+
q.world_seconds = 600.0
|
|
274
|
+
q.hunger = 1
|
|
275
|
+
q.add_item("cheese_burger")
|
|
276
|
+
w0, cm0 = q.weight, q.care_mistakes
|
|
277
|
+
q.use_item("cheese_burger")
|
|
278
|
+
assert q.weight > w0 and q.hunger == 4 # fat and fed
|
|
279
|
+
assert q.care_mistakes == cm0 # overfeeding is not a slip
|
|
@@ -37,8 +37,13 @@ def test_food_dials_match_their_blurbs():
|
|
|
37
37
|
|
|
38
38
|
def test_the_big_meals_and_the_mushroom():
|
|
39
39
|
p = _pet()
|
|
40
|
+
w0 = p.weight
|
|
40
41
|
_use(p, "cheese_burger")
|
|
41
|
-
|
|
42
|
+
# "fills the belly · weight +4" -- and NOT a care mistake since the
|
|
43
|
+
# canonization (2026-08-01): the Bandai record names overfeeding as
|
|
44
|
+
# explicitly not one, so the blurb no longer promises it either
|
|
45
|
+
assert p.hunger == FULL_HUNGER and p.weight - w0 == 4
|
|
46
|
+
assert p.care_mistakes == 0
|
|
42
47
|
p = _pet()
|
|
43
48
|
w0, e0 = p.weight, p.energy
|
|
44
49
|
_use(p, "giga_meal")
|
|
@@ -192,3 +192,41 @@ def test_battle_card_wraps_the_result_note():
|
|
|
192
192
|
statusbox.battle(app)
|
|
193
193
|
_fits(app.stats_w, "battle")
|
|
194
194
|
_no_words_lost(app.stats_w, "battle", _M.hud_note)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def test_the_home_and_egg_cards_name_the_festival():
|
|
198
|
+
"""⭐Bug report 2026-08-01 (Joel): "whyyyy is there a sun pixel sprite
|
|
199
|
+
stuck on the lcd screen?" It was the Crest of Courage — the Odaiba
|
|
200
|
+
Memorial Day decoration (arenafx.HOLIDAY_DECOR), a prop that appears in
|
|
201
|
+
the arena corner on four dates a year and was named NOWHERE on the home
|
|
202
|
+
screen. A prop with no label reads as a stuck pixel.
|
|
203
|
+
|
|
204
|
+
⛔THIS ALSO FENCES THE ROW BUDGET. The festival banner is the 16th row of
|
|
205
|
+
a 16-row card, so a future 17th row would break the home card on four days
|
|
206
|
+
a year and pass every other day. Forcing a festival here turns that
|
|
207
|
+
landmine into an always-on gate."""
|
|
208
|
+
import datetime
|
|
209
|
+
from tuipet import statusbox, tournament
|
|
210
|
+
from tuipet.arenafx import HOLIDAY_DECOR
|
|
211
|
+
fake = _FakeStats()
|
|
212
|
+
p = _pet()
|
|
213
|
+
e = Pet(num=-1, name="", stage="Egg")
|
|
214
|
+
e.world_seconds = 600.0
|
|
215
|
+
for name, (m, d) in {"Odaiba Memorial Day": (8, 1),
|
|
216
|
+
"Christmas Festival": (12, 25),
|
|
217
|
+
"Halloween Festival": (10, 31),
|
|
218
|
+
"New Year Festival": (1, 1)}.items():
|
|
219
|
+
tournament._today = (lambda mm, dd: (lambda: datetime.date(2026, mm, dd)))(m, d)
|
|
220
|
+
assert name in HOLIDAY_DECOR, f"{name} draws a prop with no decor entry"
|
|
221
|
+
for lines, tag in ((statusbox.home_lines(p), "home"),
|
|
222
|
+
(statusbox.egg_lines(e), "egg")):
|
|
223
|
+
fake.txt = "\n".join(lines)
|
|
224
|
+
_fits(fake, f"{tag} on {name}")
|
|
225
|
+
assert name in fake.txt, f"{tag} card never names {name}"
|
|
226
|
+
# ...and an ordinary day carries no banner at all
|
|
227
|
+
tournament._today = lambda: datetime.date(2026, 6, 17)
|
|
228
|
+
fake.txt = "\n".join(statusbox.home_lines(p))
|
|
229
|
+
_fits(fake, "home, ordinary day")
|
|
230
|
+
# (not a bare "★" check -- the Battle row wears ★{trophies} every day)
|
|
231
|
+
for name in ("Odaiba", "Christmas", "Halloween", "New Year"):
|
|
232
|
+
assert name not in fake.txt
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|