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

see readme

This commit is contained in:
Aaron Veden 2017-05-26 17:58:33 -07:00
parent 49a82fcff4
commit 9e361b3c06
12 changed files with 191 additions and 169 deletions

View File

@ -14,6 +14,11 @@ https://forums.factorio.com/viewtopic.php?f=94&t=31445
There will be a slight pause the first time this is started up due to indexing all the chunks that have been generated.
MP should be working
If experiencing desyncs, after an update, please due the following:
1) let me know
2) Load save with Rampant enabled
3) Save the map after Rampant has been updated
4) Load save in step 3
Configure Options not in game menu:
- Ramp up to max biter wave size
@ -50,6 +55,20 @@ Configure Options not in game menu:
# Version History
0.15.10 -
- Fix: nil chunk in pheromone utils(https://mods.factorio.com/mods/Veden/Rampant/discussion/13806)
- Tweak: Increased failed behaviors before dispanding from 3 to 6
- Improvement: Switched to untargetable indestructible safe buildings
- Improvement: Changed the "ground shake" message to be displayed at a more appropriate time
- Improvement: Recycling biter groups now has a lower threshold and checks for active nearby squads before purging the clusters
- Optimization: Adjusted factorio pathfinder parameters to favor short paths for performance
- Optimization: Moved invariants out of inner loop in pheromone dispersion
- Optimization: Reduced garbage generated when doing passive map scan
- Optimization: Switched rally cries to a once per logic cycle per chunk
- Optimization: Locallized global defines in files that use them
- Optimization: Preallocating tables of falses for chunk neighbors
- Framework: Split squad regrouping and squad cleanup
0.15.9 -
- Improvement: Added bobs higher tier big electric poles to be included with make safe toggle for big electric poles
- Improvement: Added logic to reconnect wires when big electric poles are made safe and get destroyed (Thanks Jeroen D Stout, https://forums.factorio.com/viewtopic.php?f=94&t=31445&start=140#p275663)

View File

@ -42,63 +42,46 @@ function upgrade.attempt(natives, regionMap)
regionMap.pP = nil
regionMap.pR = nil
global.version = constants.VERSION_9
global.version = constants.VERSION_9
end
if (global.version < constants.VERSION_10) then
for _,squad in pairs(natives.squads) do
squad.frenzy = false
squad.frenzyPosition = {x=0,y=0}
squad.rabid = false
end
for _,squad in pairs(natives.squads) do
squad.frenzy = false
squad.frenzyPosition = {x=0,y=0}
squad.rabid = false
end
global.version = constants.VERSION_10
global.version = constants.VERSION_10
end
if (global.version < constants.VERSION_11) then
natives.state = constants.AI_STATE_AGGRESSIVE
natives.temperament = 0
natives.state = constants.AI_STATE_AGGRESSIVE
natives.temperament = 0
global.version = constants.VERSION_11
global.version = constants.VERSION_11
end
if (global.version < constants.VERSION_12) then
for _,squad in pairs(natives.squads) do
squad.status = constants.SQUAD_GUARDING
squad.kamikaze = false
end
for _,squad in pairs(natives.squads) do
squad.status = constants.SQUAD_GUARDING
squad.kamikaze = false
end
-- reset ai build points due to error in earning points
natives.points = 0
-- reset ai build points due to error in earning points
natives.points = 0
global.version = constants.VERSION_12
end
if (global.version < constants.VERSION_13) then
-- used to rate limit the number of rally cries during a period of time
natives.rallyCries = MAX_RALLY_CRIES
global.version = constants.VERSION_13
end
if (global.version < constants.VERSION_14) then
game.map_settings.unit_group.member_disown_distance = 5
game.map_settings.unit_group.max_member_speedup_when_behind = 1.1
game.map_settings.unit_group.max_member_slowdown_when_ahead = 1.0
game.map_settings.unit_group.max_group_slowdown_factor = 0.9
game.surfaces[1].print("Rampant - Version 0.14.11")
global.version = constants.VERSION_14
global.version = constants.VERSION_12
end
if (global.version < constants.VERSION_16) then
natives.lastShakeMessage = 0
--remove version 14 retreat limit, it has been made redundant
natives.retreats = nil
natives.lastShakeMessage = 0
--remove version 14 retreat limit, it has been made redundant
natives.retreats = nil
game.map_settings.unit_group.max_group_radius = 20
game.surfaces[1].print("Rampant - Version 0.14.13")
global.version = constants.VERSION_16
game.surfaces[1].print("Rampant - Version 0.14.13")
global.version = constants.VERSION_16
end
if (global.version < constants.VERSION_18) then
print(global.version)
natives.safeEntities = {}
natives.safeEntityName = {}
@ -106,37 +89,46 @@ function upgrade.attempt(natives, regionMap)
global.version = constants.VERSION_18
end
if (global.version < constants.VERSION_20) then
natives.aiPointsScaler = settings.global["rampant-aiPointsScaler"].value
natives.aiNocturnalMode = settings.global["rampant-permanentNocturnal"].value
game.surfaces[1].print("Rampant - Version 0.15.8")
global.version = constants.VERSION_20
end
if (global.version < constants.VERSION_21) then
game.surfaces[1].print("Rampant - Version 0.15.9")
global.version = constants.VERSION_21
end
if (global.version < constants.VERSION_22) then
-- been made redundant
natives.rallyCries = nil
-- switched over to tick event
regionMap.logicTick = roundToNearest(game.tick + INTERVAL_LOGIC, INTERVAL_LOGIC)
regionMap.processTick = roundToNearest(game.tick + INTERVAL_PROCESS, INTERVAL_PROCESS)
-- needs to be on inner logic tick loop interval
natives.stateTick = roundToNearest(game.tick + INTERVAL_LOGIC, INTERVAL_LOGIC)
natives.temperamentTick = roundToNearest(game.tick + INTERVAL_LOGIC, INTERVAL_LOGIC)
game.map_settings.path_finder.short_request_ratio = 0.8
game.map_settings.path_finder.short_cache_size = 25
game.map_settings.path_finder.long_cache_size = 5
game.map_settings.path_finder.min_steps_to_check_path_find_termination = 300
game.map_settings.max_failed_behavior_count = 6
--[[
For making changes to maps that haven't had Rampant loaded and aren't starting from a brand new map
Was causing desyncs when client connected before having the below settings saved into the map
--]]
local mapSettings = game.map_settings
mapSettings.path_finder.short_request_ratio = constants.PATH_FINDER_SHORT_REQUEST_RATIO
mapSettings.path_finder.short_cache_size = constants.PATH_FINDER_SHORT_CACHE_SIZE
mapSettings.path_finder.long_cache_size = constants.PATH_FINDER_LONG_REQUEST_RATIO
mapSettings.path_finder.min_steps_to_check_path_find_termination = constants.PATH_FINDER_MIN_STEPS_TO_CHECK_PATH
mapSettings.max_failed_behavior_count = constants.MAX_FAILED_BEHAVIORS
mapSettings.unit_group.member_disown_distance = constants.UNIT_GROUP_DISOWN_DISTANCE
mapSettings.unit_group.tick_tolerance_when_member_arrives = constants.UNIT_GROUP_TICK_TOLERANCE
mapSettings.unit_group.max_group_radius = constants.UNIT_GROUP_MAX_RADIUS
mapSettings.unit_group.max_member_speedup_when_behind = constants.UNIT_GROUP_MAX_SPEED_UP
mapSettings.unit_group.max_member_slowdown_when_ahead = constants.UNIT_GROUP_MAX_SLOWDOWN
mapSettings.unit_group.max_group_slowdown_factor = constants.UNIT_GROUP_SLOWDOWN_FACTOR
game.surfaces[1].print("Rampant - Version 0.15.10")
global.version = constants.VERSION_22
end

View File

@ -53,7 +53,6 @@ local squadBeginAttack = aiAttack.squadBeginAttack
local retreatUnits = aiDefense.retreatUnits
-- local regenerateEntity = entityUtils.regenerateEntity
local addRemoveEntity = entityUtils.addRemoveEntity
local makeImmortalEntity = entityUtils.makeImmortalEntity
@ -80,7 +79,7 @@ local function onChunkGenerated(event)
end
local function onModSettingsChange(event)
if event and (string.sub(event.setting, 1, 7) ~= "rampant") then
return
end
@ -112,6 +111,7 @@ local function onModSettingsChange(event)
end
local function onConfigChanged()
if upgrade.attempt(natives, regionMap) then
onModSettingsChange(nil)
@ -132,7 +132,7 @@ local function onConfigChanged()
area = { left_top = { x = chunk.x * 32,
y = chunk.y * 32 }}})
end
end
end
end
local function onTick(event)
@ -142,7 +142,7 @@ local function onTick(event)
local surface = game.surfaces[1]
local evolutionFactor = game.forces.enemy.evolution_factor
local players = game.players
processPendingChunks(natives, regionMap, surface, pendingChunks)
scanMap(regionMap, surface, natives, evolutionFactor)
@ -150,17 +150,16 @@ local function onTick(event)
regionMap.logicTick = regionMap.logicTick + INTERVAL_LOGIC
planning(natives, evolutionFactor, tick, surface)
cleanSquads(natives, evolutionFactor)
-- regroupSquads(natives, evolutionFactor)
regroupSquads(natives, evolutionFactor)
processPlayers(players, regionMap, surface, natives, evolutionFactor, tick)
squadBeginAttack(natives, players, evolutionFactor)
squadAttack(regionMap, surface, natives)
end
processMap(regionMap, surface, natives, evolutionFactor)
processMap(regionMap, surface, natives, evolutionFactor)
end
end
@ -187,12 +186,12 @@ local function onDeath(event)
local entityPosition = entity.position
local deathChunk = getChunkByPosition(regionMap, entityPosition.x, entityPosition.y)
if (deathChunk ~= nil) then
if deathChunk then
-- drop death pheromone where unit died
deathScent(deathChunk)
if ((event.force ~= nil) and (event.force.name == "player")) then
local evolutionFactor = game.forces.enemy.evolution_factor
local evolutionFactor = entity.force.evolution_factor
local tick = event.tick
if (deathChunk[MOVEMENT_PHEROMONE] < -(evolutionFactor * RETREAT_MOVEMENT_PHEROMONE_LEVEL)) then
@ -216,7 +215,6 @@ local function onDeath(event)
end
end
-- removeScout(entity, natives)
elseif (entity.type == "unit-spawner") or (entity.type == "turret") then
addRemoveEntity(regionMap, entity, natives, false, false)
end
@ -226,7 +224,9 @@ local function onDeath(event)
if (event.force ~= nil) and (event.force.name == "enemy") then
creditNatives = true
local victoryChunk = getChunkByPosition(regionMap, entityPosition.x, entityPosition.y)
victoryScent(victoryChunk, entity.type)
if victoryChunk then
victoryScent(victoryChunk, entity.type)
end
end
if creditNatives and natives.safeBuildings and (natives.safeEntities[entity.type] or natives.safeEntityName[entity.name]) then
makeImmortalEntity(surface, entity)

View File

@ -1,6 +1,7 @@
local vanillaUpdates = require("prototypes/enemies/UpdatesVanilla")
local bobsUpdates = require("prototypes/enemies/UpdatesBobs")
local NEUpdates = require("prototypes/enemies/UpdatesNE")
local constants = require("libs/Constants")
local function bobsDetected()
return data.raw["turret"]["bob-big-explosive-worm-turret"] ~= nil
@ -25,6 +26,26 @@ if settings.startup["rampant-useDumbProjectiles"].value then
end
end
--[[
try to make sure new maps use the correct map settings without having to completely load the mod.
done because seeing desync issues with dynamic map-settings changes before re-saving the map.
--]]
local mapSettings = data.raw["map-settings"]["map-settings"]
mapSettings.path_finder.short_request_ratio = constants.PATH_FINDER_SHORT_REQUEST_RATIO
mapSettings.path_finder.short_cache_size = constants.PATH_FINDER_SHORT_CACHE_SIZE
mapSettings.path_finder.long_cache_size = constants.PATH_FINDER_LONG_REQUEST_RATIO
mapSettings.path_finder.min_steps_to_check_path_find_termination = constants.PATH_FINDER_MIN_STEPS_TO_CHECK_PATH
mapSettings.max_failed_behavior_count = constants.MAX_FAILED_BEHAVIORS
mapSettings.unit_group.member_disown_distance = constants.UNIT_GROUP_DISOWN_DISTANCE
mapSettings.unit_group.tick_tolerance_when_member_arrives = constants.UNIT_GROUP_TICK_TOLERANCE
mapSettings.unit_group.max_group_radius = constants.UNIT_GROUP_MAX_RADIUS
mapSettings.unit_group.max_member_speedup_when_behind = constants.UNIT_GROUP_MAX_SPEED_UP
mapSettings.unit_group.max_member_slowdown_when_ahead = constants.UNIT_GROUP_MAX_SLOWDOWN
mapSettings.unit_group.max_group_slowdown_factor = constants.UNIT_GROUP_SLOWDOWN_FACTOR

View File

@ -20,6 +20,14 @@ local SQUAD_GUARDING = constants.SQUAD_GUARDING
local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
local ENEMY_BASE_GENERATOR = constants.ENEMY_BASE_GENERATOR
local DEFINES_GROUP_FINISHED = defines.group_state.finished
local DEFINES_GROUP_GATHERING = defines.group_state.gathering
local DEFINES_GROUP_MOVING = defines.group_state.moving
local DEFINES_GROUP_ATTACKING_DISTRACTION = defines.group_state.attacking_distraction
local DEFINES_GROUP_ATTACKING_TARGET = defines.group_state.attacking_target
local DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
local DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
-- imported functions
local getNeighborChunksWithDirection = mapUtils.getNeighborChunksWithDirection
@ -52,21 +60,43 @@ function aiAttack.squadAttack(regionMap, surface, natives)
local squads = natives.squads
local attackPosition
local attackCmd
--[[
Constants populated by the factorio runtime
--]]
-- local DEFINES_GROUP_FINISHED
-- local DEFINES_GROUP_GATHERING
-- local DEFINES_GROUP_MOVING
-- local DEFINES_GROUP_ATTACKING_DISTRACTION
-- local DEFINES_GROUP_ATTACKING_TARGET
-- local DEFINES_DISTRACTION_BY_ENEMY
-- local DEFINES_DISTRACTION_BY_ANYTHING
if (#squads > 0) then
-- DEFINES_GROUP_FINISHED = defines.group_state.finished
-- DEFINES_GROUP_GATHERING = defines.group_state.gathering
-- DEFINES_GROUP_MOVING = defines.group_state.moving
-- DEFINES_GROUP_ATTACKING_DISTRACTION = defines.group_state.attacking_distraction
-- DEFINES_GROUP_ATTACKING_TARGET = defines.group_state.attacking_target
-- DEFINES_DISTRACTION_BY_ENEMY = defines.distraction.by_enemy
-- DEFINES_DISTRACTION_BY_ANYTHING = defines.distraction.by_anything
attackPosition = {x=0, y=0}
attackCmd = { type = defines.command.attack_area,
destination = attackPosition,
radius = 28,
distraction = defines.distraction.by_enemy }
distraction = DEFINES_DISTRACTION_BY_ENEMY }
end
for i=1,#squads do
local squad = squads[i]
local group = squad.group
if group.valid and (squad.status == SQUAD_RAIDING) then
local groupState = group.state
if (groupState == defines.group_state.finished) or (groupState == defines.group_state.gathering) or ((groupState == defines.group_state.moving) and (squad.cycles == 0)) then
local chunk = getChunkByPosition(regionMap, group.position.x, group.position.y)
if (chunk ~= nil) then
if (groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING) or ((groupState == DEFINES_GROUP_MOVING) and (squad.cycles == 0)) then
local groupPosition = group.position
local chunk = getChunkByPosition(regionMap, groupPosition.x, groupPosition.y)
if chunk then
local attackChunk, attackDirection = scoreNeighborsWithDirection(chunk,
getNeighborChunksWithDirection(regionMap, chunk.cX, chunk.cY),
validLocation,
@ -78,9 +108,9 @@ function aiAttack.squadAttack(regionMap, surface, natives)
addSquadMovementPenalty(squad, chunk.cX, chunk.cY)
if attackChunk then
if (attackChunk[PLAYER_BASE_GENERATOR] == 0) or
((groupState == defines.group_state.finished) or (groupState == defines.group_state.gathering)) then
((groupState == DEFINES_GROUP_FINISHED) or (groupState == DEFINES_GROUP_GATHERING)) then
positionFromDirectionAndChunk(attackDirection, squad.group.position, attackPosition)
positionFromDirectionAndChunk(attackDirection, groupPosition, attackPosition)
if (#squad.group.members > 80) then
squad.cycles = 6
@ -88,24 +118,24 @@ function aiAttack.squadAttack(regionMap, surface, natives)
squad.cycles = 4
end
if not squad.rabid and squad.frenzy and (euclideanDistanceNamed(squad.group.position, squad.frenzyPosition) > 100) then
if not squad.rabid and squad.frenzy and (euclideanDistanceNamed(groupPosition, squad.frenzyPosition) > 100) then
squad.frenzy = false
end
if squad.rabid or squad.frenzy then
attackCmd.distraction = defines.distraction.by_anything
attackCmd.distraction = DEFINES_DISTRACTION_BY_ANYTHING
else
attackCmd.distraction = defines.distraction.by_enemy
attackCmd.distraction = DEFINES_DISTRACTION_BY_ENEMY
end
group.set_command(attackCmd)
group.start_moving()
elseif not squad.frenzy and not squad.rabid and
((groupState == defines.group_state.attacking_distraction) or (groupState == defines.group_state.attacking_target) or
((groupState == DEFINES_GROUP_ATTACKING_DISTRACTION) or (groupState == DEFINES_GROUP_ATTACKING_TARGET) or
(attackChunk[PLAYER_BASE_GENERATOR] ~= 0)) then
squad.frenzy = true
squad.frenzyPosition.x = squad.group.position.x
squad.frenzyPosition.y = squad.group.position.y
squad.frenzyPosition.x = groupPosition.x
squad.frenzyPosition.y = groupPosition.y
end
end
end

View File

@ -6,7 +6,6 @@ local constants = require("Constants")
local mapUtils = require("MapUtils")
local unitGroupUtils = require("UnitGroupUtils")
local neighborUtils = require("NeighborUtils")
local nocturnalUtils = require("NocturnalUtils")
package.path = "../?.lua;" .. package.path
local config = require("config")
@ -31,7 +30,10 @@ local CHUNK_SIZE = constants.CHUNK_SIZE
local NORTH_SOUTH_PASSABLE = constants.NORTH_SOUTH_PASSABLE
local EAST_WEST_PASSABLE = constants.EAST_WEST_PASSABLE
local RALLY_CRY_DISTANCE = 3
local RALLY_CRY_DISTANCE = constants.RALLY_CRY_DISTANCE
local DEFINES_COMMAND_GROUP = defines.command.group
local DEFINES_DISTRACTION_NONE = defines.distraction.none
-- imported functions
@ -41,8 +43,6 @@ local scoreNeighbors = neighborUtils.scoreNeighbors
local createSquad = unitGroupUtils.createSquad
local attackWaveScaling = config.attackWaveScaling
local canAttackNocturnal = nocturnalUtils.canAttack
local mMax = math.max
-- module code
@ -52,7 +52,7 @@ local function attackWaveValidCandidate(chunk, natives, surface, evolutionFactor
if natives.attackUsePlayer then
local playerPheromone = chunk[PLAYER_PHEROMONE]
if (playerPheromone > natives.attackPlayerThreshold) then
if (playerPheromone > natives.attackPlayerThreshold) and (playerPheromone > 0) then
total = total + chunk[PLAYER_PHEROMONE]
end
end
@ -78,52 +78,6 @@ local function validUnitGroupLocation(x, chunk, neighborChunk)
return neighborChunk[NORTH_SOUTH_PASSABLE] and neighborChunk[EAST_WEST_PASSABLE] and neighborChunk[ENEMY_BASE_GENERATOR] == 0
end
-- function aiBuilding.removeScout(entity, natives)
-- --[[
-- local scouts = natives.scouts
-- for i=1, #scouts do
-- local scout = scouts[i]
-- if (scout == entity) then
-- tableRemove(scouts, i)
-- return
-- end
-- end
-- --]]
-- end
-- function aiBuilding.makeScouts(surface, natives, chunk, evolution_factor)
-- --[[
-- if (natives.points > AI_SCOUT_COST) then
-- if (#global.natives.scouts < 5) and (math.random() < 0.05) then -- TODO scaled with evolution factor
-- local enemy = surface.find_nearest_enemy({ position = { x = chunk.pX + HALF_CHUNK_SIZE,
-- y = chunk.pY + HALF_CHUNK_SIZE },
-- max_distance = 100})
-- if (enemy ~= nil) and enemy.valid and (enemy.type == "unit") then
-- natives.points = natives.points - AI_SCOUT_COST
-- global.natives.scouts[#global.natives.scouts+1] = enemy
-- -- print(enemy, enemy.unit_number)
-- end
-- end
-- end
-- --]]
-- end
-- function aiBuilding.scouting(regionMap, natives)
-- --[[
-- local scouts = natives.scouts
-- for i=1,#scouts do
-- local scout = scouts[i]
-- if scout.valid then
-- scout.set_command({type=defines.command.attack_area,
-- destination={0,0},
-- radius=32,
-- distraction=defines.distraction.none})
-- end
-- end
-- --]]
-- end
function aiBuilding.rallyUnits(chunk, regionMap, surface, natives, evolutionFactor, tick)
if (tick - chunk[RALLY_TRIGGERED] > INTERVAL_LOGIC) then
chunk[RALLY_TRIGGERED] = tick
@ -132,7 +86,7 @@ function aiBuilding.rallyUnits(chunk, regionMap, surface, natives, evolutionFact
for x=cX - RALLY_CRY_DISTANCE, cX + RALLY_CRY_DISTANCE do
for y=cY - RALLY_CRY_DISTANCE, cY + RALLY_CRY_DISTANCE do
local rallyChunk = getChunkByIndex(regionMap, x, y)
if (rallyChunk ~= nil) and (x ~= cX) and (y ~= cY) and (rallyChunk[ENEMY_BASE_GENERATOR] ~= 0) then
if rallyChunk and (x ~= cX) and (y ~= cY) and (rallyChunk[ENEMY_BASE_GENERATOR] ~= 0) then
aiBuilding.formSquads(regionMap, surface, natives, rallyChunk, evolutionFactor, AI_VENGENCE_SQUAD_COST)
end
end
@ -171,9 +125,9 @@ function aiBuilding.formSquads(regionMap, surface, natives, chunk, evolution_fac
end
local scaledWaveSize = attackWaveScaling(evolution_factor, natives)
local foundUnits = surface.set_multi_command({ command = { type = defines.command.group,
local foundUnits = surface.set_multi_command({ command = { type = DEFINES_COMMAND_GROUP,
group = squad.group,
distraction = defines.distraction.none },
distraction = DEFINES_DISTRACTION_NONE },
unit_count = scaledWaveSize,
unit_search_distance = (CHUNK_SIZE * 3)})
if (foundUnits > 0) then

View File

@ -20,6 +20,8 @@ local AI_MIN_TEMPERAMENT_DURATION = constants.AI_MIN_TEMPERAMENT_DURATION
local AI_MAX_STATE_DURATION = constants.AI_MAX_STATE_DURATION
local AI_MAX_TEMPERAMENT_DURATION = constants.AI_MAX_TEMPERAMENT_DURATION
local AI_MAX_SQUAD_COUNT = constants.AI_MAX_SQUAD_COUNT
local TICKS_A_MINUTE = constants.TICKS_A_MINUTE
-- imported functions
@ -38,12 +40,6 @@ function aiPlanning.planning(natives, evolution_factor, tick, surface)
maxPoints = maxPoints * 0.85
end
if (natives.points < maxPoints) then
--[[ check for ai points scaler being nil, potential race condition with mod config being run
discovered 0.15.8
--]]
-- if not natives.aiPointsScaler then
-- natives.aiPointsScaler = settings.global["rampant-aiPointsScaler"].value
-- end
natives.points = natives.points + math.floor((AI_POINT_GENERATOR_AMOUNT * math.random()) + ((AI_POINT_GENERATOR_AMOUNT * 0.7) * (evolution_factor ^ 2.5)) * natives.aiPointsScaler)
end
@ -64,7 +60,7 @@ function aiPlanning.planning(natives, evolution_factor, tick, surface)
natives.stateTick = randomTickEvent(tick, AI_MIN_STATE_DURATION, AI_MAX_STATE_DURATION)
end
if ((natives.state == AI_STATE_AGGRESSIVE) or canAttackNocturnal(natives, surface)) and (tick - natives.lastShakeMessage > TICKS_A_MINUTE * 5) and (natives.points > AI_MAX_POINTS) then
if ((natives.state == AI_STATE_AGGRESSIVE) or canAttackNocturnal(natives, surface)) and (tick - natives.lastShakeMessage > TICKS_A_MINUTE * 5) and ((evolution_factor > 0.7) and (natives.points > maxPoints * 0.85) and (#natives.squads > AI_MAX_SQUAD_COUNT * 0.35)) then
natives.lastShakeMessage = tick
surface.print("Rampant: The ground begins to shake")
end

View File

@ -154,6 +154,23 @@ constants.BUILDING_PHEROMONES["turret"] = 2.5
constants.retreatFilter = {}
constants.retreatFilter[constants.SQUAD_RETREATING] = true
-- map settings tweaks
constants.PATH_FINDER_SHORT_REQUEST_RATIO = 0.8
constants.PATH_FINDER_SHORT_CACHE_SIZE = 25
constants.PATH_FINDER_LONG_REQUEST_RATIO = 5
constants.PATH_FINDER_MIN_STEPS_TO_CHECK_PATH = 300
constants.MAX_FAILED_BEHAVIORS = 6
constants.UNIT_GROUP_DISOWN_DISTANCE = 5
constants.UNIT_GROUP_TICK_TOLERANCE = 80
constants.UNIT_GROUP_MAX_RADIUS = 20
constants.UNIT_GROUP_MAX_SPEED_UP = 1.1
constants.UNIT_GROUP_MAX_SLOWDOWN = 1.0
constants.UNIT_GROUP_SLOWDOWN_FACTOR = 0.9
return constants
--[[

View File

@ -14,7 +14,9 @@ local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
local ENEMY_BASE_PHEROMONE_GENERATOR_AMOUNT = constants.ENEMY_BASE_PHEROMONE_GENERATOR_AMOUNT
local CHUNK_SIZE = constants.CHUNK_SIZE
local DEFINES_DIRECTION_EAST = defines.direction.east
local DEFINES_WIRE_TYPE_RED = defines.wire_type.red
local DEFINES_WIRE_TYPE_GREEN = defines.wire_type.green
-- imported functions
@ -40,7 +42,7 @@ local function getEntityOverlapChunks(regionMap, entity)
local bottomXOffset
local bottomYOffset
if (entity.direction == defines.direction.east) then
if (entity.direction == DEFINES_DIRECTION_EAST) then
topXOffset = boundingBox.left_top.y
topYOffset = boundingBox.left_top.x
bottomXOffset = boundingBox.right_bottom.y
@ -140,11 +142,11 @@ function entityUtils.makeImmortalEntity(surface, entity)
end
elseif connectType == "red" then
for _,v in pairs(neighbourGroup) do
newEntity.connect_neighbour({wire = defines.wire_type.red, target_entity = v});
newEntity.connect_neighbour({wire = DEFINES_WIRE_TYPE_RED, target_entity = v});
end
elseif connectType == "green" then
for _,v in pairs(neighbourGroup) do
newEntity.connect_neighbour({wire = defines.wire_type.green, target_entity = v});
newEntity.connect_neighbour({wire = DEFINES_WIRE_TYPE_GREEN, target_entity = v});
end
end
end

View File

@ -21,7 +21,6 @@ local AI_UNIT_REFUND = constants.AI_UNIT_REFUND
local CHUNK_SIZE = constants.CHUNK_SIZE
local ENEMY_BASE_GENERATOR = constants.ENEMY_BASE_GENERATOR
local AI_STATE_AGGRESSIVE = constants.AI_STATE_AGGRESSIVE
local AI_STATE_NOCTURNAL = constants.AI_STATE_NOCTURNAL
local PROCESS_PLAYER_BOUND = constants.PROCESS_PLAYER_BOUND
local CHUNK_TICK = constants.CHUNK_TICK
@ -78,16 +77,13 @@ end
function mapProcessor.processMap(regionMap, surface, natives, evolution_factor)
local roll = regionMap.processRoll
local index = regionMap.processPointer
local squads = false
if (index == 1) then
roll = math.random()
regionMap.processRoll = roll
end
if ((natives.state == AI_STATE_AGGRESSIVE) or canAttackNocturnal(natives, surface)) and (0.11 <= roll) and (roll <= 0.35) then
squads = true
end
local squads = ((natives.state == AI_STATE_AGGRESSIVE) or canAttackNocturnal(natives, surface)) and (0.11 <= roll) and (roll <= 0.35)
local processQueue = regionMap.processQueue
local endIndex = mMin(index + PROCESS_QUEUE_SIZE, #processQueue)
@ -121,13 +117,10 @@ function mapProcessor.processPlayers(players, regionMap, surface, natives, evolu
-- randomize player order to ensure a single player isn't singled out
local playerOrdering = nonRepeatingRandom(players)
local squads = false
local vengenceThreshold = -(evolution_factor * RETREAT_MOVEMENT_PHEROMONE_LEVEL)
local roll = math.random()
if ((natives.state == AI_STATE_AGGRESSIVE) or canAttackNocturnal(natives, surface)) and (0.11 <= roll) and (roll <= 0.20) then
squads = true
end
local squads = ((natives.state == AI_STATE_AGGRESSIVE) or canAttackNocturnal(natives, surface)) and (0.11 <= roll) and (roll <= 0.20)
for i=1,#playerOrdering do
local player = players[playerOrdering[i]]
@ -135,7 +128,7 @@ function mapProcessor.processPlayers(players, regionMap, surface, natives, evolu
local playerPosition = player.character.position
local playerChunk = getChunkByPosition(regionMap, playerPosition.x, playerPosition.y)
if (playerChunk ~= nil) then
if playerChunk then
playerScent(playerChunk)
end
end
@ -146,17 +139,14 @@ function mapProcessor.processPlayers(players, regionMap, surface, natives, evolu
local playerPosition = player.character.position
local playerChunk = getChunkByPosition(regionMap, playerPosition.x, playerPosition.y)
if (playerChunk ~= nil) then
local vengence = false
if ((playerChunk[ENEMY_BASE_GENERATOR] ~= 0) or (playerChunk[MOVEMENT_PHEROMONE] < vengenceThreshold)) and
(natives.state == AI_STATE_AGGRESSIVE or canAttackNocturnal(natives, surface)) then
vengence = true
end
if playerChunk then
local vengence = ((playerChunk[ENEMY_BASE_GENERATOR] ~= 0) or (playerChunk[MOVEMENT_PHEROMONE] < vengenceThreshold)) and
(natives.state == AI_STATE_AGGRESSIVE or canAttackNocturnal(natives, surface))
for x=playerChunk.cX - PROCESS_PLAYER_BOUND, playerChunk.cX + PROCESS_PLAYER_BOUND do
for y=playerChunk.cY - PROCESS_PLAYER_BOUND, playerChunk.cY + PROCESS_PLAYER_BOUND do
local chunk = getChunkByIndex(regionMap, x, y)
if (chunk ~= nil) and (chunk[CHUNK_TICK] ~= tick) then
if chunk and (chunk[CHUNK_TICK] ~= tick) then
chunk[CHUNK_TICK] = tick
processPheromone(regionMap, chunk)
@ -223,7 +213,7 @@ function mapProcessor.scanMap(regionMap, surface, natives, evolution_factor)
if (unitCount > 300) then
for i=1,#natives.squads do
local squadGroup = natives.squads[i].group
if (euclideanDistanceNamed(squadGroup.position, chunkPosition) < CHUNK_SIZE * 2) then
if squadGroup.valid and (euclideanDistanceNamed(squadGroup.position, chunkPosition) < CHUNK_SIZE * 2) then
closeBy = true
end
end

View File

@ -9,9 +9,9 @@ local constants = require("Constants")
local MOVEMENT_PHEROMONE_GENERATOR_AMOUNT = constants.MOVEMENT_PHEROMONE_GENERATOR_AMOUNT
local GROUP_STATE_FINISHED = defines.group_state.finished
local GROUP_STATE_ATTACKING_TARGET = defines.group_state.attacking_target
local GROUP_STATE_ATTACKING_DISTRACTION = defines.group_state.attacking_distraction
local DEFINES_GROUP_STATE_FINISHED = defines.group_state.finished
local DEFINES_GROUP_STATE_ATTACKING_TARGET = defines.group_state.attacking_target
local DEFINES_GROUP_STATE_ATTACKING_DISTRACTION = defines.group_state.attacking_distraction
local SQUAD_RETREATING = constants.SQUAD_RETREATING
local SQUAD_GUARDING = constants.SQUAD_GUARDING
@ -142,7 +142,7 @@ end
local function isAttacking(group)
local state = group.state
return (state == GROUP_STATE_ATTACKING_TARGET) or (state == GROUP_STATE_ATTACKING_DISTRACTION)
return (state == DEFINES_GROUP_STATE_ATTACKING_TARGET) or (state == DEFINES_GROUP_STATE_ATTACKING_DISTRACTION)
end
function unitGroupUtils.cleanSquads(natives, evolution_factor)
@ -180,7 +180,7 @@ function unitGroupUtils.cleanSquads(natives, evolution_factor)
squad.frenzy = true
squad.frenzyPosition.x = squadPosition.x
squad.frenzyPosition.y = squadPosition.y
elseif (group.state == GROUP_STATE_FINISHED) then
elseif (group.state == DEFINES_GROUP_STATE_FINISHED) then
squad.status = SQUAD_GUARDING
elseif (cycles > 0) then
squad.cycles = cycles - 1

View File

@ -5,7 +5,7 @@
(require json)
(define modFolder "/home/veden/.factorio/mods/")
;; (define zipModFolder "/data/games/factorio14.18/mods/")
(define zipModFolder "/data/games/factorio15.15/mods/")
(define configuration (call-with-input-file "info.json"
(lambda (port)
(string->jsexpr (port->string port)))))
@ -77,7 +77,8 @@
(copyDirectory "prototypes" modFolder)))
(define (run)
(copyFiles modFolder)
;;(makeZip modFolder)
;; (copyFiles modFolder)
;; (copyFiles zipModFolder)
(makeZip modFolder)
)
)