diff --git a/GAMEINFO-en.md b/GAMEINFO-en.md index 5d4f4f7..eb2fce5 100644 --- a/GAMEINFO-en.md +++ b/GAMEINFO-en.md @@ -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 --------------- diff --git a/GAMEINFO-es.md b/GAMEINFO-es.md index 1c88713..f3793be 100644 --- a/GAMEINFO-es.md +++ b/GAMEINFO-es.md @@ -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 --------------- diff --git a/GAMEINFO-ru.md b/GAMEINFO-ru.md index 3fc172f..8e368d9 100644 --- a/GAMEINFO-ru.md +++ b/GAMEINFO-ru.md @@ -1,23 +1,11 @@ -# бесконечный манифест игры subnasa +# бесконечный манифест игры NSSM -Игра subnasa - самая быстрая под-игра без задержек в minetest! +Игра NSSM - самая быстрая под-игра без задержек в minetest! ## Информация **Единственный враждебный элемент — это сами игроки**, а острые ощущения — **командная работа**. -Субназа имеет **приоритет, что многие входят и что существует опасность вмешательства**, -для этого хитрость заключается в том, чтобы обеспечить **простую среду без враждебных сущностей, легкий доступ**, -это привлечет много неопытных игроков, которые заполнят сервер, это позволит -что перед лицом опасности вмешательства **других игроков** в ваши вещи **вы должны жить группами**, -а также **спрятаться**, что заставит всех задуматься о том, как защитить себя, что невозможно сделать в одиночку.. - -Эта предпосылка означает, что такие моды, как `mobs_monster` или `dmobs`, не существуют, но если `mobs_animals`, -что означает, например, что нет брони или особых биомов, но много домов и украшений, -Кроме того, по причинам оптимизации такие вещи, как `unified_inventory`, не включены, но -если включены такие вещи, как `prestibags` и `ambience`, потому что игра должна загружаться на телефоны, -Память телефона иногда невелика, и такие моды, как `nssm`, требуют обработки большого количества данных. - ## Введение --------------- diff --git a/README.md b/README.md index 1f4b3f3..b3252e3 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/mods/rspawn/License.txt b/mods/rspawn/License.txt deleted file mode 100644 index 341c30b..0000000 --- a/mods/rspawn/License.txt +++ /dev/null @@ -1,166 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - 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. - diff --git a/mods/rspawn/README.md b/mods/rspawn/README.md deleted file mode 100644 index 6fcce7e..0000000 --- a/mods/rspawn/README.md +++ /dev/null @@ -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 ` - allow another player to visit your spawn directly (levvy must be paid), or lift their exile (no levvy to pay) -* `/spawn kick ` - * revoke rights to visit you - * if the exiled player gets close to your spawn, they are kicked back to their own spawn -* `/spawn visit ` - 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 ` 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 } []` - 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 ` 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/` 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 diff --git a/mods/rspawn/depends.txt b/mods/rspawn/depends.txt deleted file mode 100644 index 3c67c0d..0000000 --- a/mods/rspawn/depends.txt +++ /dev/null @@ -1 +0,0 @@ -beds? diff --git a/mods/rspawn/init.lua b/mods/rspawn/init.lua deleted file mode 100644 index 47039c0..0000000 --- a/mods/rspawn/init.lua +++ /dev/null @@ -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") diff --git a/mods/rspawn/lua/commands.lua b/mods/rspawn/lua/commands.lua deleted file mode 100644 index 4ada423..0000000 --- a/mods/rspawn/lua/commands.lua +++ /dev/null @@ -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 | visit | kick | guests | hosts | town { open | close | ban [] | unban [] } ]", - 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 = " { new | | 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) diff --git a/mods/rspawn/lua/data.lua b/mods/rspawn/lua/data.lua deleted file mode 100644 index b790251..0000000 --- a/mods/rspawn/lua/data.lua +++ /dev/null @@ -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 - diff --git a/mods/rspawn/lua/debugging.lua b/mods/rspawn/lua/debugging.lua deleted file mode 100644 index 7765506..0000000 --- a/mods/rspawn/lua/debugging.lua +++ /dev/null @@ -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 diff --git a/mods/rspawn/lua/forceload.lua b/mods/rspawn/lua/forceload.lua deleted file mode 100644 index 2708ad2..0000000 --- a/mods/rspawn/lua/forceload.lua +++ /dev/null @@ -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 - diff --git a/mods/rspawn/lua/guestlists.lua b/mods/rspawn/lua/guestlists.lua deleted file mode 100644 index 13bd970..0000000 --- a/mods/rspawn/lua/guestlists.lua +++ /dev/null @@ -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 ' !") - end -end) diff --git a/mods/rspawn/lua/pregeneration.lua b/mods/rspawn/lua/pregeneration.lua deleted file mode 100644 index e3090ff..0000000 --- a/mods/rspawn/lua/pregeneration.lua +++ /dev/null @@ -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() - diff --git a/mods/rspawn/mod.conf b/mods/rspawn/mod.conf deleted file mode 100644 index f89908e..0000000 --- a/mods/rspawn/mod.conf +++ /dev/null @@ -1 +0,0 @@ -name = rspawn diff --git a/mods/rspawn/settingtypes.txt b/mods/rspawn/settingtypes.txt deleted file mode 100644 index fc212d5..0000000 --- a/mods/rspawn/settingtypes.txt +++ /dev/null @@ -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 diff --git a/screenshot.png b/screenshot.png deleted file mode 100644 index c9a9458..0000000 Binary files a/screenshot.png and /dev/null differ