working item collector complex entity
0
.gitignore
vendored
Normal file → Executable file
0
LICENSE.md
Normal file → Executable file
1
README.md
Normal file → Executable file
@@ -59,6 +59,7 @@ Configure Options not in game menu:
|
||||
|
||||
0.15.18 -
|
||||
- Fixed: Current version wasn't be set causing the upgrade code to run repeatedly
|
||||
- Fixed: Neighbors function not correctly clearing its state between calls
|
||||
|
||||
0.15.17 -
|
||||
- Fixed: Remote call load issue. (https://github.com/veden/Rampant/issues/5)
|
||||
|
6
Upgrade.lua
Normal file → Executable file
@@ -163,9 +163,9 @@ function upgrade.attempt(natives, world)
|
||||
global.world = {}
|
||||
world = global.world
|
||||
end
|
||||
|
||||
world.itemCollectors = {}
|
||||
world.itemCollectorIndex = 1
|
||||
|
||||
world.itemCollectorLookup = {}
|
||||
world.itemCollectorEvents = {}
|
||||
|
||||
game.surfaces[1].print("Rampant - Version 0.15.18")
|
||||
global.version = constants.VERSION_28
|
||||
|
0
config.lua
Normal file → Executable file
118
control.lua
Normal file → Executable file
@@ -19,6 +19,9 @@ local baseRegisterUtils = require("libs/BaseRegisterUtils")
|
||||
local mathUtils = require("libs/MathUtils")
|
||||
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
|
||||
|
||||
@@ -27,6 +30,13 @@ local INTERVAL_PROCESS = constants.INTERVAL_PROCESS
|
||||
|
||||
local MOVEMENT_PHEROMONE = constants.MOVEMENT_PHEROMONE
|
||||
|
||||
local DEFINES_INVENTORY_PLAYER_MAIN = defines.inventory.player_main
|
||||
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
|
||||
|
||||
-- imported functions
|
||||
@@ -39,6 +49,14 @@ local getChunkByPosition = mapUtils.getChunkByPosition
|
||||
|
||||
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 processWorld = worldProcessor.processWorld
|
||||
|
||||
local processMap = mapProcessor.processMap
|
||||
@@ -70,6 +88,8 @@ local processBases = baseProcessor.processBases
|
||||
|
||||
local mRandom = math.random
|
||||
|
||||
local getPlayerInventory = playerUtils.getPlayerInventory
|
||||
|
||||
-- local references to global
|
||||
|
||||
local regionMap -- manages the chunks that make up the game world
|
||||
@@ -248,9 +268,6 @@ local function onTick(event)
|
||||
|
||||
cleanSquads(natives)
|
||||
regroupSquads(natives)
|
||||
if (world == nil) then
|
||||
print("fucl")
|
||||
end
|
||||
|
||||
processWorld(surface, world, tick)
|
||||
|
||||
@@ -269,18 +286,7 @@ local function onTick(event)
|
||||
end
|
||||
|
||||
local function onBuild(event)
|
||||
local entity = event.created_entity
|
||||
print (entity.unit_number .. " " .. entity.name)
|
||||
if (entity.name == "steel-collector-overlay-rampant") then
|
||||
local position = entity.position
|
||||
local force = entity.force.name
|
||||
local surface = entity.surface
|
||||
entity.destroy()
|
||||
entity = surface.create_entity({position=position,
|
||||
force=force,
|
||||
name="steel-collector-rampant"})
|
||||
world.itemCollectors[#world.itemCollectors+1] = entity
|
||||
end
|
||||
local entity = buildComplexEntity(event.created_entity, world)
|
||||
addRemovePlayerEntity(regionMap, entity, natives, true, false)
|
||||
if natives.safeBuildings then
|
||||
if natives.safeEntities[entity.type] or natives.safeEntityName[entity.name] then
|
||||
@@ -289,8 +295,12 @@ local function onBuild(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function onPickUp(event)
|
||||
addRemovePlayerEntity(regionMap, event.entity, natives, false, false)
|
||||
local function onMine(event)
|
||||
addRemovePlayerEntity(regionMap,
|
||||
mineComplexEntity(event.entity, world),
|
||||
natives,
|
||||
false,
|
||||
false)
|
||||
end
|
||||
|
||||
local function onDeath(event)
|
||||
@@ -343,7 +353,13 @@ local function onDeath(event)
|
||||
if creditNatives and natives.safeBuildings and (natives.safeEntities[entity.type] or natives.safeEntityName[entity.name]) then
|
||||
makeImmortalEntity(surface, entity)
|
||||
else
|
||||
addRemovePlayerEntity(regionMap, entity, natives, false, creditNatives)
|
||||
mineComplexEntity(addRemovePlayerEntity(regionMap,
|
||||
entity,
|
||||
natives,
|
||||
false,
|
||||
creditNatives),
|
||||
world,
|
||||
true)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -376,8 +392,51 @@ local function onInit()
|
||||
hookEvents()
|
||||
end
|
||||
|
||||
local function onConfirmedBlueprint(event)
|
||||
print ("blueprint")
|
||||
-- local function onBuildingRotated(event)
|
||||
|
||||
-- end
|
||||
|
||||
local function onCursorChange(event)
|
||||
local player = game.players[event.player_index]
|
||||
swapItemStack(getPlayerCursorStack(player),
|
||||
"item-collector-base-rampant",
|
||||
"item-collector-base-overlay-rampant")
|
||||
end
|
||||
|
||||
local function onPlayerDropped(event)
|
||||
local item = event.entity
|
||||
if item.valid then
|
||||
swapItemStack(item.stack,
|
||||
"item-collector-base-overlay-rampant",
|
||||
"item-collector-base-rampant")
|
||||
end
|
||||
end
|
||||
|
||||
local function onMainInventoryChanged(event)
|
||||
swapItemInventory(getPlayerInventory(game.players[event.player_index],
|
||||
DEFINES_INVENTORY_PLAYER_MAIN,
|
||||
DEFINES_INVENTORY_GOD_MAIN),
|
||||
"item-collector-base-overlay-rampant",
|
||||
"item-collector-base-rampant")
|
||||
end
|
||||
|
||||
local function onQuickInventoryChanged(event)
|
||||
swapItemInventory(getPlayerInventory(game.players[event.player_index],
|
||||
DEFINES_INVENTORY_PLAYER_QUICKBAR,
|
||||
DEFINES_INVENTORY_GOD_QUICKBAR),
|
||||
"item-collector-base-overlay-rampant",
|
||||
"item-collector-base-rampant")
|
||||
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
|
||||
@@ -388,19 +447,32 @@ script.on_event(defines.events.on_runtime_mod_setting_changed,
|
||||
onModSettingsChange)
|
||||
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_cursor_stack_changed,
|
||||
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_preplayer_mined_item,
|
||||
defines.events.on_robot_pre_mined},
|
||||
onPickUp)
|
||||
script.on_event(defines.events.on_player_configured_blueprint,
|
||||
onConfirmedBlueprint)
|
||||
onMine)
|
||||
script.on_event({defines.events.on_built_entity,
|
||||
defines.events.on_robot_built_entity},
|
||||
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_tick, onTick)
|
||||
script.on_event(defines.events.on_chunk_generated, onChunkGenerated)
|
||||
|
0
data-final-fixes.lua
Normal file → Executable file
0
data-updates.lua
Normal file → Executable file
BIN
gimps/chests/ItemCollectorChest.xcf
Executable file
BIN
gimps/chests/itemCollector.xcf
Executable file
BIN
gimps/chests/itemCollectorBase.xcf
Executable file
BIN
gimps/chests/itemCollectorIcon.xcf
Executable file
BIN
gimps/chests/itemCollectorOverlay.xcf
Executable file
BIN
gimps/chests/itemCollectorParticle.xcf
Executable file
BIN
gimps/chests/itemCollectorTech.xcf
Executable file
BIN
graphics/entities/chest/itemCollector.png
Executable file
After Width: | Height: | Size: 124 KiB |
BIN
graphics/entities/chest/itemCollectorBase.png
Executable file
After Width: | Height: | Size: 3.9 KiB |
BIN
graphics/entities/chest/itemCollectorChest.png
Executable file
After Width: | Height: | Size: 2.8 KiB |
BIN
graphics/entities/chest/itemCollectorOverlay.png
Executable file
After Width: | Height: | Size: 18 KiB |
BIN
graphics/entities/chest/itemCollectorOverlay2.png
Executable file
After Width: | Height: | Size: 41 KiB |
BIN
graphics/entities/chest/itemCollectorOverlay3.png
Executable file
After Width: | Height: | Size: 79 KiB |
BIN
graphics/entities/chest/itemCollectorParticle.png
Executable file
After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 8.7 KiB |
0
graphics/entities/tunnel/tunnelEntrance.png
Normal file → Executable file
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
BIN
graphics/icon/itemCollectorIcon.png
Executable file
After Width: | Height: | Size: 2.4 KiB |
BIN
graphics/technology/itemCollectorTech.png
Executable file
After Width: | Height: | Size: 8.3 KiB |
0
graphics/tiles/fillableDirt/dirt-inner-corner.png
Normal file → Executable file
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
0
graphics/tiles/fillableDirt/dirt-outer-corner.png
Normal file → Executable file
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
0
graphics/tiles/fillableDirt/dirt-side.png
Normal file → Executable file
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
0
graphics/tiles/fillableDirt/dirt1.png
Normal file → Executable file
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
0
graphics/tiles/fillableDirt/dirt2.png
Normal file → Executable file
Before Width: | Height: | Size: 154 KiB After Width: | Height: | Size: 154 KiB |
0
graphics/tiles/fillableDirt/dirt4.png
Normal file → Executable file
Before Width: | Height: | Size: 474 KiB After Width: | Height: | Size: 474 KiB |
5
libs/AIAttackWave.lua
Normal file → Executable file
@@ -79,7 +79,8 @@ local function validUnitGroupLocation(neighborChunk)
|
||||
end
|
||||
|
||||
function aiAttackWave.rallyUnits(chunk, regionMap, surface, natives, tick)
|
||||
if (tick - chunk[RALLY_TRIGGERED] > INTERVAL_LOGIC) and (natives.points >= AI_VENGENCE_SQUAD_COST) then
|
||||
if ((tick - chunk[RALLY_TRIGGERED] > INTERVAL_LOGIC) and (natives.points >= AI_VENGENCE_SQUAD_COST) and
|
||||
(#natives.squads < natives.maxSquads)) then
|
||||
chunk[RALLY_TRIGGERED] = tick
|
||||
local cX = chunk.cX
|
||||
local cY = chunk.cY
|
||||
@@ -89,7 +90,7 @@ function aiAttackWave.rallyUnits(chunk, regionMap, surface, natives, tick)
|
||||
local rallyChunk = getChunkByIndex(regionMap, x, y)
|
||||
if rallyChunk and (rallyChunk[NEST_COUNT] ~= 0) then
|
||||
aiAttackWave.formSquads(regionMap, surface, natives, rallyChunk, AI_VENGENCE_SQUAD_COST)
|
||||
if (natives.points < AI_VENGENCE_SQUAD_COST) then
|
||||
if (natives.points < AI_VENGENCE_SQUAD_COST) and (#natives.squads < natives.maxSquads) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
0
libs/AIPlanning.lua
Normal file → Executable file
5
libs/AIPredicates.lua
Normal file → Executable file
@@ -16,9 +16,8 @@ local canAttackNocturnal = nocturnalUtils.canAttack
|
||||
-- module code
|
||||
|
||||
function aiPredicates.canAttack(natives, surface)
|
||||
return ((natives.state == AI_STATE_AGGRESSIVE) or
|
||||
canAttackNocturnal(natives, surface)) and not surface.peaceful_mode and
|
||||
(#natives.squads < natives.maxSquads)
|
||||
return (((natives.state == AI_STATE_AGGRESSIVE) or canAttackNocturnal(natives, surface))
|
||||
and not surface.peaceful_mode and (#natives.squads < natives.maxSquads))
|
||||
end
|
||||
|
||||
return aiPredicates
|
||||
|
4
libs/BaseProcessor.lua
Normal file → Executable file
@@ -2,7 +2,7 @@ local baseProcessor = {}
|
||||
|
||||
-- imports
|
||||
|
||||
local buildUtils = require("BuildUtils")
|
||||
local nestUtils = require("NestUtils")
|
||||
local tendrilUtils = require("TendrilUtils")
|
||||
local constants = require("Constants")
|
||||
|
||||
@@ -14,7 +14,7 @@ local BASE_QUEUE_SIZE = constants.BASE_QUEUE_SIZE
|
||||
|
||||
local mMin = math.min
|
||||
|
||||
local buildOrder = buildUtils.buildOrder
|
||||
local buildOrder = nestUtils.buildOrder
|
||||
local advanceTendrils = tendrilUtils.advanceTendrils
|
||||
|
||||
-- module code
|
||||
|
0
libs/BaseRegisterUtils.lua
Normal file → Executable file
4
libs/BaseUtils.lua
Normal file → Executable file
@@ -7,7 +7,7 @@ local constants = require("Constants")
|
||||
|
||||
local tendrilUtils = require("TendrilUtils")
|
||||
|
||||
local buildUtils = require("BuildUtils")
|
||||
local nestUtils = require("NestUtils")
|
||||
|
||||
-- constants
|
||||
|
||||
@@ -22,7 +22,7 @@ local MAGIC_MAXIMUM_BASE_NUMBER = constants.MAGIC_MAXIMUM_BASE_NUMBER
|
||||
|
||||
local euclideanDistancePoints = mathUtils.euclideanDistancePoints
|
||||
|
||||
local buildHive = buildUtils.buildHive
|
||||
local buildHive = nestUtils.buildHive
|
||||
|
||||
local mFloor = math.floor
|
||||
|
||||
|
204
libs/BuildUtils.lua
Normal file → Executable file
@@ -1,160 +1,74 @@
|
||||
local buildUtils = {}
|
||||
|
||||
-- imports
|
||||
|
||||
local constants = require("Constants")
|
||||
local mathUtils = require("MathUtils")
|
||||
|
||||
local baseRegisterUtils = require("BaseRegisterUtils")
|
||||
|
||||
local mapUtils = require("MapUtils")
|
||||
|
||||
-- constants
|
||||
|
||||
local MAGIC_MAXIMUM_BASE_NUMBER = constants.MAGIC_MAXIMUM_BASE_NUMBER
|
||||
|
||||
local AI_NEST_COST = constants.AI_NEST_COST
|
||||
local AI_WORM_COST = constants.AI_WORM_COST
|
||||
|
||||
local NEST_COUNT = constants.NEST_COUNT
|
||||
|
||||
local DOUBLE_CHUNK_SIZE = constants.DOUBLE_CHUNK_SIZE
|
||||
|
||||
-- imported functions
|
||||
|
||||
local registerEnemyBaseStructure = baseRegisterUtils.registerEnemyBaseStructure
|
||||
local gaussianRandomRange = mathUtils.gaussianRandomRange
|
||||
|
||||
local mRandom = math.random
|
||||
|
||||
local getChunkByPosition = mapUtils.getChunkByPosition
|
||||
|
||||
-- module code
|
||||
|
||||
function buildUtils.buildNest(regionMap, base, surface, targetPosition, name)
|
||||
local position = surface.find_non_colliding_position(name, targetPosition, DOUBLE_CHUNK_SIZE, 2)
|
||||
local chunk = getChunkByPosition(regionMap, position.x, position.y)
|
||||
local nest = nil
|
||||
if position and chunk and (chunk[NEST_COUNT] < 3) then
|
||||
local biterSpawner = {name=name, position=position}
|
||||
nest = surface.create_entity(biterSpawner)
|
||||
registerEnemyBaseStructure(regionMap, nest, base)
|
||||
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
|
||||
if (entity.name == "item-collector-base-overlay-rampant") then
|
||||
local position = entity.position
|
||||
local force = entity.force
|
||||
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
|
||||
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 nest
|
||||
return entity
|
||||
end
|
||||
|
||||
function buildUtils.buildHive(regionMap, base, surface)
|
||||
local valid = false
|
||||
local hive = buildUtils.buildNest(regionMap, base, surface, base, "biter-spawner-hive")
|
||||
if hive then
|
||||
if (#base.hives == 0) then
|
||||
base.x = hive.position.x
|
||||
base.y = hive.position.y
|
||||
end
|
||||
base.hives[#base.hives+1] = hive
|
||||
valid = true
|
||||
end
|
||||
return valid
|
||||
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]
|
||||
|
||||
function buildUtils.buildOutpost(regionMap, natives, base, surface, tendril)
|
||||
local foundHive = false
|
||||
for _,_ in pairs(base.hives) do
|
||||
foundHive = true
|
||||
break
|
||||
end
|
||||
if not foundHive or (base.upgradePoints < 10) then
|
||||
return
|
||||
end
|
||||
|
||||
if not tendril.unit.valid then
|
||||
return
|
||||
end
|
||||
local position = tendril.unit.position
|
||||
local generator = natives.randomGenerator
|
||||
generator.re_seed(mRandom(MAGIC_MAXIMUM_BASE_NUMBER))
|
||||
|
||||
for level=0,(base.level * 0.5) do
|
||||
local slices = (level * 3)
|
||||
slices = gaussianRandomRange(slices, slices * 0.1, slices * 0.6, slices * 1.4, generator)
|
||||
local slice = (2 * math.pi) / slices
|
||||
local pos = 0
|
||||
local thing
|
||||
local cost
|
||||
local radiusAdjustment
|
||||
if (generator() < 0.3) then
|
||||
thing = "small-worm-turret"
|
||||
cost = AI_WORM_COST
|
||||
radiusAdjustment = -4
|
||||
else
|
||||
thing = "biter-spawner"
|
||||
cost = AI_NEST_COST
|
||||
radiusAdjustment = 0
|
||||
end
|
||||
for _ = 1, slices do
|
||||
if (base.upgradePoints < 10) then
|
||||
return
|
||||
if chest and chest.valid then
|
||||
world.itemCollectorLookup[chest.unit_number] = nil
|
||||
if destroyed and (entity == chest) then
|
||||
chest.destroy()
|
||||
elseif (entity ~= chest) then
|
||||
chest.destroy()
|
||||
end
|
||||
end
|
||||
local radius = 10 * level
|
||||
local distortion = gaussianRandomRange(radius, 10, radius - 7.5 + radiusAdjustment, radius + 7.5 + radiusAdjustment, generator)
|
||||
local nestPosition = {x = position.x + (distortion * math.cos(pos)),
|
||||
y = position.y + (distortion * math.sin(pos))}
|
||||
local biterSpawner = {name=thing, position=nestPosition}
|
||||
if surface.can_place_entity(biterSpawner) then
|
||||
registerEnemyBaseStructure(regionMap, surface.create_entity(biterSpawner), base)
|
||||
base.upgradePoints = base.upgradePoints - cost
|
||||
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
|
||||
pos = pos + slice
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function buildUtils.buildOrder(regionMap, natives, base, surface)
|
||||
local foundHive = false
|
||||
for _,_ in pairs(base.hives) do
|
||||
foundHive = true
|
||||
break
|
||||
end
|
||||
if not foundHive or (base.upgradePoints < 10) then
|
||||
return
|
||||
end
|
||||
|
||||
local generator = natives.randomGenerator
|
||||
generator.re_seed(base.pattern)
|
||||
|
||||
for level=0,base.level do
|
||||
local slices = (level * 3)
|
||||
slices = gaussianRandomRange(slices, slices * 0.1, slices * 0.6, slices * 1.4, generator)
|
||||
local slice = (2 * math.pi) / slices
|
||||
local pos = 0
|
||||
local thing
|
||||
local cost
|
||||
local radiusAdjustment
|
||||
if (generator() < 0.3) then
|
||||
thing = "small-worm-turret"
|
||||
cost = AI_WORM_COST
|
||||
radiusAdjustment = -4
|
||||
else
|
||||
thing = "biter-spawner"
|
||||
cost = AI_NEST_COST
|
||||
radiusAdjustment = 0
|
||||
end
|
||||
for _ = 1, slices do
|
||||
if (base.upgradePoints < 10) then
|
||||
return
|
||||
end
|
||||
local radius = 10 * level
|
||||
local distortion = gaussianRandomRange(radius, 10, radius - 7.5 + radiusAdjustment, radius + 7.5 + radiusAdjustment, generator)
|
||||
local nestPosition = {x = base.x + (distortion * math.cos(pos)),
|
||||
y = base.y + (distortion * math.sin(pos))}
|
||||
local biterSpawner = {name=thing, position=nestPosition}
|
||||
if surface.can_place_entity(biterSpawner) then
|
||||
registerEnemyBaseStructure(regionMap, surface.create_entity(biterSpawner), base)
|
||||
base.upgradePoints = base.upgradePoints - cost
|
||||
end
|
||||
pos = pos + slice
|
||||
end
|
||||
end
|
||||
return entity
|
||||
end
|
||||
|
||||
return buildUtils
|
||||
|
8
libs/ChunkProcessor.lua
Normal file → Executable file
@@ -31,13 +31,13 @@ function chunkProcessor.processPendingChunks(natives, regionMap, surface, pendin
|
||||
|
||||
local chunkTiles = regionMap.chunkTiles
|
||||
|
||||
local start = #pendingStack
|
||||
for i=start, 1, -1 do
|
||||
for i=#pendingStack, 1, -1 do
|
||||
local event = pendingStack[i]
|
||||
pendingStack[i] = nil
|
||||
|
||||
local x = event.area.left_top.x
|
||||
local y = event.area.left_top.y
|
||||
local topLeft = event.area.left_top
|
||||
local x = topLeft.x
|
||||
local y = topLeft.y
|
||||
local chunk = createChunk(x, y)
|
||||
|
||||
areaBoundingBox[1] = chunk
|
||||
|
40
libs/ChunkUtils.lua
Normal file → Executable file
@@ -66,6 +66,9 @@ local function fullScan(chunkTiles, x, y, get_tile)
|
||||
chunkTiles[i] = nil
|
||||
end
|
||||
end
|
||||
if ((validTiles + (1024 - i)) < 615) then
|
||||
return 0, false, false
|
||||
end
|
||||
if northSouth then
|
||||
passableNorthSouth = true
|
||||
end
|
||||
@@ -83,19 +86,24 @@ local function fullScan(chunkTiles, x, y, get_tile)
|
||||
break
|
||||
end
|
||||
end
|
||||
return validTiles / 1024, passableNorthSouth, passableEastWest
|
||||
return validTiles * 0.009765625, passableNorthSouth, passableEastWest
|
||||
end
|
||||
|
||||
local function spotCheck(x, y, get_tile)
|
||||
local valid = 0
|
||||
local i = 0
|
||||
for offsetX = 0, 31, 5 do
|
||||
for offsetY = 0, 31, 5 do
|
||||
i = i + 1
|
||||
local tile = get_tile(x + offsetX,
|
||||
y + offsetY)
|
||||
if not tile.collides_with("player-layer") then
|
||||
valid = valid + 1
|
||||
end
|
||||
end
|
||||
if ((valid + (49 - i)) < 12) then
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
return valid
|
||||
@@ -108,31 +116,31 @@ function chunkUtils.checkChunkPassability(chunkTiles, chunk, surface)
|
||||
local get_tile = surface.get_tile
|
||||
|
||||
--[[
|
||||
0-10 represents water chunk
|
||||
11-46 chunk requires full scan
|
||||
47-49 assume chunk is passable in all directions
|
||||
0-12 represents water chunk
|
||||
13-44 chunk requires full scan
|
||||
45-49 assume chunk is passable in all directions
|
||||
--]]
|
||||
local cleanSpotCheck = spotCheck(x, y, get_tile)
|
||||
|
||||
local pass = CHUNK_ALL_DIRECTIONS
|
||||
if (cleanSpotCheck > 10) and (cleanSpotCheck < 47) then
|
||||
if (cleanSpotCheck < 13) then
|
||||
pass = CHUNK_IMPASSABLE
|
||||
elseif (cleanSpotCheck < 45) then
|
||||
local rating, passableNorthSouth, passableEastWest = fullScan(chunkTiles, x, y, get_tile)
|
||||
|
||||
if passableEastWest and passableNorthSouth then
|
||||
pass = CHUNK_ALL_DIRECTIONS
|
||||
elseif passableEastWest then
|
||||
pass = CHUNK_EAST_WEST
|
||||
elseif passableNorthSouth then
|
||||
pass = CHUNK_NORTH_SOUTH
|
||||
end
|
||||
|
||||
chunk[PATH_RATING] = rating
|
||||
if (rating < 0.6) then
|
||||
pass = CHUNK_IMPASSABLE
|
||||
else
|
||||
if passableEastWest and passableNorthSouth then
|
||||
pass = CHUNK_ALL_DIRECTIONS
|
||||
elseif passableEastWest then
|
||||
pass = CHUNK_EAST_WEST
|
||||
elseif passableNorthSouth then
|
||||
pass = CHUNK_NORTH_SOUTH
|
||||
else
|
||||
pass = CHUNK_IMPASSABLE
|
||||
end
|
||||
end
|
||||
elseif (cleanSpotCheck <= 10) then
|
||||
pass = CHUNK_IMPASSABLE
|
||||
else
|
||||
chunk[PATH_RATING] = 1
|
||||
end
|
||||
|
8
libs/Constants.lua
Normal file → Executable file
@@ -22,13 +22,15 @@ constants.MAGIC_MAXIMUM_NUMBER = 1e99 -- used in loops trying to find the lowest
|
||||
constants.MAGIC_MAXIMUM_BASE_NUMBER = 100000000
|
||||
constants.RETREAT_MOVEMENT_PHEROMONE_LEVEL = 10000
|
||||
|
||||
constants.PROCESS_QUEUE_SIZE = 450
|
||||
constants.SCAN_QUEUE_SIZE = 6
|
||||
constants.PROCESS_QUEUE_SIZE = 400
|
||||
constants.SCAN_QUEUE_SIZE = 5
|
||||
constants.ITEM_COLLECTOR_QUEUE_SIZE = 6
|
||||
constants.BASE_QUEUE_SIZE = 1
|
||||
constants.SQUAD_QUEUE_SIZE = 5
|
||||
constants.PROCESS_PLAYER_BOUND = 4
|
||||
|
||||
constants.ITEM_COLLECTOR_MAX_QUEUE_SIZE = 20
|
||||
|
||||
constants.TICKS_A_SECOND = 60
|
||||
constants.TICKS_A_MINUTE = constants.TICKS_A_SECOND * 60
|
||||
|
||||
@@ -41,7 +43,7 @@ constants.DEV_CUSTOM_AI = false
|
||||
|
||||
-- item collector
|
||||
|
||||
constants.ITEM_COLLECTOR_DISTANCE = 48
|
||||
constants.ITEM_COLLECTOR_DISTANCE = 44
|
||||
|
||||
-- chunk properties
|
||||
|
||||
|
1
libs/EntityUtils.lua
Normal file → Executable file
@@ -105,6 +105,7 @@ function entityUtils.addRemovePlayerEntity(regionMap, entity, natives, addObject
|
||||
rightBottom[PLAYER_BASE_GENERATOR] = rightBottom[PLAYER_BASE_GENERATOR] + entityValue
|
||||
end
|
||||
end
|
||||
return entity
|
||||
end
|
||||
|
||||
function entityUtils.makeImmortalEntity(surface, entity)
|
||||
|
0
libs/Interop.lua
Normal file → Executable file
25
libs/InventoryUtils.lua
Executable file
@@ -0,0 +1,25 @@
|
||||
local inventoryUtils = {}
|
||||
|
||||
-- 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.insert({name = dst, count = itemCount})
|
||||
inventory.remove({name = src, count = itemCount})
|
||||
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
|
6
libs/MapProcessor.lua
Normal file → Executable file
@@ -107,7 +107,7 @@ function mapProcessor.processMap(regionMap, surface, natives, tick)
|
||||
|
||||
if squads and (chunk[NEST_COUNT] ~= 0) then
|
||||
formSquads(regionMap, surface, natives, chunk, AI_SQUAD_COST)
|
||||
squads = natives.points >= AI_SQUAD_COST
|
||||
squads = (natives.points >= AI_SQUAD_COST) and (#natives.squads < natives.maxSquads)
|
||||
end
|
||||
|
||||
scents(chunk)
|
||||
@@ -169,11 +169,11 @@ function mapProcessor.processPlayers(players, regionMap, surface, natives, tick)
|
||||
if (chunk[NEST_COUNT] ~= 0) then
|
||||
if squads then
|
||||
formSquads(regionMap, surface, natives, chunk, AI_SQUAD_COST)
|
||||
squads = natives.points >= AI_SQUAD_COST
|
||||
squads = (natives.points >= AI_SQUAD_COST) and (#natives.squads < natives.maxSquads)
|
||||
end
|
||||
if vengence then
|
||||
formSquads(regionMap, surface, natives, chunk, AI_VENGENCE_SQUAD_COST)
|
||||
vengence = natives.points >= AI_VENGENCE_SQUAD_COST
|
||||
vengence = (natives.points >= AI_VENGENCE_SQUAD_COST) and (#natives.squads < natives.maxSquads)
|
||||
end
|
||||
end
|
||||
|
||||
|
22
libs/MapUtils.lua
Normal file → Executable file
@@ -25,7 +25,7 @@ local mFloor = math.floor
|
||||
|
||||
function mapUtils.getChunkByPosition(regionMap, x, y)
|
||||
local chunkX = regionMap[mFloor(x * 0.03125)]
|
||||
if (chunkX ~= nil) then
|
||||
if chunkX then
|
||||
return chunkX[mFloor(y * 0.03125)]
|
||||
end
|
||||
return nil
|
||||
@@ -33,7 +33,7 @@ end
|
||||
|
||||
function mapUtils.getChunkByIndex(regionMap, x, y)
|
||||
local chunkX = regionMap[x]
|
||||
if (chunkX ~= nil) then
|
||||
if chunkX then
|
||||
return chunkX[y]
|
||||
end
|
||||
return nil
|
||||
@@ -55,6 +55,10 @@ function mapUtils.getNeighborChunks(regionMap, chunkX, chunkY)
|
||||
neighbors[1] = xChunks[chunkYRow1]
|
||||
neighbors[4] = xChunks[chunkY]
|
||||
neighbors[6] = xChunks[chunkYRow3]
|
||||
else
|
||||
neighbors[1] = nil
|
||||
neighbors[4] = nil
|
||||
neighbors[6] = nil
|
||||
end
|
||||
|
||||
xChunks = regionMap[chunkX+1]
|
||||
@@ -62,12 +66,19 @@ function mapUtils.getNeighborChunks(regionMap, chunkX, chunkY)
|
||||
neighbors[3] = xChunks[chunkYRow1]
|
||||
neighbors[5] = xChunks[chunkY]
|
||||
neighbors[8] = xChunks[chunkYRow3]
|
||||
else
|
||||
neighbors[3] = nil
|
||||
neighbors[5] = nil
|
||||
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
|
||||
return neighbors
|
||||
end
|
||||
@@ -94,16 +105,23 @@ function mapUtils.getCardinalChunks(regionMap, chunkX, chunkY)
|
||||
if xChunks then
|
||||
neighbors[1] = xChunks[chunkY-1]
|
||||
neighbors[4] = xChunks[chunkY+1]
|
||||
else
|
||||
neighbors[1] = nil
|
||||
neighbors[4] = nil
|
||||
end
|
||||
|
||||
xChunks = regionMap[chunkX-1]
|
||||
if xChunks then
|
||||
neighbors[2] = xChunks[chunkY]
|
||||
else
|
||||
neighbors[2] = nil
|
||||
end
|
||||
|
||||
xChunks = regionMap[chunkX+1]
|
||||
if xChunks then
|
||||
neighbors[3] = xChunks[chunkY]
|
||||
else
|
||||
neighbors[3] = nil
|
||||
end
|
||||
return neighbors
|
||||
end
|
||||
|
0
libs/MathUtils.lua
Normal file → Executable file
0
libs/MovementUtils.lua
Normal file → Executable file
0
libs/NeighborUtils.lua
Normal file → Executable file
160
libs/NestUtils.lua
Executable file
@@ -0,0 +1,160 @@
|
||||
local nestUtils = {}
|
||||
|
||||
-- imports
|
||||
|
||||
local constants = require("Constants")
|
||||
local mathUtils = require("MathUtils")
|
||||
|
||||
local baseRegisterUtils = require("BaseRegisterUtils")
|
||||
|
||||
local mapUtils = require("MapUtils")
|
||||
|
||||
-- constants
|
||||
|
||||
local MAGIC_MAXIMUM_BASE_NUMBER = constants.MAGIC_MAXIMUM_BASE_NUMBER
|
||||
|
||||
local AI_NEST_COST = constants.AI_NEST_COST
|
||||
local AI_WORM_COST = constants.AI_WORM_COST
|
||||
|
||||
local NEST_COUNT = constants.NEST_COUNT
|
||||
|
||||
local DOUBLE_CHUNK_SIZE = constants.DOUBLE_CHUNK_SIZE
|
||||
|
||||
-- imported functions
|
||||
|
||||
local registerEnemyBaseStructure = baseRegisterUtils.registerEnemyBaseStructure
|
||||
local gaussianRandomRange = mathUtils.gaussianRandomRange
|
||||
|
||||
local mRandom = math.random
|
||||
|
||||
local getChunkByPosition = mapUtils.getChunkByPosition
|
||||
|
||||
-- module code
|
||||
|
||||
function nestUtils.buildNest(regionMap, base, surface, targetPosition, name)
|
||||
local position = surface.find_non_colliding_position(name, targetPosition, DOUBLE_CHUNK_SIZE, 2)
|
||||
local chunk = getChunkByPosition(regionMap, position.x, position.y)
|
||||
local nest = nil
|
||||
if position and chunk and (chunk[NEST_COUNT] < 3) then
|
||||
local biterSpawner = {name=name, position=position}
|
||||
nest = surface.create_entity(biterSpawner)
|
||||
registerEnemyBaseStructure(regionMap, nest, base)
|
||||
end
|
||||
return nest
|
||||
end
|
||||
|
||||
function nestUtils.buildHive(regionMap, base, surface)
|
||||
local valid = false
|
||||
local hive = nestUtils.buildNest(regionMap, base, surface, base, "biter-spawner-hive")
|
||||
if hive then
|
||||
if (#base.hives == 0) then
|
||||
base.x = hive.position.x
|
||||
base.y = hive.position.y
|
||||
end
|
||||
base.hives[#base.hives+1] = hive
|
||||
valid = true
|
||||
end
|
||||
return valid
|
||||
end
|
||||
|
||||
function nestUtils.buildOutpost(regionMap, natives, base, surface, tendril)
|
||||
local foundHive = false
|
||||
for _,_ in pairs(base.hives) do
|
||||
foundHive = true
|
||||
break
|
||||
end
|
||||
if not foundHive or (base.upgradePoints < 10) then
|
||||
return
|
||||
end
|
||||
|
||||
if not tendril.unit.valid then
|
||||
return
|
||||
end
|
||||
local position = tendril.unit.position
|
||||
local generator = natives.randomGenerator
|
||||
generator.re_seed(mRandom(MAGIC_MAXIMUM_BASE_NUMBER))
|
||||
|
||||
for level=0,(base.level * 0.5) do
|
||||
local slices = (level * 3)
|
||||
slices = gaussianRandomRange(slices, slices * 0.1, slices * 0.6, slices * 1.4, generator)
|
||||
local slice = (2 * math.pi) / slices
|
||||
local pos = 0
|
||||
local thing
|
||||
local cost
|
||||
local radiusAdjustment
|
||||
if (generator() < 0.3) then
|
||||
thing = "small-worm-turret"
|
||||
cost = AI_WORM_COST
|
||||
radiusAdjustment = -4
|
||||
else
|
||||
thing = "biter-spawner"
|
||||
cost = AI_NEST_COST
|
||||
radiusAdjustment = 0
|
||||
end
|
||||
for _ = 1, slices do
|
||||
if (base.upgradePoints < 10) then
|
||||
return
|
||||
end
|
||||
local radius = 10 * level
|
||||
local distortion = gaussianRandomRange(radius, 10, radius - 7.5 + radiusAdjustment, radius + 7.5 + radiusAdjustment, generator)
|
||||
local nestPosition = {x = position.x + (distortion * math.cos(pos)),
|
||||
y = position.y + (distortion * math.sin(pos))}
|
||||
local biterSpawner = {name=thing, position=nestPosition}
|
||||
if surface.can_place_entity(biterSpawner) then
|
||||
registerEnemyBaseStructure(regionMap, surface.create_entity(biterSpawner), base)
|
||||
base.upgradePoints = base.upgradePoints - cost
|
||||
end
|
||||
pos = pos + slice
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function nestUtils.buildOrder(regionMap, natives, base, surface)
|
||||
local foundHive = false
|
||||
for _,_ in pairs(base.hives) do
|
||||
foundHive = true
|
||||
break
|
||||
end
|
||||
if not foundHive or (base.upgradePoints < 10) then
|
||||
return
|
||||
end
|
||||
|
||||
local generator = natives.randomGenerator
|
||||
generator.re_seed(base.pattern)
|
||||
|
||||
for level=0,base.level do
|
||||
local slices = (level * 3)
|
||||
slices = gaussianRandomRange(slices, slices * 0.1, slices * 0.6, slices * 1.4, generator)
|
||||
local slice = (2 * math.pi) / slices
|
||||
local pos = 0
|
||||
local thing
|
||||
local cost
|
||||
local radiusAdjustment
|
||||
if (generator() < 0.3) then
|
||||
thing = "small-worm-turret"
|
||||
cost = AI_WORM_COST
|
||||
radiusAdjustment = -4
|
||||
else
|
||||
thing = "biter-spawner"
|
||||
cost = AI_NEST_COST
|
||||
radiusAdjustment = 0
|
||||
end
|
||||
for _ = 1, slices do
|
||||
if (base.upgradePoints < 10) then
|
||||
return
|
||||
end
|
||||
local radius = 10 * level
|
||||
local distortion = gaussianRandomRange(radius, 10, radius - 7.5 + radiusAdjustment, radius + 7.5 + radiusAdjustment, generator)
|
||||
local nestPosition = {x = base.x + (distortion * math.cos(pos)),
|
||||
y = base.y + (distortion * math.sin(pos))}
|
||||
local biterSpawner = {name=thing, position=nestPosition}
|
||||
if surface.can_place_entity(biterSpawner) then
|
||||
registerEnemyBaseStructure(regionMap, surface.create_entity(biterSpawner), base)
|
||||
base.upgradePoints = base.upgradePoints - cost
|
||||
end
|
||||
pos = pos + slice
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nestUtils
|
0
libs/NocturnalUtils.lua
Normal file → Executable file
24
libs/PheromoneUtils.lua
Normal file → Executable file
@@ -39,6 +39,8 @@ local IMPASSABLE_TERRAIN_GENERATOR_AMOUNT = constants.IMPASSABLE_TERRAIN_GENERAT
|
||||
|
||||
local getCardinalChunks = mapUtils.getCardinalChunks
|
||||
|
||||
local mMax = math.max
|
||||
|
||||
-- module code
|
||||
|
||||
function pheromoneUtils.scents(chunk)
|
||||
@@ -47,8 +49,9 @@ function pheromoneUtils.scents(chunk)
|
||||
chunk[BASE_PHEROMONE] = IMPASSABLE_TERRAIN_GENERATOR_AMOUNT;
|
||||
else
|
||||
chunk[BASE_PHEROMONE] = chunk[BASE_PHEROMONE] + chunk[PLAYER_BASE_GENERATOR]
|
||||
if (chunk[NEST_COUNT] == 0) and (chunk[RESOURCE_GENERATOR] > 0) then
|
||||
chunk[RESOURCE_PHEROMONE] = chunk[RESOURCE_PHEROMONE] + math.max((chunk[RESOURCE_GENERATOR] * 100), 90)
|
||||
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
|
||||
|
||||
@@ -57,7 +60,7 @@ end
|
||||
function pheromoneUtils.victoryScent(chunk, entityType)
|
||||
local value = BUILDING_PHEROMONES[entityType]
|
||||
if (value ~= nil) and (chunk[PASSABLE] ~= CHUNK_IMPASSABLE) then
|
||||
chunk[MOVEMENT_PHEROMONE] = chunk[MOVEMENT_PHEROMONE] + (value * 10000)
|
||||
chunk[MOVEMENT_PHEROMONE] = chunk[MOVEMENT_PHEROMONE] + (value * 100000)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -93,14 +96,15 @@ function pheromoneUtils.processPheromone(regionMap, chunk)
|
||||
local totalResource = 0
|
||||
|
||||
for i=1,4 do
|
||||
local neighborChunk = tempNeighbors[i]
|
||||
if neighborChunk then
|
||||
totalMovement = totalMovement + (neighborChunk[MOVEMENT_PHEROMONE] - chunkMovement)
|
||||
totalBase = totalBase + (neighborChunk[BASE_PHEROMONE] - chunkBase)
|
||||
totalPlayer = totalPlayer + (neighborChunk[PLAYER_PHEROMONE] - chunkPlayer)
|
||||
totalResource = totalResource + (neighborChunk[RESOURCE_PHEROMONE] - chunkResource)
|
||||
end
|
||||
local neighborChunk = tempNeighbors[i]
|
||||
if neighborChunk then
|
||||
totalMovement = totalMovement + (neighborChunk[MOVEMENT_PHEROMONE] - chunkMovement)
|
||||
totalBase = totalBase + (neighborChunk[BASE_PHEROMONE] - chunkBase)
|
||||
totalPlayer = totalPlayer + (neighborChunk[PLAYER_PHEROMONE] - chunkPlayer)
|
||||
totalResource = totalResource + (neighborChunk[RESOURCE_PHEROMONE] - chunkResource)
|
||||
end
|
||||
end
|
||||
|
||||
chunk[MOVEMENT_PHEROMONE] = (chunkMovement + (0.125 * totalMovement)) * MOVEMENT_PHEROMONE_PERSISTANCE * chunkPathRating
|
||||
chunk[BASE_PHEROMONE] = (chunkBase + (0.25 * totalBase)) * BASE_PHEROMONE_PERSISTANCE * chunkPathRating
|
||||
chunk[PLAYER_PHEROMONE] = (chunkPlayer + (0.25 * totalPlayer)) * PLAYER_PHEROMONE_PERSISTANCE * chunkPathRating
|
||||
|
21
libs/PlayerUtils.lua
Normal file → Executable file
@@ -11,7 +11,7 @@ local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
|
||||
-- module code
|
||||
|
||||
function playerUtils.validPlayer(player)
|
||||
return (player ~= nil) and player.connected and (player.character ~= nil) and player.character.valid and (player.character.surface.index == 1)
|
||||
return player and player.valid and player.connected and player.character and player.character.valid and (player.character.surface.index == 1)
|
||||
end
|
||||
|
||||
function playerUtils.playersWithinProximityToPosition(players, position, distance)
|
||||
@@ -25,5 +25,24 @@ function playerUtils.playersWithinProximityToPosition(players, position, distanc
|
||||
return false
|
||||
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
|
||||
|
0
libs/SquadAttack.lua
Normal file → Executable file
24
libs/SquadDefense.lua
Normal file → Executable file
@@ -83,23 +83,25 @@ function aiDefense.retreatUnits(chunk, position, squad, regionMap, surface, nati
|
||||
-- to each unit, this is the only way I have found to have snappy mid battle retreats even after 0.14.4
|
||||
|
||||
local newSquad = findNearBySquad(natives, retreatPosition, HALF_CHUNK_SIZE, RETREAT_FILTER)
|
||||
|
||||
if not newSquad then
|
||||
|
||||
if not newSquad and (#natives.squads < natives.maxSquads) then
|
||||
newSquad = createSquad(retreatPosition, surface, natives)
|
||||
newSquad.status = SQUAD_RETREATING
|
||||
newSquad.cycles = 4
|
||||
end
|
||||
|
||||
if enemiesToSquad then
|
||||
membersToSquad(newSquad, enemiesToSquad, false)
|
||||
else
|
||||
membersToSquad(newSquad, squad.group.members, true)
|
||||
newSquad.penalties = squad.penalties
|
||||
if squad.rabid then
|
||||
newSquad.rabid = true
|
||||
|
||||
if newSquad then
|
||||
if enemiesToSquad then
|
||||
membersToSquad(newSquad, enemiesToSquad, false)
|
||||
else
|
||||
membersToSquad(newSquad, squad.group.members, true)
|
||||
newSquad.penalties = squad.penalties
|
||||
if squad.rabid then
|
||||
newSquad.rabid = true
|
||||
end
|
||||
end
|
||||
addMovementPenalty(natives, newSquad, chunk.cX, chunk.cY)
|
||||
end
|
||||
addMovementPenalty(natives, newSquad, chunk.cX, chunk.cY)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
6
libs/TendrilUtils.lua
Normal file → Executable file
@@ -8,7 +8,7 @@ local baseRegisterUtils = require("BaseRegisterUtils")
|
||||
local neighborsUtils = require("NeighborUtils")
|
||||
local mathUtils = require("MathUtils")
|
||||
|
||||
local buildUtils = require("BuildUtils")
|
||||
local nestUtils = require("NestUtils")
|
||||
local mathUtils = require("MathUtils")
|
||||
|
||||
-- constants
|
||||
@@ -29,9 +29,9 @@ local getChunkByPosition = mapUtils.getChunkByPosition
|
||||
|
||||
local positionFromDirectionAndChunk = mapUtils.positionFromDirectionAndChunk
|
||||
|
||||
local buildNest = buildUtils.buildNest
|
||||
local buildNest = nestUtils.buildNest
|
||||
|
||||
local buildOutpost = buildUtils.buildOutpost
|
||||
local buildOutpost = nestUtils.buildOutpost
|
||||
|
||||
-- module code
|
||||
|
||||
|
0
libs/TunnelUtils.lua
Normal file → Executable file
30
libs/UnitGroupUtils.lua
Normal file → Executable file
@@ -41,14 +41,26 @@ local euclideanDistanceNamed = mathUtils.euclideanDistanceNamed
|
||||
function unitGroupUtils.findNearBySquad(natives, position, distance, filter)
|
||||
local squads = natives.squads
|
||||
|
||||
for i=1,#squads do
|
||||
local squad = squads[i]
|
||||
local unitGroup = squad.group
|
||||
if unitGroup.valid and (not filter or (filter and filter[squad.status])) then
|
||||
if (euclideanDistanceNamed(unitGroup.position, position) <= distance) then
|
||||
return squad
|
||||
end
|
||||
end
|
||||
if filter then
|
||||
for i=1,#squads do
|
||||
local squad = squads[i]
|
||||
local unitGroup = squad.group
|
||||
if unitGroup.valid and filter[squad.status] then
|
||||
if (euclideanDistanceNamed(unitGroup.position, position) <= distance) then
|
||||
return squad
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for i=1,#squads do
|
||||
local squad = squads[i]
|
||||
local unitGroup = squad.group
|
||||
if unitGroup.valid then
|
||||
if (euclideanDistanceNamed(unitGroup.position, position) <= distance) then
|
||||
return squad
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -221,7 +233,7 @@ function unitGroupUtils.regroupSquads(natives)
|
||||
if (maxSquadIndex == squadCount) then
|
||||
natives.regroupIndex = 1
|
||||
else
|
||||
natives.regroupIndex = maxSquadIndex
|
||||
natives.regroupIndex = maxSquadIndex + 1
|
||||
end
|
||||
end
|
||||
|
||||
|
45
libs/WorldProcessor.lua
Normal file → Executable file
@@ -12,29 +12,28 @@ local ITEM_COLLECTOR_QUEUE_SIZE = constants.ITEM_COLLECTOR_QUEUE_SIZE
|
||||
|
||||
-- imported functions
|
||||
|
||||
local mMin = math.min
|
||||
|
||||
-- module code
|
||||
|
||||
function worldProcessor.processWorld(surface, world, tick)
|
||||
local collectorIndex = world.itemCollectorIndex
|
||||
local collectors = world.itemCollectors
|
||||
local collectorLookup = world.itemCollectorLookup
|
||||
local collectors = world.itemCollectorEvents
|
||||
|
||||
local topLeftPosition = {x = 0, y = 0}
|
||||
local bottomRightPosition = {x = 0, y = 0}
|
||||
local boundingArea = {topLeftPosition,
|
||||
bottomRightPosition}
|
||||
|
||||
print ("here")
|
||||
|
||||
local endIndex = mMin(collectorIndex+ITEM_COLLECTOR_QUEUE_SIZE, #collectors)
|
||||
for index = collectorIndex, endIndex do
|
||||
local itemCollector = collectors[index]
|
||||
|
||||
print ("Found Collector")
|
||||
local count = 0
|
||||
for index = #collectors, 1, -1 do
|
||||
count = count + 1
|
||||
local itemCollectorPair = collectorLookup[collectors[index]]
|
||||
collectors[index] = nil
|
||||
local chest = itemCollectorPair[1]
|
||||
local dish = itemCollectorPair[2]
|
||||
|
||||
if itemCollector.valid then
|
||||
local collectorPosition = itemCollector.position
|
||||
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
|
||||
@@ -45,19 +44,27 @@ function worldProcessor.processWorld(surface, world, tick)
|
||||
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]
|
||||
if not counts[item.stack.name] then
|
||||
counts[item.stack.name] = 1
|
||||
else
|
||||
counts[item.stack.name] = counts[item.stack.name] + 1
|
||||
end
|
||||
item.destroy()
|
||||
end
|
||||
for k,c in pairs(counts) do
|
||||
chest.insert({name=k, count=c})
|
||||
end
|
||||
-- dish.surface.create_entity({name="item-collector-base-particle-rampant",
|
||||
-- position=dish.position})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (endIndex == #collectors) then
|
||||
world.itemCollectorIndex = 1
|
||||
else
|
||||
world.itemCollectorIndex = endIndex + 1
|
||||
if (count >= ITEM_COLLECTOR_QUEUE_SIZE) then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
24
locale/en/locale.cfg
Normal file → Executable file
@@ -12,6 +12,23 @@ small-fire-spitter=Small Fire Spitter
|
||||
biter-spawner-hive=Small Hive
|
||||
|
||||
small-tendril-biter-rampant=Small Tendril
|
||||
item-collector-base-rampant=Item Collector
|
||||
item-collector-chest-rampant=Item Collector Storage
|
||||
|
||||
[item-description]
|
||||
item-collector-base-rampant=Scans the area surrounding this chest and collects the items on the ground
|
||||
|
||||
[item-name]
|
||||
item-collector-base-rampant=Item Collector
|
||||
|
||||
[recipe-name]
|
||||
item-collector-base-rampant=Item Collector
|
||||
|
||||
[technology-name]
|
||||
short-range-electrodynamics-1-rampant=Short-range Electrodynamics
|
||||
|
||||
[technology-description]
|
||||
short-range-electrodynamics-1-rampant=Buildings that generate strong electromagnetic fields
|
||||
|
||||
[entity-description]
|
||||
tunnel-entrance=This tunnel is used by the biters to bypass player defenses. Fill the hole using landfill.
|
||||
@@ -26,6 +43,9 @@ small-fire-spitter=These biters will spit fire
|
||||
biter-spawner-hive=Small Hive
|
||||
|
||||
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-overlay-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-chest-rampant=Stores the items the scanner finds on the ground around this collector
|
||||
|
||||
[mod-setting-name]
|
||||
rampant-useDumbProjectiles=Use Dumb Projectiles
|
||||
@@ -49,6 +69,7 @@ rampant-addWallResistanceAcid=Increase wall resistance to spitters
|
||||
rampant-useCustomAI=Use Custom AI (Alpha)
|
||||
rampant-safeBuildings-lamps=Make lamps safe from biters
|
||||
rampant-removeBloodParticles=Remove blood particles (Reduces lag spikes)
|
||||
rampant-enableBuildings=Enable buildings and Technology
|
||||
|
||||
[mod-setting-description]
|
||||
rampant-useDumbProjectiles=Turns off homing projectiles for worms and spitters
|
||||
@@ -71,4 +92,5 @@ rampant-permanentNocturnal=Toggling this will cause Rampant attack waves to spaw
|
||||
rampant-aiPointsScaler=Between 0.0 and 5.0. This scales how many action points the ai gets per logic cycle to perform actions like making attack waves. 0.3 - very easy, 0.75 - easy, 1.0 - medium, 1.25+ - hard
|
||||
rampant-addWallResistanceAcid=Toggling this will cause a %60 acid resistance to be added to all wall entities to reduce the damage done by spitters to walls back to vanilla levels.
|
||||
rampant-useCustomAI=Having this enabled will completely remove the vanilla ai and change how biters build, produce units, and attack.
|
||||
rampant-removeBloodParticles=The blood particles that are created when biters are being killed can cause UPS spikes, this removes them.
|
||||
rampant-removeBloodParticles=The blood particles that are created when biters are being killed can cause UPS spikes, this removes them.
|
||||
rampant-enableBuildings=Enable buildings and technologies rampant offers
|
1
make.rkt
Normal file → Executable file
@@ -40,7 +40,6 @@
|
||||
(string->path "graphics")
|
||||
(string->path "prototypes")))
|
||||
|
||||
|
||||
(define (copyFile fileName modFolder)
|
||||
(copy-file (string->path fileName)
|
||||
(string->path (string-append modFolder
|
||||
|
578
prototypes/buildings/ItemCollector.lua
Normal file → Executable file
@@ -1,453 +1,177 @@
|
||||
-- overlays
|
||||
|
||||
-- data:extend({
|
||||
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 = 0
|
||||
radar.max_distance_of_sector_revealed = 0
|
||||
radar.energy_per_nearby_scan = "27MJ"
|
||||
radar.energy_usage = "450KW"
|
||||
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.2}
|
||||
}
|
||||
radar.minable = { result = "item-collector-base-rampant",
|
||||
mining_time = 1 }
|
||||
|
||||
-- -- {
|
||||
-- -- type = "logistic-container",
|
||||
-- -- name = "logistic-collector-active-provider-overlay-rampant",
|
||||
-- -- icon = "__base__/graphics/icons/logistic-chest-active-provider.png",
|
||||
-- -- flags = {"placeable-player", "player-creation"},
|
||||
-- -- minable = {hardness = 0.2, mining_time = 0.5, result = "logistic-collector-active-provider-overlay-rampant"},
|
||||
-- -- max_health = 350,
|
||||
-- -- corpse = "small-remnants",
|
||||
-- -- collision_box = {{-0.35, -0.35}, {0.35, 0.35}},
|
||||
-- -- selection_box = {{-0.5, -0.5}, {0.5, 0.5}},
|
||||
-- -- resistances =
|
||||
-- -- {
|
||||
-- -- {
|
||||
-- -- type = "fire",
|
||||
-- -- percent = 90
|
||||
-- -- },
|
||||
-- -- {
|
||||
-- -- type = "impact",
|
||||
-- -- percent = 60
|
||||
-- -- }
|
||||
-- -- },
|
||||
-- -- fast_replaceable_group = "container",
|
||||
-- -- inventory_size = 48,
|
||||
-- -- logistic_mode = "active-provider",
|
||||
-- -- open_sound = { filename = "__base__/sound/metallic-chest-open.ogg", volume=0.65 },
|
||||
-- -- close_sound = { filename = "__base__/sound/metallic-chest-close.ogg", volume = 0.7 },
|
||||
-- -- vehicle_impact_sound = { filename = "__base__/sound/car-metal-impact.ogg", volume = 0.65 },
|
||||
-- -- picture =
|
||||
-- -- {
|
||||
-- -- filename = "__Rampant__/graphics/entities/chest/logisticActiveCollectorOverlay.png",
|
||||
-- -- priority = "extra-high",
|
||||
-- -- width = 1600,
|
||||
-- -- height = 1600,
|
||||
-- -- shift = {0.09375, 0}
|
||||
-- -- },
|
||||
-- -- circuit_wire_connection_point =
|
||||
-- -- {
|
||||
-- -- shadow =
|
||||
-- -- {
|
||||
-- -- red = {0.734375, 0.453125},
|
||||
-- -- green = {0.609375, 0.515625},
|
||||
-- -- },
|
||||
-- -- wire =
|
||||
-- -- {
|
||||
-- -- red = {0.40625, 0.21875},
|
||||
-- -- green = {0.40625, 0.375},
|
||||
-- -- }
|
||||
-- -- },
|
||||
-- -- circuit_wire_max_distance = 9,
|
||||
-- -- circuit_connector_sprites = get_circuit_connector_sprites({0.1875, 0.15625}, nil, 18),
|
||||
-- -- },
|
||||
-- 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
|
||||
-- }
|
||||
-- }
|
||||
-- }
|
||||
-- }
|
||||
|
||||
-- -- {
|
||||
-- -- type = "logistic-container",
|
||||
-- -- name = "logistic-collector-passive-provider-overlay-rampant",
|
||||
-- -- icon = "__base__/graphics/icons/logistic-chest-passive-provider.png",
|
||||
-- -- flags = {"placeable-player", "player-creation"},
|
||||
-- -- minable = {hardness = 0.2, mining_time = 0.5, result = "logistic-collector-passive-provider-overlay-rampant"},
|
||||
-- -- max_health = 350,
|
||||
-- -- corpse = "small-remnants",
|
||||
-- -- collision_box = {{-0.35, -0.35}, {0.35, 0.35}},
|
||||
-- -- selection_box = {{-0.5, -0.5}, {0.5, 0.5}},
|
||||
-- -- resistances =
|
||||
-- -- {
|
||||
-- -- {
|
||||
-- -- type = "fire",
|
||||
-- -- percent = 90
|
||||
-- -- },
|
||||
-- -- {
|
||||
-- -- type = "impact",
|
||||
-- -- percent = 60
|
||||
-- -- }
|
||||
-- -- },
|
||||
-- -- fast_replaceable_group = "container",
|
||||
-- -- inventory_size = 48,
|
||||
-- -- logistic_mode = "active-provider",
|
||||
-- -- open_sound = { filename = "__base__/sound/metallic-chest-open.ogg", volume=0.65 },
|
||||
-- -- close_sound = { filename = "__base__/sound/metallic-chest-close.ogg", volume = 0.7 },
|
||||
-- -- vehicle_impact_sound = { filename = "__base__/sound/car-metal-impact.ogg", volume = 0.65 },
|
||||
-- -- picture =
|
||||
-- -- {
|
||||
-- -- filename = "__Rampant__/graphics/entities/chest/logisticPassiveCollectorOverlay.png",
|
||||
-- -- priority = "extra-high",
|
||||
-- -- width = 1600,
|
||||
-- -- height = 1600,
|
||||
-- -- shift = {0.09375, 0}
|
||||
-- -- },
|
||||
-- -- circuit_wire_connection_point =
|
||||
-- -- {
|
||||
-- -- shadow =
|
||||
-- -- {
|
||||
-- -- red = {0.734375, 0.453125},
|
||||
-- -- green = {0.609375, 0.515625},
|
||||
-- -- },
|
||||
-- -- wire =
|
||||
-- -- {
|
||||
-- -- red = {0.40625, 0.21875},
|
||||
-- -- green = {0.40625, 0.375},
|
||||
-- -- }
|
||||
-- -- },
|
||||
-- -- circuit_wire_max_distance = 9,
|
||||
-- -- circuit_connector_sprites = get_circuit_connector_sprites({0.1875, 0.15625}, nil, 18),
|
||||
-- -- },
|
||||
|
||||
-- -- {
|
||||
-- -- type = "container",
|
||||
-- -- name = "steel-collector-overlay-rampant",
|
||||
-- -- icon = "__base__/graphics/icons/steel-chest.png",
|
||||
-- -- flags = {"placeable-neutral", "player-creation"},
|
||||
-- -- minable = {mining_time = 1, result = "steel-collector-overlay-rampant"},
|
||||
-- -- max_health = 350,
|
||||
-- -- corpse = "small-remnants",
|
||||
-- -- open_sound = { filename = "__base__/sound/metallic-chest-open.ogg", volume=0.65 },
|
||||
-- -- close_sound = { filename = "__base__/sound/metallic-chest-close.ogg", volume = 0.7 },
|
||||
-- -- resistances =
|
||||
-- -- {
|
||||
-- -- {
|
||||
-- -- type = "fire",
|
||||
-- -- percent = 90
|
||||
-- -- },
|
||||
-- -- {
|
||||
-- -- type = "impact",
|
||||
-- -- percent = 60
|
||||
-- -- }
|
||||
-- -- },
|
||||
-- -- collision_box = {{-0.35, -0.35}, {0.35, 0.35}},
|
||||
-- -- selection_box = {{-0.5, -0.5}, {0.5, 0.5}},
|
||||
-- -- fast_replaceable_group = "container",
|
||||
-- -- inventory_size = 48,
|
||||
-- -- vehicle_impact_sound = { filename = "__base__/sound/car-metal-impact.ogg", volume = 0.65 },
|
||||
-- -- picture =
|
||||
-- -- {
|
||||
-- -- filename = "__Rampant__/graphics/entities/chest/steelCollectorOverlay.png",
|
||||
-- -- priority = "extra-high",
|
||||
-- -- width = 1000,
|
||||
-- -- height = 1000,
|
||||
-- -- shift = {0.1875, 0}
|
||||
-- -- },
|
||||
-- -- circuit_wire_connection_point =
|
||||
-- -- {
|
||||
-- -- shadow =
|
||||
-- -- {
|
||||
-- -- red = {0.734375, 0.453125},
|
||||
-- -- green = {0.609375, 0.515625},
|
||||
-- -- },
|
||||
-- -- wire =
|
||||
-- -- {
|
||||
-- -- red = {0.40625, 0.21875},
|
||||
-- -- green = {0.40625, 0.375},
|
||||
-- -- }
|
||||
-- -- },
|
||||
-- -- circuit_connector_sprites = get_circuit_connector_sprites({0.1875, 0.15625}, nil, 18),
|
||||
-- -- circuit_wire_max_distance = 9
|
||||
-- -- }
|
||||
-- })
|
||||
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 = 2800
|
||||
radarOverlay.pictures.height = 2800
|
||||
radarOverlay.pictures.direction_count = 1
|
||||
radarOverlay.pictures.line_length = 1
|
||||
radarOverlay.pictures.shift[2] = 0.07
|
||||
|
||||
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.flags[#chest.flags+1] = "not-deconstructable"
|
||||
chest.minable.result = "item-collector-base-rampant"
|
||||
|
||||
-- entities
|
||||
|
||||
data:extend({
|
||||
{
|
||||
type = "container",
|
||||
name = "steel-collector-rampant",
|
||||
icon = "__base__/graphics/icons/steel-chest.png",
|
||||
flags = {"placeable-neutral", "player-creation"},
|
||||
minable = {mining_time = 1, result = "steel-collector-overlay-rampant"},
|
||||
max_health = 350,
|
||||
corpse = "small-remnants",
|
||||
open_sound = { filename = "__base__/sound/metallic-chest-open.ogg", volume=0.65 },
|
||||
close_sound = { filename = "__base__/sound/metallic-chest-close.ogg", volume = 0.7 },
|
||||
resistances =
|
||||
{
|
||||
{
|
||||
type = "fire",
|
||||
percent = 90
|
||||
},
|
||||
{
|
||||
type = "impact",
|
||||
percent = 60
|
||||
}
|
||||
},
|
||||
collision_box = {{-0.35, -0.35}, {0.35, 0.35}},
|
||||
selection_box = {{-0.5, -0.5}, {0.5, 0.5}},
|
||||
fast_replaceable_group = "container",
|
||||
inventory_size = 48,
|
||||
vehicle_impact_sound = { filename = "__base__/sound/car-metal-impact.ogg", volume = 0.65 },
|
||||
picture =
|
||||
{
|
||||
filename = "__Rampant__/graphics/entities/chest/steelCollector.png",
|
||||
priority = "extra-high",
|
||||
width = 48,
|
||||
height = 34,
|
||||
shift = {0.1875, 0}
|
||||
},
|
||||
circuit_wire_connection_point =
|
||||
{
|
||||
shadow =
|
||||
{
|
||||
red = {0.734375, 0.453125},
|
||||
green = {0.609375, 0.515625},
|
||||
},
|
||||
wire =
|
||||
{
|
||||
red = {0.40625, 0.21875},
|
||||
green = {0.40625, 0.375},
|
||||
}
|
||||
},
|
||||
circuit_connector_sprites = get_circuit_connector_sprites({0.1875, 0.15625}, nil, 18),
|
||||
circuit_wire_max_distance = 9
|
||||
},
|
||||
|
||||
-- {
|
||||
-- type = "logistic-container",
|
||||
-- name = "logistic-collector-passive-provider-rampant",
|
||||
-- icon = "__base__/graphics/icons/logistic-chest-passive-provider.png",
|
||||
-- flags = {"placeable-player", "player-creation"},
|
||||
-- minable = {hardness = 0.2, mining_time = 0.5, result = "logistic-collector-passive-provider-rampant"},
|
||||
-- max_health = 350,
|
||||
-- corpse = "small-remnants",
|
||||
-- collision_box = {{-0.35, -0.35}, {0.35, 0.35}},
|
||||
-- selection_box = {{-0.5, -0.5}, {0.5, 0.5}},
|
||||
-- resistances =
|
||||
-- {
|
||||
-- {
|
||||
-- type = "fire",
|
||||
-- percent = 90
|
||||
-- },
|
||||
-- {
|
||||
-- type = "impact",
|
||||
-- percent = 60
|
||||
-- }
|
||||
-- },
|
||||
-- fast_replaceable_group = "container",
|
||||
-- inventory_size = 48,
|
||||
-- logistic_mode = "passive-provider",
|
||||
-- open_sound = { filename = "__base__/sound/metallic-chest-open.ogg", volume=0.65 },
|
||||
-- close_sound = { filename = "__base__/sound/metallic-chest-close.ogg", volume = 0.7 },
|
||||
-- vehicle_impact_sound = { filename = "__base__/sound/car-metal-impact.ogg", volume = 0.65 },
|
||||
-- picture =
|
||||
-- {
|
||||
-- filename = "__Rampant__/graphics/entities/chest/logisticPassiveCollector.png",
|
||||
-- priority = "extra-high",
|
||||
-- width = 38,
|
||||
-- height = 32,
|
||||
-- shift = {0.09375, 0}
|
||||
-- },
|
||||
-- circuit_wire_connection_point =
|
||||
-- {
|
||||
-- shadow =
|
||||
-- {
|
||||
-- red = {0.734375, 0.453125},
|
||||
-- green = {0.609375, 0.515625},
|
||||
-- },
|
||||
-- wire =
|
||||
-- {
|
||||
-- red = {0.40625, 0.21875},
|
||||
-- green = {0.40625, 0.375},
|
||||
-- }
|
||||
-- },
|
||||
-- circuit_wire_max_distance = 9,
|
||||
-- circuit_connector_sprites = get_circuit_connector_sprites({0.1875, 0.15625}, nil, 18),
|
||||
-- },
|
||||
|
||||
-- {
|
||||
-- type = "logistic-container",
|
||||
-- name = "logistic-collector-active-provider-rampant",
|
||||
-- icon = "__base__/graphics/icons/logistic-chest-active-provider.png",
|
||||
-- flags = {"placeable-player", "player-creation"},
|
||||
-- minable = {hardness = 0.2, mining_time = 0.5, result = "logistic-collector-active-provider-overlay-rampant"},
|
||||
-- max_health = 350,
|
||||
-- corpse = "small-remnants",
|
||||
-- collision_box = {{-0.35, -0.35}, {0.35, 0.35}},
|
||||
-- selection_box = {{-0.5, -0.5}, {0.5, 0.5}},
|
||||
-- resistances =
|
||||
-- {
|
||||
-- {
|
||||
-- type = "fire",
|
||||
-- percent = 90
|
||||
-- },
|
||||
-- {
|
||||
-- type = "impact",
|
||||
-- percent = 60
|
||||
-- }
|
||||
-- },
|
||||
-- fast_replaceable_group = "container",
|
||||
-- inventory_size = 48,
|
||||
-- logistic_mode = "active-provider",
|
||||
-- open_sound = { filename = "__base__/sound/metallic-chest-open.ogg", volume=0.65 },
|
||||
-- close_sound = { filename = "__base__/sound/metallic-chest-close.ogg", volume = 0.7 },
|
||||
-- vehicle_impact_sound = { filename = "__base__/sound/car-metal-impact.ogg", volume = 0.65 },
|
||||
-- picture =
|
||||
-- {
|
||||
-- filename = "__Rampant__/graphics/entities/chest/logisticActiveCollector.png",
|
||||
-- priority = "extra-high",
|
||||
-- width = 38,
|
||||
-- height = 32,
|
||||
-- shift = {0.09375, 0}
|
||||
-- },
|
||||
-- circuit_wire_connection_point =
|
||||
-- {
|
||||
-- shadow =
|
||||
-- {
|
||||
-- red = {0.734375, 0.453125},
|
||||
-- green = {0.609375, 0.515625},
|
||||
-- },
|
||||
-- wire =
|
||||
-- {
|
||||
-- red = {0.40625, 0.21875},
|
||||
-- green = {0.40625, 0.375},
|
||||
-- }
|
||||
-- },
|
||||
-- circuit_wire_max_distance = 9,
|
||||
-- circuit_connector_sprites = get_circuit_connector_sprites({0.1875, 0.15625}, nil, 18),
|
||||
-- }
|
||||
|
||||
radar,
|
||||
radarOverlay,
|
||||
chest-- ,
|
||||
-- particle
|
||||
})
|
||||
|
||||
-- recipes
|
||||
|
||||
data:extend({
|
||||
|
||||
-- {
|
||||
-- type = "recipe",
|
||||
-- name = "logistic-collector-active-provider-rampant",
|
||||
-- enabled = false,
|
||||
-- ingredients = {
|
||||
-- {"steel-chest", 1},
|
||||
-- {"electronic-circuit", 3},
|
||||
-- {"advanced-circuit", 1}
|
||||
-- },
|
||||
-- result = "logistic-collector-active-provider-overlay-rampant",
|
||||
-- requester_paste_multiplier = 4
|
||||
-- },
|
||||
|
||||
|
||||
{
|
||||
type = "recipe",
|
||||
name = "steel-collector-rampant",
|
||||
enabled = false,
|
||||
ingredients = {{"steel-plate", 8}},
|
||||
result = "steel-collector-rampant",
|
||||
requester_paste_multiplier = 4
|
||||
name = "item-collector-base-rampant",
|
||||
energy_required = 6,
|
||||
normal = {
|
||||
enabled = false,
|
||||
ingredients = {
|
||||
{"steel-chest", 1},
|
||||
{"accumulator", 1},
|
||||
{"radar", 1}
|
||||
},
|
||||
result = "item-collector-base-rampant",
|
||||
requester_paste_multiplier = 4
|
||||
}
|
||||
},
|
||||
|
||||
-- {
|
||||
-- type = "recipe",
|
||||
-- name = "logistic-collector-passive-provider-rampant",
|
||||
-- enabled = false,
|
||||
-- ingredients = {
|
||||
-- {"steel-chest", 1},
|
||||
-- {"electronic-circuit", 3},
|
||||
-- {"advanced-circuit", 1}
|
||||
-- },
|
||||
-- result = "logistic-collector-passive-provider-overlay-rampant",
|
||||
-- requester_paste_multiplier = 4
|
||||
-- }
|
||||
})
|
||||
|
||||
-- items
|
||||
|
||||
data:extend({
|
||||
|
||||
-- {
|
||||
-- type = "item",
|
||||
-- name = "steel-collector-overlay-rampant",
|
||||
-- icon = "__base__/graphics/icons/steel-chest.png",
|
||||
-- flags = {"goes-to-quickbar"},
|
||||
-- subgroup = "storage",
|
||||
-- order = "a[items]-c[steel-collector]",
|
||||
-- place_result = "steel-collector-overlay-rampant",
|
||||
-- stack_size = 50
|
||||
-- },
|
||||
|
||||
-- {
|
||||
-- type = "item",
|
||||
-- name = "logistic-collector-passive-provider-overlay-rampant",
|
||||
-- icon = "__base__/graphics/icons/steel-chest.png",
|
||||
-- flags = {"goes-to-quickbar"},
|
||||
-- subgroup = "storage",
|
||||
-- order = "a[items]-c[logistic-collector-passive-provider]",
|
||||
-- place_result = "logistic-collector-passive-provider-overlay-rampant",
|
||||
-- stack_size = 50
|
||||
-- },
|
||||
|
||||
-- {
|
||||
-- type = "item",
|
||||
-- name = "logistic-collector-active-provider-overlay-rampant",
|
||||
-- icon = "__base__/graphics/icons/steel-chest.png",
|
||||
-- flags = {"goes-to-quickbar"},
|
||||
-- subgroup = "storage",
|
||||
-- order = "a[items]-c[logistic-collector-active-provider]",
|
||||
-- place_result = "logistic-collector-active-provider-overlay-rampant",
|
||||
-- stack_size = 50
|
||||
-- },
|
||||
|
||||
{
|
||||
type = "item",
|
||||
name = "steel-collector-rampant",
|
||||
icon = "__base__/graphics/icons/steel-chest.png",
|
||||
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 = "steel-collector-rampant",
|
||||
place_result = "item-collector-base-rampant",
|
||||
stack_size = 50
|
||||
}-- ,
|
||||
},
|
||||
|
||||
-- {
|
||||
-- type = "item",
|
||||
-- name = "logistic-collector-passive-provider-rampant",
|
||||
-- icon = "__base__/graphics/icons/steel-chest.png",
|
||||
-- flags = {"goes-to-quickbar"},
|
||||
-- subgroup = "storage",
|
||||
-- order = "a[items]-c[logistic-collector-passive-provider]",
|
||||
-- place_result = "logistic-collector-passive-provider-rampant",
|
||||
-- stack_size = 50
|
||||
-- },
|
||||
|
||||
-- {
|
||||
-- type = "item",
|
||||
-- name = "logistic-collector-active-provider-rampant",
|
||||
-- icon = "__base__/graphics/icons/steel-chest.png",
|
||||
-- flags = {"goes-to-quickbar"},
|
||||
-- subgroup = "storage",
|
||||
-- order = "a[items]-c[logistic-collector-active-provider]",
|
||||
-- place_result = "logistic-collector-active-provider-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
|
||||
|
||||
table.insert(data.raw.technology["steel-processing"].effects,
|
||||
{
|
||||
type = "unlock-recipe",
|
||||
recipe = "steel-collector-rampant"
|
||||
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",
|
||||
},
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
-- table.insert(data.raw.technology["steel-processing"].effects,
|
||||
-- {
|
||||
-- type = "unlock-recipe",
|
||||
-- recipe = "logistic-collector-passive-provider-rampant"
|
||||
|
||||
-- })
|
||||
|
||||
-- table.insert(data.raw.technology["steel-processing"].effects,
|
||||
-- {
|
||||
-- type = "unlock-recipe",
|
||||
-- recipe = "logistic-collector-active-provider-rampant"
|
||||
|
||||
-- })
|
||||
|