init the game using the mientest minimal sub nasa as base, remove rspawn

* removed rspawn cos we will use a large area of spawn with resourses
* the new spawn will be spawnrand cos must be simple and faster in a limited area
* also no protection.. no houses no home.. user must survice with a bag
master
mckaygerhard 2023-01-10 17:53:55 -04:00
parent 05b69630e5
commit b07959331e
17 changed files with 15 additions and 1471 deletions

View File

@ -1,22 +1,10 @@
# infinite subnasa game play manifiesto
# infinite NSSG game play manifiesto
The subnasa game is the lag-free most faster subgame in minetest!
The NSSG game is the most harder to play
## Information
The **only hostile element is the players themselves** and the thrill is **teamwork**.
The subnasa has as a **priority that many enter and that there is a danger of interference**,
for this the trick is to provide an **easy environment and without hostile entities, easy to access**,
this will attract many inexperienced players which will fill the server, this will allow
that in the face of the danger of **other players interfering** with your things, **you have to live in groups**,
as well as **hide**, which will make everyone think about how to defend themselves, which cannot be done alone..
This premise means that mods like `mobs_monster` or `dmobs` do not exist, but if `mobs_animals`,
which means for example that there are no armor or special biomes, but many houses and decoration,
Additionally, for optimization reasons things like `unified_inventory` are not included but
if things like `prestibags` and `ambience` are included, because the game must load on phones,
phone memory is sometimes not large and mods like `nssm` involve a lot of data to deal with.
Take a breath before play, you will need!
## Introduction
---------------

View File

@ -1,22 +1,10 @@
# juego subnasa infinito manifiesto
# juego NSSM infinito manifiesto
¡El juego subnasa es el subjuego más rápido sin lag en minetest!
¡El juego NSSM es el subjuego más dificil
## Informacion
El **unico elemento hostil son los jugadores mismos** y la emocion es el **trabajo en equipo**.
El subnasa tiene como **prioridad que muchos entren y que exista el peligro de interferencias**,
para ello el truco es proveer un **entorno facil y sin entidades hostiles, facil de acceder**,
esto atraera a muchos jugadores inexpertos lo que llenara el servidor, esto permitira
que ante el peligro de que **otros jugadores interfieran** con tus cosas, **tengas que convivir en grupos**,
asi como **esconderse**, lo que hara que entre todos piensen como defenderse lo cual no se puede solo..
Esta premisa hace que mods como `mobs_monster` o `dmobs` no existan, pero si `mobs_animals`,
lo que significa por ejemplo que no hay armaduras ni biomas especiales, pero si muchas casas y decoracion,
adicional, por razones de optimizacion no se incluyen cosas como `unified_inventory` pero
si se incluyen cosas como `prestibags` y `ambience`, porque el juego debe cargar en telefonos,
la memoria de los telefonos a veces no es grande y mods como `nssm` implican muchos datos que manejar.
Toma un respiro antes de jugar, lo necesitaras
## Introducción
---------------

View File

@ -1,23 +1,11 @@
# бесконечный манифест игры subnasa
# бесконечный манифест игры NSSM
Игра subnasa - самая быстрая под-игра без задержек в minetest!
Игра NSSM - самая быстрая под-игра без задержек в minetest!
## Информация
**Единственный враждебный элемент — это сами игроки**, а острые ощущения — **командная работа**.
Субназа имеет **приоритет, что многие входят и что существует опасность вмешательства**,
для этого хитрость заключается в том, чтобы обеспечить **простую среду без враждебных сущностей, легкий доступ**,
это привлечет много неопытных игроков, которые заполнят сервер, это позволит
что перед лицом опасности вмешательства **других игроков** в ваши вещи **вы должны жить группами**,
а также **спрятаться**, что заставит всех задуматься о том, как защитить себя, что невозможно сделать в одиночку..
Эта предпосылка означает, что такие моды, как `mobs_monster` или `dmobs`, не существуют, но если `mobs_animals`,
что означает, например, что нет брони или особых биомов, но много домов и украшений,
Кроме того, по причинам оптимизации такие вещи, как `unified_inventory`, не включены, но
если включены такие вещи, как `prestibags` и `ambience`, потому что игра должна загружаться на телефоны,
Память телефона иногда невелика, и такие моды, как `nssm`, требуют обработки большого количества данных.
## Введение
---------------

View File

@ -1,6 +1,6 @@
# Minetest sub.nasa-g0v games
# Minetest Not So Simple Game
The vanilla anarchic famous server game
The most increible vaste enemy provided game to play and hard to defeats
* English information: [GAMEINFO-en.md](GAMEINFO-en.md), **WARNING: if you question why there is no mod "x" instead of mod "y" read the information file in the initial section **
* Informacion español: [GAMEINFO-es.md](GAMEINFO-es.md), **ADVERTENCIA: si se cuestiona porque no esta el mod "x" en vez de el mod "y" lease el archivo de informacion en la seccion inicial**
@ -8,13 +8,13 @@ The vanilla anarchic famous server game
![screenshot.png](screenshot.png)
For further information, check https://codeberg.org/minenux/minetest-game-subnasa.git or https://gitlab.com/minenux/minetest-game-subnasa
For further information, check https://codeberg.org/minenux/minetest-game-nssg.git or https://gitlab.com/minenux/minetest-game-nssg
## Installation
For specific minetest installation check [docs/INSTALL.md](docs/INSTALL.md)
- Unzip the archive, rename the folder to `subnasa` and
- Unzip the archive, rename the folder to `nssg` and
place it in .. `minetest/games/`
- GNU/Linux: If you use a system-wide installation place
@ -22,18 +22,14 @@ it in `~/.minetest/games/` or `/usr/share/games/minetest`.
## Compatibility
The Minetest subnasa Game GitHub master HEAD is only compatible with minetest4 engine
that can be found at https://codeberg.org/minenux/minetest-engine/src/branch/stable-4.0
The Minetest nssg Game GitHub master HEAD is compatible with MT 0.4.16, 4.0, 5.2 and 5.4
that can be found at https://minetest.io
It may work with the older minetest 0.4.17.1 inclusivelly 0.4.16 but is not guarantee.
To download you can play this game with the following minetest engines:
* https://codeberg.org/minenux/minetest-engine-minetest/src/branch/stable-4.1
* https://codeberg.org/minenux/minetest-engine-minetest/src/branch/stable-4.0
* https://codeberg.org/minenux/minetest-engine-multicraft/tag/v1.10.0
* https://codeberg.org/minenux/minetest-engine-multicraft/tag/v1.11.0
* https://github.com/minenux/minetest-engine-luk3yx/tree/stable-4.1
* https://github.com/MultiCraft/MultiCraft-legacy/releases/tag/v1.10.0
* https://codeberg.org/minenux/minetest-engine-minetest/src/branch/stable-5.X
#### Mods
@ -41,8 +37,6 @@ To download you can play this game with the following minetest engines:
* sorceredkid auth mod
* minetest Auth Redux as `auth_rx` [mods/auth_rx](mods/auth_rx) from https://codeberg.org/minenux/minetest-mod-auth_rx
* so then minetest Formspecs as `formspecs` [mods/formspecs](mods/formspecs) from https://codeberg.org/minenux/minetest-mod-formspecs
* minetest Random Spawn as `rspawn` [mods/rspawn](mods/rspawn) from https://codeberg.org/minenux/minetest-mod-rspawn
* so then default beds as `beds` [mods/beds](mods/beds) from default 0.4
* minetest floatlands as `floatlands` [mods/floatlands](mods/floatlands) derived from Floatlands Realm made to this servers, as https://codeberg.org/minenux/minetest-mod-floatland
* so then default flowers as `flowers` are need. Later this will need ethereal modifications.
* tenplus1 customized mods

View File

@ -1,166 +0,0 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -1,147 +0,0 @@
minetest mod rspawn
===================
Randomized Spawning for Minetest
Information
-----------
This mod its named `rspawn` , it causes players to receive a spawn point anywhere on the map.
Players will likely spawn very far from eachother into prisitine areas.
### Features
* Player is assigned randomized spawnpoint on joining
* New players will not spawn into protected areas
* Player will respawn at their spawnpoint if they die.
* If `beds` spawning is active, then beds can be used to set players' re-spawn point (they still go to their main spawnpoint on invoking `/spawn`).
* Commands
* Players can return to their spawn point with the `/spawn` command if they have `spawn` privilege.
* Players can invite other players to join their spawn - see "Spawn guests" below
* Players can allow any other player to visit their spawn - see "Town hosting" below
* Players can request a new spawn point by typing `/newspawn` if they have the `newspawn` privilege.
* Players can set their spawn point by typing `/setspawn` if they have the `setspawn` privelege.
* Moderator players can assign a new random spawn for another player using `/playerspawn` if they have the `spawnadmin` privilege.
KNOWN ISSUE - Any player not yet registered with a spawn point will be given a spawn point anywhere in the world. If applying retroactively to a server, this will cause existing players to be re-spawned once.
##### Spawn guests
Randomized spawning typically causes players to spawn far from eachother. If players wish to share a single spawn point, a player can add another to join their spawn position.
The player issuing the invite (host) must typically pay a levvy when adding another player.
* `/spawn add <player>` - allow another player to visit your spawn directly (levvy must be paid), or lift their exile (no levvy to pay)
* `/spawn kick <targetplayer>`
* revoke rights to visit you
* if the exiled player gets close to your spawn, they are kicked back to their own spawn
* `/spawn visit <player>` - visit a player's spawn
* `/spawn guests` - see who you have added to your spawn
* `/spawn hosts` - see whose spawns you may visit
Guests can help the spawn owner manage bans on their town.
##### Town hosting
You can host a town from your spawn if you wish. Hosting a town means that any player who connects to the server will be able to visit your spawn. You can still `/spawn kick <playername>` individually in this mode. If you switch off town hosting, only allowed guests in your normal guestlist can visit.
There is no levvy on hosting a town.
* `/spawn town { open | close }` - switch town hosting on or off.
* `/spawn town { ban | unban } <playername> [<town>]` - ban or unban a player from a town
* Town owners can use this, as well as unexiled guests of the town owner
Explicit guests can ban/unban other players from a town.
Town owner can forcibly ban a player by first adding the player to their guest list, and then exiling them. Guests cannot override this.
Techincal information
------------------------
Note that the spawn generation is performed in the background on a timer, allowing storing a collection of random spawn points to be generated ahead of time.
### Configuration
##### Generic settings used
* `name` - used for knowing the server admin's name
* `water_level` - Spawns are always set above water level, default `1`
* `static_spawnpoint` - main position the player will start at, default `{0,0,0}`
* `enable_bed_respawn` - from `beds` mod - if active, then respawning will happen at beds, instead of randomized spawnpoint
##### rspawn-specific settings
* Settings related to spawn generation
* `rspawn.max_pregen` - maximum number of spawn points to pre-generate, default `20`
* `rspawn.search_radius` - lateral radius around random point, within which a spawn point will be sought, default `32`
* `rspawn.gen_frequency` - how frequently (in seconds) to generate a new spawn point, default `30`, increase this on slower servers
* `rspawn.spawn_anywhere` - whether to spawn anywhere in the world at sea level (limited by the bounds spawn limits, check below)
if false, only spawns at a fixed spawn locaiton, for every player.
* if `true`, (default) spawns the player somewhere else on the map within valid air node and not inside solid block
* if `false`, will randomize around the static spawn point using search radius as maximun area for.
* `rspawn.cooldown_time` - how many seconds between two uses of `/newspawn`, per player
* `rspawn.kick_on_fail` - whether to kick the player if a randomized spawn cannot be set, default `false`
* `rspawn.spawn_block` - place this custom block under the user's spawn point
* Guestlist and town related settings
* `rspawn.levvy_name` - name of the block to use as levvy charge on the player issuing an invitation, default `default:cobble`
* `rspawn.levvy_qtty` - number of blocks to levvy from the player who issued the invitation, default `10`
* `rspawn.kick_period` - how frequently to check if exiled players are too near their locus of exile, default `3` (seconds)
* `rspawn.exile_distance` - distance from exile locus at which player gets bounced back to their own spawn, default `64` (nodes)
* `rspawn.debug` - whether to print debugging messages, default `false`
* Bounds limiting - you can limit the random spawning search area to a given subsection of the global map if you wish:
* `rspawn.min_x`, `rspawn.max_x`, `rspawn.min_z`, `rspawn.max_z` as expected
## Troubleshooting
As admin, you will receive notifications of inability to generate spawns when players join without being set a spawn. Those players will join but cannot play cos cannot spawn in a "valid spawn point".
If you only wants to solve it, just define a valid fixed spawn point with `static_spawnpoint` on your minetest.conf config file, then set `rspawn.gen_frequency` to a high number like 120 seconds or 300; warnings will continue but players will join and play (withou a spawn point set yet, take note).
If you are more hacker, you can turn on `rspawn.debug = true` to see debug in logs. Spawn generation uses a temporary forceload to read the blocks in the area ; it then releases the forceload after operating, so should not depend on the `max_forceloaded_blocks` setting.
If the generation log shows `0 air nodes found within <x>` on more than 2-3 consecutive tries, you may want to check that another mod is not forceloading blocks and then not subsequently clearing them, also try to reduce the bounds limits area of rspawn in settings, always around the fixed spawn point..
You may also find some mods do permanent forceloads by design (though this should be rare). In your world folder `~/.minetest/worlds/<yourworld>` there should eb a `force_loaded.txt` - see that its contents are simply `return {}`; if there is data in the table, then something else is forceloading blocks with permanence.
Resolutions in order of best to worst:
* Define a valid fixed spawn point with `static_spawnpoint` to be a valid air node and not a solid block
* then set `rspawn.gen_frequency` to a high number like 120 seconds or 300, and reduce the bounds limits.
* identify the mod and have it clear them properly (ideal)
* on UNIX/Linux you should be able to run `grep -rl forceload ~/.minetest/mods/` to see all mod files where forceloading is being done
* increase the max number of forceloaded blocks
* (not great - you will effectively be simply mitigating a forceloaded-blocks-related memory leak)
* Stop minetest, delete the `force_loaded.txt` file, and start it again
* (bad - some things in the mods using the forceload mechanism may break)
## Optimizations
It is also suitable for single player sessions too - if you want a new location to start a creative build, but don't need to go through creating another, separate world for it, just grab yourself a new spawnpoint!
On big multiplayers servers or small single players computers you may want to tune the mod.
#### For multiplayers big servers
* Define a valid fixed spawn point on your minetest.conf config file using the `static_spawnpoint` to a valid air node, not a solid block: it will be used if you do not want players to be kicked (by usage of `rspawn.kick_on_fail`) when there are no valid respawns points available.
* Bound limit must be little.. 400 nodes around is a number to play around. Do not set the `rspawn.search_radius` to a high number, 16 to 32 in big servers with big spawn random areas.
* Set `rspawn.gen_frequency` to a high number like 120 seconds or 300
* Change the Cooldown time - default is `300` seconds (5 minutes) between uses of `/newspawn`
#### Single Player Mode
* Add `rspawn` to your world
* Go to the *Advanced Settings* area of Minetest, look for `mods > rspawn`
* Change the frequency of pregeneration as required
* Good CPUs, enough RAM and SSD hard drives might get away with a frequency of 20sec (!)
* If you find your game immediately lagging due to excessive map generation, switch the frequency to say 120
* Change the Cooldown time - default is `300` seconds (5 minutes) between uses of `/newspawn`
* Optionally, change the maximum pregen to the desired number of spawnpoints to pregenerate and hold
* Start the game session; Wait around 1 minute or so as the initial spawn point gets generated and is assigned to you
* Jump around! (with `/newspawn`)
* Until you exhaust pregens :-P
## License
(C) 2017 Tai "DuCake" Kedzierski
Provided under the terms of the LGPL v3.0

View File

@ -1 +0,0 @@
beds?

View File

@ -1,249 +0,0 @@
rspawn = {}
rspawn.playerspawns = {}
local mpath = minetest.get_modpath("rspawn")
-- Water level, plus one to ensure we are above the sea.
local water_level = tonumber(minetest.settings:get("water_level", "0") )
local radial_step = 16
-- Setting with no namespace for interoperability
local static_spawnpoint = minetest.setting_get_pos("static_spawnpoint") or {x=0, y=0, z=0}
rspawn.admin = minetest.settings:get("name") or "" -- For messaging only
-- Setting from beds mod
rspawn.bedspawn = minetest.setting_getbool("enable_bed_respawn") ~= false -- from beds mod
-- rSpawn specific settings
rspawn.debug_on = minetest.settings:get_bool("rspawn.debug")
rspawn.spawnanywhere = minetest.settings:get_bool("rspawn.spawn_anywhere") ~= false
rspawn.kick_on_fail = minetest.settings:get_bool("rspawn.kick_on_fail") == true
rspawn.max_pregen_spawns = tonumber(minetest.settings:get("rspawn.max_pregen") or 5)
rspawn.search_radius = tonumber(minetest.settings:get("rspawn.search_radius") or 32)
rspawn.gen_frequency = tonumber(minetest.settings:get("rspawn.gen_frequency") or 30)
rspawn.spawn_block = minetest.settings:get("rspawn.spawn_block") or "default:dirt_with_grass"
rspawn.min_x = tonumber(minetest.settings:get("rspawn.min_x") or -31000)
rspawn.max_x = tonumber(minetest.settings:get("rspawn.max_x") or 31000)
rspawn.min_z = tonumber(minetest.settings:get("rspawn.min_z") or -31000)
rspawn.max_z = tonumber(minetest.settings:get("rspawn.max_z") or 31000)
dofile(mpath.."/lua/data.lua")
dofile(mpath.."/lua/guestlists.lua")
dofile(mpath.."/lua/commands.lua")
dofile(mpath.."/lua/forceload.lua")
dofile(mpath.."/lua/debugging.lua")
minetest.after(0,function()
if not minetest.registered_items[rspawn.spawn_block] then
rspawn.spawn_block = "default:dirt_with_grass"
end
end)
rspawn:spawnload()
local function set_default_node(pos)
if rspawn.spawn_block then
minetest.set_node(pos, {name=rspawn.spawn_block})
end
end
local function daylight_above(min_daylight, pos)
local level = minetest.get_node_light(pos, 0.5)
return min_daylight <= level
end
function rspawn:get_positions_for(pos, radius)
local breadth = radius
local altitude = water_level + radius
if rspawn.spawnanywhere then
altitude = radius
end
local pos1 = {x=pos.x-breadth, y=pos.y, z=pos.z-breadth}
local pos2 = {x=pos.x+breadth, y=pos.y+altitude, z=pos.z+breadth}
return pos1,pos2
end
function rspawn:newspawn(pos, radius)
-- Given a seed position and a radius, find an exact spawn location
-- that is an air node, walkable under it, non-walkable over it
-- bright during the day, and not leaves
rspawn:debug("Trying somewhere around "..minetest.pos_to_string(pos))
local pos1,pos2 = rspawn:get_positions_for(pos, radius)
rspawn:debug("Searching "..minetest.pos_to_string(pos1).." to "..minetest.pos_to_string(pos2))
local airnodes = minetest.find_nodes_in_area(pos1, pos2, {"air"})
local validnodes = {}
rspawn:debug("Found "..tostring(#airnodes).." air nodes within "..tostring(radius))
for _,anode in pairs(airnodes) do
local under = minetest.get_node( {x=anode.x, y=anode.y-1, z=anode.z} ).name
local over = minetest.get_node( {x=anode.x, y=anode.y+1, z=anode.z} ).name
under = minetest.registered_nodes[under]
over = minetest.registered_nodes[over]
if under == nil or over == nil then
-- `under` or `over` could be nil if a mod that defined that node was removed.
-- Not something this mod can resolve, and so we just ignore it.
rspawn:debug("Found an undefined node around "..minetest.pos_to_string(anode))
else
if under.walkable
and not over.walkable
and not minetest.is_protected(anode, "")
and not (under.groups and under.groups.leaves ) -- no spawning on treetops!
and daylight_above(7, anode) then
if under.buildable_to then
validnodes[#validnodes+1] = {x=anode.x, y=anode.y-1, z=anode.z}
else
validnodes[#validnodes+1] = anode
end
end
end
end
if #validnodes > 0 then
rspawn:debug("Valid spawn points found with radius "..tostring(radius))
local newpos = validnodes[math.random(1,#validnodes)]
return newpos
else
rspawn:debug("No valid air nodes")
end
end
function rspawn:genpos()
-- Generate a random position, and derive a new spawn position
local pos = static_spawnpoint
if rspawn.spawnanywhere then
pos = {
x = math.random(rspawn.min_x,rspawn.max_x),
y = water_level, -- always start at waterlevel
z = math.random(rspawn.min_z,rspawn.max_z),
}
end
return pos
end
function rspawn:set_player_spawn(name, newpos)
local tplayer = minetest.get_player_by_name(name)
if not tplayer then
return false
end
local spos = minetest.pos_to_string(newpos)
rspawn.debug("Saving spawn for "..name, spos)
rspawn.playerspawns[name] = newpos
rspawn:spawnsave()
minetest.chat_send_player(name, "New spawn set at "..spos)
tplayer:setpos(rspawn.playerspawns[name])
minetest.after(0.5,function()
set_default_node({x=newpos.x,y=newpos.y-1,z=newpos.z})
end)
return true
end
function rspawn:set_newplayer_spawn(player, attempts)
-- only use for new players / players who have never had a randomized spawn
if not player then return end
local playername = player:get_player_name()
if playername == "" then return end
if not rspawn.playerspawns[playername] then
local newpos = rspawn:get_next_spawn()
if newpos then
rspawn:set_player_spawn(playername, newpos)
else
-- We did not get a new position
if rspawn.kick_on_fail then
minetest.kick_player(playername, "No personalized spawn points available - please try again later.")
else
-- player just spawns (avoiting black screen) but still it not have spawn point assigned
if attempts <= 0 then
local fixedpos = rspawn:genpos()
fixedpos.y = water_level + rspawn.search_radius
player:setpos(fixedpos) -- player just spawns (avoiting black screen) but still it not have spawn point assigned
minetest.chat_send_player(rspawn.admin, "Exhausted spawns! just spawn "..playername.." without spawn point")
end
minetest.chat_send_player(playername, "Could not get custom spawn! Used fixed one and retrying in "..rspawn.gen_frequency.." seconds")
minetest.log("warning", "rspawn -- Exhausted spawns! Could not spawn "..playername.." so used fixed one")
minetest.after(rspawn.gen_frequency, function()
rspawn:set_newplayer_spawn(player, attempts-1)
end)
end
end
end
end
function rspawn:renew_player_spawn(playername)
local player = minetest.get_player_by_name(playername)
if not player then
return false
end
local newpos = rspawn:get_next_spawn()
if newpos then
return rspawn:set_player_spawn(playername, newpos)
else
minetest.chat_send_player(playername, "Could not get custom spawn!")
return false
end
end
minetest.register_on_joinplayer(function(player)
rspawn:set_newplayer_spawn(player, 5)
end)
minetest.register_on_respawnplayer(function(player)
-- return true to disable further respawn placement
local name = player:get_player_name()
if rspawn.bedspawn == true and beds.spawn then
local pos = beds.spawn[name]
if pos then
minetest.log("action", name.." respawns at "..minetest.pos_to_string(pos))
player:setpos(pos)
return true
end
end
local pos = rspawn.playerspawns[name]
-- And if no bed, nor bed spwawning not active:
if pos then
minetest.log("action", name.." respawns at "..minetest.pos_to_string(pos))
player:setpos(pos)
return true
else
minetest.chat_send_player(name, "Failed to find your spawn point!")
minetest.log("warning", "rspawn -- Could not find spawn point for "..name)
return false
end
end)
dofile(mpath.."/lua/pregeneration.lua")

View File

@ -1,164 +0,0 @@
local stepcount = 0
local newspawn_cooldown = {}
local cooldown_time = tonumber(minetest.settings:get("rspawn.cooldown_time")) or 300
-- Command privileges
minetest.register_privilege("spawn", "Can teleport to a spawn position and manage shared spawns.")
minetest.register_privilege("setspawn", "Can manually set a spawn point.")
minetest.register_privilege("newspawn", "Can get a new randomized spawn position.")
minetest.register_privilege("spawnadmin", "Can set new spawns for players.")
-- Support functions
local function request_new_spawn(username, targetname)
local timername = username
if targetname ~= username then
timername = username.." "..targetname
end
if not newspawn_cooldown[timername] then
if not rspawn:renew_player_spawn(targetname) then
minetest.chat_send_player(username, "Could not set new spawn for "..targetname)
return false
else
newspawn_cooldown[timername] = cooldown_time
return true
end
else
minetest.chat_send_player(username, tostring(math.ceil(newspawn_cooldown[timername])).."sec until you can randomize a new spawn for "..targetname)
return false
end
end
-- Commands
minetest.register_chatcommand("spawn", {
description = "Teleport to your spawn, or manage guests in your spawn.",
params = "[ add <player> | visit <player> | kick <player> | guests | hosts | town { open | close | ban <player> [<town>] | unban <player> [<town>] } ]",
privs = "spawn",
func = function(playername, args)
local target = rspawn.playerspawns[playername]
local args = args:split(" ", false, 1)
if #args == 0 then
if target then
minetest.get_player_by_name(playername):setpos(target)
return
else
minetest.chat_send_player(playername, "You have no spawn position!")
return
end
elseif #args < 4 then
for command,action in pairs({
["guests"] = function() rspawn.guestlists:listguests(playername) end,
["hosts"] = function() rspawn.guestlists:listhosts(playername) end,
["add"] = function(commandername,targetname) rspawn.guestlists:addplayer(commandername,targetname) end,
["visit"] = function(commandername,targetname) rspawn.guestlists:visitplayer(targetname, commandername) end,
["kick"] = function(commandername, params) rspawn.guestlists:kickplayer(commandername, params) end,
["town"] = function(commandername,mode) rspawn.guestlists:townset(commandername, mode) end,
}) do
if args[1] == command then
if #args == 2 then
action(playername, args[2])
return
elseif #args == 1 then
action(playername)
return
end
end
end
end
minetest.chat_send_player(playername, "Bad command. Please check '/help spawn'")
end
})
minetest.register_chatcommand("setspawn", {
description = "Assign current position as spawn position.",
params = "",
privs = "setspawn",
func = function(name)
rspawn.playerspawns[name] = minetest.get_player_by_name(name):getpos()
rspawn:spawnsave()
minetest.chat_send_player(name, "New spawn set !")
end
})
minetest.register_chatcommand("newspawn", {
description = "Randomly select a new spawn position.",
params = "",
privs = "newspawn",
func = function(name, args)
request_new_spawn(name, name)
end
})
minetest.register_chatcommand("playerspawn", {
description = "Randomly select a new spawn position for a player, or use specified position, or go to their spawn.",
params = "<playername> { new | <pos> | go }",
privs = "spawnadmin",
func = function(name, args)
if args ~= "" then
args = args:split(" ")
if #args == 2 then
local tname = args[1]
local tpos
if args[2] == "go" then
local user = minetest.get_player_by_name(name)
local dest = rspawn.playerspawns[args[1]]
if dest then
user:setpos(dest)
minetest.chat_send_player(name, "Moved to spawn point of "..args[1])
else
minetest.chat_send_player(name, "No rspawn coords for "..args[1])
end
return
elseif args[2] == "new" then
request_new_spawn(name, args[1])
return
else
tpos = minetest.string_to_pos(args[2])
if tpos then
rspawn.playerspawns[tname] = tpos
rspawn:spawnsave()
minetest.chat_send_player(name, tname.."'s spawn has been reset")
return
end
end
end
end
minetest.chat_send_player(name, "Error. See '/help playerspawn'")
end
})
-- Prevent players from spamming newspawn
minetest.register_globalstep(function(dtime)
local playername, playertime, shavetime
stepcount = stepcount + dtime
shavetime = stepcount
if stepcount > 0.5 then
stepcount = 0
else
return
end
for playername,playertime in pairs(newspawn_cooldown) do
playertime = playertime - shavetime
if playertime <= 0 then
newspawn_cooldown[playername] = nil
minetest.chat_send_player(playername, "/newspawn available")
else
newspawn_cooldown[playername] = playertime
end
end
end)

View File

@ -1,99 +0,0 @@
local spawnsfile = minetest.get_worldpath().."/dynamicspawns.lua.ser"
--[[ Reconcile functions
reconcile_original_spawns : convert from base implementation to invites with original spawns
reconcile_guestlist_spawns : convert from "original spawns" implementation to "guest lists"
--]]
-- Comatibility with old behaviour - players whose original spawns had not been registered receive the one they are now using
local function reconcile_original_spawns()
if not rspawn.playerspawns["original spawns"] then
rspawn.playerspawns["original spawns"] = {}
end
for playername,spawnpos in pairs(rspawn.playerspawns) do
if playername ~= "pre gen" and playername ~= "original spawns" then
if not rspawn.playerspawns["original spawns"][playername] then
rspawn.playerspawns["original spawns"][playername] = rspawn.playerspawns[playername]
end
end
end
rspawn:spawnsave()
end
local function reconcile_guest(guestname, guestspawn)
for hostname,hostspawn in pairs(rspawn.playerspawns) do
if hostname ~= "guest lists" and hostname ~= guestname and hostspawn == guestspawn then
local hostlist = rspawn.playerspawns["guest lists"][hostname] or {}
hostlist[guestname] = 1
rspawn.playerspawns["guest lists"][hostname] = hostlist
end
end
end
local function reconcile_guestlist_spawns()
if not rspawn.playerspawns["guest lists"] then rspawn.playerspawns["guest lists"] = {} end
for guestname,spawnpos in pairs(rspawn.playerspawns) do
reconcile_guest(guestname, spawnpos)
if rspawn.playerspawns["original spawns"][guestname] then
rspawn.playerspawns[guestname] = rspawn.playerspawns["original spawns"][guestname]
rspawn.playerspawns["original spawns"][guestname] = nil
else
minetest.debug("Could not return "..guestname)
end
end
if #rspawn.playerspawns["original spawns"] == 0 then
rspawn.playerspawns["original spawns"] = nil
else
minetest.log("error", "Failed to reconcile all spawns")
end
rspawn:spawnsave()
end
function rspawn:spawnsave()
local serdata = minetest.serialize(rspawn.playerspawns)
if not serdata then
minetest.log("error", "[spawn] Data serialization failed")
return
end
local file, err = io.open(spawnsfile, "w")
if err then
return err
end
file:write(serdata)
file:close()
local pregens = rspawn.playerspawns["pre gen"] or {}
minetest.debug("Wrote rspawn data with "..tostring(#pregens).." pregen nodes")
end
function rspawn:spawnload()
local file, err = io.open(spawnsfile, "r")
if not err then
rspawn.playerspawns = minetest.deserialize(file:read("*a"))
file:close()
else
minetest.log("error", "[spawn] Data read failed - initializing")
rspawn.playerspawns = {}
end
local pregens = rspawn.playerspawns["pre gen"] or {}
rspawn.playerspawns["pre gen"] = pregens
local towns = rspawn.playerspawns["town lists"] or {}
rspawn.playerspawns["town lists"] = towns
reconcile_original_spawns()
reconcile_guestlist_spawns()
minetest.debug("Loaded rspawn data with "..tostring(#pregens).." pregen nodes")
end

View File

@ -1,20 +0,0 @@
function rspawn:d(stuff)
-- Quick debugging
minetest.debug(dump(stuff))
end
function rspawn:debug(message, data)
-- Debugging from setting
if not rspawn.debug_on then
return
end
local debug_data = ""
if data ~= nil then
debug_data = " :: "..dump(data)
end
local debug_string = "[rspawn] DEBUG : "..message..debug_data
minetest.debug(debug_string)
end

View File

@ -1,37 +0,0 @@
local forceloading_happening = false
local function forceload_operate(pos1, pos2, handler, transient)
local i,j,k
for i=pos1.x,pos2.x,16 do
for j=pos1.y,pos2.y,16 do
for k=pos1.z,pos2.z,16 do
handler({x=i,y=j,z=k}, transient)
end
end
end
end
function rspawn:forceload_blocks_in(pos1, pos2)
if forceloading_happening then
rspawn:debug("Forceload operation already underway - abort")
return false
end
rspawn:debug("Forceloading blocks -----------¬", {pos1=minetest.pos_to_string(pos1),pos2=minetest.pos_to_string(pos2)})
forceloading_happening = true
minetest.emerge_area(pos1, pos2)
forceload_operate(pos1, pos2, minetest.forceload_block, true)
return true
end
function rspawn:forceload_free_blocks_in(pos1, pos2)
rspawn:debug("Freeing forceloaded blocks ____/", {pos1=minetest.pos_to_string(pos1),pos2=minetest.pos_to_string(pos2)})
-- free both cases - take no chances
forceload_operate(pos1, pos2, minetest.forceload_free_block) -- free if persistent
forceload_operate(pos1, pos2, minetest.forceload_free_block, true) -- free if transient
forceloading_happening = false
end

View File

@ -1,429 +0,0 @@
-- API holder object
rspawn.guestlists = {}
local kick_step = 0
local kick_period = tonumber(minetest.settings:get("rspawn.kick_period")) or 3
local exile_distance = tonumber(minetest.settings:get("rspawn.exile_distance")) or 64
local GUEST_BAN = 0
local GUEST_ALLOW = 1
-- Levvy helpers
-- FIXME Minetest API might actually be able to do this cross-stacks with a single call at inventory level.
local levvy_name = minetest.settings:get("rspawn.levvy_name") or "default:cobble"
local levvy_qtty = tonumber(minetest.settings:get("rspawn.levvy_qtty")) or 10
local levvy_nicename = "cobblestone"
minetest.after(0,function()
if minetest.registered_items[levvy_name] then
levvy_nicename = minetest.registered_nodes[levvy_name].description
else
minetest.debug("No such item "..levvy_name.." -- reverting to defaults.")
levvy_name = "default:cobble"
levvy_qtty = 99
end
end)
local function find_levvy(player)
-- return itemstack index, and stack itself, with qtty removed
-- or none if not found/not enough found
local i
if not player then
minetest.log("error", "[rspawn] Levvy : Tried to access undefined player")
return false
end
local pname = player:get_player_name()
local player_inv = minetest.get_inventory({type='player', name = pname})
local total_count = 0
if not player_inv then
minetest.log("error", "[rspawn] Levvy : Could not access inventory for "..pname)
return false
end
for i = 1,32 do
local itemstack = player_inv:get_stack('main', i)
local itemname = itemstack:get_name()
if itemname == levvy_name then
if itemstack:get_count() >= levvy_qtty then
return true
else
total_count = total_count + itemstack:get_count()
if total_count >= (levvy_qtty) then
return true
end
end
end
end
minetest.chat_send_player(pname, "You do not have enough "..levvy_nicename.." to pay the spawn levvy for your invitation.")
return false
end
function rspawn:consume_levvy(player)
if not player then
minetest.log("error", "[rspawn] Levvy : Tried to access undefined player")
return false
end
local i
local pname = player:get_player_name()
local player_inv = minetest.get_inventory({type='player', name = pname})
local total_count = 0
-- TODO combine find_levvy and consume_levvy so that we're
-- not scouring the inventory twice...
if find_levvy(player) then
for i = 1,32 do
local itemstack = player_inv:get_stack('main', i)
local itemname = itemstack:get_name()
if itemname == levvy_name then
if itemstack:get_count() >= levvy_qtty then
itemstack:take_item(levvy_qtty)
player_inv:set_stack('main', i, itemstack)
return true
else
total_count = total_count + itemstack:get_count()
itemstack:clear()
player_inv:set_stack('main', i, itemstack)
if total_count >= (levvy_qtty) then
return true
end
end
end
end
end
return false
end
-- Visitation rights check
local function canvisit(hostname, guestname)
local host_glist = rspawn.playerspawns["guest lists"][hostname] or {}
local town_lists = rspawn.playerspawns["town lists"] or {}
local explicitly_banned = host_glist[guestname] == GUEST_BAN
local explicitly_banned_from_town = town_lists[hostname] and
town_lists[hostname][guestname] == GUEST_BAN
local open_town = town_lists[hostname] and town_lists[hostname]["town status"] == "on"
if explicitly_banned or explicitly_banned_from_town then
return false
elseif host_glist[guestname] == GUEST_ALLOW then
return true
elseif open_town then
return true
end
return false
end
-- Operational functions (to be invoked by /command)
function rspawn.guestlists:addplayer(hostname, guestname)
local guestlist = rspawn.playerspawns["guest lists"][hostname] or {}
if guestlist[guestname] ~= nil then
if guestlist[guestname] == GUEST_BAN then
minetest.chat_send_player(guestname, hostname.." let you back into their spawn.")
minetest.log("action", "[rspawn] "..hostname.." lifted exile on "..guestname)
end
guestlist[guestname] = GUEST_ALLOW
elseif rspawn:consume_levvy(minetest.get_player_by_name(hostname) ) then -- Automatically notifies host if they don't have enough
guestlist[guestname] = GUEST_ALLOW
minetest.chat_send_player(guestname, hostname.." added you to their spawn! You can now visit them with /spawn visit "..hostname)
minetest.log("action", "[rspawn] "..hostname.." added "..guestname.." to their spawn")
else
return
end
minetest.chat_send_player(hostname, guestname.." is allowed to visit your spawn.")
rspawn.playerspawns["guest lists"][hostname] = guestlist
rspawn:spawnsave()
end
function rspawn.guestlists:exileplayer(hostname, guestname)
if hostname == guestname then
minetest.chat_send_player(hostname, "Cannot ban yourself!")
return false
end
local guestlist = rspawn.playerspawns["guest lists"][hostname] or {}
if guestlist[guestname] == GUEST_ALLOW then
guestlist[guestname] = GUEST_BAN
rspawn.playerspawns["guest lists"][hostname] = guestlist
else
minetest.chat_send_player(hostname, guestname.." is not in accepted guests list for "..hostname)
return false
end
minetest.chat_send_player(guestname, "You may no longer visit "..hostname)
minetest.log("action", "rspawn - "..hostname.." exiles "..guestname)
rspawn:spawnsave()
return true
end
function rspawn.guestlists:kickplayer(hostname, guestname)
if rspawn.guestlists:exileplayer(hostname, guestname) then
minetest.chat_send_player(hostname, "Evicted "..guestname.." from your spawn")
minetest.log("action", "rspawn - "..hostname.." evicts "..guestname)
end
end
function rspawn.guestlists:listguests(hostname)
local guests = ""
local guestlist = rspawn.playerspawns["guest lists"][hostname] or {}
local global_hosts = rspawn.playerspawns["town lists"] or {}
if global_hosts[hostname] then
guests = ", You are an active town host."
end
-- Explicit guests
for guestname,status in pairs(guestlist) do
if status == GUEST_ALLOW then status = "" else status = " (exiled guest)" end
guests = guests..", "..guestname..status
end
-- Town bans - always list so this can be maanged even when town is closed
for guestname,status in pairs(global_hosts[hostname] or {}) do
if guestname ~= "town status" then
if status == GUEST_ALLOW then status = "" else status = " (banned from town)" end
guests = guests..", "..guestname..status
end
end
if guests == "" then
guests = ", No guests, not hosting a town."
end
minetest.chat_send_player(hostname, guests:sub(3))
end
function rspawn.guestlists:listhosts(guestname)
local hosts = ""
for hostname,hostguestlist in pairs(rspawn.playerspawns["guest lists"]) do
for gname,status in pairs(hostguestlist) do
if guestname == gname then
if status == GUEST_ALLOWED then
hosts = hosts..", "..hostname
end
end
end
end
local global_hostlist = rspawn.playerspawns["town lists"] or {}
for hostname,host_banlist in pairs(global_hostlist) do
if host_banlist["town status"] == "on" and
host_banlist[guestname] ~= GUEST_BAN
then
hosts = hosts..", "..hostname.." (town)"
end
end
if hosts == "" then
hosts = ", (no visitable hosts)"
end
minetest.chat_send_player(guestname, hosts:sub(3))
end
function rspawn.guestlists:visitplayer(hostname, guestname)
if not (hostname and guestname) then return end
local guest = minetest.get_player_by_name(guestname)
local hostpos = rspawn.playerspawns[hostname]
if not hostpos then
minetest.log("error", "[rspawn] Missing spawn position data for "..hostname)
minetest.chat_send_player(guestname, "Could not find spawn position for "..hostname)
end
if guest and canvisit(hostname, guestname) then
minetest.log("action", "[rspawn] "..guestname.." visits "..hostname.." (/spawn visit)")
guest:setpos(hostpos)
else
minetest.chat_send_player(guestname, "Could not visit "..hostname)
end
end
local function act_on_behalf(hostname, callername)
return hostname == callername or -- caller is the town owner, always allow
( -- caller can act on behalf of town owner
rspawn.playerspawns["guest lists"][hostname] and
rspawn.playerspawns["guest lists"][hostname][callername] == GUEST_ALLOW
)
end
local function townban(callername, guestname, hostname)
if not (callername and guestname) then return end
hostname = hostname or callername
if act_on_behalf(hostname, callername) then
if not rspawn.playerspawns["town lists"][hostname] then
minetest.chat_send_player(callername, "No such town "..hostname)
return
end
rspawn.playerspawns["town lists"][hostname][guestname] = GUEST_BAN
minetest.chat_send_player(callername, "Evicted "..guestname.." from "..hostname.."'s spawn")
minetest.log("action", "[rspawn] - "..callername.." evicts "..guestname.." on behalf of "..hostname)
else
minetest.chat_send_player(callername, "You are not permitted to act on behalf of "..hostname)
end
rspawn:spawnsave()
end
local function townunban(callername, guestname, hostname)
if not (callername and guestname) then return end
hostname = hostname or callername
if act_on_behalf(hostname, callername) then
if not rspawn.playerspawns["town lists"][hostname] then
minetest.chat_send_player(callername, "No such town "..hostname)
return
end
rspawn.playerspawns["town lists"][hostname][guestname] = nil
minetest.chat_send_player(callername, "Allowed "..guestname.." back to town "..hostname)
minetest.log("action", "[rspawn] - "..callername.." lifts eviction on "..guestname.." on behalf of "..hostname)
else
minetest.chat_send_player(callername, "You are not permitted to act on behalf of "..hostname)
end
rspawn:spawnsave()
end
local function listtowns()
local town_lists = rspawn.playerspawns["town lists"] or {}
local open_towns = ""
for townname,banlist in pairs(town_lists) do
if banlist["town status"] == "on" then
open_towns = open_towns..", "..townname
end
end
if open_towns ~= "" then
return open_towns:sub(3)
end
end
function rspawn.guestlists:townset(hostname, params)
if not hostname then return end
params = params or ""
params = params:split(" ")
local mode = params[1]
local guestname = params[2]
local town_lists = rspawn.playerspawns["town lists"] or {}
local town_banlist = town_lists[hostname] or {}
if mode == "open" then
town_banlist["town status"] = "on"
minetest.chat_send_all(hostname.." is opens access to all!")
minetest.log("action", "[rspawn] town: "..hostname.." sets their spawn to open")
elseif mode == "close" then
town_banlist["town status"] = "off"
minetest.chat_send_all(hostname.." closes town access - only guests may directly visit.")
minetest.log("action", "[rspawn] town: "..hostname.." sets their spawn to closed")
elseif mode == "status" then
minetest.chat_send_player(hostname, "Town mode is: "..town_banlist["town status"])
return
elseif mode == "ban" and guestname and guestname ~= hostname then
townban(hostname, guestname, params[3])
elseif mode == "unban" and guestname then
townunban(hostname, guestname, params[3])
elseif mode == nil or mode == "" then
local open_towns = listtowns()
if not open_towns then
open_towns = "(none yet)"
end
minetest.chat_send_player(hostname, open_towns)
else
minetest.chat_send_player(hostname, "Unknown parameterless town operation: "..tostring(mode) )
return
end
town_lists[hostname] = town_banlist
rspawn.playerspawns["town lists"] = town_lists
rspawn:spawnsave()
end
-- Exile check
minetest.register_globalstep(function(dtime)
if kick_step < kick_period then
kick_step = kick_step + dtime
return
else
kick_step = 0
end
for _x,guest in ipairs(minetest.get_connected_players()) do
local guestname = guest:get_player_name()
local playerprivs = minetest.get_player_privs(guestname)
if not (playerprivs.basic_privs or playerprivs.server) then
local guestpos = guest:getpos()
for _y,player_list_name in ipairs({"guest lists", "town lists"}) do
for hostname,host_guestlist in pairs(rspawn.playerspawns[player_list_name] or {}) do
if host_guestlist[guestname] == GUEST_BAN then
-- Check distance of guest from banned pos
local vdist = vector.distance(guestpos, rspawn.playerspawns[hostname])
-- Check distance of guest from their own pos
-- If their spawn is very close to one they are banned from,
-- and they are close to their own, kick should not occur
local sdist = vector.distance(guestpos, rspawn.playerspawns[guestname])
if vdist < exile_distance and sdist > exile_distance then
guest:setpos(rspawn.playerspawns[guestname])
minetest.chat_send_player(guestname, "You got too close to "..hostname.."'s turf.")
minetest.log("action", "[rspawn] Auto-kicked "..guestname.." for being too close to "..hostname.."'s spawn")
elseif vdist < exile_distance*1.5 and sdist > exile_distance then
minetest.chat_send_player(guestname, "You are getting too close to "..hostname.."'s turf.")
end
end
end
end
end
end
end)
-- Announce towns!
minetest.register_on_joinplayer(function(player)
local open_towns = listtowns()
if open_towns then
minetest.chat_send_player(player:get_player_name(), "Currently open towns: "..open_towns..". Visit with '/spawn visit <townname>' !")
end
end)

View File

@ -1,85 +0,0 @@
local steptime = 0
-- Ensure pregen data is stored and saved properly
local function len_pgen()
return #rspawn.playerspawns["pre gen"]
end
local function set_pgen(idx, v)
rspawn.playerspawns["pre gen"][idx] = v
rspawn:spawnsave()
end
local function get_pgen(idx)
return rspawn.playerspawns["pre gen"][idx]
end
-- Spawn generation
local function push_new_spawn()
if len_pgen() >= rspawn.max_pregen_spawns then
rspawn:debug("Max pregenerated spawns ("..rspawn.max_pregen_spawns..") reached : "..len_pgen())
return
end
local random_pos = rspawn:genpos()
local pos1,pos2 = rspawn:get_positions_for(random_pos, rspawn.search_radius)
if rspawn:forceload_blocks_in(pos1, pos2) then
minetest.after(rspawn.gen_frequency*0.8, function()
-- Let the forceload do its thing, then act
local newpos = rspawn:newspawn(random_pos, rspawn.search_radius)
if newpos then
rspawn:debug("Generated "..minetest.pos_to_string(newpos))
set_pgen(len_pgen()+1, newpos )
else
rspawn:debug("Failed to generate new spawn point to push")
random_pos.y = random_pos.y + rspawn.search_radius
set_pgen(len_pgen()+1, random_pos )
minetest.chat_send_player(rspawn.admin, "Failed to generate new spawn.. trying fixed one")
end
rspawn:forceload_free_blocks_in(pos1, pos2)
end)
else
rspawn:debug("Failed to push new spawn point - preexisting operation took precedence.")
end
end
minetest.register_globalstep(function(dtime)
steptime = steptime + dtime
if steptime > rspawn.gen_frequency then
steptime = 0
else
return
end
push_new_spawn()
end)
-- Access pregenrated spawns
function rspawn:get_next_spawn()
local nspawn
if len_pgen() > 0 then
nspawn = get_pgen(len_pgen() )
set_pgen(len_pgen(), nil)
-- Someone might have claimed the area since.
if minetest.is_protected(nspawn, "") then
return rspawn:get_next_spawn()
else
rspawn:debug("Returning pregenerated spawn",nspawn)
end
end
return nspawn
end
-- On load...
push_new_spawn()

View File

@ -1 +0,0 @@
name = rspawn

View File

@ -1,16 +0,0 @@
rspawn.debug (Debug mode) bool false
rspawn.spawn_anywhere (Spawn anywhere) bool true
rspawn.kick_on_fail (Kick on fail) bool false
rspawn.max_pregen (Maximum blocks to pregenerate) string 10
rspawn.search_radius (Search radius) string 32
rspawn.gen_frequency (Spawnpoint generation frequency [seconds]) string 60
rspawn.spawn_block (Node to place under new spawn point) string
rspawn.levvy_name (Levvy itemstring) string "default:cobble"
rspawn.levvy_qtty (Levvy quantity) string 10
rspawn.kick_period (Exile kick check period) string 1
rspawn.exile_distance (Exile distance) string 64
rspawn.cooldown_time (Cooldown between /newspawn uses) string 300
rspawn.min_x (Westmost bounds) string -31000
rspawn.max_x (Eastmost bounds) string 31000
rspawn.min_z (Southmost bounds) string -31000
rspawn.max_z (Northmost bounds) string 31000

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB