Sooo (I said this like 10 times already) I’m making a TD game and I was working on a custom tower attack system that works with my enemy system that assigns each enemy a unique ID so they can be tracked considering they only exist as data on the server.
The tower system worked fine until I noticed that when the first enemy dies all Towers will stop attacking and never start again, even if you place a new tower it still won’t attack the enemies…
local towerModule = {}
towerModule.TowerIndex = {} --Index for all towers
local id = 1
function findNearestTarget(d, towerCframe)
local maxDistance = d
local nearestTarget = nil
for i, target in ipairs(enemymodule.Entities) do
local distance = (target.Position.Position - towerCframe.Position).Magnitude
if distance < maxDistance then
nearestTarget = target
maxDistance = distance
end
--warn(nearestTarget)
end
return nearestTarget
end
function towerModule.Attack(towerT)
local target = findNearestTarget(towerModule.TowerIndex[towerT.ID].Range, towerModule.TowerIndex[towerT.ID].Position)
if target then
animateTowerEvent:FireAllClients(towerModule.TowerIndex[towerT.ID].ID)
target.Health -= towerModule.TowerIndex[towerT.ID].Damage
warn(target.Enemy.." has "..target.Health.." health left")
end
task.wait(towerModule.TowerIndex[towerT.ID].Reload)
towerModule.Attack(towerT)
end
function towerModule.Create(Player, tower, cframe)
local towerTable = { --// Change so it works for each tower
["Tower"] = tower,
["ID"] = id,
["Position"] = cframe,
["Damage"] = 1,
["Reload"] = 0.5,
["Range"] = 25,
}
towerModule.TowerIndex[id] = towerTable
id += 1
coroutine.wrap(towerModule.Attack)(towerTable)
end
createTowerEvent.OnServerEvent:Connect(towerModule.Create)
return towerModule
This is the entire tower handling module. It’s pretty self explanatory I think.
It appears you iterate the Entities table from the enemymodule, is it possible that this module is responsible for removing values in this table? As I cannot see any code in the module provided here that is responsible for that
Yes, the enemy module removes data from the enemy table when its assigned enemy dies or enters the base. But I think I wrote it in the tower module like this that they target other enemies too I think. (Considering that the old enemy they were originally targeting gets set to nil)
The parr that removes the table for the enemy that died / entered the base. (t being an alpha value to calculate movement)
if enemyTable.Health <= 0 then
loop:Disconnect()
enemyTable.ReferenceObject:Destroy()
killEnemyEvent:FireAllClients(spawnEnemyModule.Entities[enemyTable.ID].ID)
spawnEnemyModule.Entities[enemyTable.ID] = nil
end
if t >= 1 then -- remove enemyReferenceObject and loop once last waypoint is reached
enemyTable.ReferenceObject:Destroy()
--spawnEnemyModule.Entities[id] = nil
loop:Disconnect()
workspace:SetAttribute("health", workspace:GetAttribute("health") - enemyTable.Health)
spawnEnemyModule.Entities[enemyTable.ID] = nil
updateBaseHealthVisuals:FireAllClients()
if workspace:GetAttribute("health") <= 0 then
spawnEnemyModule.clearEnemies()
gameOverBool.Value = true
end
end
A possible reason for the issue might be that the loop that damages and target enemies only runs until the first enemy dies. It literally never runs ever after for some reason