- 调整项目结构以适应打包需求

- 添加控制台便于在游戏运行过程中调试各项功能
- 添加 LevelRarity 表,增加了随关卡数动态调整的商品道具品质刷新概率
This commit is contained in:
SepComet
2026-02-18 22:53:33 +08:00
parent e151619c69
commit b4bc8b0445
202 changed files with 5160 additions and 3393 deletions
@@ -18,6 +18,11 @@ public partial class GameEntry : MonoBehaviour
public static BuiltinDataComponent BuiltinData { get; private set; }
public static HPBarComponent HPBar { get; private set; }
public static DamageTextComponent DamageText { get; private set; }
#if UNITY_EDITOR || DEVELOPMENT_BUILD
public static RuntimeDebugPanelComponent RuntimeDebugPanel { get; private set; }
#endif
public static EnemyManagerComponent EnemyManager { get; private set; }
@@ -29,6 +34,18 @@ public partial class GameEntry : MonoBehaviour
{
BuiltinData = UnityGameFramework.Runtime.GameEntry.GetComponent<BuiltinDataComponent>();
HPBar = UnityGameFramework.Runtime.GameEntry.GetComponent<HPBarComponent>();
DamageText = UnityGameFramework.Runtime.GameEntry.GetComponent<DamageTextComponent>();
if (DamageText == null && Base != null)
{
DamageText = Base.gameObject.AddComponent<DamageTextComponent>();
}
#if UNITY_EDITOR || DEVELOPMENT_BUILD
RuntimeDebugPanel = UnityGameFramework.Runtime.GameEntry.GetComponent<RuntimeDebugPanelComponent>();
if (RuntimeDebugPanel == null && Base != null)
{
RuntimeDebugPanel = Base.gameObject.AddComponent<RuntimeDebugPanelComponent>();
}
#endif
EnemyManager = UnityGameFramework.Runtime.GameEntry.GetComponent<EnemyManagerComponent>();
SpriteCache = UnityGameFramework.Runtime.GameEntry.GetComponent<SpriteCacheComponent>();
UIRouter = UnityGameFramework.Runtime.GameEntry.GetComponent<UIRouterComponent>();
@@ -0,0 +1,101 @@
using System;
using Definition.DataStruct;
using Definition.Enum;
using Entity;
using UnityEngine;
namespace Components
{
public class AbsorbComponent : MonoBehaviour
{
[SerializeField] private float _absorbRangeBase = 3f;
[SerializeField] private float _absorbSpeed = 15f;
[SerializeField] private float _collectDistance = 0.35f;
[SerializeField] private int _maxDetectCount = 64;
[SerializeField] private LayerMask _detectLayerMask = ~0;
private Player _player;
private Transform _target;
private StatComponent _statComponent;
private Collider[] _buffer;
private StatProperty _absorbRangeStat;
private Action<StatModifier, bool> _absorbRangeStatCallback;
private float AbsorbRange => Mathf.Max(0f, (_absorbRangeBase + _absorbRangeStat.Value) * _absorbRangeStat.Percent);
public void OnInit(Player player, StatComponent statComponent = null)
{
_player = player;
_target = player != null ? player.CachedTransform : null;
_statComponent = statComponent;
_buffer = new Collider[Mathf.Max(1, _maxDetectCount)];
if (_statComponent != null)
{
_absorbRangeStat = _statComponent.GetStat(StatType.AbsorbRange);
_absorbRangeStatCallback = (modifier, isApply) =>
_statComponent.UpdateStat(_absorbRangeStat, modifier, isApply);
_statComponent.Subscribe(StatType.AbsorbRange, _absorbRangeStatCallback);
}
else
{
_absorbRangeStat = new StatProperty();
}
}
public void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
if (_player == null || !_player.Available || _target == null || _buffer == null) return;
int hitCount = Physics.OverlapSphereNonAlloc(
_target.position,
AbsorbRange,
_buffer,
_detectLayerMask,
QueryTriggerInteraction.Collide
);
for (int i = 0; i < hitCount; i++)
{
Collider hit = _buffer[i];
if (hit == null) continue;
CoinEntity coin = hit.GetComponent<CoinEntity>();
if (coin != null && coin.Available)
{
AbsorbDrop(coin.CachedTransform, elapseSeconds);
coin.TryCollect(_player, _collectDistance);
continue;
}
ExpEntity exp = hit.GetComponent<ExpEntity>();
if (exp != null && exp.Available)
{
AbsorbDrop(exp.CachedTransform, elapseSeconds);
exp.TryCollect(_player, _collectDistance);
}
}
}
public void OnReset()
{
if (_statComponent != null)
{
_statComponent.Unsubscribe(StatType.AbsorbRange, _absorbRangeStatCallback);
_absorbRangeStatCallback = null;
}
_statComponent = null;
_target = null;
_player = null;
_buffer = null;
}
private void AbsorbDrop(Transform drop, float deltaTime)
{
if (drop == null || _target == null) return;
drop.position = Vector3.MoveTowards(drop.position, _target.position, _absorbSpeed * deltaTime);
}
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 00bc8bc968fa2134095a36a43f326d56
guid: 46f46350fed64d8389ebb4ae72b65796
MonoImporter:
externalObjects: {}
serializedVersion: 2
@@ -1,4 +1,4 @@
using System;
using System;
using CustomEvent;
using Definition.DataStruct;
using Definition.Enum;
@@ -119,7 +119,9 @@ namespace Components
private void CauseDamage(int damage)
{
//TODO:受击效果:跳字、粒子
if (damage <= 0 || GameEntry.DamageText == null) return;
GameEntry.DamageText.ShowDamage(transform.position + Vector3.up * 1.1f, damage);
}
}
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 051868bff0e1df3498c100dc5a9f027d
guid: 6befdfdd5f3e430a864a90bf445000e8
folderAsset: yes
DefaultImporter:
externalObjects: {}
@@ -0,0 +1,67 @@
using System.Collections.Generic;
using GameFramework.ObjectPool;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityGameFramework.Runtime;
namespace CustomComponent
{
public class DamageTextComponent : GameFrameworkComponent
{
[SerializeField] private int _instancePoolCapacity = 32;
[SerializeField] private string _poolName = "DamageTextItem";
[SerializeField] private RectTransform _instanceRoot;
[SerializeField] private Canvas _canvas;
[SerializeField] private GameObject _damageTextItemPrefab;
private IObjectPool<DamageTextItemObject> _damageTextItemPool;
private readonly List<DamageTextItem> _activeDamageTextItems = new();
private void Start()
{
_damageTextItemPool =
GameEntry.ObjectPool.CreateSingleSpawnObjectPool<DamageTextItemObject>(_poolName,
_instancePoolCapacity);
}
public void ShowDamage(Vector3 worldPosition, int damage)
{
if (damage <= 0 || _damageTextItemPool == null || _canvas == null) return;
DamageTextItem item = CreateDamageTextItem();
if (item == null) return;
item.Show(worldPosition, damage, _canvas, OnItemComplete);
_activeDamageTextItems.Add(item);
}
private DamageTextItem CreateDamageTextItem()
{
DamageTextItemObject itemObject = _damageTextItemPool.Spawn();
if (itemObject != null)
{
return (DamageTextItem)itemObject.Target;
}
GameObject itemGo = Instantiate(_damageTextItemPrefab, _instanceRoot, false);
DamageTextItem item = itemGo.GetComponent<DamageTextItem>();
_damageTextItemPool.Register(DamageTextItemObject.Create(item), true);
return item;
}
private void OnItemComplete(DamageTextItem item)
{
if (item == null) return;
item.ResetItem();
_activeDamageTextItems.Remove(item);
_damageTextItemPool.Unspawn(item);
}
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: f91ec109eb6c73a408325960701b4c94
guid: 366eb88b821a4048891b7fb01a1b8d42
MonoImporter:
externalObjects: {}
serializedVersion: 2
@@ -0,0 +1,80 @@
using System;
using DG.Tweening;
using TMPro;
using UnityEngine;
namespace CustomComponent
{
public class DamageTextItem : MonoBehaviour
{
private const float RiseDistance = 80f;
private const float RiseDuration = 0.55f;
private const float FadeDelay = 0.2f;
private const float FadeDuration = 0.35f;
private static readonly Color NormalColor = new Color(1f, 0.32f, 0.23f, 1f);
[SerializeField] private RectTransform _cachedTransform;
[SerializeField] private CanvasGroup _canvasGroup;
[SerializeField] private TMP_Text _text;
private Sequence _sequence;
private Action<DamageTextItem> _onComplete;
private void Awake()
{
if (_cachedTransform == null) _cachedTransform = GetComponent<RectTransform>();
if (_canvasGroup == null) _canvasGroup = GetComponent<CanvasGroup>();
if (_text == null) _text = GetComponent<TMP_Text>();
}
public void Show(Vector3 worldPosition, int damage, Canvas canvas, Action<DamageTextItem> onComplete)
{
if (canvas == null || GameEntry.Scene.MainCamera == null) return;
_onComplete = onComplete;
gameObject.SetActive(true);
KillSequence();
_canvasGroup.alpha = 1f;
_cachedTransform.localScale = Vector3.one;
_text.color = NormalColor;
_text.text = damage.ToString();
Vector3 screenPos = GameEntry.Scene.MainCamera.WorldToScreenPoint(worldPosition);
RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)canvas.transform, screenPos,
canvas.worldCamera, out Vector2 localPos);
localPos.x += UnityEngine.Random.Range(-24f, 24f);
_cachedTransform.anchoredPosition = localPos;
_sequence = DOTween.Sequence();
_sequence.Append(_cachedTransform.DOAnchorPosY(localPos.y + RiseDistance, RiseDuration)
.SetEase(Ease.OutQuad));
_sequence.Join(_cachedTransform.DOPunchScale(new Vector3(0.15f, 0.15f, 0f), 0.18f, 6, 0.75f));
_sequence.Join(_canvasGroup.DOFade(0f, FadeDuration).SetDelay(FadeDelay));
_sequence.OnComplete(() => _onComplete?.Invoke(this));
}
public void ResetItem()
{
KillSequence();
_onComplete = null;
_canvasGroup.alpha = 1f;
_text.text = string.Empty;
gameObject.SetActive(false);
}
private void OnDestroy()
{
KillSequence();
}
private void KillSequence()
{
if (_sequence == null) return;
_sequence.Kill();
_sequence = null;
}
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 40941eb45ca7d284f8a806370b88fa78
guid: 501e678f9cb14af6ac45e8d2050388d3
MonoImporter:
externalObjects: {}
serializedVersion: 2
@@ -0,0 +1,23 @@
using GameFramework;
using GameFramework.ObjectPool;
using UnityEngine;
namespace CustomComponent
{
public class DamageTextItemObject : ObjectBase
{
public static DamageTextItemObject Create(object target)
{
DamageTextItemObject itemObject = ReferencePool.Acquire<DamageTextItemObject>();
itemObject.Initialize(target);
return itemObject;
}
protected override void Release(bool isShutdown)
{
DamageTextItem item = (DamageTextItem)Target;
if (item == null) return;
Object.Destroy(item.gameObject);
}
}
}
@@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 7ddc8f13b2516c643a67d92a319dbf72
guid: 4aba1230dece448eba1fa7579ca7a13d
MonoImporter:
externalObjects: {}
serializedVersion: 2
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a11ef2e359b24bfdb6c9120cc2ec81b8
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,349 @@
#if UNITY_EDITOR || DEVELOPMENT_BUILD
using System;
using System.Linq;
using DataTable;
using Definition.DataStruct;
using Entity;
using Game.Utility;
using UnityEngine;
using UnityGameFramework.Runtime;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
namespace CustomComponent
{
public class RuntimeDebugPanelComponent : GameFrameworkComponent
{
private const float MinSpawnRate = 0.1f;
private const float CornerTapWindow = 0.6f;
private const int RequiredCornerTapCount = 3;
private Rect _windowRect = new Rect(20f, 60f, 460f, 620f);
private bool _isPanelVisible;
private int _windowId;
private string _searchText = string.Empty;
private int _selectedIndex;
private int _addCount = 1;
private Vector2 _buffScroll;
private float _spawnRateScaleInput = 1f;
private float _extendDurationSeconds = 30f;
private DRProp[] _allProps = Array.Empty<DRProp>();
private DRProp[] _filteredProps = Array.Empty<DRProp>();
private string[] _displayNames = Array.Empty<string>();
private int _cornerTapCount;
private float _lastCornerTapTime = -10f;
protected override void Awake()
{
base.Awake();
_windowId = GetInstanceID();
}
private void Update()
{
if (IsTogglePressed())
{
_isPanelVisible = !_isPanelVisible;
}
HandleCornerTapGesture();
}
private void OnGUI()
{
DrawToggleButton();
if (!_isPanelVisible) return;
_windowRect = GUI.Window(_windowId, _windowRect, DrawWindow, "Runtime Debug Panel");
}
private void DrawToggleButton()
{
const float width = 64f;
const float height = 30f;
Rect buttonRect = new Rect(Screen.width - width - 12f, 10f, width, height);
if (GUI.Button(buttonRect, "DEBUG"))
{
_isPanelVisible = !_isPanelVisible;
}
}
private void DrawWindow(int windowId)
{
EnsurePropList();
GUILayout.BeginVertical();
DrawBuffSection();
GUILayout.Space(8f);
GUILayout.Label(string.Empty, GUI.skin.horizontalSlider);
GUILayout.Space(8f);
DrawBattleSection();
GUILayout.Space(8f);
GUILayout.Label("Tips: press `F8` or tap top-left corner 3 times to toggle.", GUILayout.Height(20f));
GUILayout.EndVertical();
GUI.DragWindow(new Rect(0, 0, 10000, 22));
}
private void DrawBuffSection()
{
GUILayout.Label("Buff Debug");
GUILayout.BeginHorizontal();
GUILayout.Label("Search", GUILayout.Width(52f));
_searchText = GUILayout.TextField(_searchText);
if (GUILayout.Button("Refresh", GUILayout.Width(80f)))
{
EnsurePropList(true);
}
GUILayout.EndHorizontal();
ApplyFilter(_searchText);
if (_displayNames.Length == 0)
{
GUILayout.Label("No Buff data. Enter battle and try again.");
return;
}
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _displayNames.Length - 1);
_buffScroll = GUILayout.BeginScrollView(_buffScroll, GUILayout.Height(120f));
_selectedIndex = GUILayout.SelectionGrid(_selectedIndex, _displayNames, 1);
GUILayout.EndScrollView();
DRProp selectedProp = GetSelectedProp();
if (selectedProp == null) return;
GUILayout.Label($"Selected: {selectedProp.Title} ({selectedProp.Rarity})");
GUILayout.Label(ItemDescUtility.CreatePropDescription(selectedProp.Modifiers), GUILayout.Height(40f));
GUILayout.BeginHorizontal();
GUILayout.Label("Count", GUILayout.Width(52f));
string addCountText = GUILayout.TextField(_addCount.ToString(), GUILayout.Width(60f));
if (!int.TryParse(addCountText, out _addCount)) _addCount = 1;
_addCount = Mathf.Clamp(_addCount, 1, 99);
if (GUILayout.Button("Add Buff To Player", GUILayout.Height(24f)))
{
AddSelectedBuffToPlayer(selectedProp, _addCount);
}
GUILayout.EndHorizontal();
}
private void DrawBattleSection()
{
GUILayout.Label("Battle Debug");
EnemyManagerComponent enemyManager = GameEntry.EnemyManager;
Player player = FindPlayer();
if (enemyManager == null)
{
GUILayout.Label("EnemyManager unavailable.");
return;
}
GUILayout.Label($"Spawn Rate: {enemyManager.SpawnRateScale:F2}");
GUILayout.Label($"Battle Time: {enemyManager.ElapsedBattleTime:F1}s / {enemyManager.BattleDuration:F1}s");
GUILayout.BeginHorizontal();
GUILayout.Label("Rate", GUILayout.Width(52f));
string rateText = GUILayout.TextField(_spawnRateScaleInput.ToString("F2"), GUILayout.Width(60f));
if (float.TryParse(rateText, out float parsedRate))
{
_spawnRateScaleInput = Mathf.Clamp(parsedRate, MinSpawnRate, 50f);
}
if (GUILayout.Button("Apply", GUILayout.Width(70f)))
{
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
if (GUILayout.Button("x0.5", GUILayout.Width(60f)))
{
_spawnRateScaleInput = Mathf.Max(MinSpawnRate, enemyManager.SpawnRateScale * 0.5f);
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
if (GUILayout.Button("x2", GUILayout.Width(60f)))
{
_spawnRateScaleInput = enemyManager.SpawnRateScale * 2f;
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("Add Sec", GUILayout.Width(52f));
string durationText = GUILayout.TextField(_extendDurationSeconds.ToString("F0"), GUILayout.Width(60f));
if (float.TryParse(durationText, out float parsedDuration))
{
_extendDurationSeconds = Mathf.Clamp(parsedDuration, 1f, 3600f);
}
if (GUILayout.Button("Extend Battle", GUILayout.Height(24f)))
{
enemyManager.AddBattleDuration(_extendDurationSeconds);
}
GUILayout.EndHorizontal();
GUILayout.Label($"Player Weapon: {(player == null ? "Player not found" : (player.WeaponEnabled ? "Enabled" : "Disabled"))}");
GUILayout.BeginHorizontal();
GUI.enabled = player != null;
if (GUILayout.Button("Disable Weapons", GUILayout.Height(24f)))
{
player.SetWeaponEnabled(false);
}
if (GUILayout.Button("Enable Weapons", GUILayout.Height(24f)))
{
player.SetWeaponEnabled(true);
}
GUI.enabled = true;
GUILayout.EndHorizontal();
}
private void EnsurePropList(bool force = false)
{
if (!force && _allProps != null && _allProps.Length > 0) return;
if (GameEntry.DataTable == null)
{
_allProps = Array.Empty<DRProp>();
_filteredProps = Array.Empty<DRProp>();
_displayNames = Array.Empty<string>();
return;
}
var table = GameEntry.DataTable.GetDataTable<DRProp>();
_allProps = table != null ? table.ToArray() : Array.Empty<DRProp>();
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, Mathf.Max(0, _allProps.Length - 1));
ApplyFilter(_searchText);
}
private void ApplyFilter(string keyword)
{
if (_allProps == null || _allProps.Length == 0)
{
_filteredProps = Array.Empty<DRProp>();
_displayNames = Array.Empty<string>();
return;
}
if (string.IsNullOrWhiteSpace(keyword))
{
_filteredProps = _allProps;
}
else
{
string search = keyword.Trim();
_filteredProps = _allProps.Where(p =>
p != null &&
(p.Title?.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0 ||
p.Id.ToString().Contains(search))).ToArray();
}
_displayNames = _filteredProps.Select(p => $"[{p.Id}] {p.Title} ({p.Rarity})").ToArray();
if (_displayNames.Length == 0) _selectedIndex = 0;
else _selectedIndex = Mathf.Clamp(_selectedIndex, 0, _displayNames.Length - 1);
}
private DRProp GetSelectedProp()
{
if (_filteredProps == null || _filteredProps.Length == 0) return null;
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _filteredProps.Length - 1);
return _filteredProps[_selectedIndex];
}
private static Player FindPlayer()
{
return UnityEngine.Object.FindObjectOfType<Player>();
}
private static void AddSelectedBuffToPlayer(DRProp prop, int count)
{
Player player = FindPlayer();
if (player == null || prop == null || prop.Modifiers == null) return;
int applyCount = Mathf.Clamp(count, 1, 99);
for (int i = 0; i < applyCount; i++)
{
player.AddProp(new PropItem(prop.Modifiers, prop.Rarity, prop.Title, prop.IconAssetName));
}
}
private void HandleCornerTapGesture()
{
if (!TryGetTouchReleased(out Vector2 touchPosition)) return;
if (touchPosition.x > 80f || touchPosition.y < Screen.height - 80f) return;
float now = Time.unscaledTime;
if (now - _lastCornerTapTime > CornerTapWindow)
{
_cornerTapCount = 0;
}
_lastCornerTapTime = now;
_cornerTapCount++;
if (_cornerTapCount >= RequiredCornerTapCount)
{
_cornerTapCount = 0;
_isPanelVisible = !_isPanelVisible;
}
}
private static bool IsTogglePressed()
{
#if ENABLE_INPUT_SYSTEM
Keyboard keyboard = Keyboard.current;
if (keyboard == null) return false;
return keyboard.backquoteKey.wasPressedThisFrame || keyboard.f8Key.wasPressedThisFrame;
#else
return Input.GetKeyDown(KeyCode.BackQuote) || Input.GetKeyDown(KeyCode.F8);
#endif
}
private static bool TryGetTouchReleased(out Vector2 touchPosition)
{
#if ENABLE_INPUT_SYSTEM
Touchscreen touchscreen = Touchscreen.current;
if (touchscreen == null)
{
touchPosition = default;
return false;
}
var touch = touchscreen.primaryTouch;
if (!touch.press.wasReleasedThisFrame)
{
touchPosition = default;
return false;
}
touchPosition = touch.position.ReadValue();
return true;
#else
if (Input.touchCount <= 0)
{
touchPosition = default;
return false;
}
Touch touch = Input.GetTouch(0);
if (touch.phase != TouchPhase.Ended)
{
touchPosition = default;
return false;
}
touchPosition = touch.position;
return true;
#endif
}
}
}
#endif
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1d8ada5157a04921a6e543a040e57960
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -13,6 +13,8 @@ namespace CustomComponent
{
public class EnemyManagerComponent : GameFrameworkComponent
{
private const float MinSpawnRateScale = 0.1f;
private EntityComponent _entity;
private List<EntityBase> _enemies;
@@ -20,23 +22,35 @@ namespace CustomComponent
public List<EntityBase> Enemies => _enemies;
private float _spawnEnemyTimer;
private int _spawnEnemyMaxCount = 5000;
private int _currentEnemyCount;
private int _spawnDistanceFromPlayer = 20;
private int _currentSpawnEnemyId;
private int _currentLevel;
private float[] _baseSpawnEnemyIntervals;
private float[] _spawnEnemyIntervals;
private int[] _spawnEnemyIds;
private int[] _spawnEnemyCounts;
private float _duration;
private float _baseDuration;
private float[] _nextSpawnTimes;
private float _spawnRateScale = 1f;
private Transform _player;
private GameStateBattle _battle;
public float SpawnRateScale => _spawnRateScale;
public float BattleDuration => _duration;
public float ElapsedBattleTime => _spawnEnemyTimer;
#region FSM
private void Start()
@@ -64,12 +78,14 @@ namespace CustomComponent
_currentLevel = level;
DRLevel levelData = GameEntry.DataTable.GetDataTableRow<DRLevel>(_currentLevel);
_spawnEnemyIntervals = levelData.Intervals;
_baseSpawnEnemyIntervals = (float[])levelData.Intervals.Clone();
_spawnEnemyIntervals = (float[])_baseSpawnEnemyIntervals.Clone();
_spawnEnemyIds = levelData.EntityIds;
_spawnEnemyCounts = levelData.EntityCounts;
_duration = levelData.Duration;
_baseDuration = levelData.Duration;
_duration = _baseDuration;
_nextSpawnTimes = (float[])_spawnEnemyIntervals.Clone();
SetSpawnRateScale(_spawnRateScale);
_currentSpawnEnemyId = 0;
}
@@ -77,10 +93,7 @@ namespace CustomComponent
public void OnUpdate(float elapseSeconds, float realElapseSeconds)
{
_spawnEnemyTimer += elapseSeconds;
// if (_spawnEnemyTimer < _spawnEnemyInterval) return;
// SpawnEnemy();
// _spawnEnemyTimer = 0;
// _spawnEnemyInterval = Mathf.Max(0.1f, _spawnEnemyInterval - _spawnEnemyAccelerate);
if (_spawnEnemyTimer > _duration)
{
_battle.LevelOver();
@@ -108,9 +121,11 @@ namespace CustomComponent
_currentSpawnEnemyId = 0;
_currentLevel = 0;
_baseSpawnEnemyIntervals = null;
_spawnEnemyIntervals = null;
_spawnEnemyIds = null;
_spawnEnemyCounts = null;
_baseDuration = 0;
_duration = 0;
_nextSpawnTimes = null;
@@ -120,6 +135,57 @@ namespace CustomComponent
ClearEnemies();
}
public void SetSpawnRateScale(float scale)
{
float newScale = Mathf.Max(MinSpawnRateScale, scale);
if (_baseSpawnEnemyIntervals == null || _baseSpawnEnemyIntervals.Length == 0)
{
_spawnRateScale = newScale;
return;
}
bool hasRuntimeState = _nextSpawnTimes != null && _spawnEnemyIntervals != null &&
_nextSpawnTimes.Length == _baseSpawnEnemyIntervals.Length &&
_spawnEnemyIntervals.Length == _baseSpawnEnemyIntervals.Length;
float oldScale = _spawnRateScale;
_spawnRateScale = newScale;
if (!hasRuntimeState)
{
for (int i = 0; i < _baseSpawnEnemyIntervals.Length; i++)
{
_spawnEnemyIntervals[i] = GetScaledInterval(_baseSpawnEnemyIntervals[i], _spawnRateScale);
}
_nextSpawnTimes = (float[])_spawnEnemyIntervals.Clone();
return;
}
for (int i = 0; i < _baseSpawnEnemyIntervals.Length; i++)
{
float oldInterval = GetScaledInterval(_baseSpawnEnemyIntervals[i], oldScale);
float newInterval = GetScaledInterval(_baseSpawnEnemyIntervals[i], _spawnRateScale);
float remainTime = Mathf.Max(0f, _nextSpawnTimes[i] - _spawnEnemyTimer);
float remainRatio = oldInterval > Mathf.Epsilon ? Mathf.Clamp01(remainTime / oldInterval) : 0f;
_spawnEnemyIntervals[i] = newInterval;
_nextSpawnTimes[i] = _spawnEnemyTimer + newInterval * remainRatio;
}
}
public void AddBattleDuration(float seconds)
{
if (seconds <= 0f) return;
_duration += seconds;
}
private static float GetScaledInterval(float baseInterval, float scale)
{
float safeScale = Mathf.Max(MinSpawnRateScale, scale);
return baseInterval / safeScale;
}
#endregion
private void SpawnEnemy(int entityId)
@@ -128,7 +194,7 @@ namespace CustomComponent
if (_currentEnemyCount >= _spawnEnemyMaxCount) return;
int entityPoolId = _currentSpawnEnemyId % _spawnEnemyMaxCount;
var enemyData = new EnemyData(entityPoolId, entityId)
var enemyData = new EnemyData(entityPoolId, entityId, _currentLevel)
{
Position = GetRandomPosition()
};
@@ -187,4 +253,4 @@ namespace CustomComponent
#endregion
}
}
}
@@ -17,14 +17,11 @@ namespace CustomComponent
{
public class HPBarComponent : GameFrameworkComponent
{
[FormerlySerializedAs("m_HPBarItemTemplate")] [SerializeField]
private HPBarItem _hpBarItemTemplate = null;
[SerializeField] private HPBarItem _hpBarItemTemplate = null;
[FormerlySerializedAs("m_HPBarInstanceRoot")] [SerializeField]
private Transform _hpBarInstanceRoot = null;
[SerializeField] private Transform _hpBarInstanceRoot = null;
[FormerlySerializedAs("m_InstancePoolCapacity")] [SerializeField]
private int _instancePoolCapacity = 16;
[SerializeField] private int _instancePoolCapacity = 16;
private IObjectPool<HPBarItemObject> _hpBarItemObjectPool = null;
private List<HPBarItem> _activeHPBarItems = null;
@@ -39,7 +36,8 @@ namespace CustomComponent
}
_cachedCanvas = _hpBarInstanceRoot.GetComponent<Canvas>();
_hpBarItemObjectPool = GameEntry.ObjectPool.CreateSingleSpawnObjectPool<HPBarItemObject>("HPBarItem", _instancePoolCapacity);
_hpBarItemObjectPool =
GameEntry.ObjectPool.CreateSingleSpawnObjectPool<HPBarItemObject>("HPBarItem", _instancePoolCapacity);
_activeHPBarItems = new List<HPBarItem>();
}
@@ -124,4 +122,4 @@ namespace CustomComponent
return hpBarItem;
}
}
}
}
+3 -1
View File
@@ -7,6 +7,7 @@ namespace DataTable
private int m_id;
public override int Id => m_id;
public int MaxHealth { get; private set; }
public int HpAddPerLevel { get; private set; }
public float Speed { get; private set; }
public int DropCoin { get; private set; }
public int DropExp { get; private set; }
@@ -21,6 +22,7 @@ namespace DataTable
m_id = int.Parse(columnStrings[index++]);
index++;
MaxHealth = int.Parse(columnStrings[index++]);
HpAddPerLevel = int.Parse(columnStrings[index++]);
Speed = float.Parse(columnStrings[index++]);
DropCoin = int.Parse(columnStrings[index++]);
DropExp = int.Parse(columnStrings[index++]);
@@ -29,4 +31,4 @@ namespace DataTable
return true;
}
}
}
}
@@ -0,0 +1,39 @@
using UnityGameFramework.Runtime;
namespace DataTable
{
public class DRLevelRarity : DataRowBase
{
private int m_Id;
public override int Id => m_Id;
public int LevelMin { get; private set; }
public int LevelMax { get; private set; }
public int WhiteWeight { get; private set; }
public int GreenWeight { get; private set; }
public int BlueWeight { get; private set; }
public int PurpleWeight { get; private set; }
public int RedWeight { get; private set; }
public override bool ParseDataRow(string dataRowString, object userData)
{
string[] fields = dataRowString.Split(DataTableExtension.DataSplitSeparators);
int index = 0;
index++;
m_Id = int.Parse(fields[index++]);
index++;
LevelMin = int.Parse(fields[index++]);
LevelMax = int.Parse(fields[index++]);
WhiteWeight = int.Parse(fields[index++]);
GreenWeight = int.Parse(fields[index++]);
BlueWeight = int.Parse(fields[index++]);
PurpleWeight = int.Parse(fields[index++]);
RedWeight = int.Parse(fields[index++]);
return true;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2be3a3c9896a441496abfb07467e9e19
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,5 +1,7 @@
using Definition.DataStruct;
using Definition.Enum;
using Newtonsoft.Json;
using StarForce;
using UnityGameFramework.Runtime;
namespace DataTable
@@ -13,6 +15,8 @@ namespace DataTable
public string Title { get; private set; }
public string IconAssetName { get; private set; }
public ItemRarity Rarity { get; private set; }
public StatModifier[] Modifiers { get; private set; }
@@ -26,6 +30,7 @@ namespace DataTable
index++;
Title = fields[index++];
IconAssetName = fields[index++];
Rarity = EnumUtility<ItemRarity>.Get(fields[index++]);
Modifiers = JsonConvert.DeserializeObject<StatModifier[]>(fields[index++]);
return true;
@@ -16,6 +16,7 @@ namespace Definition.DataStruct
// Critical = 6,
// CriticalDamage = 7,
// Dodge = 8,
// AbsorbRange = 9
private readonly string[] _statTypeNames =
{
@@ -27,7 +28,8 @@ namespace Definition.DataStruct
"冷却",
"暴击率",
"暴击伤害",
"闪避"
"闪避",
"金币/经验吸收范围"
};
public StatType StatType;
@@ -3,7 +3,7 @@ namespace Definition.Enum
public enum StatType
{
None = 0,
MaxHealth = 1,
MovementSpeed = 2,
Attack = 3,
@@ -12,5 +12,6 @@ namespace Definition.Enum
Critical = 6,
CriticalDamage = 7,
Dodge = 8,
AbsorbRange = 9,
}
}
}
@@ -1,13 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.Text;
namespace StarForce.Editor.DataTableTools
{
public delegate void DataTableCodeGenerator(DataTableProcessor dataTableProcessor, StringBuilder codeContent, object userData);
}
@@ -1,412 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
namespace StarForce.Editor.DataTableTools
{
public sealed class DataTableGenerator
{
private const string DataTablePath = "Assets/GameMain/DataTables";
private const string CSharpCodePath = "Assets/GameMain/Scripts/DataTable";
private const string CSharpCodeTemplateFileName = "Assets/GameMain/Configs/DataTableCodeTemplate.txt";
private static readonly Regex EndWithNumberRegex = new Regex(@"\d+$");
private static readonly Regex NameRegex = new Regex(@"^[A-Z][A-Za-z0-9_]*$");
public static DataTableProcessor CreateDataTableProcessor(string dataTableName)
{
return new DataTableProcessor(Utility.Path.GetRegularPath(Path.Combine(DataTablePath, dataTableName + ".txt")), Encoding.GetEncoding("GB2312"), 1, 2, null, 3, 4, 1);
}
public static bool CheckRawData(DataTableProcessor dataTableProcessor, string dataTableName)
{
for (int i = 0; i < dataTableProcessor.RawColumnCount; i++)
{
string name = dataTableProcessor.GetName(i);
if (string.IsNullOrEmpty(name) || name == "#")
{
continue;
}
if (!NameRegex.IsMatch(name))
{
Debug.LogWarning(Utility.Text.Format("Check raw data failure. DataTableName='{0}' Name='{1}'", dataTableName, name));
return false;
}
}
return true;
}
public static void GenerateDataFile(DataTableProcessor dataTableProcessor, string dataTableName)
{
string binaryDataFileName = Utility.Path.GetRegularPath(Path.Combine(DataTablePath, dataTableName + ".bytes"));
if (!dataTableProcessor.GenerateDataFile(binaryDataFileName) && File.Exists(binaryDataFileName))
{
File.Delete(binaryDataFileName);
}
}
public static void GenerateCodeFile(DataTableProcessor dataTableProcessor, string dataTableName)
{
dataTableProcessor.SetCodeTemplate(CSharpCodeTemplateFileName, Encoding.UTF8);
dataTableProcessor.SetCodeGenerator(DataTableCodeGenerator);
string csharpCodeFileName = Utility.Path.GetRegularPath(Path.Combine(CSharpCodePath, "DR" + dataTableName + ".cs"));
if (!dataTableProcessor.GenerateCodeFile(csharpCodeFileName, Encoding.UTF8, dataTableName) && File.Exists(csharpCodeFileName))
{
File.Delete(csharpCodeFileName);
}
}
private static void DataTableCodeGenerator(DataTableProcessor dataTableProcessor, StringBuilder codeContent, object userData)
{
string dataTableName = (string)userData;
codeContent.Replace("__DATA_TABLE_CREATE_TIME__", DateTime.UtcNow.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss.fff"));
codeContent.Replace("__DATA_TABLE_NAME_SPACE__", "StarForce");
codeContent.Replace("__DATA_TABLE_CLASS_NAME__", "DR" + dataTableName);
codeContent.Replace("__DATA_TABLE_COMMENT__", dataTableProcessor.GetValue(0, 1) + "。");
codeContent.Replace("__DATA_TABLE_ID_COMMENT__", "获取" + dataTableProcessor.GetComment(dataTableProcessor.IdColumn) + "。");
codeContent.Replace("__DATA_TABLE_PROPERTIES__", GenerateDataTableProperties(dataTableProcessor));
codeContent.Replace("__DATA_TABLE_PARSER__", GenerateDataTableParser(dataTableProcessor));
codeContent.Replace("__DATA_TABLE_PROPERTY_ARRAY__", GenerateDataTablePropertyArray(dataTableProcessor));
}
private static string GenerateDataTableProperties(DataTableProcessor dataTableProcessor)
{
StringBuilder stringBuilder = new StringBuilder();
bool firstProperty = true;
for (int i = 0; i < dataTableProcessor.RawColumnCount; i++)
{
if (dataTableProcessor.IsCommentColumn(i))
{
// 注释列
continue;
}
if (dataTableProcessor.IsIdColumn(i))
{
// 编号列
continue;
}
if (firstProperty)
{
firstProperty = false;
}
else
{
stringBuilder.AppendLine().AppendLine();
}
stringBuilder
.AppendLine(" /// <summary>")
.AppendFormat(" /// 获取{0}。", dataTableProcessor.GetComment(i)).AppendLine()
.AppendLine(" /// </summary>")
.AppendFormat(" public {0} {1}", dataTableProcessor.GetLanguageKeyword(i), dataTableProcessor.GetName(i)).AppendLine()
.AppendLine(" {")
.AppendLine(" get;")
.AppendLine(" private set;")
.Append(" }");
}
return stringBuilder.ToString();
}
private static string GenerateDataTableParser(DataTableProcessor dataTableProcessor)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder
.AppendLine(" public override bool ParseDataRow(string dataRowString, object userData)")
.AppendLine(" {")
.AppendLine(" string[] columnStrings = dataRowString.Split(DataTableExtension.DataSplitSeparators);")
.AppendLine(" for (int i = 0; i < columnStrings.Length; i++)")
.AppendLine(" {")
.AppendLine(" columnStrings[i] = columnStrings[i].Trim(DataTableExtension.DataTrimSeparators);")
.AppendLine(" }")
.AppendLine()
.AppendLine(" int index = 0;");
for (int i = 0; i < dataTableProcessor.RawColumnCount; i++)
{
if (dataTableProcessor.IsCommentColumn(i))
{
// 注释列
stringBuilder.AppendLine(" index++;");
continue;
}
if (dataTableProcessor.IsIdColumn(i))
{
// 编号列
stringBuilder.AppendLine(" m_Id = int.Parse(columnStrings[index++]);");
continue;
}
if (dataTableProcessor.IsSystem(i))
{
string languageKeyword = dataTableProcessor.GetLanguageKeyword(i);
if (languageKeyword == "string")
{
stringBuilder.AppendFormat(" {0} = columnStrings[index++];", dataTableProcessor.GetName(i)).AppendLine();
}
else
{
stringBuilder.AppendFormat(" {0} = {1}.Parse(columnStrings[index++]);", dataTableProcessor.GetName(i), languageKeyword).AppendLine();
}
}
else
{
stringBuilder.AppendFormat(" {0} = DataTableExtension.Parse{1}(columnStrings[index++]);", dataTableProcessor.GetName(i), dataTableProcessor.GetType(i).Name).AppendLine();
}
}
stringBuilder.AppendLine()
.AppendLine(" GeneratePropertyArray();")
.AppendLine(" return true;")
.AppendLine(" }")
.AppendLine()
.AppendLine(" public override bool ParseDataRow(byte[] dataRowBytes, int startIndex, int length, object userData)")
.AppendLine(" {")
.AppendLine(" using (MemoryStream memoryStream = new MemoryStream(dataRowBytes, startIndex, length, false))")
.AppendLine(" {")
.AppendLine(" using (BinaryReader binaryReader = new BinaryReader(memoryStream, Encoding.UTF8))")
.AppendLine(" {");
for (int i = 0; i < dataTableProcessor.RawColumnCount; i++)
{
if (dataTableProcessor.IsCommentColumn(i))
{
// 注释列
continue;
}
if (dataTableProcessor.IsIdColumn(i))
{
// 编号列
stringBuilder.AppendLine(" m_Id = binaryReader.Read7BitEncodedInt32();");
continue;
}
string languageKeyword = dataTableProcessor.GetLanguageKeyword(i);
if (languageKeyword == "int" || languageKeyword == "uint" || languageKeyword == "long" || languageKeyword == "ulong")
{
stringBuilder.AppendFormat(" {0} = binaryReader.Read7BitEncoded{1}();", dataTableProcessor.GetName(i), dataTableProcessor.GetType(i).Name).AppendLine();
}
else
{
stringBuilder.AppendFormat(" {0} = binaryReader.Read{1}();", dataTableProcessor.GetName(i), dataTableProcessor.GetType(i).Name).AppendLine();
}
}
stringBuilder
.AppendLine(" }")
.AppendLine(" }")
.AppendLine()
.AppendLine(" GeneratePropertyArray();")
.AppendLine(" return true;")
.Append(" }");
return stringBuilder.ToString();
}
private static string GenerateDataTablePropertyArray(DataTableProcessor dataTableProcessor)
{
List<PropertyCollection> propertyCollections = new List<PropertyCollection>();
for (int i = 0; i < dataTableProcessor.RawColumnCount; i++)
{
if (dataTableProcessor.IsCommentColumn(i))
{
// 注释列
continue;
}
if (dataTableProcessor.IsIdColumn(i))
{
// 编号列
continue;
}
string name = dataTableProcessor.GetName(i);
if (!EndWithNumberRegex.IsMatch(name))
{
continue;
}
string propertyCollectionName = EndWithNumberRegex.Replace(name, string.Empty);
int id = int.Parse(EndWithNumberRegex.Match(name).Value);
PropertyCollection propertyCollection = null;
foreach (PropertyCollection pc in propertyCollections)
{
if (pc.Name == propertyCollectionName)
{
propertyCollection = pc;
break;
}
}
if (propertyCollection == null)
{
propertyCollection = new PropertyCollection(propertyCollectionName, dataTableProcessor.GetLanguageKeyword(i));
propertyCollections.Add(propertyCollection);
}
propertyCollection.AddItem(id, name);
}
StringBuilder stringBuilder = new StringBuilder();
bool firstProperty = true;
foreach (PropertyCollection propertyCollection in propertyCollections)
{
if (firstProperty)
{
firstProperty = false;
}
else
{
stringBuilder.AppendLine().AppendLine();
}
stringBuilder
.AppendFormat(" private KeyValuePair<int, {1}>[] m_{0} = null;", propertyCollection.Name, propertyCollection.LanguageKeyword).AppendLine()
.AppendLine()
.AppendFormat(" public int {0}Count", propertyCollection.Name).AppendLine()
.AppendLine(" {")
.AppendLine(" get")
.AppendLine(" {")
.AppendFormat(" return m_{0}.Length;", propertyCollection.Name).AppendLine()
.AppendLine(" }")
.AppendLine(" }")
.AppendLine()
.AppendFormat(" public {1} Get{0}(int id)", propertyCollection.Name, propertyCollection.LanguageKeyword).AppendLine()
.AppendLine(" {")
.AppendFormat(" foreach (KeyValuePair<int, {1}> i in m_{0})", propertyCollection.Name, propertyCollection.LanguageKeyword).AppendLine()
.AppendLine(" {")
.AppendLine(" if (i.Key == id)")
.AppendLine(" {")
.AppendLine(" return i.Value;")
.AppendLine(" }")
.AppendLine(" }")
.AppendLine()
.AppendFormat(" throw new GameFrameworkException(Utility.Text.Format(\"Get{0} with invalid id '{{0}}'.\", id));", propertyCollection.Name).AppendLine()
.AppendLine(" }")
.AppendLine()
.AppendFormat(" public {1} Get{0}At(int index)", propertyCollection.Name, propertyCollection.LanguageKeyword).AppendLine()
.AppendLine(" {")
.AppendFormat(" if (index < 0 || index >= m_{0}.Length)", propertyCollection.Name).AppendLine()
.AppendLine(" {")
.AppendFormat(" throw new GameFrameworkException(Utility.Text.Format(\"Get{0}At with invalid index '{{0}}'.\", index));", propertyCollection.Name).AppendLine()
.AppendLine(" }")
.AppendLine()
.AppendFormat(" return m_{0}[index].Value;", propertyCollection.Name).AppendLine()
.Append(" }");
}
if (propertyCollections.Count > 0)
{
stringBuilder.AppendLine().AppendLine();
}
stringBuilder
.AppendLine(" private void GeneratePropertyArray()")
.AppendLine(" {");
firstProperty = true;
foreach (PropertyCollection propertyCollection in propertyCollections)
{
if (firstProperty)
{
firstProperty = false;
}
else
{
stringBuilder.AppendLine().AppendLine();
}
stringBuilder
.AppendFormat(" m_{0} = new KeyValuePair<int, {1}>[]", propertyCollection.Name, propertyCollection.LanguageKeyword).AppendLine()
.AppendLine(" {");
int itemCount = propertyCollection.ItemCount;
for (int i = 0; i < itemCount; i++)
{
KeyValuePair<int, string> item = propertyCollection.GetItem(i);
stringBuilder.AppendFormat(" new KeyValuePair<int, {0}>({1}, {2}),", propertyCollection.LanguageKeyword, item.Key.ToString(), item.Value).AppendLine();
}
stringBuilder.Append(" };");
}
stringBuilder
.AppendLine()
.Append(" }");
return stringBuilder.ToString();
}
private sealed class PropertyCollection
{
private readonly string m_Name;
private readonly string m_LanguageKeyword;
private readonly List<KeyValuePair<int, string>> m_Items;
public PropertyCollection(string name, string languageKeyword)
{
m_Name = name;
m_LanguageKeyword = languageKeyword;
m_Items = new List<KeyValuePair<int, string>>();
}
public string Name
{
get
{
return m_Name;
}
}
public string LanguageKeyword
{
get
{
return m_LanguageKeyword;
}
}
public int ItemCount
{
get
{
return m_Items.Count;
}
}
public KeyValuePair<int, string> GetItem(int index)
{
if (index < 0 || index >= m_Items.Count)
{
throw new GameFrameworkException(Utility.Text.Format("GetItem with invalid index '{0}'.", index));
}
return m_Items[index];
}
public void AddItem(int id, string propertyName)
{
m_Items.Add(new KeyValuePair<int, string>(id, propertyName));
}
}
}
}
@@ -1,36 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using Procedure;
using UnityEditor;
using UnityEngine;
namespace StarForce.Editor.DataTableTools
{
public sealed class DataTableGeneratorMenu
{
[MenuItem("Star Force/Generate DataTables")]
private static void GenerateDataTables()
{
foreach (string dataTableName in ProcedurePreload.DataTableNames)
{
DataTableProcessor dataTableProcessor = DataTableGenerator.CreateDataTableProcessor(dataTableName);
if (!DataTableGenerator.CheckRawData(dataTableProcessor, dataTableName))
{
Debug.LogError(Utility.Text.Format("Check raw data failure. DataTableName='{0}'", dataTableName));
break;
}
DataTableGenerator.GenerateDataFile(dataTableProcessor, dataTableName);
DataTableGenerator.GenerateCodeFile(dataTableProcessor, dataTableName);
}
AssetDatabase.Refresh();
}
}
}
@@ -1,53 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class BooleanProcessor : GenericDataProcessor<bool>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "bool";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"bool",
"boolean",
"system.boolean"
};
}
public override bool Parse(string value)
{
return bool.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value));
}
}
}
}
@@ -1,52 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class ByteProcessor : GenericDataProcessor<byte>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "byte";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"byte",
"system.byte"
};
}
public override byte Parse(string value)
{
return byte.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 11199a40fe5a3ef49a3c3d1ae670ac97
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,52 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class CharProcessor : GenericDataProcessor<char>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "char";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"char",
"system.char"
};
}
public override char Parse(string value)
{
return char.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 37f1181bc8fb29742b06ec3f42f652b4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,58 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
using UnityEngine;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class Color32Processor : GenericDataProcessor<Color32>
{
public override bool IsSystem
{
get
{
return false;
}
}
public override string LanguageKeyword
{
get
{
return "Color32";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"color32",
"unityengine.color32"
};
}
public override Color32 Parse(string value)
{
string[] splitedValue = value.Split(',');
return new Color32(byte.Parse(splitedValue[0]), byte.Parse(splitedValue[1]), byte.Parse(splitedValue[2]), byte.Parse(splitedValue[3]));
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
Color32 color32 = Parse(value);
binaryWriter.Write(color32.r);
binaryWriter.Write(color32.g);
binaryWriter.Write(color32.b);
binaryWriter.Write(color32.a);
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2a9b916d7c8e446439b74c27340be473
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,58 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
using UnityEngine;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class ColorProcessor : GenericDataProcessor<Color>
{
public override bool IsSystem
{
get
{
return false;
}
}
public override string LanguageKeyword
{
get
{
return "Color";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"color",
"unityengine.color"
};
}
public override Color Parse(string value)
{
string[] splitedValue = value.Split(',');
return new Color(float.Parse(splitedValue[0]), float.Parse(splitedValue[1]), float.Parse(splitedValue[2]), float.Parse(splitedValue[3]));
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
Color color = Parse(value);
binaryWriter.Write(color.r);
binaryWriter.Write(color.g);
binaryWriter.Write(color.b);
binaryWriter.Write(color.a);
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f4583af9902c99a4fad14d732796117e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,71 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class CommentProcessor : DataProcessor
{
public override System.Type Type
{
get
{
return null;
}
}
public override bool IsId
{
get
{
return false;
}
}
public override bool IsComment
{
get
{
return true;
}
}
public override bool IsSystem
{
get
{
return false;
}
}
public override string LanguageKeyword
{
get
{
return null;
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
string.Empty,
"#",
"comment"
};
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 2ece238877c1e9344a50ce47697a93ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,46 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
public abstract class DataProcessor
{
public abstract System.Type Type
{
get;
}
public abstract bool IsId
{
get;
}
public abstract bool IsComment
{
get;
}
public abstract bool IsSystem
{
get;
}
public abstract string LanguageKeyword
{
get;
}
public abstract string[] GetTypeStrings();
public abstract void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value);
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ccc7c992b5573ae4fafd0d5706bdad48
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,61 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private static class DataProcessorUtility
{
private static readonly IDictionary<string, DataProcessor> s_DataProcessors = new SortedDictionary<string, DataProcessor>(StringComparer.Ordinal);
static DataProcessorUtility()
{
System.Type dataProcessorBaseType = typeof(DataProcessor);
Assembly assembly = Assembly.GetExecutingAssembly();
System.Type[] types = assembly.GetTypes();
for (int i = 0; i < types.Length; i++)
{
if (!types[i].IsClass || types[i].IsAbstract)
{
continue;
}
if (dataProcessorBaseType.IsAssignableFrom(types[i]))
{
DataProcessor dataProcessor = (DataProcessor)Activator.CreateInstance(types[i]);
foreach (string typeString in dataProcessor.GetTypeStrings())
{
s_DataProcessors.Add(typeString.ToLowerInvariant(), dataProcessor);
}
}
}
}
public static DataProcessor GetDataProcessor(string type)
{
if (type == null)
{
type = string.Empty;
}
DataProcessor dataProcessor = null;
if (s_DataProcessors.TryGetValue(type.ToLowerInvariant(), out dataProcessor))
{
return dataProcessor;
}
throw new GameFrameworkException(Utility.Text.Format("Not supported data processor type '{0}'.", type));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 83d25f17cbb262649959b7952811f8c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,53 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System;
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class DateTimeProcessor : GenericDataProcessor<DateTime>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "DateTime";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"datetime",
"system.datetime"
};
}
public override DateTime Parse(string value)
{
return DateTime.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value).Ticks);
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 4223bbe977dd5244a8611c6aad7f693e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,52 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class DecimalProcessor : GenericDataProcessor<decimal>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "decimal";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"decimal",
"system.decimal"
};
}
public override decimal Parse(string value)
{
return decimal.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: ad6d6ba18487f7643830e156d300ee75
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,52 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class DoubleProcessor : GenericDataProcessor<double>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "double";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"double",
"system.double"
};
}
public override double Parse(string value)
{
return double.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 44293fe0c3e108248bc98e8674238aed
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,41 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
public abstract class GenericDataProcessor<T> : DataProcessor
{
public override System.Type Type
{
get
{
return typeof(T);
}
}
public override bool IsId
{
get
{
return false;
}
}
public override bool IsComment
{
get
{
return false;
}
}
public abstract T Parse(string value);
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 65dd2cb98d350654fb3df2ddfc4fa4b8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,70 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class IdProcessor : DataProcessor
{
public override System.Type Type
{
get
{
return typeof(int);
}
}
public override bool IsId
{
get
{
return true;
}
}
public override bool IsComment
{
get
{
return false;
}
}
public override bool IsSystem
{
get
{
return false;
}
}
public override string LanguageKeyword
{
get
{
return "int";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"id"
};
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write7BitEncodedInt32(int.Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: f4171c2dabb4ee9468f7297ab334ddf1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,53 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class Int16Processor : GenericDataProcessor<short>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "short";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"short",
"int16",
"system.int16"
};
}
public override short Parse(string value)
{
return short.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c1e3b1767ca81c343a31324956e5f032
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,53 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class Int32Processor : GenericDataProcessor<int>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "int";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"int",
"int32",
"system.int32"
};
}
public override int Parse(string value)
{
return int.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write7BitEncodedInt32(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 239560231c239b54f95c183913ec9cbf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,53 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class Int64Processor : GenericDataProcessor<long>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "long";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"long",
"int64",
"system.int64"
};
}
public override long Parse(string value)
{
return long.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write7BitEncodedInt64(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d6dadc699adc6744e898979b1e85d6cf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,58 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
using UnityEngine;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class QuaternionProcessor : GenericDataProcessor<Quaternion>
{
public override bool IsSystem
{
get
{
return false;
}
}
public override string LanguageKeyword
{
get
{
return "Quaternion";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"quaternion",
"unityengine.quaternion"
};
}
public override Quaternion Parse(string value)
{
string[] splitedValue = value.Split(',');
return new Quaternion(float.Parse(splitedValue[0]), float.Parse(splitedValue[1]), float.Parse(splitedValue[2]), float.Parse(splitedValue[3]));
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
Quaternion quaternion = Parse(value);
binaryWriter.Write(quaternion.x);
binaryWriter.Write(quaternion.y);
binaryWriter.Write(quaternion.z);
binaryWriter.Write(quaternion.w);
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: c288505f764c21149b9986dd3ebff1ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,58 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
using UnityEngine;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class RectProcessor : GenericDataProcessor<Rect>
{
public override bool IsSystem
{
get
{
return false;
}
}
public override string LanguageKeyword
{
get
{
return "Rect";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"rect",
"unityengine.rect"
};
}
public override Rect Parse(string value)
{
string[] splitedValue = value.Split(',');
return new Rect(float.Parse(splitedValue[0]), float.Parse(splitedValue[1]), float.Parse(splitedValue[2]), float.Parse(splitedValue[3]));
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
Rect rect = Parse(value);
binaryWriter.Write(rect.x);
binaryWriter.Write(rect.y);
binaryWriter.Write(rect.width);
binaryWriter.Write(rect.height);
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 235589b35d4744a4d8ef100da517e0ce
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,52 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class SByteProcessor : GenericDataProcessor<sbyte>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "sbyte";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"sbyte",
"system.sbyte"
};
}
public override sbyte Parse(string value)
{
return sbyte.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 49f8d16f80f1ec046bfcae38be8c96a7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,53 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class SingleProcessor : GenericDataProcessor<float>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "float";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"float",
"single",
"system.single"
};
}
public override float Parse(string value)
{
return float.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 4c1502c70e1294543b14df45c7841a73
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,52 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class StringProcessor : GenericDataProcessor<string>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "string";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"string",
"system.string"
};
}
public override string Parse(string value)
{
return value;
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d502b9a1939b46246bd8e4c107b77744
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,53 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class UInt16Processor : GenericDataProcessor<ushort>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "ushort";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"ushort",
"uint16",
"system.uint16"
};
}
public override ushort Parse(string value)
{
return ushort.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 20f758534f1981b4593f97deb2a5ae25
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,53 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class UInt32Processor : GenericDataProcessor<uint>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "uint";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"uint",
"uint32",
"system.uint32"
};
}
public override uint Parse(string value)
{
return uint.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write7BitEncodedUInt32(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: fd3c289549d93924ea928ea558436a57
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,53 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class UInt64Processor : GenericDataProcessor<ulong>
{
public override bool IsSystem
{
get
{
return true;
}
}
public override string LanguageKeyword
{
get
{
return "ulong";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"ulong",
"uint64",
"system.uint64"
};
}
public override ulong Parse(string value)
{
return ulong.Parse(value);
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
binaryWriter.Write7BitEncodedUInt64(Parse(value));
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 23d841306167268488c7c5a8bb8cf685
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,56 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
using UnityEngine;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class Vector2Processor : GenericDataProcessor<Vector2>
{
public override bool IsSystem
{
get
{
return false;
}
}
public override string LanguageKeyword
{
get
{
return "Vector2";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"vector2",
"unityengine.vector2"
};
}
public override Vector2 Parse(string value)
{
string[] splitedValue = value.Split(',');
return new Vector2(float.Parse(splitedValue[0]), float.Parse(splitedValue[1]));
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
Vector2 vector2 = Parse(value);
binaryWriter.Write(vector2.x);
binaryWriter.Write(vector2.y);
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 165df2a7d4a52984282f1c3bc87d5aaa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,57 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
using UnityEngine;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class Vector3Processor : GenericDataProcessor<Vector3>
{
public override bool IsSystem
{
get
{
return false;
}
}
public override string LanguageKeyword
{
get
{
return "Vector3";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"vector3",
"unityengine.vector3"
};
}
public override Vector3 Parse(string value)
{
string[] splitedValue = value.Split(',');
return new Vector3(float.Parse(splitedValue[0]), float.Parse(splitedValue[1]), float.Parse(splitedValue[2]));
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
Vector3 vector3 = Parse(value);
binaryWriter.Write(vector3.x);
binaryWriter.Write(vector3.y);
binaryWriter.Write(vector3.z);
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: d45ef71d28b25f047ab0f4d4acac8b42
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,58 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using System.IO;
using UnityEngine;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private sealed class Vector4Processor : GenericDataProcessor<Vector4>
{
public override bool IsSystem
{
get
{
return false;
}
}
public override string LanguageKeyword
{
get
{
return "Vector4";
}
}
public override string[] GetTypeStrings()
{
return new string[]
{
"vector4",
"unityengine.vector4"
};
}
public override Vector4 Parse(string value)
{
string[] splitedValue = value.Split(',');
return new Vector4(float.Parse(splitedValue[0]), float.Parse(splitedValue[1]), float.Parse(splitedValue[2]), float.Parse(splitedValue[3]));
}
public override void WriteToStream(DataTableProcessor dataTableProcessor, BinaryWriter binaryWriter, string value)
{
Vector4 vector4 = Parse(value);
binaryWriter.Write(vector4.x);
binaryWriter.Write(vector4.y);
binaryWriter.Write(vector4.z);
binaryWriter.Write(vector4.w);
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 40409bde40a898b48af91126d343c4ae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -1,498 +0,0 @@
//------------------------------------------------------------
// Game Framework
// Copyright © 2013-2021 Jiang Yin. All rights reserved.
// Homepage: https://gameframework.cn/
// Feedback: mailto:ellan@gameframework.cn
//------------------------------------------------------------
using GameFramework;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using UnityEngine;
namespace StarForce.Editor.DataTableTools
{
public sealed partial class DataTableProcessor
{
private const string CommentLineSeparator = "#";
private static readonly char[] DataSplitSeparators = new char[] { '\t' };
private static readonly char[] DataTrimSeparators = new char[] { '\"' };
private readonly string[] m_NameRow;
private readonly string[] m_TypeRow;
private readonly string[] m_DefaultValueRow;
private readonly string[] m_CommentRow;
private readonly int m_ContentStartRow;
private readonly int m_IdColumn;
private readonly DataProcessor[] m_DataProcessor;
private readonly string[][] m_RawValues;
private readonly string[] m_Strings;
private string m_CodeTemplate;
private DataTableCodeGenerator m_CodeGenerator;
public DataTableProcessor(string dataTableFileName, Encoding encoding, int nameRow, int typeRow, int? defaultValueRow, int? commentRow, int contentStartRow, int idColumn)
{
if (string.IsNullOrEmpty(dataTableFileName))
{
throw new GameFrameworkException("Data table file name is invalid.");
}
if (!dataTableFileName.EndsWith(".txt", StringComparison.Ordinal))
{
throw new GameFrameworkException(Utility.Text.Format("Data table file '{0}' is not a txt.", dataTableFileName));
}
if (!File.Exists(dataTableFileName))
{
throw new GameFrameworkException(Utility.Text.Format("Data table file '{0}' is not exist.", dataTableFileName));
}
string[] lines = File.ReadAllLines(dataTableFileName, encoding);
int rawRowCount = lines.Length;
int rawColumnCount = 0;
List<string[]> rawValues = new List<string[]>();
for (int i = 0; i < lines.Length; i++)
{
string[] rawValue = lines[i].Split(DataSplitSeparators);
for (int j = 0; j < rawValue.Length; j++)
{
rawValue[j] = rawValue[j].Trim(DataTrimSeparators);
}
if (i == 0)
{
rawColumnCount = rawValue.Length;
}
else if (rawValue.Length != rawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Data table file '{0}', raw Column is '{2}', but line '{1}' column is '{3}'.", dataTableFileName, i, rawColumnCount, rawValue.Length));
}
rawValues.Add(rawValue);
}
m_RawValues = rawValues.ToArray();
if (nameRow < 0)
{
throw new GameFrameworkException(Utility.Text.Format("Name row '{0}' is invalid.", nameRow));
}
if (typeRow < 0)
{
throw new GameFrameworkException(Utility.Text.Format("Type row '{0}' is invalid.", typeRow));
}
if (contentStartRow < 0)
{
throw new GameFrameworkException(Utility.Text.Format("Content start row '{0}' is invalid.", contentStartRow));
}
if (idColumn < 0)
{
throw new GameFrameworkException(Utility.Text.Format("Id column '{0}' is invalid.", idColumn));
}
if (nameRow >= rawRowCount)
{
throw new GameFrameworkException(Utility.Text.Format("Name row '{0}' >= raw row count '{1}' is not allow.", nameRow, rawRowCount));
}
if (typeRow >= rawRowCount)
{
throw new GameFrameworkException(Utility.Text.Format("Type row '{0}' >= raw row count '{1}' is not allow.", typeRow, rawRowCount));
}
if (defaultValueRow.HasValue && defaultValueRow.Value >= rawRowCount)
{
throw new GameFrameworkException(Utility.Text.Format("Default value row '{0}' >= raw row count '{1}' is not allow.", defaultValueRow.Value, rawRowCount));
}
if (commentRow.HasValue && commentRow.Value >= rawRowCount)
{
throw new GameFrameworkException(Utility.Text.Format("Comment row '{0}' >= raw row count '{1}' is not allow.", commentRow.Value, rawRowCount));
}
if (contentStartRow > rawRowCount)
{
throw new GameFrameworkException(Utility.Text.Format("Content start row '{0}' > raw row count '{1}' is not allow.", contentStartRow, rawRowCount));
}
if (idColumn >= rawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Id column '{0}' >= raw column count '{1}' is not allow.", idColumn, rawColumnCount));
}
m_NameRow = m_RawValues[nameRow];
m_TypeRow = m_RawValues[typeRow];
m_DefaultValueRow = defaultValueRow.HasValue ? m_RawValues[defaultValueRow.Value] : null;
m_CommentRow = commentRow.HasValue ? m_RawValues[commentRow.Value] : null;
m_ContentStartRow = contentStartRow;
m_IdColumn = idColumn;
m_DataProcessor = new DataProcessor[rawColumnCount];
for (int i = 0; i < rawColumnCount; i++)
{
if (i == IdColumn)
{
m_DataProcessor[i] = DataProcessorUtility.GetDataProcessor("id");
}
else
{
m_DataProcessor[i] = DataProcessorUtility.GetDataProcessor(m_TypeRow[i]);
}
}
Dictionary<string, int> strings = new Dictionary<string, int>(StringComparer.Ordinal);
for (int i = contentStartRow; i < rawRowCount; i++)
{
if (IsCommentRow(i))
{
continue;
}
for (int j = 0; j < rawColumnCount; j++)
{
if (m_DataProcessor[j].LanguageKeyword != "string")
{
continue;
}
string str = m_RawValues[i][j];
if (strings.ContainsKey(str))
{
strings[str]++;
}
else
{
strings[str] = 1;
}
}
}
m_Strings = strings.OrderBy(value => value.Key).OrderByDescending(value => value.Value).Select(value => value.Key).ToArray();
m_CodeTemplate = null;
m_CodeGenerator = null;
}
public int RawRowCount
{
get
{
return m_RawValues.Length;
}
}
public int RawColumnCount
{
get
{
return m_RawValues.Length > 0 ? m_RawValues[0].Length : 0;
}
}
public int StringCount
{
get
{
return m_Strings.Length;
}
}
public int ContentStartRow
{
get
{
return m_ContentStartRow;
}
}
public int IdColumn
{
get
{
return m_IdColumn;
}
}
public bool IsIdColumn(int rawColumn)
{
if (rawColumn < 0 || rawColumn >= RawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw column '{0}' is out of range.", rawColumn));
}
return m_DataProcessor[rawColumn].IsId;
}
public bool IsCommentRow(int rawRow)
{
if (rawRow < 0 || rawRow >= RawRowCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw row '{0}' is out of range.", rawRow));
}
return GetValue(rawRow, 0).StartsWith(CommentLineSeparator, StringComparison.Ordinal);
}
public bool IsCommentColumn(int rawColumn)
{
if (rawColumn < 0 || rawColumn >= RawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw column '{0}' is out of range.", rawColumn));
}
return string.IsNullOrEmpty(GetName(rawColumn)) || m_DataProcessor[rawColumn].IsComment;
}
public string GetName(int rawColumn)
{
if (rawColumn < 0 || rawColumn >= RawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw column '{0}' is out of range.", rawColumn));
}
if (IsIdColumn(rawColumn))
{
return "Id";
}
return m_NameRow[rawColumn];
}
public bool IsSystem(int rawColumn)
{
if (rawColumn < 0 || rawColumn >= RawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw column '{0}' is out of range.", rawColumn));
}
return m_DataProcessor[rawColumn].IsSystem;
}
public System.Type GetType(int rawColumn)
{
if (rawColumn < 0 || rawColumn >= RawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw column '{0}' is out of range.", rawColumn));
}
return m_DataProcessor[rawColumn].Type;
}
public string GetLanguageKeyword(int rawColumn)
{
if (rawColumn < 0 || rawColumn >= RawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw column '{0}' is out of range.", rawColumn));
}
return m_DataProcessor[rawColumn].LanguageKeyword;
}
public string GetDefaultValue(int rawColumn)
{
if (rawColumn < 0 || rawColumn >= RawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw column '{0}' is out of range.", rawColumn));
}
return m_DefaultValueRow != null ? m_DefaultValueRow[rawColumn] : null;
}
public string GetComment(int rawColumn)
{
if (rawColumn < 0 || rawColumn >= RawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw column '{0}' is out of range.", rawColumn));
}
return m_CommentRow != null ? m_CommentRow[rawColumn] : null;
}
public string GetValue(int rawRow, int rawColumn)
{
if (rawRow < 0 || rawRow >= RawRowCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw row '{0}' is out of range.", rawRow));
}
if (rawColumn < 0 || rawColumn >= RawColumnCount)
{
throw new GameFrameworkException(Utility.Text.Format("Raw column '{0}' is out of range.", rawColumn));
}
return m_RawValues[rawRow][rawColumn];
}
public string GetString(int index)
{
if (index < 0 || index >= StringCount)
{
throw new GameFrameworkException(Utility.Text.Format("String index '{0}' is out of range.", index));
}
return m_Strings[index];
}
public int GetStringIndex(string str)
{
for (int i = 0; i < StringCount; i++)
{
if (m_Strings[i] == str)
{
return i;
}
}
return -1;
}
public bool GenerateDataFile(string outputFileName)
{
if (string.IsNullOrEmpty(outputFileName))
{
throw new GameFrameworkException("Output file name is invalid.");
}
try
{
using (FileStream fileStream = new FileStream(outputFileName, FileMode.Create, FileAccess.Write))
{
using (BinaryWriter binaryWriter = new BinaryWriter(fileStream, Encoding.UTF8))
{
for (int rawRow = ContentStartRow; rawRow < RawRowCount; rawRow++)
{
if (IsCommentRow(rawRow))
{
continue;
}
byte[] bytes = GetRowBytes(outputFileName, rawRow);
binaryWriter.Write7BitEncodedInt32(bytes.Length);
binaryWriter.Write(bytes);
}
}
}
Debug.Log(Utility.Text.Format("Parse data table '{0}' success.", outputFileName));
return true;
}
catch (Exception exception)
{
Debug.LogError(Utility.Text.Format("Parse data table '{0}' failure, exception is '{1}'.", outputFileName, exception));
return false;
}
}
public bool SetCodeTemplate(string codeTemplateFileName, Encoding encoding)
{
try
{
m_CodeTemplate = File.ReadAllText(codeTemplateFileName, encoding);
Debug.Log(Utility.Text.Format("Set code template '{0}' success.", codeTemplateFileName));
return true;
}
catch (Exception exception)
{
Debug.LogError(Utility.Text.Format("Set code template '{0}' failure, exception is '{1}'.", codeTemplateFileName, exception));
return false;
}
}
public void SetCodeGenerator(DataTableCodeGenerator codeGenerator)
{
m_CodeGenerator = codeGenerator;
}
public bool GenerateCodeFile(string outputFileName, Encoding encoding, object userData = null)
{
if (string.IsNullOrEmpty(m_CodeTemplate))
{
throw new GameFrameworkException("You must set code template first.");
}
if (string.IsNullOrEmpty(outputFileName))
{
throw new GameFrameworkException("Output file name is invalid.");
}
try
{
StringBuilder stringBuilder = new StringBuilder(m_CodeTemplate);
if (m_CodeGenerator != null)
{
m_CodeGenerator(this, stringBuilder, userData);
}
using (FileStream fileStream = new FileStream(outputFileName, FileMode.Create, FileAccess.Write))
{
using (StreamWriter stream = new StreamWriter(fileStream, encoding))
{
stream.Write(stringBuilder.ToString());
}
}
Debug.Log(Utility.Text.Format("Generate code file '{0}' success.", outputFileName));
return true;
}
catch (Exception exception)
{
Debug.LogError(Utility.Text.Format("Generate code file '{0}' failure, exception is '{1}'.", outputFileName, exception));
return false;
}
}
private byte[] GetRowBytes(string outputFileName, int rawRow)
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (BinaryWriter binaryWriter = new BinaryWriter(memoryStream, Encoding.UTF8))
{
for (int rawColumn = 0; rawColumn < RawColumnCount; rawColumn++)
{
if (IsCommentColumn(rawColumn))
{
continue;
}
try
{
m_DataProcessor[rawColumn].WriteToStream(this, binaryWriter, GetValue(rawRow, rawColumn));
}
catch
{
if (m_DataProcessor[rawColumn].IsId || string.IsNullOrEmpty(GetDefaultValue(rawColumn)))
{
Debug.LogError(Utility.Text.Format("Parse raw value failure. OutputFileName='{0}' RawRow='{1}' RowColumn='{2}' Name='{3}' Type='{4}' RawValue='{5}'", outputFileName, rawRow, rawColumn, GetName(rawColumn), GetLanguageKeyword(rawColumn), GetValue(rawRow, rawColumn)));
return null;
}
else
{
Debug.LogWarning(Utility.Text.Format("Parse raw value failure, will try default value. OutputFileName='{0}' RawRow='{1}' RowColumn='{2}' Name='{3}' Type='{4}' RawValue='{5}'", outputFileName, rawRow, rawColumn, GetName(rawColumn), GetLanguageKeyword(rawColumn), GetValue(rawRow, rawColumn)));
try
{
m_DataProcessor[rawColumn].WriteToStream(this, binaryWriter, GetDefaultValue(rawColumn));
}
catch
{
Debug.LogError(Utility.Text.Format("Parse default value failure. OutputFileName='{0}' RawRow='{1}' RowColumn='{2}' Name='{3}' Type='{4}' RawValue='{5}'", outputFileName, rawRow, rawColumn, GetName(rawColumn), GetLanguageKeyword(rawColumn), GetComment(rawColumn)));
return null;
}
}
}
}
return memoryStream.ToArray();
}
}
}
}
}
@@ -1,11 +0,0 @@
fileFormatVersion: 2
guid: 81b27209918096743b988ea62b39d109
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,278 @@
#if UNITY_EDITOR
using System;
using System.Linq;
using CustomComponent;
using DataTable;
using Definition.DataStruct;
using Entity;
using Game.Utility;
using UnityEditor;
using UnityEngine;
namespace StarForce.Editor
{
public class PlayerBuffConsoleWindow : EditorWindow
{
private const string WindowTitle = "Player Buff Console";
private string _searchText = string.Empty;
private int _selectedIndex;
private int _addCount = 1;
private Vector2 _scroll;
private DRProp[] _allProps = Array.Empty<DRProp>();
private DRProp[] _filteredProps = Array.Empty<DRProp>();
private string[] _displayNames = Array.Empty<string>();
private float _spawnRateScaleInput = 1f;
private float _extendDurationSeconds = 30f;
[MenuItem("StarForce/Debug/Player Buff Console")]
private static void Open()
{
GetWindow<PlayerBuffConsoleWindow>(WindowTitle);
}
private void OnEnable()
{
RefreshPropList();
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
}
private void OnDisable()
{
EditorApplication.playModeStateChanged -= OnPlayModeStateChanged;
}
private void OnGUI()
{
EditorGUILayout.LabelField("Player Buff Console (Editor Only)", EditorStyles.boldLabel);
EditorGUILayout.Space(4f);
using (new EditorGUI.DisabledScope(!EditorApplication.isPlaying))
{
DrawBuffSection();
EditorGUILayout.Space(8f);
EditorGUILayout.LabelField(string.Empty, GUI.skin.horizontalSlider);
EditorGUILayout.Space(8f);
DrawBattleControlSection();
}
if (!EditorApplication.isPlaying)
{
EditorGUILayout.HelpBox("Enter Play mode to use debug controls.", MessageType.Info);
}
}
private void DrawBuffSection()
{
EditorGUILayout.LabelField("Buff Debug", EditorStyles.boldLabel);
DrawToolbar();
DrawBuffSelector();
DrawSelectedBuffPreview();
DrawBuffActions();
}
private void DrawBattleControlSection()
{
EditorGUILayout.LabelField("Battle Debug", EditorStyles.boldLabel);
EnemyManagerComponent enemyManager = GameEntry.EnemyManager;
Player player = FindPlayer();
if (enemyManager == null)
{
EditorGUILayout.HelpBox("EnemyManager is unavailable.", MessageType.Warning);
return;
}
EditorGUILayout.LabelField("Current Spawn Rate Scale", enemyManager.SpawnRateScale.ToString("F2"));
EditorGUILayout.LabelField("Battle Time",
$"{enemyManager.ElapsedBattleTime:F1}s / {enemyManager.BattleDuration:F1}s");
_spawnRateScaleInput = Mathf.Clamp(EditorGUILayout.FloatField("Spawn Rate Scale", _spawnRateScaleInput), 0.1f,
50f);
_extendDurationSeconds = Mathf.Clamp(EditorGUILayout.FloatField("Add Duration (Seconds)", _extendDurationSeconds),
1f, 3600f);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Apply Spawn Rate"))
{
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
ShowNotification(new GUIContent($"Spawn rate scale = {enemyManager.SpawnRateScale:F2}"));
}
if (GUILayout.Button("x0.5"))
{
_spawnRateScaleInput = Mathf.Max(0.1f, enemyManager.SpawnRateScale * 0.5f);
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
if (GUILayout.Button("x2"))
{
_spawnRateScaleInput = enemyManager.SpawnRateScale * 2f;
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
EditorGUILayout.EndHorizontal();
if (GUILayout.Button("Add Battle Duration"))
{
enemyManager.AddBattleDuration(_extendDurationSeconds);
ShowNotification(new GUIContent($"+{_extendDurationSeconds:F0}s Battle Duration"));
}
EditorGUILayout.Space(6f);
EditorGUILayout.LabelField("Player Weapon", player == null ? "Player not found" : (player.WeaponEnabled ? "Enabled" : "Disabled"));
using (new EditorGUI.DisabledScope(player == null))
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Disable Weapons"))
{
player.SetWeaponEnabled(false);
ShowNotification(new GUIContent("Player weapons disabled"));
}
if (GUILayout.Button("Enable Weapons"))
{
player.SetWeaponEnabled(true);
ShowNotification(new GUIContent("Player weapons enabled"));
}
EditorGUILayout.EndHorizontal();
}
}
private void DrawToolbar()
{
EditorGUILayout.BeginHorizontal();
_searchText = EditorGUILayout.TextField("Search", _searchText);
if (GUILayout.Button("Refresh", GUILayout.Width(80f)))
{
RefreshPropList();
}
EditorGUILayout.EndHorizontal();
}
private void DrawBuffSelector()
{
ApplyFilter(_searchText);
if (_displayNames.Length == 0)
{
EditorGUILayout.HelpBox("No Buff data found. Ensure data tables are loaded.", MessageType.Warning);
return;
}
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _displayNames.Length - 1);
_selectedIndex = EditorGUILayout.Popup("Buff", _selectedIndex, _displayNames);
}
private void DrawSelectedBuffPreview()
{
DRProp selectedProp = GetSelectedProp();
if (selectedProp == null) return;
_scroll = EditorGUILayout.BeginScrollView(_scroll, GUILayout.Height(120f));
EditorGUILayout.LabelField("Title", selectedProp.Title);
EditorGUILayout.LabelField("Rarity", selectedProp.Rarity.ToString());
EditorGUILayout.LabelField("Description");
EditorGUILayout.HelpBox(ItemDescUtility.CreatePropDescription(selectedProp.Modifiers), MessageType.None);
EditorGUILayout.EndScrollView();
}
private void DrawBuffActions()
{
DRProp selectedProp = GetSelectedProp();
if (selectedProp == null) return;
_addCount = Mathf.Clamp(EditorGUILayout.IntField("Add Count", _addCount), 1, 99);
if (!GUILayout.Button("Add Buff To Player", GUILayout.Height(28f))) return;
Player player = FindPlayer();
if (player == null)
{
ShowNotification(new GUIContent("Player not found"));
return;
}
for (int i = 0; i < _addCount; i++)
{
player.AddProp(new PropItem(selectedProp.Modifiers, selectedProp.Rarity, selectedProp.Title,
selectedProp.IconAssetName));
}
ShowNotification(new GUIContent($"Added Buff: {selectedProp.Title} x{_addCount}"));
}
private void RefreshPropList()
{
if (!EditorApplication.isPlaying || GameEntry.DataTable == null)
{
_allProps = Array.Empty<DRProp>();
_filteredProps = Array.Empty<DRProp>();
_displayNames = Array.Empty<string>();
return;
}
var table = GameEntry.DataTable.GetDataTable<DRProp>();
_allProps = table != null ? table.ToArray() : Array.Empty<DRProp>();
_selectedIndex = 0;
ApplyFilter(_searchText);
}
private void ApplyFilter(string searchText)
{
if (_allProps == null || _allProps.Length == 0)
{
_filteredProps = Array.Empty<DRProp>();
_displayNames = Array.Empty<string>();
return;
}
if (string.IsNullOrWhiteSpace(searchText))
{
_filteredProps = _allProps;
}
else
{
string keyword = searchText.Trim();
_filteredProps = _allProps.Where(p =>
p != null &&
(p.Title?.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0 ||
p.Id.ToString().Contains(keyword))).ToArray();
}
_displayNames = _filteredProps.Select(p => $"[{p.Id}] {p.Title} ({p.Rarity})").ToArray();
if (_displayNames.Length == 0)
{
_selectedIndex = 0;
return;
}
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _displayNames.Length - 1);
}
private DRProp GetSelectedProp()
{
if (_filteredProps == null || _filteredProps.Length == 0) return null;
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _filteredProps.Length - 1);
return _filteredProps[_selectedIndex];
}
private static Player FindPlayer()
{
return UnityEngine.Object.FindObjectOfType<Player>();
}
private void OnPlayModeStateChanged(PlayModeStateChange state)
{
if (state == PlayModeStateChange.EnteredPlayMode || state == PlayModeStateChange.EnteredEditMode)
{
RefreshPropList();
Repaint();
}
}
}
}
#endif
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e43be978219545f294fbc211e32e8196
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -16,11 +16,12 @@ namespace Entity.EntityData
[SerializeField] private float _dropPercent = 0;
public EnemyData(int entityId, int typeId) : base(
public EnemyData(int entityId, int typeId, int level) : base(
entityId, typeId, CampType.Enemy)
{
DREnemy enemyRow = GameEntry.DataTable.GetDataTableRow<DREnemy>(typeId);
MaxHealthBase = enemyRow.MaxHealth;
int effectiveLevel = Mathf.Max(1, level);
MaxHealthBase = enemyRow.MaxHealth + enemyRow.HpAddPerLevel * (effectiveLevel - 1);
SpeedBase = enemyRow.Speed;
DropCoin = enemyRow.DropCoin;
DropExp = enemyRow.DropExp;
@@ -53,4 +54,4 @@ namespace Entity.EntityData
set => _dropPercent = value;
}
}
}
}
@@ -7,10 +7,12 @@ namespace Entity
public class CoinEntity : EntityBase
{
private CoinData _coinData;
private bool _isCollected;
protected override void OnShow(object userData)
{
base.OnShow(userData);
_isCollected = false;
if (userData is CoinData coinData)
{
@@ -24,14 +26,25 @@ namespace Entity
this.CachedTransform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
}
public bool TryCollect(Player player, float collectDistance = 0f)
{
if (_isCollected || player == null || !player.Available || _coinData == null) return false;
if (collectDistance > 0f)
{
float distance = Vector3.Distance(player.CachedTransform.position, CachedTransform.position);
if (distance > collectDistance) return false;
}
_isCollected = true;
player.Coin += _coinData.Value;
GameEntry.Entity.HideEntity(this);
return true;
}
private void OnTriggerEnter(Collider other)
{
var player = other.GetComponent<Player>();
if (player != null && player.Available)
{
player.Coin += _coinData.Value;
GameEntry.Entity.HideEntity(this);
}
TryCollect(other.GetComponent<Player>());
}
}
}
}
@@ -7,10 +7,12 @@ namespace Entity
public class ExpEntity:EntityBase
{
private ExpData _expData;
private bool _isCollected;
protected override void OnShow(object userData)
{
base.OnShow(userData);
_isCollected = false;
if (userData is ExpData expData)
{
@@ -23,14 +25,25 @@ namespace Entity
this.CachedTransform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
}
public bool TryCollect(Player player, float collectDistance = 0f)
{
if (_isCollected || player == null || !player.Available || _expData == null) return false;
if (collectDistance > 0f)
{
float distance = Vector3.Distance(player.CachedTransform.position, CachedTransform.position);
if (distance > collectDistance) return false;
}
_isCollected = true;
player.Exp += _expData.Value;
GameEntry.Entity.HideEntity(this);
return true;
}
private void OnTriggerEnter(Collider other)
{
var player = other.GetComponent<Player>();
if (player != null && player.Available)
{
player.Exp += _expData.Value;
GameEntry.Entity.HideEntity(this);
}
TryCollect(other.GetComponent<Player>());
}
}
}
}
@@ -15,6 +15,7 @@ namespace Entity
private InputComponent _inputComponent;
private MovementComponent _movementComponent;
private AbsorbComponent _absorbComponent;
private StatComponent _statComponent;
private BackpackComponent _backpackComponent;
private PlayerData _playerData;
@@ -44,6 +45,7 @@ namespace Entity
/// 玩家是否启用。
/// </summary>
private bool _enable;
private bool _weaponEnabled = true;
public int Coin
{
@@ -95,11 +97,19 @@ namespace Entity
if (value == _enable) return;
_enable = value;
_movementComponent.SetMove(value);
_backpackComponent.SetWeaponState(value);
_backpackComponent.SetWeaponState(value && _weaponEnabled);
_inputComponent.SetListening(value);
}
}
public bool WeaponEnabled => _weaponEnabled;
public void SetWeaponEnabled(bool enabled)
{
_weaponEnabled = enabled;
_backpackComponent?.SetWeaponState(_enable && _weaponEnabled);
}
public void InitRole(DRRole role)
{
// MovementComponent
@@ -146,9 +156,15 @@ namespace Entity
_inputComponent = GetComponent<InputComponent>();
_movementComponent = GetComponent<MovementComponent>();
_absorbComponent = GetComponent<AbsorbComponent>();
_statComponent = GetComponent<StatComponent>();
_healthComponent = GetComponent<HealthComponent>();
_backpackComponent = GetComponent<BackpackComponent>();
if (_absorbComponent == null)
{
_absorbComponent = gameObject.AddComponent<AbsorbComponent>();
}
}
protected override void OnShow(object userData)
@@ -166,6 +182,8 @@ namespace Entity
_inputComponent.OnInit();
_inputComponent.SetListening(true);
_absorbComponent.OnInit(this, _statComponent);
_weaponEnabled = true;
_currentLevel = 0;
}
@@ -178,6 +196,7 @@ namespace Entity
_movementComponent.SetDirection(_inputComponent.Direction);
_movementComponent.OnUpdate(elapseSeconds, realElapseSeconds);
_absorbComponent.OnUpdate(elapseSeconds, realElapseSeconds);
}
protected override void OnHide(bool isShutdown, object userData)
@@ -187,6 +206,7 @@ namespace Entity
_healthComponent.OnReset();
_statComponent.OnReset();
_backpackComponent.OnReset();
_absorbComponent.OnReset();
base.OnHide(isShutdown, userData);
}
@@ -206,4 +226,4 @@ namespace Entity
#endregion
}
}
}
@@ -24,15 +24,15 @@ namespace Entity
public abstract class WeaponBase : EntityBase
{
protected const string AttachPoint = "Weapon Point";
protected bool _isAttacking = false;
protected bool _isEnabled = false;
[SerializeField] protected bool _isEnabled = false;
public WeaponData WeaponData;
public bool IsAttacking => _isAttacking;
protected WeaponStateBase _currentState;
#region FSM
@@ -37,7 +37,8 @@ namespace Procedure
"Prop",
"Role",
"Level",
"LevelUpReward"
"LevelUpReward",
"LevelRarity"
};
private Dictionary<string, bool> _loadedFlag = new Dictionary<string, bool>();
@@ -50,7 +50,6 @@ namespace Procedure
if (_levelOver)
{
procedureOwner.SetData<VarByte>("CurrentLevel", (byte)(_currentLevel + 1));
_procedureGame.BattleToShopOrLevelUp();
}
}
@@ -53,6 +53,7 @@ namespace Procedure
public void BattleToShopOrLevelUp()
{
CurrentLevel++;
if (_currentGameState == GameStateType.Shop || _currentGameState == GameStateType.LevelUp) return;
_gameStates[_currentGameState].OnLeave(_procedureOwner);
@@ -45,7 +45,7 @@ public class SpriteCacheComponent : GameFrameworkComponent
new Rect(0, 0, texture.width, texture.height),
_defaultPivot,
_pixelsPerUnit);
_spriteCache.Add(assetName, newSprite);
_spriteCache.TryAdd(assetName, newSprite);
callback?.Invoke(newSprite);
}
},
@@ -7,6 +7,8 @@ using Entity;
using Procedure;
using UnityEngine;
using UnityGameFramework.Runtime;
using Game.Utility;
using GameFramework.DataTable;
namespace UI
{
@@ -15,6 +17,9 @@ namespace UI
private const int BaseRefreshPrice = 2;
private readonly GameStateLevelUp _gameStateLevelUp;
private readonly DRLevelUpReward[] _allRewards;
private readonly IDataTable<DRLevelRarity> _levelRarityTable;
private readonly Dictionary<ItemRarity, List<DRLevelUpReward>> _rewardsByRarity = new();
private readonly List<DRLevelUpReward> _validRewards = new();
private int _refreshCount;
private LevelUpFormRawData _currentModel;
@@ -26,6 +31,9 @@ namespace UI
_player = player;
_gameStateLevelUp = gameStateLevelUp;
_allRewards = GameEntry.DataTable.GetDataTable<DRLevelUpReward>().ToArray();
_levelRarityTable = GameEntry.DataTable.GetDataTable<DRLevelRarity>();
BuildRewardRarityPools();
}
public LevelUpFormRawData CreateInitialModel(int count = 4)
@@ -99,10 +107,18 @@ namespace UI
int finalCount = count > 0 ? System.Math.Min(count, _allRewards.Length) : _allRewards.Length;
List<DRLevelUpReward> selections = new List<DRLevelUpReward>(finalCount);
int currentLevel = _player != null ? _player.CurrentLevel : 1;
for (int i = 0; i < finalCount; i++)
{
int index = Random.Range(0, _allRewards.Length);
selections.Add(_allRewards[index]);
ItemRarity rarity = RarityUtility.SelectRarityForLevel(_levelRarityTable, currentLevel);
DRLevelUpReward reward = PickRewardByRarity(rarity);
if (reward == null)
{
Log.Warning("LevelUpFormUseCase::BuildModel(): No available reward for selection.");
break;
}
selections.Add(reward);
}
return new LevelUpFormRawData
@@ -131,7 +147,49 @@ namespace UI
return;
}
_player.AddProp(new PropItem(reward.Modifiers, ItemRarity.White, reward.Title, reward.IconAssetName));
_player.AddProp(new PropItem(reward.Modifiers, reward.Rarity, reward.Title, reward.IconAssetName));
}
private void BuildRewardRarityPools()
{
_rewardsByRarity.Clear();
_validRewards.Clear();
if (_allRewards == null) return;
foreach (DRLevelUpReward reward in _allRewards)
{
if (reward == null)
{
continue;
}
ItemRarity rarity = reward.Rarity;
_validRewards.Add(reward);
if (!_rewardsByRarity.TryGetValue(rarity, out List<DRLevelUpReward> list))
{
list = new List<DRLevelUpReward>();
_rewardsByRarity.Add(rarity, list);
}
list.Add(reward);
}
}
private DRLevelUpReward PickRewardByRarity(ItemRarity rarity)
{
if (_rewardsByRarity.TryGetValue(rarity, out List<DRLevelUpReward> list) && list.Count > 0)
{
return list[Random.Range(0, list.Count)];
}
if (_validRewards.Count > 0)
{
return _validRewards[Random.Range(0, _validRewards.Count)];
}
return null;
}
}
}
}
@@ -33,6 +33,10 @@ namespace UI
private readonly DRGoods[] _allGoods;
private readonly IDataTable<DRProp> _propDataTable;
private readonly IDataTable<DRWeapon> _weaponDataTable;
private readonly IDataTable<DRLevelRarity> _levelRarityTable;
private readonly List<DRGoods> _validGoods = new();
private readonly Dictionary<ItemRarity, List<DRGoods>> _goodsByRarity = new();
private readonly List<ShopGoodsSelection> _selections = new();
private int _refreshTime;
@@ -53,6 +57,9 @@ namespace UI
_allGoods = GameEntry.DataTable.GetDataTable<DRGoods>().ToArray();
_propDataTable = GameEntry.DataTable.GetDataTable<DRProp>();
_weaponDataTable = GameEntry.DataTable.GetDataTable<DRWeapon>();
_levelRarityTable = GameEntry.DataTable.GetDataTable<DRLevelRarity>();
BuildGoodsRarityPools();
}
public ShopFormRawData CreateInitialModel()
@@ -148,10 +155,18 @@ namespace UI
List<GoodsItemContext> goodsItems = new List<GoodsItemContext>(finalCount);
_selections.Clear();
int currentLevel = _procedureGame != null ? _procedureGame.CurrentLevel : 1;
for (int i = 0; i < finalCount; i++)
{
int index = Random.Range(0, _allGoods.Length);
DRGoods drGoods = _allGoods[index];
ItemRarity rarity = RarityUtility.SelectRarityForLevel(_levelRarityTable, currentLevel);
DRGoods drGoods = PickGoodsByRarity(rarity);
if (drGoods == null)
{
Log.Warning("ShopFormUseCase::BuildRandomGoodsItems: No available goods for selection.");
break;
}
GoodsItemContext goodsItem = new GoodsItemContext();
int price;
@@ -208,6 +223,87 @@ namespace UI
return goodsItems;
}
private void BuildGoodsRarityPools()
{
_goodsByRarity.Clear();
_validGoods.Clear();
if (_allGoods == null) return;
foreach (DRGoods goods in _allGoods)
{
if (goods == null) continue;
if (!TryGetGoodsRarity(goods, out ItemRarity rarity))
{
continue;
}
_validGoods.Add(goods);
if (!_goodsByRarity.TryGetValue(rarity, out List<DRGoods> list))
{
list = new List<DRGoods>();
_goodsByRarity.Add(rarity, list);
}
list.Add(goods);
}
}
private DRGoods PickGoodsByRarity(ItemRarity rarity)
{
if (_goodsByRarity.TryGetValue(rarity, out List<DRGoods> list) && list.Count > 0)
{
return list[Random.Range(0, list.Count)];
}
if (_validGoods.Count > 0)
{
return _validGoods[Random.Range(0, _validGoods.Count)];
}
return null;
}
private bool TryGetGoodsRarity(DRGoods goods, out ItemRarity rarity)
{
rarity = ItemRarity.None;
if (goods == null)
{
return false;
}
if (goods.GoodsType == GoodsType.Prop)
{
DRProp drProp = _propDataTable != null ? _propDataTable.GetDataRow(goods.GoodsTypeId) : null;
if (drProp == null)
{
Log.Warning($"ShopFormUseCase::TryGetGoodsRarity: Missing DRProp, id = {goods.GoodsTypeId}");
return false;
}
rarity = drProp.Rarity;
return true;
}
if (goods.GoodsType == GoodsType.Weapon)
{
DRWeapon drWeapon = _weaponDataTable != null ? _weaponDataTable.GetDataRow(goods.GoodsTypeId) : null;
if (drWeapon == null)
{
Log.Warning($"ShopFormUseCase::TryGetGoodsRarity: Missing DRWeapon, id = {goods.GoodsTypeId}");
return false;
}
rarity = drWeapon.Rarity;
return true;
}
Log.Warning($"ShopFormUseCase::TryGetGoodsRarity: Unsupported goods type = {goods.GoodsType}");
return false;
}
private static int CalculateRandomizedPrice(int basePrice, float priceRandomPercent)
{
float normalizedPercent = priceRandomPercent > 1f ? priceRandomPercent / 100f : priceRandomPercent;
@@ -0,0 +1,89 @@
using DataTable;
using Definition.Enum;
using GameFramework.DataTable;
using UnityEngine;
namespace Game.Utility
{
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: