add recharge
This commit is contained in:
@@ -11,13 +11,59 @@ Unit::Unit(int uId, int pId, const UnitConfig &cfg, int startX, int startY, floa
|
||||
health((float)cfg.health), maxHealth((float)cfg.health),
|
||||
buildCharges(cfg.buildCharges),
|
||||
state(UnitState::Idle), pathIndex(0), moveProgress(0.0f),
|
||||
targetTileX(startX), targetTileY(startY), attackFlashTimer(0.0f),
|
||||
targetTileX(startX), targetTileY(startY), attackFlashTimer(0.0f), rechargeTimer(0.0f),
|
||||
buildProgress(0.0f), buildDuration(0.0f), buildingImprovementId("")
|
||||
{
|
||||
QVector2D w = Pathfinder::hexToWorld(startX, startY);
|
||||
worldPos = QVector3D(w.x(), w.y(), groundZ);
|
||||
}
|
||||
|
||||
bool Unit::isRecharging() const {
|
||||
// Only military units have recharge/cooldown
|
||||
if (!config.canAttack()) return false;
|
||||
return rechargeTimer > 0.0f;
|
||||
}
|
||||
|
||||
bool Unit::canAttack(const Unit &other) const
|
||||
{
|
||||
if (other.playerId == playerId) return false;
|
||||
if (other.isDead() || isDead()) return false;
|
||||
if (!config.canAttack()) return false;
|
||||
|
||||
// Check if unit is currently on cooldown/recharge
|
||||
if (isRecharging()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int dist = Pathfinder::hexDistance(tileX, tileY, other.tileX, other.tileY);
|
||||
return dist <= config.attackRange;
|
||||
}
|
||||
|
||||
void Unit::performAttack(Unit &target)
|
||||
{
|
||||
if (!canAttack(target)) return;
|
||||
|
||||
attackFlashTimer = config.attackFlashDuration / 1000.0f; // Convert ms to seconds
|
||||
rechargeTimer = config.rechargeTime / 1000.0f; // Convert ms to seconds
|
||||
|
||||
target.takeDamage((float)config.attackDamage);
|
||||
|
||||
// Retaliation if target is adjacent melee military unit
|
||||
if (!target.isDead() && target.config.isMilitary() && !config.isRanged()) {
|
||||
int dist = Pathfinder::hexDistance(tileX, tileY, target.tileX, target.tileY);
|
||||
if (dist <= target.config.attackRange) {
|
||||
takeDamage(target.config.attackDamage * 0.5f); // 50% counterattack damage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::takeDamage(float damage)
|
||||
{
|
||||
health = std::max(0.0f, health - damage);
|
||||
attackFlashTimer = 0.4f;
|
||||
rechargeTimer = config.rechargeTime / 1000.0f; // Reset recharge on taking damage
|
||||
}
|
||||
|
||||
float Unit::getTerrainHeight(float worldX, float worldY, Matrix2D<TerrainPoint> *mapPoints, int numPoints05)
|
||||
{
|
||||
if (!mapPoints || numPoints05 <= 0) return 1.0f;
|
||||
@@ -195,10 +241,16 @@ void Unit::cancelBuilding()
|
||||
void Unit::update(float deltaTime, float tickDuration, float simSpeedMultiplier,
|
||||
Matrix2D<TerrainPoint> *mapPoints, int numPoints05)
|
||||
{
|
||||
// Update attack flash timer (visual feedback)
|
||||
if (attackFlashTimer > 0.0f) {
|
||||
attackFlashTimer = std::max(0.0f, attackFlashTimer - deltaTime);
|
||||
}
|
||||
|
||||
// Update recharge timer (cooldown between attacks)
|
||||
if (rechargeTimer > 0.0f) {
|
||||
rechargeTimer = std::max(0.0f, rechargeTimer - deltaTime * simSpeedMultiplier);
|
||||
}
|
||||
|
||||
if (state == UnitState::Building) {
|
||||
if (buildDuration > 0.001f) {
|
||||
buildProgress += (deltaTime * simSpeedMultiplier) / buildDuration;
|
||||
@@ -259,36 +311,4 @@ void Unit::update(float deltaTime, float tickDuration, float simSpeedMultiplier,
|
||||
float curZ = getTerrainHeight(curX, curY, mapPoints, numPoints05);
|
||||
|
||||
worldPos = QVector3D(curX, curY, curZ);
|
||||
}
|
||||
|
||||
bool Unit::canAttack(const Unit &other) const
|
||||
{
|
||||
if (other.playerId == playerId) return false;
|
||||
if (other.isDead() || isDead()) return false;
|
||||
if (!config.canAttack()) return false;
|
||||
|
||||
int dist = Pathfinder::hexDistance(tileX, tileY, other.tileX, other.tileY);
|
||||
return dist <= config.attackRange;
|
||||
}
|
||||
|
||||
void Unit::performAttack(Unit &target)
|
||||
{
|
||||
if (!canAttack(target)) return;
|
||||
|
||||
attackFlashTimer = 0.5f; // Visual flash duration
|
||||
target.takeDamage((float)config.attackDamage);
|
||||
|
||||
// Retaliation if target is adjacent melee military unit
|
||||
if (!target.isDead() && target.config.isMilitary() && !config.isRanged()) {
|
||||
int dist = Pathfinder::hexDistance(tileX, tileY, target.tileX, target.tileY);
|
||||
if (dist <= target.config.attackRange) {
|
||||
takeDamage(target.config.attackDamage * 0.5f); // 50% counterattack damage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::takeDamage(float damage)
|
||||
{
|
||||
health = std::max(0.0f, health - damage);
|
||||
attackFlashTimer = 0.4f;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user