diff --git a/maps/scrap_towny_ffa/evolution.lua b/maps/scrap_towny_ffa/evolution.lua index 2c29f040..5fabe37c 100644 --- a/maps/scrap_towny_ffa/evolution.lua +++ b/maps/scrap_towny_ffa/evolution.lua @@ -483,6 +483,17 @@ local function get_relative_worm_evolution(position) return relative_evolution end +function Public.get_highest_evolution() + local this = ScenarioTable.get_table() + local max_evo = 0 + for _, town_center in pairs(this.town_centers) do + if town_center.evolution.worms > max_evo then + max_evo = town_center.evolution.worms + end + end + return max_evo +end + function Public.get_evolution(position) return get_relative_biter_evolution(position) end diff --git a/maps/scrap_towny_ffa/info.lua b/maps/scrap_towny_ffa/info.lua index b69f96b7..97ba3f94 100644 --- a/maps/scrap_towny_ffa/info.lua +++ b/maps/scrap_towny_ffa/info.lua @@ -12,11 +12,12 @@ Click on the "Info" button for full intro/help. Have fun and be comfy ^.^ -Changelog (9th October 2022): - - Towns have an initial PvP protection shield for 2h + +Changelog (10th October 2022): + - Towns have an initial PvP protection shield, size and duration is scaled with the biggest town size - Temporary PvP shield available in market for breaks / AFK - Improved base defenses and offline survivability - - Fixed some freezes / desyncs + - Loads of bugfixes including freezes and desyncs ]] local info_adv = @@ -43,7 +44,7 @@ Survive as long as you can. Raid other towns. Defend your town. - It's possible to automate trading with the town center! How cool is that?!! Try it out. Tip: use filter inserters with to get coins/iron/.. out of the market -- Fishes procreate near towns (the more fishes, the quicker they multiply) +- Fishes procreate near towns. The more fishes, the quicker they multiply. Automated fish farm, anyone? - Use /rename-town (chat command) to rename your town diff --git a/maps/scrap_towny_ffa/market.lua b/maps/scrap_towny_ffa/market.lua index 6429499b..5dda9190 100644 --- a/maps/scrap_towny_ffa/market.lua +++ b/maps/scrap_towny_ffa/market.lua @@ -100,7 +100,7 @@ local upgrade_functions = { -- Double-check with the player to prevent accidental clicks if this.pvp_shield_warned[player.force.name] ~= nil and game.tick - this.pvp_shield_warned[player.force.name] < 60 * 60 then if not Town_center.enemy_players_nearby(town_center, 100) then - PvPShield.add_shield(surface, force, market.position, shield_lifetime_ticks, 2 * 60 * 60, true) + PvPShield.add_shield(surface, force, market.position, 120, shield_lifetime_ticks, 2 * 60 * 60, true) surface.play_sound({path = 'utility/scenario_message', position = player.position, volume_modifier = 1}) this.pvp_shield_warned[player.force.name] = nil else diff --git a/maps/scrap_towny_ffa/pvp_shield.lua b/maps/scrap_towny_ffa/pvp_shield.lua index 95c07f38..6232d333 100644 --- a/maps/scrap_towny_ffa/pvp_shield.lua +++ b/maps/scrap_towny_ffa/pvp_shield.lua @@ -6,10 +6,7 @@ local Event = require 'utils.event' local ScenarioTable = require 'maps.scrap_towny_ffa.table' local CommonFunctions = require 'utils.common' -local max_size = 120 local beam_type = 'electric-beam-no-sound' -local default_lifetime_ticks = 2 * 60 * 60 * 60 -local default_time_to_full_size_ticks = 60 * 60 local function draw_borders(shield) local surface = shield.surface @@ -38,7 +35,7 @@ end local function scale_size_and_box(shield) local time_scale = math.min(1, (game.tick - shield.lifetime_start) / shield.time_to_full_size_ticks) - local scaled_size = time_scale * max_size + local scaled_size = time_scale * shield.max_size local center = shield.center local box = {left_top = { x = center.x - scaled_size / 2, y = center.y - scaled_size / 2}, @@ -47,17 +44,10 @@ local function scale_size_and_box(shield) shield.size = scaled_size end -function Public.add_shield(surface, force, center, lifetime_ticks, time_to_full_size_ticks, is_pause_mode) +function Public.add_shield(surface, force, center, max_size, lifetime_ticks, time_to_full_size_ticks, is_pause_mode) local this = ScenarioTable.get_table() - if not lifetime_ticks then - lifetime_ticks = default_lifetime_ticks - end - if not time_to_full_size_ticks then - time_to_full_size_ticks = default_time_to_full_size_ticks - end - - local shield = {surface = surface, force = force, center = center, max_lifetime_ticks = lifetime_ticks, + local shield = {surface = surface, force = force, center = center, max_size = max_size, max_lifetime_ticks = lifetime_ticks, time_to_full_size_ticks = time_to_full_size_ticks, lifetime_start = game.tick, is_pause_mode = is_pause_mode} if is_pause_mode then @@ -97,7 +87,7 @@ local function update_shield_lifetime() local this = ScenarioTable.get_table() for _, shield in pairs(this.pvp_shields) do if Public.remaining_lifetime(shield) > 0 then - if shield.size < max_size then + if shield.size < shield.max_size then remove_drawn_borders(shield) scale_size_and_box(shield) draw_borders(shield) diff --git a/maps/scrap_towny_ffa/table.lua b/maps/scrap_towny_ffa/table.lua index c4949dfb..e64a8a45 100644 --- a/maps/scrap_towny_ffa/table.lua +++ b/maps/scrap_towny_ffa/table.lua @@ -18,7 +18,6 @@ function Public.reset_table() this.rocket_launches = {} this.requests = {} this.town_centers = {} - this.number_of_towns = 0 this.cooldowns_town_placement = {} this.last_respawn = {} this.last_death = {} diff --git a/maps/scrap_towny_ffa/team.lua b/maps/scrap_towny_ffa/team.lua index 97f85a3d..f3e4eb05 100644 --- a/maps/scrap_towny_ffa/team.lua +++ b/maps/scrap_towny_ffa/team.lua @@ -42,6 +42,11 @@ local destroy_robot_types = { ['logistic-robot'] = true } +local storage_types = { + ['container'] = true, + ['logistic-container'] = true, + ['storage-tank'] = true +} -- hand craftable local player_force_disabled_recipes = { 'lab', @@ -775,6 +780,9 @@ local function kill_force(force_name, cause) local balance = town_center.coin_balance local town_name = town_center.town_name surface.create_entity({name = 'big-artillery-explosion', position = position}) + + local is_suicide = force_name == cause.force.name + for _, player in pairs(force.players) do this.spawn_point[player.index] = nil this.cooldowns_town_placement[player.index] = game.tick + 3600 * 5 @@ -794,27 +802,17 @@ local function kill_force(force_name, cause) if destroy_military_types[e.type] == true then surface.create_entity({name = 'big-artillery-explosion', position = position}) e.die() - else - if destroy_robot_types[e.type] == true then - surface.create_entity({name = 'explosion', position = position}) + elseif destroy_robot_types[e.type] == true then + surface.create_entity({name = 'explosion', position = position}) + e.die() + elseif destroy_wall_types[e.type] == true then + e.die() + elseif storage_types[e.type] ~= true then -- spare chests + local random = math_random() + if random > 0.5 or e.health == nil then e.die() - else - if destroy_wall_types[e.type] == true then - e.die() - end - end - end - end - end - for _, e in pairs(surface.find_entities_filtered({force = force_name})) do - if e.valid then - local damage = math_random() * 2.5 - 0.5 - if damage > 0 then - if damage >= 1 or e.health == nil then - e.die() - else - local health = e.health - e.health = health * damage + elseif random < 0.25 then + e.health = e.health * math_random() end end end @@ -828,15 +826,17 @@ local function kill_force(force_name, cause) if this.pvp_shields[force_name] then PvPShield.remove_shield(this.pvp_shields[force_name]) end + game.merge_forces(force_name, 'neutral') this.town_centers[force_name] = nil - this.number_of_towns = this.number_of_towns - 1 delete_chart_tag_for_all_forces(market) -- reward the killer local message - if cause == nil or not cause.valid or cause.force == nil then - message = town_name .. ' has fallen!' + if is_suicide then + message = town_name .. ' has given up' + elseif cause == nil or not cause.valid or cause.force == nil then + message = town_name .. ' has fallen to an unknown entity (FIXME ID0)!' -- TODO: remove after some testing elseif cause.force.name == 'player' or cause.force.name == 'rogue' then local items = {name = 'coin', count = balance} town_center.coin_balance = 0 @@ -848,12 +848,14 @@ local function kill_force(force_name, cause) chest.insert(items) end end - if cause.name then - message = town_name .. ' has fallen to ' .. cause.name .. '!' + if cause.player then + message = town_name .. ' has fallen to ' .. cause.player.name .. '!' elseif cause.force.name == 'player' then message = town_name .. ' has fallen to outlanders!' - else + elseif cause.force.name == 'rogue' then message = town_name .. ' has fallen to rogues!' + else + message = town_name .. ' has fallen to an unknown entity (FIXME ID1)!' -- TODO: remove after some testing end elseif cause.force.name ~= 'enemy' then if this.town_centers[cause.force.name] ~= nil then @@ -862,7 +864,13 @@ local function kill_force(force_name, cause) killer_town_center.coin_balance = killer_town_center.coin_balance + balance cause.force.print(balance .. " coins have been transferred to your town") end - message = town_name .. ' has fallen to ' .. killer_town_center.town_name .. '!' + if cause.player then + message = town_name .. ' has fallen to ' .. cause.player.name .. ' from ' .. killer_town_center.town_name .. '!' + else + message = town_name .. ' has fallen to ' .. killer_town_center.town_name .. '!' + end + else + message = town_name .. ' has fallen to an unknown entity (FIXME ID2)!' -- TODO: remove after some testing end else message = town_name .. ' has fallen to the biters!' @@ -1014,14 +1022,6 @@ local function on_player_dropped_item(event) end end ----- when a player dies, reveal their base to everyone ---local function on_player_died(event) --- local player = game.players[event.player_index] --- if not player.character then return end --- if not player.character.valid then return end --- reveal_entity_to_all(player.character) ---end - local function on_entity_damaged(event) local entity = event.entity if not entity or not entity.valid then diff --git a/maps/scrap_towny_ffa/town_center.lua b/maps/scrap_towny_ffa/town_center.lua index a5926084..d016345f 100644 --- a/maps/scrap_towny_ffa/town_center.lua +++ b/maps/scrap_towny_ffa/town_center.lua @@ -15,6 +15,7 @@ local Colors = require 'maps.scrap_towny_ffa.colors' local Enemy = require 'maps.scrap_towny_ffa.enemy' local Color = require 'utils.color_presets' local PvPShield = require 'maps.scrap_towny_ffa.pvp_shield' +local Evolution = require 'maps.scrap_towny_ffa.evolution' local town_radius = 27 local radius_between_towns = 120 @@ -304,7 +305,9 @@ local function is_valid_location(force_name, surface, position) end end - if this.number_of_towns > 48 then + local town_count = 0 + for _ in pairs(this.town_centers) do town_count = town_count + 1 end + if town_count > 48 then surface.create_entity( { name = 'flying-text', @@ -401,6 +404,22 @@ local function update_pvp_shields_display() end end +local function add_pvp_shield_scaled(position, force, surface) + local evo = Evolution.get_highest_evolution() + + local min_size = 60 + local max_size = 120 + local min_duration = 0.5 * 60 * 60 * 60 + local max_duration = 8 * 60 * 60 * 60 + local lifetime_ticks = min_duration + evo * (max_duration - min_duration) + local size = min_size + evo * (max_size - min_size) + + PvPShield.add_shield(surface, force, position, size, lifetime_ticks, 60 * 60) + update_pvp_shields_display() + force.print("Based on the highest tech on map, your town deploys a PvP shield of " + .. size .. " tiles for " .. string.format("%.0f", lifetime_ticks/60/60) .. " minutes") +end + local function found_town(event) local entity = event.created_entity -- is a valid entity placed? @@ -560,12 +579,8 @@ local function found_town(event) scale_with_zoom = false } - this.number_of_towns = this.number_of_towns + 1 - Enemy.clear_enemies(position, surface, town_radius * 5) draw_town_spawn(force_name) - PvPShield.add_shield(surface, force, { x = position.x + 0.5, y = position.y + 0.5}) -- Market center is slightly shifted - update_pvp_shields_display() -- set the spawn point local pos = {x = town_center.market.position.x, y = town_center.market.position.y + 4} @@ -575,6 +590,7 @@ local function found_town(event) Team.add_player_to_town(player, town_center) Team.remove_key(player.index) Team.add_chart_tag(town_center) + add_pvp_shield_scaled({ x = position.x + 0.5, y = position.y + 0.5}, force, surface) -- Market center is slightly shifted game.print('>> ' .. player.name .. ' has founded a new town!', {255, 255, 0}) Server.to_discord_embed(player.name .. ' has founded a new town!') diff --git a/maps/scrap_towny_ffa/vehicles.lua b/maps/scrap_towny_ffa/vehicles.lua index 150d8b20..259a04ce 100644 --- a/maps/scrap_towny_ffa/vehicles.lua +++ b/maps/scrap_towny_ffa/vehicles.lua @@ -8,6 +8,9 @@ local function on_player_driving_changed_state(event) return end local vehicle = player.vehicle + if player.force.name ~= 'player' and player.force.name ~= 'rogue' then + return + end if vehicle and vehicle.valid then -- player entered a vehicle if vehicle.name == 'locomotive' or vehicle.name == 'cargo-wagon' or vehicle.name == 'fluid-wagon' then