1
0
mirror of synced 2024-11-27 17:00:50 +01:00

Add an option to ignore song unlockables for lazy people, minor fix and skin issue (fix softlock)

This commit is contained in:
0auBSQ 2024-10-17 03:01:29 +09:00
parent b3e0ba1f72
commit 223259ecb3
10 changed files with 1741 additions and 1719 deletions

View File

@ -6,7 +6,8 @@
// "Language" should include the name of your language in its native text, as well as its English variant in parentheses.
// i.e. "日本語 (Japanese)"
"Language": "English",
"Language": "English",
"Version": "0.6.0.0",
"Entries": {
// Common
@ -196,6 +197,10 @@
"SETTINGS_TRAINING_JUMPINTERVAL": "Measure Jump Time Interval",
"SETTINGS_TRAINING_JUMPINTERVAL_DESC": "The amount of time in milliseconds needed to\nrepeatedly hit the Left/Right Blue keys in\norder to jump to a bookmarked measure in\nTraining Mode.",
// Settings - Gameplay - Unlockables
"SETTINGS_GAME_IGNORESONGUNLOCKABLES": "Ignore Song Unlockables",
"SETTINGS_GAME_IGNORESONGUNLOCKABLES_DESC": "Make all songs available ignoring SongUnlockables.db3.\nThis does not add unlock entries to Saves.db3.\nUnlock notifications will still appear on results.\n\n<c.#f0ad4e>WARNING\nHaving this option ON invalidates any speedrun.</c>",
// Settings - Broken/Unused/Might Deprecate/Might Update
// Translate these anyways, even if their future is uncertain.
"SETTINGS_SYSTEM_IMAGEPREVIEWBUFFER": "Image Preview Buffer",

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,199 +1,199 @@
import ('System.Drawing')
-- Modal info
local modal_current_type = 0
local modal_current_rarity = 1
local modal_current_player = 1
local modal_current_info = nil
local modal_current_visual = nil
-- Modal graphics
local icon_players = { }
local modal_tx = { }
local modal_tx_coin = nil
local ttk_modal_header = nil
local ttk_modal_body = nil
-- Modal sounds
local modal_sfx = { }
local modal_sfx_coin = nil
-- Fonts
local font_modal_header = nil
local font_modal_body = nil
local font_modal_plate = nil
-- Modal counter
local modal_duration = 2000
local modal_counter = 0
local script_busy = false
-- After the item is revealed, a circle glow or smth like that?
local modal_loopanim_duration = 1000
local modal_loopanim_counter = 0
-- Tmp (until new format)
local modal_asset_id = 0
function isAnimationFinished()
return not script_busy
end
-- modal_asset_informations: Character object, Coin count, Nameplate unlockable whole object, etc... having all the necessary information
-- modal_asset_visual_references: Character textures table, Song preimage (?) or supporting visuals, might be null for some modal types
function registerNewModal(player, rarity, modal_type, modal_asset_informations, modal_asset_visual_references)
local _modal_header = ""
local _modal_body = ""
modal_current_type = modal_type
modal_current_rarity = rarity
modal_current_player = player
modal_current_info = modal_asset_informations
modal_current_visual = modal_asset_visual_references
modal_counter = 0
modal_loopanim_counter = 0
script_busy = true
if modal_type == 0 then
-- Coin
modal_current_rarity = 1
_modal_header = getLocalizedString("MODAL_TITLE_COIN")
_modal_body = getLocalizedString("MODAL_MESSAGE_COIN", tostring(modal_asset_informations), tostring(modal_asset_visual_references)) -- 0: Delta coin, 1: Total coin
debugLog(_modal_body)
modal_sfx_coin:PlayStart()
elseif modal_type == 1 then
-- Character
-- > modal_asset_informations: CCharacter
-- > modal_asset_visual_references: CTexture?
_modal_header = getLocalizedString("MODAL_TITLE_CHARA")
_modal_body = modal_current_info.metadata:tGetName()
elseif modal_type == 2 then
-- Puchichara
-- > modal_asset_informations: CPuchichara
-- > modal_asset_visual_references:
_modal_header = getLocalizedString("MODAL_TITLE_PUCHI")
_modal_body = modal_current_info.metadata:tGetName()
elseif modal_type == 3 then
-- Title
-- > modal_asset_informations: NameplateUnlockable
-- > modal_asset_visual_references: CLuaNamePlateScript
_modal_header = getLocalizedString("MODAL_TITLE_NAMEPLATE")
_modal_body = modal_asset_informations.Value.nameplateInfo.cld:GetString("")
ttk_modal_body = createTitleTextureKey(_modal_body, font_modal_plate, 99999, Color.FromArgb(0,0,0,1), Color.FromArgb(0,0,0,0))
elseif modal_type == 4 then
-- Song
-- > modal_asset_informations: CSongListNode
-- > modal_asset_visual_references: CTexture (Preimage)
_modal_header = getLocalizedString("MODAL_TITLE_SONG")
_modal_body = modal_current_info.ldTitle:GetString("")
end
ttk_modal_header = createTitleTextureKey(_modal_header, font_modal_header, 99999)
if modal_type ~= 3 then
ttk_modal_body = createTitleTextureKey(_modal_body, font_modal_body, 99999)
end
-- Tmp
modal_asset_id = math.max(1, math.min(5, modal_current_rarity))
if modal_type ~= 0 then
modal_sfx[modal_asset_id]:PlayStart()
end
end
function loadAssets()
config = loadConfig("Config.json")
for i = 1, 5 do
icon_players[i] = loadTexture(tostring(i).."P.png")
end
-- Tmp, to change with the new structure later
for i = 0, 4 do
modal_tx[i + 1] = loadTexture(tostring(i)..".png")
modal_sfx[i + 1] = loadSound(tostring(i)..".ogg", "soundeffect")
end
modal_tx_coin = loadTexture("Coin.png")
modal_sfx_coin = loadSound("Coin.ogg", "soundeffect")
font_modal_header = loadFontRenderer(84, "regular")
font_modal_body = loadFontRenderer(84, "regular")
font_modal_plate = loadFontRenderer(16, "regular")
end
function update()
if modal_counter <= modal_duration then
script_busy = true
modal_counter = modal_counter + (1000 * fps.deltaTime)
else
script_busy = false
modal_loopanim_counter = modal_loopanim_counter + (1000 * fps.deltaTime)
if modal_loopanim_counter >= modal_loopanim_duration then
modal_loopanim_counter = 0
end
end
-- Idea: If button press and not finished, directly set modal_counter to modal_duration and cut the appearing animation?
end
function draw()
icon_players[modal_current_player]:t2D_DisplayImage(0, 0)
tx_header = getTextTex(ttk_modal_header, false, false)
if modal_current_type == 0 then
-- Coin
modal_tx_coin:t2D_DisplayImage(0, 0)
tx_header:t2D_DisplayImage_AnchorCenter(960,180)
tx_body = getTextTex(ttk_modal_body, false, false)
tx_body:t2D_DisplayImage_AnchorCenter(960,490)
else
-- Others
modal_tx[modal_asset_id]:t2D_DisplayImage(0, 0)
tx_header:t2D_DisplayImage_AnchorCenter(960,180)
if modal_current_type == 1 then
-- Character
if modal_current_visual ~= nil then
modal_current_visual:t2D_DisplayImage(0,260)
end
tx_body = getTextTex(ttk_modal_body, false, false)
tx_body:t2D_DisplayImage_AnchorCenter(960,390)
elseif modal_current_type == 2 then
-- Puchichara
if modal_current_info.tx ~= nil then
modal_current_info.tx:t2D_DisplayImage_AnchorCenter(960,490)
end
tx_body = getTextTex(ttk_modal_body, false, false)
tx_body:t2D_DisplayImage_AnchorCenter(960,790)
elseif modal_current_type == 3 then
-- Nameplate Title
tx_title = getTextTex(ttk_modal_body, false, false)
modal_current_visual:DrawTitlePlate(960, 490, 255, modal_current_info.Value.nameplateInfo.iType, tx_title, modal_current_rarity, modal_current_info.Key)
elseif modal_current_type == 4 then
-- Song
if modal_current_visual ~= nil then
modal_current_visual:t2D_DisplayImage_AnchorCenter(960,490)
end
tx_body = getTextTex(ttk_modal_body, false, false)
tx_body:t2D_DisplayImage_AnchorCenter(960,790)
else
-- Custom modals for custom unlockables in the future??
tx_body = getTextTex(ttk_modal_body, false, false)
tx_body:t2D_DisplayImage_AnchorCenter(960,490)
end
end
end
import ('System.Drawing')
-- Modal info
local modal_current_type = 0
local modal_current_rarity = 1
local modal_current_player = 1
local modal_current_info = nil
local modal_current_visual = nil
-- Modal graphics
local icon_players = { }
local modal_tx = { }
local modal_tx_coin = nil
local ttk_modal_header = nil
local ttk_modal_body = nil
-- Modal sounds
local modal_sfx = { }
local modal_sfx_coin = nil
-- Fonts
local font_modal_header = nil
local font_modal_body = nil
local font_modal_plate = nil
-- Modal counter
local modal_duration = 2000
local modal_counter = 0
local script_busy = false
-- After the item is revealed, a circle glow or smth like that?
local modal_loopanim_duration = 1000
local modal_loopanim_counter = 0
-- Tmp (until new format)
local modal_asset_id = 0
function isAnimationFinished()
return not script_busy
end
-- modal_asset_informations: Character object, Coin count, Nameplate unlockable whole object, etc... having all the necessary information
-- modal_asset_visual_references: Character textures table, Song preimage (?) or supporting visuals, might be null for some modal types
function registerNewModal(player, rarity, modal_type, modal_asset_informations, modal_asset_visual_references)
local _modal_header = ""
local _modal_body = ""
modal_current_type = modal_type
modal_current_rarity = rarity
modal_current_player = player
modal_current_info = modal_asset_informations
modal_current_visual = modal_asset_visual_references
modal_counter = 0
modal_loopanim_counter = 0
script_busy = true
if modal_type == 0 then
-- Coin
modal_current_rarity = 1
_modal_header = getLocalizedString("MODAL_TITLE_COIN")
_modal_body = getLocalizedString("MODAL_MESSAGE_COIN", tostring(modal_asset_informations), tostring(modal_asset_visual_references)) -- 0: Delta coin, 1: Total coin
debugLog(_modal_body)
modal_sfx_coin:PlayStart()
elseif modal_type == 1 then
-- Character
-- > modal_asset_informations: CCharacter
-- > modal_asset_visual_references: CTexture?
_modal_header = getLocalizedString("MODAL_TITLE_CHARA")
_modal_body = modal_current_info.metadata:tGetName()
elseif modal_type == 2 then
-- Puchichara
-- > modal_asset_informations: CPuchichara
-- > modal_asset_visual_references:
_modal_header = getLocalizedString("MODAL_TITLE_PUCHI")
_modal_body = modal_current_info.metadata:tGetName()
elseif modal_type == 3 then
-- Title
-- > modal_asset_informations: NameplateUnlockable
-- > modal_asset_visual_references: CLuaNamePlateScript
_modal_header = getLocalizedString("MODAL_TITLE_NAMEPLATE")
_modal_body = modal_asset_informations.Value.nameplateInfo.cld:GetString("")
ttk_modal_body = createTitleTextureKey(_modal_body, font_modal_plate, 99999, Color.FromArgb(0,0,0,1), Color.FromArgb(0,0,0,0))
elseif modal_type == 4 then
-- Song
-- > modal_asset_informations: CSongListNode
-- > modal_asset_visual_references: CTexture (Preimage)
_modal_header = getLocalizedString("MODAL_TITLE_SONG")
_modal_body = (modal_current_info ~= nil) and modal_current_info.ldTitle:GetString("") or "??? (Not found)"
end
ttk_modal_header = createTitleTextureKey(_modal_header, font_modal_header, 99999)
if modal_type ~= 3 then
ttk_modal_body = createTitleTextureKey(_modal_body, font_modal_body, 99999)
end
-- Tmp
modal_asset_id = math.max(1, math.min(5, modal_current_rarity + 1))
if modal_type ~= 0 then
modal_sfx[modal_asset_id]:PlayStart()
end
end
function loadAssets()
config = loadConfig("Config.json")
for i = 1, 5 do
icon_players[i] = loadTexture(tostring(i).."P.png")
end
-- Tmp, to change with the new structure later
for i = 0, 4 do
modal_tx[i + 1] = loadTexture(tostring(i)..".png")
modal_sfx[i + 1] = loadSound(tostring(i)..".ogg", "soundeffect")
end
modal_tx_coin = loadTexture("Coin.png")
modal_sfx_coin = loadSound("Coin.ogg", "soundeffect")
font_modal_header = loadFontRenderer(84, "regular")
font_modal_body = loadFontRenderer(84, "regular")
font_modal_plate = loadFontRenderer(16, "regular")
end
function update()
if modal_counter <= modal_duration then
script_busy = true
modal_counter = modal_counter + (1000 * fps.deltaTime)
else
script_busy = false
modal_loopanim_counter = modal_loopanim_counter + (1000 * fps.deltaTime)
if modal_loopanim_counter >= modal_loopanim_duration then
modal_loopanim_counter = 0
end
end
-- Idea: If button press and not finished, directly set modal_counter to modal_duration and cut the appearing animation?
end
function draw()
icon_players[modal_current_player]:t2D_DisplayImage(0, 0)
tx_header = getTextTex(ttk_modal_header, false, false)
if modal_current_type == 0 then
-- Coin
modal_tx_coin:t2D_DisplayImage(0, 0)
tx_header:t2D_DisplayImage_AnchorCenter(960,180)
tx_body = getTextTex(ttk_modal_body, false, false)
tx_body:t2D_DisplayImage_AnchorCenter(960,490)
else
-- Others
modal_tx[modal_asset_id]:t2D_DisplayImage(0, 0)
tx_header:t2D_DisplayImage_AnchorCenter(960,180)
if modal_current_type == 1 then
-- Character
if modal_current_visual ~= nil then
modal_current_visual:t2D_DisplayImage(0,260)
end
tx_body = getTextTex(ttk_modal_body, false, false)
tx_body:t2D_DisplayImage_AnchorCenter(960,390)
elseif modal_current_type == 2 then
-- Puchichara
if modal_current_info.tx ~= nil then
modal_current_info.tx:t2D_DisplayImage_AnchorCenter(960,490)
end
tx_body = getTextTex(ttk_modal_body, false, false)
tx_body:t2D_DisplayImage_AnchorCenter(960,790)
elseif modal_current_type == 3 then
-- Nameplate Title
tx_title = getTextTex(ttk_modal_body, false, false)
modal_current_visual:DrawTitlePlate(960, 490, 255, modal_current_info.Value.nameplateInfo.iType, tx_title, modal_current_rarity, modal_current_info.Key)
elseif modal_current_type == 4 then
-- Song
if modal_current_visual ~= nil then
modal_current_visual:t2D_DisplayImage_AnchorCenter(960,490)
end
tx_body = getTextTex(ttk_modal_body, false, false)
tx_body:t2D_DisplayImage_AnchorCenter(960,790)
else
-- Custom modals for custom unlockables in the future??
tx_body = getTextTex(ttk_modal_body, false, false)
tx_body:t2D_DisplayImage_AnchorCenter(960,490)
end
end
end

View File

@ -1178,6 +1178,7 @@ namespace OpenTaiko {
public bool bDisplayDebugInfo;
public bool bEnableVSync;
public bool bFullScreen;
public bool bIgnoreSongUnlockables;
public int nWindowBaseXPosition; // #30675 2013.02.04 ikanick add
public int nWindowBaseYPosition;
public int nWindowWidth; // #23510 2010.10.31 yyagi add
@ -1658,6 +1659,7 @@ namespace OpenTaiko {
public CConfigIni() {
this.strSongsPath = "Songs" + Path.DirectorySeparatorChar;
this.bFullScreen = false;
this.bIgnoreSongUnlockables = false;
this.bEnableVSync = true;
this.nWindowBaseXPosition = 100; // #30675 2013.02.04 ikanick add
this.nWindowBaseYPosition = 100;
@ -1970,6 +1972,9 @@ namespace OpenTaiko {
sw.WriteLine("; File paths on the Saves folder.");
sw.WriteLine("SaveFileName={0}", String.Join(",", this.sSaveFile));
sw.WriteLine();
sw.WriteLine("; Ignore song unlockables (0: No, 1: Yes)");
sw.WriteLine("IgnoreSongUnlockables={0}", this.bIgnoreSongUnlockables ? 1 : 0);
sw.WriteLine();
#endregion
@ -2728,6 +2733,8 @@ namespace OpenTaiko {
this.sSaveFile[i] = _s[i];
}
}
} else if (str3.Equals("IgnoreSongUnlockables")) {
this.bIgnoreSongUnlockables = CConversion.bONorOFF(str4[0]);
}
#region [ skin関係 ]

View File

@ -14,12 +14,6 @@
_modalQueues[player].Enqueue(mp);
}
public Modal tPopModal(int player) {
if (!tIsQueueEmpty(player))
return _modalQueues[player].Dequeue();
return null;
}
// 1P => 2P => 3P => 4P => 5P
public Modal? tPopModalInOrder() {
for (int i = 0; i < OpenTaiko.ConfigIni.nPlayerCount; i++) {

View File

@ -8,12 +8,12 @@ namespace OpenTaiko {
_fn = @$"{OpenTaiko.strEXEのあるフォルダ}Databases{Path.DirectorySeparatorChar}NameplateUnlockables.db3";
using (var connection = new SqliteConnection(@$"Data Source={_fn}")) {
connection.Open();
// Get existing languages
List<string> _translations = HDatabaseHelpers.GetAvailableLanguage(connection, "translation");
// Get nameplates
connection.Open();
// Get existing languages
List<string> _translations = HDatabaseHelpers.GetAvailableLanguage(connection, "translation");
// Get nameplates
var command = connection.CreateCommand();
command.CommandText =
@$"
@ -62,7 +62,7 @@ namespace OpenTaiko {
foreach (KeyValuePair<Int64, NameplateUnlockable> item in data) {
var _npvKey = (int)item.Key;
if (!_sf.Contains(_npvKey))// !_sf.ContainsKey(_npvKey))
if (!_sf.Contains(_npvKey))// !_sf.ContainsKey(_npvKey))
{
var _fulfilled = item.Value.unlockConditions.tConditionMetWrapper(player, DBUnlockables.CUnlockConditions.EScreen.Internal).Item1;
@ -72,7 +72,7 @@ namespace OpenTaiko {
mq.tAddModal(
new Modal(
Modal.EModalType.Title,
HRarity.tRarityToLangInt(item.Value.rarity),
HRarity.tRarityToModalInt(item.Value.rarity),
item,
OpenTaiko.NamePlate.lcNamePlate
),

View File

@ -3,23 +3,25 @@ using Newtonsoft.Json;
using static OpenTaiko.DBSongUnlockables;
namespace OpenTaiko {
internal class DBSongUnlockables : CSavableT<Dictionary<string, SongUnlockable>> {
internal class DBSongUnlockables : CSavableT<Dictionary<string, SongUnlockable>> {
/* DISPLAYED : Song displayed in song select, only a lock appearing on the side, audio preview plays
* GRAYED : Box grayed, song preview does not play
* GRAYED : Box grayed, song preview does not play
* BLURED : Like grayed, but with a glitch effect on the song title and preimage making it unreadable
* HIDDEN : Song not appears on the song select list until being unlocked
*/
*/
public enum EHiddenIndex {
DISPLAYED = 0,
GRAYED = 1,
HIDDEN = 2
BLURED = 2,
HIDDEN = 3
}
public DBSongUnlockables() {
_fn = @$"{OpenTaiko.strEXEのあるフォルダ}Databases{Path.DirectorySeparatorChar}SongUnlockables.db3";
using (var connection = new SqliteConnection(@$"Data Source={_fn}")) {
connection.Open();
// Get songs info
connection.Open();
// Get songs info
var command = connection.CreateCommand();
command.CommandText =
@$"
@ -92,7 +94,7 @@ namespace OpenTaiko {
}
public bool tIsSongLocked(CSongListNode? song) {
if (song == null) return false;
if (song == null || OpenTaiko.ConfigIni.bIgnoreSongUnlockables) return false;
return !OpenTaiko.SaveFileInstances[OpenTaiko.SaveFile].data.UnlockedSongs.Contains(song.tGetUniqueId())
&& data.ContainsKey(song.tGetUniqueId());
}

File diff suppressed because it is too large Load Diff