mirror of
https://github.com/veden/Rampant.git
synced 2024-12-26 20:54:12 +02:00
see readme
This commit is contained in:
parent
49a82fcff4
commit
9e361b3c06
19
README.md
19
README.md
@ -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)
|
||||
|
100
Upgrade.lua
100
Upgrade.lua
@ -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
|
||||
|
24
control.lua
24
control.lua
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
--[[
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
7
make.rkt
7
make.rkt
@ -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)
|
||||
)
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user