1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-03 22:52:20 +02:00
Rampant/prototypes/SwarmUtils.lua
2019-03-05 22:18:03 -08:00

1495 lines
30 KiB
Lua
Executable File

local swarmUtils = {}
-- imports
local droneUtils = require("utils/DroneUtils")
local biterUtils = require("utils/BiterUtils")
local constants = require("__Rampant__/libs/Constants")
local mathUtils = require("__Rampant__/libs/MathUtils")
-- imported functions
local gaussianRandomRangeRG = mathUtils.gaussianRandomRangeRG
local roundToNearest = mathUtils.roundToNearest
local mMax = math.max
local mMin = math.min
local mFloor = math.floor
local deepcopy = util.table.deepcopy
local TIER_UPGRADE_SET_5 = constants.TIER_UPGRADE_SET_5
local TIER_UPGRADE_SET_10 = constants.TIER_UPGRADE_SET_10
local TIER_NAMING_SET_10 = constants.TIER_NAMING_SET_10
local TIER_NAMING_SET_5 = constants.TIER_NAMING_SET_5
local xorRandom = mathUtils.xorRandom(settings.startup["rampant-enemySeed"].value)
local makeBiterCorpse = biterUtils.makeBiterCorpse
local makeUnitSpawnerCorpse = biterUtils.makeUnitSpawnerCorpse
local makeWormCorpse = biterUtils.makeWormCorpse
local makeSpitterCorpse = biterUtils.makeSpitterCorpse
local makeBiter = biterUtils.makeBiter
local makeDrone = droneUtils.makeDrone
local makeSpitter = biterUtils.makeSpitter
local makeWorm = biterUtils.makeWorm
local makeUnitSpawner = biterUtils.makeUnitSpawner
-- module code
local function isMember(fieldType, fieldName, lst)
for i=1,#lst do
if (lst[i].type == fieldType) and (lst[i].name == fieldName) then
return true
end
end
return false
end
local function pushUpgrade(upgrades, upgrade)
if not isMember(upgrade.type, upgrade.name, upgrades) then
upgrades[#upgrades+1] = upgrade
end
end
local function addDefaultScales(template)
if not template.scales then
template.scales = {
[1] = 0.5,
[2] = 0.6,
[3] = 0.7,
[4] = 0.8,
[5] = 0.9,
[6] = 1,
[7] = 1.1,
[8] = 1.2,
[9] = 1.3,
[10] = 1.4
}
end
end
local function addDefaultVerticalAcceleration(upgrades)
pushUpgrade(upgrades,
{
type = "attack",
name = "particleVerticalAcceleration",
[1] = 0.01,
[2] = 0.01,
[3] = 0.02,
[4] = 0.02,
[5] = 0.03,
[6] = 0.03,
[7] = 0.04,
[8] = 0.04,
[9] = 0.05,
[10] = 0.05
})
end
local function addDefaultHoizontalSpeed(upgrades)
pushUpgrade(upgrades,
{
type = "attack",
name = "particleHoizontalSpeed",
[1] = 0.6,
[2] = 0.6,
[3] = 0.7,
[4] = 0.7,
[5] = 0.8,
[6] = 0.8,
[7] = 0.9,
[8] = 0.9,
[9] = 1,
[10] = 1
})
end
local function addDefaultHoizontalSpeedDeviation(upgrades)
pushUpgrade(upgrades,
{
type = "attack",
name = "particleHoizontalSpeedDeviation",
[1] = 0.0025,
[2] = 0.0025,
[3] = 0.0024,
[4] = 0.0024,
[5] = 0.0023,
[6] = 0.0023,
[7] = 0.0022,
[8] = 0.0022,
[9] = 0.0021,
[10] = 0.0021
})
end
local function addUnitDefaults(template, upgrades)
addDefaultScales(template)
addDefaultVerticalAcceleration(upgrades)
addDefaultHoizontalSpeed(upgrades)
addDefaultHoizontalSpeedDeviation(upgrades)
pushUpgrade(upgrades,
{
type = "attribute",
name = "healing",
[1] = 0.01,
[2] = 0.01,
[3] = 0.015,
[4] = 0.02,
[5] = 0.05,
[6] = 0.075,
[7] = 0.1,
[8] = 0.12,
[9] = 0.14,
[10] = 0.16
})
if (template.type == "biter") then
pushUpgrade(upgrades,
{
type = "attack",
name = "range",
[1] = 0.5,
[2] = 0.5,
[3] = 0.75,
[4] = 0.75,
[5] = 1.0,
[6] = 1.0,
[7] = 1.25,
[8] = 1.50,
[9] = 1.75,
[10] = 2.0
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "distancePerFrame",
[1] = 0.1,
[2] = 0.125,
[3] = 0.15,
[4] = 0.19,
[5] = 0.195,
[6] = 0.2,
[7] = 0.2,
[8] = 0.2,
[9] = 0.2,
[10] = 0.2
})
pushUpgrade(upgrades,
{
type = "resistance",
name = "physical",
decrease = {
[1] = 0,
[2] = 0,
[3] = 4,
[4] = 5,
[5] = 6,
[6] = 8,
[7] = 11,
[8] = 13,
[9] = 16,
[10] = 17
},
percent = {
[1] = 0,
[2] = 0,
[3] = 0,
[4] = 10,
[5] = 12,
[6] = 12,
[7] = 14,
[8] = 16,
[9] = 18,
[10] = 20
}
})
pushUpgrade(upgrades,
{
type = "resistance",
name = "explosion",
decrease = {
[1] = 0,
[2] = 0,
[3] = 0,
[4] = 0,
[5] = 0,
[6] = 10,
[7] = 12,
[8] = 14,
[9] = 16,
[10] = 20
},
percent = {
[1] = 0,
[2] = 0,
[3] = 0,
[4] = 10,
[5] = 12,
[6] = 13,
[7] = 15,
[8] = 16,
[9] = 17,
[10] = 20
}
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "movement",
[1] = 0.2,
[2] = 0.19,
[3] = 0.185,
[4] = 0.18,
[5] = 0.175,
[6] = 0.17,
[7] = 0.17,
[8] = 0.17,
[9] = 0.17,
[10] = 0.17
})
pushUpgrade(upgrades,
{
type = "attack",
name = "cooldown",
[1] = 35,
[2] = 35,
[3] = 35,
[4] = 35,
[5] = 35,
[6] = 35,
[7] = 50,
[8] = 50,
[9] = 55,
[10] = 57
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "health",
[1] = 15,
[2] = 75,
[3] = 150,
[4] = 250,
[5] = 1000,
[6] = 2000,
[7] = 3500,
[8] = 7500,
[9] = 15000,
[10] = 30000
})
pushUpgrade(upgrades,
{
type = "attack",
name = "cooldown",
[1] = 35,
[2] = 35,
[3] = 35,
[4] = 35,
[5] = 35,
[6] = 35,
[7] = 50,
[8] = 50,
[9] = 55,
[10] = 57
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "pollutionToAttack",
[1] = 200,
[2] = 750,
[3] = 1200,
[4] = 1750,
[5] = 2500,
[6] = 5000,
[7] = 10000,
[8] = 12500,
[9] = 15000,
[10] = 20000
})
pushUpgrade(upgrades,
{
type = "attack",
name = "damage",
[1] = 7,
[2] = 15,
[3] = 22.5,
[4] = 35,
[5] = 45,
[6] = 60,
[7] = 75,
[8] = 90,
[9] = 150,
[10] = 200
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "spawningTimeModifer",
[1] = 0,
[2] = 0,
[3] = 1,
[4] = 2,
[5] = 3,
[6] = 7,
[7] = 10,
[8] = 10,
[9] = 12,
[10] = 12
})
elseif (template.type == "spitter") then
pushUpgrade(upgrades,
{
type = "attribute",
name = "health",
[1] = 10,
[2] = 50,
[3] = 200,
[4] = 350,
[5] = 1250,
[6] = 2250,
[7] = 3250,
[8] = 6500,
[9] = 12500,
[10] = 25000
})
pushUpgrade(upgrades,
{
type = "resistance",
name = "explosion",
percent = {
[1] = 0,
[2] = 0,
[3] = 10,
[4] = 10,
[5] = 20,
[6] = 20,
[7] = 30,
[8] = 30,
[9] = 40,
[10] = 40
}
})
pushUpgrade(upgrades,
{
type = "resistance",
name = "physical",
decrease = {
[1] = 0,
[2] = 0,
[3] = 0,
[4] = 0,
[5] = 2,
[6] = 4,
[7] = 6,
[8] = 8,
[9] = 10,
[10] = 12
},
percent = {
[1] = 0,
[2] = 0,
[3] = 0,
[4] = 10,
[5] = 12,
[6] = 12,
[7] = 14,
[8] = 14,
[9] = 15,
[10] = 15
}
})
pushUpgrade(upgrades,
{
type = "attack",
name = "cooldown",
[1] = 100,
[2] = 100,
[3] = 97,
[4] = 97,
[5] = 95,
[6] = 95,
[7] = 93,
[8] = 93,
[9] = 90,
[10] = 90
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "distancePerFrame",
[1] = 0.04,
[2] = 0.045,
[3] = 0.050,
[4] = 0.055,
[5] = 0.060,
[6] = 0.065,
[7] = 0.070,
[8] = 0.075,
[9] = 0.08,
[10] = 0.084
})
pushUpgrade(upgrades,
{
type = "attack",
name = "range",
[1] = 13,
[2] = 13,
[3] = 14,
[4] = 14,
[5] = 15,
[6] = 15,
[7] = 16,
[8] = 16,
[9] = 17,
[10] = 17
})
pushUpgrade(upgrades,
{
type = "attack",
name = "radius",
[1] = 1.2,
[2] = 1.3,
[3] = 1.4,
[4] = 1.5,
[5] = 1.6,
[6] = 1.7,
[7] = 1.8,
[8] = 1.9,
[9] = 2.0,
[10] = 2.5
})
pushUpgrade(upgrades,
{
type = "attack",
name = "damage",
[1] = 4,
[2] = 9,
[3] = 14,
[4] = 23,
[5] = 30,
[6] = 37,
[7] = 45,
[8] = 57,
[9] = 70,
[10] = 80
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "movement",
[1] = 0.185,
[2] = 0.18,
[3] = 0.18,
[4] = 0.17,
[5] = 0.17,
[6] = 0.16,
[7] = 0.16,
[8] = 0.15,
[9] = 0.15,
[10] = 0.14
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "spawningTimeModifer",
[1] = 0,
[2] = 0,
[3] = 1,
[4] = 2,
[5] = 2,
[6] = 5,
[7] = 8,
[8] = 8,
[9] = 10,
[10] = 10
})
elseif (template.type == "drone") then
pushUpgrade(upgrades,
{
type = "attribute",
name = "health",
[1] = 100,
[2] = 100,
[3] = 110,
[4] = 110,
[5] = 120,
[6] = 120,
[7] = 130,
[8] = 130,
[9] = 140,
[10] = 140
})
pushUpgrade(upgrades,
{
type = "attack",
name = "cooldown",
[1] = 100,
[2] = 100,
[3] = 97,
[4] = 97,
[5] = 95,
[6] = 95,
[7] = 93,
[8] = 93,
[9] = 90,
[10] = 90
})
end
end
local function addUnitSpawnerDefaults(template, upgrades)
addDefaultScales(template)
pushUpgrade(upgrades,
{
type = "attribute",
name = "health",
[1] = 350,
[2] = 500,
[3] = 750,
[4] = 1500,
[5] = 3500,
[6] = 7500,
[7] = 11000,
[8] = 20000,
[9] = 30000,
[10] = 45000
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "healing",
[1] = 0.02,
[2] = 0.02,
[3] = 0.022,
[4] = 0.024,
[5] = 0.026,
[6] = 0.028,
[7] = 0.03,
[8] = 0.032,
[9] = 0.034,
[10] = 0.036
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "spawingCooldownStart",
[1] = 360,
[2] = 360,
[3] = 355,
[4] = 355,
[5] = 350,
[6] = 350,
[7] = 345,
[8] = 345,
[9] = 340,
[10] = 340
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "spawingCooldownEnd",
[1] = 150,
[2] = 150,
[3] = 145,
[4] = 145,
[5] = 140,
[6] = 140,
[7] = 135,
[8] = 135,
[9] = 130,
[10] = 130
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "unitsToSpawn",
[1] = 5,
[2] = 5,
[3] = 6,
[4] = 6,
[5] = 7,
[6] = 7,
[7] = 8,
[8] = 8,
[9] = 9,
[10] = 9
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "unitsOwned",
[1] = 7,
[2] = 7,
[3] = 8,
[4] = 8,
[5] = 9,
[6] = 9,
[7] = 10,
[8] = 10,
[9] = 11,
[10] = 11
})
pushUpgrade(upgrades,
{
type = "resistance",
name = "physical",
decrease = {
[1] = 2,
[2] = 2,
[3] = 4,
[4] = 4,
[5] = 6,
[6] = 6,
[7] = 10,
[8] = 12,
[9] = 12,
[10] = 14
},
percent = {
[1] = 15,
[2] = 15,
[3] = 17,
[4] = 17,
[5] = 18,
[6] = 18,
[7] = 19,
[8] = 19,
[9] = 20,
[10] = 20
}
})
pushUpgrade(upgrades,
{
type = "resistance",
name = "explosion",
decrease = {
[1] = 5,
[2] = 5,
[3] = 6,
[4] = 6,
[5] = 7,
[6] = 7,
[7] = 8,
[8] = 8,
[9] = 9,
[10] = 9
},
percent = {
[1] = 15,
[2] = 15,
[3] = 17,
[4] = 17,
[5] = 18,
[6] = 18,
[7] = 19,
[8] = 19,
[9] = 20,
[10] = 20
}
})
pushUpgrade(upgrades,
{
type = "resistance",
name = "fire",
decrease = {
[1] = 3,
[2] = 3,
[3] = 4,
[4] = 4,
[5] = 6,
[6] = 6,
[7] = 6,
[8] = 6,
[9] = 7,
[10] = 7
},
percent = {
[1] = 60,
[2] = 60,
[3] = 62,
[4] = 62,
[5] = 63,
[6] = 63,
[7] = 64,
[8] = 64,
[9] = 65,
[10] = 65
}
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "evolutionRequirement",
[1] = 0.08,
[2] = 0.16,
[3] = 0.24,
[4] = 0.35,
[5] = 0.40,
[6] = 0.45,
[7] = 0.55,
[8] = 0.65,
[9] = 0.75,
[10] = 0.9
})
end
local function addWormDefaults(template, upgrades)
addDefaultScales(template)
addDefaultVerticalAcceleration(upgrades)
addDefaultHoizontalSpeed(upgrades)
addDefaultHoizontalSpeedDeviation(upgrades)
pushUpgrade(upgrades,
{
type = "attribute",
name = "foldingSpeed",
[1] = 0.15,
[2] = 0.15,
[3] = 0.16,
[4] = 0.16,
[5] = 0.16,
[6] = 0.17,
[7] = 0.17,
[8] = 0.18,
[9] = 0.18,
[10] = 0.19
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "preparingSpeed",
[1] = 0.025,
[2] = 0.025,
[3] = 0.026,
[4] = 0.026,
[5] = 0.027,
[6] = 0.027,
[7] = 0.028,
[8] = 0.028,
[9] = 0.029,
[10] = 0.029
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "prepareRange",
[1] = 30,
[2] = 30,
[3] = 35,
[4] = 35,
[5] = 40,
[6] = 40,
[7] = 40,
[8] = 40,
[9] = 45,
[10] = 45
})
pushUpgrade(upgrades,
{
type = "attack",
name = "range",
[1] = 25,
[2] = 27,
[3] = 31,
[4] = 33,
[5] = 35,
[6] = 36,
[7] = 37,
[8] = 38,
[9] = 39,
[10] = 40
})
pushUpgrade(upgrades,
{
type = "resistance",
name = "physical",
decrease = {
[1] = 0,
[2] = 0,
[3] = 5,
[4] = 5,
[5] = 8,
[6] = 8,
[7] = 10,
[8] = 10,
[9] = 12,
[10] = 12
}
})
pushUpgrade(upgrades,
{
type = "resistance",
name = "explosion",
decrease = {
[1] = 0,
[2] = 0,
[3] = 5,
[4] = 5,
[5] = 8,
[6] = 8,
[7] = 10,
[8] = 10,
[9] = 12,
[10] = 12
},
percent = {
[1] = 0,
[2] = 0,
[3] = 10,
[4] = 10,
[5] = 20,
[6] = 20,
[7] = 30,
[8] = 30,
[9] = 40,
[10] = 40
}
})
pushUpgrade(upgrades,
{
type = "resistance",
name = "fire",
decrease = {
[1] = 3,
[2] = 3,
[3] = 4,
[4] = 4,
[5] = 6,
[6] = 6,
[7] = 6,
[8] = 6,
[9] = 7,
[10] = 7
},
percent = {
[1] = 70,
[2] = 70,
[3] = 72,
[4] = 72,
[5] = 73,
[6] = 73,
[7] = 74,
[8] = 74,
[9] = 75,
[10] = 75
}
})
pushUpgrade(upgrades,
{
type = "attack",
name = "damage",
[1] = 12,
[2] = 20,
[3] = 25,
[4] = 30,
[5] = 35,
[6] = 40,
[7] = 50,
[8] = 60,
[9] = 70,
[10] = 80
})
pushUpgrade(upgrades,
{
type = "attack",
name = "radius",
[1] = 1.5,
[2] = 1.6,
[3] = 1.7,
[4] = 1.8,
[5] = 1.9,
[6] = 2.0,
[7] = 2.2,
[8] = 2.3,
[9] = 2.5,
[10] = 3.0
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "healing",
[1] = 0.01,
[2] = 0.01,
[3] = 0.015,
[4] = 0.02,
[5] = 0.05,
[6] = 0.075,
[7] = 0.1,
[8] = 0.12,
[9] = 0.14,
[10] = 0.16
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "evolutionRequirement",
[1] = 0,
[2] = 0.1,
[3] = 0.2,
[4] = 0.3,
[5] = 0.4,
[6] = 0.5,
[7] = 0.6,
[8] = 0.7,
[9] = 0.8,
[10] = 0.9
})
pushUpgrade(upgrades,
{
type = "attack",
name = "cooldown",
[1] = 50,
[2] = 50,
[3] = 45,
[4] = 45,
[5] = 40,
[6] = 40,
[7] = 35,
[8] = 35,
[9] = 30,
[10] = 30
})
pushUpgrade(upgrades,
{
type = "attribute",
name = "health",
[1] = 200,
[2] = 350,
[3] = 500,
[4] = 750,
[5] = 2000,
[6] = 3500,
[7] = 7500,
[8] = 12000,
[9] = 20000,
[10] = 25000
})
end
local function unitSetToProbabilityTable(upgradeTable, unitSet)
local dividers = {}
for i=1,#unitSet do
dividers[i] = 1
end
if upgradeTable then
local points = #unitSet * 2
for _=1,points do
local index = mFloor(xorRandom() * #unitSet)+1
local upgrade = upgradeTable[index]
dividers[index] = dividers[index] + upgrade
end
end
local total = 0
for i=1,#dividers do
total = total + dividers[i]
end
local runningTotal = 0
for i=1,#dividers do
runningTotal = runningTotal + (dividers[i] / total)
dividers[i] = runningTotal
end
local stepUnit = 1 / (#unitSet[1] + 1)
local probabilityTable = {}
for i=1,#unitSet do
local result
if (i == 1) then
result = {
{
0,
stepUnit
},
{
dividers[i],
0
}
}
elseif (i == #unitSet) then
result = {
{
dividers[i-2],
0
},
{
1,
stepUnit
}
}
else
result = {
{
((i - 2) > 0 and dividers[i-2]) or 0,
0
},
{
dividers[i-1],
stepUnit
},
{
dividers[i],
0
}
}
end
probabilityTable[i] = result
end
local result = {}
for i=1, #probabilityTable do
local probability = probabilityTable[i]
for x=1, #unitSet[i] do
result[#result+1] = {unitSet[i][x], probability}
end
end
return result
end
local function scaleAttributes (upgrade, entity)
if (upgrade.type == "attribute") then
if (entity.type == "biter") then
if (upgrade.name == "health") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitBiterHealthScaler"].value
end
if (upgrade.name == "movement") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitBiterSpeedScaler"].value
end
if (upgrade.name == "distancePerFrame") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitBiterSpeedScaler"].value
end
elseif (entity.type == "spitter") then
if (upgrade.name == "health") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitSpitterHealthScaler"].value
end
if (upgrade.name == "movement") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitSpitterSpeedScaler"].value
end
if (upgrade.name == "distancePerFrame") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitSpitterSpeedScaler"].value
end
elseif (entity.type == "drone") then
if (upgrade.name == "health") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitDroneHealthScaler"].value
end
if (upgrade.name == "movement") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitDroneSpeedScaler"].value
end
if (upgrade.name == "distancePerFrame") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitDroneSpeedScaler"].value
end
elseif (entity.type == "spawner") then
if (upgrade.name == "health") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitSpawnerHealthScaler"].value
end
if (upgrade.name == "unitsOwned") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitSpawnerOwnedScaler"].value
end
if (upgrade.name == "unitsToSpawn") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitSpawnerSpawnScaler"].value
end
if (upgrade.name == "spawingCooldownStart") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitSpawnerRespawnScaler"].value
end
if (upgrade.name == "spawingCooldownEnd") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitSpawnerRespawnScaler"].value
end
elseif (entity.type == "worm") then
if (upgrade.name == "health") then
entity.attributes[upgrade.name] = entity.attributes[upgrade.name] * settings.startup["rampant-unitWormHealthScaler"].value
end
end
end
if (upgrade.type == "resistance") then
-- not asked for
end
if (upgrade.type == "attack") then
if (entity.type == "biter") then
if (upgrade.name == "damage") then
entity.attack[upgrade.name] = entity.attack[upgrade.name] * settings.startup["rampant-unitBiterDamageScaler"].value
end
if (upgrade.name == "range") then
entity.attack[upgrade.name] = entity.attack[upgrade.name] * settings.startup["rampant-unitBiterRangeScaler"].value
end
elseif (entity.type == "spitter") then
if (upgrade.name == "damage") then
entity.attack[upgrade.name] = entity.attack[upgrade.name] * settings.startup["rampant-unitSpitterDamageScaler"].value
end
if (upgrade.name == "stickerDamagePerTick") then
entity.attack[upgrade.name] = entity.attack[upgrade.name] * settings.startup["rampant-unitSpitterDamageScaler"].value
end
if (upgrade.name == "range") then
entity.attack[upgrade.name] = entity.attack[upgrade.name] * settings.startup["rampant-unitSpitterRangeScaler"].value
end
elseif (entity.type == "drone") then
if (upgrade.name == "damage") then
entity.attack[upgrade.name] = entity.attack[upgrade.name] * settings.startup["rampant-unitDroneDamageScaler"].value
end
if (upgrade.name == "range") then
entity.attack[upgrade.name] = entity.attack[upgrade.name] * settings.startup["rampant-unitDroneRangeScaler"].value
end
elseif (entity.type == "worm") then
if (upgrade.name == "damage") then
entity.attack[upgrade.name] = entity.attack[upgrade.name] * settings.startup["rampant-unitWormDamageScaler"].value
end
if (upgrade.name == "range") then
entity.attack[upgrade.name] = entity.attack[upgrade.name] * settings.startup["rampant-unitWormRangeScaler"].value
end
end
end
end
local function upgradeEntity(entity, upgradeTable, tier)
if upgradeTable then
for upgradeIndex=1, #upgradeTable do
local upgrade = upgradeTable[upgradeIndex]
if (upgrade.type == "attribute") then
if upgrade.mapping then
entity.attributes[upgrade.mapping] = upgrade[tier]
else
local adj = upgrade[tier]
local min = upgrade.min or adj * 0.85
local max = upgrade.max or adj * 1.30
if (adj < 0) then
local t = min
min = max
max = t
end
adj = roundToNearest(gaussianRandomRangeRG(adj, adj * 0.15, min, max, xorRandom), 0.001)
entity.attributes[upgrade.name] = (entity.attributes[upgrade.name] or 0) + adj
end
scaleAttributes(upgrade, entity)
end
if (upgrade.type == "resistance") then
local field = upgrade.name
if not entity.resistances[field] then
entity.resistances[field] = {}
end
local adj
if upgrade.decrease then
adj = upgrade.decrease[tier]
local min = upgrade.min or adj * 0.85
local max = upgrade.max or adj * 1.30
if (adj < 0) then
local t = min
min = max
max = t
end
adj = roundToNearest(gaussianRandomRangeRG(adj, adj * 0.15, min, max, xorRandom), 0.001)
entity.resistances[field].decrease = (entity.resistances[field].decrease or 0) + adj
end
if upgrade.percent then
adj = upgrade.percent[tier]
local min = upgrade.min or adj * 0.85
local max = upgrade.max or adj * 1.30
if (adj < 0) then
local t = min
min = max
max = t
end
adj = roundToNearest(gaussianRandomRangeRG(adj, adj * 0.15, min, max, xorRandom), 0.001)
entity.resistances[field].percent = mMin((entity.resistances[field].percent or 0) + adj, 100)
end
end
if (upgrade.type == "attack") then
if upgrade.mapping then
entity.attack[upgrade.mapping] = upgrade[tier]
else
local adj = upgrade[tier]
local min = upgrade.min or adj * 0.85
local max = upgrade.max or adj * 1.30
if (adj < 0) then
local t = min
min = max
max = t
end
adj = roundToNearest(gaussianRandomRangeRG(adj, adj * 0.15, min, max, xorRandom), 0.001)
entity.attack[upgrade.name] = (entity.attack[upgrade.name] or 0) + adj
end
scaleAttributes(upgrade, entity)
end
end
end
end
local function calculateRGBa(tint, tier)
local r = gaussianRandomRangeRG(tint.r, tint.r * 0.10 + (0.005 * tier), mMax(tint.r * 0.85 - (0.005 * tier), 0), mMin(tint.r * 1.15, 1), xorRandom)
local g = gaussianRandomRangeRG(tint.g, tint.g * 0.10 + (0.005 * tier), mMax(tint.g * 0.85 - (0.005 * tier), 0), mMin(tint.g * 1.15, 1), xorRandom)
local b = gaussianRandomRangeRG(tint.b, tint.b * 0.10 + (0.005 * tier), mMax(tint.b * 0.85 - (0.005 * tier), 0), mMin(tint.b * 1.15, 1), xorRandom)
local a = gaussianRandomRangeRG(tint.a, tint.a * 0.10 + (0.005 * tier), mMax(tint.a * 0.85 - (0.005 * tier), 0), mMin(tint.a * 1.15, 1), xorRandom)
return { r=r, g=g, b=b, a=a }
end
local function generateApperance(unit, tier)
local scale
if unit.scales then
local scaleValue = unit.scales[tier]
scale = gaussianRandomRangeRG(scaleValue, scaleValue * 0.12, scaleValue * 0.60, scaleValue * 1.40, xorRandom)
unit.scale = scale
unit.attributes.scale = scale
end
if unit.tint then
local tint = calculateRGBa(unit.tint, tier)
unit.attributes.tint = tint
if unit.attack then
if scale then
unit.attack.scale = scale
end
unit.attack.tint = tint
end
end
if unit.tint1 and unit.tint2 then
local tint1 = calculateRGBa(unit.tint1, tier)
local tint2 = calculateRGBa(unit.tint2, tier)
unit.attributes.tint1 = tint1
unit.attributes.tint2 = tint2
if unit.attack then
if scale then
unit.attack.scale = scale
end
unit.attack.tint1 = tint1
unit.attack.tint2 = tint2
end
end
if unit.attack then
if unit.pTint then
unit.attack.pTint = calculateRGBa(unit.pTint, tier)
end
if unit.lTint then
unit.attack.lTint = calculateRGBa(unit.lTint, tier)
end
if unit.sTint then
unit.attack.sTint = calculateRGBa(unit.sTint, tier)
end
if unit.smTint then
unit.attack.smTint = calculateRGBa(unit.smTint, tier)
end
end
end
function swarmUtils.buildUnits(template, attackGenerator, upgradeTable, variations, tiers)
addUnitDefaults(template, upgradeTable)
local unitSet = {}
for tier=1, tiers do
local t = ((tiers == 5) and TIER_NAMING_SET_5[tier]) or TIER_NAMING_SET_10[tier]
local ut = ((tiers == 5) and TIER_UPGRADE_SET_5[tier]) or TIER_UPGRADE_SET_10[tier]
local result = {}
for i=1,variations do
local unit = deepcopy(template)
unit.name = unit.name .. "-v" .. i .. "-t" .. t
unit.attributes.tier = "-v" .. i .. "-t" .. t
generateApperance(unit, ut)
upgradeEntity(unit, upgradeTable, ut)
if unit.attackName then
unit.attack.name = unit.attackName .. "-v" .. i .. "-t" .. t
end
if unit.loot then
unit.attributes.loot = { unit.loot[ut] }
end
local entity
if (unit.type == "spitter") then
unit.attributes.corpse = makeSpitterCorpse(unit)
entity = makeSpitter(unit.name,
unit.attributes,
attackGenerator(unit.attack, unit.attributes, t),
unit.resistances)
elseif (unit.type == "biter") then
unit.attributes.corpse = makeBiterCorpse(unit)
entity = makeBiter(unit.name,
unit.attributes,
attackGenerator(unit.attack, unit.attributes, t),
unit.resistances)
elseif (unit.type == "drone") then
entity = makeDrone(unit.name,
unit.attributes,
unit.resistances,
attackGenerator(unit.attack),
unit.death(unit.attack, unit.attributes, t))
end
result[#result+1] = entity.name
data:extend({entity})
end
unitSet[#unitSet+1] = result
end
return unitSet
end
function swarmUtils.buildUnitSpawner(templates, upgradeTable, attackGenerator, variations, tiers)
addUnitDefaults(templates.unit, upgradeTable.unit)
addUnitSpawnerDefaults(templates.unitSpawner, upgradeTable.unitSpawner)
if (not upgradeTable.probabilityTable) then
upgradeTable.probabilityTable = {
[1] = 1,
[2] = 1,
[3] = 1,
[4] = 1,
[5] = 1,
[6] = 1,
[7] = 1,
[8] = 1,
[9] = 1,
[10] = 1,
}
end
local unitSet = swarmUtils.buildUnits(templates.unit,
attackGenerator,
upgradeTable.unit,
variations.unit,
tiers.unit)
for tier=1, tiers.unitSpawner do
local t = ((tiers.unitSpawner == 5) and TIER_NAMING_SET_5[tier]) or TIER_NAMING_SET_10[tier]
local ut = ((tiers.unitSpawner == 5) and TIER_UPGRADE_SET_5[tier]) or TIER_UPGRADE_SET_10[tier]
-- print(tier,t,ut)
for i=1,variations.unitSpawner do
local unitSpawner = deepcopy(templates.unitSpawner)
unitSpawner.name = unitSpawner.name .. "-v" .. i .. "-t" .. t
local unitTable = unitSetToProbabilityTable(upgradeTable.probabilityTable,
unitSet)
generateApperance(unitSpawner, ut)
unitSpawner.type = "spawner"
upgradeEntity(unitSpawner, upgradeTable.unitSpawner, ut)
if unitSpawner.loot then
unitSpawner.attributes.loot = { unitSpawner.loot[ut] }
end
if unitSpawner.autoplace then
unitSpawner.attributes["autoplace"] = unitSpawner.autoplace[ut]
end
unitSpawner.attributes.corpse = makeUnitSpawnerCorpse(unitSpawner)
data:extend({
makeUnitSpawner(unitSpawner.name,
unitSpawner.attributes,
unitSpawner.resistances,
unitTable)
})
end
end
end
function swarmUtils.buildWorm(template, upgradeTable, attackGenerator, variations, tiers)
addWormDefaults(template, upgradeTable)
for tier=1, tiers do
local t = ((tiers == 5) and TIER_NAMING_SET_5[tier]) or TIER_NAMING_SET_10[tier]
local ut = ((tiers == 5) and TIER_UPGRADE_SET_5[tier]) or TIER_UPGRADE_SET_10[tier]
for i=1,variations do
local worm = deepcopy(template)
worm.name = worm.name .. "-v" .. i .. "-t" .. t
generateApperance(worm, ut)
worm.type = "worm"
upgradeEntity(worm, upgradeTable, ut)
if worm.attackName then
worm.attack.name = worm.attackName .. "-v" .. i .. "-t" .. t
end
if worm.loot then
worm.attributes.loot = { worm.loot[ut] }
end
if worm.autoplace then
worm.attributes["autoplace"] = worm.autoplace[ut]
end
worm.attributes.corpse = makeWormCorpse(worm)
data:extend({
makeWorm(worm.name,
worm.attributes,
attackGenerator(worm.attack, worm.attributes, t),
worm.resistances)
})
end
end
end
return swarmUtils