mirror of
https://github.com/veden/Rampant.git
synced 2025-03-11 14:49:32 +02:00
working on uni classes, still need base and entity upgrade logic finished
This commit is contained in:
parent
8e76817a19
commit
33815a27b7
@ -115,7 +115,7 @@ local function unitSetToProbabilityTable(points, upgradeTable, unitSet)
|
||||
return result
|
||||
end
|
||||
|
||||
local function upgradeEntity(points, entity, upgradeTable)
|
||||
local function upgradeEntity(points, entity, upgradeTable, tierMultipler)
|
||||
local remainingPoints = points
|
||||
if upgradeTable then
|
||||
while (remainingPoints > 0) do
|
||||
@ -129,28 +129,40 @@ local function upgradeEntity(points, entity, upgradeTable)
|
||||
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
|
||||
local adj = bonus.adjustment * tierMultipler
|
||||
if adj < 0 then
|
||||
adj = -adj
|
||||
adj = -gaussianRandomRangeRG(adj, adj * 0.2, adj * 0.75, adj * 1.25, xorRandom)
|
||||
else
|
||||
adj = gaussianRandomRangeRG(adj, adj * 0.2, adj * 0.75, adj * 1.25, xorRandom)
|
||||
end
|
||||
entity.attributes[bonus.name] = (entity.attributes[bonus.name] or 0) + adj
|
||||
end
|
||||
end
|
||||
if (bonus.type == "resistance") then
|
||||
local field = bonus.resistance.name
|
||||
local field = bonus.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
|
||||
if bonus.decrease then
|
||||
entity.resistances[field].decrease = (entity.resistances[field].decrease or 0) + bonus.decrease
|
||||
end
|
||||
if bonus.resistance.percentage then
|
||||
entity.resistances[field].percentage = (entity.resistances[field].percentage or 0) + bonus.resistance.percentage
|
||||
if bonus.percent then
|
||||
entity.resistances[field].percent = mMin((entity.resistances[field].percent or 0) + bonus.percent, 100)
|
||||
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"]
|
||||
if bonus.mapping then
|
||||
entity.attack[bonus.name] = bonus.mapping[entity.attack[bonus.name] or "default"]
|
||||
else
|
||||
entity.attributes[attack.name] = (entity.attributes[attack.name] or 0) + attack.adjustment
|
||||
local adj = bonus.adjustment * tierMultipler
|
||||
if adj < 0 then
|
||||
adj = -adj
|
||||
adj = -gaussianRandomRangeRG(adj, adj * 0.2, adj * 0.75, adj * 1.25, xorRandom)
|
||||
else
|
||||
adj = gaussianRandomRangeRG(adj, adj * 0.2, adj * 0.75, adj * 1.25, xorRandom)
|
||||
end
|
||||
entity.attack[bonus.name] = (entity.attack[bonus.name] or 0) + adj
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -205,14 +217,12 @@ local function buildUnits(startingPoints, template, attackGenerator, upgradeTabl
|
||||
|
||||
for t=1, tiers do
|
||||
local result = {}
|
||||
|
||||
local allottedPoints = startingPoints * t
|
||||
|
||||
for i=1,variations do
|
||||
local unit = deepcopy(template)
|
||||
unit.name = unit.name .. "-v" .. i .. "-t" .. t
|
||||
unit.name = unit.name .. "-v" .. i .. "-t" .. t .. "-rampant"
|
||||
generateApperance(unit, t)
|
||||
upgradeEntity(allottedPoints, unit, upgradeTable)
|
||||
upgradeEntity(startingPoints, unit, upgradeTable, tiers)
|
||||
|
||||
local entity
|
||||
if (unit.type == "spitter") then
|
||||
@ -246,17 +256,17 @@ function swarmUtils.buildUnitSpawner(points, templates, upgradeTable, attackGene
|
||||
variations.unit,
|
||||
tiers.unit)
|
||||
|
||||
for t=1, tiers do
|
||||
for t=1, tiers.unitSpawner do
|
||||
local allottedPoints = points.unitSpawner * t
|
||||
|
||||
for i=1,variations.unitSpawner do
|
||||
local unitSpawner = deepcopy(templates.unitSpawner)
|
||||
unitSpawner.name = unitSpawner.name .. "-v" .. i .. "-t" .. t
|
||||
unitSpawner.name = unitSpawner.name .. "-v" .. i .. "-t" .. t .. "-rampant"
|
||||
local unitTable = unitSetToProbabilityTable(points.probabilityTable,
|
||||
upgradeTable.probabilityTable,
|
||||
unitSet)
|
||||
generateApperance(unitSpawner, t)
|
||||
upgradeEntity(allottedPoints, unitSpawner, upgradeTable.unitSpawner)
|
||||
upgradeEntity(allottedPoints, unitSpawner, upgradeTable.unitSpawner, t / tiers)
|
||||
|
||||
data:extend({
|
||||
makeUnitSpawner(unitSpawner.name,
|
||||
@ -275,9 +285,9 @@ function swarmUtils.buildWorm(startingPoints, template, attackGenerator, upgrade
|
||||
|
||||
for i=1,variations do
|
||||
local worm = deepcopy(template)
|
||||
worm.name = worm.name .. "-v" .. i .. "-t" .. t
|
||||
worm.name = worm.name .. "-v" .. i .. "-t" .. t .. "-rampant"
|
||||
generateApperance(worm, t)
|
||||
upgradeEntity(allottedPoints, worm, upgradeTable)
|
||||
upgradeEntity(allottedPoints, worm, upgradeTable, t / tiers)
|
||||
|
||||
data:extend({
|
||||
makeWorm(worm.name,
|
||||
|
396
UnitClasses.lua
396
UnitClasses.lua
@ -2,6 +2,16 @@
|
||||
|
||||
local biterUtils = require("prototypes/enemies/BiterUtils")
|
||||
local swarmUtils = require("SwarmUtils")
|
||||
local constants = require("libs/Constants")
|
||||
|
||||
-- constants
|
||||
|
||||
local SUICIDE_BITER_NEST_TIERS = constants.SUICIDE_BITER_NEST_TIERS
|
||||
local SUICIDE_BITER_NEST_VARIATIONS = constants.SUICIDE_BITER_NEST_VARIATIONS
|
||||
|
||||
local NEUTRAL_NEST_TIERS = constants.NEUTRAL_NEST_TIERS
|
||||
local NEUTRAL_NEST_VARIATIONS = constants.NEUTRAL_NEST_VARIATIONS
|
||||
|
||||
|
||||
-- imported functions
|
||||
|
||||
@ -10,10 +20,13 @@ local swarmUtils = require("SwarmUtils")
|
||||
local buildUnitSpawner = swarmUtils.buildUnitSpawner
|
||||
|
||||
local createSuicideAttack = biterUtils.createSuicideAttack
|
||||
local createMeleeAttack = biterUtils.createMeleeAttack
|
||||
|
||||
|
||||
-- module code
|
||||
|
||||
|
||||
-- suicide
|
||||
buildUnitSpawner(
|
||||
{
|
||||
unit = 10,
|
||||
@ -22,7 +35,7 @@ buildUnitSpawner(
|
||||
},
|
||||
{
|
||||
unit = {
|
||||
name = "rampant-suicide-biter",
|
||||
name = "suicide-biter",
|
||||
|
||||
attributes = {
|
||||
health = 30,
|
||||
@ -44,15 +57,15 @@ buildUnitSpawner(
|
||||
resistances = {
|
||||
explosion = {
|
||||
decrease = 0,
|
||||
percentage = -50
|
||||
percent = -50
|
||||
},
|
||||
laser = {
|
||||
decrease = 1,
|
||||
percentage = 0
|
||||
percent = 0
|
||||
},
|
||||
fire = {
|
||||
decrease = 0,
|
||||
percentage = -60
|
||||
percent = -60
|
||||
}
|
||||
},
|
||||
|
||||
@ -63,7 +76,7 @@ buildUnitSpawner(
|
||||
},
|
||||
|
||||
unitSpawner = {
|
||||
name = "rampant-suicide-biter-nest",
|
||||
name = "suicide-biter-nest",
|
||||
attributes = {
|
||||
health = 30,
|
||||
healing = 0.01,
|
||||
@ -77,15 +90,15 @@ buildUnitSpawner(
|
||||
resistances = {
|
||||
explosion = {
|
||||
decrease = 0,
|
||||
percentage = -50
|
||||
percent = -50
|
||||
},
|
||||
laser = {
|
||||
decrease = 1,
|
||||
percentage = 0
|
||||
percent = 0
|
||||
},
|
||||
fire = {
|
||||
decrease = 0,
|
||||
percentage = -60
|
||||
percent = -60
|
||||
}
|
||||
},
|
||||
scale = 0.95,
|
||||
@ -178,12 +191,375 @@ buildUnitSpawner(
|
||||
|
||||
{
|
||||
unit = 5,
|
||||
unitSpawner = SUICIDE_NEST_VARIATIONS
|
||||
unitSpawner = SUICIDE_BITER_NEST_VARIATIONS
|
||||
},
|
||||
|
||||
{
|
||||
unit = 10,
|
||||
unitSpawner = SUICIDE_NEST_TIERS
|
||||
unitSpawner = SUICIDE_BITER_NEST_TIERS
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
-- neutral
|
||||
buildUnitSpawner(
|
||||
{
|
||||
unit = 50,
|
||||
unitSpawner = 3,
|
||||
probabilityTable = 3
|
||||
},
|
||||
{
|
||||
unit = {
|
||||
name = "neutral-biter",
|
||||
|
||||
attributes = {
|
||||
-- health = 10,
|
||||
-- movement = 0.19,
|
||||
-- distancePerFrame = 0.08,
|
||||
-- healing = 0.01,
|
||||
explosion = "blood-explosion-small"
|
||||
},
|
||||
|
||||
attack = {
|
||||
-- damage = 3,
|
||||
-- range = 0.5,
|
||||
cooldown = 30
|
||||
},
|
||||
|
||||
resistances = {
|
||||
-- acid = {
|
||||
-- decrease = 3,
|
||||
-- percent = 20
|
||||
-- },
|
||||
},
|
||||
|
||||
type = "biter",
|
||||
scale = 0.5,
|
||||
tint1 = {r=0.56, g=0.46, b=0.42, a=0.65},
|
||||
tint2 = {r=1, g=0.63, b=0, a=0.4}
|
||||
},
|
||||
|
||||
unitSpawner = {
|
||||
name = "neutral-biter-nest",
|
||||
attributes = {
|
||||
health = 300,
|
||||
healing = 0.01,
|
||||
unitsOwned = 7,
|
||||
unitsToSpawn = 5,
|
||||
spawingCooldownStart = 360,
|
||||
spawingCooldownStop = 150,
|
||||
|
||||
},
|
||||
|
||||
resistances = {
|
||||
explosion = {
|
||||
decrease = 3,
|
||||
percent = 10
|
||||
},
|
||||
physical = {
|
||||
decrease = 1,
|
||||
percent = 10
|
||||
},
|
||||
fire = {
|
||||
decrease = 1.5,
|
||||
percent = 40
|
||||
}
|
||||
},
|
||||
scale = 1,
|
||||
tint = {r=1.0, g=1.0, b=1.0, a=1.0}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
unit = {
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "attribute",
|
||||
name = "health",
|
||||
low = 2,
|
||||
high = 500
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "movement",
|
||||
adjustment = -0.001
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "distancePerFrame",
|
||||
adjustment = 0.001
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "pollutionToAttack",
|
||||
adjustment = 50
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "attack",
|
||||
name = "damage",
|
||||
adjustment = 5
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "pollutionToAttack",
|
||||
adjustment = 20
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "attribute",
|
||||
name = "healing",
|
||||
adjustment = 0.005
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "attribute",
|
||||
name = "movement",
|
||||
adjustment = 0.02
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "distancePerFrame",
|
||||
adjustment = 0.02
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "resistance",
|
||||
name = "physical",
|
||||
decrease = 0.5,
|
||||
percent = 3
|
||||
},
|
||||
{
|
||||
type = "resistance",
|
||||
name = "explosion",
|
||||
decrease = 0.25,
|
||||
percent = 3
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "pollutionToAttack",
|
||||
adjustment = 50
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "attack",
|
||||
name = "damage",
|
||||
adjustment = 2
|
||||
},
|
||||
{
|
||||
type = "attack",
|
||||
name = "range",
|
||||
adjustment = 0.15
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "pollutionToAttack",
|
||||
adjustment = 20
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
unitSpawner = {
|
||||
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "attribute",
|
||||
name = "health",
|
||||
adjustment = 50
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "attribute",
|
||||
name = "healing",
|
||||
adjustment = 0.02
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "attribute",
|
||||
name = "spawingCooldownStart",
|
||||
adjustment = -10
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "spawingCooldownEnd",
|
||||
adjustment = -10
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "evolutionRequirement",
|
||||
adjustment = 0.01
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "attribute",
|
||||
name = "unitsOwned",
|
||||
adjustment = 2
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "unitsToSpawn",
|
||||
adjustment = 1
|
||||
},
|
||||
{
|
||||
type = "attribute",
|
||||
name = "evolutionRequirement",
|
||||
adjustment = 0.01
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
cost = 1,
|
||||
bonus = {
|
||||
{
|
||||
type = "resistance",
|
||||
name = "physical",
|
||||
decrease = 0.5,
|
||||
percent = 2
|
||||
},
|
||||
{
|
||||
type = "resistance",
|
||||
name = "explosion",
|
||||
decrease = 1,
|
||||
percent = 2
|
||||
},
|
||||
{
|
||||
type = "resistance",
|
||||
name = "fire",
|
||||
decrease = 0.7,
|
||||
percent = 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
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
|
||||
},
|
||||
{
|
||||
cost = 1,
|
||||
index = 7,
|
||||
adjustment = 1
|
||||
},
|
||||
{
|
||||
cost = 1,
|
||||
index = 8,
|
||||
adjustment = 1
|
||||
},
|
||||
{
|
||||
cost = 1,
|
||||
index = 9,
|
||||
adjustment = 1
|
||||
},
|
||||
{
|
||||
cost = 1,
|
||||
index = 10,
|
||||
adjustment = 1
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
createMeleeAttack,
|
||||
|
||||
{
|
||||
unit = 10,
|
||||
unitSpawner = NEUTRAL_NEST_VARIATIONS
|
||||
},
|
||||
|
||||
{
|
||||
unit = 10,
|
||||
unitSpawner = NEUTRAL_NEST_TIERS
|
||||
}
|
||||
)
|
||||
|
||||
for k,v in pairs(data.raw.unit) do
|
||||
print(k)
|
||||
end
|
||||
print(serpent.dump(data.raw.unit['neutral-biter-v1-t1-rampant']))
|
||||
print(serpent.dump(data.raw.unit['neutral-biter-v2-t10-rampant']))
|
||||
|
||||
print(serpent.dump(data.raw.unit['neutral-biter-v3-t1-rampant']))
|
||||
print(serpent.dump(data.raw.unit['neutral-biter-v4-t1-rampant']))
|
||||
print(serpent.dump(data.raw.unit['neutral-biter-v5-t1-rampant']))
|
||||
print(serpent.dump(data.raw.unit['neutral-biter-v6-t1-rampant']))
|
||||
print(serpent.dump(data.raw.unit['neutral-biter-v7-t1-rampant']))
|
||||
print(serpent.dump(data.raw.unit['neutral-biter-v8-t1-rampant']))
|
||||
print(serpent.dump(data.raw.unit['neutral-biter-v9-t1-rampant']))
|
||||
print(serpent.dump(data.raw.unit['neutral-biter-v10-t1-rampant']))
|
||||
|
||||
--print(serpent.dump(data.raw.unit))
|
||||
constants.et()
|
||||
|
@ -168,6 +168,9 @@ function upgrade.attempt(natives)
|
||||
for _,squad in pairs(natives.squads) do
|
||||
squad.chunk = nil
|
||||
end
|
||||
|
||||
natives.bases = {}
|
||||
natives.baseIndex = 1
|
||||
|
||||
global.regionMap = nil
|
||||
|
||||
|
180
control.lua
180
control.lua
@ -1,6 +1,6 @@
|
||||
-- imports
|
||||
|
||||
local baseUtils = require("BaseUtils")
|
||||
local baseUtils = require("libs/BaseUtils")
|
||||
local mapUtils = require("libs/MapUtils")
|
||||
local unitGroupUtils = require("libs/UnitGroupUtils")
|
||||
local chunkProcessor = require("libs/ChunkProcessor")
|
||||
@ -21,6 +21,14 @@ local config = require("config")
|
||||
|
||||
-- constants
|
||||
|
||||
local SUICIDE_BITER_NEST_TIERS = constants.SUICIDE_BITER_NEST_TIERS
|
||||
local SUICIDE_BITER_NEST_VARIATIONS = constants.SUICIDE_BITER_NEST_VARIATIONS
|
||||
local NEUTRAL_NEST_TIERS = constants.NEUTRAL_NEST_TIERS
|
||||
local NEUTRAL_NEST_VARIATIONS = constants.NEUTRAL_NEST_VARIATIONS
|
||||
|
||||
local BASE_ALIGNMENT_NEUTRAL = constants.BASE_ALIGNMENT_NEUTRAL
|
||||
local BASE_ALIGNMENT_SUICIDE = constants.BASE_ALIGNMENT_SUICIDE
|
||||
|
||||
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
|
||||
local INTERVAL_PROCESS = constants.INTERVAL_PROCESS
|
||||
local INTERVAL_CHUNK = constants.INTERVAL_CHUNK
|
||||
@ -42,6 +50,8 @@ local DEFINES_COMMAND_ATTACK_AREA = defines.command.attack_area
|
||||
|
||||
local CHUNK_SIZE = constants.CHUNK_SIZE
|
||||
|
||||
local EVOLUTION_INCREMENTS = constants.EVOLUTION_INCREMENTS
|
||||
|
||||
local DEFINES_DISTRACTION_NONE = defines.distraction.none
|
||||
local DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
|
||||
|
||||
@ -87,6 +97,7 @@ local upgradeEntity = baseUtils.upgradeEntity
|
||||
|
||||
local processBases = baseProcessor.processBases
|
||||
|
||||
local mFloor = math.floor
|
||||
local mRandom = math.random
|
||||
|
||||
-- local references to global
|
||||
@ -151,6 +162,7 @@ local function rebuildMap()
|
||||
map.processIndex = 1
|
||||
map.scanIndex = 1
|
||||
|
||||
map.chunkToBase = {}
|
||||
map.chunkToHives = {}
|
||||
map.chunkToNests = {}
|
||||
map.chunkToWorms = {}
|
||||
@ -160,6 +172,8 @@ local function rebuildMap()
|
||||
map.chunkToResource = {}
|
||||
map.chunkToPassScan = {}
|
||||
map.chunkToSquad = {}
|
||||
|
||||
natives.bases = {}
|
||||
|
||||
-- preallocating memory to be used in code, making it fast by reducing garbage generated.
|
||||
map.neighbors = { SENTINEL_IMPASSABLE_CHUNK,
|
||||
@ -219,74 +233,50 @@ local function rebuildMap()
|
||||
y = chunk.y * 32 }}})
|
||||
end
|
||||
|
||||
processPendingChunks(natives, map, surface, pendingChunks, tick)
|
||||
|
||||
|
||||
end
|
||||
|
||||
local function onModSettingsChange(event)
|
||||
|
||||
if event and (string.sub(event.setting, 1, 7) ~= "rampant") then
|
||||
return false
|
||||
end
|
||||
|
||||
upgrade.compareTable(natives, "safeBuildings", settings.global["rampant-safeBuildings"].value)
|
||||
|
||||
upgrade.compareTable(natives.safeEntities, "curved-rail", settings.global["rampant-safeBuildings-curvedRail"].value)
|
||||
upgrade.compareTable(natives.safeEntities, "straight-rail", settings.global["rampant-safeBuildings-straightRail"].value)
|
||||
upgrade.compareTable(natives.safeEntities, "rail-signal", settings.global["rampant-safeBuildings-railSignals"].value)
|
||||
upgrade.compareTable(natives.safeEntities, "rail-chain-signal", settings.global["rampant-safeBuildings-railChainSignals"].value)
|
||||
upgrade.compareTable(natives.safeEntities, "train-stop", settings.global["rampant-safeBuildings-trainStops"].value)
|
||||
upgrade.compareTable(natives.safeEntities, "lamp", settings.global["rampant-safeBuildings-lamps"].value)
|
||||
|
||||
local changed, newValue = upgrade.compareTable(natives.safeEntityName,
|
||||
"big-electric-pole",
|
||||
settings.global["rampant-safeBuildings-bigElectricPole"].value)
|
||||
if changed then
|
||||
natives.safeEntityName["big-electric-pole"] = newValue
|
||||
natives.safeEntityName["big-electric-pole-2"] = newValue
|
||||
natives.safeEntityName["big-electric-pole-3"] = newValue
|
||||
natives.safeEntityName["big-electric-pole-4"] = newValue
|
||||
end
|
||||
|
||||
upgrade.compareTable(natives, "attackUsePlayer", settings.global["rampant-attackWaveGenerationUsePlayerProximity"].value)
|
||||
upgrade.compareTable(natives, "attackUsePollution", settings.global["rampant-attackWaveGenerationUsePollution"].value)
|
||||
|
||||
upgrade.compareTable(natives, "attackThresholdMin", settings.global["rampant-attackWaveGenerationThresholdMin"].value)
|
||||
upgrade.compareTable(natives, "attackThresholdMax", settings.global["rampant-attackWaveGenerationThresholdMax"].value)
|
||||
upgrade.compareTable(natives, "attackThresholdRange", natives.attackThresholdMax - natives.attackThresholdMin)
|
||||
upgrade.compareTable(natives, "attackWaveMaxSize", settings.global["rampant-attackWaveMaxSize"].value)
|
||||
upgrade.compareTable(natives, "attackPlayerThreshold", settings.global["rampant-attackPlayerThreshold"].value)
|
||||
upgrade.compareTable(natives, "aiNocturnalMode", settings.global["rampant-permanentNocturnal"].value)
|
||||
upgrade.compareTable(natives, "aiPointsScaler", settings.global["rampant-aiPointsScaler"].value)
|
||||
|
||||
-- RE-ENABLE WHEN COMPLETE
|
||||
natives.useCustomAI = constants.DEV_CUSTOM_AI
|
||||
-- changed, newValue = upgrade.compareTable(natives, "useCustomAI", settings.startup["rampant-useCustomAI"].value)
|
||||
-- if natives.useCustomAI then
|
||||
-- game.forces.enemy.ai_controllable = false
|
||||
-- else
|
||||
-- game.forces.enemy.ai_controllable = true
|
||||
-- end
|
||||
-- if changed and newValue then
|
||||
-- rebuildMap()
|
||||
-- return false
|
||||
-- end
|
||||
return true
|
||||
processPendingChunks(natives, map, surface, pendingChunks, tick, game.forces.enemy.evolution_factor)
|
||||
end
|
||||
|
||||
local function rebuildNativeTables()
|
||||
local position = { x=0, y=0 }
|
||||
for v=1,SUICIDE_NEST_VARIATIONS do
|
||||
for t=1,SUICIDE_NEST_TIERS do
|
||||
local entity = surface.create_entity({
|
||||
name="rampant-suicide-biter-nest-v" .. v .. "-t" .. t,
|
||||
position=position
|
||||
})
|
||||
local evoRequirement = entity.prototype.build_base_evolution_requirement
|
||||
natives.evolutionTable[#natives.evolutionTable[evoRequirement]+1] = entity.name
|
||||
entity.die()
|
||||
natives.evolutionTable = {}
|
||||
|
||||
local fileEntity = function(baseAlignment, entity)
|
||||
local evoRequirement = mFloor(entity.prototype.build_base_evolution_requirement/EVOLUTION_INCREMENTS) * EVOLUTION_INCREMENTS
|
||||
local eTable = natives.evolutionTable[baseAlignment]
|
||||
if not eTable then
|
||||
eTable = {}
|
||||
natives.evolutionTable[baseAlignment] = eTable
|
||||
end
|
||||
local aTable = eTable[evoRequirement]
|
||||
if not aTable then
|
||||
aTable = {}
|
||||
eTable[evoRequirement] = aTable
|
||||
end
|
||||
aTable[#aTable+1] = entity.name
|
||||
end
|
||||
|
||||
local surface = game.surfaces[1]
|
||||
|
||||
local position = { x = 0, y = 0 }
|
||||
|
||||
for v = 1, SUICIDE_BITER_NEST_VARIATIONS do
|
||||
for t = 1, SUICIDE_BITER_NEST_TIERS do
|
||||
local entity = surface.create_entity({
|
||||
name="suicide-biter-nest-v" .. v .. "-t" .. t .. "-rampant",
|
||||
position = position
|
||||
})
|
||||
fileEntity(BASE_ALIGNMENT_SUICIDE, entity)
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
for v=1,NEUTRAL_NEST_VARIATIONS do
|
||||
for t=1,NEUTRAL_NEST_TIERS do
|
||||
local entity = surface.create_entity({
|
||||
name="neutral-biter-nest-v" .. v .. "-t" .. t .. "-rampant",
|
||||
position = position
|
||||
})
|
||||
fileEntity(BASE_ALIGNMENT_NEUTRAL, entity)
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
-- for v=1,ACID_NEST_VARIATIONS do
|
||||
-- for t=1,ACID_NEST_TIERS do
|
||||
@ -350,6 +340,60 @@ local function rebuildNativeTables()
|
||||
-- end
|
||||
end
|
||||
|
||||
local function onModSettingsChange(event)
|
||||
|
||||
if event and (string.sub(event.setting, 1, 7) ~= "rampant") then
|
||||
return false
|
||||
end
|
||||
|
||||
upgrade.compareTable(natives, "safeBuildings", settings.global["rampant-safeBuildings"].value)
|
||||
|
||||
upgrade.compareTable(natives.safeEntities, "curved-rail", settings.global["rampant-safeBuildings-curvedRail"].value)
|
||||
upgrade.compareTable(natives.safeEntities, "straight-rail", settings.global["rampant-safeBuildings-straightRail"].value)
|
||||
upgrade.compareTable(natives.safeEntities, "rail-signal", settings.global["rampant-safeBuildings-railSignals"].value)
|
||||
upgrade.compareTable(natives.safeEntities, "rail-chain-signal", settings.global["rampant-safeBuildings-railChainSignals"].value)
|
||||
upgrade.compareTable(natives.safeEntities, "train-stop", settings.global["rampant-safeBuildings-trainStops"].value)
|
||||
upgrade.compareTable(natives.safeEntities, "lamp", settings.global["rampant-safeBuildings-lamps"].value)
|
||||
|
||||
local changed, newValue = upgrade.compareTable(natives.safeEntityName,
|
||||
"big-electric-pole",
|
||||
settings.global["rampant-safeBuildings-bigElectricPole"].value)
|
||||
if changed then
|
||||
natives.safeEntityName["big-electric-pole"] = newValue
|
||||
natives.safeEntityName["big-electric-pole-2"] = newValue
|
||||
natives.safeEntityName["big-electric-pole-3"] = newValue
|
||||
natives.safeEntityName["big-electric-pole-4"] = newValue
|
||||
end
|
||||
|
||||
upgrade.compareTable(natives, "attackUsePlayer", settings.global["rampant-attackWaveGenerationUsePlayerProximity"].value)
|
||||
upgrade.compareTable(natives, "attackUsePollution", settings.global["rampant-attackWaveGenerationUsePollution"].value)
|
||||
|
||||
upgrade.compareTable(natives, "attackThresholdMin", settings.global["rampant-attackWaveGenerationThresholdMin"].value)
|
||||
upgrade.compareTable(natives, "attackThresholdMax", settings.global["rampant-attackWaveGenerationThresholdMax"].value)
|
||||
upgrade.compareTable(natives, "attackThresholdRange", natives.attackThresholdMax - natives.attackThresholdMin)
|
||||
upgrade.compareTable(natives, "attackWaveMaxSize", settings.global["rampant-attackWaveMaxSize"].value)
|
||||
upgrade.compareTable(natives, "attackPlayerThreshold", settings.global["rampant-attackPlayerThreshold"].value)
|
||||
upgrade.compareTable(natives, "aiNocturnalMode", settings.global["rampant-permanentNocturnal"].value)
|
||||
upgrade.compareTable(natives, "aiPointsScaler", settings.global["rampant-aiPointsScaler"].value)
|
||||
|
||||
if upgrade.compareTable(natives, "enemySeed", settings.startup["rampant-enemySeed"].value) then
|
||||
rebuildNativeTables()
|
||||
end
|
||||
-- RE-ENABLE WHEN COMPLETE
|
||||
natives.useCustomAI = constants.DEV_CUSTOM_AI
|
||||
-- changed, newValue = upgrade.compareTable(natives, "useCustomAI", settings.startup["rampant-useCustomAI"].value)
|
||||
-- if natives.useCustomAI then
|
||||
-- game.forces.enemy.ai_controllable = false
|
||||
-- else
|
||||
-- game.forces.enemy.ai_controllable = true
|
||||
-- end
|
||||
-- if changed and newValue then
|
||||
-- rebuildMap()
|
||||
-- return false
|
||||
-- end
|
||||
return true
|
||||
end
|
||||
|
||||
local function onConfigChanged()
|
||||
local upgraded
|
||||
upgraded, natives = upgrade.attempt(natives)
|
||||
@ -375,7 +419,7 @@ local function onTick(event)
|
||||
map.scanTick = map.scanTick + INTERVAL_SCAN
|
||||
local surface = game.surfaces[1]
|
||||
|
||||
processPendingChunks(natives, map, surface, pendingChunks, tick)
|
||||
processPendingChunks(natives, map, surface, pendingChunks, tick, game.forces.enemy.evolution_factor)
|
||||
|
||||
scanMap(map, surface, natives)
|
||||
|
||||
@ -505,7 +549,7 @@ local function onEnemyBaseBuild(event)
|
||||
local surface = entity.surface
|
||||
if (surface.index == 1) then
|
||||
entity = upgradeEntity(map, entity, surface, natives)
|
||||
event.entity = registerEnemyBaseStructure(map, entity)
|
||||
event.entity = registerEnemyBaseStructure(map, entity, natives, game.forces.enemy.evolution_factor, surface, event.tick)
|
||||
end
|
||||
end
|
||||
|
||||
@ -613,12 +657,14 @@ remote.add_interface("rampantTests",
|
||||
gaussianRandomTest = tests.gaussianRandomTest,
|
||||
reveal = tests.reveal,
|
||||
showMovementGrid = tests.showMovementGrid,
|
||||
showBaseGrid = tests.showBaseGrid,
|
||||
baseStats = tests.baseStats,
|
||||
mergeBases = tests.mergeBases,
|
||||
clearBases = tests.clearBases,
|
||||
getOffsetChunk = tests.getOffsetChunk,
|
||||
registeredNest = tests.registeredNest,
|
||||
colorResourcePoints = tests.colorResourcePoints,
|
||||
entityStats = tests.entityStats,
|
||||
stepAdvanceTendrils = tests.stepAdvanceTendrils,
|
||||
exportAiState = tests.exportAiState(onTick)
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ function baseProcessor.processBases(map, surface, natives, tick)
|
||||
for index = baseIndex, endIndex do
|
||||
local base = bases[index]
|
||||
|
||||
if base.created then
|
||||
end
|
||||
|
||||
-- buildOrder(map, natives, base, surface, tick)
|
||||
-- advanceTendrils(map, base, surface, tick, natives)
|
||||
|
@ -11,23 +11,31 @@ local chunkPropertyUtils = require("ChunkPropertyUtils")
|
||||
-- constants
|
||||
|
||||
local BASE_DISTANCE_THRESHOLD = constants.BASE_DISTANCE_THRESHOLD
|
||||
local BASE_DISTANCE_LEVEL_BONUS = constants.BASE_DISTANCE_LEVEL_BONUS
|
||||
|
||||
local BASE_ALIGNMENT_NEUTRAL = constants.BASE_ALIGNMENT_NEUTRAL
|
||||
|
||||
local CHUNK_SIZE = constants.CHUNK_SIZE
|
||||
|
||||
local EVOLUTION_INCREMENTS = constants.EVOLUTION_INCREMENTS
|
||||
|
||||
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER
|
||||
local MAGIC_MAXIMUM_BASE_NUMBER = constants.MAGIC_MAXIMUM_BASE_NUMBER
|
||||
|
||||
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||
|
||||
-- imported functions
|
||||
|
||||
local euclideanDistancePoints = mathUtils.euclideanDistancePoints
|
||||
|
||||
local isRampant = stringUtils.isRampant
|
||||
|
||||
local gaussianRandomRange = mathUtils.gaussianRandomRange
|
||||
|
||||
local mFloor = math.floor
|
||||
|
||||
local positionToChunkXY = mapUtils.positionToChunkXY
|
||||
local getChunkByPosition = mapUtils.getChunkByPosition
|
||||
local getChunkByXY = mapUtils.getChunkByXY
|
||||
local getChunkBase = chunkPropertyUtils.getChunkBase
|
||||
local setChunkBase = chunkPropertyUtils.setChunkBase
|
||||
|
||||
@ -36,6 +44,12 @@ local mRandom = math.random
|
||||
-- module code
|
||||
|
||||
function baseUtils.findNearbyBase(map, chunk, chunkRadius)
|
||||
if (chunk == SENTINEL_IMPASSABLE_CHUNK) then
|
||||
return nil
|
||||
end
|
||||
|
||||
local tested = {}
|
||||
|
||||
local x = chunk.x
|
||||
local y = chunk.y
|
||||
|
||||
@ -48,12 +62,15 @@ function baseUtils.findNearbyBase(map, chunk, chunkRadius)
|
||||
for xi = x-chunkRadius, x+chunkRadius, CHUNK_SIZE do
|
||||
for yi = y-chunkRadius, y+chunkRadius, CHUNK_SIZE do
|
||||
if (xi ~= x) and (yi ~= y) then
|
||||
local base = getChunkBase(map, positionToChunkXY(map, xi, yi))
|
||||
local base = getChunkBase(map, getChunkByXY(map, xi, yi))
|
||||
if base then
|
||||
local distance = euclideanDistancePoints(base.x, base.y, x, y)
|
||||
if (distance <= (BASE_DISTANCE_THRESHOLD + (base.level * 100))) and (distance < closest) then
|
||||
closest = distance
|
||||
foundBase = base
|
||||
if not tested[base] then
|
||||
tested[base] = true
|
||||
local distance = euclideanDistancePoints(base.x, base.y, x, y)
|
||||
if (distance <= (BASE_DISTANCE_THRESHOLD + (base.level * BASE_DISTANCE_LEVEL_BONUS))) and (distance < closest) then
|
||||
closest = distance
|
||||
foundBase = base
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -63,20 +80,52 @@ function baseUtils.findNearbyBase(map, chunk, chunkRadius)
|
||||
return foundBase
|
||||
end
|
||||
|
||||
local function findUpgrade(base, evoIndex, natives)
|
||||
local used = { }
|
||||
local alignments = base.alignments
|
||||
|
||||
local alignmentPick = base.alignments[mRandom(#base.alignments)]
|
||||
|
||||
while alignmentPick do
|
||||
used[alignmentPick] = true
|
||||
|
||||
for evo=evoIndex, 0, -EVOLUTION_INCREMENTS do
|
||||
local entitySet = natives.evolutionTable[alignmentPick][evo]
|
||||
if (#entitySet > 0) then
|
||||
return entitySet[mRandom(#entitySet)]
|
||||
end
|
||||
end
|
||||
|
||||
alignmentPick = nil
|
||||
for x = #alignments, 1, -1 do
|
||||
if not used[alignments[x]] then
|
||||
alignmentPick = alignments[x]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
function baseUtils.upgradeEntity(map, entity, surface, natives, evolutionFactor, tick)
|
||||
if not isRampant(entity.name) then
|
||||
local position = entity.position
|
||||
entity.die()
|
||||
local chunk = positionToChunkXY(map, position)
|
||||
local chunk = getChunkByPosition(map, position)
|
||||
local base = getChunkBase(map, chunk)
|
||||
|
||||
if not base then
|
||||
baseUtils.createBase(map, natives, evolutionFactor, chunk, surface, tick)
|
||||
end
|
||||
|
||||
entity = surface.creaate_entity({name = "rampant-suicide-nest-v" .. mRandom(5) .. "-t1",
|
||||
position = position})
|
||||
|
||||
-- local distance = euclideanDistancePoints(position.x, position.y, 0, 0)
|
||||
local evoIndex = mFloor(evolutionFactor/EVOLUTION_INCREMENTS) * EVOLUTION_INCREMENTS
|
||||
|
||||
local spawnerName = findUpgrade(base, evoIndex, natives)
|
||||
if spawnerName then
|
||||
entity = surface.create_entity({name = spawnerName, position = position})
|
||||
end
|
||||
end
|
||||
|
||||
return entity
|
||||
@ -86,13 +135,19 @@ function baseUtils.createBase(map, natives, evolutionFactor, chunk, surface, tic
|
||||
local x = chunk.x
|
||||
local y = chunk.y
|
||||
local distance = euclideanDistancePoints(x, y, 0, 0)
|
||||
|
||||
local meanLevel = mFloor(distance / 200)
|
||||
|
||||
local alignments = { BASE_ALIGNMENT_NEUTRAL }
|
||||
|
||||
local base = {
|
||||
x = x,
|
||||
y = y,
|
||||
created = tick,
|
||||
alignment = { BASE_ALIGNMENT_NEUTRAL },
|
||||
evolution = evolutionFactor,
|
||||
alignments = alignments,
|
||||
pattern = mRandom(MAGIC_MAXIMUM_BASE_NUMBER),
|
||||
level = mFloor(distance / 200)
|
||||
level = gaussianRandomRange(meanLevel, meanLevel * 0.15, meanLevel * 0.50, meanLevel * 1.50)
|
||||
}
|
||||
|
||||
setChunkBase(map, chunk, base)
|
||||
@ -101,7 +156,7 @@ function baseUtils.createBase(map, natives, evolutionFactor, chunk, surface, tic
|
||||
-- return nil
|
||||
-- end
|
||||
|
||||
natives.bases[natives.bases+1] = base
|
||||
natives.bases[#natives.bases+1] = base
|
||||
|
||||
return base
|
||||
end
|
||||
|
@ -19,7 +19,7 @@ local chunkPassScan = chunkUtils.chunkPassScan
|
||||
|
||||
-- module code
|
||||
|
||||
function chunkProcessor.processPendingChunks(natives, map, surface, pendingStack, tick)
|
||||
function chunkProcessor.processPendingChunks(natives, map, surface, pendingStack, tick, evolutionFactor)
|
||||
local processQueue = map.processQueue
|
||||
|
||||
local area = map.area
|
||||
@ -41,7 +41,7 @@ function chunkProcessor.processPendingChunks(natives, map, surface, pendingStack
|
||||
bottomOffset[1] = x + CHUNK_SIZE
|
||||
bottomOffset[2] = y + CHUNK_SIZE
|
||||
|
||||
chunk = initialScan(chunk, natives, surface, map, tick)
|
||||
chunk = initialScan(chunk, natives, surface, map, tick, evolutionFactor)
|
||||
|
||||
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
local chunkX = chunk.x
|
||||
|
@ -41,12 +41,23 @@ local RESOURCE_GENERATOR_INCREMENT = constants.RESOURCE_GENERATOR_INCREMENT
|
||||
|
||||
-- imported functions
|
||||
|
||||
local setNestCount = chunkPropertyUtils.setNestCount
|
||||
local setPlayerBaseGenerator = chunkPropertyUtils.setPlayerBaseGenerator
|
||||
local addPlayerBaseGenerator = chunkPropertyUtils.addPlayerBaseGenerator
|
||||
local setResourceGenerator = chunkPropertyUtils.setResourceGenerator
|
||||
local addResourceGenerator = chunkPropertyUtils.addResourceGenerator
|
||||
local setWormCount = chunkPropertyUtils.setWormCount
|
||||
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator
|
||||
local getNestCount = chunkPropertyUtils.getNestCount
|
||||
|
||||
local findNearbyBase = baseUtils.findNearbyBase
|
||||
local createBase = baseUtils.createBase
|
||||
|
||||
local setChunkBase = chunkPropertyUtils.setChunkBase
|
||||
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount
|
||||
|
||||
local getChunkByUnalignedXY = mapUtils.getChunkByUnalignedXY
|
||||
local getChunkByPosition = mapUtils.getChunkByPosition
|
||||
|
||||
local mFloor = math.floor
|
||||
|
||||
@ -85,7 +96,7 @@ local function fullScan(chunk, can_place_entity, canPlaceQuery)
|
||||
return passableNorthSouth, passableEastWest
|
||||
end
|
||||
|
||||
local function addEnemyStructureToChunk(map, chunk, entity)
|
||||
local function addEnemyStructureToChunk(map, chunk, entity, base)
|
||||
local lookup
|
||||
if (entity.type == "unit-spawner") then
|
||||
lookup = map.chunkToNests
|
||||
@ -101,15 +112,7 @@ local function addEnemyStructureToChunk(map, chunk, entity)
|
||||
end
|
||||
lookup[chunk] = lookup[chunk] + 1
|
||||
|
||||
-- if base then
|
||||
-- local baseCollection = map.chunkToBases[chunk]
|
||||
-- if not baseCollection then
|
||||
-- baseCollection = {}
|
||||
-- map.chunkToBases[chunk] = baseCollection
|
||||
-- end
|
||||
-- baseCollection[base.id] = chunk
|
||||
-- end
|
||||
|
||||
setChunkBase(map, chunk, base)
|
||||
end
|
||||
|
||||
local function removeEnemyStructureFromChunk(map, chunk, entity)
|
||||
@ -122,20 +125,9 @@ local function removeEnemyStructureFromChunk(map, chunk, entity)
|
||||
return
|
||||
end
|
||||
|
||||
-- local base = indexChunk[entity.unit_number]
|
||||
-- local indexBase
|
||||
-- if base then
|
||||
-- if (entity.type == "unit-spawner") then
|
||||
-- if base.hives[entity.unit_number] then
|
||||
-- indexBase = base.hives
|
||||
-- else
|
||||
-- indexBase = base.nests
|
||||
-- end
|
||||
-- elseif (entity.type == "turret") then
|
||||
-- indexBase = base.worms
|
||||
-- end
|
||||
-- indexBase[entity.unit_number] = nil
|
||||
-- end
|
||||
if (getEnemyStructureCount(map, chunk) == 0) then
|
||||
setChunkBase(map, chunk, nil)
|
||||
end
|
||||
|
||||
if lookup[chunk] then
|
||||
if ((lookup[chunk] - 1) <= 0) then
|
||||
@ -297,10 +289,10 @@ function chunkUtils.initialScan(chunk, natives, surface, map, tick, evolutionFac
|
||||
end
|
||||
end
|
||||
|
||||
chunkUtils.setNestCount(map, chunk, nests)
|
||||
chunkUtils.setPlayerBaseGenerator(map, chunk, playerObjects)
|
||||
chunkUtils.setResourceGenerator(map, chunk, resources)
|
||||
chunkUtils.setWormCount(map, chunk, worms)
|
||||
setNestCount(map, chunk, nests)
|
||||
setPlayerBaseGenerator(map, chunk, playerObjects)
|
||||
setResourceGenerator(map, chunk, resources)
|
||||
setWormCount(map, chunk, worms)
|
||||
|
||||
chunk[PASSABLE] = pass
|
||||
chunk[PATH_RATING] = passScore
|
||||
@ -317,9 +309,9 @@ function chunkUtils.chunkPassScan(chunk, surface, map)
|
||||
if (passScore >= 0.40) then
|
||||
local pass = chunkUtils.scanChunkPaths(chunk, surface, map)
|
||||
|
||||
local playerObjects = chunkUtils.getPlayerBaseGenerator(map, chunk)
|
||||
local playerObjects = getPlayerBaseGenerator(map, chunk)
|
||||
|
||||
local nests = chunkUtils.getNestCount(map, chunk)
|
||||
local nests = getNestCount(map, chunk)
|
||||
|
||||
if ((playerObjects > 0) or (nests > 0)) and (pass == CHUNK_IMPASSABLE) then
|
||||
pass = CHUNK_ALL_DIRECTIONS
|
||||
@ -336,7 +328,7 @@ end
|
||||
|
||||
function chunkUtils.analyzeChunk(chunk, natives, surface, map)
|
||||
local playerObjects = chunkUtils.scorePlayerBuildings(surface, map, natives)
|
||||
chunkUtils.setPlayerBaseGenerator(map, chunk, playerObjects)
|
||||
setPlayerBaseGenerator(map, chunk, playerObjects)
|
||||
end
|
||||
|
||||
function chunkUtils.createChunk(topX, topY)
|
||||
@ -382,22 +374,31 @@ function chunkUtils.entityForPassScan(map, entity)
|
||||
end
|
||||
end
|
||||
|
||||
function chunkUtils.registerEnemyBaseStructure(map, entity)
|
||||
function chunkUtils.registerEnemyBaseStructure(map, entity, natives, evolutionFactor, surface, tick)
|
||||
local entityType = entity.type
|
||||
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
|
||||
local chunk = getChunkByPosition(map, entity.position)
|
||||
local base
|
||||
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
base = findNearbyBase(map, chunk, BASE_SEARCH_RADIUS)
|
||||
if not base then
|
||||
base = createBase(map, natives, evolutionFactor, chunk, surface, tick)
|
||||
end
|
||||
end
|
||||
|
||||
local leftTop, rightTop, leftBottom, rightBottom = getEntityOverlapChunks(map, entity)
|
||||
|
||||
if (leftTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
addEnemyStructureToChunk(map, leftTop, entity)
|
||||
addEnemyStructureToChunk(map, leftTop, entity, base)
|
||||
end
|
||||
if (rightTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
addEnemyStructureToChunk(map, rightTop, entity)
|
||||
addEnemyStructureToChunk(map, rightTop, entity, base)
|
||||
end
|
||||
if (leftBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
addEnemyStructureToChunk(map, leftBottom, entity)
|
||||
addEnemyStructureToChunk(map, leftBottom, entity, base)
|
||||
end
|
||||
if (rightBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
addEnemyStructureToChunk(map, rightBottom, entity)
|
||||
addEnemyStructureToChunk(map, rightBottom, entity, base)
|
||||
end
|
||||
end
|
||||
|
||||
@ -411,27 +412,15 @@ function chunkUtils.unregisterEnemyBaseStructure(map, entity)
|
||||
|
||||
if (leftTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
removeEnemyStructureFromChunk(map, leftTop, entity)
|
||||
if getEnemyStructureCount(map, leftTop) == 0 then
|
||||
setChunkBase(map, leftTop, nil)
|
||||
end
|
||||
end
|
||||
if (rightTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
removeEnemyStructureFromChunk(map, rightTop, entity)
|
||||
if getEnemyStructureCount(map, rightTop) == 0 then
|
||||
setChunkBase(map, rightTop, nil)
|
||||
end
|
||||
end
|
||||
if (leftBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
removeEnemyStructureFromChunk(map, leftBottom, entity)
|
||||
if getEnemyStructureCount(map, leftBottom) == 0 then
|
||||
setChunkBase(map, leftBottom, nil)
|
||||
end
|
||||
end
|
||||
if (rightBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
removeEnemyStructureFromChunk(map, rightBottom, entity)
|
||||
if getEnemyStructureCount(map, rightBottom) == 0 then
|
||||
setChunkBase(map, rightBottom, nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -450,16 +439,16 @@ function chunkUtils.addRemovePlayerEntity(map, entity, natives, addObject, credi
|
||||
entityValue = -entityValue
|
||||
end
|
||||
if (leftTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
chunkUtils.addPlayerBaseGenerator(map, leftTop, entityValue)
|
||||
addPlayerBaseGenerator(map, leftTop, entityValue)
|
||||
end
|
||||
if (rightTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
chunkUtils.addPlayerBaseGenerator(map, rightTop, entityValue)
|
||||
addPlayerBaseGenerator(map, rightTop, entityValue)
|
||||
end
|
||||
if (leftBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
chunkUtils.addPlayerBaseGenerator(map, leftBottom, entityValue)
|
||||
addPlayerBaseGenerator(map, leftBottom, entityValue)
|
||||
end
|
||||
if (rightBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
chunkUtils.addPlayerBaseGenerator(map, rightBottom, entityValue)
|
||||
addPlayerBaseGenerator(map, rightBottom, entityValue)
|
||||
end
|
||||
end
|
||||
return entity
|
||||
@ -472,16 +461,16 @@ function chunkUtils.unregisterResource(entity, map)
|
||||
local leftTop, rightTop, leftBottom, rightBottom = getEntityOverlapChunks(map, entity)
|
||||
|
||||
if (leftTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
chunkUtils.addResourceGenerator(map, leftTop, -RESOURCE_GENERATOR_INCREMENT)
|
||||
addResourceGenerator(map, leftTop, -RESOURCE_GENERATOR_INCREMENT)
|
||||
end
|
||||
if (rightTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
chunkUtils.addResourceGenerator(map, rightTop, -RESOURCE_GENERATOR_INCREMENT)
|
||||
addResourceGenerator(map, rightTop, -RESOURCE_GENERATOR_INCREMENT)
|
||||
end
|
||||
if (leftBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
chunkUtils.addResourceGenerator(map, leftBottom, -RESOURCE_GENERATOR_INCREMENT)
|
||||
addResourceGenerator(map, leftBottom, -RESOURCE_GENERATOR_INCREMENT)
|
||||
end
|
||||
if (rightBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||
chunkUtils.addResourceGenerator(map, rightBottom, -RESOURCE_GENERATOR_INCREMENT)
|
||||
addResourceGenerator(map, rightBottom, -RESOURCE_GENERATOR_INCREMENT)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -64,6 +64,7 @@ constants.CHUNK_ALL_DIRECTIONS = 3
|
||||
-- constants.CHUNK_PLAYER_INTERIOR = 5
|
||||
|
||||
constants.BASE_SEARCH_RADIUS = 4 * constants.CHUNK_SIZE
|
||||
constants.EVOLUTION_INCREMENTS = 0.05
|
||||
|
||||
-- ai
|
||||
|
||||
@ -97,13 +98,37 @@ constants.AI_MAX_TEMPERAMENT_DURATION = 15
|
||||
|
||||
-- ai base
|
||||
|
||||
constants.BASE_DISTANCE_THRESHOLD = 15 * constants.CHUNK_SIZE
|
||||
constants.BASE_DISTANCE_THRESHOLD = 40 * constants.CHUNK_SIZE
|
||||
constants.BASE_DISTANCE_LEVEL_BONUS = 300
|
||||
|
||||
constants.BASE_ALIGNMENT_NEUTRAL = 1
|
||||
constants.BASE_ALIGNMENT_FIRE = 2
|
||||
constants.BASE_ALIGNMENT_BURROW = 3
|
||||
constants.BASE_ALIGNMENT_SUICIDE = 4
|
||||
constants.BASE_ALIGNMENT_INFEST = 5
|
||||
constants.BASE_ALIGNMENT_ACID = 6
|
||||
constants.BASE_ALIGNMENT_FIRE = 7
|
||||
constants.BASE_ALIGNMENT_PHYSICAL = 8
|
||||
constants.BASE_ALIGNMENT_LASER = 9
|
||||
constants.BASE_ALIGNMENT_INFERNO = 10
|
||||
constants.BASE_ALIGNMENT_POSION = 11
|
||||
constants.BASE_ALIGNMENT_TROLL = 12
|
||||
constants.BASE_ALIGNMENT_FAST = 13
|
||||
constants.BASE_ALIGNMENT_WEB = 14
|
||||
constants.BASE_ALIGNMENT_DECAYING = 15
|
||||
constants.BASE_ALIGNMENT_UNDYING = 16
|
||||
constants.BASE_ALIGNMENT_NEUTRAL_ADVANCED = 17
|
||||
constants.BASE_ALIGNMENT_ENERGY_THIEF = 18
|
||||
constants.BASE_ALIGNMENT_ELECTRIC = 19
|
||||
|
||||
local neutralPath = {}
|
||||
neutralPath[constants.BASE_ALIGNMENT_ACID] = true
|
||||
neutralPath[constants.BASE_ALIGNMENT_FIRE] = true
|
||||
neutralPath[constants.BASE_ALIGNMENT_PHYSICAL] = true
|
||||
neutralPath[constants.BASE_ALIGNMENT_LASER] = true
|
||||
|
||||
constants.BASE_ALIGNMENT_PATHS = {}
|
||||
constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_NEUTRAL] = neutralPath
|
||||
|
||||
-- ai retreat
|
||||
|
||||
@ -228,7 +253,13 @@ constants.SENTINEL_IMPASSABLE_CHUNK.y = -1
|
||||
|
||||
-- unit spawners
|
||||
|
||||
constants.SUICIDE_NEST_TIERS = 7
|
||||
constants.SUICIDE_NEST_VARIATIONS = 5
|
||||
constants.SUICIDE_BITER_NEST_TIERS = 7
|
||||
constants.SUICIDE_BITER_NEST_VARIATIONS = 5
|
||||
|
||||
constants.NEUTRAL_NEST_TIERS = 7
|
||||
constants.NEUTRAL_NEST_VARIATIONS = 20
|
||||
|
||||
constants.ACID_NEST_TIERS = 7
|
||||
constants.ACID_NEST_VARIATIONS = 5
|
||||
|
||||
return constants
|
||||
|
@ -43,7 +43,7 @@ function mapUtils.getChunkByPosition(map, position)
|
||||
end
|
||||
|
||||
function mapUtils.getChunkByUnalignedXY(map, x, y)
|
||||
local chunkX = map[mFloor(x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE]
|
||||
local chunkX = map[mFloor(x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE]
|
||||
if chunkX then
|
||||
local chunkY = mFloor(y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
|
||||
return chunkX[chunkY] or SENTINEL_IMPASSABLE_CHUNK
|
||||
|
@ -117,7 +117,7 @@ function mathUtils.gaussianRandomRangeRG(mean, std_dev, min, max, rg)
|
||||
repeat
|
||||
iid1 = 2 * rg() + -1
|
||||
iid2 = 2 * rg() + -1
|
||||
q = (iid1 * iid1) + (iid2 * iid2)
|
||||
q = (iid1 * iid1) + (iid2 * iid2)
|
||||
until (q ~= 0) and (q < 1)
|
||||
local s = mSqrt((-2 * mLog10(q)) / q)
|
||||
local v = iid1 * s
|
||||
|
@ -27,6 +27,7 @@ function biterFunctions.makeBiter(name, biterAttributes, biterAttack, biterResis
|
||||
attack_parameters = biterAttack,
|
||||
vision_distance = biterAttributes.vision or 30,
|
||||
movement_speed = biterAttributes.movement,
|
||||
spawning_time_modifier = biterAttributes.spawningTimeModifer or 0,
|
||||
distance_per_frame = biterAttributes.distancePerFrame or 0.1,
|
||||
pollution_to_join_attack = biterAttributes.pollutionToAttack or 200,
|
||||
distraction_cooldown = biterAttributes.distractionCooldown or 300,
|
||||
@ -65,6 +66,7 @@ function biterFunctions.makeSpitter(name, biterAttributes, biterAttack, biterRes
|
||||
attack_parameters = biterAttack,
|
||||
vision_distance = biterAttributes.vision or 30,
|
||||
movement_speed = biterAttributes.movement,
|
||||
spawning_time_modifier = biterAttributes.spawningTimeModifer or 0,
|
||||
distance_per_frame = biterAttributes.distancePerFrame or 0.1,
|
||||
pollution_to_join_attack = biterAttributes.pollutionToAttack or 200,
|
||||
distraction_cooldown = biterAttributes.distractionCooldown or 300,
|
||||
@ -306,6 +308,35 @@ function biterFunctions.findTint(entity)
|
||||
return entity.run_animation.layers[2].tint
|
||||
end
|
||||
|
||||
function biterFunctions.createMeleeAttack(attributes)
|
||||
return
|
||||
{
|
||||
type = "projectile",
|
||||
range = attributes.range or 0.5,
|
||||
cooldown = attributes.cooldown or 30,
|
||||
ammo_category = "melee",
|
||||
ammo_type = {
|
||||
category = "melee",
|
||||
target_type = "entity",
|
||||
action =
|
||||
{
|
||||
type = "direct",
|
||||
action_delivery =
|
||||
{
|
||||
type = "instant",
|
||||
target_effects =
|
||||
{
|
||||
type = "damage",
|
||||
damage = { amount = attributes.damage, type = "physical"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
sound = make_biter_roars(0.4),
|
||||
animation = biterattackanimation(attributes.scale, attributes.tint1, attributes.tint2)
|
||||
}
|
||||
end
|
||||
|
||||
function biterFunctions.createFireAttack(attributes, fireAttack)
|
||||
local attack = {
|
||||
type = "stream",
|
||||
|
34
tests.lua
34
tests.lua
@ -270,6 +270,29 @@ function tests.mergeBases()
|
||||
baseUtils.mergeBases(natives)
|
||||
end
|
||||
|
||||
function tests.showBaseGrid()
|
||||
local n = {}
|
||||
|
||||
for k,v in pairs(global.natives.bases) do
|
||||
n[v] = k % 5
|
||||
end
|
||||
|
||||
local chunks = global.map.chunkToBase
|
||||
for chunk,base in pairs(chunks) do
|
||||
local pick = n[base]
|
||||
local color = "concrete"
|
||||
if (pick == 1) then
|
||||
color = "hazard-concrete-left"
|
||||
elseif (pick == 2) then
|
||||
color = "deepwater"
|
||||
elseif (pick == 3) then
|
||||
color = "water-green"
|
||||
elseif (pick == 4) then
|
||||
color = "water"
|
||||
end
|
||||
chunkUtils.colorChunk(chunk.x, chunk.y, color, game.surfaces[1])
|
||||
end
|
||||
end
|
||||
|
||||
function tests.showMovementGrid()
|
||||
local chunks = global.map.processQueue
|
||||
@ -303,6 +326,17 @@ function tests.colorResourcePoints()
|
||||
end
|
||||
end
|
||||
|
||||
function tests.entityStats(name, d)
|
||||
local playerPosition = game.players[1].position
|
||||
local chunkX = math.floor(playerPosition.x * 0.03125) * 32
|
||||
local chunkY = math.floor(playerPosition.y * 0.03125) * 32
|
||||
local a = game.surfaces[1].create_entity({name=name, position={chunkX, chunkY}})
|
||||
if d then
|
||||
a['direction'] = d
|
||||
end
|
||||
print(serpent.dump(a))
|
||||
a.destroy()
|
||||
end
|
||||
|
||||
function tests.exportAiState(onTick)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user