Compare commits
1 Commits
master
...
red_desert
Author | SHA1 | Date |
---|---|---|
Wuzzy | 02d2f7ae1a |
35
API.md
|
@ -9,19 +9,10 @@ Mods mods in MineClone 2 follow a simple naming convention: Mods with the prefix
|
|||
## Adding items
|
||||
### Special fields
|
||||
|
||||
Items can have these fields:
|
||||
* `_mcl_generate_description(itemstack)`: Required for any items which manipulate their
|
||||
description in any way. This function takes an itemstack of its own type and must set
|
||||
the proper advanced description for this itemstack. If you don't do this, anvils will
|
||||
fail at properly restoring the description when their custom name gets cleared at an
|
||||
anvil.
|
||||
See `mcl_banners` for an example.
|
||||
|
||||
All nodes can have these fields:
|
||||
|
||||
* `_mcl_hardness`: Hardness of the block, ranges from 0 to infinity (represented by -1). Determines digging times. Default: 0
|
||||
* `_mcl_blast_resistance`: How well this block blocks and resists explosions. Default: 0
|
||||
* `_mcl_after_falling(pos)`: Called after a falling node finished falling and turned into a node.
|
||||
* `_mcl_blast_resistance`: How well this block blocks and resistst explosions. Default: 0
|
||||
|
||||
Use the `mcl_sounds` mod for the sounds.
|
||||
|
||||
|
@ -31,26 +22,17 @@ A lot of things are possible by using one of the APIs in the mods. Note that not
|
|||
### Items
|
||||
* Doors: `ITEMS/mcl_doors`
|
||||
* Fences and fence gates: `ITEMS/mcl_fences`
|
||||
* Stairs and slabs: `ITEM/mcl_stairs`
|
||||
* Walls: `ITEMS/mcl_walls`
|
||||
* Beds: `ITEMS/mcl_beds`
|
||||
* Buckets: `ITEMS/mcl_buckets`
|
||||
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
|
||||
|
||||
## Mobs
|
||||
* Mobs: `ENTITIES/mcl_mods`
|
||||
|
||||
MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short.
|
||||
This is a fork of Mobs Redo [`mobs`] by TenPlus1.
|
||||
* Mobs: `ENTITIES/mods`
|
||||
|
||||
MineClone 2 uses Mobs Redo [`mobs`] by TenPlus1, a very powerful mod for adding mods of various types.
|
||||
There are modificiations from the original mod for MineClone 2 compability. Some items have been removed or moved to other mods, but the API is identical.
|
||||
You can add your own mobs, spawn eggs and spawning rules with this mod.
|
||||
API documnetation is included in `ENTITIES/mcl_mobs/api.txt`.
|
||||
|
||||
This mod includes modificiations from the original Mobs Redo. Some items have been removed or moved to other mods.
|
||||
The API is mostly identical, but a few features have been added. Compability is not really a goal,
|
||||
but function and attribute names of Mobs Redo 1.41 are kept.
|
||||
If you have code for a mod which works fine under Mobs Redo, it should be easy to make it work in MineClone 2,
|
||||
chances are good that it works out of the box.
|
||||
API documnetation is included in `ENTITIES/mobs/api.txt`.
|
||||
|
||||
### Help
|
||||
* Item help texts: `HELP/doc/doc_items`
|
||||
|
@ -61,20 +43,19 @@ chances are good that it works out of the box.
|
|||
* Statbars: `HUD/hudbars`
|
||||
|
||||
### Utility APIs
|
||||
* Change player physics: `PLAYER/playerphysics`
|
||||
* Select random treasures: `CORE/mcl_loot`
|
||||
* Get flowing direction of liquids: `CORE/flowlib`
|
||||
* `on_walk_over` callback for nodes: `CORE/walkover`
|
||||
* Get node names close to player (to reduce constant querying): `PLAYER/mcl_playerinfo`
|
||||
|
||||
### Unstable APIs
|
||||
The following APIs may be subject to change in future. You could already use these APIs but there will probably be breaking changes in the future, or the API is not as fleshed out as it should be. Use at your own risk!
|
||||
These APIs may be subject to change in future. You could already use these APIs but there will probably be breaking changes in the future, or the API is not as fleshed out as it should be. Use at your own risk!
|
||||
|
||||
* Panes (like glass panes and iron bars): `ITEMS/xpanes`
|
||||
* Slabs and stairs: `ITEM/mcl_stairs` **and** `ITEMS/mcstair`
|
||||
* `_on_ignite` callback: `ITEMS/mcl_fire`
|
||||
* Farming: `ITEMS/mcl_farming`
|
||||
* Anything related to redstone: Don't touch (yet)
|
||||
* Any other mod not explicitly mentioned above
|
||||
* Other mods not listed above
|
||||
|
||||
### Planned APIs
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ channel on irc.freenode.net. And finally, you can send e-mails to
|
|||
|
||||
There is **no** guarantee I will accept anything from anybody.
|
||||
|
||||
By sending me patches or asking me to include your changes in this game,
|
||||
By sending me patches or asking me to include your changes in this subgame,
|
||||
you agree that they fall under the terms of the LGPLv2.1, which basically
|
||||
means they will become part of a free software.
|
||||
|
||||
|
@ -70,4 +70,4 @@ Depending on what you add, the chances for inclusion vary:
|
|||
## Reporting bugs
|
||||
Report all bugs and missing Minecraft features here:
|
||||
|
||||
<https://git.minetest.land/Wuzzy/MineClone2-Bugs>
|
||||
<https://github.com/Wuzzy2/MineClone2-Bugs>
|
||||
|
|
33
GROUPS.md
|
@ -1,5 +1,5 @@
|
|||
## Groups
|
||||
This document explains all the groups used in this game.
|
||||
This document explains all the groups used in this subgame.
|
||||
|
||||
### Special groups
|
||||
|
||||
|
@ -29,8 +29,6 @@ Please read <http://minecraft.gamepedia.com/Breaking> to learn how digging times
|
|||
|
||||
### Groups for interactions
|
||||
|
||||
* `crush_after_fall=1`: For falling nodes. These will crush whatever they hit after falling, not dropping as an item
|
||||
* `falling_node_damage=1`: For falling nodes. Hurts any objects it hits while falling. Damage is based on anvils
|
||||
* `dig_by_water=1`: Blocks with this group will drop when they are near flowing water
|
||||
* `destroy_by_lava_flow=1`: Blocks with this group will be destroyed by flowing lava
|
||||
* `dig_by_piston=1`: Blocks which will drop as an item when pushed by a piston. They also cannot be pulled by sticky pistons
|
||||
|
@ -38,8 +36,7 @@ Please read <http://minecraft.gamepedia.com/Breaking> to learn how digging times
|
|||
* `cultivatable=1`: Block will be turned into Dirt by using a hoe on it
|
||||
* `flammable`: Block helps spreading fire and gets destroyed by nearby fire (rating doesn't matter)
|
||||
* `spreading_dirt_type=1`: A dirt-type block with a cover (e.g. grass) which may spread to neighbor dirt blocks
|
||||
* `dirtifies_below_solid=1`: This node turns into dirt immediately when a solid or dirtifier node is placed on top
|
||||
* `dirtifier=1`: This node turns nodes the above group into dirt when placed above
|
||||
* `dirtifies_below_solid=1`: This node turns into dirt immediately when a solid node is placed on top
|
||||
* `non_mycelium_plant=1`: A plant which can't grow on mycelium. Placing it on mycelium fails and if mycelium spreads below it, it uproots
|
||||
* `soil=1`: Saplings and other small plants can grow on it
|
||||
* `soil_sapling=2`: Soil for saplings. Intended to be natural soil. All saplings will grow on this
|
||||
|
@ -51,11 +48,6 @@ Please read <http://minecraft.gamepedia.com/Breaking> to learn how digging times
|
|||
* `destroys_items=1`: If an item happens to be *inside* this node, the item will be destroyed
|
||||
* `no_eat_delay=1`: Only for foodstuffs. When eating this, all eating delays are ignored.
|
||||
* `can_eat_when_full=1`: Only for foodstuffs. This item can be eaten when the user has a full hunger bar
|
||||
* `attached_node_facedir=1`: Like `attached_node`, but for facedir nodes
|
||||
* `cauldron`: Cauldron. 1: Empty. 2-4: Water height
|
||||
* `anvil`: Anvil. 1: No damage. 2-3: Higher damage levels
|
||||
* `no_rename=1`: Item cannot be renamed by anvil
|
||||
* `comparator_signal=X`: If set, this node outputs a constant (!) comparator signal output of strength X.
|
||||
|
||||
#### Footnotes
|
||||
|
||||
|
@ -79,7 +71,6 @@ Please read <http://minecraft.gamepedia.com/Breaking> to learn how digging times
|
|||
* `wool=1`: Wool (only full blocks)
|
||||
* `carpet=1:` (Wool) carpet
|
||||
* `stick=1`: Stick
|
||||
* `water_bucket=1`: Bucket containing a liquid of group “water”
|
||||
|
||||
### Material groups
|
||||
|
||||
|
@ -98,12 +89,10 @@ These groups are used mostly for informational purposes
|
|||
|
||||
* `solid=1`: Solid full-cube block (automatically assigned)
|
||||
* `opaque=1`: Opaque block (automatically assigned)
|
||||
* `not_solid=1`: Block is not solid (only assign this group for nodes which are automatically detected as “solid” in error
|
||||
* `not_opaque=1`: Block is not opaque (only assign this group for nodes which are automatically detected as “opaque” in error
|
||||
* `not_solid=1`: Block is sold (only assign this group for nodes which are automatically detected as “solid” in error
|
||||
* `fire=1`: Fire
|
||||
* `water=1`: Water
|
||||
* `lava=1`: Lava
|
||||
* `top_snow=X`: Top snow with X layers (1-8)
|
||||
* `torch`: Torch or torch-like node
|
||||
* `torch=1`: Torch on floor
|
||||
* `torch=2`: Torch at wall
|
||||
|
@ -120,7 +109,6 @@ These groups are used mostly for informational purposes
|
|||
* `flower_pot=2`: Flower pot with a plant or flower
|
||||
* `flower=1`: Flower
|
||||
* `place_flowerlike=1`: Node has placement rules like that of a flower
|
||||
* `place_flowerlike=2`: Node has placement rules like tall grass
|
||||
* `cake`: Cake (rating = slices left)
|
||||
* `book=1`: Book
|
||||
* `pane=1`: Node is a “pane”-like node glass pane or iron bars
|
||||
|
@ -152,27 +140,12 @@ These groups are used mostly for informational purposes
|
|||
* `container=5`: Left part of a 2-part horizontal connected container. Both parts have a `"main"` inventory
|
||||
list. Both inventories are considered to belong together. This is used for large chests.
|
||||
* `container=6`: Same as above, but for the right part.
|
||||
* `container=7`: Has inventory list "`main`", no movement allowed
|
||||
* `container=1`: Other/unspecified container type
|
||||
* `spawn_egg=1`: Spawn egg
|
||||
|
||||
* `pressure_plate=1`: Pressure plate (off)
|
||||
* `pressure_plate=2`: Wooden pressure (on)
|
||||
* `button=1`: Button (off)
|
||||
* `button=2`: Button (on)
|
||||
* `redstone_torch=1`: Redstone Torch (lit)
|
||||
* `redstone_torch=2`: Redstone Torch (unlit)
|
||||
|
||||
* `plant=1`: Plant or part of a plant
|
||||
* `double_plant`: Part of a double-sized plant. 1 = lower part, 2 = upper part
|
||||
|
||||
* `pickaxe=1`: Pickaxe
|
||||
* `shovel=1`: Shovel
|
||||
* `axe=1`: Axe
|
||||
* `sword=1`: Sword
|
||||
* `hoe=1`: Hoe (farming tool)
|
||||
* `shears=1`: Shears
|
||||
|
||||
* `weapon=1`: Item is primarily (!) a weapon
|
||||
* `tool=1`: Item is primarily (!) a tool
|
||||
* `craftitem=1`: Item is primarily (!) used for crafting
|
||||
|
|
70
README.md
|
@ -2,7 +2,7 @@
|
|||
An unofficial Minecraft-like game for Minetest. Forked from MineClone by daredevils.
|
||||
Developed by Wuzzy and contributors. Not developed or endorsed by Mojang AB.
|
||||
|
||||
Version: 0.49.0
|
||||
Version: 0.29.0
|
||||
|
||||
### Gameplay
|
||||
You start in a randomly-generated world made entirely of cubes. You can explore
|
||||
|
@ -60,29 +60,21 @@ The following items are interesting for Creative Mode and for adventure
|
|||
map builders. They can not be obtained in-game or in the creative inventory.
|
||||
|
||||
* Barrier: `mcl_core:barrier`
|
||||
* Command Block: `mesecons_commandblock:commandblock_off`
|
||||
* Monster Spawner: `mcl_mobspawners:spawner`
|
||||
* Huge mushroom blocks: See `mods/ITEMS/mcl_mushrooms/README.md`
|
||||
* Minecart with Command Block: `mcl_minecarts:command_block_minecart`
|
||||
|
||||
Use the `/giveme` chat command to obtain them. See the in-game help for
|
||||
an explanation.
|
||||
|
||||
#### Incomplete items
|
||||
These items do not work yet, but you can get them with `/giveme` for testing:
|
||||
|
||||
* Fishing Rod: `mcl_fishing:fishing_rod`
|
||||
* Activator Rail: `mcl_minecarts:activator_rail`
|
||||
* Minecart with Chest: `mcl_minecarts:chest_minecart`
|
||||
* Minecart with Furnace: `mcl_minecarts:furnace_minecart`
|
||||
* Minecart with Hopper: `mcl_minecarts:hopper_minecart`
|
||||
* Minecart with Command Block: `mcl_minecarts:command_block_minecart`
|
||||
|
||||
## Installation
|
||||
This game requires [Minetest](http://minetest.net) to run (version 5.0.0 or
|
||||
later). So you need to install Minetest first. Only stable versions of Minetest
|
||||
are officially supported.
|
||||
There is no support for running MineClone 2 in development versions of Minetest.
|
||||
|
||||
To install MineClone 2 (if you haven't already), move this directory into the
|
||||
“games” directory of your Minetest data directory. Consult the help of
|
||||
Minetest to learn more.
|
||||
This game requires [Minetest](http://minetest.net) 0.4.16 (or later) to run,
|
||||
so you need to install Minetest first. Only stable versions of Minetest are
|
||||
officially supported. There is no support whatsoever for running MineClone 2
|
||||
in development versions of Minetest.
|
||||
To install MineClone 2, move this directory into the “games” directory of
|
||||
your Minetest data directory. Consult the help of Minetest to learn more.
|
||||
|
||||
## Project description
|
||||
The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software.
|
||||
|
@ -97,17 +89,15 @@ The main goal of **MineClone 2** is to be a clone of Minecraft and to be release
|
|||
|
||||
## Completion status
|
||||
This game is currently in **alpha** stage.
|
||||
It is playable, but unfinished, many bugs are to be expected.
|
||||
It is playable, but very unfinished, many bugs are to be expected.
|
||||
Backwards-compability is *not* guaranteed, updating your world might cause small and
|
||||
big bugs (such as “missing node” errors or even crashes).
|
||||
|
||||
The following main features are available:
|
||||
|
||||
* Tools, weapons
|
||||
* Armor (unbalanced)
|
||||
* Tools, weapons and armor
|
||||
* Crafting system: 2×2 grid, crafting table (3×3 grid), furnace, including a crafting guide
|
||||
* Chests, large chests, ender chests, shulker boxes
|
||||
* Furnaces, hoppers
|
||||
* Hunger
|
||||
* Most monsters and animals
|
||||
* All ores from Minecraft
|
||||
|
@ -116,7 +106,7 @@ The following main features are available:
|
|||
* Weather
|
||||
* 28 biomes
|
||||
* The Nether, a fiery underworld in another dimension
|
||||
* Redstone circuits (partially)
|
||||
* Redstone circuits (partially): Redstone ore, redstone, redstone repeater, levers, buttons, redstone blocks, redstone lamps
|
||||
* Minecarts (partial)
|
||||
* Boats
|
||||
* Fire
|
||||
|
@ -135,13 +125,14 @@ The following main features are available:
|
|||
* Inventory menu
|
||||
* Creative inventory
|
||||
* Farming
|
||||
* Bookshelves (deco only)
|
||||
* Writable books
|
||||
* A few server commands
|
||||
* And more!
|
||||
|
||||
The following features are incomplete:
|
||||
|
||||
* Generated structures (especially villages)
|
||||
* Generated structures
|
||||
* NPCs
|
||||
* Some monsters and animals
|
||||
* Redstone-related things
|
||||
|
@ -150,7 +141,7 @@ The following features are incomplete:
|
|||
* Experience
|
||||
* Status effects
|
||||
* Brewing, potions, tipped arrows
|
||||
* Special minecarts
|
||||
* Anvil
|
||||
* A couple of non-trivial blocks and items
|
||||
|
||||
Bonus features (not found in Minecraft 1.11):
|
||||
|
@ -158,33 +149,24 @@ Bonus features (not found in Minecraft 1.11):
|
|||
* Built-in crafting guide which shows you crafting and smelting recipes
|
||||
* In-game help system containing extensive help about gameplay basics, blocks, items and more
|
||||
* Temporary crafting recipes. They only exist to make some otherwise unaccessible items available when you're not in creative mode. These recipes will be removed as development goes on an more features become available
|
||||
* Saplings in chests in mapgen v6
|
||||
* Fully moddable (thanks to Minetest's powerful Lua API)
|
||||
* New blocks and items:
|
||||
* Lookup tool, shows you the help for whatever it touches
|
||||
* More slabs and stairs
|
||||
* Nether Brick Fence Gate
|
||||
* Red Nether Brick Fence
|
||||
* Red Nether Brick Fence Gate
|
||||
|
||||
Technical differences from Minecraft:
|
||||
|
||||
* Height limit of ca. 31000 blocks (much higher than in Minecraft)
|
||||
* Horizontal world size is ca. 62000×62000 blocks (much smaller than in Minecraft, but it is still very large)
|
||||
* Still very incomplete and buggy
|
||||
* Still very, very incomplete and buggy
|
||||
* Blocks, items, enemies and other features are missing
|
||||
* A few items have slightly different names to make them easier to distinguish
|
||||
* Different music for jukebox
|
||||
* Different textures (Pixel Perfection)
|
||||
* Different sounds (various sources)
|
||||
* Different engine (Minetest)
|
||||
|
||||
… and finally, MineClone 2 is free software (“free” as in “freedom”)!
|
||||
* Free software (“free” as in freedom *and* free beer)
|
||||
|
||||
## Reporting bugs
|
||||
Please report all bugs and missing Minecraft features here:
|
||||
|
||||
<https://git.minetest.land/Wuzzy/MineClone2-Bugs>
|
||||
<https://github.com/Wuzzy2/MineClone2-Bugs>
|
||||
|
||||
## Other readme files
|
||||
|
||||
|
@ -237,7 +219,7 @@ This project is currently mostly a one-person project.
|
|||
This is a fan game, not developed or endorsed by Mojang AB.
|
||||
|
||||
Copying is an act of love. Please copy and share! <3
|
||||
Here's the detailed legalese for those who need it:
|
||||
But, oh well, if you insist, here is the legalese for you:
|
||||
|
||||
### License of source code
|
||||
MineClone 2 is a clean-room implementation of Minecraft
|
||||
|
@ -256,14 +238,18 @@ No non-free licenses are used anywhere.
|
|||
The textures, unless otherwise noted, are based on the Pixel Perfection resource pack for Minecraft 1.11,
|
||||
authored by XSSheep. Most textures are verbatim copies, while some textures have been changed or redone
|
||||
from scratch.
|
||||
The glazed terracotta textures have been created by (MysticTempest)[https://github.com/MysticTempest].
|
||||
Source: <https://www.planetminecraft.com/texture_pack/131pixel-perfection/>
|
||||
License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)
|
||||
|
||||
The main menu images are release under: [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
|
||||
MineClone 2 is currently in the processs of changing all the textures.
|
||||
The textures for the glazed terracotta come from Faithful Vanilla.
|
||||
(authored by Vattic, xMrVizzy and many others).
|
||||
Source: <https://minecraft.curseforge.com/projects/faithful-vanilla>
|
||||
|
||||
License of all main menu images: WTFPL
|
||||
|
||||
All other files, unless mentioned otherwise, fall under:
|
||||
Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 4.0)
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 4.0)
|
||||
http://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
See README.txt in each mod directory for detailed information about other authors.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
A survival sandbox game. Survive, gather, hunt, mine, build, explore, and do much more. Faithful clone of Minecraft 1.11. This is a work in progress! Expect bugs!
|
|
@ -1,2 +1 @@
|
|||
name = MineClone 2
|
||||
description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.
|
||||
|
|
|
@ -16,7 +16,7 @@ movement_speed_climb = 2.35
|
|||
|
||||
movement_liquid_fluidity = 1.13
|
||||
movement_liquid_fluidity_smooth = 0.5
|
||||
movement_liquid_sink = 23
|
||||
movement_liquid_sink = 31
|
||||
|
||||
movement_gravity = 10.4
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
This mod automatically adds groups to items based on item metadata.
|
||||
|
||||
Specifically, this mod has 2 purposes:
|
||||
1) Automatically adding the group “solid” for blocks considered “solid” in Minecraft.
|
||||
2) Generating digging time group for all nodes based on node metadata (it's complicated)
|
||||
|
||||
See init.lua for more infos.
|
||||
|
||||
The leading underscore in the name “_mcl_autogroup” was added to force Minetest to load this mod as late as possible.
|
||||
As of 0.4.16, Minetest loads mods in reverse alphabetical order.
|
|
@ -1 +0,0 @@
|
|||
MineClone 2 core mod which automatically adds groups to all items. Very important for digging times.
|
|
@ -1 +0,0 @@
|
|||
name = _mcl_autogroup
|
|
@ -1,504 +0,0 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. 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 not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the 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
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random
|
||||
Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -1,2 +0,0 @@
|
|||
Controls framework by Arcelmi.
|
||||
https://github.com/Arcelmi/minetest-controls
|
|
@ -1,63 +0,0 @@
|
|||
controls = {}
|
||||
controls.players = {}
|
||||
|
||||
controls.registered_on_press = {}
|
||||
function controls.register_on_press(func)
|
||||
controls.registered_on_press[#controls.registered_on_press+1] = func
|
||||
end
|
||||
|
||||
controls.registered_on_release = {}
|
||||
function controls.register_on_release(func)
|
||||
controls.registered_on_release[#controls.registered_on_release+1] = func
|
||||
end
|
||||
|
||||
controls.registered_on_hold = {}
|
||||
function controls.register_on_hold(func)
|
||||
controls.registered_on_hold[#controls.registered_on_hold+1]=func
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
controls.players[name] = {
|
||||
jump={false},
|
||||
right={false},
|
||||
left={false},
|
||||
LMB={false},
|
||||
RMB={false},
|
||||
sneak={false},
|
||||
aux1={false},
|
||||
down={false},
|
||||
up={false}
|
||||
}
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
controls.players[name] = nil
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
local player_name = player:get_player_name()
|
||||
local player_controls = player:get_player_control()
|
||||
for cname, cbool in pairs(player_controls) do
|
||||
--Press a key
|
||||
if cbool==true and controls.players[player_name][cname][1]==false then
|
||||
for _, func in pairs(controls.registered_on_press) do
|
||||
func(player, cname)
|
||||
end
|
||||
controls.players[player_name][cname] = {true, os.clock()}
|
||||
elseif cbool==true and controls.players[player_name][cname][1]==true then
|
||||
for _, func in pairs(controls.registered_on_hold) do
|
||||
func(player, cname, os.clock()-controls.players[player_name][cname][2])
|
||||
end
|
||||
--Release a key
|
||||
elseif cbool==false and controls.players[player_name][cname][1]==true then
|
||||
for _, func in pairs(controls.registered_on_release) do
|
||||
func(player, cname, os.clock()-controls.players[player_name][cname][2])
|
||||
end
|
||||
controls.players[player_name][cname] = {false}
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
|
@ -1 +0,0 @@
|
|||
name=controls
|
|
@ -1 +0,0 @@
|
|||
Adds additional ways for nodes to be attached.
|
|
@ -1,24 +0,0 @@
|
|||
local original_function = minetest.check_single_for_falling
|
||||
|
||||
minetest.check_single_for_falling = function(pos)
|
||||
local ret_o = original_function(pos)
|
||||
|
||||
local ret = false
|
||||
local node = minetest.get_node(pos)
|
||||
if minetest.get_item_group(node.name, "attached_node_facedir") ~= 0 then
|
||||
local dir = minetest.facedir_to_dir(node.param2)
|
||||
local cpos = vector.add(pos, dir)
|
||||
local cnode = minetest.get_node(cpos)
|
||||
if minetest.get_item_group(cnode.name, "solid") == 0 then
|
||||
minetest.remove_node(pos)
|
||||
local drops = minetest.get_node_drops(node.name, "")
|
||||
for dr=1, #drops do
|
||||
minetest.add_item(pos, drops[dr])
|
||||
end
|
||||
ret = true
|
||||
end
|
||||
end
|
||||
|
||||
return ret_o or ret
|
||||
end
|
||||
|
|
@ -1,3 +1,11 @@
|
|||
--[[ This mod automatically adds groups to items based on item metadata.
|
||||
|
||||
Specifically, this mod has 2 purposes:
|
||||
1) Automatically adding the group “solid” for blocks considered “solid” in Minecraft.
|
||||
2) Generating digging time group for all nodes based on node metadata (it's complicated)
|
||||
|
||||
]]
|
||||
|
||||
--[[ Mining times. Yeah, mining times … Alright, this is going to be FUN!
|
||||
|
||||
This mod does include a HACK to make 100% sure the digging times of all tools match Minecraft's perfectly.
|
||||
|
@ -74,8 +82,7 @@ local overwrite = function()
|
|||
groups_changed = true
|
||||
end
|
||||
-- Automatically assign the “opaque” group for opaque nodes
|
||||
if (not (ndef.paramtype == "light" or ndef.sunlight_propagates)) and
|
||||
(ndef.groups.not_opaque == 0 or ndef.groups.not_opaque == nil) then
|
||||
if not (ndef.paramtype == "light" or ndef.sunlight_propagates) then
|
||||
newgroups.opaque = 1
|
||||
groups_changed = true
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
name = mcl_autogroup
|
|
@ -1,24 +1,17 @@
|
|||
-- Some global variables (don't overwrite them!)
|
||||
mcl_vars = {}
|
||||
|
||||
--- GUI / inventory menu settings
|
||||
--- GUI / inventory menu colors
|
||||
mcl_vars.gui_slots = "listcolors[#9990;#FFF7;#FFF0;#000;#FFF]"
|
||||
-- nonbg is added as formspec prepend in mcl_formspec_prepend
|
||||
mcl_vars.gui_nonbg = mcl_vars.gui_slots
|
||||
|
||||
-- Background stuff must be manually added by mods (no formspec prepend)
|
||||
mcl_vars.gui_bg = "bgcolor[#080808BB;true]"
|
||||
mcl_vars.gui_bg_img = ""
|
||||
|
||||
mcl_vars.inventory_header = mcl_vars.gui_bg
|
||||
mcl_vars.inventory_header = mcl_vars.gui_slots .. mcl_vars.gui_bg
|
||||
|
||||
-- Mapgen variables
|
||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||
local minecraft_height_limit = 256
|
||||
local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true"
|
||||
|
||||
if not superflat then
|
||||
-- Normal mode
|
||||
if mg_name ~= "flat" then
|
||||
--[[ Realm stacking (h is for height)
|
||||
- Overworld (h>=256)
|
||||
- Void (h>=1000)
|
||||
|
@ -39,13 +32,17 @@ if not superflat then
|
|||
mcl_vars.mg_bedrock_is_rough = true
|
||||
|
||||
else
|
||||
-- Classic superflat
|
||||
local ground = minetest.get_mapgen_setting("mgflat_ground_level")
|
||||
ground = tonumber(ground)
|
||||
if not ground then
|
||||
ground = 8
|
||||
end
|
||||
mcl_vars.mg_overworld_min = ground - 3
|
||||
-- 1 perfectly flat bedrock layer
|
||||
if minetest.get_mapgen_setting("mcl_superflat_classic") == "false" then
|
||||
mcl_vars.mg_overworld_min = -30912
|
||||
else
|
||||
mcl_vars.mg_overworld_min = ground - 3
|
||||
end
|
||||
mcl_vars.mg_overworld_max_official = mcl_vars.mg_overworld_min + minecraft_height_limit
|
||||
mcl_vars.mg_bedrock_overworld_min = mcl_vars.mg_overworld_min
|
||||
mcl_vars.mg_bedrock_overworld_max = mcl_vars.mg_bedrock_overworld_min
|
||||
|
@ -61,32 +58,20 @@ mcl_vars.mg_nether_min = -29067 -- Carefully chosen to be at a mapchunk border
|
|||
mcl_vars.mg_nether_max = mcl_vars.mg_nether_min + 128
|
||||
mcl_vars.mg_bedrock_nether_bottom_min = mcl_vars.mg_nether_min
|
||||
mcl_vars.mg_bedrock_nether_top_max = mcl_vars.mg_nether_max
|
||||
if not superflat then
|
||||
mcl_vars.mg_lava_nether_max = mcl_vars.mg_nether_min + 31
|
||||
if mg_name ~= "flat" then
|
||||
mcl_vars.mg_bedrock_nether_bottom_max = mcl_vars.mg_bedrock_nether_bottom_min + 4
|
||||
mcl_vars.mg_bedrock_nether_top_min = mcl_vars.mg_bedrock_nether_top_max - 4
|
||||
mcl_vars.mg_lava_nether_max = mcl_vars.mg_nether_min + 31
|
||||
else
|
||||
-- Thin bedrock in classic superflat mapgen
|
||||
-- Thin bedrock in flat mapgen
|
||||
mcl_vars.mg_bedrock_nether_bottom_max = mcl_vars.mg_bedrock_nether_bottom_min
|
||||
mcl_vars.mg_bedrock_nether_top_min = mcl_vars.mg_bedrock_nether_top_max
|
||||
mcl_vars.mg_lava_nether_max = mcl_vars.mg_nether_min + 2
|
||||
end
|
||||
if mg_name == "flat" then
|
||||
if superflat then
|
||||
mcl_vars.mg_flat_nether_floor = mcl_vars.mg_bedrock_nether_bottom_max + 4
|
||||
mcl_vars.mg_flat_nether_ceiling = mcl_vars.mg_bedrock_nether_bottom_max + 52
|
||||
else
|
||||
mcl_vars.mg_flat_nether_floor = mcl_vars.mg_lava_nether_max + 4
|
||||
mcl_vars.mg_flat_nether_ceiling = mcl_vars.mg_lava_nether_max + 52
|
||||
end
|
||||
end
|
||||
|
||||
-- The End (surface at ca. Y = -27000)
|
||||
mcl_vars.mg_end_min = -27073 -- Carefully chosen to be at a mapchunk border
|
||||
mcl_vars.mg_end_max_official = mcl_vars.mg_end_min + minecraft_height_limit
|
||||
mcl_vars.mg_end_max = mcl_vars.mg_overworld_min - 2000
|
||||
mcl_vars.mg_end_platform_pos = { x = 100, y = mcl_vars.mg_end_min + 80, z = 0 }
|
||||
|
||||
-- Realm barrier used to safely separate the End from the void below the Overworld
|
||||
mcl_vars.mg_realm_barrier_overworld_end_max = mcl_vars.mg_end_max
|
||||
mcl_vars.mg_realm_barrier_overworld_end_min = mcl_vars.mg_end_max - 11
|
||||
|
|
|
@ -98,54 +98,3 @@ function mcl_loot.get_multi_loot(multi_loot_definitions, pr)
|
|||
end
|
||||
return items
|
||||
end
|
||||
|
||||
--[[
|
||||
Returns a table of length `max_slot` and all natural numbers between 1 and `max_slot`
|
||||
in a random order.
|
||||
]]
|
||||
local function get_random_slots(max_slot)
|
||||
local slots = {}
|
||||
for s=1, max_slot do
|
||||
slots[s] = s
|
||||
end
|
||||
local slots_out = {}
|
||||
while #slots > 0 do
|
||||
local r = math.random(1, #slots)
|
||||
table.insert(slots_out, slots[r])
|
||||
table.remove(slots, r)
|
||||
end
|
||||
return slots_out
|
||||
end
|
||||
|
||||
--[[
|
||||
Puts items in an inventory list into random slots.
|
||||
* inv: InvRef
|
||||
* listname: Inventory list name
|
||||
* items: table of items to add
|
||||
|
||||
Items will be added from start of the table to end.
|
||||
If the inventory already has occupied slots, or is
|
||||
too small, placement of some items might fail.
|
||||
]]
|
||||
function mcl_loot.fill_inventory(inv, listname, items)
|
||||
local size = inv:get_size(listname)
|
||||
local slots = get_random_slots(size)
|
||||
local leftovers = {}
|
||||
-- 1st pass: Add items into random slots
|
||||
for i=1, math.min(#items, size) do
|
||||
local item = items[i]
|
||||
local slot = slots[i]
|
||||
local old_item = inv:get_stack(listname, slot)
|
||||
local leftover = old_item:add_item(item)
|
||||
inv:set_stack(listname, slot, old_item)
|
||||
if not leftover:is_empty() then
|
||||
table.insert(leftovers, item)
|
||||
end
|
||||
end
|
||||
-- 2nd pass: If some items couldn't be added in first pass,
|
||||
-- try again in a non-random fashion
|
||||
for l=1, math.min(#leftovers, size) do
|
||||
inv:add_item(listname, leftovers[l])
|
||||
end
|
||||
-- If there are still items left, tough luck!
|
||||
end
|
||||
|
|
|
@ -67,21 +67,14 @@ blukotek (CC0 1.0)
|
|||
https://www.freesound.org/people/blukotek/sounds/251660/
|
||||
default_dig_snappy.ogg
|
||||
|
||||
sonictechtonic (CC BY 3.0)
|
||||
https://www.freesound.org/people/sonictechtonic/sounds/241872/
|
||||
player_damage.ogg
|
||||
|
||||
Voxelands project <http://www.voxelands.com/> (CC BY-SA 3.0)
|
||||
mcl_sounds_place_node_water.ogg
|
||||
mcl_sounds_dug_water.ogg
|
||||
player_damage.ogg
|
||||
|
||||
(Note: Artists from the Voxelands project include: sdzen, darkrose, sapier,
|
||||
Tom Peter, Telaron, juskiddink)
|
||||
|
||||
Michel Baradari <https://opengameart.org/content/lava-splash> (CC BY 3.0)
|
||||
|
||||
default_place_node_lava.ogg
|
||||
|
||||
Adam_N (CC0 1.0):
|
||||
player_falling_damage.ogg
|
||||
Source: <https://www.freesound.org/people/Adam_N/sounds/346692/>
|
||||
|
|
|
@ -134,21 +134,3 @@ function mcl_sounds.node_sound_water_defaults(table)
|
|||
mcl_sounds.node_sound_defaults(table)
|
||||
return table
|
||||
end
|
||||
|
||||
function mcl_sounds.node_sound_lava_defaults(table)
|
||||
table = table or {}
|
||||
-- TODO: Footstep
|
||||
table.place = table.place or
|
||||
{name = "default_place_node_lava", gain = 1.0}
|
||||
table.dug = table.dug or
|
||||
{name = "default_place_node_lava", gain = 1.0}
|
||||
-- TODO: Different dug sound
|
||||
mcl_sounds.node_sound_defaults(table)
|
||||
return table
|
||||
end
|
||||
|
||||
-- Player death sound
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
-- TODO: Add separate death sound
|
||||
minetest.sound_play({name="player_damage", gain = 1.0}, {pos=player:get_pos(), max_hear_distance=16})
|
||||
end)
|
||||
|
|
|
@ -149,7 +149,7 @@ function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_i
|
|||
return nil
|
||||
end
|
||||
|
||||
-- Returns true if itemstack is a shulker box
|
||||
-- Returns true if given itemstack is a shulker box
|
||||
local is_not_shulker_box = function(itemstack)
|
||||
local g = minetest.get_item_group(itemstack:get_name(), "shulker_box")
|
||||
return g == 0 or g == nil
|
||||
|
@ -205,11 +205,6 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list,
|
|||
local dctype = minetest.get_item_group(dnode.name, "container")
|
||||
local sctype = minetest.get_item_group(snode.name, "container")
|
||||
|
||||
-- Container type 7 does not allow any movement
|
||||
if sctype == 7 then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Normalize double container by forcing to always use the left segment first
|
||||
local normalize_double_container = function(pos, node, ctype)
|
||||
if ctype == 6 then
|
||||
|
@ -240,7 +235,7 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list,
|
|||
-- Default source lists
|
||||
if not source_list then
|
||||
-- Main inventory for most container types
|
||||
if sctype == 2 or sctype == 3 or sctype == 5 or sctype == 6 or sctype == 7 then
|
||||
if sctype == 2 or sctype == 3 or sctype == 5 or sctype == 6 then
|
||||
source_list = "main"
|
||||
-- Furnace: output
|
||||
elseif sctype == 4 then
|
||||
|
@ -286,17 +281,13 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list,
|
|||
return false
|
||||
end
|
||||
end
|
||||
-- Container type 7 does not allow any placement
|
||||
if dctype == 7 then
|
||||
return false
|
||||
end
|
||||
|
||||
-- If it's a container, put it into the container
|
||||
if dctype ~= 0 then
|
||||
-- Automatically select a destination list if omitted
|
||||
if not destination_list then
|
||||
-- Main inventory for most container types
|
||||
if dctype == 2 or dctype == 3 or dctype == 5 or dctype == 6 or dctype == 7 then
|
||||
if dctype == 2 or dctype == 3 or dctype == 5 or dctype == 6 then
|
||||
destination_list = "main"
|
||||
-- Furnace source slot
|
||||
elseif dctype == 4 then
|
||||
|
@ -340,13 +331,90 @@ function mcl_util.is_fuel(item)
|
|||
return minetest.get_craft_result({method="fuel", width=1, items={item}}).time ~= 0
|
||||
end
|
||||
|
||||
-- For a given position, returns a 2-tuple:
|
||||
-- 1st return value: true if pos is in void
|
||||
-- 2nd return value: true if it is in the deadly part of the void
|
||||
function mcl_util.is_in_void(pos)
|
||||
local void =
|
||||
not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or
|
||||
(pos.y < mcl_vars.mg_nether_max and pos.y > mcl_vars.mg_nether_min) or
|
||||
(pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min))
|
||||
|
||||
local void_deadly = false
|
||||
local deadly_tolerance = 64 -- the player must be this many nodes “deep” into the void to be damaged
|
||||
if void then
|
||||
-- Overworld → Void → End → Void → Nether → Void
|
||||
if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then
|
||||
void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance
|
||||
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max then
|
||||
void_deadly = pos.y < mcl_vars.mg_end_min - deadly_tolerance
|
||||
elseif pos.y < mcl_vars.mg_nether_min then
|
||||
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance
|
||||
end
|
||||
end
|
||||
return void, void_deadly
|
||||
end
|
||||
|
||||
-- Here come 2 simple converter functions which are important for map generators and mob spawning
|
||||
|
||||
-- Takes an Y coordinate as input and returns:
|
||||
-- 1) The corresponding Minecraft layer (can be nil if void)
|
||||
-- 2) The corresponding Minecraft dimension ("overworld", "nether" or "end") or "void" if it is in the void
|
||||
-- If the Y coordinate is not located in any dimension, it will return:
|
||||
-- nil, "void"
|
||||
function mcl_util.y_to_layer(y)
|
||||
if y >= mcl_vars.mg_overworld_min then
|
||||
return y - mcl_vars.mg_overworld_min, "overworld"
|
||||
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max then
|
||||
return y - mcl_vars.mg_nether_min, "nether"
|
||||
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
||||
return y - mcl_vars.mg_end_min, "end"
|
||||
else
|
||||
return nil, "void"
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a Minecraft layer and a “dimension” name
|
||||
-- and returns the corresponding Y coordinate for
|
||||
-- MineClone 2.
|
||||
-- mc_dimension is one of "overworld", "nether", "end" (default: "overworld").
|
||||
function mcl_util.layer_to_y(layer, mc_dimension)
|
||||
if mc_dimension == "overworld" or mc_dimension == nil then
|
||||
return layer + mcl_vars.mg_overworld_min
|
||||
elseif mc_dimension == "nether" then
|
||||
return layer + mcl_vars.mg_nether_min
|
||||
elseif mc_dimension == "end" then
|
||||
return layer + mcl_vars.mg_end_min
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a position and returns true if this position can have weather
|
||||
function mcl_util.has_weather(pos)
|
||||
-- Weather in the Overworld and the high part of the void below
|
||||
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64
|
||||
end
|
||||
|
||||
-- Takes a position (pos) and returns true if compasses are working here
|
||||
function mcl_util.compass_works(pos)
|
||||
-- It doesn't work in Nether and the End, but it works in the Overworld and in the high part of the void below
|
||||
local _, dim = mcl_util.y_to_layer(pos.y)
|
||||
if dim == "nether" or dim == "end" then
|
||||
return false
|
||||
elseif dim == "void" then
|
||||
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a position (pos) and returns true if clocks are working here
|
||||
mcl_util.clock_works = mcl_util.compass_works
|
||||
|
||||
-- Returns a on_place function for plants
|
||||
-- * condition: function(pos, node, itemstack)
|
||||
-- * condition: function(pos, node)
|
||||
-- * A function which is called by the on_place function to check if the node can be placed
|
||||
-- * Must return true, if placement is allowed, false otherwise.
|
||||
-- * If it returns a string, placement is allowed, but will place this itemstring as a node instead
|
||||
-- * Must return true, if placement is allowed, false otherwise
|
||||
-- * pos, node: Position and node table of plant node
|
||||
-- * itemstack: Itemstack to place
|
||||
function mcl_util.generate_on_place_plant_function(condition)
|
||||
return function(itemstack, placer, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
|
@ -377,10 +445,9 @@ function mcl_util.generate_on_place_plant_function(condition)
|
|||
end
|
||||
|
||||
-- Check placement rules
|
||||
local result, param2 = condition(place_pos, node, itemstack)
|
||||
if result == true then
|
||||
if (condition(place_pos, node) == true) then
|
||||
local idef = itemstack:get_definition()
|
||||
local new_itemstack, success = minetest.item_place_node(itemstack, placer, pointed_thing, param2)
|
||||
local new_itemstack, success = minetest.item_place_node(itemstack, placer, pointed_thing)
|
||||
|
||||
if success then
|
||||
if idef.sounds and idef.sounds.place then
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
mcl_init
|
|
@ -1 +0,0 @@
|
|||
Utility functions for worlds and the “dimensions”.
|
|
@ -1,140 +0,0 @@
|
|||
mcl_worlds = {}
|
||||
|
||||
-- For a given position, returns a 2-tuple:
|
||||
-- 1st return value: true if pos is in void
|
||||
-- 2nd return value: true if it is in the deadly part of the void
|
||||
function mcl_worlds.is_in_void(pos)
|
||||
local void =
|
||||
not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or
|
||||
(pos.y < mcl_vars.mg_nether_max and pos.y > mcl_vars.mg_nether_min) or
|
||||
(pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min))
|
||||
|
||||
local void_deadly = false
|
||||
local deadly_tolerance = 64 -- the player must be this many nodes “deep” into the void to be damaged
|
||||
if void then
|
||||
-- Overworld → Void → End → Void → Nether → Void
|
||||
if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then
|
||||
void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance
|
||||
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max then
|
||||
-- The void between End and Nether. Like usual, but here, the void
|
||||
-- *above* the Nether also has a small tolerance area, so player
|
||||
-- can fly above the Nether without getting hurt instantly.
|
||||
void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max + deadly_tolerance)
|
||||
elseif pos.y < mcl_vars.mg_nether_min then
|
||||
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance
|
||||
end
|
||||
end
|
||||
return void, void_deadly
|
||||
end
|
||||
|
||||
-- Takes an Y coordinate as input and returns:
|
||||
-- 1) The corresponding Minecraft layer (can be nil if void)
|
||||
-- 2) The corresponding Minecraft dimension ("overworld", "nether" or "end") or "void" if it is in the void
|
||||
-- If the Y coordinate is not located in any dimension, it will return:
|
||||
-- nil, "void"
|
||||
function mcl_worlds.y_to_layer(y)
|
||||
if y >= mcl_vars.mg_overworld_min then
|
||||
return y - mcl_vars.mg_overworld_min, "overworld"
|
||||
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max then
|
||||
return y - mcl_vars.mg_nether_min, "nether"
|
||||
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
||||
return y - mcl_vars.mg_end_min, "end"
|
||||
else
|
||||
return nil, "void"
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a pos and returns the dimension it belongs to (same as above)
|
||||
function mcl_worlds.pos_to_dimension(pos)
|
||||
local _, dim = mcl_worlds.y_to_layer(pos.y)
|
||||
return dim
|
||||
end
|
||||
|
||||
-- Takes a Minecraft layer and a “dimension” name
|
||||
-- and returns the corresponding Y coordinate for
|
||||
-- MineClone 2.
|
||||
-- mc_dimension is one of "overworld", "nether", "end" (default: "overworld").
|
||||
function mcl_worlds.layer_to_y(layer, mc_dimension)
|
||||
if mc_dimension == "overworld" or mc_dimension == nil then
|
||||
return layer + mcl_vars.mg_overworld_min
|
||||
elseif mc_dimension == "nether" then
|
||||
return layer + mcl_vars.mg_nether_min
|
||||
elseif mc_dimension == "end" then
|
||||
return layer + mcl_vars.mg_end_min
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a position and returns true if this position can have weather
|
||||
function mcl_worlds.has_weather(pos)
|
||||
-- Weather in the Overworld and the high part of the void below
|
||||
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64
|
||||
end
|
||||
|
||||
-- Takes a position (pos) and returns true if compasses are working here
|
||||
function mcl_worlds.compass_works(pos)
|
||||
-- It doesn't work in Nether and the End, but it works in the Overworld and in the high part of the void below
|
||||
local _, dim = mcl_worlds.y_to_layer(pos.y)
|
||||
if dim == "nether" or dim == "end" then
|
||||
return false
|
||||
elseif dim == "void" then
|
||||
return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- Takes a position (pos) and returns true if clocks are working here
|
||||
mcl_worlds.clock_works = mcl_worlds.compass_works
|
||||
|
||||
--------------- CALLBACKS ------------------
|
||||
mcl_worlds.registered_on_dimension_change = {}
|
||||
|
||||
-- Register a callback function func(player, dimension).
|
||||
-- It will be called whenever a player changes between dimensions.
|
||||
-- The void counts as dimension.
|
||||
-- * player: The player who changed the dimension
|
||||
-- * dimension: The new dimension of the player ("overworld", "nether", "end", "void").
|
||||
function mcl_worlds.register_on_dimension_change(func)
|
||||
table.insert(mcl_worlds.registered_on_dimension_change, func)
|
||||
end
|
||||
|
||||
-- Playername-indexed table containig the name of the last known dimension the
|
||||
-- player was in.
|
||||
local last_dimension = {}
|
||||
|
||||
-- Notifies this mod about a dimension change of a player.
|
||||
-- * player: Player who changed the dimension
|
||||
-- * dimension: New dimension ("overworld", "nether", "end", "void")
|
||||
function mcl_worlds.dimension_change(player, dimension)
|
||||
for i=1, #mcl_worlds.registered_on_dimension_change do
|
||||
mcl_worlds.registered_on_dimension_change[i](player, dimension)
|
||||
last_dimension[player:get_player_name()] = dimension
|
||||
end
|
||||
end
|
||||
|
||||
----------------------- INTERNAL STUFF ----------------------
|
||||
|
||||
-- Update the dimension callbacks every DIM_UPDATE seconds
|
||||
local DIM_UPDATE = 1
|
||||
local dimtimer = 0
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
last_dimension[player:get_player_name()] = mcl_worlds.pos_to_dimension(player:get_pos())
|
||||
end)
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
-- regular updates based on iterval
|
||||
dimtimer = dimtimer + dtime;
|
||||
if dimtimer >= DIM_UPDATE then
|
||||
local players = minetest.get_connected_players()
|
||||
for p=1, #players do
|
||||
local dim = mcl_worlds.pos_to_dimension(players[p]:get_pos())
|
||||
local name = players[p]:get_player_name()
|
||||
if dim ~= last_dimension[name] then
|
||||
mcl_worlds.dimension_change(players[p], dim)
|
||||
end
|
||||
end
|
||||
dimtimer = 0
|
||||
end
|
||||
end)
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
name = CORE
|
||||
description = Meta-modpack containing the core mods for MineClone 2 for core APIs, variables and definitions
|
|
@ -4,7 +4,7 @@ minetest.register_globalstep(function(dtime)
|
|||
timer = timer + dtime;
|
||||
if timer >= 0.3 then
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
local pp = player:get_pos()
|
||||
local pp = player:getpos()
|
||||
pp.y = math.ceil(pp.y)
|
||||
local loc = vector.add(pp, {x=0,y=-1,z=0})
|
||||
if loc ~= nil then
|
||||
|
|
|
@ -13,7 +13,6 @@ minetest.register_entity("drippingwater:drop_water", {
|
|||
physical = true,
|
||||
collide_with_objects = false,
|
||||
collisionbox = {0,0,0,0,0,0},
|
||||
pointable = false,
|
||||
visual = "cube",
|
||||
visual_size = {x=0.05, y=0.1},
|
||||
textures = {water_tex, water_tex, water_tex, water_tex, water_tex, water_tex},
|
||||
|
@ -21,19 +20,19 @@ minetest.register_entity("drippingwater:drop_water", {
|
|||
initial_sprite_basepos = {x=0, y=0},
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_sprite({x=0,y=0}, 1, 1, true)
|
||||
self.object:setsprite({x=0,y=0}, 1, 1, true)
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
local k = math.random(1,222)
|
||||
local ownpos = self.object:get_pos()
|
||||
local ownpos = self.object:getpos()
|
||||
|
||||
if k==1 then
|
||||
self.object:set_acceleration({x=0, y=-5, z=0})
|
||||
self.object:setacceleration({x=0, y=-5, z=0})
|
||||
end
|
||||
|
||||
if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then
|
||||
self.object:set_acceleration({x=0, y=-5, z=0})
|
||||
self.object:setacceleration({x=0, y=-5, z=0})
|
||||
end
|
||||
|
||||
if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then
|
||||
|
@ -59,19 +58,19 @@ minetest.register_entity("drippingwater:drop_lava", {
|
|||
initial_sprite_basepos = {x=0, y=0},
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_sprite({x=0,y=0}, 1, 0, true)
|
||||
self.object:setsprite({x=0,y=0}, 1, 0, true)
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
local k = math.random(1,222)
|
||||
local ownpos = self.object:get_pos()
|
||||
local ownpos = self.object:getpos()
|
||||
|
||||
if k==1 then
|
||||
self.object:set_acceleration({x=0, y=-5, z=0})
|
||||
self.object:setacceleration({x=0, y=-5, z=0})
|
||||
end
|
||||
|
||||
if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then
|
||||
self.object:set_acceleration({x=0, y=-5, z=0})
|
||||
self.object:setacceleration({x=0, y=-5, z=0})
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
local S = minetest.get_translator("mcl_boats")
|
||||
--
|
||||
-- Helper functions
|
||||
--
|
||||
|
@ -68,9 +67,9 @@ function boat.on_rightclick(self, clicker)
|
|||
clicker:set_properties({visual_size = {x=1, y=1}})
|
||||
mcl_player.player_attached[name] = false
|
||||
mcl_player.player_set_animation(clicker, "stand" , 30)
|
||||
local pos = clicker:get_pos()
|
||||
local pos = clicker:getpos()
|
||||
pos = {x = pos.x, y = pos.y + 0.2, z = pos.z}
|
||||
clicker:set_pos(pos)
|
||||
clicker:setpos(pos)
|
||||
elseif not self._driver then
|
||||
local attach = clicker:get_attach()
|
||||
if attach and attach:get_luaentity() then
|
||||
|
@ -83,16 +82,15 @@ function boat.on_rightclick(self, clicker)
|
|||
end
|
||||
self._driver = clicker
|
||||
clicker:set_attach(self.object, "",
|
||||
{x = 0, y = 0.42, z = -1}, {x = 0, y = 0, z = 0})
|
||||
{x = 0, y = 3.75, z = -1}, {x = 0, y = 0, z = 0})
|
||||
clicker:set_properties({ visual_size = driver_visual_size })
|
||||
mcl_player.player_attached[name] = true
|
||||
minetest.after(0.2, function(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
mcl_player.player_set_animation(player, "sit" , 30)
|
||||
minetest.after(0.2, function(clicker)
|
||||
if clicker:is_player() then
|
||||
mcl_player.player_set_animation(clicker, "sit" , 30)
|
||||
end
|
||||
end, name)
|
||||
clicker:set_look_horizontal(self.object:get_yaw())
|
||||
end, clicker)
|
||||
clicker:set_look_horizontal(self.object:getyaw())
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -132,22 +130,17 @@ function boat.on_punch(self, puncher)
|
|||
self._removed = true
|
||||
-- Drop boat as item on the ground after punching
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
minetest.add_item(self.object:get_pos(), self._itemstring)
|
||||
else
|
||||
local inv = puncher:get_inventory()
|
||||
if not inv:contains_item("main", self._itemstring) then
|
||||
inv:add_item("main", self._itemstring)
|
||||
end
|
||||
minetest.add_item(self.object:getpos(), self._itemstring)
|
||||
end
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
|
||||
function boat.on_step(self, dtime)
|
||||
self._v = get_v(self.object:get_velocity()) * get_sign(self._v)
|
||||
self._v = get_v(self.object:getvelocity()) * get_sign(self._v)
|
||||
if self._driver then
|
||||
local ctrl = self._driver:get_player_control()
|
||||
local yaw = self.object:get_yaw()
|
||||
local yaw = self.object:getyaw()
|
||||
if ctrl.up then
|
||||
-- Forwards
|
||||
self._v = self._v + 0.1
|
||||
|
@ -175,15 +168,15 @@ function boat.on_step(self, dtime)
|
|||
end
|
||||
if ctrl.left then
|
||||
if self._v < 0 then
|
||||
self.object:set_yaw(yaw - (1 + dtime) * 0.03)
|
||||
self.object:setyaw(yaw - (1 + dtime) * 0.03)
|
||||
else
|
||||
self.object:set_yaw(yaw + (1 + dtime) * 0.03)
|
||||
self.object:setyaw(yaw + (1 + dtime) * 0.03)
|
||||
end
|
||||
elseif ctrl.right then
|
||||
if self._v < 0 then
|
||||
self.object:set_yaw(yaw + (1 + dtime) * 0.03)
|
||||
self.object:setyaw(yaw + (1 + dtime) * 0.03)
|
||||
else
|
||||
self.object:set_yaw(yaw - (1 + dtime) * 0.03)
|
||||
self.object:setyaw(yaw - (1 + dtime) * 0.03)
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -193,15 +186,15 @@ function boat.on_step(self, dtime)
|
|||
self._animation = 0
|
||||
end
|
||||
end
|
||||
local velo = self.object:get_velocity()
|
||||
local velo = self.object:getvelocity()
|
||||
if self._v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
||||
self.object:set_pos(self.object:get_pos())
|
||||
self.object:setpos(self.object:getpos())
|
||||
return
|
||||
end
|
||||
local s = get_sign(self._v)
|
||||
self._v = self._v - 0.02 * s
|
||||
if s ~= get_sign(self._v) then
|
||||
self.object:set_velocity({x = 0, y = 0, z = 0})
|
||||
self.object:setvelocity({x = 0, y = 0, z = 0})
|
||||
self._v = 0
|
||||
return
|
||||
end
|
||||
|
@ -209,7 +202,7 @@ function boat.on_step(self, dtime)
|
|||
self._v = 5 * get_sign(self._v)
|
||||
end
|
||||
|
||||
local p = self.object:get_pos()
|
||||
local p = self.object:getpos()
|
||||
p.y = p.y - boat_y_offset
|
||||
local new_velo
|
||||
local new_acce = {x = 0, y = 0, z = 0}
|
||||
|
@ -221,13 +214,13 @@ function boat.on_step(self, dtime)
|
|||
else
|
||||
new_acce = {x = 0, y = -9.8, z = 0}
|
||||
end
|
||||
new_velo = get_velocity(self._v, self.object:get_yaw(),
|
||||
self.object:get_velocity().y)
|
||||
self.object:set_pos(self.object:get_pos())
|
||||
new_velo = get_velocity(self._v, self.object:getyaw(),
|
||||
self.object:getvelocity().y)
|
||||
self.object:setpos(self.object:getpos())
|
||||
else
|
||||
p.y = p.y + 1
|
||||
if is_water(p) then
|
||||
local y = self.object:get_velocity().y
|
||||
local y = self.object:getvelocity().y
|
||||
if y >= 5 then
|
||||
y = 5
|
||||
elseif y < 0 then
|
||||
|
@ -235,31 +228,31 @@ function boat.on_step(self, dtime)
|
|||
else
|
||||
new_acce = {x = 0, y = 5, z = 0}
|
||||
end
|
||||
new_velo = get_velocity(self._v, self.object:get_yaw(), y)
|
||||
self.object:set_pos(self.object:get_pos())
|
||||
new_velo = get_velocity(self._v, self.object:getyaw(), y)
|
||||
self.object:setpos(self.object:getpos())
|
||||
else
|
||||
new_acce = {x = 0, y = 0, z = 0}
|
||||
if math.abs(self.object:get_velocity().y) < 1 then
|
||||
local pos = self.object:get_pos()
|
||||
if math.abs(self.object:getvelocity().y) < 1 then
|
||||
local pos = self.object:getpos()
|
||||
pos.y = math.floor(pos.y) + boat_y_offset
|
||||
self.object:set_pos(pos)
|
||||
new_velo = get_velocity(self._v, self.object:get_yaw(), 0)
|
||||
self.object:setpos(pos)
|
||||
new_velo = get_velocity(self._v, self.object:getyaw(), 0)
|
||||
else
|
||||
new_velo = get_velocity(self._v, self.object:get_yaw(),
|
||||
self.object:get_velocity().y)
|
||||
self.object:set_pos(self.object:get_pos())
|
||||
new_velo = get_velocity(self._v, self.object:getyaw(),
|
||||
self.object:getvelocity().y)
|
||||
self.object:setpos(self.object:getpos())
|
||||
end
|
||||
end
|
||||
end
|
||||
self.object:set_velocity(new_velo)
|
||||
self.object:set_acceleration(new_acce)
|
||||
self.object:setvelocity(new_velo)
|
||||
self.object:setacceleration(new_acce)
|
||||
end
|
||||
|
||||
-- Register one entity for all boat types
|
||||
minetest.register_entity("mcl_boats:boat", boat)
|
||||
|
||||
local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak" }
|
||||
local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat") }
|
||||
local names = { "Oak Boat", "Spruce Boat", "Birch Boat", "Jungle Boat", "Acacia Boat", "Dark Oak Boat" }
|
||||
local craftstuffs = {}
|
||||
if minetest.get_modpath("mcl_core") then
|
||||
craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood" }
|
||||
|
@ -274,9 +267,9 @@ for b=1, #boat_ids do
|
|||
-- Only create one help entry for all boats
|
||||
if b == 1 then
|
||||
help = true
|
||||
longdesc = S("Boats are used to travel on the surface of water.")
|
||||
usagehelp = S("Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to make it drop as an item.")
|
||||
helpname = S("Boat")
|
||||
longdesc = "Boats are used to travel on the surface of water."
|
||||
usagehelp = "Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to make it drop as an item."
|
||||
helpname = "Boat"
|
||||
end
|
||||
|
||||
minetest.register_craftitem(itemstring, {
|
||||
|
@ -309,22 +302,11 @@ for b=1, #boat_ids do
|
|||
local boat = minetest.add_entity(pointed_thing.under, "mcl_boats:boat")
|
||||
boat:get_luaentity()._itemstring = itemstring
|
||||
boat:set_properties({textures = { "mcl_boats_texture_"..images[b].."_boat.png" }})
|
||||
boat:set_yaw(placer:get_look_horizontal())
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
||||
local below = {x=droppos.x, y=droppos.y-1, z=droppos.z}
|
||||
local belownode = minetest.get_node(below)
|
||||
-- Place boat as entity on or in water
|
||||
if minetest.get_item_group(dropnode.name, "water") ~= 0 or (dropnode.name == "air" and minetest.get_item_group(belownode.name, "water") ~= 0) then
|
||||
minetest.add_entity(droppos, "mcl_boats:boat")
|
||||
else
|
||||
minetest.add_item(droppos, stack)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
local c = craftstuffs[b]
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Falling node entities, Minecraft-style
|
|
@ -1,256 +0,0 @@
|
|||
local dmes = minetest.get_modpath("mcl_death_messages") ~= nil
|
||||
|
||||
local get_falling_depth = function(self)
|
||||
if not self._startpos then
|
||||
-- Fallback
|
||||
self._startpos = self.object:get_pos()
|
||||
end
|
||||
return self._startpos.y - vector.round(self.object:get_pos()).y
|
||||
end
|
||||
|
||||
local deal_falling_damage = function(self, dtime)
|
||||
if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then
|
||||
return
|
||||
end
|
||||
-- Cause damage to any player it hits.
|
||||
-- Algorithm based on MC anvils.
|
||||
-- TODO: Support smashing other objects, too.
|
||||
local pos = self.object:get_pos()
|
||||
if not self._startpos then
|
||||
-- Fallback
|
||||
self._startpos = pos
|
||||
end
|
||||
local objs = minetest.get_objects_inside_radius(pos, 1)
|
||||
for _,v in ipairs(objs) do
|
||||
local hp = v:get_hp()
|
||||
if v:is_player() and hp ~= 0 then
|
||||
if not self._hit_players then
|
||||
self._hit_players = {}
|
||||
end
|
||||
local name = v:get_player_name()
|
||||
local hit = false
|
||||
for _,v in ipairs(self._hit_players) do
|
||||
if name == v then
|
||||
hit = true
|
||||
end
|
||||
end
|
||||
if not hit then
|
||||
table.insert(self._hit_players, name)
|
||||
local way = self._startpos.y - pos.y
|
||||
local damage = (way - 1) * 2
|
||||
damage = math.min(40, math.max(0, damage))
|
||||
if damage >= 1 then
|
||||
hp = hp - damage
|
||||
if hp < 0 then
|
||||
hp = 0
|
||||
end
|
||||
if v:is_player() then
|
||||
-- TODO: Reduce damage if wearing a helmet
|
||||
local msg
|
||||
if minetest.get_item_group(self.node.name, "anvil") ~= 0 then
|
||||
msg = "%s was smashed by a falling anvil."
|
||||
else
|
||||
msg = "%s was smashed by a falling block."
|
||||
end
|
||||
if dmes then
|
||||
mcl_death_messages.player_damage(v, string.format(msg, v:get_player_name()))
|
||||
end
|
||||
end
|
||||
v:set_hp(hp)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_entity(":__builtin:falling_node", {
|
||||
initial_properties = {
|
||||
visual = "wielditem",
|
||||
visual_size = {x = 0.667, y = 0.667},
|
||||
textures = {},
|
||||
physical = true,
|
||||
is_visible = false,
|
||||
collide_with_objects = false,
|
||||
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
||||
},
|
||||
|
||||
node = {},
|
||||
meta = {},
|
||||
|
||||
set_node = function(self, node, meta)
|
||||
self.node = node
|
||||
self.meta = meta or {}
|
||||
self.object:set_properties({
|
||||
is_visible = true,
|
||||
textures = {node.name},
|
||||
})
|
||||
local def = core.registered_nodes[node.name]
|
||||
-- Set correct entity yaw
|
||||
if def and node.param2 ~= 0 then
|
||||
if (def.paramtype2 == "facedir" or def.paramtype2 == "colorfacedir") then
|
||||
self.object:set_yaw(core.dir_to_yaw(core.facedir_to_dir(node.param2)))
|
||||
elseif (def.paramtype2 == "wallmounted" or def.paramtype2 == "colorwallmounted") then
|
||||
self.object:set_yaw(core.dir_to_yaw(core.wallmounted_to_dir(node.param2)))
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
local meta = self.meta
|
||||
-- Workaround: Save inventory seperately from metadata.
|
||||
-- Because Minetest crashes when a node with inventory gets deactivated
|
||||
-- (GitHub issue #7020).
|
||||
-- FIXME: Remove the _inv workaround when it is no longer needed
|
||||
local inv
|
||||
if meta then
|
||||
inv = meta.inv
|
||||
meta.inventory = nil
|
||||
end
|
||||
local ds = {
|
||||
node = self.node,
|
||||
meta = self.meta,
|
||||
_inv = inv,
|
||||
_startpos = self._startpos,
|
||||
_hit_players = self._hit_players,
|
||||
}
|
||||
return minetest.serialize(ds)
|
||||
end,
|
||||
|
||||
on_activate = function(self, staticdata)
|
||||
self.object:set_armor_groups({immortal = 1})
|
||||
|
||||
local ds = minetest.deserialize(staticdata)
|
||||
if ds then
|
||||
self._startpos = ds._startpos
|
||||
self._hit_players = ds._hit_players
|
||||
if ds.node then
|
||||
local meta = ds.meta
|
||||
meta.inventory = ds._inv
|
||||
self:set_node(ds.node, meta)
|
||||
else
|
||||
self:set_node(ds)
|
||||
end
|
||||
elseif staticdata ~= "" then
|
||||
self:set_node({name = staticdata})
|
||||
end
|
||||
if not self._startpos then
|
||||
self._startpos = self.object:get_pos()
|
||||
end
|
||||
self._startpos = vector.round(self._startpos)
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
-- Set gravity
|
||||
local acceleration = self.object:get_acceleration()
|
||||
if not vector.equals(acceleration, {x = 0, y = -10, z = 0}) then
|
||||
self.object:set_acceleration({x = 0, y = -10, z = 0})
|
||||
end
|
||||
-- Turn to actual node when colliding with ground, or continue to move
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
-- Portal check
|
||||
local np = {x = pos.x, y = pos.y + 0.3, z = pos.z}
|
||||
local n2 = minetest.get_node(np)
|
||||
if n2.name == "mcl_portals:portal_end" then
|
||||
-- TODO: Teleport falling node.
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
|
||||
-- Position of bottom center point
|
||||
local bcp = {x = pos.x, y = pos.y - 0.7, z = pos.z}
|
||||
-- Avoid bugs caused by an unloaded node below
|
||||
local bcn = minetest.get_node_or_nil(bcp)
|
||||
local bcd = bcn and minetest.registered_nodes[bcn.name]
|
||||
|
||||
-- TODO: At this point, we did 2 get_nodes in 1 tick.
|
||||
-- Figure out how to improve that (if it is a problem).
|
||||
|
||||
if bcn and (not bcd or bcd.walkable or
|
||||
(minetest.get_item_group(self.node.name, "float") ~= 0 and
|
||||
bcd.liquidtype ~= "none")) then
|
||||
if bcd and bcd.leveled and
|
||||
bcn.name == self.node.name then
|
||||
local addlevel = self.node.level
|
||||
if not addlevel or addlevel <= 0 then
|
||||
addlevel = bcd.leveled
|
||||
end
|
||||
if minetest.add_node_level(bcp, addlevel) == 0 then
|
||||
if minetest.registered_nodes[self.node.name]._mcl_after_falling then
|
||||
minetest.registered_nodes[self.node.name]._mcl_after_falling(bcp, get_falling_depth(self))
|
||||
end
|
||||
deal_falling_damage(self, dtime)
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
elseif bcd and bcd.buildable_to and
|
||||
(minetest.get_item_group(self.node.name, "float") == 0 or
|
||||
bcd.liquidtype == "none") then
|
||||
minetest.remove_node(bcp)
|
||||
return
|
||||
end
|
||||
local nd = minetest.registered_nodes[n2.name]
|
||||
if n2.name == "mcl_portals:portal_end" then
|
||||
-- TODO: Teleport falling node.
|
||||
|
||||
elseif (nd and nd.buildable_to == true) or minetest.get_item_group(self.node.name, "crush_after_fall") ~= 0 then
|
||||
-- Replace destination node if it's buildable to
|
||||
minetest.remove_node(np)
|
||||
-- Run script hook
|
||||
for _, callback in pairs(minetest.registered_on_dignodes) do
|
||||
callback(np, n2)
|
||||
end
|
||||
if minetest.registered_nodes[self.node.name] then
|
||||
minetest.add_node(np, self.node)
|
||||
if minetest.registered_nodes[self.node.name]._mcl_after_falling then
|
||||
minetest.registered_nodes[self.node.name]._mcl_after_falling(np, get_falling_depth(self))
|
||||
end
|
||||
if self.meta then
|
||||
local meta = minetest.get_meta(np)
|
||||
meta:from_table(self.meta)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Drop the *falling node* as an item if the destination node is NOT buildable to
|
||||
local drops = minetest.get_node_drops(self.node.name, "")
|
||||
for _, dropped_item in pairs(drops) do
|
||||
minetest.add_item(np, dropped_item)
|
||||
end
|
||||
end
|
||||
deal_falling_damage(self, dtime)
|
||||
self.object:remove()
|
||||
minetest.check_for_falling(np)
|
||||
return
|
||||
end
|
||||
local vel = self.object:get_velocity()
|
||||
-- Fix position if entity does not move
|
||||
if vector.equals(vel, {x = 0, y = 0, z = 0}) then
|
||||
local npos = vector.round(self.object:get_pos())
|
||||
local npos2 = table.copy(npos)
|
||||
npos2.y = npos2.y - 2
|
||||
local lownode = minetest.get_node(npos2)
|
||||
-- Special check required for fences and walls, because of their overhigh collision box.
|
||||
if minetest.get_item_group(lownode.name, "fence") == 1 or minetest.get_item_group(lownode.name, "wall") == 1 then
|
||||
-- Instantly stop the node if it is above a fence/wall. This is needed
|
||||
-- because the falling node collides early with a fence/wall node.
|
||||
-- Hacky, because the falling node will teleport a short distance, instead
|
||||
-- of smoothly fall on the fence post.
|
||||
local npos3 = table.copy(npos)
|
||||
npos3.y = npos3.y - 1
|
||||
minetest.add_node(npos3, self.node)
|
||||
if minetest.registered_nodes[self.node.name]._mcl_after_falling then
|
||||
minetest.registered_nodes[self.node.name]._mcl_after_falling(npos3, get_falling_depth(self))
|
||||
end
|
||||
deal_falling_damage(self, dtime)
|
||||
self.object:remove()
|
||||
minetest.check_for_falling(npos3)
|
||||
return
|
||||
else
|
||||
-- Normal position fix (expected case)
|
||||
self.object:set_pos(npos)
|
||||
end
|
||||
end
|
||||
|
||||
deal_falling_damage(self, dtime)
|
||||
end
|
||||
})
|
|
@ -1 +0,0 @@
|
|||
name = mcl_falling_nodes
|
|
@ -4,7 +4,7 @@ by PilzAdam
|
|||
Introduction:
|
||||
This mod adds Minecraft like drop/pick up of items to Minetest.
|
||||
|
||||
This mod has been forked from item_drop in the VoxBox game.
|
||||
This mod has been forked from item_drop in the VoxBox subgame.
|
||||
|
||||
License:
|
||||
Sourcecode: WTFPL (see below)
|
||||
|
|
|
@ -55,20 +55,20 @@ end
|
|||
minetest.register_globalstep(function(dtime)
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then
|
||||
local pos = player:get_pos()
|
||||
local pos = player:getpos()
|
||||
local inv = player:get_inventory()
|
||||
local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}
|
||||
|
||||
--magnet and collection
|
||||
for _,object in ipairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.radius_magnet)) do
|
||||
if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then
|
||||
if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then
|
||||
object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
|
||||
local collected = false
|
||||
if object:get_luaentity()._magnet_timer >= 0 and object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
|
||||
|
||||
-- Collection
|
||||
if vector.distance(checkpos, object:get_pos()) <= item_drop_settings.radius_collect and not object:get_luaentity()._removed then
|
||||
-- Ignore if itemstring is not set yet
|
||||
if vector.distance(checkpos, object:getpos()) <= item_drop_settings.radius_collect and not object:get_luaentity()._removed then
|
||||
|
||||
if object:get_luaentity().itemstring ~= "" then
|
||||
inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
|
||||
minetest.sound_play("item_drop_pickup", {
|
||||
|
@ -78,14 +78,20 @@ minetest.register_globalstep(function(dtime)
|
|||
})
|
||||
check_pickup_achievements(object, player)
|
||||
|
||||
-- If this happens, itemstring was "" (=hand). This is always a bug, the hand must never drop as item.
|
||||
else
|
||||
-- Scream this to the error log because this is bad.
|
||||
minetest.log("error", "Player "..player:get_player_name().." collected a hand at "..minetest.pos_to_string(object:getpos()).." (age="..object:get_luaentity().age..")!")
|
||||
|
||||
-- Destroy entity
|
||||
-- This just prevents this section to be run again because object:remove() doesn't remove the item immediately.
|
||||
object:get_luaentity()._removed = true
|
||||
object:remove()
|
||||
collected = true
|
||||
end
|
||||
|
||||
-- Destroy entity
|
||||
|
||||
-- This just prevents this sectino to be run again because object:remove() doesn't remove the item immediately.
|
||||
object:get_luaentity()._removed = true
|
||||
object:remove()
|
||||
collected = true
|
||||
|
||||
-- Magnet
|
||||
else
|
||||
|
||||
|
@ -95,17 +101,17 @@ minetest.register_globalstep(function(dtime)
|
|||
-- Move object to player
|
||||
disable_physics(object, object:get_luaentity())
|
||||
|
||||
local opos = object:get_pos()
|
||||
local opos = object:getpos()
|
||||
local vec = vector.subtract(checkpos, opos)
|
||||
vec = vector.add(opos, vector.divide(vec, 2))
|
||||
object:move_to(vec)
|
||||
object:moveto(vec)
|
||||
|
||||
|
||||
--fix eternally falling items
|
||||
minetest.after(0, function(object)
|
||||
local lua = object:get_luaentity()
|
||||
if lua then
|
||||
object:set_acceleration({x=0, y=0, z=0})
|
||||
object:setacceleration({x=0, y=0, z=0})
|
||||
end
|
||||
end, object)
|
||||
|
||||
|
@ -115,8 +121,7 @@ minetest.register_globalstep(function(dtime)
|
|||
if object:get_luaentity().init ~= true then
|
||||
object:get_luaentity().init = true
|
||||
minetest.after(1, function(args)
|
||||
local playername = args[1]
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
local player = args[1]
|
||||
local object = args[2]
|
||||
local lua = object:get_luaentity()
|
||||
if player == nil or not player:is_player() or object == nil or lua == nil or lua.itemstring == nil then
|
||||
|
@ -137,7 +142,7 @@ minetest.register_globalstep(function(dtime)
|
|||
else
|
||||
enable_physics(object, object:get_luaentity())
|
||||
end
|
||||
end, {player:get_player_name(), object})
|
||||
end, {player, object})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -208,25 +213,18 @@ local check_can_drop = function(node_name, tool_capabilities)
|
|||
end
|
||||
|
||||
function minetest.handle_node_drops(pos, drops, digger)
|
||||
-- NOTE: This function override allows digger to be nil.
|
||||
-- This means there is no digger. This is a special case which allows this function to be called
|
||||
-- by hand. Creative Mode is intentionally ignored in this case.
|
||||
|
||||
local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops") or true
|
||||
if (digger ~= nil and minetest.settings:get_bool("creative_mode")) or doTileDrops == false then
|
||||
if minetest.settings:get_bool("creative_mode") or doTileDrops == false then
|
||||
return
|
||||
end
|
||||
|
||||
-- Check if node will yield its useful drop by the digger's tool
|
||||
local dug_node = minetest.get_node(pos)
|
||||
local toolcaps
|
||||
if digger ~= nil then
|
||||
local tool = digger:get_wielded_item()
|
||||
toolcaps = tool:get_tool_capabilities()
|
||||
local tool = digger:get_wielded_item()
|
||||
local toolcaps = tool:get_tool_capabilities()
|
||||
|
||||
if not check_can_drop(dug_node.name, toolcaps) then
|
||||
return
|
||||
end
|
||||
if not check_can_drop(dug_node.name, toolcaps) then
|
||||
return
|
||||
end
|
||||
|
||||
--[[ Special node drops when dug by shears by reading _mcl_shears_drop
|
||||
|
@ -236,7 +234,7 @@ function minetest.handle_node_drops(pos, drops, digger)
|
|||
* table: Drop every itemstring in this table when dub by shears
|
||||
]]
|
||||
local nodedef = minetest.registered_nodes[dug_node.name]
|
||||
if toolcaps ~= nil and toolcaps.groupcaps and toolcaps.groupcaps.shearsy_dig and nodedef._mcl_shears_drop then
|
||||
if toolcaps.groupcaps and toolcaps.groupcaps.shearsy_dig and nodedef._mcl_shears_drop then
|
||||
if nodedef._mcl_shears_drop == true then
|
||||
drops = { dug_node.name }
|
||||
else
|
||||
|
@ -245,16 +243,16 @@ function minetest.handle_node_drops(pos, drops, digger)
|
|||
end
|
||||
|
||||
for _,item in ipairs(drops) do
|
||||
local count
|
||||
local count, name
|
||||
if type(item) == "string" then
|
||||
count = ItemStack(item):get_count()
|
||||
count = 1
|
||||
name = item
|
||||
else
|
||||
count = item:get_count()
|
||||
name = item:get_name()
|
||||
end
|
||||
local drop_item = ItemStack(item)
|
||||
drop_item:set_count(1)
|
||||
for i=1,count do
|
||||
local obj = core.add_item(pos, drop_item)
|
||||
local obj = core.add_item(pos, name)
|
||||
if obj ~= nil then
|
||||
local x = math.random(1, 5)
|
||||
if math.random(1,2) == 1 then
|
||||
|
@ -264,7 +262,7 @@ function minetest.handle_node_drops(pos, drops, digger)
|
|||
if math.random(1,2) == 1 then
|
||||
z = -z
|
||||
end
|
||||
obj:set_velocity({x=1/x, y=obj:get_velocity().y, z=1/z})
|
||||
obj:setvelocity({x=1/x, y=obj:getvelocity().y, z=1/z})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -285,7 +283,7 @@ function minetest.item_drop(itemstack, dropper, pos)
|
|||
v.x = v.x*4
|
||||
v.y = v.y*4 + 2
|
||||
v.z = v.z*4
|
||||
obj:set_velocity(v)
|
||||
obj:setvelocity(v)
|
||||
-- Force collection delay
|
||||
obj:get_luaentity()._insta_collect = false
|
||||
return itemstack
|
||||
|
@ -295,7 +293,7 @@ end
|
|||
|
||||
--modify builtin:item
|
||||
|
||||
local time_to_live = tonumber(minetest.settings:get("item_entity_ttl"))
|
||||
local time_to_live = tonumber(core.setting_get("item_entity_ttl"))
|
||||
if not time_to_live then
|
||||
time_to_live = 300
|
||||
end
|
||||
|
@ -306,7 +304,6 @@ core.register_entity(":__builtin:item", {
|
|||
physical = true,
|
||||
collide_with_objects = false,
|
||||
collisionbox = {-0.3, -0.3, -0.3, 0.3, 0.3, 0.3},
|
||||
pointable = false,
|
||||
visual = "wielditem",
|
||||
visual_size = {x = 0.4, y = 0.4},
|
||||
textures = {""},
|
||||
|
@ -316,27 +313,17 @@ core.register_entity(":__builtin:item", {
|
|||
infotext = "",
|
||||
},
|
||||
|
||||
-- Itemstring of dropped item. The empty string is used when the item is not yet initialized yet.
|
||||
-- The itemstring MUST be set immediately to a non-empty string after creating the entity.
|
||||
-- The hand is NOT permitted as dropped item. ;-)
|
||||
-- Item entities will be deleted if they still have an empty itemstring on their first on_step tick.
|
||||
itemstring = '',
|
||||
|
||||
-- If true, item will fall
|
||||
physical_state = true,
|
||||
|
||||
-- If item entity is currently flowing in water
|
||||
_flowing = false,
|
||||
|
||||
-- Number of seconds this item entity has existed so far
|
||||
_flowing = false, -- item entity is currently flowing
|
||||
-- States:
|
||||
-- * "magnet": Attracted to a nearby player or item
|
||||
-- * "flowing": Moving in a flowing liquid
|
||||
-- * "normal": Affected by gravitiy
|
||||
age = 0,
|
||||
|
||||
set_item = function(self, itemstring)
|
||||
self.itemstring = itemstring
|
||||
if self.itemstring == "" then
|
||||
-- item not yet known
|
||||
return
|
||||
end
|
||||
local stack = ItemStack(itemstring)
|
||||
local count = stack:get_count()
|
||||
local max_count = stack:get_stack_max()
|
||||
|
@ -374,7 +361,7 @@ core.register_entity(":__builtin:item", {
|
|||
if not self or not self.object or not self.object:get_luaentity() then
|
||||
return
|
||||
end
|
||||
local vel = self.object:get_velocity()
|
||||
local vel = self.object:getvelocity()
|
||||
if vel and vel.x == 0 and vel.z == 0 then
|
||||
local x = math.random(1, 5)
|
||||
if math.random(1,2) == 1 then
|
||||
|
@ -385,7 +372,7 @@ core.register_entity(":__builtin:item", {
|
|||
z = -z
|
||||
end
|
||||
local y = math.random(2,4)
|
||||
self.object:set_velocity({x=1/x, y=y, z=1/z})
|
||||
self.object:setvelocity({x=1/x, y=y, z=1/z})
|
||||
end
|
||||
end, self)
|
||||
end
|
||||
|
@ -445,8 +432,8 @@ core.register_entity(":__builtin:item", {
|
|||
self._forcetimer = 0
|
||||
|
||||
self.object:set_armor_groups({immortal = 1})
|
||||
self.object:set_velocity({x = 0, y = 2, z = 0})
|
||||
self.object:set_acceleration({x = 0, y = -get_gravity(), z = 0})
|
||||
self.object:setvelocity({x = 0, y = 2, z = 0})
|
||||
self.object:setacceleration({x = 0, y = -get_gravity(), z = 0})
|
||||
self:set_item(self.itemstring)
|
||||
end,
|
||||
|
||||
|
@ -501,15 +488,14 @@ core.register_entity(":__builtin:item", {
|
|||
self.object:remove()
|
||||
return
|
||||
end
|
||||
-- Delete corrupted item entities. The itemstring MUST be non-empty on its first step,
|
||||
-- otherwise there might have some data corruption.
|
||||
if self.itemstring == "" then
|
||||
minetest.log("warning", "Item entity with empty itemstring found at "..minetest.pos_to_string(self.object:get_pos()).. "! Deleting it now.")
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
-- If, for some reason, an item entity with itemstring == "" (hand) appears, this is very bad.
|
||||
if not self._hand_bug_detected and self.age > 1 and self.itemstring == "" then
|
||||
-- We must this scream this into the error console. The bug is rare an
|
||||
minetest.log("error", "A hand item entity appeared at "..minetest.pos_to_string(self.object:getpos()).. "!")
|
||||
self._hand_bug_detected = true
|
||||
end
|
||||
|
||||
local p = self.object:get_pos()
|
||||
local p = self.object:getpos()
|
||||
local node = core.get_node_or_nil(p)
|
||||
local in_unloaded = (node == nil)
|
||||
|
||||
|
@ -525,15 +511,13 @@ core.register_entity(":__builtin:item", {
|
|||
return
|
||||
end
|
||||
|
||||
-- Destroy item in lava, fire or special nodes
|
||||
-- Destroy item in lava or special nodes
|
||||
local nn = node.name
|
||||
local def = minetest.registered_nodes[nn]
|
||||
local lg = minetest.get_item_group(nn, "lava")
|
||||
local fg = minetest.get_item_group(nn, "fire")
|
||||
local dg = minetest.get_item_group(nn, "destroys_items")
|
||||
if (def and (lg ~= 0 or fg ~= 0 or dg == 1)) then
|
||||
if dg ~= 2 then
|
||||
minetest.sound_play("builtin_item_lava", {pos = self.object:get_pos(), gain = 0.5})
|
||||
if (def and def.groups and (def.groups.lava or def.groups.destroys_items == 1)) then
|
||||
-- Special effect for lava
|
||||
if def.groups.lava then
|
||||
minetest.sound_play("builtin_item_lava", {pos = self.object:getpos(), gain = 0.5})
|
||||
end
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
|
@ -590,8 +574,8 @@ core.register_entity(":__builtin:item", {
|
|||
|
||||
-- Set new item moving speed accordingly
|
||||
local newv = vector.multiply(shootdir, 3)
|
||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
||||
self.object:set_velocity(newv)
|
||||
self.object:setacceleration({x = 0, y = 0, z = 0})
|
||||
self.object:setvelocity(newv)
|
||||
|
||||
disable_physics(self.object, self, false, false)
|
||||
|
||||
|
@ -644,8 +628,8 @@ core.register_entity(":__builtin:item", {
|
|||
local f = 1.39
|
||||
-- Set new item moving speed into the direciton of the liquid
|
||||
local newv = vector.multiply(vec, f)
|
||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
||||
self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z})
|
||||
self.object:setacceleration({x = 0, y = 0, z = 0})
|
||||
self.object:setvelocity({x = newv.x, y = -0.22, z = newv.z})
|
||||
|
||||
self.physical_state = true
|
||||
self._flowing = true
|
||||
|
@ -663,7 +647,7 @@ core.register_entity(":__builtin:item", {
|
|||
|
||||
-- If node is not registered or node is walkably solid and resting on nodebox
|
||||
local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
||||
local v = self.object:get_velocity()
|
||||
local v = self.object:getvelocity()
|
||||
|
||||
if not core.registered_nodes[nn] or core.registered_nodes[nn].walkable and v.y == 0 then
|
||||
if self.physical_state then
|
||||
|
|
|
@ -13,10 +13,6 @@ License of source code:
|
|||
-----------------------
|
||||
MIT License
|
||||
|
||||
Copyright (C) 2012-2016 PilzAdam
|
||||
Copyright (C) 2014-2016 SmallJoker
|
||||
Copyright (C) 2012-2016 Various Minetest developers and contributors
|
||||
|
||||
Authors/licenses of media files:
|
||||
-----------------------
|
||||
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
local S = minetest.get_translator("mcl_minecarts")
|
||||
|
||||
mcl_minecarts = {}
|
||||
mcl_minecarts.modpath = minetest.get_modpath("mcl_minecarts")
|
||||
mcl_minecarts.speed_max = 10
|
||||
mcl_minecarts.check_float_time = 15
|
||||
|
||||
dofile(mcl_minecarts.modpath.."/functions.lua")
|
||||
dofile(mcl_minecarts.modpath.."/rails.lua")
|
||||
|
@ -26,7 +23,6 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
_punched = false, -- used to re-send _velocity and position
|
||||
_velocity = {x=0, y=0, z=0}, -- only used on punch
|
||||
_start_pos = nil, -- Used to calculate distance for “On A Rail” achievement
|
||||
_last_float_check = nil, -- timestamp of last time the cart was checked to be still on a rail
|
||||
_old_dir = {x=0, y=0, z=0},
|
||||
_old_pos = nil,
|
||||
_old_vel = {x=0, y=0, z=0},
|
||||
|
@ -35,15 +31,11 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
}
|
||||
|
||||
function cart:on_activate(staticdata, dtime_s)
|
||||
local data = minetest.deserialize(staticdata)
|
||||
if type(data) == "table" then
|
||||
self._railtype = data._railtype
|
||||
end
|
||||
self.object:set_armor_groups({immortal=1})
|
||||
end
|
||||
|
||||
function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
||||
local pos = self.object:get_pos()
|
||||
local pos = self.object:getpos()
|
||||
if not self._railtype then
|
||||
local node = minetest.get_node(vector.floor(pos)).name
|
||||
self._railtype = minetest.get_item_group(node, "connect_to_raillike")
|
||||
|
@ -63,13 +55,12 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
if puncher:get_player_control().sneak then
|
||||
if self._driver then
|
||||
if self._old_pos then
|
||||
self.object:set_pos(self._old_pos)
|
||||
self.object:setpos(self._old_pos)
|
||||
end
|
||||
mcl_player.player_attached[self._driver] = nil
|
||||
local player = minetest.get_player_by_name(self._driver)
|
||||
if player then
|
||||
player:set_detach()
|
||||
player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -85,14 +76,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
-- Drop items and remove cart entity
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
for d=1, #drop do
|
||||
minetest.add_item(self.object:get_pos(), drop[d])
|
||||
end
|
||||
elseif puncher and puncher:is_player() then
|
||||
local inv = puncher:get_inventory()
|
||||
for d=1, #drop do
|
||||
if not inv:contains_item("main", drop[d]) then
|
||||
inv:add_item("main", drop[d])
|
||||
end
|
||||
minetest.add_item(self.object:getpos(), drop[d])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -100,7 +84,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
return
|
||||
end
|
||||
|
||||
local vel = self.object:get_velocity()
|
||||
local vel = self.object:getvelocity()
|
||||
if puncher:get_player_name() == self._driver then
|
||||
if math.abs(vel.x + vel.z) > 7 then
|
||||
return
|
||||
|
@ -123,59 +107,18 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
end
|
||||
|
||||
function cart:on_step(dtime)
|
||||
local vel = self.object:get_velocity()
|
||||
local vel = self.object:getvelocity()
|
||||
local update = {}
|
||||
if self._last_float_check == nil then
|
||||
self._last_float_check = 0
|
||||
else
|
||||
self._last_float_check = self._last_float_check + dtime
|
||||
end
|
||||
local pos, rou_pos, node
|
||||
-- Drop minecart if it isn't on a rail anymore
|
||||
if self._last_float_check >= mcl_minecarts.check_float_time then
|
||||
pos = self.object:get_pos()
|
||||
rou_pos = vector.round(pos)
|
||||
node = minetest.get_node(rou_pos)
|
||||
local g = minetest.get_item_group(node.name, "connect_to_raillike")
|
||||
if g ~= self._railtype and self._railtype ~= nil then
|
||||
-- Detach driver
|
||||
if self._driver then
|
||||
if self._old_pos then
|
||||
self.object:set_pos(self._old_pos)
|
||||
end
|
||||
mcl_player.player_attached[self._driver] = nil
|
||||
local player = minetest.get_player_by_name(self._driver)
|
||||
if player then
|
||||
player:set_detach()
|
||||
player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
|
||||
end
|
||||
end
|
||||
|
||||
-- Drop items and remove cart entity
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
for d=1, #drop do
|
||||
minetest.add_item(self.object:get_pos(), drop[d])
|
||||
end
|
||||
end
|
||||
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
self._last_float_check = 0
|
||||
end
|
||||
|
||||
if self._punched then
|
||||
vel = vector.add(vel, self._velocity)
|
||||
self.object:set_velocity(vel)
|
||||
self.object:setvelocity(vel)
|
||||
self._old_dir.y = 0
|
||||
elseif vector.equals(vel, {x=0, y=0, z=0}) then
|
||||
return
|
||||
end
|
||||
|
||||
local dir, last_switch = nil, nil
|
||||
if not pos then
|
||||
pos = self.object:get_pos()
|
||||
end
|
||||
local pos = self.object:getpos()
|
||||
if self._old_pos and not self._punched then
|
||||
local flo_pos = vector.floor(pos)
|
||||
local flo_old = vector.floor(self._old_pos)
|
||||
|
@ -184,16 +127,12 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
-- Prevent querying the same node over and over again
|
||||
end
|
||||
|
||||
if not rou_pos then
|
||||
rou_pos = vector.round(pos)
|
||||
end
|
||||
rou_old = vector.round(self._old_pos)
|
||||
if not node then
|
||||
node = minetest.get_node(rou_pos)
|
||||
end
|
||||
-- Update detector rails
|
||||
local rou_pos = vector.round(pos)
|
||||
local rou_old = vector.round(self._old_pos)
|
||||
local node = minetest.get_node(rou_pos)
|
||||
local node_old = minetest.get_node(rou_old)
|
||||
|
||||
-- Update detector rails
|
||||
if node.name == "mcl_minecarts:detector_rail" then
|
||||
local newnode = {name="mcl_minecarts:detector_rail_on", param2 = node.param2}
|
||||
minetest.swap_node(rou_pos, newnode)
|
||||
|
@ -219,8 +158,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
(self._old_vel.x * vel.x < 0 or self._old_vel.z * vel.z < 0) then
|
||||
self._old_vel = {x = 0, y = 0, z = 0}
|
||||
self._old_pos = pos
|
||||
self.object:set_velocity(vector.new())
|
||||
self.object:set_acceleration(vector.new())
|
||||
self.object:setvelocity(vector.new())
|
||||
self.object:setacceleration(vector.new())
|
||||
return
|
||||
end
|
||||
self._old_vel = vector.new(vel)
|
||||
|
@ -294,7 +233,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
new_acc = vector.multiply(dir, acc)
|
||||
end
|
||||
|
||||
self.object:set_acceleration(new_acc)
|
||||
self.object:setacceleration(new_acc)
|
||||
self._old_pos = vector.new(pos)
|
||||
self._old_dir = vector.new(dir)
|
||||
self._old_switch = last_switch
|
||||
|
@ -323,7 +262,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
elseif dir.z < 0 then
|
||||
yaw = 1
|
||||
end
|
||||
self.object:set_yaw(yaw * math.pi)
|
||||
self.object:setyaw(yaw * math.pi)
|
||||
end
|
||||
|
||||
if self._punched then
|
||||
|
@ -343,15 +282,15 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
|||
end
|
||||
self.object:set_animation(anim, 1, 0)
|
||||
|
||||
self.object:set_velocity(vel)
|
||||
self.object:setvelocity(vel)
|
||||
if update.pos then
|
||||
self.object:set_pos(pos)
|
||||
self.object:setpos(pos)
|
||||
end
|
||||
update = nil
|
||||
end
|
||||
|
||||
function cart:get_staticdata()
|
||||
return minetest.serialize({_railtype = self._railtype})
|
||||
return ""
|
||||
end
|
||||
|
||||
minetest.register_entity(entity_id, cart)
|
||||
|
@ -384,12 +323,8 @@ mcl_minecarts.place_minecart = function(itemstack, pointed_thing)
|
|||
local entity_id = entity_mapping[itemstack:get_name()]
|
||||
local cart = minetest.add_entity(railpos, entity_id)
|
||||
local railtype = minetest.get_item_group(node.name, "connect_to_raillike")
|
||||
local le = cart:get_luaentity()
|
||||
if le ~= nil then
|
||||
le._railtype = railtype
|
||||
end
|
||||
local cart_dir = mcl_minecarts:get_rail_direction(railpos, {x=1, y=0, z=0}, nil, nil, railtype)
|
||||
cart:set_yaw(minetest.dir_to_yaw(cart_dir))
|
||||
cart:setyaw(minetest.dir_to_yaw(cart_dir))
|
||||
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
|
@ -397,7 +332,6 @@ mcl_minecarts.place_minecart = function(itemstack, pointed_thing)
|
|||
return itemstack
|
||||
end
|
||||
|
||||
|
||||
local register_craftitem = function(itemstring, entity_id, description, longdesc, usagehelp, icon, creative)
|
||||
entity_mapping[itemstring] = entity_id
|
||||
|
||||
|
@ -422,19 +356,6 @@ local register_craftitem = function(itemstring, entity_id, description, longdesc
|
|||
|
||||
return mcl_minecarts.place_minecart(itemstack, pointed_thing)
|
||||
end,
|
||||
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
||||
-- Place minecart as entity on rail. If there's no rail, just drop it.
|
||||
local placed
|
||||
if minetest.get_item_group(dropnode.name, "rail") ~= 0 then
|
||||
-- FIXME: This places minecarts even if the spot is already occupied
|
||||
local pointed_thing = { under = droppos, above = { x=droppos.x, y=droppos.y+1, z=droppos.z } }
|
||||
placed = mcl_minecarts.place_minecart(stack, pointed_thing)
|
||||
end
|
||||
if placed == nil then
|
||||
-- Drop item
|
||||
minetest.add_item(droppos, stack)
|
||||
end
|
||||
end,
|
||||
groups = groups,
|
||||
}
|
||||
def.description = description
|
||||
|
@ -445,22 +366,7 @@ local register_craftitem = function(itemstring, entity_id, description, longdesc
|
|||
minetest.register_craftitem(itemstring, def)
|
||||
end
|
||||
|
||||
--[[
|
||||
Register a minecart
|
||||
* itemstring: Itemstring of minecart item
|
||||
* entity_id: ID of minecart entity
|
||||
* description: Item name / description
|
||||
* longdesc: Long help text
|
||||
* usagehelp: Usage help text
|
||||
* mesh: Minecart mesh
|
||||
* textures: Minecart textures table
|
||||
* icon: Item icon
|
||||
* drop: Dropped items after destroying minecart
|
||||
* on_rightclick: Called after rightclick
|
||||
* on_activate_by_rail: Called when above activator rail
|
||||
* creative: If false, don't show in Creative Inventory
|
||||
]]
|
||||
local function register_minecart(itemstring, entity_id, description, longdesc, usagehelp, mesh, textures, icon, drop, on_rightclick, on_activate_by_rail, creative)
|
||||
local function register_minecart(itemstring, entity_id, description, longdesc, usagehelp, mesh, textures, icon, drop, on_rightclick, creative)
|
||||
register_entity(entity_id, mesh, textures, drop, on_rightclick)
|
||||
register_craftitem(itemstring, entity_id, description, longdesc, usagehelp, icon, creative)
|
||||
if minetest.get_modpath("doc_identifier") ~= nil then
|
||||
|
@ -472,17 +378,16 @@ end
|
|||
register_minecart(
|
||||
"mcl_minecarts:minecart",
|
||||
"mcl_minecarts:minecart",
|
||||
S("Minecart"),
|
||||
S("Minecarts can be used for a quick transportion on rails.") .. "\n" ..
|
||||
S("Minecarts only ride on rails and always follow the tracks. At a T-junction with no straight way ahead, they turn left. The speed is affected by the rail type."),
|
||||
S("You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.") .. "\n" ..
|
||||
S("To obtain the minecart, punch it while holding down the sneak key."),
|
||||
"Minecart",
|
||||
"Minecarts can be used for a quick transportion on rails." .. "\n" ..
|
||||
"Minecarts only ride on rails and always follow the tracks. At a T-junction with no straight way ahead, they turn left. The speed is affected by the rail type.",
|
||||
"You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving." .. "\n" ..
|
||||
"To obtain the minecart, punch it while holding down the sneak key.",
|
||||
"mcl_minecarts_minecart.b3d",
|
||||
{"mcl_minecarts_minecart.png"},
|
||||
"mcl_minecarts_minecart_normal.png",
|
||||
{"mcl_minecarts:minecart"},
|
||||
function(self, clicker)
|
||||
local name = clicker:get_player_name()
|
||||
if not clicker or not clicker:is_player() then
|
||||
return
|
||||
end
|
||||
|
@ -491,20 +396,11 @@ register_minecart(
|
|||
self._driver = nil
|
||||
self._start_pos = nil
|
||||
clicker:set_detach()
|
||||
clicker:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
|
||||
elseif not self._driver then
|
||||
self._driver = player_name
|
||||
self._start_pos = self.object:get_pos()
|
||||
self._start_pos = self.object:getpos()
|
||||
mcl_player.player_attached[player_name] = true
|
||||
clicker:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0})
|
||||
mcl_player.player_attached[name] = true
|
||||
minetest.after(0.2, function(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
mcl_player.player_set_animation(player, "sit" , 30)
|
||||
player:set_eye_offset({x=0, y=-5.5, z=0},{x=0, y=-4, z=0})
|
||||
end
|
||||
end, name)
|
||||
clicker:set_attach(self.object, "", {x=0, y=3, z=0}, {x=0, y=0, z=0})
|
||||
end
|
||||
end
|
||||
)
|
||||
|
@ -513,19 +409,18 @@ register_minecart(
|
|||
register_minecart(
|
||||
"mcl_minecarts:chest_minecart",
|
||||
"mcl_minecarts:chest_minecart",
|
||||
S("Minecart with Chest"),
|
||||
"Minecart with Chest",
|
||||
nil, nil,
|
||||
"mcl_minecarts_minecart_chest.b3d",
|
||||
{ "mcl_chests_normal.png", "mcl_minecarts_minecart.png" },
|
||||
"mcl_minecarts_minecart_chest.png",
|
||||
{"mcl_minecarts:minecart", "mcl_chests:chest"},
|
||||
nil, nil, false)
|
||||
{"mcl_minecarts:minecart", "mcl_chests:chest"})
|
||||
|
||||
-- Minecart with Furnace
|
||||
register_minecart(
|
||||
"mcl_minecarts:furnace_minecart",
|
||||
"mcl_minecarts:furnace_minecart",
|
||||
S("Minecart with Furnace"),
|
||||
"Minecart with Furnace",
|
||||
nil, nil,
|
||||
"mcl_minecarts_minecart_block.b3d",
|
||||
{
|
||||
|
@ -561,14 +456,14 @@ register_minecart(
|
|||
-- DEBUG
|
||||
minetest.chat_send_player(clicker:get_player_name(), "Fuel: " .. tostring(self._fueltime))
|
||||
end
|
||||
end, nil, false
|
||||
end
|
||||
)
|
||||
|
||||
-- Minecart with Command Block
|
||||
register_minecart(
|
||||
"mcl_minecarts:command_block_minecart",
|
||||
"mcl_minecarts:command_block_minecart",
|
||||
S("Minecart with Command Block"),
|
||||
"Minecart with Command Block",
|
||||
nil, nil,
|
||||
"mcl_minecarts_minecart_block.b3d",
|
||||
{
|
||||
|
@ -582,14 +477,15 @@ register_minecart(
|
|||
},
|
||||
"mcl_minecarts_minecart_command_block.png",
|
||||
{"mcl_minecarts:minecart"},
|
||||
nil, nil, false
|
||||
nil,
|
||||
false
|
||||
)
|
||||
|
||||
-- Minecart with Hopper
|
||||
register_minecart(
|
||||
"mcl_minecarts:hopper_minecart",
|
||||
"mcl_minecarts:hopper_minecart",
|
||||
S("Minecart with Hopper"),
|
||||
"Minecart with Hopper",
|
||||
nil, nil,
|
||||
"mcl_minecarts_minecart_hopper.b3d",
|
||||
{
|
||||
|
@ -599,15 +495,14 @@ register_minecart(
|
|||
"mcl_hoppers_hopper_top.png",
|
||||
},
|
||||
"mcl_minecarts_minecart_hopper.png",
|
||||
{"mcl_minecarts:minecart", "mcl_hoppers:hopper"},
|
||||
nil, nil, false
|
||||
{"mcl_minecarts:minecart", "mcl_hoppers:hopper"}
|
||||
)
|
||||
|
||||
-- Minecart with TNT
|
||||
register_minecart(
|
||||
"mcl_minecarts:tnt_minecart",
|
||||
"mcl_minecarts:tnt_minecart",
|
||||
S("Minecart with TNT"),
|
||||
"Minecart with TNT",
|
||||
nil, nil,
|
||||
"mcl_minecarts_minecart_block.b3d",
|
||||
{
|
||||
|
@ -620,8 +515,7 @@ register_minecart(
|
|||
"mcl_minecarts_minecart.png",
|
||||
},
|
||||
"mcl_minecarts_minecart_tnt.png",
|
||||
{"mcl_minecarts:minecart", "mcl_tnt:tnt"},
|
||||
nil, nil, false
|
||||
{"mcl_minecarts:minecart", "mcl_tnt:tnt"}
|
||||
)
|
||||
|
||||
|
||||
|
@ -633,8 +527,6 @@ minetest.register_craft({
|
|||
},
|
||||
})
|
||||
|
||||
-- TODO: Re-enable crafting of special minecarts when they have been implemented
|
||||
if false then
|
||||
minetest.register_craft({
|
||||
output = "mcl_minecarts:hopper_minecart",
|
||||
recipe = {
|
||||
|
@ -666,4 +558,3 @@ minetest.register_craft({
|
|||
{"mcl_minecarts:minecart"},
|
||||
},
|
||||
})
|
||||
end
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
local S = minetest.get_translator("mcl_minecarts")
|
||||
|
||||
-- Template rail function
|
||||
local register_rail = function(itemstring, tiles, def_extras, creative)
|
||||
local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=1,dig_by_water=1,destroy_by_lava_flow=1, transport=1}
|
||||
|
@ -23,20 +21,6 @@ local register_rail = function(itemstring, tiles, def_extras, creative)
|
|||
sounds = mcl_sounds.node_sound_metal_defaults(),
|
||||
_mcl_blast_resistance = 3.5,
|
||||
_mcl_hardness = 0.7,
|
||||
after_destruct = function(pos)
|
||||
-- Scan for minecarts in this pos and force them to execute their "floating" check.
|
||||
-- Normally, this will make them drop.
|
||||
local objs = minetest.get_objects_inside_radius(pos, 1)
|
||||
for o=1, #objs do
|
||||
local le = objs[o]:get_luaentity()
|
||||
if le then
|
||||
-- All entities in this mod are minecarts, so this works
|
||||
if string.sub(le.name, 1, 14) == "mcl_minecarts:" then
|
||||
le._last_float_check = mcl_minecarts.check_float_time
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
}
|
||||
if def_extras then
|
||||
for k,v in pairs(def_extras) do
|
||||
|
@ -46,52 +30,30 @@ local register_rail = function(itemstring, tiles, def_extras, creative)
|
|||
minetest.register_node(itemstring, ndef)
|
||||
end
|
||||
|
||||
-- Redstone rules
|
||||
local rail_rules_long =
|
||||
{{x=-1, y= 0, z= 0, spread=true},
|
||||
{x= 1, y= 0, z= 0, spread=true},
|
||||
{x= 0, y=-1, z= 0, spread=true},
|
||||
{x= 0, y= 1, z= 0, spread=true},
|
||||
{x= 0, y= 0, z=-1, spread=true},
|
||||
{x= 0, y= 0, z= 1, spread=true},
|
||||
|
||||
{x= 1, y= 1, z= 0},
|
||||
{x= 1, y=-1, z= 0},
|
||||
{x=-1, y= 1, z= 0},
|
||||
{x=-1, y=-1, z= 0},
|
||||
{x= 0, y= 1, z= 1},
|
||||
{x= 0, y=-1, z= 1},
|
||||
{x= 0, y= 1, z=-1},
|
||||
{x= 0, y=-1, z=-1}}
|
||||
|
||||
local rail_rules_short = mesecon.rules.pplate
|
||||
|
||||
local railuse = S("Place them on the ground to build your railway, the rails will automatically connect to each other and will turn into curves, T-junctions, crossings and slopes as needed.")
|
||||
local railuse = "Place them on the ground to build your railway, the rails will automatically connect to each other and will turn into curves, T-junctions, crossings and slopes as needed."
|
||||
|
||||
-- Normal rail
|
||||
register_rail("mcl_minecarts:rail",
|
||||
{"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
|
||||
{
|
||||
description = S("Rail"),
|
||||
_doc_items_longdesc = S("Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction."),
|
||||
description = "Rail",
|
||||
_doc_items_longdesc = "Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction.",
|
||||
_doc_items_usagehelp = railuse,
|
||||
}
|
||||
)
|
||||
|
||||
-- Powered rail (off = brake mode)
|
||||
register_rail("mcl_minecarts:golden_rail",
|
||||
{"mcl_minecarts_rail_golden.png", "mcl_minecarts_rail_golden_curved.png", "mcl_minecarts_rail_golden_t_junction.png", "mcl_minecarts_rail_golden_crossing.png"},
|
||||
{"carts_rail_pwr.png", "carts_rail_curved_pwr.png", "carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png"},
|
||||
{
|
||||
description = S("Powered Rail"),
|
||||
_doc_items_longdesc = S("Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts."),
|
||||
_doc_items_usagehelp = railuse .. "\n" .. S("Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power."),
|
||||
description = "Powered Rail",
|
||||
_doc_items_longdesc = "Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.",
|
||||
_doc_items_usagehelp = railuse .. "\n" .. "Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.",
|
||||
_rail_acceleration = -3,
|
||||
mesecons = {
|
||||
conductor = {
|
||||
state = mesecon.state.off,
|
||||
offstate = "mcl_minecarts:golden_rail",
|
||||
onstate = "mcl_minecarts:golden_rail_on",
|
||||
rules = rail_rules_long,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -107,50 +69,40 @@ register_rail("mcl_minecarts:golden_rail_on",
|
|||
conductor = {
|
||||
state = mesecon.state.on,
|
||||
offstate = "mcl_minecarts:golden_rail",
|
||||
onstate = "mcl_minecarts:golden_rail_on",
|
||||
rules = rail_rules_long,
|
||||
},
|
||||
},
|
||||
drop = "mcl_minecarts:golden_rail",
|
||||
},
|
||||
false
|
||||
)
|
||||
|
||||
|
||||
-- Activator rail (off)
|
||||
register_rail("mcl_minecarts:activator_rail",
|
||||
{"mcl_minecarts_rail_activator.png", "mcl_minecarts_rail_activator_curved.png", "mcl_minecarts_rail_activator_t_junction.png", "mcl_minecarts_rail_activator_crossing.png"},
|
||||
{"mcl_minecarts_rail_activator.png", "default_rail_curved.png^[colorize:#FF0000:96", "default_rail_t_junction.png^[colorize:#FF0000:96", "default_rail_crossing.png^[colorize:#FF0000:96"},
|
||||
{
|
||||
description = S("Activator Rail"),
|
||||
_doc_items_longdesc = S("Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts."),
|
||||
_doc_items_usagehelp = railuse .. "\n" .. S("To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail."),
|
||||
description = "Activator Rail",
|
||||
_doc_items_longdesc = "Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts.",
|
||||
_doc_items_usagehelp = railuse .. "\n" .. "To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail.",
|
||||
mesecons = {
|
||||
conductor = {
|
||||
state = mesecon.state.off,
|
||||
offstate = "mcl_minecarts:activator_rail",
|
||||
onstate = "mcl_minecarts:activator_rail_on",
|
||||
rules = rail_rules_long,
|
||||
},
|
||||
},
|
||||
},
|
||||
-- Hidden from creative because no cart is using this rail so far.
|
||||
-- TODO: Remove this when the activator rail has become useful.
|
||||
false
|
||||
}
|
||||
)
|
||||
|
||||
-- Activator rail (on)
|
||||
register_rail("mcl_minecarts:activator_rail_on",
|
||||
{"mcl_minecarts_rail_activator_powered.png", "mcl_minecarts_rail_activator_curved_powered.png", "mcl_minecarts_rail_activator_t_junction_powered.png", "mcl_minecarts_rail_activator_crossing_powered.png"},
|
||||
{"mcl_minecarts_rail_activator_powered.png", "default_rail_curved.png^[colorize:#FF0000:128", "default_rail_t_junction.png^[colorize:#FF0000:128", "default_rail_crossing.png^[colorize:#FF0000:128"},
|
||||
{
|
||||
_doc_items_create_entry = false,
|
||||
mesecons = {
|
||||
conductor = {
|
||||
state = mesecon.state.on,
|
||||
offstate = "mcl_minecarts:activator_rail",
|
||||
onstate = "mcl_minecarts:activator_rail_on",
|
||||
rules = rail_rules_long,
|
||||
},
|
||||
},
|
||||
drop = "mcl_minecarts:activator_rail",
|
||||
},
|
||||
false
|
||||
)
|
||||
|
@ -159,13 +111,12 @@ register_rail("mcl_minecarts:activator_rail_on",
|
|||
register_rail("mcl_minecarts:detector_rail",
|
||||
{"mcl_minecarts_rail_detector.png", "mcl_minecarts_rail_detector_curved.png", "mcl_minecarts_rail_detector_t_junction.png", "mcl_minecarts_rail_detector_crossing.png"},
|
||||
{
|
||||
description = S("Detector Rail"),
|
||||
_doc_items_longdesc = S("Rails can be used to build transport tracks for minecarts. A detector rail is able to detect a minecart above it and powers redstone mechanisms."),
|
||||
_doc_items_usagehelp = railuse .. "\n" .. S("To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail."),
|
||||
description = "Detector Rail",
|
||||
_doc_items_longdesc = "Rails can be used to build transport tracks for minecarts. A detector rail is able to detect a minecart above it and powers redstone mechanisms.",
|
||||
_doc_items_usagehelp = railuse .. "\n" .. "To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail.",
|
||||
mesecons = {
|
||||
receptor = {
|
||||
state = mesecon.state.off,
|
||||
rules = rail_rules_short,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -179,10 +130,8 @@ register_rail("mcl_minecarts:detector_rail_on",
|
|||
mesecons = {
|
||||
receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = rail_rules_short,
|
||||
},
|
||||
},
|
||||
drop = "mcl_minecarts:detector_rail",
|
||||
},
|
||||
false
|
||||
)
|
||||
|
@ -207,9 +156,6 @@ minetest.register_craft({
|
|||
}
|
||||
})
|
||||
|
||||
-- Activator rail crafting is disabled until it becomes useful.
|
||||
-- TODO: Enable crafting as needed.
|
||||
if false then
|
||||
minetest.register_craft({
|
||||
output = "mcl_minecarts:activator_rail 6",
|
||||
recipe = {
|
||||
|
@ -218,7 +164,6 @@ minetest.register_craft({
|
|||
{"mcl_core:iron_ingot", "mcl_core:stick", "mcl_core:iron_ingot"},
|
||||
}
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mcl_minecarts:detector_rail 6",
|
||||
|
|
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 223 B |
Before Width: | Height: | Size: 256 B After Width: | Height: | Size: 256 B |
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 258 B |
Before Width: | Height: | Size: 254 B |
Before Width: | Height: | Size: 254 B |
Before Width: | Height: | Size: 260 B |
Before Width: | Height: | Size: 266 B |
Before Width: | Height: | Size: 258 B |
Before Width: | Height: | Size: 258 B |
|
@ -1,733 +0,0 @@
|
|||
|
||||
Mobs Redo: MineClone 2 Edition
|
||||
API documentation
|
||||
==============================
|
||||
|
||||
Welcome to the world of mobs in Minetest and hopefully an easy guide to defining
|
||||
your own mobs and having them appear in your worlds.
|
||||
|
||||
|
||||
Registering Mobs
|
||||
----------------
|
||||
|
||||
To register a mob and have it ready for use requires the following function:
|
||||
|
||||
mobs:register_mob(name, definition)
|
||||
|
||||
The 'name' of a mob usually starts with the mod name it's running from followed
|
||||
by it's own name e.g.
|
||||
|
||||
"mobs_monster:sand_monster" or "mymod:totally_awesome_beast"
|
||||
|
||||
... and the 'definition' is a table which holds all of the settings and
|
||||
functions needed for the mob to work properly which contains the following:
|
||||
|
||||
'nametag' contains the name which is shown above mob.
|
||||
'type' holds the type of mob that inhabits your world e.g.
|
||||
"animal" usually docile and walking around.
|
||||
"monster" attacks player or npc on sight.
|
||||
"npc" walk around and will defend themselves if hit first, they
|
||||
kill monsters.
|
||||
'hp_min' has the minimum health value the mob can spawn with.
|
||||
'hp_max' has the maximum health value the mob can spawn with.
|
||||
'armor' holds strength of mob, 100 is normal, lower is more powerful
|
||||
and needs more hits and better weapons to kill.
|
||||
'passive' when true allows animals to defend themselves when hit,
|
||||
otherwise they amble onwards.
|
||||
'walk_velocity' is the speed that your mob can walk around.
|
||||
'run_velocity' is the speed your mob can run with, usually when attacking.
|
||||
'walk_chance' has a 0-100 chance value your mob will walk from standing,
|
||||
set to 0 for jumping mobs only.
|
||||
'jump' when true allows your mob to jump updwards.
|
||||
'jump_height' holds the height your mob can jump, 0 to disable jumping.
|
||||
'stepheight' height of a block that your mob can easily walk up onto,
|
||||
defaults to 1.1.
|
||||
'fly' when true allows your mob to fly around instead of walking.
|
||||
'fly_in' holds the node name that the mob flies (or swims) around
|
||||
in e.g. "air" or "default:water_source".
|
||||
'runaway' if true causes animals to turn and run away when hit.
|
||||
'view_range' how many nodes in distance the mob can see a player.
|
||||
'damage' how many health points the mob does to a player or another
|
||||
mob when melee attacking.
|
||||
'knock_back' when true has mobs falling backwards when hit, the greater
|
||||
the damage the more they move back.
|
||||
'fear_height' is how high a cliff or edge has to be before the mob stops
|
||||
walking, 0 to turn off height fear.
|
||||
'fall_speed' has the maximum speed the mob can fall at, default is -10.
|
||||
'fall_damage' when true causes falling to inflict damage.
|
||||
'water_damage' holds the damage per second infliced to mobs when standing in
|
||||
water.
|
||||
'lava_damage' holds the damage per second inflicted to mobs when standing
|
||||
in lava or fire.
|
||||
'light_damage' holds the damage per second inflicted to mobs when it's too
|
||||
bright (above 13 light).
|
||||
'suffocation' when true causes mobs to suffocate inside solid blocks (2 damage per second).
|
||||
'floats' when set to 1 mob will float in water, 0 has them sink.
|
||||
'follow' mobs follow player when holding any of the items which appear
|
||||
on this table, the same items can be fed to a mob to tame or
|
||||
breed e.g. {"farming:wheat", "default:apple"}
|
||||
|
||||
'reach' is how far the mob can attack player when standing
|
||||
nearby, default is 3 nodes.
|
||||
'docile_by_day' when true has mobs wandering around during daylight
|
||||
hours and only attacking player at night or when
|
||||
provoked.
|
||||
'attacks_monsters' when true has npc's attacking monsters or not.
|
||||
'attack_animals' when true will have monsters attacking animals.
|
||||
'owner_loyal' when true will have tamed mobs attack anything player
|
||||
punches when nearby.
|
||||
'group_attack' when true has same mob type grouping together to attack
|
||||
offender.
|
||||
'attack_type' tells the api what a mob does when attacking the player
|
||||
or another mob:
|
||||
'dogfight' is a melee attack when player is within mob reach.
|
||||
'shoot' has mob shoot pre-defined arrows at player when inside
|
||||
view_range.
|
||||
'dogshoot' has melee attack when inside reach and shoot attack
|
||||
when inside view_range.
|
||||
'explode' causes mob to stop and explode when inside reach.
|
||||
'explosion_radius' the radius of explosion node destruction,
|
||||
defaults to 1
|
||||
'explosion_damage_radius' the radius of explosion entity & player damage,
|
||||
defaults to explosion_radius * 2
|
||||
'explosion_timer' number of seconds before mob explodes while its target
|
||||
is still inside reach or explosion_damage_radius,
|
||||
defaults to 3.
|
||||
'allow_fuse_reset' Allow 'explode' attack_type to reset fuse and resume
|
||||
chasing if target leaves the blast radius or line of
|
||||
sight. Defaults to true.
|
||||
'stop_to_explode' When set to true (default), mob must stop and wait for
|
||||
explosion_timer in order to explode. If false, mob will
|
||||
continue chasing.
|
||||
'arrow' holds the pre-defined arrow object to shoot when
|
||||
attacking.
|
||||
'dogshoot_switch' allows switching between attack types by using timers
|
||||
(1 for shoot, 2 for dogfight)
|
||||
'dogshoot_count_max' contains how many seconds before switching from
|
||||
dogfight to shoot.
|
||||
'dogshoot_count2_max' contains how many seconds before switching from shoot
|
||||
to dogfight.
|
||||
'shoot_interval' has the number of seconds between shots.
|
||||
'shoot_offset' holds the y position added as to where the
|
||||
arrow/fireball appears on mob.
|
||||
'specific_attack' has a table of entity names that mob can also attack
|
||||
e.g. {"player", "mobs_animal:chicken"}.
|
||||
'runaway_from' contains a table with mob names to run away from, add
|
||||
"player" to list to runaway from player also.
|
||||
'blood_amount' contains the number of blood droplets to appear when
|
||||
mob is hit.
|
||||
'blood_texture' has the texture name to use for droplets e.g.
|
||||
"mobs_blood.png", or table {"blood1.png", "blood2.png"}
|
||||
'pathfinding' set to 1 for mobs to use pathfinder feature to locate
|
||||
player, set to 2 so they can build/break also (only
|
||||
works with dogfight attack and when 'mobs_griefing'
|
||||
in minetest.conf is not false).
|
||||
'immune_to' is a table that holds specific damage when being hit by
|
||||
certain items e.g.
|
||||
{"default:sword_wood", 0} -- causes no damage.
|
||||
{"default:gold_lump", -10} -- heals by 10 health points.
|
||||
{"default:coal_block", 20} -- 20 damage when hit on head with coal blocks.
|
||||
|
||||
'makes_footstep_sound' when true you can hear mobs walking.
|
||||
'sounds' this is a table with sounds of the mob
|
||||
'distance' maximum distance sounds can be heard, default is 10.
|
||||
'random' played randomly from time to time.
|
||||
also played for overfeeding animal.
|
||||
'war_cry' what you hear when mob starts to attack player. (currently disabled)
|
||||
'attack' what you hear when being attacked.
|
||||
'shoot_attack' sound played when mob shoots.
|
||||
'damage' sound heard when mob is hurt.
|
||||
'death' played when mob is killed.
|
||||
'jump' played when mob jumps. There's a built-in cooloff timer to avoid sound spam
|
||||
'fuse' sound played when mob explode timer starts.
|
||||
'explode' sound played when mob explodes.
|
||||
|
||||
'drops' table of items that are dropped when mob is killed, fields are:
|
||||
'name' name of item to drop.
|
||||
'chance' chance of drop, 1 for always, 2 for 1-in-2 chance etc.
|
||||
'min' minimum number of items dropped.
|
||||
'max' maximum number of items dropped.
|
||||
|
||||
'visual' holds the look of the mob you wish to create:
|
||||
'cube' looks like a normal node
|
||||
'sprite' sprite which looks same from all angles.
|
||||
'upright_sprite' flat model standing upright.
|
||||
'wielditem' how it looks when player holds it in hand.
|
||||
'mesh' uses separate object file to define mob.
|
||||
'visual_size' has the size of the mob, defaults to {x = 1, y = 1}
|
||||
'collisionbox' has the box in which mob can be interacted with the
|
||||
world e.g. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}
|
||||
'selectionbox' has the box in which player can interact with mob
|
||||
'textures' holds a table list of textures to be used for mob, or you
|
||||
could use multiple lists inside another table for random
|
||||
selection e.g. { {"texture1.png"}, {"texture2.png"} }
|
||||
'child_texture' holds the texture table for when baby mobs are used.
|
||||
'gotten_texture' holds the texture table for when self.gotten value is
|
||||
true, used for milking cows or shearing sheep.
|
||||
'mesh' holds the name of the external object used for mob model
|
||||
e.g. "mobs_cow.b3d"
|
||||
'gotten_mesh" holds the name of the external object used for when
|
||||
self.gotten is true for mobs.
|
||||
'rotate' custom model rotation, 0 = front, 90 = side, 180 = back,
|
||||
270 = other side.
|
||||
'double_melee_attack' when true has the api choose between 'punch' and
|
||||
'punch2' animations.
|
||||
|
||||
'animation' holds a table containing animation names and settings for use with mesh models:
|
||||
'stand_start' start frame for when mob stands still.
|
||||
'stand_end' end frame of stand animation.
|
||||
'stand_speed' speed of animation in frames per second.
|
||||
'walk_start' when mob is walking around.
|
||||
'walk_end'
|
||||
'walk_speed'
|
||||
'run_start' when a mob runs or attacks.
|
||||
'run_end'
|
||||
'run_speed'
|
||||
'fly_start' when a mob is flying.
|
||||
'fly_end'
|
||||
'fly_speed'
|
||||
'punch_start' when a mob melee attacks.
|
||||
'punch_end'
|
||||
'punch_speed'
|
||||
'punch2_start' alternative melee attack animation.
|
||||
'punch2_end'
|
||||
'punch2_speed'
|
||||
'shoot_start' shooting animation.
|
||||
'shoot_end'
|
||||
'shoot_speed'
|
||||
'die_start' death animation
|
||||
'die_end'
|
||||
'die_speed'
|
||||
'die_loop' when set to false stops the animation looping.
|
||||
|
||||
Using '_loop = false' setting will stop any of the above animations from
|
||||
looping.
|
||||
|
||||
'speed_normal' is used for animation speed for compatibility with some
|
||||
older mobs.
|
||||
|
||||
|
||||
MineClone 2 extensions:
|
||||
|
||||
'ignores_nametag' if true, mob cannot be named by nametag
|
||||
'rain_damage' damage per second if mob is standing in rain (default: 0)
|
||||
'sunlight_damage' holds the damage per second inflicted to mobs when they
|
||||
are in direct sunlight
|
||||
'spawn_small_alternative': name of a smaller mob to use as replacement if
|
||||
spawning fails due to space requirements
|
||||
|
||||
Node Replacement
|
||||
----------------
|
||||
|
||||
Mobs can look around for specific nodes as they walk and replace them to mimic
|
||||
eating.
|
||||
|
||||
'replace_what' group of items to replace e.g.
|
||||
{"farming:wheat_8", "farming:carrot_8"}
|
||||
or you can use the specific options of what, with and
|
||||
y offset by using this instead:
|
||||
{
|
||||
{"group:grass", "air", 0},
|
||||
{"default:dirt_with_grass", "default:dirt", -1}
|
||||
}
|
||||
'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg"
|
||||
'replace_rate' how random should the replace rate be (typically 10)
|
||||
'replace_offset' +/- value to check specific node to replace
|
||||
|
||||
'on_replace(self, pos, oldnode, newnode)' is called when mob is about to
|
||||
replace a node.
|
||||
'self' ObjectRef of mob
|
||||
'pos' Position of node to replace
|
||||
'oldnode' Current node
|
||||
'newnode' What the node will become after replacing
|
||||
|
||||
If false is returned, the mob will not replace the node.
|
||||
|
||||
By default, replacing sets self.gotten to true and resets the object
|
||||
properties.
|
||||
|
||||
|
||||
Custom Definition Functions
|
||||
---------------------------
|
||||
|
||||
Along with the above mob registry settings we can also use custom functions to
|
||||
enhance mob functionality and have them do many interesting things:
|
||||
|
||||
'on_die' a function that is called when the mob is killed the
|
||||
parameters are (self, pos)
|
||||
'on_rightclick' its same as in minetest.register_entity()
|
||||
'on_blast' is called when an explosion happens near mob when using TNT
|
||||
functions, parameters are (object, damage) and returns
|
||||
(do_damage, do_knockback, drops)
|
||||
'on_spawn' is a custom function that runs on mob spawn with 'self' as
|
||||
variable, return true at end of function to run only once.
|
||||
'after_activate' is a custom function that runs once mob has been activated
|
||||
with these paramaters (self, staticdata, def, dtime)
|
||||
'on_breed' called when two similar mobs breed, paramaters are
|
||||
(parent1, parent2) objects, return false to stop child from
|
||||
being resized and owner/tamed flags and child textures being
|
||||
applied. Function itself must spawn new child mob.
|
||||
'on_grown' is called when a child mob has grown up, only paramater is
|
||||
(self).
|
||||
'do_punch' called when mob is punched with paramaters (self, hitter,
|
||||
time_from_last_punch, tool_capabilities, direction), return
|
||||
false to stop punch damage and knockback from taking place.
|
||||
'custom_attack' when set this function is called instead of the normal mob
|
||||
melee attack, parameters are (self, to_attack).
|
||||
'on_die' a function that is called when mob is killed (self, pos)
|
||||
'do_custom' a custom function that is called every tick while mob is
|
||||
active and which has access to all of the self.* variables
|
||||
e.g. (self.health for health or self.standing_in for node
|
||||
status), return with 'false' to skip remainder of mob API.
|
||||
|
||||
|
||||
Internal Variables
|
||||
------------------
|
||||
|
||||
The mob api also has some preset variables and functions that it will remember
|
||||
for each mob.
|
||||
|
||||
'self.health' contains current health of mob (cannot exceed
|
||||
self.hp_max)
|
||||
'self.texture_list' contains list of all mob textures
|
||||
'self.child_texture' contains mob child texture when growing up
|
||||
'self.base_texture' contains current skin texture which was randomly
|
||||
selected from textures list
|
||||
'self.gotten' this is used for obtaining milk from cow and wool from
|
||||
sheep
|
||||
'self.horny' when animal fed enough it is set to true and animal can
|
||||
breed with same animal
|
||||
'self.hornytimer' background timer that controls breeding functions and
|
||||
mob childhood timings
|
||||
'self.child' used for when breeding animals have child, will use
|
||||
child_texture and be half size
|
||||
'self.owner' string used to set owner of npc mobs, typically used for
|
||||
dogs
|
||||
'self.order' set to "follow" or "stand" so that npc will follow owner
|
||||
or stand it's ground
|
||||
'self.nametag' contains the name of the mob which it can show above
|
||||
|
||||
|
||||
Spawning Mobs in World
|
||||
----------------------
|
||||
|
||||
mobs:register_spawn(name, nodes, max_light, min_light, chance,
|
||||
active_object_count, max_height, day_toggle)
|
||||
|
||||
mobs:spawn_specfic(name, nodes, neighbors, min_light, max_light, interval,
|
||||
chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
|
||||
|
||||
These functions register a spawn algorithm for the mob. Without this function
|
||||
the call the mobs won't spawn.
|
||||
|
||||
'name' is the name of the animal/monster
|
||||
'nodes' is a list of nodenames on that the animal/monster can
|
||||
spawn on top of
|
||||
'neighbors' is a list of nodenames on that the animal/monster will
|
||||
spawn beside (default is {"air"} for
|
||||
mobs:register_spawn)
|
||||
'max_light' is the maximum of light
|
||||
'min_light' is the minimum of light
|
||||
'interval' is same as in register_abm() (default is 30 for
|
||||
mobs:register_spawn)
|
||||
'chance' is same as in register_abm()
|
||||
'active_object_count' number of this type of mob to spawn at one time inside
|
||||
map area
|
||||
'min_height' is the minimum height the mob can spawn
|
||||
'max_height' is the maximum height the mob can spawn
|
||||
'day_toggle' true for day spawning, false for night or nil for
|
||||
anytime
|
||||
'on_spawn' is a custom function which runs after mob has spawned
|
||||
and gives self and pos values.
|
||||
|
||||
A simpler way to handle mob spawns has been added with the mobs:spawn(def)
|
||||
command which uses above names to make settings clearer:
|
||||
|
||||
mobs:spawn({name = "mobs_monster:tree_monster",
|
||||
nodes = {"group:leaves"},
|
||||
max_light = 7,
|
||||
})
|
||||
|
||||
|
||||
For each mob that spawns with this function is a field in mobs.spawning_mobs.
|
||||
It tells if the mob should spawn or not. Default is true. So other mods can
|
||||
only use the API of this mod by disabling the spawning of the default mobs in
|
||||
this mod.
|
||||
|
||||
|
||||
mobs:spawn_abm_check(pos, node, name)
|
||||
|
||||
This global function can be changed to contain additional checks for mobs to
|
||||
spawn e.g. mobs that spawn only in specific areas and the like. By returning
|
||||
true the mob will not spawn.
|
||||
|
||||
'pos' holds the position of the spawning mob
|
||||
'node' contains the node the mob is spawning on top of
|
||||
'name' is the name of the animal/monster
|
||||
|
||||
|
||||
MineClone 2 extensions
|
||||
----------------------
|
||||
|
||||
mobs:spawn_child(pos, mob_type)
|
||||
|
||||
This function spawns a mob as a child. The parameter mob_type is the
|
||||
entitystring of the new mob.
|
||||
This function returns the mob on success and nil otherwise.
|
||||
|
||||
|
||||
Making Arrows
|
||||
-------------
|
||||
|
||||
mobs:register_arrow(name, definition)
|
||||
|
||||
This function registers a arrow for mobs with the attack type shoot.
|
||||
|
||||
'name' is the name of the arrow
|
||||
'definition' is a table with the following values:
|
||||
'visual' same is in minetest.register_entity()
|
||||
'visual_size' same is in minetest.register_entity()
|
||||
'textures' same is in minetest.register_entity()
|
||||
'velocity' the velocity of the arrow
|
||||
'drop' if set to true any arrows hitting a node will drop as item
|
||||
'hit_player' a function that is called when the arrow hits a player;
|
||||
this function should hurt the player, the parameters are
|
||||
(self, player)
|
||||
'hit_mob' a function that is called when the arrow hits a mob;
|
||||
this function should hurt the mob, the parameters are
|
||||
(self, mob)
|
||||
'hit_node' a function that is called when the arrow hits a node, the
|
||||
parameters are (self, pos, node)
|
||||
'tail' when set to 1 adds a trail or tail to mob arrows
|
||||
'tail_texture' texture string used for above effect
|
||||
'tail_size' has size for above texture (defaults to between 5 and 10)
|
||||
'expire' contains float value for how long tail appears for
|
||||
(defaults to 0.25)
|
||||
'glow' has value for how brightly tail glows 1 to 10 (default is
|
||||
0 for no glow)
|
||||
'rotate' integer value in degrees to rotate arrow
|
||||
'on_step' is a custom function when arrow is active, nil for
|
||||
default.
|
||||
|
||||
|
||||
Spawn Eggs
|
||||
----------
|
||||
|
||||
mobs:register_egg(name, description, background, addegg, no_creative)
|
||||
|
||||
This function registers a spawn egg which can be used by admin to properly spawn in a mob.
|
||||
|
||||
'name' this is the name of your new mob to spawn e.g. "mob:sheep"
|
||||
'description' the name of the new egg you are creating e.g. "Spawn Sheep"
|
||||
'background' the texture displayed for the egg in inventory
|
||||
'addegg' would you like an egg image in front of your texture (1 = yes,
|
||||
0 = no)
|
||||
'no_creative' when set to true this stops spawn egg appearing in creative
|
||||
mode for destructive mobs like Dungeon Masters.
|
||||
|
||||
|
||||
Explosion Function
|
||||
------------------
|
||||
|
||||
mobs:explosion(pos, radius) -- DEPRECATED!!! use mobs:boom() instead
|
||||
|
||||
mobs:boom(self, pos, radius)
|
||||
'self' mob entity
|
||||
'pos' centre position of explosion
|
||||
'radius' radius of explosion (typically set to 3)
|
||||
|
||||
This function generates an explosion which removes nodes in a specific radius
|
||||
and damages any entity caught inside the blast radius. Protection will limit
|
||||
node destruction but not entity damage.
|
||||
|
||||
|
||||
mobs:capture_mob
|
||||
----------------
|
||||
|
||||
mobs:capture_mob(...)
|
||||
|
||||
Does nothing and returns false.
|
||||
|
||||
This function is provided for compability with Mobs Redo for an attempt to
|
||||
capture a mob.
|
||||
Mobs cannot be captured in MineClone 2.
|
||||
|
||||
In Mobs Redo, this is generally called inside the on_rightclick section of the mob
|
||||
api code, it provides a chance of capturing the mob. See Mobs Redo documentation
|
||||
of parameters.
|
||||
|
||||
Feeding and Taming/Breeding
|
||||
---------------------------
|
||||
|
||||
mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
||||
|
||||
This function allows the mob to be fed the item inside self.follow be it apple,
|
||||
wheat or whatever a set number of times and be tamed or bred as a result.
|
||||
Will return true when mob is fed with item it likes.
|
||||
|
||||
'self' mob information
|
||||
'clicker' player information
|
||||
'feed_count' number of times mob must be fed to tame or breed
|
||||
'breed' true or false stating if mob can be bred and a child created
|
||||
afterwards
|
||||
'tame' true or false stating if mob can be tamed so player can pick
|
||||
them up
|
||||
|
||||
|
||||
Protecting Mobs
|
||||
---------------
|
||||
|
||||
mobs:protect(self, clicker)
|
||||
|
||||
This function can be used to right-click any tamed mob with mobs:protector item,
|
||||
this will protect the mob from harm inside of a protected area from other
|
||||
players. Will return true when mob right-clicked with mobs:protector item.
|
||||
|
||||
'self' mob information
|
||||
'clicker' player information
|
||||
|
||||
|
||||
Riding Mobs
|
||||
-----------
|
||||
|
||||
Mobs can now be ridden by players and the following shows its functions and
|
||||
usage:
|
||||
|
||||
|
||||
mobs:attach(self, player)
|
||||
|
||||
This function attaches a player to the mob so it can be ridden.
|
||||
|
||||
'self' mob information
|
||||
'player' player information
|
||||
|
||||
|
||||
mobs:detach(player, offset)
|
||||
|
||||
This function will detach the player currently riding a mob to an offset
|
||||
position.
|
||||
|
||||
'player' player information
|
||||
'offset' position table containing offset values
|
||||
|
||||
|
||||
mobs:drive(self, move_animation, stand_animation, can_fly, dtime)
|
||||
|
||||
This function allows an attached player to move the mob around and animate it at
|
||||
same time.
|
||||
|
||||
'self' mob information
|
||||
'move_animation' string containing movement animation e.g. "walk"
|
||||
'stand_animation' string containing standing animation e.g. "stand"
|
||||
'can_fly' if true then jump and sneak controls will allow mob to fly
|
||||
up and down
|
||||
'dtime' tick time used inside drive function
|
||||
|
||||
|
||||
mobs:fly(self, dtime, speed, can_shoot, arrow_entity, move_animation, stand_animation)
|
||||
|
||||
This function allows an attached player to fly the mob around using directional
|
||||
controls.
|
||||
|
||||
'self' mob information
|
||||
'dtime' tick time used inside fly function
|
||||
'speed' speed of flight
|
||||
'can_shoot' true if mob can fire arrow (sneak and left mouse button
|
||||
fires)
|
||||
'arrow_entity' name of arrow entity used for firing
|
||||
'move_animation' string containing name of pre-defined animation e.g. "walk"
|
||||
or "fly" etc.
|
||||
'stand_animation' string containing name of pre-defined animation e.g.
|
||||
"stand" or "blink" etc.
|
||||
|
||||
Note: animation names above are from the pre-defined animation lists inside mob
|
||||
registry without extensions.
|
||||
|
||||
|
||||
mobs:set_animation(self, name)
|
||||
|
||||
This function sets the current animation for mob, defaulting to "stand" if not
|
||||
found.
|
||||
|
||||
'self' mob information
|
||||
'name' name of animation
|
||||
|
||||
|
||||
Certain variables need to be set before using the above functions:
|
||||
|
||||
'self.v2' toggle switch used to define below values for the
|
||||
first time
|
||||
'self.max_speed_forward' max speed mob can move forward
|
||||
'self.max_speed_reverse' max speed mob can move backwards
|
||||
'self.accel' acceleration speed
|
||||
'self.terrain_type' integer containing terrain mob can walk on
|
||||
(1 = water, 2 or 3 = land)
|
||||
'self.driver_attach_at' position offset for attaching player to mob
|
||||
'self.driver_eye_offset' position offset for attached player view
|
||||
'self.driver_scale' sets driver scale for mobs larger than {x=1, y=1}
|
||||
|
||||
|
||||
External Settings for "minetest.conf"
|
||||
------------------------------------
|
||||
|
||||
'enable_damage' if true monsters will attack players (default is true)
|
||||
'only_peaceful_mobs' if true only animals will spawn in game (default is
|
||||
false)
|
||||
'mobs_disable_blood' if false blood effects appear when mob is hit (default
|
||||
is false)
|
||||
'mobs_spawn_protected' if set to false then mobs will not spawn in protected
|
||||
areas (default is true)
|
||||
'remove_far_mobs' if true then untamed mobs that are outside players
|
||||
visual range will be removed (default is true)
|
||||
'mobname' can change specific mob chance rate (0 to disable) and
|
||||
spawn number e.g. mobs_animal:cow = 1000,5
|
||||
'mob_difficulty' sets difficulty level (health and hit damage
|
||||
multiplied by this number), defaults to 1.0.
|
||||
'mob_show_health' if false then punching mob will not show health status
|
||||
(true by default)
|
||||
'mob_chance_multiplier' multiplies chance of all mobs spawning and can be set
|
||||
to 0.5 to have mobs spawn more or 2.0 to spawn less.
|
||||
e.g. 1 in 7000 * 0.5 = 1 in 3500 so better odds of
|
||||
spawning.
|
||||
'mobs_spawn' if false then mobs no longer spawn without spawner or
|
||||
spawn egg.
|
||||
'mobs_drop_items' when false mobs no longer drop items when they die.
|
||||
'mobs_griefing' when false mobs cannot break blocks when using either
|
||||
pathfinding level 2, replace functions or mobs:boom
|
||||
function.
|
||||
|
||||
Players can override the spawn chance for each mob registered by adding a line
|
||||
to their minetest.conf file with a new value, the lower the value the more each
|
||||
mob will spawn e.g.
|
||||
|
||||
mobs_animal:sheep_chance 11000
|
||||
mobs_monster:sand_monster_chance 100
|
||||
|
||||
|
||||
Rideable Horse Example Mob
|
||||
--------------------------
|
||||
|
||||
mobs:register_mob("mob_horse:horse", {
|
||||
type = "animal",
|
||||
visual = "mesh",
|
||||
visual_size = {x = 1.20, y = 1.20},
|
||||
mesh = "mobs_horse.x",
|
||||
collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.25, 0.4},
|
||||
animation = {
|
||||
speed_normal = 15,
|
||||
speed_run = 30,
|
||||
stand_start = 25,
|
||||
stand_end = 75,
|
||||
walk_start = 75,
|
||||
walk_end = 100,
|
||||
run_start = 75,
|
||||
run_end = 100,
|
||||
},
|
||||
textures = {
|
||||
{"mobs_horse.png"},
|
||||
{"mobs_horsepeg.png"},
|
||||
{"mobs_horseara.png"}
|
||||
},
|
||||
fear_height = 3,
|
||||
runaway = true,
|
||||
fly = false,
|
||||
walk_chance = 60,
|
||||
view_range = 5,
|
||||
follow = {"farming:wheat"},
|
||||
passive = true,
|
||||
hp_min = 12,
|
||||
hp_max = 16,
|
||||
armor = 200,
|
||||
lava_damage = 5,
|
||||
fall_damage = 5,
|
||||
water_damage = 1,
|
||||
makes_footstep_sound = true,
|
||||
drops = {
|
||||
{name = "mobs:meat_raw", chance = 1, min = 2, max = 3}
|
||||
},
|
||||
sounds = {
|
||||
random = "horse_neigh.ogg",
|
||||
damage = "horse_whinney.ogg",
|
||||
},
|
||||
|
||||
do_custom = function(self, dtime)
|
||||
|
||||
-- set needed values if not already present
|
||||
if not self.v2 then
|
||||
self.v2 = 0
|
||||
self.max_speed_forward = 6
|
||||
self.max_speed_reverse = 2
|
||||
self.accel = 6
|
||||
self.terrain_type = 3
|
||||
self.driver_attach_at = {x = 0, y = 20, z = -2}
|
||||
self.driver_eye_offset = {x = 0, y = 3, z = 0}
|
||||
self.driver_scale = {x = 1, y = 1}
|
||||
end
|
||||
|
||||
-- if driver present allow control of horse
|
||||
if self.driver then
|
||||
|
||||
mobs.drive(self, "walk", "stand", false, dtime)
|
||||
|
||||
return false -- skip rest of mob functions
|
||||
end
|
||||
|
||||
return true
|
||||
end,
|
||||
|
||||
on_die = function(self, pos)
|
||||
|
||||
-- drop saddle when horse is killed while riding
|
||||
-- also detach from horse properly
|
||||
if self.driver then
|
||||
minetest.add_item(pos, "mobs:saddle")
|
||||
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
|
||||
end
|
||||
|
||||
end,
|
||||
|
||||
on_rightclick = function(self, clicker)
|
||||
|
||||
-- make sure player is clicking
|
||||
if not clicker or not clicker:is_player() then
|
||||
return
|
||||
end
|
||||
|
||||
-- feed, tame or heal horse
|
||||
if mobs:feed_tame(self, clicker, 10, true, true) then
|
||||
return
|
||||
end
|
||||
|
||||
-- make sure tamed horse is being clicked by owner only
|
||||
if self.tamed and self.owner == clicker:get_player_name() then
|
||||
|
||||
local inv = clicker:get_inventory()
|
||||
|
||||
-- detatch player already riding horse
|
||||
if self.driver and clicker == self.driver then
|
||||
|
||||
mobs.detach(clicker, {x = 1, y = 0, z = 1})
|
||||
|
||||
-- add saddle back to inventory
|
||||
if inv:room_for_item("main", "mobs:saddle") then
|
||||
inv:add_item("main", "mobs:saddle")
|
||||
else
|
||||
minetest.add_item(clicker.get_pos(), "mobs:saddle")
|
||||
end
|
||||
|
||||
-- attach player to horse
|
||||
elseif not self.driver
|
||||
and clicker:get_wielded_item():get_name() == "mobs:saddle" then
|
||||
|
||||
self.object:set_properties({stepheight = 1.1})
|
||||
mobs.attach(self, clicker)
|
||||
|
||||
-- take saddle from inventory
|
||||
inv:remove_item("main", "mobs:saddle")
|
||||
end
|
||||
end
|
||||
|
||||
-- used to capture horse with magic lasso
|
||||
mobs:capture_mob(self, clicker, 0, 0, 80, false, nil)
|
||||
end
|
||||
})
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
local S = mobs.intllib
|
||||
|
||||
-- name tag
|
||||
minetest.register_craftitem("mcl_mobs:nametag", {
|
||||
description = S("Name Tag"),
|
||||
_doc_items_longdesc = S("A name tag is an item to name a mob."),
|
||||
_doc_items_usagehelp = S("Before you use the name tag, you need to set a name at an anvil. Now you can use the name tag to name a mob with a rightclick. This uses up the name tag."),
|
||||
inventory_image = "mobs_nametag.png",
|
||||
wield_image = "mobs_nametag.png",
|
||||
stack_max = 64,
|
||||
groups = { tool=1 },
|
||||
})
|
||||
|
||||
minetest.register_alias("mobs:nametag", "mcl_mobs:nametag")
|
|
@ -1 +0,0 @@
|
|||
Adds a mob API for mods to add animals or monsters, etc.
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
local path = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
-- Mob API
|
||||
dofile(path .. "/api.lua")
|
||||
|
||||
-- Rideable Mobs
|
||||
dofile(path .. "/mount.lua")
|
||||
|
||||
-- Mob Items
|
||||
dofile(path .. "/crafts.lua")
|
||||
|
||||
minetest.log("action", "[MOD] Mobs Redo: MineClone 2 Edition loaded")
|
|
@ -1,128 +0,0 @@
|
|||
# Mobs Redo translation.
|
||||
# Copyright (C) 2017 TenPlus1
|
||||
# This file is distributed under the same license as the mobs package.
|
||||
# Wuzzy <Wuzzy@mail.ru>, 2017
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-07-16 16:48+0200\n"
|
||||
"PO-Revision-Date: 2017-07-16 16:48+0200\n"
|
||||
"Last-Translator: Aleks <alexsinteck@icqmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: es\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: api.lua
|
||||
msgid "** Peaceful Mode Active - No Monsters Will Spawn"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "Mob has been protected!"
|
||||
msgstr "El mob ha sido protegido!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 (Tamed)"
|
||||
msgstr "@1 (Domesticado)"
|
||||
|
||||
#: api.lua
|
||||
msgid "Not tamed!"
|
||||
msgstr "No domesticado!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 is owner!"
|
||||
msgstr "@1 es el dueño!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Missed!"
|
||||
msgstr "Perdido!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Already protected!"
|
||||
msgstr "Ya está protegido!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 at full health (@2)"
|
||||
msgstr "@1 con salud llena (@2)"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 has been tamed!"
|
||||
msgstr "@1 ha sido domesticado!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Enter name:"
|
||||
msgstr "Ingrese nombre:"
|
||||
|
||||
#: api.lua
|
||||
msgid "Rename"
|
||||
msgstr "Renombrar"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Name Tag"
|
||||
msgstr "Nombrar etiqueta"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Leather"
|
||||
msgstr "Cuero"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Raw Meat"
|
||||
msgstr "Carne cruda"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Meat"
|
||||
msgstr "Carne"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Lasso (right-click animal to put in inventory)"
|
||||
msgstr "Lazo (click derecho en animal para colocar en inventario)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Net (right-click animal to put in inventory)"
|
||||
msgstr "Red (click derecho en animal para colocar en inventario)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Steel Shears (right-click to shear)"
|
||||
msgstr "Tijera de acero (click derecho para esquilar)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Protection Rune"
|
||||
msgstr "Runa de protección de Mob"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Saddle"
|
||||
msgstr "Montura"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Fence"
|
||||
msgstr ""
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner"
|
||||
msgstr "Generador de Mob"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob MinLight MaxLight Amount PlayerDist"
|
||||
msgstr "Mob LuzMin LuzMax Cantidad DistJugador"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Spawner Not Active (enter settings)"
|
||||
msgstr "Generador no activo (ingrese config)"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Spawner Active (@1)"
|
||||
msgstr "Generador activo (@1)"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner settings failed!"
|
||||
msgstr "Configuracion de generador de Mob falló!"
|
||||
|
||||
#: spawner.lua
|
||||
msgid ""
|
||||
"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] "
|
||||
"distance[1-20] y_offset[-10 to 10]”"
|
||||
msgstr "Sintaxis: “nombre luz_min[0-14] luz_max[0-14] max_mobs_en_area[0 para deshabilitar] "
|
||||
"distancia[1-20] compensacion[-10 a 10]”"
|
|
@ -1,129 +0,0 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-07-29 09:13+0200\n"
|
||||
"PO-Revision-Date: 2017-07-29 09:20+0200\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.12\n"
|
||||
"Last-Translator: fat115 <fat115@framasoft.org>\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"Language: fr\n"
|
||||
|
||||
#: api.lua
|
||||
msgid "** Peaceful Mode Active - No Monsters Will Spawn"
|
||||
msgstr "** Mode pacifique activé - Aucun monstre ne sera généré"
|
||||
|
||||
#: api.lua
|
||||
msgid "Mob has been protected!"
|
||||
msgstr "L'animal a été protégé !"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 (Tamed)"
|
||||
msgstr "@1 (apprivoisé)"
|
||||
|
||||
#: api.lua
|
||||
msgid "Not tamed!"
|
||||
msgstr "Non-apprivoisé !"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 is owner!"
|
||||
msgstr "Appartient à @1 !"
|
||||
|
||||
#: api.lua
|
||||
msgid "Missed!"
|
||||
msgstr "Raté !"
|
||||
|
||||
#: api.lua
|
||||
msgid "Already protected!"
|
||||
msgstr "Déjà protégé !"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 at full health (@2)"
|
||||
msgstr "@1 est en pleine forme (@2) "
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 has been tamed!"
|
||||
msgstr "@1 a été apprivoisé ! "
|
||||
|
||||
#: api.lua
|
||||
msgid "Enter name:"
|
||||
msgstr "Saisissez un nom :"
|
||||
|
||||
#: api.lua
|
||||
msgid "Rename"
|
||||
msgstr "Renommer"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Name Tag"
|
||||
msgstr "Étiquette pour collier"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Leather"
|
||||
msgstr "Cuir"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Raw Meat"
|
||||
msgstr "Viande crue"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Meat"
|
||||
msgstr "Viande"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Lasso (right-click animal to put in inventory)"
|
||||
msgstr "Lasso (clic droit sur l'animal pour le mettre dans l'inventaire)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Net (right-click animal to put in inventory)"
|
||||
msgstr "Filet (clic droit sur l'animal pour le mettre dans l'inventaire)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Steel Shears (right-click to shear)"
|
||||
msgstr "Ciseaux à laine (clic droit pour tondre)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Protection Rune"
|
||||
msgstr "Rune de protection des animaux"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Saddle"
|
||||
msgstr "Selle"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Fence"
|
||||
msgstr "Clôture à animaux"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner"
|
||||
msgstr "Générateur de mob"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob MinLight MaxLight Amount PlayerDist"
|
||||
msgstr "Mob MinLumière MaxLumière Quantité DistanceJoueur"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Spawner Not Active (enter settings)"
|
||||
msgstr "Générateur non actif (entrez les paramètres)"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Spawner Active (@1)"
|
||||
msgstr "Générateur actif (@1)"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner settings failed!"
|
||||
msgstr "Echec des paramètres du générateur"
|
||||
|
||||
#: spawner.lua
|
||||
msgid ""
|
||||
"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] "
|
||||
"distance[1-20] y_offset[-10 to 10]”"
|
||||
msgstr "Syntaxe : “nom min_lumière[0-14] max_lumière[0-14] max_mobs_dans_zone[0 pour désactiver] distance[1-20] décalage_y[-10 à 10]“"
|
|
@ -1,131 +0,0 @@
|
|||
# ITALIAN LOCALE FILE FOR THE MOBS REDO MODULE
|
||||
# Copyright (c) 2014 Krupnov Pavel and 2016 TenPlus1
|
||||
# This file is distributed under the same license as the MOBS REDO package.
|
||||
# Hamlet <h4mlet@riseup.net>, 2017.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Italian locale file for the Mobs Redo module\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-07-02 16:48+0200\n"
|
||||
"PO-Revision-Date: 2017-08-18 12:18+0100\n"
|
||||
"Last-Translator: H4mlet <h4mlet@riseup.net>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: it\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Generator: Poedit 1.6.10\n"
|
||||
|
||||
#: api.lua
|
||||
msgid "** Peaceful Mode Active - No Monsters Will Spawn"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "Mob has been protected!"
|
||||
msgstr "Il mob è stato protetto!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 (Tamed)"
|
||||
msgstr "@1 (Addomesticat*)"
|
||||
|
||||
#: api.lua
|
||||
msgid "Not tamed!"
|
||||
msgstr "Non addomesticat*!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 is owner!"
|
||||
msgstr "Proprietari* @1!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Missed!"
|
||||
msgstr "Mancat*!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Already protected!"
|
||||
msgstr "Già protett*!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 at full health (@2)"
|
||||
msgstr "@1 in piena salute (@2)"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 has been tamed!"
|
||||
msgstr "@1 è stat* addomesticat*!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Enter name:"
|
||||
msgstr "Inserire il nome:"
|
||||
|
||||
#: api.lua
|
||||
msgid "Rename"
|
||||
msgstr "Rinominare"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Name Tag"
|
||||
msgstr "Targhetta"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Leather"
|
||||
msgstr "Pelle"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Raw Meat"
|
||||
msgstr "Carne cruda"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Meat"
|
||||
msgstr "Carne"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Lasso (right-click animal to put in inventory)"
|
||||
msgstr "Lazo (click di destro per mettere l'animale nell'inventario)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Net (right-click animal to put in inventory)"
|
||||
msgstr "Rete (click destro per mettere l'animale nell'inventario)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Steel Shears (right-click to shear)"
|
||||
msgstr "Cesoie d'acciaio (click destro per tosare)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Protection Rune"
|
||||
msgstr "Runa di protezione per mob"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Saddle"
|
||||
msgstr "Sella"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Fence"
|
||||
msgstr ""
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner"
|
||||
msgstr "Generatore di mob"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob MinLight MaxLight Amount PlayerDist"
|
||||
msgstr "Mob LuceMin LuceMax Ammontare DistGiocat."
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Spawner Not Active (enter settings)"
|
||||
msgstr "Generatore inattivo (inserire le impostazioni)"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Spawner Active (@1)"
|
||||
msgstr "Generatore attivo (@1)"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner settings failed!"
|
||||
msgstr "Impostazioni del generatore di mob fallite!"
|
||||
|
||||
#: spawner.lua
|
||||
msgid ""
|
||||
"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] "
|
||||
"distance[1-20] y_offset[-10 to 10]”"
|
||||
msgstr ""
|
||||
"Sintassi: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 per "
|
||||
"disabilitare] distance[1-20] y_offset[-10 to 10]”"
|
|
@ -1,131 +0,0 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-02-05 23:40+0800\n"
|
||||
"PO-Revision-Date: 2018-02-05 23:51+0800\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
"Last-Translator: MuhdNurHidayat (MNH48) <mnh48mail@gmail.com>\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"Language: ms\n"
|
||||
|
||||
#: api.lua
|
||||
msgid "** Peaceful Mode Active - No Monsters Will Spawn"
|
||||
msgstr "** Mod Aman Diaktifkan - Tiada Raksasa Akan Muncul"
|
||||
|
||||
#: api.lua
|
||||
msgid "Mob has been protected!"
|
||||
msgstr "Mob telah pun dilindungi!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 (Tamed)"
|
||||
msgstr "@1 (Jinak)"
|
||||
|
||||
#: api.lua
|
||||
msgid "Not tamed!"
|
||||
msgstr "Belum dijinakkan!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 is owner!"
|
||||
msgstr "Ini hak milik @1!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Missed!"
|
||||
msgstr "Terlepas!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Already protected!"
|
||||
msgstr "Telah dilindungi!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 at full health (@2)"
|
||||
msgstr "Mata kesihatan @1 telah penuh (@2)"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 has been tamed!"
|
||||
msgstr "@1 telah dijinakkan!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Enter name:"
|
||||
msgstr "Masukkan nama:"
|
||||
|
||||
#: api.lua
|
||||
msgid "Rename"
|
||||
msgstr "Namakan semula"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Name Tag"
|
||||
msgstr "Tanda Nama"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Leather"
|
||||
msgstr "Kulit"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Raw Meat"
|
||||
msgstr "Daging Mentah"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Meat"
|
||||
msgstr "Daging Bakar"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Lasso (right-click animal to put in inventory)"
|
||||
msgstr "Tanjul (klik-kanan haiwan untuk masukkan ke inventori)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Net (right-click animal to put in inventory)"
|
||||
msgstr "Jaring (klik-kanan haiwan untuk masukkan ke inventori)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Steel Shears (right-click to shear)"
|
||||
msgstr "Ketam Keluli (klik-kanan untuk mengetam bulu biri-biri)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Protection Rune"
|
||||
msgstr "Rune Perlindungan Mob"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Saddle"
|
||||
msgstr "Pelana"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Fence"
|
||||
msgstr "Pagar Mob"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner"
|
||||
msgstr "Pewujud Mob"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob MinLight MaxLight Amount PlayerDist"
|
||||
msgstr "Mob CahayaMin CahayaMax Amaun JarakPemain"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Spawner Not Active (enter settings)"
|
||||
msgstr "Pewujud Mob Tidak Aktif (masukkan tetapan)"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Spawner Active (@1)"
|
||||
msgstr "Pewujud Mob Aktif (@1)"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner settings failed!"
|
||||
msgstr "Penetapan Pewujud Mob gagal!"
|
||||
|
||||
#: spawner.lua
|
||||
msgid ""
|
||||
"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] "
|
||||
"distance[1-20] y_offset[-10 to 10]”"
|
||||
msgstr ""
|
||||
"Sintaks: \"nama cahaya_minimum[0-14] cahaya_maksimum[0-14] "
|
||||
"amaun_mob_maksimum[0 untuk lumpuhkan] jarak[1-20] ketinggian[-10 hingga 10]\""
|
|
@ -1,129 +0,0 @@
|
|||
# Russian translation for the mobs_redo mod.
|
||||
# Copyright (C) 2018 TenPlus1
|
||||
# This file is distributed under the same license as the mobs_redo package.
|
||||
# Oleg720 <olegsiriak@yandex.ru>, 2017.
|
||||
# CodeXP <codexp@gmx.net>, 2018.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2017-08-13 15:47+0200\n"
|
||||
"PO-Revision-Date: 2018-03-23 22:22+0100\n"
|
||||
"Last-Translator: CodeXP <codexp@gmx.net>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: ru\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: api.lua
|
||||
msgid "** Peaceful Mode Active - No Monsters Will Spawn"
|
||||
msgstr "** Мирный модус активирован - монстры не спаунятся"
|
||||
|
||||
#: api.lua
|
||||
msgid "Mob has been protected!"
|
||||
msgstr "Моб защищен!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 (Tamed)"
|
||||
msgstr "@1 (Прирученный)"
|
||||
|
||||
#: api.lua
|
||||
msgid "Not tamed!"
|
||||
msgstr "Не прирученный"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 is owner!"
|
||||
msgstr "@1 владелец"
|
||||
|
||||
#: api.lua
|
||||
msgid "Missed!"
|
||||
msgstr "Промазал!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Already protected!"
|
||||
msgstr "Уже защищен!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 at full health (@2)"
|
||||
msgstr "@1 при полном здоровье (@2)"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 has been tamed!"
|
||||
msgstr "@1 приручен"
|
||||
|
||||
#: api.lua
|
||||
msgid "Enter name:"
|
||||
msgstr "Введите имя:"
|
||||
|
||||
#: api.lua
|
||||
msgid "Rename"
|
||||
msgstr "Переименовать"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Name Tag"
|
||||
msgstr "Новый тэг"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Leather"
|
||||
msgstr "Кожа"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Raw Meat"
|
||||
msgstr "Сырое мясо"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Meat"
|
||||
msgstr "Мясо"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Lasso (right-click animal to put in inventory)"
|
||||
msgstr "Лассо (Правый клик - положить животное в инвентарь)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Net (right-click animal to put in inventory)"
|
||||
msgstr "Сеть (Правый клик - положить животное в инвентарь)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Steel Shears (right-click to shear)"
|
||||
msgstr "Ножницы (Правый клик - подстричь)"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Protection Rune"
|
||||
msgstr "Защитная руна мобов"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Saddle"
|
||||
msgstr "Седло"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Fence"
|
||||
msgstr "Забор от мобов"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner"
|
||||
msgstr "Спаунер моба"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob MinLight MaxLight Amount PlayerDist"
|
||||
msgstr ""
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Spawner Not Active (enter settings)"
|
||||
msgstr "Спаунер не активен (введите настройки)"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Spawner Active (@1)"
|
||||
msgstr "Активные спаунер (@1)"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner settings failed!"
|
||||
msgstr "Настройки спаунера моба провалились"
|
||||
|
||||
#: spawner.lua
|
||||
msgid ""
|
||||
"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] "
|
||||
"distance[1-20] y_offset[-10 to 10]”"
|
||||
msgstr ""
|
|
@ -1,8 +0,0 @@
|
|||
|
||||
if minetest.get_modpath("lucky_block") then
|
||||
|
||||
lucky_block:add_blocks({
|
||||
{"dro", {"mcl_mobs:nametag"}, 1},
|
||||
{"lig"},
|
||||
})
|
||||
end
|
|
@ -1 +0,0 @@
|
|||
name = mcl_mobs
|
|
@ -0,0 +1 @@
|
|||
mcl_core?
|
|
@ -0,0 +1 @@
|
|||
Decorative paintings which you can placed on walls.
|
|
@ -0,0 +1,151 @@
|
|||
-- TODO: Move all textures to mcl_paintings when finished
|
||||
|
||||
-- Intllib
|
||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||
local S, NS = dofile(MP .. "/intllib.lua")
|
||||
|
||||
minetest.register_craftitem("mcl_paintings:painting", {
|
||||
description = S("Next-Gen Painting"),
|
||||
_doc_items_longdesc = S("Paintings are decorations which can be placed on walls. THIS ITEM IS INCOMPLETE."),
|
||||
wield_image = "gemalde_node.png",
|
||||
inventory_image = "gemalde_node.png",
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
local under = pointed_thing.under
|
||||
local above = pointed_thing.above
|
||||
|
||||
-- Use pointed node's on_rightclick function first, if present
|
||||
local node_under = minetest.get_node(under)
|
||||
if placer and not placer:get_player_control().sneak then
|
||||
if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then
|
||||
return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack
|
||||
end
|
||||
end
|
||||
|
||||
-- Can only be placed on side
|
||||
if under.y ~= above.y then
|
||||
return itemstack
|
||||
end
|
||||
-- Can only be placed on solid nodes
|
||||
if minetest.get_item_group(node_under.name, "solid") == 0 then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- Spawn painting and rotate
|
||||
local painting = minetest.add_entity(above, "mcl_paintings:painting")
|
||||
local yaw = minetest.dir_to_yaw(vector.direction(under, above))
|
||||
painting:set_yaw(yaw)
|
||||
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
-- List of painting IDs, indexed by size.
|
||||
-- Outer index: Width in node lengths
|
||||
-- Inner index: Height in node lengths
|
||||
local paintings = {
|
||||
[1] = {
|
||||
[1] = { 1, 2, 3, 4, 5, 6, 7 }, -- 1×1
|
||||
[2] = { 8, 9, 10, 11, 12 }, -- 1×2
|
||||
},
|
||||
[2] = {
|
||||
[1] = { 13, 14}, -- 2×1
|
||||
[2] = { 15, 16, 17, 18, 19, 20 }, -- 2×2
|
||||
},
|
||||
[3] = {
|
||||
[4] = { 25, 26 }, -- 3×4
|
||||
},
|
||||
[4] = {
|
||||
[2] = { 21 }, -- 4×2
|
||||
[4] = { 22, 23, 24 }, -- 4×4
|
||||
},
|
||||
}
|
||||
|
||||
-- Returns a random painting ID for the given size.
|
||||
-- x: Width in node lenghts
|
||||
-- y: Height in node lengths
|
||||
local function select_painting(x, y)
|
||||
if paintings[x] then
|
||||
local pool = paintings[x][y]
|
||||
if paintings[x][y] then
|
||||
local p = math.random(1, #pool)
|
||||
return p
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Returns the texture table for the given painting ID
|
||||
local get_textures = function(painting_id)
|
||||
return {
|
||||
"gemalde_bg.png",
|
||||
"gemalde_bg.png",
|
||||
"gemalde_bg.png",
|
||||
"gemalde_bg.png",
|
||||
"gemalde_"..tostring(painting_id)..".png",
|
||||
"gemalde_bg.png"
|
||||
}
|
||||
end
|
||||
|
||||
-- Painting entitty.
|
||||
-- Can be killed.
|
||||
-- Breaks and drops as item if punched.
|
||||
--
|
||||
minetest.register_entity("mcl_paintings:painting", {
|
||||
physical = false,
|
||||
collide_with_objects = true,
|
||||
hp_max = 1,
|
||||
-- TODO: Fix visual
|
||||
visual = "cube",
|
||||
visual_size = { x=1, y=1 },
|
||||
textures = get_textures(1),
|
||||
|
||||
_painting = nil, -- Holds the current painting ID. Initially nil for random painting
|
||||
|
||||
get_staticdata = function(self)
|
||||
local out = { _painting = self._painting }
|
||||
return minetest.serialize(out)
|
||||
end,
|
||||
on_activate = function(self, staticdata)
|
||||
if staticdata and staticdata ~= "" then
|
||||
local inp = minetest.deserialize(staticdata)
|
||||
self._painting = inp._painting
|
||||
end
|
||||
-- Initial spawn. Select random painting
|
||||
if not self._painting then
|
||||
self._painting = select_painting(1, 1)
|
||||
end
|
||||
self.object:set_properties({textures = get_textures(self._painting)})
|
||||
end,
|
||||
on_punch = function(self, puncher)
|
||||
if not puncher or not puncher:is_player() or self._removed then
|
||||
return
|
||||
end
|
||||
-- Drop painting as item on ground
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
minetest.add_item(self.object:getpos(), "mcl_paintings:painting")
|
||||
end
|
||||
self._removed = true
|
||||
self.object:remove()
|
||||
end
|
||||
})
|
||||
|
||||
--[[
|
||||
-- TODO: Add crafting when this mod works better
|
||||
if minetest.get_modpath("mcl_core") then
|
||||
minetest.register_craft({
|
||||
output = "mcl_paintings:painting",
|
||||
recipe = {
|
||||
{"mcl_core:stick", "mcl_core:stick", "mcl_core:stick"},
|
||||
{"mcl_core:stick", "group:wool", "mcl_core:stick"},
|
||||
{"mcl_core:stick", "mcl_core:stick", "mcl_core:stick"},
|
||||
}
|
||||
})
|
||||
end
|
||||
]]
|
|
@ -0,0 +1 @@
|
|||
name = mcl_paintings
|
|
@ -0,0 +1,462 @@
|
|||
|
||||
MOB API (13th July 2017)
|
||||
|
||||
The mob api is a function that can be called on by other mods to add new animals or monsters into minetest.
|
||||
|
||||
minetest.conf settings*
|
||||
|
||||
'enable_damage' if true monsters will attack players (default is true)
|
||||
'only_peaceful_mobs' if true only animals will spawn in game (default is false)
|
||||
'mobs_disable_blood' if false blood effects appear when mob is hit (default is false)
|
||||
'mobs_spawn_protected' if set to false then mobs will not spawn in protected areas (default is true)
|
||||
'remove_far_mobs' if true then mobs that are outside players visual range will be removed (default is false)
|
||||
'mobname' can change specific mob chance rate (0 to disable) and spawn number e.g. mobs_animal:cow = 1000,5
|
||||
'mob_difficulty' sets difficulty level (health and hit damage multiplied by this number), defaults to 1.0.
|
||||
'mob_show_health' if false then punching mob will not show health status (true by default)
|
||||
|
||||
mobs:register_mob(name, definition)
|
||||
|
||||
This functions registers a new mob as a Minetest entity.
|
||||
|
||||
'name' is the name of the mob (e.g. "mobs:dirt_monster")
|
||||
definition is a table with the following fields
|
||||
'type' the type of the mob ("monster", "animal" or "npc") where monsters attack players and npc's, animals and npc's tend to wander around and can attack when hit 1st.
|
||||
'passive' will mob defend itself, set to false to attack
|
||||
'docile_by_day' when true, mob will not attack during daylight hours unless provoked
|
||||
'attacks_monsters' usually for npc's to attack monsters in area
|
||||
'group_attack' true to defend same kind of mobs from attack in area
|
||||
'owner_loyal' when true owned mobs will attack any monsters you punch
|
||||
'attack_animals' true for monster to attack animals as well as player and npc's
|
||||
'specific_attack' has a table of entity names that monsters can attack {"player", "mobs_animal:chicken"}
|
||||
'hp_min' minimum health
|
||||
'hp_max' maximum health (mob health is randomly selected between both)
|
||||
'physical' same is in minetest.register_entity()
|
||||
'collisionbox' same is in minetest.register_entity()
|
||||
'visual' same is in minetest.register_entity()
|
||||
'visual_size' same is in minetest.register_entity()
|
||||
'textures' same is in minetest.register_entity()
|
||||
although you can add multiple lines for random textures {{"texture1.png"},{"texture2.png"}},
|
||||
'gotten_texture' alt. texture for when self.gotten value is set to true (used for shearing sheep)
|
||||
'child_texture' texture of mod for when self.child is set to true
|
||||
'mesh' same is in minetest.register_entity()
|
||||
'gotten_mesh' alternative mesh for when self.gotten is true (used for sheep)
|
||||
'makes_footstep_sound' same is in minetest.register_entity()
|
||||
'follow' item when held will cause mob to follow player, can be single string "default:apple" or table {"default:apple", "default:diamond"}. These are also items that are used to feed and tame mob.
|
||||
'view_range' the range in which the mob will follow or attack player
|
||||
'walk_chance' chance of mob walking around (0 to 100), set to 0 for jumping mob only
|
||||
'walk_velocity' the velocity when the monster is walking around
|
||||
'run_velocity' the velocity when the monster is attacking a player
|
||||
'runaway' when true mob will turn and run away when punched
|
||||
'stepheight' minimum node height mob can walk onto without jumping (default: 0.6)
|
||||
'jump' can mob jump, true or false
|
||||
'jump_height' height mob can jump, default is 6 (0 to disable jump)
|
||||
'fly' can mob fly, true or false (used for swimming mobs also)
|
||||
'fly_in' node name that mob flys inside, e.g "air", "default:water_source" for fish
|
||||
'damage' the damage mobs inflict per melee attack.
|
||||
'recovery_time' how much time from when mob is hit to recovery (default: 0.5 seconds)
|
||||
'knock_back' strength of knock-back when mob hit (default: 3)
|
||||
'immune_to' table holding special tool/item names and damage the incur e.g.
|
||||
{"default:sword_wood", 0}, {"default:gold_lump", -10} immune to sword, gold lump heals
|
||||
'blood_amount' number of droplets that appear when hit
|
||||
'blood_texture' texture of blood droplets (default: "mobs_blood.png")
|
||||
'drops' is list of tables with the following fields:
|
||||
'name' itemname e.g. default:stone
|
||||
'chance' the inverted chance (same as in abm) to get the item
|
||||
'min' the minimum number of items
|
||||
'max' the maximum number of items
|
||||
'armor' this integer holds armor strength with 100 being normal, with lower numbers hardening the armor and higher numbers making it weaker (weird I know but compatible with simple mobs)
|
||||
'drawtype' "front" or "side" (DEPRECATED, replaced with below)
|
||||
'rotate' set mob rotation, 0=front, 90=side, 180=back, 270=other side
|
||||
'water_damage' the damage per second if the mob is in water
|
||||
'lava_damage' the damage per second if the mob is in lava
|
||||
'light_damage' the damage per second if the mob is in light
|
||||
'suffocation' health value mob loses when inside a solid node
|
||||
'fall_damage' will mob be hurt when falling from height
|
||||
'fall_speed' maximum falling velocity of mob (default is -10 and must be below -2)
|
||||
'fear_height' when mob walks near a drop then anything over this value makes it stop and turn back (default is 0 to disable)
|
||||
'on_die' a function that is called when the mob is killed the parameters are (self, pos)
|
||||
'floats' 1 to float in water, 0 to sink
|
||||
'on_rightclick' its same as in minetest.register_entity()
|
||||
'pathfinding' set to 1 for mobs to use pathfinder feature to locate player, set to 2 so they can build/break also (only works with dogfight attack)
|
||||
'attack_type' the attack type of a monster
|
||||
'dogfight' follows player in range and attacks when in reach
|
||||
'shoot' shoots defined arrows when player is within range
|
||||
'explode' follows player in range and will flash and explode when in reach
|
||||
'dogshoot' shoots arrows when in range and one on one attack when in reach
|
||||
'dogshoot_switch' allows switching between shoot and dogfight modes inside dogshoot using timer (1 = shoot, 2 = dogfight)
|
||||
'dogshoot_count_max' number of seconds before switching to dogfight mode.
|
||||
'dogshoot_count2_max' number of seconds before switching back to shoot mode.
|
||||
'custom_attack' when set this function is called instead of the normal mob melee attack, parameters are (self, to_attack)
|
||||
'double_melee_attack' if false then api will choose randomly between 'punch' and 'punch2' attack animations
|
||||
'on_blast' is called when an explosion happens near mob when using TNT functions, parameters are (object, damage) and returns (do_damage, do_knockback, drops)
|
||||
'explosion_radius' radius of explosion attack (defaults to 1)
|
||||
'arrow' if the attack_type is "shoot" or "dogshoot" then the entity name of a pre-defined arrow is required, see below for arrow definition.
|
||||
'shoot_interval' the minimum shoot interval
|
||||
'shoot_offset' +/- value to position arrow/fireball when fired
|
||||
'reach' how far a reach this mob has, default is 3
|
||||
'sounds' this is a table with sounds of the mob
|
||||
'random' random sounds during gameplay
|
||||
'war_cry' sound when starting to attack player
|
||||
'attack' sound when attacking player
|
||||
'shoot_attack' sound when attacking player by shooting arrow/entity
|
||||
'damage' sound when being hit
|
||||
'death' sound when killed
|
||||
'jump' sound when jumping
|
||||
'explode' sound when exploding
|
||||
'distance' maximum distance sounds are heard from (default is 10)
|
||||
|
||||
Mobs can look for specific nodes as they walk and replace them to mimic eating.
|
||||
|
||||
'replace_what' group if items to replace e.g. {"farming:wheat_8", "farming:carrot_8"}
|
||||
'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg"
|
||||
'replace_rate' how random should the replace rate be (typically 10)
|
||||
'replace_offset' +/- value to check specific node to replace
|
||||
'on_replace(self, pos, oldnode, newnode)' gets called when mob is about to replace a node
|
||||
self: ObjectRef of mob
|
||||
pos: Position of node to replace
|
||||
oldnode: Current node
|
||||
newnode: What the node will become after replacing
|
||||
|
||||
If false is returned, the mob will not replace the node.
|
||||
|
||||
By default, replacing sets self.gotten to true and resets the object properties.
|
||||
|
||||
The 'replace_what' has been updated to use tables for what, with and y_offset e.g.
|
||||
|
||||
replace_what = { {"group:grass", "air", 0}, {"default:dirt_with_grass", "default:dirt", -1} }
|
||||
|
||||
Mob animation comes in three parts, start_frame, end_frame and frame_speed which
|
||||
can be added to the mob definition under pre-defined mob animation names like:
|
||||
|
||||
'animation' a table with the animation ranges and speed of the model
|
||||
'stand_start', 'stand_end', 'stand_speed' when mob stands still
|
||||
'walk_start', 'walk_end', 'walk_speed' when mob walks
|
||||
'run_start', 'run_end', 'run_speed' when mob runs
|
||||
'fly_start', 'fly_end', 'fly_speed' when mob flies
|
||||
'punch_start', 'punch_end', 'punch_speed' when mob attacks
|
||||
'punch2_start', 'punch2_end', 'punch2_speed' when mob attacks (alternative)
|
||||
'die_start', 'die_end', 'die_speed' when mob dies
|
||||
'*_loop' bool value to determine if any set animation loops e.g (die_loop = false)
|
||||
defaults to true if not set
|
||||
also 'speed_normal' for compatibility with older mobs for animation speed (deprecated)
|
||||
|
||||
|
||||
The mob api also has some preset variables and functions that it will remember for each mob
|
||||
|
||||
'self.health' contains current health of mob (cannot exceed self.hp_max)
|
||||
'self.texture_list' contains list of all mob textures
|
||||
'self.child_texture' contains mob child texture when growing up
|
||||
'self.base_texture' contains current skin texture which was randomly selected from textures list
|
||||
'self.gotten' this is used for obtaining milk from cow and wool from sheep
|
||||
'self.horny' when animal fed enough it is set to true and animal can breed with same animal
|
||||
'self.hornytimer' background timer that controls breeding functions and mob childhood timings
|
||||
'self.child' used for when breeding animals have child, will use child_texture and be half size
|
||||
'self.owner' string used to set owner of npc mobs, typically used for dogs
|
||||
'self.order' set to "follow" or "stand" so that npc will follow owner or stand it's ground
|
||||
'self.nametag' contains the name of the mob which it can show above
|
||||
'on_die' a function that is called when mob is killed
|
||||
'do_custom' a custom function that is called every tick while mob is active and which has access to all of the self.* variables e.g. (self.health for health or self.standing_in for node status), return with 'false' to skip remainder of mob API.
|
||||
|
||||
|
||||
mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle)
|
||||
|
||||
mobs:spawn_specfic(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
|
||||
|
||||
These functions register a spawn algorithm for the mob. Without this function the call the mobs won't spawn.
|
||||
|
||||
'name' is the name of the animal/monster
|
||||
'nodes' is a list of nodenames on that the animal/monster can spawn on top of
|
||||
'neighbors' is a list of nodenames on that the animal/monster will spawn beside (default is {"air"} for mobs:register_spawn)
|
||||
'max_light' is the maximum of light
|
||||
'min_light' is the minimum of light
|
||||
'interval' is same as in register_abm() (default is 30 for mobs:register_spawn)
|
||||
'chance' is same as in register_abm()
|
||||
'active_object_count' mob is only spawned if active_object_count_wider of ABM is <= this
|
||||
'min_height' is the minimum height the mob can spawn
|
||||
'max_height' is the maximum height the mob can spawn
|
||||
'day_toggle' true for day spawning, false for night or nil for anytime
|
||||
'on_spawn' is a custom function which runs after mob has spawned and gives self and pos values.
|
||||
|
||||
... also a simpler way to handle mob spawns has been added with the mobs:spawn(def) command which uses above names to make settings clearer:
|
||||
|
||||
mobs:spawn({name = "mobs_monster:tree_monster",
|
||||
nodes = {"group:leaves"},
|
||||
max_light = 7,
|
||||
})
|
||||
|
||||
|
||||
Players can override the spawn chance for each mob registered by adding a line to their minetest.conf file with a new value, the lower the value the more each mob will spawn e.g.
|
||||
|
||||
mobs_animal:sheep_chance 11000 or mobs_monster:sand_monster_chance 100
|
||||
|
||||
For each mob that spawns with this function is a field in mobs.spawning_mobs. It tells if the mob should spawn or not. Default is true. So other mods can only use the API of this mod by disabling the spawning of the default mobs in this mod.
|
||||
|
||||
|
||||
mobs:register_arrow(name, definition)
|
||||
|
||||
This function registers a arrow for mobs with the attack type shoot.
|
||||
|
||||
'name' is the name of the arrow
|
||||
-definition' is a table with the following values:
|
||||
'visual' same is in minetest.register_entity()
|
||||
'visual_size' same is in minetest.register_entity()
|
||||
'textures' same is in minetest.register_entity()
|
||||
'velocity' the velocity of the arrow
|
||||
'drop' if set to true any arrows hitting a node will drop as item
|
||||
'hit_player' a function that is called when the arrow hits a player; this function should hurt the player
|
||||
the parameters are (self, player)
|
||||
'hit_mob' a function that is called when the arrow hits a mob; this function should hurt the mob
|
||||
the parameters are (self, player)
|
||||
'hit_node' a function that is called when the arrow hits a node
|
||||
the parameters are (self, pos, node)
|
||||
'tail' when set to 1 adds a trail or tail to mob arrows
|
||||
'tail_texture' texture string used for above effect
|
||||
'tail_size' has size for above texture (defaults to between 5 and 10)
|
||||
'expire' contains float value for how long tail appears for (defaults to 0.25)
|
||||
'glow' has value for how brightly tail glows 1 to 10 (default is 0, no glow)
|
||||
'rotate' integer value in degrees to rotate arrow
|
||||
'on_step' is a custom function when arrow is active, nil for default.
|
||||
|
||||
|
||||
mobs:register_egg(name, description, background, addegg, no_creative)
|
||||
|
||||
This function registers a spawn egg which can be used by admin to properly spawn in a mob.
|
||||
|
||||
'name' this is the name of your new mob to spawn e.g. "mob:sheep"
|
||||
'description' the name of the new egg you are creating e.g. "Spawn Sheep"
|
||||
'background' the texture displayed for the egg in inventory
|
||||
'addegg' would you like an egg image in front of your texture (1=yes, 0=no)
|
||||
'no_creative' when set to true this stops spawn egg appearing in creative mode for destructive mobs like Dungeon Masters
|
||||
|
||||
|
||||
mobs:explosion(pos, radius) -- DEPRECATED!!! use mobs:boom() instead
|
||||
|
||||
mobs:boom(self, pos, radius)
|
||||
This function generates an explosion which removes nodes in a specific radius and damages any entity caught inside the blast radius. Protection will limit node destruction but not entity damage.
|
||||
|
||||
'self' mob entity
|
||||
'pos' centre position of explosion
|
||||
'radius' radius of explosion (typically set to 3)
|
||||
|
||||
|
||||
mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith)
|
||||
|
||||
This function is generally called inside the on_rightclick section of the mob api code, it provides a chance of capturing the mob by hand, using the net or magic lasso items, and can also have the player take the mob by force if tamed and replace with another item entirely.
|
||||
|
||||
'self' mob information
|
||||
'clicker' player information
|
||||
'chance_hand' chance of capturing mob by hand (1 to 100) 0 to disable
|
||||
'chance_net' chance of capturing mob using net (1 to 100) 0 to disable
|
||||
'chance_lasso' chance of capturing mob using magic lasso (1 to 100) 0 to disable
|
||||
'force_take' take mob by force, even if tamed (true or false)
|
||||
'replacewith' once captured replace mob with this item instead (overrides new mob eggs with saved information)
|
||||
|
||||
|
||||
mobs:feed_tame(self, clicker, feed_count, breed, tame)
|
||||
|
||||
This function allows the mob to be fed the item inside self.follow be it apple, wheat or whatever a set number of times and be tamed or bred as a result. Will return true when mob is fed with item it likes.
|
||||
|
||||
'self' mob information
|
||||
'clicker' player information
|
||||
'feed_count' number of times mob must be fed to tame or breed
|
||||
'breed' true or false stating if mob can be bred and a child created afterwards
|
||||
'tame' true or false stating if mob can be tamed so player can pick them up
|
||||
|
||||
|
||||
mobs:protect(self, clicker)
|
||||
|
||||
This function can be used to right-click any tamed mob with mobs:protector item, this will protect the mob from harm inside of a protected area from other players. Will return true when mob right-clicked with mobs:protector item.
|
||||
|
||||
'self' mob information
|
||||
'clicker' player information
|
||||
|
||||
|
||||
Mobs can now be ridden by players and the following shows the functions and usage:
|
||||
|
||||
|
||||
mobs:attach(self, player)
|
||||
|
||||
This function attaches a player to the mob so it can be ridden.
|
||||
|
||||
'self' mob information
|
||||
'player' player information
|
||||
|
||||
|
||||
mobs:detach(player, offset)
|
||||
|
||||
This function will detach the player currently riding a mob to an offset position.
|
||||
|
||||
'player' player information
|
||||
'offset' position table containing offset values
|
||||
|
||||
|
||||
mobs:drive(self, move_animation, stand_animation, can_fly, dtime)
|
||||
|
||||
This function allows an attached player to move the mob around and animate it at same time.
|
||||
|
||||
'self' mob information
|
||||
'move_animation' string containing movement animation e.g. "walk"
|
||||
'stand_animation' string containing standing animation e.g. "stand"
|
||||
'can_fly' if true then jump and sneak controls will allow mob to fly up and down
|
||||
'dtime' tick time used inside drive function
|
||||
|
||||
|
||||
mobs:fly(self, dtime, speed, can_shoot, arrow_entity, move_animation, stand_animation)
|
||||
|
||||
This function allows an attached player to fly the mob around using directional controls.
|
||||
|
||||
'self' mob information
|
||||
'dtime' tick time used inside fly function
|
||||
'speed' speed of flight
|
||||
'can_shoot' true if mob can fire arrow (sneak and left mouse button fires)
|
||||
'arrow_entity' name of arrow entity used for firing
|
||||
'move_animation' string containing name of pre-defined animation e.g. "walk" or "fly" etc.
|
||||
'stand_animation' string containing name of pre-defined animation e.g. "stand" or "blink" etc.
|
||||
|
||||
Note: animation names above are from the pre-defined animation lists inside mob registry without extensions.
|
||||
|
||||
|
||||
mobs:set_animation(self, name)
|
||||
|
||||
This function sets the current animation for mob, defaulting to "stand" if not found.
|
||||
|
||||
'self' mob information
|
||||
'name' name of animation
|
||||
|
||||
|
||||
Certain variables need to be set before using the above functions:
|
||||
|
||||
'self.v2' toggle switch used to define below values for the first time
|
||||
'self.max_speed_forward' max speed mob can move forward
|
||||
'self.max_speed_reverse' max speed mob can move backwards
|
||||
'self.accel' acceleration speed
|
||||
'self.terrain_type' integer containing terrain mob can walk on (1 = water, 2 or 3 = land)
|
||||
'self.driver_attach_at' position offset for attaching player to mob
|
||||
'self.driver_eye_offset' position offset for attached player view
|
||||
'self.driver_scale' sets driver scale for mobs larger than {x=1, y=1}
|
||||
|
||||
|
||||
Here is an example mob to show how the above functions work:
|
||||
|
||||
|
||||
-- rideable horse
|
||||
mobs:register_mob("mob_horse:horse", {
|
||||
type = "animal",
|
||||
visual = "mesh",
|
||||
visual_size = {x = 1.20, y = 1.20},
|
||||
mesh = "mobs_horse.x",
|
||||
collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.25, 0.4},
|
||||
animation = {
|
||||
speed_normal = 15,
|
||||
speed_run = 30,
|
||||
stand_start = 25,
|
||||
stand_end = 75,
|
||||
walk_start = 75,
|
||||
walk_end = 100,
|
||||
run_start = 75,
|
||||
run_end = 100,
|
||||
},
|
||||
textures = {
|
||||
{"mobs_horse.png"},
|
||||
{"mobs_horsepeg.png"},
|
||||
{"mobs_horseara.png"}
|
||||
},
|
||||
fear_height = 3,
|
||||
runaway = true,
|
||||
fly = false,
|
||||
walk_chance = 60,
|
||||
view_range = 5,
|
||||
follow = {"farming:wheat"},
|
||||
passive = true,
|
||||
hp_min = 12,
|
||||
hp_max = 16,
|
||||
armor = 200,
|
||||
lava_damage = 5,
|
||||
fall_damage = 5,
|
||||
water_damage = 1,
|
||||
makes_footstep_sound = true,
|
||||
drops = {
|
||||
{name = "mobs:meat_raw", chance = 1, min = 2, max = 3}
|
||||
},
|
||||
|
||||
do_custom = function(self, dtime)
|
||||
|
||||
-- set needed values if not already present
|
||||
if not self.v2 then
|
||||
self.v2 = 0
|
||||
self.max_speed_forward = 6
|
||||
self.max_speed_reverse = 2
|
||||
self.accel = 6
|
||||
self.terrain_type = 3
|
||||
self.driver_attach_at = {x = 0, y = 20, z = -2}
|
||||
self.driver_eye_offset = {x = 0, y = 3, z = 0}
|
||||
self.driver_scale = {x = 1, y = 1}
|
||||
end
|
||||
|
||||
-- if driver present allow control of horse
|
||||
if self.driver then
|
||||
|
||||
mobs.drive(self, "walk", "stand", false, dtime)
|
||||
|
||||
return false -- skip rest of mob functions
|
||||
end
|
||||
|
||||
return true
|
||||
end,
|
||||
|
||||
on_die = function(self, pos)
|
||||
|
||||
-- drop saddle when horse is killed while riding
|
||||
-- also detach from horse properly
|
||||
if self.driver then
|
||||
minetest.add_item(pos, "mobs:saddle")
|
||||
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
|
||||
end
|
||||
|
||||
end,
|
||||
|
||||
on_rightclick = function(self, clicker)
|
||||
|
||||
-- make sure player is clicking
|
||||
if not clicker or not clicker:is_player() then
|
||||
return
|
||||
end
|
||||
|
||||
-- feed, tame or heal horse
|
||||
if mobs:feed_tame(self, clicker, 10, true, true) then
|
||||
return
|
||||
end
|
||||
|
||||
-- make sure tamed horse is being clicked by owner only
|
||||
if self.tamed and self.owner == clicker:get_player_name() then
|
||||
|
||||
local inv = clicker:get_inventory()
|
||||
|
||||
-- detatch player already riding horse
|
||||
if self.driver and clicker == self.driver then
|
||||
|
||||
mobs.detach(clicker, {x = 1, y = 0, z = 1})
|
||||
|
||||
-- add saddle back to inventory
|
||||
if inv:room_for_item("main", "mobs:saddle") then
|
||||
inv:add_item("main", "mobs:saddle")
|
||||
else
|
||||
minetest.add_item(clicker.getpos(), "mobs:saddle")
|
||||
end
|
||||
|
||||
-- attach player to horse
|
||||
elseif not self.driver
|
||||
and clicker:get_wielded_item():get_name() == "mobs:saddle" then
|
||||
|
||||
self.object:set_properties({stepheight = 1.1})
|
||||
mobs.attach(self, clicker)
|
||||
|
||||
-- take saddle from inventory
|
||||
inv:remove_item("main", "mobs:saddle")
|
||||
end
|
||||
end
|
||||
|
||||
-- used to capture horse with magic lasso
|
||||
mobs:capture_mob(self, clicker, 0, 0, 80, false, nil)
|
||||
end
|
||||
})
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
local S = mobs.intllib
|
||||
|
||||
-- name tag
|
||||
minetest.register_craftitem("mobs:nametag", {
|
||||
description = S("Name Tag"),
|
||||
_doc_items_longdesc = S("A name tag is an item to name most animals and monsters."),
|
||||
_doc_items_usagehelp = S("Rightclick an animal or monster while holding the name tag, then enter a name."),
|
||||
inventory_image = "mobs_nametag.png",
|
||||
wield_image = "mobs_nametag.png",
|
||||
stack_max = 64,
|
||||
groups = { tool=1 },
|
||||
})
|
||||
|
|
@ -1,9 +1,6 @@
|
|||
mcl_core
|
||||
mcl_weather?
|
||||
mcl_tnt?
|
||||
mcl_hunger?
|
||||
invisibility?
|
||||
intllib?
|
||||
lucky_block?
|
||||
cmi?
|
||||
doc_identifier?
|
|
@ -0,0 +1 @@
|
|||
Adds a mob api for mods to add animals or monsters etc.
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
local path = minetest.get_modpath("mobs")
|
||||
|
||||
-- Mob API
|
||||
dofile(path .. "/api.lua")
|
||||
|
||||
-- Rideable Mobs
|
||||
dofile(path .. "/mount.lua")
|
||||
|
||||
-- Mob Items
|
||||
dofile(path .. "/crafts.lua")
|
||||
|
||||
-- Mob Spawner
|
||||
-- MCL2 has its own spawners in mcl_mobspawners
|
||||
|
||||
-- Lucky Blocks
|
||||
dofile(path .. "/lucky_block.lua")
|
||||
|
||||
minetest.log("action", "[MOD] Mobs Redo loaded")
|
|
@ -18,10 +18,6 @@ msgstr ""
|
|||
"X-Generator: Poedit 2.0.2\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: api.lua
|
||||
msgid "** Peaceful Mode Active - No Monsters Will Spawn"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "Mob has been protected!"
|
||||
msgstr "Kreatur wurde geschützt!"
|
||||
|
@ -46,6 +42,10 @@ msgstr "Daneben!"
|
|||
msgid "Already protected!"
|
||||
msgstr "Bereits geschützt!"
|
||||
|
||||
#: api.lua
|
||||
msgid "Protected!"
|
||||
msgstr "Geschützt!"
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 at full health (@2)"
|
||||
msgstr "@1 bei voller Gesundheit (@2)"
|
||||
|
@ -98,10 +98,6 @@ msgstr "Kreaturschutzrune"
|
|||
msgid "Saddle"
|
||||
msgstr "Sattel"
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Fence"
|
||||
msgstr "Kreaturen Zaun"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner"
|
||||
msgstr "Kreaturenspawner"
|
||||
|
@ -128,4 +124,4 @@ msgid ""
|
|||
"distance[1-20] y_offset[-10 to 10]”"
|
||||
msgstr ""
|
||||
"Syntax: „name min_licht[0-14] max_licht[0-14] max_mobs_im_gebiet[0 zum "
|
||||
"Deaktivieren] distanz[1-20] y_versatz[-10 bis 10]“"
|
||||
"Deaktivieren] distanz[1-20] y_versatz[-10 bis 10]“"
|
|
@ -18,10 +18,6 @@ msgstr ""
|
|||
"X-Generator: Poedit 2.0.2\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: api.lua
|
||||
msgid "** Peaceful Mode Active - No Monsters Will Spawn"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "Mob has been protected!"
|
||||
msgstr ""
|
||||
|
@ -46,6 +42,10 @@ msgstr "Faltou!"
|
|||
msgid "Already protected!"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "Protected!"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 at full health (@2)"
|
||||
msgstr "@1 em plena saude (@2)"
|
||||
|
@ -99,10 +99,6 @@ msgstr ""
|
|||
msgid "Saddle"
|
||||
msgstr ""
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Fence"
|
||||
msgstr ""
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner"
|
||||
msgstr "Spawnador de Mob"
|
||||
|
@ -130,4 +126,4 @@ msgid ""
|
|||
"distance[1-20] y_offset[-10 to 10]”"
|
||||
msgstr ""
|
||||
"> nome luz_min[0-14] luz_max[0-14] max_mobs_na_area[0 para desabilitar] "
|
||||
"distancia[1-20] y_offset[-10 a 10]"
|
||||
"distancia[1-20] y_offset[-10 a 10]"
|
|
@ -17,10 +17,6 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: api.lua
|
||||
msgid "** Peaceful Mode Active - No Monsters Will Spawn"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "Mob has been protected!"
|
||||
msgstr ""
|
||||
|
@ -45,6 +41,10 @@ msgstr ""
|
|||
msgid "Already protected!"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "Protected!"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 at full health (@2)"
|
||||
msgstr ""
|
||||
|
@ -97,10 +97,6 @@ msgstr ""
|
|||
msgid "Saddle"
|
||||
msgstr ""
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Fence"
|
||||
msgstr ""
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner"
|
||||
msgstr ""
|
||||
|
@ -125,4 +121,4 @@ msgstr ""
|
|||
msgid ""
|
||||
"Syntax: “name min_light[0-14] max_light[0-14] max_mobs_in_area[0 to disable] "
|
||||
"distance[1-20] y_offset[-10 to 10]”"
|
||||
msgstr ""
|
||||
msgstr ""
|
|
@ -18,10 +18,6 @@ msgstr ""
|
|||
"X-Generator: Poedit 2.0.2\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: api.lua
|
||||
msgid "** Peaceful Mode Active - No Monsters Will Spawn"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "Mob has been protected!"
|
||||
msgstr ""
|
||||
|
@ -46,6 +42,10 @@ msgstr "Kaçırdın!"
|
|||
msgid "Already protected!"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "Protected!"
|
||||
msgstr ""
|
||||
|
||||
#: api.lua
|
||||
msgid "@1 at full health (@2)"
|
||||
msgstr "@1 tam canında (@2)"
|
||||
|
@ -99,10 +99,6 @@ msgstr ""
|
|||
msgid "Saddle"
|
||||
msgstr ""
|
||||
|
||||
#: crafts.lua
|
||||
msgid "Mob Fence"
|
||||
msgstr "Canavar Yaratıcı"
|
||||
|
||||
#: spawner.lua
|
||||
msgid "Mob Spawner"
|
||||
msgstr "Canavar Yaratıcı"
|
||||
|
@ -130,4 +126,4 @@ msgid ""
|
|||
"distance[1-20] y_offset[-10 to 10]”"
|
||||
msgstr ""
|
||||
"> isim min_isik[0-14] max_isik[0-14] alandaki_max_canavar_sayisi[kapatmak "
|
||||
"icin 0] mesafe[1-20] y_cikinti[-10 ve 10 arası]"
|
||||
"icin 0] mesafe[1-20] y_cikinti[-10 ve 10 arası]"
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
if minetest.get_modpath("lucky_block") then
|
||||
|
||||
lucky_block:add_blocks({
|
||||
{"dro", {"mobs:meat_raw"}, 5},
|
||||
{"dro", {"mobs:meat"}, 5},
|
||||
{"dro", {"mobs:nametag"}, 1},
|
||||
{"dro", {"mobs:leather"}, 5},
|
||||
{"dro", {"mobs:net"}, 1},
|
||||
{"dro", {"mobs:magic_lasso"}, 1},
|
||||
{"dro", {"mobs:shears"}, 1},
|
||||
{"dro", {"mobs:protector"}, 1},
|
||||
{"lig"},
|
||||
})
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
name = mobs
|
|
@ -151,14 +151,12 @@ function mobs.attach(entity, player)
|
|||
}
|
||||
})
|
||||
|
||||
minetest.after(0.2, function(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
mcl_player.player_set_animation(player, "sit" , 30)
|
||||
end
|
||||
end, player:get_player_name())
|
||||
minetest.after(0.2, function()
|
||||
mcl_player.player_set_animation(player, "sit" , 30)
|
||||
end)
|
||||
|
||||
player:set_look_horizontal(entity.object:get_yaw() - rot_view)
|
||||
--player:set_look_yaw(entity.object:getyaw() - rot_view)
|
||||
player:set_look_horizontal(entity.object:getyaw() - rot_view)
|
||||
end
|
||||
|
||||
|
||||
|
@ -168,16 +166,13 @@ function mobs.detach(player, offset)
|
|||
|
||||
mcl_player.player_set_animation(player, "stand" , 30)
|
||||
|
||||
local pos = player:get_pos()
|
||||
local pos = player:getpos()
|
||||
|
||||
pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z}
|
||||
|
||||
minetest.after(0.1, function(name, pos)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
player:set_pos(pos)
|
||||
end
|
||||
end, player:get_player_name(), pos)
|
||||
minetest.after(0.1, function()
|
||||
player:setpos(pos)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
|
@ -190,13 +185,15 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
end
|
||||
|
||||
local acce_y = 0
|
||||
local velo = entity.object:get_velocity()
|
||||
local velo = entity.object:getvelocity()
|
||||
|
||||
entity.v = get_v(velo) * get_sign(entity.v)
|
||||
|
||||
-- process controls
|
||||
if entity.driver then
|
||||
|
||||
--print ("---velo", get_v(velo))
|
||||
|
||||
local ctrl = entity.driver:get_player_control()
|
||||
|
||||
-- move forwards
|
||||
|
@ -215,7 +212,8 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
end
|
||||
|
||||
-- fix mob rotation
|
||||
entity.object:set_yaw(entity.driver:get_look_horizontal() - entity.rotate)
|
||||
-- entity.object:setyaw(entity.driver:get_look_yaw() - entity.rotate)
|
||||
entity.object:setyaw(entity.driver:get_look_horizontal() - entity.rotate)
|
||||
|
||||
if can_fly then
|
||||
|
||||
|
@ -275,7 +273,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
|
||||
if s ~= get_sign(entity.v) then
|
||||
|
||||
entity.object:set_velocity({x = 0, y = 0, z = 0})
|
||||
entity.object:setvelocity({x = 0, y = 0, z = 0})
|
||||
entity.v = 0
|
||||
return
|
||||
end
|
||||
|
@ -292,7 +290,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
end
|
||||
|
||||
-- Set position, velocity and acceleration
|
||||
local p = entity.object:get_pos()
|
||||
local p = entity.object:getpos()
|
||||
local new_velo = {x = 0, y = 0, z = 0}
|
||||
local new_acce = {x = 0, y = -9.8, z = 0}
|
||||
|
||||
|
@ -346,9 +344,9 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
end
|
||||
else
|
||||
if math.abs(velo.y) < 1 then
|
||||
local pos = entity.object:get_pos()
|
||||
local pos = entity.object:getpos()
|
||||
pos.y = math.floor(pos.y) + 0.5
|
||||
entity.object:set_pos(pos)
|
||||
entity.object:setpos(pos)
|
||||
velo.y = 0
|
||||
end
|
||||
end
|
||||
|
@ -357,11 +355,11 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
end
|
||||
end
|
||||
|
||||
new_velo = get_velocity(v, entity.object:get_yaw() - rot_view, velo.y)
|
||||
new_velo = get_velocity(v, entity.object:getyaw() - rot_view, velo.y)
|
||||
new_acce.y = new_acce.y + acce_y
|
||||
|
||||
entity.object:set_velocity(new_velo)
|
||||
entity.object:set_acceleration(new_acce)
|
||||
entity.object:setvelocity(new_velo)
|
||||
entity.object:setacceleration(new_acce)
|
||||
|
||||
-- CRASH!
|
||||
if enable_crash then
|
||||
|
@ -370,6 +368,8 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|||
|
||||
if intensity >= crash_threshold then
|
||||
|
||||
--print("----------- crash", intensity)
|
||||
|
||||
entity.object:punch(entity.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = intensity}
|
||||
|
@ -387,8 +387,9 @@ end
|
|||
function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
||||
|
||||
local ctrl = entity.driver:get_player_control()
|
||||
local velo = entity.object:get_velocity()
|
||||
local velo = entity.object:getvelocity()
|
||||
local dir = entity.driver:get_look_dir()
|
||||
-- local yaw = entity.driver:get_look_yaw()
|
||||
local yaw = entity.driver:get_look_horizontal() + 1.57 -- offset fix between old and new commands
|
||||
local rot_steer, rot_view = math.pi / 2, 0
|
||||
|
||||
|
@ -397,29 +398,29 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
|||
end
|
||||
|
||||
if ctrl.up then
|
||||
entity.object:set_velocity({
|
||||
entity.object:setvelocity({
|
||||
x = dir.x * speed,
|
||||
y = dir.y * speed + 2,
|
||||
z = dir.z * speed
|
||||
})
|
||||
|
||||
elseif ctrl.down then
|
||||
entity.object:set_velocity({
|
||||
entity.object:setvelocity({
|
||||
x = -dir.x * speed,
|
||||
y = dir.y * speed + 2,
|
||||
z = -dir.z * speed
|
||||
})
|
||||
|
||||
elseif not ctrl.down or ctrl.up or ctrl.jump then
|
||||
entity.object:set_velocity({x = 0, y = -2, z = 0})
|
||||
entity.object:setvelocity({x = 0, y = -2, z = 0})
|
||||
end
|
||||
|
||||
entity.object:set_yaw(yaw + math.pi + math.pi / 2 - entity.rotate)
|
||||
entity.object:setyaw(yaw + math.pi + math.pi / 2 - entity.rotate)
|
||||
|
||||
-- firing arrows
|
||||
if ctrl.LMB and ctrl.sneak and shoots then
|
||||
|
||||
local pos = entity.object:get_pos()
|
||||
local pos = entity.object:getpos()
|
||||
local obj = minetest.add_entity({
|
||||
x = pos.x + 0 + dir.x * 2.5,
|
||||
y = pos.y + 1.5 + dir.y,
|
||||
|
@ -430,9 +431,10 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
|||
ent.switch = 1 -- for mob specific arrows
|
||||
ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding
|
||||
local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6}
|
||||
-- local yaw = entity.driver:get_look_yaw()
|
||||
local yaw = entity.driver:get_look_horizontal()
|
||||
obj:set_yaw(yaw + math.pi / 2)
|
||||
obj:set_velocity(vec)
|
||||
obj:setyaw(yaw + math.pi / 2)
|
||||
obj:setvelocity(vec)
|
||||
else
|
||||
obj:remove()
|
||||
end
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
Mobs Redo: MineClone 2 Edition
|
||||
MOBS REDO for MINETEST
|
||||
|
||||
Based on Mobs Redo from TenPlus1
|
||||
Built from PilzAdam's original Simple Mobs with additional mobs by KrupnoPavel, Zeg9, ExeterDad and AspireMint.
|
||||
|
||||
|
||||
|
@ -11,18 +10,18 @@ This mod contains the API only for adding your own mobs into the world, so pleas
|
|||
https://forum.minetest.net/viewtopic.php?f=11&t=9917
|
||||
|
||||
|
||||
Items:
|
||||
Crafts:
|
||||
|
||||
- Nametag (paper, black dye, string) can be used right-click on a tamed mob to give them a name.
|
||||
- Nametag (paper, black dye, string) can be used right-click on a tamed mob to give them a name.
|
||||
- Nets can be used to right-click tamed mobs to pick them up and place inside inventory as a spawn egg.
|
||||
- Magic Lasso is similar to nets but with a better chance of picking up larger mobs.
|
||||
- Shears are used to right-click sheep and return 1-3 wool.
|
||||
- Protection Rune lets you protect tamed mobs from harm by other players
|
||||
|
||||
Lucky Block items: 1
|
||||
Lucky Blocks: 9
|
||||
|
||||
|
||||
Changelog from original Mobs Redo mod:
|
||||
- 1.41- Mob pathfinding has been updated thanks to Elkien3
|
||||
- 1.40- Updated to use newer functions, requires Minetest 0.4.16+ to work.
|
||||
- 1.39- Added 'on_breed', 'on_grown' and 'do_punch' custom functions per mob
|
||||
- 1.38- Better entity checking, nametag setting and on_spawn function added to mob registry, tweaked light damage
|
||||
Changelog:
|
||||
- 1.37- Added support for Raymoo's CMI (common mob interface) mod: https://forum.minetest.net/viewtopic.php?f=9&t=15448
|
||||
- 1.36- Death check added, if mob dies in fire/lava/with lava pick then drops are cooked
|
||||
- 1.35- Added owner_loyal flag for owned mobs to attack player enemies, also fixed group_attack
|