Remove useless dependencies and add logic for AI to find weapons.
移除无用依赖,加入AI查找武器的逻辑。
This commit is contained in:
parent
dd16e14947
commit
7812d9c570
|
@ -10,8 +10,6 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0-preview.6.24327.7" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="15.1.6" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -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}です。
|
||||
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ではありません。
|
|
|
@ -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,こんにちは
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -46,6 +46,12 @@ public sealed partial class AiCharacter : CharacterTemplate
|
|||
/// </summary>
|
||||
private List<CharacterTemplate>? _enemyInTheScoutRange;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Every weapon in the recon area</para>
|
||||
/// <para>在侦察范围内所有的武器</para>
|
||||
/// </summary>
|
||||
private List<WeaponTemplate>? _weaponInTheScoutRange;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>Obstacle detection ray during attack</para>
|
||||
|
@ -107,6 +113,7 @@ public sealed partial class AiCharacter : CharacterTemplate
|
|||
|
||||
_enemyInTheAttackRange = new List<CharacterTemplate>();
|
||||
_enemyInTheScoutRange = new List<CharacterTemplate>();
|
||||
_weaponInTheScoutRange = new List<WeaponTemplate>();
|
||||
_screenEnabler2D = GetNode<VisibleOnScreenEnabler2D>("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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Any weapons found in the recon area</para>
|
||||
/// <para>侦察范围内是否发现武器</para>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool ScoutWeaponDetected()
|
||||
{
|
||||
if (_weaponInTheScoutRange == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _weaponInTheScoutRange.Count > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Get weapons in the recon area</para>
|
||||
/// <para>获取侦察范围内的武器</para>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public WeaponTemplate[]? GetWeaponInScoutArea()
|
||||
{
|
||||
if (_weaponInTheScoutRange == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _weaponInTheScoutRange.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Get the first enemy in range</para>
|
||||
/// <para>获取第一个进入侦察范围的敌人</para>
|
||||
|
@ -308,6 +346,11 @@ public sealed partial class AiCharacter : CharacterTemplate
|
|||
/// <param name="node"></param>
|
||||
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);
|
||||
|
|
|
@ -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
|
|||
/// </summary>
|
||||
public const string Default = "Default";
|
||||
|
||||
/// <summary>
|
||||
/// <para>LookForWeaponProcessor</para>
|
||||
/// <para>查找武器处理器</para>
|
||||
/// </summary>
|
||||
public const string LookForWeaponProcessor = "LookForWeaponProcessor";
|
||||
|
||||
/// <summary>
|
||||
/// <para>PatrolStateProcessor</para>
|
||||
/// <para>巡逻状态处理器</para>
|
||||
|
@ -119,25 +122,6 @@ public static class LogCat
|
|||
private static HashSet<string> 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";
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>Disable log Label</para>
|
||||
/// <para>禁用某个日志标签</para>
|
||||
|
|
|
@ -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<Label>("NameLabel");
|
||||
_loadingLabel = GetNode<Label>("loadingStateLabel");
|
||||
_animationPlayer = GetNode<AnimationPlayer>("AnimationPlayer");
|
||||
_animationPlayer.AnimationFinished += AnimationFinished;
|
||||
//Disable animation in Debug mode.
|
||||
//在Debug模式禁用动画。
|
||||
if (Config.IsDebug())
|
||||
{
|
||||
_loadingLabel.Modulate = Colors.White;
|
||||
_nameLabel.Modulate = Colors.White;
|
||||
AnimationFinished(_startup);
|
||||
}
|
||||
else
|
||||
{
|
||||
_animationPlayer.Play(_startup);
|
||||
_animationPlayer.AnimationFinished += AnimationFinished;
|
||||
}
|
||||
}
|
||||
|
||||
private async void AnimationFinished(StringName name)
|
||||
|
|
|
@ -24,5 +24,7 @@ public class PatrolStateMachine : StateMachineTemplate
|
|||
RegisterProcessor(patrolStateProcessor);
|
||||
var chaseStateProcessor = new ChaseStateProcessor();
|
||||
RegisterProcessor(chaseStateProcessor);
|
||||
var lookForWeaponProcessor = new LookForWeaponProcessor();
|
||||
RegisterProcessor(lookForWeaponProcessor);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using ColdMint.scripts.character;
|
||||
using System.Collections.Generic;
|
||||
using ColdMint.scripts.character;
|
||||
using ColdMint.scripts.debug;
|
||||
using ColdMint.scripts.utils;
|
||||
using ColdMint.scripts.weapon;
|
||||
|
@ -12,32 +13,73 @@ namespace ColdMint.scripts.stateMachine.StateProcessor;
|
|||
/// </summary>
|
||||
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<WeaponTemplate>(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<Node>();
|
||||
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;
|
||||
|
|
|
@ -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; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Whether to guard the origin</para>
|
||||
/// <para>是否需要守护原点</para>
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user