Fixed an issue where items on the ground still carry collision damage.
解决物品在地面上,仍然带有碰撞伤害的问题。
This commit is contained in:
parent
63a56cbb2c
commit
7805a63174
|
@ -22,11 +22,11 @@ metadata/ID = "StaffOfTheUndead"
|
|||
metadata/MaxStackQuantity = 1
|
||||
metadata/Description = "staff_of_the_undead_desc"
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
[node name="DamageArea2D" type="Area2D" parent="."]
|
||||
collision_layer = 8
|
||||
collision_mask = 68
|
||||
collision_mask = 71
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="DamageArea2D"]
|
||||
position = Vector2(25.5, 0.5)
|
||||
shape = SubResource("RectangleShape2D_obcq2")
|
||||
|
||||
|
@ -40,8 +40,3 @@ shape = SubResource("RectangleShape2D_14m1g")
|
|||
|
||||
[node name="Marker2D" type="Marker2D" parent="."]
|
||||
position = Vector2(65, 0)
|
||||
|
||||
[node name="RayCast2D" type="RayCast2D" parent="."]
|
||||
position = Vector2(26, -8)
|
||||
target_position = Vector2(0, 20)
|
||||
collision_mask = 34
|
||||
|
|
|
@ -85,6 +85,12 @@ public static class Config
|
|||
public const string Aborigines = "Aborigines";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>The percentage of speed reduced after a thrown item hits an enemy</para>
|
||||
/// <para>抛出的物品击中敌人后减少的速度百分比</para>
|
||||
/// </summary>
|
||||
public const float ThrownItemsHitEnemiesReduceSpeedByPercentage = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// <para>How much blood does a heart represent</para>
|
||||
/// <para>一颗心代表多少血量</para>
|
||||
|
|
|
@ -318,6 +318,7 @@ public partial class CharacterTemplate : CharacterBody2D
|
|||
if (pickAbleItem is WeaponTemplate weaponTemplate)
|
||||
{
|
||||
weaponTemplate.Owner = this;
|
||||
weaponTemplate.Picked = true;
|
||||
weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Platform, false);
|
||||
weaponTemplate.SetCollisionMaskValue(Config.LayerNumber.Ground, false);
|
||||
weaponTemplate.EnableContactInjury = false;
|
||||
|
@ -479,7 +480,7 @@ public partial class CharacterTemplate : CharacterBody2D
|
|||
|
||||
|
||||
var finalGlobalPosition = GlobalPosition;
|
||||
CallDeferred("GenerateLootObjects", this,lootDataArray, finalGlobalPosition);
|
||||
CallDeferred("GenerateLootObjects", this, lootDataArray, finalGlobalPosition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -669,6 +670,7 @@ public partial class CharacterTemplate : CharacterBody2D
|
|||
return;
|
||||
}
|
||||
|
||||
weaponTemplate.Picked = false;
|
||||
CallDeferred("WeaponTemplateReparent", weaponTemplate);
|
||||
var timer = new Timer();
|
||||
weaponTemplate.AddChild(timer);
|
||||
|
@ -770,5 +772,15 @@ public partial class CharacterTemplate : CharacterBody2D
|
|||
|
||||
protected virtual void HookPhysicsProcess(ref Vector2 velocity, double delta)
|
||||
{
|
||||
//The cost of applying force in the X direction.
|
||||
//对X方向施加力消耗。
|
||||
if ((int)velocity.X == 0)
|
||||
{
|
||||
velocity.X = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
velocity.X *= 0.95f;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using ColdMint.scripts.camp;
|
||||
using ColdMint.scripts.character;
|
||||
using ColdMint.scripts.damage;
|
||||
using ColdMint.scripts.weapon;
|
||||
using Godot;
|
||||
|
||||
namespace ColdMint.scripts.projectile;
|
||||
|
@ -105,8 +106,15 @@ public partial class ProjectileTemplate : CharacterBody2D
|
|||
|
||||
if (target is TileMap)
|
||||
{
|
||||
//When we hit the tile, we return true in order to place the bullet through the tile.
|
||||
//撞击到瓦片时,我们返回true,是为了放置子弹穿透瓦片。
|
||||
//When we hit the tile, we return true to prevent the bullet from penetrating the tile.
|
||||
//撞击到瓦片时,我们返回true,是为了防止子弹穿透瓦片。
|
||||
return true;
|
||||
}
|
||||
|
||||
if (target is WeaponTemplate)
|
||||
{
|
||||
//Bullets are allowed to strike objects.
|
||||
//允许子弹撞击物品。
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -130,39 +138,56 @@ public partial class ProjectileTemplate : CharacterBody2D
|
|||
/// <param name="target"></param>
|
||||
private void DoDamage(Node2D? owner, Node2D target)
|
||||
{
|
||||
if (target is not CharacterTemplate characterTemplate)
|
||||
if (target is CharacterTemplate characterTemplate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Allow damage to be caused
|
||||
//允许造成伤害
|
||||
var damage = new Damage
|
||||
{
|
||||
Attacker = owner,
|
||||
MaxDamage = MaxDamage,
|
||||
MinDamage = MinDamage
|
||||
};
|
||||
damage.CreateDamage();
|
||||
damage.MoveLeft = Velocity.X < 0;
|
||||
damage.Type = DamageType;
|
||||
characterTemplate.Damage(damage);
|
||||
if (KnockbackForce != Vector2.Zero)
|
||||
{
|
||||
//If we set the attack force, then apply the force to the object
|
||||
//如果我们设置了攻退力,那么将力应用到对象上
|
||||
var force = new Vector2();
|
||||
var forceX = Math.Abs(KnockbackForce.X);
|
||||
if (Velocity.X < 0)
|
||||
//Allow damage to be caused
|
||||
//允许造成伤害
|
||||
var damage = new Damage
|
||||
{
|
||||
//Beat back to port
|
||||
//向左击退
|
||||
forceX = -forceX;
|
||||
}
|
||||
Attacker = owner,
|
||||
MaxDamage = MaxDamage,
|
||||
MinDamage = MinDamage
|
||||
};
|
||||
damage.CreateDamage();
|
||||
damage.MoveLeft = Velocity.X < 0;
|
||||
damage.Type = DamageType;
|
||||
characterTemplate.Damage(damage);
|
||||
if (KnockbackForce != Vector2.Zero)
|
||||
{
|
||||
//If we set the attack force, then apply the force to the object
|
||||
//如果我们设置了攻退力,那么将力应用到对象上
|
||||
var force = new Vector2();
|
||||
var forceX = Math.Abs(KnockbackForce.X);
|
||||
if (Velocity.X < 0)
|
||||
{
|
||||
//Beat back to port
|
||||
//向左击退
|
||||
forceX = -forceX;
|
||||
}
|
||||
|
||||
force.X = forceX * Config.CellSize;
|
||||
force.Y = KnockbackForce.Y * Config.CellSize;
|
||||
characterTemplate.AddForce(force);
|
||||
force.X = forceX * Config.CellSize;
|
||||
force.Y = KnockbackForce.Y * Config.CellSize;
|
||||
characterTemplate.AddForce(force);
|
||||
}
|
||||
}else if (target is WeaponTemplate weaponTemplate)
|
||||
{
|
||||
if (KnockbackForce != Vector2.Zero)
|
||||
{
|
||||
//If we set the attack force, then apply the force to the object
|
||||
//如果我们设置了攻退力,那么将力应用到对象上
|
||||
var force = new Vector2();
|
||||
var forceX = Math.Abs(KnockbackForce.X);
|
||||
if (Velocity.X < 0)
|
||||
{
|
||||
//Beat back to port
|
||||
//向左击退
|
||||
forceX = -forceX;
|
||||
}
|
||||
|
||||
force.X = forceX * Config.CellSize;
|
||||
force.Y = KnockbackForce.Y * Config.CellSize;
|
||||
weaponTemplate.ApplyImpulse(force);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using ColdMint.scripts.camp;
|
||||
using ColdMint.scripts.character;
|
||||
using ColdMint.scripts.damage;
|
||||
using ColdMint.scripts.debug;
|
||||
using ColdMint.scripts.inventory;
|
||||
using Godot;
|
||||
|
||||
|
@ -24,6 +25,13 @@ public partial class WeaponTemplate : RigidBody2D, IItem
|
|||
public Action<IItem>? OnUse { get; set; }
|
||||
public Func<IItem, Node>? OnInstantiation { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>Whether the weapon is currently picked up</para>
|
||||
/// <para>当前武器是否被捡起了</para>
|
||||
/// </summary>
|
||||
public bool Picked { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// <para>Owner</para>
|
||||
/// <para>主人</para>
|
||||
|
@ -63,16 +71,20 @@ public partial class WeaponTemplate : RigidBody2D, IItem
|
|||
/// <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? _damageArea2D;
|
||||
|
||||
protected RayCast2D? RayCast2D;
|
||||
/// <summary>
|
||||
/// <para>The number of tile maps in contact with this weapon</para>
|
||||
/// <para>与此武器接触的瓦片地图数量</para>
|
||||
/// </summary>
|
||||
private int _tileMapNumber;
|
||||
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
RayCast2D = GetNode<RayCast2D>("RayCast2D");
|
||||
_area2D = GetNode<Area2D>("Area2D");
|
||||
_area2D.BodyEntered += OnBodyEnter;
|
||||
_damageArea2D = GetNode<Area2D>("DamageArea2D");
|
||||
_damageArea2D.BodyEntered += OnBodyEnter;
|
||||
_damageArea2D.BodyExited += OnBodyExited;
|
||||
Id = GetMeta("ID", "1").AsString();
|
||||
Quantity = GetMeta("Quantity", "1").AsInt32();
|
||||
MaxStackQuantity = GetMeta("MaxStackQuantity", Config.MaxStackQuantity).AsInt32();
|
||||
|
@ -85,6 +97,27 @@ public partial class WeaponTemplate : RigidBody2D, IItem
|
|||
_recoil = GetMeta("Recoil", Vector2.Zero).AsVector2();
|
||||
}
|
||||
|
||||
private void OnBodyExited(Node node)
|
||||
{
|
||||
if (Picked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//If it leaves the ground or walls.
|
||||
//如果离开了地面或墙壁。
|
||||
if (node is TileMap tileMap)
|
||||
{
|
||||
_tileMapNumber--;
|
||||
if (_tileMapNumber == 0)
|
||||
{
|
||||
//No longer in contact with any shingles can cause injury
|
||||
//不再与任何瓦片接触后,可以造成伤害
|
||||
EnableContactInjury = true;
|
||||
SetCollisionMaskValue(Config.LayerNumber.Player, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Use weapons against the enemy</para>
|
||||
|
@ -93,50 +126,57 @@ public partial class WeaponTemplate : RigidBody2D, IItem
|
|||
/// <param name="node"></param>
|
||||
private void OnBodyEnter(Node node)
|
||||
{
|
||||
if (!EnableContactInjury)
|
||||
if (Picked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (Owner == null)
|
||||
if (node is TileMap tileMap)
|
||||
{
|
||||
return;
|
||||
_tileMapNumber++;
|
||||
EnableContactInjury = false;
|
||||
//Items can be pushed by the player when they are on the ground
|
||||
//当物品在地面上时,可被玩家推动
|
||||
SetCollisionMaskValue(Config.LayerNumber.Player, true);
|
||||
}
|
||||
|
||||
if (Owner is not CharacterTemplate ownerCharacterTemplate)
|
||||
else if (node is CharacterTemplate characterTemplate)
|
||||
{
|
||||
return;
|
||||
if (!EnableContactInjury)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Owner is not CharacterTemplate ownerCharacterTemplate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Determine if your side can cause damage
|
||||
//判断所属的阵营是否可以造成伤害
|
||||
var canCauseHarm = CampManager.CanCauseHarm(CampManager.GetCamp(ownerCharacterTemplate.CampId),
|
||||
CampManager.GetCamp(characterTemplate.CampId));
|
||||
if (!canCauseHarm)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (node is not CharacterTemplate characterTemplate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Determine if your side can cause damage
|
||||
//判断所属的阵营是否可以造成伤害
|
||||
var canCauseHarm = CampManager.CanCauseHarm(CampManager.GetCamp(ownerCharacterTemplate.CampId),
|
||||
CampManager.GetCamp(characterTemplate.CampId));
|
||||
if (!canCauseHarm)
|
||||
{
|
||||
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);
|
||||
//Can only cause one collision damage.
|
||||
//仅能造成一次碰撞伤害。
|
||||
EnableContactInjury = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -147,27 +187,6 @@ public partial class WeaponTemplate : RigidBody2D, IItem
|
|||
{
|
||||
}
|
||||
|
||||
public override void _PhysicsProcess(double delta)
|
||||
{
|
||||
base._PhysicsProcess(delta);
|
||||
if (RayCast2D != null)
|
||||
{
|
||||
if (RayCast2D.IsColliding())
|
||||
{
|
||||
//If the weapon hits the ground, we disable physical damage.
|
||||
//如果武器落到地面了,我们禁用物理伤害。
|
||||
EnableContactInjury = false;
|
||||
//Items can be pushed by the player when they are on the ground
|
||||
//当物品在地面上时,可被玩家推动
|
||||
SetCollisionMaskValue(Config.LayerNumber.Player, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetCollisionMaskValue(Config.LayerNumber.Player, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <para>Discharge of the weapon</para>
|
||||
|
|
Loading…
Reference in New Issue
Block a user