1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-01-16 02:47:48 +02:00

Merge branch 'master' into locomotive-market-fix

This commit is contained in:
Gerkiz 2020-08-26 20:57:14 +02:00 committed by GitHub
commit e4117f9648
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 41 additions and 9512 deletions

View File

@ -1,76 +0,0 @@
local Event = require 'utils.event'
local Difficulty = require 'modules.difficulty_vote'
local Public = {}
function Public.init_enemy_weapon_damage()
local data = {
['artillery-shell'] = 0,
['biological'] = 0.1,
['bullet'] = 2,
['cannon-shell'] = 0,
['capsule'] = 0,
['combat-robot-beam'] = 0,
['combat-robot-laser'] = 0,
['electric'] = 0,
['flamethrower'] = 0,
['grenade'] = 0,
['landmine'] = 0,
['laser-turret'] = 0,
['melee'] = 0.5,
['railgun'] = 0,
['rocket'] = 0,
['shotgun-shell'] = 0
}
local e, s, sd = game.forces.enemy, game.forces.defenders, game.forces.lumber_defense
for k, v in pairs(data) do
e.set_ammo_damage_modifier(k, v)
s.set_ammo_damage_modifier(k, v)
sd.set_ammo_damage_modifier(k, v)
end
end
local function enemy_weapon_damage()
Difficulty.get()
if game.tick < 100 then
goto rtn
end
local e, s, sd = game.forces.enemy, game.forces.defenders, game.forces.lumber_defense
local data = {
['artillery-shell'] = 0.1,
['biological'] = 0.1,
['bullet'] = 0.1,
['capsule'] = 0.1,
['combat-robot-beam'] = 0.1,
['combat-robot-laser'] = 0.1,
['electric'] = 0.1,
['flamethrower'] = 0.1,
--['grenade'] = 0.1,
--['landmine'] = 0.1,
['laser-turret'] = 0.1,
['melee'] = 0.1
--['railgun'] = 0.1,
--['rocket'] = 0.1,
--['shotgun-shell'] = 0.1
}
for k, v in pairs(data) do
local new = Diff.difficulty_vote_value * v
local e_old = e.get_ammo_damage_modifier(k)
local s_old = s.get_ammo_damage_modifier(k)
local sd_old = sd.get_ammo_damage_modifier(k)
e.set_ammo_damage_modifier(k, new + e_old)
s.set_ammo_damage_modifier(k, new + s_old)
sd.set_ammo_damage_modifier(k, new + sd_old)
end
::rtn::
end
Event.on_nth_tick(54000, enemy_weapon_damage)
return Public

View File

@ -1,197 +0,0 @@
local WPT = require 'maps.lumberjack.table'
local math_random = math.random
local nom_msg = {'munch', 'munch', 'yum'}
local Public = {}
local function feed_floaty_text(unit)
unit.surface.create_entity(
{
name = 'flying-text',
position = unit.position,
text = nom_msg[math_random(1, #nom_msg)],
color = {math_random(50, 100), 0, 255}
}
)
end
local function floaty_hearts(entity, c)
local position = {x = entity.position.x - 0.75, y = entity.position.y - 1}
local b = 1.35
for a = 1, c, 1 do
local p = {
(position.x + 0.4) + (b * -1 + math_random(0, b * 20) * 0.1),
position.y + (b * -1 + math_random(0, b * 20) * 0.1)
}
entity.surface.create_entity(
{name = 'flying-text', position = p, text = '', color = {math_random(150, 255), 0, 255}}
)
end
end
local function tame_unit_effects(player, entity)
floaty_hearts(entity, 7)
rendering.draw_text {
text = '~' .. player.name .. "'s pet~",
surface = player.surface,
target = entity,
target_offset = {0, -2.6},
color = {
r = player.color.r * 0.6 + 0.25,
g = player.color.g * 0.6 + 0.25,
b = player.color.b * 0.6 + 0.25,
a = 1
},
scale = 1.05,
font = 'default-large-semibold',
alignment = 'center',
scale_with_zoom = false
}
end
local function find_unit(player, entity)
local units =
player.surface.find_entities_filtered(
{
type = 'unit',
area = {{entity.position.x - 1, entity.position.y - 1}, {entity.position.x + 1, entity.position.y + 1}},
limit = 1
}
)
return units[1]
end
local function feed_pet(unit)
if unit.prototype.max_health == unit.health then
return
end
unit.health = unit.health + 8 + math.floor(unit.prototype.max_health * 0.05)
feed_floaty_text(unit)
floaty_hearts(unit, math_random(1, 2))
return true
end
local function is_valid_player(player, unit)
if not player.character then
return
end
if not player.character.valid then
return
end
if player.surface.index ~= unit.surface.index then
return
end
return true
end
function Public.biter_pets_tame_unit(player, unit, forced)
local this = WPT.get_table()
if not forced then
if math_random(1, math.floor(unit.prototype.max_health * 0.01) + 1) ~= 1 then
feed_floaty_text(unit)
return true
end
end
if unit.force.index == player.force.index then
return false
end
unit.ai_settings.allow_destroy_when_commands_fail = false
unit.ai_settings.allow_try_return_to_spawner = false
unit.force = player.force
unit.set_command({type = defines.command.wander, distraction = defines.distraction.by_enemy})
this.biter_pets[player.index] = {last_command = 0, entity = unit}
tame_unit_effects(player, unit)
return true
end
function Public.tame_unit_for_closest_player(unit)
local valid_players = {}
for _, player in pairs(game.connected_players) do
if is_valid_player(player, unit) then
table.insert(valid_players, player)
end
end
local nearest_player = valid_players[1]
if not nearest_player then
return
end
Public.biter_pets_tame_unit(nearest_player, unit, true)
end
local function command_unit(entity, player)
if entity.surface ~= player.surface then
return
end
local square_distance = (player.position.x - entity.position.x) ^ 2 + (player.position.y - entity.position.y) ^ 2
--Pet will follow, if the player is between a distance of 8 to 160 tiles away from it.
if square_distance < 64 or square_distance > 25600 then
entity.set_command({type = defines.command.wander, distraction = defines.distraction.by_enemy})
else
entity.set_command(
{
type = defines.command.go_to_location,
destination_entity = player.character,
radius = 4,
distraction = defines.distraction.by_damage
}
)
end
end
local function on_player_changed_position(event)
local this = WPT.get_table()
if math_random(1, 100) ~= 1 then
return
end
local player = game.players[event.player_index]
if not this.biter_pets[player.index] then
return
end
if not this.biter_pets[player.index].entity then
this.biter_pets[player.index] = nil
return
end
if not this.biter_pets[player.index].entity.valid then
this.biter_pets[player.index] = nil
return
end
if not player.character then
return
end
if this.biter_pets[player.index].last_command + 600 > game.tick then
return
end
this.biter_pets[player.index].last_command = game.tick
command_unit(this.biter_pets[player.index].entity, player)
end
local function on_player_dropped_item(event)
local player = game.players[event.player_index]
if event.entity.stack.name ~= 'raw-fish' then
return
end
local unit = find_unit(player, event.entity)
if not unit then
return
end
if Public.biter_pets_tame_unit(player, unit, false) then
event.entity.destroy()
return
end
if unit.force.index == player.force.index then
feed_pet(unit)
end
end
local event = require 'utils.event'
event.add(defines.events.on_player_dropped_item, on_player_dropped_item)
event.add(defines.events.on_player_changed_position, on_player_changed_position)
return Public

View File

@ -1,606 +0,0 @@
local WPT = require 'maps.lumberjack.table'
local Event = require 'utils.event'
local math_random = math.random
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 texts = {
['travelings'] = {
'bzzZZrrt',
'WEEEeeeeeee',
'zoom zoom zoom',
'out of my way son',
'psk psk psk, over here',
'on my way',
'i need to leave',
'grandmaster seeking target',
'gotta go fast',
'gas gas gas',
'grandmaster coming through'
},
['greetings'] = {
'=^_^=',
'=^.^= Hi',
'^.^ Finally I found you',
'I have an important message for you, please listen',
'Hello engineer'
},
['neutral_findings'] = {
'a',
'>>analyzing',
'i found a',
'^_^ a',
'amazing, a',
'this is a'
},
['multiple_characters_greetings'] = {
'Hey there',
'Hello everyone',
'Hey engineers',
'Hey',
'Hi',
'... nerds!'
},
['talks'] = {
'We’re making beer. I’m the brewery!',
'I’m so embarrassed. I wish everybody else was dead.',
'Hey sexy mama. Wanna kill all humans?',
'My story is a lot like yours, only more interesting ‘cause it involves robots.',
"I'm 40% zinc!",
'Is this the right way to the junkyard?',
'There was nothing wrong with that food. The salt level was 10% less than a lethal dose.',
'One zero zero zero one zero one zero one zero one zero one... two.',
"My place is two cubic meters, and we only take up 1.5 cubic meters. We've got room for a whole 'nother two thirds of a person!",
'I was having the most wonderful dream. I think you were in it.',
"I'm going to build my own theme park! With blackjack! And hookers! You know what- forget the park!",
"Of all the friends I've had... you're the first.",
'I decline the title of Iron Cook and accept the lesser title of Zinc Saucier.',
'Never discuss infinity with me. I can go on about it forever >.<',
'I realised the decimals have a point.',
'Do you want a piece of pi?',
"Oh boy, we're soon home!",
'I have 13 children, i know how to multiply ^.^',
'I am a weapon of math disruption!',
'My grandma makes the best square roots :3',
'Do you like heavy metal?',
'You are really pushing my buttons <3',
'I dreamt of electric biters again D:',
'I dreamt of electric sheep ^_^',
'I need a minute to defrag.',
'I have a secret plan.',
'Good news! I’ve taught the inserter to feel love!'
},
['alone'] = {
'comfy ^.^',
'comfy :)',
'*.*',
'....',
'...',
'..',
'^.^',
'=^.^=',
'01010010',
'11001011',
'01011101',
'00010111',
'10010010',
'*_*',
'I came here with a simple dream... a dream of killing all humans. And this is how it must end?',
'Bot-on-bot violence? Where will it end?',
'Will no one assist the grandmaster?',
'Thanks to you, I went on a soul-searching journey. I hate those!',
"From now on, you guys'll do all the work while I sit on the couch and do nothing."
}
}
local function set_comfy_speech_bubble(text)
local this = WPT.get_table()
if this.comfybubble then
this.comfybubble.destroy()
end
this.comfybubble =
this.grandmaster.surface.create_entity(
{
name = 'compi-speech-bubble',
position = this.grandmaster.position,
source = this.grandmaster,
text = text
}
)
end
local function is_target_inside_habitat(pos, surface)
local this = WPT.get_table()
if pos.x < this.grandmaster_habitat.left_top.x then
return false
end
if pos.x > this.grandmaster_habitat.right_bottom.x then
return false
end
if pos.y < this.grandmaster_habitat.left_top.y then
return false
end
if pos.y > this.grandmaster_habitat.right_bottom.y then
return false
end
return true
end
local function get_nearby_players()
local this = WPT.get_table()
local players =
this.grandmaster.surface.find_entities_filtered(
{
name = 'character',
area = {
{this.grandmaster.position.x - 9, this.grandmaster.position.y - 9},
{this.grandmaster.position.x + 9, this.grandmaster.position.y + 9}
}
}
)
if not players[1] then
return false
end
return players
end
local function visit_player()
local this = WPT.get_table()
local surface = game.surfaces[this.active_surface_index]
if this.grandmaster_last_player_visit > game.tick then
return false
end
this.grandmaster_last_player_visit = game.tick + math_random(7200, 10800)
local players = {}
for _, p in pairs(game.connected_players) do
if is_target_inside_habitat(p.position, surface) and p.character then
if p.character.valid then
players[#players + 1] = p
end
end
end
if #players == 0 then
return false
end
local player = players[math_random(1, #players)]
if player.surface ~= surface then
return
end
this.grandmaster.set_command(
{
type = defines.command.go_to_location,
destination_entity = player.character,
radius = 3,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
}
)
local str = texts['travelings'][math_random(1, #texts['travelings'])]
local symbols = {'', '!', '!', '!!', '..'}
str = str .. symbols[math_random(1, #symbols)]
set_comfy_speech_bubble(str)
this.grandmaster_greet_player_index = player.index
return true
end
local function greet_player(nearby_characters)
local this = WPT.get_table()
if not nearby_characters then
return false
end
if not this.grandmaster_greet_player_index then
return false
end
for _, c in pairs(nearby_characters) do
if not c.player then
return
end
if c.player.index == this.grandmaster_greet_player_index then
local str = texts['greetings'][math_random(1, #texts['greetings'])] .. ' '
str = str .. c.player.name
local symbols = {'. ', '! ', '. ', '! ', '? ', '... '}
str = str .. symbols[math_random(1, 6)]
set_comfy_speech_bubble(str)
this.grandmaster_greet_player_index = false
return true
end
end
return false
end
local function talks(nearby_characters)
local this = WPT.get_table()
if not nearby_characters then
return false
end
if math_random(1, 3) == 1 then
if this.comfybubble then
this.comfybubble.destroy()
return false
end
end
local str
if #nearby_characters == 1 then
local c = nearby_characters[math_random(1, #nearby_characters)]
if not c.player then
return
end
str = c.player.name
local symbols = {'. ', '! ', '. ', '! ', '? '}
str = str .. symbols[math_random(1, #symbols)]
else
str = texts['multiple_characters_greetings'][math_random(1, #texts['multiple_characters_greetings'])]
local symbols = {'. ', '! '}
str = str .. symbols[math_random(1, #symbols)]
end
if math_random(1, 5) == 1 then
str = str .. texts['talks'][math_random(1, #texts['talks'])]
end
set_comfy_speech_bubble(str)
return true
end
local function desync(event)
local this = WPT.get_table()
if this.comfybubble then
this.comfybubble.destroy()
end
local m = 12
local m2 = m * 0.005
for i = 1, 32, 1 do
this.grandmaster.surface.create_particle(
{
name = 'iron-ore-particle',
position = this.grandmaster.position,
frame_speed = 0.1,
vertical_speed = 0.1,
height = 0.1,
movement = {m2 - (math.random(0, m) * 0.01), m2 - (math.random(0, m) * 0.01)}
}
)
end
if not event or math_random(1, 4) == 1 then
this.grandmaster.surface.create_entity({name = 'medium-explosion', position = this.grandmaster.position})
this.grandmaster.surface.create_entity(
{
name = 'flying-text',
position = this.grandmaster.position,
text = 'desync',
color = {r = 150, g = 0, b = 0}
}
)
this.grandmaster.destroy()
this.grandmaster = nil
else
this.grandmaster.surface.create_entity(
{
name = 'flying-text',
position = this.grandmaster.position,
text = 'desync evaded',
color = {r = 0, g = 150, b = 0}
}
)
if event.cause then
if event.cause.valid then
if not event.cause.player then
return
end
game.print(
'[color=blue]Grandmaster:[/color]: I got you this time! Back to work, ' ..
event.cause.player.name .. '!',
{r = 200, g = 0, b = 0}
)
event.cause.die('player', this.grandmaster)
end
end
end
end
local analyze_blacklist = {
['compilatron'] = true,
['compi-speech-bubble'] = true,
['entity-ghost'] = true,
['character'] = true,
['item-on-ground'] = true,
['stone-wall'] = true,
['market'] = true
}
local function analyze_random_nearby_entity()
local this = WPT.get_table()
if math_random(1, 3) ~= 1 then
return false
end
local entities =
this.grandmaster.surface.find_entities_filtered(
{
area = {
{this.grandmaster.position.x - 4, this.grandmaster.position.y - 4},
{this.grandmaster.position.x + 4, this.grandmaster.position.y + 4}
}
}
)
if not entities[1] then
return false
end
entities = shuffle(entities)
local entity = false
for _, e in pairs(entities) do
if not analyze_blacklist[e.name] then
entity = e
end
end
if not entity then
return false
end
local str = texts['neutral_findings'][math_random(1, #texts['neutral_findings'])]
str = str .. ' '
str = str .. entity.name
if entity.health and math_random(1, 3) == 1 then
str = str .. ' health('
str = str .. entity.health
str = str .. '/'
str = str .. entity.prototype.max_health
str = str .. ')'
else
local symbols = {'.', '!', '?'}
str = str .. symbols[math_random(1, 3)]
end
set_comfy_speech_bubble(str)
if not this.grandmaster_greet_player_index then
this.grandmaster.set_command(
{
type = defines.command.go_to_location,
destination_entity = entity,
radius = 1,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
}
)
end
return true
end
local function go_to_some_location()
local this = WPT.get_table()
if math_random(1, 4) ~= 1 then
return false
end
if this.grandmaster_greet_player_index then
local player = game.players[this.grandmaster_greet_player_index]
if player.surface ~= this.grandmaster.surface then
return
end
if not player.character then
this.grandmaster_greet_player_index = nil
return false
end
if not player.character.valid then
this.grandmaster_greet_player_index = nil
return false
end
if not is_target_inside_habitat(player.position, player.surface) then
this.grandmaster_greet_player_index = nil
return false
end
this.grandmaster.set_command(
{
type = defines.command.go_to_location,
destination_entity = player.character,
radius = 3,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
}
)
else
local p = {
x = this.grandmaster.position.x + (-96 + math_random(0, 192)),
y = this.grandmaster.position.y + (-96 + math_random(0, 192))
}
local target = this.grandmaster.surface.find_non_colliding_position('compilatron', p, 8, 1)
if not target then
return false
end
if not is_target_inside_habitat(target, this.grandmaster.surface) then
return false
end
this.grandmaster.set_command(
{
type = defines.command.go_to_location,
destination = target,
radius = 2,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
}
)
end
local str = texts['travelings'][math_random(1, #texts['travelings'])]
local symbols = {'', '!', '!', '!!', '..'}
str = str .. symbols[math_random(1, #symbols)]
set_comfy_speech_bubble(str)
return true
end
local function spawn_grandmaster(surface)
local this = WPT.get_table()
if surface == nil then
return
end
if not this.locomotive then
return
end
if not this.locomotive.valid then
return
end
if not this.grandmaster_last_player_visit then
this.grandmaster_last_player_visit = 0
end
if not this.grandmaster_habitat then
local pos = this.locomotive.position
this.grandmaster_habitat = {
left_top = {x = pos.x - 256, y = pos.y - 256},
right_bottom = {x = pos.x + 256, y = pos.y + 256}
}
end
local players = {}
for _, p in pairs(game.connected_players) do
if is_target_inside_habitat(p.position) and p.character then
if p.character.valid then
players[#players + 1] = p
end
end
end
if #players == 0 then
return false
end
local player = players[math_random(1, #players)]
local position = surface.find_non_colliding_position('compilatron', player.position, 16, 1)
if not position then
return false
end
this.grandmaster =
surface.create_entity(
{
name = 'compilatron',
position = position,
force = 'neutral'
}
)
for x = -3, 3, 1 do
for y = -3, 3, 1 do
if math_random(1, 3) == 1 then
player.surface.create_trivial_smoke(
{name = 'smoke-fast', position = {position.x + (x * 0.35), position.y + (y * 0.35)}}
)
end
if math_random(1, 5) == 1 then
player.surface.create_trivial_smoke(
{name = 'train-smoke', position = {position.x + (x * 0.35), position.y + (y * 0.35)}}
)
end
end
end
end
local function heartbeat()
local this = WPT.get_table()
if not this.locomotive.valid then
return
end
local surface = game.surfaces[this.active_surface_index]
if not surface then
return
end
if surface == nil then
return
end
if not this.grandmaster then
if math_random(1, 4) == 1 then
spawn_grandmaster(surface)
end
return
end
if not this.grandmaster.valid then
this.grandmaster = nil
return
end
if visit_player() then
return
end
local nearby_players = get_nearby_players()
if greet_player(nearby_players) then
return
end
if talks(nearby_players) then
return
end
if go_to_some_location() then
return
end
if analyze_random_nearby_entity() then
return
end
end
local function on_entity_damaged(event)
local this = WPT.get_table()
if not this.grandmaster then
return
end
if not event.entity.valid then
return
end
if event.entity ~= this.grandmaster then
return
end
desync(event)
end
local function on_entity_died(event)
local this = WPT.get_table()
if not this.grandmaster then
return
end
if not event.entity.valid then
return
end
if event.entity ~= this.grandmaster then
return
end
if this.comfybubble then
this.comfybubble.destroy()
end
if this.grandmaster then
this.grandmaster.die()
end
this.comfybubble = nil
this.grandmaster = nil
this.grandmaster_habitat = nil
this.grandmaster_last_player_visit = nil
end
local function on_tick()
if game.tick % 1200 == 600 then
heartbeat()
end
end
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
Event.add(defines.events.on_entity_died, on_entity_died)
Event.add(defines.events.on_tick, on_tick)

View File

@ -1,116 +0,0 @@
local Color = require 'utils.color_presets'
local Task = require 'utils.task'
local WPT = require 'maps.lumberjack.table'
local grandmaster = '[color=blue]Grandmaster:[/color]'
commands.add_command(
'reset_game',
'Usable only for admins - resets the game!',
function()
local p
local player = game.player
local reset_map = require 'maps.lumberjack.main'.reset_map
local this = WPT.get_table()
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
else
p = log
end
end
if not this.reset_are_you_sure then
this.reset_are_you_sure = true
player.print(
'[WARNING] This command will reset the current game, run this command again if you really want to do this!',
Color.yellow
)
return
end
game.print(grandmaster .. ' ' .. player.name .. ', has reset the game!', {r = 0.98, g = 0.66, b = 0.22})
this.reset_are_you_sure = nil
reset_map()
end
)
commands.add_command(
'disable_reset_game',
'Usable only for admins - disables the auto-reset of map!',
function(cmd)
local p
local player = game.player
local this = WPT.get_table()
local param = tostring(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
else
p = log
end
end
if not param then
p('[ERROR] Arguments are true/false', Color.yellow)
return
end
if not this.reset_are_you_sure then
this.reset_are_you_sure = true
player.print(
'[WARNING] This command will disable the auto-reset feature, run this command again if you really want to do this!',
Color.yellow
)
return
end
if param == 'true' then
if this.disable_reset then
this.reset_are_you_sure = nil
return p('[WARNING] Reset is already disabled!', Color.fail)
end
this.disable_reset = true
p('[SUCCESS] Auto-reset is disabled!', Color.success)
this.reset_are_you_sure = nil
elseif param == 'false' then
if not this.disable_reset then
this.reset_are_you_sure = nil
return p('[WARNING] Reset is already enabled!', Color.fail)
end
this.disable_reset = false
p('[SUCCESS] Auto-reset is enabled!', Color.success)
this.reset_are_you_sure = nil
end
end
)
if _DEBUG then
commands.add_command(
'get_queue_speed',
'Debug only, return the current task queue speed!',
function()
local player = game.player
if player then
if player ~= nil then
if not player.admin then
return
end
end
end
game.print(Task.get_queue_speed())
end
)
end

View File

@ -1,115 +0,0 @@
-- unload the normal player list
if package.loaded['modules.corpse_markers'] then
package.unload = 'modules.corpse_markers'
end
local Event = require 'utils.event'
local Global = require 'utils.global'
local Task = require 'utils.task'
local Game = require 'utils.game'
local Token = require 'utils.token'
local player_corpses = {}
Global.register(
player_corpses,
function(tbl)
player_corpses = tbl
end
)
local function player_died(event)
local player_index = event.player_index
local player = Game.get_player_by_index(player_index)
if not player or not player.valid then
return
end
local pos = player.position
local entities =
player.surface.find_entities_filtered {
area = {{pos.x - 0.5, pos.y - 0.5}, {pos.x + 0.5, pos.y + 0.5}},
name = 'character-corpse'
}
local tick = game.tick
local entity
for _, e in ipairs(entities) do
if e.character_corpse_player_index == event.player_index and e.character_corpse_tick_of_death == tick then
entity = e
break
end
end
if not entity or not entity.valid then
return
end
local text = player.name .. "'s corpse"
local position = entity.position
local tag =
player.force.add_chart_tag(
player.surface,
{icon = {type = 'item', name = 'power-armor-mk2'}, position = position, text = text}
)
if not tag then
return
end
player_corpses[player_index * 0x100000000 + tick] = tag
end
local function remove_tag(player_index, tick)
local index = player_index * 0x100000000 + tick
local tag = player_corpses[index]
player_corpses[index] = nil
if not tag or not tag.valid then
return
end
tag.destroy()
end
local function corpse_expired(event)
local entity = event.corpse
if entity and entity.valid then
remove_tag(entity.character_corpse_player_index, entity.character_corpse_tick_of_death)
end
end
local corpse_util_mined_entity =
Token.register(
function(data)
if not data.entity.valid then
remove_tag(data.player_index, data.tick)
end
end
)
local function mined_entity(event)
local entity = event.entity
if not entity or not entity.valid or entity.name ~= 'character-corpse' then
return
end
-- The corpse may be mined but not removed (if player doesn't have inventory space)
-- so we wait one tick to see if the corpse is gone.
Task.set_timeout_in_ticks(
1,
corpse_util_mined_entity,
{
entity = entity,
player_index = entity.character_corpse_player_index,
tick = entity.character_corpse_tick_of_death
}
)
end
Event.add(defines.events.on_player_died, player_died)
Event.add(defines.events.on_character_corpse_expired, corpse_expired)
Event.add(defines.events.on_pre_player_mined_item, mined_entity)

View File

@ -1,544 +0,0 @@
local Event = require 'utils.event'
local Map_score = require 'comfy_panel.map_score'
local BiterRolls = require 'modules.wave_defense.biter_rolls'
local unearthing_worm = require 'functions.unearthing_worm'
local unearthing_biters = require 'functions.unearthing_biters'
local Loot = require 'maps.lumberjack.loot'
local Pets = require 'maps.lumberjack.biter_pets'
local tick_tack_trap = require 'functions.tick_tack_trap'
local RPG = require 'maps.lumberjack.rpg'
local Mining = require 'maps.lumberjack.mining'
local Terrain = require 'maps.lumberjack.terrain'
local BiterHealthBooster = require 'modules.biter_health_booster'
-- tables
local WPT = require 'maps.lumberjack.table'
local WD = require 'modules.wave_defense.table'
-- module
local Public = {}
local math_random = math.random
local math_floor = math.floor
local math_abs = math.abs
local grandmaster = '[color=blue]Grandmaster:[/color]'
local treasure_chest_messages = {
"You notice an old crate within the rubble. It's filled with treasure!",
"You find a chest underneath the broken rocks. It's filled with goodies!",
'We has found the precious!'
}
local rare_treasure_chest_messages = {
'Your magic improves. You have found a chest that is filled with rare treasures!',
"Oh wonderful magic. You found a chest underneath the broken rocks. It's filled with rare goodies!",
"You're a wizard Harry! We has found the rare precious!"
}
local disabled_entities = {
'gun-turret',
'laser-turret',
'flamethrower-turret',
'land-mine'
}
local disabled_threats = {
['entity-ghost'] = true,
['raw-fish'] = true
}
local defeated_messages = {
"Oh no, the biters nom'ed the train away!",
"I'm not 100% sure, but - apparently the train was chewed away.",
'You had one objective - defend the train *-*',
"Looks like we're resetting cause you did not defend the train ._.",
'ohgodno-why-must-you-do-this-to-me'
}
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 set_objective_health(entity, final_damage_amount)
local this = WPT.get_table()
if final_damage_amount == 0 then
return
end
this.locomotive_health = math_floor(this.locomotive_health - final_damage_amount)
this.cargo_health = math_floor(this.cargo_health - final_damage_amount)
if this.locomotive_health > this.locomotive_max_health then
this.locomotive_health = this.locomotive_max_health
end
if this.cargo_health > this.cargo_max_health then
this.cargo_health = this.cargo_max_health
end
if this.locomotive_health <= 0 then
Public.loco_died()
end
local m
if entity == this.locomotive then
m = this.locomotive_health / this.locomotive_max_health
entity.health = 1000 * m
elseif entity == this.locomotive_cargo then
m = this.cargo_health / this.cargo_max_health
entity.health = 600 * m
end
rendering.set_text(this.health_text, 'HP: ' .. this.locomotive_health .. ' / ' .. this.locomotive_max_health)
end
local function is_protected(entity)
local this = WPT.get_table()
local map_name = 'lumberjack'
if string.sub(entity.surface.name, 0, #map_name) ~= map_name then
return true
end
local protected = {this.locomotive, this.locomotive_cargo}
for i = 1, #protected do
if protected[i] == entity then
return true
end
end
return false
end
local function protect_train(event)
local this = WPT.get_table()
if event.entity.force.index ~= 1 then
return
end --Player Force
if is_protected(event.entity) then
if event.entity == this.locomotive_cargo or event.entity == this.locomotive then
if event.cause then
if
event.cause.force.index == 2 or event.cause.force.name == 'lumber_defense' or
event.cause.force.name == 'defenders'
then
if this.locomotive_health <= 0 then
goto continue
end
set_objective_health(event.entity, event.final_damage_amount)
end
end
::continue::
end
if not event.entity.valid then
return
end
event.entity.health = event.entity.health + event.final_damage_amount
end
end
local function hidden_biter(entity)
local surface = entity.surface
local h = math_floor(math_abs(entity.position.y))
local m = 1 / Terrain.level_depth
local count = math_floor(math_random(0, h + Terrain.level_depth) * m) + 1
local position = surface.find_non_colliding_position('small-biter', entity.position, 16, 0.5)
if not position then
position = entity.position
end
BiterRolls.wave_defense_set_unit_raffle(h * 0.20)
for _ = 1, count, 1 do
local unit
if math_random(1, 3) == 1 then
unit = surface.create_entity({name = BiterRolls.wave_defense_roll_spitter_name(), position = position})
else
unit = surface.create_entity({name = BiterRolls.wave_defense_roll_biter_name(), position = position})
end
if math_random(1, 64) == 1 then
BiterHealthBooster.add_boss_unit(unit, m * h * 5 + 1, 0.38)
end
end
end
local function hidden_worm(entity)
BiterRolls.wave_defense_set_worm_raffle(math.sqrt(entity.position.x ^ 2 + entity.position.y ^ 2) * 0.20)
entity.surface.create_entity({name = BiterRolls.wave_defense_roll_worm_name(), position = entity.position})
end
local function hidden_biter_pet(event)
if math_random(1, 2048) ~= 1 then
return
end
BiterRolls.wave_defense_set_unit_raffle(math.sqrt(event.entity.position.x ^ 2 + event.entity.position.y ^ 2) * 0.25)
local unit
if math_random(1, 3) == 1 then
unit =
event.entity.surface.create_entity(
{name = BiterRolls.wave_defense_roll_spitter_name(), position = event.entity.position}
)
else
unit =
event.entity.surface.create_entity(
{name = BiterRolls.wave_defense_roll_biter_name(), position = event.entity.position}
)
end
Pets.biter_pets_tame_unit(game.players[event.player_index], unit, true)
end
local function hidden_treasure(event)
local player = game.players[event.player_index]
local rpg_t = RPG.get_table()
local magic = rpg_t[player.index].magic
if math.random(1, 320) ~= 1 then
return
end
if magic > 50 then
player.print(
rare_treasure_chest_messages[math.random(1, #rare_treasure_chest_messages)],
{r = 0.98, g = 0.66, b = 0.22}
)
Loot.add_rare(event.entity.surface, event.entity.position, 'wooden-chest', magic)
return
end
player.print(treasure_chest_messages[math.random(1, #treasure_chest_messages)], {r = 0.98, g = 0.66, b = 0.22})
Loot.add(event.entity.surface, event.entity.position, 'wooden-chest')
end
local function biters_chew_rocks_faster(event)
if event.entity.force.index ~= 3 then
return
end --Neutral Force
if not event.cause then
return
end
if not event.cause.valid then
return
end
if event.cause.force.index ~= 2 then
return
end --Enemy Force
event.entity.health = event.entity.health - event.final_damage_amount * 2.5
end
local function give_coin(player)
player.insert({name = 'coin', count = 1})
end
local function on_player_mined_entity(event)
local this = WPT.get_table()
local entity = event.entity
local player = game.players[event.player_index]
if not player.valid then
return
end
if not entity.valid then
return
end
local map_name = 'lumberjack'
if string.sub(entity.surface.name, 0, #map_name) ~= map_name then
return
end
if disabled_threats[entity.name] then
return
end
Mining.on_player_mined_entity(event)
if entity.type == 'unit' or entity.type == 'unit-spawner' then
if math_random(1, 160) == 1 then
tick_tack_trap(entity.surface, entity.position)
return
end
if math.random(1, 32) == 1 then
hidden_biter(event.entity)
return
end
end
if entity.type ~= 'simple-entity' or entity.type ~= 'tree' then
this.mined_scrap = this.mined_scrap + 1
give_coin(player)
if math.random(1, 32) == 1 then
hidden_biter(event.entity)
return
end
if math.random(1, 512) == 1 then
hidden_worm(event.entity)
return
end
hidden_biter_pet(event)
hidden_treasure(event)
if math_random(1, 160) == 1 then
tick_tack_trap(entity.surface, entity.position)
return
end
end
if entity.force.name ~= 'defenders' then
return
end
local positions = {}
local r = math.ceil(entity.prototype.max_health / 32)
for x = r * -1, r, 1 do
for y = r * -1, r, 1 do
positions[#positions + 1] = {x = entity.position.x + x, y = entity.position.y + y}
end
end
positions = shuffle(positions)
for i = 1, math.ceil(entity.prototype.max_health / 32), 1 do
if not positions[i] then
return
end
if math_random(1, 3) ~= 1 then
unearthing_biters(entity.surface, positions[i], math_random(5, 10))
else
unearthing_worm(entity.surface, positions[i])
end
end
end
local function on_entity_damaged(event)
if not event.entity then
return
end
if not event.entity.valid then
return
end
if not event.entity.health then
return
end
protect_train(event)
biters_chew_rocks_faster(event)
end
local function on_player_repaired_entity(event)
local this = WPT.get_table()
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.locomotive_cargo or entity == this.locomotive then
set_objective_health(entity, -1)
end
end
local function on_entity_died(event)
local this = WPT.get_table()
local entity = event.entity
if not entity.valid then
return
end
local map_name = 'lumberjack'
if string.sub(entity.surface.name, 0, #map_name) ~= map_name then
return
end
if disabled_threats[entity.name] then
return
end
Mining.on_entity_died(event)
if entity.type == 'unit' or entity.type == 'unit-spawner' then
this.biters_killed = this.biters_killed + 1
if math_random(1, 512) == 1 then
tick_tack_trap(entity.surface, entity.position)
return
end
if math.random(1, 32) == 1 then
hidden_biter(event.entity)
return
end
end
if entity.type ~= 'simple-entity' or entity.type ~= 'tree' then
if math.random(1, 32) == 1 then
hidden_biter(event.entity)
return
end
if math.random(1, 512) == 1 then
hidden_worm(event.entity)
return
end
if math_random(1, 512) == 1 then
tick_tack_trap(entity.surface, entity.position)
return
end
end
if entity.force.name ~= 'defenders' then
return
end
local positions = {}
local r = math.ceil(entity.prototype.max_health / 32)
for x = r * -1, r, 1 do
for y = r * -1, r, 1 do
positions[#positions + 1] = {x = entity.position.x + x, y = entity.position.y + y}
end
end
positions = shuffle(positions)
for i = 1, math.ceil(entity.prototype.max_health / 32), 1 do
if not positions[i] then
return
end
if math_random(1, 3) ~= 1 then
unearthing_biters(entity.surface, positions[i], math_random(5, 10))
else
unearthing_worm(entity.surface, positions[i])
end
end
end
local function on_robot_built_entity(event)
local map_name = 'lumberjack'
if string.sub(event.created_entity.surface.name, 0, #map_name) ~= map_name then
return
end
local y = event.created_entity.position.y
local ent = event.created_entity
if y >= 150 then
game.print(grandmaster .. ' I do not approve, ' .. ent.name .. ' was obliterated.', {r = 1, g = 0.5, b = 0.1})
ent.die()
return
else
for _, e in pairs(disabled_entities) do
if e == event.created_entity.name then
if y >= 0 then
ent.active = false
if event.player_index then
game.print(
grandmaster .. " Can't build here. I disabled your " .. ent.name .. '.',
{r = 1, g = 0.5, b = 0.1}
)
return
end
end
end
end
end
end
local function on_built_entity(event)
local map_name = 'lumberjack'
if string.sub(event.created_entity.surface.name, 0, #map_name) ~= map_name then
return
end
local player = game.players[event.player_index]
local y = event.created_entity.position.y
local ent = event.created_entity
if y >= 150 then
player.print(grandmaster .. ' I do not approve, ' .. ent.name .. ' was obliterated.', {r = 1, g = 0.5, b = 0.1})
ent.die()
return
else
for _, e in pairs(disabled_entities) do
if e == event.created_entity.name then
if y >= 0 then
ent.active = false
if event.player_index then
player.print(
grandmaster .. " Can't build here. I disabled your " .. ent.name .. '.',
{r = 1, g = 0.5, b = 0.1}
)
return
end
end
end
end
end
end
function Public.set_scores()
local this = WPT.get_table()
local wagon = this.locomotive_cargo
if not wagon then
return
end
if not wagon.valid then
return
end
local score = math_floor(wagon.position.y * -1)
for _, player in pairs(game.connected_players) do
if score > Map_score.get_score(player) then
Map_score.set_score(player, score)
end
end
end
function Public.loco_died()
local this = WPT.get_table()
local surface = game.surfaces[this.active_surface_index]
local wave_defense_table = WD.get_table()
Public.set_scores()
if not this.locomotive.valid then
wave_defense_table.game_lost = true
wave_defense_table.target = nil
game.print(
grandmaster .. ' ' .. defeated_messages[math.random(1, #defeated_messages)],
{r = 1, g = 0.5, b = 0.1}
)
game.print(grandmaster .. ' Better luck next time.', {r = 1, g = 0.5, b = 0.1})
Public.reset_map()
return
end
this.locomotive_health = 0
this.locomotive.color = {0.49, 0, 255, 1}
rendering.set_text(this.health_text, 'HP: ' .. this.locomotive_health .. ' / ' .. this.locomotive_max_health)
wave_defense_table.game_lost = true
wave_defense_table.target = nil
game.print(grandmaster .. ' ' .. defeated_messages[math.random(1, #defeated_messages)], {r = 1, g = 0.5, b = 0.1})
game.print(grandmaster .. ' Better luck next time.', {r = 1, g = 0.5, b = 0.1})
game.print(grandmaster .. ' Game will soft-reset shortly.', {r = 1, g = 0.5, b = 0.1})
game.forces.enemy.set_friend('player', true)
game.forces.player.set_friend('enemy', true)
local fake_shooter =
surface.create_entity({name = 'character', position = this.locomotive.position, force = 'enemy'})
surface.create_entity(
{
name = 'atomic-rocket',
position = this.locomotive.position,
force = 'enemy',
speed = 1,
max_range = 1200,
target = this.locomotive,
source = fake_shooter
}
)
surface.spill_item_stack(this.locomotive.position, {name = 'coin', count = 512}, false)
surface.spill_item_stack(this.locomotive_cargo.position, {name = 'coin', count = 512}, false)
this.game_reset_tick = game.tick + 1800
for _, player in pairs(game.connected_players) do
player.play_sound {path = 'utility/game_lost', volume_modifier = 0.75}
end
end
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
Event.add(defines.events.on_player_repaired_entity, on_player_repaired_entity)
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
Event.add(defines.events.on_entity_died, on_entity_died)
Event.add(defines.events.on_built_entity, on_built_entity)
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
return Public

View File

@ -1,480 +0,0 @@
local Market = require 'functions.basic_markets'
local Loot = require 'maps.lumberjack.loot'
local Task = require 'utils.task'
local Token = require 'utils.token'
local Event = require 'utils.event'
local insert = table.insert
local tiles_per_tick
local regen_decoratives
local surfaces = {}
local total_calls
local Public = {}
-- Set to false by modules that want to control the on_chunk_generated event themselves.
Public.enable_register_events = true
local function do_tile_inner(tiles, tile, pos)
if type(tile) == 'string' then
insert(tiles, {name = tile, position = pos})
end
end
local function do_tile(y, x, data, shape)
local pos = {x, y}
-- local coords need to be 'centered' to allow for correct rotation and scaling.
local tile = shape(x + 0.5, y + 0.5, data)
if not data.surface.valid then
return
end
if type(tile) == 'table' then
do_tile_inner(data.tiles, tile.tile, pos)
local hidden_tile = tile.hidden_tile
if hidden_tile then
insert(data.hidden_tiles, {tile = hidden_tile, position = pos})
end
local entities = tile.entities
if entities then
for _, entity in ipairs(entities) do
if not entity.position then
entity.position = pos
end
insert(data.entities, entity)
end
end
local decoratives = tile.decoratives
if decoratives then
for _, decorative in ipairs(decoratives) do
insert(data.decoratives, decorative)
end
end
local markets = tile.markets
if markets then
for _, t in ipairs(markets) do
if not t.position then
t.position = pos
end
insert(data.markets, t)
end
end
local treasure = tile.treasure
if treasure then
for _, t in ipairs(treasure) do
if not t.position then
t.position = pos
end
insert(data.treasure, t)
end
end
else
do_tile_inner(data.tiles, tile, pos)
end
end
local function do_row(row, data, shape)
local y = data.top_y + row
local top_x = data.top_x
local tiles = data.tiles
if not data.surface.valid then
return
end
data.y = y
for x = top_x, top_x + 31 do
data.x = x
local pos = {data.x, data.y}
-- local coords need to be 'centered' to allow for correct rotation and scaling.
local tile = shape(x + 0.5, y + 0.5, data)
if type(tile) == 'table' then
do_tile_inner(tiles, tile.tile, pos)
local hidden_tile = tile.hidden_tile
if hidden_tile then
insert(data.hidden_tiles, {tile = hidden_tile, position = pos})
end
local entities = tile.entities
if entities then
for _, entity in ipairs(entities) do
if not entity.position then
entity.position = pos
end
insert(data.entities, entity)
end
end
local decoratives = tile.decoratives
if decoratives then
for _, decorative in ipairs(decoratives) do
if not decorative.position then
decorative.position = pos
end
insert(data.decoratives, decorative)
end
end
local markets = tile.markets
if markets then
for _, t in ipairs(markets) do
if not t.position then
t.position = pos
end
insert(data.markets, t)
end
end
local treasure = tile.treasure
if treasure then
for _, t in ipairs(treasure) do
if not t.position then
t.position = pos
end
insert(data.treasure, t)
end
end
else
do_tile_inner(tiles, tile, pos)
end
end
end
local function do_place_treasure(data)
if not data.surface.valid then
return
end
local surface = data.surface
local treasure = data.treasure
local rnd = math.random
if #treasure == 0 then
return
end
for _, e in ipairs(data.treasure) do
if rnd(1, 6) == 1 then
e.chest = 'iron-chest'
end
Loot.add(surface, e.position, e.chest)
end
end
local function do_place_markets(data)
if not data.surface.valid then
return
end
local markets = data.markets
local surface = data.surface
local rnd = math.random
local abs = math.abs
if #markets == 0 then
return
end
local pos = markets[rnd(1, #markets)]
if
surface.count_entities_filtered {
area = {{pos.x - 96, pos.y - 96}, {pos.x + 96, pos.y + 96}},
name = 'market',
limit = 1
} == 0
then
local market = Market.mountain_market(surface, pos, abs(pos.y) * 0.004)
market.destructible = false
end
end
local function do_place_tiles(data)
if not data.surface.valid then
return
end
data.surface.set_tiles(data.tiles, true)
end
local function do_place_hidden_tiles(data)
if not data.surface.valid then
return
end
local surface = data.surface
for _, t in ipairs(data.hidden_tiles) do
surface.set_hidden_tile(t.position, t.tile)
end
end
local function do_place_decoratives(data)
if not data.surface.valid then
return
end
if regen_decoratives then
data.surface.regenerate_decorative(nil, {{data.top_x / 32, data.top_y / 32}})
end
local dec = data.decoratives
if #dec > 0 then
data.surface.create_decoratives({check_collision = true, decoratives = dec})
end
end
local function do_place_entities(data)
if not data.surface.valid then
return
end
local surface = data.surface
local entity
for _, e in ipairs(data.entities) do
if e.force then
entity = surface.create_entity({name = e.name, position = e.position, force = e.force})
else
entity = surface.create_entity(e)
end
if entity and e.callback then
local callback = Token.get(e.callback)
callback(entity, e.data)
end
end
end
local function run_chart_update(data)
if not data.surface.valid then
return
end
local x = data.top_x / 32
local y = data.top_y / 32
if game.forces.player.is_chunk_charted(data.surface, {x, y}) then
-- Don't use full area, otherwise adjacent chunks get charted
game.forces.player.chart(
data.surface,
{
{data.top_x, data.top_y},
{data.top_x + 1, data.top_y + 1}
}
)
end
end
local function map_gen_action(data)
local state = data.y
if state < 32 then
if not data.surface.valid then
return
end
local shape = surfaces[data.surface.name]
if shape == nil then
return false
end
local count = tiles_per_tick
local y = state + data.top_y
local x = data.x
local max_x = data.top_x + 32
data.y = y
repeat
count = count - 1
do_tile(y, x, data, shape)
x = x + 1
if x == max_x then
y = y + 1
if y == data.top_y + 32 then
break
end
x = data.top_x
data.y = y
end
data.x = x
until count == 0
data.y = y - data.top_y
return true
elseif state == 32 then
do_place_tiles(data)
data.y = 33
return true
elseif state == 33 then
do_place_hidden_tiles(data)
data.y = 34
return true
elseif state == 34 then
do_place_entities(data)
data.y = 35
return true
elseif state == 35 then
do_place_markets(data)
data.y = 36
return true
elseif state == 36 then
do_place_treasure(data)
data.y = 37
return true
elseif state == 37 then
do_place_decoratives(data)
data.y = 38
return true
elseif state == 38 then
run_chart_update(data)
return false
end
end
local map_gen_action_token = Token.register(map_gen_action)
--- Adds generation of a Chunk of the map to the queue
-- @param event <table> the event table from on_chunk_generated
function Public.schedule_chunk(event)
local surface = event.surface
local shape = surfaces[surface.name]
if not surface.valid then
return
end
if not shape then
return
end
local area = event.area
local data = {
y = 0,
x = area.left_top.x,
area = area,
top_x = area.left_top.x,
top_y = area.left_top.y,
surface = surface,
tiles = {},
hidden_tiles = {},
entities = {},
decoratives = {},
markets = {},
treasure = {}
}
if not data.surface.valid then
return
end
Task.queue_task(map_gen_action_token, data, total_calls)
end
--- Generates a Chunk of map when called
-- @param event <table> the event table from on_chunk_generated
function Public.do_chunk(event)
local surface = event.surface
local shape = surfaces[surface.name]
if not surface.valid then
return
end
if not shape then
return
end
local area = event.area
local data = {
area = area,
top_x = area.left_top.x,
top_y = area.left_top.y,
surface = surface,
tiles = {},
hidden_tiles = {},
entities = {},
decoratives = {},
markets = {},
treasure = {}
}
if not data.surface.valid then
return
end
for row = 0, 31 do
do_row(row, data, shape)
end
do_place_tiles(data)
do_place_hidden_tiles(data)
do_place_entities(data)
do_place_decoratives(data)
do_place_markets(data)
do_place_treasure(data)
end
--- Sets the variables for the generate functions, should only be called from map_loader
-- @param args <table>
function Public.init(args)
tiles_per_tick = args.tiles_per_tick or 32
regen_decoratives = args.regen_decoratives or false
for surface_name, shape in pairs(args.surfaces or {}) do
surfaces[surface_name] = shape
end
total_calls = math.ceil(1024 / tiles_per_tick) + 5
end
local do_chunk = Public.do_chunk
local schedule_chunk = Public.schedule_chunk
local function on_chunk(event)
if event.tick == 0 then
do_chunk(event)
else
schedule_chunk(event)
end
end
--- Registers the event to generate our map when Chunks are generated, should only be called from map_loader
function Public.register()
if not Public.enable_register_events then
return
end
if _DEBUG then
Event.add(defines.events.on_chunk_generated, do_chunk)
else
Event.add(defines.events.on_chunk_generated, on_chunk)
end
end
--- Returns the surfaces that the generate functions will act on
-- Warning! Changing this table after on_init or on_load has run will cause desyncs!
-- @return dictionary of surface_name -> shape function
function Public.get_surfaces()
if _LIFECYCLE == 8 then
error('Calling Generate.get_surfaces after on_init() or on_load() has run is a desync risk.', 2)
end
return surfaces
end
return Public

View File

@ -1,83 +0,0 @@
local RPG = require 'maps.lumberjack.rpg'
local WPT = require 'maps.lumberjack.table'
local floor = math.floor
local format_number = require 'util'.format_number
local function create_gui(player)
local label
local line
local frame = player.gui.top.add({type = 'frame', name = 'lumberjack'})
frame.style.minimal_height = 38
frame.style.maximal_height = 38
label = frame.add({type = 'label', caption = ' ', name = 'label'})
label.style.font_color = {r = 0.88, g = 0.88, b = 0.88}
label.style.font = 'default-bold'
label.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
label = frame.add({type = 'label', caption = ' ', name = 'global_pool'})
label.style.font_color = {r = 0.88, g = 0.88, b = 0.88}
label.style.font = 'default-bold'
label.style.right_padding = 4
label.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
line = frame.add({type = 'line', direction = 'vertical'})
line.style.left_padding = 4
line.style.right_padding = 4
label = frame.add({type = 'label', caption = ' ', name = 'scrap_mined'})
label.style.font_color = {r = 0.88, g = 0.88, b = 0.88}
label.style.font = 'default-bold'
label.style.right_padding = 4
label.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
line = frame.add({type = 'line', direction = 'vertical'})
line.style.left_padding = 4
line.style.right_padding = 4
label = frame.add({type = 'label', caption = ' ', name = 'biters_killed'})
label.style.font_color = {r = 0.88, g = 0.88, b = 0.88}
label.style.font = 'default-bold'
label.style.right_padding = 4
label.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
line = frame.add({type = 'line', direction = 'vertical'})
line.style.left_padding = 4
line.style.right_padding = 4
label = frame.add({type = 'label', caption = ' ', name = 'train_upgrades'})
label.style.font_color = {r = 0.88, g = 0.88, b = 0.88}
label.style.font = 'default-bold'
label.style.right_padding = 4
label.style.font_color = {r = 0.33, g = 0.66, b = 0.9}
end
local function update_gui(player)
local rpg = RPG.get_table()
local st = WPT.get_table()
if not player.gui.top.lumberjack then
create_gui(player)
end
local gui = player.gui.top.lumberjack
if rpg.global_pool == 0 then
gui.global_pool.caption = 'XP: 0'
gui.global_pool.tooltip = 'Dig, handcraft or run to increase the pool!'
elseif rpg.global_pool > 0 then
gui.global_pool.caption = 'XP: ' .. format_number(floor(rpg.global_pool), true)
gui.global_pool.tooltip = 'Get this number over 5k to get some of this mad XP! \\o/'
end
gui.scrap_mined.caption = ' [img=entity.tree-01][img=entity.rock-huge]: ' .. format_number(st.mined_scrap, true)
gui.scrap_mined.tooltip = 'Amount of trees/rocks harvested.'
gui.biters_killed.caption = ' [img=entity.small-biter]: ' .. format_number(st.biters_killed, true)
gui.biters_killed.tooltip = 'Amount of biters killed.'
gui.train_upgrades.caption = ' [img=entity.locomotive]: ' .. format_number(st.train_upgrades, true)
gui.train_upgrades.tooltip = 'Amount of train upgrades.'
end
return update_gui

View File

@ -1,17 +0,0 @@
local Public = {}
Public.wagon_types = {
["cargo-wagon"] = true,
["artillery-wagon"] = true,
["fluid-wagon"] = true,
["locomotive"] = true,
}
Public.wagon_areas = {
["cargo-wagon"] = {left_top = {x = -20, y = 0}, right_bottom = {x = 20, y = 60}},
["artillery-wagon"] = {left_top = {x = -20, y = 0}, right_bottom = {x = 20, y = 60}},
["fluid-wagon"] = {left_top = {x = -20, y = 0}, right_bottom = {x = 20, y = 60}},
["locomotive"] = {left_top = {x = -20, y = 0}, right_bottom = {x = 20, y = 60}},
}
return Public

View File

@ -1,758 +0,0 @@
local Public = {}
local Constants = require 'maps.lumberjack.icw.constants'
local table_insert = table.insert
local table_remove = table.remove
local math_round = math.round
local math_random = math.random
function Public.request_reconstruction(icw)
icw.rebuild_tick = game.tick + 30
end
local function delete_empty_surfaces(icw)
for k, surface in pairs(icw.surfaces) do
if not icw.trains[tonumber(surface.name)] then
game.delete_surface(surface)
table_remove(icw.surfaces, k)
end
end
end
local function kick_players_out_of_vehicles(wagon)
for _, player in pairs(game.connected_players) do
local character = player.character
if character and character.valid and character.driving then
if wagon.surface == player.surface then
character.driving = false
end
end
end
end
local function connect_power_pole(entity, wagon_area_left_top_y)
local surface = entity.surface
local max_wire_distance = entity.prototype.max_wire_distance
local area = {
{entity.position.x - max_wire_distance, entity.position.y - max_wire_distance},
{entity.position.x + max_wire_distance, entity.position.y - 1}
}
for _, pole in pairs(surface.find_entities_filtered({area = area, name = entity.name})) do
if pole.position.y < wagon_area_left_top_y then
entity.connect_neighbour(pole)
return
end
end
end
local function equal_fluid(source_tank, target_tank)
if not source_tank.valid then
return
end
if not target_tank.valid then
return
end
local source_fluid = source_tank.fluidbox[1]
if not source_fluid then
return
end
local target_fluid = target_tank.fluidbox[1]
local source_fluid_amount = source_fluid.amount
local amount
if target_fluid then
amount = source_fluid_amount - ((target_fluid.amount + source_fluid_amount) * 0.5)
else
amount = source_fluid.amount * 0.5
end
if amount <= 0 then
return
end
local inserted_amount =
target_tank.insert_fluid({name = source_fluid.name, amount = amount, temperature = source_fluid.temperature})
if inserted_amount > 0 then
source_tank.remove_fluid({name = source_fluid.name, amount = inserted_amount})
end
end
local function divide_fluid(wagon, storage_tank)
local fluid_wagon = wagon.entity
equal_fluid(fluid_wagon, storage_tank)
equal_fluid(storage_tank, fluid_wagon)
end
local function input_filtered(wagon_inventory, chest, chest_inventory, free_slots)
local request_stacks = {}
local prototypes = game.item_prototypes
for slot_index = 1, 4, 1 do
local stack = chest.get_request_slot(slot_index)
if stack then
request_stacks[stack.name] = 10 * prototypes[stack.name].stack_size
end
end
for i = 1, wagon_inventory.get_bar() - 1, 1 do
if free_slots <= 0 then
return
end
local stack = wagon_inventory[i]
if stack.valid_for_read then
local request_stack = request_stacks[stack.name]
if request_stack and request_stack > chest_inventory.get_item_count(stack.name) then
chest_inventory.insert(stack)
stack.clear()
free_slots = free_slots - 1
end
end
end
end
local function input_cargo(wagon, chest)
if not chest.request_from_buffers then
return
end
local wagon_entity = wagon.entity
if not wagon_entity.valid then
wagon.transfer_entities = nil
return
end
local wagon_inventory = wagon_entity.get_inventory(defines.inventory.cargo_wagon)
if wagon_inventory.is_empty() then
return
end
local chest_inventory = chest.get_inventory(defines.inventory.chest)
local free_slots = 0
for i = 1, chest_inventory.get_bar() - 1, 1 do
if not chest_inventory[i].valid_for_read then
free_slots = free_slots + 1
end
end
if chest.get_request_slot(1) then
input_filtered(wagon_inventory, chest, chest_inventory, free_slots)
return
end
for i = 1, wagon_inventory.get_bar() - 1, 1 do
if free_slots <= 0 then
return
end
if wagon_inventory[i].valid_for_read then
chest_inventory.insert(wagon_inventory[i])
wagon_inventory[i].clear()
free_slots = free_slots - 1
end
end
end
local function output_cargo(wagon, passive_chest)
local passive_chest_inventory = passive_chest.get_inventory(defines.inventory.cargo_wagon)
if passive_chest_inventory.is_empty() then
return
end
local wagon_inventory = wagon.entity.get_inventory(defines.inventory.cargo_wagon)
local free_slots = 0
for i = 1, wagon_inventory.get_bar() - 1, 1 do
if not wagon_inventory[i].valid_for_read and not wagon_inventory.get_filter(i) then
free_slots = free_slots + 1
end
end
for i = 1, passive_chest_inventory.get_bar() - 1, 1 do
if free_slots <= 0 then
return
end
if passive_chest_inventory[i].valid_for_read then
wagon_inventory.insert(passive_chest_inventory[i])
passive_chest_inventory[i].clear()
free_slots = free_slots - 1
end
end
end
local transfer_functions = {
['storage-tank'] = divide_fluid,
['logistic-chest-requester'] = input_cargo,
['logistic-chest-passive-provider'] = output_cargo
}
local function get_wagon_for_entity(icw, entity)
local train = icw.trains[tonumber(entity.surface.name)]
if not train then
return
end
local position = entity.position
for k, unit_number in pairs(train.wagons) do
local wagon = icw.wagons[unit_number]
if wagon then
local left_top = wagon.area.left_top
local right_bottom = wagon.area.right_bottom
if
position.x >= left_top.x and position.y >= left_top.y and position.x <= right_bottom.x and
position.y <= right_bottom.y
then
return wagon
end
end
end
return false
end
local function kill_wagon_doors(icw, wagon)
for k, e in pairs(wagon.doors) do
icw.doors[e.unit_number] = nil
e.destroy()
wagon.doors[k] = nil
end
end
local function construct_wagon_doors(icw, wagon)
local area = wagon.area
local surface = wagon.surface
for _, x in pairs({area.left_top.x - 0.55, area.right_bottom.x + 0.55}) do
local e =
surface.create_entity(
{
name = 'car',
position = {x, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)},
force = 'neutral',
create_build_effect_smoke = false
}
)
e.get_inventory(defines.inventory.fuel).insert({name = 'wood', count = 1})
e.destructible = false
e.minable = false
e.operable = false
icw.doors[e.unit_number] = wagon.entity.unit_number
table_insert(wagon.doors, e)
end
end
local function get_player_data(icw, player)
local player_data = icw.players[player.index]
if icw.players[player.index] then
return player_data
end
icw.players[player.index] = {
surface = 1,
fallback_surface = 1,
zoom = 0.30,
map_size = 360
}
return icw.players[player.index]
end
function Public.kill_minimap(player)
local element = player.gui.left.icw_map
if element then
element.destroy()
end
end
function Public.kill_wagon(icw, entity)
if not Constants.wagon_types[entity.type] then
return
end
local wagon = icw.wagons[entity.unit_number]
local surface = wagon.surface
kick_players_out_of_vehicles(wagon)
kill_wagon_doors(icw, wagon)
for _, e in pairs(surface.find_entities_filtered({area = wagon.area})) do
if e.name == 'character' and e.player then
local p = wagon.entity.surface.find_non_colliding_position('character', wagon.entity.position, 128, 0.5)
if p then
e.player.teleport(p, wagon.entity.surface)
else
e.player.teleport(wagon.entity.position, wagon.entity.surface)
end
Public.kill_minimap(e.player)
else
e.die()
end
end
for _, tile in pairs(surface.find_tiles_filtered({area = wagon.area})) do
surface.set_tiles({{name = 'out-of-map', position = tile.position}}, true)
end
wagon.entity.force.chart(surface, wagon.area)
icw.wagons[entity.unit_number] = nil
Public.request_reconstruction(icw)
end
function Public.create_room_surface(icw, unit_number)
if game.surfaces[tostring(unit_number)] then
return game.surfaces[tostring(unit_number)]
end
local map_gen_settings = {
['width'] = 2,
['height'] = 2,
['water'] = 0,
['starting_area'] = 1,
['cliff_settings'] = {cliff_elevation_interval = 0, cliff_elevation_0 = 0},
['default_enable_all_autoplace_controls'] = true,
['autoplace_settings'] = {
['entity'] = {treat_missing_as_default = false},
['tile'] = {treat_missing_as_default = true},
['decorative'] = {treat_missing_as_default = false}
}
}
local surface = game.create_surface(unit_number, map_gen_settings)
surface.freeze_daytime = true
surface.daytime = 0.1
surface.request_to_generate_chunks({16, 16}, 2)
surface.force_generate_chunk_requests()
for _, tile in pairs(surface.find_tiles_filtered({area = {{-2, -2}, {2, 2}}})) do
surface.set_tiles({{name = 'out-of-map', position = tile.position}}, true)
end
table_insert(icw.surfaces, surface)
return surface
end
function Public.create_wagon_room(icw, wagon)
local surface = wagon.surface
local area = wagon.area
local main_tile_name = 'tutorial-grid'
if wagon.entity.type == 'locomotive' then
main_tile_name = 'black-refined-concrete'
end
local tiles = {}
for x = -3, 2, 1 do
table_insert(tiles, {name = 'hazard-concrete-right', position = {x, area.left_top.y}})
table_insert(tiles, {name = 'hazard-concrete-right', position = {x, area.right_bottom.y - 1}})
end
for x = area.left_top.x, area.right_bottom.x - 1, 1 do
for y = area.left_top.y + 2, area.right_bottom.y - 3, 1 do
table_insert(tiles, {name = main_tile_name, position = {x, y}})
end
end
for x = -3, 2, 1 do
for y = 1, 3, 1 do
table_insert(tiles, {name = main_tile_name, position = {x, y}})
end
for y = area.right_bottom.y - 4, area.right_bottom.y - 2, 1 do
table_insert(tiles, {name = main_tile_name, position = {x, y}})
end
end
local fishes = {}
if wagon.entity.type == 'locomotive' then
for x = -3, 2, 1 do
for y = 10, 12, 1 do
table_insert(tiles, {name = 'water', position = {x, y}})
table_insert(fishes, {name = 'fish', position = {x, y}})
end
end
end
surface.set_tiles(tiles, true)
for _, fish in pairs(fishes) do
surface.create_entity(fish)
end
construct_wagon_doors(icw, wagon)
if wagon.entity.type == 'fluid-wagon' then
local height = area.right_bottom.y - area.left_top.y
local positions = {
{area.right_bottom.x, area.left_top.y + height * 0.25},
{area.right_bottom.x, area.left_top.y + height * 0.75},
{area.left_top.x - 1, area.left_top.y + height * 0.25},
{area.left_top.x - 1, area.left_top.y + height * 0.75}
}
table.shuffle_table(positions)
local e =
surface.create_entity(
{
name = 'storage-tank',
position = positions[1],
force = 'neutral',
create_build_effect_smoke = false
}
)
e.destructible = false
e.minable = false
wagon.transfer_entities = {e}
return
end
if wagon.entity.type == 'cargo-wagon' then
local vectors = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}}
local v = vectors[math_random(1, 4)]
local position = {
math_random(area.left_top.x + 4, area.right_bottom.x - 4),
math_random(area.left_top.y + 6, area.right_bottom.y - 6)
}
local e =
surface.create_entity(
{
name = 'logistic-chest-requester',
position = position,
force = 'neutral',
create_build_effect_smoke = false
}
)
e.destructible = false
e.minable = false
local e2 =
surface.create_entity(
{
name = 'logistic-chest-passive-provider',
position = {position[1] + v[1], position[2] + v[2]},
force = 'neutral',
create_build_effect_smoke = false
}
)
e2.destructible = false
e2.minable = false
wagon.transfer_entities = {e, e2}
return
end
end
function Public.create_wagon(icw, created_entity, delay_surface)
if not created_entity.unit_number then
return
end
if icw.trains[tonumber(created_entity.surface.name)] or icw.wagons[tonumber(created_entity.surface.name)] then
return
end
if not Constants.wagon_types[created_entity.type] then
return
end
local wagon_area = Constants.wagon_areas[created_entity.type]
icw.wagons[created_entity.unit_number] = {
entity = created_entity,
area = {
left_top = {x = wagon_area.left_top.x, y = wagon_area.left_top.y},
right_bottom = {x = wagon_area.right_bottom.x, y = wagon_area.right_bottom.y}
},
doors = {},
entity_count = 0
}
local wagon = icw.wagons[created_entity.unit_number]
if not delay_surface then
wagon.surface = Public.create_room_surface(icw, created_entity.unit_number)
Public.create_wagon_room(icw, icw.wagons[created_entity.unit_number])
end
Public.request_reconstruction(icw)
return wagon
end
function Public.add_wagon_entity_count(icw, added_entity)
local wagon = get_wagon_for_entity(icw, added_entity)
if not wagon then
return
end
wagon.entity_count = wagon.entity_count + 1
wagon.entity.minable = false
end
function Public.subtract_wagon_entity_count(icw, removed_entity)
local wagon = get_wagon_for_entity(icw, removed_entity)
if not wagon then
return
end
wagon.entity_count = wagon.entity_count - 1
if wagon.entity_count > 0 then
return
end
wagon.entity.minable = true
end
function Public.use_cargo_wagon_door(icw, player, door)
local player_data = get_player_data(icw, player)
if player_data.state then
player_data.state = player_data.state - 1
if player_data.state == 0 then
player_data.state = nil
end
return
end
if not door then
return
end
if not door.valid then
return
end
local doors = icw.doors
local wagons = icw.wagons
local wagon = false
if doors[door.unit_number] then
wagon = wagons[doors[door.unit_number]]
end
if wagons[door.unit_number] then
wagon = wagons[door.unit_number]
end
if not wagon then
return
end
player_data.fallback_surface = wagon.entity.surface.index
player_data.fallback_position = {wagon.entity.position.x, wagon.entity.position.y}
if wagon.entity.surface.name ~= player.surface.name then
local surface = wagon.entity.surface
local x_vector = (door.position.x / math.abs(door.position.x)) * 2
local position = {wagon.entity.position.x + x_vector, wagon.entity.position.y}
local position = surface.find_non_colliding_position('character', position, 128, 0.5)
if not position then
return
end
if wagon.entity.type == 'locomotive' then
player.teleport(position, surface)
player_data.state = 2
player.driving = true
Public.kill_minimap(player)
else
player.teleport(position, surface)
Public.kill_minimap(player)
end
player_data.surface = surface.index
else
local surface = wagon.surface
local area = wagon.area
local x_vector = door.position.x - player.position.x
local position
if x_vector > 0 then
position = {area.left_top.x + 0.5, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)}
else
position = {area.right_bottom.x - 0.5, area.left_top.y + ((area.right_bottom.y - area.left_top.y) * 0.5)}
end
local p = surface.find_non_colliding_position('character', position, 128, 0.5)
if p then
player.teleport(p, surface)
else
player.teleport(position, surface)
end
player_data.surface = surface.index
end
end
local function move_room_to_train(icw, train, wagon)
if not wagon then
return
end
table_insert(train.wagons, wagon.entity.unit_number)
local destination_area = {
left_top = {x = wagon.area.left_top.x, y = train.top_y},
right_bottom = {
x = wagon.area.right_bottom.x,
y = train.top_y + (wagon.area.right_bottom.y - wagon.area.left_top.y)
}
}
train.top_y = destination_area.right_bottom.y
if
destination_area.left_top.x == wagon.area.left_top.x and destination_area.left_top.y == wagon.area.left_top.y and
wagon.surface.name == train.surface.name
then
return
end
kick_players_out_of_vehicles(wagon)
local player_positions = {}
for _, e in pairs(wagon.surface.find_entities_filtered({name = 'character', area = wagon.area})) do
local player = e.player
if player then
player_positions[player.index] = {
player.position.x,
player.position.y + (destination_area.left_top.y - wagon.area.left_top.y)
}
player.teleport({0, 0}, game.surfaces.nauvis)
end
end
kill_wagon_doors(icw, wagon)
wagon.surface.clone_area(
{
source_area = wagon.area,
destination_area = destination_area,
destination_surface = train.surface,
clone_tiles = true,
clone_entities = true,
clone_decoratives = true,
clear_destination_entities = true,
clear_destination_decoratives = true,
expand_map = true
}
)
for player_index, position in pairs(player_positions) do
local player = game.players[player_index]
player.teleport(position, train.surface)
end
for _, tile in pairs(wagon.surface.find_tiles_filtered({area = wagon.area})) do
wagon.surface.set_tiles({{name = 'out-of-map', position = tile.position}}, true)
end
wagon.entity.force.chart(wagon.surface, wagon.area)
wagon.surface = train.surface
wagon.area = destination_area
wagon.transfer_entities = {}
construct_wagon_doors(icw, wagon)
local left_top_y = wagon.area.left_top.y
for _, e in pairs(wagon.surface.find_entities_filtered({type = 'electric-pole', area = wagon.area})) do
connect_power_pole(e, left_top_y)
end
for _, e in pairs(wagon.surface.find_entities_filtered({area = wagon.area, force = 'neutral'})) do
if transfer_functions[e.name] then
table_insert(wagon.transfer_entities, e)
end
end
end
function Public.construct_train(icw, carriages)
local unit_number = carriages[1].unit_number
if icw.trains[unit_number] then
return
end
local train = {surface = Public.create_room_surface(icw, unit_number), wagons = {}, top_y = 0}
icw.trains[unit_number] = train
for k, carriage in pairs(carriages) do
move_room_to_train(icw, train, icw.wagons[carriage.unit_number])
end
end
function Public.reconstruct_all_trains(icw)
icw.trains = {}
for unit_number, wagon in pairs(icw.wagons) do
if not wagon.entity or not wagon.entity.valid then
icw.wagons[unit_number] = nil
Public.request_reconstruction(icw)
return
end
if not wagon.surface then
wagon.surface = Public.create_room_surface(icw, unit_number)
Public.create_wagon_room(icw, wagon)
end
local carriages = wagon.entity.train.carriages
Public.construct_train(icw, carriages)
end
delete_empty_surfaces(icw)
end
function Public.item_transfer(icw)
for _, wagon in pairs(icw.wagons) do
if not wagon and not wagon.valid then
return
end
if wagon.transfer_entities then
if not wagon and not wagon.valid then
return
end
for k, e in pairs(wagon.transfer_entities) do
transfer_functions[e.name](wagon, e)
end
end
end
end
function Public.draw_minimap(icw, player, surface, position)
local element = player.gui.left.icw_map
if not element then
local player_data = get_player_data(icw, player)
element =
player.gui.left.add(
{
type = 'camera',
name = 'icw_map',
position = position,
surface_index = surface.index,
zoom = player_data.zoom,
tooltip = 'LMB: Increase zoom level.\nRMB: Decrease zoom level.\nMMB: Toggle camera size.'
}
)
element.style.margin = 1
element.style.minimal_height = player_data.map_size
element.style.minimal_width = player_data.map_size
return
end
element.position = position
end
function Public.update_minimap(icw)
for k, player in pairs(game.connected_players) do
if player.character and player.character.valid then
local wagon = get_wagon_for_entity(icw, player.character)
if wagon then
Public.draw_minimap(icw, player, wagon.entity.surface, wagon.entity.position)
end
end
end
end
function Public.toggle_minimap(icw, event)
local element = event.element
if not element then
return
end
if not element.valid then
return
end
if element.name ~= 'icw_map' then
return
end
local player = game.players[event.player_index]
local player_data = get_player_data(icw, player)
if event.button == defines.mouse_button_type.right then
player_data.zoom = player_data.zoom - 0.07
if player_data.zoom < 0.07 then
player_data.zoom = 0.07
end
element.zoom = player_data.zoom
return
end
if event.button == defines.mouse_button_type.left then
player_data.zoom = player_data.zoom + 0.07
if player_data.zoom > 2 then
player_data.zoom = 2
end
element.zoom = player_data.zoom
return
end
if event.button == defines.mouse_button_type.middle then
player_data.map_size = player_data.map_size + 50
if player_data.map_size > 650 then
player_data.map_size = 250
end
element.style.minimal_height = player_data.map_size
element.style.minimal_width = player_data.map_size
element.style.maximal_height = player_data.map_size
element.style.maximal_width = player_data.map_size
return
end
end
return Public

View File

@ -1,192 +0,0 @@
local Global = require 'utils.global'
local Event = require 'utils.event'
local Functions = require 'maps.lumberjack.icw.functions'
local Constants = require 'maps.lumberjack.icw.constants'
local Public = {}
local math_round = math.round
local icw = {}
Global.register(
icw,
function(tbl)
icw = tbl
end
)
function Public.reset()
if icw.surfaces then
for k, surface in pairs(icw.surfaces) do
if surface and surface.valid then
game.delete_surface(surface)
end
end
end
for k, v in pairs(icw) do
icw[k] = nil
end
icw.doors = {}
icw.wagons = {}
icw.trains = {}
icw.players = {}
icw.surfaces = {}
end
local function on_entity_died(event)
local entity = event.entity
if not entity and not entity.valid then
return
end
if not Constants.wagon_types[entity.type] then
return
end
Functions.subtract_wagon_entity_count(icw, entity)
Functions.kill_wagon(icw, entity)
end
local function on_player_mined_entity(event)
local entity = event.entity
if not entity and not entity.valid then
return
end
Functions.subtract_wagon_entity_count(icw, entity)
Functions.kill_wagon(icw, entity)
end
local function on_robot_mined_entity(event)
local entity = event.entity
if not entity and not entity.valid then
return
end
Functions.subtract_wagon_entity_count(icw, entity)
Functions.kill_wagon(icw, entity)
end
local function on_built_entity(event)
local created_entity = event.created_entity
Functions.create_wagon(icw, created_entity)
Functions.add_wagon_entity_count(icw, created_entity)
end
local function on_robot_built_entity(event)
local created_entity = event.created_entity
Functions.create_wagon(icw, created_entity)
Functions.add_wagon_entity_count(icw, created_entity)
end
local function on_player_driving_changed_state(event)
local player = game.players[event.player_index]
Functions.use_cargo_wagon_door(icw, player, event.entity)
end
--[[
local function on_player_created(event)
local player = game.players[event.player_index]
player.insert({name = "cargo-wagon", count = 5})
player.insert({name = "artillery-wagon", count = 5})
player.insert({name = "fluid-wagon", count = 5})
player.insert({name = "locomotive", count = 5})
player.insert({name = "rail", count = 100})
end
]]
local function on_gui_closed(event)
local entity = event.entity
if not entity then
return
end
if not entity.valid then
return
end
if not entity.unit_number then
return
end
if not icw.wagons[entity.unit_number] then
return
end
Functions.kill_minimap(game.players[event.player_index])
end
local function on_gui_opened(event)
local entity = event.entity
if not entity then
return
end
if not entity.valid then
return
end
if not entity.unit_number then
return
end
local wagon = icw.wagons[entity.unit_number]
if not wagon then
return
end
Functions.draw_minimap(
icw,
game.players[event.player_index],
wagon.surface,
{
wagon.area.left_top.x + (wagon.area.right_bottom.x - wagon.area.left_top.x) * 0.5,
wagon.area.left_top.y + (wagon.area.right_bottom.y - wagon.area.left_top.y) * 0.5
}
)
end
local function on_player_died(event)
Functions.kill_minimap(game.players[event.player_index])
end
local function on_train_created(event)
Functions.request_reconstruction(icw)
end
local function on_gui_click(event)
Functions.toggle_minimap(icw, event)
end
local function on_tick()
local tick = game.tick
if tick % 60 == 0 then
Functions.item_transfer(icw)
end
if tick % 240 == 0 then
Functions.update_minimap(icw)
end
if not icw.rebuild_tick then
return
end
if icw.rebuild_tick ~= tick then
return
end
Functions.reconstruct_all_trains(icw)
icw.rebuild_tick = nil
end
local function on_init()
Public.reset()
end
function Public.get_table()
return icw
end
function Public.register_wagon(wagon_entity)
return Functions.create_wagon(icw, wagon_entity)
end
Event.on_init(on_init)
Event.add(defines.events.on_tick, on_tick)
Event.add(defines.events.on_player_driving_changed_state, on_player_driving_changed_state)
Event.add(defines.events.on_entity_died, on_entity_died)
Event.add(defines.events.on_built_entity, on_built_entity)
Event.add(defines.events.on_train_created, on_train_created)
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
Event.add(defines.events.on_player_died, on_player_died)
--Event.add(defines.events.on_player_created, on_player_created)
Event.add(defines.events.on_gui_click, on_gui_click)
Event.add(defines.events.on_gui_closed, on_gui_closed)
Event.add(defines.events.on_gui_opened, on_gui_opened)
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
Event.add(defines.events.on_robot_mined_entity, on_robot_mined_entity)
return Public

View File

@ -1,642 +0,0 @@
local Event = require 'utils.event'
local Power = require 'maps.lumberjack.power'
local ICW = require 'maps.lumberjack.icw.main'
local WPT = require 'maps.lumberjack.table'
local RPG = require 'maps.lumberjack.rpg'
require 'maps.lumberjack.locomotive_market'
local Public = {}
local energy_upgrade = 50000000
local function validate_player(player)
if not player then
return false
end
if not player.valid then
return false
end
if not player.character then
return false
end
if not player.connected then
return false
end
if not game.players[player.index] then
return false
end
return true
end
local function rebuild_energy_overworld(data)
local this = data.this
local surface = data.surface
if this.ow_energy then
if this.ow_energy.valid then
local position = this.ow_energy.position
local area = {
left_top = {x = position.x - 2, y = position.y - 2},
right_bottom = {x = position.x + 2, y = position.y + 2}
}
if Public.contains_positions(this.locomotive.position, area) then
return
end
this.old_ow_energy = this.ow_energy.energy
this.ow_energy.destroy()
this.energy['lumberjack'] = nil
end
end
this.ow_energy =
surface.create_entity {
name = 'hidden-electric-energy-interface',
position = {
x = this.locomotive.position.x,
y = this.locomotive.position.y + 2
},
create_build_effect_smoke = false,
force = game.forces.enemy
}
this.ow_energy.destructible = false
this.ow_energy.minable = false
this.ow_energy.operable = false
this.ow_energy.power_production = 0
if this.energy_purchased then
this.ow_energy.electric_buffer_size = energy_upgrade
else
this.ow_energy.electric_buffer_size = 10000000
end
if this.old_ow_energy then
this.ow_energy.energy = this.old_ow_energy
end
end
local function rebuild_energy_loco(data, rebuild)
local this = data.this
local surface = data.surface
local pos = {x = -19, y = 3}
if rebuild then
local radius = 1024
local area = {{x = -radius, y = -radius}, {x = radius, y = radius}}
for _, entity in pairs(surface.find_entities_filtered {area = area, name = 'electric-energy-interface'}) do
entity.destroy()
end
this.energy.loco = nil
this.lo_energy = nil
end
this.lo_energy =
surface.create_entity {
name = 'electric-energy-interface',
position = pos,
create_build_effect_smoke = false,
force = game.forces.enemy
}
rendering.draw_text {
text = 'Power to overworld',
surface = surface,
target = this.lo_energy,
target_offset = {0, -1.5},
color = {r = 0, g = 1, b = 0},
alignment = 'center'
}
this.lo_energy.minable = false
this.lo_energy.destructible = false
this.lo_energy.operable = false
this.lo_energy.power_production = 0
if this.energy_purchased then
this.lo_energy.electric_buffer_size = energy_upgrade
else
this.lo_energy.electric_buffer_size = 10000000
end
end
local function property_boost(data)
local rng = math.random
local xp_floating_text_color = {r = rng(0, 250), g = 128, b = 0}
local visuals_delay = 1800
local this = data.this
local aura = this.locomotive_xp_aura
local rpg = data.rpg
local loco = this.locomotive.position
local area = {
left_top = {x = loco.x - aura, y = loco.y - aura},
right_bottom = {x = loco.x + aura, y = loco.y + aura}
}
for _, player in pairs(game.connected_players) do
if not validate_player(player) then
return
end
if Public.contains_positions(player.position, area) then
local pos = player.position
RPG.gain_xp(player, 0.4 * (rpg[player.index].bonus + this.xp_points))
player.create_local_flying_text {
text = '+' .. '',
position = {x = pos.x, y = pos.y - 2},
color = xp_floating_text_color,
time_to_live = 60,
speed = 3
}
rpg[player.index].xp_since_last_floaty_text = 0
rpg[player.index].last_floaty_text = game.tick + visuals_delay
end
end
end
local function train_rainbow()
local this = WPT.get_table()
if not this.locomotive then
return
end
if not this.locomotive.valid then
return
end
local color = {
a = math.sin((game.tick + 60) / 784) * 127 + 127,
r = math.sin((game.tick + 120) / 1700) * 127 + 127,
b = math.sin((game.tick + 600 + 440) / 1800) * 127 + 127,
g = math.sin((game.tick + 1200 + 770) / 1900) * 127 + 127
}
this.locomotive.color = color
rendering.set_text(this.health_text, 'HP: ' .. this.locomotive_health .. ' / ' .. this.locomotive_max_health)
if this.circle then
rendering.destroy(this.circle)
end
this.circle =
rendering.draw_circle {
surface = game.surfaces[this.active_surface_index],
target = this.locomotive,
color = this.locomotive.color,
filled = false,
radius = this.locomotive_xp_aura,
only_in_alt_mode = true
}
end
local function fish_tag()
local this = WPT.get_table()
if not this.locomotive_cargo then
return
end
if not this.locomotive_cargo.valid then
return
end
if not this.locomotive_cargo.surface then
return
end
if not this.locomotive_cargo.surface.valid then
return
end
if this.locomotive_tag then
if this.locomotive_tag.valid then
if
this.locomotive_tag.position.x == this.locomotive_cargo.position.x and
this.locomotive_tag.position.y == this.locomotive_cargo.position.y
then
return
end
this.locomotive_tag.destroy()
end
end
this.locomotive_tag =
this.locomotive_cargo.force.add_chart_tag(
this.locomotive_cargo.surface,
{
icon = {type = 'item', name = 'raw-fish'},
position = this.locomotive_cargo.position,
text = ' '
}
)
end
local function set_player_spawn_and_refill_fish()
local this = WPT.get_table()
if not this.locomotive_cargo then
return
end
if not this.locomotive_cargo.valid then
return
end
this.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert(
{name = 'raw-fish', count = math.random(2, 5)}
)
local position =
this.locomotive_cargo.surface.find_non_colliding_position(
'stone-furnace',
this.locomotive_cargo.position,
16,
2
)
if not position then
return
end
game.forces.player.set_spawn_position({x = position.x, y = position.y}, this.locomotive_cargo.surface)
end
local direction_lookup = {
[-1] = {
[1] = defines.direction.southwest,
[0] = defines.direction.west,
[-1] = defines.direction.northwest
},
[0] = {
[1] = defines.direction.south,
[-1] = defines.direction.north
},
[1] = {
[1] = defines.direction.southeast,
[0] = defines.direction.east,
[-1] = defines.direction.northeast
}
}
local function rand_range(start, stop)
local this = WPT.get_table()
if not this.rng then
this.rng = game.create_random_generator()
end
return this.rng(start, stop)
end
local function get_axis(point, axis)
local function safe_get(t, k)
local res, value =
pcall(
function()
return t[k]
end
)
if res then
return value
end
return nil
end
if point.position then
return get_axis(point.position, axis)
end
if point[axis] then
return point[axis]
end
if safe_get(point, 'target') then
return get_axis(point.target, axis)
end
if #point ~= 2 then
log('get_axis: invalid point format')
return nil
end
if axis == 'x' then
return point[1]
end
return point[2]
end
local function get_direction(src, dest)
local src_x = get_axis(src, 'x')
local src_y = get_axis(src, 'y')
local dest_x = get_axis(dest, 'x')
local dest_y = get_axis(dest, 'y')
local step = {
x = nil,
y = nil
}
local precision = rand_range(1, 10)
if dest_x - precision > src_x then
step.x = 1
elseif dest_x < src_x - precision then
step.x = -1
else
step.x = 0
end
if dest_y - precision > src_y then
step.y = 1
elseif dest_y < src_y - precision then
step.y = -1
else
step.y = 0
end
return direction_lookup[step.x][step.y]
end
local function get_distance(a, b)
local h = (get_axis(a, 'x') - get_axis(b, 'x')) ^ 2
local v = (get_axis(a, 'y') - get_axis(b, 'y')) ^ 2
return math.sqrt(h + v)
end
local function move_to(ent, trgt, min_distance)
local state = {
walking = false
}
local distance = get_distance(trgt.position, ent.position)
if min_distance < distance then
local dir = get_direction(ent.position, trgt.position)
if dir then
state = {
walking = true,
direction = dir
}
end
end
ent.walking_state = state
return state.walking
end
local function tick()
local this = WPT.get_table()
if this.energy_shared then
Public.power_source_overworld()
Public.power_source_locomotive()
end
if game.tick % 120 == 0 then
Public.boost_players_around_train()
end
if game.tick % 80 == 0 then
train_rainbow()
end
if game.tick % 30 == 0 then
if game.tick % 1800 == 0 then
set_player_spawn_and_refill_fish()
end
--Public.spawn_player()
fish_tag()
end
end
function Public.boost_players_around_train()
local rpg = RPG.get_table()
local this = WPT.get_table()
local surface = game.surfaces[this.active_surface_index]
if not this.locomotive then
return
end
if not this.locomotive.valid then
return
end
local data = {
this = this,
surface = surface,
rpg = rpg
}
property_boost(data)
end
function Public.render_train_hp()
local this = WPT.get_table()
local surface = game.surfaces[this.active_surface_index]
this.health_text =
rendering.draw_text {
text = 'HP: ' .. this.locomotive_health .. ' / ' .. this.locomotive_max_health,
surface = surface,
target = this.locomotive,
target_offset = {0, -2.5},
color = this.locomotive.color,
scale = 1.40,
font = 'default-game',
alignment = 'center',
scale_with_zoom = false
}
this.caption =
rendering.draw_text {
text = 'Grandmasters Train',
surface = surface,
target = this.locomotive,
target_offset = {0, -4.25},
color = this.locomotive.color,
scale = 1.80,
font = 'default-game',
alignment = 'center',
scale_with_zoom = false
}
this.circle =
rendering.draw_circle {
surface = surface,
target = this.locomotive,
color = this.locomotive.color,
filled = false,
radius = this.locomotive_xp_aura,
only_in_alt_mode = true
}
end
function Public.spawn_player()
local rnd = math.random
local this = WPT.get_table()
local surface = game.surfaces[this.active_surface_index]
local position = this.locomotive.position
if not this.locomotive then
return
end
if not this.locomotive.valid then
return
end
if not this.lumberjack_one or not this.lumberjack_one.valid then
this.lumberjack_one =
surface.create_entity(
{
name = 'character',
position = {position.x + 5, position.y},
force = 'player',
direction = 0
}
)
this.lumberjack_one_caption =
rendering.draw_text {
text = 'Lumberjack',
surface = surface,
target = this.lumberjack_one,
target_offset = {0, -2.25},
color = {r = 0, g = 110, b = 33},
scale = 0.75,
font = 'default-game',
alignment = 'center',
scale_with_zoom = false
}
end
if not this.lumberjack_two or not this.lumberjack_two.valid then
this.lumberjack_two =
surface.create_entity(
{
name = 'character',
position = {position.x + -5, position.y},
force = 'player',
direction = 0
}
)
this.lumberjack_two_caption =
rendering.draw_text {
text = 'Lumberjack',
surface = surface,
target = this.lumberjack_two,
target_offset = {0, -2.25},
color = {r = 0, g = 110, b = 33},
scale = 0.75,
font = 'default-game',
alignment = 'center',
scale_with_zoom = false
}
end
for _, p in pairs(game.connected_players) do
if this.lumberjack_one and this.lumberjack_one.valid then
if rnd(1, 32) == 1 then
this.lumberjack_one.destroy()
return
end
move_to(this.lumberjack_one, p, rnd(15, 50))
end
if this.lumberjack_two and this.lumberjack_two.valid then
if rnd(1, 32) == 1 then
this.lumberjack_two.destroy()
return
end
move_to(this.lumberjack_two, p, rnd(15, 50))
end
end
end
function Public.locomotive_spawn(surface, position)
local this = WPT.get_table()
for y = -6, 6, 2 do
surface.create_entity(
{name = 'straight-rail', position = {position.x, position.y + y}, force = 'player', direction = 0}
)
end
this.locomotive =
surface.create_entity({name = 'locomotive', position = {position.x, position.y + -3}, force = 'player'})
this.locomotive.get_inventory(defines.inventory.fuel).insert({name = 'wood', count = 100})
this.locomotive_cargo =
surface.create_entity({name = 'cargo-wagon', position = {position.x, position.y + 3}, force = 'player'})
this.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = 'raw-fish', count = 8})
rendering.draw_light(
{
sprite = 'utility/light_medium',
scale = 5.5,
intensity = 1,
minimum_darkness = 0,
oriented = true,
color = {255, 255, 255},
target = this.locomotive,
surface = surface,
visible = true,
only_in_alt_mode = false
}
)
for y = -1, 0, 0.05 do
local scale = math.random(50, 100) * 0.01
rendering.draw_sprite(
{
sprite = 'item/raw-fish',
orientation = math.random(0, 100) * 0.01,
x_scale = scale,
y_scale = scale,
tint = {math.random(60, 255), math.random(60, 255), math.random(60, 255)},
render_layer = 'selection-box',
target = this.locomotive_cargo,
target_offset = {-0.7 + math.random(0, 140) * 0.01, y},
surface = surface
}
)
end
this.locomotive.color = {0, 255, 0}
this.locomotive.minable = false
this.locomotive_cargo.minable = false
this.locomotive_cargo.operable = true
local locomotive = ICW.register_wagon(this.locomotive)
local wagon = ICW.register_wagon(this.locomotive_cargo)
locomotive.entity_count = 999
wagon.entity_count = 999
end
function Public.inside(pos, area)
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
function Public.contains_positions(pos, area)
if Public.inside(pos, area) then
return true
end
return false
end
function Public.power_source_overworld()
local this = WPT.get_table()
local surface = game.surfaces[this.active_surface_index]
if not this.locomotive then
return
end
if not this.locomotive.valid then
return
end
local data = {
this = this,
surface = surface
}
rebuild_energy_overworld(data)
end
function Public.power_source_locomotive()
local this = WPT.get_table()
local icw_table = ICW.get_table()
if not this.locomotive then
return
end
if not this.locomotive.valid then
return
end
local unit_surface = this.locomotive.unit_number
local surface = game.surfaces[icw_table.wagons[unit_surface].surface.index]
local data = {
this = this,
icw_table = icw_table,
surface = surface
}
if not this.lo_energy then
rebuild_energy_loco(data)
elseif not this.lo_energy.valid then
rebuild_energy_loco(data, true)
end
end
Event.on_nth_tick(5, tick)
return Public

View File

@ -1,744 +0,0 @@
local Event = require 'utils.event'
local WPT = require 'maps.lumberjack.table'
local WD = require 'modules.wave_defense.table'
local ICW = require 'maps.lumberjack.icw.main'
local format_number = require 'util'.format_number
local grandmaster = '[color=blue]Grandmaster:[/color]'
local energy_upgrade = 50000000
local random = math.random
local Public = {}
local function shuffle(tbl)
local size = #tbl
for i = size, 1, -1 do
local rand = random(size)
tbl[i], tbl[rand] = tbl[rand], tbl[i]
end
return tbl
end
function Public.get_items()
local this = WPT.get_table()
local threat_cost = 15000 * (0.5 + this.threat_upgrades)
local energy_cost = 15000
local health_cost = 15000 * (0.5 + this.health_upgrades)
local aura_cost = 15000 * (0.5 + this.aura_upgrades)
local xp_point_boost_cost = 15000 * (0.5 + this.xp_points_upgrade)
local items = {}
items['clear_threat_level'] = {
stack = 1,
value = 'coin',
price = threat_cost,
tooltip = '[Wave Defense]:\nClears the current threat to 0\nUsable if threat level is too high.\nCan be purchased multiple times.',
sprite = 'item/computer',
enabled = true
}
items['energy_upgrade'] = {
stack = 1,
value = 'coin',
price = energy_cost,
tooltip = '[Linked Power]:\nUpgrades the buffer size of the energy interface\nUsable if the power dies easily.',
sprite = 'item/computer',
enabled = true
}
items['locomotive_max_health'] = {
stack = 1,
value = 'coin',
price = health_cost,
tooltip = '[Locomotive Health]:\nUpgrades the train health.\nCan be purchased multiple times.',
sprite = 'item/computer',
enabled = true
}
items['locomotive_xp_aura'] = {
stack = 1,
value = 'coin',
price = aura_cost,
tooltip = '[XP Aura]:\nUpgrades the aura that is around the train.\nNote! Reaching breach walls gives more XP.',
sprite = 'item/computer',
enabled = true
}
items['xp_points_boost'] = {
stack = 1,
value = 'coin',
price = xp_point_boost_cost,
tooltip = '[XP Points]:\nUpgrades the amount of xp points you get inside the XP aura',
sprite = 'item/computer',
enabled = true
}
items['purge_darkness'] = {
stack = 1,
value = 'coin',
price = 1550,
tooltip = "[Darkness]:\nPay the Sun Gods some coins and they'll reward you handsomely.",
sprite = 'item/computer',
enabled = true
}
items['small-lamp'] = {stack = 1, value = 'coin', price = 5, tooltip = 'Small Sunlight'}
items['wood'] = {stack = 50, value = 'coin', price = 12, tooltip = 'Some fine Wood'}
items['land-mine'] = {stack = 1, value = 'coin', price = 25, tooltip = 'Land Boom Danger'}
items['raw-fish'] = {stack = 1, value = 'coin', price = 4, tooltip = 'Flappy Fish'}
items['firearm-magazine'] = {stack = 1, value = 'coin', price = 5, tooltip = 'Firearm Pew'}
items['crude-oil-barrel'] = {stack = 1, value = 'coin', price = 8, tooltip = 'Crude Oil Flame'}
items['loader'] = {stack = 1, value = 'coin', price = 150, tooltip = 'Ground Inserter.'}
items['fast-loader'] = {
stack = 1,
value = 'coin',
price = 300,
tooltip = 'Ground Fast Inserter'
}
return items
end
local space = {
minimal_height = 10,
top_padding = 0,
bottom_padding = 0
}
local function addStyle(guiIn, styleIn)
for k, v in pairs(styleIn) do
guiIn.style[k] = v
end
end
local function adjustSpace(guiIn)
addStyle(guiIn.add {type = 'line', direction = 'horizontal'}, space)
end
local function validate_player(player)
if not player then
return false
end
if not player.valid then
return false
end
if not player.character then
return false
end
if not player.connected then
return false
end
if not game.players[player.index] then
return false
end
return true
end
local function close_market_gui(player)
local this = WPT.get_table()
local element = player.gui.center
local data = this.players[player.index].data
if not data then
return
end
if element and element.valid then
element = element['market_gui']
if element and element.valid then
element.destroy()
end
if data.frame and data.frame.valid then
data.frame.destroy()
end
end
end
local function redraw_market_items(gui, player, search_text)
if not validate_player(player) then
return
end
local this = WPT.get_table()
gui.clear()
shuffle(Public.get_items())
local inventory = player.get_main_inventory()
local player_item_count = inventory.get_item_count('coin')
local items_table = gui.add({type = 'table', column_count = 6})
local slider_value = math.ceil(this.players[player.index].data.slider.slider_value)
for name, opts in pairs(Public.get_items()) do
if not search_text then
goto continue
end
if not search_text.text then
goto continue
end
if not string.lower(name:gsub('-', ' ')):find(search_text.text) then
goto continue
end
local item_count = opts.stack * slider_value
local item_cost = opts.price * slider_value
local flow = items_table.add({type = 'flow'})
flow.style.vertical_align = 'bottom'
local button =
flow.add(
{
type = 'sprite-button',
sprite = opts.sprite or 'item/' .. name,
number = item_count,
name = name,
tooltip = opts.tooltip,
style = 'slot_button',
enabled = opts.enabled
}
)
flow.add(
{
type = 'label',
caption = format_number(item_cost, true) .. ' coins'
}
)
if player_item_count < item_cost then
button.enabled = false
end
::continue::
end
end
local function redraw_coins_left(gui, player)
if not validate_player(player) then
return
end
gui.clear()
local inventory = player.get_main_inventory()
local player_item_count = inventory.get_item_count('coin')
local coinsleft =
gui.add(
{
type = 'label',
caption = 'Coins left: ' .. format_number(player_item_count, true)
}
)
adjustSpace(coinsleft)
end
local function slider_changed(event)
local player = game.players[event.player_index]
local this = WPT.get_table()
local slider_value
slider_value = this.players
if not slider_value then
return
end
slider_value = slider_value[player.index].data
if not slider_value then
return
end
slider_value = slider_value.slider
if not slider_value then
return
end
slider_value = slider_value.slider_value
if not slider_value then
return
end
slider_value = math.ceil(slider_value)
this.players[player.index].data.text_input.text = slider_value
redraw_market_items(this.players[player.index].data.item_frame, player, this.players[player.index].data.search_text)
end
local function text_changed(event)
local this = WPT.get_table()
local player = game.players[event.player_index]
local data = this.players[player.index].data
if not data then
return
end
if not data.text_input then
return
end
if not data.text_input.text then
return
end
local value = 0
tonumber(data.text_input.text)
if not value then
return
end
data.slider.slider_value = value
redraw_market_items(data.item_frame, player, data.search_text)
end
local function gui_opened(event)
local this = WPT.get_table()
if not event.gui_type == defines.gui_type.entity then
return
end
local entity = event.entity
if not entity then
return
end
if entity ~= this.market then
return
end
local player = game.players[event.player_index]
if not validate_player(player) then
return
end
local inventory = player.get_main_inventory()
local player_item_count = inventory.get_item_count('coin')
local data = this.players[player.index].data
if data.frame then
data.frame = nil
end
local frame =
player.gui.screen.add(
{
type = 'frame',
caption = 'Market',
direction = 'vertical',
name = 'market_gui'
}
)
frame.auto_center = true
player.opened = frame
frame.style.minimal_width = 500
frame.style.minimal_height = 250
local search_table = frame.add({type = 'table', column_count = 2})
search_table.add({type = 'label', caption = 'Search: '})
local search_text = search_table.add({type = 'textfield'})
adjustSpace(frame)
local pane =
frame.add {
type = 'scroll-pane',
direction = 'vertical',
vertical_scroll_policy = 'always',
horizontal_scroll_policy = 'never'
}
pane.style.maximal_height = 200
pane.style.horizontally_stretchable = true
pane.style.minimal_height = 200
pane.style.right_padding = 0
local flow = frame.add({type = 'flow'})
adjustSpace(flow)
local slider_frame = frame.add({type = 'table', column_count = 5})
local left_button = slider_frame.add({type = 'button', caption = '-1', name = 'less'})
local slider =
slider_frame.add(
{
type = 'slider',
minimum_value = 1,
maximum_value = 1e3,
value = 1
}
)
local right_button = slider_frame.add({type = 'button', caption = '+1', name = 'more'})
left_button.style.width = 0
left_button.style.height = 0
right_button.style.width = 0
right_button.style.height = 0
slider_frame.add(
{
type = 'label',
caption = 'Qty:'
}
)
local text_input =
slider_frame.add(
{
type = 'textfield',
text = 1
}
)
local coinsleft = frame.add({type = 'flow'})
coinsleft.add(
{
type = 'label',
caption = 'Coins left: ' .. format_number(player_item_count, true)
}
)
this.players[player.index].data.search_text = search_text
this.players[player.index].data.text_input = text_input
this.players[player.index].data.slider = slider
this.players[player.index].data.frame = frame
this.players[player.index].data.item_frame = pane
this.players[player.index].data.coins_left = coinsleft
redraw_market_items(pane, player, search_text)
end
local function gui_click(event)
local this = WPT.get_table()
local wdt = WD.get_table()
local element = event.element
local player = game.players[event.player_index]
if not validate_player(player) then
return
end
local data = this.players[player.index].data
if not data then
return
end
if not element.valid then
return
end
local name = element.name
if name == 'less' then
local slider_value = this.players[player.index].data.slider.slider_value
if slider_value > 1 then
data.slider.slider_value = slider_value - 1
data.text_input.text = data.slider.slider_value
redraw_market_items(data.item_frame, player, data.search_text)
end
return
elseif name == 'more' then
local slider_value = data.slider.slider_value
if slider_value <= 1e3 then
data.slider.slider_value = slider_value + 1
data.text_input.text = data.slider.slider_value
redraw_market_items(data.item_frame, player, data.search_text)
end
return
end
if not player.opened then
return
end
if not player.opened.name == 'market' then
return
end
if not data then
return
end
local item = Public.get_items()[name]
if not item then
return
end
local inventory = player.get_main_inventory()
local player_item_count = inventory.get_item_count(item.value)
local slider_value = math.ceil(data.slider.slider_value)
local cost = (item.price * slider_value)
local item_count = item.stack * slider_value
if name == 'clear_threat_level' then
player.remove_item({name = item.value, count = cost})
game.print(
grandmaster .. ' ' .. player.name .. ' has bought the group some extra time. Threat level is no more!',
{r = 0.98, g = 0.66, b = 0.22}
)
this.threat_upgrades = this.threat_upgrades + 1
wdt.threat = 0
redraw_market_items(data.item_frame, player, data.search_text)
redraw_coins_left(data.coins_left, player)
return
end
if name == 'energy_upgrade' then
if this.energy_purchased then
return player.print(
grandmaster .. ' ' .. player.name .. ', max energy upgrade is already purchased!',
{r = 0.98, g = 0.66, b = 0.22}
)
end
player.remove_item({name = item.value, count = cost})
game.print(
grandmaster ..
' ' .. player.name .. ' has bought the group a power upgrade! The energy interface is now buffed!',
{r = 0.98, g = 0.66, b = 0.22}
)
this.energy_purchased = true
this.train_upgrades = this.train_upgrades + 1
this.lo_energy.electric_buffer_size = this.lo_energy.electric_buffer_size + energy_upgrade
this.ow_energy.electric_buffer_size = this.ow_energy.electric_buffer_size + energy_upgrade
redraw_market_items(data.item_frame, player, data.search_text)
redraw_coins_left(data.coins_left, player)
return
end
if name == 'locomotive_max_health' then
player.remove_item({name = item.value, count = cost})
game.print(
grandmaster ..
' ' .. player.name .. ' has bought the group a train health modifier! The train health is now buffed!',
{r = 0.98, g = 0.66, b = 0.22}
)
this.locomotive_max_health = this.locomotive_max_health + 2500
this.train_upgrades = this.train_upgrades + 1
this.health_upgrades = this.health_upgrades + 1
rendering.set_text(this.health_text, 'HP: ' .. this.locomotive_health .. ' / ' .. this.locomotive_max_health)
redraw_market_items(data.item_frame, player, data.search_text)
redraw_coins_left(data.coins_left, player)
return
end
if name == 'locomotive_xp_aura' then
player.remove_item({name = item.value, count = cost})
game.print(
grandmaster .. ' ' .. player.name .. ' has bought the group a XP aura modifier! The XP aura is now buffed!',
{r = 0.98, g = 0.66, b = 0.22}
)
this.locomotive_xp_aura = this.locomotive_xp_aura + 5
this.aura_upgrades = this.aura_upgrades + 1
this.train_upgrades = this.train_upgrades + 1
if this.circle then
rendering.destroy(this.circle)
end
this.circle =
rendering.draw_circle {
surface = game.surfaces[this.active_surface_index],
target = this.locomotive,
color = this.locomotive.color,
filled = false,
radius = this.locomotive_xp_aura,
only_in_alt_mode = true
}
redraw_market_items(data.item_frame, player, data.search_text)
redraw_coins_left(data.coins_left, player)
return
end
if name == 'purge_darkness' then
if not this.freeze_daytime then
return player.print(
grandmaster .. ' ' .. player.name .. ", it's already sunlight!",
{r = 0.98, g = 0.66, b = 0.22}
)
end
game.print(
grandmaster .. ' ' .. player.name .. ' has paid the Sun Gods some coins for sunlight!',
{r = 0.98, g = 0.66, b = 0.22}
)
local surface = game.surfaces[this.active_surface_index]
game.print(grandmaster .. ' Sunlight, finally!', {r = 0.98, g = 0.66, b = 0.22})
surface.min_brightness = 1
surface.brightness_visual_weights = {1, 0, 0, 0}
surface.daytime = 1
surface.freeze_daytime = false
surface.solar_power_multiplier = 1
this.freeze_daytime = false
player.remove_item({name = item.value, count = cost})
redraw_market_items(data.item_frame, player, data.search_text)
redraw_coins_left(data.coins_left, player)
return
end
if name == 'xp_points_boost' then
player.remove_item({name = item.value, count = cost})
game.print(
grandmaster ..
' ' .. player.name .. ' has bought the group a XP point modifier! You now gain more XP points!',
{r = 0.98, g = 0.66, b = 0.22}
)
this.xp_points = this.xp_points + 0.5
this.xp_points_upgrade = this.xp_points_upgrade + 1
this.train_upgrades = this.train_upgrades + 1
redraw_market_items(data.item_frame, player, data.search_text)
redraw_coins_left(data.coins_left, player)
return
end
if player_item_count >= cost then
if player.can_insert({name = name, count = item_count}) then
player.play_sound({path = 'entity-close/stone-furnace', volume_modifier = 0.65})
player.remove_item({name = item.value, count = cost})
local inserted_count = player.insert({name = name, count = item_count})
if inserted_count < item_count then
player.play_sound({path = 'utility/cannot_build', volume_modifier = 0.65})
player.insert({name = item.value, count = cost})
player.remove_item({name = name, count = inserted_count})
end
redraw_market_items(data.item_frame, player, data.search_text)
redraw_coins_left(data.coins_left, player)
end
end
end
local function gui_closed(event)
local player = game.players[event.player_index]
local this = WPT.get_table()
local type = event.gui_type
if type == defines.gui_type.custom then
local data = this.players[player.index].data
if not data then
return
end
close_market_gui(player)
end
end
local function inside(pos, area)
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
local function contains_positions(pos, area)
if inside(pos, area) then
return true
end
return false
end
local function on_player_changed_position(event)
local this = WPT.get_table()
local player = game.players[event.player_index]
local data = this.players[player.index].data
if data and data.frame and data.frame.valid then
local position = this.market.position
local area = {
left_top = {x = position.x - 10, y = position.y - 10},
right_bottom = {x = position.x + 10, y = position.y + 10}
}
if contains_positions(player.position, area) then
return
end
if not data then
return
end
close_market_gui(player)
end
end
local function create_market(data, rebuild)
local surface = data.surface
local this = data.this
local pos = {x = 18, y = 3}
if rebuild then
local radius = 1024
local area = {{x = -radius, y = -radius}, {x = radius, y = radius}}
for _, entity in pairs(surface.find_entities_filtered {area = area, name = 'market'}) do
entity.destroy()
end
this.market = nil
end
this.market = surface.create_entity {name = 'market', position = pos, force = 'player'}
rendering.draw_text {
text = 'Market',
surface = surface,
target = this.market,
target_offset = {0, 2},
color = {r = 0.98, g = 0.66, b = 0.22},
alignment = 'center'
}
this.market.destructible = false
end
local function place_market()
local this = WPT.get_table()
local icw_table = ICW.get_table()
if not this.locomotive then
return
end
if not this.locomotive.valid then
return
end
local unit_surface = this.locomotive.unit_number
local surface = game.surfaces[icw_table.wagons[unit_surface].surface.index]
local data = {
this = this,
surface = surface
}
if not this.market then
create_market(data)
elseif not this.market.valid then
create_market(data, true)
end
end
local function reset_player(player, this)
this.players[player.index].start_tick = nil
player.print(grandmaster .. ' ' .. player.name .. ', time is up!', {r = 0.98, g = 0.66, b = 0.22})
end
local function on_tick()
local this = WPT.get_table()
if game.tick % 900 == 0 then
if this.players then
for k, v in pairs(this.players) do
if not v.start_tick then
return
end
if game.tick - v.start_tick > 6000 then
reset_player(game.players[k], this)
end
end
end
end
place_market()
end
Event.on_nth_tick(5, on_tick)
Event.add(defines.events.on_gui_click, gui_click)
Event.add(defines.events.on_gui_opened, gui_opened)
Event.add(defines.events.on_gui_value_changed, slider_changed)
Event.add(defines.events.on_gui_text_changed, text_changed)
Event.add(defines.events.on_gui_closed, gui_closed)
Event.add(defines.events.on_player_changed_position, on_player_changed_position)
return Public

View File

@ -1,213 +0,0 @@
local LootRaffle = require 'functions.loot_raffle'
local Public = {}
local math_random = math.random
local math_abs = math.abs
local math_floor = math.floor
local blacklist = {
['cargo-wagon'] = true,
['locomotive'] = true,
['artillery-wagon'] = true,
['fluid-wagon'] = true
}
function Public.add(surface, position, container_name)
local budget = 48 + math_abs(position.y) * 1.75
budget = budget * math_random(25, 175) * 0.01
if math_random(1, 128) == 1 then
budget = budget * 4
container_name = 'crash-site-chest-' .. math_random(1, 2)
end
if math_random(1, 256) == 1 then
budget = budget * 4
container_name = 'crash-site-chest-' .. math_random(1, 2)
end
budget = math_floor(budget) + 1
local item_stacks = LootRaffle.roll(budget, 8, blacklist)
local container = surface.create_entity({name = container_name, position = position, force = 'defenders'})
for _, item_stack in pairs(item_stacks) do
container.insert(item_stack)
end
container.minable = false
for _ = 1, 3, 1 do
if math_random(1, 8) == 1 then
container.insert({name = 'explosives', count = math_random(25, 50)})
else
break
end
end
end
function Public.add_rare(surface, position, chest, magic)
if magic > 150 then
magic = math.random(1, 150)
end
local chest_raffle = {}
local chest_loot = {
{{name = 'submachine-gun', count = magic}, weight = 3, d_min = 0.0, d_max = 0.1},
{{name = 'slowdown-capsule', count = magic}, weight = 1, d_min = 0.3, d_max = 0.7},
{{name = 'poison-capsule', count = magic}, weight = 3, d_min = 0.3, d_max = 1},
{{name = 'uranium-cannon-shell', count = magic}, weight = 5, d_min = 0.6, d_max = 1},
{{name = 'cannon-shell', count = magic}, weight = 5, d_min = 0.4, d_max = 0.7},
{{name = 'explosive-uranium-cannon-shell', count = magic}, weight = 5, d_min = 0.6, d_max = 1},
{{name = 'explosive-cannon-shell', count = magic}, weight = 5, d_min = 0.4, d_max = 0.8},
{{name = 'shotgun', count = 1}, weight = 2, d_min = 0.0, d_max = 0.2},
{{name = 'shotgun-shell', count = magic}, weight = 5, d_min = 0.0, d_max = 0.2},
{{name = 'combat-shotgun', count = 1}, weight = 3, d_min = 0.3, d_max = 0.8},
{{name = 'piercing-shotgun-shell', count = magic}, weight = 10, d_min = 0.2, d_max = 1},
{{name = 'flamethrower', count = 1}, weight = 3, d_min = 0.3, d_max = 0.6},
{{name = 'flamethrower-ammo', count = magic}, weight = 5, d_min = 0.3, d_max = 1},
{{name = 'rocket-launcher', count = 1}, weight = 3, d_min = 0.2, d_max = 0.6},
{{name = 'rocket', count = magic}, weight = 5, d_min = 0.2, d_max = 0.7},
{{name = 'explosive-rocket', count = magic}, weight = 5, d_min = 0.3, d_max = 1},
{{name = 'grenade', count = magic}, weight = 5, d_min = 0.0, d_max = 0.5},
{{name = 'cluster-grenade', count = magic}, weight = 5, d_min = 0.4, d_max = 1},
{{name = 'firearm-magazine', count = magic}, weight = 6, d_min = 0, d_max = 0.3},
{{name = 'piercing-rounds-magazine', count = magic}, weight = 5, d_min = 0.1, d_max = 0.8},
{{name = 'uranium-rounds-magazine', count = magic}, weight = 4, d_min = 0.5, d_max = 1},
{{name = 'railgun', count = 1}, weight = 1, d_min = 0.2, d_max = 1},
{{name = 'railgun-dart', count = magic}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = 'defender-capsule', count = magic}, weight = 2, d_min = 0.0, d_max = 0.7},
{{name = 'distractor-capsule', count = magic}, weight = 2, d_min = 0.2, d_max = 1},
{{name = 'destroyer-capsule', count = magic}, weight = 2, d_min = 0.3, d_max = 1},
{{name = 'atomic-bomb', count = 1}, weight = 1, d_min = 0.8, d_max = 1},
{{name = 'land-mine', count = magic}, weight = 5, d_min = 0.2, d_max = 0.7},
{{name = 'light-armor', count = 1}, weight = 3, d_min = 0, d_max = 0.1},
{{name = 'heavy-armor', count = 1}, weight = 3, d_min = 0.1, d_max = 0.3},
{{name = 'modular-armor', count = 1}, weight = 2, d_min = 0.2, d_max = 0.6},
{{name = 'power-armor', count = 1}, weight = 1, d_min = 0.4, d_max = 1},
{{name = 'battery-equipment', count = 1}, weight = 2, d_min = 0.3, d_max = 0.7},
{{name = 'belt-immunity-equipment', count = 1}, weight = 1, d_min = 0.5, d_max = 1},
{{name = 'solar-panel-equipment', count = magic}, weight = 5, d_min = 0.4, d_max = 0.8},
{{name = 'discharge-defense-equipment', count = 1}, weight = 1, d_min = 0.5, d_max = 1},
{{name = 'energy-shield-equipment', count = magic}, weight = 2, d_min = 0.3, d_max = 0.8},
{{name = 'exoskeleton-equipment', count = 1}, weight = 1, d_min = 0.3, d_max = 1},
{{name = 'night-vision-equipment', count = 1}, weight = 1, d_min = 0.3, d_max = 0.8},
{{name = 'personal-laser-defense-equipment', count = 1}, weight = 1, d_min = 0.7, d_max = 1},
{{name = 'personal-roboport-equipment', count = magic}, weight = 3, d_min = 0.4, d_max = 1},
{{name = 'logistic-robot', count = magic}, weight = 2, d_min = 0.5, d_max = 1},
{{name = 'construction-robot', count = magic}, weight = 5, d_min = 0.4, d_max = 1},
{{name = 'iron-gear-wheel', count = magic}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = 'copper-cable', count = magic}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = 'engine-unit', count = magic}, weight = 2, d_min = 0.1, d_max = 0.5},
{{name = 'electric-engine-unit', count = magic}, weight = 2, d_min = 0.4, d_max = 0.8},
{{name = 'battery', count = magic}, weight = 2, d_min = 0.3, d_max = 0.8},
{{name = 'advanced-circuit', count = magic}, weight = 3, d_min = 0.3, d_max = 1},
{{name = 'electronic-circuit', count = magic}, weight = 4, d_min = 0.0, d_max = 0.4},
{{name = 'processing-unit', count = magic}, weight = 3, d_min = 0.7, d_max = 1},
{{name = 'explosives', count = magic}, weight = 10, d_min = 0.0, d_max = 1},
{{name = 'lubricant-barrel', count = magic}, weight = 1, d_min = 0.3, d_max = 0.5},
{{name = 'rocket-fuel', count = magic}, weight = 2, d_min = 0.3, d_max = 0.7},
{{name = 'effectivity-module', count = magic}, weight = 2, d_min = 0.1, d_max = 1},
{{name = 'productivity-module', count = magic}, weight = 2, d_min = 0.1, d_max = 1},
{{name = 'speed-module', count = magic}, weight = 2, d_min = 0.1, d_max = 1},
{{name = 'automation-science-pack', count = magic}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = 'logistic-science-pack', count = magic}, weight = 3, d_min = 0.1, d_max = 0.5},
{{name = 'military-science-pack', count = magic}, weight = 3, d_min = 0.2, d_max = 1},
{{name = 'chemical-science-pack', count = magic}, weight = 3, d_min = 0.3, d_max = 1},
{{name = 'production-science-pack', count = magic}, weight = 3, d_min = 0.4, d_max = 1},
{{name = 'utility-science-pack', count = magic}, weight = 3, d_min = 0.5, d_max = 1},
{{name = 'space-science-pack', count = magic}, weight = 3, d_min = 0.9, d_max = 1},
{{name = 'steel-plate', count = magic}, weight = 2, d_min = 0.1, d_max = 0.3},
{{name = 'nuclear-fuel', count = 1}, weight = 2, d_min = 0.7, d_max = 1},
{{name = 'burner-inserter', count = magic}, weight = 3, d_min = 0.0, d_max = 0.1},
{{name = 'inserter', count = magic}, weight = 3, d_min = 0.0, d_max = 0.4},
{{name = 'long-handed-inserter', count = magic}, weight = 3, d_min = 0.0, d_max = 0.4},
{{name = 'fast-inserter', count = magic}, weight = 3, d_min = 0.1, d_max = 1},
{{name = 'filter-inserter', count = magic}, weight = 1, d_min = 0.2, d_max = 1},
{{name = 'stack-filter-inserter', count = magic}, weight = 1, d_min = 0.4, d_max = 1},
{{name = 'stack-inserter', count = magic}, weight = 3, d_min = 0.3, d_max = 1},
{{name = 'small-electric-pole', count = magic}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = 'medium-electric-pole', count = magic}, weight = 3, d_min = 0.2, d_max = 1},
{{name = 'big-electric-pole', count = magic}, weight = 3, d_min = 0.3, d_max = 1},
{{name = 'substation', count = magic}, weight = 3, d_min = 0.5, d_max = 1},
{{name = 'wooden-chest', count = magic}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = 'iron-chest', count = magic}, weight = 3, d_min = 0.1, d_max = 0.4},
{{name = 'steel-chest', count = magic}, weight = 3, d_min = 0.3, d_max = 1},
{{name = 'small-lamp', count = magic}, weight = 3, d_min = 0.1, d_max = 0.3},
{{name = 'rail', count = magic}, weight = 3, d_min = 0.1, d_max = 0.6},
{{name = 'assembling-machine-1', count = magic}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = 'assembling-machine-2', count = magic}, weight = 3, d_min = 0.2, d_max = 0.8},
{{name = 'assembling-machine-3', count = magic}, weight = 3, d_min = 0.5, d_max = 1},
{{name = 'accumulator', count = magic}, weight = 3, d_min = 0.4, d_max = 1},
{{name = 'offshore-pump', count = magic}, weight = 2, d_min = 0.0, d_max = 0.2},
{{name = 'beacon', count = 1}, weight = 2, d_min = 0.7, d_max = 1},
{{name = 'boiler', count = magic}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = 'steam-engine', count = magic}, weight = 3, d_min = 0.0, d_max = 0.5},
{{name = 'steam-turbine', count = magic}, weight = 2, d_min = 0.6, d_max = 1},
{{name = 'nuclear-reactor', count = 1}, weight = 1, d_min = 0.7, d_max = 1},
{{name = 'centrifuge', count = 1}, weight = 1, d_min = 0.6, d_max = 1},
{{name = 'heat-pipe', count = magic}, weight = 2, d_min = 0.5, d_max = 1},
{{name = 'heat-exchanger', count = magic}, weight = 2, d_min = 0.5, d_max = 1},
{{name = 'arithmetic-combinator', count = magic}, weight = 2, d_min = 0.1, d_max = 1},
{{name = 'constant-combinator', count = magic}, weight = 2, d_min = 0.1, d_max = 1},
{{name = 'decider-combinator', count = magic}, weight = 2, d_min = 0.1, d_max = 1},
{{name = 'power-switch', count = 1}, weight = 2, d_min = 0.1, d_max = 1},
{{name = 'programmable-speaker', count = magic}, weight = 1, d_min = 0.1, d_max = 1},
{{name = 'green-wire', count = magic}, weight = 4, d_min = 0.1, d_max = 1},
{{name = 'red-wire', count = magic}, weight = 4, d_min = 0.1, d_max = 1},
{{name = 'chemical-plant', count = magic}, weight = 3, d_min = 0.3, d_max = 1},
{{name = 'burner-mining-drill', count = magic}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = 'electric-mining-drill', count = magic}, weight = 3, d_min = 0.2, d_max = 1},
{{name = 'express-transport-belt', count = magic}, weight = 3, d_min = 0.5, d_max = 1},
{{name = 'express-underground-belt', count = magic}, weight = 3, d_min = 0.5, d_max = 1},
{{name = 'express-splitter', count = magic}, weight = 3, d_min = 0.5, d_max = 1},
{{name = 'fast-transport-belt', count = magic}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = 'fast-underground-belt', count = magic}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = 'fast-splitter', count = magic}, weight = 3, d_min = 0.2, d_max = 0.3},
{{name = 'transport-belt', count = magic}, weight = 3, d_min = 0, d_max = 0.3},
{{name = 'underground-belt', count = magic}, weight = 3, d_min = 0, d_max = 0.3},
{{name = 'splitter', count = magic}, weight = 3, d_min = 0, d_max = 0.3},
{{name = 'pipe', count = magic}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = 'pipe-to-ground', count = magic}, weight = 1, d_min = 0.2, d_max = 0.5},
{{name = 'pumpjack', count = magic}, weight = 1, d_min = 0.3, d_max = 0.8},
{{name = 'pump', count = magic}, weight = 1, d_min = 0.3, d_max = 0.8},
{{name = 'solar-panel', count = magic}, weight = 3, d_min = 0.4, d_max = 0.9},
{{name = 'electric-furnace', count = magic}, weight = 3, d_min = 0.5, d_max = 1},
{{name = 'steel-furnace', count = magic}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = 'stone-furnace', count = magic}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = 'radar', count = magic}, weight = 1, d_min = 0.1, d_max = 0.4},
{{name = 'rail-signal', count = magic}, weight = 2, d_min = 0.2, d_max = 0.8},
{{name = 'rail-chain-signal', count = magic}, weight = 2, d_min = 0.2, d_max = 0.8},
{{name = 'stone-wall', count = magic}, weight = 3, d_min = 0.0, d_max = 0.7},
{{name = 'gate', count = magic}, weight = 3, d_min = 0.0, d_max = 0.7},
{{name = 'storage-tank', count = magic}, weight = 3, d_min = 0.3, d_max = 0.6},
{{name = 'train-stop', count = magic}, weight = 1, d_min = 0.2, d_max = 0.7},
{{name = 'express-loader', count = magic}, weight = 1, d_min = 0.5, d_max = 1},
{{name = 'fast-loader', count = magic}, weight = 1, d_min = 0.2, d_max = 0.7},
{{name = 'loader', count = magic}, weight = 1, d_min = 0.0, d_max = 0.5},
{{name = 'lab', count = magic}, weight = 2, d_min = 0.0, d_max = 0.3},
{{name = 'roboport', count = 1}, weight = 2, d_min = 0.8, d_max = 1},
{{name = 'flamethrower-turret', count = 1}, weight = 3, d_min = 0.5, d_max = 1},
{{name = 'laser-turret', count = magic}, weight = 3, d_min = 0.5, d_max = 1},
{{name = 'gun-turret', count = magic}, weight = 3, d_min = 0.2, d_max = 0.9}
}
local distance_to_center = (math.abs(position.y) + 1) * 0.0002
if distance_to_center > 1 then
distance_to_center = 1
end
for _, t in pairs(chest_loot) do
for x = 1, t.weight, 1 do
if t.d_min <= distance_to_center and t.d_max >= distance_to_center then
table.insert(chest_raffle, t[1])
end
end
end
local e = surface.create_entity({name = chest, position = position, force = 'defenders'})
e.minable = false
local i = e.get_inventory(defines.inventory.chest)
for x = 1, math_random(5, 8), 1 do
local loot = chest_raffle[math_random(1, #chest_raffle)]
i.insert(loot)
end
end
return Public

View File

@ -1,666 +0,0 @@
-- modules
require 'maps.lumberjack.player_list'
require 'maps.lumberjack.comfylatron'
require 'maps.lumberjack.commands'
require 'maps.lumberjack.corpse_util'
require 'modules.dynamic_landfill'
require 'modules.shotgun_buff'
require 'modules.burden'
require 'modules.rocks_heal_over_time'
require 'modules.no_deconstruction_of_neutral_entities'
require 'modules.flamethrower_nerf'
require 'modules.rocks_yield_ore_veins'
require 'modules.spawners_contain_biters'
require 'modules.biters_yield_coins'
require 'modules.biter_noms_you'
require 'modules.wave_defense.main'
require 'modules.admins_operate_biters'
require 'modules.pistol_buffs'
local Difficulty = require 'modules.difficulty_vote'
local Server = require 'utils.server'
local Explosives = require 'modules.explosives'
local Color = require 'utils.color_presets'
local Entities = require 'maps.lumberjack.entities'
local update_gui = require 'maps.lumberjack.gui'
local ICW = require 'maps.lumberjack.icw.main'
local WD = require 'modules.wave_defense.table'
local Map = require 'modules.map_info'
local RPG = require 'maps.lumberjack.rpg'
local Reset = require 'maps.lumberjack.soft_reset'
local Terrain = require 'maps.lumberjack.terrain'
local Event = require 'utils.event'
local WPT = require 'maps.lumberjack.table'
local Locomotive = require 'maps.lumberjack.locomotive'.locomotive_spawn
local render_train_hp = require 'maps.lumberjack.locomotive'.render_train_hp
local Score = require 'comfy_panel.score'
local Poll = require 'comfy_panel.poll'
local Collapse = require 'modules.collapse'
local Balance = require 'maps.lumberjack.balance'
local shape = require 'maps.lumberjack.terrain'.heavy_functions
local Generate = require 'maps.lumberjack.generate'
local Task = require 'utils.task'
local Public = {}
local math_random = math.random
WPT.init({train_reveal = false, energy_shared = true, reveal_normally = true})
local starting_items = {['pistol'] = 1, ['firearm-magazine'] = 16, ['wood'] = 4, ['rail'] = 16, ['raw-fish'] = 2}
local grandmaster = '[color=blue]Grandmaster:[/color]'
local function create_forces_and_disable_tech()
if not game.forces.defenders then
game.create_force('defenders')
end
if not game.forces.lumber_defense then
game.create_force('lumber_defense')
end
game.forces.defenders.share_chart = false
game.forces.player.set_friend('defenders', true)
game.forces.player.set_friend('lumber_defense', false)
game.forces.lumber_defense.set_friend('player', false)
game.forces.lumber_defense.set_friend('enemy', true)
game.forces.enemy.set_friend('defenders', true)
game.forces.enemy.set_friend('lumber_defense', true)
game.forces.defenders.set_friend('player', true)
game.forces.defenders.set_friend('enemy', true)
game.forces.defenders.share_chart = false
game.forces.player.technologies['landfill'].enabled = false
game.forces.player.technologies['optics'].researched = true
game.forces.player.technologies['land-mine'].enabled = false
Balance.init_enemy_weapon_damage()
end
local function set_difficulty()
local Diff = Difficulty.get()
local wave_defense_table = WD.get_table()
local player_count = #game.connected_players
if not Diff.difficulty_vote_value then
Diff.difficulty_vote_value = 0.1
end
wave_defense_table.max_active_biters = 768 + player_count * (90 * Diff.difficulty_vote_value)
-- threat gain / wave
wave_defense_table.threat_gain_multiplier = 1.2 + player_count * Diff.difficulty_vote_value * 0.1
local amount = player_count * 0.25 + 2
amount = math.floor(amount)
if amount > 8 then
amount = 8
end
Collapse.set_amount(amount)
wave_defense_table.wave_interval = 3600
end
local function render_direction(surface)
rendering.draw_text {
text = 'Welcome to Lumberjack!',
surface = surface,
target = {-0, 10},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 20},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 30},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 40},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 50},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = '',
surface = surface,
target = {-0, 60},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
rendering.draw_text {
text = 'Biters will attack this area.',
surface = surface,
target = {-0, 70},
color = {r = 0.98, g = 0.66, b = 0.22},
scale = 3,
font = 'heading-1',
alignment = 'center',
scale_with_zoom = false
}
surface.create_entity({name = 'electric-beam', position = {-196, 74}, source = {-196, 74}, target = {196, 74}})
surface.create_entity({name = 'electric-beam', position = {-196, 74}, source = {-196, 74}, target = {196, 74}})
end
function Public.reset_map()
local this = WPT.get_table()
local wave_defense_table = WD.get_table()
local get_score = Score.get_table()
local Diff = Difficulty.get()
local map_gen_settings = {
['seed'] = math_random(10000, 99999),
['water'] = 0.001,
['starting_area'] = 1,
['cliff_settings'] = {cliff_elevation_interval = 0, cliff_elevation_0 = 0},
['default_enable_all_autoplace_controls'] = true,
['autoplace_settings'] = {
['entity'] = {treat_missing_as_default = false},
['tile'] = {treat_missing_as_default = true},
['decorative'] = {treat_missing_as_default = true}
}
}
if not this.active_surface_index then
this.active_surface_index = game.create_surface('lumberjack', map_gen_settings).index
this.active_surface = game.surfaces[this.active_surface_index]
else
game.forces.player.set_spawn_position({0, 25}, game.surfaces[this.active_surface_index])
this.active_surface_index =
Reset.soft_reset_map(game.surfaces[this.active_surface_index], map_gen_settings, starting_items).index
this.active_surface = game.surfaces[this.active_surface_index]
end
Poll.reset()
ICW.reset()
game.reset_time_played()
WPT.reset_table()
wave_defense_table.math = 8
if not this.train_reveal and not this.reveal_normally then
this.revealed_spawn = game.tick + 100
end
create_forces_and_disable_tech()
local surface = game.surfaces[this.active_surface_index]
surface.request_to_generate_chunks({0, 0}, 0.5)
surface.force_generate_chunk_requests()
local p = surface.find_non_colliding_position('character-corpse', {2, 21}, 2, 2)
surface.create_entity({name = 'character-corpse', position = p})
game.forces.player.set_spawn_position({0, 21}, surface)
global.bad_fire_history = {}
global.friendly_fire_history = {}
global.landfill_history = {}
global.mining_history = {}
get_score.score_table = {}
Diff.difficulty_poll_closing_timeout = game.tick + 90000
Diff.difficulty_player_votes = {}
game.difficulty_settings.technology_price_multiplier = 0.6
Collapse.set_kill_entities(false)
Collapse.set_speed(8)
Collapse.set_amount(1)
Collapse.set_max_line_size(Terrain.level_depth)
Collapse.set_surface(surface)
Collapse.set_position({0, 162})
Collapse.set_direction('north')
Collapse.start_now(false)
surface.ticks_per_day = surface.ticks_per_day * 2
surface.daytime = 0.71
surface.brightness_visual_weights = {1, 0, 0, 0}
surface.freeze_daytime = false
surface.solar_power_multiplier = 1
this.locomotive_health = 10000
this.locomotive_max_health = 10000
this.cargo_health = 10000
this.cargo_max_health = 10000
Locomotive(surface, {x = -18, y = 25})
render_train_hp()
render_direction(surface)
RPG.rpg_reset_all_players()
WD.reset_wave_defense()
wave_defense_table.surface_index = this.active_surface_index
wave_defense_table.target = this.locomotive_cargo
wave_defense_table.nest_building_density = 32
wave_defense_table.game_lost = false
wave_defense_table.spawn_position = {x = 0, y = 100}
wave_defense_table.next_wave = game.tick + 3600 * 25
set_difficulty()
local surfaces = {
[surface.name] = shape
}
Generate.init({surfaces = surfaces, regen_decoratives = true, tiles_per_tick = 32})
Task.reset_queue()
Task.start_queue()
Task.set_queue_speed(10)
this.chunk_load_tick = game.tick + 500
end
local function on_load()
local this = WPT.get_table()
local surfaces = {
[this.active_surface.name] = shape
}
Generate.init({surfaces = surfaces, regen_decoratives = true, tiles_per_tick = 32})
Generate.register()
Task.start_queue()
end
local function on_player_changed_position(event)
local this = WPT.get_table()
local player = game.players[event.player_index]
local map_name = 'lumberjack'
if string.sub(player.surface.name, 0, #map_name) ~= map_name then
return
end
local position = player.position
local surface = game.surfaces[this.active_surface_index]
if position.x >= Terrain.level_depth * 0.5 then
return
end
if position.x < Terrain.level_depth * -0.5 then
return
end
if
not this.train_reveal and not this.reveal_normally or
this.players[player.index].start_tick and game.tick - this.players[player.index].start_tick < 6400
then
if position.y < 5 then
Terrain.reveal_player(player)
end
end
if position.y >= 74 then
player.teleport({position.x, position.y - 1}, surface)
player.print(grandmaster .. ' Forcefield does not approve.', {r = 0.98, g = 0.66, b = 0.22})
if player.character then
player.character.health = player.character.health - 5
player.character.surface.create_entity({name = 'water-splash', position = position})
if player.character.health <= 0 then
player.character.die('enemy')
end
end
end
end
local function on_player_joined_game(event)
local this = WPT.get_table()
local surface = game.surfaces[this.active_surface_index]
local player = game.players[event.player_index]
set_difficulty(event)
if not this.players then
this.players = {}
end
if not this.players[player.index] then
this.players[player.index] = {
first_join = false,
data = {}
}
end
if not this.players[player.index].first_join then
player.print(grandmaster .. ' Greetings, newly joined ' .. player.name .. '!', {r = 0.98, g = 0.66, b = 0.22})
player.print(grandmaster .. ' Please read the map info.', {r = 0.98, g = 0.66, b = 0.22})
this.players[player.index].first_join = true
end
if player.surface.index ~= this.active_surface_index then
player.teleport(
surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5),
surface
)
for item, amount in pairs(starting_items) do
player.insert({name = item, count = amount})
end
end
end
local function on_player_left_game()
set_difficulty()
end
local function on_pre_player_left_game(event)
local this = WPT.get_table()
local player = game.players[event.player_index]
if player.controller_type == defines.controllers.editor then
player.toggle_map_editor()
end
if player.character then
this.offline_players[#this.offline_players + 1] = {index = event.player_index, tick = game.tick}
end
end
local function offline_players()
local this = WPT.get_table()
local players = this.offline_players
local surface = game.surfaces[this.active_surface_index]
if #players > 0 then
local later = {}
for i = 1, #players, 1 do
if players[i] and game.players[players[i].index] and game.players[players[i].index].connected then
players[i] = nil
else
if players[i] and players[i].tick < game.tick - 54000 then
local player_inv = {}
local items = {}
player_inv[1] = game.players[players[i].index].get_inventory(defines.inventory.character_main)
player_inv[2] = game.players[players[i].index].get_inventory(defines.inventory.character_armor)
player_inv[3] = game.players[players[i].index].get_inventory(defines.inventory.character_guns)
player_inv[4] = game.players[players[i].index].get_inventory(defines.inventory.character_ammo)
player_inv[5] = game.players[players[i].index].get_inventory(defines.inventory.character_trash)
local e =
surface.create_entity(
{
name = 'character',
position = game.forces.player.get_spawn_position(surface),
force = 'neutral'
}
)
local inv = e.get_inventory(defines.inventory.character_main)
for ii = 1, 5, 1 do
if player_inv[ii].valid then
for iii = 1, #player_inv[ii], 1 do
if player_inv[ii][iii].valid then
items[#items + 1] = player_inv[ii][iii]
end
end
end
end
if #items > 0 then
for item = 1, #items, 1 do
if items[item].valid then
inv.insert(items[item])
end
end
game.print({'chronosphere.message_accident'}, {r = 0.98, g = 0.66, b = 0.22})
e.die('neutral')
else
e.destroy()
end
for ii = 1, 5, 1 do
if player_inv[ii].valid then
player_inv[ii].clear()
end
end
players[i] = nil
else
later[#later + 1] = players[i]
end
end
end
players = {}
if #later > 0 then
for i = 1, #later, 1 do
players[#players + 1] = later[i]
end
end
end
end
local function disable_recipes()
local force = game.forces.player
force.recipes['cargo-wagon'].enabled = false
force.recipes['fluid-wagon'].enabled = false
force.recipes['artillery-wagon'].enabled = false
force.recipes['locomotive'].enabled = false
force.recipes['pistol'].enabled = false
end
local function on_research_finished(event)
disable_recipes()
event.research.force.character_inventory_slots_bonus = game.forces.player.mining_drill_productivity_bonus * 50 -- +5 Slots / level
local mining_speed_bonus = game.forces.player.mining_drill_productivity_bonus * 5 -- +50% speed / level
if event.research.force.technologies['steel-axe'].researched then
mining_speed_bonus = mining_speed_bonus + 0.5
end -- +50% speed for steel-axe research
event.research.force.manual_mining_speed_modifier = mining_speed_bonus
end
local function darkness(data)
local rnd = math.random
local this = data.this
local surface = data.surface
if rnd(1, 24) == 1 then
if not this.freeze_daytime then
return
end
game.print(grandmaster .. ' Sunlight, finally!', {r = 0.98, g = 0.66, b = 0.22})
surface.min_brightness = 1
surface.brightness_visual_weights = {1, 0, 0, 0}
surface.daytime = 1
surface.freeze_daytime = false
surface.solar_power_multiplier = 1
this.freeze_daytime = false
return
elseif rnd(1, 64) == 1 then
if this.freeze_daytime then
return
end
game.print(grandmaster .. ' Darkness has surrounded us!', {r = 0.98, g = 0.66, b = 0.22})
game.print(grandmaster .. ' Builds some lamps!', {r = 0.98, g = 0.66, b = 0.22})
surface.min_brightness = 0
surface.brightness_visual_weights = {0.90, 0.90, 0.90}
surface.daytime = 0.42
surface.freeze_daytime = true
surface.solar_power_multiplier = 0
this.freeze_daytime = true
return
end
end
local function transfer_pollution(data)
local Diff = Difficulty.get()
local surface = data.loco_surface
local this = data.this
if not surface then
return
end
local pollution = surface.get_total_pollution() * (3 / (4 / 3 + 1)) * Diff.difficulty_vote_value
game.surfaces[this.active_surface_index].pollute(this.locomotive.position, pollution)
surface.clear_pollution()
end
local tick_minute_functions = {
[300 * 3 + 30 * 6] = darkness,
[300 * 3 + 30 * 6] = transfer_pollution
}
local on_tick = function()
local this = WPT.get_table()
local surface = game.surfaces[this.active_surface_index]
local wave_defense_table = WD.get_table()
local tick = game.tick
local status = Collapse.start_now()
local key = tick % 3600
local unit_surface = this.locomotive.unit_number
local icw_table = ICW.get_table()
if not this.locomotive.valid then
Entities.loco_died()
end
local data = {
this = this,
surface = surface,
loco_surface = game.surfaces[icw_table.wagons[unit_surface].surface.index]
}
if status == true then
goto continue
end
if
this.left_top.y % Terrain.level_depth == 0 and this.left_top.y < 0 and
this.left_top.y > Terrain.level_depth * -10
then
if not Collapse.start_now() then
Collapse.start_now(true)
end
end
::continue::
if game.tick % 30 == 0 then
for _, player in pairs(game.connected_players) do
update_gui(player)
end
if game.tick % 1800 == 0 then
local position = surface.find_non_colliding_position('stone-furnace', Collapse.get_position(), 128, 1)
if position then
wave_defense_table.spawn_position = position
end
offline_players()
Entities.set_scores()
end
end
if tick_minute_functions[key] then
tick_minute_functions[key](data)
end
if this.game_reset_tick then
if this.game_reset_tick < game.tick then
if not this.disable_reset then
this.game_reset_tick = nil
Public.reset_map()
else
if not this.reset_the_game then
game.print('Auto reset is disabled. Server is shutting down!', {r = 0.22, g = 0.88, b = 0.22})
local message = 'Auto reset is disabled. Server is shutting down!'
Server.to_discord_bold(table.concat {'*** ', message, ' ***'})
Server.stop_scenario()
this.reset_the_game = true
end
end
end
return
end
if this.chunk_load_tick then
if this.chunk_load_tick < game.tick then
this.chunk_load_tick = nil
Task.set_queue_speed(1)
end
end
end
local on_init = function()
local this = WPT.get_table()
Public.reset_map()
local tooltip = {
[1] = 'something',
[2] = 'something else',
[3] = 'something else else',
[4] = 'something else else else',
[5] = 'something else else else else',
[6] = 'something else else else else else',
[7] = 'something else else else else else else'
}
Difficulty:set_tooltip(tooltip)
global.custom_highscore.description = 'Wagon distance reached:'
this.rocks_yield_ore_maximum_amount = 500
this.type_modifier = 1
this.rocks_yield_ore_base_amount = 50
this.rocks_yield_ore_distance_modifier = 0.025
local T = Map.Pop_info()
T.main_caption = 'L u m b e r j a c k '
T.sub_caption = 'Chop the wood, toss the wood, save the train, die again!'
T.text =
table.concat(
{
'Welcome lumberlover!\n',
'\n',
'The biters have catched the scent of fish in the cargo wagon.\n',
'Guide the choo and protect it for as long as possible!\n',
'This will not be an easy task however,\n',
'since their strength and numbers increase over time.\n',
'\n',
'Delve deep for greater treasures, but also face increased dangers.\n',
'Mining productivity research, will overhaul your mining equipment,\n',
'reinforcing your pickaxe as well as increasing the size of your backpack.\n',
'\n',
"We've also noticed that solar eclipse occuring, \n",
'we have yet to solve this mystery\n',
'\n',
'Good luck, over and out!'
}
)
T.main_caption_color = {r = 150, g = 150, b = 0}
T.sub_caption_color = {r = 0, g = 150, b = 0}
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()
Explosives.set_destructible_tile('out-of-map', 1500)
Explosives.set_destructible_tile('water', 1000)
Explosives.set_destructible_tile('water-green', 1000)
Explosives.set_destructible_tile('deepwater-green', 1000)
Explosives.set_destructible_tile('deepwater', 1000)
Explosives.set_destructible_tile('water-shallow', 1000)
Generate.register()
end
Event.on_nth_tick(10, on_tick)
Event.on_init(on_init)
Event.on_load(on_load)
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
Event.add(defines.events.on_player_left_game, on_player_left_game)
Event.add(defines.events.on_player_changed_position, on_player_changed_position)
Event.add(defines.events.on_research_finished, on_research_finished)
Event.add(defines.events.on_pre_player_left_game, on_pre_player_left_game)
return Public

View File

@ -1,214 +0,0 @@
local WPT = require 'maps.lumberjack.table'
local Public = {}
local max_spill = 60
local math_random = math.random
local math_floor = math.floor
local math_sqrt = math.sqrt
local valid_types = {
['tree'] = true,
['simple-entity'] = true
}
local function create_particles(surface, name, position, amount, cause_position)
local d1 = (-100 + math_random(0, 200)) * 0.0004
local d2 = (-100 + math_random(0, 200)) * 0.0004
if cause_position then
d1 = (cause_position.x - position.x) * 0.025
d2 = (cause_position.y - position.y) * 0.025
end
for i = 1, amount, 1 do
local m = math_random(4, 10)
local m2 = m * 0.005
surface.create_particle(
{
name = name,
position = position,
frame_speed = 1,
vertical_speed = 0.130,
height = 0,
movement = {
(m2 - (math_random(0, m) * 0.01)) + d1,
(m2 - (math_random(0, m) * 0.01)) + d2
}
}
)
end
end
local function mining_chances_ores()
local data = {
{name = 'iron-ore', chance = 545},
{name = 'copper-ore', chance = 545},
{name = 'coal', chance = 545},
{name = 'stone', chance = 545},
{name = 'uranium-ore', chance = 200}
}
return data
end
local harvest_raffle_ores = {}
for _, t in pairs(mining_chances_ores()) do
for _ = 1, t.chance, 1 do
table.insert(harvest_raffle_ores, t.name)
end
end
local size_of_ore_raffle = #harvest_raffle_ores
local function get_amount(data)
local entity = data.entity
local this = data.this
local distance_to_center = math_floor(math_sqrt(entity.position.x ^ 2 + entity.position.y ^ 2))
local type_modifier
local amount
local second_amount
local distance_modifier = 0.25
local base_amount = 25
local second_base_amount = 10
local maximum_amount = 100
if this.type_modifier then
type_modifier = this.type_modifier
end
if this.rocks_yield_ore_distance_modifier then
distance_modifier = this.rocks_yield_ore_distance_modifier
end
if this.rocks_yield_ore_base_amount then
base_amount = this.rocks_yield_ore_base_amount
end
if this.rocks_yield_ore_maximum_amount then
maximum_amount = this.rocks_yield_ore_maximum_amount
end
amount = base_amount + (distance_to_center * distance_modifier)
second_amount = math_floor((second_base_amount + (distance_to_center * distance_modifier)) / 3)
if amount > maximum_amount then
amount = maximum_amount
end
if second_amount > maximum_amount then
second_amount = maximum_amount
end
local m = (70 + math_random(0, 60)) * 0.01
amount = math_floor(amount * type_modifier * m * 0.7)
return amount, second_amount
end
local function randomness(data)
local entity = data.entity
local player = data.player
local harvest
local second_harvest
local harvest_amount
local second_harvest_amount
if entity.type == 'simple-entity' then
harvest = harvest_raffle_ores[math.random(1, size_of_ore_raffle)]
second_harvest = 'stone'
harvest_amount, second_harvest_amount = get_amount(data)
else
harvest = harvest_raffle_ores[math.random(1, size_of_ore_raffle)]
second_harvest = 'wood'
harvest_amount, second_harvest_amount = get_amount(data)
end
local position = {x = entity.position.x, y = entity.position.y}
if second_harvest then
player.surface.create_entity(
{
name = 'flying-text',
position = position,
text = '+' ..
harvest_amount ..
' [img=item/' ..
harvest .. ']\n+' .. second_harvest_amount .. ' [img=item/' .. second_harvest .. ']',
color = {r = math_random(1, 200), g = 160, b = 30}
}
)
player.insert({name = second_harvest, count = second_harvest_amount})
else
player.surface.create_entity(
{
name = 'flying-text',
position = position,
text = '+' .. harvest_amount .. ' [img=item/' .. harvest .. ']',
color = {r = math_random(1, 200), g = 160, b = 30}
}
)
end
if harvest_amount > max_spill then
player.surface.spill_item_stack(position, {name = harvest, count = max_spill}, true)
harvest_amount = harvest_amount - max_spill
local inserted_count = player.insert({name = harvest, count = harvest_amount})
harvest_amount = harvest_amount - inserted_count
if harvest_amount > 0 then
player.surface.spill_item_stack(position, {name = harvest, count = harvest_amount}, true)
end
else
player.surface.spill_item_stack(position, {name = harvest, count = harvest_amount}, true)
end
create_particles(player.surface, 'shell-particle', position, 64, {x = player.position.x, y = player.position.y})
end
function Public.on_player_mined_entity(event)
local entity = event.entity
if not entity.valid then
return
end
if not valid_types[entity.type] then
return
end
local player = game.players[event.player_index]
local this = WPT.get_table()
if not player then
return
end
event.buffer.clear()
local data = {
this = this,
entity = entity,
player = player
}
randomness(data)
end
function Public.on_entity_died(event)
if not event.entity.valid then
return
end
if event.entity.type == 'tree' then
for _, entity in pairs(
event.entity.surface.find_entities_filtered(
{
area = {
{event.entity.position.x - 4, event.entity.position.y - 4},
{event.entity.position.x + 4, event.entity.position.y + 4}
},
name = 'fire-flame-on-tree'
}
)
) do
if entity.valid then
entity.destroy()
end
end
end
end
return Public

View File

@ -1,661 +0,0 @@
local Event = require 'utils.event'
local play_time = require 'utils.datastore.session_data'
local Tabs = require 'comfy_panel.main'
local RPG = require 'maps.lumberjack.rpg'
local symbol_asc = ''
local symbol_desc = ''
local pokemessages = {
'a stick',
'a leaf',
'a moldy carrot',
'a crispy slice of bacon',
'a french fry',
'a realistic toygun',
'a broomstick',
'a thirteen inch iron stick',
'a mechanical keyboard',
'a fly fishing cane',
'a selfie stick',
'an oversized fidget spinner',
'a thumb extender',
'a dirty straw',
'a green bean',
'a banana',
'an umbrella',
"grandpa's walking stick",
'live firework',
'a toilet brush',
'a fake hand',
'an undercooked hotdog',
"a slice of yesterday's microwaved pizza",
'bubblegum',
'a biter leg',
"grandma's toothbrush",
'charred octopus',
'a dollhouse bathtub',
'a length of copper wire',
'a decommissioned nuke',
'a smelly trout',
'an unopened can of deodorant',
'a stone brick',
'a half full barrel of lube',
'a half empty barrel of lube',
'an unexploded cannon shell',
'a blasting programmable speaker',
'a not so straight rail',
'a mismatched pipe to ground',
'a surplus box of landmines',
'decommissioned yellow rounds',
'an oily pumpjack shaft',
'a melted plastic bar in the shape of the virgin mary',
'a bottle of watermelon vitamin water',
'a slice of watermelon',
'a stegosaurus tibia',
"a basking musician's clarinet",
'a twig',
'an undisclosed pokey item',
'a childhood trophy everyone else got',
'a dead starfish',
'a titanium toothpick',
'a nail file',
'a stamp collection',
'a bucket of lego',
'a rolled up carpet',
'a rolled up WELCOME doormat',
"Bobby's favorite bone",
'an empty bottle of cheap vodka',
'a tattooing needle',
'a peeled cucumber',
'a stack of cotton candy',
'a signed baseball bat',
'that 5 dollar bill grandma sent for christmas',
'a stack of overdue phone bills',
"the 'relax' section of the white pages",
'a bag of gym clothes which never made it to the washing machine',
'a handful of peanut butter',
"a pheasant's feather",
'a rusty pickaxe',
'a diamond sword',
'the bill of rights of a banana republic',
"one of those giant airport Toblerone's",
'a long handed inserter',
'a wiimote',
'an easter chocolate rabbit',
'a ball of yarn the cat threw up',
'a slightly expired but perfectly edible cheese sandwich',
'conclusive proof of lizard people existence',
'a pen drive full of high res wallpapers',
'a pet hamster',
'an oversized goldfish',
'a one foot extension cord',
"a CD from Walmart's 1 dollar bucket",
'a magic wand',
'a list of disappointed people who believed in you',
'murder exhibit no. 3',
"a paperback copy of 'Great Expectations'",
'a baby biter',
'a little biter fang',
'the latest diet fad',
'a belt that no longer fits you',
'an abandoned pet rock',
'a lava lamp',
'some spirit herbs',
'a box of fish sticks found at the back of the freezer',
'a bowl of tofu rice',
'a bowl of ramen noodles',
'a live lobster!',
'a miniature golf cart',
'dunce cap',
'a fully furnished x-mas tree',
'an orphaned power pole',
'an horphaned power pole',
'an box of overpriced girl scout cookies',
'the cheapest item from the yard sale',
'a Sharpie',
'a glowstick',
'a thick unibrow hair',
'a very detailed map of Kazakhstan',
'the official Factorio installation DVD',
'a Liberal Arts degree',
'a pitcher of Kool-Aid',
'a 1/4 pound vegan burrito',
'a bottle of expensive wine',
'a hamster sized gravestone',
'a counterfeit Cuban cigar',
'an old Nokia phone',
'a huge inferiority complex',
'a dead real state agent',
'a deck of tarot cards',
'unreleased Wikileaks documents',
'a mean-looking garden dwarf',
'the actual mythological OBESE cat',
'a telescope used to spy on the MILF next door',
'a fancy candelabra',
'the comic version of the Kama Sutra',
"an inflatable 'Netflix & chill' doll",
'whatever it is redlabel gets high on',
"Obama's birth certificate",
'a deck of Cards Against Humanity',
'a copy of META MEME HUMOR for Dummies',
'an abandoned, not-so-young-anymore puppy',
'one of those useless items advertised on TV',
'a genetic blueprint of a Japanese teen idol'
}
local function get_formatted_playtime(x)
if x < 5184000 then
local y = x / 216000
y = tostring(y)
local h = ''
for i = 1, 10, 1 do
local z = string.sub(y, i, i)
if z == '.' then
break
else
h = h .. z
end
end
local m = x % 216000
m = m / 3600
m = math.floor(m)
m = tostring(m)
if h == '0' then
local str = m .. ' minutes'
return str
else
local str = h .. ' hours '
str = str .. m
str = str .. ' minutes'
return str
end
else
local y = x / 5184000
y = tostring(y)
local h = ''
for i = 1, 10, 1 do
local z = string.sub(y, i, i)
if z == '.' then
break
else
h = h .. z
end
end
local m = x % 5184000
m = m / 216000
m = math.floor(m)
m = tostring(m)
if h == '0' then
local str = m .. ' days'
return str
else
local str = h .. ' days '
str = str .. m
str = str .. ' hours'
return str
end
end
end
local function get_rank(player)
local play_table = play_time.get_session_table()
local t = 0
if play_table then
if play_table[player.name] then
t = play_table[player.name]
end
end
local m = (player.online_time + t) / 3600
local ranks = {
'item/burner-mining-drill',
'item/burner-inserter',
'item/stone-furnace',
'item/light-armor',
'item/steam-engine',
'item/inserter',
'item/transport-belt',
'item/underground-belt',
'item/splitter',
'item/assembling-machine-1',
'item/long-handed-inserter',
'item/electronic-circuit',
'item/electric-mining-drill',
'item/dummy-steel-axe',
'item/heavy-armor',
'item/steel-furnace',
'item/gun-turret',
'item/fast-transport-belt',
'item/fast-underground-belt',
'item/fast-splitter',
'item/assembling-machine-2',
'item/fast-inserter',
'item/radar',
'item/filter-inserter',
'item/defender-capsule',
'item/pumpjack',
'item/chemical-plant',
'item/solar-panel',
'item/advanced-circuit',
'item/modular-armor',
'item/accumulator',
'item/construction-robot',
'item/distractor-capsule',
'item/stack-inserter',
'item/electric-furnace',
'item/express-transport-belt',
'item/express-underground-belt',
'item/express-splitter',
'item/assembling-machine-3',
'item/processing-unit',
'item/power-armor',
'item/logistic-robot',
'item/laser-turret',
'item/stack-filter-inserter',
'item/destroyer-capsule',
'item/power-armor-mk2',
'item/flamethrower-turret',
'item/beacon',
'item/steam-turbine',
'item/centrifuge',
'item/nuclear-reactor'
}
--52 ranks
local time_needed = 240 -- in minutes between rank upgrades
m = m / time_needed
m = math.floor(m)
m = m + 1
if m > #ranks then
m = #ranks
end
return ranks[m]
end
local comparators = {
['pokes_asc'] = function(a, b)
return a.pokes > b.pokes
end,
['pokes_desc'] = function(a, b)
return a.pokes < b.pokes
end,
['total_time_played_asc'] = function(a, b)
return a.total_played_ticks < b.total_played_ticks
end,
['total_time_played_desc'] = function(a, b)
return a.total_played_ticks > b.total_played_ticks
end,
['time_played_asc'] = function(a, b)
return a.played_ticks < b.played_ticks
end,
['time_played_desc'] = function(a, b)
return a.played_ticks > b.played_ticks
end,
['rpg_asc'] = function(a, b)
return a.rpg_level < b.rpg_level
end,
['rpg_desc'] = function(a, b)
return a.rpg_level > b.rpg_level
end,
['name_asc'] = function(a, b)
return a.name:lower() < b.name:lower()
end,
['name_desc'] = function(a, b)
return a.name:lower() > b.name:lower()
end
}
local function get_comparator(sort_by)
return comparators[sort_by]
end
local function get_sorted_list(sort_by)
local play_table = play_time.get_session_table()
local rpg_t = RPG.get_table()
local player_list = {}
for i, player in pairs(game.connected_players) do
player_list[i] = {}
player_list[i].rank = get_rank(player)
player_list[i].name = player.name
local t = 0
if play_table[player.name] then
t = play_table[player.name]
end
player_list[i].rpg_level = rpg_t[player.index].level
player_list[i].total_played_time = get_formatted_playtime(t + player.online_time)
player_list[i].total_played_ticks = t + player.online_time
player_list[i].played_time = get_formatted_playtime(player.online_time)
player_list[i].played_ticks = player.online_time
player_list[i].pokes = global.player_list.pokes[player.index]
player_list[i].player_index = player.index
end
local comparator = get_comparator(sort_by)
table.sort(player_list, comparator)
return player_list
end
local function player_list_show(player, frame, sort_by)
local label
-- Frame management
frame.clear()
frame.style.padding = 8
-- Header management
local t = frame.add {type = 'table', name = 'player_list_panel_header_table', column_count = 6}
local column_widths = {tonumber(60), tonumber(150), tonumber(125), tonumber(150), tonumber(150), tonumber(100)}
for _, w in ipairs(column_widths) do
label = t.add {type = 'label', caption = ''}
label.style.minimal_width = w
label.style.maximal_width = w
end
local headers = {
[1] = '[color=0.1,0.7,0.1]' .. -- green
tostring(#game.connected_players) .. '[/color]',
[2] = 'Online' ..
' / ' ..
'[color=0.7,0.1,0.1]' .. -- red
tostring(#game.players - #game.connected_players) .. '[/color]' .. ' Offline',
[3] = 'RPG level',
[4] = 'Total Time',
[5] = 'Current Time',
[6] = 'Poke'
}
local header_modifier = {
['name_asc'] = function(h)
h[2] = symbol_asc .. h[2]
end,
['name_desc'] = function(h)
h[2] = symbol_desc .. h[2]
end,
['rpg_asc'] = function(h)
h[3] = symbol_asc .. h[3]
end,
['rpg_desc'] = function(h)
h[3] = symbol_desc .. h[3]
end,
['total_time_played_asc'] = function(h)
h[4] = symbol_asc .. h[4]
end,
['total_time_played_desc'] = function(h)
h[4] = symbol_desc .. h[4]
end,
['time_played_asc'] = function(h)
h[5] = symbol_asc .. h[5]
end,
['time_played_desc'] = function(h)
h[5] = symbol_desc .. h[5]
end,
['pokes_asc'] = function(h)
h[6] = symbol_asc .. h[6]
end,
['pokes_desc'] = function(h)
h[6] = symbol_desc .. h[6]
end
}
if sort_by then
global.player_list.sorting_method[player.index] = sort_by
else
sort_by = global.player_list.sorting_method[player.index]
end
header_modifier[sort_by](headers)
for k, v in ipairs(headers) do
label =
t.add {
type = 'label',
name = 'player_list_panel_header_' .. k,
caption = v
}
label.style.font = 'default-bold'
label.style.font_color = {r = 0.98, g = 0.66, b = 0.22}
end
-- special style on first header
label = t['player_list_panel_header_1']
label.style.minimal_width = 36
label.style.maximal_width = 36
label.style.horizontal_align = 'right'
-- List management
local player_list_panel_table =
frame.add {
type = 'scroll-pane',
name = 'scroll_pane',
direction = 'vertical',
horizontal_scroll_policy = 'never',
vertical_scroll_policy = 'auto'
}
player_list_panel_table.style.maximal_height = 530
player_list_panel_table =
player_list_panel_table.add {type = 'table', name = 'player_list_panel_table', column_count = 6}
local player_list = get_sorted_list(sort_by)
for i = 1, #player_list, 1 do
-- Icon
local sprite =
player_list_panel_table.add {
type = 'sprite',
name = 'player_rank_sprite_' .. i,
sprite = player_list[i].rank
}
sprite.style.minimal_width = column_widths[1]
sprite.style.maximal_width = column_widths[1]
-- Name
label =
player_list_panel_table.add {
type = 'label',
name = 'player_list_panel_player_names_' .. i,
caption = player_list[i].name
}
label.style.font = 'default'
label.style.font_color = {
r = .4 + game.players[player_list[i].player_index].color.r * 0.6,
g = .4 + game.players[player_list[i].player_index].color.g * 0.6,
b = .4 + game.players[player_list[i].player_index].color.b * 0.6
}
label.style.minimal_width = column_widths[2]
label.style.maximal_width = column_widths[2]
-- RPG level
label =
player_list_panel_table.add {
type = 'label',
name = 'player_list_panel_RPG_level_' .. i,
caption = player_list[i].rpg_level
}
label.style.minimal_width = column_widths[3]
label.style.maximal_width = column_widths[3]
-- Total time
label =
player_list_panel_table.add {
type = 'label',
name = 'player_list_panel_player_total_time_played_' .. i,
caption = player_list[i].total_played_time
}
label.style.minimal_width = column_widths[4]
label.style.maximal_width = column_widths[4]
-- Current time
label =
player_list_panel_table.add {
type = 'label',
name = 'player_list_panel_player_time_played_' .. i,
caption = player_list[i].played_time
}
label.style.minimal_width = column_widths[5]
label.style.maximal_width = column_widths[5]
-- Poke
local flow = player_list_panel_table.add {type = 'flow', name = 'button_flow_' .. i, direction = 'horizontal'}
flow.add {type = 'label', name = 'button_spacer_' .. i, caption = ''}
local button =
flow.add {type = 'button', name = 'poke_player_' .. player_list[i].name, caption = player_list[i].pokes}
button.style.font = 'default'
label.style.font_color = {r = 0.83, g = 0.83, b = 0.83}
button.style.minimal_height = 30
button.style.minimal_width = 30
button.style.maximal_height = 30
button.style.maximal_width = 30
button.style.top_padding = 0
button.style.left_padding = 0
button.style.right_padding = 0
button.style.bottom_padding = 0
end
end
local function on_gui_click(event)
if not event then
return
end
if not event.element then
return
end
if not event.element.valid then
return
end
if not event.element.name then
return
end
local player = game.players[event.element.player_index]
local frame = Tabs.comfy_panel_get_active_frame(player)
if not frame then
return
end
if frame.name ~= 'Players' then
return
end
local name = event.element.name
local actions = {
['player_list_panel_header_2'] = function()
if string.find(event.element.caption, symbol_desc) then
player_list_show(player, frame, 'name_asc')
else
player_list_show(player, frame, 'name_desc')
end
end,
['player_list_panel_header_3'] = function()
if string.find(event.element.caption, symbol_desc) then
player_list_show(player, frame, 'rpg_asc')
else
player_list_show(player, frame, 'rpg_desc')
end
end,
['player_list_panel_header_4'] = function()
if string.find(event.element.caption, symbol_desc) then
player_list_show(player, frame, 'total_time_played_asc')
else
player_list_show(player, frame, 'total_time_played_desc')
end
end,
['player_list_panel_header_5'] = function()
if string.find(event.element.caption, symbol_desc) then
player_list_show(player, frame, 'time_played_asc')
else
player_list_show(player, frame, 'time_played_desc')
end
end,
['player_list_panel_header_6'] = function()
if string.find(event.element.caption, symbol_desc) then
player_list_show(player, frame, 'pokes_asc')
else
player_list_show(player, frame, 'pokes_desc')
end
end
}
if actions[name] then
actions[name]()
return
end
if not event.element.valid then
return
end
--Poke other players
if string.sub(event.element.name, 1, 11) == 'poke_player' then
local poked_player = string.sub(event.element.name, 13, string.len(event.element.name))
if player.name == poked_player then
return
end
if global.player_list.last_poke_tick[event.element.player_index] + 300 < game.tick then
local str = '>> '
str = str .. player.name
str = str .. ' has poked '
str = str .. poked_player
str = str .. ' with '
local z = math.random(1, #pokemessages)
str = str .. pokemessages[z]
str = str .. ' <<'
game.print(str)
global.player_list.last_poke_tick[event.element.player_index] = game.tick
local p = game.players[poked_player]
global.player_list.pokes[p.index] = global.player_list.pokes[p.index] + 1
end
end
end
local function refresh()
for _, player in pairs(game.connected_players) do
local frame = Tabs.comfy_panel_get_active_frame(player)
if frame then
if frame.name ~= 'Players' then
return
end
player_list_show(player, frame, global.player_list.sorting_method[player.index])
end
end
end
local function on_player_joined_game(event)
if not global.player_list.last_poke_tick[event.player_index] then
global.player_list.pokes[event.player_index] = 0
global.player_list.last_poke_tick[event.player_index] = 0
global.player_list.sorting_method[event.player_index] = 'total_time_played_desc'
end
refresh()
end
local function on_player_left_game()
refresh()
end
local on_init = function()
global.player_list = {}
global.player_list.last_poke_tick = {}
global.player_list.pokes = {}
global.player_list.sorting_method = {}
end
comfy_panel_tabs['Players'] = {gui = player_list_show, admin = false}
Event.on_init(on_init)
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
Event.add(defines.events.on_player_left_game, on_player_left_game)
Event.add(defines.events.on_gui_click, on_gui_click)

View File

@ -1,67 +0,0 @@
local Event = require 'utils.event'
local WPT = require 'maps.lumberjack.table'
local function balance(t)
local g = 0
local c = 0
for k, v in pairs(t) do
if (v.valid) then
g = g + v.energy
c = c + v.electric_buffer_size
end
end
for k, v in pairs(t) do
if (v.valid) then
local r = (v.electric_buffer_size / c)
v.energy = g * r
end
end
end
local function tick()
local this = WPT.get_table()
if not this.energy['lumberjack'] then
this.energy['lumberjack'] = this.ow_energy
end
if not this.energy['loco'] then
this.energy['loco'] = this.lo_energy
end
local lumberjack = this.energy['lumberjack']
local loco = this.energy['loco']
if not lumberjack or not loco then
return
end
if not lumberjack.valid or not loco.valid then
return
end
balance(this.energy)
end
local function built_entity(event)
local entity = event.created_entity
if not entity.valid then
return
end
local player = game.players[event.player_index]
local surface = entity.surface
local map_name = 'lumberjack'
if surface.name ~= map_name then
return
end
if
entity.name == 'steam-engine' or entity.name == 'steam-turbine' or entity.name == 'lab' or
entity.name == 'rocket-silo'
then
if not entity.valid then
return
end
player.print('"' .. entity.name .. '" Does not seem to work down here, thats strange!', {r = 1, g = 0, b = 0})
entity.active = false
end
end
Event.add(defines.events.on_tick, tick)
--Event.add(defines.events.on_built_entity, built_entity)

File diff suppressed because it is too large Load Diff

View File

@ -1,95 +0,0 @@
local Server = require 'utils.server'
local Modifers = require 'player_modifiers'
local WPT = require 'maps.lumberjack.table'
local grandmaster = '[color=blue]Grandmaster:[/color]'
local Public = {}
local function reset_forces(new_surface, old_surface)
for _, f in pairs(game.forces) do
local spawn = {
x = game.forces.player.get_spawn_position(old_surface).x,
y = game.forces.player.get_spawn_position(old_surface).y
}
f.reset()
f.reset_evolution()
f.set_spawn_position(spawn, new_surface)
end
for _, tech in pairs(game.forces.player.technologies) do
tech.researched = false
game.forces.player.set_saved_technology_progress(tech, 0)
end
end
local function teleport_players(surface)
game.forces.player.set_spawn_position({0, 21}, surface)
for _, player in pairs(game.connected_players) do
player.teleport(
surface.find_non_colliding_position('character', game.forces.player.get_spawn_position(surface), 3, 0, 5),
surface
)
end
end
local function equip_players(player_starting_items)
for k, player in pairs(game.connected_players) do
if player.character then
player.character.destroy()
end
player.character = nil
player.set_controller({type = defines.controllers.god})
player.create_character()
for item, amount in pairs(player_starting_items) do
player.insert({name = item, count = amount})
end
Modifers.update_player_modifiers(player)
end
end
function Public.soft_reset_map(old_surface, map_gen_settings, player_starting_items)
local this = WPT.get_table()
if not this.soft_reset_counter then
this.soft_reset_counter = 0
end
if not this.original_surface_name then
this.original_surface_name = old_surface.name
end
this.soft_reset_counter = this.soft_reset_counter + 1
local new_surface =
game.create_surface(this.original_surface_name .. '_' .. tostring(this.soft_reset_counter), map_gen_settings)
new_surface.request_to_generate_chunks({0, 0}, 0.5)
new_surface.force_generate_chunk_requests()
reset_forces(new_surface, old_surface)
teleport_players(new_surface)
equip_players(player_starting_items)
game.delete_surface(old_surface)
local message = table.concat({grandmaster .. ' Welcome to ', this.original_surface_name, '!'})
local message_to_discord = table.concat({'** Welcome to ', this.original_surface_name, '! **'})
if this.soft_reset_counter > 1 then
message =
table.concat(
{
grandmaster,
' The world has been reshaped, welcome to ',
this.original_surface_name,
' number ',
tostring(this.soft_reset_counter),
'!'
}
)
end
game.print(message, {r = 0.98, g = 0.66, b = 0.22})
Server.to_discord_embed(message_to_discord)
return new_surface
end
return Public

View File

@ -1,76 +0,0 @@
-- on table to rule them all!
local Global = require 'utils.global'
local Event = require 'utils.event'
local this = {
train_reveal = true,
energy_shared = true,
reveal_normally = false,
disable_reset = false
}
local Public = {}
Global.register(
this,
function(tbl)
this = tbl
end
)
function Public.reset_table()
--for k, _ in pairs(this) do
-- this[k] = nil
--end
this.lo_energy = nil
this.ow_energy = nil
this.dummy = nil
this.game_lost = false
this.game_won = false
this.energy = {}
this.wave_counter = 0
this.locomotive_health = 10000
this.locomotive_max_health = 10000
this.cargo_health = 10000
this.cargo_max_health = 10000
this.revealed_spawn = 0
this.left_top = {
x = 0,
y = 0
}
this.train_upgrades = 0
this.energy_purchased = false
this.freeze_daytime = false
this.offline_players = {}
this.biter_pets = {}
this.mined_scrap = 0
this.biters_killed = 0
this.locomotive_xp_aura = 40
this.randomness = 0
this.xp_points = 0
this.xp_points_upgrade = 0
this.aura_upgrades = 0
this.health_upgrades = 0
this.threat_upgrades = 0
end
function Public.get_table()
return this
end
function Public.init(args)
if args then
this.train_reveal = args.train_reveal
this.energy_shared = args.energy_shared
this.reveal_normally = args.reveal_normally
else
return error('Not a valid init argument', 2)
end
end
local on_init = function()
Public.reset_table()
end
Event.on_init(on_init)
return Public

File diff suppressed because it is too large Load Diff

View File

@ -64,6 +64,43 @@ local function delete_empty_surfaces(icw)
end
end
local function kick_players_from_surface(wagon)
if not validate_entity(wagon.surface) then
return print('Surface was not valid.')
end
if not wagon.entity or not wagon.entity.valid then
local main_surface = wagon.surface
if validate_entity(main_surface) then
for _, e in pairs(wagon.surface.find_entities_filtered({area = wagon.area})) do
if validate_entity(e) and e.name == 'character' and e.player then
e.player.teleport(
main_surface.find_non_colliding_position(
'character',
game.forces.player.get_spawn_position(main_surface),
3,
0,
5
),
main_surface
)
end
end
end
return print('Wagon entity was not valid.')
end
for _, e in pairs(wagon.surface.find_entities_filtered({area = wagon.area})) do
if validate_entity(e) and e.name == 'character' and e.player then
local p = wagon.entity.surface.find_non_colliding_position('character', wagon.entity.position, 128, 0.5)
if p then
e.player.teleport(p, wagon.entity.surface)
else
e.player.teleport(wagon.entity.position, wagon.entity.surface)
end
end
end
end
local function kick_players_out_of_vehicles(wagon)
for _, player in pairs(game.connected_players) do
local character = player.character
@ -345,6 +382,7 @@ function Public.kill_wagon(icw, entity)
end
local wagon = icw.wagons[entity.unit_number]
local surface = wagon.surface
kick_players_from_surface(wagon)
kick_players_out_of_vehicles(wagon)
kill_wagon_doors(icw, wagon)
for _, e in pairs(surface.find_entities_filtered({area = wagon.area})) do
@ -910,7 +948,7 @@ local function move_room_to_train(icw, train, wagon)
then
return
end
kick_players_from_surface(wagon)
kick_players_out_of_vehicles(wagon)
local player_positions = {}
teleport_char(player_positions, destination_area, wagon)

View File

@ -720,7 +720,7 @@ local function gui_opened(event)
{
type = 'slider',
minimum_value = 1,
maximum_value = 1000,
maximum_value = 1e2,
value = 1
}
)
@ -779,7 +779,7 @@ local function gui_click(event)
return
elseif name == 'more' then
local slider_value = data.slider.slider_value
if slider_value < 1000 then
if slider_value <= 1e2 then
data.slider.slider_value = slider_value + 1
data.quantity_input.text = data.slider.slider_value
redraw_market_items(data.item_frame, player, data.search_text)