Compare commits

..

1 Commits

Author SHA1 Message Date
MysticTempest 3e5dfcc957 Implement slimeblock piston launchers:
Adds the mechanic of launching entities standing on, or in
front of slimeblocks; which are attached to, and pushed by pistons.

I've also updated the rules regarding pushing, and pulling
of nodes & objects. So, that more complex circuits can be built.

This enables the feature of some nodes being unpullable, but
otherwise pushable or diggable.
A certain selection of nodes that can never be moved.
And, stops certain entities from being pushed if they shouldn't move.
2022-05-10 16:41:32 -05:00
1515 changed files with 13164 additions and 33668 deletions

2
API.md
View File

@ -42,7 +42,7 @@ A lot of things are possible by using one of the APIs in the mods. Note that not
* Buckets: `ITEMS/mcl_buckets`
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
### Mobs
## Mobs
* Mobs: `ENTITIES/mcl_mobs`
MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short.

View File

@ -2,7 +2,7 @@
So you want to contribute to MineClone2?
Wow, thank you! :-)
MineClone2 is maintained by Nicu and Cora. If you have any
MineClone2 is maintained by Nicu and Fleckenstein. If you have any
problems or questions, contact us (See Links section below).
You can help with MineClone2's development in many different ways,
@ -11,9 +11,18 @@ whether you're a programmer or not.
## MineClone2's development target is to...
- Crucially, create a stable, moddable, free/libre clone of Minecraft
based on the Minetest engine with polished features, usable in both
singleplayer and multiplayer. Currently, a lot of Minecraft features
are already implemented.
Polishing existing features is always welcome.
singleplayer and multiplayer. Currently, most of **Minecraft Java
Edition 1.12.2** features are already implemented and polishing existing
features are prioritized over new feature requests.
- With lessened priority yet strictly, implement features targetting
**Minecraft version 1.17 + OptiFine** (OptiFine only as far as supported
by the Minetest Engine). This means features in parity with the listed
Minecraft experiences are prioritized over those that don't fulfill this
scope.
- Optionally, create a performant experience that will run relatively
well on really low spec computers. Unfortunately, due to Minecraft's
mechanisms and Minetest engine's limitations along with a very small
playerbase on low spec computers, optimizations are hard to investigate.
## Links
* [Mesehub](https://git.minetest.land/MineClone2/MineClone2)
@ -36,10 +45,8 @@ referenced frequently because of its usefulness. As such, it is valuable
in learning how git works and its terminology. It can also help you
keeping your game updated, and easily test pull requests.
Look at our wiki for some concrete guides:
https://git.minetest.land/MineClone2/MineClone2/wiki/
## How you can help as a non-programmer
As someone who does not know how to write programs in Lua or does not
know how to use the Minetest API, you can still help us out a lot. For
example, by opening an issue in the
@ -51,10 +58,12 @@ you can report a bug or request a feature.
discussion.
* Choose a descriptive title (e.g. not just "crash", "bug" or "question"
).
* Please write in plain, understandable English. It will be easier to
communicate.
* Please start the issue title with a capital letter.
* Always check the currently opened issues before creating a new one.
Try not to report bugs that have already been reported or request features
that already have been requested. This can often be ambiguous though.
If in doubt open an issue!
Don't report bugs that have already been reported or request features
that already have been requested.
* If you know about Minetest's inner workings, please think about
whether the bug / the feature that you are reporting / requesting is
actually an issue with Minetest itself, and if it is, head to the
@ -64,9 +73,6 @@ instead.
an issue, feel free to ask on the Discord / Matrix server or the IRC
channel.
The link to the mesehub registration page is: https://git.minetest.land/user/sign_up
(It appears to sometimes get lost on the page itsself)
### Reporting bugs
* A bug is an unintended behavior or, in the worst case, a crash.
However, it is not a bug if you believe something is missing in the
@ -105,28 +111,23 @@ would report issues will pull requests similar to when you were
reporting bugs that are the mainline (See Reporting bugs section). You
can find currently open pull requests here:
<https://git.minetest.land/MineClone2/MineClone2/pulls>. Note that pull
requests that start with a `WIP:` are not done yet and therefore could
still undergo substantial change. Testing these is still helpful however
because that is the reason developers put them up as WIP so other people
can have a look at the PR.
requests that start with a `WIP:` are not done yet, and therefore might
not work, so it's not very useful to try them out yet.
### Contributing assets
Due to license problems, MineClone2 cannot use Minecraft's assets,
therefore we are always looking for asset contributions.
To contribute assets, it can be useful to learn git basics and read
the section for Programmers of this document, however this is not required.
It's also a good idea to join the Discord server
Due to license problems, MineClone2 unfortunately cannot use
Minecraft's assets, therefore we are always looking for asset
contributions. To contribute assets, it can be useful to learn git
basics and read the section for Programmers of this document, however
this is not required. It's also a good idea to join the Discord server
(or alternatively IRC or Matrix).
#### Textures
For textures we use the Pixel Perfection texture pack. For older Minecraft
features that is mostly enough but a lot of the newer textures in it are
copies or slight modifications of the original MC textures so great caution
needs to be taken when using any textures coming from Minecraft texture
packs.
If you want to make such contributions, join our Discord server. Demands
for textures will be communicated there.
For textures we use the Pixel Perfection texture pack. This is mostly
enough; however in some cases - e.g. for newer Minecraft features, it's
useful to have texture artists around. If you want to make such
contributions, join our Discord server. Demands for textures will be
communicated there.
#### Sounds
MineClone2 currently does not have a consistent way to handle sounds.
@ -250,25 +251,16 @@ of the results)
* [Official Minecraft Wiki](https://minecraft.fandom.com/wiki/Minecraft_Wiki)
(Include a link to the specific page you used)
### Guidelines
### Stick to our guidelines
#### Git Guidelines
* Pushing to master is disabled - don't even try it.
* Every change is tracked as a PR.
* All but the tiniest changes require at least one approval from a Developer
* To update branches we use rebase not merge (so we don't end up with
excessive git bureaucracy commits in master)
* We use merge to add the commits from a PR/branch to master
* Submodules should only be used if a) upstream is highly reliable and
b) it is 100% certain that no mcl2 specific changes to the code will be
needed (this has never been the case before, hence mcl2 is submodule free so far)
* Commit messages should be descriptive and never contain mcl2 specific
issueids - there are other projects who might use commits from mcl2 and
it will confuse their issue trackers.
* Try to group your submissions best as you can:
* Try to keep your PRs small: In some cases things reasonably be can't
split up but in general multiple small PRs are better than a big one.
* Similarly multiple small commits are better than a giant one. (use git commit -p)
* We use merge rather than rebase or squash merge
* We don't use git submodules.
* Your commit names should be relatively descriptive, e.g. when saying
"Fix #issueid", the commit message should also contain the title of the
issue.
* Try to keep your commits as atomic as possible (advise, but completely
optional)
#### Code Guidelines
* Each mod must provide `mod.conf`.
@ -351,23 +343,36 @@ Active and trusted contributors are often granted write access to the
MineClone2 repository.
#### Developer responsibilities
- If you have developer privileges you can just open a new branch in the
mcl2 repository (which is preferred). From that you create a pull request.
This way other people can review your changes and make sure they work
before they get merged.
- If you do not (yet) have developer privs you do your work on a branch
on your private repository e.g. using the "fork" function on mesehub.
- Any developer is welcome to review, test and merge PRs. A PR needs
at least one approval (by someone else than the author) but the maintainers
are usually relatively quick to react to new submissions.
- You should not push things directly to
MineClone2 master - rather, do your work on a branch on your private
repository, then create a pull request. This way other people can review
your changes and make sure they work before they get merged.
- Merge PRs only when they have recieved the necessary feedback and have
been tested by at least two different people (including the author of
the pull request), to avoid crashes or the introduction of new bugs.
- You may also be assigned to issues or pull
requests as a developer. In this case it is your responsibility to fix
the issue / review and merge the pull request when it is ready. You can
also unassign yourself from the issue / PR if you have no time or don't
want to take care of it for some other reason. After all, everyone is a
volunteer and we can't expect you to do work that you are not interested
in. **The important thing is that you make sure to inform us if you
won't take care of something that has been assigned to you.**
- Please assign yourself to something that you want to work on to avoid
duplicate work.
- As a developer, it should be easy to reach you about your work. You
should be in at least one of the public MineClone2 discussion rooms -
preferrably Discord, but if you really don't like Discord, Matrix
or IRC are fine too.
### Maintainer status
Maintainers carry the main responsibility for the project.
#### Maintainer responsibilities
- Making sure issues are addressed and pull requests are reviewed and
merged.
merged, by assigning either themselves or Developers to issues / PRs
- Making releases
- Making sure guidelines are kept
- Making project decisions based on community feedback
- Granting/revoking developer access
- Enforcing the code of conduct (See CODE_OF_CONDUCT.md)
@ -375,8 +380,8 @@ merged.
- Resolving conflicts and problems within the community
#### Current maintainers
* Cora - responsible for gameplay review, publishing releases,
technical guidelines
* Fleckenstein - responsible for gameplay review, publishing releases,
technical guidelines and issue/PR delegation
* Nicu - responsible for community related issues
#### Release process

View File

@ -27,13 +27,6 @@
* Code-Sploit
* NO11
* kabou
* rudzik8
* chmodsayshello
* PrairieWind
* RandomLegoBrick
* SumianVoice
* MrRar
* talamh
## Contributors
* Laurent Rocher
@ -67,6 +60,7 @@
* Benjamin Schötz
* Doloment
* Sydney Gems
* talamh
* Emily2255
* Emojigit
* FinishedFragment
@ -77,18 +71,6 @@
* Sven792
* aldum
* Dieter44
* Pepebotella
* MrRar
* Lazerbeak12345
* mrminer
* Thunder1035
* opfromthestart
* snowyu
* FaceDeer
* Faerraven / Michieal
* FossFanatic
* Herbert West
* GuyLiner
## MineClone5
* kay27
@ -96,12 +78,10 @@
* epCode
* NO11
* j45
* chmodsayshello
* 3raven
* PrairieWind
* Gustavo6046 / wallabra
* PrarieWind
* Gustavo1
* CableGuy67
* MrRar
## Mineclonia
* erlehmann
@ -139,7 +119,6 @@
* 4Evergreen4
* jordan4ibanez
* paramat
* cora
## 3D Models
* 22i
@ -155,9 +134,6 @@
* yutyo
* NO11
* kay27
* MysticTempest
* RandomLegoBrick
* cora
## Translations
* Wuzzy
@ -167,10 +143,6 @@
* pitchum
* todoporlalibertad
* Marcin Serwin
* Pepebotella
* Emojigit
* snowyu
* 3raven
## Funders
* 40W
@ -178,6 +150,5 @@
## Special thanks
* celeron55 for creating Minetest
* Jordach for the jukebox music compilation from Big Freaking Dig
* wsor for working tirelessly in the shadows for the good of all of us, particularly helping with solving contentDB and copyright issues.
* The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game
* Notch and Jeb for being the major forces behind Minecraft

View File

@ -103,7 +103,6 @@ Please read <http://minecraft.gamepedia.com/Breaking> to learn how digging times
* `enchantability=X`: How good the enchantments are the item gets (1 equals book)
* `enchanted=1`: The item is already enchanted, meaning that it can't be enchanted using an enchanting table
* `cobble=1`: Cobblestone of any kind
* `soul_block`: Fire burning on these blocks turns to soul fire, can be used to craft soul torch
### Material groups
@ -205,9 +204,6 @@ These groups are used mostly for informational purposes
* `building_block=1`: Block is a building block
* `deco_block=1`: Block is a decorational block
* `blast_furnace_smeltable=1` : Item or node is smeltable by a blast furnace
* `smoker_cookable=1` : Food is cookable by a smoker.
## Fake item groups
These groups put similar items together which should all be treated by the gameplay or the GUI as a single item.

View File

@ -2,7 +2,7 @@
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
Developed by many people. Not developed or endorsed by Mojang AB.
Version: 0.81 (in development)
Version: 0.75 (in development)
### Gameplay
You start in a randomly-generated world made entirely of cubes. You can explore
@ -91,11 +91,11 @@ The MineClone2 repository is hosted at Mesehub. To contribute or report issues,
## Target
- Crucially, create a stable, moddable, free/libre clone of Minecraft
based on the Minetest engine with polished features, usable in both
singleplayer and multiplayer. Currently, a lot of **Minecraft Java
Edition** features are already implemented and polishing existing
singleplayer and multiplayer. Currently, most of **Minecraft Java
Edition 1.12.2** features are already implemented and polishing existing
features are prioritized over new feature requests.
- With lessened priority yet strictly, implement features targetting
**Current Minecraft versions + OptiFine** (OptiFine only as far as supported
**Minecraft version 1.17 + OptiFine** (OptiFine only as far as supported
by the Minetest Engine). This means features in parity with the listed
Minecraft experiences are prioritized over those that don't fulfill this
scope.
@ -108,7 +108,8 @@ playerbase on low spec computers, optimizations are hard to investigate.
This game is currently in **beta** stage.
It is playable, but not yet feature-complete.
Backwards-compability is not entirely guaranteed, updating your world might cause small bugs.
If you want to use the development version of MineClone2 in production, the master branch is usually relatively stable. The testing branch often features some experimental PRs and should be considered less stable.
If you want to use the git version of MineClone2 in production, consider using the production branch.
It is updated weekly and contains relatively stable code for servers.
The following main features are available:
@ -123,7 +124,7 @@ The following main features are available:
* Most blocks in the overworld
* Water and lava
* Weather
* 28 biomes + 5 Nether Biomes
* 28 biomes
* The Nether, a fiery underworld in another dimension
* Redstone circuits (partially)
* Minecarts (partial)
@ -161,7 +162,7 @@ The following features are incomplete:
* Special minecarts
* A couple of non-trivial blocks and items
Bonus features (not found in Minecraft):
Bonus features (not found in Minecraft 1.12):
* 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
@ -174,9 +175,6 @@ Bonus features (not found in Minecraft):
* Nether Brick Fence Gate
* Red Nether Brick Fence
* Red Nether Brick Fence Gate
* Structure replacements - these small variants of Minecraft structures serve as replacements until we can get large structures working:
* Woodland Cabin (Mansions)
* Nether Outpost (Fortress)
Technical differences from Minecraft:

View File

@ -1,170 +0,0 @@
# MineClone2
Un jeu non-officiel similaire à Minecraft pour Minetest. Forké depuis Mineclone par davedevils. Développé par de nombreuses personnes. Ni développé ou supporté par Mojang AB.
Version: 0.79 (en dévelopment)
### Gameplay
Vous atterissez dans un monde fait entièrement de cubes et généré aléatoirement. Vous pouvez explorer le monde, miner et construire presque n'importe quel bloc pour créer de nouvelles structures. Vous pouvez choisir de jouer en "mode survie" dans lequel vous devez combattre des monstres et la faim et progresser lentement dans différents aspects du jeu, comme l'extraction de minerai, l'agriculture, la construction de machines et ainsi de suite. Ou alors vous pouvez jouer en "mode créatif" où vous pouvez construire à peu près n'importe quoi instantanément.
### Résumé du Gameplay
* Jeu de type bac-à-sable, sans objetifs
* Survie : combattre des monstres hostiles et la faim
* Creuser pour du minerai et d'autres trésors
* Magie : gagner de l'expérience et enchanter les outils
* Utiliser les blocs ramassés pour construire de magnifiques bâtiments, votre imagination est la limite
* Ramasser des fleurs (et d'autres sources de teinture) et colorez votre monde
* Trouvez des graines et commencez à cultiver
* Trouvez ou fabriquez des centaines d'objets
* Construisez un réseau ferroviaire complexe et amusez vous avec les wagonnets
* En mode créatif vous pouvez construire presque n'importe quoi gratuitement et sans limite
## Comment jouer (démarrer rapidement)
### Commencer
* **Frappez un arbre** jusqu'à ce qu'il casse et donne du bois
* Placez le **bois dans la grille 2x2** (la "grille de fabrication" de votre menu d'inventaire) et fabriquez 4 planches de bois
* Placer les 4 planches de bois dans la grille 2x2 et **fabriquez une table d'artisanat**
* **Cliquez droit la table d'artisanat** (icone livre) pour apprendre toutes les recettes possibles
* **Fabriquez une pioche de bois** pour miner la pierre
* Différents outils minent différentes sortes de blocs. Essayez les !
* Continuez à jouer comme vous voulez. Amusez vous !
### Agriculture
* Trouvez des graines
* Fabriquez une houe
* Cliquez droit la terre ou des blocs similaires avec la houe pour créer des terres agricoles
* Placer des graines sur des terres agricoles et regardez les pousser
* Récoltez les plantes une fois matûres
* Les terres agricoles proche de l'eau deviennent humides et accélèrent la croissance
### Four
* Fabriquer un Four
* Le four permet d'obtenir plus d'objets
* L'emplacement du haut doit contienir un objet fondable (par ex : minerai de fer)
* L'emplacement du bas doit contienir un objet combustible (par ex : charbon)
* Voir le guide d'artisanat pour en apprendre plus sur les objets fondables et combustibles
### Aide supplémentaire
Plus d'aide à propos du jeu, des blocs, objets et plus encore peuvent être trouvés dans le jeu. Vous pouvez accéder à l'aide depuis le menu inventaire.
### Objets spéciaux
Les objets suivants sont intéressants pour le mode Créatif et pour les constructeurs de cartes d'aventure. Ils ne peuvent être obtenus dans le jeu ou dans l'inventaire créatif.
* Barrière : `mcl_core:barrier`
Utilisez la commande de chat `/giveme` pour les obtenir. Voir l'aide interne au jeu pour une explication.
## Installation
Ce jeu nécessite [Minetest](http://minetest.net) pour fonctionner (version 5.4.1 ou plus). Vous devez donc installer Minetest d'abord. Seules les versions stables de Minetest sont officielement supportées.
Il n'y a pas de support de MineClone2 dans les versions développement de Minetest.
Pour installer MineClone2 (si ce n'est pas déjà fait), déplacez ce dossier dans le dossier “games” de Minetest. Consultez l'aide de Minetest pour en apprendre plus.
## Liens utiles
Le dépôt de MineClone2 est hébergé sur Mesehub. Pour contribuer ou rapporter des problèmes, aller là-bas.
* Mesehub: <https://git.minetest.land/MineClone2/MineClone2>
* Discord: <https://discord.gg/xE4z8EEpDC>
* YouTube <https://www.youtube.com/channel/UClI_YcsXMF3KNeJtoBfnk9A>
* IRC: <https://web.libera.chat/#mineclone2>
* Matrix: <https://app.element.io/#/room/#mc2:matrix.org>
* Reddit: <https://www.reddit.com/r/MineClone2/>
* Minetest forums: <https://forum.minetest.net/viewtopic.php?f=50&t=16407>
* ContentDB: <https://content.minetest.net/packages/wuzzy/mineclone2/>
* OpenCollective: <https://opencollective.com/mineclone2>
## Objectif
* Créer un clone stable, moddable, libre et gratuit basé sur le moteur de jeu Minetest avec des fonctionalités abouties, utilisable à la fois en mode solo et multijoueur. Actuellement, beaucoup des fonctionalités de **Minecraft Java Edition** sont déjà implémentées et leur amélioration est prioritaire sur les nouvelles demandes.
* Avec une priorité moindre, implémenter les fonctionalités des versions **Minecraft + OptiFine** (OtiFine autant que supporté par le moteur Minetest). Cela signifie que les fonctionalités présentes dans les versions listées sont priorisées.
* Dans l'idéal, créer une expérience performante qui tourne bien sur des ordinateurs à basse performance. Malheureusement, en raison des mécanismes de Minecraft et des limitations du moteur Minetest ainsi que de la petite taille de la communauté de joueurs sur des ordinateurs à basse performances, les optimisations sont difficiles à explorer.
## Statut de complétion
Ce jeu est actuellement au stade **beta**.
Il est jouable mais incomplet en fonctionalités.
La rétro-compatibilité n'est pas entièrement garantie, mettre votre monde à jour peut causer de petits bugs.
Si vous voulez utiliser la version de développement de MineClone2 en production, la branche master est habituellement relativement stable. Les branches de test fusionnent souvent des pull requests expérimentales et doivent être considérées comme moins stable.
Les principales fonctionalités suivantes sont disponibles :
* Outils, armes
* Armure
* Système de fabrication : grille 2x2, table d'artisanat (grille 3x3), four, incluant un guide de fabrication
* Coffres, grands coffres, coffre ender, boite de shulker
* Fours, entonnoirs
* Faim
* La plupart des monstres et animaux
* Tout les minerais de Minecraft
* La plupart des blocs de l'overworld
* Eau et lave
* Météo
* 28 biomes + 5 biomes du nether
* Le Nether, monde souterrain brûlant dans une autre dimension
* Circuits Redstone (partiel)
* Effets de Statut (partiel)
* Expérience
* Enchantement
* Brassage, potions, flèches trempées (partiel)
* Bâteaux
* Feu
* Blocs de construction : escaliers, dalles, portes, trappes, barrière, portillon, muret
* Horloge
* Boussole
* Eponge
* Bloc de slime
* Petites plantes et pousses
* Teintures
* Bannières
* Blocs de décoration : verre, verre teinté, vitres, barres de fer, terre cuites (et couleurs), têtes et plus
* Cadres d'objets
* Juke-boxes
* Livres pour écrire
* Commandes
* Villages
* L'End
* et plus !
Les fonctionalités suivantes sont incomplètes :
* certains monstres et animaux
* certains composants de Redstone
* Wagonnets spéciaux
* quelques blocs et objets non-triviaux
Fonctionalités bonus (absentes de Minecraft) :
* Guide d'artisanat intégré au jeu qui montre les recettes d'artisanat et de cuisson
* Système d'aide intégré au jeu contenant des informations à propos des techniques de base, blocs, objets et plus
* Recettes d'artisanat temporaires. Elles existent uniquement pour rendre des objets accessibles qui ne le seraient pas autrement sauf en mode créatif. Elles seront retirées au cours de l'avancement du développement et de l'ajout de nouvelles fonctionalités.
* Pousses dans les coffres en mapgen v6
* Entièrement moddable (grâce la puissante API lua de Minetest)
* Nouveaux blocs et objets :
* Outil de recherche, montre l'aide de ce qu'il touche
* Plus de dalles et d'escaliers
* Portillon en briques du Nether
* Barrière en briques du Nether rouges
* Portillon en briques du Nether rouges
* Structures de remplacement - ces petites variantes de structures de Minecraft servent de remplacement en attendant qu'on arrive à en faire fonctionner de plus grandes :
* Cabine dans les bois (Manoir des bois)
* Avant-poste du Nether (Forteresse)
Différences techniques avec Minecraft :
* Limite en hauteur de 31000 blocs (bien plus grand que Minecraft)
* Taille horizontale du monde 62000×62000 blocs (bien plus petit que Minecraft mais toujours très grand)
* Toujours assez incomplet et buggé
* Des blocs, objets, ennemis et fonctionalités manquent
* Quelques objets ont des noms légèrement différents pour être plus faciles à distinguer
* Des musiques différentes pour le juke-boxe
* Des textures différentes (Pixel Perfection)
* Des sons différents (sources diverses)
* Un moteur de jeu différent (Minetest)
* Des bonus cachés différents
...et enfin MineClone2 est un logiciel libre !
## Autres fichiers readme
* `LICENSE.txt`: Le texte de la license GPLv3
* `CONTRIBUTING.md`: Information pour ceux qui veulent contribuer
* `API.md`: Pour les modders Minetest qui veulent modder ce jeu
* `LEGAL.md`: Information légale
* `CREDITS.md`: Liste des contributeurs

View File

@ -1,2 +1,2 @@
title = MineClone 2
name = MineClone 2
description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.

View File

@ -5,8 +5,6 @@
-- Nodes in group "supported_node" can be placed on any node that does not
-- have the "airlike" drawtype. Carpets are an example of this type.
local pairs = pairs
local math = math
local vector = vector
local facedir_to_dir = minetest.facedir_to_dir
@ -24,17 +22,15 @@ local add_item = minetest.add_item
-- We need this to do the exact same dropping node handling in our override
-- minetest.check_single_for_falling() function as in the builtin function.
--
---@param p Vector
local function drop_attached_node(p)
local n = get_node(p)
local drops = get_node_drops(n, "")
local def = registered_nodes[n.name]
if def and def.preserve_metadata then
local oldmeta = get_meta(p):to_table().fields
-- Copy pos and node because the callback can modify them.
local pos_copy = vector.copy(p)
local node_copy = { name = n.name, param1 = n.param1, param2 = n.param2 }
local pos_copy = vector.new(p)
local node_copy = {name=n.name, param1=n.param1, param2=n.param2}
local drop_stacks = {}
for k, v in pairs(drops) do
drop_stacks[k] = ItemStack(v)
@ -42,18 +38,16 @@ local function drop_attached_node(p)
drops = drop_stacks
def.preserve_metadata(pos_copy, node_copy, oldmeta, drops)
end
if def and def.sounds and def.sounds.fall then
minetest.sound_play(def.sounds.fall, { pos = p }, true)
core.sound_play(def.sounds.fall, {pos = p}, true)
end
remove_node(p)
for _, item in pairs(drops) do
local pos = vector.offset(p,
math.random() / 2 - 0.25,
math.random() / 2 - 0.25,
math.random() / 2 - 0.25
)
local pos = {
x = p.x + math.random()/2 - 0.25,
y = p.y + math.random()/2 - 0.25,
z = p.z + math.random()/2 - 0.25,
}
add_item(pos, item)
end
end
@ -96,3 +90,4 @@ function minetest.check_single_for_falling(pos)
return false
end

View File

@ -12,10 +12,9 @@ mcl_damage = {
drown = {bypasses_armor = true},
starve = {bypasses_armor = true, bypasses_magic = true},
cactus = {},
sweet_berry = {},
fall = {bypasses_armor = true},
fly_into_wall = {bypasses_armor = true}, -- unused
out_of_world = {bypasses_armor = true, bypasses_magic = true, bypasses_invulnerability = true, bypasses_totem = true},
out_of_world = {bypasses_armor = true, bypasses_magic = true, bypasses_invulnerability = true},
generic = {bypasses_armor = true},
magic = {is_magic = true, bypasses_armor = true},
dragon_breath = {is_magic = true, bypasses_armor = true}, -- this is only used for dragon fireball; dragon fireball does not actually deal impact damage tho, so this is unreachable
@ -34,8 +33,6 @@ mcl_damage = {
}
}
local damage_enabled = minetest.settings:get_bool("enabled_damage",true)
function mcl_damage.register_modifier(func, priority)
table.insert(mcl_damage.modifiers, {func = func, priority = priority or 0})
end
@ -81,7 +78,7 @@ function mcl_damage.from_punch(mcl_reason, object)
mcl_reason.type = "arrow"
elseif luaentity._is_fireball then
mcl_reason.type = "fireball"
elseif luaentity.is_mob then
elseif luaentity._cmi_is_mob then
mcl_reason.type = "mob"
end
mcl_reason.source = mcl_reason.source or luaentity._source_object
@ -142,7 +139,6 @@ function mcl_damage.register_type(name, def)
end
minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
if not damage_enabled then return 0 end
if hp_change < 0 then
if player:get_hp() <= 0 then
return 0
@ -153,7 +149,6 @@ minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
end, true)
minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
if not damage_enabled then return 0 end
if player:get_hp() > 0 then
mt_reason.approved = true
if hp_change < 0 then
@ -166,9 +161,9 @@ minetest.register_on_dieplayer(function(player, mt_reason)
if mt_reason.approved then
mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason))
end
minetest.log("action","Player "..player:get_player_name().." died at "..minetest.pos_to_string(vector.round(player:get_pos())))
end)
minetest.register_on_mods_loaded(function()
table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end)
end)

View File

@ -130,10 +130,10 @@ local function add_particles(pos, radius)
time = 0.125,
minpos = pos,
maxpos = pos,
minvel = vector.new(-radius, -radius, -radius),
maxvel = vector.new(radius, radius, radius),
minacc = vector.zero(),
maxacc = vector.zero(),
minvel = {x = -radius, y = -radius, z = -radius},
maxvel = {x = radius, y = radius, z = radius},
minacc = vector.new(),
maxacc = vector.new(),
minexptime = 0.5,
maxexptime = 1.0,
minsize = radius * 0.5,
@ -288,7 +288,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
rdir_y = rdir_y / rdir_len
rdir_z = rdir_z / rdir_len
for i = 0, rdir_len / STEP_LENGTH do
for i=0, rdir_len / STEP_LENGTH do
rpos_x = rpos_x + rdir_x * STEP_LENGTH
rpos_y = rpos_y + rdir_y * STEP_LENGTH
rpos_z = rpos_z + rdir_z * STEP_LENGTH
@ -333,17 +333,17 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
end
if sleep_formspec_doesnt_close_mt53 then
minetest.after(0.3,
function() -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE
minetest.after(0.3, function() -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE
if not obj:is_player() then
return
end
mcl_util.deal_damage(obj, damage, { type = "explosion", direct = direct, source = source })
mcl_util.deal_damage(obj, damage, {type = "explosion", direct = direct, source = source})
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
end)
else
mcl_util.deal_damage(obj, damage, { type = "explosion", direct = direct, source = source })
mcl_util.deal_damage(obj, damage, {type = "explosion", direct = direct, source = source})
if obj:is_player() or ent.tnt_knockback then
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
@ -389,24 +389,23 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc
-- We use bulk_set_node instead of LVM because we want to have on_destruct and
-- on_construct being called
if #airs > 0 then
bulk_set_node(airs, { name = "air" })
bulk_set_node(airs, {name="air"})
end
if #fires > 0 then
bulk_set_node(fires, { name = "mcl_fire:fire" })
bulk_set_node(fires, {name="mcl_fire:fire"})
end
-- Update falling nodes
for a = 1, #airs do
for a=1, #airs do
local p = airs[a]
check_for_falling(vector.offset(p, 0, 1, 0))
check_for_falling({x=p.x, y=p.y+1, z=p.z})
end
for f = 1, #fires do
for f=1, #fires do
local p = fires[f]
check_for_falling(vector.offset(p, 0, 1, 0))
check_for_falling({x=p.x, y=p.y+1, z=p.z})
end
-- Log explosion
minetest.log("action", "Explosion at " .. pos_to_string(pos) .. " with strength " .. strength .. " and radius " ..
radius)
minetest.log("action", "Explosion at "..pos_to_string(pos).." with strength "..strength.." and radius "..radius)
end
-- Create an explosion with strength at pos.
@ -430,11 +429,6 @@ end
-- griefing - If true, the explosion will destroy nodes (default: true)
-- grief_protected - If true, the explosion will also destroy nodes which have
-- been protected (default: false)
---@param pos Vector
---@param strength number
---@param info {drop_chance: number, max_blast_resistance: number, sound: boolean, particles: boolean, fire: boolean, griefing: boolean, grief_protected: boolean}
---@param direct? ObjectRef
---@param source? ObjectRef
function mcl_explosions.explode(pos, strength, info, direct, source)
if info == nil then
info = {}

View File

@ -138,7 +138,6 @@ 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
mcl_vars.mg_nether_deco_max = mcl_vars.mg_nether_max -11 -- this is so ceiling decorations don't spill into other biomes as bedrock generation calls minetest.generate_decorations to put netherrack under the bedrock
if not superflat 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
@ -163,8 +162,7 @@ end
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 + 64, z = 0 }
mcl_vars.mg_end_exit_portal_pos = vector.new(0, mcl_vars.mg_end_min + 71, 0)
mcl_vars.mg_end_platform_pos = { x = 100, y = mcl_vars.mg_end_min + 74, 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

View File

@ -22,16 +22,6 @@ function table.update_nil(t, ...)
return t
end
function mcl_util.file_exists(name)
if type(name) ~= "string" then return end
local f = io.open(name)
if not f then
return false
end
f:close()
return true
end
-- Based on minetest.rotate_and_place
--[[
@ -534,7 +524,7 @@ function mcl_util.deal_damage(target, damage, mcl_reason)
if luaentity.deal_damage then
luaentity:deal_damage(damage, mcl_reason or {type = "generic"})
return
elseif luaentity.is_mob then
elseif luaentity._cmi_is_mob then
-- local puncher = mcl_reason and mcl_reason.direct or target
-- target:punch(puncher, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = damage}}, vector.direction(puncher:get_pos(), target:get_pos()), damage)
if luaentity.health > 0 then
@ -554,7 +544,7 @@ end
function mcl_util.get_hp(obj)
local luaentity = obj:get_luaentity()
if luaentity and luaentity.is_mob then
if luaentity and luaentity._cmi_is_mob then
return luaentity.health
else
return obj:get_hp()
@ -620,95 +610,3 @@ function mcl_util.get_pointed_thing(player, liquid)
end
end
end
-- This following part is 2 wrapper functions + helpers for
-- object:set_bones
-- and player:set_properties preventing them from being resent on
-- every globalstep when they have not changed.
local function roundN(n, d)
if type(n) ~= "number" then return n end
local m = 10^d
return math.floor(n * m + 0.5) / m
end
local function close_enough(a,b)
local rt=true
if type(a) == "table" and type(b) == "table" then
for k,v in pairs(a) do
if roundN(v,2) ~= roundN(b[k],2) then
rt=false
break
end
end
else
rt = roundN(a,2) == roundN(b,2)
end
return rt
end
local function props_changed(props,oldprops)
local changed=false
local p={}
for k,v in pairs(props) do
if not close_enough(v,oldprops[k]) then
p[k]=v
changed=true
end
end
return changed,p
end
--tests for roundN
local test_round1=15
local test_round2=15.00199999999
local test_round3=15.00111111
local test_round4=15.00999999
assert(roundN(test_round1,2)==roundN(test_round1,2))
assert(roundN(test_round1,2)==roundN(test_round2,2))
assert(roundN(test_round1,2)==roundN(test_round3,2))
assert(roundN(test_round1,2)~=roundN(test_round4,2))
-- tests for close_enough
local test_cb = {-0.35,0,-0.35,0.35,0.8,0.35} --collisionboxes
local test_cb_close = {-0.351213,0,-0.35,0.35,0.8,0.351212}
local test_cb_diff = {-0.35,0,-1.35,0.35,0.8,0.35}
local test_eh = 1.65 --eye height
local test_eh_close = 1.65123123
local test_eh_diff = 1.35
local test_nt = { r = 225, b = 225, a = 225, g = 225 } --nametag
local test_nt_diff = { r = 225, b = 225, a = 0, g = 225 }
assert(close_enough(test_cb,test_cb_close))
assert(not close_enough(test_cb,test_cb_diff))
assert(close_enough(test_eh,test_eh_close))
assert(not close_enough(test_eh,test_eh_diff))
assert(not close_enough(test_nt,test_nt_diff)) --no floats involved here
--tests for properties_changed
local test_properties_set1={collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}
local test_properties_set2={collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}
local test_p1,_=props_changed(test_properties_set1,test_properties_set1)
local test_p2,_=props_changed(test_properties_set1,test_properties_set2)
assert(not test_p1)
assert(test_p2)
function mcl_util.set_properties(obj,props)
local changed,p=props_changed(props,obj:get_properties())
if changed then
obj:set_properties(p)
end
end
function mcl_util.set_bone_position(obj,b,p,r) --bone,position,rotation
local oldp,oldr=obj:get_bone_position(b)
if vector.equals(vector.round(oldp),vector.round(p)) and vector.equals(vector.round(oldr),vector.round(r)) then
return
end
obj:set_bone_position(b,p,r)
end

View File

@ -28,10 +28,11 @@ end)
local timer = 0
minetest.register_globalstep(function(dtime)
timer = timer + dtime
if timer >= 0.6 then
if timer >= 0.3 then
for _, player in pairs(get_connected_players()) do
local ppos = player:get_pos()
local npos = vector.add(ppos, vector.new(0, -0.1, 0))
ppos.y = ceil(ppos.y)
local npos = vector.add(ppos, vector.new(0, -1, 0))
if npos then
local node = get_node(npos)
if node then

View File

@ -13,21 +13,11 @@ local function is_group(pos, group)
end
local is_water = flowlib.is_water
local function is_river_water(p)
local n = minetest.get_node(p).name
if n == "mclx_core:river_water_source" or n == "mclx_core:river_water_flowing" then
return true
end
end
local function is_ice(pos)
return is_group(pos, "ice")
end
local function is_fire(pos)
return is_group(pos, "set_on_fire")
end
local function get_sign(i)
if i == 0 then
return 0
@ -56,7 +46,7 @@ end
local function set_attach(boat)
boat._driver:set_attach(boat.object, "",
{x = 0, y = 1.5, z = 1}, {x = 0, y = 0, z = 0})
{x = 0, y = 0.42, z = -1}, {x = 0, y = 0, z = 0})
end
local function set_double_attach(boat)
@ -65,13 +55,9 @@ local function set_double_attach(boat)
boat._passenger:set_attach(boat.object, "",
{x = 0, y = 0.42, z = -2.2}, {x = 0, y = 0, z = 0})
end
local function set_choat_attach(boat)
boat._driver:set_attach(boat.object, "",
{x = 0, y = 1.5, z = 1}, {x = 0, y = 0, z = 0})
end
local function attach_object(self, obj)
if self._driver and not self._inv_id then
if self._driver then
if self._driver:is_player() then
self._passenger = obj
else
@ -81,12 +67,8 @@ local function attach_object(self, obj)
set_double_attach(self)
else
self._driver = obj
if self._inv_id then
set_choat_attach(self)
else
set_attach(self)
end
end
local visual_size = get_visual_size(obj)
local yaw = self.object:get_yaw()
@ -128,14 +110,12 @@ end
local boat = {
physical = true,
pointable = true,
-- Warning: Do not change the position of the collisionbox top surface,
-- lowering it causes the boat to fall through the world if underwater
collisionbox = {-0.5, -0.15, -0.5, 0.5, 0.55, 0.5},
selectionbox = {-0.7, -0.15, -0.7, 0.7, 0.55, 0.7},
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
visual = "mesh",
mesh = "mcl_boats_boat.b3d",
textures = { "mcl_boats_texture_oak_boat.png", "blank.png" },
textures = {"mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png"},
visual_size = boat_visual_size,
hp_max = boat_max_hp,
damage_texture_modifier = "^[colorize:white:0",
@ -146,7 +126,7 @@ local boat = {
_last_v = 0, -- Temporary speed variable
_removed = false, -- If true, boat entity is considered removed (e.g. after punch) and should be ignored
_itemstring = "mcl_boats:boat", -- Itemstring of the boat item (implies boat type)
_animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling backwards
_animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling forwards
_regen_timer = 0,
_damage_anim = 0,
}
@ -169,14 +149,8 @@ function boat.on_activate(self, staticdata, dtime_s)
self._last_v = self._v
self._itemstring = data.itemstring
-- Update the texutes for existing old boat entity instances.
-- Maybe remove this in the future.
if #data.textures ~= 2 then
local has_chest = self._itemstring:find("chest")
data.textures = {
data.textures[1]:gsub("_chest", ""),
has_chest and "mcl_chests_normal.png" or "blank.png"
}
while #data.textures < 5 do
table.insert(data.textures, data.textures[1])
end
self.object:set_properties({textures = data.textures})
@ -220,8 +194,6 @@ end
function boat.on_step(self, dtime, moveresult)
mcl_burning.tick(self.object, dtime, self)
-- mcl_burning.tick may remove object immediately
if not self.object:get_pos() then return end
self._v = get_v(self.object:get_velocity()) * get_sign(self._v)
local v_factor = 1
@ -230,21 +202,16 @@ function boat.on_step(self, dtime, moveresult)
local on_water = true
local on_ice = false
local in_water = is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z})
local in_river_water = is_river_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z})
local waterp = {x=p.x, y=p.y-boat_y_offset - 0.1, z=p.z}
if not is_water(waterp) then
on_water = false
if not in_water and is_ice(waterp) then
on_ice = true
elseif is_fire({x=p.x, y=p.y-boat_y_offset, z=p.z}) then
boat.on_death(self, nil)
self.object:remove()
return
else
v_slowdown = 0.04
v_factor = 0.5
end
elseif in_water and not in_river_water then
elseif in_water then
on_water = false
in_water = true
v_factor = 0.75
@ -347,7 +314,7 @@ function boat.on_step(self, dtime, moveresult)
for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do
local entity = obj:get_luaentity()
if entity and entity.is_mob then
if entity and entity._cmi_is_mob then
attach_object(self, obj)
break
end
@ -376,18 +343,7 @@ function boat.on_step(self, dtime, moveresult)
else
p.y = p.y + 1
local is_obsidian_boat = self.object:get_luaentity()._itemstring == "mcl_boats:boat_obsidian"
if is_river_water(p) then
local y = self.object:get_velocity().y
if y >= 5 then
y = 5
elseif y < 0 then
new_acce = {x = 0, y = 10, z = 0}
else
new_acce = {x = 0, y = 2, z = 0}
end
new_velo = get_velocity(self._v, self.object:get_yaw(), y)
self.object:set_pos(self.object:get_pos())
elseif is_water(p) and not is_river_water(p) or is_obsidian_boat then
if is_water(p) or is_obsidian_boat then
-- Inside water: Slowly sink
local y = self.object:get_velocity().y
y = y - 0.01
@ -427,18 +383,13 @@ end
-- Register one entity for all boat types
minetest.register_entity("mcl_boats:boat", boat)
local cboat = table.copy(boat)
cboat.textures = { "mcl_boats_texture_oak_chest_boat.png", "mcl_chests_normal.png" }
cboat._itemstring = "mcl_boats:chest_boat"
cboat.collisionbox = {-0.5, -0.15, -0.5, 0.5, 0.75, 0.5}
cboat.selectionbox = {-0.7, -0.15, -0.7, 0.7, 0.75, 0.7}
minetest.register_entity("mcl_boats:chest_boat", cboat)
mcl_entity_invs.register_inv("mcl_boats:chest_boat","Boat",27)
local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak", "boat_obsidian", "boat_mangrove", "chest_boat", "chest_boat_spruce", "chest_boat_birch", "chest_boat_jungle", "chest_boat_acacia", "chest_boat_dark_oak", "chest_boat_mangrove" }
local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat"), S("Obsidian Boat"), S("Mangrove Boat"), S("Oak Chest Boat"), S("Spruce Chest Boat"), S("Birch Chest Boat"), S("Jungle Chest Boat"), S("Acacia Chest Boat"), S("Dark Oak Chest Boat"), S("Mangrove Chest Boat") }
local craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood", "mcl_core:obsidian", "mcl_mangrove:mangrove_wood" }
local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak", "boat_obsidian" }
local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat"), S("Obsidian 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", "mcl_core:obsidian" }
end
local images = { "oak", "spruce", "birch", "jungle", "acacia", "dark_oak", "obsidian" }
for b=1, #boat_ids do
local itemstring = "mcl_boats:"..boat_ids[b]
@ -454,21 +405,6 @@ for b=1, #boat_ids do
end
tt_help = S("Water vehicle")
local inventory_image
local texture
local id = boat_ids[b]
if id:find("chest") then
if id == "chest_boat" then id = "oak" end
local id = id:gsub("chest_boat_", "")
inventory_image = "mcl_boats_" .. id .. "_chest_boat.png"
texture = "mcl_boats_texture_" .. id .. "_boat.png"
else
if id == "boat" then id = "oak" end
local id = id:gsub("boat_", "")
inventory_image = "mcl_boats_" .. id .. "_boat.png"
texture = "mcl_boats_texture_" .. id .. "_boat.png"
end
minetest.register_craftitem(itemstring, {
description = names[b],
_tt_help = tt_help,
@ -476,7 +412,7 @@ for b=1, #boat_ids do
_doc_items_entry_name = helpname,
_doc_items_longdesc = longdesc,
_doc_items_usagehelp = usagehelp,
inventory_image = inventory_image,
inventory_image = "mcl_boats_"..images[b].."_boat.png",
liquids_pointable = true,
groups = { boat = 1, transport = 1},
stack_max = 1,
@ -503,15 +439,10 @@ for b=1, #boat_ids do
else
pos = vector.add(pos, vector.multiply(dir, boat_y_offset_ground))
end
local boat_ent = "mcl_boats:boat"
local chest_tex = "blank.png"
if itemstring:find("chest") then
boat_ent = "mcl_boats:chest_boat"
chest_tex = "mcl_chests_normal.png"
end
local boat = minetest.add_entity(pos, boat_ent)
local boat = minetest.add_entity(pos, "mcl_boats:boat")
local texture = "mcl_boats_texture_"..images[b].."_boat.png"
boat:get_luaentity()._itemstring = itemstring
boat:set_properties({ textures = { texture, chest_tex } })
boat:set_properties({textures = { texture, texture, texture, texture, texture }})
boat:set_yaw(placer:get_look_horizontal())
if not minetest.is_creative_enabled(placer:get_player_name()) then
itemstack:take_item()
@ -531,14 +462,6 @@ for b=1, #boat_ids do
})
local c = craftstuffs[b]
if not itemstring:find("chest") then
minetest.register_craft({
output = itemstring:gsub(":boat",":chest_boat"),
recipe = {
{"mcl_chests:chest"},
{itemstring},
},
})
minetest.register_craft({
output = itemstring,
recipe = {
@ -546,7 +469,6 @@ for b=1, #boat_ids do
{c, c, c},
},
})
end
end
minetest.register_craft({

View File

@ -9,5 +9,4 @@ Oak Boat=Bateau en Chêne
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. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Utilisez [Sneak] pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet.
Spruce Boat=Bateau en Sapin
Water vehicle=Véhicule aquatique
Sneak to dismount=Se baisser pour descendre
Obsidian Boat=Bateau en Obsidienne
Sneak to dismount=

View File

@ -10,4 +10,3 @@ Rightclick on a water source to place the boat. Rightclick the boat to enter it.
Spruce Boat=
Water vehicle=
Sneak to dismount=
Obsidian Boat=

View File

@ -1,5 +1,7 @@
name = mcl_boats
author = PilzAdam
description = Adds drivable boats.
depends = mcl_player, flowlib, mcl_title, mcl_entity_invs
depends = mcl_player, flowlib, mcl_title
optional_depends = mcl_core, doc_identifier

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,5 +1,3 @@
local enable_damage = minetest.settings:get_bool("enable_damage")
function mcl_burning.get_storage(obj)
return obj:is_player() and mcl_burning.storage[obj] or obj:get_luaentity()
end
@ -79,7 +77,7 @@ end
-- The effective burn duration is modified by obj's armor protection.
-- If obj was already burning, its burn duration is updated if the current
-- duration is less than burn_time.
-- If obj is dead, fireproof or enable_damage is disabled, this function does nothing.
-- If obj is dead, fireproof or a creative player, this function does nothing.
--
function mcl_burning.set_on_fire(obj, burn_time)
if obj:get_hp() < 0 then
@ -91,9 +89,8 @@ function mcl_burning.set_on_fire(obj, burn_time)
return
end
if obj:is_player() and not enable_damage then
if obj:is_player() and minetest.is_creative_enabled(obj:get_player_name()) then
burn_time = 0
return
else
local max_fire_prot_lvl = 0
local inv = mcl_util.get_inventory(obj)
@ -137,7 +134,6 @@ function mcl_burning.set_on_fire(obj, burn_time)
end
function mcl_burning.extinguish(obj)
if not obj:get_pos() then return end
if mcl_burning.is_burning(obj) then
local storage = mcl_burning.get_storage(obj)
if obj:is_player() then

View File

@ -1,4 +1,3 @@
name = mcl_burning
description = Burning Objects for MineClone2
author = Fleckenstein
depends = mcl_weather

View File

@ -1,36 +0,0 @@
# mcl_dripping
Dripping Mod by kddekadenz, modified for MineClone 2 by Wuzzy, NO11 and AFCM
## Manual
- drops are generated rarely under solid nodes
- they will stay some time at the generated block and than they fall down
- when they collide with the ground, a sound is played and they are destroyed
Water and Lava have builtin drops registered.
## License
code & sounds: CC0
## API
```lua
mcl_dripping.register_drop({
-- The group the liquid's nodes belong to
liquid = "water",
-- The texture used (particles will take a random 2x2 area of it)
texture = "default_water_source_animated.png",
-- Define particle glow, ranges from `0` to `minetest.LIGHT_MAX`
light = 1,
-- The nodes (or node group) the particles will spawn under
nodes = { "group:opaque", "group:leaves" },
-- The sound that will be played then the particle detaches from the roof, see SimpleSoundSpec in lua_api.txt
sound = "drippingwater_drip",
-- The interval for the ABM to run
interval = 60,
-- The chance of the ABM
chance = 10,
})
```

View File

@ -1,101 +1,66 @@
-- Dripping Water Mod
-- by kddekadenz
-- License of code, textures & sounds: CC0
local math = math
mcl_dripping = {}
-- License of code, textures & sounds: CC0
---@param pos Vector
---@param liquid string
---@param sound SimpleSoundSpec
---@param interval integer
---@param texture string
local function make_drop(pos, liquid, sound, interval, texture)
local pt = {
velocity = vector.zero(),
collision_removal = false,
}
local t = math.random() + math.random(1, interval)
minetest.after(t, function()
local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100
pt.pos = vector.offset(pos, x, -0.52, z)
pt.acceleration = vector.zero()
pt.collisiondetection = false
pt.expirationtime = t
pt.texture = "[combine:2x2:" ..
-math.random(1, 16) .. "," .. -math.random(1, 16) .. "=" .. texture
minetest.add_particle(pt)
minetest.after(t, function()
pt.acceleration = vector.new(0, -5, 0)
pt.collisiondetection = true
pt.expirationtime = math.random() + math.random(1, interval / 2)
minetest.add_particle(pt)
minetest.sound_play(sound, { pos = pos, gain = 0.5, max_hear_distance = 8 },
true)
end)
end)
end
---@class mcl_dripping_drop_definition
---@field liquid string The group the liquid's nodes belong to
---@field texture string The texture used (particles will take a random 2x2 area of it)
---@field light integer Define particle glow, ranges from `0` to `minetest.LIGHT_MAX`
---@field nodes string[] The nodes (or node group) the particles will spawn under
---@field interval integer The interval for the ABM to run
---@field chance integer The chance of the ABM
---@field sound SimpleSoundSpec The sound that will be played then the particle detaches from the roof
---@param def mcl_dripping_drop_definition
function mcl_dripping.register_drop(def)
local function register_drop(liquid, glow, sound, nodes)
minetest.register_entity("mcl_dripping:drop_" .. liquid, {
hp_max = 1,
physical = true,
collide_with_objects = false,
collisionbox = {-0.01, 0.01, -0.01, 0.01, 0.01, 0.01},
glow = glow,
pointable = false,
visual = "sprite",
visual_size = {x = 0.1, y = 0.1},
textures = {""},
spritediv = {x = 1, y = 1},
initial_sprite_basepos = {x = 0, y = 0},
static_save = false,
_dropped = false,
on_activate = function(self)
self.object:set_properties({
textures = {"[combine:2x2:" .. -math.random(1, 16) .. "," .. -math.random(1, 16) .. "=default_" .. liquid .. "_source_animated.png"}
})
end,
on_step = function(self, dtime)
local k = math.random(1, 222)
local ownpos = self.object:get_pos()
if k == 1 then
self.object:set_acceleration(vector.new(0, -5, 0))
end
if minetest.get_node(vector.offset(ownpos, 0, 0.5, 0)).name == "air" then
self.object:set_acceleration(vector.new(0, -5, 0))
end
if minetest.get_node(vector.offset(ownpos, 0, -0.1, 0)).name ~= "air" then
local ent = self.object:get_luaentity()
if not ent._dropped then
ent._dropped = true
minetest.sound_play({name = "drippingwater_" .. sound .. "drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true)
end
if k < 3 then
self.object:remove()
end
end
end,
})
minetest.register_abm({
label = "Create drops",
nodenames = def.nodes,
neighbors = { "group:" .. def.liquid },
interval = def.interval,
chance = def.chance,
nodenames = nodes,
neighbors = {"group:" .. liquid},
interval = 2,
chance = 22,
action = function(pos)
local below = minetest.get_node(vector.offset(pos,0,-1,0)).name
if below ~= "air" then return end
local r = math.ceil(def.interval / 20)
local nn = minetest.find_nodes_in_area(vector.offset(pos, -r, 0, -r), vector.offset(pos, r, 0, r), def.nodes)
--start a bunch of particle cycles to be able to get away
--with longer abm cycles
table.shuffle(nn)
for i = 1, math.random(#nn) do
if minetest.get_item_group(minetest.get_node(vector.offset(nn[i], 0, 1, 0)).name, def.liquid) ~= 0 then
make_drop(nn[i], def.liquid, def.sound, def.interval, def.texture)
end
if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1, 0)).name, liquid) ~= 0
and minetest.get_node(vector.offset(pos, 0, -1, 0)).name == "air" then
local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100
minetest.add_entity(vector.offset(pos, x, -0.520, z), "mcl_dripping:drop_" .. liquid)
end
end,
})
end
mcl_dripping.register_drop({
liquid = "water",
texture = "default_water_source_animated.png",
light = 1,
nodes = { "group:opaque", "group:leaves" },
sound = "drippingwater_drip",
interval = 60.3,
chance = 10,
})
mcl_dripping.register_drop({
liquid = "lava",
texture = "default_lava_source_animated.png",
light = math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3),
nodes = { "group:opaque" },
sound = "drippingwater_lavadrip",
interval = 110.1,
chance = 10,
})
register_drop("water", 1, "", {"group:opaque", "group:leaves"})
register_drop("lava", math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), "lava", {"group:opaque"})

View File

@ -0,0 +1,29 @@
Dripping Mod
by kddekadenz
modified for MineClone 2 by Wuzzy and NO11
Installing instructions:
1. Copy the mcl_dripping mod folder into games/gamemode/mods
2. Start game and enjoy :)
Manual:
-> drops are generated rarely under solid nodes
-> they will stay some time at the generated block and than they fall down
-> when they collide with the ground, a sound is played and they are destroyed
License:
code & sounds: CC0
Changelog:
16.04.2012 - first release
28.04.2012 - drops are now 3D; added lava drops; fixed generating of drops (not at edges now)

View File

@ -1,13 +0,0 @@
mcl_entity_invs
===============
Inventories for your entities. It's simple. Depend on mcl_entity_invs and register your entity like so:
* mcl_entity_invs.register_inv("entity:name","Title shown in formspec",inventory_size,disable_on_righclick)
*If disable_on_righclick is true other mods can handle when to show the inventory themselves
* The inventory size can be set dynamically by initializing it with an explicit nil
* mcl_entity_invs.show_inv_form(entity,clicker,[formspec text])
* formspec_text is an additional text that is put after the title
It works by setting up a detached inventory per entity which is accessed by an id/hash generated from the entities position at creation, the progressed gametime at creation and a random salt.

View File

@ -1,173 +0,0 @@
mcl_entity_invs = {}
local open_invs = {}
local function check_distance(inv,player,count)
for _,o in pairs(minetest.get_objects_inside_radius(player:get_pos(),5)) do
local l = o:get_luaentity()
if l and l._inv_id and inv:get_location().name == l._inv_id then return count end
end
return 0
end
local inv_callbacks = {
allow_take = function(inv, listname, index, stack, player)
return check_distance(inv,player,stack:get_count())
end,
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
return check_distance(inv,player,count)
end,
allow_put = function(inv, listname, index, stack, player)
return check_distance(inv,player,stack:get_count())
end,
}
local function load_inv(ent,size)
if not ent._inv_id then return end
local inv = minetest.get_inventory({type="detached", name=ent._inv_id})
if not inv then
inv = minetest.create_detached_inventory(ent._inv_id, inv_callbacks)
inv:set_size("main", size)
if ent._items then
inv:set_list("main",ent._items)
end
end
return inv
end
local function save_inv(ent)
if ent._inv then
ent._items = {}
for i,it in ipairs(ent._inv:get_list("main")) do
ent._items[i] = it:to_string()
end
minetest.remove_detached_inventory(ent._inv_id)
ent._inv = nil
end
end
function mcl_entity_invs.show_inv_form(ent,player,text)
if not ent._inv_id then return end
if not open_invs[ent] then
open_invs[ent] = 0
end
text = text or ""
ent._inv = load_inv(ent,ent._inv_size)
open_invs[ent] = open_invs[ent] + 1
local playername = player:get_player_name()
local rows = 3
local cols = (math.ceil(ent._inv_size/rows))
local spacing = (9 - cols) / 2
local formspec = "size[9,8.75]"
.. "label[0,0;" .. minetest.formspec_escape(
minetest.colorize("#313131", ent._inv_title .. " ".. text)) .. "]"
.. "list[detached:"..ent._inv_id..";main;"..spacing..",0.5;"..cols..","..rows..";]"
.. mcl_formspec.get_itemslot_bg(spacing,0.5,cols,rows)
.. "label[0,4.0;" .. minetest.formspec_escape(
minetest.colorize("#313131", "Inventory")) .. "]"
.. "list[current_player;main;0,4.5;9,3;9]"
.. mcl_formspec.get_itemslot_bg(0,4.5,9,3)
.. "list[current_player;main;0,7.74;9,1;]"
.. mcl_formspec.get_itemslot_bg(0,7.74,9,1)
.. "listring[detached:"..ent._inv_id..";main]"
.. "listring[current_player;main]"
minetest.show_formspec(playername,ent._inv_id,formspec)
end
local function drop_inv(ent)
if not ent._items then return end
local pos = ent.object:get_pos()
for i,it in pairs(ent._items) do
local p = vector.add(pos,vector.new(math.random() - 0.5, math.random()-0.5, math.random()-0.5))
minetest.add_item(p,it)
end
ent._items = nil
end
local function on_remove(self,killer,oldf)
save_inv(self)
drop_inv(self)
if oldf then return oldf(self,killer) end
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
for k,v in pairs(open_invs) do
if formname == k._inv_id then
open_invs[k] = open_invs[k] - 1
if open_invs[k] < 1 then
save_inv(k)
open_invs[k] = nil
end
end
end
end)
function mcl_entity_invs.register_inv(entity_name,show_name,size,no_on_righclick,no_sneak)
assert(minetest.registered_entities[entity_name],"mcl_entity_invs.register_inv called with invalid entity: "..tostring(entity_name))
minetest.registered_entities[entity_name]._inv_size = size
minetest.registered_entities[entity_name]._inv_title = show_name
local old_oa = minetest.registered_entities[entity_name].on_activate
minetest.registered_entities[entity_name].on_activate = function(self,staticdata,dtime_s)
local r
if old_oa then r=old_oa(self,staticdata,dtime_s) end
local d = minetest.deserialize(staticdata)
if type(d) == "table" and d._inv_id then
self._inv_id = d._inv_id
self._items = d._items
self._inv_size = d._inv_size
else
self._inv_id="entity_inv_"..minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random()))
--gametime and position for collision safety and math.random salt to protect against position brute-force
end
return r
end
if not no_on_righclick then
local old_rc = minetest.registered_entities[entity_name].on_rightclick
minetest.registered_entities[entity_name].on_rightclick = function(self,clicker)
if no_sneak or clicker:get_player_control().sneak then
mcl_entity_invs.show_inv_form(self,clicker,"")
if not no_sneak then return end
end
if old_rc then return old_rc(self,clicker) end
end
end
local old_gsd = minetest.registered_entities[entity_name].get_staticdata
minetest.registered_entities[entity_name].get_staticdata = function(self)
local old_sd = old_gsd(self)
local d = minetest.deserialize(old_sd)
assert(type(d) == "table","mcl_entity_invs currently only works with entities that return a (serialized) table in get_staticdata. "..tostring(self.name).." returned: "..tostring(old_sd))
d._inv_id = self._inv_id
d._inv_size = self._inv_size
d._items = {}
if self._items then
for i,it in ipairs(self._items) do
d._items[i] = it
end
end
return minetest.serialize(d)
end
local old_ode = minetest.registered_entities[entity_name].on_deactivate
minetest.registered_entities[entity_name].on_deactivate = function(self,removal)
save_inv(self)
if removal then
on_remove(self)
end
if old_ode then return old_ode(self,removal) end
end
local old_od = minetest.registered_entities[entity_name].on_death
minetest.registered_entities[entity_name].on_death = function(self,killer)
if not self.is_mob then
on_remove(self,killer,old_od)
end
end
local old_odi = minetest.registered_entities[entity_name].on_die
minetest.registered_entities[entity_name].on_die = function(self,killer)
if self.is_mob then
on_remove(self,killer,old_od)
end
end
end

View File

@ -1,3 +0,0 @@
name = mcl_entity_invs
author = cora
depends = mcl_formspec

View File

@ -59,10 +59,6 @@ mcl_item_entity.register_pickup_achievement("tree", "mcl:mineWood")
mcl_item_entity.register_pickup_achievement("mcl_mobitems:blaze_rod", "mcl:blazeRod")
mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow")
mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds")
mcl_item_entity.register_pickup_achievement("mcl_core:crying_obsidian", "mcl:whosCuttingOnions")
mcl_item_entity.register_pickup_achievement("mcl_nether:ancient_debris", "mcl:hiddenInTheDepths")
mcl_item_entity.register_pickup_achievement("mcl_end:dragon_egg", "mcl:PickUpDragonEgg")
mcl_item_entity.register_pickup_achievement("mcl_armor:elytra", "mcl:skysTheLimit")
local function check_pickup_achievements(object, player)
if has_awards then
@ -82,6 +78,7 @@ local function enable_physics(object, luaentity, ignore_check)
object:set_properties({
physical = true
})
object:set_velocity({x=0,y=0,z=0})
object:set_acceleration({x=0,y=-get_gravity(),z=0})
end
end
@ -320,14 +317,18 @@ function minetest.handle_node_drops(pos, drops, digger)
-- Spawn item and apply random speed
local obj = minetest.add_item(dpos, drop_item)
if obj then
-- set the velocity multiplier to the stored amount or if the game dug this node, apply a bigger velocity
local v = 1
if digger and digger:is_player() then
obj:get_luaentity().random_velocity = 1
else
obj:get_luaentity().random_velocity = 1.6
local x = math.random(1, 5)
if math.random(1,2) == 1 then
x = -x
end
local z = math.random(1, 5)
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:get_luaentity().age = item_drop_settings.dug_buffer
obj:get_luaentity()._insta_collect = false
end
end
@ -406,33 +407,9 @@ minetest.register_entity(":__builtin:item", {
-- Number of seconds this item entity has existed so far
age = 0,
-- Multiplier for initial random velocity when the item is spawned
random_velocity = 1,
-- How old it has become in the collection animation
collection_age = 0,
-- Function to apply a random velocity
apply_random_vel = function(self, speed)
if not self or not self.object or not self.object:get_luaentity() then
return
end
-- if you passed a value then use that for the velocity multiplier
if speed ~= nil then self.random_velocity = speed end
local vel = self.object:get_velocity()
if vel and vel.x == 0 and vel.z == 0 and self.random_velocity > 0 then
local v = self.random_velocity
local x = math.random(5, 10) / 10 * v
if math.random(0,10) < 5 then x = -x end
local z = math.random(5, 10) / 10 * v
if math.random(0,10) < 5 then z = -z end
local y = math.random(2,4)
self.object:set_velocity({x=x, y=y, z=z})
end
self.random_velocity = 0
end,
set_item = function(self, itemstring)
self.itemstring = itemstring
if self.itemstring == "" then
@ -441,11 +418,7 @@ minetest.register_entity(":__builtin:item", {
end
local stack = ItemStack(itemstring)
if minetest.get_item_group(stack:get_name(), "compass") > 0 then
if string.find(stack:get_name(), "_lodestone") then
stack:set_name("mcl_compass:18_lodestone")
else
stack:set_name("mcl_compass:18")
end
stack:set_name("mcl_compass:16")
itemstring = stack:to_string()
self.itemstring = itemstring
end
@ -485,9 +458,27 @@ minetest.register_entity(":__builtin:item", {
glow = glow,
}
self.object:set_properties(prop)
if item_drop_settings.random_item_velocity == true and self.age < 1 then
minetest.after(0, self.apply_random_vel, self)
if item_drop_settings.random_item_velocity == true then
minetest.after(0, function(self)
if not self or not self.object or not self.object:get_luaentity() then
return
end
local vel = self.object:get_velocity()
if vel and vel.x == 0 and vel.z == 0 then
local x = math.random(1, 5)
if math.random(1,2) == 1 then
x = -x
end
local z = math.random(1, 5)
if math.random(1,2) == 1 then
z = -z
end
local y = math.random(2,4)
self.object:set_velocity({x=1/x, y=y, z=1/z})
end
end, self)
end
end,
get_staticdata = function(self)
@ -541,9 +532,9 @@ minetest.register_entity(":__builtin:item", {
self.itemstring = data.itemstring
self.always_collect = data.always_collect
if data.age then
self.age = data.age
self.age = data.age + dtime_s
else
self.age = self.age
self.age = dtime_s
end
--remember collection data
-- If true, can collect item without delay
@ -576,7 +567,7 @@ minetest.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_velocity({x = 0, y = 2, z = 0})
self.object:set_acceleration({x = 0, y = -get_gravity(), z = 0})
self:set_item(self.itemstring)
end,
@ -606,13 +597,12 @@ minetest.register_entity(":__builtin:item", {
end
-- Merge the remote stack into this one
-- local pos = object:get_pos()
-- pos.y = pos.y + ((total_count - count) / max_count) * 0.15
-- self.object:move_to(pos)
local pos = object:get_pos()
pos.y = pos.y + ((total_count - count) / max_count) * 0.15
self.object:move_to(pos)
self.age = 0 -- Handle as new entity
own_stack:set_count(total_count)
self.random_velocity = 0
self:set_item(own_stack:to_string())
entity._removed = true
@ -651,53 +641,33 @@ minetest.register_entity(":__builtin:item", {
local node = minetest.get_node_or_nil(p)
local in_unloaded = (node == nil)
if in_unloaded then
-- Don't infinetly fall into unloaded map
disable_physics(self.object, self)
return
end
if self.is_clock then
self.object:set_properties({
textures = {"mcl_clock:clock_" .. (mcl_worlds.clock_works(p) and mcl_clock.old_time or mcl_clock.random_frame)}
})
end
local nn = node.name
local is_in_water = (minetest.get_item_group(nn, "liquid") ~= 0)
local nn_above = minetest.get_node({x=p.x, y=p.y+0.1, z=p.z}).name
-- make sure it's more or less stationary and is at water level
local sleep_threshold = 0.3
local is_floating = false
local is_stationary = math.abs(self.object:get_velocity().x) < sleep_threshold
and math.abs(self.object:get_velocity().y) < sleep_threshold
and math.abs(self.object:get_velocity().z) < sleep_threshold
if is_in_water and is_stationary then
is_floating = (is_in_water
and (minetest.get_item_group(nn_above, "liquid") == 0))
end
if is_floating and self.physical_state == true then
self.object:set_velocity({x = 0, y = 0, z = 0})
self.object:set_acceleration({x = 0, y = 0, z = 0})
disable_physics(self.object, self)
end
-- If no collector was found for a long enough time, declare the magnet as disabled
if self._magnet_active and (self._collector_timer == nil or (self._collector_timer > item_drop_settings.magnet_time)) then
self._magnet_active = false
enable_physics(self.object, self)
return
end
if in_unloaded then
-- Don't infinetly fall into unloaded map
disable_physics(self.object, self)
return
end
-- Destroy item in lava, fire 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
--Wait 2 seconds to allow mob drops to be cooked, & picked up instead of instantly destroyed.
if self.age > 2 and minetest.get_item_group(self.itemstring, "fire_immune") == 0 then
if self.age > 2 then
if dg ~= 2 then
minetest.sound_play("builtin_item_lava", {pos = self.object:get_pos(), gain = 0.5})
end
@ -720,7 +690,7 @@ minetest.register_entity(":__builtin:item", {
end
-- Push item out when stuck inside solid opaque node
if not is_in_water and def and def.walkable and def.groups and def.groups.opaque == 1 then
if def and def.walkable and def.groups and def.groups.opaque == 1 then
local shootdir
local cx = (p.x % 1) - 0.5
local cz = (p.z % 1) - 0.5
@ -761,8 +731,8 @@ minetest.register_entity(":__builtin:item", {
local newv = vector.multiply(shootdir, 3)
self.object:set_acceleration({x = 0, y = 0, z = 0})
self.object:set_velocity(newv)
disable_physics(self.object, self, false, false)
disable_physics(self.object, self, false, false)
if shootdir.y == 0 then
self._force = newv
@ -800,9 +770,8 @@ minetest.register_entity(":__builtin:item", {
return
end
-- Move item around on flowing liquids; add 'source' check to allow items to continue flowing a bit in the source block of flowing water.
if def and not is_floating and (def.liquidtype == "flowing" or def.liquidtype == "source") then
self._flowing = true
-- Move item around on flowing liquids
if def and def.liquidtype == "flowing" then
--[[ Get flowing direction (function call from flowlib), if there's a liquid.
NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7.
@ -811,11 +780,11 @@ minetest.register_entity(":__builtin:item", {
-- Just to make sure we don't manipulate the speed for no reason
if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then
-- Minecraft Wiki: Flowing speed is "about 1.39 meters per second"
local f = 1.2
local f = 1.39
-- Set new item moving speed into the direciton of the liquid
local newv = vector.multiply(vec, f)
-- Swap to acceleration instead of a static speed to better mimic MC mechanics.
self.object:set_acceleration({x = newv.x, y = -0.22, z = newv.z})
self.object:set_acceleration({x = 0, y = 0, z = 0})
self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z})
self.physical_state = true
self._flowing = true
@ -824,29 +793,7 @@ minetest.register_entity(":__builtin:item", {
})
return
end
if is_in_water and def.liquidtype == "source" then
local cur_vec = self.object:get_velocity()
-- apply some acceleration in the opposite direction so it doesn't slide forever
local vec = {
x = 0 -cur_vec.x*0.9,
y = 3 -cur_vec.y*0.9,
z = 0 -cur_vec.z*0.9}
self.object:set_acceleration(vec)
-- slow down the item in water
local vel = self.object:get_velocity()
if vel.y < 0 then
vel.y = vel.y * 0.9
end
self.object:set_velocity(vel)
if self.physical_state ~= false or self._flowing ~= true then
self.physical_state = true
self._flowing = true
self.object:set_properties({
physical = true
})
end
end
elseif self._flowing == true and not is_in_water and not is_floating then
elseif self._flowing == true then
-- Disable flowing physics if not on/in flowing liquid
self._flowing = false
enable_physics(self.object, self, true)
@ -855,13 +802,10 @@ minetest.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 def = minetest.registered_nodes[nn]
local v = self.object:get_velocity()
local is_on_floor = def and (def.walkable
and not def.groups.slippery and v.y == 0)
if not minetest.registered_nodes[nn]
or is_floating or is_on_floor then
if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable and v.y == 0 then
if self.physical_state then
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
-- Merge with close entities of the same item
for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do
@ -872,17 +816,14 @@ minetest.register_entity(":__builtin:item", {
return
end
end
-- don't disable if underwater
if not is_in_water then
end
disable_physics(self.object, self)
end
end
else
if self._magnet_active == false and not is_floating then
if self._magnet_active == false then
enable_physics(self.object, self)
end
end
end,
-- Note: on_punch intentionally left out. The player should *not* be able to collect items by punching

View File

@ -677,8 +677,7 @@ register_minecart(
{ "mcl_chests_normal.png", "mcl_minecarts_minecart.png" },
"mcl_minecarts_minecart_chest.png",
{"mcl_minecarts:minecart", "mcl_chests:chest"},
nil, nil, true)
mcl_entity_invs.register_inv("mcl_minecarts:chest_minecart","Minecart",27,false,true)
nil, nil, false)
-- Minecart with Furnace
register_minecart(
@ -731,7 +730,7 @@ register_minecart(
"mcl_minecarts_minecart.png",
}})
end
end, nil, true
end, nil, false
)
-- Minecart with Command Block
@ -831,7 +830,8 @@ minetest.register_craft({
},
})
minetest.register_craft({
-- TODO: Re-enable crafting of special minecarts when they have been implemented
--[[minetest.register_craft({
output = "mcl_minecarts:furnace_minecart",
recipe = {
{"mcl_furnaces:furnace"},
@ -839,16 +839,13 @@ minetest.register_craft({
},
})
-- TODO: Re-enable crafting of special minecarts when they have been implemented
--[[minetest.register_craft({
minetest.register_craft({
output = "mcl_minecarts:hopper_minecart",
recipe = {
{"mcl_hoppers:hopper"},
{"mcl_minecarts:minecart"},
},
})
--]]
minetest.register_craft({
output = "mcl_minecarts:chest_minecart",
@ -856,7 +853,7 @@ minetest.register_craft({
{"mcl_chests:chest"},
{"mcl_minecarts:minecart"},
},
})
})]]
if has_mcl_wip then

View File

@ -33,4 +33,4 @@ Activates minecarts when powered=Active les wagonnets lorsqu'il est alimenté
Emits redstone power when a minecart is detected=Émet de l'énergie redstone lorsqu'un wagonnet est détecté
Vehicle for fast travel on rails=Véhicule pour voyager rapidement sur rails
Can be ignited by tools or powered activator rail=Peut être allumé par des outils ou un rail d'activation motorisé
Sneak to dismount=Se baisser pour descendre
Sneak to dismount=

View File

@ -1,5 +1,6 @@
name = mcl_minecarts
author = Krock
description = Minecarts are vehicles to move players quickly on rails.
depends = mcl_title, mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons, mcl_entity_invs
depends = mcl_title, mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons
optional_depends = doc_identifier, mcl_wip

View File

@ -21,7 +21,7 @@ local function register_rail(itemstring, tiles, def_extras, creative)
stack_max = 64,
groups = groups,
sounds = mcl_sounds.node_sound_metal_defaults(),
_mcl_blast_resistance = 0.7,
_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.

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,7 @@ functions needed for the mob to work properly which contains the following:
'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.
'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.
@ -66,13 +66,13 @@ functions needed for the mob to work properly which contains the following:
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_damage' holds the damage per second infliced to mobs when standing in
water (default: 0).
'lava_damage' holds the damage per second inflicted to mobs when standing
in lava (default: 8).
'fire_damage' holds the damage per second inflicted to mobs when standing
in fire (default: 1).
'light_damage'holds the damage per second inflicted to mobs when it's too
'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.
@ -119,7 +119,7 @@ functions needed for the mob to work properly which contains the following:
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
'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.
@ -136,7 +136,7 @@ functions needed for the mob to work properly which contains the following:
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: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.
@ -194,10 +194,9 @@ functions needed for the mob to work properly which contains the following:
'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_start' start frame for when mob stands still.
'stand_end' end frame of stand animation.
'stand_speed'speed of animation in frames per second.
'stand_speed' speed of animation in frames per second.
'walk_start' when mob is walking around.
'walk_end'
'walk_speed'
@ -207,20 +206,19 @@ functions needed for the mob to work properly which contains the following:
'fly_start' when a mob is flying.
'fly_end'
'fly_speed'
'punch_start'when a mob melee attacks.
'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_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.
@ -239,7 +237,7 @@ functions needed for the mob to work properly which contains the following:
'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
'spawn_small_alternative': name of a smaller mob to use as replacement if
spawning fails due to space requirements
'glow' same as in entity definition
'child' if true, spawn mob as child
@ -255,15 +253,6 @@ functions needed for the mob to work properly which contains the following:
'fire_resistant' If true, the mob can't burn
'fire_damage_resistant' If true the mob will not take damage when burning
'ignited_by_sunlight' If true the mod will burn at daytime. (Takes sunlight_damage per second)
'nofollow' Do not follow players when they wield the "follow" item. For mobs (like villagers)
that are bred in a different way.
'pick_up' table of itemstrings the mob will pick up (e.g. for breeding)
'on_pick_up' function that will be called on item pickup - arguments are self and the itementity return a (modified) itemstack
'custom_visual_size' will not reset visual_size from the base class on reload
'noyaw' If true this mob will not automatically change yaw
'particlespawners' Table of particlespawners attached to the mob. This is implemented in a coord safe manner i.e. spawners are only sent to players within the player_transfer_distance (and automatically removed). This enables infinitely lived particlespawners.
mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival
@ -308,7 +297,7 @@ 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). Return true to skip the builtin
death animation and death effects
'on_rightclick'its same as in minetest.register_entity()
'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)
@ -319,13 +308,13 @@ enhance mob functionality and have them do many interesting things:
'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.
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
'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
@ -346,9 +335,9 @@ for each mob.
damage at all (cannot exceed self.breath_max). Breath
decreases by 1 each second while in a node with drowning
damage and increases by 1 each second otherwise.
'self.texture_list'contains list of all mob textures
'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
'self.base_texture' contains current skin texture which was randomly
selected from textures list
'self.gotten' this is used to track whether some special item has been
gotten from the mob, for example, wool from sheep.
@ -417,7 +406,7 @@ command which uses above names to make settings clearer:
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
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.
@ -425,7 +414,7 @@ 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
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
@ -436,7 +425,7 @@ true the mob will not spawn.
MineClone 2 extensions
----------------------
mcl_mobs:spawn_child(pos, mob_type)
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.
@ -446,7 +435,6 @@ mobs:death_effect(pos, collisionbox)
Create death particles at pos with the given collisionbox.
mcl_mobs.spawn(pos,name/entity name)
Making Arrows
-------------
@ -458,7 +446,7 @@ 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()
'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
@ -488,13 +476,13 @@ This function registers a arrow for mobs with the attack type shoot.
Spawn Eggs
----------
mobs:register_egg(name, description, background_color, overlay_color, addegg, no_creative)
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_color' and 'overlay_color' define the colors for the texture displayed for the egg in inventory
'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
@ -510,7 +498,7 @@ mobs:boom(self, pos, radius)
'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
and damages any entity caught inside the blast radius. Protection will limit
node destruction but not entity damage.
@ -554,7 +542,7 @@ 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.
players. Will return true when mob right-clicked with mobs:protector item.
'self' mob information
'clicker' player information
@ -590,7 +578,7 @@ 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"
'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
@ -608,7 +596,7 @@ controls.
'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"
'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.
@ -635,7 +623,7 @@ Certain variables need to be set before using the above functions:
'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_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}
@ -654,7 +642,7 @@ External Settings for "minetest.conf"
multiplied by this number), defaults to 1.0.
'mob_spawn_chance' 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
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.

View File

@ -12,7 +12,7 @@ local crash_threshold = 6.5 -- ignored if enable_crash=false
local node_ok = function(pos, fallback)
fallback = fallback or mcl_mobs.fallback_node
fallback = fallback or mobs.fallback_node
local node = minetest.get_node_or_nil(pos)
@ -119,7 +119,7 @@ end)
-------------------------------------------------------------------------------
function mcl_mobs.attach(entity, player)
function mobs.attach(entity, player)
local attach_at, eye_offset
@ -162,7 +162,7 @@ function mcl_mobs.attach(entity, player)
end
function mcl_mobs.detach(player, offset)
function mobs.detach(player, offset)
force_detach(player)
@ -185,7 +185,7 @@ function mcl_mobs.detach(player, offset)
end
function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
local rot_view = 0
@ -206,7 +206,7 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- move forwards
if ctrl.up then
entity.v = entity.v + entity.accel / 10 * entity.run_velocity / 2.6
entity.v = entity.v + entity.accel / 10
-- move backwards
elseif ctrl.down then
@ -261,7 +261,7 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
if stand_anim then
mcl_mobs:set_animation(entity, stand_anim)
mobs:set_animation(entity, stand_anim)
end
return
@ -269,7 +269,7 @@ function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- set moving animation
if moving_anim then
mcl_mobs:set_animation(entity, moving_anim)
mobs:set_animation(entity, moving_anim)
end
-- Stop!
@ -388,7 +388,7 @@ end
-- directional flying routine by D00Med (edited by TenPlus1)
function mcl_mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
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()
@ -440,9 +440,9 @@ function mcl_mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_an
-- change animation if stopped
if velo.x == 0 and velo.y == 0 and velo.z == 0 then
mcl_mobs:set_animation(entity, stand_anim)
mobs:set_animation(entity, stand_anim)
else
-- moving animation
mcl_mobs:set_animation(entity, moving_anim)
mobs:set_animation(entity, moving_anim)
end
end

View File

@ -1,5 +1,4 @@
--lua locals
local minetest,vector,math,table = minetest,vector,math,table
local get_node = minetest.get_node
local get_item_group = minetest.get_item_group
local get_node_light = minetest.get_node_light
@ -16,7 +15,7 @@ local math_cos = math.cos
local math_sin = math.sin
local math_round = function(x) return (x > 0) and math_floor(x + 0.5) or math_ceil(x - 0.5) end
local vector_distance = vector.distance
--local vector_distance = vector.distance
local vector_new = vector.new
local vector_floor = vector.floor
@ -24,26 +23,13 @@ local table_copy = table.copy
local table_remove = table.remove
local pairs = pairs
local dbg_spawn_attempts = 0
local dbg_spawn_succ = 0
local dbg_spawn_counts = {}
-- range for mob count
local aoc_range = 136
local mob_cap = {
monster = tonumber(minetest.settings:get("mcl_mob_cap_monster")) or 70,
animal = tonumber(minetest.settings:get("mcl_mob_cap_animal")) or 10,
ambient = tonumber(minetest.settings:get("mcl_mob_cap_ambient")) or 15,
water = tonumber(minetest.settings:get("mcl_mob_cap_water")) or 5, --currently unused
water_ambient = tonumber(minetest.settings:get("mcl_mob_cap_water_ambient")) or 20, --currently unused
player = tonumber(minetest.settings:get("mcl_mob_cap_player")) or 75,
total = tonumber(minetest.settings:get("mcl_mob_cap_total")) or 500,
}
-- range for mob count
local aoc_range = 32
--do mobs spawn?
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
local spawn_protected = minetest.settings:get_bool("mobs_spawn_protected") ~= false
local logging = minetest.settings:get_bool("mcl_logging_mobs_spawn",true)
local noise_params = {
offset = 0,
@ -77,7 +63,6 @@ local list_of_all_biomes = {
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
"MangroveSwamp_underground",
-- ocean:
@ -141,8 +126,6 @@ local list_of_all_biomes = {
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"MangroveSwamp_ocean",
"MangroveSwamp_deep_ocean",
-- water or beach?
@ -166,15 +149,10 @@ local list_of_all_biomes = {
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MangroveSwamp_shore",
-- dimension biome:
"Nether",
"BasaltDelta",
"CrimsonForest",
"WarpedForest",
"SoulsandValley",
"End",
-- Overworld regular:
@ -184,8 +162,6 @@ local list_of_all_biomes = {
"Swampland",
"Taiga",
"ExtremeHills",
"ExtremeHillsM",
"ExtremeHills+_snowtop",
"Jungle",
"Savanna",
"BirchForest",
@ -204,6 +180,7 @@ local list_of_all_biomes = {
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
@ -212,50 +189,23 @@ local list_of_all_biomes = {
"MesaBryce",
"JungleEdge",
"SavannaM",
"MangroveSwamp",
}
-- count how many mobs are in an area
local function count_mobs(pos,r,mob_type)
local function count_mobs(pos)
local num = 0
for _,l in pairs(minetest.luaentities) do
if l and l.is_mob and (mob_type == nil or l.type == mob_type) then
local p = l.object:get_pos()
if p and vector_distance(p,pos) < r then
for _,object in pairs(get_objects_inside_radius(pos, aoc_range)) do
if object and object:get_luaentity() and object:get_luaentity()._cmi_is_mob then
num = num + 1
end
end
end
return num
end
local function count_mobs_total(mob_type)
local num = 0
for _,l in pairs(minetest.luaentities) do
if l.is_mob then
if mob_type == nil or l.type == mob_type then
num = num + 1
end
end
end
return num
end
local function count_mobs_total_cap(mob_type)
local num = 0
for _,l in pairs(minetest.luaentities) do
if l.is_mob then
if ( mob_type == nil or l.type == mob_type ) and l.can_despawn and not l.nametag then
num = num + 1
end
end
end
return num
end
-- global functions
function mcl_mobs:spawn_abm_check(pos, node, name)
function mobs:spawn_abm_check(pos, node, name)
-- global function to add additional spawn checks
-- return true to stop spawning mob
end
@ -291,7 +241,7 @@ WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua??
local spawn_dictionary = {}
local summary_chance = 0
function mcl_mobs:spawn_setup(def)
function mobs:spawn_setup(def)
if not mobs_spawn then return end
if not def then
@ -325,10 +275,10 @@ function mcl_mobs:spawn_setup(def)
chance = tonumber(numbers[1]) or chance
aoc = tonumber(numbers[2]) or aoc
if chance == 0 then
minetest.log("warning", string.format("[mcl_mobs] %s has spawning disabled", name))
minetest.log("warning", string.format("[mobs] %s has spawning disabled", name))
return
end
minetest.log("action", string.format("[mcl_mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
minetest.log("action", string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
end
if chance < 1 then
@ -354,7 +304,7 @@ function mcl_mobs:spawn_setup(def)
summary_chance = summary_chance + chance
end
function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn)
function mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn)
-- Do mobs spawn at all?
if not mobs_spawn then
@ -370,11 +320,11 @@ function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_
aoc = tonumber(numbers[2]) or aoc
if chance == 0 then
minetest.log("warning", string.format("[mcl_mobs] %s has spawning disabled", name))
minetest.log("warning", string.format("[mobs] %s has spawning disabled", name))
return
end
minetest.log("action", string.format("[mcl_mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
minetest.log("action", string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
end
--load information into the spawn dictionary
@ -426,217 +376,13 @@ local function is_farm_animal(n)
return n == "mobs_mc:pig" or n == "mobs_mc:cow" or n == "mobs_mc:sheep" or n == "mobs_mc:chicken" or n == "mobs_mc:horse" or n == "mobs_mc:donkey"
end
local function get_water_spawn(p)
local nn = minetest.find_nodes_in_area(vector.offset(p,-2,-1,-2),vector.offset(p,2,-15,2),{"group:water"})
if nn and #nn > 0 then
return nn[math.random(#nn)]
end
end
local function has_room(self,pos)
local cb = self.collisionbox
local nodes = {}
if self.fly_in then
local t = type(self.fly_in)
if t == "table" then
nodes = table.copy(self.fly_in)
elseif t == "string" then
table.insert(nodes,self.fly_in)
end
end
table.insert(nodes,"air")
local x = cb[4] - cb[1]
local y = cb[5] - cb[2]
local z = cb[6] - cb[3]
local r = math.ceil(x * y * z)
local p1 = vector.offset(pos,cb[1],cb[2],cb[3])
local p2 = vector.offset(pos,cb[4],cb[5],cb[6])
local n = #minetest.find_nodes_in_area(p1,p2,nodes) or 0
if r > n then
minetest.log("warning","[mcl_mobs] No room for mob "..self.name.." at "..minetest.pos_to_string(vector.round(pos)))
return false
end
return true
end
local function spawn_check(pos,spawn_def,ignore_caps)
if not spawn_def then return end
dbg_spawn_attempts = dbg_spawn_attempts + 1
local dimension = mcl_worlds.pos_to_dimension(pos)
local mob_def = minetest.registered_entities[spawn_def.name]
local mob_type = mob_def.type
local gotten_node = get_node(pos).name
local gotten_biome = minetest.get_biome_data(pos)
if not gotten_node or not gotten_biome then return end
gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with
local is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0
if not is_ground then
pos.y = pos.y - 1
gotten_node = get_node(pos).name
is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0
end
pos.y = pos.y + 1
local is_water = get_item_group(gotten_node, "water") ~= 0
local is_lava = get_item_group(gotten_node, "lava") ~= 0
local is_leaf = get_item_group(gotten_node, "leaves") ~= 0
local is_bedrock = gotten_node == "mcl_core:bedrock"
local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0
local mob_count_wide = 0
local mob_count = 0
if not ignore_caps then
mob_count = count_mobs(pos,32,mob_type)
mob_count_wide = count_mobs(pos,aoc_range,mob_type)
end
if pos and spawn_def
and ( mob_count_wide < (mob_cap[mob_type] or 15) )
and ( mob_count < 5 )
and pos.y >= spawn_def.min_height
and pos.y <= spawn_def.max_height
and spawn_def.dimension == dimension
and biome_check(spawn_def.biomes, gotten_biome)
and (is_ground or spawn_def.type_of_spawning ~= "ground")
and (spawn_def.type_of_spawning ~= "ground" or not is_leaf)
and has_room(mob_def,pos)
and (spawn_def.check_position and spawn_def.check_position(pos) or true)
and (not is_farm_animal(spawn_def.name) or is_grass)
and (spawn_def.type_of_spawning ~= "water" or is_water)
and ( not spawn_protected or not minetest.is_protected(pos, "") )
and not is_bedrock then
--only need to poll for node light if everything else worked
local gotten_light = get_node_light(pos)
if gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light then
return true
end
end
return false
end
function mcl_mobs.spawn(pos,id)
local def = minetest.registered_entities[id] or minetest.registered_entities["mobs_mc:"..id] or minetest.registered_entities["extra_mobs:"..id]
if not def or (def.can_spawn and not def.can_spawn(pos)) or not def.is_mob then
return false
end
if not dbg_spawn_counts[def.name] then
dbg_spawn_counts[def.name] = 1
else
dbg_spawn_counts[def.name] = dbg_spawn_counts[def.name] + 1
end
return minetest.add_entity(pos, def.name)
end
local function spawn_group(p,mob,spawn_on,group_max,group_min)
if not group_min then group_min = 1 end
local nn= minetest.find_nodes_in_area_under_air(vector.offset(p,-5,-3,-5),vector.offset(p,5,3,5),spawn_on)
local o
table.shuffle(nn)
if not nn or #nn < 1 then
nn = {}
table.insert(nn,p)
end
for i = 1, math.random(group_min,group_max) do
local sp = vector.offset(nn[math.random(#nn)],0,1,0)
if spawn_check(nn[math.random(#nn)],mob,true) then
if mob.type_of_spawning == "water" then
sp = get_water_spawn(sp)
end
o = mcl_mobs.spawn(sp,mob.name)
if o then dbg_spawn_succ = dbg_spawn_succ + 1 end
end
end
return o
end
mcl_mobs.spawn_group = spawn_group
local S = minetest.get_translator("mcl_mobs")
minetest.register_chatcommand("spawn_mob",{
privs = { debug = true },
description=S("spawn_mob is a chatcommand that allows you to type in the name of a mob without 'typing mobs_mc:' all the time like so; 'spawn_mob spider'. however, there is more you can do with this special command, currently you can edit any number, boolian, and string variable you choose with this format: spawn_mob 'any_mob:var<mobs_variable=variable_value>:'. any_mob being your mob of choice, mobs_variable being the variable, and variable value being the value of the chosen variable. and example of this format: \n spawn_mob skeleton:var<passive=true>:\n this would spawn a skeleton that wouldn't attack you. REMEMBER-THIS> when changing a number value always prefix it with 'NUM', example: \n spawn_mob skeleton:var<jump_height=NUM10>:\n this setting the skelly's jump height to 10. if you want to make multiple changes to a mob, you can, example: \n spawn_mob skeleton:var<passive=true>::var<jump_height=NUM10>::var<fly_in=air>::var<fly=true>:\n etc."),
func = function(n,param)
local pos = minetest.get_player_by_name(n):get_pos()
local modifiers = {}
for capture in string.gmatch(param, "%:(.-)%:") do
table.insert(modifiers, ":"..capture)
end
local mod1 = string.find(param, ":")
local mobname = param
if mod1 then
mobname = string.sub(param, 1, mod1-1)
end
local mob = mcl_mobs.spawn(pos,mobname)
for c=1, #modifiers do
modifs = modifiers[c]
local mod1 = string.find(modifs, ":")
local mod_start = string.find(modifs, "<")
local mod_vals = string.find(modifs, "=")
local mod_end = string.find(modifs, ">")
local mod_end = string.find(modifs, ">")
if mob then
local mob_entity = mob:get_luaentity()
if string.sub(modifs, mod1+1, mod1+3) == "var" then
if mod1 and mod_start and mod_vals and mod_end then
local variable = string.sub(modifs, mod_start+1, mod_vals-1)
local value = string.sub(modifs, mod_vals+1, mod_end-1)
number_tag = string.find(value, "NUM")
if number_tag then
value = tonumber(string.sub(value, 4, -1))
end
if value == "true" then
value = true
elseif value == "false" then
value = false
end
if not mob_entity[variable] then
minetest.log("warning", n.." mob variable "..variable.." previously unset")
end
mob_entity[variable] = value
else
minetest.log("warning", n.." couldn't modify "..mobname.." at "..minetest.pos_to_string(pos).. ", missing paramaters")
end
else
minetest.log("warning", n.." couldn't modify "..mobname.." at "..minetest.pos_to_string(pos).. ", missing modification type")
end
end
end
if mob then
return true, mobname.." spawned at "..minetest.pos_to_string(pos),
minetest.log("action", n.." spawned "..mobname.." at "..minetest.pos_to_string(pos))
end
return false, "Couldn't spawn "..mobname
end
})
if mobs_spawn then
local perlin_noise
local function spawn_a_mob(pos, dimension, y_min, y_max)
--create a disconnected clone of the spawn dictionary
--prevents memory leak
local mob_library_worker_table = table_copy(spawn_dictionary)
local dimension = dimension or mcl_worlds.pos_to_dimension(pos)
local goal_pos = get_next_mob_spawn_pos(pos)
--grab mob that fits into the spawning location
--randomly grab a mob, don't exclude any possibilities
local spawning_position_list = find_nodes_in_area_under_air(
{x = goal_pos.x, y = y_min, z = goal_pos.z},
{x = goal_pos.x, y = y_max, z = goal_pos.z},
@ -645,10 +391,41 @@ if mobs_spawn then
if #spawning_position_list <= 0 then return end
local spawning_position = spawning_position_list[math_random(1, #spawning_position_list)]
--hard code mob limit in area to 5 for now
if count_mobs(spawning_position) >= 5 then return end
local gotten_node = get_node(spawning_position).name
local gotten_biome = minetest.get_biome_data(spawning_position)
if not gotten_node or not gotten_biome then return end
gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with
--add this so mobs don't spawn inside nodes
spawning_position.y = spawning_position.y + 1
--only need to poll for node light if everything else worked
local gotten_light = get_node_light(spawning_position)
local is_water = get_item_group(gotten_node, "water") ~= 0
local is_lava = get_item_group(gotten_node, "lava") ~= 0
local is_ground = not (is_water or is_lava)
local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0
local has_bed = minetest.find_node_near(pos,25,{"group:bed"})
if not is_ground then
spawning_position.y = spawning_position.y - 1
end
local mob_def
--create a disconnected clone of the spawn dictionary
--prevents memory leak
local mob_library_worker_table = table_copy(spawn_dictionary)
--grab mob that fits into the spawning location
--randomly grab a mob, don't exclude any possibilities
perlin_noise = perlin_noise or minetest_get_perlin(noise_params)
local noise = perlin_noise:get_3d(spawning_position)
local current_summary_chance = summary_chance
table.shuffle(mob_library_worker_table)
while #mob_library_worker_table > 0 do
local mob_chance_offset = (math_round(noise * current_summary_chance + 12345) % current_summary_chance) + 1
local mob_index = 1
@ -660,35 +437,23 @@ if mobs_spawn then
step_chance = step_chance + mob_chance
end
local mob_def = mob_library_worker_table[mob_index]
--minetest.log(mob_def.name.." "..step_chance.. " "..mob_chance)
local spawn_in_group = minetest.registered_entities[mob_def.name].spawn_in_group or 4
local spawn_in_group_min = minetest.registered_entities[mob_def.name].spawn_in_group_min or 1
local mob_type = minetest.registered_entities[mob_def.name].type
if spawn_check(spawning_position,mob_def) then
if mob_def.type_of_spawning == "water" then
spawning_position = get_water_spawn(spawning_position)
if not spawning_position then
minetest.log("warning","[mcl_mobs] no water spawn for mob "..mob_def.name.." found at "..minetest.pos_to_string(vector.round(pos)))
return
end
end
if minetest.registered_entities[mob_def.name].can_spawn and not minetest.registered_entities[mob_def.name].can_spawn(spawning_position) then
minetest.log("warning","[mcl_mobs] mob "..mob_def.name.." refused to spawn at "..minetest.pos_to_string(vector.round(spawning_position)))
return
end
if mob_def
and spawning_position.y >= mob_def.min_height
and spawning_position.y <= mob_def.max_height
and mob_def.dimension == dimension
and biome_check(mob_def.biomes, gotten_biome)
and gotten_light >= mob_def.min_light
and gotten_light <= mob_def.max_light
and (is_ground or mob_def.type_of_spawning ~= "ground")
and (mob_def.check_position and mob_def.check_position(spawning_position) or true)
and (not is_farm_animal(mob_def.name) or is_grass)
and (mob_type ~= "npc" or has_bed)
then
--everything is correct, spawn mob
local object
if spawn_in_group and ( mob_type ~= "monster" or math.random(5) == 1 ) then
if logging then
minetest.log("action", "[mcl_mobs] A group of mob " .. mob_def.name .. " spawns on " ..minetest.get_node(vector.offset(spawning_position,0,-1,0)).name .." at " .. minetest.pos_to_string(spawning_position, 1))
end
object = spawn_group(spawning_position,mob_def,{minetest.get_node(vector.offset(spawning_position,0,-1,0)).name},spawn_in_group,spawn_in_group_min)
else
if logging then
minetest.log("action", "[mcl_mobs] Mob " .. mob_def.name .. " spawns on " ..minetest.get_node(vector.offset(spawning_position,0,-1,0)).name .." at ".. minetest.pos_to_string(spawning_position, 1))
end
object = mcl_mobs.spawn(spawning_position, mob_def.name)
local object = minetest.add_entity(spawning_position, mob_def.name)
if object then
return mob_def.on_spawn and mob_def.on_spawn(object, pos)
end
end
current_summary_chance = current_summary_chance - mob_chance
@ -704,32 +469,16 @@ if mobs_spawn then
timer = timer + dtime
if timer < 10 then return end
timer = 0
local players = get_connected_players()
local total_mobs = count_mobs_total_cap()
if total_mobs > mob_cap.total or total_mobs > #players * mob_cap.player then
minetest.log("action","[mcl_mobs] global mob cap reached. no cycle spawning.")
return
end --mob cap per player
for _, player in pairs(players) do
for _, player in pairs(get_connected_players()) do
local pos = player:get_pos()
local dimension = mcl_worlds.pos_to_dimension(pos)
-- ignore void and unloaded area
if dimension ~= "void" and dimension ~= "default" then
local y_min, y_max = decypher_limits(pos.y)
for i = 1, math_random(1, 4) do
spawn_a_mob(pos, dimension, y_min, y_max)
end
end
end
end)
end
minetest.register_chatcommand("mobstats",{
privs = { debug = true },
func = function(n,param)
minetest.chat_send_player(n,dump(dbg_spawn_counts))
local pos = minetest.get_player_by_name(n):get_pos()
minetest.chat_send_player(n,"mobs within 32 radius of player:"..count_mobs(pos,32))
minetest.chat_send_player(n,"total mobs:"..count_mobs_total())
minetest.chat_send_player(n,"spawning attempts since server start:"..dbg_spawn_attempts)
minetest.chat_send_player(n,"successful spawns since server start:"..dbg_spawn_succ)
end
})

View File

@ -38,23 +38,13 @@ local function wither_spawn(pos)
if check_schem(p, schem) then
remove_schem(p, schem)
minetest.add_entity(vector.add(p, {x = 0, y = 1, z = 0, [d] = 1}), "mobs_mc:wither")
local objects = minetest.get_objects_inside_radius(pos, 20)
for _, players in ipairs(objects) do
if players:is_player() then
awards.unlock(players:get_player_name(), "mcl:witheringHeights")
end
end
end
end
end
end
local wither_head = minetest.registered_nodes["mcl_heads:wither_skeleton"]
local old_on_place = wither_head.on_place
function wither_head.on_place(itemstack, placer, pointed)
local n = minetest.get_node(vector.offset(pointed.above,0,-1,0))
if n and n.name == "mcl_nether:soul_sand" then
local old_onplace=minetest.registered_nodes[mobs_mc.items.head_wither_skeleton].on_place
minetest.registered_nodes[mobs_mc.items.head_wither_skeleton].on_place=function(itemstack,placer,pointed)
minetest.after(0, wither_spawn, pointed.above)
end
return old_on_place(itemstack, placer, pointed)
old_onplace(itemstack,placer,pointed)
end

View File

@ -0,0 +1,333 @@
--[[ This table contains the concrete itemstrings to be used by this mod.
All mobs in this mod must use variables in this table, instead
of hardcoding the itemstring.
This way, external mods are enabled to replace the itemstrings to provide
their own items and game integration is made much simpler.
An item IDs is supposed to be overwritten by adding
mobs_mc.override.items["example:item"] in a game mod
with name "mobs_mc_gameconfig". ]]
-- Standard items
-- If true, mobs_mc adds the monster egg nodes (needs default mod).
-- Set to false in your gameconfig mod if you create your own monster egg nodes.
mobs_mc.create_monster_egg_nodes = true
mobs_mc.items = {}
mobs_mc.items = {
-- Items defined in mobs_mc
blaze_rod = "mobs_mc:blaze_rod",
blaze_powder = "mobs_mc:blaze_powder",
chicken_raw = "mobs_mc:chicken_raw",
chicken_cooked = "mobs_mc:chicken_cooked",
feather = "mobs_mc:feather",
beef_raw = "mobs_mc:beef_raw",
beef_cooked = "mobs_mc:beef_cooked",
bowl = "mobs_mc:bowl",
mushroom_stew = "mobs_mc:mushroom_stew",
milk = "mobs_mc:milk_bucket",
dragon_egg = "mobs_mc:dragon_egg",
egg = "mobs_mc:egg",
ender_eye = "mobs_mc:ender_eye",
ghast_tear = "mobs_mc:ghast_tear",
saddle = "mobs:saddle",
iron_horse_armor = "mobs_mc:iron_horse_armor",
gold_horse_armor = "mobs_mc:gold_horse_armor",
diamond_horse_armor = "mobs_mc:diamond_horse_armor",
porkchop_raw = "mobs_mc:porkchop_raw",
porkchop_cooked = "mobs_mc:porkchop_cooked",
carrot_on_a_stick = "mobs_mc:carrot_on_a_stick",
rabbit_raw = "mobs_mc:rabbit_raw",
rabbit_cooked = "mobs_mc:rabbit_cooked",
rabbit_hide = "mobs_mc:rabbit_hide",
mutton_raw = "mobs_mc:mutton_raw",
mutton_cooked = "mobs_mc:mutton_cooked",
shulker_shell = "mobs_mc:shulker_shell",
magma_cream = "mobs_mc:magma_cream",
spider_eye = "mobs_mc:spider_eye",
snowball = "mobs_mc:snowball",
totem = "mobs_mc:totem",
rotten_flesh = "mobs_mc:rotten_flesh",
nether_star = "mobs_mc:nether_star",
bone = "mobs_mc:bone",
slimeball = "mobs_mc:slimeball",
arrow = "mobs_mc:arrow",
bow = "mobs_mc:bow_wood",
head_creeper = "mobs_mc:head_creeper",
head_zombie = "mobs_mc:head_zombie",
head_skeleton = "mobs_mc:head_skeleton",
head_wither_skeleton = "mobs_mc:head_wither_skeleton",
-- External items
-- Mobs Redo
leather = "mobs:leather",
shears = "mobs:shears",
-- Minetest Game
top_snow = "default:snow",
snow_block = "default:snowblock",
mushroom_red = "flowers:mushroom_red",
bucket = "bucket:bucket_empty",
grass_block = "default:dirt_with_grass",
string = "farming:string",
stick = "default:stick",
flint = "default:flint",
iron_ingot = "default:steel_ingot",
iron_block = "default:steelblock",
fire = "fire:basic_flame",
gunpowder = "tnt:gunpowder",
flint_and_steel = "fire:flint_and_steel",
water_source = "default:water_source",
river_water_source = "default:river_water_source",
black_dye = "dye:black",
poppy = "flowers:rose",
dandelion = "flowers:dandelion_yellow",
coal = "default:coal_lump",
emerald = "default:diamond",
iron_axe = "default:axe_steel",
gold_sword = "default:sword_mese",
gold_ingot = "default:gold_ingot",
gold_nugget = "default:gold_lump",
glowstone_dust = "default:mese_crystal_fragment",
redstone = "default:mese_crystal_fragment",
glass_bottle = "vessels:glass_bottle",
sugar = "default:papyrus",
wheat = "farming:wheat",
hay_bale = "farming:straw",
prismarine_shard = "default:mese_crystal_fragment",
prismarine_crystals = "default:mese_crystal",
apple = "default:apple",
golden_apple = "default:apple",
rabbit_foot = "mobs_mc:rabbit_foot",
-- Boss items
wet_sponge = "default:gold_block", -- only dropped by elder guardian; there is no equivalent block in Minetest Game
-- Other
nether_brick_block = "nether:brick",
mycelium = "ethereal:mushroom_dirt",
carrot = "farming:carrot",
potato = "farming:potato",
golden_carrot = "farming:carrot_gold",
fishing_rod = "fishing:pole_wood",
fish_raw = "fishing:fish_raw",
salmon_raw = "fishing:carp_raw",
clownfish_raw = "fishing:clownfish_raw",
pufferfish_raw = "fishing:pike_raw",
cookie = "farming:cookie",
-- TODO: Add actual ender pearl
ender_pearl = "farorb:farorb",
nether_portal = "nether:portal",
netherrack = "nether:rack",
nether_brick_block = "nether:brick",
-- Wool (Minecraft color scheme)
wool_white = "wool:white",
wool_light_grey = "wool:grey",
wool_grey = "wool:dark_grey",
wool_blue = "wool:blue",
wool_lime = "wool:green",
wool_green = "wool:dark_green",
wool_purple = "wool:violet",
wool_pink = "wool:pink",
wool_yellow = "wool:yellow",
wool_orange = "wool:orange",
wool_brown = "wool:brown",
wool_red = "wool:red",
wool_cyan = "wool:cyan",
wool_magenta = "wool:magenta",
wool_black = "wool:black",
-- Light blue intentionally missing
-- Special items
music_discs = {}, -- No music discs by default; used by creeper. Override this if your game has music discs.
}
-- Tables for attracting, feeding and breeding mobs
mobs_mc.follow = {
sheep = { mobs_mc.items.wheat },
cow = { mobs_mc.items.wheat },
chicken = { "farming:seed_wheat", "farming:seed_cotton" }, -- seeds in general
parrot = { "farming:seed_wheat", "farming:seed_cotton" }, -- seeds in general
horse = { mobs_mc.items.apple, mobs_mc.items.sugar, mobs_mc.items.wheat, mobs_mc.items.hay_bale, mobs_mc.items.golden_apple, mobs_mc.items.golden_carrot },
llama = { mobs_mc.items.wheat, mobs_mc.items.hay_bale, },
pig = { mobs_mc.items.potato, mobs_mc.items.carrot, mobs_mc.items.carrot_on_a_stick,
mobs_mc.items.apple, -- Minetest Game extra
},
rabbit = { mobs_mc.items.dandelion, mobs_mc.items.carrot, mobs_mc.items.golden_carrot, "farming_plus:carrot_item", },
ocelot = { mobs_mc.items.fish_raw, mobs_mc.items.salmon_raw, mobs_mc.items.clownfish_raw, mobs_mc.items.pufferfish_raw,
mobs_mc.items.chicken_raw, -- Minetest Game extra
},
wolf = { mobs_mc.items.bone },
dog = { mobs_mc.items.rabbit_raw, mobs_mc.items.rabbit_cooked, mobs_mc.items.mutton_raw, mobs_mc.items.mutton_cooked, mobs_mc.items.beef_raw, mobs_mc.items.beef_cooked, mobs_mc.items.chicken_raw, mobs_mc.items.chicken_cooked, mobs_mc.items.rotten_flesh,
-- Mobs Redo items
"mobs:meat", "mobs:meat_raw" },
}
-- Contents for replace_what
mobs_mc.replace = {
-- Rabbits reduce carrot growth stage by 1
rabbit = {
-- Farming Redo carrots
{"farming:carrot_8", "farming:carrot_7", 0},
{"farming:carrot_7", "farming:carrot_6", 0},
{"farming:carrot_6", "farming:carrot_5", 0},
{"farming:carrot_5", "farming:carrot_4", 0},
{"farming:carrot_4", "farming:carrot_3", 0},
{"farming:carrot_3", "farming:carrot_2", 0},
{"farming:carrot_2", "farming:carrot_1", 0},
{"farming:carrot_1", "air", 0},
-- Farming Plus carrots
{"farming_plus:carrot", "farming_plus:carrot_7", 0},
{"farming_plus:carrot_6", "farming_plus:carrot_5", 0},
{"farming_plus:carrot_5", "farming_plus:carrot_4", 0},
{"farming_plus:carrot_4", "farming_plus:carrot_3", 0},
{"farming_plus:carrot_3", "farming_plus:carrot_2", 0},
{"farming_plus:carrot_2", "farming_plus:carrot_1", 0},
{"farming_plus:carrot_1", "air", 0},
},
-- Sheep eat grass
sheep = {
-- Grass Block
{ "default:dirt_with_grass", "default:dirt", -1 },
-- “Tall Grass”
{ "default:grass_5", "air", 0 },
{ "default:grass_4", "air", 0 },
{ "default:grass_3", "air", 0 },
{ "default:grass_2", "air", 0 },
{ "default:grass_1", "air", 0 },
},
-- Silverfish populate stone, etc. with monster eggs
silverfish = {
{"default:stone", "mobs_mc:monster_egg_stone", -1},
{"default:cobble", "mobs_mc:monster_egg_cobble", -1},
{"default:mossycobble", "mobs_mc:monster_egg_mossycobble", -1},
{"default:stonebrick", "mobs_mc:monster_egg_stonebrick", -1},
{"default:stone_block", "mobs_mc:monster_egg_stone_block", -1},
},
}
-- List of nodes which endermen can take
mobs_mc.enderman_takable = {
-- Generic handling, useful for entensions
"group:enderman_takable",
-- Generic nodes
"group:sand",
"group:flower",
-- Minetest Game
"default:dirt",
"default:dirt_with_grass",
"default:dirt_with_dry_grass",
"default:dirt_with_snow",
"default:dirt_with_rainforest_litter",
"default:dirt_with_grass_footsteps",
-- FIXME: For some reason, Minetest has a Lua error when an enderman tries to place a Minetest Game cactus.
-- Maybe this is because default:cactus has rotate_and_place?
-- "default:cactus", -- TODO: Re-enable cactus when it works again
"default:gravel",
"default:clay",
"flowers:mushroom_red",
"flowers:mushroom_brown",
"tnt:tnt",
-- Nether mod
"nether:rack",
}
--[[ Table of nodes to replace when an enderman takes it.
If the enderman takes an indexed node, it the enderman will get the item in the value.
Table indexes: Original node, taken by enderman.
Table values: The item which the enderman *actually* gets
Example:
mobs_mc.enderman_node_replace = {
["default:dirt_with_dry_grass"] = "default_dirt_with_grass",
}
-- This means, if the enderman takes a dirt with dry grass, he will get a dirt with grass
-- on his hand instead.
]]
mobs_mc.enderman_replace_on_take = {} -- no replacements by default
-- A table which can be used to override block textures of blocks carried by endermen.
-- Only works for cube-shaped nodes and nodeboxes.
-- Key: itemstrings of the blocks to replace
-- Value: A table with the texture overrides (6 textures)
mobs_mc.enderman_block_texture_overrides = {
}
-- List of nodes on which mobs can spawn
mobs_mc.spawn = {
solid = { "group:cracky", "group:crumbly", "group:shovely", "group:pickaxey" }, -- spawn on "solid" nodes (this is mostly just guessing)
grassland = { mobs_mc.items.grass_block, "ethereal:prairie_dirt" },
savanna = { "default:dirt_with_dry_grass" },
grassland_savanna = { mobs_mc.items.grass_block, "default:dirt_with_dry_grass" },
desert = { "default:desert_sand", "group:sand" },
jungle = { "default:dirt_with_rainforest_litter", "default:jungleleaves", "default:junglewood", "mcl_core:jungleleaves", "mcl_core:junglewood" },
snow = { "default:snow", "default:snowblock", "default:dirt_with_snow" },
end_city = { "default:sandstonebrick", "mcl_end:purpur_block", "mcl_end:end_stone" },
wolf = { mobs_mc.items.grass_block, "default:dirt_with_rainforest_litter", "default:dirt", "default:dirt_with_snow", "default:snow", "default:snowblock" },
village = { "mg_villages:road" },
-- These probably don't need overrides
mushroom_island = { mobs_mc.items.mycelium, "mcl_core:mycelium" },
nether_fortress = { mobs_mc.items.nether_brick_block, "mcl_nether:nether_brick", },
nether = { mobs_mc.items.netherrack, "mcl_nether:netherrack", },
nether_portal = { mobs_mc.items.nether_portal, "mcl_portals:portal" },
water = { mobs_mc.items.water_source, "mcl_core:water_source", "default:water_source" },
}
-- This table contains important spawn height references for the mob spawn height.
-- Please base your mob spawn height on these numbers to keep things clean.
mobs_mc.spawn_height = {
water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld
-- Overworld boundaries (inclusive) --I adjusted this to be more reasonable
overworld_min = -64,-- -2999,
overworld_max = 31000,
-- Nether boundaries (inclusive)
nether_min = -29067,-- -3369,
nether_max = -28939,-- -3000,
-- End boundaries (inclusive)
end_min = -6200,
end_max = -6000,
}
mobs_mc.misc = {
shears_wear = 276, -- Wear to add per shears usage (238 uses)
totem_fail_nodes = {} -- List of nodes in which the totem of undying fails
}
-- Item name overrides from mobs_mc_gameconfig (if present)
if minetest.get_modpath("mobs_mc_gameconfig") and mobs_mc.override then
local tables = {"items", "follow", "replace", "spawn", "spawn_height", "misc"}
for t=1, #tables do
local tbl = tables[t]
if mobs_mc.override[tbl] then
for k, v in pairs(mobs_mc.override[tbl]) do
mobs_mc[tbl][k] = v
end
end
end
if mobs_mc.override.enderman_takable then
mobs_mc.enderman_takable = mobs_mc.override.enderman_takable
end
if mobs_mc.override.enderman_replace_on_take then
mobs_mc.enderman_replace_on_take = mobs_mc.override.enderman_replace_on_take
end
if mobs_mc.enderman_block_texture_overrides then
mobs_mc.enderman_block_texture_overrides = mobs_mc.override.enderman_block_texture_overrides
end
end

View File

@ -0,0 +1,587 @@
--MCmobs v0.5
--maikerumine
--made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes
--THIS IS THE MASTER ITEM LIST TO USE WITH DEFAULT
-- NOTE: Most strings intentionally not marked for translation, other mods already have these items.
-- TODO: Remove this file eventually, most items are already outsourced in other mods.
local S = minetest.get_translator(minetest.get_current_modname())
local c = mobs_mc.is_item_variable_overridden
-- Blaze
if c("blaze_rod") then
minetest.register_craftitem("mobs_mc:blaze_rod", {
description = "Blaze Rod",
_doc_items_longdesc = "This is a crafting component dropped from dead blazes.",
wield_image = "mcl_mobitems_blaze_rod.png",
inventory_image = "mcl_mobitems_blaze_rod.png",
})
-- Make blaze rod furnace-burnable. 1.5 times the burn time of a coal lump
local coalcraft, burntime
if minetest.get_modpath("default") then
coalcraft = minetest.get_craft_result({method="fuel", width=1, items={"default:coal_lump"}})
end
if coalcraft then
burntime = math.floor(coalcraft.time * 1.5)
end
if burntime == nil or burntime == 0 then
burntime = 60
end
minetest.register_craft({
type = "fuel",
burntime = burntime,
recipe = "mobs_mc:blaze_rod",
})
end
if c("blaze_powder") then
minetest.register_craftitem("mobs_mc:blaze_powder", {
description = "Blaze Powder",
_doc_items_longdesc = "This item is mainly used for brewing potions and crafting.",
wield_image = "mcl_mobitems_blaze_powder.png",
inventory_image = "mcl_mobitems_blaze_powder.png",
})
end
if c("blaze_rod") and c("blaze_powder") then
minetest.register_craft({
output = "mobs_mc:blaze_powder 2",
recipe = {{ "mobs_mc:blaze_rod" }},
})
end
-- Chicken
if c("chicken_raw") then
minetest.register_craftitem("mobs_mc:chicken_raw", {
description = "Raw Chicken",
_doc_items_longdesc = "Raw chicken is a food item and can be eaten safely. Cooking it will increase its nutritional value.",
inventory_image = "mcl_mobitems_chicken_raw.png",
groups = { food = 2, eatable = 2 },
on_use = minetest.item_eat(2),
})
end
if c("chicken_cooked") then
minetest.register_craftitem("mobs_mc:chicken_cooked", {
description = "Cooked Chicken",
_doc_items_longdesc = "A cooked chicken is a healthy food item which can be eaten.",
inventory_image = "mcl_mobitems_chicken_cooked.png",
groups = { food = 2, eatable = 6 },
on_use = minetest.item_eat(6),
})
end
if c("chicken_raw") and c("chicken_cooked") then
minetest.register_craft({
type = "cooking",
output = "mobs_mc:chicken_cooked",
recipe = "mobs_mc:chicken_raw",
cooktime = 5,
})
end
if c("feather") then
minetest.register_craftitem("mobs_mc:feather", {
description = "Feather",
_doc_items_longdesc = "Feathers are used in crafting and are dropped from chickens.",
inventory_image = "mcl_mobitems_feather.png",
})
end
-- Cow and mooshroom
if c("beef_raw") then
minetest.register_craftitem("mobs_mc:beef_raw", {
description = "Raw Beef",
_doc_items_longdesc = "Raw beef is the flesh from cows and can be eaten safely. Cooking it will greatly increase its nutritional value.",
inventory_image = "mcl_mobitems_beef_raw.png",
groups = { food = 2, eatable = 3 },
on_use = minetest.item_eat(3),
})
end
if c("beef_cooked") then
minetest.register_craftitem("mobs_mc:beef_cooked", {
description = "Steak",
_doc_items_longdesc = "Steak is cooked beef from cows and can be eaten.",
inventory_image = "mcl_mobitems_beef_cooked.png",
groups = { food = 2, eatable = 8 },
on_use = minetest.item_eat(8),
})
end
if c("beef_raw") and c("beef_cooked") then
minetest.register_craft({
type = "cooking",
output = "mobs_mc:beef_cooked",
recipe = "mobs_mc:beef_raw",
cooktime = 5,
})
end
if c("milk") then
-- milk
minetest.register_craftitem("mobs_mc:milk_bucket", {
description = "Milk",
_doc_items_longdesc = "Milk is a food item obtained by using a bucket on a cow.",
inventory_image = "mobs_bucket_milk.png",
groups = { food = 3, eatable = 1 },
on_use = minetest.item_eat(1, "bucket:bucket_empty"),
stack_max = 1,
})
end
if c("bowl") then
minetest.register_craftitem("mobs_mc:bowl", {
description = "Bowl",
_doc_items_longdesc = "Bowls are mainly used to hold tasty soups.",
inventory_image = "mcl_core_bowl.png",
})
minetest.register_craft({
output = "mobs_mc:bowl",
recipe = {
{ "group:wood", "", "group:wood" },
{ "", "group:wood", "", },
}
})
minetest.register_craft({
type = "fuel",
recipe = "mobs_mc:bowl",
burntime = 5,
})
end
if c("mushroom_stew") then
minetest.register_craftitem("mobs_mc:mushroom_stew", {
description = "Mushroom Stew",
_doc_items_longdesc = "Mushroom stew is a healthy soup.",
inventory_image = "farming_mushroom_stew.png",
groups = { food = 3, eatable = 6 },
on_use = minetest.item_eat(6, "mobs_mc:bowl"),
stack_max = 1,
})
end
-- Ender dragon
if c("dragon_egg") then
local dragon_egg_sounds
if minetest.get_modpath("default") then
dragon_egg_sounds = default.node_sound_stone_defaults()
end
--ender dragon
minetest.register_node("mobs_mc:dragon_egg", {
description = "Dragon Egg",
tiles = {
"mcl_end_dragon_egg.png",
"mcl_end_dragon_egg.png",
"mcl_end_dragon_egg.png",
"mcl_end_dragon_egg.png",
"mcl_end_dragon_egg.png",
"mcl_end_dragon_egg.png",
},
drawtype = "nodebox",
is_ground_content = false,
paramtype = "light",
light_source = 1,
node_box = {
type = "fixed",
fixed = {
{-0.375, -0.5, -0.375, 0.375, -0.4375, 0.375},
{-0.5, -0.4375, -0.5, 0.5, -0.1875, 0.5},
{-0.4375, -0.1875, -0.4375, 0.4375, 0, 0.4375},
{-0.375, 0, -0.375, 0.375, 0.125, 0.375},
{-0.3125, 0.125, -0.3125, 0.3125, 0.25, 0.3125},
{-0.25, 0.25, -0.25, 0.25, 0.3125, 0.25},
{-0.1875, 0.3125, -0.1875, 0.1875, 0.375, 0.1875},
{-0.125, 0.375, -0.125, 0.125, 0.4375, 0.125},
{-0.0625, 0.4375, -0.0625, 0.0625, 0.5, 0.0625},
}
},
selection_box = {
type = "regular",
},
groups = {snappy = 1, falling_node = 1, deco_block = 1, not_in_creative_inventory = 1, dig_by_piston = 1 },
sounds = dragon_egg_sounds,
-- TODO: Make dragon egg teleport on punching
})
end
local longdesc_craftitem
if minetest.get_modpath("doc_items") then
longdesc_craftitem = doc.sub.items.temp.craftitem
end
-- Enderman
if c("ender_eye") then
minetest.register_craftitem("mobs_mc:ender_eye", {
description = "Eye of Ender",
_doc_items_longdesc = longdesc_craftitem,
inventory_image = "mcl_end_ender_eye.png",
groups = { craftitem = 1 },
})
end
if c("ender_eye") and c("blaze_powder") and c("blaze_rod") then
minetest.register_craft({
type = "shapeless",
output = "mobs_mc:ender_eye",
recipe = { "mobs_mc:blaze_powder", "mobs_mc:blaze_rod"},
})
end
-- Ghast
if c("ghast_tear") then
minetest.register_craftitem("mobs_mc:ghast_tear", {
description = "Ghast Tear",
_doc_items_longdesc = "A ghast tear is an item used in potion brewing. It is dropped from dead ghasts.",
wield_image = "mcl_mobitems_ghast_tear.png",
inventory_image = "mcl_mobitems_ghast_tear.png",
groups = { brewitem = 1 },
})
end
-- Saddle
if c("saddle") then
-- Overwrite the saddle from Mobs Redo
minetest.register_craftitem(":mobs:saddle", {
description = "Saddle",
_doc_items_longdesc = "Saddles can be put on horses, donkeys, mules and pigs in order to mount them.",
_doc_items_usagehelp = "Rightclick an animal while holding a saddle to put on the saddle. You can now mount the animal by rightclicking it again.",
inventory_image = "mcl_mobitems_saddle.png",
stack_max = 1,
})
end
-- Horse Armor
local horse_armor_use = S("Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.")
-- TODO: Balance the horse armor strength, compare with MC armor strength
if c("iron_horse_armor") then
minetest.register_craftitem("mobs_mc:iron_horse_armor", {
description = S("Iron Horse Armor"),
_doc_items_longdesc = S("Iron horse armor can be worn by horses to increase their protection from harm a bit."),
_doc_items_usagehelp = horse_armor_use,
inventory_image = "mobs_mc_iron_horse_armor.png",
_horse_overlay_image = "mobs_mc_horse_armor_iron.png",
sounds = {
_mcl_armor_equip = "mcl_armor_equip_iron",
},
stack_max = 1,
groups = { horse_armor = 85 },
})
end
if c("gold_horse_armor") then
minetest.register_craftitem("mobs_mc:gold_horse_armor", {
description = S("Golden Horse Armor"),
_doc_items_longdesc = S("Golden horse armor can be worn by horses to increase their protection from harm."),
_doc_items_usagehelp = horse_armor_use,
inventory_image = "mobs_mc_gold_horse_armor.png",
_horse_overlay_image = "mobs_mc_horse_armor_gold.png",
sounds = {
_mcl_armor_equip = "mcl_armor_equip_iron",
},
stack_max = 1,
groups = { horse_armor = 60 },
})
end
if c("diamond_horse_armor") then
minetest.register_craftitem("mobs_mc:diamond_horse_armor", {
description = S("Diamond Horse Armor"),
_doc_items_longdesc = S("Diamond horse armor can be worn by horses to greatly increase their protection from harm."),
_doc_items_usagehelp = horse_armor_use,
inventory_image = "mobs_mc_diamond_horse_armor.png",
_horse_overlay_image = "mobs_mc_horse_armor_diamond.png",
sounds = {
_mcl_armor_equip = "mcl_armor_equip_diamond",
},
stack_max = 1,
groups = { horse_armor = 45 },
})
end
-- Pig
if c("porkchop_raw") then
minetest.register_craftitem("mobs_mc:porkchop_raw", {
description = "Raw Porkchop",
_doc_items_longdesc = "A raw porkchop is the flesh from a pig and can be eaten safely. Cooking it will greatly increase its nutritional value.",
inventory_image = "mcl_mobitems_porkchop_raw.png",
groups = { food = 2, eatable = 3 },
on_use = minetest.item_eat(3),
})
end
if c("porkchop_cooked") then
minetest.register_craftitem("mobs_mc:porkchop_cooked", {
description = "Cooked Porkchop",
_doc_items_longdesc = "Cooked porkchop is the cooked flesh of a pig and is used as food.",
inventory_image = "mcl_mobitems_porkchop_cooked.png",
groups = { food = 2, eatable = 8 },
on_use = minetest.item_eat(8),
})
end
if c("porkchop_raw") and c("porkchop_cooked") then
minetest.register_craft({
type = "cooking",
output = "mobs_mc:porkchop_cooked",
recipe = "mobs_mc:porkchop_raw",
cooktime = 5,
})
end
if c("carrot_on_a_stick") then
minetest.register_tool("mobs_mc:carrot_on_a_stick", {
description = "Carrot on a Stick",
_doc_items_longdesc = "A carrot on a stick can be used on saddled pigs to ride them. Pigs will also follow anyone who holds a carrot on a stick near them.",
_doc_items_usagehelp = "Rightclick a saddled pig with the carrot on a stick to mount it. You can now ride it like a horse.",
wield_image = "mcl_mobitems_carrot_on_a_stick.png",
inventory_image = "mcl_mobitems_carrot_on_a_stick.png",
sounds = { breaks = "default_tool_breaks" },
})
end
-- Poor-man's recipes for carrot on a stick
if c("carrot_on_a_stick") and c("stick") and c("string") and minetest.get_modpath("farming") then
minetest.register_craft({
output = "mobs_mc:carrot_on_a_stick",
recipe = {
{"", "", "farming:string" },
{"", "group:stick", "farming:string" },
{"group:stick", "", "farming:bread" },
}
})
-- FIXME: Identify correct farming mod (check if it includes the carrot item)
minetest.register_craft({
output = "mobs_mc:carrot_on_a_stick",
recipe = {
{"", "", "farming:string" },
{"", "group:stick", "farming:string" },
{"group:stick", "", "farming:carrot" },
}
})
end
if c("carrot_on_a_stick") and c("stick") and c("string") and minetest.get_modpath("fishing") and minetest.get_modpath("farming") then
minetest.register_craft({
type = "shapeless",
output = "mobs_mc:carrot_on_a_stick",
recipe = {"fishing:pole_wood", "farming:carrot"},
})
end
-- Rabbit
if c("rabbit_raw") then
minetest.register_craftitem("mobs_mc:rabbit_raw", {
description = "Raw Rabbit",
_doc_items_longdesc = "Raw rabbit is a food item from a dead rabbit. It can be eaten safely. Cooking it will increase its nutritional value.",
inventory_image = "mcl_mobitems_rabbit_raw.png",
groups = { food = 2, eatable = 3 },
on_use = minetest.item_eat(3),
})
end
if c("rabbit_cooked") then
minetest.register_craftitem("mobs_mc:rabbit_cooked", {
description = "Cooked Rabbit",
_doc_items_longdesc = "This is a food item which can be eaten.",
inventory_image = "mcl_mobitems_rabbit_cooked.png",
groups = { food = 2, eatable = 5 },
on_use = minetest.item_eat(5),
})
end
if c("rabbit_raw") and c("rabbit_cooked") then
minetest.register_craft({
type = "cooking",
output = "mobs_mc:rabbit_cooked",
recipe = "mobs_mc:rabbit_raw",
cooktime = 5,
})
end
if c("rabbit_hide") then
minetest.register_craftitem("mobs_mc:rabbit_hide", {
description = "Rabbit Hide",
_doc_items_longdesc = "Rabbit hide is used to create leather.",
inventory_image = "mcl_mobitems_rabbit_hide.png"
})
end
if c("leather") and c("rabbit_hide") then
minetest.register_craft({
output = "mobs:leather",
recipe = {
{ "mobs_mc:rabbit_hide", "mobs_mc:rabbit_hide" },
{ "mobs_mc:rabbit_hide", "mobs_mc:rabbit_hide" },
}
})
end
if c("rabbit_foot") then
minetest.register_craftitem("mobs_mc:rabbit_foot", {
description = "Rabbit's Foot",
_doc_items_longdesc = "This item is used in brewing.",
inventory_image = "mcl_mobitems_rabbit_foot.png"
})
end
-- Sheep
if c("mutton_raw") then
minetest.register_craftitem("mobs_mc:mutton_raw", {
description = "Raw Mutton",
_doc_items_longdesc = "Raw mutton is the flesh from a sheep and can be eaten safely. Cooking it will greatly increase its nutritional value.",
inventory_image = "mcl_mobitems_mutton_raw.png",
groups = { food = 2, eatable = 4 },
on_use = minetest.item_eat(4),
})
end
if c("mutton_cooked") then
minetest.register_craftitem("mobs_mc:mutton_cooked", {
description = "Cooked Mutton",
_doc_items_longdesc = "Cooked mutton is the cooked flesh from a sheep and is used as food.",
inventory_image = "mcl_mobitems_mutton_cooked.png",
groups = { food = 2, eatable = 8 },
on_use = minetest.item_eat(8),
})
end
if c("mutton_raw") and c("mutton_cooked") then
minetest.register_craft({
type = "cooking",
output = "mobs_mc:mutton_cooked",
recipe = "mobs_mc:mutton_raw",
cooktime = 5,
})
end
-- Shulker
if c("shulker_shell") then
minetest.register_craftitem("mobs_mc:shulker_shell", {
description = "Shulker Shell",
_doc_items_longdesc = "Shulker shells are used in crafting. They are dropped from dead shulkers.",
inventory_image = "mcl_mobitems_shulker_shell.png",
groups = { craftitem = 1 },
})
end
-- Magma cube
if c("magma_cream") then
minetest.register_craftitem("mobs_mc:magma_cream", {
description = "Magma Cream",
_doc_items_longdesc = "Magma cream is a crafting component.",
wield_image = "mcl_mobitems_magma_cream.png",
inventory_image = "mcl_mobitems_magma_cream.png",
groups = { brewitem = 1 },
})
end
-- Slime
if c("slimeball") then
minetest.register_craftitem("mobs_mc:slimeball", {
description = "Slimeball",
_doc_items_longdesc = "Slimeballs are used in crafting. They are dropped from slimes.",
inventory_image = "mcl_mobitems_slimeball.png"
})
if minetest.get_modpath("mesecons_materials") then
minetest.register_craft({
output = "mesecons_materials:glue",
recipe = {{ "mobs_mc:slimeball" }},
})
end
end
-- Spider
if c("spider_eye") then
minetest.register_craftitem("mobs_mc:spider_eye", {
description = "Spider Eye",
_doc_items_longdesc = "Spider eyes are used mainly in crafting and brewing. Spider eyes can be eaten, but they poison you and reduce your health by 2 hit points.",
inventory_image = "mcl_mobitems_spider_eye.png",
wield_image = "mcl_mobitems_spider_eye.png",
-- Simplified poisonous food
groups = { food = 2, eatable = -2 },
on_use = minetest.item_eat(-2),
})
end
-- Evoker
if c("totem") then
-- Totem of Undying
minetest.register_craftitem("mobs_mc:totem", {
description = S("Totem of Undying"),
_tt_help = minetest.colorize(mcl_colors.GREEN, S("Protects you from death while wielding it")),
_doc_items_longdesc = S("A totem of undying is a rare artifact which may safe you from certain death."),
_doc_items_usagehelp = S("The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however."),
inventory_image = "mcl_totems_totem.png",
wield_image = "mcl_totems_totem.png",
stack_max = 1,
groups = {combat_item = 1, offhand_item = 1},
})
end
-- Rotten flesh
if c("rotten_flesh") then
minetest.register_craftitem("mobs_mc:rotten_flesh", {
description = "Rotten Flesh",
_doc_items_longdesc = "Yuck! This piece of flesh clearly has seen better days. Eating it will only poison you and reduces your health by 4 hit points. But tamed wolves can eat it just fine.",
inventory_image = "mcl_mobitems_rotten_flesh.png",
-- Simplified poisonous food
groups = { food = 2, eatable = -4 },
on_use = minetest.item_eat(-4),
})
end
-- Misc.
if c("nether_star") then
minetest.register_craftitem("mobs_mc:nether_star", {
description = "Nether Star",
_doc_items_longdesc = "A nether star is a crafting component. It is dropped from the Wither.",
inventory_image = "mcl_mobitems_nether_star.png"
})
end
if c("snowball") and minetest.get_modpath("default") then
minetest.register_craft({
output = "mobs_mc:snowball 2",
recipe = {
{"default:snow"},
},
})
minetest.register_craft({
output = "default:snow 2",
recipe = {
{"mobs_mc:snowball", "mobs_mc:snowball"},
{"mobs_mc:snowball", "mobs_mc:snowball"},
},
})
-- Change the appearance of default snow to avoid confusion with snowball
minetest.override_item("default:snow", {
inventory_image = "",
wield_image = "",
})
end
if c("bone") then
minetest.register_craftitem("mobs_mc:bone", {
description = "Bone",
_doc_items_longdesc = "Bones can be used to tame wolves so they will protect you. They are also useful as a crafting ingredient.",
_doc_items_usagehelp = "Hold the bone in your hand near wolves to attract them. Rightclick the wolf to give it a bone and tame it.",
inventory_image = "mcl_mobitems_bone.png"
})
if minetest.get_modpath("bones") then
minetest.register_craft({
output = "mobs_mc:bone 3",
recipe = {{ "bones:bones" }},
})
end
end

View File

@ -0,0 +1,402 @@
--MCmobs v0.5
--maikerumine
--made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes
-- NOTE: Strings intentionally not marked for translation, other mods already have these items.
-- TODO: Remove this file eventually, all items here are already outsourced in other mods.
local S = minetest.get_translator("mobs_mc")
--maikerumines throwing code
--arrow (weapon)
local c = mobs_mc.is_item_variable_overridden
minetest.register_node("mobs_mc:arrow_box", {
drawtype = "nodebox",
is_ground_content = false,
node_box = {
type = "fixed",
fixed = {
-- Shaft
{-6.5/17, -1.5/17, -1.5/17, -4.5/17, 1.5/17, 1.5/17},
{-4.5/17, -0.5/17, -0.5/17, 5.5/17, 0.5/17, 0.5/17},
{5.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17},
-- Tip
{-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17},
{-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17},
-- Fletching
{6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17},
{7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17},
{7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17},
{6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17},
{7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17},
{8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17},
{8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17},
{7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17},
}
},
tiles = {"mcl_bows_arrow.png^[transformFX", "mcl_bows_arrow.png^[transformFX", "mcl_bows_arrow_back.png", "mcl_bows_arrow_front.png", "mcl_bows_arrow.png", "mcl_bows_arrow.png^[transformFX"},
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
groups = {not_in_creative_inventory=1, dig_immediate=3},
node_placement_prediction = "",
on_construct = function(pos)
minetest.log("error", "[mobs_mc] Trying to construct mobs_mc:arrow_box at "..minetest.pos_to_string(pos))
minetest.remove_node(pos)
end,
drop = "",
})
local THROWING_ARROW_ENTITY={
physical = false,
timer=0,
visual = "wielditem",
visual_size = {x=0.1, y=0.1},
textures = {"mobs_mc:arrow_box"},
velocity = 10,
lastpos={},
collisionbox = {0,0,0,0,0,0},
}
--ARROW CODE
THROWING_ARROW_ENTITY.on_step = function(self, dtime)
self.timer=self.timer+dtime
local pos = self.object:get_pos()
local node = minetest.get_node(pos)
minetest.add_particle({
pos = pos,
velocity = {x=0, y=0, z=0},
acceleration = {x=0, y=0, z=0},
expirationtime = .3,
size = 1,
collisiondetection = false,
vertical = false,
texture = "mobs_mc_arrow_particle.png",
})
if self.timer>0.2 then
local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1.5)
for k, obj in pairs(objs) do
if obj:get_luaentity() ~= nil then
if obj:get_luaentity().name ~= "mobs_mc:arrow_entity" and obj:get_luaentity().name ~= "__builtin:item" then
local damage = 3
minetest.sound_play("damage", {pos = pos}, true)
obj:punch(self.object, 1.0, {
full_punch_interval=1.0,
damage_groups={fleshy=damage},
}, nil)
self.object:remove()
end
else
local damage = 3
minetest.sound_play("damage", {pos = pos}, true)
obj:punch(self.object, 1.0, {
full_punch_interval=1.0,
damage_groups={fleshy=damage},
}, nil)
self.object:remove()
end
end
end
if self.lastpos.x~=nil then
if node.name ~= "air" then
minetest.sound_play("bowhit1", {pos = pos}, true)
minetest.add_item(self.lastpos, 'mobs_mc:arrow')
self.object:remove()
end
end
self.lastpos={x=pos.x, y=pos.y, z=pos.z}
end
minetest.register_entity("mobs_mc:arrow_entity", THROWING_ARROW_ENTITY)
local arrows = {
{"mobs_mc:arrow", "mobs_mc:arrow_entity" },
}
local throwing_shoot_arrow = function(itemstack, player)
for _,arrow in pairs(arrows) do
if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow[1] then
if not minetest.is_creative_enabled(player:get_player_name()) then
player:get_inventory():remove_item("main", arrow[1])
end
local playerpos = player:get_pos()
local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, arrow[2]) --mc
local dir = player:get_look_dir()
obj:set_velocity({x=dir.x*22, y=dir.y*22, z=dir.z*22})
obj:set_acceleration({x=dir.x*-3, y=-10, z=dir.z*-3})
obj:set_yaw(player:get_look_yaw()+math.pi)
minetest.sound_play("throwing_sound", {pos=playerpos}, true)
if obj:get_luaentity().player == "" then
obj:get_luaentity().player = player
end
obj:get_luaentity().node = player:get_inventory():get_stack("main", 1):get_name()
return true
end
end
return false
end
if c("arrow") then
minetest.register_craftitem("mobs_mc:arrow", {
description = "Arrow",
_doc_items_longdesc = "Arrows are ammunition for bows.",
_doc_items_usagehelp = "To use arrows as ammunition for a bow, put them in the inventory slot following the bow. Slots are counted left to right, top to bottom.",
inventory_image = "mcl_bows_arrow_inv.png",
})
end
if c("arrow") and c("flint") and c("feather") and c("stick") then
minetest.register_craft({
output = 'mobs_mc:arrow 4',
recipe = {
{mobs_mc.items.flint},
{mobs_mc.items.stick},
{mobs_mc.items.feather},
}
})
end
if c("bow") then
minetest.register_tool("mobs_mc:bow_wood", {
description = "Bow",
_doc_items_longdesc = "Bows are ranged weapons to shoot arrows at your foes.",
_doc_items_usagehelp = "To use the bow, you first need to have at least one arrow in slot following the bow. Leftclick to shoot. Each hit deals 3 damage.",
inventory_image = "mcl_bows_bow.png",
on_use = function(itemstack, user, pointed_thing)
if throwing_shoot_arrow(itemstack, user, pointed_thing) then
if not minetest.is_creative_enabled(user:get_player_name()) then
itemstack:add_wear(65535/50)
end
end
return itemstack
end,
})
minetest.register_craft({
output = 'mobs_mc:bow_wood',
recipe = {
{mobs_mc.items.string, mobs_mc.items.stick, ''},
{mobs_mc.items.string, '', mobs_mc.items.stick},
{mobs_mc.items.string, mobs_mc.items.stick, ''},
}
})
end
local how_to_throw = "Hold it in your and and leftclick to throw."
-- egg throwing item
-- egg entity
if c("egg") then
local egg_GRAVITY = 9
local egg_VELOCITY = 19
mobs:register_arrow("mobs_mc:egg_entity", {
visual = "sprite",
visual_size = {x=.5, y=.5},
textures = {"mobs_chicken_egg.png"},
velocity = egg_VELOCITY,
hit_player = function(self, player)
player:punch(minetest.get_player_by_name(self.playername) or self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {},
}, nil)
end,
hit_mob = function(self, mob)
mob:punch(minetest.get_player_by_name(self.playername) or self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {},
}, nil)
end,
hit_node = function(self, pos, node)
if math.random(1, 10) > 1 then
return
end
pos.y = pos.y + 1
local nod = minetest.get_node_or_nil(pos)
if not nod
or not minetest.registered_nodes[nod.name]
or minetest.registered_nodes[nod.name].walkable == true then
return
end
local mob = minetest.add_entity(pos, "mobs_mc:chicken")
local ent2 = mob:get_luaentity()
mob:set_properties({
visual_size = {
x = ent2.base_size.x / 2,
y = ent2.base_size.y / 2
},
collisionbox = {
ent2.base_colbox[1] / 2,
ent2.base_colbox[2] / 2,
ent2.base_colbox[3] / 2,
ent2.base_colbox[4] / 2,
ent2.base_colbox[5] / 2,
ent2.base_colbox[6] / 2
},
})
ent2.child = true
ent2.tamed = true
ent2.owner = self.playername
end
})
-- shoot egg
local mobs_shoot_egg = function (item, player, pointed_thing)
local playerpos = player:get_pos()
minetest.sound_play("default_place_node_hard", {
pos = playerpos,
gain = 1.0,
max_hear_distance = 5,
}, true)
local obj = minetest.add_entity({
x = playerpos.x,
y = playerpos.y +1.5,
z = playerpos.z
}, "mobs_mc:egg_entity")
local ent = obj:get_luaentity()
local dir = player:get_look_dir()
ent.velocity = egg_VELOCITY -- needed for api internal timing
ent.switch = 1 -- needed so that egg doesn't despawn straight away
obj:set_velocity({
x = dir.x * egg_VELOCITY,
y = dir.y * egg_VELOCITY,
z = dir.z * egg_VELOCITY
})
obj:set_acceleration({
x = dir.x * -3,
y = -egg_GRAVITY,
z = dir.z * -3
})
-- pass player name to egg for chick ownership
local ent2 = obj:get_luaentity()
ent2.playername = player:get_player_name()
if not minetest.is_creative_enabled(player:get_player_name()) then
item:take_item()
end
return item
end
minetest.register_craftitem("mobs_mc:egg", {
description = "Egg",
_doc_items_longdesc = "Eggs can be thrown and break on impact. There is a small chance that 1 or even 4 chicks will pop out",
_doc_items_usagehelp = how_to_throw,
inventory_image = "mobs_chicken_egg.png",
on_use = mobs_shoot_egg,
})
end
-- Snowball
local snowball_GRAVITY = 9
local snowball_VELOCITY = 19
mobs:register_arrow("mobs_mc:snowball_entity", {
visual = "sprite",
visual_size = {x=.5, y=.5},
textures = {"mcl_throwing_snowball.png"},
velocity = snowball_VELOCITY,
hit_player = function(self, player)
-- FIXME: No knockback
player:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {},
}, nil)
end,
hit_mob = function(self, mob)
-- Hurt blazes, but not damage to anything else
local dmg = {}
if mob:get_luaentity().name == "mobs_mc:blaze" then
dmg = {fleshy = 3}
end
-- FIXME: No knockback
mob:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = dmg,
}, nil)
end,
})
if c("snowball") then
-- shoot snowball
local mobs_shoot_snowball = function (item, player, pointed_thing)
local playerpos = player:get_pos()
local obj = minetest.add_entity({
x = playerpos.x,
y = playerpos.y +1.5,
z = playerpos.z
}, "mobs_mc:snowball_entity")
local ent = obj:get_luaentity()
local dir = player:get_look_dir()
ent.velocity = snowball_VELOCITY -- needed for api internal timing
ent.switch = 1 -- needed so that egg doesn't despawn straight away
obj:set_velocity({
x = dir.x * snowball_VELOCITY,
y = dir.y * snowball_VELOCITY,
z = dir.z * snowball_VELOCITY
})
obj:set_acceleration({
x = dir.x * -3,
y = -snowball_GRAVITY,
z = dir.z * -3
})
-- pass player name to egg for chick ownership
local ent2 = obj:get_luaentity()
ent2.playername = player:get_player_name()
if not minetest.is_creative_enabled(player:get_player_name()) then
item:take_item()
end
return item
end
-- Snowball
minetest.register_craftitem("mobs_mc:snowball", {
description = "Snowball",
_doc_items_longdesc = "Snowballs can be thrown at your enemies. A snowball deals 3 damage to blazes, but is harmless to anything else.",
_doc_items_usagehelp = how_to_throw,
inventory_image = "mcl_throwing_snowball.png",
on_use = mobs_shoot_snowball,
})
end
--end maikerumine code

View File

@ -0,0 +1,65 @@
local pr = PseudoRandom(os.time()*5)
local offsets = {}
for x=-2, 2 do
for z=-2, 2 do
table.insert(offsets, {x=x, y=0, z=z})
end
end
--[[ Periodically check and teleport mob to owner if not sitting (order ~= "sit") and
the owner is too far away. To be used with do_custom. Note: Optimized for mobs smaller than 1×1×1.
Larger mobs might have space problems after teleportation.
* dist: Minimum required distance from owner to teleport. Default: 12
* teleport_check_interval: Optional. Interval in seconds to check the mob teleportation. Default: 4 ]]
mobs_mc.make_owner_teleport_function = function(dist, teleport_check_interval)
return function(self, dtime)
-- No teleportation if no owner or if sitting
if not self.owner or self.order == "sit" then
return
end
if not teleport_check_interval then
teleport_check_interval = 4
end
if not dist then
dist = 12
end
if self._teleport_timer == nil then
self._teleport_timer = teleport_check_interval
return
end
self._teleport_timer = self._teleport_timer - dtime
if self._teleport_timer <= 0 then
self._teleport_timer = teleport_check_interval
local mob_pos = self.object:get_pos()
local owner = minetest.get_player_by_name(self.owner)
if not owner then
-- No owner found, no teleportation
return
end
local owner_pos = owner:get_pos()
local dist_from_owner = vector.distance(owner_pos, mob_pos)
if dist_from_owner > dist then
-- Check for nodes below air in a 5×1×5 area around the owner position
local check_offsets = table.copy(offsets)
-- Attempt to place mob near player. Must be placed on walkable node below a non-walkable one. Place inside that air node.
while #check_offsets > 0 do
local r = pr:next(1, #check_offsets)
local telepos = vector.add(owner_pos, check_offsets[r])
local telepos_below = {x=telepos.x, y=telepos.y-1, z=telepos.z}
table.remove(check_offsets, r)
-- Long story short, spawn on a platform
local trynode = minetest.registered_nodes[minetest.get_node(telepos).name]
local trybelownode = minetest.registered_nodes[minetest.get_node(telepos_below).name]
if trynode and not trynode.walkable and
trybelownode and trybelownode.walkable then
-- Correct position found! Let's teleport.
self.object:set_pos(telepos)
return
end
end
end
end
end
end

View File

@ -0,0 +1,62 @@
--MC Heads for minetest
--maikerumine
-- NOTE: Strings intentionally not marked for translation, other mods already have these items.
-- TODO: Remove this file eventually, all items here are already outsourced in other mods.
local S = minetest.get_translator("mobs_mc")
-- Heads system
local sounds
if minetest.get_modpath("default") then
sounds = default.node_sound_defaults({
footstep = {name="default_hard_footstep", gain=0.3}
})
end
local function addhead(mobname, desc, longdesc)
if not mobs_mc.is_item_variable_overridden("head_"..mobname) then
return
end
minetest.register_node("mobs_mc:head_"..mobname, {
description = desc,
_doc_items_longdesc = longdesc,
drawtype = "nodebox",
is_ground_content = false,
node_box = {
type = "fixed",
fixed = {
{ -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, },
},
},
groups = { oddly_breakable_by_hand=3, head=1, },
-- The head textures are based off the textures of an actual mob.
-- FIXME: This code assumes 16×16 textures for the mob textures!
tiles = {
-- Note: bottom texture is overlaid over top texture to get rid of possible transparency.
-- This is required for skeleton skull and wither skeleton skull.
"[combine:16x16:-4,4=mobs_mc_"..mobname..".png", -- top
"([combine:16x16:-4,4=mobs_mc_"..mobname..".png)^([combine:16x16:-12,4=mobs_mc_"..mobname..".png)", -- bottom
"[combine:16x16:-12,0=mobs_mc_"..mobname..".png", -- left
"[combine:16x16:4,0=mobs_mc_"..mobname..".png", -- right
"[combine:16x16:-20,0=mobs_mc_"..mobname..".png", -- back
"[combine:16x16:-4,0=mobs_mc_"..mobname..".png", -- front
},
paramtype = "light",
paramtype2 = "facedir",
sunlight_propagates = true,
walkable = true,
sounds = sounds,
selection_box = {
type = "fixed",
fixed = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, },
},
})
end
-- Add heads
addhead("zombie", "Zombie Head", "A zombie head is a small decorative block which resembles the head of a zombie.")
addhead("creeper", "Creeper Head", "A creeper head is a small decorative block which resembles the head of a creeper.")
addhead("skeleton", "Skeleton Skull", "A skeleton skull is a small decorative block which resembles the skull of a skeleton.")
addhead("wither_skeleton", "Wither Skeleton Skull", "A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton.")

View File

@ -0,0 +1,20 @@
local function is_forbidden_node(pos, node)
node = node or minetest.get_node(pos)
return minetest.get_item_group(node.name, "stair") > 0 or minetest.get_item_group(node.name, "slab") > 0 or minetest.get_item_group(node.name, "carpet") > 0
end
function mobs:spawn_abm_check(pos, node, name)
-- Don't spawn monsters on mycelium
if (node.name == "mcl_core:mycelium" or node.name == "mcl_core:mycelium_snow") and minetest.registered_entities[name].type == "monster" then
return true
--Don't Spawn mobs on stairs, slabs, or carpets
elseif is_forbidden_node(pos, node) or is_forbidden_node(vector.add(pos, vector.new(0, 1, 0))) then
return true
-- Spawn on opaque or liquid nodes
elseif minetest.get_item_group(node.name, "opaque") ~= 0 or minetest.registered_nodes[node.name].liquidtype ~= "none" or node.name == "mcl_core:grass_path" then
return false
end
-- Reject everything else
return true
end

View File

@ -75,7 +75,6 @@ Origin of those models:
* `mobs_mc_mushroom_brown.png` (CC0)
* “Spawn egg” textures (`mobs_mc_spawn_icon_*`) by 22i
* Llama decor (carpet) textures (`mobs_mc_llama_decor_*`) by erlehmann and rudzik8
* Any other texture not mentioned here are licensed under the MIT License
## Sounds

View File

@ -17,6 +17,11 @@ This mod adds mobs which closely resemble the mobs from the game Minecraft, vers
* Code: GNU General Public License, version 3 (see `LICENSE`)
* Media: MIT, CC0, CC BY 3.0 CC BY-SA 4.0, LGPLv2.1, GPLv3. See `LICENSE_media.md` for details
## Useful information for developers
### Game integration
Want to include this mod in your game? Read `gameconfig.md`.
### Links
* [`mobs_mc`](https://github.com/maikerumine/mobs_mc)

View File

@ -0,0 +1,39 @@
--###################
--################### AGENT - seemingly unused
--###################
local S = minetest.get_translator("mobs_mc")
mobs:register_mob("mobs_mc:agent", {
type = "npc",
spawn_class = "passive",
passive = true,
hp_min = 20,
hp_max = 20,
armor = 100,
collisionbox = {-0.35, -0.01, -0.35, 0.35, 1, 0.35},
visual = "mesh",
mesh = "mobs_mc_agent.b3d",
textures = {
{"mobs_mc_agent.png"},
},
-- TODO: sounds
visual_size = {x=3, y=3},
walk_chance = 0,
walk_velocity = 0.6,
run_velocity = 2,
jump = true,
animation = {
stand_speed = 25,
walk_speed = 25,
run_speed = 50,
stand_start = 20,
stand_end = 60,
walk_start = 0,
walk_end = 20,
run_start = 0,
run_end = 20,
},
})
mobs:register_egg("mobs_mc:agent", S("Agent"), "mobs_mc_spawn_icon_agent.png", 0)

View File

@ -2,12 +2,11 @@
local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:bat", {
mobs:register_mob("mobs_mc:bat", {
description = S("Bat"),
type = "animal",
spawn_class = "ambient",
can_despawn = true,
spawn_in_group = 8,
passive = true,
hp_min = 6,
hp_max = 6,
@ -66,7 +65,7 @@ else
end
-- Spawn on solid blocks at or below Sea level and the selected light level
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:bat",
"overworld",
"ground",
@ -139,9 +138,9 @@ maxlight,
20,
5000,
2,
mcl_vars.mg_overworld_min,
mobs_mc.water_level-1)
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.water-1)
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:bat", S("Bat"), "#4c3e30", "#0f0f0f", 0)
mobs:register_egg("mobs_mc:bat", S("Bat"), "mobs_mc_spawn_icon_bat.png", 0)

View File

@ -12,12 +12,10 @@ local mod_target = minetest.get_modpath("mcl_target")
--###################
mcl_mobs:register_mob("mobs_mc:blaze", {
mobs:register_mob("mobs_mc:blaze", {
description = S("Blaze"),
type = "monster",
spawn_class = "hostile",
spawn_in_group_min = 2,
spawn_in_group = 3,
hp_min = 20,
hp_max = 20,
xp_min = 10,
@ -26,12 +24,6 @@ mcl_mobs:register_mob("mobs_mc:blaze", {
rotate = -180,
visual = "mesh",
mesh = "mobs_mc_blaze.b3d",
head_swivel = "head.control",
bone_eye_height = 4,
head_eye_height = 3.5,
curiosity = 10,
head_yaw_offset = 180,
head_pitch_multiplier=-1,
textures = {
{"mobs_mc_blaze.png"},
},
@ -49,7 +41,7 @@ mcl_mobs:register_mob("mobs_mc:blaze", {
reach = 2,
pathfinding = 1,
drops = {
{name = "mcl_mobitems:blaze_rod",
{name = mobs_mc.items.blaze_rod,
chance = 1,
min = 0,
max = 1,
@ -139,7 +131,7 @@ mcl_mobs:register_mob("mobs_mc:blaze", {
end,
})
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:blaze",
"nether",
"ground",
@ -149,11 +141,11 @@ minetest.LIGHT_MAX+1,
30,
5000,
3,
mcl_vars.mg_nether_min,
mcl_vars.mg_nether_max)
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- Blaze fireball
mcl_mobs:register_arrow("mobs_mc:blaze_fireball", {
mobs:register_arrow("mobs_mc:blaze_fireball", {
visual = "sprite",
visual_size = {x = 0.3, y = 0.3},
textures = {"mcl_fire_fire_charge.png"},
@ -189,7 +181,7 @@ mcl_mobs:register_arrow("mobs_mc:blaze_fireball", {
-- Node hit, make fire
hit_node = function(self, pos, node)
if node == "air" then
minetest.set_node(pos, {name = "mcl_fire:fire"})
minetest.set_node(pos, {name = mobs_mc.items.fire})
else
if self._shot_from_dispenser and mod_target and node == "mcl_target:target_off" then
mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks
@ -201,11 +193,11 @@ mcl_mobs:register_arrow("mobs_mc:blaze_fireball", {
-- Set fire if node is air, or a replacable flammable node (e.g. a plant)
if crashnode.name == "air" or
(cndef and cndef.buildable_to and minetest.get_item_group(crashnode.name, "flammable") >= 1) then
minetest.set_node(crashpos, {name = "mcl_fire:fire"})
minetest.set_node(crashpos, {name = mobs_mc.items.fire})
end
end
end
})
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:blaze", S("Blaze"), "#f6b201", "#fff87e", 0)
mobs:register_egg("mobs_mc:blaze", S("Blaze"), "mobs_mc_spawn_icon_blaze.png", 0)

View File

@ -8,7 +8,7 @@ local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:chicken", {
mobs:register_mob("mobs_mc:chicken", {
description = S("Chicken"),
type = "animal",
spawn_class = "passive",
@ -20,28 +20,22 @@ mcl_mobs:register_mob("mobs_mc:chicken", {
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.69, 0.2},
runaway = true,
floats = 1,
head_swivel = "head.control",
bone_eye_height = 4,
head_eye_height = 1.5,
horrizonatal_head_height = -.3,
curiosity = 10,
head_yaw="z",
visual_size = {x=1,y=1},
visual = "mesh",
mesh = "mobs_mc_chicken.b3d",
textures = {
{"mobs_mc_chicken.png"},
},
visual_size = {x=2.2, y=2.2},
makes_footstep_sound = true,
walk_velocity = 1,
drops = {
{name = "mcl_mobitems:chicken",
{name = mobs_mc.items.chicken_raw,
chance = 1,
min = 1,
max = 1,
looting = "common",},
{name = "mcl_mobitems:feather",
{name = mobs_mc.items.feather,
chance = 1,
min = 0,
max = 2,
@ -64,28 +58,20 @@ mcl_mobs:register_mob("mobs_mc:chicken", {
distance = 16,
},
animation = {
stand_speed = 25, walk_speed = 25, run_speed = 50,
stand_start = 0, stand_end = 0,
walk_start = 0, walk_end = 20, walk_speed = 25,
run_start = 0, run_end = 20, run_speed = 50,
},
child_animations = {
stand_start = 31, stand_end = 31,
walk_start = 31, walk_end = 51, walk_speed = 37,
run_start = 31, run_end = 51, run_speed = 75,
},
follow = {
"mcl_farming:wheat_seeds",
"mcl_farming:melon_seeds",
"mcl_farming:pumpkin_seeds",
"mcl_farming:beetroot_seeds",
walk_start = 0, walk_end = 40,
run_start = 0, run_end = 40,
},
follow = mobs_mc.follow.chicken,
view_range = 16,
fear_height = 4,
on_rightclick = function(self, clicker)
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
if mcl_mobs:protect(self, clicker) then return end
if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end
if mobs:feed_tame(self, clicker, 1, true, true) then return end
if mobs:protect(self, clicker) then return end
if mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end
end,
do_custom = function(self, dtime)
@ -103,7 +89,7 @@ mcl_mobs:register_mob("mobs_mc:chicken", {
local pos = self.object:get_pos()
minetest.add_item(pos, "mcl_throwing:egg")
minetest.add_item(pos, mobs_mc.items.egg)
minetest.sound_play("mobs_mc_chicken_lay_egg", {
pos = pos,
@ -115,7 +101,7 @@ mcl_mobs:register_mob("mobs_mc:chicken", {
})
--spawn
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:chicken",
"overworld",
"ground",
@ -131,6 +117,8 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach",
"ExtremeHillsM",
"ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach",
"Plains",
"Plains_beach",
"SunflowerPlains",
@ -159,8 +147,8 @@ mcl_mobs:spawn_specific(
minetest.LIGHT_MAX+1,
30, 17000,
3,
mobs_mc.water_level,
mcl_vars.mg_overworld_max)
mobs_mc.spawn_height.water,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:chicken", S("Chicken"), "#a1a1a1", "#ff0000", 0)
mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0)

View File

@ -1,274 +0,0 @@
--MCmobs v0.4
--maikerumine
--made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes
local pi = math.pi
local atann = math.atan
local atan = function(x)
if not x or x ~= x then
return 0
else
return atann(x)
end
end
local dir_to_pitch = function(dir)
local dir2 = vector.normalize(dir)
local xz = math.abs(dir.x) + math.abs(dir.z)
return -math.atan2(-dir.y, xz)
end
local function degrees(rad)
return rad * 180.0 / math.pi
end
local S = minetest.get_translator(minetest.get_current_modname())
--###################
--################### cod
--###################
local cod = {
type = "animal",
spawn_class = "water",
can_despawn = true,
passive = true,
hp_min = 3,
hp_max = 3,
xp_min = 1,
xp_max = 3,
armor = 100,
rotate = 180,
spawn_in_group_min = 3,
spawn_in_group = 8,
tilt_swim = true,
collisionbox = {-0.3, 0.0, -0.3, 0.3, 0.79, 0.3},
visual = "mesh",
mesh = "extra_mobs_cod.b3d",
textures = {
{"extra_mobs_cod.png"}
},
sounds = {
},
animation = {
stand_start = 1,
stand_end = 20,
walk_start = 1,
walk_end = 20,
run_start = 1,
run_end = 20,
},
drops = {
{name = "mcl_fishing:fish_raw",
chance = 1,
min = 1,
max = 1,},
{name = "mcl_dye:white",
chance = 20,
min = 1,
max = 1,},
},
visual_size = {x=3, y=3},
makes_footstep_sound = false,
fly = true,
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
breathes_in_water = true,
jump = false,
view_range = 16,
runaway = true,
fear_height = 4,
do_custom = function(self)
--[[ this is supposed to make them jump out the water but doesn't appear to work very well
self.object:set_bone_position("body", vector.new(0,1,0), vector.new(degrees(dir_to_pitch(self.object:get_velocity())) * -1 + 90,0,0))
if minetest.get_item_group(self.standing_in, "water") ~= 0 then
if self.object:get_velocity().y < 5 then
self.object:add_velocity({ x = 0 , y = math.random(-.007, .007), z = 0 })
end
end
--]]
for _,object in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 10)) do
local lp = object:get_pos()
local s = self.object:get_pos()
local vec = {
x = lp.x - s.x,
y = lp.y - s.y,
z = lp.z - s.z
}
if object and not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mobs_mc:cod" then
self.state = "runaway"
self.object:set_rotation({x=0,y=(atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate,z=0})
end
end
end,
on_rightclick = function(self, clicker)
if clicker:get_wielded_item():get_name() == "mcl_buckets:bucket_water" then
self.object:remove()
clicker:set_wielded_item("mcl_buckets:bucket_cod")
awards.unlock(clicker:get_player_name(), "mcl:tacticalFishing")
end
end
}
mcl_mobs:register_mob("mobs_mc:cod", cod)
--spawning TODO: in schools
local water = 0
mcl_mobs:spawn_specific(
"mobs_mc:cod",
"overworld",
"water",
{
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"FlowerForest_underground",
"JungleEdge_underground",
"StoneBeach_underground",
"MesaBryce_underground",
"Mesa_underground",
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",
"ExtremeHills_underground",
"MegaSpruceTaiga_underground",
"BirchForestM_underground",
"SavannaM_underground",
"MesaPlateauFM_underground",
"Desert_underground",
"Savanna_underground",
"Forest_underground",
"SunflowerPlains_underground",
"ColdTaiga_underground",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
30,
4000,
3,
water-16,
water+1)
--spawn egg
mcl_mobs:register_egg("mobs_mc:cod", S("Cod"), "#c1a76a", "#e5c48b", 0)

View File

@ -6,35 +6,27 @@ local cow_def = {
description = S("Cow"),
type = "animal",
spawn_class = "passive",
passive = true,
hp_min = 10,
hp_max = 10,
xp_min = 1,
xp_max = 3,
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.39, 0.45},
spawn_in_group = 8,
spawn_in_group_min = 3,
visual = "mesh",
mesh = "mobs_mc_cow.b3d",
textures = { {
"mobs_mc_cow.png",
"blank.png",
}, },
head_swivel = "head.control",
bone_eye_height = 10,
head_eye_height = 1.1,
horrizonatal_head_height=-1.8,
curiosity = 2,
head_yaw="z",
visual_size = {x=2.8, y=2.8},
makes_footstep_sound = true,
walk_velocity = 1,
drops = {
{name = "mcl_mobitems:beef",
{name = mobs_mc.items.beef_raw,
chance = 1,
min = 1,
max = 3,
looting = "common",},
{name = "mcl_mobitems:leather",
{name = mobs_mc.items.leather,
chance = 1,
min = 0,
max = 2,
@ -49,70 +41,67 @@ local cow_def = {
distance = 16,
},
animation = {
stand_start = 0, stand_end = 0,
walk_start = 0, walk_end = 40, walk_speed = 30,
run_start = 0, run_end = 40, run_speed = 40,
},
child_animations = {
stand_start = 41, stand_end = 41,
walk_start = 41, walk_end = 81, walk_speed = 45,
run_start = 41, run_end = 81, run_speed = 60,
stand_speed = 25, walk_speed = 40,
run_speed = 60, stand_start = 0,
stand_end = 0, walk_start = 0,
walk_end = 40, run_start = 0,
run_end = 40,
},
follow = mobs_mc.follow.cow,
on_rightclick = function(self, clicker)
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
if mcl_mobs:protect(self, clicker) then return end
if mobs:feed_tame(self, clicker, 1, true, true) then return end
if mobs:protect(self, clicker) then return end
if self.child then
return
end
local item = clicker:get_wielded_item()
if item:get_name() == "mcl_buckets:bucket_empty" and clicker:get_inventory() then
if item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
local inv = clicker:get_inventory()
inv:remove_item("main", "mcl_buckets:bucket_empty")
inv:remove_item("main", mobs_mc.items.bucket)
minetest.sound_play("mobs_mc_cow_milk", {pos=self.object:get_pos(), gain=0.6})
-- if room add bucket of milk to inventory, otherwise drop as item
if inv:room_for_item("main", {name = "mcl_mobitems:milk_bucket"}) then
clicker:get_inventory():add_item("main", "mcl_mobitems:milk_bucket")
if inv:room_for_item("main", {name=mobs_mc.items.milk}) then
clicker:get_inventory():add_item("main", mobs_mc.items.milk)
else
local pos = self.object:get_pos()
pos.y = pos.y + 0.5
minetest.add_item(pos, {name = "mcl_mobitems:milk_bucket"})
minetest.add_item(pos, {name = mobs_mc.items.milk})
end
return
end
mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
end,
follow = "mcl_farming:wheat_item",
follow = mobs_mc.items.wheat,
view_range = 10,
fear_height = 4,
}
mcl_mobs:register_mob("mobs_mc:cow", cow_def)
mobs:register_mob("mobs_mc:cow", cow_def)
-- Mooshroom
local mooshroom_def = table.copy(cow_def)
mooshroom_def.description = S("Mooshroom")
mooshroom_def.spawn_in_group_min = 4
mooshroom_def.spawn_in_group = 8
mooshroom_def.mesh = "mobs_mc_cow.b3d"
mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } }
mooshroom_def.on_rightclick = function(self, clicker)
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
if mcl_mobs:protect(self, clicker) then return end
if mobs:feed_tame(self, clicker, 1, true, true) then return end
if mobs:protect(self, clicker) then return end
if self.child then
return
end
local item = clicker:get_wielded_item()
-- Use shears to get mushrooms and turn mooshroom into cow
if item:get_name() == "mcl_tools:shears" then
if item:get_name() == mobs_mc.items.shears then
local pos = self.object:get_pos()
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
if self.base_texture[1] == "mobs_mc_mooshroom_brown.png" then
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, "mcl_mushrooms:mushroom_brown 5")
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, mobs_mc.items.mushroom_brown .. " 5")
else
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, "mcl_mushrooms:mushroom_red 5")
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, mobs_mc.items.mushroom_red .. " 5")
end
local oldyaw = self.object:get_yaw()
@ -121,64 +110,59 @@ mooshroom_def.on_rightclick = function(self, clicker)
cow:set_yaw(oldyaw)
if not minetest.is_creative_enabled(clicker:get_player_name()) then
item:add_wear(mobs_mc.shears_wear)
item:add_wear(mobs_mc.misc.shears_wear)
clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item)
end
-- Use bucket to milk
elseif item:get_name() == "mcl_buckets:bucket_empty" and clicker:get_inventory() then
elseif item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
local inv = clicker:get_inventory()
inv:remove_item("main", "mcl_buckets:bucket_empty")
inv:remove_item("main", mobs_mc.items.bucket)
minetest.sound_play("mobs_mc_cow_milk", {pos=self.object:get_pos(), gain=0.6})
-- If room, add milk to inventory, otherwise drop as item
if inv:room_for_item("main", {name="mcl_mobitems:milk_bucket"}) then
clicker:get_inventory():add_item("main", "mcl_mobitems:milk_bucket")
if inv:room_for_item("main", {name=mobs_mc.items.milk}) then
clicker:get_inventory():add_item("main", mobs_mc.items.milk)
else
local pos = self.object:get_pos()
pos.y = pos.y + 0.5
minetest.add_item(pos, {name = "mcl_mobitems:milk_bucket"})
minetest.add_item(pos, {name = mobs_mc.items.milk})
end
-- Use bowl to get mushroom stew
elseif item:get_name() == "mcl_core:bowl" and clicker:get_inventory() then
elseif item:get_name() == mobs_mc.items.bowl and clicker:get_inventory() then
local inv = clicker:get_inventory()
inv:remove_item("main", "mcl_core:bowl")
inv:remove_item("main", mobs_mc.items.bowl)
minetest.sound_play("mobs_mc_cow_mushroom_stew", {pos=self.object:get_pos(), gain=0.6})
-- If room, add mushroom stew to inventory, otherwise drop as item
if inv:room_for_item("main", {name="mcl_mushrooms:mushroom_stew"}) then
clicker:get_inventory():add_item("main", "mcl_mushrooms:mushroom_stew")
if inv:room_for_item("main", {name=mobs_mc.items.mushroom_stew}) then
clicker:get_inventory():add_item("main", mobs_mc.items.mushroom_stew)
else
local pos = self.object:get_pos()
pos.y = pos.y + 0.5
minetest.add_item(pos, {name = "mcl_mushrooms:mushroom_stew"})
minetest.add_item(pos, {name = mobs_mc.items.mushroom_stew})
end
end
mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
end
mooshroom_def.on_lightning_strike = function(self, pos, pos2, objects)
if self.base_texture[1] == "mobs_mc_mooshroom_brown.png" then
self.base_texture = { "mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png" }
else
self.base_texture = { "mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" }
end
self.object:set_properties({ textures = self.base_texture })
return true
end
mcl_mobs:register_mob("mobs_mc:mooshroom", mooshroom_def)
mobs:register_mob("mobs_mc:mooshroom", mooshroom_def)
-- Spawning
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:cow",
"overworld",
"ground",
{
"flat",
"IcePlainsSpikes",
"ColdTaiga",
"ColdTaiga_beach",
"ColdTaiga_beach_water",
"MegaTaiga",
"MegaSpruceTaiga",
"ExtremeHills",
"ExtremeHills_beach",
"ExtremeHillsM",
"ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach",
"Plains",
"Plains_beach",
@ -209,12 +193,12 @@ minetest.LIGHT_MAX+1,
30,
17000,
10,
mobs_mc.water_level,
mcl_vars.mg_overworld_max)
mobs_mc.spawn_height.water,
mobs_mc.spawn_height.overworld_max)
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:mooshroom",
"overworld",
"ground",
@ -227,9 +211,9 @@ minetest.LIGHT_MAX+1,
30,
17000,
5,
mcl_vars.mg_overworld_min,
mcl_vars.mg_overworld_max)
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- spawn egg
mcl_mobs:register_egg("mobs_mc:cow", S("Cow"), "#443626", "#a1a1a1", 0)
mcl_mobs:register_egg("mobs_mc:mooshroom", S("Mooshroom"), "#a00f10", "#b7b7b7", 0)
mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0)
mobs:register_egg("mobs_mc:mooshroom", S("Mooshroom"), "mobs_mc_spawn_icon_mooshroom.png", 0)

View File

@ -9,10 +9,9 @@ local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:creeper", {
mobs:register_mob("mobs_mc:creeper", {
type = "monster",
spawn_class = "hostile",
spawn_in_group = 1,
hp_min = 20,
hp_max = 20,
xp_min = 5,
@ -21,9 +20,6 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
pathfinding = 1,
visual = "mesh",
mesh = "mobs_mc_creeper.b3d",
head_swivel = "Head_Control",
bone_eye_height = 2.35,
curiosity = 2,
textures = {
{"mobs_mc_creeper.png",
"mobs_mc_empty.png"},
@ -62,7 +58,7 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
return
end
local item = clicker:get_wielded_item()
if item:get_name() == "mcl_fire:flint_and_steel" then
if item:get_name() == mobs_mc.items.flint_and_steel then
if not minetest.is_creative_enabled(clicker:get_player_name()) then
-- Wear tool
local wdef = item:get_definition()
@ -81,7 +77,7 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
if self._forced_explosion_countdown_timer ~= nil then
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
if self._forced_explosion_countdown_timer <= 0 then
mcl_mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
end
end
end,
@ -92,14 +88,14 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
if luaentity and luaentity.name:find("arrow") then
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity()
if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_jukebox:record_" .. math.random(9))
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, mobs_mc.items.music_discs[math.random(1, #mobs_mc.items.music_discs)])
end
end
end
end,
maxdrops = 2,
drops = {
{name = "mcl_mobitems:gunpowder",
{name = mobs_mc.items.gunpowder,
chance = 1,
min = 0,
max = 2,
@ -107,7 +103,7 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
-- Head
-- TODO: Only drop if killed by charged creeper
{name = "mcl_heads:creeper",
{name = mobs_mc.items.head_creeper,
chance = 200, -- 0.5%
min = 1,
max = 1,},
@ -133,7 +129,7 @@ mcl_mobs:register_mob("mobs_mc:creeper", {
view_range = 16,
})
mcl_mobs:register_mob("mobs_mc:creeper_charged", {
mobs:register_mob("mobs_mc:creeper_charged", {
description = S("Creeper"),
type = "monster",
spawn_class = "hostile",
@ -184,7 +180,7 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", {
return
end
local item = clicker:get_wielded_item()
if item:get_name() == "mcl_fire:flint_and_steel" then
if item:get_name() == mobs_mc.items.flint_and_steel then
if not minetest.is_creative_enabled(clicker:get_player_name()) then
-- Wear tool
local wdef = item:get_definition()
@ -203,7 +199,7 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", {
if self._forced_explosion_countdown_timer ~= nil then
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
if self._forced_explosion_countdown_timer <= 0 then
mcl_mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
end
end
end,
@ -214,18 +210,14 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", {
if luaentity and luaentity.name:find("arrow") then
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity()
if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_jukebox:record_" .. math.random(9))
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, mobs_mc.items.music_discs[math.random(1, #mobs_mc.items.music_discs)])
end
end
end
end,
on_lightning_strike = function(self, pos, pos2, objects)
mcl_util.replace_mob(self.object, "mobs_mc:creeper_charged")
return true
end,
maxdrops = 2,
drops = {
{name = "mcl_mobitems:gunpowder",
{name = mobs_mc.items.gunpowder,
chance = 1,
min = 0,
max = 2,
@ -233,7 +225,7 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", {
-- Head
-- TODO: Only drop if killed by charged creeper
{name = "mcl_heads:creeper",
{name = mobs_mc.items.head_creeper,
chance = 200, -- 0.5%
min = 1,
max = 1,},
@ -262,7 +254,7 @@ mcl_mobs:register_mob("mobs_mc:creeper_charged", {
glow = 3,
})
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:creeper",
"overworld",
"ground",
@ -282,6 +274,7 @@ mcl_mobs:spawn_specific(
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
@ -308,6 +301,7 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
@ -346,6 +340,7 @@ mcl_mobs:spawn_specific(
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
@ -355,6 +350,7 @@ mcl_mobs:spawn_specific(
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
@ -380,6 +376,7 @@ mcl_mobs:spawn_specific(
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",
@ -407,8 +404,8 @@ mcl_mobs:spawn_specific(
20,
16500,
2,
mcl_vars.mg_overworld_min,
mcl_vars.mg_overworld_max)
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:creeper", S("Creeper"), "#0da70a", "#000000", 0)
mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0)

View File

@ -0,0 +1 @@
mcl_mobs

View File

@ -1,253 +0,0 @@
--MCmobs v0.4
--maikerumine
--made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes
local pi = math.pi
local atann = math.atan
local atan = function(x)
if not x or x ~= x then
return 0
else
return atann(x)
end
end
local dir_to_pitch = function(dir)
local dir2 = vector.normalize(dir)
local xz = math.abs(dir.x) + math.abs(dir.z)
return -math.atan2(-dir.y, xz)
end
local function degrees(rad)
return rad * 180.0 / math.pi
end
local S = minetest.get_translator(minetest.get_current_modname())
--###################
--################### dolphin
--###################
local dolphin = {
type = "animal",
spawn_class = "water",
can_despawn = true,
passive = true,
hp_min = 10,
hp_max = 10,
xp_min = 1,
xp_max = 3,
armor = 100,
walk_chance = 100,
breath_max = 120,
rotate = 180,
spawn_in_group_min = 3,
spawn_in_group = 5,
tilt_swim = true,
collisionbox = {-0.3, 0.0, -0.3, 0.3, 0.79, 0.3},
visual = "mesh",
mesh = "extra_mobs_dolphin.b3d",
textures = {
{"extra_mobs_dolphin.png"}
},
sounds = {
},
animation = {
stand_start = 20,
stand_end = 20,
walk_start = 0,
walk_end = 15,
run_start = 30,
run_end = 45,
},
drops = {
{name = "mcl_fishing:fish_raw",
chance = 1,
min = 0,
max = 1,},
},
visual_size = {x=3, y=3},
makes_footstep_sound = false,
fly = true,
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
breathes_in_water = true,
jump = false,
view_range = 16,
fear_height = 4,
walk_velocity = 3,
run_velocity = 6,
reach = 2,
damage = 2.5,
attack_type = "dogfight",
do_custom = function(self,dtime)
--[[ this is supposed to make them jump out the water but doesn't appear to work very well
self.object:set_bone_position("body", vector.new(0,1,0), vector.new(degrees(dir_to_pitch(self.object:get_velocity())) * -1 + 90,0,0))
if minetest.get_item_group(self.standing_in, "water") ~= 0 then
if self.object:get_velocity().y < 5 then
self.object:add_velocity({ x = 0 , y = math.random(-.007, .007), z = 0 })
end
end
--]]
end,
}
mcl_mobs:register_mob("mobs_mc:dolphin", dolphin)
--spawning TO DO: in schools
local water = 0
mcl_mobs:spawn_specific(
"mobs_mc:dolphin",
"overworld",
"water",
{
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"FlowerForest_underground",
"JungleEdge_underground",
"StoneBeach_underground",
"MesaBryce_underground",
"Mesa_underground",
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",
"ExtremeHills_underground",
"MegaSpruceTaiga_underground",
"BirchForestM_underground",
"SavannaM_underground",
"MesaPlateauFM_underground",
"Desert_underground",
"Savanna_underground",
"Forest_underground",
"SunflowerPlains_underground",
"ColdTaiga_underground",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX+1,
30,
4000,
3,
water-16,
water+1)
--spawn egg
mcl_mobs:register_egg("mobs_mc:dolphin", S("Dolphin"), "#223b4d", "#f9f9f9", 0)

View File

@ -4,51 +4,7 @@
local S = minetest.get_translator("mobs_mc")
local BEAM_CHECK_FREQUENCY = 2
local POS_CHECK_FREQUENCY = 15
local HEAL_AMMOUNT = 37
local function heal(self)
local o = self.object
self.health = math.min(self.hp_max,self.health + HEAL_AMMOUNT)
end
local function check_beam(self)
for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 80)) do
local luaentity = obj:get_luaentity()
if luaentity and luaentity.name == "mcl_end:crystal" then
if luaentity.beam then
if luaentity.beam == self.beam then
heal(self)
break
end
else
if self.beam then
self.beam:remove()
end
minetest.add_entity(self.object:get_pos(), "mcl_end:crystal_beam"):get_luaentity():init(self.object, obj)
break
end
end
end
end
local function check_pos(self)
if self._portal_pos then
-- migrate old format
if type(self._portal_pos) == "string" then
self._portal_pos = minetest.string_to_pos(self._portal_pos)
end
local portal_center = vector.add(self._portal_pos, vector.new(0, 11, 0))
local pos = self.object:get_pos()
if vector.distance(pos, portal_center) > 50 then
self.object:set_pos(self._last_good_pos or portal_center)
else
self._last_good_pos = pos
end
end
end
mcl_mobs:register_mob("mobs_mc:enderdragon", {
mobs:register_mob("mobs_mc:enderdragon", {
description = S("Ender Dragon"),
type = "monster",
spawn_class = "hostile",
@ -67,7 +23,7 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", {
{"mobs_mc_dragon.png"},
},
visual_size = {x=3, y=3},
view_range = 64,
view_range = 35,
walk_velocity = 6,
run_velocity = 6,
can_despawn = false,
@ -79,7 +35,6 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", {
},
physical = true,
damage = 10,
knock_back = false,
jump = true,
jump_height = 14,
fly = true,
@ -105,33 +60,45 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", {
run_start = 0, run_end = 20,
},
ignores_nametag = true,
do_custom = function(self,dtime)
do_custom = function(self)
mcl_bossbars.update_boss(self.object, "Ender Dragon", "light_purple")
if self._pos_timer == nil or self._pos_timer > POS_CHECK_FREQUENCY then
self._pos_timer = 0
check_pos(self)
for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 80)) do
local luaentity = obj:get_luaentity()
if luaentity and luaentity.name == "mcl_end:crystal" then
if luaentity.beam then
if luaentity.beam == self.beam then
break
end
else
if self.beam then
self.beam:remove()
end
minetest.add_entity(self.object:get_pos(), "mcl_end:crystal_beam"):get_luaentity():init(self.object, obj)
break
end
end
end
if self._portal_pos then
-- migrate old format
if type(self._portal_pos) == "string" then
self._portal_pos = minetest.string_to_pos(self._portal_pos)
end
local portal_center = vector.add(self._portal_pos, vector.new(3, 11, 3))
local pos = self.object:get_pos()
if vector.distance(pos, portal_center) > 50 then
self.object:set_pos(self._last_good_pos or portal_center)
else
self._last_good_pos = pos
end
if self._beam_timer == nil or self._beam_timer > BEAM_CHECK_FREQUENCY then
self._beam_timer = 0
check_beam(self)
end
self._beam_timer = self._beam_timer + dtime
self._pos_timer = self._pos_timer + dtime
end,
on_die = function(self, pos, cmi_cause)
on_die = function(self, pos)
if self._portal_pos then
mcl_portals.spawn_gateway_portal()
mcl_structures.place_structure(self._portal_pos,mcl_structures.registered_structures["end_exit_portal_open"],PseudoRandom(minetest.get_mapgen_setting("seed")),-1)
mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open")
if self._initial then
mcl_experience.throw_xp(pos, 11500) -- 500 + 11500 = 12000
minetest.set_node(vector.add(self._portal_pos, vector.new(0, 5, 0)), {name = "mcl_end:dragon_egg"})
end
end
-- Free The End Advancement
for _,players in pairs(minetest.get_objects_inside_radius(pos,64)) do
if players:is_player() then
awards.unlock(players:get_player_name(), "mcl:freeTheEnd")
minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg})
end
end
end,
@ -142,7 +109,7 @@ mcl_mobs:register_mob("mobs_mc:enderdragon", {
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
-- dragon fireball (projectile)
mcl_mobs:register_arrow("mobs_mc:dragon_fireball", {
mobs:register_arrow("mobs_mc:dragon_fireball", {
visual = "sprite",
visual_size = {x = 1.25, y = 1.25},
textures = {"mobs_mc_dragon_fireball.png"},
@ -166,11 +133,10 @@ mcl_mobs:register_arrow("mobs_mc:dragon_fireball", {
-- node hit, explode
hit_node = function(self, pos, node)
mcl_mobs:boom(self, pos, 2)
mobs:boom(self, pos, 2)
end
})
mcl_mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "#252525", "#b313c9", 0, true)
mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true)
mcl_wip.register_wip_item("mobs_mc:enderdragon")

View File

@ -24,25 +24,7 @@
-- added rain damage.
-- fixed the grass_with_dirt issue.
minetest.register_entity("mobs_mc:ender_eyes", {
visual = "mesh",
mesh = "mobs_mc_spider.b3d",
visual_size = {x=1.01/3, y=1.01/3},
textures = {
"mobs_mc_enderman_eyes.png",
},
on_step = function(self)
if self and self.object then
if not self.object:get_attach() then
self.object:remove()
end
end
end,
glow = 50,
})
local S = minetest.get_translator("mobs_mc")
local enable_damage = minetest.settings:get_bool("enable_damage")
local telesound = function(pos, is_source)
local snd
@ -66,37 +48,6 @@ local take_frequency_max = 245
local place_frequency_min = 235
local place_frequency_max = 245
-- Texuture overrides for enderman block. Required for cactus because it's original is a nodebox
-- and the textures have tranparent pixels.
local block_texture_overrides
do
local cbackground = "mobs_mc_enderman_cactus_background.png"
local ctiles = minetest.registered_nodes["mcl_core:cactus"].tiles
local ctable = {}
local last
for i=1, 6 do
if ctiles[i] then
last = ctiles[i]
end
table.insert(ctable, cbackground .. "^" .. last)
end
block_texture_overrides = {
["mcl_core:cactus"] = ctable,
-- FIXME: replace colorize colors with colors from palette
["mcl_core:dirt_with_grass"] =
{
"mcl_core_grass_block_top.png^[colorize:green:90",
"default_dirt.png",
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)",
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)",
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)",
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)"}
}
end
-- Create the textures table for the enderman, depending on which kind of block
-- the enderman holds (if any).
local create_enderman_textures = function(block_type, itemstring)
@ -118,9 +69,9 @@ local create_enderman_textures = function(block_type, itemstring)
local tiles = minetest.registered_nodes[itemstring].tiles
local textures = {}
local last
if block_texture_overrides[itemstring] then
if mobs_mc.enderman_block_texture_overrides[itemstring] then
-- Texture override available? Use these instead!
textures = block_texture_overrides[itemstring]
textures = mobs_mc.enderman_block_texture_overrides[itemstring]
else
-- Extract the texture names
for i = 1, 6 do
@ -237,25 +188,8 @@ local select_enderman_animation = function(animation_type)
end
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
local psdefs = {{
amount = 5,
minpos = vector.new(-0.6,0,-0.6),
maxpos = vector.new(0.6,3,0.6),
minvel = vector.new(-0.25,-0.25,-0.25),
maxvel = vector.new(0.25,0.25,0.25),
minacc = vector.new(-0.5,-0.5,-0.5),
maxacc = vector.new(0.5,0.5,0.5),
minexptime = 0.2,
maxexptime = 3,
minsize = 0.2,
maxsize = 1.2,
collisiondetection = true,
vertical = false,
time = 0,
texture = "mcl_portals_particle"..math.random(1, 5)..".png",
}}
mcl_mobs:register_mob("mobs_mc:enderman", {
mobs:register_mob("mobs_mc:enderman", {
description = S("Enderman"),
type = "monster",
spawn_class = "passive",
@ -271,19 +205,6 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
textures = create_enderman_textures(),
visual_size = {x=3, y=3},
makes_footstep_sound = true,
on_spawn = function(self)
local spider_eyes=false
for n = 1, #self.object:get_children() do
local obj = self.object:get_children()[n]
if obj:get_luaentity() and self.object:get_luaentity().name == "mobs_mc:ender_eyes" then
spider_eyes = true
end
end
if not spider_eyes then
minetest.add_entity(self.object:get_pos(), "mobs_mc:ender_eyes"):set_attach(self.object, "head.top", vector.new(0,2.54,-1.99), vector.new(90,0,180))
minetest.add_entity(self.object:get_pos(), "mobs_mc:ender_eyes"):set_attach(self.object, "head.top", vector.new(1,2.54,-1.99), vector.new(90,0,180))
end
end,
sounds = {
-- TODO: Custom war cry sound
war_cry = "mobs_sandmonster",
@ -296,9 +217,8 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
run_velocity = 3.4,
damage = 7,
reach = 2,
particlespawners = psdefs,
drops = {
{name = "mcl_throwing:ender_pearl",
{name = mobs_mc.items.ender_pearl,
chance = 1,
min = 0,
max = 1,
@ -306,12 +226,23 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
},
animation = select_enderman_animation("normal"),
_taken_node = "",
can_spawn = function(pos)
return #minetest.find_nodes_in_area(vector.offset(pos,0,1,0),vector.offset(pos,0,3,0),{"air"}) > 2
end,
do_custom = function(self, dtime)
-- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE.
-- PARTICLE BEHAVIOUR HERE.
local enderpos = self.object:get_pos()
local chanceOfParticle = math.random(0, 1)
if chanceOfParticle == 1 then
minetest.add_particle({
pos = {x=enderpos.x+math.random(-1,1)*math.random()/2,y=enderpos.y+math.random(0,3),z=enderpos.z+math.random(-1,1)*math.random()/2},
velocity = {x=math.random(-.25,.25), y=math.random(-.25,.25), z=math.random(-.25,.25)},
acceleration = {x=math.random(-.5,.5), y=math.random(-.5,.5), z=math.random(-.5,.5)},
expirationtime = math.random(),
size = math.random(),
collisiondetection = true,
vertical = false,
texture = "mcl_portals_particle"..math.random(1, 5)..".png",
})
end
-- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE.
local dim = mcl_worlds.pos_to_dimension(enderpos)
if dim == "overworld" then
if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then
@ -347,6 +278,10 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
else return end
-- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE.
if self.state == "attack" then
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
--self:teleport(nil)
--self.state = ""
--else
if self.attack then
local target = self.attack
local pos = target:get_pos()
@ -356,16 +291,11 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
end
end
end
else --if not attacking try to tp to the dark
local light = minetest.get_node_light(enderpos)
if light and light > minetest.LIGHT_MAX then
self:teleport(nil)
end
--end
end
-- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE.
-- Check for arrows and people nearby.
enderpos = self.object:get_pos()
local enderpos = self.object:get_pos()
enderpos.y = enderpos.y + 1.5
local objs = minetest.get_objects_inside_radius(enderpos, 2)
for n = 1, #objs do
@ -394,7 +324,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
-- self:teleport(nil)
-- self.state = ""
--else
if self.attack ~= nil and enable_damage then
if self.attack ~= nil and not minetest.settings:get_bool("creative_mode") then
self.state = 'attack'
end
--end
@ -458,7 +388,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
self._take_place_timer = 0
self._next_take_place_time = math.random(place_frequency_min, place_frequency_max)
local pos = self.object:get_pos()
local takable_nodes = minetest.find_nodes_in_area_under_air({x=pos.x-2, y=pos.y-1, z=pos.z-2}, {x=pos.x+2, y=pos.y+1, z=pos.z+2}, "group:enderman_takable")
local takable_nodes = minetest.find_nodes_in_area_under_air({x=pos.x-2, y=pos.y-1, z=pos.z-2}, {x=pos.x+2, y=pos.y+1, z=pos.z+2}, mobs_mc.enderman_takable)
if #takable_nodes >= 1 then
local r = pr:next(1, #takable_nodes)
local take_pos = takable_nodes[r]
@ -468,7 +398,11 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
minetest.remove_node(take_pos)
local dug = minetest.get_node_or_nil(take_pos)
if dug and dug.name == "air" then
if mobs_mc.enderman_replace_on_take[node.name] then
self._taken_node = mobs_mc.enderman_replace_on_take[node.name]
else
self._taken_node = node.name
end
local def = minetest.registered_nodes[self._taken_node]
-- Update animation and texture accordingly (adds visibly carried block)
local block_type
@ -497,7 +431,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
self.base_texture = create_enderman_textures(block_type, self._taken_node)
self.object:set_properties({ textures = self.base_texture })
self.animation = select_enderman_animation("block")
mcl_mobs:set_animation(self, self.animation.current)
mobs:set_animation(self, self.animation.current)
if def.sounds and def.sounds.dug then
minetest.sound_play(def.sounds.dug, {pos = take_pos, max_hear_distance = 16}, true)
end
@ -520,7 +454,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
local def = minetest.registered_nodes[self._taken_node]
-- Update animation accordingly (removes visible block)
self.animation = select_enderman_animation("normal")
mcl_mobs:set_animation(self, self.animation.current)
mobs:set_animation(self, self.animation.current)
if def.sounds and def.sounds.place then
minetest.sound_play(def.sounds.place, {pos = place_pos, max_hear_distance = 16}, true)
end
@ -629,28 +563,24 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
attack_type = "dogfight",
})
-- End spawn
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:enderman",
"end",
"ground",
{
"End",
"EndIsland",
"EndMidlands",
"EndBarrens",
"EndBorder",
"EndSmallIslands"
"End"
},
0,
minetest.LIGHT_MAX+1,
30,
3000,
12,
mcl_vars.mg_end_min,
mcl_vars.mg_end_max)
mobs_mc.spawn_height.end_min,
mobs_mc.spawn_height.end_max)
-- Overworld spawn
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:enderman",
"overworld",
"ground",
@ -670,6 +600,7 @@ mcl_mobs:spawn_specific(
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
@ -696,6 +627,7 @@ mcl_mobs:spawn_specific(
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
@ -734,6 +666,7 @@ mcl_mobs:spawn_specific(
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
@ -743,6 +676,7 @@ mcl_mobs:spawn_specific(
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
@ -768,6 +702,7 @@ mcl_mobs:spawn_specific(
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",
@ -795,41 +730,24 @@ mcl_mobs:spawn_specific(
30,
19000,
2,
mcl_vars.mg_overworld_min,
mcl_vars.mg_overworld_max)
mobs_mc.spawn_height.overworld_min,
mobs_mc.spawn_height.overworld_max)
-- Nether spawn (rare)
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:enderman",
"nether",
"ground",
{
"Nether",
"SoulsandValley",
"Nether"
},
0,
11,
7,
30,
27500,
4,
mcl_vars.mg_nether_min,
mcl_vars.mg_nether_max)
-- Warped Forest spawn (common)
mcl_mobs:spawn_specific(
"mobs_mc:enderman",
"nether",
"ground",
{
"WarpedForest"
},
0,
11,
30,
5000,
4,
mcl_vars.mg_nether_min,
mcl_vars.mg_nether_max)
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:enderman", S("Enderman"), "#252525", "#151515", 0)
mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0)

View File

@ -4,7 +4,7 @@
local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:endermite", {
mobs:register_mob("mobs_mc:endermite", {
description = S("Endermite"),
type = "monster",
spawn_class = "hostile",
@ -38,4 +38,4 @@ mcl_mobs:register_mob("mobs_mc:endermite", {
reach = 1,
})
mcl_mobs:register_egg("mobs_mc:endermite", S("Endermite"), "#161616", "#6d6d6d", 0)
mobs:register_egg("mobs_mc:endermite", S("Endermite"), "mobs_mc_spawn_icon_endermite.png", 0)

View File

@ -0,0 +1,59 @@
# Game integration help
This mod has been designed to make game integration rather easy. Ideally, it should be possible to include this mod verbatim in your game, with modifications only done by an external mod.
To integrate this mod in a game, you have to do 2 things: Adding the mod, and adding another mod which tells `mobs_mc` which items to use. The idea is that `mobs_mc` should work with any items. Specifically, these are the steps you need to follow:
* Add the `mobs_mc` mod and its dependencies
* Add a mod with name “`mobs_mc_gameconfig`”
* In this mod, do this:
* Do *not* depend on `mobs_mc`
* Create the table `mobs_mc`
* Create the table `mobs_mc.override`
* In `mobs_mc.override`, create subtables (`items`, `spawn`, etc.) like in `0_gameconfig.lua`, defining the na
* Read `0_gameconfig.lua` to see which items you can override (and more explanations)
* In `on_construct` of a pumpkin or jack'o lantern node, call:
* `mobs_mc.tools.check_iron_golem_summon(pos)`
* `mobs_mc.tools.check_snow_golem_summon(pos)`
* For more information, see `snowman.lua` and `iron_golem.lua`
Some things to note:
* Every override is optional, but explicitly setting all the item overrides is strongly recommended
* `mobs_mc` ships many (but not all) items on its own. If not item name override is set, the `mobs_mc` item is used
* You decide whether your game defines its own items, outside of `mobs_mc` or if you let `mobs_mc` do the work.
* Make sure to avoid duplicate items!
* After finishing this, throughly test this
* Without `mobs_mc_gameconfig`, the mod assumes Minetest Game items
* `mobs_mc` optionally depends on `mobs_mc_gameconfig`
## Example `init.lua` in `mobs_mc_gameconfig`
```
mobs_mc = {}
mobs_mc.override = {}
-- Set the item names here
mobs_mc.override.items = {
blaze_rod = "mcl_mobitems:blaze_rod",
blaze_powder = "mcl_mobitems:blaze_powder",
chicken_raw = "mcl_mobitems:chicken",
-- And so on ...
}
-- Set the “follow” field of mobs (used for attracting mob, feeding and breeding)
mobs_mc.override.follow = {
chicken = { "mcl_farming:wheat_seeds", "mcl_farming:melon_seeds", "mcl_farming:pumpkin_seeds", "mcl_farming:beetroot_seeds", },
horse = { "mcl_core:apple", mobs_mc.override.items.wheat }, -- TODO
pig = { "mcl_farming:potato", mobs_mc.override.items.carrot, mobs_mc.override.items.carrot_on_a_stick},
-- And so on ...
}
-- Custom spawn nodes
mobs_mc.override.spawn = {
snow = { "example:snow", "example:snow2" },
-- And so on ...
}
-- Take a look at the other possible tables, see 0_gameconfig.lua
```

View File

@ -10,7 +10,7 @@ local S = minetest.get_translator("mobs_mc")
--###################
mcl_mobs:register_mob("mobs_mc:ghast", {
mobs:register_mob("mobs_mc:ghast", {
description = S("Ghast"),
type = "monster",
spawn_class = "hostile",
@ -23,7 +23,6 @@ mcl_mobs:register_mob("mobs_mc:ghast", {
collisionbox = {-2, 5, -2, 2, 9, 2},
visual = "mesh",
mesh = "mobs_mc_ghast.b3d",
spawn_in_group = 1,
textures = {
{"mobs_mc_ghast.png"},
},
@ -40,8 +39,8 @@ mcl_mobs:register_mob("mobs_mc:ghast", {
walk_velocity = 1.6,
run_velocity = 3.2,
drops = {
{name = "mcl_mobitems:gunpowder", chance = 1, min = 0, max = 2, looting = "common"},
{name = "mcl_mobitems:ghast_tear", chance = 10/6, min = 0, max = 1, looting = "common", looting_ignore_chance = true},
{name = mobs_mc.items.gunpowder, chance = 1, min = 0, max = 2, looting = "common"},
{name = mobs_mc.items.ghast_tear, chance = 10/6, min = 0, max = 1, looting = "common", looting_ignore_chance = true},
},
animation = {
stand_speed = 50, walk_speed = 50, run_speed = 50,
@ -65,14 +64,6 @@ mcl_mobs:register_mob("mobs_mc:ghast", {
makes_footstep_sound = false,
instant_death = true,
fire_resistant = true,
can_spawn = function(pos)
if not minetest.get_item_group(minetest.get_node(pos).name,"solid") then return false end
local p1=vector.offset(pos,-2,1,-2)
local p2=vector.offset(pos,2,5,2)
local nn = minetest.find_nodes_in_area(p1,p2,{"air"})
if #nn< 41 then return false end
return true
end,
do_custom = function(self)
if self.firing == true then
self.base_texture = {"mobs_mc_ghast_firing.png"}
@ -85,25 +76,23 @@ mcl_mobs:register_mob("mobs_mc:ghast", {
})
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:ghast",
"nether",
"ground",
{
"Nether",
"SoulsandValley",
"BasaltDelta",
"Nether"
},
0,
7,
minetest.LIGHT_MAX+1,
30,
72000,
18000,
2,
mcl_vars.mg_nether_min,
mcl_vars.mg_nether_max)
mobs_mc.spawn_height.nether_min,
mobs_mc.spawn_height.nether_max)
-- fireball (projectile)
mcl_mobs:register_arrow("mobs_mc:fireball", {
mobs:register_arrow("mobs_mc:fireball", {
visual = "sprite",
visual_size = {x = 1, y = 1},
textures = {"mcl_fire_fire_charge.png"},
@ -116,12 +105,7 @@ mcl_mobs:register_arrow("mobs_mc:fireball", {
full_punch_interval = 1.0,
damage_groups = {fleshy = 6},
}, nil)
local p = self.object:get_pos()
if p then
mcl_mobs:boom(self, p, 1, true)
else
mcl_mobs:boom(self, player:get_pos(), 1, true)
end
mobs:boom(self, self.object:get_pos(), 1, true)
end,
hit_mob = function(self, mob)
@ -129,11 +113,11 @@ mcl_mobs:register_arrow("mobs_mc:fireball", {
full_punch_interval = 1.0,
damage_groups = {fleshy = 6},
}, nil)
mcl_mobs:boom(self, self.object:get_pos(), 1, true)
mobs:boom(self, self.object:get_pos(), 1, true)
end,
hit_node = function(self, pos, node)
mcl_mobs:boom(self, pos, 1, true)
mobs:boom(self, pos, 1, true)
end
})
@ -141,4 +125,4 @@ mcl_mobs:register_arrow("mobs_mc:fireball", {
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:ghast", S("Ghast"), "#f9f9f9", "#bcbcbc", 0)
mobs:register_egg("mobs_mc:ghast", S("Ghast"), "mobs_mc_spawn_icon_ghast.png", 0)

View File

@ -1,246 +0,0 @@
--MCmobs v0.4
--maikerumine
--made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc")
local base_psdef = {
amount = 8,
time=0,
minpos = vector.new(-1,-1,-1),
maxpos = vector.new(1,1,1),
minvel = vector.new(-0.25,-0.25,-0.25),
maxvel = vector.new(0.25,0.25,0.25),
minacc = vector.new(-0.5,-0.5,-0.5),
maxacc = vector.new(0.5,0.5,0.5),
minexptime = 1,
maxexptime = 2,
minsize = 0.8,
maxsize= 1.5,
glow = 5,
collisiondetection = true,
collision_removal = true,
}
local psdefs = {}
for i=1,4 do
local p = table.copy(base_psdef)
p.texture = "extra_mobs_glow_squid_glint"..i..".png"
table.insert(psdefs,p)
end
mcl_mobs:register_mob("mobs_mc:glow_squid", {
type = "animal",
spawn_class = "water",
can_despawn = true,
passive = true,
hp_min = 10,
hp_max = 10,
xp_min = 1,
xp_max = 3,
armor = 100,
rotate = 0,
-- tilt_swim breaks the animations.
--tilt_swim = true,
-- FIXME: If the qlow squid is near the floor, it turns black
collisionbox = { -0.4, 0.0, -0.4, 0.4, 0.9, 0.4 },
visual = "mesh",
mesh = "extra_mobs_glow_squid.b3d",
textures = {
{ "extra_mobs_glow_squid.png" }
},
sounds = {
damage = { name = "mobs_mc_squid_hurt", gain = 0.3 },
death = { name = "mobs_mc_squid_death", gain = 0.4 },
flop = "mobs_mc_squid_flop",
distance = 16,
},
animation = {
stand_start = 1,
stand_end = 60,
walk_start = 1,
walk_end = 60,
run_start = 1,
run_end = 60,
},
drops = {
{ name = "mcl_mobitems:glow_ink_sac",
chance = 1,
min = 1,
max = 3,
looting = "common", },
},
visual_size = { x = 3, y = 3 },
makes_footstep_sound = false,
swim = true,
breathes_in_water = true,
jump = false,
view_range = 16,
runaway = true,
fear_height = 4,
fly = true,
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
-- don't add "mcl_core:water_flowing", or it won't move vertically.
glow = minetest.LIGHT_MAX,
particlespawners = psdefs,
})
-- spawning
local water = mobs_mc.water_level - 1
-- local water = mobs_mc.spawn_height.water + 1
mcl_mobs:spawn_specific(
"mobs_mc:glow_squid",
"overworld",
"water",
{
"Mesa",
"FlowerForest",
"Swampland",
"Taiga",
"ExtremeHills",
"Jungle",
"Savanna",
"BirchForest",
"MegaSpruceTaiga",
"MegaTaiga",
"ExtremeHills+",
"Forest",
"Plains",
"Desert",
"ColdTaiga",
"MushroomIsland",
"IcePlainsSpikes",
"SunflowerPlains",
"IcePlains",
"RoofedForest",
"ExtremeHills+_snowtop",
"MesaPlateauFM_grasstop",
"JungleEdgeM",
"ExtremeHillsM",
"JungleM",
"BirchForestM",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"JungleEdge",
"SavannaM",
"FlowerForest_beach",
"Forest_beach",
"StoneBeach",
"ColdTaiga_beach_water",
"Taiga_beach",
"Savanna_beach",
"Plains_beach",
"ExtremeHills_beach",
"ColdTaiga_beach",
"Swampland_shore",
"MushroomIslandShore",
"JungleM_shore",
"Jungle_shore",
"MesaPlateauFM_sandlevel",
"MesaPlateauF_sandlevel",
"MesaBryce_sandlevel",
"Mesa_sandlevel",
"RoofedForest_ocean",
"JungleEdgeM_ocean",
"BirchForestM_ocean",
"BirchForest_ocean",
"IcePlains_deep_ocean",
"Jungle_deep_ocean",
"Savanna_ocean",
"MesaPlateauF_ocean",
"ExtremeHillsM_deep_ocean",
"Savanna_deep_ocean",
"SunflowerPlains_ocean",
"Swampland_deep_ocean",
"Swampland_ocean",
"MegaSpruceTaiga_deep_ocean",
"ExtremeHillsM_ocean",
"JungleEdgeM_deep_ocean",
"SunflowerPlains_deep_ocean",
"BirchForest_deep_ocean",
"IcePlainsSpikes_ocean",
"Mesa_ocean",
"StoneBeach_ocean",
"Plains_deep_ocean",
"JungleEdge_deep_ocean",
"SavannaM_deep_ocean",
"Desert_deep_ocean",
"Mesa_deep_ocean",
"ColdTaiga_deep_ocean",
"Plains_ocean",
"MesaPlateauFM_ocean",
"Forest_deep_ocean",
"JungleM_deep_ocean",
"FlowerForest_deep_ocean",
"MushroomIsland_ocean",
"MegaTaiga_ocean",
"StoneBeach_deep_ocean",
"IcePlainsSpikes_deep_ocean",
"ColdTaiga_ocean",
"SavannaM_ocean",
"MesaPlateauF_deep_ocean",
"MesaBryce_deep_ocean",
"ExtremeHills+_deep_ocean",
"ExtremeHills_ocean",
"MushroomIsland_deep_ocean",
"Forest_ocean",
"MegaTaiga_deep_ocean",
"JungleEdge_ocean",
"MesaBryce_ocean",
"MegaSpruceTaiga_ocean",
"ExtremeHills+_ocean",
"Jungle_ocean",
"RoofedForest_deep_ocean",
"IcePlains_ocean",
"FlowerForest_ocean",
"ExtremeHills_deep_ocean",
"MesaPlateauFM_deep_ocean",
"Desert_ocean",
"Taiga_ocean",
"BirchForestM_deep_ocean",
"Taiga_deep_ocean",
"JungleM_ocean",
"FlowerForest_underground",
"JungleEdge_underground",
"StoneBeach_underground",
"MesaBryce_underground",
"Mesa_underground",
"RoofedForest_underground",
"Jungle_underground",
"Swampland_underground",
"MushroomIsland_underground",
"BirchForest_underground",
"Plains_underground",
"MesaPlateauF_underground",
"ExtremeHills_underground",
"MegaSpruceTaiga_underground",
"BirchForestM_underground",
"SavannaM_underground",
"MesaPlateauFM_underground",
"Desert_underground",
"Savanna_underground",
"Forest_underground",
"SunflowerPlains_underground",
"ColdTaiga_underground",
"IcePlains_underground",
"IcePlainsSpikes_underground",
"MegaTaiga_underground",
"Taiga_underground",
"ExtremeHills+_underground",
"JungleM_underground",
"ExtremeHillsM_underground",
"JungleEdgeM_underground",
},
0,
minetest.LIGHT_MAX + 1,
30,
10000,
3,
water - 16,
water)
-- spawn egg
mcl_mobs:register_egg("mobs_mc:glow_squid", S("Glow Squid"), "#095757", "#87f6c0", 0)

View File

@ -4,12 +4,10 @@
local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:guardian", {
mobs:register_mob("mobs_mc:guardian", {
description = S("Guardian"),
type = "monster",
spawn_class = "hostile",
spawn_in_group_min = 2,
spawn_in_group = 4,
hp_min = 30,
hp_max = 30,
xp_min = 10,
@ -46,7 +44,7 @@ mcl_mobs:register_mob("mobs_mc:guardian", {
},
drops = {
-- Greatly increased amounts of prismarine
{name = "mcl_ocean:prismarine_shard",
{name = mobs_mc.items.prismarine_shard,
chance = 1,
min = 0,
max = 32,
@ -55,37 +53,37 @@ mcl_mobs:register_mob("mobs_mc:guardian", {
-- The following drops are approximations
-- Fish / prismarine crystal
{name = "mcl_fishing:fish_raw",
{name = mobs_mc.items.fish_raw,
chance = 4,
min = 1,
max = 1,
looting = "common",},
{name = "mcl_ocean:prismarine_crystals",
{name = mobs_mc.items.prismarine_crystals,
chance = 4,
min = 1,
max = 2,
looting = "common",},
-- Rare drop: fish
{name = "mcl_fishing:fish_raw",
{name = mobs_mc.items.fish_raw,
chance = 160, -- 2.5% / 4
min = 1,
max = 1,
looting = "rare",
looting_factor = 0.0025,},
{name = "mcl_fishing:salmon_raw",
{name = mobs_mc.items.salmon_raw,
chance = 160,
min = 1,
max = 1,
looting = "rare",
looting_factor = 0.0025,},
{name = "mcl_fishing:clownfish_raw",
{name = mobs_mc.items.clownfish_raw,
chance = 160,
min = 1,
max = 1,
looting = "rare",
looting_factor = 0.0025,},
{name = "mcl_fishing:pufferfish_raw",
{name = mobs_mc.items.pufferfish_raw,
chance = 160,
min = 1,
max = 1,
@ -94,14 +92,14 @@ mcl_mobs:register_mob("mobs_mc:guardian", {
},
fly = true,
makes_footstep_sound = false,
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
jump = false,
view_range = 16,
})
-- Spawning disabled due to size issues
-- TODO: Re-enable spawning
--mcl_mobs:spawn_specific("mobs_mc:guardian", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level - 10)
--mobs:spawn_specific("mobs_mc:guardian", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water - 10)
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:guardian", S("Guardian"), "#5a8272", "#f17d31", 0)
mobs:register_egg("mobs_mc:guardian", S("Guardian"), "mobs_mc_spawn_icon_guardian.png", 0)

View File

@ -6,7 +6,7 @@
local S = minetest.get_translator("mobs_mc")
mcl_mobs:register_mob("mobs_mc:guardian_elder", {
mobs:register_mob("mobs_mc:guardian_elder", {
description = S("Elder Guardian"),
type = "monster",
spawn_class = "hostile",
@ -49,51 +49,51 @@ mcl_mobs:register_mob("mobs_mc:guardian_elder", {
-- TODO: Reduce # of drops when ocean monument is ready.
-- Greatly increased amounts of prismarine
{name = "mcl_ocean:prismarine_shard",
{name = mobs_mc.items.prismarine_shard,
chance = 1,
min = 1,
max = 64,
looting = "common",},
-- TODO: Only drop if killed by player
{name = "mcl_sponges:sponge_wet",
{name = mobs_mc.items.wet_sponge,
chance = 1,
min = 1,
max = 1,},
-- The following drops are approximations
-- Fish / prismarine crystal
{name = "mcl_fishing:fish_raw",
{name = mobs_mc.items.fish_raw,
chance = 4,
min = 1,
max = 1,
looting = "common",},
{name = "mcl_ocean:prismarine_crystals",
{name = mobs_mc.items.prismarine_crystals,
chance = 1,
min = 1,
max = 10,
looting = "common",},
-- Rare drop: fish
{name = "mcl_fishing:fish_raw",
{name = mobs_mc.items.fish_raw,
chance = 160, -- 2.5% / 4
min = 1,
max = 1,
looting = "rare",
looting_factor = 0.01 / 4,},
{name = "mcl_fishing:salmon_raw",
{name = mobs_mc.items.salmon_raw,
chance = 160,
min = 1,
max = 1,
looting = "rare",
looting_factor = 0.01 / 4,},
{name = "mcl_fishing:clownfish_raw",
{name = mobs_mc.items.clownfish_raw,
chance = 160,
min = 1,
max = 1,
looting = "rare",
looting_factor = 0.01 / 4,},
{name = "mcl_fishing:pufferfish_raw",
{name = mobs_mc.items.pufferfish_raw,
chance = 160,
min = 1,
max = 1,
@ -102,16 +102,15 @@ mcl_mobs:register_mob("mobs_mc:guardian_elder", {
},
fly = true,
makes_footstep_sound = false,
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
jump = false,
view_range = 16,
})
-- Spawning disabled due to size issues <- what do you mean? -j4i
-- TODO: Re-enable spawning
-- mcl_mobs:spawn_specific("mobs_mc:guardian_elder", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level-18)
-- mobs:spawn_specific("mobs_mc:guardian_elder", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-18)
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "#ceccba", "#747693", 0)
mobs:register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "mobs_mc_spawn_icon_guardian_elder.png", 0)

View File

@ -1,135 +0,0 @@
--MCmobs v0.4
--maikerumine
--made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc")
--###################
--################### hoglin
--###################
local hoglin = {
type = "monster",
passive = false,
spawn_class = "hostile",
hp_min = 40,
hp_max = 40,
xp_min = 9,
xp_max = 9,
armor = {fleshy = 90},
attack_type = "dogfight",
damage = 4,
reach = 3,
collisionbox = {-.6, -0.01, -.6, .6, 1.4, .6},
visual = "mesh",
mesh = "extra_mobs_hoglin.b3d",
textures = { {
"extra_mobs_hoglin.png",
} },
visual_size = {x=3, y=3},
sounds = {
random = "extra_mobs_hoglin",
damage = "extra_mobs_hoglin_hurt",
distance = 16,
},
jump = true,
makes_footstep_sound = true,
walk_velocity = 1,
run_velocity = 4,
drops = {
{name = "mobs_mcitems:leather",
chance = 1,
min = 0,
max = 1,},
},
drops = {
{name = "mcl_mobitems:porkchop",
chance = 1,
min = 2,
max = 4,},
},
animation = {
stand_speed = 7,
walk_speed = 7,
run_speed = 15,
stand_start = 24,
stand_end = 24,
walk_start = 11,
walk_end = 21,
run_start = 1,
run_end = 10,
punch_start = 22,
punch_end = 32,
},
fear_height = 4,
view_range = 32,
floats = 0,
custom_attack = function(self)
if self.state == "attack" and self.reach > vector.distance(self.object:get_pos(), self.attack:get_pos()) then
self.attack:add_velocity({x=0,y=13,z=0})
self.attack:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = self.damage}
}, nil)
end
end,
do_custom = function(self)
if self.object:get_pos().y > -100 then
local zog = minetest.add_entity(self.object:get_pos(), "mobs_mc:zoglin")
zog:set_rotation(self.object:get_rotation())
self.object:remove()
end
end,
attack_animals = true,
}
mcl_mobs:register_mob("mobs_mc:hoglin", hoglin)
local zoglin = table.copy(hoglin)
zoglin.fire_resistant = 1
zoglin.textures = {"extra_mobs_zoglin.png"}
zoglin.do_custom = function()
return
end
zoglin.attacks_monsters = true
zoglin.lava_damage = 0
zoglin.fire_damage = 0
mcl_mobs:register_mob("mobs_mc:zoglin", zoglin)
-- Baby hoglin.
local baby_hoglin = table.copy(hoglin)
baby_hoglin.collisionbox = {-.3, -0.01, -.3, .3, 0.94, .3}
baby_hoglin.xp_min = 20
baby_hoglin.xp_max = 20
baby_hoglin.visual_size = {x=hoglin.visual_size.x/2, y=hoglin.visual_size.y/2}
textures = { {
"extra_mobs_hoglin.png",
"extra_mobs_trans.png",
} }
baby_hoglin.walk_velocity = 1.2
baby_hoglin.run_velocity = 2.4
baby_hoglin.child = 1
mcl_mobs:register_mob("mobs_mc:baby_hoglin", baby_hoglin)
-- Regular spawning in the Nether
mcl_mobs:spawn_specific(
"mobs_mc:hoglin",
"nether",
"ground",
{
"Nether",
"CrimsonForest"
},
0,
minetest.LIGHT_MAX+1,
30,
6000,
3,
mcl_vars.mg_nether_min,
mcl_vars.mg_nether_max)
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:hoglin", S("Hoglin"), "#85682e", "#2b2140", 0)

View File

@ -34,30 +34,6 @@ local horse_extra_texture = function(horse)
return textures
end
local function get_drops(self)
self.drops = {}
table.insert(self.drops,
{name = "mcl_mobitems:leather",
chance = 1,
min = 0,
max = 2,
looting = "common",
})
if self._saddle then
table.insert(self.drops,{name = "mcl_mobitems:saddle",
chance = 1,
min = 1,
max = 1,})
end
if self._chest then
table.insert(self.drops,{name = "mcl_chests:chest",
chance = 1,
min = 1,
max = 1,})
end
end
-- Helper functions to determine equipment rules
local can_equip_horse_armor = function(entity_id)
return entity_id == "mobs_mc:horse" or entity_id == "mobs_mc:skeleton_horse" or entity_id == "mobs_mc:zombie_horse"
@ -105,27 +81,11 @@ for b=1, #horse_base do
end
end
-- in e7898352d890c2414af653eba624939df9c0b8b4 (0.76-dev) all items from mobs_mc were moved to mcl_mobitems
-- this results in existing horses wearing armor would still have the old texture filename in their
-- properties this function updates them. It should be removed some time in the future when we can be
-- reasonably sure all horses that want it get the new nexture.
local function update_textures(self)
local old = "mobs_mc_horse_armor_"
local txt = self.object:get_properties().textures
if txt[2]:find(old) then
txt[2] = txt[2]:gsub(old,"mcl_mobitems_horse_armor_")
self.object:set_properties({textures=txt})
return
end
end
-- Horse
local horse = {
description = S("Horse"),
type = "animal",
spawn_class = "passive",
spawn_in_group_min = 2,
spawn_in_group = 6,
visual = "mesh",
mesh = "mobs_mc_horse.b3d",
visual_size = {x=3.0, y=3.0},
@ -154,14 +114,7 @@ local horse = {
fly = false,
walk_chance = 60,
view_range = 16,
follow = {
"mcl_core:apple",
"mcl_core:sugar",
"mcl_farming:wheat_item",
"mcl_farming:hay_block",
"mcl_core:apple_gold",
"mcl_farming:carrot_item_gold",
},
follow = mobs_mc.follow.horse,
passive = true,
hp_min = 15,
hp_max = 30,
@ -172,20 +125,14 @@ local horse = {
jump = true,
jump_height = 5.75, -- can clear 2.5 blocks
drops = {
{name = "mcl_mobitems:leather",
{name = mobs_mc.items.leather,
chance = 1,
min = 0,
max = 2,
looting = "common",},
},
on_spawn = update_textures,
do_custom = function(self, dtime)
if not self._horse_speed then
self._horse_speed = math.random(486, 1457)/100
elseif self.run_velocity ~= self._horse_speed then
self.run_velocity = self._horse_speed
end
do_custom = function(self, dtime)
-- set needed values if not already present
if not self._regentimer then
@ -214,7 +161,7 @@ local horse = {
-- Some weird human is riding. Buck them off?
if self.driver and not self.tamed and self.buck_off_time <= 0 then
if math.random() < 0.2 then
mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1})
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
-- TODO bucking animation
else
-- Nah, can't be bothered. Think about it again in one second
@ -235,7 +182,7 @@ local horse = {
-- if driver present and horse has a saddle allow control of horse
if self.driver and self._saddle then
mcl_mobs.drive(self, "walk", "stand", false, dtime)
mobs.drive(self, "walk", "stand", false, dtime)
return false -- skip rest of mob functions
end
@ -247,11 +194,11 @@ local horse = {
-- drop saddle when horse is killed while riding
if self._saddle then
minetest.add_item(pos, "mcl_mobitems:saddle")
minetest.add_item(pos, mobs_mc.items.saddle)
end
-- also detach from horse properly
if self.driver then
mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1})
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end
end,
@ -267,27 +214,6 @@ local horse = {
local iname = item:get_name()
local heal = 0
if self._inv_id then
if not self._chest and item:get_name() == "mcl_chests:chest" then
item:take_item()
clicker:set_wielded_item(item)
self._chest = true
-- Update texture
if not self._naked_texture then
-- Base horse texture without chest or saddle
self._naked_texture = self.base_texture[2]
end
local tex = horse_extra_texture(self)
self.base_texture = tex
self.object:set_properties({textures = self.base_texture})
get_drops(self)
return
elseif self._chest and clicker:get_player_control().sneak then
mcl_entity_invs.show_inv_form(self,clicker)
return
end
end
-- Taming
self.temper = self.temper or (math.random(1,100))
@ -296,20 +222,20 @@ local horse = {
-- Feeding, intentionally not using mobs:feed_tame because horse taming is
-- different and more complicated
if (iname == "mcl_core:sugar") then
if (iname == mobs_mc.items.sugar) then
temper_increase = 3
elseif (iname == "mcl_farming:wheat_item") then
elseif (iname == mobs_mc.items.wheat) then
temper_increase = 3
elseif (iname == "mcl_core:apple") then
elseif (iname == mobs_mc.items.apple) then
temper_increase = 3
elseif (iname == "mcl_farming:carrot_item_gold") then
elseif (iname == mobs_mc.items.golden_carrot) then
temper_increase = 5
elseif (iname == "mcl_core:apple_gold") then
elseif (iname == mobs_mc.items.golden_apple) then
temper_increase = 10
-- Trying to ride
elseif not self.driver then
self.object:set_properties({stepheight = 1.1})
mcl_mobs.attach(self, clicker)
mobs.attach(self, clicker)
self.buck_off_time = 40 -- TODO how long does it take in minecraft?
if self.temper > 100 then
self.tamed = true -- NOTE taming can only be finished by riding the horse
@ -321,7 +247,7 @@ local horse = {
-- Clicking on the horse while riding ==> unmount
elseif self.driver and self.driver == clicker then
mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1})
mobs.detach(clicker, {x = 1, y = 0, z = 1})
end
-- If nothing happened temper_increase = 0 and addition does nothing
@ -332,31 +258,31 @@ local horse = {
if can_breed(self.name) then
-- Breed horse with golden apple or golden carrot
if (iname == "mcl_core:apple_gold") then
if (iname == mobs_mc.items.golden_apple) then
heal = 10
elseif (iname == "mcl_farming:carrot_item_gold") then
elseif (iname == mobs_mc.items.golden_carrot) then
heal = 4
end
if heal > 0 and mcl_mobs:feed_tame(self, clicker, heal, true, false) then
if heal > 0 and mobs:feed_tame(self, clicker, heal, true, false) then
return
end
end
-- Feed with anything else
-- TODO heal amounts don't work
if (iname == "mcl_core:sugar") then
if (iname == mobs_mc.items.sugar) then
heal = 1
elseif (iname == "mcl_farming:wheat_item") then
elseif (iname == mobs_mc.items.wheat) then
heal = 2
elseif (iname == "mcl_core:apple") then
elseif (iname == mobs_mc.items.apple) then
heal = 3
elseif (iname == "mcl_farming:hay_block") then
elseif (iname == mobs_mc.items.hay_bale) then
heal = 20
end
if heal > 0 and mcl_mobs:feed_tame(self, clicker, heal, false, false) then
if heal > 0 and mobs:feed_tame(self, clicker, heal, false, false) then
return
end
if mcl_mobs:protect(self, clicker) then
if mobs:protect(self, clicker) then
return
end
@ -368,11 +294,11 @@ local horse = {
-- detatch player already riding horse
if self.driver and clicker == self.driver then
mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1})
mobs.detach(clicker, {x = 1, y = 0, z = 1})
-- Put on saddle if tamed
elseif not self.driver and not self._saddle
and iname == "mcl_mobitems:saddle" then
and iname == mobs_mc.items.saddle then
-- Put on saddle and take saddle from player's inventory
local w = clicker:get_wielded_item()
@ -391,7 +317,6 @@ local horse = {
self.base_texture = tex
self.object:set_properties({textures = self.base_texture})
minetest.sound_play({name = "mcl_armor_equip_leather"}, {gain=0.5, max_hear_distance=12, pos=self.object:get_pos()}, true)
get_drops(self)
-- Put on horse armor if tamed
elseif can_equip_horse_armor(self.name) and not self.driver and not self._horse_armor
@ -430,18 +355,18 @@ local horse = {
elseif not self.driver and self._saddle then
self.object:set_properties({stepheight = 1.1})
mcl_mobs.attach(self, clicker)
mobs.attach(self, clicker)
-- Used to capture horse
elseif not self.driver and iname ~= "" then
mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
end
end
end,
on_breed = function(parent1, parent2)
local pos = parent1.object:get_pos()
local child = mcl_mobs:spawn_child(pos, parent1.name)
local child = mobs:spawn_child(pos, parent1.name)
if child then
local ent_c = child:get_luaentity()
local p = math.random(1, 2)
@ -490,7 +415,7 @@ local horse = {
end,
}
mcl_mobs:register_mob("mobs_mc:horse", horse)
mobs:register_mob("mobs_mc:horse", horse)
-- Skeleton horse
local skeleton_horse = table.copy(horse)
@ -499,7 +424,7 @@ skeleton_horse.breath_max = -1
skeleton_horse.armor = {undead = 100, fleshy = 100}
skeleton_horse.textures = {{"blank.png", "mobs_mc_horse_skeleton.png", "blank.png"}}
skeleton_horse.drops = {
{name = "mcl_mobitems:bone",
{name = mobs_mc.items.bone,
chance = 1,
min = 0,
max = 2,},
@ -513,7 +438,7 @@ skeleton_horse.sounds = {
distance = 16,
}
skeleton_horse.harmed_by_heal = true
mcl_mobs:register_mob("mobs_mc:skeleton_horse", skeleton_horse)
mobs:register_mob("mobs_mc:skeleton_horse", skeleton_horse)
-- Zombie horse
local zombie_horse = table.copy(horse)
@ -522,7 +447,7 @@ zombie_horse.breath_max = -1
zombie_horse.armor = {undead = 100, fleshy = 100}
zombie_horse.textures = {{"blank.png", "mobs_mc_horse_zombie.png", "blank.png"}}
zombie_horse.drops = {
{name = "mcl_mobitems:rotten_flesh",
{name = mobs_mc.items.rotten_flesh,
chance = 1,
min = 0,
max = 2,},
@ -537,15 +462,13 @@ zombie_horse.sounds = {
distance = 16,
}
zombie_horse.harmed_by_heal = true
mcl_mobs:register_mob("mobs_mc:zombie_horse", zombie_horse)
mobs:register_mob("mobs_mc:zombie_horse", zombie_horse)
-- Donkey
local d = 0.86 -- donkey scale
local donkey = table.copy(horse)
donkey.description = S("Donkey")
donkey.textures = {{"blank.png", "mobs_mc_donkey.png", "blank.png"}}
donkey.spawn_in_group = 3
donkey.spawn_in_group_min = 1
donkey.animation = {
speed_normal = 25,
stand_start = 0, stand_end = 0,
@ -570,9 +493,8 @@ donkey.collisionbox = {
donkey.jump = true
donkey.jump_height = 3.75 -- can clear 1 block height
mobs:register_mob("mobs_mc:donkey", donkey)
mcl_mobs:register_mob("mobs_mc:donkey", donkey)
mcl_entity_invs.register_inv("mobs_mc:donkey","Donkey",15,true)
-- Mule
local m = 0.94
local mule = table.copy(donkey)
@ -589,60 +511,84 @@ mule.collisionbox = {
horse.collisionbox[5] * m,
horse.collisionbox[6] * m,
}
mcl_mobs:register_mob("mobs_mc:mule", mule)
mcl_entity_invs.register_inv("mobs_mc:mule","Mule",15,true)
mobs:register_mob("mobs_mc:mule", mule)
--===========================
--Spawn Function
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:horse",
"overworld",
"ground",
{
"flat",
"IcePlainsSpikes",
"ColdTaiga",
"ColdTaiga_beach",
"ColdTaiga_beach_water",
"MegaTaiga",
"MegaSpruceTaiga",
"ExtremeHills",
"ExtremeHills_beach",
"ExtremeHillsM",
"ExtremeHills+",
"ExtremeHills+_snowtop",
"StoneBeach",
"Plains",
"Plains_beach",
"SunflowerPlains",
"Taiga",
"Taiga_beach",
"Forest",
"Forest_beach",
"FlowerForest",
"FlowerForest_beach",
"BirchForest",
"BirchForestM",
"RoofedForest",
"Savanna",
"Savanna_beach",
"SavannaM",
"Savanna_beach",
"Plains_beach",
"Jungle",
"Jungle_shore",
"JungleM",
"JungleM_shore",
"JungleEdge",
"JungleEdgeM",
"Swampland",
"Swampland_shore"
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
4,
mobs_mc.water_level+3,
mcl_vars.mg_overworld_max)
mobs_mc.spawn_height.water+3,
mobs_mc.spawn_height.overworld_max)
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:donkey",
"overworld",
"ground",
{
"flat",
"Plains",
"Plains_beach",
"SunflowerPlains",
"Savanna",
"Savanna_beach",
"SavannaM",
"Savanna_beach",
"Plains_beach",
"Mesa",
"MesaPlateauFM_grasstop",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
},
9,
0,
minetest.LIGHT_MAX+1,
30,
15000,
4,
mobs_mc.water_level+3,
mcl_vars.mg_overworld_max)
mobs_mc.spawn_height.water+3,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:horse", S("Horse"), "#c09e7d", "#eee500", 0)
mcl_mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "#68684f", "#e5e5d8", 0)
--mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "#2a5a37", "#84d080", 0)
mcl_mobs:register_egg("mobs_mc:donkey", S("Donkey"), "#534539", "#867566", 0)
mcl_mobs:register_egg("mobs_mc:mule", S("Mule"), "#1b0200", "#51331d", 0)
mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)
mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0)
--mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0)
mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0)
mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0)

View File

@ -2,100 +2,45 @@
--maikerumine
--made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes
mobs_mc = {}
local pr = PseudoRandom(os.time()*5)
local path = minetest.get_modpath("mobs_mc")
local offsets = {}
for x=-2, 2 do
for z=-2, 2 do
table.insert(offsets, {x=x, y=0, z=z})
end
if not minetest.get_modpath("mobs_mc_gameconfig") then
mobs_mc = {}
end
--[[ Periodically check and teleport mob to owner if not sitting (order ~= "sit") and
the owner is too far away. To be used with do_custom. Note: Optimized for mobs smaller than 1×1×1.
Larger mobs might have space problems after teleportation.
-- For utility functions
mobs_mc.tools = {}
* dist: Minimum required distance from owner to teleport. Default: 12
* teleport_check_interval: Optional. Interval in seconds to check the mob teleportation. Default: 4 ]]
mobs_mc.make_owner_teleport_function = function(dist, teleport_check_interval)
return function(self, dtime)
-- No teleportation if no owner or if sitting
if not self.owner or self.order == "sit" then
return
-- This function checks if the item ID has been overwritten and returns true if it is unchanged
if minetest.get_modpath("mobs_mc_gameconfig") and mobs_mc.override and mobs_mc.override.items then
mobs_mc.is_item_variable_overridden = function(id)
return mobs_mc.override.items[id] == nil
end
if not teleport_check_interval then
teleport_check_interval = 4
end
if not dist then
dist = 12
end
if self._teleport_timer == nil then
self._teleport_timer = teleport_check_interval
return
end
self._teleport_timer = self._teleport_timer - dtime
if self._teleport_timer <= 0 then
self._teleport_timer = teleport_check_interval
local mob_pos = self.object:get_pos()
local owner = minetest.get_player_by_name(self.owner)
if not owner then
-- No owner found, no teleportation
return
end
local owner_pos = owner:get_pos()
local dist_from_owner = vector.distance(owner_pos, mob_pos)
if dist_from_owner > dist then
-- Check for nodes below air in a 5×1×5 area around the owner position
local check_offsets = table.copy(offsets)
-- Attempt to place mob near player. Must be placed on walkable node below a non-walkable one. Place inside that air node.
while #check_offsets > 0 do
local r = pr:next(1, #check_offsets)
local telepos = vector.add(owner_pos, check_offsets[r])
local telepos_below = {x=telepos.x, y=telepos.y-1, z=telepos.z}
table.remove(check_offsets, r)
-- Long story short, spawn on a platform
local trynode = minetest.registered_nodes[minetest.get_node(telepos).name]
local trybelownode = minetest.registered_nodes[minetest.get_node(telepos_below).name]
if trynode and not trynode.walkable and
trybelownode and trybelownode.walkable then
-- Correct position found! Let's teleport.
self.object:set_pos(telepos)
return
end
end
end
end
end
end
local function is_forbidden_node(pos, node)
node = node or minetest.get_node(pos)
return minetest.get_item_group(node.name, "stair") > 0 or minetest.get_item_group(node.name, "slab") > 0 or minetest.get_item_group(node.name, "carpet") > 0
end
function mcl_mobs:spawn_abm_check(pos, node, name)
-- Don't spawn monsters on mycelium
if (node.name == "mcl_core:mycelium" or node.name == "mcl_core:mycelium_snow") and minetest.registered_entities[name].type == "monster" then
else
-- No items are overwritten, so always return true
mobs_mc.is_item_variable_overridden = function(id)
return true
--Don't Spawn mobs on stairs, slabs, or carpets
elseif is_forbidden_node(pos, node) or is_forbidden_node(vector.add(pos, vector.new(0, 1, 0))) then
return true
-- Spawn on opaque or liquid nodes
elseif minetest.get_item_group(node.name, "opaque") ~= 0 or minetest.registered_nodes[node.name].liquidtype ~= "none" or node.name == "mcl_core:grass_path" then
return false
end
-- Reject everything else
return true
end
mobs_mc.shears_wear = 276
mobs_mc.water_level = tonumber(minetest.settings:get("water_level")) or 0
--MOB ITEMS SELECTOR SWITCH
dofile(path .. "/0_gameconfig.lua")
--Items
dofile(path .. "/1_items_default.lua")
-- Bow, arrow and throwables
dofile(path .. "/2_throwing.lua")
-- Shared functions
dofile(path .. "/3_shared.lua")
--Mob heads
dofile(path .. "/4_heads.lua")
dofile(path .. "/5_spawn_abm_check.lua")
-- Animals
local path = minetest.get_modpath("mobs_mc")
dofile(path .. "/bat.lua") -- Mesh and animation by toby109tt / https://github.com/22i
dofile(path .. "/rabbit.lua") -- Mesh and animation byExeterDad
dofile(path .. "/chicken.lua") -- Mesh and animation by Pavel_S
@ -112,9 +57,10 @@ dofile(path .. "/squid.lua") -- Animation, sound and egg texture by daufinsyd
-- NPCs
dofile(path .. "/villager.lua") -- KrupnoPavel Mesh and animation by toby109tt / https://github.com/22i
-- Agent texture missing
--dofile(path .. "/agent.lua") -- Mesh and animation by toby109tt / https://github.com/22i
-- Illagers and witch
dofile(path .. "/pillager.lua") -- Mesh by KrupnoPavel and MrRar, animation by MrRar
dofile(path .. "/villager_evoker.lua") -- Mesh and animation by toby109tt / https://github.com/22i
dofile(path .. "/villager_vindicator.lua") -- Mesh and animation by toby109tt / https://github.com/22i
dofile(path .. "/villager_zombie.lua") -- Mesh and animation by toby109tt / https://github.com/22i
@ -143,16 +89,12 @@ dofile(path .. "/slime+magma_cube.lua") -- Wuzzy
dofile(path .. "/spider.lua") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture)
dofile(path .. "/vex.lua") -- KrupnoPavel
dofile(path .. "/wither.lua") -- Mesh and animation by toby109tt / https://github.com/22i
dofile(path .. "/cod.lua")
dofile(path .. "/salmon.lua")
dofile(path .. "/tropical_fish.lua")
dofile(path .. "/dolphin.lua")
dofile(path .. "/glow_squid.lua")
dofile(path .. "/piglin.lua")
dofile(path .. "/hoglin+zoglin.lua")
dofile(path .. "/strider.lua")
--NOTES:
--
--[[
COLISIONBOX in minetest press f5 to see where you are looking at then put these wool collor nodes on the ground in direction of north/east/west... to make colisionbox editing easier
#1west-pink/#2down/#3south-blue/#4east-red/#5up/#6north-yelow
{-1, -0.5, -1, 1, 3, 1}, Right, Bottom, Back, Left, Top, Front
--]]
--
--

View File

@ -9,9 +9,9 @@ local S = minetest.get_translator("mobs_mc")
--################### IRON GOLEM
--###################
local etime = 0
mcl_mobs:register_mob("mobs_mc:iron_golem", {
mobs:register_mob("mobs_mc:iron_golem", {
description = S("Iron Golem"),
type = "npc",
spawn_class = "passive",
@ -22,9 +22,6 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", {
collisionbox = {-0.7, -0.01, -0.7, 0.7, 2.69, 0.7},
visual = "mesh",
mesh = "mobs_mc_iron_golem.b3d",
head_swivel = "head.control",
bone_eye_height = 3.38,
curiosity = 10,
textures = {
{"mobs_mc_iron_golem.png"},
},
@ -40,38 +37,16 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", {
run_velocity = 1.2,
-- Approximation
damage = 14,
knock_back = false,
reach = 3,
group_attack = true,
attacks_monsters = true,
attack_type = "dogfight",
_got_poppy = false,
pick_up = {"mcl_flowers:poppy"},
on_pick_up = function(self,n)
local it = ItemStack(n.itemstring)
if it:get_name() == "mcl_flowers:poppy" then
if not self._got_poppy then
self._got_poppy=true
it:take_item(1)
end
end
return it
end,
replace_what = {"mcl_flowers:poppy"},
replace_with = {"air"},
on_replace = function(self, pos, oldnode, newnode)
if not self.got_poppy and oldnode.name == "mcl_flowers:poppy" then
self._got_poppy=true
return
end
return false
end,
drops = {
{name = "mcl_core:iron_ingot",
{name = mobs_mc.items.iron_ingot,
chance = 1,
min = 3,
max = 5,},
{name = "mcl_flowers:poppy",
{name = mobs_mc.items.poppy,
chance = 1,
min = 0,
max = 2,},
@ -85,19 +60,12 @@ mcl_mobs:register_mob("mobs_mc:iron_golem", {
punch_start = 40, punch_end = 50,
},
jump = true,
on_step = function(self,dtime)
etime = etime + dtime
if etime > 10 then
if self._home and vector.distance(self._home,self.object:get_pos()) > 50 then
mcl_mobs:gopath(self,self._home)
end
end
end,
})
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:iron_golem", S("Iron Golem"), "#3b3b3b", "#f57223", 0)
mobs:register_egg("mobs_mc:iron_golem", S("Iron Golem"), "mobs_mc_spawn_icon_iron_golem.png", 0)
--[[ This is to be called when a pumpkin or jack'o lantern has been placed. Recommended: In the on_construct function of the node.
This summons an iron golen if placing the pumpkin created an iron golem summon pattern:
@ -111,7 +79,7 @@ I = Iron block
. = Air
]]
function mobs_mc.check_iron_golem_summon(pos)
mobs_mc.tools.check_iron_golem_summon = function(pos)
local checks = {
-- These are the possible placement patterns, with offset from the pumpkin block.
-- These tables include the positions of the iron blocks (1-4) and air blocks (5-8)
@ -169,7 +137,7 @@ function mobs_mc.check_iron_golem_summon(pos)
for i=1, 4 do
local cpos = vector.add(pos, checks[c][i])
local node = minetest.get_node(cpos)
if node.name ~= "mcl_core:ironblock" then
if node.name ~= mobs_mc.items.iron_block then
ok = false
break
end

View File

@ -24,52 +24,15 @@ local carpets = {
unicolor_light_blue = { "mcl_wool:light_blue_carpet", "light_blue" },
}
local function get_drops(self)
self.drops = {}
table.insert(self.drops,
{name = "mcl_mobitems:leather",
chance = 1,
min = 0,
max = 2,
looting = "common",
})
if self.carpet then
table.insert(self.drops,{name = self.carpet,
chance = 1,
min = 1,
max = 1,})
end
if self._has_chest then
table.insert(self.drops,{name = "mcl_chests:chest",
chance = 1,
min = 1,
max = 1,})
end
end
mcl_mobs:register_mob("mobs_mc:llama", {
mobs:register_mob("mobs_mc:llama", {
description = S("Llama"),
type = "animal",
spawn_class = "passive",
passive = false,
attack_type = "shoot",
shoot_interval = 5.5,
arrow = "mobs_mc:llamaspit",
shoot_offset = 1, --3.5 *would* be a good value visually but it somehow messes with the projectiles trajectory
spawn_in_group_min = 4,
spawn_in_group = 6,
head_swivel = "head.control",
bone_eye_height = 11,
head_eye_height = 3,
horrizonatal_head_height=0,
curiosity = 60,
head_yaw = "z",
hp_min = 15,
hp_max = 30,
xp_min = 1,
xp_max = 3,
passive = false,
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.86, 0.45},
visual = "mesh",
mesh = "mobs_mc_llama.b3d",
@ -79,15 +42,17 @@ mcl_mobs:register_mob("mobs_mc:llama", {
{"blank.png", "blank.png", "mobs_mc_llama_gray.png"},
{"blank.png", "blank.png", "mobs_mc_llama_white.png"},
{"blank.png", "blank.png", "mobs_mc_llama.png"},
-- TODO: Add llama carpet textures (Pixel Perfection seems to use verbatim copy from Minecraft :-( )
},
visual_size = {x=3, y=3},
makes_footstep_sound = true,
runaway = false,
runaway = true,
walk_velocity = 1,
run_velocity = 4.4,
follow_velocity = 4.4,
floats = 1,
drops = {
{name = "mcl_mobitems:leather",
{name = mobs_mc.items.leather,
chance = 1,
min = 0,
max = 2,
@ -101,35 +66,43 @@ mcl_mobs:register_mob("mobs_mc:llama", {
distance = 16,
},
animation = {
stand_start = 0, stand_end = 0,
walk_start = 0, walk_end = 40, walk_speed = 35,
run_start = 0, run_end = 40, run_speed = 50,
speed_normal = 24,
run_speed = 60,
run_start = 0,
run_end = 40,
stand_start = 0,
stand_end = 0,
walk_start = 0,
walk_end = 40,
hurt_start = 118,
hurt_end = 154,
death_start = 154,
death_end = 179,
eat_start = 49,
eat_end = 78,
look_start = 78,
look_end = 108,
},
child_animations = {
stand_start = 41, stand_end = 41,
walk_start = 41, walk_end = 81, walk_speed = 50,
run_start = 41, run_end = 81, run_speed = 75,
},
follow = { "mcl_farming:wheat_item", "mcl_farming:hay_block" },
follow = mobs_mc.follow.llama,
view_range = 16,
do_custom = function(self, dtime)
-- set needed values if not already present
if not self.v3 then
self.v3 = 0
if not self.v2 then
self.v2 = 0
self.max_speed_forward = 4
self.max_speed_reverse = 2
self.accel = 4
self.terrain_type = 3
self.driver_attach_at = {x = 0, y = 12.7, z = -5}
self.driver_eye_offset = {x = 0, y = 6, z = 0}
self.driver_attach_at = {x = 0, y = 4.17, z = -1.5}
self.driver_eye_offset = {x = 0, y = 3, z = 0}
self.driver_scale = {x = 1/self.visual_size.x, y = 1/self.visual_size.y}
end
-- if driver present allow control of llama
if self.driver then
mcl_mobs.drive(self, "walk", "stand", false, dtime)
mobs.drive(self, "walk", "stand", false, dtime)
return false -- skip rest of mob functions
end
@ -141,7 +114,7 @@ mcl_mobs:register_mob("mobs_mc:llama", {
-- detach from llama properly
if self.driver then
mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1})
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end
end,
@ -154,32 +127,20 @@ mcl_mobs:register_mob("mobs_mc:llama", {
end
local item = clicker:get_wielded_item()
if item:get_name() == "mcl_farming:hay_block" then
if item:get_name() == mobs_mc.items.hay_bale then
-- Breed with hay bale
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
elseif not self._has_chest and item:get_name() == "mcl_chests:chest" then
item:take_item()
clicker:set_wielded_item(item)
self._has_chest = true
self.base_texture = table.copy(self.base_texture)
self.base_texture[1] = self.base_texture[3]
self.object:set_properties({
textures = self.base_texture,
})
get_drops(self)
return
elseif self._has_chest and clicker:get_player_control().sneak then
mcl_entity_invs.show_inv_form(self,clicker," - Strength "..math.floor(self._inv_size / 3))
return
if mobs:feed_tame(self, clicker, 1, true, false) then return end
else
-- Feed with anything else
if mcl_mobs:feed_tame(self, clicker, 1, false, true) then return end
if mobs:feed_tame(self, clicker, 1, false, true) then return end
end
if mcl_mobs:protect(self, clicker) then return end
if mobs:protect(self, clicker) then return end
-- Make sure tamed llama is mature and being clicked by owner only
if self.tamed and not self.child and self.owner == clicker:get_player_name() then
-- Place carpet
--[[ TODO: Re-enable this code when carpet textures arrived.
if minetest.get_item_group(item:get_name(), "carpet") == 1 and not self.carpet then
for group, carpetdata in pairs(carpets) do
if minetest.get_item_group(item:get_name(), group) == 1 then
@ -195,23 +156,42 @@ mcl_mobs:register_mob("mobs_mc:llama", {
textures = self.base_texture,
})
self.carpet = item:get_name()
get_drops(self)
self.drops = {
{name = mobs_mc.items.leather,
chance = 1,
min = 0,
max = 2,},
{name = item:get_name(),
chance = 1,
min = 1,
max = 1,},
}
return
end
end
end
]]
-- detatch player already riding llama
if self.driver and clicker == self.driver then
mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1})
mobs.detach(clicker, {x = 1, y = 0, z = 1})
-- attach player to llama
elseif not self.driver then
self.object:set_properties({stepheight = 1.1})
mcl_mobs.attach(self, clicker)
mobs.attach(self, clicker)
end
-- Used to capture llama
elseif not self.driver and clicker:get_wielded_item():get_name() ~= "" then
mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
end
end,
--[[
TODO: Enable this code when carpet textures arrived.
on_breed = function(parent1, parent2)
-- When breeding, make sure the child has no carpet
local pos = parent1.object:get_pos()
@ -221,7 +201,7 @@ mcl_mobs:register_mob("mobs_mc:llama", {
else
parent = parent2
end
child = mcl_mobs:spawn_child(pos, parent.name)
child = mobs:spawn_child(pos, parent.name)
if child then
local ent_c = child:get_luaentity()
ent_c.base_texture = table.copy(ent_c.base_texture)
@ -233,68 +213,36 @@ mcl_mobs:register_mob("mobs_mc:llama", {
return false
end
end,
on_spawn = function(self)
if not self._inv_size then
local r = math.random(1000)
if r < 80 then
self._inv_size = 15
elseif r < 160 then
self._inv_size = 12
elseif r < 488 then
self._inv_size = 9
elseif r < 816 then
self._inv_size = 6
else
self._inv_size = 3
end
end
end,
})
]]
mcl_entity_invs.register_inv("mobs_mc:llama","Llama",nil,true)
-- spit arrow (weapon)
mcl_mobs:register_arrow("mobs_mc:llamaspit", {
visual = "sprite",
visual_size = {x = 0.10, y = 0.10},
textures = {"mobs_mc_llama_spit.png"},
velocity = 5,
hit_player = function(self, player)
player:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 1},
}, nil)
end,
hit_mob = function(self, mob)
end,
hit_node = function(self, pos, node)
end
})
--spawn
mcl_mobs:spawn_specific(
mobs:spawn_specific(
"mobs_mc:llama",
"overworld",
"ground",
{
"Savanna",
"SavannaM",
"SavannaM_beach",
"Savanna_beach",
"Savanna_ocean",
"ExtremeHills",
"ExtremeHills_beach",
"ExtremeHillsM",
}, --FIXME: Needs Windswept Forest when that is added.
"Mesa",
"MesaPlateauFM_grasstop",
"MesaPlateauF",
"MesaPlateauFM",
"MesaPlateauF_grasstop",
"MesaBryce",
"Jungle",
"Jungle_shore",
"JungleM",
"JungleM_shore",
"JungleEdge",
"JungleEdgeM",
},
0,
minetest.LIGHT_MAX+1,
30,
15000,
5,
mobs_mc.water_level+15,
mcl_vars.mg_overworld_max)
mobs_mc.spawn_height.water+15,
mobs_mc.spawn_height.overworld_max)
-- spawn eggs
mcl_mobs:register_egg("mobs_mc:llama", S("Llama"), "#c09e7d", "#995f40", 0)
mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0)

View File

@ -1,4 +1,7 @@
# textdomain: mobs_mc
Totem of Undying=Totem der Unsterblichkeit
A totem of undying is a rare artifact which may safe you from certain death.=Ein Totem der Unsterblichkeit ist ein seltenes Artefakt, dass Sie vor dem sicheren Tod bewahren kann.
The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=Der Totem funktioniert nur, während Sie ihn halten. Wenn Sie normalerweise tödlich hohen Schaden erhalten, werden Sie vor dem Tod bewahrt und Sie erhalten eine zweite Chance mit 1 TP. Der Totem wird dabei zerstört.
Agent=Akteur
Bat=Fledermaus
Blaze=Lohe
@ -49,6 +52,13 @@ Wolf=Wolf
Husk=Wüstenzombie
Zombie=Zombie
Zombie Pigman=Schweinezombie
Iron Horse Armor=Eisenpferderüstung
Iron horse armor can be worn by horses to increase their protection from harm a bit.=Eine Eisenpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden etwas zu erhöhen.
Golden Horse Armor=Goldpferderüstung
Golden horse armor can be worn by horses to increase their protection from harm.=Eine Goldpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden zu erhöhen.
Diamond Horse Armor=Diamantpferderüstung
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Eine Diamantpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden beträchtlich zu erhöhen.
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Platzieren Sie es auf einem Pferd, um die Pferderüstung aufzusetzen. Esel und Maultiere können keine Pferderüstung tragen.
Farmer=Bauer
Fisherman=Fischer
Fletcher=Pfeilmacher
@ -62,3 +72,4 @@ Weapon Smith=Waffenschmied
Tool Smith=Werkzeugschmied
Cleric=Priester
Nitwit=Dorftrottel
Protects you from death while wielding it=Schützt vor dem Tod, wenn es gehalten wird

View File

@ -1,58 +1,74 @@
# textdomain: mobs_mc
Totem of Undying=Tótem de la inmortalidad
A totem of undying is a rare artifact which may safe you from certain death.=Un tótem de la inmortalidad es un artefacto raro que puede salvarte de una muerte segura.
The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=El tótem solo funciona mientras lo sostienes en tu mano. Si recibes un daño crítico, no mueres y obtienes una segunda oportunidad con 1 HP. Sin embargo, el tótem se destruye en el proceso.
Agent=Agente
Bat=Murciélago
Blaze=Blaze
Chicken=Pollo
Cod=Bacalao
Cow=Vaca
Mooshroom=Champivaca
Mooshroom=Champiñaca
Creeper=Creeper
Dolphin=Delfín
Ender Dragon=Ender Dragon
Ender Dragon=Enderdragón
Enderman=Enderman
Endermite=Endermite
Ghast=Ghast
Elder Guardian=Gran guardián
Guardian=Guardián
Elder Guardian=Guardián Anciano
Donkey=Burro
Horse=Caballo
Skeleton Horse=Caballo esquelético
Zombie Horse=Caballo zombie
Donkey=Burro
Mule=Mula
Skeleton Horse=Caballo esqueleto
Zombie Horse=Caballo zombi
Iron Golem=Golem de hierro
Llama=Llama
Cat=Gato
Ocelot=Ocelote
Parrot=Loro
Pig=Cerdo
Polar Bear=Oso polar
Killer Bunny=Conejo asesino
Rabbit=Conejo
Salmon=Salmón
Killer Bunny=Conejo asesino
Sheep=Oveja
Shulker=Shulker
Silverfish=Lepisma
Skeleton=Esqueleto
Stray=Esqueleto glacial
Wither Skeleton=Esqueleto del Wither
Stray=Esqueleto
Wither Skeleton=Esqueleto wither
Magma Cube=Cubo de Magma
Slime=Slime
Snow Golem=Golem de nieve
Cave Spider=Araña de las cuevas
Spider=Araña
Cave Spider=Araña de las cuevas
Squid=Calamar
Vex=Ánima
Master=Maestro
Villager=Aldeano
Evoker=Invocador
Illusioner=Illusionista
Villager=Aldeano
Vindicator=Vindicador
Zombie Villager=Aldeano zombi
Zombie Villager=Aldeano zombie
Witch=Bruja
Wither=Wither
Wolf=Lobo
Baby Husk=Bebé Zombi Momificado
Baby Zombie=Bebé Zombi
Husk=Zombi Momificado
Zombie=Zombi
Baby Zombie Pigman=Bebé Hombrecerdo Zombi
Zombie Pigman=Hombrecerdo Zombi
Husk=Husk
Zombie=Zombie
Zombie Pigman=Cerdo Zombie
Iron Horse Armor=Armadura de hierro para caballo
Iron horse armor can be worn by horses to increase their protection from harm a bit.=Los caballos pueden usar armadura de caballo de hierro para aumentar un poco su protección contra el daño.
Golden Horse Armor=Armadura de oro para caballo
Golden horse armor can be worn by horses to increase their protection from harm.=Los caballos pueden usar armadura de caballo de oro para aumentar su protección contra el daño.
Diamond Horse Armor=Armadura de diamante para caballo
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Los caballos pueden usar armadura de caballo de diamante para aumentar en gran medida su protección contra el daño.
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Colóquelo en un caballo para ponerle la armadura de caballo. Los burros y las mulas no pueden usar armadura de caballo.
Farmer=Granjero
Fisherman=Pescador
Fletcher=Flechador
Shepherd=Sacerdote
Librarian=Bibliotecario
Cartographer=Cartógrafo
Armorer=Armero
Leatherworker=Peletero
Butcher=Carnicero
Weapon Smith=Herrero de Armas
Tool Smith=Herrero de Herramientas
Cleric=Sacerdote
Nitwit=Simple

View File

@ -1,4 +1,7 @@
# textdomain: mobs_mc
Totem of Undying=Totem d'immortalité
A totem of undying is a rare artifact which may safe you from certain death.=Un totem d'immortalité est un artefact rare qui peut vous protéger d'une mort certaine.
The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=Le totem ne fonctionne que lorsque vous le tenez dans votre main. Si vous recevez des dégâts mortels, vous êtes sauvé de la mort et vous obtenez une seconde chance avec 1 HP. Cependant, le totem est détruit.
Agent=Agent
Bat=Chauve-souris
Blaze=Blaze
@ -49,6 +52,13 @@ Wolf=Loup
Husk=Zombie Momifié
Zombie=Zombie
Zombie Pigman=Zombie Cochon
Iron Horse Armor=Armure de cheval en fer
Iron horse armor can be worn by horses to increase their protection from harm a bit.=L'armure de cheval en fer peut être portée par les chevaux pour augmenter un peu leur protection contre les dommages.
Golden Horse Armor=Armure de cheval en or
Golden horse armor can be worn by horses to increase their protection from harm.=Une armure de cheval en or peut être portée par les chevaux pour augmenter leur protection contre les dommages.
Diamond Horse Armor=Armure de cheval en diamant
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Une armure de cheval en diament peut être portée par les chevaux pour augmenter fortement leur protection contre les dommages.
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Placez-la sur un cheval pour mettre l'armure de cheval. Les ânes et les mules ne peuvent pas porter d'armure de cheval.
Farmer=Fermier
Fisherman=Pêcheur
Fletcher=Archer
@ -62,8 +72,4 @@ Weapon Smith=Fabriquant d'arme
Tool Smith=Fabriquant d'outil
Cleric=Clerc
Nitwit=Crétin
Cod=Morue
Salmon=Saumon
Dolphin=Dauphin
Pillager=Pilleur
Tropical fish=Poisson tropical
Protects you from death while wielding it=Vous protège de la mort en la maniant

View File

@ -1,4 +1,7 @@
# textdomain: mobs_mc
Totem of Undying=Тотем бессмертия
A totem of undying is a rare artifact which may safe you from certain death.=Тотем бессмертия это редкий артефакт, способный спасти вас от смерти.
The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=Тотем работает только когда вы держите его в руке. Если вы получаете смертельный урон, вы спасаетесь от смерти и получаете второй шанс с 1 HP. Однако тотем при этом уничтожается.
Agent=Агент
Bat=Летучая мышь
Blaze=Ифрит
@ -49,6 +52,13 @@ Wolf=Волк
Husk=Кадавр
Zombie=Зомби
Zombie Pigman=Зомби-свиночеловек
Iron Horse Armor=Железные доспехи лошади
Iron horse armor can be worn by horses to increase their protection from harm a bit.=Железные доспехи лошади, надетые на лошадь, немного защищают её от вреда.
Golden Horse Armor=Золотые доспехи лошади
Golden horse armor can be worn by horses to increase their protection from harm.=Золотые доспехи лошади, надетые на лошадь, защищают её от вреда.
Diamond Horse Armor=Алмазные доспехи лошади
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Алмазные доспехи лошади, надетые на лошадь, отлично защищают её от вреда.
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Поместите это на лошадь, чтобы одеть лошадь в доспехи. Ослики и мулы не могут носить лошадиные доспехи.
Farmer=Фермер
Fisherman=Рыбак
Fletcher=Лучник
@ -62,3 +72,4 @@ Weapon Smith=Оружейник
Tool Smith=Инструментальщик
Cleric=Церковник
Nitwit=Нищий
Protects you from death while wielding it=Защищает вас от смерти, пока вы владеете им

View File

@ -1,4 +1,7 @@
# textdomain: mobs_mc
Totem of Undying=
A totem of undying is a rare artifact which may safe you from certain death.=
The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=
Agent=
Bat=
Blaze=
@ -49,6 +52,13 @@ Wolf=
Husk=
Zombie=
Zombie Pigman=
Iron Horse Armor=
Iron horse armor can be worn by horses to increase their protection from harm a bit.=
Golden Horse Armor=
Golden horse armor can be worn by horses to increase their protection from harm.=
Diamond Horse Armor=
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=
Farmer=
Fisherman=
Fletcher=
@ -62,8 +72,4 @@ Weapon Smith=
Tool Smith=
Cleric=
Nitwit=
Cod=
Salmon=
Dolphin=
Pillager=
Tropical fish=
Protects you from death while wielding it=

View File

@ -1,5 +1,6 @@
name = mobs_mc
author = maikerumine
description = Adds Minecraft-like monsters and animals.
depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip, mcl_core, mcl_util
depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip
optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, mobs_mc_gameconfig, doc_items

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More