fixed # 修复作物资源位置不对的历史遗留BUG

add # 新增作物会生虫的逻辑
This commit is contained in:
2026-10-19 17:25:25 +08:00
parent 24ae6102c0
commit 15646525cb
80 changed files with 793505 additions and 226 deletions
+67
View File
@@ -0,0 +1,67 @@
"""离线虫害时间结算;只投影状态,不读写数据库或使用随机数。"""
from dataclasses import replace
from .domain import Plot, integer
def season_duration(plot: Plot) -> int:
return (plot.plant.growth_seconds if plot.harvest_count == 0
else plot.plant.regrowth_seconds)
def spawn_interval(plot: Plot) -> int:
return max(3600, (season_duration(plot) + 3) // 4)
def start_growth(plot: Plot, now: int) -> Plot:
duration = season_duration(plot)
return advance_plot(replace(
plot, mature_at=integer(now + duration), pest_count=0, pest_spawned=0,
growth_remaining=integer(duration * 100), growth_updated_at=now,
next_pest_at=integer(now + spawn_interval(plot)), maturity_pests=0,
), now)
def _advance(remaining, cursor, pests, spawned, next_at, interval, now):
while remaining:
rate = 100 - pests * 5
finish = integer(cursor + (remaining + rate - 1) // rate)
if finish <= now and (next_at is None or finish <= next_at):
return 0, finish, pests, spawned, None, finish
end = min(now, next_at) if next_at is not None else now
remaining -= (end - cursor) * rate
cursor = end
if next_at is None or cursor < next_at:
break
pests += 1
spawned += 1
next_at = integer(next_at + interval) if spawned < 3 else None
if cursor == now:
break
return remaining, cursor, pests, spawned, next_at, None
def advance_plot(plot: Plot, now: int) -> Plot:
integer(now)
if (plot.plant is None or plot.withered
or plot.growth_remaining is None or not plot.growth_remaining):
return plot
if now < plot.growth_updated_at:
return plot
interval = spawn_interval(plot)
remaining, cursor, pests, spawned, next_at, finish = _advance(
plot.growth_remaining, plot.growth_updated_at, plot.pest_count,
plot.pest_spawned, plot.next_pest_at, interval, now,
)
if finish is None:
finish = _advance(
remaining, cursor, pests, spawned, next_at, interval,
integer(cursor + (remaining + 84) // 85),
)[-1]
return replace(
plot, mature_at=finish, pest_count=pests, pest_spawned=spawned,
growth_remaining=remaining, growth_updated_at=cursor,
next_pest_at=next_at,
maturity_pests=pests if remaining == 0 else 0,
)