mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-01-05 22:53:39 +02:00
Merge pull request #1144 from Refactorio/crash_site_dunes
Crash Site Arrakis
This commit is contained in:
commit
cb2b142e42
@ -21,12 +21,12 @@ crash_site_airstrike_count_name_label=Airstrike Damage __1__
|
||||
crash_site_airstrike_not_researched=You have not researched airstrike yet. Visit the market at the spawn [gps=-3,-3,redmew]
|
||||
crash_site_airstrike_insufficient_currency_error=To send an air strike, load __1__ more poison capsules into the payment chest [gps=-0.5,-3.5,redmew]
|
||||
crash_site_airstrike_friendly_fire_error=You don't want to do that, no enemies found in the target area.
|
||||
crash_site_airstrike_damage_upgrade_success=Airstrike damage has been upgraded to level __1__
|
||||
crash_site_airstrike_radius_upgrade_success=Airstrike radius has been upgraded to level __1__
|
||||
crash_site_airstrike_damage_upgrade_success=__1__ has upgraded Airstrike Damage to level __2__
|
||||
crash_site_airstrike_radius_upgrade_success=__1__ has updgraded Airstrike Radius to level __2__
|
||||
crash_site_airstrike_success=__1__ called an air strike [gps=__2__,__3__,redmew]
|
||||
crash_site_rocket_tanks_name_label=Rocket Tanks Fire Interval __1__
|
||||
crash_site_rocket_tank_upgrade_success=__1__ has upgraded Rocket Tank interval to level __2__
|
||||
crash_site_rocket_tanks_description= Upgrade the rocket tank firing interval to reduce the time between rockets.\n\nPlace rockets in the tank inventory to have them automatically target enemy worms and nests.
|
||||
crash_site_rocket_tank_upgrade_success=Rocket tank interval has been upgraded to level __1__
|
||||
max_level=(MAX LEVEL)
|
||||
dataset_copy=Copies a dataset
|
||||
dataset_move=Moves a dataset
|
||||
|
@ -141,6 +141,7 @@ aliens_killed=Aliens liberated
|
||||
coins_earned=Coins earned
|
||||
coins_spent=Coins spent
|
||||
player_deaths=Player deaths
|
||||
player_kills=Player_kills
|
||||
player_console_chats=Player console chats
|
||||
player_items_crafted=Player items crafted
|
||||
player_distance_walked=Distance walked
|
||||
|
@ -431,10 +431,12 @@ function Public.control(config)
|
||||
local strikeCost = count * 4
|
||||
|
||||
local name = item.name
|
||||
local player_name = event.player.name
|
||||
if name == 'airstrike_damage' then
|
||||
airstrike_data.count_level = airstrike_data.count_level + 1
|
||||
|
||||
Toast.toast_all_players(15, {'command_description.crash_site_airstrike_damage_upgrade_success', count_level})
|
||||
Toast.toast_all_players(15, {'command_description.crash_site_airstrike_damage_upgrade_success', player_name, count_level})
|
||||
Server.to_discord_bold('*** '..player_name..' has upgraded Airstrike Damage to level '..count_level..' ***')
|
||||
item.name_label = {'command_description.crash_site_airstrike_count_name_label', (count_level + 1)}
|
||||
item.price = math.floor(math.exp(airstrike_data.count_level ^ 0.8) / 2) * 1000
|
||||
item.description = {
|
||||
@ -447,8 +449,8 @@ function Public.control(config)
|
||||
Retailer.set_item(market_id, item) -- this updates the retailer with the new item values.
|
||||
elseif name == 'airstrike_radius' then
|
||||
airstrike_data.radius_level = airstrike_data.radius_level + 1
|
||||
Toast.toast_all_players(15,
|
||||
{'command_description.crash_site_airstrike_radius_upgrade_success', radius_level})
|
||||
Toast.toast_all_players(15, {'command_description.crash_site_airstrike_radius_upgrade_success', player_name, radius_level})
|
||||
Server.to_discord_bold('*** '..player_name..' has upgraded Airstrike Radius to level '..radius_level..' ***')
|
||||
item.name_label = {'command_description.crash_site_airstrike_radius_name_label', (radius_level + 1)}
|
||||
item.description = {
|
||||
'command_description.crash_site_airstrike_radius',
|
||||
|
@ -3,6 +3,7 @@ local Global = require 'utils.global'
|
||||
local Toast = require 'features.gui.toast'
|
||||
local Retailer = require 'features.retailer'
|
||||
local Token = require 'utils.token'
|
||||
local Server = require 'features.server'
|
||||
|
||||
local tank_entities = {}
|
||||
local tank_research = {interval_level = 1}
|
||||
@ -98,8 +99,8 @@ Event.add(Retailer.events.on_market_purchase, function(event)
|
||||
local max_level = 5
|
||||
if interval_level < max_level then
|
||||
tank_research.interval_level = tank_research.interval_level + 1
|
||||
|
||||
Toast.toast_all_players(15, {'command_description.crash_site_rocket_tank_upgrade_success', interval_level})
|
||||
Toast.toast_all_players(15, {'command_description.crash_site_rocket_tank_upgrade_success', event.player.name, interval_level})
|
||||
Server.to_discord_bold('*** '..event.player.name..' has upgraded Rocket Tanks to level '..interval_level..' ***') -- doesn't need locale string
|
||||
item.name_label = {'command_description.crash_site_rocket_tanks_name_label', (interval_level + 1)}
|
||||
item.price = (interval_level + 1) * 1000
|
||||
Retailer.set_item(market_id, item) -- this updates the retailer with the new item values.
|
130
map_gen/maps/crash_site/features/sandworms.lua
Normal file
130
map_gen/maps/crash_site/features/sandworms.lua
Normal file
@ -0,0 +1,130 @@
|
||||
-- This module starts spawning worms every 5 to 10 minutes (approx) when a roboport is placed.
|
||||
-- Makes it necessary to defend roboports and limits the usefulness of large roboport networks
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
|
||||
local set_timeout_in_ticks = Task.set_timeout_in_ticks
|
||||
local min_worm_period_secs = 300 -- 5 minutes
|
||||
local max_worm_period_secs = 900 -- 15 minutes
|
||||
local max_worm_spawn_radius = 30
|
||||
|
||||
local roboports = {}
|
||||
Global.register({roboports = roboports}, function(tbl)
|
||||
roboports = tbl.roboports
|
||||
|
||||
end)
|
||||
|
||||
local sandworms = {
|
||||
['small-worm-turret'] = {evo_min = 0, evo_max = 0.4},
|
||||
['medium-worm-turret'] = {evo_min = 0.4, evo_max = 0.6},
|
||||
['big-worm-turret'] = {evo_min = 0.6, evo_max = 0.9},
|
||||
['behemoth-worm-turret'] = {evo_min = 0.9, evo_max = 1}
|
||||
}
|
||||
|
||||
local sandworm_biters = {
|
||||
['small-worm-turret'] = {['small-biter'] = {min = 2.5, max = 3.5}, ['medium-biter'] = {min = 1.0, max = 2}},
|
||||
['medium-worm-turret'] = {['small-biter'] = {min = 2.5, max = 6.5}, ['medium-biter'] = {min = 1.0, max = 5}},
|
||||
['big-worm-turret'] = {
|
||||
['small-biter'] = {min = 2.5, max = 4},
|
||||
['medium-biter'] = {min = 1.5, max = 2.2},
|
||||
['medium-spitter'] = {min = 1.5, max = 2.2},
|
||||
['big-biter'] = {min = 1.5, max = 2.2}
|
||||
},
|
||||
['behemoth-worm-turret'] = {
|
||||
['small-biter'] = {min = 4, max = 5.2},
|
||||
['medium-biter'] = {min = 2.5, max = 3.8},
|
||||
['big-biter'] = {min = 1.2, max = 2.4},
|
||||
['big-spitter'] = {min = 1.2, max = 2.4},
|
||||
['behemoth-biter'] = {min = 1.2, max = 2.4}
|
||||
}
|
||||
}
|
||||
|
||||
local function spawn_sandworms(entity)
|
||||
local evolution = game.forces["enemy"].evolution_factor
|
||||
for index, worm_type in pairs(sandworms) do
|
||||
-- Determine which worm type to spawn based on the evolution
|
||||
if (evolution > worm_type.evo_min) and (evolution <= worm_type.evo_max) then
|
||||
local s = entity.surface
|
||||
local worm_position = {
|
||||
entity.position.x + math.random(max_worm_spawn_radius * -1, max_worm_spawn_radius),
|
||||
entity.position.y + math.random(max_worm_spawn_radius * -1, max_worm_spawn_radius)
|
||||
}
|
||||
worm_position = s.find_non_colliding_position(index, worm_position, 20, 1)
|
||||
if worm_position then
|
||||
s.create_entity {name = index, position = worm_position, force = "enemy"}
|
||||
end
|
||||
-- For the appropriate worm for each evolution region, spawn some accompanying biters to attack the roboport
|
||||
for worm, biters in pairs(sandworm_biters) do
|
||||
if worm == index then
|
||||
for biter, data in pairs(biters) do
|
||||
local amount = math.random(data.min, data.max)
|
||||
local extra_chance = amount % 1
|
||||
if extra_chance > 0 then
|
||||
if math.random(0,1) <= extra_chance then
|
||||
amount = math.ceil(amount)
|
||||
else
|
||||
amount = math.floor(amount)
|
||||
end
|
||||
end
|
||||
for _ = 1, amount do
|
||||
local pos = s.find_non_colliding_position(biter, worm_position, 20, 1)
|
||||
if pos then
|
||||
local spawned_biter = s.create_entity {name = biter, position = pos, force = "enemy"}
|
||||
spawned_biter.set_command({type = defines.command.attack, target = entity})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local thump_text_callback
|
||||
thump_text_callback = Token.register(function(entity)
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
local s = entity.surface
|
||||
local entity_position = entity.position
|
||||
s.create_entity{name="flying-text", position={(entity_position.x + math.random(-3,3)),(entity_position.y + math.random(0,3))}, text="*thump*", color={r=0.6,g=0.4,b=0}}
|
||||
end)
|
||||
|
||||
local worm_callback
|
||||
worm_callback = Token.register(function(entity)
|
||||
if entity.valid then -- stops the callback if the roboport has been removed
|
||||
spawn_sandworms(entity)
|
||||
local callback_timer = math.random(min_worm_period_secs * 60, max_worm_period_secs * 60)
|
||||
set_timeout_in_ticks(callback_timer, worm_callback, entity)
|
||||
for i = 1, 5 do -- repeat thump text 30 seconds before worm will arrive to give players visual reminder they need to protect roboports
|
||||
set_timeout_in_ticks(callback_timer-1800+(120*i), thump_text_callback, entity)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local function start_worm_attacks(entity)
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
local callback_timer = math.random(min_worm_period_secs * 60, max_worm_period_secs * 60)
|
||||
set_timeout_in_ticks(callback_timer, worm_callback, entity)
|
||||
for i = 1, 5 do
|
||||
set_timeout_in_ticks(120*i, thump_text_callback, entity)
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_robot_built_entity, function(event)
|
||||
if event.created_entity.valid and event.created_entity.name == 'roboport' then
|
||||
start_worm_attacks(event.created_entity)
|
||||
end
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_built_entity, function(event)
|
||||
if event.created_entity.valid and event.created_entity.name == 'roboport' then
|
||||
start_worm_attacks(event.created_entity)
|
||||
local player = game.get_player(event.player_index)
|
||||
player.print("A sandworm approaches.....")
|
||||
end
|
||||
end)
|
89
map_gen/maps/crash_site/features/vehicle_repair_beams.lua
Normal file
89
map_gen/maps/crash_site/features/vehicle_repair_beams.lua
Normal file
@ -0,0 +1,89 @@
|
||||
-- This module allows cars and tanks (any vehicle of type == car) to repair friendly structures
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local car_entities = {}
|
||||
|
||||
Global.register({car_entities = car_entities}, function(tbl)
|
||||
car_entities = tbl.car_entities
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_entity_destroyed, function(event)
|
||||
car_entities[event.unit_number] = nil
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_player_driving_changed_state, function(event)
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid or (entity.type ~= 'car') then
|
||||
return
|
||||
end
|
||||
if not entity.get_driver() then -- no driver? Remove that car from the table to check
|
||||
car_entities[entity.unit_number] = nil
|
||||
else
|
||||
local player = game.get_player(event.player_index)
|
||||
local driver = entity.get_driver()
|
||||
if player ~= driver.player then -- if the player that got in the vehicle is not the driver then return
|
||||
return
|
||||
else
|
||||
car_entities[entity.unit_number] = entity
|
||||
script.register_on_entity_destroyed(entity)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local turrets = {
|
||||
['gun-turret'] = true,
|
||||
['laser-turret'] = true,
|
||||
['flamethrower-turret'] = true,
|
||||
['artillery-turret'] = true
|
||||
}
|
||||
|
||||
local function on_nth_tick()
|
||||
for _, car in pairs(car_entities) do
|
||||
if not car.valid or car.speed ~= 0 then -- only allow cars to repair if they have a driver and are not moving
|
||||
goto continue
|
||||
end
|
||||
|
||||
local inv = car.get_inventory(defines.inventory.car_trunk)
|
||||
local stack = inv.find_item_stack('repair-pack')
|
||||
if not stack then
|
||||
goto continue
|
||||
end
|
||||
|
||||
-- Search for damaged entities and heal them
|
||||
local surface = car.surface
|
||||
local targets = surface.find_entities_filtered {position = car.position, radius = 20, force = "player"}
|
||||
|
||||
local repair_amount = 150
|
||||
for i, entity in pairs(targets) do
|
||||
if entity.unit_number and (entity.get_health_ratio() or 1) < 1 then
|
||||
-- Rules for when cars/tanks can repair:
|
||||
-- if the damaged entity is a turret, the turret cooldown must be complete (entity.active == true) to help reduce turret creeping
|
||||
-- if the damaged entity is not the car. Cars can heal other cars but not themselves.
|
||||
-- if the damaged entity is not a character
|
||||
-- if the entity is not moving. Vehicles must have a speed of 0, entities that can't move will be nil
|
||||
if (entity ~= car and (entity.speed == 0 or entity.speed == nil) and entity.name ~= 'character' and not turrets[entity.name]) or (turrets[entity.name] and entity.active == true) then
|
||||
surface.create_entity {
|
||||
name = "electric-beam",
|
||||
position = car.position,
|
||||
source = car.position,
|
||||
target = entity.position, -- use the position not the entity otherwise it will damage the entity
|
||||
speed = 1,
|
||||
duration = 20
|
||||
}
|
||||
local max_health = entity.prototype.max_health
|
||||
if (max_health - entity.health) < repair_amount then
|
||||
repair_amount = max_health - entity.health -- so that the player doesn't lose part of a repair pack partially healing an entity
|
||||
end
|
||||
entity.health = entity.health + repair_amount
|
||||
stack.drain_durability(repair_amount)
|
||||
goto continue -- break out because we only want to heal one entity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
::continue::
|
||||
end
|
||||
end
|
||||
|
||||
Event.on_nth_tick(60, on_nth_tick)
|
@ -998,8 +998,10 @@ local function do_outpost_upgrade(event)
|
||||
local level = outpost_data.level + 1
|
||||
outpost_data.level = level
|
||||
|
||||
|
||||
local player_name = event.player.name
|
||||
local outpost_name = Retailer.get_market_group_label(outpost_id)
|
||||
local message = concat {outpost_name, ' has been upgraded to level ', level}
|
||||
local message = concat {player_name, ' has upgraded ', outpost_name, ' to level ', level}
|
||||
|
||||
CrashSiteToast.do_outpost_toast(outpost_data.market, message)
|
||||
Server.to_discord_bold(concat {'*** ', message, ' ***'})
|
||||
|
48
map_gen/maps/crash_site/presets/arrakis.lua
Normal file
48
map_gen/maps/crash_site/presets/arrakis.lua
Normal file
@ -0,0 +1,48 @@
|
||||
require 'map_gen.maps.crash_site.features.sandworms'
|
||||
require 'map_gen.maps.crash_site.features.vehicle_repair_beams'
|
||||
|
||||
local ScenarioInfo = require 'features.gui.info'
|
||||
local MGSP = require 'resources.map_gen_settings'
|
||||
|
||||
local config = {
|
||||
scenario_name = 'crashsite-arrakis',
|
||||
map_gen_settings = {
|
||||
MGSP.sand_only,
|
||||
MGSP.water_none,
|
||||
MGSP.starting_area_very_low,
|
||||
MGSP.ore_oil_none,
|
||||
MGSP.enemy_none,
|
||||
MGSP.tree_none,
|
||||
MGSP.cliff_none,
|
||||
{
|
||||
property_expression_names = {
|
||||
['control-setting:moisture:bias'] = '-0.500000'
|
||||
},
|
||||
autoplace_controls = {
|
||||
trees = {
|
||||
frequency = 6,
|
||||
richness = 1,
|
||||
size = 0.1666666716337204
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
local Scenario = require 'map_gen.maps.crash_site.scenario'
|
||||
ScenarioInfo.set_map_name('Crashsite Arrakis')
|
||||
ScenarioInfo.set_map_description('Capture outposts and defend against the biters. Even drier than desert, sandworms roam the desert and will attack roboports on sight.')
|
||||
ScenarioInfo.add_map_extra_info(
|
||||
[[
|
||||
- Arrakis is even drier than crash site Desert.
|
||||
- Sandworms are attracted to the vibration caused by roboports and will spawn intermittently to neutralise this threat to their peace.
|
||||
- Cars have repair beams.
|
||||
- Outposts have enemy turrets defending them.
|
||||
- Outposts have loot and provide a steady stream of resources.
|
||||
- Outpost markets to purchase items and outpost upgrades.
|
||||
- Capturing outposts increases evolution.\n- Reduced damage by all player weapons, turrets, and ammo.
|
||||
- Biters have more health and deal more damage.\n- Biters and spitters spawn on death of entities.
|
||||
]]
|
||||
)
|
||||
|
||||
return Scenario.init(config)
|
@ -1,4 +1,5 @@
|
||||
local MGSP = require 'resources.map_gen_settings'
|
||||
local ScenarioInfo = require 'features.gui.info'
|
||||
|
||||
local config = {
|
||||
scenario_name = 'crashsite-desert',
|
||||
@ -29,5 +30,19 @@ local config = {
|
||||
}
|
||||
|
||||
local Scenario = require 'map_gen.maps.crash_site.scenario'
|
||||
ScenarioInfo.set_map_name('Crashsite Desert')
|
||||
ScenarioInfo.set_map_description('A desert version of Crash Site. Capture outposts and defend against the biters.')
|
||||
ScenarioInfo.add_map_extra_info(
|
||||
[[
|
||||
A desert version of Crash Site, with sandy terrain, scattered oases and few trees.
|
||||
- Outposts have enemy turrets defending them.
|
||||
- Outposts have loot and provide a steady stream of resources.
|
||||
- Outpost markets to purchase items and outpost upgrades.
|
||||
- Capturing outposts increases evolution.
|
||||
- Reduced damage by all player weapons, turrets, and ammo.
|
||||
- Biters have more health and deal more damage.
|
||||
- Biters and spitters spawn on death of entities.
|
||||
]]
|
||||
)
|
||||
|
||||
return Scenario.init(config)
|
||||
|
@ -1,4 +1,5 @@
|
||||
local MGSP = require 'resources.map_gen_settings'
|
||||
local ScenarioInfo = require 'features.gui.info'
|
||||
|
||||
local config = {
|
||||
scenario_name = 'crashsite',
|
||||
@ -17,5 +18,17 @@ local config = {
|
||||
}
|
||||
|
||||
local Scenario = require 'map_gen.maps.crash_site.scenario'
|
||||
ScenarioInfo.set_map_name('Crashsite')
|
||||
ScenarioInfo.set_map_description('Capture outposts and defend against the biters.')
|
||||
ScenarioInfo.add_map_extra_info(
|
||||
[[
|
||||
- Outposts have enemy turrets defending them.
|
||||
- Outposts have loot and provide a steady stream of resources.
|
||||
- Outpost markets to purchase items and outpost upgrades.
|
||||
- Capturing outposts increases evolution.\n- Reduced damage by all player weapons, turrets, and ammo.
|
||||
- Biters have more health and deal more damage.
|
||||
- Biters and spitters spawn on death of entities.
|
||||
]]
|
||||
)
|
||||
|
||||
return Scenario.init(config)
|
||||
|
@ -1,5 +1,6 @@
|
||||
local b = require 'map_gen.shared.builders'
|
||||
local MGSP = require 'resources.map_gen_settings'
|
||||
local ScenarioInfo = require 'features.gui.info'
|
||||
|
||||
local type = type
|
||||
local water_tiles = b.water_tiles
|
||||
@ -34,6 +35,20 @@ local config = {
|
||||
}
|
||||
|
||||
local Scenario = require 'map_gen.maps.crash_site.scenario'
|
||||
ScenarioInfo.set_map_name('Crashsite World')
|
||||
ScenarioInfo.set_map_description('Capture outposts and defend against the biters.')
|
||||
ScenarioInfo.add_map_extra_info(
|
||||
[[
|
||||
- A world map version of Crash Site.
|
||||
- Outposts have enemy turrets defending them.
|
||||
- Outposts have loot and provide a steady stream of resources.
|
||||
- Outpost markets to purchase items and outpost upgrades.
|
||||
- Capturing outposts increases evolution.
|
||||
- Reduced damage by all player weapons, turrets, and ammo.
|
||||
- Biters have more health and deal more damage.
|
||||
- Biters and spitters spawn on death of entities.
|
||||
]]
|
||||
)
|
||||
local crashsite = Scenario.init(config)
|
||||
|
||||
local function get_tile_name(tile)
|
||||
|
@ -1,7 +1,7 @@
|
||||
require 'map_gen.maps.crash_site.blueprint_extractor'
|
||||
require 'map_gen.maps.crash_site.events'
|
||||
require 'map_gen.maps.crash_site.weapon_balance'
|
||||
require 'map_gen.maps.crash_site.rocket_tanks'
|
||||
require 'map_gen.maps.crash_site.features.rocket_tanks'
|
||||
|
||||
|
||||
local b = require 'map_gen.shared.builders'
|
||||
@ -11,7 +11,6 @@ local OutpostBuilder = require 'map_gen.maps.crash_site.outpost_builder'
|
||||
local Token = require 'utils.token'
|
||||
local Task = require 'utils.task'
|
||||
local math = require 'utils.math'
|
||||
local ScenarioInfo = require 'features.gui.info'
|
||||
local table = require 'utils.table'
|
||||
local RS = require 'map_gen.shared.redmew_surface'
|
||||
local MGSP = require 'resources.map_gen_settings'
|
||||
@ -48,13 +47,6 @@ local function control(config)
|
||||
RS.set_map_gen_settings(map_gen_settings)
|
||||
end
|
||||
|
||||
-- Comment out this block if you're getting scenario info from another source.
|
||||
ScenarioInfo.set_map_name('Crashsite')
|
||||
ScenarioInfo.set_map_description('Capture outposts and defend against the biters.')
|
||||
ScenarioInfo.add_map_extra_info(
|
||||
'- Outposts have enemy turrets defending them.\n- Outposts have loot and provide a steady stream of resources.\n- Outpost markets to purchase items and outpost upgrades.\n- Capturing outposts increases evolution.\n- Reduced damage by all player weapons, turrets, and ammo.\n- Biters have more health and deal more damage.\n- Biters and spitters spawn on death of entities.'
|
||||
)
|
||||
|
||||
RedmewConfig.market.enabled = false
|
||||
RedmewConfig.biter_attacks.enabled = false
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user