basic capture functionality
This commit is contained in:
parent
246f3c0840
commit
c141e6a169
20 changed files with 430 additions and 14 deletions
|
|
@ -15,6 +15,10 @@ run/main_scene="uid://dackb8ekt4sk6"
|
|||
config/features=PackedStringArray("4.6", "C#", "GL Compatibility")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[autoload]
|
||||
|
||||
GameRoot="*uid://boip0mbmeqmhk"
|
||||
|
||||
[dotnet]
|
||||
|
||||
project/assembly_name="ocker"
|
||||
|
|
@ -54,10 +58,21 @@ ui_down={
|
|||
]
|
||||
}
|
||||
debug_cycle_time={
|
||||
"deadzone": 0.5,
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":84,"key_label":0,"unicode":116,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
interact={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
capture_mash={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":32,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":1,"position":Vector2(389, 19),"global_position":Vector2(398, 67),"factor":1.0,"button_index":1,"canceled":false,"pressed":true,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[physics]
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,12 @@
|
|||
[ext_resource type="Script" uid="uid://cqdq8fslu7cyp" path="res://scripts/world/ChunkManager.cs" id="2_0bbpv"]
|
||||
[ext_resource type="Script" uid="uid://db2vbbh5737ke" path="res://scripts/core/PackManager.cs" id="3_rarhs"]
|
||||
[ext_resource type="PackedScene" uid="uid://bs7qu34sfgvjx" path="res://scenes/world/PickupMarker.tscn" id="3_vcsgt"]
|
||||
[ext_resource type="PackedScene" uid="uid://bjil24xdbm76x" path="res://scenes/world/CreatureMarker.tscn" id="4_nxtc6"]
|
||||
[ext_resource type="PackedScene" uid="uid://djkstm7pmu7gq" path="res://scenes/world/Creature.tscn" id="4_nxtc6"]
|
||||
[ext_resource type="Script" uid="uid://osk74jjhtcjy" path="res://scripts/core/SaveManager.cs" id="4_rarhs"]
|
||||
[ext_resource type="Script" uid="uid://b6gxknud5unt" path="res://scripts/core/WorldClock.cs" id="6_c01mt"]
|
||||
[ext_resource type="Script" uid="uid://boip0mbmeqmhk" path="res://scripts/core/GameRoot.cs" id="8_jlsqs"]
|
||||
[ext_resource type="PackedScene" uid="uid://bffdg1ki45e4e" path="res://ui/CaptureUI.tscn" id="9_lhr70"]
|
||||
[ext_resource type="Script" uid="uid://bl7xagtutg20w" path="res://scripts/core/CaptureController.cs" id="10_wp0k4"]
|
||||
|
||||
[node name="Main" type="Node2D" unique_id=1194367579]
|
||||
|
||||
|
|
@ -31,3 +34,12 @@ script = ExtResource("4_rarhs")
|
|||
|
||||
[node name="WorldClock" type="Node" parent="." unique_id=437350596]
|
||||
script = ExtResource("6_c01mt")
|
||||
|
||||
[node name="GameRoot" type="Node" parent="." unique_id=1464632231]
|
||||
script = ExtResource("8_jlsqs")
|
||||
|
||||
[node name="CaptureUi" parent="." unique_id=1650401906 instance=ExtResource("9_lhr70")]
|
||||
|
||||
[node name="CaptureController" type="Node" parent="." unique_id=68644702]
|
||||
script = ExtResource("10_wp0k4")
|
||||
CaptureUIPath = NodePath("../CaptureUi")
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
[gd_scene format=3 uid="uid://bjt15rm720w5g"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://duf0vlr2yin8l" path="res://scripts/gameplay/Player.cs" id="1_p0vlq"]
|
||||
[ext_resource type="Script" uid="uid://dtaa141c1wb8e" path="res://scripts/world/PlayerInteractor.cs" id="2_v6fml"]
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_p0vlq"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_3li8b"]
|
||||
|
||||
[node name="Player" type="CharacterBody2D" unique_id=1675096620]
|
||||
script = ExtResource("1_p0vlq")
|
||||
|
||||
|
|
@ -27,3 +30,10 @@ offset_right = 8.0
|
|||
offset_bottom = 8.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="InteractArea" type="Area2D" parent="." unique_id=973889967]
|
||||
script = ExtResource("2_v6fml")
|
||||
GameRootPath = NodePath("")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea" unique_id=524618181]
|
||||
shape = SubResource("CircleShape2D_3li8b")
|
||||
|
|
|
|||
15
scenes/world/Creature.tscn
Normal file
15
scenes/world/Creature.tscn
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[gd_scene format=3 uid="uid://djkstm7pmu7gq"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://it4jgvdqmkvr" path="res://scripts/world/Creature.cs" id="1_65v7p"]
|
||||
[ext_resource type="Script" uid="uid://c3276p03ic158" path="res://scripts/world/CreatureVisual.cs" id="1_u1pt2"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_65v7p"]
|
||||
|
||||
[node name="Creature" type="Area2D" unique_id=60731392]
|
||||
script = ExtResource("1_65v7p")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=470973293]
|
||||
shape = SubResource("CircleShape2D_65v7p")
|
||||
|
||||
[node name="Visual" type="Node2D" parent="." unique_id=688427995]
|
||||
script = ExtResource("1_u1pt2")
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
[gd_scene format=3 uid="uid://bjil24xdbm76x"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c3276p03ic158" path="res://scripts/world/CreatureVisual.cs" id="1_vucws"]
|
||||
|
||||
[node name="CreatureMarker" type="Node2D" unique_id=1874810005]
|
||||
|
||||
[node name="Visual" type="Node2D" parent="." unique_id=309456162]
|
||||
script = ExtResource("1_vucws")
|
||||
|
|
|
|||
28
scripts/core/CaptureController.cs
Normal file
28
scripts/core/CaptureController.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
using Godot;
|
||||
|
||||
public partial class CaptureController : Node
|
||||
{
|
||||
[Export] public NodePath CaptureUIPath { get; set; }
|
||||
|
||||
private GameRoot _root = null!;
|
||||
private CaptureUI? _ui;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_ui = GetNodeOrNull<CaptureUI>(CaptureUIPath);
|
||||
if (_ui == null)
|
||||
{
|
||||
GD.PrintErr("CaptureController: CaptureUIPath not set.");
|
||||
return;
|
||||
}
|
||||
|
||||
GameRoot.Instance.CaptureRequested += OnRequestCapture;
|
||||
}
|
||||
|
||||
private void OnRequestCapture(Creature creature)
|
||||
{
|
||||
if (_ui == null) return;
|
||||
if (!IsInstanceValid(creature)) return;
|
||||
_ui.StartCapture(creature);
|
||||
}
|
||||
}
|
||||
1
scripts/core/CaptureController.cs.uid
Normal file
1
scripts/core/CaptureController.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bl7xagtutg20w
|
||||
14
scripts/core/GameRoot.cs
Normal file
14
scripts/core/GameRoot.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using Godot;
|
||||
|
||||
public partial class GameRoot : Node
|
||||
{
|
||||
public static GameRoot Instance { get; private set; } = null!;
|
||||
public event System.Action<Creature>? CaptureRequested;
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
public void RequestCapture(Creature creature) => CaptureRequested?.Invoke(creature);
|
||||
}
|
||||
1
scripts/core/GameRoot.cs.uid
Normal file
1
scripts/core/GameRoot.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://boip0mbmeqmhk
|
||||
|
|
@ -9,6 +9,8 @@ public class SaveState
|
|||
// Respawnables: pickupId -> unixTimeSeconds when it becomes available again
|
||||
public Dictionary<string, long> PickupRespawnAt { get; set; } = new();
|
||||
|
||||
public HashSet<string> CapturedCreatures { get; set; } = new();
|
||||
|
||||
//public Vector2I? LastPlayerChunk { get; set; } // optional debug, requires "using Godot;"
|
||||
//public int[]? LastPlayerChunk { get; set; } // [x,y] same debug as above, does not require Godot
|
||||
}
|
||||
|
|
|
|||
121
scripts/ui/CaptureUI.cs
Normal file
121
scripts/ui/CaptureUI.cs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
using Godot;
|
||||
|
||||
public partial class CaptureUI : CanvasLayer
|
||||
{
|
||||
[Export] public float BaseTimeLimit = 3.0f;
|
||||
[Export] public float BaseRequired = 14.0f; // “energy” required
|
||||
[Export] public float EnergyPerPress = 1.0f;
|
||||
|
||||
private Creature? _target;
|
||||
private SaveManager? _save;
|
||||
|
||||
private float _timeLeft;
|
||||
private float _required;
|
||||
private float _energy;
|
||||
|
||||
private OptionButton _ballOption = null!;
|
||||
private ProgressBar _bar = null!;
|
||||
private Label _timer = null!;
|
||||
private Label _title = null!;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
_ballOption = GetNode<OptionButton>("Panel/VBoxContainer/SoulballOption");
|
||||
_bar = GetNode<ProgressBar>("Panel/VBoxContainer/MashBar");
|
||||
_timer = GetNode<Label>("Panel/VBoxContainer/TimerLabel");
|
||||
_title = GetNode<Label>("Panel/VBoxContainer/CreatureNameLabel");
|
||||
|
||||
Visible = false;
|
||||
|
||||
// v0 balls
|
||||
_ballOption.Clear();
|
||||
_ballOption.AddItem("Basic Soulball (easy)", 0);
|
||||
_ballOption.AddItem("Heavy Soulball (hard)", 1);
|
||||
|
||||
_save = GetNodeOrNull<SaveManager>("/root/Main/SaveManager"); // or export a path if you prefer
|
||||
}
|
||||
|
||||
public void StartCapture(Creature target)
|
||||
{
|
||||
_target = target;
|
||||
_energy = 0;
|
||||
|
||||
// Ball selection affects difficulty (v0)
|
||||
int ballId = _ballOption.GetSelectedId();
|
||||
float difficultyMul = ballId switch
|
||||
{
|
||||
0 => 1.0f,
|
||||
1 => 1.4f,
|
||||
_ => 1.0f
|
||||
};
|
||||
|
||||
_required = BaseRequired * difficultyMul;
|
||||
_timeLeft = BaseTimeLimit;
|
||||
|
||||
_title.Text = $"Capture: {target.CreatureId}";
|
||||
_bar.MinValue = 0;
|
||||
_bar.MaxValue = _required;
|
||||
_bar.Value = 0;
|
||||
|
||||
Visible = true;
|
||||
|
||||
// Optional: pause world while capturing
|
||||
GetTree().Paused = true;
|
||||
ProcessMode = ProcessModeEnum.WhenPaused;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (!Visible || _target == null) return;
|
||||
|
||||
// Count presses
|
||||
if (Input.IsActionJustPressed("capture_mash"))
|
||||
{
|
||||
_energy += EnergyPerPress;
|
||||
_bar.Value = _energy;
|
||||
}
|
||||
|
||||
_timeLeft -= (float)delta;
|
||||
_timer.Text = $"Time: {_timeLeft:0.00}s";
|
||||
|
||||
if (_energy >= _required)
|
||||
{
|
||||
OnCaptureSuccess();
|
||||
}
|
||||
else if (_timeLeft <= 0)
|
||||
{
|
||||
OnCaptureFail();
|
||||
}
|
||||
}
|
||||
|
||||
private void EndCapture()
|
||||
{
|
||||
Visible = false;
|
||||
GetTree().Paused = false;
|
||||
ProcessMode = ProcessModeEnum.Inherit;
|
||||
_target = null;
|
||||
}
|
||||
|
||||
private void OnCaptureSuccess()
|
||||
{
|
||||
if (_target == null) return;
|
||||
|
||||
GD.Print($"Captured {_target.CreatureId}");
|
||||
|
||||
// v0: store captured creature IDs
|
||||
if (_save != null)
|
||||
{
|
||||
_save.State.CapturedCreatures.Add(_target.CreatureId);
|
||||
_save.Save();
|
||||
}
|
||||
|
||||
_target.Despawn();
|
||||
EndCapture();
|
||||
}
|
||||
|
||||
private void OnCaptureFail()
|
||||
{
|
||||
GD.Print("Capture failed");
|
||||
EndCapture();
|
||||
}
|
||||
}
|
||||
1
scripts/ui/CaptureUI.cs.uid
Normal file
1
scripts/ui/CaptureUI.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cg3q7gxpffte
|
||||
|
|
@ -21,6 +21,7 @@ public partial class ChunkManager : Node2D
|
|||
private WorldIndex? _world;
|
||||
private Dictionary<(int x, int y), string> _chunkMap = new();
|
||||
private readonly Dictionary<(int x, int y), Node2D> _loaded = new();
|
||||
private readonly Dictionary<(int x, int y), ChunkData> _chunkDataByCoord = new();
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
|
|
@ -102,6 +103,7 @@ public partial class ChunkManager : Node2D
|
|||
{
|
||||
_loaded[k].QueueFree();
|
||||
_loaded.Remove(k);
|
||||
_chunkDataByCoord.Remove(k);
|
||||
}
|
||||
|
||||
if (_clock != null)
|
||||
|
|
@ -140,7 +142,7 @@ public partial class ChunkManager : Node2D
|
|||
var biome = data.biome ?? "biome:unknown";
|
||||
|
||||
var node = CreateDebugChunkNode(x, y, _world!.chunk_size_px, biome);
|
||||
node.SetMeta("chunk_data", data);
|
||||
_chunkDataByCoord[(x, y)] = data;
|
||||
// Put the chunk into the scene tree first so Timers can run.
|
||||
AddChild(node);
|
||||
AddChunkMarkers(node, data);
|
||||
|
|
@ -174,6 +176,8 @@ public partial class ChunkManager : Node2D
|
|||
_ => new Color(0.2f, 0.2f, 0.2f, 0.25f)
|
||||
}
|
||||
};
|
||||
rect.ZIndex = -100; // keep the biome overlay behind all markers
|
||||
rect.ZAsRelative = true;
|
||||
|
||||
n.AddChild(rect);
|
||||
return n;
|
||||
|
|
@ -249,14 +253,73 @@ public partial class ChunkManager : Node2D
|
|||
}
|
||||
|
||||
// Collision rects: gray outlines (optional later)
|
||||
AddCollisionRects(chunkNode, data);
|
||||
|
||||
//if (data.spawn_zones != null)
|
||||
//{
|
||||
//foreach (var z in data.spawn_zones)
|
||||
//SpawnCreaturesForZone(chunkNode, z);
|
||||
//}
|
||||
|
||||
if (data.spawn_zones != null)
|
||||
{
|
||||
foreach (var z in data.spawn_zones)
|
||||
{
|
||||
var r = z.rect;
|
||||
var zoneRect = new ColorRect
|
||||
{
|
||||
Position = new Vector2(r[0], r[1]),
|
||||
Size = new Vector2(r[2], r[3]),
|
||||
Color = new Color(0.9f, 0.9f, 0.1f, 0.10f), // faint yellow overlay
|
||||
MouseFilter = Control.MouseFilterEnum.Ignore
|
||||
};
|
||||
chunkNode.AddChild(zoneRect);
|
||||
|
||||
SpawnCreaturesForZone(chunkNode, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void AddCollisionRects(Node2D chunkNode, ChunkData data)
|
||||
{
|
||||
if (data.collision_rects == null) return;
|
||||
|
||||
foreach (var c in data.collision_rects)
|
||||
{
|
||||
var r = c.rect; // [x,y,w,h]
|
||||
|
||||
// Physics body
|
||||
var body = new StaticBody2D
|
||||
{
|
||||
Name = $"Col_{c.id.Replace(":", "_")}",
|
||||
Position = new Vector2(r[0], r[1])
|
||||
};
|
||||
|
||||
var shape = new CollisionShape2D();
|
||||
var rectShape = new RectangleShape2D
|
||||
{
|
||||
Size = new Vector2(r[2], r[3])
|
||||
};
|
||||
shape.Shape = rectShape;
|
||||
|
||||
// CollisionShape2D is centered, so offset it by half-size to align to top-left rect coords
|
||||
shape.Position = new Vector2(r[2] / 2f, r[3] / 2f);
|
||||
|
||||
body.AddChild(shape);
|
||||
|
||||
// Visual outline (gray)
|
||||
var outline = new RectOutline
|
||||
{
|
||||
Size = new Vector2(r[2], r[3]),
|
||||
ZIndex = 10,
|
||||
ZAsRelative = true
|
||||
};
|
||||
body.AddChild(outline);
|
||||
|
||||
chunkNode.AddChild(body);
|
||||
}
|
||||
}
|
||||
|
||||
private static long NowUnixSeconds()
|
||||
{
|
||||
return DateTimeOffset.UtcNow.ToUnixTimeSeconds();
|
||||
|
|
@ -381,6 +444,8 @@ public partial class ChunkManager : Node2D
|
|||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var c = (Node2D)CreatureMarkerScene.Instantiate();
|
||||
c.ZIndex = 50; // draw above debug chunk background
|
||||
c.ZAsRelative = true;
|
||||
c.Position = new Vector2(
|
||||
r[0] + rng.RandfRange(0, r[2]),
|
||||
r[1] + rng.RandfRange(0, r[3])
|
||||
|
|
@ -391,23 +456,23 @@ public partial class ChunkManager : Node2D
|
|||
|
||||
private void RefreshCreaturesInLoadedChunks()
|
||||
{
|
||||
foreach (var chunk in _loaded.Values)
|
||||
foreach (var kv in _loaded)
|
||||
{
|
||||
var coord = kv.Key;
|
||||
var chunk = kv.Value;
|
||||
|
||||
// Remove existing creature containers
|
||||
foreach (var child in chunk.GetChildren())
|
||||
foreach (var childObj in chunk.GetChildren())
|
||||
{
|
||||
if (child is Node n && n.Name.StartsWith("Creatures_"))
|
||||
if (childObj is Node n && n.Name.ToString().StartsWith("Creatures_"))
|
||||
n.QueueFree();
|
||||
}
|
||||
|
||||
// Re-read spawn zones by re-parsing the chunk json is overkill.
|
||||
// v0 hack: store ChunkData on the chunk node as metadata.
|
||||
if (chunk.HasMeta("chunk_data"))
|
||||
// Re-spawn creatures based on stored ChunkData
|
||||
if (_chunkDataByCoord.TryGetValue(coord, out var data) && data.spawn_zones != null)
|
||||
{
|
||||
var data = (ChunkData)chunk.GetMeta("chunk_data");
|
||||
if (data.spawn_zones != null)
|
||||
foreach (var z in data.spawn_zones)
|
||||
SpawnCreaturesForZone(chunk, z);
|
||||
foreach (var z in data.spawn_zones)
|
||||
SpawnCreaturesForZone(chunk, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
scripts/world/Creature.cs
Normal file
20
scripts/world/Creature.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using Godot;
|
||||
|
||||
public partial class Creature : Area2D
|
||||
{
|
||||
[Export] public string CreatureId { get; set; } = "creature:ember_fox";
|
||||
public bool IsCaptured { get; private set; } = false;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
// Make sure we receive overlap events
|
||||
Monitoring = true;
|
||||
Monitorable = true;
|
||||
}
|
||||
|
||||
public void Despawn()
|
||||
{
|
||||
IsCaptured = true;
|
||||
QueueFree();
|
||||
}
|
||||
}
|
||||
1
scripts/world/Creature.cs.uid
Normal file
1
scripts/world/Creature.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://it4jgvdqmkvr
|
||||
52
scripts/world/PlayerInteractor.cs
Normal file
52
scripts/world/PlayerInteractor.cs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public partial class PlayerInteractor : Area2D
|
||||
{
|
||||
private readonly List<Creature> _nearbyCreatures = new();
|
||||
private GameRoot _gameRoot = null!;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
AreaEntered += OnAreaEntered;
|
||||
AreaExited += OnAreaExited;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (!Input.IsActionJustPressed("interact"))
|
||||
return;
|
||||
|
||||
var creature = GetClosestCreature();
|
||||
if (creature == null) return;
|
||||
|
||||
// Ask GameRoot to start capture
|
||||
GameRoot.Instance.RequestCapture(creature);
|
||||
}
|
||||
|
||||
private void OnAreaEntered(Area2D area)
|
||||
{
|
||||
if (area is Creature c && !c.IsCaptured)
|
||||
_nearbyCreatures.Add(c);
|
||||
}
|
||||
|
||||
private void OnAreaExited(Area2D area)
|
||||
{
|
||||
if (area is Creature c)
|
||||
_nearbyCreatures.Remove(c);
|
||||
}
|
||||
|
||||
private Creature? GetClosestCreature()
|
||||
{
|
||||
Creature? best = null;
|
||||
float bestDist = float.MaxValue;
|
||||
|
||||
foreach (var c in _nearbyCreatures)
|
||||
{
|
||||
if (!IsInstanceValid(c)) continue;
|
||||
float d = GlobalPosition.DistanceSquaredTo(c.GlobalPosition);
|
||||
if (d < bestDist) { bestDist = d; best = c; }
|
||||
}
|
||||
return best;
|
||||
}
|
||||
}
|
||||
1
scripts/world/PlayerInteractor.cs.uid
Normal file
1
scripts/world/PlayerInteractor.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dtaa141c1wb8e
|
||||
14
scripts/world/RectOutline.cs
Normal file
14
scripts/world/RectOutline.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using Godot;
|
||||
|
||||
public partial class RectOutline : Node2D
|
||||
{
|
||||
[Export] public Vector2 Size = new Vector2(64, 64);
|
||||
|
||||
public override void _Draw()
|
||||
{
|
||||
// Draw an outline only (transparent fill)
|
||||
DrawRect(new Rect2(Vector2.Zero, Size), new Color(0.6f, 0.6f, 0.6f, 0.9f), filled: false, width: 2f);
|
||||
}
|
||||
|
||||
public override void _Ready() => QueueRedraw();
|
||||
}
|
||||
1
scripts/world/RectOutline.cs.uid
Normal file
1
scripts/world/RectOutline.cs.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bvfgl0jt8ked7
|
||||
39
ui/CaptureUI.tscn
Normal file
39
ui/CaptureUI.tscn
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
[gd_scene format=3 uid="uid://bffdg1ki45e4e"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cg3q7gxpffte" path="res://scripts/ui/CaptureUI.cs" id="1_yh5tq"]
|
||||
|
||||
[node name="CaptureUi" type="CanvasLayer" unique_id=1650401906]
|
||||
script = ExtResource("1_yh5tq")
|
||||
|
||||
[node name="Panel" type="Panel" parent="." unique_id=408425947]
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -20.0
|
||||
offset_top = -20.0
|
||||
offset_right = 20.0
|
||||
offset_bottom = 20.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="Panel" unique_id=1359653087]
|
||||
layout_mode = 0
|
||||
offset_right = 40.0
|
||||
offset_bottom = 40.0
|
||||
|
||||
[node name="CreatureNameLabel" type="Label" parent="Panel/VBoxContainer" unique_id=1713970266]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SoulballOption" type="OptionButton" parent="Panel/VBoxContainer" unique_id=1054549403]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="MashBar" type="ProgressBar" parent="Panel/VBoxContainer" unique_id=1767444517]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TimerLabel" type="Label" parent="Panel/VBoxContainer" unique_id=756325425]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HintLabel" type="Label" parent="Panel/VBoxContainer" unique_id=1785928314]
|
||||
layout_mode = 2
|
||||
Loading…
Add table
Add a link
Reference in a new issue