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:
commit
e4117f9648
@ -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
|
@ -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
|
@ -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)
|
@ -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
|
@ -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)
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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)
|
@ -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
@ -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
|
@ -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
@ -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)
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user