mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2024-12-30 23:17:53 +02:00
refactor and new map
This commit is contained in:
parent
c2829984fe
commit
1f017f687a
@ -70,6 +70,7 @@ require 'modules.autostash'
|
||||
|
||||
---- enable maps here ---- (maps higher up in the list may be more actually playable)
|
||||
--require 'maps.chronosphere.main'
|
||||
--require 'maps.crab_defender.main'
|
||||
--require 'maps.fish_defender_v2.main'
|
||||
--require 'maps.fish_defender.main'
|
||||
--require 'maps.biter_battles_v2.main'
|
||||
|
45
locale/en/crab_defender.cfg
Normal file
45
locale/en/crab_defender.cfg
Normal file
@ -0,0 +1,45 @@
|
||||
[crab_defender]
|
||||
map_info_main_caption=-- Crab Defender --
|
||||
map_info_sub_caption= ~~ the battle for crab-earth ~~
|
||||
map_info_text=The biters are trying to take over the crab world.\nFend them off as long as possible!\nThis however will not be an easy task,\nsince their strength and resistance increases constantly over time.\n\nYour ultimate goal is to evacuate all the fishes that are in the crab-y lakes to crab planet!\nPut them in your rocket's cargo and launch them into space.\nDon't worry, you will still get space science.\n\nThe Market will gladly take any coin you might find.\nAdditional turret slots can be bought at the market.\nSeveral unique upgrades are available too.\nResearching tanks will unlock the artillery technology early.\nAny container bearing dangerous goods, like ammo, grenades or barrels,\ncauses heavy explosions when it breaks.\nMaybe this can be used to our advantage.\n\nBiters will only attack from both sides of the crab claws, be fast with the defenses!\n\nBiters are intelligent,\nthey have placed some sort of anti-inhabitant system so walking on the white-colored tile hurts you.
|
||||
boss_message=Boss Wave __1__ - - __2__
|
||||
50=The Big Anti-crab Gang
|
||||
100=Crabzilla
|
||||
150=The Spitter Squad
|
||||
200=The Wall Nibblers
|
||||
250=Conveyor Munchers
|
||||
300=Furnace Freezers
|
||||
350=Crabby Cabel Chewers
|
||||
400=Power Pole Thieves
|
||||
450=Assembler Annihilators
|
||||
500=Inserter Crunchers
|
||||
550=Crab Engineer Eaters
|
||||
600=Belt Unbalancers
|
||||
650=Turret Devourers
|
||||
700=Pipe Perforators
|
||||
750=Desync Bros
|
||||
800=Ratio Randomizers
|
||||
850=Wire Chompers
|
||||
900=The Bus Mixers
|
||||
950=Roundabout Deadlockers
|
||||
1000=Happy Tree Friends
|
||||
1050=Uranium Digesters
|
||||
1100=Bot Banishers
|
||||
1150=Chest Crushers
|
||||
1200=Cargo Wagon Scratchers
|
||||
1250=Transport Belt Surfers
|
||||
1300=Pumpjack Pulverizers
|
||||
1350=Radar Ravagers
|
||||
1400=Mall Deconstrutors
|
||||
1450=Lamp Dimmers
|
||||
1500=Roboport Disablers
|
||||
1550=Signal Spammers
|
||||
1600=Brick Tramplers
|
||||
1650=Drill Destroyers
|
||||
1700=Gearwheel Grinders
|
||||
1750=Crab Inhabitant Seekers
|
||||
1800=Circuit Breakers
|
||||
1850=Bullet Absorbers
|
||||
1900=Oil Guzzlers
|
||||
1950=Belt Rotators
|
||||
2000=Bluescreen Factor
|
@ -1,7 +1,7 @@
|
||||
[fish_defender_v2]
|
||||
map_info_main_caption=--Fish Defender v2--
|
||||
map_info_sub_caption= ~~blb blubby blub~~
|
||||
map_info_text=The biters have catched the scent of fish in the market.\nFend them off as long as possible!\nThis however will not be an easy task,\nsince their strength and resistance increases constantly over time.\n\nYour ultimate goal is to evacuate all the fish to cat planet!\nPut them in your rocket's cargo and launch them into space.\nDon't worry, you will still get space science.\n\nThe Market will gladly take any coin you might find.\nAdditional turret slots can be bought at the market.\nSeveral unique upgrades are available too.\nResearching tanks will unlock the artillery technology early.\nAny container bearing dangerous goods, like ammo, grenades or barrels,\ncauses heavy explosions when it breaks.\nMaybe this can be used to our advantage.
|
||||
map_info_text=The biters have catched the scent of fish in the market.\nFend them off as long as possible!\nThis however will not be an easy task,\nsince their strength and resistance increases constantly over time.\n\nYour ultimate goal is to evacuate all the fish to cat planet!\nPut them in your rocket's cargo and launch them into space.\nDon't worry, you will still get space science.\n\nThe Market will gladly take any coin you might find.\nAdditional turret slots can be bought at the market.\nSeveral unique upgrades are available too.\nResearching tanks will unlock the artillery technology early.\nAny container bearing dangerous goods, like ammo, grenades or barrels,\ncauses heavy explosions when it breaks.\nMaybe this can be used to our advantage.\n\nBiters will only attack in the middle until wave is greater than 80.
|
||||
boss_message=Boss Wave __1__ - - __2__
|
||||
50=The Big Biter Gang
|
||||
100=Biterzilla
|
||||
|
208
maps/crab_defender/b.lua
Normal file
208
maps/crab_defender/b.lua
Normal file
@ -0,0 +1,208 @@
|
||||
local simplex_noise = require 'utils.simplex_noise'.d2
|
||||
local map_data = require 'maps.crab_defender.crab_defender'
|
||||
|
||||
local random = math.random
|
||||
local abs = math.abs
|
||||
local floor = math.floor
|
||||
local scale = 1
|
||||
|
||||
local Public = {}
|
||||
|
||||
local tile_map = {
|
||||
[1] = false,
|
||||
[2] = true,
|
||||
[3] = 'concrete',
|
||||
[4] = 'deepwater-green',
|
||||
[5] = 'deepwater',
|
||||
[6] = 'dirt-1',
|
||||
[7] = 'dirt-2',
|
||||
[8] = 'dirt-3',
|
||||
[9] = 'dirt-4',
|
||||
[10] = 'dirt-5',
|
||||
[11] = 'dirt-6',
|
||||
[12] = 'dirt-7',
|
||||
[13] = 'dry-dirt',
|
||||
[14] = 'grass-1',
|
||||
[15] = 'grass-2',
|
||||
[16] = 'grass-3',
|
||||
[17] = 'grass-4',
|
||||
[18] = 'tutorial-grid',
|
||||
[19] = 'hazard-concrete-right',
|
||||
[20] = 'lab-dark-1',
|
||||
[21] = 'lab-dark-2',
|
||||
[22] = 'lab-white',
|
||||
[23] = 'out-of-map',
|
||||
[24] = 'red-desert-0',
|
||||
[25] = 'red-desert-1',
|
||||
[26] = 'red-desert-2',
|
||||
[27] = 'red-desert-3',
|
||||
[28] = 'sand-1',
|
||||
[29] = 'sand-2',
|
||||
[30] = 'sand-3',
|
||||
[31] = 'stone-path',
|
||||
[32] = 'water-green',
|
||||
[33] = 'water'
|
||||
}
|
||||
|
||||
local rock_raffle = {
|
||||
'sand-rock-big',
|
||||
'sand-rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-huge'
|
||||
}
|
||||
|
||||
local function decompress()
|
||||
local decompressed = {}
|
||||
local data = map_data.data
|
||||
local height = map_data.height
|
||||
local width = map_data.width
|
||||
|
||||
for y = 1, height do
|
||||
local row = data[y]
|
||||
local u_row = {}
|
||||
decompressed[y] = u_row
|
||||
local x = 1
|
||||
for index = 1, #row, 2 do
|
||||
local pixel = row[index]
|
||||
local count = row[index + 1]
|
||||
|
||||
for _ = 1, count do
|
||||
u_row[x] = pixel
|
||||
x = x + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return decompressed, width, height
|
||||
end
|
||||
local tile_data, width, height = decompress()
|
||||
|
||||
local function get_pos(x, y)
|
||||
-- the plus one is because lua tables are one based.
|
||||
local half_width = floor(width / 2) + 1
|
||||
local half_height = floor(height / 2) + 1
|
||||
x = x / scale
|
||||
y = y / scale
|
||||
x = floor(x)
|
||||
y = floor(y)
|
||||
local x2 = x + half_width
|
||||
local y2 = y + half_height
|
||||
|
||||
if y2 > 0 and y2 <= height and x2 > 0 and x2 <= width then
|
||||
return tile_map[tile_data[y2][x2]]
|
||||
end
|
||||
end
|
||||
|
||||
local ores = {'coal', 'iron-ore', 'copper-ore', 'stone'}
|
||||
|
||||
local function plankton_territory(position, seed, ent)
|
||||
local noise = simplex_noise(position.x * 0.009, position.y * 0.009, seed)
|
||||
local d = 196
|
||||
|
||||
if get_pos(position.x, position.y) then
|
||||
return
|
||||
end
|
||||
|
||||
local noise_2 = simplex_noise(position.x * 0.0075, position.y * 0.0075, seed + 10000)
|
||||
if noise_2 > 0.87 then
|
||||
return 'deepwater-green'
|
||||
end
|
||||
if noise_2 > 0.75 then
|
||||
local i = floor(noise * 6) % 4 + 1
|
||||
ent[#ent + 1] = {name = ores[i], position = position, amount = 1 + 2500 * abs(noise_2 * 3)}
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
if noise_2 < -0.76 then
|
||||
local i = floor(noise * 6) % 4 + 1
|
||||
if noise_2 < -0.86 then
|
||||
ent[#ent + 1] = {name = 'uranium-ore', position = position, amount = 1 + 1000 * abs(noise_2 * 2)}
|
||||
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
if random(1, 3) ~= 1 then
|
||||
ent[#ent + 1] = {name = rock_raffle[random(1, #rock_raffle)], position = position}
|
||||
end
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
|
||||
if noise < 0.12 and noise > -0.12 then
|
||||
local i = floor(noise * 32) % 4 + 1
|
||||
if random(1, 5) == 1 then
|
||||
ent[#ent + 1] = {name = rock_raffle[random(1, #rock_raffle)], position = position}
|
||||
end
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
|
||||
if random(1, 128) == 1 then
|
||||
ent[#ent + 1] = {name = 'fish', position = position}
|
||||
end
|
||||
|
||||
return 'water'
|
||||
end
|
||||
|
||||
local function get_random_ore(position)
|
||||
local noise = (position.x * 0.009)
|
||||
local i = floor(noise * 6) % 4 + 1
|
||||
local ore = ores[i]
|
||||
|
||||
return ore
|
||||
end
|
||||
|
||||
function Public.make_chunk(event)
|
||||
local map_name = 'crab_defender'
|
||||
|
||||
if string.sub(event.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = event.surface
|
||||
|
||||
local x1 = event.area.left_top.x
|
||||
local y1 = event.area.left_top.y
|
||||
local x2 = event.area.right_bottom.x
|
||||
local y2 = event.area.right_bottom.y
|
||||
|
||||
local seed = game.surfaces[1].map_gen_settings.seed
|
||||
|
||||
local noise = {}
|
||||
local tiles = {}
|
||||
local ent = {}
|
||||
|
||||
for x = x1, x2 do
|
||||
for y = y1, y2 do
|
||||
local pos = {x = x, y = y}
|
||||
local new = get_pos(x, y)
|
||||
local ore = get_random_ore(pos)
|
||||
|
||||
if new and type(new) == 'string' then
|
||||
if new == 'lab-dark-2' then
|
||||
ent[#ent + 1] = {name = ore, position = pos, amount = 2500}
|
||||
else
|
||||
tiles[#tiles + 1] = {name = new, position = pos}
|
||||
end
|
||||
else
|
||||
local tile_to_set = plankton_territory(pos, seed, ent)
|
||||
if tile_to_set then
|
||||
noise[#noise + 1] = {name = tile_to_set, position = pos}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
surface.set_tiles(tiles, true)
|
||||
surface.set_tiles(noise, true)
|
||||
for i = 1, #ent do
|
||||
if ent[i].amount then
|
||||
surface.create_entity({name = ent[i].name, position = ent[i].position, amount = ent[i].amount})
|
||||
else
|
||||
surface.create_entity({name = ent[i].name, position = ent[i].position})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Public
|
99
maps/crab_defender/boss_biters.lua
Normal file
99
maps/crab_defender/boss_biters.lua
Normal file
@ -0,0 +1,99 @@
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
|
||||
local boss_biter = {}
|
||||
local math_random = math.random
|
||||
local radius = 6
|
||||
local targets = {}
|
||||
local acid_splashes = {
|
||||
['big-biter'] = 'acid-stream-worm-medium',
|
||||
['behemoth-biter'] = 'acid-stream-worm-big',
|
||||
['big-spitter'] = 'acid-stream-worm-medium',
|
||||
['behemoth-spitter'] = 'acid-stream-worm-big'
|
||||
}
|
||||
local acid_lines = {
|
||||
['big-spitter'] = 'acid-stream-spitter-medium',
|
||||
['behemoth-spitter'] = 'acid-stream-spitter-big'
|
||||
}
|
||||
for x = radius * -1, radius, 1 do
|
||||
for y = radius * -1, radius, 1 do
|
||||
if math.sqrt(x ^ 2 + y ^ 2) <= radius then
|
||||
targets[#targets + 1] = {x = x, y = y}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function acid_nova(event)
|
||||
for _ = 1, math.random(16, 32) do
|
||||
local i = math.random(1, #targets)
|
||||
event.entity.surface.create_entity(
|
||||
{
|
||||
name = acid_splashes[event.entity.name],
|
||||
position = event.entity.position,
|
||||
force = event.entity.force.name,
|
||||
source = event.entity.position,
|
||||
target = {x = event.entity.position.x + targets[i].x, y = event.entity.position.y + targets[i].y},
|
||||
max_range = radius,
|
||||
speed = 0.001
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
boss_biter.died = function(event)
|
||||
local this = FDT.get()
|
||||
if acid_splashes[event.entity.name] then
|
||||
acid_nova(event)
|
||||
end
|
||||
if this.acid_lines_delay[event.entity.unit_number] then
|
||||
this.acid_lines_delay[event.entity.unit_number] = nil
|
||||
end
|
||||
this.boss_biters[event.entity.unit_number] = nil
|
||||
end
|
||||
|
||||
local function acid_line(surface, name, source, target)
|
||||
local distance = math.sqrt((source.x - target.x) ^ 2 + (source.y - target.y) ^ 2)
|
||||
|
||||
if distance > 16 then
|
||||
return false
|
||||
end
|
||||
|
||||
local modifier = {(target.x - source.x) / distance, (target.y - source.y) / distance}
|
||||
|
||||
local position = {source.x, source.y}
|
||||
|
||||
for i = 1, distance + 4, 1 do
|
||||
if math_random(1, 3) == 1 then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = name,
|
||||
position = source,
|
||||
force = 'enemy',
|
||||
source = source,
|
||||
target = position,
|
||||
max_range = 25,
|
||||
speed = 1
|
||||
}
|
||||
)
|
||||
end
|
||||
position = {position[1] + modifier[1], position[2] + modifier[2]}
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
boss_biter.damaged_entity = function(event)
|
||||
if acid_lines[event.cause.name] then
|
||||
local this = FDT.get()
|
||||
if not this.acid_lines_delay[event.cause.unit_number] then
|
||||
this.acid_lines_delay[event.cause.unit_number] = 0
|
||||
end
|
||||
|
||||
if this.acid_lines_delay[event.cause.unit_number] < game.tick then
|
||||
if acid_line(event.cause.surface, acid_lines[event.cause.name], event.cause.position, event.entity.position) then
|
||||
this.acid_lines_delay[event.cause.unit_number] = game.tick + 180
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return boss_biter
|
76
maps/crab_defender/bouncy_shells.lua
Normal file
76
maps/crab_defender/bouncy_shells.lua
Normal file
@ -0,0 +1,76 @@
|
||||
local radius = 9
|
||||
local math_random = math.random
|
||||
|
||||
local ammo_to_projectile_translation = {
|
||||
['shotgun-shell'] = 'shotgun-pellet',
|
||||
['piercing-shotgun-shell'] = 'piercing-shotgun-pellet'
|
||||
}
|
||||
|
||||
local function create_projectile(surface, position, target, name)
|
||||
surface.create_entity(
|
||||
{
|
||||
name = name,
|
||||
position = position,
|
||||
force = 'player',
|
||||
source = position,
|
||||
target = target,
|
||||
max_range = 16,
|
||||
speed = 0.3
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
local function bounce(surface, position, ammo)
|
||||
if math_random(1, 3) ~= 1 then
|
||||
return
|
||||
end
|
||||
local valid_entities = {}
|
||||
for _, e in pairs(
|
||||
surface.find_entities_filtered(
|
||||
{area = {{position.x - radius, position.y - radius}, {position.x + radius, position.y + radius}}}
|
||||
)
|
||||
) do
|
||||
if e.health then
|
||||
if e.force.name ~= 'player' then
|
||||
--local distance_from_center = math_sqrt((e.position.x - position.x) ^ 2 + (e.position.y - position.y) ^ 2)
|
||||
--if distance_from_center <= radius then
|
||||
valid_entities[#valid_entities + 1] = e
|
||||
--end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not valid_entities[1] then
|
||||
return
|
||||
end
|
||||
|
||||
for _ = 1, math_random(3, 6), 1 do
|
||||
create_projectile(surface, position, valid_entities[math_random(1, #valid_entities)].position, ammo)
|
||||
end
|
||||
end
|
||||
|
||||
local function bouncy_shells(event)
|
||||
if event.damage_type.name ~= 'physical' then
|
||||
return false
|
||||
end
|
||||
local player = event.cause
|
||||
if player.shooting_state.state == defines.shooting.not_shooting then
|
||||
return false
|
||||
end
|
||||
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
|
||||
if selected_weapon.name ~= 'combat-shotgun' and selected_weapon.name ~= 'shotgun' then
|
||||
return false
|
||||
end
|
||||
|
||||
local selected_ammo = player.get_inventory(defines.inventory.character_ammo)[player.selected_gun_index]
|
||||
if not selected_ammo then
|
||||
return
|
||||
end
|
||||
if not ammo_to_projectile_translation[selected_ammo.name] then
|
||||
return
|
||||
end
|
||||
|
||||
bounce(player.surface, event.entity.position, ammo_to_projectile_translation[selected_ammo.name])
|
||||
end
|
||||
|
||||
return bouncy_shells
|
148
maps/crab_defender/commands.lua
Normal file
148
maps/crab_defender/commands.lua
Normal file
@ -0,0 +1,148 @@
|
||||
local Server = require 'utils.server'
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
local Task = require 'utils.task'
|
||||
|
||||
local mapkeeper = '[color=blue]Mapkeeper:[/color]'
|
||||
|
||||
commands.add_command(
|
||||
'scenario',
|
||||
'Usable only for admins - controls the scenario!',
|
||||
function(cmd)
|
||||
local p
|
||||
local player = game.player
|
||||
|
||||
if not player or not player.valid then
|
||||
p = log
|
||||
else
|
||||
p = player.print
|
||||
if not player.admin then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local param = cmd.parameter
|
||||
|
||||
if param == 'restart' or param == 'shutdown' or param == 'reset' or param == 'restartnow' then
|
||||
goto continue
|
||||
else
|
||||
p('[ERROR] Arguments are:\nrestart\nshutdown\nreset\nrestartnow')
|
||||
return
|
||||
end
|
||||
|
||||
::continue::
|
||||
|
||||
local this = FDT.get()
|
||||
local reset_map = require 'maps.crab_defender.main'.reset_game
|
||||
|
||||
if not this.reset_are_you_sure then
|
||||
this.reset_are_you_sure = true
|
||||
p(
|
||||
'[WARNING] This command will disable the soft-reset feature, run this command again if you really want to do this!'
|
||||
)
|
||||
return
|
||||
end
|
||||
|
||||
if param == 'restart' then
|
||||
if this.restart then
|
||||
this.reset_are_you_sure = nil
|
||||
this.restart = false
|
||||
this.soft_reset = true
|
||||
p('[SUCCESS] Soft-reset is enabled.')
|
||||
return
|
||||
else
|
||||
this.reset_are_you_sure = nil
|
||||
this.restart = true
|
||||
this.soft_reset = false
|
||||
if this.shutdown then
|
||||
this.shutdown = false
|
||||
end
|
||||
p('[WARNING] Soft-reset is disabled! Server will restart from scenario.')
|
||||
return
|
||||
end
|
||||
elseif param == 'restartnow' then
|
||||
this.reset_are_you_sure = nil
|
||||
p(player.name .. ' has restarted the game.')
|
||||
Server.start_scenario('Crab_Defender')
|
||||
return
|
||||
elseif param == 'shutdown' then
|
||||
if this.shutdown then
|
||||
this.reset_are_you_sure = nil
|
||||
this.shutdown = false
|
||||
this.soft_reset = true
|
||||
p('[SUCCESS] Soft-reset is enabled.')
|
||||
return
|
||||
else
|
||||
this.reset_are_you_sure = nil
|
||||
this.shutdown = true
|
||||
this.soft_reset = false
|
||||
if this.restart then
|
||||
this.restart = false
|
||||
end
|
||||
p('[WARNING] Soft-reset is disabled! Server will shutdown.')
|
||||
return
|
||||
end
|
||||
elseif param == 'reset' then
|
||||
this.reset_are_you_sure = nil
|
||||
if player and player.valid then
|
||||
game.print(mapkeeper .. ' ' .. player.name .. ', has reset the game!', {r = 0.98, g = 0.66, b = 0.22})
|
||||
else
|
||||
game.print(mapkeeper .. ' server, has reset the game!', {r = 0.98, g = 0.66, b = 0.22})
|
||||
end
|
||||
reset_map()
|
||||
p('[WARNING] Game has been reset!')
|
||||
return
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
commands.add_command(
|
||||
'set_queue_speed',
|
||||
'Usable only for admins - sets the queue speed of this map!',
|
||||
function(cmd)
|
||||
local p
|
||||
local player = game.player
|
||||
local param = tonumber(cmd.parameter)
|
||||
|
||||
if player then
|
||||
if player ~= nil then
|
||||
p = player.print
|
||||
if not player.admin then
|
||||
p("[ERROR] You're not admin!", Color.fail)
|
||||
return
|
||||
end
|
||||
if not param then
|
||||
return
|
||||
end
|
||||
p('Queue speed set to: ' .. param)
|
||||
Task.set_queue_speed(param)
|
||||
else
|
||||
p = log
|
||||
p('Queue speed set to: ' .. param)
|
||||
Task.set_queue_speed(param)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
commands.add_command(
|
||||
'get_queue_speed',
|
||||
'Usable only for admins - gets the queue speed of this map!',
|
||||
function()
|
||||
local p
|
||||
local player = game.player
|
||||
|
||||
if player then
|
||||
if player ~= nil then
|
||||
p = player.print
|
||||
if not player.admin then
|
||||
p("[ERROR] You're not admin!", Color.fail)
|
||||
return
|
||||
end
|
||||
p(Task.get_queue_speed())
|
||||
else
|
||||
p = log
|
||||
p(Task.get_queue_speed())
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
2054
maps/crab_defender/crab_defender.lua
Normal file
2054
maps/crab_defender/crab_defender.lua
Normal file
File diff suppressed because it is too large
Load Diff
27
maps/crab_defender/crumbly_walls.lua
Normal file
27
maps/crab_defender/crumbly_walls.lua
Normal file
@ -0,0 +1,27 @@
|
||||
local Event = require 'utils.event'
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
local math_random = math.random
|
||||
|
||||
local rock_raffle = {'sand-rock-big', 'rock-big', 'rock-big', 'rock-big', 'rock-huge'}
|
||||
|
||||
local function on_entity_died(event)
|
||||
local crumbly_walls_unlocked = FDT.get('crumbly_walls_unlocked')
|
||||
if not crumbly_walls_unlocked then
|
||||
return
|
||||
end
|
||||
local entity = event.entity
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
if entity.name ~= 'stone-wall' then
|
||||
return
|
||||
end
|
||||
if math_random(1, 4) == 1 then
|
||||
return
|
||||
end
|
||||
entity.surface.create_entity(
|
||||
{name = rock_raffle[math_random(1, #rock_raffle)], position = entity.position, force = 'player'}
|
||||
)
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
46
maps/crab_defender/explosive_gun_bullets.lua
Normal file
46
maps/crab_defender/explosive_gun_bullets.lua
Normal file
@ -0,0 +1,46 @@
|
||||
local radius = 3
|
||||
|
||||
local function splash_damage(surface, position, final_damage_amount)
|
||||
local damage = math.random(math.floor(final_damage_amount * 3), math.floor(final_damage_amount * 4))
|
||||
for _, e in pairs(
|
||||
surface.find_entities_filtered(
|
||||
{area = {{position.x - radius, position.y - radius}, {position.x + radius, position.y + radius}}}
|
||||
)
|
||||
) do
|
||||
if e.valid and e.health then
|
||||
local distance_from_center = math.sqrt((e.position.x - position.x) ^ 2 + (e.position.y - position.y) ^ 2)
|
||||
if distance_from_center <= radius then
|
||||
local damage_distance_modifier = 1 - distance_from_center / radius
|
||||
if damage > 0 then
|
||||
if math.random(1, 3) == 1 then
|
||||
surface.create_entity({name = 'explosion', position = e.position})
|
||||
end
|
||||
e.damage(damage * damage_distance_modifier, 'player', 'explosion')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function explosive_bullets(event)
|
||||
if math.random(1, 3) ~= 1 then
|
||||
return false
|
||||
end
|
||||
if event.damage_type.name ~= 'physical' then
|
||||
return false
|
||||
end
|
||||
local player = event.cause
|
||||
if player.shooting_state.state == defines.shooting.not_shooting then
|
||||
return false
|
||||
end
|
||||
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
|
||||
if selected_weapon.name ~= 'submachine-gun' and selected_weapon.name ~= 'pistol' then
|
||||
return false
|
||||
end
|
||||
|
||||
player.surface.create_entity({name = 'explosion', position = event.entity.position})
|
||||
|
||||
splash_damage(player.surface, event.entity.position, event.final_damage_amount)
|
||||
end
|
||||
|
||||
return explosive_bullets
|
2054
maps/crab_defender/fish_defender_layout.lua
Normal file
2054
maps/crab_defender/fish_defender_layout.lua
Normal file
File diff suppressed because it is too large
Load Diff
52
maps/crab_defender/flame_boots.lua
Normal file
52
maps/crab_defender/flame_boots.lua
Normal file
@ -0,0 +1,52 @@
|
||||
local Event = require 'utils.event'
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
|
||||
local function on_player_changed_position(event)
|
||||
local flame_boots = FDT.get('flame_boots')
|
||||
if not flame_boots then
|
||||
return
|
||||
end
|
||||
local player = game.players[event.player_index]
|
||||
if not player.character then
|
||||
return
|
||||
end
|
||||
if player.character.driving then
|
||||
return
|
||||
end
|
||||
|
||||
if not flame_boots[player.index] then
|
||||
flame_boots[player.index] = {}
|
||||
end
|
||||
|
||||
if not flame_boots[player.index].fuel then
|
||||
return
|
||||
end
|
||||
|
||||
if flame_boots[player.index].fuel < 0 then
|
||||
player.print('Your flame boots have worn out.', {r = 0.22, g = 0.77, b = 0.44})
|
||||
flame_boots[player.index] = {}
|
||||
return
|
||||
end
|
||||
|
||||
if flame_boots[player.index].fuel % 500 == 0 then
|
||||
player.print('Fuel remaining: ' .. flame_boots[player.index].fuel, {r = 0.22, g = 0.77, b = 0.44})
|
||||
end
|
||||
|
||||
if not flame_boots[player.index].step_history then
|
||||
flame_boots[player.index].step_history = {}
|
||||
end
|
||||
|
||||
local elements = #flame_boots[player.index].step_history
|
||||
|
||||
flame_boots[player.index].step_history[elements + 1] = {x = player.position.x, y = player.position.y}
|
||||
|
||||
if elements < 50 then
|
||||
return
|
||||
end
|
||||
|
||||
player.surface.create_entity({name = 'fire-flame', position = flame_boots[player.index].step_history[elements - 2]})
|
||||
|
||||
flame_boots[player.index].fuel = flame_boots[player.index].fuel - 1
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_player_changed_position, on_player_changed_position)
|
37
maps/crab_defender/laser_pointer.lua
Normal file
37
maps/crab_defender/laser_pointer.lua
Normal file
@ -0,0 +1,37 @@
|
||||
local Event = require 'utils.event'
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
local radius = 32
|
||||
|
||||
local function on_player_used_capsule(event)
|
||||
local laser_pointer_unlocked = FDT.get('laser_pointer_unlocked')
|
||||
if not laser_pointer_unlocked then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
local position = event.position
|
||||
local used_item = event.item
|
||||
if used_item.name ~= 'artillery-targeting-remote' then
|
||||
return
|
||||
end
|
||||
|
||||
for _, unit in pairs(player.surface.find_enemy_units(position, radius, 'player')) do
|
||||
if math.random(1, 2) == 1 then
|
||||
unit.set_command(
|
||||
{
|
||||
type = defines.command.go_to_location,
|
||||
destination = position,
|
||||
radius = 2,
|
||||
distraction = defines.distraction.none,
|
||||
pathfind_flags = {
|
||||
allow_destroy_friendly_entities = false,
|
||||
prefer_straight_paths = false,
|
||||
low_priority = false
|
||||
}
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_player_used_capsule, on_player_used_capsule)
|
1470
maps/crab_defender/main.lua
Normal file
1470
maps/crab_defender/main.lua
Normal file
File diff suppressed because it is too large
Load Diff
345
maps/crab_defender/market.lua
Normal file
345
maps/crab_defender/market.lua
Normal file
@ -0,0 +1,345 @@
|
||||
require 'maps.crab_defender.flame_boots'
|
||||
require 'maps.crab_defender.trapped_capsules'
|
||||
require 'maps.crab_defender.ultra_mines'
|
||||
require 'maps.crab_defender.crumbly_walls'
|
||||
require 'maps.crab_defender.vehicle_nanobots'
|
||||
require 'maps.crab_defender.laser_pointer'
|
||||
|
||||
local Event = require 'utils.event'
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
local Server = require 'utils.server'
|
||||
|
||||
local slot_upgrade_offers = {
|
||||
[1] = {'gun-turret', 'gun turret'},
|
||||
[2] = {'laser-turret', 'laser turret'},
|
||||
[3] = {'artillery-turret', 'artillery turret'},
|
||||
[4] = {'flamethrower-turret', 'flamethrower turret'},
|
||||
[5] = {'land-mine', 'land mine'}
|
||||
}
|
||||
|
||||
local special_descriptions = {
|
||||
['flame-boots'] = 'Flame Boots - Get yourself some hot boots.',
|
||||
['explosive-bullets'] = 'Unlock Explosive Bullets - Submachine-Gun and Pistol gains a chance to deal splash damage.',
|
||||
['bouncy-shells'] = 'Unlock Bouncy Shells - Shotgun projectiles may bounce to multiple targets.',
|
||||
['trapped-capsules'] = 'Unlock Trapped Capsules - Combat robots will send a last deadly projectile to a nearby enemy when killed.',
|
||||
['ultra-mines'] = 'Unlock Ultra Mines - Careful with these...',
|
||||
['railgun-enhancer'] = 'Unlock Railgun Enhancer - Turns the railgun into a powerful forking gun.',
|
||||
['crumbly-walls'] = 'Unlock Crumbly Walls - Fortifications which crumble, may turn into rocks.',
|
||||
['vehicle-nanobots'] = 'Unlock Vehicle Nanobots - Vehicles repair rapidly while driving.',
|
||||
['laser-pointer'] = 'Unlock Laser Pointer - The biters are on a quest to slay the red (artillery) dot.'
|
||||
}
|
||||
|
||||
local function refresh_market_offers()
|
||||
local this = FDT.get()
|
||||
if not this.market or not this.market.valid then
|
||||
return
|
||||
end
|
||||
for i = 1, 100, 1 do
|
||||
local a = this.market.remove_market_item(1)
|
||||
if a == false then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local str1 =
|
||||
'Gun Turret Slot for ' ..
|
||||
tostring(this.entity_limits['gun-turret'].limit * this.entity_limits['gun-turret'].slot_price)
|
||||
str1 = str1 .. ' Coins.'
|
||||
|
||||
local str2 =
|
||||
'Laser Turret Slot for ' ..
|
||||
tostring(this.entity_limits['laser-turret'].limit * this.entity_limits['laser-turret'].slot_price)
|
||||
str2 = str2 .. ' Coins.'
|
||||
|
||||
local str3 =
|
||||
'Artillery Slot for ' ..
|
||||
tostring(this.entity_limits['artillery-turret'].limit * this.entity_limits['artillery-turret'].slot_price)
|
||||
str3 = str3 .. ' Coins.'
|
||||
|
||||
local current_limit = 1
|
||||
if this.entity_limits['flamethrower-turret'].limit ~= 0 then
|
||||
current_limit = current_limit + this.entity_limits['flamethrower-turret'].limit
|
||||
end
|
||||
local str4 =
|
||||
'Flamethrower Turret Slot for ' ..
|
||||
tostring(current_limit * this.entity_limits['flamethrower-turret'].slot_price)
|
||||
str4 = str4 .. ' Coins.'
|
||||
|
||||
local str5 =
|
||||
'Landmine Slot for ' ..
|
||||
tostring(math.ceil((this.entity_limits['land-mine'].limit / 3) * this.entity_limits['land-mine'].slot_price))
|
||||
str5 = str5 .. ' Coins.'
|
||||
|
||||
local market_items = {
|
||||
{price = {}, offer = {type = 'nothing', effect_description = str1}},
|
||||
{price = {}, offer = {type = 'nothing', effect_description = str2}},
|
||||
{price = {}, offer = {type = 'nothing', effect_description = str3}},
|
||||
{price = {}, offer = {type = 'nothing', effect_description = str4}},
|
||||
{price = {}, offer = {type = 'nothing', effect_description = str5}},
|
||||
{price = {{'coin', 5}}, offer = {type = 'give-item', item = 'raw-fish', count = 1}},
|
||||
{price = {{'coin', 1}}, offer = {type = 'give-item', item = 'wood', count = 8}},
|
||||
{price = {{'coin', 8}}, offer = {type = 'give-item', item = 'grenade', count = 1}},
|
||||
{price = {{'coin', 32}}, offer = {type = 'give-item', item = 'cluster-grenade', count = 1}},
|
||||
{price = {{'coin', 1}}, offer = {type = 'give-item', item = 'land-mine', count = 1}},
|
||||
{price = {{'coin', 80}}, offer = {type = 'give-item', item = 'car', count = 1}},
|
||||
{price = {{'coin', 1200}}, offer = {type = 'give-item', item = 'tank', count = 1}},
|
||||
{price = {{'coin', 3}}, offer = {type = 'give-item', item = 'cannon-shell', count = 1}},
|
||||
{price = {{'coin', 7}}, offer = {type = 'give-item', item = 'explosive-cannon-shell', count = 1}},
|
||||
{price = {{'coin', 50}}, offer = {type = 'give-item', item = 'gun-turret', count = 1}},
|
||||
{price = {{'coin', 300}}, offer = {type = 'give-item', item = 'laser-turret', count = 1}},
|
||||
{price = {{'coin', 450}}, offer = {type = 'give-item', item = 'artillery-turret', count = 1}},
|
||||
{price = {{'coin', 10}}, offer = {type = 'give-item', item = 'artillery-shell', count = 1}},
|
||||
{price = {{'coin', 25}}, offer = {type = 'give-item', item = 'artillery-targeting-remote', count = 1}},
|
||||
{price = {{'coin', 1}}, offer = {type = 'give-item', item = 'firearm-magazine', count = 1}},
|
||||
{price = {{'coin', 4}}, offer = {type = 'give-item', item = 'piercing-rounds-magazine', count = 1}},
|
||||
{price = {{'coin', 2}}, offer = {type = 'give-item', item = 'shotgun-shell', count = 1}},
|
||||
{price = {{'coin', 6}}, offer = {type = 'give-item', item = 'piercing-shotgun-shell', count = 1}},
|
||||
{price = {{'coin', 30}}, offer = {type = 'give-item', item = 'submachine-gun', count = 1}},
|
||||
{price = {{'coin', 250}}, offer = {type = 'give-item', item = 'combat-shotgun', count = 1}},
|
||||
{price = {{'coin', 450}}, offer = {type = 'give-item', item = 'flamethrower', count = 1}},
|
||||
{price = {{'coin', 25}}, offer = {type = 'give-item', item = 'flamethrower-ammo', count = 1}},
|
||||
{price = {{'coin', 125}}, offer = {type = 'give-item', item = 'rocket-launcher', count = 1}},
|
||||
{price = {{'coin', 2}}, offer = {type = 'give-item', item = 'rocket', count = 1}},
|
||||
{price = {{'coin', 7}}, offer = {type = 'give-item', item = 'explosive-rocket', count = 1}},
|
||||
{price = {{'coin', 7500}}, offer = {type = 'give-item', item = 'atomic-bomb', count = 1}},
|
||||
{price = {{'coin', 325}}, offer = {type = 'give-item', item = 'railgun', count = 1}},
|
||||
{price = {{'coin', 8}}, offer = {type = 'give-item', item = 'railgun-dart', count = 1}},
|
||||
{price = {{'coin', 40}}, offer = {type = 'give-item', item = 'poison-capsule', count = 1}},
|
||||
{price = {{'coin', 4}}, offer = {type = 'give-item', item = 'defender-capsule', count = 1}},
|
||||
{price = {{'coin', 10}}, offer = {type = 'give-item', item = 'light-armor', count = 1}},
|
||||
{price = {{'coin', 125}}, offer = {type = 'give-item', item = 'heavy-armor', count = 1}},
|
||||
{price = {{'coin', 350}}, offer = {type = 'give-item', item = 'modular-armor', count = 1}},
|
||||
{price = {{'coin', 1500}}, offer = {type = 'give-item', item = 'power-armor', count = 1}},
|
||||
{price = {{'coin', 12000}}, offer = {type = 'give-item', item = 'power-armor-mk2', count = 1}},
|
||||
{price = {{'coin', 50}}, offer = {type = 'give-item', item = 'solar-panel-equipment', count = 1}},
|
||||
{price = {{'coin', 2250}}, offer = {type = 'give-item', item = 'fusion-reactor-equipment', count = 1}},
|
||||
{price = {{'coin', 100}}, offer = {type = 'give-item', item = 'battery-equipment', count = 1}},
|
||||
{price = {{'coin', 200}}, offer = {type = 'give-item', item = 'energy-shield-equipment', count = 1}},
|
||||
{price = {{'coin', 850}}, offer = {type = 'give-item', item = 'personal-laser-defense-equipment', count = 1}},
|
||||
{price = {{'coin', 175}}, offer = {type = 'give-item', item = 'exoskeleton-equipment', count = 1}},
|
||||
{price = {{'coin', 125}}, offer = {type = 'give-item', item = 'night-vision-equipment', count = 1}},
|
||||
{price = {{'coin', 200}}, offer = {type = 'give-item', item = 'belt-immunity-equipment', count = 1}},
|
||||
{price = {{'coin', 250}}, offer = {type = 'give-item', item = 'personal-roboport-equipment', count = 1}},
|
||||
{price = {{'coin', 35}}, offer = {type = 'give-item', item = 'construction-robot', count = 1}},
|
||||
{price = {{'coin', 25}}, offer = {type = 'give-item', item = 'cliff-explosives', count = 1}},
|
||||
{price = {{'coin', 80}}, offer = {type = 'nothing', effect_description = special_descriptions['flame-boots']}}
|
||||
}
|
||||
|
||||
for _, item in pairs(market_items) do
|
||||
this.market.add_market_item(item)
|
||||
end
|
||||
|
||||
if not this.railgun_enhancer_unlocked then
|
||||
this.market.add_market_item(
|
||||
{
|
||||
price = {{'coin', 1500}},
|
||||
offer = {type = 'nothing', effect_description = special_descriptions['railgun-enhancer']}
|
||||
}
|
||||
)
|
||||
end
|
||||
if not this.trapped_capsules_unlocked then
|
||||
this.market.add_market_item(
|
||||
{
|
||||
price = {{'coin', 3500}},
|
||||
offer = {type = 'nothing', effect_description = special_descriptions['trapped-capsules']}
|
||||
}
|
||||
)
|
||||
end
|
||||
if not this.explosive_bullets_unlocked then
|
||||
this.market.add_market_item(
|
||||
{
|
||||
price = {{'coin', 4500}},
|
||||
offer = {type = 'nothing', effect_description = special_descriptions['explosive-bullets']}
|
||||
}
|
||||
)
|
||||
end
|
||||
if not this.bouncy_shells_unlocked then
|
||||
this.market.add_market_item(
|
||||
{
|
||||
price = {{'coin', 10000}},
|
||||
offer = {type = 'nothing', effect_description = special_descriptions['bouncy-shells']}
|
||||
}
|
||||
)
|
||||
end
|
||||
if not this.vehicle_nanobots_unlocked then
|
||||
this.market.add_market_item(
|
||||
{
|
||||
price = {{'coin', 15000}},
|
||||
offer = {type = 'nothing', effect_description = special_descriptions['vehicle-nanobots']}
|
||||
}
|
||||
)
|
||||
end
|
||||
--[[
|
||||
if not this.crumbly_walls_unlocked then
|
||||
this.market.add_market_item({price = {{"coin", 35000}}, offer = {type = 'nothing', effect_description = special_descriptions["crumbly-walls"]}})
|
||||
end
|
||||
if not this.ultra_mines_unlocked then
|
||||
this.market.add_market_item({price = {{"coin", 45000}}, offer = {type = 'nothing', effect_description = special_descriptions["ultra-mines"]}})
|
||||
end
|
||||
]]
|
||||
if not this.laser_pointer_unlocked then
|
||||
this.market.add_market_item(
|
||||
{
|
||||
price = {{'coin', 65000}},
|
||||
offer = {type = 'nothing', effect_description = special_descriptions['laser-pointer']}
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local function slot_upgrade(player, offer_index)
|
||||
local this = FDT.get()
|
||||
local price =
|
||||
this.entity_limits[slot_upgrade_offers[offer_index][1]].limit *
|
||||
this.entity_limits[slot_upgrade_offers[offer_index][1]].slot_price
|
||||
|
||||
local gain = 1
|
||||
if offer_index == 5 then
|
||||
price =
|
||||
math.ceil(
|
||||
(this.entity_limits[slot_upgrade_offers[offer_index][1]].limit / 3) *
|
||||
this.entity_limits[slot_upgrade_offers[offer_index][1]].slot_price
|
||||
)
|
||||
gain = 3
|
||||
end
|
||||
|
||||
if slot_upgrade_offers[offer_index][1] == 'flamethrower-turret' then
|
||||
price =
|
||||
(this.entity_limits[slot_upgrade_offers[offer_index][1]].limit + 1) *
|
||||
this.entity_limits[slot_upgrade_offers[offer_index][1]].slot_price
|
||||
end
|
||||
|
||||
local coins_removed = player.remove_item({name = 'coin', count = price})
|
||||
if coins_removed ~= price then
|
||||
if coins_removed > 0 then
|
||||
player.insert({name = 'coin', count = coins_removed})
|
||||
end
|
||||
player.print('Not enough coins.', {r = 0.22, g = 0.77, b = 0.44})
|
||||
return false
|
||||
end
|
||||
|
||||
this.entity_limits[slot_upgrade_offers[offer_index][1]].limit =
|
||||
this.entity_limits[slot_upgrade_offers[offer_index][1]].limit + gain
|
||||
game.print(
|
||||
player.name .. ' has bought a ' .. slot_upgrade_offers[offer_index][2] .. ' slot for ' .. price .. ' coins!',
|
||||
{r = 0.22, g = 0.77, b = 0.44}
|
||||
)
|
||||
if math.random(1, 2) == 1 then
|
||||
Server.to_discord_bold(
|
||||
table.concat {
|
||||
'*** ' ..
|
||||
player.name ..
|
||||
' has bought a ' ..
|
||||
slot_upgrade_offers[offer_index][2] .. ' slot for ' .. price .. ' coins! ***'
|
||||
}
|
||||
)
|
||||
end
|
||||
refresh_market_offers()
|
||||
end
|
||||
|
||||
local function on_market_item_purchased(event)
|
||||
local player = game.players[event.player_index]
|
||||
local market = event.market
|
||||
local offer_index = event.offer_index
|
||||
local offers = market.get_market_items()
|
||||
local bought_offer = offers[offer_index].offer
|
||||
if bought_offer.type ~= 'nothing' then
|
||||
return
|
||||
end
|
||||
local this = FDT.get()
|
||||
|
||||
if slot_upgrade_offers[offer_index] then
|
||||
if slot_upgrade(player, offer_index) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if offer_index < 50 then
|
||||
return
|
||||
end
|
||||
|
||||
if bought_offer.effect_description == special_descriptions['flame-boots'] then
|
||||
game.print(player.name .. ' has bought themselves some flame boots.', {r = 0.22, g = 0.77, b = 0.44})
|
||||
if not this.flame_boots[player.index].fuel then
|
||||
this.flame_boots[player.index].fuel = math.random(1500, 3000)
|
||||
else
|
||||
this.flame_boots[player.index].fuel = this.flame_boots[player.index].fuel + math.random(1500, 3000)
|
||||
end
|
||||
|
||||
player.print('Fuel remaining: ' .. this.flame_boots[player.index].fuel, {r = 0.22, g = 0.77, b = 0.44})
|
||||
refresh_market_offers()
|
||||
return
|
||||
end
|
||||
|
||||
if bought_offer.effect_description == special_descriptions['explosive-bullets'] then
|
||||
game.print(player.name .. ' has unlocked explosive bullets.', {r = 0.22, g = 0.77, b = 0.44})
|
||||
this.explosive_bullets_unlocked = true
|
||||
refresh_market_offers()
|
||||
return
|
||||
end
|
||||
|
||||
if bought_offer.effect_description == special_descriptions['bouncy-shells'] then
|
||||
game.print(player.name .. ' has unlocked bouncy shells.', {r = 0.22, g = 0.77, b = 0.44})
|
||||
this.bouncy_shells_unlocked = true
|
||||
refresh_market_offers()
|
||||
return
|
||||
end
|
||||
|
||||
if bought_offer.effect_description == special_descriptions['trapped-capsules'] then
|
||||
game.print(player.name .. ' has unlocked trapped capsules!', {r = 0.22, g = 0.77, b = 0.44})
|
||||
this.trapped_capsules_unlocked = true
|
||||
refresh_market_offers()
|
||||
return
|
||||
end
|
||||
|
||||
if bought_offer.effect_description == special_descriptions['ultra-mines'] then
|
||||
game.print(player.name .. ' has unlocked ultra mines!', {r = 0.22, g = 0.77, b = 0.44})
|
||||
this.ultra_mines_unlocked = true
|
||||
refresh_market_offers()
|
||||
return
|
||||
end
|
||||
|
||||
if bought_offer.effect_description == special_descriptions['laser-pointer'] then
|
||||
game.print(player.name .. ' has unleashed the quest to slay the red dot!', {r = 0.22, g = 0.77, b = 0.44})
|
||||
this.laser_pointer_unlocked = true
|
||||
refresh_market_offers()
|
||||
return
|
||||
end
|
||||
|
||||
if bought_offer.effect_description == special_descriptions['railgun-enhancer'] then
|
||||
game.print(player.name .. ' has unlocked the enhanced railgun!', {r = 0.22, g = 0.77, b = 0.44})
|
||||
this.railgun_enhancer_unlocked = true
|
||||
refresh_market_offers()
|
||||
return
|
||||
end
|
||||
|
||||
if bought_offer.effect_description == special_descriptions['crumbly-walls'] then
|
||||
game.print(player.name .. ' has unlocked crumbly walls!', {r = 0.22, g = 0.77, b = 0.44})
|
||||
this.crumbly_walls_unlocked = true
|
||||
refresh_market_offers()
|
||||
return
|
||||
end
|
||||
|
||||
if bought_offer.effect_description == special_descriptions['vehicle-nanobots'] then
|
||||
game.print(player.name .. ' has unlocked vehicle nanobots!', {r = 0.22, g = 0.77, b = 0.44})
|
||||
this.vehicle_nanobots_unlocked = true
|
||||
refresh_market_offers()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local function on_gui_opened(event)
|
||||
if not event.entity then
|
||||
return
|
||||
end
|
||||
if not event.entity.valid then
|
||||
return
|
||||
end
|
||||
if event.entity.name == 'market' then
|
||||
refresh_market_offers()
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
|
||||
Event.add(defines.events.on_gui_opened, on_gui_opened)
|
65
maps/crab_defender/on_entity_damaged.lua
Normal file
65
maps/crab_defender/on_entity_damaged.lua
Normal file
@ -0,0 +1,65 @@
|
||||
require 'maps.crab_defender.boss_biters'
|
||||
|
||||
local Event = require 'utils.event'
|
||||
local enhance_railgun = require 'maps.crab_defender.railgun_enhancer'
|
||||
local explosive_bullets = require 'maps.crab_defender.explosive_gun_bullets'
|
||||
local bouncy_shells = require 'maps.crab_defender.bouncy_shells'
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
|
||||
local function protect_market(event)
|
||||
if event.entity.name ~= 'market' then
|
||||
return
|
||||
end
|
||||
if event.cause then
|
||||
if event.cause.force.name == 'enemy' then
|
||||
return
|
||||
end
|
||||
end
|
||||
event.entity.health = event.entity.health + event.final_damage_amount
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
if not event.entity then
|
||||
return
|
||||
end
|
||||
if not event.entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if protect_market(event) then
|
||||
return
|
||||
end
|
||||
|
||||
if not event.cause then
|
||||
return
|
||||
end
|
||||
local explosive_bullets_unlocked = FDT.get('explosive_bullets_unlocked')
|
||||
local bouncy_shells_unlocked = FDT.get('bouncy_shells_unlocked')
|
||||
|
||||
--if event.cause.unit_number then
|
||||
-- if this.boss_biters[event.cause.unit_number] then
|
||||
-- boss_biter.damaged_entity(event)
|
||||
-- end
|
||||
--end
|
||||
|
||||
if event.cause.name ~= 'character' then
|
||||
return
|
||||
end
|
||||
|
||||
if enhance_railgun(event) then
|
||||
return
|
||||
end
|
||||
if explosive_bullets_unlocked then
|
||||
if explosive_bullets(event) then
|
||||
return
|
||||
end
|
||||
end
|
||||
if bouncy_shells_unlocked then
|
||||
if bouncy_shells(event) then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
157
maps/crab_defender/railgun_enhancer.lua
Normal file
157
maps/crab_defender/railgun_enhancer.lua
Normal file
@ -0,0 +1,157 @@
|
||||
-- improves the damage of the railgun and adds visual effects -- by mewmew
|
||||
-- laser turret research will increase it´s damage even further --
|
||||
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
|
||||
local damage_min = 400
|
||||
local damage_max = 800
|
||||
local math_random = math.random
|
||||
local additional_visual_effects = true
|
||||
|
||||
local biological_target_types = {
|
||||
['unit'] = true,
|
||||
['player'] = true,
|
||||
['turret'] = true,
|
||||
['unit-spawner'] = true
|
||||
}
|
||||
|
||||
local function create_visuals(source_entity, target_entity)
|
||||
if not source_entity.valid then
|
||||
return
|
||||
end
|
||||
if not target_entity.valid then
|
||||
return
|
||||
end
|
||||
if not additional_visual_effects then
|
||||
return
|
||||
end
|
||||
local surface = target_entity.surface
|
||||
surface.create_entity({name = 'water-splash', position = target_entity.position})
|
||||
if biological_target_types[target_entity.type] then
|
||||
surface.create_entity({name = 'blood-explosion-big', position = target_entity.position})
|
||||
for x = -8, 8, 1 do
|
||||
for y = -8, 8, 1 do
|
||||
if math_random(1, 16) == 1 then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'blood-fountain',
|
||||
position = {target_entity.position.x + (x * 0.1), target_entity.position.y + (y * 0.1)}
|
||||
}
|
||||
)
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'blood-fountain-big',
|
||||
position = {target_entity.position.x + (x * 0.1), target_entity.position.y + (y * 0.1)}
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if math_random(1, 3) ~= 1 then
|
||||
surface.create_entity({name = 'fire-flame', position = target_entity.position})
|
||||
end
|
||||
for x = -3, 3, 1 do
|
||||
for y = -3, 3, 1 do
|
||||
if math_random(1, 3) == 1 then
|
||||
surface.create_trivial_smoke(
|
||||
{
|
||||
name = 'smoke-fast',
|
||||
position = {target_entity.position.x + (x * 0.35), target_entity.position.y + (y * 0.35)}
|
||||
}
|
||||
)
|
||||
end
|
||||
if math_random(1, 5) == 1 then
|
||||
surface.create_trivial_smoke(
|
||||
{
|
||||
name = 'train-smoke',
|
||||
position = {target_entity.position.x + (x * 0.35), target_entity.position.y + (y * 0.35)}
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function do_splash_damage_around_entity(source_entity, player)
|
||||
if not source_entity.valid then
|
||||
return
|
||||
end
|
||||
local research_damage_bonus = player.force.get_ammo_damage_modifier('laser-turret') + 1
|
||||
local research_splash_radius_bonus = player.force.get_ammo_damage_modifier('laser-turret') * 0.5
|
||||
local splash_area = {
|
||||
{
|
||||
source_entity.position.x - (2.5 + research_splash_radius_bonus),
|
||||
source_entity.position.y - (2.5 + research_splash_radius_bonus)
|
||||
},
|
||||
{
|
||||
source_entity.position.x + (2.5 + research_splash_radius_bonus),
|
||||
source_entity.position.y + (2.5 + research_splash_radius_bonus)
|
||||
}
|
||||
}
|
||||
local entities = source_entity.surface.find_entities_filtered({area = splash_area})
|
||||
for _, entity in pairs(entities) do
|
||||
if entity.valid then
|
||||
if entity.health and entity ~= source_entity and entity ~= player then
|
||||
if additional_visual_effects then
|
||||
local surface = entity.surface
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'railgun-beam',
|
||||
position = source_entity.position,
|
||||
source = source_entity.position,
|
||||
target = entity.position
|
||||
}
|
||||
)
|
||||
surface.create_entity({name = 'water-splash', position = entity.position})
|
||||
if biological_target_types[entity.type] then
|
||||
surface.create_entity({name = 'blood-fountain', position = entity.position})
|
||||
end
|
||||
end
|
||||
local damage =
|
||||
math_random(
|
||||
math.ceil((damage_min * research_damage_bonus) / 16),
|
||||
math.ceil((damage_max * research_damage_bonus) / 16)
|
||||
)
|
||||
entity.damage(damage, player.force, 'physical')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function enhance(event)
|
||||
local railgun_enhancer_unlocked = FDT.get('railgun_enhancer_unlocked')
|
||||
if not railgun_enhancer_unlocked then
|
||||
return
|
||||
end
|
||||
if event.damage_type.name ~= 'physical' then
|
||||
return
|
||||
end
|
||||
if event.original_damage_amount ~= 100 then
|
||||
return
|
||||
end
|
||||
|
||||
local player = event.cause
|
||||
if player.shooting_state.state == defines.shooting.not_shooting then
|
||||
return
|
||||
end
|
||||
local selected_weapon = player.get_inventory(defines.inventory.character_guns)[player.selected_gun_index]
|
||||
if selected_weapon.name ~= 'railgun' then
|
||||
return
|
||||
end
|
||||
|
||||
create_visuals(event.cause, event.entity)
|
||||
|
||||
do_splash_damage_around_entity(event.entity, player)
|
||||
|
||||
event.entity.health = event.entity.health + event.final_damage_amount
|
||||
|
||||
local research_damage_bonus = player.force.get_ammo_damage_modifier('laser-turret') + 1
|
||||
local damage =
|
||||
math_random(math.ceil(damage_min * research_damage_bonus), math.ceil(damage_max * research_damage_bonus))
|
||||
event.entity.damage(damage, player.force, 'physical')
|
||||
return true
|
||||
end
|
||||
|
||||
return enhance
|
31
maps/crab_defender/shotgun_buff.lua
Normal file
31
maps/crab_defender/shotgun_buff.lua
Normal file
@ -0,0 +1,31 @@
|
||||
local Event = require 'utils.event'
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
local gain_multiplier = 4
|
||||
|
||||
local function on_research_finished(event)
|
||||
local research = event.research
|
||||
local force_name = research.force.name
|
||||
local this = FDT.get()
|
||||
|
||||
if not this.shotgun_shell_damage_modifier_old[force_name] then
|
||||
this.shotgun_shell_damage_modifier_old[force_name] =
|
||||
game.forces[force_name].get_ammo_damage_modifier('shotgun-shell') - 0.1
|
||||
end
|
||||
|
||||
if string.sub(research.name, 0, 26) == 'physical-projectile-damage' then
|
||||
local current_damage = game.forces[force_name].get_ammo_damage_modifier('shotgun-shell')
|
||||
local vanilla_gain = current_damage - this.shotgun_shell_damage_modifier_old[force_name]
|
||||
local additional_gain = vanilla_gain * (gain_multiplier - 1)
|
||||
game.forces[force_name].set_ammo_damage_modifier('shotgun-shell', current_damage + additional_gain)
|
||||
end
|
||||
|
||||
this.shotgun_shell_damage_modifier_old[force_name] =
|
||||
game.forces[force_name].get_ammo_damage_modifier('shotgun-shell')
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
game.forces.player.set_ammo_damage_modifier('shotgun-shell', 1)
|
||||
end
|
||||
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
102
maps/crab_defender/table.lua
Normal file
102
maps/crab_defender/table.lua
Normal file
@ -0,0 +1,102 @@
|
||||
-- one table to rule them all!
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local this = {}
|
||||
local Public = {}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
this = tbl
|
||||
end
|
||||
)
|
||||
|
||||
function Public.reset_table()
|
||||
-- @start
|
||||
-- these 3 are in case of stop/start/reloading the instance.
|
||||
this.soft_reset = true
|
||||
this.restart = false
|
||||
this.shutdown = false
|
||||
this.announced_message = false
|
||||
this.force_chunk = false
|
||||
-- @end
|
||||
this.game_has_ended = false
|
||||
this.game_reset = false
|
||||
this.spawn_area_generated = false
|
||||
this.results_sent = false
|
||||
|
||||
this.explosive_bullets_unlocked = false
|
||||
this.bouncy_shells_unlocked = false
|
||||
this.trapped_capsules_unlocked = false
|
||||
this.ultra_mines_unlocked = false
|
||||
this.laser_pointer_unlocked = false
|
||||
this.railgun_enhancer_unlocked = false
|
||||
this.crumbly_walls_unlocked = false
|
||||
this.vehicle_nanobots_unlocked = false
|
||||
this.game_restart_timer = nil
|
||||
this.wave_count = 0
|
||||
this.attack_wave_threat = nil
|
||||
this.market = nil
|
||||
this.market_age = nil
|
||||
this.last_reset = game.tick
|
||||
this.wave_interval = 3600
|
||||
this.wave_grace_period = game.tick + 3600 * 20
|
||||
-- this.wave_grace_period = game.tick + 3600
|
||||
this.boss_biters = {}
|
||||
this.acid_lines_delay = {}
|
||||
this.entity_limits = {
|
||||
['gun-turret'] = {placed = 1, limit = 1, str = 'gun turret', slot_price = 75},
|
||||
['laser-turret'] = {placed = 0, limit = 1, str = 'laser turret', slot_price = 300},
|
||||
['artillery-turret'] = {placed = 0, limit = 1, str = 'artillery turret', slot_price = 500},
|
||||
['flamethrower-turret'] = {placed = 0, limit = 0, str = 'flamethrower turret', slot_price = 50000},
|
||||
['land-mine'] = {placed = 0, limit = 1, str = 'mine', slot_price = 20}
|
||||
}
|
||||
this.difficulties_votes = {
|
||||
[1] = {wave_interval = 4500, amount_modifier = 0.52, strength_modifier = 0.40, boss_modifier = 3.0},
|
||||
[2] = {wave_interval = 4100, amount_modifier = 0.76, strength_modifier = 0.65, boss_modifier = 4.0},
|
||||
[3] = {wave_interval = 3800, amount_modifier = 0.92, strength_modifier = 0.85, boss_modifier = 5.0},
|
||||
[4] = {wave_interval = 3600, amount_modifier = 1.00, strength_modifier = 1.00, boss_modifier = 6.0},
|
||||
[5] = {wave_interval = 3400, amount_modifier = 1.08, strength_modifier = 1.25, boss_modifier = 7.0},
|
||||
[6] = {wave_interval = 3100, amount_modifier = 1.24, strength_modifier = 1.75, boss_modifier = 8.0},
|
||||
[7] = {wave_interval = 2700, amount_modifier = 1.48, strength_modifier = 2.50, boss_modifier = 9.0}
|
||||
}
|
||||
this.boss_waves = {
|
||||
[50] = {{name = 'big-biter', count = 3}},
|
||||
[100] = {{name = 'behemoth-biter', count = 1}},
|
||||
[150] = {{name = 'behemoth-spitter', count = 4}, {name = 'big-spitter', count = 16}},
|
||||
[200] = {
|
||||
{name = 'behemoth-biter', count = 4},
|
||||
{name = 'behemoth-spitter', count = 2},
|
||||
{name = 'big-biter', count = 32}
|
||||
},
|
||||
[250] = {
|
||||
{name = 'behemoth-biter', count = 8},
|
||||
{name = 'behemoth-spitter', count = 4},
|
||||
{name = 'big-spitter', count = 32}
|
||||
},
|
||||
[300] = {{name = 'behemoth-biter', count = 16}, {name = 'behemoth-spitter', count = 8}}
|
||||
}
|
||||
this.comfylatron_habitat = {
|
||||
left_top = {x = -1500, y = -1500},
|
||||
right_bottom = {x = -80, y = 1500}
|
||||
}
|
||||
this.shotgun_shell_damage_modifier_old = {}
|
||||
this.flame_boots = {}
|
||||
end
|
||||
|
||||
function Public.get(key)
|
||||
if key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function()
|
||||
Public.reset_table()
|
||||
end
|
||||
|
||||
Event.on_init(on_init)
|
||||
|
||||
return Public
|
300
maps/crab_defender/terrain.lua
Normal file
300
maps/crab_defender/terrain.lua
Normal file
@ -0,0 +1,300 @@
|
||||
local Event = require 'utils.event'
|
||||
local Builder = require 'maps.crab_defender.b'
|
||||
local map_functions = require 'tools.map_functions'
|
||||
local simplex_noise = require 'utils.simplex_noise'.d2
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
local math_random = math.random
|
||||
local math_abs = math.abs
|
||||
|
||||
local function shuffle(tbl)
|
||||
local size = #tbl
|
||||
for i = size, 1, -1 do
|
||||
local rand = math.random(size)
|
||||
tbl[i], tbl[rand] = tbl[rand], tbl[i]
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function get_replacement_tile(surface, position)
|
||||
for i = 1, 128, 1 do
|
||||
local vectors = {{0, i}, {0, i * -1}, {i, 0}, {i * -1, 0}}
|
||||
shuffle(vectors)
|
||||
for k, v in pairs(vectors) do
|
||||
local tile = surface.get_tile(position.x + v[1], position.y + v[2])
|
||||
if not tile.collides_with('resource-layer') then
|
||||
return tile.name
|
||||
end
|
||||
end
|
||||
end
|
||||
return 'grass-1'
|
||||
end
|
||||
|
||||
local function is_enemy_territory(surface, p)
|
||||
local get_tile = surface.get_tile(p)
|
||||
if get_tile.valid and get_tile.name == 'tutorial-grid' then
|
||||
return true
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function place_crab_market(surface, position)
|
||||
local market = surface.create_entity({name = 'market', position = position, force = 'player'})
|
||||
market.minable = false
|
||||
return market
|
||||
end
|
||||
|
||||
local function enemy_territory(surface, left_top)
|
||||
if left_top.x > 778 then
|
||||
return
|
||||
end
|
||||
if left_top.x < -607 then
|
||||
return
|
||||
end
|
||||
if left_top.y < -590 then
|
||||
return
|
||||
end
|
||||
if left_top.y > -150 then
|
||||
return
|
||||
end
|
||||
|
||||
local area = {{left_top.x, left_top.y}, {left_top.x + 32, left_top.y + 32}}
|
||||
local find_entities_filtered = surface.find_entities_filtered
|
||||
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local pos = {x = left_top.x + x, y = left_top.y + y}
|
||||
local get_tile = surface.get_tile(pos)
|
||||
|
||||
if is_enemy_territory(surface, pos) then
|
||||
if get_tile.valid and get_tile.name == 'tutorial-grid' then
|
||||
if math_random(1, 1024) == 1 then
|
||||
if surface.can_place_entity({name = 'biter-spawner', force = 'decoratives', position = pos}) then
|
||||
local entity
|
||||
if math_random(1, 4) == 1 then
|
||||
entity =
|
||||
surface.create_entity(
|
||||
{name = 'spitter-spawner', force = 'decoratives', position = pos}
|
||||
)
|
||||
else
|
||||
entity =
|
||||
surface.create_entity(
|
||||
{name = 'biter-spawner', force = 'decoratives', position = pos}
|
||||
)
|
||||
end
|
||||
entity.active = false
|
||||
entity.destructible = false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for _, entity in pairs(find_entities_filtered({area = area, type = 'resource'})) do
|
||||
if is_enemy_territory(surface, entity.position) then
|
||||
surface.create_entity({name = 'uranium-ore', position = entity.position, amount = math_random(200, 8000)})
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function render_market_hp()
|
||||
local this = FDT.get()
|
||||
local surface = game.surfaces[this.active_surface_index]
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
this.caption =
|
||||
rendering.draw_text {
|
||||
text = 'Crab Market',
|
||||
surface = surface,
|
||||
target = this.market,
|
||||
target_offset = {0, -3.4},
|
||||
color = {0, 255, 0},
|
||||
scale = 1.80,
|
||||
font = 'default-game',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
end
|
||||
|
||||
local function generate_spawn_area(this, surface)
|
||||
if this.spawn_area_generated then
|
||||
return
|
||||
end
|
||||
local find_entities_filtered = surface.find_entities_filtered
|
||||
|
||||
surface.request_to_generate_chunks({x = 0, y = 0}, 1)
|
||||
surface.request_to_generate_chunks({x = 32, y = 118}, 1)
|
||||
|
||||
if not surface.is_chunk_generated({-7, 0}) then
|
||||
return
|
||||
end
|
||||
if not surface.is_chunk_generated({5, 0}) then
|
||||
return
|
||||
end
|
||||
|
||||
local spawn_position_x = 32
|
||||
local spawn_position_y = 120
|
||||
|
||||
surface.create_entity({name = 'electric-beam', position = {-532, -10}, source = {-532, -10}, target = {-471, -124}})
|
||||
surface.create_entity({name = 'electric-beam', position = {665, -10}, source = {665, -10}, target = {601, -127}})
|
||||
|
||||
for _, tile in pairs(surface.find_tiles_filtered({name = {'water', 'deepwater'}, area = {{-145, -133}, {32, 59}}})) do
|
||||
local noise =
|
||||
math_abs(
|
||||
simplex_noise(tile.position.x * 0.02, tile.position.y * 0.02, game.surfaces[1].map_gen_settings.seed) * 16
|
||||
)
|
||||
if tile.position.x > -160 + noise then
|
||||
surface.set_tiles(
|
||||
{{name = get_replacement_tile(surface, tile.position), position = {tile.position.x, tile.position.y}}},
|
||||
true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
for _, entity in pairs(
|
||||
find_entities_filtered(
|
||||
{
|
||||
type = {'resource', 'cliff'},
|
||||
area = {
|
||||
{spawn_position_x - 128, spawn_position_y - 132},
|
||||
{spawn_position_x + 64, spawn_position_y + 32}
|
||||
}
|
||||
}
|
||||
)
|
||||
) do
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
local decorative_names = {}
|
||||
for k, v in pairs(game.decorative_prototypes) do
|
||||
if v.autoplace_specification then
|
||||
decorative_names[#decorative_names + 1] = k
|
||||
end
|
||||
end
|
||||
for x = -4, 4, 1 do
|
||||
for y = -3, 3, 1 do
|
||||
surface.regenerate_decorative(decorative_names, {{x, y}})
|
||||
end
|
||||
end
|
||||
|
||||
local ore_positions = {
|
||||
{x = spawn_position_x - 80, y = spawn_position_y + 50},
|
||||
{x = spawn_position_x - 40, y = spawn_position_y + 50},
|
||||
{x = spawn_position_x, y = spawn_position_y + 50},
|
||||
{x = spawn_position_x + 40, y = spawn_position_y + 50},
|
||||
{x = spawn_position_x + 80, y = spawn_position_y + 50}
|
||||
}
|
||||
shuffle(ore_positions)
|
||||
map_functions.draw_smoothed_out_ore_circle(ore_positions[1], 'copper-ore', surface, 15, 2500)
|
||||
map_functions.draw_smoothed_out_ore_circle(ore_positions[2], 'iron-ore', surface, 15, 2500)
|
||||
map_functions.draw_smoothed_out_ore_circle(ore_positions[3], 'coal', surface, 15, 1500)
|
||||
map_functions.draw_smoothed_out_ore_circle(ore_positions[4], 'stone', surface, 15, 1500)
|
||||
map_functions.draw_noise_tile_circle({x = spawn_position_x, y = spawn_position_y + 25}, 'water', surface, 16)
|
||||
map_functions.draw_oil_circle(ore_positions[5], 'crude-oil', surface, 8, 200000)
|
||||
|
||||
local pos = surface.find_non_colliding_position('market', {spawn_position_x, spawn_position_y}, 50, 1)
|
||||
this.market = place_crab_market(surface, pos)
|
||||
|
||||
render_market_hp()
|
||||
|
||||
local r = 32
|
||||
for _, entity in pairs(
|
||||
find_entities_filtered(
|
||||
{
|
||||
area = {
|
||||
{this.market.position.x - r, this.market.position.y - r},
|
||||
{this.market.position.x + r, this.market.position.y + r}
|
||||
},
|
||||
type = 'tree'
|
||||
}
|
||||
)
|
||||
) do
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
local turret_pos =
|
||||
surface.find_non_colliding_position('gun-turret', {spawn_position_x, spawn_position_y - 5}, 50, 1)
|
||||
local turret = surface.create_entity({name = 'gun-turret', position = turret_pos, force = 'player'})
|
||||
turret.insert({name = 'firearm-magazine', count = 32})
|
||||
|
||||
for x = -20, 20, 1 do
|
||||
for y = -20, 20, 1 do
|
||||
local market_pos = {x = this.market.position.x + x, y = this.market.position.y + y}
|
||||
local distance_to_center = x ^ 2 + y ^ 2
|
||||
if distance_to_center > 64 and distance_to_center < 225 then
|
||||
if
|
||||
math_random(1, 3) == 1 and
|
||||
surface.can_place_entity({name = 'wooden-chest', position = market_pos, force = 'player'})
|
||||
then
|
||||
surface.create_entity({name = 'wooden-chest', position = market_pos, force = 'player'})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local area = {{x = -160, y = -96}, {x = 160, y = 96}}
|
||||
for _, tile in pairs(surface.find_tiles_filtered({name = 'water', area = area})) do
|
||||
if math_random(1, 32) == 1 then
|
||||
surface.create_entity({name = 'fish', position = tile.position})
|
||||
end
|
||||
end
|
||||
|
||||
local character_pos =
|
||||
surface.find_non_colliding_position('character', {spawn_position_x + 1, spawn_position_y}, 50, 1)
|
||||
game.forces['player'].set_spawn_position(character_pos, surface)
|
||||
for _, player in pairs(game.connected_players) do
|
||||
local spawn_pos =
|
||||
surface.find_non_colliding_position('character', {spawn_position_x + 1, spawn_position_y}, 50, 1)
|
||||
player.teleport(spawn_pos, surface)
|
||||
end
|
||||
this.spawn_area_generated = true
|
||||
end
|
||||
|
||||
local function process_chunk(left_top)
|
||||
local this = FDT.get()
|
||||
local surface = game.surfaces[this.active_surface_index]
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
local find_entities_filtered = surface.find_entities_filtered
|
||||
|
||||
generate_spawn_area(this, surface, left_top)
|
||||
enemy_territory(surface, left_top)
|
||||
|
||||
for _, entity in pairs(
|
||||
find_entities_filtered(
|
||||
{
|
||||
area = {{left_top.x - 32, left_top.y - 32}, {left_top.x + 32, left_top.y + 32}},
|
||||
type = {'tree', 'simple-entity', 'cliff'}
|
||||
}
|
||||
)
|
||||
) do
|
||||
if is_enemy_territory(surface, entity.position) then
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
game.forces.player.chart(surface, {{left_top.x, left_top.y}, {left_top.x + 31, left_top.y + 31}})
|
||||
if this.market and this.market.valid then
|
||||
this.game_reset = false
|
||||
end
|
||||
end
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
local map_name = 'crab_defender'
|
||||
|
||||
if string.sub(event.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
end
|
||||
|
||||
local left_top = event.area.left_top
|
||||
Builder.make_chunk(event)
|
||||
|
||||
process_chunk(left_top)
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
|
61
maps/crab_defender/trapped_capsules.lua
Normal file
61
maps/crab_defender/trapped_capsules.lua
Normal file
@ -0,0 +1,61 @@
|
||||
local Event = require 'utils.event'
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
|
||||
local radius = 20
|
||||
|
||||
local whitelist = {
|
||||
['defender'] = 'explosive-cannon-projectile',
|
||||
['distractor'] = 'explosive-uranium-cannon-projectile',
|
||||
['destroyer'] = 'explosive-uranium-cannon-projectile'
|
||||
}
|
||||
|
||||
local function on_entity_died(event)
|
||||
local trapped_capsules_unlocked = FDT.get('trapped_capsules_unlocked')
|
||||
if not trapped_capsules_unlocked then
|
||||
return
|
||||
end
|
||||
|
||||
if not event.entity.valid then
|
||||
return
|
||||
end
|
||||
if not whitelist[event.entity.name] then
|
||||
return
|
||||
end
|
||||
|
||||
local valid_targets = {}
|
||||
local position = event.entity.position
|
||||
|
||||
for _, e in pairs(
|
||||
event.entity.surface.find_entities_filtered(
|
||||
{
|
||||
area = {{position.x - radius, position.y - radius}, {position.x + radius, position.y + radius}},
|
||||
force = 'enemy'
|
||||
}
|
||||
)
|
||||
) do
|
||||
if e.health then
|
||||
local distance_from_center = math.sqrt((e.position.x - position.x) ^ 2 + (e.position.y - position.y) ^ 2)
|
||||
if distance_from_center <= radius then
|
||||
valid_targets[#valid_targets + 1] = e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not valid_targets[1] then
|
||||
return
|
||||
end
|
||||
|
||||
event.entity.surface.create_entity(
|
||||
{
|
||||
name = whitelist[event.entity.name],
|
||||
position = position,
|
||||
force = 'player',
|
||||
source = position,
|
||||
target = valid_targets[math.random(1, #valid_targets)].position,
|
||||
max_range = 20,
|
||||
speed = 0.1
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
52
maps/crab_defender/ultra_mines.lua
Normal file
52
maps/crab_defender/ultra_mines.lua
Normal file
@ -0,0 +1,52 @@
|
||||
local Event = require 'utils.event'
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
local radius = 8
|
||||
|
||||
local function damage_entities_around_target(entity, damage)
|
||||
for _, e in pairs(
|
||||
entity.surface.find_entities_filtered(
|
||||
{
|
||||
area = {
|
||||
{entity.position.x - radius, entity.position.y - radius},
|
||||
{entity.position.x + radius, entity.position.y + radius}
|
||||
}
|
||||
}
|
||||
)
|
||||
) do
|
||||
if e.health then
|
||||
if e.force.name ~= 'player' then
|
||||
local distance_from_center =
|
||||
math.sqrt((e.position.x - entity.position.x) ^ 2 + (e.position.y - entity.position.y) ^ 2)
|
||||
if distance_from_center <= radius then
|
||||
e.damage(damage, 'player', 'explosion')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local ultra_mines_unlocked = FDT.get('ultra_mines_unlocked')
|
||||
if not ultra_mines_unlocked then
|
||||
return
|
||||
end
|
||||
if not event.entity.valid then
|
||||
return
|
||||
end
|
||||
if event.entity.name ~= 'land-mine' then
|
||||
return
|
||||
end
|
||||
|
||||
event.entity.surface.create_entity(
|
||||
{
|
||||
name = 'big-artillery-explosion',
|
||||
position = event.entity.position
|
||||
}
|
||||
)
|
||||
|
||||
local damage = (1 + event.entity.force.get_ammo_damage_modifier('grenade')) * 250
|
||||
|
||||
damage_entities_around_target(event.entity, damage)
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
29
maps/crab_defender/vehicle_nanobots.lua
Normal file
29
maps/crab_defender/vehicle_nanobots.lua
Normal file
@ -0,0 +1,29 @@
|
||||
local Event = require 'utils.event'
|
||||
local FDT = require 'maps.crab_defender.table'
|
||||
|
||||
local function on_player_changed_position(event)
|
||||
local vehicle_nanobots_unlocked = FDT.get('vehicle_nanobots_unlocked')
|
||||
|
||||
if not vehicle_nanobots_unlocked then
|
||||
return
|
||||
end
|
||||
local player = game.players[event.player_index]
|
||||
if not player.character then
|
||||
return
|
||||
end
|
||||
if not player.character.driving then
|
||||
return
|
||||
end
|
||||
if not player.vehicle then
|
||||
return
|
||||
end
|
||||
if not player.vehicle.valid then
|
||||
return
|
||||
end
|
||||
if player.vehicle.health == player.vehicle.prototype.max_health then
|
||||
return
|
||||
end
|
||||
player.vehicle.health = player.vehicle.health + player.vehicle.prototype.max_health * 0.005
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_player_changed_position, on_player_changed_position)
|
221
maps/fish_defender_v2/b.lua
Normal file
221
maps/fish_defender_v2/b.lua
Normal file
@ -0,0 +1,221 @@
|
||||
local simplex_noise = require 'utils.simplex_noise'.d2
|
||||
-- local map_data = require 'maps.fish_defender_v2.fish_defender_layout'
|
||||
local map_data = require 'maps.fish_defender_v2.cat_defender_layout_v2'
|
||||
|
||||
local random = math.random
|
||||
local abs = math.abs
|
||||
local floor = math.floor
|
||||
local scale = 1
|
||||
|
||||
local Public = {}
|
||||
|
||||
local tile_map = {
|
||||
[1] = false,
|
||||
[2] = true,
|
||||
[3] = 'concrete',
|
||||
[4] = 'deepwater-green',
|
||||
[5] = 'deepwater',
|
||||
[6] = 'dirt-1',
|
||||
[7] = 'dirt-2',
|
||||
[8] = 'dirt-3',
|
||||
[9] = 'dirt-4',
|
||||
[10] = 'dirt-5',
|
||||
[11] = 'dirt-6',
|
||||
[12] = 'dirt-7',
|
||||
[13] = 'dry-dirt',
|
||||
[14] = 'grass-1',
|
||||
[15] = 'grass-2',
|
||||
[16] = 'grass-3',
|
||||
[17] = 'grass-4',
|
||||
[18] = 'hazard-concrete-left',
|
||||
[19] = 'hazard-concrete-right',
|
||||
[20] = 'lab-dark-1',
|
||||
[21] = 'lab-dark-2',
|
||||
[22] = 'lab-white',
|
||||
[23] = 'out-of-map',
|
||||
[24] = 'red-desert-0',
|
||||
[25] = 'red-desert-1',
|
||||
[26] = 'red-desert-2',
|
||||
[27] = 'red-desert-3',
|
||||
[28] = 'sand-1',
|
||||
[29] = 'sand-2',
|
||||
[30] = 'sand-3',
|
||||
[31] = 'stone-path',
|
||||
[32] = 'water-green',
|
||||
[33] = 'water'
|
||||
}
|
||||
|
||||
local rock_raffle = {
|
||||
'sand-rock-big',
|
||||
'sand-rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-huge'
|
||||
}
|
||||
|
||||
local function decompress()
|
||||
local decompressed = {}
|
||||
local data = map_data.data
|
||||
local height = map_data.height
|
||||
local width = map_data.width
|
||||
|
||||
for y = 1, height do
|
||||
local row = data[y]
|
||||
local u_row = {}
|
||||
decompressed[y] = u_row
|
||||
local x = 1
|
||||
for index = 1, #row, 2 do
|
||||
local pixel = row[index]
|
||||
local count = row[index + 1]
|
||||
|
||||
for _ = 1, count do
|
||||
u_row[x] = pixel
|
||||
x = x + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return decompressed, width, height
|
||||
end
|
||||
local tile_data, width, height = decompress()
|
||||
|
||||
local function get_pos(x, y)
|
||||
-- the plus one is because lua tables are one based.
|
||||
local half_width = floor(width / 2) + 1
|
||||
local half_height = floor(height / 2) + 1
|
||||
x = x / scale
|
||||
y = y / scale
|
||||
x = floor(x)
|
||||
y = floor(y)
|
||||
local x2 = x + half_width
|
||||
local y2 = y + half_height
|
||||
|
||||
if y2 > 0 and y2 <= height and x2 > 0 and x2 <= width then
|
||||
return tile_map[tile_data[y2][x2]]
|
||||
end
|
||||
end
|
||||
|
||||
local ores = {'coal', 'iron-ore', 'copper-ore', 'stone'}
|
||||
|
||||
local function plankton_territory(position, seed, ent)
|
||||
local noise = simplex_noise(position.x * 0.009, position.y * 0.009, seed)
|
||||
local d = 196
|
||||
|
||||
if get_pos(position.x, position.y) then
|
||||
return
|
||||
end
|
||||
|
||||
if
|
||||
position.x + position.y > (d * -1) - (abs(noise) * d * 3) and
|
||||
position.x > position.y - (d + (abs(noise) * d * 3))
|
||||
then
|
||||
return 'out-of-map'
|
||||
end
|
||||
|
||||
local noise_2 = simplex_noise(position.x * 0.0075, position.y * 0.0075, seed + 10000)
|
||||
--if noise_2 > 0.87 then surface.set_tiles({{name = "deepwater-green", position = position}}, true) return true end
|
||||
if noise_2 > 0.87 then
|
||||
return 'deepwater-green'
|
||||
end
|
||||
if noise_2 > 0.75 then
|
||||
local i = floor(noise * 6) % 4 + 1
|
||||
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
|
||||
ent[#ent + 1] = {name = ores[i], position = position, amount = 1 + 2500 * abs(noise_2 * 3)}
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
if noise_2 < -0.76 then
|
||||
local i = floor(noise * 6) % 4 + 1
|
||||
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
|
||||
if noise_2 < -0.86 then
|
||||
ent[#ent + 1] = {name = 'uranium-ore', position = position, amount = 1 + 1000 * abs(noise_2 * 2)}
|
||||
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
if random(1, 3) ~= 1 then
|
||||
ent[#ent + 1] = {name = rock_raffle[random(1, #rock_raffle)], position = position}
|
||||
end
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
|
||||
if noise < 0.12 and noise > -0.12 then
|
||||
local i = floor(noise * 32) % 4 + 1
|
||||
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
|
||||
if random(1, 5) == 1 then
|
||||
ent[#ent + 1] = {name = rock_raffle[random(1, #rock_raffle)], position = position}
|
||||
end
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
|
||||
--surface.set_tiles({{name = "water", position = position}}, true)
|
||||
if random(1, 128) == 1 then
|
||||
ent[#ent + 1] = {name = 'fish', position = position}
|
||||
end
|
||||
|
||||
return 'water'
|
||||
end
|
||||
|
||||
local function get_random_ore(position)
|
||||
local noise = (position.x * 0.009)
|
||||
local i = floor(noise * 6) % 4 + 1
|
||||
local ore = ores[i]
|
||||
|
||||
return ore
|
||||
end
|
||||
|
||||
function Public.make_chunk(event)
|
||||
local map_name = 'fish_defender'
|
||||
|
||||
if string.sub(event.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = event.surface
|
||||
|
||||
local x1 = event.area.left_top.x
|
||||
local y1 = event.area.left_top.y
|
||||
local x2 = event.area.right_bottom.x
|
||||
local y2 = event.area.right_bottom.y
|
||||
|
||||
local seed = game.surfaces[1].map_gen_settings.seed
|
||||
|
||||
local noise = {}
|
||||
local tiles = {}
|
||||
local ent = {}
|
||||
|
||||
for x = x1, x2 do
|
||||
for y = y1, y2 do
|
||||
local pos = {x = x, y = y}
|
||||
local new = get_pos(x, y)
|
||||
local ore = get_random_ore(pos)
|
||||
|
||||
if new and type(new) == 'string' then
|
||||
if new == 'lab-dark-2' then
|
||||
ent[#ent + 1] = {name = ore, position = pos, amount = 2500}
|
||||
else
|
||||
tiles[#tiles + 1] = {name = new, position = pos}
|
||||
end
|
||||
else
|
||||
local tile_to_set = plankton_territory(pos, seed, ent)
|
||||
if tile_to_set then
|
||||
noise[#noise + 1] = {name = tile_to_set, position = pos}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
surface.set_tiles(tiles, true)
|
||||
surface.set_tiles(noise, true)
|
||||
for i = 1, #ent do
|
||||
if ent[i].amount then
|
||||
surface.create_entity({name = ent[i].name, position = ent[i].position, amount = ent[i].amount})
|
||||
else
|
||||
surface.create_entity({name = ent[i].name, position = ent[i].position})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Public
|
2054
maps/fish_defender_v2/cat_defender_layout.lua
Normal file
2054
maps/fish_defender_v2/cat_defender_layout.lua
Normal file
File diff suppressed because it is too large
Load Diff
2054
maps/fish_defender_v2/cat_defender_layout_v2.lua
Normal file
2054
maps/fish_defender_v2/cat_defender_layout_v2.lua
Normal file
File diff suppressed because it is too large
Load Diff
2054
maps/fish_defender_v2/fish_defender_layout.lua
Normal file
2054
maps/fish_defender_v2/fish_defender_layout.lua
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,6 +2,7 @@
|
||||
|
||||
--require "modules.rpg"
|
||||
|
||||
require 'maps.fish_defender_v2.terrain'
|
||||
require 'maps.fish_defender_v2.market'
|
||||
require 'maps.fish_defender_v2.commands'
|
||||
require 'maps.fish_defender_v2.shotgun_buff'
|
||||
@ -12,8 +13,6 @@ require 'modules.biters_yield_coins'
|
||||
require 'modules.dangerous_goods'
|
||||
require 'modules.custom_death_messages'
|
||||
|
||||
local Terrain = require 'maps.fish_defender_v2.terrain'
|
||||
local Task = require 'utils.task'
|
||||
local Unit_health_booster = require 'modules.biter_health_booster'
|
||||
local Difficulty = require 'modules.difficulty_vote'
|
||||
local Map = require 'modules.map_info'
|
||||
@ -359,8 +358,14 @@ local function spawn_biter(pos, biter_pool)
|
||||
end
|
||||
|
||||
local function get_y_coord_raffle_table()
|
||||
local this = FDT.get()
|
||||
local t = {}
|
||||
for y = -96, 96, 8 do
|
||||
|
||||
--for y = -96, 96, 8 do -- fish
|
||||
for y = -96, 240, 8 do -- cat
|
||||
if this.wave_count <= 80 then
|
||||
y = 0
|
||||
end
|
||||
t[#t + 1] = y
|
||||
end
|
||||
shuffle(t)
|
||||
@ -402,7 +407,9 @@ local function clear_corpses(surface)
|
||||
if this.wave_count > 500 then
|
||||
chance = 2
|
||||
end
|
||||
for _, entity in pairs(surface.find_entities_filtered {type = 'corpse'}) do
|
||||
|
||||
local area = {{-137, -256}, {160, 256}}
|
||||
for _, entity in pairs(surface.find_entities_filtered {area = area, type = 'corpse'}) do
|
||||
if math_random(1, chance) == 1 then
|
||||
entity.destroy()
|
||||
end
|
||||
@ -655,7 +662,7 @@ local function biter_attack_wave()
|
||||
-- end
|
||||
--end
|
||||
|
||||
for _, e in pairs(surface.find_entities_filtered({area = {{110, -256}, {360, 256}}})) do
|
||||
for _, e in pairs(surface.find_entities_filtered({area = {{160, -256}, {360, 256}}})) do
|
||||
damage_entity_outside_and_inside_of_fence(e)
|
||||
end
|
||||
|
||||
@ -673,18 +680,9 @@ local function biter_attack_wave()
|
||||
end
|
||||
|
||||
local biter_pool = get_biter_pool()
|
||||
--local spawners = surface.find_entities_filtered({type = "unit-spawner", area = {{160, -196},{512, 196}}})
|
||||
--shuffle(spawners)
|
||||
|
||||
while this.attack_wave_threat > 0 do
|
||||
for i = 1, #unit_groups, 1 do
|
||||
--local biter
|
||||
--if spawners[i] then
|
||||
--biter = spawn_biter(spawners[i].position, biter_pool)
|
||||
--else
|
||||
--biter = spawn_biter(unit_groups[i].position, biter_pool)
|
||||
--end
|
||||
|
||||
local biter = spawn_biter(unit_groups[i].position, biter_pool)
|
||||
if biter then
|
||||
unit_groups[i].add_member(biter)
|
||||
@ -1035,6 +1033,16 @@ local function on_entity_died(event)
|
||||
return
|
||||
end
|
||||
|
||||
if event.entity == this.market then
|
||||
market_kill_visuals()
|
||||
this.market.die()
|
||||
this.market = nil
|
||||
this.market_age = game.tick - this.last_reset
|
||||
this.game_has_ended = true
|
||||
is_game_lost()
|
||||
return
|
||||
end
|
||||
|
||||
if this.entity_limits[event.entity.name] then
|
||||
this.entity_limits[event.entity.name].placed = this.entity_limits[event.entity.name].placed - 1
|
||||
update_fd_stats()
|
||||
@ -1168,17 +1176,10 @@ local function on_player_changed_position(event)
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
if player.position.x + player.position.y < 0 then
|
||||
return
|
||||
end
|
||||
if player.position.x < player.position.y then
|
||||
return
|
||||
end
|
||||
|
||||
if player.position.x >= 160 then
|
||||
player.teleport({player.position.x - 1, player.position.y}, surface)
|
||||
if player.position.y > this.map_height or player.position.y < this.map_height * -1 then
|
||||
player.teleport({player.position.x, 0}, surface)
|
||||
end
|
||||
player.teleport({player.position.x - 1, 0}, surface)
|
||||
|
||||
if player.character then
|
||||
player.character.health = player.character.health - 25
|
||||
player.character.surface.create_entity({name = 'water-splash', position = player.position})
|
||||
@ -1223,112 +1224,6 @@ local function on_player_respawned(event)
|
||||
player.character.destructible = false
|
||||
end
|
||||
|
||||
local function set_objective_health(final_damage_amount)
|
||||
local this = FDT.get()
|
||||
if final_damage_amount == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if this.market_health <= 0 then
|
||||
this.market.health = this.market.health + final_damage_amount
|
||||
return
|
||||
end
|
||||
|
||||
this.market_health = math.floor(this.market_health - final_damage_amount)
|
||||
if this.market_health > this.market_max_health then
|
||||
this.market_health = this.market_max_health
|
||||
end
|
||||
|
||||
if this.market_health <= 0 then
|
||||
market_kill_visuals()
|
||||
this.market.die()
|
||||
this.market = nil
|
||||
this.market_age = game.tick - this.last_reset
|
||||
this.game_has_ended = true
|
||||
is_game_lost()
|
||||
return
|
||||
end
|
||||
|
||||
local m = this.market_health / this.market_max_health
|
||||
this.market.health = 150 * m
|
||||
|
||||
rendering.set_text(this.health_text, 'HP: ' .. this.market_health .. ' / ' .. this.market_max_health)
|
||||
end
|
||||
|
||||
local function protect_entities(event)
|
||||
local this = FDT.get()
|
||||
local entity = event.entity
|
||||
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if not this.market or not this.market.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if entity.force.index ~= 1 then
|
||||
return
|
||||
end --Player Force
|
||||
|
||||
if event.cause then
|
||||
if event.cause.force.index == 2 and entity == this.market then
|
||||
set_objective_health(event.final_damage_amount)
|
||||
elseif event.cause.force.index == 2 then
|
||||
return
|
||||
else
|
||||
event.entity.health = event.entity.health + event.final_damage_amount
|
||||
end
|
||||
end
|
||||
if entity and entity.valid then
|
||||
event.entity.health = event.entity.health + event.final_damage_amount
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
|
||||
if not entity then
|
||||
return
|
||||
end
|
||||
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
|
||||
protect_entities(event)
|
||||
end
|
||||
|
||||
local function on_player_repaired_entity(event)
|
||||
local this = FDT.get()
|
||||
if not event.entity then
|
||||
return
|
||||
end
|
||||
if not event.entity.valid then
|
||||
return
|
||||
end
|
||||
if not event.entity.health then
|
||||
return
|
||||
end
|
||||
local entity = event.entity
|
||||
if entity == this.market then
|
||||
set_objective_health(-1)
|
||||
end
|
||||
end
|
||||
|
||||
local function set_market_health()
|
||||
local this = FDT.get()
|
||||
if not this.market then
|
||||
return
|
||||
end
|
||||
if not this.market.valid then
|
||||
return
|
||||
end
|
||||
local m = this.market_health / this.market_max_health
|
||||
this.market.health = 150 * m
|
||||
rendering.set_text(this.health_text, 'HP: ' .. this.market_health .. ' / ' .. this.market_max_health)
|
||||
end
|
||||
|
||||
local function has_the_game_ended()
|
||||
local this = FDT.get()
|
||||
if this.market_age then
|
||||
@ -1413,10 +1308,10 @@ function Public.reset_game()
|
||||
map_gen_settings.terrain_segmentation = 3
|
||||
map_gen_settings.cliff_settings = {cliff_elevation_interval = 32, cliff_elevation_0 = 32}
|
||||
map_gen_settings.autoplace_controls = {
|
||||
['coal'] = {frequency = 3, size = 1.5, richness = 1},
|
||||
['stone'] = {frequency = 3, size = 1.5, richness = 1},
|
||||
['copper-ore'] = {frequency = 3, size = 1.5, richness = 1},
|
||||
['iron-ore'] = {frequency = 3, size = 1.5, richness = 1},
|
||||
['coal'] = {frequency = 4, size = 1.5, richness = 2},
|
||||
['stone'] = {frequency = 4, size = 1.5, richness = 2},
|
||||
['copper-ore'] = {frequency = 4, size = 1.5, richness = 2},
|
||||
['iron-ore'] = {frequency = 4, size = 1.5, richness = 2},
|
||||
['uranium-ore'] = {frequency = 0, size = 0, richness = 0},
|
||||
['crude-oil'] = {frequency = 5, size = 1.25, richness = 2},
|
||||
['trees'] = {frequency = 2, size = 1, richness = 1},
|
||||
@ -1437,12 +1332,39 @@ function Public.reset_game()
|
||||
|
||||
surface.peaceful_mode = false
|
||||
|
||||
global.chunk_queue = {}
|
||||
-- Terrain.fish_eye(surface, {x = -1442, y = -59})
|
||||
|
||||
Terrain.fish_eye(surface, {x = -2150, y = -300})
|
||||
--[[ local radius = 200
|
||||
--local pos = {x = 419, y = -308} -- fish
|
||||
local pos = {x = -27, y = -308} -- cat
|
||||
game.forces.player.chart(
|
||||
surface,
|
||||
{
|
||||
{pos.x - radius - 100, pos.y - radius - 40},
|
||||
{pos.x + radius + 250, pos.y + radius}
|
||||
}
|
||||
)
|
||||
|
||||
Task.get_task_queue(4)
|
||||
Task.start_queue()
|
||||
radius = 50
|
||||
-- pos = {x = -1575, y = 2}
|
||||
-- pos = {x = -1246, y = 74} -- fish
|
||||
pos = {x = -748, y = -309} -- cat
|
||||
game.forces.player.chart(
|
||||
surface,
|
||||
{
|
||||
{pos.x - radius, pos.y - radius},
|
||||
{pos.x + radius, pos.y + radius}
|
||||
}
|
||||
) ]]
|
||||
local r = 750
|
||||
local p = {x = -131, y = 5}
|
||||
game.forces.player.chart(
|
||||
surface,
|
||||
{
|
||||
{p.x - r - 200, p.y - r},
|
||||
{p.x + r + 600, p.y + r}
|
||||
}
|
||||
)
|
||||
|
||||
game.map_settings.enemy_expansion.enabled = false
|
||||
game.map_settings.enemy_evolution.destroy_factor = 0
|
||||
@ -1473,6 +1395,7 @@ function Public.reset_game()
|
||||
|
||||
this.market_health = 500
|
||||
this.market_max_health = 500
|
||||
this.spawn_area_generated = false
|
||||
end
|
||||
|
||||
function Public.on_init()
|
||||
@ -1480,14 +1403,9 @@ function Public.on_init()
|
||||
|
||||
local T = Map.Pop_info()
|
||||
T.localised_category = 'fish_defender_v2'
|
||||
T.main_caption = '-- Chonk Defender -- '
|
||||
T.main_caption_color = {r = 0.11, g = 0.8, b = 0.44}
|
||||
T.sub_caption_color = {r = 0.33, g = 0.66, b = 0.9}
|
||||
|
||||
local mgs = game.surfaces['nauvis'].map_gen_settings
|
||||
mgs.width = 16
|
||||
mgs.height = 16
|
||||
game.surfaces['nauvis'].map_gen_settings = mgs
|
||||
game.surfaces['nauvis'].clear()
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
@ -1500,7 +1418,6 @@ local function on_tick()
|
||||
if game.tick % 30 == 0 then
|
||||
has_the_game_ended()
|
||||
if this.market then
|
||||
set_market_health()
|
||||
for _, player in pairs(game.connected_players) do
|
||||
if surface.peaceful_mode == false then
|
||||
create_wave_gui(player)
|
||||
@ -1509,7 +1426,7 @@ local function on_tick()
|
||||
end
|
||||
if game.tick % 180 == 0 then
|
||||
if surface then
|
||||
game.forces.player.chart(surface, {{-160, -128}, {192, 128}})
|
||||
game.forces.player.chart(surface, {{-160, -160}, {192, 300}})
|
||||
if Diff.difficulty_vote_index then
|
||||
this.wave_interval = this.difficulties_votes[Diff.difficulty_vote_index].wave_interval
|
||||
end
|
||||
@ -1527,7 +1444,6 @@ end
|
||||
|
||||
local on_init = Public.on_init
|
||||
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_gui_click, on_gui_click)
|
||||
Event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
|
||||
Event.add(defines.events.on_player_respawned, on_player_respawned)
|
||||
@ -1538,7 +1454,6 @@ Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
|
||||
Event.add(defines.events.on_player_repaired_entity, on_player_repaired_entity)
|
||||
Event.add(defines.events.on_robot_mined_entity, on_robot_mined_entity)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
Event.on_init(on_init)
|
||||
|
@ -81,7 +81,6 @@ function Public.reset_table()
|
||||
left_top = {x = -1500, y = -1500},
|
||||
right_bottom = {x = -80, y = 1500}
|
||||
}
|
||||
this.map_height = 96
|
||||
this.shotgun_shell_damage_modifier_old = {}
|
||||
this.flame_boots = {}
|
||||
end
|
||||
|
@ -1,29 +1,11 @@
|
||||
local Event = require 'utils.event'
|
||||
local Builder = require 'maps.fish_defender_v2.b'
|
||||
local map_functions = require 'tools.map_functions'
|
||||
local simplex_noise = require 'utils.simplex_noise'.d2
|
||||
local FDT = require 'maps.fish_defender_v2.table'
|
||||
local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
local math_random = math.random
|
||||
local math_abs = math.abs
|
||||
local math_floor = math.floor
|
||||
local math_sqrt = math.sqrt
|
||||
local tiles_per_call = 16
|
||||
local total_calls = math.ceil(1024 / tiles_per_call)
|
||||
|
||||
local Public = {}
|
||||
|
||||
local rock_raffle = {
|
||||
'sand-rock-big',
|
||||
'sand-rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-big',
|
||||
'rock-huge'
|
||||
}
|
||||
|
||||
local function shuffle(tbl)
|
||||
local size = #tbl
|
||||
@ -65,76 +47,6 @@ local function is_enemy_territory(p)
|
||||
if p.y < -512 then
|
||||
return false
|
||||
end
|
||||
local noise = math_abs(simplex_noise(0, p.y * 0.015, game.surfaces[1].map_gen_settings.seed) * 96)
|
||||
local noise_2 = math_abs(simplex_noise(0, p.y * 0.1, game.surfaces[1].map_gen_settings.seed) * 16)
|
||||
if p.x > 288 + noise + noise_2 + math_abs(p.y * 0.75) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local body_radius = 3072
|
||||
local body_square_radius = body_radius ^ 2
|
||||
local body_center_position = {x = -1500, y = 0}
|
||||
local body_spacing = math_floor(body_radius * 0.82)
|
||||
local body_circle_center_1 = {x = body_center_position.x, y = body_center_position.y - body_spacing}
|
||||
local body_circle_center_2 = {x = body_center_position.x, y = body_center_position.y + body_spacing}
|
||||
|
||||
local fin_radius = 800
|
||||
local square_fin_radius = fin_radius ^ 2
|
||||
local fin_circle_center_1 = {x = -480, y = 0}
|
||||
local fin_circle_center_2 = {x = -480 - 360, y = 0}
|
||||
|
||||
local function is_body(p)
|
||||
local this = FDT.get()
|
||||
if p.y <= this.map_height and p.y >= this.map_height * -1 and p.x <= 160 and p.x > body_center_position.x then
|
||||
return true
|
||||
end
|
||||
|
||||
--Main Fish Body
|
||||
local distance_to_center_1 = ((p.x - body_circle_center_1.x) ^ 2 + (p.y - body_circle_center_1.y) ^ 2)
|
||||
local distance_to_center_2 = ((p.x - body_circle_center_2.x) ^ 2 + (p.y - body_circle_center_2.y) ^ 2)
|
||||
--if distance_to_center_1 < body_square_radius and distance_to_center_2 < body_square_radius then return true end
|
||||
if distance_to_center_1 < body_square_radius then
|
||||
if distance_to_center_2 < body_square_radius then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
--Fish Fins
|
||||
distance_to_center_1 = ((p.x - fin_circle_center_1.x) ^ 2 + (p.y - fin_circle_center_1.y) ^ 2)
|
||||
if
|
||||
distance_to_center_1 + math_abs(simplex_noise(0, p.y * 0.075, game.surfaces[1].map_gen_settings.seed) * 32000) >
|
||||
square_fin_radius
|
||||
then
|
||||
distance_to_center_2 = ((p.x - fin_circle_center_2.x) ^ 2 + (p.y - fin_circle_center_2.y) ^ 2)
|
||||
if distance_to_center_2 < square_fin_radius then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function is_out_of_map_tile(p)
|
||||
if p.y > 850 then
|
||||
return true
|
||||
end
|
||||
if p.y < -850 then
|
||||
return true
|
||||
end
|
||||
if p.x < -3264 then
|
||||
return true
|
||||
end
|
||||
if p.x > 800 then
|
||||
return true
|
||||
end
|
||||
if is_enemy_territory(p) then
|
||||
return false
|
||||
end
|
||||
if is_body(p) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
@ -151,10 +63,10 @@ local function enemy_territory(surface, left_top)
|
||||
if left_top.x > 750 then
|
||||
return
|
||||
end
|
||||
if left_top.y > 512 then
|
||||
if left_top.y > 766 then
|
||||
return
|
||||
end
|
||||
if left_top.y < -512 then
|
||||
if left_top.y < -160 then
|
||||
return
|
||||
end
|
||||
|
||||
@ -208,86 +120,6 @@ local function enemy_territory(surface, left_top)
|
||||
end
|
||||
end
|
||||
|
||||
local function fish_mouth(surface, left_top)
|
||||
if left_top.x > -2300 then
|
||||
return
|
||||
end
|
||||
if left_top.y > 64 then
|
||||
return
|
||||
end
|
||||
if left_top.y < -64 then
|
||||
return
|
||||
end
|
||||
if left_top.x < -3292 then
|
||||
return
|
||||
end
|
||||
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local pos = {x = left_top.x + x, y = left_top.y + y}
|
||||
local noise = simplex_noise(pos.x * 0.006, 0, game.surfaces[1].map_gen_settings.seed) * 20
|
||||
if pos.y <= 12 + noise and pos.y >= -12 + noise then
|
||||
surface.set_tiles({{name = 'water', position = pos}})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local ores = {'coal', 'iron-ore', 'copper-ore', 'stone'}
|
||||
|
||||
local function plankton_territory(surface, position, seed)
|
||||
local noise = simplex_noise(position.x * 0.009, position.y * 0.009, seed)
|
||||
local d = 196
|
||||
if
|
||||
position.x + position.y > (d * -1) - (math_abs(noise) * d * 3) and
|
||||
position.x > position.y - (d + (math_abs(noise) * d * 3))
|
||||
then
|
||||
return 'out-of-map'
|
||||
end
|
||||
|
||||
local noise_2 = simplex_noise(position.x * 0.0075, position.y * 0.0075, seed + 10000)
|
||||
--if noise_2 > 0.87 then surface.set_tiles({{name = "deepwater-green", position = position}}, true) return true end
|
||||
if noise_2 > 0.87 then
|
||||
return 'deepwater-green'
|
||||
end
|
||||
if noise_2 > 0.75 then
|
||||
local i = math_floor(noise * 6) % 4 + 1
|
||||
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
|
||||
surface.create_entity({name = ores[i], position = position, amount = 1 + 2500 * math_abs(noise_2 * 3)})
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
if noise_2 < -0.76 then
|
||||
local i = math_floor(noise * 6) % 4 + 1
|
||||
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
|
||||
if noise_2 < -0.86 then
|
||||
surface.create_entity(
|
||||
{name = 'uranium-ore', position = position, amount = 1 + 1000 * math_abs(noise_2 * 2)}
|
||||
)
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
if math_random(1, 3) ~= 1 then
|
||||
surface.create_entity({name = rock_raffle[math_random(1, #rock_raffle)], position = position})
|
||||
end
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
|
||||
if noise < 0.12 and noise > -0.12 then
|
||||
local i = math_floor(noise * 32) % 4 + 1
|
||||
--surface.set_tiles({{name = "grass-" .. i, position = position}}, true)
|
||||
if math_random(1, 5) == 1 then
|
||||
surface.create_entity({name = rock_raffle[math_random(1, #rock_raffle)], position = position})
|
||||
end
|
||||
return ('grass-' .. i)
|
||||
end
|
||||
|
||||
--surface.set_tiles({{name = "water", position = position}}, true)
|
||||
if math_random(1, 128) == 1 then
|
||||
surface.create_entity({name = 'fish', position = position})
|
||||
end
|
||||
|
||||
return 'water'
|
||||
end
|
||||
|
||||
local function render_market_hp()
|
||||
local this = FDT.get()
|
||||
local surface = game.surfaces[this.active_surface_index]
|
||||
@ -295,25 +127,12 @@ local function render_market_hp()
|
||||
return
|
||||
end
|
||||
|
||||
this.health_text =
|
||||
rendering.draw_text {
|
||||
text = 'HP: ' .. this.market_health .. ' / ' .. this.market_max_health,
|
||||
surface = surface,
|
||||
target = this.market,
|
||||
target_offset = {0, -3},
|
||||
color = {0, 255, 0},
|
||||
scale = 1.40,
|
||||
font = 'default-game',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
|
||||
this.caption =
|
||||
rendering.draw_text {
|
||||
text = 'Fish Market',
|
||||
surface = surface,
|
||||
target = this.market,
|
||||
target_offset = {0, -4.4},
|
||||
target_offset = {0, -3.4},
|
||||
color = {0, 255, 0},
|
||||
scale = 1.80,
|
||||
font = 'default-game',
|
||||
@ -329,7 +148,6 @@ local function generate_spawn_area(this, surface)
|
||||
|
||||
surface.request_to_generate_chunks({x = 0, y = 0}, 7)
|
||||
surface.request_to_generate_chunks({x = 160, y = 0}, 4)
|
||||
--surface.force_generate_chunk_requests()
|
||||
|
||||
if not surface.is_chunk_generated({-7, 0}) then
|
||||
return
|
||||
@ -340,7 +158,9 @@ local function generate_spawn_area(this, surface)
|
||||
|
||||
local spawn_position_x = -128
|
||||
|
||||
surface.create_entity({name = 'electric-beam', position = {160, -96}, source = {160, -96}, target = {160, 96}})
|
||||
surface.create_entity({name = 'electric-beam', position = {160, -132}, source = {160, -132}, target = {160, 305}}) -- cat
|
||||
--surface.create_entity({name = 'electric-beam', position = {160, -101}, source = {160, -101}, target = {160, 248}}) -- fish
|
||||
--surface.create_entity({name = 'electric-beam', position = {160, -88}, source = {160, -88}, target = {160, 185}})
|
||||
|
||||
for _, tile in pairs(
|
||||
surface.find_tiles_filtered({name = {'water', 'deepwater'}, area = {{-160, -160}, {160, 160}}})
|
||||
@ -362,20 +182,18 @@ local function generate_spawn_area(this, surface)
|
||||
{type = {'resource', 'cliff'}, area = {{spawn_position_x - 32, -256}, {160, 256}}}
|
||||
)
|
||||
) do
|
||||
if is_body(entity.position) then
|
||||
if
|
||||
entity.position.x >
|
||||
spawn_position_x - 32 +
|
||||
math_abs(
|
||||
simplex_noise(
|
||||
entity.position.x * 0.02,
|
||||
entity.position.y * 0.02,
|
||||
game.surfaces[1].map_gen_settings.seed
|
||||
) * 16
|
||||
)
|
||||
then
|
||||
entity.destroy()
|
||||
end
|
||||
if
|
||||
entity.position.x >
|
||||
spawn_position_x - 32 +
|
||||
math_abs(
|
||||
simplex_noise(
|
||||
entity.position.x * 0.02,
|
||||
entity.position.y * 0.02,
|
||||
game.surfaces[1].map_gen_settings.seed
|
||||
) * 16
|
||||
)
|
||||
then
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
@ -391,13 +209,13 @@ local function generate_spawn_area(this, surface)
|
||||
end
|
||||
end
|
||||
|
||||
local y = 80
|
||||
local _y = 80
|
||||
local ore_positions = {
|
||||
{x = spawn_position_x - 52, y = y},
|
||||
{x = spawn_position_x - 52, y = y * 0.5},
|
||||
{x = spawn_position_x - 52, y = _y},
|
||||
{x = spawn_position_x - 52, y = _y * 0.5},
|
||||
{x = spawn_position_x - 52, y = 0},
|
||||
{x = spawn_position_x - 52, y = y * -0.5},
|
||||
{x = spawn_position_x - 52, y = y * -1}
|
||||
{x = spawn_position_x - 52, y = _y * -0.5},
|
||||
{x = spawn_position_x - 52, y = _y * -1}
|
||||
}
|
||||
shuffle(ore_positions)
|
||||
map_functions.draw_smoothed_out_ore_circle(ore_positions[1], 'copper-ore', surface, 15, 2500)
|
||||
@ -435,22 +253,20 @@ local function generate_spawn_area(this, surface)
|
||||
end
|
||||
end
|
||||
|
||||
local pos = surface.find_non_colliding_position('gun-turret', {spawn_position_x + 5, 1}, 50, 1)
|
||||
local turret = surface.create_entity({name = 'gun-turret', position = pos, force = 'player'})
|
||||
local turret_pos = surface.find_non_colliding_position('gun-turret', {spawn_position_x + 5, 1}, 50, 1)
|
||||
local turret = surface.create_entity({name = 'gun-turret', position = turret_pos, force = 'player'})
|
||||
turret.insert({name = 'firearm-magazine', count = 32})
|
||||
|
||||
for x = -20, 20, 1 do
|
||||
for y = -20, 20, 1 do
|
||||
local pos = {x = this.market.position.x + x, y = this.market.position.y + y}
|
||||
--local distance_to_center = math_sqrt(x^2 + y^2)
|
||||
--if distance_to_center > 8 and distance_to_center < 15 then
|
||||
local market_pos = {x = this.market.position.x + x, y = this.market.position.y + y}
|
||||
local distance_to_center = x ^ 2 + y ^ 2
|
||||
if distance_to_center > 64 and distance_to_center < 225 then
|
||||
if
|
||||
math_random(1, 3) == 1 and
|
||||
surface.can_place_entity({name = 'wooden-chest', position = pos, force = 'player'})
|
||||
surface.can_place_entity({name = 'wooden-chest', position = market_pos, force = 'player'})
|
||||
then
|
||||
surface.create_entity({name = 'wooden-chest', position = pos, force = 'player'})
|
||||
surface.create_entity({name = 'wooden-chest', position = market_pos, force = 'player'})
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -463,11 +279,11 @@ local function generate_spawn_area(this, surface)
|
||||
end
|
||||
end
|
||||
|
||||
local pos = surface.find_non_colliding_position('character', {spawn_position_x + 1, 4}, 50, 1)
|
||||
game.forces['player'].set_spawn_position(pos, surface)
|
||||
local character_pos = surface.find_non_colliding_position('character', {spawn_position_x + 1, 4}, 50, 1)
|
||||
game.forces['player'].set_spawn_position(character_pos, surface)
|
||||
for _, player in pairs(game.connected_players) do
|
||||
local pos = surface.find_non_colliding_position('character', {spawn_position_x + 1, 4}, 50, 1)
|
||||
player.teleport(pos, surface)
|
||||
local spawn_pos = surface.find_non_colliding_position('character', {spawn_position_x + 1, 4}, 50, 1)
|
||||
player.teleport(spawn_pos, surface)
|
||||
end
|
||||
this.spawn_area_generated = true
|
||||
end
|
||||
@ -479,100 +295,26 @@ local function process_chunk(left_top)
|
||||
return
|
||||
end
|
||||
|
||||
local seed = game.surfaces[1].map_gen_settings.seed
|
||||
|
||||
generate_spawn_area(this, surface, left_top)
|
||||
enemy_territory(surface, left_top)
|
||||
fish_mouth(surface, left_top)
|
||||
|
||||
local tiles = {}
|
||||
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local pos = {x = left_top.x + x, y = left_top.y + y}
|
||||
if is_out_of_map_tile(pos) then
|
||||
--if not plankton_territory(surface, pos, seed) then surface.set_tiles({{name = "out-of-map", position = pos}}, true) end
|
||||
local tile_to_set = plankton_territory(surface, pos, seed)
|
||||
--local tile_to_set = "out-of-map"
|
||||
tiles[#tiles + 1] = {name = tile_to_set, position = pos}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
surface.set_tiles(tiles, true)
|
||||
|
||||
--if game.tick == 0 then return end
|
||||
--if game.forces.player.is_chunk_charted(surface, {left_top.x / 32, left_top.y / 32}) then
|
||||
game.forces.player.chart(surface, {{left_top.x, left_top.y}, {left_top.x + 31, left_top.y + 31}})
|
||||
--end
|
||||
if this.market and this.market.valid then
|
||||
this.game_reset = false
|
||||
end
|
||||
end
|
||||
|
||||
local process_chunk_queue =
|
||||
Token.register(
|
||||
function(data)
|
||||
local chunk_queue = data.chunk_queue
|
||||
|
||||
for i = 1, #chunk_queue do
|
||||
local pos = {x = chunk_queue[i].x, y = chunk_queue[i].y}
|
||||
process_chunk(pos)
|
||||
chunk_queue[i] = nil
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
local map_name = 'fish_defender'
|
||||
|
||||
if string.sub(event.surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
end
|
||||
|
||||
local left_top = event.area.left_top
|
||||
local this = FDT.get()
|
||||
if this.game_has_ended then
|
||||
return
|
||||
end
|
||||
Builder.make_chunk(event)
|
||||
|
||||
if game.tick == 0 or this.game_reset or this.force_chunk then
|
||||
process_chunk(left_top)
|
||||
else
|
||||
global.chunk_queue[#global.chunk_queue + 1] = {x = left_top.x, y = left_top.y}
|
||||
|
||||
local data = {
|
||||
chunk_queue = global.chunk_queue
|
||||
}
|
||||
Task.set_timeout_in_ticks(total_calls, process_chunk_queue, data)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.fish_eye(surface, position)
|
||||
surface.request_to_generate_chunks(position, 2)
|
||||
surface.force_generate_chunk_requests()
|
||||
for x = -48, 48, 1 do
|
||||
for y = -48, 48, 1 do
|
||||
local p = {x = position.x + x, y = position.y + y}
|
||||
--local distance = math_sqrt(((position.x - p.x) ^ 2) + ((position.y - p.y) ^ 2))
|
||||
--if distance < 44 then
|
||||
-- surface.set_tiles({{name = "water-green", position = p}}, true)
|
||||
--end
|
||||
--if distance < 22 then
|
||||
-- surface.set_tiles({{name = "out-of-map", position = p}}, true)
|
||||
--end
|
||||
|
||||
local distance = ((position.x - p.x) ^ 2) + ((position.y - p.y) ^ 2)
|
||||
if distance < 1936 then
|
||||
if distance < 484 then
|
||||
surface.set_tiles({{name = 'out-of-map', position = p}}, true)
|
||||
else
|
||||
surface.set_tiles({{name = 'water-green', position = p}}, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
process_chunk(left_top)
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
|
||||
|
||||
return Public
|
||||
|
@ -76,7 +76,9 @@ local function distance(player)
|
||||
if breach_max_times then
|
||||
rpg_extra.breached_walls = rpg_extra.breached_walls + 1
|
||||
rpg_extra.reward_new_players = bonus_xp_on_join * rpg_extra.breached_walls
|
||||
WPT.get().breached_wall = breached_wall + 1
|
||||
WPT.set().breached_wall = breached_wall + 1
|
||||
WPT.set().placed_trains_in_zone.placed = 0
|
||||
WPT.set().placed_trains_in_zone.positions = {}
|
||||
raise_event(Balance.events.breached_wall, {})
|
||||
|
||||
local data = {
|
||||
|
@ -1,8 +1,22 @@
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local ICW = require 'maps.mountain_fortress_v3.icw.main'
|
||||
local WPT = require 'maps.mountain_fortress_v3.table'
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local this = {
|
||||
power_sources = {index = 1},
|
||||
refill_turrets = {index = 1},
|
||||
magic_crafters = {index = 1},
|
||||
magic_fluid_crafters = {index = 1}
|
||||
}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(t)
|
||||
this = t
|
||||
end
|
||||
)
|
||||
|
||||
local Public = {}
|
||||
|
||||
@ -22,7 +36,7 @@ local function fast_remove(tbl, index)
|
||||
end
|
||||
|
||||
local function do_refill_turrets()
|
||||
local refill_turrets = WPT.get('refill_turrets')
|
||||
local refill_turrets = this.refill_turrets
|
||||
local index = refill_turrets.index
|
||||
|
||||
if index > #refill_turrets then
|
||||
@ -58,7 +72,7 @@ local function turret_died(event)
|
||||
if not number then
|
||||
return
|
||||
end
|
||||
local power_sources = WPT.get('power_sources')
|
||||
local power_sources = this.power_sources
|
||||
|
||||
local ps_data = power_sources[number]
|
||||
if ps_data then
|
||||
@ -78,7 +92,7 @@ local function turret_died(event)
|
||||
end
|
||||
|
||||
local function do_magic_crafters()
|
||||
local magic_crafters = WPT.get('magic_crafters')
|
||||
local magic_crafters = this.magic_crafters
|
||||
local limit = #magic_crafters
|
||||
if limit == 0 then
|
||||
return
|
||||
@ -122,7 +136,7 @@ local function do_magic_crafters()
|
||||
end
|
||||
|
||||
local function do_magic_fluid_crafters()
|
||||
local magic_fluid_crafters = WPT.get('magic_fluid_crafters')
|
||||
local magic_fluid_crafters = this.magic_fluid_crafters
|
||||
local limit = #magic_fluid_crafters
|
||||
|
||||
if limit == 0 then
|
||||
@ -173,8 +187,8 @@ local function do_magic_fluid_crafters()
|
||||
end
|
||||
|
||||
local function add_magic_crafter_output(entity, output, distance)
|
||||
local magic_fluid_crafters = WPT.get('magic_fluid_crafters')
|
||||
local magic_crafters = WPT.get('magic_crafters')
|
||||
local magic_fluid_crafters = this.magic_fluid_crafters
|
||||
local magic_crafters = this.magic_crafters
|
||||
local rate = output.min_rate + output.distance_factor * distance
|
||||
|
||||
local fluidbox_index = output.fluidbox_index
|
||||
@ -282,7 +296,7 @@ local disable_active_callback = Public.disable_active_callback
|
||||
Public.refill_turret_callback =
|
||||
Token.register(
|
||||
function(turret, data)
|
||||
local refill_turrets = WPT.get('refill_turrets')
|
||||
local refill_turrets = this.refill_turrets
|
||||
local callback_data = data.callback_data
|
||||
turret.direction = 3
|
||||
|
||||
@ -293,7 +307,7 @@ Public.refill_turret_callback =
|
||||
Public.refill_liquid_turret_callback =
|
||||
Token.register(
|
||||
function(turret, data)
|
||||
local refill_turrets = WPT.get('refill_turrets')
|
||||
local refill_turrets = this.refill_turrets
|
||||
local callback_data = data.callback_data
|
||||
callback_data.liquid = true
|
||||
|
||||
@ -304,7 +318,7 @@ Public.refill_liquid_turret_callback =
|
||||
Public.power_source_callback =
|
||||
Token.register(
|
||||
function(turret, data)
|
||||
local power_sources = WPT.get('power_sources')
|
||||
local power_sources = this.power_sources
|
||||
local callback_data = data.callback_data
|
||||
|
||||
local power_source =
|
||||
@ -477,6 +491,13 @@ Public.light_oil_ammo = {name = 'light-oil', amount = 100}
|
||||
Public.artillery_shell_ammo = {name = 'artillery-shell', count = 15}
|
||||
Public.laser_turrent_power_source = {buffer_size = 2400000, power_production = 40000}
|
||||
|
||||
function Public.reset_table()
|
||||
this.power_sources = {index = 1}
|
||||
this.refill_turrets = {index = 1}
|
||||
this.magic_crafters = {index = 1}
|
||||
this.magic_fluid_crafters = {index = 1}
|
||||
end
|
||||
|
||||
Event.on_nth_tick(10, tick)
|
||||
--Event.add(defines.events.on_tick, tick)
|
||||
Event.add(defines.events.on_entity_died, turret_died)
|
||||
|
@ -26,6 +26,7 @@ local WD = require 'modules.wave_defense.table'
|
||||
local Map = require 'modules.map_info'
|
||||
local RPG = require 'maps.mountain_fortress_v3.rpg'
|
||||
local Terrain = require 'maps.mountain_fortress_v3.terrain'
|
||||
local Functions = require 'maps.mountain_fortress_v3.functions'
|
||||
local Event = require 'utils.event'
|
||||
local WPT = require 'maps.mountain_fortress_v3.table'
|
||||
local Locomotive = require 'maps.mountain_fortress_v3.locomotive'
|
||||
@ -223,6 +224,7 @@ function Public.reset_map()
|
||||
|
||||
Poll.reset()
|
||||
ICW.reset()
|
||||
Functions.reset_table()
|
||||
game.reset_time_played()
|
||||
WPT.reset_table()
|
||||
Map_score.reset_score()
|
||||
@ -264,6 +266,7 @@ function Public.reset_map()
|
||||
Collapse.set_direction('north')
|
||||
Collapse.start_now(false)
|
||||
|
||||
--[[
|
||||
local x_value = rng(15, 25)
|
||||
local y_value = rng(50, 60)
|
||||
|
||||
@ -274,6 +277,8 @@ function Public.reset_map()
|
||||
['locomotive'] = {left_top = {x = -x_value, y = 0}, right_bottom = {x = x_value, y = y_value}}
|
||||
}
|
||||
ICT.set_wagon_area(data)
|
||||
|
||||
]]
|
||||
this.locomotive_health = 10000
|
||||
this.locomotive_max_health = 10000
|
||||
|
||||
|
@ -5,16 +5,12 @@ local Event = require 'utils.event'
|
||||
local this = {
|
||||
players = {},
|
||||
offline_players = {},
|
||||
hidden_dimension = {
|
||||
--[[ hidden_dimension = {
|
||||
logistic_research_level = 0,
|
||||
reset_counter = 1
|
||||
},
|
||||
power_sources = {index = 1},
|
||||
refill_turrets = {index = 1},
|
||||
magic_crafters = {index = 1},
|
||||
magic_fluid_crafters = {index = 1},
|
||||
]]
|
||||
breached_wall = 1,
|
||||
entity_limits = {},
|
||||
traps = {}
|
||||
}
|
||||
local Public = {}
|
||||
@ -43,11 +39,7 @@ function Public.reset_table()
|
||||
this.train_upgrades = 0
|
||||
this.offline_players = {}
|
||||
this.biter_pets = {}
|
||||
this.power_sources = {index = 1}
|
||||
this.flamethrower_damage = {}
|
||||
this.refill_turrets = {index = 1}
|
||||
this.magic_crafters = {index = 1}
|
||||
this.magic_fluid_crafters = {index = 1}
|
||||
this.mined_scrap = 0
|
||||
this.biters_killed = 0
|
||||
this.locomotive_xp_aura = 40
|
||||
@ -77,7 +69,6 @@ function Public.reset_table()
|
||||
this.aura_upgrades = 0
|
||||
this.health_upgrades = 0
|
||||
this.breached_wall = 1
|
||||
this.entity_limits = {}
|
||||
this.offline_players_enabled = true
|
||||
this.left_top = {
|
||||
x = 0,
|
||||
@ -95,6 +86,11 @@ function Public.reset_table()
|
||||
this.force_mining_speed = {
|
||||
speed = 0
|
||||
}
|
||||
this.placed_trains_in_zone = {
|
||||
placed = 0,
|
||||
positions = {},
|
||||
limit = 5
|
||||
}
|
||||
end
|
||||
|
||||
function Public.get(key)
|
||||
@ -105,6 +101,14 @@ function Public.get(key)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set(key)
|
||||
if key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function()
|
||||
Public.reset_table()
|
||||
end
|
||||
|
@ -10,9 +10,6 @@ local Public = {}
|
||||
Public.level_depth = 704
|
||||
Public.level_width = 512
|
||||
local worm_level_modifier = 0.19
|
||||
local average_number_of_wagons_per_level = 2
|
||||
local chunks_per_level = ((Public.level_depth - 32) / 32) ^ 2
|
||||
local chance_for_wagon_spawn = math.floor(chunks_per_level / average_number_of_wagons_per_level)
|
||||
|
||||
local wagon_raffle = {'cargo-wagon', 'cargo-wagon', 'cargo-wagon', 'locomotive', 'fluid-wagon'}
|
||||
local rock_raffle = {
|
||||
@ -84,8 +81,22 @@ local turret_list = {
|
||||
}
|
||||
|
||||
local function place_wagon(data)
|
||||
if math.random(1, 1500) ~= 1 then
|
||||
return
|
||||
local function is_position_near(area, table_to_check)
|
||||
local status = false
|
||||
local function inside(pos)
|
||||
local lt = area.left_top
|
||||
local rb = area.right_bottom
|
||||
|
||||
return pos.x >= lt.x and pos.y >= lt.y and pos.x <= rb.x and pos.y <= rb.y
|
||||
end
|
||||
|
||||
for k, entity in pairs(table_to_check) do
|
||||
if inside(entity, area) then
|
||||
status = true
|
||||
end
|
||||
end
|
||||
|
||||
return status
|
||||
end
|
||||
local surface = data.surface
|
||||
local tiles = data.tiles
|
||||
@ -97,6 +108,26 @@ local function place_wagon(data)
|
||||
callback = Functions.disable_minable_and_ICW_callback
|
||||
}
|
||||
|
||||
local rail_mineable = {
|
||||
callback = Functions.disable_destructible_callback
|
||||
}
|
||||
|
||||
local placed_trains_in_zone = WPT.get('placed_trains_in_zone')
|
||||
|
||||
if placed_trains_in_zone.placed >= placed_trains_in_zone.limit then
|
||||
return
|
||||
end
|
||||
|
||||
local radius = 300
|
||||
local area = {
|
||||
left_top = {x = position.x - radius, y = position.y - radius},
|
||||
right_bottom = {x = position.x + radius, y = position.y + radius}
|
||||
}
|
||||
|
||||
if is_position_near(area, placed_trains_in_zone.positions) then
|
||||
return
|
||||
end
|
||||
|
||||
local location
|
||||
local direction
|
||||
local r1 = math.random(2, 4) * 2
|
||||
@ -124,20 +155,21 @@ local function place_wagon(data)
|
||||
name = 'straight-rail',
|
||||
position = tile.position,
|
||||
force = 'player',
|
||||
direction = direction
|
||||
direction = direction,
|
||||
callback = rail_mineable
|
||||
}
|
||||
end
|
||||
end
|
||||
entities[#entities + 1] = {
|
||||
name = wagon_raffle[math.random(1, #wagon_raffle)],
|
||||
position = position,
|
||||
force = 'player',
|
||||
callback = wagon_mineable
|
||||
}
|
||||
placed_trains_in_zone.placed = placed_trains_in_zone.placed + 1
|
||||
placed_trains_in_zone.positions[#placed_trains_in_zone.positions + 1] = position
|
||||
print('Placed trains are: ' .. placed_trains_in_zone.placed)
|
||||
|
||||
table.insert(
|
||||
entities,
|
||||
{
|
||||
name = wagon_raffle[math.random(1, #wagon_raffle)],
|
||||
position = position,
|
||||
force = 'player',
|
||||
callback = wagon_mineable
|
||||
}
|
||||
)
|
||||
return true
|
||||
end
|
||||
|
||||
@ -1703,9 +1735,7 @@ function Public.heavy_functions(x, y, data)
|
||||
|
||||
if top_y < 0 then
|
||||
process_bits(x, y, data)
|
||||
if math.random(1, chance_for_wagon_spawn) == 1 then
|
||||
place_wagon(data)
|
||||
end
|
||||
place_wagon(data)
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -3,13 +3,11 @@ local Tabs = require 'comfy_panel.main'
|
||||
|
||||
local map_info = {
|
||||
localised_category = false,
|
||||
main_caption = 'Insert Main Caption',
|
||||
main_caption = nil,
|
||||
main_caption_color = {r = 0.6, g = 0.3, b = 0.99},
|
||||
sub_caption = 'Insert Sub Caption',
|
||||
sub_caption = nil,
|
||||
sub_caption_color = {r = 0.2, g = 0.9, b = 0.2},
|
||||
text = [[
|
||||
Add info text to map_info.
|
||||
]]
|
||||
text = nil
|
||||
}
|
||||
|
||||
Global.register(
|
||||
@ -36,10 +34,14 @@ local create_map_intro = (function(player, frame)
|
||||
line.style.top_margin = 4
|
||||
line.style.bottom_margin = 4
|
||||
|
||||
local caption = map_info.main_caption or {map_info.localised_category .. '.map_info_main_caption'}
|
||||
local sub_caption = map_info.sub_caption or {map_info.localised_category .. '.map_info_sub_caption'}
|
||||
local text = map_info.text or {map_info.localised_category .. '.map_info_text'}
|
||||
|
||||
if map_info.localised_category then
|
||||
map_info.main_caption = {map_info.localised_category .. '.map_info_main_caption'}
|
||||
map_info.sub_caption = {map_info.localised_category .. '.map_info_sub_caption'}
|
||||
map_info.text = {map_info.localised_category .. '.map_info_text'}
|
||||
map_info.main_caption = caption
|
||||
map_info.sub_caption = sub_caption
|
||||
map_info.text = text
|
||||
end
|
||||
local l = t.add {type = 'label', caption = map_info.main_caption}
|
||||
l.style.font = 'heading-1'
|
||||
|
Loading…
Reference in New Issue
Block a user