eep sorry
i should probably move this to code review but i might aswell just reply
i’ll just post the scripts that are responsible for the core game:
the script that spawns enemies in the blue box (which is seen for the entirety of that video)
local enemyStats = require(game:GetService("ServerScriptService"):WaitForChild("Enemies").EnemyStats)
local difficulty = game:GetService("ServerScriptService"):WaitForChild("Phases"):WaitForChild("Waves").Difficulty
local waveNumber = game:GetService("ServerScriptService"):WaitForChild("Phases"):WaitForChild("Waves").Wave
local spawnCap = game:GetService("ServerScriptService"):WaitForChild("Phases"):WaitForChild("Waves").SpawnCap
local spawnParts = workspace:WaitForChild("SpawnParts")
local SS = game:GetService("ServerStorage")
local meleeEnemies = {
[SS.Enemies.WaveEnemies.Shambler] = 100
}
local rangedEnemies = { -- UNUSED FOR NOW
}
function RNG(enemy)
local totalChance = 0
for _,chance in enemy do
totalChance += chance
end
local rng = math.random(1, totalChance)
for option,chance in enemy do
rng -= chance
if rng <= 0 then return option end
end
end
local wave = {}
-- // SPAWNING ENEMIES FUNCTION
local totalEnemies = 0
function wave.SpawnEnemies()
totalEnemies = 0
workspace.Enemies:ClearAllChildren()
if difficulty.Value >= 5 and waveNumber.Value >= 5 then
-- // SPAWN RANGED AND MELEE ENEMIES
end
for _,part in spawnParts:GetChildren() do
if part.Name == "WaveSpawn" then
while totalEnemies < spawnCap.Value do
local size = part.Size
local position = part.Position
local halfSize = size * 0.5
local randomX = math.random(-halfSize.X, halfSize.X)
local randomZ = math.random(-halfSize.Z, halfSize.Z)
local randomPosition = position + Vector3.new(randomX, 0, randomZ)
local enemy = RNG(meleeEnemies)
local enemyClone = enemy:Clone()
enemyClone.Parent = workspace.Enemies
enemyClone.HumanoidRootPart.CFrame = CFrame.new(randomPosition)
enemyClone.DetectionPart.Size = Vector3.new(1000,250,1000)
local isWaveEnemy = Instance.new("BoolValue")
isWaveEnemy.Name = "IsWaveEnemy"
isWaveEnemy.Value = true
isWaveEnemy.Parent = enemyClone
totalEnemies += 1
print("Spawned enemy, total enemies: " .. totalEnemies)
task.wait()
end
return totalEnemies
end
end
end
-- // REDUCING ENEMY COUNT FUNCTION
function wave.ReduceEnemyCount(storm, stormStart, stormMoving, scavenging)
local enemyCount = workspace.Enemies
if #enemyCount:GetChildren() > 0 then
totalEnemies = math.max(0, totalEnemies - 1)
print("Enemies remaining: " .. totalEnemies)
else
print("The wave is ending...")
if waveNumber.Value <= 3 then
spawnCap.Value += 3
else
if difficulty.Value > 12 then -- this is a total cluster of code and i wish i could've done this differently
spawnCap.Value *= 2
else
spawnCap.Value += 5
end
end
task.wait(3)
waveNumber.Value += 1
difficulty.Value += math.random(1,3)
print("Current wave: " .. waveNumber.Value)
print("Current difficulty: " .. difficulty.Value)
print("Current spawncap: " .. spawnCap.Value)
storm.CFrame = stormStart.CFrame
stormMoving.Value = false
scavenging.Value = true
end
end
-- // DESTROY LOOTABLES FUNCTION
function wave.DestroyLootables()
for _,lootable in workspace.SpawnParts:GetChildren() do
if lootable.Name == "Locker" or lootable.Name == "Crate" then
lootable:Destroy()
end
end
end
return wave
the script that handles spawning lockers and stuff (scavenging)
local SS = game:GetService("ServerStorage")
local openables = SS:WaitForChild("Openables")
local spawnParts = workspace:WaitForChild("SpawnParts")
local enemies = SS:WaitForChild("Enemies"):WaitForChild("ScavengingEnemies")
local scavenging = {}
-- // OPENABLE CHANCES
local lockerChances = {
[openables.Locker] = 77,
[openables.Nothing] = 23
}
local crateChances = {
[openables.Crate] = 50,
[openables.Nothing] = 50
}
-- // AMMO CHANCES
local ammoChances = { -- this is unused for now, ignore
Light = 20,
Medium = 20,
Heavy = 20,
Sniper = 20,
Energy = 20
}
-- // ENEMY CHANCES
local enemyChances = {
[enemies.Shambler] = 100
}
-- // RNG FUNCTION
function RNG(loot)
local totalChance = 0
for _,chance in loot do
totalChance += chance
end
local rng = math.random(1, totalChance)
for option,chance in loot do
rng -= chance
if rng <= 0 then return option end
end
end
-- // FUNCTION RESPONSIBLE FOR SPAWNING OPENABLES
function scavenging.Lootables()
for _,part in spawnParts:GetChildren() do
if RNG(lockerChances) == openables.Locker then
if part.Name == "LockerSpawn" then
local locker = openables.Locker:Clone()
locker.Parent = spawnParts
locker:SetPrimaryPartCFrame(part.CFrame)
end
end
if RNG(crateChances) == openables.Crate then
if part.Name == "CrateSpawn" then
local crate = openables.Crate:Clone()
crate.Parent = spawnParts
crate:SetPrimaryPartCFrame(part.CFrame)
end
end
end
end
-- // SPAWNING ENEMIES
function scavenging.SpawnEnemies()
for _,part in spawnParts:GetChildren() do
if part.Name == "EnemySpawn" then
local maxSpawns = part.MaxSpawns
local randomSpawns = math.random(1,6)
while maxSpawns.Value < randomSpawns do
local size = part.Size
local position = part.Position
local halfSize = size * 0.5
local randomX = math.random(-halfSize.X, halfSize.X)
local randomZ = math.random(-halfSize.Z, halfSize.Z)
local randomPosition = position + Vector3.new(randomX, 0, randomZ)
local enemy = RNG(enemyChances):Clone()
enemy.Parent = workspace.Enemies
enemy.HumanoidRootPart.CFrame = CFrame.new(randomPosition)
maxSpawns.Value += 1
end
end
end
end
return scavenging
all of these are module scripts which are then called in .Changed events