2.5d test

This commit is contained in:
2026-09-27 21:08:05 +09:00
parent 84dd12414a
commit abd2da2057
201 changed files with 24297 additions and 295 deletions
@@ -4,6 +4,7 @@ using System.Collections.Generic;
using BumpCombat.Combat;
using BumpCombat.Constants;
using BumpCombat.Core;
using BumpCombat.Defense;
using BumpCombat.Player;
using BumpCombat.Progression;
using BumpCombat.Stage;
@@ -70,6 +71,7 @@ namespace BumpCombat.Enemies
private static readonly int HurtParameter = Animator.StringToHash("Hurt");
private static readonly int DeathState = Animator.StringToHash("Base Layer.Death");
private static readonly Collider2D[] SeparationBuffer = new Collider2D[16];
private static readonly RaycastHit2D[] RouteCollisionBuffer = new RaycastHit2D[16];
private static readonly Dictionary<int, HashSet<EnemyController>> EncounterGroups = new();
private static Sprite launchWhiteSprite;
private static int nextSpawnLifetimeIdentity;
@@ -94,6 +96,7 @@ namespace BumpCombat.Enemies
private ActiveArtifactController activeArtifactController;
private Transform player;
private PlayerHealth playerHealth;
private DefenseSummonUnit defenseCombatTarget;
private Vector2 lockedDirection;
private Vector2 capturedTarget;
private Vector2 knockbackVelocity;
@@ -112,6 +115,7 @@ namespace BumpCombat.Enemies
private float vulnerabilityIncrease;
private bool ownsAttackToken;
private bool registeredAlive;
private bool suppressTowerTestDummyRewards;
private float nextSeparationRefreshTime;
private Vector2 cachedSeparation;
private RunTimedEvent? runEventRole;
@@ -259,6 +263,7 @@ namespace BumpCombat.Enemies
public EnemyController SummonOwner => summonOwner;
public bool IsProtectedFromCleanup => runEventRole.HasValue || phaseSummon;
public bool HasContactDamage => definition != null && definition.HasContactDamage;
public DefenseSummonUnit DefenseCombatTarget => defenseCombatTarget != null && defenseCombatTarget.IsOperational ? defenseCombatTarget : null;
public bool IsFlying => definition != null && definition.IsFlying;
public Collider2D BodyCollider => bodyCollider != null ? bodyCollider : (bodyCollider = GetComponent<Collider2D>());
public bool HasDetectedPlayer => hasDetectedPlayer;
@@ -405,6 +410,16 @@ namespace BumpCombat.Enemies
}
#endif
public void ConfigureTowerTestDummy()
{
suppressTowerTestDummyRewards = true;
if (body != null)
{
body.linearVelocity = Vector2.zero;
body.constraints = RigidbodyConstraints2D.FreezeAll;
}
}
public void ConfigureEncounterGroup(int groupId, Vector2 anchor)
{
UnregisterEncounterGroup();
@@ -1588,9 +1603,29 @@ namespace BumpCombat.Enemies
return false;
}
Vector2 destination = ClampEnemyPosition(position);
Vector2 delta = destination - body.position;
if (DefensePrototypeController.Instance != null && DefensePrototypeController.Instance.IsActive
&& delta.sqrMagnitude > 0.000001f)
{
ContactFilter2D filter = ContactFilter2D.noFilter;
filter.useTriggers = false;
int hitCount = bodyCollider.Cast(delta.normalized, filter,
RouteCollisionBuffer, delta.magnitude);
for (int i = 0; i < hitCount; i++)
{
Collider2D hit = RouteCollisionBuffer[i].collider;
DefenseSummonUnit summon = hit != null
? hit.GetComponentInParent<DefenseSummonUnit>() : null;
if (summon == null || !summon.IsOperational) continue;
if (RouteCollisionBuffer[i].distance <= 0.001f
&& Vector2.Dot(delta.normalized, body.position - (Vector2)hit.bounds.center) >= 0f) continue;
return false;
}
}
knockbackVelocity = Vector2.zero;
body.linearVelocity = Vector2.zero;
body.position = ClampEnemyPosition(position);
body.position = destination;
transform.position = body.position;
return true;
}
@@ -1793,7 +1828,7 @@ namespace BumpCombat.Enemies
SetFacing(direction);
float repeatWarning = WarningDuration
* runEventTuning.RepeatWarningDurationMultiplier;
BeginAttackWarning(direction, player.position, repeatWarning);
BeginAttackWarning(direction, attackTarget, repeatWarning);
}
private void BeginAttackWarning(
@@ -1953,7 +1988,7 @@ namespace BumpCombat.Enemies
CurrentAttackPatternIndex);
completedAttacksInSequence = 0;
remainingBackHitsToInterrupt = BackHitsToInterrupt;
BeginAttackWarning(direction, player.position, WarningDuration);
BeginAttackWarning(direction, attackTarget, WarningDuration);
return;
}
@@ -2181,6 +2216,11 @@ namespace BumpCombat.Enemies
private Vector2 GetAttackTargetPosition()
{
DefenseSummonUnit summon = DefenseCombatTarget;
if (summon != null && summon.BodyCollider != null)
{
return summon.BodyCollider.bounds.center;
}
if (UsesHorizontalRootAttackVisual && playerHealth != null)
{
Collider2D targetCollider =
@@ -2201,20 +2241,18 @@ namespace BumpCombat.Enemies
return true;
}
float targetMinY = player.position.y;
float targetMaxY = player.position.y;
if (playerHealth != null)
Collider2D targetCollider = DefenseCombatTarget != null
? DefenseCombatTarget.BodyCollider
: playerHealth != null ? playerHealth.GetComponent<Collider2D>() : null;
float targetMinY = DefenseCombatTarget != null
? DefenseCombatTarget.transform.position.y : player.position.y;
float targetMaxY = targetMinY;
if (targetCollider != null)
{
Collider2D targetCollider =
playerHealth.GetComponent<Collider2D>();
if (targetCollider != null)
{
Bounds targetBounds = targetCollider.bounds;
targetMinY = targetBounds.min.y;
targetMaxY = targetBounds.max.y;
}
Bounds targetBounds = targetCollider.bounds;
targetMinY = targetBounds.min.y;
targetMaxY = targetBounds.max.y;
}
// Match the same world-space horizontal attack band used by
// EnemyAttack's OverlapBox. Collider bounds include the player
// foot offset, so alignment does not infer the body from its
@@ -2318,6 +2356,10 @@ namespace BumpCombat.Enemies
|| (state == EnemyState.Warning && attackAnimationStarted));
}
public void SetDefenseCombatTarget(DefenseSummonUnit target)
{
defenseCombatTarget = target != null && target.IsOperational ? target : null;
}
public void Alert()
{
MarkPlayerDetected(false);
@@ -2390,7 +2432,7 @@ namespace BumpCombat.Enemies
private bool RefreshChaseAwareness()
{
if (IsEventEnemy)
if (IsEventEnemy || DefenseCombatTarget != null)
{
return true;
}
@@ -2930,16 +2972,19 @@ namespace BumpCombat.Enemies
animator.Play(DeathState, 0, 0f);
}
if (experienceOrbPrefab != null)
if (!suppressTowerTestDummyRewards)
{
ExperienceOrb orb = Instantiate(experienceOrbPrefab, transform.position, Quaternion.identity);
orb.Initialize(
experienceValueOverride >= 0
? experienceValueOverride
: definition.ExperienceValue);
}
if (experienceOrbPrefab != null)
{
ExperienceOrb orb = Instantiate(experienceOrbPrefab, transform.position, Quaternion.identity);
orb.Initialize(
experienceValueOverride >= 0
? experienceValueOverride
: definition.ExperienceValue);
}
CombatEvents.RaiseEnemyDied(gameObject);
CombatEvents.RaiseEnemyDied(gameObject);
}
OnDied?.Invoke(this);
Destroy(
gameObject,