mirror of
https://github.com/Refactorio/RedMew.git
synced 2025-03-17 21:08:08 +02:00
Changed all windows style line endings to unix style line endings (#393)
This commit is contained in:
parent
bdfd122f3c
commit
7fa48bc583
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.lua text eol=lf
|
||||
*.md text eol=lf
|
@ -1,6 +1,6 @@
|
||||
## RedMew Documentation Index
|
||||
- [Installing and Using the RedMew Scenario](Installation.md)
|
||||
- [Creating a New Scenario Using the RedMew Framework](NewScenario.md)
|
||||
|
||||
### Scenario Specific Documentation
|
||||
- [Diggy Installation and Configuration](scenarios/Diggy.md)
|
||||
## RedMew Documentation Index
|
||||
- [Installing and Using the RedMew Scenario](Installation.md)
|
||||
- [Creating a New Scenario Using the RedMew Framework](NewScenario.md)
|
||||
|
||||
### Scenario Specific Documentation
|
||||
- [Diggy Installation and Configuration](scenarios/Diggy.md)
|
||||
|
@ -1,49 +1,49 @@
|
||||
## Installing and Using the RedMew Scenario
|
||||
Some scenarios have more detailed information, please check [the index](Index.md) before continuing with the generic
|
||||
RedMew installation. To install the RedMew scenario directly into something playable, [download the
|
||||
archive](https://github.com/Valansch/RedMew/archive/develop.zip) and take the next step based on your Operating System.
|
||||
|
||||
- **Windows**: extract the the zip file into `%appdata%\Factorio\Scenarios\RedMew`
|
||||
- **MacOS**: extract the the zip file into `~/Library/Application Support/factorio/Scenarios/RedMew`
|
||||
- **Linux**: extract the the zip file into `~/.factorio/scenarios/RedMew`
|
||||
|
||||
Make sure it's called RedMew and there's a `control.lua` in the root of that directory. If you are using the RedMew
|
||||
scenario for a public-facing multi-player server, be sure to provide attribution back to github and keep links to the
|
||||
Discord, Patreon and website intact.
|
||||
|
||||
> _Note_: these locations are based on the default configuration [defined by
|
||||
factorio](https://wiki.factorio.com/Application_directory). If your installation is not default, you have to find your
|
||||
scenarios directory in another way.
|
||||
|
||||
## Generating maps
|
||||
There are 3 ways to generate maps using our scenario: Vanilla, FactorioMapConverter and Custom Maps.
|
||||
|
||||
### Vanilla
|
||||
Start the scenario from the scenario menu and you are ready to go. Additionally you can turn features on or off via
|
||||
[`control.lua`](../control.lua) if desired.
|
||||
|
||||
### Custom Maps
|
||||
There are many pre-made map modules that can be combined to create a unique map.
|
||||
|
||||
Map module previews can be found in [map_gen/data/.map_previews](../map_gen/data/.map_previews). You can select and
|
||||
activate a module by removing the `--` in front of the require in [`map_layout.lua`](../map_layout.lua).
|
||||
|
||||
You can mix as many modules as you want, as long as they logically fit together.
|
||||
|
||||
### FactorioMapConverter (Windows only)
|
||||
|
||||
You can generate your own maps from images. First convert the image file into a lua file (For example `image_data.lua`).
|
||||
Then use our scenario to load the `image_data.lua` file and generate the map from it.
|
||||
|
||||
To create your own map preview:
|
||||
1. Download the Map Converter [here](https://github.com/grilledham/FactorioMapConverter/releases) to generate the
|
||||
`image_data.lua`.
|
||||
2. Place your `image_data.lua` file in the `map_gen/data/presets/` directory.
|
||||
3. Create new lua file (for example `my_image.lua`) inside the folder `map_gen/presets/`. This file is used to configure
|
||||
your map (scale, translate etc.). To do this, you can copy `map_gen/presets/template.lua` and replace line 8 to point
|
||||
to your `image_data.lua`
|
||||
4. Load your new preset by adding a new line to `map_layout.lua`. This should look similar to this:
|
||||
```lua
|
||||
MAP_GEN = require "map_gen.presets.my_image.lua"
|
||||
```
|
||||
5. Load the scenario from the scenario menu.
|
||||
## Installing and Using the RedMew Scenario
|
||||
Some scenarios have more detailed information, please check [the index](Index.md) before continuing with the generic
|
||||
RedMew installation. To install the RedMew scenario directly into something playable, [download the
|
||||
archive](https://github.com/Valansch/RedMew/archive/develop.zip) and take the next step based on your Operating System.
|
||||
|
||||
- **Windows**: extract the the zip file into `%appdata%\Factorio\Scenarios\RedMew`
|
||||
- **MacOS**: extract the the zip file into `~/Library/Application Support/factorio/Scenarios/RedMew`
|
||||
- **Linux**: extract the the zip file into `~/.factorio/scenarios/RedMew`
|
||||
|
||||
Make sure it's called RedMew and there's a `control.lua` in the root of that directory. If you are using the RedMew
|
||||
scenario for a public-facing multi-player server, be sure to provide attribution back to github and keep links to the
|
||||
Discord, Patreon and website intact.
|
||||
|
||||
> _Note_: these locations are based on the default configuration [defined by
|
||||
factorio](https://wiki.factorio.com/Application_directory). If your installation is not default, you have to find your
|
||||
scenarios directory in another way.
|
||||
|
||||
## Generating maps
|
||||
There are 3 ways to generate maps using our scenario: Vanilla, FactorioMapConverter and Custom Maps.
|
||||
|
||||
### Vanilla
|
||||
Start the scenario from the scenario menu and you are ready to go. Additionally you can turn features on or off via
|
||||
[`control.lua`](../control.lua) if desired.
|
||||
|
||||
### Custom Maps
|
||||
There are many pre-made map modules that can be combined to create a unique map.
|
||||
|
||||
Map module previews can be found in [map_gen/data/.map_previews](../map_gen/data/.map_previews). You can select and
|
||||
activate a module by removing the `--` in front of the require in [`map_layout.lua`](../map_layout.lua).
|
||||
|
||||
You can mix as many modules as you want, as long as they logically fit together.
|
||||
|
||||
### FactorioMapConverter (Windows only)
|
||||
|
||||
You can generate your own maps from images. First convert the image file into a lua file (For example `image_data.lua`).
|
||||
Then use our scenario to load the `image_data.lua` file and generate the map from it.
|
||||
|
||||
To create your own map preview:
|
||||
1. Download the Map Converter [here](https://github.com/grilledham/FactorioMapConverter/releases) to generate the
|
||||
`image_data.lua`.
|
||||
2. Place your `image_data.lua` file in the `map_gen/data/presets/` directory.
|
||||
3. Create new lua file (for example `my_image.lua`) inside the folder `map_gen/presets/`. This file is used to configure
|
||||
your map (scale, translate etc.). To do this, you can copy `map_gen/presets/template.lua` and replace line 8 to point
|
||||
to your `image_data.lua`
|
||||
4. Load your new preset by adding a new line to `map_layout.lua`. This should look similar to this:
|
||||
```lua
|
||||
MAP_GEN = require "map_gen.presets.my_image.lua"
|
||||
```
|
||||
5. Load the scenario from the scenario menu.
|
||||
|
@ -1,28 +1,28 @@
|
||||
## Creating a New Scenario Using the RedMew Framework
|
||||
To add a new scenario and make it available to everyone that wants to use RedMew, make a Pull Request on github to
|
||||
request adding your scenario to the repository.
|
||||
|
||||
### Starting From Scratch
|
||||
Depending on the size of the scenario, it could be desired to have its own dedicated directory. By default a scenario
|
||||
is added in `map_gen/combined/your_scenario.lua`.
|
||||
|
||||
#### Step 1
|
||||
If you're not experienced with git, it's advised to read up on how git works first or ask someone else to help out. To
|
||||
get your change into the repository, you need to [fork the repository](https://help.github.com/articles/fork-a-repo/)
|
||||
and eventually make your Pull Request from there. [Clone](https://help.github.com/articles/cloning-a-repository/) the
|
||||
fork to your local environment and get your favorite IDE or Editor ready.
|
||||
|
||||
#### Step 2
|
||||
Small scenarios can go into a single lua file, bigger scenarios might need their own dedicated directory. To follow the
|
||||
RedMew structure for scenarios, create your scenario file: `map_gen/combined/your_scenario_file.lua`.
|
||||
|
||||
#### Step 3 (Optional)
|
||||
If you plan on making a bigger scenario, create a directory: `map_gen/combined/your_scenario_file/` where you can place
|
||||
your scenario specific lua files.
|
||||
|
||||
#### Step 4
|
||||
Regardless, the `map_gen/combined/your_scenario_file.lua` file will be the entry point for your scenario and will be
|
||||
loaded via `map_layout.lua`. Underneath `--combined--`, add your require: `require map_gen.combined.your_scenario_file`.
|
||||
|
||||
When making the Pull Request, make sure to comment the require in `map_layout.lua` as by default it should be off. To
|
||||
enable debugging and get some extra feedback during development, enable `_DEBUG` in `config.lua`.
|
||||
## Creating a New Scenario Using the RedMew Framework
|
||||
To add a new scenario and make it available to everyone that wants to use RedMew, make a Pull Request on github to
|
||||
request adding your scenario to the repository.
|
||||
|
||||
### Starting From Scratch
|
||||
Depending on the size of the scenario, it could be desired to have its own dedicated directory. By default a scenario
|
||||
is added in `map_gen/combined/your_scenario.lua`.
|
||||
|
||||
#### Step 1
|
||||
If you're not experienced with git, it's advised to read up on how git works first or ask someone else to help out. To
|
||||
get your change into the repository, you need to [fork the repository](https://help.github.com/articles/fork-a-repo/)
|
||||
and eventually make your Pull Request from there. [Clone](https://help.github.com/articles/cloning-a-repository/) the
|
||||
fork to your local environment and get your favorite IDE or Editor ready.
|
||||
|
||||
#### Step 2
|
||||
Small scenarios can go into a single lua file, bigger scenarios might need their own dedicated directory. To follow the
|
||||
RedMew structure for scenarios, create your scenario file: `map_gen/combined/your_scenario_file.lua`.
|
||||
|
||||
#### Step 3 (Optional)
|
||||
If you plan on making a bigger scenario, create a directory: `map_gen/combined/your_scenario_file/` where you can place
|
||||
your scenario specific lua files.
|
||||
|
||||
#### Step 4
|
||||
Regardless, the `map_gen/combined/your_scenario_file.lua` file will be the entry point for your scenario and will be
|
||||
loaded via `map_layout.lua`. Underneath `--combined--`, add your require: `require map_gen.combined.your_scenario_file`.
|
||||
|
||||
When making the Pull Request, make sure to comment the require in `map_layout.lua` as by default it should be off. To
|
||||
enable debugging and get some extra feedback during development, enable `_DEBUG` in `config.lua`.
|
||||
|
@ -1,79 +1,79 @@
|
||||
## Diggy Installation and Configuration
|
||||
Diggy is a custom [RedMew](../../README.md) scenario. You start out with nothing but a market, your pick-axe and some
|
||||
walls [deep, deep in the mine](https://www.youtube.com/watch?v=ov5pxaIbJlM). The goal is to launch a rocket, but be
|
||||
careful, there's not a lot of space and the mine is unstable!
|
||||
|
||||
- Gameplay: https://www.youtube.com/watch?v=J3lheDK-6Cw
|
||||
- Time lapse video: https://www.youtube.com/watch?v=4cRsx-wl_fk (By Namelesshunter Gaming)
|
||||
|
||||
> _Note_: Scenarios- also known as soft-mods- are scripted maps. They can be played online without having to download
|
||||
any mods as the script is included in the map.
|
||||
|
||||
### Scenario Information
|
||||
The idea of Diggy is similar to vanilla, except that it greatly changes how to build your factory. As you're in a cave,
|
||||
each rock you dig, each support entity you remove and every tile you mine, can cause a collapse. You can use walls,
|
||||
stone paths and (refined) concrete floor to increase the strength of your mine and reduce the chance of a collapse.
|
||||
|
||||
Whenever you place or remove a wall for example, the stress level of the area around it (9x9 tiles) will rise or lower.
|
||||
When a certain threshold is reached, the cave will collapse. You can stop this by quickly placing walls or run away as
|
||||
fast as you can. Letting the cave collapse _will_ destroy structures below it! The recommended pattern on dirt is to
|
||||
place a wall every 4th tile. Using stone paths and concrete will increase this to 5 tiles while refined concrete will
|
||||
make it 6.
|
||||
|
||||
## How to start Diggy for Single-player mode
|
||||
|
||||
#### Step 1
|
||||
Download the zip file from
|
||||
[https://github.com/Valansch/RedMew/archive/develop.zip](https://github.com/Valansch/RedMew/archive/develop.zip)
|
||||
|
||||
#### Step 2
|
||||
- **Windows**: extract the the zip file into `%appdata%\Factorio\Scenarios\Diggy`
|
||||
- **MacOS**: extract the the zip file into `~/Library/Application Support/factorio/Scenarios/Diggy`
|
||||
- **Linux**: extract the the zip file into `~/.factorio/scenarios/Diggy`
|
||||
|
||||
Make sure it's called Diggy and there's a `control.lua` in the root of that directory.
|
||||
|
||||
> _Note_: these locations are based on the default configuration [defined by
|
||||
factorio](https://wiki.factorio.com/Application_directory). If your installation is not default, you have to find your
|
||||
scenarios directory in another way.
|
||||
|
||||
#### Step 3
|
||||
Open `map_layout.lua` in that directory and look for `--require "map_gen.combined.diggy"`.
|
||||
Change this to `require "map_gen.combined.diggy"`, by removing the double dashes.
|
||||
|
||||
#### Step 4
|
||||
In factorio start either a local or online game via Scenarios. Select `Diggy` under
|
||||
`User scenarios` and start it up.
|
||||
|
||||
> _Note:_ Downloading the latest version might not always be a functional version, please consult on discord for a
|
||||
working version if this is the case.
|
||||
|
||||
#### Step 5 (optional)
|
||||
Diggy is designed to work for at least 15 players online, working together. It's advised to change the configuration
|
||||
to adjust the difficulty for your needs. You can find the config in `map_gen/Diggy/Config.lua`. Most options should be
|
||||
well-explained. For Single-player it's recommend to enable cheats with modified values. You can change the starting
|
||||
items and some pre-defined cheat values (if cheats are enabled) under the `SetupPlayer` config item.
|
||||
|
||||
## Configuring Diggy
|
||||
|
||||
### Changing or Disabling Biter Spawning
|
||||
You can find the biter spawning feature in the config file under `AlienSpawner`. If you don't want biters to spawn
|
||||
according to the Diggy scenario, turn this feature off completely.
|
||||
|
||||
### Disabling Collapses
|
||||
While one of the core features, it can also be fun to play without. To turn off collapses completely, you can turn off
|
||||
this feature under `DiggyCaveCollapse`. If you experience performance issues while digging, you can turn off this
|
||||
feature as well as it can be quite heavy.
|
||||
|
||||
### Configuring Resource Spawning
|
||||
At the moment, Diggy is not yet using any of the build-in mechanics to spawn resources and you will have to manually add
|
||||
them. The resource spawning mechanism is quite complex, so don't hesitate to us how to configure it on Discord. Most
|
||||
basic configuration can be found under `ScatteredResources`. To customize the resource weights, you have to configure
|
||||
those specifics in the `map_gen/Diggy/Orepattern` directory. Resources are defined with a weight, meaning you can add
|
||||
your own resources (for example bobs or angels) with a value and the scenario will automatically calculate the proper
|
||||
spawn chances.
|
||||
|
||||
### Adding Market Items
|
||||
Items can be configured by adding the desired item under the `MarketExchange` configuration. You only have to define a
|
||||
level at which it unlocks, a price or prices in case it can cost more, and what the item prototype is. For a list of
|
||||
items, you can look up each possible item on the [Factorio raw data page](https://wiki.factorio.com/Data.raw#item).
|
||||
## Diggy Installation and Configuration
|
||||
Diggy is a custom [RedMew](../../README.md) scenario. You start out with nothing but a market, your pick-axe and some
|
||||
walls [deep, deep in the mine](https://www.youtube.com/watch?v=ov5pxaIbJlM). The goal is to launch a rocket, but be
|
||||
careful, there's not a lot of space and the mine is unstable!
|
||||
|
||||
- Gameplay: https://www.youtube.com/watch?v=J3lheDK-6Cw
|
||||
- Time lapse video: https://www.youtube.com/watch?v=4cRsx-wl_fk (By Namelesshunter Gaming)
|
||||
|
||||
> _Note_: Scenarios- also known as soft-mods- are scripted maps. They can be played online without having to download
|
||||
any mods as the script is included in the map.
|
||||
|
||||
### Scenario Information
|
||||
The idea of Diggy is similar to vanilla, except that it greatly changes how to build your factory. As you're in a cave,
|
||||
each rock you dig, each support entity you remove and every tile you mine, can cause a collapse. You can use walls,
|
||||
stone paths and (refined) concrete floor to increase the strength of your mine and reduce the chance of a collapse.
|
||||
|
||||
Whenever you place or remove a wall for example, the stress level of the area around it (9x9 tiles) will rise or lower.
|
||||
When a certain threshold is reached, the cave will collapse. You can stop this by quickly placing walls or run away as
|
||||
fast as you can. Letting the cave collapse _will_ destroy structures below it! The recommended pattern on dirt is to
|
||||
place a wall every 4th tile. Using stone paths and concrete will increase this to 5 tiles while refined concrete will
|
||||
make it 6.
|
||||
|
||||
## How to start Diggy for Single-player mode
|
||||
|
||||
#### Step 1
|
||||
Download the zip file from
|
||||
[https://github.com/Valansch/RedMew/archive/develop.zip](https://github.com/Valansch/RedMew/archive/develop.zip)
|
||||
|
||||
#### Step 2
|
||||
- **Windows**: extract the the zip file into `%appdata%\Factorio\Scenarios\Diggy`
|
||||
- **MacOS**: extract the the zip file into `~/Library/Application Support/factorio/Scenarios/Diggy`
|
||||
- **Linux**: extract the the zip file into `~/.factorio/scenarios/Diggy`
|
||||
|
||||
Make sure it's called Diggy and there's a `control.lua` in the root of that directory.
|
||||
|
||||
> _Note_: these locations are based on the default configuration [defined by
|
||||
factorio](https://wiki.factorio.com/Application_directory). If your installation is not default, you have to find your
|
||||
scenarios directory in another way.
|
||||
|
||||
#### Step 3
|
||||
Open `map_layout.lua` in that directory and look for `--require "map_gen.combined.diggy"`.
|
||||
Change this to `require "map_gen.combined.diggy"`, by removing the double dashes.
|
||||
|
||||
#### Step 4
|
||||
In factorio start either a local or online game via Scenarios. Select `Diggy` under
|
||||
`User scenarios` and start it up.
|
||||
|
||||
> _Note:_ Downloading the latest version might not always be a functional version, please consult on discord for a
|
||||
working version if this is the case.
|
||||
|
||||
#### Step 5 (optional)
|
||||
Diggy is designed to work for at least 15 players online, working together. It's advised to change the configuration
|
||||
to adjust the difficulty for your needs. You can find the config in `map_gen/Diggy/Config.lua`. Most options should be
|
||||
well-explained. For Single-player it's recommend to enable cheats with modified values. You can change the starting
|
||||
items and some pre-defined cheat values (if cheats are enabled) under the `SetupPlayer` config item.
|
||||
|
||||
## Configuring Diggy
|
||||
|
||||
### Changing or Disabling Biter Spawning
|
||||
You can find the biter spawning feature in the config file under `AlienSpawner`. If you don't want biters to spawn
|
||||
according to the Diggy scenario, turn this feature off completely.
|
||||
|
||||
### Disabling Collapses
|
||||
While one of the core features, it can also be fun to play without. To turn off collapses completely, you can turn off
|
||||
this feature under `DiggyCaveCollapse`. If you experience performance issues while digging, you can turn off this
|
||||
feature as well as it can be quite heavy.
|
||||
|
||||
### Configuring Resource Spawning
|
||||
At the moment, Diggy is not yet using any of the build-in mechanics to spawn resources and you will have to manually add
|
||||
them. The resource spawning mechanism is quite complex, so don't hesitate to us how to configure it on Discord. Most
|
||||
basic configuration can be found under `ScatteredResources`. To customize the resource weights, you have to configure
|
||||
those specifics in the `map_gen/Diggy/Orepattern` directory. Resources are defined with a weight, meaning you can add
|
||||
your own resources (for example bobs or angels) with a value and the scenario will automatically calculate the proper
|
||||
spawn chances.
|
||||
|
||||
### Adding Market Items
|
||||
Items can be configured by adding the desired item under the `MarketExchange` configuration. You only have to define a
|
||||
level at which it unlocks, a price or prices in case it can cost more, and what the item prototype is. For a list of
|
||||
items, you can look up each possible item on the [Factorio raw data page](https://wiki.factorio.com/Data.raw#item).
|
||||
|
@ -1,360 +1,360 @@
|
||||
local Module = {}
|
||||
|
||||
local Gui = require("utils.gui")
|
||||
local Utils = require("utils.utils");
|
||||
local Game = require 'utils.game'
|
||||
|
||||
local report_frame_name = Gui.uid_name()
|
||||
local report_close_button_name = Gui.uid_name()
|
||||
local report_tab_button_name = Gui.uid_name()
|
||||
local jail_offender_button_name = Gui.uid_name()
|
||||
local report_body_name = Gui.uid_name()
|
||||
local prefix = '------------------NOTICE-------------------'
|
||||
local prefix_e = '--------------------------------------------'
|
||||
|
||||
global.reports = {}
|
||||
global.player_report_data = {}
|
||||
|
||||
|
||||
local function draw_report(parent, report_id)
|
||||
local report = global.reports[report_id]
|
||||
if report_id == 0 or not report then
|
||||
parent.add {type = "label", caption="No reports yet."}
|
||||
return
|
||||
end
|
||||
|
||||
local reported_player_name = Game.get_player_by_index(report.reported_player_index).name
|
||||
local reporting_player_name = "<script>"
|
||||
if report.reporting_player_index then
|
||||
reporting_player_name = Game.get_player_by_index(report.reporting_player_index).name
|
||||
end
|
||||
local time = Utils.format_time(report.tick)
|
||||
local time_ago = Utils.format_time(game.tick - report.tick)
|
||||
|
||||
local message = report.message
|
||||
Gui.clear(parent)
|
||||
|
||||
parent.add {type="label", caption="Offender: " .. reported_player_name}
|
||||
local msg_label_pane = parent.add {type="scroll-pane", vertical_scroll_policy = "auto-and-reserve-space", horizontal_scroll_policy="never"}
|
||||
msg_label_pane.style.maximal_height = 400
|
||||
local msg_label = msg_label_pane.add {type="label", caption="Message: " .. message}
|
||||
local jail_offender_button = parent.add {type = 'button', name = jail_offender_button_name, caption = 'Jail ' .. reported_player_name}
|
||||
jail_offender_button.style.height = 24
|
||||
jail_offender_button.style.font = 'default-small'
|
||||
jail_offender_button.style.top_padding = 0
|
||||
jail_offender_button.style.bottom_padding = 0
|
||||
jail_offender_button.style.left_padding = 0
|
||||
jail_offender_button.style.right_padding = 0
|
||||
msg_label.style.single_line = false
|
||||
msg_label.style.maximal_width = 680
|
||||
parent.add {type="label", caption=string.format("Time: %s (%s ago)", time, time_ago)}
|
||||
parent.add {type="label", caption="Reported by: " .. reporting_player_name}
|
||||
end
|
||||
|
||||
Module.show_reports = function(player)
|
||||
local reports = global.reports or {}
|
||||
|
||||
local center = player.gui.center
|
||||
|
||||
local report_frame = center[report_frame_name]
|
||||
if report_frame and report_frame.valid then
|
||||
Gui.destroy(report_frame)
|
||||
end
|
||||
|
||||
report_frame = center.add {
|
||||
type = 'frame',
|
||||
name = report_frame_name,
|
||||
direction = 'vertical',
|
||||
caption = 'User reports'
|
||||
}
|
||||
report_frame.style.maximal_width = 700
|
||||
player.opened = report_frame
|
||||
|
||||
if #reports > 1 then
|
||||
local scroll_pane = report_frame.add{type = "scroll-pane", horizontal_scroll_policy = "auto-and-reserve-space", vertical_scroll_policy="never"}
|
||||
local tab_flow = scroll_pane.add{type="flow"}
|
||||
for k,report in pairs(reports) do
|
||||
local button_cell = tab_flow.add{type="flow", caption="reportuid" .. k}
|
||||
button_cell.add {
|
||||
type="button",
|
||||
name=report_tab_button_name,
|
||||
caption = Game.get_player_by_index(report.reported_player_index).name
|
||||
}
|
||||
end
|
||||
end
|
||||
local report_body = report_frame.add {type = "scroll-pane", name = report_body_name, horizontal_scroll_policy = "never", vertical_scroll_policy="never"}
|
||||
report_frame.add {type = 'button', name = report_close_button_name, caption = 'Close'}
|
||||
|
||||
draw_report(report_body, #reports)
|
||||
end
|
||||
|
||||
function Module.report(reporting_player, reported_player, message)
|
||||
local player_index
|
||||
if reporting_player then
|
||||
player_index = reporting_player.index
|
||||
end
|
||||
table.insert(global.reports, {reporting_player_index = player_index, reported_player_index = reported_player.index, message = message, tick = game.tick})
|
||||
|
||||
local notified = false
|
||||
for _,p in pairs(game.players) do
|
||||
if p.admin and p.connected then
|
||||
p.play_sound{path='utility/tutorial_notice', volume_modifier = 1}
|
||||
Module.show_reports(p)
|
||||
if p.afk_time < 3600 then notified = true end
|
||||
end
|
||||
end
|
||||
if not notified then
|
||||
for _,p in pairs(game.players) do
|
||||
if p.admin then
|
||||
Module.show_reports(p)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Module.cmd_report(cmd)
|
||||
local reporting_player = game.player
|
||||
if reporting_player then
|
||||
local params = {}
|
||||
for param in string.gmatch(cmd.parameter, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
if #params < 2 then
|
||||
reporting_player.print('Please enter then name of the offender and the reason for the report.')
|
||||
return nil
|
||||
end
|
||||
local reported_player_name = params[1] or ''
|
||||
local reported_player = game.players[reported_player_name]
|
||||
|
||||
if not reported_player then
|
||||
reporting_player.print(reported_player_name .. ' does not exist.')
|
||||
return nil
|
||||
end
|
||||
Module.report(reporting_player, reported_player, string.sub(cmd.parameter, string.len(params[1]) + 2))
|
||||
end
|
||||
end
|
||||
|
||||
-- Places a target in jail as long as player is admin or server
|
||||
function Module.jail(target_player, player)
|
||||
-- Set the name of the jail permission group
|
||||
local jail_name = 'Jail'
|
||||
|
||||
local print
|
||||
local jailed_by
|
||||
if player then
|
||||
jailed_by = "a server admin"
|
||||
print = player.print
|
||||
else
|
||||
jailed_by = "script for causing too many collapses"
|
||||
print = log
|
||||
end
|
||||
|
||||
if not target_player then
|
||||
print('Unknown player.')
|
||||
return
|
||||
end
|
||||
|
||||
local permissions = game.permissions
|
||||
|
||||
-- Check if the permission group exists, if it doesn't, create it.
|
||||
local permission_group = permissions.get_group(jail_name)
|
||||
if not permission_group then
|
||||
permission_group = permissions.create_group(jail_name)
|
||||
end
|
||||
|
||||
if target_player.permission_group == permission_group then
|
||||
print('Player ' .. target_player.name .. ' is already in jail.')
|
||||
return
|
||||
end
|
||||
|
||||
-- Set all permissions to disabled
|
||||
for action_name, _ in pairs(defines.input_action) do
|
||||
permission_group.set_allows_action(defines.input_action[action_name], false)
|
||||
end
|
||||
-- Enable writing to console to allow a person to speak
|
||||
permission_group.set_allows_action(defines.input_action.write_to_console, true)
|
||||
permission_group.set_allows_action(defines.input_action.edit_permission_group, true)
|
||||
|
||||
-- Kick player out of vehicle
|
||||
target_player.driving=false
|
||||
-- Add player to jail group
|
||||
permission_group.add_player(target_player)
|
||||
-- If a player is shooting when they're jailed they can't stop shooting, so we change their shooting state
|
||||
if target_player.shooting_state.state ~= 0 then
|
||||
target_player.shooting_state.state = {state = defines.shooting.not_shooting, position = {0,0}}
|
||||
end
|
||||
|
||||
-- Check that it worked
|
||||
if target_player.permission_group == permission_group then
|
||||
-- Let admin know it worked, let target know what's going on.
|
||||
print(target_player.name .. ' has been jailed. They have been advised of this.')
|
||||
target_player.print(prefix)
|
||||
target_player.print('You have been placed in jail by ' .. jailed_by .. '. The only action avaliable to you is chatting.')
|
||||
target_player.print('Please respond to inquiries from the admins.', {r = 1, g = 1, b = 0, a = 1})
|
||||
Utils.print_admins(target_player.name .. 'has been jailed by' .. player.name)
|
||||
Utils.log_command(player, 'jail', target_player.name)
|
||||
else
|
||||
-- Let admin know it didn't work.
|
||||
print('Something went wrong in the jailing of ' .. target_player.name .. '. You can still change their group via /permissions.')
|
||||
end
|
||||
end
|
||||
|
||||
function Module.unjail_player(cmd)
|
||||
local default_group = 'Default'
|
||||
local player = game.player
|
||||
-- Check if the player can run the command
|
||||
if player and not player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
-- Check if the target is valid (copied from the invoke command)
|
||||
local target = cmd['parameter']
|
||||
if target == nil then
|
||||
Game.player_print('Usage: /unjail <player>')
|
||||
return
|
||||
end
|
||||
|
||||
local target_player = game.players[target]
|
||||
if not target_player then
|
||||
Game.player_print('Unknown player.')
|
||||
return
|
||||
end
|
||||
|
||||
local permissions = game.permissions
|
||||
|
||||
-- Check if the permission group exists, if it doesn't, create it.
|
||||
local permission_group = permissions.get_group(default_group)
|
||||
if not permission_group then
|
||||
permission_group = permissions.create_group(default_group)
|
||||
end
|
||||
|
||||
local jail_permission_group = permissions.get_group('Jail')
|
||||
if (not jail_permission_group) or target_player.permission_group ~= jail_permission_group then
|
||||
Game.player_print('The player ' .. target .. ' is already not in Jail.')
|
||||
return
|
||||
end
|
||||
|
||||
-- Move player
|
||||
permission_group.add_player(target)
|
||||
-- Set player to a non-shooting state (solves a niche case where players jailed while shooting will be locked into a shooting state)
|
||||
target_player.shooting_state.state = 0
|
||||
|
||||
-- Check that it worked
|
||||
if target_player.permission_group == permission_group then
|
||||
-- Let admin know it worked, let target know what's going on.
|
||||
Game.player_print(target .. ' has been returned to the default group. They have been advised of this.')
|
||||
target_player.print(prefix)
|
||||
target_player.print('Your ability to perform actions has been restored', {r = 0, g = 1, b = 0, a = 1})
|
||||
target_player.print(prefix_e)
|
||||
else
|
||||
-- Let admin know it didn't work.
|
||||
Game.player_print(
|
||||
'Something went wrong in the unjailing of ' ..
|
||||
target .. '. You can still change their group via /permissions and inform them.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
Gui.on_custom_close(
|
||||
report_frame_name,
|
||||
function(event)
|
||||
Gui.destroy(event.element)
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
report_close_button_name,
|
||||
function(event)
|
||||
Gui.destroy(event.element.parent)
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
jail_offender_button_name,
|
||||
function(event)
|
||||
local target_name = string.sub(event.element.caption, 6)
|
||||
local target = game.players[target_name]
|
||||
Module.jail(target, event.player)
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
report_tab_button_name,
|
||||
function(event)
|
||||
local center = event.player.gui.center
|
||||
local report_frame = center[report_frame_name]
|
||||
local report_uid_str = string.sub(event.element.parent.caption, 10)
|
||||
local report_uid = tonumber(report_uid_str)
|
||||
draw_report(report_frame[report_body_name], report_uid)
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
local reporting_popup_name = Gui.uid_name()
|
||||
local reporting_cancel_button_name = Gui.uid_name()
|
||||
local reporting_submit_button_name = Gui.uid_name()
|
||||
local reporting_input_name = Gui.uid_name()
|
||||
|
||||
Module.spawn_reporting_popup = function(player, reported_player)
|
||||
|
||||
local center = player.gui.center
|
||||
|
||||
local reporting_popup = center[reporting_popup_name]
|
||||
if reporting_popup and reporting_popup.valid then
|
||||
Gui.destroy(reporting_popup)
|
||||
end
|
||||
reporting_popup = center.add {
|
||||
type = 'frame',
|
||||
name = reporting_popup_name,
|
||||
direction = 'vertical',
|
||||
caption = 'Report player ' .. reported_player.name
|
||||
}
|
||||
Gui.set_data(reporting_popup, {reported_player_index = reported_player.index})
|
||||
|
||||
reporting_popup.style.maximal_width = 500
|
||||
player.opened = reporting_popup
|
||||
reporting_popup.add {
|
||||
type = 'label',
|
||||
caption = 'Report message:'
|
||||
}
|
||||
local input = reporting_popup.add {type = 'text-box', name=reporting_input_name}
|
||||
input.style.width = 400
|
||||
input.style.height = 85
|
||||
local button_flow = reporting_popup.add {type = "flow"}
|
||||
button_flow.add {type = "button", name = reporting_submit_button_name, caption="Submit"}
|
||||
button_flow.add {type = "button", name = reporting_cancel_button_name, caption="Cancel"}
|
||||
end
|
||||
|
||||
Gui.on_custom_close(
|
||||
reporting_popup_name,
|
||||
function(event)
|
||||
Gui.destroy(event.element)
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
reporting_cancel_button_name,
|
||||
function(event)
|
||||
local frame = event.element.parent.parent
|
||||
Gui.destroy(frame)
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
reporting_submit_button_name,
|
||||
function(event)
|
||||
local frame = event.element.parent.parent
|
||||
local msg = frame[reporting_input_name].text
|
||||
local data = Gui.get_data(frame)
|
||||
local reported_player_index = data["reported_player_index"]
|
||||
local print = event.player.print
|
||||
|
||||
Gui.destroy(frame)
|
||||
Module.report(event.player, Game.get_player_by_index(reported_player_index), msg)
|
||||
print(prefix)
|
||||
print("You have successfully reported the player: " .. Game.get_player_by_index(reported_player_index).name)
|
||||
print(prefix_e)
|
||||
end
|
||||
)
|
||||
|
||||
return Module
|
||||
local Module = {}
|
||||
|
||||
local Gui = require("utils.gui")
|
||||
local Utils = require("utils.utils");
|
||||
local Game = require 'utils.game'
|
||||
|
||||
local report_frame_name = Gui.uid_name()
|
||||
local report_close_button_name = Gui.uid_name()
|
||||
local report_tab_button_name = Gui.uid_name()
|
||||
local jail_offender_button_name = Gui.uid_name()
|
||||
local report_body_name = Gui.uid_name()
|
||||
local prefix = '------------------NOTICE-------------------'
|
||||
local prefix_e = '--------------------------------------------'
|
||||
|
||||
global.reports = {}
|
||||
global.player_report_data = {}
|
||||
|
||||
|
||||
local function draw_report(parent, report_id)
|
||||
local report = global.reports[report_id]
|
||||
if report_id == 0 or not report then
|
||||
parent.add {type = "label", caption="No reports yet."}
|
||||
return
|
||||
end
|
||||
|
||||
local reported_player_name = Game.get_player_by_index(report.reported_player_index).name
|
||||
local reporting_player_name = "<script>"
|
||||
if report.reporting_player_index then
|
||||
reporting_player_name = Game.get_player_by_index(report.reporting_player_index).name
|
||||
end
|
||||
local time = Utils.format_time(report.tick)
|
||||
local time_ago = Utils.format_time(game.tick - report.tick)
|
||||
|
||||
local message = report.message
|
||||
Gui.clear(parent)
|
||||
|
||||
parent.add {type="label", caption="Offender: " .. reported_player_name}
|
||||
local msg_label_pane = parent.add {type="scroll-pane", vertical_scroll_policy = "auto-and-reserve-space", horizontal_scroll_policy="never"}
|
||||
msg_label_pane.style.maximal_height = 400
|
||||
local msg_label = msg_label_pane.add {type="label", caption="Message: " .. message}
|
||||
local jail_offender_button = parent.add {type = 'button', name = jail_offender_button_name, caption = 'Jail ' .. reported_player_name}
|
||||
jail_offender_button.style.height = 24
|
||||
jail_offender_button.style.font = 'default-small'
|
||||
jail_offender_button.style.top_padding = 0
|
||||
jail_offender_button.style.bottom_padding = 0
|
||||
jail_offender_button.style.left_padding = 0
|
||||
jail_offender_button.style.right_padding = 0
|
||||
msg_label.style.single_line = false
|
||||
msg_label.style.maximal_width = 680
|
||||
parent.add {type="label", caption=string.format("Time: %s (%s ago)", time, time_ago)}
|
||||
parent.add {type="label", caption="Reported by: " .. reporting_player_name}
|
||||
end
|
||||
|
||||
Module.show_reports = function(player)
|
||||
local reports = global.reports or {}
|
||||
|
||||
local center = player.gui.center
|
||||
|
||||
local report_frame = center[report_frame_name]
|
||||
if report_frame and report_frame.valid then
|
||||
Gui.destroy(report_frame)
|
||||
end
|
||||
|
||||
report_frame = center.add {
|
||||
type = 'frame',
|
||||
name = report_frame_name,
|
||||
direction = 'vertical',
|
||||
caption = 'User reports'
|
||||
}
|
||||
report_frame.style.maximal_width = 700
|
||||
player.opened = report_frame
|
||||
|
||||
if #reports > 1 then
|
||||
local scroll_pane = report_frame.add{type = "scroll-pane", horizontal_scroll_policy = "auto-and-reserve-space", vertical_scroll_policy="never"}
|
||||
local tab_flow = scroll_pane.add{type="flow"}
|
||||
for k,report in pairs(reports) do
|
||||
local button_cell = tab_flow.add{type="flow", caption="reportuid" .. k}
|
||||
button_cell.add {
|
||||
type="button",
|
||||
name=report_tab_button_name,
|
||||
caption = Game.get_player_by_index(report.reported_player_index).name
|
||||
}
|
||||
end
|
||||
end
|
||||
local report_body = report_frame.add {type = "scroll-pane", name = report_body_name, horizontal_scroll_policy = "never", vertical_scroll_policy="never"}
|
||||
report_frame.add {type = 'button', name = report_close_button_name, caption = 'Close'}
|
||||
|
||||
draw_report(report_body, #reports)
|
||||
end
|
||||
|
||||
function Module.report(reporting_player, reported_player, message)
|
||||
local player_index
|
||||
if reporting_player then
|
||||
player_index = reporting_player.index
|
||||
end
|
||||
table.insert(global.reports, {reporting_player_index = player_index, reported_player_index = reported_player.index, message = message, tick = game.tick})
|
||||
|
||||
local notified = false
|
||||
for _,p in pairs(game.players) do
|
||||
if p.admin and p.connected then
|
||||
p.play_sound{path='utility/tutorial_notice', volume_modifier = 1}
|
||||
Module.show_reports(p)
|
||||
if p.afk_time < 3600 then notified = true end
|
||||
end
|
||||
end
|
||||
if not notified then
|
||||
for _,p in pairs(game.players) do
|
||||
if p.admin then
|
||||
Module.show_reports(p)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Module.cmd_report(cmd)
|
||||
local reporting_player = game.player
|
||||
if reporting_player then
|
||||
local params = {}
|
||||
for param in string.gmatch(cmd.parameter, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
if #params < 2 then
|
||||
reporting_player.print('Please enter then name of the offender and the reason for the report.')
|
||||
return nil
|
||||
end
|
||||
local reported_player_name = params[1] or ''
|
||||
local reported_player = game.players[reported_player_name]
|
||||
|
||||
if not reported_player then
|
||||
reporting_player.print(reported_player_name .. ' does not exist.')
|
||||
return nil
|
||||
end
|
||||
Module.report(reporting_player, reported_player, string.sub(cmd.parameter, string.len(params[1]) + 2))
|
||||
end
|
||||
end
|
||||
|
||||
-- Places a target in jail as long as player is admin or server
|
||||
function Module.jail(target_player, player)
|
||||
-- Set the name of the jail permission group
|
||||
local jail_name = 'Jail'
|
||||
|
||||
local print
|
||||
local jailed_by
|
||||
if player then
|
||||
jailed_by = "a server admin"
|
||||
print = player.print
|
||||
else
|
||||
jailed_by = "script for causing too many collapses"
|
||||
print = log
|
||||
end
|
||||
|
||||
if not target_player then
|
||||
print('Unknown player.')
|
||||
return
|
||||
end
|
||||
|
||||
local permissions = game.permissions
|
||||
|
||||
-- Check if the permission group exists, if it doesn't, create it.
|
||||
local permission_group = permissions.get_group(jail_name)
|
||||
if not permission_group then
|
||||
permission_group = permissions.create_group(jail_name)
|
||||
end
|
||||
|
||||
if target_player.permission_group == permission_group then
|
||||
print('Player ' .. target_player.name .. ' is already in jail.')
|
||||
return
|
||||
end
|
||||
|
||||
-- Set all permissions to disabled
|
||||
for action_name, _ in pairs(defines.input_action) do
|
||||
permission_group.set_allows_action(defines.input_action[action_name], false)
|
||||
end
|
||||
-- Enable writing to console to allow a person to speak
|
||||
permission_group.set_allows_action(defines.input_action.write_to_console, true)
|
||||
permission_group.set_allows_action(defines.input_action.edit_permission_group, true)
|
||||
|
||||
-- Kick player out of vehicle
|
||||
target_player.driving=false
|
||||
-- Add player to jail group
|
||||
permission_group.add_player(target_player)
|
||||
-- If a player is shooting when they're jailed they can't stop shooting, so we change their shooting state
|
||||
if target_player.shooting_state.state ~= 0 then
|
||||
target_player.shooting_state.state = {state = defines.shooting.not_shooting, position = {0,0}}
|
||||
end
|
||||
|
||||
-- Check that it worked
|
||||
if target_player.permission_group == permission_group then
|
||||
-- Let admin know it worked, let target know what's going on.
|
||||
print(target_player.name .. ' has been jailed. They have been advised of this.')
|
||||
target_player.print(prefix)
|
||||
target_player.print('You have been placed in jail by ' .. jailed_by .. '. The only action avaliable to you is chatting.')
|
||||
target_player.print('Please respond to inquiries from the admins.', {r = 1, g = 1, b = 0, a = 1})
|
||||
Utils.print_admins(target_player.name .. 'has been jailed by' .. player.name)
|
||||
Utils.log_command(player, 'jail', target_player.name)
|
||||
else
|
||||
-- Let admin know it didn't work.
|
||||
print('Something went wrong in the jailing of ' .. target_player.name .. '. You can still change their group via /permissions.')
|
||||
end
|
||||
end
|
||||
|
||||
function Module.unjail_player(cmd)
|
||||
local default_group = 'Default'
|
||||
local player = game.player
|
||||
-- Check if the player can run the command
|
||||
if player and not player.admin then
|
||||
Utils.cant_run(cmd.name)
|
||||
return
|
||||
end
|
||||
-- Check if the target is valid (copied from the invoke command)
|
||||
local target = cmd['parameter']
|
||||
if target == nil then
|
||||
Game.player_print('Usage: /unjail <player>')
|
||||
return
|
||||
end
|
||||
|
||||
local target_player = game.players[target]
|
||||
if not target_player then
|
||||
Game.player_print('Unknown player.')
|
||||
return
|
||||
end
|
||||
|
||||
local permissions = game.permissions
|
||||
|
||||
-- Check if the permission group exists, if it doesn't, create it.
|
||||
local permission_group = permissions.get_group(default_group)
|
||||
if not permission_group then
|
||||
permission_group = permissions.create_group(default_group)
|
||||
end
|
||||
|
||||
local jail_permission_group = permissions.get_group('Jail')
|
||||
if (not jail_permission_group) or target_player.permission_group ~= jail_permission_group then
|
||||
Game.player_print('The player ' .. target .. ' is already not in Jail.')
|
||||
return
|
||||
end
|
||||
|
||||
-- Move player
|
||||
permission_group.add_player(target)
|
||||
-- Set player to a non-shooting state (solves a niche case where players jailed while shooting will be locked into a shooting state)
|
||||
target_player.shooting_state.state = 0
|
||||
|
||||
-- Check that it worked
|
||||
if target_player.permission_group == permission_group then
|
||||
-- Let admin know it worked, let target know what's going on.
|
||||
Game.player_print(target .. ' has been returned to the default group. They have been advised of this.')
|
||||
target_player.print(prefix)
|
||||
target_player.print('Your ability to perform actions has been restored', {r = 0, g = 1, b = 0, a = 1})
|
||||
target_player.print(prefix_e)
|
||||
else
|
||||
-- Let admin know it didn't work.
|
||||
Game.player_print(
|
||||
'Something went wrong in the unjailing of ' ..
|
||||
target .. '. You can still change their group via /permissions and inform them.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
Gui.on_custom_close(
|
||||
report_frame_name,
|
||||
function(event)
|
||||
Gui.destroy(event.element)
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
report_close_button_name,
|
||||
function(event)
|
||||
Gui.destroy(event.element.parent)
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
jail_offender_button_name,
|
||||
function(event)
|
||||
local target_name = string.sub(event.element.caption, 6)
|
||||
local target = game.players[target_name]
|
||||
Module.jail(target, event.player)
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
report_tab_button_name,
|
||||
function(event)
|
||||
local center = event.player.gui.center
|
||||
local report_frame = center[report_frame_name]
|
||||
local report_uid_str = string.sub(event.element.parent.caption, 10)
|
||||
local report_uid = tonumber(report_uid_str)
|
||||
draw_report(report_frame[report_body_name], report_uid)
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
local reporting_popup_name = Gui.uid_name()
|
||||
local reporting_cancel_button_name = Gui.uid_name()
|
||||
local reporting_submit_button_name = Gui.uid_name()
|
||||
local reporting_input_name = Gui.uid_name()
|
||||
|
||||
Module.spawn_reporting_popup = function(player, reported_player)
|
||||
|
||||
local center = player.gui.center
|
||||
|
||||
local reporting_popup = center[reporting_popup_name]
|
||||
if reporting_popup and reporting_popup.valid then
|
||||
Gui.destroy(reporting_popup)
|
||||
end
|
||||
reporting_popup = center.add {
|
||||
type = 'frame',
|
||||
name = reporting_popup_name,
|
||||
direction = 'vertical',
|
||||
caption = 'Report player ' .. reported_player.name
|
||||
}
|
||||
Gui.set_data(reporting_popup, {reported_player_index = reported_player.index})
|
||||
|
||||
reporting_popup.style.maximal_width = 500
|
||||
player.opened = reporting_popup
|
||||
reporting_popup.add {
|
||||
type = 'label',
|
||||
caption = 'Report message:'
|
||||
}
|
||||
local input = reporting_popup.add {type = 'text-box', name=reporting_input_name}
|
||||
input.style.width = 400
|
||||
input.style.height = 85
|
||||
local button_flow = reporting_popup.add {type = "flow"}
|
||||
button_flow.add {type = "button", name = reporting_submit_button_name, caption="Submit"}
|
||||
button_flow.add {type = "button", name = reporting_cancel_button_name, caption="Cancel"}
|
||||
end
|
||||
|
||||
Gui.on_custom_close(
|
||||
reporting_popup_name,
|
||||
function(event)
|
||||
Gui.destroy(event.element)
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
reporting_cancel_button_name,
|
||||
function(event)
|
||||
local frame = event.element.parent.parent
|
||||
Gui.destroy(frame)
|
||||
end
|
||||
)
|
||||
|
||||
Gui.on_click(
|
||||
reporting_submit_button_name,
|
||||
function(event)
|
||||
local frame = event.element.parent.parent
|
||||
local msg = frame[reporting_input_name].text
|
||||
local data = Gui.get_data(frame)
|
||||
local reported_player_index = data["reported_player_index"]
|
||||
local print = event.player.print
|
||||
|
||||
Gui.destroy(frame)
|
||||
Module.report(event.player, Game.get_player_by_index(reported_player_index), msg)
|
||||
print(prefix)
|
||||
print("You have successfully reported the player: " .. Game.get_player_by_index(reported_player_index).name)
|
||||
print(prefix_e)
|
||||
end
|
||||
)
|
||||
|
||||
return Module
|
||||
|
@ -1,159 +1,159 @@
|
||||
--[[-- info
|
||||
Original (javascript) version: https://hastebin.com/udakacavap.js
|
||||
Can be tested against: https://wiki.factorio.com/Enemies#Spawn_chances_by_evolution_factor
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Global = require 'utils.global'
|
||||
local random = math.random
|
||||
local round = math.round
|
||||
|
||||
-- this
|
||||
local AlienEvolutionProgress = {}
|
||||
|
||||
local alien_cache = {
|
||||
biters = {
|
||||
evolution = -1,
|
||||
cache = {},
|
||||
},
|
||||
spitters = {
|
||||
evolution = -1,
|
||||
cache = {},
|
||||
},
|
||||
}
|
||||
|
||||
Global.register({
|
||||
alien_cache = alien_cache,
|
||||
}, function(tbl)
|
||||
alien_cache = tbl.alien_cache
|
||||
end)
|
||||
|
||||
-- values are in the form {evolution, weight}
|
||||
local biters = {
|
||||
{'small-biter', {{0.0, 0.3}, {0.6, 0.0}}},
|
||||
{'medium-biter', {{0.2, 0.0}, {0.6, 0.3}, {0.7, 0.1}}},
|
||||
{'big-biter', {{0.5, 0.0}, {1.0, 0.4}}},
|
||||
{'behemoth-biter', {{0.9, 0.0}, {1.0, 0.3}}},
|
||||
}
|
||||
|
||||
local spitters = {
|
||||
{'small-biter', {{0.0, 0.3}, {0.35, 0.0}}},
|
||||
{'small-spitter', {{0.25, 0.0}, {0.5, 0.3}, {0.7, 0.0}}},
|
||||
{'medium-spitter', {{0.4, 0.0}, {0.7, 0.3}, {0.9, 0.1}}},
|
||||
{'big-spitter', {{0.5, 0.0}, {1.0, 0.4}}},
|
||||
{'behemoth-spitter', {{0.9, 0.0}, {1.0, 0.3}}},
|
||||
}
|
||||
|
||||
local function lerp(low, high, pos)
|
||||
local s = high[1] - low[1];
|
||||
local l = (pos - low[1]) / s;
|
||||
return (low[2] * (1 - l)) + (high[2] * l)
|
||||
end
|
||||
|
||||
local function get_values(map, evo)
|
||||
local result = {}
|
||||
local sum = 0
|
||||
|
||||
for _, data in pairs(map) do
|
||||
local list = data[2];
|
||||
local low = list[1];
|
||||
local high = list[#list];
|
||||
|
||||
for _, val in pairs(list) do
|
||||
if(val[1] <= evo and val[1] > low[1]) then
|
||||
low = val;
|
||||
end
|
||||
if(val[1] >= evo and val[1] < high[1]) then
|
||||
high = val
|
||||
end
|
||||
end
|
||||
|
||||
local val
|
||||
if (evo <= low[1]) then
|
||||
val = low[2]
|
||||
elseif (evo >= high[1]) then
|
||||
val = high[2];
|
||||
else
|
||||
val = lerp(low, high, evo)
|
||||
end
|
||||
sum = sum + val;
|
||||
|
||||
result[data[1]] = val;
|
||||
end
|
||||
|
||||
for index, _ in pairs(result) do
|
||||
result[index] = result[index] / sum
|
||||
end
|
||||
|
||||
return result;
|
||||
end
|
||||
|
||||
local function get_name_by_random(collection)
|
||||
local pre_calculated = random()
|
||||
local current = 0
|
||||
|
||||
for name, probability in pairs(collection) do
|
||||
current = current + probability
|
||||
if (current >= pre_calculated) then
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
Debug.print('AlienEvolutionProgress.get_name_by_random: Current \'' .. current .. '\' should be higher or equal to random \'' .. pre_calculated .. '\'')
|
||||
end
|
||||
|
||||
function AlienEvolutionProgress.getBiterValues(evolution)
|
||||
local evolution_value = round(evolution * 100)
|
||||
|
||||
if (alien_cache.biters.evolution < evolution_value) then
|
||||
alien_cache.biters.evolution = evolution_value
|
||||
alien_cache.biters.cache = get_values(biters, evolution)
|
||||
end
|
||||
|
||||
return alien_cache.biters.cache
|
||||
end
|
||||
|
||||
function AlienEvolutionProgress.getSpitterValues(evolution)
|
||||
local evolution_value = round(evolution * 100)
|
||||
|
||||
if (alien_cache.spitters.evolution < evolution_value) then
|
||||
alien_cache.spitters.evolution = evolution_value
|
||||
alien_cache.spitters.cache = get_values(spitters, evolution)
|
||||
end
|
||||
|
||||
return alien_cache.spitters.cache
|
||||
end
|
||||
|
||||
function AlienEvolutionProgress.getBitersByEvolution(total_biters, evolution)
|
||||
local biters_calculated = {}
|
||||
local map = AlienEvolutionProgress.getBiterValues(evolution)
|
||||
|
||||
for i = 1, total_biters do
|
||||
local name = get_name_by_random(map)
|
||||
if (nil == biters_calculated[name]) then
|
||||
biters_calculated[name] = 1
|
||||
else
|
||||
biters_calculated[name] = biters_calculated[name] + 1
|
||||
end
|
||||
end
|
||||
|
||||
return biters_calculated
|
||||
end
|
||||
|
||||
function AlienEvolutionProgress.getSpittersByEvolution(total_spitters, evolution)
|
||||
local spitters_calculated = {}
|
||||
local map = AlienEvolutionProgress.getSpitterValues(evolution)
|
||||
|
||||
for i = 1, total_spitters do
|
||||
local name = get_name_by_random(map)
|
||||
if (nil == spitters_calculated[name]) then
|
||||
spitters_calculated[name] = 1
|
||||
else
|
||||
spitters_calculated[name] = spitters_calculated[name] + 1
|
||||
end
|
||||
end
|
||||
|
||||
return spitters_calculated
|
||||
end
|
||||
|
||||
return AlienEvolutionProgress
|
||||
--[[-- info
|
||||
Original (javascript) version: https://hastebin.com/udakacavap.js
|
||||
Can be tested against: https://wiki.factorio.com/Enemies#Spawn_chances_by_evolution_factor
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Global = require 'utils.global'
|
||||
local random = math.random
|
||||
local round = math.round
|
||||
|
||||
-- this
|
||||
local AlienEvolutionProgress = {}
|
||||
|
||||
local alien_cache = {
|
||||
biters = {
|
||||
evolution = -1,
|
||||
cache = {},
|
||||
},
|
||||
spitters = {
|
||||
evolution = -1,
|
||||
cache = {},
|
||||
},
|
||||
}
|
||||
|
||||
Global.register({
|
||||
alien_cache = alien_cache,
|
||||
}, function(tbl)
|
||||
alien_cache = tbl.alien_cache
|
||||
end)
|
||||
|
||||
-- values are in the form {evolution, weight}
|
||||
local biters = {
|
||||
{'small-biter', {{0.0, 0.3}, {0.6, 0.0}}},
|
||||
{'medium-biter', {{0.2, 0.0}, {0.6, 0.3}, {0.7, 0.1}}},
|
||||
{'big-biter', {{0.5, 0.0}, {1.0, 0.4}}},
|
||||
{'behemoth-biter', {{0.9, 0.0}, {1.0, 0.3}}},
|
||||
}
|
||||
|
||||
local spitters = {
|
||||
{'small-biter', {{0.0, 0.3}, {0.35, 0.0}}},
|
||||
{'small-spitter', {{0.25, 0.0}, {0.5, 0.3}, {0.7, 0.0}}},
|
||||
{'medium-spitter', {{0.4, 0.0}, {0.7, 0.3}, {0.9, 0.1}}},
|
||||
{'big-spitter', {{0.5, 0.0}, {1.0, 0.4}}},
|
||||
{'behemoth-spitter', {{0.9, 0.0}, {1.0, 0.3}}},
|
||||
}
|
||||
|
||||
local function lerp(low, high, pos)
|
||||
local s = high[1] - low[1];
|
||||
local l = (pos - low[1]) / s;
|
||||
return (low[2] * (1 - l)) + (high[2] * l)
|
||||
end
|
||||
|
||||
local function get_values(map, evo)
|
||||
local result = {}
|
||||
local sum = 0
|
||||
|
||||
for _, data in pairs(map) do
|
||||
local list = data[2];
|
||||
local low = list[1];
|
||||
local high = list[#list];
|
||||
|
||||
for _, val in pairs(list) do
|
||||
if(val[1] <= evo and val[1] > low[1]) then
|
||||
low = val;
|
||||
end
|
||||
if(val[1] >= evo and val[1] < high[1]) then
|
||||
high = val
|
||||
end
|
||||
end
|
||||
|
||||
local val
|
||||
if (evo <= low[1]) then
|
||||
val = low[2]
|
||||
elseif (evo >= high[1]) then
|
||||
val = high[2];
|
||||
else
|
||||
val = lerp(low, high, evo)
|
||||
end
|
||||
sum = sum + val;
|
||||
|
||||
result[data[1]] = val;
|
||||
end
|
||||
|
||||
for index, _ in pairs(result) do
|
||||
result[index] = result[index] / sum
|
||||
end
|
||||
|
||||
return result;
|
||||
end
|
||||
|
||||
local function get_name_by_random(collection)
|
||||
local pre_calculated = random()
|
||||
local current = 0
|
||||
|
||||
for name, probability in pairs(collection) do
|
||||
current = current + probability
|
||||
if (current >= pre_calculated) then
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
Debug.print('AlienEvolutionProgress.get_name_by_random: Current \'' .. current .. '\' should be higher or equal to random \'' .. pre_calculated .. '\'')
|
||||
end
|
||||
|
||||
function AlienEvolutionProgress.getBiterValues(evolution)
|
||||
local evolution_value = round(evolution * 100)
|
||||
|
||||
if (alien_cache.biters.evolution < evolution_value) then
|
||||
alien_cache.biters.evolution = evolution_value
|
||||
alien_cache.biters.cache = get_values(biters, evolution)
|
||||
end
|
||||
|
||||
return alien_cache.biters.cache
|
||||
end
|
||||
|
||||
function AlienEvolutionProgress.getSpitterValues(evolution)
|
||||
local evolution_value = round(evolution * 100)
|
||||
|
||||
if (alien_cache.spitters.evolution < evolution_value) then
|
||||
alien_cache.spitters.evolution = evolution_value
|
||||
alien_cache.spitters.cache = get_values(spitters, evolution)
|
||||
end
|
||||
|
||||
return alien_cache.spitters.cache
|
||||
end
|
||||
|
||||
function AlienEvolutionProgress.getBitersByEvolution(total_biters, evolution)
|
||||
local biters_calculated = {}
|
||||
local map = AlienEvolutionProgress.getBiterValues(evolution)
|
||||
|
||||
for i = 1, total_biters do
|
||||
local name = get_name_by_random(map)
|
||||
if (nil == biters_calculated[name]) then
|
||||
biters_calculated[name] = 1
|
||||
else
|
||||
biters_calculated[name] = biters_calculated[name] + 1
|
||||
end
|
||||
end
|
||||
|
||||
return biters_calculated
|
||||
end
|
||||
|
||||
function AlienEvolutionProgress.getSpittersByEvolution(total_spitters, evolution)
|
||||
local spitters_calculated = {}
|
||||
local map = AlienEvolutionProgress.getSpitterValues(evolution)
|
||||
|
||||
for i = 1, total_spitters do
|
||||
local name = get_name_by_random(map)
|
||||
if (nil == spitters_calculated[name]) then
|
||||
spitters_calculated[name] = 1
|
||||
else
|
||||
spitters_calculated[name] = spitters_calculated[name] + 1
|
||||
end
|
||||
end
|
||||
|
||||
return spitters_calculated
|
||||
end
|
||||
|
||||
return AlienEvolutionProgress
|
||||
|
@ -1,224 +1,224 @@
|
||||
-- dependencies
|
||||
local min = math.min
|
||||
local max = math.max
|
||||
local floor = math.floor
|
||||
local abs = math.abs
|
||||
|
||||
-- this
|
||||
local Debug = {}
|
||||
|
||||
-- private state
|
||||
local debug = false
|
||||
local cheats = false
|
||||
|
||||
function Debug.enable_debug()
|
||||
debug = true
|
||||
end
|
||||
|
||||
function Debug.disable_debug()
|
||||
debug = false
|
||||
end
|
||||
|
||||
function Debug.enable_cheats()
|
||||
cheats = true
|
||||
end
|
||||
|
||||
function Debug.disable_cheats()
|
||||
cheats = true
|
||||
end
|
||||
|
||||
global.message_count = 0
|
||||
|
||||
--[[--
|
||||
Shows the given message if debug is enabled.
|
||||
|
||||
@param message string
|
||||
]]
|
||||
function Debug.print(message)
|
||||
if type(message) ~= 'string' and type(message) ~= 'number' and type(message) ~= 'boolean' then message = type(message) end
|
||||
global.message_count = global.message_count + 1
|
||||
if (debug) then
|
||||
game.print('[' .. global.message_count .. '] ' .. tostring(message))
|
||||
log('[' .. global.message_count .. '] ' .. tostring(message))
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Shows the given message with serpent enabled, if debug is enabled.
|
||||
|
||||
@param message string
|
||||
]]
|
||||
function Debug.print_serpent(message)
|
||||
Debug.print(serpent.line(message))
|
||||
end
|
||||
|
||||
--[[--
|
||||
Shows the given message if _DEBUG == true for a given position.
|
||||
|
||||
@param x number
|
||||
@param y number
|
||||
@param message string
|
||||
]]
|
||||
function Debug.print_position(position, message)
|
||||
message = message or ''
|
||||
if type(message) ~= 'string' and type(message) ~= 'number' and type(message) ~= 'boolean' then message = type(message) end
|
||||
global.message_count = global.message_count + 1
|
||||
if (debug) then
|
||||
game.print('[' .. global.message_count .. '] {x=' .. position.x .. ', y=' .. position.y .. '} ' .. tostring(message))
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Executes the given callback if cheating is enabled.
|
||||
|
||||
@param callback function
|
||||
]]
|
||||
function Debug.cheat(callback)
|
||||
if (cheats) then
|
||||
callback()
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Prints a colored value on a location.
|
||||
|
||||
@param value between -1 and 1
|
||||
@param surface LuaSurface
|
||||
@param position Position {x, y}
|
||||
@param scale float
|
||||
@param offset float
|
||||
@param immutable bool if immutable, only set, never do a surface lookup, values never change
|
||||
]]
|
||||
function Debug.print_grid_value(value, surface, position, scale, offset, immutable)
|
||||
local is_string = type(value) == 'string'
|
||||
local color = {r = 1, g = 1, b = 1}
|
||||
text = value
|
||||
|
||||
if type(immutable) ~= 'boolean' then
|
||||
immutable = false
|
||||
end
|
||||
|
||||
if not is_string then
|
||||
scale = scale or 1
|
||||
offset = offset or 0
|
||||
position = {x = position.x + offset, y = position.y + offset}
|
||||
local r = max(1, value) / scale
|
||||
local g = 1 - abs(value) / scale
|
||||
local b = min(1, value) / scale
|
||||
|
||||
if (r > 0) then
|
||||
r = 0
|
||||
end
|
||||
|
||||
if (b < 0) then
|
||||
b = 0
|
||||
end
|
||||
|
||||
if (g < 0) then
|
||||
g = 0
|
||||
end
|
||||
|
||||
r = abs(r)
|
||||
|
||||
color = { r = r, g = g, b = b}
|
||||
|
||||
-- round at precision of 2
|
||||
text = floor(100 * value) * 0.01
|
||||
|
||||
if (0 == text) then
|
||||
text = '0.00'
|
||||
end
|
||||
end
|
||||
|
||||
if not immutable then
|
||||
local text_entity = surface.find_entity('flying-text', position)
|
||||
|
||||
if text_entity then
|
||||
text_entity.text = text
|
||||
text_entity.color = color
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
surface.create_entity{
|
||||
name = 'flying-text',
|
||||
color = color,
|
||||
text = text,
|
||||
position = position
|
||||
}.active = false
|
||||
end
|
||||
|
||||
--[[--
|
||||
Prints a colored value on a location. When given a color_value and a delta_color,
|
||||
will change the color of the text from the base to base + value * delta. This will
|
||||
make the color of the text range from 'base_color' to 'base_color + delta_color'
|
||||
as the color_value ranges from 0 to 1
|
||||
|
||||
@param value of number to be displayed
|
||||
@param surface LuaSurface
|
||||
@param position Position {x, y}
|
||||
@param scale float
|
||||
@param offset float position offset
|
||||
@param immutable bool if immutable, only set, never do a surface lookup, values never change
|
||||
@param color_value float How far along the range of values of colors the value is to be displayed
|
||||
@param base_color {r,g,b} The color for the text to be if color_value is 0
|
||||
@param delta_color {r,g,b} The amount to correct the base_color if color_value is 1
|
||||
@param under_bound {r,g,b} The color to be used if color_value < 0
|
||||
@param over_bound {r,g,b} The color to be used if color_value > 1
|
||||
]]
|
||||
function Debug.print_colored_grid_value(value, surface, position, scale, offset, immutable,
|
||||
color_value, base_color, delta_color, under_bound, over_bound)
|
||||
local is_string = type(value) == 'string'
|
||||
-- default values:
|
||||
local color = base_color or {r = 1, g = 1, b = 1}
|
||||
local d_color = delta_color or {r = 0, g = 0, b = 0}
|
||||
local u_color = under_bound or color
|
||||
local o_color = over_bound or color
|
||||
|
||||
if (color_value < 0) then
|
||||
color = u_color
|
||||
elseif (color_value > 1) then
|
||||
color = o_color
|
||||
else
|
||||
color = { r = color.r + color_value * d_color.r,
|
||||
g = color.g + color_value * d_color.g,
|
||||
b = color.b + color_value * d_color.b }
|
||||
end
|
||||
|
||||
text = value
|
||||
|
||||
if type(immutable) ~= 'boolean' then
|
||||
immutable = false
|
||||
end
|
||||
|
||||
if not is_string then
|
||||
offset = offset or 0
|
||||
position = {x = position.x + offset, y = position.y + offset}
|
||||
|
||||
-- round at precision of 2
|
||||
text = floor(100 * value) * 0.01
|
||||
|
||||
if (0 == text) then
|
||||
text = '0.00'
|
||||
end
|
||||
end
|
||||
|
||||
if not immutable then
|
||||
local text_entity = surface.find_entity('flying-text', position)
|
||||
|
||||
if text_entity then
|
||||
text_entity.text = text
|
||||
text_entity.color = color
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
surface.create_entity{
|
||||
name = 'flying-text',
|
||||
color = color,
|
||||
text = text,
|
||||
position = position
|
||||
}.active = false
|
||||
end
|
||||
|
||||
return Debug
|
||||
-- dependencies
|
||||
local min = math.min
|
||||
local max = math.max
|
||||
local floor = math.floor
|
||||
local abs = math.abs
|
||||
|
||||
-- this
|
||||
local Debug = {}
|
||||
|
||||
-- private state
|
||||
local debug = false
|
||||
local cheats = false
|
||||
|
||||
function Debug.enable_debug()
|
||||
debug = true
|
||||
end
|
||||
|
||||
function Debug.disable_debug()
|
||||
debug = false
|
||||
end
|
||||
|
||||
function Debug.enable_cheats()
|
||||
cheats = true
|
||||
end
|
||||
|
||||
function Debug.disable_cheats()
|
||||
cheats = true
|
||||
end
|
||||
|
||||
global.message_count = 0
|
||||
|
||||
--[[--
|
||||
Shows the given message if debug is enabled.
|
||||
|
||||
@param message string
|
||||
]]
|
||||
function Debug.print(message)
|
||||
if type(message) ~= 'string' and type(message) ~= 'number' and type(message) ~= 'boolean' then message = type(message) end
|
||||
global.message_count = global.message_count + 1
|
||||
if (debug) then
|
||||
game.print('[' .. global.message_count .. '] ' .. tostring(message))
|
||||
log('[' .. global.message_count .. '] ' .. tostring(message))
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Shows the given message with serpent enabled, if debug is enabled.
|
||||
|
||||
@param message string
|
||||
]]
|
||||
function Debug.print_serpent(message)
|
||||
Debug.print(serpent.line(message))
|
||||
end
|
||||
|
||||
--[[--
|
||||
Shows the given message if _DEBUG == true for a given position.
|
||||
|
||||
@param x number
|
||||
@param y number
|
||||
@param message string
|
||||
]]
|
||||
function Debug.print_position(position, message)
|
||||
message = message or ''
|
||||
if type(message) ~= 'string' and type(message) ~= 'number' and type(message) ~= 'boolean' then message = type(message) end
|
||||
global.message_count = global.message_count + 1
|
||||
if (debug) then
|
||||
game.print('[' .. global.message_count .. '] {x=' .. position.x .. ', y=' .. position.y .. '} ' .. tostring(message))
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Executes the given callback if cheating is enabled.
|
||||
|
||||
@param callback function
|
||||
]]
|
||||
function Debug.cheat(callback)
|
||||
if (cheats) then
|
||||
callback()
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Prints a colored value on a location.
|
||||
|
||||
@param value between -1 and 1
|
||||
@param surface LuaSurface
|
||||
@param position Position {x, y}
|
||||
@param scale float
|
||||
@param offset float
|
||||
@param immutable bool if immutable, only set, never do a surface lookup, values never change
|
||||
]]
|
||||
function Debug.print_grid_value(value, surface, position, scale, offset, immutable)
|
||||
local is_string = type(value) == 'string'
|
||||
local color = {r = 1, g = 1, b = 1}
|
||||
text = value
|
||||
|
||||
if type(immutable) ~= 'boolean' then
|
||||
immutable = false
|
||||
end
|
||||
|
||||
if not is_string then
|
||||
scale = scale or 1
|
||||
offset = offset or 0
|
||||
position = {x = position.x + offset, y = position.y + offset}
|
||||
local r = max(1, value) / scale
|
||||
local g = 1 - abs(value) / scale
|
||||
local b = min(1, value) / scale
|
||||
|
||||
if (r > 0) then
|
||||
r = 0
|
||||
end
|
||||
|
||||
if (b < 0) then
|
||||
b = 0
|
||||
end
|
||||
|
||||
if (g < 0) then
|
||||
g = 0
|
||||
end
|
||||
|
||||
r = abs(r)
|
||||
|
||||
color = { r = r, g = g, b = b}
|
||||
|
||||
-- round at precision of 2
|
||||
text = floor(100 * value) * 0.01
|
||||
|
||||
if (0 == text) then
|
||||
text = '0.00'
|
||||
end
|
||||
end
|
||||
|
||||
if not immutable then
|
||||
local text_entity = surface.find_entity('flying-text', position)
|
||||
|
||||
if text_entity then
|
||||
text_entity.text = text
|
||||
text_entity.color = color
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
surface.create_entity{
|
||||
name = 'flying-text',
|
||||
color = color,
|
||||
text = text,
|
||||
position = position
|
||||
}.active = false
|
||||
end
|
||||
|
||||
--[[--
|
||||
Prints a colored value on a location. When given a color_value and a delta_color,
|
||||
will change the color of the text from the base to base + value * delta. This will
|
||||
make the color of the text range from 'base_color' to 'base_color + delta_color'
|
||||
as the color_value ranges from 0 to 1
|
||||
|
||||
@param value of number to be displayed
|
||||
@param surface LuaSurface
|
||||
@param position Position {x, y}
|
||||
@param scale float
|
||||
@param offset float position offset
|
||||
@param immutable bool if immutable, only set, never do a surface lookup, values never change
|
||||
@param color_value float How far along the range of values of colors the value is to be displayed
|
||||
@param base_color {r,g,b} The color for the text to be if color_value is 0
|
||||
@param delta_color {r,g,b} The amount to correct the base_color if color_value is 1
|
||||
@param under_bound {r,g,b} The color to be used if color_value < 0
|
||||
@param over_bound {r,g,b} The color to be used if color_value > 1
|
||||
]]
|
||||
function Debug.print_colored_grid_value(value, surface, position, scale, offset, immutable,
|
||||
color_value, base_color, delta_color, under_bound, over_bound)
|
||||
local is_string = type(value) == 'string'
|
||||
-- default values:
|
||||
local color = base_color or {r = 1, g = 1, b = 1}
|
||||
local d_color = delta_color or {r = 0, g = 0, b = 0}
|
||||
local u_color = under_bound or color
|
||||
local o_color = over_bound or color
|
||||
|
||||
if (color_value < 0) then
|
||||
color = u_color
|
||||
elseif (color_value > 1) then
|
||||
color = o_color
|
||||
else
|
||||
color = { r = color.r + color_value * d_color.r,
|
||||
g = color.g + color_value * d_color.g,
|
||||
b = color.b + color_value * d_color.b }
|
||||
end
|
||||
|
||||
text = value
|
||||
|
||||
if type(immutable) ~= 'boolean' then
|
||||
immutable = false
|
||||
end
|
||||
|
||||
if not is_string then
|
||||
offset = offset or 0
|
||||
position = {x = position.x + offset, y = position.y + offset}
|
||||
|
||||
-- round at precision of 2
|
||||
text = floor(100 * value) * 0.01
|
||||
|
||||
if (0 == text) then
|
||||
text = '0.00'
|
||||
end
|
||||
end
|
||||
|
||||
if not immutable then
|
||||
local text_entity = surface.find_entity('flying-text', position)
|
||||
|
||||
if text_entity then
|
||||
text_entity.text = text
|
||||
text_entity.color = color
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
surface.create_entity{
|
||||
name = 'flying-text',
|
||||
color = color,
|
||||
text = text,
|
||||
position = position
|
||||
}.active = false
|
||||
end
|
||||
|
||||
return Debug
|
||||
|
@ -1,66 +1,66 @@
|
||||
--[[-- info
|
||||
Provides the ability to spawn aliens.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local AlienEvolutionProgress = require 'map_gen.Diggy.AlienEvolutionProgress'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local insert = table.insert
|
||||
local random = math.random
|
||||
|
||||
-- this
|
||||
local AlienSpawner = {}
|
||||
|
||||
local function spawn_alien(surface, x, y)
|
||||
local enemy_force = game.forces.enemy
|
||||
local enemy_force_evolution = enemy_force.evolution_factor
|
||||
local position = {x = x, y = y}
|
||||
local biters = AlienEvolutionProgress.getBitersByEvolution(random(1, 2), enemy_force_evolution)
|
||||
local spitters = AlienEvolutionProgress.getSpittersByEvolution(random(1, 2), enemy_force_evolution)
|
||||
|
||||
local units = {}
|
||||
for name, amount in pairs(biters) do
|
||||
insert(units, {name = name, position = position, force = enemy_force, amount = amount})
|
||||
end
|
||||
for name, amount in pairs(spitters) do
|
||||
insert(units, {name = name, position = position, force = enemy_force, amount = amount})
|
||||
end
|
||||
|
||||
Template.units(surface, units, 1.5, 'small-biter')
|
||||
end
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function AlienSpawner.register(config)
|
||||
local alien_minimum_distance_square = config.alien_minimum_distance ^ 2
|
||||
|
||||
Event.add(Template.events.on_void_removed, function (event)
|
||||
game.forces.enemy.evolution_factor = game.forces.enemy.evolution_factor + 0.0000012
|
||||
|
||||
local position = event.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
|
||||
if (x * x + y * y < alien_minimum_distance_square or config.alien_probability < random()) then
|
||||
return
|
||||
end
|
||||
|
||||
spawn_alien(event.surface, x, y)
|
||||
end)
|
||||
end
|
||||
|
||||
function AlienSpawner.get_extra_map_info(config)
|
||||
return [[Alien Spawner, aliens might spawn when mining!
|
||||
Spawn chance: ]] .. (config.alien_probability * 100) .. [[%
|
||||
Minimum spawn distance: ]] .. config.alien_minimum_distance .. ' tiles'
|
||||
end
|
||||
|
||||
function AlienSpawner.on_init()
|
||||
-- base factorio = pollution_factor = 0.000015
|
||||
game.map_settings.enemy_evolution.pollution_factor = 0.000004
|
||||
end
|
||||
|
||||
return AlienSpawner
|
||||
--[[-- info
|
||||
Provides the ability to spawn aliens.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local AlienEvolutionProgress = require 'map_gen.Diggy.AlienEvolutionProgress'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local insert = table.insert
|
||||
local random = math.random
|
||||
|
||||
-- this
|
||||
local AlienSpawner = {}
|
||||
|
||||
local function spawn_alien(surface, x, y)
|
||||
local enemy_force = game.forces.enemy
|
||||
local enemy_force_evolution = enemy_force.evolution_factor
|
||||
local position = {x = x, y = y}
|
||||
local biters = AlienEvolutionProgress.getBitersByEvolution(random(1, 2), enemy_force_evolution)
|
||||
local spitters = AlienEvolutionProgress.getSpittersByEvolution(random(1, 2), enemy_force_evolution)
|
||||
|
||||
local units = {}
|
||||
for name, amount in pairs(biters) do
|
||||
insert(units, {name = name, position = position, force = enemy_force, amount = amount})
|
||||
end
|
||||
for name, amount in pairs(spitters) do
|
||||
insert(units, {name = name, position = position, force = enemy_force, amount = amount})
|
||||
end
|
||||
|
||||
Template.units(surface, units, 1.5, 'small-biter')
|
||||
end
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function AlienSpawner.register(config)
|
||||
local alien_minimum_distance_square = config.alien_minimum_distance ^ 2
|
||||
|
||||
Event.add(Template.events.on_void_removed, function (event)
|
||||
game.forces.enemy.evolution_factor = game.forces.enemy.evolution_factor + 0.0000012
|
||||
|
||||
local position = event.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
|
||||
if (x * x + y * y < alien_minimum_distance_square or config.alien_probability < random()) then
|
||||
return
|
||||
end
|
||||
|
||||
spawn_alien(event.surface, x, y)
|
||||
end)
|
||||
end
|
||||
|
||||
function AlienSpawner.get_extra_map_info(config)
|
||||
return [[Alien Spawner, aliens might spawn when mining!
|
||||
Spawn chance: ]] .. (config.alien_probability * 100) .. [[%
|
||||
Minimum spawn distance: ]] .. config.alien_minimum_distance .. ' tiles'
|
||||
end
|
||||
|
||||
function AlienSpawner.on_init()
|
||||
-- base factorio = pollution_factor = 0.000015
|
||||
game.map_settings.enemy_evolution.pollution_factor = 0.000004
|
||||
end
|
||||
|
||||
return AlienSpawner
|
||||
|
@ -1,57 +1,57 @@
|
||||
--[[-- info
|
||||
Provides the ability to setup a player when first joined.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local CaveCollapse = require 'map_gen.Diggy.Feature.DiggyCaveCollapse'
|
||||
local Game = require 'utils.game'
|
||||
local Report = require 'features.report'
|
||||
|
||||
-- this
|
||||
local Antigrief = {}
|
||||
|
||||
global.Antigrief = {
|
||||
autojail = false,
|
||||
jailed_players = {},
|
||||
last_collapse = 0
|
||||
}
|
||||
|
||||
local allowed_collapses_first_hour = 0
|
||||
|
||||
local player_collapses = {}
|
||||
|
||||
Global.register({
|
||||
cave_collapse_disabled = cave_collapse_disabled
|
||||
}, function(tbl)
|
||||
cave_collapse_disabled = tbl.cave_collapse_disabled
|
||||
end)
|
||||
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function Antigrief.register(config)
|
||||
global.Antigrief.autojail = config.autojail
|
||||
allowed_collapses_first_hour = config.allowed_collapses_first_hour
|
||||
end
|
||||
|
||||
|
||||
Event.add(CaveCollapse.events.on_collapse, function(event)
|
||||
local player_index = event.player_index
|
||||
if player_index and global.Antigrief.last_collapse ~= game.tick then
|
||||
global.Antigrief.last_collapse = game.tick
|
||||
local count = player_collapses[player_index] or 0
|
||||
count = count + 1
|
||||
player_collapses[player_index] = count
|
||||
local player = Game.get_player_by_index(player_index)
|
||||
if global.Antigrief.autojail and count > allowed_collapses_first_hour and player.online_time < 216000 and not global.Antigrief.jailed_players[player_index] then
|
||||
Report.jail(player)
|
||||
Report.report(nil, player, string.format("Caused %d collapses in the first hour", count))
|
||||
global.Antigrief.jailed_players[player_index] = true
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
return Antigrief
|
||||
--[[-- info
|
||||
Provides the ability to setup a player when first joined.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local CaveCollapse = require 'map_gen.Diggy.Feature.DiggyCaveCollapse'
|
||||
local Game = require 'utils.game'
|
||||
local Report = require 'features.report'
|
||||
|
||||
-- this
|
||||
local Antigrief = {}
|
||||
|
||||
global.Antigrief = {
|
||||
autojail = false,
|
||||
jailed_players = {},
|
||||
last_collapse = 0
|
||||
}
|
||||
|
||||
local allowed_collapses_first_hour = 0
|
||||
|
||||
local player_collapses = {}
|
||||
|
||||
Global.register({
|
||||
cave_collapse_disabled = cave_collapse_disabled
|
||||
}, function(tbl)
|
||||
cave_collapse_disabled = tbl.cave_collapse_disabled
|
||||
end)
|
||||
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function Antigrief.register(config)
|
||||
global.Antigrief.autojail = config.autojail
|
||||
allowed_collapses_first_hour = config.allowed_collapses_first_hour
|
||||
end
|
||||
|
||||
|
||||
Event.add(CaveCollapse.events.on_collapse, function(event)
|
||||
local player_index = event.player_index
|
||||
if player_index and global.Antigrief.last_collapse ~= game.tick then
|
||||
global.Antigrief.last_collapse = game.tick
|
||||
local count = player_collapses[player_index] or 0
|
||||
count = count + 1
|
||||
player_collapses[player_index] = count
|
||||
local player = Game.get_player_by_index(player_index)
|
||||
if global.Antigrief.autojail and count > allowed_collapses_first_hour and player.online_time < 216000 and not global.Antigrief.jailed_players[player_index] then
|
||||
Report.jail(player)
|
||||
Report.report(nil, player, string.format("Caused %d collapses in the first hour", count))
|
||||
global.Antigrief.jailed_players[player_index] = true
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
return Antigrief
|
||||
|
@ -1,242 +1,242 @@
|
||||
--[[-- info
|
||||
Provides the ability to collect coins and send them to space.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local ScoreTable = require 'map_gen.Diggy.ScoreTable'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local random = math.random
|
||||
local ceil = math.ceil
|
||||
local Gui = require 'utils.gui'
|
||||
local utils = require 'utils.utils'
|
||||
|
||||
-- this
|
||||
local ArtefactHunting = {}
|
||||
|
||||
-- some GUI stuff
|
||||
local function redraw_table(data)
|
||||
local list = data.list
|
||||
Gui.clear(list)
|
||||
|
||||
data.frame.caption = 'Scoretable'
|
||||
|
||||
local score_keys = ScoreTable.all_keys()
|
||||
|
||||
for _, data in pairs(score_keys) do
|
||||
local val = ScoreTable.get(data)
|
||||
|
||||
local table = list.add({type = 'table', column_count = 2})
|
||||
|
||||
local key = table.add({type = 'label', name = 'Diggy.ArtefactHunting.Frame.List.Key', caption = data})
|
||||
key.style.minimal_width = 175
|
||||
|
||||
local val = table.add({type = 'label', name = 'Diggy.ArtefactHunting.Frame.List.Val', caption = utils.comma_value(val)})
|
||||
val.style.minimal_width = 225
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function toggle(event)
|
||||
local player = event.player
|
||||
local center = player.gui.left
|
||||
local frame = center['Diggy.ArtefactHunting.Frame']
|
||||
|
||||
if (frame and event.trigger == nil) then
|
||||
Gui.destroy(frame)
|
||||
return
|
||||
elseif (frame) then
|
||||
local data = Gui.get_data(frame)
|
||||
redraw_table(data)
|
||||
return
|
||||
end
|
||||
|
||||
frame = center.add({name = 'Diggy.ArtefactHunting.Frame', type = 'frame', direction = 'vertical'})
|
||||
|
||||
local scroll_pane = frame.add({type = 'scroll-pane'})
|
||||
scroll_pane.style.maximal_height = 400
|
||||
|
||||
frame.add({ type = 'button', name = 'Diggy.ArtefactHunting.Button', caption = 'Close'})
|
||||
|
||||
local data = {
|
||||
frame = frame,
|
||||
list = scroll_pane
|
||||
}
|
||||
|
||||
redraw_table(data)
|
||||
|
||||
Gui.set_data(frame, data)
|
||||
end
|
||||
|
||||
local function on_player_created(event)
|
||||
Game.get_player_by_index(event.player_index).gui.top.add({
|
||||
name = 'Diggy.ArtefactHunting.Button',
|
||||
type = 'sprite-button',
|
||||
sprite = 'item/steel-axe',
|
||||
})
|
||||
end
|
||||
|
||||
Gui.on_click('Diggy.ArtefactHunting.Button', toggle)
|
||||
Gui.on_custom_close('Diggy.ArtefactHunting.Frame', function (event)
|
||||
event.element.destroy()
|
||||
end)
|
||||
|
||||
function ArtefactHunting.update_gui()
|
||||
for _, p in ipairs(game.connected_players) do
|
||||
local frame = p.gui.left['Diggy.ArtefactHunting.Frame']
|
||||
|
||||
if frame and frame.valid then
|
||||
local data = {player = p, trigger = 'update_gui'}
|
||||
toggle(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function ArtefactHunting.register(config)
|
||||
Event.add(defines.events.on_player_created, on_player_created)
|
||||
Event.on_nth_tick(61, ArtefactHunting.update_gui)
|
||||
|
||||
ScoreTable.reset('Coins sent to space')
|
||||
|
||||
local seed
|
||||
local function get_noise(surface, x, y)
|
||||
seed = seed or surface.map_gen_settings.seed + surface.index + 300
|
||||
return Perlin.noise(x * config.noise_variance * 0.9, y * config.noise_variance * 1.1, seed)
|
||||
end
|
||||
|
||||
local distance_required = config.minimal_treasure_chest_distance * config.minimal_treasure_chest_distance
|
||||
|
||||
Event.add(defines.events.on_rocket_launched, function (event)
|
||||
local coins = event.rocket.get_inventory(defines.inventory.rocket).get_item_count('coin')
|
||||
if coins > 0 then
|
||||
local sum = ScoreTable.add('Coins sent to space', coins)
|
||||
game.print('sent ' .. coins .. ' coins into space! The space station is now holding ' .. sum .. ' coins.')
|
||||
end
|
||||
end)
|
||||
|
||||
Event.add(Template.events.on_void_removed, function (event)
|
||||
local position = event.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
|
||||
if (x * x + y * y <= distance_required) then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = event.surface
|
||||
|
||||
if get_noise(surface, x, y) < config.treasure_chest_noise_threshold then
|
||||
return
|
||||
end
|
||||
|
||||
local chest = surface.create_entity({name = 'steel-chest', position = position, force = game.forces.player})
|
||||
|
||||
if not chest then
|
||||
return
|
||||
end
|
||||
|
||||
for name, prototype in pairs(config.treasure_chest_raffle) do
|
||||
if random() <= prototype.chance then
|
||||
chest.insert({name = name, count = random(prototype.min, prototype.max)})
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local modifiers = config.alien_coin_modifiers
|
||||
|
||||
local function picked_up_coins(player_index, count)
|
||||
local text
|
||||
if count == 1 then
|
||||
text = '+1 coin'
|
||||
ScoreTable.increment('Collected coins')
|
||||
else
|
||||
text = '+' .. count ..' coins'
|
||||
ScoreTable.add('Collected coins', count)
|
||||
end
|
||||
|
||||
Game.print_player_floating_text(player_index, text, {r = 255, g = 215, b = 0})
|
||||
end
|
||||
|
||||
ScoreTable.reset('Collected coins')
|
||||
|
||||
Event.add(defines.events.on_entity_died, function (event)
|
||||
local entity = event.entity
|
||||
local force = entity.force
|
||||
|
||||
if force.name ~= 'enemy' then
|
||||
return
|
||||
end
|
||||
|
||||
local cause = event.cause
|
||||
|
||||
if not cause or cause.type ~= 'player' or not cause.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local modifier = modifiers[entity.name] or 1
|
||||
local evolution_multiplier = force.evolution_factor * 11
|
||||
local count = random(
|
||||
ceil(2 * evolution_multiplier * 0.1),
|
||||
ceil(5 * (evolution_multiplier * evolution_multiplier + modifier) * 0.1)
|
||||
)
|
||||
|
||||
entity.surface.create_entity({
|
||||
name = 'item-on-ground',
|
||||
position = entity.position,
|
||||
stack = {name = 'coin', count = count}
|
||||
})
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_picked_up_item, function (event)
|
||||
local stack = event.item_stack
|
||||
if stack.name ~= 'coin' then
|
||||
return
|
||||
end
|
||||
|
||||
picked_up_coins(event.player_index, stack.count)
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_pre_player_mined_item, function (event)
|
||||
if event.entity.type ~= 'simple-entity' then
|
||||
return
|
||||
end
|
||||
|
||||
if random() > config.mining_artefact_chance then
|
||||
return
|
||||
end
|
||||
|
||||
local count = random(config.mining_artefact_amount.min, config.mining_artefact_amount.max)
|
||||
local player_index = event.player_index
|
||||
|
||||
Game.get_player_by_index(player_index).insert({name = 'coin', count = count})
|
||||
picked_up_coins(player_index, count)
|
||||
end)
|
||||
|
||||
if (config.display_chest_locations) then
|
||||
Event.add(defines.events.on_chunk_generated, function (event)
|
||||
local surface = event.surface
|
||||
local area = event.area
|
||||
|
||||
for x = area.left_top.x, area.left_top.x + 31 do
|
||||
local sq_x = x * x
|
||||
for y = area.left_top.y, area.left_top.y + 31 do
|
||||
if sq_x + y * y >= distance_required and get_noise(surface, x, y) >= config.treasure_chest_noise_threshold then
|
||||
Debug.print_grid_value('chest', surface, {x = x, y = y}, nil, nil, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ArtefactHunting.get_extra_map_info(config)
|
||||
return 'Artefact Hunting, find precious coins while mining and launch them to the surface!'
|
||||
end
|
||||
|
||||
return ArtefactHunting
|
||||
--[[-- info
|
||||
Provides the ability to collect coins and send them to space.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Game = require 'utils.game'
|
||||
local ScoreTable = require 'map_gen.Diggy.ScoreTable'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local random = math.random
|
||||
local ceil = math.ceil
|
||||
local Gui = require 'utils.gui'
|
||||
local utils = require 'utils.utils'
|
||||
|
||||
-- this
|
||||
local ArtefactHunting = {}
|
||||
|
||||
-- some GUI stuff
|
||||
local function redraw_table(data)
|
||||
local list = data.list
|
||||
Gui.clear(list)
|
||||
|
||||
data.frame.caption = 'Scoretable'
|
||||
|
||||
local score_keys = ScoreTable.all_keys()
|
||||
|
||||
for _, data in pairs(score_keys) do
|
||||
local val = ScoreTable.get(data)
|
||||
|
||||
local table = list.add({type = 'table', column_count = 2})
|
||||
|
||||
local key = table.add({type = 'label', name = 'Diggy.ArtefactHunting.Frame.List.Key', caption = data})
|
||||
key.style.minimal_width = 175
|
||||
|
||||
local val = table.add({type = 'label', name = 'Diggy.ArtefactHunting.Frame.List.Val', caption = utils.comma_value(val)})
|
||||
val.style.minimal_width = 225
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function toggle(event)
|
||||
local player = event.player
|
||||
local center = player.gui.left
|
||||
local frame = center['Diggy.ArtefactHunting.Frame']
|
||||
|
||||
if (frame and event.trigger == nil) then
|
||||
Gui.destroy(frame)
|
||||
return
|
||||
elseif (frame) then
|
||||
local data = Gui.get_data(frame)
|
||||
redraw_table(data)
|
||||
return
|
||||
end
|
||||
|
||||
frame = center.add({name = 'Diggy.ArtefactHunting.Frame', type = 'frame', direction = 'vertical'})
|
||||
|
||||
local scroll_pane = frame.add({type = 'scroll-pane'})
|
||||
scroll_pane.style.maximal_height = 400
|
||||
|
||||
frame.add({ type = 'button', name = 'Diggy.ArtefactHunting.Button', caption = 'Close'})
|
||||
|
||||
local data = {
|
||||
frame = frame,
|
||||
list = scroll_pane
|
||||
}
|
||||
|
||||
redraw_table(data)
|
||||
|
||||
Gui.set_data(frame, data)
|
||||
end
|
||||
|
||||
local function on_player_created(event)
|
||||
Game.get_player_by_index(event.player_index).gui.top.add({
|
||||
name = 'Diggy.ArtefactHunting.Button',
|
||||
type = 'sprite-button',
|
||||
sprite = 'item/steel-axe',
|
||||
})
|
||||
end
|
||||
|
||||
Gui.on_click('Diggy.ArtefactHunting.Button', toggle)
|
||||
Gui.on_custom_close('Diggy.ArtefactHunting.Frame', function (event)
|
||||
event.element.destroy()
|
||||
end)
|
||||
|
||||
function ArtefactHunting.update_gui()
|
||||
for _, p in ipairs(game.connected_players) do
|
||||
local frame = p.gui.left['Diggy.ArtefactHunting.Frame']
|
||||
|
||||
if frame and frame.valid then
|
||||
local data = {player = p, trigger = 'update_gui'}
|
||||
toggle(data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function ArtefactHunting.register(config)
|
||||
Event.add(defines.events.on_player_created, on_player_created)
|
||||
Event.on_nth_tick(61, ArtefactHunting.update_gui)
|
||||
|
||||
ScoreTable.reset('Coins sent to space')
|
||||
|
||||
local seed
|
||||
local function get_noise(surface, x, y)
|
||||
seed = seed or surface.map_gen_settings.seed + surface.index + 300
|
||||
return Perlin.noise(x * config.noise_variance * 0.9, y * config.noise_variance * 1.1, seed)
|
||||
end
|
||||
|
||||
local distance_required = config.minimal_treasure_chest_distance * config.minimal_treasure_chest_distance
|
||||
|
||||
Event.add(defines.events.on_rocket_launched, function (event)
|
||||
local coins = event.rocket.get_inventory(defines.inventory.rocket).get_item_count('coin')
|
||||
if coins > 0 then
|
||||
local sum = ScoreTable.add('Coins sent to space', coins)
|
||||
game.print('sent ' .. coins .. ' coins into space! The space station is now holding ' .. sum .. ' coins.')
|
||||
end
|
||||
end)
|
||||
|
||||
Event.add(Template.events.on_void_removed, function (event)
|
||||
local position = event.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
|
||||
if (x * x + y * y <= distance_required) then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = event.surface
|
||||
|
||||
if get_noise(surface, x, y) < config.treasure_chest_noise_threshold then
|
||||
return
|
||||
end
|
||||
|
||||
local chest = surface.create_entity({name = 'steel-chest', position = position, force = game.forces.player})
|
||||
|
||||
if not chest then
|
||||
return
|
||||
end
|
||||
|
||||
for name, prototype in pairs(config.treasure_chest_raffle) do
|
||||
if random() <= prototype.chance then
|
||||
chest.insert({name = name, count = random(prototype.min, prototype.max)})
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
local modifiers = config.alien_coin_modifiers
|
||||
|
||||
local function picked_up_coins(player_index, count)
|
||||
local text
|
||||
if count == 1 then
|
||||
text = '+1 coin'
|
||||
ScoreTable.increment('Collected coins')
|
||||
else
|
||||
text = '+' .. count ..' coins'
|
||||
ScoreTable.add('Collected coins', count)
|
||||
end
|
||||
|
||||
Game.print_player_floating_text(player_index, text, {r = 255, g = 215, b = 0})
|
||||
end
|
||||
|
||||
ScoreTable.reset('Collected coins')
|
||||
|
||||
Event.add(defines.events.on_entity_died, function (event)
|
||||
local entity = event.entity
|
||||
local force = entity.force
|
||||
|
||||
if force.name ~= 'enemy' then
|
||||
return
|
||||
end
|
||||
|
||||
local cause = event.cause
|
||||
|
||||
if not cause or cause.type ~= 'player' or not cause.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local modifier = modifiers[entity.name] or 1
|
||||
local evolution_multiplier = force.evolution_factor * 11
|
||||
local count = random(
|
||||
ceil(2 * evolution_multiplier * 0.1),
|
||||
ceil(5 * (evolution_multiplier * evolution_multiplier + modifier) * 0.1)
|
||||
)
|
||||
|
||||
entity.surface.create_entity({
|
||||
name = 'item-on-ground',
|
||||
position = entity.position,
|
||||
stack = {name = 'coin', count = count}
|
||||
})
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_picked_up_item, function (event)
|
||||
local stack = event.item_stack
|
||||
if stack.name ~= 'coin' then
|
||||
return
|
||||
end
|
||||
|
||||
picked_up_coins(event.player_index, stack.count)
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_pre_player_mined_item, function (event)
|
||||
if event.entity.type ~= 'simple-entity' then
|
||||
return
|
||||
end
|
||||
|
||||
if random() > config.mining_artefact_chance then
|
||||
return
|
||||
end
|
||||
|
||||
local count = random(config.mining_artefact_amount.min, config.mining_artefact_amount.max)
|
||||
local player_index = event.player_index
|
||||
|
||||
Game.get_player_by_index(player_index).insert({name = 'coin', count = count})
|
||||
picked_up_coins(player_index, count)
|
||||
end)
|
||||
|
||||
if (config.display_chest_locations) then
|
||||
Event.add(defines.events.on_chunk_generated, function (event)
|
||||
local surface = event.surface
|
||||
local area = event.area
|
||||
|
||||
for x = area.left_top.x, area.left_top.x + 31 do
|
||||
local sq_x = x * x
|
||||
for y = area.left_top.y, area.left_top.y + 31 do
|
||||
if sq_x + y * y >= distance_required and get_noise(surface, x, y) >= config.treasure_chest_noise_threshold then
|
||||
Debug.print_grid_value('chest', surface, {x = x, y = y}, nil, nil, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ArtefactHunting.get_extra_map_info(config)
|
||||
return 'Artefact Hunting, find precious coins while mining and launch them to the surface!'
|
||||
end
|
||||
|
||||
return ArtefactHunting
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,307 +1,307 @@
|
||||
--[[-- info
|
||||
Provides the ability to "mine" through out-of-map tiles by destroying or
|
||||
mining rocks next to it.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local Game = require 'utils.game'
|
||||
local Scanner = require 'map_gen.Diggy.Scanner'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local ScoreTable = require 'map_gen.Diggy.ScoreTable'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local insert = table.insert
|
||||
local random = math.random
|
||||
|
||||
-- todo remove this dependency
|
||||
local ResourceConfig = require 'map_gen.Diggy.Config'.features.ScatteredResources
|
||||
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Simplex = require 'map_gen.shared.simplex_noise'
|
||||
|
||||
-- this
|
||||
local DiggyHole = {}
|
||||
|
||||
-- keeps track of the amount of times per player when they mined with a full inventory in a row
|
||||
local full_inventory_mining_cache = {}
|
||||
|
||||
Global.register({
|
||||
full_inventory_mining_cache = full_inventory_mining_cache,
|
||||
}, function (tbl)
|
||||
full_inventory_mining_cache = tbl.full_inventory_mining_cache
|
||||
end)
|
||||
|
||||
local function reset_player_full_inventory_cache(player)
|
||||
if not full_inventory_mining_cache[player.index] then
|
||||
return
|
||||
end
|
||||
|
||||
full_inventory_mining_cache[player.index] = nil
|
||||
end
|
||||
|
||||
local full_inventory_message = 'Miner, you have a full inventory!\n\nMake sure to empty it before you continue digging.'
|
||||
|
||||
local function trigger_inventory_warning(player)
|
||||
local player_index = player.index
|
||||
local count = full_inventory_mining_cache[player_index]
|
||||
if not count then
|
||||
full_inventory_mining_cache[player_index] = 1
|
||||
player.print('## - ' .. full_inventory_message, {r = 1, g = 1, b = 0, a = 1})
|
||||
player.play_sound{path='utility/new_objective', volume_modifier = 1 }
|
||||
return
|
||||
end
|
||||
|
||||
full_inventory_mining_cache[player_index] = count + 1
|
||||
|
||||
if count % 5 == 0 then
|
||||
require 'features.gui.popup'.player(player, full_inventory_message)
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Triggers a diggy diggy hole for a given sand-rock-big or rock-huge.
|
||||
|
||||
Will return true even if the tile behind it is immune.
|
||||
|
||||
@param entity LuaEntity
|
||||
]]
|
||||
local function diggy_hole(entity)
|
||||
if ((entity.name ~= 'sand-rock-big') and (entity.name ~= 'rock-huge')) then
|
||||
return
|
||||
end
|
||||
|
||||
local tiles = {}
|
||||
local rocks = {}
|
||||
local surface = entity.surface
|
||||
local position = entity.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
|
||||
local out_of_map_found = Scanner.scan_around_position(surface, position, 'out-of-map');
|
||||
local distance = ResourceConfig.distance(x, y)
|
||||
|
||||
-- source of noise for resource generation
|
||||
-- index determines offset
|
||||
-- '-1' is reserved for cluster mode
|
||||
-- compound clusters use as many indexes as needed > 1
|
||||
local base_seed
|
||||
local function seeded_noise(surface, x, y, index, sources)
|
||||
base_seed = base_seed or surface.map_gen_settings.seed + surface.index + 4000
|
||||
local noise = 0
|
||||
for _, settings in ipairs(sources) do
|
||||
settings.type = settings.type or 'perlin'
|
||||
settings.offset = settings.offset or 0
|
||||
if settings.type == 'zero' then
|
||||
noise = noise + 0
|
||||
elseif settings.type == 'one' then
|
||||
noise = noise + settings.weight * 1
|
||||
elseif settings.type == 'perlin' then
|
||||
noise = noise + settings.weight * Perlin.noise(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
elseif settings.type == 'simplex' then
|
||||
noise = noise + settings.weight * Simplex.d2(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
else
|
||||
Debug.print('noise type \'' .. settings.type .. '\' not recognized')
|
||||
end
|
||||
|
||||
end
|
||||
return noise
|
||||
end
|
||||
|
||||
-- global config values
|
||||
local resource_richness_weights = ResourceConfig.resource_richness_weights
|
||||
local resource_richness_weights_sum = 0
|
||||
for _, weight in pairs(resource_richness_weights) do
|
||||
resource_richness_weights_sum = resource_richness_weights_sum + weight
|
||||
end
|
||||
|
||||
local s_resource_weights = ResourceConfig.scattered_resource_weights
|
||||
local s_resource_weights_sum = 0
|
||||
for _, weight in pairs(s_resource_weights) do
|
||||
s_resource_weights_sum = s_resource_weights_sum + weight
|
||||
end
|
||||
|
||||
-- compound cluster spawning
|
||||
local c_mode = ResourceConfig.cluster_mode
|
||||
-- local c_clusters = Config.features.ScatteredResources.clusters
|
||||
local c_clusters = require(ResourceConfig.cluster_file_location)
|
||||
if ('table' ~= type(c_clusters)) then
|
||||
error('cluster_file_location invalid')
|
||||
end
|
||||
|
||||
local c_count = 0
|
||||
for _, cluster in ipairs(c_clusters) do
|
||||
c_count = c_count + 1
|
||||
cluster.weights_sum = 0
|
||||
for _, weight in pairs(cluster.weights) do
|
||||
cluster.weights_sum = cluster.weights_sum + weight
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_cluster_resource(surface, x, y, cluster_index, cluster)
|
||||
for name, weight in pairs(cluster.weights) do
|
||||
if name == 'skip' then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local huge_rock_inserted = false
|
||||
for _, position in pairs(out_of_map_found) do
|
||||
insert(tiles, {name = 'dirt-' .. random(1, 7), position = position})
|
||||
-- if (random() > 0.50) then
|
||||
-- insert(rocks, {name = 'rock-huge', position = position})
|
||||
|
||||
|
||||
if c_mode then
|
||||
for index,cluster in ipairs(c_clusters) do
|
||||
if distance >= cluster.min_distance and cluster.noise_settings.type ~= 'skip' then
|
||||
if cluster.noise_settings.type == "connected_tendril" then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if -1 * cluster.noise_settings.threshold < noise and noise < cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
elseif cluster.noise_settings.type == "fragmented_tendril" then
|
||||
local noise1 = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
local noise2 = seeded_noise(surface, x, y, index, cluster.noise_settings.discriminator)
|
||||
if -1 * cluster.noise_settings.threshold < noise1 and noise1 < cluster.noise_settings.threshold
|
||||
and -1 * cluster.noise_settings.discriminator_threshold < noise2
|
||||
and noise2 < cluster.noise_settings.discriminator_threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
else
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if noise >= cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (huge_rock_inserted == false) then
|
||||
insert(rocks, {name = 'sand-rock-big', position = position})
|
||||
end
|
||||
end
|
||||
|
||||
Template.insert(surface, tiles, rocks)
|
||||
end
|
||||
|
||||
local artificial_tiles = {
|
||||
['stone-brick'] = true,
|
||||
['stone-path'] = true,
|
||||
['concrete'] = true,
|
||||
['hazard-concrete-left'] = true,
|
||||
['hazard-concrete-right'] = true,
|
||||
['refined-concrete'] = true,
|
||||
['refined-hazard-concrete-left'] = true,
|
||||
['refined-hazard-concrete-right'] = true,
|
||||
}
|
||||
|
||||
local function on_mined_tile(surface, tiles)
|
||||
local new_tiles = {}
|
||||
|
||||
for _, tile in pairs(tiles) do
|
||||
if (artificial_tiles[tile.old_tile.name]) then
|
||||
insert(new_tiles, { name = 'dirt-' .. random(1, 7), position = tile.position})
|
||||
end
|
||||
end
|
||||
|
||||
Template.insert(surface, new_tiles, {})
|
||||
end
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function DiggyHole.register(config)
|
||||
ScoreTable.reset('Void removed')
|
||||
|
||||
Event.add(defines.events.on_entity_died, function (event)
|
||||
diggy_hole(event.entity)
|
||||
end)
|
||||
|
||||
local enable_digging_warning = config.enable_digging_warning
|
||||
|
||||
Event.add(defines.events.on_player_mined_entity, function (event)
|
||||
local entity = event.entity
|
||||
local name = entity.name
|
||||
|
||||
if name == 'sand-rock-big' or name == 'rock-huge' then
|
||||
event.buffer.remove({name = 'coal', count = 100})
|
||||
|
||||
-- this logic can be replaced once we've fully replaced the stone to surface functionality
|
||||
if enable_digging_warning then
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
if player and player.valid then
|
||||
if player.get_main_inventory().can_insert({name = 'stone'}) then
|
||||
reset_player_full_inventory_cache(player)
|
||||
else
|
||||
trigger_inventory_warning(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
diggy_hole(entity)
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_robot_mined_tile, function (event)
|
||||
on_mined_tile(event.robot.surface, event.tiles)
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_player_mined_tile, function (event)
|
||||
on_mined_tile(game.surfaces[event.surface_index], event.tiles)
|
||||
end)
|
||||
|
||||
Event.add(Template.events.on_void_removed, function ()
|
||||
ScoreTable.increment('Void removed')
|
||||
end)
|
||||
|
||||
if config.enable_debug_commands then
|
||||
commands.add_command('clear-void', '<left top x> <left top y> <width> <height> <surface index> triggers Template.insert for the given area.', function(cmd)
|
||||
local params = {}
|
||||
local args = cmd.parameter or ''
|
||||
for param in string.gmatch(args, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
|
||||
if (#params ~= 5) then
|
||||
game.player.print('/clear-void requires exactly 5 arguments: <left top x> <left top y> <width> <height> <surface index>')
|
||||
return
|
||||
end
|
||||
|
||||
local left_top_x = tonumber(params[1])
|
||||
local left_top_y = tonumber(params[2])
|
||||
local width = tonumber(params[3])
|
||||
local height = tonumber(params[4])
|
||||
local surface_index = params[5]
|
||||
local tiles = {}
|
||||
local entities = {}
|
||||
|
||||
for x = 0, width do
|
||||
for y = 0, height do
|
||||
insert(tiles, {name = 'dirt-' .. random(1, 7), position = {x = x + left_top_x, y = y + left_top_y}})
|
||||
end
|
||||
end
|
||||
|
||||
Template.insert(game.surfaces[surface_index], tiles, entities)
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function DiggyHole.on_init()
|
||||
game.forces.player.technologies['landfill'].enabled = false
|
||||
end
|
||||
|
||||
return DiggyHole
|
||||
--[[-- info
|
||||
Provides the ability to "mine" through out-of-map tiles by destroying or
|
||||
mining rocks next to it.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Global = require 'utils.global'
|
||||
local Game = require 'utils.game'
|
||||
local Scanner = require 'map_gen.Diggy.Scanner'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local ScoreTable = require 'map_gen.Diggy.ScoreTable'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local insert = table.insert
|
||||
local random = math.random
|
||||
|
||||
-- todo remove this dependency
|
||||
local ResourceConfig = require 'map_gen.Diggy.Config'.features.ScatteredResources
|
||||
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Simplex = require 'map_gen.shared.simplex_noise'
|
||||
|
||||
-- this
|
||||
local DiggyHole = {}
|
||||
|
||||
-- keeps track of the amount of times per player when they mined with a full inventory in a row
|
||||
local full_inventory_mining_cache = {}
|
||||
|
||||
Global.register({
|
||||
full_inventory_mining_cache = full_inventory_mining_cache,
|
||||
}, function (tbl)
|
||||
full_inventory_mining_cache = tbl.full_inventory_mining_cache
|
||||
end)
|
||||
|
||||
local function reset_player_full_inventory_cache(player)
|
||||
if not full_inventory_mining_cache[player.index] then
|
||||
return
|
||||
end
|
||||
|
||||
full_inventory_mining_cache[player.index] = nil
|
||||
end
|
||||
|
||||
local full_inventory_message = 'Miner, you have a full inventory!\n\nMake sure to empty it before you continue digging.'
|
||||
|
||||
local function trigger_inventory_warning(player)
|
||||
local player_index = player.index
|
||||
local count = full_inventory_mining_cache[player_index]
|
||||
if not count then
|
||||
full_inventory_mining_cache[player_index] = 1
|
||||
player.print('## - ' .. full_inventory_message, {r = 1, g = 1, b = 0, a = 1})
|
||||
player.play_sound{path='utility/new_objective', volume_modifier = 1 }
|
||||
return
|
||||
end
|
||||
|
||||
full_inventory_mining_cache[player_index] = count + 1
|
||||
|
||||
if count % 5 == 0 then
|
||||
require 'features.gui.popup'.player(player, full_inventory_message)
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Triggers a diggy diggy hole for a given sand-rock-big or rock-huge.
|
||||
|
||||
Will return true even if the tile behind it is immune.
|
||||
|
||||
@param entity LuaEntity
|
||||
]]
|
||||
local function diggy_hole(entity)
|
||||
if ((entity.name ~= 'sand-rock-big') and (entity.name ~= 'rock-huge')) then
|
||||
return
|
||||
end
|
||||
|
||||
local tiles = {}
|
||||
local rocks = {}
|
||||
local surface = entity.surface
|
||||
local position = entity.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
|
||||
local out_of_map_found = Scanner.scan_around_position(surface, position, 'out-of-map');
|
||||
local distance = ResourceConfig.distance(x, y)
|
||||
|
||||
-- source of noise for resource generation
|
||||
-- index determines offset
|
||||
-- '-1' is reserved for cluster mode
|
||||
-- compound clusters use as many indexes as needed > 1
|
||||
local base_seed
|
||||
local function seeded_noise(surface, x, y, index, sources)
|
||||
base_seed = base_seed or surface.map_gen_settings.seed + surface.index + 4000
|
||||
local noise = 0
|
||||
for _, settings in ipairs(sources) do
|
||||
settings.type = settings.type or 'perlin'
|
||||
settings.offset = settings.offset or 0
|
||||
if settings.type == 'zero' then
|
||||
noise = noise + 0
|
||||
elseif settings.type == 'one' then
|
||||
noise = noise + settings.weight * 1
|
||||
elseif settings.type == 'perlin' then
|
||||
noise = noise + settings.weight * Perlin.noise(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
elseif settings.type == 'simplex' then
|
||||
noise = noise + settings.weight * Simplex.d2(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
else
|
||||
Debug.print('noise type \'' .. settings.type .. '\' not recognized')
|
||||
end
|
||||
|
||||
end
|
||||
return noise
|
||||
end
|
||||
|
||||
-- global config values
|
||||
local resource_richness_weights = ResourceConfig.resource_richness_weights
|
||||
local resource_richness_weights_sum = 0
|
||||
for _, weight in pairs(resource_richness_weights) do
|
||||
resource_richness_weights_sum = resource_richness_weights_sum + weight
|
||||
end
|
||||
|
||||
local s_resource_weights = ResourceConfig.scattered_resource_weights
|
||||
local s_resource_weights_sum = 0
|
||||
for _, weight in pairs(s_resource_weights) do
|
||||
s_resource_weights_sum = s_resource_weights_sum + weight
|
||||
end
|
||||
|
||||
-- compound cluster spawning
|
||||
local c_mode = ResourceConfig.cluster_mode
|
||||
-- local c_clusters = Config.features.ScatteredResources.clusters
|
||||
local c_clusters = require(ResourceConfig.cluster_file_location)
|
||||
if ('table' ~= type(c_clusters)) then
|
||||
error('cluster_file_location invalid')
|
||||
end
|
||||
|
||||
local c_count = 0
|
||||
for _, cluster in ipairs(c_clusters) do
|
||||
c_count = c_count + 1
|
||||
cluster.weights_sum = 0
|
||||
for _, weight in pairs(cluster.weights) do
|
||||
cluster.weights_sum = cluster.weights_sum + weight
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_cluster_resource(surface, x, y, cluster_index, cluster)
|
||||
for name, weight in pairs(cluster.weights) do
|
||||
if name == 'skip' then return false end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local huge_rock_inserted = false
|
||||
for _, position in pairs(out_of_map_found) do
|
||||
insert(tiles, {name = 'dirt-' .. random(1, 7), position = position})
|
||||
-- if (random() > 0.50) then
|
||||
-- insert(rocks, {name = 'rock-huge', position = position})
|
||||
|
||||
|
||||
if c_mode then
|
||||
for index,cluster in ipairs(c_clusters) do
|
||||
if distance >= cluster.min_distance and cluster.noise_settings.type ~= 'skip' then
|
||||
if cluster.noise_settings.type == "connected_tendril" then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if -1 * cluster.noise_settings.threshold < noise and noise < cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
elseif cluster.noise_settings.type == "fragmented_tendril" then
|
||||
local noise1 = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
local noise2 = seeded_noise(surface, x, y, index, cluster.noise_settings.discriminator)
|
||||
if -1 * cluster.noise_settings.threshold < noise1 and noise1 < cluster.noise_settings.threshold
|
||||
and -1 * cluster.noise_settings.discriminator_threshold < noise2
|
||||
and noise2 < cluster.noise_settings.discriminator_threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
else
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if noise >= cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
insert(rocks, {name = 'rock-huge', position = position})
|
||||
huge_rock_inserted = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (huge_rock_inserted == false) then
|
||||
insert(rocks, {name = 'sand-rock-big', position = position})
|
||||
end
|
||||
end
|
||||
|
||||
Template.insert(surface, tiles, rocks)
|
||||
end
|
||||
|
||||
local artificial_tiles = {
|
||||
['stone-brick'] = true,
|
||||
['stone-path'] = true,
|
||||
['concrete'] = true,
|
||||
['hazard-concrete-left'] = true,
|
||||
['hazard-concrete-right'] = true,
|
||||
['refined-concrete'] = true,
|
||||
['refined-hazard-concrete-left'] = true,
|
||||
['refined-hazard-concrete-right'] = true,
|
||||
}
|
||||
|
||||
local function on_mined_tile(surface, tiles)
|
||||
local new_tiles = {}
|
||||
|
||||
for _, tile in pairs(tiles) do
|
||||
if (artificial_tiles[tile.old_tile.name]) then
|
||||
insert(new_tiles, { name = 'dirt-' .. random(1, 7), position = tile.position})
|
||||
end
|
||||
end
|
||||
|
||||
Template.insert(surface, new_tiles, {})
|
||||
end
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function DiggyHole.register(config)
|
||||
ScoreTable.reset('Void removed')
|
||||
|
||||
Event.add(defines.events.on_entity_died, function (event)
|
||||
diggy_hole(event.entity)
|
||||
end)
|
||||
|
||||
local enable_digging_warning = config.enable_digging_warning
|
||||
|
||||
Event.add(defines.events.on_player_mined_entity, function (event)
|
||||
local entity = event.entity
|
||||
local name = entity.name
|
||||
|
||||
if name == 'sand-rock-big' or name == 'rock-huge' then
|
||||
event.buffer.remove({name = 'coal', count = 100})
|
||||
|
||||
-- this logic can be replaced once we've fully replaced the stone to surface functionality
|
||||
if enable_digging_warning then
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
if player and player.valid then
|
||||
if player.get_main_inventory().can_insert({name = 'stone'}) then
|
||||
reset_player_full_inventory_cache(player)
|
||||
else
|
||||
trigger_inventory_warning(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
diggy_hole(entity)
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_robot_mined_tile, function (event)
|
||||
on_mined_tile(event.robot.surface, event.tiles)
|
||||
end)
|
||||
|
||||
Event.add(defines.events.on_player_mined_tile, function (event)
|
||||
on_mined_tile(game.surfaces[event.surface_index], event.tiles)
|
||||
end)
|
||||
|
||||
Event.add(Template.events.on_void_removed, function ()
|
||||
ScoreTable.increment('Void removed')
|
||||
end)
|
||||
|
||||
if config.enable_debug_commands then
|
||||
commands.add_command('clear-void', '<left top x> <left top y> <width> <height> <surface index> triggers Template.insert for the given area.', function(cmd)
|
||||
local params = {}
|
||||
local args = cmd.parameter or ''
|
||||
for param in string.gmatch(args, '%S+') do
|
||||
table.insert(params, param)
|
||||
end
|
||||
|
||||
if (#params ~= 5) then
|
||||
game.player.print('/clear-void requires exactly 5 arguments: <left top x> <left top y> <width> <height> <surface index>')
|
||||
return
|
||||
end
|
||||
|
||||
local left_top_x = tonumber(params[1])
|
||||
local left_top_y = tonumber(params[2])
|
||||
local width = tonumber(params[3])
|
||||
local height = tonumber(params[4])
|
||||
local surface_index = params[5]
|
||||
local tiles = {}
|
||||
local entities = {}
|
||||
|
||||
for x = 0, width do
|
||||
for y = 0, height do
|
||||
insert(tiles, {name = 'dirt-' .. random(1, 7), position = {x = x + left_top_x, y = y + left_top_y}})
|
||||
end
|
||||
end
|
||||
|
||||
Template.insert(game.surfaces[surface_index], tiles, entities)
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function DiggyHole.on_init()
|
||||
game.forces.player.technologies['landfill'].enabled = false
|
||||
end
|
||||
|
||||
return DiggyHole
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,40 +1,40 @@
|
||||
--[[-- info
|
||||
Provides the ability to refresh the map and generate darkness.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local insert = table.insert
|
||||
|
||||
-- this
|
||||
local RefreshMap = {}
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function RefreshMap.register(config)
|
||||
Event.add(defines.events.on_chunk_generated, function (event)
|
||||
local tiles = {}
|
||||
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local target_x = event.area.left_top.x + x
|
||||
local target_y = event.area.left_top.y + y
|
||||
local tile = 'out-of-map'
|
||||
|
||||
if (target_x < 1 and target_y < 1 and target_x > -2 and target_y > -2) then
|
||||
tile = 'lab-dark-1'
|
||||
end
|
||||
|
||||
insert(tiles, {
|
||||
name = tile,
|
||||
position = {x = target_x, y = target_y}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
event.surface.set_tiles(tiles)
|
||||
end)
|
||||
end
|
||||
|
||||
return RefreshMap
|
||||
--[[-- info
|
||||
Provides the ability to refresh the map and generate darkness.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local insert = table.insert
|
||||
|
||||
-- this
|
||||
local RefreshMap = {}
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function RefreshMap.register(config)
|
||||
Event.add(defines.events.on_chunk_generated, function (event)
|
||||
local tiles = {}
|
||||
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local target_x = event.area.left_top.x + x
|
||||
local target_y = event.area.left_top.y + y
|
||||
local tile = 'out-of-map'
|
||||
|
||||
if (target_x < 1 and target_y < 1 and target_x > -2 and target_y > -2) then
|
||||
tile = 'lab-dark-1'
|
||||
end
|
||||
|
||||
insert(tiles, {
|
||||
name = tile,
|
||||
position = {x = target_x, y = target_y}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
event.surface.set_tiles(tiles)
|
||||
end)
|
||||
end
|
||||
|
||||
return RefreshMap
|
||||
|
@ -1,262 +1,262 @@
|
||||
--[[-- info
|
||||
Provides the ability to spawn random ores all over the place.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Simplex = require 'map_gen.shared.simplex_noise'
|
||||
local random = math.random
|
||||
local sqrt = math.sqrt
|
||||
local ceil = math.ceil
|
||||
local floor = math.floor
|
||||
|
||||
-- this
|
||||
local ScatteredResources = {}
|
||||
|
||||
local function get_name_by_weight(collection, sum)
|
||||
local pre_calculated = random()
|
||||
local current = 0
|
||||
local target = pre_calculated * sum
|
||||
|
||||
for name, weight in pairs(collection) do
|
||||
current = current + weight
|
||||
if (current >= target) then
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
Debug.print('Current \'' .. current .. '\' should be higher or equal to random \'' .. target .. '\'')
|
||||
end
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function ScatteredResources.register(config)
|
||||
|
||||
-- source of noise for resource generation
|
||||
-- index determines offset
|
||||
-- '-1' is reserved for cluster mode
|
||||
-- compound clusters use as many indexes as needed > 1
|
||||
local base_seed
|
||||
local function seeded_noise(surface, x, y, index, sources)
|
||||
base_seed = base_seed or surface.map_gen_settings.seed + surface.index + 4000
|
||||
local noise = 0
|
||||
for _, settings in ipairs(sources) do
|
||||
settings.type = settings.type or 'perlin'
|
||||
settings.offset = settings.offset or 0
|
||||
if settings.type == 'zero' then
|
||||
noise = noise + 0
|
||||
elseif settings.type == 'one' then
|
||||
noise = noise + settings.weight * 1
|
||||
elseif settings.type == 'perlin' then
|
||||
noise = noise + settings.weight * Perlin.noise(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
elseif settings.type == 'simplex' then
|
||||
noise = noise + settings.weight * Simplex.d2(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
else
|
||||
Debug.print('noise type \'' .. settings.type .. '\' not recognized')
|
||||
end
|
||||
|
||||
end
|
||||
return noise
|
||||
end
|
||||
|
||||
-- global config values
|
||||
|
||||
local resource_richness_weights = config.resource_richness_weights
|
||||
local resource_richness_weights_sum = 0
|
||||
for _, weight in pairs(resource_richness_weights) do
|
||||
resource_richness_weights_sum = resource_richness_weights_sum + weight
|
||||
end
|
||||
local resource_richness_values = config.resource_richness_values
|
||||
local resource_type_scalar = config.resource_type_scalar
|
||||
|
||||
-- scattered config values
|
||||
local s_mode = config.scattered_mode
|
||||
local s_dist_mod = config.scattered_distance_probability_modifier
|
||||
local s_min_prob = config.scattered_min_probability
|
||||
local s_max_prob = config.scattered_max_probability
|
||||
local s_dist_richness = config.scattered_distance_richness_modifier
|
||||
local s_cluster_prob = config.scattered_cluster_probability_multiplier
|
||||
local s_cluster_mult = config.scattered_cluster_yield_multiplier
|
||||
|
||||
local s_resource_weights = config.scattered_resource_weights
|
||||
local s_resource_weights_sum = 0
|
||||
for _, weight in pairs(s_resource_weights) do
|
||||
s_resource_weights_sum = s_resource_weights_sum + weight
|
||||
end
|
||||
local s_min_dist = config.scattered_minimum_resource_distance
|
||||
|
||||
-- cluster config values
|
||||
local cluster_mode = config.cluster_mode
|
||||
|
||||
-- compound cluster spawning
|
||||
local c_mode = config.cluster_mode
|
||||
local c_clusters = require(config.cluster_file_location)
|
||||
if ('table' ~= type(c_clusters)) then
|
||||
error('cluster_file_location invalid')
|
||||
end
|
||||
local c_count = 0
|
||||
for _, cluster in ipairs(c_clusters) do
|
||||
c_count = c_count + 1
|
||||
cluster.weights_sum = 0
|
||||
-- ensure the cluster colors are valid otherwise it fails silently
|
||||
-- and breaks things elsewhere
|
||||
if cluster.color then
|
||||
local c = cluster.color
|
||||
if (not c.r) or (not c.g) or (not c.b) then
|
||||
cluster.color = nil
|
||||
elseif c.r < 0 or c.r > 1 or c.g < 0 or c.g > 1 or c.b < 0 or c.b > 1 then
|
||||
cluster.color = nil
|
||||
end
|
||||
end
|
||||
for _, weight in pairs(cluster.weights) do
|
||||
cluster.weights_sum = cluster.weights_sum + weight
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_cluster_resource(surface, x, y, cluster_index, cluster)
|
||||
local distance = sqrt(x * x + y * y)
|
||||
local resource_name = get_name_by_weight(cluster.weights, cluster.weights_sum)
|
||||
if resource_name == 'skip' then
|
||||
return false
|
||||
end
|
||||
if cluster.distances[resource_name] then
|
||||
if distance < cluster.distances[resource_name] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local range = resource_richness_values[get_name_by_weight(resource_richness_weights, resource_richness_weights_sum)]
|
||||
local amount = random(range[1], range[2])
|
||||
amount = amount * (1 + ((distance / cluster.distance_richness) * 0.01))
|
||||
amount = amount * cluster.yield
|
||||
|
||||
if resource_type_scalar[resource_name] then
|
||||
amount = amount * resource_type_scalar[resource_name]
|
||||
end
|
||||
|
||||
Template.resources(surface, {{name = resource_name, position = {x = x, y = y}, amount = ceil(amount)}})
|
||||
return true
|
||||
end
|
||||
|
||||
-- event registration
|
||||
Event.add(Template.events.on_void_removed, function (event)
|
||||
local position = event.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
local surface = event.surface
|
||||
|
||||
local distance = config.distance(x, y)
|
||||
|
||||
if c_mode then
|
||||
for index,cluster in ipairs(c_clusters) do
|
||||
if distance >= cluster.min_distance and cluster.noise_settings.type ~= 'skip' then
|
||||
if cluster.noise_settings.type == "connected_tendril" then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if -1 * cluster.noise_settings.threshold < noise and noise < cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
return -- resource spawned
|
||||
end
|
||||
end
|
||||
elseif cluster.noise_settings.type == "fragmented_tendril" then
|
||||
local noise1 = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
local noise2 = seeded_noise(surface, x, y, index, cluster.noise_settings.discriminator)
|
||||
if -1 * cluster.noise_settings.threshold < noise1 and noise1 < cluster.noise_settings.threshold
|
||||
and -1 * cluster.noise_settings.discriminator_threshold < noise2
|
||||
and noise2 < cluster.noise_settings.discriminator_threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
return -- resource spawned
|
||||
end
|
||||
end
|
||||
else
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if noise >= cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
return -- resource spawned
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if s_mode then
|
||||
local probability = math.min(s_max_prob, s_min_prob + 0.01 * (distance / s_dist_mod))
|
||||
|
||||
if (cluster_mode) then
|
||||
probability = probability * s_cluster_prob
|
||||
end
|
||||
|
||||
if (probability > random()) then
|
||||
-- spawn single resource point for scatter mode
|
||||
local resource_name = get_name_by_weight(s_resource_weights, s_resource_weights_sum)
|
||||
if resource_name == 'skip' or s_min_dist[resource_name] > distance then
|
||||
return
|
||||
end
|
||||
|
||||
local range = resource_richness_values[get_name_by_weight(resource_richness_weights, resource_richness_weights_sum)]
|
||||
local amount = random(range[1], range[2])
|
||||
amount = amount * (1 + ((distance / s_dist_richness) * 0.01))
|
||||
|
||||
if resource_type_scalar[resource_name] then
|
||||
amount = amount * resource_type_scalar[resource_name]
|
||||
end
|
||||
|
||||
if (cluster_mode) then
|
||||
amount = amount * s_cluster_mult
|
||||
end
|
||||
|
||||
Template.resources(surface, {{name = resource_name, position={x=x,y=y}, amount = ceil(amount)}})
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if (config.display_ore_clusters) then
|
||||
local color = {}
|
||||
Event.add(defines.events.on_chunk_generated, function (event)
|
||||
local surface = event.surface
|
||||
local area = event.area
|
||||
|
||||
for x = area.left_top.x, area.left_top.x + 31 do
|
||||
for y = area.left_top.y, area.left_top.y + 31 do
|
||||
for index,cluster in ipairs(c_clusters) do
|
||||
if cluster.noise_settings.type == "connected_tendril" then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if -1 * cluster.noise_settings.threshold < noise and noise < cluster.noise_settings.threshold then
|
||||
color[index] = color[index] or cluster.color or {r=random(), g=random(), b=random()}
|
||||
Debug.print_colored_grid_value('o' .. index, surface, {x = x, y = y}, nil, nil, true, 0, color[index])
|
||||
end
|
||||
elseif cluster.noise_settings.type == "fragmented_tendril" then
|
||||
local noise1 = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
local noise2 = seeded_noise(surface, x, y, index, cluster.noise_settings.discriminator)
|
||||
if -1 * cluster.noise_settings.threshold < noise1 and noise1 < cluster.noise_settings.threshold
|
||||
and -1 * cluster.noise_settings.discriminator_threshold < noise2
|
||||
and noise2 < cluster.noise_settings.discriminator_threshold then
|
||||
color[index] = color[index] or cluster.color or {r=random(), g=random(), b=random()}
|
||||
Debug.print_colored_grid_value('o' .. index, surface, {x = x, y = y}, nil, nil, true, 0, color[index])
|
||||
end
|
||||
elseif cluster.noise_settings.type ~= 'skip' then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if noise >= cluster.noise_settings.threshold then
|
||||
color[index] = color[index] or cluster.color or {r=random(), g=random(), b=random()}
|
||||
Debug.print_colored_grid_value('o' .. index, surface, {x = x, y = y}, nil, nil, true, 0, color[index])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ScatteredResources.get_extra_map_info(config)
|
||||
return [[Scattered Resources, resources are everywhere!
|
||||
Scans of the mine have shown greater amounts of resources to be deeper in the mine]]
|
||||
end
|
||||
|
||||
return ScatteredResources
|
||||
--[[-- info
|
||||
Provides the ability to spawn random ores all over the place.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Simplex = require 'map_gen.shared.simplex_noise'
|
||||
local random = math.random
|
||||
local sqrt = math.sqrt
|
||||
local ceil = math.ceil
|
||||
local floor = math.floor
|
||||
|
||||
-- this
|
||||
local ScatteredResources = {}
|
||||
|
||||
local function get_name_by_weight(collection, sum)
|
||||
local pre_calculated = random()
|
||||
local current = 0
|
||||
local target = pre_calculated * sum
|
||||
|
||||
for name, weight in pairs(collection) do
|
||||
current = current + weight
|
||||
if (current >= target) then
|
||||
return name
|
||||
end
|
||||
end
|
||||
|
||||
Debug.print('Current \'' .. current .. '\' should be higher or equal to random \'' .. target .. '\'')
|
||||
end
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function ScatteredResources.register(config)
|
||||
|
||||
-- source of noise for resource generation
|
||||
-- index determines offset
|
||||
-- '-1' is reserved for cluster mode
|
||||
-- compound clusters use as many indexes as needed > 1
|
||||
local base_seed
|
||||
local function seeded_noise(surface, x, y, index, sources)
|
||||
base_seed = base_seed or surface.map_gen_settings.seed + surface.index + 4000
|
||||
local noise = 0
|
||||
for _, settings in ipairs(sources) do
|
||||
settings.type = settings.type or 'perlin'
|
||||
settings.offset = settings.offset or 0
|
||||
if settings.type == 'zero' then
|
||||
noise = noise + 0
|
||||
elseif settings.type == 'one' then
|
||||
noise = noise + settings.weight * 1
|
||||
elseif settings.type == 'perlin' then
|
||||
noise = noise + settings.weight * Perlin.noise(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
elseif settings.type == 'simplex' then
|
||||
noise = noise + settings.weight * Simplex.d2(x/settings.variance, y/settings.variance,
|
||||
base_seed + 2000*index + settings.offset)
|
||||
else
|
||||
Debug.print('noise type \'' .. settings.type .. '\' not recognized')
|
||||
end
|
||||
|
||||
end
|
||||
return noise
|
||||
end
|
||||
|
||||
-- global config values
|
||||
|
||||
local resource_richness_weights = config.resource_richness_weights
|
||||
local resource_richness_weights_sum = 0
|
||||
for _, weight in pairs(resource_richness_weights) do
|
||||
resource_richness_weights_sum = resource_richness_weights_sum + weight
|
||||
end
|
||||
local resource_richness_values = config.resource_richness_values
|
||||
local resource_type_scalar = config.resource_type_scalar
|
||||
|
||||
-- scattered config values
|
||||
local s_mode = config.scattered_mode
|
||||
local s_dist_mod = config.scattered_distance_probability_modifier
|
||||
local s_min_prob = config.scattered_min_probability
|
||||
local s_max_prob = config.scattered_max_probability
|
||||
local s_dist_richness = config.scattered_distance_richness_modifier
|
||||
local s_cluster_prob = config.scattered_cluster_probability_multiplier
|
||||
local s_cluster_mult = config.scattered_cluster_yield_multiplier
|
||||
|
||||
local s_resource_weights = config.scattered_resource_weights
|
||||
local s_resource_weights_sum = 0
|
||||
for _, weight in pairs(s_resource_weights) do
|
||||
s_resource_weights_sum = s_resource_weights_sum + weight
|
||||
end
|
||||
local s_min_dist = config.scattered_minimum_resource_distance
|
||||
|
||||
-- cluster config values
|
||||
local cluster_mode = config.cluster_mode
|
||||
|
||||
-- compound cluster spawning
|
||||
local c_mode = config.cluster_mode
|
||||
local c_clusters = require(config.cluster_file_location)
|
||||
if ('table' ~= type(c_clusters)) then
|
||||
error('cluster_file_location invalid')
|
||||
end
|
||||
local c_count = 0
|
||||
for _, cluster in ipairs(c_clusters) do
|
||||
c_count = c_count + 1
|
||||
cluster.weights_sum = 0
|
||||
-- ensure the cluster colors are valid otherwise it fails silently
|
||||
-- and breaks things elsewhere
|
||||
if cluster.color then
|
||||
local c = cluster.color
|
||||
if (not c.r) or (not c.g) or (not c.b) then
|
||||
cluster.color = nil
|
||||
elseif c.r < 0 or c.r > 1 or c.g < 0 or c.g > 1 or c.b < 0 or c.b > 1 then
|
||||
cluster.color = nil
|
||||
end
|
||||
end
|
||||
for _, weight in pairs(cluster.weights) do
|
||||
cluster.weights_sum = cluster.weights_sum + weight
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_cluster_resource(surface, x, y, cluster_index, cluster)
|
||||
local distance = sqrt(x * x + y * y)
|
||||
local resource_name = get_name_by_weight(cluster.weights, cluster.weights_sum)
|
||||
if resource_name == 'skip' then
|
||||
return false
|
||||
end
|
||||
if cluster.distances[resource_name] then
|
||||
if distance < cluster.distances[resource_name] then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local range = resource_richness_values[get_name_by_weight(resource_richness_weights, resource_richness_weights_sum)]
|
||||
local amount = random(range[1], range[2])
|
||||
amount = amount * (1 + ((distance / cluster.distance_richness) * 0.01))
|
||||
amount = amount * cluster.yield
|
||||
|
||||
if resource_type_scalar[resource_name] then
|
||||
amount = amount * resource_type_scalar[resource_name]
|
||||
end
|
||||
|
||||
Template.resources(surface, {{name = resource_name, position = {x = x, y = y}, amount = ceil(amount)}})
|
||||
return true
|
||||
end
|
||||
|
||||
-- event registration
|
||||
Event.add(Template.events.on_void_removed, function (event)
|
||||
local position = event.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
local surface = event.surface
|
||||
|
||||
local distance = config.distance(x, y)
|
||||
|
||||
if c_mode then
|
||||
for index,cluster in ipairs(c_clusters) do
|
||||
if distance >= cluster.min_distance and cluster.noise_settings.type ~= 'skip' then
|
||||
if cluster.noise_settings.type == "connected_tendril" then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if -1 * cluster.noise_settings.threshold < noise and noise < cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
return -- resource spawned
|
||||
end
|
||||
end
|
||||
elseif cluster.noise_settings.type == "fragmented_tendril" then
|
||||
local noise1 = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
local noise2 = seeded_noise(surface, x, y, index, cluster.noise_settings.discriminator)
|
||||
if -1 * cluster.noise_settings.threshold < noise1 and noise1 < cluster.noise_settings.threshold
|
||||
and -1 * cluster.noise_settings.discriminator_threshold < noise2
|
||||
and noise2 < cluster.noise_settings.discriminator_threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
return -- resource spawned
|
||||
end
|
||||
end
|
||||
else
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if noise >= cluster.noise_settings.threshold then
|
||||
if spawn_cluster_resource(surface, x, y, index, cluster) then
|
||||
return -- resource spawned
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if s_mode then
|
||||
local probability = math.min(s_max_prob, s_min_prob + 0.01 * (distance / s_dist_mod))
|
||||
|
||||
if (cluster_mode) then
|
||||
probability = probability * s_cluster_prob
|
||||
end
|
||||
|
||||
if (probability > random()) then
|
||||
-- spawn single resource point for scatter mode
|
||||
local resource_name = get_name_by_weight(s_resource_weights, s_resource_weights_sum)
|
||||
if resource_name == 'skip' or s_min_dist[resource_name] > distance then
|
||||
return
|
||||
end
|
||||
|
||||
local range = resource_richness_values[get_name_by_weight(resource_richness_weights, resource_richness_weights_sum)]
|
||||
local amount = random(range[1], range[2])
|
||||
amount = amount * (1 + ((distance / s_dist_richness) * 0.01))
|
||||
|
||||
if resource_type_scalar[resource_name] then
|
||||
amount = amount * resource_type_scalar[resource_name]
|
||||
end
|
||||
|
||||
if (cluster_mode) then
|
||||
amount = amount * s_cluster_mult
|
||||
end
|
||||
|
||||
Template.resources(surface, {{name = resource_name, position={x=x,y=y}, amount = ceil(amount)}})
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if (config.display_ore_clusters) then
|
||||
local color = {}
|
||||
Event.add(defines.events.on_chunk_generated, function (event)
|
||||
local surface = event.surface
|
||||
local area = event.area
|
||||
|
||||
for x = area.left_top.x, area.left_top.x + 31 do
|
||||
for y = area.left_top.y, area.left_top.y + 31 do
|
||||
for index,cluster in ipairs(c_clusters) do
|
||||
if cluster.noise_settings.type == "connected_tendril" then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if -1 * cluster.noise_settings.threshold < noise and noise < cluster.noise_settings.threshold then
|
||||
color[index] = color[index] or cluster.color or {r=random(), g=random(), b=random()}
|
||||
Debug.print_colored_grid_value('o' .. index, surface, {x = x, y = y}, nil, nil, true, 0, color[index])
|
||||
end
|
||||
elseif cluster.noise_settings.type == "fragmented_tendril" then
|
||||
local noise1 = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
local noise2 = seeded_noise(surface, x, y, index, cluster.noise_settings.discriminator)
|
||||
if -1 * cluster.noise_settings.threshold < noise1 and noise1 < cluster.noise_settings.threshold
|
||||
and -1 * cluster.noise_settings.discriminator_threshold < noise2
|
||||
and noise2 < cluster.noise_settings.discriminator_threshold then
|
||||
color[index] = color[index] or cluster.color or {r=random(), g=random(), b=random()}
|
||||
Debug.print_colored_grid_value('o' .. index, surface, {x = x, y = y}, nil, nil, true, 0, color[index])
|
||||
end
|
||||
elseif cluster.noise_settings.type ~= 'skip' then
|
||||
local noise = seeded_noise(surface, x, y, index, cluster.noise_settings.sources)
|
||||
if noise >= cluster.noise_settings.threshold then
|
||||
color[index] = color[index] or cluster.color or {r=random(), g=random(), b=random()}
|
||||
Debug.print_colored_grid_value('o' .. index, surface, {x = x, y = y}, nil, nil, true, 0, color[index])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function ScatteredResources.get_extra_map_info(config)
|
||||
return [[Scattered Resources, resources are everywhere!
|
||||
Scans of the mine have shown greater amounts of resources to be deeper in the mine]]
|
||||
end
|
||||
|
||||
return ScatteredResources
|
||||
|
@ -1,53 +1,53 @@
|
||||
--[[-- info
|
||||
Provides the ability to setup a player when first joined.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Game = require 'utils.game'
|
||||
|
||||
-- this
|
||||
local SetupPlayer = {}
|
||||
|
||||
global.SetupPlayer = {
|
||||
first_player_spawned = false,
|
||||
}
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function SetupPlayer.register(config)
|
||||
Event.add(defines.events.on_player_created, function (event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
local player_insert = player.insert
|
||||
local position = {0, 0}
|
||||
local surface = player.surface
|
||||
|
||||
for _, item in pairs(config.starting_items) do
|
||||
player_insert(item)
|
||||
end
|
||||
|
||||
if (global.SetupPlayer.first_player_spawned) then
|
||||
position = surface.find_non_colliding_position('player', position, 3, 0.1)
|
||||
else
|
||||
global.SetupPlayer.first_player_spawned = true
|
||||
end
|
||||
|
||||
player.force.set_spawn_position(position, surface)
|
||||
player.teleport(position)
|
||||
|
||||
Debug.cheat(function()
|
||||
local cheats = config.cheats
|
||||
player.force.manual_mining_speed_modifier = cheats.manual_mining_speed_modifier
|
||||
player.force.character_inventory_slots_bonus = cheats.character_inventory_slots_bonus
|
||||
player.force.character_running_speed_modifier = cheats.character_running_speed_modifier
|
||||
|
||||
for _, item in pairs(cheats.starting_items) do
|
||||
player_insert(item)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
return SetupPlayer
|
||||
--[[-- info
|
||||
Provides the ability to setup a player when first joined.
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local Game = require 'utils.game'
|
||||
|
||||
-- this
|
||||
local SetupPlayer = {}
|
||||
|
||||
global.SetupPlayer = {
|
||||
first_player_spawned = false,
|
||||
}
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function SetupPlayer.register(config)
|
||||
Event.add(defines.events.on_player_created, function (event)
|
||||
local player = Game.get_player_by_index(event.player_index)
|
||||
local player_insert = player.insert
|
||||
local position = {0, 0}
|
||||
local surface = player.surface
|
||||
|
||||
for _, item in pairs(config.starting_items) do
|
||||
player_insert(item)
|
||||
end
|
||||
|
||||
if (global.SetupPlayer.first_player_spawned) then
|
||||
position = surface.find_non_colliding_position('player', position, 3, 0.1)
|
||||
else
|
||||
global.SetupPlayer.first_player_spawned = true
|
||||
end
|
||||
|
||||
player.force.set_spawn_position(position, surface)
|
||||
player.teleport(position)
|
||||
|
||||
Debug.cheat(function()
|
||||
local cheats = config.cheats
|
||||
player.force.manual_mining_speed_modifier = cheats.manual_mining_speed_modifier
|
||||
player.force.character_inventory_slots_bonus = cheats.character_inventory_slots_bonus
|
||||
player.force.character_running_speed_modifier = cheats.character_running_speed_modifier
|
||||
|
||||
for _, item in pairs(cheats.starting_items) do
|
||||
player_insert(item)
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
return SetupPlayer
|
||||
|
@ -1,108 +1,108 @@
|
||||
--[[-- info
|
||||
Provides the ability to make a simple room with contents
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Event = require 'utils.event'
|
||||
local Debug = require'map_gen.Diggy.Debug'
|
||||
local Task = require 'utils.Task'
|
||||
local Token = require 'utils.global_token'
|
||||
local raise_event = script.raise_event
|
||||
|
||||
-- this
|
||||
local SimpleRoomGenerator = {}
|
||||
|
||||
local do_spawn_tile = Token.register(function(params)
|
||||
Template.insert(params.surface, {params.tile}, {})
|
||||
end)
|
||||
|
||||
local do_mine = Token.register(function(params)
|
||||
local surface = params.surface
|
||||
local position = params.position
|
||||
local rocks = surface.find_entities_filtered({ position = position, name = { 'sand-rock-big', 'rock-huge'}})
|
||||
|
||||
if (0 == #rocks) then
|
||||
return
|
||||
end
|
||||
|
||||
for _, rock in pairs(rocks) do
|
||||
raise_event(defines.events.on_entity_died, {entity = rock})
|
||||
rock.destroy()
|
||||
end
|
||||
end)
|
||||
|
||||
local function handle_noise(name, surface, position)
|
||||
Task.set_timeout_in_ticks(1, do_mine, {surface = surface, position = position})
|
||||
|
||||
if ('water' == name) then
|
||||
-- water is slower because for some odd reason it doesn't always want to mine it properly
|
||||
Task.set_timeout_in_ticks(4, do_spawn_tile, { surface = surface, tile = { name = 'deepwater-green', position = position}})
|
||||
return
|
||||
end
|
||||
|
||||
if ('dirt' == name) then
|
||||
return
|
||||
end
|
||||
|
||||
error('No noise handled for type \'' .. name .. '\'')
|
||||
end
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function SimpleRoomGenerator.register(config)
|
||||
local room_noise_minimum_distance_sq = config.room_noise_minimum_distance * config.room_noise_minimum_distance
|
||||
|
||||
local seed
|
||||
local function get_noise(surface, x, y)
|
||||
seed = seed or surface.map_gen_settings.seed + surface.index + 100
|
||||
return Perlin.noise(x * config.noise_variance, y * config.noise_variance, seed)
|
||||
end
|
||||
|
||||
Event.add(Template.events.on_void_removed, function (event)
|
||||
local position = event.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
|
||||
local distance_sq = x * x + y * y
|
||||
|
||||
if (distance_sq <= room_noise_minimum_distance_sq) then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = event.surface
|
||||
local noise = get_noise(surface, x, y)
|
||||
|
||||
for _, noise_range in pairs(config.room_noise_ranges) do
|
||||
if (noise >= noise_range.min and noise <= noise_range.max) then
|
||||
handle_noise(noise_range.name, surface, position)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if (config.display_room_locations) then
|
||||
Event.add(defines.events.on_chunk_generated, function (event)
|
||||
local surface = event.surface
|
||||
local area = event.area
|
||||
|
||||
for x = area.left_top.x, area.left_top.x + 31 do
|
||||
for y = area.left_top.y, area.left_top.y + 31 do
|
||||
for _, noise_range in pairs(config.room_noise_ranges) do
|
||||
local noise = get_noise(surface, x, y)
|
||||
if (noise >= noise_range.min and noise <= noise_range.max) then
|
||||
Debug.print_grid_value(noise_range.name, surface, {x = x, y = y}, nil, nil, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function SimpleRoomGenerator.get_extra_map_info(config)
|
||||
return 'Simple Room Generator, digging around might open rooms!'
|
||||
end
|
||||
|
||||
return SimpleRoomGenerator
|
||||
--[[-- info
|
||||
Provides the ability to make a simple room with contents
|
||||
]]
|
||||
|
||||
-- dependencies
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local Perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Event = require 'utils.event'
|
||||
local Debug = require'map_gen.Diggy.Debug'
|
||||
local Task = require 'utils.Task'
|
||||
local Token = require 'utils.global_token'
|
||||
local raise_event = script.raise_event
|
||||
|
||||
-- this
|
||||
local SimpleRoomGenerator = {}
|
||||
|
||||
local do_spawn_tile = Token.register(function(params)
|
||||
Template.insert(params.surface, {params.tile}, {})
|
||||
end)
|
||||
|
||||
local do_mine = Token.register(function(params)
|
||||
local surface = params.surface
|
||||
local position = params.position
|
||||
local rocks = surface.find_entities_filtered({ position = position, name = { 'sand-rock-big', 'rock-huge'}})
|
||||
|
||||
if (0 == #rocks) then
|
||||
return
|
||||
end
|
||||
|
||||
for _, rock in pairs(rocks) do
|
||||
raise_event(defines.events.on_entity_died, {entity = rock})
|
||||
rock.destroy()
|
||||
end
|
||||
end)
|
||||
|
||||
local function handle_noise(name, surface, position)
|
||||
Task.set_timeout_in_ticks(1, do_mine, {surface = surface, position = position})
|
||||
|
||||
if ('water' == name) then
|
||||
-- water is slower because for some odd reason it doesn't always want to mine it properly
|
||||
Task.set_timeout_in_ticks(4, do_spawn_tile, { surface = surface, tile = { name = 'deepwater-green', position = position}})
|
||||
return
|
||||
end
|
||||
|
||||
if ('dirt' == name) then
|
||||
return
|
||||
end
|
||||
|
||||
error('No noise handled for type \'' .. name .. '\'')
|
||||
end
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function SimpleRoomGenerator.register(config)
|
||||
local room_noise_minimum_distance_sq = config.room_noise_minimum_distance * config.room_noise_minimum_distance
|
||||
|
||||
local seed
|
||||
local function get_noise(surface, x, y)
|
||||
seed = seed or surface.map_gen_settings.seed + surface.index + 100
|
||||
return Perlin.noise(x * config.noise_variance, y * config.noise_variance, seed)
|
||||
end
|
||||
|
||||
Event.add(Template.events.on_void_removed, function (event)
|
||||
local position = event.position
|
||||
local x = position.x
|
||||
local y = position.y
|
||||
|
||||
local distance_sq = x * x + y * y
|
||||
|
||||
if (distance_sq <= room_noise_minimum_distance_sq) then
|
||||
return
|
||||
end
|
||||
|
||||
local surface = event.surface
|
||||
local noise = get_noise(surface, x, y)
|
||||
|
||||
for _, noise_range in pairs(config.room_noise_ranges) do
|
||||
if (noise >= noise_range.min and noise <= noise_range.max) then
|
||||
handle_noise(noise_range.name, surface, position)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if (config.display_room_locations) then
|
||||
Event.add(defines.events.on_chunk_generated, function (event)
|
||||
local surface = event.surface
|
||||
local area = event.area
|
||||
|
||||
for x = area.left_top.x, area.left_top.x + 31 do
|
||||
for y = area.left_top.y, area.left_top.y + 31 do
|
||||
for _, noise_range in pairs(config.room_noise_ranges) do
|
||||
local noise = get_noise(surface, x, y)
|
||||
if (noise >= noise_range.min and noise <= noise_range.max) then
|
||||
Debug.print_grid_value(noise_range.name, surface, {x = x, y = y}, nil, nil, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function SimpleRoomGenerator.get_extra_map_info(config)
|
||||
return 'Simple Room Generator, digging around might open rooms!'
|
||||
end
|
||||
|
||||
return SimpleRoomGenerator
|
||||
|
@ -1,81 +1,81 @@
|
||||
--[[-- info
|
||||
Provides the ability to create a pre-configured starting zone.
|
||||
]]
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Token = require 'utils.global_token'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local DiggyCaveCollapse = require 'map_gen.Diggy.Feature.DiggyCaveCollapse'
|
||||
local insert = table.insert
|
||||
local random = math.random
|
||||
local sqrt = math.sqrt
|
||||
local floor = math.floor
|
||||
|
||||
-- this
|
||||
local StartingZone = {}
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function StartingZone.register(config)
|
||||
local callback_token
|
||||
local starting_zone_size = config.starting_size
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
local start_point_area = {{-0.9, -0.9}, {0.9, 0.9}}
|
||||
local start_point_cleanup = {{-0.9, -0.9}, {1.9, 1.9}}
|
||||
local surface = event.surface
|
||||
|
||||
-- hack to figure out whether the important chunks are generated via Diggy.Feature.RefreshMap.
|
||||
if (4 ~= surface.count_tiles_filtered({start_point_area, name = 'lab-dark-1'})) then
|
||||
return
|
||||
end
|
||||
|
||||
-- ensure a clean starting point
|
||||
for _, entity in pairs(surface.find_entities_filtered({area = start_point_cleanup, type = 'resource'})) do
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
local tiles = {}
|
||||
local rocks = {}
|
||||
|
||||
local dirt_range = floor(starting_zone_size * 0.5)
|
||||
local rock_range = starting_zone_size - 2
|
||||
local stress_hack = floor(starting_zone_size * 0.1)
|
||||
|
||||
for x = -starting_zone_size, starting_zone_size do
|
||||
for y = -starting_zone_size, starting_zone_size do
|
||||
local distance = floor(sqrt(x * x + y * y))
|
||||
|
||||
if (distance < starting_zone_size) then
|
||||
if (distance > dirt_range) then
|
||||
insert(tiles, {name = 'dirt-' .. random(1, 7), position = {x = x, y = y}})
|
||||
else
|
||||
insert(tiles, {name = 'stone-path', position = {x = x, y = y}})
|
||||
end
|
||||
|
||||
if (distance > rock_range) then
|
||||
insert(rocks, {name = 'sand-rock-big', position = {x = x, y = y}})
|
||||
end
|
||||
|
||||
-- hack to avoid starting area from collapsing
|
||||
if (distance > stress_hack) then
|
||||
DiggyCaveCollapse.stress_map_add(surface, {x = x, y = y}, -0.5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Template.insert(event.surface, tiles, rocks)
|
||||
|
||||
Event.remove_removable(defines.events.on_chunk_generated, callback_token)
|
||||
end
|
||||
|
||||
callback_token = Token.register(on_chunk_generated)
|
||||
|
||||
Event.add_removable(defines.events.on_chunk_generated, callback_token)
|
||||
end
|
||||
|
||||
|
||||
return StartingZone
|
||||
--[[-- info
|
||||
Provides the ability to create a pre-configured starting zone.
|
||||
]]
|
||||
-- dependencies
|
||||
local Event = require 'utils.event'
|
||||
local Token = require 'utils.global_token'
|
||||
local Template = require 'map_gen.Diggy.Template'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local DiggyCaveCollapse = require 'map_gen.Diggy.Feature.DiggyCaveCollapse'
|
||||
local insert = table.insert
|
||||
local random = math.random
|
||||
local sqrt = math.sqrt
|
||||
local floor = math.floor
|
||||
|
||||
-- this
|
||||
local StartingZone = {}
|
||||
|
||||
--[[--
|
||||
Registers all event handlers.
|
||||
]]
|
||||
function StartingZone.register(config)
|
||||
local callback_token
|
||||
local starting_zone_size = config.starting_size
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
local start_point_area = {{-0.9, -0.9}, {0.9, 0.9}}
|
||||
local start_point_cleanup = {{-0.9, -0.9}, {1.9, 1.9}}
|
||||
local surface = event.surface
|
||||
|
||||
-- hack to figure out whether the important chunks are generated via Diggy.Feature.RefreshMap.
|
||||
if (4 ~= surface.count_tiles_filtered({start_point_area, name = 'lab-dark-1'})) then
|
||||
return
|
||||
end
|
||||
|
||||
-- ensure a clean starting point
|
||||
for _, entity in pairs(surface.find_entities_filtered({area = start_point_cleanup, type = 'resource'})) do
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
local tiles = {}
|
||||
local rocks = {}
|
||||
|
||||
local dirt_range = floor(starting_zone_size * 0.5)
|
||||
local rock_range = starting_zone_size - 2
|
||||
local stress_hack = floor(starting_zone_size * 0.1)
|
||||
|
||||
for x = -starting_zone_size, starting_zone_size do
|
||||
for y = -starting_zone_size, starting_zone_size do
|
||||
local distance = floor(sqrt(x * x + y * y))
|
||||
|
||||
if (distance < starting_zone_size) then
|
||||
if (distance > dirt_range) then
|
||||
insert(tiles, {name = 'dirt-' .. random(1, 7), position = {x = x, y = y}})
|
||||
else
|
||||
insert(tiles, {name = 'stone-path', position = {x = x, y = y}})
|
||||
end
|
||||
|
||||
if (distance > rock_range) then
|
||||
insert(rocks, {name = 'sand-rock-big', position = {x = x, y = y}})
|
||||
end
|
||||
|
||||
-- hack to avoid starting area from collapsing
|
||||
if (distance > stress_hack) then
|
||||
DiggyCaveCollapse.stress_map_add(surface, {x = x, y = y}, -0.5)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Template.insert(event.surface, tiles, rocks)
|
||||
|
||||
Event.remove_removable(defines.events.on_chunk_generated, callback_token)
|
||||
end
|
||||
|
||||
callback_token = Token.register(on_chunk_generated)
|
||||
|
||||
Event.add_removable(defines.events.on_chunk_generated, callback_token)
|
||||
end
|
||||
|
||||
|
||||
return StartingZone
|
||||
|
@ -1,3 +1,3 @@
|
||||
## RedMew - Diggy, Custom Scenario
|
||||
|
||||
The documentation for Diggy has moved to [docs/scenarios/Diggy.md](../../docs/scenarios/Diggy.md).
|
||||
## RedMew - Diggy, Custom Scenario
|
||||
|
||||
The documentation for Diggy has moved to [docs/scenarios/Diggy.md](../../docs/scenarios/Diggy.md).
|
||||
|
@ -1,42 +1,42 @@
|
||||
-- dependencies
|
||||
local insert = table.insert
|
||||
|
||||
-- this
|
||||
local Scanner = {}
|
||||
|
||||
--[[--
|
||||
returns a list with all direct positions that contain tile_search.
|
||||
|
||||
@param surface LuaSurface
|
||||
@param position Position
|
||||
@param tile_search string name of the tile to search for
|
||||
@return table with 0~4 directions of which have the tile searched for adjacent
|
||||
]]
|
||||
function Scanner.scan_around_position(surface, position, tile_search)
|
||||
local tile_found = {}
|
||||
local get_tile = surface.get_tile
|
||||
|
||||
-- north
|
||||
if (tile_search == get_tile(position.x, position.y - 1).name) then
|
||||
insert(tile_found, {x = position.x, y = position.y - 1})
|
||||
end
|
||||
|
||||
-- east
|
||||
if (tile_search == get_tile(position.x + 1, position.y).name) then
|
||||
insert(tile_found, {x = position.x + 1, y = position.y})
|
||||
end
|
||||
|
||||
-- south
|
||||
if (tile_search == get_tile(position.x, position.y + 1).name) then
|
||||
insert(tile_found, {x = position.x, y = position.y + 1})
|
||||
end
|
||||
|
||||
-- west
|
||||
if (tile_search == get_tile(position.x - 1, position.y).name) then
|
||||
insert(tile_found, {x = position.x - 1, y = position.y})
|
||||
end
|
||||
|
||||
return tile_found;
|
||||
end
|
||||
|
||||
return Scanner
|
||||
-- dependencies
|
||||
local insert = table.insert
|
||||
|
||||
-- this
|
||||
local Scanner = {}
|
||||
|
||||
--[[--
|
||||
returns a list with all direct positions that contain tile_search.
|
||||
|
||||
@param surface LuaSurface
|
||||
@param position Position
|
||||
@param tile_search string name of the tile to search for
|
||||
@return table with 0~4 directions of which have the tile searched for adjacent
|
||||
]]
|
||||
function Scanner.scan_around_position(surface, position, tile_search)
|
||||
local tile_found = {}
|
||||
local get_tile = surface.get_tile
|
||||
|
||||
-- north
|
||||
if (tile_search == get_tile(position.x, position.y - 1).name) then
|
||||
insert(tile_found, {x = position.x, y = position.y - 1})
|
||||
end
|
||||
|
||||
-- east
|
||||
if (tile_search == get_tile(position.x + 1, position.y).name) then
|
||||
insert(tile_found, {x = position.x + 1, y = position.y})
|
||||
end
|
||||
|
||||
-- south
|
||||
if (tile_search == get_tile(position.x, position.y + 1).name) then
|
||||
insert(tile_found, {x = position.x, y = position.y + 1})
|
||||
end
|
||||
|
||||
-- west
|
||||
if (tile_search == get_tile(position.x - 1, position.y).name) then
|
||||
insert(tile_found, {x = position.x - 1, y = position.y})
|
||||
end
|
||||
|
||||
return tile_found;
|
||||
end
|
||||
|
||||
return Scanner
|
||||
|
@ -1,96 +1,96 @@
|
||||
-- dependencies
|
||||
local Config = require 'map_gen.Diggy.Config'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local ScenarioInfo = require 'features.gui.info'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
require 'utils.list_utils'
|
||||
require 'utils.utils'
|
||||
|
||||
-- this
|
||||
local Scenario = {}
|
||||
|
||||
global.diggy_scenario_registered = false
|
||||
|
||||
--[[--
|
||||
Allows calling a callback for each enabled feature.
|
||||
|
||||
Signature: callback(feature_name, Table feature_data) from {@see Config.features}.
|
||||
|
||||
@param if_enabled function to be called if enabled
|
||||
]]
|
||||
local function each_enabled_feature(if_enabled)
|
||||
local type = type(if_enabled)
|
||||
if ('function' ~= type) then
|
||||
error('each_enabled_feature expects callback to be a function, given type: ' .. type)
|
||||
end
|
||||
|
||||
for current_name, feature_data in pairs(Config.features) do
|
||||
if (nil == feature_data.enabled) then
|
||||
error('Feature ' .. current_name .. ' did not define the enabled property.')
|
||||
end
|
||||
|
||||
if (feature_data.enabled) then
|
||||
if_enabled(current_name, feature_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Register the events required to initialize the scenario.
|
||||
]]
|
||||
function Scenario.register(debug)
|
||||
if global.diggy_scenario_registered then
|
||||
error('Cannot register the Diggy scenario multiple times.')
|
||||
return
|
||||
end
|
||||
|
||||
global.scenario.config.player_list.enable_coin_col = false
|
||||
if global.scenario.config then
|
||||
global.scenario.config.fish_market.enable = nil
|
||||
end
|
||||
|
||||
if ('boolean' == type(debug)) then
|
||||
Config.Debug = debug
|
||||
end
|
||||
|
||||
if (Config.debug) then
|
||||
Debug.enable_debug()
|
||||
end
|
||||
|
||||
if (Config.cheats) then
|
||||
Debug.enable_cheats()
|
||||
end
|
||||
|
||||
local extra_map_info = ''
|
||||
|
||||
each_enabled_feature(
|
||||
function(feature_name, feature_config)
|
||||
local feature = require ('map_gen.Diggy.Feature.' .. feature_name)
|
||||
if ('function' ~= type(feature.register)) then
|
||||
error('Feature ' .. feature_name .. ' did not define a register function.')
|
||||
end
|
||||
|
||||
feature.register(feature_config)
|
||||
|
||||
if ('function' == type(feature.get_extra_map_info)) then
|
||||
extra_map_info = extra_map_info .. feature.get_extra_map_info(feature_config) .. '\n\n'
|
||||
end
|
||||
|
||||
if ('function' == type(feature.on_init)) then
|
||||
Event.on_init(feature.on_init)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local landfill_tiles = {'dirt-1','dirt-2','dirt-3','dirt-4','dirt-5','dirt-6','dirt-7'}
|
||||
require ('map_gen.misc.change_landfill_tile')(landfill_tiles)
|
||||
|
||||
ScenarioInfo.set_map_name('Diggy')
|
||||
ScenarioInfo.set_map_description('Dig your way through!')
|
||||
ScenarioInfo.set_map_extra_info(extra_map_info)
|
||||
|
||||
global.diggy_scenario_registered = true
|
||||
end
|
||||
|
||||
return Scenario
|
||||
-- dependencies
|
||||
local Config = require 'map_gen.Diggy.Config'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local ScenarioInfo = require 'features.gui.info'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
require 'utils.list_utils'
|
||||
require 'utils.utils'
|
||||
|
||||
-- this
|
||||
local Scenario = {}
|
||||
|
||||
global.diggy_scenario_registered = false
|
||||
|
||||
--[[--
|
||||
Allows calling a callback for each enabled feature.
|
||||
|
||||
Signature: callback(feature_name, Table feature_data) from {@see Config.features}.
|
||||
|
||||
@param if_enabled function to be called if enabled
|
||||
]]
|
||||
local function each_enabled_feature(if_enabled)
|
||||
local type = type(if_enabled)
|
||||
if ('function' ~= type) then
|
||||
error('each_enabled_feature expects callback to be a function, given type: ' .. type)
|
||||
end
|
||||
|
||||
for current_name, feature_data in pairs(Config.features) do
|
||||
if (nil == feature_data.enabled) then
|
||||
error('Feature ' .. current_name .. ' did not define the enabled property.')
|
||||
end
|
||||
|
||||
if (feature_data.enabled) then
|
||||
if_enabled(current_name, feature_data)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Register the events required to initialize the scenario.
|
||||
]]
|
||||
function Scenario.register(debug)
|
||||
if global.diggy_scenario_registered then
|
||||
error('Cannot register the Diggy scenario multiple times.')
|
||||
return
|
||||
end
|
||||
|
||||
global.scenario.config.player_list.enable_coin_col = false
|
||||
if global.scenario.config then
|
||||
global.scenario.config.fish_market.enable = nil
|
||||
end
|
||||
|
||||
if ('boolean' == type(debug)) then
|
||||
Config.Debug = debug
|
||||
end
|
||||
|
||||
if (Config.debug) then
|
||||
Debug.enable_debug()
|
||||
end
|
||||
|
||||
if (Config.cheats) then
|
||||
Debug.enable_cheats()
|
||||
end
|
||||
|
||||
local extra_map_info = ''
|
||||
|
||||
each_enabled_feature(
|
||||
function(feature_name, feature_config)
|
||||
local feature = require ('map_gen.Diggy.Feature.' .. feature_name)
|
||||
if ('function' ~= type(feature.register)) then
|
||||
error('Feature ' .. feature_name .. ' did not define a register function.')
|
||||
end
|
||||
|
||||
feature.register(feature_config)
|
||||
|
||||
if ('function' == type(feature.get_extra_map_info)) then
|
||||
extra_map_info = extra_map_info .. feature.get_extra_map_info(feature_config) .. '\n\n'
|
||||
end
|
||||
|
||||
if ('function' == type(feature.on_init)) then
|
||||
Event.on_init(feature.on_init)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
local landfill_tiles = {'dirt-1','dirt-2','dirt-3','dirt-4','dirt-5','dirt-6','dirt-7'}
|
||||
require ('map_gen.misc.change_landfill_tile')(landfill_tiles)
|
||||
|
||||
ScenarioInfo.set_map_name('Diggy')
|
||||
ScenarioInfo.set_map_description('Dig your way through!')
|
||||
ScenarioInfo.set_map_extra_info(extra_map_info)
|
||||
|
||||
global.diggy_scenario_registered = true
|
||||
end
|
||||
|
||||
return Scenario
|
||||
|
@ -1,84 +1,84 @@
|
||||
-- dependencies
|
||||
local Global = require 'utils.global'
|
||||
|
||||
-- this
|
||||
local ScoreTable = {}
|
||||
|
||||
local scores = {}
|
||||
|
||||
Global.register({
|
||||
scores = scores,
|
||||
}, function (tbl)
|
||||
scores = tbl.scores
|
||||
end)
|
||||
|
||||
--[[--
|
||||
Resets the score 0 for the given name
|
||||
|
||||
@param name String
|
||||
]]
|
||||
function ScoreTable.reset(name)
|
||||
scores[name] = 0
|
||||
end
|
||||
|
||||
--[[--
|
||||
Adds score.
|
||||
|
||||
@param name String
|
||||
@param value int amount to add
|
||||
|
||||
@return int the sum for the score added by name
|
||||
]]
|
||||
function ScoreTable.add(name, value)
|
||||
local new = (scores[name] or 0) + value
|
||||
scores[name] = new
|
||||
return new
|
||||
end
|
||||
|
||||
--[[--
|
||||
Increments the score by 1 for name.
|
||||
|
||||
@param name String
|
||||
|
||||
@return int the sum for the score incremented by name
|
||||
]]
|
||||
function ScoreTable.increment(name)
|
||||
return ScoreTable.add(name, 1)
|
||||
end
|
||||
|
||||
--[[--
|
||||
Returns the score for a single key.
|
||||
|
||||
@param
|
||||
]]
|
||||
function ScoreTable.get(name)
|
||||
return scores[name] or 0
|
||||
end
|
||||
|
||||
--[[--
|
||||
Returns all scores.
|
||||
|
||||
@return table {[string] = int}
|
||||
]]
|
||||
function ScoreTable.all()
|
||||
return scores
|
||||
end
|
||||
|
||||
--[[--
|
||||
Returns all keys of table scores.
|
||||
|
||||
@return table {[string] = name of key}
|
||||
]]
|
||||
function ScoreTable.all_keys()
|
||||
local keyset = {}
|
||||
local n = 0
|
||||
|
||||
for k, v in pairs(scores) do
|
||||
n = n + 1
|
||||
keyset[n] = k
|
||||
end
|
||||
|
||||
return keyset
|
||||
end
|
||||
|
||||
return ScoreTable
|
||||
-- dependencies
|
||||
local Global = require 'utils.global'
|
||||
|
||||
-- this
|
||||
local ScoreTable = {}
|
||||
|
||||
local scores = {}
|
||||
|
||||
Global.register({
|
||||
scores = scores,
|
||||
}, function (tbl)
|
||||
scores = tbl.scores
|
||||
end)
|
||||
|
||||
--[[--
|
||||
Resets the score 0 for the given name
|
||||
|
||||
@param name String
|
||||
]]
|
||||
function ScoreTable.reset(name)
|
||||
scores[name] = 0
|
||||
end
|
||||
|
||||
--[[--
|
||||
Adds score.
|
||||
|
||||
@param name String
|
||||
@param value int amount to add
|
||||
|
||||
@return int the sum for the score added by name
|
||||
]]
|
||||
function ScoreTable.add(name, value)
|
||||
local new = (scores[name] or 0) + value
|
||||
scores[name] = new
|
||||
return new
|
||||
end
|
||||
|
||||
--[[--
|
||||
Increments the score by 1 for name.
|
||||
|
||||
@param name String
|
||||
|
||||
@return int the sum for the score incremented by name
|
||||
]]
|
||||
function ScoreTable.increment(name)
|
||||
return ScoreTable.add(name, 1)
|
||||
end
|
||||
|
||||
--[[--
|
||||
Returns the score for a single key.
|
||||
|
||||
@param
|
||||
]]
|
||||
function ScoreTable.get(name)
|
||||
return scores[name] or 0
|
||||
end
|
||||
|
||||
--[[--
|
||||
Returns all scores.
|
||||
|
||||
@return table {[string] = int}
|
||||
]]
|
||||
function ScoreTable.all()
|
||||
return scores
|
||||
end
|
||||
|
||||
--[[--
|
||||
Returns all keys of table scores.
|
||||
|
||||
@return table {[string] = name of key}
|
||||
]]
|
||||
function ScoreTable.all_keys()
|
||||
local keyset = {}
|
||||
local n = 0
|
||||
|
||||
for k, v in pairs(scores) do
|
||||
n = n + 1
|
||||
keyset[n] = k
|
||||
end
|
||||
|
||||
return keyset
|
||||
end
|
||||
|
||||
return ScoreTable
|
||||
|
@ -1,216 +1,216 @@
|
||||
-- dependencies
|
||||
local Task = require 'utils.Task'
|
||||
local Token = require 'utils.global_token'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local insert = table.insert
|
||||
local min = math.min
|
||||
local ceil = math.ceil
|
||||
local raise_event = script.raise_event
|
||||
|
||||
-- this
|
||||
local Template = {}
|
||||
|
||||
local tiles_per_call = 5 --how many tiles are inserted with each call of insert_action
|
||||
local entities_per_call = 5 --how many entities are inserted with each call of insert_action
|
||||
|
||||
Template.events = {
|
||||
--[[--
|
||||
When an entity is placed via the template function.
|
||||
- event.entity LuaEntity
|
||||
]]
|
||||
on_placed_entity = script.generate_event_name(),
|
||||
|
||||
--[[--
|
||||
Triggers when an 'out-of-map' tile is replaced by something else.
|
||||
|
||||
{surface, old_tile={name, position={x, y}}}
|
||||
]]
|
||||
on_void_removed = script.generate_event_name(),
|
||||
}
|
||||
|
||||
local function insert_next_tiles(data)
|
||||
local void_removed = {}
|
||||
local surface = data.surface
|
||||
local get_tile = surface.get_tile
|
||||
local tiles = {}
|
||||
|
||||
pcall(
|
||||
function()
|
||||
--use pcall to assure tile_iterator is always incremented, to avoid endless loops
|
||||
for i = data.tile_iterator, min(data.tile_iterator + tiles_per_call - 1, data.tiles_n) do
|
||||
local new_tile = data.tiles[i]
|
||||
insert(tiles, new_tile)
|
||||
local current_tile = get_tile(new_tile.position.x, new_tile.position.y)
|
||||
local current_is_void = current_tile.name == 'out-of-map'
|
||||
local new_is_void = new_tile.name == 'out-of-map'
|
||||
|
||||
if (current_is_void and not new_is_void) then
|
||||
insert(void_removed, {surface = surface, position = current_tile.position})
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
data.tile_iterator = data.tile_iterator + tiles_per_call
|
||||
|
||||
surface.set_tiles(tiles)
|
||||
|
||||
for _, event in pairs(void_removed) do
|
||||
raise_event(Template.events.on_void_removed, event)
|
||||
end
|
||||
end
|
||||
|
||||
local function insert_next_entities(data)
|
||||
local created_entities = {}
|
||||
local surface = data.surface
|
||||
local create_entity = surface.create_entity
|
||||
|
||||
pcall(
|
||||
function()
|
||||
--use pcall to assure tile_iterator is always incremented, to avoid endless loops
|
||||
for i = data.entity_iterator, min(data.entity_iterator + entities_per_call - 1, data.entities_n) do
|
||||
local entity = data.entities[i]
|
||||
local created_entity = create_entity(entity)
|
||||
if (nil == created_entity) then
|
||||
error('Failed creating entity ' .. entity.name .. ' on surface.')
|
||||
end
|
||||
|
||||
insert(created_entities, created_entity)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
data.entity_iterator = data.entity_iterator + entities_per_call
|
||||
|
||||
for _, entity in pairs(created_entities) do
|
||||
raise_event(Template.events.on_placed_entity, {entity = entity})
|
||||
end
|
||||
|
||||
return data.entity_iterator <= data.entities_n
|
||||
end
|
||||
|
||||
local function insert_action(data)
|
||||
if data.tile_iterator <= data.tiles_n then
|
||||
insert_next_tiles(data)
|
||||
return true
|
||||
end
|
||||
|
||||
return insert_next_entities(data)
|
||||
end
|
||||
|
||||
local insert_token = Token.register(insert_action)
|
||||
|
||||
--[[--
|
||||
Inserts a batch of tiles and then entities.
|
||||
|
||||
@see LuaSurface.set_tiles
|
||||
@see LuaSurface.entity
|
||||
|
||||
@param surface LuaSurface to put the tiles and entities on
|
||||
@param tiles table of tiles as required by set_tiles
|
||||
@param entities table of entities as required by create_entity
|
||||
]]
|
||||
function Template.insert(surface, tiles, entities)
|
||||
tiles = tiles or {}
|
||||
entities = entities or {}
|
||||
|
||||
local tiles_n = #tiles
|
||||
local entities_n = #entities
|
||||
local total_calls = ceil(tiles_n / tiles_per_call) + (entities_n / entities_per_call)
|
||||
local data = {
|
||||
tiles_n = tiles_n,
|
||||
tile_iterator = 1,
|
||||
entities_n = entities_n,
|
||||
entity_iterator = 1,
|
||||
surface = surface,
|
||||
tiles = tiles,
|
||||
entities = entities
|
||||
}
|
||||
|
||||
local continue = true
|
||||
for i = 1, 4 do
|
||||
continue = insert_action(data)
|
||||
if not continue then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if continue then
|
||||
Task.queue_task(insert_token, data, total_calls - 4)
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Designed to spawn aliens, uses find_non_colliding_position.
|
||||
|
||||
@see LuaSurface.entity
|
||||
|
||||
@param surface LuaSurface to put the tiles and entities on
|
||||
@param units table of entities as required by create_entity
|
||||
@param non_colliding_distance int amount of tiles to scan around original position in case it's already taken
|
||||
@param generic_unit_name_for_spawn_size String allows setting a custom unit name for spawn size, will overwrite the actual
|
||||
]]
|
||||
function Template.units(surface, units, non_colliding_distance, generic_unit_name_for_spawn_size)
|
||||
non_colliding_distance = non_colliding_distance or 1
|
||||
generic_unit_name_for_spawn_size = generic_unit_name_for_spawn_size or 'player'
|
||||
|
||||
local create_entity = surface.create_entity
|
||||
local position
|
||||
|
||||
for _, entity in pairs(units) do
|
||||
position = position or surface.find_non_colliding_position(
|
||||
generic_unit_name_for_spawn_size,
|
||||
entity.position, non_colliding_distance,
|
||||
0.5
|
||||
)
|
||||
|
||||
if (nil ~= position) then
|
||||
entity.position = position
|
||||
create_entity(entity)
|
||||
elseif (nil == create_entity(entity)) then
|
||||
Debug.print_position(entity.position, "Failed to spawn '" .. entity.name .. "'")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Designed to spawn resources.
|
||||
|
||||
@see LuaSurface.entity
|
||||
|
||||
@param surface LuaSurface to put the tiles and entities on
|
||||
@param resources table of entities as required by create_entity
|
||||
]]
|
||||
function Template.resources(surface, resources)
|
||||
local create_entity = surface.create_entity
|
||||
for _, entity in pairs(resources) do
|
||||
create_entity(entity)
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Designed to spawn a market.
|
||||
|
||||
@param surface LuaSurface
|
||||
@param position Position
|
||||
@param force LuaForce
|
||||
@param market_items Table
|
||||
]]
|
||||
function Template.market(surface, position, force, market_inventory)
|
||||
local market = surface.create_entity({name = 'market', position = position})
|
||||
local add_market_item = market.add_market_item
|
||||
market.destructible = false
|
||||
|
||||
for _, item in ipairs(market_inventory) do
|
||||
add_market_item(item)
|
||||
end
|
||||
|
||||
force.add_chart_tag(surface, {
|
||||
text = 'Market',
|
||||
position = position,
|
||||
})
|
||||
|
||||
raise_event(Template.events.on_placed_entity, {entity = market})
|
||||
end
|
||||
|
||||
return Template
|
||||
-- dependencies
|
||||
local Task = require 'utils.Task'
|
||||
local Token = require 'utils.global_token'
|
||||
local Debug = require 'map_gen.Diggy.Debug'
|
||||
local insert = table.insert
|
||||
local min = math.min
|
||||
local ceil = math.ceil
|
||||
local raise_event = script.raise_event
|
||||
|
||||
-- this
|
||||
local Template = {}
|
||||
|
||||
local tiles_per_call = 5 --how many tiles are inserted with each call of insert_action
|
||||
local entities_per_call = 5 --how many entities are inserted with each call of insert_action
|
||||
|
||||
Template.events = {
|
||||
--[[--
|
||||
When an entity is placed via the template function.
|
||||
- event.entity LuaEntity
|
||||
]]
|
||||
on_placed_entity = script.generate_event_name(),
|
||||
|
||||
--[[--
|
||||
Triggers when an 'out-of-map' tile is replaced by something else.
|
||||
|
||||
{surface, old_tile={name, position={x, y}}}
|
||||
]]
|
||||
on_void_removed = script.generate_event_name(),
|
||||
}
|
||||
|
||||
local function insert_next_tiles(data)
|
||||
local void_removed = {}
|
||||
local surface = data.surface
|
||||
local get_tile = surface.get_tile
|
||||
local tiles = {}
|
||||
|
||||
pcall(
|
||||
function()
|
||||
--use pcall to assure tile_iterator is always incremented, to avoid endless loops
|
||||
for i = data.tile_iterator, min(data.tile_iterator + tiles_per_call - 1, data.tiles_n) do
|
||||
local new_tile = data.tiles[i]
|
||||
insert(tiles, new_tile)
|
||||
local current_tile = get_tile(new_tile.position.x, new_tile.position.y)
|
||||
local current_is_void = current_tile.name == 'out-of-map'
|
||||
local new_is_void = new_tile.name == 'out-of-map'
|
||||
|
||||
if (current_is_void and not new_is_void) then
|
||||
insert(void_removed, {surface = surface, position = current_tile.position})
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
data.tile_iterator = data.tile_iterator + tiles_per_call
|
||||
|
||||
surface.set_tiles(tiles)
|
||||
|
||||
for _, event in pairs(void_removed) do
|
||||
raise_event(Template.events.on_void_removed, event)
|
||||
end
|
||||
end
|
||||
|
||||
local function insert_next_entities(data)
|
||||
local created_entities = {}
|
||||
local surface = data.surface
|
||||
local create_entity = surface.create_entity
|
||||
|
||||
pcall(
|
||||
function()
|
||||
--use pcall to assure tile_iterator is always incremented, to avoid endless loops
|
||||
for i = data.entity_iterator, min(data.entity_iterator + entities_per_call - 1, data.entities_n) do
|
||||
local entity = data.entities[i]
|
||||
local created_entity = create_entity(entity)
|
||||
if (nil == created_entity) then
|
||||
error('Failed creating entity ' .. entity.name .. ' on surface.')
|
||||
end
|
||||
|
||||
insert(created_entities, created_entity)
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
data.entity_iterator = data.entity_iterator + entities_per_call
|
||||
|
||||
for _, entity in pairs(created_entities) do
|
||||
raise_event(Template.events.on_placed_entity, {entity = entity})
|
||||
end
|
||||
|
||||
return data.entity_iterator <= data.entities_n
|
||||
end
|
||||
|
||||
local function insert_action(data)
|
||||
if data.tile_iterator <= data.tiles_n then
|
||||
insert_next_tiles(data)
|
||||
return true
|
||||
end
|
||||
|
||||
return insert_next_entities(data)
|
||||
end
|
||||
|
||||
local insert_token = Token.register(insert_action)
|
||||
|
||||
--[[--
|
||||
Inserts a batch of tiles and then entities.
|
||||
|
||||
@see LuaSurface.set_tiles
|
||||
@see LuaSurface.entity
|
||||
|
||||
@param surface LuaSurface to put the tiles and entities on
|
||||
@param tiles table of tiles as required by set_tiles
|
||||
@param entities table of entities as required by create_entity
|
||||
]]
|
||||
function Template.insert(surface, tiles, entities)
|
||||
tiles = tiles or {}
|
||||
entities = entities or {}
|
||||
|
||||
local tiles_n = #tiles
|
||||
local entities_n = #entities
|
||||
local total_calls = ceil(tiles_n / tiles_per_call) + (entities_n / entities_per_call)
|
||||
local data = {
|
||||
tiles_n = tiles_n,
|
||||
tile_iterator = 1,
|
||||
entities_n = entities_n,
|
||||
entity_iterator = 1,
|
||||
surface = surface,
|
||||
tiles = tiles,
|
||||
entities = entities
|
||||
}
|
||||
|
||||
local continue = true
|
||||
for i = 1, 4 do
|
||||
continue = insert_action(data)
|
||||
if not continue then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if continue then
|
||||
Task.queue_task(insert_token, data, total_calls - 4)
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Designed to spawn aliens, uses find_non_colliding_position.
|
||||
|
||||
@see LuaSurface.entity
|
||||
|
||||
@param surface LuaSurface to put the tiles and entities on
|
||||
@param units table of entities as required by create_entity
|
||||
@param non_colliding_distance int amount of tiles to scan around original position in case it's already taken
|
||||
@param generic_unit_name_for_spawn_size String allows setting a custom unit name for spawn size, will overwrite the actual
|
||||
]]
|
||||
function Template.units(surface, units, non_colliding_distance, generic_unit_name_for_spawn_size)
|
||||
non_colliding_distance = non_colliding_distance or 1
|
||||
generic_unit_name_for_spawn_size = generic_unit_name_for_spawn_size or 'player'
|
||||
|
||||
local create_entity = surface.create_entity
|
||||
local position
|
||||
|
||||
for _, entity in pairs(units) do
|
||||
position = position or surface.find_non_colliding_position(
|
||||
generic_unit_name_for_spawn_size,
|
||||
entity.position, non_colliding_distance,
|
||||
0.5
|
||||
)
|
||||
|
||||
if (nil ~= position) then
|
||||
entity.position = position
|
||||
create_entity(entity)
|
||||
elseif (nil == create_entity(entity)) then
|
||||
Debug.print_position(entity.position, "Failed to spawn '" .. entity.name .. "'")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Designed to spawn resources.
|
||||
|
||||
@see LuaSurface.entity
|
||||
|
||||
@param surface LuaSurface to put the tiles and entities on
|
||||
@param resources table of entities as required by create_entity
|
||||
]]
|
||||
function Template.resources(surface, resources)
|
||||
local create_entity = surface.create_entity
|
||||
for _, entity in pairs(resources) do
|
||||
create_entity(entity)
|
||||
end
|
||||
end
|
||||
|
||||
--[[--
|
||||
Designed to spawn a market.
|
||||
|
||||
@param surface LuaSurface
|
||||
@param position Position
|
||||
@param force LuaForce
|
||||
@param market_items Table
|
||||
]]
|
||||
function Template.market(surface, position, force, market_inventory)
|
||||
local market = surface.create_entity({name = 'market', position = position})
|
||||
local add_market_item = market.add_market_item
|
||||
market.destructible = false
|
||||
|
||||
for _, item in ipairs(market_inventory) do
|
||||
add_market_item(item)
|
||||
end
|
||||
|
||||
force.add_chart_tag(surface, {
|
||||
text = 'Market',
|
||||
position = position,
|
||||
})
|
||||
|
||||
raise_event(Template.events.on_placed_entity, {entity = market})
|
||||
end
|
||||
|
||||
return Template
|
||||
|
@ -1,2 +1,2 @@
|
||||
-- authors Linaori, valansch
|
||||
require 'map_gen.Diggy.Scenario'.register(_DEBUG)
|
||||
-- authors Linaori, valansch
|
||||
require 'map_gen.Diggy.Scenario'.register(_DEBUG)
|
||||
|
@ -1,191 +1,191 @@
|
||||
return {
|
||||
height = 185,
|
||||
width = 337,
|
||||
data = {
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,10,1,30,2,84,1,30,2,80,1,29,2,74,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{2,10,1,30,2,84,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,79,1,31,2,73,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,79,1,31,2,73,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
}
|
||||
return {
|
||||
height = 185,
|
||||
width = 337,
|
||||
data = {
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,10,1,30,2,84,1,30,2,80,1,29,2,74,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{1,108,2,16,1,30,2,80,1,29,2,16,1,58,},
|
||||
{2,10,1,30,2,84,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,195,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,79,1,31,2,73,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,11,1,167,2,5,},
|
||||
{2,11,1,28,2,85,1,30,2,79,1,31,2,73,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,124,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,17,1,166,2,12,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,80,1,29,2,74,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
{2,11,1,28,2,85,1,30,2,183,},
|
||||
}
|
||||
}
|
@ -1,48 +1,48 @@
|
||||
local perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local random_ores = {'iron-ore', 'coal', 'copper-ore', 'stone', 'uranium-ore'}
|
||||
local random_dense = {1.6, 0.8, 1, 0.6, 0.5} --ore density reference
|
||||
|
||||
local function run_ores_module_setup()
|
||||
local seed = game.surfaces[1].map_gen_settings.seed
|
||||
if not global.ores_seed_A then
|
||||
global.ores_seed_A = seed
|
||||
end
|
||||
if not global.ores_seed_B then
|
||||
global.ores_seed_B = seed * 2
|
||||
end
|
||||
end
|
||||
|
||||
Event.on_init(run_ores_module_setup)
|
||||
|
||||
return function(x, y, world)
|
||||
local d_sq = world.x * world.x + world.y * world.y
|
||||
if d_sq < 9216 then
|
||||
return
|
||||
end
|
||||
|
||||
local distance_bonus = 100 + 0.4 * d ^ 1.2
|
||||
|
||||
local wiggle = 100 + perlin.noise((x * 0.005), (y * 0.005), global.ores_seed_A + 41) * 60
|
||||
local Ores_A = perlin.noise((x * 0.01), (y * 0.01), global.ores_seed_B + 57) * wiggle
|
||||
|
||||
if Ores_A > 35 then --we place ores
|
||||
local Ores_B = perlin.noise((x * 0.02), (y * 0.02), global.ores_seed_B + 13) * wiggle
|
||||
local a = 5
|
||||
--
|
||||
if Ores_A < 76 then
|
||||
a = math.floor(Ores_A * 0.75 + Ores_B * 0.5) % 4 + 1
|
||||
end --if its not super high we place normal ores
|
||||
--
|
||||
local res_amount = distance_bonus
|
||||
res_amount = math.floor(res_amount * random_dense[a])
|
||||
--
|
||||
|
||||
return {name = random_ores[a], amount = res_amount}
|
||||
elseif Ores_A < -60 then
|
||||
if math.random(1, 200) == 1 then
|
||||
return {name = 'crude-oil', amount = 5000 + math.floor(distance_bonus) * 500}
|
||||
end
|
||||
end
|
||||
end
|
||||
local perlin = require 'map_gen.shared.perlin_noise'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local random_ores = {'iron-ore', 'coal', 'copper-ore', 'stone', 'uranium-ore'}
|
||||
local random_dense = {1.6, 0.8, 1, 0.6, 0.5} --ore density reference
|
||||
|
||||
local function run_ores_module_setup()
|
||||
local seed = game.surfaces[1].map_gen_settings.seed
|
||||
if not global.ores_seed_A then
|
||||
global.ores_seed_A = seed
|
||||
end
|
||||
if not global.ores_seed_B then
|
||||
global.ores_seed_B = seed * 2
|
||||
end
|
||||
end
|
||||
|
||||
Event.on_init(run_ores_module_setup)
|
||||
|
||||
return function(x, y, world)
|
||||
local d_sq = world.x * world.x + world.y * world.y
|
||||
if d_sq < 9216 then
|
||||
return
|
||||
end
|
||||
|
||||
local distance_bonus = 100 + 0.4 * d ^ 1.2
|
||||
|
||||
local wiggle = 100 + perlin.noise((x * 0.005), (y * 0.005), global.ores_seed_A + 41) * 60
|
||||
local Ores_A = perlin.noise((x * 0.01), (y * 0.01), global.ores_seed_B + 57) * wiggle
|
||||
|
||||
if Ores_A > 35 then --we place ores
|
||||
local Ores_B = perlin.noise((x * 0.02), (y * 0.02), global.ores_seed_B + 13) * wiggle
|
||||
local a = 5
|
||||
--
|
||||
if Ores_A < 76 then
|
||||
a = math.floor(Ores_A * 0.75 + Ores_B * 0.5) % 4 + 1
|
||||
end --if its not super high we place normal ores
|
||||
--
|
||||
local res_amount = distance_bonus
|
||||
res_amount = math.floor(res_amount * random_dense[a])
|
||||
--
|
||||
|
||||
return {name = random_ores[a], amount = res_amount}
|
||||
elseif Ores_A < -60 then
|
||||
if math.random(1, 200) == 1 then
|
||||
return {name = 'crude-oil', amount = 5000 + math.floor(distance_bonus) * 500}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,178 +1,178 @@
|
||||
-- Map by Jayefuu, plague006 and grilledham
|
||||
-- Map in the shape of a maltese cross, with narrow water bridges around the spawn to force "interesting" transfer of materials
|
||||
|
||||
local b = require 'map_gen.shared.builders'
|
||||
local math = require "utils.math"
|
||||
local degrees = math.rad
|
||||
|
||||
local function value(base, mult, pow)
|
||||
return function(x, y)
|
||||
local d_sq = x * x + y * y
|
||||
return base + mult * d_sq ^ (pow / 2) -- d ^ pow
|
||||
end
|
||||
end
|
||||
|
||||
local function no_trees(world, tile)
|
||||
if not tile then
|
||||
return
|
||||
end
|
||||
for _, e in ipairs(
|
||||
world.surface.find_entities_filtered(
|
||||
{type = 'tree', area = {{world.x, world.y}, {world.x + 1, world.y + 1}}}
|
||||
)
|
||||
) do
|
||||
e.destroy()
|
||||
end
|
||||
return tile
|
||||
end
|
||||
|
||||
local function no_resources(world, tile)
|
||||
for _, e in ipairs(
|
||||
world.surface.find_entities_filtered(
|
||||
{type = 'resource', area = {{world.x, world.y}, {world.x + 1, world.y + 1}}}
|
||||
)
|
||||
) do
|
||||
e.destroy()
|
||||
end
|
||||
return tile
|
||||
end
|
||||
|
||||
local starting_area = 59
|
||||
|
||||
local gradient = 0.05
|
||||
local tiles_half = (starting_area) * 0.5
|
||||
|
||||
local function maltese_cross(x,y)
|
||||
--Create maltese shape
|
||||
|
||||
local abs_x = math.abs(x)
|
||||
local abs_y = math.abs(y)
|
||||
|
||||
return not (abs_x > (tiles_half+(abs_y*gradient)) and abs_y > (tiles_half+(abs_x*gradient)))
|
||||
end
|
||||
|
||||
-- create water crossings and pattern
|
||||
local water_line =
|
||||
b.any {
|
||||
b.rectangle(10,8)
|
||||
}
|
||||
water_line = b.change_tile(water_line, true, 'water')
|
||||
|
||||
local waters = b.single_y_pattern(water_line, 9)
|
||||
local bounds = b.rectangle(10, starting_area+1)
|
||||
waters = b.choose(bounds, waters, b.empty_shape)
|
||||
waters = b.translate(waters,34,0)
|
||||
|
||||
local water_pattern = b.any{
|
||||
waters,
|
||||
b.rotate(waters,degrees(90)),
|
||||
b.rotate(waters,degrees(180)),
|
||||
b.rotate(waters,degrees(270))
|
||||
}
|
||||
|
||||
-- create the starting area as a grass square
|
||||
local starting_square = b.rectangle(60, 60)
|
||||
starting_square = b.change_tile(starting_square, true, 'grass-1')
|
||||
|
||||
local starting_patch = b.circle(20)
|
||||
local starting_coal = b.resource(starting_patch, 'coal', value(1800, 0.8, 1.5))
|
||||
local starting_iron = b.resource(starting_patch, 'iron-ore', value(3000, 0.8, 1.5))
|
||||
local starting_copper = b.resource(starting_patch, 'copper-ore', value(2200, 0.75, 1.5))
|
||||
local starting_stone = b.resource(starting_patch, 'stone', value(1100, 0.75, 1.5))
|
||||
local null = b.no_entity
|
||||
local starting_resources = b.segment_pattern({null,starting_coal,null,starting_copper,null,starting_stone,null,starting_iron})
|
||||
starting_resources = b.rotate(starting_resources, degrees(45/2))
|
||||
-- starting_circle = b.circle(14)
|
||||
|
||||
-- ore generation
|
||||
local patch = b.circle(20)
|
||||
local small_patch = b.circle(8)
|
||||
local patches = b.single_pattern(patch, 220, 220)
|
||||
|
||||
local stone = b.resource(patch, 'stone', value(100, 0.75, 1.1))
|
||||
local oil = b.resource(b.throttle_world_xy(small_patch,1,4,1,4), 'crude-oil', value(33000, 50, 1.05))
|
||||
local coal = b.resource(patch, 'coal', value(100, 0.75, 1.1))
|
||||
local uranium = b.resource(small_patch, 'uranium-ore', value(200, 0.75, 1.1))
|
||||
|
||||
local pattern1 =
|
||||
{
|
||||
{stone, oil,stone},
|
||||
{stone, oil, oil},
|
||||
{stone, stone, stone}
|
||||
}
|
||||
local stone_arm = b.grid_pattern(pattern1, 3, 3, 220,220)
|
||||
|
||||
local pattern2 =
|
||||
{
|
||||
{coal, coal, coal},
|
||||
{coal, coal, coal},
|
||||
{coal, coal, uranium}
|
||||
}
|
||||
local coal_arm = b.grid_pattern(pattern2, 3, 3, 220, 220)
|
||||
local iron = b.resource(patches, 'iron-ore', value(500, 0.8, 1.075))
|
||||
local copper = b.resource(patches, 'copper-ore', value(400, 0.75, 1.1))
|
||||
|
||||
local resources = b.segment_pattern({null,coal_arm,null,copper,null,stone_arm,null,iron})
|
||||
resources = b.rotate(resources, degrees(45/2))
|
||||
|
||||
-- worm islands
|
||||
local worm_island = b.rectangle(20,300)
|
||||
local worm_island_end = b.circle(10)
|
||||
worm_island = b.any{
|
||||
worm_island_end,
|
||||
b.translate(worm_island,0,-150),
|
||||
b.translate(worm_island_end,0,-300)
|
||||
}
|
||||
worm_island = b.change_tile(worm_island, true, 'grass-1')
|
||||
|
||||
--[[
|
||||
local worm_names = {
|
||||
'small-worm-turret',
|
||||
'medium-worm-turret',
|
||||
'big-worm-turret'
|
||||
}
|
||||
]]--
|
||||
|
||||
local max_worm_chance = 64 / 128
|
||||
local worm_chance_factor = 1 --/ (192 * 512)
|
||||
local function worms(_, _, world)
|
||||
local wx, wy = world.x, world.y
|
||||
local d = math.sqrt(wx * wx + wy * wy)
|
||||
local worm_chance = d - 20
|
||||
if worm_chance > 0 then
|
||||
worm_chance = worm_chance * worm_chance_factor
|
||||
worm_chance = math.min(worm_chance, max_worm_chance)
|
||||
if math.random() < worm_chance then
|
||||
return {name = 'big-worm-turret'}
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
worm_island = b.apply_entity(worm_island, worms)
|
||||
worm_island = b.apply_effect(worm_island, no_trees)
|
||||
|
||||
local worm_islands = b.any{
|
||||
b.rotate(b.translate(worm_island,0,-110),degrees(45)),
|
||||
b.rotate(b.translate(worm_island,0,-110),degrees(45+90)),
|
||||
b.rotate(b.translate(worm_island,0,-110),degrees(45+180)),
|
||||
b.rotate(b.translate(worm_island,0,-110),degrees(45+270))
|
||||
}
|
||||
|
||||
-- create the start area using the water and grass square
|
||||
local start_area =
|
||||
b.any {
|
||||
water_pattern,
|
||||
starting_square
|
||||
}
|
||||
|
||||
-- finalising some bits
|
||||
start_area = b.apply_entity(start_area, starting_resources) -- adds a different density ore patch to start
|
||||
maltese_cross = b.change_tile(maltese_cross, true, 'grass-1')
|
||||
maltese_cross = b.apply_entity(maltese_cross, resources) -- adds our custom ore gen
|
||||
local sea = b.change_tile(b.full_shape, true, 'water') -- turn the void to water
|
||||
sea = b.fish(sea, 0.00125) -- feesh!
|
||||
local map = b.any{worm_islands, start_area, maltese_cross, sea} -- combine everything
|
||||
map = b.apply_effect(map, no_resources) -- removes vanilla ores
|
||||
|
||||
-- Map by Jayefuu, plague006 and grilledham
|
||||
-- Map in the shape of a maltese cross, with narrow water bridges around the spawn to force "interesting" transfer of materials
|
||||
|
||||
local b = require 'map_gen.shared.builders'
|
||||
local math = require "utils.math"
|
||||
local degrees = math.rad
|
||||
|
||||
local function value(base, mult, pow)
|
||||
return function(x, y)
|
||||
local d_sq = x * x + y * y
|
||||
return base + mult * d_sq ^ (pow / 2) -- d ^ pow
|
||||
end
|
||||
end
|
||||
|
||||
local function no_trees(world, tile)
|
||||
if not tile then
|
||||
return
|
||||
end
|
||||
for _, e in ipairs(
|
||||
world.surface.find_entities_filtered(
|
||||
{type = 'tree', area = {{world.x, world.y}, {world.x + 1, world.y + 1}}}
|
||||
)
|
||||
) do
|
||||
e.destroy()
|
||||
end
|
||||
return tile
|
||||
end
|
||||
|
||||
local function no_resources(world, tile)
|
||||
for _, e in ipairs(
|
||||
world.surface.find_entities_filtered(
|
||||
{type = 'resource', area = {{world.x, world.y}, {world.x + 1, world.y + 1}}}
|
||||
)
|
||||
) do
|
||||
e.destroy()
|
||||
end
|
||||
return tile
|
||||
end
|
||||
|
||||
local starting_area = 59
|
||||
|
||||
local gradient = 0.05
|
||||
local tiles_half = (starting_area) * 0.5
|
||||
|
||||
local function maltese_cross(x,y)
|
||||
--Create maltese shape
|
||||
|
||||
local abs_x = math.abs(x)
|
||||
local abs_y = math.abs(y)
|
||||
|
||||
return not (abs_x > (tiles_half+(abs_y*gradient)) and abs_y > (tiles_half+(abs_x*gradient)))
|
||||
end
|
||||
|
||||
-- create water crossings and pattern
|
||||
local water_line =
|
||||
b.any {
|
||||
b.rectangle(10,8)
|
||||
}
|
||||
water_line = b.change_tile(water_line, true, 'water')
|
||||
|
||||
local waters = b.single_y_pattern(water_line, 9)
|
||||
local bounds = b.rectangle(10, starting_area+1)
|
||||
waters = b.choose(bounds, waters, b.empty_shape)
|
||||
waters = b.translate(waters,34,0)
|
||||
|
||||
local water_pattern = b.any{
|
||||
waters,
|
||||
b.rotate(waters,degrees(90)),
|
||||
b.rotate(waters,degrees(180)),
|
||||
b.rotate(waters,degrees(270))
|
||||
}
|
||||
|
||||
-- create the starting area as a grass square
|
||||
local starting_square = b.rectangle(60, 60)
|
||||
starting_square = b.change_tile(starting_square, true, 'grass-1')
|
||||
|
||||
local starting_patch = b.circle(20)
|
||||
local starting_coal = b.resource(starting_patch, 'coal', value(1800, 0.8, 1.5))
|
||||
local starting_iron = b.resource(starting_patch, 'iron-ore', value(3000, 0.8, 1.5))
|
||||
local starting_copper = b.resource(starting_patch, 'copper-ore', value(2200, 0.75, 1.5))
|
||||
local starting_stone = b.resource(starting_patch, 'stone', value(1100, 0.75, 1.5))
|
||||
local null = b.no_entity
|
||||
local starting_resources = b.segment_pattern({null,starting_coal,null,starting_copper,null,starting_stone,null,starting_iron})
|
||||
starting_resources = b.rotate(starting_resources, degrees(45/2))
|
||||
-- starting_circle = b.circle(14)
|
||||
|
||||
-- ore generation
|
||||
local patch = b.circle(20)
|
||||
local small_patch = b.circle(8)
|
||||
local patches = b.single_pattern(patch, 220, 220)
|
||||
|
||||
local stone = b.resource(patch, 'stone', value(100, 0.75, 1.1))
|
||||
local oil = b.resource(b.throttle_world_xy(small_patch,1,4,1,4), 'crude-oil', value(33000, 50, 1.05))
|
||||
local coal = b.resource(patch, 'coal', value(100, 0.75, 1.1))
|
||||
local uranium = b.resource(small_patch, 'uranium-ore', value(200, 0.75, 1.1))
|
||||
|
||||
local pattern1 =
|
||||
{
|
||||
{stone, oil,stone},
|
||||
{stone, oil, oil},
|
||||
{stone, stone, stone}
|
||||
}
|
||||
local stone_arm = b.grid_pattern(pattern1, 3, 3, 220,220)
|
||||
|
||||
local pattern2 =
|
||||
{
|
||||
{coal, coal, coal},
|
||||
{coal, coal, coal},
|
||||
{coal, coal, uranium}
|
||||
}
|
||||
local coal_arm = b.grid_pattern(pattern2, 3, 3, 220, 220)
|
||||
local iron = b.resource(patches, 'iron-ore', value(500, 0.8, 1.075))
|
||||
local copper = b.resource(patches, 'copper-ore', value(400, 0.75, 1.1))
|
||||
|
||||
local resources = b.segment_pattern({null,coal_arm,null,copper,null,stone_arm,null,iron})
|
||||
resources = b.rotate(resources, degrees(45/2))
|
||||
|
||||
-- worm islands
|
||||
local worm_island = b.rectangle(20,300)
|
||||
local worm_island_end = b.circle(10)
|
||||
worm_island = b.any{
|
||||
worm_island_end,
|
||||
b.translate(worm_island,0,-150),
|
||||
b.translate(worm_island_end,0,-300)
|
||||
}
|
||||
worm_island = b.change_tile(worm_island, true, 'grass-1')
|
||||
|
||||
--[[
|
||||
local worm_names = {
|
||||
'small-worm-turret',
|
||||
'medium-worm-turret',
|
||||
'big-worm-turret'
|
||||
}
|
||||
]]--
|
||||
|
||||
local max_worm_chance = 64 / 128
|
||||
local worm_chance_factor = 1 --/ (192 * 512)
|
||||
local function worms(_, _, world)
|
||||
local wx, wy = world.x, world.y
|
||||
local d = math.sqrt(wx * wx + wy * wy)
|
||||
local worm_chance = d - 20
|
||||
if worm_chance > 0 then
|
||||
worm_chance = worm_chance * worm_chance_factor
|
||||
worm_chance = math.min(worm_chance, max_worm_chance)
|
||||
if math.random() < worm_chance then
|
||||
return {name = 'big-worm-turret'}
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
worm_island = b.apply_entity(worm_island, worms)
|
||||
worm_island = b.apply_effect(worm_island, no_trees)
|
||||
|
||||
local worm_islands = b.any{
|
||||
b.rotate(b.translate(worm_island,0,-110),degrees(45)),
|
||||
b.rotate(b.translate(worm_island,0,-110),degrees(45+90)),
|
||||
b.rotate(b.translate(worm_island,0,-110),degrees(45+180)),
|
||||
b.rotate(b.translate(worm_island,0,-110),degrees(45+270))
|
||||
}
|
||||
|
||||
-- create the start area using the water and grass square
|
||||
local start_area =
|
||||
b.any {
|
||||
water_pattern,
|
||||
starting_square
|
||||
}
|
||||
|
||||
-- finalising some bits
|
||||
start_area = b.apply_entity(start_area, starting_resources) -- adds a different density ore patch to start
|
||||
maltese_cross = b.change_tile(maltese_cross, true, 'grass-1')
|
||||
maltese_cross = b.apply_entity(maltese_cross, resources) -- adds our custom ore gen
|
||||
local sea = b.change_tile(b.full_shape, true, 'water') -- turn the void to water
|
||||
sea = b.fish(sea, 0.00125) -- feesh!
|
||||
local map = b.any{worm_islands, start_area, maltese_cross, sea} -- combine everything
|
||||
map = b.apply_effect(map, no_resources) -- removes vanilla ores
|
||||
|
||||
return map
|
@ -1,3 +1,3 @@
|
||||
return function(x, y, world)
|
||||
return not (x < -150 or y > 32 or y < -568)
|
||||
end
|
||||
return function(x, y, world)
|
||||
return not (x < -150 or y > 32 or y < -568)
|
||||
end
|
||||
|
@ -1,16 +1,16 @@
|
||||
local thickness = 72 -- change this to change the spiral thickness.
|
||||
|
||||
local inv_pi = 1 / math.pi
|
||||
local thickness2 = thickness * 2
|
||||
|
||||
return function(x, y)
|
||||
local d_sq = x * x + y * y
|
||||
if d_sq < 16384 then --d < 128
|
||||
return true
|
||||
end
|
||||
|
||||
local angle = 1 + inv_pi * math.atan2(x, y)
|
||||
local offset = d + (angle * thickness)
|
||||
|
||||
return offset % thickness2 >= thickness
|
||||
end
|
||||
local thickness = 72 -- change this to change the spiral thickness.
|
||||
|
||||
local inv_pi = 1 / math.pi
|
||||
local thickness2 = thickness * 2
|
||||
|
||||
return function(x, y)
|
||||
local d_sq = x * x + y * y
|
||||
if d_sq < 16384 then --d < 128
|
||||
return true
|
||||
end
|
||||
|
||||
local angle = 1 + inv_pi * math.atan2(x, y)
|
||||
local offset = d + (angle * thickness)
|
||||
|
||||
return offset % thickness2 >= thickness
|
||||
end
|
||||
|
@ -1,20 +1,20 @@
|
||||
return function(x, y, world)
|
||||
local distance = math.sqrt(x * x + y * y)
|
||||
if distance > 128 then
|
||||
local angle = 180 + math.deg(math.atan2(x, y))
|
||||
|
||||
local offset = distance
|
||||
local offset2 = distance
|
||||
if angle ~= 0 then
|
||||
offset2 = offset - angle / 3.75
|
||||
offset = offset + angle / 3.75
|
||||
end
|
||||
--if angle ~= 0 then offset = offset + angle /1.33333333 end
|
||||
|
||||
if offset % 96 < 64 then
|
||||
return offset2 % 96 >= 64
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
return function(x, y, world)
|
||||
local distance = math.sqrt(x * x + y * y)
|
||||
if distance > 128 then
|
||||
local angle = 180 + math.deg(math.atan2(x, y))
|
||||
|
||||
local offset = distance
|
||||
local offset2 = distance
|
||||
if angle ~= 0 then
|
||||
offset2 = offset - angle / 3.75
|
||||
offset = offset + angle / 3.75
|
||||
end
|
||||
--if angle ~= 0 then offset = offset + angle /1.33333333 end
|
||||
|
||||
if offset % 96 < 64 then
|
||||
return offset2 % 96 >= 64
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
@ -1,23 +1,23 @@
|
||||
return function(x, y, world)
|
||||
local distance = math.sqrt(x * x + y * y)
|
||||
if distance > 128 then
|
||||
local angle = (180 + math.deg(math.atan2(x, y))) * 3
|
||||
|
||||
local offset = distance * 0.75
|
||||
if angle ~= 0 then
|
||||
offset = offset + angle / 3.75
|
||||
end
|
||||
--if angle ~= 0 then offset = offset + angle /1.33333333 end
|
||||
|
||||
if offset % 96 < 48 then
|
||||
local offset2 = distance * 0.125
|
||||
if angle ~= 0 then
|
||||
offset2 = offset2 - angle / 3.75
|
||||
end
|
||||
|
||||
return offset2 % 96 >= 80
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
return function(x, y, world)
|
||||
local distance = math.sqrt(x * x + y * y)
|
||||
if distance > 128 then
|
||||
local angle = (180 + math.deg(math.atan2(x, y))) * 3
|
||||
|
||||
local offset = distance * 0.75
|
||||
if angle ~= 0 then
|
||||
offset = offset + angle / 3.75
|
||||
end
|
||||
--if angle ~= 0 then offset = offset + angle /1.33333333 end
|
||||
|
||||
if offset % 96 < 48 then
|
||||
local offset2 = distance * 0.125
|
||||
if angle ~= 0 then
|
||||
offset2 = offset2 - angle / 3.75
|
||||
end
|
||||
|
||||
return offset2 % 96 >= 80
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
@ -1,21 +1,21 @@
|
||||
-- Author: flowild
|
||||
|
||||
local arm_width = 96
|
||||
|
||||
local function is_on_spiral(x, y, distance, angle_offset)
|
||||
local angle = angle_offset + math.deg(math.atan2(x, y))
|
||||
|
||||
local offset = distance
|
||||
if angle ~= 0 then
|
||||
offset = offset + angle / 3.75 * 2
|
||||
end
|
||||
return offset % 96 * 2 >= 48 * 2
|
||||
end
|
||||
|
||||
return function(x, y, world)
|
||||
local pseudo_x = x / (arm_width / 48)
|
||||
local pseudo_y = y / (arm_width / 48)
|
||||
local distance = math.sqrt(pseudo_x * pseudo_x + pseudo_y * pseudo_y)
|
||||
|
||||
return not (distance > 100 and not is_on_spiral(x, y, distance, 0))
|
||||
end
|
||||
-- Author: flowild
|
||||
|
||||
local arm_width = 96
|
||||
|
||||
local function is_on_spiral(x, y, distance, angle_offset)
|
||||
local angle = angle_offset + math.deg(math.atan2(x, y))
|
||||
|
||||
local offset = distance
|
||||
if angle ~= 0 then
|
||||
offset = offset + angle / 3.75 * 2
|
||||
end
|
||||
return offset % 96 * 2 >= 48 * 2
|
||||
end
|
||||
|
||||
return function(x, y, world)
|
||||
local pseudo_x = x / (arm_width / 48)
|
||||
local pseudo_y = y / (arm_width / 48)
|
||||
local distance = math.sqrt(pseudo_x * pseudo_x + pseudo_y * pseudo_y)
|
||||
|
||||
return not (distance > 100 and not is_on_spiral(x, y, distance, 0))
|
||||
end
|
||||
|
@ -1,3 +1,3 @@
|
||||
return function(x, y, world)
|
||||
return not (x > 180 or x < -180 or y > 80)
|
||||
end
|
||||
return function(x, y, world)
|
||||
return not (x > 180 or x < -180 or y > 80)
|
||||
end
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,106 +1,106 @@
|
||||
--from https://github.com/thenumbernine/lua-simplexnoise/blob/master/2d.lua
|
||||
--Mostly as a test, does not give same results as perlin but is designed to give patterns all the same
|
||||
|
||||
local Simplex = {}
|
||||
|
||||
-- 2D simplex noise
|
||||
|
||||
local grad3 = {
|
||||
{1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0},
|
||||
{1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1},
|
||||
{0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}
|
||||
}
|
||||
|
||||
local p = {151,160,137,91,90,15,
|
||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180}
|
||||
local perm = {}
|
||||
for i=0,511 do
|
||||
perm[i+1] = p[bit32.band(i, 255) + 1]
|
||||
end
|
||||
|
||||
local function dot(g, ...)
|
||||
local v = {...}
|
||||
local sum = 0
|
||||
for i=1,#v do
|
||||
sum = sum + v[i] * g[i]
|
||||
end
|
||||
return sum
|
||||
end
|
||||
|
||||
local F2 = 0.5*(math.sqrt(3.0)-1.0)
|
||||
local G2 = (3.0-math.sqrt(3.0))/6.0
|
||||
function Simplex.d2(xin, yin,seed)
|
||||
xin = xin + seed
|
||||
yin = yin + seed
|
||||
local n0, n1, n2 -- Noise contributions from the three corners
|
||||
-- Skew the input space to determine which simplex cell we're in
|
||||
local s = (xin+yin)*F2; -- Hairy factor for 2D
|
||||
local i = math.floor(xin+s)
|
||||
local j = math.floor(yin+s)
|
||||
local t = (i+j)*G2
|
||||
local X0 = i-t -- Unskew the cell origin back to (x,y) space
|
||||
local Y0 = j-t
|
||||
local x0 = xin-X0 -- The x,y distances from the cell origin
|
||||
local y0 = yin-Y0
|
||||
-- For the 2D case, the simplex shape is an equilateral triangle.
|
||||
-- Determine which simplex we are in.
|
||||
local i1, j1 -- Offsets for second (middle) corner of simplex in (i,j) coords
|
||||
if x0 > y0 then
|
||||
i1 = 1
|
||||
j1 = 0 -- lower triangle, XY order: (0,0)->(1,0)->(1,1)
|
||||
else
|
||||
i1 = 0
|
||||
j1 = 1
|
||||
end-- upper triangle, YX order: (0,0)->(0,1)->(1,1)
|
||||
-- A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
|
||||
-- a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
|
||||
-- c = (3-sqrt(3))/6
|
||||
local x1 = x0 - i1 + G2 -- Offsets for middle corner in (x,y) unskewed coords
|
||||
local y1 = y0 - j1 + G2
|
||||
local x2 = x0 - 1 + 2 * G2 -- Offsets for last corner in (x,y) unskewed coords
|
||||
local y2 = y0 - 1 + 2 * G2
|
||||
-- Work out the hashed gradient indices of the three simplex corners
|
||||
local ii = bit32.band(i, 255)
|
||||
local jj = bit32.band(j, 255)
|
||||
local gi0 = perm[ii + perm[jj+1]+1] % 12
|
||||
local gi1 = perm[ii + i1 + perm[jj + j1+1]+1] % 12
|
||||
local gi2 = perm[ii + 1 + perm[jj + 1+1]+1] % 12
|
||||
-- Calculate the contribution from the three corners
|
||||
local t0 = 0.5 - x0 * x0 - y0 * y0
|
||||
if t0 < 0 then
|
||||
n0 = 0.0
|
||||
else
|
||||
t0 = t0 * t0
|
||||
n0 = t0 * t0 * dot(grad3[gi0+1], x0, y0) -- (x,y) of grad3 used for 2D gradient
|
||||
end
|
||||
local t1 = 0.5 - x1 * x1 - y1 * y1
|
||||
if t1 < 0 then
|
||||
n1 = 0.0
|
||||
else
|
||||
t1 = t1 * t1
|
||||
n1 = t1 * t1 * dot(grad3[gi1+1], x1, y1)
|
||||
end
|
||||
local t2 = 0.5 - x2 * x2 - y2 * y2
|
||||
if t2 < 0 then
|
||||
n2 = 0.0
|
||||
else
|
||||
t2 = t2 * t2
|
||||
n2 = t2 * t2 * dot(grad3[gi2+1], x2, y2)
|
||||
end
|
||||
-- Add contributions from each corner to get the final noise value.
|
||||
-- The result is scaled to return values in the interval [-1,1].
|
||||
return 70.0 * (n0 + n1 + n2)
|
||||
end
|
||||
|
||||
return Simplex
|
||||
--from https://github.com/thenumbernine/lua-simplexnoise/blob/master/2d.lua
|
||||
--Mostly as a test, does not give same results as perlin but is designed to give patterns all the same
|
||||
|
||||
local Simplex = {}
|
||||
|
||||
-- 2D simplex noise
|
||||
|
||||
local grad3 = {
|
||||
{1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0},
|
||||
{1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1},
|
||||
{0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}
|
||||
}
|
||||
|
||||
local p = {151,160,137,91,90,15,
|
||||
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
|
||||
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
|
||||
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
|
||||
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
|
||||
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
|
||||
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
|
||||
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
|
||||
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
|
||||
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
|
||||
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
|
||||
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
|
||||
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180}
|
||||
local perm = {}
|
||||
for i=0,511 do
|
||||
perm[i+1] = p[bit32.band(i, 255) + 1]
|
||||
end
|
||||
|
||||
local function dot(g, ...)
|
||||
local v = {...}
|
||||
local sum = 0
|
||||
for i=1,#v do
|
||||
sum = sum + v[i] * g[i]
|
||||
end
|
||||
return sum
|
||||
end
|
||||
|
||||
local F2 = 0.5*(math.sqrt(3.0)-1.0)
|
||||
local G2 = (3.0-math.sqrt(3.0))/6.0
|
||||
function Simplex.d2(xin, yin,seed)
|
||||
xin = xin + seed
|
||||
yin = yin + seed
|
||||
local n0, n1, n2 -- Noise contributions from the three corners
|
||||
-- Skew the input space to determine which simplex cell we're in
|
||||
local s = (xin+yin)*F2; -- Hairy factor for 2D
|
||||
local i = math.floor(xin+s)
|
||||
local j = math.floor(yin+s)
|
||||
local t = (i+j)*G2
|
||||
local X0 = i-t -- Unskew the cell origin back to (x,y) space
|
||||
local Y0 = j-t
|
||||
local x0 = xin-X0 -- The x,y distances from the cell origin
|
||||
local y0 = yin-Y0
|
||||
-- For the 2D case, the simplex shape is an equilateral triangle.
|
||||
-- Determine which simplex we are in.
|
||||
local i1, j1 -- Offsets for second (middle) corner of simplex in (i,j) coords
|
||||
if x0 > y0 then
|
||||
i1 = 1
|
||||
j1 = 0 -- lower triangle, XY order: (0,0)->(1,0)->(1,1)
|
||||
else
|
||||
i1 = 0
|
||||
j1 = 1
|
||||
end-- upper triangle, YX order: (0,0)->(0,1)->(1,1)
|
||||
-- A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
|
||||
-- a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
|
||||
-- c = (3-sqrt(3))/6
|
||||
local x1 = x0 - i1 + G2 -- Offsets for middle corner in (x,y) unskewed coords
|
||||
local y1 = y0 - j1 + G2
|
||||
local x2 = x0 - 1 + 2 * G2 -- Offsets for last corner in (x,y) unskewed coords
|
||||
local y2 = y0 - 1 + 2 * G2
|
||||
-- Work out the hashed gradient indices of the three simplex corners
|
||||
local ii = bit32.band(i, 255)
|
||||
local jj = bit32.band(j, 255)
|
||||
local gi0 = perm[ii + perm[jj+1]+1] % 12
|
||||
local gi1 = perm[ii + i1 + perm[jj + j1+1]+1] % 12
|
||||
local gi2 = perm[ii + 1 + perm[jj + 1+1]+1] % 12
|
||||
-- Calculate the contribution from the three corners
|
||||
local t0 = 0.5 - x0 * x0 - y0 * y0
|
||||
if t0 < 0 then
|
||||
n0 = 0.0
|
||||
else
|
||||
t0 = t0 * t0
|
||||
n0 = t0 * t0 * dot(grad3[gi0+1], x0, y0) -- (x,y) of grad3 used for 2D gradient
|
||||
end
|
||||
local t1 = 0.5 - x1 * x1 - y1 * y1
|
||||
if t1 < 0 then
|
||||
n1 = 0.0
|
||||
else
|
||||
t1 = t1 * t1
|
||||
n1 = t1 * t1 * dot(grad3[gi1+1], x1, y1)
|
||||
end
|
||||
local t2 = 0.5 - x2 * x2 - y2 * y2
|
||||
if t2 < 0 then
|
||||
n2 = 0.0
|
||||
else
|
||||
t2 = t2 * t2
|
||||
n2 = t2 * t2 * dot(grad3[gi2+1], x2, y2)
|
||||
end
|
||||
-- Add contributions from each corner to get the final noise value.
|
||||
-- The result is scaled to return values in the interval [-1,1].
|
||||
return 70.0 * (n0 + n1 + n2)
|
||||
end
|
||||
|
||||
return Simplex
|
||||
|
@ -1,178 +1,178 @@
|
||||
local perlin = require 'map_gen.shared.perlin_noise'
|
||||
local simplex = require 'map_gen.shared.simplex_noise'
|
||||
|
||||
local tree_to_place = {'dry-tree', 'dry-hairy-tree', 'tree-06', 'tree-06', 'tree-01', 'tree-02', 'tree-03'}
|
||||
|
||||
function run_terrain_module(event)
|
||||
if not global.terrain_seed_A then
|
||||
global.terrain_seed_A = math.random(10, 10000)
|
||||
end
|
||||
if not global.terrain_seed_B then
|
||||
global.terrain_seed_B = math.random(10, 10000)
|
||||
end
|
||||
|
||||
local area = event.area
|
||||
local surface = event.surface
|
||||
local tiles = {}
|
||||
local tileswater = {}
|
||||
|
||||
local entities = surface.find_entities(area)
|
||||
for _, entity in pairs(entities) do
|
||||
--if entity.type == "simple-entity" or entity.type == "resource" or entity.type == "tree" then
|
||||
if entity.type == 'simple-entity' or entity.type == 'tree' then
|
||||
--end
|
||||
entity.destroy()
|
||||
elseif (run_ores_module ~= nil and entity.type == 'resource') then
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
local top_left = area.left_top --make a more direct reference
|
||||
|
||||
--do it only per chunk, cause cheaper than every square, and who care anyway.
|
||||
--local distance_bonus = 200 + math.sqrt(top_left.x*top_left.x + top_left.y*top_left.y) * 0.2
|
||||
|
||||
--for x = 0, 31, 1 do
|
||||
-- for y = 0, 31, 1 do
|
||||
|
||||
--game.print(top_left.x .."-" ..top_left.y .. " to " .. area.right_bottom.x .. "-" .. area.right_bottom.y)
|
||||
|
||||
for x = top_left.x - 1, top_left.x + 32 do
|
||||
for y = top_left.y - 1, top_left.y + 32 do
|
||||
--local pos_x = top_left.x + x
|
||||
--local pos_y = top_left.y + y
|
||||
local tile = surface.get_tile(x, y)
|
||||
|
||||
if tile.name ~= 'out-of-map' then
|
||||
local tile_to_insert = 'grass-3'
|
||||
|
||||
local wiggle = 50 + perlin.noise((x * 0.005), (y * 0.005), global.terrain_seed_A + 71) * 60
|
||||
local terrain_A = perlin.noise((x * 0.005), (y * 0.005), global.terrain_seed_A + 19) * wiggle --For determining where water is
|
||||
local terrain_sqr = terrain_A * terrain_A --we can use this again to mess with other layers as well
|
||||
local terrain_D = 10 + perlin.noise((x * 0.001), (y * 0.001), global.terrain_seed_A + 5) * wiggle --terrain layer
|
||||
|
||||
--local wiggle = 50 + Simplex.d2((x*0.005),(y*0.005),global.terrain_seed_A + 71) * 60
|
||||
--local terrain_A = Simplex.d2((x*0.005),(y*0.005),global.terrain_seed_A + 19) * wiggle --For determining where water is
|
||||
--local terrain_sqr = terrain_A * terrain_A --we can use this again to mess with other layers as well
|
||||
--local terrain_D = 10 + Simplex.d2((x*0.001),(y*0.001),global.terrain_seed_A + 5) * wiggle --terrain layer
|
||||
|
||||
if terrain_sqr < 50 then --Main water areas
|
||||
--local deep = (terrain_sqr < 20) and true or false
|
||||
terrain_A = perlin.noise((x * 0.01), (y * 0.01), global.terrain_seed_A + 31) * 90 + (wiggle * -0.2) --we only gen this when we consider placing water
|
||||
--terrain_A = Simplex.d2((x*0.01),(y*0.01),global.terrain_seed_A + 31) * 90 + (wiggle * -0.2) --we only gen this when we consider placing water
|
||||
|
||||
if terrain_A * terrain_A > 40 then --creates random bridges over the water by overlapping with another noise layer
|
||||
--table.insert(tileswater, {name = "water", position = {x,y}})
|
||||
--table.insert(tileswater, {name = "water", position = {x+1,y}})
|
||||
--table.insert(tileswater, {name = "water", position = {x,y+1}})
|
||||
--table.insert(tileswater, {name = "water", position = {x+1,y+1}})
|
||||
tile_to_insert = 'water'
|
||||
else
|
||||
if terrain_D >= 20 then
|
||||
tile_to_insert = 'sand-1'
|
||||
end
|
||||
end
|
||||
elseif terrain_sqr > 70 then
|
||||
wiggle = 100 + perlin.noise((x * 0.01), (y * 0.01), global.terrain_seed_B + 41) * 60
|
||||
local terrain_C = perlin.noise((x * 0.02), (y * 0.02), global.terrain_seed_A + 13) * wiggle --tree layer
|
||||
|
||||
--wiggle = 100 + Simplex.d2((x*0.01),(y*0.01),global.terrain_seed_B + 41) * 60
|
||||
--local terrain_C = Simplex.d2((x*0.02),(y*0.02),global.terrain_seed_A + 13) * wiggle --tree layer
|
||||
|
||||
--if surface.can_place_entity {name="stone", position={x,y}} then
|
||||
-- surface.create_entity {name="stone", position={x,y}, amount=math.floor(terrain_sqr)}
|
||||
--end
|
||||
|
||||
if run_ores_module ~= nil then
|
||||
run_ores_module_setup()
|
||||
if x > top_left.x - 1 and x < top_left.x + 32 and y > top_left.y - 1 and y < top_left.y + 32 then
|
||||
run_ores_module_tile(surface, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
--if terrain_B > 35 then --we place ores
|
||||
-- local a = 5
|
||||
--
|
||||
-- if terrain_B < 76 then a = math.floor(terrain_B*0.75 + terrain_C*0.5) % 4 + 1 end --if its not super high we place normal ores
|
||||
--
|
||||
-- local res_amount = distance_bonus + terrain_sqr * 0.1
|
||||
-- res_amount = math.floor(res_amount * random_dense[a])
|
||||
--
|
||||
-- if surface.can_place_entity {name=random_ores[a], position={pos_x,pos_y}} then
|
||||
-- surface.create_entity {name=random_ores[a], position={pos_x,pos_y}, amount=res_amount}
|
||||
-- end
|
||||
--end
|
||||
|
||||
--wiggle = 100 + perlin.noise((pos_x*0.02),(pos_y*0.02),global.terrain_seed_B + 71) * 60
|
||||
|
||||
if terrain_D < 20 then
|
||||
if terrain_C < 4 then --we set grass-1 around near forest areas
|
||||
tile_to_insert = 'grass-1'
|
||||
|
||||
if terrain_C < -20 and math.random(1, 3) == 1 then --dense trees
|
||||
local treenum = math.random(3, 7)
|
||||
if surface.can_place_entity {name = tree_to_place[treenum], position = {x, y}} then
|
||||
surface.create_entity {name = tree_to_place[treenum], position = {x, y}}
|
||||
end
|
||||
else
|
||||
if terrain_C < 0 and math.random(1, 7) == 1 then --less dense trees
|
||||
local treenum = math.random(3, 5)
|
||||
if surface.can_place_entity {name = tree_to_place[treenum], position = {x, y}} then
|
||||
surface.create_entity {name = tree_to_place[treenum], position = {x, y}}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if terrain_D < 30 then
|
||||
tile_to_insert = 'sand-1'
|
||||
|
||||
if terrain_C < -20 and math.random(1, 7) == 1 then --dense trees
|
||||
local treenum = math.random(1, 3)
|
||||
if surface.can_place_entity {name = tree_to_place[treenum], position = {x, y}} then
|
||||
surface.create_entity {name = tree_to_place[treenum], position = {x, y}}
|
||||
end
|
||||
elseif terrain_C < 0 and math.random(1, 13) == 1 then --less dense trees
|
||||
local treenum = math.random(1, 2)
|
||||
if surface.can_place_entity {name = tree_to_place[treenum], position = {x, y}} then
|
||||
surface.create_entity {name = tree_to_place[treenum], position = {x, y}}
|
||||
end
|
||||
end
|
||||
else
|
||||
--if terrain_C > 40 and math.random(1,200) == 1 and surface.can_place_entity {name="crude-oil", position={pos_x,pos_y}} then
|
||||
-- surface.create_entity {name="crude-oil", position={pos_x,pos_y}, amount = math.random(20000,60000) +distance_bonus* 2000 }
|
||||
--end
|
||||
tile_to_insert = 'sand-3'
|
||||
end
|
||||
end
|
||||
|
||||
if
|
||||
math.floor(terrain_D) % 5 == 1 and math.random(1, 70) == 1 and
|
||||
surface.can_place_entity {name = 'rock-big', position = {x, y}}
|
||||
then
|
||||
surface.create_entity {name = 'rock-big', position = {x, y}}
|
||||
end
|
||||
else
|
||||
if terrain_D >= 20 then
|
||||
if terrain_D < 30 then
|
||||
tile_to_insert = 'sand-1'
|
||||
else
|
||||
tile_to_insert = 'sand-3'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--if tile_to_insert == "water" then
|
||||
--table.insert(tileswater, {name = tile_to_insert, position = {x,y}})
|
||||
--else
|
||||
table.insert(tiles, {name = tile_to_insert, position = {x, y}})
|
||||
--end
|
||||
end
|
||||
end
|
||||
end
|
||||
--game.print("break end")
|
||||
--game.print(lowest .. " to " .. highest)
|
||||
|
||||
surface.set_tiles(tiles, true)
|
||||
--surface.set_tiles(tileswater,true)
|
||||
end
|
||||
local perlin = require 'map_gen.shared.perlin_noise'
|
||||
local simplex = require 'map_gen.shared.simplex_noise'
|
||||
|
||||
local tree_to_place = {'dry-tree', 'dry-hairy-tree', 'tree-06', 'tree-06', 'tree-01', 'tree-02', 'tree-03'}
|
||||
|
||||
function run_terrain_module(event)
|
||||
if not global.terrain_seed_A then
|
||||
global.terrain_seed_A = math.random(10, 10000)
|
||||
end
|
||||
if not global.terrain_seed_B then
|
||||
global.terrain_seed_B = math.random(10, 10000)
|
||||
end
|
||||
|
||||
local area = event.area
|
||||
local surface = event.surface
|
||||
local tiles = {}
|
||||
local tileswater = {}
|
||||
|
||||
local entities = surface.find_entities(area)
|
||||
for _, entity in pairs(entities) do
|
||||
--if entity.type == "simple-entity" or entity.type == "resource" or entity.type == "tree" then
|
||||
if entity.type == 'simple-entity' or entity.type == 'tree' then
|
||||
--end
|
||||
entity.destroy()
|
||||
elseif (run_ores_module ~= nil and entity.type == 'resource') then
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
local top_left = area.left_top --make a more direct reference
|
||||
|
||||
--do it only per chunk, cause cheaper than every square, and who care anyway.
|
||||
--local distance_bonus = 200 + math.sqrt(top_left.x*top_left.x + top_left.y*top_left.y) * 0.2
|
||||
|
||||
--for x = 0, 31, 1 do
|
||||
-- for y = 0, 31, 1 do
|
||||
|
||||
--game.print(top_left.x .."-" ..top_left.y .. " to " .. area.right_bottom.x .. "-" .. area.right_bottom.y)
|
||||
|
||||
for x = top_left.x - 1, top_left.x + 32 do
|
||||
for y = top_left.y - 1, top_left.y + 32 do
|
||||
--local pos_x = top_left.x + x
|
||||
--local pos_y = top_left.y + y
|
||||
local tile = surface.get_tile(x, y)
|
||||
|
||||
if tile.name ~= 'out-of-map' then
|
||||
local tile_to_insert = 'grass-3'
|
||||
|
||||
local wiggle = 50 + perlin.noise((x * 0.005), (y * 0.005), global.terrain_seed_A + 71) * 60
|
||||
local terrain_A = perlin.noise((x * 0.005), (y * 0.005), global.terrain_seed_A + 19) * wiggle --For determining where water is
|
||||
local terrain_sqr = terrain_A * terrain_A --we can use this again to mess with other layers as well
|
||||
local terrain_D = 10 + perlin.noise((x * 0.001), (y * 0.001), global.terrain_seed_A + 5) * wiggle --terrain layer
|
||||
|
||||
--local wiggle = 50 + Simplex.d2((x*0.005),(y*0.005),global.terrain_seed_A + 71) * 60
|
||||
--local terrain_A = Simplex.d2((x*0.005),(y*0.005),global.terrain_seed_A + 19) * wiggle --For determining where water is
|
||||
--local terrain_sqr = terrain_A * terrain_A --we can use this again to mess with other layers as well
|
||||
--local terrain_D = 10 + Simplex.d2((x*0.001),(y*0.001),global.terrain_seed_A + 5) * wiggle --terrain layer
|
||||
|
||||
if terrain_sqr < 50 then --Main water areas
|
||||
--local deep = (terrain_sqr < 20) and true or false
|
||||
terrain_A = perlin.noise((x * 0.01), (y * 0.01), global.terrain_seed_A + 31) * 90 + (wiggle * -0.2) --we only gen this when we consider placing water
|
||||
--terrain_A = Simplex.d2((x*0.01),(y*0.01),global.terrain_seed_A + 31) * 90 + (wiggle * -0.2) --we only gen this when we consider placing water
|
||||
|
||||
if terrain_A * terrain_A > 40 then --creates random bridges over the water by overlapping with another noise layer
|
||||
--table.insert(tileswater, {name = "water", position = {x,y}})
|
||||
--table.insert(tileswater, {name = "water", position = {x+1,y}})
|
||||
--table.insert(tileswater, {name = "water", position = {x,y+1}})
|
||||
--table.insert(tileswater, {name = "water", position = {x+1,y+1}})
|
||||
tile_to_insert = 'water'
|
||||
else
|
||||
if terrain_D >= 20 then
|
||||
tile_to_insert = 'sand-1'
|
||||
end
|
||||
end
|
||||
elseif terrain_sqr > 70 then
|
||||
wiggle = 100 + perlin.noise((x * 0.01), (y * 0.01), global.terrain_seed_B + 41) * 60
|
||||
local terrain_C = perlin.noise((x * 0.02), (y * 0.02), global.terrain_seed_A + 13) * wiggle --tree layer
|
||||
|
||||
--wiggle = 100 + Simplex.d2((x*0.01),(y*0.01),global.terrain_seed_B + 41) * 60
|
||||
--local terrain_C = Simplex.d2((x*0.02),(y*0.02),global.terrain_seed_A + 13) * wiggle --tree layer
|
||||
|
||||
--if surface.can_place_entity {name="stone", position={x,y}} then
|
||||
-- surface.create_entity {name="stone", position={x,y}, amount=math.floor(terrain_sqr)}
|
||||
--end
|
||||
|
||||
if run_ores_module ~= nil then
|
||||
run_ores_module_setup()
|
||||
if x > top_left.x - 1 and x < top_left.x + 32 and y > top_left.y - 1 and y < top_left.y + 32 then
|
||||
run_ores_module_tile(surface, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
--if terrain_B > 35 then --we place ores
|
||||
-- local a = 5
|
||||
--
|
||||
-- if terrain_B < 76 then a = math.floor(terrain_B*0.75 + terrain_C*0.5) % 4 + 1 end --if its not super high we place normal ores
|
||||
--
|
||||
-- local res_amount = distance_bonus + terrain_sqr * 0.1
|
||||
-- res_amount = math.floor(res_amount * random_dense[a])
|
||||
--
|
||||
-- if surface.can_place_entity {name=random_ores[a], position={pos_x,pos_y}} then
|
||||
-- surface.create_entity {name=random_ores[a], position={pos_x,pos_y}, amount=res_amount}
|
||||
-- end
|
||||
--end
|
||||
|
||||
--wiggle = 100 + perlin.noise((pos_x*0.02),(pos_y*0.02),global.terrain_seed_B + 71) * 60
|
||||
|
||||
if terrain_D < 20 then
|
||||
if terrain_C < 4 then --we set grass-1 around near forest areas
|
||||
tile_to_insert = 'grass-1'
|
||||
|
||||
if terrain_C < -20 and math.random(1, 3) == 1 then --dense trees
|
||||
local treenum = math.random(3, 7)
|
||||
if surface.can_place_entity {name = tree_to_place[treenum], position = {x, y}} then
|
||||
surface.create_entity {name = tree_to_place[treenum], position = {x, y}}
|
||||
end
|
||||
else
|
||||
if terrain_C < 0 and math.random(1, 7) == 1 then --less dense trees
|
||||
local treenum = math.random(3, 5)
|
||||
if surface.can_place_entity {name = tree_to_place[treenum], position = {x, y}} then
|
||||
surface.create_entity {name = tree_to_place[treenum], position = {x, y}}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if terrain_D < 30 then
|
||||
tile_to_insert = 'sand-1'
|
||||
|
||||
if terrain_C < -20 and math.random(1, 7) == 1 then --dense trees
|
||||
local treenum = math.random(1, 3)
|
||||
if surface.can_place_entity {name = tree_to_place[treenum], position = {x, y}} then
|
||||
surface.create_entity {name = tree_to_place[treenum], position = {x, y}}
|
||||
end
|
||||
elseif terrain_C < 0 and math.random(1, 13) == 1 then --less dense trees
|
||||
local treenum = math.random(1, 2)
|
||||
if surface.can_place_entity {name = tree_to_place[treenum], position = {x, y}} then
|
||||
surface.create_entity {name = tree_to_place[treenum], position = {x, y}}
|
||||
end
|
||||
end
|
||||
else
|
||||
--if terrain_C > 40 and math.random(1,200) == 1 and surface.can_place_entity {name="crude-oil", position={pos_x,pos_y}} then
|
||||
-- surface.create_entity {name="crude-oil", position={pos_x,pos_y}, amount = math.random(20000,60000) +distance_bonus* 2000 }
|
||||
--end
|
||||
tile_to_insert = 'sand-3'
|
||||
end
|
||||
end
|
||||
|
||||
if
|
||||
math.floor(terrain_D) % 5 == 1 and math.random(1, 70) == 1 and
|
||||
surface.can_place_entity {name = 'rock-big', position = {x, y}}
|
||||
then
|
||||
surface.create_entity {name = 'rock-big', position = {x, y}}
|
||||
end
|
||||
else
|
||||
if terrain_D >= 20 then
|
||||
if terrain_D < 30 then
|
||||
tile_to_insert = 'sand-1'
|
||||
else
|
||||
tile_to_insert = 'sand-3'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--if tile_to_insert == "water" then
|
||||
--table.insert(tileswater, {name = tile_to_insert, position = {x,y}})
|
||||
--else
|
||||
table.insert(tiles, {name = tile_to_insert, position = {x, y}})
|
||||
--end
|
||||
end
|
||||
end
|
||||
end
|
||||
--game.print("break end")
|
||||
--game.print(lowest .. " to " .. highest)
|
||||
|
||||
surface.set_tiles(tiles, true)
|
||||
--surface.set_tiles(tileswater,true)
|
||||
end
|
||||
|
314
utils/utils.lua
314
utils/utils.lua
@ -1,157 +1,157 @@
|
||||
local Module = {}
|
||||
local Game = require 'utils.game'
|
||||
local prefix = '## - '
|
||||
|
||||
Module.distance = function(pos1, pos2)
|
||||
local dx = pos2.x - pos1.x
|
||||
local dy = pos2.y - pos1.y
|
||||
return math.sqrt(dx * dx + dy * dy)
|
||||
end
|
||||
|
||||
Module.print_except = function(msg, player)
|
||||
for _, p in pairs(game.players) do
|
||||
if p.connected and p ~= player then
|
||||
p.print(msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a LuaPlayer or string as source
|
||||
Module.print_admins = function(msg, source)
|
||||
local source_name
|
||||
local chat_color
|
||||
if source then
|
||||
if type(source) == 'string' then
|
||||
source_name = source
|
||||
chat_colot = game.players[source].chat_color
|
||||
else
|
||||
source_name = source.name
|
||||
chat_color = source.chat_color
|
||||
end
|
||||
else
|
||||
source_name = "Server"
|
||||
chat_color = {r=255, g=255, b=255}
|
||||
end
|
||||
for _, p in pairs(game.connected_players) do
|
||||
if p.admin then
|
||||
p.print(string.format('%s(ADMIN) %s: %s', prefix, source_name, msg), chat_color)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Module.get_actor = function()
|
||||
if game.player then
|
||||
return game.player.name
|
||||
end
|
||||
return '<server>'
|
||||
end
|
||||
|
||||
Module.cast_bool = function(var)
|
||||
if var then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
Module.find_entities_by_last_user =
|
||||
function(player, surface, filters)
|
||||
if type(player) == 'string' or not player then
|
||||
error(
|
||||
"bad argument #1 to '" ..
|
||||
debug.getinfo(1, 'n').name .. "' (number or LuaPlayer expected, got " .. type(player) .. ')',
|
||||
1
|
||||
)
|
||||
return
|
||||
end
|
||||
if type(surface) ~= 'table' and type(surface) ~= 'number' then
|
||||
error(
|
||||
"bad argument #2 to '" ..
|
||||
debug.getinfo(1, 'n').name .. "' (number or LuaSurface expected, got " .. type(surface) .. ')',
|
||||
1
|
||||
)
|
||||
return
|
||||
end
|
||||
local entities = {}
|
||||
local surface = surface
|
||||
local player = player
|
||||
local filters = filters or {}
|
||||
if type(surface) == 'number' then
|
||||
surface = game.surfaces[surface]
|
||||
end
|
||||
if type(player) == 'number' then
|
||||
player = Game.get_player_by_index(player)
|
||||
end
|
||||
filters.force = player.force.name
|
||||
for _, e in pairs(surface.find_entities_filtered(filters)) do
|
||||
if e.last_user == player then
|
||||
table.insert(entities, e)
|
||||
end
|
||||
end
|
||||
return entities
|
||||
end
|
||||
|
||||
Module.ternary = function(c, t, f)
|
||||
if c then
|
||||
return t
|
||||
else
|
||||
return f
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local minutes_to_ticks = 60 * 60
|
||||
local hours_to_ticks = 60 * 60 * 60
|
||||
local ticks_to_minutes = 1 / minutes_to_ticks
|
||||
local ticks_to_hours = 1 / hours_to_ticks
|
||||
Module.format_time = function(ticks)
|
||||
local result = {}
|
||||
|
||||
local hours = math.floor(ticks * ticks_to_hours)
|
||||
if hours > 0 then
|
||||
ticks = ticks - hours * hours_to_ticks
|
||||
table.insert(result, hours)
|
||||
if hours == 1 then
|
||||
table.insert(result, 'hour')
|
||||
else
|
||||
table.insert(result, 'hours')
|
||||
end
|
||||
end
|
||||
|
||||
local minutes = math.floor(ticks * ticks_to_minutes)
|
||||
table.insert(result, minutes)
|
||||
if minutes == 1 then
|
||||
table.insert(result, 'minute')
|
||||
else
|
||||
table.insert(result, 'minutes')
|
||||
end
|
||||
|
||||
return table.concat(result, ' ')
|
||||
end
|
||||
|
||||
Module.cant_run = function(name)
|
||||
Game.player_print("Can't run command (" .. name .. ') - insufficient permission.')
|
||||
end
|
||||
|
||||
Module.log_command = function(user, command, parameters)
|
||||
local name
|
||||
|
||||
-- We can use a LuaPlayer or a string (ex. "Server").
|
||||
if type(user) == 'string' then
|
||||
name = user
|
||||
else
|
||||
name = user.name
|
||||
end
|
||||
local action = table.concat {'[Admin-Command] ', name, ' used: ', command}
|
||||
if parameters then
|
||||
action = table.concat {'[Admin-Command] ', name, ' used: ', command, ' ', parameters}
|
||||
end
|
||||
log(action)
|
||||
end
|
||||
|
||||
Module.comma_value = function(n) -- credit http://richard.warburton.it
|
||||
local left,num,right = string.match(n, '^([^%d]*%d)(%d*)(.-)$')
|
||||
return left .. (num:reverse():gsub('(%d%d%d)', '%1,'):reverse()) .. right
|
||||
end
|
||||
|
||||
return Module
|
||||
local Module = {}
|
||||
local Game = require 'utils.game'
|
||||
local prefix = '## - '
|
||||
|
||||
Module.distance = function(pos1, pos2)
|
||||
local dx = pos2.x - pos1.x
|
||||
local dy = pos2.y - pos1.y
|
||||
return math.sqrt(dx * dx + dy * dy)
|
||||
end
|
||||
|
||||
Module.print_except = function(msg, player)
|
||||
for _, p in pairs(game.players) do
|
||||
if p.connected and p ~= player then
|
||||
p.print(msg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a LuaPlayer or string as source
|
||||
Module.print_admins = function(msg, source)
|
||||
local source_name
|
||||
local chat_color
|
||||
if source then
|
||||
if type(source) == 'string' then
|
||||
source_name = source
|
||||
chat_colot = game.players[source].chat_color
|
||||
else
|
||||
source_name = source.name
|
||||
chat_color = source.chat_color
|
||||
end
|
||||
else
|
||||
source_name = "Server"
|
||||
chat_color = {r=255, g=255, b=255}
|
||||
end
|
||||
for _, p in pairs(game.connected_players) do
|
||||
if p.admin then
|
||||
p.print(string.format('%s(ADMIN) %s: %s', prefix, source_name, msg), chat_color)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Module.get_actor = function()
|
||||
if game.player then
|
||||
return game.player.name
|
||||
end
|
||||
return '<server>'
|
||||
end
|
||||
|
||||
Module.cast_bool = function(var)
|
||||
if var then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
Module.find_entities_by_last_user =
|
||||
function(player, surface, filters)
|
||||
if type(player) == 'string' or not player then
|
||||
error(
|
||||
"bad argument #1 to '" ..
|
||||
debug.getinfo(1, 'n').name .. "' (number or LuaPlayer expected, got " .. type(player) .. ')',
|
||||
1
|
||||
)
|
||||
return
|
||||
end
|
||||
if type(surface) ~= 'table' and type(surface) ~= 'number' then
|
||||
error(
|
||||
"bad argument #2 to '" ..
|
||||
debug.getinfo(1, 'n').name .. "' (number or LuaSurface expected, got " .. type(surface) .. ')',
|
||||
1
|
||||
)
|
||||
return
|
||||
end
|
||||
local entities = {}
|
||||
local surface = surface
|
||||
local player = player
|
||||
local filters = filters or {}
|
||||
if type(surface) == 'number' then
|
||||
surface = game.surfaces[surface]
|
||||
end
|
||||
if type(player) == 'number' then
|
||||
player = Game.get_player_by_index(player)
|
||||
end
|
||||
filters.force = player.force.name
|
||||
for _, e in pairs(surface.find_entities_filtered(filters)) do
|
||||
if e.last_user == player then
|
||||
table.insert(entities, e)
|
||||
end
|
||||
end
|
||||
return entities
|
||||
end
|
||||
|
||||
Module.ternary = function(c, t, f)
|
||||
if c then
|
||||
return t
|
||||
else
|
||||
return f
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local minutes_to_ticks = 60 * 60
|
||||
local hours_to_ticks = 60 * 60 * 60
|
||||
local ticks_to_minutes = 1 / minutes_to_ticks
|
||||
local ticks_to_hours = 1 / hours_to_ticks
|
||||
Module.format_time = function(ticks)
|
||||
local result = {}
|
||||
|
||||
local hours = math.floor(ticks * ticks_to_hours)
|
||||
if hours > 0 then
|
||||
ticks = ticks - hours * hours_to_ticks
|
||||
table.insert(result, hours)
|
||||
if hours == 1 then
|
||||
table.insert(result, 'hour')
|
||||
else
|
||||
table.insert(result, 'hours')
|
||||
end
|
||||
end
|
||||
|
||||
local minutes = math.floor(ticks * ticks_to_minutes)
|
||||
table.insert(result, minutes)
|
||||
if minutes == 1 then
|
||||
table.insert(result, 'minute')
|
||||
else
|
||||
table.insert(result, 'minutes')
|
||||
end
|
||||
|
||||
return table.concat(result, ' ')
|
||||
end
|
||||
|
||||
Module.cant_run = function(name)
|
||||
Game.player_print("Can't run command (" .. name .. ') - insufficient permission.')
|
||||
end
|
||||
|
||||
Module.log_command = function(user, command, parameters)
|
||||
local name
|
||||
|
||||
-- We can use a LuaPlayer or a string (ex. "Server").
|
||||
if type(user) == 'string' then
|
||||
name = user
|
||||
else
|
||||
name = user.name
|
||||
end
|
||||
local action = table.concat {'[Admin-Command] ', name, ' used: ', command}
|
||||
if parameters then
|
||||
action = table.concat {'[Admin-Command] ', name, ' used: ', command, ' ', parameters}
|
||||
end
|
||||
log(action)
|
||||
end
|
||||
|
||||
Module.comma_value = function(n) -- credit http://richard.warburton.it
|
||||
local left,num,right = string.match(n, '^([^%d]*%d)(%d*)(.-)$')
|
||||
return left .. (num:reverse():gsub('(%d%d%d)', '%1,'):reverse()) .. right
|
||||
end
|
||||
|
||||
return Module
|
||||
|
Loading…
x
Reference in New Issue
Block a user