using System; using ColdMint.scripts.camp; using ColdMint.scripts.character; using ColdMint.scripts.damage; using ColdMint.scripts.debug; using ColdMint.scripts.inventory; using Godot; namespace ColdMint.scripts.pickable; /// /// Templates for all fallen objects /// 所有掉落物的模板 /// public partial class PickAbleTemplate : RigidBody2D, IItem { [Export] public virtual string Id { get; set; } = "ID"; [Export] protected Texture2D? UniqueIcon { get; set; } public Texture2D Icon => UniqueIcon ?? ItemTypeManager.DefaultIconOf(Id); [Export] protected string? UniqueName { get; set; } public new string Name => UniqueName ?? ItemTypeManager.DefaultNameOf(Id); [Export] protected string? UniqueDescription { get; set; } public virtual bool CanPutInPack => true; /// /// Owner /// 主人 /// public new Node2D? Owner { get; set; } /// /// Enabled contact injury /// 启用接触伤害 /// public bool EnableContactInjury; [Export] private int _minContactInjury = 1; [Export] private int _maxContactInjury = 2; public string? Description => UniqueDescription ?? ItemTypeManager.DefaultDescriptionOf(Id); public int Quantity { get; set; } = 1; /// /// The number of tile maps that come into contact with this item /// 与此物品接触的瓦片地图数量 /// private int _tileMapNumber; /// /// This area represents the collision range of the weapon, and when other nodes enter this area, they will deal damage. /// 这个区域表示武器的碰撞范围,当其他节点进入此区域时,会造成伤害。 /// private Area2D? _damageArea2D; /// /// Whether the item is currently picked up /// 当前物品是否被捡起了 /// public bool Picked { get; set; } public int MaxQuantity { get; set; } public virtual void Use(Node2D? owner, Vector2 targetGlobalPosition) { } public override void _Ready() { _damageArea2D = GetNode("DamageArea2D"); _damageArea2D.BodyEntered += OnBodyEnter; _damageArea2D.BodyExited += OnBodyExited; } private void OnBodyExited(Node node) { if (Picked) { return; } //If it leaves the ground or walls. //如果离开了地面或墙壁。 if (node is TileMapLayer) { _tileMapNumber--; if (_tileMapNumber == 0) { //No longer in contact with any shingles can cause injury //不再与任何瓦片接触后,可以造成伤害 EnableContactInjury = true; SetCollisionMaskValue(Config.LayerNumber.Player, false); } } } /// /// Use objects to smash enemies /// 使用物品砸敌人 /// /// private void OnBodyEnter(Node node) { if (Picked) { return; } if (node is TileMapLayer) { _tileMapNumber++; EnableContactInjury = false; //Items can be pushed by the player when they are on the ground //当物品在地面上时,可被玩家推动 SetCollisionMaskValue(Config.LayerNumber.Player, true); } else if (node is CharacterTemplate characterTemplate) { if (!EnableContactInjury) { LogCat.LogWarning("contact_damage_disabled_during_collision"); return; } if (Owner == null) { LogCat.LogWarning("item_has_no_owner"); return; } if (Owner is not CharacterTemplate ownerCharacterTemplate) { LogCat.LogWarning("owner_of_the_item_is_not_character"); return; } //Determine if your side can cause damage //判断所属的阵营是否可以造成伤害 var canCauseHarm = CampManager.CanCauseHarm(CampManager.GetCamp(ownerCharacterTemplate.CampId), CampManager.GetCamp(characterTemplate.CampId)); if (!canCauseHarm) { LogCat.Log("no_damage_between_camps"); return; } //If allowed to cause harm //如果允许造成伤害 var damage = new Damage { MaxDamage = Math.Abs(_maxContactInjury), MinDamage = Math.Abs(_minContactInjury), Attacker = ownerCharacterTemplate }; damage.CreateDamage(); damage.MoveLeft = LinearVelocity.X < 0; damage.Type = Config.DamageType.Physical; characterTemplate.Damage(damage); //Reduce speed after hitting enemies. //击中敌人后减少速度。 LinearVelocity *= 1 - Config.ThrownItemsHitEnemiesReduceSpeedByPercentage; } } /// /// Flip item /// 翻转物品 /// /// public void Flip(bool facingLeft) { } public virtual void Destroy() { QueueFree(); } public bool CanStackWith(IItem item) => false; }