2025-08-26 18:09:04 +08:00
|
|
|
@tool
|
|
|
|
|
extends PanelContainer
|
2025-08-26 18:15:01 +08:00
|
|
|
class_name Feed
|
|
|
|
|
|
2025-08-27 16:33:21 +08:00
|
|
|
signal selected(applied: bool)
|
|
|
|
|
|
2025-09-21 13:34:51 +08:00
|
|
|
@export var avatarTexture: Texture2D = null
|
2025-08-26 18:15:01 +08:00
|
|
|
@export var displayName: String = "未命名饲料"
|
2025-08-28 08:51:08 +08:00
|
|
|
@export var quality: FeedName.Quality = FeedName.Quality.COMMON
|
2025-09-05 22:23:41 +08:00
|
|
|
@export var topic: FeedName.Topic = FeedName.Topic.SURVIVAL
|
2025-08-26 18:15:01 +08:00
|
|
|
@export var fields: Array[FieldStore.Entity] = []
|
2025-08-26 18:44:28 +08:00
|
|
|
@export var fieldValues: Array[float] = []
|
2025-09-21 16:35:49 +08:00
|
|
|
@export var weapons: Array[PackedScene] = []
|
2025-08-26 18:15:01 +08:00
|
|
|
@export var costs: Array[ItemStore.ItemType] = []
|
2025-08-26 18:44:28 +08:00
|
|
|
@export var costCounts: Array[int] = []
|
2025-08-26 18:15:01 +08:00
|
|
|
|
2025-08-26 18:44:28 +08:00
|
|
|
@onready var avatarRect: TextureRect = $"%avatar"
|
2025-08-28 08:51:08 +08:00
|
|
|
@onready var nameLabel: FeedName = $"%name"
|
2025-08-26 18:15:01 +08:00
|
|
|
@onready var fieldsBox: VBoxContainer = $"%fields"
|
2025-09-21 16:35:49 +08:00
|
|
|
@onready var weaponsBox: VBoxContainer = $"%weapons"
|
2025-08-26 18:44:28 +08:00
|
|
|
@onready var costsBox: GridContainer = $"%costs"
|
2025-08-26 20:46:02 +08:00
|
|
|
@onready var selectButton: Button = $"%selectBtn"
|
2026-01-30 11:50:16 +08:00
|
|
|
var freeToBuy: bool = false
|
2025-08-26 18:44:28 +08:00
|
|
|
|
2025-08-26 20:46:02 +08:00
|
|
|
func _ready():
|
|
|
|
|
selectButton.pressed.connect(
|
|
|
|
|
func():
|
2025-08-27 16:33:21 +08:00
|
|
|
apply(UIState.player)
|
2025-08-26 20:46:02 +08:00
|
|
|
)
|
2025-08-28 14:59:36 +08:00
|
|
|
rebuildInfo()
|
2025-08-26 20:46:02 +08:00
|
|
|
|
2025-08-27 11:48:54 +08:00
|
|
|
func allHad(entity: EntityBase) -> bool:
|
2026-01-30 11:50:16 +08:00
|
|
|
if freeToBuy:
|
|
|
|
|
return true
|
2025-08-26 19:35:26 +08:00
|
|
|
for i in range(min(costs.size(), costCounts.size())):
|
|
|
|
|
var item = costs[i]
|
2025-09-30 17:32:15 +08:00
|
|
|
var count = countOf(i)
|
2025-08-26 19:35:26 +08:00
|
|
|
if entity.inventory[item] < count:
|
2025-09-30 17:32:15 +08:00
|
|
|
return false
|
|
|
|
|
return true
|
2025-08-27 11:48:54 +08:00
|
|
|
func apply(entity: EntityBase):
|
|
|
|
|
var allHave = allHad(entity)
|
2025-08-26 19:35:26 +08:00
|
|
|
if allHave:
|
2026-04-12 15:43:13 +08:00
|
|
|
for i in range(min(costs.size(), costCounts.size())):
|
|
|
|
|
var item = costs[i]
|
|
|
|
|
var count = countOf(i)
|
|
|
|
|
if !freeToBuy || count < 0:
|
2026-04-02 22:39:29 +08:00
|
|
|
entity.inventory[item] -= count
|
2025-08-26 19:35:26 +08:00
|
|
|
for i in range(min(fields.size(), fieldValues.size())):
|
|
|
|
|
var field = fields[i]
|
|
|
|
|
var value = fieldValues[i]
|
2025-08-28 14:05:39 +08:00
|
|
|
var applier = FieldStore.entityApplier.get(field)
|
2025-08-27 10:23:57 +08:00
|
|
|
if !applier or applier.call(entity, value):
|
|
|
|
|
entity.fields[field] += value
|
2026-01-17 11:34:35 +08:00
|
|
|
entity.fields[field] = clamp(entity.fields[field], FieldStore.entityMinValueMap.get(field, 0), FieldStore.entityMaxValueMap.get(field, INF))
|
2025-09-21 17:00:11 +08:00
|
|
|
for i in weapons:
|
|
|
|
|
var instance = i.instantiate() as Weapon
|
|
|
|
|
if UIState.player.weaponBag.has(instance.displayName):
|
|
|
|
|
UIState.player.getItem({
|
|
|
|
|
ItemStore.ItemType.SOUL: instance.soulLevel
|
|
|
|
|
})
|
|
|
|
|
else:
|
|
|
|
|
instance.hide()
|
|
|
|
|
entity.weapons.append(instance)
|
|
|
|
|
entity.weaponBag.append(instance.displayName)
|
|
|
|
|
entity.weaponStore.add_child(instance)
|
|
|
|
|
entity.rebuildWeaponIcons()
|
2025-08-27 16:33:21 +08:00
|
|
|
hide()
|
2026-05-03 17:45:00 +08:00
|
|
|
else:
|
|
|
|
|
UIState.showTip("物品不足!", TipBox.MessageType.ERROR)
|
2025-08-27 16:33:21 +08:00
|
|
|
selected.emit(allHave)
|
2025-08-26 22:31:28 +08:00
|
|
|
return allHave
|
2025-09-30 17:32:15 +08:00
|
|
|
func countOf(index: int) -> int:
|
|
|
|
|
return ceil(costCounts[index] * multipiler())
|
2025-08-27 11:48:54 +08:00
|
|
|
func multipiler() -> float:
|
2025-09-30 17:39:32 +08:00
|
|
|
if is_instance_valid(UIState.player):
|
|
|
|
|
return 1 - UIState.player.fields.get(FieldStore.Entity.PRICE_REDUCTION)
|
|
|
|
|
else:
|
|
|
|
|
return 1
|
2025-08-28 14:59:36 +08:00
|
|
|
func rebuildInfo():
|
|
|
|
|
avatarRect.texture = avatarTexture
|
|
|
|
|
nameLabel.displayName = displayName
|
|
|
|
|
nameLabel.quality = quality
|
2025-09-05 22:23:41 +08:00
|
|
|
nameLabel.topic = topic
|
2025-08-28 14:59:36 +08:00
|
|
|
for i in fieldsBox.get_children():
|
|
|
|
|
i.queue_free()
|
|
|
|
|
var noField = true
|
|
|
|
|
for i in range(min(fields.size(), fieldValues.size())):
|
|
|
|
|
noField = false
|
|
|
|
|
var field = fields[i]
|
|
|
|
|
var value = fieldValues[i]
|
2025-09-21 13:34:51 +08:00
|
|
|
var fieldShow: FieldShow = ComponentManager.getUIComponent("FieldShow").instantiate()
|
2025-08-28 14:59:36 +08:00
|
|
|
fieldShow.field = field
|
|
|
|
|
fieldShow.value = value
|
2025-09-30 17:51:22 +08:00
|
|
|
fieldShow.showAdvantage = true
|
2025-09-30 17:39:32 +08:00
|
|
|
if is_instance_valid(UIState.player):
|
|
|
|
|
fieldShow.maxed = value + UIState.player.fields[field] > FieldStore.entityMaxValueMap.get(field, INF)
|
2025-08-28 14:59:36 +08:00
|
|
|
fieldsBox.add_child(fieldShow)
|
|
|
|
|
if noField:
|
|
|
|
|
fieldsBox.add_child(QuickUI.smallText("无词条"))
|
2025-09-21 16:49:52 +08:00
|
|
|
for i in weaponsBox.get_children():
|
|
|
|
|
i.queue_free()
|
|
|
|
|
for weapon in weapons:
|
|
|
|
|
var weaponShow: WeaponShow = ComponentManager.getUIComponent("WeaponShow").instantiate()
|
|
|
|
|
weaponShow.weapon = weapon
|
2025-09-30 17:41:13 +08:00
|
|
|
if is_instance_valid(UIState.player):
|
|
|
|
|
weaponShow.operation = WeaponShow.Operation.EXTRACT if UIState.player.weaponBag.has(weapon.instantiate().displayName) else WeaponShow.Operation.GET
|
2025-09-21 16:49:52 +08:00
|
|
|
weaponShow.visible = true
|
|
|
|
|
weaponsBox.add_child(weaponShow)
|
2025-08-28 14:59:36 +08:00
|
|
|
for i in costsBox.get_children():
|
|
|
|
|
i.queue_free()
|
2026-04-12 15:43:13 +08:00
|
|
|
for i in range(min(costs.size(), costCounts.size())):
|
|
|
|
|
var cost = costs[i]
|
|
|
|
|
var count = countOf(i)
|
|
|
|
|
var costShow: ItemShow = ComponentManager.getUIComponent("ItemShow").instantiate()
|
|
|
|
|
costShow.enough = is_instance_valid(UIState.player) and UIState.player.inventory[cost] >= count
|
|
|
|
|
costShow.type = cost
|
|
|
|
|
costShow.count = count
|
|
|
|
|
costShow.visible = !freeToBuy || count < 0
|
|
|
|
|
costsBox.add_child(costShow)
|