Skip to content

Commit bd72d34

Browse files
authored
Merge pull request #93 from Project-Funk-Engine/localization
Localization
2 parents 74322c6 + a1b6e02 commit bd72d34

29 files changed

+672
-109
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
.idea/.idea.Funk Engine/.idea/
1212

1313
*.DotSettings.user
14-
export_presets.cfg
14+
export_presets.cfg
15+
*.translation

Funk Engine.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<RootNamespace>FunkEngine</RootNamespace>
88
</PropertyGroup>
99
<ItemGroup>
10-
<Content Include="SaveData\SaveData.json" />
10+
<Content Include="Globals\translations.csv" />
1111
<PackageReference Include="Melanchall.DryWetMidi" Version="7.2.0" />
1212
</ItemGroup>
1313
<Target Name="Husky" BeforeTargets="Restore;CollectPackageReferences" Condition="'$(HUSKY)' != 0">

Globals/BgAudioPlayer.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ public partial class BgAudioPlayer : AudioStreamPlayer
77

88
private void PlayMusic(AudioStream music, float volume)
99
{
10+
ProcessMode = ProcessModeEnum.Always;
1011
if (Playing && music.Equals(Stream))
1112
{
1213
return;

Globals/FunkEngineNameSpace.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ public enum Stages
6363
Quit,
6464
Map,
6565
Controls,
66+
Options,
6667
}
6768

6869
public class MapGrid
@@ -166,7 +167,6 @@ private void CreateCommonChildren(int width, int height)
166167
continue;
167168
if (_map[curPos.X, curPos.Y + 1] == 0)
168169
continue;
169-
GD.Print("Added child on same X.");
170170
room.AddChild(_map[curPos.X, curPos.Y + 1]);
171171
}
172172
}

Globals/Scribe.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public partial class Scribe : Node
2424
),
2525
new Note(
2626
"PlayerBase",
27-
"Basic player note, deals damage to enemy",
27+
"Basic player note, deals damage to enemy.",
2828
GD.Load<Texture2D>("res://Classes/Notes/assets/single_note.png"),
2929
null,
3030
1,
@@ -35,7 +35,7 @@ public partial class Scribe : Node
3535
),
3636
new Note(
3737
"PlayerDouble",
38-
"Basic player note, deals double damage to enemy",
38+
"Basic player note, deals double damage to enemy.",
3939
GD.Load<Texture2D>("res://Classes/Notes/assets/double_note.png"),
4040
null,
4141
1,
@@ -48,7 +48,7 @@ public partial class Scribe : Node
4848
),
4949
new Note(
5050
"PlayerHeal",
51-
"Basic player note, heals player",
51+
"Basic player note, heals player.",
5252
GD.Load<Texture2D>("res://Classes/Notes/assets/heal_note.png"),
5353
null,
5454
1,
@@ -59,7 +59,7 @@ public partial class Scribe : Node
5959
),
6060
new Note(
6161
"PlayerVampire",
62-
"Steals health from enemy",
62+
"Steals health from enemy.",
6363
GD.Load<Texture2D>("res://Classes/Notes/assets/vampire_note.png"),
6464
null,
6565
1,
@@ -71,7 +71,7 @@ public partial class Scribe : Node
7171
),
7272
new Note(
7373
"PlayerQuarter",
74-
"Basic note at a quarter of the cost",
74+
"Basic note at a quarter of the cost.",
7575
GD.Load<Texture2D>("res://Classes/Notes/assets/quarter_note.png"),
7676
null,
7777
1,

Globals/StageProducer.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@ public partial class StageProducer : Node
2525
//TODO: Allow for permanent changes and battle temporary stat changes.
2626
public static PlayerStats PlayerStats;
2727

28+
public override void _EnterTree()
29+
{
30+
InitFromCfg();
31+
}
32+
33+
private void InitFromCfg()
34+
{
35+
OptionsMenu.ChangeVolume(
36+
SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.Volume).As<float>()
37+
);
38+
TranslationServer.SetLocale(
39+
SaveSystem.GetConfigValue(SaveSystem.ConfigSettings.LanguageKey).As<string>()
40+
);
41+
}
42+
2843
public void StartGame()
2944
{
3045
Map.InitMapGrid(MapSize.X, MapSize.Y, 3);
@@ -63,9 +78,6 @@ public void TransitionStage(Stages nextStage, int nextRoomIdx = -1)
6378
Config = MakeConfig(nextStage, nextRoomIdx);
6479
GetTree().ChangeSceneToFile("res://scenes/BattleDirector/test_battle_scene.tscn");
6580
break;
66-
case Stages.Controls:
67-
GetTree().ChangeSceneToFile("res://scenes/Remapping/Remap.tscn");
68-
break;
6981
case Stages.Chest:
7082
Config = MakeConfig(nextStage, nextRoomIdx);
7183
GetTree().ChangeSceneToFile("res://scenes/ChestScene/ChestScene.tscn");

Globals/translations.csv

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
keys,en,cn
2+
TITLE,Midnight Riff,中夜现场
3+
TITLE_START,Start Game,开始游戏
4+
TITLE_QUIT,Quit Game,退出游戏
5+
TITLE_OPTIONS,Options,选项
6+
TITLE_CONTROLS,Change Controls,更改操控
7+
CONTROLS_TITLE_TYPE_WASD,WASD,WASD
8+
CONTROLS_TITLE_TYPE_QWER,QWERT,QWERT
9+
CONTROLS_TITLE_TYPE_ARROW,Arrow,箭头键
10+
CONTROLS_TITLE_SELECTED,Selected,已选择
11+
CONTROLS_WASD_BUTTON,WASD,WASD
12+
CONTROLS_QWER_BUTTON,QWER,QWER
13+
CONTROLS_ARROW_BUTTON,Arrow Keys,箭头键
14+
CONTROLS_RETURN_BUTTON,Return,返回
15+
ESCAPE_MENU_RESUME,Resume,继续
16+
ESCAPE_MENU_QUIT,Quit,退出
17+
ESCAPE_MENU_TITLE,Quit to Title,返回标题
18+
CHEST_ROOM_REWARDS,Rewards!,奖励!
19+
CHEST_ROOM_SKIP,Skip,跳过
20+
CHEST_ROOM_ACCEPT,Accept,接受
21+
BATTLE_ROOM_BEGIN_BUTTON,"Begin Battle [Enter]","开始战斗 [Enter]"
22+
BATTLE_ROOM_PERFECT,Perfect,精准
23+
BATTLE_ROOM_GOOD,Good,良好
24+
BATTLE_ROOM_OK,OK,可以
25+
BATTLE_ROOM_MISS,Miss,错误
26+
BATTLE_ROOM_WIN,"You win!","你获胜了!"
27+
BATTLE_ROOM_LOSE,"Game Over!","游戏结束!"
28+
END_SCREEN_RESTART,Restart,重新开始
29+
BATTLE_ROOM_SKIP_BUTTON,Skip,跳过
30+
BATTLE_ROOM_ACCEPT_BUTTON,Accept,接受
31+
NOTE_ENEMYBASE_NAME,EnemyBase,敌人基地
32+
NOTE_ENEMYBASE_TOOLTIP,"Basic enemy note, deals damage to player.","基础敌人音符,对玩家造成伤害"
33+
NOTE_PLAYERBASE_NAME,PlayerBase,玩家基地
34+
NOTE_PLAYERBASE_TOOLTIP,"Basic player note, deals damage to enemy.","基础玩家音符,对敌人造成伤害"
35+
NOTE_PLAYERDOUBLE_NAME,PlayerDouble,玩家双击
36+
NOTE_PLAYERDOUBLE_TOOLTIP,"Basic player note, deals double damage to enemy.","基础玩家音符,对敌人造成双倍伤害"
37+
NOTE_PLAYERHEAL_NAME,PlayerHeal,玩家治愈
38+
NOTE_PLAYERHEAL_TOOLTIP,"Basic player note, heals player.","基础玩家音符,治愈玩家"
39+
NOTE_PLAYERVAMPIRE_NAME,PlayerVampire,玩家吸血
40+
NOTE_PLAYERVAMPIRE_TOOLTIP,"Steals health from enemy.","从敌人吸取生命值"
41+
NOTE_PLAYERQUARTER_NAME,PlayerQuarter,玩家一分之一
42+
NOTE_PLAYERQUARTER_TOOLTIP,"Basic note at a quarter of the cost.","以四分之一的耗费时间量发出基础音符"
43+
RELIC_BREAKFAST_NAME,Breakfast,早餐
44+
RELIC_BREAKFAST_TOOLTIP,"Increases max hp.",提高最大生命值
45+
RELIC_GOODVIBES_NAME,Good Vibes,良好消息
46+
RELIC_GOODVIBES_TOOLTIP,"Heals the player whenever they place a note.","每开始一个音符时治愈玩家"
47+
RELIC_AUROBOROS_NAME,Auroboros,无尾蛇
48+
RELIC_AUROBOROS_TOOLTIP,"Bigger number, better person. Increases combo multiplier every riff.","进一步增加综合倍数,每次现场提升"
49+
RELIC_COLORBOROS_NAME,Colorboros,彩蛇轮回
50+
RELIC_COLORBOROS_TOOLTIP,"Taste the rainbow. Charges the freestyle bar every riff.","品尝临岛,每次现场充值自由格条"
51+
INVENTORY_TAB_NOTES,Notes,乐谱
52+
INVENTORY_TAB_RELICS,Relics,遗物
53+
OPTIONS_VOLUME_LABEL,Master Volume,最终音量设置
54+
OPTIONS_CONTRAST_LABEL,High Contrast,高对比度模式

Globals/translations.csv.import

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[remap]
2+
3+
importer="csv_translation"
4+
type="Translation"
5+
uid="uid://drjnsd6mqpxqh"
6+
7+
[deps]
8+
9+
files=["res://Globals/translations.en.translation", "res://Globals/translations.cn.translation"]
10+
11+
source_file="res://Globals/translations.csv"
12+
dest_files=["res://Globals/translations.en.translation", "res://Globals/translations.cn.translation"]
13+
14+
[params]
15+
16+
compress=true
17+
delimiter=0

SaveData/SaveData.json

Lines changed: 0 additions & 9 deletions
This file was deleted.

SaveData/SaveSystem.cs

Lines changed: 104 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,127 @@
11
using System.Collections.Generic;
22
using System.IO;
3+
using System.Linq;
34
using System.Text.Json;
45
using Godot;
6+
using FileAccess = Godot.FileAccess;
57

68
// TODO: implement saving
79

810
public static class SaveSystem
911
{
10-
private static string SavePath => "res://SaveData/SaveData.json"; // Update if needed
12+
public static string UserConfigPath = "user://Options.cfg";
13+
private static ConfigFile _curConfigData;
1114

12-
// Loads only the notes section
13-
public static Dictionary<string, int> LoadNotes()
15+
private const float DefaultVolume = 80f;
16+
private const string DefaultInput = "WASD";
17+
private const string DefaultLanguage = "en";
18+
private const bool DefaultHighCon = false;
19+
20+
public enum ConfigSettings
21+
{
22+
Volume,
23+
InputKey,
24+
LanguageKey,
25+
HighContrast,
26+
}
27+
28+
private static void InitConfig()
29+
{
30+
_curConfigData = new ConfigFile();
31+
UpdateConfig(ConfigSettings.Volume, DefaultVolume);
32+
UpdateConfig(ConfigSettings.InputKey, DefaultInput);
33+
UpdateConfig(ConfigSettings.LanguageKey, DefaultLanguage);
34+
UpdateConfig(ConfigSettings.HighContrast, DefaultHighCon);
35+
}
36+
37+
private static void SaveConfig()
38+
{
39+
AssertConfigFile();
40+
_curConfigData.Save(UserConfigPath);
41+
}
42+
43+
public static void UpdateConfig(ConfigSettings setting, Variant value)
1444
{
15-
var saveData = LoadSaveData();
16-
if (saveData != null && saveData.Notes != null)
45+
AssertConfigFile();
46+
switch (setting)
1747
{
18-
return saveData.Notes;
48+
case ConfigSettings.Volume:
49+
_curConfigData.SetValue("Options", "Volume", value);
50+
break;
51+
case ConfigSettings.InputKey:
52+
_curConfigData.SetValue("Options", "InputKey", value);
53+
break;
54+
case ConfigSettings.LanguageKey:
55+
_curConfigData.SetValue("Options", "LanguageKey", value);
56+
break;
57+
case ConfigSettings.HighContrast:
58+
_curConfigData.SetValue("Options", "HighContrast", value);
59+
break;
1960
}
20-
else
61+
SaveConfig();
62+
}
63+
64+
public static void AssertConfigFile()
65+
{
66+
if (_curConfigData == null)
2167
{
22-
return new Dictionary<string, int>();
68+
LoadConfigData();
2369
}
2470
}
2571

2672
// This method loads the entire save data
27-
public static SaveData LoadSaveData()
73+
private static void LoadConfigData()
2874
{
29-
string path = ProjectSettings.GlobalizePath(SavePath);
30-
if (!File.Exists(path))
31-
{
32-
GD.PrintErr("Can't load save game");
33-
return null;
34-
}
75+
_curConfigData = new ConfigFile();
76+
VerifyConfig();
77+
if (_curConfigData.Load(UserConfigPath) == Error.Ok)
78+
return;
79+
GD.Print("No config could be found, creating a new one.");
80+
InitConfig();
81+
SaveConfig();
82+
}
3583

36-
string json = File.ReadAllText(path);
37-
SaveData data = JsonSerializer.Deserialize<SaveData>(json);
38-
return data;
84+
//Really naive approach to verifying config integrity, could I have just changed back to JSON? yes. But I'm a real programmer.
85+
//In theory ConfigFiles should be more stable across any version changes.
86+
private static void VerifyConfig()
87+
{
88+
if (!FileAccess.FileExists(UserConfigPath))
89+
return;
90+
string[] sus = new[]
91+
{
92+
"init",
93+
"object",
94+
"script",
95+
"source",
96+
"extends",
97+
"RefCounted",
98+
"sus",
99+
};
100+
FileAccess file = FileAccess.Open(UserConfigPath, FileAccess.ModeFlags.Read);
101+
if (!sus.Any(s => file.GetAsText().Contains(s)))
102+
return;
103+
file.Close();
104+
InitConfig();
39105
}
40-
}
41106

42-
public class SaveData
43-
{
44-
public string AccountName { get; set; }
45-
public Dictionary<string, int> Notes { get; set; } = new Dictionary<string, int>();
46-
public Dictionary<string, object> Relics { get; set; } = new Dictionary<string, object>();
47-
public Dictionary<string, float> Settings { get; set; } = new Dictionary<string, float>();
107+
public static Variant GetConfigValue(ConfigSettings setting)
108+
{
109+
AssertConfigFile();
110+
switch (setting)
111+
{
112+
case ConfigSettings.Volume:
113+
return _curConfigData.GetValue("Options", "Volume", DefaultVolume);
114+
case ConfigSettings.InputKey:
115+
return _curConfigData.GetValue("Options", "InputKey", DefaultInput);
116+
case ConfigSettings.LanguageKey:
117+
return _curConfigData.GetValue("Options", "LanguageKey", DefaultLanguage);
118+
case ConfigSettings.HighContrast:
119+
return _curConfigData.GetValue("Options", "HighContrast", DefaultHighCon);
120+
default:
121+
GD.PushError(
122+
"SaveSystem.GetConfigValue: Invalid config setting passed. " + setting
123+
);
124+
return float.MinValue;
125+
}
126+
}
48127
}

0 commit comments

Comments
 (0)