稍微优化了一下签到系统和抽奖系统

This commit is contained in:
2025-07-12 21:08:36 +08:00
parent aa8707878e
commit 09b1f19a8f
10 changed files with 791 additions and 1184 deletions

View File

@@ -1984,7 +1984,7 @@ func _handle_daily_check_in_response(response: Dictionary) -> void:
player_bag_panel.update_player_bag_ui() player_bag_panel.update_player_bag_ui()
# 向签到面板传递响应 # 向签到面板传递响应
daily_check_in_panel.handle_check_in_response(response) daily_check_in_panel.handle_daily_check_in_response(response)
# 显示签到结果通知 # 显示签到结果通知
var success = response.get("success", false) var success = response.get("success", false)

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=67 format=3 uid="uid://dgh61dttaas5a"] [gd_scene load_steps=72 format=3 uid="uid://dgh61dttaas5a"]
[ext_resource type="Script" uid="uid://2pt11sfcaxf7" path="res://MainGame.gd" id="1_v3yaj"] [ext_resource type="Script" uid="uid://2pt11sfcaxf7" path="res://MainGame.gd" id="1_v3yaj"]
[ext_resource type="Texture2D" uid="uid://du2pyiojliasy" path="res://assets/游戏UI/经验球.webp" id="2_6jgly"] [ext_resource type="Texture2D" uid="uid://du2pyiojliasy" path="res://assets/游戏UI/经验球.webp" id="2_6jgly"]
@@ -136,6 +136,34 @@ scale_min = 0.5
scale_max = 0.5 scale_max = 0.5
turbulence_enabled = true turbulence_enabled = true
[sub_resource type="Curve" id="Curve_4ka7t"]
_data = [Vector2(0, 0.951807), 0.0, 0.0, 0, 0, Vector2(0.0153846, 1), 0.0, 0.0, 0, 0, Vector2(0.0461538, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 4
[sub_resource type="CurveTexture" id="CurveTexture_nf3jg"]
curve = SubResource("Curve_4ka7t")
[sub_resource type="Gradient" id="Gradient_adtqp"]
offsets = PackedFloat32Array(0.52, 0.697143)
colors = PackedColorArray(1, 1, 1, 0.352941, 1, 1, 1, 1)
[sub_resource type="GradientTexture1D" id="GradientTexture1D_5dq3w"]
gradient = SubResource("Gradient_adtqp")
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_jiccn"]
lifetime_randomness = 0.07
particle_flag_disable_z = true
emission_shape = 3
emission_box_extents = Vector3(1000, 1, 1)
gravity = Vector3(46, 80, 0)
scale_min = 0.2
scale_max = 0.3
color_initial_ramp = SubResource("GradientTexture1D_5dq3w")
alpha_curve = SubResource("CurveTexture_nf3jg")
turbulence_enabled = true
turbulence_influence_min = 0.02
turbulence_influence_max = 0.08
[node name="main" type="Node"] [node name="main" type="Node"]
script = ExtResource("1_v3yaj") script = ExtResource("1_v3yaj")
@@ -4249,15 +4277,6 @@ vertical_alignment = 1
[node name="WeatherSystem" type="Node2D" parent="."] [node name="WeatherSystem" type="Node2D" parent="."]
[node name="Snow" type="GPUParticles2D" parent="WeatherSystem"]
position = Vector2(-170, -272)
amount = 16
sub_emitter = NodePath(".")
texture = ExtResource("53_4ka7t")
lifetime = 15.0
randomness = 0.5
process_material = SubResource("ParticleProcessMaterial_nf3jg")
[node name="Rain" type="GPUParticles2D" parent="WeatherSystem"] [node name="Rain" type="GPUParticles2D" parent="WeatherSystem"]
visible = false visible = false
position = Vector2(-170, -272) position = Vector2(-170, -272)
@@ -4268,6 +4287,18 @@ lifetime = 15.0
randomness = 0.5 randomness = 0.5
process_material = SubResource("ParticleProcessMaterial_nf3jg") process_material = SubResource("ParticleProcessMaterial_nf3jg")
[node name="Snow" type="GPUParticles2D" parent="WeatherSystem"]
z_index = 10
position = Vector2(249, -262)
amount = 300
texture = ExtResource("53_4ka7t")
lifetime = 15.0
preprocess = 30.0
visibility_rect = Rect2(-900, 0, 2000, 2000)
trail_sections = 2
trail_section_subdivisions = 1
process_material = SubResource("ParticleProcessMaterial_jiccn")
[node name="DayNightSystem" type="Node2D" parent="."] [node name="DayNightSystem" type="Node2D" parent="."]
[connection signal="pressed" from="UI/GUI/GameInfoHBox3/WatchBroadcast" to="." method="_on_watch_broadcast_button_pressed"] [connection signal="pressed" from="UI/GUI/GameInfoHBox3/WatchBroadcast" to="." method="_on_watch_broadcast_button_pressed"]

37
Scene/Particle/snow.tscn Normal file
View File

@@ -0,0 +1,37 @@
[gd_scene load_steps=7 format=3 uid="uid://b5j2tonaoiku5"]
[ext_resource type="Texture2D" uid="uid://dk4yl4ghmxaa2" path="res://assets/天气系统图片/雪花.webp" id="1_nqr5d"]
[sub_resource type="Curve" id="Curve_4ka7t"]
_data = [Vector2(0, 0.951807), 0.0, 0.0, 0, 0, Vector2(0.0153846, 1), 0.0, 0.0, 0, 0, Vector2(0.0461538, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 4
[sub_resource type="CurveTexture" id="CurveTexture_nf3jg"]
curve = SubResource("Curve_4ka7t")
[sub_resource type="Gradient" id="Gradient_adtqp"]
offsets = PackedFloat32Array(0.52, 0.697143)
colors = PackedColorArray(1, 1, 1, 0.352941, 1, 1, 1, 1)
[sub_resource type="GradientTexture1D" id="GradientTexture1D_5dq3w"]
gradient = SubResource("Gradient_adtqp")
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_jiccn"]
particle_flag_disable_z = true
emission_shape = 3
emission_box_extents = Vector3(1000, 1, 1)
gravity = Vector3(45, 98, 0)
scale_min = 0.4
scale_max = 0.8
color_initial_ramp = SubResource("GradientTexture1D_5dq3w")
alpha_curve = SubResource("CurveTexture_nf3jg")
turbulence_enabled = true
turbulence_influence_min = 0.02
turbulence_influence_max = 0.08
[node name="Snow" type="GPUParticles2D"]
amount = 200
texture = ExtResource("1_nqr5d")
lifetime = 10.0
preprocess = 30.0
process_material = SubResource("ParticleProcessMaterial_jiccn")

View File

@@ -1,136 +1,31 @@
extends Panel extends Panel
class_name DailyCheckInPanel class_name DailyCheckInPanel
## 每日签到系统 - 后端对接版本 signal check_in_completed(rewards: Dictionary)
## 功能:与服务器对接的签到系统,支持实时数据同步 signal check_in_failed(error_message: String)
## 奖励平衡性已根据 crop_data.json 调整
# =============================================================================
# 信号定义 - 用于与后端系统通信
# =============================================================================
signal check_in_completed(rewards: Dictionary) # 签到完成信号
signal reward_claimed(reward_type: String, amount: int) # 奖励领取信号
signal check_in_data_loaded(data: Dictionary) # 签到数据加载完成信号
signal check_in_failed(error_message: String) # 签到失败信号
# =============================================================================
# 节点引用
# =============================================================================
@onready var daily_check_in_history: RichTextLabel = $Scroll/DailyCheckInHistory @onready var daily_check_in_history: RichTextLabel = $Scroll/DailyCheckInHistory
@onready var daily_check_in_reward: RichTextLabel = $DailyCheckInReward @onready var daily_check_in_reward: RichTextLabel = $DailyCheckInReward
@onready var daily_check_in_button: Button = $DailyCheckInButton @onready var daily_check_in_button: Button = $DailyCheckInButton
@onready var main_game = get_node("/root/main")
@onready var tcp_network_manager_panel: Panel = $'../TCPNetworkManagerPanel'
# ============================================================================= var check_in_history: Dictionary = {}
# 数据存储
# =============================================================================
var check_in_data: Dictionary = {}
var today_date: String
var consecutive_days: int = 0 var consecutive_days: int = 0
var has_checked_in_today: bool = false var has_checked_in_today: bool = false
# 网络管理器引用
@onready var main_game = get_node("/root/main")
@onready var lucky_draw_panel: LuckyDrawPanel = $'../LuckyDrawPanel'
@onready var daily_check_in_panel: DailyCheckInPanel = $'.'
@onready var tcp_network_manager_panel: Panel = $'../TCPNetworkManagerPanel'
@onready var item_store_panel: Panel = $'../ItemStorePanel'
@onready var item_bag_panel: Panel = $'../ItemBagPanel'
@onready var player_bag_panel: Panel = $'../PlayerBagPanel'
@onready var crop_warehouse_panel: Panel = $'../CropWarehousePanel'
@onready var crop_store_panel: Panel = $'../CropStorePanel'
@onready var player_ranking_panel: Panel = $'../PlayerRankingPanel'
@onready var login_panel: PanelContainer = $'../LoginPanel'
# =============================================================================
# 奖励配置系统 - 根据 crop_data.json 平衡调整
# =============================================================================
var reward_configs: Dictionary = {
"coins": {
"min": 200,
"max": 500,
"name": "钱币",
"color": "#FFD700",
"icon": "💰"
},
"exp": {
"min": 50,
"max": 120,
"name": "经验",
"color": "#00BFFF",
"icon": ""
},
# 种子配置根据 crop_data.json 的作物等级和价值设定
"seeds": {
"普通": [
{"name": "小麦", "color": "#F4A460", "icon": "🌱", "rarity_color": "#FFFFFF"},
{"name": "胡萝卜", "color": "#FFA500", "icon": "🌱", "rarity_color": "#FFFFFF"},
{"name": "土豆", "color": "#D2691E", "icon": "🌱", "rarity_color": "#FFFFFF"},
{"name": "稻谷", "color": "#DAA520", "icon": "🌱", "rarity_color": "#FFFFFF"}
],
"优良": [
{"name": "玉米", "color": "#FFD700", "icon": "🌱", "rarity_color": "#00FF00"},
{"name": "番茄", "color": "#FF6347", "icon": "🌱", "rarity_color": "#00FF00"},
{"name": "洋葱", "color": "#DDA0DD", "icon": "🌱", "rarity_color": "#00FF00"},
{"name": "大豆", "color": "#8FBC8F", "icon": "🌱", "rarity_color": "#00FF00"},
{"name": "豌豆", "color": "#90EE90", "icon": "🌱", "rarity_color": "#00FF00"},
{"name": "黄瓜", "color": "#32CD32", "icon": "🌱", "rarity_color": "#00FF00"},
{"name": "大白菜", "color": "#F0FFF0", "icon": "🌱", "rarity_color": "#00FF00"}
],
"稀有": [
{"name": "草莓", "color": "#FF69B4", "icon": "🌱", "rarity_color": "#0080FF"},
{"name": "花椰菜", "color": "#F5F5DC", "icon": "🌱", "rarity_color": "#0080FF"},
{"name": "柿子", "color": "#FF4500", "icon": "🌱", "rarity_color": "#0080FF"},
{"name": "蓝莓", "color": "#4169E1", "icon": "🌱", "rarity_color": "#0080FF"},
{"name": "树莓", "color": "#DC143C", "icon": "🌱", "rarity_color": "#0080FF"}
],
"史诗": [
{"name": "葡萄", "color": "#9370DB", "icon": "🌱", "rarity_color": "#8A2BE2"},
{"name": "南瓜", "color": "#FF8C00", "icon": "🌱", "rarity_color": "#8A2BE2"},
{"name": "芦笋", "color": "#9ACD32", "icon": "🌱", "rarity_color": "#8A2BE2"},
{"name": "茄子", "color": "#9400D3", "icon": "🌱", "rarity_color": "#8A2BE2"},
{"name": "向日葵", "color": "#FFD700", "icon": "🌱", "rarity_color": "#8A2BE2"},
{"name": "蕨菜", "color": "#228B22", "icon": "🌱", "rarity_color": "#8A2BE2"}
],
"传奇": [
{"name": "西瓜", "color": "#FF69B4", "icon": "🌱", "rarity_color": "#FF8C00"},
{"name": "甘蔗", "color": "#DDA0DD", "icon": "🌱", "rarity_color": "#FF8C00"},
{"name": "香草", "color": "#98FB98", "icon": "🌱", "rarity_color": "#FF8C00"},
{"name": "甜菜", "color": "#DC143C", "icon": "🌱", "rarity_color": "#FF8C00"},
{"name": "人参", "color": "#DAA520", "icon": "🌱", "rarity_color": "#FF8C00"},
{"name": "富贵竹", "color": "#32CD32", "icon": "🌱", "rarity_color": "#FF8C00"},
{"name": "芦荟", "color": "#9ACD32", "icon": "🌱", "rarity_color": "#FF8C00"},
{"name": "哈密瓜", "color": "#FFB6C1", "icon": "🌱", "rarity_color": "#FF8C00"}
]
}
}
# =============================================================================
# 系统初始化
# =============================================================================
func _ready() -> void: func _ready() -> void:
visibility_changed.connect(_on_visibility_changed)
_initialize_system() _initialize_system()
func _initialize_system() -> void: func _initialize_system() -> void:
"""初始化签到系统"""
daily_check_in_reward.hide() daily_check_in_reward.hide()
today_date = Time.get_date_string_from_system()
_update_display() _update_display()
_check_daily_status() _check_daily_status()
# 从服务器加载签到数据
if tcp_network_manager_panel and tcp_network_manager_panel.is_connected_to_server(): if tcp_network_manager_panel and tcp_network_manager_panel.is_connected_to_server():
tcp_network_manager_panel.sendGetCheckInData() tcp_network_manager_panel.sendGetCheckInData()
# =============================================================================
# 网络后端交互方法
# =============================================================================
## 处理服务器签到响应
func handle_daily_check_in_response(response: Dictionary) -> void: func handle_daily_check_in_response(response: Dictionary) -> void:
var success = response.get("success", false) var success = response.get("success", false)
var message = response.get("message", "") var message = response.get("message", "")
@@ -140,71 +35,39 @@ func handle_daily_check_in_response(response: Dictionary) -> void:
consecutive_days = response.get("consecutive_days", 0) consecutive_days = response.get("consecutive_days", 0)
has_checked_in_today = true has_checked_in_today = true
# 显示奖励
_show_reward_animation(rewards) _show_reward_animation(rewards)
# 更新按钮状态
_set_button_state(false, "已签到", Color(0.7, 0.7, 0.7, 1)) _set_button_state(false, "已签到", Color(0.7, 0.7, 0.7, 1))
# 发送完成信号
check_in_completed.emit(rewards) check_in_completed.emit(rewards)
# 发送奖励信号
for reward_type in rewards.keys():
if reward_type == "seeds":
for seed_reward in rewards.seeds:
reward_claimed.emit("seed_" + seed_reward.name, seed_reward.quantity)
elif reward_type in ["coins", "exp", "bonus_coins", "bonus_exp"]:
reward_claimed.emit(reward_type, rewards[reward_type])
Toast.show(message, Color.GREEN) Toast.show(message, Color.GREEN)
print("签到成功: ", message)
else: else:
has_checked_in_today = response.get("has_checked_in", false) has_checked_in_today = response.get("has_checked_in", false)
_set_button_state(false, "已签到", Color(0.7, 0.7, 0.7, 1)) if has_checked_in_today else _set_button_state(true, "签到", Color(1, 1, 0.52549, 1)) _set_button_state(false, "已签到", Color(0.7, 0.7, 0.7, 1)) if has_checked_in_today else _set_button_state(true, "签到", Color(1, 1, 0.52549, 1))
check_in_failed.emit(message) check_in_failed.emit(message)
Toast.show(message, Color.RED) Toast.show(message, Color.RED)
print("签到失败: ", message)
## 处理服务器签到数据响应
func handle_check_in_data_response(response: Dictionary) -> void: func handle_check_in_data_response(response: Dictionary) -> void:
var success = response.get("success", false) var success = response.get("success", false)
if success: if success:
check_in_data = response.get("check_in_data", {}) check_in_history = response.get("check_in_data", {})
consecutive_days = response.get("consecutive_days", 0) consecutive_days = response.get("consecutive_days", 0)
has_checked_in_today = response.get("has_checked_in_today", false) has_checked_in_today = response.get("has_checked_in_today", false)
today_date = response.get("current_date", Time.get_date_string_from_system())
# 更新显示
_update_display() _update_display()
_check_daily_status() _check_daily_status()
# 发送数据加载完成信号
check_in_data_loaded.emit(check_in_data)
print("签到数据加载成功,连续签到:", consecutive_days, "")
else:
print("加载签到数据失败")
# =============================================================================
# 核心业务逻辑
# =============================================================================
## 检查今日签到状态
func _check_daily_status() -> void: func _check_daily_status() -> void:
if has_checked_in_today: if has_checked_in_today:
_set_button_state(false, "已签到", Color(0.7, 0.7, 0.7, 1)) _set_button_state(false, "已签到", Color(0.7, 0.7, 0.7, 1))
else: else:
_set_button_state(true, "签到", Color(1, 1, 0.52549, 1)) _set_button_state(true, "签到", Color(1, 1, 0.52549, 1))
## 设置按钮状态
func _set_button_state(enabled: bool, text: String, color: Color) -> void: func _set_button_state(enabled: bool, text: String, color: Color) -> void:
daily_check_in_button.disabled = not enabled daily_check_in_button.disabled = not enabled
daily_check_in_button.text = text daily_check_in_button.text = text
daily_check_in_button.modulate = color daily_check_in_button.modulate = color
## 执行签到
func execute_check_in() -> void: func execute_check_in() -> void:
if has_checked_in_today: if has_checked_in_today:
Toast.show("今日已签到,请明日再来", Color.ORANGE) Toast.show("今日已签到,请明日再来", Color.ORANGE)
@@ -214,41 +77,30 @@ func execute_check_in() -> void:
Toast.show("未连接到服务器,无法签到", Color.RED) Toast.show("未连接到服务器,无法签到", Color.RED)
return return
# 发送签到请求到服务器
tcp_network_manager_panel.sendDailyCheckIn() tcp_network_manager_panel.sendDailyCheckIn()
daily_check_in_button.disabled = true daily_check_in_button.disabled = true
daily_check_in_button.text = "签到中..." daily_check_in_button.text = "签到中..."
# 3秒后重新启用按钮防止网络超时
await get_tree().create_timer(3.0).timeout await get_tree().create_timer(3.0).timeout
if daily_check_in_button.disabled and daily_check_in_button.text == "签到中...": if daily_check_in_button.disabled and daily_check_in_button.text == "签到中...":
daily_check_in_button.disabled = false daily_check_in_button.disabled = false
daily_check_in_button.text = "签到" daily_check_in_button.text = "签到"
## 显示奖励动画
func _show_reward_animation(rewards: Dictionary) -> void: func _show_reward_animation(rewards: Dictionary) -> void:
daily_check_in_reward.text = _format_reward_text(rewards) daily_check_in_reward.text = _format_reward_text(rewards)
daily_check_in_reward.show() daily_check_in_reward.show()
# 创建动画效果
var tween = create_tween() var tween = create_tween()
tween.parallel().tween_method(_animate_reward_display, 0.0, 1.0, 0.5) tween.parallel().tween_method(_animate_reward_display, 0.0, 1.0, 0.5)
## 奖励显示动画
func _animate_reward_display(progress: float) -> void: func _animate_reward_display(progress: float) -> void:
daily_check_in_reward.modulate.a = progress daily_check_in_reward.modulate.a = progress
var scale = 0.8 + (0.2 * progress) var scale = 0.8 + (0.2 * progress)
daily_check_in_reward.scale = Vector2(scale, scale) daily_check_in_reward.scale = Vector2(scale, scale)
# =============================================================================
# UI显示格式化
# =============================================================================
## 格式化奖励显示文本
func _format_reward_text(rewards: Dictionary) -> String: func _format_reward_text(rewards: Dictionary) -> String:
var text = "" var text = ""
# 显示连续签到信息
text += "[center][color=#FF69B4]🔥 连续签到第%d天 🔥[/color][/center]\n" % consecutive_days text += "[center][color=#FF69B4]🔥 连续签到第%d天 🔥[/color][/center]\n" % consecutive_days
if consecutive_days > 1: if consecutive_days > 1:
var multiplier = 1.0 + (consecutive_days - 1) * 0.1 var multiplier = 1.0 + (consecutive_days - 1) * 0.1
@@ -257,58 +109,32 @@ func _format_reward_text(rewards: Dictionary) -> String:
else: else:
text += "\n" text += "\n"
# 基础奖励
if rewards.has("coins"): if rewards.has("coins"):
text += "[color=%s]%s +%d %s[/color]\n" % [ text += "[color=#FFD700]💰 +%d 金币[/color]\n" % rewards.coins
reward_configs.coins.color,
reward_configs.coins.icon,
rewards.coins,
reward_configs.coins.name
]
if rewards.has("exp"): if rewards.has("exp"):
text += "[color=%s]%s +%d %s[/color]\n" % [ text += "[color=#00BFFF]⭐ +%d 经验[/color]\n" % rewards.exp
reward_configs.exp.color,
reward_configs.exp.icon,
rewards.exp,
reward_configs.exp.name
]
# 种子奖励
if rewards.has("seeds") and rewards.seeds.size() > 0: if rewards.has("seeds") and rewards.seeds.size() > 0:
for seed_reward in rewards.seeds: for seed_reward in rewards.seeds:
var seed_name = seed_reward.name var seed_name = seed_reward.name
var quantity = seed_reward.quantity var quantity = seed_reward.quantity
var quality = seed_reward.quality var quality = seed_reward.quality
var rarity_color = _get_rarity_color(quality)
# 从配置中找到对应的种子信息 text += "[color=%s]🌱 %s x%d[/color] [color=%s](%s)[/color]\n" % [
var seed_info = _get_seed_info(seed_name, quality) rarity_color, seed_name, quantity, rarity_color, quality
if seed_info:
text += "[color=%s]%s[/color] [color=%s]%s[/color] x%d [color=%s](%s)[/color]\n" % [
seed_info.color, seed_info.icon, seed_info.color, seed_name, quantity, seed_info.rarity_color, quality
] ]
# 连续签到额外奖励
if rewards.has("bonus_coins"): if rewards.has("bonus_coins"):
text += "\n[color=#FFD700]🎁 连续签到奖励:[/color]\n" text += "\n[color=#FFD700]🎁 连续签到奖励:[/color]\n"
text += "[color=%s]%s +%d %s[/color] [color=#FFD700]✨[/color]\n" % [ text += "[color=#FFD700]💰 +%d 额外金币[/color] [color=#FFD700]✨[/color]\n" % rewards.bonus_coins
reward_configs.coins.color,
reward_configs.coins.icon,
rewards.bonus_coins,
reward_configs.coins.name
]
if rewards.has("bonus_exp"): if rewards.has("bonus_exp"):
if not rewards.has("bonus_coins"): if not rewards.has("bonus_coins"):
text += "\n[color=#FFD700]🎁 连续签到奖励:[/color]\n" text += "\n[color=#FFD700]🎁 连续签到奖励:[/color]\n"
text += "[color=%s]%s +%d %s[/color] [color=#FFD700]✨[/color]\n" % [ text += "[color=#00BFFF]⭐ +%d 额外经验[/color] [color=#FFD700]✨[/color]\n" % rewards.bonus_exp
reward_configs.exp.color,
reward_configs.exp.icon,
rewards.bonus_exp,
reward_configs.exp.name
]
# 下一个奖励预告
var next_bonus_day = 0 var next_bonus_day = 0
if consecutive_days < 3: if consecutive_days < 3:
next_bonus_day = 3 next_bonus_day = 3
@@ -318,6 +144,8 @@ func _format_reward_text(rewards: Dictionary) -> String:
next_bonus_day = 14 next_bonus_day = 14
elif consecutive_days < 21: elif consecutive_days < 21:
next_bonus_day = 21 next_bonus_day = 21
elif consecutive_days < 30:
next_bonus_day = 30
if next_bonus_day > 0: if next_bonus_day > 0:
var days_needed = next_bonus_day - consecutive_days var days_needed = next_bonus_day - consecutive_days
@@ -325,52 +153,18 @@ func _format_reward_text(rewards: Dictionary) -> String:
return text return text
## 获取种子信息 func _get_rarity_color(rarity: String) -> String:
func _get_seed_info(seed_name: String, quality: String) -> Dictionary: match rarity:
if quality in reward_configs.seeds: "普通": return "#90EE90"
for seed in reward_configs.seeds[quality]: "优良": return "#87CEEB"
if seed.name == seed_name: "稀有": return "#DDA0DD"
return seed "史诗": return "#9932CC"
return {} "传奇": return "#FF8C00"
_: return "#FFFFFF"
## 格式化历史记录文本
func _format_history_text(date: String, rewards: Dictionary) -> String:
var text = "[color=#87CEEB]📅 %s[/color] " % date
var reward_parts = []
if rewards.has("coins"):
reward_parts.append("[color=%s]%s %d[/color]" % [
reward_configs.coins.color,
reward_configs.coins.name,
rewards.coins
])
if rewards.has("exp"):
reward_parts.append("[color=%s]%s %d[/color]" % [
reward_configs.exp.color,
reward_configs.exp.name,
rewards.exp
])
if rewards.has("seeds") and rewards.seeds.size() > 0:
for seed_reward in rewards.seeds:
var seed_name = seed_reward.name
var quantity = seed_reward.quantity
var quality = seed_reward.quality
var seed_info = _get_seed_info(seed_name, quality)
if seed_info:
reward_parts.append("[color=%s]%s x%d[/color]" % [
seed_info.color, seed_name, quantity
])
text += " ".join(reward_parts)
return text
## 更新显示内容
func _update_display() -> void: func _update_display() -> void:
var history_text = "[center][color=#FFB6C1]📋 签到历史[/color][/center]\n" var history_text = "[center][color=#FFB6C1]📋 签到历史[/color][/center]\n"
# 显示连续签到状态
if consecutive_days > 0: if consecutive_days > 0:
history_text += "[center][color=#FF69B4]🔥 当前连续签到: %d天[/color][/center]\n" % consecutive_days history_text += "[center][color=#FF69B4]🔥 当前连续签到: %d天[/color][/center]\n" % consecutive_days
if consecutive_days >= 30: if consecutive_days >= 30:
@@ -380,61 +174,43 @@ func _update_display() -> void:
history_text += "\n" history_text += "\n"
if check_in_data.size() == 0: if check_in_history.size() == 0:
history_text += "[center][color=#DDDDDD]暂无签到记录[/color][/center]" history_text += "[center][color=#DDDDDD]暂无签到记录[/color][/center]"
else: else:
# 按日期排序显示历史记录 # 按时间排序显示历史记录
var sorted_dates = check_in_data.keys() var sorted_times = check_in_history.keys()
sorted_dates.sort() sorted_times.sort()
sorted_dates.reverse() # 最新的在前 sorted_times.reverse()
for date in sorted_dates: for time_key in sorted_times:
var day_data = check_in_data[date] var reward_text = check_in_history[time_key]
var rewards = day_data.get("rewards", {}) history_text += "[color=#87CEEB]%s[/color] [color=#90EE90]%s[/color]\n" % [time_key, reward_text]
var day_consecutive = day_data.get("consecutive_days", 1) history_text += "---------------------------------------------\n"
history_text += _format_history_text(date, rewards)
history_text += " [color=#90EE90](连续%d天)[/color]\n" % day_consecutive
history_text += "-----------------------------------------------------------------------------------------------------------------\n"
daily_check_in_history.text = history_text daily_check_in_history.text = history_text
# =============================================================================
# 事件处理 # 事件处理
# =============================================================================
## 关闭面板按钮
func _on_quit_button_pressed() -> void: func _on_quit_button_pressed() -> void:
self.hide() self.hide()
## 签到按钮
func _on_daily_check_in_button_pressed() -> void: func _on_daily_check_in_button_pressed() -> void:
execute_check_in() execute_check_in()
#面板显示与隐藏切换处理
func _on_visibility_changed(): func _on_visibility_changed():
if visible: if visible:
GlobalVariables.isZoomDisabled = true GlobalVariables.isZoomDisabled = true
pass
else: else:
GlobalVariables.isZoomDisabled = false GlobalVariables.isZoomDisabled = false
pass
# =============================================================================
# 公共接口方法 - 供主游戏调用
# =============================================================================
## 刷新签到数据 # 公共接口
func refresh_check_in_data() -> void: func refresh_check_in_data() -> void:
if tcp_network_manager_panel and tcp_network_manager_panel.is_connected_to_server(): if tcp_network_manager_panel and tcp_network_manager_panel.is_connected_to_server():
tcp_network_manager_panel.sendGetCheckInData() tcp_network_manager_panel.sendGetCheckInData()
## 获取当前签到状态
func get_check_in_status() -> Dictionary: func get_check_in_status() -> Dictionary:
return { return {
"has_checked_in_today": has_checked_in_today, "has_checked_in_today": has_checked_in_today,
"consecutive_days": consecutive_days, "consecutive_days": consecutive_days
"today_date": today_date
} }

View File

@@ -1,79 +1,46 @@
extends Panel extends Panel
class_name LuckyDrawPanel class_name LuckyDrawPanel
signal draw_completed(rewards: Array, draw_type: String)
signal draw_failed(error_message: String)
signal draw_completed(rewards: Array, draw_type: String) # 抽奖完成信号
signal reward_obtained(reward_type: String, amount: int) # 奖励获得信号
signal draw_failed(error_message: String) # 抽奖失败信号
#这个展示抽奖获得的奖励
@onready var lucky_draw_reward: RichTextLabel = $LuckyDrawReward @onready var lucky_draw_reward: RichTextLabel = $LuckyDrawReward
#这个是展示有哪些奖励选项最多15个奖励就在这里面随机挑选
@onready var grid: GridContainer = $Grid @onready var grid: GridContainer = $Grid
#这个是奖励模板
@onready var reward_item: RichTextLabel = $Grid/RewardItem @onready var reward_item: RichTextLabel = $Grid/RewardItem
@onready var main_game = get_node("/root/main")
@onready var tcp_network_manager_panel: Panel = $'../TCPNetworkManagerPanel'
var reward_templates: Array[RichTextLabel] = [] var reward_templates: Array[RichTextLabel] = []
var current_rewards: Array = [] var current_rewards: Array = []
@onready var main_game = get_node("/root/main") var seed_rewards: Dictionary = {}
@onready var daily_check_in_panel: DailyCheckInPanel = $'../DailyCheckInPanel'
@onready var tcp_network_manager_panel: Panel = $'../TCPNetworkManagerPanel'
@onready var item_store_panel: Panel = $'../ItemStorePanel'
@onready var item_bag_panel: Panel = $'../ItemBagPanel'
@onready var player_bag_panel: Panel = $'../PlayerBagPanel'
@onready var crop_warehouse_panel: Panel = $'../CropWarehousePanel'
@onready var crop_store_panel: Panel = $'../CropStorePanel'
@onready var player_ranking_panel: Panel = $'../PlayerRankingPanel'
@onready var login_panel: PanelContainer = $'../LoginPanel'
# 15种不同的模板颜色
var template_colors: Array[Color] = [
Color(1.0, 0.8, 0.8, 1.0), # 淡红色
Color(0.8, 1.0, 0.8, 1.0), # 淡绿色
Color(0.8, 0.8, 1.0, 1.0), # 淡蓝色
Color(1.0, 1.0, 0.8, 1.0), # 淡黄色
Color(1.0, 0.8, 1.0, 1.0), # 淡紫色
Color(0.8, 1.0, 1.0, 1.0), # 淡青色
Color(1.0, 0.9, 0.8, 1.0), # 淡橙色
Color(0.9, 0.8, 1.0, 1.0), # 淡紫蓝色
Color(0.8, 1.0, 0.9, 1.0), # 淡薄荷色
Color(1.0, 0.8, 0.9, 1.0), # 淡粉色
Color(0.9, 1.0, 0.8, 1.0), # 淡柠檬色
Color(0.8, 0.9, 1.0, 1.0), # 淡天蓝色
Color(1.0, 0.95, 0.8, 1.0), # 淡香槟色
Color(0.85, 0.8, 1.0, 1.0), # 淡薰衣草色
Color(0.95, 1.0, 0.85, 1.0) # 淡春绿色
]
var anticipation_tween: Tween = null var anticipation_tween: Tween = null
# 15种模板颜色
var template_colors: Array[Color] = [
Color(1.0, 0.8, 0.8, 1.0), Color(0.8, 1.0, 0.8, 1.0), Color(0.8, 0.8, 1.0, 1.0),
Color(1.0, 1.0, 0.8, 1.0), Color(1.0, 0.8, 1.0, 1.0), Color(0.8, 1.0, 1.0, 1.0),
Color(1.0, 0.9, 0.8, 1.0), Color(0.9, 0.8, 1.0, 1.0), Color(0.8, 1.0, 0.9, 1.0),
Color(1.0, 0.8, 0.9, 1.0), Color(0.9, 1.0, 0.8, 1.0), Color(0.8, 0.9, 1.0, 1.0),
Color(1.0, 0.95, 0.8, 1.0), Color(0.85, 0.8, 1.0, 1.0), Color(0.95, 1.0, 0.85, 1.0)
]
var base_rewards: Dictionary = { var base_rewards: Dictionary = {
"coins": {"name": "金币", "icon": "💰", "color": "#FFD700"}, "coins": {"name": "金币", "icon": "💰", "color": "#FFD700"},
"exp": {"name": "经验", "icon": "", "color": "#00BFFF"}, "exp": {"name": "经验", "icon": "", "color": "#00BFFF"},
"empty": {"name": "谢谢惠顾", "icon": "😅", "color": "#CCCCCC"} "empty": {"name": "谢谢惠顾", "icon": "😅", "color": "#CCCCCC"}
} }
var seed_rewards: Dictionary = {}
# 抽奖费用配置
var draw_costs: Dictionary = { var draw_costs: Dictionary = {
"single": 800, "single": 800,
"five": 3600, # 800 * 5 * 0.9 = 3600 "five": 3600,
"ten": 6400 # 800 * 10 * 0.8 = 6400 "ten": 6400
} }
var server_reward_pools: Dictionary = {}
func _ready() -> void: func _ready() -> void:
visibility_changed.connect(_on_visibility_changed)
_initialize_system() _initialize_system()
#初始化抽奖系统
func _initialize_system() -> void: func _initialize_system() -> void:
# 连接信号
if main_game: if main_game:
draw_completed.connect(main_game._on_lucky_draw_completed) draw_completed.connect(main_game._on_lucky_draw_completed)
draw_failed.connect(main_game._on_lucky_draw_failed) draw_failed.connect(main_game._on_lucky_draw_failed)
@@ -83,21 +50,18 @@ func _initialize_system() -> void:
_generate_reward_templates() _generate_reward_templates()
_update_template_display() _update_template_display()
#从主游戏加载作物数据并构建种子奖励
func _load_crop_data_and_build_rewards() -> void: func _load_crop_data_and_build_rewards() -> void:
if main_game and main_game.has_method("get_crop_data"): if main_game and main_game.has_method("get_crop_data"):
var crop_data = main_game.get_crop_data() var crop_data = main_game.get_crop_data()
if crop_data: if crop_data:
_build_seed_rewards_from_crop_data(crop_data) _build_seed_rewards_from_crop_data(crop_data)
#根据 crop_data.json 构建种子奖励配置
func _build_seed_rewards_from_crop_data(crop_data: Dictionary) -> void: func _build_seed_rewards_from_crop_data(crop_data: Dictionary) -> void:
seed_rewards.clear() seed_rewards.clear()
for crop_name in crop_data.keys(): for crop_name in crop_data.keys():
var crop_info = crop_data[crop_name] var crop_info = crop_data[crop_name]
# 跳过测试作物和不能购买的作物
if crop_name == "测试作物" or not crop_info.get("能否购买", true): if crop_name == "测试作物" or not crop_info.get("能否购买", true):
continue continue
@@ -112,52 +76,36 @@ func _build_seed_rewards_from_crop_data(crop_data: Dictionary) -> void:
"cost": crop_info.get("花费", 50) "cost": crop_info.get("花费", 50)
} }
#根据稀有度获取颜色
func _get_rarity_color(rarity: String) -> String: func _get_rarity_color(rarity: String) -> String:
match rarity: match rarity:
"普通": "普通": return "#90EE90"
return "#90EE90" "优良": return "#87CEEB"
"优良": "稀有": return "#DDA0DD"
return "#87CEEB" "史诗": return "#9932CC"
"稀有": "传奇": return "#FF8C00"
return "#DDA0DD" _: return "#FFFFFF"
"史诗":
return "#9932CC"
"传奇":
return "#FF8C00"
_:
return "#FFFFFF"
## 生成15个奖励模板
func _generate_reward_templates() -> void: func _generate_reward_templates() -> void:
# 清空现有模板
for child in grid.get_children(): for child in grid.get_children():
if child != reward_item: if child != reward_item:
child.queue_free() child.queue_free()
reward_templates.clear() reward_templates.clear()
# 生成15个模板包括原有的一个
for i in range(15): for i in range(15):
var template: RichTextLabel var template: RichTextLabel
if i == 0: if i == 0:
# 使用原有的模板
template = reward_item template = reward_item
else: else:
# 创建新的模板
template = reward_item.duplicate() template = reward_item.duplicate()
grid.add_child(template) grid.add_child(template)
# 设置不同的颜色
template.self_modulate = template_colors[i] template.self_modulate = template_colors[i]
template.bbcode_enabled = true template.bbcode_enabled = true
template.threaded = true template.threaded = true
reward_templates.append(template) reward_templates.append(template)
## 更新模板显示
func _update_template_display() -> void: func _update_template_display() -> void:
var sample_rewards = _generate_sample_rewards() var sample_rewards = _generate_sample_rewards()
@@ -170,16 +118,13 @@ func _update_template_display() -> void:
else: else:
template.hide() template.hide()
## 生成示例奖励显示
func _generate_sample_rewards() -> Array: func _generate_sample_rewards() -> Array:
var sample_rewards = [] var sample_rewards = []
# 添加基础奖励示例
sample_rewards.append({"type": "coins", "amount_range": [100, 300], "rarity": "普通"}) sample_rewards.append({"type": "coins", "amount_range": [100, 300], "rarity": "普通"})
sample_rewards.append({"type": "exp", "amount_range": [50, 150], "rarity": "普通"}) sample_rewards.append({"type": "exp", "amount_range": [50, 150], "rarity": "普通"})
sample_rewards.append({"type": "empty", "name": "谢谢惠顾", "rarity": "空奖"}) sample_rewards.append({"type": "empty", "name": "谢谢惠顾", "rarity": "空奖"})
# 添加各品质种子示例
var quality_examples = ["普通", "优良", "稀有", "史诗", "传奇"] var quality_examples = ["普通", "优良", "稀有", "史诗", "传奇"]
for quality in quality_examples: for quality in quality_examples:
var example_seeds = [] var example_seeds = []
@@ -188,7 +133,7 @@ func _generate_sample_rewards() -> Array:
example_seeds.append(seed_name) example_seeds.append(seed_name)
if example_seeds.size() > 0: if example_seeds.size() > 0:
var seed_name = example_seeds[0] # 取第一个作为示例 var seed_name = example_seeds[0]
sample_rewards.append({ sample_rewards.append({
"type": "seed", "type": "seed",
"name": seed_name, "name": seed_name,
@@ -196,18 +141,14 @@ func _generate_sample_rewards() -> Array:
"amount_range": [1, 3] if quality != "传奇" else [1, 1] "amount_range": [1, 3] if quality != "传奇" else [1, 1]
}) })
# 添加礼包示例
sample_rewards.append({"type": "package", "name": "成长套餐", "rarity": "优良"}) sample_rewards.append({"type": "package", "name": "成长套餐", "rarity": "优良"})
sample_rewards.append({"type": "package", "name": "稀有礼包", "rarity": "稀有"}) sample_rewards.append({"type": "package", "name": "稀有礼包", "rarity": "稀有"})
sample_rewards.append({"type": "package", "name": "传奇大礼包", "rarity": "传奇"}) sample_rewards.append({"type": "package", "name": "传奇大礼包", "rarity": "传奇"})
# 添加高级奖励示例
sample_rewards.append({"type": "coins", "amount_range": [1000, 2000], "rarity": "史诗"}) sample_rewards.append({"type": "coins", "amount_range": [1000, 2000], "rarity": "史诗"})
sample_rewards.append({"type": "exp", "amount_range": [500, 1000], "rarity": "传奇"}) sample_rewards.append({"type": "exp", "amount_range": [500, 1000], "rarity": "传奇"})
return sample_rewards.slice(0, 15) # 只取前15个 return sample_rewards.slice(0, 15)
## 格式化模板文本
func _format_template_text(reward: Dictionary) -> String: func _format_template_text(reward: Dictionary) -> String:
var text = "[center]" var text = "[center]"
@@ -251,44 +192,30 @@ func _format_template_text(reward: Dictionary) -> String:
text += "[/center]" text += "[/center]"
return text return text
## 执行网络抽奖
func _perform_network_draw(draw_type: String) -> void: func _perform_network_draw(draw_type: String) -> void:
if not tcp_network_manager_panel or not tcp_network_manager_panel.is_connected_to_server(): if not tcp_network_manager_panel or not tcp_network_manager_panel.is_connected_to_server():
_show_error_message("网络未连接,无法进行抽奖") _show_error_message("网络未连接,无法进行抽奖")
return return
# 检查费用
var cost = draw_costs.get(draw_type, 800) var cost = draw_costs.get(draw_type, 800)
if main_game and main_game.money < cost: if main_game and main_game.money < cost:
_show_error_message("金币不足,需要 %d 金币" % cost) _show_error_message("金币不足,需要 %d 金币" % cost)
return return
# 发送抽奖请求
var success = tcp_network_manager_panel.sendLuckyDraw(draw_type) var success = tcp_network_manager_panel.sendLuckyDraw(draw_type)
if not success: if not success:
_show_error_message("发送抽奖请求失败") _show_error_message("发送抽奖请求失败")
return return
# 显示等待动画 _show_waiting_animation()
_show_waiting_animation(draw_type)
## 显示等待动画 func _show_waiting_animation() -> void:
func _show_waiting_animation(draw_type: String) -> void:
# 禁用抽奖按钮
_set_draw_buttons_enabled(false) _set_draw_buttons_enabled(false)
# 隐藏结果区域
lucky_draw_reward.hide() lucky_draw_reward.hide()
# 播放期待动画
_play_anticipation_animation() _play_anticipation_animation()
## 处理服务器抽奖响应
func handle_lucky_draw_response(response: Dictionary) -> void: func handle_lucky_draw_response(response: Dictionary) -> void:
# 停止期待动画
_stop_anticipation_animation() _stop_anticipation_animation()
# 重新启用按钮
_set_draw_buttons_enabled(true) _set_draw_buttons_enabled(true)
if response.get("success", false): if response.get("success", false):
@@ -296,44 +223,30 @@ func handle_lucky_draw_response(response: Dictionary) -> void:
var draw_type = response.get("draw_type", "single") var draw_type = response.get("draw_type", "single")
var cost = response.get("cost", 0) var cost = response.get("cost", 0)
# 显示抽奖结果
_show_server_draw_results(rewards, draw_type, cost) _show_server_draw_results(rewards, draw_type, cost)
# 发送信号
draw_completed.emit(rewards, draw_type) draw_completed.emit(rewards, draw_type)
else: else:
var error_message = response.get("message", "抽奖失败") var error_message = response.get("message", "抽奖失败")
_show_error_message(error_message) _show_error_message(error_message)
draw_failed.emit(error_message) draw_failed.emit(error_message)
## 显示服务器返回的抽奖结果
func _show_server_draw_results(rewards: Array, draw_type: String, cost: int) -> void: func _show_server_draw_results(rewards: Array, draw_type: String, cost: int) -> void:
current_rewards = rewards current_rewards = rewards
# 显示结果动画已在handle_lucky_draw_response中停止
var result_text = _format_server_draw_results(rewards, draw_type, cost) var result_text = _format_server_draw_results(rewards, draw_type, cost)
lucky_draw_reward.text = result_text lucky_draw_reward.text = result_text
lucky_draw_reward.show() lucky_draw_reward.show()
# 播放结果动画
_play_result_animation() _play_result_animation()
## 格式化服务器抽奖结果文本
func _format_server_draw_results(rewards: Array, draw_type: String, cost: int) -> String: func _format_server_draw_results(rewards: Array, draw_type: String, cost: int) -> String:
var type_names = { var type_names = {"single": "单抽", "five": "五连抽", "ten": "十连抽"}
"single": "单抽",
"five": "五连抽",
"ten": "十连抽"
}
var text = "[center][color=#FFD700]🎊 %s结果 🎊[/color][/center]\n" % type_names.get(draw_type, draw_type) var text = "[center][color=#FFD700]🎊 %s结果 🎊[/color][/center]\n" % type_names.get(draw_type, draw_type)
text += "[center][color=#87CEEB]消费 %d 金币[/color][/center]\n" % cost text += "[center][color=#87CEEB]消费 %d 金币[/color][/center]\n" % cost
# 统计稀有度
var stats = _count_server_reward_rarity(rewards) var stats = _count_server_reward_rarity(rewards)
# 显示稀有度统计
var stat_parts = [] var stat_parts = []
if stats.legendary > 0: if stats.legendary > 0:
stat_parts.append("[color=#FF8C00]🏆传奇x%d[/color]" % stats.legendary) stat_parts.append("[color=#FF8C00]🏆传奇x%d[/color]" % stats.legendary)
@@ -349,11 +262,9 @@ func _format_server_draw_results(rewards: Array, draw_type: String, cost: int) -
text += "\n" text += "\n"
# 显示具体奖励
for reward in rewards: for reward in rewards:
text += _format_single_server_reward(reward) + "\n" text += _format_single_server_reward(reward) + "\n"
# 鼓励文案
if stats.empty_only: if stats.empty_only:
text += "[center][color=#87CEEB]💪 别灰心,下次一定能中大奖![/color][/center]" text += "[center][color=#87CEEB]💪 别灰心,下次一定能中大奖![/color][/center]"
elif stats.legendary > 0: elif stats.legendary > 0:
@@ -363,28 +274,16 @@ func _format_server_draw_results(rewards: Array, draw_type: String, cost: int) -
return text return text
## 统计服务器奖励稀有度
func _count_server_reward_rarity(rewards: Array) -> Dictionary: func _count_server_reward_rarity(rewards: Array) -> Dictionary:
var stats = { var stats = {"legendary": 0, "epic": 0, "rare": 0, "package": 0, "empty": 0, "empty_only": false}
"legendary": 0,
"epic": 0,
"rare": 0,
"package": 0,
"empty": 0,
"empty_only": false
}
for reward in rewards: for reward in rewards:
var rarity = reward.get("rarity", "普通") var rarity = reward.get("rarity", "普通")
match rarity: match rarity:
"传奇": "传奇": stats.legendary += 1
stats.legendary += 1 "史诗": stats.epic += 1
"史诗": "稀有": stats.rare += 1
stats.epic += 1 "空奖": stats.empty += 1
"稀有":
stats.rare += 1
"空奖":
stats.empty += 1
if reward.get("type") == "package": if reward.get("type") == "package":
stats.package += 1 stats.package += 1
@@ -392,21 +291,17 @@ func _count_server_reward_rarity(rewards: Array) -> Dictionary:
stats.empty_only = (stats.empty == rewards.size() and rewards.size() == 1) stats.empty_only = (stats.empty == rewards.size() and rewards.size() == 1)
return stats return stats
## 格式化单个服务器奖励显示
func _format_single_server_reward(reward: Dictionary) -> String: func _format_single_server_reward(reward: Dictionary) -> String:
var text = ""
var reward_type = reward.get("type", "") var reward_type = reward.get("type", "")
var rarity = reward.get("rarity", "普通") var rarity = reward.get("rarity", "普通")
var rarity_color = _get_rarity_color(rarity) var rarity_color = _get_rarity_color(rarity)
match reward_type: match reward_type:
"empty": "empty":
var reward_name = reward.get("name", "空奖励") return "[color=%s]😅 %s[/color]" % [rarity_color, reward.get("name", "空奖励")]
text = "[color=%s]😅 %s[/color]" % [rarity_color, reward_name]
"package": "package":
var reward_name = reward.get("name", "礼包") var text = "[color=%s]🎁 %s[/color]\n" % [rarity_color, reward.get("name", "礼包")]
text = "[color=%s]🎁 %s[/color]\n" % [rarity_color, reward_name]
text += "[color=#DDDDDD]内含:[/color] " text += "[color=#DDDDDD]内含:[/color] "
var content_parts = [] var content_parts = []
@@ -417,50 +312,35 @@ func _format_single_server_reward(reward: Dictionary) -> String:
content_parts.append(part) content_parts.append(part)
text += " ".join(content_parts) text += " ".join(content_parts)
return text
"coins": "coins":
var amount = reward.get("amount", 0) return "[color=%s]💰 金币 +%d[/color]" % [rarity_color, reward.get("amount", 0)]
text = "[color=%s]💰 金币 +%d[/color]" % [rarity_color, amount]
"exp": "exp":
var amount = reward.get("amount", 0) return "[color=%s]⭐ 经验 +%d[/color]" % [rarity_color, reward.get("amount", 0)]
text = "[color=%s]⭐ 经验 +%d[/color]" % [rarity_color, amount]
"seed": "seed":
var reward_name = reward.get("name", "种子") return "[color=%s]🌱 %s x%d[/color] [color=#CCCCCC](%s)[/color]" % [
var amount = reward.get("amount", 0) rarity_color, reward.get("name", "种子"), reward.get("amount", 0), rarity
text = "[color=%s]🌱 %s x%d[/color] [color=#CCCCCC](%s)[/color]" % [
rarity_color, reward_name, amount, rarity
] ]
_: _:
text = "[color=#CCCCCC]未知奖励[/color]" return "[color=#CCCCCC]未知奖励[/color]"
return text
## 格式化礼包内容
func _format_package_content(content: Dictionary) -> String: func _format_package_content(content: Dictionary) -> String:
var content_type = content.get("type", "") var content_type = content.get("type", "")
var amount = content.get("amount", 0) var amount = content.get("amount", 0)
match content_type: match content_type:
"coins": "coins": return "[color=#FFD700]💰%d[/color]" % amount
return "[color=#FFD700]💰%d[/color]" % amount "exp": return "[color=#00BFFF]⭐%d[/color]" % amount
"exp": "seed": return "[color=#90EE90]🌱%sx%d[/color]" % [content.get("name", "种子"), amount]
return "[color=#00BFFF]⭐%d[/color]" % amount _: return ""
"seed":
var seed_name = content.get("name", "种子")
return "[color=#90EE90]🌱%sx%d[/color]" % [seed_name, amount]
_:
return ""
## 播放期待动画(简化版)
func _play_anticipation_animation() -> void: func _play_anticipation_animation() -> void:
"""播放期待动画"""
# 停止之前的动画
_stop_anticipation_animation() _stop_anticipation_animation()
# 创建简单的闪烁动画
anticipation_tween = create_tween() anticipation_tween = create_tween()
anticipation_tween.set_loops() anticipation_tween.set_loops()
@@ -468,68 +348,38 @@ func _play_anticipation_animation() -> void:
if template.visible: if template.visible:
anticipation_tween.parallel().tween_method( anticipation_tween.parallel().tween_method(
func(progress: float): _anticipation_flash(template, progress), func(progress: float): _anticipation_flash(template, progress),
0.0, 1.0, 0.5 0.0, 1.0, 0.8
) )
func _anticipation_flash(template: RichTextLabel, progress: float) -> void: func _anticipation_flash(template: RichTextLabel, progress: float) -> void:
"""期待动画闪烁效果""" var flash_intensity = 1.0 + sin(progress * PI * 2) * 0.2
var flash_intensity = 1.0 + sin(progress * PI * 2) * 0.3
template.modulate = Color(flash_intensity, flash_intensity, flash_intensity, 1.0) template.modulate = Color(flash_intensity, flash_intensity, flash_intensity, 1.0)
## 停止期待动画
func _stop_anticipation_animation() -> void: func _stop_anticipation_animation() -> void:
if anticipation_tween: if anticipation_tween:
anticipation_tween.kill() anticipation_tween.kill()
anticipation_tween = null anticipation_tween = null
# 恢复所有模板的正常颜色 for template in reward_templates:
for i in range(reward_templates.size()):
var template = reward_templates[i]
template.modulate = Color.WHITE template.modulate = Color.WHITE
## 播放结果动画
func _play_result_animation() -> void: func _play_result_animation() -> void:
var tween = create_tween() var tween = create_tween()
# 奖励区域动画
lucky_draw_reward.modulate.a = 0.0 lucky_draw_reward.modulate.a = 0.0
lucky_draw_reward.scale = Vector2(0.8, 0.8) lucky_draw_reward.scale = Vector2(0.8, 0.8)
tween.parallel().tween_property(lucky_draw_reward, "modulate:a", 1.0, 0.5) tween.parallel().tween_property(lucky_draw_reward, "modulate:a", 1.0, 0.5)
tween.parallel().tween_property(lucky_draw_reward, "scale", Vector2(1.0, 1.0), 0.5) tween.parallel().tween_property(lucky_draw_reward, "scale", Vector2(1.0, 1.0), 0.5)
tween.tween_callback(func(): lucky_draw_reward.modulate.a = 1.0)
## 显示错误信息
func _show_error_message(message: String) -> void: func _show_error_message(message: String) -> void:
lucky_draw_reward.text = "[center][color=#FF6B6B]❌ %s[/color][/center]" % message lucky_draw_reward.text = "[center][color=#FF6B6B]❌ %s[/color][/center]" % message
lucky_draw_reward.show() lucky_draw_reward.show()
# 2秒后隐藏错误信息
await get_tree().create_timer(2.0).timeout await get_tree().create_timer(2.0).timeout
lucky_draw_reward.hide() lucky_draw_reward.hide()
# =============================================================================
# 事件处理
# =============================================================================
## 关闭面板
func _on_quit_button_pressed() -> void:
self.hide()
## 单次抽奖
func _on_lucky_draw_button_pressed() -> void:
_perform_network_draw("single")
## 五连抽
func _on_five_lucky_draw_button_pressed() -> void:
_perform_network_draw("five")
## 十连抽
func _on_ten_lucky_draw_button_pressed() -> void:
_perform_network_draw("ten")
## 设置抽奖按钮可用状态
func _set_draw_buttons_enabled(enabled: bool) -> void: func _set_draw_buttons_enabled(enabled: bool) -> void:
var buttons = [ var buttons = [
$HBox/LuckyDrawButton, $HBox/LuckyDrawButton,
@@ -541,30 +391,33 @@ func _set_draw_buttons_enabled(enabled: bool) -> void:
if button: if button:
button.disabled = not enabled button.disabled = not enabled
# ============================================================================= # 事件处理
# 公共接口方法 func _on_quit_button_pressed() -> void:
# ============================================================================= self.hide()
## 获取当前奖励结果 func _on_lucky_draw_button_pressed() -> void:
_perform_network_draw("single")
func _on_five_lucky_draw_button_pressed() -> void:
_perform_network_draw("five")
func _on_ten_lucky_draw_button_pressed() -> void:
_perform_network_draw("ten")
func _on_visibility_changed():
if visible:
GlobalVariables.isZoomDisabled = true
else:
GlobalVariables.isZoomDisabled = false
# 公共接口
func get_current_rewards() -> Array: func get_current_rewards() -> Array:
return current_rewards return current_rewards
## 清空抽奖结果
func clear_draw_results() -> void: func clear_draw_results() -> void:
current_rewards.clear() current_rewards.clear()
lucky_draw_reward.hide() lucky_draw_reward.hide()
## 刷新奖励显示(当作物数据更新时调用)
func refresh_reward_display() -> void: func refresh_reward_display() -> void:
_load_crop_data_and_build_rewards() _load_crop_data_and_build_rewards()
_update_template_display() _update_template_display()
#面板显示与隐藏切换处理
func _on_visibility_changed():
if visible:
GlobalVariables.isZoomDisabled = true
pass
else:
GlobalVariables.isZoomDisabled = false
pass

View File

@@ -65,6 +65,7 @@ server_version: str = "2.0.1"
# TCP游戏服务器类 # TCP游戏服务器类
# ============================================================================ # ============================================================================
class TCPGameServer(TCPServer): class TCPGameServer(TCPServer):
""" """
萌芽农场TCP游戏服务器 萌芽农场TCP游戏服务器
""" """
@@ -6206,6 +6207,39 @@ class TCPGameServer(TCPServer):
#==========================每日签到处理========================== #==========================每日签到处理==========================
#加载每日签到配置
def _load_daily_check_in_config(self):
"""加载每日签到配置"""
try:
config_path = os.path.join(self.config_dir, "daily_checkin_config.json")
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
return json.load(f)
except:
pass
# 默认配置
return {
"基础奖励": {
"金币": {"最小值": 200, "最大值": 500, "图标": "💰", "颜色": "#FFD700"},
"经验": {"最小值": 50, "最大值": 120, "图标": "", "颜色": "#00BFFF"}
},
"种子奖励": {
"普通": {"概率": 0.6, "数量范围": [2, 5], "种子池": ["小麦", "胡萝卜", "土豆", "稻谷"]},
"优良": {"概率": 0.25, "数量范围": [2, 4], "种子池": ["玉米", "番茄", "洋葱", "大豆", "豌豆", "黄瓜", "大白菜"]},
"稀有": {"概率": 0.12, "数量范围": [1, 3], "种子池": ["草莓", "花椰菜", "柿子", "蓝莓", "树莓"]},
"史诗": {"概率": 0.025, "数量范围": [1, 2], "种子池": ["葡萄", "南瓜", "芦笋", "茄子", "向日葵", "蕨菜"]},
"传奇": {"概率": 0.005, "数量范围": [1, 1], "种子池": ["西瓜", "甘蔗", "香草", "甜菜", "人参", "富贵竹", "芦荟", "哈密瓜"]}
},
"连续签到奖励": {
"第3天": {"额外金币": 100, "额外经验": 50, "描述": "连续签到奖励"},
"第7天": {"额外金币": 200, "额外经验": 100, "描述": "一周连击奖励"},
"第14天": {"额外金币": 500, "额外经验": 200, "描述": "半月连击奖励"},
"第21天": {"额外金币": 800, "额外经验": 300, "描述": "三周连击奖励"},
"第30天": {"额外金币": 1500, "额外经验": 500, "描述": "满月连击奖励"}
}
}
#处理每日签到请求 #处理每日签到请求
def _handle_daily_check_in_request(self, client_id, message): def _handle_daily_check_in_request(self, client_id, message):
"""处理每日签到请求""" """处理每日签到请求"""
@@ -6219,11 +6253,17 @@ class TCPGameServer(TCPServer):
if not player_data: if not player_data:
return self.send_data(client_id, response) return self.send_data(client_id, response)
# 检查今日是否已签到 # 清理过期签到记录并使用新格式
current_date = datetime.datetime.now().strftime("%Y-%m-%d") self._cleanup_check_in_history(player_data)
check_in_data = player_data.get("daily_check_in", {})
if current_date in check_in_data: # 检查今日是否已签到
current_time = datetime.datetime.now()
today_key = current_time.strftime("%Y年%m月%d")
check_in_history = player_data.get("签到历史", {})
# 检查今日是否已签到
for time_key in check_in_history.keys():
if time_key.startswith(today_key):
return self.send_data(client_id, { return self.send_data(client_id, {
"type": "daily_check_in_response", "type": "daily_check_in_response",
"success": False, "success": False,
@@ -6232,23 +6272,22 @@ class TCPGameServer(TCPServer):
}) })
# 计算连续签到天数 # 计算连续签到天数
consecutive_days = self._calculate_consecutive_check_in_days(check_in_data, current_date) consecutive_days = self._calculate_consecutive_check_in_days_new(check_in_history)
# 生成签到奖励 # 生成签到奖励
rewards = self._generate_check_in_rewards(consecutive_days) config = self._load_daily_check_in_config()
rewards = self._generate_check_in_rewards_new(consecutive_days, config)
# 发放奖励 # 发放奖励
self._apply_check_in_rewards(player_data, rewards) self._apply_check_in_rewards(player_data, rewards)
# 保存签到记录 # 保存签到记录 - 使用新格式
if "daily_check_in" not in player_data: if "签到历史" not in player_data:
player_data["daily_check_in"] = {} player_data["签到历史"] = {}
player_data["daily_check_in"][current_date] = { time_key = current_time.strftime("%Y年%m月%d%H时%M分%S秒")
"rewards": rewards, reward_text = self._format_reward_text_simple(rewards)
"consecutive_days": consecutive_days, player_data["签到历史"][time_key] = reward_text
"timestamp": time.time()
}
# 保存玩家数据 # 保存玩家数据
self.save_player_data(username, player_data) self.save_player_data(username, player_data)
@@ -6282,144 +6321,201 @@ class TCPGameServer(TCPServer):
if not player_data: if not player_data:
return self.send_data(client_id, response) return self.send_data(client_id, response)
current_date = datetime.datetime.now().strftime("%Y-%m-%d") # 清理过期签到记录
check_in_data = player_data.get("daily_check_in", {}) self._cleanup_check_in_history(player_data)
check_in_history = player_data.get("签到历史", {})
# 计算连续签到天数 # 计算连续签到天数
consecutive_days = self._calculate_consecutive_check_in_days(check_in_data, current_date) consecutive_days = self._calculate_consecutive_check_in_days_new(check_in_history)
# 检查今日是否已签到 # 检查今日是否已签到
has_checked_in_today = current_date in check_in_data current_time = datetime.datetime.now()
today_key = current_time.strftime("%Y年%m月%d")
has_checked_in_today = any(time_key.startswith(today_key) for time_key in check_in_history.keys())
return self.send_data(client_id, { return self.send_data(client_id, {
"type": "check_in_data_response", "type": "check_in_data_response",
"success": True, "success": True,
"check_in_data": check_in_data, "check_in_data": check_in_history,
"consecutive_days": consecutive_days, "consecutive_days": consecutive_days,
"has_checked_in_today": has_checked_in_today, "has_checked_in_today": has_checked_in_today,
"current_date": current_date "current_date": current_time.strftime("%Y年%m月%d")
}) })
#计算连续签到天数 #清理过期签到记录
def _calculate_consecutive_check_in_days(self, check_in_data, current_date): def _cleanup_check_in_history(self, player_data):
"""计算连续签到天数""" """清理过期签到记录只保留最近30天的记录"""
if not check_in_data: if "签到历史" not in player_data:
return
current_time = datetime.datetime.now()
cutoff_time = current_time - datetime.timedelta(days=30)
# 清理过期记录
history = player_data["签到历史"]
keys_to_remove = []
for time_key in history.keys():
try:
# 解析时间字符串
check_time = datetime.datetime.strptime(time_key, "%Y年%m月%d%H时%M分%S秒")
if check_time < cutoff_time:
keys_to_remove.append(time_key)
except:
# 如果解析失败,删除这条记录
keys_to_remove.append(time_key)
for key in keys_to_remove:
del history[key]
#计算连续签到天数(新版本)
def _calculate_consecutive_check_in_days_new(self, check_in_history):
"""计算连续签到天数(新版本)"""
if not check_in_history:
return 0 return 0
# 取所有签到日期并排序 # 取所有签到日期(只取日期部分)
sorted_dates = sorted(check_in_data.keys()) check_dates = set()
if not sorted_dates: for time_key in check_in_history.keys():
try:
check_time = datetime.datetime.strptime(time_key, "%Y年%m月%d%H时%M分%S秒")
date_str = check_time.strftime("%Y-%m-%d")
check_dates.add(date_str)
except:
continue
if not check_dates:
return 0 return 0
# 从最新日期开始向前计算连续天数 # 从今天开始向前计算连续天数
consecutive_days = 0 consecutive_days = 0
current_datetime = datetime.datetime.strptime(current_date, "%Y-%m-%d") current_date = datetime.datetime.now()
# 如果今天已经签到,从今天开始计算,否则从昨天开始 # 检查今天是否已签到
if current_date in check_in_data: today_str = current_date.strftime("%Y-%m-%d")
check_date = current_datetime if today_str in check_dates:
consecutive_days += 1
check_date = current_date - datetime.timedelta(days=1)
else: else:
check_date = current_datetime - datetime.timedelta(days=1) check_date = current_date - datetime.timedelta(days=1)
# 向前查找连续签到天数 # 向前查找连续签到天数
while True: while True:
date_string = check_date.strftime("%Y-%m-%d") date_str = check_date.strftime("%Y-%m-%d")
if date_string in check_in_data: if date_str in check_dates:
consecutive_days += 1 consecutive_days += 1
check_date -= datetime.timedelta(days=1) check_date -= datetime.timedelta(days=1)
else: else:
break break
# 限制最大连续天数为30天,避免过度奖励 # 限制最大连续天数为30天
if consecutive_days >= 30: if consecutive_days >= 30:
break break
return consecutive_days return consecutive_days
#生成签到奖励 #生成签到奖励(新版本)
def _generate_check_in_rewards(self, consecutive_days): def _generate_check_in_rewards_new(self, consecutive_days, config):
"""生成签到奖励""" """生成签到奖励(新版本)"""
import random import random
# 加载作物配置
crop_data = self._load_crop_data()
rewards = {} rewards = {}
# 基础奖励倍数(根据连续签到天数) # 基础奖励倍数
base_multiplier = 1.0 + (consecutive_days - 1) * 0.1 # 每连续签到一天增加10% base_multiplier = 1.0 + (consecutive_days - 1) * 0.1
max_multiplier = 3.0 # 最大3倍奖励 max_multiplier = 3.0
multiplier = min(base_multiplier, max_multiplier) multiplier = min(base_multiplier, max_multiplier)
# 钱币奖励 (基础200-500受连续签到影响) # 基础金币奖励
base_coins = random.randint(200, 500) coin_config = config.get("基础奖励", {}).get("金币", {})
base_coins = random.randint(coin_config.get("最小值", 200), coin_config.get("最大值", 500))
rewards["coins"] = int(base_coins * multiplier) rewards["coins"] = int(base_coins * multiplier)
# 经验奖励 (基础50-120受连续签到影响) # 基础经验奖励
base_exp = random.randint(50, 120) exp_config = config.get("基础奖励", {}).get("经验", {})
base_exp = random.randint(exp_config.get("最小值", 50), exp_config.get("最大值", 120))
rewards["exp"] = int(base_exp * multiplier) rewards["exp"] = int(base_exp * multiplier)
# 种子奖励 (根据连续签到天数获得更好的种子) # 种子奖励
seeds = self._generate_check_in_seeds(consecutive_days, crop_data) seeds = self._generate_check_in_seeds_new(consecutive_days, config)
if seeds: if seeds:
rewards["seeds"] = seeds rewards["seeds"] = seeds
# 连续签到特殊奖励 # 连续签到特殊奖励
if consecutive_days >= 3: consecutive_rewards = config.get("连续签到奖励", {})
rewards["bonus_coins"] = int(100 * (consecutive_days // 3)) for milestone, bonus in consecutive_rewards.items():
milestone_days = int(milestone.replace("", "").replace("", ""))
if consecutive_days >= 7: if consecutive_days >= milestone_days:
rewards["bonus_exp"] = int(200 * (consecutive_days // 7)) if "额外金币" in bonus:
rewards["bonus_coins"] = bonus["额外金币"]
if "额外经验" in bonus:
rewards["bonus_exp"] = bonus["额外经验"]
return rewards return rewards
#生成签到种子奖励 #生成签到种子奖励(新版本)
def _generate_check_in_seeds(self, consecutive_days, crop_data): def _generate_check_in_seeds_new(self, consecutive_days, config):
"""生成签到种子奖励""" """生成签到种子奖励(新版本)"""
import random import random
seeds = [] seeds = []
seed_configs = config.get("种子奖励", {})
# 根据连续签到天数确定种子类型和数量 # 根据连续签到天数确定种子稀有度
if consecutive_days <= 2: if consecutive_days <= 2:
# 1-2天普通种子 rarity = "普通"
common_seeds = ["小麦", "胡萝卜", "土豆", "稻谷"]
elif consecutive_days <= 5: elif consecutive_days <= 5:
# 3-5天优良种子 rarity = "优良"
common_seeds = ["玉米", "番茄", "洋葱", "大豆", "豌豆", "黄瓜", "大白菜"]
elif consecutive_days <= 10: elif consecutive_days <= 10:
# 6-10天稀有种子 rarity = "稀有"
common_seeds = ["草莓", "花椰菜", "柿子", "蓝莓", "树莓"]
elif consecutive_days <= 15: elif consecutive_days <= 15:
# 11-15天史诗种子 rarity = "史诗"
common_seeds = ["葡萄", "南瓜", "芦笋", "茄子", "向日葵", "蕨菜"]
else: else:
# 16天以上传奇种子 rarity = "传奇"
common_seeds = ["西瓜", "甘蔗", "香草", "甜菜", "人参", "富贵竹", "芦荟", "哈密瓜"]
# 获取对应稀有度的种子池
rarity_config = seed_configs.get(rarity, {})
seed_pool = rarity_config.get("种子池", [])
quantity_range = rarity_config.get("数量范围", [1, 2])
if not seed_pool:
return seeds
# 生成1-3个种子 # 生成1-3个种子
seed_count = random.randint(1, min(3, len(common_seeds))) seed_count = random.randint(1, min(3, len(seed_pool)))
selected_seeds = random.sample(common_seeds, seed_count) selected_seeds = random.sample(seed_pool, seed_count)
for seed_name in selected_seeds: for seed_name in selected_seeds:
if seed_name in crop_data: quantity = random.randint(quantity_range[0], quantity_range[1])
# 根据种子等级确定数量
seed_level = crop_data[seed_name].get("等级", 1)
if seed_level <= 2:
quantity = random.randint(2, 5)
elif seed_level <= 4:
quantity = random.randint(1, 3)
else:
quantity = 1
seeds.append({ seeds.append({
"name": seed_name, "name": seed_name,
"quantity": quantity, "quantity": quantity,
"quality": crop_data[seed_name].get("品质", "普通") "quality": rarity
}) })
return seeds return seeds
#格式化奖励文本(简单版本)
def _format_reward_text_simple(self, rewards):
"""格式化奖励文本(简单版本)"""
parts = []
if "coins" in rewards:
parts.append(f"金币{rewards['coins']}")
if "exp" in rewards:
parts.append(f"经验{rewards['exp']}")
if "bonus_coins" in rewards:
parts.append(f"额外金币{rewards['bonus_coins']}")
if "bonus_exp" in rewards:
parts.append(f"额外经验{rewards['bonus_exp']}")
if "seeds" in rewards:
for seed in rewards["seeds"]:
parts.append(f"{seed['name']}x{seed['quantity']}")
return " ".join(parts)
#应用签到奖励到玩家数据 #应用签到奖励到玩家数据
def _apply_check_in_rewards(self, player_data, rewards): def _apply_check_in_rewards(self, player_data, rewards):
"""应用签到奖励到玩家数据""" """应用签到奖励到玩家数据"""
@@ -6620,22 +6716,27 @@ class TCPGameServer(TCPServer):
if not player_data: if not player_data:
return self.send_data(client_id, response) return self.send_data(client_id, response)
# 删除历史记录(如果存在)
if "lucky_draw_history" in player_data:
del player_data["lucky_draw_history"]
draw_type = message.get("draw_type", "single") # single, five, ten draw_type = message.get("draw_type", "single") # single, five, ten
draw_count = 1
base_cost = 800 # 基础抽奖费用 # 从配置文件获取费用
config = self._load_lucky_draw_config()
costs = config.get("抽奖费用", {"单抽": 800, "五连抽": 3600, "十连抽": 6400})
# 计算抽奖费用和数量 # 计算抽奖费用和数量
if draw_type == "single": if draw_type == "single":
draw_count = 1 draw_count = 1
total_cost = base_cost total_cost = costs.get("单抽", 800)
elif draw_type == "five": elif draw_type == "five":
draw_count = 5 draw_count = 5
total_cost = int(base_cost * 5 * 0.9) # 五连抽九折 total_cost = costs.get("五连抽", 3600)
elif draw_type == "ten": elif draw_type == "ten":
draw_count = 10 draw_count = 10
total_cost = int(base_cost * 10 * 0.8) # 十连抽八折 total_cost = costs.get("十连抽", 6400)
else: else:
self.log('WARNING', f"玩家 {username} 使用了无效的抽奖类型: {draw_type}", 'SERVER')
return self.send_data(client_id, { return self.send_data(client_id, {
"type": "lucky_draw_response", "type": "lucky_draw_response",
"success": False, "success": False,
@@ -6644,44 +6745,21 @@ class TCPGameServer(TCPServer):
# 检查玩家金钱是否足够 # 检查玩家金钱是否足够
if player_data.get("money", 0) < total_cost: if player_data.get("money", 0) < total_cost:
self.log('WARNING', f"玩家 {username} 金币不足进行{draw_type}抽奖,需要{total_cost},当前{player_data.get('money', 0)}", 'SERVER')
return self.send_data(client_id, { return self.send_data(client_id, {
"type": "lucky_draw_response", "type": "lucky_draw_response",
"success": False, "success": False,
"message": f"金钱不足,{draw_type}抽奖需要 {total_cost} 金币" "message": f"金钱不足,需要 {total_cost} 金币"
}) })
# 扣除金钱 # 扣除金钱
player_data["money"] -= total_cost player_data["money"] -= total_cost
# 生成奖励 # 生成奖励
rewards = self._generate_lucky_draw_rewards(draw_count, draw_type) rewards = self._generate_lucky_draw_rewards(draw_count, draw_type, config)
# 验证奖励格式
for reward in rewards:
if not reward.get("rarity"):
reward["rarity"] = "普通"
self.log('WARNING', f"奖励缺少稀有度字段,已设置为普通: {reward}", 'SERVER')
# 应用奖励到玩家数据 # 应用奖励到玩家数据
self._apply_lucky_draw_rewards(player_data, rewards) self._apply_lucky_draw_rewards(player_data, rewards)
# 记录抽奖历史
if "lucky_draw_history" not in player_data:
player_data["lucky_draw_history"] = []
draw_record = {
"date": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"type": draw_type,
"cost": total_cost,
"rewards": rewards
}
player_data["lucky_draw_history"].append(draw_record)
# 只保留最近100次记录
if len(player_data["lucky_draw_history"]) > 100:
player_data["lucky_draw_history"] = player_data["lucky_draw_history"][-100:]
# 保存玩家数据 # 保存玩家数据
self.save_player_data(username, player_data) self.save_player_data(username, player_data)
@@ -6703,24 +6781,40 @@ class TCPGameServer(TCPServer):
}) })
except Exception as e: except Exception as e:
# 捕获所有异常,防止服务器崩溃
self.log('ERROR', f"处理玩家抽奖请求时出错: {str(e)}", 'SERVER') self.log('ERROR', f"处理玩家抽奖请求时出错: {str(e)}", 'SERVER')
# 尝试获取用户名
try:
username = self.user_data[client_id].get("username", "未知用户")
except:
username = "未知用户"
# 发送错误响应
return self.send_data(client_id, { return self.send_data(client_id, {
"type": "lucky_draw_response", "type": "lucky_draw_response",
"success": False, "success": False,
"message": "服务器处理抽奖时出现错误,请稍后重试" "message": "服务器处理抽奖时出现错误,请稍后重试"
}) })
#加载抽奖配置
def _load_lucky_draw_config(self):
"""加载抽奖配置"""
try:
config_path = os.path.join(self.config_dir, "lucky_draw_config.json")
if os.path.exists(config_path):
with open(config_path, 'r', encoding='utf-8') as f:
return json.load(f)
except:
pass
# 默认配置
return {
"抽奖费用": {"单抽": 800, "五连抽": 3600, "十连抽": 6400},
"概率配置": {
"普通": {"概率": 0.45, "金币范围": [100, 300], "经验范围": [50, 150], "种子数量": [2, 4]},
"优良": {"概率": 0.25, "金币范围": [300, 600], "经验范围": [150, 300], "种子数量": [1, 3]},
"稀有": {"概率": 0.12, "金币范围": [600, 1000], "经验范围": [300, 500], "种子数量": [1, 2]},
"史诗": {"概率": 0.025, "金币范围": [1000, 1500], "经验范围": [500, 800], "种子数量": [1, 1]},
"传奇": {"概率": 0.005, "金币范围": [1500, 2500], "经验范围": [800, 1200], "种子数量": [1, 1]},
"空奖": {"概率": 0.15, "提示语": ["谢谢惠顾", "下次再来", "再试一次", "继续努力"]}
}
}
#生成幸运抽奖奖励 #生成幸运抽奖奖励
def _generate_lucky_draw_rewards(self, count: int, draw_type: str): def _generate_lucky_draw_rewards(self, count: int, draw_type: str, config: dict):
"""生成幸运抽奖奖励""" """生成幸运抽奖奖励"""
import random import random
@@ -6730,42 +6824,28 @@ class TCPGameServer(TCPServer):
rewards = [] rewards = []
# 根据 crop_data.json 构建奖励池 # 根据 crop_data.json 构建奖励池
common_seeds = [] seed_pools = {"普通": [], "优良": [], "稀有": [], "史诗": [], "传奇": []}
good_seeds = []
rare_seeds = []
epic_seeds = []
legendary_seeds = []
for crop_name, crop_info in crop_data.items(): for crop_name, crop_info in crop_data.items():
if not crop_info.get("能否购买", True): if not crop_info.get("能否购买", True):
continue # 跳过不能购买的作物 continue
quality = crop_info.get("品质", "普通") quality = crop_info.get("品质", "普通")
if quality == "普通": if quality in seed_pools:
common_seeds.append(crop_name) seed_pools[quality].append(crop_name)
elif quality == "优良":
good_seeds.append(crop_name)
elif quality == "稀有":
rare_seeds.append(crop_name)
elif quality == "史诗":
epic_seeds.append(crop_name)
elif quality == "传奇":
legendary_seeds.append(crop_name)
# 十连抽保底机制:至少一个稀有以上 # 十连抽保底机制
guaranteed_rare = (draw_type == "ten") guaranteed_rare = (draw_type == "ten")
rare_given = False rare_given = False
for i in range(count): for i in range(count):
# 生成单个奖励 # 生成单个奖励
reward = self._generate_single_lucky_reward( reward = self._generate_single_lucky_reward(
common_seeds, good_seeds, rare_seeds, epic_seeds, legendary_seeds, seed_pools, config, guaranteed_rare and i == count - 1 and not rare_given
guaranteed_rare and i == count - 1 and not rare_given
) )
# 检查是否给出了稀有奖励(使用安全的方式访问) # 检查是否给出了稀有奖励
reward_rarity = reward.get("rarity", "普通") if reward.get("rarity", "普通") in ["稀有", "史诗", "传奇"]:
if reward_rarity in ["稀有", "史诗", "传奇"]:
rare_given = True rare_given = True
rewards.append(reward) rewards.append(reward)
@@ -6773,278 +6853,166 @@ class TCPGameServer(TCPServer):
return rewards return rewards
#生成单个抽奖奖励 #生成单个抽奖奖励
def _generate_single_lucky_reward(self, common_seeds, good_seeds, rare_seeds, epic_seeds, legendary_seeds, force_rare=False): def _generate_single_lucky_reward(self, seed_pools: dict, config: dict, force_rare=False):
"""生成单个幸运抽奖奖励""" """生成单个幸运抽奖奖励"""
import random import random
# 概率配置 prob_config = config.get("概率配置", {})
# 决定稀有度
if force_rare: if force_rare:
# 强制稀有33%稀有33%史诗34%传奇 # 强制稀有33%稀有33%史诗34%传奇
rand = random.random() rand = random.random()
if rand < 0.33: if rand < 0.33:
reward_type = "rare" rarity = "稀有"
elif rand < 0.66: elif rand < 0.66:
reward_type = "epic" rarity = "史诗"
else: else:
reward_type = "legendary" rarity = "传奇"
else: else:
# 正常概率45%普通25%优良15%空奖12%稀有2.5%史诗0.5%传奇 # 正常概率
rand = random.random() rand = random.random()
if rand < 0.45: cumulative = 0
reward_type = "common" rarity = "普通"
elif rand < 0.70:
reward_type = "good"
elif rand < 0.85:
reward_type = "empty"
elif rand < 0.97:
reward_type = "rare"
elif rand < 0.995:
reward_type = "epic"
else:
reward_type = "legendary"
reward = {} for r, config_data in prob_config.items():
prob = config_data.get("概率", 0)
cumulative += prob
if rand < cumulative:
rarity = r
break
if reward_type == "empty": # 根据稀有度生成奖励
# 谢谢惠顾 if rarity == "空奖":
empty_messages = ["谢谢惠顾", "下次再来", "再试一次", "继续努力"] empty_messages = prob_config.get("空奖", {}).get("提示语", ["谢谢惠顾"])
reward = { return {
"type": "empty", "type": "empty",
"name": random.choice(empty_messages), "name": random.choice(empty_messages),
"rarity": "空奖", "rarity": "空奖",
"amount": 0 "amount": 0
} }
elif reward_type == "common": # 获取稀有度配置
# 普通奖励:金币、经验或普通种子 rarity_config = prob_config.get(rarity, {})
reward_choice = random.choice(["coins", "exp", "seed"])
if reward_choice == "coins": # 根据奖励类型权重选择奖励类型
reward = { type_weights = config.get("奖励类型权重", {}).get(rarity, {"金币": 0.5, "经验": 0.3, "种子": 0.2})
# 随机选择奖励类型
rand = random.random()
cumulative = 0
reward_type = "金币"
for r_type, weight in type_weights.items():
cumulative += weight
if rand < cumulative:
reward_type = r_type
break
# 生成具体奖励
if reward_type == "金币":
coin_range = rarity_config.get("金币范围", [100, 300])
return {
"type": "coins", "type": "coins",
"name": "金币", "name": "金币",
"rarity": "普通", "rarity": rarity,
"amount": random.randint(100, 300) "amount": random.randint(coin_range[0], coin_range[1])
}
elif reward_choice == "exp":
reward = {
"type": "exp",
"name": "经验",
"rarity": "普通",
"amount": random.randint(50, 150)
}
else: # seed
if common_seeds:
seed_name = random.choice(common_seeds)
reward = {
"type": "seed",
"name": seed_name,
"rarity": "普通",
"amount": random.randint(2, 4)
}
else:
reward = {
"type": "coins",
"name": "金币",
"rarity": "普通",
"amount": random.randint(100, 300)
} }
elif reward_type == "good": elif reward_type == "经验":
# 优良奖励:更多金币经验或优良种子 exp_range = rarity_config.get("经验范围", [50, 150])
reward_choice = random.choice(["coins", "exp", "seed", "package"]) return {
if reward_choice == "coins":
reward = {
"type": "coins",
"name": "金币",
"rarity": "优良",
"amount": random.randint(300, 600)
}
elif reward_choice == "exp":
reward = {
"type": "exp", "type": "exp",
"name": "经验", "name": "经验",
"rarity": "优良", "rarity": rarity,
"amount": random.randint(150, 300) "amount": random.randint(exp_range[0], exp_range[1])
} }
elif reward_choice == "seed":
if good_seeds: elif reward_type == "种子":
seed_name = random.choice(good_seeds) seeds = seed_pools.get(rarity, [])
reward = { if not seeds:
"type": "seed", # 如果没有对应稀有度的种子,给金币
"name": seed_name, coin_range = rarity_config.get("金币范围", [100, 300])
"rarity": "优良", return {
"amount": random.randint(1, 3)
}
else:
reward = {
"type": "coins", "type": "coins",
"name": "金币", "name": "金币",
"rarity": "优良", "rarity": rarity,
"amount": random.randint(300, 600) "amount": random.randint(coin_range[0], coin_range[1])
} }
else: # package
reward = { seed_count_range = rarity_config.get("种子数量", [1, 2])
return {
"type": "seed",
"name": random.choice(seeds),
"rarity": rarity,
"amount": random.randint(seed_count_range[0], seed_count_range[1])
}
elif reward_type == "礼包":
package_config = config.get("礼包配置", {})
package_names = [name for name, info in package_config.items() if info.get("稀有度") == rarity]
if not package_names:
# 如果没有对应稀有度的礼包,给金币
coin_range = rarity_config.get("金币范围", [100, 300])
return {
"type": "coins",
"name": "金币",
"rarity": rarity,
"amount": random.randint(coin_range[0], coin_range[1])
}
package_name = random.choice(package_names)
package_info = package_config[package_name]
contents = []
# 生成礼包内容
content_config = package_info.get("内容", {})
if "金币" in content_config:
coin_range = content_config["金币"]
contents.append({
"type": "coins",
"amount": random.randint(coin_range[0], coin_range[1]),
"rarity": rarity
})
if "经验" in content_config:
exp_range = content_config["经验"]
contents.append({
"type": "exp",
"amount": random.randint(exp_range[0], exp_range[1]),
"rarity": rarity
})
if "种子数量" in content_config:
seed_count_range = content_config["种子数量"]
lower_rarity = {"优良": "普通", "稀有": "优良", "史诗": "稀有", "传奇": "史诗"}.get(rarity, "普通")
seeds = seed_pools.get(lower_rarity, [])
if seeds:
contents.append({
"type": "seed",
"name": random.choice(seeds),
"amount": random.randint(seed_count_range[0], seed_count_range[1]),
"rarity": rarity
})
return {
"type": "package", "type": "package",
"name": "成长套餐", "name": package_name,
"rarity": "优良", "rarity": rarity,
"amount": 1, "amount": 1,
"contents": [ "contents": contents
{"type": "coins", "amount": random.randint(200, 400)},
{"type": "exp", "amount": random.randint(100, 200)},
{"type": "seed", "name": random.choice(common_seeds) if common_seeds else "小麦", "amount": random.randint(2, 3)}
]
} }
elif reward_type == "rare": # 默认给金币
# 稀有奖励 coin_range = rarity_config.get("金币范围", [100, 300])
reward_choice = random.choice(["coins", "exp", "seed", "package"]) return {
if reward_choice == "coins":
reward = {
"type": "coins", "type": "coins",
"name": "金币", "name": "金币",
"rarity": "稀有", "rarity": rarity,
"amount": random.randint(600, 1000) "amount": random.randint(coin_range[0], coin_range[1])
} }
elif reward_choice == "exp":
reward = {
"type": "exp",
"name": "经验",
"rarity": "稀有",
"amount": random.randint(300, 500)
}
elif reward_choice == "seed":
if rare_seeds:
seed_name = random.choice(rare_seeds)
reward = {
"type": "seed",
"name": seed_name,
"rarity": "稀有",
"amount": random.randint(1, 2)
}
else:
reward = {
"type": "coins",
"name": "金币",
"rarity": "稀有",
"amount": random.randint(600, 1000)
}
else: # package
reward = {
"type": "package",
"name": "稀有礼包",
"rarity": "稀有",
"amount": 1,
"contents": [
{"type": "coins", "amount": random.randint(400, 700)},
{"type": "exp", "amount": random.randint(200, 350)},
{"type": "seed", "name": random.choice(good_seeds) if good_seeds else "番茄", "amount": random.randint(2, 3)}
]
}
elif reward_type == "epic":
# 史诗奖励
reward_choice = random.choice(["coins", "exp", "seed", "package"])
if reward_choice == "coins":
reward = {
"type": "coins",
"name": "金币",
"rarity": "史诗",
"amount": random.randint(1000, 1500)
}
elif reward_choice == "exp":
reward = {
"type": "exp",
"name": "经验",
"rarity": "史诗",
"amount": random.randint(500, 800)
}
elif reward_choice == "seed":
if epic_seeds:
seed_name = random.choice(epic_seeds)
reward = {
"type": "seed",
"name": seed_name,
"rarity": "史诗",
"amount": 1
}
else:
reward = {
"type": "coins",
"name": "金币",
"rarity": "史诗",
"amount": random.randint(1000, 1500)
}
else: # package
reward = {
"type": "package",
"name": "史诗礼包",
"rarity": "史诗",
"amount": 1,
"contents": [
{"type": "coins", "amount": random.randint(700, 1200)},
{"type": "exp", "amount": random.randint(350, 600)},
{"type": "seed", "name": random.choice(rare_seeds) if rare_seeds else "草莓", "amount": random.randint(1, 2)}
]
}
else: # legendary
# 传奇奖励
reward_choice = random.choice(["coins", "exp", "seed", "package"])
if reward_choice == "coins":
reward = {
"type": "coins",
"name": "金币",
"rarity": "传奇",
"amount": random.randint(1500, 2500)
}
elif reward_choice == "exp":
reward = {
"type": "exp",
"name": "经验",
"rarity": "传奇",
"amount": random.randint(800, 1200)
}
elif reward_choice == "seed":
if legendary_seeds:
seed_name = random.choice(legendary_seeds)
reward = {
"type": "seed",
"name": seed_name,
"rarity": "传奇",
"amount": 1
}
else:
reward = {
"type": "coins",
"name": "金币",
"rarity": "传奇",
"amount": random.randint(1500, 2500)
}
else: # package
reward = {
"type": "package",
"name": "传奇大礼包",
"rarity": "传奇",
"amount": 1,
"contents": [
{"type": "coins", "amount": random.randint(1000, 2000)},
{"type": "exp", "amount": random.randint(600, 1000)},
{"type": "seed", "name": random.choice(epic_seeds) if epic_seeds else "葡萄", "amount": 1},
{"type": "seed", "name": random.choice(rare_seeds) if rare_seeds else "草莓", "amount": random.randint(2, 3)}
]
}
# 确保所有奖励都有基本字段
if not reward.get("rarity"):
reward["rarity"] = "普通"
if not reward.get("amount"):
reward["amount"] = 0
if not reward.get("type"):
reward["type"] = "empty"
if not reward.get("name"):
reward["name"] = "未知奖励"
return reward
#应用幸运抽奖奖励到玩家数据 #应用幸运抽奖奖励到玩家数据
def _apply_lucky_draw_rewards(self, player_data, rewards): def _apply_lucky_draw_rewards(self, player_data, rewards):
@@ -7640,6 +7608,10 @@ class TCPGameServer(TCPServer):
"success": False, "success": False,
"message": message "message": message
}) })
#==========================稻草人系统处理==========================
#==========================智慧树系统处理========================== #==========================智慧树系统处理==========================
def _handle_wisdom_tree_operation(self, client_id, message): def _handle_wisdom_tree_operation(self, client_id, message):
@@ -8303,7 +8275,6 @@ class TCPGameServer(TCPServer):
# 更新杀虫时间为当前时间,避免重复扣血 # 更新杀虫时间为当前时间,避免重复扣血
wisdom_tree_config["距离上一次杀虫时间"] = current_time wisdom_tree_config["距离上一次杀虫时间"] = current_time
#==========================智慧树系统处理========================== #==========================智慧树系统处理==========================
#==========================稻草人系统处理==========================

View File

@@ -0,0 +1,82 @@
{
"基础奖励": {
"金币": {
"最小值": 200,
"最大值": 500,
"图标": "💰",
"颜色": "#FFD700"
},
"经验": {
"最小值": 50,
"最大值": 120,
"图标": "⭐",
"颜色": "#00BFFF"
}
},
"种子奖励": {
"普通": {
"概率": 0.6,
"数量范围": [2, 5],
"种子池": ["小麦", "胡萝卜", "土豆", "稻谷"]
},
"优良": {
"概率": 0.25,
"数量范围": [2, 4],
"种子池": ["玉米", "番茄", "洋葱", "大豆", "豌豆", "黄瓜", "大白菜"]
},
"稀有": {
"概率": 0.12,
"数量范围": [1, 3],
"种子池": ["草莓", "花椰菜", "柿子", "蓝莓", "树莓"]
},
"史诗": {
"概率": 0.025,
"数量范围": [1, 2],
"种子池": ["葡萄", "南瓜", "芦笋", "茄子", "向日葵", "蕨菜"]
},
"传奇": {
"概率": 0.005,
"数量范围": [1, 1],
"种子池": ["西瓜", "甘蔗", "香草", "甜菜", "人参", "富贵竹", "芦荟", "哈密瓜"]
}
},
"连续签到奖励": {
"第3天": {
"额外金币": 100,
"额外经验": 50,
"描述": "连续签到奖励"
},
"第7天": {
"额外金币": 200,
"额外经验": 100,
"描述": "一周连击奖励"
},
"第14天": {
"额外金币": 500,
"额外经验": 200,
"描述": "半月连击奖励"
},
"第21天": {
"额外金币": 800,
"额外经验": 300,
"描述": "三周连击奖励"
},
"第30天": {
"额外金币": 1500,
"额外经验": 500,
"描述": "满月连击奖励"
}
},
"连击倍率": {
"启用": true,
"基础倍率": 1.0,
"每日递增": 0.1,
"最大倍率": 3.0,
"说明": "连续签到可提升奖励倍率"
},
"历史记录": {
"保存天数": 30,
"清理规则": "超过30天的记录自动清理",
"格式": "年月日时分秒: 奖励描述"
}
}

View File

@@ -0,0 +1,113 @@
{
"抽奖费用": {
"单抽": 800,
"五连抽": 3600,
"十连抽": 6400
},
"概率配置": {
"普通": {
"概率": 0.45,
"金币范围": [100, 300],
"经验范围": [50, 150],
"种子数量": [2, 4]
},
"优良": {
"概率": 0.25,
"金币范围": [300, 600],
"经验范围": [150, 300],
"种子数量": [1, 3]
},
"稀有": {
"概率": 0.12,
"金币范围": [600, 1000],
"经验范围": [300, 500],
"种子数量": [1, 2]
},
"史诗": {
"概率": 0.025,
"金币范围": [1000, 1500],
"经验范围": [500, 800],
"种子数量": [1, 1]
},
"传奇": {
"概率": 0.005,
"金币范围": [1500, 2500],
"经验范围": [800, 1200],
"种子数量": [1, 1]
},
"空奖": {
"概率": 0.15,
"提示语": ["谢谢惠顾", "下次再来", "再试一次", "继续努力"]
}
},
"礼包配置": {
"成长套餐": {
"稀有度": "优良",
"内容": {
"金币": [200, 400],
"经验": [100, 200],
"种子数量": [2, 3]
}
},
"稀有礼包": {
"稀有度": "稀有",
"内容": {
"金币": [400, 700],
"经验": [200, 350],
"种子数量": [2, 3]
}
},
"史诗礼包": {
"稀有度": "史诗",
"内容": {
"金币": [700, 1200],
"经验": [350, 600],
"种子数量": [1, 2]
}
},
"传奇大礼包": {
"稀有度": "传奇",
"内容": {
"金币": [1000, 2000],
"经验": [600, 1000],
"史诗种子数量": [1, 1],
"稀有种子数量": [2, 3]
}
}
},
"保底机制": {
"十连抽保底": true,
"保底最低稀有度": "稀有"
},
"奖励类型权重": {
"普通": {
"金币": 0.4,
"经验": 0.3,
"种子": 0.3
},
"优良": {
"金币": 0.3,
"经验": 0.2,
"种子": 0.3,
"礼包": 0.2
},
"稀有": {
"金币": 0.2,
"经验": 0.2,
"种子": 0.4,
"礼包": 0.2
},
"史诗": {
"金币": 0.2,
"经验": 0.2,
"种子": 0.4,
"礼包": 0.2
},
"传奇": {
"金币": 0.1,
"经验": 0.1,
"种子": 0.5,
"礼包": 0.3
}
}
}

View File

@@ -1,13 +1,13 @@
{ {
"experience": 1858, "experience": 1826,
"level": 26, "level": 27,
"money": 1223582, "money": 1214966,
"farm_name": "柚大青の小农场", "farm_name": "柚大青の小农场",
"player_name": "柚大青", "player_name": "柚大青",
"user_name": "2143323382", "user_name": "2143323382",
"user_password": "tyh@19900420", "user_password": "tyh@19900420",
"last_login_time": "2025年07月09日19时17分38秒", "last_login_time": "2025年07月12日21时05分43秒",
"total_login_time": "5时0分7秒", "total_login_time": "5时10分30秒",
"farm_lots": [ "farm_lots": [
{ {
"crop_type": "", "crop_type": "",
@@ -560,286 +560,23 @@
"土地等级": 0 "土地等级": 0
} }
], ],
"player_bag": [], "player_bag": [
{
"name": "稻谷",
"quality": "普通",
"count": 2
},
{
"name": "土豆",
"quality": "普通",
"count": 3
}
],
"total_likes": 3, "total_likes": 3,
"last_water_reset_date": "2025-06-05", "last_water_reset_date": "2025-06-05",
"daily_check_in": {
"2025-06-03": {
"rewards": {
"coins": 259,
"exp": 75,
"seeds": [
{
"name": "土豆",
"quantity": 5,
"quality": "普通"
},
{
"name": "小麦",
"quantity": 4,
"quality": "普通"
},
{
"name": "稻谷",
"quantity": 4,
"quality": "普通"
}
]
},
"consecutive_days": 0,
"timestamp": 1748950405.029992
},
"2025-06-04": {
"rewards": {
"coins": 455,
"exp": 93,
"seeds": [
{
"name": "小麦",
"quantity": 3,
"quality": "普通"
},
{
"name": "胡萝卜",
"quantity": 3,
"quality": "普通"
}
]
},
"consecutive_days": 1,
"timestamp": 1749033203.8079362
},
"2025-06-08": {
"rewards": {
"coins": 376,
"exp": 83,
"seeds": [
{
"name": "胡萝卜",
"quantity": 3,
"quality": "普通"
}
]
},
"consecutive_days": 0,
"timestamp": 1749387590.7727287
},
"2025-06-15": {
"rewards": {
"coins": 329,
"exp": 58,
"seeds": [
{
"name": "胡萝卜",
"quantity": 3,
"quality": "普通"
},
{
"name": "稻谷",
"quantity": 2,
"quality": "普通"
},
{
"name": "土豆",
"quantity": 5,
"quality": "普通"
}
]
},
"consecutive_days": 0,
"timestamp": 1749994853.8761835
},
"2025-06-16": {
"rewards": {
"coins": 219,
"exp": 107,
"seeds": [
{
"name": "稻谷",
"quantity": 5,
"quality": "普通"
},
{
"name": "胡萝卜",
"quantity": 4,
"quality": "普通"
}
]
},
"consecutive_days": 1,
"timestamp": 1750048317.4814892
},
"2025-06-17": {
"rewards": {
"coins": 292,
"exp": 125,
"seeds": [
{
"name": "胡萝卜",
"quantity": 2,
"quality": "普通"
},
{
"name": "小麦",
"quantity": 4,
"quality": "普通"
},
{
"name": "土豆",
"quantity": 5,
"quality": "普通"
}
]
},
"consecutive_days": 2,
"timestamp": 1750171931.7031996
},
"2025-06-19": {
"rewards": {
"coins": 325,
"exp": 93,
"seeds": [
{
"name": "小麦",
"quantity": 4,
"quality": "普通"
}
]
},
"consecutive_days": 0,
"timestamp": 1750313565.2168045
},
"2025-06-20": {
"rewards": {
"coins": 491,
"exp": 119,
"seeds": [
{
"name": "稻谷",
"quantity": 3,
"quality": "普通"
},
{
"name": "胡萝卜",
"quantity": 3,
"quality": "普通"
},
{
"name": "小麦",
"quantity": 2,
"quality": "普通"
}
]
},
"consecutive_days": 1,
"timestamp": 1750391114.5208066
},
"2025-06-21": {
"rewards": {
"coins": 419,
"exp": 111,
"seeds": [
{
"name": "小麦",
"quantity": 2,
"quality": "普通"
},
{
"name": "胡萝卜",
"quantity": 4,
"quality": "普通"
},
{
"name": "稻谷",
"quantity": 3,
"quality": "普通"
}
]
},
"consecutive_days": 2,
"timestamp": 1750474647.3564475
},
"2025-06-22": {
"rewards": {
"coins": 312,
"exp": 128,
"seeds": [
{
"name": "番茄",
"quantity": 5,
"quality": "优良"
},
{
"name": "豌豆",
"quantity": 5,
"quality": "优良"
},
{
"name": "玉米",
"quantity": 2,
"quality": "优良"
}
],
"bonus_coins": 100
},
"consecutive_days": 3,
"timestamp": 1750595733.8604188
},
"2025-06-23": {
"rewards": {
"coins": 403,
"exp": 67,
"seeds": [
{
"name": "大豆",
"quantity": 2,
"quality": "优良"
},
{
"name": "番茄",
"quantity": 4,
"quality": "优良"
}
],
"bonus_coins": 100
},
"consecutive_days": 4,
"timestamp": 1750645219.0674949
},
"2025-06-25": {
"rewards": {
"coins": 285,
"exp": 71,
"seeds": [
{
"name": "胡萝卜",
"quantity": 2,
"quality": "普通"
}
]
},
"consecutive_days": 0,
"timestamp": 1750843274.268298
},
"2025-06-27": {
"rewards": {
"coins": 264,
"exp": 71,
"seeds": [
{
"name": "土豆",
"quantity": 3,
"quality": "普通"
}
]
},
"consecutive_days": 0,
"timestamp": 1750985100.9851904
}
},
"体力值": 20, "体力值": 20,
"体力上次刷新时间": "2025-07-09", "体力上次刷新时间": "2025-07-12",
"体力上次恢复时间": 1752023968.6234932, "体力上次恢复时间": 1752323298.9468062,
"new_player_gift_claimed": true, "new_player_gift_claimed": true,
"new_player_gift_time": "2025-06-08 20:58:40", "new_player_gift_time": "2025-06-08 20:58:40",
"daily_likes": { "daily_likes": {
@@ -971,6 +708,11 @@
"start_time": 1752023968.623608, "start_time": 1752023968.623608,
"claimed_gifts": {}, "claimed_gifts": {},
"total_online_time": 1282.0 "total_online_time": 1282.0
},
"2025-07-12": {
"start_time": 1752323298.9470074,
"claimed_gifts": {},
"total_online_time": 623.0
} }
}, },
"注册时间": "2025年05月21日15时00分00秒", "注册时间": "2025年05月21日15时00分00秒",
@@ -1083,12 +825,8 @@
} }
} }
], ],
"巡逻宠物": [ "巡逻宠物": ["1751716398095"],
"1751716398095" "出战宠物": ["1751716398095"],
],
"出战宠物": [
"1751716398095"
],
"稻草人配置": { "稻草人配置": {
"已拥有稻草人类型": [ "已拥有稻草人类型": [
"稻草人1" "稻草人1"
@@ -1126,5 +864,8 @@
"最大经验值": 480, "最大经验值": 480,
"最大生命值": 106, "最大生命值": 106,
"当前生命值": 106 "当前生命值": 106
},
"签到历史": {
"2025年07月12日21时05分47秒": "金币249 经验75 土豆x3"
} }
} }

View File

@@ -557,16 +557,13 @@
"player_name": "树萌芽", "player_name": "树萌芽",
"level": 63, "level": 63,
"money": 615397111148, "money": 615397111148,
"last_login_time": "2025年07月12日18时58分12秒", "last_login_time": "2025年07月12日19时41分20秒",
"total_login_time": "161时31分59秒", "total_login_time": "161时39分12秒",
"user_name": "3205788256", "user_name": "3205788256",
"user_password": "tyh@19900420", "user_password": "tyh@19900420",
"last_water_reset_date": "2025-06-06", "last_water_reset_date": "2025-06-06",
"daily_likes": {}, "daily_likes": {},
"last_check_in_date": "2025-06-01", "last_check_in_date": "2025-06-01",
"check_in_count": 1,
"daily_check_in": {},
"lucky_draw_history": [],
"total_likes": 1, "total_likes": 1,
"体力值": 20, "体力值": 20,
"体力上次刷新时间": "2025-07-12", "体力上次刷新时间": "2025-07-12",
@@ -574,7 +571,13 @@
"new_player_gift_claimed": true, "new_player_gift_claimed": true,
"new_player_gift_time": "2025-06-08 19:22:41", "new_player_gift_time": "2025-06-08 19:22:41",
"session_start_time": 1749878790.288913, "session_start_time": 1749878790.288913,
"online_gift": {}, "online_gift": {
"2025-07-12": {
"start_time": 1752319030.8083963,
"claimed_gifts": {},
"total_online_time": 433.0
}
},
"个人简介": "人生啊,就这样吧", "个人简介": "人生啊,就这样吧",
"注册时间": "2025年05月21日15时00分00秒", "注册时间": "2025年05月21日15时00分00秒",
"作物仓库": [], "作物仓库": [],