第一批重构,主要是物理迁移脚本和部分命名空间的调整
- 结构上迁移文件,将脚本分成 Base/Runtime/Presentation/Procedure/Editor 五大文件夹 - 调整 DataTable 和 Definition 下脚本的命名空间 - 依据 UI-5层架构设计规范 拆分原先的 UI 到 Runtime 和 Presentation 下
This commit is contained in:
@@ -0,0 +1,291 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using SepCore.Definition;
|
||||
using Entity;
|
||||
using Entity.Weapon;
|
||||
using UnityEngine;
|
||||
using UnityGameFramework.Runtime;
|
||||
using Random = UnityEngine.Random;
|
||||
|
||||
namespace CustomUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// AI 工具类。
|
||||
/// </summary>
|
||||
public static class AIUtility
|
||||
{
|
||||
private static Dictionary<CampPair, RelationType> s_CampPairToRelation = new();
|
||||
|
||||
private static Dictionary<KeyValuePair<CampType, RelationType>, CampType[]> s_CampAndRelationToCamps = new();
|
||||
|
||||
static AIUtility()
|
||||
{
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Player), RelationType.Friendly);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Enemy), RelationType.Hostile);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Neutral), RelationType.Neutral);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Player2), RelationType.Hostile);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Enemy2), RelationType.Hostile);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Player, CampType.Neutral2), RelationType.Neutral);
|
||||
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Enemy, CampType.Enemy), RelationType.Friendly);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Enemy, CampType.Neutral), RelationType.Neutral);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Enemy, CampType.Player2), RelationType.Hostile);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Enemy, CampType.Enemy2), RelationType.Hostile);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Enemy, CampType.Neutral2), RelationType.Neutral);
|
||||
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Neutral, CampType.Neutral), RelationType.Neutral);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Neutral, CampType.Player2), RelationType.Neutral);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Neutral, CampType.Enemy2), RelationType.Neutral);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Neutral, CampType.Neutral2), RelationType.Hostile);
|
||||
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Player2, CampType.Player2), RelationType.Friendly);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Player2, CampType.Enemy2), RelationType.Hostile);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Player2, CampType.Neutral2), RelationType.Neutral);
|
||||
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Enemy2, CampType.Enemy2), RelationType.Friendly);
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Enemy2, CampType.Neutral2), RelationType.Neutral);
|
||||
|
||||
s_CampPairToRelation.Add(new CampPair(CampType.Neutral2, CampType.Neutral2), RelationType.Neutral);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取两个阵营之间的关系。
|
||||
/// </summary>
|
||||
/// <param name="first">阵营一。</param>
|
||||
/// <param name="second">阵营二。</param>
|
||||
/// <returns>阵营间关系。</returns>
|
||||
public static RelationType GetRelation(CampType first, CampType second)
|
||||
{
|
||||
if (first > second)
|
||||
{
|
||||
(first, second) = (second, first);
|
||||
}
|
||||
|
||||
RelationType relationType;
|
||||
if (s_CampPairToRelation.TryGetValue(new CampPair(first, second), out relationType))
|
||||
{
|
||||
return relationType;
|
||||
}
|
||||
|
||||
Log.Warning("Unknown relation between '{0}' and '{1}'.", first.ToString(), second.ToString());
|
||||
return RelationType.Unknown;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取和指定具有特定关系的所有阵营。
|
||||
/// </summary>
|
||||
/// <param name="camp">指定阵营。</param>
|
||||
/// <param name="relation">关系。</param>
|
||||
/// <returns>满足条件的阵营数组。</returns>
|
||||
public static CampType[] GetCamps(CampType camp, RelationType relation)
|
||||
{
|
||||
KeyValuePair<CampType, RelationType> key = new KeyValuePair<CampType, RelationType>(camp, relation);
|
||||
if (s_CampAndRelationToCamps.TryGetValue(key, out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: GC Alloc
|
||||
List<CampType> camps = new List<CampType>();
|
||||
Array campTypes = Enum.GetValues(typeof(CampType));
|
||||
for (int i = 0; i < campTypes.Length; i++)
|
||||
{
|
||||
CampType campType = (CampType)campTypes.GetValue(i);
|
||||
if (GetRelation(camp, campType) == relation)
|
||||
{
|
||||
camps.Add(campType);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: GC Alloc
|
||||
result = camps.ToArray();
|
||||
s_CampAndRelationToCamps[key] = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取实体间的距离。
|
||||
/// </summary>
|
||||
/// <returns>实体间的距离。</returns>
|
||||
public static float GetDistance(EntityBase fromEntity, EntityBase toEntity)
|
||||
{
|
||||
Transform fromTransform = fromEntity.CachedTransform;
|
||||
Transform toTransform = toEntity.CachedTransform;
|
||||
return (toTransform.position - fromTransform.position).magnitude;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取实体间的平方距离。
|
||||
/// </summary>
|
||||
/// <returns>实体间的平方距离。</returns>
|
||||
public static float GetSqrMagnitude(EntityBase fromEntity, EntityBase toEntity)
|
||||
{
|
||||
Transform fromTransform = fromEntity.CachedTransform;
|
||||
Transform toTransform = toEntity.CachedTransform;
|
||||
return (toTransform.position - fromTransform.position).sqrMagnitude;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取实体间在 XZ 平面的距离(忽略 Y 轴)。
|
||||
/// </summary>
|
||||
/// <returns>实体间在 XZ 平面的距离。</returns>
|
||||
public static float GetDistanceXZ(EntityBase fromEntity, EntityBase toEntity)
|
||||
{
|
||||
return Mathf.Sqrt(GetSqrMagnitudeXZ(fromEntity, toEntity));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取实体间在 XZ 平面的平方距离(忽略 Y 轴)。
|
||||
/// </summary>
|
||||
/// <returns>实体间在 XZ 平面的平方距离。</returns>
|
||||
public static float GetSqrMagnitudeXZ(EntityBase fromEntity, EntityBase toEntity)
|
||||
{
|
||||
Transform fromTransform = fromEntity.CachedTransform;
|
||||
Transform toTransform = toEntity.CachedTransform;
|
||||
|
||||
Vector3 delta = toTransform.position - fromTransform.position;
|
||||
delta.y = 0f;
|
||||
return delta.sqrMagnitude;
|
||||
}
|
||||
|
||||
public static void PerformCollision(TargetableObject entity, EntityBase other)
|
||||
{
|
||||
PerformCollision(entity, other, false);
|
||||
}
|
||||
|
||||
public static void PerformCollision(TargetableObject entity, EntityBase other, bool ignoreRuntimeState)
|
||||
{
|
||||
if (entity == null || other == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// TargetableObject target = other as TargetableObject;
|
||||
// if (target != null)
|
||||
// {
|
||||
// ImpactData entityImpactData = entity.GetImpactData();
|
||||
// ImpactData targetImpactData = target.GetImpactData();
|
||||
// if (GetRelation(entityImpactData.Camp, targetImpactData.Camp) == RelationType.Friendly)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// int entityDamageHP = CalcDamageHP(targetImpactData.Attack, entityImpactData.Defense);
|
||||
// int targetDamageHP = CalcDamageHP(entityImpactData.Attack, targetImpactData.Defense);
|
||||
//
|
||||
// entity.ApplyDamage(target, entityDamageHP);
|
||||
// target.ApplyDamage(entity, targetDamageHP);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Bullet bullet = other as Bullet;
|
||||
// if (bullet != null)
|
||||
// {
|
||||
// ImpactData entityImpactData = entity.GetImpactData();
|
||||
// ImpactData bulletImpactData = bullet.GetImpactData();
|
||||
// if (GetRelation(entityImpactData.Camp, bulletImpactData.Camp) == RelationType.Friendly)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// int entityDamageHP = CalcDamageHP(bulletImpactData.AttackBase, bulletImpactData.AttackStat,
|
||||
// entityImpactData.DefenseStat, entityImpactData.DodgeStat);
|
||||
//
|
||||
// entity.ApplyDamage(bullet, entityDamageHP);
|
||||
// GameEntry.Entity.HideEntity(bullet);
|
||||
// return;
|
||||
// }
|
||||
|
||||
EnemyProjectile enemyProjectile = other as EnemyProjectile;
|
||||
if (enemyProjectile != null)
|
||||
{
|
||||
if (!ignoreRuntimeState && !enemyProjectile.IsActive) return;
|
||||
|
||||
ImpactData entityImpactData = entity.GetImpactData();
|
||||
ImpactData projectileImpactData = enemyProjectile.GetImpactData();
|
||||
if (GetRelation(entityImpactData.Camp, projectileImpactData.Camp) == RelationType.Friendly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int entityDamageHP = CalcDamageHP(projectileImpactData.AttackBase, projectileImpactData.AttackStat,
|
||||
entityImpactData.DefenseStat, entityImpactData.DodgeStat);
|
||||
|
||||
entity.ApplyDamage(enemyProjectile, entityDamageHP);
|
||||
enemyProjectile.Expire();
|
||||
return;
|
||||
}
|
||||
|
||||
WeaponBase weapon = other as WeaponBase;
|
||||
if (weapon != null)
|
||||
{
|
||||
if (!ignoreRuntimeState && !weapon.IsAttacking) return;
|
||||
ImpactData entityImpactData = entity.GetImpactData();
|
||||
ImpactData weaponImpactData = weapon.GetImpactData();
|
||||
if (GetRelation(entityImpactData.Camp, weaponImpactData.Camp) == RelationType.Friendly)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int entityDamageHP = CalcDamageHP(weaponImpactData.AttackBase, weaponImpactData.AttackStat,
|
||||
entityImpactData.DefenseStat, entityImpactData.DodgeStat);
|
||||
|
||||
entity.ApplyDamage(weapon, entityDamageHP);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static int CalcDamageHP(int attack, StatProperty attackStat, StatProperty defenseStat,
|
||||
StatProperty dodgeStat)
|
||||
{
|
||||
// 1. 处理闪避(闪避率取值 (0, 0.9),不允许拉满闪避)
|
||||
if (dodgeStat != null)
|
||||
{
|
||||
if (Random.value < Mathf.Clamp(dodgeStat.Value, 0, 0.9f)) return 0;
|
||||
}
|
||||
|
||||
// 2. 处理攻击加成 最终伤害 = (基础伤害 + 伤害提升固定值) * 伤害提升率
|
||||
float damage = attack;
|
||||
if (attackStat != null)
|
||||
{
|
||||
damage = (attack + attackStat.Value) * attackStat.Percent;
|
||||
}
|
||||
|
||||
// 3. 处理防御加成 最终伤害 = (基础伤害 - 防御提升固定值) / 防御提升率
|
||||
if (defenseStat != null)
|
||||
{
|
||||
damage = (damage - defenseStat.Value) / defenseStat.Percent;
|
||||
}
|
||||
|
||||
// 将伤害限制为正整数,避免堆防御导致无法造成伤害
|
||||
if (damage < 1) return 1;
|
||||
else return Mathf.CeilToInt(damage);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
private struct CampPair
|
||||
{
|
||||
private readonly CampType m_First;
|
||||
private readonly CampType m_Second;
|
||||
|
||||
public CampPair(CampType first, CampType second)
|
||||
{
|
||||
m_First = first;
|
||||
m_Second = second;
|
||||
}
|
||||
|
||||
public CampType First => m_First;
|
||||
|
||||
public CampType Second => m_Second;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f1870ca304d9c4d49905b5d3da2841e5
|
||||
timeCreated: 1528026163
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,68 @@
|
||||
using Text = GameFramework.Utility.Text;
|
||||
|
||||
namespace CustomUtility
|
||||
{
|
||||
public static class AssetUtility
|
||||
{
|
||||
public static string GetConfigAsset(string assetName, bool fromBytes)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/Configs/{0}.{1}", assetName, fromBytes ? "bytes" : "txt");
|
||||
}
|
||||
|
||||
public static string GetDataTableAsset(string assetName, bool fromBytes)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/DataTables/{0}.{1}", assetName, fromBytes ? "bytes" : "txt");
|
||||
}
|
||||
|
||||
public static string GetDictionaryAsset(string assetName, bool fromBytes)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/Localization/{0}/Dictionaries/{1}.{2}",
|
||||
GameEntry.Localization.Language, assetName, fromBytes ? "bytes" : "xml");
|
||||
}
|
||||
|
||||
public static string GetFontAsset(string assetName)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/Fonts/{0}.ttf", assetName);
|
||||
}
|
||||
|
||||
public static string GetTMPFontAsset(string assetName)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/Fonts/{0}.asset", assetName);
|
||||
}
|
||||
|
||||
public static string GetSceneAsset(string assetName)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/Scenes/{0}.unity", assetName);
|
||||
}
|
||||
|
||||
public static string GetMusicAsset(string assetName)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/Music/{0}.mp3", assetName);
|
||||
}
|
||||
|
||||
public static string GetSoundAsset(string assetName)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/Sounds/{0}.wav", assetName);
|
||||
}
|
||||
|
||||
public static string GetEntityAsset(string assetName)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/Entities/{0}.prefab", assetName);
|
||||
}
|
||||
|
||||
public static string GetUIFormAsset(string assetName)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/UI/UIForms/{0}.prefab", assetName);
|
||||
}
|
||||
|
||||
public static string GetUISoundAsset(string assetName)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/UI/UISounds/{0}.wav", assetName);
|
||||
}
|
||||
|
||||
public static string GetUITextureIconAsset(string assetName)
|
||||
{
|
||||
return Text.Format("Assets/GameMain/UI/UISprites/Icons/{0}.png", assetName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec33154bafd23a84a8f6a414f5b25ae2
|
||||
timeCreated: 1528026163
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace CustomUtility
|
||||
{
|
||||
public static class EnumUtility<T> where T : struct, System.Enum
|
||||
{
|
||||
private static readonly Dictionary<string, T> _enumCache = new();
|
||||
|
||||
public static T Get(string value)
|
||||
{
|
||||
if (!_enumCache.TryGetValue(value, out T result))
|
||||
{
|
||||
if (System.Enum.TryParse(value, true, out result))
|
||||
{
|
||||
_enumCache[value] = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.Error($"Enum 解析失败:类型:{typeof(T).Name} 不包含值 {value}");
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8a39ac998e79e504fa643b459880ee9e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,120 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using SepCore.DataTable;
|
||||
using SepCore.Definition;
|
||||
using Entity.EntityData;
|
||||
using Entity.Weapon;
|
||||
using System;
|
||||
using UnityGameFramework.Runtime;
|
||||
|
||||
namespace CustomUtility
|
||||
{
|
||||
public static class ItemDescUtility
|
||||
{
|
||||
private static readonly Dictionary<string, string> _paramsDict = new(StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
{"hitHalfWidth", "横向半宽"},
|
||||
{"hitRadius", "攻击半宽"},
|
||||
{"hitHeight", "判定高度"},
|
||||
{"hitCenterYOffset", "判定高度偏移"},
|
||||
{"sectorAngle", "攻击角度"},
|
||||
{"pierceLength", "前戳距离"},
|
||||
{"thrustDistance", "前戳距离(旧)"},
|
||||
{"forwardOffset", "前置偏移"},
|
||||
{"rotateSpeed", "转向速度"},
|
||||
{"attackDuration", "突刺时长"},
|
||||
{"returnDuration", "收枪时长"}
|
||||
};
|
||||
|
||||
public static string CreatePropDescription(StatModifier[] modifiers)
|
||||
{
|
||||
if (modifiers == null || modifiers.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (StatModifier modifier in modifiers)
|
||||
{
|
||||
sb.Append(modifier);
|
||||
sb.Append('\n');
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static string CreateWeaponDescription(DRWeapon drWeapon)
|
||||
{
|
||||
if (drWeapon == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return CreateWeaponDescription(drWeapon.Attack, drWeapon.Cooldown, drWeapon.AttackRange, drWeapon.Modifiers,
|
||||
drWeapon.Pramas);
|
||||
}
|
||||
|
||||
public static string CreateWeaponDescription(WeaponBase weapon)
|
||||
{
|
||||
if (weapon == null || weapon.WeaponData == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return CreateWeaponDescription(weapon.WeaponData);
|
||||
}
|
||||
|
||||
public static string CreateWeaponDescription(WeaponData weaponData)
|
||||
{
|
||||
if (weaponData == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return CreateWeaponDescription(weaponData.Attack, weaponData.Cooldown,
|
||||
weaponData.AttackRange, weaponData.Modifiers, weaponData.Params);
|
||||
}
|
||||
|
||||
public static string CreatePropDescription(PropItem prop)
|
||||
{
|
||||
if (prop == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return CreatePropDescription(prop.Modifiers);
|
||||
}
|
||||
|
||||
private static string CreateWeaponDescription(int attack, float cooldown, float attackRange,
|
||||
StatModifier[] modifiers, Dictionary<string, string> @params)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine($"攻击: {attack}");
|
||||
sb.AppendLine($"冷却: {cooldown}");
|
||||
sb.AppendLine($"范围: {attackRange}");
|
||||
|
||||
string modifiersDesc = CreatePropDescription(modifiers);
|
||||
if (!string.IsNullOrEmpty(modifiersDesc))
|
||||
{
|
||||
sb.Append(modifiersDesc);
|
||||
}
|
||||
|
||||
if (@params == null || @params.Count == 0)
|
||||
{
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
foreach (var kvp in @params)
|
||||
{
|
||||
if (!_paramsDict.TryGetValue(kvp.Key, out string value))
|
||||
{
|
||||
value = kvp.Key;
|
||||
Log.Warning($"{kvp.Key} is not defined.");
|
||||
}
|
||||
sb.AppendLine($"{value}: {kvp.Value}");
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dcfdad321f8ce314fa013b885c2a78f7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace CustomUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// Newtonsoft.Json 函数集辅助器。
|
||||
/// </summary>
|
||||
public class JsonNetUtility : GameFramework.Utility.Json.IJsonHelper
|
||||
{
|
||||
public string ToJson(object obj)
|
||||
{
|
||||
return JsonConvert.SerializeObject(obj);
|
||||
}
|
||||
|
||||
public T ToObject<T>(string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(json);
|
||||
}
|
||||
|
||||
public object ToObject(Type objectType, string json)
|
||||
{
|
||||
return JsonConvert.DeserializeObject(json, objectType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a2eb0a4b148e1c24ebc91cb3a2ef3180
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,89 @@
|
||||
using SepCore.DataTable;
|
||||
using SepCore.Definition;
|
||||
using GameFramework.DataTable;
|
||||
using UnityEngine;
|
||||
|
||||
namespace CustomUtility
|
||||
{
|
||||
public static class RarityUtility
|
||||
{
|
||||
public static ItemRarity SelectRarityForLevel(IDataTable<DRLevelRarity> table, int level)
|
||||
{
|
||||
DRLevelRarity row = GetLevelRarityRow(table, level);
|
||||
if (row == null)
|
||||
{
|
||||
return ItemRarity.White;
|
||||
}
|
||||
|
||||
int white = Mathf.Max(0, row.WhiteWeight);
|
||||
int green = Mathf.Max(0, row.GreenWeight);
|
||||
int blue = Mathf.Max(0, row.BlueWeight);
|
||||
int purple = Mathf.Max(0, row.PurpleWeight);
|
||||
int red = Mathf.Max(0, row.RedWeight);
|
||||
|
||||
int total = white + green + blue + purple + red;
|
||||
if (total <= 0)
|
||||
{
|
||||
return ItemRarity.White;
|
||||
}
|
||||
|
||||
int roll = Random.Range(1, total + 1);
|
||||
if (roll <= white) return ItemRarity.White;
|
||||
roll -= white;
|
||||
if (roll <= green) return ItemRarity.Green;
|
||||
roll -= green;
|
||||
if (roll <= blue) return ItemRarity.Blue;
|
||||
roll -= blue;
|
||||
if (roll <= purple) return ItemRarity.Purple;
|
||||
return ItemRarity.Red;
|
||||
}
|
||||
|
||||
private static DRLevelRarity GetLevelRarityRow(IDataTable<DRLevelRarity> table, int level)
|
||||
{
|
||||
if (table == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
DRLevelRarity[] rows = table.GetAllDataRows();
|
||||
if (rows == null || rows.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int safeLevel = Mathf.Max(1, level);
|
||||
DRLevelRarity below = null;
|
||||
DRLevelRarity above = null;
|
||||
|
||||
foreach (DRLevelRarity row in rows)
|
||||
{
|
||||
if (row == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (safeLevel >= row.LevelMin && safeLevel <= row.LevelMax)
|
||||
{
|
||||
return row;
|
||||
}
|
||||
|
||||
if (safeLevel < row.LevelMin)
|
||||
{
|
||||
if (above == null || row.LevelMin < above.LevelMin)
|
||||
{
|
||||
above = row;
|
||||
}
|
||||
}
|
||||
else if (safeLevel > row.LevelMax)
|
||||
{
|
||||
if (below == null || row.LevelMax > below.LevelMax)
|
||||
{
|
||||
below = row;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return above ?? below;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9186261c82d4f0b8270048f08158b0f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
//------------------------------------------------------------
|
||||
// Game Framework
|
||||
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
|
||||
// Homepage: https://gameframework.cn/
|
||||
// Feedback: mailto:ellan@gameframework.cn
|
||||
//------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
|
||||
namespace StarForce
|
||||
{
|
||||
public static class WebUtility
|
||||
{
|
||||
public static string EscapeString(string stringToEscape)
|
||||
{
|
||||
return Uri.EscapeDataString(stringToEscape);
|
||||
}
|
||||
|
||||
public static string UnescapeString(string stringToUnescape)
|
||||
{
|
||||
return Uri.UnescapeDataString(stringToUnescape);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bbf9721704b3fd240b878d887bf58800
|
||||
timeCreated: 1528026163
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user