```
feat(gameplay): 添加水晶矿资源产出系统和改进AI卡组管理 - 实现水晶矿占领后的能量资源产出功能,包括manaInterval和manaAmount配置 - 添加敌方AI的能量管理系统,支持通过AddMana方法增加能量 - 实现AI卡组轮转机制,包含手牌管理和抽卡队列功能 - 优化单位AI的目标选择和战斗逻辑,修复目标切换问题 - 水晶矿现在可以按设定间隔为所属阵营提供能量资源 -
This commit is contained in:
1 parent
b185e5768b
commit
06940a849c
21 files changed
+555
-520
No files matched your search
@@ -0,0 +1,130 @@
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// 混沌之门:被占领后按固定间隔从所属阵营卡组随机出兵。
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(CrystalMineCapture))]
|
||||
public class ChaosGateSpawner : MonoBehaviour
|
||||
{
|
||||
[Header("出兵配置")]
|
||||
[Min(1f)] public float spawnInterval = 12f;
|
||||
[Min(0f)] public float spawnRadius = 1.5f;
|
||||
public bool spawnImmediatelyOnCapture = false;
|
||||
|
||||
[Header("蓝方卡组")]
|
||||
[SerializeField] private string[] blueDeckDataNames =
|
||||
{
|
||||
"人类士兵Data", "弓箭手Data", "盾卫Data", "精锐士兵Data",
|
||||
"法师Data", "狂暴狼人Data", "石巨人Data", "弓箭猎人Data"
|
||||
};
|
||||
|
||||
private CrystalMineCapture capture;
|
||||
private UnitTeam unitTeam;
|
||||
private float spawnTimer;
|
||||
private int previousTeamId = 2;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
capture = GetComponent<CrystalMineCapture>();
|
||||
unitTeam = GetComponent<UnitTeam>();
|
||||
spawnTimer = spawnInterval;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (unitTeam == null)
|
||||
{
|
||||
unitTeam = GetComponent<UnitTeam>();
|
||||
if (unitTeam == null) return;
|
||||
}
|
||||
|
||||
int currentTeamId = unitTeam.teamId;
|
||||
if (currentTeamId != previousTeamId)
|
||||
{
|
||||
previousTeamId = currentTeamId;
|
||||
spawnTimer = spawnImmediatelyOnCapture ? 0f : spawnInterval;
|
||||
}
|
||||
|
||||
if (currentTeamId != 0 && currentTeamId != 1)
|
||||
{
|
||||
spawnTimer = spawnInterval;
|
||||
return;
|
||||
}
|
||||
|
||||
spawnTimer -= Time.deltaTime;
|
||||
if (spawnTimer > 0f) return;
|
||||
|
||||
if (TrySpawn(currentTeamId))
|
||||
spawnTimer = spawnInterval;
|
||||
else
|
||||
spawnTimer = 1f;
|
||||
}
|
||||
|
||||
private bool TrySpawn(int teamId)
|
||||
{
|
||||
Vector3 position = transform.position;
|
||||
position.x += Random.Range(-spawnRadius, spawnRadius);
|
||||
position.z += Random.Range(-spawnRadius, spawnRadius);
|
||||
|
||||
if (teamId == 1)
|
||||
{
|
||||
EnemyCastleAI enemyAI = FindObjectOfType<EnemyCastleAI>();
|
||||
return enemyAI != null && enemyAI.TrySpawnFromPortal(position, transform.rotation);
|
||||
}
|
||||
|
||||
CharacterData card = ChooseBlueCard();
|
||||
if (card == null || CastleSpawnManager.Instance == null)
|
||||
return false;
|
||||
|
||||
return SpawnBlueUnit(card, position, transform.rotation);
|
||||
}
|
||||
|
||||
private CharacterData ChooseBlueCard()
|
||||
{
|
||||
CharacterData[] cards = new CharacterData[blueDeckDataNames.Length];
|
||||
int validCount = 0;
|
||||
foreach (string dataName in blueDeckDataNames)
|
||||
{
|
||||
CharacterData data = Resources.Load<CharacterData>("Data/" + dataName);
|
||||
if (data != null && data.unitPrefab != null)
|
||||
cards[validCount++] = data;
|
||||
}
|
||||
|
||||
if (validCount == 0) return null;
|
||||
|
||||
float totalWeight = 0f;
|
||||
for (int i = 0; i < validCount; i++)
|
||||
totalWeight += 1f / Mathf.Max(1, cards[i].manaCost);
|
||||
|
||||
float roll = Random.value * totalWeight;
|
||||
for (int i = 0; i < validCount; i++)
|
||||
{
|
||||
roll -= 1f / Mathf.Max(1, cards[i].manaCost);
|
||||
if (roll <= 0f) return cards[i];
|
||||
}
|
||||
return cards[validCount - 1];
|
||||
}
|
||||
|
||||
private bool SpawnBlueUnit(CharacterData data, Vector3 position, Quaternion rotation)
|
||||
{
|
||||
if (ManaSystem.Instance == null || !ManaSystem.Instance.TryConsumeMana(data.manaCost))
|
||||
return false;
|
||||
|
||||
GameObject unit = Instantiate(data.unitPrefab, position, rotation);
|
||||
UnitTeam team = unit.GetComponent<UnitTeam>();
|
||||
if (team != null)
|
||||
{
|
||||
team.teamId = 0;
|
||||
unit.tag = "Friend";
|
||||
}
|
||||
|
||||
UnitBase unitBase = unit.GetComponent<UnitBase>();
|
||||
if (unitBase != null)
|
||||
{
|
||||
unitBase.InitializeFromPlayerData(data.GetMaxHealth(1), data.GetAttackPower(1), data.GetMoveSpeed(1));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user