Files
BlockSpace-v1.5.0b/Assets/Scripts/Assembly-CSharp/BSValue.cs
T
2026-06-01 17:19:55 +02:00

309 lines
5.7 KiB
C#

using System;
using BlockSpace.Voxels;
using UnityEngine;
[Serializable]
public struct BSValue
{
private const double WholeNumberEpsilon = 0.0001;
public BSValueKind Kind;
public double Number;
public string Text;
public bool Bool;
public int PlayerId;
public int GroupId;
public bool IsInitialized
{
get
{
if (Kind == BSValueKind.None && !(Math.Abs(Number) > 0.0001) && string.IsNullOrEmpty(Text) && PlayerId == 0)
{
return GroupId != 0;
}
return true;
}
}
public static BSValue None => new BSValue
{
Kind = BSValueKind.None
};
public static BSValue FromBool(bool value)
{
return new BSValue
{
Kind = BSValueKind.Bool,
Bool = value
};
}
public static BSValue FromNumber(double value)
{
return new BSValue
{
Kind = BSValueKind.Number,
Number = NormalizeNumber(value)
};
}
public static BSValue FromText(string value)
{
if (string.IsNullOrWhiteSpace(value) || string.Equals(value, "None", StringComparison.OrdinalIgnoreCase) || string.Equals(value, "Null", StringComparison.OrdinalIgnoreCase))
{
return None;
}
if (string.Equals(value, "True", StringComparison.OrdinalIgnoreCase) || string.Equals(value, "False", StringComparison.OrdinalIgnoreCase))
{
return FromBool(string.Equals(value, "True", StringComparison.OrdinalIgnoreCase));
}
if (double.TryParse(value, out var result))
{
return FromNumber(result);
}
return new BSValue
{
Kind = BSValueKind.Text,
Text = value
};
}
public static BSValue FromPlayer(int playerId)
{
return new BSValue
{
Kind = BSValueKind.Player,
PlayerId = playerId
};
}
public static BSValue FromGroup(int groupId)
{
return new BSValue
{
Kind = BSValueKind.Group,
GroupId = groupId
};
}
public BSValue Normalize()
{
switch (Kind)
{
case BSValueKind.Number:
Number = NormalizeNumber(Number);
break;
case BSValueKind.Text:
if (Text == null)
{
Text = string.Empty;
}
break;
}
return this;
}
public bool IsWholeNumber()
{
return Math.Abs(Number - Math.Round(Number)) <= 0.0001;
}
public double AsNumber()
{
switch (Kind)
{
case BSValueKind.Number:
return NormalizeNumber(Number);
case BSValueKind.Bool:
if (!Bool)
{
return 0.0;
}
return 1.0;
case BSValueKind.Text:
{
if (double.TryParse(Text, out var result))
{
return NormalizeNumber(result);
}
return EncodeTextAsNumber(Text);
}
case BSValueKind.Player:
return PlayerId;
case BSValueKind.Group:
return GroupId;
default:
return 0.0;
}
}
public bool AsBool()
{
return Kind switch
{
BSValueKind.Bool => Bool,
BSValueKind.None => false,
BSValueKind.Number => Math.Abs(AsNumber()) > 0.0001,
BSValueKind.Text => !string.IsNullOrEmpty(AsText()),
BSValueKind.Player => AsPlayerId() > 0,
BSValueKind.Group => AsGroupId() > 0,
_ => false,
};
}
public string AsText()
{
switch (Kind)
{
case BSValueKind.Number:
if (!IsWholeNumber())
{
return NormalizeNumber(Number).ToString("0.#######");
}
return Math.Round(Number).ToString();
case BSValueKind.Bool:
if (!Bool)
{
return "False";
}
return "True";
case BSValueKind.Text:
return Text ?? string.Empty;
case BSValueKind.Player:
return PlayerId.ToString();
case BSValueKind.Group:
return GroupId.ToString();
default:
return string.Empty;
}
}
public int AsPlayerId()
{
switch (Kind)
{
case BSValueKind.Player:
return PlayerId;
case BSValueKind.Number:
return Mathf.RoundToInt((float)NormalizeNumber(Number));
case BSValueKind.Group:
return GroupId;
case BSValueKind.Text:
{
if (int.TryParse(Text, out var result))
{
return result;
}
return Mathf.RoundToInt((float)EncodeTextAsNumber(Text));
}
default:
return 0;
}
}
public int AsGroupId()
{
switch (Kind)
{
case BSValueKind.Group:
return GroupId;
case BSValueKind.Number:
return Mathf.RoundToInt((float)NormalizeNumber(Number));
case BSValueKind.Player:
return PlayerId;
case BSValueKind.Text:
{
if (int.TryParse(Text, out var result))
{
return result;
}
return Mathf.RoundToInt((float)EncodeTextAsNumber(Text));
}
default:
return 0;
}
}
public bool TryResolveGroup(out VoxelGroup group)
{
return TryResolveGroup(VoxelGroupManager.Instance, out group);
}
public bool TryResolveGroup(VoxelGroupManager manager, out VoxelGroup group)
{
group = null;
if (manager == null)
{
return false;
}
int num = AsGroupId();
if (num > 0 && num <= 65535 && manager.TryGetGroup((ushort)num, out group))
{
return group != null;
}
return false;
}
public BSValue ConvertTo(BSValueKind targetKind)
{
return targetKind switch
{
BSValueKind.Bool => FromBool(AsBool()),
BSValueKind.Number => FromNumber(AsNumber()),
BSValueKind.Text => new BSValue
{
Kind = BSValueKind.Text,
Text = AsText()
},
BSValueKind.Player => FromPlayer(AsPlayerId()),
BSValueKind.Group => FromGroup(AsGroupId()),
_ => None,
};
}
public override string ToString()
{
return Kind switch
{
BSValueKind.Number => AsText(),
BSValueKind.Text => AsText(),
BSValueKind.Bool => AsText(),
BSValueKind.Player => $"Player({AsPlayerId()})",
BSValueKind.Group => $"Group({AsGroupId()})",
_ => "None",
};
}
private static double NormalizeNumber(double value)
{
double num = Math.Round(value);
if (!(Math.Abs(value - num) <= 0.0001))
{
return value;
}
return num;
}
private static double EncodeTextAsNumber(string value)
{
if (string.IsNullOrEmpty(value))
{
return 0.0;
}
uint num = 2166136261u;
for (int i = 0; i < value.Length; i++)
{
num ^= value[i];
num *= 16777619;
}
return num;
}
}