Expand fish and equipment catalogs
This commit is contained in:
parent
63e50e285d
commit
f55663c105
380 changed files with 9430 additions and 575 deletions
151
items/fishing_rod_data.gd
Normal file
151
items/fishing_rod_data.gd
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
class_name FishingRodData
|
||||
extends ItemData
|
||||
|
||||
const FishDataType = preload("res://fish/fish_data.gd")
|
||||
const FishingContextType = preload("res://fishing/fishing_context.gd")
|
||||
|
||||
enum TimeAffinity {
|
||||
ANY,
|
||||
DAY,
|
||||
NIGHT,
|
||||
}
|
||||
|
||||
enum WeatherAffinity {
|
||||
ANY,
|
||||
RAIN,
|
||||
FOG,
|
||||
}
|
||||
|
||||
const MULTIPLIER_COUNT: int = 5
|
||||
|
||||
@export_category("Rod Shop")
|
||||
@export var shop_enabled: bool = true
|
||||
@export_range(1, 999, 1) var shop_order: int = 1
|
||||
@export_range(0, 1000000, 1) var shop_price: int = 0
|
||||
@export_range(1, 100000, 1) var unlock_level: int = 1
|
||||
|
||||
@export_category("Rod Presentation")
|
||||
## Optional authored visual. A null scene deliberately uses the current
|
||||
## temporary rod mesh so new rod data never requires a model to function.
|
||||
@export var rod_model_scene: PackedScene
|
||||
@export var rod_model_transform: Transform3D = Transform3D.IDENTITY
|
||||
@export var rod_tip_position := Vector3(0.0, 1.1, 0.0)
|
||||
|
||||
@export_category("Rod Affinity")
|
||||
@export var preferred_location_tags: Array[StringName] = []
|
||||
@export var preferred_collection_groups: Array[StringName] = []
|
||||
@export var time_affinity: TimeAffinity = TimeAffinity.ANY
|
||||
@export var weather_affinity: WeatherAffinity = WeatherAffinity.ANY
|
||||
@export_range(0.0, 10.0, 0.01) var affinity_weight_multiplier: float = 1.0
|
||||
@export_range(0.0, 10.0, 0.01) var undiscovered_weight_multiplier: float = 1.0
|
||||
|
||||
@export_category("Rod Catch Modifiers")
|
||||
@export_range(-0.5, 0.5, 0.01) var weight_roll_bias: float = 0.0
|
||||
@export_range(0.05, 5.0, 0.01) var bite_time_multiplier: float = 1.0
|
||||
@export_range(0.05, 5.0, 0.01) var reel_speed_multiplier: float = 1.0
|
||||
@export_range(0.05, 5.0, 0.01) var barrier_power_multiplier: float = 1.0
|
||||
@export var rarity_weight_multipliers: Array[float] = [
|
||||
1.0, 1.0, 1.0, 1.0, 1.0,
|
||||
]
|
||||
@export var quality_weight_multipliers: Array[float] = [
|
||||
1.0, 1.0, 1.0, 1.0, 1.0,
|
||||
]
|
||||
@export_multiline var effect_summary: String
|
||||
@export_multiline var tradeoff: String
|
||||
|
||||
|
||||
func is_valid() -> bool:
|
||||
return (
|
||||
super.is_valid()
|
||||
and category == Category.ROD
|
||||
and shop_order >= 1
|
||||
and shop_price >= 0
|
||||
and unlock_level >= 1
|
||||
and rarity_weight_multipliers.size() == MULTIPLIER_COUNT
|
||||
and quality_weight_multipliers.size() == MULTIPLIER_COUNT
|
||||
and _multipliers_are_non_negative(rarity_weight_multipliers)
|
||||
and _multipliers_are_non_negative(quality_weight_multipliers)
|
||||
and affinity_weight_multiplier >= 0.0
|
||||
and undiscovered_weight_multiplier >= 0.0
|
||||
and bite_time_multiplier > 0.0
|
||||
and reel_speed_multiplier > 0.0
|
||||
and barrier_power_multiplier > 0.0
|
||||
)
|
||||
|
||||
|
||||
func is_shop_available() -> bool:
|
||||
return is_available() and shop_enabled and icon != null
|
||||
|
||||
|
||||
func get_affinity_multiplier(
|
||||
fish: FishDataType,
|
||||
context: FishingContextType,
|
||||
) -> float:
|
||||
if fish == null or context == null or not _has_authored_affinity():
|
||||
return 1.0
|
||||
if (
|
||||
not preferred_location_tags.is_empty()
|
||||
and not _has_any_match(
|
||||
preferred_location_tags,
|
||||
context.location_tags,
|
||||
)
|
||||
):
|
||||
return 1.0
|
||||
if (
|
||||
not preferred_collection_groups.is_empty()
|
||||
and fish.collection_group not in preferred_collection_groups
|
||||
):
|
||||
return 1.0
|
||||
match time_affinity:
|
||||
TimeAffinity.DAY:
|
||||
if context.is_night or context.is_day_night_transition:
|
||||
return 1.0
|
||||
TimeAffinity.NIGHT:
|
||||
if not context.is_night or context.is_day_night_transition:
|
||||
return 1.0
|
||||
match weather_affinity:
|
||||
WeatherAffinity.RAIN:
|
||||
if not context.is_raining:
|
||||
return 1.0
|
||||
WeatherAffinity.FOG:
|
||||
if not context.is_foggy:
|
||||
return 1.0
|
||||
return maxf(affinity_weight_multiplier, 0.0)
|
||||
|
||||
|
||||
func get_rarity_multiplier(rarity: int) -> float:
|
||||
if rarity < 0 or rarity >= rarity_weight_multipliers.size():
|
||||
return 1.0
|
||||
return maxf(rarity_weight_multipliers[rarity], 0.0)
|
||||
|
||||
|
||||
func get_quality_multiplier(quality: int) -> float:
|
||||
if quality < 0 or quality >= quality_weight_multipliers.size():
|
||||
return 1.0
|
||||
return maxf(quality_weight_multipliers[quality], 0.0)
|
||||
|
||||
|
||||
func _has_authored_affinity() -> bool:
|
||||
return (
|
||||
not preferred_location_tags.is_empty()
|
||||
or not preferred_collection_groups.is_empty()
|
||||
or time_affinity != TimeAffinity.ANY
|
||||
or weather_affinity != WeatherAffinity.ANY
|
||||
)
|
||||
|
||||
|
||||
func _has_any_match(
|
||||
expected: Array[StringName],
|
||||
actual: Array[StringName],
|
||||
) -> bool:
|
||||
for value: StringName in expected:
|
||||
if value in actual:
|
||||
return true
|
||||
return false
|
||||
|
||||
|
||||
func _multipliers_are_non_negative(values: Array[float]) -> bool:
|
||||
for value: float in values:
|
||||
if not is_finite(value) or value < 0.0:
|
||||
return false
|
||||
return true
|
||||
Loading…
Add table
Add a link
Reference in a new issue