mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 06:45:33 +00:00
Implemented vending machine
This commit is contained in:
parent
d78daf4e18
commit
e5ffb0cf94
32 changed files with 3074 additions and 1992 deletions
File diff suppressed because one or more lines are too long
|
|
@ -2316,6 +2316,7 @@
|
|||
{
|
||||
"classname" "actor_elevator_1"
|
||||
"origin" "-176 544 15"
|
||||
"targetname" "elevator_card"
|
||||
}
|
||||
// entity 73
|
||||
{
|
||||
|
|
@ -3662,6 +3663,13 @@
|
|||
}
|
||||
// entity 271
|
||||
{
|
||||
"classname" "actor_controlpad"
|
||||
"origin" "-192 572 36"
|
||||
"target" "elevator_card"
|
||||
"activationtype" "Toggle"
|
||||
}
|
||||
// entity 272
|
||||
{
|
||||
"classname" "func_group"
|
||||
"_tb_type" "_tb_layer"
|
||||
"_tb_name" "Shrouds"
|
||||
|
|
@ -3669,7 +3677,7 @@
|
|||
"_tb_layer_sort_index" "0"
|
||||
"_tb_layer_hidden" "1"
|
||||
}
|
||||
// entity 272
|
||||
// entity 273
|
||||
{
|
||||
"classname" "func_shroud"
|
||||
"targetname" "secret_001"
|
||||
|
|
@ -3685,7 +3693,7 @@
|
|||
( 128 800 48 ) ( 128 800 49 ) ( 128 801 48 ) Manual/Black [ 0 1 0 0 ] [ 0 0 -1 -4 ] 180 1 1
|
||||
}
|
||||
}
|
||||
// entity 273
|
||||
// entity 274
|
||||
{
|
||||
"classname" "func_shroud"
|
||||
"targetname" "wall_trap_1"
|
||||
|
|
@ -3701,7 +3709,7 @@
|
|||
( -72 248 52 ) ( -72 248 53 ) ( -72 249 52 ) Manual/Black [ 0 1 0 0 ] [ 0 0 -1 0 ] 90 1 1
|
||||
}
|
||||
}
|
||||
// entity 274
|
||||
// entity 275
|
||||
{
|
||||
"classname" "func_shroud"
|
||||
"targetname" "wall_trap_1"
|
||||
|
|
@ -3717,7 +3725,7 @@
|
|||
( -72 352 52 ) ( -72 352 53 ) ( -72 353 52 ) Manual/Black [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 1 1
|
||||
}
|
||||
}
|
||||
// entity 275
|
||||
// entity 276
|
||||
{
|
||||
"classname" "func_group"
|
||||
"_tb_type" "_tb_layer"
|
||||
|
|
@ -3725,7 +3733,7 @@
|
|||
"_tb_id" "15"
|
||||
"_tb_layer_sort_index" "1"
|
||||
}
|
||||
// entity 276
|
||||
// entity 277
|
||||
{
|
||||
"classname" "func_group"
|
||||
"_tb_type" "_tb_group"
|
||||
|
|
@ -3735,7 +3743,7 @@
|
|||
"_tb_transformation" "1 0 0 -508 0 1 0 576 0 0 1 32 0 0 0 1"
|
||||
"_tb_layer" "15"
|
||||
}
|
||||
// entity 277
|
||||
// entity 278
|
||||
{
|
||||
"classname" "func_group"
|
||||
"_tb_type" "_tb_group"
|
||||
|
|
@ -3822,7 +3830,7 @@
|
|||
( -160 528 16 ) ( -160 528 17 ) ( -160 529 16 ) Manual/Chevron_2 [ 0 1 0 0 ] [ 0 0 -1 -8 ] 0 1 1
|
||||
}
|
||||
}
|
||||
// entity 278
|
||||
// entity 279
|
||||
{
|
||||
"classname" "func_group"
|
||||
"_tb_type" "_tb_group"
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@
|
|||
( -96 -192 -16 ) ( -96 -192 -15 ) ( -95 -192 -16 ) special/clip [ 1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1
|
||||
( -96 -224 8 ) ( -95 -224 8 ) ( -96 -223 8 ) special/clip [ -1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1
|
||||
( 32 -96 16 ) ( 32 -95 16 ) ( 33 -96 16 ) Floors/Floor_Tiled_0088 [ 1 0 0 0 ] [ 0 -1 0 0 ] 90 1 1
|
||||
( 32 -96 16 ) ( 33 -96 16 ) ( 32 -96 17 ) special/clip [ -1 0 0 0 ] [ 0 0 -1 0 ] 270 1 1
|
||||
( 32 -96 16 ) ( 33 -96 16 ) ( 32 -96 17 ) Manual/Black [ -1 0 0 0 ] [ 0 0 -1 0 ] 270 1 1
|
||||
( 32 -96 16 ) ( 32 -96 17 ) ( 32 -95 16 ) special/clip [ 0 1 0 0 ] [ 0 0 -1 0 ] 270 1 1
|
||||
}
|
||||
// brush 16
|
||||
|
|
@ -183,7 +183,7 @@
|
|||
( -192 -128 -16 ) ( -191 -128 -16 ) ( -192 -127 -16 ) special/clip [ -1 0 0 0 ] [ 0 -1 0 0 ] 90 1 1
|
||||
( -64 0 16 ) ( -64 1 16 ) ( -63 0 16 ) Floors/Floor_Tiled_0088 [ 1 0 0 0 ] [ 0 -1 0 0 ] 270 1 1
|
||||
( -64 32 16 ) ( -63 32 16 ) ( -64 32 17 ) special/clip [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1
|
||||
( -64 0 16 ) ( -64 0 17 ) ( -64 1 16 ) special/clip [ 0 1 0 0 ] [ 0 0 -1 0 ] 90 1 1
|
||||
( -64 0 16 ) ( -64 0 17 ) ( -64 1 16 ) Manual/Black [ 0 1 0 0 ] [ 0 0 -1 0 ] 90 1 1
|
||||
}
|
||||
// brush 20
|
||||
{
|
||||
|
|
@ -273,7 +273,7 @@
|
|||
( -120 -160 16 ) ( -119 -160 16 ) ( -120 -159 16 ) special/clip [ -1 0 0 -24 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( -88 -128 48 ) ( -88 -127 48 ) ( -87 -128 48 ) Manual/Black [ 1 0 0 0 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( -88 -96 48 ) ( -87 -96 48 ) ( -88 -96 49 ) Walls/wall_concrete_003 [ -1 0 0 -8 ] [ 0 0 -1 -16 ] 90 1 1
|
||||
( -88 -128 48 ) ( -88 -128 49 ) ( -88 -127 48 ) Walls/wall_concrete_003 [ 0 1 0 0 ] [ 0 0 -1 -16 ] 180 1 1
|
||||
( -88 -128 48 ) ( -88 -128 49 ) ( -88 -127 48 ) Manual/Black [ 0 1 0 0 ] [ 0 0 -1 -16 ] 180 1 1
|
||||
}
|
||||
// brush 30
|
||||
{
|
||||
|
|
@ -1008,10 +1008,10 @@
|
|||
{
|
||||
( -224 -256 16 ) ( -224 -255 16 ) ( -224 -256 17 ) special/clip [ 0 -1 0 0 ] [ 0 0 -1 0 ] 180 1 1
|
||||
( -224 -256 16 ) ( -224 -256 17 ) ( -223 -256 16 ) special/clip [ 1 0 0 0 ] [ 0 0 -1 0 ] 180 1 1
|
||||
( -224 -256 16 ) ( -223 -256 16 ) ( -224 -255 16 ) special/clip [ -1 0 0 0 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( -224 -256 -16 ) ( -223 -256 -16 ) ( -224 -255 -16 ) special/clip [ -1 0 0 0 ] [ 0 -1 0 0 ] 90 1 1
|
||||
( -192 -224 48 ) ( -192 -223 48 ) ( -191 -224 48 ) Manual/Black [ 1 0 0 0 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( -192 -128 48 ) ( -191 -128 48 ) ( -192 -128 49 ) Manual/Black [ -1 0 0 0 ] [ 0 0 -1 0 ] 180 1 1
|
||||
( -192 -224 48 ) ( -192 -224 49 ) ( -192 -223 48 ) Walls/wall_concrete_003 [ 0 1 0 0 ] [ 0 0 -1 -16 ] 180 1 1
|
||||
( -192 -224 48 ) ( -192 -224 49 ) ( -192 -223 48 ) Manual/Black [ 0 1 0 0 ] [ 0 0 -1 -16 ] 180 1 1
|
||||
}
|
||||
// brush 112
|
||||
{
|
||||
|
|
@ -1020,7 +1020,7 @@
|
|||
( -96 -320 -16 ) ( -95 -320 -16 ) ( -96 -319 -16 ) special/clip [ -1 0 0 0 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( -64 -288 48 ) ( -64 -287 48 ) ( -63 -288 48 ) Manual/Black [ 1 0 0 0 ] [ 0 -1 0 0 ] 270 1 1
|
||||
( -64 -256 48 ) ( -63 -256 48 ) ( -64 -256 49 ) Walls/Wall0 [ -1 0 0 0 ] [ 0 0 -1 -16 ] 0 1 1
|
||||
( -192 -288 48 ) ( -192 -288 49 ) ( -192 -287 48 ) Walls/wall_concrete_003 [ 0 1 0 0 ] [ 0 0 -1 -16 ] 90 1 1
|
||||
( -192 -288 48 ) ( -192 -288 49 ) ( -192 -287 48 ) Manual/Black [ 0 1 0 0 ] [ 0 0 -1 -16 ] 90 1 1
|
||||
}
|
||||
// brush 113
|
||||
{
|
||||
|
|
@ -1056,7 +1056,7 @@
|
|||
( 8 -72 16 ) ( 9 -72 16 ) ( 8 -71 16 ) special/clip [ -1 0 0 8 ] [ 0 -1 0 -8 ] 270 1 1
|
||||
( 40 -40 48 ) ( 40 -39 48 ) ( 41 -40 48 ) Manual/Black [ 1 0 0 0 ] [ 0 -1 0 0 ] 270 1 1
|
||||
( 40 -96 48 ) ( 41 -96 48 ) ( 40 -96 49 ) Manual/Black [ -1 0 0 0 ] [ 0 0 -1 0 ] 0 1 1
|
||||
( 40 -40 48 ) ( 40 -40 49 ) ( 40 -39 48 ) Walls/wall_concrete_003 [ 0 1 0 8 ] [ 0 0 -1 -16 ] 270 1 1
|
||||
( 40 -40 48 ) ( 40 -40 49 ) ( 40 -39 48 ) Manual/Black [ 0 1 0 8 ] [ 0 0 -1 -16 ] 270 1 1
|
||||
}
|
||||
// brush 117
|
||||
{
|
||||
|
|
@ -1193,6 +1193,33 @@
|
|||
( 240 232 56 ) ( 241 232 56 ) ( 240 232 57 ) Manual/Black [ -1 0 0 0 ] [ 0 0 -1 0 ] 270 1 1
|
||||
( 72 232 56 ) ( 72 232 57 ) ( 72 233 56 ) Manual/Black [ 0 1 0 24 ] [ 0 0 -1 0 ] 90 1 1
|
||||
}
|
||||
// brush 132
|
||||
{
|
||||
( -96 -104 48 ) ( -96 -103 48 ) ( -96 -104 49 ) special/clip [ 0 -1 0 0 ] [ 0 0 -1 0 ] 180 1 1
|
||||
( -24 -104 48 ) ( -24 -104 49 ) ( -23 -104 48 ) special/clip [ 1 0 0 24 ] [ 0 0 -1 0 ] 270 1 1
|
||||
( -24 -104 48 ) ( -23 -104 48 ) ( -24 -103 48 ) special/clip [ -1 0 0 -24 ] [ 0 -1 0 0 ] 270 1 1
|
||||
( 200 -96 52 ) ( 200 -95 52 ) ( 201 -96 52 ) Manual/Black [ 1 0 0 0 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( 200 -96 56 ) ( 201 -96 56 ) ( 200 -96 57 ) Walls/WallTop_002 [ -1 0 0 0 ] [ 0 0 -1 0 ] 270 1 1
|
||||
( -72 -96 56 ) ( -72 -96 57 ) ( -72 -95 56 ) special/clip [ 0 1 0 0 ] [ 0 0 -1 0 ] 270 1 1
|
||||
}
|
||||
// brush 133
|
||||
{
|
||||
( -72 -104 48 ) ( -72 -103 48 ) ( -72 -104 49 ) special/clip [ 0 -1 0 0 ] [ 0 0 -1 0 ] 90 1 1
|
||||
( 8 -104 48 ) ( 8 -104 49 ) ( 9 -104 48 ) special/clip [ 1 0 0 -8 ] [ 0 0 -1 0 ] 270 1 1
|
||||
( 8 -104 48 ) ( 9 -104 48 ) ( 8 -103 48 ) special/clip [ -1 0 0 8 ] [ 0 -1 0 0 ] 270 1 1
|
||||
( 232 -96 52 ) ( 232 -95 52 ) ( 233 -96 52 ) Manual/Black [ 1 0 0 0 ] [ 0 -1 0 0 ] 180 1 1
|
||||
( 232 -96 56 ) ( 233 -96 56 ) ( 232 -96 57 ) Manual/Black [ -1 0 0 0 ] [ 0 0 -1 0 ] 270 1 1
|
||||
( -40 -96 56 ) ( -40 -96 57 ) ( -40 -95 56 ) special/clip [ 0 1 0 0 ] [ 0 0 -1 0 ] 270 1 1
|
||||
}
|
||||
// brush 134
|
||||
{
|
||||
( -72 -64 48 ) ( -72 -64 49 ) ( -72 -65 48 ) special/clip [ -1.0718754395722282e-15 -1 0 0 ] [ 0 0 -1 0 ] 0 1 1
|
||||
( -64 -96 56 ) ( -64 -96 57 ) ( -63 -96 56 ) special/clip [ 1 -1.0718754395722282e-15 0 0 ] [ 0 0 -1 0 ] 270 1 1
|
||||
( -72 -64 48 ) ( -72 -65 48 ) ( -71 -64 48 ) special/clip [ 1.0718754395722282e-15 1 0 0 ] [ -1 1.0718754395722282e-15 0 0 ] 270 1 1
|
||||
( -64 -288 52 ) ( -63 -288 52 ) ( -64 -289 52 ) Manual/Black [ -1.0718754395722282e-15 -1 0 0 ] [ -1 1.0718754395722282e-15 0 0 ] 0 1 1
|
||||
( -72 -40 48 ) ( -71 -40 48 ) ( -72 -40 49 ) Walls/WallTop_002 [ -1 1.0718754395722282e-15 0 0 ] [ 0 0 -1 0 ] 270 1 1
|
||||
( -64 -288 56 ) ( -64 -289 56 ) ( -64 -288 57 ) Manual/Black [ 1.0718754395722282e-15 1 0 0 ] [ 0 0 -1 0 ] 0 1 1
|
||||
}
|
||||
}
|
||||
// entity 1
|
||||
{
|
||||
|
|
@ -1617,7 +1644,7 @@
|
|||
// entity 71
|
||||
{
|
||||
"classname" "marker_spawn_item"
|
||||
"origin" "-36 -116 22"
|
||||
"origin" "-124 -28 22"
|
||||
"resource_path" "res://Resources/Items/DARK_MACHINE_GUN_Item.tres"
|
||||
}
|
||||
// entity 72
|
||||
|
|
@ -1661,3 +1688,51 @@
|
|||
"classname" "actor_box_red"
|
||||
"origin" "40 88 20"
|
||||
}
|
||||
// entity 80
|
||||
{
|
||||
"classname" "actor_vendingmachine"
|
||||
"origin" "-56 -152 28"
|
||||
}
|
||||
// entity 81
|
||||
{
|
||||
"classname" "actor_terminal"
|
||||
"origin" "-4 -188 28"
|
||||
"angles" "0 90 0"
|
||||
"custom_dialogue" "asdf"
|
||||
}
|
||||
// entity 82
|
||||
{
|
||||
"classname" "marker_spawn_item"
|
||||
"origin" "-20 -100 22"
|
||||
"resource_path" "res://Resources/Items/Money_Pickup.tres"
|
||||
}
|
||||
// entity 83
|
||||
{
|
||||
"classname" "marker_spawn_item"
|
||||
"origin" "-20 -132 22"
|
||||
"resource_path" "res://Resources/Items/Money_Pickup.tres"
|
||||
}
|
||||
// entity 84
|
||||
{
|
||||
"classname" "marker_spawn_item"
|
||||
"origin" "-4 -124 22"
|
||||
"resource_path" "res://Resources/Items/Money_Pickup.tres"
|
||||
}
|
||||
// entity 85
|
||||
{
|
||||
"classname" "marker_spawn_item"
|
||||
"origin" "-20 -116 22"
|
||||
"resource_path" "res://Resources/Items/Money_Pickup.tres"
|
||||
}
|
||||
// entity 86
|
||||
{
|
||||
"classname" "marker_spawn_item"
|
||||
"origin" "12 -132 22"
|
||||
"resource_path" "res://Resources/Items/Money_Pickup.tres"
|
||||
}
|
||||
// entity 87
|
||||
{
|
||||
"classname" "marker_spawn_item"
|
||||
"origin" "-4 -140 22"
|
||||
"resource_path" "res://Resources/Items/Money_Pickup.tres"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,24 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://bb2pjblwkb7ub"]
|
||||
[gd_scene format=3 uid="uid://bb2pjblwkb7ub"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://cphr15gnmriw3" path="res://3D/BlockbenchModels/VendingMachine/VendingMachine.gltf" id="1_wtma2"]
|
||||
[ext_resource type="Script" uid="uid://kt08ji546nms" path="res://Scripts/Actors/3D/VendingMachine3D.cs" id="2_script"]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_hsg1w"]
|
||||
size = Vector3(1.0528, 2.01202, 0.990539)
|
||||
|
||||
[node name="VendingMachine" type="StaticBody3D"]
|
||||
[node name="VendingMachine" type="Area3D" unique_id=920711293 groups=["Interactable"]]
|
||||
collision_layer = 32
|
||||
collision_mask = 0
|
||||
script = ExtResource("2_script")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=855169760]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0167541, 0.24654551, 0.00338751)
|
||||
shape = SubResource("BoxShape3D_hsg1w")
|
||||
|
||||
[node name="blockbench_export" parent="." instance=ExtResource("1_wtma2")]
|
||||
[node name="Body" type="StaticBody3D" parent="." unique_id=1920958687]
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Body" unique_id=1000054276]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0167541, 0.24654551, 0.00338751)
|
||||
shape = SubResource("BoxShape3D_hsg1w")
|
||||
|
||||
[node name="blockbench_export" parent="." unique_id=1405020962 instance=ExtResource("1_wtma2")]
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
[gd_resource type="Resource" script_class="FuncGodotFGDModelPointClass" load_steps=5 format=3 uid="uid://bmfarpfcbbfa5"]
|
||||
[gd_resource type="Resource" script_class="FuncGodotFGDModelPointClass" format=3 uid="uid://bmfarpfcbbfa5"]
|
||||
|
||||
[ext_resource type="Resource" uid="uid://5bc1qysixhmh" path="res://3D/TrenchBroom/EntityDefinitions/base/actor_base.tres" id="1_2x8yp"]
|
||||
[ext_resource type="PackedScene" uid="uid://bb2pjblwkb7ub" path="res://3D/Scenes/Props/Vending_Machine_3D.tscn" id="2_2x8yp"]
|
||||
[ext_resource type="Script" uid="uid://d1nwwgcrner8b" path="res://addons/func_godot/src/fgd/func_godot_fgd_point_class_display_descriptor.gd" id="2_8x313"]
|
||||
[ext_resource type="Script" uid="uid://ldfqjtq0br35" path="res://addons/func_godot/src/fgd/func_godot_fgd_model_point_class.gd" id="3_2x8yp"]
|
||||
[ext_resource type="Resource" uid="uid://dwc3j47cgj78j" path="res://3D/TrenchBroom/EntityDefinitions/base/requirement_key_base.tres" id="4_req"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("3_2x8yp")
|
||||
|
|
@ -13,7 +14,15 @@ scene_file = ExtResource("2_2x8yp")
|
|||
apply_scale_on_map_build = false
|
||||
classname = "actor_vendingmachine"
|
||||
description = "Vending Machine"
|
||||
base_classes = Array[Resource]([ExtResource("1_2x8yp")])
|
||||
base_classes = Array[Resource]([ExtResource("1_2x8yp"), ExtResource("4_req")])
|
||||
class_properties = Dictionary[String, Variant]({
|
||||
"shop_definition_path": "",
|
||||
"shop_ui_scene_path": ""
|
||||
})
|
||||
class_property_descriptions = Dictionary[String, Variant]({
|
||||
"shop_definition_path": "Optional resource path or uid:// for a VendingShopDefinition. Leave blank to use the scene default.",
|
||||
"shop_ui_scene_path": "Optional packed scene path or uid:// for the shop UI. Leave blank to use the scene default."
|
||||
})
|
||||
meta_properties = Dictionary[String, Variant]({
|
||||
"model": "{\"path\": \"3D/MapModels/actor_vendingmachine.glb\", \"scale\": 16.0 }",
|
||||
"size": AABB(-8, -8, -12, 8, 8, 12)
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -1,5 +1,6 @@
|
|||
[gd_resource type="Resource" script_class="BulletScript3D" format=3 uid="uid://boiwvdhs2jjmf"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://da0qevb67wh1i" path="res://Scripts/Resources/AttackPattern.cs" id="1_14tto"]
|
||||
[ext_resource type="Resource" uid="uid://qrqsywgiij7i" path="res://Resources/Bullets/3D/simple_enemy_bullet_small_3D.tres" id="1_bdx2k"]
|
||||
[ext_resource type="Script" uid="uid://b5s5mjuk1rng5" path="res://Scripts/Resources/TimeModifier.cs" id="2_14tto"]
|
||||
[ext_resource type="Script" uid="uid://bxiprx5nwmpnu" path="res://Scripts/AttackPatterns/ShootingPattern3D.cs" id="3_wsvd4"]
|
||||
|
|
@ -23,7 +24,7 @@ metadata/_bullet_graph_layout_v1 = {
|
|||
script = ExtResource("4_7mmfe")
|
||||
Title = "Danmaku Room 1"
|
||||
Description = "Script for the first danmaku room"
|
||||
Patterns = Array[Object]([SubResource("Resource_bdx2k")])
|
||||
Patterns = Array[ExtResource("1_14tto")]([SubResource("Resource_bdx2k")])
|
||||
metadata/_custom_type_script = "uid://w8hcpu68ssq"
|
||||
metadata/_bullet_graph_layout_v1 = {
|
||||
"res://Resources/BulletScripts/Danmaku_Room_1.tres": Vector2(-1280, 40),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
[gd_resource type="Resource" script_class="BulletScript3D" format=3 uid="uid://dibxxg4o015cd"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://da0qevb67wh1i" path="res://Scripts/Resources/AttackPattern.cs" id="1_wko0l"]
|
||||
[ext_resource type="Resource" uid="uid://qrqsywgiij7i" path="res://Resources/Bullets/3D/simple_enemy_bullet_small_3D.tres" id="1_ww6vs"]
|
||||
[ext_resource type="Script" uid="uid://b5s5mjuk1rng5" path="res://Scripts/Resources/TimeModifier.cs" id="2_wko0l"]
|
||||
[ext_resource type="Script" uid="uid://bxiprx5nwmpnu" path="res://Scripts/AttackPatterns/ShootingPattern3D.cs" id="3_tp6n0"]
|
||||
|
|
@ -23,5 +24,5 @@ metadata/_custom_type_script = "uid://bxiprx5nwmpnu"
|
|||
|
||||
[resource]
|
||||
script = ExtResource("4_2smox")
|
||||
Patterns = Array[Object]([SubResource("Resource_ww6vs")])
|
||||
Patterns = Array[ExtResource("1_wko0l")]([SubResource("Resource_ww6vs")])
|
||||
metadata/_custom_type_script = "uid://w8hcpu68ssq"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
[gd_resource type="Resource" script_class="BulletScript3D" format=3 uid="uid://cx0rbqwvfmm5w"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://da0qevb67wh1i" path="res://Scripts/Resources/AttackPattern.cs" id="1_3hbyi"]
|
||||
[ext_resource type="Resource" uid="uid://dugnfpcenki5l" path="res://Resources/Bullets/3D/simple_blue_bullet_3D.tres" id="1_7k2by"]
|
||||
[ext_resource type="Script" uid="uid://b5s5mjuk1rng5" path="res://Scripts/Resources/TimeModifier.cs" id="2_7k2by"]
|
||||
[ext_resource type="Script" uid="uid://bxiprx5nwmpnu" path="res://Scripts/AttackPatterns/ShootingPattern3D.cs" id="3_knai5"]
|
||||
|
|
@ -19,5 +20,5 @@ metadata/_custom_type_script = "uid://bxiprx5nwmpnu"
|
|||
|
||||
[resource]
|
||||
script = ExtResource("4_ohb2x")
|
||||
Patterns = Array[Object]([SubResource("Resource_7k2by")])
|
||||
Patterns = Array[ExtResource("1_3hbyi")]([SubResource("Resource_7k2by")])
|
||||
metadata/_custom_type_script = "uid://w8hcpu68ssq"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
[gd_resource type="Resource" script_class="BulletScript3D" format=3 uid="uid://wvcda1h8wa2g"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://da0qevb67wh1i" path="res://Scripts/Resources/AttackPattern.cs" id="1_8cm4j"]
|
||||
[ext_resource type="Resource" uid="uid://dpnauedcubupa" path="res://Resources/Bullets/3D/rice_bullet_small_red_3D.tres" id="1_c4f5k"]
|
||||
[ext_resource type="Script" uid="uid://b5s5mjuk1rng5" path="res://Scripts/Resources/TimeModifier.cs" id="2_8cm4j"]
|
||||
[ext_resource type="Script" uid="uid://bxiprx5nwmpnu" path="res://Scripts/AttackPatterns/ShootingPattern3D.cs" id="3_l6rg6"]
|
||||
|
|
@ -22,5 +23,5 @@ metadata/_custom_type_script = "uid://bxiprx5nwmpnu"
|
|||
|
||||
[resource]
|
||||
script = ExtResource("4_or1wb")
|
||||
Patterns = Array[Object]([SubResource("Resource_c4f5k")])
|
||||
Patterns = Array[ExtResource("1_8cm4j")]([SubResource("Resource_c4f5k")])
|
||||
metadata/_custom_type_script = "uid://w8hcpu68ssq"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
[gd_resource type="Resource" script_class="BulletScript3D" format=3 uid="uid://ddw7u1nudixdv"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://da0qevb67wh1i" path="res://Scripts/Resources/AttackPattern.cs" id="1_7dhjl"]
|
||||
[ext_resource type="Resource" uid="uid://dpnauedcubupa" path="res://Resources/Bullets/3D/rice_bullet_small_red_3D.tres" id="1_k1eey"]
|
||||
[ext_resource type="Script" uid="uid://b5s5mjuk1rng5" path="res://Scripts/Resources/TimeModifier.cs" id="2_7dhjl"]
|
||||
[ext_resource type="Script" uid="uid://bxiprx5nwmpnu" path="res://Scripts/AttackPatterns/ShootingPattern3D.cs" id="3_ou3hf"]
|
||||
|
|
@ -23,5 +24,5 @@ metadata/_custom_type_script = "uid://bxiprx5nwmpnu"
|
|||
|
||||
[resource]
|
||||
script = ExtResource("4_748vc")
|
||||
Patterns = Array[Object]([SubResource("Resource_k1eey")])
|
||||
Patterns = Array[ExtResource("1_7dhjl")]([SubResource("Resource_k1eey")])
|
||||
metadata/_custom_type_script = "uid://w8hcpu68ssq"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
[gd_resource type="Resource" script_class="BulletScript3D" format=3 uid="uid://cfhjwydjjjxat"]
|
||||
|
||||
[ext_resource type="Resource" uid="uid://qrqsywgiij7i" path="res://Resources/Bullets/3D/simple_enemy_bullet_small_3D.tres" id="1_hnqww"]
|
||||
[ext_resource type="Script" uid="uid://da0qevb67wh1i" path="res://Scripts/Resources/AttackPattern.cs" id="1_q5dwt"]
|
||||
[ext_resource type="Script" uid="uid://b5s5mjuk1rng5" path="res://Scripts/Resources/TimeModifier.cs" id="2_hnqww"]
|
||||
[ext_resource type="Script" uid="uid://bxiprx5nwmpnu" path="res://Scripts/AttackPatterns/ShootingPattern3D.cs" id="3_ko0d0"]
|
||||
[ext_resource type="Script" uid="uid://w8hcpu68ssq" path="res://Scripts/Resources/BulletScripts/BulletScript3D.cs" id="4_hhjh3"]
|
||||
|
|
@ -14,5 +15,5 @@ metadata/_custom_type_script = "uid://bxiprx5nwmpnu"
|
|||
|
||||
[resource]
|
||||
script = ExtResource("4_hhjh3")
|
||||
Patterns = Array[Object]([SubResource("Resource_7yyul")])
|
||||
Patterns = Array[ExtResource("1_q5dwt")]([SubResource("Resource_7yyul")])
|
||||
metadata/_custom_type_script = "uid://w8hcpu68ssq"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="Resource" script_class="CreditsCollection" load_steps=23 format=3 uid="uid://cojsc1rtf41i1"]
|
||||
[gd_resource type="Resource" script_class="CreditsCollection" format=3 uid="uid://cojsc1rtf41i1"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://buq8eurx510ps" path="res://Scripts/Resources/CreditsCollection.cs" id="1_0bwsf"]
|
||||
[ext_resource type="Script" uid="uid://bc4f4ggvk3ktf" path="res://Scripts/Resources/CreditsEntry.cs" id="1_aaqha"]
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ ShortName = &""
|
|||
ItemDescription = &"Ammo for Ice-Based Weapons"
|
||||
ItemKey = &"ICE_AMMO"
|
||||
Item = 3
|
||||
Price = 2
|
||||
Amount = 5
|
||||
Max = 30
|
||||
ConsumeOnUse = true
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="Resource" script_class="LootItem" load_steps=3 format=3 uid="uid://cltxhkrqp055v"]
|
||||
[gd_resource type="Resource" script_class="LootItem" format=3 uid="uid://cltxhkrqp055v"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://4x3ouxyxjqjc" path="res://Sprites/Items/Credits_Pickup.png" id="1_woor7"]
|
||||
[ext_resource type="Script" uid="uid://epnwjptvks3t" path="res://Scripts/Resources/LootItem.cs" id="2_swcup"]
|
||||
|
|
@ -10,11 +10,9 @@ ShortName = &""
|
|||
ItemDescription = &"Can be used to buy things"
|
||||
ItemKey = &"CREDITS"
|
||||
Item = 12
|
||||
Tier = 0
|
||||
Price = 0
|
||||
Price = 1
|
||||
Amount = 1
|
||||
Max = 10
|
||||
PickupIfMaxed = false
|
||||
Max = 99999999
|
||||
ConsumeOnUse = true
|
||||
UiType = 6
|
||||
Selectable = true
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="Resource" script_class="LootItem" load_steps=3 format=3 uid="uid://cfod8kephnio6"]
|
||||
[gd_resource type="Resource" script_class="LootItem" format=3 uid="uid://cfod8kephnio6"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bxwcjp25xba1j" path="res://Sprites/Items/Nuclear_Ammo.png" id="1_nas3h"]
|
||||
[ext_resource type="Script" uid="uid://epnwjptvks3t" path="res://Scripts/Resources/LootItem.cs" id="2_x45it"]
|
||||
|
|
@ -10,14 +10,10 @@ ShortName = &""
|
|||
ItemDescription = &"Ammo for Nuclear weapons"
|
||||
ItemKey = &"NUCLEAR_AMMO"
|
||||
Item = 3
|
||||
Tier = 0
|
||||
Price = 0
|
||||
Price = 5
|
||||
Amount = 10
|
||||
Max = 50
|
||||
PickupIfMaxed = false
|
||||
ConsumeOnUse = true
|
||||
UiType = 0
|
||||
Selectable = false
|
||||
AutoPickup = true
|
||||
InventorySprite = ExtResource("1_nas3h")
|
||||
DropScenePath = &"res://Scenes/Items/GenericItem.tscn"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
[gd_resource type="Resource" script_class="LootItem" load_steps=3 format=3 uid="uid://diqm2ju0xakkt"]
|
||||
[gd_resource type="Resource" script_class="LootItem" format=3 uid="uid://diqm2ju0xakkt"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://b61po207ggn63" path="res://Sprites/Items/Yin_Ammo.png" id="1_jt7l8"]
|
||||
[ext_resource type="Script" uid="uid://epnwjptvks3t" path="res://Scripts/Resources/LootItem.cs" id="3_ajs4l"]
|
||||
|
|
@ -10,14 +10,10 @@ ShortName = &""
|
|||
ItemDescription = &"Ammo for Ying-Yang based weapons"
|
||||
ItemKey = &"YINYANG_AMMO"
|
||||
Item = 3
|
||||
Tier = 0
|
||||
Price = 0
|
||||
Price = 3
|
||||
Amount = 10
|
||||
Max = 50
|
||||
PickupIfMaxed = false
|
||||
ConsumeOnUse = true
|
||||
UiType = 0
|
||||
Selectable = false
|
||||
AutoPickup = true
|
||||
InventorySprite = ExtResource("1_jt7l8")
|
||||
DropScenePath = &"res://Scenes/Items/GenericItem.tscn"
|
||||
|
|
|
|||
27
Resources/Shops/VendingMachine_Default.tres
Normal file
27
Resources/Shops/VendingMachine_Default.tres
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
[gd_resource type="Resource" script_class="VendingShopDefinition" format=3 uid="uid://cqj0olnkplmvu"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dg6j01fkmdhwd" path="res://Scripts/Resources/VendingShopDefinition.cs" id="1_definition"]
|
||||
[ext_resource type="Script" uid="uid://c0o5wfundmjk" path="res://Scripts/Resources/VendingShopEntry.cs" id="2_entry"]
|
||||
[ext_resource type="Resource" uid="uid://dodwpect0ldjf" path="res://Resources/Items/Heart_Pickup.tres" id="3_health"]
|
||||
[ext_resource type="Resource" uid="uid://bhbufxodybsw4" path="res://Resources/Items/Shield_Pickup.tres" id="4_shield"]
|
||||
[ext_resource type="Resource" uid="uid://ct1fa2huvy34n" path="res://Resources/Items/Ammo1.tres" id="5_ammo"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_health"]
|
||||
script = ExtResource("2_entry")
|
||||
Item = ExtResource("3_health")
|
||||
Unlimited = false
|
||||
StartingQuantity = 4
|
||||
|
||||
[sub_resource type="Resource" id="Resource_shield"]
|
||||
script = ExtResource("2_entry")
|
||||
Item = ExtResource("4_shield")
|
||||
Unlimited = false
|
||||
StartingQuantity = 3
|
||||
|
||||
[sub_resource type="Resource" id="Resource_ammo"]
|
||||
script = ExtResource("2_entry")
|
||||
Item = ExtResource("5_ammo")
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_definition")
|
||||
Entries = Array[ExtResource("2_entry")]([SubResource("Resource_health"), SubResource("Resource_shield"), SubResource("Resource_ammo")])
|
||||
BIN
SFX/sfx_purchase.wav
(Stored with Git LFS)
Normal file
BIN
SFX/sfx_purchase.wav
(Stored with Git LFS)
Normal file
Binary file not shown.
24
SFX/sfx_purchase.wav.import
Normal file
24
SFX/sfx_purchase.wav.import
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
[remap]
|
||||
|
||||
importer="wav"
|
||||
type="AudioStreamWAV"
|
||||
uid="uid://beanbp4411et"
|
||||
path="res://.godot/imported/sfx_purchase.wav-fa7f8a65baa4e5e87a38940df7aab2ed.sample"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://SFX/sfx_purchase.wav"
|
||||
dest_files=["res://.godot/imported/sfx_purchase.wav-fa7f8a65baa4e5e87a38940df7aab2ed.sample"]
|
||||
|
||||
[params]
|
||||
|
||||
force/8_bit=false
|
||||
force/mono=false
|
||||
force/max_rate=false
|
||||
force/max_rate_hz=44100
|
||||
edit/trim=false
|
||||
edit/normalize=false
|
||||
edit/loop_mode=0
|
||||
edit/loop_begin=0
|
||||
edit/loop_end=-1
|
||||
compress/mode=2
|
||||
183
Scenes/HUD/VendingMachineShopUi.tscn
Normal file
183
Scenes/HUD/VendingMachineShopUi.tscn
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
[gd_scene format=3 uid="uid://bnwnkjeuy8vw2"]
|
||||
|
||||
[ext_resource type="Theme" uid="uid://dnsadvmunm76k" path="res://Resources/Styles/MainMenuButtons.tres" id="1_theme"]
|
||||
[ext_resource type="StyleBox" uid="uid://ctw2hju32l3rg" path="res://Resources/Styles/PixelStyleBoxRed.tres" id="2_panel"]
|
||||
[ext_resource type="Script" uid="uid://dwf1c6gber6qn" path="res://Scripts/UI/VendingMachineShopUi.cs" id="3_script"]
|
||||
|
||||
[node name="VendingMachineShopUi" type="CanvasLayer" unique_id=1039113089 node_paths=PackedStringArray("CreditsValueLabel", "ShopItemList", "PreviewTexture", "ItemNameLabel", "DescriptionLabel", "PriceValueLabel", "StockValueLabel", "OwnedValueLabel", "MaxValueLabel", "AllAmmoButton", "BuyButton", "CancelButton", "CloseButton")]
|
||||
process_mode = 3
|
||||
layer = 2
|
||||
script = ExtResource("3_script")
|
||||
CreditsValueLabel = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/HeaderRow/CreditsRow/CreditsValue")
|
||||
ShopItemList = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/LeftColumn/ShopItemList")
|
||||
PreviewTexture = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/PreviewPanel/PreviewTexture")
|
||||
ItemNameLabel = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/ItemName")
|
||||
DescriptionLabel = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/Description")
|
||||
PriceValueLabel = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid/PriceValue")
|
||||
StockValueLabel = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid/StockValue")
|
||||
OwnedValueLabel = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid/OwnedValue")
|
||||
MaxValueLabel = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid/MaxValue")
|
||||
AllAmmoButton = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/LeftColumn/AllAmmoButton")
|
||||
BuyButton = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/FooterRow/BuyButton")
|
||||
CancelButton = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/FooterRow/CancelButton")
|
||||
CloseButton = NodePath("Overlay/PanelContainer/MarginContainer/RootColumn/HeaderRow/CloseButton")
|
||||
|
||||
[node name="Overlay" type="Control" parent="." unique_id=1092991846]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="Backdrop" type="ColorRect" parent="Overlay" unique_id=1819897996]
|
||||
layout_mode = 0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0, 0, 0, 0.68)
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="Overlay" unique_id=728531908]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = -7.0
|
||||
offset_bottom = 7.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme = ExtResource("1_theme")
|
||||
theme_override_styles/panel = ExtResource("2_panel")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="Overlay/PanelContainer" unique_id=1176588702]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="RootColumn" type="VBoxContainer" parent="Overlay/PanelContainer/MarginContainer" unique_id=1296448860]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="HeaderRow" type="HBoxContainer" parent="Overlay/PanelContainer/MarginContainer/RootColumn" unique_id=828923911]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="Title" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/HeaderRow" unique_id=444435654]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Vending Shop"
|
||||
|
||||
[node name="CreditsRow" type="HBoxContainer" parent="Overlay/PanelContainer/MarginContainer/RootColumn/HeaderRow" unique_id=602893457]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="CreditsLabel" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/HeaderRow/CreditsRow" unique_id=45059238]
|
||||
layout_mode = 2
|
||||
text = "Credits:"
|
||||
|
||||
[node name="CreditsValue" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/HeaderRow/CreditsRow" unique_id=329239546]
|
||||
layout_mode = 2
|
||||
text = "0"
|
||||
|
||||
[node name="CloseButton" type="Button" parent="Overlay/PanelContainer/MarginContainer/RootColumn/HeaderRow" unique_id=2132068348]
|
||||
layout_mode = 2
|
||||
text = "X"
|
||||
|
||||
[node name="ContentRow" type="HBoxContainer" parent="Overlay/PanelContainer/MarginContainer/RootColumn" unique_id=197741149]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="LeftColumn" type="VBoxContainer" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow" unique_id=536170789]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="ShopItemList" type="ItemList" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/LeftColumn" unique_id=978618349]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
allow_reselect = true
|
||||
same_column_width = true
|
||||
|
||||
[node name="AllAmmoButton" type="Button" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/LeftColumn" unique_id=1067558866]
|
||||
layout_mode = 2
|
||||
text = "ALL AMMO"
|
||||
|
||||
[node name="RightColumn" type="VBoxContainer" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow" unique_id=872210061]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 4
|
||||
|
||||
[node name="PreviewPanel" type="PanelContainer" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn" unique_id=547238106]
|
||||
custom_minimum_size = Vector2(0, 84)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="PreviewTexture" type="TextureRect" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/PreviewPanel" unique_id=1476414198]
|
||||
layout_mode = 2
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="ItemName" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn" unique_id=560995581]
|
||||
layout_mode = 2
|
||||
text = "Item"
|
||||
|
||||
[node name="Description" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn" unique_id=948571316]
|
||||
clip_contents = true
|
||||
layout_mode = 2
|
||||
text = "Description"
|
||||
autowrap_mode = 3
|
||||
|
||||
[node name="StatsGrid" type="GridContainer" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn" unique_id=864466544]
|
||||
layout_mode = 2
|
||||
columns = 4
|
||||
|
||||
[node name="PriceLabel" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid" unique_id=54171325]
|
||||
layout_mode = 2
|
||||
text = "Price"
|
||||
|
||||
[node name="PriceValue" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid" unique_id=1742129607]
|
||||
layout_mode = 2
|
||||
text = "0"
|
||||
|
||||
[node name="OwnedLabel" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid" unique_id=2140810319]
|
||||
layout_mode = 2
|
||||
text = "Owned"
|
||||
|
||||
[node name="OwnedValue" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid" unique_id=987928714]
|
||||
layout_mode = 2
|
||||
text = "0"
|
||||
|
||||
[node name="StockLabel" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid" unique_id=1276999766]
|
||||
layout_mode = 2
|
||||
text = "Stock"
|
||||
|
||||
[node name="StockValue" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid" unique_id=2002064651]
|
||||
layout_mode = 2
|
||||
text = "0"
|
||||
|
||||
[node name="MaxLabel" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid" unique_id=542385111]
|
||||
layout_mode = 2
|
||||
text = "Max"
|
||||
|
||||
[node name="MaxValue" type="Label" parent="Overlay/PanelContainer/MarginContainer/RootColumn/ContentRow/RightColumn/StatsGrid" unique_id=493157067]
|
||||
layout_mode = 2
|
||||
text = "0"
|
||||
|
||||
[node name="FooterRow" type="HBoxContainer" parent="Overlay/PanelContainer/MarginContainer/RootColumn" unique_id=336387742]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 6
|
||||
alignment = 2
|
||||
|
||||
[node name="BuyButton" type="Button" parent="Overlay/PanelContainer/MarginContainer/RootColumn/FooterRow" unique_id=670623925]
|
||||
layout_mode = 2
|
||||
text = "BUY"
|
||||
|
||||
[node name="CancelButton" type="Button" parent="Overlay/PanelContainer/MarginContainer/RootColumn/FooterRow" unique_id=179357201]
|
||||
layout_mode = 2
|
||||
text = "CANCEL"
|
||||
222
Scripts/Actors/3D/VendingMachine3D.cs
Normal file
222
Scripts/Actors/3D/VendingMachine3D.cs
Normal file
|
|
@ -0,0 +1,222 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Cirno.Scripts.Interactables;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Cirno.Scripts.UI;
|
||||
using Cirno.Scripts.Utils;
|
||||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Actors._3D;
|
||||
|
||||
[Tool]
|
||||
public partial class VendingMachine3D : Interactable3D
|
||||
{
|
||||
public sealed class RuntimeShopEntry
|
||||
{
|
||||
public RuntimeShopEntry(VendingShopEntry entry)
|
||||
{
|
||||
Entry = entry;
|
||||
RemainingQuantity = Math.Max(0, entry.StartingQuantity);
|
||||
}
|
||||
|
||||
public VendingShopEntry Entry { get; }
|
||||
|
||||
public LootItem Item => Entry.Item;
|
||||
|
||||
public bool Unlimited => Entry.Unlimited;
|
||||
|
||||
public int RemainingQuantity { get; private set; }
|
||||
|
||||
public bool CanPurchase(int purchaseCount = 1)
|
||||
{
|
||||
return purchaseCount <= 0 || Unlimited || RemainingQuantity >= purchaseCount;
|
||||
}
|
||||
|
||||
public bool TryConsume(int purchaseCount = 1)
|
||||
{
|
||||
if (purchaseCount <= 0 || Unlimited)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (RemainingQuantity < purchaseCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
RemainingQuantity -= purchaseCount;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[Signal]
|
||||
public delegate void ShopOpenedEventHandler();
|
||||
|
||||
[Signal]
|
||||
public delegate void ShopClosedEventHandler();
|
||||
|
||||
[Export]
|
||||
public PackedScene ShopUiScene { get; private set; } =
|
||||
ResourceLoader.Load<PackedScene>("res://Scenes/HUD/VendingMachineShopUi.tscn");
|
||||
|
||||
[Export]
|
||||
public VendingShopDefinition ShopDefinition { get; private set; } =
|
||||
ResourceLoader.Load<VendingShopDefinition>("res://Resources/Shops/VendingMachine_Default.tres");
|
||||
|
||||
private readonly List<RuntimeShopEntry> _runtimeEntries = [];
|
||||
private VendingMachineShopUi _activeShopUi;
|
||||
private bool _runtimeInitialized;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
AddToGroup("Interactable");
|
||||
|
||||
if (Engine.IsEditorHint())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureRuntimeEntries();
|
||||
}
|
||||
|
||||
public override bool CanActivate()
|
||||
{
|
||||
if (Engine.IsEditorHint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
EnsureRuntimeEntries();
|
||||
|
||||
return !IsShopOpen()
|
||||
&& ShopUiScene != null
|
||||
&& _runtimeEntries.Count > 0
|
||||
&& GameStateManager.Instance?.GameState is not GameState.Shop;
|
||||
}
|
||||
|
||||
public override bool Activate(ActivationType activationType = ActivationType.Toggle)
|
||||
{
|
||||
if (Engine.IsEditorHint())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var typeToUse = activationType is ActivationType.Toggle ? ActivationType.Use : activationType;
|
||||
if (typeToUse is not ActivationType.Use)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!MeetsRequirements() || !CanActivate())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
EnsureRuntimeEntries();
|
||||
|
||||
if (GameStateManager.Instance == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
GameStateManager.Instance.ChangeState(GameState.Shop);
|
||||
|
||||
_activeShopUi = ShopUiScene.Instantiate<VendingMachineShopUi>();
|
||||
_activeShopUi.Init(this);
|
||||
_activeShopUi.Closed += OnShopUiClosed;
|
||||
|
||||
var parent = GetTree().CurrentScene ?? GetTree().Root;
|
||||
parent.AddChild(_activeShopUi);
|
||||
|
||||
EmitSignal(SignalName.ShopOpened);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
if (IsInstanceValid(_activeShopUi))
|
||||
{
|
||||
_activeShopUi.Closed -= OnShopUiClosed;
|
||||
_activeShopUi.QueueFree();
|
||||
}
|
||||
|
||||
_activeShopUi = null;
|
||||
}
|
||||
|
||||
public IReadOnlyList<RuntimeShopEntry> GetEntries()
|
||||
{
|
||||
EnsureRuntimeEntries();
|
||||
return _runtimeEntries;
|
||||
}
|
||||
|
||||
public RuntimeShopEntry FindEntry(StringName itemKey)
|
||||
{
|
||||
EnsureRuntimeEntries();
|
||||
return _runtimeEntries.FirstOrDefault(entry => entry.Item?.ItemKey == itemKey);
|
||||
}
|
||||
|
||||
public bool TryConsumeStock(StringName itemKey, int purchaseCount = 1)
|
||||
{
|
||||
var entry = FindEntry(itemKey);
|
||||
return entry?.TryConsume(purchaseCount) ?? false;
|
||||
}
|
||||
|
||||
// public void _func_godot_apply_properties(Godot.Collections.Dictionary props)
|
||||
// {
|
||||
// if (props.TryGetValue("shop_definition_path", out var shopDefinitionPath))
|
||||
// {
|
||||
// var path = shopDefinitionPath.AsString();
|
||||
// if (!string.IsNullOrWhiteSpace(path))
|
||||
// {
|
||||
// var loadedDefinition = ResourceLoader.Load<VendingShopDefinition>(path);
|
||||
// if (loadedDefinition != null)
|
||||
// {
|
||||
// ShopDefinition = loadedDefinition;
|
||||
// _runtimeInitialized = false;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// GD.PrintErr($"Failed to load vending shop definition from '{path}'");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
private void EnsureRuntimeEntries()
|
||||
{
|
||||
if (_runtimeInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_runtimeInitialized = true;
|
||||
_runtimeEntries.Clear();
|
||||
|
||||
if (ShopDefinition == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var entry in ShopDefinition.Entries.Where(entry => entry?.Item != null))
|
||||
{
|
||||
_runtimeEntries.Add(new RuntimeShopEntry(entry));
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsShopOpen()
|
||||
{
|
||||
return IsInstanceValid(_activeShopUi);
|
||||
}
|
||||
|
||||
private void OnShopUiClosed()
|
||||
{
|
||||
if (IsInstanceValid(_activeShopUi))
|
||||
{
|
||||
_activeShopUi.Closed -= OnShopUiClosed;
|
||||
}
|
||||
|
||||
_activeShopUi = null;
|
||||
EmitSignal(SignalName.ShopClosed);
|
||||
}
|
||||
}
|
||||
1
Scripts/Actors/3D/VendingMachine3D.cs.uid
Normal file
1
Scripts/Actors/3D/VendingMachine3D.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://kt08ji546nms
|
||||
|
|
@ -130,36 +130,50 @@ public partial class InventoryManager : Node
|
|||
public bool AddItem(LootItem item)
|
||||
{
|
||||
//var item = new LootItem() { Item = type, Amount = amount };
|
||||
var maxCount = item.Max <= 0 ? int.MaxValue : item.Max;
|
||||
|
||||
if (!_itemsDict.TryGetValue(item.ItemKey, out var itm))
|
||||
{
|
||||
var startingCount = Math.Clamp(item.Amount, 0, maxCount);
|
||||
if (startingCount <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_itemsDict.Add(item.ItemKey, new ItemContainer()
|
||||
{
|
||||
Item = item,
|
||||
Count = item.Amount,
|
||||
Count = startingCount,
|
||||
});
|
||||
GD.Print($"Added new ({item.ItemKey}) {item.Item} x{item.Amount}");
|
||||
GD.Print($"Added new ({item.ItemKey}) {item.Item} x{startingCount}");
|
||||
|
||||
EmitSignal(SignalName.ItemAdded, item, item.Amount);
|
||||
EmitSignal(SignalName.ItemAdded, item, startingCount);
|
||||
|
||||
if (item.Item is ItemTypes.Ammo)
|
||||
{
|
||||
EmitSignal(SignalName.TotalAmmoChanged, item.ItemKey, startingCount);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (itm.Count < item.Max)
|
||||
if (itm.Count >= maxCount)
|
||||
{
|
||||
itm.Count += item.Amount;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (item.PickupIfMaxed)
|
||||
{
|
||||
itm.Count = item.Max;
|
||||
}
|
||||
else
|
||||
if (!item.PickupIfMaxed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
itm.Count = Math.Clamp(itm.Count + item.Amount, 0, maxCount);
|
||||
}
|
||||
|
||||
EmitSignal(SignalName.ItemAdded, item, itm.Count);
|
||||
|
||||
if (item.Item is ItemTypes.Ammo)
|
||||
{
|
||||
EmitSignal(SignalName.TotalAmmoChanged, item.ItemKey, itm.Count);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ public partial class LootItem : Resource
|
|||
[Export] public bool AutoPickup { get; private set; } = false;
|
||||
|
||||
[Export] public Texture2D InventorySprite;
|
||||
[Export] public Texture2D LargePreviewSprite;
|
||||
|
||||
//[Export] public SpriteFrames WorldSprite;
|
||||
//[Export] public PackedScene HudItemScene;
|
||||
|
|
|
|||
11
Scripts/Resources/VendingShopDefinition.cs
Normal file
11
Scripts/Resources/VendingShopDefinition.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using Godot;
|
||||
using Godot.Collections;
|
||||
|
||||
namespace Cirno.Scripts.Resources;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class VendingShopDefinition : Resource
|
||||
{
|
||||
[Export] public Array<VendingShopEntry> Entries { get; set; } = [];
|
||||
}
|
||||
1
Scripts/Resources/VendingShopDefinition.cs.uid
Normal file
1
Scripts/Resources/VendingShopDefinition.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dg6j01fkmdhwd
|
||||
12
Scripts/Resources/VendingShopEntry.cs
Normal file
12
Scripts/Resources/VendingShopEntry.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.Resources;
|
||||
|
||||
[GlobalClass]
|
||||
[Tool]
|
||||
public partial class VendingShopEntry : Resource
|
||||
{
|
||||
[Export] public LootItem Item { get; set; }
|
||||
[Export] public bool Unlimited { get; set; } = true;
|
||||
[Export] public int StartingQuantity { get; set; } = 1;
|
||||
}
|
||||
1
Scripts/Resources/VendingShopEntry.cs.uid
Normal file
1
Scripts/Resources/VendingShopEntry.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://c0o5wfundmjk
|
||||
447
Scripts/UI/VendingMachineShopUi.cs
Normal file
447
Scripts/UI/VendingMachineShopUi.cs
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Cirno.Scripts.Actors._3D;
|
||||
using Cirno.Scripts.Resources;
|
||||
using Cirno.Scripts.Utils;
|
||||
using Godot;
|
||||
|
||||
namespace Cirno.Scripts.UI;
|
||||
|
||||
public partial class VendingMachineShopUi : CanvasLayer
|
||||
{
|
||||
private sealed class AmmoPurchasePlan
|
||||
{
|
||||
public required VendingMachine3D.RuntimeShopEntry Entry { get; init; }
|
||||
public required int BundleCount { get; init; }
|
||||
public required int TotalPrice { get; init; }
|
||||
}
|
||||
|
||||
[Signal]
|
||||
public delegate void ClosedEventHandler();
|
||||
|
||||
[Export] public Label CreditsValueLabel { get; private set; }
|
||||
[Export] public ItemList ShopItemList { get; private set; }
|
||||
[Export] public TextureRect PreviewTexture { get; private set; }
|
||||
[Export] public Label ItemNameLabel { get; private set; }
|
||||
[Export] public Label DescriptionLabel { get; private set; }
|
||||
[Export] public Label PriceValueLabel { get; private set; }
|
||||
[Export] public Label StockValueLabel { get; private set; }
|
||||
[Export] public Label OwnedValueLabel { get; private set; }
|
||||
[Export] public Label MaxValueLabel { get; private set; }
|
||||
[Export] public Button AllAmmoButton { get; private set; }
|
||||
[Export] public Button BuyButton { get; private set; }
|
||||
[Export] public Button CancelButton { get; private set; }
|
||||
[Export] public Button CloseButton { get; private set; }
|
||||
|
||||
[Export] public StringName CancelActionName { get; private set; } = "ui_cancel";
|
||||
[Export] public bool AutoFitToViewport { get; private set; }
|
||||
[Export] public Vector2 ShopPanelDesignSize { get; private set; } = new(720f, 380f);
|
||||
[Export(PropertyHint.None, "suffix:px")] public float ViewportMargin { get; private set; } = 24f;
|
||||
|
||||
private readonly List<VendingMachine3D.RuntimeShopEntry> _entries = [];
|
||||
private VendingMachine3D _machine;
|
||||
private bool _isClosing;
|
||||
private bool _isReady;
|
||||
private int _selectedIndex = -1;
|
||||
private PanelContainer _rootPanel;
|
||||
|
||||
public void Init(VendingMachine3D machine)
|
||||
{
|
||||
_machine = machine;
|
||||
|
||||
if (_isReady)
|
||||
{
|
||||
RefreshUi();
|
||||
}
|
||||
}
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
ProcessMode = ProcessModeEnum.Always;
|
||||
|
||||
_isReady = true;
|
||||
_rootPanel = GetNode<PanelContainer>("Overlay/PanelContainer");
|
||||
|
||||
CloseButton.Pressed += CloseShop;
|
||||
CancelButton.Pressed += CloseShop;
|
||||
BuyButton.Pressed += BuySelectedItem;
|
||||
AllAmmoButton.Pressed += BuyAllAmmo;
|
||||
ShopItemList.ItemSelected += OnItemSelected;
|
||||
ShopItemList.ItemActivated += OnItemActivated;
|
||||
|
||||
if (AutoFitToViewport && GetViewport() != null)
|
||||
{
|
||||
GetViewport().SizeChanged += OnViewportSizeChanged;
|
||||
}
|
||||
|
||||
FitToViewport();
|
||||
|
||||
if (InventoryManager.Instance != null)
|
||||
{
|
||||
InventoryManager.Instance.ItemAdded += OnInventoryChanged;
|
||||
InventoryManager.Instance.ItemRemoved += OnInventoryChanged;
|
||||
}
|
||||
|
||||
RefreshUi();
|
||||
}
|
||||
|
||||
public override void _ExitTree()
|
||||
{
|
||||
if (AutoFitToViewport && GetViewport() != null)
|
||||
{
|
||||
GetViewport().SizeChanged -= OnViewportSizeChanged;
|
||||
}
|
||||
|
||||
if (InventoryManager.Instance != null)
|
||||
{
|
||||
InventoryManager.Instance.ItemAdded -= OnInventoryChanged;
|
||||
InventoryManager.Instance.ItemRemoved -= OnInventoryChanged;
|
||||
}
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (_isClosing || GameStateManager.Instance?.GameState is not GameState.Shop)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Input.IsActionJustPressed(CancelActionName))
|
||||
{
|
||||
CloseShop();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnInventoryChanged(LootItem item, int currentAmount)
|
||||
{
|
||||
RefreshUi();
|
||||
}
|
||||
|
||||
private void OnInventoryChanged(string itemKey, int currentAmount)
|
||||
{
|
||||
RefreshUi();
|
||||
}
|
||||
|
||||
private void RefreshUi()
|
||||
{
|
||||
FitToViewport();
|
||||
PopulateList();
|
||||
UpdateCredits();
|
||||
UpdateAllAmmoButton();
|
||||
UpdateSelectionDetails();
|
||||
|
||||
if (_entries.Count > 0)
|
||||
{
|
||||
if (_selectedIndex < 0)
|
||||
{
|
||||
SelectEntry(0, true);
|
||||
}
|
||||
|
||||
CallDeferred(MethodName.GrabListFocus);
|
||||
}
|
||||
}
|
||||
|
||||
private void GrabListFocus()
|
||||
{
|
||||
ShopItemList?.GrabFocus();
|
||||
}
|
||||
|
||||
private void OnViewportSizeChanged()
|
||||
{
|
||||
FitToViewport();
|
||||
}
|
||||
|
||||
private void FitToViewport()
|
||||
{
|
||||
if (!AutoFitToViewport || _rootPanel == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var viewport = GetViewport();
|
||||
if (viewport == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var viewportSize = viewport.GetVisibleRect().Size;
|
||||
var availableWidth = Mathf.Max(1f, viewportSize.X - (ViewportMargin * 2f));
|
||||
var availableHeight = Mathf.Max(1f, viewportSize.Y - (ViewportMargin * 2f));
|
||||
var scale = Mathf.Min(1f, Mathf.Min(availableWidth / ShopPanelDesignSize.X, availableHeight / ShopPanelDesignSize.Y));
|
||||
var scaledSize = ShopPanelDesignSize * scale;
|
||||
|
||||
_rootPanel.SetAnchorsPreset(Control.LayoutPreset.TopLeft);
|
||||
_rootPanel.Size = ShopPanelDesignSize;
|
||||
_rootPanel.PivotOffset = Vector2.Zero;
|
||||
_rootPanel.Scale = new Vector2(scale, scale);
|
||||
_rootPanel.Position = (viewportSize - scaledSize) * 0.5f;
|
||||
}
|
||||
|
||||
private void PopulateList()
|
||||
{
|
||||
_entries.Clear();
|
||||
ShopItemList.Clear();
|
||||
|
||||
if (_machine != null)
|
||||
{
|
||||
_entries.AddRange(_machine.GetEntries());
|
||||
}
|
||||
|
||||
for (var index = 0; index < _entries.Count; index++)
|
||||
{
|
||||
var entry = _entries[index];
|
||||
var item = entry.Item;
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var displayName = GetDisplayName(item);
|
||||
var stockLabel = entry.Unlimited ? "INF" : entry.RemainingQuantity.ToString();
|
||||
var row = $"{displayName} {item.Price}c [{stockLabel}]";
|
||||
|
||||
ShopItemList.AddItem(row, item.InventorySprite, true);
|
||||
ShopItemList.SetItemTooltip(index, item.ItemDescription.ToString());
|
||||
}
|
||||
|
||||
if (_entries.Count == 0)
|
||||
{
|
||||
_selectedIndex = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
_selectedIndex = Math.Clamp(_selectedIndex, 0, _entries.Count - 1);
|
||||
ShopItemList.Select(_selectedIndex);
|
||||
}
|
||||
|
||||
private void UpdateCredits()
|
||||
{
|
||||
var credits = InventoryManager.Instance?.GetItemCount("CREDITS") ?? 0;
|
||||
CreditsValueLabel.Text = credits.ToString();
|
||||
}
|
||||
|
||||
private void UpdateAllAmmoButton()
|
||||
{
|
||||
var plans = BuildAllAmmoPlan(out var totalPrice, out var canPurchase);
|
||||
|
||||
AllAmmoButton.Text = plans.Count == 0 ? "ALL AMMO" : $"ALL AMMO ({totalPrice}c)";
|
||||
AllAmmoButton.Disabled = !canPurchase;
|
||||
}
|
||||
|
||||
private void UpdateSelectionDetails()
|
||||
{
|
||||
if (!TryGetSelectedEntry(out var entry))
|
||||
{
|
||||
PreviewTexture.Texture = null;
|
||||
ItemNameLabel.Text = "No Stock";
|
||||
DescriptionLabel.Text = "This vending machine has no shop entries configured.";
|
||||
PriceValueLabel.Text = "--";
|
||||
StockValueLabel.Text = "--";
|
||||
OwnedValueLabel.Text = "--";
|
||||
MaxValueLabel.Text = "--";
|
||||
BuyButton.Text = "BUY";
|
||||
BuyButton.Disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var item = entry.Item;
|
||||
var currentCount = GetCurrentCount(item);
|
||||
var canBuy = CanBuy(entry);
|
||||
|
||||
PreviewTexture.Texture = item.LargePreviewSprite ?? item.InventorySprite;
|
||||
ItemNameLabel.Text = item.ItemName.ToString();
|
||||
DescriptionLabel.Text = item.ItemDescription.ToString();
|
||||
PriceValueLabel.Text = item.Price.ToString();
|
||||
StockValueLabel.Text = entry.Unlimited ? "Unlimited" : entry.RemainingQuantity.ToString();
|
||||
OwnedValueLabel.Text = currentCount.ToString();
|
||||
MaxValueLabel.Text = item.Max.ToString();
|
||||
BuyButton.Text = $"BUY ({item.Price}c)";
|
||||
BuyButton.Disabled = !canBuy;
|
||||
}
|
||||
|
||||
private void OnItemSelected(long index)
|
||||
{
|
||||
SelectEntry((int)index);
|
||||
}
|
||||
|
||||
private void OnItemActivated(long index)
|
||||
{
|
||||
SelectEntry((int)index);
|
||||
BuySelectedItem();
|
||||
}
|
||||
|
||||
private void SelectEntry(int index, bool forceFocus = false)
|
||||
{
|
||||
if (_entries.Count == 0)
|
||||
{
|
||||
_selectedIndex = -1;
|
||||
UpdateSelectionDetails();
|
||||
return;
|
||||
}
|
||||
|
||||
_selectedIndex = Math.Clamp(index, 0, _entries.Count - 1);
|
||||
ShopItemList.Select(_selectedIndex);
|
||||
UpdateSelectionDetails();
|
||||
|
||||
if (forceFocus)
|
||||
{
|
||||
ShopItemList.GrabFocus();
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryGetSelectedEntry(out VendingMachine3D.RuntimeShopEntry entry)
|
||||
{
|
||||
if (_selectedIndex < 0 || _selectedIndex >= _entries.Count)
|
||||
{
|
||||
entry = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
entry = _entries[_selectedIndex];
|
||||
return entry?.Item != null;
|
||||
}
|
||||
|
||||
private bool CanBuy(VendingMachine3D.RuntimeShopEntry entry)
|
||||
{
|
||||
var item = entry.Item;
|
||||
if (item == null || InventoryManager.Instance == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var currentCount = GetCurrentCount(item);
|
||||
if (currentCount >= item.Max)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return entry.CanPurchase()
|
||||
&& InventoryManager.Instance.CanAddItem(item.ItemKey.ToString())
|
||||
&& InventoryManager.Instance.GetItemCount("CREDITS") >= item.Price;
|
||||
}
|
||||
|
||||
private void BuySelectedItem()
|
||||
{
|
||||
if (!TryGetSelectedEntry(out var entry) || !CanBuy(entry) || InventoryManager.Instance == null)
|
||||
{
|
||||
RefreshUi();
|
||||
return;
|
||||
}
|
||||
|
||||
_machine.TryConsumeStock(entry.Item.ItemKey);
|
||||
InventoryManager.Instance.RemoveItem("CREDITS", entry.Item.Price);
|
||||
InventoryManager.Instance.AddItem(entry.Item);
|
||||
|
||||
RefreshUi();
|
||||
}
|
||||
|
||||
private void BuyAllAmmo()
|
||||
{
|
||||
if (InventoryManager.Instance == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var plans = BuildAllAmmoPlan(out var totalPrice, out var canPurchase);
|
||||
if (!canPurchase || plans.Count == 0)
|
||||
{
|
||||
RefreshUi();
|
||||
return;
|
||||
}
|
||||
|
||||
InventoryManager.Instance.RemoveItem("CREDITS", totalPrice);
|
||||
|
||||
foreach (var plan in plans)
|
||||
{
|
||||
_machine.TryConsumeStock(plan.Entry.Item.ItemKey, plan.BundleCount);
|
||||
|
||||
for (var purchaseIndex = 0; purchaseIndex < plan.BundleCount; purchaseIndex++)
|
||||
{
|
||||
InventoryManager.Instance.AddItem(plan.Entry.Item);
|
||||
}
|
||||
}
|
||||
|
||||
RefreshUi();
|
||||
}
|
||||
|
||||
private List<AmmoPurchasePlan> BuildAllAmmoPlan(out int totalPrice, out bool canPurchase)
|
||||
{
|
||||
totalPrice = 0;
|
||||
canPurchase = false;
|
||||
|
||||
if (InventoryManager.Instance == null)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var plans = new List<AmmoPurchasePlan>();
|
||||
|
||||
foreach (var entry in _entries.Where(entry => entry.Item?.Item == ItemTypes.Ammo))
|
||||
{
|
||||
if (!InventoryManager.Instance.TryGetItem(entry.Item.ItemKey.ToString(), out var ownedItem))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ownedItem.Count >= entry.Item.Max)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var bundleSize = Math.Max(1, entry.Item.Amount);
|
||||
var missingAmount = entry.Item.Max - ownedItem.Count;
|
||||
var bundleCount = Mathf.CeilToInt(missingAmount / (float)bundleSize);
|
||||
|
||||
if (!entry.CanPurchase(bundleCount))
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var price = bundleCount * entry.Item.Price;
|
||||
plans.Add(new AmmoPurchasePlan
|
||||
{
|
||||
Entry = entry,
|
||||
BundleCount = bundleCount,
|
||||
TotalPrice = price,
|
||||
});
|
||||
totalPrice += price;
|
||||
}
|
||||
|
||||
canPurchase = plans.Count > 0 && InventoryManager.Instance.GetItemCount("CREDITS") >= totalPrice;
|
||||
return plans;
|
||||
}
|
||||
|
||||
private int GetCurrentCount(LootItem item)
|
||||
{
|
||||
return InventoryManager.Instance?.GetItemCount(item.ItemKey.ToString()) ?? 0;
|
||||
}
|
||||
|
||||
private void CloseShop()
|
||||
{
|
||||
if (_isClosing)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_isClosing = true;
|
||||
|
||||
if (GameStateManager.Instance != null)
|
||||
{
|
||||
GameStateManager.Instance.ChangeState(GameState.Playing);
|
||||
}
|
||||
|
||||
EmitSignal(SignalName.Closed);
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
private static string GetDisplayName(LootItem item)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(item.ShortName.ToString()))
|
||||
{
|
||||
return item.ShortName.ToString();
|
||||
}
|
||||
|
||||
return item.ItemName.ToString();
|
||||
}
|
||||
}
|
||||
1
Scripts/UI/VendingMachineShopUi.cs.uid
Normal file
1
Scripts/UI/VendingMachineShopUi.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dwf1c6gber6qn
|
||||
Loading…
Add table
Add a link
Reference in a new issue