13 Commits

Author SHA1 Message Date
msk 23eac84782 Update README.md 2022-02-23 20:15:16 -08:00
msk 274288e453 Update README.md 2022-02-16 01:37:10 -08:00
msk caa4dae8b3 Update README.md 2022-02-14 15:16:52 -08:00
msk f81069f658 quick fixup 2022-02-14 13:02:43 -08:00
msk a9be72693c hp text customization, shrink hp bg border, hide hp when aiming there 2022-02-14 00:07:51 -08:00
msk 416e49d6d7 README changes 2022-02-13 03:32:30 -08:00
msk 6249f07788 implement stats tilt
encompasses releases 1.1.2 and 1.1.3
2022-02-13 03:17:47 -08:00
msk 640245cdd5 fixed wave counter's lack of font 2022-01-30 14:41:03 -08:00
msk d4c5e84404 1.1.0 release! many new features. 2022-01-30 03:16:24 -08:00
msk 1eb6628a37 many shit (survived an SSD failure, plz push more) 2022-01-28 20:07:51 -08:00
msk fcea383739 win/lose hold stats, hp crystal expiration 2022-01-26 01:23:39 -08:00
msk 6f938e95c8 fix in-play stuff not working in other maps 2022-01-24 03:40:08 -08:00
msk b259424300 stop searching for TNHLBPC after 120s, add option for hp text visibility 2022-01-24 01:48:22 -08:00
51 changed files with 1883 additions and 188 deletions
+2 -2
View File
@@ -13,14 +13,14 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
PackageName: TNH_Quality_of_Life_Improvements PackageName: TNH_Quality_of_Life_Improvements
Author: muskit Author: muskit
Version: 1.0.0 Version: 1.2.1
Icon: {fileID: 2800000, guid: 785b7946398f5314b95bf593d2d77d67, type: 3} Icon: {fileID: 2800000, guid: 785b7946398f5314b95bf593d2d77d67, type: 3}
ReadMe: {fileID: 102900000, guid: ab1d6dea017447a48ac348db588a6f35, type: 3} ReadMe: {fileID: 102900000, guid: ab1d6dea017447a48ac348db588a6f35, type: 3}
WebsiteURL: https://github.com/muskit/TNH-Quality-of-Life-Improvements WebsiteURL: https://github.com/muskit/TNH-Quality-of-Life-Improvements
Description: Quality of life improvements to the Take and Hold experience. Description: Quality of life improvements to the Take and Hold experience.
AdditionalDependencies: AdditionalDependencies:
- BepInEx-BepInExPack_H3VR-5.4.1700 - BepInEx-BepInExPack_H3VR-5.4.1700
StripNamespaces: 1 StripNamespaces: 0
AdditionalNamespaces: AdditionalNamespaces:
- TNHQoLImprovements - TNHQoLImprovements
BuildItems: BuildItems:
+171 -19
View File
@@ -1,10 +1,12 @@
#if H3VR_IMPORTED #if H3VR_IMPORTED
using HarmonyLib;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using BepInEx; using BepInEx;
using BepInEx.Bootstrap; using BepInEx.Bootstrap;
using BepInEx.Configuration; using BepInEx.Configuration;
using UnityEngine; using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement; using UnityEngine.SceneManagement;
using TNHQoLImprovements; using TNHQoLImprovements;
@@ -33,68 +35,212 @@ public class MeatKitPlugin : BaseUnityPlugin
private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); private static readonly string BasePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
#pragma warning restore 414 #pragma warning restore 414
private bool lpcKilled = false;
public static AssetBundle bundle; public static AssetBundle bundle;
public static Font fontAgencyFB;
public static Font fontBombardier;
public static ConfigEntry<bool> showHPBackground; public static GameObject playerCamera;
public static ConfigEntry<float> hpBackgroundOpacity;
public static ConfigEntry<bool> showTokens;
public static ConfigEntry<bool> showHolds;
// BepInEx configuration
//--- Health Counter ---//
public static ConfigEntry<bool> cfgHPHiddenWhenAiming;
public static ConfigEntry<bool> cfgShowHPBackground;
public static ConfigEntry<float> cfgHPBackgroundOpacity;
public static ConfigEntry<HPTextType> cfgHPTextType;
//--- Take and Hold Info ---//
public static ConfigEntry<bool> cfgShowLPC;
public static ConfigEntry<bool> cfgInfoFollowCamera;
public static ConfigEntry<bool> cfgShowTokens;
public static ConfigEntry<bool> cfgShowHolds;
public static ConfigEntry<bool> cfgShowNumbersAtShop;
public static ConfigEntry<bool> cfgShowInfoOnGameOver;
public static ConfigEntry<bool> cfgShowWaves;
//--- Misc. ---//
public static ConfigEntry<HealthExpireIndicationType> cfgHealthCrystalIndicator;
// Take and Hold modifications
private static InPlay instance; private static InPlay instance;
private LeaderboardPlayerCountPatch lpc;
// Searching for old leaderboards player count mod to disable
private bool lpcModGone = false;
private float lpcModSearchTimeEnd;
private Harmony harmony;
private void SceneChanged(Scene from, Scene to) private void SceneChanged(Scene from, Scene to)
{ {
//Logger.LogInfo(string.Format("scene chg: {0} --> {1}", from.name, to.name)); GetFonts();
if(GameObject.Find("_NewTAHReticle") != null) playerCamera = GameObject.FindGameObjectWithTag("MainCamera");
// apply health counter tweaks globally
var healthCounter = FindObjectOfType<FistVR.FVRHealthBar>();
if (healthCounter != null)
{ {
HPReadability.ImproveHPTextReadability(healthCounter.transform.GetChild(0).gameObject);
if (cfgHPHiddenWhenAiming.Value)
healthCounter.gameObject.AddComponent<HPHideWhenAiming>();
}
// TNH patches
if (GameObject.Find("_GameManager") != null || FindObjectOfType<FistVR.TNH_Manager>() != null)
{
Logger.LogInfo("We are in a TNH game!");
instance = new GameObject().AddComponent<InPlay>(); instance = new GameObject().AddComponent<InPlay>();
} }
else else
{ {
Logger.LogInfo("We are NOT in a TNH game!");
Destroy(instance); Destroy(instance);
} }
} }
// called on scene change, find fonts from game if they're not set
private void GetFonts()
{
// Agency FB
if (fontAgencyFB == null)
{
var healthCounter = FindObjectOfType<FistVR.FVRHealthBar>();
if (healthCounter != null)
{
fontAgencyFB = healthCounter.transform.GetChild(0).GetChild(0).GetComponent<Text>().font;
}
else
{
var query = FindObjectsOfType<Text>();
foreach (Text itm in query)
{
if (itm.font.name == "AGENCYR")
{
fontAgencyFB = itm.font;
break;
}
}
}
}
}
public MeatKitPlugin(): base()
{
harmony = new Harmony("muskit.TNHQualityOfLifeImprovements");
}
private void Awake() private void Awake()
{ {
// MeatKit requirement
LoadAssets();
// get Agency FB from system (BAD IDEA, NOT EVERYONE WILL HAVE IT)
//fontAgencyFB = Font.CreateDynamicFontFromOSFont("Agency FB", 16);
// load asset bundle // load asset bundle
bundle = AssetBundle.LoadFromFile(Path.Combine(BasePath, "tnh_qol_improvements")); bundle = AssetBundle.LoadFromFile(Path.Combine(BasePath, "tnh_qol_improvements"));
SceneManager.activeSceneChanged += SceneChanged; SceneManager.activeSceneChanged += SceneChanged;
LoadAssets();
fontBombardier = bundle.LoadAsset<Font>("Bombardier");
// setup configuration // setup configuration
showHPBackground = Config.Bind("Health Counter", //--- Health Counter ---//
cfgHPHiddenWhenAiming = Config.Bind("Health Counter",
"Hide HP Counter When Aiming",
true,
"While aiming around the health counter in view, hide it.");
cfgShowHPBackground = Config.Bind("Health Counter",
"Background enabled", "Background enabled",
true, true,
"Apply a background to the health text."); "Apply a background to the health text.");
hpBackgroundOpacity = Config.Bind("Health Counter", cfgHPBackgroundOpacity = Config.Bind("Health Counter",
"Background opacity", "Background opacity",
0.74f, 0.74f,
"Set opacity of health text's background (if enabled)."); "Set opacity of health text's background (if enabled).");
showTokens = Config.Bind("Game Info", cfgHPTextType = Config.Bind("Health Counter",
"HP Text Type",
HPTextType.Solidify,
"Solidify: Set text to full opacity and give it a drop shadow\n" +
"Untouched: Leave text untouched\n" +
"Hidden: Hide health counter completely (will hide background if enabled)");
//--- Take and Hold Info ---//
cfgShowLPC = Config.Bind("Take and Hold Info",
"Show Player Count in Online Leaderboards",
true,
"Shows the number of players in the currently selected TNH leaderboard.");
cfgInfoFollowCamera = Config.Bind("Take and Hold Info",
"Tilt Wrist Stats Towards Camera",
true,
"Tilt the extra wrist statistics from this mod towards the player's camera, allowing for easier readability.");
cfgShowTokens = Config.Bind("Take and Hold Info",
"Show Tokens", "Show Tokens",
true, true,
"Shows how many tokens the player has by their radar hand."); "Shows how many tokens the player has by their radar hand.");
showHolds = Config.Bind("Game Info", cfgShowHolds = Config.Bind("Take and Hold Info",
"Show Holds", "Show Holds",
true, true,
"Shows how many holds the player has completed by their radar hand."); "Shows how many holds the player has completed by their radar hand.");
cfgShowWaves = Config.Bind("Take and Hold Info",
"Show Waves",
true,
"Shows how many waves the player has completed on the current hold by their radar hand.");
cfgShowInfoOnGameOver = Config.Bind("Take and Hold Info",
"Show Extra Info at Game Over",
true,
"Show enabled extra game information at the game over area.");
cfgShowNumbersAtShop = Config.Bind("Take and Hold Info",
"Show Numbers for Tokens at Item Station",
true,
"At the item station, add a numberical representation to costs and player's tokens.");
//--- Misc. ---//
cfgHealthCrystalIndicator = Config.Bind("Misc.",
"Show expiration of Health Crystals",
HealthExpireIndicationType.Flashing,
"Add a visual indication on the Health Crystal's despawn timer.");
// patch the leaderboard // give 120 seconds to search for old mod, which we want to kill
lpc = new LeaderboardPlayerCountPatch(); lpcModSearchTimeEnd = Time.time + 120;
RunPatches();
} }
// DO NOT EDIT. // DO NOT EDIT.
private void LoadAssets() {} private void LoadAssets() {}
private void RunPatches()
{
if (harmony == null)
return;
// patch KillAll code (only acts w/ health crystals)
if (cfgHealthCrystalIndicator.Value != HealthExpireIndicationType.None)
TimedHealthCrystalPatch.Patch(harmony);
// patch leaderboard code
if (cfgShowLPC.Value)
LeaderboardPlayerCountPatch.Patch(harmony);
// for counting wins/loses for TNHInfo.holdCounter
if (cfgShowHolds.Value)
HoldCounterPatch.Patch(harmony);
// stick stats to hand after game over
if (cfgShowHolds.Value || cfgShowTokens.Value)
InPlay.Patch(harmony);
// show numerical representation of shop values
if (cfgShowNumbersAtShop.Value)
{
// costs
ShopCostPatch.Patch(harmony);
// player tokens
ShopTokenPatch.Patch(harmony);
}
}
/// <summary> /// <summary>
/// Its only purpose: to kill TNH Leaderboard Player Count /// Its only purpose: to kill the deprecated TNH Leaderboard Player Count mod.
/// </summary> /// </summary>
private void Update() private void Update()
{ {
if (lpcKilled) if (lpcModGone)
return; return;
foreach (var plugin in Chainloader.PluginInfos) foreach (var plugin in Chainloader.PluginInfos)
@@ -103,9 +249,15 @@ public class MeatKitPlugin : BaseUnityPlugin
{ {
Logger.LogWarning("TNH Leaderboard Player Count mod detected. Destroying it to avoid interference."); Logger.LogWarning("TNH Leaderboard Player Count mod detected. Destroying it to avoid interference.");
Destroy(plugin.Value.Instance); Destroy(plugin.Value.Instance);
lpcKilled = true; lpcModGone = true;
} }
} }
if (Time.realtimeSinceStartup >= lpcModSearchTimeEnd)
{
Logger.LogInfo("Stopping search for TNH Leaderboard Player Count mod after 120 seconds.");
lpcModGone = true;
}
} }
} }
#endif #endif
+52 -6
View File
@@ -1,14 +1,60 @@
# TNH Quality of Life Improvements # TNH Quality of Life Improvements
This mod adds quality of life improvements to the *Take and Hold* experience. Ever got frustrated checking your HP against a bright ceiling in TNH?
Have you forgotten how many Holds you're playing for, so you don't know if you should spend all your tokens?
And... wait, which hold are you on again?
**This mod adds quality of life improvements to the *Take and Hold* experience that help with these questions, and then some.**
## Features ## Features
* More visible HP counter * Better health counter visibility
* Token and hold counter on wrist * Health counter fade when aiming around it
* Token, hold, and wave counter on radar hand
* Player count for online leaderboards; see how you stack up! * Player count for online leaderboards; see how you stack up!
* Incompatible with [*TakeAndHoldTweaker*](https://h3vr.thunderstore.io/package/devyndamonster/TakeAndHoldTweaker/); feature will be disabled! * Won't work with [*TakeAndHoldTweaker*](https://h3vr.thunderstore.io/package/devyndamonster/TakeAndHoldTweaker/) installed
* Numerical representation of tokens at item stations
* Expiration indication for health crystals (configurable to multiple types)
* ...and possibly more!
Enable/disable these features in your mod manager's *Config editor*. Toggle and customize these features in your mod manager's *Config editor*.
For any issues/ideas, please create an issue on the GitHub repo (linked on Thunderstore page). **This mod will not disqualify you from Steam or TNHTweaker leaderboards.**
For any issues/ideas, please create an issue at the GitHub repository (linked on Thunderstore page).
## Changelog
1.2.1
* [TNH] Changed leaderboard player count message for unavailability with TNHTweaker
**1.2.0**
* HP counter text can now be hidden completely
* Added HP counter fading when pointing a firearm towards it, allowing better visiblity
* Shrunk borders of health counter's background
1.1.3
* [TNH] Fixed wrist stats still trying to look at the camera in the game over area, resulting in weird rotations
1.1.2
* [TNH] Wrist stats can now tilt towards the camera, making it less awkward to read
1.1.1
* Fixed wave counter text not showing up during a hold
**1.1.0**
* [TNH] Added win/lose count on hold counter
* [TNH] Added enemy waves counter (substitutes token counter during hold if enabled)
* [TNH] Added token numerical representation to shop
* [TNH] Extra info from this mod now shows in game over
* Added expiration indicators to Health Crystals
* Health readability now applies outside of Take and Hold
1.0.1
* Fixed the in-play improvements only applying to Classic Hallways map (whoops!!)
* Added option to enable/disable showing player count of online leaderboards
* Added option to enable/disable HP text opacity/shadow change
* (Surprisingly, the HP text normally doesn't have full opacity)
* Searching for the deprecated TNH Leaderboards Player Count mod to kill now stops after 120s
**1.0.0**
* Initial release!
**NOTE: [*TNH Leaderboard Player Count*](https://h3vr.thunderstore.io/package/muskit/TNH_Leaderboard_Player_Count/) has been merged with this mod. If installed, please remove that mod as it lacks features and is no longer supported.** **NOTE: [*TNH Leaderboard Player Count*](https://h3vr.thunderstore.io/package/muskit/TNH_Leaderboard_Player_Count/) has been merged with this mod. If installed, please remove that mod as it lacks features and is no longer supported.**
+1 -1
View File
@@ -1,7 +1,7 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 623ce5e3a46127b4492d42d663741c3c guid: 623ce5e3a46127b4492d42d663741c3c
folderAsset: yes folderAsset: yes
timeCreated: 1642676798 timeCreated: 1643540751
licenseType: Free licenseType: Free
DefaultImporter: DefaultImporter:
userData: userData:
Binary file not shown.
Binary file not shown.
+21
View File
@@ -0,0 +1,21 @@
fileFormatVersion: 2
guid: db8c1f9217651f543827c4f8bb8fda6e
timeCreated: 1643449316
licenseType: Free
TrueTypeFontImporter:
serializedVersion: 4
fontSize: 16
forceTextureCase: -2
characterSpacing: 0
characterPadding: 1
includeFontData: 1
fontName: Bombardier
fontNames:
- Bombardier
fallbackFontReferences: []
customCharacters:
fontRenderingMode: 0
ascentCalculationMode: 1
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
@@ -1,6 +1,6 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 05d48c500227c8a4bbb7c02e3ccbb0b3 guid: bd993af5e164abe478f9fb24772e9e5d
timeCreated: 1642730970 timeCreated: 1643449316
licenseType: Free licenseType: Free
TrueTypeFontImporter: TrueTypeFontImporter:
serializedVersion: 4 serializedVersion: 4
@@ -9,9 +9,9 @@ TrueTypeFontImporter:
characterSpacing: 0 characterSpacing: 0
characterPadding: 1 characterPadding: 1
includeFontData: 1 includeFontData: 1
fontName: Agency FB fontName: Gewtymol
fontNames: fontNames:
- Agency FB - Gewtymol
fallbackFontReferences: [] fallbackFontReferences: []
customCharacters: customCharacters:
fontRenderingMode: 0 fontRenderingMode: 0
+187
View File
@@ -0,0 +1,187 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1634027973393822}
m_IsPrefabParent: 1
--- !u!1 &1475934434838188
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224853189626207054}
- component: {fileID: 222684863573680672}
- component: {fileID: 114673309682266402}
m_Layer: 5
m_Name: Image
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1634027973393822
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224077453978722080}
- component: {fileID: 223544683124447678}
- component: {fileID: 114094006499494552}
- component: {fileID: 114774830210974956}
- component: {fileID: 114654661998195444}
m_Layer: 5
m_Name: HealthCrystalTimer
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114094006499494552
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1634027973393822}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!114 &114654661998195444
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1634027973393822}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c0cc182175a3417499d53e43378f028c, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &114673309682266402
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1475934434838188}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_Sprite: {fileID: 21300000, guid: 3677786155d617b4cb39bf42eddd24ad, type: 3}
m_Type: 3
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 0
m_FillOrigin: 2
--- !u!114 &114774830210974956
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1634027973393822}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!222 &222684863573680672
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1475934434838188}
--- !u!223 &223544683124447678
Canvas:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1634027973393822}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 2
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &224077453978722080
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1634027973393822}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224853189626207054}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 574, y: 308.5}
m_SizeDelta: {x: 468, y: 472}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224853189626207054
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1475934434838188}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224077453978722080}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 468, y: 472}
m_Pivot: {x: 0.5, y: 0.5}
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: a97af7648bcd6394b867989bf8fb9ed0
timeCreated: 1643099434
licenseType: Free
NativeFormatImporter:
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:
+108 -18
View File
@@ -66,6 +66,24 @@ GameObject:
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 1
--- !u!1 &1774018057659698
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224420167260936368}
- component: {fileID: 222388691975761020}
- component: {fileID: 114828117127462556}
- component: {fileID: 114042133408737726}
m_Layer: 5
m_Name: Text (2)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114032145135548160 --- !u!114 &114032145135548160
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 1 m_ObjectHideFlags: 1
@@ -86,12 +104,12 @@ MonoBehaviour:
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData: m_FontData:
m_Font: {fileID: 12800000, guid: 05d48c500227c8a4bbb7c02e3ccbb0b3, type: 3} m_Font: {fileID: 12800000, guid: c51b17758851dcc44b27cae745b28eaa, type: 3}
m_FontSize: 30 m_FontSize: 70
m_FontStyle: 0 m_FontStyle: 0
m_BestFit: 1 m_BestFit: 1
m_MinSize: 10 m_MinSize: 10
m_MaxSize: 67 m_MaxSize: 70
m_Alignment: 7 m_Alignment: 7
m_AlignByGeometry: 0 m_AlignByGeometry: 0
m_RichText: 1 m_RichText: 1
@@ -99,6 +117,20 @@ MonoBehaviour:
m_VerticalOverflow: 0 m_VerticalOverflow: 0
m_LineSpacing: 1 m_LineSpacing: 1
m_Text: HOLDS COMPLETED m_Text: HOLDS COMPLETED
--- !u!114 &114042133408737726
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1774018057659698}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1573420865, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EffectColor: {r: 0, g: 0, b: 0, a: 0.734}
m_EffectDistance: {x: 3.5, y: -3.5}
m_UseGraphicAlpha: 1
--- !u!114 &114133878122943296 --- !u!114 &114133878122943296
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 1 m_ObjectHideFlags: 1
@@ -179,19 +211,52 @@ MonoBehaviour:
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData: m_FontData:
m_Font: {fileID: 12800000, guid: 05d48c500227c8a4bbb7c02e3ccbb0b3, type: 3} m_Font: {fileID: 12800000, guid: c51b17758851dcc44b27cae745b28eaa, type: 3}
m_FontSize: 200 m_FontSize: 178
m_FontStyle: 0 m_FontStyle: 0
m_BestFit: 1 m_BestFit: 1
m_MinSize: 2 m_MinSize: 0
m_MaxSize: 200 m_MaxSize: 231
m_Alignment: 1 m_Alignment: 4
m_AlignByGeometry: 0 m_AlignByGeometry: 0
m_RichText: 1 m_RichText: 1
m_HorizontalOverflow: 0 m_HorizontalOverflow: 0
m_VerticalOverflow: 0 m_VerticalOverflow: 0
m_LineSpacing: 1 m_LineSpacing: 1
m_Text: "-1 / \u221E" m_Text: "-1 / \u221E"
--- !u!114 &114828117127462556
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1774018057659698}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: c51b17758851dcc44b27cae745b28eaa, type: 3}
m_FontSize: 56
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 100
m_Alignment: 7
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 'W: 0 L: 0'
--- !u!114 &114972162530505676 --- !u!114 &114972162530505676
MonoBehaviour: MonoBehaviour:
m_ObjectHideFlags: 1 m_ObjectHideFlags: 1
@@ -208,6 +273,12 @@ MonoBehaviour:
m_BlockingMask: m_BlockingMask:
serializedVersion: 2 serializedVersion: 2
m_Bits: 4294967295 m_Bits: 4294967295
--- !u!222 &222388691975761020
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1774018057659698}
--- !u!222 &222541359112789466 --- !u!222 &222541359112789466
CanvasRenderer: CanvasRenderer:
m_ObjectHideFlags: 1 m_ObjectHideFlags: 1
@@ -255,8 +326,8 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -45} m_AnchoredPosition: {x: 0, y: -11.854996}
m_SizeDelta: {x: 0, y: -90} m_SizeDelta: {x: 0, y: -97.490005}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224364969672532764 --- !u!224 &224364969672532764
RectTransform: RectTransform:
@@ -271,11 +342,29 @@ RectTransform:
m_Father: {fileID: 224724389550513542} m_Father: {fileID: 224724389550513542}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 0.5}
m_AnchoredPosition: {x: 0, y: 105.9} m_AnchoredPosition: {x: 0, y: 180}
m_SizeDelta: {x: 0, y: -211.8} m_SizeDelta: {x: 0, y: 90}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 1}
--- !u!224 &224420167260936368
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1774018057659698}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224724389550513542}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 0.5, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 498.43, y: 76.42}
m_Pivot: {x: 0.5, y: 0}
--- !u!224 &224724389550513542 --- !u!224 &224724389550513542
RectTransform: RectTransform:
m_ObjectHideFlags: 1 m_ObjectHideFlags: 1
@@ -283,16 +372,17 @@ RectTransform:
m_PrefabInternal: {fileID: 100100000} m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1421894940388160} m_GameObject: {fileID: 1421894940388160}
m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0, y: 0, z: 150.00005} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: m_Children:
- {fileID: 224364969672532764} - {fileID: 224364969672532764}
- {fileID: 224142695019321682} - {fileID: 224142695019321682}
- {fileID: 224420167260936368}
m_Father: {fileID: 0} m_Father: {fileID: 0}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 500, y: 300} m_SizeDelta: {x: 580, y: 360}
m_Pivot: {x: 1, y: 1} m_Pivot: {x: 1, y: 0.5}
@@ -113,9 +113,9 @@ MonoBehaviour:
m_AlignByGeometry: 0 m_AlignByGeometry: 0
m_RichText: 1 m_RichText: 1
m_HorizontalOverflow: 0 m_HorizontalOverflow: 0
m_VerticalOverflow: 0 m_VerticalOverflow: 1
m_LineSpacing: 1 m_LineSpacing: 1
m_Text: LOADING PLAYER COUNT m_Text: RETRIEVING PLAYER COUNT
--- !u!222 &222658238543524802 --- !u!222 &222658238543524802
CanvasRenderer: CanvasRenderer:
m_ObjectHideFlags: 1 m_ObjectHideFlags: 1
+4
View File
@@ -16,3 +16,7 @@ MonoBehaviour:
- {fileID: 1428988585174978, guid: c034a3fdd4eaa554bb81a9a202bf37dd, type: 2} - {fileID: 1428988585174978, guid: c034a3fdd4eaa554bb81a9a202bf37dd, type: 2}
- {fileID: 1421894940388160, guid: 2e88fb286dba59a45b49fb0ae7d9449b, type: 2} - {fileID: 1421894940388160, guid: 2e88fb286dba59a45b49fb0ae7d9449b, type: 2}
- {fileID: 1395656030192232, guid: 6085354c72844664589bb5f21f9872b1, type: 2} - {fileID: 1395656030192232, guid: 6085354c72844664589bb5f21f9872b1, type: 2}
- {fileID: 1634027973393822, guid: a97af7648bcd6394b867989bf8fb9ed0, type: 2}
- {fileID: 1106932692061560, guid: 9c96f08f84c4ede44ae45ae4afd1901b, type: 2}
- {fileID: 12800000, guid: db8c1f9217651f543827c4f8bb8fda6e, type: 3}
- {fileID: 1484126367028484, guid: 5a8f723d4ab4740458cbb4df16bf2c5e, type: 2}
+53
View File
@@ -0,0 +1,53 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1106932692061560}
m_IsPrefabParent: 1
--- !u!1 &1106932692061560
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 4863261474150994}
- component: {fileID: 114110489569638852}
m_Layer: 0
m_Name: TNHInfo
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4863261474150994
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1106932692061560}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &114110489569638852
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1106932692061560}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 0d549cfce77855f4e9d9778d4c602f21, type: 3}
m_Name:
m_EditorClassIdentifier:
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 9c96f08f84c4ede44ae45ae4afd1901b
timeCreated: 1643333802
licenseType: Free
NativeFormatImporter:
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:
+15 -15
View File
@@ -159,12 +159,12 @@ MonoBehaviour:
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData: m_FontData:
m_Font: {fileID: 12800000, guid: 05d48c500227c8a4bbb7c02e3ccbb0b3, type: 3} m_Font: {fileID: 12800000, guid: c51b17758851dcc44b27cae745b28eaa, type: 3}
m_FontSize: 200 m_FontSize: 225
m_FontStyle: 0 m_FontStyle: 0
m_BestFit: 1 m_BestFit: 0
m_MinSize: 1 m_MinSize: 1
m_MaxSize: 200 m_MaxSize: 274
m_Alignment: 3 m_Alignment: 3
m_AlignByGeometry: 0 m_AlignByGeometry: 0
m_RichText: 1 m_RichText: 1
@@ -247,10 +247,10 @@ RectTransform:
m_Father: {fileID: 224329896993820026} m_Father: {fileID: 224329896993820026}
m_RootOrder: 1 m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 1, y: 1} m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: 73.2, y: 0} m_AnchoredPosition: {x: 373.2, y: 0}
m_SizeDelta: {x: -146.4, y: 0} m_SizeDelta: {x: 353.6, y: 370}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!224 &224145026042435474 --- !u!224 &224145026042435474
RectTransform: RectTransform:
@@ -265,11 +265,11 @@ RectTransform:
m_Father: {fileID: 224329896993820026} m_Father: {fileID: 224329896993820026}
m_RootOrder: 0 m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0, y: 0.5}
m_AnchoredPosition: {x: -122, y: 0} m_AnchoredPosition: {x: 50, y: 0}
m_SizeDelta: {x: 120, y: 120} m_SizeDelta: {x: 120, y: 120}
m_Pivot: {x: 1, y: 0.5} m_Pivot: {x: 0, y: 0.5}
--- !u!224 &224329896993820026 --- !u!224 &224329896993820026
RectTransform: RectTransform:
m_ObjectHideFlags: 1 m_ObjectHideFlags: 1
@@ -277,7 +277,7 @@ RectTransform:
m_PrefabInternal: {fileID: 100100000} m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1428988585174978} m_GameObject: {fileID: 1428988585174978}
m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068} m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0, y: 0, z: 150.00002} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: m_Children:
- {fileID: 224145026042435474} - {fileID: 224145026042435474}
@@ -288,5 +288,5 @@ RectTransform:
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0} m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 500, y: 300} m_SizeDelta: {x: 500, y: 360}
m_Pivot: {x: 0, y: 1} m_Pivot: {x: 0, y: 0.5}
+298
View File
@@ -0,0 +1,298 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 1484126367028484}
m_IsPrefabParent: 1
--- !u!1 &1284361357339212
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224892970170756718}
- component: {fileID: 222469931575018544}
- component: {fileID: 114369350517400038}
- component: {fileID: 114774221110400688}
m_Layer: 5
m_Name: Text (1)
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1484126367028484
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224505954339385570}
- component: {fileID: 223350672124862004}
- component: {fileID: 114814645303408290}
- component: {fileID: 114323534746903312}
- component: {fileID: 114211714150175156}
m_Layer: 5
m_Name: WaveCounter
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &1767730806891424
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 5
m_Component:
- component: {fileID: 224426227895944482}
- component: {fileID: 222191868559757652}
- component: {fileID: 114991591682320102}
- component: {fileID: 114225475503413820}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &114211714150175156
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1484126367028484}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c0c3423ff90fccc45bc00c97177b33fb, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &114225475503413820
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1767730806891424}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1573420865, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EffectColor: {r: 0, g: 0, b: 0, a: 0.734}
m_EffectDistance: {x: 3.5, y: -3.5}
m_UseGraphicAlpha: 1
--- !u!114 &114323534746903312
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1484126367028484}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1301386320, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_IgnoreReversedGraphics: 1
m_BlockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &114369350517400038
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1284361357339212}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: c51b17758851dcc44b27cae745b28eaa, type: 3}
m_FontSize: 178
m_FontStyle: 0
m_BestFit: 1
m_MinSize: 0
m_MaxSize: 290
m_Alignment: 4
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: "-1 / \u221E"
--- !u!114 &114774221110400688
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1284361357339212}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1573420865, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EffectColor: {r: 0, g: 0, b: 0, a: 0.734}
m_EffectDistance: {x: 3.5, y: -3.5}
m_UseGraphicAlpha: 1
--- !u!114 &114814645303408290
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1484126367028484}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1980459831, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_UiScaleMode: 0
m_ReferencePixelsPerUnit: 100
m_ScaleFactor: 1
m_ReferenceResolution: {x: 800, y: 600}
m_ScreenMatchMode: 0
m_MatchWidthOrHeight: 0
m_PhysicalUnit: 3
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
--- !u!114 &114991591682320102
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1767730806891424}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_RaycastTarget: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
m_FontData:
m_Font: {fileID: 12800000, guid: c51b17758851dcc44b27cae745b28eaa, type: 3}
m_FontSize: 70
m_FontStyle: 0
m_BestFit: 1
m_MinSize: 10
m_MaxSize: 70
m_Alignment: 7
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: WAVES COMPLETED
--- !u!222 &222191868559757652
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1767730806891424}
--- !u!222 &222469931575018544
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1284361357339212}
--- !u!223 &223350672124862004
Canvas:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1484126367028484}
m_Enabled: 1
serializedVersion: 3
m_RenderMode: 2
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 0
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingBucketNormalizedSize: 0
m_AdditionalShaderChannelsFlag: 0
m_SortingLayerID: 0
m_SortingOrder: 0
m_TargetDisplay: 0
--- !u!224 &224426227895944482
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1767730806891424}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224505954339385570}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0.5}
m_AnchorMax: {x: 1, y: 0.5}
m_AnchoredPosition: {x: 0, y: 180}
m_SizeDelta: {x: 0, y: 90}
m_Pivot: {x: 0.5, y: 1}
--- !u!224 &224505954339385570
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1484126367028484}
m_LocalRotation: {x: 0.7071068, y: 0, z: 0, w: 0.7071068}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 224426227895944482}
- {fileID: 224892970170756718}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 90, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 580, y: 360}
m_Pivot: {x: 0, y: 0.5}
--- !u!224 &224892970170756718
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 1284361357339212}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 224505954339385570}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: -30.3}
m_SizeDelta: {x: 0, y: -60.6}
m_Pivot: {x: 0.5, y: 0.5}
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5a8f723d4ab4740458cbb4df16bf2c5e
timeCreated: 1643271770
licenseType: Free
NativeFormatImporter:
mainObjectFileID: 100100000
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.
Binary file not shown.
+127
View File
@@ -0,0 +1,127 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using FistVR;
// To be attached to FVRHealthBar object
public class HPHideWhenAiming : MonoBehaviour {
CanvasGroup canvasGroup;
GameObject gObjHUD;
RawImage background;
FVRViveHand leftHand;
FVRViveHand rightHand;
BoxCollider hudCollider;
GameObject gObjLeftLine;
GameObject gObjRightLine;
LineRenderer leftHandLine;
LineRenderer rightHandLine;
//// Testing renderers
//GameObject gObjColliderRenderer;
//LineRenderer colliderRenderer;
// Use this for initialization
void Start() {
gObjHUD = transform.GetChild(0).gameObject;
leftHand = MeatKitPlugin.playerCamera.transform.parent.GetChild(1).GetComponent<FVRViveHand>();
rightHand = MeatKitPlugin.playerCamera.transform.parent.GetChild(0).GetComponent<FVRViveHand>();
canvasGroup = gameObject.AddComponent<CanvasGroup>();
var gObjBG = gObjHUD.transform.Find("Background");
if (gObjBG != null)
background = gObjBG.GetComponent<RawImage>();
hudCollider = gObjHUD.AddComponent<BoxCollider>();
hudCollider.isTrigger = true;
hudCollider.gameObject.layer = LayerMask.NameToLayer("UI");
hudCollider.size = new Vector3(40, 25, .01f);
//// TESTING: collider visuals
//gObjColliderRenderer = new GameObject();
//gObjColliderRenderer.transform.SetParent(hudCollider.transform, false);
//colliderRenderer = gObjColliderRenderer.AddComponent<LineRenderer>();
//colliderRenderer.SetWidth(.005f, .005f);
//colliderRenderer.SetColors(Color.blue, Color.blue);
//colliderRenderer.positionCount = 8;
//// TESTING: beam from held weapons
//gObjLeftLine = new GameObject();
//leftHandLine = gObjLeftLine.AddComponent<LineRenderer>();
//leftHandLine.positionCount = 2;
//leftHandLine.SetWidth(.008f, .008f);
//leftHandLine.SetColors(Color.blue, Color.blue);
//gObjRightLine = new GameObject();
//rightHandLine = gObjRightLine.AddComponent<LineRenderer>();
//rightHandLine.positionCount = 2;
//rightHandLine.SetWidth(.008f, .008f);
//rightHandLine.SetColors(Color.blue, Color.blue);
}
void FixedUpdate()
{
FVRInteractiveObject[] objs = { leftHand.CurrentInteractable, rightHand.CurrentInteractable };
LineRenderer[] lines = { leftHandLine, rightHandLine };
bool rayHit = false;
for (int i = 0; i < 2; ++i)
{
Transform transMuzzle;
if (objs[i] is FVRFireArm)
{
var firearm = objs[i] as FVRFireArm;
transMuzzle = firearm.CurrentMuzzle;
}
else if (objs[i] is SosigWeaponPlayerInterface)
{
var playerInterface = objs[i] as SosigWeaponPlayerInterface;
var sosigWeapon = playerInterface.gameObject.GetComponent<SosigWeapon>();
transMuzzle = sosigWeapon.Muzzle;
}
else // not a recognized weapon, don't do anything
continue;
// TESTING: draw beam from held wpn muzzle
//Vector3[] beamPos = { transMuzzle.position, transMuzzle.position + 5 * transMuzzle.forward };
//lines[i].SetPositions(beamPos);
RaycastHit hitInfo;
if (hudCollider.Raycast(new Ray(transMuzzle.position, transMuzzle.forward), out hitInfo, 20) ||
hudCollider.Raycast(new Ray(transMuzzle.position, -transMuzzle.forward), out hitInfo, 20))
rayHit = true;
}
if (rayHit)
{
canvasGroup.alpha = 0.1f;
if (background != null)
background.enabled = false;
}
else
{
canvasGroup.alpha = 1f;
if (background != null)
background.enabled = true;
}
// TESTING: draw the collider
//var trans = hudCollider.transform;
//var min = hudCollider.center - hudCollider.size * 0.5f;
//var max = hudCollider.center + hudCollider.size * 0.5f;
//Vector3[] points = {
// trans.TransformPoint(new Vector3(min.x, min.y, min.z)),
// trans.TransformPoint(new Vector3(min.x, min.y, max.z)),
// trans.TransformPoint(new Vector3(min.x, max.y, min.z)),
// trans.TransformPoint(new Vector3(min.x, max.y, max.z)),
// trans.TransformPoint(new Vector3(max.x, min.y, min.z)),
// trans.TransformPoint(new Vector3(max.x, min.y, max.z)),
// trans.TransformPoint(new Vector3(max.x, max.y, min.z)),
// trans.TransformPoint(new Vector3(max.x, max.y, max.z))
//};
//colliderRenderer.SetPositions(points);
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 4c5bf6246707f204db6b73a5d74267f8
timeCreated: 1644787924
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+64
View File
@@ -0,0 +1,64 @@
using UnityEngine;
using UnityEngine.UI;
namespace TNHQoLImprovements
{
public enum HPTextType
{
Solidify, Untouched, Hidden
}
public static class HPReadability
{
public static void ImproveHPTextReadability(GameObject gObjHUD)
{
var canvas = gObjHUD.GetComponent<Canvas>();
Transform[] tranHPText = {
gObjHUD.transform.Find("Label_Title (1)"), // header
gObjHUD.transform.Find("Label_Title") // HP number
};
// apply background only if hp text type is not "Hidden"
if (MeatKitPlugin.cfgShowHPBackground.Value &&
MeatKitPlugin.cfgHPTextType.Value != HPTextType.Hidden)
{
var gObjBG = new GameObject();
gObjBG.name = "Background";
gObjBG.transform.SetParent(gObjHUD.transform, false);
gObjBG.transform.SetSiblingIndex(0);
gObjBG.transform.localPosition = new Vector3(0, 1, 0);
gObjBG.transform.localScale = tranHPText[0].localScale;
//gObjBG.transform.localRotation = Quaternion.identity;
var rawImage = gObjBG.AddComponent<RawImage>();
rawImage.color = new Color(0, 0, 0, MeatKitPlugin.cfgHPBackgroundOpacity.Value);
rawImage.rectTransform.SetWidth(85);
rawImage.rectTransform.SetHeight(44);
}
// set text type
if (MeatKitPlugin.cfgHPTextType.Value == HPTextType.Untouched)
return;
switch (MeatKitPlugin.cfgHPTextType.Value)
{
case HPTextType.Solidify:
foreach (var text in tranHPText)
{
// full alpha
text.GetComponent<Text>().color = Color.white;
// drop shadow
var shadow = text.gameObject.AddComponent<Shadow>();
shadow.effectColor = new Color(0, 0, 0, .95f);
shadow.effectDistance = new Vector2(0.5f, -0.5f);
}
break;
case HPTextType.Hidden:
foreach (var text in tranHPText)
{
text.GetComponent<Text>().color = new Color(0, 0, 0, 0);
}
break;
}
}
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 13876b4618c99394bbb2838f5c26cd19
timeCreated: 1643268023
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+36 -10
View File
@@ -1,37 +1,63 @@
using System.Collections; using System.Reflection;
using System.Collections.Generic; using HarmonyLib;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using FistVR; using FistVR;
namespace TNHQoLImprovements namespace TNHQoLImprovements
{ {
public static class HoldCounterPatch
{
public static void Patch(Harmony harmony)
{
var original = typeof(TNH_Manager).GetMethod("HoldPointCompleted", BindingFlags.Public | BindingFlags.Instance);
var patch = typeof(HoldCounter).GetMethod("OnHoldEnd");
harmony.Patch(original, postfix: new HarmonyMethod(patch));
}
}
public class HoldCounter : MonoBehaviour public class HoldCounter : MonoBehaviour
{ {
private void OnDeath(bool _) private Text lblHoldCount;
private Text lblWinLose;
public static int[] winLose = { -1, 1 };
public const string WIN_LOSE_TEXT = "W: {0} L: {1}";
//public const string WIN_LOSE_TEXT = "<color=#10ff10>{0}</color> <color=red>{1}</color>";
public static void OnHoldEnd(TNH_HoldPoint p, bool success)
{ {
Debug.Log("I died!"); if (success)
winLose[0]++;
else
winLose[1]++;
} }
void Start() void Start()
{ {
transform.parent = GameObject.Find("_NewTAHReticle/TAHReticle_HealthBar").transform; lblHoldCount = transform.GetChild(1).GetComponent<Text>();
transform.localPosition = new Vector3(-1f, 0, -.5f); lblWinLose = transform.GetChild(2).GetComponent<Text>();
transform.localRotation = Quaternion.Euler(90, 0, 0);
transform.localScale = new Vector3(0.002f, 0.002f, 0.002f);
GameObject.Find("[SceneSettings]").GetComponent<FVRSceneSettings>().PlayerDeathEvent += OnDeath; transform.GetChild(0).GetComponent<Text>().font = MeatKitPlugin.fontAgencyFB;
lblHoldCount.font = MeatKitPlugin.fontAgencyFB;
lblWinLose.font = MeatKitPlugin.fontAgencyFB;
winLose[0] = 0;
winLose[1] = 0;
} }
void Update() void Update()
{ {
// Total hold count
string display = ""; string display = "";
if (InPlay.tnhManager.ProgressionMode == TNHSetting_ProgressionType.Marathon) if (InPlay.tnhManager.ProgressionMode == TNHSetting_ProgressionType.Marathon)
display = InPlay.tnhManager.m_level.ToString() + " / ∞"; display = InPlay.tnhManager.m_level.ToString() + " / ∞";
else else
display = string.Format("{0} / {1}", InPlay.tnhManager.m_level, InPlay.tnhManager.m_maxLevels); display = string.Format("{0} / {1}", InPlay.tnhManager.m_level, InPlay.tnhManager.m_maxLevels);
lblHoldCount.text = display;
transform.GetChild(1).GetComponent<Text>().text = display; // Win/Lost holds
lblWinLose.text = string.Format(WIN_LOSE_TEXT, winLose[0], winLose[1]);
} }
} }
} }
+36 -39
View File
@@ -1,4 +1,5 @@
using System.Collections; using HarmonyLib;
using System.Reflection;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using FistVR; using FistVR;
@@ -10,56 +11,52 @@ namespace TNHQoLImprovements
/// </summary> /// </summary>
public class InPlay : MonoBehaviour public class InPlay : MonoBehaviour
{ {
private GameObject gObjHUD;
private GameObject gObjTokens;
public static TNH_Manager tnhManager; public static TNH_Manager tnhManager;
#region INITIALIZATION private static Transform[] hands;
void ImproveHPTextReadability() private static GameObject tnhInfo;
{
var canvas = gObjHUD.GetComponent<Canvas>();
var gObjBG = new GameObject();
var tranHPTitle = gObjHUD.transform.Find("Label_Title (1)");
var tranHP = gObjHUD.transform.Find("Label_Title");
// apply background public static bool InHold()
if (MeatKitPlugin.showHPBackground.Value)
{ {
gObjBG.transform.parent = gObjHUD.transform; if (tnhManager == null)
gObjBG.transform.SetSiblingIndex(0); return false;
gObjBG.transform.localPosition = new Vector3(0, 1, 0);
gObjBG.transform.localRotation = Quaternion.identity; return tnhManager.Phase == TNH_Phase.Hold;
gObjBG.transform.localScale = tranHP.localScale;
var rawImage = gObjBG.AddComponent<RawImage>();
rawImage.color = new Color(0, 0, 0, MeatKitPlugin.hpBackgroundOpacity.Value);
rawImage.rectTransform.SetWidth(100);
rawImage.rectTransform.SetHeight(52);
} }
// full text alphas // Bring extra info into game over
tranHPTitle.GetComponent<Text>().color = Color.white; public static void Patch(Harmony harmony)
tranHP.GetComponent<Text>().color = Color.white; {
// text shadows var original = typeof(TNH_Manager).GetMethod("SetPhase", BindingFlags.NonPublic | BindingFlags.Instance);
var shadow = tranHPTitle.gameObject.AddComponent<Shadow>(); var patch = typeof(InPlay).GetMethod("MoveStatsToController", BindingFlags.NonPublic | BindingFlags.Static);
shadow.effectColor = new Color(0, 0, 0, .95f); harmony.Patch(original, postfix: new HarmonyMethod(patch));
shadow.effectDistance = new Vector2(0.5f, -0.5f); }
shadow = tranHP.gameObject.AddComponent<Shadow>();
shadow.effectColor = new Color(0, 0, 0, .95f); private static void MoveStatsToController(TNH_Phase p)
shadow.effectDistance = new Vector2(0.5f, -0.5f); {
if (tnhManager == null)
return;
if (p == TNH_Phase.Dead || p == TNH_Phase.Completed)
{
int handSide = tnhManager.RadarHand == TNH_RadarHand.Left ? 0 : 1;
tnhInfo.transform.SetParent(hands[handSide], false);
tnhInfo.GetComponent<TNHInfo>().GameOverPos();
}
} }
// Use this for initialization
void Start() void Start()
{ {
tnhManager = GameObject.Find("_GameManager").GetComponent<TNH_Manager>(); tnhManager = GameObject.Find("_GameManager").GetComponent<TNH_Manager>();
gObjHUD = GameObject.Find("HealthBar(Clone)/f");
ImproveHPTextReadability(); var rig = Object.FindObjectOfType<FVRMovementManager>().transform;
if (MeatKitPlugin.showTokens.Value) hands = new Transform[] {
Instantiate(MeatKitPlugin.bundle.LoadAsset<GameObject>("TokenCounter")); rig.transform.GetChild(1), rig.transform.GetChild(0)
if (MeatKitPlugin.showHolds.Value) };
Instantiate(MeatKitPlugin.bundle.LoadAsset<GameObject>("HoldCounter"));
tnhInfo = Instantiate<GameObject>(MeatKitPlugin.bundle.LoadAsset<GameObject>("TNHInfo"), FindObjectOfType<TAH_Reticle>().transform.GetChild(3));
tnhInfo.transform.localScale = new Vector3(0.002f, 0.002f, 0.002f);
} }
#endregion
} }
} }
+20 -16
View File
@@ -15,41 +15,37 @@ namespace TNHQoLImprovements
private bool tnhTweakerInstalled = false; private bool tnhTweakerInstalled = false;
private string curID; private string curID;
private string loadingStr;
private TNH_ScoreDisplay scoreDisplay; private TNH_ScoreDisplay scoreDisplay;
private Text lblGlobalScores; private Text lblGlobalScores;
private GameObject gObjLoading; private GameObject gObjLoading;
#region INITIALIZATION #region INITIALIZATION
// public void Start()
// {
// Debug.Log("--- Installed BepInEx Plugins ---");
// foreach (var plugin in Chainloader.PluginInfos)
// {
// Debug.Log(plugin.Key);
// }
// Debug.Log("--- End Plugins ---");
//}
public void Init(TNH_ScoreDisplay tnhScore, Text scoreLabel, GameObject gObjLoading) public void Init(TNH_ScoreDisplay tnhScore, Text scoreLabel, GameObject gObjLoading)
{ {
if (initialized) if (initialized)
return; return;
this.scoreDisplay = tnhScore; // don't run with TNHTweaker installed
this.lblGlobalScores = scoreLabel;
this.lblGlobalScores.resizeTextForBestFit = true;
this.lblGlobalScores.horizontalOverflow = HorizontalWrapMode.Overflow;
this.gObjLoading = gObjLoading; this.gObjLoading = gObjLoading;
var loadedAssemblies = System.AppDomain.CurrentDomain.GetAssemblies(); var loadedAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
if (Array.Exists<Assembly>(loadedAssemblies, x => x.GetName().Name == "TakeAndHoldTweaker")) if (Array.Exists<Assembly>(loadedAssemblies, x => x.GetName().Name == "TakeAndHoldTweaker"))
{ {
tnhTweakerInstalled = true; tnhTweakerInstalled = true;
this.gObjLoading.transform.GetChild(0).GetComponent<Text>().text = "<color=lightblue>Online leaderboards player count is incompatible with TNHTweaker.</color>"; this.gObjLoading.transform.GetChild(0).GetComponent<Text>().text = "<color=lightblue><size=30>Online leaderboards player count unavailable for TNHTweaker.</size></color>";
this.gObjLoading.SetActive(true); this.gObjLoading.SetActive(true);
return;
} }
this.scoreDisplay = tnhScore;
this.lblGlobalScores = scoreLabel;
this.lblGlobalScores.resizeTextForBestFit = true;
this.lblGlobalScores.horizontalOverflow = HorizontalWrapMode.Overflow;
loadingStr = gObjLoading.GetComponentInChildren<Text>().text;
initialized = true; initialized = true;
} }
#endregion #endregion
@@ -72,6 +68,7 @@ namespace TNHQoLImprovements
string playerCountText = Steamworks.SteamUserStats string playerCountText = Steamworks.SteamUserStats
.GetLeaderboardEntryCount(HighScoreManager.Leaderboards[id]) .GetLeaderboardEntryCount(HighScoreManager.Leaderboards[id])
.ToString("N0"); .ToString("N0");
lblGlobalScores.text = "Global Scores: <color=lightblue>(" + playerCountText + " players)</color>"; lblGlobalScores.text = "Global Scores: <color=lightblue>(" + playerCountText + " players)</color>";
curID = id; curID = id;
gObjLoading.SetActive(false); gObjLoading.SetActive(false);
@@ -79,9 +76,16 @@ namespace TNHQoLImprovements
catch (KeyNotFoundException e) catch (KeyNotFoundException e)
{ {
lblGlobalScores.text = "Global Scores:"; lblGlobalScores.text = "Global Scores:";
gObjLoading.GetComponentInChildren<Text>().text = loadingStr;
gObjLoading.SetActive(true); gObjLoading.SetActive(true);
curID = null; curID = null;
} }
catch (Exception e)
{
gObjLoading.GetComponentInChildren<Text>().text = string.Format("<color=lightblue><size=30>Unknown error occured trying to retrieve online player count.</size></color>\n" +
"<color=red>{0}</color>", e);
gObjLoading.SetActive(true);
}
} }
} }
#endregion #endregion
@@ -1,25 +1,24 @@
using HarmonyLib; using System.Reflection;
using HarmonyLib;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using FistVR; using FistVR;
namespace TNHQoLImprovements namespace TNHQoLImprovements
{ {
[HarmonyPatch] public static class LeaderboardPlayerCountPatch
public class LeaderboardPlayerCountPatch
{ {
Harmony harmony;
private static GameObject gObjLoading; private static GameObject gObjLoading;
private static Text uiGlobalText; private static Text uiGlobalText;
public LeaderboardPlayerCountPatch() public static void Patch(Harmony harmony)
{ {
harmony = new Harmony("me.muskit.TNHQualityOfLifeImprovements.LeaderboardPlayerCount"); var original = typeof(TNH_ScoreDisplay).GetMethod("Start", BindingFlags.NonPublic | BindingFlags.Instance);
harmony.PatchAll(); var newfunc = typeof(LeaderboardPlayerCountPatch).GetMethod("Setup");
harmony.Patch(original, postfix: new HarmonyMethod(newfunc));
} }
[HarmonyPostfix]
[HarmonyPatch(typeof(TNH_ScoreDisplay), "Start")]
public static void Setup(TNH_ScoreDisplay __instance) public static void Setup(TNH_ScoreDisplay __instance)
{ {
GameObject gObjLeaderboard = null; GameObject gObjLeaderboard = null;
+64
View File
@@ -0,0 +1,64 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace TNHQoLImprovements
{
/// <summary>
/// Flash attached MeshRenderer the timer runs out.
/// </summary>
public class MeshRendererFlicker : MonoBehaviour
{
private bool initialized = false;
private float beginTime;
private float onLength;
private float offLength;
private float stateChangeTime = 0;
private bool visible = true;
private MeshRenderer mesh;
void Start()
{
mesh = GetComponent<MeshRenderer>();
}
public void Init(float interval, float onToOffRatio = 0.5f, float beginAfter = 0)
{
beginTime = Time.time + beginAfter;
onLength = interval * onToOffRatio;
offLength = interval * (1 - onToOffRatio);
initialized = true;
}
void Update()
{
if (!initialized || Time.time < beginTime)
return;
if (Time.time >= stateChangeTime)
{
visible = !visible;
mesh.enabled = visible;
if (visible) // set time to stay on
{
stateChangeTime = Time.time + onLength;
}
else // set time to stay off
{
stateChangeTime = Time.time + offLength;
}
}
//if (Time.time >= stateChangeTime)
// {
// stateChangeTime = Time.time + interval;
// visible = !visible;
// mesh.enabled = visible;
// }
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 41ced368c613e2444bdbb07051989499
timeCreated: 1643160950
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+57
View File
@@ -0,0 +1,57 @@
using System.Collections.Generic;
using System.Reflection;
using HarmonyLib;
using UnityEngine;
using UnityEngine.UI;
using FistVR;
namespace TNHQoLImprovements
{
public class ShopCostPatch : MonoBehaviour
{
public static void Patch(Harmony harmony)
{
var original = typeof(TNH_ObjectConstructorIcon).GetMethod("Init", BindingFlags.Public | BindingFlags.Instance);
var postfix = typeof(ShopCostPatch).GetMethod("AddCostNumber", BindingFlags.NonPublic | BindingFlags.Static);
harmony.Patch(original, new HarmonyMethod(postfix));
}
private static void AddCostNumber(TNH_ObjectConstructorIcon __instance)
{
foreach (Transform curTran in __instance.gameObject.transform)
{
if (curTran.name.Contains("Cost"))
curTran.gameObject.AddComponent<CostNumber>();
}
}
}
public class CostNumber : MonoBehaviour
{
private TNH_ObjectConstructorIcon objConstructorIcon;
private Text text;
public void Awake()
{
objConstructorIcon = transform.parent.GetComponent<TNH_ObjectConstructorIcon>();
}
public void Start()
{
var textTran = new GameObject().transform;
textTran.SetParent(transform, false);
textTran.localPosition = new Vector2(0, 245);
text = textTran.gameObject.AddComponent<Text>();
text.font = MeatKitPlugin.fontBombardier;
text.alignment = TextAnchor.MiddleCenter;
text.fontSize = 72;
}
public void Update()
{
text.text = objConstructorIcon.Cost.ToString();
text.color = objConstructorIcon.GetComponent<Image>().color;
}
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 51b19459f850a654488e4057bf5dbb1f
timeCreated: 1643424482
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+47
View File
@@ -0,0 +1,47 @@
using HarmonyLib;
using System.Reflection;
using UnityEngine;
using UnityEngine.UI;
using FistVR;
namespace TNHQoLImprovements
{
public static class ShopTokenPatch
{
public static void Patch(Harmony harmony)
{
var original = typeof(TNH_ObjectConstructor).GetMethod("Start", BindingFlags.NonPublic | BindingFlags.Instance);
var postfix = typeof(ShopTokenPatch).GetMethod("Postfix", BindingFlags.NonPublic | BindingFlags.Static);
harmony.Patch(original, postfix: new HarmonyMethod(postfix));
}
private static void Postfix(TNH_ObjectConstructor __instance)
{
// add component to 1st token icon
__instance.transform.GetChild(0).GetChild(0).GetChild(2).GetChild(0).gameObject.AddComponent<ShopTokenNumber>();
}
}
// child of TopCell (the 0th child)
class ShopTokenNumber : MonoBehaviour
{
private Text text;
private void Start()
{
var gObjText = new GameObject("TokenCounter");
gObjText.transform.SetParent(transform, false);
gObjText.transform.localPosition = new Vector3(0, -4, 0);
text = gObjText.AddComponent<Text>();
text.alignment = TextAnchor.MiddleCenter;
text.font = MeatKitPlugin.fontBombardier;
text.fontSize = 55;
text.color = new Color(0.1307786f, 0.2461715f, 0.359f);
}
private void Update()
{
int tokens = InPlay.tnhManager.GetNumTokens();
text.text = tokens.ToString();
}
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 54fa5d5e1f85520468a10f9556e53456
timeCreated: 1643446256
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+104
View File
@@ -0,0 +1,104 @@
using HarmonyLib;
using UnityEngine;
using FistVR;
namespace TNHQoLImprovements
{
class TNHInfo : MonoBehaviour
{
private GameObject holdCounter;
private GameObject tokenCounter;
private GameObject waveCounter;
public void Start()
{
if (MeatKitPlugin.cfgShowHolds.Value)
holdCounter = Instantiate<GameObject>(MeatKitPlugin.bundle.LoadAsset<GameObject>("HoldCounter"), transform);
if (MeatKitPlugin.cfgShowTokens.Value)
tokenCounter = Instantiate<GameObject>(MeatKitPlugin.bundle.LoadAsset<GameObject>("TokenCounter"), transform);
if (MeatKitPlugin.cfgShowWaves.Value)
waveCounter = Instantiate<GameObject>(MeatKitPlugin.bundle.LoadAsset<GameObject>("WaveCounter"), transform);
PlayPos();
}
public void PlayPos()
{
transform.localPosition = new Vector3(0, 0, -1.2f);
if (holdCounter != null)
holdCounter.transform.localPosition = new Vector3(-333, 0, 0);
if (tokenCounter != null)
tokenCounter.transform.localPosition = new Vector3(333, 0, 0);
if (waveCounter != null)
waveCounter.transform.localPosition = new Vector3(333, 0, 0);
}
public void GameOverPos()
{
transform.localScale = new Vector3(.0002f, .0002f, .0002f);
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity;
if (holdCounter != null)
{
holdCounter.gameObject.GetComponent<RectTransform>().pivot = new Vector2(1, 1);
holdCounter.transform.localPosition = new Vector3(-250, 0, 0);
}
if (tokenCounter != null)
{
tokenCounter.gameObject.GetComponent<RectTransform>().pivot = new Vector2(0, 1);
tokenCounter.transform.localPosition = new Vector3(250, 0, 0);
}
if (waveCounter != null)
{
waveCounter.gameObject.GetComponent<RectTransform>().pivot = new Vector2(0.5f, 0);
waveCounter.transform.localPosition = new Vector3(0, 0, 140);
}
}
public void Update()
{
// game over area; do not update anything else
if (InPlay.tnhManager.Phase == TNH_Phase.Dead || InPlay.tnhManager.Phase == TNH_Phase.Completed)
{
if (tokenCounter != null)
tokenCounter.SetActive(true);
return;
}
// TNHInfo rotate to player camera
if (MeatKitPlugin.cfgInfoFollowCamera.Value)
{
transform.LookAt(MeatKitPlugin.playerCamera.transform);
var rotLook = transform.localEulerAngles;
var rot = Vector3.zero;
rot.x = -rotLook.x - 90;
transform.localRotation = Quaternion.Euler(rot);
}
// we're in a hold; hide token count and show wave count
if (InPlay.tnhManager.Phase == TNH_Phase.Hold)
{
if (tokenCounter != null)
tokenCounter.SetActive(false);
if (waveCounter != null)
waveCounter.SetActive(true);
}
else // NOT in hold; do the inverse
{
if (tokenCounter != null)
tokenCounter.SetActive(true);
if (waveCounter != null)
waveCounter.SetActive(false);
}
}
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0d549cfce77855f4e9d9778d4c602f21
timeCreated: 1643333500
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,55 @@
using System.Reflection;
using HarmonyLib;
using UnityEngine;
using FistVR;
namespace TNHQoLImprovements
{
public enum HealthExpireIndicationType
{
None, Flashing, CircularGraphic
}
/// <summary>
/// If KillAfter is attached to a HealthCrystal, show visual representation of expiration.
/// </summary>
public static class TimedHealthCrystalPatch
{
private static GameObject timerAsset;
public const int VISUAL_APPROACH = 2;
public static void Patch(Harmony harmony)
{
timerAsset = MeatKitPlugin.bundle.LoadAsset<GameObject>("HealthCrystalTimer");
var original = typeof(KillAfter).GetMethod("Start", BindingFlags.NonPublic | BindingFlags.Instance);
var newfunc = typeof(TimedHealthCrystalPatch).GetMethod("Setup");
harmony.Patch(original, postfix: new HarmonyMethod(newfunc));
}
public static void Setup(KillAfter __instance)
{
// only work with Health Crystals
if (__instance.transform.GetComponentInChildren<HealthPickUp>() == null)
return;
GameObject timer;
Transform healthCrystal = __instance.transform.Find("HealthCrystal");
switch (MeatKitPlugin.cfgHealthCrystalIndicator.Value)
{
case HealthExpireIndicationType.CircularGraphic: // ring above
timer = GameObject.Instantiate<GameObject>(timerAsset, healthCrystal);
timer.GetComponent<UIRingTimer>().Init(__instance.DieTime);
timer.transform.localScale = new Vector2(0.001f, 0.001f);
timer.transform.localPosition = new Vector3(0, .9f, 0);
// TODO: disable scoring?
break;
case HealthExpireIndicationType.Flashing: // flashing crystal
var flicker = healthCrystal.gameObject.AddComponent<MeshRendererFlicker>();
flicker.Init(.6f, .7f, __instance.DieTime - 3);
break;
}
}
}
}
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: e2d8d57a4a90c704da061837b5f7b16a
timeCreated: 1643082249
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+9 -9
View File
@@ -1,18 +1,18 @@
using System.Collections; using System.Collections;
using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.UI; using UnityEngine.UI;
using FistVR;
namespace TNHQoLImprovements namespace TNHQoLImprovements
{ {
public class TokenCounter : MonoBehaviour public class TokenCounter : MonoBehaviour
{ {
private Text text;
void Start() void Start()
{ {
transform.parent = GameObject.Find("_NewTAHReticle/TAHReticle_HealthBar").transform; text = transform.GetChild(1).GetComponent<Text>();
transform.localPosition = new Vector3(1, 0, -.5f); text.font = MeatKitPlugin.fontAgencyFB;
transform.localRotation = Quaternion.Euler(90, 0, 0);
transform.localScale = new Vector3(0.002f, 0.002f, 0.002f);
StartCoroutine(SetTokenImage()); StartCoroutine(SetTokenImage());
} }
@@ -21,7 +21,7 @@ namespace TNHQoLImprovements
{ {
int debug_iterations = 0; int debug_iterations = 0;
Sprite tokenSprite = null; Sprite tokenSprite = null;
while (tokenSprite == null) // END: loop until Token sprite is found while (tokenSprite == null) // loop until Token sprite is found
{ {
var obj = GameObject.Find("_TNH_ObjectConstructor(Clone)/_CanvasHolder/_UITest_Canvas/Icon_0/Cost_1/Image"); var obj = GameObject.Find("_TNH_ObjectConstructor(Clone)/_CanvasHolder/_UITest_Canvas/Icon_0/Cost_1/Image");
if (obj != null) if (obj != null)
@@ -31,17 +31,17 @@ namespace TNHQoLImprovements
else else
{ {
debug_iterations++; debug_iterations++;
yield return new WaitForSeconds(0.25f); yield return new WaitForEndOfFrame();
} }
} }
Debug.Log("Token sprite found after " + debug_iterations.ToString() + " iterations."); //Debug.Log("Token sprite found after " + debug_iterations.ToString() + " iterations.");
transform.GetChild(0).GetComponent<Image>().sprite = tokenSprite; transform.GetChild(0).GetComponent<Image>().sprite = tokenSprite;
} }
void Update() void Update()
{ {
int tokens = InPlay.tnhManager.GetNumTokens(); int tokens = InPlay.tnhManager.GetNumTokens();
transform.GetChild(1).GetComponent<Text>().text = tokens.ToString(); text.text = tokens.ToString();
} }
} }
} }
+35
View File
@@ -0,0 +1,35 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIRingTimer : MonoBehaviour {
private bool initialized = false;
private float endTime;
private float length;
private Image ringImg;
private void Start()
{
ringImg = GetComponentInChildren<Image>();
}
public void Init(float timeInSeconds)
{
length = timeInSeconds;
endTime = Time.time + length;
initialized = true;
}
void Update () {
if (!initialized)
return;
float amount = (endTime - Time.time) / length;
ringImg.fillAmount = Mathf.Clamp01(amount);
transform.LookAt(MeatKitPlugin.playerCamera.transform);
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c0cc182175a3417499d53e43378f028c
timeCreated: 1643099834
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+39
View File
@@ -0,0 +1,39 @@
using HarmonyLib;
using UnityEngine;
using UnityEngine.UI;
using FistVR;
namespace TNHQoLImprovements
{
public class WaveCounter : MonoBehaviour
{
private TNH_HoldPoint curHoldPoint;
private Traverse<int> trCurPhaseIdx;
private Traverse<int> trMaxPhases;
private Text text;
// Use this for initialization
void Start()
{
transform.GetChild(0).GetComponent<Text>().font = MeatKitPlugin.fontAgencyFB;
text = transform.GetChild(1).GetComponent<Text>();
text.font = MeatKitPlugin.fontAgencyFB;
}
// Update is called once per frame
void Update()
{
if (InPlay.tnhManager.Phase != TNH_Phase.Hold)
return;
if(!ReferenceEquals(curHoldPoint, InPlay.tnhManager.m_curHoldPoint))
{
curHoldPoint = InPlay.tnhManager.m_curHoldPoint;
trCurPhaseIdx = Traverse.Create(curHoldPoint).Field<int>("m_phaseIndex");
trMaxPhases = Traverse.Create(curHoldPoint).Field<int>("m_maxPhases");
}
text.text = string.Format("{0} / {1}", trCurPhaseIdx.Value, trMaxPhases.Value);
}
}
}
+12
View File
@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c0c3423ff90fccc45bc00c97177b33fb
timeCreated: 1643271842
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+9
View File
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 202273f3dee1d244dbfc63238c672310
folderAsset: yes
timeCreated: 1643099086
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

+76
View File
@@ -0,0 +1,76 @@
fileFormatVersion: 2
guid: 3677786155d617b4cb39bf42eddd24ad
timeCreated: 1643099089
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 0
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 0
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
filterMode: -1
aniso: -1
mipBias: -1
wrapMode: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 1
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 1
spriteTessellationDetail: -1
textureType: 8
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
textureFormat: -1
textureCompression: 1
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
+10 -4
View File
@@ -3,16 +3,22 @@ A *Hot Dogs, Horseshoes, and Hand Grenades* mod that adds quality of life improv
Get it on [Thunderstore](https://h3vr.thunderstore.io/package/muskit/TNH_Quality_of_Life_Improvements/). Get it on [Thunderstore](https://h3vr.thunderstore.io/package/muskit/TNH_Quality_of_Life_Improvements/).
## Features ## Features (check Thunderstore for up-to-date list)
More visible HP counter<br/> More visible HP counter<br/>
<img src=preview/hp.png> <img src=preview/hp.png>
Token and hold counter on wrist<br/> Less visible HP counter when aiming around it<br/>
<img src=preview/stats.png> <img src=preview/aimhide.png>
Useful contextual game stats on radar hand<br/>
<img src=preview/stats_new.png>
Numbered tokens at item stations<br/>
<img src="preview/item station.png">
Player count for online leaderboards (won't work w/ *TNHTweaker* installed)<br/> Player count for online leaderboards (won't work w/ *TNHTweaker* installed)<br/>
<img src=preview/leaderboard.png><br/> <img src=preview/leaderboard.png><br/>
Features are modifiable via the mod manager's *Config editor*. Features are modifiable via the mod manager's *Config editor*.
**NOTE: [*TNH Leaderboard Player Count*](https://github.com/muskit/TNH-Leaderboard-Player-Count/) has been merged with this mod.** **This mod is built on [MeatKit](https://github.com/H3VR-Modding/MeatKit).**
Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB