1
0
mirror of https://github.com/veden/Rampant.git synced 2024-12-26 20:54:12 +02:00

working hives

This commit is contained in:
Aaron Veden 2019-11-29 16:49:22 -08:00
parent af99d18d3f
commit b6bbd36d7d
28 changed files with 1570 additions and 1663 deletions

View File

@ -211,10 +211,7 @@ function upgrade.attempt(natives, setNewSurface)
base.state = BASE_AI_STATE_DORMANT
base.stateTick = 0
base.alignment = {base.alignment}
end
natives.nextChunkSort = 0
natives.nextChunkSortTick = 0
end
global.version = constants.VERSION_72
end
@ -298,17 +295,24 @@ function upgrade.attempt(natives, setNewSurface)
natives.ENEMY_VARIATIONS = settings.startup["rampant-newEnemyVariations"].value
natives.baseOrdering = {}
natives.baseOrdering.len = 0
-- natives.baseOrdering = {}
-- natives.baseOrdering.len = 0
natives.evolutionTableBiterSpawner = {}
natives.evolutionTableSpitterSpawner = {}
natives.evolutionTableOutpost = {}
natives.evolutionTableHive = {}
natives.evolutionTableTrap = {}
natives.evolutionTableTurret = {}
natives.evolutionTableUtility = {}
-- natives.evolutionTable = {}
-- natives.evolutionAlignmentTable = {}
-- natives.evolutionTableSpitterSpawner = {}
-- natives.evolutionTableOutpost = {}
-- natives.evolutionTableHive = {}
-- natives.evolutionTableTrap = {}
-- natives.evolutionTableTurret = {}
-- natives.evolutionTableUtility = {}
natives.nextChunkSort = nil
natives.nextChunkSortTick = nil
natives.evolutionLevel = game.forces.enemy.evolution_factor
natives.evolutionTableUnitSpawner = nil
natives.evolutionTableWorm = nil

View File

@ -1,6 +1,8 @@
---------------------------------------------------------------------------------------------------
Version: 0.17.29
Date: 11. 12. 2019
Date: 11. 29. 2019
Features:
- Hives that can produce unit spawners, turrets, or more hives. Typically appear on resources patches.
Improvements:
- Pathfinding now looks two steps ahead
- Squad formation now has a gathering delay to allow all members to make the initial group
@ -16,6 +18,12 @@ Date: 11. 12. 2019
- Added blood explosions to each new enemy
- Nuclear biters have more visual explosions
- Changed poison biter death cloud to be generated using dying_trigger_effect
- Reduced sticker damage and duration everywhere
- Switched general spit projectile from direction only to positional targeting
- Added spit projectile stickers to tooltip
- Default for new enemies spit projectile stickers no longer do damage only slow
- Spawner spitter and worm eggs now damage the immediate area around the egg
- Acid pools no longer cause friendly fire
Optimizations:
- Better object reuse for squad and pending attack, creating less garbage
- Trimmed table creation where possible
@ -38,7 +46,9 @@ Date: 11. 12. 2019
- Fixed enemy volume not changing based on tier
- Fixed Nuclear and Suicide spawners instantly spawning low level units
- Fixed Physical and troll spawner and worm scales
- Fixed chunk processing not checking chunk generation status
Framework:
- Bobs enemies and Natural Evolution Enemies no longer able to be active with Rampant's new enemies
- Cleaned up new enemy creation
- Dropped support for 5 tier new enemy configuration
- Changed default blood particle removal optimization to off

View File

@ -151,7 +151,7 @@ local function onIonCannonFired(event)
natives.points = natives.points + 3000
local chunk = getChunkByPosition(map, event.position)
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
rallyUnits(chunk, map, surface, natives, event.tick)
rallyUnits(chunk, map, surface, event.tick)
end
end
end
@ -160,8 +160,6 @@ local function hookEvents()
if config.ionCannonPresent then
script.on_event(remote.call("orbital_ion_cannon", "on_ion_cannon_fired"),
onIonCannonFired)
-- script.on_event(remote.call("orbital_ion_cannon", "on_ion_cannon_targeted"),
-- onIonCannonTargeted)
end
end
@ -170,12 +168,6 @@ local function onLoad()
natives = global.natives
pendingChunks = global.pendingChunks
-- print(serpent.dump(global))
-- print(serpent.dump(map.chunkToSquad))
-- print(serpent.dump(natives))
-- print(serpent.dump(natives.squads))
-- print(serpent.dump(natives.bases))
hookEvents()
end
@ -193,8 +185,6 @@ local function rebuildMap()
-- prevents queue adding duplicate chunks
-- chunks are by key, so should overwrite old
-- game.forces.enemy.kill_all_units()
global.map = {}
map = global.map
map.processQueue = {}
@ -203,7 +193,10 @@ local function rebuildMap()
map.chunkToBase = {}
map.chunkToNests = {}
map.chunkToWorms = {}
map.chunkToTurrets = {}
map.chunkToTraps = {}
map.chunkToUtilities = {}
map.chunkToHives = {}
map.chunkToPlayerBase = {}
map.chunkToResource = {}
@ -212,7 +205,6 @@ local function rebuildMap()
map.chunkToRetreats = {}
map.chunkToRallys = {}
-- map.chunkToSpawner = {}
map.chunkToSettler = {}
map.chunkToPassable = {}
@ -222,7 +214,8 @@ local function rebuildMap()
map.chunkToActiveNest = {}
map.chunkToActiveRaidNest = {}
-- map.queueSpawners = {}
map.nextChunkSort = 0
map.nextChunkSortTick = 0
-- preallocating memory to be used in code, making it fast by reducing garbage generated.
map.neighbors = {
@ -262,7 +255,7 @@ local function rebuildMap()
SENTINEL_IMPASSABLE_CHUNK,
SENTINEL_IMPASSABLE_CHUNK
}
map.mapOrdering = {}
map.mapOrdering.len = 0
map.enemiesToSquad = {}
@ -283,11 +276,19 @@ local function rebuildMap()
map.filteredEntitiesUnitQuery = { area=map.area, force="enemy",type="unit" }
map.filteredEntitiesClearBuildingQuery = { area=map.buildArea, force="neutral",collision_mask="player-layer" }
map.filteredEntitiesEnemyUnitQuery = { area=map.area, force="enemy", type="unit", limit=301 }
map.filteredEntitiesUnitSpawnereQuery = { area=map.area, force="enemy", type="unit-spawner" }
map.filteredEntitiesUnitSpawnerQuery = { area=map.area, force="enemy", type="unit-spawner" }
map.filteredEntitiesWormQuery = { area=map.area, force="enemy", type="turret" }
map.filteredEntitiesSpawnerQueryLimited = { area=map.area2, force="enemy", type="unit-spawner" }
map.filteredEntitiesWormQueryLimited = { area=map.area2, force="enemy", type="turret" }
map.filteredEntitiesPointQueryLimited = {
position = map.position,
radius = 10,
limit = 1,
force = "enemy",
type = {
"unit-spawner",
"turret"
}
}
map.activePlayerForces = {"player"}
for _,force in pairs(game.forces) do
@ -341,9 +342,18 @@ local function rebuildMap()
local sharedArea = {{0,0},{0,0}}
map.filteredEntitiesCliffQuery = { area=sharedArea, type="cliff", limit = 1 }
map.filteredTilesPathQuery = { area=sharedArea, collision_mask="water-tile", limit = 1 }
map.cliffQuery = {
area=map.area2,
type="cliff"
}
map.canPlaceQuery = { name="", position={0,0} }
map.filteredTilesQuery = { collision_mask="water-tile", area=map.area }
map.upgradeEntityQuery = {
name = "",
position = nil
}
map.attackCommand = {
type = DEFINES_COMMAND_ATTACK_AREA,
destination = map.position,
@ -470,6 +480,9 @@ local function onModSettingsChange(event)
upgrade.compareTable(natives, "aiAggressiveness", settings.global["rampant-aiAggressiveness"].value)
-- if (game.active_mods) then
-- game.
-- end
upgrade.compareTable(natives, "newEnemies", settings.startup["rampant-newEnemies"].value)
upgrade.compareTable(natives, "enemySeed", settings.startup["rampant-enemySeed"].value)
@ -478,7 +491,7 @@ local function onModSettingsChange(event)
natives.enabledMigration = natives.expansion and settings.global["rampant-enableMigration"].value
upgrade.compareTable(natives, "ENEMY_VARIATIONS", settings.startup["rampant-newEnemyVariations"].value)
game.forces.enemy.ai_controllable = not natives.disableVanillaAI
return true
@ -509,6 +522,9 @@ local function prepWorld(rebuild, surfaceIndex)
if upgraded then
rebuildMap()
map.natives = natives
natives.map = map
-- clear pending chunks, will be added when loop runs below
global.pendingChunks = {}
pendingChunks = global.pendingChunks
@ -516,19 +532,26 @@ local function prepWorld(rebuild, surfaceIndex)
-- queue all current chunks that wont be generated during play
local surface = game.surfaces[natives.activeSurface]
local tick = game.tick
local position = {0,0}
natives.nextChunkSort = 0
for chunk in surface.get_chunks() do
onChunkGenerated({ tick = tick,
surface = surface,
area = { left_top = { x = chunk.x * 32,
y = chunk.y * 32 }}})
local x = chunk.x
local y = chunk.y
position[1] = x
position[2] = y
if surface.is_chunk_generated(position) then
onChunkGenerated({ surface = surface,
area = { left_top = { x = x * 32,
y = y * 32}}})
end
end
if natives.newEnemies and rebuild then
game.forces.enemy.kill_all_units()
end
-- UNCOMMENT ME
-- if natives.newEnemies and rebuild then
-- game.forces.enemy.kill_all_units()
-- end
processPendingChunks(natives, map, surface, pendingChunks, tick, game.forces.enemy.evolution_factor, rebuild)
processPendingChunks(map, surface, pendingChunks, tick, rebuild)
end
end
@ -544,7 +567,6 @@ script.on_nth_tick(INTERVAL_PLAYER_PROCESS,
processPlayers(gameRef.players,
map,
gameRef.surfaces[natives.activeSurface],
natives,
event.tick)
end)
@ -555,9 +577,7 @@ script.on_nth_tick(INTERVAL_MAP_PROCESS,
processMap(map,
gameRef.surfaces[natives.activeSurface],
natives,
event.tick,
gameRef.forces.enemy.evolution_factor)
event.tick)
end)
script.on_nth_tick(INTERVAL_SCAN,
@ -566,9 +586,9 @@ script.on_nth_tick(INTERVAL_SCAN,
local gameRef = game
local surface = gameRef.surfaces[natives.activeSurface]
processPendingChunks(natives, map, surface, pendingChunks, tick, gameRef.forces.enemy.evolution_factor)
processPendingChunks(map, surface, pendingChunks, tick)
scanMap(map, surface, natives, tick)
scanMap(map, surface, tick)
processScanChunks(map, surface)
end)
@ -591,21 +611,19 @@ end)
script.on_nth_tick(INTERVAL_SQUAD,
function ()
squadsDispatch(map,
game.surfaces[natives.activeSurface],
natives)
game.surfaces[natives.activeSurface])
end)
script.on_nth_tick(INTERVAL_BUILDERS,
function ()
cleanBuilders(map,
natives,
cleanBuilders(natives,
game.surfaces[natives.activeSurface])
end)
script.on_nth_tick(INTERVAL_RESQUAD,
function ()
regroupSquads(natives, map)
regroupSquads(natives)
end)
@ -615,7 +633,7 @@ local function onBuild(event)
if (entity.type == "resource") and (entity.force.name == "neutral") then
registerResource(entity, map)
else
accountPlayerEntity(map, entity, natives, true, false)
accountPlayerEntity(entity, natives, true, false)
if natives.safeBuildings then
if natives.safeEntities[entity.type] or natives.safeEntityName[entity.name] then
entity.destructible = false
@ -634,7 +652,7 @@ local function onMine(event)
unregisterResource(entity, map)
end
else
accountPlayerEntity(map, entity, natives, false, false)
accountPlayerEntity(entity, natives, false, false)
end
end
end
@ -664,24 +682,16 @@ local function onDeath(event)
convertUnitGroupToSquad(natives, entity.unit_group),
map,
surface,
natives,
tick,
(artilleryBlast and RETREAT_SPAWNER_GRAB_RADIUS) or RETREAT_GRAB_RADIUS,
artilleryBlast)
if (mRandom() < natives.rallyThreshold) and not surface.peaceful_mode then
rallyUnits(chunk, map, surface, natives, tick)
rallyUnits(chunk, map, surface, tick)
end
end
end
-- local cloudName = POISON_LOOKUP[entity.name]
-- if cloudName then
-- surface.create_entity({position=entity.position,
-- name=cloudName})
-- end
elseif event.force and (event.force.name ~= "enemy") and ((entityType == "unit-spawner") or (entityType == "turret")) then
natives.points = natives.points + (((entityType == "unit-spawner") and RECOVER_NEST_COST) or RECOVER_WORM_COST)
@ -689,29 +699,19 @@ local function onDeath(event)
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
unregisterEnemyBaseStructure(map, entity)
rallyUnits(chunk, map, surface, natives, tick)
rallyUnits(chunk, map, surface, tick)
retreatUnits(chunk,
entityPosition,
nil,
map,
surface,
natives,
tick,
RETREAT_SPAWNER_GRAB_RADIUS,
(cause and ((cause.type == "artillery-wagon") or (cause.type == "artillery-turret"))))
end
end
-- if (cause and not artilleryBlast) then
-- local causeChunk = getChunkByPosition(map, cause.position)
-- if (causeChunk ~= SENTINEL_IMPASSABLE_CHUNK) and
-- (causeChunk ~= chunk)
-- then
-- deathScent(map, causeChunk)
-- end
-- end
local pair = natives.drainPylons[entity.unit_number]
if pair then
local target = pair[1]
@ -783,9 +783,8 @@ local function onDeath(event)
if creditNatives and natives.safeBuildings and (natives.safeEntities[entityType] or natives.safeEntityName[entity.name]) then
makeImmortalEntity(surface, entity)
else
accountPlayerEntity(map, entity, natives, false, creditNatives)
accountPlayerEntity(entity, natives, false, creditNatives)
end
-- print("destroyed", entityType, getPlayerBaseGenerator(map,chunk))
end
end
end
@ -795,25 +794,22 @@ local function onEnemyBaseBuild(event)
local surface = entity.surface
if entity.valid and (surface.index == natives.activeSurface) then
local chunk = getChunkByPosition(map, entity.position)
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
local evolutionFactor = entity.force.evolution_factor
local base
if natives.newEnemies then
base = findNearbyBase(map, chunk, natives)
base = findNearbyBase(map, chunk)
if not base then
base = createBase(map,
natives,
evolutionFactor,
base = createBase(natives,
chunk,
event.tick)
end
entity = upgradeEntity(entity,
surface,
base.alignment[mRandom(#base.alignment)],
base.alignment,
natives,
evolutionFactor)
nil,
true)
end
if entity and entity.valid then
event.entity = registerEnemyBaseStructure(map, entity, base)
@ -876,9 +872,11 @@ end
local function onUsedCapsule(event)
local surface = game.players[event.player_index].surface
if (event.item.name == "cliff-explosives") and (surface.index == natives.activeSurface) then
local cliffs = surface.find_entities_filtered({area={{event.position.x-0.75,event.position.y-0.75},
{event.position.x+0.75,event.position.y+0.75}},
type="cliff"})
map.position2Top.x = event.position.x-0.75
map.position2Top.y = event.position.y-0.75
map.position2Bottom.x = event.position.x+0.75
map.position2Bottom.y = event.position.y+0.75
local cliffs = surface.find_entities_filtered(map.cliffQuery)
for i=1,#cliffs do
entityForPassScan(map, cliffs[i])
end
@ -919,55 +917,40 @@ end
local function onEntitySpawned(event)
local entity = event.entity
if (entity.valid and entity.type ~= "unit") then
if natives.newEnemies and (entity.valid and entity.type ~= "unit") then
local spawner = event.spawner
local surface = entity.surface
if (surface.index == natives.activeSurface) then
local entitySet = HIVE_BUILDINGS[entity.name]
if entitySet then
local name = entitySet[mRandom(#entitySet)]
local disPos = mathUtils.distortPosition(entity.position, 8)
entity.destroy()
local canPlaceQuery = map.canPlaceQuery
canPlaceQuery.name = name
canPlaceQuery.position = disPos
if surface.can_place_entity(canPlaceQuery) then
surface.create_entity(canPlaceQuery)
else
local pos = movementUtils.findMovementPositionEntity(name,
surface,
disPos)
if pos then
canPlaceQuery.position = pos
entity = surface.create_entity(canPlaceQuery)
local chunk = getChunkByPosition(map, pos)
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
local evolutionFactor = entity.force.evolution_factor
local base
if natives.newEnemies then
base = findNearbyBase(map, chunk, natives)
if not base then
base = createBase(map,
natives,
evolutionFactor,
chunk,
event.tick)
end
entity = upgradeEntity(entity,
surface,
base.alignment[mRandom(#base.alignment)],
natives,
evolutionFactor)
end
if entity and entity.valid then
event.entity = registerEnemyBaseStructure(map, entity, base)
end
end
end
local disPos = mathUtils.distortPosition(entity.position, 8)
local canPlaceQuery = map.canPlaceQuery
local chunk = getChunkByPosition(map, disPos)
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
local base = findNearbyBase(map, chunk)
if not base then
base = createBase(natives,
chunk,
event.tick)
end
entity = upgradeEntity(entity,
surface,
base.alignment,
natives,
disPos)
if entity and entity.valid then
event.entity = registerEnemyBaseStructure(map, entity, base)
end
else
entity.destroy()
-- local position = {disPos[1],disPos[2]}
-- if (surface.is_chunk_generated(position)) then
-- onChunkGenerated({
-- area = { left_top = position },
-- surface = surface
-- })
-- end
end
end
end
end
end

View File

@ -4,13 +4,8 @@ local biterFunctions = require("prototypes/utils/BiterUtils")
local swarmUtils = require("prototypes/SwarmUtils")
swarmUtils.processFactions()
if settings.startup["rampant-newEnemies"].value then
-- require("prototypes/Decaying")
-- require("prototypes/Undying")
if settings.startup["rampant-newEnemies"].value then
swarmUtils.processFactions()
end
if settings.startup["rampant-removeBloodParticles"].value then
@ -23,12 +18,15 @@ if settings.startup["rampant-removeBloodParticles"].value then
end
end
for _, unitSpawner in pairs(data.raw["unit-spawner"]) do
if settings.startup["rampant-unitSpawnerBreath"].value then
if not unitSpawner.flags then
unitSpawner.flags = {}
end
unitSpawner.flags[#unitSpawner.flags+1] = "breaths-air"
if settings.startup["rampant-unitSpawnerBreath"].value then
for _, unitSpawner in pairs(data.raw["unit-spawner"]) do
if (string.find(unitSpawner.name, "hive") or string.find(unitSpawner.name, "biter") or
string.find(unitSpawner.name, "spitter")) then
if not unitSpawner.flags then
unitSpawner.flags = {}
end
unitSpawner.flags[#unitSpawner.flags+1] = "breaths-air"
end
end
end
@ -43,7 +41,12 @@ if settings.startup["rampant-enableSwarm"].value then
if not settings.startup["rampant-newEnemies"].value then
unit.affected_by_tiles = true
unit.ai_settings = { destroy_when_commands_fail = false, allow_try_return_to_spawner = true, path_resolution_modifier = -5, do_seperation = true }
unit.ai_settings = {
destroy_when_commands_fail = false,
allow_try_return_to_spawner = true,
path_resolution_modifier = -5,
do_seperation = true
}
end
end
end
@ -51,7 +54,7 @@ end
if settings.startup["rampant-enableShrinkNestsAndWorms"].value then
for k, unit in pairs(data.raw["unit-spawner"]) do
if (string.find(k, "biter") or string.find(k, "spitter")) and unit.collision_box then
if (string.find(k, "biter") or string.find(k, "spitter") or string.find(k, "hive")) and unit.collision_box then
unit.collision_box = {
{unit.collision_box[1][1] * 0.50, unit.collision_box[1][2] * 0.50},
{unit.collision_box[2][1] * 0.50, unit.collision_box[2][2] * 0.50}

View File

@ -120,8 +120,8 @@ local function validUnitGroupLocation(map, neighborChunk)
(getNestCount(map, neighborChunk) == 0)
end
function aiAttackWave.rallyUnits(chunk, map, surface, natives, tick)
if ((tick - getRallyTick(map, chunk) > INTERVAL_RALLY) and (natives.points >= AI_VENGENCE_SQUAD_COST)) then
function aiAttackWave.rallyUnits(chunk, map, surface, tick)
if ((tick - getRallyTick(map, chunk) > INTERVAL_RALLY) and (map.natives.points >= AI_VENGENCE_SQUAD_COST)) then
setRallyTick(map, chunk, tick)
local cX = chunk.x
local cY = chunk.y
@ -130,7 +130,7 @@ function aiAttackWave.rallyUnits(chunk, map, surface, natives, tick)
if (x ~= cX) and (y ~= cY) then
local rallyChunk = getChunkByXY(map, x, y)
if (rallyChunk ~= SENTINEL_IMPASSABLE_CHUNK) and (getNestCount(map, rallyChunk) > 0) then
if not aiAttackWave.formVengenceSquad(map, surface, natives, rallyChunk) then
if not aiAttackWave.formVengenceSquad(map, surface, rallyChunk) then
return
end
end
@ -156,7 +156,8 @@ local function noNearbySettlers(map, chunk, tick)
return true
end
function aiAttackWave.formSettlers(map, surface, natives, chunk, tick)
function aiAttackWave.formSettlers(map, surface, chunk, tick)
local natives = map.natives
if (mRandom() < natives.formSquadThreshold) and ((natives.squads.len + #natives.building) < AI_MAX_SQUAD_COUNT) then
local squadPath, squadDirection
@ -213,10 +214,10 @@ function aiAttackWave.formSettlers(map, surface, natives, chunk, tick)
return (natives.points - AI_SETTLER_COST) > 0
end
function aiAttackWave.formVengenceSquad(map, surface, natives, chunk)
function aiAttackWave.formVengenceSquad(map, surface, chunk)
local natives = map.natives
if (mRandom() < natives.formSquadThreshold) and (natives.squads.len < AI_MAX_SQUAD_COUNT)
then
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(map, chunk.x, chunk.y),
validUnitGroupLocation,
scoreUnitGroupLocation,
@ -257,7 +258,8 @@ function aiAttackWave.formVengenceSquad(map, surface, natives, chunk)
return (natives.points - AI_VENGENCE_SQUAD_COST) > 0
end
function aiAttackWave.formSquads(map, surface, natives, chunk, tick)
function aiAttackWave.formSquads(map, surface, chunk, tick)
local natives = map.natives
if attackWaveValidCandidate(chunk, natives, map) and
(mRandom() < natives.formSquadThreshold) and
(natives.squads.len < AI_MAX_SQUAD_COUNT)

View File

@ -60,6 +60,8 @@ function aiPlanning.planning(natives, evolution_factor, tick)
if natives.aiNocturnalMode then
maxPoints = maxPoints * 0.85
end
natives.evolutionLevel = evolution_factor
local maxOverflowPoints = maxPoints * 3

File diff suppressed because it is too large Load Diff

View File

@ -1,127 +0,0 @@
if bobsBaseUnits then
return bobsBaseUnits
end
local bobs = {}
-- imports
local constants = require("Constants")
-- imported constants
local BASE_ALIGNMENT_BOBS = constants.BASE_ALIGNMENT_BOBS
-- imported functions
local mMin = math.min
-- module code
local function fileEntity(baseAlignment, entity, evolutionTable, natives, evo)
local evoRequirement = mMin(evo or entity.prototype.build_base_evolution_requirement, 1)
local eTable = evolutionTable[baseAlignment]
if not eTable then
eTable = {}
evolutionTable[baseAlignment] = eTable
end
local aTable = eTable[evoRequirement]
if not aTable then
aTable = {}
eTable[evoRequirement] = aTable
end
aTable[#aTable+1] = entity.name
-- natives.enemyAlignmentLookup[entity.name] = baseAlignment
end
function bobs.processBobsUnitClass(natives, surface)
local position = { x = 0, y = 0 }
local entity = surface.create_entity({
name = "bob-biter-spawner",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
entity.destroy()
entity = surface.create_entity({
name = "bob-spitter-spawner",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
entity.destroy()
entity = surface.create_entity({
name = "small-worm-turret",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "medium-worm-turret",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "big-worm-turret",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-big-explosive-worm-turret",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-big-fire-worm-turret",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-big-poison-worm-turret",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-big-piercing-worm-turret",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-big-electric-worm-turret",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-giant-worm-turret",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "behemoth-worm-turret",
position = position
})
fileEntity(BASE_ALIGNMENT_BOBS, entity, natives.evolutionTableWorm, natives)
entity.destroy()
end
bobsBaseUnits = bobs
return bobs

View File

@ -51,14 +51,14 @@ local function sorter(a, b)
return (aDistance < bDistance)
end
function chunkProcessor.processPendingChunks(natives, map, surface, pendingStack, tick, evolutionFactor, rebuilding)
function chunkProcessor.processPendingChunks(map, surface, pendingStack, tick, rebuilding)
local processQueue = map.processQueue
local area = map.area
local topOffset = area[1]
local bottomOffset = area[2]
for i=#pendingStack, 1, -1 do
local event = pendingStack[i]
pendingStack[i] = nil
@ -72,7 +72,7 @@ function chunkProcessor.processPendingChunks(natives, map, surface, pendingStack
bottomOffset[1] = x + CHUNK_SIZE
bottomOffset[2] = y + CHUNK_SIZE
if map[x] and map[x][y] then
if map[x] and map[x][y] then
mapScanChunk(map[x][y], surface, map)
else
if map[x] == nil then
@ -80,28 +80,28 @@ function chunkProcessor.processPendingChunks(natives, map, surface, pendingStack
end
local chunk = createChunk(x, y)
chunk = initialScan(chunk, natives, surface, map, tick, evolutionFactor, rebuilding)
chunk = initialScan(chunk, surface, map, tick, rebuilding)
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
map[x][y] = chunk
processQueue[#processQueue+1] = chunk
end
end
end
end
if (#processQueue > natives.nextChunkSort) or
(((tick - natives.nextChunkSortTick) > MAX_TICKS_BEFORE_SORT_CHUNKS) and ((natives.nextChunkSort - 75) ~= #processQueue))
if (#processQueue > map.nextChunkSort) or
(((tick - map.nextChunkSortTick) > MAX_TICKS_BEFORE_SORT_CHUNKS) and ((map.nextChunkSort - 75) ~= #processQueue))
then
natives.nextChunkSort = #processQueue + 75
natives.nextChunkSortTick = tick
map.nextChunkSort = #processQueue + 75
map.nextChunkSortTick = tick
tSort(processQueue, sorter)
end
end
function chunkProcessor.processScanChunks(map, surface)
local area = map.area
local topOffset = area[1]
local bottomOffset = area[2]
@ -110,7 +110,7 @@ function chunkProcessor.processScanChunks(map, surface)
local chunkCount = 0
local chunkToPassScan = map.chunkToPassScan
for chunk,_ in pairs(chunkToPassScan) do
local x = chunk.x
local y = chunk.y
@ -128,7 +128,7 @@ function chunkProcessor.processScanChunks(map, surface)
chunkCount = chunkCount + 1
removals[chunkCount] = chunk
end
chunkToPassScan[chunk] = nil
end

View File

@ -18,15 +18,51 @@ function chunkPropertyUtils.getNestCount(map, chunk)
return map.chunkToNests[chunk] or 0
end
function chunkPropertyUtils.getWormCount(map, chunk)
return map.chunkToWorms[chunk] or 0
function chunkPropertyUtils.getTurretCount(map, chunk)
return map.chunkToTurrets[chunk] or 0
end
function chunkPropertyUtils.setWormCount(map, chunk, count)
function chunkPropertyUtils.getTrapCount(map, chunk)
return map.chunkToTraps[chunk] or 0
end
function chunkPropertyUtils.getUtilityCount(map, chunk)
return map.chunkToUtilities[chunk] or 0
end
function chunkPropertyUtils.getHiveCount(map, chunk)
return map.chunkToHives[chunk] or 0
end
function chunkPropertyUtils.setTurretCount(map, chunk, count)
if (count <= 0) then
map.chunkToWorms[chunk] = nil
map.chunkToTurrets[chunk] = nil
else
map.chunkToWorms[chunk] = count
map.chunkToTurrets[chunk] = count
end
end
function chunkPropertyUtils.setHiveCount(map, chunk, count)
if (count <= 0) then
map.chunkToHives[chunk] = nil
else
map.chunkToHives[chunk] = count
end
end
function chunkPropertyUtils.setTrapCount(map, chunk, count)
if (count <= 0) then
map.chunkToTraps[chunk] = nil
else
map.chunkToTraps[chunk] = count
end
end
function chunkPropertyUtils.setUtilityCount(map, chunk, count)
if (count <= 0) then
map.chunkToUtilities[chunk] = nil
else
map.chunkToUtilities[chunk] = count
end
end
@ -62,12 +98,9 @@ function chunkPropertyUtils.setChunkBase(map, chunk, base)
map.chunkToBase[chunk] = base
end
function chunkPropertyUtils.getWormCount(map, chunk)
return map.chunkToWorms[chunk] or 0
end
function chunkPropertyUtils.getEnemyStructureCount(map, chunk)
return (map.chunkToNests[chunk] or 0) + (map.chunkToWorms[chunk] or 0)
return (map.chunkToNests[chunk] or 0) + (map.chunkToTurrets[chunk] or 0) + (map.chunkToTraps[chunk] or 0) +
(map.chunkToUtilities[chunk] or 0) + (map.chunkToHives[chunk] or 0)
end
function chunkPropertyUtils.getRetreatTick(map, chunk)

View File

@ -13,6 +13,8 @@ local chunkPropertyUtils = require("ChunkPropertyUtils")
-- constants
local HIVE_BUILDINGS_TYPES = constants.HIVE_BUILDINGS_TYPES
local CHUNK_SIZE_DIVIDER = constants.CHUNK_SIZE_DIVIDER
local DEFINES_WIRE_TYPE_RED = defines.wire_type.red
local DEFINES_WIRE_TYPE_GREEN = defines.wire_type.green
@ -57,12 +59,21 @@ local setPlayerBaseGenerator = chunkPropertyUtils.setPlayerBaseGenerator
local addPlayerBaseGenerator = chunkPropertyUtils.addPlayerBaseGenerator
local setResourceGenerator = chunkPropertyUtils.setResourceGenerator
local addResourceGenerator = chunkPropertyUtils.addResourceGenerator
local setWormCount = chunkPropertyUtils.setWormCount
local setHiveCount = chunkPropertyUtils.setHiveCount
local setTrapCount = chunkPropertyUtils.setTrapCount
local setTurretCount = chunkPropertyUtils.setTurretCount
local setUtilityCount = chunkPropertyUtils.setUtilityCount
local getPlayerBaseGenerator = chunkPropertyUtils.getPlayerBaseGenerator
local getNestCount = chunkPropertyUtils.getNestCount
local getHiveCount = chunkPropertyUtils.getHiveCount
local getTrapCount = chunkPropertyUtils.getTrapCount
local getUtilityCount = chunkPropertyUtils.getUtilityCount
local getTurretCount = chunkPropertyUtils.getTurretCount
local setRaidNestActiveness = chunkPropertyUtils.setRaidNestActiveness
local setNestActiveness = chunkPropertyUtils.setNestActiveness
local getEnemyStructureCount = chunkPropertyUtils.getEnemyStructureCount
local findNearbyBase = baseUtils.findNearbyBase
local createBase = baseUtils.createBase
@ -185,15 +196,16 @@ local function scorePlayerBuildings(surface, map)
(surface.count_entities_filtered(map.filteredEntitiesPlayerQuery12000) * GENERATOR_PHEROMONE_LEVEL_6)
end
function chunkUtils.initialScan(chunk, natives, surface, map, tick, evolutionFactor, rebuilding)
function chunkUtils.initialScan(chunk, surface, map, tick, rebuilding)
local passScore = 1 - (surface.count_tiles_filtered(map.filteredTilesQuery) * 0.0009765625)
local natives = map.natives
if (passScore >= CHUNK_PASS_THRESHOLD) then
local pass = scanPaths(chunk, surface, map)
local playerObjects = scorePlayerBuildings(surface, map)
local nests = surface.find_entities_filtered(map.filteredEntitiesUnitSpawnereQuery)
local nests = surface.find_entities_filtered(map.filteredEntitiesUnitSpawnerQuery)
if ((playerObjects > 0) or (#nests > 0)) and (pass == CHUNK_IMPASSABLE) then
pass = CHUNK_ALL_DIRECTIONS
@ -203,14 +215,18 @@ function chunkUtils.initialScan(chunk, natives, surface, map, tick, evolutionFac
local worms = surface.find_entities_filtered(map.filteredEntitiesWormQuery)
local resources = surface.count_entities_filtered(map.countResourcesQuery) * RESOURCE_NORMALIZER
local buildingHiveTypeLookup = natives.buildingHiveTypeLookup
local counts = {}
for i=1,#HIVE_BUILDINGS_TYPES do
counts[HIVE_BUILDINGS_TYPES[i]] = 0
end
if natives.newEnemies and ((#nests > 0) or (#worms > 0)) then
local nestCount = 0
local wormCount = 0
local base = findNearbyBase(map, chunk, natives)
local base = findNearbyBase(map, chunk)
if base then
setChunkBase(map, chunk, base)
else
base = createBase(map, natives, evolutionFactor, chunk, tick, rebuilding)
base = createBase(natives, chunk, tick, rebuilding)
end
local alignment = base.alignment
@ -222,43 +238,72 @@ function chunkUtils.initialScan(chunk, natives, surface, map, tick, evolutionFac
if (#nests > 0) then
for i = 1, #nests do
local nest = nests[i]
if rebuilding then
if not isRampant(nests[i].name) then
if upgradeEntity(nests[i], surface, alignment[mRandom(#alignment)], natives, evolutionFactor) then
nestCount = nestCount + 1
if not isRampant(nest.name) then
local newEntity = upgradeEntity(nest, surface, alignment, natives, nil, true)
if newEntity then
local hiveType = buildingHiveTypeLookup[newEntity.name]
counts[hiveType] = counts[hiveType] + 1
end
else
nestCount = nestCount + 1
local hiveType = buildingHiveTypeLookup[nest.name]
counts[hiveType] = counts[hiveType] + 1
end
else
if upgradeEntity(nests[i], surface, alignment[mRandom(#alignment)], natives, evolutionFactor) then
nestCount = nestCount + 1
local newEntity = upgradeEntity(nest, surface, alignment, natives, nil, true)
if newEntity then
local hiveType = buildingHiveTypeLookup[newEntity.name]
counts[hiveType] = counts[hiveType] + 1
end
end
end
end
if (#worms > 0) then
for i = 1, #worms do
local worm = worms[i]
if rebuilding then
if not isRampant(worms[i].name) then
if upgradeEntity(worms[i], surface, alignment[mRandom(#alignment)], natives, evolutionFactor) then
wormCount = wormCount + 1
if not isRampant(worm.name) then
local newEntity = upgradeEntity(worm, surface, alignment, natives, nil, true)
if newEntity then
local hiveType = buildingHiveTypeLookup[newEntity.name]
counts[hiveType] = counts[hiveType] + 1
end
else
wormCount = wormCount + 1
local hiveType = buildingHiveTypeLookup[worm.name]
counts[hiveType] = counts[hiveType] + 1
end
else
if upgradeEntity(worms[i], surface, alignment[mRandom(#alignment)], natives, evolutionFactor) then
wormCount = wormCount + 1
local newEntity = upgradeEntity(worm, surface, alignment, natives, nil, true)
if newEntity then
local hiveType = buildingHiveTypeLookup[newEntity.name]
counts[hiveType] = counts[hiveType] + 1
end
end
end
end
setNestCount(map, chunk, nestCount)
setWormCount(map, chunk, wormCount)
setNestCount(map, chunk, counts["spitter-spawner"] + counts["biter-spawner"])
setUtilityCount(map, chunk, counts["utility"])
setHiveCount(map, chunk, counts["hive"])
setTrapCount(map, chunk, counts["trap"])
setTurretCount(map, chunk, counts["turret"])
else
setNestCount(map, chunk, #nests)
setWormCount(map, chunk, #worms)
for i=1,#nests do
local hiveType = buildingHiveTypeLookup[nests[i].name]
counts[hiveType] = counts[hiveType] + 1
end
for i=1,#worms do
local hiveType = buildingHiveTypeLookup[worms[i].name]
counts[hiveType] = counts[hiveType] + 1
end
setNestCount(map, chunk, counts["spitter-spawner"] + counts["biter-spawner"])
setUtilityCount(map, chunk, counts["utility"])
setHiveCount(map, chunk, counts["hive"])
setTrapCount(map, chunk, counts["trap"])
setTurretCount(map, chunk, counts["turret"])
end
setPlayerBaseGenerator(map, chunk, playerObjects)
@ -302,10 +347,10 @@ function chunkUtils.mapScanChunk(chunk, surface, map)
setPlayerBaseGenerator(map, chunk, playerObjects)
local resources = surface.count_entities_filtered(map.countResourcesQuery) * RESOURCE_NORMALIZER
setResourceGenerator(map, chunk, resources)
local nests = surface.count_entities_filtered(map.filteredEntitiesUnitSpawnereQuery)
local nests = surface.count_entities_filtered(map.filteredEntitiesUnitSpawnerQuery)
setNestCount(map, chunk, nests)
local worms = surface.count_entities_filtered(map.filteredEntitiesWormQuery)
setWormCount(map, chunk, worms)
setTurretCount(map, chunk, worms)
end
function chunkUtils.entityForPassScan(map, entity)
@ -350,17 +395,31 @@ function chunkUtils.registerEnemyBaseStructure(map, entity, base)
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
local overlapArray = getEntityOverlapChunks(map, entity)
local lookup
if (entityType == "unit-spawner") then
lookup = map.chunkToNests
elseif (entityType == "turret") then
lookup = map.chunkToWorms
local getFunc
local setFunc
local hiveTypeLookup = map.natives.buildingHiveTypeLookup
local hiveType = hiveTypeLookup[entity.name]
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
getFunc = getNestCount
setFunc = setNestCount
elseif (hiveType == "turret") then
getFunc = getTurretCount
setFunc = setTurretCount
elseif (hiveType == "trap") then
getFunc = getTrapCount
setFunc = setTrapCount
elseif (hiveType == "utility") then
getFunc = getUtilityCount
setFunc = setUtilityCount
elseif (hiveType == "hive") then
getFunc = getHiveCount
setFunc = setHiveCount
end
for i=1,#overlapArray do
local chunk = overlapArray[i]
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
lookup[chunk] = (lookup[chunk] or 0) + 1
setFunc(map, chunk, getFunc(map, chunk) + 1)
setChunkBase(map, chunk, base)
end
end
@ -374,32 +433,43 @@ function chunkUtils.unregisterEnemyBaseStructure(map, entity)
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
local overlapArray = getEntityOverlapChunks(map, entity)
local mainLookup
local secondaryLookup
if (entityType == "unit-spawner") then
mainLookup = map.chunkToNests
secondaryLookup = map.chunkToWorms
elseif (entity.type == "turret") then
mainLookup = map.chunkToWorms
secondaryLookup = map.chunkToNests
local getFunc
local setFunc
local hiveTypeLookup = map.natives.buildingHiveTypeLookup
local hiveType = hiveTypeLookup[entity.name]
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
getFunc = getNestCount
setFunc = setNestCount
elseif (hiveType == "turret") then
getFunc = getTurretCount
setFunc = setTurretCount
elseif (hiveType == "trap") then
getFunc = getTrapCount
setFunc = setTrapCount
elseif (hiveType == "utility") then
getFunc = getUtilityCount
setFunc = setUtilityCount
elseif (hiveType == "hive") then
getFunc = getHiveCount
setFunc = setHiveCount
end
for i=1,#overlapArray do
local chunk = overlapArray[i]
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
local count = mainLookup[chunk]
local count = getFunc(map, chunk)
if count then
if (count <= 1) then
if (entityType == "unit-spawner") then
if (hiveType == "spitter-spawner") or (hiveType == "biter-spawner") then
setRaidNestActiveness(map, chunk, 0)
setNestActiveness(map, chunk, 0)
end
mainLookup[chunk] = nil
if not secondaryLookup[chunk] then
setFunc(map, chunk, 0)
if (getEnemyStructureCount(map, chunk) == 0) then
setChunkBase(map, chunk, nil)
end
else
mainLookup[chunk] = count - 1
setFunc(map, chunk, count - 1)
end
end
end
@ -408,9 +478,10 @@ function chunkUtils.unregisterEnemyBaseStructure(map, entity)
end
end
function chunkUtils.accountPlayerEntity(map, entity, natives, addObject, creditNatives)
function chunkUtils.accountPlayerEntity(entity, natives, addObject, creditNatives)
if (BUILDING_PHEROMONES[entity.type] ~= nil) and (entity.force.name ~= "enemy") then
local map = natives.map
local entityValue = BUILDING_PHEROMONES[entity.type]
local overlapArray = getEntityOverlapChunks(map, entity)

View File

@ -130,10 +130,10 @@ constants.AI_STATE_ONSLAUGHT = 7
constants.BASE_AI_STATE_DORMANT = 0
constants.BASE_AI_STATE_ACTIVE = 1
constants.BASE_AI_STATE_WORMS = 2
constants.BASE_AI_STATE_NESTS = 3
constants.BASE_AI_STATE_OVERDRIVE = 4
constants.BASE_AI_STATE_MUTATE = 5
-- constants.BASE_AI_STATE_WORMS = 2
-- constants.BASE_AI_STATE_NESTS = 3
constants.BASE_AI_STATE_OVERDRIVE = 2
constants.BASE_AI_STATE_MUTATE = 3
constants.AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION = 0.5
@ -159,7 +159,6 @@ constants.BASE_DEADZONE_TTL = constants.TICKS_A_MINUTE * 18
constants.BASE_COLLECTION_THRESHOLD = constants.TICKS_A_MINUTE * 2
constants.BASE_DISTANCE_TO_EVO_INDEX = 1 / 9600
-- constants.BASE_DISTANCE_TO_EVO_INDEX = 1 / 32000
constants.BASE_SPAWNER_UPGRADE = 250
constants.BASE_WORM_UPGRADE = 200
@ -168,213 +167,8 @@ constants.BASE_UPGRADE = 1500
constants.BASE_DISTANCE_THRESHOLD = 30 * constants.CHUNK_SIZE
constants.BASE_DISTANCE_LEVEL_BONUS = 15
constants.BASE_ALIGNMENT_NEUTRAL = 1
constants.BASE_ALIGNMENT_FIRE = 2
constants.BASE_ALIGNMENT_NUCLEAR = 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_POISON = 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_ENERGY_THIEF = 17
constants.BASE_ALIGNMENT_ELECTRIC = 18
constants.BASE_ALIGNMENT_WASP = 19
constants.BASE_ALIGNMENT_DEADZONE = 20
constants.BASE_ALIGNMENT_NE = 21
constants.BASE_ALIGNMENT_BOBS = 22
constants.BASE_ALIGNMENT_SPAWNER = 23
constants.BASE_ALIGNMENT_NE_BLUE = 24
constants.BASE_ALIGNMENT_NE_RED = 25
constants.BASE_ALIGNMENT_NE_YELLOW = 26
constants.BASE_ALIGNMENT_NE_GREEN = 27
constants.BASE_ALIGNMENT_NE_PINK = 28
-- constants.BASE_ALIGNMENT_BURROW = 3
constants.BASE_PROCESS_INTERVAL = constants.TICKS_A_SECOND * 2
-- neutralPath[constants.BASE_ALIGNMENT_DECAYING] = true
-- neutralPath[constants.BASE_ALIGNMENT_WEB] = true
-- neutralPath[constants.BASE_ALIGNMENT_WASP] = true
-- local acidPath = {}
-- acidPath[constants.BASE_ALIGNMENT_POISON] = true
-- acidPath[constants.BASE_ALIGNMENT_INFEST] = true
-- local decayingPath = {}
-- decayingPath[constants.BASE_ALIGNMENT_UNDYING] = true
constants.BASE_ALIGNMENT_EVOLUTION_BASELINE = {
[constants.BASE_ALIGNMENT_NEUTRAL] = 0
}
constants.BASE_ALIGNMENT_PATHS = {}
-- constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_NEUTRAL] = {
-- constants.BASE_ALIGNMENT_ACID,
-- constants.BASE_ALIGNMENT_FIRE,
-- constants.BASE_ALIGNMENT_WASP,
-- constants.BASE_ALIGNMENT_PHYSICAL,
-- constants.BASE_ALIGNMENT_ELECTRIC,
-- constants.BASE_ALIGNMENT_SUICIDE,
-- constants.BASE_ALIGNMENT_TROLL,
-- constants.BASE_ALIGNMENT_FAST
-- }
local function pushBasePath(x)
local tbl = constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_NEUTRAL]
if not tbl then
tbl = {}
constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_NEUTRAL] = tbl
end
tbl[#tbl+1] = x
end
if settings.startup["rampant-acidEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_ACID)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_ACID] = 0.1
end
if settings.startup["rampant-physicalEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_PHYSICAL)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_PHYSICAL] = 0.4
end
if settings.startup["rampant-suicideEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_SUICIDE)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_SUICIDE] = 0.3
end
if settings.startup["rampant-fireEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_FIRE)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_FIRE] = 0.4
end
if settings.startup["rampant-electricEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_ELECTRIC)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_ELECTRIC] = 0.2
end
if settings.startup["rampant-nuclearEnemy"].value then
if settings.startup["rampant-suicideEnemy"].value then
constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_SUICIDE] = { constants.BASE_ALIGNMENT_NUCLEAR }
end
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_NUCLEAR] = 0.7
end
if settings.startup["rampant-fastEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_FAST)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_FAST] = 0.5
end
if settings.startup["rampant-trollEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_TROLL)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_TROLL] = 0.5
end
if settings.startup["rampant-laserEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_LASER)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_LASER] = 0.4
end
if settings.startup["rampant-waspEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_WASP)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_WASP] = 0.5
end
if settings.startup["rampant-energyThiefEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_ENERGY_THIEF)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_ENERGY_THIEF] = 0.4
end
if settings.startup["rampant-poisonEnemy"].value then
pushBasePath(constants.BASE_ALIGNMENT_POISON)
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_POISON] = 0.4
end
-- constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_FIRE] = { constants.BASE_ALIGNMENT_INFERNO }
-- constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_SUICIDE] = { constants.BASE_ALIGNMENT_NUCLEAR }
-- constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_WASP] = { constants.BASE_ALIGNMENT_SPAWNER }
-- constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_ACID] = acidPath
-- constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_DECAYING] = decayingPath
-- constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_ELECTRIC] = { constants.BASE_ALIGNMENT_LASER }
-- [constants.BASE_ALIGNMENT_WASP] = 0.5,
-- [constants.BASE_ALIGNMENT_SPAWNER] = 0.7,
-- [constants.BASE_ALIGNMENT_INFERNO] = 0.6,
if settings.startup["rampant-infernoEnemy"].value then
if settings.startup["rampant-fireEnemy"].value then
constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_FIRE] = { constants.BASE_ALIGNMENT_INFERNO }
end
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_INFERNO] = 0.6
end
if settings.startup["rampant-spawnerEnemy"].value then
if settings.startup["rampant-waspEnemy"].value then
constants.BASE_ALIGNMENT_PATHS[constants.BASE_ALIGNMENT_WASP] = { constants.BASE_ALIGNMENT_SPAWNER }
end
local tbl = constants.BASE_ALIGNMENT_EVOLUTION_BASELINE
tbl[constants.BASE_ALIGNMENT_SPAWNER] = 0.7
end
constants.ENABLED_NE_UNITS = settings.startup["rampant-enableNEUnits"].value and (settings.startup["NE_Difficulty"] ~= nil)
constants.ENABLED_BOBS_UNITS = settings.startup["rampant-enableBobsUnits"].value and (settings.startup["bobmods-enemies-enableartifacts"] ~= nil)
if constants.ENABLED_BOBS_UNITS then
constants.BASE_ALIGNMENT_EVOLUTION_BASELINE[constants.BASE_ALIGNMENT_BOBS] = 0.1
end
if constants.ENABLED_NE_UNITS then
constants.BASE_ALIGNMENT_EVOLUTION_BASELINE[constants.BASE_ALIGNMENT_NE] = 0.1
if settings.startup["NE_Blue_Spawners"].value then
constants.BASE_ALIGNMENT_EVOLUTION_BASELINE[constants.BASE_ALIGNMENT_NE_BLUE] = 0.1
end
if settings.startup["NE_Red_Spawners"].value then
constants.BASE_ALIGNMENT_EVOLUTION_BASELINE[constants.BASE_ALIGNMENT_NE_RED] = 0.1
end
if settings.startup["NE_Pink_Spawners"].value then
constants.BASE_ALIGNMENT_EVOLUTION_BASELINE[constants.BASE_ALIGNMENT_NE_PINK] = 0.1
end
if settings.startup["NE_Green_Spawners"].value then
constants.BASE_ALIGNMENT_EVOLUTION_BASELINE[constants.BASE_ALIGNMENT_NE_GREEN] = 0.1
end
if settings.startup["NE_Yellow_Spawners"].value then
constants.BASE_ALIGNMENT_EVOLUTION_BASELINE[constants.BASE_ALIGNMENT_NE_YELLOW] = 0.1
end
end
-- ai retreat
constants.NO_RETREAT_BASE_PERCENT = 0.10
@ -576,7 +370,6 @@ constants.ENERGY_THIEF_DRAIN_CRYSTALS = {
constants.NEIGHBOR_DIVIDER = {1/1, 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8}
-- unit spawners
local function roundToNearest(number, multiple)
@ -618,23 +411,13 @@ for tier=1, 10 do
end
end
-- constants.POISON_LOOKUP = {}
-- for tier=1, 10 do
-- local effectiveLevel = constants.TIER_UPGRADE_SET_10[tier]
-- for i=1,variations do
-- constants.POISON_LOOKUP["poison-biter-v" .. i .. "-t" .. tier .. "-rampant"] = "poison-cloud-v" .. effectiveLevel .. "-cloud-rampant"
-- end
-- end
-- constants.SPAWNER_EGG_TIMEOUT = constants.TICKS_A_SECOND * 5
constants.FACTION_SET = {}
constants.FACTION_SET[#constants.FACTION_SET+1] = {
type = "neutral",
tint = {r=0.9, g=0.9, b=0.9, a=1},
tint2 = {r=1, g=1, b=1, a=1},
acceptRate = {1, 7, 0.3, 0.1},
evo = 0,
units = {
{
@ -661,6 +444,7 @@ constants.FACTION_SET[#constants.FACTION_SET+1] = {
type = "spitter-spawner",
name = "spitter-spawner",
majorResistances = {},
acceptRate = {1, 10, 0.1, 0.2},
minorResistances = {},
attributes = {},
drops = {"nilArtifact"},
@ -672,6 +456,7 @@ constants.FACTION_SET[#constants.FACTION_SET+1] = {
type = "biter-spawner",
name = "biter-spawner",
majorResistances = {},
acceptRate = {1, 10, 0.1, 0.2},
minorResistances = {},
attributes = {},
drops = {"nilArtifact"},
@ -683,6 +468,7 @@ constants.FACTION_SET[#constants.FACTION_SET+1] = {
type = "turret",
name = "worm",
majorResistances = {},
acceptRate = {1, 10, 0.8, 0.6},
minorResistances = {},
attackAttributes = {"spit", "acid"},
attributes = {},
@ -694,6 +480,7 @@ constants.FACTION_SET[#constants.FACTION_SET+1] = {
majorResistances = {},
minorResistances = {},
attributes = {},
acceptRate = {2, 10, 0.005, 0.03},
drops = {"nilArtifact"},
buildSets = {
{"biter-spawner", 1, 10, 0.1, 0.2},
@ -710,6 +497,7 @@ if settings.startup["rampant-acidEnemy"].value then
type = "acid",
tint = {r=1, g=1, b=1, a=1},
tint2 = {r=0, g=0.9, b=0, a=1},
acceptRate = {1, 10, 0.1, 0.2},
evo = 0,
units = {
{
@ -737,6 +525,7 @@ if settings.startup["rampant-acidEnemy"].value then
name = "spitter-spawner",
majorResistances = {"acid"},
minorResistances = {"poison"},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {},
drops = {"greenArtifact"},
buildSets = {
@ -748,6 +537,7 @@ if settings.startup["rampant-acidEnemy"].value then
name = "biter-spawner",
majorResistances = {"acid"},
minorResistances = {"poison"},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {},
drops = {"greenArtifact"},
buildSets = {
@ -760,6 +550,7 @@ if settings.startup["rampant-acidEnemy"].value then
majorResistances = {"acid"},
minorResistances = {"poison"},
attackAttributes = {"spit", "acid"},
acceptRate = {1, 10, 0.8, 0.6},
attributes = {},
drops = {"greenArtifact"}
},
@ -768,6 +559,7 @@ if settings.startup["rampant-acidEnemy"].value then
name = "hive",
majorResistances = {"acid"},
minorResistances = {"poison"},
acceptRate = {2, 10, 0.005, 0.03},
attributes = {},
drops = {"greenArtifact"},
buildSets = {
@ -786,7 +578,8 @@ if settings.startup["rampant-laserEnemy"].value then
type = "laser",
tint = {r=0.3, g=0.3, b=0.42, a=1},
tint2 = {r=0, g=0.6, b=0.8, a=1},
evo = 0.15,
acceptRate = {2, 10, 0.1, 0.15},
evo = 0.10,
units = {
{
type = "biter",
@ -810,6 +603,7 @@ if settings.startup["rampant-laserEnemy"].value then
type = "spitter-spawner",
name = "spitter-spawner",
majorResistances = {"laser", "electric"},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {},
drops = {"blueArtifact"},
buildSets = {
@ -820,6 +614,7 @@ if settings.startup["rampant-laserEnemy"].value then
type = "biter-spawner",
name = "biter-spawner",
majorResistances = {"laser", "electric"},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {},
drops = {"blueArtifact"},
buildSets = {
@ -831,6 +626,7 @@ if settings.startup["rampant-laserEnemy"].value then
name = "worm",
majorResistances = {"laser", "electric"},
attackAttributes = {"spit", "laser", "cluster"},
acceptRate = {1, 10, 0.8, 0.6},
attributes = {},
drops = {"blueArtifact"}
},
@ -839,6 +635,7 @@ if settings.startup["rampant-laserEnemy"].value then
name = "hive",
majorResistances = {"laser", "electric"},
attributes = {},
acceptRate = {2, 10, 0.005, 0.003},
drops = {"blueArtifact"},
buildSets = {
{"biter-spawner", 1, 10, 0.1, 0.2},
@ -856,6 +653,7 @@ if settings.startup["rampant-fireEnemy"].value then
type = "fire",
tint = {r=1, g=1, b=1, a=1},
tint2 = {r=0.9, g=0, b=0, a=1},
acceptRate = {2, 10, 0.1, 0.15},
evo = 0.12,
units = {
{
@ -883,6 +681,7 @@ if settings.startup["rampant-fireEnemy"].value then
name = "spitter-spawner",
majorResistances = {"fire", "acid"},
minorResistances = {},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {},
drops = {"redArtifact"},
buildSets = {
@ -893,6 +692,7 @@ if settings.startup["rampant-fireEnemy"].value then
type = "biter-spawner",
name = "biter-spawner",
majorResistances = {"fire", "acid"},
acceptRate = {1, 10, 0.1, 0.2},
minorResistances = {},
attributes = {},
drops = {"redArtifact"},
@ -906,6 +706,7 @@ if settings.startup["rampant-fireEnemy"].value then
majorResistances = {"fire", "acid"},
minorResistances = {},
attackAttributes = {"spit", "acid"},
acceptRate = {1, 10, 0.8, 0.6},
attributes = {},
drops = {"redArtifact"}
},
@ -915,6 +716,7 @@ if settings.startup["rampant-fireEnemy"].value then
majorResistances = {"fire", "acid"},
minorResistances = {},
attributes = {},
acceptRate = {2, 10, 0.005, 0.03},
drops = {"redArtifact"},
buildSets = {
{"biter-spawner", 1, 10, 0.1, 0.2},
@ -931,7 +733,8 @@ if settings.startup["rampant-infernoEnemy"].value then
constants.FACTION_SET[#constants.FACTION_SET+1] = {
type = "inferno",
tint = {r=0.7, g=0.45, b=0.5, a=1},
tint2 = {r=0.9, g=0, b=0, a=1},
tint2 = {r=0.9, g=0, b=0, a=1},
acceptRate = {3, 10, 0.1, 0.125},
evo = 0.2,
units = {
{
@ -950,6 +753,7 @@ if settings.startup["rampant-infernoEnemy"].value then
name = "spitter-spawner",
majorResistances = {"acid", "fire"},
minorWeaknesses = {"poison"},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {},
drops = {"orangeArtifact"},
buildSets = {
@ -961,6 +765,7 @@ if settings.startup["rampant-infernoEnemy"].value then
name = "worm",
majorResistances = {"acid", "fire"},
minorWeaknesses = {"poison"},
acceptRate = {1, 10, 0.8, 0.6},
attackAttributes = {"stream", "acid"},
attributes = {},
drops = {"orangeArtifact"}
@ -969,11 +774,125 @@ if settings.startup["rampant-infernoEnemy"].value then
}
end
if settings.startup["rampant-waspEnemy"].value then
constants.FACTION_SET[#constants.FACTION_SET+1] = {
type = "wasp",
tint = {r=0.9, g=0.8, b=0.9, a=1},
tint2 = {r=0.85, g=0.85, b=0, a=1},
acceptRate = {3, 10, 0.1, 0.125},
evo = 0.2,
units = {
{
type = "drone",
attackAttributes = {"spit", "acid"},
name = "wasp",
attributes = {"followsPlayer"},
drops = {}
},
{
type = "drone",
attackAttributes = {"stream", "acid"},
name = "worm-wasp",
attributes = {"stationary"},
drops = {}
},
{
type = "spitter",
attackAttributes = {"capsule", {"drone", "wasp"}},
name = "spitter",
attributes = {},
drops = {"purpleArtifact"}
}
},
buildings = {
{
type = "spitter-spawner",
name = "spitter-spawner",
attributes = {},
acceptRate = {1, 10, 0.1, 0.2},
drops = {"purpleArtifact"},
buildSets = {
{"spitter", 1, 10}
}
},
{
type = "turret",
name = "worm",
attackAttributes = {"capsule", {"drone", "worm-wasp"}},
acceptRate = {1, 10, 0.8, 0.6},
attributes = {},
drops = {"purpleArtifact"}
}
}
}
end
if settings.startup["rampant-spawnerEnemy"].value then
constants.FACTION_SET[#constants.FACTION_SET+1] = {
type = "spawner",
tint = {r=0.7, g=0, b=0.7, a=1},
tint2 = {r=0.8, g=0, b=0.8, a=1},
acceptRate = {3, 10, 0.1, 0.125},
evo = 0.2,
units = {
{
type = "biter",
attackAttributes = {"melee"},
name = "spawn",
attributes = {"fragile", "unstable", "smallest"},
drops = {}
},
{
type = "drone",
attackAttributes = {"touch", "acid"},
name = "egg",
attributes = {"stationary", {"clusterDeath", "spawn"}},
drops = {}
},
{
type = "drone",
attackAttributes = {"touch", "acid"},
name = "worm-egg",
attributes = {"stationary", {"clusterDeath", "spawn"}},
drops = {}
},
{
type = "spitter",
attackAttributes = {"capsule", {"drone", "egg"}},
name = "spitter",
attributes = {"selfDamaging"},
drops = {"orangeArtifact"}
}
},
buildings = {
{
type = "spitter-spawner",
name = "spitter-spawner",
attributes = {},
drops = {"orangeArtifact"},
acceptRate = {1, 10, 0.1, 0.2},
buildSets = {
{"spitter", 1, 10}
}
},
{
type = "turret",
name = "worm",
attackAttributes = {"capsule", {"drone", "worm-egg"}},
acceptRate = {1, 10, 0.8, 0.6},
attributes = {},
drops = {"orangeArtifact"}
}
}
}
end
if settings.startup["rampant-electricEnemy"].value then
constants.FACTION_SET[#constants.FACTION_SET+1] = {
type = "electric",
tint = {r=0.7, g=0.7, b=1.0, a=1.0},
tint2 = {r=0, g=0, b=1, a=1},
acceptRate = {2, 10, 0.1, 0.15},
evo = 0.1,
units = {
{
@ -992,6 +911,7 @@ if settings.startup["rampant-electricEnemy"].value then
name = "biter-spawner",
majorResistances = {"electric"},
minorResistances = {"laser"},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {},
drops = {"blueArtifact"},
buildSets = {
@ -1003,6 +923,7 @@ if settings.startup["rampant-electricEnemy"].value then
name = "worm",
majorResistances = {"electric"},
minorResistances = {"laser"},
acceptRate = {1, 10, 0.8, 0.6},
attackAttributes = {"spit", "electric", "cluster"},
attributes = {},
drops = {"blueArtifact"}
@ -1016,6 +937,7 @@ if settings.startup["rampant-physicalEnemy"].value then
type = "physical",
tint = {r=0.9, g=0.9, b=0.9, a=1},
tint2 = {r=0, g=0, b=0, a=1},
acceptRate = {2, 10, 0.1, 0.15},
evo = 0.12,
units = {
{
@ -1035,6 +957,7 @@ if settings.startup["rampant-physicalEnemy"].value then
majorResistances = {"physical", "explosion"},
minorWeaknesses = {"laser", "electric"},
attributes = {"highHealth", "big", "highRegen"},
acceptRate = {1, 10, 0.1, 0.2},
drops = {"redArtifact"},
buildSets = {
{"biter", 1, 10}
@ -1046,6 +969,7 @@ if settings.startup["rampant-physicalEnemy"].value then
majorResistances = {"physical", "explosion"},
minorWeaknesses = {"laser", "electric"},
attackAttributes = {"spit", "physical"},
acceptRate = {1, 10, 0.8, 0.6},
attributes = {"highHealth", "big", "highRegen"},
drops = {"redArtifact"}
}
@ -1058,6 +982,7 @@ if settings.startup["rampant-trollEnemy"].value then
type = "troll",
tint = {r=0.4, g=0.4, b=0.4, a=1},
tint2 = {r=0.8, g=0.8, b=0.8, a=1},
acceptRate = {3, 10, 0.1, 0.125},
evo = 0.17,
units = {
{
@ -1076,6 +1001,7 @@ if settings.startup["rampant-trollEnemy"].value then
name = "biter-spawner",
minorResistances = {"physical", "explosion"},
majorWeaknesses = {"fire"},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {"highestHealth", "bigger", "highestRegen"},
drops = {"greenArtifact"},
buildSets = {
@ -1088,6 +1014,7 @@ if settings.startup["rampant-trollEnemy"].value then
minorResistances = {"physical", "explosion"},
majorWeaknesses = {"fire"},
attackAttributes = {"spit", "physical"},
acceptRate = {1, 10, 0.8, 0.6},
attributes = {"highestHealth", "bigger", "highestRegen"},
drops = {"greenArtifact"}
}
@ -1100,6 +1027,7 @@ if settings.startup["rampant-poisonEnemy"].value then
type = "poison",
tint = {r=0.4, g=0.6, b=0.5, a=1},
tint2 = {r=0, g=0.7, b=0, a=1},
acceptRate = {2, 10, 0.1, 0.15},
evo = 0.17,
units = {
{
@ -1119,8 +1047,9 @@ if settings.startup["rampant-poisonEnemy"].value then
name = "biter-spawner",
minorResistances = {"fire"},
majorResistances = {"poison"},
minorWeaknesses = {"electric", "explosion", "laser"},
minorWeaknesses = {"electric", "explosion", "laser"},
attributes = {"poisonDeathCloud"},
acceptRate = {1, 10, 0.1, 0.2},
drops = {"greenArtifact"},
buildSets = {
{"biter", 1, 10}
@ -1132,6 +1061,7 @@ if settings.startup["rampant-poisonEnemy"].value then
minorResistances = {"fire"},
majorResistances = {"poison"},
minorWeaknesses = {"electric", "explosion", "laser"},
acceptRate = {1, 10, 0.8, 0.6},
attackAttributes = {"spit", "poison"},
attributes = {"poisonDeathCloud"},
drops = {"greenArtifact"}
@ -1145,6 +1075,7 @@ if settings.startup["rampant-suicideEnemy"].value then
type = "suicide",
tint = {r=1, g=1, b=1, a=1},
tint2 = {r=0.85, g=0.85, b=0, a=1},
acceptRate = {1, 10, 0.05, 0.15},
evo = 0.12,
units = {
{
@ -1163,6 +1094,7 @@ if settings.startup["rampant-suicideEnemy"].value then
name = "biter-spawner",
majorResistances = {"explosion"},
minorResistances = {"poison"},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {},
drops = {"yellowArtifact", "quickSpawning", "lowUnits"},
buildSets = {
@ -1175,6 +1107,7 @@ if settings.startup["rampant-suicideEnemy"].value then
majorResistances = {"explosion"},
minorResistances = {"poison"},
attackAttributes = {"spit", "acid", "slow"},
acceptRate = {1, 10, 0.8, 0.6},
attributes = {},
drops = {"yellowArtifact"}
}
@ -1182,12 +1115,12 @@ if settings.startup["rampant-suicideEnemy"].value then
}
end
if settings.startup["rampant-nuclearEnemy"].value then
constants.FACTION_SET[#constants.FACTION_SET+1] = {
type = "nuclear",
tint = {r=0.6, g=0.6, b=0.4, a=1},
tint2 = {r=0.95, g=0.95, b=0, a=1},
acceptRate = {3, 10, 0.1, 0.125},
evo = 0.2,
units = {
{
@ -1205,6 +1138,7 @@ if settings.startup["rampant-nuclearEnemy"].value then
name = "biter-spawner",
majorResistances = {"explosion"},
minorResistances = {"fire"},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {},
drops = {"yellowArtifact", "quickSpawning", "lowUnits"},
buildSets = {
@ -1216,6 +1150,7 @@ if settings.startup["rampant-nuclearEnemy"].value then
name = "worm",
majorResistances = {"explosion"},
minorResistances = {"fire"},
acceptRate = {1, 10, 0.8, 0.6},
attackAttributes = {"spit", "acid", "slow"},
attributes = {},
drops = {"yellowArtifact"}
@ -1224,12 +1159,12 @@ if settings.startup["rampant-nuclearEnemy"].value then
}
end
if settings.startup["rampant-energyThiefEnemy"].value then
constants.FACTION_SET[#constants.FACTION_SET+1] = {
type = "energy-thief",
tint = {r=0.4, g=0.5, b=0.7, a=1},
tint2 = {r=0, g=0, b=0.7, a=1},
acceptRate = {3, 10, 0.1, 0.125},
evo = 0.2,
units = {
{
@ -1248,6 +1183,7 @@ if settings.startup["rampant-energyThiefEnemy"].value then
name = "biter-spawner",
majorResistances = {"electric", "laser"},
minorResistances = {},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {},
drops = {"blueArtifact"},
buildSets = {
@ -1259,6 +1195,7 @@ if settings.startup["rampant-energyThiefEnemy"].value then
name = "worm",
majorResistances = {"electric", "laser"},
minorResistances = {},
acceptRate = {1, 10, 0.8, 0.6},
attackAttributes = {"spit", "electric", "cluster"},
attributes = {},
drops = {"blueArtifact"}
@ -1272,6 +1209,7 @@ if settings.startup["rampant-fastEnemy"].value then
type = "fast",
tint = {r=0.26, g=0.66, b=0.62, a=1},
tint2 = {r=0, g=0.85, b=0.80, a=1},
acceptRate = {2, 10, 0.1, 0.15},
evo = 0.12,
units = {
{
@ -1300,6 +1238,7 @@ if settings.startup["rampant-fastEnemy"].value then
majorResistances = {},
minorResistances = {"explosion"},
attributes = {"quickSpawning"},
acceptRate = {1, 10, 0.1, 0.2},
drops = {"purpleArtifact"},
buildSets = {
{"spitter", 1, 10}
@ -1310,6 +1249,7 @@ if settings.startup["rampant-fastEnemy"].value then
name = "biter-spawner",
majorResistances = {},
minorResistances = {"explosion"},
acceptRate = {1, 10, 0.1, 0.2},
attributes = {"quickSpawning"},
drops = {"purpleArtifact"},
buildSets = {
@ -1321,6 +1261,7 @@ if settings.startup["rampant-fastEnemy"].value then
name = "worm",
majorResistances = {},
minorResistances = {"explosion"},
acceptRate = {1, 10, 0.8, 0.6},
attackAttributes = {"spit", "acid"},
attributes = {"quickCooldown"},
drops = {"purpleArtifact"}
@ -1331,6 +1272,7 @@ if settings.startup["rampant-fastEnemy"].value then
majorResistances = {},
minorResistances = {"explosion"},
attributes = {"quickSpawning"},
acceptRate = {2, 10, 0.005, 0.03},
drops = {"purpleArtifact"},
buildSets = {
{"biter-spawner", 1, 10, 0.1, 0.2},
@ -1343,87 +1285,6 @@ if settings.startup["rampant-fastEnemy"].value then
}
end
constants.BUILDING_SPACE_LOOKUP = {}
for t = 1, 10 do
local wormTier = t + 1
for v = 1, 20 do
constants.BUILDING_SPACE_LOOKUP["neutral-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["neutral-spitter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["neutral-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["acid-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["acid-spitter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["acid-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["acid-hive-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["physical-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["physical-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["electric-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["electric-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["suicide-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["suicide-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["nuclear-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["nuclear-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["fire-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["fire-spitter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["fire-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["inferno-spitter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["inferno-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["troll-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["troll-spitter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["troll-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["fast-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["fast-spitter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["fast-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["laser-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["laser-spitter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["laser-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["wasp-spitter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["wasp-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["spawner-spitter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["spawner-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["energy-thief-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["energy-thief-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["poison-biter-spawner-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. t .. "-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["poison-worm-v" .. v .. "-t" .. t .. "-rampant"] = "chunk-scanner-" .. wormTier .. "-nest-rampant"
end
end
constants.BUILDING_SPACE_LOOKUP["biter-spawner"] = "chunk-scanner-5-nest-rampant"
constants.BUILDING_SPACE_LOOKUP["spitter-spawner"] = "chunk-scanner-5-nest-rampant"
-- constants.FACTION_TYPES = {
-- "neutral",
-- "acid",
-- "physical",
-- "electric",
-- "suicide",
-- "nuclear",
-- "fire",
-- "inferno",
-- "troll",
-- "fast",
-- "laser",
-- "wasp",
-- "spawner",
-- "energy-thief",
-- "poison"
-- }
constants.HIVE_BUILDINGS_TYPES = {
"trap",
"turret",
@ -1433,42 +1294,13 @@ constants.HIVE_BUILDINGS_TYPES = {
"hive"
}
-- constants.HIVE_BUILDINGS = {}
-- for t=1,10 do
-- for ift=1,#constants.FACTION_TYPES do
-- for ihbt=1,#constants.HIVE_BUILDINGS_TYPES do
-- local hbt = constants.HIVE_BUILDINGS_TYPES[ihbt]
-- local name = constants.FACTION_TYPES[ift]
-- if (hbt == "turret") then
-- local set = {}
-- constants.HIVE_BUILDINGS["entity-proxy-" .. hbt .. "-t" .. t .. "-rampant"] = set
-- for v=1,20 do
-- set[#set+1] = true
-- end
-- elseif (hbt == "spitter-spawner") then
-- local set = {}
-- constants.HIVE_BUILDINGS["entity-proxy-" .. hbt .. "-t" .. t .. "-rampant"] = set
-- for v=1,20 do
-- set[#set+1] = true
-- end
-- elseif (hbt == "biter-spawner") then
-- local set = {}
-- constants.HIVE_BUILDINGS["entity-proxy-" .. hbt .. "-t" .. t .. "-rampant"] = set
-- for v=1,20 do
-- set[#set+1] = true
-- end
-- elseif (hbt == "hive") then
-- local set = {}
-- constants.HIVE_BUILDINGS["entity-proxy-" .. hbt .. "-t" .. t .. "-rampant"] = set
-- for v=1,20 do
-- set[#set+1] = true
-- end
-- end
-- end
-- end
-- end
constants.HIVE_BUILDINGS_COST = {}
constants.HIVE_BUILDINGS_COST["trap"] = constants.BASE_WORM_UPGRADE * 0.5
constants.HIVE_BUILDINGS_COST["turret"] = constants.BASE_WORM_UPGRADE
constants.HIVE_BUILDINGS_COST["utility"] = constants.BASE_SPAWNER_UPGRADE * 1.5
constants.HIVE_BUILDINGS_COST["spitter-spawner"] = constants.BASE_SPAWNER_UPGRADE
constants.HIVE_BUILDINGS_COST["biter-spawner"] = constants.BASE_SPAWNER_UPGRADE
constants.HIVE_BUILDINGS_COST["hive"] = constants.BASE_SPAWNER_UPGRADE * 2
constantsG = constants
return constants

View File

@ -113,7 +113,7 @@ end
In theory, this might be fine as smaller bases have less surface to attack and need to have
pheromone dissipate at a faster rate.
--]]
function mapProcessor.processMap(map, surface, natives, tick, evolutionFactor)
function mapProcessor.processMap(map, surface, tick)
local roll = map.processRoll
local index = map.processIndex
@ -124,6 +124,8 @@ function mapProcessor.processMap(map, surface, natives, tick, evolutionFactor)
map.processRoll = roll
end
local natives = map.natives
local newEnemies = natives.newEnemies
local scentStaging = map.scentStaging
@ -143,16 +145,16 @@ function mapProcessor.processMap(map, surface, natives, tick, evolutionFactor)
processPheromone(map, chunk, scentStaging[i])
if squads then
squads = formSquads(map, surface, natives, chunk, tick)
squads = formSquads(map, surface, chunk, tick)
end
if settlers and (getNestCount(map, chunk) > 0) then
settlers = formSettlers(map, surface, natives, chunk, tick)
settlers = formSettlers(map, surface, chunk, tick)
end
if newEnemies then
local base = chunkToBase[chunk]
if base and ((tick - base.tick) > BASE_PROCESS_INTERVAL) and (mRandom() < 0.10) then
processBase(map, chunk, surface, natives, tick, base, evolutionFactor)
processBase(chunk, surface, natives, tick, base)
end
end
end
@ -181,10 +183,11 @@ end
vs
the slower passive version processing the entire map in multiple passes.
--]]
function mapProcessor.processPlayers(players, map, surface, natives, tick)
function mapProcessor.processPlayers(players, map, surface, tick)
-- put down player pheromone for player hunters
-- randomize player order to ensure a single player isn't singled out
local playerOrdering = nonRepeatingRandom(map, players)
local natives = map.natives
local roll = mRandom()
@ -243,7 +246,7 @@ function mapProcessor.processPlayers(players, map, surface, natives, tick)
squads = formSquads(map, surface, natives, chunk)
end
if vengence and (getNestCount(map, chunk) > 0) then
vengence = formVengenceSquad(map, surface, natives, chunk)
vengence = formVengenceSquad(map, surface, chunk)
end
end
i = i + 1
@ -279,7 +282,7 @@ end
--[[
Passive scan to find entities that have been generated outside the factorio event system
--]]
function mapProcessor.scanMap(map, surface, natives, tick)
function mapProcessor.scanMap(map, surface, tick)
local index = map.scanIndex
local unitCountQuery = map.filteredEntitiesEnemyUnitQuery
@ -296,6 +299,8 @@ function mapProcessor.scanMap(map, surface, natives, tick)
local endIndex = mMin(index + SCAN_QUEUE_SIZE, #processQueue)
local isFullMapScan = settings.global["rampant-enableFullMapScan"].value
local natives = map.natives
for x=index,endIndex do
local chunk = processQueue[x]

View File

@ -34,7 +34,19 @@ end
function mathUtils.randomTickEvent(tick, low, high)
local range = high - low
local minutesToTick = (range * mRandom()) + low
return tick + (TICKS_A_MINUTE * minutesToTick)
return tick + mathUtils.roundToNearest(TICKS_A_MINUTE * minutesToTick, 1)
end
function mathUtils.distort(xorRandom, num, stdDev, min, max)
local min = min or num * 0.85
local max = max or num * 1.30
local sd = stdDev or 0.30
if (num < 0) then
local t = min
min = max
max = t
end
return mathUtils.roundToNearest(mathUtils.gaussianRandomRangeRG(num, num * sd, min, max, xorRandom), 0.01)
end
function mathUtils.linearInterpolation(percent, min, max)

View File

@ -87,7 +87,7 @@ end
--[[
Expects all neighbors adjacent to a chunk
--]]
function movementUtils.scoreNeighborsForAttack(map, natives, chunk, neighborDirectionChunks, scoreFunction, squad)
function movementUtils.scoreNeighborsForAttack(map, chunk, neighborDirectionChunks, scoreFunction, squad)
local highestChunk = SENTINEL_IMPASSABLE_CHUNK
local highestScore = -MAGIC_MAXIMUM_NUMBER
local highestDirection
@ -96,6 +96,8 @@ function movementUtils.scoreNeighborsForAttack(map, natives, chunk, neighborDire
local nextHighestScore = -MAGIC_MAXIMUM_NUMBER
local nextHighestDirection
local natives = map.natives
for x=1,8 do
local neighborChunk = neighborDirectionChunks[x]

View File

@ -1,209 +0,0 @@
if neBaseUtilsG then
return neBaseUtilsG
end
local ne = {}
-- imports
local constants = require("Constants")
-- imported constants
local BASE_ALIGNMENT_NE = constants.BASE_ALIGNMENT_NE
local ENABLED_BOBS_UNITS = constants.ENABLED_BOBS_UNITS
local BASE_ALIGNMENT_NE_BLUE = constants.BASE_ALIGNMENT_NE_BLUE
local BASE_ALIGNMENT_NE_RED = constants.BASE_ALIGNMENT_NE_RED
local BASE_ALIGNMENT_NE_PINK = constants.BASE_ALIGNMENT_NE_PINK
local BASE_ALIGNMENT_NE_GREEN = constants.BASE_ALIGNMENT_NE_GREEN
local BASE_ALIGNMENT_NE_YELLOW = constants.BASE_ALIGNMENT_NE_YELLOW
-- imported functions
local mMin = math.min
-- module code
local function fileEntity(baseAlignment, entity, evolutionTable, natives, evo)
local evoRequirement = mMin(evo or entity.prototype.build_base_evolution_requirement, 1)
local eTable = evolutionTable[baseAlignment]
if not eTable then
eTable = {}
evolutionTable[baseAlignment] = eTable
end
local aTable = eTable[evoRequirement]
if not aTable then
aTable = {}
eTable[evoRequirement] = aTable
end
aTable[#aTable+1] = entity.name
-- natives.enemyAlignmentLookup[entity.name] = baseAlignment
end
function ne.processNEUnitClass(natives, surface)
local position = { x = 0, y = 0 }
local factionSet = {}
local entity = surface.create_entity({
name = "biter-spawner",
position = position
})
fileEntity(BASE_ALIGNMENT_NE, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
entity.destroy()
entity = surface.create_entity({
name = "spitter-spawner",
position = position
})
fileEntity(BASE_ALIGNMENT_NE, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
entity.destroy()
if settings.startup["NE_Blue_Spawners"].value then
entity = surface.create_entity({
name = "ne-spawner-blue",
position = position
})
fileEntity(BASE_ALIGNMENT_NE_BLUE, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
factionSet[#factionSet+1] = BASE_ALIGNMENT_NE_BLUE
entity.destroy()
end
if settings.startup["NE_Red_Spawners"].value then
entity = surface.create_entity({
name = "ne-spawner-red",
position = position
})
fileEntity(BASE_ALIGNMENT_NE_RED, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
factionSet[#factionSet+1] = BASE_ALIGNMENT_NE_RED
entity.destroy()
end
if settings.startup["NE_Green_Spawners"].value then
entity = surface.create_entity({
name = "ne-spawner-green",
position = position
})
fileEntity(BASE_ALIGNMENT_NE_GREEN, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
factionSet[#factionSet+1] = BASE_ALIGNMENT_NE_GREEN
entity.destroy()
end
if settings.startup["NE_Yellow_Spawners"].value then
entity = surface.create_entity({
name = "ne-spawner-yellow",
position = position
})
fileEntity(BASE_ALIGNMENT_NE_YELLOW, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
factionSet[#factionSet+1] = BASE_ALIGNMENT_NE_YELLOW
entity.destroy()
end
if settings.startup["NE_Pink_Spawners"].value then
entity = surface.create_entity({
name = "ne-spawner-pink",
position = position
})
fileEntity(BASE_ALIGNMENT_NE_PINK, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
factionSet[#factionSet+1] = BASE_ALIGNMENT_NE_PINK
entity.destroy()
end
factionSet[#factionSet+1] = BASE_ALIGNMENT_NE
if ENABLED_BOBS_UNITS then
entity = surface.create_entity({
name = "bob-biter-spawner",
position = position
})
fileEntity(BASE_ALIGNMENT_NE, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
entity.destroy()
entity = surface.create_entity({
name = "bob-spitter-spawner",
position = position
})
fileEntity(BASE_ALIGNMENT_NE, entity, natives.evolutionTableUnitSpawner, natives, 0.0)
entity.destroy()
for _,alignment in pairs(factionSet) do
entity = surface.create_entity({
name = "bob-big-fire-worm-turret",
position = position
})
fileEntity(alignment, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-big-poison-worm-turret",
position = position
})
fileEntity(alignment, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-big-piercing-worm-turret",
position = position
})
fileEntity(alignment, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-big-electric-worm-turret",
position = position
})
fileEntity(alignment, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-giant-worm-turret",
position = position
})
fileEntity(alignment, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "behemoth-worm-turret",
position = position
})
fileEntity(alignment, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "bob-big-explosive-worm-turret",
position = position
})
fileEntity(alignment, entity, natives.evolutionTableWorm, natives)
entity.destroy()
end
end
for _,alignment in pairs(factionSet) do
entity = surface.create_entity({
name = "small-worm-turret",
position = position
})
fileEntity(alignment, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "medium-worm-turret",
position = position
})
fileEntity(alignment, entity, natives.evolutionTableWorm, natives)
entity.destroy()
entity = surface.create_entity({
name = "big-worm-turret",
position = position
})
fileEntity(alignment, entity, natives.evolutionTableWorm, natives)
entity.destroy()
end
end
neBaseUtilsG = ne
return ne

View File

@ -116,7 +116,7 @@ local function scoreAttackKamikazeLocation(natives, squad, neighborChunk)
end
local function settleMove(map, squad, natives, surface)
local function settleMove(map, squad, surface)
local targetPosition = map.position
local targetPosition2 = map.position2
local group = squad.group
@ -126,6 +126,7 @@ local function settleMove(map, squad, natives, surface)
local chunk = getChunkByXY(map, x, y)
local scoreFunction = scoreResourceLocation
local groupState = group.state
local natives = map.natives
if (natives.state == AI_STATE_SIEGE) then
scoreFunction = scoreSiegeLocation
end
@ -196,6 +197,8 @@ local function settleMove(map, squad, natives, surface)
positionFromDirectionAndFlat(attackDirection, groupPosition, targetPosition)
position = findMovementPosition(surface, targetPosition)
local attackPlayerThreshold = natives.attackPlayerThreshold
if not position then
squad.cycles = 30
cmd = map.wonderCommand
@ -206,7 +209,7 @@ local function settleMove(map, squad, natives, surface)
targetPosition.y = position.y
if (getPlayerBaseGenerator(map, attackChunk) ~= 0) or
(attackChunk[PLAYER_PHEROMONE] >= natives.attackPlayerThreshold)
(attackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold)
then
cmd = map.attackCommand
@ -236,7 +239,7 @@ local function settleMove(map, squad, natives, surface)
if ((cmd ~= map.attackCommand) and
((getPlayerBaseGenerator(map, nextAttackChunk) ~= 0) or
(nextAttackChunk[PLAYER_PHEROMONE] >= natives.attackPlayerThreshold)))
(nextAttackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold)))
then
cmd = map.attackCommand
@ -282,7 +285,7 @@ local function settleMove(map, squad, natives, surface)
end
end
local function attackMove(map, squad, natives, surface)
local function attackMove(map, squad, surface)
local targetPosition = map.position
local targetPosition2 = map.position2
@ -303,7 +306,6 @@ local function attackMove(map, squad, natives, surface)
end
squad.frenzy = (squad.frenzy and (euclideanDistanceNamed(groupPosition, squad.frenzyPosition) < 100))
local attackChunk, attackDirection, nextAttackChunk, nextAttackDirection = scoreNeighborsForAttack(map,
natives,
chunk,
getNeighborChunks(map, x, y),
attackScorer,
@ -316,6 +318,7 @@ local function attackMove(map, squad, natives, surface)
else
positionFromDirectionAndFlat(attackDirection, groupPosition, targetPosition)
local attackPlayerThreshold = map.natives.attackPlayerThreshold
local position = findMovementPosition(surface, targetPosition)
if not position then
@ -328,7 +331,7 @@ local function attackMove(map, squad, natives, surface)
targetPosition.y = position.y
if (getPlayerBaseGenerator(map, attackChunk) ~= 0) and
(attackChunk[PLAYER_PHEROMONE] >= natives.attackPlayerThreshold)
(attackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold)
then
cmd = map.attackCommand
@ -360,7 +363,7 @@ local function attackMove(map, squad, natives, surface)
if (cmd ~= map.attackCommand) and
((getPlayerBaseGenerator(map, nextAttackChunk) ~= 0) or
(nextAttackChunk[PLAYER_PHEROMONE] >= natives.attackPlayerThreshold))
(nextAttackChunk[PLAYER_PHEROMONE] >= attackPlayerThreshold))
then
cmd = map.attackCommand
@ -378,7 +381,8 @@ local function attackMove(map, squad, natives, surface)
end
end
function squadAttack.squadsDispatch(map, surface, natives)
function squadAttack.squadsDispatch(map, surface)
local natives = map.natives
local squads = natives.squads
-- print("start dispatch")
@ -422,7 +426,7 @@ function squadAttack.squadsDispatch(map, surface, natives)
(groupState == DEFINES_GROUP_GATHERING) or
((groupState == DEFINES_GROUP_MOVING) and (cycles <= 0))
then
attackMove(map, squad, natives, surface)
attackMove(map, squad, surface)
else
local chunk = getChunkByPosition(map, group.position)
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
@ -436,7 +440,7 @@ function squadAttack.squadsDispatch(map, surface, natives)
(groupState == DEFINES_GROUP_GATHERING) or
((groupState == DEFINES_GROUP_MOVING) and (cycles <= 0))
then
settleMove(map, squad, natives, surface)
settleMove(map, squad, surface)
else
local chunk = getChunkByPosition(map, group.position)
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then

View File

@ -56,7 +56,7 @@ local function scoreRetreatLocation(map, neighborChunk)
-(getPlayerBaseGenerator(map, neighborChunk) * 1000))
end
function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, tick, radius, artilleryBlast)
function aiDefense.retreatUnits(chunk, position, squad, map, surface, tick, radius, artilleryBlast)
if (tick - getRetreatTick(map, chunk) > INTERVAL_RETREAT) and
((getEnemyStructureCount(map, chunk) == 0) or artilleryBlast)
then
@ -75,7 +75,7 @@ function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, t
end
end
enemiesToSquad.len = unitCount
if (mRandom() < calculateKamikazeThreshold(unitCount, natives)) then
if (mRandom() < calculateKamikazeThreshold(unitCount, map.natives)) then
setRetreatTick(map, chunk, tick)
return
end
@ -122,7 +122,7 @@ function aiDefense.retreatUnits(chunk, position, squad, map, surface, natives, t
if not newSquad then
newSquad = createSquad(retreatPosition, surface)
local squads = natives.squads
local squads = map.natives.squads
squads.len = squads.len+1
squads[squads.len] = newSquad
end

View File

@ -178,13 +178,13 @@ function unitGroupUtils.recycleBiters(natives, biters)
natives.points = natives.points + (unitCount * natives.unitRefundAmount)
end
function unitGroupUtils.cleanBuilders(map, natives, surface)
function unitGroupUtils.cleanBuilders(natives, surface)
local squads = natives.building
local squadCount = #squads
local startIndex = natives.cleanBuildingIndex
local position = map.position
local cmd = map.compoundSettleCommand
local position = natives.map.position
local cmd = natives.map.compoundSettleCommand
local maxSquadIndex = mMin(startIndex + SQUAD_QUEUE_SIZE, squadCount)
for i=maxSquadIndex,startIndex,-1 do
@ -225,9 +225,10 @@ function unitGroupUtils.cleanBuilders(map, natives, surface)
end
end
function unitGroupUtils.regroupSquads(natives, map)
function unitGroupUtils.regroupSquads(natives)
local squads = natives.squads
local squadCount = squads.len
local map = natives.map
local startIndex = natives.regroupIndex

View File

@ -1,6 +1,7 @@
local swarmUtils = {}
-- imports
local droneUtils = require("utils/DroneUtils")
local bombUtils = require("utils/BombUtils")
local attackFlame = require("utils/AttackFlame")
local energyThiefFaction = require("EnergyThief")
@ -11,6 +12,7 @@ local droneUtils = require("utils/DroneUtils")
local biterUtils = require("utils/BiterUtils")
local particleUtils = require("utils/ParticleUtils")
local stickerUtils = require("utils/StickerUtils")
local unitUtils = require("utils/UnitUtils")
local constants = require("__Rampant__/libs/Constants")
local mathUtils = require("__Rampant__/libs/MathUtils")
@ -25,6 +27,8 @@ local roundToNearest = mathUtils.roundToNearest
local mMax = math.max
local mMin = math.min
local distort = mathUtils.distort
local mFloor = math.floor
local deepcopy = util.table.deepcopy
@ -32,13 +36,21 @@ local TIER_UPGRADE_SET_10 = constants.TIER_UPGRADE_SET_10
local xorRandom = mathUtils.xorRandom(settings.startup["rampant-enemySeed"].value)
local biterattackanimation = unitUtils.biterattackanimation
local createProjectileAttack = biterUtils.createProjectileAttack
local createCapsuleProjectile = droneUtils.createCapsuleProjectile
local makeSticker = stickerUtils.makeSticker
local makeAtomicBlast = bombUtils.makeAtomicBlast
local makeLaser = beamUtils.makeLaser
local createAttackBall = acidBall.createAttackBall
local createRangedAttack = biterUtils.createRangedAttack
local createMeleeAttack = biterUtils.createMeleeAttack
local makeUnitAlienLootTable = biterUtils.makeUnitAlienLootTabl
local makeWormAlienLootTable = biterUtils.makeWormAlienLootTable
local makeUnitAlienLootTable = biterUtils.makeUnitAlienLootTable
local makeSpawnerAlienLootTable = biterUtils.makeSpawnerAlienLootTable
local createSuicideAttack = biterUtils.createSuicideAttack
@ -159,9 +171,9 @@ local spitterAttributeNumeric = {
["range"] = { 13, 13, 14, 14, 15, 15, 16, 16, 17, 17 },
["radius"] = { 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5 },
["cooldown"] = { 100, 100, 97, 97, 95, 95, 93, 93, 90, 90 },
["stickerDuration"] = { 600, 650, 700, 750, 800, 850, 900, 950, 1000, 1050 },
["stickerDuration"] = { 600, 610, 620, 630, 640, 650, 660, 670, 680, 690 },
["damagePerTick"] = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 },
["stickerDamagePerTick"] = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 },
-- ["stickerDamagePerTick"] = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 },
["stickerMovementModifier"] = { 0.8, 0.7, 0.6, 0.55, 0.50, 0.45, 0.40, 0.35, 0.30, 0.25 },
["damage"] = { 16, 30, 45, 60, 90, 110, 130, 150, 170, 190 },
["particleVerticalAcceleration"] = { 0.01, 0.01, 0.02, 0.02, 0.03, 0.03, 0.04, 0.04, 0.05, 0.05 },
@ -180,14 +192,23 @@ local spitterAttributeNumeric = {
}
local droneAttributeNumeric = {
["scale"] = { 0.5, 0.5, 0.6, 0.6, 0.7, 0.7, 0.8, 0.8, 0.9, 0.9 },
["particleVerticalAcceleration"] = { 0.01, 0.01, 0.02, 0.02, 0.03, 0.03, 0.04, 0.04, 0.05, 0.05 },
["particleHoizontalSpeed"] = { 0.6, 0.6, 0.7, 0.7, 0.8, 0.8, 0.9, 0.9, 1, 1 },
["particleHoizontalSpeedDeviation"] = { 0.0025, 0.0025, 0.0024, 0.0024, 0.0023, 0.0023, 0.0022, 0.0022, 0.0021, 0.0021 },
["stickerDuration"] = { 600, 650, 700, 750, 800, 850, 900, 950, 1000, 1050 },
["stickerDuration"] = { 600, 610, 620, 630, 640, 650, 660, 670, 680, 690 },
["stickerMovementModifier"] = { 0.8, 0.7, 0.6, 0.55, 0.50, 0.45, 0.40, 0.35, 0.30, 0.25 },
["damagePerTick"] = { 0.1, 0.2, 0.6, 1.2, 1.2, 1.3, 1.3, 1.3, 1.4, 1.4 },
["cooldown"] = { 100, 100, 97, 97, 95, 95, 93, 93, 90, 90 },
["health"] = { 100, 100, 110, 110, 120, 120, 130, 130, 140, 140 }
["damagePerTick"] = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 },
["cooldown"] = { 60, 60, 55, 55, 50, 50, 45, 45, 40, 40 },
["ttl"] = { 300, 300, 350, 350, 400, 400, 450, 450, 500, 500 },
["damage"] = { 2, 4, 7, 13, 15, 18, 22, 28, 35, 40 },
["movement"] = { 0.06, 0.06, 0.07, 0.07, 0.08, 0.08, 0.09, 0.09, 0.1, 0.1 },
["distancePerFrame"] = { 0.08, 0.08, 0.085, 0.085, 0.09, 0.09, 0.092, 0.092, 0.094, 0.094 },
["rangeFromPlayer"] = { 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 },
["range"] = { 10, 10, 11, 11, 12, 12, 13, 13, 14, 14 },
["radius"] = { 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.5 },
["health"] = { 15, 75, 100, 150, 200, 250, 275, 300, 325, 350 },
["healing"] = { 0.01, 0.01, 0.015, 0.02, 0.05, 0.075, 0.1, 0.12, 0.14, 0.16 },
}
local unitSpawnerAttributeNumeric = {
@ -231,9 +252,9 @@ local hiveAttributeNumeric = {
}
local wormAttributeNumeric = {
["stickerDuration"] = { 1200, 1250, 1300, 1350, 1400, 1450, 1500, 1550, 1600, 1650 },
["stickerDuration"] = { 800, 810, 820, 830, 840, 850, 860, 870, 880, 890 },
["stickerMovementModifier"] = { 0.8, 0.7, 0.6, 0.55, 0.50, 0.45, 0.40, 0.35, 0.30, 0.25 },
["damagePerTick"] = { 0.1, 0.2, 0.6, 1.2, 1.2, 1.3, 1.3, 1.3, 1.4, 1.4 },
["damagePerTick"] = { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1 },
["range"] = { 25, 27, 31, 33, 35, 36, 37, 38, 39, 40 },
["cooldown"] = { 70, 70, 68, 66, 64, 62, 60, 58, 56, 54 },
["damage"] = { 36, 45, 85, 135, 155, 175, 195, 215, 235, 255 },
@ -347,7 +368,9 @@ local function scaleAttributes (entity)
entity["movement"] = entity["movement"] * settings.startup["rampant-unitSpitterSpeedScaler"].value
entity["distancePerFrame"] = entity["distancePerFrame"] * settings.startup["rampant-unitSpitterSpeedScaler"].value
entity["damage"] = entity["damage"] * settings.startup["rampant-unitSpitterDamageScaler"].value
entity["stickerDamagePerTick"] = entity["stickerDamagePerTick"] * settings.startup["rampant-unitSpitterDamageScaler"].value
if entity["stickerDamagePerTick"] then
entity["stickerDamagePerTick"] = entity["stickerDamagePerTick"] * settings.startup["rampant-unitSpitterDamageScaler"].value
end
entity["damagePerTick"] = entity["damagePerTick"] * settings.startup["rampant-unitSpitterDamageScaler"].value
entity["range"] = entity["range"] * settings.startup["rampant-unitSpitterRangeScaler"].value
entity["healing"] = entity["healing"] * settings.startup["rampant-unitSpitterHealingScaler"].value
@ -375,16 +398,16 @@ local function scaleAttributes (entity)
end
end
local function distort(num, min, max)
local min = min or num * 0.85
local max = max or num * 1.30
if (num < 0) then
local t = min
min = max
max = t
end
return roundToNearest(gaussianRandomRangeRG(num, num * 0.15, min, max, xorRandom), 0.01)
end
-- local function distort(xorRandom, num, min, max)
-- local min = min or num * 0.85
-- local max = max or num * 1.30
-- if (num < 0) then
-- local t = min
-- min = max
-- max = t
-- end
-- return roundToNearest(gaussianRandomRangeRG(num, num * 0.15, min, max, xorRandom), 0.01)
-- end
local function fillEntityTemplate(entity)
local tier = entity.effectiveLevel
@ -392,41 +415,49 @@ local function fillEntityTemplate(entity)
if (entity.type == "biter") then
for key,value in pairs(biterAttributeNumeric) do
if not entity[key] then
entity[key] = distort(value[tier])
entity[key] = distort(xorRandom, value[tier])
else
entity[key] = distort(entity[key][tier])
entity[key] = distort(xorRandom, entity[key][tier])
end
end
elseif (entity.type == "spitter") then
for key,value in pairs(spitterAttributeNumeric) do
if not entity[key] then
entity[key] = distort(value[tier])
entity[key] = distort(xorRandom, value[tier])
else
entity[key] = distort(entity[key][tier])
entity[key] = distort(xorRandom, entity[key][tier])
end
end
elseif (entity.type == "biter-spawner") or (entity.type == "spitter-spawner") then
for key,value in pairs(unitSpawnerAttributeNumeric) do
if not entity[key] then
entity[key] = distort(value[tier])
entity[key] = distort(xorRandom, value[tier])
else
entity[key] = distort(entity[key][tier])
entity[key] = distort(xorRandom, entity[key][tier])
end
end
elseif (entity.type == "hive") then
for key,value in pairs(hiveAttributeNumeric) do
if not entity[key] then
entity[key] = distort(value[tier])
entity[key] = distort(xorRandom, value[tier])
else
entity[key] = distort(entity[key][tier])
entity[key] = distort(xorRandom, entity[key][tier])
end
end
elseif (entity.type == "turret") then
for key,value in pairs(wormAttributeNumeric) do
if not entity[key] then
entity[key] = distort(value[tier])
entity[key] = distort(xorRandom, value[tier])
else
entity[key] = distort(entity[key][tier])
entity[key] = distort(xorRandom, entity[key][tier])
end
end
elseif (entity.type == "drone") then
for key,value in pairs(droneAttributeNumeric) do
if not entity[key] then
entity[key] = distort(xorRandom, value[tier])
else
entity[key] = distort(xorRandom, entity[key][tier])
end
end
end
@ -463,9 +494,13 @@ local function fillEntityTemplate(entity)
entity.loot[#entity.loot+1] = lootTable[tier]
end
elseif (key == "explosion") then
entity[key] = entity[key] .. "-" .. bloodFountains[tier]
local ti = tier
if (entity.type == "drone") then
ti = 1
end
entity[key] = entity[key] .. "-" .. bloodFountains[ti]
elseif (key == "evolutionFunction") then
entity["evolutionRequirement"] = distort(value(tier))
entity["evolutionRequirement"] = distort(xorRandom, value(tier))
elseif (key == "majorResistances") then
for i=1,#value do
addMajorResistance(entity, value[i], tier)
@ -516,7 +551,38 @@ local function fillEntityTemplate(entity)
elseif (attribute == "big") then
entity["scale"] = entity["scale"] * 1.2
elseif (attribute == "bigger") then
entity["scale"] = entity["scale"] * 1.35
entity["scale"] = entity["scale"] * 1.35
elseif (attribute == "smallest") then
entity["scale"] = entity["scale"] * 0.5
elseif (attribute == "fragile") then
entity["health"] = entity["health"] * 0.1
elseif (attribute == "selfDamaging") then
local divider
if entity.health < 100 then
divider = 2
else
divider = 2.5
end
entity.healthDamage = entity.health / divider
entity.sourceEffect = function (attributes)
return
{
{
type = "damage",
affects_target = true,
damage = {amount = attributes.healthDamage or 5, type = attributes.damageType or "physical"}
}
}
end
elseif (attribute == "unstable") then
entity["healing"] = entity["healing"] * -1
elseif (attribute == "checkBuildability") then
entity.checkBuildability = true
elseif (attribute == "followsPlayer") then
entity.followsPlayer = true
elseif (attribute == "stationary") then
entity.movement = 0
entity.distancePerFrame = 0
elseif (attribute == "highHealth") then
entity["health"] = entity["health"] * 1.20
elseif (attribute == "poisonDeathCloud") then
@ -526,6 +592,33 @@ local function fillEntityTemplate(entity)
}
elseif (attribute == "highestHealth") then
entity["health"] = entity["health"] * 1.35
elseif type(attribute) == "table" then
if (attribute[1] == "clusterDeath") then
entity.deathGenerator = function (attack)
return {
{
type = "cluster",
cluster_count = attack.clusters,
distance = attack.clusterDistance,
distance_deviation = 3,
action_delivery =
{
type = "projectile",
projectile = createCapsuleProjectile(attack,
attack.faction .. "-" .. attribute[2]
.. "-v" .. attack.variation .. "-t"
.. attack.effectiveLevel .. "-rampant"),
direction_deviation = 0.6,
starting_speed = 0.25,
max_range = attack.range,
starting_speed_deviation = 0.3
}
}
}
end
else
error("Unknown table attribute " .. attribute[1])
end
else
error("Unknown attribute " .. attribute)
end
@ -578,6 +671,7 @@ function swarmUtils.buildUnits(template)
unit.name = unit.name .. "-v" .. i .. "-t" .. tier
-- unit.nameSuffix = "-v" .. i .. "-t" .. tier
unit.effectiveLevel = effectiveLevel
unit.variation = i
generateApperance(unit)
fillEntityTemplate(unit)
unit.attack = unit.attackGenerator(unit)
@ -590,7 +684,18 @@ function swarmUtils.buildUnits(template)
entity = makeBiter(unit)
elseif (unit.type == "drone") then
if not death then
error("drone needs death deathGenerator")
death = {
type = "direct",
action_delivery =
{
type = "instant",
target_effects =
{
type = "create-entity",
entity_name = unit.explosion
}
}
}
end
entity = makeDrone(unit)
end
@ -640,6 +745,7 @@ function swarmUtils.buildEntitySpawner(template)
local unitSpawner = deepcopy(template)
unitSpawner.name = unitSpawner.name .. "-v" .. i .. "-t" .. tier
unitSpawner.effectiveLevel = effectiveLevel
unitSpawner.variation = i
generateApperance(unitSpawner)
fillEntityTemplate(unitSpawner)
@ -652,10 +758,8 @@ function swarmUtils.buildEntitySpawner(template)
})
end
end
end
function swarmUtils.buildUnitSpawner(template)
local variations = settings.startup["rampant-newEnemyVariations"].value
@ -666,6 +770,7 @@ function swarmUtils.buildUnitSpawner(template)
local unitSpawner = deepcopy(template)
unitSpawner.name = unitSpawner.name .. "-v" .. i .. "-t" .. tier
unitSpawner.effectiveLevel = effectiveLevel
unitSpawner.variation = i
local unitTable = unitSetToProbabilityTable(template.unitSet)
unitSpawner.unitSet = unitTable
generateApperance(unitSpawner)
@ -691,6 +796,7 @@ function swarmUtils.buildWorm(template)
local worm = deepcopy(template)
worm.name = worm.name .. "-v" .. i .. "-t" .. tier
worm.effectiveLevel = effectiveLevel
worm.variation = i
generateApperance(worm)
fillEntityTemplate(worm)
@ -714,6 +820,8 @@ local function makeLootTables(template)
makeLootTable = makeWormAlienLootTable
elseif (template.type == "biter-spawner") or (template.type == "spitter-spawner") then
makeLootTable = makeSpawnerAlienLootTable
elseif (template.type == "hive") then
makeLootTable = makeSpawnerAlienLootTable
else
return nil
end
@ -746,7 +854,19 @@ local function buildAttack(faction, template)
template.attackGenerator = createMeleeAttack
elseif (attack == "spit") then
template.attackType = "projectile"
template.attackDirectionOnly = true
-- template.attackDirectionOnly = true
template.attackGenerator = function (attack)
return createRangedAttack(attack,
createAttackBall(attack),
(template.attackAnimation and template.attackAnimation(attack.scale,
attack.tint,
attack.tint2)) or nil)
end
elseif (attack == "touch") then
template.attackType = "projectile"
-- template.attackDirectionOnly = true
template.range = { 0.1, 0.1, 0.1, 0.2, 0.2, 0.3, 0.3, 0.3, 0.3, 0.4 }
template.attackGenerator = function (attack)
return createRangedAttack(attack,
@ -907,6 +1027,42 @@ local function buildAttack(faction, template)
attack.tint,
attack.tint2)) or nil)
end
elseif (attack == "capsule") then
template.attackType = "projectile"
-- template.attackDirectionOnly = true
template.attackGenerator = function (attack)
return createProjectileAttack(attack,
createCapsuleProjectile(attack,
attack.entityGenerator(attack)),
(template.attackAnimation and template.attackAnimation(attack.scale,
attack.tint,
attack.tint2)) or nil)
end
elseif (attack == "noFriendlyFire") then
template["force"] = "enemy"
elseif (attack == "noAcidPuddle") then
template.noAcidPuddle = true
elseif (type(attack) == "table") then
if (attack[1] == "drone") then
template.entityGenerator = function (attributes)
return template.faction .. "-" .. attack[2] .. "-v" ..
attributes.variation .. "-t" .. attributes.effectiveLevel .. "-drone-rampant"
end
end
else
error ("unknown attack " .. attack)
end
end
end
local function checkForAddons(template)
for i=1,#template.attributes do
local attribute = template.attributes[i]
if (type(attribute) == "table") then
if (attribute[1] == "clusterDeath") then
template.addon[#template.addon+1] = clusterAttackNumeric
end
end
end
end
@ -918,19 +1074,21 @@ local function buildUnitTemplate(faction, unit)
template.tint = faction.tint
template.tint2 = faction.tint2
template.faction = faction.type
template.addon = {}
template.explosion = faction.type
template.resistances = {}
local attackAnimation
if (unit.type == "biter") then
attackAnimation = biterattackanimation
elseif (unit.type == "spitter") then
attackAnimation = spitterattackanimation
if (template.type == "biter") then
template.attackAnimation = biterattackanimation
elseif (template.type == "spitter") then
template.attackAnimation = spitterattackanimation
end
template.attackAnimation = attackAnimation
checkForAddons(template)
buildAttack(faction, template)
@ -952,6 +1110,8 @@ local function buildTurretTemplate(faction, turret)
template.tint = faction.tint
template.tint2 = faction.tint2
template.faction = faction.type
template.evolutionFunction = function (tier)
if (tier == 0) then
return 0
@ -967,6 +1127,8 @@ local function buildTurretTemplate(faction, turret)
buildAttack(faction, template)
checkForAddons(template)
if template.drops then
template.drops = makeLootTables(template)
end
@ -985,6 +1147,8 @@ local function buildUnitSpawnerTemplate(faction, template, unitSets)
template.tint = faction.tint
template.tint2 = faction.tint2
template.faction = faction.type
template.evolutionFunction = function (tier)
if (tier == 0) then
return 0
@ -996,6 +1160,8 @@ local function buildUnitSpawnerTemplate(faction, template, unitSets)
template.explosion = faction.type
template.addon = {}
checkForAddons(template)
template.resistances = {}
local unitSet = {}
@ -1038,6 +1204,8 @@ local function buildHiveTemplate(faction, template)
template.tint = faction.tint
template.tint2 = faction.tint2
template.faction = faction.type
template.evolutionFunction = function (tier)
if (tier == 0) then
return 0
@ -1049,6 +1217,8 @@ local function buildHiveTemplate(faction, template)
template.addon = {}
template.explosion = faction.type
checkForAddons(template)
template.resistances = {}
local unitSet = {}
@ -1105,7 +1275,7 @@ function swarmUtils.processFactions()
{
type = "damage-type",
name = "healing"
}
}
})
poisonFaction.addFactionAddon()
end
@ -1127,11 +1297,11 @@ function swarmUtils.processFactions()
for iu=1,#faction.buildings do
local building = faction.buildings[iu]
if (building.type == "spitter-template") then
if (building.type == "spitter-spawner") then
local template = buildUnitSpawnerTemplate(faction, building, unitSets)
swarmUtils.buildUnitSpawner(template)
elseif (building.type == "biter-template") then
elseif (building.type == "biter-spawner") then
local template = buildUnitSpawnerTemplate(faction, building, unitSets)
swarmUtils.buildUnitSpawner(template)

View File

@ -45,35 +45,6 @@ local scales = {
[11] = 2.2
}
for t=1,11 do
local scale = scales[t] * 1.2
data:extend(
{
{
type = "simple-entity-with-force",
name = "chunk-scanner-" .. t .. "-nest-rampant",
icon = "__base__/graphics/icons/steel-chest.png",
icon_size = 32,
flags = {},
order = "s-e-w-f",
collision_mask = {"player-layer", "object-layer", "water-tile"},
minable = nil,
max_health = 100,
corpse = nil,
collision_box = {{-3 * scale, -2 * scale}, {2 * scale, 2 * scale}},
selection_box = {{-3 * scale, -2 * scale}, {2 * scale, 2 * scale}},
picture =
{
filename = "__core__/graphics/empty.png",
priority = "extra-high",
width = 1,
height = 1
}
}
}
)
end
local subTypes = constants.HIVE_BUILDINGS_TYPES
for t=1,11 do
@ -90,6 +61,7 @@ for t=1,11 do
icon = "__base__/graphics/icons/steel-chest.png",
icon_size = 32,
flags = {},
build_base_evolution_requirement = 0.8 * (t-1),
order = "s-e-w-f",
collision_mask = {"player-layer", "object-layer", "water-tile"},
minable = nil,

View File

@ -43,52 +43,62 @@ function AttackBall.createAttackBall(attributes)
}
}
local targetEffects
if attributes.attackPointEffects then
targetEffects = (attributes.attackPointEffects and attributes.attackPointEffects(attributes))
else
local rec = {
{
type = "damage",
damage = templateDirectDamage
},
{
type = "create-entity",
entity_name = "water-splash",
tile_collision_mask = { "ground-tile" }
},
{
type = "play-sound",
sound =
{
{
filename = "__base__/sound/creatures/projectile-acid-burn-1.ogg",
volume = 0.25 + (attributes.effectiveLevel * 0.05)
},
{
filename = "__base__/sound/creatures/projectile-acid-burn-2.ogg",
volume = 0.25 + (attributes.effectiveLevel * 0.05)
},
{
filename = "__base__/sound/creatures/projectile-acid-burn-long-1.ogg",
volume = 0.25 + (attributes.effectiveLevel * 0.05)
},
{
filename = "__base__/sound/creatures/projectile-acid-burn-long-2.ogg",
volume = 0.25 + (attributes.effectiveLevel * 0.05)
}
}
}
}
if not attributes.noAcidPuddle then
rec[#rec+1] = {
type="create-fire",
entity_name = makeAcidSplashFire(attributes, attributes.stickerName or makeSticker(attributes)),
check_buildability = true,
initial_ground_flame_count = 1,
show_in_tooltip = true
}
end
targetEffects = rec
end
local templateActions = {
templateArea,
{
type = "direct",
action_delivery = {
type = "instant",
target_effects = (attributes.attackPointEffects and attributes.attackPointEffects(attributes)) or
{
{
type="create-fire",
entity_name = makeAcidSplashFire(attributes, attributes.stickerName or makeSticker(attributes)),
check_buildability = true,
initial_ground_flame_count = 1
},
{
type = "damage",
damage = templateDirectDamage
},
{
type = "create-entity",
entity_name = "water-splash",
tile_collision_mask = { "ground-tile" }
},
{
type = "play-sound",
sound =
{
{
filename = "__base__/sound/creatures/projectile-acid-burn-1.ogg",
volume = 0.25 + (attributes.effectiveLevel * 0.05)
},
{
filename = "__base__/sound/creatures/projectile-acid-burn-2.ogg",
volume = 0.25 + (attributes.effectiveLevel * 0.05)
},
{
filename = "__base__/sound/creatures/projectile-acid-burn-long-1.ogg",
volume = 0.25 + (attributes.effectiveLevel * 0.05)
},
{
filename = "__base__/sound/creatures/projectile-acid-burn-long-2.ogg",
volume = 0.25 + (attributes.effectiveLevel * 0.05)
}
}
}
}
target_effects = targetEffects
}
}
}
@ -118,13 +128,13 @@ function AttackBall.generateVanilla()
AttackBall.createAttackBall({name="acid-ball", scale=0.5, directionOnly=true, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=16, damagePerTick=0.1, stickerName="acid-sticker-small", radius=1.2, effectiveLevel=1})
AttackBall.createAttackBall({name="acid-ball-1", scale=0.65, directionOnly=true, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=32, damagePerTick=0.2, stickerName="acid-sticker-medium", radius=1.3, effectiveLevel=3})
AttackBall.createAttackBall({name="acid-ball-2-direction", scale=0.85, directionOnly=true, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=60, damagePerTick=0.6, stickerName="acid-sticker-big", radius=1.4, effectiveLevel=5})
AttackBall.createAttackBall({name="acid-ball-3-direction", scale=1.0, directionOnly=true, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=90, damagePerTick=1.2, stickerName="acid-sticker-behemoth", radius=1.5, effectiveLevel=7})
AttackBall.createAttackBall({name="acid-ball-2-direction", scale=0.85, directionOnly=true, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=60, damagePerTick=0.03, stickerName="acid-sticker-big", radius=1.4, effectiveLevel=5})
AttackBall.createAttackBall({name="acid-ball-3-direction", scale=1.0, directionOnly=true, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=90, damagePerTick=0.55, stickerName="acid-sticker-behemoth", radius=1.5, effectiveLevel=7})
AttackBall.createAttackBall({name="acid-ball-2", scale=0.85, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=36, damagePerTick=0.2, stickerName="acid-sticker-small", radius=1.4, effectiveLevel=3})
AttackBall.createAttackBall({name="acid-ball-3", scale=1.0, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=45, damagePerTick=0.6, stickerName="acid-sticker-medium", radius=1.5, effectiveLevel=5})
AttackBall.createAttackBall({name="acid-ball-4", scale=1.2, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=85, damagePerTick=1.2, stickerName="acid-sticker-big", radius=1.75, effectiveLevel=7})
AttackBall.createAttackBall({name="acid-ball-5", scale=1.3, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=135, damagePerTick=1.5, stickerName="acid-sticker-behemoth", radius=2, effectiveLevel=8})
AttackBall.createAttackBall({name="acid-ball-3", scale=1.0, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=45, damagePerTick=0.5, stickerName="acid-sticker-medium", radius=1.5, effectiveLevel=5})
AttackBall.createAttackBall({name="acid-ball-4", scale=1.2, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=85, damagePerTick=0.75, stickerName="acid-sticker-big", radius=1.75, effectiveLevel=7})
AttackBall.createAttackBall({name="acid-ball-5", scale=1.3, attackType="projectile", tint2={r=0, g=1, b=0.3, a=0.5}, damage=135, damagePerTick=1, stickerName="acid-sticker-behemoth", radius=2, effectiveLevel=8})
end
return AttackBall

View File

@ -6,6 +6,7 @@ local wormUtils = require("WormUtils")
-- local FORCE_OLD_PROJECTILES = settings.startup["rampant-forceOldProjectiles"].value
local biterattackanimation = unitUtils.biterattackanimation
local biterrunanimation = unitUtils.biterrunanimation
local spitter_alternative_attacking_animation_sequence = unitUtils.spitter_alternative_attacking_animation_sequence
local spawner_integration = unitSpawnerUtils.spawner_integration
@ -250,7 +251,7 @@ function biterFunctions.makeBiter(attributes)
dying_explosion = attributes.explosion,
dying_trigger_effect = attributes.dyingEffect,
affected_by_tiles = true,
dying_sound = make_biter_dying_sounds(0.3 + (0.05 * attributes.effectiveLevel)),
dying_sound = make_biter_dying_sounds(0.3 + (0.05 * attributes.effectiveLevel)),
working_sound = make_biter_calls(0.2 + (0.05 * attributes.effectiveLevel)),
run_animation = biterrunanimation(attributes.scale, attributes.tint, attributes.tint2 or attributes.tint, attributes.altBiter),
ai_settings = { destroy_when_commands_fail = false, allow_try_return_to_spawner = true, path_resolution_modifier = -5, do_seperation = true }
@ -315,7 +316,7 @@ function biterFunctions.makeUnitSpawner(attributes)
v.type = k
resistances[#resistances+1] = v
end
-- print(name .. " " .. biterAttributes.health)
-- print(attributes.name)
local o = {
type = "unit-spawner",
name = attributes.name .. "-rampant",

View File

@ -2,15 +2,15 @@ local util = require ("util")
local droneUtils = {}
function droneUtils.makeDrone(name, attributes, biterResistances, biterAttack, biterDeath)
local n = name .. "-drone-rampant"
function droneUtils.makeDrone(attributes)
local n = attributes.name .. "-drone-rampant"
local resistances = {}
for k,v in pairs(biterResistances) do
for k,v in pairs(attributes.resistances) do
v.type = k
resistances[#resistances+1] = v
end
attributes.name = name
-- attributes.name = name
local drone = {
type = "combat-robot",
name = n,
@ -24,14 +24,14 @@ function droneUtils.makeDrone(name, attributes, biterResistances, biterAttack, b
alert_when_damaged = false,
collision_box = {{0, 0}, {0, 0}},
selection_box = {{-0.5, -1.5}, {0.5, -0.5}},
distance_per_frame = attributes.distancePerFrame or 0.0,
distance_per_frame = attributes.distancePerFrame or 0,
time_to_live = attributes.ttl or (60 * 45),
follows_player = attributes.followsPlayer or false,
follows_player = attributes.followsPlayer,
friction = attributes.friction or 0.01,
range_from_player = attributes.rangeFromPlayer or 6.0,
speed = attributes.movement or 0.00,
destroy_action = biterDeath,
attack_parameters = biterAttack,
speed = attributes.movement or 0,
destroy_action = attributes.death,
attack_parameters = attributes.attack,
idle =
{
layers =
@ -94,7 +94,6 @@ function droneUtils.makeDrone(name, attributes, biterResistances, biterAttack, b
width = 43,
height = 23,
frame_count = 1,
tint = attributes.tint,
direction_count = 16,
shift = {0.859375, 0.609375},
hr_version = {
@ -104,7 +103,6 @@ function droneUtils.makeDrone(name, attributes, biterResistances, biterAttack, b
width = 88,
height = 50,
frame_count = 1,
tint = attributes.tint,
direction_count = 16,
shift = util.by_pixel(25.5, 19),
scale = 0.5
@ -199,8 +197,8 @@ function droneUtils.makeDrone(name, attributes, biterResistances, biterAttack, b
return drone
end
function droneUtils.createCapsuleProjectile(name, attributes, entityName)
local n = name .. "-capsule-rampant"
function droneUtils.createCapsuleProjectile(attributes, entityName)
local n = attributes.name .. "-capsule-rampant"
local actions = {
{
@ -237,7 +235,7 @@ function droneUtils.createCapsuleProjectile(name, attributes, entityName)
flags = {"not-on-map"},
collision_box = attributes.collisionBox or {{-0.01, -0.01}, {0.01, 0.01}},
collision_mask = attributes.collisionMask,
direction_only = attributes.directionOnly,
direction_only = attributes.attackDirectionOnly,
piercing_damage = attributes.piercingDamage or 0,
acceleration = attributes.acceleration or 0.01,
action = actions,

View File

@ -241,7 +241,7 @@ function fireUtils.makeAcidSplashFire(attributes, stickerName)
type = "fire",
name = name,
flags = {"placeable-off-grid", "not-on-map"},
damage_per_tick = {amount = attributes.damagePerTick or 0, type = attributes.damageType or "acid"},
damage_per_tick = {amount = 0, type = "acid"},
maximum_damage_multiplier = 3,
damage_multiplier_increase_per_added_fuel = 1,
damage_multiplier_decrease_per_tick = 0.005,
@ -288,11 +288,11 @@ function fireUtils.makeAcidSplashFire(attributes, stickerName)
on_damage_tick_effect =
{
type = "direct",
type = "area",
radius = attributes.radius or 2.5,
force = "enemy",
filter_enabled = true,
ignore_collision_condition = true,
-- filter_enabled = true,
action_delivery =
{
type = "instant",

View File

@ -1,3 +1,4 @@
local stickerUtils = {}
-- imported

View File

@ -17,6 +17,352 @@ function unitUtils.spitter_alternative_attacking_animation_sequence()
}
end
local function vanillaAttackBiter(scale, tint1, tint2)
return
{
layers=
{
{
filenames =
{
"__base__/graphics/entity/biter/biter-attack-01.png",
"__base__/graphics/entity/biter/biter-attack-02.png",
"__base__/graphics/entity/biter/biter-attack-03.png",
"__base__/graphics/entity/biter/biter-attack-04.png",
},
slice = 11,
lines_per_file = 4,
line_length = 16,
width = 182,
height = 176,
frame_count = 11,
direction_count = 16,
animation_speed = 0.4,
shift = util.mul_shift(util.by_pixel(-2, -26), scale),
scale = scale,
hr_version =
{
filenames =
{
"__base__/graphics/entity/biter/hr-biter-attack-01.png",
"__base__/graphics/entity/biter/hr-biter-attack-02.png",
"__base__/graphics/entity/biter/hr-biter-attack-03.png",
"__base__/graphics/entity/biter/hr-biter-attack-04.png",
},
slice = 11,
lines_per_file = 4,
line_length = 16,
width = 356,
height = 348,
frame_count = 11,
shift = util.mul_shift(util.by_pixel(0, -25), scale),
direction_count = 16,
animation_speed = 0.4,
scale = 0.5 * scale,
}
},
{
filenames =
{
"__base__/graphics/entity/biter/biter-attack-mask1-01.png",
"__base__/graphics/entity/biter/biter-attack-mask1-02.png",
"__base__/graphics/entity/biter/biter-attack-mask1-03.png",
"__base__/graphics/entity/biter/biter-attack-mask1-04.png",
},
slice = 11,
lines_per_file = 4,
flags = { "mask" },
line_length = 16,
width = 178,
height = 144,
frame_count = 11,
direction_count = 16,
animation_speed = 0.4,
shift = util.mul_shift(util.by_pixel(0, -42), scale),
scale = scale,
tint = tint1,
hr_version =
{
filenames =
{
"__base__/graphics/entity/biter/hr-biter-attack-mask1-01.png",
"__base__/graphics/entity/biter/hr-biter-attack-mask1-02.png",
"__base__/graphics/entity/biter/hr-biter-attack-mask1-03.png",
"__base__/graphics/entity/biter/hr-biter-attack-mask1-04.png",
},
slice = 11,
lines_per_file = 4,
line_length = 16,
width = 360,
height = 282,
frame_count = 11,
shift = util.mul_shift(util.by_pixel(-1, -41), scale),
direction_count = 16,
animation_speed = 0.4,
scale = 0.5 * scale,
tint = tint1,
}
},
{
filenames =
{
"__base__/graphics/entity/biter/biter-attack-mask2-01.png",
"__base__/graphics/entity/biter/biter-attack-mask2-02.png",
"__base__/graphics/entity/biter/biter-attack-mask2-03.png",
"__base__/graphics/entity/biter/biter-attack-mask2-04.png",
},
slice = 11,
lines_per_file = 4,
flags = { "mask" },
line_length = 16,
width = 182,
height = 144,
frame_count = 11,
direction_count = 16,
animation_speed = 0.4,
shift = util.mul_shift(util.by_pixel(-2, -42), scale),
scale = scale,
tint = tint2,
hr_version =
{
filenames =
{
"__base__/graphics/entity/biter/hr-biter-attack-mask2-01.png",
"__base__/graphics/entity/biter/hr-biter-attack-mask2-02.png",
"__base__/graphics/entity/biter/hr-biter-attack-mask2-03.png",
"__base__/graphics/entity/biter/hr-biter-attack-mask2-04.png",
},
slice = 11,
lines_per_file = 4,
line_length = 16,
width = 358,
height = 282,
frame_count = 11,
shift = util.mul_shift(util.by_pixel(-1, -41), scale),
direction_count = 16,
animation_speed = 0.4,
scale = 0.5 * scale,
tint = tint2,
}
},
{
filenames =
{
"__base__/graphics/entity/biter/biter-attack-shadow-01.png",
"__base__/graphics/entity/biter/biter-attack-shadow-02.png",
"__base__/graphics/entity/biter/biter-attack-shadow-03.png",
"__base__/graphics/entity/biter/biter-attack-shadow-04.png",
},
slice = 11,
lines_per_file = 4,
line_length = 16,
width = 240,
height = 128,
frame_count = 11,
shift = util.mul_shift(util.by_pixel(30, 0), scale),
direction_count = 16,
animation_speed = 0.4,
scale = scale,
draw_as_shadow = true,
hr_version =
{
filenames =
{
"__base__/graphics/entity/biter/hr-biter-attack-shadow-01.png",
"__base__/graphics/entity/biter/hr-biter-attack-shadow-02.png",
"__base__/graphics/entity/biter/hr-biter-attack-shadow-03.png",
"__base__/graphics/entity/biter/hr-biter-attack-shadow-04.png",
},
slice = 11,
lines_per_file = 4,
line_length = 16,
width = 476,
height = 258,
frame_count = 11,
shift = util.mul_shift(util.by_pixel(31, -1), scale),
direction_count = 16,
animation_speed = 0.4,
scale = 0.5 * scale,
draw_as_shadow = true,
}
},
}
}
end
local function crabAttackBiter(scale, tint1, tint2)
return
{
layers=
{
{
filenames =
{
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-04.png",
},
slice = 11,
lines_per_file = 4,
line_length = 16,
width = 280,
height = 200,
frame_count = 11,
direction_count = 16,
animation_speed = 0.4,
shift = {0,0},
scale = scale,
-- hr_version =
-- {
-- filenames =
-- {
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-04.png",
-- },
-- slice = 11,
-- lines_per_file = 4,
-- line_length = 16,
-- width = 356,
-- height = 348,
-- frame_count = 11,
-- shift = util.mul_shift(util.by_pixel(0, -25), scale),
-- direction_count = 16,
-- animation_speed = 0.4,
-- scale = 0.5 * scale,
-- }
},
{
filenames =
{
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-mask1-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-mask1-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-mask1-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-mask1-04.png",
},
slice = 11,
lines_per_file = 4,
flags = { "mask" },
line_length = 16,
width = 280,
height = 200,
frame_count = 11,
direction_count = 16,
animation_speed = 0.4,
shift = {0,0},
scale = scale,
tint = tint1,
-- hr_version =
-- {
-- filenames =
-- {
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-mask1-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-mask1-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-mask1-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-mask1-04.png",
-- },
-- slice = 11,
-- lines_per_file = 4,
-- line_length = 16,
-- width = 360,
-- height = 282,
-- frame_count = 11,
-- shift = util.mul_shift(util.by_pixel(-1, -41), scale),
-- direction_count = 16,
-- animation_speed = 0.4,
-- scale = 0.5 * scale,
-- tint = tint1,
-- }
},
{
filenames =
{
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-mask2-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-mask2-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-mask2-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-mask2-04.png",
},
slice = 11,
lines_per_file = 4,
flags = { "mask" },
line_length = 16,
width = 280,
height = 200,
frame_count = 11,
direction_count = 16,
animation_speed = 0.4,
shift = {0,0},
scale = scale,
tint = tint2,
-- hr_version =
-- {
-- filenames =
-- {
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-mask2-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-mask2-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-mask2-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-mask2-04.png",
-- },
-- slice = 11,
-- lines_per_file = 4,
-- line_length = 16,
-- width = 358,
-- height = 282,
-- frame_count = 11,
-- shift = util.mul_shift(util.by_pixel(-1, -41), scale),
-- direction_count = 16,
-- animation_speed = 0.4,
-- scale = 0.5 * scale,
-- tint = tint2,
-- }
},
{
filenames =
{
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-shadow-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-shadow-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-shadow-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-attack-shadow-04.png",
},
slice = 11,
lines_per_file = 4,
line_length = 16,
width = 280,
height = 200,
frame_count = 11,
shift = {0,0},
direction_count = 16,
animation_speed = 0.4,
scale = scale,
draw_as_shadow = true,
-- hr_version =
-- {
-- filenames =
-- {
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-shadow-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-shadow-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-shadow-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-attack-shadow-04.png",
-- },
-- slice = 11,
-- lines_per_file = 4,
-- line_length = 16,
-- width = 476,
-- height = 258,
-- frame_count = 11,
-- shift = util.mul_shift(util.by_pixel(31, -1), scale),
-- direction_count = 16,
-- animation_speed = 0.4,
-- scale = 0.5 * scale,
-- draw_as_shadow = true,
-- }
},
}
}
end
local function crabRunBiter(scale, tint1, tint2)
return
{
@ -25,10 +371,10 @@ local function crabRunBiter(scale, tint1, tint2)
{
filenames =
{
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-04.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-04.png",
},
slice = 8,
lines_per_file = 8,
@ -44,10 +390,10 @@ local function crabRunBiter(scale, tint1, tint2)
-- {
-- filenames =
-- {
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-04.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-04.png",
-- },
-- slice = 8,
-- lines_per_file = 8,
@ -63,10 +409,10 @@ local function crabRunBiter(scale, tint1, tint2)
{
filenames =
{
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-mask1-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-mask1-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-mask1-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-mask1-04.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-mask1-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-mask1-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-mask1-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-mask1-04.png",
},
slice = 8,
lines_per_file = 8,
@ -83,10 +429,10 @@ local function crabRunBiter(scale, tint1, tint2)
-- {
-- filenames =
-- {
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-mask1-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-mask1-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-mask1-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-mask1-04.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-mask1-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-mask1-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-mask1-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-mask1-04.png",
-- },
-- slice = 8,
-- lines_per_file = 8,
@ -103,10 +449,10 @@ local function crabRunBiter(scale, tint1, tint2)
{
filenames =
{
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-mask2-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-mask2-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-mask2-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-mask2-04.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-mask2-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-mask2-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-mask2-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-mask2-04.png",
},
slice = 8,
lines_per_file = 8,
@ -123,10 +469,10 @@ local function crabRunBiter(scale, tint1, tint2)
-- {
-- filenames =
-- {
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-mask2-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-mask2-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-mask2-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-mask2-04.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-mask2-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-mask2-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-mask2-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-mask2-04.png",
-- },
-- slice = 8,
-- lines_per_file = 8,
@ -143,10 +489,10 @@ local function crabRunBiter(scale, tint1, tint2)
{
filenames =
{
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-shadow-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-shadow-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-shadow-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/biter-run-shadow-04.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-shadow-01.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-shadow-02.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-shadow-03.png",
"__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/biter-run-shadow-04.png",
},
slice = 8,
lines_per_file = 8,
@ -162,10 +508,10 @@ local function crabRunBiter(scale, tint1, tint2)
-- {
-- filenames =
-- {
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-shadow-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-shadow-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-shadow-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Run_Anim/hr-biter-run-shadow-04.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-shadow-01.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-shadow-02.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-shadow-03.png",
-- "__Rampant__/graphics/entities/CybranM_Biter_Attack-Run_Anim/hr-biter-run-shadow-04.png",
-- },
-- slice = 8,
-- lines_per_file = 8,
@ -348,6 +694,15 @@ local function vanillaRunBiter(scale, tint1, tint2)
}
end
function unitUtils.biterattackanimation(scale, tint1, tint2, altBiter)
if altBiter then
return crabAttackBiter(scale, tint1, tint2)
else
return vanillaAttackBiter(scale, tint1, tint2)
end
end
function unitUtils.biterrunanimation(scale, tint1, tint2, altBiter)
if altBiter then
return crabRunBiter(scale, tint1, tint2)

View File

@ -30,7 +30,7 @@ function tests.pheromoneLevels(size)
for i=1,#chunk do
str = str .. " " .. tostring(i) .. "/" .. tostring(chunk[i])
end
str = str .. " " .. "p/" .. game.surfaces[global.natives.activeSurface].get_pollution(chunk) .. " " .. "n/" .. chunkPropertyUtils.getNestCount(global.map, chunk) .. " " .. "w/" .. chunkPropertyUtils.getWormCount(global.map, chunk) .. " pg/" .. chunkPropertyUtils.getPlayerBaseGenerator(global.map, chunk)
str = str .. " " .. "p/" .. game.surfaces[global.natives.activeSurface].get_pollution(chunk) .. " " .. "n/" .. chunkPropertyUtils.getNestCount(global.map, chunk) .. " " .. "w/" .. chunkPropertyUtils.getTurretCount(global.map, chunk) .. " pg/" .. chunkPropertyUtils.getPlayerBaseGenerator(global.map, chunk)
if (chunk.x == playerChunkX) and (chunk.y == playerChunkY) then
print("=============")
print(chunk.x, chunk.y, str)
@ -411,7 +411,7 @@ function tests.exportAiState()
chunk.x,
chunk.y,
chunkPropertyUtils.getNestCount(global.map, chunk),
chunkPropertyUtils.getWormCount(global.map, chunk),
chunkPropertyUtils.getTurretCount(global.map, chunk),
chunkPropertyUtils.getRallyTick(global.map, chunk),
chunkPropertyUtils.getRetreatTick(global.map, chunk),
chunkPropertyUtils.getResourceGenerator(global.map, chunk),
@ -421,7 +421,10 @@ function tests.exportAiState()
chunkPropertyUtils.getNestActiveness(global.map, chunk),
chunkPropertyUtils.getRaidNestActiveness(global.map, chunk),
#chunkPropertyUtils.getSquadsOnChunk(global.map, chunk),
alignmentCount}, ",") .. "\n"
alignmentCount,
chunkPropertyUtils.getHiveCount(global.map, chunk),
chunkPropertyUtils.getTrapCount(global.map, chunk),
chunkPropertyUtils.getUtilityCount(global.map, chunk)}, ",") .. "\n"
end
game.write_file("rampantState.txt", s, false)
end