1
0
mirror of https://github.com/veden/Rampant.git synced 2025-01-28 03:29:34 +02:00

see changelog

This commit is contained in:
Aaron Veden 2021-04-29 22:24:14 -07:00
parent 8e46e96667
commit f7c99d03ab
No known key found for this signature in database
GPG Key ID: FF5990B1C6DD3F84
15 changed files with 145 additions and 18948 deletions

View File

@ -397,8 +397,21 @@ function upgrade.attempt(universe)
universe.squadCount = 0
addCommandSet(universe)
end
if global.version < 116 then
global.version = 116
game.print("Rampant - Version 1.0.8")
universe.maxPoints = 0
if (universe.maps) then
for _,map in pairs(universe.maps) do
for _,base in pairs(map.bases) do
base.damagedBy = {}
end
end
end
game.print("Rampant - Version 1.0.10")
end
return (starting ~= global.version) and global.version

View File

@ -1,3 +1,23 @@
---------------------------------------------------------------------------------------------------
Version: 1.0.10
Date: 29. 04. 2021
Features:
- Added new enemies adaptation to damage type that kills them. So if you kill biters with physical damage you will start seeing biters that are resistant to physical damage.
Improvements:
- Increased ai baseline point accumulation based on temperament
Tweaks:
- Increased spitter and worm projectile size by 20%
- Decreased spitter and worm projectile speed by ~40%
- Increased baseline ai point accumulation for active nests by x3
- Increased baseline ai point accumulation at min and max temperament by 0.2
- Increased raid nest contribution to temperament by x2.7
- Increased siege chance at max ai temperament by 25%
- Decreased settler cost to ai by 33%
- Increased base ai min and max duration by ~x1.8
Bugfixes:
- Settlers not spawning as they should do to incorrect weighting on spawn locations
- Fixed new enemies factions not mutating or upgrading structures overtime
---------------------------------------------------------------------------------------------------
Version: 1.0.9
Date: 21. 04. 2021

View File

@ -335,7 +335,6 @@ local function prepMap(surface)
map.squads = nil
map.pendingAttack = nil
map.building = nil
map.groupNumberToSquad = {}
map.evolutionLevel = game.forces.enemy.evolution_factor
map.canAttackTick = 0
@ -406,8 +405,11 @@ local function onConfigChanged()
universe.buildingHiveTypeLookup["behemoth-worm-turret"] = "turret"
end
if version and (version <= 114) then
for _,surface in pairs(game.surfaces) do
for _,surface in pairs(game.surfaces) do
if not universe.maps then
universe.maps = {}
end
if not universe.maps[surface.index] then
prepMap(surface)
end
end
@ -465,6 +467,18 @@ local function onDeath(event)
if (entityType == "unit") then
if (chunk ~= -1) and event.force and (event.force.name ~= "enemy") then
local group = entity.unit_group
if group then
local damageType = event.damage_type
local squad = map.groupNumberToSquad[group.group_number]
if squad then
local base = squad.base
if base then
base.damagedBy[damageType] = (base.damagedBy[damageType] or 0) + 0.01
end
end
end
-- drop death pheromone where unit died
deathScent(map, chunk)
@ -488,7 +502,7 @@ local function onDeath(event)
map.points = map.points +
(((entityType == "unit-spawner") and RECOVER_NEST_COST) or RECOVER_WORM_COST)
unregisterEnemyBaseStructure(map, entity)
unregisterEnemyBaseStructure(map, entity, event.damage_type)
if (chunk ~= -1) then
rallyUnits(chunk, map, tick)
@ -804,6 +818,13 @@ local function onUnitGroupCreated(event)
squad = createSquad(nil, nil, group, settler)
map.groupNumberToSquad[group.group_number] = squad
if universe.NEW_ENEMIES then
local chunk = getChunkByPosition(map, group.position)
if (chunk ~= -1) then
squad.base = findNearbyBase(map, chunk)
end
end
if settler then
universe.builderCount = universe.builderCount + 1
else
@ -828,6 +849,14 @@ local function onUnitGroupCreated(event)
squad = createSquad(nil, nil, group, settler)
map.groupNumberToSquad[group.group_number] = squad
if universe.NEW_ENEMIES then
local chunk = getChunkByPosition(group.position)
if (chunk ~= -1) then
squad.base = findNearbyBase(map, chunk)
end
end
if settler then
universe.builderCount = universe.builderCount + 1
else

View File

@ -1,7 +1,7 @@
{
"name" : "Rampant",
"factorio_version" : "1.1",
"version" : "1.0.9",
"version" : "1.0.10",
"title" : "Rampant",
"author" : "Veden",
"homepage" : "https://forums.factorio.com/viewtopic.php?f=94&t=31445",

View File

@ -12,6 +12,7 @@ local unitGroupUtils = require("UnitGroupUtils")
local movementUtils = require("MovementUtils")
local mathUtils = require("MathUtils")
local config = require("__Rampant__/config")
local baseUtils = require("BaseUtils")
-- constants
@ -35,14 +36,14 @@ local CHUNK_SIZE = constants.CHUNK_SIZE
local RALLY_CRY_DISTANCE = constants.RALLY_CRY_DISTANCE
local RESOURCE_MINIMUM_FORMATION_DELTA = constants.RESOURCE_MINIMUM_FORMATION_DELTA
local AI_STATE_SIEGE = constants.AI_STATE_SIEGE
local AI_STATE_RAIDING = constants.AI_STATE_RAIDING
-- imported functions
local findNearbyBase = baseUtils.findNearbyBase
local randomTickEvent = mathUtils.randomTickEvent
local calculateKamikazeThreshold = unitGroupUtils.calculateKamikazeThreshold
@ -107,7 +108,7 @@ local function validSettlerLocation(map, chunk, neighborChunk)
local chunkResource = chunk[RESOURCE_PHEROMONE]
return (getPassable(map, neighborChunk) == CHUNK_ALL_DIRECTIONS) and
(getNestCount(map, neighborChunk) == 0) and
(neighborChunk[RESOURCE_PHEROMONE] >= (chunkResource * RESOURCE_MINIMUM_FORMATION_DELTA))
(neighborChunk[RESOURCE_PHEROMONE] >= chunkResource)
end
local function validUnitGroupLocation(map, neighborChunk)
@ -224,6 +225,9 @@ function aiAttackWave.formSettlers(map, chunk)
universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(universe.formCommand)
if (foundUnits > 0) then
if universe.NEW_ENEMIES then
squad.base = findNearbyBase(map, chunk)
end
squad.kamikaze = mRandom() < calculateKamikazeThreshold(foundUnits, universe)
universe.builderCount = universe.builderCount + 1
map.points = map.points - AI_SETTLER_COST
@ -268,6 +272,9 @@ function aiAttackWave.formVengenceSquad(map, chunk)
universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(universe.formCommand)
if (foundUnits > 0) then
if universe.NEW_ENEMIES then
squad.base = findNearbyBase(map, chunk)
end
squad.kamikaze = mRandom() < calculateKamikazeThreshold(foundUnits, universe)
map.groupNumberToSquad[squad.groupNumber] = squad
universe.squadCount = universe.squadCount + 1
@ -313,14 +320,17 @@ function aiAttackWave.formSquads(map, chunk, tick)
universe.formCommand.unit_count = scaledWaveSize
local foundUnits = surface.set_multi_command(universe.formCommand)
if (foundUnits > 0) then
if universe.NEW_ENEMIES then
squad.base = findNearbyBase(map, chunk)
end
squad.kamikaze = mRandom() < calculateKamikazeThreshold(foundUnits, universe)
map.points = map.points - AI_SQUAD_COST
universe.squadCount = universe.squadCount + 1
map.groupNumberToSquad[squad.groupNumber] = squad
if tick and (map.state == AI_STATE_AGGRESSIVE) then
map.canAttackTick = randomTickEvent(tick,
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
AGGRESSIVE_CAN_ATTACK_WAIT_MIN_DURATION,
AGGRESSIVE_CAN_ATTACK_WAIT_MAX_DURATION)
end
else
if (squad.group.valid) then

View File

@ -57,6 +57,7 @@ function aiPlanning.planning(map, evolution_factor, tick)
universe.evolutionLevel = evolution_factor
local maxPoints = mMax(AI_MAX_POINTS * evolution_factor, MINIMUM_AI_POINTS)
universe.maxPoints = maxPoints
if not universe.ranIncompatibleMessage and universe.newEnemies and
(game.active_mods["bobenemies"] or game.active_mods["Natural_Evolution_Enemies"]) then
@ -95,13 +96,23 @@ function aiPlanning.planning(map, evolution_factor, tick)
universe.unitRefundAmount = AI_UNIT_REFUND * evolution_factor
universe.kamikazeThreshold = NO_RETREAT_BASE_PERCENT + (evolution_factor * NO_RETREAT_EVOLUTION_BONUS_MAX)
local points = ((AI_POINT_GENERATOR_AMOUNT * mRandom()) + (map.activeNests * 0.001) +
(AI_POINT_GENERATOR_AMOUNT * mMax(evolution_factor ^ 2.5, 0.1))) * universe.aiPointsScaler
local points = ((AI_POINT_GENERATOR_AMOUNT * mRandom()) + (map.activeNests * 0.003) +
(AI_POINT_GENERATOR_AMOUNT * mMax(evolution_factor ^ 2.5, 0.1)))
if (map.temperament < 0.05) or (map.temperament > 0.95) then
points = points + 0.3
elseif (map.temperament < 0.25) or (map.temperament > 0.75) then
points = points + 0.2
elseif (map.temperament < 0.40) or (map.temperament > 0.60) then
points = points + 0.1
end
if (map.state == AI_STATE_ONSLAUGHT) then
points = points * 2
end
points = points * universe.aiPointsScaler
map.baseIncrement = points
local currentPoints = map.points
@ -232,7 +243,7 @@ function aiPlanning.planning(map, evolution_factor, tick)
end
else
if (universe.enabledMigration and universe.raidAIToggle) then
if (roll < 0.2) and universe.siegeAIToggle then
if (roll < 0.25) and universe.siegeAIToggle then
map.state = AI_STATE_SIEGE
elseif (roll < 0.6) then
map.state = AI_STATE_RAIDING
@ -240,7 +251,7 @@ function aiPlanning.planning(map, evolution_factor, tick)
map.state = AI_STATE_ONSLAUGHT
end
elseif (universe.enabledMigration) then
if (roll < 0.2) and universe.siegeAIToggle then
if (roll < 0.25) and universe.siegeAIToggle then
map.state = AI_STATE_SIEGE
else
map.state = AI_STATE_ONSLAUGHT
@ -304,10 +315,10 @@ function aiPlanning.temperamentPlanner(map)
end
if activeRaidNests > 0 then
local val = (0.000221 * activeRaidNests)
local val = (0.0006 * activeRaidNests)
delta = delta - val
else
delta = delta - 0.007232
delta = delta - 0.01
end
if lostEnemyUnits > 0 then

View File

@ -18,8 +18,6 @@ local MAGIC_MAXIMUM_NUMBER = constants.MAGIC_MAXIMUM_NUMBER
local BASE_AI_STATE_DORMANT = constants.BASE_AI_STATE_DORMANT
local BASE_AI_STATE_ACTIVE = constants.BASE_AI_STATE_ACTIVE
local BASE_AI_STATE_WORMS = constants.BASE_AI_STATE_WORMS
local BASE_AI_STATE_NESTS = constants.BASE_AI_STATE_NESTS
local BASE_AI_STATE_OVERDRIVE = constants.BASE_AI_STATE_OVERDRIVE
local BASE_AI_STATE_MUTATE = constants.BASE_AI_STATE_MUTATE
@ -28,9 +26,7 @@ local FACTION_SET = constants.FACTION_SET
local BASE_DEADZONE_TTL = constants.BASE_DEADZONE_TTL
local BASE_AI_MIN_STATE_DURATION = constants.BASE_AI_MIN_STATE_DURATION
local BASE_AI_MIN_TEMPERAMENT_DURATION = constants.BASE_AI_MIN_TEMPERAMENT_DURATION
local BASE_AI_MAX_STATE_DURATION = constants.BASE_AI_MAX_STATE_DURATION
local BASE_AI_MAX_TEMPERAMENT_DURATION = constants.BASE_AI_MAX_TEMPERAMENT_DURATION
local BASE_UPGRADE = constants.BASE_UPGRADE
@ -349,7 +345,7 @@ function baseUtils.processBase(chunk, map, tick, base)
point.x = chunk.x + (CHUNK_SIZE * mRandom())
point.y = chunk.y + (CHUNK_SIZE * mRandom())
if (base.state == BASE_AI_STATE_ACTIVE) then
if (base.state ~= BASE_AI_STATE_MUTATE) then
local entities = surface.find_entities_filtered(universe.filteredEntitiesPointQueryLimited)
if #entities ~= 0 then
local entity = entities[1]
@ -363,7 +359,7 @@ function baseUtils.processBase(chunk, map, tick, base)
end
end
end
elseif (base.state == BASE_AI_STATE_MUTATE) then
else
if (base.points >= BASE_UPGRADE) then
if upgradeBase(map, base) then
base.points = base.points - BASE_UPGRADE
@ -373,34 +369,26 @@ function baseUtils.processBase(chunk, map, tick, base)
if (base.state == BASE_AI_STATE_OVERDRIVE) then
base.points = base.points + (map.baseIncrement * 5)
elseif (base.state ~= BASE_AI_STATE_DORMANT) then
else
base.points = base.points + map.baseIncrement
end
if (base.temperamentTick <= tick) then
base.temperament = mRandom()
base.temperamentTick = randomTickEvent(tick,
BASE_AI_MIN_TEMPERAMENT_DURATION,
BASE_AI_MAX_TEMPERAMENT_DURATION)
if (base.points > universe.maxPoints) then
base.points = universe.maxPoints
end
print(serpent.dump(base.damagedBy))
base.damagedBy = {}
if (base.stateTick <= tick) then
local roll = mRandom() * mMax(1 - map.evolutionLevel, 0.15)
if (roll > map.temperament) then
base.state = BASE_AI_STATE_DORMANT
local roll = mRandom()
if (roll < 0.70) then
base.state = BASE_AI_STATE_ACTIVE
elseif (roll < 0.965) then
base.state = BASE_AI_STATE_OVERDRIVE
else
roll = mRandom()
if (roll < 0.70) then
base.state = BASE_AI_STATE_ACTIVE
elseif (roll < 0.80) then
base.state = BASE_AI_STATE_NESTS
elseif (roll < 0.90) then
base.state = BASE_AI_STATE_WORMS
elseif (roll < 0.975) then
base.state = BASE_AI_STATE_OVERDRIVE
else
base.state = BASE_AI_STATE_MUTATE
end
base.state = BASE_AI_STATE_MUTATE
end
base.stateTick = randomTickEvent(tick,
BASE_AI_MIN_STATE_DURATION,
@ -443,11 +431,10 @@ function baseUtils.createBase(map, chunk, tick, rebuilding)
distanceThreshold = distanceThreshold,
tick = baseTick,
alignment = alignment,
state = BASE_AI_STATE_DORMANT,
state = BASE_AI_STATE_ACTIVE,
damagedBy = {},
stateTick = 0,
temperamentTick = 0,
createdTick = tick,
temperament = 0,
points = 0,
id = map.baseId
}

View File

@ -73,6 +73,7 @@ local createBase = baseUtils.createBase
local upgradeEntity = baseUtils.upgradeEntity
local getChunkBase = chunkPropertyUtils.getChunkBase
local setChunkBase = chunkPropertyUtils.setChunkBase
local setPassable = chunkPropertyUtils.setPassable
local setPathRating = chunkPropertyUtils.setPathRating
@ -469,7 +470,7 @@ function chunkUtils.registerEnemyBaseStructure(map, entity, base)
return entity
end
function chunkUtils.unregisterEnemyBaseStructure(map, entity)
function chunkUtils.unregisterEnemyBaseStructure(map, entity, damageType)
local entityType = entity.type
if ((entityType == "unit-spawner") or (entityType == "turret")) and (entity.force.name == "enemy") then
local overlapArray = getEntityOverlapChunks(map, entity)
@ -520,6 +521,10 @@ function chunkUtils.unregisterEnemyBaseStructure(map, entity)
setNestActiveness(map, chunk, 0)
end
setFunc(map, chunk, 0)
local base = getChunkBase(map, chunk)
if base then
base.damagedBy[damageType] = (base.damagedBy[damageType] or 0) + 1
end
if (getEnemyStructureCount(map, chunk) == 0) then
setChunkBase(map, chunk, nil)
end

View File

@ -121,7 +121,7 @@ constants.AI_SQUAD_COST = 175
constants.RECOVER_NEST_COST = constants.AI_SQUAD_COST
constants.RECOVER_WORM_COST = constants.AI_SQUAD_COST * 0.5
constants.AI_VENGENCE_SQUAD_COST = 45
constants.AI_SETTLER_COST = 400
constants.AI_SETTLER_COST = 300
constants.AI_BASE_BUILDING_COST = 500
constants.AI_TUNNEL_COST = 100
constants.AI_MAX_POINTS = 15500
@ -166,10 +166,8 @@ constants.AI_MAX_STATE_DURATION = 25
constants.AI_MIN_TEMPERAMENT_DURATION = 25
constants.AI_MAX_TEMPERAMENT_DURATION = 32
constants.BASE_AI_MIN_STATE_DURATION = 2
constants.BASE_AI_MAX_STATE_DURATION = 10
constants.BASE_AI_MIN_TEMPERAMENT_DURATION = 5
constants.BASE_AI_MAX_TEMPERAMENT_DURATION = 15
constants.BASE_AI_MIN_STATE_DURATION = 12
constants.BASE_AI_MAX_STATE_DURATION = 20
-- ai base

View File

@ -45,15 +45,6 @@ function mapUtils.getChunkByPosition(map, position)
return -1
end
function mapUtils.getChunkByUnalignedXY(map, x, y)
local chunkX = map[mFloor(x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE]
if chunkX then
local chunkY = mFloor(y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
return chunkX[chunkY] or -1
end
return -1
end
function mapUtils.positionToChunkXY(position)
local chunkX = mFloor(position.x * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE
local chunkY = mFloor(position.y * CHUNK_SIZE_DIVIDER) * CHUNK_SIZE

View File

@ -10,6 +10,7 @@ local mapUtils = require("MapUtils")
local unitGroupUtils = require("UnitGroupUtils")
local movementUtils = require("MovementUtils")
local chunkPropertyUtils = require("ChunkPropertyUtils")
local baseUtils = require("BaseUtils")
-- constants
@ -24,6 +25,8 @@ local COOLDOWN_RETREAT = constants.COOLDOWN_RETREAT
-- imported functions
local findNearbyBase = baseUtils.findNearbyBase
local addSquadToChunk = chunkPropertyUtils.addSquadToChunk
local positionFromDirectionAndFlat = mapUtils.positionFromDirectionAndFlat
@ -112,6 +115,9 @@ function aiDefense.retreatUnits(chunk, cause, map, tick, radius)
end
if created then
if universe.NEW_ENEMIES then
newSquad.base = findNearbyBase(map, chunk)
end
map.groupNumberToSquad[newSquad.groupNumber] = newSquad
universe.squadCount = universe.squadCount + 1
end

View File

@ -81,6 +81,7 @@ function unitGroupUtils.createSquad(position, surface, group, settlers)
status = SQUAD_GUARDING,
rabid = false,
penalties = {},
base = nil,
frenzy = false,
settlers = settlers or false,
kamikaze = false,

File diff suppressed because it is too large Load Diff

View File

@ -1067,7 +1067,7 @@ function biterFunctions.createProjectileAttack(attributes, projectile, animation
projectile_creation_distance = 0.6,
range = attributes.range or 20,
min_attack_distance = (attributes.range and (attributes.range - 2)) or 20,
lead_target_for_projectile_speed = 0.6,
lead_target_for_projectile_speed = 0.95,
use_shooter_direction = true,
ammo_type =
{

View File

@ -1,5 +1,6 @@
local projectileUtils = {}
function projectileUtils.makeProjectile(attributes, attack)
local n = attributes.name .. "-projectile-rampant"
@ -11,7 +12,8 @@ function projectileUtils.makeProjectile(attributes, attack)
collision_mask = attributes.attackCollisionMask or {"layer-13"},
direction_only = attributes.attackDirectionOnly,
piercing_damage = attributes.attackPiercingDamage or 0,
acceleration = attributes.attackAcceleration or 0.02,
acceleration = attributes.attackAcceleration or 0.000001,
max_speed = math.min(math.max(attributes.scale*0.60, 0.4), 0.7),
force_condition = (settings.startup["rampant--disableCollidingProjectiles"].value and "not-same") or nil,
action = attack,
animation =
@ -21,10 +23,10 @@ function projectileUtils.makeProjectile(attributes, attack)
width = 22,
height = 84,
frame_count = 15,
shift = util.mul_shift(util.by_pixel(-2, 30), attributes.scale or 1),
shift = util.mul_shift(util.by_pixel(-2, 30), attributes.scale*1.2 or 1),
tint = attributes.tint2,
priority = "high",
scale = (attributes.scale or 1),
scale = (attributes.scale*1.2 or 1),
animation_speed = 1,
hr_version =
{
@ -33,10 +35,10 @@ function projectileUtils.makeProjectile(attributes, attack)
width = 42,
height = 164,
frame_count = 15,
shift = util.mul_shift(util.by_pixel(-2, 31), attributes.scale or 1),
shift = util.mul_shift(util.by_pixel(-2, 31), attributes.scale*1.2 or 1),
tint = attributes.tint2,
priority = "high",
scale = 0.5 * (attributes.scale or 1),
scale = 0.5 * (attributes.scale*1.2 or 1),
animation_speed = 1,
}
},
@ -48,9 +50,9 @@ function projectileUtils.makeProjectile(attributes, attack)
height = 84,
frame_count = 15,
priority = "high",
shift = util.mul_shift(util.by_pixel(-2, 30), attributes.scale or 1),
shift = util.mul_shift(util.by_pixel(-2, 30), attributes.scale*1.2 or 1),
draw_as_shadow = true,
scale = (attributes.scale or 1),
scale = (attributes.scale*1.2 or 1),
animation_speed = 1,
hr_version =
{
@ -59,10 +61,10 @@ function projectileUtils.makeProjectile(attributes, attack)
width = 42,
height = 164,
frame_count = 15,
shift = util.mul_shift(util.by_pixel(-2, 31), attributes.scale or 1),
shift = util.mul_shift(util.by_pixel(-2, 31), attributes.scale*1.2 or 1),
draw_as_shadow = true,
priority = "high",
scale = 0.5 * (attributes.scale or 1),
scale = 0.5 * (attributes.scale*1.2 or 1),
animation_speed = 1,
}
},