campfire wip 2

pull/3/head
John Montagu, the 4th Earl of Sandvich 2023-06-10 22:15:28 -07:00
parent 5c8a9cb32b
commit e586ae0e6d
Signed by: sandvich
GPG Key ID: 9A39BE37E602B22D
16 changed files with 275 additions and 112 deletions

View File

@ -0,0 +1,54 @@
using Godot;
namespace SupaLidlGame.BoundingBoxes;
public partial class InteractionRay : RayCast2D
{
private InteractionTrigger _trigger;
public InteractionTrigger Trigger
{
get => _trigger;
protected set
{
if (_trigger != value)
{
EmitSignal(SignalName.TriggerHit, value);
}
if (_trigger is not null)
{
LastValidTrigger = value;
}
_trigger = value;
}
}
public InteractionTrigger LastValidTrigger { get; set; }
[Signal]
public delegate void TriggerHitEventHandler(InteractionTrigger trigger);
public override void _Ready()
{
}
public override void _PhysicsProcess(double delta)
{
if (IsColliding())
{
var obj = GetCollider();
// if obj is an InteractionTrigger then we signal hit
if (obj is InteractionTrigger trigger)
{
Trigger = trigger;
}
}
else
{
Trigger = null;
}
}
}

View File

@ -5,66 +5,4 @@ namespace SupaLidlGame.BoundingBoxes;
public partial class InteractionReceiver : Area2D public partial class InteractionReceiver : Area2D
{ {
[Signal]
public delegate void TriggerEventHandler(
InteractionTrigger trigger,
InteractionTrigger closestTrigger);
[Signal]
public delegate void ClosestTriggerEventHandler(InteractionTrigger trigger);
private InteractionTrigger _closestTrigger;
private HashSet<InteractionTrigger> _triggers;
public InteractionReceiver()
{
_triggers = new HashSet<InteractionTrigger>();
}
private void UpdateClosestTrigger()
{
float minDist = float.MaxValue;
InteractionTrigger best = null;
foreach (var trigger in _triggers)
{
float dist = trigger.GlobalPosition
.DistanceSquaredTo(GlobalPosition);
if (dist <= minDist)
{
best = trigger;
minDist = dist;
}
}
if (_closestTrigger != best)
{
EmitSignal(SignalName.ClosestTrigger, best);
_closestTrigger = best;
}
}
public void _on_area_entered(Area2D area)
{
if (area is InteractionTrigger trigger)
{
EmitSignal(SignalName.Trigger, _closestTrigger);
}
}
public void _on_area_exited(Area2D area)
{
// update closest trigger
if (area is InteractionTrigger trigger)
{
if (_triggers.Contains(trigger))
{
_triggers.Remove(trigger);
}
UpdateClosestTrigger();
}
GD.PushWarning("Area entered is not an InteractionTrigger.");
}
} }

View File

@ -1,7 +1,24 @@
using Godot; using Godot;
using SupaLidlGame.Characters;
namespace SupaLidlGame.BoundingBoxes; namespace SupaLidlGame.BoundingBoxes;
public partial class InteractionTrigger : Area2D public partial class InteractionTrigger : Area2D
{ {
[Signal]
public delegate void InteractionEventHandler();
[Signal]
public delegate void TargetEventHandler();
[Signal]
public delegate void UntargetEventHandler();
/// <summary>
/// Invokes or triggers an interaction to occur.
/// </summary>
public void InvokeInteraction()
{
EmitSignal(SignalName.Interaction);
}
} }

View File

@ -73,9 +73,17 @@ public partial class Character : CharacterBody2D, IFaction
[Export] [Export]
public CharacterStateMachine StateMachine { get; set; } public CharacterStateMachine StateMachine { get; set; }
[Export]
public BoundingBoxes.Hurtbox Hurtbox { get; set; }
[Export] [Export]
public ushort Faction { get; set; } public ushort Faction { get; set; }
public override void _Ready()
{
Hurtbox.ReceivedDamage += OnReceivedDamage;
}
public override void _Process(double delta) public override void _Process(double delta)
{ {
if (StateMachine != null) if (StateMachine != null)
@ -133,7 +141,7 @@ public partial class Character : CharacterBody2D, IFaction
StunTime += time; StunTime += time;
} }
protected void DrawTarget() protected virtual void DrawTarget()
{ {
Vector2 target = Target; Vector2 target = Target;
float angle = Mathf.Atan2(target.Y, Mathf.Abs(target.X)); float angle = Mathf.Atan2(target.Y, Mathf.Abs(target.X));
@ -173,13 +181,14 @@ public partial class Character : CharacterBody2D, IFaction
} }
} }
public virtual void _on_hurtbox_received_damage( public virtual void OnReceivedDamage(
float damage, float damage,
Character inflictor, Character inflictor,
float knockback, float knockback,
Vector2 knockbackOrigin = default, Vector2 knockbackOrigin = default,
Vector2 knockbackVector = default) Vector2 knockbackVector = default)
{ {
float oldHealth = Health;
Health -= damage; Health -= damage;
// create damage text // create damage text
@ -225,5 +234,19 @@ public partial class Character : CharacterBody2D, IFaction
// very small pitch deviation // very small pitch deviation
sound.At(GlobalPosition).WithPitchDeviation(0.125f).Play(); sound.At(GlobalPosition).WithPitchDeviation(0.125f).Play();
} }
Events.HealthChangedArgs args = new Events.HealthChangedArgs
{
Attacker = inflictor,
OldHealth = oldHealth,
NewHealth = Health,
Damage = damage,
};
EmitSignal(SignalName.Hurt, args);
if (Health <= 0)
{
EmitSignal(SignalName.Death, args);
}
} }
} }

View File

@ -130,7 +130,7 @@ _data = {
"RESET": SubResource("Animation_k6l16") "RESET": SubResource("Animation_k6l16")
} }
[node name="ExampleEnemy" type="CharacterBody2D" node_paths=PackedStringArray("Sprite", "Inventory", "StateMachine")] [node name="ExampleEnemy" type="CharacterBody2D" node_paths=PackedStringArray("Sprite", "Inventory", "StateMachine", "Hurtbox")]
y_sort_enabled = true y_sort_enabled = true
texture_filter = 3 texture_filter = 3
material = SubResource("ShaderMaterial_ms3xg") material = SubResource("ShaderMaterial_ms3xg")
@ -141,6 +141,7 @@ Health = 50.0
Sprite = NodePath("Sprite") Sprite = NodePath("Sprite")
Inventory = NodePath("Inventory") Inventory = NodePath("Inventory")
StateMachine = NodePath("StateMachine") StateMachine = NodePath("StateMachine")
Hurtbox = NodePath("Hurtbox")
Faction = 2 Faction = 2
[node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState", "Character")] [node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState", "Character")]
@ -191,6 +192,4 @@ libraries = {
[node name="HurtSound" type="AudioStreamPlayer2D" parent="."] [node name="HurtSound" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource("10_n1e64") stream = ExtResource("10_n1e64")
[connection signal="ReceivedDamage" from="Hurtbox" to="." method="_on_hurtbox_received_damage"]
[editable path="Hurtbox"] [editable path="Hurtbox"]

View File

@ -1,9 +1,12 @@
using Godot; using Godot;
using GodotUtilities;
using SupaLidlGame.Utils; using SupaLidlGame.Utils;
using SupaLidlGame.BoundingBoxes;
namespace SupaLidlGame.Characters; namespace SupaLidlGame.Characters;
public partial class Player : Character [Scene]
public sealed partial class Player : Character
{ {
private AnimatedSprite2D _sprite; private AnimatedSprite2D _sprite;
private string _spriteAnim; private string _spriteAnim;
@ -11,6 +14,11 @@ public partial class Player : Character
[Export] [Export]
public PlayerCamera Camera { get; set; } public PlayerCamera Camera { get; set; }
[Export]
public Marker2D DirectionMarker { get; private set; }
public InteractionRay InteractionRay { get; private set; }
public string Animation public string Animation
{ {
get => _sprite.Animation; get => _sprite.Animation;
@ -32,11 +40,13 @@ public partial class Player : Character
public override void _Ready() public override void _Ready()
{ {
InteractionRay = GetNode<InteractionRay>("Direction2D/InteractionRay");
_sprite = GetNode<AnimatedSprite2D>("Sprite"); _sprite = GetNode<AnimatedSprite2D>("Sprite");
if (_spriteAnim != default) if (_spriteAnim != default)
{ {
_sprite.Animation = _spriteAnim; _sprite.Animation = _spriteAnim;
} }
base._Ready();
} }
public override void ModifyVelocity() public override void ModifyVelocity()
@ -61,4 +71,12 @@ public partial class Player : Character
GD.Print("died"); GD.Print("died");
//base.Die(); //base.Die();
} }
protected override void DrawTarget()
{
base.DrawTarget();
DirectionMarker.GlobalRotation = DirectionMarker.GlobalPosition
.DirectionTo(GetGlobalMousePosition())
.Angle();
}
} }

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=29 format=3 uid="uid://b2254pup8k161"] [gd_scene load_steps=30 format=3 uid="uid://b2254pup8k161"]
[ext_resource type="Script" path="res://Characters/Player.cs" id="1_flygr"] [ext_resource type="Script" path="res://Characters/Player.cs" id="1_flygr"]
[ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="2_ngsgt"] [ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="2_ngsgt"]
@ -12,6 +12,7 @@
[ext_resource type="Script" path="res://State/Character/PlayerRollState.cs" id="8_fy0v5"] [ext_resource type="Script" path="res://State/Character/PlayerRollState.cs" id="8_fy0v5"]
[ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="9_avyu4"] [ext_resource type="PackedScene" uid="uid://cjgxyhgcyvsv7" path="res://BoundingBoxes/Hurtbox.tscn" id="9_avyu4"]
[ext_resource type="AudioStream" uid="uid://njun3e6v4854" path="res://Assets/Sounds/hurt.wav" id="12_h0x0g"] [ext_resource type="AudioStream" uid="uid://njun3e6v4854" path="res://Assets/Sounds/hurt.wav" id="12_h0x0g"]
[ext_resource type="Script" path="res://BoundingBoxes/InteractionRay.cs" id="13_hs3u1"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_h78y7"]
shader = ExtResource("2_ngsgt") shader = ExtResource("2_ngsgt")
@ -133,19 +134,21 @@ _data = {
"RESET": SubResource("Animation_k6l16") "RESET": SubResource("Animation_k6l16")
} }
[node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("Camera", "Sprite", "Inventory", "StateMachine")] [node name="Player" type="CharacterBody2D" node_paths=PackedStringArray("Camera", "DirectionMarker", "Sprite", "Inventory", "StateMachine", "Hurtbox")]
y_sort_enabled = true y_sort_enabled = true
texture_filter = 3 texture_filter = 3
material = SubResource("ShaderMaterial_h78y7") material = SubResource("ShaderMaterial_h78y7")
position = Vector2(0, -12) position = Vector2(1, -12)
collision_layer = 6 collision_layer = 6
collision_mask = 17 collision_mask = 17
script = ExtResource("1_flygr") script = ExtResource("1_flygr")
Camera = NodePath("Camera2D") Camera = NodePath("Camera2D")
DirectionMarker = NodePath("Direction2D")
Speed = 64.0 Speed = 64.0
Sprite = NodePath("Sprite") Sprite = NodePath("Sprite")
Inventory = NodePath("Inventory") Inventory = NodePath("Inventory")
StateMachine = NodePath("StateMachine") StateMachine = NodePath("StateMachine")
Hurtbox = NodePath("Hurtbox")
Faction = 1 Faction = 1
[node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState", "Character")] [node name="StateMachine" type="Node" parent="." node_paths=PackedStringArray("InitialState", "Character")]
@ -231,6 +234,13 @@ max_distance = 64.0
[node name="AudioListener2D" type="AudioListener2D" parent="."] [node name="AudioListener2D" type="AudioListener2D" parent="."]
current = true current = true
[connection signal="ReceivedDamage" from="Hurtbox" to="." method="_on_hurtbox_received_damage"] [node name="Direction2D" type="Marker2D" parent="."]
position = Vector2(0, 6)
[node name="InteractionRay" type="RayCast2D" parent="Direction2D"]
target_position = Vector2(16, 0)
collision_mask = 64
collide_with_areas = true
script = ExtResource("13_hs3u1")
[editable path="Hurtbox"] [editable path="Hurtbox"]

View File

@ -1,23 +1,35 @@
using Godot; using Godot;
using System; using GodotUtilities;
using SupaLidlGame.BoundingBoxes;
namespace SupaLidlGame.Entities; namespace SupaLidlGame.Entities;
public partial class Campfire : StaticBody2D [Scene]
public partial class Campfire : StaticBody2D, Utils.IInteractive
{ {
private PointLight2D _light; private PointLight2D _light;
public InteractionTrigger InteractionTrigger { get; set; }
[Signal] [Signal]
public delegate void OnCampfireUseEventHandler(); public delegate void UseEventHandler();
public override void _Ready() public override void _Ready()
{ {
InteractionTrigger = GetNode<InteractionTrigger>("InteractionTrigger");
_light = GetNode<PointLight2D>("PointLight2D"); _light = GetNode<PointLight2D>("PointLight2D");
InteractionTrigger.Interaction += () =>
{
// save the player's spawn position to be their position on interaction
EmitSignal(SignalName.Use);
this.GetAncestor<Utils.World>().SetSpawn(GlobalPosition);
};
} }
public override void _Process(double delta) public override void _Process(double delta)
{ {
_light.Energy += (GD.Randf() - 0.5f) * 8 * (float)delta; _light.Energy += (GD.Randf() - 0.5f) * 8 * (float)delta;
_light.Energy = Math.Clamp(_light.Energy, 1.2f, 2.0f); _light.Energy = Mathf.Clamp(_light.Energy, 1.8f, 2f);
} }
} }

View File

@ -1,8 +1,9 @@
[gd_scene load_steps=11 format=3 uid="uid://dhl071rj5wyvx"] [gd_scene load_steps=13 format=3 uid="uid://dhl071rj5wyvx"]
[ext_resource type="Texture2D" uid="uid://yqet0b22i70d" path="res://Assets/Sprites/campfire.png" id="1_7eor7"] [ext_resource type="Texture2D" uid="uid://yqet0b22i70d" path="res://Assets/Sprites/campfire.png" id="1_7eor7"]
[ext_resource type="Script" path="res://Entities/Campfire.cs" id="1_w4gfp"] [ext_resource type="Script" path="res://Entities/Campfire.cs" id="1_w4gfp"]
[ext_resource type="Texture2D" uid="uid://coarr28adgo1u" path="res://Assets/Sprites/Particles/point-light.png" id="3_lm3vq"] [ext_resource type="Texture2D" uid="uid://coarr28adgo1u" path="res://Assets/Sprites/Particles/point-light.png" id="3_lm3vq"]
[ext_resource type="Script" path="res://BoundingBoxes/InteractionTrigger.cs" id="4_h1bqe"]
[sub_resource type="AtlasTexture" id="AtlasTexture_68qj1"] [sub_resource type="AtlasTexture" id="AtlasTexture_68qj1"]
atlas = ExtResource("1_7eor7") atlas = ExtResource("1_7eor7")
@ -55,6 +56,9 @@ animations = [{
[sub_resource type="RectangleShape2D" id="RectangleShape2D_ubam4"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_ubam4"]
size = Vector2(16, 4) size = Vector2(16, 4)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_dfj3a"]
size = Vector2(20, 10)
[node name="Campfire" type="StaticBody2D"] [node name="Campfire" type="StaticBody2D"]
texture_filter = 3 texture_filter = 3
position = Vector2(0, -8) position = Vector2(0, -8)
@ -74,3 +78,12 @@ texture_scale = 0.25
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(0, 6) position = Vector2(0, 6)
shape = SubResource("RectangleShape2D_ubam4") shape = SubResource("RectangleShape2D_ubam4")
[node name="InteractionTrigger" type="Area2D" parent="."]
collision_layer = 64
collision_mask = 0
script = ExtResource("4_h1bqe")
[node name="CollisionShape2D" type="CollisionShape2D" parent="InteractionTrigger"]
position = Vector2(0, 5)
shape = SubResource("RectangleShape2D_dfj3a")

View File

@ -1,5 +1,4 @@
using Godot; using Godot;
using System;
namespace SupaLidlGame.Scenes; namespace SupaLidlGame.Scenes;

View File

@ -1,10 +1,11 @@
[gd_scene load_steps=14 format=3 uid="uid://bxtpv6jqodj4v"] [gd_scene load_steps=15 format=3 uid="uid://bxtpv6jqodj4v"]
[ext_resource type="PackedScene" uid="uid://clwv2owvk6abe" path="res://Scenes/BaseMap.tscn" id="1_vly6f"] [ext_resource type="PackedScene" uid="uid://clwv2owvk6abe" path="res://Scenes/BaseMap.tscn" id="1_vly6f"]
[ext_resource type="Texture2D" uid="uid://dl2h266oa2x31" path="res://Assets/Sprites/night-grass.png" id="2_ote21"] [ext_resource type="Texture2D" uid="uid://dl2h266oa2x31" path="res://Assets/Sprites/night-grass.png" id="2_ote21"]
[ext_resource type="PackedScene" uid="uid://bf55wbq7m1gpp" path="res://Characters/ExampleEnemy.tscn" id="3_hwof6"] [ext_resource type="PackedScene" uid="uid://bf55wbq7m1gpp" path="res://Characters/ExampleEnemy.tscn" id="3_hwof6"]
[ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="4_mwgaq"] [ext_resource type="Shader" path="res://Shaders/Flash.gdshader" id="4_mwgaq"]
[ext_resource type="PackedScene" uid="uid://5nvn1tw56m8e" path="res://Utils/Spawner.tscn" id="4_pi4df"] [ext_resource type="PackedScene" uid="uid://5nvn1tw56m8e" path="res://Utils/Spawner.tscn" id="4_pi4df"]
[ext_resource type="PackedScene" uid="uid://dhl071rj5wyvx" path="res://Entities/Campfire.tscn" id="6_r6kxn"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_dvbe3"] [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_dvbe3"]
texture = ExtResource("2_ote21") texture = ExtResource("2_ote21")
@ -211,31 +212,31 @@ physics_layer_0/collision_mask = 16
physics_layer_1/collision_layer = 1 physics_layer_1/collision_layer = 1
sources/0 = SubResource("TileSetAtlasSource_dvbe3") sources/0 = SubResource("TileSetAtlasSource_dvbe3")
[sub_resource type="ShaderMaterial" id="ShaderMaterial_kq7i3"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_qliqj"]
resource_local_to_scene = true resource_local_to_scene = true
shader = ExtResource("4_mwgaq") shader = ExtResource("4_mwgaq")
shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/color = Quaternion(1, 1, 1, 1)
shader_parameter/intensity = 0.0 shader_parameter/intensity = 0.0
[sub_resource type="ShaderMaterial" id="ShaderMaterial_ck37u"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_xpy5p"]
resource_local_to_scene = true resource_local_to_scene = true
shader = ExtResource("4_mwgaq") shader = ExtResource("4_mwgaq")
shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/color = Quaternion(1, 1, 1, 1)
shader_parameter/intensity = 0.0 shader_parameter/intensity = 0.0
[sub_resource type="ShaderMaterial" id="ShaderMaterial_3i2mi"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_jlmdb"]
resource_local_to_scene = true resource_local_to_scene = true
shader = ExtResource("4_mwgaq") shader = ExtResource("4_mwgaq")
shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/color = Quaternion(1, 1, 1, 1)
shader_parameter/intensity = 0.0 shader_parameter/intensity = 0.0
[sub_resource type="ShaderMaterial" id="ShaderMaterial_trolh"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_pd2a6"]
resource_local_to_scene = true resource_local_to_scene = true
shader = ExtResource("4_mwgaq") shader = ExtResource("4_mwgaq")
shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/color = Quaternion(1, 1, 1, 1)
shader_parameter/intensity = 0.0 shader_parameter/intensity = 0.0
[sub_resource type="ShaderMaterial" id="ShaderMaterial_vuv4g"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_th2v6"]
resource_local_to_scene = true resource_local_to_scene = true
shader = ExtResource("4_mwgaq") shader = ExtResource("4_mwgaq")
shader_parameter/color = Quaternion(1, 1, 1, 1) shader_parameter/color = Quaternion(1, 1, 1, 1)
@ -251,26 +252,32 @@ layer_4/tile_data = PackedInt32Array(1114105, 196608, 3, 1114106, 262144, 3, 111
layer_5/tile_data = PackedInt32Array(786438, 262144, 3, 720899, 262144, 3, 851971, 458752, 3, 196611, 458752, 3, 1835019, 262144, 3, 1835034, 458752, 3) layer_5/tile_data = PackedInt32Array(786438, 262144, 3, 720899, 262144, 3, 851971, 458752, 3, 196611, 458752, 3, 1835019, 262144, 3, 1835034, 458752, 3)
[node name="ExampleEnemy" parent="Entities" index="0" instance=ExtResource("3_hwof6")] [node name="ExampleEnemy" parent="Entities" index="0" instance=ExtResource("3_hwof6")]
material = SubResource("ShaderMaterial_kq7i3") material = SubResource("ShaderMaterial_qliqj")
position = Vector2(169, 115) position = Vector2(169, 115)
[node name="ExampleEnemy2" parent="Entities" index="1" instance=ExtResource("3_hwof6")] [node name="ExampleEnemy2" parent="Entities" index="1" instance=ExtResource("3_hwof6")]
material = SubResource("ShaderMaterial_ck37u") material = SubResource("ShaderMaterial_xpy5p")
position = Vector2(75, 130) position = Vector2(75, 130)
[node name="ExampleEnemy3" parent="Entities" index="2" instance=ExtResource("3_hwof6")] [node name="ExampleEnemy3" parent="Entities" index="2" instance=ExtResource("3_hwof6")]
material = SubResource("ShaderMaterial_3i2mi") material = SubResource("ShaderMaterial_jlmdb")
position = Vector2(140, 177) position = Vector2(140, 177)
[node name="ExampleEnemy4" parent="Entities" index="3" instance=ExtResource("3_hwof6")] [node name="ExampleEnemy4" parent="Entities" index="3" instance=ExtResource("3_hwof6")]
material = SubResource("ShaderMaterial_trolh") material = SubResource("ShaderMaterial_pd2a6")
position = Vector2(14, 159) position = Vector2(14, 159)
[node name="ExampleEnemy5" parent="Entities" index="4" instance=ExtResource("3_hwof6")] [node name="ExampleEnemy5" parent="Entities" index="4" instance=ExtResource("3_hwof6")]
material = SubResource("ShaderMaterial_vuv4g") material = SubResource("ShaderMaterial_th2v6")
position = Vector2(10, 22) position = Vector2(10, 22)
Faction = 1 Faction = 1
[node name="Campfire" parent="Entities" index="5" instance=ExtResource("6_r6kxn")]
position = Vector2(155, -27)
[node name="PointLight2D" parent="Entities/Campfire" index="1"]
color = Color(0.996078, 0.780392, 0.501961, 1)
[node name="Spawner" parent="Spawners" index="0" instance=ExtResource("4_pi4df")] [node name="Spawner" parent="Spawners" index="0" instance=ExtResource("4_pi4df")]
position = Vector2(250, 512) position = Vector2(250, 512)
Character = ExtResource("3_hwof6") Character = ExtResource("3_hwof6")
@ -279,4 +286,5 @@ SpawnTime = 5.0
[node name="CollisionShape2D" parent="Spawners/Spawner/Area2D" index="0"] [node name="CollisionShape2D" parent="Spawners/Spawner/Area2D" index="0"]
shape = SubResource("RectangleShape2D_oods2") shape = SubResource("RectangleShape2D_oods2")
[editable path="Entities/Campfire"]
[editable path="Spawners/Spawner"] [editable path="Spawners/Spawner"]

View File

@ -13,9 +13,10 @@ public abstract partial class PlayerState : CharacterState
public override CharacterState Input(InputEvent @event) public override CharacterState Input(InputEvent @event)
{ {
var inventory = Character.Inventory; var inventory = Character.Inventory;
var player = _player;
if (this is PlayerIdleState or PlayerMoveState && if (this is PlayerIdleState or PlayerMoveState &&
!_player.Inventory.IsUsingItem) !player.Inventory.IsUsingItem)
{ {
if (@event.IsActionPressed("equip_1")) if (@event.IsActionPressed("equip_1"))
{ {
@ -25,6 +26,13 @@ public abstract partial class PlayerState : CharacterState
{ {
inventory.SelectedItem = inventory.GetItemByMap("equip_2"); inventory.SelectedItem = inventory.GetItemByMap("equip_2");
} }
if (@event.IsActionPressed("interact"))
{
// if looking at a trigger then interact with it
GD.Print("interacting");
player.InteractionRay.Trigger?.InvokeInteraction();
}
} }
return base.Input(@event); return base.Input(@event);

View File

@ -3,4 +3,7 @@
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<EnableDynamicLoading>true</EnableDynamicLoading> <EnableDynamicLoading>true</EnableDynamicLoading>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Firebelley.GodotUtilities" Version="4.0.4" />
</ItemGroup>
</Project> </Project>

View File

@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012 # Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SupaLidlGame", "SupaLidlGame.csproj", "{AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SupaLidlGame", "SupaLidlGame.csproj", "{BC071CA6-9462-4CEC-AA20-B0CA618321E5}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -9,11 +9,11 @@ Global
ExportRelease|Any CPU = ExportRelease|Any CPU ExportRelease|Any CPU = ExportRelease|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.Debug|Any CPU.Build.0 = Debug|Any CPU {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.ExportDebug|Any CPU.ActiveCfg = ExportDebug|Any CPU
{AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.ExportDebug|Any CPU.Build.0 = ExportDebug|Any CPU
{AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
{AF3A4D72-D276-44C3-A64F-EAB32D2B9B97}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU {BC071CA6-9462-4CEC-AA20-B0CA618321E5}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

View File

@ -0,0 +1,6 @@
namespace SupaLidlGame.Utils;
public interface IInteractive
{
public BoundingBoxes.InteractionTrigger InteractionTrigger { get; set; }
}

View File

@ -23,7 +23,9 @@ public partial class World : Node2D
private string _currentMapResourcePath; private string _currentMapResourcePath;
private Entities.Campfire _lastCampfire = null; //private Entities.Campfire _lastCampfire = null;
public Vector2 SaveLocation { get; set; }
public string SaveMapKey { get; set; }
private const string PLAYER_PATH = "res://Characters/Player.tscn"; private const string PLAYER_PATH = "res://Characters/Player.tscn";
private PackedScene _playerScene; private PackedScene _playerScene;
@ -47,25 +49,15 @@ public partial class World : Node2D
CurrentPlayer.Death += (Events.HealthChangedArgs args) => CurrentPlayer.Death += (Events.HealthChangedArgs args) =>
{ {
// TODO: respawn the player at the last campfire. // TODO: respawn the player at the last campfire.
SpawnPlayer();
}; };
base._Ready(); base._Ready();
} }
public void LoadScene(PackedScene scene) private void LoadMap(Map map)
{ {
GD.Print("Loading map " + scene.ResourcePath); GD.Print("Loading map " + map.Name);
Map map;
if (_maps.ContainsKey(scene.ResourcePath))
{
map = _maps[scene.ResourcePath];
}
else
{
map = scene.Instantiate<Map>();
_maps.Add(scene.ResourcePath, map);
}
if (CurrentMap is not null) if (CurrentMap is not null)
{ {
@ -86,6 +78,39 @@ public partial class World : Node2D
} }
} }
public void LoadScene(PackedScene scene)
{
Map map;
if (_maps.ContainsKey(scene.ResourcePath))
{
map = _maps[scene.ResourcePath];
}
else
{
map = scene.Instantiate<Map>();
_maps.Add(scene.ResourcePath, map);
}
LoadMap(map);
}
public void LoadScene(string path)
{
Map map;
if (_maps.ContainsKey(path))
{
map = _maps[path];
}
else
{
var scene = ResourceLoader.Load<PackedScene>(path);
map = scene.Instantiate<Map>();
_maps.Add(scene.ResourcePath, map);
}
LoadMap(map);
}
public void CreatePlayer() public void CreatePlayer()
{ {
CurrentPlayer = _playerScene.Instantiate<Player>(); CurrentPlayer = _playerScene.Instantiate<Player>();
@ -152,4 +177,34 @@ public partial class World : Node2D
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }
/// <summary>
/// Sets the player's saved spawn position.
/// </summary>
/// <param name="position">The position to save and spawn the player in</param>
/// <param name="mapKey">
/// The map to spawn the player in. If <see langword="null" />, use the
/// <c>World</c>'s <c>CurrentMap</c>
/// </param>
public void SetSpawn(Vector2 position, string mapKey = null)
{
GD.Print("Set spawn");
if (mapKey is null)
{
mapKey = CurrentMap.SceneFilePath;
SaveLocation = position;
SaveMapKey = mapKey;
}
}
public void SpawnPlayer()
{
// TODO: add max health property
CurrentPlayer.Health = 100;
CurrentPlayer.GlobalPosition = SaveLocation;
if (CurrentMap.SceneFilePath != SaveMapKey)
{
LoadScene(SaveMapKey);
}
}
} }