tuipet 0.5.332__tar.gz → 0.5.334__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.
Files changed (356) hide show
  1. {tuipet-0.5.332/src/tuipet.egg-info → tuipet-0.5.334}/PKG-INFO +1 -1
  2. {tuipet-0.5.332 → tuipet-0.5.334}/pyproject.toml +1 -1
  3. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/app.py +1 -1
  4. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/arena.py +4 -6
  5. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/arenafx.py +39 -4
  6. {tuipet-0.5.332 → tuipet-0.5.334/src/tuipet.egg-info}/PKG-INFO +1 -1
  7. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_scene_actors.py +78 -0
  8. {tuipet-0.5.332 → tuipet-0.5.334}/LICENSE +0 -0
  9. {tuipet-0.5.332 → tuipet-0.5.334}/README.md +0 -0
  10. {tuipet-0.5.332 → tuipet-0.5.334}/setup.cfg +0 -0
  11. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/__init__.py +0 -0
  12. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/__main__.py +0 -0
  13. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/accountscreen.py +0 -0
  14. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/adventure.py +0 -0
  15. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/adventurescreen.py +0 -0
  16. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/albumscreen.py +0 -0
  17. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/anim.py +0 -0
  18. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/appactions.py +0 -0
  19. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/appboot.py +0 -0
  20. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/assistscreen.py +0 -0
  21. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/backgrounds.py +0 -0
  22. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/backgroundscreen.py +0 -0
  23. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/battle.py +0 -0
  24. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/battlescreen.py +0 -0
  25. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/bugscreen.py +0 -0
  26. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/cloudsync.py +0 -0
  27. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/attr_icons.json +0 -0
  28. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/backgrounds.json.gz +0 -0
  29. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/battle_fx.json.gz +0 -0
  30. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/battle_overlays.json +0 -0
  31. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/careEffect.csv +0 -0
  32. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/deviceAttacks.csv +0 -0
  33. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/digicoreMenuConfig.csv +0 -0
  34. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/digimon.csv +0 -0
  35. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/dropRate.csv +0 -0
  36. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/effects.json.gz +0 -0
  37. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/eggUnlock.csv +0 -0
  38. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/eggs.json.gz +0 -0
  39. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/elementAffinity.csv +0 -0
  40. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/enemies.csv +0 -0
  41. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/evolutions.csv +0 -0
  42. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/fieldAffinity.csv +0 -0
  43. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/foods.csv +0 -0
  44. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/hp_dummies.json +0 -0
  45. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/icons.json.gz +0 -0
  46. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/items.csv +0 -0
  47. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/jogress_overlays.json +0 -0
  48. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/lines.csv +0 -0
  49. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/lootTable.csv +0 -0
  50. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/maps.csv +0 -0
  51. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/orbs.json.gz +0 -0
  52. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/shopConsumable.csv +0 -0
  53. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/alarm.wav +0 -0
  54. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/angry.wav +0 -0
  55. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/attack.wav +0 -0
  56. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/attackHit.wav +0 -0
  57. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/battle.wav +0 -0
  58. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/boot.wav +0 -0
  59. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/cancel.wav +0 -0
  60. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/champion.wav +0 -0
  61. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/click.wav +0 -0
  62. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/compatible.wav +0 -0
  63. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/confirm.wav +0 -0
  64. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/death.wav +0 -0
  65. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/eat.wav +0 -0
  66. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/error.wav +0 -0
  67. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/evolve.wav +0 -0
  68. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/happy.wav +0 -0
  69. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/hatch.wav +0 -0
  70. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/jogress.wav +0 -0
  71. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/largePoop.wav +0 -0
  72. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/lastBite.wav +0 -0
  73. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/lose.wav +0 -0
  74. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/menu.wav +0 -0
  75. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/mischief.wav +0 -0
  76. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/poop.wav +0 -0
  77. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/refuse.wav +0 -0
  78. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/reward.wav +0 -0
  79. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/scroll.wav +0 -0
  80. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/select.wav +0 -0
  81. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/smallPoop.wav +0 -0
  82. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/startBattle.wav +0 -0
  83. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/strongAttack.wav +0 -0
  84. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/strongHit.wav +0 -0
  85. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/trainhit.wav +0 -0
  86. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/wash.wav +0 -0
  87. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sounds/win.wav +0 -0
  88. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/sprites.json.gz +0 -0
  89. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/titles.csv +0 -0
  90. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/tournies.csv +0 -0
  91. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/towns.csv +0 -0
  92. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/train_wall.json +0 -0
  93. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/vitems.json +0 -0
  94. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data/zones.csv +0 -0
  95. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data.py +0 -0
  96. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data_core.py +0 -0
  97. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data_meta.py +0 -0
  98. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data_shop.py +0 -0
  99. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/data_world.py +0 -0
  100. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/deathscreen.py +0 -0
  101. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/digicore.py +0 -0
  102. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/digicorescreen.py +0 -0
  103. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/disciplinescreen.py +0 -0
  104. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/dnascreen.py +0 -0
  105. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/egg.py +0 -0
  106. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/eggguidescreen.py +0 -0
  107. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/eggmigrate.py +0 -0
  108. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/eggselectscreen.py +0 -0
  109. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/evolution.py +0 -0
  110. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/feedscreen.py +0 -0
  111. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/grid.py +0 -0
  112. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/hallscreen.py +0 -0
  113. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/helpscreen.py +0 -0
  114. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/hostinfo.py +0 -0
  115. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/itemfx.py +0 -0
  116. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/jogress.py +0 -0
  117. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/jogressscreen.py +0 -0
  118. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/lines.py +0 -0
  119. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/lobbybout.py +0 -0
  120. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/lobbychat.py +0 -0
  121. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/lobbyscreen.py +0 -0
  122. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/menu.py +0 -0
  123. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/net.py +0 -0
  124. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/optionsscreen.py +0 -0
  125. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/persistence.py +0 -0
  126. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/persistio.py +0 -0
  127. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/pet.py +0 -0
  128. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/petbase.py +0 -0
  129. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/petbattle.py +0 -0
  130. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/petbody.py +0 -0
  131. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/petcare.py +0 -0
  132. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/petdna.py +0 -0
  133. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/placeholder.py +0 -0
  134. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/raidscreen.py +0 -0
  135. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/render.py +0 -0
  136. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/rival.py +0 -0
  137. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/shop.py +0 -0
  138. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/shopscreen.py +0 -0
  139. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/sound.py +0 -0
  140. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/statusbox.py +0 -0
  141. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/strikefx.py +0 -0
  142. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/theme.py +0 -0
  143. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/themescreen.py +0 -0
  144. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/titlescreen.py +0 -0
  145. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/tournament.py +0 -0
  146. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/tournamentscreen.py +0 -0
  147. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/towneggscreen.py +0 -0
  148. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/townscreen.py +0 -0
  149. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/training.py +0 -0
  150. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet/update.py +0 -0
  151. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet.egg-info/SOURCES.txt +0 -0
  152. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet.egg-info/dependency_links.txt +0 -0
  153. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet.egg-info/entry_points.txt +0 -0
  154. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet.egg-info/requires.txt +0 -0
  155. {tuipet-0.5.332 → tuipet-0.5.334}/src/tuipet.egg-info/top_level.txt +0 -0
  156. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_audit.py +0 -0
  157. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_boss.py +0 -0
  158. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_conditions.py +0 -0
  159. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_drain.py +0 -0
  160. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_encounters.py +0 -0
  161. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_finds.py +0 -0
  162. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_foundation.py +0 -0
  163. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_geography.py +0 -0
  164. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_hazards.py +0 -0
  165. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_holiday.py +0 -0
  166. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_march.py +0 -0
  167. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_placement.py +0 -0
  168. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_progression.py +0 -0
  169. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_replay.py +0 -0
  170. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_rewards.py +0 -0
  171. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_score.py +0 -0
  172. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_shop.py +0 -0
  173. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_streak.py +0 -0
  174. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_summary.py +0 -0
  175. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_towns.py +0 -0
  176. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_adventure_transport.py +0 -0
  177. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_album_completable.py +0 -0
  178. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_album_dex.py +0 -0
  179. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_album_screen.py +0 -0
  180. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_anim_canon.py +0 -0
  181. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_anim_hardening.py +0 -0
  182. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_anim_timing.py +0 -0
  183. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_announce.py +0 -0
  184. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_armor_canon.py +0 -0
  185. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_audit_fixes.py +0 -0
  186. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_auto_care.py +0 -0
  187. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_auto_update.py +0 -0
  188. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_away_flag.py +0 -0
  189. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_background_audit.py +0 -0
  190. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_backgrounds.py +0 -0
  191. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_battle_audit.py +0 -0
  192. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_battle_race.py +0 -0
  193. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_bedtime.py +0 -0
  194. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_birthday.py +0 -0
  195. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_body_math.py +0 -0
  196. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_body_tells.py +0 -0
  197. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_bugreport.py +0 -0
  198. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_call_cadence.py +0 -0
  199. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_canon_discipline.py +0 -0
  200. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_canon_injury.py +0 -0
  201. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_card_runoffs.py +0 -0
  202. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_care_asleep.py +0 -0
  203. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_care_audit.py +0 -0
  204. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_care_bonus.py +0 -0
  205. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_catalog_categories.py +0 -0
  206. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_catalog_record.py +0 -0
  207. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_catalog_touches.py +0 -0
  208. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_clock_units.py +0 -0
  209. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_completeness_sweep.py +0 -0
  210. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_constant_shadowing.py +0 -0
  211. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_cup_audit.py +0 -0
  212. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_cup_cadence.py +0 -0
  213. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_cup_festival_eggs.py +0 -0
  214. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_cup_theater.py +0 -0
  215. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_dark_room_fx.py +0 -0
  216. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_data.py +0 -0
  217. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_data_facade.py +0 -0
  218. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_dead_gate.py +0 -0
  219. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_death.py +0 -0
  220. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_device_lines.py +0 -0
  221. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_digicore.py +0 -0
  222. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_digimemory.py +0 -0
  223. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_digimental_gates.py +0 -0
  224. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_distribution.py +0 -0
  225. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_divergence.py +0 -0
  226. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_dmx_level.py +0 -0
  227. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_dna_audit.py +0 -0
  228. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_dna_charge.py +0 -0
  229. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_dna_slim.py +0 -0
  230. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_effects_integrity.py +0 -0
  231. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_egg_audit.py +0 -0
  232. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_egg_dominance.py +0 -0
  233. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_egg_economy.py +0 -0
  234. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_egg_guide.py +0 -0
  235. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_egg_guide_audit.py +0 -0
  236. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_egg_unlock.py +0 -0
  237. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_egg_unlock_math.py +0 -0
  238. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_encoding.py +0 -0
  239. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_energy_system.py +0 -0
  240. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_evolution.py +0 -0
  241. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_evolution_audit.py +0 -0
  242. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_evolution_math.py +0 -0
  243. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_evolution_system.py +0 -0
  244. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_feed.py +0 -0
  245. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_feeding_math.py +0 -0
  246. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_festival_gifts.py +0 -0
  247. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_filth_sick_rate.py +0 -0
  248. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_filth_system.py +0 -0
  249. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_food_audit.py +0 -0
  250. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_fusion_mode_canon.py +0 -0
  251. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_fx.py +0 -0
  252. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_gift_birthday_math.py +0 -0
  253. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_hall.py +0 -0
  254. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_hardening_0712.py +0 -0
  255. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_help.py +0 -0
  256. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_hint_strips.py +0 -0
  257. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_holiday_decor.py +0 -0
  258. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_home_battle.py +0 -0
  259. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_honors.py +0 -0
  260. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_hud.py +0 -0
  261. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_humulos_eggs.py +0 -0
  262. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_hunger.py +0 -0
  263. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_ios_support.py +0 -0
  264. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_item_expansion.py +0 -0
  265. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_item_heal.py +0 -0
  266. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_itemfx.py +0 -0
  267. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_items_p5.py +0 -0
  268. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_items_p6.py +0 -0
  269. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_items_sweep.py +0 -0
  270. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_jogress.py +0 -0
  271. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_jogress_canon.py +0 -0
  272. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_jogress_math.py +0 -0
  273. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_jogress_wire.py +0 -0
  274. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_ko6_gate.py +0 -0
  275. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_ko6_reachable.py +0 -0
  276. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_line_anchoring.py +0 -0
  277. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_line_curation.py +0 -0
  278. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_lines.py +0 -0
  279. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_liveplay_audit.py +0 -0
  280. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_lobby.py +0 -0
  281. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_lobby_admin.py +0 -0
  282. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_lobby_audit.py +0 -0
  283. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_lobby_chat_polish.py +0 -0
  284. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_lobby_screens.py +0 -0
  285. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_menu_bounds.py +0 -0
  286. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_menu_runoffs.py +0 -0
  287. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_messages.py +0 -0
  288. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_mortality_math.py +0 -0
  289. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_msg_strip.py +0 -0
  290. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_nav_quit.py +0 -0
  291. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_night_palette.py +0 -0
  292. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_note_marquee.py +0 -0
  293. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_options.py +0 -0
  294. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_orb_integrity.py +0 -0
  295. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_panel_smoke.py +0 -0
  296. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_performance.py +0 -0
  297. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_persistence.py +0 -0
  298. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_persistence_audit.py +0 -0
  299. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_pet_effect.py +0 -0
  300. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_poop_audit.py +0 -0
  301. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_poop_model.py +0 -0
  302. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_poop_placement.py +0 -0
  303. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_poop_report.py +0 -0
  304. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_pvp_duel.py +0 -0
  305. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_qol_polish.py +0 -0
  306. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_raid.py +0 -0
  307. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_rank_system.py +0 -0
  308. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_render_budgets.py +0 -0
  309. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_rival.py +0 -0
  310. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_road_presents.py +0 -0
  311. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_robustness.py +0 -0
  312. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_rooms.py +0 -0
  313. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_save_integrity.py +0 -0
  314. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_scene_picker.py +0 -0
  315. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_screen_sweep.py +0 -0
  316. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_sfx_scroll.py +0 -0
  317. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_shop_clone.py +0 -0
  318. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_shop_dossier_audit.py +0 -0
  319. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_shops_audit.py +0 -0
  320. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_sickness_clone.py +0 -0
  321. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_silent_failures.py +0 -0
  322. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_sleep.py +0 -0
  323. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_sleep_audit.py +0 -0
  324. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_sleep_system.py +0 -0
  325. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_sound.py +0 -0
  326. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_sound_ios.py +0 -0
  327. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_special_idles.py +0 -0
  328. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_stage_arrival.py +0 -0
  329. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_status_box.py +0 -0
  330. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_status_box_sweep.py +0 -0
  331. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_status_icons.py +0 -0
  332. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_sync.py +0 -0
  333. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_theme.py +0 -0
  334. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_theme_contrast.py +0 -0
  335. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_tier1_robustness.py +0 -0
  336. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_tier2_onboarding.py +0 -0
  337. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_tier3_moments.py +0 -0
  338. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_timing_honesty.py +0 -0
  339. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_tournament.py +0 -0
  340. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_town_cup.py +0 -0
  341. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_town_egg_market.py +0 -0
  342. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_town_shop_economy.py +0 -0
  343. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_training_audit.py +0 -0
  344. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_training_clone.py +0 -0
  345. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_training_hp.py +0 -0
  346. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_training_system.py +0 -0
  347. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_ui_stats.py +0 -0
  348. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_update.py +0 -0
  349. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_update_install.py +0 -0
  350. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_verx.py +0 -0
  351. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_visual_audit.py +0 -0
  352. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_visual_polish.py +0 -0
  353. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_weight_system.py +0 -0
  354. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_whats_new.py +0 -0
  355. {tuipet-0.5.332 → tuipet-0.5.334}/tests/test_wild_memory.py +0 -0
  356. {tuipet-0.5.332 → tuipet-0.5.334}/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.332
3
+ Version: 0.5.334
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "tuipet"
3
- version = "0.5.332"
3
+ version = "0.5.334"
4
4
  description = "A terminal virtual pet (Digimon V-Pet style) rendered with halfblock sprites, built on data from the real devices."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -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 = ("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.")
153
+ WHATS_NEW = ("THE FESTIVAL DECORATION REALLY STOPS CLIPPING NOW: the last fix taught the main painter to keep your mon out of the prop, but the yawn and poop-dance idles ran a second copy of that rule that never learned itso the mon still walked 9 pixels into the decoration whenever one of those poses played. There is one rule now, in one place, shared by every path that puts your mon on screen.")
154
154
 
155
155
  BINDINGS = [
156
156
  # jogress is LOBBY-ONLY (fusion needs a real partner from the
@@ -32,7 +32,7 @@ from .arenafx import ( # noqa: F401,E402
32
32
  PLAY_HOP, PLAY_HOP_H, PLAY_LEAD, POOP_PAD, POOP_W, SCREEN_COLS,
33
33
  SCREEN_ROWS, SICK_ZONE, SPRITE_W, _FxCtx, _WINDOW, _clip_win,
34
34
  _HIDDEN_STATUS_ICONS, _blit, _effect_overlay, _evol_strobe, _filth_pts,
35
- _filth_right, _sick_mark_up)
35
+ _filth_right, _holiday_right, _sick_mark_up, _zone_clamp)
36
36
 
37
37
 
38
38
  def hearts(n, total=4, color=None):
@@ -189,11 +189,9 @@ class Screen(FxMixin, Static):
189
189
  # 2026-07-11): the filth block is a hard left wall and the sick skull
190
190
  # a hard right one -- sleep/sick/startle bypass the roamer's bounds,
191
191
  # so the clamp here is what actually guarantees no overlap.
192
- base = PET_BASE_X
193
- lo = (_filth_right(pet.poop) if pet.poop else grid.X0) - base
194
- cap = ((grid.X1 - SICK_ZONE if _sick_mark_up(pet) else grid.X1)
195
- - SPRITE_W) - base
196
- xshift = min(max(xshift, lo), max(cap, lo)) # poop wins over the skull (it yields when crowded)
192
+ xshift = _zone_clamp(pet, xshift) # ONE source (arenafx._zone_clamp):
193
+ # filth + festival prop are left walls, the skull a right one, and
194
+ # poop wins over the skull (it yields when crowded)
197
195
  pts = _effect_overlay(pet, wf, SCREEN_COLS, SCREEN_ROWS * 2, tick=self.frame_i)
198
196
  # (THE AMBIENT SULK IS POSE-ONLY -- Joel 2026-07-28, final: "the
199
197
  # smoke is the reaction sprites... we already went over this." The
@@ -60,6 +60,44 @@ def _evol_strobe(c):
60
60
  if ev[y % mh][x % mw] == "1"]
61
61
 
62
62
 
63
+ def _holiday_right(today=None):
64
+ """Right edge x of TODAY's festival prop, or grid.X0 on an ordinary day.
65
+
66
+ ⭐The decor is a LEFT-WALL occupant exactly like the filth block (Joel
67
+ 2026-08-01: "my mon is clipping right into it. looks like shit"). The
68
+ exclusive-floor-zone law -- filth a hard left wall, the sick skull a hard
69
+ right one -- predates the prop by three months, and when the prop landed
70
+ (2026-07-24) it simply never joined the clamp. Its own comment claimed it
71
+ "sits where a resting pet does not reach", which is true of a CENTRED
72
+ sleeper and false of the roamer, which walks the whole band; and the
73
+ overlay is stamped AFTER the sprite, so the prop punched straight through
74
+ the mon. Four days a year, the arena looked broken."""
75
+ deco = _holiday_decor(today)
76
+ if not deco:
77
+ return grid.X0
78
+ return grid.X0 + max(len(r) for r in deco)
79
+
80
+
81
+ def _zone_clamp(pet, xshift):
82
+ """THE EXCLUSIVE FLOOR ZONES, IN ONE PLACE (Bandai-grammar sweep
83
+ 2026-07-11; unified 2026-08-01). The filth block and today's festival
84
+ prop are hard LEFT walls, the sick skull a hard RIGHT one; sleep / sick /
85
+ startle / the special idles all bypass the roamer's own bounds, so this
86
+ clamp is what actually guarantees no sprite draws on another.
87
+
88
+ ⚠IT WAS COPIED, AND THE COPY ROTTED. `Screen.paint` and the yawn /
89
+ poopdance branch of `_paint_fx` each carried their own transcription of
90
+ these three lines. v0.5.333 taught the prop to the first one and shipped;
91
+ Joel: "woooooow dude.... still clipping into it" -- the special idles were
92
+ still walking the mon straight through the crest, 9 px deep. One
93
+ function now, so a fourth caller cannot inherit a stale wall."""
94
+ lo = max(_filth_right(pet.poop) if pet.poop else grid.X0,
95
+ _holiday_right()) - PET_BASE_X
96
+ cap = ((grid.X1 - SICK_ZONE if _sick_mark_up(pet) else grid.X1)
97
+ - SPRITE_W) - PET_BASE_X
98
+ return min(max(xshift, lo), max(cap, lo))
99
+
100
+
63
101
  def _filth_right(count):
64
102
  """Right edge x of the filth block: fixed POOP_W columns like DVPet's 30px slots."""
65
103
  n = min(count or 0, POOP_MAX_PILES)
@@ -560,10 +598,7 @@ class FxMixin:
560
598
  # The pose sways around the roamer's spot, so it gets the same
561
599
  # zone clamp as paint() (sickness striking MID-yawn would
562
600
  # otherwise stand the skull on the pet for the pose's last beats).
563
- lo = (_filth_right(pet.poop) if pet.poop else grid.X0) - PET_BASE_X
564
- cap = ((grid.X1 - SICK_ZONE if _sick_mark_up(pet) else grid.X1)
565
- - SPRITE_W) - PET_BASE_X
566
- c.xshift = min(max(c.xshift, lo), max(cap, lo))
601
+ c.xshift = _zone_clamp(pet, c.xshift)
567
602
  c.overlay += _effect_overlay(pet, self.frame_i // 4, SCREEN_COLS, c.px_h,
568
603
  tick=self.frame_i)
569
604
  if dark: # the opaque cover: black over everything
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tuipet
3
- Version: 0.5.332
3
+ Version: 0.5.334
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
@@ -363,3 +363,81 @@ def test_the_ambient_sulk_is_pose_only():
363
363
  assert '_FX.get("unhappy")' not in src, "the idle painter still draws smoke"
364
364
  afx = open("src/tuipet/arenafx.py").read()
365
365
  assert afx.count('"unhappy"') >= 2, "the REACTION smoke must survive"
366
+
367
+
368
+ def test_no_sprite_draws_on_the_festival_prop(monkeypatch):
369
+ """⭐Bug report 2026-08-01 (Joel): "my mon is clipping right into it.
370
+ looks like shit."
371
+
372
+ The exclusive-floor-zone law (2026-07-11) gives the filth block a hard
373
+ LEFT wall and the sick skull a hard RIGHT one, and `test_no_sprite_ever_
374
+ draws_on_another` above sweeps it. The festival prop landed three months
375
+ later (2026-07-24) in the top-LEFT corner and never joined the clamp: its
376
+ own comment claimed it "sits where a resting pet does not reach", true of
377
+ a centred sleeper and false of the roamer, which walks the whole band --
378
+ and the overlay is stamped AFTER the sprite, so it punched through the
379
+ mon. Measured before the fix: 11 pixels of crest inside the creature.
380
+
381
+ ⚠The sweep above could never catch it, because it runs on whatever day
382
+ the suite runs and 361 of them have no prop -- and conftest's
383
+ `ordinary_day` now pins even that away. This one FORCES each festival."""
384
+ import datetime
385
+ from tuipet import arenafx, tournament
386
+ cap = _paint_capture(monkeypatch)
387
+ for m, d in ((8, 1), (12, 25), (10, 31), (1, 1)):
388
+ monkeypatch.setattr(tournament, "_today",
389
+ lambda mm=m, dd=d: datetime.date(2026, mm, dd))
390
+ assert arenafx._holiday_decor() is not None, (m, d)
391
+ assert arenafx._holiday_right() > grid.X0 # a real wall
392
+ for n, sizes in LOADS:
393
+ random.seed(7)
394
+ p = _pet(weather="Clear", poop=n, poop_sizes=list(sizes))
395
+ s = _screen()
396
+ for i in range(30):
397
+ s.advance(p)
398
+ s.paint(p)
399
+ pet_px = _sprite_px(cap["rows"], cap["xshift"], cap["mirror"])
400
+ hit = pet_px & set(cap["overlay"])
401
+ assert not hit, ((m, d), n, i, sorted(hit)[:6])
402
+
403
+
404
+ def test_the_special_idles_share_the_one_zone_clamp(monkeypatch):
405
+ """⭐Joel 2026-08-01: "woooooow dude.... still clipping into it."
406
+
407
+ v0.5.333 taught the festival prop to `Screen.paint`'s wall and shipped --
408
+ but the yawn / poopdance branch of `_paint_fx` carried its OWN
409
+ transcription of the same three lines, and that copy still knew only the
410
+ filth wall. The special idles walked the mon 9 px into the crest. There
411
+ is ONE `arenafx._zone_clamp` now; this sweeps the fx paths that the
412
+ scene-actor sweep above never drove."""
413
+ import datetime
414
+ from tuipet import arenafx, tournament
415
+ cap = _paint_capture(monkeypatch)
416
+ for m, d in ((8, 1), (12, 25), (10, 31), (1, 1)):
417
+ monkeypatch.setattr(tournament, "_today",
418
+ lambda mm=m, dd=d: datetime.date(2026, mm, dd))
419
+ for kind in ("yawn", "poopdance"):
420
+ for poop in (0, 2):
421
+ random.seed(3)
422
+ p = _pet(weather="Clear", poop=poop, poop_sizes=[2] * poop)
423
+ s = _screen()
424
+ s.start_fx(kind)
425
+ # walk the mon ACROSS the band while the pose plays: the bug
426
+ # only shows where the roamer stood, and the default anchor
427
+ # sits clear of the corner
428
+ for x0 in range(grid.X0 - 4, grid.X1 + 1):
429
+ s.roamer.x = float(x0)
430
+ if not s.fx:
431
+ s.start_fx(kind)
432
+ s.advance(p)
433
+ s.paint(p)
434
+ pet_px = _sprite_px(cap["rows"], cap["xshift"],
435
+ cap["mirror"])
436
+ hit = pet_px & set(cap["overlay"])
437
+ assert not hit, (kind, (m, d), poop, x0, sorted(hit)[:6])
438
+ # and the clamp is genuinely ONE function, not three transcriptions
439
+ import inspect
440
+ from tuipet import arena
441
+ for src in (inspect.getsource(arena.Screen.paint),
442
+ inspect.getsource(arenafx.FxMixin._paint_fx)):
443
+ assert "_filth_right(" not in src, "a hand-rolled wall crept back in"
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