From 78cba7f311c166d603d36f7ddfa944dea87fc2be Mon Sep 17 00:00:00 2001 From: Gerkiz Date: Thu, 9 Jul 2020 14:26:07 +0200 Subject: [PATCH] minor changes --- comfy_panel/score.lua | 671 +++++++++++--------- maps/fish_defender/bouncy_shells.lua | 5 +- maps/fish_defender/crumbly_walls.lua | 4 +- maps/fish_defender/main.lua | 211 +++--- maps/fish_defender/table.lua | 3 +- maps/fish_defender/terrain.lua | 12 +- maps/mountain_fortress_v3/basic_markets.lua | 10 +- maps/mountain_fortress_v3/main.lua | 10 +- modules/biters_yield_coins.lua | 180 +++--- utils/core.lua | 24 +- utils/jail_data.lua | 180 +++--- 11 files changed, 752 insertions(+), 558 deletions(-) diff --git a/comfy_panel/score.lua b/comfy_panel/score.lua index 44992d43..68d32672 100644 --- a/comfy_panel/score.lua +++ b/comfy_panel/score.lua @@ -6,373 +6,463 @@ local Tabs = require 'comfy_panel.main' local Public = {} local this = { - score_table = {}, - sort_by = {} + score_table = {}, + sort_by = {} } Global.register( - this, - function(t) - this = t - end + this, + function(t) + this = t + end ) -local sorting_symbol = {ascending = "▲", descending = "▼"} +local sorting_symbol = {ascending = '▲', descending = '▼'} local building_and_mining_blacklist = { - ["tile-ghost"] = true, - ["entity-ghost"] = true, - ["item-entity"] = true, + ['tile-ghost'] = true, + ['entity-ghost'] = true, + ['item-entity'] = true } function Public.get_table() - return this + return this end -local function init_player_table(player) - if not player then return end - if not this.score_table[player.force.name] then this.score_table[player.force.name] = {} end - if not this.score_table[player.force.name].players then this.score_table[player.force.name].players = {} end - if not this.score_table[player.force.name].players[player.name] then - this.score_table[player.force.name].players[player.name] = { - built_entities = 0, - deaths = 0, - killscore = 0, - mined_entities = 0, - } - end +function Public.init_player_table(player) + if not player then + return + end + if not this.score_table[player.force.name] then + this.score_table[player.force.name] = {} + end + if not this.score_table[player.force.name].players then + this.score_table[player.force.name].players = {} + end + if not this.score_table[player.force.name].players[player.name] then + this.score_table[player.force.name].players[player.name] = { + built_entities = 0, + deaths = 0, + killscore = 0, + mined_entities = 0 + } + end end local function get_score_list(force) - local score_force = this.score_table[force] - local score_list = {} - for _, p in pairs(game.connected_players) do - if score_force.players[p.name] then - local score = score_force.players[p.name] - table.insert(score_list, { - name = p.name, - killscore = score.killscore or 0, - deaths = score.deaths or 0, - built_entities = score.built_entities or 0, - mined_entities = score.mined_entities or 0, - }) - end - end - return score_list + local score_force = this.score_table[force] + local score_list = {} + for _, p in pairs(game.connected_players) do + if score_force.players[p.name] then + local score = score_force.players[p.name] + table.insert( + score_list, + { + name = p.name, + killscore = score.killscore or 0, + deaths = score.deaths or 0, + built_entities = score.built_entities or 0, + mined_entities = score.mined_entities or 0 + } + ) + end + end + return score_list end local function get_sorted_list(method, column_name, score_list) - local comparators = { - ["ascending"] = function(a,b) return a[column_name] < b[column_name] end, - ["descending"] = function(a,b) return a[column_name] > b[column_name] end - } - table.sort(score_list, comparators[method]) - return score_list + local comparators = { + ['ascending'] = function(a, b) + return a[column_name] < b[column_name] + end, + ['descending'] = function(a, b) + return a[column_name] > b[column_name] + end + } + table.sort(score_list, comparators[method]) + return score_list end -local biters = {"small-biter", "medium-biter", "big-biter", "behemoth-biter", "small-spitter", "medium-spitter", "big-spitter", "behemoth-spitter"} +local biters = { + 'small-biter', + 'medium-biter', + 'big-biter', + 'behemoth-biter', + 'small-spitter', + 'medium-spitter', + 'big-spitter', + 'behemoth-spitter' +} local function get_total_biter_killcount(force) - local count = 0 - for _, biter in pairs(biters) do - count = count + force.kill_count_statistics.get_input_count(biter) - end - return count + local count = 0 + for _, biter in pairs(biters) do + count = count + force.kill_count_statistics.get_input_count(biter) + end + return count end local function add_global_stats(frame, player) - local score = this.score_table[player.force.name] - local t = frame.add { type = "table", column_count = 5} + local score = this.score_table[player.force.name] + local t = frame.add {type = 'table', column_count = 5} - local l = t.add { type = "label", caption = "Rockets launched: "} - l.style.font = "default-game" - l.style.font_color = {r = 175, g = 75, b = 255} - l.style.minimal_width = 140 + local l = t.add {type = 'label', caption = 'Rockets launched: '} + l.style.font = 'default-game' + l.style.font_color = {r = 175, g = 75, b = 255} + l.style.minimal_width = 140 - local l = t.add { type = "label", caption = player.force.rockets_launched} - l.style.font = "default-listbox" - l.style.font_color = { r=0.9, g=0.9, b=0.9} - l.style.minimal_width = 123 + local l = t.add {type = 'label', caption = player.force.rockets_launched} + l.style.font = 'default-listbox' + l.style.font_color = {r = 0.9, g = 0.9, b = 0.9} + l.style.minimal_width = 123 - local l = t.add { type = "label", caption = "Dead bugs: "} - l.style.font = "default-game" - l.style.font_color = { r=0.90, g=0.3, b=0.3} - l.style.minimal_width = 100 + local l = t.add {type = 'label', caption = 'Dead bugs: '} + l.style.font = 'default-game' + l.style.font_color = {r = 0.90, g = 0.3, b = 0.3} + l.style.minimal_width = 100 - local l = t.add { type = "label", caption = tostring(get_total_biter_killcount(player.force))} - l.style.font = "default-listbox" - l.style.font_color = { r=0.9, g=0.9, b=0.9} - l.style.minimal_width = 145 + local l = t.add {type = 'label', caption = tostring(get_total_biter_killcount(player.force))} + l.style.font = 'default-listbox' + l.style.font_color = {r = 0.9, g = 0.9, b = 0.9} + l.style.minimal_width = 145 - local l = t.add { type = "checkbox", caption = "Show floating numbers", state = global.show_floating_killscore[player.name], name = "show_floating_killscore_texts" } - l.style.font_color = { r=0.8, g=0.8, b=0.8} + local l = + t.add { + type = 'checkbox', + caption = 'Show floating numbers', + state = global.show_floating_killscore[player.name], + name = 'show_floating_killscore_texts' + } + l.style.font_color = {r = 0.8, g = 0.8, b = 0.8} end -local show_score = (function (player, frame) - frame.clear() +local show_score = (function(player, frame) + frame.clear() - init_player_table(player) + Public.init_player_table(player) - -- Global stats : rockets, biters kills - add_global_stats(frame, player) + -- Global stats : rockets, biters kills + add_global_stats(frame, player) - -- Separator - local line = frame.add { type = "line"} - line.style.top_margin = 8 - line.style.bottom_margin = 8 - - -- Score per player - local t = frame.add { type = "table", column_count = 5 } + -- Separator + local line = frame.add {type = 'line'} + line.style.top_margin = 8 + line.style.bottom_margin = 8 - -- Score headers - local headers = { - { name = "score_player", caption = "Player" }, - { column = "killscore", name = "score_killscore", caption = "Killscore" }, - { column = "deaths", name = "score_deaths", caption = "Deaths" }, - { column = "built_entities", name = "score_built_entities", caption = "Built structures" }, - { column = "mined_entities", name = "score_mined_entities", caption = "Mined entities" } - } + -- Score per player + local t = frame.add {type = 'table', column_count = 5} - local sorting_pref = this.sort_by[player.name] - for _, header in ipairs(headers) do - local cap = header.caption + -- Score headers + local headers = { + {name = 'score_player', caption = 'Player'}, + {column = 'killscore', name = 'score_killscore', caption = 'Killscore'}, + {column = 'deaths', name = 'score_deaths', caption = 'Deaths'}, + {column = 'built_entities', name = 'score_built_entities', caption = 'Built structures'}, + {column = 'mined_entities', name = 'score_mined_entities', caption = 'Mined entities'} + } - -- Add sorting symbol if any - if header.column and sorting_pref.column == header.column then - local symbol = sorting_symbol[sorting_pref.method] - cap = symbol .. cap - end + local sorting_pref = this.sort_by[player.name] + for _, header in ipairs(headers) do + local cap = header.caption - -- Header - local label = t.add { - type = "label", - caption = cap, - name = header.name - } - label.style.font = "default-listbox" - label.style.font_color = { r=0.98, g=0.66, b=0.22 } -- yellow - label.style.minimal_width = 150 - label.style.horizontal_align = "right" - end + -- Add sorting symbol if any + if header.column and sorting_pref.column == header.column then + local symbol = sorting_symbol[sorting_pref.method] + cap = symbol .. cap + end - -- Score list - local score_list = get_score_list(player.force.name) + -- Header + local label = + t.add { + type = 'label', + caption = cap, + name = header.name + } + label.style.font = 'default-listbox' + label.style.font_color = {r = 0.98, g = 0.66, b = 0.22} -- yellow + label.style.minimal_width = 150 + label.style.horizontal_align = 'right' + end - if #game.connected_players > 1 then - score_list = get_sorted_list(sorting_pref.method, sorting_pref.column, score_list) - end + -- Score list + local score_list = get_score_list(player.force.name) - -- New pane for scores (while keeping headers at same position) - local scroll_pane = frame.add({ type = "scroll-pane", name = "score_scroll_pane", direction = "vertical", horizontal_scroll_policy = "never", vertical_scroll_policy = "auto"}) - scroll_pane.style.maximal_height = 400 - local t = scroll_pane.add { type = "table", column_count = 5} + if #game.connected_players > 1 then + score_list = get_sorted_list(sorting_pref.method, sorting_pref.column, score_list) + end - -- Score entries - for _, entry in pairs(score_list) do - local p = game.players[entry.name] - local special_color = { - r = p.color.r * 0.6 + 0.4, - g = p.color.g * 0.6 + 0.4, - b = p.color.b * 0.6 + 0.4, - a = 1 - } - local line = { - { caption = entry.name, color = special_color }, - { caption = tostring(entry.killscore) }, - { caption = tostring(entry.deaths) }, - { caption = tostring(entry.built_entities) }, - { caption = tostring(entry.mined_entities) } - } - local default_color = { r=0.9, g=0.9, b=0.9 } + -- New pane for scores (while keeping headers at same position) + local scroll_pane = + frame.add( + { + type = 'scroll-pane', + name = 'score_scroll_pane', + direction = 'vertical', + horizontal_scroll_policy = 'never', + vertical_scroll_policy = 'auto' + } + ) + scroll_pane.style.maximal_height = 400 + local t = scroll_pane.add {type = 'table', column_count = 5} - for _, column in ipairs(line) do - local label = t.add { - type = "label", - caption = column.caption, - color = column.color or default_color - } - label.style.font = "default" - label.style.minimal_width = 150 - label.style.maximal_width = 150 - label.style.horizontal_align = "right" - end -- foreach column - end -- foreach entry -end -- show_score -) + -- Score entries + for _, entry in pairs(score_list) do + local p = game.players[entry.name] + local special_color = { + r = p.color.r * 0.6 + 0.4, + g = p.color.g * 0.6 + 0.4, + b = p.color.b * 0.6 + 0.4, + a = 1 + } + local line = { + {caption = entry.name, color = special_color}, + {caption = tostring(entry.killscore)}, + {caption = tostring(entry.deaths)}, + {caption = tostring(entry.built_entities)}, + {caption = tostring(entry.mined_entities)} + } + local default_color = {r = 0.9, g = 0.9, b = 0.9} + + for _, column in ipairs(line) do + local label = + t.add { + type = 'label', + caption = column.caption, + color = column.color or default_color + } + label.style.font = 'default' + label.style.minimal_width = 150 + label.style.maximal_width = 150 + label.style.horizontal_align = 'right' + end -- foreach column + end -- foreach entry +end) -- show_score local function refresh_score_full() - for _, player in pairs(game.connected_players) do - local frame = Tabs.comfy_panel_get_active_frame(player) - if frame then - if frame.name == "Scoreboard" then - show_score(player, frame) - end - end - end + for _, player in pairs(game.connected_players) do + local frame = Tabs.comfy_panel_get_active_frame(player) + if frame then + if frame.name == 'Scoreboard' then + show_score(player, frame) + end + end + end end local function on_player_joined_game(event) - local player = game.players[event.player_index] - init_player_table(player) - if not this.sort_by[player.name] then - this.sort_by[player.name] = {method = "descending", column = "killscore"} - end - if not global.show_floating_killscore then global.show_floating_killscore = {} end - if not global.show_floating_killscore[player.name] then global.show_floating_killscore[player.name] = false end + local player = game.players[event.player_index] + Public.init_player_table(player) + if not this.sort_by[player.name] then + this.sort_by[player.name] = {method = 'descending', column = 'killscore'} + end + if not global.show_floating_killscore then + global.show_floating_killscore = {} + end + if not global.show_floating_killscore[player.name] then + global.show_floating_killscore[player.name] = false + 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 then + return + end + if not event.element then + return + end + if not event.element.valid 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 ~= "Scoreboard" then return end - - local name = event.element.name + 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 ~= 'Scoreboard' then + return + end - -- Handles click on the checkbox, for floating score - if name == "show_floating_killscore_texts" then - global.show_floating_killscore[player.name] = event.element.state - return - end + local name = event.element.name - -- Handles click on a score header - local element_to_column = { - ["score_killscore"] = "killscore", - ["score_deaths"] = "deaths", - ["score_built_entities"] = "built_entities", - ["score_mined_entities"] = "mined_entities" - } - local column = element_to_column[name] - if column then - local sorting_pref = this.sort_by[player.name] - if sorting_pref.column == column and sorting_pref.method == "descending" then - sorting_pref.method = "ascending" - else - sorting_pref.method = "descending" - sorting_pref.column = column - end - show_score(player, frame) - return - end + -- Handles click on the checkbox, for floating score + if name == 'show_floating_killscore_texts' then + global.show_floating_killscore[player.name] = event.element.state + return + end - -- No more to handle + -- Handles click on a score header + local element_to_column = { + ['score_killscore'] = 'killscore', + ['score_deaths'] = 'deaths', + ['score_built_entities'] = 'built_entities', + ['score_mined_entities'] = 'mined_entities' + } + local column = element_to_column[name] + if column then + local sorting_pref = this.sort_by[player.name] + if sorting_pref.column == column and sorting_pref.method == 'descending' then + sorting_pref.method = 'ascending' + else + sorting_pref.method = 'descending' + sorting_pref.column = column + end + show_score(player, frame) + return + end + + -- No more to handle end local function on_rocket_launched(event) - refresh_score_full() + refresh_score_full() end local entity_score_values = { - ["behemoth-biter"] = 100, - ["behemoth-spitter"] = 100, - ["behemoth-worm-turret"] = 300, - ["big-biter"] = 30, - ["big-spitter"] = 30, - ["big-worm-turret"] = 300, - ["biter-spawner"] = 200, - ["medium-biter"] = 15, - ["medium-spitter"] = 15, - ["medium-worm-turret"] = 150, - ["character"] = 1000, - ["small-biter"] = 5, - ["small-spitter"] = 5, - ["small-worm-turret"] = 50, - ["spitter-spawner"] = 200, - ["gun-turret"] = 50, - ["laser-turret"] = 150, - ["flamethrower-turret"] = 300, + ['behemoth-biter'] = 100, + ['behemoth-spitter'] = 100, + ['behemoth-worm-turret'] = 300, + ['big-biter'] = 30, + ['big-spitter'] = 30, + ['big-worm-turret'] = 300, + ['biter-spawner'] = 200, + ['medium-biter'] = 15, + ['medium-spitter'] = 15, + ['medium-worm-turret'] = 150, + ['character'] = 1000, + ['small-biter'] = 5, + ['small-spitter'] = 5, + ['small-worm-turret'] = 50, + ['spitter-spawner'] = 200, + ['gun-turret'] = 50, + ['laser-turret'] = 150, + ['flamethrower-turret'] = 300 } -local function train_type_cause(event) - local players = {} - if event.cause.train.passengers then - for _, player in pairs(event.cause.train.passengers) do - players[#players + 1] = player - end - end - return players +local function train_type_cause(event) + local players = {} + if event.cause.train.passengers then + for _, player in pairs(event.cause.train.passengers) do + players[#players + 1] = player + end + end + return players end local kill_causes = { - ["character"] = - function(event) - if not event.cause.player then return end - return {event.cause.player} - end, - ["combat-robot"] = - function(event) - if not event.cause.last_user then return end - if not game.players[event.cause.last_user.index] then return end - return {game.players[event.cause.last_user.index]} - end, - ["car"] = - function(event) - local players = {} - local driver = event.cause.get_driver() - if driver then - if driver.player then players[#players + 1] = driver.player end - end - local passenger = event.cause.get_passenger() - if passenger then - if passenger.player then players[#players + 1] = passenger.player end - end - return players - end, - ["locomotive"] = train_type_cause, - ["cargo-wagon"] = train_type_cause, - ["artillery-wagon"] = train_type_cause, - ["fluid-wagon"] = train_type_cause, + ['character'] = function(event) + if not event.cause.player then + return + end + return {event.cause.player} + end, + ['combat-robot'] = function(event) + if not event.cause.last_user then + return + end + if not game.players[event.cause.last_user.index] then + return + end + return {game.players[event.cause.last_user.index]} + end, + ['car'] = function(event) + local players = {} + local driver = event.cause.get_driver() + if driver then + if driver.player then + players[#players + 1] = driver.player + end + end + local passenger = event.cause.get_passenger() + if passenger then + if passenger.player then + players[#players + 1] = passenger.player + end + end + return players + end, + ['locomotive'] = train_type_cause, + ['cargo-wagon'] = train_type_cause, + ['artillery-wagon'] = train_type_cause, + ['fluid-wagon'] = train_type_cause } local function on_entity_died(event) - if not event.entity.valid then return end - if not event.cause then return end - if not event.cause.valid then return end - if event.entity.force.index == event.cause.force.index then return end - if not entity_score_values[event.entity.name] then return end - if not kill_causes[event.cause.type] then return end - local players_to_reward = kill_causes[event.cause.type](event) - if not players_to_reward then return end - if #players_to_reward == 0 then return end - for _, player in pairs(players_to_reward) do - init_player_table(player) - local score = this.score_table[player.force.name].players[player.name] - score.killscore = score.killscore + entity_score_values[event.entity.name] - if global.show_floating_killscore[player.name] then - event.entity.surface.create_entity({name = "flying-text", position = event.entity.position, text = tostring(entity_score_values[event.entity.name]), color = player.chat_color}) - end - end -end + if not event.entity.valid then + return + end + if not event.cause then + return + end + if not event.cause.valid then + return + end + if event.entity.force.index == event.cause.force.index then + return + end + if not entity_score_values[event.entity.name] then + return + end + if not kill_causes[event.cause.type] then + return + end + local players_to_reward = kill_causes[event.cause.type](event) + if not players_to_reward then + return + end + if #players_to_reward == 0 then + return + end + for _, player in pairs(players_to_reward) do + Public.init_player_table(player) + local score = this.score_table[player.force.name].players[player.name] + score.killscore = score.killscore + entity_score_values[event.entity.name] + if global.show_floating_killscore[player.name] then + event.entity.surface.create_entity( + { + name = 'flying-text', + position = event.entity.position, + text = tostring(entity_score_values[event.entity.name]), + color = player.chat_color + } + ) + end + end +end local function on_player_died(event) - local player = game.players[event.player_index] - init_player_table(player) - local score = this.score_table[player.force.name].players[player.name] - score.deaths = 1 + (score.deaths or 0) + local player = game.players[event.player_index] + Public.init_player_table(player) + local score = this.score_table[player.force.name].players[player.name] + score.deaths = 1 + (score.deaths or 0) end local function on_player_mined_entity(event) - if not event.entity.valid then return end - if building_and_mining_blacklist[event.entity.type] then return end - - local player = game.players[event.player_index] - init_player_table(player) - local score = this.score_table[player.force.name].players[player.name] - score.mined_entities = 1 + (score.mined_entities or 0) + if not event.entity.valid then + return + end + if building_and_mining_blacklist[event.entity.type] then + return + end + + local player = game.players[event.player_index] + Public.init_player_table(player) + local score = this.score_table[player.force.name].players[player.name] + score.mined_entities = 1 + (score.mined_entities or 0) end local function on_built_entity(event) - if not event.created_entity.valid then return end - if building_and_mining_blacklist[event.created_entity.type] then return end - local player = game.players[event.player_index] - init_player_table(player) - local score = this.score_table[player.force.name].players[player.name] - score.built_entities = 1 + (score.built_entities or 0) + if not event.created_entity.valid then + return + end + if building_and_mining_blacklist[event.created_entity.type] then + return + end + local player = game.players[event.player_index] + Public.init_player_table(player) + local score = this.score_table[player.force.name].players[player.name] + score.built_entities = 1 + (score.built_entities or 0) end -comfy_panel_tabs["Scoreboard"] = {gui = show_score, admin = false} +comfy_panel_tabs['Scoreboard'] = {gui = show_score, admin = false} Event.add(defines.events.on_player_mined_entity, on_player_mined_entity) Event.add(defines.events.on_player_died, on_player_died) @@ -382,5 +472,4 @@ Event.add(defines.events.on_gui_click, on_gui_click) Event.add(defines.events.on_player_joined_game, on_player_joined_game) Event.add(defines.events.on_rocket_launched, on_rocket_launched) - -return Public \ No newline at end of file +return Public diff --git a/maps/fish_defender/bouncy_shells.lua b/maps/fish_defender/bouncy_shells.lua index ab28fdd2..76eb4d54 100644 --- a/maps/fish_defender/bouncy_shells.lua +++ b/maps/fish_defender/bouncy_shells.lua @@ -1,6 +1,5 @@ local radius = 9 local math_random = math.random -local math_sqrt = math.sqrt local ammo_to_projectile_translation = { ['shotgun-shell'] = 'shotgun-pellet', @@ -12,7 +11,7 @@ local function create_projectile(surface, position, target, name) { name = name, position = position, - force = force, + force = 'player', source = position, target = target, max_range = 16, @@ -45,7 +44,7 @@ local function bounce(surface, position, ammo) return end - for c = 1, math_random(3, 6), 1 do + for _ = 1, math_random(3, 6), 1 do create_projectile(surface, position, valid_entities[math_random(1, #valid_entities)].position, ammo) end end diff --git a/maps/fish_defender/crumbly_walls.lua b/maps/fish_defender/crumbly_walls.lua index c3dc197c..ea5ffddd 100644 --- a/maps/fish_defender/crumbly_walls.lua +++ b/maps/fish_defender/crumbly_walls.lua @@ -1,4 +1,4 @@ -local event = require 'utils.event' +local Event = require 'utils.event' local FDT = require 'maps.fish_defender.table' local math_random = math.random @@ -24,4 +24,4 @@ local function on_entity_died(event) ) end -event.add(defines.events.on_entity_died, on_entity_died) +Event.add(defines.events.on_entity_died, on_entity_died) diff --git a/maps/fish_defender/main.lua b/maps/fish_defender/main.lua index 2e8d7a75..bd926cfe 100644 --- a/maps/fish_defender/main.lua +++ b/maps/fish_defender/main.lua @@ -103,7 +103,7 @@ end local function show_fd_stats(player) local gui_id = 'fd-stats' local table_id = gui_id .. 'table' - local entity_limits = FDT.get('entity_limits') + local this = FDT.get() if player.gui.left[gui_id] then player.gui.left[gui_id].destroy() @@ -127,7 +127,7 @@ local function show_fd_stats(player) h.style.font = 'heading-2' end - for k, v in pairs(entity_limits) do + for k, v in pairs(this.entity_limits) do local name = v.str local placed = v.placed local limit = v.limit @@ -194,16 +194,16 @@ local threat_values = { } local function get_biter_initial_pool() - local wave_count = FDT.get('wave_count') + local this = FDT.get() local biter_pool - if wave_count > 1750 then + if this.wave_count > 1750 then biter_pool = { {name = 'behemoth-biter', threat = threat_values.behemoth_biter, weight = 2}, {name = 'behemoth-spitter', threat = threat_values.behemoth_spitter, weight = 1} } return biter_pool end - if wave_count > 1500 then + if this.wave_count > 1500 then biter_pool = { {name = 'big-biter', threat = threat_values.big_biter, weight = 1}, {name = 'behemoth-biter', threat = threat_values.behemoth_biter, weight = 2}, @@ -211,7 +211,7 @@ local function get_biter_initial_pool() } return biter_pool end - if wave_count > 1250 then + if this.wave_count > 1250 then biter_pool = { {name = 'big-biter', threat = threat_values.big_biter, weight = 2}, {name = 'behemoth-biter', threat = threat_values.behemoth_biter, weight = 2}, @@ -219,7 +219,7 @@ local function get_biter_initial_pool() } return biter_pool end - if wave_count > 1000 then + if this.wave_count > 1000 then biter_pool = { {name = 'big-biter', threat = threat_values.big_biter, weight = 3}, {name = 'behemoth-biter', threat = threat_values.behemoth_biter, weight = 2}, @@ -343,7 +343,11 @@ local function spawn_biter(pos, biter_pool) return false end - local surface = this.active_surface + local surface = game.surfaces[this.active_surface_index] + if not surface or not surface.valid then + return + end + biter_pool = shuffle(biter_pool) this.attack_wave_threat = this.attack_wave_threat - biter_pool[1].threat local valid_pos = surface.find_non_colliding_position(biter_pool[1].name, pos, 100, 2) @@ -385,16 +389,16 @@ local function get_number_of_attack_groups() end local function clear_corpses(surface) - local wave_count = FDT.get('wave_count') + local this = FDT.get() - if not wave_count then + if not this.wave_count then return end local chance = 4 - if wave_count > 250 then + if this.wave_count > 250 then chance = 3 end - if wave_count > 500 then + if this.wave_count > 500 then chance = 2 end for _, entity in pairs(surface.find_entities_filtered {type = 'corpse'}) do @@ -406,8 +410,8 @@ end local function send_unit_group(unit_group) local commands = {} - local market = FDT.get('market') - for x = unit_group.position.x, market.position.x, -48 do + local this = FDT.get() + for x = unit_group.position.x, this.market.position.x, -48 do local destination = unit_group.surface.find_non_colliding_position('stone-wall', {x = x, y = unit_group.position.y}, 32, 4) if destination then @@ -421,13 +425,13 @@ local function send_unit_group(unit_group) end commands[#commands + 1] = { type = defines.command.attack_area, - destination = {x = market.position.x, y = unit_group.position.y}, + destination = {x = this.market.position.x, y = unit_group.position.y}, radius = 16, distraction = defines.distraction.by_enemy } commands[#commands + 1] = { type = defines.command.attack, - target = market, + target = this.market, distraction = defines.distraction.by_enemy } @@ -488,8 +492,8 @@ local function spawn_boss_units(surface) end local function wake_up_the_biters(surface) - local market = FDT.get('market') - if not market or not market.valid then + local this = FDT.get() + if not this.market or not this.market.valid then return end @@ -534,7 +538,7 @@ local function wake_up_the_biters(surface) { command = { type = defines.command.attack, - target = market, + target = this.market, distraction = defines.distraction.none }, unit_count = 16, @@ -579,7 +583,10 @@ local function biter_attack_wave() if this.wave_grace_period then return end - local surface = this.active_surface + local surface = game.surfaces[this.active_surface_index] + if not surface or not surface.valid then + return + end clear_corpses(surface) wake_up_the_biters(surface) @@ -742,13 +749,7 @@ local function get_mvps() end local function is_game_lost() - local market = FDT.get('market') - if market then - return - end - local this = FDT.get() - local l for _, player in pairs(game.connected_players) do if player.gui.left['fish_defense_game_lost'] then @@ -766,12 +767,15 @@ local function is_game_lost() f.style.font_color = {r = 0.65, g = 0.1, b = 0.99} local t = f.add({type = 'table', column_count = 2}) - l = t.add({type = 'label', caption = 'Survival Time >> '}) - l.style.font = 'default-listbox' - l.style.font_color = {r = 0.22, g = 0.77, b = 0.44} + + local survival_time_label = t.add({type = 'label', caption = 'Survival Time >> '}) + survival_time_label.style.font = 'default-listbox' + survival_time_label.style.font_color = {r = 0.22, g = 0.77, b = 0.44} + + local market_age_label if this.market_age >= 216000 then - l = + market_age_label = t.add( { type = 'label', @@ -779,42 +783,48 @@ local function is_game_lost() ' hours ' .. math.ceil((this.market_age % 216000 / 60) / 60) .. ' minutes' } ) - l.style.font = 'default-bold' - l.style.font_color = {r = 0.33, g = 0.66, b = 0.9} + market_age_label.style.font = 'default-bold' + market_age_label.style.font_color = {r = 0.33, g = 0.66, b = 0.9} else - l = t.add({type = 'label', caption = math.ceil((this.market_age % 216000 / 60) / 60) .. ' minutes'}) - l.style.font = 'default-bold' - l.style.font_color = {r = 0.33, g = 0.66, b = 0.9} + market_age_label = + t.add({type = 'label', caption = math.ceil((this.market_age % 216000 / 60) / 60) .. ' minutes'}) + market_age_label.style.font = 'default-bold' + market_age_label.style.font_color = {r = 0.33, g = 0.66, b = 0.9} end local mvp = get_mvps() if mvp then - l = t.add({type = 'label', caption = 'MVP Defender >> '}) - l.style.font = 'default-listbox' - l.style.font_color = {r = 0.22, g = 0.77, b = 0.44} - l = t.add({type = 'label', caption = mvp.killscore.name .. ' with a score of ' .. mvp.killscore.score}) - l.style.font = 'default-bold' - l.style.font_color = {r = 0.33, g = 0.66, b = 0.9} + local mvp_defender_label = t.add({type = 'label', caption = 'MVP Defender >> '}) + mvp_defender_label.style.font = 'default-listbox' + mvp_defender_label.style.font_color = {r = 0.22, g = 0.77, b = 0.44} - l = t.add({type = 'label', caption = 'MVP Builder >> '}) - l.style.font = 'default-listbox' - l.style.font_color = {r = 0.22, g = 0.77, b = 0.44} - l = + local mvp_killscore_label = + t.add({type = 'label', caption = mvp.killscore.name .. ' with a score of ' .. mvp.killscore.score}) + mvp_killscore_label.style.font = 'default-bold' + mvp_killscore_label.style.font_color = {r = 0.33, g = 0.66, b = 0.9} + + local mvp_builder_label = t.add({type = 'label', caption = 'MVP Builder >> '}) + mvp_builder_label.style.font = 'default-listbox' + mvp_builder_label.style.font_color = {r = 0.22, g = 0.77, b = 0.44} + + local mvp_built_ent_label = t.add( { type = 'label', caption = mvp.built_entities.name .. ' built ' .. mvp.built_entities.score .. ' things' } ) - l.style.font = 'default-bold' - l.style.font_color = {r = 0.33, g = 0.66, b = 0.9} + mvp_built_ent_label.style.font = 'default-bold' + mvp_built_ent_label.style.font_color = {r = 0.33, g = 0.66, b = 0.9} - l = t.add({type = 'label', caption = 'MVP Deaths >> '}) - l.style.font = 'default-listbox' - l.style.font_color = {r = 0.22, g = 0.77, b = 0.44} - l = t.add({type = 'label', caption = mvp.deaths.name .. ' died ' .. mvp.deaths.score .. ' times'}) - l.style.font = 'default-bold' - l.style.font_color = {r = 0.33, g = 0.66, b = 0.9} + local mvp_deaths_label = t.add({type = 'label', caption = 'MVP Deaths >> '}) + mvp_deaths_label.style.font = 'default-listbox' + mvp_deaths_label.style.font_color = {r = 0.22, g = 0.77, b = 0.44} + + local mvp_deaths_name_label = + t.add({type = 'label', caption = mvp.deaths.name .. ' died ' .. mvp.deaths.score .. ' times'}) + mvp_deaths_name_label.style.font = 'default-bold' + mvp_deaths_name_label.style.font_color = {r = 0.33, g = 0.66, b = 0.9} if not this.results_sent then local result = {} @@ -867,9 +877,11 @@ local function damage_entities_in_radius(surface, position, radius, damage) end local function market_kill_visuals() - local market = FDT.get('market') - local active_surface_index = FDT.get('active_surface_index') - local surface = game.surfaces[active_surface_index] + local this = FDT.get() + local surface = game.surfaces[this.active_surface_index] + if not surface or not surface.valid then + return + end local is_branch_18 = sub(branch_version, 3, 4) local get_active_version = sub(game.active_mods.base, 3, 4) @@ -878,7 +890,7 @@ local function market_kill_visuals() return end - if not market or not market.valid then + if not this.market or not this.market.valid then return end @@ -889,7 +901,7 @@ local function market_kill_visuals() surface.create_particle( { name = 'branch-particle', - position = market.position, + position = this.market.position, frame_speed = 0.1, vertical_speed = 0.1, height = 0.1, @@ -902,7 +914,7 @@ local function market_kill_visuals() surface.create_entity( { name = 'branch-particle', - position = market.position, + position = this.market.position, frame_speed = 0.1, vertical_speed = 0.1, height = 0.1, @@ -917,7 +929,7 @@ local function market_kill_visuals() surface.create_trivial_smoke( { name = 'smoke-fast', - position = {market.position.x + (x * 0.35), market.position.y + (y * 0.35)} + position = {this.market.position.x + (x * 0.35), this.market.position.y + (y * 0.35)} } ) end @@ -925,13 +937,13 @@ local function market_kill_visuals() surface.create_trivial_smoke( { name = 'train-smoke', - position = {market.position.x + (x * 0.35), market.position.y + (y * 0.35)} + position = {this.market.position.x + (x * 0.35), this.market.position.y + (y * 0.35)} } ) end end end - surface.spill_item_stack(market.position, {name = 'raw-fish', count = 1024}, true) + surface.spill_item_stack(this.market.position, {name = 'raw-fish', count = 1024}, true) end local biter_splash_damage = { @@ -1013,8 +1025,11 @@ end local function on_player_joined_game(event) local player = game.players[event.player_index] - local active_surface_index = FDT.get('active_surface_index') - local surface = game.surfaces[active_surface_index] + local this = FDT.get() + local surface = game.surfaces[this.active_surface_index] + if not surface or not surface.valid then + return + end if player.gui.left['fish_defense_game_lost'] then player.gui.left['fish_defense_game_lost'].destroy() @@ -1035,7 +1050,7 @@ local function on_player_joined_game(event) if not pos and player.online_time < 2 then player.teleport(game.forces['player'].get_spawn_position(surface), surface) - elseif player.online_time < 2 or player.surface.index ~= active_surface_index then + elseif player.online_time < 2 or player.surface.index ~= this.active_surface_index then player.teleport(pos, surface) end @@ -1100,17 +1115,18 @@ end local function on_robot_built_entity(event) local entity = event.created_entity - local entity_limits = FDT.get('entity_limits') - if entity_limits[entity.name] then + local this = FDT.get() + if this.entity_limits[entity.name] then local surface = entity.surface - if entity_limits[entity.name].placed < entity_limits[entity.name].limit then - entity_limits[entity.name].placed = entity_limits[entity.name].placed + 1 + if this.entity_limits[entity.name].placed < this.entity_limits[entity.name].limit then + this.entity_limits[entity.name].placed = this.entity_limits[entity.name].placed + 1 surface.create_entity( { name = 'flying-text', position = entity.position, - text = entity_limits[entity.name].placed .. - ' / ' .. entity_limits[entity.name].limit .. ' ' .. entity_limits[entity.name].str .. 's', + text = this.entity_limits[entity.name].placed .. + ' / ' .. + this.entity_limits[entity.name].limit .. ' ' .. this.entity_limits[entity.name].str .. 's', color = {r = 0.98, g = 0.66, b = 0.22} } ) @@ -1120,7 +1136,7 @@ local function on_robot_built_entity(event) { name = 'flying-text', position = entity.position, - text = entity_limits[entity.name].str .. ' limit reached.', + text = this.entity_limits[entity.name].str .. ' limit reached.', color = {r = 0.82, g = 0.11, b = 0.11} } ) @@ -1133,9 +1149,11 @@ end local function on_player_changed_position(event) local player = game.players[event.player_index] - local active_surface_index = FDT.get('active_surface_index') - local surface = game.surfaces[active_surface_index] - local map_height = FDT.get('map_height') + local this = FDT.get() + local surface = game.surfaces[this.active_surface_index] + if not surface or not surface.valid then + return + end if player.position.x + player.position.y < 0 then return end @@ -1144,7 +1162,7 @@ local function on_player_changed_position(event) end if player.position.x >= 160 then player.teleport({player.position.x - 1, player.position.y}, surface) - if player.position.y > map_height or player.position.y < map_height * -1 then + if player.position.y > this.map_height or player.position.y < this.map_height * -1 then player.teleport({player.position.x, 0}, surface) end if player.character then @@ -1183,8 +1201,8 @@ local function on_research_finished(event) end local function on_player_respawned(event) - local market_age = FDT.get('market_age') - if not market_age then + local this = FDT.get() + if not this.market_age then return end local player = game.players[event.player_index] @@ -1291,11 +1309,9 @@ local function set_market_health() if not this.market.valid then return end - local market_health = FDT.get('market_health') - local market_max_health = FDT.get('market_max_health') - local m = market_health / market_max_health + local m = this.market_health / this.market_max_health this.market.health = 150 * m - rendering.set_text(this.health_text, 'HP: ' .. market_health .. ' / ' .. market_max_health) + rendering.set_text(this.health_text, 'HP: ' .. this.market_health .. ' / ' .. this.market_max_health) end local function has_the_game_ended() @@ -1360,14 +1376,18 @@ end function Public.on_init() FDT.reset_table() Poll.reset() - local get_score = Score.get_table() local this = FDT.get() local is_branch_18 = sub(branch_version, 3, 4) local get_active_version = sub(game.active_mods.base, 3, 4) Difficulty.reset_difficulty_poll() Difficulty.set_poll_closing_timeout = game.tick + 36000 - get_score.score_table = {} + + local players = game.connected_players + for i = 1, #players do + local player = players[i] + Score.init_player_table(player) + end local map_gen_settings = {} map_gen_settings.height = 2048 @@ -1394,7 +1414,10 @@ function Public.on_init() this.active_surface = game.surfaces[this.active_surface_index] end - local surface = this.active_surface + local surface = game.surfaces[this.active_surface_index] + if not surface or not surface.valid then + return + end surface.peaceful_mode = false @@ -1451,9 +1474,11 @@ end local function on_tick() local Diff = Difficulty.get() - local active_surface_index = FDT.get('active_surface_index') - local surface = game.surfaces[active_surface_index] local this = FDT.get() + local surface = game.surfaces[this.active_surface_index] + if not surface or not surface.valid then + return + end if game.tick % 30 == 0 then has_the_game_ended() if this.market then @@ -1500,4 +1525,16 @@ Event.add(defines.events.on_robot_mined_entity, on_robot_mined_entity) Event.add(defines.events.on_tick, on_tick) Event.on_init(on_init) +--[[ local gmeta = getmetatable(_ENV) +if not gmeta then + gmeta = {} + setmetatable(_ENV, gmeta) +end +gmeta.__newindex = function(_, n, v) + log('Desync warning: attempt to write to undeclared var ' .. n) + global[n] = v +end +gmeta.__index = function(_, n) + return global[n] +end ]] return Public diff --git a/maps/fish_defender/table.lua b/maps/fish_defender/table.lua index ae2f3424..af786a36 100644 --- a/maps/fish_defender/table.lua +++ b/maps/fish_defender/table.lua @@ -33,7 +33,8 @@ function Public.reset_table() this.crumbly_walls_unlocked = false this.vehicle_nanobots_unlocked = false this.game_restart_timer = nil - this.wave_count = 1 + this.wave_count = 0 + this.attack_wave_threat = nil this.market = nil this.market_age = nil this.last_reset = game.tick diff --git a/maps/fish_defender/terrain.lua b/maps/fish_defender/terrain.lua index 5f3e8689..a8443500 100644 --- a/maps/fish_defender/terrain.lua +++ b/maps/fish_defender/terrain.lua @@ -294,8 +294,11 @@ local function plankton_territory(surface, position, seed) end local function process_chunk(left_top) - local active_surface_index = FDT.get('active_surface_index') - local surface = game.surfaces[active_surface_index] + local this = FDT.get() + local surface = game.surfaces[this.active_surface_index] + if not surface or not surface.valid then + return + end local market = FDT.get('market') if not surface or not surface.valid then @@ -364,6 +367,9 @@ end local function render_market_hp() local this = FDT.get() local surface = game.surfaces[this.active_surface_index] + if not surface or not surface.valid then + return + end this.health_text = rendering.draw_text { @@ -519,7 +525,7 @@ function Public.generate_spawn_area(surface) math_random(1, 3) == 1 and surface.can_place_entity({name = 'wooden-chest', position = pos, force = 'player'}) then - local chest = surface.create_entity({name = 'wooden-chest', position = pos, force = 'player'}) + surface.create_entity({name = 'wooden-chest', position = pos, force = 'player'}) end end end diff --git a/maps/mountain_fortress_v3/basic_markets.lua b/maps/mountain_fortress_v3/basic_markets.lua index 13e6cbfd..d6d508bf 100644 --- a/maps/mountain_fortress_v3/basic_markets.lua +++ b/maps/mountain_fortress_v3/basic_markets.lua @@ -265,7 +265,7 @@ function Public.get_random_item(rarity, sell, buy) return items_return end -function Public.mountain_market(surface, position, rarity) +function Public.mountain_market(surface, position, rarity, buy) local types = get_types() table.shuffle_table(types) local items = get_market_item_list({types[1], types[2], types[3]}, rarity) @@ -300,9 +300,11 @@ function Public.mountain_market(surface, position, rarity) mrk.add_market_item(sells[i]) end - local buys = get_resource_market_buys() - for i = 1, math.random(1, 3), 1 do - mrk.add_market_item(buys[i]) + if buy then + local buys = get_resource_market_buys() + for i = 1, math.random(1, 3), 1 do + mrk.add_market_item(buys[i]) + end end return mrk diff --git a/maps/mountain_fortress_v3/main.lua b/maps/mountain_fortress_v3/main.lua index a212d11a..501aa91d 100644 --- a/maps/mountain_fortress_v3/main.lua +++ b/maps/mountain_fortress_v3/main.lua @@ -562,7 +562,7 @@ local has_the_game_ended = function() game.print('Soft-reset is disabled. Server will restart!', {r = 0.22, g = 0.88, b = 0.22}) local message = 'Soft-reset is disabled. Server will restart!' Server.to_discord_bold(table.concat {'*** ', message, ' ***'}) - Server.start_scenario('Fish_Defender') + Server.start_scenario('Mountain_Fortress_v3') this.announced_message = true return end @@ -608,10 +608,10 @@ local boost_difficulty = function() if name == 'Easy' then rpg_extra.difficulty = 1 - game.forces.player.manual_mining_speed_modifier = 1.5 + game.forces.player.manual_mining_speed_modifier = 1 force_mining_speed.speed = game.forces.player.manual_mining_speed_modifier game.forces.player.character_running_speed_modifier = 0.2 - game.forces.player.manual_crafting_speed_modifier = 0.4 + game.forces.player.manual_crafting_speed_modifier = 0.3 WPT.get().coin_amount = 2 WPT.get('upgrades').flame_turret.limit = 25 WPT.get('upgrades').landmine.limit = 100 @@ -621,10 +621,10 @@ local boost_difficulty = function() WPT.get().bonus_xp_on_join = 700 elseif name == 'Normal' then rpg_extra.difficulty = 0.5 - game.forces.player.manual_mining_speed_modifier = 1 + game.forces.player.manual_mining_speed_modifier = 0.5 force_mining_speed.speed = game.forces.player.manual_mining_speed_modifier game.forces.player.character_running_speed_modifier = 0.1 - game.forces.player.manual_crafting_speed_modifier = 0.2 + game.forces.player.manual_crafting_speed_modifier = 0.1 WPT.get().coin_amount = 1 WPT.get('upgrades').flame_turret.limit = 10 WPT.get('upgrades').landmine.limit = 50 diff --git a/modules/biters_yield_coins.lua b/modules/biters_yield_coins.lua index 39dacb18..b6a599e4 100644 --- a/modules/biters_yield_coins.lua +++ b/modules/biters_yield_coins.lua @@ -1,94 +1,116 @@ -- biters yield coins -- by mewmew -local event = require 'utils.event' +local Event = require 'utils.event' local insert = table.insert local math_floor = math.floor local coin_yield = { - ["behemoth-biter"] = 5, - ["behemoth-spitter"] = 5, - ["behemoth-worm-turret"] = 20, - ["big-biter"] = 3, - ["big-spitter"] = 3, - ["big-worm-turret"] = 16, - ["biter-spawner"] = 32, - ["medium-biter"] = 2, - ["medium-spitter"] = 2, - ["medium-worm-turret"] = 12, - ["small-biter"] = 1, - ["small-spitter"] = 1, - ["small-worm-turret"] = 8, - ["spitter-spawner"] = 32, + ['behemoth-biter'] = 5, + ['behemoth-spitter'] = 5, + ['behemoth-worm-turret'] = 20, + ['big-biter'] = 3, + ['big-spitter'] = 3, + ['big-worm-turret'] = 16, + ['biter-spawner'] = 32, + ['medium-biter'] = 2, + ['medium-spitter'] = 2, + ['medium-worm-turret'] = 12, + ['small-biter'] = 1, + ['small-spitter'] = 1, + ['small-worm-turret'] = 8, + ['spitter-spawner'] = 32 } local entities_that_earn_coins = { - ["artillery-turret"] = true, - ["gun-turret"] = true, - ["laser-turret"] = true, - ["flamethrower-turret"] = true - } - + ['artillery-turret'] = true, + ['gun-turret'] = true, + ['laser-turret'] = true, + ['flamethrower-turret'] = true +} + --extra coins for "boss" biters from biter_health_booster.lua local function get_coin_count(entity) - local coin_count = coin_yield[entity.name] - if not coin_count then return end - if not global.biter_health_boost_units then return coin_count end - local unit_number = entity.unit_number - if not unit_number then return coin_count end - if not global.biter_health_boost_units[unit_number] then return coin_count end - if not global.biter_health_boost_units[unit_number][3] then return coin_count end - local m = 1 / global.biter_health_boost_units[unit_number][2] - coin_count = math_floor(coin_count * m) - if coin_count < 1 then return 1 end - return coin_count + local coin_count = coin_yield[entity.name] + if not coin_count then + return + end + if not global.biter_health_boost_units then + return coin_count + end + local unit_number = entity.unit_number + if not unit_number then + return coin_count + end + if not global.biter_health_boost_units[unit_number] then + return coin_count + end + if not global.biter_health_boost_units[unit_number][3] then + return coin_count + end + local m = 1 / global.biter_health_boost_units[unit_number][2] + coin_count = math_floor(coin_count * m) + if coin_count < 1 then + return 1 + end + return coin_count end local function on_entity_died(event) - local entity = event.entity - if not entity.valid then return end - if entity.force.index ~= 2 then return end - - local coin_count = get_coin_count(entity) - if not coin_count then return end - - local players_to_reward = {} - local reward_has_been_given = false - - if event.cause then - if event.cause.valid then - if event.cause.name == "character" then - insert(players_to_reward, event.cause) - reward_has_been_given = true - end - if event.cause.type == "car" then - local player = event.cause.get_driver() - local passenger = event.cause.get_passenger() - if player then insert(players_to_reward, player.player) end - if passenger then insert(players_to_reward, passenger.player) end - reward_has_been_given = true - end - if event.cause.type == "locomotive" then - local train_passengers = event.cause.train.passengers - if train_passengers then - for _, passenger in pairs(train_passengers) do - insert(players_to_reward, passenger) - end - reward_has_been_given = true - end - end - for _, player in pairs(players_to_reward) do - player.insert({name = "coin", count = coin_count}) - end - end - if entities_that_earn_coins[event.cause.name] then - event.entity.surface.spill_item_stack(event.cause.position,{name = "coin", count = coin_count}, true) - reward_has_been_given = true - end - end - - if reward_has_been_given == false then - event.entity.surface.spill_item_stack(event.entity.position,{name = "coin", count = coin_count}, true) - end + local entity = event.entity + if not entity.valid then + return + end + if entity.force.index ~= 2 then + return + end + + local coin_count = get_coin_count(entity) + if not coin_count then + return + end + + local players_to_reward = {} + local reward_has_been_given = false + + if event.cause then + if event.cause.valid then + if event.cause.name == 'character' then + insert(players_to_reward, event.cause) + reward_has_been_given = true + end + if event.cause.type == 'car' then + local player = event.cause.get_driver() + local passenger = event.cause.get_passenger() + if player then + insert(players_to_reward, player.player) + end + if passenger then + insert(players_to_reward, passenger.player) + end + reward_has_been_given = true + end + if event.cause.type == 'locomotive' then + local train_passengers = event.cause.train.passengers + if train_passengers then + for _, passenger in pairs(train_passengers) do + insert(players_to_reward, passenger) + end + reward_has_been_given = true + end + end + for _, player in pairs(players_to_reward) do + player.insert({name = 'coin', count = coin_count}) + end + end + if entities_that_earn_coins[event.cause.name] then + event.entity.surface.spill_item_stack(event.cause.position, {name = 'coin', count = coin_count}, true) + reward_has_been_given = true + end + end + + if reward_has_been_given == false then + event.entity.surface.spill_item_stack(event.entity.position, {name = 'coin', count = coin_count}, true) + end end - -event.add(defines.events.on_entity_died, on_entity_died) \ No newline at end of file + +Event.add(defines.events.on_entity_died, on_entity_died) diff --git a/utils/core.lua b/utils/core.lua index 0de90420..417cf08b 100644 --- a/utils/core.lua +++ b/utils/core.lua @@ -45,13 +45,23 @@ function Public.print_except(msg, player, color) end end +function Public.print_to(player_ident, msg) + local player = Public.validate_player(player_ident) + + if player then + player.print(prefix .. msg, Color.yellow) + else + game.print(prefix .. msg, Color.yellow) + end +end + --- Prints a message to all online admins -- @param msg table if locale is used -- @param source string must be the name of a player, nil for server. function Public.print_admins(msg, source) local source_name local chat_color - if source then + if source and game.players[source] then if type(source) == 'string' then source_name = source chat_color = game.players[source].chat_color @@ -63,7 +73,7 @@ function Public.print_admins(msg, source) source_name = 'Server' chat_color = Color.yellow end - local formatted_msg = {'utils_core.print_admins', prefix, source_name, msg} + local formatted_msg = prefix .. '(ADMIN) ' .. source_name .. ': ' .. msg log(formatted_msg) for _, p in pairs(game.connected_players) do if p.admin then @@ -217,6 +227,16 @@ function Public.action_warning(warning_prefix, msg) Server.to_discord_bold(msg) end +--- Takes msg and prints it to all players. Also prints to the log and discord +-- @param msg The message to print +-- @param warning_prefix The name of the module/warning +function Public.action_warning_embed(warning_prefix, msg) + game.print(prefix .. msg, Color.yellow) + msg = format('%s %s', warning_prefix, msg) + log(msg) + Server.to_discord_embed(msg) +end + --- Takes msg and prints it to the log and discord. -- @param msg The message to print -- @param warning_prefix The name of the module/warning diff --git a/utils/jail_data.lua b/utils/jail_data.lua index d7dc36c3..7ace8e4e 100644 --- a/utils/jail_data.lua +++ b/utils/jail_data.lua @@ -5,10 +5,12 @@ local Token = require 'utils.token' local Task = require 'utils.task' local Server = require 'utils.server' local Event = require 'utils.event' -local table = require 'utils.table' +local Utils = require 'utils.core' local jailed_data_set = 'jailed' local jailed = {} +local votejail = {} +local votejail_count = 3 local set_data = Server.set_data local try_get_data = Server.try_get_data local concat = table.concat @@ -29,31 +31,32 @@ local valid_commands = { } Global.register( - jailed, + { + jailed = jailed, + votejail = votejail + }, function(t) - jailed = t + jailed = t.jailed + votejail = t.votejail end ) local Public = {} -local function admin_only_message(str) - for _, player in pairs(game.connected_players) do - if player.admin == true then - player.print('Admins-only-message: ' .. str, {r = 0.88, g = 0.88, b = 0.88}) - end - end -end - local jail = function(target_player, player) if jailed[target_player] then if player then - game.players[player].print(target_player .. ' is already jailed!', {r = 1, g = 0.5, b = 0.1}) + Utils.print_to(player, target_player .. ' is already jailed!') return false else return false end end + + if not game.players[target_player] then + return + end + local permission_group = game.permissions.get_group('prisoner') if not permission_group then permission_group = game.permissions.create_group('prisoner') @@ -82,47 +85,49 @@ local jail = function(target_player, player) game.players[target_player].character.driving = false end - jailed[target_player] = true + Utils.print_to(nil, message) + Utils.action_warning_embed('{Jailed}', message) + Utils.print_admins('Jailed ' .. target_player, player) - game.print(message, {r = 0.98, g = 0.66, b = 0.22}) - Server.to_discord_embed( - table.concat { - message - } - ) - admin_only_message(target_player .. ' was jailed by ' .. player) + game.players[target_player].clear_console() + Utils.print_to(target_player, message) return true end local free = function(target_player, player) if not jailed[target_player] then if player then - game.players[player].print(target_player .. ' is not jailed!', {r = 1, g = 0.5, b = 0.1}) + Utils.print_to(player, target_player .. ' is not jailed!') return false else return false end end + + if not game.players[target_player] then + return + end + local permission_group = game.permissions.get_group('Default') permission_group.add_player(target_player) - local messsage + local message if player then - messsage = + message = target_player .. ' was set free from jail by ' .. player .. '. ' .. freedom_messages[math.random(1, #freedom_messages)] else - messsage = target_player .. ' was set free from jail. ' .. freedom_messages[math.random(1, #freedom_messages)] + message = target_player .. ' was set free from jail. ' .. freedom_messages[math.random(1, #freedom_messages)] end jailed[target_player] = nil - game.print(messsage, {r = 0.98, g = 0.66, b = 0.22}) - Server.to_discord_embed( - table.concat { - messsage - } - ) - admin_only_message(player .. ' set ' .. target_player .. ' free from jail') + if votejail[target_player] then + votejail[target_player] = nil + end + + Utils.print_to(nil, message) + Utils.action_warning_embed('{Jailed}', message) + Utils.print_admins('Free´d ' .. target_player .. ' from jail.', player) return true end @@ -132,8 +137,10 @@ local is_jailed = local key = data.key local value = data.value if value then - jail(key) - jailed[key] = value + if value.jailed then + jail(key) + jailed[key] = {jailed = true, actor = value.actor} + end end end ) @@ -143,15 +150,13 @@ local update_jailed = function(data) local key = data.key local value = data.value - local player = data.player + local player = data.player or 'script' if value then - set_data(jailed_data_set, key, value) - jail(key, player) - jailed[key] = value + jail(key) + set_data(jailed_data_set, key, {jailed = true, actor = player}) else + free(key) set_data(jailed_data_set, key, nil) - free(key, player) - jailed[key] = value end end ) @@ -160,7 +165,9 @@ local update_jailed = -- @param data_set player token function Public.try_dl_data(key) key = tostring(key) + local secs = Server.get_current_time() + if not secs then return else @@ -172,23 +179,14 @@ end -- @param data_set player token function Public.try_ul_data(key, value, player) key = tostring(key) - local secs = Server.get_current_time() + local data = { key = key, value = value, player = player or nil } - if not secs then - if value then - jail(key, player) - return true - else - free(key, player) - return true - end - else - Task.set_timeout_in_ticks(1, update_jailed, data) - end + + Task.set_timeout_in_ticks(1, update_jailed, data) end --- Checks if a player exists within the table @@ -220,27 +218,22 @@ Event.add( defines.events.on_player_joined_game, function(event) local player = game.get_player(event.player_index) - local secs = Server.get_current_time() - if not secs then - return - end - if not player or player.valid then + if not player or not player.valid then return end - if game.is_multiplayer() then - Public.try_dl_data(player.name) - end + Public.try_dl_data(player.name) end ) Event.add( defines.events.on_console_command, function(event) - local trusted = Session.get_trusted_table() local tracker = Session.get_session_table() - local p + local script = 'script' local cmd = event.command + local _10d = 51840000 -- 10d + local _12h = 2592000 -- 12h if not valid_commands[cmd] then return @@ -251,38 +244,61 @@ Event.add( return end - if not game.players[griefer] then - return - end - if event.player_index then local player = game.players[event.player_index] - p = player.print + + if game.players[griefer] then + griefer = game.players[griefer].name + end + + if not game.players[griefer] then + return Utils.print_to(player, 'Invalid name.') + end local playtime = player.online_time if tracker[player.name] then playtime = player.online_time + tracker[player.name] end - if playtime < 25920000 then -- 5 days - return p('You are not trusted enough to run this command.', {r = 1, g = 0.5, b = 0.1}) + + if votejail[player.name] and not player.admin then + return Utils.print_to(player, 'You are currently being investigated since you have griefed.') end if jailed[player.name] and not player.admin then - return p('You are jailed, there is nothing to be done.', {r = 1, g = 0.5, b = 0.1}) + return Utils.print_to(player, 'You are jailed, you can´t run this command.') end - if not trusted[player.name] then - if not player.admin then - p("You're not admin nor are you trusted enough to run this command!", {r = 1, g = 0.5, b = 0.1}) - return - end - end if player.name == griefer then - return p("You can't select yourself!", {r = 1, g = 0.5, b = 0.1}) + return Utils.print_to(player, 'You can´t select yourself.') end if game.players[griefer].admin and not player.admin then - return p("You can't sadly jail an admin!", {r = 1, g = 0.5, b = 0.1}) + return Utils.print_to(player, 'You can´t select an admin.') + end + + if playtime >= _12h and playtime < _10d and not player.admin then + if not votejail[griefer] then + votejail[griefer] = {} + local message = player.name .. ' has started a vote to jail player ' .. griefer + Utils.print_to(nil, message) + end + if not votejail[griefer][player.name] then + votejail[griefer][player.name] = true + Utils.print_to(player, 'You have voted to jail player ' .. griefer .. '.') + if + #votejail[griefer] >= votejail_count or + (#votejail[griefer] == 2 and 3 == #game.connected_players) + then + local message = griefer .. ' has been jailed by player vote.' + Utils.print_to(nil, message) + Public.try_ul_data(griefer, true, script) + end + else + Utils.print_to(player, 'You have already voted to kick ' .. griefer .. '.') + end + return + elseif playtime < _10d and not player.admin then + return Utils.print_to(player, 'You are not trusted enough to run this command.') end if cmd == 'jail' then @@ -294,10 +310,10 @@ Event.add( end else if cmd == 'jail' then - Public.try_ul_data(griefer, true) + Public.try_ul_data(griefer, true, script) return elseif cmd == 'free' then - Public.try_ul_data(griefer, false) + Public.try_ul_data(griefer, false, script) return end end @@ -307,9 +323,11 @@ Event.add( Server.on_data_set_changed( jailed_data_set, function(data) - jailed[data.key] = data.value if data and data.value then - jail(data.key) + if data.value.jailed and data.value.actor then + jail(data.key) + jailed[data.key] = {jailed = true, actor = data.value.actor} + end else free(data.key) end