mirror of
https://github.com/veden/Rampant.git
synced 2025-09-16 09:16:43 +02:00
working adjustments and refactoring
This commit is contained in:
@@ -48,7 +48,6 @@ Configure Options not in game menu:
|
|||||||
- Pathfinding - Unit groups will use potential fields to perform only single step pathfinding allowing for efficient and dynamic pathing
|
- Pathfinding - Unit groups will use potential fields to perform only single step pathfinding allowing for efficient and dynamic pathing
|
||||||
- Peace mode - If something sets peace mode, Rampant will respect it
|
- Peace mode - If something sets peace mode, Rampant will respect it
|
||||||
- Ion Cannon Reaction - Firing the Ion Cannon will cause nests around the blast site to form into an attack wave and agitate all biters
|
- Ion Cannon Reaction - Firing the Ion Cannon will cause nests around the blast site to form into an attack wave and agitate all biters
|
||||||
- Item Collector + Technology to unlock it - An entity that collects the items on the ground around itself
|
|
||||||
|
|
||||||
# Planned Features
|
# Planned Features
|
||||||
|
|
||||||
@@ -61,6 +60,14 @@ Configure Options not in game menu:
|
|||||||
|
|
||||||
# Version History
|
# Version History
|
||||||
|
|
||||||
|
0.15.23 -
|
||||||
|
- Fixed: Retreat radius being centered on chunk corner instead of on the unit dying
|
||||||
|
- Fixed: Spitter flamethrower sound fx
|
||||||
|
- Moved: Item Collector into separate mod
|
||||||
|
- Balance: Adjusted spitter and worms damages, ranges, and cooldowns to be more inline with vanilla
|
||||||
|
- Optimization: Reduced memory footprint for faster saving and loading
|
||||||
|
- Framework: Reorganization of files
|
||||||
|
|
||||||
0.15.22 -
|
0.15.22 -
|
||||||
- Contribution - Martok88, Improvement: Added optional attack wave message per player
|
- Contribution - Martok88, Improvement: Added optional attack wave message per player
|
||||||
|
|
||||||
|
24
Upgrade.lua
24
Upgrade.lua
@@ -8,7 +8,6 @@ local mathUtils = require("libs/MathUtils")
|
|||||||
-- constants
|
-- constants
|
||||||
|
|
||||||
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
|
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
|
||||||
local INTERVAL_PROCESS = constants.INTERVAL_PROCESS
|
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
@@ -16,7 +15,7 @@ local roundToNearest = mathUtils.roundToNearest
|
|||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
|
|
||||||
function upgrade.attempt(natives, world)
|
function upgrade.attempt(natives)
|
||||||
local starting = global.version
|
local starting = global.version
|
||||||
if (global.version == nil) then
|
if (global.version == nil) then
|
||||||
natives.squads = {}
|
natives.squads = {}
|
||||||
@@ -157,25 +156,14 @@ function upgrade.attempt(natives, world)
|
|||||||
game.surfaces[1].print("Rampant - Version 0.15.17")
|
game.surfaces[1].print("Rampant - Version 0.15.17")
|
||||||
global.version = constants.VERSION_27
|
global.version = constants.VERSION_27
|
||||||
end
|
end
|
||||||
if (global.version < constants.VERSION_28) then
|
if (global.version < constants.VERSION_33) then
|
||||||
|
|
||||||
if (world == nil) then
|
global.world = nil
|
||||||
global.world = {}
|
|
||||||
world = global.world
|
|
||||||
end
|
|
||||||
|
|
||||||
world.itemCollectorLookup = {}
|
|
||||||
world.itemCollectorEvents = {}
|
|
||||||
|
|
||||||
game.surfaces[1].print("Rampant - Version 0.15.18")
|
game.surfaces[1].print("Rampant - Version 0.15.23")
|
||||||
global.version = constants.VERSION_28
|
global.version = constants.VERSION_33
|
||||||
end
|
end
|
||||||
if (global.version < constants.VERSION_32) then
|
return starting ~= global.version, natives
|
||||||
|
|
||||||
game.surfaces[1].print("Rampant - Version 0.15.22")
|
|
||||||
global.version = constants.VERSION_32
|
|
||||||
end
|
|
||||||
return starting ~= global.version, natives, world
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function upgrade.compareTable(entities, option, new)
|
function upgrade.compareTable(entities, option, new)
|
||||||
|
223
control.lua
223
control.lua
@@ -1,6 +1,5 @@
|
|||||||
-- imports
|
-- imports
|
||||||
|
|
||||||
local entityUtils = require("libs/EntityUtils")
|
|
||||||
local mapUtils = require("libs/MapUtils")
|
local mapUtils = require("libs/MapUtils")
|
||||||
local unitGroupUtils = require("libs/UnitGroupUtils")
|
local unitGroupUtils = require("libs/UnitGroupUtils")
|
||||||
local chunkProcessor = require("libs/ChunkProcessor")
|
local chunkProcessor = require("libs/ChunkProcessor")
|
||||||
@@ -14,14 +13,10 @@ local aiAttackWave = require("libs/AIAttackWave")
|
|||||||
local aiPlanning = require("libs/AIPlanning")
|
local aiPlanning = require("libs/AIPlanning")
|
||||||
local interop = require("libs/Interop")
|
local interop = require("libs/Interop")
|
||||||
local tests = require("tests")
|
local tests = require("tests")
|
||||||
|
local chunkUtils = require("libs/ChunkUtils")
|
||||||
local upgrade = require("Upgrade")
|
local upgrade = require("Upgrade")
|
||||||
local baseRegisterUtils = require("libs/BaseRegisterUtils")
|
|
||||||
local mathUtils = require("libs/MathUtils")
|
local mathUtils = require("libs/MathUtils")
|
||||||
local config = require("config")
|
local config = require("config")
|
||||||
local worldProcessor = require("libs/WorldProcessor")
|
|
||||||
local inventoryUtils = require("libs/InventoryUtils")
|
|
||||||
local playerUtils = require("libs/PlayerUtils")
|
|
||||||
local buildUtils = require("libs/BuildUtils")
|
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
|
|
||||||
@@ -30,12 +25,7 @@ local INTERVAL_PROCESS = constants.INTERVAL_PROCESS
|
|||||||
|
|
||||||
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
||||||
|
|
||||||
local DEFINES_INVENTORY_PLAYER_MAIN = defines.inventory.player_main
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
local DEFINES_INVENTORY_GOD_MAIN = defines.inventory.god_main
|
|
||||||
local DEFINES_INVENTORY_PLAYER_QUICKBAR = defines.inventory.player_quickbar
|
|
||||||
local DEFINES_INVENTORY_GOD_QUICKBAR = defines.inventory.god_quickbar
|
|
||||||
|
|
||||||
local ITEM_COLLECTOR_MAX_QUEUE_SIZE = constants.ITEM_COLLECTOR_MAX_QUEUE_SIZE
|
|
||||||
|
|
||||||
local AI_MAX_OVERFLOW_POINTS = constants.AI_MAX_OVERFLOW_POINTS
|
local AI_MAX_OVERFLOW_POINTS = constants.AI_MAX_OVERFLOW_POINTS
|
||||||
|
|
||||||
@@ -49,17 +39,6 @@ local getChunkByPosition = mapUtils.getChunkByPosition
|
|||||||
|
|
||||||
local processPendingChunks = chunkProcessor.processPendingChunks
|
local processPendingChunks = chunkProcessor.processPendingChunks
|
||||||
|
|
||||||
local buildComplexEntity = buildUtils.buildComplexEntity
|
|
||||||
local mineComplexEntity = buildUtils.mineComplexEntity
|
|
||||||
|
|
||||||
local getPlayerCursorStack = playerUtils.getPlayerCursorStack
|
|
||||||
|
|
||||||
local swapItemStack = inventoryUtils.swapItemStack
|
|
||||||
local swapItemInventory = inventoryUtils.swapItemInventory
|
|
||||||
local topOffHand = inventoryUtils.topOffHand
|
|
||||||
|
|
||||||
local processWorld = worldProcessor.processWorld
|
|
||||||
|
|
||||||
local processMap = mapProcessor.processMap
|
local processMap = mapProcessor.processMap
|
||||||
local processPlayers = mapProcessor.processPlayers
|
local processPlayers = mapProcessor.processPlayers
|
||||||
local scanMap = mapProcessor.scanMap
|
local scanMap = mapProcessor.scanMap
|
||||||
@@ -80,23 +59,22 @@ local squadsBeginAttack = squadAttack.squadsBeginAttack
|
|||||||
|
|
||||||
local retreatUnits = squadDefense.retreatUnits
|
local retreatUnits = squadDefense.retreatUnits
|
||||||
|
|
||||||
local addRemovePlayerEntity = entityUtils.addRemovePlayerEntity
|
local addRemovePlayerEntity = chunkUtils.addRemovePlayerEntity
|
||||||
local unregisterEnemyBaseStructure = baseRegisterUtils.unregisterEnemyBaseStructure
|
local unregisterEnemyBaseStructure = chunkUtils.unregisterEnemyBaseStructure
|
||||||
local registerEnemyBaseStructure = baseRegisterUtils.registerEnemyBaseStructure
|
local registerEnemyBaseStructure = chunkUtils.registerEnemyBaseStructure
|
||||||
local makeImmortalEntity = entityUtils.makeImmortalEntity
|
local makeImmortalEntity = chunkUtils.makeImmortalEntity
|
||||||
|
|
||||||
local processBases = baseProcessor.processBases
|
local processBases = baseProcessor.processBases
|
||||||
|
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
|
|
||||||
local getPlayerInventory = playerUtils.getPlayerInventory
|
local positionToChunkXY = mapUtils.positionToChunkXY
|
||||||
|
|
||||||
-- local references to global
|
-- local references to global
|
||||||
|
|
||||||
local regionMap -- manages the chunks that make up the game world
|
local regionMap -- manages the chunks that make up the game world
|
||||||
local natives -- manages the enemy units, structures, and ai
|
local natives -- manages the enemy units, structures, and ai
|
||||||
local pendingChunks -- chunks that have yet to be processed by the mod
|
local pendingChunks -- chunks that have yet to be processed by the mod
|
||||||
local world -- manages the player built structures and any other events in the world
|
|
||||||
|
|
||||||
-- hook functions
|
-- hook functions
|
||||||
|
|
||||||
@@ -110,13 +88,10 @@ local function onIonCannonFired(event)
|
|||||||
if (natives.points > AI_MAX_OVERFLOW_POINTS) then
|
if (natives.points > AI_MAX_OVERFLOW_POINTS) then
|
||||||
natives.points = AI_MAX_OVERFLOW_POINTS
|
natives.points = AI_MAX_OVERFLOW_POINTS
|
||||||
end
|
end
|
||||||
local chunk = getChunkByPosition(regionMap, event.position.x, event.position.y)
|
local chunkX, chunkY = positionToChunkXY(event.position)
|
||||||
if chunk then
|
local chunk = getChunkByPosition(regionMap, chunkX, chunkY)
|
||||||
rallyUnits(chunk,
|
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
regionMap,
|
rallyUnits(chunk, regionMap, surface, natives, event.tick)
|
||||||
surface,
|
|
||||||
natives,
|
|
||||||
event.tick)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -134,7 +109,6 @@ local function onLoad()
|
|||||||
regionMap = global.regionMap
|
regionMap = global.regionMap
|
||||||
natives = global.natives
|
natives = global.natives
|
||||||
pendingChunks = global.pendingChunks
|
pendingChunks = global.pendingChunks
|
||||||
world = global.world
|
|
||||||
|
|
||||||
hookEvents()
|
hookEvents()
|
||||||
end
|
end
|
||||||
@@ -158,9 +132,28 @@ local function rebuildRegionMap()
|
|||||||
regionMap.processQueue = {}
|
regionMap.processQueue = {}
|
||||||
regionMap.processIndex = 1
|
regionMap.processIndex = 1
|
||||||
regionMap.scanIndex = 1
|
regionMap.scanIndex = 1
|
||||||
|
|
||||||
|
regionMap.chunkToHives = {}
|
||||||
|
regionMap.chunkToNests = {}
|
||||||
|
regionMap.chunkToWorms = {}
|
||||||
|
regionMap.chunkToRetreats = {}
|
||||||
|
regionMap.chunkToRallys = {}
|
||||||
|
regionMap.chunkToPlayerBase = {}
|
||||||
|
regionMap.chunkToResource = {}
|
||||||
|
|
||||||
-- preallocating memory to be used in code, making it fast by reducing garbage generated.
|
-- preallocating memory to be used in code, making it fast by reducing garbage generated.
|
||||||
regionMap.neighbors = { nil, nil, nil, nil, nil, nil, nil, nil }
|
regionMap.neighbors = { SENTINEL_IMPASSABLE_CHUNK,
|
||||||
regionMap.cardinalNeighbors = { nil, nil, nil, nil }
|
SENTINEL_IMPASSABLE_CHUNK,
|
||||||
|
SENTINEL_IMPASSABLE_CHUNK,
|
||||||
|
SENTINEL_IMPASSABLE_CHUNK,
|
||||||
|
SENTINEL_IMPASSABLE_CHUNK,
|
||||||
|
SENTINEL_IMPASSABLE_CHUNK,
|
||||||
|
SENTINEL_IMPASSABLE_CHUNK,
|
||||||
|
SENTINEL_IMPASSABLE_CHUNK }
|
||||||
|
regionMap.cardinalNeighbors = { SENTINEL_IMPASSABLE_CHUNK,
|
||||||
|
SENTINEL_IMPASSABLE_CHUNK,
|
||||||
|
SENTINEL_IMPASSABLE_CHUNK,
|
||||||
|
SENTINEL_IMPASSABLE_CHUNK }
|
||||||
regionMap.chunkTiles = {}
|
regionMap.chunkTiles = {}
|
||||||
regionMap.position = {x=0,
|
regionMap.position = {x=0,
|
||||||
y=0}
|
y=0}
|
||||||
@@ -242,7 +235,7 @@ end
|
|||||||
|
|
||||||
local function onConfigChanged()
|
local function onConfigChanged()
|
||||||
local upgraded
|
local upgraded
|
||||||
upgraded, natives, world = upgrade.attempt(natives, world)
|
upgraded, natives = upgrade.attempt(natives)
|
||||||
if upgraded and onModSettingsChange(nil) then
|
if upgraded and onModSettingsChange(nil) then
|
||||||
rebuildRegionMap()
|
rebuildRegionMap()
|
||||||
end
|
end
|
||||||
@@ -271,8 +264,6 @@ local function onTick(event)
|
|||||||
cleanSquads(natives)
|
cleanSquads(natives)
|
||||||
regroupSquads(natives)
|
regroupSquads(natives)
|
||||||
|
|
||||||
processWorld(surface, world, tick)
|
|
||||||
|
|
||||||
processPlayers(players, regionMap, surface, natives, tick)
|
processPlayers(players, regionMap, surface, natives, tick)
|
||||||
|
|
||||||
if natives.useCustomAI then
|
if natives.useCustomAI then
|
||||||
@@ -288,7 +279,7 @@ local function onTick(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onBuild(event)
|
local function onBuild(event)
|
||||||
local entity = buildComplexEntity(event.created_entity, world)
|
local entity = event.created_entity
|
||||||
addRemovePlayerEntity(regionMap, entity, natives, true, false)
|
addRemovePlayerEntity(regionMap, entity, natives, true, false)
|
||||||
if natives.safeBuildings then
|
if natives.safeBuildings then
|
||||||
if natives.safeEntities[entity.type] or natives.safeEntityName[entity.name] then
|
if natives.safeEntities[entity.type] or natives.safeEntityName[entity.name] then
|
||||||
@@ -298,24 +289,20 @@ local function onBuild(event)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local function onMine(event)
|
local function onMine(event)
|
||||||
mineComplexEntity(addRemovePlayerEntity(regionMap,
|
addRemovePlayerEntity(regionMap, event.entity, natives, false, false)
|
||||||
event.entity,
|
|
||||||
natives,
|
|
||||||
false,
|
|
||||||
false),
|
|
||||||
world)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onDeath(event)
|
local function onDeath(event)
|
||||||
local entity = event.entity
|
local entity = event.entity
|
||||||
local surface = entity.surface
|
local surface = entity.surface
|
||||||
if (surface.index == 1) then
|
if (surface.index == 1) then
|
||||||
|
local entityPosition = entity.position
|
||||||
|
local chunkX, chunkY = positionToChunkXY(entityPosition)
|
||||||
if (entity.force.name == "enemy") then
|
if (entity.force.name == "enemy") then
|
||||||
if (entity.type == "unit") then
|
if (entity.type == "unit") then
|
||||||
local entityPosition = entity.position
|
local deathChunk = getChunkByPosition(regionMap, chunkX, chunkY)
|
||||||
local deathChunk = getChunkByPosition(regionMap, entityPosition.x, entityPosition.y)
|
|
||||||
|
|
||||||
if deathChunk then
|
if (deathChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
-- drop death pheromone where unit died
|
-- drop death pheromone where unit died
|
||||||
deathScent(deathChunk)
|
deathScent(deathChunk)
|
||||||
|
|
||||||
@@ -324,18 +311,14 @@ local function onDeath(event)
|
|||||||
|
|
||||||
retreatUnits(deathChunk,
|
retreatUnits(deathChunk,
|
||||||
entityPosition,
|
entityPosition,
|
||||||
convertUnitGroupToSquad(natives,
|
convertUnitGroupToSquad(natives, entity.unit_group),
|
||||||
entity.unit_group),
|
|
||||||
regionMap,
|
regionMap,
|
||||||
surface,
|
surface,
|
||||||
natives,
|
natives,
|
||||||
tick)
|
tick)
|
||||||
|
|
||||||
if (mRandom() < natives.rallyThreshold) and not surface.peaceful_mode then
|
if (mRandom() < natives.rallyThreshold) and not surface.peaceful_mode then
|
||||||
rallyUnits(deathChunk,
|
rallyUnits(deathChunk, regionMap, surface, natives, tick)
|
||||||
regionMap,
|
|
||||||
surface,
|
|
||||||
natives,
|
|
||||||
tick)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -345,32 +328,24 @@ local function onDeath(event)
|
|||||||
end
|
end
|
||||||
elseif (entity.force.name == "player") then
|
elseif (entity.force.name == "player") then
|
||||||
local creditNatives = false
|
local creditNatives = false
|
||||||
local entityPosition = entity.position
|
|
||||||
if (event.force ~= nil) and (event.force.name == "enemy") then
|
if (event.force ~= nil) and (event.force.name == "enemy") then
|
||||||
creditNatives = true
|
creditNatives = true
|
||||||
local victoryChunk = getChunkByPosition(regionMap, entityPosition.x, entityPosition.y)
|
local victoryChunk = getChunkByPosition(regionMap, chunkX, chunkY)
|
||||||
if victoryChunk then
|
if (victoryChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
victoryScent(victoryChunk, entity.type)
|
victoryScent(victoryChunk, entity.type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if creditNatives and natives.safeBuildings and (natives.safeEntities[entity.type] or natives.safeEntityName[entity.name]) then
|
if creditNatives and natives.safeBuildings and (natives.safeEntities[entity.type] or natives.safeEntityName[entity.name]) then
|
||||||
makeImmortalEntity(surface, entity)
|
makeImmortalEntity(surface, entity)
|
||||||
else
|
else
|
||||||
mineComplexEntity(addRemovePlayerEntity(regionMap,
|
addRemovePlayerEntity(regionMap, entity, natives, false, creditNatives)
|
||||||
entity,
|
|
||||||
natives,
|
|
||||||
false,
|
|
||||||
creditNatives),
|
|
||||||
world,
|
|
||||||
true)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onEnemyBaseBuild(event)
|
local function onEnemyBaseBuild(event)
|
||||||
local entity = event.entity
|
registerEnemyBaseStructure(regionMap, event.entity, nil)
|
||||||
registerEnemyBaseStructure(regionMap, entity, nil)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onSurfaceTileChange(event)
|
local function onSurfaceTileChange(event)
|
||||||
@@ -384,128 +359,30 @@ local function onInit()
|
|||||||
global.regionMap = {}
|
global.regionMap = {}
|
||||||
global.pendingChunks = {}
|
global.pendingChunks = {}
|
||||||
global.natives = {}
|
global.natives = {}
|
||||||
global.world = {}
|
|
||||||
|
|
||||||
regionMap = global.regionMap
|
regionMap = global.regionMap
|
||||||
natives = global.natives
|
natives = global.natives
|
||||||
pendingChunks = global.pendingChunks
|
pendingChunks = global.pendingChunks
|
||||||
world = global.world
|
|
||||||
|
|
||||||
onConfigChanged()
|
onConfigChanged()
|
||||||
hookEvents()
|
hookEvents()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- local function onBuildingRotated(event)
|
|
||||||
|
|
||||||
-- end
|
|
||||||
|
|
||||||
local function onCursorChange(event)
|
|
||||||
if settings.startup["rampant-enableBuildings"].value then
|
|
||||||
local player = game.players[event.player_index]
|
|
||||||
swapItemStack(getPlayerCursorStack(player),
|
|
||||||
"item-collector-base-rampant",
|
|
||||||
"item-collector-base-overlay-rampant")
|
|
||||||
local inventory = getPlayerInventory(player,
|
|
||||||
DEFINES_INVENTORY_PLAYER_QUICKBAR,
|
|
||||||
DEFINES_INVENTORY_GOD_QUICKBAR)
|
|
||||||
topOffHand(inventory,
|
|
||||||
player.cursor_stack,
|
|
||||||
"item-collector-base-rampant",
|
|
||||||
"item-collector-base-overlay-rampant")
|
|
||||||
inventory = getPlayerInventory(player,
|
|
||||||
DEFINES_INVENTORY_PLAYER_MAIN,
|
|
||||||
DEFINES_INVENTORY_GOD_MAIN)
|
|
||||||
topOffHand(inventory,
|
|
||||||
player.cursor_stack,
|
|
||||||
"item-collector-base-rampant",
|
|
||||||
"item-collector-base-overlay-rampant")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function onPlayerDropped(event)
|
|
||||||
if settings.startup["rampant-enableBuildings"].value then
|
|
||||||
local item = event.entity
|
|
||||||
if item.valid then
|
|
||||||
swapItemStack(item.stack,
|
|
||||||
"item-collector-base-overlay-rampant",
|
|
||||||
"item-collector-base-rampant")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function onMainInventoryChanged(event)
|
|
||||||
if settings.startup["rampant-enableBuildings"].value then
|
|
||||||
local player = game.players[event.player_index]
|
|
||||||
local inventory = getPlayerInventory(player,
|
|
||||||
DEFINES_INVENTORY_PLAYER_MAIN,
|
|
||||||
DEFINES_INVENTORY_GOD_MAIN)
|
|
||||||
swapItemInventory(inventory,
|
|
||||||
"item-collector-base-overlay-rampant",
|
|
||||||
"item-collector-base-rampant")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function onQuickInventoryChanged(event)
|
|
||||||
if settings.startup["rampant-enableBuildings"].value then
|
|
||||||
local player = game.players[event.player_index]
|
|
||||||
local inventory = getPlayerInventory(player,
|
|
||||||
DEFINES_INVENTORY_PLAYER_QUICKBAR,
|
|
||||||
DEFINES_INVENTORY_GOD_QUICKBAR)
|
|
||||||
swapItemInventory(inventory,
|
|
||||||
"item-collector-base-overlay-rampant",
|
|
||||||
"item-collector-base-rampant")
|
|
||||||
topOffHand(inventory,
|
|
||||||
player.cursor_stack,
|
|
||||||
"item-collector-base-rampant",
|
|
||||||
"item-collector-base-overlay-rampant")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function onScannedSector(event)
|
|
||||||
local radar = event.radar
|
|
||||||
if (radar.name == "item-collector-base-rampant") then
|
|
||||||
local count = #world.itemCollectorEvents
|
|
||||||
if (count <= ITEM_COLLECTOR_MAX_QUEUE_SIZE) then
|
|
||||||
world.itemCollectorEvents[count+1] = radar.unit_number
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- hooks
|
-- hooks
|
||||||
|
|
||||||
script.on_init(onInit)
|
script.on_init(onInit)
|
||||||
script.on_load(onLoad)
|
script.on_load(onLoad)
|
||||||
script.on_event(defines.events.on_runtime_mod_setting_changed,
|
script.on_event(defines.events.on_runtime_mod_setting_changed, onModSettingsChange)
|
||||||
onModSettingsChange)
|
|
||||||
script.on_configuration_changed(onConfigChanged)
|
script.on_configuration_changed(onConfigChanged)
|
||||||
|
|
||||||
-- script.on_event(defines.events.on_player_rotated_entity,
|
|
||||||
-- onBuildingRotated)
|
|
||||||
|
|
||||||
script.on_event(defines.events.on_player_built_tile, onSurfaceTileChange)
|
script.on_event(defines.events.on_player_built_tile, onSurfaceTileChange)
|
||||||
|
|
||||||
script.on_event(defines.events.on_player_cursor_stack_changed,
|
script.on_event(defines.events.on_biter_base_built, onEnemyBaseBuild)
|
||||||
onCursorChange)
|
|
||||||
|
|
||||||
script.on_event(defines.events.on_player_main_inventory_changed,
|
|
||||||
onMainInventoryChanged)
|
|
||||||
script.on_event(defines.events.on_player_quickbar_inventory_changed,
|
|
||||||
onQuickInventoryChanged)
|
|
||||||
|
|
||||||
script.on_event(defines.events.on_biter_base_built,
|
|
||||||
onEnemyBaseBuild)
|
|
||||||
script.on_event({defines.events.on_player_mined_entity,
|
script.on_event({defines.events.on_player_mined_entity,
|
||||||
defines.events.on_robot_mined_entity},
|
defines.events.on_robot_mined_entity}, onMine)
|
||||||
onMine)
|
|
||||||
script.on_event({defines.events.on_built_entity,
|
script.on_event({defines.events.on_built_entity,
|
||||||
defines.events.on_robot_built_entity},
|
defines.events.on_robot_built_entity}, onBuild)
|
||||||
onBuild)
|
|
||||||
script.on_event(defines.events.on_player_dropped_item,
|
|
||||||
onPlayerDropped)
|
|
||||||
|
|
||||||
script.on_event(defines.events.on_sector_scanned,
|
|
||||||
onScannedSector)
|
|
||||||
script.on_event(defines.events.on_entity_died, onDeath)
|
script.on_event(defines.events.on_entity_died, onDeath)
|
||||||
script.on_event(defines.events.on_tick, onTick)
|
script.on_event(defines.events.on_tick, onTick)
|
||||||
script.on_event(defines.events.on_chunk_generated, onChunkGenerated)
|
script.on_event(defines.events.on_chunk_generated, onChunkGenerated)
|
||||||
|
5
data.lua
5
data.lua
@@ -11,8 +11,3 @@ require("prototypes/enemies/UnitFireSpitters")
|
|||||||
require("prototypes/enemies/UnitTendril")
|
require("prototypes/enemies/UnitTendril")
|
||||||
|
|
||||||
|
|
||||||
if settings.startup["rampant-enableBuildings"].value then
|
|
||||||
require("prototypes/buildings/ItemCollector")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name" : "Rampant",
|
"name" : "Rampant",
|
||||||
"factorio_version" : "0.15",
|
"factorio_version" : "0.15",
|
||||||
"version" : "0.15.22",
|
"version" : "0.15.23",
|
||||||
"title" : "Rampant",
|
"title" : "Rampant",
|
||||||
"author" : "Veden",
|
"author" : "Veden",
|
||||||
"homepage" : "https://forums.factorio.com/viewtopic.php?f=94&t=31445",
|
"homepage" : "https://forums.factorio.com/viewtopic.php?f=94&t=31445",
|
||||||
|
@@ -4,8 +4,9 @@ local aiAttackWave = {}
|
|||||||
|
|
||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
local mapUtils = require("MapUtils")
|
local mapUtils = require("MapUtils")
|
||||||
|
local chunkUtils = require("ChunkUtils")
|
||||||
local unitGroupUtils = require("UnitGroupUtils")
|
local unitGroupUtils = require("UnitGroupUtils")
|
||||||
local neighborUtils = require("NeighborUtils")
|
local movementUtils = require("MovementUtils")
|
||||||
package.path = "../?.lua;" .. package.path
|
package.path = "../?.lua;" .. package.path
|
||||||
local config = require("config")
|
local config = require("config")
|
||||||
|
|
||||||
@@ -18,19 +19,21 @@ local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
|||||||
local AI_SQUAD_COST = constants.AI_SQUAD_COST
|
local AI_SQUAD_COST = constants.AI_SQUAD_COST
|
||||||
local AI_VENGENCE_SQUAD_COST = constants.AI_VENGENCE_SQUAD_COST
|
local AI_VENGENCE_SQUAD_COST = constants.AI_VENGENCE_SQUAD_COST
|
||||||
|
|
||||||
local RALLY_TRIGGERED = constants.RALLY_TRIGGERED
|
|
||||||
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
|
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
|
||||||
|
|
||||||
local TRIPLE_CHUNK_SIZE = constants.TRIPLE_CHUNK_SIZE
|
local TRIPLE_CHUNK_SIZE = constants.TRIPLE_CHUNK_SIZE
|
||||||
local PASSABLE = constants.PASSABLE
|
|
||||||
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
|
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
|
||||||
|
|
||||||
|
local CHUNK_SIZE = constants.CHUNK_SIZE
|
||||||
|
|
||||||
local RALLY_CRY_DISTANCE = constants.RALLY_CRY_DISTANCE
|
local RALLY_CRY_DISTANCE = constants.RALLY_CRY_DISTANCE
|
||||||
|
|
||||||
local DEFINES_COMMAND_GROUP = defines.command.group
|
local DEFINES_COMMAND_GROUP = defines.command.group
|
||||||
local DEFINES_DISTRACTION_NONE = defines.distraction.none
|
local DEFINES_DISTRACTION_NONE = defines.distraction.none
|
||||||
|
|
||||||
local NEST_COUNT = constants.NEST_COUNT
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
|
||||||
|
local PASSABLE = constants.PASSABLE
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
@@ -38,9 +41,13 @@ local mRandom = math.random
|
|||||||
|
|
||||||
local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
|
local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
|
||||||
|
|
||||||
|
local getNestCount = chunkUtils.getNestCount
|
||||||
|
local getRallyTick = chunkUtils.getRallyTick
|
||||||
|
local setRallyTick = chunkUtils.setRallyTick
|
||||||
|
|
||||||
local getNeighborChunks = mapUtils.getNeighborChunks
|
local getNeighborChunks = mapUtils.getNeighborChunks
|
||||||
local getChunkByIndex = mapUtils.getChunkByIndex
|
local getChunkByPosition = mapUtils.getChunkByPosition
|
||||||
local scoreNeighborsForFormation = neighborUtils.scoreNeighborsForFormation
|
local scoreNeighborsForFormation = movementUtils.scoreNeighborsForFormation
|
||||||
local createSquad = unitGroupUtils.createSquad
|
local createSquad = unitGroupUtils.createSquad
|
||||||
local attackWaveScaling = config.attackWaveScaling
|
local attackWaveScaling = config.attackWaveScaling
|
||||||
|
|
||||||
@@ -74,21 +81,21 @@ local function scoreUnitGroupLocation(neighborChunk)
|
|||||||
return neighborChunk[PLAYER_PHEROMONE] + neighborChunk[MOVEMENT_PHEROMONE] + neighborChunk[BASE_PHEROMONE]
|
return neighborChunk[PLAYER_PHEROMONE] + neighborChunk[MOVEMENT_PHEROMONE] + neighborChunk[BASE_PHEROMONE]
|
||||||
end
|
end
|
||||||
|
|
||||||
local function validUnitGroupLocation(neighborChunk)
|
local function validUnitGroupLocation(regionMap, neighborChunk)
|
||||||
return (neighborChunk[PASSABLE] == CHUNK_ALL_DIRECTIONS) and (neighborChunk[NEST_COUNT] == 0)
|
return neighborChunk[PASSABLE] == CHUNK_ALL_DIRECTIONS and (getNestCount(regionMap, neighborChunk) == 0)
|
||||||
end
|
end
|
||||||
|
|
||||||
function aiAttackWave.rallyUnits(chunk, regionMap, surface, natives, tick)
|
function aiAttackWave.rallyUnits(chunk, regionMap, surface, natives, tick)
|
||||||
if ((tick - chunk[RALLY_TRIGGERED] > INTERVAL_LOGIC) and (natives.points >= AI_VENGENCE_SQUAD_COST) and
|
if ((tick - getRallyTick(regionMap, chunk) > INTERVAL_LOGIC) and (natives.points >= AI_VENGENCE_SQUAD_COST) and
|
||||||
(#natives.squads < natives.maxSquads)) then
|
(#natives.squads < natives.maxSquads)) then
|
||||||
chunk[RALLY_TRIGGERED] = tick
|
setRallyTick(regionMap, chunk, tick)
|
||||||
local cX = chunk.cX
|
local cX = chunk.x
|
||||||
local cY = chunk.cY
|
local cY = chunk.y
|
||||||
for x=cX - RALLY_CRY_DISTANCE, cX + RALLY_CRY_DISTANCE do
|
for x=cX - RALLY_CRY_DISTANCE, cX + RALLY_CRY_DISTANCE, 32 do
|
||||||
for y=cY - RALLY_CRY_DISTANCE, cY + RALLY_CRY_DISTANCE do
|
for y=cY - RALLY_CRY_DISTANCE, cY + RALLY_CRY_DISTANCE, 32 do
|
||||||
if (x ~= cX) and (y ~= cY) then
|
if (x ~= cX) and (y ~= cY) then
|
||||||
local rallyChunk = getChunkByIndex(regionMap, x, y)
|
local rallyChunk = getChunkByPosition(regionMap, x, y)
|
||||||
if rallyChunk and (rallyChunk[NEST_COUNT] ~= 0) then
|
if (rallyChunk ~= SENTINEL_IMPASSABLE_CHUNK) and (getNestCount(regionMap, rallyChunk) > 0) then
|
||||||
aiAttackWave.formSquads(regionMap, surface, natives, rallyChunk, AI_VENGENCE_SQUAD_COST)
|
aiAttackWave.formSquads(regionMap, surface, natives, rallyChunk, AI_VENGENCE_SQUAD_COST)
|
||||||
if (natives.points < AI_VENGENCE_SQUAD_COST) and (#natives.squads < natives.maxSquads) then
|
if (natives.points < AI_VENGENCE_SQUAD_COST) and (#natives.squads < natives.maxSquads) then
|
||||||
return
|
return
|
||||||
@@ -105,16 +112,17 @@ function aiAttackWave.formSquads(regionMap, surface, natives, chunk, cost)
|
|||||||
|
|
||||||
if valid and (mRandom() < natives.formSquadThreshold) then
|
if valid and (mRandom() < natives.formSquadThreshold) then
|
||||||
|
|
||||||
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(regionMap, chunk.cX, chunk.cY),
|
local squadPath, squadDirection = scoreNeighborsForFormation(getNeighborChunks(regionMap, chunk.x, chunk.y),
|
||||||
validUnitGroupLocation,
|
validUnitGroupLocation,
|
||||||
scoreUnitGroupLocation)
|
scoreUnitGroupLocation,
|
||||||
if squadPath then
|
regionMap)
|
||||||
local squadPosition = surface.find_non_colliding_position("biter-spawner-hive",
|
if (squadPath ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
local squadPosition = surface.find_non_colliding_position("biter-spawner-hive-rampant",
|
||||||
positionFromDirectionAndChunk(squadDirection,
|
positionFromDirectionAndChunk(squadDirection,
|
||||||
chunk,
|
chunk,
|
||||||
regionMap.position,
|
regionMap.position,
|
||||||
0.98),
|
0.98),
|
||||||
32,
|
CHUNK_SIZE,
|
||||||
4)
|
4)
|
||||||
if squadPosition then
|
if squadPosition then
|
||||||
local squad = createSquad(squadPosition, surface, natives)
|
local squad = createSquad(squadPosition, surface, natives)
|
||||||
|
@@ -3,21 +3,28 @@ local aiPredicates = {}
|
|||||||
-- imports
|
-- imports
|
||||||
|
|
||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
local nocturnalUtils = require("NocturnalUtils")
|
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
|
|
||||||
local AI_STATE_AGGRESSIVE = constants.AI_STATE_AGGRESSIVE
|
local AI_STATE_AGGRESSIVE = constants.AI_STATE_AGGRESSIVE
|
||||||
|
local AI_STATE_NOCTURNAL = constants.AI_STATE_NOCTURNAL
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
local canAttackNocturnal = nocturnalUtils.canAttack
|
|
||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
|
|
||||||
function aiPredicates.canAttack(natives, surface)
|
function aiPredicates.canAttack(natives, surface)
|
||||||
return (((natives.state == AI_STATE_AGGRESSIVE) or canAttackNocturnal(natives, surface))
|
return (((natives.state == AI_STATE_AGGRESSIVE) or aiPredicates.canAttackDark(natives, surface))
|
||||||
and not surface.peaceful_mode and (#natives.squads < natives.maxSquads))
|
and not surface.peaceful_mode and (#natives.squads < natives.maxSquads))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function aiPredicates.isDark(surface)
|
||||||
|
return surface.darkness > 0.65
|
||||||
|
end
|
||||||
|
|
||||||
|
function aiPredicates.canAttackDark(natives, surface)
|
||||||
|
return aiPredicates.isDark(surface) and natives.state == AI_STATE_NOCTURNAL
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
return aiPredicates
|
return aiPredicates
|
||||||
|
@@ -1,118 +0,0 @@
|
|||||||
local baseRegisterUtils = {}
|
|
||||||
|
|
||||||
-- imports
|
|
||||||
|
|
||||||
local constants = require("Constants")
|
|
||||||
|
|
||||||
local entityUtils = require("EntityUtils")
|
|
||||||
|
|
||||||
-- constants
|
|
||||||
|
|
||||||
local NEST_COUNT = constants.NEST_COUNT
|
|
||||||
local WORM_COUNT = constants.WORM_COUNT
|
|
||||||
|
|
||||||
local NEST_BASE = constants.NEST_BASE
|
|
||||||
local WORM_BASE = constants.WORM_BASE
|
|
||||||
|
|
||||||
-- imported functions
|
|
||||||
|
|
||||||
local getEntityOverlapChunks = entityUtils.getEntityOverlapChunks
|
|
||||||
|
|
||||||
-- module code
|
|
||||||
|
|
||||||
function baseRegisterUtils.addEnemyStructureToChunk(chunk, entity, base)
|
|
||||||
local indexChunk
|
|
||||||
local indexBase
|
|
||||||
local countChunk
|
|
||||||
if (entity.type == "unit-spawner") then
|
|
||||||
indexChunk = chunk[NEST_BASE]
|
|
||||||
if base then
|
|
||||||
if base.hives[entity.unit_number] then
|
|
||||||
indexBase = base.hives
|
|
||||||
else
|
|
||||||
indexBase = base.nests
|
|
||||||
end
|
|
||||||
end
|
|
||||||
countChunk = NEST_COUNT
|
|
||||||
elseif (entity.type == "turret") then
|
|
||||||
indexChunk = chunk[WORM_BASE]
|
|
||||||
if base then
|
|
||||||
indexBase = base.worms
|
|
||||||
end
|
|
||||||
countChunk = WORM_COUNT
|
|
||||||
end
|
|
||||||
chunk[countChunk] = chunk[countChunk] + 1
|
|
||||||
if indexBase then
|
|
||||||
indexChunk[entity.unit_number] = base
|
|
||||||
indexBase[entity.unit_number] = entity
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function baseRegisterUtils.removeEnemyStructureFromChunk(chunk, entity)
|
|
||||||
local indexChunk
|
|
||||||
local countChunk
|
|
||||||
if (entity.type == "unit-spawner") then
|
|
||||||
indexChunk = chunk[NEST_BASE]
|
|
||||||
countChunk = NEST_COUNT
|
|
||||||
elseif (entity.type == "turret") then
|
|
||||||
indexChunk = chunk[WORM_BASE]
|
|
||||||
countChunk = WORM_COUNT
|
|
||||||
end
|
|
||||||
local base = indexChunk[entity.unit_number]
|
|
||||||
local indexBase
|
|
||||||
if base then
|
|
||||||
if (entity.type == "unit-spawner") then
|
|
||||||
if base.hives[entity.unit_number] then
|
|
||||||
indexBase = base.hives
|
|
||||||
else
|
|
||||||
indexBase = base.nests
|
|
||||||
end
|
|
||||||
elseif (entity.type == "turret") then
|
|
||||||
indexBase = base.worms
|
|
||||||
end
|
|
||||||
indexBase[entity.unit_number] = nil
|
|
||||||
end
|
|
||||||
chunk[countChunk] = chunk[countChunk] - 1
|
|
||||||
end
|
|
||||||
|
|
||||||
function baseRegisterUtils.registerEnemyBaseStructure(regionMap, entity, base)
|
|
||||||
local entityType = entity.type
|
|
||||||
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
|
|
||||||
local leftTop, rightTop, leftBottom, rightBottom = getEntityOverlapChunks(regionMap, entity)
|
|
||||||
|
|
||||||
if leftTop then
|
|
||||||
baseRegisterUtils.addEnemyStructureToChunk(leftTop, entity, base)
|
|
||||||
end
|
|
||||||
if rightTop then
|
|
||||||
baseRegisterUtils.addEnemyStructureToChunk(rightTop, entity, base)
|
|
||||||
end
|
|
||||||
if leftBottom then
|
|
||||||
baseRegisterUtils.addEnemyStructureToChunk(leftBottom, entity, base)
|
|
||||||
end
|
|
||||||
if rightBottom then
|
|
||||||
baseRegisterUtils.addEnemyStructureToChunk(rightBottom, entity, base)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function baseRegisterUtils.unregisterEnemyBaseStructure(regionMap, entity)
|
|
||||||
local entityType = entity.type
|
|
||||||
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
|
|
||||||
local leftTop, rightTop, leftBottom, rightBottom = getEntityOverlapChunks(regionMap, entity)
|
|
||||||
|
|
||||||
if leftTop then
|
|
||||||
baseRegisterUtils.removeEnemyStructureFromChunk(leftTop, entity)
|
|
||||||
end
|
|
||||||
if rightTop then
|
|
||||||
baseRegisterUtils.removeEnemyStructureFromChunk(rightTop, entity)
|
|
||||||
end
|
|
||||||
if leftBottom then
|
|
||||||
baseRegisterUtils.removeEnemyStructureFromChunk(leftBottom, entity)
|
|
||||||
end
|
|
||||||
if rightBottom then
|
|
||||||
baseRegisterUtils.removeEnemyStructureFromChunk(rightBottom, entity)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return baseRegisterUtils
|
|
@@ -5,7 +5,7 @@ local baseUtils = {}
|
|||||||
local mathUtils = require("MathUtils")
|
local mathUtils = require("MathUtils")
|
||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
|
|
||||||
local tendrilUtils = require("TendrilUtils")
|
-- local tendrilUtils = require("TendrilUtils")
|
||||||
|
|
||||||
local nestUtils = require("NestUtils")
|
local nestUtils = require("NestUtils")
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ local buildHive = nestUtils.buildHive
|
|||||||
|
|
||||||
local mFloor = math.floor
|
local mFloor = math.floor
|
||||||
|
|
||||||
local buildTendril = tendrilUtils.buildTendril
|
-- local buildTendril = tendrilUtils.buildTendril
|
||||||
|
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ function baseUtils.createBase(regionMap, natives, position, surface, tick)
|
|||||||
if not buildHive(regionMap, base, surface) then
|
if not buildHive(regionMap, base, surface) then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
buildTendril(regionMap, natives, base, surface, tick)
|
-- buildTendril(regionMap, natives, base, surface, tick)
|
||||||
bases[#bases+1] = base
|
bases[#bases+1] = base
|
||||||
return base
|
return base
|
||||||
end
|
end
|
||||||
|
@@ -1,78 +0,0 @@
|
|||||||
local buildUtils = {}
|
|
||||||
|
|
||||||
-- module code
|
|
||||||
|
|
||||||
function buildUtils.buildComplexEntity(entity, world)
|
|
||||||
if (entity.name == "item-collector-base-overlay-rampant") or (entity.name == "item-collector-base-rampant") then
|
|
||||||
local surface = entity.surface
|
|
||||||
local x = entity.position.x
|
|
||||||
local y = entity.position.y
|
|
||||||
local chest
|
|
||||||
local position = entity.position
|
|
||||||
local force = entity.force
|
|
||||||
if (entity.name == "item-collector-base-overlay-rampant") then
|
|
||||||
entity.destroy()
|
|
||||||
chest = surface.create_entity({name = "item-collector-chest-rampant",
|
|
||||||
position = position,
|
|
||||||
force = force})
|
|
||||||
entity = surface.create_entity({name="item-collector-base-rampant",
|
|
||||||
position = position,
|
|
||||||
force = force})
|
|
||||||
else
|
|
||||||
local ghosts = surface.find_entities_filtered({name="entity-ghost",
|
|
||||||
area={{x=x-1,
|
|
||||||
y=y-1},
|
|
||||||
{x=x+1,
|
|
||||||
y=y+1}},
|
|
||||||
limit=1})
|
|
||||||
if (#ghosts > 0) then
|
|
||||||
local ghost = ghosts[1]
|
|
||||||
if (ghost.ghost_name == "item-collector-chest-rampant") then
|
|
||||||
local conflicts
|
|
||||||
conflicts, chest = ghost.revive()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
chest = surface.create_entity({name = "item-collector-chest-rampant",
|
|
||||||
position = position,
|
|
||||||
force = force})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chest and chest.valid then
|
|
||||||
local pair = { chest, entity }
|
|
||||||
world.itemCollectorLookup[chest.unit_number] = pair
|
|
||||||
world.itemCollectorLookup[entity.unit_number] = pair
|
|
||||||
entity.backer_name = ""
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return entity
|
|
||||||
end
|
|
||||||
|
|
||||||
function buildUtils.mineComplexEntity(entity, world, destroyed)
|
|
||||||
if (entity.name == "item-collector-chest-rampant") or (entity.name == "item-collector-base-rampant") then
|
|
||||||
local pair = world.itemCollectorLookup[entity.unit_number]
|
|
||||||
if pair then
|
|
||||||
local chest = pair[1]
|
|
||||||
local dish = pair[2]
|
|
||||||
|
|
||||||
if chest and chest.valid then
|
|
||||||
world.itemCollectorLookup[chest.unit_number] = nil
|
|
||||||
if destroyed and (entity == chest) then
|
|
||||||
chest.die()
|
|
||||||
elseif (entity ~= chest) then
|
|
||||||
chest.destroy()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if dish and dish.valid then
|
|
||||||
world.itemCollectorLookup[dish.unit_number] = nil
|
|
||||||
if destroyed and (entity ~= dish) then
|
|
||||||
dish.die()
|
|
||||||
elseif (entity ~= dish) then
|
|
||||||
dish.destroy()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return entity
|
|
||||||
end
|
|
||||||
|
|
||||||
return buildUtils
|
|
@@ -9,6 +9,8 @@ local constants = require("Constants")
|
|||||||
|
|
||||||
local CHUNK_SIZE = constants.CHUNK_SIZE
|
local CHUNK_SIZE = constants.CHUNK_SIZE
|
||||||
|
|
||||||
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
local remakeChunk = chunkUtils.remakeChunk
|
local remakeChunk = chunkUtils.remakeChunk
|
||||||
@@ -39,26 +41,31 @@ function chunkProcessor.processPendingChunks(natives, regionMap, surface, pendin
|
|||||||
local x = topLeft.x
|
local x = topLeft.x
|
||||||
local y = topLeft.y
|
local y = topLeft.y
|
||||||
local chunk = createChunk(x, y)
|
local chunk = createChunk(x, y)
|
||||||
|
|
||||||
areaBoundingBox[1] = chunk
|
|
||||||
offset[1] = x + CHUNK_SIZE
|
|
||||||
offset[2] = y + CHUNK_SIZE
|
|
||||||
|
|
||||||
local chunkX = chunk.cX
|
chunk = checkChunkPassability(chunkTiles, chunk, surface)
|
||||||
|
|
||||||
if regionMap[chunkX] == nil then
|
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
regionMap[chunkX] = {}
|
|
||||||
end
|
areaBoundingBox[1] = chunk
|
||||||
regionMap[chunkX][chunk.cY] = chunk
|
offset[1] = x + CHUNK_SIZE
|
||||||
|
offset[2] = y + CHUNK_SIZE
|
||||||
checkChunkPassability(chunkTiles, chunk, surface)
|
|
||||||
if vanillaAI then
|
if vanillaAI then
|
||||||
registerChunkEnemies(chunk, surface, query)
|
registerChunkEnemies(regionMap, chunk, surface, query)
|
||||||
else
|
else
|
||||||
remakeChunk(regionMap, chunk, surface, natives, tick, query)
|
remakeChunk(regionMap, chunk, surface, natives, tick, query)
|
||||||
|
end
|
||||||
|
scoreChunk(regionMap, chunk, surface, natives, query)
|
||||||
|
|
||||||
|
local chunkX = chunk.x
|
||||||
|
|
||||||
|
if regionMap[chunkX] == nil then
|
||||||
|
regionMap[chunkX] = {}
|
||||||
|
end
|
||||||
|
regionMap[chunkX][chunk.y] = chunk
|
||||||
|
|
||||||
|
processQueue[#processQueue+1] = chunk
|
||||||
end
|
end
|
||||||
scoreChunk(chunk, surface, natives, query)
|
|
||||||
processQueue[#processQueue+1] = chunk
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@@ -3,31 +3,25 @@ local chunkUtils = {}
|
|||||||
-- imports
|
-- imports
|
||||||
|
|
||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
|
local mapUtils = require("MapUtils")
|
||||||
local baseUtils = require("BaseUtils")
|
|
||||||
|
|
||||||
local baseRegisterUtils = require("BaseRegisterUtils")
|
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
|
|
||||||
|
local DEFINES_DIRECTION_EAST = defines.direction.east
|
||||||
|
local DEFINES_WIRE_TYPE_RED = defines.wire_type.red
|
||||||
|
local DEFINES_WIRE_TYPE_GREEN = defines.wire_type.green
|
||||||
|
|
||||||
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
|
||||||
local BASE_PHEROMONE = constants.BASE_PHEROMONE
|
local BASE_PHEROMONE = constants.BASE_PHEROMONE
|
||||||
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
|
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
|
||||||
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
||||||
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE
|
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE
|
||||||
local BUILDING_PHEROMONES = constants.BUILDING_PHEROMONES
|
local BUILDING_PHEROMONES = constants.BUILDING_PHEROMONES
|
||||||
local NEST_BASE = constants.NEST_BASE
|
|
||||||
local WORM_BASE = constants.WORM_BASE
|
|
||||||
local NEST_COUNT = constants.NEST_COUNT
|
|
||||||
local WORM_COUNT = constants.WORM_COUNT
|
|
||||||
|
|
||||||
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
|
|
||||||
local RESOURCE_GENERATOR = constants.RESOURCE_GENERATOR
|
|
||||||
|
|
||||||
local CHUNK_NORTH_SOUTH = constants.CHUNK_NORTH_SOUTH
|
local CHUNK_NORTH_SOUTH = constants.CHUNK_NORTH_SOUTH
|
||||||
local CHUNK_EAST_WEST = constants.CHUNK_EAST_WEST
|
local CHUNK_EAST_WEST = constants.CHUNK_EAST_WEST
|
||||||
|
|
||||||
local PASSABLE = constants.PASSABLE
|
|
||||||
|
|
||||||
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
|
local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
|
||||||
local CHUNK_IMPASSABLE = constants.CHUNK_IMPASSABLE
|
local CHUNK_IMPASSABLE = constants.CHUNK_IMPASSABLE
|
||||||
|
|
||||||
@@ -35,14 +29,13 @@ local CHUNK_TICK = constants.CHUNK_TICK
|
|||||||
|
|
||||||
local PATH_RATING = constants.PATH_RATING
|
local PATH_RATING = constants.PATH_RATING
|
||||||
|
|
||||||
local RETREAT_TRIGGERED = constants.RETREAT_TRIGGERED
|
local PASSABLE = constants.PASSABLE
|
||||||
local RALLY_TRIGGERED = constants.RALLY_TRIGGERED
|
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
local findNearbyBase = baseUtils.findNearbyBase
|
local getChunkByPosition = mapUtils.getChunkByPosition
|
||||||
local createBase = baseUtils.createBase
|
|
||||||
local addEnemyStructureToChunk = baseRegisterUtils.addEnemyStructureToChunk
|
local mFloor = math.floor
|
||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
|
|
||||||
@@ -109,6 +102,126 @@ local function spotCheck(x, y, get_tile)
|
|||||||
return valid
|
return valid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function addEnemyStructureToChunk(regionMap, chunk, entity, base)
|
||||||
|
local lookup
|
||||||
|
if (entity.type == "unit-spawner") then
|
||||||
|
lookup = regionMap.chunkToNests
|
||||||
|
elseif (entity.type == "turret") then
|
||||||
|
lookup = regionMap.chunkToWorms
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local entityCollection = lookup[chunk]
|
||||||
|
if not entityCollection then
|
||||||
|
entityCollection = {}
|
||||||
|
lookup[chunk] = entityCollection
|
||||||
|
end
|
||||||
|
entityCollection[#entityCollection+1] = entity
|
||||||
|
|
||||||
|
-- if base then
|
||||||
|
-- local baseCollection = regionMap.chunkToBases[chunk]
|
||||||
|
-- if not baseCollection then
|
||||||
|
-- baseCollection = {}
|
||||||
|
-- regionMap.chunkToBases[chunk] = baseCollection
|
||||||
|
-- end
|
||||||
|
-- baseCollection[base.id] = chunk
|
||||||
|
-- end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function removeEnemyStructureFromChunk(regionMap, chunk, entity)
|
||||||
|
local lookup
|
||||||
|
if (entity.type == "unit-spawner") then
|
||||||
|
lookup = regionMap.chunkToNests
|
||||||
|
elseif (entity.type == "turret") then
|
||||||
|
lookup = regionMap.chunkToWorms
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- local base = indexChunk[entity.unit_number]
|
||||||
|
-- local indexBase
|
||||||
|
-- if base then
|
||||||
|
-- if (entity.type == "unit-spawner") then
|
||||||
|
-- if base.hives[entity.unit_number] then
|
||||||
|
-- indexBase = base.hives
|
||||||
|
-- else
|
||||||
|
-- indexBase = base.nests
|
||||||
|
-- end
|
||||||
|
-- elseif (entity.type == "turret") then
|
||||||
|
-- indexBase = base.worms
|
||||||
|
-- end
|
||||||
|
-- indexBase[entity.unit_number] = nil
|
||||||
|
-- end
|
||||||
|
local collection = lookup[chunk]
|
||||||
|
if collection then
|
||||||
|
for i=1,#collection do
|
||||||
|
local e = collection[i]
|
||||||
|
if e.valid and (e == entity) then
|
||||||
|
table.remove(collection, i)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getEntityOverlapChunks(regionMap, entity)
|
||||||
|
local boundingBox = entity.prototype.selection_box or entity.prototype.collision_box;
|
||||||
|
|
||||||
|
local leftTopChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
local rightTopChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
local leftBottomChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
local rightBottomChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
|
||||||
|
if (boundingBox ~= nil) then
|
||||||
|
local center = entity.position
|
||||||
|
local topXOffset
|
||||||
|
local topYOffset
|
||||||
|
|
||||||
|
local bottomXOffset
|
||||||
|
local bottomYOffset
|
||||||
|
|
||||||
|
if (entity.direction == DEFINES_DIRECTION_EAST) then
|
||||||
|
topXOffset = boundingBox.left_top.y
|
||||||
|
topYOffset = boundingBox.left_top.x
|
||||||
|
bottomXOffset = boundingBox.right_bottom.y
|
||||||
|
bottomYOffset = boundingBox.right_bottom.x
|
||||||
|
else
|
||||||
|
topXOffset = boundingBox.left_top.x
|
||||||
|
topYOffset = boundingBox.left_top.y
|
||||||
|
bottomXOffset = boundingBox.right_bottom.x
|
||||||
|
bottomYOffset = boundingBox.right_bottom.y
|
||||||
|
end
|
||||||
|
|
||||||
|
local leftTopChunkX = mFloor(center.x + topXOffset)
|
||||||
|
local leftTopChunkY = mFloor(center.y + topYOffset)
|
||||||
|
|
||||||
|
-- used to force things on chunk boundary to not spill over 0.0001
|
||||||
|
local rightTopChunkX = mFloor(center.x + bottomXOffset - 0.0001)
|
||||||
|
local rightTopChunkY = leftTopChunkY
|
||||||
|
|
||||||
|
-- used to force things on chunk boundary to not spill over 0.0001
|
||||||
|
local leftBottomChunkX = leftTopChunkX
|
||||||
|
local leftBottomChunkY = mFloor(center.y + bottomYOffset - 0.0001)
|
||||||
|
|
||||||
|
local rightBottomChunkX = rightTopChunkX
|
||||||
|
local rightBottomChunkY = leftBottomChunkY
|
||||||
|
|
||||||
|
leftTopChunk = getChunkByPosition(regionMap, leftTopChunkX, leftTopChunkY)
|
||||||
|
if (leftTopChunkX ~= rightTopChunkX) then
|
||||||
|
rightTopChunk = getChunkByPosition(regionMap, rightTopChunkX, rightTopChunkY)
|
||||||
|
end
|
||||||
|
if (leftTopChunkY ~= leftBottomChunkY) then
|
||||||
|
leftBottomChunk = getChunkByPosition(regionMap, leftBottomChunkX, leftBottomChunkY)
|
||||||
|
end
|
||||||
|
if (leftTopChunkX ~= rightBottomChunkX) and (leftTopChunkY ~= rightBottomChunkY) then
|
||||||
|
rightBottomChunk = getChunkByPosition(regionMap, rightBottomChunkX, rightBottomChunkY)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return leftTopChunk, rightTopChunk, leftBottomChunk, rightBottomChunk
|
||||||
|
end
|
||||||
|
|
||||||
|
-- external functions
|
||||||
|
|
||||||
function chunkUtils.checkChunkPassability(chunkTiles, chunk, surface)
|
function chunkUtils.checkChunkPassability(chunkTiles, chunk, surface)
|
||||||
local x = chunk.x
|
local x = chunk.x
|
||||||
local y = chunk.y
|
local y = chunk.y
|
||||||
@@ -139,12 +252,17 @@ function chunkUtils.checkChunkPassability(chunkTiles, chunk, surface)
|
|||||||
pass = CHUNK_NORTH_SOUTH
|
pass = CHUNK_NORTH_SOUTH
|
||||||
else
|
else
|
||||||
pass = CHUNK_IMPASSABLE
|
pass = CHUNK_IMPASSABLE
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
chunk[PATH_RATING] = 1
|
chunk[PATH_RATING] = 1
|
||||||
end
|
end
|
||||||
chunk[PASSABLE] = pass
|
if (pass == CHUNK_IMPASSABLE) then
|
||||||
|
return SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
else
|
||||||
|
chunk[PASSABLE] = pass
|
||||||
|
return chunk
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function chunkUtils.remakeChunk(regionMap, chunk, surface, natives, tick, tempQuery)
|
function chunkUtils.remakeChunk(regionMap, chunk, surface, natives, tick, tempQuery)
|
||||||
@@ -155,7 +273,7 @@ function chunkUtils.remakeChunk(regionMap, chunk, surface, natives, tick, tempQu
|
|||||||
for f=1, #enemies do
|
for f=1, #enemies do
|
||||||
local enemy = enemies[f]
|
local enemy = enemies[f]
|
||||||
local entityType = enemies[f].type
|
local entityType = enemies[f].type
|
||||||
if not ((enemy.name == "small-tendril-biter-rampant") or (enemy.name == "biter-spawner-hive")) then
|
if not ((enemy.name == "small-tendril-biter-rampant") or (enemy.name == "biter-spawner-hive-rampant")) then
|
||||||
if (entityType == "unit-spawner") then
|
if (entityType == "unit-spawner") then
|
||||||
points = points + 3
|
points = points + 3
|
||||||
elseif (entityType == "turret") then
|
elseif (entityType == "turret") then
|
||||||
@@ -166,13 +284,13 @@ function chunkUtils.remakeChunk(regionMap, chunk, surface, natives, tick, tempQu
|
|||||||
enemy.destroy()
|
enemy.destroy()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local foundBase = findNearbyBase(natives, chunk) or createBase(regionMap, natives, chunk, surface, tick)
|
-- local foundBase = findNearbyBase(natives, chunk) or createBase(regionMap, natives, chunk, surface, tick)
|
||||||
if foundBase then
|
-- if foundBase then
|
||||||
foundBase.upgradePoints = foundBase.upgradePoints + points
|
-- foundBase.upgradePoints = foundBase.upgradePoints + points
|
||||||
end
|
-- end
|
||||||
end
|
end
|
||||||
|
|
||||||
function chunkUtils.registerChunkEnemies(chunk, surface, tempQuery)
|
function chunkUtils.registerChunkEnemies(regionMap, chunk, surface, tempQuery)
|
||||||
tempQuery.force = "enemy"
|
tempQuery.force = "enemy"
|
||||||
local enemies = surface.find_entities_filtered(tempQuery)
|
local enemies = surface.find_entities_filtered(tempQuery)
|
||||||
|
|
||||||
@@ -180,15 +298,61 @@ function chunkUtils.registerChunkEnemies(chunk, surface, tempQuery)
|
|||||||
local enemy = enemies[i]
|
local enemy = enemies[i]
|
||||||
local enemyType = enemy.type
|
local enemyType = enemy.type
|
||||||
if (enemyType == "unit-spawner") or (enemyType == "turret") then
|
if (enemyType == "unit-spawner") or (enemyType == "turret") then
|
||||||
addEnemyStructureToChunk(chunk, enemy, nil)
|
addEnemyStructureToChunk(regionMap, chunk, enemy, nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function chunkUtils.scoreChunk(chunk, surface, natives, tempQuery)
|
function chunkUtils.getNestCount(regionMap, chunk)
|
||||||
|
local nests = regionMap.chunkToNests[chunk]
|
||||||
|
return (nests and #nests) or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.getWormCount(regionMap, chunk)
|
||||||
|
local worms = regionMap.chunkToWorms[chunk]
|
||||||
|
return (worms and #worms) or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.getRetreatTick(regionMap, chunk)
|
||||||
|
return regionMap.chunkToRetreats[chunk] or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.getRallyTick(regionMap, chunk)
|
||||||
|
return regionMap.chunkToRallys[chunk] or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.setRallyTick(regionMap, chunk, tick)
|
||||||
|
regionMap.chunkToRallys[chunk] = tick
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.setRetreatTick(regionMap, chunk, tick)
|
||||||
|
regionMap.chunkToRetreats[chunk] = tick
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.setResourceGenerator(regionMap, chunk, playerGenerator)
|
||||||
|
regionMap.chunkToResource[chunk] = playerGenerator
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.getResourceGenerator(regionMap, chunk)
|
||||||
|
return regionMap.chunkToResource[chunk] or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.getPlayerBaseGenerator(regionMap, chunk)
|
||||||
|
return regionMap.chunkToPlayerBase[chunk] or 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.setPlayerBaseGenerator(regionMap, chunk, playerGenerator)
|
||||||
|
regionMap.chunkToPlayerBase[chunk] = playerGenerator
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.addPlayerBaseGenerator(regionMap, chunk, playerGenerator)
|
||||||
|
regionMap.chunkToPlayerBase[chunk] = regionMap.chunkToPlayerBase[chunk] + playerGenerator
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.scoreChunk(regionMap, chunk, surface, natives, tempQuery)
|
||||||
tempQuery.force = nil
|
tempQuery.force = nil
|
||||||
tempQuery.type = "resource"
|
tempQuery.type = "resource"
|
||||||
chunk[RESOURCE_GENERATOR] = surface.count_entities_filtered(tempQuery) * 0.001
|
chunkUtils.setResourceGenerator(regionMap, chunk, surface.count_entities_filtered(tempQuery) * 0.001)
|
||||||
|
|
||||||
tempQuery.type = nil
|
tempQuery.type = nil
|
||||||
tempQuery.force = "player"
|
tempQuery.force = "player"
|
||||||
@@ -207,36 +371,27 @@ function chunkUtils.scoreChunk(chunk, surface, natives, tempQuery)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local entityScore = BUILDING_PHEROMONES[entityType]
|
local entityScore = BUILDING_PHEROMONES[entityType]
|
||||||
if (entityScore ~= nil) then
|
if entityScore then
|
||||||
playerObjects = playerObjects + entityScore
|
playerObjects = playerObjects + entityScore
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
chunk[PLAYER_BASE_GENERATOR] = playerObjects
|
chunkUtils.setPlayerBaseGenerator(regionMap, chunk, playerObjects)
|
||||||
end
|
end
|
||||||
|
|
||||||
function chunkUtils.createChunk(topX, topY)
|
function chunkUtils.createChunk(topX, topY)
|
||||||
local chunk = {
|
local chunk = {
|
||||||
x = topX,
|
x = topX,
|
||||||
y = topY,
|
y = topY
|
||||||
cX = topX * 0.03125,
|
|
||||||
cY = topY * 0.03125
|
|
||||||
}
|
}
|
||||||
chunk[MOVEMENT_PHEROMONE] = 0
|
chunk[MOVEMENT_PHEROMONE] = 0
|
||||||
chunk[BASE_PHEROMONE] = 0
|
chunk[BASE_PHEROMONE] = 0
|
||||||
chunk[PLAYER_PHEROMONE] = 0
|
chunk[PLAYER_PHEROMONE] = 0
|
||||||
chunk[RESOURCE_PHEROMONE] = 0
|
chunk[RESOURCE_PHEROMONE] = 0
|
||||||
chunk[PLAYER_BASE_GENERATOR] = 0
|
|
||||||
chunk[RESOURCE_GENERATOR] = 0
|
|
||||||
chunk[PASSABLE] = 0
|
chunk[PASSABLE] = 0
|
||||||
chunk[CHUNK_TICK] = 0
|
chunk[CHUNK_TICK] = 0
|
||||||
chunk[RETREAT_TRIGGERED] = 0
|
|
||||||
chunk[RALLY_TRIGGERED] = 0
|
|
||||||
chunk[NEST_BASE] = {}
|
|
||||||
chunk[WORM_BASE] = {}
|
|
||||||
chunk[NEST_COUNT] = 0
|
|
||||||
chunk[WORM_COUNT] = 0
|
|
||||||
chunk[PATH_RATING] = 0
|
chunk[PATH_RATING] = 0
|
||||||
|
|
||||||
return chunk
|
return chunk
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -250,4 +405,109 @@ function chunkUtils.colorChunk(x, y, tileType, surface)
|
|||||||
surface.set_tiles(tiles, false)
|
surface.set_tiles(tiles, false)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function chunkUtils.registerEnemyBaseStructure(regionMap, entity, base)
|
||||||
|
local entityType = entity.type
|
||||||
|
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
|
||||||
|
local leftTop, rightTop, leftBottom, rightBottom = getEntityOverlapChunks(regionMap, entity)
|
||||||
|
|
||||||
|
if (leftTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
addEnemyStructureToChunk(regionMap, leftTop, entity, base)
|
||||||
|
end
|
||||||
|
if (rightTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
addEnemyStructureToChunk(regionMap, rightTop, entity, base)
|
||||||
|
end
|
||||||
|
if (leftBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
addEnemyStructureToChunk(regionMap, leftBottom, entity, base)
|
||||||
|
end
|
||||||
|
if (rightBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
addEnemyStructureToChunk(regionMap, rightBottom, entity, base)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.unregisterEnemyBaseStructure(regionMap, entity)
|
||||||
|
local entityType = entity.type
|
||||||
|
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
|
||||||
|
local leftTop, rightTop, leftBottom, rightBottom = getEntityOverlapChunks(regionMap, entity)
|
||||||
|
|
||||||
|
if (leftTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
removeEnemyStructureFromChunk(regionMap, leftTop, entity)
|
||||||
|
end
|
||||||
|
if (rightTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
removeEnemyStructureFromChunk(regionMap, rightTop, entity)
|
||||||
|
end
|
||||||
|
if (leftBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
removeEnemyStructureFromChunk(regionMap, leftBottom, entity)
|
||||||
|
end
|
||||||
|
if (rightBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
removeEnemyStructureFromChunk(regionMap, rightBottom, entity)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.addRemovePlayerEntity(regionMap, entity, natives, addObject, creditNatives)
|
||||||
|
local leftTop, rightTop, leftBottom, rightBottom
|
||||||
|
local entityValue
|
||||||
|
if (BUILDING_PHEROMONES[entity.type] ~= nil) and (entity.force.name == "player") then
|
||||||
|
entityValue = BUILDING_PHEROMONES[entity.type]
|
||||||
|
|
||||||
|
leftTop, rightTop, leftBottom, rightBottom = getEntityOverlapChunks(regionMap, entity)
|
||||||
|
if not addObject then
|
||||||
|
if creditNatives then
|
||||||
|
natives.points = natives.points + entityValue
|
||||||
|
end
|
||||||
|
entityValue = -entityValue
|
||||||
|
end
|
||||||
|
if (leftTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
chunkUtils.addPlayerBaseGenerator(regionMap, leftTop, entityValue)
|
||||||
|
end
|
||||||
|
if (rightTop ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
chunkUtils.addPlayerBaseGenerator(regionMap, rightTop, entityValue)
|
||||||
|
end
|
||||||
|
if (leftBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
chunkUtils.addPlayerBaseGenerator(regionMap, leftBottom, entityValue)
|
||||||
|
end
|
||||||
|
if (rightBottom ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
|
chunkUtils.addPlayerBaseGenerator(regionMap, rightBottom, entityValue)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return entity
|
||||||
|
end
|
||||||
|
|
||||||
|
function chunkUtils.makeImmortalEntity(surface, entity)
|
||||||
|
local repairPosition = entity.position
|
||||||
|
local repairName = entity.name
|
||||||
|
local repairForce = entity.force
|
||||||
|
local repairDirection = entity.direction
|
||||||
|
|
||||||
|
local wires
|
||||||
|
if (entity.type == "electric-pole") then
|
||||||
|
wires = entity.neighbours
|
||||||
|
end
|
||||||
|
entity.destroy()
|
||||||
|
local newEntity = surface.create_entity({position=repairPosition,
|
||||||
|
name=repairName,
|
||||||
|
direction=repairDirection,
|
||||||
|
force=repairForce})
|
||||||
|
if wires then
|
||||||
|
for connectType,neighbourGroup in pairs(wires) do
|
||||||
|
if connectType == "copper" then
|
||||||
|
for _,v in pairs(neighbourGroup) do
|
||||||
|
newEntity.connect_neighbour(v);
|
||||||
|
end
|
||||||
|
elseif connectType == "red" then
|
||||||
|
for _,v in pairs(neighbourGroup) do
|
||||||
|
newEntity.connect_neighbour({wire = DEFINES_WIRE_TYPE_RED, target_entity = v});
|
||||||
|
end
|
||||||
|
elseif connectType == "green" then
|
||||||
|
for _,v in pairs(neighbourGroup) do
|
||||||
|
newEntity.connect_neighbour({wire = DEFINES_WIRE_TYPE_GREEN, target_entity = v});
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
newEntity.destructible = false
|
||||||
|
end
|
||||||
|
|
||||||
return chunkUtils
|
return chunkUtils
|
||||||
|
@@ -15,10 +15,11 @@ constants.VERSION_25 = 25
|
|||||||
constants.VERSION_26 = 26
|
constants.VERSION_26 = 26
|
||||||
constants.VERSION_27 = 27
|
constants.VERSION_27 = 27
|
||||||
constants.VERSION_28 = 28
|
constants.VERSION_28 = 28
|
||||||
constants.VERSION_32 = 32
|
constants.VERSION_33 = 33
|
||||||
|
|
||||||
-- misc
|
-- misc
|
||||||
|
|
||||||
|
constants.CHUNK_SIZE_DIVIDER = 0.03125
|
||||||
constants.MAGIC_MAXIMUM_NUMBER = 1e99 -- used in loops trying to find the lowest/highest score
|
constants.MAGIC_MAXIMUM_NUMBER = 1e99 -- used in loops trying to find the lowest/highest score
|
||||||
constants.MAGIC_MAXIMUM_BASE_NUMBER = 100000000
|
constants.MAGIC_MAXIMUM_BASE_NUMBER = 100000000
|
||||||
constants.RETREAT_MOVEMENT_PHEROMONE_LEVEL = 10000
|
constants.RETREAT_MOVEMENT_PHEROMONE_LEVEL = 10000
|
||||||
@@ -28,7 +29,7 @@ constants.SCAN_QUEUE_SIZE = 5
|
|||||||
constants.ITEM_COLLECTOR_QUEUE_SIZE = 6
|
constants.ITEM_COLLECTOR_QUEUE_SIZE = 6
|
||||||
constants.BASE_QUEUE_SIZE = 1
|
constants.BASE_QUEUE_SIZE = 1
|
||||||
constants.SQUAD_QUEUE_SIZE = 2
|
constants.SQUAD_QUEUE_SIZE = 2
|
||||||
constants.PROCESS_PLAYER_BOUND = 4
|
constants.PROCESS_PLAYER_BOUND = 128
|
||||||
|
|
||||||
constants.ITEM_COLLECTOR_MAX_QUEUE_SIZE = 20
|
constants.ITEM_COLLECTOR_MAX_QUEUE_SIZE = 20
|
||||||
|
|
||||||
@@ -42,6 +43,18 @@ constants.PLAYER_PHEROMONE_MULTIPLER = 100
|
|||||||
|
|
||||||
constants.DEV_CUSTOM_AI = false
|
constants.DEV_CUSTOM_AI = false
|
||||||
|
|
||||||
|
-- mask
|
||||||
|
|
||||||
|
constants.MASK_PASSABLE = 3
|
||||||
|
constants.MASK_PASSABLE_SIZE = 2
|
||||||
|
constants.MASK_NEST_COUNT = 511
|
||||||
|
constants.MASK_NEST_COUNT_SIZE = 9
|
||||||
|
constants.MASK_WORM_COUNT = 511
|
||||||
|
constants.MASK_WORM_COUNT_SIZE = 9
|
||||||
|
constants.MASK_PASSABLE_AND_NEST_COUNT = 2047
|
||||||
|
constants.MASK_PASSABLE_AND_NEST_COUNT_SIZE = 11
|
||||||
|
|
||||||
|
|
||||||
-- item collector
|
-- item collector
|
||||||
|
|
||||||
constants.ITEM_COLLECTOR_DISTANCE = 50
|
constants.ITEM_COLLECTOR_DISTANCE = 50
|
||||||
@@ -127,19 +140,11 @@ constants.BASE_PHEROMONE = 2
|
|||||||
constants.PLAYER_PHEROMONE = 3
|
constants.PLAYER_PHEROMONE = 3
|
||||||
constants.RESOURCE_PHEROMONE = 4
|
constants.RESOURCE_PHEROMONE = 4
|
||||||
|
|
||||||
constants.PLAYER_BASE_GENERATOR = 5
|
constants.PASSABLE = 5
|
||||||
constants.RESOURCE_GENERATOR = 6
|
|
||||||
|
|
||||||
constants.PASSABLE = 7
|
constants.CHUNK_TICK = 6
|
||||||
|
|
||||||
constants.CHUNK_TICK = 8
|
constants.PATH_RATING = 7
|
||||||
constants.RETREAT_TRIGGERED = 9
|
|
||||||
constants.RALLY_TRIGGERED = 10
|
|
||||||
constants.NEST_BASE = 11
|
|
||||||
constants.WORM_BASE = 12
|
|
||||||
constants.NEST_COUNT = 13
|
|
||||||
constants.WORM_COUNT = 14
|
|
||||||
constants.PATH_RATING = 15
|
|
||||||
|
|
||||||
-- Squad status
|
-- Squad status
|
||||||
|
|
||||||
@@ -155,7 +160,7 @@ constants.RETREAT_GRAB_RADIUS = 24
|
|||||||
constants.BASE_RALLY_CHANCE = 0.02
|
constants.BASE_RALLY_CHANCE = 0.02
|
||||||
constants.BONUS_RALLY_CHANCE = 0.06
|
constants.BONUS_RALLY_CHANCE = 0.06
|
||||||
|
|
||||||
constants.RALLY_CRY_DISTANCE = 3
|
constants.RALLY_CRY_DISTANCE = 96
|
||||||
|
|
||||||
constants.GROUP_MERGE_DISTANCE = 28
|
constants.GROUP_MERGE_DISTANCE = 28
|
||||||
|
|
||||||
@@ -211,6 +216,20 @@ constants.UNIT_GROUP_MAX_SPEED_UP = 1.1
|
|||||||
constants.UNIT_GROUP_MAX_SLOWDOWN = 1.0
|
constants.UNIT_GROUP_MAX_SLOWDOWN = 1.0
|
||||||
constants.UNIT_GROUP_SLOWDOWN_FACTOR = 0.9
|
constants.UNIT_GROUP_SLOWDOWN_FACTOR = 0.9
|
||||||
|
|
||||||
|
-- sentinels
|
||||||
|
|
||||||
|
constants.SENTINEL_IMPASSABLE_CHUNK = {}
|
||||||
|
|
||||||
|
constants.SENTINEL_IMPASSABLE_CHUNK[constants.MOVEMENT_PHEROMONE] = constants.IMPASSABLE_TERRAIN_GENERATOR_AMOUNT
|
||||||
|
constants.SENTINEL_IMPASSABLE_CHUNK[constants.BASE_PHEROMONE] = constants.IMPASSABLE_TERRAIN_GENERATOR_AMOUNT
|
||||||
|
constants.SENTINEL_IMPASSABLE_CHUNK[constants.PLAYER_PHEROMONE] = constants.IMPASSABLE_TERRAIN_GENERATOR_AMOUNT
|
||||||
|
constants.SENTINEL_IMPASSABLE_CHUNK[constants.RESOURCE_PHEROMONE] = constants.IMPASSABLE_TERRAIN_GENERATOR_AMOUNT
|
||||||
|
constants.SENTINEL_IMPASSABLE_CHUNK[constants.PASSABLE] = constants.CHUNK_IMPASSABLE
|
||||||
|
constants.SENTINEL_IMPASSABLE_CHUNK[constants.CHUNK_TICK] = 0
|
||||||
|
constants.SENTINEL_IMPASSABLE_CHUNK[constants.PATH_RATING] = 0
|
||||||
|
constants.SENTINEL_IMPASSABLE_CHUNK.x = 0
|
||||||
|
constants.SENTINEL_IMPASSABLE_CHUNK.y = 0
|
||||||
|
|
||||||
return constants
|
return constants
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
|
@@ -1,147 +0,0 @@
|
|||||||
local entityUtils = {}
|
|
||||||
|
|
||||||
-- imports
|
|
||||||
|
|
||||||
local mapUtils = require("MapUtils")
|
|
||||||
local constants = require("Constants")
|
|
||||||
|
|
||||||
-- constants
|
|
||||||
|
|
||||||
local BUILDING_PHEROMONES = constants.BUILDING_PHEROMONES
|
|
||||||
|
|
||||||
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
|
|
||||||
|
|
||||||
local DEFINES_DIRECTION_EAST = defines.direction.east
|
|
||||||
local DEFINES_WIRE_TYPE_RED = defines.wire_type.red
|
|
||||||
local DEFINES_WIRE_TYPE_GREEN = defines.wire_type.green
|
|
||||||
|
|
||||||
-- imported functions
|
|
||||||
|
|
||||||
local getChunkByIndex = mapUtils.getChunkByIndex
|
|
||||||
|
|
||||||
local mFloor = math.floor
|
|
||||||
|
|
||||||
-- module code
|
|
||||||
|
|
||||||
function entityUtils.getEntityOverlapChunks(regionMap, entity)
|
|
||||||
local boundingBox = entity.prototype.selection_box or entity.prototype.collision_box;
|
|
||||||
|
|
||||||
local leftTopChunk
|
|
||||||
local rightTopChunk
|
|
||||||
local leftBottomChunk
|
|
||||||
local rightBottomChunk
|
|
||||||
|
|
||||||
if (boundingBox ~= nil) then
|
|
||||||
local center = entity.position
|
|
||||||
local topXOffset
|
|
||||||
local topYOffset
|
|
||||||
|
|
||||||
local bottomXOffset
|
|
||||||
local bottomYOffset
|
|
||||||
|
|
||||||
if (entity.direction == DEFINES_DIRECTION_EAST) then
|
|
||||||
topXOffset = boundingBox.left_top.y
|
|
||||||
topYOffset = boundingBox.left_top.x
|
|
||||||
bottomXOffset = boundingBox.right_bottom.y
|
|
||||||
bottomYOffset = boundingBox.right_bottom.x
|
|
||||||
else
|
|
||||||
topXOffset = boundingBox.left_top.x
|
|
||||||
topYOffset = boundingBox.left_top.y
|
|
||||||
bottomXOffset = boundingBox.right_bottom.x
|
|
||||||
bottomYOffset = boundingBox.right_bottom.y
|
|
||||||
end
|
|
||||||
|
|
||||||
local leftTopChunkX = mFloor((center.x + topXOffset) * 0.03125)
|
|
||||||
local leftTopChunkY = mFloor((center.y + topYOffset) * 0.03125)
|
|
||||||
|
|
||||||
-- used to force things on chunk boundary to not spill over 0.0001
|
|
||||||
local rightTopChunkX = mFloor((center.x + bottomXOffset - 0.0001) * 0.03125)
|
|
||||||
local rightTopChunkY = leftTopChunkY
|
|
||||||
|
|
||||||
-- used to force things on chunk boundary to not spill over 0.0001
|
|
||||||
local leftBottomChunkX = leftTopChunkX
|
|
||||||
local leftBottomChunkY = mFloor((center.y + bottomYOffset - 0.0001) * 0.03125)
|
|
||||||
|
|
||||||
local rightBottomChunkX = rightTopChunkX
|
|
||||||
local rightBottomChunkY = leftBottomChunkY
|
|
||||||
|
|
||||||
leftTopChunk = getChunkByIndex(regionMap, leftTopChunkX, leftTopChunkY)
|
|
||||||
if (leftTopChunkX ~= rightTopChunkX) then
|
|
||||||
rightTopChunk = getChunkByIndex(regionMap, rightTopChunkX, rightTopChunkY)
|
|
||||||
end
|
|
||||||
if (leftTopChunkY ~= leftBottomChunkY) then
|
|
||||||
leftBottomChunk = getChunkByIndex(regionMap, leftBottomChunkX, leftBottomChunkY)
|
|
||||||
end
|
|
||||||
if (leftTopChunkX ~= rightBottomChunkX) and (leftTopChunkY ~= rightBottomChunkY) then
|
|
||||||
rightBottomChunk = getChunkByIndex(regionMap, rightBottomChunkX, rightBottomChunkY)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return leftTopChunk, rightTopChunk, leftBottomChunk, rightBottomChunk
|
|
||||||
end
|
|
||||||
|
|
||||||
function entityUtils.addRemovePlayerEntity(regionMap, entity, natives, addObject, creditNatives)
|
|
||||||
local leftTop, rightTop, leftBottom, rightBottom
|
|
||||||
local entityValue
|
|
||||||
if (BUILDING_PHEROMONES[entity.type] ~= nil) and (entity.force.name == "player") then
|
|
||||||
entityValue = BUILDING_PHEROMONES[entity.type]
|
|
||||||
|
|
||||||
leftTop, rightTop, leftBottom, rightBottom = entityUtils.getEntityOverlapChunks(regionMap, entity)
|
|
||||||
if not addObject then
|
|
||||||
if creditNatives then
|
|
||||||
natives.points = natives.points + entityValue
|
|
||||||
end
|
|
||||||
entityValue = -entityValue
|
|
||||||
end
|
|
||||||
if leftTop then
|
|
||||||
leftTop[PLAYER_BASE_GENERATOR] = leftTop[PLAYER_BASE_GENERATOR] + entityValue
|
|
||||||
end
|
|
||||||
if rightTop then
|
|
||||||
rightTop[PLAYER_BASE_GENERATOR] = rightTop[PLAYER_BASE_GENERATOR] + entityValue
|
|
||||||
end
|
|
||||||
if leftBottom then
|
|
||||||
leftBottom[PLAYER_BASE_GENERATOR] = leftBottom[PLAYER_BASE_GENERATOR] + entityValue
|
|
||||||
end
|
|
||||||
if rightBottom then
|
|
||||||
rightBottom[PLAYER_BASE_GENERATOR] = rightBottom[PLAYER_BASE_GENERATOR] + entityValue
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return entity
|
|
||||||
end
|
|
||||||
|
|
||||||
function entityUtils.makeImmortalEntity(surface, entity)
|
|
||||||
local repairPosition = entity.position
|
|
||||||
local repairName = entity.name
|
|
||||||
local repairForce = entity.force
|
|
||||||
local repairDirection = entity.direction
|
|
||||||
|
|
||||||
local wires
|
|
||||||
if (entity.type == "electric-pole") then
|
|
||||||
wires = entity.neighbours
|
|
||||||
end
|
|
||||||
entity.destroy()
|
|
||||||
local newEntity = surface.create_entity({position=repairPosition,
|
|
||||||
name=repairName,
|
|
||||||
direction=repairDirection,
|
|
||||||
force=repairForce})
|
|
||||||
if wires then
|
|
||||||
for connectType,neighbourGroup in pairs(wires) do
|
|
||||||
if connectType == "copper" then
|
|
||||||
for _,v in pairs(neighbourGroup) do
|
|
||||||
newEntity.connect_neighbour(v);
|
|
||||||
end
|
|
||||||
elseif connectType == "red" then
|
|
||||||
for _,v in pairs(neighbourGroup) do
|
|
||||||
newEntity.connect_neighbour({wire = DEFINES_WIRE_TYPE_RED, target_entity = v});
|
|
||||||
end
|
|
||||||
elseif connectType == "green" then
|
|
||||||
for _,v in pairs(neighbourGroup) do
|
|
||||||
newEntity.connect_neighbour({wire = DEFINES_WIRE_TYPE_GREEN, target_entity = v});
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
newEntity.destructible = false
|
|
||||||
end
|
|
||||||
|
|
||||||
return entityUtils
|
|
@@ -1,46 +0,0 @@
|
|||||||
local inventoryUtils = {}
|
|
||||||
|
|
||||||
-- imported functions
|
|
||||||
|
|
||||||
local mMin = math.min
|
|
||||||
|
|
||||||
-- modules code
|
|
||||||
|
|
||||||
function inventoryUtils.swapItemInventory(inventory, src, dst)
|
|
||||||
if inventory and inventory.valid then
|
|
||||||
local itemCount = inventory.get_item_count(src)
|
|
||||||
if (itemCount > 0) then
|
|
||||||
inventory.remove({name = src, count = itemCount})
|
|
||||||
inventory.insert({name = dst, count = itemCount})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function inventoryUtils.topOffHand(inventory, handStack, src, dst)
|
|
||||||
if inventory and inventory.valid then
|
|
||||||
local itemCount = inventory.get_item_count(src)
|
|
||||||
if (itemCount > 0) then
|
|
||||||
if handStack and handStack.valid and handStack.valid_for_read and (handStack.prototype.name == dst) then
|
|
||||||
local remaining = mMin(itemCount, handStack.prototype.stack_size - handStack.count)
|
|
||||||
if (remaining > 0) then
|
|
||||||
local stack = { name = src, count = remaining + handStack.count }
|
|
||||||
if (handStack.can_set_stack(stack)) and handStack.set_stack(stack) then
|
|
||||||
inventory.remove({name = src, count = remaining})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function inventoryUtils.swapItemStack(stack, src, dst)
|
|
||||||
if stack and stack.valid_for_read and (stack.name == src) then
|
|
||||||
local item = { name = dst, count = stack.count }
|
|
||||||
if stack.can_set_stack(item) then
|
|
||||||
stack.set_stack(item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
return inventoryUtils
|
|
@@ -3,14 +3,13 @@ local mapProcessor = {}
|
|||||||
-- imports
|
-- imports
|
||||||
|
|
||||||
local unitGroupUtils = require("UnitGroupUtils")
|
local unitGroupUtils = require("UnitGroupUtils")
|
||||||
|
|
||||||
local pheromoneUtils = require("PheromoneUtils")
|
local pheromoneUtils = require("PheromoneUtils")
|
||||||
local aiAttackWave = require("AIAttackWave")
|
local aiAttackWave = require("AIAttackWave")
|
||||||
local aiPredicates = require("AIPredicates")
|
local aiPredicates = require("AIPredicates")
|
||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
local mapUtils = require("MapUtils")
|
local mapUtils = require("MapUtils")
|
||||||
local playerUtils = require("PlayerUtils")
|
local playerUtils = require("PlayerUtils")
|
||||||
|
local chunkUtils = require("ChunkUtils")
|
||||||
local mathUtils = require("MathUtils")
|
local mathUtils = require("MathUtils")
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
@@ -26,30 +25,33 @@ local TRIPLE_CHUNK_SIZE = constants.TRIPLE_CHUNK_SIZE
|
|||||||
local PROCESS_PLAYER_BOUND = constants.PROCESS_PLAYER_BOUND
|
local PROCESS_PLAYER_BOUND = constants.PROCESS_PLAYER_BOUND
|
||||||
local CHUNK_TICK = constants.CHUNK_TICK
|
local CHUNK_TICK = constants.CHUNK_TICK
|
||||||
|
|
||||||
local NEST_COUNT = constants.NEST_COUNT
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
local WORM_COUNT = constants.WORM_COUNT
|
|
||||||
|
|
||||||
local AI_SQUAD_COST = constants.AI_SQUAD_COST
|
local AI_SQUAD_COST = constants.AI_SQUAD_COST
|
||||||
local AI_VENGENCE_SQUAD_COST = constants.AI_VENGENCE_SQUAD_COST
|
local AI_VENGENCE_SQUAD_COST = constants.AI_VENGENCE_SQUAD_COST
|
||||||
|
|
||||||
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
||||||
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
|
|
||||||
local RESOURCE_GENERATOR = constants.RESOURCE_GENERATOR
|
|
||||||
local BUILDING_PHEROMONES = constants.BUILDING_PHEROMONES
|
local BUILDING_PHEROMONES = constants.BUILDING_PHEROMONES
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
local scents = pheromoneUtils.scents
|
local scents = pheromoneUtils.scents
|
||||||
local processPheromone = pheromoneUtils.processPheromone
|
local processPheromone = pheromoneUtils.processPheromone
|
||||||
|
local playerScent = pheromoneUtils.playerScent
|
||||||
|
|
||||||
local formSquads = aiAttackWave.formSquads
|
local formSquads = aiAttackWave.formSquads
|
||||||
|
|
||||||
local getChunkByIndex = mapUtils.getChunkByIndex
|
|
||||||
local getChunkByPosition = mapUtils.getChunkByPosition
|
local getChunkByPosition = mapUtils.getChunkByPosition
|
||||||
|
local positionToChunkXY = mapUtils.positionToChunkXY
|
||||||
|
|
||||||
local recycleBiters = unitGroupUtils.recycleBiters
|
local recycleBiters = unitGroupUtils.recycleBiters
|
||||||
|
|
||||||
local playerScent = pheromoneUtils.playerScent
|
local validPlayer = playerUtils.validPlayer
|
||||||
|
|
||||||
|
local setResourceGenerator = chunkUtils.setResourceGenerator
|
||||||
|
local setPlayerBaseGenerator = chunkUtils.setPlayerBaseGenerator
|
||||||
|
local getNestCount = chunkUtils.getNestCount
|
||||||
|
local getWormCount = chunkUtils.getWormCount
|
||||||
|
|
||||||
local canAttack = aiPredicates.canAttack
|
local canAttack = aiPredicates.canAttack
|
||||||
|
|
||||||
@@ -57,8 +59,6 @@ local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
|
|||||||
|
|
||||||
local mMin = math.min
|
local mMin = math.min
|
||||||
|
|
||||||
local validPlayer = playerUtils.validPlayer
|
|
||||||
|
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
@@ -105,12 +105,12 @@ function mapProcessor.processMap(regionMap, surface, natives, tick)
|
|||||||
|
|
||||||
processPheromone(regionMap, chunk)
|
processPheromone(regionMap, chunk)
|
||||||
|
|
||||||
if squads and (chunk[NEST_COUNT] ~= 0) then
|
if squads and (getNestCount(regionMap, chunk) > 0) then
|
||||||
formSquads(regionMap, surface, natives, chunk, AI_SQUAD_COST)
|
formSquads(regionMap, surface, natives, chunk, AI_SQUAD_COST)
|
||||||
squads = (natives.points >= AI_SQUAD_COST) and (#natives.squads < natives.maxSquads)
|
squads = (natives.points >= AI_SQUAD_COST) and (#natives.squads < natives.maxSquads)
|
||||||
end
|
end
|
||||||
|
|
||||||
scents(chunk)
|
scents(regionMap, chunk)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -141,10 +141,10 @@ function mapProcessor.processPlayers(players, regionMap, surface, natives, tick)
|
|||||||
for i=1,#playerOrdering do
|
for i=1,#playerOrdering do
|
||||||
local player = players[playerOrdering[i]]
|
local player = players[playerOrdering[i]]
|
||||||
if validPlayer(player) then
|
if validPlayer(player) then
|
||||||
local playerPosition = player.character.position
|
local chunkX, chunkY = positionToChunkXY(player.character.position)
|
||||||
local playerChunk = getChunkByPosition(regionMap, playerPosition.x, playerPosition.y)
|
local playerChunk = getChunkByPosition(regionMap, chunkX, chunkY)
|
||||||
|
|
||||||
if playerChunk then
|
if (playerChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
playerScent(playerChunk)
|
playerScent(playerChunk)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -152,21 +152,24 @@ function mapProcessor.processPlayers(players, regionMap, surface, natives, tick)
|
|||||||
for i=1,#playerOrdering do
|
for i=1,#playerOrdering do
|
||||||
local player = players[playerOrdering[i]]
|
local player = players[playerOrdering[i]]
|
||||||
if validPlayer(player) then
|
if validPlayer(player) then
|
||||||
local playerPosition = player.character.position
|
local chunkX, chunkY = positionToChunkXY(player.character.position)
|
||||||
local playerChunk = getChunkByPosition(regionMap, playerPosition.x, playerPosition.y)
|
local playerChunk = getChunkByPosition(regionMap, chunkX, chunkY)
|
||||||
|
|
||||||
if playerChunk then
|
if (playerChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
local vengence = allowingAttacks and ((playerChunk[NEST_COUNT] ~= 0) or (playerChunk[WORM_COUNT] ~= 0) or (playerChunk[MOVEMENT_PHEROMONE] < natives.retreatThreshold)) and (natives.points >= AI_VENGENCE_SQUAD_COST)
|
local vengence = (allowingAttacks and
|
||||||
|
(natives.points >= AI_VENGENCE_SQUAD_COST) and
|
||||||
|
((getWormCount(regionMap, playerChunk) > 0) or (getNestCount(regionMap, playerChunk) > 0) or (playerChunk[MOVEMENT_PHEROMONE] < natives.retreatThreshold)))
|
||||||
|
|
||||||
for x=playerChunk.cX - PROCESS_PLAYER_BOUND, playerChunk.cX + PROCESS_PLAYER_BOUND do
|
for x=playerChunk.x - PROCESS_PLAYER_BOUND, playerChunk.x + PROCESS_PLAYER_BOUND, 32 do
|
||||||
for y=playerChunk.cY - PROCESS_PLAYER_BOUND, playerChunk.cY + PROCESS_PLAYER_BOUND do
|
for y=playerChunk.y - PROCESS_PLAYER_BOUND, playerChunk.y + PROCESS_PLAYER_BOUND, 32 do
|
||||||
local chunk = getChunkByIndex(regionMap, x, y)
|
local chunk = getChunkByPosition(regionMap, x, y)
|
||||||
if chunk and (chunk[CHUNK_TICK] ~= tick) then
|
|
||||||
|
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) and (chunk[CHUNK_TICK] ~= tick) then
|
||||||
chunk[CHUNK_TICK] = tick
|
chunk[CHUNK_TICK] = tick
|
||||||
|
|
||||||
processPheromone(regionMap, chunk)
|
processPheromone(regionMap, chunk)
|
||||||
|
|
||||||
if (chunk[NEST_COUNT] ~= 0) then
|
if (getNestCount(regionMap, chunk) > 0) then
|
||||||
if squads then
|
if squads then
|
||||||
formSquads(regionMap, surface, natives, chunk, AI_SQUAD_COST)
|
formSquads(regionMap, surface, natives, chunk, AI_SQUAD_COST)
|
||||||
squads = (natives.points >= AI_SQUAD_COST) and (#natives.squads < natives.maxSquads)
|
squads = (natives.points >= AI_SQUAD_COST) and (#natives.squads < natives.maxSquads)
|
||||||
@@ -177,7 +180,7 @@ function mapProcessor.processPlayers(players, regionMap, surface, natives, tick)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scents(chunk)
|
scents(regionMap, chunk)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -232,7 +235,7 @@ function mapProcessor.scanMap(regionMap, surface, natives)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
chunk[RESOURCE_GENERATOR] = surface.count_entities_filtered(resourceQuery) * 0.001
|
setResourceGenerator(regionMap, chunk, surface.count_entities_filtered(resourceQuery) * 0.001)
|
||||||
|
|
||||||
local entities = surface.find_entities_filtered(playerQuery)
|
local entities = surface.find_entities_filtered(playerQuery)
|
||||||
local playerBaseGenerator = 0
|
local playerBaseGenerator = 0
|
||||||
@@ -250,7 +253,7 @@ function mapProcessor.scanMap(regionMap, surface, natives)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
chunk[PLAYER_BASE_GENERATOR] = playerBaseGenerator
|
setPlayerBaseGenerator(regionMap, chunk, playerBaseGenerator)
|
||||||
end
|
end
|
||||||
|
|
||||||
if (endIndex == #processQueue) then
|
if (endIndex == #processQueue) then
|
||||||
|
@@ -13,10 +13,12 @@ local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
|
|||||||
|
|
||||||
local PASSABLE = constants.PASSABLE
|
local PASSABLE = constants.PASSABLE
|
||||||
|
|
||||||
local CHUNK_IMPASSABLE = constants.CHUNK_IMPASSABLE
|
|
||||||
|
|
||||||
local CHUNK_SIZE = constants.CHUNK_SIZE
|
local CHUNK_SIZE = constants.CHUNK_SIZE
|
||||||
|
|
||||||
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
|
||||||
|
local CHUNK_SIZE_DIVIDER = constants.CHUNK_SIZE_DIVIDER
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
local mFloor = math.floor
|
local mFloor = math.floor
|
||||||
@@ -24,19 +26,17 @@ local mFloor = math.floor
|
|||||||
-- module code
|
-- module code
|
||||||
|
|
||||||
function mapUtils.getChunkByPosition(regionMap, x, y)
|
function mapUtils.getChunkByPosition(regionMap, x, y)
|
||||||
local chunkX = regionMap[mFloor(x * 0.03125)]
|
|
||||||
if chunkX then
|
|
||||||
return chunkX[mFloor(y * 0.03125)]
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
function mapUtils.getChunkByIndex(regionMap, x, y)
|
|
||||||
local chunkX = regionMap[x]
|
local chunkX = regionMap[x]
|
||||||
if chunkX then
|
if chunkX then
|
||||||
return chunkX[y]
|
return chunkX[y] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
end
|
end
|
||||||
return nil
|
return SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
end
|
||||||
|
|
||||||
|
function mapUtils.positionToChunkXY(position)
|
||||||
|
local chunkX = mFloor(position.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
|
||||||
|
local chunkY = mFloor(position.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
|
||||||
|
return chunkX, chunkY
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
@@ -46,39 +46,39 @@ end
|
|||||||
/|\
|
/|\
|
||||||
6 7 8
|
6 7 8
|
||||||
]]--
|
]]--
|
||||||
function mapUtils.getNeighborChunks(regionMap, chunkX, chunkY)
|
function mapUtils.getNeighborChunks(regionMap, x, y)
|
||||||
local neighbors = regionMap.neighbors
|
local neighbors = regionMap.neighbors
|
||||||
local chunkYRow1 = chunkY - 1
|
local chunkYRow1 = y - CHUNK_SIZE
|
||||||
local chunkYRow3 = chunkY + 1
|
local chunkYRow3 = y + CHUNK_SIZE
|
||||||
local xChunks = regionMap[chunkX-1]
|
local xChunks = regionMap[x-CHUNK_SIZE]
|
||||||
if xChunks then
|
if xChunks then
|
||||||
neighbors[1] = xChunks[chunkYRow1]
|
neighbors[1] = xChunks[chunkYRow1] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
neighbors[4] = xChunks[chunkY]
|
neighbors[4] = xChunks[y] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
neighbors[6] = xChunks[chunkYRow3]
|
neighbors[6] = xChunks[chunkYRow3] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
else
|
else
|
||||||
neighbors[1] = nil
|
neighbors[1] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
neighbors[4] = nil
|
neighbors[4] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
neighbors[6] = nil
|
neighbors[6] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
end
|
||||||
|
|
||||||
|
xChunks = regionMap[x+CHUNK_SIZE]
|
||||||
|
if xChunks then
|
||||||
|
neighbors[3] = xChunks[chunkYRow1] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
neighbors[5] = xChunks[y] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
neighbors[8] = xChunks[chunkYRow3] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
else
|
||||||
|
neighbors[3] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
neighbors[5] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
neighbors[8] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
end
|
end
|
||||||
|
|
||||||
xChunks = regionMap[chunkX+1]
|
xChunks = regionMap[x]
|
||||||
if xChunks then
|
if xChunks then
|
||||||
neighbors[3] = xChunks[chunkYRow1]
|
neighbors[2] = xChunks[chunkYRow1] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
neighbors[5] = xChunks[chunkY]
|
neighbors[7] = xChunks[chunkYRow3] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
neighbors[8] = xChunks[chunkYRow3]
|
|
||||||
else
|
else
|
||||||
neighbors[3] = nil
|
neighbors[2] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
neighbors[5] = nil
|
neighbors[7] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
neighbors[8] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
xChunks = regionMap[chunkX]
|
|
||||||
if xChunks then
|
|
||||||
neighbors[2] = xChunks[chunkYRow1]
|
|
||||||
neighbors[7] = xChunks[chunkYRow3]
|
|
||||||
else
|
|
||||||
neighbors[2] = nil
|
|
||||||
neighbors[7] = nil
|
|
||||||
end
|
end
|
||||||
return neighbors
|
return neighbors
|
||||||
end
|
end
|
||||||
@@ -87,41 +87,41 @@ function mapUtils.canMoveChunkDirection(direction, startChunk, endChunk)
|
|||||||
local canMove = false
|
local canMove = false
|
||||||
local startPassable = startChunk[PASSABLE]
|
local startPassable = startChunk[PASSABLE]
|
||||||
local endPassable = endChunk[PASSABLE]
|
local endPassable = endChunk[PASSABLE]
|
||||||
if ((direction == 2) or (direction == 7)) and (startPassable == CHUNK_NORTH_SOUTH) and (endPassable == CHUNK_NORTH_SOUTH) then
|
if (startPassable == CHUNK_ALL_DIRECTIONS) and (endPassable == CHUNK_ALL_DIRECTIONS) then
|
||||||
canMove = true
|
|
||||||
elseif ((direction == 4) or (direction == 5)) and (startPassable == CHUNK_EAST_WEST) and (endPassable == CHUNK_EAST_WEST) then
|
|
||||||
canMove = true
|
|
||||||
elseif (startPassable == CHUNK_ALL_DIRECTIONS) and (endPassable == CHUNK_ALL_DIRECTIONS) then
|
|
||||||
canMove = true
|
canMove = true
|
||||||
elseif (startPassable ~= CHUNK_IMPASSABLE) and (endPassable == CHUNK_ALL_DIRECTIONS) then
|
elseif ((direction == 2) or (direction == 7)) and (startPassable == CHUNK_NORTH_SOUTH) and (endPassable == CHUNK_NORTH_SOUTH) then
|
||||||
|
canMove = true
|
||||||
|
elseif ((direction == 4) or (direction == 5)) and (startPassable == CHUNK_EAST_WEST) and (endPassable == CHUNK_EAST_WEST) then
|
||||||
|
canMove = true
|
||||||
|
elseif (startChunk ~= SENTINEL_IMPASSABLE_CHUNK) and (endPassable == CHUNK_ALL_DIRECTIONS) then
|
||||||
canMove = true
|
canMove = true
|
||||||
end
|
end
|
||||||
return canMove
|
return canMove
|
||||||
end
|
end
|
||||||
|
|
||||||
function mapUtils.getCardinalChunks(regionMap, chunkX, chunkY)
|
function mapUtils.getCardinalChunks(regionMap, x, y)
|
||||||
local neighbors = regionMap.cardinalNeighbors
|
local neighbors = regionMap.cardinalNeighbors
|
||||||
local xChunks = regionMap[chunkX]
|
local xChunks = regionMap[x]
|
||||||
if xChunks then
|
if xChunks then
|
||||||
neighbors[1] = xChunks[chunkY-1]
|
neighbors[1] = xChunks[y-CHUNK_SIZE] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
neighbors[4] = xChunks[chunkY+1]
|
neighbors[4] = xChunks[y+CHUNK_SIZE] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
else
|
else
|
||||||
neighbors[1] = nil
|
neighbors[1] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
neighbors[4] = nil
|
neighbors[4] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
end
|
end
|
||||||
|
|
||||||
xChunks = regionMap[chunkX-1]
|
xChunks = regionMap[x-CHUNK_SIZE]
|
||||||
if xChunks then
|
if xChunks then
|
||||||
neighbors[2] = xChunks[chunkY]
|
neighbors[2] = xChunks[y] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
else
|
else
|
||||||
neighbors[2] = nil
|
neighbors[2] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
end
|
end
|
||||||
|
|
||||||
xChunks = regionMap[chunkX+1]
|
xChunks = regionMap[x+CHUNK_SIZE]
|
||||||
if xChunks then
|
if xChunks then
|
||||||
neighbors[3] = xChunks[chunkY]
|
neighbors[3] = xChunks[y] or SENTINEL_IMPASSABLE_CHUNK
|
||||||
else
|
else
|
||||||
neighbors[3] = nil
|
neighbors[3] = SENTINEL_IMPASSABLE_CHUNK
|
||||||
end
|
end
|
||||||
return neighbors
|
return neighbors
|
||||||
end
|
end
|
||||||
|
@@ -4,7 +4,7 @@ local movementUtils = {}
|
|||||||
|
|
||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
local unitGroupUtils = require("UnitGroupUtils")
|
local unitGroupUtils = require("UnitGroupUtils")
|
||||||
|
local mapUtils = require("MapUtils")
|
||||||
local mathUtils = require("MathUtils")
|
local mathUtils = require("MathUtils")
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
@@ -12,8 +12,16 @@ local mathUtils = require("MathUtils")
|
|||||||
local MOVEMENT_PHEROMONE_GENERATOR_AMOUNT = constants.MOVEMENT_PHEROMONE_GENERATOR_AMOUNT
|
local MOVEMENT_PHEROMONE_GENERATOR_AMOUNT = constants.MOVEMENT_PHEROMONE_GENERATOR_AMOUNT
|
||||||
local MAX_PENALTY_BEFORE_PURGE = constants.MAX_PENALTY_BEFORE_PURGE
|
local MAX_PENALTY_BEFORE_PURGE = constants.MAX_PENALTY_BEFORE_PURGE
|
||||||
|
|
||||||
|
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER
|
||||||
|
|
||||||
|
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE
|
||||||
|
|
||||||
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
|
local canMoveChunkDirection = mapUtils.canMoveChunkDirection
|
||||||
|
|
||||||
local recycleBiters = unitGroupUtils.recycleBiters
|
local recycleBiters = unitGroupUtils.recycleBiters
|
||||||
|
|
||||||
local tableRemove = table.remove
|
local tableRemove = table.remove
|
||||||
@@ -31,11 +39,11 @@ function movementUtils.findMovementPosition(surface, position, distort)
|
|||||||
return (distort and distortPosition(pos)) or pos
|
return (distort and distortPosition(pos)) or pos
|
||||||
end
|
end
|
||||||
|
|
||||||
function movementUtils.addMovementPenalty(natives, units, chunkX, chunkY)
|
function movementUtils.addMovementPenalty(natives, units, x, y)
|
||||||
local penalties = units.penalties
|
local penalties = units.penalties
|
||||||
for i=1,#penalties do
|
for i=1,#penalties do
|
||||||
local penalty = penalties[i]
|
local penalty = penalties[i]
|
||||||
if (penalty.x == chunkX) and (penalty.y == chunkY) then
|
if (penalty.x == x) and (penalty.y == y) then
|
||||||
penalty.v = penalty.v + MOVEMENT_PHEROMONE_GENERATOR_AMOUNT
|
penalty.v = penalty.v + MOVEMENT_PHEROMONE_GENERATOR_AMOUNT
|
||||||
if (penalty.v > MAX_PENALTY_BEFORE_PURGE) then
|
if (penalty.v > MAX_PENALTY_BEFORE_PURGE) then
|
||||||
local group = units.group
|
local group = units.group
|
||||||
@@ -53,15 +61,15 @@ function movementUtils.addMovementPenalty(natives, units, chunkX, chunkY)
|
|||||||
tableRemove(penalties, 7)
|
tableRemove(penalties, 7)
|
||||||
end
|
end
|
||||||
tableInsert(penalties, 1, { v = MOVEMENT_PHEROMONE_GENERATOR_AMOUNT,
|
tableInsert(penalties, 1, { v = MOVEMENT_PHEROMONE_GENERATOR_AMOUNT,
|
||||||
x = chunkX,
|
x = x,
|
||||||
y = chunkY })
|
y = y })
|
||||||
end
|
end
|
||||||
|
|
||||||
function movementUtils.lookupMovementPenalty(squad, chunkX, chunkY)
|
function movementUtils.lookupMovementPenalty(squad, x, y)
|
||||||
local penalties = squad.penalties
|
local penalties = squad.penalties
|
||||||
for i=1,#penalties do
|
for i=1,#penalties do
|
||||||
local penalty = penalties[i]
|
local penalty = penalties[i]
|
||||||
if (penalty.x == chunkX) and (penalty.y == chunkY) then
|
if (penalty.x == x) and (penalty.y == y) then
|
||||||
return penalty.v
|
return penalty.v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -69,4 +77,101 @@ function movementUtils.lookupMovementPenalty(squad, chunkX, chunkY)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Expects all neighbors adjacent to a chunk
|
||||||
|
--]]
|
||||||
|
function movementUtils.scoreNeighborsForAttack(chunk, neighborDirectionChunks, scoreFunction, squad)
|
||||||
|
local highestChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
||||||
|
local highestDirection
|
||||||
|
for x=1,8 do
|
||||||
|
local neighborChunk = neighborDirectionChunks[x]
|
||||||
|
if (neighborChunk ~= SENTINEL_IMPASSABLE_CHUNK) and canMoveChunkDirection(x, chunk, neighborChunk) then
|
||||||
|
local score = scoreFunction(squad, neighborChunk)
|
||||||
|
if (score > highestScore) then
|
||||||
|
highestScore = score
|
||||||
|
highestChunk = neighborChunk
|
||||||
|
highestDirection = x
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if scoreFunction(squad, chunk) > highestScore then
|
||||||
|
return SENTINEL_IMPASSABLE_CHUNK, -1
|
||||||
|
end
|
||||||
|
|
||||||
|
return highestChunk, highestDirection
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Expects all neighbors adjacent to a chunk
|
||||||
|
--]]
|
||||||
|
function movementUtils.scoreNeighborsForResource(chunk, neighborDirectionChunks, scoreFunction, squad, threshold)
|
||||||
|
local highestChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
||||||
|
local highestDirection
|
||||||
|
for x=1,8 do
|
||||||
|
local neighborChunk = neighborDirectionChunks[x]
|
||||||
|
if (neighborChunk ~= SENTINEL_IMPASSABLE_CHUNK) and canMoveChunkDirection(x, chunk, neighborChunk) and (neighborChunk[RESOURCE_PHEROMONE] > (threshold or 1)) then
|
||||||
|
local score = scoreFunction(squad, neighborChunk)
|
||||||
|
if (score > highestScore) then
|
||||||
|
highestScore = score
|
||||||
|
highestChunk = neighborChunk
|
||||||
|
highestDirection = x
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if scoreFunction(squad, chunk) > highestScore then
|
||||||
|
return SENTINEL_IMPASSABLE_CHUNK, -1
|
||||||
|
end
|
||||||
|
|
||||||
|
return highestChunk, highestDirection
|
||||||
|
end
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Expects all neighbors adjacent to a chunk
|
||||||
|
--]]
|
||||||
|
function movementUtils.scoreNeighborsForRetreat(chunk, neighborDirectionChunks, scoreFunction, regionMap)
|
||||||
|
local highestChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
||||||
|
local highestDirection
|
||||||
|
for x=1,8 do
|
||||||
|
local neighborChunk = neighborDirectionChunks[x]
|
||||||
|
if (neighborChunk ~= SENTINEL_IMPASSABLE_CHUNK) and canMoveChunkDirection(x, chunk, neighborChunk) then
|
||||||
|
local score = scoreFunction(regionMap, neighborChunk)
|
||||||
|
if (score > highestScore) then
|
||||||
|
highestScore = score
|
||||||
|
highestChunk = neighborChunk
|
||||||
|
highestDirection = x
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return highestChunk, highestDirection
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Expects all neighbors adjacent to a chunk
|
||||||
|
--]]
|
||||||
|
function movementUtils.scoreNeighborsForFormation(neighborChunks, validFunction, scoreFunction, regionMap)
|
||||||
|
local highestChunk = SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
||||||
|
local highestDirection
|
||||||
|
for x=1,8 do
|
||||||
|
local neighborChunk = neighborChunks[x]
|
||||||
|
if (neighborChunk ~= SENTINEL_IMPASSABLE_CHUNK) and validFunction(regionMap, neighborChunk) then
|
||||||
|
local score = scoreFunction(neighborChunk)
|
||||||
|
if (score > highestScore) then
|
||||||
|
highestScore = score
|
||||||
|
highestChunk = neighborChunk
|
||||||
|
highestDirection = x
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return highestChunk, highestDirection
|
||||||
|
end
|
||||||
|
|
||||||
return movementUtils
|
return movementUtils
|
||||||
|
@@ -1,119 +0,0 @@
|
|||||||
local neighborUtils = {}
|
|
||||||
|
|
||||||
-- imports
|
|
||||||
|
|
||||||
local mapUtils = require("MapUtils")
|
|
||||||
|
|
||||||
local constants = require("Constants")
|
|
||||||
|
|
||||||
-- constants
|
|
||||||
|
|
||||||
local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER
|
|
||||||
|
|
||||||
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE
|
|
||||||
|
|
||||||
-- imported functions
|
|
||||||
|
|
||||||
local canMoveChunkDirection = mapUtils.canMoveChunkDirection
|
|
||||||
|
|
||||||
-- module code
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Expects all neighbors adjacent to a chunk
|
|
||||||
--]]
|
|
||||||
function neighborUtils.scoreNeighborsForAttack(chunk, neighborDirectionChunks, scoreFunction, squad)
|
|
||||||
local highestChunk
|
|
||||||
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
|
||||||
local highestDirection
|
|
||||||
for x=1,8 do
|
|
||||||
local neighborChunk = neighborDirectionChunks[x]
|
|
||||||
if neighborChunk and canMoveChunkDirection(x, chunk, neighborChunk) then
|
|
||||||
local score = scoreFunction(squad, neighborChunk)
|
|
||||||
if (score > highestScore) then
|
|
||||||
highestScore = score
|
|
||||||
highestChunk = neighborChunk
|
|
||||||
highestDirection = x
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if scoreFunction(squad, chunk) > highestScore then
|
|
||||||
return nil, -1
|
|
||||||
end
|
|
||||||
|
|
||||||
return highestChunk, highestDirection
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Expects all neighbors adjacent to a chunk
|
|
||||||
--]]
|
|
||||||
function neighborUtils.scoreNeighborsForResource(chunk, neighborDirectionChunks, scoreFunction, squad, threshold)
|
|
||||||
local highestChunk
|
|
||||||
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
|
||||||
local highestDirection
|
|
||||||
for x=1,8 do
|
|
||||||
local neighborChunk = neighborDirectionChunks[x]
|
|
||||||
if neighborChunk and canMoveChunkDirection(x, chunk, neighborChunk) and (neighborChunk[RESOURCE_PHEROMONE] > (threshold or 1)) then
|
|
||||||
local score = scoreFunction(squad, neighborChunk)
|
|
||||||
if (score > highestScore) then
|
|
||||||
highestScore = score
|
|
||||||
highestChunk = neighborChunk
|
|
||||||
highestDirection = x
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if scoreFunction(squad, chunk) > highestScore then
|
|
||||||
return nil, -1
|
|
||||||
end
|
|
||||||
|
|
||||||
return highestChunk, highestDirection
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Expects all neighbors adjacent to a chunk
|
|
||||||
--]]
|
|
||||||
function neighborUtils.scoreNeighborsForRetreat(chunk, neighborDirectionChunks, scoreFunction)
|
|
||||||
local highestChunk
|
|
||||||
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
|
||||||
local highestDirection
|
|
||||||
for x=1,8 do
|
|
||||||
local neighborChunk = neighborDirectionChunks[x]
|
|
||||||
if neighborChunk and canMoveChunkDirection(x, chunk, neighborChunk) then
|
|
||||||
local score = scoreFunction(neighborChunk)
|
|
||||||
if (score > highestScore) then
|
|
||||||
highestScore = score
|
|
||||||
highestChunk = neighborChunk
|
|
||||||
highestDirection = x
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return highestChunk, highestDirection
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--[[
|
|
||||||
Expects all neighbors adjacent to a chunk
|
|
||||||
--]]
|
|
||||||
function neighborUtils.scoreNeighborsForFormation(neighborChunks, validFunction, scoreFunction)
|
|
||||||
local highestChunk
|
|
||||||
local highestScore = -MAGIC_MAXIMUM_NUMBER
|
|
||||||
local highestDirection
|
|
||||||
for x=1,8 do
|
|
||||||
local neighborChunk = neighborChunks[x]
|
|
||||||
if neighborChunk and validFunction(neighborChunk) then
|
|
||||||
local score = scoreFunction(neighborChunk)
|
|
||||||
if (score > highestScore) then
|
|
||||||
highestScore = score
|
|
||||||
highestChunk = neighborChunk
|
|
||||||
highestDirection = x
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return highestChunk, highestDirection
|
|
||||||
end
|
|
||||||
|
|
||||||
return neighborUtils
|
|
@@ -4,10 +4,8 @@ local nestUtils = {}
|
|||||||
|
|
||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
local mathUtils = require("MathUtils")
|
local mathUtils = require("MathUtils")
|
||||||
|
|
||||||
local baseRegisterUtils = require("BaseRegisterUtils")
|
|
||||||
|
|
||||||
local mapUtils = require("MapUtils")
|
local mapUtils = require("MapUtils")
|
||||||
|
local chunkUtils = require("ChunkUtils")
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
|
|
||||||
@@ -20,9 +18,11 @@ local NEST_COUNT = constants.NEST_COUNT
|
|||||||
|
|
||||||
local DOUBLE_CHUNK_SIZE = constants.DOUBLE_CHUNK_SIZE
|
local DOUBLE_CHUNK_SIZE = constants.DOUBLE_CHUNK_SIZE
|
||||||
|
|
||||||
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
local registerEnemyBaseStructure = baseRegisterUtils.registerEnemyBaseStructure
|
local registerEnemyBaseStructure = chunkUtils.registerEnemyBaseStructure
|
||||||
local gaussianRandomRange = mathUtils.gaussianRandomRange
|
local gaussianRandomRange = mathUtils.gaussianRandomRange
|
||||||
|
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
@@ -35,7 +35,7 @@ function nestUtils.buildNest(regionMap, base, surface, targetPosition, name)
|
|||||||
local position = surface.find_non_colliding_position(name, targetPosition, DOUBLE_CHUNK_SIZE, 2)
|
local position = surface.find_non_colliding_position(name, targetPosition, DOUBLE_CHUNK_SIZE, 2)
|
||||||
local chunk = getChunkByPosition(regionMap, position.x, position.y)
|
local chunk = getChunkByPosition(regionMap, position.x, position.y)
|
||||||
local nest = nil
|
local nest = nil
|
||||||
if position and chunk and (chunk[NEST_COUNT] < 3) then
|
if position and (chunk ~= SENTINEL_IMPASSABLE_CHUNK) and (chunk[NEST_COUNT] < 3) then
|
||||||
local biterSpawner = {name=name, position=position}
|
local biterSpawner = {name=name, position=position}
|
||||||
nest = surface.create_entity(biterSpawner)
|
nest = surface.create_entity(biterSpawner)
|
||||||
registerEnemyBaseStructure(regionMap, nest, base)
|
registerEnemyBaseStructure(regionMap, nest, base)
|
||||||
@@ -45,7 +45,7 @@ end
|
|||||||
|
|
||||||
function nestUtils.buildHive(regionMap, base, surface)
|
function nestUtils.buildHive(regionMap, base, surface)
|
||||||
local valid = false
|
local valid = false
|
||||||
local hive = nestUtils.buildNest(regionMap, base, surface, base, "biter-spawner-hive")
|
local hive = nestUtils.buildNest(regionMap, base, surface, base, "biter-spawner-hive-rampant")
|
||||||
if hive then
|
if hive then
|
||||||
if (#base.hives == 0) then
|
if (#base.hives == 0) then
|
||||||
base.x = hive.position.x
|
base.x = hive.position.x
|
||||||
@@ -101,7 +101,7 @@ function nestUtils.buildOutpost(regionMap, natives, base, surface, tendril)
|
|||||||
y = position.y + (distortion * math.sin(pos))}
|
y = position.y + (distortion * math.sin(pos))}
|
||||||
local biterSpawner = {name=thing, position=nestPosition}
|
local biterSpawner = {name=thing, position=nestPosition}
|
||||||
if surface.can_place_entity(biterSpawner) then
|
if surface.can_place_entity(biterSpawner) then
|
||||||
registerEnemyBaseStructure(regionMap, surface.create_entity(biterSpawner), base)
|
registerEnemyBaseStructure(natives, regionMap, surface.create_entity(biterSpawner), base)
|
||||||
base.upgradePoints = base.upgradePoints - cost
|
base.upgradePoints = base.upgradePoints - cost
|
||||||
end
|
end
|
||||||
pos = pos + slice
|
pos = pos + slice
|
||||||
@@ -149,7 +149,7 @@ function nestUtils.buildOrder(regionMap, natives, base, surface)
|
|||||||
y = base.y + (distortion * math.sin(pos))}
|
y = base.y + (distortion * math.sin(pos))}
|
||||||
local biterSpawner = {name=thing, position=nestPosition}
|
local biterSpawner = {name=thing, position=nestPosition}
|
||||||
if surface.can_place_entity(biterSpawner) then
|
if surface.can_place_entity(biterSpawner) then
|
||||||
registerEnemyBaseStructure(regionMap, surface.create_entity(biterSpawner), base)
|
registerEnemyBaseStructure(natives, regionMap, surface.create_entity(biterSpawner), base)
|
||||||
base.upgradePoints = base.upgradePoints - cost
|
base.upgradePoints = base.upgradePoints - cost
|
||||||
end
|
end
|
||||||
pos = pos + slice
|
pos = pos + slice
|
||||||
|
@@ -1,21 +0,0 @@
|
|||||||
local nocturnalUtils = {}
|
|
||||||
|
|
||||||
-- imports
|
|
||||||
|
|
||||||
local constants = require("Constants")
|
|
||||||
|
|
||||||
-- constants
|
|
||||||
|
|
||||||
local AI_STATE_NOCTURNAL = constants.AI_STATE_NOCTURNAL
|
|
||||||
|
|
||||||
-- module code
|
|
||||||
|
|
||||||
function nocturnalUtils.isDark(surface)
|
|
||||||
return surface.darkness > 0.65
|
|
||||||
end
|
|
||||||
|
|
||||||
function nocturnalUtils.canAttack(natives, surface)
|
|
||||||
return nocturnalUtils.isDark(surface) and natives.state == AI_STATE_NOCTURNAL
|
|
||||||
end
|
|
||||||
|
|
||||||
return nocturnalUtils
|
|
@@ -4,6 +4,7 @@ local pheromoneUtils = {}
|
|||||||
|
|
||||||
local mapUtils = require("MapUtils")
|
local mapUtils = require("MapUtils")
|
||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
|
local chunkUtils = require("ChunkUtils")
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
|
|
||||||
@@ -14,9 +15,6 @@ local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE
|
|||||||
|
|
||||||
local BUILDING_PHEROMONES = constants.BUILDING_PHEROMONES
|
local BUILDING_PHEROMONES = constants.BUILDING_PHEROMONES
|
||||||
|
|
||||||
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
|
|
||||||
local RESOURCE_GENERATOR = constants.RESOURCE_GENERATOR
|
|
||||||
|
|
||||||
local PLAYER_PHEROMONE_GENERATOR_AMOUNT = constants.PLAYER_PHEROMONE_GENERATOR_AMOUNT
|
local PLAYER_PHEROMONE_GENERATOR_AMOUNT = constants.PLAYER_PHEROMONE_GENERATOR_AMOUNT
|
||||||
local DEATH_PHEROMONE_GENERATOR_AMOUNT = constants.DEATH_PHEROMONE_GENERATOR_AMOUNT
|
local DEATH_PHEROMONE_GENERATOR_AMOUNT = constants.DEATH_PHEROMONE_GENERATOR_AMOUNT
|
||||||
|
|
||||||
@@ -25,63 +23,45 @@ local BASE_PHEROMONE_PERSISTANCE = constants.BASE_PHEROMONE_PERSISTANCE
|
|||||||
local PLAYER_PHEROMONE_PERSISTANCE = constants.PLAYER_PHEROMONE_PERSISTANCE
|
local PLAYER_PHEROMONE_PERSISTANCE = constants.PLAYER_PHEROMONE_PERSISTANCE
|
||||||
local RESOURCE_PHEROMONE_PERSISTANCE = constants.RESOURCE_PHEROMONE_PERSISTANCE
|
local RESOURCE_PHEROMONE_PERSISTANCE = constants.RESOURCE_PHEROMONE_PERSISTANCE
|
||||||
|
|
||||||
local CHUNK_IMPASSABLE = constants.CHUNK_IMPASSABLE
|
|
||||||
|
|
||||||
local PASSABLE = constants.PASSABLE
|
|
||||||
|
|
||||||
local NEST_COUNT = constants.NEST_COUNT
|
|
||||||
|
|
||||||
local PATH_RATING = constants.PATH_RATING
|
local PATH_RATING = constants.PATH_RATING
|
||||||
|
|
||||||
local IMPASSABLE_TERRAIN_GENERATOR_AMOUNT = constants.IMPASSABLE_TERRAIN_GENERATOR_AMOUNT
|
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
local getCardinalChunks = mapUtils.getCardinalChunks
|
local getCardinalChunks = mapUtils.getCardinalChunks
|
||||||
|
|
||||||
local mMax = math.max
|
local mMax = math.max
|
||||||
|
local getNestCount = chunkUtils.getNestCount
|
||||||
|
local getWormCount = chunkUtils.getWormCount
|
||||||
|
local getPlayerBaseGenerator = chunkUtils.getPlayerBaseGenerator
|
||||||
|
local getResourceGenerator = chunkUtils.getResourceGenerator
|
||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
|
|
||||||
function pheromoneUtils.scents(chunk)
|
function pheromoneUtils.scents(regionMap, chunk)
|
||||||
|
chunk[BASE_PHEROMONE] = chunk[BASE_PHEROMONE] + getPlayerBaseGenerator(regionMap, chunk)
|
||||||
if (chunk[PASSABLE] == CHUNK_IMPASSABLE) then
|
local resourceGenerator = getResourceGenerator(regionMap, chunk)
|
||||||
chunk[BASE_PHEROMONE] = IMPASSABLE_TERRAIN_GENERATOR_AMOUNT;
|
if (resourceGenerator > 0) and (getNestCount(regionMap, chunk) == 0) and (getWormCount(regionMap, chunk) == 0) then
|
||||||
else
|
chunk[RESOURCE_PHEROMONE] = chunk[RESOURCE_PHEROMONE] + mMax(resourceGenerator * 100, 90)
|
||||||
chunk[BASE_PHEROMONE] = chunk[BASE_PHEROMONE] + chunk[PLAYER_BASE_GENERATOR]
|
|
||||||
local resourceGenerator = chunk[RESOURCE_GENERATOR]
|
|
||||||
if (resourceGenerator > 0) and (chunk[NEST_COUNT] == 0) then
|
|
||||||
chunk[RESOURCE_PHEROMONE] = chunk[RESOURCE_PHEROMONE] + mMax(resourceGenerator * 100, 90)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function pheromoneUtils.victoryScent(chunk, entityType)
|
function pheromoneUtils.victoryScent(chunk, entityType)
|
||||||
local value = BUILDING_PHEROMONES[entityType]
|
local value = BUILDING_PHEROMONES[entityType]
|
||||||
if value and (chunk[PASSABLE] ~= CHUNK_IMPASSABLE) then
|
if value then
|
||||||
chunk[MOVEMENT_PHEROMONE] = chunk[MOVEMENT_PHEROMONE] + (value * 100000)
|
chunk[MOVEMENT_PHEROMONE] = chunk[MOVEMENT_PHEROMONE] + (value * 100000)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function pheromoneUtils.deathScent(chunk)
|
function pheromoneUtils.deathScent(chunk)
|
||||||
if (chunk[PASSABLE] ~= CHUNK_IMPASSABLE) then
|
chunk[MOVEMENT_PHEROMONE] = chunk[MOVEMENT_PHEROMONE] - DEATH_PHEROMONE_GENERATOR_AMOUNT
|
||||||
chunk[MOVEMENT_PHEROMONE] = chunk[MOVEMENT_PHEROMONE] - DEATH_PHEROMONE_GENERATOR_AMOUNT
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function pheromoneUtils.playerScent(playerChunk)
|
function pheromoneUtils.playerScent(playerChunk)
|
||||||
if (playerChunk[PASSABLE] ~= CHUNK_IMPASSABLE) then
|
playerChunk[PLAYER_PHEROMONE] = playerChunk[PLAYER_PHEROMONE] + PLAYER_PHEROMONE_GENERATOR_AMOUNT
|
||||||
playerChunk[PLAYER_PHEROMONE] = playerChunk[PLAYER_PHEROMONE] + PLAYER_PHEROMONE_GENERATOR_AMOUNT
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function pheromoneUtils.processPheromone(regionMap, chunk)
|
function pheromoneUtils.processPheromone(regionMap, chunk)
|
||||||
|
|
||||||
if (chunk[PASSABLE] == CHUNK_IMPASSABLE) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local chunkMovement = chunk[MOVEMENT_PHEROMONE]
|
local chunkMovement = chunk[MOVEMENT_PHEROMONE]
|
||||||
local chunkBase = chunk[BASE_PHEROMONE]
|
local chunkBase = chunk[BASE_PHEROMONE]
|
||||||
local chunkPlayer = chunk[PLAYER_PHEROMONE]
|
local chunkPlayer = chunk[PLAYER_PHEROMONE]
|
||||||
@@ -93,17 +73,31 @@ function pheromoneUtils.processPheromone(regionMap, chunk)
|
|||||||
local totalPlayer = 0
|
local totalPlayer = 0
|
||||||
local totalResource = 0
|
local totalResource = 0
|
||||||
|
|
||||||
local tempNeighbors = getCardinalChunks(regionMap, chunk.cX, chunk.cY)
|
local tempNeighbors = getCardinalChunks(regionMap, chunk.x, chunk.y)
|
||||||
|
|
||||||
for i=1,4 do
|
local neighborChunk = tempNeighbors[1]
|
||||||
local neighborChunk = tempNeighbors[i]
|
totalMovement = totalMovement + (neighborChunk[MOVEMENT_PHEROMONE] - chunkMovement)
|
||||||
if neighborChunk then
|
totalBase = totalBase + (neighborChunk[BASE_PHEROMONE] - chunkBase)
|
||||||
totalMovement = totalMovement + (neighborChunk[MOVEMENT_PHEROMONE] - chunkMovement)
|
totalPlayer = totalPlayer + (neighborChunk[PLAYER_PHEROMONE] - chunkPlayer)
|
||||||
totalBase = totalBase + (neighborChunk[BASE_PHEROMONE] - chunkBase)
|
totalResource = totalResource + (neighborChunk[RESOURCE_PHEROMONE] - chunkResource)
|
||||||
totalPlayer = totalPlayer + (neighborChunk[PLAYER_PHEROMONE] - chunkPlayer)
|
|
||||||
totalResource = totalResource + (neighborChunk[RESOURCE_PHEROMONE] - chunkResource)
|
neighborChunk = tempNeighbors[2]
|
||||||
end
|
totalMovement = totalMovement + (neighborChunk[MOVEMENT_PHEROMONE] - chunkMovement)
|
||||||
end
|
totalBase = totalBase + (neighborChunk[BASE_PHEROMONE] - chunkBase)
|
||||||
|
totalPlayer = totalPlayer + (neighborChunk[PLAYER_PHEROMONE] - chunkPlayer)
|
||||||
|
totalResource = totalResource + (neighborChunk[RESOURCE_PHEROMONE] - chunkResource)
|
||||||
|
|
||||||
|
neighborChunk = tempNeighbors[3]
|
||||||
|
totalMovement = totalMovement + (neighborChunk[MOVEMENT_PHEROMONE] - chunkMovement)
|
||||||
|
totalBase = totalBase + (neighborChunk[BASE_PHEROMONE] - chunkBase)
|
||||||
|
totalPlayer = totalPlayer + (neighborChunk[PLAYER_PHEROMONE] - chunkPlayer)
|
||||||
|
totalResource = totalResource + (neighborChunk[RESOURCE_PHEROMONE] - chunkResource)
|
||||||
|
|
||||||
|
neighborChunk = tempNeighbors[4]
|
||||||
|
totalMovement = totalMovement + (neighborChunk[MOVEMENT_PHEROMONE] - chunkMovement)
|
||||||
|
totalBase = totalBase + (neighborChunk[BASE_PHEROMONE] - chunkBase)
|
||||||
|
totalPlayer = totalPlayer + (neighborChunk[PLAYER_PHEROMONE] - chunkPlayer)
|
||||||
|
totalResource = totalResource + (neighborChunk[RESOURCE_PHEROMONE] - chunkResource)
|
||||||
|
|
||||||
chunk[MOVEMENT_PHEROMONE] = (chunkMovement + (0.125 * totalMovement)) * MOVEMENT_PHEROMONE_PERSISTANCE * chunkPathRating
|
chunk[MOVEMENT_PHEROMONE] = (chunkMovement + (0.125 * totalMovement)) * MOVEMENT_PHEROMONE_PERSISTANCE * chunkPathRating
|
||||||
chunk[BASE_PHEROMONE] = (chunkBase + (0.25 * totalBase)) * BASE_PHEROMONE_PERSISTANCE * chunkPathRating
|
chunk[BASE_PHEROMONE] = (chunkBase + (0.25 * totalBase)) * BASE_PHEROMONE_PERSISTANCE * chunkPathRating
|
||||||
|
@@ -25,24 +25,4 @@ function playerUtils.playersWithinProximityToPosition(players, position, distanc
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function playerUtils.getPlayerInventory(player, withChar, withoutChar)
|
|
||||||
local inventory = nil
|
|
||||||
if player and player.valid and player.connected then
|
|
||||||
if player.character and player.character.valid then
|
|
||||||
inventory = player.character.get_inventory(withChar)
|
|
||||||
else
|
|
||||||
inventory = player.get_inventory(withoutChar)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return inventory
|
|
||||||
end
|
|
||||||
|
|
||||||
function playerUtils.getPlayerCursorStack(player)
|
|
||||||
local result = nil
|
|
||||||
if player and player.valid then
|
|
||||||
result = player.cursor_stack
|
|
||||||
end
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
return playerUtils
|
return playerUtils
|
||||||
|
@@ -6,9 +6,9 @@ local constants = require("Constants")
|
|||||||
local mapUtils = require("MapUtils")
|
local mapUtils = require("MapUtils")
|
||||||
local unitGroupUtils = require("UnitGroupUtils")
|
local unitGroupUtils = require("UnitGroupUtils")
|
||||||
local playerUtils = require("PlayerUtils")
|
local playerUtils = require("PlayerUtils")
|
||||||
local neighborUtils = require("NeighborUtils")
|
|
||||||
local movementUtils = require("MovementUtils")
|
local movementUtils = require("MovementUtils")
|
||||||
local mathUtils = require("MathUtils")
|
local mathUtils = require("MathUtils")
|
||||||
|
local chunkUtils = require("ChunkUtils")
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ local BASE_PHEROMONE = constants.BASE_PHEROMONE
|
|||||||
local SQUAD_RAIDING = constants.SQUAD_RAIDING
|
local SQUAD_RAIDING = constants.SQUAD_RAIDING
|
||||||
local SQUAD_GUARDING = constants.SQUAD_GUARDING
|
local SQUAD_GUARDING = constants.SQUAD_GUARDING
|
||||||
|
|
||||||
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
|
local CHUNK_SIZE = constants.CHUNK_SIZE
|
||||||
|
|
||||||
local PLAYER_PHEROMONE_MULTIPLER = constants.PLAYER_PHEROMONE_MULTIPLER
|
local PLAYER_PHEROMONE_MULTIPLER = constants.PLAYER_PHEROMONE_MULTIPLER
|
||||||
|
|
||||||
@@ -32,6 +32,8 @@ local DEFINES_GROUP_ATTACKING_TARGET = defines.group_state.attacking_target
|
|||||||
local DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
|
local DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
|
||||||
local DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
|
local DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
|
||||||
|
|
||||||
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
local mRandom = math.random
|
local mRandom = math.random
|
||||||
@@ -48,14 +50,17 @@ local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
|
|||||||
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
|
local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
|
||||||
|
|
||||||
local playersWithinProximityToPosition = playerUtils.playersWithinProximityToPosition
|
local playersWithinProximityToPosition = playerUtils.playersWithinProximityToPosition
|
||||||
|
local getPlayerBaseGenerator = chunkUtils.getPlayerBaseGenerator
|
||||||
|
|
||||||
local scoreNeighborsForAttack = neighborUtils.scoreNeighborsForAttack
|
local positionToChunkXY = mapUtils.positionToChunkXY
|
||||||
|
|
||||||
|
local scoreNeighborsForAttack = movementUtils.scoreNeighborsForAttack
|
||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
|
|
||||||
local function scoreAttackLocation(squad, neighborChunk)
|
local function scoreAttackLocation(squad, neighborChunk)
|
||||||
local damage = (2*neighborChunk[MOVEMENT_PHEROMONE]) + neighborChunk[BASE_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
local damage = (2*neighborChunk[MOVEMENT_PHEROMONE]) + neighborChunk[BASE_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
|
||||||
return damage - lookupMovementPenalty(squad, neighborChunk.cX, neighborChunk.cY)
|
return damage - lookupMovementPenalty(squad, neighborChunk.x, neighborChunk.y)
|
||||||
end
|
end
|
||||||
|
|
||||||
function squadAttack.squadsAttack(regionMap, surface, natives)
|
function squadAttack.squadsAttack(regionMap, surface, natives)
|
||||||
@@ -67,7 +72,7 @@ function squadAttack.squadsAttack(regionMap, surface, natives)
|
|||||||
attackPosition = regionMap.position
|
attackPosition = regionMap.position
|
||||||
attackCmd = { type = DEFINES_COMMAND_ATTACK_AREA,
|
attackCmd = { type = DEFINES_COMMAND_ATTACK_AREA,
|
||||||
destination = attackPosition,
|
destination = attackPosition,
|
||||||
radius = 32,
|
radius = CHUNK_SIZE,
|
||||||
distraction = DEFINES_DISTRACTION_BY_ENEMY }
|
distraction = DEFINES_DISTRACTION_BY_ENEMY }
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -78,18 +83,17 @@ function squadAttack.squadsAttack(regionMap, surface, natives)
|
|||||||
local groupState = group.state
|
local groupState = group.state
|
||||||
if (groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING) or ((groupState == DEFINES_GROUP_MOVING) and (squad.cycles == 0)) then
|
if (groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING) or ((groupState == DEFINES_GROUP_MOVING) and (squad.cycles == 0)) then
|
||||||
local groupPosition = group.position
|
local groupPosition = group.position
|
||||||
local chunk = getChunkByPosition(regionMap, groupPosition.x, groupPosition.y)
|
local chunkX, chunkY = positionToChunkXY(groupPosition)
|
||||||
if chunk then
|
local chunk = getChunkByPosition(regionMap, chunkX, chunkY)
|
||||||
|
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
local attackChunk, attackDirection = scoreNeighborsForAttack(chunk,
|
local attackChunk, attackDirection = scoreNeighborsForAttack(chunk,
|
||||||
getNeighborChunks(regionMap,
|
getNeighborChunks(regionMap, chunkX, chunkY),
|
||||||
chunk.cX,
|
|
||||||
chunk.cY),
|
|
||||||
scoreAttackLocation,
|
scoreAttackLocation,
|
||||||
squad)
|
squad)
|
||||||
addMovementPenalty(natives, squad, chunk.cX, chunk.cY)
|
addMovementPenalty(natives, squad, chunkX, chunkY)
|
||||||
if group.valid and attackChunk then
|
if group.valid and (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
if (attackChunk[PLAYER_BASE_GENERATOR] == 0) or
|
local playerBaseGenerator = getPlayerBaseGenerator(regionMap, attackChunk)
|
||||||
((groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING)) then
|
if (playerBaseGenerator == 0) or ((groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING)) then
|
||||||
|
|
||||||
squad.cycles = ((#squad.group.members > 80) and 6) or 4
|
squad.cycles = ((#squad.group.members > 80) and 6) or 4
|
||||||
|
|
||||||
@@ -102,22 +106,18 @@ function squadAttack.squadsAttack(regionMap, surface, natives)
|
|||||||
attackCmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
|
attackCmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
|
||||||
end
|
end
|
||||||
|
|
||||||
local position = findMovementPosition(surface,
|
local position = findMovementPosition(surface, positionFromDirectionAndChunk(attackDirection, groupPosition, attackPosition, 1.35))
|
||||||
positionFromDirectionAndChunk(attackDirection,
|
|
||||||
groupPosition,
|
|
||||||
attackPosition,
|
|
||||||
1.35))
|
|
||||||
if position then
|
if position then
|
||||||
attackPosition.x = position.x
|
attackPosition.x = position.x
|
||||||
attackPosition.y = position.y
|
attackPosition.y = position.y
|
||||||
group.set_command(attackCmd)
|
group.set_command(attackCmd)
|
||||||
group.start_moving()
|
group.start_moving()
|
||||||
else
|
else
|
||||||
addMovementPenalty(natives, squad, attackChunk.cX, attackChunk.cY)
|
addMovementPenalty(natives, squad, attackChunk.x, attackChunk.y)
|
||||||
end
|
end
|
||||||
elseif not squad.frenzy and not squad.rabid and
|
elseif not squad.frenzy and not squad.rabid and
|
||||||
((groupState == DEFINES_GROUP_ATTACKING_DISTRACTION) or (groupState == DEFINES_GROUP_ATTACKING_TARGET) or
|
((groupState == DEFINES_GROUP_ATTACKING_DISTRACTION) or (groupState == DEFINES_GROUP_ATTACKING_TARGET) or
|
||||||
(attackChunk[PLAYER_BASE_GENERATOR] ~= 0)) then
|
(playerBaseGenerator ~= 0)) then
|
||||||
squad.frenzy = true
|
squad.frenzy = true
|
||||||
squad.frenzyPosition.x = groupPosition.x
|
squad.frenzyPosition.x = groupPosition.x
|
||||||
squad.frenzyPosition.y = groupPosition.y
|
squad.frenzyPosition.y = groupPosition.y
|
||||||
|
@@ -5,14 +5,13 @@ local aiDefense = {}
|
|||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
local mapUtils = require("MapUtils")
|
local mapUtils = require("MapUtils")
|
||||||
local unitGroupUtils = require("UnitGroupUtils")
|
local unitGroupUtils = require("UnitGroupUtils")
|
||||||
local neighborUtils = require("NeighborUtils")
|
|
||||||
local movementUtils = require("MovementUtils")
|
local movementUtils = require("MovementUtils")
|
||||||
|
local chunkUtils = require("ChunkUtils")
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
|
|
||||||
local RETREAT_GRAB_RADIUS = constants.RETREAT_GRAB_RADIUS
|
local RETREAT_GRAB_RADIUS = constants.RETREAT_GRAB_RADIUS
|
||||||
|
|
||||||
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
|
|
||||||
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
||||||
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
|
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
|
||||||
local BASE_PHEROMONE = constants.BASE_PHEROMONE
|
local BASE_PHEROMONE = constants.BASE_PHEROMONE
|
||||||
@@ -23,12 +22,9 @@ local SQUAD_RETREATING = constants.SQUAD_RETREATING
|
|||||||
|
|
||||||
local RETREAT_FILTER = constants.RETREAT_FILTER
|
local RETREAT_FILTER = constants.RETREAT_FILTER
|
||||||
|
|
||||||
local RETREAT_TRIGGERED = constants.RETREAT_TRIGGERED
|
|
||||||
|
|
||||||
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
|
local INTERVAL_LOGIC = constants.INTERVAL_LOGIC
|
||||||
|
|
||||||
local NEST_COUNT = constants.NEST_COUNT
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
local WORM_COUNT = constants.WORM_COUNT
|
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
@@ -38,42 +34,43 @@ local findNearBySquad = unitGroupUtils.findNearBySquad
|
|||||||
local addMovementPenalty = movementUtils.addMovementPenalty
|
local addMovementPenalty = movementUtils.addMovementPenalty
|
||||||
local createSquad = unitGroupUtils.createSquad
|
local createSquad = unitGroupUtils.createSquad
|
||||||
local membersToSquad = unitGroupUtils.membersToSquad
|
local membersToSquad = unitGroupUtils.membersToSquad
|
||||||
local scoreNeighborsForRetreat = neighborUtils.scoreNeighborsForRetreat
|
local scoreNeighborsForRetreat = movementUtils.scoreNeighborsForRetreat
|
||||||
local findMovementPosition = movementUtils.findMovementPosition
|
local findMovementPosition = movementUtils.findMovementPosition
|
||||||
|
|
||||||
|
local getRetreatTick = chunkUtils.getRetreatTick
|
||||||
|
local getPlayerBaseGenerator = chunkUtils.getPlayerBaseGenerator
|
||||||
|
local setRetreatTick = chunkUtils.setRetreatTick
|
||||||
|
local getNestCount = chunkUtils.getNestCount
|
||||||
|
local getWormCount = chunkUtils.getWormCount
|
||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
|
|
||||||
local function scoreRetreatLocation(neighborChunk)
|
local function scoreRetreatLocation(regionMap, neighborChunk)
|
||||||
return -(neighborChunk[BASE_PHEROMONE] + -neighborChunk[MOVEMENT_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * 100) + (neighborChunk[PLAYER_BASE_GENERATOR] * 20))
|
return -(neighborChunk[BASE_PHEROMONE] + -neighborChunk[MOVEMENT_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * 100) + (getPlayerBaseGenerator(regionMap, neighborChunk) * 20))
|
||||||
end
|
end
|
||||||
|
|
||||||
function aiDefense.retreatUnits(chunk, position, squad, regionMap, surface, natives, tick)
|
function aiDefense.retreatUnits(chunk, position, squad, regionMap, surface, natives, tick)
|
||||||
if (tick - chunk[RETREAT_TRIGGERED] > INTERVAL_LOGIC) and (chunk[NEST_COUNT] == 0) and (chunk[WORM_COUNT] == 0) then
|
if (tick - getRetreatTick(regionMap, chunk) > INTERVAL_LOGIC) and (getNestCount(regionMap, chunk) == 0) and (getWormCount(regionMap, chunk) == 0) then
|
||||||
local performRetreat = false
|
local performRetreat = false
|
||||||
local enemiesToSquad = nil
|
local enemiesToSquad = nil
|
||||||
|
|
||||||
if not squad then
|
if not squad then
|
||||||
enemiesToSquad = surface.find_enemy_units(chunk, RETREAT_GRAB_RADIUS)
|
enemiesToSquad = surface.find_enemy_units(position, RETREAT_GRAB_RADIUS)
|
||||||
performRetreat = #enemiesToSquad > 0
|
performRetreat = #enemiesToSquad > 0
|
||||||
elseif squad.group.valid and (squad.status ~= SQUAD_RETREATING) and not squad.kamikaze then
|
elseif squad.group.valid and (squad.status ~= SQUAD_RETREATING) and not squad.kamikaze then
|
||||||
performRetreat = #squad.group.members > 1
|
performRetreat = #squad.group.members > 1
|
||||||
end
|
end
|
||||||
|
|
||||||
if performRetreat then
|
if performRetreat then
|
||||||
chunk[RETREAT_TRIGGERED] = tick
|
setRetreatTick(regionMap, chunk, tick)
|
||||||
local exitPath,exitDirection = scoreNeighborsForRetreat(chunk,
|
local exitPath,exitDirection = scoreNeighborsForRetreat(chunk,
|
||||||
getNeighborChunks(regionMap,
|
getNeighborChunks(regionMap, chunk.x, chunk.y),
|
||||||
chunk.cX,
|
scoreRetreatLocation,
|
||||||
chunk.cY),
|
regionMap)
|
||||||
scoreRetreatLocation)
|
if (exitPath ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
if exitPath then
|
|
||||||
local retreatPosition = findMovementPosition(surface,
|
local retreatPosition = findMovementPosition(surface,
|
||||||
positionFromDirectionAndChunk(exitDirection,
|
positionFromDirectionAndChunk(exitDirection, position, regionMap.position, 0.98),
|
||||||
position,
|
|
||||||
regionMap.position,
|
|
||||||
0.98),
|
|
||||||
false)
|
false)
|
||||||
|
|
||||||
|
|
||||||
if not retreatPosition then
|
if not retreatPosition then
|
||||||
return
|
return
|
||||||
@@ -100,7 +97,7 @@ function aiDefense.retreatUnits(chunk, position, squad, regionMap, surface, nati
|
|||||||
newSquad.rabid = true
|
newSquad.rabid = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
addMovementPenalty(natives, newSquad, chunk.cX, chunk.cY)
|
addMovementPenalty(natives, newSquad, chunk.x, chunk.y)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@@ -4,24 +4,18 @@ local tendrilUtils = {}
|
|||||||
|
|
||||||
local constants = require("Constants")
|
local constants = require("Constants")
|
||||||
local mapUtils = require("MapUtils")
|
local mapUtils = require("MapUtils")
|
||||||
local baseRegisterUtils = require("BaseRegisterUtils")
|
|
||||||
local neighborsUtils = require("NeighborUtils")
|
|
||||||
local mathUtils = require("MathUtils")
|
|
||||||
|
|
||||||
local nestUtils = require("NestUtils")
|
local nestUtils = require("NestUtils")
|
||||||
local mathUtils = require("MathUtils")
|
local movementUtils = require("MovementUtils")
|
||||||
|
|
||||||
-- constants
|
-- constants
|
||||||
|
|
||||||
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE
|
local RESOURCE_PHEROMONE = constants.RESOURCE_PHEROMONE
|
||||||
|
|
||||||
local RESOURCE_GENERATOR = constants.RESOURCE_GENERATOR
|
local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
|
||||||
|
|
||||||
local NEST_COUNT = constants.NEST_COUNT
|
|
||||||
|
|
||||||
-- imported functions
|
-- imported functions
|
||||||
|
|
||||||
local scoreNeighborsForResource = neighborsUtils.scoreNeighborsForResource
|
local scoreNeighborsForResource = movementUtils.scoreNeighborsForResource
|
||||||
|
|
||||||
local getNeighborChunks = mapUtils.getNeighborChunks
|
local getNeighborChunks = mapUtils.getNeighborChunks
|
||||||
|
|
||||||
@@ -74,11 +68,9 @@ local function buildTendrilPath(regionMap, tendril, surface, base, tick, natives
|
|||||||
end
|
end
|
||||||
local tendrilPosition = tendrilUnit.position
|
local tendrilPosition = tendrilUnit.position
|
||||||
local chunk = getChunkByPosition(regionMap, tendrilPosition.x, tendrilPosition.y)
|
local chunk = getChunkByPosition(regionMap, tendrilPosition.x, tendrilPosition.y)
|
||||||
if chunk then
|
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
|
||||||
local tendrilPath,tendrilDirection = scoreNeighborsForResource(chunk,
|
local tendrilPath,tendrilDirection = scoreNeighborsForResource(chunk,
|
||||||
getNeighborChunks(regionMap,
|
getNeighborChunks(regionMap, chunk.x, chunk.y),
|
||||||
chunk.cX,
|
|
||||||
chunk.cY),
|
|
||||||
scoreTendrilChunk,
|
scoreTendrilChunk,
|
||||||
nil)
|
nil)
|
||||||
if (tendrilDirection == -1) then
|
if (tendrilDirection == -1) then
|
||||||
|
@@ -1,83 +0,0 @@
|
|||||||
local worldProcessor = {}
|
|
||||||
|
|
||||||
-- imports
|
|
||||||
|
|
||||||
local constants = require("Constants")
|
|
||||||
|
|
||||||
-- constants
|
|
||||||
|
|
||||||
local ITEM_COLLECTOR_DISTANCE = constants.ITEM_COLLECTOR_DISTANCE
|
|
||||||
|
|
||||||
local ITEM_COLLECTOR_QUEUE_SIZE = constants.ITEM_COLLECTOR_QUEUE_SIZE
|
|
||||||
|
|
||||||
-- imported functions
|
|
||||||
|
|
||||||
-- module code
|
|
||||||
|
|
||||||
function worldProcessor.processWorld(surface, world, tick)
|
|
||||||
local collectors = world.itemCollectorEvents
|
|
||||||
if (#collectors > 0) then
|
|
||||||
local collectorLookup = world.itemCollectorLookup
|
|
||||||
|
|
||||||
local inserter = {name="", count=0}
|
|
||||||
local topLeftPosition = {x = 0, y = 0}
|
|
||||||
local bottomRightPosition = {x = 0, y = 0}
|
|
||||||
local boundingArea = {topLeftPosition,
|
|
||||||
bottomRightPosition}
|
|
||||||
|
|
||||||
local count = 0
|
|
||||||
for index = #collectors, 1, -1 do
|
|
||||||
count = count + 1
|
|
||||||
local itemCollectorPair = collectorLookup[collectors[index]]
|
|
||||||
collectors[index] = nil
|
|
||||||
|
|
||||||
if itemCollectorPair then
|
|
||||||
local chest = itemCollectorPair[1]
|
|
||||||
local dish = itemCollectorPair[2]
|
|
||||||
|
|
||||||
if chest.valid and dish.valid then
|
|
||||||
|
|
||||||
local collectorPosition = dish.position
|
|
||||||
|
|
||||||
topLeftPosition.x = collectorPosition.x - ITEM_COLLECTOR_DISTANCE
|
|
||||||
topLeftPosition.y = collectorPosition.y - ITEM_COLLECTOR_DISTANCE
|
|
||||||
|
|
||||||
bottomRightPosition.x = collectorPosition.x + ITEM_COLLECTOR_DISTANCE
|
|
||||||
bottomRightPosition.y = collectorPosition.y + ITEM_COLLECTOR_DISTANCE
|
|
||||||
|
|
||||||
local items = surface.find_entities_filtered({area = boundingArea,
|
|
||||||
name = "item-on-ground"})
|
|
||||||
|
|
||||||
local counts = {}
|
|
||||||
if (#items > 0) then
|
|
||||||
for x=1,#items do
|
|
||||||
local item = items[x]
|
|
||||||
local itemName = item.stack.name
|
|
||||||
if not counts[itemName] then
|
|
||||||
counts[itemName] = {item}
|
|
||||||
else
|
|
||||||
counts[itemName][#counts[itemName]+1] = item
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for k,a in pairs(counts) do
|
|
||||||
inserter.name = k
|
|
||||||
inserter.count = #a
|
|
||||||
local stored = chest.insert(inserter)
|
|
||||||
for i=1,stored do
|
|
||||||
a[i].destroy()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- dish.surface.create_entity({name="item-collector-base-particle-rampant",
|
|
||||||
-- position=dish.position})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if (count >= ITEM_COLLECTOR_QUEUE_SIZE) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
return worldProcessor
|
|
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
[entity-name]
|
[entity-name]
|
||||||
tunnel-entrance=Tunnel Entrance
|
tunnel-entrance-rampant=Tunnel Entrance
|
||||||
|
|
||||||
small-suicide-biter=Small Suicide Biter
|
small-suicide-biter=Small Suicide Biter
|
||||||
medium-suicide-biter=Medium Suicide Biter
|
medium-suicide-biter=Medium Suicide Biter
|
||||||
@@ -9,7 +9,7 @@ behemoth-suicide-biter=Behemoth Suicide Biter
|
|||||||
|
|
||||||
small-fire-spitter=Small Fire Spitter
|
small-fire-spitter=Small Fire Spitter
|
||||||
|
|
||||||
biter-spawner-hive=Small Hive
|
biter-spawner-hive-rampant=Small Hive
|
||||||
|
|
||||||
small-tendril-biter-rampant=Small Tendril
|
small-tendril-biter-rampant=Small Tendril
|
||||||
item-collector-base-rampant=Item Collector
|
item-collector-base-rampant=Item Collector
|
||||||
@@ -32,7 +32,7 @@ short-range-electrodynamics-1-rampant=Short-range Electrodynamics
|
|||||||
short-range-electrodynamics-1-rampant=Buildings that generate strong electromagnetic fields
|
short-range-electrodynamics-1-rampant=Buildings that generate strong electromagnetic fields
|
||||||
|
|
||||||
[entity-description]
|
[entity-description]
|
||||||
tunnel-entrance=This tunnel is used by the biters to bypass player defenses. Fill the hole using landfill.
|
tunnel-entrance-rampant=This tunnel is used by the biters to bypass player defenses. Fill the hole using landfill.
|
||||||
|
|
||||||
small-suicide-biter=These biters will explode at close range
|
small-suicide-biter=These biters will explode at close range
|
||||||
medium-suicide-biter=These biters will explode at close range
|
medium-suicide-biter=These biters will explode at close range
|
||||||
@@ -41,7 +41,7 @@ behemoth-suicide-biter=These biters will explode at close range
|
|||||||
|
|
||||||
small-fire-spitter=These biters will spit fire
|
small-fire-spitter=These biters will spit fire
|
||||||
|
|
||||||
biter-spawner-hive=Small Hive
|
biter-spawner-hive-rampant=Small Hive
|
||||||
|
|
||||||
small-tendril-biter-rampant=Small Tendril
|
small-tendril-biter-rampant=Small Tendril
|
||||||
item-collector-base-rampant=Scans the surrounding area for items on the ground, if any items are found they are pulled into the storage chest when the sector is finished scanning.
|
item-collector-base-rampant=Scans the surrounding area for items on the ground, if any items are found they are pulled into the storage chest when the sector is finished scanning.
|
||||||
|
6
make.rkt
6
make.rkt
@@ -36,6 +36,7 @@
|
|||||||
(string->path "README.md")
|
(string->path "README.md")
|
||||||
(string->path "NOTICE")
|
(string->path "NOTICE")
|
||||||
(string->path "libs")
|
(string->path "libs")
|
||||||
|
(string->path "sounds")
|
||||||
(string->path "locale")
|
(string->path "locale")
|
||||||
(string->path "graphics")
|
(string->path "graphics")
|
||||||
(string->path "prototypes")))
|
(string->path "prototypes")))
|
||||||
@@ -72,12 +73,13 @@
|
|||||||
(copyFile "tests.lua" modFolder)
|
(copyFile "tests.lua" modFolder)
|
||||||
(copyDirectory "libs" modFolder)
|
(copyDirectory "libs" modFolder)
|
||||||
(copyDirectory "locale" modFolder)
|
(copyDirectory "locale" modFolder)
|
||||||
|
(copyDirectory "sounds" modFolder)
|
||||||
(copyDirectory "graphics" modFolder)
|
(copyDirectory "graphics" modFolder)
|
||||||
(copyDirectory "prototypes" modFolder)))
|
(copyDirectory "prototypes" modFolder)))
|
||||||
|
|
||||||
(define (run)
|
(define (run)
|
||||||
;;(copyFiles modFolder)
|
(copyFiles modFolder)
|
||||||
;;(copyFiles zipModFolder)
|
;;(copyFiles zipModFolder)
|
||||||
(makeZip modFolder)
|
;;(makeZip modFolder)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@@ -1,197 +0,0 @@
|
|||||||
-- overlays
|
|
||||||
|
|
||||||
local radar = util.table.deepcopy(data.raw["radar"]["radar"])
|
|
||||||
radar.name = "item-collector-base-rampant"
|
|
||||||
radar.icon = "__Rampant__/graphics/icon/itemCollectorIcon.png"
|
|
||||||
radar.collision_box = {{-0.35, -0.35}, {0.35, 0.35}}
|
|
||||||
radar.selection_box = {{-0.485, -0.7}, {0.465, -0.1}}
|
|
||||||
radar.energy_per_sector = "27MJ"
|
|
||||||
radar.max_distance_of_nearby_sector_revealed = 1
|
|
||||||
radar.max_distance_of_sector_revealed = 0
|
|
||||||
radar.energy_per_nearby_scan = "27MJ"
|
|
||||||
radar.energy_usage = "450KW"
|
|
||||||
radar.flags[#radar.flags+1] = "not-deconstructable"
|
|
||||||
radar.pictures = {
|
|
||||||
filename = "__Rampant__/graphics/entities/chest/itemCollector.png",
|
|
||||||
priority = "low",
|
|
||||||
width = 46,
|
|
||||||
height = 49,
|
|
||||||
apply_projection = false,
|
|
||||||
direction_count = 64,
|
|
||||||
line_length = 8,
|
|
||||||
shift = {0.1875, -0.24}
|
|
||||||
}
|
|
||||||
radar.minable = nil
|
|
||||||
|
|
||||||
-- local particle = {
|
|
||||||
-- type = "explosion",
|
|
||||||
-- name = "item-collector-base-particle-rampant",
|
|
||||||
-- flags = {"not-on-map"},
|
|
||||||
-- animations =
|
|
||||||
-- {
|
|
||||||
-- {
|
|
||||||
-- filename = "__Rampant__/graphics/entities/chest/itemCollectorParticle.png",
|
|
||||||
-- priority = "extra-high",
|
|
||||||
-- width = 46,
|
|
||||||
-- height = 49,
|
|
||||||
-- frame_count = 16,
|
|
||||||
-- line_length = 8,
|
|
||||||
-- animation_speed = 0.2
|
|
||||||
-- }
|
|
||||||
-- },
|
|
||||||
-- light = {intensity = 1, size = 20, color = {r=1.0, g=1.0, b=1.0}},
|
|
||||||
-- smoke = "smoke-fast",
|
|
||||||
-- smoke_count = 0,
|
|
||||||
-- smoke_slow_down_factor = 1,
|
|
||||||
-- sound =
|
|
||||||
-- {
|
|
||||||
-- aggregation =
|
|
||||||
-- {
|
|
||||||
-- max_count = 1,
|
|
||||||
-- remove = true
|
|
||||||
-- },
|
|
||||||
-- variations =
|
|
||||||
-- {
|
|
||||||
-- {
|
|
||||||
-- filename = "__base__/sound/fight/small-explosion-1.ogg",
|
|
||||||
-- volume = 0.75
|
|
||||||
-- }
|
|
||||||
-- }
|
|
||||||
-- }
|
|
||||||
-- }
|
|
||||||
|
|
||||||
local radarOverlay = util.table.deepcopy(radar)
|
|
||||||
radarOverlay.name = "item-collector-base-overlay-rampant"
|
|
||||||
radarOverlay.pictures.filename = "__Rampant__/graphics/entities/chest/itemCollectorOverlay2.png"
|
|
||||||
radarOverlay.pictures.width = 2048
|
|
||||||
radarOverlay.pictures.height = 2048
|
|
||||||
radarOverlay.pictures.direction_count = 1
|
|
||||||
radarOverlay.pictures.line_length = 1
|
|
||||||
radarOverlay.pictures.shift[2] = 0.07
|
|
||||||
radarOverlay.pictures.hr_version = {
|
|
||||||
filename = "__Rampant__/graphics/entities/chest/itemCollectorOverlay2.5.png",
|
|
||||||
priority = "low",
|
|
||||||
width = 3200,
|
|
||||||
height = 3200,
|
|
||||||
apply_projection = false,
|
|
||||||
direction_count = 1,
|
|
||||||
line_length = 1,
|
|
||||||
shift = {0.1875, -0.24}
|
|
||||||
}
|
|
||||||
|
|
||||||
local chest = util.table.deepcopy(data.raw["container"]["steel-chest"])
|
|
||||||
chest.name = "item-collector-chest-rampant"
|
|
||||||
chest.picture = {
|
|
||||||
filename = "__core__/graphics/empty.png",
|
|
||||||
priority = "low",
|
|
||||||
width = 46,
|
|
||||||
height = 49,
|
|
||||||
line_length = 1,
|
|
||||||
shift = {0.1875, -0.2}
|
|
||||||
}
|
|
||||||
chest.selection_box = {{-0.485, -0.1}, {0.465, 0.6}}
|
|
||||||
chest.collision_mask = {}
|
|
||||||
chest.minable.result = "item-collector-base-rampant"
|
|
||||||
|
|
||||||
|
|
||||||
data:extend({
|
|
||||||
radar,
|
|
||||||
radarOverlay,
|
|
||||||
chest-- ,
|
|
||||||
-- particle
|
|
||||||
})
|
|
||||||
|
|
||||||
data:extend({
|
|
||||||
|
|
||||||
{
|
|
||||||
type = "recipe",
|
|
||||||
name = "item-collector-base-rampant",
|
|
||||||
normal = {
|
|
||||||
enabled = false,
|
|
||||||
energy_required = 10,
|
|
||||||
ingredients = {
|
|
||||||
{"steel-chest", 1},
|
|
||||||
{"accumulator", 1},
|
|
||||||
{"radar", 1}
|
|
||||||
},
|
|
||||||
result = "item-collector-base-rampant",
|
|
||||||
requester_paste_multiplier = 4
|
|
||||||
},
|
|
||||||
expensive = {
|
|
||||||
enabled = false,
|
|
||||||
energy_required = 10,
|
|
||||||
ingredients = {
|
|
||||||
{"steel-chest", 2},
|
|
||||||
{"accumulator", 2},
|
|
||||||
{"radar", 2}
|
|
||||||
},
|
|
||||||
result = "item-collector-base-rampant",
|
|
||||||
requester_paste_multiplier = 4
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
type = "item",
|
|
||||||
name = "item-collector-base-rampant",
|
|
||||||
icon = "__Rampant__/graphics/icon/itemCollectorIcon.png",
|
|
||||||
flags = {"goes-to-quickbar"},
|
|
||||||
subgroup = "storage",
|
|
||||||
order = "a[items]-c[steel-collector]",
|
|
||||||
place_result = "item-collector-base-rampant",
|
|
||||||
stack_size = 50
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
type = "item",
|
|
||||||
name = "item-collector-base-overlay-rampant",
|
|
||||||
icon = "__Rampant__/graphics/icon/itemCollectorIcon.png",
|
|
||||||
flags = {"goes-to-quickbar"},
|
|
||||||
subgroup = "storage",
|
|
||||||
order = "a[items]-c[steel-collector]",
|
|
||||||
place_result = "item-collector-base-overlay-rampant",
|
|
||||||
stack_size = 50
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
type = "item",
|
|
||||||
name = "item-collector-chest-rampant",
|
|
||||||
icon = "__Rampant__/graphics/icon/itemCollectorIcon.png",
|
|
||||||
flags = {"goes-to-quickbar"},
|
|
||||||
subgroup = "storage",
|
|
||||||
order = "a[items]-c[steel-collector]",
|
|
||||||
place_result = "item-collector-chest-rampant",
|
|
||||||
stack_size = 50
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
-- technology insertions
|
|
||||||
|
|
||||||
data:extend({
|
|
||||||
{
|
|
||||||
type = "technology",
|
|
||||||
name = "short-range-electrodynamics-1-rampant",
|
|
||||||
icon = "__Rampant__/graphics/technology/itemCollectorTech.png",
|
|
||||||
icon_size = 128,
|
|
||||||
localised_name = {"technology-name.short-range-electrodynamics-1-rampant"},
|
|
||||||
effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "unlock-recipe",
|
|
||||||
recipe = "item-collector-base-rampant"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
prerequisites = {"electric-energy-accumulators-1"},
|
|
||||||
unit =
|
|
||||||
{
|
|
||||||
count = 200,
|
|
||||||
ingredients =
|
|
||||||
{
|
|
||||||
{"science-pack-1", 1},
|
|
||||||
{"science-pack-2", 1}
|
|
||||||
},
|
|
||||||
time = 22
|
|
||||||
},
|
|
||||||
order = "c-e-a",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
@@ -102,7 +102,7 @@ data:extend({
|
|||||||
|
|
||||||
{
|
{
|
||||||
type = "unit-spawner",
|
type = "unit-spawner",
|
||||||
name = "biter-spawner-hive",
|
name = "biter-spawner-hive-rampant",
|
||||||
icon = "__base__/graphics/icons/biter-spawner.png",
|
icon = "__base__/graphics/icons/biter-spawner.png",
|
||||||
flags = {"placeable-player", "placeable-enemy", "not-repairable"},
|
flags = {"placeable-player", "placeable-enemy", "not-repairable"},
|
||||||
max_health = 350,
|
max_health = 350,
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
data:extend({
|
data:extend({
|
||||||
{
|
{
|
||||||
type = "simple-entity",
|
type = "simple-entity",
|
||||||
name = "tunnel-entrance",
|
name = "tunnel-entrance-rampant",
|
||||||
flags = {"placeable-neutral", "placeable-off-grid", "not-on-map"},
|
flags = {"placeable-neutral", "placeable-off-grid", "not-on-map"},
|
||||||
icon = "__base__/graphics/icons/small-scorchmark.png",
|
icon = "__base__/graphics/icons/small-scorchmark.png",
|
||||||
subgroup = "grass",
|
subgroup = "grass",
|
||||||
|
@@ -10,278 +10,95 @@ local makeColor = colorUtils.makeColor
|
|||||||
|
|
||||||
-- dumb acid projectiles
|
-- dumb acid projectiles
|
||||||
|
|
||||||
makeStream({
|
local templateDamage = { amount = 4, type = "acid" }
|
||||||
name = "acid-ball",
|
local templateArea = {
|
||||||
particleTint = {r=0, g=1, b=1, a=0.5},
|
type = "area",
|
||||||
spineAnimationTint = {r=0, g=1, b=1, a=0.5},
|
perimeter = 1.2,
|
||||||
softSmokeTint = makeColor(0.3, 0.75, 0.3, 0.1),
|
action_delivery =
|
||||||
actions = {
|
{
|
||||||
{
|
{
|
||||||
type = "area",
|
type = "instant",
|
||||||
perimeter = 1.5,
|
target_effects =
|
||||||
action_delivery =
|
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
type = "instant",
|
type = "damage",
|
||||||
target_effects =
|
damage = templateDamage
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 15, type = "acid" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "direct",
|
|
||||||
action_delivery = {
|
|
||||||
type = "instant",
|
|
||||||
target_effects = {
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
|
local templateActions = {
|
||||||
|
templateArea,
|
||||||
|
{
|
||||||
|
type = "direct",
|
||||||
|
action_delivery = {
|
||||||
|
type = "instant",
|
||||||
|
target_effects = {
|
||||||
|
type= "create-entity",
|
||||||
|
entity_name = "acid-splash-purple"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
local template = {
|
||||||
|
name = "acid-ball",
|
||||||
|
particleTint = {r=0, g=1, b=1, a=0.5},
|
||||||
|
spineAnimationTint = {r=0, g=1, b=1, a=0.5},
|
||||||
|
softSmokeTint = makeColor(0.3, 0.75, 0.3, 0.1),
|
||||||
|
actions = templateActions
|
||||||
|
}
|
||||||
|
|
||||||
|
makeStream(template)
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
makeStream({
|
template.name = "acid-ball-1"
|
||||||
name = "acid-ball-1",
|
templateDamage.amount = 9
|
||||||
particleTint = {r=0, g=1, b=1, a=0.5},
|
templateArea.perimeter = 1.3
|
||||||
spineAnimationTint = {r=0, g=1, b=1, a=0.5},
|
makeStream(template)
|
||||||
softSmokeTint = makeColor(0.3, 0.75, 0.3, 0.1),
|
|
||||||
actions = {
|
|
||||||
{
|
|
||||||
type = "area",
|
|
||||||
perimeter = 1.5,
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 22, type = "acid" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "direct",
|
|
||||||
action_delivery = {
|
|
||||||
type = "instant",
|
|
||||||
target_effects = {
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
makeStream({
|
template.name = "acid-ball-2"
|
||||||
name = "acid-ball-2",
|
templateDamage.amount = 14
|
||||||
particleTint = {r=0, g=1, b=1, a=0.5},
|
templateArea.perimeter = 1.4
|
||||||
spineAnimationTint = {r=0, g=1, b=1, a=0.5},
|
makeStream(template)
|
||||||
softSmokeTint = makeColor(0.3, 0.75, 0.3, 0.1),
|
|
||||||
actions = {
|
|
||||||
{
|
|
||||||
type = "area",
|
|
||||||
perimeter = 1.5,
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 32, type = "acid" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "direct",
|
|
||||||
action_delivery = {
|
|
||||||
type = "instant",
|
|
||||||
target_effects = {
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
makeStream({
|
template.name = "acid-ball-3"
|
||||||
name = "acid-ball-3",
|
templateDamage.amount = 23
|
||||||
particleTint = {r=0, g=1, b=1, a=0.5},
|
templateArea.perimeter = 1.5
|
||||||
spineAnimationTint = {r=0, g=1, b=1, a=0.5},
|
makeStream(template)
|
||||||
softSmokeTint = makeColor(0.3, 0.75, 0.3, 0.1),
|
|
||||||
actions = {
|
|
||||||
{
|
|
||||||
type = "area",
|
|
||||||
perimeter = 1.5,
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 45, type = "acid" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "direct",
|
|
||||||
action_delivery = {
|
|
||||||
type = "instant",
|
|
||||||
target_effects = {
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
makeStream({
|
template.name = "wide-acid-ball"
|
||||||
name = "wide-acid-ball",
|
templateDamage.amount = 18
|
||||||
particleTint = {r=0, g=1, b=1, a=0.5},
|
templateArea.perimeter = 3
|
||||||
spineAnimationTint = {r=0, g=1, b=1, a=0.5},
|
makeStream(template)
|
||||||
softSmokeTint = makeColor(0.3, 0.75, 0.3, 0.1),
|
|
||||||
actions = {
|
|
||||||
{
|
|
||||||
type = "area",
|
|
||||||
perimeter = 3,
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 35, type = "acid" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "direct",
|
|
||||||
action_delivery = {
|
|
||||||
type = "instant",
|
|
||||||
target_effects = {
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
makeStream({
|
template.name = "acid-ball-4"
|
||||||
name = "acid-ball-4",
|
templateDamage.amount = 25
|
||||||
particleTint = {r=0, g=1, b=1, a=0.5},
|
templateArea.perimeter = 1.75
|
||||||
spineAnimationTint = {r=0, g=1, b=1, a=0.5},
|
makeStream(template)
|
||||||
softSmokeTint = makeColor(0.3, 0.75, 0.3, 0.1),
|
|
||||||
actions = {
|
|
||||||
{
|
|
||||||
type = "area",
|
|
||||||
perimeter = 2,
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 95, type = "acid" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "direct",
|
|
||||||
action_delivery = {
|
|
||||||
type = "instant",
|
|
||||||
target_effects = {
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
||||||
makeStream({
|
template.name = "acid-ball-5"
|
||||||
name = "acid-ball-5",
|
templateDamage.amount = 50
|
||||||
particleTint = {r=0, g=1, b=1, a=0.5},
|
templateArea.perimeter = 2
|
||||||
spineAnimationTint = {r=0, g=1, b=1, a=0.5},
|
makeStream(template)
|
||||||
softSmokeTint = makeColor(0.3, 0.75, 0.3, 0.1),
|
|
||||||
actions = {
|
--
|
||||||
{
|
|
||||||
type = "area",
|
template.name = "acid-ball-6"
|
||||||
perimeter = 2,
|
templateDamage.amount = 70
|
||||||
action_delivery =
|
templateArea.perimeter = 2.5
|
||||||
{
|
makeStream(template)
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 145, type = "acid" }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "direct",
|
|
||||||
action_delivery = {
|
|
||||||
type = "instant",
|
|
||||||
target_effects = {
|
|
||||||
type= "create-entity",
|
|
||||||
entity_name = "acid-splash-purple"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
@@ -57,57 +57,7 @@ makeStream({
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 35, type = "explosion" }
|
damage = { amount = 25, type = "explosion" }
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
makeStream({
|
|
||||||
name = "bob-explosive-ball-1",
|
|
||||||
particleTint = {r=1, g=0.97, b=0.34, a=0.5},
|
|
||||||
spineAnimationTint = {r=1, g=0.97, b=0.34, a=0.5},
|
|
||||||
softSmokeTint = makeColor(0.3, 0.75, 0.3, 0.1),
|
|
||||||
actions = {
|
|
||||||
{
|
|
||||||
type = "direct",
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "create-entity",
|
|
||||||
entity_name = "small-scorchmark",
|
|
||||||
check_buildability = true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "create-entity",
|
|
||||||
entity_name = "big-explosion",
|
|
||||||
check_buildability = true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "create-entity",
|
|
||||||
entity_name = "small-fire-cloud"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "area",
|
|
||||||
perimeter = 3,
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 55, type = "explosion" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -166,7 +116,7 @@ makeStream({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 43, type = "fire" }
|
damage = { amount = 20, type = "fire" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,47 +164,6 @@ makeStream({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
|
|
||||||
makeStream({
|
|
||||||
name = "bob-poison-ball-1",
|
|
||||||
particleTint = {r=0.1, g=0.5, b=1, a=0.5},
|
|
||||||
spineAnimationTint = {r=0, g=0, b=1, a=0.5},
|
|
||||||
softSmokeTint = makeColor(0.7, 0.4, 0.2, 0.1),
|
|
||||||
actions = {
|
|
||||||
{
|
|
||||||
type = "direct",
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "create-entity",
|
|
||||||
entity_name = "small-poison-cloud"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "area",
|
|
||||||
perimeter = 2,
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 43, type = "poison" }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
-- piercing
|
-- piercing
|
||||||
|
|
||||||
data:extend({
|
data:extend({
|
||||||
@@ -318,7 +227,7 @@ makeStream({
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 43, type = "bob-pierce" }
|
damage = { amount = 30, type = "bob-pierce" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -400,47 +309,7 @@ makeStream({
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 10, type = "electric" }
|
damage = { amount = 25, type = "electric" }
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
--
|
|
||||||
|
|
||||||
makeStream({
|
|
||||||
name = "bob-electric-ball-1",
|
|
||||||
particleTint = {r=0, g=0.1, b=1, a=1},
|
|
||||||
spineAnimationTint = {r=0, g=0.1, b=1, a=1},
|
|
||||||
softSmokeTint = makeColor(0.7, 0.4, 0.2, 0.1),
|
|
||||||
actions = {
|
|
||||||
{
|
|
||||||
type = "cluster",
|
|
||||||
cluster_count = 10,
|
|
||||||
distance = 4,
|
|
||||||
distance_deviation = 3,
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "projectile",
|
|
||||||
projectile = "electric-spike-rampant",
|
|
||||||
direction_deviation = 0.6,
|
|
||||||
starting_speed = 0.65,
|
|
||||||
starting_speed_deviation = 0.0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "area",
|
|
||||||
perimeter = 3,
|
|
||||||
action_delivery =
|
|
||||||
{
|
|
||||||
type = "instant",
|
|
||||||
target_effects =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 55, type = "electric" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -465,7 +334,7 @@ makeStream({
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
type = "create-entity",
|
type = "create-entity",
|
||||||
entity_name = "small-poison-cloud"
|
entity_name = "small-fire-cloud"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "create-entity",
|
type = "create-entity",
|
||||||
@@ -484,19 +353,15 @@ makeStream({
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 15, type = "electric" }
|
damage = { amount = 10, type = "electric" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 15, type = "explosion" }
|
damage = { amount = 10, type = "explosion" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 15, type = "fire" }
|
damage = { amount = 10, type = "fire" }
|
||||||
},
|
|
||||||
{
|
|
||||||
type = "damage",
|
|
||||||
damage = { amount = 15, type = "poison" }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -615,7 +480,7 @@ makeStream({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 20, type = "explosion" }
|
damage = { amount = 15, type = "explosion" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
@@ -631,7 +496,7 @@ makeStream({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 20, type = "acid" }
|
damage = { amount = 15, type = "acid" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -42,7 +42,7 @@ makeStream({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = {amount = 25, type = "poison"}
|
damage = {amount = 24, type = "poison"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,11 +91,11 @@ makeStream({
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 5, type = "explosion" }
|
damage = { amount = 8, type = "explosion" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 15, type = "acid" }
|
damage = { amount = 18, type = "acid" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,11 +135,11 @@ makeStream({
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 3, type = "explosion" }
|
damage = { amount = 5, type = "explosion" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 7, type = "poison" }
|
damage = { amount = 12, type = "poison" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,11 +183,11 @@ makeStream({
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 7, type = "explosion" }
|
damage = { amount = 5, type = "explosion" }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type = "damage",
|
type = "damage",
|
||||||
damage = { amount = 14, type = "acid" }
|
damage = { amount = 12, type = "acid" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -218,22 +218,50 @@ function biterFunctions.createFireAttack(attributes, fireAttack)
|
|||||||
begin_sound =
|
begin_sound =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
filename = "__base__/sound/fight/flamethrower-start.ogg",
|
filename = "__base__/sound/creatures/spitter-1.ogg",
|
||||||
|
volume = 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filename = "__base__/sound/creatures/spitter-2.ogg",
|
||||||
|
volume = 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filename = "__base__/sound/creatures/spitter-3.ogg",
|
||||||
|
volume = 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filename = "__base__/sound/creatures/spitter-4.ogg",
|
||||||
|
volume = 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filename = "__base__/sound/creatures/spitter-5.ogg",
|
||||||
|
volume = 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filename = "__base__/sound/creatures/spitter-6.ogg",
|
||||||
|
volume = 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filename = "__base__/sound/creatures/spitter-7.ogg",
|
||||||
|
volume = 0.7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
filename = "__base__/sound/creatures/spitter-8.ogg",
|
||||||
volume = 0.7
|
volume = 0.7
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
middle_sound =
|
middle_sound =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
filename = "__base__/sound/fight/flamethrower-mid.ogg",
|
filename = attributes.midSound or "__Rampant__/sounds/attacks/acid-mid.ogg",
|
||||||
volume = 0.7
|
volume = 0.5
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
end_sound =
|
end_sound =
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
filename = "__base__/sound/fight/flamethrower-end.ogg",
|
filename = attributes.endSound or "__Rampant__/sounds/attacks/acid-end.ogg",
|
||||||
volume = 0.7
|
volume = 0.5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,7 +10,8 @@ local makeSmokeSoft = smokeUtils.makeSmokeSoft
|
|||||||
|
|
||||||
-- module code
|
-- module code
|
||||||
|
|
||||||
function streamUtils.makeStream(attributes)
|
function streamUtils.makeStream(info)
|
||||||
|
local attributes = util.table.deepcopy(info)
|
||||||
local softSmokeName = attributes.softSmokeName or makeSmokeSoft(attributes)
|
local softSmokeName = attributes.softSmokeName or makeSmokeSoft(attributes)
|
||||||
data:extend(
|
data:extend(
|
||||||
{
|
{
|
||||||
@@ -79,7 +80,7 @@ function streamUtils.makeStream(attributes)
|
|||||||
height = 64,
|
height = 64,
|
||||||
frame_count = 32,
|
frame_count = 32,
|
||||||
line_length = 8
|
line_length = 8
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@@ -7,19 +7,19 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
|
|
||||||
turrets["bob-big-explosive-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["bob-big-explosive-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 25,
|
range = 26,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
scale = 1.2
|
scale = 1.2
|
||||||
},
|
},
|
||||||
"bob-explosive-ball-1-stream-rampant")
|
"bob-explosive-ball-stream-rampant")
|
||||||
|
|
||||||
turrets["bob-big-fire-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["bob-big-fire-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 25,
|
range = 26,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
@@ -29,19 +29,19 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
|
|
||||||
turrets["bob-big-poison-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["bob-big-poison-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 25,
|
range = 26,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
scale = 1.2
|
scale = 1.2
|
||||||
},
|
},
|
||||||
"bob-poison-ball-1-stream-rampant")
|
"bob-poison-ball-stream-rampant")
|
||||||
|
|
||||||
turrets["bob-big-piercing-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["bob-big-piercing-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 25,
|
range = 26,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
@@ -51,44 +51,44 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
|
|
||||||
turrets["bob-big-electric-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["bob-big-electric-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 25,
|
range = 26,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
scale = 1.2
|
scale = 1.2
|
||||||
},
|
},
|
||||||
"bob-electric-ball-1-stream-rampant")
|
"bob-electric-ball-stream-rampant")
|
||||||
|
|
||||||
turrets["bob-giant-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["bob-giant-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 28,
|
range = 28,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
scale = 1.6
|
scale = 1.6
|
||||||
},
|
},
|
||||||
"acid-ball-4-stream-rampant")
|
"acid-ball-5-stream-rampant")
|
||||||
|
|
||||||
turrets["bob-behemoth-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["bob-behemoth-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 30,
|
range = 30,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
scale = 2
|
scale = 2
|
||||||
},
|
},
|
||||||
"acid-ball-5-stream-rampant")
|
"acid-ball-6-stream-rampant")
|
||||||
|
|
||||||
local units = data.raw["unit"]
|
local units = data.raw["unit"]
|
||||||
|
|
||||||
local unit = units["behemoth-spitter"]
|
local unit = units["behemoth-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 16,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
@@ -102,10 +102,11 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
unit = units["bob-big-electric-spitter"]
|
unit = units["bob-big-electric-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 15,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
|
damageModifier = 0.6,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
scale = biterUtils.findRunScale(unit),
|
scale = biterUtils.findRunScale(unit),
|
||||||
@@ -117,11 +118,12 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
unit = units["bob-huge-explosive-spitter"]
|
unit = units["bob-huge-explosive-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 16,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
|
damageModifier = 0.8,
|
||||||
fire_penalty = 15,
|
fire_penalty = 15,
|
||||||
scale = biterUtils.findRunScale(unit),
|
scale = biterUtils.findRunScale(unit),
|
||||||
tint1 = biterUtils.findTint(unit),
|
tint1 = biterUtils.findTint(unit),
|
||||||
@@ -132,8 +134,8 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
unit = units["bob-huge-acid-spitter"]
|
unit = units["bob-huge-acid-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 16,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
@@ -147,8 +149,8 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
unit = units["bob-giant-fire-spitter"]
|
unit = units["bob-giant-fire-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 16,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
@@ -162,8 +164,8 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
unit = units["bob-giant-poison-spitter"]
|
unit = units["bob-giant-poison-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 16,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
@@ -177,8 +179,8 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
unit = units["bob-titan-spitter"]
|
unit = units["bob-titan-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 16,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
@@ -192,8 +194,8 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
unit = units["bob-behemoth-spitter"]
|
unit = units["bob-behemoth-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 16,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
@@ -208,8 +210,8 @@ function bobsUpdates.useDumbProjectiles()
|
|||||||
unit = units["bob-leviathan-spitter"]
|
unit = units["bob-leviathan-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 17,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
|
@@ -7,8 +7,8 @@ function NEUpdates.useNEUnitLaunchers ()
|
|||||||
|
|
||||||
turrets["medium-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["medium-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 22,
|
range = 25,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
@@ -19,8 +19,8 @@ function NEUpdates.useNEUnitLaunchers ()
|
|||||||
|
|
||||||
turrets["big-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["big-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 27,
|
range = 30,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
@@ -40,13 +40,13 @@ function NEUpdates.useDumbProjectiles()
|
|||||||
turret["attack_parameters"].range = 22
|
turret["attack_parameters"].range = 22
|
||||||
turret["attack_parameters"] = biterUtils.createFireAttack(
|
turret["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 22,
|
range = 25,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
damageModifier = 4.5,
|
damageModifier = 4.5,
|
||||||
scale = 1.0
|
scale = 1.2
|
||||||
},
|
},
|
||||||
"ne-infected-ball-stream-rampant")
|
"ne-infected-ball-stream-rampant")
|
||||||
|
|
||||||
@@ -54,13 +54,13 @@ function NEUpdates.useDumbProjectiles()
|
|||||||
turret["attack_parameters"].range = 27
|
turret["attack_parameters"].range = 27
|
||||||
turret["attack_parameters"] = biterUtils.createFireAttack(
|
turret["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 27,
|
range = 30,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
damageModifier = 5.5,
|
damageModifier = 5.5,
|
||||||
scale = 1.2
|
scale = 1.6
|
||||||
},
|
},
|
||||||
"ne-mutated-ball-stream-rampant")
|
"ne-mutated-ball-stream-rampant")
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ function NEUpdates.useDumbProjectiles()
|
|||||||
local unit = units["small-spitter-Mk2"]
|
local unit = units["small-spitter-Mk2"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 150,
|
cooldown = 100,
|
||||||
range = 13,
|
range = 13,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
@@ -85,7 +85,7 @@ function NEUpdates.useDumbProjectiles()
|
|||||||
unit = units["small-spitter-Mk3"]
|
unit = units["small-spitter-Mk3"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 150,
|
cooldown = 100,
|
||||||
range = 13,
|
range = 13,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
@@ -102,7 +102,7 @@ function NEUpdates.useDumbProjectiles()
|
|||||||
unit = units["medium-spitter-Mk2"]
|
unit = units["medium-spitter-Mk2"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 150,
|
cooldown = 100,
|
||||||
range = 14,
|
range = 14,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
@@ -118,7 +118,7 @@ function NEUpdates.useDumbProjectiles()
|
|||||||
unit = units["medium-spitter-Mk3"]
|
unit = units["medium-spitter-Mk3"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 150,
|
cooldown = 100,
|
||||||
range = 14,
|
range = 14,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
@@ -134,7 +134,7 @@ function NEUpdates.useDumbProjectiles()
|
|||||||
unit = units["big-spitter-Mk2"]
|
unit = units["big-spitter-Mk2"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 150,
|
cooldown = 100,
|
||||||
range = 15,
|
range = 15,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
@@ -151,7 +151,7 @@ function NEUpdates.useDumbProjectiles()
|
|||||||
unit = units["big-spitter-Mk3"]
|
unit = units["big-spitter-Mk3"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 150,
|
cooldown = 100,
|
||||||
range = 15,
|
range = 15,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
|
@@ -7,44 +7,46 @@ function vanillaUpdates.useDumbProjectiles()
|
|||||||
|
|
||||||
turrets["small-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["small-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 50,
|
cooldown = 60,
|
||||||
range = 18,
|
range = 21,
|
||||||
min_range = 5,
|
min_range = 5,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
|
damageModifier = 0.9,
|
||||||
scale = 0.8
|
scale = 0.8
|
||||||
},
|
},
|
||||||
"acid-ball-stream-rampant")
|
"acid-ball-2-stream-rampant")
|
||||||
|
|
||||||
turrets["medium-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["medium-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 20,
|
range = 25,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
|
damageModifier = 0.87,
|
||||||
scale = 1
|
scale = 1
|
||||||
},
|
},
|
||||||
"acid-ball-1-stream-rampant")
|
"acid-ball-3-stream-rampant")
|
||||||
|
|
||||||
|
|
||||||
turrets["big-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
turrets["big-worm-turret"]["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 60,
|
||||||
range = 25,
|
range = 26,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
fire_penalty = 0,
|
fire_penalty = 0,
|
||||||
scale = 1.2
|
scale = 1.2
|
||||||
},
|
},
|
||||||
"acid-ball-2-stream-rampant")
|
"acid-ball-4-stream-rampant")
|
||||||
|
|
||||||
local units = data.raw["unit"];
|
local units = data.raw["unit"];
|
||||||
|
|
||||||
local unit = units["small-spitter"]
|
local unit = units["small-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 100,
|
||||||
range = 13,
|
range = 13,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
@@ -59,7 +61,7 @@ function vanillaUpdates.useDumbProjectiles()
|
|||||||
unit = units["medium-spitter"]
|
unit = units["medium-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 95,
|
||||||
range = 14,
|
range = 14,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
@@ -74,7 +76,7 @@ function vanillaUpdates.useDumbProjectiles()
|
|||||||
unit = units["big-spitter"]
|
unit = units["big-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 15,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
@@ -89,8 +91,8 @@ function vanillaUpdates.useDumbProjectiles()
|
|||||||
unit = units["behemoth-spitter"]
|
unit = units["behemoth-spitter"]
|
||||||
unit["attack_parameters"] = biterUtils.createFireAttack(
|
unit["attack_parameters"] = biterUtils.createFireAttack(
|
||||||
{
|
{
|
||||||
cooldown = 80,
|
cooldown = 90,
|
||||||
range = 15,
|
range = 16,
|
||||||
min_range = 3,
|
min_range = 3,
|
||||||
warmup = 30,
|
warmup = 30,
|
||||||
turn_range = 1,
|
turn_range = 1,
|
||||||
|
11
settings.lua
11
settings.lua
@@ -193,17 +193,6 @@ data:extend({
|
|||||||
order = "h[modifier]-a[optimize]",
|
order = "h[modifier]-a[optimize]",
|
||||||
per_user = false
|
per_user = false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
type = "bool-setting",
|
|
||||||
name = "rampant-enableBuildings",
|
|
||||||
description = "rampant-enableBuildings",
|
|
||||||
setting_type = "startup",
|
|
||||||
default_value = true,
|
|
||||||
order = "i[modifier]-a[buildings]",
|
|
||||||
per_user = false
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
{
|
||||||
type = "bool-setting",
|
type = "bool-setting",
|
||||||
|
BIN
sounds/attacks/acid-end.ogg
Executable file
BIN
sounds/attacks/acid-end.ogg
Executable file
Binary file not shown.
BIN
sounds/attacks/acid-mid.ogg
Executable file
BIN
sounds/attacks/acid-mid.ogg
Executable file
Binary file not shown.
31
tests.lua
31
tests.lua
@@ -5,22 +5,23 @@ local mathUtils = require("libs/MathUtils")
|
|||||||
local chunkUtils = require("libs/ChunkUtils")
|
local chunkUtils = require("libs/ChunkUtils")
|
||||||
local mapUtils = require("libs/MapUtils")
|
local mapUtils = require("libs/MapUtils")
|
||||||
local baseUtils = require("libs/BaseUtils")
|
local baseUtils = require("libs/BaseUtils")
|
||||||
local baseRegisterUtils = require("libs/BaseRegisterUtils")
|
-- local tendrilUtils = require("libs/TendrilUtils")
|
||||||
local tendrilUtils = require("libs/TendrilUtils")
|
|
||||||
|
|
||||||
function tests.pheromoneLevels(size)
|
function tests.pheromoneLevels(size)
|
||||||
local player = game.player.character
|
local player = game.player.character
|
||||||
local playerChunkX = math.floor(player.position.x / 32)
|
local playerChunkX = math.floor(player.position.x / 32) * constants.CHUNK_SIZE
|
||||||
local playerChunkY = math.floor(player.position.y / 32)
|
local playerChunkY = math.floor(player.position.y / 32) * constants.CHUNK_SIZE
|
||||||
if not size then
|
if not size then
|
||||||
size = 3
|
size = 3 * constants.CHUNK_SIZE
|
||||||
|
else
|
||||||
|
size = size * constants.CHUNK_SIZE
|
||||||
end
|
end
|
||||||
print("------")
|
print("------")
|
||||||
print(#global.regionMap.processQueue)
|
print(#global.regionMap.processQueue)
|
||||||
print(playerChunkX .. ", " .. playerChunkY)
|
print(playerChunkX .. ", " .. playerChunkY)
|
||||||
print("--")
|
print("--")
|
||||||
for y=playerChunkY-size, playerChunkY+size do
|
for y=playerChunkY-size, playerChunkY+size,32 do
|
||||||
for x=playerChunkX-size, playerChunkX+size do
|
for x=playerChunkX-size, playerChunkX+size,32 do
|
||||||
if (global.regionMap[x] ~= nil) then
|
if (global.regionMap[x] ~= nil) then
|
||||||
local chunk = global.regionMap[x][y]
|
local chunk = global.regionMap[x][y]
|
||||||
if (chunk ~= nil) then
|
if (chunk ~= nil) then
|
||||||
@@ -29,12 +30,12 @@ function tests.pheromoneLevels(size)
|
|||||||
str = str .. " " .. tostring(i) .. "/" .. tostring(chunk[i])
|
str = str .. " " .. tostring(i) .. "/" .. tostring(chunk[i])
|
||||||
end
|
end
|
||||||
str = str .. " " .. "p/" .. game.surfaces[1].get_pollution(chunk)
|
str = str .. " " .. "p/" .. game.surfaces[1].get_pollution(chunk)
|
||||||
if (chunk.cX == playerChunkX) and (chunk.cY == playerChunkY) then
|
if (chunk.x == playerChunkX) and (chunk.y == playerChunkY) then
|
||||||
print("=============")
|
print("=============")
|
||||||
print(chunk.cX, chunk.cY, str)
|
print(chunk.x, chunk.y, str)
|
||||||
print("=============")
|
print("=============")
|
||||||
else
|
else
|
||||||
print(chunk.cX, chunk.cY, str)
|
print(chunk.x, chunk.y, str)
|
||||||
end
|
end
|
||||||
-- print(str)
|
-- print(str)
|
||||||
print("----")
|
print("----")
|
||||||
@@ -109,7 +110,7 @@ function tests.tunnelTest()
|
|||||||
local playerPosition = game.players[1].position
|
local playerPosition = game.players[1].position
|
||||||
local chunkX = math.floor(playerPosition.x * 0.03125) * 32
|
local chunkX = math.floor(playerPosition.x * 0.03125) * 32
|
||||||
local chunkY = math.floor(playerPosition.y * 0.03125) * 32
|
local chunkY = math.floor(playerPosition.y * 0.03125) * 32
|
||||||
game.surfaces[1].create_entity({name="tunnel-entrance", position={chunkX, chunkY}})
|
game.surfaces[1].create_entity({name="tunnel-entrance-rampant", position={chunkX, chunkY}})
|
||||||
end
|
end
|
||||||
|
|
||||||
function tests.createEnemy(x)
|
function tests.createEnemy(x)
|
||||||
@@ -121,7 +122,7 @@ end
|
|||||||
|
|
||||||
function tests.registeredNest(x)
|
function tests.registeredNest(x)
|
||||||
local entity = tests.createEnemy(x)
|
local entity = tests.createEnemy(x)
|
||||||
baseRegisterUtils.registerEnemyBaseStructure(global.regionMap,
|
chunk.registerEnemyBaseStructure(global.regionMap,
|
||||||
entity,
|
entity,
|
||||||
nil)
|
nil)
|
||||||
end
|
end
|
||||||
@@ -280,9 +281,9 @@ function tests.showMovementGrid()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function tests.stepAdvanceTendrils()
|
function tests.stepAdvanceTendrils()
|
||||||
for _, base in pairs(global.natives.bases) do
|
-- for _, base in pairs(global.natives.bases) do
|
||||||
tendrilUtils.advanceTendrils(global.regionMap, base, game.surfaces[1], {nil,nil,nil,nil,nil,nil,nil,nil})
|
-- tendrilUtils.advanceTendrils(global.regionMap, base, game.surfaces[1], {nil,nil,nil,nil,nil,nil,nil,nil})
|
||||||
end
|
-- end
|
||||||
end
|
end
|
||||||
|
|
||||||
return tests
|
return tests
|
||||||
|
Reference in New Issue
Block a user