1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-02-01 13:08:05 +02:00

Merge pull request #162 from ComfyFactory/adjustments

Minor changes to RPG, Wave defense and Mtn v3
This commit is contained in:
Gerkiz 2021-11-11 02:00:22 +01:00 committed by GitHub
commit e40c406116
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 399 additions and 170 deletions

View File

@ -2,7 +2,9 @@ local Color = require 'utils.color_presets'
local Task = require 'utils.task'
local Server = require 'utils.server'
local WPT = require 'maps.mountain_fortress_v3.table'
local Collapse = require 'modules.collapse'
local WD = require 'modules.wave_defense.table'
local WDM = require 'modules.wave_defense.main'
local mapkeeper = '[color=blue]Mapkeeper:[/color]'
@ -175,3 +177,57 @@ commands.add_command(
end
end
)
if _DEBUG then
commands.add_command(
'start_collapse',
'Enabled only on SP',
function()
local p
local player = game.player
if game.is_multiplayer() then
return
end
if player and player.valid then
p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
if not Collapse.start_now() then
Collapse.start_now(true)
p('Collapse started!')
else
Collapse.start_now(false)
p('Collapse stopped!')
end
end
end
)
commands.add_command(
'spawn_wave',
'Enabled only on SP',
function()
local p
local player = game.player
if game.is_multiplayer() then
return
end
if player and player.valid then
p = player.print
if not player.admin then
p("[ERROR] You're not admin!", Color.fail)
return
end
WD.enable_debug()
WDM.spawn_unit_group(true)
p('Spawning wave!')
end
end
)
end

View File

@ -1189,6 +1189,7 @@ function Public.set_spawn_position()
::retry::
local y_value_position = WPT.get('y_value_position')
local locomotive_positions = WPT.get('locomotive_pos')
local total_pos = #locomotive_positions.tbl
@ -1206,7 +1207,7 @@ function Public.set_spawn_position()
collapse_position = surface.find_non_colliding_position('solar-panel', collapse_pos, 32, 2)
end
if not collapse_position then
collapse_position = surface.find_non_colliding_position('small-biter', collapse_pos, 32, 2)
collapse_position = surface.find_non_colliding_position('steel-chest', collapse_pos, 32, 2)
end
local sizeof = locomotive_positions.tbl[total_pos - total_pos + 1]
if not sizeof then
@ -1221,7 +1222,7 @@ function Public.set_spawn_position()
goto retry
end
local locomotive_position = surface.find_non_colliding_position('small-biter', sizeof, 128, 1)
local locomotive_position = surface.find_non_colliding_position('steel-chest', sizeof, 128, 1)
local distance_from = floor(math2d.position.distance(locomotive_position, locomotive.position))
local l_y = l.y
local t_y = locomotive_position.y
@ -1248,20 +1249,22 @@ function Public.set_spawn_position()
return
end
debug_str('distance_from was higher - spawning at locomotive_position')
WD.set_spawn_position({x = locomotive_position.x, y = collapse_pos.y - 20})
WD.set_spawn_position({x = locomotive_position.x, y = collapse_pos.y - y_value_position})
else
debug_str('distance_from was lower - spawning at locomotive_position')
WD.set_spawn_position({x = locomotive_position.x, y = collapse_pos.y - 20})
WD.set_spawn_position({x = locomotive_position.x, y = collapse_pos.y - y_value_position})
end
else
if collapse_position then
debug_str('total_pos was higher - spawning at collapse_position')
collapse_position = {x = collapse_position.x, y = collapse_position.y - y_value_position}
WD.set_spawn_position(collapse_position)
end
end
else
if collapse_position then
debug_str('total_pos was lower - spawning at collapse_position')
collapse_position = {x = collapse_position.x, y = collapse_position.y - y_value_position}
WD.set_spawn_position(collapse_position)
end
end

View File

@ -5,6 +5,8 @@ local Task = require 'utils.task'
local Token = require 'utils.token'
local Event = require 'utils.event'
local Terrain = require 'maps.mountain_fortress_v3.terrain'
local WD = require 'modules.wave_defense.table'
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
local Public = {}
@ -269,25 +271,27 @@ local function do_place_buildings(data)
} == 0
then
entity = surface.create_entity(e)
if entity and e.direction then
entity.direction = e.direction
end
if entity and e.force then
entity.force = e.force
end
if entity and e.callback then
local c = e.callback.callback
if not c then
return
if entity then
if e.direction then
entity.direction = e.direction
end
local d = {callback_data = e.callback.data}
if not d then
if e.force then
entity.force = e.force
end
if e.callback then
local c = e.callback.callback
if not c then
return
end
local d = {callback_data = e.callback.data}
if not d then
callback = Token.get(c)
callback(entity)
return
end
callback = Token.get(c)
callback(entity)
return
callback(entity, d)
end
callback = Token.get(c)
callback(entity, d)
end
end
end
@ -340,56 +344,67 @@ local function do_place_entities(data)
if e.collision then
if surface.can_place_entity(e) then
entity = surface.create_entity(e)
wintery(entity)
if entity and e.direction then
entity.direction = e.direction
end
if entity and e.force then
entity.force = e.force
end
if entity and e.amount then
entity.amount = e.amount
end
if entity and e.callback then
local c = e.callback.callback
if not c then
return
if entity then
if e.note and e.note == 'wall' then
local wall_defenders_health_modifier = WD.get('modified_boss_unit_health')
BiterHealthBooster.add_unit(entity, wall_defenders_health_modifier)
end
local d = {callback_data = e.callback.data}
if not d then
callback = Token.get(c)
callback(entity)
return
wintery(entity)
if e.direction then
entity.direction = e.direction
end
if e.force then
entity.force = e.force
end
if e.amount then
entity.amount = e.amount
end
if e.callback then
local c = e.callback.callback
if not c then
return
end
local d = {callback_data = e.callback.data}
if not d then
callback = Token.get(c)
callback(entity)
else
callback = Token.get(c)
callback(entity, d)
end
end
callback = Token.get(c)
callback(entity, d)
end
end
else
entity = surface.create_entity(e)
wintery(entity)
if entity and e.direction then
entity.direction = e.direction
end
if entity and e.force then
entity.force = e.force
end
if entity and e.amount then
entity.amount = e.amount
end
if entity and e.callback then
local c = e.callback.callback
if not c then
return
if entity then
if e.note and e.note == 'wall' then
local wall_defenders_health_modifier = WD.get('modified_boss_unit_health')
BiterHealthBooster.add_unit(entity, wall_defenders_health_modifier)
end
local d = {callback_data = e.callback.data}
if not d then
callback = Token.get(c)
callback(entity)
return
wintery(entity)
if e.direction then
entity.direction = e.direction
end
if e.force then
entity.force = e.force
end
if e.amount then
entity.amount = e.amount
end
if e.callback then
local c = e.callback.callback
if c then
local d = {callback_data = e.callback.data}
if not d then
callback = Token.get(c)
callback(entity)
else
callback = Token.get(c)
callback(entity, d)
end
end
end
callback = Token.get(c)
callback(entity, d)
end
end
end

View File

@ -268,7 +268,7 @@ function Public.hazardous_debris()
end
end
for _ = 1, 2 * speed, 1 do
for _ = 1, 6 * speed, 1 do
local position = fallout_debris[random(1, size_of_debris)]
local p = {x = position[1], y = position[2]}
local get_tile = surface.get_tile(p)
@ -277,7 +277,24 @@ function Public.hazardous_debris()
end
end
for _ = 1, 1 * speed, 1 do
for _ = 1, 4 * speed, 1 do
local position = fallout_debris[random(1, size_of_debris)]
local p = {x = position[1], y = position[2]}
local get_tile = surface.get_tile(p)
if get_tile.valid and get_tile.name == 'out-of-map' then
create(
{
name = 'atomic-bomb-wave-spawns-nuke-shockwave-explosion',
position = position,
force = 'neutral',
target = {position[1], position[2] + fallout_width * 2},
speed = speed
}
)
end
end
for _ = 1, 6 * speed, 1 do
local position = fallout_debris[random(1, size_of_debris)]
local p = {x = position[1], y = position[2]}
local get_tile = surface.get_tile(p)

View File

@ -203,6 +203,7 @@ function Public.reset_map()
BiterHealthBooster.check_on_entity_died(true)
BiterHealthBooster.boss_spawns_projectiles(true)
BiterHealthBooster.enable_boss_loot(false)
BiterHealthBooster.enable_randomize_discharge_stun(true)
Balance.init_enemy_weapon_damage()

View File

@ -192,6 +192,7 @@ function Public.reset_table()
this.offline_players = {}
this.collapse_amount = false
this.collapse_speed = false
this.y_value_position = 20
this.spawn_near_collapse = {
active = true,
total_pos = 35,

View File

@ -227,7 +227,8 @@ local function spawn_turret(entities, p, probability)
force = 'enemy',
callback = turret_list[probability].callback,
direction = 4,
collision = true
collision = true,
note = 'wall'
}
end
@ -369,7 +370,8 @@ local function wall(p, data)
entities[#entities + 1] = {
name = Biters.wave_defense_roll_worm_name(),
position = p,
force = 'enemy'
force = 'enemy',
note = 'wall'
}
end
end
@ -2002,12 +2004,12 @@ local function process_level_1_position(x, y, data, void_or_lab)
end
--Chasms
if noise_cave_ponds < 0.111 and noise_cave_ponds > -0.112 then
if small_caves > 0.53 then
if noise_cave_ponds < 0.110 and noise_cave_ponds > -0.112 then
if small_caves > 0.5 then
tiles[#tiles + 1] = {name = void_or_lab, position = p}
return
end
if small_caves < -0.53 then
if small_caves < -0.5 then
tiles[#tiles + 1] = {name = void_or_lab, position = p}
return
end
@ -2144,10 +2146,10 @@ local function process_level_0_position(x, y, data, void_or_lab)
local markets = data.markets
local treasure = data.treasure
local small_caves = get_perlin('dungeons', p, seed)
local noise_cave_ponds = get_perlin('cave_ponds', p, seed)
local smol_areas = get_perlin('smol_areas', p, seed)
local no_rocks_2 = get_perlin('no_rocks_2', p, seed)
local small_caves = get_perlin('dungeons', p, seed + 34883)
local noise_cave_ponds = get_perlin('cave_ponds', p, seed + 28939)
local smol_areas = get_perlin('smol_areas', p, seed + 3992)
local no_rocks_2 = get_perlin('no_rocks_2', p, seed + 1922)
local cave_rivers = get_perlin('cave_rivers', p, seed)
local no_rocks = get_perlin('no_rocks', p, seed)
@ -2168,20 +2170,20 @@ local function process_level_0_position(x, y, data, void_or_lab)
end
--Chasms
if noise_cave_ponds < 0.111 and noise_cave_ponds > -0.112 then
if small_caves > 0.53 then
if noise_cave_ponds < 0.105 and noise_cave_ponds > -0.112 then
if small_caves > 0.52 then
tiles[#tiles + 1] = {name = void_or_lab, position = p}
return
end
if small_caves < -0.53 then
if small_caves < -0.52 then
tiles[#tiles + 1] = {name = void_or_lab, position = p}
return
end
end
--Water Ponds
if noise_cave_ponds > 0.670 then
if noise_cave_ponds > 0.750 then
if noise_cave_ponds > 0.64 then
if noise_cave_ponds > 0.74 then
tiles[#tiles + 1] = {name = 'grass-' .. floor(noise_cave_ponds * 32) % 3 + 1, position = p}
if random(1, 4) == 1 then
markets[#markets + 1] = p
@ -2199,7 +2201,7 @@ local function process_level_0_position(x, y, data, void_or_lab)
end
--Rivers
if cave_rivers < 0.044 and cave_rivers > -0.062 then
if cave_rivers < 0.042 and cave_rivers > -0.062 then
if noise_cave_ponds > 0.1 then
tiles[#tiles + 1] = {name = 'water-shallow', position = p}
if random(1, 64) == 1 then
@ -2209,7 +2211,7 @@ local function process_level_0_position(x, y, data, void_or_lab)
end
end
if noise_cave_ponds > 0.632 then
if noise_cave_ponds > 0.622 then
if noise_cave_ponds > 0.542 then
if cave_rivers > -0.302 then
tiles[#tiles + 1] = {name = 'refined-hazard-concrete-right', position = p}
@ -2222,7 +2224,7 @@ local function process_level_0_position(x, y, data, void_or_lab)
end
--Worm oil Zones
if no_rocks < 0.031 and no_rocks > -0.141 then
if no_rocks < 0.035 and no_rocks > -0.145 then
if small_caves > 0.081 then
tiles[#tiles + 1] = {name = 'grass-' .. floor(noise_cave_ponds * 32) % 3 + 1, position = p}
if random(1, 250) == 1 then
@ -2254,7 +2256,7 @@ local function process_level_0_position(x, y, data, void_or_lab)
return
end
tiles[#tiles + 1] = {name = 'dirt-' .. floor(no_rocks_2 * 8) % 2 + 5, position = p}
if random(1, 32) == 1 then
if random(1, 18) == 1 then
entities[#entities + 1] = {name = 'tree-0' .. random(1, 9), position = p}
end
@ -2333,11 +2335,22 @@ local function border_chunk(p, data)
entities[#entities + 1] = {name = trees[random(1, #trees)], position = pos}
end
if random(1, 10) == 1 then
tiles[#tiles + 1] = {name = 'red-desert-' .. random(1, 3), position = pos}
else
tiles[#tiles + 1] = {name = 'dirt-' .. math.random(1, 6), position = pos}
local seed = data.seed
local small_caves = get_perlin('dungeons', p, seed + 34883)
local noise_cave_ponds = get_perlin('cave_ponds', p, seed + 28939)
local cave_rivers = get_perlin('cave_rivers', p, seed)
if small_caves > 0.64 then
tiles[#tiles + 1] = {name = 'nuclear-ground', position = pos}
end
if noise_cave_ponds > 0.33 then
tiles[#tiles + 1] = {name = 'red-desert-' .. random(1, 3), position = pos}
end
if cave_rivers > 0.54 then
tiles[#tiles + 1] = {name = 'grass-' .. random(1, 4), position = pos}
end
-- tiles[#tiles + 1] = {name = 'dirt-' .. random(1, 6), position = pos}
local scrap_mineable_entities, scrap_mineable_entities_index = get_scrap_mineable_entities()

View File

@ -30,7 +30,8 @@ local this = {
acid_lines_delay = {},
acid_nova = false,
boss_spawns_projectiles = false,
enable_boss_loot = false
enable_boss_loot = false,
randomize_discharge_stun = false
}
local radius = 6
@ -40,6 +41,8 @@ local acid_splashes = {
['behemoth-biter'] = 'acid-stream-worm-big'
}
local acid_lines = {
['small-spitter'] = 'acid-stream-spitter-small',
['medium-spitter'] = 'acid-stream-spitter-medium',
['big-spitter'] = 'acid-stream-spitter-big',
['behemoth-spitter'] = 'acid-stream-spitter-big'
}
@ -71,9 +74,19 @@ Global.register(
end
)
local filters = {
{filter = 'name', name = 'unit'},
{filter = 'name', name = 'turret'},
{filter = 'name', name = 'ammo-turret'},
{filter = 'name', name = 'electric-turret'},
{filter = 'name', name = 'unit-spawner'}
}
local entity_types = {
['unit'] = true,
['turret'] = true,
['ammo-turret'] = true,
['electric-turret'] = true,
['unit-spawner'] = true
}
@ -112,7 +125,7 @@ local function loaded_biters(event)
{
name = projectiles[random(1, 10)],
position = entity.position,
force = 'neutral',
force = 'enemy',
source = entity.position,
target = position,
max_range = 16,
@ -137,7 +150,8 @@ local function acid_nova(event)
)
end
end
local function acid_line(surface, name, source, target)
local function create_entity_radius(surface, name, source, target)
local distance = sqrt((source.x - target.x) ^ 2 + (source.y - target.y) ^ 2)
local modifier = {(target.x - source.x) / distance, (target.y - source.y) / distance}
@ -228,7 +242,7 @@ local function set_boss_healthbar(health, max_health, healthbar_id)
rendering.set_color(healthbar_id, {floor(255 - 255 * m), floor(200 * m), 0})
end
local function try_acid(cause, target)
local function extra_projectiles(cause, target)
if not cause or not cause.valid then
return
end
@ -242,7 +256,7 @@ local function try_acid(cause, target)
this.acid_lines_delay[cause_unit_number] = 0
end
if this.acid_lines_delay[cause_unit_number] < game.tick then
acid_line(cause.surface, acid_lines[cause.name], cause.position, target.position)
create_entity_radius(cause.surface, acid_lines[cause.name], cause.position, target.position)
this.acid_lines_delay[cause_unit_number] = game.tick + 180
end
end
@ -255,28 +269,37 @@ local function on_entity_damaged(event)
if not (biter and biter.valid) then
return
end
local surface = biter.surface
local cause = event.cause
local biter_health_boost_units = this.biter_health_boost_units
local unit_number = biter.unit_number
local damage = event.final_damage_amount
--Create new health pool
local health_pool = biter_health_boost_units[unit_number]
try_acid(cause, biter)
extra_projectiles(cause, biter)
if not entity_types[biter.type] then
return
end
local damage_type = event.damage_type
if damage_type and damage_type.name == 'electric' then
local stickers = event.entity.stickers
if stickers and #stickers > 0 then
for i = 1, #stickers, 1 do
if stickers[i].sticked_to == event.entity and stickers[i].name == 'stun-sticker' then
stickers[i].destroy()
break
if this.randomize_discharge_stun then
local damage_type = event.damage_type
if damage_type and damage_type.name == 'electric' then
local stickers = biter.stickers
if stickers and #stickers > 0 then
for i = 1, #stickers, 1 do
if random(1, 4) == 1 then -- there's a % that biters can recover from stun and get slowed instead.
if stickers[i].sticked_to == biter and stickers[i].name == 'stun-sticker' then
stickers[i].destroy()
local slow = surface.create_entity {name = 'slowdown-sticker', position = biter.position, target = biter}
slow.time_to_live = 200
break
end
end
end
end
end
@ -305,7 +328,7 @@ local function on_entity_damaged(event)
end
--Reduce health pool
health_pool[1] = health_pool[1] - event.final_damage_amount
health_pool[1] = health_pool[1] - damage
--Set entity health relative to health pool
biter.health = health_pool[1] * health_pool[2]
@ -352,7 +375,7 @@ local function on_entity_died(event)
end
end
if this.boss_spawns_projectiles then
if random(1, 96) == 1 then
if random(1, 32) == 1 then
loaded_biters(event)
end
end
@ -513,13 +536,22 @@ function Public.enable_make_normal_unit_mini_bosses(boolean)
return this.make_normal_unit_mini_bosses
end
--- Enables that enemies can recover from stun randomly.
---@param boolean
function Public.enable_randomize_discharge_stun(boolean)
this.randomize_discharge_stun = boolean or false
return this.randomize_discharge_stun
end
Event.on_init(
function()
Public.reset_table()
end
)
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
Event.add(defines.events.on_entity_damaged, on_entity_damaged, filters)
Event.on_nth_tick(7200, check_clear_table)
Event.add(defines.events.on_entity_died, on_entity_died)
Event.add(defines.events.on_entity_died, on_entity_died, filters)
return Public

View File

@ -26,6 +26,8 @@ local spell2_button_name = Public.spell2_button_name
local spell3_button_name = Public.spell3_button_name
local sub = string.sub
local round = math.round
local floor = math.floor
function Public.draw_gui_char_button(player)
if player.gui.top[draw_main_frame_name] then
@ -236,7 +238,7 @@ local function draw_main_frame(player, location)
end
add_gui_description(scroll_table, ({'rpg_gui.experience_name'}), 100)
local exp_gui = add_gui_stat(scroll_table, math.floor(rpg_t.xp), 125, ({'rpg_gui.gain_info_tooltip'}))
local exp_gui = add_gui_stat(scroll_table, floor(rpg_t.xp), 125, ({'rpg_gui.gain_info_tooltip'}))
data.exp_gui = exp_gui
add_gui_description(scroll_table, ' ', 75)
@ -281,11 +283,11 @@ local function draw_main_frame(player, location)
add_gui_description(left_bottom_table, ' ', 40)
add_gui_description(left_bottom_table, ({'rpg_gui.life_name'}), w1, ({'rpg_gui.life_tooltip'}))
local health_gui = add_gui_stat(left_bottom_table, math.floor(player.character.health), w2, ({'rpg_gui.life_increase'}))
local health_gui = add_gui_stat(left_bottom_table, floor(player.character.health), w2, ({'rpg_gui.life_increase'}))
data.health = health_gui
add_gui_stat(
left_bottom_table,
math.floor(player.character.prototype.max_health + player.character_health_bonus + player.force.character_health_bonus),
floor(player.character.prototype.max_health + player.character_health_bonus + player.force.character_health_bonus),
w2,
({'rpg_gui.life_maximum'})
)
@ -299,8 +301,8 @@ local function draw_main_frame(player, location)
local i = player.character.get_inventory(defines.inventory.character_armor)
if not i.is_empty() then
if i[1].grid then
shield = math.floor(i[1].grid.shield)
shield_max = math.floor(i[1].grid.max_shield)
shield = floor(i[1].grid.shield)
shield_max = floor(i[1].grid.max_shield)
shield_desc_tip = ({'rpg_gui.shield_tooltip'})
shield_tip = ({'rpg_gui.shield_current'})
shield_max_tip = ({'rpg_gui.shield_max'})
@ -341,17 +343,17 @@ local function draw_main_frame(player, location)
add_gui_description(right_bottom_table, ' ', w0)
add_gui_description(right_bottom_table, ({'rpg_gui.mining_name'}), w1)
local mining_speed_value = math.round((player.force.manual_mining_speed_modifier + player.character_mining_speed_modifier + 1) * 100) .. '%'
local mining_speed_value = round((player.force.manual_mining_speed_modifier + player.character_mining_speed_modifier + 1) * 100) .. '%'
add_gui_stat(right_bottom_table, mining_speed_value, w2)
add_gui_description(right_bottom_table, ' ', w0)
add_gui_description(right_bottom_table, ({'rpg_gui.slot_name'}), w1)
local slot_bonus_value = '+ ' .. math.round(player.force.character_inventory_slots_bonus + player.character_inventory_slots_bonus)
local slot_bonus_value = '+ ' .. round(player.force.character_inventory_slots_bonus + player.character_inventory_slots_bonus)
add_gui_stat(right_bottom_table, slot_bonus_value, w2)
add_gui_description(right_bottom_table, ' ', w0)
add_gui_description(right_bottom_table, ({'rpg_gui.melee_name'}), w1)
local melee_damage_value = math.round(100 * (1 + Public.get_melee_modifier(player))) .. '%'
local melee_damage_value = round(100 * (1 + Public.get_melee_modifier(player))) .. '%'
local melee_damage_tooltip
if rpg_extra.enable_one_punch then
melee_damage_tooltip = ({
@ -391,17 +393,17 @@ local function draw_main_frame(player, location)
add_gui_description(right_bottom_table, ' ', w0)
add_gui_description(right_bottom_table, ({'rpg_gui.crafting_speed'}), w1)
local crafting_speed_value = math.round((player.force.manual_crafting_speed_modifier + player.character_crafting_speed_modifier + 1) * 100) .. '%'
local crafting_speed_value = round((player.force.manual_crafting_speed_modifier + player.character_crafting_speed_modifier + 1) * 100) .. '%'
add_gui_stat(right_bottom_table, crafting_speed_value, w2)
add_gui_description(right_bottom_table, ' ', w0)
add_gui_description(right_bottom_table, ({'rpg_gui.running_speed'}), w1)
local running_speed_value = math.round((player.force.character_running_speed_modifier + player.character_running_speed_modifier + 1) * 100) .. '%'
local running_speed_value = round((player.force.character_running_speed_modifier + player.character_running_speed_modifier + 1) * 100) .. '%'
add_gui_stat(right_bottom_table, running_speed_value, w2)
add_gui_description(right_bottom_table, ' ', w0)
add_gui_description(right_bottom_table, ({'rpg_gui.health_bonus_name'}), w1)
local health_bonus_value = '+ ' .. math.round((player.force.character_health_bonus + player.character_health_bonus))
local health_bonus_value = '+ ' .. round((player.force.character_health_bonus + player.character_health_bonus))
local health_tooltip = ({'rpg_gui.health_tooltip', Public.get_heal_modifier(player)})
add_gui_stat(right_bottom_table, health_bonus_value, w2, health_tooltip)
@ -409,10 +411,10 @@ local function draw_main_frame(player, location)
if rpg_extra.enable_mana then
add_gui_description(right_bottom_table, ({'rpg_gui.mana_bonus'}), w1)
local mana_bonus_value = '+ ' .. (math.floor(Public.get_mana_modifier(player) * 10) / 10)
local mana_bonus_value = '+ ' .. (floor(Public.get_mana_modifier(player) * 10) / 10)
local mana_bonus_tooltip = ({
'rpg_gui.mana_regen_bonus',
(math.floor(Public.get_mana_modifier(player) * 10) / 10)
(floor(Public.get_mana_modifier(player) * 10) / 10)
})
add_gui_stat(right_bottom_table, mana_bonus_value, w2, mana_bonus_tooltip)
end
@ -475,28 +477,28 @@ function Public.update_player_stats(player)
local rpg_extra = Public.get('rpg_extra')
local rpg_t = Public.get_value_from_player(player.index)
local strength = rpg_t.strength - 10
P.update_single_modifier(player, 'character_inventory_slots_bonus', 'rpg', math.round(strength * 0.2, 3))
P.update_single_modifier(player, 'character_mining_speed_modifier', 'rpg', math.round(strength * 0.007, 3))
P.update_single_modifier(player, 'character_maximum_following_robot_count_bonus', 'rpg', math.round(strength / 2 * 0.03, 3))
P.update_single_modifier(player, 'character_inventory_slots_bonus', 'rpg', round(strength * 0.2, 3))
P.update_single_modifier(player, 'character_mining_speed_modifier', 'rpg', round(strength * 0.007, 3))
P.update_single_modifier(player, 'character_maximum_following_robot_count_bonus', 'rpg', round(strength / 2 * 0.03, 3))
local magic = rpg_t.magicka - 10
local v = magic * 0.22
P.update_single_modifier(player, 'character_build_distance_bonus', 'rpg', math.min(60, math.round(v * 0.12, 3)))
P.update_single_modifier(player, 'character_item_drop_distance_bonus', 'rpg', math.min(60, math.round(v * 0.05, 3)))
P.update_single_modifier(player, 'character_reach_distance_bonus', 'rpg', math.min(60, math.round(v * 0.12, 3)))
P.update_single_modifier(player, 'character_loot_pickup_distance_bonus', 'rpg', math.min(20, math.round(v * 0.12, 3)))
P.update_single_modifier(player, 'character_item_pickup_distance_bonus', 'rpg', math.min(20, math.round(v * 0.12, 3)))
P.update_single_modifier(player, 'character_resource_reach_distance_bonus', 'rpg', math.min(20, math.round(v * 0.05, 3)))
P.update_single_modifier(player, 'character_build_distance_bonus', 'rpg', math.min(60, round(v * 0.12, 3)))
P.update_single_modifier(player, 'character_item_drop_distance_bonus', 'rpg', math.min(60, round(v * 0.05, 3)))
P.update_single_modifier(player, 'character_reach_distance_bonus', 'rpg', math.min(60, round(v * 0.12, 3)))
P.update_single_modifier(player, 'character_loot_pickup_distance_bonus', 'rpg', math.min(20, round(v * 0.12, 3)))
P.update_single_modifier(player, 'character_item_pickup_distance_bonus', 'rpg', math.min(20, round(v * 0.12, 3)))
P.update_single_modifier(player, 'character_resource_reach_distance_bonus', 'rpg', math.min(20, round(v * 0.05, 3)))
if rpg_t.mana_max >= rpg_extra.mana_limit then
rpg_t.mana_max = rpg_extra.mana_limit
else
rpg_t.mana_max = math.round((magic) * 2, 3)
rpg_t.mana_max = round((magic) * 2, 3)
end
local dexterity = rpg_t.dexterity - 10
P.update_single_modifier(player, 'character_running_speed_modifier', 'rpg', math.round(dexterity * 0.0015, 3))
P.update_single_modifier(player, 'character_crafting_speed_modifier', 'rpg', math.round(dexterity * 0.015, 3))
P.update_single_modifier(player, 'character_health_bonus', 'rpg', math.round((rpg_t.vitality - 10) * 6, 3))
P.update_single_modifier(player, 'character_running_speed_modifier', 'rpg', round(dexterity * 0.0010, 3)) -- reduced since too high speed kills UPS.
P.update_single_modifier(player, 'character_crafting_speed_modifier', 'rpg', round(dexterity * 0.015, 3))
P.update_single_modifier(player, 'character_health_bonus', 'rpg', round((rpg_t.vitality - 10) * 6, 3))
P.update_player_modifiers(player)
end

View File

@ -57,20 +57,39 @@ local function valid(userdata)
return true
end
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 find_initial_spot(surface, position)
local spot = WD.get('spot')
if not spot then
local pos = surface.find_non_colliding_position('rocket-silo', position, 128, 1)
local pos = surface.find_non_colliding_position('stone-furnace', position, 128, 1)
if not pos then
pos = surface.find_non_colliding_position('rocket-silo', position, 148, 1)
pos = surface.find_non_colliding_position('stone-furnace', position, 148, 1)
end
if not pos then
pos = surface.find_non_colliding_position('rocket-silo', position, 164, 1)
pos = surface.find_non_colliding_position('stone-furnace', position, 164, 1)
end
if not pos then
pos = position
end
if math_random(1, 2) == 1 then
local random_pos = {{x = pos.x - 10, y = pos.y - 5}, {x = pos.x + 10, y = pos.y + 5}, {x = pos.x - 10, y = pos.y + 5}, {x = pos.x + 10, y = pos.y - 5}}
local actual_pos = shuffle(random_pos)
pos = {x = actual_pos[1].x, y = actual_pos[1].y}
end
if not pos then
pos = position
end
WD.set('spot', pos)
return pos
else
@ -181,7 +200,7 @@ local function get_spawn_pos()
local initial_position = WD.get('spawn_position')
local located_position = find_initial_spot(surface, initial_position)
local valid_position = surface.find_non_colliding_position('behemoth-biter', located_position, 32, 1)
local valid_position = surface.find_non_colliding_position('steel-chest', located_position, 32, 1)
local debug = WD.get('debug')
if debug then
if valid_position then
@ -338,6 +357,12 @@ local function set_main_target()
end
end
local unit_groups_size = WD.get('unit_groups_size')
if unit_groups_size < 0 then
unit_groups_size = 0
end
WD.set('unit_groups_size', unit_groups_size)
local sec_target = SideTargets.get_side_target()
if not sec_target then
sec_target = get_random_character()
@ -429,9 +454,14 @@ local function get_active_unit_groups_count()
count = count + 1
else
g.destroy()
unit_groups[k] = nil
local unit_groups_size = WD.get('unit_groups_size')
WD.set('unit_groups_size', unit_groups_size - 1)
end
else
unit_groups[k] = nil
local unit_groups_size = WD.get('unit_groups_size')
WD.set('unit_groups_size', unit_groups_size - 1)
local unit_group_last_command = WD.get('unit_group_last_command')
if unit_group_last_command[k] then
unit_group_last_command[k] = nil
@ -447,10 +477,12 @@ local function get_active_unit_groups_count()
return count
end
local function spawn_biter(surface, is_boss_biter)
if not is_boss_biter then
if not can_units_spawn() then
return
local function spawn_biter(surface, position, forceSpawn, is_boss_biter)
if not forceSpawn then
if not is_boss_biter then
if not can_units_spawn() then
return
end
end
end
@ -462,11 +494,17 @@ local function spawn_biter(surface, is_boss_biter)
else
name = BiterRolls.wave_defense_roll_biter_name()
end
local position = get_spawn_pos()
local old_position = position
position = surface.find_non_colliding_position('steel-chest', position, 10, 1)
if not position then
position = old_position
end
local biter = surface.create_entity({name = name, position = position, force = 'enemy'})
biter.ai_settings.allow_destroy_when_commands_fail = true
biter.ai_settings.allow_try_return_to_spawner = true
biter.ai_settings.allow_try_return_to_spawner = false
biter.ai_settings.do_separation = true
local increase_health_per_wave = WD.get('increase_health_per_wave')
@ -615,6 +653,8 @@ local function reform_group(group)
debug_print('Creating new unit group, because old one was stuck.')
local unit_groups = WD.get('unit_groups')
unit_groups[new_group.group_number] = new_group
local unit_groups_size = WD.get('unit_groups_size')
WD.set('unit_groups_size', unit_groups_size + 1)
return new_group
else
@ -631,6 +671,8 @@ local function reform_group(group)
positions[group.group_number] = nil
end
table.remove(unit_groups, group.group_number)
local unit_groups_size = WD.get('unit_groups_size')
WD.set('unit_groups_size', unit_groups_size - 1)
end
group.destroy()
end
@ -883,10 +925,14 @@ local function give_main_command_to_group()
end
end
local function spawn_unit_group()
if not can_units_spawn() then
debug_print('spawn_unit_group - Cant spawn units?')
return
local function spawn_unit_group(fs)
if fs then
debug_print('spawn_unit_group - forcing new biters')
else
if not can_units_spawn() then
debug_print('spawn_unit_group - Cant spawn units?')
return
end
end
local target = WD.get('target')
if not valid(target) then
@ -895,9 +941,13 @@ local function spawn_unit_group()
end
local max_active_unit_groups = WD.get('max_active_unit_groups')
if get_active_unit_groups_count() >= max_active_unit_groups then
debug_print('spawn_unit_group - unit_groups at max')
return
if fs then
debug_print('spawn_unit_group - forcing new biters')
else
if get_active_unit_groups_count() >= max_active_unit_groups then
debug_print('spawn_unit_group - unit_groups at max')
return
end
end
local surface_index = WD.get('surface_index')
local remove_entities = WD.get('remove_entities')
@ -932,15 +982,14 @@ local function spawn_unit_group()
BiterRolls.wave_defense_set_unit_raffle(wave_number)
debug_print('Spawning unit group at x' .. spawn_position.x .. ' y' .. spawn_position.y)
local position = spawn_position
local unit_group_pos = WD.get('unit_group_pos')
local unit_group = surface.create_unit_group({position = position, force = 'enemy'})
local unit_group = surface.create_unit_group({position = spawn_position, force = 'enemy'})
unit_group_pos.positions[unit_group.group_number] = {position = unit_group.position, index = 0}
local average_unit_group_size = WD.get('average_unit_group_size')
local group_size = math_floor(average_unit_group_size * group_size_modifier_raffle[math_random(1, group_size_modifier_raffle_size)])
for _ = 1, group_size, 1 do
local biter = spawn_biter(surface)
local biter = spawn_biter(surface, spawn_position, fs)
if not biter then
debug_print('spawn_unit_group - No biters were found?')
break
@ -951,7 +1000,7 @@ local function spawn_unit_group()
end
local boss_wave = WD.get('boss_wave')
if boss_wave then
if not boss_wave then
local count = math_random(1, math_floor(wave_number * 0.01) + 2)
if count > 16 then
count = 16
@ -960,7 +1009,7 @@ local function spawn_unit_group()
count = 4
end
for _ = 1, count, 1 do
local biter = spawn_biter(surface, true)
local biter = spawn_biter(surface, spawn_position, fs, true)
if not biter then
debug_print('spawn_unit_group - No biters were found?')
break
@ -972,8 +1021,10 @@ local function spawn_unit_group()
local unit_groups = WD.get('unit_groups')
unit_groups[unit_group.group_number] = unit_group
local unit_groups_size = WD.get('unit_groups_size')
WD.set('unit_groups_size', unit_groups_size + 1)
if math_random(1, 2) == 1 then
WD.set('random_group', unit_group.group_number)
WD.set('random_group', unit_group)
end
WD.set('spot', 'nil')
return true
@ -1028,7 +1079,6 @@ end
local tick_tasks = {
[30] = set_main_target,
[60] = set_enemy_evolution,
[90] = spawn_unit_group,
[120] = give_main_command_to_group,
[150] = ThreatEvent.build_nest,
[180] = ThreatEvent.build_worm,
@ -1037,7 +1087,7 @@ local tick_tasks = {
[7200] = refresh_active_unit_threat
}
local function on_tick()
local function t1()
local tick = game.tick
local game_lost = WD.get('game_lost')
if game_lost then
@ -1058,10 +1108,10 @@ local function on_tick()
local t2 = tick % 18000
if tick_tasks[t] then
tick_tasks[t]()
tick_tasks[t](true)
end
if tick_tasks[t2] then
tick_tasks[t2]()
tick_tasks[t2](true)
end
local resolve_pathing = WD.get('resolve_pathing')
@ -1083,6 +1133,23 @@ local function on_tick()
end
end
Event.on_nth_tick(30, on_tick)
local function t2()
local game_lost = WD.get('game_lost')
if game_lost then
return
end
local paused = WD.get('paused')
if paused then
return
end
spawn_unit_group()
end
Public.spawn_unit_group = spawn_unit_group
Event.on_nth_tick(30, t1)
Event.on_nth_tick(130, t2)
return Public

View File

@ -18,6 +18,10 @@ function Public.debug_module()
this.debug = true
end
function Public.enable_debug()
this.debug = true
end
function Public.reset_wave_defense()
this.boss_wave = false
this.boss_wave_warning = false
@ -50,6 +54,7 @@ function Public.reset_wave_defense()
this.threat_log = {}
this.threat_log_index = 0
this.unit_groups = {}
this.unit_groups_size = 0
this.unit_group_pos = {
positions = {}
}

View File

@ -36,7 +36,10 @@ end
local function place_nest_near_unit_group()
local unit_groups = WD.get('unit_groups')
local random_group = WD.get('random_group')
local group = unit_groups[random_group]
if not (random_group and random_group.valid) then
return
end
local group = unit_groups[random_group.group_number]
if not group then
return
end
@ -74,6 +77,7 @@ local function place_nest_near_unit_group()
return
end
local spawner = unit.surface.create_entity({name = name, position = position, force = unit.force})
BiterHealthBooster.add_boss_unit(spawner, 4)
local nests = WD.get('nests')
nests[#nests + 1] = spawner
unit.surface.create_entity({name = 'blood-explosion-huge', position = position})
@ -90,8 +94,8 @@ function Public.build_nest()
if threat < 1024 then
return
end
local index = WD.get('index')
if index == 0 then
local unit_groups_size = WD.get('unit_groups_size')
if unit_groups_size == 0 then
return
end
for _ = 1, 2, 1 do
@ -111,14 +115,17 @@ function Public.build_worm()
return
end
local index = WD.get('index')
if index == 0 then
local unit_groups_size = WD.get('unit_groups_size')
if unit_groups_size == 0 then
return
end
local random_group = WD.get('random_group')
if not (random_group and random_group.valid) then
return
end
local unit_groups = WD.get('unit_groups')
local group = unit_groups[random_group]
local group = unit_groups[random_group.group_number]
if not group then
return
end
@ -157,7 +164,8 @@ function Public.build_worm()
then
return
end
unit.surface.create_entity({name = worm, position = position, force = unit.force})
local u = unit.surface.create_entity({name = worm, position = position, force = unit.force})
BiterHealthBooster.add_boss_unit(u, 4)
unit.surface.create_entity({name = 'blood-explosion-huge', position = position})
unit.surface.create_entity({name = 'blood-explosion-huge', position = unit.position})
remove_unit(unit)

View File

@ -161,12 +161,13 @@ end
-- See documentation at top of file for details on using events.
-- @param event_name<number>
-- @param handler<function>
function Event.add(event_name, handler)
-- @optional param filters<table>
function Event.add(event_name, handler, filters)
if _LIFECYCLE == 8 then
error('Calling Event.add after on_init() or on_load() has run is a desync risk.', 2)
end
core_add(event_name, handler)
core_add(event_name, handler, filters)
end
--- Register a handler for the script.on_init event.

View File

@ -91,15 +91,23 @@ local function on_nth_tick_event(event)
end
--- Do not use this function, use Event.add instead as it has safety checks.
function Public.add(event_name, handler)
function Public.add(event_name, handler, filters)
local handlers = event_handlers[event_name]
if not handlers then
event_handlers[event_name] = {handler}
script_on_event(event_name, on_event)
if filters then
script_on_event(event_name, on_event, filters)
else
script_on_event(event_name, on_event)
end
else
table.insert(handlers, handler)
if #handlers == 1 then
script_on_event(event_name, on_event)
if filters then
script_on_event(event_name, on_event, filters)
else
script_on_event(event_name, on_event)
end
end
end
end