using UnityEngine; using static GameConstants.EnemySpawning; public static class GameConstants { public static class PlayerPrefsKeys { public static string PlayerAccountDataKey = "playerAccountData"; public static string CharacterDataKey = "characterData"; public static string CharacterInventoryDataKey = "characterInventoryData"; public static string CharacterEquipmentDataKey = "characterEquipmentData"; public static string CharacterBuildDataKey = "characterBuildData"; public static string PlayerCoinKey = "playerCoin"; public static string AbilityTomeKey = "abilityTome"; public const string ClassUnlockedKey = "classUnlocked"; public const string SunMapUsedKey = "sunMapUsed"; public const string MoonMapUsedKey = "moonMapUsed"; public const string RiverAveMapUsedKey = "riverAveMapUsed"; public const string NecroAutoSummonOnSceneRefreshIndexKey = "necroASoSRIndex"; #region GetKeyMethods public static string GetPlayerAccountDataKey(string playerName) { return PlayerAccountDataKey + "-" + playerName; } public static string GetCharacterDataKey(string playerName, string characterName) { return CharacterDataKey + "-" + playerName + "-" + characterName; } public static string GetCharacterInventoryDataKey(string playerName, string characterName) { return CharacterInventoryDataKey + "-" + playerName + "-" + characterName; } public static string GetCharacterEquipmentDataKey(string playerName, string characterName) { return CharacterEquipmentDataKey + "-" + playerName + "-" + characterName; } public static string GetCharacterBuildDataKey(string playerName, string characterName) { return CharacterBuildDataKey + "-" + playerName + "-" + characterName; } public static string GetPlayerCoinKey(string playerName) { return PlayerCoinKey + "-" + playerName; } public static string GetSunMapUsedKey(string playerName) { return SunMapUsedKey + "-" + playerName; } public static string GetMapUsedKeyByHiddenMapZone(string playerName, HiddenMapZone mapZone) { switch (mapZone) { case HiddenMapZone.SunMap: return SunMapUsedKey + "-" + playerName; case HiddenMapZone.MoonMap: return MoonMapUsedKey + "-" + playerName; case HiddenMapZone.RiverAveMap: return RiverAveMapUsedKey + "-" + playerName; default: return SunMapUsedKey + "-" + playerName; } } public static string GetAbilityTomeKey(string playerName, int abilityIndex) { return playerName + "-" + AbilityTomeKey + "-" + abilityIndex; } public static string GetClassUnlockedKey(string playerName, string className) { return playerName + "-" + ClassUnlockedKey + "-" + className; } #endregion } public static class Input { // Movement public const string HorizontalAxis = "Horizontal"; public const string VerticalAxis = "Vertical"; // Aiming public const string AimHorizontalAxis = "RightStickHorizontal"; public const string AimVerticalAxis = "RightStickVertical"; // Triggers public const string RightTrigger = "RightTrigger"; public const string LeftTrigger = "LeftTrigger"; // Face Buttons public const string ActionButton = "Submit"; public const string CancelButton = "Cancel"; public const string MenuButton = "Menu"; // Shoulder Buttons public const string RightShoulder = "RightShoulder"; public const string LeftShoulder = "LeftShoulder"; // D-Pad public const string DPadHorizontal = "DPadHorizontal"; public const string DPadVertical = "DPadVertical"; } public static class Audio { } public static class CharacterStatsBalancing { public const float AttackDamageIncreaseFromStrength = 0.35f; // 35% str => AttkDmg public const float AttackDamageIncreaseFromAgility = 0.25f; // 25% agi => AttkDmg public const float SpellDamageIncreaseFromIntelligence = 0.35f; //35% int => SpDmg public const float SpellDamageIncreaseFromSpirit = 0.25f; // 25% spi => SpDmg public const float CritChanceIncreaseFromAgility = 0.001f; //0.5% agi => critChance (6% +/- tops) this is base public const float CritChanceIncreaseFromIntelligence = 0.001f; //0.2% int => critChance (6% +/- tops) this is base //public const float CritDamageIncreaseFromStrength = 0.001f; //0.2% str => critDmg //public const float CritDamageIncreaseFromAgility = 0.001f; //0.2% agi => critDmg //public const float CritDamageIncreaseFromIntelligence = 0.001f; //0.1% int => critDmg public const float MaxHealthIncreaseFromSpirit = 0.35f; // 35% spi => MaxHP public const float MaxHealthIncreaseFromVitality = 2f; //1 vit => 2 MaxHP //public const float ArmorIncreaseFromStrength = 0.1f; //10% str => Armor //public const float ArmorIncreaseFromAgility = 0.1f; // 10% agi => Armor //public const float ArmorIncreaseFromVitality = 0.3f; //30% vit => Armor //public const float MagicResistanceIncreaseFromIntelligence = 0.1f; // 10% int => MagicRess public const float MagicResistanceIncreaseFromSpirit = 0.1f; //10% spi => MagicRes //public const float MagicResistanceIncreaseFromVitality = 0.2f; //20% vit => MagicRes public const float PercentArmorIntoDamageReduction = 0.01f; //each point of armor == 0.01% attack dmg reduction public const float PercentMagicResistanceIntoDamageReduction = 0.01f; // each point of MR == 0.01% spell dmg reduction public const float MaximumPercentDamageReductionFromArmor = 0.75f; public const float MaximumPercentDamageReductionFromMagicResistance = 0.75f; public const float BaseMaxHealthGrowthPerLevel = 0.2f; //public const float VitalityToHealthRate = 10f; public const float IntelligenceToManaRate = 0.5f; public const float SpiritToSpiritPowerRate = 0.5f; public const float BonusStrengthToFlatRegenRate = 0.01f; public const float BonusVitalityToFlatRegenRate = 0.01f; public const float BonusSpiritToFlatRegenRate = 0.08f; //public const float BonusSpiritToPercentRegenRate = 0.01f; public const float RelativePowerToSpiritCostPercent = 0.05f; public const float HealthDecayOnSpiritExhaustion = 0.15f; public const int StatPointsPerLevel = 3; public const int StatPointsPerReputationLevel = 3; } public static class CharacterBalancing { // Define ranges and corresponding ranks private static readonly (int Min, int Max, string Rank)[] PowerLevelRanges = new[] { (0, 690, "E"), (691, 1699, "D"), (1700, 3999, "C"), (4000, 8999, "B"), (9000, 55999, "A"), (56000, 289999, "S"), (290000, int.MaxValue, "S+") // For very high values }; public static string GetRankBasedOnRelativeTotalPowerLevel(int powerLevel) { foreach (var range in PowerLevelRanges) { if (powerLevel >= range.Min && powerLevel <= range.Max) { return range.Rank; } } return "E"; // Default rank if the value somehow doesn't match (e.g., negative input) } public const float BaseExperienceThreshold = 600f; public const float ExperienceThresholdGrowth = 165f; public const float ExperienceThresholdGrowthPerLevelExponent = 1.88f; public const float BaseReputationExperienceThreshold = 5f; public const float ReputationExperienceThresholdGrowth = 1.375f; public const float ReputationExperienceThresholdGrowthPerLevelExponent = 1.88f; public const float SoloCheatDeathHealthPercent = 0.5f; public const float SoloCheatDeathInvulnerabilityDuration = 3f; public const float GroupBleedOutDuration = 30f; public const float ReviveTriggerRadius = 3f; public const float ReviveSpeed = 1f; public const float ReviveTime = 5f; public const float ReviveHealthPercent = 0.5f; public const float MovementSpeedCap = 10f; public const float PercentAngularSpeedCap = 1f; public const float PercentAccelerationCap = 1f; public const float MovementSpeedCastingPenalty = -0.75f; public const float MovementSpeedLowestCap = 0.25f; public const float BossMovementSpeedBaseLowestPercentCap = 0.8f; //bosses can only be lowered to 80% of their normal speed: 2.85 base speed == 2.28 minimum speed } public static class GameBalancing { public const int TotalPagesPerAbilityTome = 1; public const int AbilityTomeDropChance = 5; public const int AbilitySlot_II_LevelRequired = 2; public const int AbilitySlot_III_LevelRequired = 3; public const int AbilitySlot_IV_LevelRequired = 4; public const float IncreasedCoinDropBasedOnDifficultyMultiplier = 1.66f; public const float IncreasedItemDropBasedOnDifficultyMultiplier = 0.33f; public const float MinimumFindFishWaitTime = 2.5f; public const float MaximumFindFishWaitTime = 3.25f; public const float HealthIntoExperienceMultiplier = Mathf.PI; public const float ReputationLevelIntoIncreasedExperienceMultiplier = 0.05f; public const int MinimumNumberOfWavesPerRift = 3; public const int MaximumNumberOfWavesPerRift = 4; public const int MinimumQuantityAngrySkelly = 5; public const int MaximumQuantityAngrySkelly = 8; public const int MinimumQuantitySkellyMage = 2; public const int MaximumQuantitySkellyMage = 3; public const int MinimumQuantityVineGolem = 1; public const int MaximumQuantityVineGolem = 2; public const int MinimumQuantityPolygonGolem = 1; public const int MaximumQuantityPolygonGolem = 2; public const int MinimumQuantityLich = 2; public const int MaximumQuantityLich = 3; public const int MinimumQuantityCraziedOrcGrunt = 5; public const int MaximumQuantityCraziedOrcGrunt = 8; public const float RiftStartSpawningDelay = 1.5f; public const float RiftDelayBetweenSpawns = 0.5f; public const float BossTargetLockInPhaseDuration = 6f; public const float BossSearchForNewTargetLockInDuration = 6f; public const int DragonGroundAttacksNeededToChangeToFlyingStance = 8; public const int DragonFlyingAttacksNeededToChangeToGroundStance = 6; public const float DragonFlyingSpeed = 9f; public const float DragonFlyingSightRange = 600f; public const float DragonFlyingAttackRange = 600f; public const float PermaDeathInfoTime = 2f; public static int GetMinimumQuantityByEnemyID(EnemyID id) { return id switch { EnemyID.AngrySkelly => MinimumQuantityAngrySkelly, EnemyID.SkellyMage => MinimumQuantitySkellyMage, EnemyID.VineGolem => MinimumQuantityVineGolem, EnemyID.PolygonGolem => MinimumQuantityPolygonGolem, EnemyID.Lich => MinimumQuantityLich, EnemyID.CraziedOrcGrunt => MinimumQuantityCraziedOrcGrunt, EnemyID.Count => 0, _ => 0, }; } public static int GetMaximumQuantityByEnemyID(EnemyID id) { return id switch { EnemyID.AngrySkelly => MaximumQuantityAngrySkelly, EnemyID.SkellyMage => MaximumQuantitySkellyMage, EnemyID.VineGolem => MaximumQuantityVineGolem, EnemyID.PolygonGolem => MaximumQuantityPolygonGolem, EnemyID.Lich => MaximumQuantityLich, EnemyID.CraziedOrcGrunt => MaximumQuantityCraziedOrcGrunt, EnemyID.Count => 0, _ => 0, }; } } [System.Serializable] public static class EnemySpawning { [System.Serializable] public enum EnemyID { AngrySkelly = 0, SkellyMage = 1, VineGolem = 2, PolygonGolem = 3, Lich = 4, CraziedOrcGrunt = 5, Count } } public static class ObjectSources { #region Object Sources (example stat increase source) public static object AllocatedSource = "Allocated"; public static object AllocatedReputationSource = "Rep Alloc"; public static object LevelSource = "Level"; public static object BaseValueSource = "Base"; public static object CraftingSource = "Crafting"; public static object StrengthSource = "Strength"; public static object AgilitySource = "Agility"; public static object IntelligenceSource = "Intelligence"; public static object SpiritSource = "Spirit"; public static object VitalitySource = "Vitality"; #endregion } public static class NetworkEventCodes { #region Network Event Codes public const byte JobSelection = 112; public const byte CancelChangeLevelVoted = 114; public const byte ChangeLevelVoted = 115; public const byte LoadLevelStarting = 116; #endregion } public static class NetworkPropertyKeys { public const string AvailableJobsKey = "availableJobs"; public const string CurrentMultiJobRiftRaid = "currentMultiJobRiftRaid"; } public static class Sizes { public const int TotalEquipmentSlots = 6; public const int TotalInventorySlots = 18; public const int TotalBuildSlots = 3; } public static class Animation { public static bool IsAnimationEventBasedAbility(AbilityAnimationType anim) { return anim == AbilityAnimationType.Melee || anim == AbilityAnimationType.Shoot || anim == AbilityAnimationType.PunchA || anim == AbilityAnimationType.PunchB || anim == AbilityAnimationType.Kick; } } public static class Scenes { public const string CharacterList = "2-CharacterList"; public const string HuntersInn = "4-RiftHuntersInn"; public const string Skellyard = "4-Skellyard"; public const string Dayard = "4-Dayard"; public const string VampsDen = "4-VampsDen"; public const string DragonsLair = "4-DragonsLair"; public const string RiverAve = "4-RiverAve"; public const string RiftRaid = "5-RiftRaid"; public static string GetSceneNameByZoneName(string zoneName) { zoneName = zoneName.ToLower(); if (zoneName.Contains("huntersinn")) return HuntersInn; if (zoneName.Contains("skellyard")) return Skellyard; if (zoneName.Contains("dayard")) return Dayard; if (zoneName.Contains("vamp")) return VampsDen; if (zoneName.Contains("dragon")) return DragonsLair; if (zoneName.Contains("river")) return RiverAve; if (zoneName.Contains("rift raid")) return RiftRaid; return HuntersInn; } } public static class BehaviorUtils { public static AnimationCurve GetIceshardProjectileCurve() { var keyframes = new Keyframe[] { // time, value, inTangent, outTangent new Keyframe(0.0f, 0.0f, -0.0635979f, -0.0635979f), new Keyframe(0.6008623f, 1.0058026f, 3.168166f, 3.168166f), // ← This steep tangent creates the sharp rise! new Keyframe(0.9846547f, 1.3325472f, 0.3161671f, 0.3161671f) }; var curve = new AnimationCurve(keyframes); curve.preWrapMode = WrapMode.PingPong; curve.postWrapMode = WrapMode.PingPong; return curve; } } }