Add catfish species and update fish artwork
15
fish/pools/fish_catalog.tres
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[gd_resource type="Resource" load_steps=10 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://fish/fish_pool.gd" id="1_pool"]
|
||||
[ext_resource type="Resource" path="res://fish/species/bluegill/bluegill.tres" id="2_bluegill"]
|
||||
[ext_resource type="Resource" path="res://fish/species/bass/bass.tres" id="3_bass"]
|
||||
[ext_resource type="Resource" path="res://fish/species/carp/carp.tres" id="4_carp"]
|
||||
[ext_resource type="Resource" path="res://fish/species/sunfish/sunfish.tres" id="5_sunfish"]
|
||||
[ext_resource type="Resource" path="res://fish/species/catfish_blue/catfish_blue.tres" id="6_catfish_blue"]
|
||||
[ext_resource type="Resource" path="res://fish/species/catfish_channel/catfish_channel.tres" id="7_catfish_channel"]
|
||||
[ext_resource type="Resource" path="res://fish/species/catfish_flathead/catfish_flathead.tres" id="8_catfish_flathead"]
|
||||
[ext_resource type="Resource" path="res://fish/species/catfish_white/catfish_white.tres" id="9_catfish_white"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_pool")
|
||||
candidates = [ExtResource("2_bluegill"), ExtResource("3_bass"), ExtResource("4_carp"), ExtResource("5_sunfish"), ExtResource("6_catfish_blue"), ExtResource("7_catfish_channel"), ExtResource("8_catfish_flathead"), ExtResource("9_catfish_white")]
|
||||
15
fish/pools/starter_pond_pool.tres
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[gd_resource type="Resource" load_steps=10 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://fish/fish_pool.gd" id="1_pool"]
|
||||
[ext_resource type="Resource" path="res://fish/species/bluegill/bluegill.tres" id="2_bluegill"]
|
||||
[ext_resource type="Resource" path="res://fish/species/bass/bass.tres" id="3_bass"]
|
||||
[ext_resource type="Resource" path="res://fish/species/carp/carp.tres" id="4_carp"]
|
||||
[ext_resource type="Resource" path="res://fish/species/sunfish/sunfish.tres" id="5_sunfish"]
|
||||
[ext_resource type="Resource" path="res://fish/species/catfish_blue/catfish_blue.tres" id="6_catfish_blue"]
|
||||
[ext_resource type="Resource" path="res://fish/species/catfish_channel/catfish_channel.tres" id="7_catfish_channel"]
|
||||
[ext_resource type="Resource" path="res://fish/species/catfish_flathead/catfish_flathead.tres" id="8_catfish_flathead"]
|
||||
[ext_resource type="Resource" path="res://fish/species/catfish_white/catfish_white.tres" id="9_catfish_white"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_pool")
|
||||
candidates = [ExtResource("2_bluegill"), ExtResource("3_bass"), ExtResource("4_carp"), ExtResource("5_sunfish"), ExtResource("6_catfish_blue"), ExtResource("7_catfish_channel"), ExtResource("8_catfish_flathead"), ExtResource("9_catfish_white")]
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 46 KiB |
32
fish/species/catfish_blue/catfish_blue.tres
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
[gd_resource type="Resource" load_steps=5 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||
[ext_resource type="Resource" path="res://fishing/bass_catch_profile.tres" id="2_profile"]
|
||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
||||
[ext_resource type="Texture2D" path="res://fish/species/catfish_blue/fish_catfish_blue.png" id="4_texture"]
|
||||
|
||||
[sub_resource type="Resource" id="BlueCatfishAvailability"]
|
||||
script = ExtResource("3_availability_script")
|
||||
allowed_location_tags = Array[StringName]([&"starter_pond"])
|
||||
allow_day = true
|
||||
allow_night = true
|
||||
preferred_bait_tags = Array[StringName]([&"worm", &"minnow"])
|
||||
preferred_bait_weight_multiplier = 1.35
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_fish_data")
|
||||
id = &"catfish_blue"
|
||||
display_name = "blue catfish"
|
||||
rarity = 1
|
||||
base_catch_weight = 1.25
|
||||
catch_profile = ExtResource("2_profile")
|
||||
availability = SubResource("BlueCatfishAvailability")
|
||||
weight_min_lb = 3.0
|
||||
weight_max_lb = 12.0
|
||||
display_scale_min = 0.95
|
||||
display_scale_max = 1.55
|
||||
display_scale_curve = 0.9
|
||||
sell_value_min = 6
|
||||
sell_value_max = 9
|
||||
sell_value_curve = 0.9
|
||||
display_texture = ExtResource("4_texture")
|
||||
BIN
fish/species/catfish_blue/fish_catfish_blue.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
40
fish/species/catfish_blue/fish_catfish_blue.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://7f1dtcou8moe"
|
||||
path="res://.godot/imported/fish_catfish_blue.png-03480cfe99c4fdece0a97273445594bd.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://fish/species/catfish_blue/fish_catfish_blue.png"
|
||||
dest_files=["res://.godot/imported/fish_catfish_blue.png-03480cfe99c4fdece0a97273445594bd.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
|
||||
32
fish/species/catfish_channel/catfish_channel.tres
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
[gd_resource type="Resource" load_steps=5 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
||||
[ext_resource type="Texture2D" path="res://fish/species/catfish_channel/fish_catfish_channel.png" id="4_texture"]
|
||||
|
||||
[sub_resource type="Resource" id="ChannelCatfishAvailability"]
|
||||
script = ExtResource("3_availability_script")
|
||||
allowed_location_tags = Array[StringName]([&"starter_pond"])
|
||||
allow_day = true
|
||||
allow_night = true
|
||||
preferred_bait_tags = Array[StringName]([&"worm"])
|
||||
preferred_bait_weight_multiplier = 1.35
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_fish_data")
|
||||
id = &"catfish_channel"
|
||||
display_name = "channel catfish"
|
||||
rarity = 0
|
||||
base_catch_weight = 2.0
|
||||
catch_profile = ExtResource("2_profile")
|
||||
availability = SubResource("ChannelCatfishAvailability")
|
||||
weight_min_lb = 1.5
|
||||
weight_max_lb = 7.0
|
||||
display_scale_min = 0.85
|
||||
display_scale_max = 1.35
|
||||
display_scale_curve = 1.0
|
||||
sell_value_min = 4
|
||||
sell_value_max = 7
|
||||
sell_value_curve = 1.0
|
||||
display_texture = ExtResource("4_texture")
|
||||
BIN
fish/species/catfish_channel/fish_catfish_channel.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
40
fish/species/catfish_channel/fish_catfish_channel.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dvxpk2ltt3blb"
|
||||
path="res://.godot/imported/fish_catfish_channel.png-5078da9a00f276d273bfcd2b50b98937.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://fish/species/catfish_channel/fish_catfish_channel.png"
|
||||
dest_files=["res://.godot/imported/fish_catfish_channel.png-5078da9a00f276d273bfcd2b50b98937.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
|
||||
32
fish/species/catfish_flathead/catfish_flathead.tres
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
[gd_resource type="Resource" load_steps=5 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||
[ext_resource type="Resource" path="res://fishing/bass_catch_profile.tres" id="2_profile"]
|
||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
||||
[ext_resource type="Texture2D" path="res://fish/species/catfish_flathead/fish_catfish_flathead.png" id="4_texture"]
|
||||
|
||||
[sub_resource type="Resource" id="FlatheadCatfishAvailability"]
|
||||
script = ExtResource("3_availability_script")
|
||||
allowed_location_tags = Array[StringName]([&"starter_pond"])
|
||||
allow_day = true
|
||||
allow_night = true
|
||||
preferred_bait_tags = Array[StringName]([&"worm", &"minnow"])
|
||||
preferred_bait_weight_multiplier = 1.35
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_fish_data")
|
||||
id = &"catfish_flathead"
|
||||
display_name = "flathead catfish"
|
||||
rarity = 1
|
||||
base_catch_weight = 1.0
|
||||
catch_profile = ExtResource("2_profile")
|
||||
availability = SubResource("FlatheadCatfishAvailability")
|
||||
weight_min_lb = 3.0
|
||||
weight_max_lb = 14.0
|
||||
display_scale_min = 1.0
|
||||
display_scale_max = 1.6
|
||||
display_scale_curve = 0.9
|
||||
sell_value_min = 7
|
||||
sell_value_max = 10
|
||||
sell_value_curve = 0.9
|
||||
display_texture = ExtResource("4_texture")
|
||||
BIN
fish/species/catfish_flathead/fish_catfish_flathead.png
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bacx63lp0yh7t"
|
||||
path="res://.godot/imported/fish_catfish_flathead.png-31b800b34c27c75b84a2ee98a13ff954.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://fish/species/catfish_flathead/fish_catfish_flathead.png"
|
||||
dest_files=["res://.godot/imported/fish_catfish_flathead.png-31b800b34c27c75b84a2ee98a13ff954.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
|
||||
32
fish/species/catfish_white/catfish_white.tres
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
[gd_resource type="Resource" load_steps=5 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://fish/fish_data.gd" id="1_fish_data"]
|
||||
[ext_resource type="Resource" path="res://fishing/common_catch_profile.tres" id="2_profile"]
|
||||
[ext_resource type="Script" path="res://fish/fish_availability.gd" id="3_availability_script"]
|
||||
[ext_resource type="Texture2D" path="res://fish/species/catfish_white/fish_catfish_white.png" id="4_texture"]
|
||||
|
||||
[sub_resource type="Resource" id="WhiteCatfishAvailability"]
|
||||
script = ExtResource("3_availability_script")
|
||||
allowed_location_tags = Array[StringName]([&"starter_pond"])
|
||||
allow_day = true
|
||||
allow_night = true
|
||||
preferred_bait_tags = Array[StringName]([&"worm"])
|
||||
preferred_bait_weight_multiplier = 1.35
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_fish_data")
|
||||
id = &"catfish_white"
|
||||
display_name = "white catfish"
|
||||
rarity = 0
|
||||
base_catch_weight = 2.0
|
||||
catch_profile = ExtResource("2_profile")
|
||||
availability = SubResource("WhiteCatfishAvailability")
|
||||
weight_min_lb = 1.0
|
||||
weight_max_lb = 5.0
|
||||
display_scale_min = 0.8
|
||||
display_scale_max = 1.25
|
||||
display_scale_curve = 1.0
|
||||
sell_value_min = 4
|
||||
sell_value_max = 6
|
||||
sell_value_curve = 1.0
|
||||
display_texture = ExtResource("4_texture")
|
||||
BIN
fish/species/catfish_white/fish_catfish_white.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
40
fish/species/catfish_white/fish_catfish_white.png.import
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bf6kiawwekv7g"
|
||||
path="res://.godot/imported/fish_catfish_white.png-13b8ec9cfaabf9930cf00da49c81a3bd.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://fish/species/catfish_white/fish_catfish_white.png"
|
||||
dest_files=["res://.godot/imported/fish_catfish_white.png-13b8ec9cfaabf9930cf00da49c81a3bd.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
|
||||
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 23 KiB |
|
|
@ -5,7 +5,7 @@
|
|||
[ext_resource type="Script" path="res://main/main.gd" id="3_main"]
|
||||
[ext_resource type="PackedScene" path="res://fishing/fishing_spot.tscn" id="4_spot"]
|
||||
[ext_resource type="PackedScene" path="res://ui/game_ui.tscn" id="5_ui"]
|
||||
[ext_resource type="Resource" path="res://fish/pools/test_water_pool.tres" id="6_pool"]
|
||||
[ext_resource type="Resource" path="res://fish/pools/fish_catalog.tres" id="6_pool"]
|
||||
[ext_resource type="Resource" path="res://economy/buyers/pelicans.tres" id="7_pelicans"]
|
||||
[ext_resource type="Script" path="res://world/water_recovery_controller.gd" id="8_recovery"]
|
||||
[ext_resource type="Script" path="res://save/player_save_manager.gd" id="9_save"]
|
||||
|
|
|
|||
153
tests/fish_catalog_content_validation.gd
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
extends SceneTree
|
||||
|
||||
const FishCatchType = preload("res://fish/fish_catch.gd")
|
||||
const CollectionLogType = preload("res://collection/collection_log.gd")
|
||||
const FishDataType = preload("res://fish/fish_data.gd")
|
||||
const FishInventoryType = preload("res://inventory/fish_inventory.gd")
|
||||
const FishPoolType = preload("res://fish/fish_pool.gd")
|
||||
const FishSelectorType = preload("res://fish/fish_selector.gd")
|
||||
const FishingContextType = preload("res://fishing/fishing_context.gd")
|
||||
const NetworkSaleServiceType = preload(
|
||||
"res://network/network_sale_service.gd"
|
||||
)
|
||||
|
||||
const Catalog: FishPoolType = preload("res://fish/pools/fish_catalog.tres")
|
||||
const PondPool: FishPoolType = preload(
|
||||
"res://fish/pools/starter_pond_pool.tres"
|
||||
)
|
||||
const OceanPool: FishPoolType = preload(
|
||||
"res://fish/pools/test_water_pool.tres"
|
||||
)
|
||||
const PelicanBuyer = preload("res://economy/buyers/pelicans.tres")
|
||||
|
||||
const ORIGINAL_IDS: Array[StringName] = [
|
||||
&"bluegill", &"bass", &"carp", &"sunfish",
|
||||
]
|
||||
const CATFISH_IDS: Array[StringName] = [
|
||||
&"catfish_blue",
|
||||
&"catfish_channel",
|
||||
&"catfish_flathead",
|
||||
&"catfish_white",
|
||||
]
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
call_deferred("_run")
|
||||
|
||||
|
||||
func _run() -> void:
|
||||
_validate_catalog_and_pools()
|
||||
_validate_catches_and_authoritative_sale()
|
||||
print("Fish catalog content validation: PASS")
|
||||
quit()
|
||||
|
||||
|
||||
func _validate_catalog_and_pools() -> void:
|
||||
assert(Catalog.candidates.size() == 8)
|
||||
assert(PondPool.candidates.size() == 8)
|
||||
assert(OceanPool.candidates.size() == 4)
|
||||
for fish_id: StringName in ORIGINAL_IDS:
|
||||
var original_fish: FishDataType = Catalog.get_fish_by_id(fish_id)
|
||||
assert(original_fish != null)
|
||||
assert(original_fish.is_selectable())
|
||||
assert(PondPool.get_fish_by_id(fish_id) != null)
|
||||
assert(OceanPool.get_fish_by_id(fish_id) != null)
|
||||
for fish_id: StringName in CATFISH_IDS:
|
||||
var fish: FishDataType = Catalog.get_fish_by_id(fish_id)
|
||||
assert(fish != null)
|
||||
assert(fish.is_selectable())
|
||||
assert(PondPool.get_fish_by_id(fish_id) == fish)
|
||||
assert(OceanPool.get_fish_by_id(fish_id) == null)
|
||||
assert(fish.availability.allowed_location_tags == [&"starter_pond"])
|
||||
assert(LogbookCatalog.category_for(fish) == (
|
||||
LogbookCatalog.Category.FRESH_WATER
|
||||
))
|
||||
|
||||
var expected_values: Dictionary[StringName, Array] = {
|
||||
&"catfish_blue": [1, 1.25, 3.0, 12.0, 6, 9],
|
||||
&"catfish_channel": [0, 2.0, 1.5, 7.0, 4, 7],
|
||||
&"catfish_flathead": [1, 1.0, 3.0, 14.0, 7, 10],
|
||||
&"catfish_white": [0, 2.0, 1.0, 5.0, 4, 6],
|
||||
}
|
||||
for fish_id: StringName in CATFISH_IDS:
|
||||
var fish: FishDataType = Catalog.get_fish_by_id(fish_id)
|
||||
var values: Array = expected_values[fish_id]
|
||||
assert(int(fish.rarity) == int(values[0]))
|
||||
assert(is_equal_approx(fish.base_catch_weight, float(values[1])))
|
||||
assert(is_equal_approx(fish.weight_min_lb, float(values[2])))
|
||||
assert(is_equal_approx(fish.weight_max_lb, float(values[3])))
|
||||
assert(fish.sell_value_min == int(values[4]))
|
||||
assert(fish.sell_value_max == int(values[5]))
|
||||
|
||||
var pond_context := FishingContextType.new()
|
||||
pond_context.location_tags = [&"starter_pond"]
|
||||
var ocean_context := FishingContextType.new()
|
||||
ocean_context.location_tags = [&"coast", &"ocean"]
|
||||
for fish_id: StringName in CATFISH_IDS:
|
||||
var fish: FishDataType = Catalog.get_fish_by_id(fish_id)
|
||||
assert(fish.availability.is_available(pond_context))
|
||||
assert(not fish.availability.is_available(ocean_context))
|
||||
var single_species_pool := FishPoolType.new()
|
||||
single_species_pool.candidates = [fish]
|
||||
var collection := CollectionLogType.new()
|
||||
var selector := FishSelectorType.new()
|
||||
selector.use_deterministic_test_seed = true
|
||||
selector.begin_roll()
|
||||
assert(
|
||||
selector.select_fish(
|
||||
single_species_pool, pond_context, collection
|
||||
) == fish
|
||||
)
|
||||
collection.free()
|
||||
|
||||
|
||||
func _validate_catches_and_authoritative_sale() -> void:
|
||||
var inventory := FishInventoryType.new()
|
||||
root.add_child(inventory)
|
||||
var selector := FishSelectorType.new()
|
||||
selector.use_deterministic_test_seed = true
|
||||
selector.begin_roll()
|
||||
var sale_service := NetworkSaleServiceType.new()
|
||||
var session := NetworkSession.new()
|
||||
root.add_child(session)
|
||||
root.add_child(sale_service)
|
||||
sale_service.set("_session", session)
|
||||
sale_service.set("_fish_catalog", Catalog)
|
||||
sale_service.set("_buyer", PelicanBuyer)
|
||||
|
||||
for index: int in Catalog.candidates.size():
|
||||
var fish: FishDataType = Catalog.candidates[index]
|
||||
var fish_catch: FishCatch = selector.create_catch(fish)
|
||||
assert(fish_catch != null)
|
||||
fish_catch.catch_sequence = index + 1
|
||||
assert(fish_catch.fish.display_texture == fish.display_texture)
|
||||
|
||||
var loaded: FishCatch = FishCatchType.from_save_dict(
|
||||
fish_catch.to_save_dict(), Catalog.get_fish_by_id(fish.id)
|
||||
)
|
||||
assert(loaded != null)
|
||||
assert(loaded.fish_id == fish.id)
|
||||
assert(loaded.fish == fish)
|
||||
|
||||
var replicated: FishCatch = FishCatchType.from_network_dict(
|
||||
fish_catch.to_network_dict(), Catalog.get_fish_by_id(fish.id)
|
||||
)
|
||||
assert(replicated != null)
|
||||
assert(replicated.fish_id == fish.id)
|
||||
assert(replicated.fish.display_texture == fish.display_texture)
|
||||
|
||||
inventory.add_catch(loaded)
|
||||
assert(inventory.contains_catch_id(loaded.catch_id))
|
||||
var sale_result: Dictionary = sale_service.call(
|
||||
"_build_authoritative_result",
|
||||
1,
|
||||
"catalog_sale_%d" % index,
|
||||
[loaded.to_network_dict()],
|
||||
)
|
||||
assert(bool(sale_result.get("accepted", false)))
|
||||
assert(int(sale_result.get("base_value", -1)) == loaded.sale_value)
|
||||
assert((sale_result.get("catch_ids", []) as Array).size() == 1)
|
||||
|
||||
inventory.queue_free()
|
||||
sale_service.queue_free()
|
||||
session.queue_free()
|
||||
1
tests/fish_catalog_content_validation.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dmocxxio0u53e
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
extends SceneTree
|
||||
|
||||
const MainScene = preload("res://main/main.tscn")
|
||||
const FishCatchType = preload("res://fish/fish_catch.gd")
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
|
|
@ -19,6 +20,7 @@ func _run() -> void:
|
|||
for _frame: int in 8:
|
||||
await process_frame
|
||||
assert(bool(main.get("_gameplay_started")))
|
||||
_validate_save_round_trip(main, save_manager)
|
||||
|
||||
var game_ui := main.get_node("%GameUI") as GameUI
|
||||
var player_menu := game_ui.get_node("%PlayerMenu") as PlayerMenu
|
||||
|
|
@ -44,7 +46,7 @@ func _run() -> void:
|
|||
"_select_category", LogbookCatalog.Category.FRESH_WATER
|
||||
)
|
||||
await create_timer(0.25).timeout
|
||||
assert((logbook.get("_entry_buttons") as Dictionary).is_empty())
|
||||
assert((logbook.get("_entry_buttons") as Dictionary).size() == 4)
|
||||
await _capture_if_requested("-fresh")
|
||||
logbook.call("_select_category", LogbookCatalog.Category.SALT_WATER)
|
||||
await create_timer(0.25).timeout
|
||||
|
|
@ -84,6 +86,71 @@ func _run() -> void:
|
|||
quit()
|
||||
|
||||
|
||||
func _validate_save_round_trip(
|
||||
main: Node,
|
||||
save_manager: PlayerSaveManager,
|
||||
) -> void:
|
||||
var player := main.get("_player") as Player
|
||||
var catalog := main.get("fish_catalog") as FishPool
|
||||
assert(catalog != null)
|
||||
assert(catalog.candidates.size() == 8)
|
||||
for index: int in 4:
|
||||
_add_test_catch(player, catalog.candidates[index])
|
||||
assert(save_manager.save_now())
|
||||
var no_catches: Array[FishCatch] = []
|
||||
var no_discoveries: Array[StringName] = []
|
||||
assert(player.inventory.replace_all_catches(no_catches, 1))
|
||||
assert(player.collection_log.replace_discovered_ids(no_discoveries))
|
||||
assert(save_manager.load_player_data())
|
||||
assert(player.inventory.get_all_catches().size() == 4)
|
||||
for index: int in 4:
|
||||
var original_fish: FishData = catalog.candidates[index]
|
||||
assert(player.inventory.get_count(original_fish.id) == 1)
|
||||
assert(player.collection_log.has_discovered(original_fish.id))
|
||||
|
||||
for index: int in range(4, catalog.candidates.size()):
|
||||
_add_test_catch(player, catalog.candidates[index])
|
||||
assert(save_manager.save_now())
|
||||
assert(player.inventory.replace_all_catches(no_catches, 1))
|
||||
assert(player.collection_log.replace_discovered_ids(no_discoveries))
|
||||
assert(save_manager.load_player_data())
|
||||
assert(player.inventory.get_all_catches().size() == 8)
|
||||
for fish: FishData in catalog.candidates:
|
||||
assert(player.inventory.get_count(fish.id) == 1)
|
||||
assert(player.collection_log.has_discovered(fish.id))
|
||||
for fish_id: StringName in [
|
||||
&"catfish_blue",
|
||||
&"catfish_channel",
|
||||
&"catfish_flathead",
|
||||
&"catfish_white",
|
||||
]:
|
||||
var fish_catch: FishCatch = (
|
||||
player.inventory.get_catches_by_fish_id(fish_id).front()
|
||||
)
|
||||
player.begin_catch_showcase(fish_catch)
|
||||
var catch_sprite := player.get_node(
|
||||
"%CatchSprite"
|
||||
) as Sprite3D
|
||||
assert(catch_sprite.texture == fish_catch.fish.display_texture)
|
||||
player.end_catch_showcase(Callable(), true)
|
||||
|
||||
|
||||
func _add_test_catch(player: Player, fish: FishData) -> void:
|
||||
var fish_catch := FishCatchType.new()
|
||||
fish_catch.fish = fish
|
||||
fish_catch.fish_id = fish.id
|
||||
fish_catch.weight_lb = fish.get_minimum_weight()
|
||||
fish_catch.display_scale = fish.get_display_scale_for_weight(
|
||||
fish_catch.weight_lb
|
||||
)
|
||||
fish_catch.sale_value = fish.get_sale_value_for_weight(
|
||||
fish_catch.weight_lb
|
||||
)
|
||||
fish_catch.ensure_identity()
|
||||
player.inventory.add_catch(fish_catch)
|
||||
player.collection_log.mark_discovered(fish.id)
|
||||
|
||||
|
||||
func _capture_if_requested(suffix: String) -> void:
|
||||
if not OS.has_environment("NETFISHING_LOGBOOK_CAPTURE"):
|
||||
return
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ const FishPoolType = preload("res://fish/fish_pool.gd")
|
|||
const CollectionLogType = preload("res://collection/collection_log.gd")
|
||||
const LogbookPageScene = preload("res://ui/logbook_page.tscn")
|
||||
const CatalogResource: FishPoolType = preload(
|
||||
"res://fish/pools/test_water_pool.tres"
|
||||
"res://fish/pools/fish_catalog.tres"
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -34,21 +34,29 @@ func _run() -> void:
|
|||
|
||||
func _validate_catalog() -> void:
|
||||
var expected_ids: Array[StringName] = [
|
||||
&"bluegill", &"bass", &"carp", &"sunfish",
|
||||
&"bluegill",
|
||||
&"bass",
|
||||
&"carp",
|
||||
&"sunfish",
|
||||
&"catfish_blue",
|
||||
&"catfish_channel",
|
||||
&"catfish_flathead",
|
||||
&"catfish_white",
|
||||
]
|
||||
assert(LogbookCatalog.CATALOG_ORDER == expected_ids)
|
||||
for index: int in expected_ids.size():
|
||||
var fish := CatalogResource.get_fish_by_id(expected_ids[index])
|
||||
assert(fish != null)
|
||||
var expected_category: LogbookCatalog.Category = (
|
||||
LogbookCatalog.Category.OTHER
|
||||
if index < 4
|
||||
else LogbookCatalog.Category.FRESH_WATER
|
||||
)
|
||||
assert(
|
||||
LogbookCatalog.category_for(fish)
|
||||
== LogbookCatalog.Category.OTHER
|
||||
== expected_category
|
||||
)
|
||||
assert(LogbookCatalog.catalog_number(fish.id) == index + 1)
|
||||
assert(
|
||||
LogbookCatalog.empty_state(LogbookCatalog.Category.FRESH_WATER)
|
||||
== "No freshwater catches cataloged yet."
|
||||
)
|
||||
assert(
|
||||
LogbookCatalog.empty_state(LogbookCatalog.Category.SALT_WATER)
|
||||
== "No saltwater catches cataloged yet."
|
||||
|
|
@ -83,11 +91,14 @@ func _validate_page() -> void:
|
|||
"_select_category", LogbookCatalog.Category.FRESH_WATER
|
||||
)
|
||||
await create_timer(0.25).timeout
|
||||
assert((page.get("_entry_buttons") as Dictionary).is_empty())
|
||||
assert(
|
||||
(page.get("_empty_state") as Label).text
|
||||
== "No freshwater catches cataloged yet."
|
||||
)
|
||||
assert((page.get("_entry_buttons") as Dictionary).size() == 4)
|
||||
for entry_value: Variant in (
|
||||
page.get("_entry_buttons") as Dictionary
|
||||
).values():
|
||||
var unknown_catfish := entry_value as Button
|
||||
assert(unknown_catfish != null)
|
||||
assert(unknown_catfish.text.contains("???"))
|
||||
assert(unknown_catfish.icon == null)
|
||||
page.call("_select_category", LogbookCatalog.Category.SALT_WATER)
|
||||
await create_timer(0.25).timeout
|
||||
assert((page.get("_entry_buttons") as Dictionary).is_empty())
|
||||
|
|
|
|||
|
|
@ -16,10 +16,19 @@ const CATALOG_ORDER: Array[StringName] = [
|
|||
&"bass",
|
||||
&"carp",
|
||||
&"sunfish",
|
||||
&"catfish_blue",
|
||||
&"catfish_channel",
|
||||
&"catfish_flathead",
|
||||
&"catfish_white",
|
||||
]
|
||||
|
||||
# These maps remain explicit until fish resources gain authored habitat fields.
|
||||
const FRESH_WATER_IDS: Array[StringName] = []
|
||||
const FRESH_WATER_IDS: Array[StringName] = [
|
||||
&"catfish_blue",
|
||||
&"catfish_channel",
|
||||
&"catfish_flathead",
|
||||
&"catfish_white",
|
||||
]
|
||||
const SALT_WATER_IDS: Array[StringName] = []
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
[ext_resource type="PackedScene" uid="uid://bk38p45urtjis" path="res://art/exported/environment/terrain/starter_island.glb" id="2_island"]
|
||||
[ext_resource type="Script" uid="uid://b6fp2obu0y2d0" path="res://world/fishable_water_region.gd" id="3_water"]
|
||||
[ext_resource type="Resource" path="res://fish/pools/test_water_pool.tres" id="4_pool"]
|
||||
[ext_resource type="Resource" path="res://fish/pools/starter_pond_pool.tres" id="12_pond_pool"]
|
||||
[ext_resource type="Script" uid="uid://dnlbnlimgxoc2" path="res://world/player_water_trigger.gd" id="5_trigger"]
|
||||
[ext_resource type="Script" uid="uid://df2lsduguegxh" path="res://world/safe_respawn_point.gd" id="6_safe"]
|
||||
[ext_resource type="PackedScene" path="res://world/interactables/fishing_shop_world.tscn" id="7_shop"]
|
||||
|
|
@ -103,7 +104,7 @@ collision_mask = 0
|
|||
monitoring = false
|
||||
script = ExtResource("3_water")
|
||||
location_tags = Array[StringName]([&"starter_pond"])
|
||||
fish_pool = ExtResource("4_pool")
|
||||
fish_pool = ExtResource("12_pond_pool")
|
||||
selection_priority = 1
|
||||
surface_height_mode = 1
|
||||
|
||||
|
|
|
|||