extends Resource class_name ItemAffixDefinition @export var affix_id: String = "" @export var display_name: String = "" @export_multiline var description: String = "" @export var stat_key: String = "" @export_enum("%", "pkt", "/s", "px/s", "s") var unit: String = "%" @export var enabled: bool = true @export_range(0.0, 1000.0, 0.1) var selection_weight: float = 1.0 @export_group("Dozwolone przedmioty") @export_flags("Weapon", "Shield", "Hull", "Reactor", "Engine", "Active extension", "Computer") var category_mask: int = 95 # Empty means every item in the allowed categories. @export var allowed_item_ids: PackedStringArray = PackedStringArray() @export var excluded_item_ids: PackedStringArray = PackedStringArray() @export_group("Zakres i skalowanie") @export_range(1, 1000) var minimum_level: int = 1 @export_range(1, 1000) var maximum_level: int = 1000 @export var minimum_value_level_1: float = 1.0 @export var maximum_value_level_1: float = 3.0 # Caps apply to percentages and cooldown reductions; flat stats keep growing. @export var minimum_value_cap: float = 25.0 @export var maximum_value_cap: float = 50.0 @export_group("Zasady łączenia") # At most one affix from a nonempty group can appear on the same item. @export var exclusive_group: String = "" @export var incompatible_affix_ids: PackedStringArray = PackedStringArray() func can_roll(item: ItemDefinition, level: int) -> bool: return ( enabled and selection_weight > 0.0 and not affix_id.is_empty() and not stat_key.is_empty() and item != null and item.category != ItemDefinition.Category.ACTIVE_EXTENSION and level >= minimum_level and level <= maximum_level and (category_mask & (1 << item.category)) != 0 and (allowed_item_ids.is_empty() or item.item_id in allowed_item_ids) and item.item_id not in excluded_item_ids ) func can_combine(other: ItemAffixDefinition) -> bool: return ( affix_id != other.affix_id and (exclusive_group.is_empty() or exclusive_group != other.exclusive_group) and other.affix_id not in incompatible_affix_ids and affix_id not in other.incompatible_affix_ids ) func roll_value(level: int) -> float: var bounds := get_value_range(level) return randf_range(bounds.x, bounds.y) func get_value_range(level: int) -> Vector2: var scale_factor := preload("res://scripts/levels/level_balance.gd").item_stat_scale(clampi(level, 1, 1000)) var lower := minimum_value_level_1 * scale_factor var upper := maximum_value_level_1 * scale_factor if unit == "%" or stat_key == "missile_cooldown_reduction": lower = minf(lower, minimum_value_cap) upper = minf(upper, maximum_value_cap) return Vector2(minf(lower, upper), maxf(lower, upper))