first attempt

This commit is contained in:
Aaron Veden
2017-12-20 19:50:36 -08:00
parent a4a5d2c83c
commit d0ed774587
13 changed files with 323 additions and 165 deletions
+3 -3
View File
@@ -163,10 +163,10 @@ function upgrade.attempt(natives)
game.surfaces[1].print("Rampant - Version 0.15.23")
global.version = constants.VERSION_33
end
if (global.version < constants.VERSION_35) then
if (global.version < constants.VERSION_36) then
game.surfaces[1].print("Rampant - Version 0.16.0")
global.version = constants.VERSION_35
game.surfaces[1].print("Rampant - Version 0.16.1")
global.version = constants.VERSION_36
end
return starting ~= global.version, natives
end
+6 -4
View File
@@ -154,12 +154,14 @@ local function rebuildRegionMap()
SENTINEL_IMPASSABLE_CHUNK,
SENTINEL_IMPASSABLE_CHUNK,
SENTINEL_IMPASSABLE_CHUNK }
regionMap.chunkTiles = {}
regionMap.position = {x=0,
y=0}
for i=1,1024 do
regionMap.chunkTiles[i] = nil
end
--this is shared between two different queries
local sharedFilterArea = {{0, 0}, {0, 0}}
regionMap.filteredEntitiesQuery = { area=sharedFilterArea, force=false }
regionMap.cliffQuery = { type="cliff", area={{0, 0}, {0, 0}} }
regionMap.filteredTilesQuery = { name="", area=sharedFilterArea }
-- switched over to tick event
regionMap.logicTick = roundToNearest(game.tick + INTERVAL_LOGIC, INTERVAL_LOGIC)
+8
View File
@@ -11,6 +11,14 @@ if settings.startup["rampant-enableSwarm"] then
end
end
for k, cliff in pairs(data.raw["cliff"]) do
if not cliff.collision_mask then
cliff.collision_mask = {}
end
cliff.collision_mask[#cliff.collision_mask+1] = "water-tile"
end
if settings.startup["rampant-addWallResistanceAcid"].value then
vanillaBuildings.addWallAcidResistance()
end
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name" : "Rampant",
"factorio_version" : "0.16",
"version" : "0.16.0",
"version" : "0.16.1",
"title" : "Rampant",
"author" : "Veden",
"homepage" : "https://forums.factorio.com/viewtopic.php?f=94&t=31445",
+15 -21
View File
@@ -13,7 +13,6 @@ local SENTINEL_IMPASSABLE_CHUNK = constants.SENTINEL_IMPASSABLE_CHUNK
-- imported functions
local remakeChunk = chunkUtils.remakeChunk
local createChunk = chunkUtils.createChunk
local checkChunkPassability = chunkUtils.checkChunkPassability
local scoreChunk = chunkUtils.scoreChunk
@@ -21,17 +20,16 @@ local registerChunkEnemies = chunkUtils.registerChunkEnemies
-- module code
function chunkProcessor.processPendingChunks(natives, regionMap, surface, pendingStack, tick)
function chunkProcessor.processPendingChunks(natives, regionMap, surface, pendingStack)
local processQueue = regionMap.processQueue
local offset = {0, 0}
local areaBoundingBox = {false, offset}
local query = {area=areaBoundingBox,
force=false}
local filteredEntitiesQuery = regionMap.filteredEntitiesQuery
local vanillaAI = not natives.useCustomAI
local topOffset = filteredEntitiesQuery.area[1]
local bottomOffset = filteredEntitiesQuery.area[2]
local chunkTiles = regionMap.chunkTiles
local filteredTilesQuery = regionMap.filteredTilesQuery
local cliffQuery = regionMap.cliffQuery
for i=#pendingStack, 1, -1 do
local event = pendingStack[i]
@@ -41,21 +39,17 @@ function chunkProcessor.processPendingChunks(natives, regionMap, surface, pendin
local x = topLeft.x
local y = topLeft.y
local chunk = createChunk(x, y)
chunk = checkChunkPassability(chunkTiles, chunk, surface)
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
topOffset[1] = x
topOffset[2] = y
bottomOffset[1] = x + CHUNK_SIZE
bottomOffset[2] = y + CHUNK_SIZE
areaBoundingBox[1] = chunk
offset[1] = x + CHUNK_SIZE
offset[2] = y + CHUNK_SIZE
if vanillaAI then
registerChunkEnemies(regionMap, chunk, surface, query)
else
remakeChunk(regionMap, chunk, surface, natives, tick, query)
end
scoreChunk(regionMap, chunk, surface, natives, query)
chunk = checkChunkPassability(chunk, surface, filteredTilesQuery, cliffQuery)
if (chunk ~= SENTINEL_IMPASSABLE_CHUNK) then
registerChunkEnemies(regionMap, chunk, surface, filteredEntitiesQuery)
scoreChunk(regionMap, chunk, surface, natives, filteredEntitiesQuery)
local chunkX = chunk.x
+80 -114
View File
@@ -7,6 +7,8 @@ local mapUtils = require("MapUtils")
-- constants
local WATER_TILE_NAMES = constants.WATER_TILE_NAMES
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
@@ -26,6 +28,7 @@ local CHUNK_ALL_DIRECTIONS = constants.CHUNK_ALL_DIRECTIONS
local CHUNK_IMPASSABLE = constants.CHUNK_IMPASSABLE
local CHUNK_TICK = constants.CHUNK_TICK
local CHUNK_SIZE = constants.CHUNK_SIZE
local PATH_RATING = constants.PATH_RATING
@@ -39,67 +42,37 @@ local mFloor = math.floor
-- module code
local function fullScan(chunkTiles, x, y, get_tile)
local endY = y + 31
local i = 0
local validTiles = 0
local function fullScan(x, y, count_entities_filtered, cliffQuery)
local passableNorthSouth = false
local passableEastWest = false
local area = cliffQuery.area
local top = area[1]
local bottom = area[2]
top[2] = y
bottom[2] = y + CHUNK_SIZE
for xi=x, x + 31 do
local northSouth = true
for yi=y, endY do
i = i + 1
local tile = get_tile(xi, yi)
if not tile.collides_with("player-layer") then
validTiles = validTiles + 1
chunkTiles[i] = tile
else
northSouth = false
chunkTiles[i] = nil
end
end
if ((validTiles + (1024 - i)) < 615) then
return 0, false, false
end
if northSouth then
top[1] = xi
bottom[1] = xi + 1
if (count_entities_filtered(cliffQuery) == 0) then
passableNorthSouth = true
break
end
end
for yi=1, 32 do
local westEast = true
for xi=0, 992, 32 do
if not chunkTiles[yi + xi] then
westEast = false
break
end
end
if westEast then
top[1] = x
bottom[1] = x + CHUNK_SIZE
for yi=y, y + 31 do
top[2] = yi
bottom[2] = yi + 1
if (count_entities_filtered(cliffQuery) == 0) then
passableEastWest = true
break
end
end
return validTiles * 0.0009765625, 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
return passableNorthSouth, passableEastWest
end
local function addEnemyStructureToChunk(regionMap, chunk, entity, base)
@@ -217,77 +190,66 @@ end
-- external functions
function chunkUtils.checkChunkPassability(chunkTiles, chunk, surface)
local x = chunk.x
local y = chunk.y
function chunkUtils.checkChunkPassability(chunk, surface, filteredTilesQuery, cliffQuery)
local count_tiles_filtered = surface.count_tiles_filtered
local count_entities_filtered = surface.count_entities_filtered
local get_tile = surface.get_tile
local passScore = 0
for i=1,#WATER_TILE_NAMES do
filteredTilesQuery.name = WATER_TILE_NAMES[i]
passScore = passScore + count_tiles_filtered(filteredTilesQuery)
end
--[[
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 < 13) then
pass = CHUNK_IMPASSABLE
elseif (cleanSpotCheck < 45) then
local rating, passableNorthSouth, passableEastWest = fullScan(chunkTiles, x, y, get_tile)
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
passScore = 1 - (passScore * 0.0009765625)
local pass = CHUNK_IMPASSABLE
if (passScore >= 0.60) then
local passableNorthSouth, passableEastWest = fullScan(chunk.x, chunk.y, count_entities_filtered, cliffQuery)
if passableEastWest and passableNorthSouth then
pass = CHUNK_ALL_DIRECTIONS
elseif passableEastWest then
pass = CHUNK_EAST_WEST
elseif passableNorthSouth then
pass = CHUNK_NORTH_SOUTH
end
else
chunk[PATH_RATING] = 1
end
if (pass == CHUNK_IMPASSABLE) then
return SENTINEL_IMPASSABLE_CHUNK
else
chunk[PASSABLE] = pass
chunk[PATH_RATING] = passScore
return chunk
end
end
function chunkUtils.remakeChunk(regionMap, chunk, surface, natives, tick, tempQuery)
tempQuery.force = "enemy"
local enemies = surface.find_entities_filtered(tempQuery)
-- function chunkUtils.remakeChunk(regionMap, chunk, surface, natives, tick, tempQuery)
-- tempQuery.force = "enemy"
-- local enemies = surface.find_entities_filtered(tempQuery)
local points = 0
for f=1, #enemies do
local enemy = enemies[f]
local entityType = enemies[f].type
if not ((enemy.name == "small-tendril-biter-rampant") or (enemy.name == "biter-spawner-hive-rampant")) then
if (entityType == "unit-spawner") then
points = points + 3
elseif (entityType == "turret") then
points = points + 2
elseif (entityType == "unit") then
points = points + 1
end
enemy.destroy()
end
end
-- local foundBase = findNearbyBase(natives, chunk) or createBase(regionMap, natives, chunk, surface, tick)
-- if foundBase then
-- foundBase.upgradePoints = foundBase.upgradePoints + points
-- end
end
-- local points = 0
-- for f=1, #enemies do
-- local enemy = enemies[f]
-- local entityType = enemies[f].type
-- if not ((enemy.name == "small-tendril-biter-rampant") or (enemy.name == "biter-spawner-hive-rampant")) then
-- if (entityType == "unit-spawner") then
-- points = points + 3
-- elseif (entityType == "turret") then
-- points = points + 2
-- elseif (entityType == "unit") then
-- points = points + 1
-- end
-- enemy.destroy()
-- end
-- end
-- -- local foundBase = findNearbyBase(natives, chunk) or createBase(regionMap, natives, chunk, surface, tick)
-- -- if foundBase then
-- -- foundBase.upgradePoints = foundBase.upgradePoints + points
-- -- end
-- end
function chunkUtils.registerChunkEnemies(regionMap, chunk, surface, tempQuery)
tempQuery.force = "enemy"
local enemies = surface.find_entities_filtered(tempQuery)
function chunkUtils.registerChunkEnemies(regionMap, chunk, surface, filteredEntitiesQuery)
filteredEntitiesQuery.force = "enemy"
local enemies = surface.find_entities_filtered(filteredEntitiesQuery)
for i=1, #enemies do
local enemy = enemies[i]
@@ -306,6 +268,10 @@ function chunkUtils.getWormCount(regionMap, chunk)
return regionMap.chunkToWorms[chunk] or 0
end
function chunkUtils.getEnemyStructureCount(regionMap, chunk)
return (regionMap.chunkToNests[chunk] or 0) + (regionMap.chunkToWorms[chunk] or 0)
end
function chunkUtils.getRetreatTick(regionMap, chunk)
return regionMap.chunkToRetreats[chunk] or 0
end
@@ -342,14 +308,14 @@ 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.type = "resource"
chunkUtils.setResourceGenerator(regionMap, chunk, surface.count_entities_filtered(tempQuery) * 0.001)
function chunkUtils.scoreChunk(regionMap, chunk, surface, natives, filteredEntitiesQuery)
filteredEntitiesQuery.force = nil
filteredEntitiesQuery.type = "resource"
chunkUtils.setResourceGenerator(regionMap, chunk, surface.count_entities_filtered(filteredEntitiesQuery) * 0.001)
tempQuery.type = nil
tempQuery.force = "player"
local entities = surface.find_entities_filtered(tempQuery)
filteredEntitiesQuery.type = nil
filteredEntitiesQuery.force = "player"
local entities = surface.find_entities_filtered(filteredEntitiesQuery)
local playerObjects = 0
local safeBuildings = natives.safeBuildings
+3 -1
View File
@@ -16,11 +16,13 @@ constants.VERSION_26 = 26
constants.VERSION_27 = 27
constants.VERSION_28 = 28
constants.VERSION_33 = 33
constants.VERSION_35 = 35
constants.VERSION_36 = 36
-- misc
constants.WATER_TILE_NAMES = { "water", "deepwater", "water-green", "deepwater-green" }
constants.CHUNK_SIZE_DIVIDER = 0.03125
constants.MAGIC_MAXIMUM_NUMBER = 1e99 -- used in loops trying to find the lowest/highest score
constants.MAGIC_MAXIMUM_BASE_NUMBER = 100000000
+6 -5
View File
@@ -39,11 +39,11 @@ function movementUtils.findMovementPosition(surface, position, distort)
return (distort and distortPosition(pos)) or pos
end
function movementUtils.addMovementPenalty(natives, units, x, y)
function movementUtils.addMovementPenalty(natives, units, chunk)
local penalties = units.penalties
for i=1,#penalties do
local penalty = penalties[i]
if (penalty.x == x) and (penalty.y == y) then
if (penalty.c == chunk) then
penalty.v = penalty.v + MOVEMENT_PHEROMONE_GENERATOR_AMOUNT
if (penalty.v > MAX_PENALTY_BEFORE_PURGE) then
local group = units.group
@@ -60,9 +60,10 @@ function movementUtils.addMovementPenalty(natives, units, x, y)
if (#penalties == 7) then
tableRemove(penalties, 7)
end
tableInsert(penalties, 1, { v = MOVEMENT_PHEROMONE_GENERATOR_AMOUNT,
x = x,
y = y })
tableInsert(penalties,
1,
{ v = MOVEMENT_PHEROMONE_GENERATOR_AMOUNT,
c = chunk })
end
function movementUtils.lookupMovementPenalty(squad, x, y)
+6 -8
View File
@@ -60,7 +60,7 @@ local scoreNeighborsForAttack = movementUtils.scoreNeighborsForAttack
local function scoreAttackLocation(squad, neighborChunk)
local damage = (2*neighborChunk[MOVEMENT_PHEROMONE]) + neighborChunk[BASE_PHEROMONE] + (neighborChunk[PLAYER_PHEROMONE] * PLAYER_PHEROMONE_MULTIPLER)
return damage - lookupMovementPenalty(squad, neighborChunk.x, neighborChunk.y)
return damage - lookupMovementPenalty(squad, neighborChunk)
end
function squadAttack.squadsAttack(regionMap, surface, natives)
@@ -90,7 +90,7 @@ function squadAttack.squadsAttack(regionMap, surface, natives)
getNeighborChunks(regionMap, chunkX, chunkY),
scoreAttackLocation,
squad)
addMovementPenalty(natives, squad, chunkX, chunkY)
addMovementPenalty(natives, squad, chunk)
if group.valid and (attackChunk ~= SENTINEL_IMPASSABLE_CHUNK) then
local playerBaseGenerator = getPlayerBaseGenerator(regionMap, attackChunk)
if (playerBaseGenerator == 0) or ((groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING)) then
@@ -110,6 +110,7 @@ function squadAttack.squadsAttack(regionMap, surface, natives)
if position then
attackPosition.x = position.x
attackPosition.y = position.y
group.set_command(attackCmd)
group.start_moving()
else
@@ -138,17 +139,14 @@ function squadAttack.squadsBeginAttack(natives, players)
local groupPosition = group.position
local kamikazeThreshold = calculateKamikazeThreshold(squad, natives)
local playerNearby = playersWithinProximityToPosition(players, groupPosition, 100)
if playerNearby then
if playersWithinProximityToPosition(players, groupPosition, 100) then
squad.frenzy = true
squad.frenzyPosition.x = groupPosition.x
squad.frenzyPosition.y = groupPosition.y
end
if (mRandom() < 0.70) then
squad.kamikaze = mRandom() < kamikazeThreshold
squad.status = SQUAD_RAIDING
end
squad.kamikaze = mRandom() < kamikazeThreshold
squad.status = SQUAD_RAIDING
end
end
end
+3 -4
View File
@@ -40,8 +40,7 @@ local findMovementPosition = movementUtils.findMovementPosition
local getRetreatTick = chunkUtils.getRetreatTick
local getPlayerBaseGenerator = chunkUtils.getPlayerBaseGenerator
local setRetreatTick = chunkUtils.setRetreatTick
local getNestCount = chunkUtils.getNestCount
local getWormCount = chunkUtils.getWormCount
local getEnemyStructureCount = chunkUtils.getEnemyStructureCount
-- module code
@@ -50,7 +49,7 @@ local function scoreRetreatLocation(regionMap, neighborChunk)
end
function aiDefense.retreatUnits(chunk, position, squad, regionMap, surface, natives, tick)
if (tick - getRetreatTick(regionMap, chunk) > INTERVAL_LOGIC) and (getNestCount(regionMap, chunk) == 0) and (getWormCount(regionMap, chunk) == 0) then
if (tick - getRetreatTick(regionMap, chunk) > INTERVAL_LOGIC) and (getEnemyStructureCount(regionMap, chunk) == 0) then
local performRetreat = false
local enemiesToSquad = nil
@@ -97,7 +96,7 @@ function aiDefense.retreatUnits(chunk, position, squad, regionMap, surface, nati
newSquad.rabid = true
end
end
addMovementPenalty(natives, newSquad, chunk.x, chunk.y)
addMovementPenalty(natives, newSquad, chunk)
end
end
end
+2 -2
View File
@@ -80,8 +80,8 @@
(copyDirectory "prototypes" modFolder)))
(define (run)
;;(copyFiles modFolder)
(copyFiles modFolder)
;;(copyFiles zipModFolder)
(makeZip modFolder)
;;(makeZip modFolder)
)
)
+184
View File
@@ -186,6 +186,190 @@ data:extend({
max_spawn_shift = 0,
max_richness_for_spawn_shift = 100,
call_for_help_radius = 50
},
{
type = "unit-spawner",
name = "chunk-scanner-ew-rampant",
icon = "__base__/graphics/icons/biter-spawner.png",
icon_size = 32,
flags = {},
collision_mask = {"player-layer"},
selectable_in_game = false,
max_health = 350,
order="b-b-g",
subgroup="enemies",
resistances =
{
{
type = "physical",
decrease = 2,
percent = 15
},
{
type = "explosion",
decrease = 5,
percent = 15,
},
{
type = "fire",
decrease = 3,
percent = 60,
}
},
working_sound = {
sound =
{
{
filename = "__base__/sound/creatures/spawner.ogg",
volume = 1.0
}
},
apparent_volume = 2
},
dying_sound =
{
{
filename = "__base__/sound/creatures/spawner-death-1.ogg",
volume = 1.0
},
{
filename = "__base__/sound/creatures/spawner-death-2.ogg",
volume = 1.0
}
},
healing_per_tick = 0.02,
collision_box = {{0, -0.5}, {32, 0}},
selection_box = {{0, 0}, {32, 1}},
-- in ticks per 1 pu
pollution_absorbtion_absolute = 20,
pollution_absorbtion_proportional = 0.01,
corpse = "biter-spawner-corpse",
dying_explosion = "blood-explosion-huge",
max_count_of_owned_units = 7,
max_friends_around_to_spawn = 5,
animations =
{
spawner_idle_animation(0, biter_spawner_powered_tint),
spawner_idle_animation(1, biter_spawner_powered_tint),
spawner_idle_animation(2, biter_spawner_powered_tint),
spawner_idle_animation(3, biter_spawner_powered_tint)
},
result_units = (function()
local res = {}
res[1] = {"small-biter", {{0.0, 0.3}, {0.6, 0.0}}}
if not data.is_demo then
-- from evolution_factor 0.3 the weight for medium-biter is linearly rising from 0 to 0.3
-- this means for example that when the evolution_factor is 0.45 the probability of spawning
-- a small biter is 66% while probability for medium biter is 33%.
res[2] = {"medium-biter", {{0.2, 0.0}, {0.6, 0.3}, {0.7, 0.1}}}
-- for evolution factor of 1 the spawning probabilities are: small-biter 0%, medium-biter 1/8, big-biter 4/8, behemoth biter 3/8
res[3] = {"big-biter", {{0.5, 0.0}, {1.0, 0.4}}}
res[4] = {"behemoth-biter", {{0.9, 0.0}, {1.0, 0.3}}}
end
return res
end)(),
-- With zero evolution the spawn rate is 6 seconds, with max evolution it is 2.5 seconds
spawning_cooldown = {360, 150},
spawning_radius = 10,
spawning_spacing = 3,
max_spawn_shift = 0,
max_richness_for_spawn_shift = 100,
call_for_help_radius = 50
},
{
type = "unit-spawner",
name = "chunk-scanner-ns-rampant",
icon = "__base__/graphics/icons/biter-spawner.png",
icon_size = 32,
flags = {},
collision_mask = {"player-layer"},
selectable_in_game = false,
max_health = 350,
order="b-b-g",
subgroup="enemies",
resistances =
{
{
type = "physical",
decrease = 2,
percent = 15
},
{
type = "explosion",
decrease = 5,
percent = 15,
},
{
type = "fire",
decrease = 3,
percent = 60,
}
},
working_sound = {
sound =
{
{
filename = "__base__/sound/creatures/spawner.ogg",
volume = 1.0
}
},
apparent_volume = 2
},
dying_sound =
{
{
filename = "__base__/sound/creatures/spawner-death-1.ogg",
volume = 1.0
},
{
filename = "__base__/sound/creatures/spawner-death-2.ogg",
volume = 1.0
}
},
healing_per_tick = 0.02,
collision_box = {{-0.5, 0}, {0, 32}},
selection_box = {{0, 0}, {32, 1}},
-- in ticks per 1 pu
pollution_absorbtion_absolute = 20,
pollution_absorbtion_proportional = 0.01,
corpse = "biter-spawner-corpse",
dying_explosion = "blood-explosion-huge",
max_count_of_owned_units = 7,
max_friends_around_to_spawn = 5,
animations =
{
spawner_idle_animation(0, biter_spawner_powered_tint),
spawner_idle_animation(1, biter_spawner_powered_tint),
spawner_idle_animation(2, biter_spawner_powered_tint),
spawner_idle_animation(3, biter_spawner_powered_tint)
},
result_units = (function()
local res = {}
res[1] = {"small-biter", {{0.0, 0.3}, {0.6, 0.0}}}
if not data.is_demo then
-- from evolution_factor 0.3 the weight for medium-biter is linearly rising from 0 to 0.3
-- this means for example that when the evolution_factor is 0.45 the probability of spawning
-- a small biter is 66% while probability for medium biter is 33%.
res[2] = {"medium-biter", {{0.2, 0.0}, {0.6, 0.3}, {0.7, 0.1}}}
-- for evolution factor of 1 the spawning probabilities are: small-biter 0%, medium-biter 1/8, big-biter 4/8, behemoth biter 3/8
res[3] = {"big-biter", {{0.5, 0.0}, {1.0, 0.4}}}
res[4] = {"behemoth-biter", {{0.9, 0.0}, {1.0, 0.3}}}
end
return res
end)(),
-- With zero evolution the spawn rate is 6 seconds, with max evolution it is 2.5 seconds
spawning_cooldown = {360, 150},
spawning_radius = 10,
spawning_spacing = 3,
max_spawn_shift = 0,
max_richness_for_spawn_shift = 100,
call_for_help_radius = 50
}
})
+6 -2
View File
@@ -150,11 +150,15 @@ function tests.tunnelTest()
game.surfaces[1].create_entity({name="tunnel-entrance-rampant", position={chunkX, chunkY}})
end
function tests.createEnemy(x)
function tests.createEnemy(x,d)
local playerPosition = game.players[1].position
local chunkX = math.floor(playerPosition.x * 0.03125) * 32
local chunkY = math.floor(playerPosition.y * 0.03125) * 32
return game.surfaces[1].create_entity({name=x, position={chunkX, chunkY}})
local a = {name=x, position={chunkX, chunkY}}
if d then
a['direction'] = d
end
return game.surfaces[1].create_entity(a)
end
function tests.registeredNest(x)