Teleport enemy to random room item

This commit is contained in:
2025-03-02 11:55:19 -08:00
parent 2439791d05
commit 05295f535a
20 changed files with 166 additions and 59 deletions

View File

@@ -11,7 +11,7 @@ config_version=5
[application]
config/name="GameJamDungeon"
run/main_scene="uid://bc1sp6xwe0j65"
run/main_scene="uid://d1gjaijijd5ot"
run/print_header=false
config/features=PackedStringArray("4.4", "C#", "GL Compatibility")
boot_splash/show_image=false

View File

@@ -165,7 +165,13 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
public void StopAttackTimer()
{
_attackTimer.Timeout -= OnAttackTimeout;
}
public Vector3 EnemyGlobalPosition => GlobalPosition;
public void SetEnemyGlobalPosition(Vector3 target)
{
GlobalPosition = target;
}
private void OnAttackTimeout()

View File

@@ -19,4 +19,6 @@ public interface IEnemy : IKillable
public void StopAttackTimer();
public abstract void SetTarget(Vector3 target);
public void SetEnemyGlobalPosition(Vector3 target);
}

View File

@@ -1054,6 +1054,36 @@ tracks/3/keys = {
"values": [false, true, false]
}
[sub_resource type="Animation" id="Animation_hr7xb"]
resource_name = "idle_left"
length = 0.0833417
loop_mode = 1
step = 0.0833333
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Sprite3D/SubViewportContainer/SubViewport/AnimatedSprite:animation")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [&"idle_left"]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Sprite3D/SubViewportContainer/SubViewport/AnimatedSprite:frame")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [0]
}
[sub_resource type="Animation" id="Animation_sodds"]
resource_name = "idle_left_walk"
length = 1.41668
@@ -1276,36 +1306,6 @@ tracks/1/keys = {
"values": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
[sub_resource type="Animation" id="Animation_hr7xb"]
resource_name = "idle_left"
length = 0.0833417
loop_mode = 1
step = 0.0833333
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Sprite3D/SubViewportContainer/SubViewport/AnimatedSprite:animation")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [&"idle_left"]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Sprite3D/SubViewportContainer/SubViewport/AnimatedSprite:frame")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [0]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_46p8q"]
_data = {
&"RESET": SubResource("Animation_46p8q"),

View File

@@ -5,6 +5,7 @@ using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System;
using System.Collections.Immutable;
[Meta(typeof(IAutoNode))]
public partial class Game : Node3D, IGame
@@ -179,6 +180,8 @@ public partial class Game : Node3D, IGame
InGameUI.PlayerInfoUI.DisplayMessage(message);
}
public IDungeonFloor CurrentFloor => Map.CurrentFloor;
private void OnEnemyDefeated(Vector3 vector, EnemyStatResource resource)
{
Player.GainExp(resource.ExpFromDefeat * GameRepo.EXPRate);

View File

@@ -11,6 +11,8 @@ public interface IGame : IProvide<IGameRepo>, IProvide<IGameEventDepot>, IProvid
public RescuedItemDatabase RescuedItems { get; }
public IDungeonFloor CurrentFloor { get; }
public void DropItem(IInventoryItem item);
public void ThrowItem(IInventoryItem item);

View File

@@ -3,6 +3,7 @@ using Chickensoft.Introspection;
using Godot;
using System;
using System.Collections.Immutable;
using System.Linq;
namespace GameJamDungeon;
@@ -74,6 +75,33 @@ public partial class ThrowableItem : Node3D, IUsableItem
ChangeAffinity();
}
public void TeleportToRandomRoom(IEnemy enemy)
{
var currentFloor = Game.CurrentFloor;
var rooms = currentFloor.Rooms;
var rng = new RandomNumberGenerator();
rng.Randomize();
var randomRoom = rooms[rng.RandiRange(0, rooms.Count - 1)];
var spawnPoints = randomRoom.EnemySpawnPoints.GetChildren().OfType<Marker3D>().ToList();
var randomSpawnPoint = spawnPoints[rng.RandiRange(0, spawnPoints.Count - 1)];
enemy.SetEnemyGlobalPosition(randomSpawnPoint.GlobalPosition);
}
public void TeleportToRandomRoom(IPlayer player)
{
var currentFloor = Game.CurrentFloor;
var rooms = currentFloor.Rooms;
var rng = new RandomNumberGenerator();
rng.Randomize();
var randomRoom = rooms[rng.RandiRange(0, rooms.Count - 1)];
var spawnPoint = randomRoom.PlayerSpawn;
player.TeleportPlayer(spawnPoint.GlobalPosition);
}
private void ChangeAffinity()
{
var maximumElements = Enum.GetNames(typeof(ElementType)).Length;

View File

@@ -3,7 +3,8 @@
public enum ThrowableItemTag
{
LowerTargetTo1HP,
CanChangeAffinity
CanChangeAffinity,
TeleportToRandomLocation
}
public enum UsableItemTag

View File

@@ -0,0 +1,19 @@
[gd_resource type="Resource" script_class="ThrowableItemStats" load_steps=3 format=3 uid="uid://lo37qfyxlhx1"]
[ext_resource type="Texture2D" uid="uid://cagebvc1lp28y" path="res://src/items/throwable/textures/tablet.PNG" id="1_xt2mp"]
[ext_resource type="Script" uid="uid://d3wlunkcuv2w2" path="res://src/items/throwable/ThrowableItemStats.cs" id="2_m680r"]
[resource]
script = ExtResource("2_m680r")
ThrowableItemTags = Array[int]([2])
ElementType = 0
UsableItemTags = Array[int]([])
Name = "Gospel of Dimension"
Description = "Teleports target to a random location."
Texture = ExtResource("1_xt2mp")
SpawnRate = 0.1
ThrowSpeed = 20.0
HealHPAmount = 0
HealVTAmount = 0
ThrowDamage = 20
ItemTags = Array[int]([])

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cagebvc1lp28y"
path="res://.godot/imported/tablet.PNG-95771620877422607611342ad4de8709.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://src/items/throwable/textures/tablet.PNG"
dest_files=["res://.godot/imported/tablet.PNG-95771620877422607611342ad4de8709.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@@ -1,6 +1,7 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Linq;
namespace GameJamDungeon;
@@ -39,8 +40,20 @@ public partial class ThrownItem : RigidBody3D
{
if (ItemThatIsThrown is ThrowableItem throwableItem)
{
switch (throwableItem.ThrowableItemTags.Single())
{
case ThrowableItemTag.LowerTargetTo1HP:
enemy.TakeDamage(enemy.CurrentHP - 1, ignoreDefense: true, ignoreElementalResistance: true);
break;
case ThrowableItemTag.TeleportToRandomLocation:
throwableItem.TeleportToRandomRoom(enemy);
break;
}
if (throwableItem.ThrowableItemTags.Contains(ThrowableItemTag.LowerTargetTo1HP))
enemy.TakeDamage(enemy.CurrentHP - 1, ignoreDefense: true, ignoreElementalResistance: true);
else if (throwableItem.ThrowableItemTags.Contains(ThrowableItemTag.TeleportToRandomLocation))
//enemy teleport
return;
else
enemy.TakeDamage(throwableItem.ThrowDamage, throwableItem.ElementType);
}

View File

@@ -10,6 +10,8 @@ public interface IMap : INode3D
{
public Godot.Collections.Array<PackedScene> Floors { get; }
public IDungeonFloor CurrentFloor { get; }
public void SpawnNextFloor();
public Transform3D GetPlayerSpawnPosition();
@@ -27,7 +29,7 @@ public partial class Map : Node3D, IMap
[Export]
public Godot.Collections.Array<PackedScene> Floors { get; set; } = default!;
private IDungeonFloor _currentFloor;
public IDungeonFloor CurrentFloor { get; private set; }
public void Setup()
{
@@ -36,14 +38,14 @@ public partial class Map : Node3D, IMap
public void SpawnNextFloor()
{
var oldFloor = _currentFloor;
var oldFloor = CurrentFloor;
oldFloor.CallDeferred(MethodName.QueueFree, []);
LoadFloor();
_currentFloor.InitializeDungeon();
CurrentFloor.InitializeDungeon();
Game.NextFloorLoaded();
}
public Transform3D GetPlayerSpawnPosition() => _currentFloor.GetPlayerSpawnPoint();
public Transform3D GetPlayerSpawnPosition() => CurrentFloor.GetPlayerSpawnPoint();
private void LoadFloor()
{
@@ -51,7 +53,7 @@ public partial class Map : Node3D, IMap
var instantiator = new Instantiator(GetTree());
var loadedScene = instantiator.LoadAndInstantiate<Node3D>(currentFloorScene.ResourcePath);
AddChild(loadedScene);
_currentFloor = (IDungeonFloor)loadedScene;
CurrentFloor = (IDungeonFloor)loadedScene;
Floors.Remove(currentFloorScene);
}
}

View File

@@ -1,6 +1,7 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Immutable;
namespace GameJamDungeon;
@@ -11,6 +12,8 @@ public partial class BossFloor : Node3D, IDungeonFloor
private BossRoomA BossRoom;
public ImmutableList<MonsterRoom> Rooms => [];
public void InitializeDungeon()
{
var bossRoomScene = GD.Load<PackedScene>($"res://src/map/dungeon/scenes/BossRoom.tscn");

View File

@@ -2,6 +2,7 @@ using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
namespace GameJamDungeon
@@ -17,7 +18,7 @@ namespace GameJamDungeon
private Transform3D _playerSpawnPoint;
internal List<MonsterRoom> Rooms { get; private set; }
public ImmutableList<MonsterRoom> Rooms { get; private set; }
public void InitializeDungeon()
{
@@ -43,7 +44,7 @@ namespace GameJamDungeon
return result.GlobalTransform;
}
private static List<MonsterRoom> FindAllDungeonRooms(List<Node> nodesToSearch, List<MonsterRoom> roomsFound)
private static ImmutableList<MonsterRoom> FindAllDungeonRooms(List<Node> nodesToSearch, ImmutableList<MonsterRoom> roomsFound)
{
if (nodesToSearch.Count == 0)
return roomsFound;
@@ -51,7 +52,7 @@ namespace GameJamDungeon
foreach (var node in nodesToSearch)
{
if (node is MonsterRoom dungeonRoom)
roomsFound.Add(dungeonRoom);
roomsFound = roomsFound.Add(dungeonRoom);
if (node.HasSignal("dungeon_done_generating"))
node.EmitSignal("dungeon_done_generating");

View File

@@ -1,6 +1,7 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Immutable;
namespace GameJamDungeon;
@@ -15,6 +16,8 @@ public partial class Floor0 : Node3D, IDungeonFloor, IExitRoom
[Node] private Marker3D PlayerSpawnPoint { get; set; } = default!;
public ImmutableList<MonsterRoom> Rooms => [];
public void Setup()
{
Show();

View File

@@ -1,5 +1,6 @@
using Chickensoft.GodotNodeInterfaces;
using Godot;
using System.Collections.Immutable;
namespace GameJamDungeon;
public interface IDungeonFloor : INode3D
@@ -7,4 +8,6 @@ public interface IDungeonFloor : INode3D
void InitializeDungeon();
public Transform3D GetPlayerSpawnPoint();
public ImmutableList<MonsterRoom> Rooms { get; }
}

View File

@@ -1,6 +1,7 @@
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Collections.Immutable;
namespace GameJamDungeon;
[Meta(typeof(IAutoNode))]
@@ -12,6 +13,8 @@ public partial class Overworld : Node3D, IDungeonFloor
[Node] public Marker3D ExitSpawnPoint { get; set; } = default!;
public ImmutableList<MonsterRoom> Rooms => [];
public void InitializeDungeon()
{
Show();

View File

@@ -16,7 +16,7 @@
[ext_resource type="Texture2D" uid="uid://4k6vtn4oip5f" path="res://src/map/dungeon/models/Set A/02. Altar/02_ALTAR_FLOOR_ZER0_VER_TILE4.png" id="14_qqc7i"]
[ext_resource type="Texture2D" uid="uid://cururtxtgylxf" path="res://src/map/dungeon/models/Set A/02. Altar/02_ALTAR_FLOOR_ZER0_VER_COLUMN.jpg" id="15_ojbcg"]
[ext_resource type="PackedScene" uid="uid://1fl6s352e2ej" path="res://src/items/throwable/ThrowableItem.tscn" id="16_db2o3"]
[ext_resource type="Resource" uid="uid://bph8c6by4s047" path="res://src/items/throwable/resources/GeomanticDice.tres" id="17_ntxe5"]
[ext_resource type="Resource" uid="uid://lo37qfyxlhx1" path="res://src/items/throwable/resources/Gospel of Dimension.tres" id="17_db2o3"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_3ubi4"]
shading_mode = 0
@@ -856,7 +856,7 @@ shape = SubResource("BoxShape3D_xh2ej")
[node name="ThrowableItem" parent="." instance=ExtResource("16_db2o3")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3.469, -2.5, 0)
_throwableItemStats = ExtResource("17_ntxe5")
_throwableItemStats = ExtResource("17_db2o3")
[node name="CSGBox3D" type="CSGBox3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -2.22379, 0)

View File

@@ -1,12 +1,9 @@
[gd_scene load_steps=15 format=3 uid="uid://bc1sp6xwe0j65"]
[gd_scene load_steps=12 format=3 uid="uid://bc1sp6xwe0j65"]
[ext_resource type="Script" uid="uid://dwt6302nsf4vq" path="res://src/map/dungeon/code/DungeonFloor.cs" id="1_0ecnn"]
[ext_resource type="Script" uid="uid://b1x125h0tya2w" path="res://addons/SimpleDungeons/DungeonGenerator3D.gd" id="2_cxmwa"]
[ext_resource type="PackedScene" uid="uid://dpec2lbt83dhe" path="res://src/map/dungeon/rooms/Set A/03. Antechamber A.tscn" id="3_gkkr3"]
[ext_resource type="PackedScene" uid="uid://b82dx66mgs2d7" path="res://src/map/dungeon/rooms/Set A/08. Basin Room.tscn" id="8_5rblf"]
[ext_resource type="PackedScene" uid="uid://cmvimr0pvsgqy" path="res://src/enemy/enemy_types/10. Eden Pillar/Eden Pillar.tscn" id="10_atq1f"]
[ext_resource type="PackedScene" uid="uid://cfecvvav8kkp6" path="res://src/player/Player.tscn" id="11_sdyti"]
[ext_resource type="PackedScene" uid="uid://c6tqt27ql8s35" path="res://src/enemy/enemy_types/07. chinthe/Chinthe.tscn" id="12_1l8yt"]
[ext_resource type="PackedScene" uid="uid://dbvr8ewajja6a" path="res://src/enemy/EnemyDatabase.tscn" id="12_aw26s"]
[ext_resource type="PackedScene" uid="uid://cihbmyo0ltq4m" path="res://src/map/dungeon/rooms/Set A/19. Floor Exit A.tscn" id="12_n02rw"]
[ext_resource type="PackedScene" uid="uid://bksq62muhk3h5" path="res://src/enemy/enemy_types/01. sproingy/Sproingy.tscn" id="13_kwaga"]
@@ -175,16 +172,3 @@ shape = SubResource("BoxShape3D_xw4dv")
[node name="EnemyDatabase" parent="." instance=ExtResource("12_aw26s")]
unique_name_in_owner = true
EnemyList = Array[PackedScene]([ExtResource("13_kwaga"), ExtResource("14_gkkr3")])
[node name="Eden Pillar" parent="." instance=ExtResource("10_atq1f")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -29.7976, -1.33866, 30.3232)
[node name="Player" parent="." instance=ExtResource("11_sdyti")]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.07588, -1.71359, 12.7507)
[node name="Chinthe" parent="." instance=ExtResource("12_1l8yt")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.2934, -0.81355, 21.6535)
PrimaryAttackElementalType = 0
PrimaryAttackElementalDamageBonus = 1.0
_movementSpeed = 2.0