1
1
mirror of https://github.com/Rundll86/Dog-Lynx-And-HCN.git synced 2026-05-27 22:41:56 +08:00

feat(武器系统): 添加自动强化和一键强化功能

- 新增自动强化开关和按钮图标资源
- 实现武器自动强化逻辑
- 添加一键强化功能可连续升级
- 优化武器卡UI布局和样式
- 增加强化操作时的提示信息
This commit is contained in:
2026-05-03 17:45:00 +08:00
parent bc89c93feb
commit 9df62992e5
16 changed files with 351 additions and 33 deletions
+43 -12
View File
@@ -5,7 +5,12 @@
[ext_resource type="Texture2D" uid="uid://dwwpkn4q07ja2" path="res://icon.svg" id="2_j0w4u"]
[ext_resource type="PackedScene" uid="uid://ch81vd3awkmhk" path="res://components/UI/WeaponName.tscn" id="3_qv0b1"]
[ext_resource type="Texture2D" uid="uid://k13cte17httt" path="res://resources/items/energy.svg" id="4_6gohw"]
[ext_resource type="Texture2D" uid="uid://bq8wf01j5ulwe" path="res://resources/ui/update-level.svg" id="4_do015"]
[ext_resource type="Texture2D" uid="uid://f5rjbiw18tew" path="res://resources/ui/auto.png" id="4_h3enm"]
[ext_resource type="Texture2D" uid="uid://bqplsjw07wkn8" path="res://resources/ui/update-soul.svg" id="4_j0v0r"]
[ext_resource type="PackedScene" uid="uid://bbm8l3hr4ihar" path="res://components/UI/ItemShow.tscn" id="4_k01vb"]
[ext_resource type="Texture2D" uid="uid://clobdvvfmj618" path="res://resources/ui/downdate-soul.svg" id="5_j7v7d"]
[ext_resource type="Texture2D" uid="uid://lrvlfvt55j0" path="res://resources/ui/once-update.svg" id="5_jv1l6"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_n2ewr"]
content_margin_left = 30.0
@@ -13,15 +18,17 @@ content_margin_top = 20.0
content_margin_right = 30.0
content_margin_bottom = 20.0
bg_color = Color(0, 0, 0, 0.5)
border_width_left = 2
border_width_top = 2
border_width_right = 2
border_width_bottom = 2
border_color = Color(0, 0, 0, 0.75)
corner_radius_top_left = 5
corner_radius_top_right = 5
corner_radius_bottom_right = 5
corner_radius_bottom_left = 5
border_width_left = 10
border_width_top = 10
border_width_right = 10
border_width_bottom = 10
border_color = Color(1, 1, 1, 1)
border_blend = true
corner_radius_top_left = 15
corner_radius_top_right = 15
corner_radius_bottom_right = 15
corner_radius_bottom_left = 15
corner_detail = 1
[sub_resource type="LabelSettings" id="LabelSettings_b3nsw"]
font_size = 12
@@ -50,11 +57,32 @@ alignment = 1
[node name="wrapper" type="VBoxContainer" parent="container" unique_id=673686123]
layout_mode = 2
[node name="updates" type="HBoxContainer" parent="container/wrapper" unique_id=901133416]
layout_mode = 2
[node name="autoUpdateBtn" type="Button" parent="container/wrapper/updates" unique_id=287764631]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_fwkd3")
toggle_mode = true
text = "自动强化"
icon = ExtResource("4_h3enm")
[node name="onceUpdateBtn" type="Button" parent="container/wrapper/updates" unique_id=1523224875]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_fwkd3")
text = "一键强化"
icon = ExtResource("5_jv1l6")
[node name="updateBtn" type="Button" parent="container/wrapper" unique_id=248603389]
unique_name_in_owner = true
layout_mode = 2
theme = ExtResource("2_fwkd3")
text = "升级"
text = "强化武器"
icon = ExtResource("4_do015")
[node name="souls" type="HBoxContainer" parent="container/wrapper" unique_id=1439164733]
layout_mode = 2
@@ -64,14 +92,16 @@ unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_fwkd3")
text = "提炼"
text = "灵魂·提炼"
icon = ExtResource("4_j0v0r")
[node name="inlayBtn" type="Button" parent="container/wrapper/souls" unique_id=1008423578]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
theme = ExtResource("2_fwkd3")
text = "镶嵌"
text = "灵魂·镶嵌"
icon = ExtResource("5_j7v7d")
[node name="info" type="VBoxContainer" parent="container" unique_id=1625294072]
layout_mode = 2
@@ -162,6 +192,7 @@ fit_content = true
[node name="tease" type="Label" parent="container" unique_id=689277044]
unique_name_in_owner = true
visible = false
layout_mode = 2
label_settings = SubResource("LabelSettings_b3nsw")
horizontal_alignment = 1
Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

+40
View File
@@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://f5rjbiw18tew"
path="res://.godot/imported/auto.png-ad5b7fc14787a8899369c158f319b816.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://resources/ui/auto.png"
dest_files=["res://.godot/imported/auto.png-ad5b7fc14787a8899369c158f319b816.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
+1
View File
@@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12.61111" height="12.61111" viewBox="0,0,12.61111,12.61111"><g transform="translate(-233.69444,-173.69444)"><g stroke-miterlimit="10"><path d="M234.44444,180c0,-3.06825 2.48731,-5.55556 5.55556,-5.55556c3.06825,0 5.55556,2.48731 5.55556,5.55556c0,3.06825 -2.48731,5.55556 -5.55556,5.55556c-3.06825,0 -5.55556,-2.48731 -5.55556,-5.55556z" fill="none" stroke="#ffffff" stroke-width="1.5"/><text transform="translate(237.46,182.24046) scale(0.19419,0.19419)" font-size="40" xml:space="preserve" fill="#ffffff" stroke="none" stroke-width="1" font-family="Sans Serif" font-weight="normal" text-anchor="start"><tspan x="0" dy="0">A</tspan></text></g></g></svg><!--rotationCenter:6.305555555555571:6.305555555555571-->

After

Width:  |  Height:  |  Size: 815 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bsk7o4p3bhab1"
path="res://.godot/imported/auto.svg-253ef1198e5abac5b88bffc824c6c2c2.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://resources/ui/auto.svg"
dest_files=["res://.godot/imported/auto.svg-253ef1198e5abac5b88bffc824c6c2c2.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="29.73512" height="16.03431" viewBox="0,0,29.73512,16.03431"><g transform="translate(-225.50744,-171.98285)"><g stroke-linecap="round" stroke-miterlimit="10"><g><g fill="#ffffff" stroke="none" stroke-width="0"><g><path d="M235.88937,180.00192h-4.72955l2.35344,-8.01907l2.37028,8.07646"/><path d="M235.88354,179.9407l-2.37028,8.07646l-2.35344,-8.01907h4.72955"/></g><g><path d="M233.52651,177.63522v4.72955l-8.01907,-2.35344l8.07646,-2.37028"/><path d="M233.46529,177.64106l8.07646,2.37028l-8.01907,2.35344v-4.72955"/></g></g><g fill="none" stroke="#ffffff" stroke-width="1.5"><path d="M252.91194,174.53216h-7.39415"/><path d="M248.01135,184.13533v-9.32134"/><g><path d="M249.1878,185.46784l-5.25063,-5.25063"/><path d="M254.49256,180.21721l-5.25063,5.25063"/></g><path d="M250.41838,174.79426v9.32134"/></g></g></g></g></svg><!--rotationCenter:14.492560184560602:8.01714857142855-->

After

Width:  |  Height:  |  Size: 985 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://clobdvvfmj618"
path="res://.godot/imported/downdate-soul.svg-4940d058a3f28afe423042c147fa67ea.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://resources/ui/downdate-soul.svg"
dest_files=["res://.godot/imported/downdate-soul.svg-4940d058a3f28afe423042c147fa67ea.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="28.05539" height="12.43568" viewBox="0,0,28.05539,12.43568"><g transform="translate(-225.9723,-173.78216)"><g fill="none" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-miterlimit="10"><g><path d="M228.30292,185.46784h7.39415"/><path d="M230.79648,175.86467v9.32134"/><g><path d="M226.7223,179.78279l5.25063,-5.25063"/><path d="M232.02706,174.53216l5.25063,5.25063"/></g><path d="M233.20351,175.8844v9.32134"/></g><g><path d="M244.30293,185.46784h7.39415"/><path d="M246.79649,175.86467v9.32134"/><g><path d="M242.72231,179.78279l5.25063,-5.25063"/><path d="M248.02707,174.53216l5.25063,5.25063"/></g><path d="M249.20352,175.8844v9.32134"/></g></g></g></svg><!--rotationCenter:14.027695000000165:6.217839999999995-->

After

Width:  |  Height:  |  Size: 839 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://lrvlfvt55j0"
path="res://.godot/imported/once-update.svg-f4b1e5659f6e3a349130c0b70453ee90.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://resources/ui/once-update.svg"
dest_files=["res://.godot/imported/once-update.svg-f4b1e5659f6e3a349130c0b70453ee90.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12.05539" height="12.43568" viewBox="0,0,12.05539,12.43568"><g transform="translate(-233.9723,-173.78216)"><g fill="none" stroke="#ffffff" stroke-width="1.5" stroke-linecap="round" stroke-miterlimit="10"><g><path d="M236.30293,185.46784h7.39415"/><path d="M238.79649,185.18601v-9.32134"/><g><path d="M234.72231,179.78279l5.25063,-5.25063"/><path d="M245.2777,179.78279l-5.25063,-5.25063"/></g><path d="M241.20352,185.20574v-9.32134"/></g></g></g></svg><!--rotationCenter:6.027694999999994:6.217839999999995-->

After

Width:  |  Height:  |  Size: 613 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bq8wf01j5ulwe"
path="res://.godot/imported/update-level.svg-c783aa8a587d702ab0b6f2ab2cae6028.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://resources/ui/update-level.svg"
dest_files=["res://.godot/imported/update-level.svg-c783aa8a587d702ab0b6f2ab2cae6028.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+1
View File
@@ -0,0 +1 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="29.73512" height="16.03432" viewBox="0,0,29.73512,16.03432"><g transform="translate(-225.50744,-171.98284)"><g stroke-linecap="round" stroke-miterlimit="10"><g><g fill="#ffffff" stroke="none" stroke-width="0"><g><path d="M235.88937,180.00192h-4.72955l2.35344,-8.01907l2.37028,8.07646"/><path d="M235.88354,179.9407l-2.37028,8.07646l-2.35344,-8.01907h4.72955"/></g><g><path d="M233.52651,177.63522v4.72955l-8.01907,-2.35344l8.07646,-2.37028"/><path d="M233.46529,177.64106l8.07646,2.37028l-8.01907,2.35344v-4.72955"/></g></g><g fill="none" stroke="#ffffff" stroke-width="1.5"><path d="M245.51779,185.46784h7.39415"/><path d="M248.01135,185.18601v-9.32134"/><g><path d="M249.1878,174.53216l-5.25063,5.25063"/><path d="M249.24193,174.53216l5.25063,5.25063"/></g><path d="M250.41838,185.20574v-9.32134"/></g></g></g></g></svg><!--rotationCenter:14.492560184560602:8.017158571428553-->

After

Width:  |  Height:  |  Size: 984 B

+43
View File
@@ -0,0 +1,43 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bqplsjw07wkn8"
path="res://.godot/imported/update-soul.svg-6c04c5cb2f7fa02a9e0fd187158d3b93.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://resources/ui/update-soul.svg"
dest_files=["res://.godot/imported/update-soul.svg-6c04c5cb2f7fa02a9e0fd187158d3b93.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false
+4
View File
@@ -312,6 +312,10 @@ func bulletHit(bullet: BulletBase, crit: bool):
func collectItem(itemType: ItemStore.ItemType, amount: int):
inventory[itemType] += amount
playSound("collect")
for weapon in weapons:
if weapon.autoUpdate && weapon.canUpdate(self ):
weapon.updateApply(self )
UIState.showTip("[b]%s[/b]已自动强化!" % weapon.displayName)
func storeEnergy(value: float, dontChangeDirection: bool = false):
energy += value * fields.get(FieldStore.Entity.ENERGY_MULTIPILER)
energyChanged.emit(energy, dontChangeDirection)
+2
View File
@@ -66,6 +66,8 @@ func apply(entity: EntityBase):
entity.weaponStore.add_child(instance)
entity.rebuildWeaponIcons()
hide()
else:
UIState.showTip("物品不足!", TipBox.MessageType.ERROR)
selected.emit(allHave)
return allHave
func countOf(index: int) -> int:
+42 -21
View File
@@ -30,34 +30,53 @@ enum EmitType {
@export var debugRebuild: bool = false
@export var level: int = 0
@onready var avatarRect: TextureRect = $"%avatar"
@onready var nameLabel: WeaponName = $"%name"
@onready var sourceLabel: Label = $"%source"
@onready var teaseLabel: Label = $"%tease"
@onready var energyLabel: Label = $"%energy"
@onready var beachball: ItemShow = $"%beachball"
@onready var soul: ItemShow = $"%soul"
@onready var descriptionLabel: RichTextLabel = $"%description"
@onready var updateBtn: Button = $"%updateBtn"
@onready var extractBtn: Button = $"%extractBtn"
@onready var inlayBtn: Button = $"%inlayBtn"
@onready var sounds: Node2D = $"%sounds"
@onready var moveLeftBtn: Button = $"%moveleft"
@onready var moveRightBtn: Button = $"%moveright"
@onready var avatarRect: TextureRect = $%avatar
@onready var nameLabel: WeaponName = $%name
@onready var sourceLabel: Label = $%source
@onready var teaseLabel: Label = $%tease
@onready var energyLabel: Label = $%energy
@onready var beachball: ItemShow = $%beachball
@onready var soul: ItemShow = $%soul
@onready var descriptionLabel: RichTextLabel = $%description
@onready var sounds: Node2D = $%sounds
@onready var moveLeftBtn: Button = $%moveleft
@onready var moveRightBtn: Button = $%moveright
@onready var autoUpdateBtn: Button = $%autoUpdateBtn
@onready var onceUpdateBtn: Button = $%onceUpdateBtn
@onready var updateBtn: Button = $%updateBtn
@onready var extractBtn: Button = $%extractBtn
@onready var inlayBtn: Button = $%inlayBtn
var cooldownTimer: CooldownTimer = null
var originalStore: Dictionary = {}
var chargedTime: float = 0
var attackSpeed: float = 1
var looping: bool = false
var autoUpdate: bool = false
func _ready():
cooldownTimer = CooldownTimer.new()
cooldownTimer.cooldown = cooldown
originalStore = store
autoUpdateBtn.toggled.connect(
func(on: bool):
autoUpdate = on
)
onceUpdateBtn.pressed.connect(
func():
var count = 0
while canUpdate(UIState.player):
updateApply(UIState.player)
count += 1
if count > 0:
UIState.showTip("一键强化提升了[b]%d[/b]级!" % count)
else:
UIState.showTip("一键强化没有提升等级......", TipBox.MessageType.ERROR)
)
updateBtn.pressed.connect(
func():
apply(UIState.player)
updateApply(UIState.player)
)
extractBtn.pressed.connect(
func():
@@ -105,18 +124,20 @@ func _physics_process(_delta):
if debugRebuild:
rebuildInfo()
func canUpdate():
return UIState.player.hasItem({ItemStore.ItemType.BEACHBALL: costBeachball})
func canUpdate(entity: EntityBase):
return entity.hasItem({ItemStore.ItemType.BEACHBALL: costBeachball})
func canInlay():
return UIState.player.hasItem({ItemStore.ItemType.SOUL: soulLevel})
func apply(entity: EntityBase) -> bool:
if canUpdate():
func updateApply(entity: EntityBase) -> bool:
if canUpdate(entity):
level += 1
entity.inventory[ItemStore.ItemType.BEACHBALL] -= costBeachball
updateStore(level, entity)
costBeachball = floor(GameRule.weaponUpdateCost * costBeachball)
rebuildInfo(true)
return true
else:
UIState.showTip("沙滩球不足!", TipBox.MessageType.ERROR)
return false
func updateStore(to: int, entity: EntityBase):
store = update(to, originalStore.duplicate(), entity)
@@ -142,9 +163,9 @@ func rebuildInfo(showNext: bool = false):
beachball.count = costBeachball
soul.count = soulLevel
if is_instance_valid(UIState.player):
beachball.enough = canUpdate()
beachball.enough = canUpdate(UIState.player)
soul.enough = canInlay()
descriptionLabel.text = buildDescription(showNext && (canUpdate() || canInlay()))
descriptionLabel.text = buildDescription(showNext && (canUpdate(UIState.player) || canInlay()))
func formatValue(value: Variant, type: FieldStore.DataType) -> String:
if type == FieldStore.DataType.VALUE:
return "%.2f" % value