diff --git a/ColdMint.Traveler.csproj b/ColdMint.Traveler.csproj index c8681d1..9ba3342 100644 --- a/ColdMint.Traveler.csproj +++ b/ColdMint.Traveler.csproj @@ -10,8 +10,6 @@ - - \ No newline at end of file diff --git a/locals/Log.csv b/locals/Log.csv index f23d688..ec89ed7 100644 --- a/locals/Log.csv +++ b/locals/Log.csv @@ -72,11 +72,15 @@ log_state_processor_not_found,找不到状态处理器{0}。,State processor {0} log_chase_no_enemy,追逐没有敌人。,Chase no enemy.,敵がいない追跡です。 log_bubble_not_found,找不到气泡{0}。,Bubble {0} not found.,バブル{0}が見つかりません。 log_owner_is_not_AiCharacter,所有者不是AiCharacter。,Owner is not AiCharacter.,所有者はAiCharacterではありません。 -log_weaponContainer_is_null,武器容器为空。,Weapon container is null.,武器コンテナが空です。 log_find_nearest_item,查找最近的物品。,Find the nearest item.,最も近いアイテムを見つけます。 log_float_label_instantiate_failed,浮动标签实例化失败。,Float label instantiation failed.,フロートラベルのインスタンス化に失敗しました。 log_pickable_picked_up,可拾捡物被捡起了,那么不显示标签。,"If the pickable item is picked up, the label is not displayed.",でも、拾得物が拾い上げられたら、ラベルは表示されません。 log_start_uploading,开始上传{0}条日志。,Start uploading {0} logs.,{0}個のログをアップロードを開始します。 log_upload_successful,上传成功,已上传{0}条日志,剩余{1}条日志待上传。,"Upload successful, {0} logs uploaded, {1} logs remaining.",アップロードが成功しました、{0}個のログがアップロードされ、{1}個のログが残っています。 log_upload_failed,上传失败,错误代码:{0},剩余{1}条日志待上传。,"Upload failed, error code: {0}, {1} logs remaining.",アップロードに失敗しました、エラーコード:{0}、{1}個のログが残っています。 -log_upload_status,已记录{0}条日志,上传阈值为{1}。,"{0} logs recorded, upload threshold is {1}.",{0}個のログが記録され、アップロード閾値は{1}です。 \ No newline at end of file +log_upload_status,已记录{0}条日志,上传阈值为{1}。,"{0} logs recorded, upload threshold is {1}.",{0}個のログが記録され、アップロード閾値は{1}です。 +log_weapon_detected,检测到武器。,Weapon detected.,武器が検出されました。 +log_no_weapon_detected,没有检测到武器。,No weapon detected.,武器が検出されません。 +log_weapon_lost,武器丢失。,Weapon lost.,武器が失われました。 +log_nearest_node_is_null,最近的节点为空。,The nearest node is null.,最も近いノードが空です。 +log_node_is_not_WeaponTemplate,节点不是WeaponTemplate。,The node is not a WeaponTemplate.,ノードはWeaponTemplateではありません。 \ No newline at end of file diff --git a/locals/Slogan.csv b/locals/Slogan.csv index 9116ba0..e9a1f5d 100644 --- a/locals/Slogan.csv +++ b/locals/Slogan.csv @@ -4,4 +4,3 @@ slogan_1,Kawaii!,Kawaii!,Kawaii! slogan_2,魔法是想象的世界。,Magic is an imaginary world.,魔法は想像の世界です。 slogan_3,也试试《Minecraft》!,Also try 'Minecraft'!,「Minecraft」もやってみて! slogan_4,也试试《Terraria》!,Also try 'Terraria'!,「Terraria」もやってみて! -slogan_5,你好,Hello,こんにちは \ No newline at end of file diff --git a/prefab/entitys/DelivererOfDarkMagic.tscn b/prefab/entitys/DelivererOfDarkMagic.tscn index 1b6b35d..feedaf1 100644 --- a/prefab/entitys/DelivererOfDarkMagic.tscn +++ b/prefab/entitys/DelivererOfDarkMagic.tscn @@ -34,7 +34,6 @@ radius = 233.808 collision_layer = 64 collision_mask = 38 script = ExtResource("1_ubaid") -InitWeaponRes = "res://prefab/weapons/staffOfTheUndead.tscn" LootListId = "test" metadata/CampId = "Mazoku" metadata/MaxHp = 50 @@ -95,7 +94,7 @@ scale = Vector2(2.04, 3.05) [node name="ScoutArea2D" type="Area2D" parent="."] collision_layer = 0 -collision_mask = 68 +collision_mask = 76 [node name="CollisionShape2D" type="CollisionShape2D" parent="ScoutArea2D"] shape = SubResource("CircleShape2D_fowd5") diff --git a/scenes/splashScreen.tscn b/scenes/splashScreen.tscn index 0e01cab..20e11f3 100644 --- a/scenes/splashScreen.tscn +++ b/scenes/splashScreen.tscn @@ -265,7 +265,6 @@ vertical_alignment = 1 libraries = { "": SubResource("AnimationLibrary_mraly") } -autoplay = "startup" [node name="NameLabel" type="Label" parent="."] modulate = Color(1, 1, 1, 0) diff --git a/scripts/character/AiCharacter.cs b/scripts/character/AiCharacter.cs index ca16c6e..c63eab4 100644 --- a/scripts/character/AiCharacter.cs +++ b/scripts/character/AiCharacter.cs @@ -46,6 +46,12 @@ public sealed partial class AiCharacter : CharacterTemplate /// private List? _enemyInTheScoutRange; + /// + /// Every weapon in the recon area + /// 在侦察范围内所有的武器 + /// + private List? _weaponInTheScoutRange; + /// /// Obstacle detection ray during attack @@ -107,6 +113,7 @@ public sealed partial class AiCharacter : CharacterTemplate _enemyInTheAttackRange = new List(); _enemyInTheScoutRange = new List(); + _weaponInTheScoutRange = new List(); _screenEnabler2D = GetNode("VisibleOnScreenEnabler2D"); _screenEnabler2D.ScreenEntered += () => { @@ -182,7 +189,7 @@ public sealed partial class AiCharacter : CharacterTemplate //You must create an item container for the character before you can pick up the item. //必须为角色创建物品容器后才能拾起物品。 var universalItemContainer = new UniversalItemContainer(); - var itemSlotNode = universalItemContainer.AddItemSlot(this); + var itemSlotNode = universalItemContainer.AddItemSlot(this); itemSlotNode?.Hide(); ProtectedItemContainer = universalItemContainer; //Add initial weapon @@ -209,6 +216,7 @@ public sealed partial class AiCharacter : CharacterTemplate { return; } + NodeUtils.CallDeferredAddChild(this, weaponTemplate); PickItem(weaponTemplate); } @@ -260,6 +268,36 @@ public sealed partial class AiCharacter : CharacterTemplate return _enemyInTheScoutRange.Count > 0; } + /// + /// Any weapons found in the recon area + /// 侦察范围内是否发现武器 + /// + /// + public bool ScoutWeaponDetected() + { + if (_weaponInTheScoutRange == null) + { + return false; + } + + return _weaponInTheScoutRange.Count > 0; + } + + /// + /// Get weapons in the recon area + /// 获取侦察范围内的武器 + /// + /// + public WeaponTemplate[]? GetWeaponInScoutArea() + { + if (_weaponInTheScoutRange == null) + { + return null; + } + + return _weaponInTheScoutRange.ToArray(); + } + /// /// Get the first enemy in range /// 获取第一个进入侦察范围的敌人 @@ -308,6 +346,11 @@ public sealed partial class AiCharacter : CharacterTemplate /// private void EnterTheScoutArea(Node node) { + if (node is WeaponTemplate weaponTemplate) + { + _weaponInTheScoutRange?.Add(weaponTemplate); + } + CanCauseHarmNode(node, (canCause, characterTemplate) => { if (canCause && characterTemplate != null) @@ -329,6 +372,11 @@ public sealed partial class AiCharacter : CharacterTemplate return; } + if (node is WeaponTemplate weaponTemplate) + { + _weaponInTheScoutRange?.Remove(weaponTemplate); + } + if (node is CharacterTemplate characterTemplate) { _enemyInTheScoutRange?.Remove(characterTemplate); diff --git a/scripts/debug/LogCat.cs b/scripts/debug/LogCat.cs index bd82d75..aaab15b 100644 --- a/scripts/debug/LogCat.cs +++ b/scripts/debug/LogCat.cs @@ -4,9 +4,6 @@ using System.Text; using ColdMint.scripts.openObserve; using ColdMint.scripts.utils; using Godot; -using Microsoft.Extensions.Logging; -using OpenTelemetry.Exporter; -using OpenTelemetry.Logs; namespace ColdMint.scripts.debug; @@ -20,6 +17,12 @@ public static class LogCat /// public const string Default = "Default"; + /// + /// LookForWeaponProcessor + /// 查找武器处理器 + /// + public const string LookForWeaponProcessor = "LookForWeaponProcessor"; + /// /// PatrolStateProcessor /// 巡逻状态处理器 @@ -119,25 +122,6 @@ public static class LogCat private static HashSet DisabledLogLabels { get; } = []; - public static void Init() - { - var loggerFactory = LoggerFactory.Create(builder => - { - builder.AddOpenTelemetry(options => { options.AddOtlpExporter(OtlpExporterOptions); }); - }); - var logger = loggerFactory.CreateLogger("323"); - logger.Log(LogLevel.Debug, "你好"); - } - - public static void OtlpExporterOptions(OtlpExporterOptions options) - { - options.Protocol = OtlpExportProtocol.HttpProtobuf; - options.Endpoint = new Uri("http://test.coldmint.top/api/default/traces"); - options.Headers = - "Authorization=Basic cm9vdEBleGFtcGxlLmNvbTp5V0kwVzZYcWhteTBzQml3,organization=default,stream-name=default"; - } - - /// /// Disable log Label /// 禁用某个日志标签 diff --git a/scripts/loader/uiLoader/SplashScreenLoader.cs b/scripts/loader/uiLoader/SplashScreenLoader.cs index 8817992..b80687a 100644 --- a/scripts/loader/uiLoader/SplashScreenLoader.cs +++ b/scripts/loader/uiLoader/SplashScreenLoader.cs @@ -23,6 +23,8 @@ public partial class SplashScreenLoader : UiLoaderTemplate private Label? _loadingLabel; private PackedScene? _mainMenuScene; private AnimationPlayer? _animationPlayer; + private string _startup = "startup"; + private Label? _nameLabel; public override void InitializeData() { @@ -31,9 +33,22 @@ public partial class SplashScreenLoader : UiLoaderTemplate public override void InitializeUi() { + _nameLabel = GetNode public class LookForWeaponProcessor : StateProcessorTemplate { - protected WeaponTemplate weaponTemplate; + protected WeaponTemplate? TargetWeapon; + protected override void OnExecute(StateContext context, Node owner) { - //Find weapons around your character. - //查找角色周围的武器。 if (owner is not AiCharacter aiCharacter) { - LogCat.LogError("owner_is_not_AiCharacter"); + LogCat.LogError("owner_is_not_AiCharacter", LogCat.LogLabel.LookForWeaponProcessor); return; } - if (GameSceneNodeHolder.WeaponContainer == null) + if (TargetWeapon != null) { - LogCat.LogError("weaponContainer_is_null"); + //If the nearest weapon is found, move the character to the weapon. + //如果有最近的武器被找到了,那么将角色移动到武器旁边。 + aiCharacter.SetTargetPosition(TargetWeapon.GlobalPosition); return; } - NodeUtils.ForEachNode(GameSceneNodeHolder.WeaponContainer, template => + if (aiCharacter.ScoutWeaponDetected()) { - if (template.GlobalPosition.DistanceTo(aiCharacter.GlobalPosition) > 100) + //Weapons were found in the character's recon area. + //在角色的侦察范围内发现了武器。 + //We search for the nearest weapon. + //我们搜索最近的武器。 + LogCat.Log("weapon_detected", LogCat.LogLabel.LookForWeaponProcessor); + var weaponTemplates = aiCharacter.GetWeaponInScoutArea(); + if (weaponTemplates == null || weaponTemplates.Length == 0) { - weaponTemplate = template; - return true; + //The weapon may have been lost or taken by someone else. + //武器可能已丢失,或被他人占用。 + LogCat.Log("weapon_lost", LogCat.LogLabel.LookForWeaponProcessor); + return; } - return false; - }); + + var nodes = new List(); + foreach (var weapon in weaponTemplates) + { + if (weapon is Node newNode) + { + nodes.Add(newNode); + } + } + + var node = NodeUtils.GetTheNearestNode(aiCharacter, nodes.ToArray()); + if (node == null) + { + //When looking for the nearest node, return null. + //查找最近的节点时,返回null。 + LogCat.Log("nearest_node_is_null", LogCat.LogLabel.LookForWeaponProcessor); + return; + } + + if (node is WeaponTemplate weaponTemplate) + { + TargetWeapon = weaponTemplate; + } + else + { + LogCat.LogError("node_is_not_WeaponTemplate", LogCat.LogLabel.LookForWeaponProcessor); + } + } + else + { + //No weapons detected + //没有检测到武器 + LogCat.Log("no_weapon_detected", LogCat.LogLabel.LookForWeaponProcessor); + } } public override State State => State.LookForWeapon; diff --git a/scripts/stateMachine/StateProcessor/PatrolStateProcessor.cs b/scripts/stateMachine/StateProcessor/PatrolStateProcessor.cs index 5d10ed8..b2f66ba 100644 --- a/scripts/stateMachine/StateProcessor/PatrolStateProcessor.cs +++ b/scripts/stateMachine/StateProcessor/PatrolStateProcessor.cs @@ -1,5 +1,6 @@ using ColdMint.scripts.character; using ColdMint.scripts.debug; +using ColdMint.scripts.weapon; using Godot; namespace ColdMint.scripts.stateMachine.StateProcessor; @@ -11,6 +12,7 @@ namespace ColdMint.scripts.stateMachine.StateProcessor; public class PatrolStateProcessor : StateProcessorTemplate { public Vector2[]? Points { get; set; } + /// /// Whether to guard the origin /// 是否需要守护原点 @@ -45,14 +47,14 @@ public class PatrolStateProcessor : StateProcessorTemplate { //Once the enemy enters the reconnaissance range, we first see if the character has a weapon, if so, then pursue the enemy, otherwise, the patrol state changes to looking for weapons. //发现敌人进入侦察范围后,我们先看角色是否持有武器,如果有,那么追击敌人,否则,巡逻状态转换为寻找武器。 - // if (aiCharacter.CurrentItem is WeaponTemplate weaponTemplate) - // { - context.CurrentState = State.Chase; - // } - // else - // { - // context.CurrentState = State.LookForWeapon; - // } + if (aiCharacter.CurrentItem is WeaponTemplate weaponTemplate) + { + context.CurrentState = State.Chase; + } + else + { + context.CurrentState = State.LookForWeapon; + } LogCat.Log("patrol_enemy_detected", label: LogCat.LogLabel.PatrolStateProcessor); return; @@ -78,7 +80,7 @@ public class PatrolStateProcessor : StateProcessorTemplate _originPosition = aiCharacter.GlobalPosition; LogCat.LogWithFormat("patrol_origin_position", LogCat.LogLabel.PatrolStateProcessor, - LogCat.UploadFormat,_originPosition); + LogCat.UploadFormat, _originPosition); } var point = _originPosition + Points[_index]; @@ -87,7 +89,8 @@ public class PatrolStateProcessor : StateProcessorTemplate { //No need to actually come to the patrol point, we just need a distance to get close. //无需真正的来到巡逻点,我们只需要一个距离接近了就可以了。 - LogCat.LogWithFormat("patrol_arrival_point", LogCat.LogLabel.PatrolStateProcessor, LogCat.UploadFormat,point); + LogCat.LogWithFormat("patrol_arrival_point", LogCat.LogLabel.PatrolStateProcessor, LogCat.UploadFormat, + point); _index++; if (_index >= Points.Length) { @@ -96,7 +99,8 @@ public class PatrolStateProcessor : StateProcessorTemplate } else { - LogCat.LogWithFormat("patrol_to_next_point", label: LogCat.LogLabel.PatrolStateProcessor, LogCat.UploadFormat,point, + LogCat.LogWithFormat("patrol_to_next_point", label: LogCat.LogLabel.PatrolStateProcessor, + LogCat.UploadFormat, point, aiCharacter.GlobalPosition, Points[_index], distance); aiCharacter.SetTargetPosition(point.Value);