Version 4.7 - Radial Menu
Add a new button-"Radial Menu (Z)" instead of "Recall (B)"
This commit is contained in:
@@ -51,6 +51,7 @@ namespace DevourClient
|
|||||||
public static float exp = 1000f;
|
public static float exp = 1000f;
|
||||||
public static bool _walkInLobby = false;
|
public static bool _walkInLobby = false;
|
||||||
public static bool infinite_mirrors = false;
|
public static bool infinite_mirrors = false;
|
||||||
|
static bool radialMenuEnabled = true;
|
||||||
static bool player_esp = false;
|
static bool player_esp = false;
|
||||||
static bool player_skel_esp = false;
|
static bool player_skel_esp = false;
|
||||||
static bool player_snapline = false;
|
static bool player_snapline = false;
|
||||||
@@ -188,11 +189,9 @@ namespace DevourClient
|
|||||||
fly = !fly;
|
fly = !fly;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recall to base position (B key, only if enabled)
|
// Z-key radial menu logic is managed by RadialMenuManager
|
||||||
if (recallEnabled && Input.GetKeyDown(KeyCode.B) && Player.IsInGameOrLobby())
|
RadialMenuManager.Enabled = radialMenuEnabled;
|
||||||
{
|
RadialMenuManager.HandleUpdate();
|
||||||
Helpers.RecallHelper.RecallToBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Player.IsInGameOrLobby())
|
if (Player.IsInGameOrLobby())
|
||||||
{
|
{
|
||||||
@@ -607,12 +606,15 @@ namespace DevourClient
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// End of EventType.Repaint branch
|
||||||
|
}
|
||||||
|
|
||||||
if (crosshair && in_game_cache)
|
if (crosshair && in_game_cache)
|
||||||
{
|
{
|
||||||
const float crosshairSize = 4;
|
const float crosshairSize = 4f;
|
||||||
|
|
||||||
float xMin = (Settings.Settings.width) - (crosshairSize / 2);
|
float xMin = Settings.Settings.width - (crosshairSize / 2f);
|
||||||
float yMin = (Settings.Settings.height) - (crosshairSize / 2);
|
float yMin = Settings.Settings.height - (crosshairSize / 2f);
|
||||||
|
|
||||||
if (crosshairTexture == null)
|
if (crosshairTexture == null)
|
||||||
{
|
{
|
||||||
@@ -622,7 +624,8 @@ namespace DevourClient
|
|||||||
GUI.DrawTexture(new Rect(xMin, yMin, crosshairSize, crosshairSize), crosshairTexture);
|
GUI.DrawTexture(new Rect(xMin, yMin, crosshairSize, crosshairSize), crosshairTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
// Radial menu rendering
|
||||||
|
RadialMenuManager.HandleOnGUI();
|
||||||
|
|
||||||
if (Settings.Settings.menu_enable)
|
if (Settings.Settings.menu_enable)
|
||||||
{
|
{
|
||||||
@@ -2028,14 +2031,14 @@ namespace DevourClient
|
|||||||
_walkInLobby = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 155, 140, 20), _walkInLobby, MultiLanguageSystem.Translate("Walk In Lobby"));
|
_walkInLobby = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 155, 140, 20), _walkInLobby, MultiLanguageSystem.Translate("Walk In Lobby"));
|
||||||
_IsAutoRespawn = GUI.Toggle(new Rect(Settings.Settings.x + 160, Settings.Settings.y + 155, 140, 20), _IsAutoRespawn, MultiLanguageSystem.Translate("Auto Respawn"));
|
_IsAutoRespawn = GUI.Toggle(new Rect(Settings.Settings.x + 160, Settings.Settings.y + 155, 140, 20), _IsAutoRespawn, MultiLanguageSystem.Translate("Auto Respawn"));
|
||||||
|
|
||||||
fly = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 190, 100, 20), fly, MultiLanguageSystem.Translate("Fly"));
|
fly = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 180, 100, 20), fly, MultiLanguageSystem.Translate("Fly"));
|
||||||
if (GUI.Button(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 190, 60, 20), Settings.Settings.flyKey.ToString()))
|
if (GUI.Button(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 180, 60, 20), Settings.Settings.flyKey.ToString()))
|
||||||
{
|
{
|
||||||
Settings.Settings.flyKey = Settings.Settings.GetKey();
|
Settings.Settings.flyKey = Settings.Settings.GetKey();
|
||||||
}
|
}
|
||||||
GUI.Label(new Rect(Settings.Settings.x + 20, Settings.Settings.y + 215, 80, 20), MultiLanguageSystem.Translate("Fly Speed") + ":");
|
GUI.Label(new Rect(Settings.Settings.x + 20, Settings.Settings.y + 205, 80, 20), MultiLanguageSystem.Translate("Fly Speed") + ":");
|
||||||
fly_speed = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 100, Settings.Settings.y + 220, 150, 10), fly_speed, 5f, 20f);
|
fly_speed = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 100, Settings.Settings.y + 210, 150, 10), fly_speed, 5f, 20f);
|
||||||
GUI.Label(new Rect(Settings.Settings.x + 260, Settings.Settings.y + 215, 50, 20), ((int)fly_speed).ToString());
|
GUI.Label(new Rect(Settings.Settings.x + 260, Settings.Settings.y + 205, 50, 20), ((int)fly_speed).ToString());
|
||||||
|
|
||||||
spoofLevel = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 250, 200, 20), spoofLevel, MultiLanguageSystem.Translate("Spoof Level"));
|
spoofLevel = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 250, 200, 20), spoofLevel, MultiLanguageSystem.Translate("Spoof Level"));
|
||||||
GUI.Label(new Rect(Settings.Settings.x + 20, Settings.Settings.y + 275, 80, 20), MultiLanguageSystem.Translate("Level") + ":");
|
GUI.Label(new Rect(Settings.Settings.x + 20, Settings.Settings.y + 275, 80, 20), MultiLanguageSystem.Translate("Level") + ":");
|
||||||
@@ -2054,7 +2057,7 @@ namespace DevourClient
|
|||||||
|
|
||||||
showCoordinates = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 430, 200, 20), showCoordinates, MultiLanguageSystem.Translate("Show Coordinates"));
|
showCoordinates = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 430, 200, 20), showCoordinates, MultiLanguageSystem.Translate("Show Coordinates"));
|
||||||
|
|
||||||
recallEnabled = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 455, 200, 20), recallEnabled, MultiLanguageSystem.Translate("Recall (B)"));
|
radialMenuEnabled = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 455, 200, 20), radialMenuEnabled, MultiLanguageSystem.Translate("Radial Menu (Z)"));
|
||||||
|
|
||||||
// Display player coordinates at the bottom of Misc tab
|
// Display player coordinates at the bottom of Misc tab
|
||||||
if (showCoordinates && Player.IsInGameOrLobby())
|
if (showCoordinates && Player.IsInGameOrLobby())
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ using System.Collections.Generic;
|
|||||||
|
|
||||||
namespace DevourClient.ESP
|
namespace DevourClient.ESP
|
||||||
{
|
{
|
||||||
/// <summary>
|
// Item ESP configuration management class - dynamically display different item types based on map
|
||||||
/// Item ESP configuration management class - dynamically display different item types based on map
|
|
||||||
/// </summary>
|
|
||||||
public static class ItemESPConfig
|
public static class ItemESPConfig
|
||||||
{
|
{
|
||||||
// ESP type enumeration
|
// ESP type enumeration
|
||||||
@@ -260,9 +258,6 @@ namespace DevourClient.ESP
|
|||||||
{ ESPType.Collectables, false }
|
{ ESPType.Collectables, false }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get list of ESP types supported by specified map
|
|
||||||
/// </summary>
|
|
||||||
public static List<ESPType> GetMapESPTypes(string sceneName)
|
public static List<ESPType> GetMapESPTypes(string sceneName)
|
||||||
{
|
{
|
||||||
// If in menu, return empty list
|
// If in menu, return empty list
|
||||||
@@ -284,35 +279,23 @@ namespace DevourClient.ESP
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get ESP type enable status
|
|
||||||
/// </summary>
|
|
||||||
public static bool GetESPState(ESPType type)
|
public static bool GetESPState(ESPType type)
|
||||||
{
|
{
|
||||||
return espStates.ContainsKey(type) ? espStates[type] : false;
|
return espStates.ContainsKey(type) ? espStates[type] : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set ESP type enable status
|
|
||||||
/// </summary>
|
|
||||||
public static void SetESPState(ESPType type, bool enabled)
|
public static void SetESPState(ESPType type, bool enabled)
|
||||||
{
|
{
|
||||||
if (espStates.ContainsKey(type))
|
if (espStates.ContainsKey(type))
|
||||||
espStates[type] = enabled;
|
espStates[type] = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Toggle ESP type enable status
|
|
||||||
/// </summary>
|
|
||||||
public static void ToggleESPState(ESPType type)
|
public static void ToggleESPState(ESPType type)
|
||||||
{
|
{
|
||||||
if (espStates.ContainsKey(type))
|
if (espStates.ContainsKey(type))
|
||||||
espStates[type] = !espStates[type];
|
espStates[type] = !espStates[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get ESP type display name (for translation key)
|
|
||||||
/// </summary>
|
|
||||||
public static string GetESPTypeName(ESPType type)
|
public static string GetESPTypeName(ESPType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
@@ -420,9 +403,6 @@ namespace DevourClient.ESP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get corresponding ESP type based on item name
|
|
||||||
/// </summary>
|
|
||||||
public static ESPType? GetESPTypeByItemName(string itemName)
|
public static ESPType? GetESPTypeByItemName(string itemName)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(itemName))
|
if (string.IsNullOrEmpty(itemName))
|
||||||
@@ -617,9 +597,6 @@ namespace DevourClient.ESP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if ESP should be shown for specified item
|
|
||||||
/// </summary>
|
|
||||||
public static bool ShouldShowESP(string itemName)
|
public static bool ShouldShowESP(string itemName)
|
||||||
{
|
{
|
||||||
ESPType? espType = GetESPTypeByItemName(itemName);
|
ESPType? espType = GetESPTypeByItemName(itemName);
|
||||||
@@ -629,9 +606,6 @@ namespace DevourClient.ESP
|
|||||||
return GetESPState(espType.Value);
|
return GetESPState(espType.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Reset all ESP states
|
|
||||||
/// </summary>
|
|
||||||
public static void ResetAllStates()
|
public static void ResetAllStates()
|
||||||
{
|
{
|
||||||
var keys = new List<ESPType>(espStates.Keys);
|
var keys = new List<ESPType>(espStates.Keys);
|
||||||
|
|||||||
@@ -1,74 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
using MelonLoader;
|
|
||||||
|
|
||||||
namespace DevourClient.Helpers
|
|
||||||
{
|
|
||||||
public static class RecallHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Teleports the local player to the base coordinates of the current map
|
|
||||||
/// </summary>
|
|
||||||
public static void RecallToBase()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Il2Cpp.NolanBehaviour nb = Player.GetPlayer();
|
|
||||||
if (nb == null)
|
|
||||||
{
|
|
||||||
MelonLogger.Warning("Player not found!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
string sceneName = Map.GetActiveScene();
|
|
||||||
Vector3 targetPos = Vector3.zero;
|
|
||||||
string mapName = "";
|
|
||||||
|
|
||||||
// Map coordinates based on scene name
|
|
||||||
switch (sceneName)
|
|
||||||
{
|
|
||||||
case "Devour":
|
|
||||||
case "Anna": // Farmhouse
|
|
||||||
targetPos = new Vector3(5.03f, 4.20f, -50.02f);
|
|
||||||
mapName = "Farm";
|
|
||||||
break;
|
|
||||||
case "Molly": // Asylum
|
|
||||||
targetPos = new Vector3(17.52f, 1.38f, 7.04f);
|
|
||||||
mapName = "Asylum";
|
|
||||||
break;
|
|
||||||
case "Inn":
|
|
||||||
targetPos = new Vector3(3.53f, 0.84f, 2.47f);
|
|
||||||
mapName = "Inn";
|
|
||||||
break;
|
|
||||||
case "Town":
|
|
||||||
targetPos = new Vector3(-63.51f, 10.88f, -12.32f);
|
|
||||||
mapName = "Town";
|
|
||||||
break;
|
|
||||||
case "Slaughterhouse":
|
|
||||||
targetPos = new Vector3(6.09f, 0.70f, -17.58f);
|
|
||||||
mapName = "Slaughterhouse";
|
|
||||||
break;
|
|
||||||
case "Manor":
|
|
||||||
targetPos = new Vector3(3.67f, 1.32f, -23.34f);
|
|
||||||
mapName = "Manor";
|
|
||||||
break;
|
|
||||||
case "Carnival":
|
|
||||||
targetPos = new Vector3(-91.46f, 8.13f, -24.51f);
|
|
||||||
mapName = "Carnival";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MelonLogger.Warning($"Teleport not available for scene: {sceneName}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Teleport player to target position
|
|
||||||
nb.locomotion.SetPosition(targetPos, false);
|
|
||||||
MelonLogger.Msg($"Teleported to {mapName} coordinates: X:{targetPos.x:F2} Y:{targetPos.y:F2} Z:{targetPos.z:F2}");
|
|
||||||
}
|
|
||||||
catch (System.Exception ex)
|
|
||||||
{
|
|
||||||
MelonLogger.Error($"Failed to teleport: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -5,17 +5,13 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace DevourClient.Helpers
|
namespace DevourClient.Helpers
|
||||||
{
|
{
|
||||||
/// <summary>
|
// Shared revive utilities. When running as host we mirror DevourX's revive flow.
|
||||||
/// Shared revive utilities. When running as host we mirror DevourX's revive flow.
|
|
||||||
/// </summary>
|
|
||||||
public static class ReviveHelper
|
public static class ReviveHelper
|
||||||
{
|
{
|
||||||
private static readonly Vector3 HostFallbackPosition = new Vector3(0f, -150f, 0f);
|
private static readonly Vector3 HostFallbackPosition = new Vector3(0f, -150f, 0f);
|
||||||
|
|
||||||
/// <summary>
|
// Try to revive the provided NolanBehaviour using host-specific logic first,
|
||||||
/// Try to revive the provided NolanBehaviour using host-specific logic first,
|
// then fall back to the standard interactable flow.
|
||||||
/// then fall back to the standard interactable flow.
|
|
||||||
/// </summary>
|
|
||||||
public static bool TryRevive(Il2Cpp.NolanBehaviour target)
|
public static bool TryRevive(Il2Cpp.NolanBehaviour target)
|
||||||
{
|
{
|
||||||
if (target == null || target.gameObject == null)
|
if (target == null || target.gameObject == null)
|
||||||
@@ -88,11 +84,9 @@ namespace DevourClient.Helpers
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
// Legacy revive method migrated from StateHelper.BasePlayer.Revive().
|
||||||
/// Legacy revive method migrated from StateHelper.BasePlayer.Revive().
|
// This method preserves the original implementation from StateHelper.
|
||||||
/// This method preserves the original implementation from StateHelper.
|
// targetGameObject: The GameObject of the player to revive.
|
||||||
/// </summary>
|
|
||||||
/// <param name="targetGameObject">The GameObject of the player to revive</param>
|
|
||||||
public static void ReviveLegacy(GameObject targetGameObject)
|
public static void ReviveLegacy(GameObject targetGameObject)
|
||||||
{
|
{
|
||||||
if (targetGameObject == null)
|
if (targetGameObject == null)
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "老鼠透视" },
|
{ "Rat ESP", "老鼠透视" },
|
||||||
{ "Region", "区域" },
|
{ "Region", "区域" },
|
||||||
{ "Revive", "复活" },
|
{ "Revive", "复活" },
|
||||||
|
{ "Radial Menu (Z)", "轮盘菜单 (Z)" },
|
||||||
{ "Ritual Book", "仪式书" },
|
{ "Ritual Book", "仪式书" },
|
||||||
{ "Rose", "玫瑰" },
|
{ "Rose", "玫瑰" },
|
||||||
{ "Ritual Book ESP", "仪式书透视" },
|
{ "Ritual Book ESP", "仪式书透视" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "传送到 Azazel" },
|
{ "TP to Azazel", "传送到 Azazel" },
|
||||||
{ "TV", "电视" },
|
{ "TV", "电视" },
|
||||||
{ "Teleport Keys", "传送钥匙" },
|
{ "Teleport Keys", "传送钥匙" },
|
||||||
{ "Recall (B)", "回城 (B)" },
|
|
||||||
{ "Teleport to", "传送至" },
|
{ "Teleport to", "传送至" },
|
||||||
|
{ "TP Base", "传送至基地" },
|
||||||
|
{ "TP Altar", "传送至祭坛" },
|
||||||
|
{ "TP Basin", "传送至水池" },
|
||||||
|
{ "TP Fountain", "传送至喷泉" },
|
||||||
{ "Ticket", "票券" },
|
{ "Ticket", "票券" },
|
||||||
{ "Town", "小镇" },
|
{ "Town", "小镇" },
|
||||||
{ "TownDoor", "小镇门" },
|
{ "TownDoor", "小镇门" },
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "Rat ESP" },
|
{ "Rat ESP", "Rat ESP" },
|
||||||
{ "Region", "Region" },
|
{ "Region", "Region" },
|
||||||
{ "Revive", "Revive" },
|
{ "Revive", "Revive" },
|
||||||
|
{ "Radial Menu (Z)", "Radial Menu (Z)" },
|
||||||
{ "Ritual Book", "Ritual Book" },
|
{ "Ritual Book", "Ritual Book" },
|
||||||
{ "Rose", "Rose" },
|
{ "Rose", "Rose" },
|
||||||
{ "Ritual Book ESP", "Ritual Book ESP" },
|
{ "Ritual Book ESP", "Ritual Book ESP" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "TP to Azazel" },
|
{ "TP to Azazel", "TP to Azazel" },
|
||||||
{ "TV", "TV" },
|
{ "TV", "TV" },
|
||||||
{ "Teleport Keys", "Teleport Keys" },
|
{ "Teleport Keys", "Teleport Keys" },
|
||||||
{ "Recall (B)", "Recall (B)" },
|
|
||||||
{ "Teleport to", "Teleport to" },
|
{ "Teleport to", "Teleport to" },
|
||||||
|
{ "TP Base", "TP Base" },
|
||||||
|
{ "TP Altar", "TP Altar" },
|
||||||
|
{ "TP Basin", "TP Basin" },
|
||||||
|
{ "TP Fountain", "TP Fountain" },
|
||||||
{ "Ticket", "Ticket" },
|
{ "Ticket", "Ticket" },
|
||||||
{ "Town", "Town" },
|
{ "Town", "Town" },
|
||||||
{ "TownDoor", "TownDoor" },
|
{ "TownDoor", "TownDoor" },
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "ESP rat" },
|
{ "Rat ESP", "ESP rat" },
|
||||||
{ "Region", "Région" },
|
{ "Region", "Région" },
|
||||||
{ "Revive", "Réanimer" },
|
{ "Revive", "Réanimer" },
|
||||||
|
{ "Radial Menu (Z)", "Menu radial (Z)" },
|
||||||
{ "Ritual Book", "Livre rituel" },
|
{ "Ritual Book", "Livre rituel" },
|
||||||
{ "Rose", "Rose" },
|
{ "Rose", "Rose" },
|
||||||
{ "Ritual Book ESP", "ESP livre rituel" },
|
{ "Ritual Book ESP", "ESP livre rituel" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "TP vers Azazel" },
|
{ "TP to Azazel", "TP vers Azazel" },
|
||||||
{ "TV", "Télévision" },
|
{ "TV", "Télévision" },
|
||||||
{ "Teleport Keys", "Téléporter clés" },
|
{ "Teleport Keys", "Téléporter clés" },
|
||||||
{ "Recall (B)", "Retour (B)" },
|
|
||||||
{ "Teleport to", "Téléporter" },
|
{ "Teleport to", "Téléporter" },
|
||||||
|
{ "TP Base", "TP base" },
|
||||||
|
{ "TP Altar", "TP autel" },
|
||||||
|
{ "TP Basin", "TP bassin" },
|
||||||
|
{ "TP Fountain", "TP fontaine" },
|
||||||
{ "Ticket", "Billet" },
|
{ "Ticket", "Billet" },
|
||||||
{ "Town", "Ville" },
|
{ "Town", "Ville" },
|
||||||
{ "TownDoor", "Porte de ville" },
|
{ "TownDoor", "Porte de ville" },
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "Ratte-ESP" },
|
{ "Rat ESP", "Ratte-ESP" },
|
||||||
{ "Region", "Region" },
|
{ "Region", "Region" },
|
||||||
{ "Revive", "Wiederbeleben" },
|
{ "Revive", "Wiederbeleben" },
|
||||||
|
{ "Radial Menu (Z)", "Radiales Menü (Z)" },
|
||||||
{ "Ritual Book", "Ritualbuch" },
|
{ "Ritual Book", "Ritualbuch" },
|
||||||
{ "Rose", "Rose" },
|
{ "Rose", "Rose" },
|
||||||
{ "Ritual Book ESP", "Ritualbuch-ESP" },
|
{ "Ritual Book ESP", "Ritualbuch-ESP" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "TP zu Azazel" },
|
{ "TP to Azazel", "TP zu Azazel" },
|
||||||
{ "TV", "Fernseher" },
|
{ "TV", "Fernseher" },
|
||||||
{ "Teleport Keys", "Schlüssel teleportieren" },
|
{ "Teleport Keys", "Schlüssel teleportieren" },
|
||||||
{ "Recall (B)", "Zurückrufen (B)" },
|
|
||||||
{ "Teleport to", "Teleportieren" },
|
{ "Teleport to", "Teleportieren" },
|
||||||
|
{ "TP Base", "TP Basis" },
|
||||||
|
{ "TP Altar", "TP Altar" },
|
||||||
|
{ "TP Basin", "TP Becken" },
|
||||||
|
{ "TP Fountain", "TP Brunnen" },
|
||||||
{ "Ticket", "Ticket" },
|
{ "Ticket", "Ticket" },
|
||||||
{ "Town", "Stadt" },
|
{ "Town", "Stadt" },
|
||||||
{ "TownDoor", "Stadttür" },
|
{ "TownDoor", "Stadttür" },
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "ESP ratto" },
|
{ "Rat ESP", "ESP ratto" },
|
||||||
{ "Region", "Regione" },
|
{ "Region", "Regione" },
|
||||||
{ "Revive", "Rianima" },
|
{ "Revive", "Rianima" },
|
||||||
|
{ "Radial Menu (Z)", "Menu radiale (Z)" },
|
||||||
{ "Ritual Book", "Libro rituale" },
|
{ "Ritual Book", "Libro rituale" },
|
||||||
{ "Rose", "Rosa" },
|
{ "Rose", "Rosa" },
|
||||||
{ "Ritual Book ESP", "ESP libro rituale" },
|
{ "Ritual Book ESP", "ESP libro rituale" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "TP ad Azazel" },
|
{ "TP to Azazel", "TP ad Azazel" },
|
||||||
{ "TV", "Televisione" },
|
{ "TV", "Televisione" },
|
||||||
{ "Teleport Keys", "Teletrasporta chiavi" },
|
{ "Teleport Keys", "Teletrasporta chiavi" },
|
||||||
{ "Recall (B)", "Richiama (B)" },
|
|
||||||
{ "Teleport to", "Teletrasporta" },
|
{ "Teleport to", "Teletrasporta" },
|
||||||
|
{ "TP Base", "TP Base" },
|
||||||
|
{ "TP Altar", "TP Altare" },
|
||||||
|
{ "TP Basin", "TP Bacino" },
|
||||||
|
{ "TP Fountain", "TP Fontana" },
|
||||||
{ "Ticket", "Biglietto" },
|
{ "Ticket", "Biglietto" },
|
||||||
{ "Town", "Città" },
|
{ "Town", "Città" },
|
||||||
{ "TownDoor", "Porta della città" },
|
{ "TownDoor", "Porta della città" },
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "ネズミESP" },
|
{ "Rat ESP", "ネズミESP" },
|
||||||
{ "Region", "地域" },
|
{ "Region", "地域" },
|
||||||
{ "Revive", "蘇生" },
|
{ "Revive", "蘇生" },
|
||||||
|
{ "Radial Menu (Z)", "ラジアルメニュー (Z)" },
|
||||||
{ "Ritual Book", "儀式の本" },
|
{ "Ritual Book", "儀式の本" },
|
||||||
{ "Rose", "バラ" },
|
{ "Rose", "バラ" },
|
||||||
{ "Ritual Book ESP", "儀式の本ESP" },
|
{ "Ritual Book ESP", "儀式の本ESP" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "Azazelへテレポート" },
|
{ "TP to Azazel", "Azazelへテレポート" },
|
||||||
{ "TV", "テレビ" },
|
{ "TV", "テレビ" },
|
||||||
{ "Teleport Keys", "鍵をテレポート" },
|
{ "Teleport Keys", "鍵をテレポート" },
|
||||||
{ "Recall (B)", "リコール (B)" },
|
|
||||||
{ "Teleport to", "テレポート" },
|
{ "Teleport to", "テレポート" },
|
||||||
|
{ "TP Base", "ベースTP" },
|
||||||
|
{ "TP Altar", "祭壇TP" },
|
||||||
|
{ "TP Basin", "水盤TP" },
|
||||||
|
{ "TP Fountain", "噴水TP" },
|
||||||
{ "Ticket", "チケット" },
|
{ "Ticket", "チケット" },
|
||||||
{ "Town", "町" },
|
{ "Town", "町" },
|
||||||
{ "TownDoor", "町のドア" },
|
{ "TownDoor", "町のドア" },
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "쥐 ESP" },
|
{ "Rat ESP", "쥐 ESP" },
|
||||||
{ "Region", "지역" },
|
{ "Region", "지역" },
|
||||||
{ "Revive", "부활" },
|
{ "Revive", "부활" },
|
||||||
|
{ "Radial Menu (Z)", "방사형 메뉴 (Z)" },
|
||||||
{ "Ritual Book", "의식서" },
|
{ "Ritual Book", "의식서" },
|
||||||
{ "Rose", "장미" },
|
{ "Rose", "장미" },
|
||||||
{ "Ritual Book ESP", "의식서 ESP" },
|
{ "Ritual Book ESP", "의식서 ESP" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "Azazel로 텔레포트" },
|
{ "TP to Azazel", "Azazel로 텔레포트" },
|
||||||
{ "TV", "TV" },
|
{ "TV", "TV" },
|
||||||
{ "Teleport Keys", "열쇠 텔레포트" },
|
{ "Teleport Keys", "열쇠 텔레포트" },
|
||||||
{ "Recall (B)", "리콜 (B)" },
|
|
||||||
{ "Teleport to", "텔레포트" },
|
{ "Teleport to", "텔레포트" },
|
||||||
|
{ "TP Base", "기지 TP" },
|
||||||
|
{ "TP Altar", "제단 TP" },
|
||||||
|
{ "TP Basin", "대야 TP" },
|
||||||
|
{ "TP Fountain", "분수 TP" },
|
||||||
{ "Ticket", "티켓" },
|
{ "Ticket", "티켓" },
|
||||||
{ "Town", "마을" },
|
{ "Town", "마을" },
|
||||||
{ "TownDoor", "마을 문" },
|
{ "TownDoor", "마을 문" },
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "ESP rato" },
|
{ "Rat ESP", "ESP rato" },
|
||||||
{ "Region", "Região" },
|
{ "Region", "Região" },
|
||||||
{ "Revive", "Reviver" },
|
{ "Revive", "Reviver" },
|
||||||
|
{ "Radial Menu (Z)", "Menu radial (Z)" },
|
||||||
{ "Ritual Book", "Livro ritual" },
|
{ "Ritual Book", "Livro ritual" },
|
||||||
{ "Rose", "Rosa" },
|
{ "Rose", "Rosa" },
|
||||||
{ "Ritual Book ESP", "ESP livro ritual" },
|
{ "Ritual Book ESP", "ESP livro ritual" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "TP para Azazel" },
|
{ "TP to Azazel", "TP para Azazel" },
|
||||||
{ "TV", "Televisão" },
|
{ "TV", "Televisão" },
|
||||||
{ "Teleport Keys", "Teletransportar chaves" },
|
{ "Teleport Keys", "Teletransportar chaves" },
|
||||||
{ "Recall (B)", "Recuar (B)" },
|
|
||||||
{ "Teleport to", "Teletransportar" },
|
{ "Teleport to", "Teletransportar" },
|
||||||
|
{ "TP Base", "TP base" },
|
||||||
|
{ "TP Altar", "TP altar" },
|
||||||
|
{ "TP Basin", "TP bacia" },
|
||||||
|
{ "TP Fountain", "TP fonte" },
|
||||||
{ "Ticket", "Bilhete" },
|
{ "Ticket", "Bilhete" },
|
||||||
{ "Town", "Cidade" },
|
{ "Town", "Cidade" },
|
||||||
{ "TownDoor", "Porta da cidade" },
|
{ "TownDoor", "Porta da cidade" },
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "ESP крысы" },
|
{ "Rat ESP", "ESP крысы" },
|
||||||
{ "Region", "Регион" },
|
{ "Region", "Регион" },
|
||||||
{ "Revive", "Воскресить" },
|
{ "Revive", "Воскресить" },
|
||||||
|
{ "Radial Menu (Z)", "Радиальное меню (Z)" },
|
||||||
{ "Ritual Book", "Ритуальная книга" },
|
{ "Ritual Book", "Ритуальная книга" },
|
||||||
{ "Rose", "Роза" },
|
{ "Rose", "Роза" },
|
||||||
{ "Ritual Book ESP", "ESP ритуальной книги" },
|
{ "Ritual Book ESP", "ESP ритуальной книги" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "ТП к Azazel" },
|
{ "TP to Azazel", "ТП к Azazel" },
|
||||||
{ "TV", "Телевизор" },
|
{ "TV", "Телевизор" },
|
||||||
{ "Teleport Keys", "Телепорт ключей" },
|
{ "Teleport Keys", "Телепорт ключей" },
|
||||||
{ "Recall (B)", "Возврат (B)" },
|
|
||||||
{ "Teleport to", "Телепорт" },
|
{ "Teleport to", "Телепорт" },
|
||||||
|
{ "TP Base", "ТП база" },
|
||||||
|
{ "TP Altar", "ТП алтарь" },
|
||||||
|
{ "TP Basin", "ТП чаша" },
|
||||||
|
{ "TP Fountain", "ТП фонтан" },
|
||||||
{ "Ticket", "Билет" },
|
{ "Ticket", "Билет" },
|
||||||
{ "Town", "Город" },
|
{ "Town", "Город" },
|
||||||
{ "TownDoor", "Дверь города" },
|
{ "TownDoor", "Дверь города" },
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "ESP rata" },
|
{ "Rat ESP", "ESP rata" },
|
||||||
{ "Region", "Región" },
|
{ "Region", "Región" },
|
||||||
{ "Revive", "Revivir" },
|
{ "Revive", "Revivir" },
|
||||||
|
{ "Radial Menu (Z)", "Menú radial (Z)" },
|
||||||
{ "Ritual Book", "Libro ritual" },
|
{ "Ritual Book", "Libro ritual" },
|
||||||
{ "Rose", "Rosa" },
|
{ "Rose", "Rosa" },
|
||||||
{ "Ritual Book ESP", "ESP libro ritual" },
|
{ "Ritual Book ESP", "ESP libro ritual" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "TP a Azazel" },
|
{ "TP to Azazel", "TP a Azazel" },
|
||||||
{ "TV", "Televisión" },
|
{ "TV", "Televisión" },
|
||||||
{ "Teleport Keys", "Teletransportar llaves" },
|
{ "Teleport Keys", "Teletransportar llaves" },
|
||||||
{ "Recall (B)", "Regresar (B)" },
|
|
||||||
{ "Teleport to", "Teletransportar" },
|
{ "Teleport to", "Teletransportar" },
|
||||||
|
{ "TP Base", "TP base" },
|
||||||
|
{ "TP Altar", "TP altar" },
|
||||||
|
{ "TP Basin", "TP pila" },
|
||||||
|
{ "TP Fountain", "TP fuente" },
|
||||||
{ "Ticket", "Boleto" },
|
{ "Ticket", "Boleto" },
|
||||||
{ "Town", "Pueblo" },
|
{ "Town", "Pueblo" },
|
||||||
{ "TownDoor", "Puerta de pueblo" },
|
{ "TownDoor", "Puerta de pueblo" },
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "Rat ESP", "Chuột ESP" },
|
{ "Rat ESP", "Chuột ESP" },
|
||||||
{ "Region", "Khu vực" },
|
{ "Region", "Khu vực" },
|
||||||
{ "Revive", "Hồi sinh" },
|
{ "Revive", "Hồi sinh" },
|
||||||
|
{ "Radial Menu (Z)", "Menu vòng tròn (Z)" },
|
||||||
{ "Ritual Book", "Sách nghi lễ" },
|
{ "Ritual Book", "Sách nghi lễ" },
|
||||||
{ "Rose", "Hoa hồng" },
|
{ "Rose", "Hoa hồng" },
|
||||||
{ "Ritual Book ESP", "Sách nghi lễ ESP" },
|
{ "Ritual Book ESP", "Sách nghi lễ ESP" },
|
||||||
@@ -253,8 +254,11 @@ namespace DevourClient.Localization.Translations
|
|||||||
{ "TP to Azazel", "TP đến Azazel" },
|
{ "TP to Azazel", "TP đến Azazel" },
|
||||||
{ "TV", "TV" },
|
{ "TV", "TV" },
|
||||||
{ "Teleport Keys", "Phím dịch chuyển" },
|
{ "Teleport Keys", "Phím dịch chuyển" },
|
||||||
{ "Recall (B)", "Triệu hồi (B)" },
|
|
||||||
{ "Teleport to", "Dịch chuyển đến" },
|
{ "Teleport to", "Dịch chuyển đến" },
|
||||||
|
{ "TP Base", "TP căn cứ" },
|
||||||
|
{ "TP Altar", "TP bàn thờ" },
|
||||||
|
{ "TP Basin", "TP bể nước" },
|
||||||
|
{ "TP Fountain", "TP đài phun nước" },
|
||||||
{ "Ticket", "Vé" },
|
{ "Ticket", "Vé" },
|
||||||
{ "Town", "Town" },
|
{ "Town", "Town" },
|
||||||
{ "TownDoor", "TownDoor" },
|
{ "TownDoor", "TownDoor" },
|
||||||
|
|||||||
@@ -8,17 +8,13 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace DevourClient.Network
|
namespace DevourClient.Network
|
||||||
{
|
{
|
||||||
/// <summary>
|
// Lobby creation and management class
|
||||||
/// Lobby creation and management class
|
|
||||||
/// </summary>
|
|
||||||
public static class LobbyManager
|
public static class LobbyManager
|
||||||
{
|
{
|
||||||
/// <summary>
|
// Create game lobby/room.
|
||||||
/// Create game lobby/room
|
// regionCode: Region code (e.g.: "eu", "us", "asia", "usw", "sa", "jp", "au", "ru", "in", "kr").
|
||||||
/// </summary>
|
// lobbyLimit: Maximum player limit (1-64).
|
||||||
/// <param name="regionCode">Region code (e.g.: "eu", "us", "asia", "usw", "sa", "jp", "au", "ru", "in", "kr")</param>
|
// isPrivate: Whether this is a private room.
|
||||||
/// <param name="lobbyLimit">Maximum player limit (1-64)</param>
|
|
||||||
/// <param name="isPrivate">Whether this is a private room</param>
|
|
||||||
public static void CreateLobby(string regionCode, int lobbyLimit, bool isPrivate)
|
public static void CreateLobby(string regionCode, int lobbyLimit, bool isPrivate)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -96,9 +92,6 @@ namespace DevourClient.Network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Get PhotonRegion object for specified region
|
|
||||||
/// </summary>
|
|
||||||
private static PhotonRegion GetPhotonRegion(string regionCode)
|
private static PhotonRegion GetPhotonRegion(string regionCode)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -113,9 +106,6 @@ namespace DevourClient.Network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Find Menu controller
|
|
||||||
/// </summary>
|
|
||||||
private static Il2CppHorror.Menu FindMenuController()
|
private static Il2CppHorror.Menu FindMenuController()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -142,9 +132,6 @@ namespace DevourClient.Network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Check if in game
|
|
||||||
/// </summary>
|
|
||||||
private static bool IsInGame()
|
private static bool IsInGame()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -159,9 +146,6 @@ namespace DevourClient.Network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Force start lobby game (host only)
|
|
||||||
/// </summary>
|
|
||||||
public static void ForceLobbyStart()
|
public static void ForceLobbyStart()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -189,9 +173,6 @@ namespace DevourClient.Network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Show message box
|
|
||||||
/// </summary>
|
|
||||||
public static void ShowMessageBox(string message)
|
public static void ShowMessageBox(string message)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|||||||
698
DevourClient/RadialMenuManager.cs
Normal file
698
DevourClient/RadialMenuManager.cs
Normal file
@@ -0,0 +1,698 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using MelonLoader;
|
||||||
|
using UnityEngine;
|
||||||
|
using DevourClient.Helpers;
|
||||||
|
using DevourClient.Localization;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace DevourClient
|
||||||
|
{
|
||||||
|
// Manages the Z-key radial menu: building options, drawing the UI, and executing actions.
|
||||||
|
// Public static methods are called from the appropriate ClientMain lifecycle hooks.
|
||||||
|
internal static class RadialMenuManager
|
||||||
|
{
|
||||||
|
private static bool _active;
|
||||||
|
private static int _selectedIndex = -1;
|
||||||
|
private static readonly List<RadialOption> _options = new List<RadialOption>();
|
||||||
|
private static bool _cursorStateStored;
|
||||||
|
private static bool _prevCursorVisible;
|
||||||
|
private static CursorLockMode _prevCursorLockState;
|
||||||
|
private static bool _enabled = true; // Controls whether the radial menu is enabled
|
||||||
|
|
||||||
|
// Material used to draw radial arcs (GL immediate mode)
|
||||||
|
private static Material _radialMaterial;
|
||||||
|
|
||||||
|
// Public property to enable/disable the radial menu
|
||||||
|
public static bool Enabled
|
||||||
|
{
|
||||||
|
get => _enabled;
|
||||||
|
set => _enabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum RadialActionType
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
SpawnItem,
|
||||||
|
TeleportBase,
|
||||||
|
TeleportFixedPoint
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RadialOption
|
||||||
|
{
|
||||||
|
public string Label = string.Empty;
|
||||||
|
public RadialActionType ActionType = RadialActionType.None;
|
||||||
|
public string Payload = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called from Update: handles input, builds / closes the radial menu and executes actions.
|
||||||
|
public static void HandleUpdate()
|
||||||
|
{
|
||||||
|
if (!_enabled || !Player.IsInGameOrLobby())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Input.GetKeyDown(KeyCode.Z))
|
||||||
|
{
|
||||||
|
BuildForCurrentScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Input.GetKeyUp(KeyCode.Z) && _active)
|
||||||
|
{
|
||||||
|
if (_selectedIndex >= 0 && _selectedIndex < _options.Count)
|
||||||
|
{
|
||||||
|
ExecuteOption(_options[_selectedIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
_active = false;
|
||||||
|
_selectedIndex = -1;
|
||||||
|
_options.Clear();
|
||||||
|
|
||||||
|
RestoreCursorState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called from OnGUI: draws the radial menu if it is active.
|
||||||
|
public static void HandleOnGUI()
|
||||||
|
{
|
||||||
|
if (!_enabled || !_active || !Player.IsInGameOrLobby())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void BuildForCurrentScene()
|
||||||
|
{
|
||||||
|
_options.Clear();
|
||||||
|
_selectedIndex = -1;
|
||||||
|
|
||||||
|
string sceneName = Helpers.Map.GetActiveScene();
|
||||||
|
if (string.IsNullOrEmpty(sceneName) || sceneName == "Menu")
|
||||||
|
{
|
||||||
|
_active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("First aid"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalFirstAid"
|
||||||
|
});
|
||||||
|
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Battery"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalBattery"
|
||||||
|
});
|
||||||
|
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("TP Base"),
|
||||||
|
ActionType = RadialActionType.TeleportBase,
|
||||||
|
Payload = string.Empty
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (sceneName)
|
||||||
|
{
|
||||||
|
case "Devour":
|
||||||
|
case "Anna":
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("TP Altar"),
|
||||||
|
ActionType = RadialActionType.TeleportFixedPoint,
|
||||||
|
Payload = "8.57 0.01 -65.19"
|
||||||
|
});
|
||||||
|
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Hay"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalHay"
|
||||||
|
});
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Gasoline"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalGasoline"
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Molly":
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("TP Altar"),
|
||||||
|
ActionType = RadialActionType.TeleportFixedPoint,
|
||||||
|
Payload = "18.12 -8.80 21.06"
|
||||||
|
});
|
||||||
|
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Fuse"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalFuse"
|
||||||
|
});
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("RottenFood"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalRottenFood"
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Inn":
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("TP Fountain"),
|
||||||
|
ActionType = RadialActionType.TeleportFixedPoint,
|
||||||
|
Payload = "-3.43 0.06 24.31"
|
||||||
|
});
|
||||||
|
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Bleach"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalBleach"
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Town":
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("TP Altar"),
|
||||||
|
ActionType = RadialActionType.TeleportFixedPoint,
|
||||||
|
Payload = "-56.88 7.17 -34.51"
|
||||||
|
});
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Matchbox"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "Matchbox-3"
|
||||||
|
});
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Gasoline"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalGasoline"
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Slaughterhouse":
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("TP Altar"),
|
||||||
|
ActionType = RadialActionType.TeleportFixedPoint,
|
||||||
|
Payload = "26.68 4.01 -9.27"
|
||||||
|
});
|
||||||
|
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Bone"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalBone"
|
||||||
|
});
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Gasoline"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalGasoline"
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Manor":
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("TP Basin"),
|
||||||
|
ActionType = RadialActionType.TeleportFixedPoint,
|
||||||
|
Payload = "38.93 -4.62 -3.86"
|
||||||
|
});
|
||||||
|
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Bleach"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalBleach"
|
||||||
|
});
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Cake"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalCake"
|
||||||
|
});
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Spade"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalSpade"
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Carnival":
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("TP Altar"),
|
||||||
|
ActionType = RadialActionType.TeleportFixedPoint,
|
||||||
|
Payload = "-114.65 4.07 -4.12"
|
||||||
|
});
|
||||||
|
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("Coin"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalCoin"
|
||||||
|
});
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("MusicBox"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "MusicBox-Idle"
|
||||||
|
});
|
||||||
|
_options.Add(new RadialOption
|
||||||
|
{
|
||||||
|
Label = MultiLanguageSystem.Translate("DollHead"),
|
||||||
|
ActionType = RadialActionType.SpawnItem,
|
||||||
|
Payload = "SurvivalDollHead"
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_options.Count == 0)
|
||||||
|
{
|
||||||
|
_active = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_active = true;
|
||||||
|
HideCursorForRadial();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Draw()
|
||||||
|
{
|
||||||
|
Event e = Event.current;
|
||||||
|
if (e == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool isRepaint = e.type == EventType.Repaint;
|
||||||
|
|
||||||
|
float centerX = Screen.width / 2f;
|
||||||
|
float centerY = Screen.height / 2f;
|
||||||
|
Vector2 center = new Vector2(centerX, centerY);
|
||||||
|
|
||||||
|
float radiusOuter = 140f;
|
||||||
|
float radiusInner = 40f;
|
||||||
|
|
||||||
|
Vector2 mouse = e.mousePosition;
|
||||||
|
Vector2 dir = mouse - center;
|
||||||
|
float dist = dir.magnitude;
|
||||||
|
|
||||||
|
_selectedIndex = -1;
|
||||||
|
|
||||||
|
if (dist >= radiusInner && dist <= radiusOuter && _options.Count > 0)
|
||||||
|
{
|
||||||
|
// Normalize angles: convert GUI coordinates (y down) to math coordinates (y up)
|
||||||
|
// and treat "up" as 0° increasing clockwise.
|
||||||
|
Vector2 upDir = new Vector2(dir.x, -dir.y);
|
||||||
|
float mathAngle = Mathf.Atan2(upDir.y, upDir.x); // [-PI, PI], 0 is on the right, counterclockwise is positive
|
||||||
|
|
||||||
|
float logicalAngle = (Mathf.PI / 2f) - mathAngle;
|
||||||
|
if (logicalAngle < 0f)
|
||||||
|
{
|
||||||
|
logicalAngle += Mathf.PI * 2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float logicalSectorAngle = (Mathf.PI * 2f) / _options.Count;
|
||||||
|
int index = Mathf.Clamp(Mathf.FloorToInt(logicalAngle / logicalSectorAngle), 0, _options.Count - 1);
|
||||||
|
_selectedIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = _options.Count;
|
||||||
|
if (count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (isRepaint)
|
||||||
|
{
|
||||||
|
EnsureRadialMaterial();
|
||||||
|
DrawFilledCircle(center, radiusOuter + 6f, new Color(0f, 0f, 0f, 0.55f));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sector layout and label radius
|
||||||
|
float logicalAnglePerSector = (Mathf.PI * 2f) / count;
|
||||||
|
float radiusFactor;
|
||||||
|
if (count <= 6)
|
||||||
|
radiusFactor = 0.55f;
|
||||||
|
else if (count == 7)
|
||||||
|
radiusFactor = 0.48f;
|
||||||
|
else if (count <= 8)
|
||||||
|
radiusFactor = 0.5f;
|
||||||
|
else
|
||||||
|
radiusFactor = 0.45f;
|
||||||
|
float labelRadius = radiusInner + (radiusOuter - radiusInner) * radiusFactor;
|
||||||
|
|
||||||
|
if (isRepaint)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
float logicalStart = logicalAnglePerSector * i;
|
||||||
|
float logicalEnd = logicalAnglePerSector * (i + 1);
|
||||||
|
|
||||||
|
float displayStart = (Mathf.PI / 2f) - logicalStart;
|
||||||
|
float displayEnd = (Mathf.PI / 2f) - logicalEnd;
|
||||||
|
|
||||||
|
Color sectorColor = (i == _selectedIndex)
|
||||||
|
? new Color(0.15f, 0.7f, 0.3f, 0.8f)
|
||||||
|
: new Color(0.1f, 0.1f, 0.1f, 0.7f);
|
||||||
|
|
||||||
|
DrawFilledSector(center, radiusInner, radiusOuter, displayStart, displayEnd, sectorColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GUIStyle labelStyle = new GUIStyle(GUI.skin.label)
|
||||||
|
{
|
||||||
|
alignment = TextAnchor.MiddleCenter,
|
||||||
|
normal = { textColor = Color.white },
|
||||||
|
fontSize = (count <= 6) ? 14 : (count <= 8 ? 12 : 10),
|
||||||
|
wordWrap = true
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
float logicalMid = logicalAnglePerSector * (i + 0.5f);
|
||||||
|
float displayMid = (Mathf.PI / 2f) - logicalMid;
|
||||||
|
|
||||||
|
float lx = centerX + Mathf.Cos(displayMid) * labelRadius;
|
||||||
|
float ly = centerY - Mathf.Sin(displayMid) * labelRadius;
|
||||||
|
|
||||||
|
float arcLength = logicalAnglePerSector * labelRadius;
|
||||||
|
float arcFactor;
|
||||||
|
float minWidth;
|
||||||
|
float maxWidth;
|
||||||
|
|
||||||
|
if (count <= 6)
|
||||||
|
{
|
||||||
|
arcFactor = 0.8f;
|
||||||
|
minWidth = 60f;
|
||||||
|
maxWidth = 120f;
|
||||||
|
}
|
||||||
|
else if (count == 7)
|
||||||
|
{
|
||||||
|
arcFactor = 0.6f;
|
||||||
|
minWidth = 45f;
|
||||||
|
maxWidth = 75f;
|
||||||
|
}
|
||||||
|
else if (count <= 8)
|
||||||
|
{
|
||||||
|
arcFactor = 0.65f;
|
||||||
|
minWidth = 45f;
|
||||||
|
maxWidth = 80f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
arcFactor = 0.55f;
|
||||||
|
minWidth = 40f;
|
||||||
|
maxWidth = 70f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float baseWidth = arcLength * arcFactor;
|
||||||
|
|
||||||
|
float labelWidth = Mathf.Clamp(baseWidth, minWidth, maxWidth);
|
||||||
|
float labelHeight = 32f;
|
||||||
|
|
||||||
|
Rect labelRect = new Rect(lx - labelWidth / 2f, ly - labelHeight / 2f, labelWidth, labelHeight);
|
||||||
|
GUI.Label(labelRect, _options[i].Label, labelStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnsureRadialMaterial()
|
||||||
|
{
|
||||||
|
if (_radialMaterial != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Shader shader = Shader.Find("Hidden/Internal-Colored");
|
||||||
|
if (shader == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_radialMaterial = new Material(shader)
|
||||||
|
{
|
||||||
|
hideFlags = HideFlags.HideAndDontSave
|
||||||
|
};
|
||||||
|
_radialMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
|
||||||
|
_radialMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
|
||||||
|
_radialMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off);
|
||||||
|
_radialMaterial.SetInt("_ZWrite", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DrawFilledCircle(Vector2 center, float radius, Color color)
|
||||||
|
{
|
||||||
|
if (_radialMaterial == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_radialMaterial.SetPass(0);
|
||||||
|
GL.PushMatrix();
|
||||||
|
GL.LoadPixelMatrix(0, Screen.width, Screen.height, 0);
|
||||||
|
|
||||||
|
GL.Begin(GL.TRIANGLES);
|
||||||
|
GL.Color(color);
|
||||||
|
|
||||||
|
const int steps = 64;
|
||||||
|
for (int i = 0; i < steps; i++)
|
||||||
|
{
|
||||||
|
float t0 = (float)i / steps;
|
||||||
|
float t1 = (float)(i + 1) / steps;
|
||||||
|
|
||||||
|
float ang0 = t0 * Mathf.PI * 2f;
|
||||||
|
float ang1 = t1 * Mathf.PI * 2f;
|
||||||
|
|
||||||
|
float x0 = center.x + Mathf.Cos(ang0) * radius;
|
||||||
|
float y0 = center.y - Mathf.Sin(ang0) * radius;
|
||||||
|
float x1 = center.x + Mathf.Cos(ang1) * radius;
|
||||||
|
float y1 = center.y - Mathf.Sin(ang1) * radius;
|
||||||
|
|
||||||
|
GL.Vertex3(center.x, center.y, 0f);
|
||||||
|
GL.Vertex3(x0, y0, 0f);
|
||||||
|
GL.Vertex3(x1, y1, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.End();
|
||||||
|
GL.PopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DrawFilledSector(Vector2 center, float innerRadius, float outerRadius,
|
||||||
|
float startAngle, float endAngle, Color color)
|
||||||
|
{
|
||||||
|
if (_radialMaterial == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_radialMaterial.SetPass(0);
|
||||||
|
GL.PushMatrix();
|
||||||
|
GL.LoadPixelMatrix(0, Screen.width, Screen.height, 0);
|
||||||
|
|
||||||
|
GL.Begin(GL.TRIANGLES);
|
||||||
|
GL.Color(color);
|
||||||
|
|
||||||
|
int steps = Mathf.Max(8, Mathf.CeilToInt(Mathf.Abs(endAngle - startAngle) / (Mathf.PI / 24f)));
|
||||||
|
float delta = (endAngle - startAngle) / steps;
|
||||||
|
|
||||||
|
for (int i = 0; i < steps; i++)
|
||||||
|
{
|
||||||
|
float a0 = startAngle + delta * i;
|
||||||
|
float a1 = startAngle + delta * (i + 1);
|
||||||
|
|
||||||
|
Vector2 o0 = new Vector2(
|
||||||
|
center.x + Mathf.Cos(a0) * outerRadius,
|
||||||
|
center.y - Mathf.Sin(a0) * outerRadius);
|
||||||
|
Vector2 o1 = new Vector2(
|
||||||
|
center.x + Mathf.Cos(a1) * outerRadius,
|
||||||
|
center.y - Mathf.Sin(a1) * outerRadius);
|
||||||
|
|
||||||
|
Vector2 i0 = new Vector2(
|
||||||
|
center.x + Mathf.Cos(a0) * innerRadius,
|
||||||
|
center.y - Mathf.Sin(a0) * innerRadius);
|
||||||
|
Vector2 i1 = new Vector2(
|
||||||
|
center.x + Mathf.Cos(a1) * innerRadius,
|
||||||
|
center.y - Mathf.Sin(a1) * innerRadius);
|
||||||
|
|
||||||
|
GL.Vertex3(o0.x, o0.y, 0f);
|
||||||
|
GL.Vertex3(o1.x, o1.y, 0f);
|
||||||
|
GL.Vertex3(i1.x, i1.y, 0f);
|
||||||
|
|
||||||
|
GL.Vertex3(o0.x, o0.y, 0f);
|
||||||
|
GL.Vertex3(i1.x, i1.y, 0f);
|
||||||
|
GL.Vertex3(i0.x, i0.y, 0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.End();
|
||||||
|
GL.PopMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ExecuteOption(RadialOption option)
|
||||||
|
{
|
||||||
|
if (option == null || option.ActionType == RadialActionType.None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (option.ActionType)
|
||||||
|
{
|
||||||
|
case RadialActionType.SpawnItem:
|
||||||
|
if (string.IsNullOrEmpty(option.Payload))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ClientMain_HandleItemCarry(option.Payload);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RadialActionType.TeleportBase:
|
||||||
|
TeleportToBase();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RadialActionType.TeleportFixedPoint:
|
||||||
|
TeleportToFixedPoint(option.Payload);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MelonLogger.Error($"Radial option execution failed: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void HideCursorForRadial()
|
||||||
|
{
|
||||||
|
if (!_cursorStateStored)
|
||||||
|
{
|
||||||
|
_prevCursorVisible = Cursor.visible;
|
||||||
|
_prevCursorLockState = Cursor.lockState;
|
||||||
|
_cursorStateStored = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cursor.lockState = CursorLockMode.None;
|
||||||
|
Cursor.visible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RestoreCursorState()
|
||||||
|
{
|
||||||
|
if (!_cursorStateStored)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Cursor.lockState = _prevCursorLockState;
|
||||||
|
Cursor.visible = _prevCursorVisible;
|
||||||
|
_cursorStateStored = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calls ClientMain.HandleItemCarry via reflection to avoid tight coupling,
|
||||||
|
// and falls back to Hacks.Misc.CarryObject if that fails.
|
||||||
|
private static void ClientMain_HandleItemCarry(string payload)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var type = typeof(ClientMain);
|
||||||
|
var method = type.GetMethod("HandleItemCarry",
|
||||||
|
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
|
||||||
|
if (method != null)
|
||||||
|
{
|
||||||
|
method.Invoke(null, new object[] { payload });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// ignore and fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
Hacks.Misc.CarryObject(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Teleports the player to a fixed world position.
|
||||||
|
// Payload format: "x y z" using '.' as decimal separator.
|
||||||
|
private static void TeleportToFixedPoint(string payload)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(payload))
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string[] parts = payload.Split(new[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (parts.Length < 3)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float x = float.Parse(parts[0], CultureInfo.InvariantCulture);
|
||||||
|
float y = float.Parse(parts[1], CultureInfo.InvariantCulture);
|
||||||
|
float z = float.Parse(parts[2], CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
Il2Cpp.NolanBehaviour nb = Player.GetPlayer();
|
||||||
|
if (nb == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vector3 target = new Vector3(x, y, z);
|
||||||
|
nb.TeleportTo(target, Quaternion.identity);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MelonLogger.Error($"TeleportToFixedPoint failed: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Teleports the player to the map-specific base coordinates (former RecallToBase logic).
|
||||||
|
private static void TeleportToBase()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Il2Cpp.NolanBehaviour nb = Player.GetPlayer();
|
||||||
|
if (nb == null)
|
||||||
|
{
|
||||||
|
MelonLogger.Warning("Player not found!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string sceneName = Helpers.Map.GetActiveScene();
|
||||||
|
Vector3 targetPos = Vector3.zero;
|
||||||
|
string mapName = "";
|
||||||
|
|
||||||
|
switch (sceneName)
|
||||||
|
{
|
||||||
|
case "Devour":
|
||||||
|
case "Anna": // Farmhouse
|
||||||
|
targetPos = new Vector3(5.03f, 4.20f, -50.02f);
|
||||||
|
mapName = "Farm";
|
||||||
|
break;
|
||||||
|
case "Molly": // Asylum
|
||||||
|
targetPos = new Vector3(17.52f, 1.38f, 7.04f);
|
||||||
|
mapName = "Asylum";
|
||||||
|
break;
|
||||||
|
case "Inn":
|
||||||
|
targetPos = new Vector3(3.53f, 0.84f, 2.47f);
|
||||||
|
mapName = "Inn";
|
||||||
|
break;
|
||||||
|
case "Town":
|
||||||
|
targetPos = new Vector3(-63.51f, 10.88f, -12.32f);
|
||||||
|
mapName = "Town";
|
||||||
|
break;
|
||||||
|
case "Slaughterhouse":
|
||||||
|
targetPos = new Vector3(6.09f, 0.70f, -17.58f);
|
||||||
|
mapName = "Slaughterhouse";
|
||||||
|
break;
|
||||||
|
case "Manor":
|
||||||
|
targetPos = new Vector3(3.67f, 1.32f, -23.34f);
|
||||||
|
mapName = "Manor";
|
||||||
|
break;
|
||||||
|
case "Carnival":
|
||||||
|
targetPos = new Vector3(-91.46f, 8.13f, -24.51f);
|
||||||
|
mapName = "Carnival";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
MelonLogger.Warning($"Teleport not available for scene: {sceneName}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nb.locomotion.SetPosition(targetPos, false);
|
||||||
|
MelonLogger.Msg($"Teleported to {mapName} coordinates: X:{targetPos.x:F2} Y:{targetPos.y:F2} Z:{targetPos.z:F2}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
MelonLogger.Error($"Failed to teleport to base: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -103,9 +103,9 @@ If you want to modify and develop the code, please follow the [Building from sou
|
|||||||
|
|
||||||
4、运行devour → 如果安装成功,你会看到一个windows窗口进行各类安装提示后,自动进入游戏。点击insert键即可打开和关闭devourclient窗口
|
4、运行devour → 如果安装成功,你会看到一个windows窗口进行各类安装提示后,自动进入游戏。点击insert键即可打开和关闭devourclient窗口
|
||||||
|
|
||||||
**注意:**有些电脑在安装melonloader之后,会出现fatal error的提示,这个我目前并没有碰到过。但是出现这个提示的主要原因,基本是melonloader安装过程中,提取到devour根目录的melonloader文件夹里的文件出现了问题,比较简单的解决办法就是(1)在别人的同系统同位宽(x86,x32)的电脑里拷贝出来他的melonloader文件夹,然后直接粘贴到自己的电脑里。(2)将melonloader文件夹完全删除,然后重装。(3)在直到游戏完全运行,菜单正常工作之前,保持VPN线路通畅。
|
注意:有些电脑在安装melonloader之后,会出现fatal error的提示,这个我目前并没有碰到过。但是出现这个提示的主要原因,基本是melonloader安装过程中,提取到devour根目录的melonloader文件夹里的文件出现了问题,比较简单的解决办法就是(1)在别人的同系统同位宽(x86,x32)的电脑里拷贝出来他的melonloader文件夹,然后直接粘贴到自己的电脑里。(2)将melonloader文件夹完全删除,然后重装。(3)在直到游戏完全运行,菜单正常工作之前,保持VPN线路通畅。
|
||||||
|
|
||||||
**注意:**如果在加载时提示 “0 mod”,请检查你的dll文件是否正常,是否已经将dll文件放置到devour的“mods”文件夹中。
|
注意:如果在加载时提示 “0 mod”,请检查你的dll文件是否正常,是否已经将dll文件放置到devour的“mods”文件夹中。
|
||||||
|
|
||||||
如果你想要对代码进行修改和开发,请按照下面的 [building from source](#building-from-source) 的步骤,逐步进行
|
如果你想要对代码进行修改和开发,请按照下面的 [building from source](#building-from-source) 的步骤,逐步进行
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user