Code Farm: per-plot auto-replant pause and crop-lock check; community sync and node work

Continuous Delivery could never be turned off once a crop was planted. Add a
one-shot per-plot "stop after harvest" flag (POST /game/plot/stop, Devii tool
game_plot_stop, game_plots.stop_after_harvest), cleared by the next plant,
autoreplant claim or Refactor. Autoreplant now also respects crop locks through
the shared _crop_lock predicate. Plan and measurements in happyplanting.md.

Also includes the pending community sync, node network and related work in the
tree; the full suite passed (4999) with all of it.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-17 02:23:43 +02:00
co-authored by Claude Sonnet 5.5
parent ce899fc5e1
commit 02ab747cd0
203 changed files with 11624 additions and 301 deletions
+108
View File
@@ -1178,3 +1178,111 @@ def test_claim_grant_partial_treasury(local_db):
result = store.claim_grant(user)
assert result["amount"] == 300
assert store.treasury_balance() == 0
# --- per-plot auto-replant pause ---------------------------------------------------------
def _plot(user, slot=0):
return store.get_plots(store.get_farm(user["uid"])["uid"])[slot]
def test_autoreplant_replants_by_default(local_db):
user = _reset("unit_a")
_set(user, mastery_autoreplant=1)
store.plant(user, 0, "shell")
_warp(user)
store.harvest(user, 0)
plot = _plot(user)
assert plot["crop_key"] == "shell"
assert not plot.get("stop_after_harvest")
def test_plot_stop_skips_one_replant_then_plant_resets_flag(local_db):
user = _reset("unit_a")
_set(user, mastery_autoreplant=1)
store.plant(user, 0, "shell")
assert store.set_plot_stop(user, 0, True)["stop"] is True
_warp(user)
store.harvest(user, 0)
assert not _plot(user).get("crop_key")
store.plant(user, 0, "python")
plot = _plot(user)
assert plot["crop_key"] == "python"
assert not plot.get("stop_after_harvest")
_warp(user)
store.harvest(user, 0)
assert _plot(user)["crop_key"] == "python"
def test_plot_stop_can_be_cancelled(local_db):
user = _reset("unit_a")
_set(user, mastery_autoreplant=1)
store.plant(user, 0, "shell")
store.set_plot_stop(user, 0, True)
store.set_plot_stop(user, 0, False)
_warp(user)
store.harvest(user, 0)
assert _plot(user)["crop_key"] == "shell"
def test_plot_stop_requires_continuous_delivery(local_db):
user = _reset("unit_a")
store.plant(user, 0, "shell")
with pytest.raises(GameError):
store.set_plot_stop(user, 0, True)
def test_plot_stop_rejects_empty_plot(local_db):
user = _reset("unit_a")
_set(user, mastery_autoreplant=1)
with pytest.raises(GameError):
store.set_plot_stop(user, 0, True)
def test_plot_stop_honoured_by_auto_harvest(local_db):
user = _reset("unit_a")
_set(user, mastery_autoreplant=1, legacy_autoharvest=1)
store.plant(user, 0, "shell")
store.plant(user, 1, "shell")
store.set_plot_stop(user, 0, True)
_warp(user)
store.serialize_farm(store.get_farm(user["uid"]), viewer=user, owner=user)
assert not _plot(user, 0).get("crop_key")
assert _plot(user, 1)["crop_key"] == "shell"
def test_autoreplant_skips_locked_crop(local_db):
user = _reset("unit_a")
_set(user, mastery_autoreplant=1)
store.plant(user, 0, "shell")
_warp(user)
original = economy.crop_lock_reason
economy.crop_lock_reason = lambda *args, **kwargs: ("level", "is locked")
try:
store.harvest(user, 0)
finally:
economy.crop_lock_reason = original
assert not _plot(user).get("crop_key")
def test_plot_stop_serialized_for_owner_only(local_db):
owner = _reset("unit_a")
visitor = _reset("unit_b")
_set(owner, mastery_autoreplant=1)
store.plant(owner, 0, "shell")
store.set_plot_stop(owner, 0, True)
farm = store.get_farm(owner["uid"])
own_view = store.serialize_farm(farm, viewer=owner, owner=owner)["plots"][0]
assert own_view["can_stop_replant"] and own_view["stop_after_harvest"]
other_view = store.serialize_farm(farm, viewer=visitor, owner=owner)["plots"][0]
assert not other_view["can_stop_replant"] and not other_view["stop_after_harvest"]
def test_prestige_resets_plot_stop(local_db):
user = _reset("unit_a", coins=10**9)
_set(user, mastery_autoreplant=1, xp=10**7, level=economy.PRESTIGE_MIN_LEVEL)
store.plant(user, 0, "shell")
store.set_plot_stop(user, 0, True)
store.prestige(user)
assert not _plot(user).get("stop_after_harvest")