From a590aa92095265616f34f6e7edba54bedac80a7d Mon Sep 17 00:00:00 2001 From: HumanoidSandvichDispenser Date: Sat, 1 Jun 2024 15:43:46 -0700 Subject: [PATCH] Add Snus Dealer example vendor NPC --- Characters/NPC.cs | 32 ++++++++++++++++++++++++++++++++ Characters/SnusDealer.tscn | 8 ++++---- Dialogue/snus-dealer.dialogue | 24 ++++++++++++------------ State/Thinker/VendorIdle.cs | 17 +++++++++++++++++ 4 files changed, 65 insertions(+), 16 deletions(-) create mode 100644 State/Thinker/VendorIdle.cs diff --git a/Characters/NPC.cs b/Characters/NPC.cs index 2b438e7..a5806a3 100644 --- a/Characters/NPC.cs +++ b/Characters/NPC.cs @@ -3,6 +3,7 @@ using Godot; using SupaLidlGame.Extensions; using SupaLidlGame.Items; +using SupaLidlGame.Utils; using System; namespace SupaLidlGame.Characters; @@ -127,6 +128,37 @@ public partial class NPC : Character return bestChar; } + /// + /// Finds the best character whose faction aligns with this character's. + /// + public virtual Character FindBestNeutral() + { + float bestScore = float.MaxValue; + Character bestChar = null; + // NOTE: this relies on all Characters being under the Entities node + foreach (Node node in GetParent().GetChildren()) + { + if (node is Character character) + { + bool isFriendly = ((IFaction)this).AlignsWith(character); + if (isFriendly || character.Health <= 0) + { + continue; + } + + float score = 0; + score -= Position.DistanceTo(character.Position); + + if (score < bestScore) + { + bestScore = score; + bestChar = character; + } + } + } + return bestChar; + } + public override void _Process(double delta) { ThinkerStateMachine.Process(delta); diff --git a/Characters/SnusDealer.tscn b/Characters/SnusDealer.tscn index 625e8ea..569eb06 100644 --- a/Characters/SnusDealer.tscn +++ b/Characters/SnusDealer.tscn @@ -4,14 +4,14 @@ [ext_resource type="Script" path="res://State/Character/CharacterStateMachine.cs" id="2_kynkg"] [ext_resource type="Texture2D" uid="uid://bej8thq7ruyty" path="res://Assets/Sprites/Characters/forsen2.png" id="2_s5nik"] [ext_resource type="Script" path="res://State/Character/NPCIdleState.cs" id="3_pcrll"] -[ext_resource type="Script" path="res://State/Thinker/IdleState.cs" id="3_rgc42"] [ext_resource type="Script" path="res://State/Thinker/ThinkerStateMachine.cs" id="4_mo4wj"] +[ext_resource type="Script" path="res://State/Thinker/VendorIdle.cs" id="5_oau5d"] [ext_resource type="PackedScene" uid="uid://dldnp8eunxj3q" path="res://BoundingBoxes/InteractionTrigger.tscn" id="5_sjs24"] [ext_resource type="Script" path="res://Utils/InteractionTriggerDialogue.cs" id="5_yknpw"] [ext_resource type="Resource" uid="uid://c4n7vhoxybu70" path="res://Dialogue/snus-dealer.dialogue" id="6_isvnq"] [ext_resource type="Script" path="res://Items/Inventory.cs" id="7_vip6b"] -[node name="Character" type="CharacterBody2D" node_paths=PackedStringArray("ThinkerStateMachine", "Sprite", "Inventory", "StateMachine")] +[node name="SnusDealer" type="CharacterBody2D" node_paths=PackedStringArray("ThinkerStateMachine", "Sprite", "Inventory", "StateMachine")] script = ExtResource("1_04gcf") ThinkerStateMachine = NodePath("Thinker") Sprite = NodePath("Sprites/Sprite") @@ -32,7 +32,7 @@ script = ExtResource("4_mo4wj") InitialState = NodePath("Idle") [node name="Idle" type="Node" parent="Thinker" node_paths=PackedStringArray("NPC")] -script = ExtResource("3_rgc42") +script = ExtResource("5_oau5d") NPC = NodePath("../..") [node name="Animations" type="Node" parent="."] @@ -64,7 +64,7 @@ position = Vector2(0, -4) script = ExtResource("5_yknpw") InteractionTrigger = NodePath("InteractionTrigger") DialogueResource = ExtResource("6_isvnq") -DialogueTitle = "shop" +DialogueTitle = "start" [node name="InteractionTrigger" parent="Interaction" instance=ExtResource("5_sjs24")] diff --git a/Dialogue/snus-dealer.dialogue b/Dialogue/snus-dealer.dialogue index d70cfe4..8572f45 100644 --- a/Dialogue/snus-dealer.dialogue +++ b/Dialogue/snus-dealer.dialogue @@ -1,23 +1,23 @@ ~ start -Snus Dealer: d - -% => test -% => dont_snus - -=> END - -~ test - -Snus Dealer: asdadsadasd +Snus Dealer: Hey kid, wanna buy some snus? +- Alright. => shop +- No, I don't think so. => END +- Snus? => dont_snus => END ~ dont_snus +Snus Dealer: You know what they say. Snus Dealer: If you don't snus... Snus Dealer: you lose. +- Pepepains + +=> start + +~ shop + +do emit("EnterShop", "res://Items/Shops/SnusDealer.tres") => END - -~ shop \ No newline at end of file diff --git a/State/Thinker/VendorIdle.cs b/State/Thinker/VendorIdle.cs new file mode 100644 index 0000000..d0154f6 --- /dev/null +++ b/State/Thinker/VendorIdle.cs @@ -0,0 +1,17 @@ +using Godot; +using GodotUtilities; + +namespace SupaLidlGame.State.Thinker; + +public partial class VendorIdle : ThinkerState +{ + public override ThinkerState Think() + { + var bestNeutral = NPC.FindBestNeutral(); + if (bestNeutral is not null) + { + NPC.Target = bestNeutral.Position - NPC.Position; + } + return null; + } +}