@tool extends PanelContainer class_name Weapon @export var avatarTexture: Texture2D = preload("res://icon.svg") @export var displayName: String = "未命名饲料" @export var quality: WeaponName.Quality = WeaponName.Quality.COMMON @export var typeTopic: WeaponName.TypeTopic = WeaponName.TypeTopic.IMPACT @export var costBeachball: int = 0 @export var store: Dictionary = { "atk": 10 } @export var storeType: Array[FieldStore.DataType] = [ FieldStore.DataType.VALUE ] @export var descriptionTemplate: String = "造成$atk点伤害。" @export var needEnergy: float = 0 @export var cooldown: float = 100 @export var debugRebuild: bool = false @export var level: int = 0 @onready var avatarRect: TextureRect = $"%avatar" @onready var nameLabel: WeaponName = $"%name" @onready var energyLabel: Label = $"%energy" @onready var beachballLabel: Label = $"%beachball" @onready var descriptionLabel: RichTextLabel = $"%description" @onready var updateButton: Button = $"%updateBtn" @onready var sounds: Node2D = $"%sounds" var cooldownTimer = CooldownTimer.new() var originalStore: Dictionary = {} func _ready(): originalStore = store updateButton.pressed.connect( func(): apply(UIState.player) ) cooldownTimer.cooldown = cooldown for i in sounds.get_children(): i.process_mode = ProcessMode.PROCESS_MODE_ALWAYS rebuildInfo() debugRebuild = false # 只能在编辑器里打开 func _physics_process(_delta): if debugRebuild: rebuildInfo() func allHad(entity: EntityBase) -> bool: return entity.inventory[ItemStore.ItemType.BEACHBALL] >= costBeachball func apply(entity: EntityBase): var allHave = allHad(entity) if allHave: level += 1 entity.inventory[ItemStore.ItemType.BEACHBALL] -= costBeachball store = update(level, originalStore.duplicate(), entity) costBeachball *= 2 rebuildInfo() return allHave func multipiler() -> float: if is_instance_valid(UIState.player): return 1 - UIState.player.fields.get(FieldStore.Entity.PRICE_REDUCTION) else: return 1 func rebuildInfo(): avatarRect.texture = avatarTexture nameLabel.displayName = displayName nameLabel.quality = quality nameLabel.typeTopic = typeTopic nameLabel.level = level energyLabel.text = "%.1f" % needEnergy beachballLabel.text = str(costBeachball) descriptionLabel.text = buildDescription() func buildDescription() -> String: var result = descriptionTemplate var i = 0 for key in store.keys(): var data = store[key] var type = storeType[i] if type == FieldStore.DataType.VALUE: data = "%.1f" % data elif type == FieldStore.DataType.PERCENT: data = ("%.1f" % (data * 100)) + "%" elif type == FieldStore.DataType.ANGLE: data = "%.1f°" % data result = result.replace("$" + key, "[color=cyan]%s[/color]" % data) i += 1 return "[center]%s[/center]" % result func readStore(key: String, default: Variant = null): return store.get(key, default) func playSound(sound: String): var body = sounds.get_node_or_null(sound) if body is AudioStreamPlayer2D: var cloned = body.duplicate() as AudioStreamPlayer2D add_child(cloned) cloned.play() await cloned.finished cloned.queue_free() func tryAttack(entity: EntityBase): if cooldownTimer.start(): if entity.useEnergy(needEnergy): return attack(entity) # 抽象 func update(_to: int, origin: Dictionary, _entity: EntityBase): return origin func attack(_entity: EntityBase): pass