mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-03-12 13:13:32 +00:00
Merge pull request #537 from misternebula/translator-text
Translator text
This commit is contained in:
commit
e60cfc2c4f
Binary file not shown.
Binary file not shown.
@ -1,4 +1,5 @@
|
||||
using QSB.Utility;
|
||||
using OWML.Common;
|
||||
using QSB.Utility;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
@ -22,13 +23,19 @@ public static class QSBLocalization
|
||||
foreach (var file in files)
|
||||
{
|
||||
var translation = QSBCore.Helper.Storage.Load<Translation>($"Translations\\{file.Name}", false);
|
||||
|
||||
if (translation == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Error - could not load translation at {Path.Combine(QSBCore.Helper.Manifest.ModFolderPath, $"Translations\\{file.Name}")}", MessageType.Error);
|
||||
}
|
||||
|
||||
_translations.Add(translation);
|
||||
DebugLog.DebugWrite($"- Added translation for language {translation.Language}");
|
||||
}
|
||||
|
||||
if (_translations.Count == 0)
|
||||
{
|
||||
DebugLog.ToConsole($"FATAL - No translation files found!", OWML.Common.MessageType.Fatal);
|
||||
DebugLog.ToConsole("FATAL - No translation files found!", MessageType.Fatal);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ internal class MenuManager : MonoBehaviour, IAddComponentOnStart
|
||||
private const int _titleButtonIndex = 2;
|
||||
private float _connectPopupOpenTime;
|
||||
|
||||
private const string UpdateChangelog = $"QSB Version 0.20.0\r\nThis updates brings better ship syncing (including destruction), more things around the village being synced, and general bug fixes.";
|
||||
private const string UpdateChangelog = $"QSB Version 0.20.0\r\nThis update brings better ship syncing (including destruction), more things around the village being synced, and general bug fixes.";
|
||||
|
||||
private Action<bool> PopupClose;
|
||||
|
||||
|
@ -87,4 +87,5 @@ public partial class PlayerInfo
|
||||
public bool ProbeActive { get; set; }
|
||||
public GameObject RoastingStick { get; set; }
|
||||
public QSBProbeLauncher ProbeLauncherEquipped { get; set; }
|
||||
public bool IsTranslating { get; set; }
|
||||
}
|
||||
|
49
QSB/PlayerBodySetup/Remote/FontReplacer.cs
Normal file
49
QSB/PlayerBodySetup/Remote/FontReplacer.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using QSB.Utility;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.PlayerBodySetup.Remote;
|
||||
|
||||
public static class FontReplacer
|
||||
{
|
||||
public static void ReplaceFonts(GameObject prefab)
|
||||
{
|
||||
var allFonts = Resources.LoadAll<Font>("fonts/english - latin");
|
||||
|
||||
foreach (var monoBehaviour in prefab.GetComponentsInChildren<MonoBehaviour>(true))
|
||||
{
|
||||
var publicFields = monoBehaviour
|
||||
.GetType()
|
||||
.GetFields(BindingFlags.Public | BindingFlags.Instance);
|
||||
var privateSerializedFields = monoBehaviour
|
||||
.GetType()
|
||||
.GetFields(BindingFlags.NonPublic | BindingFlags.Instance)
|
||||
.Where(x => x.IsDefined(typeof(SerializeField)));
|
||||
|
||||
foreach (var field in publicFields.Concat(privateSerializedFields))
|
||||
{
|
||||
if (field.FieldType != typeof(Font))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var existingFont = (Font)field.GetValue(monoBehaviour);
|
||||
if (existingFont == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var fontName = existingFont.name;
|
||||
var replacementFont = allFonts.FirstOrDefault(x => x.name == fontName);
|
||||
if (replacementFont == null)
|
||||
{
|
||||
DebugLog.ToConsole($"Warning - Couldn't find replacement font for {fontName}.", OWML.Common.MessageType.Warning);
|
||||
continue;
|
||||
}
|
||||
|
||||
field.SetValue(monoBehaviour, replacementFont);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ public static class RemotePlayerCreation
|
||||
|
||||
_prefab = QSBCore.NetworkAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/REMOTE_Player_Body.prefab");
|
||||
ShaderReplacer.ReplaceShaders(_prefab);
|
||||
FontReplacer.ReplaceFonts(_prefab);
|
||||
QSBDopplerFixer.AddDopplerFixers(_prefab);
|
||||
return _prefab;
|
||||
}
|
||||
|
@ -74,6 +74,7 @@ public class QSBCore : ModBehaviour
|
||||
{
|
||||
EpicRerouter.ModSide.Interop.Go();
|
||||
|
||||
// no, we cant localize this - languages are loaded after the splash screen
|
||||
UIHelper.ReplaceUI(UITextType.PleaseUseController,
|
||||
"<color=orange>Quantum Space Buddies</color> is best experienced with friends...");
|
||||
}
|
||||
@ -126,6 +127,12 @@ public class QSBCore : ModBehaviour
|
||||
ConversationAssetBundle = Helper.Assets.LoadBundle("AssetBundles/qsb_conversation");
|
||||
DebugAssetBundle = Helper.Assets.LoadBundle("AssetBundles/qsb_debug");
|
||||
|
||||
if (NetworkAssetBundle == null || ConversationAssetBundle == null || DebugAssetBundle == null)
|
||||
{
|
||||
DebugLog.ToConsole($"FATAL - An assetbundle is missing! Re-install mod or contact devs.", MessageType.Fatal);
|
||||
return;
|
||||
}
|
||||
|
||||
QSBPatchManager.Init();
|
||||
DeterministicManager.Init();
|
||||
QSBLocalization.Init();
|
||||
|
@ -186,6 +186,13 @@ public class QSBNetworkManager : NetworkManager, IAddComponentOnStart
|
||||
private static GameObject MakeNewNetworkObject(int assetId, string name, Type networkBehaviourType)
|
||||
{
|
||||
var bundle = QSBCore.Helper.Assets.LoadBundle("AssetBundles/qsb_empty");
|
||||
|
||||
if (bundle == null)
|
||||
{
|
||||
DebugLog.ToConsole($"FATAL - An assetbundle is missing! Re-install mod or contact devs.", MessageType.Fatal);
|
||||
return null;
|
||||
}
|
||||
|
||||
var template = bundle.LoadAsset<GameObject>("Assets/Prefabs/Empty.prefab");
|
||||
bundle.Unload(false);
|
||||
|
||||
|
@ -17,6 +17,7 @@ internal static class ProbeCreator
|
||||
|
||||
_prefab = QSBCore.NetworkAssetBundle.LoadAsset<GameObject>("Assets/Prefabs/REMOTE_Probe_Body.prefab");
|
||||
ShaderReplacer.ReplaceShaders(_prefab);
|
||||
FontReplacer.ReplaceFonts(_prefab);
|
||||
QSBDopplerFixer.AddDopplerFixers(_prefab);
|
||||
return _prefab;
|
||||
}
|
||||
|
19
QSB/Tools/TranslatorTool/Messages/IsTranslatingMessage.cs
Normal file
19
QSB/Tools/TranslatorTool/Messages/IsTranslatingMessage.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.Tools.TranslatorTool.Messages;
|
||||
|
||||
internal class IsTranslatingMessage : QSBMessage<bool>
|
||||
{
|
||||
public IsTranslatingMessage(bool translating) : base(translating) { }
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(From);
|
||||
player.IsTranslating = Data;
|
||||
((QSBNomaiTranslator)player.Translator).UpdateTranslating(Data);
|
||||
}
|
||||
|
||||
public override void OnReceiveLocal()
|
||||
=> QSBPlayerManager.LocalPlayer.IsTranslating = Data;
|
||||
}
|
16
QSB/Tools/TranslatorTool/Messages/TranslatorScrollMessage.cs
Normal file
16
QSB/Tools/TranslatorTool/Messages/TranslatorScrollMessage.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using QSB.Messaging;
|
||||
using QSB.Player;
|
||||
|
||||
namespace QSB.Tools.TranslatorTool.Messages;
|
||||
|
||||
internal class TranslatorScrollMessage : QSBMessage<float>
|
||||
{
|
||||
public TranslatorScrollMessage(float scrollPos) : base(scrollPos) { }
|
||||
|
||||
public override void OnReceiveRemote()
|
||||
{
|
||||
var player = QSBPlayerManager.GetPlayer(From);
|
||||
var translator = (QSBNomaiTranslator)player.Translator;
|
||||
translator.SetScroll(Data);
|
||||
}
|
||||
}
|
212
QSB/Tools/TranslatorTool/Patches/TranslatorPatches.cs
Normal file
212
QSB/Tools/TranslatorTool/Patches/TranslatorPatches.cs
Normal file
@ -0,0 +1,212 @@
|
||||
using HarmonyLib;
|
||||
using QSB.Messaging;
|
||||
using QSB.Patches;
|
||||
using QSB.Tools.TranslatorTool.Messages;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace QSB.Tools.TranslatorTool.Patches;
|
||||
|
||||
internal class TranslatorPatches : QSBPatch
|
||||
{
|
||||
public override QSBPatchTypes Type => QSBPatchTypes.OnClientConnect;
|
||||
|
||||
[HarmonyPatch(typeof(NomaiTranslatorProp), nameof(NomaiTranslatorProp.Update))]
|
||||
public static bool Update(NomaiTranslatorProp __instance)
|
||||
{
|
||||
var targetTranslated = __instance._nomaiTextComponent != null && __instance._nomaiTextComponent.IsTranslated(__instance._currentTextID);
|
||||
var canTranslate = !__instance._isTargetingGhostText && !targetTranslated && __instance._textNodeToDisplay != null;
|
||||
|
||||
__instance._centerTranslatePrompt.SetVisibility(canTranslate && !__instance._hasUsedTranslator);
|
||||
__instance._translatePrompt.SetVisibility(canTranslate && __instance._hasUsedTranslator);
|
||||
if (!__instance._hasUsedTranslator && targetTranslated && Locator.GetPlayerSuit().IsWearingHelmet())
|
||||
{
|
||||
PlayerData.SetPersistentCondition("HAS_USED_TRANSLATOR", true);
|
||||
__instance._hasUsedTranslator = true;
|
||||
}
|
||||
|
||||
__instance.UpdateTimeFreeze(targetTranslated, __instance._nomaiTextComponent);
|
||||
if (__instance._textNodeToDisplay != null && __instance._textNodeToDisplay != __instance._lastTextNodeToDisplay)
|
||||
{
|
||||
__instance.StopTranslating();
|
||||
__instance.SwitchTextNode(__instance._textNodeToDisplay);
|
||||
}
|
||||
|
||||
__instance._lastTextNodeToDisplay = __instance._textNodeToDisplay;
|
||||
if (__instance._isTargetingGhostText)
|
||||
{
|
||||
__instance._textField.text = UITextLibrary.GetString(__instance._isTooCloseToTarget
|
||||
? UITextType.TranslatorTooCloseWarning
|
||||
: UITextType.TranslatorUntranslatableWarning);
|
||||
}
|
||||
else if (__instance._textNodeToDisplay == null)
|
||||
{
|
||||
__instance._textField.text = "";
|
||||
__instance._pageNumberTextField.text = "";
|
||||
__instance.StopTranslating();
|
||||
}
|
||||
else if (__instance._isTooCloseToTarget)
|
||||
{
|
||||
__instance._textField.text = UITextLibrary.GetString(UITextType.TranslatorTooCloseWarning);
|
||||
}
|
||||
else
|
||||
{
|
||||
__instance.DisplayTextNode();
|
||||
}
|
||||
|
||||
__instance._textField.rectTransform.sizeDelta = new Vector2(__instance._textField.rectTransform.sizeDelta.x, __instance._textField.preferredHeight);
|
||||
__instance._scrollRect.content.sizeDelta = new Vector2(__instance._scrollRect.content.sizeDelta.x, __instance._textField.preferredHeight);
|
||||
var num = __instance._textField.fontSize / (__instance._textField.preferredHeight - __instance._scrollRect.viewport.sizeDelta.y);
|
||||
if (OWInput.IsNewlyPressed(InputLibrary.toolOptionUp, InputMode.All))
|
||||
{
|
||||
__instance._scrollRect.verticalNormalizedPosition = Mathf.Clamp01(__instance._scrollRect.verticalNormalizedPosition + num);
|
||||
new TranslatorScrollMessage(__instance._scrollRect.verticalNormalizedPosition).Send();
|
||||
}
|
||||
|
||||
if (OWInput.IsNewlyPressed(InputLibrary.toolOptionDown, InputMode.All))
|
||||
{
|
||||
__instance._scrollRect.verticalNormalizedPosition = Mathf.Clamp01(__instance._scrollRect.verticalNormalizedPosition - num);
|
||||
new TranslatorScrollMessage(__instance._scrollRect.verticalNormalizedPosition).Send();
|
||||
}
|
||||
|
||||
__instance._scrollPrompt.SetVisibility(__instance._textField.preferredHeight > __instance._scrollRect.viewport.sizeDelta.y);
|
||||
var hasPages = __instance._inNomaiAudioVolume
|
||||
&& __instance._nomaiTextComponent != null
|
||||
&& __instance._nomaiTextComponent.IsTranslated(1)
|
||||
&& !__instance._isTranslating
|
||||
&& __instance._nomaiTextComponent.GetNumTextBlocks() > 1;
|
||||
|
||||
var currentPage = __instance._currentTextID;
|
||||
if (hasPages)
|
||||
{
|
||||
var numTextBlocks = __instance._nomaiTextComponent.GetNumTextBlocks();
|
||||
if (OWInput.IsNewlyPressed(InputLibrary.toolOptionLeft, InputMode.All))
|
||||
{
|
||||
currentPage = Mathf.Max(1, __instance._currentTextID - 1);
|
||||
}
|
||||
|
||||
if (OWInput.IsNewlyPressed(InputLibrary.toolOptionRight, InputMode.All))
|
||||
{
|
||||
currentPage = Mathf.Min(numTextBlocks, __instance._currentTextID + 1);
|
||||
}
|
||||
|
||||
if (currentPage != __instance._currentTextID)
|
||||
{
|
||||
__instance._currentTextID = currentPage;
|
||||
if (__instance._nomaiTextComponent != null && __instance._inNomaiAudioVolume)
|
||||
{
|
||||
__instance._textNodeToDisplay = __instance._nomaiTextComponent.GetTextNode(__instance._currentTextID);
|
||||
__instance.SetNomaiAudioArrowEmissions();
|
||||
}
|
||||
}
|
||||
|
||||
if (__instance._pageNumberTextField != null)
|
||||
{
|
||||
__instance._pageNumberStrBuilder.Length = 0;
|
||||
__instance._pageNumberStrBuilder.Append(currentPage);
|
||||
__instance._pageNumberStrBuilder.Append(" / ");
|
||||
__instance._pageNumberStrBuilder.Append(numTextBlocks);
|
||||
if (__instance._pageNumberTextField.text != __instance._pageNumberStrBuilder.ToString())
|
||||
{
|
||||
__instance._pageNumberTextField.text = __instance._pageNumberStrBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (__instance._pageNumberTextField != null && __instance._pageNumberTextField.text != "")
|
||||
{
|
||||
__instance._pageNumberTextField.text = "";
|
||||
}
|
||||
|
||||
__instance._pagePrompt.SetVisibility(hasPages);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[HarmonyPatch(typeof(NomaiTranslatorProp), nameof(NomaiTranslatorProp.DisplayTextNode))]
|
||||
public static bool DisplayTextNode(NomaiTranslatorProp __instance)
|
||||
{
|
||||
if (!__instance._nomaiTextComponent.IsTranslated(__instance._currentTextID))
|
||||
{
|
||||
if (OWInput.IsPressed(InputLibrary.toolActionPrimary, 0f) || (__instance._inNomaiAudioVolume && __instance._currentTextID > 1))
|
||||
{
|
||||
__instance._translationTimeElapsed += Time.deltaTime;
|
||||
if (!__instance._isTranslating)
|
||||
{
|
||||
new IsTranslatingMessage(true).Send();
|
||||
__instance._isTranslating = true;
|
||||
__instance._audioController.PlayTranslateAudio();
|
||||
}
|
||||
}
|
||||
else if (__instance._isTranslating)
|
||||
{
|
||||
new IsTranslatingMessage(false).Send();
|
||||
__instance.StopTranslating();
|
||||
}
|
||||
}
|
||||
else if (__instance._nomaiTextComponent.IsTranslated(__instance._currentTextID))
|
||||
{
|
||||
__instance._translationTimeElapsed += Time.deltaTime;
|
||||
}
|
||||
|
||||
var isDynamic = false;
|
||||
string text;
|
||||
if (__instance._translationTimeElapsed == 0f && !__instance._nomaiTextComponent.IsTranslated(__instance._currentTextID))
|
||||
{
|
||||
text = __instance._inNomaiAudioVolume ? UITextLibrary.GetString(UITextType.TranslatorUntranslatedRecordingWarning) : UITextLibrary.GetString(UITextType.TranslatorUntranslatedWritingWarning);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (__instance._translationTimeElapsed > (float)(__instance._numTranslatedWords + 1) * __instance._perWordTranslationTime && __instance._numTranslatedWords < __instance._listDisplayWords.Count)
|
||||
{
|
||||
__instance._listDisplayWordsByLength[__instance._numTranslatedWords].BeginTranslation(__instance._perWordTranslationTime);
|
||||
__instance._numTranslatedWords++;
|
||||
}
|
||||
|
||||
for (var i = 0; i < __instance._listDisplayWords.Count; i++)
|
||||
{
|
||||
__instance._listDisplayWordsByLength[i].UpdateDisplayText(Time.deltaTime);
|
||||
}
|
||||
|
||||
__instance._strBuilder.Length = 0;
|
||||
var allWordsTranslated = true;
|
||||
for (var j = 0; j < __instance._listDisplayWords.Count; j++)
|
||||
{
|
||||
var translatorWord = __instance._listDisplayWords[j];
|
||||
__instance._strBuilder.Append(translatorWord.DisplayText);
|
||||
if (!translatorWord.IsTranslated())
|
||||
{
|
||||
allWordsTranslated = false;
|
||||
}
|
||||
}
|
||||
|
||||
text = __instance._strBuilder.ToString();
|
||||
if (allWordsTranslated)
|
||||
{
|
||||
__instance.StopTranslating();
|
||||
__instance._nomaiTextComponent.SetAsTranslated(__instance._currentTextID);
|
||||
__instance.SetNomaiAudioArrowEmissions();
|
||||
if (text.Contains("</i>") || text.Contains("</b>") || text.Contains("</u>") || text.Contains("</size>"))
|
||||
{
|
||||
isDynamic = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isDynamic && __instance._textField.font != __instance._dynamicFontInUse)
|
||||
{
|
||||
__instance._textField.font = __instance._dynamicFontInUse;
|
||||
}
|
||||
else if (!isDynamic && __instance._textField.font != __instance._fontInUse)
|
||||
{
|
||||
__instance._textField.font = __instance._fontInUse;
|
||||
}
|
||||
|
||||
__instance._textField.text = text;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace QSB.Tools.TranslatorTool;
|
||||
|
||||
internal class QSBNomaiTranslator : QSBTool
|
||||
public class QSBNomaiTranslator : QSBTool
|
||||
{
|
||||
public static float distToClosestTextCenter = 1f;
|
||||
|
||||
@ -50,6 +50,12 @@ internal class QSBNomaiTranslator : QSBTool
|
||||
_translatorProp.OnFinishUnequipAnimation();
|
||||
}
|
||||
|
||||
public void SetScroll(float scrollPosition)
|
||||
=> _translatorProp.SetScroll(scrollPosition);
|
||||
|
||||
public void UpdateTranslating(bool translating)
|
||||
=> _translatorProp.UpdateTranslating(translating);
|
||||
|
||||
public override void Update()
|
||||
{
|
||||
base.Update();
|
||||
@ -120,10 +126,12 @@ internal class QSBNomaiTranslator : QSBTool
|
||||
if (nomaiTextLine && !nomaiTextLine.IsHidden() && nomaiTextLine.IsActive())
|
||||
{
|
||||
distToClosestTextCenter = Vector3.Distance(raycastHit.point, nomaiTextLine.GetWorldCenter());
|
||||
_translatorProp.SetNomaiText(_currentNomaiText, nomaiTextLine.GetEntryID());
|
||||
_translatorProp.SetNomaiTextLine(nomaiTextLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
_translatorProp.ClearNomaiText();
|
||||
_translatorProp.ClearNomaiTextLine();
|
||||
_lastHighlightedTextLine = null;
|
||||
_lastLineWasTranslated = false;
|
||||
@ -136,6 +144,7 @@ internal class QSBNomaiTranslator : QSBTool
|
||||
if (closestRing)
|
||||
{
|
||||
distToClosestTextCenter = Mathf.Min(num2 * 2f, 1f);
|
||||
_translatorProp.SetNomaiText(_currentNomaiText, closestRing.GetEntryID());
|
||||
_translatorProp.SetNomaiComputerRing(closestRing);
|
||||
}
|
||||
}
|
||||
@ -145,19 +154,32 @@ internal class QSBNomaiTranslator : QSBTool
|
||||
if (closestRing2)
|
||||
{
|
||||
distToClosestTextCenter = Mathf.Min(num3 * 2f, 1f);
|
||||
_translatorProp.SetNomaiText(_currentNomaiText, closestRing2.GetEntryID());
|
||||
_translatorProp.SetNomaiVesselComputerRing(closestRing2);
|
||||
}
|
||||
}
|
||||
else if (_currentNomaiText is GhostWallText ghostWallText)
|
||||
{
|
||||
_translatorProp.SetTargetingGhostText(true);
|
||||
_translatorProp.SetNomaiTextLine(ghostWallText.GetTextLine());
|
||||
}
|
||||
else if (raycastHit.textureCoord2 == Vector2.zero)
|
||||
{
|
||||
_translatorProp.SetNomaiText(this._currentNomaiText);
|
||||
}
|
||||
else
|
||||
{
|
||||
var textID = Mathf.RoundToInt(raycastHit.textureCoord2.x * 10f);
|
||||
_translatorProp.SetNomaiText(this._currentNomaiText, textID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_translatorProp.ClearNomaiText();
|
||||
_translatorProp.ClearNomaiTextLine();
|
||||
_translatorProp.ClearNomaiComputerRing();
|
||||
_translatorProp.ClearNomaiVesselComputerRing();
|
||||
_translatorProp.SetTargetingGhostText(false);
|
||||
}
|
||||
|
||||
_translatorProp.SetTooCloseToTarget(tooCloseToTarget);
|
||||
|
@ -1,4 +1,7 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace QSB.Tools.TranslatorTool;
|
||||
|
||||
@ -10,14 +13,58 @@ internal class QSBNomaiTranslatorProp : MonoBehaviour
|
||||
public GameObject TranslatorProp;
|
||||
public MeshRenderer _leftPageArrowRenderer;
|
||||
public MeshRenderer _rightPageArrowRenderer;
|
||||
public Font _defaultPropFont;
|
||||
public Font _defaultPropFontDynamic;
|
||||
public float _defaultFontSpacing = 0.7f;
|
||||
public Text _textField;
|
||||
public Text _pageNumberTextField;
|
||||
|
||||
private Font _fontInUse;
|
||||
private Font _dynamicFontInUse;
|
||||
private float _fontSpacingInUse;
|
||||
private Color _baseEmissionColor;
|
||||
private float _totalTranslateTime = 0.2f;
|
||||
private float _totalAlreadyTranslatedTime;
|
||||
private float _translationTimeElapsed;
|
||||
private float _perWordTranslationTime;
|
||||
private float _fullTextTranslationTime;
|
||||
private float _equipTime;
|
||||
private string _lastTextNodeToDisplay;
|
||||
private string _textNodeToDisplay;
|
||||
private string _translatedText;
|
||||
private TranslatorWordLengthComparer _lengthComparer;
|
||||
private List<TranslatorWord> _listDisplayWordsByLength;
|
||||
private List<TranslatorWord> _listDisplayWords;
|
||||
private int _numTranslatedWords;
|
||||
private Canvas _canvas;
|
||||
private ScrollRect _scrollRect;
|
||||
private StringBuilder _strBuilder;
|
||||
private StringBuilder _pageNumberStrBuilder;
|
||||
private NomaiText _nomaiTextComponent;
|
||||
private int _currentTextID;
|
||||
private TranslatorTargetBeam _targetBeam;
|
||||
private QSBTranslatorScanBeam[] _scanBeams;
|
||||
private PlayerAudioController _audioController;
|
||||
private ThrusterModel _jetpackModel;
|
||||
private bool _isTooCloseToTarget;
|
||||
private bool _isTargetingGhostText;
|
||||
private bool _isTranslating;
|
||||
private bool _hasUsedTranslator;
|
||||
private bool _isTimeFrozen;
|
||||
private QSBNomaiTranslator _nomaiTranslator;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_nomaiTranslator = base.GetComponentInParent<QSBNomaiTranslator>();
|
||||
this._listDisplayWords = new List<TranslatorWord>(1024);
|
||||
this._listDisplayWordsByLength = new List<TranslatorWord>(1024);
|
||||
this._lengthComparer = new TranslatorWordLengthComparer();
|
||||
this._textNodeToDisplay = null;
|
||||
this._strBuilder = new StringBuilder();
|
||||
this._pageNumberStrBuilder = new StringBuilder();
|
||||
this._canvas = base.transform.GetComponentInChildren<Canvas>();
|
||||
this._scrollRect = base.transform.GetComponentInChildren<ScrollRect>();
|
||||
|
||||
_targetBeam = transform.GetComponentInChildren<TranslatorTargetBeam>();
|
||||
|
||||
if (s_matPropBlock == null)
|
||||
@ -33,18 +80,46 @@ internal class QSBNomaiTranslatorProp : MonoBehaviour
|
||||
}
|
||||
|
||||
TurnOffArrowEmission();
|
||||
|
||||
this._canvas.enabled = false;
|
||||
_scanBeams = transform.GetComponentsInChildren<QSBTranslatorScanBeam>();
|
||||
for (var i = 0; i < _scanBeams.Length; i++)
|
||||
{
|
||||
_scanBeams[i].enabled = false;
|
||||
}
|
||||
|
||||
enabled = false;
|
||||
|
||||
TranslatorProp.SetActive(false);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
this.InitializeFont();
|
||||
TextTranslation.Get().OnLanguageChanged += this.InitializeFont;
|
||||
enabled = false;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
TextTranslation.Get().OnLanguageChanged -= this.InitializeFont;
|
||||
}
|
||||
|
||||
private void InitializeFont()
|
||||
{
|
||||
if (TextTranslation.Get().IsLanguageLatin())
|
||||
{
|
||||
this._fontInUse = this._defaultPropFont;
|
||||
this._dynamicFontInUse = this._defaultPropFontDynamic;
|
||||
this._fontSpacingInUse = this._defaultFontSpacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._fontInUse = TextTranslation.GetFont(false);
|
||||
this._dynamicFontInUse = TextTranslation.GetFont(true);
|
||||
this._fontSpacingInUse = TextTranslation.GetDefaultFontSpacing();
|
||||
}
|
||||
this._textField.font = this._fontInUse;
|
||||
this._textField.lineSpacing = this._fontSpacingInUse;
|
||||
}
|
||||
|
||||
private void TurnOffArrowEmission()
|
||||
{
|
||||
if (_leftPageArrowRenderer != null)
|
||||
@ -74,6 +149,7 @@ internal class QSBNomaiTranslatorProp : MonoBehaviour
|
||||
public void OnEquipTool()
|
||||
{
|
||||
enabled = true;
|
||||
_canvas.enabled = true;
|
||||
if (_targetBeam)
|
||||
{
|
||||
_targetBeam.Activate();
|
||||
@ -106,6 +182,7 @@ internal class QSBNomaiTranslatorProp : MonoBehaviour
|
||||
_scanBeams[i].enabled = false;
|
||||
}
|
||||
|
||||
_canvas.enabled = false;
|
||||
TranslatorProp.SetActive(false);
|
||||
}
|
||||
|
||||
@ -171,6 +248,40 @@ internal class QSBNomaiTranslatorProp : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
public void SetNomaiText(NomaiText text, int textID)
|
||||
{
|
||||
if (_nomaiTextComponent != text || _currentTextID != textID)
|
||||
{
|
||||
_nomaiTextComponent = text;
|
||||
_currentTextID = textID;
|
||||
_textNodeToDisplay = _nomaiTextComponent.GetTextNode(_currentTextID);
|
||||
_scrollRect.verticalNormalizedPosition = 1f;
|
||||
TurnOffArrowEmission();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetNomaiText(NomaiText text)
|
||||
{
|
||||
if (_nomaiTextComponent != text)
|
||||
{
|
||||
_nomaiTextComponent = text;
|
||||
_currentTextID = -1;
|
||||
_textNodeToDisplay = _nomaiTextComponent.GetTextNode(_currentTextID);
|
||||
_scrollRect.verticalNormalizedPosition = 1f;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearNomaiText()
|
||||
{
|
||||
_nomaiTextComponent = null;
|
||||
_textNodeToDisplay = null;
|
||||
}
|
||||
|
||||
public void SetTargetingGhostText(bool isTargetingGhostText)
|
||||
{
|
||||
_isTargetingGhostText = isTargetingGhostText;
|
||||
}
|
||||
|
||||
private void StopTranslating()
|
||||
{
|
||||
if (_isTranslating)
|
||||
@ -178,4 +289,160 @@ internal class QSBNomaiTranslatorProp : MonoBehaviour
|
||||
_isTranslating = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetScroll(float scrollPos)
|
||||
=> _scrollRect.verticalNormalizedPosition = scrollPos;
|
||||
|
||||
public void UpdateTranslating(bool translating)
|
||||
{
|
||||
if (translating)
|
||||
{
|
||||
_isTranslating = true;
|
||||
_audioController.PlayTranslateAudio();
|
||||
}
|
||||
else
|
||||
{
|
||||
StopTranslating();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
var textIsTranslated = _nomaiTextComponent != null && _nomaiTextComponent.IsTranslated(_currentTextID);
|
||||
var flag2 = !_isTargetingGhostText && !textIsTranslated && _textNodeToDisplay != null;
|
||||
if (_textNodeToDisplay != null && _textNodeToDisplay != _lastTextNodeToDisplay)
|
||||
{
|
||||
StopTranslating();
|
||||
SwitchTextNode(_textNodeToDisplay);
|
||||
}
|
||||
|
||||
_lastTextNodeToDisplay = _textNodeToDisplay;
|
||||
if (_isTargetingGhostText)
|
||||
{
|
||||
_textField.text = UITextLibrary.GetString(_isTooCloseToTarget ? UITextType.TranslatorTooCloseWarning : UITextType.TranslatorUntranslatableWarning);
|
||||
}
|
||||
else if (_textNodeToDisplay == null)
|
||||
{
|
||||
_textField.text = "";
|
||||
_pageNumberTextField.text = "";
|
||||
StopTranslating();
|
||||
}
|
||||
else if (_isTooCloseToTarget)
|
||||
{
|
||||
_textField.text = UITextLibrary.GetString(UITextType.TranslatorTooCloseWarning);
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayTextNode();
|
||||
}
|
||||
|
||||
_textField.rectTransform.sizeDelta = new Vector2(_textField.rectTransform.sizeDelta.x, _textField.preferredHeight);
|
||||
_scrollRect.content.sizeDelta = new Vector2(_scrollRect.content.sizeDelta.x, _textField.preferredHeight);
|
||||
|
||||
if (_pageNumberTextField != null && _pageNumberTextField.text != "")
|
||||
{
|
||||
_pageNumberTextField.text = "";
|
||||
}
|
||||
}
|
||||
|
||||
protected void DisplayTextNode()
|
||||
{
|
||||
if (!_nomaiTextComponent.IsTranslated(_currentTextID))
|
||||
{
|
||||
if (_nomaiTranslator.Player.IsTranslating)
|
||||
{
|
||||
_translationTimeElapsed += Time.deltaTime;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_translationTimeElapsed += Time.deltaTime;
|
||||
}
|
||||
|
||||
var flag = false;
|
||||
string text;
|
||||
if (_translationTimeElapsed == 0f && !_nomaiTextComponent.IsTranslated(_currentTextID))
|
||||
{
|
||||
text = UITextLibrary.GetString(UITextType.TranslatorUntranslatedWritingWarning);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_translationTimeElapsed > (float)(_numTranslatedWords + 1) * _perWordTranslationTime && _numTranslatedWords < _listDisplayWords.Count)
|
||||
{
|
||||
_listDisplayWordsByLength[_numTranslatedWords].BeginTranslation(_perWordTranslationTime);
|
||||
_numTranslatedWords++;
|
||||
}
|
||||
|
||||
for (var i = 0; i < _listDisplayWords.Count; i++)
|
||||
{
|
||||
_listDisplayWordsByLength[i].UpdateDisplayText(Time.deltaTime);
|
||||
}
|
||||
|
||||
_strBuilder.Length = 0;
|
||||
var flag2 = true;
|
||||
for (var j = 0; j < _listDisplayWords.Count; j++)
|
||||
{
|
||||
var translatorWord = _listDisplayWords[j];
|
||||
_strBuilder.Append(translatorWord.DisplayText);
|
||||
if (!translatorWord.IsTranslated())
|
||||
{
|
||||
flag2 = false;
|
||||
}
|
||||
}
|
||||
|
||||
text = _strBuilder.ToString();
|
||||
if (flag2)
|
||||
{
|
||||
StopTranslating();
|
||||
_nomaiTextComponent.SetAsTranslated(_currentTextID);
|
||||
if (text.Contains("</i>") || text.Contains("</b>") || text.Contains("</u>") || text.Contains("</size>"))
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (flag && _textField.font != _dynamicFontInUse)
|
||||
{
|
||||
_textField.font = _dynamicFontInUse;
|
||||
}
|
||||
else if (!flag && _textField.font != _fontInUse)
|
||||
{
|
||||
_textField.font = _fontInUse;
|
||||
}
|
||||
|
||||
_textField.text = text;
|
||||
}
|
||||
|
||||
private void SwitchTextNode(string textNode)
|
||||
{
|
||||
_translationTimeElapsed = 0f;
|
||||
_fullTextTranslationTime = _nomaiTextComponent.IsTranslated(_currentTextID) ? _totalAlreadyTranslatedTime : _totalTranslateTime;
|
||||
_translatedText = CleanupText(textNode);
|
||||
_listDisplayWords.Clear();
|
||||
_listDisplayWordsByLength.Clear();
|
||||
var num = 0;
|
||||
while (num >= 0 && num < _translatedText.Length)
|
||||
{
|
||||
var num2 = _translatedText.IndexOf(' ', num);
|
||||
if (num2 == -1)
|
||||
{
|
||||
num2 = _translatedText.Length - 1;
|
||||
}
|
||||
|
||||
var item = new TranslatorWord(_translatedText.Substring(num, num2 + 1 - num), num, num2 + 1, _nomaiTextComponent.IsTranslated(_currentTextID), _fullTextTranslationTime);
|
||||
_listDisplayWords.Add(item);
|
||||
_listDisplayWordsByLength.Add(item);
|
||||
num = num2 + 1;
|
||||
}
|
||||
|
||||
_listDisplayWordsByLength.Sort(_lengthComparer);
|
||||
_numTranslatedWords = 0;
|
||||
_perWordTranslationTime = _fullTextTranslationTime / (float)_listDisplayWords.Count;
|
||||
}
|
||||
|
||||
private string CleanupText(string text)
|
||||
{
|
||||
return text.Trim();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user