Conduct code reviews.

进行代码审查。
This commit is contained in:
Cold-Mint 2024-06-05 21:38:45 +08:00
parent 2a836e32e6
commit 39ca716e3d
Signed by: Cold-Mint
GPG Key ID: C5A9BF8A98E0CE99
29 changed files with 422 additions and 337 deletions

View File

@ -13,10 +13,10 @@ collision_layer = 0
collision_mask = 0 collision_mask = 0
script = ExtResource("1_ib3qh") script = ExtResource("1_ib3qh")
metadata/Speed = 500.0 metadata/Speed = 500.0
metadata/Life = 10.0
metadata/Durability = 1.0 metadata/Durability = 1.0
metadata/DamageType = 2 metadata/DamageType = 2
metadata/Knockback = Vector2(2, -3) metadata/Knockback = Vector2(2, -3)
metadata/Life = 5000
[node name="CurseOfTheUndead" type="Sprite2D" parent="."] [node name="CurseOfTheUndead" type="Sprite2D" parent="."]
texture = ExtResource("1_k8el6") texture = ExtResource("1_k8el6")

View File

@ -8,7 +8,11 @@ namespace ColdMint.scripts;
public static class Config public static class Config
{ {
public class BehaviorTreeId /// <summary>
/// <para>ID of the behavior tree</para>
/// <para>行为树的ID</para>
/// </summary>
public static class BehaviorTreeId
{ {
/// <summary> /// <summary>
/// <para>巡逻</para> /// <para>巡逻</para>
@ -21,7 +25,7 @@ public static class Config
/// <para>BehaviorTreeResult</para> /// <para>BehaviorTreeResult</para>
/// <para>行为树的结果</para> /// <para>行为树的结果</para>
/// </summary> /// </summary>
public class BehaviorTreeResult public static class BehaviorTreeResult
{ {
/// <summary> /// <summary>
/// <para>Running</para> /// <para>Running</para>
@ -149,13 +153,18 @@ public static class Config
return OS.HasFeature("editor"); return OS.HasFeature("editor");
} }
public class RoomInjectionProcessorId /// <summary>
/// <para>Room Injector ID</para>
/// <para>房间注入器ID</para>
/// </summary>
public static class RoomInjectionProcessorId
{ {
/// <summary> /// <summary>
/// <para>Chance</para> /// <para>Chance</para>
/// <para>概率的</para> /// <para>概率的</para>
/// </summary> /// </summary>
public const string Chance = "Chance"; public const string Chance = "Chance";
/// <summary> /// <summary>
/// <para>TimeInterval</para> /// <para>TimeInterval</para>
/// <para>时间范围的</para> /// <para>时间范围的</para>
@ -191,11 +200,7 @@ public static class Config
//The host operating system is a web browser //The host operating system is a web browser
//宿主操作系统是网页浏览器 //宿主操作系统是网页浏览器
Web, Web
//Editor
//编辑器
// Editor
} }
/// <summary> /// <summary>
@ -205,11 +210,6 @@ public static class Config
/// <returns></returns> /// <returns></returns>
public static OsEnum GetOs() public static OsEnum GetOs()
{ {
// if (OS.HasFeature("editor"))
// {
// return OsEnum.Editor;
// }
if (OS.HasFeature("windows")) if (OS.HasFeature("windows"))
{ {
return OsEnum.Windows; return OsEnum.Windows;
@ -239,9 +239,15 @@ public static class Config
{ {
return OsEnum.Ios; return OsEnum.Ios;
} }
return OsEnum.Unknown; return OsEnum.Unknown;
} }
/// <summary>
/// <para>Get the game version</para>
/// <para>获取游戏版本</para>
/// </summary>
/// <returns></returns>
public static string GetVersion() public static string GetVersion()
{ {
var stringBuilder = new StringBuilder(); var stringBuilder = new StringBuilder();
@ -347,7 +353,7 @@ public static class Config
/// <para>Physical collision layer number</para> /// <para>Physical collision layer number</para>
/// <para>物理碰撞层 序号</para> /// <para>物理碰撞层 序号</para>
/// </summary> /// </summary>
public class LayerNumber public static class LayerNumber
{ {
public const int RoomArea = 1; public const int RoomArea = 1;
public const int Ground = 2; public const int Ground = 2;
@ -358,23 +364,7 @@ public static class Config
public const int Mob = 7; public const int Mob = 7;
} }
/// <summary> public static class RoomDataTag
/// <para>The event of entering the room</para>
/// <para>进入房间的事件</para>
/// </summary>
public class EnterRoomEventId
{
}
/// <summary>
/// <para>Exit the room event</para>
/// <para>退出房间的事件</para>
/// </summary>
public class ExitRoomEventId
{
}
public class RoomDataTag
{ {
/// <summary> /// <summary>
/// <para>Mark the starting room</para> /// <para>Mark the starting room</para>
@ -387,7 +377,7 @@ public static class Config
/// <para>Specify the type of damage used in the game</para> /// <para>Specify the type of damage used in the game</para>
/// <para>指定游戏内使用的伤害类型</para> /// <para>指定游戏内使用的伤害类型</para>
/// </summary> /// </summary>
public class DamageType public static class DamageType
{ {
/// <summary> /// <summary>
/// <para>physical injury</para> /// <para>physical injury</para>

View File

@ -3,7 +3,11 @@ using ColdMint.scripts.map.events;
namespace ColdMint.scripts; namespace ColdMint.scripts;
public class EventManager /// <summary>
/// <para>EventManager</para>
/// <para>事件管理器</para>
/// </summary>
public static class EventManager
{ {
/// <summary> /// <summary>
/// <para>Event when the AI character is generated</para> /// <para>Event when the AI character is generated</para>

View File

@ -8,12 +8,14 @@ namespace ColdMint.scripts;
/// </summary> /// </summary>
public partial class FpsLabel : Label public partial class FpsLabel : Label
{ {
bool _enable; private bool _enable;
private LabelSettings? _labelSettings; private LabelSettings? _labelSettings;
public override void _Ready() public override void _Ready()
{ {
Text = null; Text = null;
//Enabled only in debug mode.
//仅在调试模式启用。
if (Config.IsDebug()) if (Config.IsDebug())
{ {
_labelSettings = new LabelSettings(); _labelSettings = new LabelSettings();

View File

@ -22,17 +22,34 @@ public static class GameSceneNodeHolder
/// </summary> /// </summary>
public static Node2D? WeaponContainer { get; set; } public static Node2D? WeaponContainer { get; set; }
/// <summary>
/// <para>PlayerContainer</para>
/// <para>玩家容器</para>
/// </summary>
public static Node2D? PlayerContainer { get; set; } public static Node2D? PlayerContainer { get; set; }
/// <summary> /// <summary>
/// <para>AICharacterContainer</para> /// <para>AICharacterContainer</para>
/// <para>AICharacter角色</para> /// <para>AICharacter角色</para>
/// </summary> /// </summary>
public static Node2D? AICharacterContainer { get; set; } public static Node2D? AiCharacterContainer { get; set; }
/// <summary>
/// <para>HotBar</para>
/// <para>快捷栏</para>
/// </summary>
public static HotBar? HotBar { get; set; } public static HotBar? HotBar { get; set; }
/// <summary>
/// <para>Health Bar UI</para>
/// <para>健康条UI</para>
/// </summary>
public static HealthBarUi? HealthBarUi { get; set; } public static HealthBarUi? HealthBarUi { get; set; }
/// <summary>
/// <para>operation tip</para>
/// <para>操作提示</para>
/// </summary>
public static RichTextLabel? OperationTipLabel { get; set; } public static RichTextLabel? OperationTipLabel { get; set; }
} }

View File

@ -3,10 +3,19 @@ using Godot;
namespace ColdMint.scripts; namespace ColdMint.scripts;
/// <summary>
/// <para>HealthBarUi</para>
/// <para>健康条UI</para>
/// </summary>
public partial class HealthBarUi : HBoxContainer public partial class HealthBarUi : HBoxContainer
{ {
private int _maxHp; private int _maxHp;
private int _currentHp; private int _currentHp;
private Texture2D? _heartFull;
private Texture2D? _heartEmpty;
private Texture2D? _heartHalf;
private Texture2D? _heartQuarter;
private Texture2D? _heartThreeFourths;
public int CurrentHp public int CurrentHp
{ {
@ -139,11 +148,6 @@ public partial class HealthBarUi : HBoxContainer
} }
} }
private Texture2D? _heartFull;
private Texture2D? _heartEmpty;
private Texture2D? _heartHalf;
private Texture2D? _heartQuarter;
private Texture2D? _heartThreeFourths;
public override void _Ready() public override void _Ready()
{ {

View File

@ -1,5 +1,4 @@
using System.Collections.Generic; using ColdMint.scripts.utils;
using ColdMint.scripts.utils;
using Godot; using Godot;
namespace ColdMint.scripts; namespace ColdMint.scripts;

View File

@ -8,7 +8,7 @@ namespace ColdMint.scripts.camp;
/// </summary> /// </summary>
public class Camp public class Camp
{ {
private string _id; private readonly string _id;
private readonly List<string> _friendlyCampIdList; private readonly List<string> _friendlyCampIdList;
public Camp(string id) public Camp(string id)

View File

@ -146,7 +146,9 @@ public partial class CharacterTemplate : CharacterBody2D
return; return;
} }
CurrentHp = newHp; //Check whether the new Hp is greater than the maximum Hp. If yes, set the current Hp to the maximum Hp. If no, set the current Hp to the new HP
//判断新的Hp是否大于最大Hp若大于那么将当前Hp设置为最大Hp否则设置为新的Hp
CurrentHp = newHp > MaxHp ? MaxHp : newHp;
Visible = true; Visible = true;
} }
@ -352,10 +354,10 @@ public partial class CharacterTemplate : CharacterBody2D
//If the time difference between the last injury and the current time is greater than the time displayed in the health bar, the health bar is hidden //If the time difference between the last injury and the current time is greater than the time displayed in the health bar, the health bar is hidden
//如果上次受到伤害的时间与当前时间的时间差大于健康条显示时间,则隐藏健康条 //如果上次受到伤害的时间与当前时间的时间差大于健康条显示时间,则隐藏健康条
if (_healthBar is { Visible: true })
{
var timeSpan = DateTime.Now - _lastDamageTime; var timeSpan = DateTime.Now - _lastDamageTime;
if (timeSpan > Config.HealthBarDisplaysTime) if (timeSpan > Config.HealthBarDisplaysTime)
{
if (_healthBar != null)
{ {
_healthBar.Visible = false; _healthBar.Visible = false;
} }

View File

@ -12,22 +12,16 @@ public partial class DamageNumberNodeSpawn : Marker2D
private Node2D? _rootNode; private Node2D? _rootNode;
/// <summary> /// <summary>
/// <para>The horizontal velocity is in the X positive direction</para> /// <para>The vector in the negative direction</para>
/// <para>水平速度的X正方向</para> /// <para>负方向的向量</para>
/// </summary> /// </summary>
private int _horizontalVelocityPositiveDirection; private Vector2 _negativeVector;
/// <summary> /// <summary>
/// <para>Horizontal velocity in the negative X direction</para> /// <para>Vector in the positive direction</para>
/// <para>水平速度的X负方向</para> /// <para>正方向的向量</para>
/// </summary> /// </summary>
private int _horizontalVelocityNegativeDirection; private Vector2 _positiveVector;
/// <summary>
/// <para>vertical height</para>
/// <para>垂直高度</para>
/// </summary>
private int _verticalHeight;
/// <summary> /// <summary>
/// <para>物理渐变色</para> /// <para>物理渐变色</para>
@ -53,18 +47,31 @@ public partial class DamageNumberNodeSpawn : Marker2D
base._Ready(); base._Ready();
_damageNumberPackedScene = GD.Load("res://prefab/ui/DamageNumber.tscn") as PackedScene; _damageNumberPackedScene = GD.Load("res://prefab/ui/DamageNumber.tscn") as PackedScene;
_rootNode = GetNode<Node2D>("/root/Game/DamageNumberContainer"); _rootNode = GetNode<Node2D>("/root/Game/DamageNumberContainer");
_horizontalVelocityPositiveDirection = Config.CellSize * Config.HorizontalSpeedOfDamageNumbers; //The horizontal velocity is in the X positive direction
_horizontalVelocityNegativeDirection = -_horizontalVelocityPositiveDirection; //水平速度的X正方向
_verticalHeight = -Config.CellSize * Config.VerticalVelocityOfDamageNumbers; var horizontalVelocityPositiveDirection = Config.CellSize * Config.HorizontalSpeedOfDamageNumbers;
//Horizontal velocity in the negative X direction
//水平速度的X负方向
var horizontalVelocityNegativeDirection = -horizontalVelocityPositiveDirection;
//vertical height
//垂直高度
var verticalHeight = -Config.CellSize * Config.VerticalVelocityOfDamageNumbers;
//Compute left and right vectors
//计算左右向量
_negativeVector = new Vector2(horizontalVelocityNegativeDirection, verticalHeight);
_positiveVector = new Vector2(horizontalVelocityPositiveDirection, verticalHeight);
_physicalGradient = new Gradient(); _physicalGradient = new Gradient();
//Physical color from OpenColor2 to OpenColor6 (red)
//物理色 从OpenColor2 到 OpenColor6红色 //物理色 从OpenColor2 到 OpenColor6红色
_physicalGradient.SetColor(0, new Color("#ffc9c9")); _physicalGradient.SetColor(0, new Color("#ffc9c9"));
_physicalGradient.SetColor(1, new Color("#fa5252")); _physicalGradient.SetColor(1, new Color("#fa5252"));
_magicGradient = new Gradient(); _magicGradient = new Gradient();
//Magic Color from OpenColor2 to OpenColor6(Purple)
//魔法色 从OpenColor2 到 OpenColor6(紫色) //魔法色 从OpenColor2 到 OpenColor6(紫色)
_magicGradient.SetColor(0, new Color("#d0bfff")); _magicGradient.SetColor(0, new Color("#d0bfff"));
_magicGradient.SetColor(1, new Color("#7950f2")); _magicGradient.SetColor(1, new Color("#7950f2"));
_defaultGradient = new Gradient(); _defaultGradient = new Gradient();
//default behavior
//默认行为 //默认行为
_defaultGradient.SetColor(0, new Color("#ff8787")); _defaultGradient.SetColor(0, new Color("#ff8787"));
_defaultGradient.SetColor(1, new Color("#fa5252")); _defaultGradient.SetColor(1, new Color("#fa5252"));
@ -87,7 +94,7 @@ public partial class DamageNumberNodeSpawn : Marker2D
/// <param name="damageTemplate"></param> /// <param name="damageTemplate"></param>
public void Display(DamageTemplate damageTemplate) public void Display(DamageTemplate damageTemplate)
{ {
if (_damageNumberPackedScene == null) if (_rootNode == null || _damageNumberPackedScene == null)
{ {
return; return;
} }
@ -98,18 +105,22 @@ public partial class DamageNumberNodeSpawn : Marker2D
} }
CallDeferred("AddDamageNumberNode", damageNumber); CallDeferred("AddDamageNumberNode", damageNumber);
damageNumber.Position = GlobalPosition; damageNumber.Position = GlobalPosition;
if (damageTemplate.MoveLeft) if (damageTemplate.MoveLeft)
{ {
damageNumber.SetVelocity(new Vector2(_horizontalVelocityNegativeDirection, _verticalHeight)); damageNumber.SetVelocity(_negativeVector);
} }
else else
{ {
damageNumber.SetVelocity(new Vector2(_horizontalVelocityPositiveDirection, _verticalHeight)); damageNumber.SetVelocity(_positiveVector);
} }
var damageLabel = damageNumber.GetNode<Label>("Label"); var damageLabel = damageNumber.GetNode<Label>("Label");
if (damageLabel == null)
{
return;
}
damageLabel.Text = damageTemplate.Damage.ToString(); damageLabel.Text = damageTemplate.Damage.ToString();
var labelSettings = new LabelSettings(); var labelSettings = new LabelSettings();
var offset = damageTemplate.Damage / (float)damageTemplate.MaxDamage; var offset = damageTemplate.Damage / (float)damageTemplate.MaxDamage;

View File

@ -34,7 +34,7 @@ public partial class GameSceneLoader : SceneLoaderTemplate
//Load AICharacter container //Load AICharacter container
//加载AICharacter容器 //加载AICharacter容器
var aiCharacterContainer = GetNode<Node2D>("AICharacterContainer"); var aiCharacterContainer = GetNode<Node2D>("AICharacterContainer");
GameSceneNodeHolder.AICharacterContainer = aiCharacterContainer; GameSceneNodeHolder.AiCharacterContainer = aiCharacterContainer;
//Load player container //Load player container
//加载玩家容器 //加载玩家容器
var playerContainer = GetNode<Node2D>("PlayerContainer"); var playerContainer = GetNode<Node2D>("PlayerContainer");

View File

@ -38,12 +38,12 @@ public partial class AiCharacterSpawn : Marker2D
return; return;
} }
if (GameSceneNodeHolder.AICharacterContainer == null) if (GameSceneNodeHolder.AiCharacterContainer == null)
{ {
return; return;
} }
GameSceneNodeHolder.AICharacterContainer.AddChild(aiCharacter); GameSceneNodeHolder.AiCharacterContainer.AddChild(aiCharacter);
aiCharacter.Position = GlobalPosition; aiCharacter.Position = GlobalPosition;
} }

View File

@ -1,5 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using ColdMint.scripts.debug; using ColdMint.scripts.debug;
using ColdMint.scripts.levelGraphEditor; using ColdMint.scripts.levelGraphEditor;
@ -149,9 +148,9 @@ public static class MapGenerator
return; return;
} }
if (GameSceneNodeHolder.AICharacterContainer != null) if (GameSceneNodeHolder.AiCharacterContainer != null)
{ {
NodeUtils.DeleteAllChild(GameSceneNodeHolder.AICharacterContainer); NodeUtils.DeleteAllChild(GameSceneNodeHolder.AiCharacterContainer);
} }
NodeUtils.DeleteAllChild(_mapRoot); NodeUtils.DeleteAllChild(_mapRoot);

View File

@ -1,15 +0,0 @@
using Godot;
namespace ColdMint.scripts.map;
public partial class RoomAreaDetector : Node2D
{
private Area2D? _area2D;
public override void _Ready()
{
base._Ready();
_area2D = GetNode<Area2D>("Area2D");
}
}

View File

@ -12,9 +12,7 @@ namespace ColdMint.scripts.projectile;
/// </summary> /// </summary>
public partial class ProjectileTemplate : CharacterBody2D public partial class ProjectileTemplate : CharacterBody2D
{ {
protected Timer? Timer; protected long Life;
protected double Life;
//The durability of the projectile //The durability of the projectile
//抛射体的耐久度 //抛射体的耐久度
@ -26,9 +24,12 @@ public partial class ProjectileTemplate : CharacterBody2D
protected int MinDamage; protected int MinDamage;
protected int DamageType; protected int DamageType;
//We use the Time node to specify when to destroy the projectile /// <summary>
//我们用Time节点来指定何时销毁抛射体 /// <para>After this time destroy the projectile</para>
private Timer? _timer; /// <para>超过此时刻销毁抛射体</para>
/// </summary>
private DateTime? _destructionTime;
/// <summary> /// <summary>
/// <para>The impact area of the bullet</para> /// <para>The impact area of the bullet</para>
@ -46,10 +47,7 @@ public partial class ProjectileTemplate : CharacterBody2D
/// </remarks> /// </remarks>
protected Vector2 KnockbackForce; protected Vector2 KnockbackForce;
public float Speed public float Speed => GetMeta("Speed", "15").AsSingle();
{
get => GetMeta("Speed", "15").AsSingle();
}
/// <summary> /// <summary>
/// <para>The master of the weapon</para> /// <para>The master of the weapon</para>
@ -59,6 +57,7 @@ public partial class ProjectileTemplate : CharacterBody2D
public override void _Ready() public override void _Ready()
{ {
//The bullet's impact detection area
//子弹的碰撞检测区域 //子弹的碰撞检测区域
Area2D = GetNode<Area2D>("CollisionDetectionArea"); Area2D = GetNode<Area2D>("CollisionDetectionArea");
Area2D.Monitoring = true; Area2D.Monitoring = true;
@ -69,20 +68,17 @@ public partial class ProjectileTemplate : CharacterBody2D
MinDamage = GetMeta("MinDamage", "5").AsInt32(); MinDamage = GetMeta("MinDamage", "5").AsInt32();
DamageType = GetMeta("DamageType", Config.DamageType.Physical).AsInt32(); DamageType = GetMeta("DamageType", Config.DamageType.Physical).AsInt32();
KnockbackForce = GetMeta("Knockback", Vector2.Zero).AsVector2(); KnockbackForce = GetMeta("Knockback", Vector2.Zero).AsVector2();
//子弹的存在时间 //life(ms)
Life = GetMeta("Life", "10").AsDouble(); //子弹的存在时间(毫秒)
Life = GetMeta("Life", "10000").AsInt64();
//If the existence time is less than or equal to 0, then it is set to exist for 10 seconds, and projectiles that exist indefinitely are prohibited
//如果存在时间小于等于0那么设置为存在10秒禁止无限期存在的抛射体 //如果存在时间小于等于0那么设置为存在10秒禁止无限期存在的抛射体
if (Life <= 0) if (Life <= 0)
{ {
Life = 10; Life = 10000;
} }
Timer = new Timer(); _destructionTime = DateTime.Now.AddMilliseconds(Life);
AddChild(Timer);
Timer.WaitTime = Life;
Timer.OneShot = true;
Timer.Start();
Timer.Timeout += OnTimeOut;
} }
@ -141,10 +137,12 @@ public partial class ProjectileTemplate : CharacterBody2D
//Allow damage to be caused //Allow damage to be caused
//允许造成伤害 //允许造成伤害
var damage = new Damage(); var damage = new Damage
damage.Attacker = owner; {
damage.MaxDamage = MaxDamage; Attacker = owner,
damage.MinDamage = MinDamage; MaxDamage = MaxDamage,
MinDamage = MinDamage
};
damage.CreateDamage(); damage.CreateDamage();
damage.MoveLeft = Velocity.X < 0; damage.MoveLeft = Velocity.X < 0;
damage.Type = DamageType; damage.Type = DamageType;
@ -182,6 +180,7 @@ public partial class ProjectileTemplate : CharacterBody2D
{ {
return; return;
} }
DoDamage(Owner, node); DoDamage(Owner, node);
//Please specify in the Mask who the bullet will collide with //Please specify in the Mask who the bullet will collide with
//请在Mask内配置子弹会和谁碰撞 //请在Mask内配置子弹会和谁碰撞
@ -215,6 +214,16 @@ public partial class ProjectileTemplate : CharacterBody2D
QueueFree(); QueueFree();
} }
public override void _Process(double delta)
{
//If the existence time is exceeded, the projectile is destroyed
//如果超过了存在时间,那么销毁抛射体
if (DateTime.Now >= _destructionTime)
{
OnTimeOut();
}
}
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
{ {
MoveAndSlide(); MoveAndSlide();

View File

@ -5,9 +5,13 @@ using System.Threading.Tasks;
namespace ColdMint.scripts.serialization; namespace ColdMint.scripts.serialization;
/// <summary>
/// <para>JsonSerialization</para>
/// <para>Json序列化工具</para>
/// </summary>
public static class JsonSerialization public static class JsonSerialization
{ {
private static JsonSerializerOptions _options = new JsonSerializerOptions private static readonly JsonSerializerOptions Options = new()
{ {
//Case-insensitive attribute matching //Case-insensitive attribute matching
//不区分大小写的属性匹配 //不区分大小写的属性匹配
@ -30,7 +34,7 @@ public static class JsonSerialization
public static async Task<T?> ReadJsonFileToObj<T>(string path) public static async Task<T?> ReadJsonFileToObj<T>(string path)
{ {
await using var openStream = File.OpenRead(path); await using var openStream = File.OpenRead(path);
return await JsonSerializer.DeserializeAsync<T>(openStream, _options); return await JsonSerializer.DeserializeAsync<T>(openStream, Options);
} }
/// <summary> /// <summary>
@ -41,7 +45,7 @@ public static class JsonSerialization
/// <returns></returns> /// <returns></returns>
public static string Serialize(object obj) public static string Serialize(object obj)
{ {
return JsonSerializer.Serialize(obj, _options); return JsonSerializer.Serialize(obj, Options);
} }
/// <summary> /// <summary>
@ -53,11 +57,11 @@ public static class JsonSerialization
/// <returns></returns> /// <returns></returns>
public static T? Deserialize<T>(string json) public static T? Deserialize<T>(string json)
{ {
return JsonSerializer.Deserialize<T>(json, _options); return JsonSerializer.Deserialize<T>(json, Options);
} }
public static async Task<T?> ReadJsonFileToObj<T>(Stream openStream) public static async Task<T?> ReadJsonFileToObj<T>(Stream openStream)
{ {
return await JsonSerializer.DeserializeAsync<T>(openStream, _options); return await JsonSerializer.DeserializeAsync<T>(openStream, Options);
} }
} }

View File

@ -2,7 +2,11 @@
namespace ColdMint.scripts.utils; namespace ColdMint.scripts.utils;
public class CoordinateUtils /// <summary>
/// <para>CoordinateUtils</para>
/// <para>坐标工具类</para>
/// </summary>
public static class CoordinateUtils
{ {
/// <summary> /// <summary>
/// <para>方向描述</para> /// <para>方向描述</para>

View File

@ -1,4 +1,5 @@
using System.Diagnostics; using System;
using System.Diagnostics;
namespace ColdMint.scripts.utils; namespace ColdMint.scripts.utils;
@ -6,7 +7,7 @@ namespace ColdMint.scripts.utils;
/// <para>Explorer Utils</para> /// <para>Explorer Utils</para>
/// <para>资源管理器工具</para> /// <para>资源管理器工具</para>
/// </summary> /// </summary>
public class ExplorerUtils public static class ExplorerUtils
{ {
/// <summary> /// <summary>
/// <para>Call Explorer to open the directory</para> /// <para>Call Explorer to open the directory</para>
@ -53,6 +54,12 @@ public class ExplorerUtils
}; };
Process.Start(startInfoAndroid); Process.Start(startInfoAndroid);
break; break;
case Config.OsEnum.Unknown:
case Config.OsEnum.Macos:
case Config.OsEnum.Ios:
case Config.OsEnum.Web:
default:
throw new ArgumentOutOfRangeException();
} }
} }
@ -64,14 +71,10 @@ public class ExplorerUtils
public static bool SupportOpenDirectory() public static bool SupportOpenDirectory()
{ {
var osEnum = Config.GetOs(); var osEnum = Config.GetOs();
switch (osEnum) return osEnum switch
{ {
case Config.OsEnum.Windows: Config.OsEnum.Windows or Config.OsEnum.Linux or Config.OsEnum.Android => true,
case Config.OsEnum.Linux: _ => false
case Config.OsEnum.Android: };
return true;
default:
return false;
}
} }
} }

View File

@ -2,7 +2,11 @@
namespace ColdMint.scripts.utils; namespace ColdMint.scripts.utils;
public class GuidUtils /// <summary>
/// <para>GuidUtils</para>
/// <para>Guid工具</para>
/// </summary>
public static class GuidUtils
{ {
/// <summary> /// <summary>
/// <para>Get the new GUID</para> /// <para>Get the new GUID</para>

View File

@ -2,7 +2,11 @@
namespace ColdMint.scripts.utils; namespace ColdMint.scripts.utils;
public class HashCodeUtils /// <summary>
/// <para>Hash code utils</para>
/// <para>哈希码工具</para>
/// </summary>
public static class HashCodeUtils
{ {
/// <summary> /// <summary>
/// <para>Gets the hash code for a string</para> /// <para>Gets the hash code for a string</para>
@ -15,6 +19,8 @@ public class HashCodeUtils
/// <returns></returns> /// <returns></returns>
public static uint GetFixedHashCode(string str) public static uint GetFixedHashCode(string str)
{ {
//Turn off overflow checking to improve performance
//关闭溢出检查,以提高性能
unchecked unchecked
{ {
return str.Aggregate(2166136261, (current, c) => (current ^ c) * 16777619); return str.Aggregate(2166136261, (current, c) => (current ^ c) * 16777619);

View File

@ -15,15 +15,11 @@ public class Md5Utils
/// <returns></returns> /// <returns></returns>
public static string GetFileMd5(string filePath) public static string GetFileMd5(string filePath)
{ {
using (var md5 = MD5.Create()) using var md5 = MD5.Create();
{ using var stream = File.OpenRead(filePath);
using (var stream = File.OpenRead(filePath))
{
var hash = md5.ComputeHash(stream); var hash = md5.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
} }
}
}
/// <summary> /// <summary>
/// <para>Calculates the Md5 value of the string</para> /// <para>Calculates the Md5 value of the string</para>
@ -33,10 +29,8 @@ public class Md5Utils
/// <returns></returns> /// <returns></returns>
public static string GetStringMd5(string str) public static string GetStringMd5(string str)
{ {
using (var md5 = MD5.Create()) using var md5 = MD5.Create();
{
var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(str)); var hash = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
} }
}
} }

View File

@ -4,7 +4,11 @@ using Godot;
namespace ColdMint.scripts.utils; namespace ColdMint.scripts.utils;
public class NodeUtils /// <summary>
/// <para>Node Utils</para>
/// <para>节点工具</para>
/// </summary>
public static class NodeUtils
{ {
/// <summary> /// <summary>
/// <para>Delete all child nodes</para> /// <para>Delete all child nodes</para>
@ -81,11 +85,10 @@ public class NodeUtils
continue; continue;
} }
var distance = node2D.GlobalPosition - origin.GlobalPosition; var distance = node2D.GlobalPosition.DistanceTo(origin.GlobalPosition);
var distanceLength = distance.Length(); if (distance < closestDistance)
if (distanceLength < closestDistance)
{ {
closestDistance = distanceLength; closestDistance = distance;
closestNode = node2D; closestNode = node2D;
} }
} }

View File

@ -6,7 +6,7 @@ namespace ColdMint.scripts.utils;
/// <para>ParabolicUtils</para> /// <para>ParabolicUtils</para>
/// <para>抛物线工具</para> /// <para>抛物线工具</para>
/// </summary> /// </summary>
public class ParabolicUtils public static class ParabolicUtils
{ {
/// <summary> /// <summary>
/// <para>Calculated parabola</para> /// <para>Calculated parabola</para>
@ -40,7 +40,7 @@ public class ParabolicUtils
// 初始化结果数组 // 初始化结果数组
var points = new Vector2[numSteps]; var points = new Vector2[numSteps];
// 计算每个采样点的位置 // 计算每个采样点的位置
for (int i = 0; i < numSteps; i++) for (var i = 0; i < numSteps; i++)
{ {
// 计算当前时间 // 计算当前时间
var t = i * steps; var t = i * steps;

View File

@ -1,6 +1,10 @@
namespace ColdMint.scripts.utils; namespace ColdMint.scripts.utils;
public class StrUtils /// <summary>
/// <para>StrUtils</para>
/// <para>字符串工具</para>
/// </summary>
public static class StrUtils
{ {
/// <summary> /// <summary>

View File

@ -2,6 +2,10 @@
namespace ColdMint.scripts.utils; namespace ColdMint.scripts.utils;
/// <summary>
/// <para>TileMapUtils</para>
/// <para>TileMap工具</para>
/// </summary>
public static class TileMapUtils public static class TileMapUtils
{ {
/// <summary> /// <summary>

View File

@ -3,6 +3,10 @@ using ColdMint.scripts.debug;
namespace ColdMint.scripts.utils; namespace ColdMint.scripts.utils;
/// <summary>
/// <para>Time Utils</para>
/// <para>时间工具</para>
/// </summary>
public static class TimeUtils public static class TimeUtils
{ {
/// <summary> /// <summary>

View File

@ -2,6 +2,10 @@
namespace ColdMint.scripts.utils; namespace ColdMint.scripts.utils;
/// <summary>
/// <para>Translation server utils</para>
/// <para>翻译服务器工具</para>
/// </summary>
public static class TranslationServerUtils public static class TranslationServerUtils
{ {
/// <summary> /// <summary>

View File

@ -5,9 +5,26 @@ using Godot;
namespace ColdMint.scripts.weapon; namespace ColdMint.scripts.weapon;
/// <summary>
/// <para>Projectile weapons</para>
/// <para>抛射体武器</para>
/// </summary>
/// <remarks>
///<para>These weapons can fire projectiles to attack the enemy.For example: guns and scepters.Generate a bullet to attack the enemy.</para>
///<para>这类武器可发射抛射体,攻击敌人。例如:枪支和法杖。生成一个子弹攻击敌人。</para>
/// </remarks>
public partial class ProjectileWeapon : WeaponTemplate public partial class ProjectileWeapon : WeaponTemplate
{ {
/// <summary>
/// <para>The formation position of the projectile</para>
/// <para>抛射体的生成位置</para>
/// </summary>
private Marker2D? _marker2D; private Marker2D? _marker2D;
/// <summary>
/// <para>List of projectiles</para>
/// <para>抛射体列表</para>
/// </summary>
private string[]? _projectiles; private string[]? _projectiles;
private Dictionary<string, PackedScene>? _projectileCache; private Dictionary<string, PackedScene>? _projectileCache;
private Node2D? _projectileContainer; private Node2D? _projectileContainer;
@ -21,6 +38,10 @@ public partial class ProjectileWeapon : WeaponTemplate
foreach (var projectileItem in _projectiles) foreach (var projectileItem in _projectiles)
{ {
var packedScene = GD.Load<PackedScene>(projectileItem); var packedScene = GD.Load<PackedScene>(projectileItem);
if (packedScene == null)
{
continue;
}
_projectileCache.Add(projectileItem, packedScene); _projectileCache.Add(projectileItem, packedScene);
} }
@ -30,26 +51,25 @@ public partial class ProjectileWeapon : WeaponTemplate
protected override void DoFire(Node2D? owner, Vector2 enemyGlobalPosition) protected override void DoFire(Node2D? owner, Vector2 enemyGlobalPosition)
{ {
if (_projectiles.IsEmpty())
{
LogCat.LogError("projectiles_is_empty");
return;
}
if (_projectileCache == null || _projectiles == null || owner == null || _projectileContainer == null || if (_projectileCache == null || _projectiles == null || owner == null || _projectileContainer == null ||
_marker2D == null) _marker2D == null)
{ {
return; return;
} }
if (_projectiles.IsEmpty())
{
LogCat.LogError("projectiles_is_empty");
return;
}
//Get the first projectile //Get the first projectile
//获取第一个抛射体
var projectileScene = _projectileCache[_projectiles[0]]; var projectileScene = _projectileCache[_projectiles[0]];
var projectile = projectileScene.Instantiate() as ProjectileTemplate; var projectile = projectileScene.Instantiate() as ProjectileTemplate;
if (projectile != null) if (projectile != null)
{ {
projectile.Owner = owner; projectile.Owner = owner;
var vector2 = (enemyGlobalPosition - _marker2D.GlobalPosition).Normalized() * projectile.Speed; projectile.Velocity = (enemyGlobalPosition - _marker2D.GlobalPosition).Normalized() * projectile.Speed;
projectile.Velocity = vector2;
projectile.Position = _marker2D.GlobalPosition; projectile.Position = _marker2D.GlobalPosition;
} }

View File

@ -13,7 +13,7 @@ namespace ColdMint.scripts.weapon;
/// </summary> /// </summary>
public partial class WeaponTemplate : RigidBody2D, IItem public partial class WeaponTemplate : RigidBody2D, IItem
{ {
public float Gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle(); private float _gravity = ProjectSettings.GetSetting("physics/2d/default_gravity").AsSingle();
public string? Id { get; set; } public string? Id { get; set; }
public int Quantity { get; set; } public int Quantity { get; set; }
@ -42,7 +42,10 @@ public partial class WeaponTemplate : RigidBody2D, IItem
private DateTime? _lastFiringTime; private DateTime? _lastFiringTime;
//开火间隔 /// <summary>
/// <para>Firing interval</para>
/// <para>开火间隔</para>
/// </summary>
private TimeSpan _firingInterval; private TimeSpan _firingInterval;
@ -56,6 +59,10 @@ public partial class WeaponTemplate : RigidBody2D, IItem
/// </remarks> /// </remarks>
private Vector2 _recoil; private Vector2 _recoil;
/// <summary>
/// <para>This area represents the collision range of the weapon, and when other nodes enter this area, they will deal damage.</para>
/// <para>这个区域表示武器的碰撞范围,当其他节点进入此区域时,会造成伤害。</para>
/// </summary>
private Area2D? _area2D; private Area2D? _area2D;
protected RayCast2D? RayCast2D; protected RayCast2D? RayCast2D;
@ -117,7 +124,6 @@ public partial class WeaponTemplate : RigidBody2D, IItem
//If allowed to cause harm //If allowed to cause harm
//如果允许造成伤害 //如果允许造成伤害
Owner = null;
var damage = new Damage var damage = new Damage
{ {
MaxDamage = Math.Abs(_maxContactInjury), MaxDamage = Math.Abs(_maxContactInjury),
@ -128,6 +134,9 @@ public partial class WeaponTemplate : RigidBody2D, IItem
damage.MoveLeft = LinearVelocity.X < 0; damage.MoveLeft = LinearVelocity.X < 0;
damage.Type = Config.DamageType.Physical; damage.Type = Config.DamageType.Physical;
characterTemplate.Damage(damage); characterTemplate.Damage(damage);
//Can only cause one collision damage.
//仅能造成一次碰撞伤害。
EnableContactInjury = false;
} }
/// <summary> /// <summary>