1
0
mirror of https://github.com/veden/Rampant.git synced 2025-03-11 14:49:32 +02:00

working unitclass generation

This commit is contained in:
Aaron Veden 2018-01-13 16:12:09 -08:00
parent 347c057dc2
commit c709c47011
6 changed files with 538 additions and 329 deletions

View File

@ -1,3 +1,4 @@
local swarmUtils = {}
-- imports
local biterUtils = require("prototypes/enemies/BiterUtils")
@ -5,21 +6,22 @@ local mathUtils = require("libs/MathUtils")
-- imported functions
local gaussianRandomRange = mathUtils.gaussianRandomRange
local gaussianRandomRangeRG = mathUtils.gaussianRandomRangeRG
local mRandom = math.random
local mMin = math.min
local mMax = math.max
local mMin = math.min
local mFloor = math.floor
local deepcopy = util.table.deepcopy
local xorRandom = mathUtils.xorRandom(settings.startup["rampant-enemySeed"].value)
local makeBiter = biterUtils.makeBiter
local makeSpitter = biterUtils.makeSpitter
local makeWorm = biterUtils.makeWorm
local makeUnitSpawner = biterUtils.makeUnitSpawner
local createSuicideAttack = biterUtils.createSuicideAttack
-- module code
local function unitSetToProbabilityTable(points, upgradeTable, unitSet)
@ -29,17 +31,19 @@ local function unitSetToProbabilityTable(points, upgradeTable, unitSet)
dividers[i] = 1
end
while (points > 0) do
local upgrade = upgradeTable[mRandom(#upgradeTable)]
if upgradeTable then
while (points > 0) do
local upgrade = upgradeTable[mFloor(xorRandom() * #upgradeTable)+1]
local cost = upgrade.cost
local index = upgrade.index
local cost = upgrade.cost
local index = upgrade.index
dividers[index] = dividers[index] + upgrade.adjustment
points = points - cost
dividers[index] = dividers[index] + upgrade.adjustment
points = points - cost
end
end
local total = 0
for i=1,#dividers do
total = total + dividers[i]
@ -51,8 +55,8 @@ local function unitSetToProbabilityTable(points, upgradeTable, unitSet)
dividers[i] = runningTotal
end
local stepUnit = 1 / #unitSet[1]
local stepUnit = 1 / (#unitSet[1] + 1)
local probabilityTable = {}
for i=1,#unitSet do
@ -111,9 +115,94 @@ local function unitSetToProbabilityTable(points, upgradeTable, unitSet)
return result
end
local function upgradeEntity(points, entity, upgradeTable)
local remainingPoints = points
if upgradeTable then
while (remainingPoints > 0) do
local upgrade = upgradeTable[mFloor(xorRandom() * #upgradeTable)+1]
local cost = upgrade.cost
for i=1, #upgrade.bonus do
local bonus = upgrade.bonus[i]
if (bonus.type == "attribute") then
if bonus.mapping then
entity.attributes[bonus.name] = bonus.mapping[entity.attributes[bonus.name] or "default"]
else
entity.attributes[bonus.name] = (entity.attributes[bonus.name] or 0) + bonus.adjustment
end
end
if (bonus.type == "resistance") then
local field = bonus.resistance.name
if not entity.resistances[field] then
entity.resistances[field] = {}
end
if bonus.resistance.decrease then
entity.resistances[field].decrease = (entity.resistances[field].decrease or 0) + bonus.resistance.decrease
end
if bonus.resistance.percentage then
entity.resistances[field].percentage = (entity.resistances[field].percentage or 0) + bonus.resistance.percentage
end
end
if (bonus.type == "attack") then
local attack = bonus.attack
entity.attack[attack.name] = (entity.attack[attack.name] or 0) + attack.adjustment
if attack.mapping then
entity.attributes[attack.name] = attack.mapping[entity.attributes[attack.name] or "default"]
else
entity.attributes[attack.name] = (entity.attributes[attack.name] or 0) + attack.adjustment
end
end
end
remainingPoints = remainingPoints - cost
end
end
end
local function generateApperance(unit, tier)
local scale = gaussianRandomRangeRG(unit.scale, unit.scale * 0.12, unit.scale * 0.60, unit.scale * 1.40, xorRandom) + (0.05 * tier)
local r,g,b,a
if unit.tint then
r = gaussianRandomRangeRG(unit.tint.r, unit.tint.r * 0.10 + (0.005 * tier), mMax(unit.tint.r * 0.85 - (0.005 * tier), 0), mMin(unit.tint.r * 1.15, 1), xorRandom)
g = gaussianRandomRangeRG(unit.tint.g, unit.tint.g * 0.10 + (0.005 * tier), mMax(unit.tint.g * 0.85 - (0.005 * tier), 0), mMin(unit.tint.g * 1.15, 1), xorRandom)
b = gaussianRandomRangeRG(unit.tint.b, unit.tint.b * 0.10 + (0.005 * tier), mMax(unit.tint.b * 0.85 - (0.005 * tier), 0), mMin(unit.tint.b * 1.15, 1), xorRandom)
a = gaussianRandomRangeRG(unit.tint.a, unit.tint.a * 0.10 + (0.005 * tier), mMax(unit.tint.a * 0.85 - (0.005 * tier), 0), mMin(unit.tint.a * 1.15, 1), xorRandom)
local tint = { r=r, g=g, b=b, a=a }
unit.attributes.scale = scale
unit.attributes.tint = tint
else
r = gaussianRandomRangeRG(unit.tint1.r, unit.tint1.r * 0.10 + (0.005 * tier), mMax(unit.tint1.r * 0.85 - (0.005 * tier), 0), mMin(unit.tint1.r * 1.15, 1), xorRandom)
g = gaussianRandomRangeRG(unit.tint1.g, unit.tint1.g * 0.10 + (0.005 * tier), mMax(unit.tint1.g * 0.85 - (0.005 * tier), 0), mMin(unit.tint1.g * 1.15, 1), xorRandom)
b = gaussianRandomRangeRG(unit.tint1.b, unit.tint1.b * 0.10 + (0.005 * tier), mMax(unit.tint1.b * 0.85 - (0.005 * tier), 0), mMin(unit.tint1.b * 1.15, 1), xorRandom)
a = gaussianRandomRangeRG(unit.tint1.a, unit.tint1.a * 0.10 + (0.005 * tier), mMax(unit.tint1.a * 0.85 - (0.005 * tier), 0), mMin(unit.tint1.a * 1.15, 1), xorRandom)
local tint1 = { r=r, g=g, b=b, a=a }
r = gaussianRandomRangeRG(unit.tint2.r, unit.tint2.r * 0.10 + (0.005 * tier), mMax(unit.tint2.r * 0.85 - (0.005 * tier), 0), mMin(unit.tint2.r * 1.15, 1), xorRandom)
g = gaussianRandomRangeRG(unit.tint2.g, unit.tint2.g * 0.10 + (0.005 * tier), mMax(unit.tint2.g * 0.85 - (0.005 * tier), 0), mMin(unit.tint2.g * 1.15, 1), xorRandom)
b = gaussianRandomRangeRG(unit.tint2.b, unit.tint2.b * 0.10 + (0.005 * tier), mMax(unit.tint2.b * 0.85 - (0.005 * tier), 0), mMin(unit.tint2.b * 1.15, 1), xorRandom)
a = gaussianRandomRangeRG(unit.tint2.a, unit.tint2.a * 0.10 + (0.005 * tier), mMax(unit.tint2.a * 0.85 - (0.005 * tier), 0), mMin(unit.tint2.a * 1.15, 1), xorRandom)
local tint2 = { r=r, g=g, b=b, a=a }
unit.attributes.scale = scale
unit.attributes.tint1 = tint1
unit.attributes.tint2 = tint2
unit.attack.scale = scale
unit.attack.tint1 = tint1
unit.attack.tint2 = tint2
end
end
local function buildUnits(startingPoints, template, attackGenerator, upgradeTable, variations, tiers)
local unitSet = {}
for t=1, tiers do
local result = {}
@ -122,58 +211,9 @@ local function buildUnits(startingPoints, template, attackGenerator, upgradeTabl
for i=1,variations do
local unit = deepcopy(template)
unit.name = unit.name .. "-v" .. i .. "-t" .. t
local remainingPoints = allottedPoints
while (remainingPoints > 0) do
local upgrade = upgradeTable[mRandom(#upgradeTable)]
local cost = upgrade.cost
if upgrade.attribute then
local attribute = upgrade.attribute
unit.attributes[attribute.name] = unit.attributes[attribute.name] + attribute.adjustment
end
if upgrade.resistance then
local field = upgrade.resistance.name
if not unit.resistances[field] then
unit.resistances[field] = {}
end
if upgrade.resistance.decrease then
unit.resistances[field].decrease = (unit.resistances[field].decrease or 0) + upgrade.resistance.decrease
end
if upgrade.resistance.percentage then
unit.resistances[field].percentage = (unit.resistances[field].percentage or 0) + upgrade.resistance.percentage
end
end
if upgrade.attack then
local attack = upgrade.attack
unit.attack[attack.name] = (unit.attack[attack.name] or 0) + attack.adjustment
end
remainingPoints = remainingPoints - cost
end
local scale = gaussianRandomRange(unit.scale, unit.scale * 0.12, unit.scale * 0.60, unit.scale * 1.40) + (0.05 * t)
local tint1 = {
gaussianRandomRange(unit.tint1.r, unit.tint1.r * 0.06 + (0.005 * t), unit.tint1.r * 0.85 - (0.005 * t), unit.tint1.r * 1.15),
gaussianRandomRange(unit.tint1.g, unit.tint1.g * 0.06 + (0.005 * t), unit.tint1.g * 0.85 - (0.005 * t), unit.tint1.g * 1.15),
gaussianRandomRange(unit.tint1.b, unit.tint1.b * 0.06 + (0.005 * t), unit.tint1.b * 0.85 - (0.005 * t), unit.tint1.b * 1.15),
gaussianRandomRange(unit.tint1.a, unit.tint1.a * 0.06 + (0.005 * t), unit.tint1.a * 0.85 - (0.005 * t), unit.tint1.a * 1.15)
}
local tint2 = {
gaussianRandomRange(unit.tint2.r, unit.tint2.r * 0.06 + (0.005 * t), unit.tint2.r * 0.85 - (0.005 * t), unit.tint2.r * 1.15),
gaussianRandomRange(unit.tint2.g, unit.tint2.g * 0.06 + (0.005 * t), unit.tint2.g * 0.85 - (0.005 * t), unit.tint2.g * 1.15),
gaussianRandomRange(unit.tint2.b, unit.tint2.b * 0.06 + (0.005 * t), unit.tint2.b * 0.85 - (0.005 * t), unit.tint2.b * 1.15),
gaussianRandomRange(unit.tint2.a, unit.tint2.a * 0.06 + (0.005 * t), unit.tint2.a * 0.85 - (0.005 * t), unit.tint2.a * 1.15)
}
generateApperance(unit, t)
upgradeEntity(allottedPoints, unit, upgradeTable)
unit.attributes.scale = scale
unit.attributes.tint1 = tint1
unit.attributes.tint2 = tint2
unit.attack.scale = scale
unit.attack.tint1 = tint1
unit.attack.tint2 = tint2
local entity
if (unit.type == "spitter") then
entity = makeSpitter(unit.name,
@ -205,42 +245,8 @@ local function buildUnitSpawner(startingPoints, template, upgradeTable, unitTabl
for i=1,variations do
local unitSpawner = deepcopy(template)
unitSpawner.name = unitSpawner.name .. "-v" .. i .. "-t" .. t
local remainingPoints = allottedPoints
while (remainingPoints > 0) do
local upgrade = upgradeTable[mRandom(#upgradeTable)]
local cost = upgrade.cost
if upgrade.attribute then
local attribute = upgrade.attribute
unitSpawner.attributes[attribute.name] = unitSpawner.attributes[attribute.name] + attribute.adjustment
end
if upgrade.resistance then
local field = upgrade.resistance.name
if not unitSpawner.resistances[field] then
unitSpawner.resistances[field] = {}
unitSpawner.resistances[field].type = field
end
if upgrade.resistance.decrease then
unitSpawner.resistances[field].decrease = (unitSpawner.resistances[field].decrease or 0) + upgrade.resistance.decrease
end
if upgrade.resistance.percentage then
unitSpawner.resistances[field].percentage = (unitSpawner.resistances[field].percentage or 0) + upgrade.resistance.percentage
end
end
remainingPoints = remainingPoints - cost
end
local scale = gaussianRandomRange(unitSpawner.scale, unitSpawner.scale * 0.12, unitSpawner.scale * 0.60, unitSpawner.scale * 1.40) + (0.05 * t)
local tint = {
gaussianRandomRange(unitSpawner.tint1.r, unitSpawner.tint1.r * 0.06 + (0.005 * t), unitSpawner.tint1.r * 0.85 - (0.005 * t), unitSpawner.tint1.r * 1.15),
gaussianRandomRange(unitSpawner.tint1.g, unitSpawner.tint1.g * 0.06 + (0.005 * t), unitSpawner.tint1.g * 0.85 - (0.005 * t), unitSpawner.tint1.g * 1.15),
gaussianRandomRange(unitSpawner.tint1.b, unitSpawner.tint1.b * 0.06 + (0.005 * t), unitSpawner.tint1.b * 0.85 - (0.005 * t), unitSpawner.tint1.b * 1.15),
gaussianRandomRange(unitSpawner.tint1.a, unitSpawner.tint1.a * 0.06 + (0.005 * t), unitSpawner.tint1.a * 0.85 - (0.005 * t), unitSpawner.tint1.a * 1.15)
}
unitSpawner.attributes.scale = scale
unitSpawner.attributes.tint = tint
generateApperance(unitSpawner, t)
upgradeEntity(allottedPoints, unitSpawner, upgradeTable)
data:extend({
makeUnitSpawner(unitSpawner.name,
@ -253,61 +259,16 @@ local function buildUnitSpawner(startingPoints, template, upgradeTable, unitTabl
end
local function buildWorm(startingPoints, template, attackGenerator, upgradeTable, variations, tiers)
function swarmUtils.buildWorm(startingPoints, template, attackGenerator, upgradeTable, variations, tiers)
for t=1, tiers do
local allottedPoints = startingPoints * t
for i=1,variations do
local worm = deepcopy(template)
worm.name = worm.name .. "-v" .. i .. "-t" .. t
local remainingPoints = allottedPoints
while (remainingPoints > 0) do
local upgrade = upgradeTable[mRandom(#upgradeTable)]
local cost = upgrade.cost
if upgrade.attribute then
local attribute = upgrade.attribute
worm.attributes[attribute.name] = worm.attributes[attribute.name] + attribute.adjustment
end
if upgrade.resistance then
local field = upgrade.resistance.name
if not worm.resistances[field] then
worm.resistances[field] = {}
worm.resistances[field].type = field
end
if upgrade.resistance.decrease then
worm.resistances[field].decrease = (worm.resistances[field].decrease or 0) + upgrade.resistance.decrease
end
if upgrade.resistance.percentage then
worm.resistances[field].percentage = (worm.resistances[field].percentage or 0) + upgrade.resistance.percentage
end
end
remainingPoints = remainingPoints - cost
end
local scale = gaussianRandomRange(worm.scale, worm.scale * 0.12, worm.scale * 0.60, worm.scale * 1.40) + (0.05 * t)
local tint1 = {
gaussianRandomRange(worm.tint1.r, worm.tint1.r * 0.06 + (0.005 * t), worm.tint1.r * 0.85 - (0.005 * t), worm.tint1.r * 1.15),
gaussianRandomRange(worm.tint1.g, worm.tint1.g * 0.06 + (0.005 * t), worm.tint1.g * 0.85 - (0.005 * t), worm.tint1.g * 1.15),
gaussianRandomRange(worm.tint1.b, worm.tint1.b * 0.06 + (0.005 * t), worm.tint1.b * 0.85 - (0.005 * t), worm.tint1.b * 1.15),
gaussianRandomRange(worm.tint1.a, worm.tint1.a * 0.06 + (0.005 * t), worm.tint1.a * 0.85 - (0.005 * t), worm.tint1.a * 1.15)
}
local tint2 = {
gaussianRandomRange(worm.tint2.r, worm.tint2.r * 0.06 + (0.005 * t), worm.tint2.r * 0.85 - (0.005 * t), worm.tint2.r * 1.15),
gaussianRandomRange(worm.tint2.g, worm.tint2.g * 0.06 + (0.005 * t), worm.tint2.g * 0.85 - (0.005 * t), worm.tint2.g * 1.15),
gaussianRandomRange(worm.tint2.b, worm.tint2.b * 0.06 + (0.005 * t), worm.tint2.b * 0.85 - (0.005 * t), worm.tint2.b * 1.15),
gaussianRandomRange(worm.tint2.a, worm.tint2.a * 0.06 + (0.005 * t), worm.tint2.a * 0.85 - (0.005 * t), worm.tint2.a * 1.15)
}
worm.attributes.scale = scale
worm.attributes.tint1 = tint1
worm.attributes.tint2 = tint2
worm.attack.scale = scale
worm.attack.tint1 = tint1
worm.attack.tint2 = tint2
generateApperance(worm, t)
upgradeEntity(allottedPoints, worm, upgradeTable)
data:extend({
makeWorm(worm.name,
worm.attributes,
@ -318,12 +279,10 @@ local function buildWorm(startingPoints, template, attackGenerator, upgradeTable
end
end
local function createUnitClass(points, templates, upgradeTable, attackGenerator, variations, tiers)
function swarmUtils.createUnitClass(points, templates, upgradeTable, attackGenerator, variations, tiers)
buildUnitSpawner(points.unitSpawner,
templates.unitSpawner,
upgradeTable.unitSpawner,
variations.unitSpawner,
tiers.unitSpawner,
unitSetToProbabilityTable(points.probabilityTable,
upgradeTable.probabilityTable,
buildUnits(points.unit,
@ -332,98 +291,8 @@ local function createUnitClass(points, templates, upgradeTable, attackGenerator,
upgradeTable.unit,
variations.unit,
tiers.unit)),
variations.unitSpawner,
tiers.unitSpawner)
end
createUnitClass({
unit = 10,
unitSpawner = 5,
probabilityTable = 5
},
{
unit = {
name = "rampant-suicide-biter",
attributes = {
health = 30,
movement = 0.21,
distancePerFrame = 0.1,
healing = 0.01,
explosion = "blood-explosion-small",
},
attack = {
area = 3.5,
damage = 20,
explosion = "explosion",
scorchmark = "small-scorchmark",
explosionCount = 2,
explosionDistance = 2,
},
resistances = {
explosion = {
decrease = 0,
percentage = -50
},
laser = {
decrease = 1,
percentage = 0
},
fire = {
decrease = 0,
percentage = -60
}
},
type = "biter",
scale = 0.55,
tint1 = {r=0.6, g=0.0, b=0.70, a=0.8},
tint2 = {r=0.7, g=0.0, b=0.72, a=0.4}
},
unitSpawner = {
scale = 0.55,
tint1 = {},
tint2 = {}
}
},
{
unit = {
{
cost = 1,
attribute = {
name = "health",
adjustment = 50
}
}
},
unitSpawner = {
{
cost = 1,
attribute = {
name = "health",
adjustment = 50
}
}
},
probabilityTable = {
{
cost = 1,
index = 1,
adjustment = 1
}
}
},
createSuicideAttack,
{
unit = 5,
unitSpawner = 5
},
{
unit = 7,
unitSpawner = 7
}
)
local function dog(a)
a[1] = 2
end
dog()
return swarmUtils

188
UnitClasses.lua Executable file
View File

@ -0,0 +1,188 @@
-- imports
local biterUtils = require("prototypes/enemies/BiterUtils")
local swarmUtils = require("Swarmutils")
-- imported functions
local createUnitClass = swarmUtils.createUnitClass
local createSuicideAttack = biterUtils.createSuicideAttack
-- module code
createUnitClass(
{
unit = 10,
unitSpawner = 5,
probabilityTable = 5
},
{
unit = {
name = "rampant-suicide-biter",
attributes = {
health = 30,
movement = 0.21,
distancePerFrame = 0.1,
healing = 0.01,
explosion = "blood-explosion-small",
},
attack = {
area = 3.5,
damage = 20,
explosion = "explosion",
scorchmark = "small-scorchmark",
explosionCount = 2,
explosionDistance = 2,
},
resistances = {
explosion = {
decrease = 0,
percentage = -50
},
laser = {
decrease = 1,
percentage = 0
},
fire = {
decrease = 0,
percentage = -60
}
},
type = "biter",
scale = 0.55,
tint1 = {r=0.6, g=0.0, b=0.70, a=0.8},
tint2 = {r=0.7, g=0.0, b=0.72, a=0.4}
},
unitSpawner = {
name = "rampant-suicide-nest",
attributes = {
health = 30,
healing = 0.01,
unitsOwned = 7,
unitsToSpawn = 5,
spawingCooldownStart = 360,
spawingCooldownStop = 150,
},
resistances = {
explosion = {
decrease = 0,
percentage = -50
},
laser = {
decrease = 1,
percentage = 0
},
fire = {
decrease = 0,
percentage = -60
}
},
scale = 0.95,
tint = {r=0.7, g=0.0, b=0.72, a=0.4}
}
},
{
unit = {
{
cost = 1,
bonus = {
{
type = "attribute",
name = "health",
adjustment = 50
}
}
}
},
unitSpawner = {
{
cost = 1,
bonus = {
{
type = "attribute",
name = "health",
adjustment = 50
}
}
}
},
probabilityTable = {
{
cost = 1,
index = 1,
adjustment = 1
},
{
cost = 1,
index = 2,
adjustment = 1
},
{
cost = 1,
index = 3,
adjustment = 1
},
{
cost = 1,
index = 4,
adjustment = 1
},
{
cost = 1,
index = 5,
adjustment = 1
},
{
cost = 1,
index = 6,
adjustment = 1.5
},
{
cost = 1,
index = 7,
adjustment = 2
},
{
cost = 1,
index = 8,
adjustment = 2
},
{
cost = 1,
index = 9,
adjustment = 1.5
},
{
cost = 1,
index = 10,
adjustment = 1
}
}
},
createSuicideAttack,
{
unit = 5,
unitSpawner = 5
},
{
unit = 10,
unitSpawner = 7
}
)

View File

@ -8,10 +8,10 @@ require("prototypes/tile/fillableDirt")
-- if settings.startup["rampant-newEnemies"].value then
if settings.startup["rampant-newEnemies"].value then
require("BuildSwarm")
-- end
end
require("prototypes/enemies/UnitSuicideBiters")
require("prototypes/enemies/UnitFireSpitters")
require("prototypes/enemies/UnitTendril")
-- require("prototypes/enemies/UnitSuicideBiters")
-- require("prototypes/enemies/UnitFireSpitters")
-- require("prototypes/enemies/UnitTendril")

View File

@ -16,9 +16,8 @@ local mMax = math.max
local mSqrt = math.sqrt
local mLog10 = math.log10
local mFloor = math.floor
local mRandom = math.random
local mFloor = math.floor
-- module code
@ -33,37 +32,98 @@ function mathUtils.randomTickEvent(tick, low, high)
return tick + nextTick
end
function mathUtils.xorRandom(state)
local xor = bit32.bxor
local lshift = bit32.lshift
local rshift = bit32.rshift
state = state + 21594771
return function()
state = xor(state, lshift(state, 13))
state = xor(state, rshift(state, 17))
state = xor(state, lshift(state, 5))
state = state % 2147483647
return state * 4.65661287525e-10
end
end
--[[
Used for gaussian random numbers
--]]
local function marsagliaPolarMethod(rg)
function mathUtils.gaussianRandom(mean, std_dev)
-- marsagliaPolarMethod
local iid1
local iid2
local q
repeat
if rg then
iid1 = 2 * rg() + -1
iid2 = 2 * rg() + -1
else
iid1 = 2 * mRandom() + -1
iid2 = 2 * mRandom() + -1
end
iid1 = 2 * mRandom() + -1
iid2 = 2 * mRandom() + -1
q = (iid1 * iid1) + (iid2 * iid2)
until (q ~= 0) and (q < 1)
local s = mSqrt((-2 * mLog10(q)) / q)
return iid1 * s
local v = iid1 * s
return mean + (v * std_dev)
end
function mathUtils.gaussianRandom(mean, std_dev, rg)
return mean + (marsagliaPolarMethod(rg) * std_dev)
end
function mathUtils.gaussianRandomRange(mean, std_dev, min, max, rg)
local q
function mathUtils.gaussianRandomRange(mean, std_dev, min, max)
if (min == max) then
return min
end
local r
repeat
q = mathUtils.gaussianRandom(mean, std_dev, rg)
until (q >= min) and (q <= max)
return q
local iid1
local iid2
local q
repeat
iid1 = 2 * mRandom() + -1
iid2 = 2 * mRandom() + -1
q = (iid1 * iid1) + (iid2 * iid2)
until (q ~= 0) and (q < 1)
local s = mSqrt((-2 * mLog10(q)) / q)
local v = iid1 * s
r = mean + (v * std_dev)
until (r >= min) and (r <= max)
return r
end
function mathUtils.gaussianRandomRG(mean, std_dev, rg)
-- marsagliaPolarMethod
local iid1
local iid2
local q
repeat
iid1 = 2 * rg() + -1
iid2 = 2 * rg() + -1
q = (iid1 * iid1) + (iid2 * iid2)
until (q ~= 0) and (q < 1)
local s = mSqrt((-2 * mLog10(q)) / q)
local v = iid1 * s
return mean + (v * std_dev)
end
function mathUtils.gaussianRandomRangeRG(mean, std_dev, min, max, rg)
local r
if (min == max) then
return min
end
repeat
local iid1
local iid2
local q
repeat
iid1 = 2 * rg() + -1
iid2 = 2 * rg() + -1
q = (iid1 * iid1) + (iid2 * iid2)
until (q ~= 0) and (q < 1)
local s = mSqrt((-2 * mLog10(q)) / q)
local v = iid1 * s
r = mean + (v * std_dev)
until (r >= min) and (r <= max)
return r
end
function mathUtils.euclideanDistanceNamed(p1, p2)

View File

@ -1,6 +1,12 @@
local biterFunctions = {}
function biterFunctions.makeBiter(name, biterAttributes, biterAttack, biterResistances)
local resistances = {}
for k,v in pairs(biterResistances) do
v.type = k
resistances[#resistances+1] = v
end
return {
type = "unit",
name = name,
@ -11,7 +17,7 @@ function biterFunctions.makeBiter(name, biterAttributes, biterAttack, biterResis
order = "b-b-a",
subgroup="enemies",
healing_per_tick = biterAttributes.healing,
resistances = biterResistances,
resistances = resistances,
collision_box = {{-0.4 * biterAttributes.scale, -0.4 * biterAttributes.scale},
{0.4 * biterAttributes.scale, 0.4 * biterAttributes.scale}},
selection_box = {{-0.7 * biterAttributes.scale, -1.5 * biterAttributes.scale},
@ -33,6 +39,12 @@ function biterFunctions.makeBiter(name, biterAttributes, biterAttack, biterResis
end
function biterFunctions.makeSpitter(name, biterAttributes, biterAttack, biterResistances)
local resistances = {}
for k,v in pairs(biterResistances) do
v.type = k
resistances[#resistances+1] = v
end
return {
type = "unit",
name = name,
@ -43,7 +55,7 @@ function biterFunctions.makeSpitter(name, biterAttributes, biterAttack, biterRes
order = "b-b-a",
subgroup="enemies",
healing_per_tick = biterAttributes.healing,
resistances = biterResistances,
resistances = resistances,
collision_box = {{-0.4 * biterAttributes.scale, -0.4 * biterAttributes.scale},
{0.4 * biterAttributes.scale, 0.4 * biterAttributes.scale}},
selection_box = {{-0.7 * biterAttributes.scale, -1.5 * biterAttributes.scale},
@ -65,62 +77,69 @@ function biterFunctions.makeSpitter(name, biterAttributes, biterAttack, biterRes
end
function biterFunctions.makeUnitSpawner(name, biterAttributes, biterResistances, unitSet)
local resistances = {}
for k,v in pairs(biterResistances) do
v.type = k
resistances[#resistances+1] = v
end
local o = {
type = "unit-spawner",
name = name,
icon = "__base__/graphics/icons/biter-spawner.png",
icon_size = 32,
flags = {"placeable-player", "placeable-enemy", "not-repairable"},
max_health = biterAttributes.health,
order="b-b-g",
subgroup="enemies",
resistances = biterResistances,
working_sound = {
sound =
{
{
filename = "__base__/sound/creatures/spawner.ogg",
volume = 1.0
}
},
apparent_volume = 2
},
dying_sound =
{
{
filename = "__base__/sound/creatures/spawner-death-1.ogg",
volume = 1.0
},
{
filename = "__base__/sound/creatures/spawner-death-2.ogg",
volume = 1.0
}
},
healing_per_tick = biterAttributes.healing or 0.02,
collision_box = {{-3.2 * biterAttributes.scale, -2.2 * biterAttributes.scale}, {2.2 * biterAttributes.scale, 2.2 * biterAttributes.scale}},
selection_box = {{-3.5 * biterAttributes.scale, -2.5 * biterAttributes.scale}, {2.5 * biterAttributes.scale, 2.5 * biterAttributes.scale}},
-- in ticks per 1 pu
pollution_absorbtion_absolute = biterAttributes.pollutionAbsorbtionAbs or 20,
pollution_absorbtion_proportional = biterAttributes.pollutionAbsorbtionPro or 0.01,
corpse = "biter-spawner-corpse",
dying_explosion = "blood-explosion-huge",
max_count_of_owned_units = biterAttributes.unitsOwned or 7,
max_friends_around_to_spawn = biterAttributes.unitsToSpawn or 5,
animations =
{
spawner_idle_animation(0, biterAttributes.tint),
spawner_idle_animation(1, biterAttributes.tint),
spawner_idle_animation(2, biterAttributes.tint),
spawner_idle_animation(3, biterAttributes.tint)
},
result_units = unitSet,
-- With zero evolution the spawn rate is 6 seconds, with max evolution it is 2.5 seconds
spawning_cooldown = biterAttributes.spawningCooldown or {360, 150},
spawning_radius = biterAttributes.spawningRadius or 10,
spawning_spacing = biterAttributes.spawningSpacing or 3,
max_spawn_shift = 0,
max_richness_for_spawn_shift = 100,
call_for_help_radius = 50
type = "unit-spawner",
name = name,
icon = "__base__/graphics/icons/biter-spawner.png",
icon_size = 32,
flags = {"placeable-player", "placeable-enemy", "not-repairable"},
max_health = biterAttributes.health,
order="b-b-g",
subgroup="enemies",
resistances = resistances,
working_sound = {
sound =
{
{
filename = "__base__/sound/creatures/spawner.ogg",
volume = 1.0
}
},
apparent_volume = 2
},
dying_sound =
{
{
filename = "__base__/sound/creatures/spawner-death-1.ogg",
volume = 1.0
},
{
filename = "__base__/sound/creatures/spawner-death-2.ogg",
volume = 1.0
}
},
healing_per_tick = biterAttributes.healing or 0.02,
collision_box = {{-3.2 * biterAttributes.scale, -2.2 * biterAttributes.scale}, {2.2 * biterAttributes.scale, 2.2 * biterAttributes.scale}},
selection_box = {{-3.5 * biterAttributes.scale, -2.5 * biterAttributes.scale}, {2.5 * biterAttributes.scale, 2.5 * biterAttributes.scale}},
-- in ticks per 1 pu
pollution_absorbtion_absolute = biterAttributes.pollutionAbsorbtionAbs or 20,
pollution_absorbtion_proportional = biterAttributes.pollutionAbsorbtionPro or 0.01,
corpse = "biter-spawner-corpse",
dying_explosion = "blood-explosion-huge",
max_count_of_owned_units = biterAttributes.unitsOwned or 7,
max_friends_around_to_spawn = biterAttributes.unitsToSpawn or 5,
animations =
{
spawner_idle_animation(0, biterAttributes.tint),
spawner_idle_animation(1, biterAttributes.tint),
spawner_idle_animation(2, biterAttributes.tint),
spawner_idle_animation(3, biterAttributes.tint)
},
result_units = unitSet,
-- With zero evolution the spawn rate is 6 seconds, with max evolution it is 2.5 seconds
spawning_cooldown = biterAttributes.spawningCooldown or {360, 150},
spawning_radius = biterAttributes.spawningRadius or 10,
spawning_spacing = biterAttributes.spawningSpacing or 3,
max_spawn_shift = 0,
max_richness_for_spawn_shift = 100,
build_base_evolution_requirement = biterAttributes.evolutionRequirement or 0.0,
call_for_help_radius = 50
}
if biterAttributes.autoplace then
o["autoplace"] = enemy_spawner_autoplace(biterAttributes.autoplace)
@ -128,6 +147,57 @@ function biterFunctions.makeUnitSpawner(name, biterAttributes, biterResistances,
return o
end
function biterFunctions.makeWorm(name, attributes, attack, wormResistances)
local resistances = {}
for k,v in pairs(wormResistances) do
v.type = k
resistances[#resistances+1] = v
end
local o = {
type = "turret",
name = name,
icon = "__base__/graphics/icons/medium-worm.png",
icon_size = 32,
flags = attributes.flags or {"placeable-player", "placeable-enemy", "not-repairable", "breaths-air"},
order="b-b-e",
subgroup="enemies",
max_health = attributes.health,
resistances = resistances,
healing_per_tick = attributes.healing or 0.01,
collision_box = {{-1.1 * attributes.scale, -1.0 * attributes.scale}, {1.1 * attributes.scale, 1.0 * attributes.scale}},
selection_box = {{-1.1 * attributes.scale, -1.0 * attributes.scale}, {1.1 * attributes.scale, 1.0 * attributes.scale}},
shooting_cursor_size = attributes.cursorSize or 3,
rotation_speed = attributes.rotationSpeed or 1,
corpse = "medium-worm-corpse",
dying_explosion = "blood-explosion-big",
dying_sound = make_worm_dying_sounds(0.9),
folded_speed = attributes.foldedSpeed or 0.01,
folded_animation = worm_folded_animation(attributes.scale, attributes.tint),
preparing_speed = attributes.preparingSpeed or 0.025,
preparing_animation = worm_preparing_animation(attributes.scale, attributes.tint, "forward"),
prepared_speed = attributes.preparedSpeed or 0.015,
prepared_animation = worm_prepared_animation(attributes.scale, attributes.tint),
starting_attack_speed = attributes.attackSpeed or 0.03,
starting_attack_animation = worm_attack_animation(attributes.scale, attributes.tint, "forward"),
starting_attack_sound = make_worm_roars(0.8),
ending_attack_speed = attributes.endingAttackSpeed or 0.03,
ending_attack_animation = worm_attack_animation(attributes.scale, attributes.tint, "backward"),
folding_speed = attributes.foldingSpeed or 0.015,
folding_animation = worm_preparing_animation(attributes.scale, attributes.tint, "backward"),
prepare_range = attributes.prepareRange or 30,
attack_parameters = attack,
build_base_evolution_requirement = attributes.evolutionRequirement or 0.0,
call_for_help_radius = 40
}
if attributes.autoplace then
o["autoplace"] = enemy_worm_autoplace(attributes.autoplace)
end
return o
end
function biterFunctions.createSuicideAttack(attributes)
return { type = "projectile",
range = 0.5,

View File

@ -212,7 +212,29 @@ data:extend({
default_value = true,
order = "k[modifier]-a[unit]",
per_user = false
},
{
type = "int-setting",
name = "rampant-enemySeed",
description = "rampant-enemySeed",
setting_type = "startup",
minimum_value = 0,
default_value = 0,
order = "l[modifer]-a[seed]",
per_user = false
},
{
type = "bool-setting",
name = "rampant-newEnemies",
description = "rampant-newEnemies",
setting_type = "startup",
default_value = true,
order = "l[modifier]-b[unit]",
per_user = false
}
-- {
-- type = "bool-setting",