新增菜园陷阱
This commit is contained in:
@@ -18,7 +18,9 @@ from .garden_models import (
|
||||
GARDEN_CROPS,
|
||||
GARDEN_FRUITS,
|
||||
GARDEN_MISC_ITEMS,
|
||||
GARDEN_TRAPS_DICT,
|
||||
GardenCropDefinition,
|
||||
GardenTrapDefinition,
|
||||
get_garden_db_models,
|
||||
)
|
||||
|
||||
@@ -248,12 +250,134 @@ class GardenService:
|
||||
# endregion
|
||||
|
||||
# region Steal
|
||||
def _is_theft_banned(self, user_id: int) -> Tuple[bool, Optional[str]]:
|
||||
"""检查用户是否被禁止偷盗
|
||||
|
||||
Returns:
|
||||
(是否被禁止, 如果被禁止则返回解封时间字符串,否则为None)
|
||||
"""
|
||||
cursor = self._db.conn.cursor()
|
||||
cursor.execute(
|
||||
"SELECT banned_until FROM garden_theft_ban WHERE user_id = ?",
|
||||
(user_id,),
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
if not row:
|
||||
return False, None
|
||||
|
||||
banned_until_str = row["banned_until"]
|
||||
banned_until = _parse_local_iso(banned_until_str)
|
||||
now = _local_now()
|
||||
|
||||
if banned_until > now:
|
||||
return True, banned_until_str
|
||||
else:
|
||||
# 已过期,删除记录
|
||||
cursor.execute("DELETE FROM garden_theft_ban WHERE user_id = ?", (user_id,))
|
||||
self._db.conn.commit()
|
||||
return False, None
|
||||
|
||||
def _ban_theft(self, user_id: int, ban_hours: int) -> str:
|
||||
"""禁止用户偷盗一定时间
|
||||
|
||||
Returns:
|
||||
解封时间字符串
|
||||
"""
|
||||
banned_until = _local_now() + timedelta(hours=ban_hours)
|
||||
banned_until_str = banned_until.isoformat()
|
||||
|
||||
cursor = self._db.conn.cursor()
|
||||
cursor.execute(
|
||||
"""
|
||||
INSERT INTO garden_theft_ban (user_id, banned_until)
|
||||
VALUES (?, ?)
|
||||
ON CONFLICT(user_id) DO UPDATE SET banned_until = excluded.banned_until
|
||||
""",
|
||||
(user_id, banned_until_str),
|
||||
)
|
||||
self._db.conn.commit()
|
||||
return banned_until_str
|
||||
|
||||
def _check_trap(self, plot: Dict[str, object], thief_id: int) -> Optional[Dict[str, object]]:
|
||||
"""检查并触发陷阱
|
||||
|
||||
Returns:
|
||||
如果触发陷阱,返回陷阱信息字典;否则返回None
|
||||
"""
|
||||
trap_item_id = plot.get("trap_item_id")
|
||||
if not trap_item_id:
|
||||
return None
|
||||
|
||||
# 检查陷阱耐久度
|
||||
trap_durability = int(plot.get("trap_durability", 0))
|
||||
if trap_durability <= 0:
|
||||
return None
|
||||
|
||||
trap = GARDEN_TRAPS_DICT.get(trap_item_id)
|
||||
if not trap:
|
||||
return None
|
||||
|
||||
# 检查触发概率
|
||||
if random.random() > trap.trigger_rate:
|
||||
return None
|
||||
|
||||
# 触发陷阱:设置禁令
|
||||
banned_until_str = self._ban_theft(thief_id, trap.ban_hours)
|
||||
|
||||
# 减少耐久度
|
||||
new_durability = trap_durability - 1
|
||||
user_id = int(plot["user_id"])
|
||||
plot_index = int(plot["plot_index"])
|
||||
|
||||
cursor = self._db.conn.cursor()
|
||||
if new_durability <= 0:
|
||||
# 耐久度归零,移除陷阱
|
||||
cursor.execute(
|
||||
"""
|
||||
UPDATE garden_plots SET trap_item_id = NULL, trap_config = NULL, trap_durability = 0
|
||||
WHERE user_id = ? AND plot_index = ?
|
||||
""",
|
||||
(user_id, plot_index),
|
||||
)
|
||||
else:
|
||||
# 更新耐久度
|
||||
cursor.execute(
|
||||
"""
|
||||
UPDATE garden_plots SET trap_durability = ?
|
||||
WHERE user_id = ? AND plot_index = ?
|
||||
""",
|
||||
(new_durability, user_id, plot_index),
|
||||
)
|
||||
self._db.conn.commit()
|
||||
|
||||
return {
|
||||
"trap": trap,
|
||||
"fine_points": trap.fine_points,
|
||||
"ban_hours": trap.ban_hours,
|
||||
"banned_until": banned_until_str,
|
||||
"durability": new_durability,
|
||||
"durability_exhausted": new_durability <= 0,
|
||||
"trigger_message": trap.trigger_message.format(
|
||||
fine=trap.fine_points,
|
||||
hours=trap.ban_hours,
|
||||
),
|
||||
}
|
||||
|
||||
def steal(self, *, thief_id: int, owner_id: int, plot_index: int) -> Dict[str, object]:
|
||||
plot = self.get_plot(owner_id, plot_index)
|
||||
if not plot:
|
||||
raise ValueError("目标地块不存在")
|
||||
if int(plot["is_mature"]) != 1:
|
||||
raise ValueError("目标作物尚未成熟")
|
||||
|
||||
# 检查是否被禁止偷盗
|
||||
is_banned, banned_until_str = self._is_theft_banned(thief_id)
|
||||
if is_banned:
|
||||
banned_until = _parse_local_iso(banned_until_str)
|
||||
now = _local_now()
|
||||
remaining_hours = (banned_until - now).total_seconds() / 3600
|
||||
raise ValueError(f"你已被禁止偷盗,解封时间:{self.format_display_time(banned_until_str)}(剩余约{int(remaining_hours)}小时)")
|
||||
|
||||
crop = GARDEN_CROPS.get(plot["seed_id"])
|
||||
if not crop:
|
||||
raise ValueError("未知作物")
|
||||
@@ -264,6 +388,10 @@ class GardenService:
|
||||
theft_users = set(json.loads(plot["theft_users"]))
|
||||
if thief_id in theft_users:
|
||||
raise ValueError("你已经偷取过该作物")
|
||||
|
||||
# 检查陷阱(在偷盗之前检查)
|
||||
trap_result = self._check_trap(plot, thief_id)
|
||||
|
||||
theft_users.add(thief_id)
|
||||
remaining -= 1
|
||||
cursor = self._db.conn.cursor()
|
||||
@@ -280,12 +408,61 @@ class GardenService:
|
||||
),
|
||||
)
|
||||
self._db.conn.commit()
|
||||
return {
|
||||
|
||||
result = {
|
||||
"crop": crop,
|
||||
"stolen_quantity": 1,
|
||||
"remaining": remaining,
|
||||
"chat_id": plot["chat_id"],
|
||||
"trap_result": trap_result,
|
||||
}
|
||||
return result
|
||||
|
||||
# endregion
|
||||
|
||||
# region Trap
|
||||
def place_trap(self, *, user_id: int, plot_index: int, trap_item_id: str) -> None:
|
||||
"""在地块上放置陷阱"""
|
||||
plot = self.get_plot(user_id, plot_index)
|
||||
if not plot:
|
||||
raise ValueError("目标地块不存在")
|
||||
|
||||
trap = GARDEN_TRAPS_DICT.get(trap_item_id)
|
||||
if not trap:
|
||||
raise ValueError("未知陷阱物品")
|
||||
|
||||
# 构建陷阱配置(JSON格式)
|
||||
trap_config = json.dumps({
|
||||
"item_id": trap.item_id,
|
||||
"display_name": trap.display_name,
|
||||
"tier": trap.tier,
|
||||
})
|
||||
|
||||
cursor = self._db.conn.cursor()
|
||||
cursor.execute(
|
||||
"""
|
||||
UPDATE garden_plots SET trap_item_id = ?, trap_config = ?, trap_durability = ?
|
||||
WHERE user_id = ? AND plot_index = ?
|
||||
""",
|
||||
(trap_item_id, trap_config, trap.durability, user_id, plot_index),
|
||||
)
|
||||
self._db.conn.commit()
|
||||
|
||||
def remove_trap(self, *, user_id: int, plot_index: int) -> None:
|
||||
"""移除地块上的陷阱"""
|
||||
plot = self.get_plot(user_id, plot_index)
|
||||
if not plot:
|
||||
raise ValueError("目标地块不存在")
|
||||
|
||||
cursor = self._db.conn.cursor()
|
||||
cursor.execute(
|
||||
"""
|
||||
UPDATE garden_plots SET trap_item_id = NULL, trap_config = NULL, trap_durability = 0
|
||||
WHERE user_id = ? AND plot_index = ?
|
||||
""",
|
||||
(user_id, plot_index),
|
||||
)
|
||||
self._db.conn.commit()
|
||||
|
||||
# endregion
|
||||
|
||||
|
||||
Reference in New Issue
Block a user