天气系统完成
This commit is contained in:
@@ -320,45 +320,51 @@ func _create_crop_button(crop_name: String, crop_quality: String) -> Button:
|
||||
|
||||
# 正常模式下的成熟物点击处理
|
||||
func _on_crop_selected(crop_name, crop_count):
|
||||
# 显示成熟物信息
|
||||
var info_text = ""
|
||||
|
||||
if main_game.can_planted_crop.has(crop_name):
|
||||
var crop = main_game.can_planted_crop[crop_name]
|
||||
var display_name = crop_name
|
||||
var mature_name = crop.get("成熟物名称")
|
||||
if mature_name != null and mature_name != "":
|
||||
display_name = mature_name
|
||||
else:
|
||||
display_name = crop.get("作物名称", crop_name)
|
||||
var quality = crop.get("品质", "未知")
|
||||
var price = crop.get("花费", 0)
|
||||
var grow_time = crop.get("生长时间", 0)
|
||||
var profit = crop.get("收益", 0)
|
||||
var level_req = crop.get("等级", 1)
|
||||
|
||||
# 将成熟时间转换为可读格式
|
||||
var time_str = ""
|
||||
var total_seconds = int(grow_time)
|
||||
var hours = total_seconds / 3600
|
||||
var minutes = (total_seconds % 3600) / 60
|
||||
var seconds = total_seconds % 60
|
||||
|
||||
if hours > 0:
|
||||
time_str += str(hours) + "小时"
|
||||
if minutes > 0:
|
||||
time_str += str(minutes) + "分钟"
|
||||
if seconds > 0:
|
||||
time_str += str(seconds) + "秒"
|
||||
|
||||
info_text = quality + "-" + display_name + " (数量: " + str(crop_count) + ")\n"
|
||||
info_text += "原价格: " + str(price) + "元, 原收益: " + str(profit) + "元\n"
|
||||
info_text += "成熟时间: " + time_str + ", 需求等级: " + str(level_req) + "\n"
|
||||
info_text += "这是收获的成熟品,可以用于出售或其他用途"
|
||||
# 获取作物信息面板的引用
|
||||
var crop_inform_panel = get_node("/root/main/UI/SmallPanel/CropInformPanel")
|
||||
if crop_inform_panel and crop_inform_panel.has_method("show_crop_info"):
|
||||
# 打开作物信息面板并传递作物数据
|
||||
crop_inform_panel.show_crop_info(crop_name, crop_count)
|
||||
else:
|
||||
info_text = crop_name + " (数量: " + str(crop_count) + ")"
|
||||
|
||||
Toast.show(info_text, Color.GOLD, 3.0, 1.0)
|
||||
# 如果作物信息面板不可用,显示Toast作为后备方案
|
||||
var info_text = ""
|
||||
|
||||
if main_game.can_planted_crop.has(crop_name):
|
||||
var crop = main_game.can_planted_crop[crop_name]
|
||||
var display_name = crop_name
|
||||
var mature_name = crop.get("成熟物名称")
|
||||
if mature_name != null and mature_name != "":
|
||||
display_name = mature_name
|
||||
else:
|
||||
display_name = crop.get("作物名称", crop_name)
|
||||
var quality = crop.get("品质", "未知")
|
||||
var price = crop.get("花费", 0)
|
||||
var grow_time = crop.get("生长时间", 0)
|
||||
var profit = crop.get("收益", 0)
|
||||
var level_req = crop.get("等级", 1)
|
||||
|
||||
# 将成熟时间转换为可读格式
|
||||
var time_str = ""
|
||||
var total_seconds = int(grow_time)
|
||||
var hours = total_seconds / 3600
|
||||
var minutes = (total_seconds % 3600) / 60
|
||||
var seconds = total_seconds % 60
|
||||
|
||||
if hours > 0:
|
||||
time_str += str(hours) + "小时"
|
||||
if minutes > 0:
|
||||
time_str += str(minutes) + "分钟"
|
||||
if seconds > 0:
|
||||
time_str += str(seconds) + "秒"
|
||||
|
||||
info_text = quality + "-" + display_name + " (数量: " + str(crop_count) + ")\n"
|
||||
info_text += "原价格: " + str(price) + "元, 原收益: " + str(profit) + "元\n"
|
||||
info_text += "成熟时间: " + time_str + ", 需求等级: " + str(level_req) + "\n"
|
||||
info_text += "这是收获的成熟品,可以用于出售或其他用途"
|
||||
else:
|
||||
info_text = crop_name + " (数量: " + str(crop_count) + ")"
|
||||
|
||||
Toast.show(info_text, Color.GOLD, 3.0, 1.0)
|
||||
|
||||
# 访问模式下的成熟物点击处理
|
||||
func _on_visit_crop_selected(crop_name, crop_count):
|
||||
|
||||
@@ -1,35 +1,52 @@
|
||||
#玩家登录注册面板
|
||||
extends PanelContainer
|
||||
|
||||
#玩家登录账号,用QQ号代替
|
||||
@onready var username_input : LineEdit = $VBox/UserName/username_input
|
||||
#用户登录密码
|
||||
@onready var password_input : LineEdit = $VBox/Password1/password_input
|
||||
#登录按钮
|
||||
@onready var login_button : Button = $VBox/LoginRegister/login_button
|
||||
#默认显示登录面板(登录面板可以进入注册面板和忘记密码面板)
|
||||
@onready var login_v_box: VBoxContainer = $LoginVBox #显示或隐藏登录面板
|
||||
@onready var user_name: HBoxContainer = $LoginVBox/UserName #玩家账号
|
||||
@onready var password: HBoxContainer = $LoginVBox/Password #玩家密码
|
||||
@onready var login_button: Button = $LoginVBox/LoginButton #登录按钮
|
||||
@onready var register_button: Button = $LoginVBox/RegisterButton #注册按钮,点击后隐藏登录面板显示注册面板
|
||||
@onready var forget_passwd_button: Button = $LoginVBox/ForgetPasswdButton #忘记密码按钮,点击后隐藏登录面板显示忘记密码面板
|
||||
@onready var status_label: Label = $LoginVBox/status_label #登录状态
|
||||
|
||||
#下面是注册相关的
|
||||
#注册按钮
|
||||
@onready var register_button : Button = $VBox/LoginRegister/register_button
|
||||
#注册账号时二次确认密码
|
||||
@onready var password_input_2 : LineEdit = $VBox/Password2/password_input2
|
||||
#农场名称
|
||||
@onready var farmname_input : LineEdit = $VBox/FarmName/farmname_input
|
||||
#玩家昵称
|
||||
@onready var playername_input :LineEdit = $VBox/PlayerName/playername_input
|
||||
#邮箱验证码
|
||||
@onready var verificationcode_input :LineEdit = $VBox/VerificationCode/verificationcode_input
|
||||
#发送验证码按钮
|
||||
@onready var send_button :Button = $VBox/VerificationCode/SendButton
|
||||
#状态提示标签
|
||||
@onready var status_label : Label = $VBox/status_label
|
||||
# 登录面板输入框
|
||||
@onready var username_input: LineEdit = $LoginVBox/UserName/username_input
|
||||
@onready var password_input: LineEdit = $LoginVBox/Password/password_input
|
||||
|
||||
#注册面板,注册成功跳转回登录面板
|
||||
@onready var register_vbox: VBoxContainer = $RegisterVbox #显示或隐藏注册面板
|
||||
@onready var register_user_name: HBoxContainer = $RegisterVbox/RegisterUserName #注册玩家账号
|
||||
@onready var password_1: HBoxContainer = $RegisterVbox/Password1 #注册密码
|
||||
@onready var password_2: HBoxContainer = $RegisterVbox/Password2 #二次确认密码
|
||||
@onready var player_name: HBoxContainer = $RegisterVbox/PlayerName #注册玩家昵称
|
||||
@onready var farm_name: HBoxContainer = $RegisterVbox/FarmName #注册玩家农场名称
|
||||
@onready var verification_code: HBoxContainer = $RegisterVbox/VerificationCode #注册所需验证码
|
||||
@onready var register_button_2: Button = $RegisterVbox/RegisterButton2 #注册按钮
|
||||
@onready var status_label_2: Label = $RegisterVbox/status_label2 #注册状态
|
||||
|
||||
@onready var password_2: HBoxContainer = $VBox/Password2
|
||||
@onready var verification_code: HBoxContainer = $VBox/VerificationCode
|
||||
@onready var player_name: HBoxContainer = $VBox/PlayerName
|
||||
@onready var farm_name: HBoxContainer = $VBox/FarmName
|
||||
# 注册面板输入框
|
||||
@onready var register_username_input: LineEdit = $RegisterVbox/RegisterUserName/username_input
|
||||
@onready var password_input_1: LineEdit = $RegisterVbox/Password1/password_input
|
||||
@onready var password_input_2: LineEdit = $RegisterVbox/Password2/password_input2
|
||||
@onready var playername_input: LineEdit = $RegisterVbox/PlayerName/playername_input
|
||||
@onready var farmname_input: LineEdit = $RegisterVbox/FarmName/farmname_input
|
||||
@onready var verificationcode_input: LineEdit = $RegisterVbox/VerificationCode/verificationcode_input
|
||||
@onready var send_button: Button = $RegisterVbox/VerificationCode/SendButton
|
||||
|
||||
#忘记密码面板,设置新密码成功后同样跳转到登录面板
|
||||
@onready var forget_password_vbox: VBoxContainer = $ForgetPasswordVbox #显示或隐藏忘记密码面板
|
||||
@onready var forget_password_user_name: HBoxContainer = $ForgetPasswordVbox/ForgetPasswordUserName #忘记密码的玩家账号
|
||||
@onready var new_password: HBoxContainer = $ForgetPasswordVbox/NewPassword #设置该账号新的密码
|
||||
@onready var verification_code_2: HBoxContainer = $ForgetPasswordVbox/VerificationCode2 #忘记密码所需验证码
|
||||
@onready var forget_password_button: Button = $ForgetPasswordVbox/ForgetPasswordButton #设置新密码确认按钮
|
||||
@onready var status_label_3: Label = $ForgetPasswordVbox/status_label3 #设置新密码状态
|
||||
|
||||
# 忘记密码面板输入框
|
||||
@onready var forget_username_input: LineEdit = $ForgetPasswordVbox/ForgetPasswordUserName/username_input
|
||||
@onready var new_password_input: LineEdit = $ForgetPasswordVbox/NewPassword/password_input
|
||||
@onready var forget_verificationcode_input: LineEdit = $ForgetPasswordVbox/VerificationCode2/verificationcode_input
|
||||
@onready var forget_send_button: Button = $ForgetPasswordVbox/VerificationCode2/SendButton
|
||||
|
||||
|
||||
# 记住密码选项
|
||||
@@ -53,16 +70,20 @@ var remember_password : bool = true # 默认记住密码
|
||||
# 准备函数
|
||||
func _ready():
|
||||
self.show()
|
||||
#隐藏注册相关UI
|
||||
password_2.hide()
|
||||
verification_code.hide()
|
||||
player_name.hide()
|
||||
farm_name.hide()
|
||||
|
||||
# 初始状态:只显示登录面板,隐藏注册和忘记密码面板
|
||||
login_v_box.show()
|
||||
register_vbox.hide()
|
||||
forget_password_vbox.hide()
|
||||
|
||||
# 连接按钮信号
|
||||
login_button.pressed.connect(self._on_login_button_pressed)
|
||||
register_button.pressed.connect(self._on_register_button_pressed)
|
||||
register_button.pressed.connect(self._on_show_register_panel)
|
||||
forget_passwd_button.pressed.connect(self._on_forget_password_button_pressed)
|
||||
register_button_2.pressed.connect(self._on_register_button_2_pressed)
|
||||
forget_password_button.pressed.connect(self._on_forget_password_confirm_pressed)
|
||||
send_button.pressed.connect(self._on_send_button_pressed)
|
||||
forget_send_button.pressed.connect(self._on_forget_send_button_pressed)
|
||||
|
||||
# 加载保存的登录信息
|
||||
_load_login_info()
|
||||
@@ -70,6 +91,23 @@ func _ready():
|
||||
# 显示客户端版本号
|
||||
_display_version_info()
|
||||
|
||||
# 面板切换函数
|
||||
func _on_show_register_panel():
|
||||
"""切换到注册面板"""
|
||||
login_v_box.hide()
|
||||
register_vbox.show()
|
||||
forget_password_vbox.hide()
|
||||
status_label_2.text = "请填写注册信息"
|
||||
status_label_2.modulate = Color.WHITE
|
||||
|
||||
func _on_forget_password_button_pressed():
|
||||
"""切换到忘记密码面板"""
|
||||
login_v_box.hide()
|
||||
register_vbox.hide()
|
||||
forget_password_vbox.show()
|
||||
status_label_3.text = "请输入账号和新密码"
|
||||
status_label_3.modulate = Color.WHITE
|
||||
|
||||
# 处理登录按钮点击
|
||||
func _on_login_button_pressed():
|
||||
password_2.hide()
|
||||
@@ -129,32 +167,30 @@ func _on_login_button_pressed():
|
||||
|
||||
# 处理验证码发送按钮点击
|
||||
func _on_send_button_pressed():
|
||||
|
||||
|
||||
var user_name = username_input.text.strip_edges()
|
||||
var user_name = register_username_input.text.strip_edges()
|
||||
|
||||
if user_name == "":
|
||||
status_label.text = "请输入QQ号以接收验证码!"
|
||||
status_label.modulate = Color.RED
|
||||
status_label_2.text = "请输入QQ号以接收验证码!"
|
||||
status_label_2.modulate = Color.RED
|
||||
return
|
||||
|
||||
if !is_valid_qq_number(user_name):
|
||||
status_label.text = "请输入正确的QQ号码(5-12位数字)!"
|
||||
status_label.modulate = Color.RED
|
||||
status_label_2.text = "请输入正确的QQ号码(5-12位数字)!"
|
||||
status_label_2.modulate = Color.RED
|
||||
return
|
||||
|
||||
# 检查网络连接状态
|
||||
if !tcp_network_manager_panel.client.is_client_connected():
|
||||
status_label.text = "未连接到服务器,正在尝试连接..."
|
||||
status_label.modulate = Color.YELLOW
|
||||
status_label_2.text = "未连接到服务器,正在尝试连接..."
|
||||
status_label_2.modulate = Color.YELLOW
|
||||
# 尝试自动连接到服务器
|
||||
tcp_network_manager_panel.connect_to_current_server()
|
||||
await get_tree().create_timer(2.0).timeout
|
||||
|
||||
# 再次检查连接状态
|
||||
if !tcp_network_manager_panel.client.is_client_connected():
|
||||
status_label.text = "连接服务器失败,正在尝试其他服务器..."
|
||||
status_label.modulate = Color.YELLOW
|
||||
status_label_2.text = "连接服务器失败,正在尝试其他服务器..."
|
||||
status_label_2.modulate = Color.YELLOW
|
||||
# 等待自动服务器切换完成
|
||||
await get_tree().create_timer(3.0).timeout
|
||||
|
||||
@@ -162,8 +198,8 @@ func _on_send_button_pressed():
|
||||
# 禁用按钮,防止重复点击
|
||||
send_button.disabled = true
|
||||
|
||||
status_label.text = "正在发送验证码,请稍候..."
|
||||
status_label.modulate = Color.YELLOW
|
||||
status_label_2.text = "正在发送验证码,请稍候..."
|
||||
status_label_2.modulate = Color.YELLOW
|
||||
|
||||
# 发送验证码请求
|
||||
tcp_network_manager_panel.sendVerificationCodeRequest(user_name)
|
||||
@@ -179,19 +215,14 @@ func _on_send_button_pressed():
|
||||
send_button.disabled = false
|
||||
send_button.text = "发送验证码"
|
||||
|
||||
if status_label.text == "正在发送验证码,请稍候...":
|
||||
status_label.text = "验证码发送超时,请重试!"
|
||||
status_label.modulate = Color.RED
|
||||
if status_label_2.text == "正在发送验证码,请稍候...":
|
||||
status_label_2.text = "验证码发送超时,请重试!"
|
||||
status_label_2.modulate = Color.RED
|
||||
|
||||
# 处理注册按钮点击
|
||||
func _on_register_button_pressed():
|
||||
password_2.show()
|
||||
verification_code.show()
|
||||
player_name.show()
|
||||
farm_name.show()
|
||||
|
||||
var user_name = username_input.text.strip_edges()
|
||||
var user_password = password_input.text.strip_edges()
|
||||
func _on_register_button_2_pressed():
|
||||
var user_name = register_username_input.text.strip_edges()
|
||||
var user_password = password_input_1.text.strip_edges()
|
||||
var user_password_2 = password_input_2.text.strip_edges()
|
||||
var farmname = farmname_input.text.strip_edges()
|
||||
var player_name = playername_input.text.strip_edges()
|
||||
@@ -199,69 +230,180 @@ func _on_register_button_pressed():
|
||||
|
||||
# 检查密码格式(只允许数字和字母)
|
||||
if not is_valid_password(user_password):
|
||||
status_label.text = "密码只能包含数字和字母!"
|
||||
status_label.modulate = Color.RED
|
||||
status_label_2.text = "密码只能包含数字和字母!"
|
||||
status_label_2.modulate = Color.RED
|
||||
return
|
||||
|
||||
if user_name == "" or user_password == "":
|
||||
status_label.text = "用户名或密码不能为空!"
|
||||
status_label.modulate = Color.RED
|
||||
status_label_2.text = "用户名或密码不能为空!"
|
||||
status_label_2.modulate = Color.RED
|
||||
return
|
||||
if farmname == "":
|
||||
status_label.text = "农场名称不能为空!"
|
||||
status_label.modulate = Color.RED
|
||||
status_label_2.text = "农场名称不能为空!"
|
||||
status_label_2.modulate = Color.RED
|
||||
return
|
||||
if user_password != user_password_2:
|
||||
status_label.text = "两次输入的密码不一致!"
|
||||
status_label.modulate = Color.RED
|
||||
status_label_2.text = "两次输入的密码不一致!"
|
||||
status_label_2.modulate = Color.RED
|
||||
return
|
||||
|
||||
if !is_valid_qq_number(user_name):
|
||||
status_label.text = "请输入正确的QQ号码(5-12位数字)!"
|
||||
status_label.modulate = Color.RED
|
||||
status_label_2.text = "请输入正确的QQ号码(5-12位数字)!"
|
||||
status_label_2.modulate = Color.RED
|
||||
return
|
||||
|
||||
if verification_code == "":
|
||||
status_label.text = "请输入验证码!"
|
||||
status_label.modulate = Color.RED
|
||||
status_label_2.text = "请输入验证码!"
|
||||
status_label_2.modulate = Color.RED
|
||||
return
|
||||
|
||||
# 检查网络连接状态
|
||||
# 检查网络连接状态
|
||||
if !tcp_network_manager_panel.client.is_client_connected():
|
||||
status_label.text = "未连接到服务器,正在尝试连接..."
|
||||
status_label.modulate = Color.YELLOW
|
||||
status_label_2.text = "未连接到服务器,正在尝试连接..."
|
||||
status_label_2.modulate = Color.YELLOW
|
||||
# 尝试自动连接到服务器
|
||||
tcp_network_manager_panel.connect_to_current_server()
|
||||
await get_tree().create_timer(2.0).timeout
|
||||
|
||||
# 再次检查连接状态
|
||||
if !tcp_network_manager_panel.client.is_client_connected():
|
||||
status_label.text = "连接服务器失败,正在尝试其他服务器..."
|
||||
status_label.modulate = Color.YELLOW
|
||||
status_label_2.text = "连接服务器失败,正在尝试其他服务器..."
|
||||
status_label_2.modulate = Color.YELLOW
|
||||
# 等待自动服务器切换完成
|
||||
await get_tree().create_timer(3.0).timeout
|
||||
|
||||
|
||||
# 禁用按钮,防止重复点击
|
||||
register_button.disabled = true
|
||||
register_button_2.disabled = true
|
||||
|
||||
status_label.text = "正在注册,请稍候..."
|
||||
status_label.modulate = Color.YELLOW
|
||||
status_label_2.text = "正在注册,请稍候..."
|
||||
status_label_2.modulate = Color.YELLOW
|
||||
|
||||
# 发送注册请求
|
||||
# 发送注册请求
|
||||
tcp_network_manager_panel.sendRegisterInfo(user_name, user_password, farmname, player_name, verification_code)
|
||||
|
||||
|
||||
# 更新主游戏数据
|
||||
main_game.user_name = user_name
|
||||
main_game.user_password = user_password
|
||||
main_game.farmname = farmname
|
||||
# farmname 直接在注册成功后通过UI更新,这里不需要设置
|
||||
|
||||
# 5秒后重新启用按钮(如果没有收到响应)
|
||||
await get_tree().create_timer(5.0).timeout
|
||||
if register_button.disabled:
|
||||
register_button.disabled = false
|
||||
status_label.text = "注册超时,请重试!"
|
||||
status_label.modulate = Color.RED
|
||||
if register_button_2.disabled:
|
||||
register_button_2.disabled = false
|
||||
status_label_2.text = "注册超时,请重试!"
|
||||
status_label_2.modulate = Color.RED
|
||||
|
||||
# 忘记密码发送验证码按钮处理
|
||||
func _on_forget_send_button_pressed():
|
||||
var user_name = forget_username_input.text.strip_edges()
|
||||
|
||||
if user_name == "":
|
||||
status_label_3.text = "请输入QQ号以接收验证码!"
|
||||
status_label_3.modulate = Color.RED
|
||||
return
|
||||
|
||||
if !is_valid_qq_number(user_name):
|
||||
status_label_3.text = "请输入正确的QQ号码(5-12位数字)!"
|
||||
status_label_3.modulate = Color.RED
|
||||
return
|
||||
|
||||
# 检查网络连接状态
|
||||
if !tcp_network_manager_panel.client.is_client_connected():
|
||||
status_label_3.text = "未连接到服务器,正在尝试连接..."
|
||||
status_label_3.modulate = Color.YELLOW
|
||||
# 尝试自动连接到服务器
|
||||
tcp_network_manager_panel.connect_to_current_server()
|
||||
await get_tree().create_timer(2.0).timeout
|
||||
|
||||
# 再次检查连接状态
|
||||
if !tcp_network_manager_panel.client.is_client_connected():
|
||||
status_label_3.text = "连接服务器失败,正在尝试其他服务器..."
|
||||
status_label_3.modulate = Color.YELLOW
|
||||
# 等待自动服务器切换完成
|
||||
await get_tree().create_timer(3.0).timeout
|
||||
|
||||
# 禁用按钮,防止重复点击
|
||||
forget_send_button.disabled = true
|
||||
|
||||
status_label_3.text = "正在发送验证码,请稍候..."
|
||||
status_label_3.modulate = Color.YELLOW
|
||||
|
||||
# 发送验证码请求(用于忘记密码)
|
||||
tcp_network_manager_panel.sendForgetPasswordVerificationCode(user_name)
|
||||
|
||||
# 60秒后重新启用按钮
|
||||
var timer = 60
|
||||
while timer > 0 and forget_send_button.disabled:
|
||||
forget_send_button.text = "重新发送(%d)" % timer
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
timer -= 1
|
||||
|
||||
if forget_send_button.disabled:
|
||||
forget_send_button.disabled = false
|
||||
forget_send_button.text = "发送验证码"
|
||||
|
||||
if status_label_3.text == "正在发送验证码,请稍候...":
|
||||
status_label_3.text = "验证码发送超时,请重试!"
|
||||
status_label_3.modulate = Color.RED
|
||||
|
||||
# 忘记密码确认按钮处理
|
||||
func _on_forget_password_confirm_pressed():
|
||||
var user_name = forget_username_input.text.strip_edges()
|
||||
var new_password = new_password_input.text.strip_edges()
|
||||
var verification_code = forget_verificationcode_input.text.strip_edges()
|
||||
|
||||
# 检查密码格式(只允许数字和字母)
|
||||
if not is_valid_password(new_password):
|
||||
status_label_3.text = "密码只能包含数字和字母!"
|
||||
status_label_3.modulate = Color.RED
|
||||
return
|
||||
|
||||
if user_name == "" or new_password == "":
|
||||
status_label_3.text = "用户名或新密码不能为空!"
|
||||
status_label_3.modulate = Color.RED
|
||||
return
|
||||
|
||||
if !is_valid_qq_number(user_name):
|
||||
status_label_3.text = "请输入正确的QQ号码(5-12位数字)!"
|
||||
status_label_3.modulate = Color.RED
|
||||
return
|
||||
|
||||
if verification_code == "":
|
||||
status_label_3.text = "请输入验证码!"
|
||||
status_label_3.modulate = Color.RED
|
||||
return
|
||||
|
||||
# 检查网络连接状态
|
||||
if !tcp_network_manager_panel.client.is_client_connected():
|
||||
status_label_3.text = "未连接到服务器,正在尝试连接..."
|
||||
status_label_3.modulate = Color.YELLOW
|
||||
# 尝试自动连接到服务器
|
||||
tcp_network_manager_panel.connect_to_current_server()
|
||||
await get_tree().create_timer(2.0).timeout
|
||||
|
||||
# 再次检查连接状态
|
||||
if !tcp_network_manager_panel.client.is_client_connected():
|
||||
status_label_3.text = "连接服务器失败,正在尝试其他服务器..."
|
||||
status_label_3.modulate = Color.YELLOW
|
||||
# 等待自动服务器切换完成
|
||||
await get_tree().create_timer(3.0).timeout
|
||||
|
||||
# 禁用按钮,防止重复点击
|
||||
forget_password_button.disabled = true
|
||||
|
||||
status_label_3.text = "正在重置密码,请稍候..."
|
||||
status_label_3.modulate = Color.YELLOW
|
||||
|
||||
# 发送忘记密码请求
|
||||
tcp_network_manager_panel.sendForgetPasswordRequest(user_name, new_password, verification_code)
|
||||
|
||||
# 5秒后重新启用按钮(如果没有收到响应)
|
||||
await get_tree().create_timer(5.0).timeout
|
||||
if forget_password_button.disabled:
|
||||
forget_password_button.disabled = false
|
||||
status_label_3.text = "重置密码超时,请重试!"
|
||||
status_label_3.modulate = Color.RED
|
||||
|
||||
# 处理验证码发送响应
|
||||
func _on_verification_code_response(success: bool, message: String):
|
||||
@@ -390,24 +532,67 @@ func _on_login_response_received(success: bool, message: String, user_data: Dict
|
||||
# 处理注册响应
|
||||
func _on_register_response_received(success: bool, message: String):
|
||||
# 启用按钮
|
||||
register_button.disabled = false
|
||||
register_button_2.disabled = false
|
||||
|
||||
if success:
|
||||
status_label.text = "注册成功!请登录游戏"
|
||||
status_label.modulate = Color.GREEN
|
||||
status_label_2.text = "注册成功!请登录游戏"
|
||||
status_label_2.modulate = Color.GREEN
|
||||
|
||||
# 注册成功后,如果启用了记住密码,保存登录信息
|
||||
if remember_password:
|
||||
var user_name = username_input.text.strip_edges()
|
||||
var user_password = password_input.text.strip_edges()
|
||||
var user_name = register_username_input.text.strip_edges()
|
||||
var user_password = password_input_1.text.strip_edges()
|
||||
_save_login_info(user_name, user_password)
|
||||
|
||||
# 清除注册相关的输入框
|
||||
password_input_2.text = ""
|
||||
verificationcode_input.text = ""
|
||||
|
||||
# 切换回登录面板
|
||||
register_vbox.hide()
|
||||
forget_password_vbox.hide()
|
||||
login_v_box.show()
|
||||
|
||||
# 如果记住密码,自动填充登录信息
|
||||
if remember_password:
|
||||
username_input.text = register_username_input.text
|
||||
password_input.text = password_input_1.text
|
||||
else:
|
||||
status_label.text = "注册失败:" + message
|
||||
status_label.modulate = Color.RED
|
||||
status_label_2.text = "注册失败:" + message
|
||||
status_label_2.modulate = Color.RED
|
||||
|
||||
# 处理忘记密码响应
|
||||
func _on_forget_password_response_received(success: bool, message: String):
|
||||
# 启用按钮
|
||||
forget_password_button.disabled = false
|
||||
|
||||
if success:
|
||||
status_label_3.text = "密码重置成功!请使用新密码登录"
|
||||
status_label_3.modulate = Color.GREEN
|
||||
|
||||
# 保存新的登录信息
|
||||
if remember_password:
|
||||
var user_name = forget_username_input.text.strip_edges()
|
||||
var new_password = new_password_input.text.strip_edges()
|
||||
_save_login_info(user_name, new_password)
|
||||
|
||||
# 清除输入框
|
||||
forget_verificationcode_input.text = ""
|
||||
|
||||
# 切换回登录面板并自动填充账号信息
|
||||
forget_password_vbox.hide()
|
||||
register_vbox.hide()
|
||||
login_v_box.show()
|
||||
|
||||
# 自动填充登录信息
|
||||
username_input.text = forget_username_input.text
|
||||
password_input.text = new_password_input.text
|
||||
|
||||
status_label.text = "密码已重置,请登录"
|
||||
status_label.modulate = Color.GREEN
|
||||
else:
|
||||
status_label_3.text = "密码重置失败:" + message
|
||||
status_label_3.modulate = Color.RED
|
||||
|
||||
# 保存登录信息到JSON文件
|
||||
func _save_login_info(user_name: String, password: String):
|
||||
|
||||
374
Script/BigPanel/PlayerStorePanel.gd
Normal file
374
Script/BigPanel/PlayerStorePanel.gd
Normal file
@@ -0,0 +1,374 @@
|
||||
extends Panel
|
||||
#玩家小卖部(目前可以卖道具,种子,成熟作物)
|
||||
#初始玩家有10个格子
|
||||
#然后玩家额外购买格子需要1000元,多加一个格子加500元,最多40个格子,格子满了不能再放了
|
||||
#玩家自己点击自己的摊位(商品格子)显示弹窗是否要取消放置商品
|
||||
#别人拜访玩家打开小卖部点击被拜访玩家的摊位显示批量购买弹窗
|
||||
@onready var quit_button: Button = $QuitButton #关闭玩家小卖部面板
|
||||
@onready var refresh_button: Button = $RefreshButton #刷新小卖部按钮
|
||||
@onready var store_grid: GridContainer = $ScrollContainer/Store_Grid #小卖部商品格子
|
||||
@onready var buy_product_booth_button: Button = $BuyProductBoothButton #购买格子按钮
|
||||
|
||||
# 获取主游戏引用
|
||||
@onready var main_game = get_node("/root/main")
|
||||
|
||||
# 当前小卖部数据
|
||||
var player_store_data: Array = []
|
||||
var max_store_slots: int = 10 # 默认10个格子
|
||||
|
||||
func _ready():
|
||||
# 连接按钮信号
|
||||
quit_button.pressed.connect(_on_quit_button_pressed)
|
||||
refresh_button.pressed.connect(_on_refresh_button_pressed)
|
||||
buy_product_booth_button.pressed.connect(_on_buy_product_booth_button_pressed)
|
||||
|
||||
# 连接可见性改变信号
|
||||
visibility_changed.connect(_on_visibility_changed)
|
||||
|
||||
# 默认隐藏面板
|
||||
self.hide()
|
||||
|
||||
#面板显示与隐藏切换处理
|
||||
func _on_visibility_changed():
|
||||
if visible:
|
||||
GlobalVariables.isZoomDisabled = true
|
||||
# 面板显示时更新小卖部数据
|
||||
update_player_store_ui()
|
||||
else:
|
||||
GlobalVariables.isZoomDisabled = false
|
||||
|
||||
# 初始化玩家小卖部
|
||||
func init_player_store():
|
||||
update_player_store_ui()
|
||||
|
||||
# 更新小卖部UI
|
||||
func update_player_store_ui():
|
||||
# 清空商品格子
|
||||
for child in store_grid.get_children():
|
||||
child.queue_free()
|
||||
|
||||
# 获取小卖部数据
|
||||
if main_game.is_visiting_mode:
|
||||
# 访问模式:显示被访问玩家的小卖部
|
||||
player_store_data = main_game.visited_player_data.get("玩家小卖部", [])
|
||||
max_store_slots = main_game.visited_player_data.get("小卖部格子数", 10)
|
||||
buy_product_booth_button.hide() # 访问模式下隐藏购买格子按钮
|
||||
else:
|
||||
# 正常模式:显示自己的小卖部
|
||||
player_store_data = main_game.login_data.get("玩家小卖部", [])
|
||||
max_store_slots = main_game.login_data.get("小卖部格子数", 10)
|
||||
buy_product_booth_button.show() # 正常模式下显示购买格子按钮
|
||||
|
||||
# 创建商品按钮
|
||||
_create_store_buttons()
|
||||
|
||||
# 更新购买格子按钮文本
|
||||
_update_buy_booth_button()
|
||||
|
||||
# 创建小卖部商品按钮
|
||||
func _create_store_buttons():
|
||||
# 为每个格子创建按钮
|
||||
for i in range(max_store_slots):
|
||||
var button = _create_store_slot_button(i)
|
||||
store_grid.add_child(button)
|
||||
|
||||
# 创建单个商品格子按钮
|
||||
func _create_store_slot_button(slot_index: int) -> Button:
|
||||
var button = main_game.item_button.duplicate()
|
||||
|
||||
# 确保按钮可见并可点击
|
||||
button.visible = true
|
||||
button.disabled = false
|
||||
button.focus_mode = Control.FOCUS_ALL
|
||||
|
||||
# 检查该格子是否有商品
|
||||
var product_data = null
|
||||
if slot_index < player_store_data.size():
|
||||
product_data = player_store_data[slot_index]
|
||||
|
||||
if product_data:
|
||||
# 有商品的格子
|
||||
var product_name = product_data.get("商品名称", "未知商品")
|
||||
var product_price = product_data.get("商品价格", 0)
|
||||
var product_count = product_data.get("商品数量", 0)
|
||||
var product_type = product_data.get("商品类型", "作物")
|
||||
|
||||
# 设置按钮文本
|
||||
button.text = str(product_name + "\n" + str(product_price) + "元/个\n库存:" + str(product_count))
|
||||
|
||||
# 更新商品图片
|
||||
_update_button_product_image(button, product_name, product_type)
|
||||
|
||||
# 设置工具提示
|
||||
button.tooltip_text = str(
|
||||
"商品: " + product_name + "\n" +
|
||||
"类型: " + product_type + "\n" +
|
||||
"单价: " + str(product_price) + " 元\n" +
|
||||
"库存: " + str(product_count) + " 个"
|
||||
)
|
||||
|
||||
# 连接点击事件
|
||||
if main_game.is_visiting_mode:
|
||||
# 访问模式:显示购买弹窗
|
||||
button.pressed.connect(func(): _on_product_buy_selected(product_data, slot_index))
|
||||
else:
|
||||
# 自己的小卖部:显示移除商品弹窗
|
||||
button.pressed.connect(func(): _on_product_manage_selected(product_data, slot_index))
|
||||
else:
|
||||
# 空格子
|
||||
button.text = "空闲格子\n\n点击添加商品"
|
||||
|
||||
# 设置为灰色样式
|
||||
if button.has_node("Title"):
|
||||
button.get_node("Title").modulate = Color.GRAY
|
||||
|
||||
# 只有在非访问模式下才允许点击空格子
|
||||
if not main_game.is_visiting_mode:
|
||||
button.pressed.connect(func(): _on_empty_slot_selected(slot_index))
|
||||
else:
|
||||
button.disabled = true
|
||||
|
||||
return button
|
||||
|
||||
# 更新商品图片
|
||||
func _update_button_product_image(button: Button, product_name: String, product_type: String):
|
||||
var crop_image = button.get_node_or_null("CropImage")
|
||||
if not crop_image:
|
||||
return
|
||||
|
||||
var texture = null
|
||||
|
||||
if product_type == "作物":
|
||||
# 作物商品:加载收获物图片
|
||||
texture = _get_crop_harvest_texture(product_name)
|
||||
# 未来可以添加其他类型的商品图片加载
|
||||
|
||||
if texture:
|
||||
crop_image.texture = texture
|
||||
crop_image.visible = true
|
||||
else:
|
||||
crop_image.visible = false
|
||||
|
||||
# 获取作物的收获物图片
|
||||
func _get_crop_harvest_texture(crop_name: String) -> Texture2D:
|
||||
var crop_path = "res://assets/作物/" + crop_name + "/"
|
||||
var harvest_texture_path = crop_path + "收获物.webp"
|
||||
|
||||
if ResourceLoader.exists(harvest_texture_path):
|
||||
var texture = load(harvest_texture_path)
|
||||
if texture:
|
||||
return texture
|
||||
|
||||
# 如果没有找到,使用默认的收获物图片
|
||||
var default_harvest_path = "res://assets/作物/默认/收获物.webp"
|
||||
if ResourceLoader.exists(default_harvest_path):
|
||||
var texture = load(default_harvest_path)
|
||||
if texture:
|
||||
return texture
|
||||
|
||||
return null
|
||||
|
||||
# 访问模式:点击商品购买
|
||||
func _on_product_buy_selected(product_data: Dictionary, slot_index: int):
|
||||
var product_name = product_data.get("商品名称", "未知商品")
|
||||
var product_price = product_data.get("商品价格", 0)
|
||||
var product_count = product_data.get("商品数量", 0)
|
||||
var product_type = product_data.get("商品类型", "作物")
|
||||
|
||||
# 检查商品是否还有库存
|
||||
if product_count <= 0:
|
||||
Toast.show("该商品已售罄", Color.RED, 2.0, 1.0)
|
||||
return
|
||||
|
||||
# 获取批量购买弹窗
|
||||
var batch_buy_popup = get_node_or_null("/root/main/UI/DiaLog/BatchBuyPopup")
|
||||
if batch_buy_popup and batch_buy_popup.has_method("show_buy_popup"):
|
||||
# 显示批量购买弹窗
|
||||
batch_buy_popup.show_buy_popup(
|
||||
product_name,
|
||||
product_price,
|
||||
"玩家小卖部商品",
|
||||
"store_product", # 特殊类型标识
|
||||
_on_confirm_buy_store_product,
|
||||
_on_cancel_buy_store_product
|
||||
)
|
||||
|
||||
# 临时保存购买信息
|
||||
batch_buy_popup.set_meta("store_slot_index", slot_index)
|
||||
batch_buy_popup.set_meta("store_product_data", product_data)
|
||||
else:
|
||||
Toast.show("购买功能暂未实现", Color.RED, 2.0, 1.0)
|
||||
|
||||
# 确认购买小卖部商品
|
||||
func _on_confirm_buy_store_product(product_name: String, unit_price: int, quantity: int, buy_type: String):
|
||||
var slot_index = get_node("/root/main/UI/DiaLog/BatchBuyPopup").get_meta("store_slot_index", -1)
|
||||
var product_data = get_node("/root/main/UI/DiaLog/BatchBuyPopup").get_meta("store_product_data", {})
|
||||
|
||||
if slot_index == -1 or product_data.is_empty():
|
||||
Toast.show("购买信息错误", Color.RED, 2.0, 1.0)
|
||||
return
|
||||
|
||||
# 发送购买请求到服务器
|
||||
var tcp_network_manager = get_node_or_null("/root/main/UI/BigPanel/TCPNetworkManagerPanel")
|
||||
if tcp_network_manager and tcp_network_manager.has_method("send_message"):
|
||||
var visited_player_name = main_game.visited_player_data.get("player_name", "")
|
||||
var message = {
|
||||
"type": "buy_store_product",
|
||||
"seller_username": main_game.visited_player_data.get("username", ""),
|
||||
"slot_index": slot_index,
|
||||
"product_name": product_name,
|
||||
"unit_price": unit_price,
|
||||
"quantity": quantity
|
||||
}
|
||||
tcp_network_manager.send_message(message)
|
||||
|
||||
Toast.show("购买请求已发送", Color.YELLOW, 2.0, 1.0)
|
||||
else:
|
||||
Toast.show("网络连接异常,无法购买", Color.RED, 2.0, 1.0)
|
||||
|
||||
# 取消购买小卖部商品
|
||||
func _on_cancel_buy_store_product():
|
||||
# 不需要做任何事情,弹窗会自动关闭
|
||||
pass
|
||||
|
||||
# 自己的小卖部:点击商品管理
|
||||
func _on_product_manage_selected(product_data: Dictionary, slot_index: int):
|
||||
var product_name = product_data.get("商品名称", "未知商品")
|
||||
var product_count = product_data.get("商品数量", 0)
|
||||
|
||||
# 显示管理确认对话框
|
||||
_show_product_manage_dialog(product_name, product_count, slot_index)
|
||||
|
||||
# 显示商品管理对话框
|
||||
func _show_product_manage_dialog(product_name: String, product_count: int, slot_index: int):
|
||||
var confirm_dialog = AcceptDialog.new()
|
||||
confirm_dialog.dialog_text = str(
|
||||
"商品管理\n\n" +
|
||||
"商品:" + product_name + "\n" +
|
||||
"库存:" + str(product_count) + " 个\n\n" +
|
||||
"确认要下架这个商品吗?\n" +
|
||||
"商品将返回到您的仓库中。"
|
||||
)
|
||||
confirm_dialog.title = "商品管理"
|
||||
confirm_dialog.ok_button_text = "下架商品"
|
||||
confirm_dialog.add_cancel_button("取消")
|
||||
|
||||
# 添加到场景
|
||||
add_child(confirm_dialog)
|
||||
|
||||
# 连接信号
|
||||
confirm_dialog.confirmed.connect(_on_confirm_remove_product.bind(slot_index, confirm_dialog))
|
||||
confirm_dialog.canceled.connect(_on_cancel_remove_product.bind(confirm_dialog))
|
||||
|
||||
# 显示对话框
|
||||
confirm_dialog.popup_centered()
|
||||
|
||||
# 确认下架商品
|
||||
func _on_confirm_remove_product(slot_index: int, dialog: AcceptDialog):
|
||||
# 发送下架商品请求到服务器
|
||||
var tcp_network_manager = get_node_or_null("/root/main/UI/BigPanel/TCPNetworkManagerPanel")
|
||||
if tcp_network_manager and tcp_network_manager.has_method("send_message"):
|
||||
var message = {
|
||||
"type": "remove_store_product",
|
||||
"slot_index": slot_index
|
||||
}
|
||||
tcp_network_manager.send_message(message)
|
||||
|
||||
Toast.show("下架请求已发送", Color.YELLOW, 2.0, 1.0)
|
||||
else:
|
||||
Toast.show("网络连接异常,无法下架", Color.RED, 2.0, 1.0)
|
||||
|
||||
dialog.queue_free()
|
||||
|
||||
# 取消下架商品
|
||||
func _on_cancel_remove_product(dialog: AcceptDialog):
|
||||
dialog.queue_free()
|
||||
|
||||
# 点击空格子
|
||||
func _on_empty_slot_selected(slot_index: int):
|
||||
Toast.show("请从作物仓库选择商品添加到小卖部", Color.CYAN, 3.0, 1.0)
|
||||
|
||||
# 更新购买格子按钮
|
||||
func _update_buy_booth_button():
|
||||
if main_game.is_visiting_mode:
|
||||
return
|
||||
|
||||
var next_slot_cost = 1000 + (max_store_slots - 10) * 500
|
||||
if max_store_slots >= 40:
|
||||
buy_product_booth_button.text = "格子已满(40/40)"
|
||||
buy_product_booth_button.disabled = true
|
||||
else:
|
||||
buy_product_booth_button.text = str("购买格子(+" + str(next_slot_cost) + "元)")
|
||||
buy_product_booth_button.disabled = false
|
||||
|
||||
# 购买格子按钮处理
|
||||
func _on_buy_product_booth_button_pressed():
|
||||
if main_game.is_visiting_mode:
|
||||
return
|
||||
|
||||
if max_store_slots >= 40:
|
||||
Toast.show("格子数量已达上限", Color.RED, 2.0, 1.0)
|
||||
return
|
||||
|
||||
var next_slot_cost = 1000 + (max_store_slots - 10) * 500
|
||||
|
||||
if main_game.money < next_slot_cost:
|
||||
Toast.show("金钱不足,需要 " + str(next_slot_cost) + " 元", Color.RED, 2.0, 1.0)
|
||||
return
|
||||
|
||||
# 显示购买确认对话框
|
||||
_show_buy_booth_dialog(next_slot_cost)
|
||||
|
||||
# 显示购买格子确认对话框
|
||||
func _show_buy_booth_dialog(cost: int):
|
||||
var confirm_dialog = AcceptDialog.new()
|
||||
confirm_dialog.dialog_text = str(
|
||||
"购买小卖部格子\n\n" +
|
||||
"费用:" + str(cost) + " 元\n" +
|
||||
"当前格子数:" + str(max_store_slots) + "\n" +
|
||||
"购买后格子数:" + str(max_store_slots + 1) + "\n\n" +
|
||||
"确认购买吗?"
|
||||
)
|
||||
confirm_dialog.title = "购买格子"
|
||||
confirm_dialog.ok_button_text = "确认购买"
|
||||
confirm_dialog.add_cancel_button("取消")
|
||||
|
||||
# 添加到场景
|
||||
add_child(confirm_dialog)
|
||||
|
||||
# 连接信号
|
||||
confirm_dialog.confirmed.connect(_on_confirm_buy_booth.bind(cost, confirm_dialog))
|
||||
confirm_dialog.canceled.connect(_on_cancel_buy_booth.bind(confirm_dialog))
|
||||
|
||||
# 显示对话框
|
||||
confirm_dialog.popup_centered()
|
||||
|
||||
# 确认购买格子
|
||||
func _on_confirm_buy_booth(cost: int, dialog: AcceptDialog):
|
||||
# 发送购买格子请求到服务器
|
||||
var tcp_network_manager = get_node_or_null("/root/main/UI/BigPanel/TCPNetworkManagerPanel")
|
||||
if tcp_network_manager and tcp_network_manager.has_method("send_message"):
|
||||
var message = {
|
||||
"type": "buy_store_booth",
|
||||
"cost": cost
|
||||
}
|
||||
tcp_network_manager.send_message(message)
|
||||
|
||||
Toast.show("购买请求已发送", Color.YELLOW, 2.0, 1.0)
|
||||
else:
|
||||
Toast.show("网络连接异常,无法购买", Color.RED, 2.0, 1.0)
|
||||
|
||||
dialog.queue_free()
|
||||
|
||||
# 取消购买格子
|
||||
func _on_cancel_buy_booth(dialog: AcceptDialog):
|
||||
dialog.queue_free()
|
||||
|
||||
# 关闭面板
|
||||
func _on_quit_button_pressed():
|
||||
self.hide()
|
||||
|
||||
# 刷新小卖部
|
||||
func _on_refresh_button_pressed():
|
||||
update_player_store_ui()
|
||||
Toast.show("小卖部已刷新", Color.GREEN, 2.0, 1.0)
|
||||
1
Script/BigPanel/PlayerStorePanel.gd.uid
Normal file
1
Script/BigPanel/PlayerStorePanel.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bdavskipn547h
|
||||
197
Script/Dialog/AddProduct2StorePopup.gd
Normal file
197
Script/Dialog/AddProduct2StorePopup.gd
Normal file
@@ -0,0 +1,197 @@
|
||||
extends PanelContainer
|
||||
#用于添加商品到玩家小卖部的弹窗
|
||||
@onready var title: Label = $VBox/Title #弹窗标题
|
||||
@onready var contents: Label = $VBox/Contents #这里显示弹窗内容
|
||||
@onready var sell_num_input: LineEdit = $VBox/SellNumInput #这里输入需要放入小卖部的商品数量
|
||||
@onready var sell_price_input: LineEdit = $VBox/SellPriceInput #这里输入每件商品的价格
|
||||
@onready var sure_button: Button = $VBox/HBox/SureButton #确定放入按钮
|
||||
@onready var cancel_button: Button = $VBox/HBox/CancelButton #取消按钮
|
||||
|
||||
# 当前要添加的商品信息
|
||||
var current_product_name: String = ""
|
||||
var current_max_count: int = 0
|
||||
var current_suggested_price: int = 0
|
||||
var current_product_desc: String = ""
|
||||
|
||||
# 回调函数,用于处理确认添加
|
||||
var confirm_callback: Callable
|
||||
var cancel_callback: Callable
|
||||
|
||||
func _ready():
|
||||
# 连接按钮信号
|
||||
sure_button.pressed.connect(_on_sure_button_pressed)
|
||||
cancel_button.pressed.connect(_on_cancel_button_pressed)
|
||||
|
||||
# 设置输入框的默认值和限制
|
||||
sell_num_input.text = "1"
|
||||
sell_num_input.placeholder_text = "请输入数量"
|
||||
sell_price_input.placeholder_text = "请输入单价"
|
||||
|
||||
# 只允许输入数字
|
||||
sell_num_input.text_changed.connect(_on_sell_num_changed)
|
||||
sell_price_input.text_changed.connect(_on_sell_price_changed)
|
||||
|
||||
# 连接可见性改变信号
|
||||
visibility_changed.connect(_on_visibility_changed)
|
||||
|
||||
# 默认隐藏弹窗
|
||||
self.hide()
|
||||
|
||||
#面板显示与隐藏切换处理
|
||||
func _on_visibility_changed():
|
||||
if visible:
|
||||
GlobalVariables.isZoomDisabled = true
|
||||
pass
|
||||
else:
|
||||
GlobalVariables.isZoomDisabled = false
|
||||
pass
|
||||
|
||||
# 显示添加商品弹窗
|
||||
func show_add_product_popup(product_name: String, max_count: int, suggested_price: int, product_desc: String, on_confirm: Callable, on_cancel: Callable = Callable()):
|
||||
current_product_name = product_name
|
||||
current_max_count = max_count
|
||||
current_suggested_price = suggested_price
|
||||
current_product_desc = product_desc
|
||||
confirm_callback = on_confirm
|
||||
cancel_callback = on_cancel
|
||||
|
||||
# 设置弹窗内容
|
||||
title.text = "添加商品到小卖部"
|
||||
|
||||
contents.text = str(
|
||||
"商品名称: " + product_name + "\n" +
|
||||
"可用数量: " + str(max_count) + " 个\n" +
|
||||
"建议价格: " + str(suggested_price) + " 元/个\n" +
|
||||
"描述: " + product_desc + "\n\n" +
|
||||
"请设置出售数量和价格:"
|
||||
)
|
||||
|
||||
# 设置默认值
|
||||
sell_num_input.text = "1"
|
||||
sell_price_input.text = str(suggested_price)
|
||||
|
||||
# 显示弹窗并居中
|
||||
self.show()
|
||||
self.move_to_front()
|
||||
|
||||
# 处理数量输入变化
|
||||
func _on_sell_num_changed(new_text: String):
|
||||
# 只允许输入数字
|
||||
var filtered_text = ""
|
||||
for char in new_text:
|
||||
if char.is_valid_int():
|
||||
filtered_text += char
|
||||
|
||||
if filtered_text != new_text:
|
||||
sell_num_input.text = filtered_text
|
||||
sell_num_input.caret_column = filtered_text.length()
|
||||
|
||||
# 更新预览信息
|
||||
_update_preview_info()
|
||||
|
||||
# 处理价格输入变化
|
||||
func _on_sell_price_changed(new_text: String):
|
||||
# 只允许输入数字
|
||||
var filtered_text = ""
|
||||
for char in new_text:
|
||||
if char.is_valid_int():
|
||||
filtered_text += char
|
||||
|
||||
if filtered_text != new_text:
|
||||
sell_price_input.text = filtered_text
|
||||
sell_price_input.caret_column = filtered_text.length()
|
||||
|
||||
# 更新预览信息
|
||||
_update_preview_info()
|
||||
|
||||
# 更新预览信息
|
||||
func _update_preview_info():
|
||||
var quantity = get_sell_quantity()
|
||||
var unit_price = get_sell_price()
|
||||
var total_value = quantity * unit_price
|
||||
|
||||
# 检查数量是否超过最大可用数量
|
||||
var quantity_status = ""
|
||||
if quantity > current_max_count:
|
||||
quantity_status = " (超出库存!)"
|
||||
|
||||
# 检查价格是否合理
|
||||
var price_status = ""
|
||||
if unit_price <= 0:
|
||||
price_status = " (价格无效!)"
|
||||
elif unit_price < current_suggested_price * 0.5:
|
||||
price_status = " (价格偏低)"
|
||||
elif unit_price > current_suggested_price * 2:
|
||||
price_status = " (价格偏高)"
|
||||
|
||||
var preview_info = "\n上架数量: " + str(quantity) + " 个" + quantity_status + "\n单价: " + str(unit_price) + " 元/个" + price_status + "\n总价值: " + str(total_value) + " 元"
|
||||
|
||||
# 更新内容显示
|
||||
var base_content = str(
|
||||
"商品名称: " + current_product_name + "\n" +
|
||||
"可用数量: " + str(current_max_count) + " 个\n" +
|
||||
"建议价格: " + str(current_suggested_price) + " 元/个\n" +
|
||||
"描述: " + current_product_desc + "\n\n" +
|
||||
"请设置出售数量和价格:"
|
||||
)
|
||||
|
||||
contents.text = base_content + preview_info
|
||||
|
||||
# 获取出售数量
|
||||
func get_sell_quantity() -> int:
|
||||
var text = sell_num_input.text.strip_edges()
|
||||
if text.is_empty():
|
||||
return 1
|
||||
|
||||
var quantity = text.to_int()
|
||||
return max(1, quantity) # 至少出售1个
|
||||
|
||||
# 获取出售价格
|
||||
func get_sell_price() -> int:
|
||||
var text = sell_price_input.text.strip_edges()
|
||||
if text.is_empty():
|
||||
return current_suggested_price
|
||||
|
||||
var price = text.to_int()
|
||||
return max(1, price) # 至少1元
|
||||
|
||||
# 确认添加按钮处理
|
||||
func _on_sure_button_pressed():
|
||||
var quantity = get_sell_quantity()
|
||||
var unit_price = get_sell_price()
|
||||
|
||||
if quantity <= 0:
|
||||
_show_error("数量必须大于0")
|
||||
return
|
||||
|
||||
if quantity > current_max_count:
|
||||
_show_error("数量不能超过库存数量(" + str(current_max_count) + ")")
|
||||
return
|
||||
|
||||
if unit_price <= 0:
|
||||
_show_error("价格必须大于0")
|
||||
return
|
||||
|
||||
# 调用确认回调函数
|
||||
if confirm_callback.is_valid():
|
||||
confirm_callback.call(current_product_name, quantity, unit_price)
|
||||
|
||||
# 隐藏弹窗
|
||||
self.hide()
|
||||
|
||||
# 取消添加按钮处理
|
||||
func _on_cancel_button_pressed():
|
||||
# 调用取消回调函数
|
||||
if cancel_callback.is_valid():
|
||||
cancel_callback.call()
|
||||
|
||||
# 隐藏弹窗
|
||||
self.hide()
|
||||
|
||||
# 显示错误信息
|
||||
func _show_error(message: String):
|
||||
# 显示Toast错误提示
|
||||
if has_node("/root/Toast"):
|
||||
get_node("/root/Toast").show(message, Color.RED, 2.0, 1.0)
|
||||
else:
|
||||
print("添加商品弹窗错误: " + message)
|
||||
1
Script/Dialog/AddProduct2StorePopup.gd.uid
Normal file
1
Script/Dialog/AddProduct2StorePopup.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cha0uw4ra1trr
|
||||
154
Script/Dialog/BatchSellPopup.gd
Normal file
154
Script/Dialog/BatchSellPopup.gd
Normal file
@@ -0,0 +1,154 @@
|
||||
extends PanelContainer
|
||||
#用于作物批量出售作物弹窗
|
||||
@onready var title: Label = $VBox/Title #弹窗标题
|
||||
@onready var contents: Label = $VBox/Contents #这里显示弹窗内容
|
||||
@onready var sell_num_edit: LineEdit = $VBox/SellNumEdit #出售作物数量
|
||||
@onready var sure_button: Button = $VBox/HBox/SureButton #确定按钮
|
||||
@onready var cancel_button: Button = $VBox/HBox/CancelButton #取消按钮
|
||||
|
||||
# 当前出售的作物信息
|
||||
var current_crop_name: String = ""
|
||||
var current_max_count: int = 0
|
||||
var current_unit_price: int = 0
|
||||
var current_crop_desc: String = ""
|
||||
|
||||
# 回调函数,用于处理确认出售
|
||||
var confirm_callback: Callable
|
||||
var cancel_callback: Callable
|
||||
|
||||
func _ready():
|
||||
# 连接按钮信号
|
||||
sure_button.pressed.connect(_on_sure_button_pressed)
|
||||
cancel_button.pressed.connect(_on_cancel_button_pressed)
|
||||
|
||||
# 设置数量输入框的默认值和限制
|
||||
sell_num_edit.text = "1"
|
||||
sell_num_edit.placeholder_text = "请输入出售数量"
|
||||
|
||||
# 只允许输入数字
|
||||
sell_num_edit.text_changed.connect(_on_sell_num_changed)
|
||||
|
||||
# 连接可见性改变信号
|
||||
visibility_changed.connect(_on_visibility_changed)
|
||||
|
||||
# 默认隐藏弹窗
|
||||
self.hide()
|
||||
|
||||
#面板显示与隐藏切换处理
|
||||
func _on_visibility_changed():
|
||||
if visible:
|
||||
GlobalVariables.isZoomDisabled = true
|
||||
pass
|
||||
else:
|
||||
GlobalVariables.isZoomDisabled = false
|
||||
pass
|
||||
|
||||
# 显示批量出售弹窗
|
||||
func show_sell_popup(crop_name: String, max_count: int, unit_price: int, crop_desc: String, on_confirm: Callable, on_cancel: Callable = Callable()):
|
||||
current_crop_name = crop_name
|
||||
current_max_count = max_count
|
||||
current_unit_price = unit_price
|
||||
current_crop_desc = crop_desc
|
||||
confirm_callback = on_confirm
|
||||
cancel_callback = on_cancel
|
||||
|
||||
# 设置弹窗内容
|
||||
title.text = "批量出售作物"
|
||||
|
||||
contents.text = str(
|
||||
"作物名称: " + crop_name + "\n" +
|
||||
"单价: " + str(unit_price) + " 元/个\n" +
|
||||
"可出售数量: " + str(max_count) + " 个\n" +
|
||||
"描述: " + crop_desc + "\n\n" +
|
||||
"请输入出售数量:"
|
||||
)
|
||||
|
||||
# 重置出售数量为1
|
||||
sell_num_edit.text = "1"
|
||||
|
||||
# 显示弹窗并居中
|
||||
self.show()
|
||||
self.move_to_front()
|
||||
|
||||
# 处理数量输入变化
|
||||
func _on_sell_num_changed(new_text: String):
|
||||
# 只允许输入数字
|
||||
var filtered_text = ""
|
||||
for char in new_text:
|
||||
if char.is_valid_int():
|
||||
filtered_text += char
|
||||
|
||||
if filtered_text != new_text:
|
||||
sell_num_edit.text = filtered_text
|
||||
sell_num_edit.caret_column = filtered_text.length()
|
||||
|
||||
# 更新总价显示
|
||||
_update_total_income()
|
||||
|
||||
# 更新总收入显示
|
||||
func _update_total_income():
|
||||
var quantity = get_sell_quantity()
|
||||
var total_income = quantity * current_unit_price
|
||||
|
||||
# 检查数量是否超过最大可售数量
|
||||
var quantity_status = ""
|
||||
if quantity > current_max_count:
|
||||
quantity_status = " (超出库存!)"
|
||||
|
||||
var income_info = "\n出售数量: " + str(quantity) + " 个" + quantity_status + "\n总收入: " + str(total_income) + " 元"
|
||||
|
||||
# 更新内容显示
|
||||
var base_content = str(
|
||||
"作物名称: " + current_crop_name + "\n" +
|
||||
"单价: " + str(current_unit_price) + " 元/个\n" +
|
||||
"可出售数量: " + str(current_max_count) + " 个\n" +
|
||||
"描述: " + current_crop_desc + "\n\n" +
|
||||
"请输入出售数量:"
|
||||
)
|
||||
|
||||
contents.text = base_content + income_info
|
||||
|
||||
# 获取出售数量
|
||||
func get_sell_quantity() -> int:
|
||||
var text = sell_num_edit.text.strip_edges()
|
||||
if text.is_empty():
|
||||
return 1
|
||||
|
||||
var quantity = text.to_int()
|
||||
return max(1, quantity) # 至少出售1个
|
||||
|
||||
# 确认出售按钮处理
|
||||
func _on_sure_button_pressed():
|
||||
var quantity = get_sell_quantity()
|
||||
|
||||
if quantity <= 0:
|
||||
_show_error("出售数量必须大于0")
|
||||
return
|
||||
|
||||
if quantity > current_max_count:
|
||||
_show_error("出售数量不能超过库存数量(" + str(current_max_count) + ")")
|
||||
return
|
||||
|
||||
# 调用确认回调函数
|
||||
if confirm_callback.is_valid():
|
||||
confirm_callback.call(current_crop_name, quantity, current_unit_price)
|
||||
|
||||
# 隐藏弹窗
|
||||
self.hide()
|
||||
|
||||
# 取消出售按钮处理
|
||||
func _on_cancel_button_pressed():
|
||||
# 调用取消回调函数
|
||||
if cancel_callback.is_valid():
|
||||
cancel_callback.call()
|
||||
|
||||
# 隐藏弹窗
|
||||
self.hide()
|
||||
|
||||
# 显示错误信息
|
||||
func _show_error(message: String):
|
||||
# 显示Toast错误提示
|
||||
if has_node("/root/Toast"):
|
||||
get_node("/root/Toast").show(message, Color.RED, 2.0, 1.0)
|
||||
else:
|
||||
print("批量出售弹窗错误: " + message)
|
||||
1
Script/Dialog/BatchSellPopup.gd.uid
Normal file
1
Script/Dialog/BatchSellPopup.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dsmmxivba06ab
|
||||
216
Script/SmallPanel/CropInformPanel.gd
Normal file
216
Script/SmallPanel/CropInformPanel.gd
Normal file
@@ -0,0 +1,216 @@
|
||||
extends Panel
|
||||
|
||||
@onready var quit_button: Button = $QuitButton #关闭作物信息面板
|
||||
@onready var crop_image: TextureRect = $VBox/CropImage #显示作物图片
|
||||
@onready var crop_name: Label = $VBox/CropName #作物名称
|
||||
@onready var crop_description: Label = $VBox/CropDescription #作物介绍
|
||||
@onready var crop_price: Label = $VBox/CropPrice #作物价格
|
||||
@onready var crop_quality: Label = $VBox/CropQuality #作物品质
|
||||
@onready var sale_product: Button = $VBox/HBox/SaleProduct #直接出售
|
||||
@onready var add_to_store: Button = $VBox/HBox/AddToStore #添加到小卖部
|
||||
|
||||
@onready var add_product_to_store_popup: PanelContainer = $'../../DiaLog/AddProductToStorePopup'
|
||||
|
||||
|
||||
|
||||
# 当前显示的作物信息
|
||||
var current_crop_name: String = ""
|
||||
var current_crop_count: int = 0
|
||||
|
||||
# 获取主游戏引用
|
||||
@onready var main_game = get_node("/root/main")
|
||||
|
||||
func _ready():
|
||||
# 连接按钮信号
|
||||
quit_button.pressed.connect(_on_quit_button_pressed)
|
||||
sale_product.pressed.connect(_on_sale_product_pressed)
|
||||
add_to_store.pressed.connect(_on_add_to_store_pressed)
|
||||
|
||||
# 默认隐藏面板
|
||||
self.hide()
|
||||
|
||||
# 显示作物信息
|
||||
func show_crop_info(crop_name: String, crop_count: int):
|
||||
current_crop_name = crop_name
|
||||
current_crop_count = crop_count
|
||||
|
||||
# 更新作物信息显示
|
||||
_update_crop_display()
|
||||
|
||||
# 显示面板
|
||||
self.show()
|
||||
self.move_to_front()
|
||||
|
||||
# 更新作物信息显示
|
||||
func _update_crop_display():
|
||||
if not main_game.can_planted_crop.has(current_crop_name):
|
||||
crop_name.text = "作物名称:" + current_crop_name
|
||||
crop_description.text = "描述:未知作物"
|
||||
crop_price.text = "收购价:未知"
|
||||
crop_quality.text = "品质:未知"
|
||||
return
|
||||
|
||||
var crop_data = main_game.can_planted_crop[current_crop_name]
|
||||
|
||||
# 获取显示名称
|
||||
var display_name = current_crop_name
|
||||
var mature_name = crop_data.get("成熟物名称")
|
||||
if mature_name != null and mature_name != "":
|
||||
display_name = mature_name
|
||||
else:
|
||||
display_name = crop_data.get("作物名称", current_crop_name)
|
||||
|
||||
# 更新文本显示
|
||||
crop_name.text = "作物名称:" + display_name + " (数量: " + str(current_crop_count) + ")"
|
||||
crop_description.text = "描述:" + crop_data.get("描述", "美味的作物")
|
||||
|
||||
# 计算出售价格(基于收益)
|
||||
var sell_price = crop_data.get("收益", 0)
|
||||
crop_price.text = "收购价:" + str(sell_price) + " 元/个"
|
||||
|
||||
var quality = crop_data.get("品质", "普通")
|
||||
crop_quality.text = "品质:" + quality
|
||||
|
||||
# 更新作物图片
|
||||
_update_crop_image()
|
||||
|
||||
# 更新作物图片
|
||||
func _update_crop_image():
|
||||
var texture = _get_crop_harvest_texture(current_crop_name)
|
||||
if texture:
|
||||
crop_image.texture = texture
|
||||
else:
|
||||
# 使用默认图片
|
||||
var default_texture = _get_crop_harvest_texture("默认")
|
||||
if default_texture:
|
||||
crop_image.texture = default_texture
|
||||
|
||||
# 获取作物的收获物图片
|
||||
func _get_crop_harvest_texture(crop_name: String) -> Texture2D:
|
||||
var crop_path = "res://assets/作物/" + crop_name + "/"
|
||||
var harvest_texture_path = crop_path + "收获物.webp"
|
||||
|
||||
if ResourceLoader.exists(harvest_texture_path):
|
||||
var texture = load(harvest_texture_path)
|
||||
if texture:
|
||||
return texture
|
||||
|
||||
# 如果没有找到,使用默认的收获物图片
|
||||
var default_harvest_path = "res://assets/作物/默认/收获物.webp"
|
||||
if ResourceLoader.exists(default_harvest_path):
|
||||
var texture = load(default_harvest_path)
|
||||
if texture:
|
||||
return texture
|
||||
|
||||
return null
|
||||
|
||||
# 关闭面板
|
||||
func _on_quit_button_pressed():
|
||||
self.hide()
|
||||
|
||||
# 直接出售按钮处理
|
||||
func _on_sale_product_pressed():
|
||||
# 检查是否在访问模式
|
||||
if main_game.is_visiting_mode:
|
||||
Toast.show("访问模式下无法出售作物", Color.ORANGE, 2.0, 1.0)
|
||||
return
|
||||
|
||||
# 获取批量出售弹窗
|
||||
var batch_sell_popup = get_node_or_null("/root/main/UI/DiaLog/BatchSellPopup")
|
||||
if batch_sell_popup and batch_sell_popup.has_method("show_sell_popup"):
|
||||
# 获取作物数据以传递给出售弹窗
|
||||
var crop_data = main_game.can_planted_crop.get(current_crop_name, {})
|
||||
var sell_price = crop_data.get("收益", 0)
|
||||
var description = crop_data.get("描述", "美味的作物")
|
||||
|
||||
# 显示批量出售弹窗
|
||||
batch_sell_popup.show_sell_popup(
|
||||
current_crop_name,
|
||||
current_crop_count,
|
||||
sell_price,
|
||||
description,
|
||||
_on_confirm_sell_crop,
|
||||
_on_cancel_sell_crop
|
||||
)
|
||||
else:
|
||||
Toast.show("批量出售功能暂未实现", Color.RED, 2.0, 1.0)
|
||||
print("错误:找不到BatchSellPopup或相关方法")
|
||||
|
||||
# 确认出售作物回调
|
||||
func _on_confirm_sell_crop(crop_name: String, sell_count: int, unit_price: int):
|
||||
# 发送出售请求到服务器
|
||||
var tcp_network_manager = get_node_or_null("/root/main/UI/BigPanel/TCPNetworkManagerPanel")
|
||||
if tcp_network_manager and tcp_network_manager.has_method("send_message"):
|
||||
var message = {
|
||||
"type": "sell_crop",
|
||||
"crop_name": crop_name,
|
||||
"sell_count": sell_count,
|
||||
"unit_price": unit_price
|
||||
}
|
||||
tcp_network_manager.send_message(message)
|
||||
|
||||
# 关闭作物信息面板
|
||||
self.hide()
|
||||
|
||||
Toast.show("出售请求已发送", Color.YELLOW, 2.0, 1.0)
|
||||
else:
|
||||
Toast.show("网络连接异常,无法出售", Color.RED, 2.0, 1.0)
|
||||
|
||||
# 取消出售作物回调
|
||||
func _on_cancel_sell_crop():
|
||||
# 不需要做任何事情,弹窗会自动关闭
|
||||
pass
|
||||
|
||||
# 添加到小卖部按钮处理
|
||||
func _on_add_to_store_pressed():
|
||||
# 检查是否在访问模式
|
||||
if main_game.is_visiting_mode:
|
||||
Toast.show("访问模式下无法操作小卖部", Color.ORANGE, 2.0, 1.0)
|
||||
return
|
||||
|
||||
# 获取添加商品到小卖部的弹窗
|
||||
|
||||
if add_product_to_store_popup and add_product_to_store_popup.has_method("show_add_product_popup"):
|
||||
# 获取作物数据以传递给弹窗
|
||||
var crop_data = main_game.can_planted_crop.get(current_crop_name, {})
|
||||
var sell_price = crop_data.get("收益", 0)
|
||||
var description = crop_data.get("描述", "美味的作物")
|
||||
|
||||
# 显示添加商品弹窗
|
||||
add_product_to_store_popup.show_add_product_popup(
|
||||
current_crop_name,
|
||||
current_crop_count,
|
||||
sell_price,
|
||||
description,
|
||||
_on_confirm_add_to_store,
|
||||
_on_cancel_add_to_store
|
||||
)
|
||||
else:
|
||||
Toast.show("添加商品功能暂未实现", Color.RED, 2.0, 1.0)
|
||||
print("错误:找不到AddProduct2StorePopup或相关方法")
|
||||
|
||||
# 确认添加到小卖部回调
|
||||
func _on_confirm_add_to_store(crop_name: String, add_count: int, unit_price: int):
|
||||
# 发送添加商品到小卖部的请求到服务器
|
||||
var tcp_network_manager = get_node_or_null("/root/main/UI/BigPanel/TCPNetworkManagerPanel")
|
||||
if tcp_network_manager and tcp_network_manager.has_method("send_message"):
|
||||
var message = {
|
||||
"type": "add_product_to_store",
|
||||
"product_type": "作物",
|
||||
"product_name": crop_name,
|
||||
"product_count": add_count,
|
||||
"product_price": unit_price
|
||||
}
|
||||
tcp_network_manager.send_message(message)
|
||||
|
||||
# 关闭作物信息面板
|
||||
self.hide()
|
||||
|
||||
Toast.show("添加商品请求已发送", Color.YELLOW, 2.0, 1.0)
|
||||
else:
|
||||
Toast.show("网络连接异常,无法添加商品", Color.RED, 2.0, 1.0)
|
||||
|
||||
# 取消添加到小卖部回调
|
||||
func _on_cancel_add_to_store():
|
||||
# 不需要做任何事情,弹窗会自动关闭
|
||||
pass
|
||||
1
Script/SmallPanel/CropInformPanel.gd.uid
Normal file
1
Script/SmallPanel/CropInformPanel.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b185o1hjnlrv5
|
||||
@@ -98,7 +98,12 @@ func _update_performance_data():
|
||||
# 从主游戏获取加载信息
|
||||
if main_game and main_game.crop_texture_manager:
|
||||
var manager = main_game.crop_texture_manager
|
||||
performance_data["loaded_textures"] = manager.texture_cache.size() + manager.mature_texture_cache.size()
|
||||
# 计算所有加载的纹理数量(新的三阶段系统)
|
||||
var total_textures = 0
|
||||
for crop_name in manager.texture_cache.keys():
|
||||
total_textures += manager.texture_cache[crop_name].size()
|
||||
total_textures += manager.default_textures.size()
|
||||
performance_data["loaded_textures"] = total_textures
|
||||
performance_data["failed_textures"] = manager.failed_resources.size()
|
||||
|
||||
# 加载进度
|
||||
|
||||
Reference in New Issue
Block a user