10.8
This commit is contained in:
parent
f65fe41412
commit
2ccb1caec7
@ -461,9 +461,14 @@ var triger:Dictionary={
|
||||
"end_event":func(data):now_game_flow.event_panel.hide(),
|
||||
"flow_time":func (data):flow_time(data),
|
||||
"fight":func (data):fight(data),
|
||||
#货币变更触发器
|
||||
"add_currency":func (data):change_currency_game(data["ind"],data["value"]),
|
||||
#交易触发器
|
||||
"trade":func(data): show_trade(data),
|
||||
"show_identifaction":func(data):show_identification(data)
|
||||
#鉴定触发器
|
||||
"show_identifaction":func(data):show_identification(data),
|
||||
#拍卖触发器
|
||||
"show_auction":func(data):show_auction(data)
|
||||
}
|
||||
#使用事件触发器
|
||||
func call_triger(triger_type:String,data):
|
||||
@ -533,6 +538,11 @@ func recreate_rand_dic(condition:float)->Dictionary:
|
||||
"last_rand_result":new_rand_result,
|
||||
}
|
||||
return dic
|
||||
func show_auction(data:Dictionary):
|
||||
if now_game_flow!=null:
|
||||
now_game_flow.show_auction(data["npc"],data["item"])
|
||||
|
||||
pass
|
||||
|
||||
#多次鉴定时每回合使用的处理函数(对字典处理),返回bool类型,表示本轮是否成功
|
||||
var identfication_round_triger_dic:Dictionary={
|
||||
|
@ -201,5 +201,36 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"auction_test":{
|
||||
"name":"拍卖测试事件",
|
||||
"texture":"test_scene",
|
||||
"text":"这是一个测试鉴定系统的事件",
|
||||
"choice":[
|
||||
{
|
||||
"name":"拍卖",
|
||||
"triger":[
|
||||
{
|
||||
"type":"show_auction",
|
||||
"data":{
|
||||
|
||||
"npc":["npc_01","npc_02"],
|
||||
"item":["item_01","item_02","item_03","item_04"]
|
||||
|
||||
}
|
||||
},
|
||||
{
|
||||
"type":"end_event",
|
||||
"data":""
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"结束",
|
||||
"triger":[{
|
||||
"type":"end_event",
|
||||
"data":""
|
||||
},]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,10 @@
|
||||
"name":"鉴定测试",
|
||||
"event":"fish_test"
|
||||
},
|
||||
{
|
||||
"name":"拍卖测试",
|
||||
"event":"auction_test"
|
||||
}
|
||||
],
|
||||
"linked_scene":[{
|
||||
"name":"测试场景2",
|
||||
|
281
scene/auction.gd
Normal file
281
scene/auction.gd
Normal file
@ -0,0 +1,281 @@
|
||||
extends Control
|
||||
const AUCTION_CARD = preload("res://scene/auction_card.tscn")
|
||||
var auction_card_arr:Array=[null,null,null]
|
||||
@export var texture_arr:Array[Texture2D]=[]
|
||||
@export var scale_parameter:float=0.5
|
||||
var now_index:int=0:
|
||||
set(val):
|
||||
now_index=val
|
||||
if now_index!=now_auction_item_ind:
|
||||
%out_price_btn.disable(true)
|
||||
else:
|
||||
%out_price_btn.disable(false)
|
||||
|
||||
update_out_price()
|
||||
pass
|
||||
# Called when the node enters the scene tree for the first time.
|
||||
func _ready() -> void:
|
||||
|
||||
pass # Replace with function body.
|
||||
|
||||
func init_texture():
|
||||
for i in %card_add_pos.get_children():
|
||||
i.queue_free()
|
||||
now_index=0
|
||||
auction_card_arr[1]=AUCTION_CARD.instantiate()
|
||||
%card_add_pos.add_child(auction_card_arr[1])
|
||||
auction_card_arr[1].set_item_texture(texture_arr[0])
|
||||
auction_card_arr[1].global_position=%center_mask.global_position
|
||||
auction_card_arr[1].size=%center_mask.size
|
||||
auction_card_arr[1].modulate.a=1
|
||||
if texture_arr.size()>1:
|
||||
auction_card_arr[2]=AUCTION_CARD.instantiate()
|
||||
%card_add_pos.add_child(auction_card_arr[2])
|
||||
auction_card_arr[2].set_item_texture(texture_arr[0])
|
||||
auction_card_arr[2].global_position=%right_mark.global_position-%center_mask.size*scale_parameter/2
|
||||
auction_card_arr[2].size=%center_mask.size*scale_parameter
|
||||
auction_card_arr[2].set_item_texture(texture_arr[1])
|
||||
auction_card_arr[2].modulate.a=1
|
||||
pass
|
||||
|
||||
func left():
|
||||
if now_index>0:
|
||||
now_index-=1
|
||||
var before_center_card:AuctionCard=auction_card_arr[1]
|
||||
before_center_card.move_size_to(%right_mark.global_position-%center_mask.size*scale_parameter/2,%center_mask.size*scale_parameter,false)
|
||||
var before_left=auction_card_arr[0]
|
||||
if before_left is AuctionCard:
|
||||
before_left.move_size_to(%center_mask.global_position,%center_mask.size,false)
|
||||
if auction_card_arr[2]!=null:
|
||||
var rightcard=auction_card_arr[2] as AuctionCard
|
||||
rightcard.move_size_to(%right_out_mark.global_position-%center_mask.size*scale_parameter/2,%center_mask.size*scale_parameter,true)
|
||||
auction_card_arr.pop_back()
|
||||
if now_index>0:
|
||||
var new_card:AuctionCard=AUCTION_CARD.instantiate()
|
||||
%card_add_pos.add_child(new_card)
|
||||
new_card.global_position=%left_out_mark.global_position-%center_mask.size*scale_parameter/2
|
||||
new_card.size=%center_mask.size*scale_parameter
|
||||
new_card.move_size_to(%left_mark.global_position-%center_mask.size*scale_parameter/2,%center_mask.size*scale_parameter,false)
|
||||
new_card.set_item_texture(texture_arr[now_index-1])
|
||||
auction_card_arr.push_front(new_card)
|
||||
else:
|
||||
auction_card_arr.push_front(null)
|
||||
func right():
|
||||
|
||||
if now_index<texture_arr.size()-1:
|
||||
now_index+=1
|
||||
var before_center_card:AuctionCard=auction_card_arr[1]
|
||||
before_center_card.move_size_to(%left_mark.global_position-%center_mask.size*scale_parameter/2,%center_mask.size*scale_parameter,false)
|
||||
var before_right=auction_card_arr[2]
|
||||
if before_right is AuctionCard:
|
||||
before_right.move_size_to(%center_mask.global_position,%center_mask.size,false)
|
||||
if auction_card_arr[0]!=null:
|
||||
var leftcard=auction_card_arr[0] as AuctionCard
|
||||
leftcard.move_size_to(%left_out_mark.global_position-%center_mask.size*scale_parameter/2,%center_mask.size*scale_parameter,true)
|
||||
auction_card_arr.pop_front()
|
||||
if now_index<texture_arr.size()-1:
|
||||
var new_card:AuctionCard=AUCTION_CARD.instantiate()
|
||||
%card_add_pos.add_child(new_card)
|
||||
new_card.global_position=%right_out_mark.global_position-%center_mask.size*scale_parameter/2
|
||||
new_card.size=%center_mask.size*scale_parameter
|
||||
new_card.move_size_to(%right_mark.global_position-%center_mask.size*scale_parameter/2,%center_mask.size*scale_parameter,false)
|
||||
new_card.set_item_texture(texture_arr[now_index+1])
|
||||
auction_card_arr.push_back(new_card)
|
||||
else:
|
||||
auction_card_arr.push_back(null)
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
if timer.is_stopped():
|
||||
%time.hide()
|
||||
else:
|
||||
%time.show()
|
||||
%time.text=str(int(timer.time_left))
|
||||
pass
|
||||
#决策
|
||||
#已知这个人有钱x,当前竞拍物品标准价值y,人物需要程度z(0-1),当前竞拍价格a,最小加价b
|
||||
func auction_bid_decision(x:int, y:int, z:float, a:int, b:int,t=0.7):
|
||||
var p_max:int=int(y*(1+z))
|
||||
if a+b>=p_max ||a+b>x:
|
||||
return null
|
||||
var r=randf()
|
||||
if r>t:
|
||||
if randf()>0.5:
|
||||
return null
|
||||
else:
|
||||
var res:int= randi_range(a+b,p_max)
|
||||
if res>x:
|
||||
return null
|
||||
else:
|
||||
return res
|
||||
else:
|
||||
return a+b
|
||||
|
||||
func _on_test_pressed() -> void:
|
||||
set_npc_arr_and_item_arr([Database.get_npc_data("npc_01"),Database.get_npc_data("npc_02")],[Database.get_item_data("item_01"),Database.get_item_data("item_02")])
|
||||
pass # Replace with function body.
|
||||
#本场参与拍卖的NPC字典数组
|
||||
var npc_arr:Array=[]
|
||||
#本场物品数组
|
||||
var item_arr:Array=[]
|
||||
#随机需求数组
|
||||
var npc_need_item_arr:Array=[]
|
||||
|
||||
var now_auction_item_ind:int=0:
|
||||
set(val):
|
||||
now_auction_item_ind=val
|
||||
if now_index!=now_auction_item_ind:
|
||||
%out_price_btn.disable(true)
|
||||
else:
|
||||
%out_price_btn.disable(false)
|
||||
#报价历史数组
|
||||
#[[[npc序列,价格],[npc序列(玩家为-1),价格]....],...]
|
||||
|
||||
var auction_price_arr:Array=[[]]
|
||||
#最小加价
|
||||
var min_price_add:int=10
|
||||
func start_turn():
|
||||
var res_arr=auction_price_arr[now_auction_item_ind]
|
||||
var now_item=item_arr[now_auction_item_ind]
|
||||
for i in npc_arr.size():
|
||||
var now_price:int=0
|
||||
if res_arr.size()==0:
|
||||
now_price=now_item["price"]/2
|
||||
else:
|
||||
now_price=res_arr[res_arr.size()-1][1]
|
||||
var npc_data=npc_arr[i]
|
||||
var out_price=auction_bid_decision(npc_data["gold"],now_item["price"],npc_need_item_arr[i][now_auction_item_ind],now_price,min_price_add)
|
||||
if out_price!=null:
|
||||
|
||||
res_arr.append([i,out_price])
|
||||
timer.start(30)
|
||||
update_out_price()
|
||||
|
||||
const AUCTION_LABEL = preload("res://scene/auction_label.tscn")
|
||||
|
||||
func update_out_price():
|
||||
for i in %label_add_pos.get_children():
|
||||
i.queue_free()
|
||||
var res_arr
|
||||
if now_index<auction_price_arr.size():
|
||||
res_arr=auction_price_arr[now_index]
|
||||
else:
|
||||
res_arr=[]
|
||||
for i in res_arr:
|
||||
var new_label=AUCTION_LABEL.instantiate()
|
||||
var str=""
|
||||
if i[0]>=0:
|
||||
str+=npc_arr[i[0]]["name"]
|
||||
else:
|
||||
str+="我"
|
||||
new_label.add_theme_color_override("font_color",Color.GREEN)
|
||||
if i[1]<0:
|
||||
str+="拍下了此物品"
|
||||
else:
|
||||
str+=(":出价"+str(i[1]))
|
||||
pass
|
||||
new_label.text=str
|
||||
%label_add_pos.add_child(new_label)
|
||||
|
||||
|
||||
pass
|
||||
func set_npc_arr_and_item_arr(npc_arr:Array,item_arr:Array):
|
||||
npc_need_item_arr.clear()
|
||||
auction_price_arr=[[]]
|
||||
self.npc_arr=npc_arr
|
||||
self.item_arr=item_arr
|
||||
#填写随机需求
|
||||
for i in npc_arr.size():
|
||||
npc_need_item_arr.append([])
|
||||
for j in item_arr:
|
||||
npc_need_item_arr[i].append(randf_range(0.5,1))
|
||||
now_auction_item_ind=0
|
||||
start_turn()
|
||||
timer.start()
|
||||
texture_arr.clear()
|
||||
for i in item_arr:
|
||||
texture_arr.append(Database.get_texture(i["texture"]))
|
||||
init_texture()
|
||||
pass
|
||||
|
||||
@onready var timer: Timer = $Timer
|
||||
|
||||
func _on_timer_timeout() -> void:
|
||||
timer.stop()
|
||||
var res_arr=auction_price_arr[now_auction_item_ind]
|
||||
if res_arr.size()!=0:
|
||||
var left_arr=res_arr[res_arr.size()-1]
|
||||
var left_ind:int=left_arr[0]
|
||||
var left_price:int=left_arr[1]
|
||||
if left_ind<0:
|
||||
Global.add_item_to_bag(item_arr[now_auction_item_ind])
|
||||
Global.change_currency_game(1,-left_price)
|
||||
pass
|
||||
else:
|
||||
add_item_to_npc(item_arr[now_auction_item_ind],npc_arr[left_ind])
|
||||
res_arr.append([left_ind,-1])
|
||||
pass
|
||||
if now_index==now_auction_item_ind:
|
||||
right()
|
||||
|
||||
now_auction_item_ind+=1
|
||||
if now_auction_item_ind<item_arr.size():
|
||||
auction_price_arr.append([])
|
||||
start_turn()
|
||||
else:
|
||||
_on_close_pressed()
|
||||
pass
|
||||
#拍卖结束
|
||||
pass # Replace with function body.
|
||||
#向NPC背包中添加item
|
||||
func add_item_to_npc(item_data:Dictionary,npc_data:Dictionary):
|
||||
if item_data["allow_merge"]:
|
||||
for i in npc_data["sold_item"]:
|
||||
if i["id"]==item_data["id"]:
|
||||
if i.has("num"):
|
||||
i["num"]+=item_data["num"]
|
||||
else:
|
||||
i["num"]=2
|
||||
return
|
||||
npc_data["sold_item"].append(item_data)
|
||||
else:
|
||||
npc_data["sold_item"].append(item_data)
|
||||
|
||||
#钱 npc_data["gold"]
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_out_price_btn_pressed() -> void:
|
||||
var price=%price_edit.value
|
||||
var res_arr=auction_price_arr[now_auction_item_ind]
|
||||
var now_item=item_arr[now_auction_item_ind]
|
||||
var now_price:int=0
|
||||
if res_arr.size()==0:
|
||||
now_price=now_item["price"]/2
|
||||
else:
|
||||
now_price=res_arr[res_arr.size()-1][1]
|
||||
if price-now_price>=min_price_add and price<=Global.get_currency_game(1):
|
||||
res_arr.append([-1,price])
|
||||
timer.stop()
|
||||
update_out_price()
|
||||
start_turn()
|
||||
timer.start(30)
|
||||
pass # Replace with function body.
|
||||
|
||||
func get_now_item():
|
||||
if now_index<item_arr.size():
|
||||
return item_arr[now_index]
|
||||
else:
|
||||
return null
|
||||
|
||||
|
||||
func _on_jump_pressed() -> void:
|
||||
_on_timer_timeout()
|
||||
pass # Replace with function body.
|
||||
|
||||
signal close
|
||||
func _on_close_pressed() -> void:
|
||||
self.hide()
|
||||
close.emit()
|
||||
timer.stop()
|
||||
pass # Replace with function body.
|
@ -1,10 +1,15 @@
|
||||
[gd_scene load_steps=22 format=3 uid="uid://cykq0nd4y57xe"]
|
||||
[gd_scene load_steps=35 format=3 uid="uid://cykq0nd4y57xe"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://uqdkgws2e3dt" path="res://res/ui/ui_029_multi_indetification/tuceng384.png" id="1_6ffgs"]
|
||||
[ext_resource type="Script" path="res://scene/auction.gd" id="1_butyf"]
|
||||
[ext_resource type="Texture2D" uid="uid://dxu1jj5xxy21e" path="res://res/ui/ui_031_auction/juxing1.png" id="2_5wobl"]
|
||||
[ext_resource type="Texture2D" uid="uid://be3n1b7s2o4mm" path="res://icon.svg" id="2_ow75k"]
|
||||
[ext_resource type="Texture2D" uid="uid://cq18f4k8fhpn" path="res://res/ui/ui_031_auction/juxing2.png" id="3_8sfr8"]
|
||||
[ext_resource type="Texture2D" uid="uid://da4mwbefqkahf" path="res://test/texture/tsubaki_1.png" id="3_ehg1w"]
|
||||
[ext_resource type="Texture2D" uid="uid://dltavh71w452u" path="res://test/texture/test_tower.jpg" id="4_3kwax"]
|
||||
[ext_resource type="Texture2D" uid="uid://bv2ns53p6wrbk" path="res://res/ui/ui_031_auction/juxing10.png" id="4_wpjm4"]
|
||||
[ext_resource type="Texture2D" uid="uid://bsw6sxyhckrp" path="res://res/ui/ui_031_auction/paimaihang.png" id="5_a1r23"]
|
||||
[ext_resource type="Texture2D" uid="uid://cla7m1ytnm1hj" path="res://test/texture/test_texture.png" id="5_u4sbb"]
|
||||
[ext_resource type="Texture2D" uid="uid://dnw2askasnnuh" path="res://res/ui/ui_031_auction/tuceng1.png" id="6_d87c1"]
|
||||
[ext_resource type="Texture2D" uid="uid://bygnvkcpv0eox" path="res://res/ui/ui_031_auction/tuceng388.png" id="7_36vno"]
|
||||
[ext_resource type="Texture2D" uid="uid://dhrjshw4swani" path="res://res/ui/ui_031_auction/tuceng389.png" id="8_cxqd0"]
|
||||
@ -13,6 +18,7 @@
|
||||
[ext_resource type="PackedScene" uid="uid://bdlo2wn4qnygv" path="res://scene/tool/tool_button.tscn" id="11_yjciw"]
|
||||
[ext_resource type="Texture2D" uid="uid://dujkfvxy78pu" path="res://res/ui/ui_031_auction/juxing5_2.png" id="12_5iejr"]
|
||||
[ext_resource type="Texture2D" uid="uid://butvsyebc5fep" path="res://res/ui/ui_031_auction/juxing5_1.png" id="13_ubgv7"]
|
||||
[ext_resource type="Script" path="res://scene/auction_center_mask.gd" id="14_8d3i1"]
|
||||
[ext_resource type="Texture2D" uid="uid://c3nm3avrqj4pf" path="res://res/ui/ui_031_auction/tuceng385.png" id="14_bdkb3"]
|
||||
|
||||
[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_ycg8o"]
|
||||
@ -37,11 +43,42 @@ gradient = SubResource("Gradient_brav2")
|
||||
fill_from = Vector2(0.5, 0)
|
||||
fill_to = Vector2(0.5, 1)
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_kjvk4"]
|
||||
[sub_resource type="StyleBoxTexture" id="StyleBoxTexture_ycvga"]
|
||||
texture = ExtResource("7_36vno")
|
||||
texture_margin_left = 35.1384
|
||||
texture_margin_top = 216.687
|
||||
texture_margin_right = 33.6743
|
||||
texture_margin_bottom = 203.51
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_bsiux"]
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_k2jnl"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_5lc4h"]
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_evaax"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_2nda4"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_8y2eq"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ors3e"]
|
||||
|
||||
[sub_resource type="Theme" id="Theme_t6pgw"]
|
||||
default_font_size = 59
|
||||
LineEdit/colors/font_color = Color(0, 0, 0, 1)
|
||||
LineEdit/styles/focus = SubResource("StyleBoxEmpty_k2jnl")
|
||||
LineEdit/styles/normal = SubResource("StyleBoxEmpty_evaax")
|
||||
LineEdit/styles/read_only = SubResource("StyleBoxEmpty_2nda4")
|
||||
Panel/styles/panel = SubResource("StyleBoxEmpty_8y2eq")
|
||||
PanelContainer/styles/panel = SubResource("StyleBoxEmpty_ors3e")
|
||||
|
||||
[sub_resource type="CompressedTexture2D" id="CompressedTexture2D_ioyj6"]
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_d48ll"]
|
||||
offsets = PackedFloat32Array(0.102362, 0.267717, 0.724409, 0.913386)
|
||||
colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_1benm"]
|
||||
gradient = SubResource("Gradient_d48ll")
|
||||
width = 1080
|
||||
use_hdr = true
|
||||
|
||||
[node name="auction" type="Control"]
|
||||
layout_mode = 3
|
||||
@ -50,6 +87,8 @@ anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_butyf")
|
||||
texture_arr = Array[Texture2D]([ExtResource("2_ow75k"), ExtResource("3_ehg1w"), ExtResource("4_3kwax"), ExtResource("5_u4sbb")])
|
||||
|
||||
[node name="bg" type="TextureRect" parent="."]
|
||||
layout_mode = 1
|
||||
@ -79,6 +118,7 @@ layout_mode = 2
|
||||
theme_override_styles/panel = SubResource("StyleBoxTexture_ycg8o")
|
||||
|
||||
[node name="Panel" type="Panel" parent="MarginContainer/Panel"]
|
||||
z_index = 1
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.0471645
|
||||
@ -119,116 +159,12 @@ anchor_bottom = 0.963183
|
||||
horizontal_scroll_mode = 0
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/Panel/Panel/ScrollContainer"]
|
||||
[node name="label_add_pos" type="VBoxContainer" parent="MarginContainer/Panel/Panel/ScrollContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 6
|
||||
|
||||
[node name="Label" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label2" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label3" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label4" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label5" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label6" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label7" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label8" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label9" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label10" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label11" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label12" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label13" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label14" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Label15" type="Label" parent="MarginContainer/Panel/Panel/ScrollContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="MarginContainer/Panel"]
|
||||
layout_mode = 0
|
||||
anchor_left = 0.425604
|
||||
@ -250,6 +186,7 @@ texture = ExtResource("5_a1r23")
|
||||
stretch_mode = 3
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/Panel"]
|
||||
z_index = 1
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.368894
|
||||
@ -265,10 +202,30 @@ size_flags_horizontal = 0
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("6_d87c1")
|
||||
|
||||
[node name="TextureRect2" type="TextureRect" parent="MarginContainer/Panel/HBoxContainer"]
|
||||
[node name="left" parent="MarginContainer/Panel/HBoxContainer/TextureRect" instance=ExtResource("11_yjciw")]
|
||||
layout_mode = 1
|
||||
|
||||
[node name="PanelContainer" type="Panel" parent="MarginContainer/Panel/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
texture = ExtResource("7_36vno")
|
||||
theme_override_styles/panel = SubResource("StyleBoxTexture_ycvga")
|
||||
|
||||
[node name="aspect" type="AspectRatioContainer" parent="MarginContainer/Panel/HBoxContainer/PanelContainer"]
|
||||
layout_mode = 2
|
||||
anchor_left = 0.111
|
||||
anchor_top = 0.176
|
||||
anchor_right = 0.892
|
||||
anchor_bottom = 0.822
|
||||
offset_left = -5.959
|
||||
offset_top = -90.992
|
||||
offset_right = 5.85199
|
||||
offset_bottom = 92.026
|
||||
ratio = 0.7
|
||||
|
||||
[node name="center_mask" type="Control" parent="MarginContainer/Panel/HBoxContainer/PanelContainer/aspect"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
script = ExtResource("14_8d3i1")
|
||||
|
||||
[node name="TextureRect3" type="TextureRect" parent="MarginContainer/Panel/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
@ -276,13 +233,18 @@ size_flags_horizontal = 8
|
||||
size_flags_vertical = 4
|
||||
texture = ExtResource("8_cxqd0")
|
||||
|
||||
[node name="right" parent="MarginContainer/Panel/HBoxContainer/TextureRect3" instance=ExtResource("11_yjciw")]
|
||||
layout_mode = 1
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/Panel"]
|
||||
layout_mode = 0
|
||||
offset_left = 692.0
|
||||
offset_top = 720.0
|
||||
offset_right = 1131.0
|
||||
offset_bottom = 760.0
|
||||
anchor_left = 0.388546
|
||||
anchor_top = 0.713578
|
||||
anchor_right = 0.635036
|
||||
anchor_bottom = 0.962339
|
||||
offset_bottom = -211.0
|
||||
theme_override_constants/separation = 32
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="TextureRect2" type="TextureRect" parent="MarginContainer/Panel/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
@ -306,17 +268,16 @@ text = "报价:"
|
||||
horizontal_alignment = 2
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="LineEdit" type="LineEdit" parent="MarginContainer/Panel/VBoxContainer/TextureRect2/HBoxContainer"]
|
||||
[node name="price_edit" type="SpinBox" parent="MarginContainer/Panel/VBoxContainer/TextureRect2/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_colors/font_selected_color = Color(0, 0, 0, 1)
|
||||
theme_override_colors/font_uneditable_color = Color(0, 0, 0, 1)
|
||||
theme_override_colors/font_color = Color(0, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 48
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_kjvk4")
|
||||
theme_override_styles/read_only = SubResource("StyleBoxEmpty_bsiux")
|
||||
theme_override_styles/normal = SubResource("StyleBoxEmpty_5lc4h")
|
||||
text = "9999"
|
||||
theme = SubResource("Theme_t6pgw")
|
||||
theme_override_icons/updown = SubResource("CompressedTexture2D_ioyj6")
|
||||
max_value = 99999.0
|
||||
value = 140.0
|
||||
allow_greater = true
|
||||
update_on_text_changed = true
|
||||
|
||||
[node name="TextureRect3" type="TextureRect" parent="MarginContainer/Panel/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
@ -336,16 +297,18 @@ text = "出价"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ToolButton" parent="MarginContainer/Panel/VBoxContainer/TextureRect3" instance=ExtResource("11_yjciw")]
|
||||
[node name="out_price_btn" parent="MarginContainer/Panel/VBoxContainer/TextureRect3" instance=ExtResource("11_yjciw")]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
|
||||
[node name="HBoxContainer2" type="HBoxContainer" parent="MarginContainer/Panel"]
|
||||
layout_mode = 0
|
||||
offset_left = 1197.0
|
||||
offset_top = 878.0
|
||||
offset_right = 1777.0
|
||||
offset_bottom = 971.0
|
||||
anchor_left = 0.672094
|
||||
anchor_top = 0.870169
|
||||
anchor_right = 0.997754
|
||||
anchor_bottom = 0.962339
|
||||
theme_override_constants/separation = 43
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="MarginContainer/Panel/HBoxContainer2"]
|
||||
layout_mode = 2
|
||||
@ -367,7 +330,7 @@ horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="ToolButton" parent="MarginContainer/Panel/HBoxContainer2/TextureRect" instance=ExtResource("11_yjciw")]
|
||||
[node name="jump" parent="MarginContainer/Panel/HBoxContainer2/TextureRect" instance=ExtResource("11_yjciw")]
|
||||
layout_mode = 1
|
||||
|
||||
[node name="TextureRect2" type="TextureRect" parent="MarginContainer/Panel/HBoxContainer2"]
|
||||
@ -402,5 +365,90 @@ offset_bottom = 40.0
|
||||
grow_horizontal = 0
|
||||
texture = ExtResource("14_bdkb3")
|
||||
|
||||
[node name="ToolButton" parent="MarginContainer/Panel/TextureRect2" instance=ExtResource("11_yjciw")]
|
||||
[node name="close" parent="MarginContainer/Panel/TextureRect2" instance=ExtResource("11_yjciw")]
|
||||
layout_mode = 1
|
||||
|
||||
[node name="left_mark" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchor_left = 0.183854
|
||||
anchor_top = 0.437963
|
||||
anchor_right = 0.183854
|
||||
anchor_bottom = 0.437963
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="left_out_mark" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchor_left = -0.203646
|
||||
anchor_top = 0.437963
|
||||
anchor_right = -0.203646
|
||||
anchor_bottom = 0.437963
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="right_mark" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchor_left = 0.819271
|
||||
anchor_top = 0.437963
|
||||
anchor_right = 0.819271
|
||||
anchor_bottom = 0.437963
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="right_out_mark" type="Control" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 1
|
||||
anchor_left = 1.18594
|
||||
anchor_top = 0.437963
|
||||
anchor_right = 1.18594
|
||||
anchor_bottom = 0.437963
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="test" type="Button" parent="."]
|
||||
layout_mode = 0
|
||||
offset_right = 305.0
|
||||
offset_bottom = 128.0
|
||||
text = "测试"
|
||||
|
||||
[node name="card_add_pos" type="TextureRect" parent="."]
|
||||
unique_name_in_owner = true
|
||||
clip_children = 1
|
||||
clip_contents = true
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_left = 0.0359375
|
||||
anchor_top = 0.0324074
|
||||
anchor_right = 0.961458
|
||||
anchor_bottom = 0.966667
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
texture = SubResource("GradientTexture1D_1benm")
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="Timer" type="Timer" parent="."]
|
||||
wait_time = 30.0
|
||||
one_shot = true
|
||||
|
||||
[node name="time" type="Label" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 0
|
||||
anchor_left = 0.625
|
||||
anchor_top = 0.207407
|
||||
anchor_right = 0.704687
|
||||
anchor_bottom = 0.271296
|
||||
offset_top = 1.52588e-05
|
||||
theme_override_colors/font_color = Color(1, 0, 0, 1)
|
||||
theme_override_font_sizes/font_size = 43
|
||||
text = "10"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
metadata/_edit_use_anchors_ = true
|
||||
|
||||
[connection signal="pressed" from="MarginContainer/Panel/HBoxContainer/TextureRect/left" to="." method="left"]
|
||||
[connection signal="pressed" from="MarginContainer/Panel/HBoxContainer/TextureRect3/right" to="." method="right"]
|
||||
[connection signal="pressed" from="MarginContainer/Panel/VBoxContainer/TextureRect3/out_price_btn" to="." method="_on_out_price_btn_pressed"]
|
||||
[connection signal="pressed" from="MarginContainer/Panel/HBoxContainer2/TextureRect/jump" to="." method="_on_jump_pressed"]
|
||||
[connection signal="pressed" from="MarginContainer/Panel/TextureRect2/close" to="." method="_on_close_pressed"]
|
||||
[connection signal="pressed" from="test" to="." method="_on_test_pressed"]
|
||||
[connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"]
|
||||
|
19
scene/auction_card.gd
Normal file
19
scene/auction_card.gd
Normal file
@ -0,0 +1,19 @@
|
||||
extends TextureRect
|
||||
class_name AuctionCard
|
||||
@export var animation_time:float=0.2
|
||||
func set_item_texture(texture:Texture2D):
|
||||
$TextureRect.texture=texture
|
||||
var tween:Tween
|
||||
func move_size_to(pos:Vector2,_size:Vector2,is_queue_free_finish:bool=false):
|
||||
if tween!=null:
|
||||
tween.kill()
|
||||
tween=create_tween()
|
||||
tween.tween_property(self,"global_position",pos,animation_time)
|
||||
tween.parallel().tween_property(self,"size",_size,animation_time)
|
||||
tween.set_parallel(false)
|
||||
|
||||
if is_queue_free_finish:
|
||||
tween.tween_callback(queue_free)
|
||||
else:
|
||||
tween.parallel().tween_property(self,"modulate:a",1,animation_time)
|
||||
|
24
scene/auction_card.tscn
Normal file
24
scene/auction_card.tscn
Normal file
@ -0,0 +1,24 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://bh7cd33u0jy7w"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://dchivamy84hsy" path="res://res/ui/ui_031_auction/juxing3.png" id="1_fxc5c"]
|
||||
[ext_resource type="Script" path="res://scene/auction_card.gd" id="2_877km"]
|
||||
|
||||
[node name="auction_card" type="TextureRect"]
|
||||
modulate = Color(1, 1, 1, 0)
|
||||
offset_right = 348.0
|
||||
offset_bottom = 425.0
|
||||
mouse_filter = 2
|
||||
texture = ExtResource("1_fxc5c")
|
||||
expand_mode = 1
|
||||
script = ExtResource("2_877km")
|
||||
|
||||
[node name="TextureRect" type="TextureRect" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
14
scene/auction_center_mask.gd
Normal file
14
scene/auction_center_mask.gd
Normal file
@ -0,0 +1,14 @@
|
||||
extends Control
|
||||
var data:Dictionary={}
|
||||
const BAG_SIDE_CARD_INTRODUCTION = preload("res://scene/bag_side_card_introduction.tscn")
|
||||
|
||||
func _get_tooltip(at_position: Vector2) -> String:
|
||||
|
||||
return JSON.stringify(owner.get_now_item())
|
||||
pass
|
||||
|
||||
func _make_custom_tooltip(for_text: String) -> Object:
|
||||
var new_card=BAG_SIDE_CARD_INTRODUCTION.instantiate()
|
||||
new_card.data=JSON.parse_string(for_text)
|
||||
return new_card
|
||||
pass
|
7
scene/auction_label.tscn
Normal file
7
scene/auction_label.tscn
Normal file
@ -0,0 +1,7 @@
|
||||
[gd_scene format=3 uid="uid://d1510psvrrvko"]
|
||||
|
||||
[node name="auction_label" type="Label"]
|
||||
theme_override_font_sizes/font_size = 36
|
||||
text = "xxx:出价xxxxx"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
@ -110,6 +110,6 @@ unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/line_spacing = 11
|
||||
theme_override_font_sizes/font_size = 24
|
||||
theme_override_font_sizes/font_size = 15
|
||||
text = "物品介绍物品介绍物品介绍物品介绍物品介绍物品介绍物品介绍物品介绍物品介绍物品介绍物品介绍物品介绍物品介绍物品"
|
||||
autowrap_mode = 3
|
||||
|
@ -132,3 +132,17 @@ func show_identification(id:String):
|
||||
var indetification=Database.get_identifation_data(id)
|
||||
%identification.set_data(indetification)
|
||||
pass
|
||||
|
||||
func show_auction(npc_id_array:Array,item_id_array:Array):
|
||||
%auction.show()
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
var npc_data_arr:Array=[]
|
||||
var item_data_arr:Array=[]
|
||||
for i in npc_id_array:
|
||||
var npc_data=Global.get_now_game_npc_data(i)
|
||||
npc_data_arr.append(npc_data)
|
||||
for i in item_id_array:
|
||||
var item_data=Database.get_item_data(i)
|
||||
item_data_arr.append(item_data)
|
||||
%auction.set_npc_arr_and_item_arr(npc_data_arr,item_data_arr)
|
||||
|
@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=29 format=3 uid="uid://bht5sd88340s5"]
|
||||
[gd_scene load_steps=30 format=3 uid="uid://bht5sd88340s5"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://5vyvaedcfv38" path="res://res/ui/ui_019_game_flow/tuceng1.png" id="1_gjw3y"]
|
||||
[ext_resource type="Script" path="res://scene/game_flow.gd" id="1_w6afk"]
|
||||
@ -22,6 +22,7 @@
|
||||
[ext_resource type="PackedScene" uid="uid://cewsjbnll1iol" path="res://scene/trade.tscn" id="20_ql26d"]
|
||||
[ext_resource type="PackedScene" uid="uid://ln0ri824gh2c" path="res://scene/save_and_load.tscn" id="21_2j45w"]
|
||||
[ext_resource type="PackedScene" uid="uid://mcf2riinvukc" path="res://scene/single_identification.tscn" id="22_0wbgg"]
|
||||
[ext_resource type="PackedScene" uid="uid://cykq0nd4y57xe" path="res://scene/auction.tscn" id="23_mavou"]
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_4wq1v"]
|
||||
|
||||
@ -466,6 +467,11 @@ unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
|
||||
[node name="auction" parent="." instance=ExtResource("23_mavou")]
|
||||
unique_name_in_owner = true
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
|
||||
[connection signal="pressed" from="hbox/TextureRect/head_btn" to="." method="_on_head_btn_pressed"]
|
||||
[connection signal="pressed" from="HBoxContainer/TextureRect/save" to="." method="_on_save_pressed"]
|
||||
[connection signal="pressed" from="HBoxContainer/TextureRect2/load" to="." method="_on_load_pressed"]
|
||||
|
@ -52,6 +52,21 @@ content_margin_right = 97.0
|
||||
content_margin_bottom = 7.0
|
||||
texture = ExtResource("16_nbuwj")
|
||||
|
||||
[sub_resource type="Animation" id="Animation_d6bed"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("card_show:modulate")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(1, 1, 1, 0)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_7g1t6"]
|
||||
resource_name = "show_card"
|
||||
length = 0.25
|
||||
@ -68,21 +83,6 @@ tracks/0/keys = {
|
||||
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_d6bed"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("card_show:modulate")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(1, 1, 1, 0)]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_bx88s"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_d6bed"),
|
||||
|
Loading…
Reference in New Issue
Block a user