Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 79 additions & 19 deletions Globals/FunkEngineNameSpace.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FunkEngine.Classes.MidiMaestro;
using Godot;
Expand Down Expand Up @@ -251,6 +252,13 @@ public enum Stages
Quit,
Map,
Load,
Continue,
}

public enum Area
{
Forest = 0,
City = 1,
}

public enum Rarity
Expand Down Expand Up @@ -308,59 +316,111 @@ public void AddChild(int newIdx)
}
}

//TODO: Make odds for rooms based on y-level, e.g. elites only spawn on y > 3
public struct MapConfig
{
public int Width { get; private set; }
public int Height { get; private set; }
public int Paths { get; private set; }

/// <summary>
/// Rooms that exist at set levels, only one room can be set per y-level.
/// </summary>
public Dictionary<int, Stages> SetRooms { get; private set; } =
new()
{
{ 0, Stages.Battle }, //The first, e.g. y = 0 room, should always be a battle.
};

public const int NumStages = 2;

public static readonly Stages[] StagsToRoll = new[] { Stages.Battle, Stages.Chest };

/// <summary>
/// The odds for each stage to appear in a non-set room position.
/// </summary>
public float[] StageOdds = new float[2];

public MapConfig(int width, int height, int paths, float[] odds)
{
Width = width;
Height = height;
Paths = paths;
for (int i = 0; i < NumStages; i++)
{
StageOdds[i] = odds[i];
}
}

/// <summary>
/// Adds a set room type to be generated guaranteed. Additional entries in the same y-level are ignored.
/// </summary>
/// <param name="height">The y-level of the rooms</param>
/// <param name="roomType">The room type to be set.</param>
public MapConfig AddSetRoom(int height, Stages roomType)
{
SetRooms.TryAdd(height, roomType);
return this;
}
}

/**
* <summary>Initializes the map with max <c>width</c>, max <c>height</c>, and with number of <c>paths</c>.</summary>
*/
public void InitMapGrid(int width, int height, int paths)
public void InitMapGrid(MapConfig curConfig)
{
_curIdx = 0;
_rooms = Array.Empty<Room>();
_map = new int[width, height]; //x,y
_rooms = [];
_map = new int[curConfig.Width, curConfig.Height]; //x,y

int startX = (width / 2);
int startX = (curConfig.Width / 2);
_rooms = _rooms.Append(new Room(_curIdx, startX, 0)).ToArray();
_rooms[0].SetType(Stages.Battle);
_map[startX, 0] = _curIdx++;

for (int i = 0; i < paths; i++)
for (int i = 0; i < curConfig.Paths; i++)
{
GeneratePath_r(startX, 0, width, height);
GeneratePath_r(startX, 0, curConfig);
}
CreateCommonChildren(width, height);
AddBossRoom(width, height);
CreateCommonChildren(curConfig.Width, curConfig.Height);
AddBossRoom(curConfig.Width, curConfig.Height);
}

/**Start at x, y, assume prev room exists. Picks new x pos within +/- 1, attaches recursively*/
private void GeneratePath_r(int x, int y, int width, int height)
private void GeneratePath_r(int x, int y, MapConfig curConfig)
{
int nextX = StageProducer.GlobalRng.RandiRange(
Math.Max(x - 1, 0),
Math.Min(x + 1, width - 1)
Math.Min(x + 1, curConfig.Width - 1)
);
if (_map[nextX, y + 1] == 0)
{
_rooms = _rooms.Append(new Room(_curIdx, nextX, y + 1)).ToArray();
_map[nextX, y + 1] = _curIdx;
_rooms[_map[x, y]].AddChild(_curIdx++);
_rooms[^1].SetType(PickRoomType(x, y));
_rooms[^1].SetType(PickRoomType(x, y, curConfig));
}
else
{
_rooms[_map[x, y]].AddChild(_map[nextX, y + 1]);
}
if (y < height - 2)
if (y < curConfig.Height - 2)
{
GeneratePath_r(nextX, y + 1, width, height);
GeneratePath_r(nextX, y + 1, curConfig);
}
}

private Stages PickRoomType(int x, int y)
private Stages PickRoomType(int x, int y, MapConfig curConfig)
{
if (y % 3 == 0)
return Stages.Chest;
if (StageProducer.GlobalRng.Randf() < .08)
return Stages.Chest;
return Stages.Battle;
//If the y has a set room return it.
if (curConfig.SetRooms.TryGetValue(y, out Stages result))
{
return result;
}

//Random roll for the room type.
int idx = (int)StageProducer.GlobalRng.RandWeighted(curConfig.StageOdds);
return MapConfig.StagsToRoll[idx];
}

//Asserts that if there is a room at the same x, but y+1 they are connected
Expand Down
59 changes: 52 additions & 7 deletions Globals/StageProducer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,28 @@ public partial class StageProducer : Node

public static readonly RandomNumberGenerator GlobalRng = new();

public static Vector2I MapSize { get; } = new(7, 6); //For now, make width an odd number
public static MapGrid Map { get; } = new();
private static readonly MapGrid.MapConfig FirstMapConfig = new MapGrid.MapConfig(
7,
6,
3,
[10, 1]
).AddSetRoom(3, Stages.Chest);

private static readonly MapGrid.MapConfig TestMapConfig = new MapGrid.MapConfig(
10,
10,
5,
[10, 2]
)
.AddSetRoom(3, Stages.Chest)
.AddSetRoom(6, Stages.Chest);

private static readonly MapGrid.MapConfig[] MapConfigs = new[] { FirstMapConfig };

public static MapGrid Map { get; private set; } = new();
private Stages _curStage = Stages.Title;
public static int CurRoom { get; private set; }
public static Area CurArea { get; private set; } = Area.Forest;

private Node _curScene;
private Node _preloadStage;
Expand Down Expand Up @@ -53,12 +71,13 @@ private void InitFromCfg()
private void GenerateMapConsistent()
{
GlobalRng.State = GlobalRng.Seed << 5 / 2; //Fudge seed state, to get consistent maps across new/loaded games
Map.InitMapGrid(MapSize.X, MapSize.Y, 3);
Map.InitMapGrid(MapConfigs[(int)CurArea]);
}

private void StartNewGame()
{
GlobalRng.Randomize();
CurArea = Area.Forest;
GenerateMapConsistent();

PlayerStats = new PlayerStats();
Expand Down Expand Up @@ -112,10 +131,10 @@ public void TransitionFromRoom(int nextRoomIdx)

private Task _loadTask;

/**
* <summary>To be used from Cartographer. Preloads the scene during transition animation.
* This removes the occasionally noticeable load time for the scene change.</summary>
*/
/// <summary>
/// To be used from Cartographer. Preloads the scene during transition animation. This removes the occasionally noticeable load time for the scene change.
/// </summary>
/// <param name="nextRoomIdx">Index of the next room in the map to get the stage from.</param>
public void PreloadScene(int nextRoomIdx)
{
Stages nextStage = Map.GetRooms()[nextRoomIdx].Type;
Expand Down Expand Up @@ -174,6 +193,10 @@ public void TransitionStage(Stages nextStage, int nextRoomIdx = -1)
case Stages.Quit:
GetTree().Quit();
return;
case Stages.Continue:
ProgressAreas();
GetTree().ChangeSceneToFile("res://Scenes/Maps/InBetween.tscn");
break;
default:
GD.PushError($"Error Scene Transition is {nextStage}");
break;
Expand Down Expand Up @@ -227,4 +250,26 @@ public override void _Input(InputEvent @event)
return;
}
}

#region Area Management

/// <summary>
/// There should always be a mapconfig for each area. It's preferable to crash later if there isn't even a placeholder config.
/// </summary>
/// <returns>True if there is another area.</returns>
public static bool IsMoreAreas()
{
return (int)CurArea + 1 < MapConfigs.Length;
}

public void ProgressAreas()
{
CurArea += 1;

Map = new();
GenerateMapConsistent();
CurRoom = Map.GetRooms()[0].Idx;
}

#endregion
}
7 changes: 4 additions & 3 deletions Globals/Translations/Translations.csv
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ CONTROLS_CHOOSE_BUTTON,Choose new button,选择输入按钮
ESCAPE_MENU_RESUME,Resume,继续
ESCAPE_MENU_QUIT,Quit,退出
ESCAPE_MENU_TITLE,Quit to Title,返回标题
INBETWEEN_CONTINUE,Continue,继续
CHEST_ROOM_REWARDS,Reward Selection!,奖励!
CHEST_ROOM_SKIP,Skip,跳过
CHEST_ROOM_ACCEPT,Accept,接受
Expand Down Expand Up @@ -65,15 +66,15 @@ RELIC_COLORBOROS_TOOLTIP,"Taste the rainbow. Charges the freestyle bar every rif
RELIC_CHIPS_NAME,"Chips",薯片
RELIC_CHIPS_TOOLTIP,"Hitting a note deals a bit of damage.","击中音符会造成少量伤害。"
RELIC_PAPERCUT_NAME,Paper Cut,纸割伤
RELIC_PAPERCUT_TOOLTIP,"Deals damage each loop.","每轮造成伤害"
RELIC_PAPERCUT_TOOLTIP,"Deals damage each riff.","每轮造成伤害"
RELIC_ENERGYDRINK_NAME,Energy Drink,"能量饮料"
RELIC_ENERGYDRINK_TOOLTIP,"Take a chance to cool down and sip an energy drink to increase your max energy bar.","碰碰运气,喝一口能量饮料来冷静下来并增加你的最大能量条。"
RELIC_BANDAGE_NAME,Bandage,"绷带"
RELIC_BANDAGE_TOOLTIP,"A clean strip of cloth. Use it after a fight to patch up and feel better.","一块干净的布条,战斗后使用来包扎并恢复一些健康。"
RELIC_MEDKIT_NAME,Medkit,"急救包"
RELIC_MEDKIT_TOOLTIP,"A small kit with medical supplies. Heals you a bit after each loop.","包含一些医疗用品的小包,每次循环后恢复少量生命。"
RELIC_MEDKIT_TOOLTIP,"A small kit with medical supplies. Heals you a bit after each riff.","包含一些医疗用品的小包,每次循环后恢复少量生命。"
RELIC_VINYLRECORD_NAME,Vinyl Record,"黑胶唱片"
RELIC_VINYLRECORD_TOOLTIP,"Right round, right round. All loop effects trigger twice.","把我转起来,把我转起来。所有循环效果触发两次。"
RELIC_VINYLRECORD_TOOLTIP,"Right round, right round. All riff effects trigger twice.","把我转起来,把我转起来。所有循环效果触发两次。"
INVENTORY_TAB_NOTES,Notes,乐谱
INVENTORY_TAB_RELICS,Relics,遗物
OPTIONS_VOLUME_LABEL,Master Volume,最终音量设置
Expand Down
16 changes: 16 additions & 0 deletions Scenes/AreaBasedBackground.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using FunkEngine;
using Godot;

public partial class AreaBasedBackground : TextureRect
{
public override void _Ready()
{
Texture = StageProducer.CurArea switch
{
Area.Forest => GD.Load<Texture2D>("res://SharedAssets/BackGround_Full.png"),
Area.City => GD.Load<Texture2D>("res://icon.svg"),
_ => null,
};
}
}
1 change: 1 addition & 0 deletions Scenes/AreaBasedBackground.cs.uid
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://cp6t6haqyef7o
7 changes: 5 additions & 2 deletions Scenes/BattleDirector/BattleScene.tscn
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
[gd_scene load_steps=11 format=3 uid="uid://b0mrgr7h0ty1y"]
[gd_scene load_steps=12 format=3 uid="uid://b0mrgr7h0ty1y"]

[ext_resource type="Script" uid="uid://bttu0wmy2fp64" path="res://Scenes/BattleDirector/Scripts/BattleDirector.cs" id="1_jmdo1"]
[ext_resource type="Script" uid="uid://pl57giqyhckb" path="res://Scenes/UI/Scripts/MenuModule.cs" id="2_ka0ws"]
[ext_resource type="Script" uid="uid://tg14hkh1n7iv" path="res://Scenes/BattleDirector/Scripts/Conductor.cs" id="3_elcaj"]
[ext_resource type="PackedScene" uid="uid://duhiilcv4tat3" path="res://Scenes/BattleDirector/NotePlacementBar.tscn" id="4_qk7om"]
[ext_resource type="PackedScene" uid="uid://dfevfib11kou1" path="res://Scenes/ChartViewport/ChartViewport.tscn" id="5_r2xh0"]
[ext_resource type="Texture2D" uid="uid://qhwve7fik4do" path="res://SharedAssets/BackGround_Full.png" id="6_0jtpx"]
[ext_resource type="Script" uid="uid://cp6t6haqyef7o" path="res://Scenes/AreaBasedBackground.cs" id="7_6k2qj"]
[ext_resource type="Texture2D" uid="uid://dbjotl0v1ymia" path="res://SharedAssets/BattleFrame1.png" id="7_klvil"]
[ext_resource type="Theme" uid="uid://d37e3tpsbxwak" path="res://Scenes/UI/Assets/GeneralTheme.tres" id="8_62qim"]

Expand All @@ -18,9 +19,10 @@ gradient = SubResource("Gradient_8uy3a")
fill_from = Vector2(1, 0)
fill_to = Vector2(0.738532, 1)

[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("PuppetMarkers", "CD", "CM", "NPB", "Audio", "_focusedButton")]
[node name="ProtoBattleDirector" type="Node2D" node_paths=PackedStringArray("BackgroundRect", "PuppetMarkers", "CD", "CM", "NPB", "Audio", "_focusedButton")]
process_mode = 1
script = ExtResource("1_jmdo1")
BackgroundRect = NodePath("BackGround")
PuppetMarkers = [NodePath("PlayerMarker"), NodePath("Enemy1Marker"), NodePath("Enemy2Marker"), NodePath("Enemy3Marker")]
CD = NodePath("Conductor")
CM = NodePath("SubViewport")
Expand Down Expand Up @@ -73,6 +75,7 @@ z_index = -1
offset_right = 640.0
offset_bottom = 178.0
texture = ExtResource("6_0jtpx")
script = ExtResource("7_6k2qj")

[node name="BattleFrame" type="TextureRect" parent="."]
z_index = 1
Expand Down
7 changes: 5 additions & 2 deletions Scenes/ChestScene/ChestScene.tscn
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
[gd_scene load_steps=10 format=3 uid="uid://c4vmb783d3v03"]
[gd_scene load_steps=11 format=3 uid="uid://c4vmb783d3v03"]

[ext_resource type="Script" uid="uid://cetn71kolbrmg" path="res://Scenes/ChestScene/ChestScene.cs" id="1_ardd2"]
[ext_resource type="AudioStream" uid="uid://be5ial13ynf3o" path="res://Audio/Song1.ogg" id="2_x78jo"]
[ext_resource type="Script" uid="uid://pl57giqyhckb" path="res://Scenes/UI/Scripts/MenuModule.cs" id="3_5uvci"]
[ext_resource type="Script" uid="uid://cp6t6haqyef7o" path="res://Scenes/AreaBasedBackground.cs" id="5_u0wcg"]
[ext_resource type="Shader" uid="uid://dp36iuuy414k1" path="res://SharedAssets/StarryNight.gdshader" id="5_whthd"]
[ext_resource type="Texture2D" uid="uid://qhwve7fik4do" path="res://SharedAssets/BackGround_Full.png" id="6_37nar"]
[ext_resource type="Texture2D" uid="uid://d0ywqw1j1k71v" path="res://Scenes/ChestScene/Assets/Chest.png" id="6_58hf4"]
Expand All @@ -16,11 +17,12 @@ shader_parameter/bg_bottom_color = Vector4(0.028, 0.008, 0.184, 0)
shader_parameter/gradient_ratio = 1.0
shader_parameter/time_scale = 1.0

[node name="ChestScene" type="Node2D" node_paths=PackedStringArray("ChestButton", "PlayerMarker")]
[node name="ChestScene" type="Node2D" node_paths=PackedStringArray("ChestButton", "PlayerMarker", "BackgroundRect")]
process_mode = 1
script = ExtResource("1_ardd2")
ChestButton = NodePath("CenterContainer/VBoxContainer/ChestButton")
PlayerMarker = NodePath("PlayerMarker")
BackgroundRect = NodePath("BackGround")

[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="."]
stream = ExtResource("2_x78jo")
Expand All @@ -38,6 +40,7 @@ z_index = -1
offset_right = 640.0
offset_bottom = 178.0
texture = ExtResource("6_37nar")
script = ExtResource("5_u0wcg")

[node name="BattleFrame" type="TextureRect" parent="."]
z_index = 1
Expand Down
Loading