1
0
mirror of https://github.com/veden/Rampant.git synced 2025-02-03 13:11:54 +02:00

added fire biter prototype logic

This commit is contained in:
veden 2016-08-21 14:48:55 -07:00
parent 15a9fa5d51
commit 7a414e9ade
17 changed files with 290 additions and 208 deletions

View File

@ -3,7 +3,7 @@ Factorio Mod - Uses potential fields to improve the enemy AI
# Recommend Map Settings
Enemy Bases Frequeny:Very Low, Size:Very Big
Enemy Bases Frequeny:Very Low, Size:Big
Everything else is open to what ever you like
# Features

View File

@ -18,22 +18,6 @@ local regionMap -- chunk based map
local pendingChunks -- pending chunks to be processed
local natives -- units that are being commanded
-- initialization
chunkProcessor.install(chunkUtils.checkChunkPassability)
chunkProcessor.install(chunkUtils.scoreChunk)
mapProcessor.install(pheromoneUtils.enemyBaseScent, 0, 1)
mapProcessor.install(pheromoneUtils.playerDefenseScent, 0, 1)
mapProcessor.install(pheromoneUtils.playerBaseScent, 0, 1)
mapProcessor.install(aiBuilding.sendScouts, 0.05, 0.10)
mapProcessor.install(aiBuilding.formSquads, 0.11, 0.25)
mapProcessor.install(pheromoneUtils.processPheromone, 0, 1)
-- constants
local DEATH_PHEROMONE_GENERATOR_AMOUNT = constants.DEATH_PHEROMONE_GENERATOR_AMOUNT
-- imported functions
local processPendingChunks = chunkProcessor.processPendingChunks
@ -43,6 +27,7 @@ local processMap = mapProcessor.processMap
local accumulatePoints = aiBuilding.accumulatePoints
local removeScout = aiBuilding.removeScout
local scouting = aiBuilding.scouting
local digTunnel = aiBuilding.digTunnel
local playerScent = pheromoneUtils.playerScent
local deathScent = pheromoneUtils.deathScent
@ -58,8 +43,6 @@ local retreatUnits = aiDefense.retreatUnits
local addRemoveObject = mapUtils.addRemoveObject
local mRandom = math.random
-- hook functions
function onInit()
@ -127,8 +110,12 @@ function onTick(event)
squadAttackPlayer(regionMap, surface, natives, game.players)
squadBeginAttack(natives)
-- digTunnel(regionMap, surface, natives)
squadAttackLocation(regionMap, surface, natives)
-- print(natives.points)
end
processPendingChunks(regionMap, surface, natives, pendingChunks)
processMap(regionMap, surface, natives, game.evolution_factor)
@ -149,18 +136,13 @@ function onDeath(event)
if (entity.type == "unit") then
local entityPosition = entity.position
-- drop death pheromone where unit died
local squad = convertUnitGroupToSquad(natives, entity.unit_group)
local surface = game.surfaces[1]
deathScent(regionMap,
surface,
entityPosition.x,
entityPosition.y,
squad,
DEATH_PHEROMONE_GENERATOR_AMOUNT)
deathScent(regionMap, surface, entityPosition.x, entityPosition.y)
if (event.force ~= nil) and (event.force.name == "player") then
local squad = convertUnitGroupToSquad(natives, entity.unit_group)
retreatUnits(entityPosition, squad, regionMap, surface, natives)
end
@ -174,7 +156,10 @@ function onDeath(event)
end
function onPutItem(event)
print(serpent.dump(event))
-- local player = game.players[event.player_index]
-- if (player.surface.index==1) then
-- aiBuilding.fillTunnel(global.regionMap, player.surface, global.natives, event.positions)
-- end
end
-- hooks

View File

@ -3,6 +3,8 @@ if RampantConfig == nil then
end
require("prototypes/buildings/tunnel")
require("prototypes/tile/fillableDirt")
require("prototypes/enemies/suicideBiters")
require("prototypes/enemies/suicideBiters")
require("prototypes/enemies/fireSpitters")

View File

@ -61,7 +61,7 @@ function aiAttack.squadAttackLocation(regionMap, surface, natives)
local group = squad.group
if group.valid and ((squad.status == SQUAD_RAIDING) or (squad.status == SQUAD_SUICIDE_RAID)) then
local groupState = group.state
if (groupState == GROUP_STATE_FINISHED) or (groupState == GROUP_STATE_GATHERING) or (groupState == GROUP_STATE_MOVING) then
if (groupState == GROUP_STATE_FINISHED) or (groupState == GROUP_STATE_GATHERING) or ((groupState == GROUP_STATE_MOVING) and (squad.cycles == 0)) then
local chunk = positionToChunk(regionMap, group.position.x, group.position.y)
addSquadMovementPenalty(squad, chunk.cX, chunk.cY)
local attackLocationNeighbors = getCardinalChunks(regionMap, chunk.cX, chunk.cY)
@ -77,7 +77,7 @@ function aiAttack.squadAttackLocation(regionMap, surface, natives)
attackPosition.y = neighborChunk.pY
local squadMovementPenalty = lookupSquadMovementPenalty(squad, neighborChunk.cX, neighborChunk.cY)
local damageScore = surface.get_pollution(attackPosition) + neighborChunk[PLAYER_BASE_PHEROMONE] + neighborChunk[PLAYER_PHEROMONE] + neighborChunk[PLAYER_DEFENSE_GENERATOR]
local avoidScore = neighborChunk[DEATH_PHEROMONE] + (neighborChunk[ENEMY_BASE_GENERATOR] * 2) --+ (neighborChunk[ENEMY_BASE_PHEROMONE] * 0.5)
local avoidScore = neighborChunk[DEATH_PHEROMONE] + neighborChunk[ENEMY_BASE_PHEROMONE]
local score = damageScore - avoidScore - squadMovementPenalty
if (score > attackScore) then
attackScore = score
@ -96,6 +96,8 @@ function aiAttack.squadAttackLocation(regionMap, surface, natives)
attackPosition = positionDirectionToChunkCornerCardinal(attackDirection, attackChunk)
squad.cX = attackChunk.cX
squad.cY = attackChunk.cY
squad.cycles = 2
squad.direction = attackDirection
group.set_command({type=COMMAND_ATTACK_AREA,
destination=attackPosition,

View File

@ -8,6 +8,9 @@ local unitGroupUtils = require("UnitGroupUtils")
-- constants
local SQUAD_GUARDING = constants.SQUAD_GUARDING
local SQUAD_BURROWING = constants.SQUAD_BURROWING
local PLAYER_BASE_PHEROMONE = constants.PLAYER_BASE_PHEROMONE
local PLAYER_PHEROMONE = constants.PLAYER_PHEROMONE
local PLAYER_DEFENSE_PHEROMONE = constants.PLAYER_DEFENSE_PHEROMONE
@ -20,6 +23,7 @@ local ENEMY_BASE_GENERATOR = constants.ENEMY_BASE_GENERATOR
local AI_SCOUT_COST = constants.AI_SCOUT_COST
local AI_SQUAD_COST = constants.AI_SQUAD_COST
local AI_TUNNEL_COST = constants.AI_TUNNEL_COST
local AI_MAX_SQUAD_COUNT = constants.AI_MAX_SQUAD_COUNT
local AI_MAX_SQUAD_SIZE = constants.AI_MAX_SQUAD_SIZE
@ -85,10 +89,6 @@ function aiBuilding.scouting(regionMap, surface, natives)
-- if ()
end
function aiBuilding.digTunnel(regionMap, surface, natives)
end
function aiBuilding.formSquads(regionMap, surface, natives, chunk, neighbors, evolution_factor)
if (natives.points > AI_SQUAD_COST) then
local score = chunk[PLAYER_BASE_PHEROMONE] + chunk[PLAYER_PHEROMONE] + chunk[PLAYER_DEFENSE_PHEROMONE] + surface.get_pollution({chunk.pX, chunk.pY})

View File

@ -47,7 +47,7 @@ local retreatFilter = {[SQUAD_RETREATING] = true}
function aiDefense.retreatUnits(position, squad, regionMap, surface, natives)
local chunk = getChunkByPosition(regionMap, position.x, position.y)
if (chunk ~= nil) and (chunk[DEATH_PHEROMONE] > (game.evolution_factor * RETREAT_DEATH_PHEROMONE_LEVEL)) then -- TODO sliding scale of death based on evolution
if (chunk ~= nil) and (chunk[DEATH_PHEROMONE] > (game.evolution_factor * RETREAT_DEATH_PHEROMONE_LEVEL)) then
local performRetreat = false
local enemiesToSquad
@ -93,10 +93,6 @@ function aiDefense.retreatUnits(position, squad, regionMap, surface, natives)
-- retreatPosition.x = exitPath.pX + constants.HALF_CHUNK_SIZE
-- retreatPosition.y = exitPath.pY + constants.HALF_CHUNK_SIZE
if (squad ~= nil) and (squad.cX ~= nil) then
local chunk = getChunkByIndex(regionMap, squad.cX, squad.cY)
chunk[DEATH_PHEROMONE] = chunk[DEATH_PHEROMONE] + DEATH_PHEROMONE_GENERATOR_AMOUNT
end
local newSquad = findNearBySquad(natives,
retreatPosition,
@ -112,6 +108,10 @@ function aiDefense.retreatUnits(position, squad, regionMap, surface, natives)
membersToSquad(newSquad, enemiesToSquad, false, DISTRACTION_NONE)
else
-- newSquad.penalties = squad.penalties
-- newSquad.lastCX = squad.cX
-- newSquad.lastCY = squad.cY
-- newSquad.lastDirection = squad.direction
-- newSquad.canTunnel = true
membersToSquad(newSquad, squad.group.members, true, DISTRACTION_NONE)
end
end

View File

@ -12,10 +12,8 @@ local CHUNK_MAX_QUEUE_SIZE = constants.CHUNK_MAX_QUEUE_SIZE
-- imported functions
local createChunk = chunkUtils.createChunk
-- premade tables
local processors = {}
local checkChunkPassability = chunkUtils.checkChunkPassability
local scoreChunk = chunkUtils.scoreChunk
-- module code
@ -41,9 +39,8 @@ function chunkProcessor.processPendingChunks(regionMap, surface, natives, pendin
end
regionMap[chunkX][chunk.cY] = chunk
for i=1, #processors do
processors[i](chunk, surface, natives)
end
checkChunkPassability(chunk, surface, natives)
scoreChunk(chunk, surface, natives)
local processQueue = regionMap.pQ[regionMap.pI]
if (#processQueue == CHUNK_MAX_QUEUE_SIZE) then
@ -61,8 +58,4 @@ function chunkProcessor.processPendingChunks(regionMap, surface, natives, pendin
end
end
function chunkProcessor.install(processor)
processors[#processors+1] = processor
end
return chunkProcessor

View File

@ -2,15 +2,14 @@ local constants = {}
-- misc
constants.MAGIC_MAXIMUM_NUMBER = 1e99 -- used in loops trying to find the lowest score
-- constants.MAX_PHEROMONE = 20000
constants.RETREAT_DEATH_PHEROMONE_LEVEL = 12000
constants.MAGIC_MAXIMUM_NUMBER = 1e99 -- used in loops trying to find the lowest/highest score
constants.RETREAT_DEATH_PHEROMONE_LEVEL = 10000
constants.CHUNK_MAX_QUEUE_SIZE = 400
-- ai
constants.AI_POINT_GENERATOR_AMOUNT = 10
constants.AI_POINT_GENERATOR_AMOUNT = 5
constants.AI_SCOUT_COST = 45
constants.AI_SQUAD_COST = 150
constants.AI_SETTLER_COST = 75
@ -33,13 +32,16 @@ constants.EAST_WEST = 2
constants.MOVEMENT_PENALTY_PHEROMONE_GENERATOR_AMOUNT = 500
constants.MOVEMENT_PHEROMONE_GENERATOR_AMOUNT = 500
constants.ENEMY_BASE_PHEROMONE_GENERATOR_AMOUNT = 35
constants.DEATH_PHEROMONE_GENERATOR_AMOUNT = 35
constants.DEATH_PHEROMONE_GENERATOR_AMOUNT = 100
constants.PLAYER_PHEROMONE_GENERATOR_AMOUNT = 300
-- pheromone diffusion amounts
constants.STANDARD_PHERONOME_DIFFUSION_AMOUNT = 0.03
constants.DEATH_PHEROMONE_DIFFUSION_AMOUNT = 0.00125
constants.DEATH_PHEROMONE_DIFFUSION_AMOUNT = 0.00250
constants.DEATH_PHEROMONE_PERSISTANCE = 0.99
constants.STANDARD_PHEROMONE_PERSISTANCE = 0.95
-- chunk attributes
@ -62,13 +64,13 @@ constants.EAST_WEST_PASSABLE = 11
constants.SQUAD_RETREATING = 1 -- used during squad retreat
constants.SQUAD_GUARDING = 2 -- used when squad is idle
constants.SQUAD_ATTACKING = 3 -- used as an attack state to be transitioned into hunt, raid, siege, burrow
-- constants.SQUAD_SIEGE = 3
constants.SQUAD_HUNTING = 4 -- used when player is close to unit group
constants.SQUAD_SUICIDE_HUNT = 5 -- used when player is close with no retreat
-- constants.SQUAD_BURROWING = 6
-- constants.SQUAD_SCOUTING = 7
constants.SQUAD_BURROWING = 6
constants.SQUAD_RAIDING = 8 -- used when player stuff is close
constants.SQUAD_SUICIDE_RAID = 9 -- when player stuff is close with no retreat
-- constants.SQUAD_SCOUTING = 7
-- constants.SQUAD_SIEGE = 3
-- player building pheromones

View File

@ -3,19 +3,21 @@ local mapProcessor = {}
-- imports
local mapUtils = require("MapUtils")
local pheromoneUtils = require("PheromoneUtils")
local aiBuilding = require("AIBuilding")
-- imported functions
local scents = pheromoneUtils.scents
local processPheromone = pheromoneUtils.processPheromone
local sendScouts = aiBuilding.sendScouts
local formSquads = aiBuilding.formSquads
local getCardinalChunks = mapUtils.getCardinalChunks
local mRandom = math.random
-- premade tables
local processors = {}
local processorsProbabilityLow = {}
local processorsProbabilityHigh = {}
-- module code
-- processing is not consistant as it depends on the number of chunks that have been generated
@ -23,23 +25,27 @@ local processorsProbabilityHigh = {}
-- In theory, this might be fine as smaller bases have less surface to attack and need to have
-- pheromone dissipate at a faster rate.
function mapProcessor.processMap(regionMap, surface, natives, evolution_factor)
local count = 0
if (regionMap.pP == 1) then
regionMap.pR = mRandom()
end
local roll = regionMap.pR
local chunkQueue = regionMap.pQ[regionMap.pP]
for x=1, #chunkQueue do
local chunk = chunkQueue[x]
local cardinalArray = getCardinalChunks(regionMap, chunk.cX, chunk.cY)
for i=1, #processors do
if (processorsProbabilityLow[i] <= roll) and (roll <= processorsProbabilityHigh[i]) then
processors[i](regionMap, surface, natives, chunk, cardinalArray, evolution_factor)
end
scents(regionMap, surface, natives, chunk, cardinalArray, evolution_factor)
if (0.05 <= roll) and (roll <= 0.10) then
sendScouts(regionMap, surface, natives, chunk, cardinalArray, evolution_factor)
end
if (0.11 <= roll) and (roll <= 0.25) then
formSquads(regionMap, surface, natives, chunk, cardinalArray, evolution_factor)
end
processPheromone(regionMap, surface, natives, chunk, cardinalArray, evolution_factor)
end
regionMap.pP = regionMap.pP + 1
@ -48,11 +54,4 @@ function mapProcessor.processMap(regionMap, surface, natives, evolution_factor)
end
end
function mapProcessor.install(processor, useProbabilityLow, useProbabilityHigh)
processors[#processors+1] = processor
processorsProbabilityLow[#processorsProbabilityLow+1] = useProbabilityLow
processorsProbabilityHigh[#processorsProbabilityHigh+1] = useProbabilityHigh
end
return mapProcessor

View File

@ -20,51 +20,43 @@ local PLAYER_BASE_GENERATOR = constants.PLAYER_BASE_GENERATOR
local ENEMY_BASE_GENERATOR = constants.ENEMY_BASE_GENERATOR
local PLAYER_PHEROMONE_GENERATOR_AMOUNT = constants.PLAYER_PHEROMONE_GENERATOR_AMOUNT
local DEATH_PHEROMONE_GENERATOR_AMOUNT = constants.DEATH_PHEROMONE_GENERATOR_AMOUNT
local STANDARD_PHERONOME_DIFFUSION_AMOUNT = constants.STANDARD_PHERONOME_DIFFUSION_AMOUNT
local DEATH_PHEROMONE_DIFFUSION_AMOUNT = constants.DEATH_PHEROMONE_DIFFUSION_AMOUNT
local DEATH_PHEROMONE_PERSISTANCE = constants.DEATH_PHEROMONE_PERSISTANCE
local STANDARD_PHEROMONE_PERSISTANCE = constants.STANDARD_PHEROMONE_PERSISTANCE
-- imported functions
local getChunkByPosition = mapUtils.getChunkByPosition
local mFloor = math.floor
local mFloor = math.floor
-- module code
function pheromoneUtils.deathScent(regionMap, surface, x, y, squad, amount)
if (squad ~= nil) and (squad.cX ~= nil) then
local chunk = getChunkByPosition(regionMap, x, y)
if (chunk ~= nil) then
chunk[DEATH_PHEROMONE] = chunk[DEATH_PHEROMONE] + (amount * 5)
end
function pheromoneUtils.scents(regionMap, surface, natives, chunk, neighbors, evolution_factor)
local amount = chunk[PLAYER_DEFENSE_GENERATOR]
if (amount > 0) then
chunk[PLAYER_DEFENSE_PHEROMONE] = chunk[PLAYER_DEFENSE_PHEROMONE] + amount
end
amount = chunk[PLAYER_BASE_GENERATOR]
if (amount > 0) then
chunk[PLAYER_BASE_PHEROMONE] = chunk[PLAYER_BASE_PHEROMONE] + amount
end
amount = chunk[ENEMY_BASE_GENERATOR]
if (amount > 0) then
chunk[ENEMY_BASE_PHEROMONE] = chunk[ENEMY_BASE_PHEROMONE] + amount
end
end
function pheromoneUtils.deathScent(regionMap, surface, x, y)
local chunk = getChunkByPosition(regionMap, x, y)
if (chunk ~= nil) then
chunk[DEATH_PHEROMONE] = chunk[DEATH_PHEROMONE] + amount
end
end
function pheromoneUtils.playerDefenseScent(regionMap, surface, natives, chunk, neighbors, evolution_factor)
local baseScore = chunk[PLAYER_DEFENSE_GENERATOR]
if (baseScore > 0) then
chunk[PLAYER_DEFENSE_PHEROMONE] = chunk[PLAYER_DEFENSE_PHEROMONE] + baseScore
end
end
function pheromoneUtils.playerBaseScent(regionMap, surface, natives, chunk, neighbors, evolution_factor)
local baseScore = chunk[PLAYER_BASE_GENERATOR]
if (baseScore > 0) then
chunk[PLAYER_BASE_PHEROMONE] = chunk[PLAYER_BASE_PHEROMONE] + baseScore
end
end
function pheromoneUtils.enemyBaseScent(regionMap, surface, natives, chunk, neighbors, evolution_factor)
local spawners = chunk[ENEMY_BASE_GENERATOR]
if (spawners > 0) then
chunk[ENEMY_BASE_PHEROMONE] = chunk[ENEMY_BASE_PHEROMONE] + spawners
chunk[DEATH_PHEROMONE] = chunk[DEATH_PHEROMONE] + DEATH_PHEROMONE_GENERATOR_AMOUNT
end
end
@ -84,13 +76,13 @@ function pheromoneUtils.processPheromone(regionMap, surface, natives, chunk, nei
local persistence
if (x == DEATH_PHEROMONE) then
diffusionAmount = DEATH_PHEROMONE_DIFFUSION_AMOUNT
persistence = 0.99
persistence = DEATH_PHEROMONE_PERSISTANCE
else
diffusionAmount = STANDARD_PHERONOME_DIFFUSION_AMOUNT
persistence = 0.95
persistence = STANDARD_PHEROMONE_PERSISTANCE
end
local totalDiffused = 0
for i=1,4 do
for i=1,#neighbors do
local neighborChunk = neighbors[i]
if (neighborChunk ~= nil) then
local diffusedAmount = (chunk[x] * diffusionAmount)

View File

@ -1,5 +1,14 @@
local tunnelUtils = {}
function tunnelUtils.digTunnel(regionMap, surface, natives, startChunk, endChunk)
end
function tunnelUtils.fillTunnel(regionMap, surface, natives, tilePositions)
local tunnels = natives.tunnels
for i=1, #tunnels do
end
end
return tunnelUtils

View File

@ -2,6 +2,7 @@
[entity-name]
tunnel-entrance = Tunnel Entrance
small-suicide-biter = Small Suicide Biter
medium-suicide-biter = Medium Suicide Biter
big-suicide-biter = Big Suicide Biter
@ -9,6 +10,7 @@ behemoth-suicide-biter = Behemoth Suicide Biter
[entity-description]
tunnel-entrance = This tunnel is used by the biters to bypass player defenses. Fill the hole using landfill.
small-suicide-biter = These biters will explode at close range
medium-suicide-biter = These biters will explode at close range
big-suicide-biter = These biters will explode at close range

View File

@ -8,18 +8,6 @@ data:extend({
order = "b[decorative]-k[tunnel-entrance]-a[big]",
collision_box = {{-1.3, -1.3}, {1.3, 1.3}},
selection_box = {{-1.5, -1.5}, {1.5, 1.5}},
-- minable =
-- {
-- mining_particle = "stone-particle",
-- mining_time = 8,
-- result = "stone",
-- count = 20
-- },
-- loot =
-- {
-- {item = "stone", probability = 1, count_min = 5, count_max = 10}
-- },
-- mined_sound = { filename = "__base__/sound/deconstruct-bricks.ogg" },
render_layer = "remnants",
max_health = 0,
pictures =

View File

@ -0,0 +1,154 @@
local biterFunctions = {}
function biterFunctions.makeBiter(biterAttributes, biterAttack, biterResistances)
return {
type = "unit",
name = biterAttributes.name,
icon = "__base__/graphics/icons/small-biter.png",
flags = {"placeable-player", "placeable-enemy", "placeable-off-grid", "breaths-air"},
max_health = biterAttributes.health,
order = "b-b-a",
subgroup="enemies",
healing_per_tick = biterAttributes.healing,
resistances = biterResistances,
collision_box = {{-0.4 * biterAttributes.scale, -0.4 * biterAttributes.scale},
{0.4 * biterAttributes.scale, 0.4 * biterAttributes.scale}},
selection_box = {{-0.7 * biterAttributes.scale, -1.5 * biterAttributes.scale},
{0.7 * biterAttributes.scale, 0.3 * biterAttributes.scale}},
sticker_box = {{-0.6 * biterAttributes.scale, -0.8 * biterAttributes.scale},
{0.6 * biterAttributes.scale, 0}},
attack_parameters = biterAttack,
vision_distance = 30,
movement_speed = biterAttributes.movement,
distance_per_frame = 0.1,
pollution_to_join_attack = 200,
distraction_cooldown = 300,
dying_explosion = biterAttributes.explosion,
dying_sound = make_biter_dying_sounds(1.0),
working_sound = make_biter_calls(0.7),
run_animation = biterrunanimation(biterAttributes.scale, biterAttributes.tint1, biterAttributes.tint2)
}
end
function biterFunctions.createSuicideAttack(attributes)
return { type = "projectile",
range = 0.5,
cooldown = 35,
ammo_category = "melee",
ammo_type = {
category = "biological",
action = { type = "direct",
action_delivery = { type = "instant",
target_effects = {
{ type = "create-entity",
entity_name = attributes.explosion
},
{ type = "nested-result",
action = { type = "area",
perimeter = attributes.area,
action_delivery = { type = "instant",
target_effects = {
{
type = "damage",
damage = {amount = attributes.damage,
type = "explosion"}
},
}
}
}
},
{
type = "create-entity",
entity_name = attributes.scorchmark,
check_buildability = true
}
}
}
}
},
sound = make_biter_roars(0.5),
animation = biterattackanimation(smallbiterscale, small_biter_tint1, small_biter_tint2)
}
end
local turret_gun_shift = {
}
function biterFunctions.createFireAttack(attributes)
return {
type = "stream",
ammo_category = "flame-thrower",
cooldown = 4,
range = attributes.range,
min_range = attributes.minRange,
turn_range = attributes.turnRange,
fire_penalty = attributes.firePenalty,
animation = biterattackanimation(attributes.scale,
attributes.tint1,
attributes.tint2),
gun_barrel_length = 2 * attributes.scale,
gun_center_shift = {
north = {0, -0.65 * attributes.scale},
east = {0, 0},
south = {0, 0},
west = {0, 0}
},
ammo_type =
{
category = "flame-thrower",
action =
{
type = "direct",
action_delivery =
{
type = "stream",
stream = "flamethrower-fire-stream",
duration = 160,
}
}
},
cyclic_sound =
{
begin_sound =
{
{
filename = "__base__/sound/fight/flamethrower-start.ogg",
volume = 0.7
}
},
middle_sound =
{
{
filename = "__base__/sound/fight/flamethrower-mid.ogg",
volume = 0.7
}
},
end_sound =
{
{
filename = "__base__/sound/fight/flamethrower-end.ogg",
volume = 0.7
}
}
}
}
end
function biterFunctions.makeResistance(name, decrease, percentage)
local obj = {
type = name,
}
if (decrease ~= 0) then
obj.decrease = decrease
end
if (percentage ~= 0) then
obj.percentage = percentage
end
return obj
end
return biterFunctions

View File

@ -0,0 +1,22 @@
local utils = require("BiterFunctions")
local createFireAttack = utils.createFireAttack
local makeBiter = utils.makeBiter
data:extend({
makeBiter({name = "small-fire-spitter",
health = 30,
movement = 0.25,
healing = 0.01,
scale = 0.5,
tint1 = {r=0.6, g=0.0, b=0.70, a=0.8},
tint2 = {r=0.7, g=0.0, b=0.72, a=0.4},
explosion = "blood-explosion-small"},
createFireAttack({ scale = 0.5,
tint1 = {r=0.6, g=0.0, b=0.70, a=0.8},
tint2 = {r=0.7, g=0.0, b=0.72, a=0.4},
range = 20,
minRange = 1,
turnRange = 1.0/3.0,
firePenalty = 15}))
})

View File

@ -1,86 +1,8 @@
function makeBiter(biterAttributes, biterAttack, biterResistances)
return {
type = "unit",
name = biterAttributes.name,
icon = "__base__/graphics/icons/small-biter.png",
flags = {"placeable-player", "placeable-enemy", "placeable-off-grid", "breaths-air"},
max_health = biterAttributes.health,
order = "b-b-a",
subgroup="enemies",
healing_per_tick = biterAttributes.healing,
resistances = biterResistances,
collision_box = {{-0.4 * biterAttributes.scale, -0.4 * biterAttributes.scale},
{0.4 * biterAttributes.scale, 0.4 * biterAttributes.scale}},
selection_box = {{-0.7 * biterAttributes.scale, -1.5 * biterAttributes.scale},
{0.7 * biterAttributes.scale, 0.3 * biterAttributes.scale}},
sticker_box = {{-0.6 * biterAttributes.scale, -0.8 * biterAttributes.scale},
{0.6 * biterAttributes.scale, 0}},
attack_parameters = biterAttack,
vision_distance = 30,
movement_speed = biterAttributes.movement,
distance_per_frame = 0.1,
pollution_to_join_attack = 200,
distraction_cooldown = 300,
dying_explosion = biterAttributes.explosion,
dying_sound = make_biter_dying_sounds(1.0),
working_sound = make_biter_calls(0.7),
run_animation = biterrunanimation(biterAttributes.scale, biterAttributes.tint1, biterAttributes.tint2)
}
end
local util = require("BiterFunctions")
function createSuicideAttack(attributes)
return { type = "projectile",
range = 0.5,
cooldown = 35,
ammo_category = "melee",
ammo_type = {
category = "biological",
action = { type = "direct",
action_delivery = { type = "instant",
target_effects = {
{ type = "create-entity",
entity_name = attributes.explosion
},
{ type = "nested-result",
action = { type = "area",
perimeter = attributes.area,
action_delivery = { type = "instant",
target_effects = {
{
type = "damage",
damage = {amount = attributes.damage,
type = "explosion"}
},
}
}
}
},
{
type = "create-entity",
entity_name = attributes.scorchmark,
check_buildability = true
}
}
}
}
},
sound = make_biter_roars(0.5),
animation = biterattackanimation(smallbiterscale, small_biter_tint1, small_biter_tint2)
}
end
function makeResistance(name, decrease, percentage)
local obj = {
type = name,
}
if (decrease ~= 0) then
obj.decrease = decrease
end
if (percentage ~= 0) then
obj.percentage = percentage
end
return obj
end
local makeBiter = util.makeBiter
local createSuicideAttack = util.createSuicideAttack
local makeResistance = util.makeResistance
data:extend({
makeBiter({name = "small-suicide-biter",

View File

@ -14,7 +14,17 @@ function tests.test1()
if (global.regionMap[x] ~= nil) then
local chunk = global.regionMap[x][y]
if (chunk ~= nil) then
print(serpent.dump(chunk))
local str = ""
for i=1,#chunk do
str = str .. " " .. tostring(i) .. "/" .. tostring(chunk[i])
end
if (chunk.cX == playerChunkX) and (chunk.cY == playerChunkY) then
print("*", chunk.cX, chunk.cY, str)
else
print(chunk.cX, chunk.cY, str)
end
-- print(str)
print("-")
end
end
end